Commit | Line | Data |
---|---|---|
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 | */ | |
25 | struct 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 | 232 | static const unsigned int vdram2_voltages[] = { |
f67ff1bd HHW |
233 | 600000, 1800000, |
234 | }; | |
235 | ||
431ea63b | 236 | static const unsigned int vsim_voltages[] = { |
f67ff1bd HHW |
237 | 1700000, 1800000, 2700000, 3000000, 3100000, |
238 | }; | |
239 | ||
431ea63b | 240 | static const unsigned int vibr_voltages[] = { |
f67ff1bd HHW |
241 | 1200000, 1300000, 1500000, 1800000, |
242 | 2000000, 2800000, 3000000, 3300000, | |
243 | }; | |
244 | ||
431ea63b | 245 | static const unsigned int vusb_voltages[] = { |
f67ff1bd HHW |
246 | 3000000, 3100000, |
247 | }; | |
248 | ||
431ea63b | 249 | static const unsigned int vcamd_voltages[] = { |
f67ff1bd HHW |
250 | 900000, 1000000, 1100000, 1200000, |
251 | 1300000, 1500000, 1800000, | |
252 | }; | |
253 | ||
431ea63b | 254 | static const unsigned int vefuse_voltages[] = { |
f67ff1bd HHW |
255 | 1700000, 1800000, 1900000, |
256 | }; | |
257 | ||
431ea63b | 258 | static const unsigned int vmch_vemc_voltages[] = { |
f67ff1bd HHW |
259 | 2900000, 3000000, 3300000, |
260 | }; | |
261 | ||
431ea63b | 262 | static const unsigned int vcama_voltages[] = { |
f67ff1bd HHW |
263 | 1800000, 2500000, 2700000, |
264 | 2800000, 2900000, 3000000, | |
265 | }; | |
266 | ||
65bae54e | 267 | static const unsigned int vcn33_voltages[] = { |
f67ff1bd HHW |
268 | 3300000, 3400000, 3500000, |
269 | }; | |
270 | ||
431ea63b | 271 | static const unsigned int vmc_voltages[] = { |
f67ff1bd HHW |
272 | 1800000, 2900000, 3000000, 3300000, |
273 | }; | |
274 | ||
431ea63b | 275 | static const unsigned int vldo28_voltages[] = { |
f67ff1bd HHW |
276 | 2800000, 3000000, |
277 | }; | |
278 | ||
279 | static const u32 vdram2_idx[] = { | |
280 | 0, 12, | |
281 | }; | |
282 | ||
283 | static const u32 vsim_idx[] = { | |
284 | 3, 4, 8, 11, 12, | |
285 | }; | |
286 | ||
287 | static const u32 vibr_idx[] = { | |
288 | 0, 1, 2, 4, 5, 9, 11, 13, | |
289 | }; | |
290 | ||
291 | static const u32 vusb_idx[] = { | |
292 | 3, 4, | |
293 | }; | |
294 | ||
295 | static const u32 vcamd_idx[] = { | |
296 | 3, 4, 5, 6, 7, 9, 12, | |
297 | }; | |
298 | ||
299 | static const u32 vefuse_idx[] = { | |
300 | 11, 12, 13, | |
301 | }; | |
302 | ||
303 | static const u32 vmch_vemc_idx[] = { | |
304 | 2, 3, 5, | |
305 | }; | |
306 | ||
307 | static const u32 vcama_idx[] = { | |
308 | 0, 7, 9, 10, 11, 12, | |
309 | }; | |
310 | ||
65bae54e | 311 | static const u32 vcn33_idx[] = { |
f67ff1bd HHW |
312 | 1, 2, 3, |
313 | }; | |
314 | ||
315 | static const u32 vmc_idx[] = { | |
316 | 4, 10, 11, 13, | |
317 | }; | |
318 | ||
319 | static const u32 vldo28_idx[] = { | |
320 | 1, 3, | |
321 | }; | |
322 | ||
323 | static 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 | ||
329 | static 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 | ||
346 | static 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 | ||
372 | static 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, ®val); | |
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 | ||
390 | static 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, ®val); | |
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 | ||
405 | static 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 | ||
431 | static 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, ®val); | |
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 | ||
453 | static 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 | ||
467 | static 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 | ||
479 | static 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 | 488 | static 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 | 566 | static 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 |
632 | static 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) { | |
67cb6088 | 664 | dev_err(dev, "Failed to disable VCN33_WIFI\n"); |
65bae54e CYT |
665 | return ret; |
666 | } | |
667 | ||
668 | return 0; | |
669 | } | |
670 | ||
f67ff1bd HHW |
671 | static 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 | ||
7442edec CYT |
679 | switch (mt6397->chip_id) { |
680 | case MT6358_CHIP_ID: | |
f0e3c626 JW |
681 | max_regulator = MT6358_MAX_REGULATOR; |
682 | mt6358_info = mt6358_regulators; | |
7442edec CYT |
683 | break; |
684 | case MT6366_CHIP_ID: | |
685 | max_regulator = MT6366_MAX_REGULATOR; | |
686 | mt6358_info = mt6366_regulators; | |
687 | break; | |
688 | default: | |
689 | dev_err(&pdev->dev, "unsupported chip ID: %d\n", mt6397->chip_id); | |
690 | return -EINVAL; | |
f0e3c626 | 691 | } |
f67ff1bd | 692 | |
649fee5a CYT |
693 | ret = mt6358_sync_vcn33_setting(&pdev->dev); |
694 | if (ret) | |
695 | return ret; | |
696 | ||
f0e3c626 | 697 | for (i = 0; i < max_regulator; i++) { |
f67ff1bd | 698 | config.dev = &pdev->dev; |
f67ff1bd HHW |
699 | config.regmap = mt6397->regmap; |
700 | ||
701 | rdev = devm_regulator_register(&pdev->dev, | |
f0e3c626 | 702 | &mt6358_info[i].desc, |
f67ff1bd HHW |
703 | &config); |
704 | if (IS_ERR(rdev)) { | |
705 | dev_err(&pdev->dev, "failed to register %s\n", | |
f0e3c626 | 706 | mt6358_info[i].desc.name); |
f67ff1bd HHW |
707 | return PTR_ERR(rdev); |
708 | } | |
709 | } | |
710 | ||
711 | return 0; | |
712 | } | |
713 | ||
714 | static const struct platform_device_id mt6358_platform_ids[] = { | |
715 | {"mt6358-regulator", 0}, | |
716 | { /* sentinel */ }, | |
717 | }; | |
718 | MODULE_DEVICE_TABLE(platform, mt6358_platform_ids); | |
719 | ||
720 | static struct platform_driver mt6358_regulator_driver = { | |
721 | .driver = { | |
722 | .name = "mt6358-regulator", | |
d3b81d97 | 723 | .probe_type = PROBE_PREFER_ASYNCHRONOUS, |
f67ff1bd HHW |
724 | }, |
725 | .probe = mt6358_regulator_probe, | |
726 | .id_table = mt6358_platform_ids, | |
727 | }; | |
728 | ||
729 | module_platform_driver(mt6358_regulator_driver); | |
730 | ||
731 | MODULE_AUTHOR("Hsin-Hsiung Wang <hsin-hsiung.wang@mediatek.com>"); | |
732 | MODULE_DESCRIPTION("Regulator Driver for MediaTek MT6358 PMIC"); | |
733 | MODULE_LICENSE("GPL"); |