12874c5fdSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
2462c9fc5SMatt Porter /*
3462c9fc5SMatt Porter * Broadcom BCM590xx regulator driver
4462c9fc5SMatt Porter *
5462c9fc5SMatt Porter * Copyright 2014 Linaro Limited
6462c9fc5SMatt Porter * Author: Matt Porter <mporter@linaro.org>
7462c9fc5SMatt Porter */
8462c9fc5SMatt Porter
9462c9fc5SMatt Porter #include <linux/err.h>
10462c9fc5SMatt Porter #include <linux/init.h>
11462c9fc5SMatt Porter #include <linux/kernel.h>
12462c9fc5SMatt Porter #include <linux/mfd/bcm590xx.h>
13462c9fc5SMatt Porter #include <linux/module.h>
14462c9fc5SMatt Porter #include <linux/of.h>
15462c9fc5SMatt Porter #include <linux/platform_device.h>
16462c9fc5SMatt Porter #include <linux/regulator/driver.h>
17462c9fc5SMatt Porter #include <linux/regulator/machine.h>
18462c9fc5SMatt Porter #include <linux/regulator/of_regulator.h>
19462c9fc5SMatt Porter #include <linux/slab.h>
20462c9fc5SMatt Porter
21c6466950SMatt Porter /* I2C slave 0 registers */
22462c9fc5SMatt Porter #define BCM590XX_RFLDOPMCTRL1 0x60
23462c9fc5SMatt Porter #define BCM590XX_IOSR1PMCTRL1 0x7a
24462c9fc5SMatt Porter #define BCM590XX_IOSR2PMCTRL1 0x7c
25462c9fc5SMatt Porter #define BCM590XX_CSRPMCTRL1 0x7e
26462c9fc5SMatt Porter #define BCM590XX_SDSR1PMCTRL1 0x82
27462c9fc5SMatt Porter #define BCM590XX_SDSR2PMCTRL1 0x86
28462c9fc5SMatt Porter #define BCM590XX_MSRPMCTRL1 0x8a
29462c9fc5SMatt Porter #define BCM590XX_VSRPMCTRL1 0x8e
30462c9fc5SMatt Porter #define BCM590XX_RFLDOCTRL 0x96
31462c9fc5SMatt Porter #define BCM590XX_CSRVOUT1 0xc0
32c6466950SMatt Porter
33c6466950SMatt Porter /* I2C slave 1 registers */
34c6466950SMatt Porter #define BCM590XX_GPLDO5PMCTRL1 0x16
35c6466950SMatt Porter #define BCM590XX_GPLDO6PMCTRL1 0x18
36c6466950SMatt Porter #define BCM590XX_GPLDO1CTRL 0x1a
37c6466950SMatt Porter #define BCM590XX_GPLDO2CTRL 0x1b
38c6466950SMatt Porter #define BCM590XX_GPLDO3CTRL 0x1c
39c6466950SMatt Porter #define BCM590XX_GPLDO4CTRL 0x1d
40c6466950SMatt Porter #define BCM590XX_GPLDO5CTRL 0x1e
41c6466950SMatt Porter #define BCM590XX_GPLDO6CTRL 0x1f
42c6466950SMatt Porter #define BCM590XX_OTG_CTRL 0x40
43c6466950SMatt Porter #define BCM590XX_GPLDO1PMCTRL1 0x57
44c6466950SMatt Porter #define BCM590XX_GPLDO2PMCTRL1 0x59
45c6466950SMatt Porter #define BCM590XX_GPLDO3PMCTRL1 0x5b
46c6466950SMatt Porter #define BCM590XX_GPLDO4PMCTRL1 0x5d
47c6466950SMatt Porter
48c6466950SMatt Porter #define BCM590XX_REG_ENABLE BIT(7)
49c6466950SMatt Porter #define BCM590XX_VBUS_ENABLE BIT(2)
50462c9fc5SMatt Porter #define BCM590XX_LDO_VSEL_MASK GENMASK(5, 3)
51462c9fc5SMatt Porter #define BCM590XX_SR_VSEL_MASK GENMASK(5, 0)
52462c9fc5SMatt Porter
53c6466950SMatt Porter /*
54c6466950SMatt Porter * RFLDO to VSR regulators are
55c6466950SMatt Porter * accessed via I2C slave 0
56c6466950SMatt Porter */
57c6466950SMatt Porter
58462c9fc5SMatt Porter /* LDO regulator IDs */
59462c9fc5SMatt Porter #define BCM590XX_REG_RFLDO 0
60462c9fc5SMatt Porter #define BCM590XX_REG_CAMLDO1 1
61462c9fc5SMatt Porter #define BCM590XX_REG_CAMLDO2 2
62462c9fc5SMatt Porter #define BCM590XX_REG_SIMLDO1 3
63462c9fc5SMatt Porter #define BCM590XX_REG_SIMLDO2 4
64462c9fc5SMatt Porter #define BCM590XX_REG_SDLDO 5
65462c9fc5SMatt Porter #define BCM590XX_REG_SDXLDO 6
66462c9fc5SMatt Porter #define BCM590XX_REG_MMCLDO1 7
67462c9fc5SMatt Porter #define BCM590XX_REG_MMCLDO2 8
68462c9fc5SMatt Porter #define BCM590XX_REG_AUDLDO 9
69462c9fc5SMatt Porter #define BCM590XX_REG_MICLDO 10
70462c9fc5SMatt Porter #define BCM590XX_REG_USBLDO 11
71462c9fc5SMatt Porter #define BCM590XX_REG_VIBLDO 12
72462c9fc5SMatt Porter
73462c9fc5SMatt Porter /* DCDC regulator IDs */
74462c9fc5SMatt Porter #define BCM590XX_REG_CSR 13
75462c9fc5SMatt Porter #define BCM590XX_REG_IOSR1 14
76462c9fc5SMatt Porter #define BCM590XX_REG_IOSR2 15
77462c9fc5SMatt Porter #define BCM590XX_REG_MSR 16
78462c9fc5SMatt Porter #define BCM590XX_REG_SDSR1 17
79462c9fc5SMatt Porter #define BCM590XX_REG_SDSR2 18
80462c9fc5SMatt Porter #define BCM590XX_REG_VSR 19
81462c9fc5SMatt Porter
82c6466950SMatt Porter /*
83c6466950SMatt Porter * GPLDO1 to VBUS regulators are
84c6466950SMatt Porter * accessed via I2C slave 1
85c6466950SMatt Porter */
86c6466950SMatt Porter
87c6466950SMatt Porter #define BCM590XX_REG_GPLDO1 20
88c6466950SMatt Porter #define BCM590XX_REG_GPLDO2 21
89c6466950SMatt Porter #define BCM590XX_REG_GPLDO3 22
90c6466950SMatt Porter #define BCM590XX_REG_GPLDO4 23
91c6466950SMatt Porter #define BCM590XX_REG_GPLDO5 24
92c6466950SMatt Porter #define BCM590XX_REG_GPLDO6 25
93c6466950SMatt Porter #define BCM590XX_REG_VBUS 26
94c6466950SMatt Porter
95c6466950SMatt Porter #define BCM590XX_NUM_REGS 27
96462c9fc5SMatt Porter
97462c9fc5SMatt Porter #define BCM590XX_REG_IS_LDO(n) (n < BCM590XX_REG_CSR)
98c6466950SMatt Porter #define BCM590XX_REG_IS_GPLDO(n) \
99c6466950SMatt Porter ((n > BCM590XX_REG_VSR) && (n < BCM590XX_REG_VBUS))
100c6466950SMatt Porter #define BCM590XX_REG_IS_VBUS(n) (n == BCM590XX_REG_VBUS)
101462c9fc5SMatt Porter
102462c9fc5SMatt Porter /* LDO group A: supported voltages in microvolts */
103462c9fc5SMatt Porter static const unsigned int ldo_a_table[] = {
104462c9fc5SMatt Porter 1200000, 1800000, 2500000, 2700000, 2800000,
105462c9fc5SMatt Porter 2900000, 3000000, 3300000,
106462c9fc5SMatt Porter };
107462c9fc5SMatt Porter
108462c9fc5SMatt Porter /* LDO group C: supported voltages in microvolts */
109462c9fc5SMatt Porter static const unsigned int ldo_c_table[] = {
110462c9fc5SMatt Porter 3100000, 1800000, 2500000, 2700000, 2800000,
111462c9fc5SMatt Porter 2900000, 3000000, 3300000,
112462c9fc5SMatt Porter };
113462c9fc5SMatt Porter
114636f4a31SGraham Williams static const unsigned int ldo_vbus[] = {
115636f4a31SGraham Williams 5000000,
116636f4a31SGraham Williams };
117636f4a31SGraham Williams
118462c9fc5SMatt Porter /* DCDC group CSR: supported voltages in microvolts */
11960ab7f41SMatti Vaittinen static const struct linear_range dcdc_csr_ranges[] = {
120462c9fc5SMatt Porter REGULATOR_LINEAR_RANGE(860000, 2, 50, 10000),
121462c9fc5SMatt Porter REGULATOR_LINEAR_RANGE(1360000, 51, 55, 20000),
122462c9fc5SMatt Porter REGULATOR_LINEAR_RANGE(900000, 56, 63, 0),
123462c9fc5SMatt Porter };
124462c9fc5SMatt Porter
125462c9fc5SMatt Porter /* DCDC group IOSR1: supported voltages in microvolts */
12660ab7f41SMatti Vaittinen static const struct linear_range dcdc_iosr1_ranges[] = {
127462c9fc5SMatt Porter REGULATOR_LINEAR_RANGE(860000, 2, 51, 10000),
128462c9fc5SMatt Porter REGULATOR_LINEAR_RANGE(1500000, 52, 52, 0),
129462c9fc5SMatt Porter REGULATOR_LINEAR_RANGE(1800000, 53, 53, 0),
130462c9fc5SMatt Porter REGULATOR_LINEAR_RANGE(900000, 54, 63, 0),
131462c9fc5SMatt Porter };
132462c9fc5SMatt Porter
133462c9fc5SMatt Porter /* DCDC group SDSR1: supported voltages in microvolts */
13460ab7f41SMatti Vaittinen static const struct linear_range dcdc_sdsr1_ranges[] = {
135462c9fc5SMatt Porter REGULATOR_LINEAR_RANGE(860000, 2, 50, 10000),
136462c9fc5SMatt Porter REGULATOR_LINEAR_RANGE(1340000, 51, 51, 0),
137462c9fc5SMatt Porter REGULATOR_LINEAR_RANGE(900000, 52, 63, 0),
138462c9fc5SMatt Porter };
139462c9fc5SMatt Porter
140462c9fc5SMatt Porter struct bcm590xx_info {
141462c9fc5SMatt Porter const char *name;
142462c9fc5SMatt Porter const char *vin_name;
143462c9fc5SMatt Porter u8 n_voltages;
144462c9fc5SMatt Porter const unsigned int *volt_table;
145462c9fc5SMatt Porter u8 n_linear_ranges;
14660ab7f41SMatti Vaittinen const struct linear_range *linear_ranges;
147462c9fc5SMatt Porter };
148462c9fc5SMatt Porter
149462c9fc5SMatt Porter #define BCM590XX_REG_TABLE(_name, _table) \
150462c9fc5SMatt Porter { \
151462c9fc5SMatt Porter .name = #_name, \
152462c9fc5SMatt Porter .n_voltages = ARRAY_SIZE(_table), \
153462c9fc5SMatt Porter .volt_table = _table, \
154462c9fc5SMatt Porter }
155462c9fc5SMatt Porter
156462c9fc5SMatt Porter #define BCM590XX_REG_RANGES(_name, _ranges) \
157462c9fc5SMatt Porter { \
158462c9fc5SMatt Porter .name = #_name, \
1591e791405STim Kryger .n_voltages = 64, \
160462c9fc5SMatt Porter .n_linear_ranges = ARRAY_SIZE(_ranges), \
161462c9fc5SMatt Porter .linear_ranges = _ranges, \
162462c9fc5SMatt Porter }
163462c9fc5SMatt Porter
164462c9fc5SMatt Porter static struct bcm590xx_info bcm590xx_regs[] = {
165462c9fc5SMatt Porter BCM590XX_REG_TABLE(rfldo, ldo_a_table),
166462c9fc5SMatt Porter BCM590XX_REG_TABLE(camldo1, ldo_c_table),
167462c9fc5SMatt Porter BCM590XX_REG_TABLE(camldo2, ldo_c_table),
168462c9fc5SMatt Porter BCM590XX_REG_TABLE(simldo1, ldo_a_table),
169462c9fc5SMatt Porter BCM590XX_REG_TABLE(simldo2, ldo_a_table),
170462c9fc5SMatt Porter BCM590XX_REG_TABLE(sdldo, ldo_c_table),
171462c9fc5SMatt Porter BCM590XX_REG_TABLE(sdxldo, ldo_a_table),
172462c9fc5SMatt Porter BCM590XX_REG_TABLE(mmcldo1, ldo_a_table),
173462c9fc5SMatt Porter BCM590XX_REG_TABLE(mmcldo2, ldo_a_table),
174462c9fc5SMatt Porter BCM590XX_REG_TABLE(audldo, ldo_a_table),
175462c9fc5SMatt Porter BCM590XX_REG_TABLE(micldo, ldo_a_table),
176462c9fc5SMatt Porter BCM590XX_REG_TABLE(usbldo, ldo_a_table),
177462c9fc5SMatt Porter BCM590XX_REG_TABLE(vibldo, ldo_c_table),
178462c9fc5SMatt Porter BCM590XX_REG_RANGES(csr, dcdc_csr_ranges),
179462c9fc5SMatt Porter BCM590XX_REG_RANGES(iosr1, dcdc_iosr1_ranges),
180462c9fc5SMatt Porter BCM590XX_REG_RANGES(iosr2, dcdc_iosr1_ranges),
181462c9fc5SMatt Porter BCM590XX_REG_RANGES(msr, dcdc_iosr1_ranges),
182462c9fc5SMatt Porter BCM590XX_REG_RANGES(sdsr1, dcdc_sdsr1_ranges),
183462c9fc5SMatt Porter BCM590XX_REG_RANGES(sdsr2, dcdc_iosr1_ranges),
184462c9fc5SMatt Porter BCM590XX_REG_RANGES(vsr, dcdc_iosr1_ranges),
185c6466950SMatt Porter BCM590XX_REG_TABLE(gpldo1, ldo_a_table),
186c6466950SMatt Porter BCM590XX_REG_TABLE(gpldo2, ldo_a_table),
187c6466950SMatt Porter BCM590XX_REG_TABLE(gpldo3, ldo_a_table),
188c6466950SMatt Porter BCM590XX_REG_TABLE(gpldo4, ldo_a_table),
189c6466950SMatt Porter BCM590XX_REG_TABLE(gpldo5, ldo_a_table),
190c6466950SMatt Porter BCM590XX_REG_TABLE(gpldo6, ldo_a_table),
191636f4a31SGraham Williams BCM590XX_REG_TABLE(vbus, ldo_vbus),
192462c9fc5SMatt Porter };
193462c9fc5SMatt Porter
194462c9fc5SMatt Porter struct bcm590xx_reg {
195462c9fc5SMatt Porter struct regulator_desc *desc;
196462c9fc5SMatt Porter struct bcm590xx *mfd;
197462c9fc5SMatt Porter };
198462c9fc5SMatt Porter
bcm590xx_get_vsel_register(int id)199462c9fc5SMatt Porter static int bcm590xx_get_vsel_register(int id)
200462c9fc5SMatt Porter {
201462c9fc5SMatt Porter if (BCM590XX_REG_IS_LDO(id))
202462c9fc5SMatt Porter return BCM590XX_RFLDOCTRL + id;
203c6466950SMatt Porter else if (BCM590XX_REG_IS_GPLDO(id))
204c6466950SMatt Porter return BCM590XX_GPLDO1CTRL + id;
205462c9fc5SMatt Porter else
206462c9fc5SMatt Porter return BCM590XX_CSRVOUT1 + (id - BCM590XX_REG_CSR) * 3;
207462c9fc5SMatt Porter }
208462c9fc5SMatt Porter
bcm590xx_get_enable_register(int id)209462c9fc5SMatt Porter static int bcm590xx_get_enable_register(int id)
210462c9fc5SMatt Porter {
211462c9fc5SMatt Porter int reg = 0;
212462c9fc5SMatt Porter
213462c9fc5SMatt Porter if (BCM590XX_REG_IS_LDO(id))
214462c9fc5SMatt Porter reg = BCM590XX_RFLDOPMCTRL1 + id * 2;
215c6466950SMatt Porter else if (BCM590XX_REG_IS_GPLDO(id))
216c6466950SMatt Porter reg = BCM590XX_GPLDO1PMCTRL1 + id * 2;
217462c9fc5SMatt Porter else
218462c9fc5SMatt Porter switch (id) {
219462c9fc5SMatt Porter case BCM590XX_REG_CSR:
220462c9fc5SMatt Porter reg = BCM590XX_CSRPMCTRL1;
221462c9fc5SMatt Porter break;
222462c9fc5SMatt Porter case BCM590XX_REG_IOSR1:
223462c9fc5SMatt Porter reg = BCM590XX_IOSR1PMCTRL1;
224462c9fc5SMatt Porter break;
225462c9fc5SMatt Porter case BCM590XX_REG_IOSR2:
226462c9fc5SMatt Porter reg = BCM590XX_IOSR2PMCTRL1;
227462c9fc5SMatt Porter break;
228462c9fc5SMatt Porter case BCM590XX_REG_MSR:
229462c9fc5SMatt Porter reg = BCM590XX_MSRPMCTRL1;
230462c9fc5SMatt Porter break;
231462c9fc5SMatt Porter case BCM590XX_REG_SDSR1:
232462c9fc5SMatt Porter reg = BCM590XX_SDSR1PMCTRL1;
233462c9fc5SMatt Porter break;
234462c9fc5SMatt Porter case BCM590XX_REG_SDSR2:
235462c9fc5SMatt Porter reg = BCM590XX_SDSR2PMCTRL1;
236462c9fc5SMatt Porter break;
237d6afa2beSAxel Lin case BCM590XX_REG_VSR:
238d6afa2beSAxel Lin reg = BCM590XX_VSRPMCTRL1;
239d6afa2beSAxel Lin break;
240c6466950SMatt Porter case BCM590XX_REG_VBUS:
241c6466950SMatt Porter reg = BCM590XX_OTG_CTRL;
242d6afa2beSAxel Lin break;
243f3f400e7SJavier Martinez Canillas }
244462c9fc5SMatt Porter
245c6466950SMatt Porter
246462c9fc5SMatt Porter return reg;
247462c9fc5SMatt Porter }
248462c9fc5SMatt Porter
24920f860c1SBhumika Goyal static const struct regulator_ops bcm590xx_ops_ldo = {
250462c9fc5SMatt Porter .is_enabled = regulator_is_enabled_regmap,
251462c9fc5SMatt Porter .enable = regulator_enable_regmap,
252462c9fc5SMatt Porter .disable = regulator_disable_regmap,
253462c9fc5SMatt Porter .get_voltage_sel = regulator_get_voltage_sel_regmap,
254462c9fc5SMatt Porter .set_voltage_sel = regulator_set_voltage_sel_regmap,
255462c9fc5SMatt Porter .list_voltage = regulator_list_voltage_table,
256462c9fc5SMatt Porter .map_voltage = regulator_map_voltage_iterate,
257462c9fc5SMatt Porter };
258462c9fc5SMatt Porter
25920f860c1SBhumika Goyal static const struct regulator_ops bcm590xx_ops_dcdc = {
260462c9fc5SMatt Porter .is_enabled = regulator_is_enabled_regmap,
261462c9fc5SMatt Porter .enable = regulator_enable_regmap,
262462c9fc5SMatt Porter .disable = regulator_disable_regmap,
263462c9fc5SMatt Porter .get_voltage_sel = regulator_get_voltage_sel_regmap,
264462c9fc5SMatt Porter .set_voltage_sel = regulator_set_voltage_sel_regmap,
265462c9fc5SMatt Porter .list_voltage = regulator_list_voltage_linear_range,
266462c9fc5SMatt Porter .map_voltage = regulator_map_voltage_linear_range,
267462c9fc5SMatt Porter };
268462c9fc5SMatt Porter
26920f860c1SBhumika Goyal static const struct regulator_ops bcm590xx_ops_vbus = {
270c6466950SMatt Porter .is_enabled = regulator_is_enabled_regmap,
271c6466950SMatt Porter .enable = regulator_enable_regmap,
272c6466950SMatt Porter .disable = regulator_disable_regmap,
273c6466950SMatt Porter };
274c6466950SMatt Porter
bcm590xx_probe(struct platform_device * pdev)275462c9fc5SMatt Porter static int bcm590xx_probe(struct platform_device *pdev)
276462c9fc5SMatt Porter {
277462c9fc5SMatt Porter struct bcm590xx *bcm590xx = dev_get_drvdata(pdev->dev.parent);
278462c9fc5SMatt Porter struct bcm590xx_reg *pmu;
279462c9fc5SMatt Porter struct regulator_config config = { };
280462c9fc5SMatt Porter struct bcm590xx_info *info;
281462c9fc5SMatt Porter struct regulator_dev *rdev;
282462c9fc5SMatt Porter int i;
283462c9fc5SMatt Porter
284462c9fc5SMatt Porter pmu = devm_kzalloc(&pdev->dev, sizeof(*pmu), GFP_KERNEL);
285c969faadSJingoo Han if (!pmu)
286462c9fc5SMatt Porter return -ENOMEM;
287462c9fc5SMatt Porter
288462c9fc5SMatt Porter pmu->mfd = bcm590xx;
289462c9fc5SMatt Porter
290462c9fc5SMatt Porter platform_set_drvdata(pdev, pmu);
291462c9fc5SMatt Porter
292a86854d0SKees Cook pmu->desc = devm_kcalloc(&pdev->dev,
293a86854d0SKees Cook BCM590XX_NUM_REGS,
294a86854d0SKees Cook sizeof(struct regulator_desc),
295a86854d0SKees Cook GFP_KERNEL);
296c969faadSJingoo Han if (!pmu->desc)
297462c9fc5SMatt Porter return -ENOMEM;
298462c9fc5SMatt Porter
299462c9fc5SMatt Porter info = bcm590xx_regs;
300462c9fc5SMatt Porter
301462c9fc5SMatt Porter for (i = 0; i < BCM590XX_NUM_REGS; i++, info++) {
302462c9fc5SMatt Porter /* Register the regulators */
303462c9fc5SMatt Porter pmu->desc[i].name = info->name;
304a4e73625SAxel Lin pmu->desc[i].of_match = of_match_ptr(info->name);
305a4e73625SAxel Lin pmu->desc[i].regulators_node = of_match_ptr("regulators");
306462c9fc5SMatt Porter pmu->desc[i].supply_name = info->vin_name;
307462c9fc5SMatt Porter pmu->desc[i].id = i;
308462c9fc5SMatt Porter pmu->desc[i].volt_table = info->volt_table;
309462c9fc5SMatt Porter pmu->desc[i].n_voltages = info->n_voltages;
310462c9fc5SMatt Porter pmu->desc[i].linear_ranges = info->linear_ranges;
311462c9fc5SMatt Porter pmu->desc[i].n_linear_ranges = info->n_linear_ranges;
312462c9fc5SMatt Porter
313c6466950SMatt Porter if ((BCM590XX_REG_IS_LDO(i)) || (BCM590XX_REG_IS_GPLDO(i))) {
314462c9fc5SMatt Porter pmu->desc[i].ops = &bcm590xx_ops_ldo;
315462c9fc5SMatt Porter pmu->desc[i].vsel_mask = BCM590XX_LDO_VSEL_MASK;
316c6466950SMatt Porter } else if (BCM590XX_REG_IS_VBUS(i))
317c6466950SMatt Porter pmu->desc[i].ops = &bcm590xx_ops_vbus;
318c6466950SMatt Porter else {
319462c9fc5SMatt Porter pmu->desc[i].ops = &bcm590xx_ops_dcdc;
320462c9fc5SMatt Porter pmu->desc[i].vsel_mask = BCM590XX_SR_VSEL_MASK;
321462c9fc5SMatt Porter }
322462c9fc5SMatt Porter
323c6466950SMatt Porter if (BCM590XX_REG_IS_VBUS(i))
324c6466950SMatt Porter pmu->desc[i].enable_mask = BCM590XX_VBUS_ENABLE;
325c6466950SMatt Porter else {
326462c9fc5SMatt Porter pmu->desc[i].vsel_reg = bcm590xx_get_vsel_register(i);
327462c9fc5SMatt Porter pmu->desc[i].enable_is_inverted = true;
328462c9fc5SMatt Porter pmu->desc[i].enable_mask = BCM590XX_REG_ENABLE;
329c6466950SMatt Porter }
330462c9fc5SMatt Porter pmu->desc[i].enable_reg = bcm590xx_get_enable_register(i);
331462c9fc5SMatt Porter pmu->desc[i].type = REGULATOR_VOLTAGE;
332462c9fc5SMatt Porter pmu->desc[i].owner = THIS_MODULE;
333462c9fc5SMatt Porter
334462c9fc5SMatt Porter config.dev = bcm590xx->dev;
335462c9fc5SMatt Porter config.driver_data = pmu;
336c6466950SMatt Porter if (BCM590XX_REG_IS_GPLDO(i) || BCM590XX_REG_IS_VBUS(i))
337c6466950SMatt Porter config.regmap = bcm590xx->regmap_sec;
338c6466950SMatt Porter else
339c6466950SMatt Porter config.regmap = bcm590xx->regmap_pri;
340462c9fc5SMatt Porter
341462c9fc5SMatt Porter rdev = devm_regulator_register(&pdev->dev, &pmu->desc[i],
342462c9fc5SMatt Porter &config);
343462c9fc5SMatt Porter if (IS_ERR(rdev)) {
344462c9fc5SMatt Porter dev_err(bcm590xx->dev,
345462c9fc5SMatt Porter "failed to register %s regulator\n",
346462c9fc5SMatt Porter pdev->name);
347462c9fc5SMatt Porter return PTR_ERR(rdev);
348462c9fc5SMatt Porter }
349462c9fc5SMatt Porter }
350462c9fc5SMatt Porter
351462c9fc5SMatt Porter return 0;
352462c9fc5SMatt Porter }
353462c9fc5SMatt Porter
354462c9fc5SMatt Porter static struct platform_driver bcm590xx_regulator_driver = {
355462c9fc5SMatt Porter .driver = {
356462c9fc5SMatt Porter .name = "bcm590xx-vregs",
357*259b93b2SDouglas Anderson .probe_type = PROBE_PREFER_ASYNCHRONOUS,
358462c9fc5SMatt Porter },
359462c9fc5SMatt Porter .probe = bcm590xx_probe,
360462c9fc5SMatt Porter };
361462c9fc5SMatt Porter module_platform_driver(bcm590xx_regulator_driver);
362462c9fc5SMatt Porter
363462c9fc5SMatt Porter MODULE_AUTHOR("Matt Porter <mporter@linaro.org>");
364462c9fc5SMatt Porter MODULE_DESCRIPTION("BCM590xx voltage regulator driver");
365462c9fc5SMatt Porter MODULE_LICENSE("GPL v2");
366c9347431SAxel Lin MODULE_ALIAS("platform:bcm590xx-vregs");
367