1 /*
2 * Copyright (c) 2025, Mediatek Inc. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #ifndef PMIC_SET_LOWPOWER_H
8 #define PMIC_SET_LOWPOWER_H
9
10 #include <stdint.h>
11
12 #include <drivers/spmi_api.h>
13
14 #include "mt6316_lowpower_reg.h"
15 #include "mt6319_lowpower_reg.h"
16 #include "mt6363_lowpower_reg.h"
17 #include "mt6373_lowpower_reg.h"
18
19 #define OP_MODE_MU 0
20 #define OP_MODE_LP 1
21
22 #define HW_OFF 0
23 #define HW_ON 0
24 #define HW_LP 1
25 #define HW_ONLV (0x10 | 1)
26 #define NORMAL_OP_CFG 0x10
27
28 enum {
29 RC0 = 0,
30 RC1,
31 RC2,
32 RC3,
33 RC4,
34 RC5,
35 RC6,
36 RC7,
37 RC8 = 0,
38 RC9,
39 RC10,
40 RC11,
41 RC12,
42 RC13,
43 HW0 = 0,
44 HW1,
45 HW2,
46 HW3,
47 HW4,
48 HW5,
49 HW6,
50 HW7,
51 HW8 = 0,
52 HW9,
53 HW10,
54 HW11,
55 HW12,
56 HW13,
57 };
58
59 #define VOTER_EN_SET 1
60 #define VOTER_EN_CLR 2
61
62 enum {
63 VOTER_EN_LO_BIT0 = 0,
64 VOTER_EN_LO_BIT1,
65 VOTER_EN_LO_BIT2,
66 VOTER_EN_LO_BIT3,
67 VOTER_EN_LO_BIT4,
68 VOTER_EN_LO_BIT5,
69 VOTER_EN_LO_BIT6,
70 VOTER_EN_LO_BIT7,
71 VOTER_EN_HI_BIT0 = 0,
72 VOTER_EN_HI_BIT1,
73 VOTER_EN_HI_BIT2,
74 VOTER_EN_HI_BIT3,
75 };
76
77 enum {
78 MT6363_SLAVE = SPMI_SLAVE_4,
79 MT6368_SLAVE = SPMI_SLAVE_5,
80 MT6369_SLAVE = SPMI_SLAVE_5,
81 MT6373_SLAVE = SPMI_SLAVE_5,
82 MT6316_S6_SLAVE = SPMI_SLAVE_6,
83 MT6316_S7_SLAVE = SPMI_SLAVE_7,
84 MT6316_S8_SLAVE = SPMI_SLAVE_8,
85 MT6316_S15_SLAVE = SPMI_SLAVE_15,
86 MT6319_S6_SLAVE = SPMI_SLAVE_6,
87 MT6319_S7_SLAVE = SPMI_SLAVE_7,
88 MT6319_S8_SLAVE = SPMI_SLAVE_8,
89 MT6319_S15_SLAVE = SPMI_SLAVE_15,
90 };
91
92 extern struct spmi_device *lowpower_sdev[SPMI_MAX_SLAVE_ID];
93
94 #define PMIC_BUCK_SET_LP(_chip, _name, _user, _en, _mode, _cfg) \
95 { \
96 uint8_t val = 0; \
97 struct spmi_device *sdev = lowpower_sdev[_chip##_SLAVE]; \
98 if (sdev && \
99 !spmi_ext_register_readl(sdev, _chip##_RG_BUCK_##_name##_HW0_OP_CFG_ADDR, &val, 1) && \
100 !(val & NORMAL_OP_CFG)) {\
101 if ((_cfg) == HW_ONLV) { \
102 pmic_spmi_update_bits(sdev, \
103 _chip##_RG_BUCK_##_name##_ONLV_EN_ADDR, \
104 (1 << _chip##_RG_BUCK_##_name##_ONLV_EN_SHIFT), \
105 (1 << _chip##_RG_BUCK_##_name##_ONLV_EN_SHIFT)); \
106 } else if ((_cfg) == HW_LP) { \
107 pmic_spmi_update_bits(sdev, \
108 _chip##_RG_BUCK_##_name##_ONLV_EN_ADDR, \
109 (1 << _chip##_RG_BUCK_##_name##_ONLV_EN_SHIFT), \
110 0); \
111 } \
112 pmic_spmi_update_bits(sdev, \
113 _chip##_RG_BUCK_##_name##_##_user##_OP_CFG_ADDR, \
114 1 << (_user), \
115 ((_cfg) & 0x1) ? 1 << (_user) : 0); \
116 pmic_spmi_update_bits(sdev, \
117 _chip##_RG_BUCK_##_name##_##_user##_OP_MODE_ADDR, \
118 1 << (_user), \
119 (_mode) ? 1 << (_user) : 0); \
120 pmic_spmi_update_bits(sdev, \
121 _chip##_RG_BUCK_##_name##_##_user##_OP_EN_ADDR, \
122 1 << (_user), \
123 (_en) ? 1 << (_user) : 0); \
124 } \
125 }
126
127 #define PMIC_LDO_SET_LP(_chip, _name, _user, _en, _mode, _cfg) \
128 { \
129 uint8_t val = 0; \
130 struct spmi_device *sdev = lowpower_sdev[_chip##_SLAVE]; \
131 if (sdev && \
132 !spmi_ext_register_readl(sdev, _chip##_RG_LDO_##_name##_HW0_OP_CFG_ADDR, &val, 1) && \
133 !(val & NORMAL_OP_CFG)) {\
134 if ((_cfg) == HW_ONLV) { \
135 pmic_spmi_update_bits(sdev, \
136 _chip##_RG_LDO_##_name##_ONLV_EN_ADDR, \
137 (1 << _chip##_RG_LDO_##_name##_ONLV_EN_SHIFT), \
138 (1 << _chip##_RG_LDO_##_name##_ONLV_EN_SHIFT)); \
139 } else { \
140 pmic_spmi_update_bits(sdev, \
141 _chip##_RG_LDO_##_name##_ONLV_EN_ADDR, \
142 (1 << _chip##_RG_LDO_##_name##_ONLV_EN_SHIFT), \
143 0); \
144 } \
145 pmic_spmi_update_bits(sdev, \
146 _chip##_RG_LDO_##_name##_##_user##_OP_CFG_ADDR, \
147 1 << (_user), \
148 ((_cfg) & 0x1) ? 1 << (_user) : 0); \
149 pmic_spmi_update_bits(sdev, \
150 _chip##_RG_LDO_##_name##_##_user##_OP_MODE_ADDR, \
151 1 << (_user), \
152 (_mode) ? 1 << (_user) : 0); \
153 pmic_spmi_update_bits(sdev, \
154 _chip##_RG_LDO_##_name##_##_user##_OP_EN_ADDR, \
155 1 << (_user), \
156 (_en) ? 1 << (_user) : 0); \
157 } \
158 }
159
160 #define PMIC_SLVID_BUCK_SET_LP(_chip, _slvid, _name, _user, _en, _mode, _cfg) \
161 { \
162 struct spmi_device *sdev = lowpower_sdev[_chip##_##_slvid##_SLAVE]; \
163 if (sdev) {\
164 pmic_spmi_update_bits(sdev, \
165 _chip##_RG_BUCK_##_name##_##_user##_OP_CFG_ADDR, \
166 1 << (_user), \
167 (_cfg) ? 1 << (_user) : 0); \
168 pmic_spmi_update_bits(sdev, \
169 _chip##_RG_BUCK_##_name##_##_user##_OP_MODE_ADDR, \
170 1 << (_user), \
171 (_mode) ? 1 << (_user) : 0); \
172 pmic_spmi_update_bits(sdev, \
173 _chip##_RG_BUCK_##_name##_##_user##_OP_EN_ADDR, \
174 1 << (_user), \
175 (_en) ? 1 << (_user) : 0); \
176 } \
177 }
178
179 #define PMIC_BUCK_VOTER_EN(_chip, _name, _user, _cfg) \
180 { \
181 struct spmi_device *sdev = lowpower_sdev[_chip##_SLAVE]; \
182 if (sdev) {\
183 pmic_spmi_update_bits(sdev, \
184 _chip##_RG_BUCK_##_name##_##_user##_ADDR + (_cfg), \
185 1 << (_user), \
186 1 << (_user)); \
187 } \
188 }
189
pmic_spmi_update_bits(struct spmi_device * sdev,uint16_t reg,uint8_t mask,uint8_t val)190 static inline int pmic_spmi_update_bits(struct spmi_device *sdev, uint16_t reg,
191 uint8_t mask, uint8_t val)
192 {
193 uint8_t org = 0;
194 int ret = 0;
195
196 ret = spmi_ext_register_readl(sdev, reg, &org, 1);
197 if (ret < 0)
198 return ret;
199
200 org &= ~mask;
201 org |= val & mask;
202
203 ret = spmi_ext_register_writel(sdev, reg, &org, 1);
204 return ret;
205 }
206
207 #endif /* PMIC_SET_LOWPOWER_H */
208