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