Linux Audio

Check our new training course

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