]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blame - drivers/regulator/88pm8607.c
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
[mirror_ubuntu-jammy-kernel.git] / drivers / regulator / 88pm8607.c
CommitLineData
be0e2d3e
HZ
1/*
2 * Regulators driver for Marvell 88PM8607
3 *
4 * Copyright (C) 2009 Marvell International Ltd.
e54f19bf 5 * Haojian Zhuang <haojian.zhuang@marvell.com>
be0e2d3e
HZ
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#include <linux/kernel.h>
12#include <linux/init.h>
13#include <linux/err.h>
2e57d567
HZ
14#include <linux/of.h>
15#include <linux/regulator/of_regulator.h>
be0e2d3e
HZ
16#include <linux/platform_device.h>
17#include <linux/regulator/driver.h>
18#include <linux/regulator/machine.h>
53dbab7a 19#include <linux/mfd/88pm860x.h>
65602c32 20#include <linux/module.h>
be0e2d3e
HZ
21
22struct pm8607_regulator_info {
23 struct regulator_desc desc;
be0e2d3e 24
9f79e9db
HZ
25 unsigned int *vol_suspend;
26
be0e2d3e
HZ
27 int slope_double;
28};
29
9f79e9db
HZ
30static const unsigned int BUCK1_table[] = {
31 725000, 750000, 775000, 800000, 825000, 850000, 875000, 900000,
32 925000, 950000, 975000, 1000000, 1025000, 1050000, 1075000, 1100000,
33 1125000, 1150000, 1175000, 1200000, 1225000, 1250000, 1275000, 1300000,
34 1325000, 1350000, 1375000, 1400000, 1425000, 1450000, 1475000, 1500000,
35 0, 25000, 50000, 75000, 100000, 125000, 150000, 175000,
36 200000, 225000, 250000, 275000, 300000, 325000, 350000, 375000,
37 400000, 425000, 450000, 475000, 500000, 525000, 550000, 575000,
38 600000, 625000, 650000, 675000, 700000, 725000, 750000, 775000,
39};
be0e2d3e 40
9f79e9db
HZ
41static const unsigned int BUCK1_suspend_table[] = {
42 0, 25000, 50000, 75000, 100000, 125000, 150000, 175000,
43 200000, 225000, 250000, 275000, 300000, 325000, 350000, 375000,
44 400000, 425000, 450000, 475000, 500000, 525000, 550000, 575000,
45 600000, 625000, 650000, 675000, 700000, 725000, 750000, 775000,
46 800000, 825000, 850000, 875000, 900000, 925000, 950000, 975000,
47 1000000, 1025000, 1050000, 1075000, 1100000, 1125000, 1150000, 1175000,
48 1200000, 1225000, 1250000, 1275000, 1300000, 1325000, 1350000, 1375000,
49 1400000, 1425000, 1450000, 1475000, 1500000, 1500000, 1500000, 1500000,
50};
51
52static const unsigned int BUCK2_table[] = {
53 0, 50000, 100000, 150000, 200000, 250000, 300000, 350000,
54 400000, 450000, 500000, 550000, 600000, 650000, 700000, 750000,
55 800000, 850000, 900000, 950000, 1000000, 1050000, 1100000, 1150000,
56 1200000, 1250000, 1300000, 1350000, 1400000, 1450000, 1500000, 1550000,
57 1600000, 1650000, 1700000, 1750000, 1800000, 1850000, 1900000, 1950000,
58 2000000, 2050000, 2100000, 2150000, 2200000, 2250000, 2300000, 2350000,
59 2400000, 2450000, 2500000, 2550000, 2600000, 2650000, 2700000, 2750000,
60 2800000, 2850000, 2900000, 2950000, 3000000, 3000000, 3000000, 3000000,
61};
62
63static const unsigned int BUCK2_suspend_table[] = {
64 0, 50000, 100000, 150000, 200000, 250000, 300000, 350000,
65 400000, 450000, 500000, 550000, 600000, 650000, 700000, 750000,
66 800000, 850000, 900000, 950000, 1000000, 1050000, 1100000, 1150000,
67 1200000, 1250000, 1300000, 1350000, 1400000, 1450000, 1500000, 1550000,
68 1600000, 1650000, 1700000, 1750000, 1800000, 1850000, 1900000, 1950000,
69 2000000, 2050000, 2100000, 2150000, 2200000, 2250000, 2300000, 2350000,
70 2400000, 2450000, 2500000, 2550000, 2600000, 2650000, 2700000, 2750000,
71 2800000, 2850000, 2900000, 2950000, 3000000, 3000000, 3000000, 3000000,
72};
73
74static const unsigned int BUCK3_table[] = {
e54f19bf 75 0, 25000, 50000, 75000, 100000, 125000, 150000, 175000,
9f79e9db
HZ
76 200000, 225000, 250000, 275000, 300000, 325000, 350000, 375000,
77 400000, 425000, 450000, 475000, 500000, 525000, 550000, 575000,
78 600000, 625000, 650000, 675000, 700000, 725000, 750000, 775000,
79 800000, 825000, 850000, 875000, 900000, 925000, 950000, 975000,
80 1000000, 1025000, 1050000, 1075000, 1100000, 1125000, 1150000, 1175000,
81 1200000, 1225000, 1250000, 1275000, 1300000, 1325000, 1350000, 1375000,
82 1400000, 1425000, 1450000, 1475000, 1500000, 1500000, 1500000, 1500000,
83};
84
85static const unsigned int BUCK3_suspend_table[] = {
e54f19bf 86 0, 25000, 50000, 75000, 100000, 125000, 150000, 175000,
9f79e9db
HZ
87 200000, 225000, 250000, 275000, 300000, 325000, 350000, 375000,
88 400000, 425000, 450000, 475000, 500000, 525000, 550000, 575000,
89 600000, 625000, 650000, 675000, 700000, 725000, 750000, 775000,
90 800000, 825000, 850000, 875000, 900000, 925000, 950000, 975000,
91 1000000, 1025000, 1050000, 1075000, 1100000, 1125000, 1150000, 1175000,
92 1200000, 1225000, 1250000, 1275000, 1300000, 1325000, 1350000, 1375000,
93 1400000, 1425000, 1450000, 1475000, 1500000, 1500000, 1500000, 1500000,
94};
95
96static const unsigned int LDO1_table[] = {
97 1800000, 1200000, 2800000, 0,
98};
99
100static const unsigned int LDO1_suspend_table[] = {
101 1800000, 1200000, 0, 0,
102};
103
104static const unsigned int LDO2_table[] = {
105 1800000, 1850000, 1900000, 2700000, 2750000, 2800000, 2850000, 3300000,
106};
107
108static const unsigned int LDO2_suspend_table[] = {
109 1800000, 1850000, 1900000, 2700000, 2750000, 2800000, 2850000, 2900000,
110};
111
112static const unsigned int LDO3_table[] = {
113 1800000, 1850000, 1900000, 2700000, 2750000, 2800000, 2850000, 3300000,
114};
115
116static const unsigned int LDO3_suspend_table[] = {
117 1800000, 1850000, 1900000, 2700000, 2750000, 2800000, 2850000, 2900000,
118};
119
120static const unsigned int LDO4_table[] = {
121 1800000, 1850000, 1900000, 2700000, 2750000, 2800000, 2900000, 3300000,
122};
123
124static const unsigned int LDO4_suspend_table[] = {
125 1800000, 1850000, 1900000, 2700000, 2750000, 2800000, 2900000, 2900000,
126};
127
128static const unsigned int LDO5_table[] = {
129 2900000, 3000000, 3100000, 3300000,
130};
131
132static const unsigned int LDO5_suspend_table[] = {
133 2900000, 0, 0, 0,
134};
135
136static const unsigned int LDO6_table[] = {
137 1800000, 1850000, 2600000, 2650000, 2700000, 2750000, 2800000, 3300000,
138};
139
140static const unsigned int LDO6_suspend_table[] = {
141 1800000, 1850000, 2600000, 2650000, 2700000, 2750000, 2800000, 2900000,
142};
143
144static const unsigned int LDO7_table[] = {
145 1800000, 1850000, 1900000, 2700000, 2750000, 2800000, 2850000, 2900000,
146};
147
148static const unsigned int LDO7_suspend_table[] = {
149 1800000, 1850000, 1900000, 2700000, 2750000, 2800000, 2850000, 2900000,
150};
151
152static const unsigned int LDO8_table[] = {
153 1800000, 1850000, 1900000, 2700000, 2750000, 2800000, 2850000, 2900000,
154};
155
156static const unsigned int LDO8_suspend_table[] = {
157 1800000, 1850000, 1900000, 2700000, 2750000, 2800000, 2850000, 2900000,
158};
159
160static const unsigned int LDO9_table[] = {
161 1800000, 1850000, 1900000, 2700000, 2750000, 2800000, 2850000, 3300000,
162};
163
164static const unsigned int LDO9_suspend_table[] = {
165 1800000, 1850000, 1900000, 2700000, 2750000, 2800000, 2850000, 2900000,
166};
167
168static const unsigned int LDO10_table[] = {
169 1800000, 1850000, 1900000, 2700000, 2750000, 2800000, 2850000, 3300000,
170 1200000, 1200000, 1200000, 1200000, 1200000, 1200000, 1200000, 1200000,
171};
172
173static const unsigned int LDO10_suspend_table[] = {
174 1800000, 1850000, 1900000, 2700000, 2750000, 2800000, 2850000, 2900000,
175 1200000, 1200000, 1200000, 1200000, 1200000, 1200000, 1200000, 1200000,
176};
177
178static const unsigned int LDO12_table[] = {
179 1800000, 1900000, 2700000, 2800000, 2900000, 3000000, 3100000, 3300000,
180 1200000, 1200000, 1200000, 1200000, 1200000, 1200000, 1200000, 1200000,
181};
182
183static const unsigned int LDO12_suspend_table[] = {
184 1800000, 1900000, 2700000, 2800000, 2900000, 2900000, 2900000, 2900000,
185 1200000, 1200000, 1200000, 1200000, 1200000, 1200000, 1200000, 1200000,
186};
187
188static const unsigned int LDO13_table[] = {
3380643b 189 1200000, 1300000, 1800000, 2000000, 2500000, 2800000, 3000000, 0,
9f79e9db
HZ
190};
191
192static const unsigned int LDO13_suspend_table[] = {
193 0,
194};
195
196static const unsigned int LDO14_table[] = {
197 1800000, 1850000, 2700000, 2750000, 2800000, 2850000, 2900000, 3300000,
198};
199
200static const unsigned int LDO14_suspend_table[] = {
201 1800000, 1850000, 2700000, 2750000, 2800000, 2850000, 2900000, 2900000,
202};
be0e2d3e
HZ
203
204static int pm8607_list_voltage(struct regulator_dev *rdev, unsigned index)
205{
206 struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
2654d368
AL
207 int ret;
208
209 ret = regulator_list_voltage_table(rdev, index);
210 if (ret < 0)
211 return ret;
212
213 if (info->slope_double)
214 ret <<= 1;
be0e2d3e 215
be0e2d3e
HZ
216 return ret;
217}
218
32cb5d30 219static const struct regulator_ops pm8607_regulator_ops = {
d3d7bccc 220 .list_voltage = pm8607_list_voltage,
c6f0a0ef 221 .set_voltage_sel = regulator_set_voltage_sel_regmap,
c006b21f 222 .get_voltage_sel = regulator_get_voltage_sel_regmap,
ef26e0db
AL
223 .enable = regulator_enable_regmap,
224 .disable = regulator_disable_regmap,
225 .is_enabled = regulator_is_enabled_regmap,
be0e2d3e
HZ
226};
227
32cb5d30 228static const struct regulator_ops pm8606_preg_ops = {
318c658b
AL
229 .enable = regulator_enable_regmap,
230 .disable = regulator_disable_regmap,
231 .is_enabled = regulator_is_enabled_regmap,
e7a7810a
JZ
232};
233
234#define PM8606_PREG(ereg, ebit) \
235{ \
236 .desc = { \
237 .name = "PREG", \
e6626427
AL
238 .of_match = of_match_ptr("PREG"), \
239 .regulators_node = of_match_ptr("regulators"), \
e7a7810a
JZ
240 .ops = &pm8606_preg_ops, \
241 .type = REGULATOR_CURRENT, \
242 .id = PM8606_ID_PREG, \
243 .owner = THIS_MODULE, \
244 .enable_reg = PM8606_##ereg, \
245 .enable_mask = (ebit), \
318c658b 246 .enable_is_inverted = true, \
e7a7810a
JZ
247 }, \
248}
249
53b6949e 250#define PM8607_DVC(vreg, ureg, ubit, ereg, ebit) \
be0e2d3e
HZ
251{ \
252 .desc = { \
9f79e9db 253 .name = #vreg, \
e6626427
AL
254 .of_match = of_match_ptr(#vreg), \
255 .regulators_node = of_match_ptr("regulators"), \
be0e2d3e
HZ
256 .ops = &pm8607_regulator_ops, \
257 .type = REGULATOR_VOLTAGE, \
9f79e9db 258 .id = PM8607_ID_##vreg, \
be0e2d3e 259 .owner = THIS_MODULE, \
2654d368 260 .volt_table = vreg##_table, \
53b6949e 261 .n_voltages = ARRAY_SIZE(vreg##_table), \
c006b21f
AL
262 .vsel_reg = PM8607_##vreg, \
263 .vsel_mask = ARRAY_SIZE(vreg##_table) - 1, \
c6f0a0ef
AL
264 .apply_reg = PM8607_##ureg, \
265 .apply_bit = (ubit), \
ef26e0db
AL
266 .enable_reg = PM8607_##ereg, \
267 .enable_mask = 1 << (ebit), \
be0e2d3e 268 }, \
be0e2d3e 269 .slope_double = (0), \
9f79e9db 270 .vol_suspend = (unsigned int *)&vreg##_suspend_table, \
be0e2d3e
HZ
271}
272
53b6949e 273#define PM8607_LDO(_id, vreg, shift, ereg, ebit) \
be0e2d3e
HZ
274{ \
275 .desc = { \
276 .name = "LDO" #_id, \
e6626427
AL
277 .of_match = of_match_ptr("LDO" #_id), \
278 .regulators_node = of_match_ptr("regulators"), \
be0e2d3e
HZ
279 .ops = &pm8607_regulator_ops, \
280 .type = REGULATOR_VOLTAGE, \
281 .id = PM8607_ID_LDO##_id, \
282 .owner = THIS_MODULE, \
2654d368 283 .volt_table = LDO##_id##_table, \
53b6949e 284 .n_voltages = ARRAY_SIZE(LDO##_id##_table), \
c006b21f
AL
285 .vsel_reg = PM8607_##vreg, \
286 .vsel_mask = (ARRAY_SIZE(LDO##_id##_table) - 1) << (shift), \
ef26e0db
AL
287 .enable_reg = PM8607_##ereg, \
288 .enable_mask = 1 << (ebit), \
be0e2d3e 289 }, \
be0e2d3e 290 .slope_double = (0), \
9f79e9db 291 .vol_suspend = (unsigned int *)&LDO##_id##_suspend_table, \
be0e2d3e
HZ
292}
293
294static struct pm8607_regulator_info pm8607_regulator_info[] = {
c6f0a0ef
AL
295 PM8607_DVC(BUCK1, GO, BIT(0), SUPPLIES_EN11, 0),
296 PM8607_DVC(BUCK2, GO, BIT(1), SUPPLIES_EN11, 1),
297 PM8607_DVC(BUCK3, GO, BIT(2), SUPPLIES_EN11, 2),
53b6949e
AL
298
299 PM8607_LDO(1, LDO1, 0, SUPPLIES_EN11, 3),
300 PM8607_LDO(2, LDO2, 0, SUPPLIES_EN11, 4),
301 PM8607_LDO(3, LDO3, 0, SUPPLIES_EN11, 5),
302 PM8607_LDO(4, LDO4, 0, SUPPLIES_EN11, 6),
303 PM8607_LDO(5, LDO5, 0, SUPPLIES_EN11, 7),
304 PM8607_LDO(6, LDO6, 0, SUPPLIES_EN12, 0),
305 PM8607_LDO(7, LDO7, 0, SUPPLIES_EN12, 1),
306 PM8607_LDO(8, LDO8, 0, SUPPLIES_EN12, 2),
307 PM8607_LDO(9, LDO9, 0, SUPPLIES_EN12, 3),
308 PM8607_LDO(10, LDO10, 0, SUPPLIES_EN12, 4),
309 PM8607_LDO(12, LDO12, 0, SUPPLIES_EN12, 5),
310 PM8607_LDO(13, VIBRATOR_SET, 1, VIBRATOR_SET, 0),
311 PM8607_LDO(14, LDO14, 0, SUPPLIES_EN12, 6),
ff13e9e2 312};
e7a7810a 313
ff13e9e2 314static struct pm8607_regulator_info pm8606_regulator_info[] = {
e7a7810a 315 PM8606_PREG(PREREGULATORB, 5),
be0e2d3e
HZ
316};
317
a5023574 318static int pm8607_regulator_probe(struct platform_device *pdev)
be0e2d3e 319{
22aad001
HZ
320 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
321 struct pm8607_regulator_info *info = NULL;
dff91d0b 322 struct regulator_init_data *pdata = dev_get_platdata(&pdev->dev);
c172708d 323 struct regulator_config config = { };
0e819b51 324 struct regulator_dev *rdev;
586e1a17 325 struct resource *res;
be0e2d3e
HZ
326 int i;
327
02367029 328 res = platform_get_resource(pdev, IORESOURCE_REG, 0);
ff13e9e2
HZ
329 if (res) {
330 /* There're resources in 88PM8607 regulator driver */
331 for (i = 0; i < ARRAY_SIZE(pm8607_regulator_info); i++) {
332 info = &pm8607_regulator_info[i];
333 if (info->desc.vsel_reg == res->start)
334 break;
335 }
336 if (i == ARRAY_SIZE(pm8607_regulator_info)) {
337 dev_err(&pdev->dev, "Failed to find regulator %llu\n",
338 (unsigned long long)res->start);
339 return -EINVAL;
340 }
341 } else {
342 /* There's no resource in 88PM8606 PREG regulator driver */
343 info = &pm8606_regulator_info[0];
344 /* i is used to check regulator ID */
345 i = -1;
be0e2d3e 346 }
be0e2d3e 347
22aad001 348 /* check DVC ramp slope double */
0e819b51 349 if ((i == PM8607_ID_BUCK3) && chip->buck3_double)
586e1a17 350 info->slope_double = 1;
22aad001 351
e6626427 352 config.dev = chip->dev;
c172708d
MB
353 config.driver_data = info;
354
e6626427
AL
355 if (pdata)
356 config.init_data = pdata;
2e57d567 357
ef26e0db
AL
358 if (chip->id == CHIP_PM8607)
359 config.regmap = chip->regmap;
360 else
361 config.regmap = chip->regmap_companion;
362
0e819b51
AL
363 rdev = devm_regulator_register(&pdev->dev, &info->desc, &config);
364 if (IS_ERR(rdev)) {
be0e2d3e
HZ
365 dev_err(&pdev->dev, "failed to register regulator %s\n",
366 info->desc.name);
0e819b51 367 return PTR_ERR(rdev);
be0e2d3e
HZ
368 }
369
be0e2d3e
HZ
370 platform_set_drvdata(pdev, info);
371 return 0;
372}
373
0cfeddbd 374static const struct platform_device_id pm8607_regulator_driver_ids[] = {
e7a7810a
JZ
375 {
376 .name = "88pm860x-regulator",
377 .driver_data = 0,
378 }, {
379 .name = "88pm860x-preg",
380 .driver_data = 0,
381 },
382 { },
383};
384MODULE_DEVICE_TABLE(platform, pm8607_regulator_driver_ids);
385
192bbb95
HZ
386static struct platform_driver pm8607_regulator_driver = {
387 .driver = {
388 .name = "88pm860x-regulator",
192bbb95
HZ
389 },
390 .probe = pm8607_regulator_probe,
e7a7810a 391 .id_table = pm8607_regulator_driver_ids,
be0e2d3e
HZ
392};
393
394static int __init pm8607_regulator_init(void)
395{
192bbb95 396 return platform_driver_register(&pm8607_regulator_driver);
be0e2d3e
HZ
397}
398subsys_initcall(pm8607_regulator_init);
399
400static void __exit pm8607_regulator_exit(void)
401{
192bbb95 402 platform_driver_unregister(&pm8607_regulator_driver);
be0e2d3e
HZ
403}
404module_exit(pm8607_regulator_exit);
405
406MODULE_LICENSE("GPL");
407MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
408MODULE_DESCRIPTION("Regulator Driver for Marvell 88PM8607 PMIC");
409MODULE_ALIAS("platform:88pm8607-regulator");