xref: /linux/drivers/regulator/lp8788-ldo.c (revision f9c41a62bba3f3f7ef3541b2a025e3371bcbba97)
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 
91 enum 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 
116 struct 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 */
124 static 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 */
132 static const int lp8788_dldo4_vtbl[] = { 1800000, 3000000 };
133 
134 /* DLDO 5, 7, 8 and ALDO 6 voltage table */
135 static 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 */
141 static const int lp8788_dldo6_vtbl[] = {
142 	3000000, 3100000, 3200000, 3300000, 3400000, 3500000, 3600000, 3600000,
143 };
144 
145 /* DLDO 10, 11 voltage table */
146 static 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 */
152 static const int lp8788_aldo1_vtbl[] = { 1800000, 2850000 };
153 
154 /* ALDO 7 voltage table */
155 static const int lp8788_aldo7_vtbl[] = {
156 	1200000, 1300000, 1400000, 1500000, 1600000, 1700000, 1800000, 1800000,
157 };
158 
159 static enum lp8788_ldo_id lp8788_dldo_id[] = {
160 	DLDO1,
161 	DLDO2,
162 	DLDO3,
163 	DLDO4,
164 	DLDO5,
165 	DLDO6,
166 	DLDO7,
167 	DLDO8,
168 	DLDO9,
169 	DLDO10,
170 	DLDO11,
171 	DLDO12,
172 };
173 
174 static enum lp8788_ldo_id lp8788_aldo_id[] = {
175 	ALDO1,
176 	ALDO2,
177 	ALDO3,
178 	ALDO4,
179 	ALDO5,
180 	ALDO6,
181 	ALDO7,
182 	ALDO8,
183 	ALDO9,
184 	ALDO10,
185 };
186 
187 static int lp8788_ldo_enable(struct regulator_dev *rdev)
188 {
189 	struct lp8788_ldo *ldo = rdev_get_drvdata(rdev);
190 
191 	if (ldo->en_pin) {
192 		gpio_set_value(ldo->en_pin->gpio, ENABLE);
193 		return 0;
194 	} else {
195 		return regulator_enable_regmap(rdev);
196 	}
197 }
198 
199 static int lp8788_ldo_disable(struct regulator_dev *rdev)
200 {
201 	struct lp8788_ldo *ldo = rdev_get_drvdata(rdev);
202 
203 	if (ldo->en_pin) {
204 		gpio_set_value(ldo->en_pin->gpio, DISABLE);
205 		return 0;
206 	} else {
207 		return regulator_disable_regmap(rdev);
208 	}
209 }
210 
211 static int lp8788_ldo_is_enabled(struct regulator_dev *rdev)
212 {
213 	struct lp8788_ldo *ldo = rdev_get_drvdata(rdev);
214 
215 	if (ldo->en_pin)
216 		return gpio_get_value(ldo->en_pin->gpio) ? 1 : 0;
217 	else
218 		return regulator_is_enabled_regmap(rdev);
219 }
220 
221 static int lp8788_ldo_enable_time(struct regulator_dev *rdev)
222 {
223 	struct lp8788_ldo *ldo = rdev_get_drvdata(rdev);
224 	enum lp8788_ldo_id id = rdev_get_id(rdev);
225 	u8 val, addr = LP8788_DLDO1_TIMESTEP + id;
226 
227 	if (lp8788_read_byte(ldo->lp, addr, &val))
228 		return -EINVAL;
229 
230 	val = (val & LP8788_STARTUP_TIME_M) >> LP8788_STARTUP_TIME_S;
231 
232 	return ENABLE_TIME_USEC * val;
233 }
234 
235 static int lp8788_ldo_fixed_get_voltage(struct regulator_dev *rdev)
236 {
237 	enum lp8788_ldo_id id = rdev_get_id(rdev);
238 
239 	switch (id) {
240 	case ALDO2 ... ALDO5:
241 		return 2850000;
242 	case DLDO12:
243 	case ALDO8 ... ALDO9:
244 		return 2500000;
245 	case ALDO10:
246 		return 1100000;
247 	default:
248 		return -EINVAL;
249 	}
250 }
251 
252 static struct regulator_ops lp8788_ldo_voltage_table_ops = {
253 	.list_voltage = regulator_list_voltage_table,
254 	.set_voltage_sel = regulator_set_voltage_sel_regmap,
255 	.get_voltage_sel = regulator_get_voltage_sel_regmap,
256 	.enable = lp8788_ldo_enable,
257 	.disable = lp8788_ldo_disable,
258 	.is_enabled = lp8788_ldo_is_enabled,
259 	.enable_time = lp8788_ldo_enable_time,
260 };
261 
262 static struct regulator_ops lp8788_ldo_voltage_fixed_ops = {
263 	.get_voltage = lp8788_ldo_fixed_get_voltage,
264 	.enable = lp8788_ldo_enable,
265 	.disable = lp8788_ldo_disable,
266 	.is_enabled = lp8788_ldo_is_enabled,
267 	.enable_time = lp8788_ldo_enable_time,
268 };
269 
270 static struct regulator_desc lp8788_dldo_desc[] = {
271 	{
272 		.name = "dldo1",
273 		.id = DLDO1,
274 		.ops = &lp8788_ldo_voltage_table_ops,
275 		.n_voltages = ARRAY_SIZE(lp8788_dldo1239_vtbl),
276 		.volt_table = lp8788_dldo1239_vtbl,
277 		.type = REGULATOR_VOLTAGE,
278 		.owner = THIS_MODULE,
279 		.vsel_reg = LP8788_DLDO1_VOUT,
280 		.vsel_mask = LP8788_VOUT_5BIT_M,
281 		.enable_reg = LP8788_EN_LDO_A,
282 		.enable_mask = LP8788_EN_DLDO1_M,
283 	},
284 	{
285 		.name = "dldo2",
286 		.id = DLDO2,
287 		.ops = &lp8788_ldo_voltage_table_ops,
288 		.n_voltages = ARRAY_SIZE(lp8788_dldo1239_vtbl),
289 		.volt_table = lp8788_dldo1239_vtbl,
290 		.type = REGULATOR_VOLTAGE,
291 		.owner = THIS_MODULE,
292 		.vsel_reg = LP8788_DLDO2_VOUT,
293 		.vsel_mask = LP8788_VOUT_5BIT_M,
294 		.enable_reg = LP8788_EN_LDO_A,
295 		.enable_mask = LP8788_EN_DLDO2_M,
296 	},
297 	{
298 		.name = "dldo3",
299 		.id = DLDO3,
300 		.ops = &lp8788_ldo_voltage_table_ops,
301 		.n_voltages = ARRAY_SIZE(lp8788_dldo1239_vtbl),
302 		.volt_table = lp8788_dldo1239_vtbl,
303 		.type = REGULATOR_VOLTAGE,
304 		.owner = THIS_MODULE,
305 		.vsel_reg = LP8788_DLDO3_VOUT,
306 		.vsel_mask = LP8788_VOUT_5BIT_M,
307 		.enable_reg = LP8788_EN_LDO_A,
308 		.enable_mask = LP8788_EN_DLDO3_M,
309 	},
310 	{
311 		.name = "dldo4",
312 		.id = DLDO4,
313 		.ops = &lp8788_ldo_voltage_table_ops,
314 		.n_voltages = ARRAY_SIZE(lp8788_dldo4_vtbl),
315 		.volt_table = lp8788_dldo4_vtbl,
316 		.type = REGULATOR_VOLTAGE,
317 		.owner = THIS_MODULE,
318 		.vsel_reg = LP8788_DLDO4_VOUT,
319 		.vsel_mask = LP8788_VOUT_1BIT_M,
320 		.enable_reg = LP8788_EN_LDO_A,
321 		.enable_mask = LP8788_EN_DLDO4_M,
322 	},
323 	{
324 		.name = "dldo5",
325 		.id = DLDO5,
326 		.ops = &lp8788_ldo_voltage_table_ops,
327 		.n_voltages = ARRAY_SIZE(lp8788_dldo578_aldo6_vtbl),
328 		.volt_table = lp8788_dldo578_aldo6_vtbl,
329 		.type = REGULATOR_VOLTAGE,
330 		.owner = THIS_MODULE,
331 		.vsel_reg = LP8788_DLDO5_VOUT,
332 		.vsel_mask = LP8788_VOUT_4BIT_M,
333 		.enable_reg = LP8788_EN_LDO_A,
334 		.enable_mask = LP8788_EN_DLDO5_M,
335 	},
336 	{
337 		.name = "dldo6",
338 		.id = DLDO6,
339 		.ops = &lp8788_ldo_voltage_table_ops,
340 		.n_voltages = ARRAY_SIZE(lp8788_dldo6_vtbl),
341 		.volt_table = lp8788_dldo6_vtbl,
342 		.type = REGULATOR_VOLTAGE,
343 		.owner = THIS_MODULE,
344 		.vsel_reg = LP8788_DLDO6_VOUT,
345 		.vsel_mask = LP8788_VOUT_3BIT_M,
346 		.enable_reg = LP8788_EN_LDO_A,
347 		.enable_mask = LP8788_EN_DLDO6_M,
348 	},
349 	{
350 		.name = "dldo7",
351 		.id = DLDO7,
352 		.ops = &lp8788_ldo_voltage_table_ops,
353 		.n_voltages = ARRAY_SIZE(lp8788_dldo578_aldo6_vtbl),
354 		.volt_table = lp8788_dldo578_aldo6_vtbl,
355 		.type = REGULATOR_VOLTAGE,
356 		.owner = THIS_MODULE,
357 		.vsel_reg = LP8788_DLDO7_VOUT,
358 		.vsel_mask = LP8788_VOUT_4BIT_M,
359 		.enable_reg = LP8788_EN_LDO_A,
360 		.enable_mask = LP8788_EN_DLDO7_M,
361 	},
362 	{
363 		.name = "dldo8",
364 		.id = DLDO8,
365 		.ops = &lp8788_ldo_voltage_table_ops,
366 		.n_voltages = ARRAY_SIZE(lp8788_dldo578_aldo6_vtbl),
367 		.volt_table = lp8788_dldo578_aldo6_vtbl,
368 		.type = REGULATOR_VOLTAGE,
369 		.owner = THIS_MODULE,
370 		.vsel_reg = LP8788_DLDO8_VOUT,
371 		.vsel_mask = LP8788_VOUT_4BIT_M,
372 		.enable_reg = LP8788_EN_LDO_A,
373 		.enable_mask = LP8788_EN_DLDO8_M,
374 	},
375 	{
376 		.name = "dldo9",
377 		.id = DLDO9,
378 		.ops = &lp8788_ldo_voltage_table_ops,
379 		.n_voltages = ARRAY_SIZE(lp8788_dldo1239_vtbl),
380 		.volt_table = lp8788_dldo1239_vtbl,
381 		.type = REGULATOR_VOLTAGE,
382 		.owner = THIS_MODULE,
383 		.vsel_reg = LP8788_DLDO9_VOUT,
384 		.vsel_mask = LP8788_VOUT_5BIT_M,
385 		.enable_reg = LP8788_EN_LDO_B,
386 		.enable_mask = LP8788_EN_DLDO9_M,
387 	},
388 	{
389 		.name = "dldo10",
390 		.id = DLDO10,
391 		.ops = &lp8788_ldo_voltage_table_ops,
392 		.n_voltages = ARRAY_SIZE(lp8788_dldo1011_vtbl),
393 		.volt_table = lp8788_dldo1011_vtbl,
394 		.type = REGULATOR_VOLTAGE,
395 		.owner = THIS_MODULE,
396 		.vsel_reg = LP8788_DLDO10_VOUT,
397 		.vsel_mask = LP8788_VOUT_4BIT_M,
398 		.enable_reg = LP8788_EN_LDO_B,
399 		.enable_mask = LP8788_EN_DLDO10_M,
400 	},
401 	{
402 		.name = "dldo11",
403 		.id = DLDO11,
404 		.ops = &lp8788_ldo_voltage_table_ops,
405 		.n_voltages = ARRAY_SIZE(lp8788_dldo1011_vtbl),
406 		.volt_table = lp8788_dldo1011_vtbl,
407 		.type = REGULATOR_VOLTAGE,
408 		.owner = THIS_MODULE,
409 		.vsel_reg = LP8788_DLDO11_VOUT,
410 		.vsel_mask = LP8788_VOUT_4BIT_M,
411 		.enable_reg = LP8788_EN_LDO_B,
412 		.enable_mask = LP8788_EN_DLDO11_M,
413 	},
414 	{
415 		.name = "dldo12",
416 		.id = DLDO12,
417 		.ops = &lp8788_ldo_voltage_fixed_ops,
418 		.n_voltages = 1,
419 		.type = REGULATOR_VOLTAGE,
420 		.owner = THIS_MODULE,
421 		.enable_reg = LP8788_EN_LDO_B,
422 		.enable_mask = LP8788_EN_DLDO12_M,
423 	},
424 };
425 
426 static struct regulator_desc lp8788_aldo_desc[] = {
427 	{
428 		.name = "aldo1",
429 		.id = ALDO1,
430 		.ops = &lp8788_ldo_voltage_table_ops,
431 		.n_voltages = ARRAY_SIZE(lp8788_aldo1_vtbl),
432 		.volt_table = lp8788_aldo1_vtbl,
433 		.type = REGULATOR_VOLTAGE,
434 		.owner = THIS_MODULE,
435 		.vsel_reg = LP8788_ALDO1_VOUT,
436 		.vsel_mask = LP8788_VOUT_1BIT_M,
437 		.enable_reg = LP8788_EN_LDO_B,
438 		.enable_mask = LP8788_EN_ALDO1_M,
439 	},
440 	{
441 		.name = "aldo2",
442 		.id = ALDO2,
443 		.ops = &lp8788_ldo_voltage_fixed_ops,
444 		.n_voltages = 1,
445 		.type = REGULATOR_VOLTAGE,
446 		.owner = THIS_MODULE,
447 		.enable_reg = LP8788_EN_LDO_B,
448 		.enable_mask = LP8788_EN_ALDO2_M,
449 	},
450 	{
451 		.name = "aldo3",
452 		.id = ALDO3,
453 		.ops = &lp8788_ldo_voltage_fixed_ops,
454 		.n_voltages = 1,
455 		.type = REGULATOR_VOLTAGE,
456 		.owner = THIS_MODULE,
457 		.enable_reg = LP8788_EN_LDO_B,
458 		.enable_mask = LP8788_EN_ALDO3_M,
459 	},
460 	{
461 		.name = "aldo4",
462 		.id = ALDO4,
463 		.ops = &lp8788_ldo_voltage_fixed_ops,
464 		.n_voltages = 1,
465 		.type = REGULATOR_VOLTAGE,
466 		.owner = THIS_MODULE,
467 		.enable_reg = LP8788_EN_LDO_B,
468 		.enable_mask = LP8788_EN_ALDO4_M,
469 	},
470 	{
471 		.name = "aldo5",
472 		.id = ALDO5,
473 		.ops = &lp8788_ldo_voltage_fixed_ops,
474 		.n_voltages = 1,
475 		.type = REGULATOR_VOLTAGE,
476 		.owner = THIS_MODULE,
477 		.enable_reg = LP8788_EN_LDO_C,
478 		.enable_mask = LP8788_EN_ALDO5_M,
479 	},
480 	{
481 		.name = "aldo6",
482 		.id = ALDO6,
483 		.ops = &lp8788_ldo_voltage_table_ops,
484 		.n_voltages = ARRAY_SIZE(lp8788_dldo578_aldo6_vtbl),
485 		.volt_table = lp8788_dldo578_aldo6_vtbl,
486 		.type = REGULATOR_VOLTAGE,
487 		.owner = THIS_MODULE,
488 		.vsel_reg = LP8788_ALDO6_VOUT,
489 		.vsel_mask = LP8788_VOUT_4BIT_M,
490 		.enable_reg = LP8788_EN_LDO_C,
491 		.enable_mask = LP8788_EN_ALDO6_M,
492 	},
493 	{
494 		.name = "aldo7",
495 		.id = ALDO7,
496 		.ops = &lp8788_ldo_voltage_table_ops,
497 		.n_voltages = ARRAY_SIZE(lp8788_aldo7_vtbl),
498 		.volt_table = lp8788_aldo7_vtbl,
499 		.type = REGULATOR_VOLTAGE,
500 		.owner = THIS_MODULE,
501 		.vsel_reg = LP8788_ALDO7_VOUT,
502 		.vsel_mask = LP8788_VOUT_3BIT_M,
503 		.enable_reg = LP8788_EN_LDO_C,
504 		.enable_mask = LP8788_EN_ALDO7_M,
505 	},
506 	{
507 		.name = "aldo8",
508 		.id = ALDO8,
509 		.ops = &lp8788_ldo_voltage_fixed_ops,
510 		.n_voltages = 1,
511 		.type = REGULATOR_VOLTAGE,
512 		.owner = THIS_MODULE,
513 		.enable_reg = LP8788_EN_LDO_C,
514 		.enable_mask = LP8788_EN_ALDO8_M,
515 	},
516 	{
517 		.name = "aldo9",
518 		.id = ALDO9,
519 		.ops = &lp8788_ldo_voltage_fixed_ops,
520 		.n_voltages = 1,
521 		.type = REGULATOR_VOLTAGE,
522 		.owner = THIS_MODULE,
523 		.enable_reg = LP8788_EN_LDO_C,
524 		.enable_mask = LP8788_EN_ALDO9_M,
525 	},
526 	{
527 		.name = "aldo10",
528 		.id = ALDO10,
529 		.ops = &lp8788_ldo_voltage_fixed_ops,
530 		.n_voltages = 1,
531 		.type = REGULATOR_VOLTAGE,
532 		.owner = THIS_MODULE,
533 		.enable_reg = LP8788_EN_LDO_C,
534 		.enable_mask = LP8788_EN_ALDO10_M,
535 	},
536 };
537 
538 static int lp8788_gpio_request_ldo_en(struct platform_device *pdev,
539 				struct lp8788_ldo *ldo,
540 				enum lp8788_ext_ldo_en_id id)
541 {
542 	struct device *dev = &pdev->dev;
543 	struct lp8788_ldo_enable_pin *pin = ldo->en_pin;
544 	int ret, gpio, pinstate;
545 	char *name[] = {
546 		[EN_ALDO1]   = "LP8788_EN_ALDO1",
547 		[EN_ALDO234] = "LP8788_EN_ALDO234",
548 		[EN_ALDO5]   = "LP8788_EN_ALDO5",
549 		[EN_ALDO7]   = "LP8788_EN_ALDO7",
550 		[EN_DLDO7]   = "LP8788_EN_DLDO7",
551 		[EN_DLDO911] = "LP8788_EN_DLDO911",
552 	};
553 
554 	gpio = pin->gpio;
555 	if (!gpio_is_valid(gpio)) {
556 		dev_err(dev, "invalid gpio: %d\n", gpio);
557 		return -EINVAL;
558 	}
559 
560 	pinstate = pin->init_state;
561 	ret = devm_gpio_request_one(dev, gpio, pinstate, name[id]);
562 	if (ret == -EBUSY) {
563 		dev_warn(dev, "gpio%d already used\n", gpio);
564 		return 0;
565 	}
566 
567 	return ret;
568 }
569 
570 static int lp8788_config_ldo_enable_mode(struct platform_device *pdev,
571 					struct lp8788_ldo *ldo,
572 					enum lp8788_ldo_id id)
573 {
574 	int ret;
575 	struct lp8788 *lp = ldo->lp;
576 	struct lp8788_platform_data *pdata = lp->pdata;
577 	enum lp8788_ext_ldo_en_id enable_id;
578 	u8 en_mask[] = {
579 		[EN_ALDO1]   = LP8788_EN_SEL_ALDO1_M,
580 		[EN_ALDO234] = LP8788_EN_SEL_ALDO234_M,
581 		[EN_ALDO5]   = LP8788_EN_SEL_ALDO5_M,
582 		[EN_ALDO7]   = LP8788_EN_SEL_ALDO7_M,
583 		[EN_DLDO7]   = LP8788_EN_SEL_DLDO7_M,
584 		[EN_DLDO911] = LP8788_EN_SEL_DLDO911_M,
585 	};
586 
587 	switch (id) {
588 	case DLDO7:
589 		enable_id = EN_DLDO7;
590 		break;
591 	case DLDO9:
592 	case DLDO11:
593 		enable_id = EN_DLDO911;
594 		break;
595 	case ALDO1:
596 		enable_id = EN_ALDO1;
597 		break;
598 	case ALDO2 ... ALDO4:
599 		enable_id = EN_ALDO234;
600 		break;
601 	case ALDO5:
602 		enable_id = EN_ALDO5;
603 		break;
604 	case ALDO7:
605 		enable_id = EN_ALDO7;
606 		break;
607 	default:
608 		return 0;
609 	}
610 
611 	/* if no platform data for ldo pin, then set default enable mode */
612 	if (!pdata || !pdata->ldo_pin || !pdata->ldo_pin[enable_id])
613 		goto set_default_ldo_enable_mode;
614 
615 	ldo->en_pin = pdata->ldo_pin[enable_id];
616 
617 	ret = lp8788_gpio_request_ldo_en(pdev, ldo, enable_id);
618 	if (ret) {
619 		ldo->en_pin = NULL;
620 		goto set_default_ldo_enable_mode;
621 	}
622 
623 	return ret;
624 
625 set_default_ldo_enable_mode:
626 	return lp8788_update_bits(lp, LP8788_EN_SEL, en_mask[enable_id], 0);
627 }
628 
629 static int lp8788_dldo_probe(struct platform_device *pdev)
630 {
631 	struct lp8788 *lp = dev_get_drvdata(pdev->dev.parent);
632 	int id = pdev->id;
633 	struct lp8788_ldo *ldo;
634 	struct regulator_config cfg = { };
635 	struct regulator_dev *rdev;
636 	int ret;
637 
638 	ldo = devm_kzalloc(&pdev->dev, sizeof(struct lp8788_ldo), GFP_KERNEL);
639 	if (!ldo)
640 		return -ENOMEM;
641 
642 	ldo->lp = lp;
643 	ret = lp8788_config_ldo_enable_mode(pdev, ldo, lp8788_dldo_id[id]);
644 	if (ret)
645 		return ret;
646 
647 	cfg.dev = pdev->dev.parent;
648 	cfg.init_data = lp->pdata ? lp->pdata->dldo_data[id] : NULL;
649 	cfg.driver_data = ldo;
650 	cfg.regmap = lp->regmap;
651 
652 	rdev = regulator_register(&lp8788_dldo_desc[id], &cfg);
653 	if (IS_ERR(rdev)) {
654 		ret = PTR_ERR(rdev);
655 		dev_err(&pdev->dev, "DLDO%d regulator register err = %d\n",
656 				id + 1, ret);
657 		return ret;
658 	}
659 
660 	ldo->regulator = rdev;
661 	platform_set_drvdata(pdev, ldo);
662 
663 	return 0;
664 }
665 
666 static int lp8788_dldo_remove(struct platform_device *pdev)
667 {
668 	struct lp8788_ldo *ldo = platform_get_drvdata(pdev);
669 
670 	platform_set_drvdata(pdev, NULL);
671 	regulator_unregister(ldo->regulator);
672 
673 	return 0;
674 }
675 
676 static struct platform_driver lp8788_dldo_driver = {
677 	.probe = lp8788_dldo_probe,
678 	.remove = lp8788_dldo_remove,
679 	.driver = {
680 		.name = LP8788_DEV_DLDO,
681 		.owner = THIS_MODULE,
682 	},
683 };
684 
685 static int lp8788_aldo_probe(struct platform_device *pdev)
686 {
687 	struct lp8788 *lp = dev_get_drvdata(pdev->dev.parent);
688 	int id = pdev->id;
689 	struct lp8788_ldo *ldo;
690 	struct regulator_config cfg = { };
691 	struct regulator_dev *rdev;
692 	int ret;
693 
694 	ldo = devm_kzalloc(&pdev->dev, sizeof(struct lp8788_ldo), GFP_KERNEL);
695 	if (!ldo)
696 		return -ENOMEM;
697 
698 	ldo->lp = lp;
699 	ret = lp8788_config_ldo_enable_mode(pdev, ldo, lp8788_aldo_id[id]);
700 	if (ret)
701 		return ret;
702 
703 	cfg.dev = pdev->dev.parent;
704 	cfg.init_data = lp->pdata ? lp->pdata->aldo_data[id] : NULL;
705 	cfg.driver_data = ldo;
706 	cfg.regmap = lp->regmap;
707 
708 	rdev = regulator_register(&lp8788_aldo_desc[id], &cfg);
709 	if (IS_ERR(rdev)) {
710 		ret = PTR_ERR(rdev);
711 		dev_err(&pdev->dev, "ALDO%d regulator register err = %d\n",
712 				id + 1, ret);
713 		return ret;
714 	}
715 
716 	ldo->regulator = rdev;
717 	platform_set_drvdata(pdev, ldo);
718 
719 	return 0;
720 }
721 
722 static int lp8788_aldo_remove(struct platform_device *pdev)
723 {
724 	struct lp8788_ldo *ldo = platform_get_drvdata(pdev);
725 
726 	platform_set_drvdata(pdev, NULL);
727 	regulator_unregister(ldo->regulator);
728 
729 	return 0;
730 }
731 
732 static struct platform_driver lp8788_aldo_driver = {
733 	.probe = lp8788_aldo_probe,
734 	.remove = lp8788_aldo_remove,
735 	.driver = {
736 		.name = LP8788_DEV_ALDO,
737 		.owner = THIS_MODULE,
738 	},
739 };
740 
741 static int __init lp8788_ldo_init(void)
742 {
743 	int ret;
744 
745 	ret = platform_driver_register(&lp8788_dldo_driver);
746 	if (ret)
747 		return ret;
748 
749 	return platform_driver_register(&lp8788_aldo_driver);
750 }
751 subsys_initcall(lp8788_ldo_init);
752 
753 static void __exit lp8788_ldo_exit(void)
754 {
755 	platform_driver_unregister(&lp8788_aldo_driver);
756 	platform_driver_unregister(&lp8788_dldo_driver);
757 }
758 module_exit(lp8788_ldo_exit);
759 
760 MODULE_DESCRIPTION("TI LP8788 LDO Driver");
761 MODULE_AUTHOR("Milo Kim");
762 MODULE_LICENSE("GPL");
763 MODULE_ALIAS("platform:lp8788-dldo");
764 MODULE_ALIAS("platform:lp8788-aldo");
765