1// SPDX-License-Identifier: GPL-2.0+
2//
3// Regulator driver for ATC260x PMICs
4//
5// Copyright (C) 2019 Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
6// Copyright (C) 2020 Cristian Ciocaltea <cristian.ciocaltea@gmail.com>
7
8#include <linux/mfd/atc260x/core.h>
9#include <linux/module.h>
10#include <linux/of.h>
11#include <linux/platform_device.h>
12#include <linux/regmap.h>
13#include <linux/regulator/driver.h>
14
15struct atc260x_regulator_data {
16	int voltage_time_dcdc;
17	int voltage_time_ldo;
18};
19
20static const struct linear_range atc2603c_dcdc_voltage_ranges[] = {
21	REGULATOR_LINEAR_RANGE(1300000, 0, 13, 50000),
22	REGULATOR_LINEAR_RANGE(1950000, 14, 15, 100000),
23};
24
25static const struct linear_range atc2609a_dcdc_voltage_ranges[] = {
26	REGULATOR_LINEAR_RANGE(600000, 0, 127, 6250),
27	REGULATOR_LINEAR_RANGE(1400000, 128, 232, 25000),
28};
29
30static const struct linear_range atc2609a_ldo_voltage_ranges0[] = {
31	REGULATOR_LINEAR_RANGE(700000, 0, 15, 100000),
32	REGULATOR_LINEAR_RANGE(2100000, 0, 12, 100000),
33};
34
35static const struct linear_range atc2609a_ldo_voltage_ranges1[] = {
36	REGULATOR_LINEAR_RANGE(850000, 0, 15, 100000),
37	REGULATOR_LINEAR_RANGE(2100000, 0, 11, 100000),
38};
39
40static const unsigned int atc260x_ldo_voltage_range_sel[] = {
41	0x0, 0x1,
42};
43
44static int atc260x_dcdc_set_voltage_time_sel(struct regulator_dev *rdev,
45					     unsigned int old_selector,
46					     unsigned int new_selector)
47{
48	struct atc260x_regulator_data *data = rdev_get_drvdata(rdev);
49
50	if (new_selector > old_selector)
51		return data->voltage_time_dcdc;
52
53	return 0;
54}
55
56static int atc260x_ldo_set_voltage_time_sel(struct regulator_dev *rdev,
57					    unsigned int old_selector,
58					    unsigned int new_selector)
59{
60	struct atc260x_regulator_data *data = rdev_get_drvdata(rdev);
61
62	if (new_selector > old_selector)
63		return data->voltage_time_ldo;
64
65	return 0;
66}
67
68static const struct regulator_ops atc260x_dcdc_ops = {
69	.enable	= regulator_enable_regmap,
70	.disable = regulator_disable_regmap,
71	.is_enabled = regulator_is_enabled_regmap,
72	.list_voltage = regulator_list_voltage_linear,
73	.set_voltage_sel = regulator_set_voltage_sel_regmap,
74	.get_voltage_sel = regulator_get_voltage_sel_regmap,
75	.set_voltage_time_sel = atc260x_dcdc_set_voltage_time_sel,
76};
77
78static const struct regulator_ops atc260x_ldo_ops = {
79	.enable	= regulator_enable_regmap,
80	.disable = regulator_disable_regmap,
81	.is_enabled = regulator_is_enabled_regmap,
82	.list_voltage = regulator_list_voltage_linear,
83	.set_voltage_sel = regulator_set_voltage_sel_regmap,
84	.get_voltage_sel = regulator_get_voltage_sel_regmap,
85	.set_voltage_time_sel = atc260x_ldo_set_voltage_time_sel,
86};
87
88static const struct regulator_ops atc260x_ldo_bypass_ops = {
89	.enable	= regulator_enable_regmap,
90	.disable = regulator_disable_regmap,
91	.is_enabled = regulator_is_enabled_regmap,
92	.list_voltage = regulator_list_voltage_linear,
93	.set_voltage_sel = regulator_set_voltage_sel_regmap,
94	.get_voltage_sel = regulator_get_voltage_sel_regmap,
95	.set_voltage_time_sel = atc260x_ldo_set_voltage_time_sel,
96	.set_bypass = regulator_set_bypass_regmap,
97	.get_bypass = regulator_get_bypass_regmap,
98};
99
100static const struct regulator_ops atc260x_ldo_bypass_discharge_ops = {
101	.enable	= regulator_enable_regmap,
102	.disable = regulator_disable_regmap,
103	.is_enabled = regulator_is_enabled_regmap,
104	.list_voltage = regulator_list_voltage_linear,
105	.set_voltage_sel = regulator_set_voltage_sel_regmap,
106	.get_voltage_sel = regulator_get_voltage_sel_regmap,
107	.set_voltage_time_sel = atc260x_ldo_set_voltage_time_sel,
108	.set_bypass = regulator_set_bypass_regmap,
109	.get_bypass = regulator_get_bypass_regmap,
110	.set_active_discharge = regulator_set_active_discharge_regmap,
111};
112
113static const struct regulator_ops atc260x_dcdc_range_ops = {
114	.enable	= regulator_enable_regmap,
115	.disable = regulator_disable_regmap,
116	.is_enabled = regulator_is_enabled_regmap,
117	.list_voltage = regulator_list_voltage_linear_range,
118	.set_voltage_sel = regulator_set_voltage_sel_regmap,
119	.get_voltage_sel = regulator_get_voltage_sel_regmap,
120	.set_voltage_time_sel = atc260x_dcdc_set_voltage_time_sel,
121};
122
123static const struct regulator_ops atc260x_ldo_range_pick_ops = {
124	.enable	= regulator_enable_regmap,
125	.disable = regulator_disable_regmap,
126	.is_enabled = regulator_is_enabled_regmap,
127	.list_voltage = regulator_list_voltage_pickable_linear_range,
128	.set_voltage_sel = regulator_set_voltage_sel_pickable_regmap,
129	.get_voltage_sel = regulator_get_voltage_sel_pickable_regmap,
130	.set_voltage_time_sel = atc260x_ldo_set_voltage_time_sel,
131};
132
133static const struct regulator_ops atc260x_dcdc_fixed_ops = {
134	.list_voltage = regulator_list_voltage_linear,
135	.set_voltage_sel = regulator_set_voltage_sel_regmap,
136	.get_voltage_sel = regulator_get_voltage_sel_regmap,
137	.set_voltage_time_sel = atc260x_dcdc_set_voltage_time_sel,
138};
139
140static const struct regulator_ops atc260x_ldo_fixed_ops = {
141	.list_voltage = regulator_list_voltage_linear,
142	.set_voltage_sel = regulator_set_voltage_sel_regmap,
143	.get_voltage_sel = regulator_get_voltage_sel_regmap,
144	.set_voltage_time_sel = atc260x_ldo_set_voltage_time_sel,
145};
146
147static const struct regulator_ops atc260x_no_ops = {
148};
149
150/*
151 * Note LDO8 is not documented in datasheet (v2.4), but supported
152 * in the vendor's driver implementation (xapp-le-kernel).
153 */
154enum atc2603c_reg_ids {
155	ATC2603C_ID_DCDC1,
156	ATC2603C_ID_DCDC2,
157	ATC2603C_ID_DCDC3,
158	ATC2603C_ID_LDO1,
159	ATC2603C_ID_LDO2,
160	ATC2603C_ID_LDO3,
161	ATC2603C_ID_LDO5,
162	ATC2603C_ID_LDO6,
163	ATC2603C_ID_LDO7,
164	ATC2603C_ID_LDO8,
165	ATC2603C_ID_LDO11,
166	ATC2603C_ID_LDO12,
167	ATC2603C_ID_SWITCHLDO1,
168	ATC2603C_ID_MAX,
169};
170
171#define atc2603c_reg_desc_dcdc(num, min, step, n_volt, vsel_h, vsel_l) { \
172	.name = "DCDC"#num, \
173	.supply_name = "dcdc"#num, \
174	.of_match = of_match_ptr("dcdc"#num), \
175	.regulators_node = of_match_ptr("regulators"), \
176	.id = ATC2603C_ID_DCDC##num, \
177	.ops = &atc260x_dcdc_ops, \
178	.type = REGULATOR_VOLTAGE, \
179	.min_uV = min, \
180	.uV_step = step, \
181	.n_voltages = n_volt, \
182	.vsel_reg = ATC2603C_PMU_DC##num##_CTL0, \
183	.vsel_mask = GENMASK(vsel_h, vsel_l), \
184	.enable_reg = ATC2603C_PMU_DC##num##_CTL0, \
185	.enable_mask = BIT(15), \
186	.enable_time = 800, \
187	.owner = THIS_MODULE, \
188}
189
190#define atc2603c_reg_desc_dcdc_range(num, vsel_h, vsel_l) { \
191	.name = "DCDC"#num, \
192	.supply_name = "dcdc"#num, \
193	.of_match = of_match_ptr("dcdc"#num), \
194	.regulators_node = of_match_ptr("regulators"), \
195	.id = ATC2603C_ID_DCDC##num, \
196	.ops = &atc260x_dcdc_range_ops, \
197	.type = REGULATOR_VOLTAGE, \
198	.n_voltages = 16, \
199	.linear_ranges = atc2603c_dcdc_voltage_ranges, \
200	.n_linear_ranges = ARRAY_SIZE(atc2603c_dcdc_voltage_ranges), \
201	.vsel_reg = ATC2603C_PMU_DC##num##_CTL0, \
202	.vsel_mask = GENMASK(vsel_h, vsel_l), \
203	.enable_reg = ATC2603C_PMU_DC##num##_CTL0, \
204	.enable_mask = BIT(15), \
205	.enable_time = 800, \
206	.owner = THIS_MODULE, \
207}
208
209#define atc2603c_reg_desc_dcdc_fixed(num, min, step, n_volt, vsel_h, vsel_l) { \
210	.name = "DCDC"#num, \
211	.supply_name = "dcdc"#num, \
212	.of_match = of_match_ptr("dcdc"#num), \
213	.regulators_node = of_match_ptr("regulators"), \
214	.id = ATC2603C_ID_DCDC##num, \
215	.ops = &atc260x_dcdc_fixed_ops, \
216	.type = REGULATOR_VOLTAGE, \
217	.min_uV = min, \
218	.uV_step = step, \
219	.n_voltages = n_volt, \
220	.vsel_reg = ATC2603C_PMU_DC##num##_CTL0, \
221	.vsel_mask = GENMASK(vsel_h, vsel_l), \
222	.enable_time = 800, \
223	.owner = THIS_MODULE, \
224}
225
226#define atc2603c_reg_desc_ldo(num, min, step, n_volt, vsel_h, vsel_l) { \
227	.name = "LDO"#num, \
228	.supply_name = "ldo"#num, \
229	.of_match = of_match_ptr("ldo"#num), \
230	.regulators_node = of_match_ptr("regulators"), \
231	.id = ATC2603C_ID_LDO##num, \
232	.ops = &atc260x_ldo_ops, \
233	.type = REGULATOR_VOLTAGE, \
234	.min_uV = min, \
235	.uV_step = step, \
236	.n_voltages = n_volt, \
237	.vsel_reg = ATC2603C_PMU_LDO##num##_CTL, \
238	.vsel_mask = GENMASK(vsel_h, vsel_l), \
239	.enable_reg = ATC2603C_PMU_LDO##num##_CTL, \
240	.enable_mask = BIT(0), \
241	.enable_time = 2000, \
242	.owner = THIS_MODULE, \
243}
244
245#define atc2603c_reg_desc_ldo_fixed(num, min, step, n_volt, vsel_h, vsel_l) { \
246	.name = "LDO"#num, \
247	.supply_name = "ldo"#num, \
248	.of_match = of_match_ptr("ldo"#num), \
249	.regulators_node = of_match_ptr("regulators"), \
250	.id = ATC2603C_ID_LDO##num, \
251	.ops = &atc260x_ldo_fixed_ops, \
252	.type = REGULATOR_VOLTAGE, \
253	.min_uV = min, \
254	.uV_step = step, \
255	.n_voltages = n_volt, \
256	.vsel_reg = ATC2603C_PMU_LDO##num##_CTL, \
257	.vsel_mask = GENMASK(vsel_h, vsel_l), \
258	.enable_time = 2000, \
259	.owner = THIS_MODULE, \
260}
261
262#define atc2603c_reg_desc_ldo_noops(num, vfixed) { \
263	.name = "LDO"#num, \
264	.supply_name = "ldo"#num, \
265	.of_match = of_match_ptr("ldo"#num), \
266	.regulators_node = of_match_ptr("regulators"), \
267	.id = ATC2603C_ID_LDO##num, \
268	.ops = &atc260x_no_ops, \
269	.type = REGULATOR_VOLTAGE, \
270	.fixed_uV = vfixed, \
271	.n_voltages = 1, \
272	.owner = THIS_MODULE, \
273}
274
275#define atc2603c_reg_desc_ldo_switch(num, min, step, n_volt, vsel_h, vsel_l) { \
276	.name = "SWITCHLDO"#num, \
277	.supply_name = "switchldo"#num, \
278	.of_match = of_match_ptr("switchldo"#num), \
279	.regulators_node = of_match_ptr("regulators"), \
280	.id = ATC2603C_ID_SWITCHLDO##num, \
281	.ops = &atc260x_ldo_bypass_discharge_ops, \
282	.type = REGULATOR_VOLTAGE, \
283	.min_uV = min, \
284	.uV_step = step, \
285	.n_voltages = n_volt, \
286	.vsel_reg = ATC2603C_PMU_SWITCH_CTL, \
287	.vsel_mask = GENMASK(vsel_h, vsel_l), \
288	.enable_reg = ATC2603C_PMU_SWITCH_CTL, \
289	.enable_mask = BIT(15), \
290	.enable_is_inverted = true, \
291	.enable_time = 2000, \
292	.bypass_reg = ATC2603C_PMU_SWITCH_CTL, \
293	.bypass_mask = BIT(5), \
294	.active_discharge_reg = ATC2603C_PMU_SWITCH_CTL, \
295	.active_discharge_mask = BIT(1), \
296	.active_discharge_on = BIT(1), \
297	.owner = THIS_MODULE, \
298}
299
300static const struct regulator_desc atc2603c_reg[] = {
301	atc2603c_reg_desc_dcdc_fixed(1, 700000, 25000, 29, 11, 7),
302	atc2603c_reg_desc_dcdc_range(2, 12, 8),
303	atc2603c_reg_desc_dcdc_fixed(3, 2600000, 100000, 8, 11, 9),
304	atc2603c_reg_desc_ldo_fixed(1, 2600000, 100000, 8, 15, 13),
305	atc2603c_reg_desc_ldo_fixed(2, 2600000, 100000, 8, 15, 13),
306	atc2603c_reg_desc_ldo_fixed(3, 1500000, 100000, 6, 15, 13),
307	atc2603c_reg_desc_ldo(5, 2600000, 100000, 8, 15, 13),
308	atc2603c_reg_desc_ldo_fixed(6, 700000, 25000, 29, 15, 11),
309	atc2603c_reg_desc_ldo(7, 1500000, 100000, 6, 15, 13),
310	atc2603c_reg_desc_ldo(8, 2300000, 100000, 11, 15, 12),
311	atc2603c_reg_desc_ldo_fixed(11, 2600000, 100000, 8, 15, 13),
312	atc2603c_reg_desc_ldo_noops(12, 1800000),
313	atc2603c_reg_desc_ldo_switch(1, 3000000, 100000, 4, 4, 3),
314};
315
316static const struct regulator_desc atc2603c_reg_dcdc2_ver_b =
317	atc2603c_reg_desc_dcdc(2, 1000000, 50000, 18, 12, 8);
318
319enum atc2609a_reg_ids {
320	ATC2609A_ID_DCDC0,
321	ATC2609A_ID_DCDC1,
322	ATC2609A_ID_DCDC2,
323	ATC2609A_ID_DCDC3,
324	ATC2609A_ID_DCDC4,
325	ATC2609A_ID_LDO0,
326	ATC2609A_ID_LDO1,
327	ATC2609A_ID_LDO2,
328	ATC2609A_ID_LDO3,
329	ATC2609A_ID_LDO4,
330	ATC2609A_ID_LDO5,
331	ATC2609A_ID_LDO6,
332	ATC2609A_ID_LDO7,
333	ATC2609A_ID_LDO8,
334	ATC2609A_ID_LDO9,
335	ATC2609A_ID_MAX,
336};
337
338#define atc2609a_reg_desc_dcdc(num, en_bit) { \
339	.name = "DCDC"#num, \
340	.supply_name = "dcdc"#num, \
341	.of_match = of_match_ptr("dcdc"#num), \
342	.regulators_node = of_match_ptr("regulators"), \
343	.id = ATC2609A_ID_DCDC##num, \
344	.ops = &atc260x_dcdc_ops, \
345	.type = REGULATOR_VOLTAGE, \
346	.min_uV = 600000, \
347	.uV_step = 6250, \
348	.n_voltages = 256, \
349	.vsel_reg = ATC2609A_PMU_DC##num##_CTL0, \
350	.vsel_mask = GENMASK(15, 8), \
351	.enable_reg = ATC2609A_PMU_DC_OSC, \
352	.enable_mask = BIT(en_bit), \
353	.enable_time = 800, \
354	.owner = THIS_MODULE, \
355}
356
357#define atc2609a_reg_desc_dcdc_range(num, en_bit) { \
358	.name = "DCDC"#num, \
359	.supply_name = "dcdc"#num, \
360	.of_match = of_match_ptr("dcdc"#num), \
361	.regulators_node = of_match_ptr("regulators"), \
362	.id = ATC2609A_ID_DCDC##num, \
363	.ops = &atc260x_dcdc_range_ops, \
364	.type = REGULATOR_VOLTAGE, \
365	.n_voltages = 233, \
366	.linear_ranges = atc2609a_dcdc_voltage_ranges, \
367	.n_linear_ranges = ARRAY_SIZE(atc2609a_dcdc_voltage_ranges), \
368	.vsel_reg = ATC2609A_PMU_DC##num##_CTL0, \
369	.vsel_mask = GENMASK(15, 8), \
370	.enable_reg = ATC2609A_PMU_DC_OSC, \
371	.enable_mask = BIT(en_bit), \
372	.enable_time = 800, \
373	.owner = THIS_MODULE, \
374}
375
376#define atc2609a_reg_desc_ldo(num) { \
377	.name = "LDO"#num, \
378	.supply_name = "ldo"#num, \
379	.of_match = of_match_ptr("ldo"#num), \
380	.regulators_node = of_match_ptr("regulators"), \
381	.id = ATC2609A_ID_LDO##num, \
382	.ops = &atc260x_ldo_ops, \
383	.type = REGULATOR_VOLTAGE, \
384	.min_uV = 700000, \
385	.uV_step = 100000, \
386	.n_voltages = 16, \
387	.vsel_reg = ATC2609A_PMU_LDO##num##_CTL0, \
388	.vsel_mask = GENMASK(4, 1), \
389	.enable_reg = ATC2609A_PMU_LDO##num##_CTL0, \
390	.enable_mask = BIT(0), \
391	.enable_time = 2000, \
392	.owner = THIS_MODULE, \
393}
394
395#define atc2609a_reg_desc_ldo_bypass(num) { \
396	.name = "LDO"#num, \
397	.supply_name = "ldo"#num, \
398	.of_match = of_match_ptr("ldo"#num), \
399	.regulators_node = of_match_ptr("regulators"), \
400	.id = ATC2609A_ID_LDO##num, \
401	.ops = &atc260x_ldo_bypass_ops, \
402	.type = REGULATOR_VOLTAGE, \
403	.min_uV = 2300000, \
404	.uV_step = 100000, \
405	.n_voltages = 12, \
406	.vsel_reg = ATC2609A_PMU_LDO##num##_CTL0, \
407	.vsel_mask = GENMASK(5, 2), \
408	.enable_reg = ATC2609A_PMU_LDO##num##_CTL0, \
409	.enable_mask = BIT(0), \
410	.enable_time = 2000, \
411	.bypass_reg = ATC2609A_PMU_LDO##num##_CTL0, \
412	.bypass_mask = BIT(1), \
413	.owner = THIS_MODULE, \
414}
415
416#define atc2609a_reg_desc_ldo_range_pick(num, n_range, n_volt) { \
417	.name = "LDO"#num, \
418	.supply_name = "ldo"#num, \
419	.of_match = of_match_ptr("ldo"#num), \
420	.regulators_node = of_match_ptr("regulators"), \
421	.id = ATC2609A_ID_LDO##num, \
422	.ops = &atc260x_ldo_range_pick_ops, \
423	.type = REGULATOR_VOLTAGE, \
424	.linear_ranges = atc2609a_ldo_voltage_ranges##n_range, \
425	.n_linear_ranges = ARRAY_SIZE(atc2609a_ldo_voltage_ranges##n_range), \
426	.n_voltages = n_volt, \
427	.vsel_reg = ATC2609A_PMU_LDO##num##_CTL0, \
428	.vsel_mask = GENMASK(4, 1), \
429	.vsel_range_reg = ATC2609A_PMU_LDO##num##_CTL0, \
430	.vsel_range_mask = BIT(5), \
431	.linear_range_selectors_bitfield = atc260x_ldo_voltage_range_sel, \
432	.enable_reg = ATC2609A_PMU_LDO##num##_CTL0, \
433	.enable_mask = BIT(0), \
434	.enable_time = 2000, \
435	.owner = THIS_MODULE, \
436}
437
438#define atc2609a_reg_desc_ldo_fixed(num) { \
439	.name = "LDO"#num, \
440	.supply_name = "ldo"#num, \
441	.of_match = of_match_ptr("ldo"#num), \
442	.regulators_node = of_match_ptr("regulators"), \
443	.id = ATC2609A_ID_LDO##num, \
444	.ops = &atc260x_ldo_fixed_ops, \
445	.type = REGULATOR_VOLTAGE, \
446	.min_uV = 2600000, \
447	.uV_step = 100000, \
448	.n_voltages = 8, \
449	.vsel_reg = ATC2609A_PMU_LDO##num##_CTL, \
450	.vsel_mask = GENMASK(15, 13), \
451	.enable_time = 2000, \
452	.owner = THIS_MODULE, \
453}
454
455static const struct regulator_desc atc2609a_reg[] = {
456	atc2609a_reg_desc_dcdc(0, 4),
457	atc2609a_reg_desc_dcdc(1, 5),
458	atc2609a_reg_desc_dcdc(2, 6),
459	atc2609a_reg_desc_dcdc_range(3, 7),
460	atc2609a_reg_desc_dcdc(4, 8),
461	atc2609a_reg_desc_ldo_bypass(0),
462	atc2609a_reg_desc_ldo_bypass(1),
463	atc2609a_reg_desc_ldo_bypass(2),
464	atc2609a_reg_desc_ldo_range_pick(3, 0, 29),
465	atc2609a_reg_desc_ldo_range_pick(4, 0, 29),
466	atc2609a_reg_desc_ldo(5),
467	atc2609a_reg_desc_ldo_range_pick(6, 1, 28),
468	atc2609a_reg_desc_ldo_range_pick(7, 0, 29),
469	atc2609a_reg_desc_ldo_range_pick(8, 0, 29),
470	atc2609a_reg_desc_ldo_fixed(9),
471};
472
473static int atc260x_regulator_probe(struct platform_device *pdev)
474{
475	struct atc260x *atc260x = dev_get_drvdata(pdev->dev.parent);
476	struct device *dev = atc260x->dev;
477	struct atc260x_regulator_data *atc260x_data;
478	struct regulator_config config = {};
479	struct regulator_dev *atc260x_rdev;
480	const struct regulator_desc *regulators;
481	bool atc2603c_ver_b = false;
482	int i, nregulators;
483
484	atc260x_data = devm_kzalloc(&pdev->dev, sizeof(*atc260x_data), GFP_KERNEL);
485	if (!atc260x_data)
486		return -ENOMEM;
487
488	atc260x_data->voltage_time_dcdc = 350;
489	atc260x_data->voltage_time_ldo = 800;
490
491	switch (atc260x->ic_type) {
492	case ATC2603C:
493		regulators = atc2603c_reg;
494		nregulators = ATC2603C_ID_MAX;
495		atc2603c_ver_b = atc260x->ic_ver == ATC260X_B;
496		break;
497	case ATC2609A:
498		atc260x_data->voltage_time_dcdc = 250;
499		regulators = atc2609a_reg;
500		nregulators = ATC2609A_ID_MAX;
501		break;
502	default:
503		dev_err(dev, "unsupported ATC260X ID %d\n", atc260x->ic_type);
504		return -EINVAL;
505	}
506
507	config.dev = dev;
508	config.regmap = atc260x->regmap;
509	config.driver_data = atc260x_data;
510
511	/* Instantiate the regulators */
512	for (i = 0; i < nregulators; i++) {
513		if (atc2603c_ver_b && regulators[i].id == ATC2603C_ID_DCDC2)
514			atc260x_rdev = devm_regulator_register(&pdev->dev,
515							       &atc2603c_reg_dcdc2_ver_b,
516							       &config);
517		else
518			atc260x_rdev = devm_regulator_register(&pdev->dev,
519							       &regulators[i],
520							       &config);
521		if (IS_ERR(atc260x_rdev)) {
522			dev_err(dev, "failed to register regulator: %d\n", i);
523			return PTR_ERR(atc260x_rdev);
524		}
525	}
526
527	return 0;
528}
529
530static struct platform_driver atc260x_regulator_driver = {
531	.probe = atc260x_regulator_probe,
532	.driver = {
533		.name = "atc260x-regulator",
534		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
535	},
536};
537
538module_platform_driver(atc260x_regulator_driver);
539
540MODULE_DESCRIPTION("Regulator driver for ATC260x PMICs");
541MODULE_AUTHOR("Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>");
542MODULE_AUTHOR("Cristian Ciocaltea <cristian.ciocaltea@gmail.com>");
543MODULE_LICENSE("GPL");
544