1// SPDX-License-Identifier: GPL-2.0
2//
3// Copyright (c) 2022 Collabora Ltd.
4// Author: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
5//
6// Based on mt6323-regulator.c,
7// Copyright (c) 2016 MediaTek Inc.
8//
9
10#include <linux/module.h>
11#include <linux/of.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>
20
21#define MT6331_LDO_MODE_NORMAL 0
22#define MT6331_LDO_MODE_LP 1
23
24/*
25 * MT6331 regulators information
26 *
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
34 */
35struct mt6331_regulator_info {
36 struct regulator_desc desc;
37 u32 qi;
38 u32 vselon_reg;
39 u32 vselctrl_reg;
40 u32 vselctrl_mask;
41 u32 modeset_reg;
42 u32 modeset_mask;
43 u32 status_reg;
44 u32 status_mask;
45};
46
47#define MT6331_BUCK(match, vreg, min, max, step, volt_ranges, enreg, \
48 vosel, vosel_mask, voselon, vosel_ctrl) \
49[MT6331_ID_##vreg] = { \
50 .desc = { \
51 .name = #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), \
60 .vsel_reg = vosel, \
61 .vsel_mask = vosel_mask, \
62 .enable_reg = enreg, \
63 .enable_mask = BIT(0), \
64 }, \
65 .qi = BIT(13), \
66 .vselon_reg = voselon, \
67 .vselctrl_reg = vosel_ctrl, \
68 .vselctrl_mask = BIT(1), \
69 .status_mask = 0, \
70}
71
72#define MT6331_LDO_AO(match, vreg, ldo_volt_table, vosel, vosel_mask) \
73[MT6331_ID_##vreg] = { \
74 .desc = { \
75 .name = #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, \
83 .vsel_reg = vosel, \
84 .vsel_mask = vosel_mask, \
85 }, \
86}
87
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] = { \
92 .desc = { \
93 .name = #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, \
101 .vsel_reg = vosel, \
102 .vsel_mask = vosel_mask, \
103 .enable_reg = enreg, \
104 .enable_mask = BIT(enbit), \
105 }, \
106 .modeset_reg = _modeset_reg, \
107 .modeset_mask = _modeset_mask, \
108 .status_reg = _status_reg, \
109 .status_mask = _status_mask, \
110}
111
112#define MT6331_LDO(match, vreg, ldo_volt_table, enreg, enbit, vosel, \
113 vosel_mask, _modeset_reg, _modeset_mask) \
114[MT6331_ID_##vreg] = { \
115 .desc = { \
116 .name = #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, \
126 .vsel_reg = vosel, \
127 .vsel_mask = vosel_mask, \
128 .enable_reg = enreg, \
129 .enable_mask = BIT(enbit), \
130 }, \
131 .qi = BIT(15), \
132 .modeset_reg = _modeset_reg, \
133 .modeset_mask = _modeset_mask, \
134}
135
136#define MT6331_REG_FIXED(match, vreg, enreg, enbit, qibit, volt, \
137 _modeset_reg, _modeset_mask) \
138[MT6331_ID_##vreg] = { \
139 .desc = { \
140 .name = #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, \
148 .n_voltages = 1, \
149 .enable_reg = enreg, \
150 .enable_mask = BIT(enbit), \
151 .min_uV = volt, \
152 }, \
153 .qi = BIT(qibit), \
154 .modeset_reg = _modeset_reg, \
155 .modeset_mask = _modeset_mask, \
156}
157
158static const struct linear_range buck_volt_range[] = {
159 REGULATOR_LINEAR_RANGE(700000, 0, 0x7f, 6250),
160};
161
162static const unsigned int ldo_volt_table1[] = {
163 2800000, 3000000, 0, 3200000
164};
165
166static const unsigned int ldo_volt_table2[] = {
167 1500000, 1800000, 2500000, 2800000,
168};
169
170static const unsigned int ldo_volt_table3[] = {
171 1200000, 1300000, 1500000, 1800000, 2000000, 2800000, 3000000, 3300000,
172};
173
174static const unsigned int ldo_volt_table4[] = {
175 0, 0, 1700000, 1800000, 1860000, 2760000, 3000000, 3100000,
176};
177
178static const unsigned int ldo_volt_table5[] = {
179 1800000, 3300000, 1800000, 3300000,
180};
181
182static const unsigned int ldo_volt_table6[] = {
183 3000000, 3300000,
184};
185
186static const unsigned int ldo_volt_table7[] = {
187 1200000, 1600000, 1700000, 1800000, 1900000, 2000000, 2100000, 2200000,
188};
189
190static const unsigned int ldo_volt_table8[] = {
191 900000, 1000000, 1100000, 1220000, 1300000, 1500000, 1500000, 1500000,
192};
193
194static const unsigned int ldo_volt_table9[] = {
195 1000000, 1050000, 1100000, 1150000, 1200000, 1250000, 1300000, 1300000,
196};
197
198static const unsigned int ldo_volt_table10[] = {
199 1200000, 1300000, 1500000, 1800000,
200};
201
202static const unsigned int ldo_volt_table11[] = {
203 1200000, 1300000, 1400000, 1500000, 1600000, 1700000, 1800000, 1800000,
204};
205
206static int mt6331_get_status(struct regulator_dev *rdev)
207{
208 struct mt6331_regulator_info *info = rdev_get_drvdata(rdev);
209 u32 regval;
210 int ret;
211
212 ret = regmap_read(map: rdev->regmap, reg: info->desc.enable_reg, val: &regval);
213 if (ret != 0) {
214 dev_err(&rdev->dev, "Failed to get enable reg: %d\n", ret);
215 return ret;
216 }
217
218 return (regval & info->qi) ? REGULATOR_STATUS_ON : REGULATOR_STATUS_OFF;
219}
220
221static int mt6331_ldo_set_mode(struct regulator_dev *rdev, unsigned int mode)
222{
223 struct mt6331_regulator_info *info = rdev_get_drvdata(rdev);
224 int val;
225
226 switch (mode) {
227 case REGULATOR_MODE_STANDBY:
228 val = MT6331_LDO_MODE_LP;
229 break;
230 case REGULATOR_MODE_NORMAL:
231 val = MT6331_LDO_MODE_NORMAL;
232 break;
233 default:
234 return -EINVAL;
235 }
236
237 val <<= ffs(info->modeset_mask) - 1;
238
239 return regmap_update_bits(map: rdev->regmap, reg: info->modeset_reg,
240 mask: info->modeset_mask, val);
241}
242
243static unsigned int mt6331_ldo_get_mode(struct regulator_dev *rdev)
244{
245 struct mt6331_regulator_info *info = rdev_get_drvdata(rdev);
246 unsigned int val;
247 int ret;
248
249 ret = regmap_read(map: rdev->regmap, reg: info->modeset_reg, val: &val);
250 if (ret < 0)
251 return ret;
252
253 val &= info->modeset_mask;
254 val >>= ffs(info->modeset_mask) - 1;
255
256 return (val & BIT(0)) ? REGULATOR_MODE_STANDBY : REGULATOR_MODE_NORMAL;
257}
258
259static 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,
269};
270
271static 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,
281};
282
283static 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,
294};
295
296static 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,
308};
309
310static 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,
316};
317
318static 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,
324};
325
326static 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,
334};
335
336/* The array is indexed by id(MT6331_ID_XXX) */
337static 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)),
413};
414
415static int mt6331_set_buck_vosel_reg(struct platform_device *pdev)
416{
417 struct mt6397_chip *mt6331 = dev_get_drvdata(dev: pdev->dev.parent);
418 int i;
419 u32 regval;
420
421 for (i = 0; i < MT6331_ID_VREG_MAX; i++) {
422 if (mt6331_regulators[i].vselctrl_reg) {
423 if (regmap_read(map: mt6331->regmap,
424 reg: mt6331_regulators[i].vselctrl_reg,
425 val: &regval) < 0) {
426 dev_err(&pdev->dev,
427 "Failed to read buck ctrl\n");
428 return -EIO;
429 }
430
431 if (regval & mt6331_regulators[i].vselctrl_mask) {
432 mt6331_regulators[i].desc.vsel_reg =
433 mt6331_regulators[i].vselon_reg;
434 }
435 }
436 }
437
438 return 0;
439}
440
441static int mt6331_regulator_probe(struct platform_device *pdev)
442{
443 struct mt6397_chip *mt6331 = dev_get_drvdata(dev: pdev->dev.parent);
444 struct regulator_config config = {};
445 struct regulator_dev *rdev;
446 int i;
447 u32 reg_value;
448
449 /* Query buck controller to select activated voltage register part */
450 if (mt6331_set_buck_vosel_reg(pdev))
451 return -EIO;
452
453 /* Read PMIC chip revision to update constraints and voltage table */
454 if (regmap_read(map: mt6331->regmap, MT6331_HWCID, val: &reg_value) < 0) {
455 dev_err(&pdev->dev, "Failed to read Chip ID\n");
456 return -EIO;
457 }
458 reg_value &= GENMASK(7, 0);
459
460 dev_info(&pdev->dev, "Chip ID = 0x%x\n", reg_value);
461
462 /*
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
467 * some device.
468 */
469 if (reg_value == 0x10) {
470 dev_err(&pdev->dev, "Chip version not supported. Bailing out.\n");
471 return -EINVAL;
472 }
473
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(dev: &pdev->dev,
479 regulator_desc: &mt6331_regulators[i].desc, config: &config);
480 if (IS_ERR(ptr: rdev)) {
481 dev_err(&pdev->dev, "failed to register %s\n",
482 mt6331_regulators[i].desc.name);
483 return PTR_ERR(ptr: rdev);
484 }
485 }
486 return 0;
487}
488
489static const struct platform_device_id mt6331_platform_ids[] = {
490 {"mt6331-regulator", 0},
491 { /* sentinel */ },
492};
493MODULE_DEVICE_TABLE(platform, mt6331_platform_ids);
494
495static struct platform_driver mt6331_regulator_driver = {
496 .driver = {
497 .name = "mt6331-regulator",
498 .probe_type = PROBE_PREFER_ASYNCHRONOUS,
499 },
500 .probe = mt6331_regulator_probe,
501 .id_table = mt6331_platform_ids,
502};
503
504module_platform_driver(mt6331_regulator_driver);
505
506MODULE_AUTHOR("AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>");
507MODULE_DESCRIPTION("Regulator Driver for MediaTek MT6331 PMIC");
508MODULE_LICENSE("GPL");
509

source code of linux/drivers/regulator/mt6331-regulator.c