Merge tag 'hwmon-for-v6.5' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck...
[linux-block.git] / drivers / regulator / mt6358-regulator.c
CommitLineData
f67ff1bd
HHW
1// SPDX-License-Identifier: GPL-2.0
2//
3// Copyright (c) 2019 MediaTek Inc.
4
5#include <linux/mfd/mt6358/registers.h>
6#include <linux/mfd/mt6397/core.h>
7#include <linux/module.h>
8#include <linux/of.h>
9#include <linux/platform_device.h>
10#include <linux/regmap.h>
11#include <linux/regulator/driver.h>
12#include <linux/regulator/machine.h>
13#include <linux/regulator/mt6358-regulator.h>
14#include <linux/regulator/of_regulator.h>
15
16#define MT6358_BUCK_MODE_AUTO 0
17#define MT6358_BUCK_MODE_FORCE_PWM 1
18
19/*
20 * MT6358 regulators' information
21 *
22 * @desc: standard fields of regulator description.
23 * @qi: Mask for query enable signal status of regulators
24 */
25struct mt6358_regulator_info {
26 struct regulator_desc desc;
27 u32 status_reg;
28 u32 qi;
29 const u32 *index_table;
30 unsigned int n_table;
f67ff1bd
HHW
31 u32 da_vsel_reg;
32 u32 da_vsel_mask;
f67ff1bd
HHW
33 u32 modeset_reg;
34 u32 modeset_mask;
f67ff1bd
HHW
35};
36
1ff35e66
CYT
37#define to_regulator_info(x) container_of((x), struct mt6358_regulator_info, desc)
38
f67ff1bd 39#define MT6358_BUCK(match, vreg, min, max, step, \
ea861df7 40 vosel_mask, _da_vsel_reg, _da_vsel_mask, \
b99b7b79 41 _modeset_reg, _modeset_shift) \
f67ff1bd
HHW
42[MT6358_ID_##vreg] = { \
43 .desc = { \
44 .name = #vreg, \
45 .of_match = of_match_ptr(match), \
46 .ops = &mt6358_volt_range_ops, \
47 .type = REGULATOR_VOLTAGE, \
48 .id = MT6358_ID_##vreg, \
49 .owner = THIS_MODULE, \
50 .n_voltages = ((max) - (min)) / (step) + 1, \
ea861df7
CYT
51 .min_uV = (min), \
52 .uV_step = (step), \
f67ff1bd
HHW
53 .vsel_reg = MT6358_BUCK_##vreg##_ELR0, \
54 .vsel_mask = vosel_mask, \
55 .enable_reg = MT6358_BUCK_##vreg##_CON0, \
56 .enable_mask = BIT(0), \
57 .of_map_mode = mt6358_map_mode, \
58 }, \
59 .status_reg = MT6358_BUCK_##vreg##_DBG1, \
60 .qi = BIT(0), \
61 .da_vsel_reg = _da_vsel_reg, \
62 .da_vsel_mask = _da_vsel_mask, \
f67ff1bd
HHW
63 .modeset_reg = _modeset_reg, \
64 .modeset_mask = BIT(_modeset_shift), \
f67ff1bd
HHW
65}
66
67#define MT6358_LDO(match, vreg, ldo_volt_table, \
68 ldo_index_table, enreg, enbit, vosel, \
b99b7b79 69 vosel_mask) \
f67ff1bd
HHW
70[MT6358_ID_##vreg] = { \
71 .desc = { \
72 .name = #vreg, \
73 .of_match = of_match_ptr(match), \
74 .ops = &mt6358_volt_table_ops, \
75 .type = REGULATOR_VOLTAGE, \
76 .id = MT6358_ID_##vreg, \
77 .owner = THIS_MODULE, \
78 .n_voltages = ARRAY_SIZE(ldo_volt_table), \
79 .volt_table = ldo_volt_table, \
80 .vsel_reg = vosel, \
81 .vsel_mask = vosel_mask, \
82 .enable_reg = enreg, \
83 .enable_mask = BIT(enbit), \
84 }, \
85 .status_reg = MT6358_LDO_##vreg##_CON1, \
86 .qi = BIT(15), \
87 .index_table = ldo_index_table, \
88 .n_table = ARRAY_SIZE(ldo_index_table), \
f67ff1bd
HHW
89}
90
91#define MT6358_LDO1(match, vreg, min, max, step, \
ea861df7 92 _da_vsel_reg, _da_vsel_mask, \
b99b7b79 93 vosel, vosel_mask) \
f67ff1bd
HHW
94[MT6358_ID_##vreg] = { \
95 .desc = { \
96 .name = #vreg, \
97 .of_match = of_match_ptr(match), \
98 .ops = &mt6358_volt_range_ops, \
99 .type = REGULATOR_VOLTAGE, \
100 .id = MT6358_ID_##vreg, \
101 .owner = THIS_MODULE, \
102 .n_voltages = ((max) - (min)) / (step) + 1, \
ea861df7
CYT
103 .min_uV = (min), \
104 .uV_step = (step), \
f67ff1bd
HHW
105 .vsel_reg = vosel, \
106 .vsel_mask = vosel_mask, \
107 .enable_reg = MT6358_LDO_##vreg##_CON0, \
108 .enable_mask = BIT(0), \
109 }, \
110 .da_vsel_reg = _da_vsel_reg, \
111 .da_vsel_mask = _da_vsel_mask, \
f67ff1bd
HHW
112 .status_reg = MT6358_LDO_##vreg##_DBG1, \
113 .qi = BIT(0), \
114}
115
116#define MT6358_REG_FIXED(match, vreg, \
117 enreg, enbit, volt) \
118[MT6358_ID_##vreg] = { \
119 .desc = { \
120 .name = #vreg, \
121 .of_match = of_match_ptr(match), \
122 .ops = &mt6358_volt_fixed_ops, \
123 .type = REGULATOR_VOLTAGE, \
124 .id = MT6358_ID_##vreg, \
125 .owner = THIS_MODULE, \
126 .n_voltages = 1, \
127 .enable_reg = enreg, \
128 .enable_mask = BIT(enbit), \
129 .min_uV = volt, \
130 }, \
131 .status_reg = MT6358_LDO_##vreg##_CON1, \
132 .qi = BIT(15), \
133}
134
f0e3c626 135#define MT6366_BUCK(match, vreg, min, max, step, \
ea861df7 136 vosel_mask, _da_vsel_reg, _da_vsel_mask, \
f0e3c626
JW
137 _modeset_reg, _modeset_shift) \
138[MT6366_ID_##vreg] = { \
139 .desc = { \
140 .name = #vreg, \
141 .of_match = of_match_ptr(match), \
142 .ops = &mt6358_volt_range_ops, \
143 .type = REGULATOR_VOLTAGE, \
144 .id = MT6366_ID_##vreg, \
145 .owner = THIS_MODULE, \
146 .n_voltages = ((max) - (min)) / (step) + 1, \
ea861df7
CYT
147 .min_uV = (min), \
148 .uV_step = (step), \
f0e3c626
JW
149 .vsel_reg = MT6358_BUCK_##vreg##_ELR0, \
150 .vsel_mask = vosel_mask, \
151 .enable_reg = MT6358_BUCK_##vreg##_CON0, \
152 .enable_mask = BIT(0), \
153 .of_map_mode = mt6358_map_mode, \
154 }, \
155 .status_reg = MT6358_BUCK_##vreg##_DBG1, \
156 .qi = BIT(0), \
157 .da_vsel_reg = _da_vsel_reg, \
158 .da_vsel_mask = _da_vsel_mask, \
159 .modeset_reg = _modeset_reg, \
160 .modeset_mask = BIT(_modeset_shift), \
161}
162
163#define MT6366_LDO(match, vreg, ldo_volt_table, \
164 ldo_index_table, enreg, enbit, vosel, \
165 vosel_mask) \
166[MT6366_ID_##vreg] = { \
167 .desc = { \
168 .name = #vreg, \
169 .of_match = of_match_ptr(match), \
170 .ops = &mt6358_volt_table_ops, \
171 .type = REGULATOR_VOLTAGE, \
172 .id = MT6366_ID_##vreg, \
173 .owner = THIS_MODULE, \
174 .n_voltages = ARRAY_SIZE(ldo_volt_table), \
175 .volt_table = ldo_volt_table, \
176 .vsel_reg = vosel, \
177 .vsel_mask = vosel_mask, \
178 .enable_reg = enreg, \
179 .enable_mask = BIT(enbit), \
180 }, \
181 .status_reg = MT6358_LDO_##vreg##_CON1, \
182 .qi = BIT(15), \
183 .index_table = ldo_index_table, \
184 .n_table = ARRAY_SIZE(ldo_index_table), \
185}
186
187#define MT6366_LDO1(match, vreg, min, max, step, \
ea861df7 188 _da_vsel_reg, _da_vsel_mask, \
f0e3c626
JW
189 vosel, vosel_mask) \
190[MT6366_ID_##vreg] = { \
191 .desc = { \
192 .name = #vreg, \
193 .of_match = of_match_ptr(match), \
194 .ops = &mt6358_volt_range_ops, \
195 .type = REGULATOR_VOLTAGE, \
196 .id = MT6366_ID_##vreg, \
197 .owner = THIS_MODULE, \
198 .n_voltages = ((max) - (min)) / (step) + 1, \
ea861df7
CYT
199 .min_uV = (min), \
200 .uV_step = (step), \
f0e3c626
JW
201 .vsel_reg = vosel, \
202 .vsel_mask = vosel_mask, \
203 .enable_reg = MT6358_LDO_##vreg##_CON0, \
204 .enable_mask = BIT(0), \
205 }, \
206 .da_vsel_reg = _da_vsel_reg, \
207 .da_vsel_mask = _da_vsel_mask, \
208 .status_reg = MT6358_LDO_##vreg##_DBG1, \
209 .qi = BIT(0), \
210}
211
212#define MT6366_REG_FIXED(match, vreg, \
213 enreg, enbit, volt) \
214[MT6366_ID_##vreg] = { \
215 .desc = { \
216 .name = #vreg, \
217 .of_match = of_match_ptr(match), \
218 .ops = &mt6358_volt_fixed_ops, \
219 .type = REGULATOR_VOLTAGE, \
220 .id = MT6366_ID_##vreg, \
221 .owner = THIS_MODULE, \
222 .n_voltages = 1, \
223 .enable_reg = enreg, \
224 .enable_mask = BIT(enbit), \
225 .min_uV = volt, \
226 }, \
227 .status_reg = MT6358_LDO_##vreg##_CON1, \
228 .qi = BIT(15), \
229}
230
f67ff1bd 231
431ea63b 232static const unsigned int vdram2_voltages[] = {
f67ff1bd
HHW
233 600000, 1800000,
234};
235
431ea63b 236static const unsigned int vsim_voltages[] = {
f67ff1bd
HHW
237 1700000, 1800000, 2700000, 3000000, 3100000,
238};
239
431ea63b 240static const unsigned int vibr_voltages[] = {
f67ff1bd
HHW
241 1200000, 1300000, 1500000, 1800000,
242 2000000, 2800000, 3000000, 3300000,
243};
244
431ea63b 245static const unsigned int vusb_voltages[] = {
f67ff1bd
HHW
246 3000000, 3100000,
247};
248
431ea63b 249static const unsigned int vcamd_voltages[] = {
f67ff1bd
HHW
250 900000, 1000000, 1100000, 1200000,
251 1300000, 1500000, 1800000,
252};
253
431ea63b 254static const unsigned int vefuse_voltages[] = {
f67ff1bd
HHW
255 1700000, 1800000, 1900000,
256};
257
431ea63b 258static const unsigned int vmch_vemc_voltages[] = {
f67ff1bd
HHW
259 2900000, 3000000, 3300000,
260};
261
431ea63b 262static const unsigned int vcama_voltages[] = {
f67ff1bd
HHW
263 1800000, 2500000, 2700000,
264 2800000, 2900000, 3000000,
265};
266
65bae54e 267static const unsigned int vcn33_voltages[] = {
f67ff1bd
HHW
268 3300000, 3400000, 3500000,
269};
270
431ea63b 271static const unsigned int vmc_voltages[] = {
f67ff1bd
HHW
272 1800000, 2900000, 3000000, 3300000,
273};
274
431ea63b 275static const unsigned int vldo28_voltages[] = {
f67ff1bd
HHW
276 2800000, 3000000,
277};
278
279static const u32 vdram2_idx[] = {
280 0, 12,
281};
282
283static const u32 vsim_idx[] = {
284 3, 4, 8, 11, 12,
285};
286
287static const u32 vibr_idx[] = {
288 0, 1, 2, 4, 5, 9, 11, 13,
289};
290
291static const u32 vusb_idx[] = {
292 3, 4,
293};
294
295static const u32 vcamd_idx[] = {
296 3, 4, 5, 6, 7, 9, 12,
297};
298
299static const u32 vefuse_idx[] = {
300 11, 12, 13,
301};
302
303static const u32 vmch_vemc_idx[] = {
304 2, 3, 5,
305};
306
307static const u32 vcama_idx[] = {
308 0, 7, 9, 10, 11, 12,
309};
310
65bae54e 311static const u32 vcn33_idx[] = {
f67ff1bd
HHW
312 1, 2, 3,
313};
314
315static const u32 vmc_idx[] = {
316 4, 10, 11, 13,
317};
318
319static const u32 vldo28_idx[] = {
320 1, 3,
321};
322
323static unsigned int mt6358_map_mode(unsigned int mode)
324{
325 return mode == MT6358_BUCK_MODE_AUTO ?
326 REGULATOR_MODE_NORMAL : REGULATOR_MODE_FAST;
327}
328
329static int mt6358_set_voltage_sel(struct regulator_dev *rdev,
330 unsigned int selector)
331{
1ff35e66 332 const struct mt6358_regulator_info *info = to_regulator_info(rdev->desc);
f67ff1bd
HHW
333 int idx, ret;
334 const u32 *pvol;
f67ff1bd
HHW
335
336 pvol = info->index_table;
337
338 idx = pvol[selector];
b99b7b79 339 idx <<= ffs(info->desc.vsel_mask) - 1;
f67ff1bd 340 ret = regmap_update_bits(rdev->regmap, info->desc.vsel_reg,
b99b7b79 341 info->desc.vsel_mask, idx);
f67ff1bd
HHW
342
343 return ret;
344}
345
346static int mt6358_get_voltage_sel(struct regulator_dev *rdev)
347{
1ff35e66 348 const struct mt6358_regulator_info *info = to_regulator_info(rdev->desc);
f67ff1bd
HHW
349 int idx, ret;
350 u32 selector;
f67ff1bd
HHW
351 const u32 *pvol;
352
353 ret = regmap_read(rdev->regmap, info->desc.vsel_reg, &selector);
354 if (ret != 0) {
355 dev_info(&rdev->dev,
356 "Failed to get mt6358 %s vsel reg: %d\n",
357 info->desc.name, ret);
358 return ret;
359 }
360
b99b7b79
AL
361 selector = (selector & info->desc.vsel_mask) >>
362 (ffs(info->desc.vsel_mask) - 1);
f67ff1bd
HHW
363 pvol = info->index_table;
364 for (idx = 0; idx < info->desc.n_voltages; idx++) {
365 if (pvol[idx] == selector)
366 return idx;
367 }
368
369 return -EINVAL;
370}
371
372static int mt6358_get_buck_voltage_sel(struct regulator_dev *rdev)
373{
1ff35e66 374 const struct mt6358_regulator_info *info = to_regulator_info(rdev->desc);
f67ff1bd 375 int ret, regval;
f67ff1bd
HHW
376
377 ret = regmap_read(rdev->regmap, info->da_vsel_reg, &regval);
378 if (ret != 0) {
379 dev_err(&rdev->dev,
380 "Failed to get mt6358 Buck %s vsel reg: %d\n",
381 info->desc.name, ret);
382 return ret;
383 }
384
b99b7b79 385 ret = (regval & info->da_vsel_mask) >> (ffs(info->da_vsel_mask) - 1);
f67ff1bd
HHW
386
387 return ret;
388}
389
390static int mt6358_get_status(struct regulator_dev *rdev)
391{
1ff35e66 392 const struct mt6358_regulator_info *info = to_regulator_info(rdev->desc);
f67ff1bd
HHW
393 int ret;
394 u32 regval;
f67ff1bd
HHW
395
396 ret = regmap_read(rdev->regmap, info->status_reg, &regval);
397 if (ret != 0) {
398 dev_info(&rdev->dev, "Failed to get enable reg: %d\n", ret);
399 return ret;
400 }
401
402 return (regval & info->qi) ? REGULATOR_STATUS_ON : REGULATOR_STATUS_OFF;
403}
404
405static int mt6358_regulator_set_mode(struct regulator_dev *rdev,
406 unsigned int mode)
407{
1ff35e66 408 const struct mt6358_regulator_info *info = to_regulator_info(rdev->desc);
f67ff1bd
HHW
409 int val;
410
411 switch (mode) {
412 case REGULATOR_MODE_FAST:
413 val = MT6358_BUCK_MODE_FORCE_PWM;
414 break;
415 case REGULATOR_MODE_NORMAL:
416 val = MT6358_BUCK_MODE_AUTO;
417 break;
418 default:
419 return -EINVAL;
420 }
421
b99b7b79
AL
422 dev_dbg(&rdev->dev, "mt6358 buck set_mode %#x, %#x, %#x\n",
423 info->modeset_reg, info->modeset_mask, val);
f67ff1bd 424
b99b7b79 425 val <<= ffs(info->modeset_mask) - 1;
f67ff1bd
HHW
426
427 return regmap_update_bits(rdev->regmap, info->modeset_reg,
428 info->modeset_mask, val);
429}
430
431static unsigned int mt6358_regulator_get_mode(struct regulator_dev *rdev)
432{
1ff35e66 433 const struct mt6358_regulator_info *info = to_regulator_info(rdev->desc);
f67ff1bd
HHW
434 int ret, regval;
435
436 ret = regmap_read(rdev->regmap, info->modeset_reg, &regval);
437 if (ret != 0) {
438 dev_err(&rdev->dev,
439 "Failed to get mt6358 buck mode: %d\n", ret);
440 return ret;
441 }
442
b99b7b79 443 switch ((regval & info->modeset_mask) >> (ffs(info->modeset_mask) - 1)) {
f67ff1bd
HHW
444 case MT6358_BUCK_MODE_AUTO:
445 return REGULATOR_MODE_NORMAL;
446 case MT6358_BUCK_MODE_FORCE_PWM:
447 return REGULATOR_MODE_FAST;
448 default:
449 return -EINVAL;
450 }
451}
452
453static const struct regulator_ops mt6358_volt_range_ops = {
ea861df7
CYT
454 .list_voltage = regulator_list_voltage_linear,
455 .map_voltage = regulator_map_voltage_linear,
f67ff1bd
HHW
456 .set_voltage_sel = regulator_set_voltage_sel_regmap,
457 .get_voltage_sel = mt6358_get_buck_voltage_sel,
458 .set_voltage_time_sel = regulator_set_voltage_time_sel,
459 .enable = regulator_enable_regmap,
460 .disable = regulator_disable_regmap,
461 .is_enabled = regulator_is_enabled_regmap,
462 .get_status = mt6358_get_status,
463 .set_mode = mt6358_regulator_set_mode,
464 .get_mode = mt6358_regulator_get_mode,
465};
466
467static const struct regulator_ops mt6358_volt_table_ops = {
468 .list_voltage = regulator_list_voltage_table,
469 .map_voltage = regulator_map_voltage_iterate,
470 .set_voltage_sel = mt6358_set_voltage_sel,
471 .get_voltage_sel = mt6358_get_voltage_sel,
472 .set_voltage_time_sel = regulator_set_voltage_time_sel,
473 .enable = regulator_enable_regmap,
474 .disable = regulator_disable_regmap,
475 .is_enabled = regulator_is_enabled_regmap,
476 .get_status = mt6358_get_status,
477};
478
479static const struct regulator_ops mt6358_volt_fixed_ops = {
480 .list_voltage = regulator_list_voltage_linear,
481 .enable = regulator_enable_regmap,
482 .disable = regulator_disable_regmap,
483 .is_enabled = regulator_is_enabled_regmap,
484 .get_status = mt6358_get_status,
485};
486
487/* The array is indexed by id(MT6358_ID_XXX) */
1ff35e66 488static const struct mt6358_regulator_info mt6358_regulators[] = {
f67ff1bd 489 MT6358_BUCK("buck_vdram1", VDRAM1, 500000, 2087500, 12500,
ea861df7 490 0x7f, MT6358_BUCK_VDRAM1_DBG0, 0x7f, MT6358_VDRAM1_ANA_CON0, 8),
f67ff1bd 491 MT6358_BUCK("buck_vcore", VCORE, 500000, 1293750, 6250,
ea861df7 492 0x7f, MT6358_BUCK_VCORE_DBG0, 0x7f, MT6358_VCORE_VGPU_ANA_CON0, 1),
f67ff1bd 493 MT6358_BUCK("buck_vpa", VPA, 500000, 3650000, 50000,
ea861df7 494 0x3f, MT6358_BUCK_VPA_DBG0, 0x3f, MT6358_VPA_ANA_CON0, 3),
f67ff1bd 495 MT6358_BUCK("buck_vproc11", VPROC11, 500000, 1293750, 6250,
ea861df7 496 0x7f, MT6358_BUCK_VPROC11_DBG0, 0x7f, MT6358_VPROC_ANA_CON0, 1),
f67ff1bd 497 MT6358_BUCK("buck_vproc12", VPROC12, 500000, 1293750, 6250,
ea861df7 498 0x7f, MT6358_BUCK_VPROC12_DBG0, 0x7f, MT6358_VPROC_ANA_CON0, 2),
f67ff1bd 499 MT6358_BUCK("buck_vgpu", VGPU, 500000, 1293750, 6250,
ea861df7 500 0x7f, MT6358_BUCK_VGPU_ELR0, 0x7f, MT6358_VCORE_VGPU_ANA_CON0, 2),
f67ff1bd 501 MT6358_BUCK("buck_vs2", VS2, 500000, 2087500, 12500,
ea861df7 502 0x7f, MT6358_BUCK_VS2_DBG0, 0x7f, MT6358_VS2_ANA_CON0, 8),
f67ff1bd 503 MT6358_BUCK("buck_vmodem", VMODEM, 500000, 1293750, 6250,
ea861df7 504 0x7f, MT6358_BUCK_VMODEM_DBG0, 0x7f, MT6358_VMODEM_ANA_CON0, 8),
f67ff1bd 505 MT6358_BUCK("buck_vs1", VS1, 1000000, 2587500, 12500,
ea861df7 506 0x7f, MT6358_BUCK_VS1_DBG0, 0x7f, MT6358_VS1_ANA_CON0, 8),
f67ff1bd
HHW
507 MT6358_REG_FIXED("ldo_vrf12", VRF12,
508 MT6358_LDO_VRF12_CON0, 0, 1200000),
509 MT6358_REG_FIXED("ldo_vio18", VIO18,
510 MT6358_LDO_VIO18_CON0, 0, 1800000),
511 MT6358_REG_FIXED("ldo_vcamio", VCAMIO,
512 MT6358_LDO_VCAMIO_CON0, 0, 1800000),
513 MT6358_REG_FIXED("ldo_vcn18", VCN18, MT6358_LDO_VCN18_CON0, 0, 1800000),
514 MT6358_REG_FIXED("ldo_vfe28", VFE28, MT6358_LDO_VFE28_CON0, 0, 2800000),
515 MT6358_REG_FIXED("ldo_vcn28", VCN28, MT6358_LDO_VCN28_CON0, 0, 2800000),
516 MT6358_REG_FIXED("ldo_vxo22", VXO22, MT6358_LDO_VXO22_CON0, 0, 2200000),
517 MT6358_REG_FIXED("ldo_vaux18", VAUX18,
518 MT6358_LDO_VAUX18_CON0, 0, 1800000),
519 MT6358_REG_FIXED("ldo_vbif28", VBIF28,
520 MT6358_LDO_VBIF28_CON0, 0, 2800000),
521 MT6358_REG_FIXED("ldo_vio28", VIO28, MT6358_LDO_VIO28_CON0, 0, 2800000),
522 MT6358_REG_FIXED("ldo_va12", VA12, MT6358_LDO_VA12_CON0, 0, 1200000),
523 MT6358_REG_FIXED("ldo_vrf18", VRF18, MT6358_LDO_VRF18_CON0, 0, 1800000),
524 MT6358_REG_FIXED("ldo_vaud28", VAUD28,
525 MT6358_LDO_VAUD28_CON0, 0, 2800000),
526 MT6358_LDO("ldo_vdram2", VDRAM2, vdram2_voltages, vdram2_idx,
b99b7b79 527 MT6358_LDO_VDRAM2_CON0, 0, MT6358_LDO_VDRAM2_ELR0, 0xf),
f67ff1bd 528 MT6358_LDO("ldo_vsim1", VSIM1, vsim_voltages, vsim_idx,
b99b7b79 529 MT6358_LDO_VSIM1_CON0, 0, MT6358_VSIM1_ANA_CON0, 0xf00),
f67ff1bd 530 MT6358_LDO("ldo_vibr", VIBR, vibr_voltages, vibr_idx,
b99b7b79 531 MT6358_LDO_VIBR_CON0, 0, MT6358_VIBR_ANA_CON0, 0xf00),
f67ff1bd 532 MT6358_LDO("ldo_vusb", VUSB, vusb_voltages, vusb_idx,
b99b7b79 533 MT6358_LDO_VUSB_CON0_0, 0, MT6358_VUSB_ANA_CON0, 0x700),
f67ff1bd 534 MT6358_LDO("ldo_vcamd", VCAMD, vcamd_voltages, vcamd_idx,
b99b7b79 535 MT6358_LDO_VCAMD_CON0, 0, MT6358_VCAMD_ANA_CON0, 0xf00),
f67ff1bd 536 MT6358_LDO("ldo_vefuse", VEFUSE, vefuse_voltages, vefuse_idx,
b99b7b79 537 MT6358_LDO_VEFUSE_CON0, 0, MT6358_VEFUSE_ANA_CON0, 0xf00),
f67ff1bd 538 MT6358_LDO("ldo_vmch", VMCH, vmch_vemc_voltages, vmch_vemc_idx,
b99b7b79 539 MT6358_LDO_VMCH_CON0, 0, MT6358_VMCH_ANA_CON0, 0x700),
f67ff1bd 540 MT6358_LDO("ldo_vcama1", VCAMA1, vcama_voltages, vcama_idx,
b99b7b79 541 MT6358_LDO_VCAMA1_CON0, 0, MT6358_VCAMA1_ANA_CON0, 0xf00),
f67ff1bd 542 MT6358_LDO("ldo_vemc", VEMC, vmch_vemc_voltages, vmch_vemc_idx,
b99b7b79 543 MT6358_LDO_VEMC_CON0, 0, MT6358_VEMC_ANA_CON0, 0x700),
65bae54e
CYT
544 MT6358_LDO("ldo_vcn33", VCN33, vcn33_voltages, vcn33_idx,
545 MT6358_LDO_VCN33_CON0_0, 0, MT6358_VCN33_ANA_CON0, 0x300),
f67ff1bd 546 MT6358_LDO("ldo_vcama2", VCAMA2, vcama_voltages, vcama_idx,
b99b7b79 547 MT6358_LDO_VCAMA2_CON0, 0, MT6358_VCAMA2_ANA_CON0, 0xf00),
f67ff1bd 548 MT6358_LDO("ldo_vmc", VMC, vmc_voltages, vmc_idx,
b99b7b79 549 MT6358_LDO_VMC_CON0, 0, MT6358_VMC_ANA_CON0, 0xf00),
f67ff1bd
HHW
550 MT6358_LDO("ldo_vldo28", VLDO28, vldo28_voltages, vldo28_idx,
551 MT6358_LDO_VLDO28_CON0_0, 0,
b99b7b79 552 MT6358_VLDO28_ANA_CON0, 0x300),
f67ff1bd 553 MT6358_LDO("ldo_vsim2", VSIM2, vsim_voltages, vsim_idx,
b99b7b79 554 MT6358_LDO_VSIM2_CON0, 0, MT6358_VSIM2_ANA_CON0, 0xf00),
f67ff1bd 555 MT6358_LDO1("ldo_vsram_proc11", VSRAM_PROC11, 500000, 1293750, 6250,
ea861df7 556 MT6358_LDO_VSRAM_PROC11_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON0, 0x7f),
f67ff1bd 557 MT6358_LDO1("ldo_vsram_others", VSRAM_OTHERS, 500000, 1293750, 6250,
ea861df7 558 MT6358_LDO_VSRAM_OTHERS_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON2, 0x7f),
f67ff1bd 559 MT6358_LDO1("ldo_vsram_gpu", VSRAM_GPU, 500000, 1293750, 6250,
ea861df7 560 MT6358_LDO_VSRAM_GPU_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON3, 0x7f),
f67ff1bd 561 MT6358_LDO1("ldo_vsram_proc12", VSRAM_PROC12, 500000, 1293750, 6250,
ea861df7 562 MT6358_LDO_VSRAM_PROC12_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON1, 0x7f),
f67ff1bd
HHW
563};
564
f0e3c626 565/* The array is indexed by id(MT6366_ID_XXX) */
1ff35e66 566static const struct mt6358_regulator_info mt6366_regulators[] = {
f0e3c626 567 MT6366_BUCK("buck_vdram1", VDRAM1, 500000, 2087500, 12500,
ea861df7 568 0x7f, MT6358_BUCK_VDRAM1_DBG0, 0x7f, MT6358_VDRAM1_ANA_CON0, 8),
f0e3c626 569 MT6366_BUCK("buck_vcore", VCORE, 500000, 1293750, 6250,
ea861df7 570 0x7f, MT6358_BUCK_VCORE_DBG0, 0x7f, MT6358_VCORE_VGPU_ANA_CON0, 1),
f0e3c626 571 MT6366_BUCK("buck_vpa", VPA, 500000, 3650000, 50000,
ea861df7 572 0x3f, MT6358_BUCK_VPA_DBG0, 0x3f, MT6358_VPA_ANA_CON0, 3),
f0e3c626 573 MT6366_BUCK("buck_vproc11", VPROC11, 500000, 1293750, 6250,
ea861df7 574 0x7f, MT6358_BUCK_VPROC11_DBG0, 0x7f, MT6358_VPROC_ANA_CON0, 1),
f0e3c626 575 MT6366_BUCK("buck_vproc12", VPROC12, 500000, 1293750, 6250,
ea861df7 576 0x7f, MT6358_BUCK_VPROC12_DBG0, 0x7f, MT6358_VPROC_ANA_CON0, 2),
f0e3c626 577 MT6366_BUCK("buck_vgpu", VGPU, 500000, 1293750, 6250,
ea861df7 578 0x7f, MT6358_BUCK_VGPU_ELR0, 0x7f, MT6358_VCORE_VGPU_ANA_CON0, 2),
f0e3c626 579 MT6366_BUCK("buck_vs2", VS2, 500000, 2087500, 12500,
ea861df7 580 0x7f, MT6358_BUCK_VS2_DBG0, 0x7f, MT6358_VS2_ANA_CON0, 8),
f0e3c626 581 MT6366_BUCK("buck_vmodem", VMODEM, 500000, 1293750, 6250,
ea861df7 582 0x7f, MT6358_BUCK_VMODEM_DBG0, 0x7f, MT6358_VMODEM_ANA_CON0, 8),
f0e3c626 583 MT6366_BUCK("buck_vs1", VS1, 1000000, 2587500, 12500,
ea861df7 584 0x7f, MT6358_BUCK_VS1_DBG0, 0x7f, MT6358_VS1_ANA_CON0, 8),
f0e3c626
JW
585 MT6366_REG_FIXED("ldo_vrf12", VRF12,
586 MT6358_LDO_VRF12_CON0, 0, 1200000),
587 MT6366_REG_FIXED("ldo_vio18", VIO18,
588 MT6358_LDO_VIO18_CON0, 0, 1800000),
589 MT6366_REG_FIXED("ldo_vcn18", VCN18, MT6358_LDO_VCN18_CON0, 0, 1800000),
590 MT6366_REG_FIXED("ldo_vfe28", VFE28, MT6358_LDO_VFE28_CON0, 0, 2800000),
591 MT6366_REG_FIXED("ldo_vcn28", VCN28, MT6358_LDO_VCN28_CON0, 0, 2800000),
592 MT6366_REG_FIXED("ldo_vxo22", VXO22, MT6358_LDO_VXO22_CON0, 0, 2200000),
593 MT6366_REG_FIXED("ldo_vaux18", VAUX18,
594 MT6358_LDO_VAUX18_CON0, 0, 1800000),
595 MT6366_REG_FIXED("ldo_vbif28", VBIF28,
596 MT6358_LDO_VBIF28_CON0, 0, 2800000),
597 MT6366_REG_FIXED("ldo_vio28", VIO28, MT6358_LDO_VIO28_CON0, 0, 2800000),
598 MT6366_REG_FIXED("ldo_va12", VA12, MT6358_LDO_VA12_CON0, 0, 1200000),
599 MT6366_REG_FIXED("ldo_vrf18", VRF18, MT6358_LDO_VRF18_CON0, 0, 1800000),
600 MT6366_REG_FIXED("ldo_vaud28", VAUD28,
601 MT6358_LDO_VAUD28_CON0, 0, 2800000),
602 MT6366_LDO("ldo_vdram2", VDRAM2, vdram2_voltages, vdram2_idx,
603 MT6358_LDO_VDRAM2_CON0, 0, MT6358_LDO_VDRAM2_ELR0, 0x10),
604 MT6366_LDO("ldo_vsim1", VSIM1, vsim_voltages, vsim_idx,
605 MT6358_LDO_VSIM1_CON0, 0, MT6358_VSIM1_ANA_CON0, 0xf00),
606 MT6366_LDO("ldo_vibr", VIBR, vibr_voltages, vibr_idx,
607 MT6358_LDO_VIBR_CON0, 0, MT6358_VIBR_ANA_CON0, 0xf00),
608 MT6366_LDO("ldo_vusb", VUSB, vusb_voltages, vusb_idx,
609 MT6358_LDO_VUSB_CON0_0, 0, MT6358_VUSB_ANA_CON0, 0x700),
610 MT6366_LDO("ldo_vefuse", VEFUSE, vefuse_voltages, vefuse_idx,
611 MT6358_LDO_VEFUSE_CON0, 0, MT6358_VEFUSE_ANA_CON0, 0xf00),
612 MT6366_LDO("ldo_vmch", VMCH, vmch_vemc_voltages, vmch_vemc_idx,
613 MT6358_LDO_VMCH_CON0, 0, MT6358_VMCH_ANA_CON0, 0x700),
614 MT6366_LDO("ldo_vemc", VEMC, vmch_vemc_voltages, vmch_vemc_idx,
615 MT6358_LDO_VEMC_CON0, 0, MT6358_VEMC_ANA_CON0, 0x700),
65bae54e
CYT
616 MT6366_LDO("ldo_vcn33", VCN33, vcn33_voltages, vcn33_idx,
617 MT6358_LDO_VCN33_CON0_0, 0, MT6358_VCN33_ANA_CON0, 0x300),
f0e3c626
JW
618 MT6366_LDO("ldo_vmc", VMC, vmc_voltages, vmc_idx,
619 MT6358_LDO_VMC_CON0, 0, MT6358_VMC_ANA_CON0, 0xf00),
620 MT6366_LDO("ldo_vsim2", VSIM2, vsim_voltages, vsim_idx,
621 MT6358_LDO_VSIM2_CON0, 0, MT6358_VSIM2_ANA_CON0, 0xf00),
622 MT6366_LDO1("ldo_vsram_proc11", VSRAM_PROC11, 500000, 1293750, 6250,
ea861df7 623 MT6358_LDO_VSRAM_PROC11_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON0, 0x7f),
f0e3c626 624 MT6366_LDO1("ldo_vsram_others", VSRAM_OTHERS, 500000, 1293750, 6250,
ea861df7 625 MT6358_LDO_VSRAM_OTHERS_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON2, 0x7f),
f0e3c626 626 MT6366_LDO1("ldo_vsram_gpu", VSRAM_GPU, 500000, 1293750, 6250,
ea861df7 627 MT6358_LDO_VSRAM_GPU_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON3, 0x7f),
f0e3c626 628 MT6366_LDO1("ldo_vsram_proc12", VSRAM_PROC12, 500000, 1293750, 6250,
ea861df7 629 MT6358_LDO_VSRAM_PROC12_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON1, 0x7f),
f0e3c626
JW
630};
631
65bae54e
CYT
632static int mt6358_sync_vcn33_setting(struct device *dev)
633{
634 struct mt6397_chip *mt6397 = dev_get_drvdata(dev->parent);
635 unsigned int val;
636 int ret;
637
638 /*
639 * VCN33_WIFI and VCN33_BT are two separate enable bits for the same
640 * regulator. They share the same voltage setting and output pin.
641 * Instead of having two potentially conflicting regulators, just have
642 * one VCN33 regulator. Sync the two enable bits and only use one in
643 * the regulator device.
644 */
645 ret = regmap_read(mt6397->regmap, MT6358_LDO_VCN33_CON0_1, &val);
646 if (ret) {
647 dev_err(dev, "Failed to read VCN33_WIFI setting\n");
648 return ret;
649 }
650
651 if (!(val & BIT(0)))
652 return 0;
653
654 /* Sync VCN33_WIFI enable status to VCN33_BT */
655 ret = regmap_update_bits(mt6397->regmap, MT6358_LDO_VCN33_CON0_0, BIT(0), BIT(0));
656 if (ret) {
657 dev_err(dev, "Failed to sync VCN33_WIFI setting to VCN33_BT\n");
658 return ret;
659 }
660
661 /* Disable VCN33_WIFI */
662 ret = regmap_update_bits(mt6397->regmap, MT6358_LDO_VCN33_CON0_1, BIT(0), 0);
663 if (ret) {
664 dev_err(dev, "Failed to disable VCN33_BT\n");
665 return ret;
666 }
667
668 return 0;
669}
670
f67ff1bd
HHW
671static int mt6358_regulator_probe(struct platform_device *pdev)
672{
673 struct mt6397_chip *mt6397 = dev_get_drvdata(pdev->dev.parent);
674 struct regulator_config config = {};
675 struct regulator_dev *rdev;
1ff35e66 676 const struct mt6358_regulator_info *mt6358_info;
65bae54e
CYT
677 int i, max_regulator, ret;
678
679 ret = mt6358_sync_vcn33_setting(&pdev->dev);
680 if (ret)
681 return ret;
f0e3c626
JW
682
683 if (mt6397->chip_id == MT6366_CHIP_ID) {
684 max_regulator = MT6366_MAX_REGULATOR;
685 mt6358_info = mt6366_regulators;
686 } else {
687 max_regulator = MT6358_MAX_REGULATOR;
688 mt6358_info = mt6358_regulators;
689 }
f67ff1bd 690
f0e3c626 691 for (i = 0; i < max_regulator; i++) {
f67ff1bd 692 config.dev = &pdev->dev;
f67ff1bd
HHW
693 config.regmap = mt6397->regmap;
694
695 rdev = devm_regulator_register(&pdev->dev,
f0e3c626 696 &mt6358_info[i].desc,
f67ff1bd
HHW
697 &config);
698 if (IS_ERR(rdev)) {
699 dev_err(&pdev->dev, "failed to register %s\n",
f0e3c626 700 mt6358_info[i].desc.name);
f67ff1bd
HHW
701 return PTR_ERR(rdev);
702 }
703 }
704
705 return 0;
706}
707
708static const struct platform_device_id mt6358_platform_ids[] = {
709 {"mt6358-regulator", 0},
710 { /* sentinel */ },
711};
712MODULE_DEVICE_TABLE(platform, mt6358_platform_ids);
713
714static struct platform_driver mt6358_regulator_driver = {
715 .driver = {
716 .name = "mt6358-regulator",
d3b81d97 717 .probe_type = PROBE_PREFER_ASYNCHRONOUS,
f67ff1bd
HHW
718 },
719 .probe = mt6358_regulator_probe,
720 .id_table = mt6358_platform_ids,
721};
722
723module_platform_driver(mt6358_regulator_driver);
724
725MODULE_AUTHOR("Hsin-Hsiung Wang <hsin-hsiung.wang@mediatek.com>");
726MODULE_DESCRIPTION("Regulator Driver for MediaTek MT6358 PMIC");
727MODULE_LICENSE("GPL");