blob: c3854c6927d0a42d8f02d77ee18c14d08152cb6b [file] [log] [blame]
xjb04a4022021-11-25 15:01:52 +08001// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (c) 2019 MediaTek Inc.
4 */
5#include <linux/mfd/mt6315/registers.h>
6#include <linux/pmif.h>
7#include <linux/regmap.h>
8#include <linux/regulator/consumer.h>
9#include <linux/regulator/mt6315-misc.h>
10#include <linux/regulator/mt6315-regulator.h>
11
12#define LP_INIT_SETTING_VERIFIED 1
13
14#define MT6315_DECL_CHIP(_mid, _saddr)\
15{ \
16 .master_idx = _mid, \
17 .slave_addr = _saddr, \
18 .regmap = NULL, \
19}
20
21static struct mt6315_misc mt6315_misc[] = {
22#if defined(CONFIG_MACH_MT6885) || defined(CONFIG_MACH_MT6873)
23 MT6315_DECL_CHIP(SPMI_MASTER_0, MT6315_SLAVE_ID_6),
24 MT6315_DECL_CHIP(SPMI_MASTER_0, MT6315_SLAVE_ID_7),
25 MT6315_DECL_CHIP(SPMI_MASTER_0, MT6315_SLAVE_ID_3),
26#elif defined(CONFIG_MACH_MT6853)
27 MT6315_DECL_CHIP(SPMI_MASTER_0, MT6315_SLAVE_ID_3),
28#else /* For MT6890 */
29 MT6315_DECL_CHIP(SPMI_MASTER_1, MT6315_SLAVE_ID_5),
30#endif
31};
32
33static struct mt6315_misc *mt6315_find_chip_sid(u32 sid)
34{
35 int i;
36
37 for (i = 0; i < ARRAY_SIZE(mt6315_misc); i++) {
38 if (mt6315_misc[i].slave_addr == sid)
39 return &mt6315_misc[i];
40 }
41 return NULL;
42}
43
44static unsigned int g_vmodem_vosel;
45static unsigned int g_vnr_vosel;
46static unsigned int g_vsram_md_vosel;
47
48static void mt6315_S3_default_vosel(void)
49{
50 struct mt6315_misc *mt6315;
51 struct regmap *regmap;
52
53 mt6315 = mt6315_find_chip_sid(MT6315_SLAVE_ID_3);
54 if (!mt6315) {
55 pr_info("%s MT6315S3 not ready.\n", __func__);
56 return;
57 }
58
59 regmap = mt6315->regmap;
60 if (!regmap) {
61 pr_info("%s null regmap.\n", __func__);
62 return;
63 }
64
65 if (g_vmodem_vosel != 0) {
66#if defined(CONFIG_MACH_MT6885) || defined(CONFIG_MACH_MT6873)
67 regmap_write(regmap, MT6315_PMIC_RG_BUCK_VBUCK1_VOSEL_ADDR,
68 g_vmodem_vosel);
69 regmap_write(regmap, MT6315_PMIC_RG_BUCK_VBUCK3_VOSEL_ADDR,
70 g_vnr_vosel);
71 regmap_write(regmap, MT6315_PMIC_RG_BUCK_VBUCK4_VOSEL_ADDR,
72 g_vsram_md_vosel);
73#elif defined(CONFIG_MACH_MT6853)
74 regmap_write(regmap, MT6315_PMIC_RG_BUCK_VBUCK4_VOSEL_ADDR,
75 g_vsram_md_vosel);
76 regmap_write(regmap, MT6315_PMIC_RG_BUCK_VBUCK1_VOSEL_ADDR,
77 g_vmodem_vosel);
78#endif
79 pr_info("[%s] set vmodem=0x%x, vnr=0x%x, vsram_md=0x%x\n"
80 , __func__, g_vmodem_vosel, g_vnr_vosel,
81 g_vsram_md_vosel);
82 } else {
83#if defined(CONFIG_MACH_MT6885) || defined(CONFIG_MACH_MT6873)
84 regmap_read(regmap, MT6315_PMIC_DA_VBUCK1_VOSEL_ADDR,
85 &g_vmodem_vosel);
86 regmap_read(regmap, MT6315_PMIC_DA_VBUCK3_VOSEL_ADDR,
87 &g_vnr_vosel);
88 regmap_read(regmap, MT6315_PMIC_DA_VBUCK4_VOSEL_ADDR,
89 &g_vsram_md_vosel);
90#elif defined(CONFIG_MACH_MT6853)
91 regmap_read(regmap, MT6315_PMIC_DA_VBUCK1_VOSEL_ADDR,
92 &g_vmodem_vosel);
93 g_vnr_vosel = g_vmodem_vosel;
94 regmap_read(regmap, MT6315_PMIC_DA_VBUCK4_VOSEL_ADDR,
95 &g_vsram_md_vosel);
96#endif
97 pr_info("[%s] record vmodem=0x%x, vnr=0x%x, vsram_md=0x%x\n"
98 , __func__, g_vmodem_vosel, g_vnr_vosel,
99 g_vsram_md_vosel);
100 }
101}
102
103void mt6315_vmd1_pmic_setting_on(void)
104{
105 /* Reset VMODEM/VNR/VSRAM_MD default voltage */
106 mt6315_S3_default_vosel();
107}
108
109static int is_mt6315_regulator_exist(const char *name)
110{
111 int ret = 0;
112 struct regulator *reg;
113
114 reg = regulator_get_optional(NULL, name);
115 if (IS_ERR(reg))
116 return 0;
117 ret = regulator_is_enabled(reg);
118 regulator_put(reg);
119
120 return ret;
121}
122
123int is_mt6315_exist(void)
124{
125 int ret = 0;
126#if defined(CONFIG_MACH_MT6885) || defined(CONFIG_MACH_MT6873)
127 pr_info("%s S3:%d S6:%d S7:%d\n", __func__,
128 is_mt6315_regulator_exist("3_vbuck1"),
129 is_mt6315_regulator_exist("6_vbuck1"),
130 is_mt6315_regulator_exist("7_vbuck1"));
131 if (is_mt6315_regulator_exist("3_vbuck1") &&
132 is_mt6315_regulator_exist("6_vbuck1") &&
133 is_mt6315_regulator_exist("7_vbuck1"))
134 return 1;
135#elif defined(CONFIG_MACH_MT6853)
136 ret = is_mt6315_regulator_exist("3_vbuck1");
137 pr_info("%s S3:%d\n", __func__, ret);
138#else
139 ret = is_mt6315_regulator_exist("5_vbuck1");
140 pr_info("%s S5:%d\n", __func__, ret);
141#endif
142 return ret;
143}
144
145#if LP_INIT_SETTING_VERIFIED
146static void mt6315_vbuck1_lp_setting(struct regmap *regmap,
147 enum MT6315_BUCK_EN_USER user, unsigned char mode,
148 unsigned char en, unsigned char cfg)
149{
150 if (user == MT6315_SRCLKEN0) {
151 regmap_update_bits(regmap,
152 MT6315_PMIC_RG_BUCK_VBUCK1_HW0_OP_MODE_ADDR,
153 0x1 << MT6315_PMIC_RG_BUCK_VBUCK1_HW0_OP_MODE_SHIFT,
154 mode << MT6315_PMIC_RG_BUCK_VBUCK1_HW0_OP_MODE_SHIFT);
155 regmap_update_bits(regmap,
156 MT6315_PMIC_RG_BUCK_VBUCK1_HW0_OP_EN_ADDR,
157 0x1 << MT6315_PMIC_RG_BUCK_VBUCK1_HW0_OP_EN_SHIFT,
158 en << MT6315_PMIC_RG_BUCK_VBUCK1_HW0_OP_EN_SHIFT);
159 regmap_update_bits(regmap,
160 MT6315_PMIC_RG_BUCK_VBUCK1_HW0_OP_CFG_ADDR,
161 0x1 << MT6315_PMIC_RG_BUCK_VBUCK1_HW0_OP_CFG_SHIFT,
162 cfg << MT6315_PMIC_RG_BUCK_VBUCK1_HW0_OP_CFG_SHIFT);
163 } else {
164 pr_info("%s non support user control(%d).\n", __func__, user);
165 }
166}
167
168static void mt6315_vbuck2_lp_setting(struct regmap *regmap,
169 enum MT6315_BUCK_EN_USER user, unsigned char mode,
170 unsigned char en, unsigned char cfg)
171{
172 if (user == MT6315_SRCLKEN0) {
173 regmap_update_bits(regmap,
174 MT6315_PMIC_RG_BUCK_VBUCK2_HW0_OP_MODE_ADDR,
175 0x1 << MT6315_PMIC_RG_BUCK_VBUCK2_HW0_OP_MODE_SHIFT,
176 mode << MT6315_PMIC_RG_BUCK_VBUCK2_HW0_OP_MODE_SHIFT);
177 regmap_update_bits(regmap,
178 MT6315_PMIC_RG_BUCK_VBUCK2_HW0_OP_EN_ADDR,
179 0x1 << MT6315_PMIC_RG_BUCK_VBUCK2_HW0_OP_EN_SHIFT,
180 en << MT6315_PMIC_RG_BUCK_VBUCK2_HW0_OP_EN_SHIFT);
181 regmap_update_bits(regmap,
182 MT6315_PMIC_RG_BUCK_VBUCK2_HW0_OP_CFG_ADDR,
183 0x1 << MT6315_PMIC_RG_BUCK_VBUCK2_HW0_OP_CFG_SHIFT,
184 cfg << MT6315_PMIC_RG_BUCK_VBUCK2_HW0_OP_CFG_SHIFT);
185 } else {
186 pr_info("%s non support user control(%d).\n", __func__, user);
187 }
188}
189
190static void mt6315_vbuck3_lp_setting(struct regmap *regmap,
191 enum MT6315_BUCK_EN_USER user, unsigned char mode,
192 unsigned char en, unsigned char cfg)
193{
194 if (user == MT6315_SRCLKEN0) {
195 regmap_update_bits(regmap,
196 MT6315_PMIC_RG_BUCK_VBUCK3_HW0_OP_MODE_ADDR,
197 0x1 << MT6315_PMIC_RG_BUCK_VBUCK3_HW0_OP_MODE_SHIFT,
198 mode << MT6315_PMIC_RG_BUCK_VBUCK3_HW0_OP_MODE_SHIFT);
199 regmap_update_bits(regmap,
200 MT6315_PMIC_RG_BUCK_VBUCK3_HW0_OP_EN_ADDR,
201 0x1 << MT6315_PMIC_RG_BUCK_VBUCK3_HW0_OP_EN_SHIFT,
202 en << MT6315_PMIC_RG_BUCK_VBUCK3_HW0_OP_EN_SHIFT);
203 regmap_update_bits(regmap,
204 MT6315_PMIC_RG_BUCK_VBUCK3_HW0_OP_CFG_ADDR,
205 0x1 << MT6315_PMIC_RG_BUCK_VBUCK3_HW0_OP_CFG_SHIFT,
206 cfg << MT6315_PMIC_RG_BUCK_VBUCK3_HW0_OP_CFG_SHIFT);
207 } else {
208 pr_info("%s non support user control(%d).\n", __func__, user);
209 }
210}
211
212static void mt6315_vbuck4_lp_setting(struct regmap *regmap,
213 enum MT6315_BUCK_EN_USER user, unsigned char mode,
214 unsigned char en, unsigned char cfg)
215{
216 if (user == MT6315_SRCLKEN0) {
217 regmap_update_bits(regmap,
218 MT6315_PMIC_RG_BUCK_VBUCK4_HW0_OP_MODE_ADDR,
219 0x1 << MT6315_PMIC_RG_BUCK_VBUCK4_HW0_OP_MODE_SHIFT,
220 mode << MT6315_PMIC_RG_BUCK_VBUCK4_HW0_OP_MODE_SHIFT);
221 regmap_update_bits(regmap,
222 MT6315_PMIC_RG_BUCK_VBUCK4_HW0_OP_EN_ADDR,
223 0x1 << MT6315_PMIC_RG_BUCK_VBUCK4_HW0_OP_EN_SHIFT,
224 en << MT6315_PMIC_RG_BUCK_VBUCK4_HW0_OP_EN_SHIFT);
225 regmap_update_bits(regmap,
226 MT6315_PMIC_RG_BUCK_VBUCK4_HW0_OP_CFG_ADDR,
227 0x1 << MT6315_PMIC_RG_BUCK_VBUCK4_HW0_OP_CFG_SHIFT,
228 cfg << MT6315_PMIC_RG_BUCK_VBUCK4_HW0_OP_CFG_SHIFT);
229 } else {
230 pr_info("%s non support user control(%d).\n", __func__, user);
231 }
232}
233
234
235static void mt6315_lp_set(unsigned char slave_id, unsigned char buck_id,
236 enum MT6315_BUCK_EN_USER user, unsigned char op_mode,
237 unsigned char op_en, unsigned char op_cfg)
238{
239 struct mt6315_misc *mt6315;
240 struct regmap *regmap;
241
242 mt6315 = mt6315_find_chip_sid(slave_id);
243 if (!mt6315) {
244 pr_info("%s MT6315S%d not ready\n", __func__, slave_id);
245 return;
246 }
247
248 regmap = mt6315->regmap;
249 if (!regmap) {
250 pr_info("%s null regmap.\n", __func__);
251 return;
252 }
253
254 if (buck_id == 1)
255 mt6315_vbuck1_lp_setting(regmap, user, op_mode, op_en, op_cfg);
256 else if (buck_id == 2)
257 mt6315_vbuck2_lp_setting(regmap, user, op_mode, op_en, op_cfg);
258 else if (buck_id == 3)
259 mt6315_vbuck3_lp_setting(regmap, user, op_mode, op_en, op_cfg);
260 else if (buck_id == 4)
261 mt6315_vbuck4_lp_setting(regmap, user, op_mode, op_en, op_cfg);
262 else
263 pr_info("%s invalid buck_id=%d.\n", __func__, buck_id);
264}
265
266/* enable VDIG18 SRCLKEN low power mode */
267static void mt6315_vdig18_hw_op_set(unsigned char slave_id, unsigned char en)
268{
269 struct mt6315_misc *mt6315;
270 struct regmap *regmap;
271
272 mt6315 = mt6315_find_chip_sid(slave_id);
273 if (!mt6315) {
274 pr_info("%s MT6315S%d not ready\n", __func__, slave_id);
275 return;
276 }
277
278 regmap = mt6315->regmap;
279 if (!regmap) {
280 pr_info("%s null regmap.\n", __func__);
281 return;
282 }
283
284 regmap_write(regmap, MT6315_PMIC_DIG_WPK_KEY_H_ADDR, 0x63);
285 regmap_write(regmap, MT6315_PMIC_DIG_WPK_KEY_ADDR, 0x15);
286 regmap_update_bits(regmap,
287 MT6315_PMIC_RG_LDO_VDIG18_HW_OP_EN_ADDR,
288 0x1 << MT6315_PMIC_RG_LDO_VDIG18_HW_OP_EN_SHIFT,
289 en << MT6315_PMIC_RG_LDO_VDIG18_HW_OP_EN_SHIFT);
290 regmap_write(regmap, MT6315_PMIC_DIG_WPK_KEY_ADDR, 0x0);
291 regmap_write(regmap, MT6315_PMIC_DIG_WPK_KEY_H_ADDR, 0x0);
292}
293#endif /* End of LP_INIT_SETTING_VERIFIED */
294
295static void mt6315_S3_lp_initial_setting(void)
296{
297#if LP_INIT_SETTING_VERIFIED
298#if defined(CONFIG_MACH_MT6885) || defined(CONFIG_MACH_MT6873)
299 mt6315_vdig18_hw_op_set(MT6315_SLAVE_ID_3, 1);
300 /* vmodem/vnr/vsram_md */
301 mt6315_lp_set(MT6315_SLAVE_ID_3, 1, MT6315_SRCLKEN0, 1, 1, HW_LP);
302 mt6315_lp_set(MT6315_SLAVE_ID_3, 3, MT6315_SRCLKEN0, 1, 1, HW_LP);
303 mt6315_lp_set(MT6315_SLAVE_ID_3, 4, MT6315_SRCLKEN0, 1, 1, HW_LP);
304#elif defined(CONFIG_MACH_MT6853)
305 mt6315_vdig18_hw_op_set(MT6315_SLAVE_ID_3, 1);
306 /* vmodem/vpu/vsram_md */
307 mt6315_lp_set(MT6315_SLAVE_ID_3, 1, MT6315_SRCLKEN0, 1, 1, HW_LP);
308 mt6315_lp_set(MT6315_SLAVE_ID_3, 3, MT6315_SRCLKEN0, 1, 1, HW_LP);
309 mt6315_lp_set(MT6315_SLAVE_ID_3, 4, MT6315_SRCLKEN0, 1, 1, HW_LP);
310#endif
311#endif
312}
313
314static void mt6315_S5_lp_initial_setting(void)
315{
316#if LP_INIT_SETTING_VERIFIED
317 mt6315_vdig18_hw_op_set(MT6315_SLAVE_ID_5, 1);
318 /* vproc/vmdd2 */
319 mt6315_lp_set(MT6315_SLAVE_ID_5, 1, MT6315_SRCLKEN0, 1, 1, HW_LP);
320 mt6315_lp_set(MT6315_SLAVE_ID_5, 3, MT6315_SRCLKEN0, 1, 1, HW_LP);
321#endif
322}
323
324static void mt6315_S6_lp_initial_setting(void)
325{
326#if LP_INIT_SETTING_VERIFIED
327#if defined(CONFIG_MACH_MT6885) || defined(CONFIG_MACH_MT6873)
328 mt6315_vdig18_hw_op_set(MT6315_SLAVE_ID_6, 1);
329#endif
330#endif
331}
332
333static void mt6315_S7_lp_initial_setting(void)
334{
335#if LP_INIT_SETTING_VERIFIED
336#if defined(CONFIG_MACH_MT6885)
337 mt6315_vdig18_hw_op_set(MT6315_SLAVE_ID_7, 1);
338 /* vsram_core */
339 mt6315_lp_set(MT6315_SLAVE_ID_7, 3, MT6315_SRCLKEN0, 1, 1, HW_LP);
340#elif defined(CONFIG_MACH_MT6873)
341 mt6315_vdig18_hw_op_set(MT6315_SLAVE_ID_7, 1);
342#endif
343#endif
344}
345
346static void mt6315_misc_initial_setting(u32 sid)
347{
348 switch (sid) {
349 case MT6315_SLAVE_ID_3:
350 mt6315_S3_lp_initial_setting();
351 mt6315_S3_default_vosel();
352 break;
353
354 case MT6315_SLAVE_ID_5:
355 mt6315_S5_lp_initial_setting();
356 break;
357
358 case MT6315_SLAVE_ID_6:
359 mt6315_S6_lp_initial_setting();
360 break;
361
362 case MT6315_SLAVE_ID_7:
363 mt6315_S7_lp_initial_setting();
364 break;
365
366 default:
367 pr_info("unsupported chip sid: %d\n", sid);
368 return;
369 }
370}
371
372void mt6315_misc_init(u32 sid, struct regmap *regmap)
373{
374 struct mt6315_misc *mt6315;
375
376 mt6315 = mt6315_find_chip_sid(sid);
377 if (mt6315)
378 mt6315->regmap = regmap;
379
380 mt6315_misc_initial_setting(sid);
381
382 pr_info("%s sid=%d done\n", __func__, sid);
383}