1 // SPDX-License-Identifier: GPL-2.0
3 // Copyright (c) 2022 Collabora Ltd.
4 // Author: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
6 // Based on mt6323-regulator.c,
7 // Copyright (c) 2016 MediaTek Inc.
10 #include <linux/module.h>
12 #include <linux/platform_device.h>
13 #include <linux/regmap.h>
14 #include <linux/mfd/mt6397/core.h>
15 #include <linux/mfd/mt6331/registers.h>
16 #include <linux/regulator/driver.h>
17 #include <linux/regulator/machine.h>
18 #include <linux/regulator/mt6331-regulator.h>
19 #include <linux/regulator/of_regulator.h>
21 #define MT6331_LDO_MODE_NORMAL 0
22 #define MT6331_LDO_MODE_LP 1
25 * MT6331 regulators information
27 * @desc: standard fields of regulator description.
28 * @qi: Mask for query enable signal status of regulators
29 * @vselon_reg: Register sections for hardware control mode of bucks
30 * @vselctrl_reg: Register for controlling the buck control mode.
31 * @vselctrl_mask: Mask for query buck's voltage control mode.
32 * @status_reg: Register for regulator enable status where qi unavailable
33 * @status_mask: Mask for querying regulator enable status
35 struct mt6331_regulator_info
{
36 struct regulator_desc desc
;
47 #define MT6331_BUCK(match, vreg, min, max, step, volt_ranges, enreg, \
48 vosel, vosel_mask, voselon, vosel_ctrl) \
49 [MT6331_ID_##vreg] = { \
52 .of_match = of_match_ptr(match), \
53 .ops = &mt6331_volt_range_ops, \
54 .type = REGULATOR_VOLTAGE, \
55 .id = MT6331_ID_##vreg, \
56 .owner = THIS_MODULE, \
57 .n_voltages = (max - min)/step + 1, \
58 .linear_ranges = volt_ranges, \
59 .n_linear_ranges = ARRAY_SIZE(volt_ranges), \
61 .vsel_mask = vosel_mask, \
62 .enable_reg = enreg, \
63 .enable_mask = BIT(0), \
66 .vselon_reg = voselon, \
67 .vselctrl_reg = vosel_ctrl, \
68 .vselctrl_mask = BIT(1), \
72 #define MT6331_LDO_AO(match, vreg, ldo_volt_table, vosel, vosel_mask) \
73 [MT6331_ID_##vreg] = { \
76 .of_match = of_match_ptr(match), \
77 .ops = &mt6331_volt_table_ao_ops, \
78 .type = REGULATOR_VOLTAGE, \
79 .id = MT6331_ID_##vreg, \
80 .owner = THIS_MODULE, \
81 .n_voltages = ARRAY_SIZE(ldo_volt_table), \
82 .volt_table = ldo_volt_table, \
84 .vsel_mask = vosel_mask, \
88 #define MT6331_LDO_S(match, vreg, ldo_volt_table, enreg, enbit, vosel, \
89 vosel_mask, _modeset_reg, _modeset_mask, \
90 _status_reg, _status_mask) \
91 [MT6331_ID_##vreg] = { \
94 .of_match = of_match_ptr(match), \
95 .ops = &mt6331_volt_table_no_qi_ops, \
96 .type = REGULATOR_VOLTAGE, \
97 .id = MT6331_ID_##vreg, \
98 .owner = THIS_MODULE, \
99 .n_voltages = ARRAY_SIZE(ldo_volt_table), \
100 .volt_table = ldo_volt_table, \
102 .vsel_mask = vosel_mask, \
103 .enable_reg = enreg, \
104 .enable_mask = BIT(enbit), \
106 .modeset_reg = _modeset_reg, \
107 .modeset_mask = _modeset_mask, \
108 .status_reg = _status_reg, \
109 .status_mask = _status_mask, \
112 #define MT6331_LDO(match, vreg, ldo_volt_table, enreg, enbit, vosel, \
113 vosel_mask, _modeset_reg, _modeset_mask) \
114 [MT6331_ID_##vreg] = { \
117 .of_match = of_match_ptr(match), \
118 .ops = (_modeset_reg ? \
119 &mt6331_volt_table_ops : \
120 &mt6331_volt_table_no_ms_ops), \
121 .type = REGULATOR_VOLTAGE, \
122 .id = MT6331_ID_##vreg, \
123 .owner = THIS_MODULE, \
124 .n_voltages = ARRAY_SIZE(ldo_volt_table), \
125 .volt_table = ldo_volt_table, \
127 .vsel_mask = vosel_mask, \
128 .enable_reg = enreg, \
129 .enable_mask = BIT(enbit), \
132 .modeset_reg = _modeset_reg, \
133 .modeset_mask = _modeset_mask, \
136 #define MT6331_REG_FIXED(match, vreg, enreg, enbit, qibit, volt, \
137 _modeset_reg, _modeset_mask) \
138 [MT6331_ID_##vreg] = { \
141 .of_match = of_match_ptr(match), \
142 .ops = (_modeset_reg ? \
143 &mt6331_volt_fixed_ops : \
144 &mt6331_volt_fixed_no_ms_ops), \
145 .type = REGULATOR_VOLTAGE, \
146 .id = MT6331_ID_##vreg, \
147 .owner = THIS_MODULE, \
149 .enable_reg = enreg, \
150 .enable_mask = BIT(enbit), \
154 .modeset_reg = _modeset_reg, \
155 .modeset_mask = _modeset_mask, \
158 static const struct linear_range buck_volt_range
[] = {
159 REGULATOR_LINEAR_RANGE(700000, 0, 0x7f, 6250),
162 static const unsigned int ldo_volt_table1
[] = {
163 2800000, 3000000, 0, 3200000
166 static const unsigned int ldo_volt_table2
[] = {
167 1500000, 1800000, 2500000, 2800000,
170 static const unsigned int ldo_volt_table3
[] = {
171 1200000, 1300000, 1500000, 1800000, 2000000, 2800000, 3000000, 3300000,
174 static const unsigned int ldo_volt_table4
[] = {
175 0, 0, 1700000, 1800000, 1860000, 2760000, 3000000, 3100000,
178 static const unsigned int ldo_volt_table5
[] = {
179 1800000, 3300000, 1800000, 3300000,
182 static const unsigned int ldo_volt_table6
[] = {
186 static const unsigned int ldo_volt_table7
[] = {
187 1200000, 1600000, 1700000, 1800000, 1900000, 2000000, 2100000, 2200000,
190 static const unsigned int ldo_volt_table8
[] = {
191 900000, 1000000, 1100000, 1220000, 1300000, 1500000, 1500000, 1500000,
194 static const unsigned int ldo_volt_table9
[] = {
195 1000000, 1050000, 1100000, 1150000, 1200000, 1250000, 1300000, 1300000,
198 static const unsigned int ldo_volt_table10
[] = {
199 1200000, 1300000, 1500000, 1800000,
202 static const unsigned int ldo_volt_table11
[] = {
203 1200000, 1300000, 1400000, 1500000, 1600000, 1700000, 1800000, 1800000,
206 static int mt6331_get_status(struct regulator_dev
*rdev
)
208 struct mt6331_regulator_info
*info
= rdev_get_drvdata(rdev
);
212 ret
= regmap_read(rdev
->regmap
, info
->desc
.enable_reg
, ®val
);
214 dev_err(&rdev
->dev
, "Failed to get enable reg: %d\n", ret
);
218 return (regval
& info
->qi
) ? REGULATOR_STATUS_ON
: REGULATOR_STATUS_OFF
;
221 static int mt6331_ldo_set_mode(struct regulator_dev
*rdev
, unsigned int mode
)
223 struct mt6331_regulator_info
*info
= rdev_get_drvdata(rdev
);
227 case REGULATOR_MODE_STANDBY
:
228 val
= MT6331_LDO_MODE_LP
;
230 case REGULATOR_MODE_NORMAL
:
231 val
= MT6331_LDO_MODE_NORMAL
;
237 val
<<= ffs(info
->modeset_mask
) - 1;
239 return regmap_update_bits(rdev
->regmap
, info
->modeset_reg
,
240 info
->modeset_mask
, val
);
243 static unsigned int mt6331_ldo_get_mode(struct regulator_dev
*rdev
)
245 struct mt6331_regulator_info
*info
= rdev_get_drvdata(rdev
);
249 ret
= regmap_read(rdev
->regmap
, info
->modeset_reg
, &val
);
253 val
&= info
->modeset_mask
;
254 val
>>= ffs(info
->modeset_mask
) - 1;
256 return (val
& BIT(0)) ? REGULATOR_MODE_STANDBY
: REGULATOR_MODE_NORMAL
;
259 static const struct regulator_ops mt6331_volt_range_ops
= {
260 .list_voltage
= regulator_list_voltage_linear_range
,
261 .map_voltage
= regulator_map_voltage_linear_range
,
262 .set_voltage_sel
= regulator_set_voltage_sel_regmap
,
263 .get_voltage_sel
= regulator_get_voltage_sel_regmap
,
264 .set_voltage_time_sel
= regulator_set_voltage_time_sel
,
265 .enable
= regulator_enable_regmap
,
266 .disable
= regulator_disable_regmap
,
267 .is_enabled
= regulator_is_enabled_regmap
,
268 .get_status
= mt6331_get_status
,
271 static const struct regulator_ops mt6331_volt_table_no_ms_ops
= {
272 .list_voltage
= regulator_list_voltage_table
,
273 .map_voltage
= regulator_map_voltage_iterate
,
274 .set_voltage_sel
= regulator_set_voltage_sel_regmap
,
275 .get_voltage_sel
= regulator_get_voltage_sel_regmap
,
276 .set_voltage_time_sel
= regulator_set_voltage_time_sel
,
277 .enable
= regulator_enable_regmap
,
278 .disable
= regulator_disable_regmap
,
279 .is_enabled
= regulator_is_enabled_regmap
,
280 .get_status
= mt6331_get_status
,
283 static const struct regulator_ops mt6331_volt_table_no_qi_ops
= {
284 .list_voltage
= regulator_list_voltage_table
,
285 .map_voltage
= regulator_map_voltage_iterate
,
286 .set_voltage_sel
= regulator_set_voltage_sel_regmap
,
287 .get_voltage_sel
= regulator_get_voltage_sel_regmap
,
288 .set_voltage_time_sel
= regulator_set_voltage_time_sel
,
289 .enable
= regulator_enable_regmap
,
290 .disable
= regulator_disable_regmap
,
291 .is_enabled
= regulator_is_enabled_regmap
,
292 .set_mode
= mt6331_ldo_set_mode
,
293 .get_mode
= mt6331_ldo_get_mode
,
296 static const struct regulator_ops mt6331_volt_table_ops
= {
297 .list_voltage
= regulator_list_voltage_table
,
298 .map_voltage
= regulator_map_voltage_iterate
,
299 .set_voltage_sel
= regulator_set_voltage_sel_regmap
,
300 .get_voltage_sel
= regulator_get_voltage_sel_regmap
,
301 .set_voltage_time_sel
= regulator_set_voltage_time_sel
,
302 .enable
= regulator_enable_regmap
,
303 .disable
= regulator_disable_regmap
,
304 .is_enabled
= regulator_is_enabled_regmap
,
305 .get_status
= mt6331_get_status
,
306 .set_mode
= mt6331_ldo_set_mode
,
307 .get_mode
= mt6331_ldo_get_mode
,
310 static const struct regulator_ops mt6331_volt_table_ao_ops
= {
311 .list_voltage
= regulator_list_voltage_table
,
312 .map_voltage
= regulator_map_voltage_iterate
,
313 .set_voltage_sel
= regulator_set_voltage_sel_regmap
,
314 .get_voltage_sel
= regulator_get_voltage_sel_regmap
,
315 .set_voltage_time_sel
= regulator_set_voltage_time_sel
,
318 static const struct regulator_ops mt6331_volt_fixed_no_ms_ops
= {
319 .list_voltage
= regulator_list_voltage_linear
,
320 .enable
= regulator_enable_regmap
,
321 .disable
= regulator_disable_regmap
,
322 .is_enabled
= regulator_is_enabled_regmap
,
323 .get_status
= mt6331_get_status
,
326 static const struct regulator_ops mt6331_volt_fixed_ops
= {
327 .list_voltage
= regulator_list_voltage_linear
,
328 .enable
= regulator_enable_regmap
,
329 .disable
= regulator_disable_regmap
,
330 .is_enabled
= regulator_is_enabled_regmap
,
331 .get_status
= mt6331_get_status
,
332 .set_mode
= mt6331_ldo_set_mode
,
333 .get_mode
= mt6331_ldo_get_mode
,
336 /* The array is indexed by id(MT6331_ID_XXX) */
337 static struct mt6331_regulator_info mt6331_regulators
[] = {
338 MT6331_BUCK("buck-vdvfs11", VDVFS11
, 700000, 1493750, 6250,
339 buck_volt_range
, MT6331_VDVFS11_CON9
,
340 MT6331_VDVFS11_CON11
, GENMASK(6, 0),
341 MT6331_VDVFS11_CON12
, MT6331_VDVFS11_CON7
),
342 MT6331_BUCK("buck-vdvfs12", VDVFS12
, 700000, 1493750, 6250,
343 buck_volt_range
, MT6331_VDVFS12_CON9
,
344 MT6331_VDVFS12_CON11
, GENMASK(6, 0),
345 MT6331_VDVFS12_CON12
, MT6331_VDVFS12_CON7
),
346 MT6331_BUCK("buck-vdvfs13", VDVFS13
, 700000, 1493750, 6250,
347 buck_volt_range
, MT6331_VDVFS13_CON9
,
348 MT6331_VDVFS13_CON11
, GENMASK(6, 0),
349 MT6331_VDVFS13_CON12
, MT6331_VDVFS13_CON7
),
350 MT6331_BUCK("buck-vdvfs14", VDVFS14
, 700000, 1493750, 6250,
351 buck_volt_range
, MT6331_VDVFS14_CON9
,
352 MT6331_VDVFS14_CON11
, GENMASK(6, 0),
353 MT6331_VDVFS14_CON12
, MT6331_VDVFS14_CON7
),
354 MT6331_BUCK("buck-vcore2", VCORE2
, 700000, 1493750, 6250,
355 buck_volt_range
, MT6331_VCORE2_CON9
,
356 MT6331_VCORE2_CON11
, GENMASK(6, 0),
357 MT6331_VCORE2_CON12
, MT6331_VCORE2_CON7
),
358 MT6331_REG_FIXED("buck-vio18", VIO18
, MT6331_VIO18_CON9
, 0, 13, 1800000, 0, 0),
359 MT6331_REG_FIXED("ldo-vrtc", VRTC
, MT6331_DIGLDO_CON11
, 8, 15, 2800000, 0, 0),
360 MT6331_REG_FIXED("ldo-vtcxo1", VTCXO1
, MT6331_ANALDO_CON1
, 10, 15, 2800000,
361 MT6331_ANALDO_CON1
, GENMASK(1, 0)),
362 MT6331_REG_FIXED("ldo-vtcxo2", VTCXO2
, MT6331_ANALDO_CON2
, 10, 15, 2800000,
363 MT6331_ANALDO_CON2
, GENMASK(1, 0)),
364 MT6331_REG_FIXED("ldo-vsram", VSRAM_DVFS1
, MT6331_SYSLDO_CON4
, 10, 15, 1012500,
365 MT6331_SYSLDO_CON4
, GENMASK(1, 0)),
366 MT6331_REG_FIXED("ldo-vio28", VIO28
, MT6331_DIGLDO_CON1
, 10, 15, 2800000,
367 MT6331_DIGLDO_CON1
, GENMASK(1, 0)),
368 MT6331_LDO("ldo-avdd32aud", AVDD32_AUD
, ldo_volt_table1
, MT6331_ANALDO_CON3
, 10,
369 MT6331_ANALDO_CON10
, GENMASK(6, 5), MT6331_ANALDO_CON3
, GENMASK(1, 0)),
370 MT6331_LDO("ldo-vauxa32", VAUXA32
, ldo_volt_table1
, MT6331_ANALDO_CON4
, 10,
371 MT6331_ANALDO_CON6
, GENMASK(6, 5), MT6331_ANALDO_CON4
, GENMASK(1, 0)),
372 MT6331_LDO("ldo-vemc33", VEMC33
, ldo_volt_table6
, MT6331_DIGLDO_CON5
, 10,
373 MT6331_DIGLDO_CON17
, BIT(6), MT6331_DIGLDO_CON5
, GENMASK(1, 0)),
374 MT6331_LDO("ldo-vibr", VIBR
, ldo_volt_table3
, MT6331_DIGLDO_CON12
, 10,
375 MT6331_DIGLDO_CON20
, GENMASK(6, 4), MT6331_DIGLDO_CON12
, GENMASK(1, 0)),
376 MT6331_LDO("ldo-vmc", VMC
, ldo_volt_table5
, MT6331_DIGLDO_CON3
, 10,
377 MT6331_DIGLDO_CON15
, GENMASK(5, 4), MT6331_DIGLDO_CON3
, GENMASK(1, 0)),
378 MT6331_LDO("ldo-vmch", VMCH
, ldo_volt_table6
, MT6331_DIGLDO_CON4
, 10,
379 MT6331_DIGLDO_CON16
, BIT(6), MT6331_DIGLDO_CON4
, GENMASK(1, 0)),
380 MT6331_LDO("ldo-vmipi", VMIPI
, ldo_volt_table3
, MT6331_SYSLDO_CON5
, 10,
381 MT6331_SYSLDO_CON13
, GENMASK(5, 3), MT6331_SYSLDO_CON5
, GENMASK(1, 0)),
382 MT6331_LDO("ldo-vsim1", VSIM1
, ldo_volt_table4
, MT6331_DIGLDO_CON8
, 10,
383 MT6331_DIGLDO_CON21
, GENMASK(6, 4), MT6331_DIGLDO_CON8
, GENMASK(1, 0)),
384 MT6331_LDO("ldo-vsim2", VSIM2
, ldo_volt_table4
, MT6331_DIGLDO_CON9
, 10,
385 MT6331_DIGLDO_CON22
, GENMASK(6, 4), MT6331_DIGLDO_CON9
, GENMASK(1, 0)),
386 MT6331_LDO("ldo-vusb10", VUSB10
, ldo_volt_table9
, MT6331_SYSLDO_CON2
, 10,
387 MT6331_SYSLDO_CON10
, GENMASK(5, 3), MT6331_SYSLDO_CON2
, GENMASK(1, 0)),
388 MT6331_LDO("ldo-vcama", VCAMA
, ldo_volt_table2
, MT6331_ANALDO_CON5
, 15,
389 MT6331_ANALDO_CON9
, GENMASK(5, 4), 0, 0),
390 MT6331_LDO_S("ldo-vcamaf", VCAM_AF
, ldo_volt_table3
, MT6331_DIGLDO_CON2
, 10,
391 MT6331_DIGLDO_CON14
, GENMASK(6, 4), MT6331_DIGLDO_CON2
, GENMASK(1, 0),
392 MT6331_EN_STATUS1
, BIT(0)),
393 MT6331_LDO_S("ldo-vcamd", VCAMD
, ldo_volt_table8
, MT6331_SYSLDO_CON1
, 15,
394 MT6331_SYSLDO_CON9
, GENMASK(6, 4), MT6331_SYSLDO_CON1
, GENMASK(1, 0),
395 MT6331_EN_STATUS1
, BIT(11)),
396 MT6331_LDO_S("ldo-vcamio", VCAM_IO
, ldo_volt_table10
, MT6331_SYSLDO_CON3
, 10,
397 MT6331_SYSLDO_CON11
, GENMASK(4, 3), MT6331_SYSLDO_CON3
, GENMASK(1, 0),
398 MT6331_EN_STATUS1
, BIT(13)),
399 MT6331_LDO_S("ldo-vgp1", VGP1
, ldo_volt_table3
, MT6331_DIGLDO_CON6
, 10,
400 MT6331_DIGLDO_CON19
, GENMASK(6, 4), MT6331_DIGLDO_CON6
, GENMASK(1, 0),
401 MT6331_EN_STATUS1
, BIT(4)),
402 MT6331_LDO_S("ldo-vgp2", VGP2
, ldo_volt_table10
, MT6331_SYSLDO_CON6
, 10,
403 MT6331_SYSLDO_CON14
, GENMASK(4, 3), MT6331_SYSLDO_CON6
, GENMASK(1, 0),
404 MT6331_EN_STATUS1
, BIT(15)),
405 MT6331_LDO_S("ldo-vgp3", VGP3
, ldo_volt_table10
, MT6331_SYSLDO_CON7
, 10,
406 MT6331_SYSLDO_CON15
, GENMASK(4, 3), MT6331_SYSLDO_CON7
, GENMASK(1, 0),
407 MT6331_EN_STATUS2
, BIT(0)),
408 MT6331_LDO_S("ldo-vgp4", VGP4
, ldo_volt_table7
, MT6331_DIGLDO_CON7
, 10,
409 MT6331_DIGLDO_CON18
, GENMASK(6, 4), MT6331_DIGLDO_CON7
, GENMASK(1, 0),
410 MT6331_EN_STATUS1
, BIT(5)),
411 MT6331_LDO_AO("ldo-vdig18", VDIG18
, ldo_volt_table11
,
412 MT6331_DIGLDO_CON28
, GENMASK(14, 12)),
415 static int mt6331_set_buck_vosel_reg(struct platform_device
*pdev
)
417 struct mt6397_chip
*mt6331
= dev_get_drvdata(pdev
->dev
.parent
);
421 for (i
= 0; i
< MT6331_ID_VREG_MAX
; i
++) {
422 if (mt6331_regulators
[i
].vselctrl_reg
) {
423 if (regmap_read(mt6331
->regmap
,
424 mt6331_regulators
[i
].vselctrl_reg
,
427 "Failed to read buck ctrl\n");
431 if (regval
& mt6331_regulators
[i
].vselctrl_mask
) {
432 mt6331_regulators
[i
].desc
.vsel_reg
=
433 mt6331_regulators
[i
].vselon_reg
;
441 static int mt6331_regulator_probe(struct platform_device
*pdev
)
443 struct mt6397_chip
*mt6331
= dev_get_drvdata(pdev
->dev
.parent
);
444 struct regulator_config config
= {};
445 struct regulator_dev
*rdev
;
449 /* Query buck controller to select activated voltage register part */
450 if (mt6331_set_buck_vosel_reg(pdev
))
453 /* Read PMIC chip revision to update constraints and voltage table */
454 if (regmap_read(mt6331
->regmap
, MT6331_HWCID
, ®_value
) < 0) {
455 dev_err(&pdev
->dev
, "Failed to read Chip ID\n");
458 reg_value
&= GENMASK(7, 0);
460 dev_info(&pdev
->dev
, "Chip ID = 0x%x\n", reg_value
);
463 * ChipID 0x10 is "MT6331 E1", has a different voltage table and
464 * it's currently not supported in this driver. Upon detection of
465 * this ID, refuse to register the regulators, as we will wrongly
466 * interpret the VSEL for this revision, potentially overvolting
469 if (reg_value
== 0x10) {
470 dev_err(&pdev
->dev
, "Chip version not supported. Bailing out.\n");
474 for (i
= 0; i
< MT6331_ID_VREG_MAX
; i
++) {
475 config
.dev
= &pdev
->dev
;
476 config
.driver_data
= &mt6331_regulators
[i
];
477 config
.regmap
= mt6331
->regmap
;
478 rdev
= devm_regulator_register(&pdev
->dev
,
479 &mt6331_regulators
[i
].desc
, &config
);
481 dev_err(&pdev
->dev
, "failed to register %s\n",
482 mt6331_regulators
[i
].desc
.name
);
483 return PTR_ERR(rdev
);
489 static const struct platform_device_id mt6331_platform_ids
[] = {
490 {"mt6331-regulator", 0},
493 MODULE_DEVICE_TABLE(platform
, mt6331_platform_ids
);
495 static struct platform_driver mt6331_regulator_driver
= {
497 .name
= "mt6331-regulator",
498 .probe_type
= PROBE_PREFER_ASYNCHRONOUS
,
500 .probe
= mt6331_regulator_probe
,
501 .id_table
= mt6331_platform_ids
,
504 module_platform_driver(mt6331_regulator_driver
);
506 MODULE_AUTHOR("AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>");
507 MODULE_DESCRIPTION("Regulator Driver for MediaTek MT6331 PMIC");
508 MODULE_LICENSE("GPL");