blob: ff4f7e346437b5b2e45fe29da419fc7f180b3e72 [file] [log] [blame]
Hope Wangd4e6f982024-12-13 16:04:57 +08001/*
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
18static const struct pmic_psc_config *pmic_psc;
19
20static 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
33static 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
45static 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
57int 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
68int 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
79int 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
90int 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
110int 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}