1 /* 2 * Copyright (c) 2025, Mediatek Inc. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <errno.h> 8 9 #include <common/debug.h> 10 #include <drivers/pmic/pmic_psc.h> 11 #ifdef CONFIG_MTK_PMIC_SHUTDOWN_CFG 12 #include <drivers/pmic/pmic_shutdown_cfg.h> 13 #endif 14 15 #define ERR_INVALID_ARGS -EINVAL 16 #define ERR_NOT_CONFIGURED -ENODEV 17 18 static const struct pmic_psc_config *pmic_psc; 19 20 static uint32_t read_pmic_psc_reg(enum pmic_psc_reg_name reg_name) 21 { 22 uint32_t val = 0; 23 const struct pmic_psc_reg *reg; 24 25 if (reg_name >= pmic_psc->reg_size) 26 return 0; 27 28 reg = &pmic_psc->regs[reg_name]; 29 pmic_psc->read_field(reg->reg_addr, &val, reg->reg_mask, reg->reg_shift); 30 return val; 31 } 32 33 static int set_pmic_psc_reg(enum pmic_psc_reg_name reg_name) 34 { 35 const struct pmic_psc_reg *reg; 36 37 if (reg_name >= pmic_psc->reg_size) 38 return ERR_INVALID_ARGS; 39 40 reg = &pmic_psc->regs[reg_name]; 41 pmic_psc->write_field(reg->reg_addr, 1, reg->reg_mask, reg->reg_shift); 42 return 0; 43 } 44 45 static int clr_pmic_psc_reg(enum pmic_psc_reg_name reg_name) 46 { 47 const struct pmic_psc_reg *reg; 48 49 if (reg_name >= pmic_psc->reg_size) 50 return ERR_INVALID_ARGS; 51 52 reg = &pmic_psc->regs[reg_name]; 53 pmic_psc->write_field(reg->reg_addr, 0, reg->reg_mask, reg->reg_shift); 54 return 0; 55 } 56 57 int enable_pmic_smart_reset(bool enable) 58 { 59 if (!pmic_psc) 60 return ERR_NOT_CONFIGURED; 61 if (enable) 62 set_pmic_psc_reg(RG_SMART_RST_MODE); 63 else 64 clr_pmic_psc_reg(RG_SMART_RST_MODE); 65 return 0; 66 } 67 68 int enable_pmic_smart_reset_shutdown(bool enable) 69 { 70 if (!pmic_psc) 71 return ERR_NOT_CONFIGURED; 72 if (enable) 73 set_pmic_psc_reg(RG_SMART_RST_SDN_EN); 74 else 75 clr_pmic_psc_reg(RG_SMART_RST_SDN_EN); 76 return 0; 77 } 78 79 int platform_cold_reset(void) 80 { 81 if (!pmic_psc) 82 return ERR_NOT_CONFIGURED; 83 /* Some PMICs may not support cold reset */ 84 if (!pmic_psc->regs[RG_CRST].reg_addr) 85 return ERR_NOT_CONFIGURED; 86 set_pmic_psc_reg(RG_CRST); 87 return 0; 88 } 89 90 int platform_power_hold(bool hold) 91 { 92 int use_spmi_cmd_sdn = 0; 93 94 if (!pmic_psc) 95 return ERR_NOT_CONFIGURED; 96 if (hold) 97 set_pmic_psc_reg(RG_PWRHOLD); 98 else { 99 #ifdef CONFIG_MTK_PMIC_SHUTDOWN_CFG 100 use_spmi_cmd_sdn = pmic_shutdown_cfg(); 101 #endif 102 if (use_spmi_cmd_sdn == 1) 103 spmi_shutdown(); 104 else 105 clr_pmic_psc_reg(RG_PWRHOLD); 106 } 107 return 0; 108 } 109 110 int pmic_psc_register(const struct pmic_psc_config *psc) 111 { 112 if (!psc || !psc->regs || !psc->read_field || !psc->write_field) 113 return ERR_INVALID_ARGS; 114 pmic_psc = psc; 115 INFO("POWER_HOLD=0x%x\n", read_pmic_psc_reg(RG_PWRHOLD)); 116 return 0; 117 } 118