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