1/*
2 * TI LP8788 MFD - ldo regulator driver
3 *
4 * Copyright 2012 Texas Instruments
5 *
6 * Author: Milo(Woogyom) Kim <milo.kim@ti.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 */
13
14#include <linux/module.h>
15#include <linux/slab.h>
16#include <linux/err.h>
17#include <linux/platform_device.h>
18#include <linux/regulator/driver.h>
19#include <linux/gpio.h>
20#include <linux/mfd/lp8788.h>
21
22/* register address */
23#define LP8788_EN_LDO_A			0x0D	/* DLDO 1 ~ 8 */
24#define LP8788_EN_LDO_B			0x0E	/* DLDO 9 ~ 12, ALDO 1 ~ 4 */
25#define LP8788_EN_LDO_C			0x0F	/* ALDO 5 ~ 10 */
26#define LP8788_EN_SEL			0x10
27#define LP8788_DLDO1_VOUT		0x2E
28#define LP8788_DLDO2_VOUT		0x2F
29#define LP8788_DLDO3_VOUT		0x30
30#define LP8788_DLDO4_VOUT		0x31
31#define LP8788_DLDO5_VOUT		0x32
32#define LP8788_DLDO6_VOUT		0x33
33#define LP8788_DLDO7_VOUT		0x34
34#define LP8788_DLDO8_VOUT		0x35
35#define LP8788_DLDO9_VOUT		0x36
36#define LP8788_DLDO10_VOUT		0x37
37#define LP8788_DLDO11_VOUT		0x38
38#define LP8788_DLDO12_VOUT		0x39
39#define LP8788_ALDO1_VOUT		0x3A
40#define LP8788_ALDO2_VOUT		0x3B
41#define LP8788_ALDO3_VOUT		0x3C
42#define LP8788_ALDO4_VOUT		0x3D
43#define LP8788_ALDO5_VOUT		0x3E
44#define LP8788_ALDO6_VOUT		0x3F
45#define LP8788_ALDO7_VOUT		0x40
46#define LP8788_ALDO8_VOUT		0x41
47#define LP8788_ALDO9_VOUT		0x42
48#define LP8788_ALDO10_VOUT		0x43
49#define LP8788_DLDO1_TIMESTEP		0x44
50
51/* mask/shift bits */
52#define LP8788_EN_DLDO1_M		BIT(0)	/* Addr 0Dh ~ 0Fh */
53#define LP8788_EN_DLDO2_M		BIT(1)
54#define LP8788_EN_DLDO3_M		BIT(2)
55#define LP8788_EN_DLDO4_M		BIT(3)
56#define LP8788_EN_DLDO5_M		BIT(4)
57#define LP8788_EN_DLDO6_M		BIT(5)
58#define LP8788_EN_DLDO7_M		BIT(6)
59#define LP8788_EN_DLDO8_M		BIT(7)
60#define LP8788_EN_DLDO9_M		BIT(0)
61#define LP8788_EN_DLDO10_M		BIT(1)
62#define LP8788_EN_DLDO11_M		BIT(2)
63#define LP8788_EN_DLDO12_M		BIT(3)
64#define LP8788_EN_ALDO1_M		BIT(4)
65#define LP8788_EN_ALDO2_M		BIT(5)
66#define LP8788_EN_ALDO3_M		BIT(6)
67#define LP8788_EN_ALDO4_M		BIT(7)
68#define LP8788_EN_ALDO5_M		BIT(0)
69#define LP8788_EN_ALDO6_M		BIT(1)
70#define LP8788_EN_ALDO7_M		BIT(2)
71#define LP8788_EN_ALDO8_M		BIT(3)
72#define LP8788_EN_ALDO9_M		BIT(4)
73#define LP8788_EN_ALDO10_M		BIT(5)
74#define LP8788_EN_SEL_DLDO911_M		BIT(0)	/* Addr 10h */
75#define LP8788_EN_SEL_DLDO7_M		BIT(1)
76#define LP8788_EN_SEL_ALDO7_M		BIT(2)
77#define LP8788_EN_SEL_ALDO5_M		BIT(3)
78#define LP8788_EN_SEL_ALDO234_M		BIT(4)
79#define LP8788_EN_SEL_ALDO1_M		BIT(5)
80#define LP8788_VOUT_5BIT_M		0x1F	/* Addr 2Eh ~ 43h */
81#define LP8788_VOUT_4BIT_M		0x0F
82#define LP8788_VOUT_3BIT_M		0x07
83#define LP8788_VOUT_1BIT_M		0x01
84#define LP8788_STARTUP_TIME_M		0xF8	/* Addr 44h ~ 59h */
85#define LP8788_STARTUP_TIME_S		3
86
87#define ENABLE_TIME_USEC		32
88#define ENABLE				GPIOF_OUT_INIT_HIGH
89#define DISABLE				GPIOF_OUT_INIT_LOW
90
91enum lp8788_ldo_id {
92	DLDO1,
93	DLDO2,
94	DLDO3,
95	DLDO4,
96	DLDO5,
97	DLDO6,
98	DLDO7,
99	DLDO8,
100	DLDO9,
101	DLDO10,
102	DLDO11,
103	DLDO12,
104	ALDO1,
105	ALDO2,
106	ALDO3,
107	ALDO4,
108	ALDO5,
109	ALDO6,
110	ALDO7,
111	ALDO8,
112	ALDO9,
113	ALDO10,
114};
115
116struct lp8788_ldo {
117	struct lp8788 *lp;
118	struct regulator_desc *desc;
119	struct regulator_dev *regulator;
120	struct lp8788_ldo_enable_pin *en_pin;
121};
122
123/* DLDO 1, 2, 3, 9 voltage table */
124static const int lp8788_dldo1239_vtbl[] = {
125	1800000, 1900000, 2000000, 2100000, 2200000, 2300000, 2400000, 2500000,
126	2600000, 2700000, 2800000, 2900000, 3000000, 2850000, 2850000, 2850000,
127	2850000, 2850000, 2850000, 2850000, 2850000, 2850000, 2850000, 2850000,
128	2850000, 2850000, 2850000, 2850000, 2850000, 2850000, 2850000, 2850000,
129};
130
131/* DLDO 4 voltage table */
132static const int lp8788_dldo4_vtbl[] = { 1800000, 3000000 };
133
134/* DLDO 5, 7, 8 and ALDO 6 voltage table */
135static const int lp8788_dldo578_aldo6_vtbl[] = {
136	1800000, 1900000, 2000000, 2100000, 2200000, 2300000, 2400000, 2500000,
137	2600000, 2700000, 2800000, 2900000, 3000000, 3000000, 3000000, 3000000,
138};
139
140/* DLDO 6 voltage table */
141static const int lp8788_dldo6_vtbl[] = {
142	3000000, 3100000, 3200000, 3300000, 3400000, 3500000, 3600000, 3600000,
143};
144
145/* DLDO 10, 11 voltage table */
146static const int lp8788_dldo1011_vtbl[] = {
147	1100000, 1150000, 1200000, 1250000, 1300000, 1350000, 1400000, 1450000,
148	1500000, 1500000, 1500000, 1500000, 1500000, 1500000, 1500000, 1500000,
149};
150
151/* ALDO 1 voltage table */
152static const int lp8788_aldo1_vtbl[] = { 1800000, 2850000 };
153
154/* ALDO 7 voltage table */
155static const int lp8788_aldo7_vtbl[] = {
156	1200000, 1300000, 1400000, 1500000, 1600000, 1700000, 1800000, 1800000,
157};
158
159static int lp8788_ldo_enable_time(struct regulator_dev *rdev)
160{
161	struct lp8788_ldo *ldo = rdev_get_drvdata(rdev);
162	enum lp8788_ldo_id id = rdev_get_id(rdev);
163	u8 val, addr = LP8788_DLDO1_TIMESTEP + id;
164
165	if (lp8788_read_byte(ldo->lp, addr, &val))
166		return -EINVAL;
167
168	val = (val & LP8788_STARTUP_TIME_M) >> LP8788_STARTUP_TIME_S;
169
170	return ENABLE_TIME_USEC * val;
171}
172
173static struct regulator_ops lp8788_ldo_voltage_table_ops = {
174	.list_voltage = regulator_list_voltage_table,
175	.set_voltage_sel = regulator_set_voltage_sel_regmap,
176	.get_voltage_sel = regulator_get_voltage_sel_regmap,
177	.enable = regulator_enable_regmap,
178	.disable = regulator_disable_regmap,
179	.is_enabled = regulator_is_enabled_regmap,
180	.enable_time = lp8788_ldo_enable_time,
181};
182
183static struct regulator_ops lp8788_ldo_voltage_fixed_ops = {
184	.list_voltage = regulator_list_voltage_linear,
185	.enable = regulator_enable_regmap,
186	.disable = regulator_disable_regmap,
187	.is_enabled = regulator_is_enabled_regmap,
188	.enable_time = lp8788_ldo_enable_time,
189};
190
191static struct regulator_desc lp8788_dldo_desc[] = {
192	{
193		.name = "dldo1",
194		.id = DLDO1,
195		.ops = &lp8788_ldo_voltage_table_ops,
196		.n_voltages = ARRAY_SIZE(lp8788_dldo1239_vtbl),
197		.volt_table = lp8788_dldo1239_vtbl,
198		.type = REGULATOR_VOLTAGE,
199		.owner = THIS_MODULE,
200		.vsel_reg = LP8788_DLDO1_VOUT,
201		.vsel_mask = LP8788_VOUT_5BIT_M,
202		.enable_reg = LP8788_EN_LDO_A,
203		.enable_mask = LP8788_EN_DLDO1_M,
204	},
205	{
206		.name = "dldo2",
207		.id = DLDO2,
208		.ops = &lp8788_ldo_voltage_table_ops,
209		.n_voltages = ARRAY_SIZE(lp8788_dldo1239_vtbl),
210		.volt_table = lp8788_dldo1239_vtbl,
211		.type = REGULATOR_VOLTAGE,
212		.owner = THIS_MODULE,
213		.vsel_reg = LP8788_DLDO2_VOUT,
214		.vsel_mask = LP8788_VOUT_5BIT_M,
215		.enable_reg = LP8788_EN_LDO_A,
216		.enable_mask = LP8788_EN_DLDO2_M,
217	},
218	{
219		.name = "dldo3",
220		.id = DLDO3,
221		.ops = &lp8788_ldo_voltage_table_ops,
222		.n_voltages = ARRAY_SIZE(lp8788_dldo1239_vtbl),
223		.volt_table = lp8788_dldo1239_vtbl,
224		.type = REGULATOR_VOLTAGE,
225		.owner = THIS_MODULE,
226		.vsel_reg = LP8788_DLDO3_VOUT,
227		.vsel_mask = LP8788_VOUT_5BIT_M,
228		.enable_reg = LP8788_EN_LDO_A,
229		.enable_mask = LP8788_EN_DLDO3_M,
230	},
231	{
232		.name = "dldo4",
233		.id = DLDO4,
234		.ops = &lp8788_ldo_voltage_table_ops,
235		.n_voltages = ARRAY_SIZE(lp8788_dldo4_vtbl),
236		.volt_table = lp8788_dldo4_vtbl,
237		.type = REGULATOR_VOLTAGE,
238		.owner = THIS_MODULE,
239		.vsel_reg = LP8788_DLDO4_VOUT,
240		.vsel_mask = LP8788_VOUT_1BIT_M,
241		.enable_reg = LP8788_EN_LDO_A,
242		.enable_mask = LP8788_EN_DLDO4_M,
243	},
244	{
245		.name = "dldo5",
246		.id = DLDO5,
247		.ops = &lp8788_ldo_voltage_table_ops,
248		.n_voltages = ARRAY_SIZE(lp8788_dldo578_aldo6_vtbl),
249		.volt_table = lp8788_dldo578_aldo6_vtbl,
250		.type = REGULATOR_VOLTAGE,
251		.owner = THIS_MODULE,
252		.vsel_reg = LP8788_DLDO5_VOUT,
253		.vsel_mask = LP8788_VOUT_4BIT_M,
254		.enable_reg = LP8788_EN_LDO_A,
255		.enable_mask = LP8788_EN_DLDO5_M,
256	},
257	{
258		.name = "dldo6",
259		.id = DLDO6,
260		.ops = &lp8788_ldo_voltage_table_ops,
261		.n_voltages = ARRAY_SIZE(lp8788_dldo6_vtbl),
262		.volt_table = lp8788_dldo6_vtbl,
263		.type = REGULATOR_VOLTAGE,
264		.owner = THIS_MODULE,
265		.vsel_reg = LP8788_DLDO6_VOUT,
266		.vsel_mask = LP8788_VOUT_3BIT_M,
267		.enable_reg = LP8788_EN_LDO_A,
268		.enable_mask = LP8788_EN_DLDO6_M,
269	},
270	{
271		.name = "dldo7",
272		.id = DLDO7,
273		.ops = &lp8788_ldo_voltage_table_ops,
274		.n_voltages = ARRAY_SIZE(lp8788_dldo578_aldo6_vtbl),
275		.volt_table = lp8788_dldo578_aldo6_vtbl,
276		.type = REGULATOR_VOLTAGE,
277		.owner = THIS_MODULE,
278		.vsel_reg = LP8788_DLDO7_VOUT,
279		.vsel_mask = LP8788_VOUT_4BIT_M,
280		.enable_reg = LP8788_EN_LDO_A,
281		.enable_mask = LP8788_EN_DLDO7_M,
282	},
283	{
284		.name = "dldo8",
285		.id = DLDO8,
286		.ops = &lp8788_ldo_voltage_table_ops,
287		.n_voltages = ARRAY_SIZE(lp8788_dldo578_aldo6_vtbl),
288		.volt_table = lp8788_dldo578_aldo6_vtbl,
289		.type = REGULATOR_VOLTAGE,
290		.owner = THIS_MODULE,
291		.vsel_reg = LP8788_DLDO8_VOUT,
292		.vsel_mask = LP8788_VOUT_4BIT_M,
293		.enable_reg = LP8788_EN_LDO_A,
294		.enable_mask = LP8788_EN_DLDO8_M,
295	},
296	{
297		.name = "dldo9",
298		.id = DLDO9,
299		.ops = &lp8788_ldo_voltage_table_ops,
300		.n_voltages = ARRAY_SIZE(lp8788_dldo1239_vtbl),
301		.volt_table = lp8788_dldo1239_vtbl,
302		.type = REGULATOR_VOLTAGE,
303		.owner = THIS_MODULE,
304		.vsel_reg = LP8788_DLDO9_VOUT,
305		.vsel_mask = LP8788_VOUT_5BIT_M,
306		.enable_reg = LP8788_EN_LDO_B,
307		.enable_mask = LP8788_EN_DLDO9_M,
308	},
309	{
310		.name = "dldo10",
311		.id = DLDO10,
312		.ops = &lp8788_ldo_voltage_table_ops,
313		.n_voltages = ARRAY_SIZE(lp8788_dldo1011_vtbl),
314		.volt_table = lp8788_dldo1011_vtbl,
315		.type = REGULATOR_VOLTAGE,
316		.owner = THIS_MODULE,
317		.vsel_reg = LP8788_DLDO10_VOUT,
318		.vsel_mask = LP8788_VOUT_4BIT_M,
319		.enable_reg = LP8788_EN_LDO_B,
320		.enable_mask = LP8788_EN_DLDO10_M,
321	},
322	{
323		.name = "dldo11",
324		.id = DLDO11,
325		.ops = &lp8788_ldo_voltage_table_ops,
326		.n_voltages = ARRAY_SIZE(lp8788_dldo1011_vtbl),
327		.volt_table = lp8788_dldo1011_vtbl,
328		.type = REGULATOR_VOLTAGE,
329		.owner = THIS_MODULE,
330		.vsel_reg = LP8788_DLDO11_VOUT,
331		.vsel_mask = LP8788_VOUT_4BIT_M,
332		.enable_reg = LP8788_EN_LDO_B,
333		.enable_mask = LP8788_EN_DLDO11_M,
334	},
335	{
336		.name = "dldo12",
337		.id = DLDO12,
338		.ops = &lp8788_ldo_voltage_fixed_ops,
339		.n_voltages = 1,
340		.type = REGULATOR_VOLTAGE,
341		.owner = THIS_MODULE,
342		.enable_reg = LP8788_EN_LDO_B,
343		.enable_mask = LP8788_EN_DLDO12_M,
344		.min_uV = 2500000,
345	},
346};
347
348static struct regulator_desc lp8788_aldo_desc[] = {
349	{
350		.name = "aldo1",
351		.id = ALDO1,
352		.ops = &lp8788_ldo_voltage_table_ops,
353		.n_voltages = ARRAY_SIZE(lp8788_aldo1_vtbl),
354		.volt_table = lp8788_aldo1_vtbl,
355		.type = REGULATOR_VOLTAGE,
356		.owner = THIS_MODULE,
357		.vsel_reg = LP8788_ALDO1_VOUT,
358		.vsel_mask = LP8788_VOUT_1BIT_M,
359		.enable_reg = LP8788_EN_LDO_B,
360		.enable_mask = LP8788_EN_ALDO1_M,
361	},
362	{
363		.name = "aldo2",
364		.id = ALDO2,
365		.ops = &lp8788_ldo_voltage_fixed_ops,
366		.n_voltages = 1,
367		.type = REGULATOR_VOLTAGE,
368		.owner = THIS_MODULE,
369		.enable_reg = LP8788_EN_LDO_B,
370		.enable_mask = LP8788_EN_ALDO2_M,
371		.min_uV = 2850000,
372	},
373	{
374		.name = "aldo3",
375		.id = ALDO3,
376		.ops = &lp8788_ldo_voltage_fixed_ops,
377		.n_voltages = 1,
378		.type = REGULATOR_VOLTAGE,
379		.owner = THIS_MODULE,
380		.enable_reg = LP8788_EN_LDO_B,
381		.enable_mask = LP8788_EN_ALDO3_M,
382		.min_uV = 2850000,
383	},
384	{
385		.name = "aldo4",
386		.id = ALDO4,
387		.ops = &lp8788_ldo_voltage_fixed_ops,
388		.n_voltages = 1,
389		.type = REGULATOR_VOLTAGE,
390		.owner = THIS_MODULE,
391		.enable_reg = LP8788_EN_LDO_B,
392		.enable_mask = LP8788_EN_ALDO4_M,
393		.min_uV = 2850000,
394	},
395	{
396		.name = "aldo5",
397		.id = ALDO5,
398		.ops = &lp8788_ldo_voltage_fixed_ops,
399		.n_voltages = 1,
400		.type = REGULATOR_VOLTAGE,
401		.owner = THIS_MODULE,
402		.enable_reg = LP8788_EN_LDO_C,
403		.enable_mask = LP8788_EN_ALDO5_M,
404		.min_uV = 2850000,
405	},
406	{
407		.name = "aldo6",
408		.id = ALDO6,
409		.ops = &lp8788_ldo_voltage_table_ops,
410		.n_voltages = ARRAY_SIZE(lp8788_dldo578_aldo6_vtbl),
411		.volt_table = lp8788_dldo578_aldo6_vtbl,
412		.type = REGULATOR_VOLTAGE,
413		.owner = THIS_MODULE,
414		.vsel_reg = LP8788_ALDO6_VOUT,
415		.vsel_mask = LP8788_VOUT_4BIT_M,
416		.enable_reg = LP8788_EN_LDO_C,
417		.enable_mask = LP8788_EN_ALDO6_M,
418	},
419	{
420		.name = "aldo7",
421		.id = ALDO7,
422		.ops = &lp8788_ldo_voltage_table_ops,
423		.n_voltages = ARRAY_SIZE(lp8788_aldo7_vtbl),
424		.volt_table = lp8788_aldo7_vtbl,
425		.type = REGULATOR_VOLTAGE,
426		.owner = THIS_MODULE,
427		.vsel_reg = LP8788_ALDO7_VOUT,
428		.vsel_mask = LP8788_VOUT_3BIT_M,
429		.enable_reg = LP8788_EN_LDO_C,
430		.enable_mask = LP8788_EN_ALDO7_M,
431	},
432	{
433		.name = "aldo8",
434		.id = ALDO8,
435		.ops = &lp8788_ldo_voltage_fixed_ops,
436		.n_voltages = 1,
437		.type = REGULATOR_VOLTAGE,
438		.owner = THIS_MODULE,
439		.enable_reg = LP8788_EN_LDO_C,
440		.enable_mask = LP8788_EN_ALDO8_M,
441		.min_uV = 2500000,
442	},
443	{
444		.name = "aldo9",
445		.id = ALDO9,
446		.ops = &lp8788_ldo_voltage_fixed_ops,
447		.n_voltages = 1,
448		.type = REGULATOR_VOLTAGE,
449		.owner = THIS_MODULE,
450		.enable_reg = LP8788_EN_LDO_C,
451		.enable_mask = LP8788_EN_ALDO9_M,
452		.min_uV = 2500000,
453	},
454	{
455		.name = "aldo10",
456		.id = ALDO10,
457		.ops = &lp8788_ldo_voltage_fixed_ops,
458		.n_voltages = 1,
459		.type = REGULATOR_VOLTAGE,
460		.owner = THIS_MODULE,
461		.enable_reg = LP8788_EN_LDO_C,
462		.enable_mask = LP8788_EN_ALDO10_M,
463		.min_uV = 1100000,
464	},
465};
466
467static int lp8788_config_ldo_enable_mode(struct platform_device *pdev,
468					struct lp8788_ldo *ldo,
469					enum lp8788_ldo_id id)
470{
471	struct lp8788 *lp = ldo->lp;
472	struct lp8788_platform_data *pdata = lp->pdata;
473	enum lp8788_ext_ldo_en_id enable_id;
474	u8 en_mask[] = {
475		[EN_ALDO1]   = LP8788_EN_SEL_ALDO1_M,
476		[EN_ALDO234] = LP8788_EN_SEL_ALDO234_M,
477		[EN_ALDO5]   = LP8788_EN_SEL_ALDO5_M,
478		[EN_ALDO7]   = LP8788_EN_SEL_ALDO7_M,
479		[EN_DLDO7]   = LP8788_EN_SEL_DLDO7_M,
480		[EN_DLDO911] = LP8788_EN_SEL_DLDO911_M,
481	};
482
483	switch (id) {
484	case DLDO7:
485		enable_id = EN_DLDO7;
486		break;
487	case DLDO9:
488	case DLDO11:
489		enable_id = EN_DLDO911;
490		break;
491	case ALDO1:
492		enable_id = EN_ALDO1;
493		break;
494	case ALDO2 ... ALDO4:
495		enable_id = EN_ALDO234;
496		break;
497	case ALDO5:
498		enable_id = EN_ALDO5;
499		break;
500	case ALDO7:
501		enable_id = EN_ALDO7;
502		break;
503	default:
504		return 0;
505	}
506
507	/* if no platform data for ldo pin, then set default enable mode */
508	if (!pdata || !pdata->ldo_pin || !pdata->ldo_pin[enable_id])
509		goto set_default_ldo_enable_mode;
510
511	ldo->en_pin = pdata->ldo_pin[enable_id];
512	return 0;
513
514set_default_ldo_enable_mode:
515	return lp8788_update_bits(lp, LP8788_EN_SEL, en_mask[enable_id], 0);
516}
517
518static int lp8788_dldo_probe(struct platform_device *pdev)
519{
520	struct lp8788 *lp = dev_get_drvdata(pdev->dev.parent);
521	int id = pdev->id;
522	struct lp8788_ldo *ldo;
523	struct regulator_config cfg = { };
524	struct regulator_dev *rdev;
525	int ret;
526
527	ldo = devm_kzalloc(&pdev->dev, sizeof(struct lp8788_ldo), GFP_KERNEL);
528	if (!ldo)
529		return -ENOMEM;
530
531	ldo->lp = lp;
532	ret = lp8788_config_ldo_enable_mode(pdev, ldo, id);
533	if (ret)
534		return ret;
535
536	if (ldo->en_pin) {
537		cfg.ena_gpio = ldo->en_pin->gpio;
538		cfg.ena_gpio_flags = ldo->en_pin->init_state;
539	}
540
541	cfg.dev = pdev->dev.parent;
542	cfg.init_data = lp->pdata ? lp->pdata->dldo_data[id] : NULL;
543	cfg.driver_data = ldo;
544	cfg.regmap = lp->regmap;
545
546	rdev = devm_regulator_register(&pdev->dev, &lp8788_dldo_desc[id], &cfg);
547	if (IS_ERR(rdev)) {
548		ret = PTR_ERR(rdev);
549		dev_err(&pdev->dev, "DLDO%d regulator register err = %d\n",
550				id + 1, ret);
551		return ret;
552	}
553
554	ldo->regulator = rdev;
555	platform_set_drvdata(pdev, ldo);
556
557	return 0;
558}
559
560static struct platform_driver lp8788_dldo_driver = {
561	.probe = lp8788_dldo_probe,
562	.driver = {
563		.name = LP8788_DEV_DLDO,
564	},
565};
566
567static int lp8788_aldo_probe(struct platform_device *pdev)
568{
569	struct lp8788 *lp = dev_get_drvdata(pdev->dev.parent);
570	int id = pdev->id;
571	struct lp8788_ldo *ldo;
572	struct regulator_config cfg = { };
573	struct regulator_dev *rdev;
574	int ret;
575
576	ldo = devm_kzalloc(&pdev->dev, sizeof(struct lp8788_ldo), GFP_KERNEL);
577	if (!ldo)
578		return -ENOMEM;
579
580	ldo->lp = lp;
581	ret = lp8788_config_ldo_enable_mode(pdev, ldo, id + ALDO1);
582	if (ret)
583		return ret;
584
585	if (ldo->en_pin) {
586		cfg.ena_gpio = ldo->en_pin->gpio;
587		cfg.ena_gpio_flags = ldo->en_pin->init_state;
588	}
589
590	cfg.dev = pdev->dev.parent;
591	cfg.init_data = lp->pdata ? lp->pdata->aldo_data[id] : NULL;
592	cfg.driver_data = ldo;
593	cfg.regmap = lp->regmap;
594
595	rdev = devm_regulator_register(&pdev->dev, &lp8788_aldo_desc[id], &cfg);
596	if (IS_ERR(rdev)) {
597		ret = PTR_ERR(rdev);
598		dev_err(&pdev->dev, "ALDO%d regulator register err = %d\n",
599				id + 1, ret);
600		return ret;
601	}
602
603	ldo->regulator = rdev;
604	platform_set_drvdata(pdev, ldo);
605
606	return 0;
607}
608
609static struct platform_driver lp8788_aldo_driver = {
610	.probe = lp8788_aldo_probe,
611	.driver = {
612		.name = LP8788_DEV_ALDO,
613	},
614};
615
616static int __init lp8788_ldo_init(void)
617{
618	int ret;
619
620	ret = platform_driver_register(&lp8788_dldo_driver);
621	if (ret)
622		return ret;
623
624	return platform_driver_register(&lp8788_aldo_driver);
625}
626subsys_initcall(lp8788_ldo_init);
627
628static void __exit lp8788_ldo_exit(void)
629{
630	platform_driver_unregister(&lp8788_aldo_driver);
631	platform_driver_unregister(&lp8788_dldo_driver);
632}
633module_exit(lp8788_ldo_exit);
634
635MODULE_DESCRIPTION("TI LP8788 LDO Driver");
636MODULE_AUTHOR("Milo Kim");
637MODULE_LICENSE("GPL");
638MODULE_ALIAS("platform:lp8788-dldo");
639MODULE_ALIAS("platform:lp8788-aldo");
640