1 /*
2  * TI LP8788 MFD - buck 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/mfd/lp8788.h>
20 #include <linux/gpio.h>
21 
22 /* register address */
23 #define LP8788_EN_BUCK			0x0C
24 #define LP8788_BUCK_DVS_SEL		0x1D
25 #define LP8788_BUCK1_VOUT0		0x1E
26 #define LP8788_BUCK1_VOUT1		0x1F
27 #define LP8788_BUCK1_VOUT2		0x20
28 #define LP8788_BUCK1_VOUT3		0x21
29 #define LP8788_BUCK2_VOUT0		0x22
30 #define LP8788_BUCK2_VOUT1		0x23
31 #define LP8788_BUCK2_VOUT2		0x24
32 #define LP8788_BUCK2_VOUT3		0x25
33 #define LP8788_BUCK3_VOUT		0x26
34 #define LP8788_BUCK4_VOUT		0x27
35 #define LP8788_BUCK1_TIMESTEP		0x28
36 #define LP8788_BUCK_PWM			0x2D
37 
38 /* mask/shift bits */
39 #define LP8788_EN_BUCK1_M		BIT(0)	/* Addr 0Ch */
40 #define LP8788_EN_BUCK2_M		BIT(1)
41 #define LP8788_EN_BUCK3_M		BIT(2)
42 #define LP8788_EN_BUCK4_M		BIT(3)
43 #define LP8788_BUCK1_DVS_SEL_M		0x04	/* Addr 1Dh */
44 #define LP8788_BUCK1_DVS_M		0x03
45 #define LP8788_BUCK1_DVS_S		0
46 #define LP8788_BUCK2_DVS_SEL_M		0x40
47 #define LP8788_BUCK2_DVS_M		0x30
48 #define LP8788_BUCK2_DVS_S		4
49 #define LP8788_BUCK1_DVS_I2C		BIT(2)
50 #define LP8788_BUCK2_DVS_I2C		BIT(6)
51 #define LP8788_BUCK1_DVS_PIN		(0 << 2)
52 #define LP8788_BUCK2_DVS_PIN		(0 << 6)
53 #define LP8788_VOUT_M			0x1F	/* Addr 1Eh ~ 27h */
54 #define LP8788_STARTUP_TIME_M		0xF8	/* Addr 28h ~ 2Bh */
55 #define LP8788_STARTUP_TIME_S		3
56 #define LP8788_FPWM_BUCK1_M		BIT(0)	/* Addr 2Dh */
57 #define LP8788_FPWM_BUCK1_S		0
58 #define LP8788_FPWM_BUCK2_M		BIT(1)
59 #define LP8788_FPWM_BUCK2_S		1
60 #define LP8788_FPWM_BUCK3_M		BIT(2)
61 #define LP8788_FPWM_BUCK3_S		2
62 #define LP8788_FPWM_BUCK4_M		BIT(3)
63 #define LP8788_FPWM_BUCK4_S		3
64 
65 #define INVALID_ADDR			0xFF
66 #define LP8788_FORCE_PWM		1
67 #define LP8788_AUTO_PWM			0
68 #define PIN_LOW				0
69 #define PIN_HIGH			1
70 #define ENABLE_TIME_USEC		32
71 
72 #define BUCK_FPWM_MASK(x)		(1 << (x))
73 #define BUCK_FPWM_SHIFT(x)		(x)
74 
75 enum lp8788_dvs_state {
76 	DVS_LOW  = GPIOF_OUT_INIT_LOW,
77 	DVS_HIGH = GPIOF_OUT_INIT_HIGH,
78 };
79 
80 enum lp8788_dvs_mode {
81 	REGISTER,
82 	EXTPIN,
83 };
84 
85 enum lp8788_buck_id {
86 	BUCK1,
87 	BUCK2,
88 	BUCK3,
89 	BUCK4,
90 };
91 
92 struct lp8788_buck {
93 	struct lp8788 *lp;
94 	struct regulator_dev *regulator;
95 	void *dvs;
96 };
97 
98 /* BUCK 1 ~ 4 voltage table */
99 static const int lp8788_buck_vtbl[] = {
100 	 500000,  800000,  850000,  900000,  950000, 1000000, 1050000, 1100000,
101 	1150000, 1200000, 1250000, 1300000, 1350000, 1400000, 1450000, 1500000,
102 	1550000, 1600000, 1650000, 1700000, 1750000, 1800000, 1850000, 1900000,
103 	1950000, 2000000,
104 };
105 
lp8788_buck1_set_dvs(struct lp8788_buck * buck)106 static void lp8788_buck1_set_dvs(struct lp8788_buck *buck)
107 {
108 	struct lp8788_buck1_dvs *dvs = (struct lp8788_buck1_dvs *)buck->dvs;
109 	enum lp8788_dvs_state pinstate;
110 
111 	if (!dvs)
112 		return;
113 
114 	pinstate = dvs->vsel == DVS_SEL_V0 ? DVS_LOW : DVS_HIGH;
115 	if (gpio_is_valid(dvs->gpio))
116 		gpio_set_value(dvs->gpio, pinstate);
117 }
118 
lp8788_buck2_set_dvs(struct lp8788_buck * buck)119 static void lp8788_buck2_set_dvs(struct lp8788_buck *buck)
120 {
121 	struct lp8788_buck2_dvs *dvs = (struct lp8788_buck2_dvs *)buck->dvs;
122 	enum lp8788_dvs_state pin1, pin2;
123 
124 	if (!dvs)
125 		return;
126 
127 	switch (dvs->vsel) {
128 	case DVS_SEL_V0:
129 		pin1 = DVS_LOW;
130 		pin2 = DVS_LOW;
131 		break;
132 	case DVS_SEL_V1:
133 		pin1 = DVS_HIGH;
134 		pin2 = DVS_LOW;
135 		break;
136 	case DVS_SEL_V2:
137 		pin1 = DVS_LOW;
138 		pin2 = DVS_HIGH;
139 		break;
140 	case DVS_SEL_V3:
141 		pin1 = DVS_HIGH;
142 		pin2 = DVS_HIGH;
143 		break;
144 	default:
145 		return;
146 	}
147 
148 	if (gpio_is_valid(dvs->gpio[0]))
149 		gpio_set_value(dvs->gpio[0], pin1);
150 
151 	if (gpio_is_valid(dvs->gpio[1]))
152 		gpio_set_value(dvs->gpio[1], pin2);
153 }
154 
lp8788_set_dvs(struct lp8788_buck * buck,enum lp8788_buck_id id)155 static void lp8788_set_dvs(struct lp8788_buck *buck, enum lp8788_buck_id id)
156 {
157 	switch (id) {
158 	case BUCK1:
159 		lp8788_buck1_set_dvs(buck);
160 		break;
161 	case BUCK2:
162 		lp8788_buck2_set_dvs(buck);
163 		break;
164 	default:
165 		break;
166 	}
167 }
168 
169 static enum lp8788_dvs_mode
lp8788_get_buck_dvs_ctrl_mode(struct lp8788_buck * buck,enum lp8788_buck_id id)170 lp8788_get_buck_dvs_ctrl_mode(struct lp8788_buck *buck, enum lp8788_buck_id id)
171 {
172 	u8 val, mask;
173 
174 	switch (id) {
175 	case BUCK1:
176 		mask = LP8788_BUCK1_DVS_SEL_M;
177 		break;
178 	case BUCK2:
179 		mask = LP8788_BUCK2_DVS_SEL_M;
180 		break;
181 	default:
182 		return REGISTER;
183 	}
184 
185 	lp8788_read_byte(buck->lp, LP8788_BUCK_DVS_SEL, &val);
186 
187 	return val & mask ? REGISTER : EXTPIN;
188 }
189 
lp8788_is_valid_buck_addr(u8 addr)190 static bool lp8788_is_valid_buck_addr(u8 addr)
191 {
192 	switch (addr) {
193 	case LP8788_BUCK1_VOUT0:
194 	case LP8788_BUCK1_VOUT1:
195 	case LP8788_BUCK1_VOUT2:
196 	case LP8788_BUCK1_VOUT3:
197 	case LP8788_BUCK2_VOUT0:
198 	case LP8788_BUCK2_VOUT1:
199 	case LP8788_BUCK2_VOUT2:
200 	case LP8788_BUCK2_VOUT3:
201 		return true;
202 	default:
203 		return false;
204 	}
205 }
206 
lp8788_select_buck_vout_addr(struct lp8788_buck * buck,enum lp8788_buck_id id)207 static u8 lp8788_select_buck_vout_addr(struct lp8788_buck *buck,
208 					enum lp8788_buck_id id)
209 {
210 	enum lp8788_dvs_mode mode = lp8788_get_buck_dvs_ctrl_mode(buck, id);
211 	struct lp8788_buck1_dvs *b1_dvs;
212 	struct lp8788_buck2_dvs *b2_dvs;
213 	u8 val, idx, addr;
214 	int pin1, pin2;
215 
216 	switch (id) {
217 	case BUCK1:
218 		if (mode == EXTPIN) {
219 			b1_dvs = (struct lp8788_buck1_dvs *)buck->dvs;
220 			if (!b1_dvs)
221 				goto err;
222 
223 			idx = gpio_get_value(b1_dvs->gpio) ? 1 : 0;
224 		} else {
225 			lp8788_read_byte(buck->lp, LP8788_BUCK_DVS_SEL, &val);
226 			idx = (val & LP8788_BUCK1_DVS_M) >> LP8788_BUCK1_DVS_S;
227 		}
228 		addr = LP8788_BUCK1_VOUT0 + idx;
229 		break;
230 	case BUCK2:
231 		if (mode == EXTPIN) {
232 			b2_dvs = (struct lp8788_buck2_dvs *)buck->dvs;
233 			if (!b2_dvs)
234 				goto err;
235 
236 			pin1 = gpio_get_value(b2_dvs->gpio[0]);
237 			pin2 = gpio_get_value(b2_dvs->gpio[1]);
238 
239 			if (pin1 == PIN_LOW && pin2 == PIN_LOW)
240 				idx = 0;
241 			else if (pin1 == PIN_LOW && pin2 == PIN_HIGH)
242 				idx = 2;
243 			else if (pin1 == PIN_HIGH && pin2 == PIN_LOW)
244 				idx = 1;
245 			else
246 				idx = 3;
247 		} else {
248 			lp8788_read_byte(buck->lp, LP8788_BUCK_DVS_SEL, &val);
249 			idx = (val & LP8788_BUCK2_DVS_M) >> LP8788_BUCK2_DVS_S;
250 		}
251 		addr = LP8788_BUCK2_VOUT0 + idx;
252 		break;
253 	default:
254 		goto err;
255 	}
256 
257 	return addr;
258 err:
259 	return INVALID_ADDR;
260 }
261 
lp8788_buck12_set_voltage_sel(struct regulator_dev * rdev,unsigned selector)262 static int lp8788_buck12_set_voltage_sel(struct regulator_dev *rdev,
263 					unsigned selector)
264 {
265 	struct lp8788_buck *buck = rdev_get_drvdata(rdev);
266 	enum lp8788_buck_id id = rdev_get_id(rdev);
267 	u8 addr;
268 
269 	if (buck->dvs)
270 		lp8788_set_dvs(buck, id);
271 
272 	addr = lp8788_select_buck_vout_addr(buck, id);
273 	if (!lp8788_is_valid_buck_addr(addr))
274 		return -EINVAL;
275 
276 	return lp8788_update_bits(buck->lp, addr, LP8788_VOUT_M, selector);
277 }
278 
lp8788_buck12_get_voltage_sel(struct regulator_dev * rdev)279 static int lp8788_buck12_get_voltage_sel(struct regulator_dev *rdev)
280 {
281 	struct lp8788_buck *buck = rdev_get_drvdata(rdev);
282 	enum lp8788_buck_id id = rdev_get_id(rdev);
283 	int ret;
284 	u8 val, addr;
285 
286 	addr = lp8788_select_buck_vout_addr(buck, id);
287 	if (!lp8788_is_valid_buck_addr(addr))
288 		return -EINVAL;
289 
290 	ret = lp8788_read_byte(buck->lp, addr, &val);
291 	if (ret)
292 		return ret;
293 
294 	return val & LP8788_VOUT_M;
295 }
296 
lp8788_buck_enable_time(struct regulator_dev * rdev)297 static int lp8788_buck_enable_time(struct regulator_dev *rdev)
298 {
299 	struct lp8788_buck *buck = rdev_get_drvdata(rdev);
300 	enum lp8788_buck_id id = rdev_get_id(rdev);
301 	u8 val, addr = LP8788_BUCK1_TIMESTEP + id;
302 
303 	if (lp8788_read_byte(buck->lp, addr, &val))
304 		return -EINVAL;
305 
306 	val = (val & LP8788_STARTUP_TIME_M) >> LP8788_STARTUP_TIME_S;
307 
308 	return ENABLE_TIME_USEC * val;
309 }
310 
lp8788_buck_set_mode(struct regulator_dev * rdev,unsigned int mode)311 static int lp8788_buck_set_mode(struct regulator_dev *rdev, unsigned int mode)
312 {
313 	struct lp8788_buck *buck = rdev_get_drvdata(rdev);
314 	enum lp8788_buck_id id = rdev_get_id(rdev);
315 	u8 mask, val;
316 
317 	mask = BUCK_FPWM_MASK(id);
318 	switch (mode) {
319 	case REGULATOR_MODE_FAST:
320 		val = LP8788_FORCE_PWM << BUCK_FPWM_SHIFT(id);
321 		break;
322 	case REGULATOR_MODE_NORMAL:
323 		val = LP8788_AUTO_PWM << BUCK_FPWM_SHIFT(id);
324 		break;
325 	default:
326 		return -EINVAL;
327 	}
328 
329 	return lp8788_update_bits(buck->lp, LP8788_BUCK_PWM, mask, val);
330 }
331 
lp8788_buck_get_mode(struct regulator_dev * rdev)332 static unsigned int lp8788_buck_get_mode(struct regulator_dev *rdev)
333 {
334 	struct lp8788_buck *buck = rdev_get_drvdata(rdev);
335 	enum lp8788_buck_id id = rdev_get_id(rdev);
336 	u8 val;
337 	int ret;
338 
339 	ret = lp8788_read_byte(buck->lp, LP8788_BUCK_PWM, &val);
340 	if (ret)
341 		return ret;
342 
343 	return val & BUCK_FPWM_MASK(id) ?
344 				REGULATOR_MODE_FAST : REGULATOR_MODE_NORMAL;
345 }
346 
347 static const struct regulator_ops lp8788_buck12_ops = {
348 	.list_voltage = regulator_list_voltage_table,
349 	.map_voltage = regulator_map_voltage_ascend,
350 	.set_voltage_sel = lp8788_buck12_set_voltage_sel,
351 	.get_voltage_sel = lp8788_buck12_get_voltage_sel,
352 	.enable = regulator_enable_regmap,
353 	.disable = regulator_disable_regmap,
354 	.is_enabled = regulator_is_enabled_regmap,
355 	.enable_time = lp8788_buck_enable_time,
356 	.set_mode = lp8788_buck_set_mode,
357 	.get_mode = lp8788_buck_get_mode,
358 };
359 
360 static const struct regulator_ops lp8788_buck34_ops = {
361 	.list_voltage = regulator_list_voltage_table,
362 	.map_voltage = regulator_map_voltage_ascend,
363 	.set_voltage_sel = regulator_set_voltage_sel_regmap,
364 	.get_voltage_sel = regulator_get_voltage_sel_regmap,
365 	.enable = regulator_enable_regmap,
366 	.disable = regulator_disable_regmap,
367 	.is_enabled = regulator_is_enabled_regmap,
368 	.enable_time = lp8788_buck_enable_time,
369 	.set_mode = lp8788_buck_set_mode,
370 	.get_mode = lp8788_buck_get_mode,
371 };
372 
373 static struct regulator_desc lp8788_buck_desc[] = {
374 	{
375 		.name = "buck1",
376 		.id = BUCK1,
377 		.ops = &lp8788_buck12_ops,
378 		.n_voltages = ARRAY_SIZE(lp8788_buck_vtbl),
379 		.volt_table = lp8788_buck_vtbl,
380 		.type = REGULATOR_VOLTAGE,
381 		.owner = THIS_MODULE,
382 		.enable_reg = LP8788_EN_BUCK,
383 		.enable_mask = LP8788_EN_BUCK1_M,
384 	},
385 	{
386 		.name = "buck2",
387 		.id = BUCK2,
388 		.ops = &lp8788_buck12_ops,
389 		.n_voltages = ARRAY_SIZE(lp8788_buck_vtbl),
390 		.volt_table = lp8788_buck_vtbl,
391 		.type = REGULATOR_VOLTAGE,
392 		.owner = THIS_MODULE,
393 		.enable_reg = LP8788_EN_BUCK,
394 		.enable_mask = LP8788_EN_BUCK2_M,
395 	},
396 	{
397 		.name = "buck3",
398 		.id = BUCK3,
399 		.ops = &lp8788_buck34_ops,
400 		.n_voltages = ARRAY_SIZE(lp8788_buck_vtbl),
401 		.volt_table = lp8788_buck_vtbl,
402 		.type = REGULATOR_VOLTAGE,
403 		.owner = THIS_MODULE,
404 		.vsel_reg = LP8788_BUCK3_VOUT,
405 		.vsel_mask = LP8788_VOUT_M,
406 		.enable_reg = LP8788_EN_BUCK,
407 		.enable_mask = LP8788_EN_BUCK3_M,
408 	},
409 	{
410 		.name = "buck4",
411 		.id = BUCK4,
412 		.ops = &lp8788_buck34_ops,
413 		.n_voltages = ARRAY_SIZE(lp8788_buck_vtbl),
414 		.volt_table = lp8788_buck_vtbl,
415 		.type = REGULATOR_VOLTAGE,
416 		.owner = THIS_MODULE,
417 		.vsel_reg = LP8788_BUCK4_VOUT,
418 		.vsel_mask = LP8788_VOUT_M,
419 		.enable_reg = LP8788_EN_BUCK,
420 		.enable_mask = LP8788_EN_BUCK4_M,
421 	},
422 };
423 
lp8788_dvs_gpio_request(struct platform_device * pdev,struct lp8788_buck * buck,enum lp8788_buck_id id)424 static int lp8788_dvs_gpio_request(struct platform_device *pdev,
425 				struct lp8788_buck *buck,
426 				enum lp8788_buck_id id)
427 {
428 	struct lp8788_platform_data *pdata = buck->lp->pdata;
429 	char *b1_name = "LP8788_B1_DVS";
430 	char *b2_name[] = { "LP8788_B2_DVS1", "LP8788_B2_DVS2" };
431 	int i, gpio, ret;
432 
433 	switch (id) {
434 	case BUCK1:
435 		gpio = pdata->buck1_dvs->gpio;
436 		ret = devm_gpio_request_one(&pdev->dev, gpio, DVS_LOW,
437 					    b1_name);
438 		if (ret)
439 			return ret;
440 
441 		buck->dvs = pdata->buck1_dvs;
442 		break;
443 	case BUCK2:
444 		for (i = 0; i < LP8788_NUM_BUCK2_DVS; i++) {
445 			gpio = pdata->buck2_dvs->gpio[i];
446 			ret = devm_gpio_request_one(&pdev->dev, gpio,
447 						    DVS_LOW, b2_name[i]);
448 			if (ret)
449 				return ret;
450 		}
451 		buck->dvs = pdata->buck2_dvs;
452 		break;
453 	default:
454 		break;
455 	}
456 
457 	return 0;
458 }
459 
lp8788_init_dvs(struct platform_device * pdev,struct lp8788_buck * buck,enum lp8788_buck_id id)460 static int lp8788_init_dvs(struct platform_device *pdev,
461 			struct lp8788_buck *buck, enum lp8788_buck_id id)
462 {
463 	struct lp8788_platform_data *pdata = buck->lp->pdata;
464 	u8 mask[] = { LP8788_BUCK1_DVS_SEL_M, LP8788_BUCK2_DVS_SEL_M };
465 	u8 val[]  = { LP8788_BUCK1_DVS_PIN, LP8788_BUCK2_DVS_PIN };
466 	u8 default_dvs_mode[] = { LP8788_BUCK1_DVS_I2C, LP8788_BUCK2_DVS_I2C };
467 
468 	/* no dvs for buck3, 4 */
469 	if (id > BUCK2)
470 		return 0;
471 
472 	/* no dvs platform data, then dvs will be selected by I2C registers */
473 	if (!pdata)
474 		goto set_default_dvs_mode;
475 
476 	if ((id == BUCK1 && !pdata->buck1_dvs) ||
477 		(id == BUCK2 && !pdata->buck2_dvs))
478 		goto set_default_dvs_mode;
479 
480 	if (lp8788_dvs_gpio_request(pdev, buck, id))
481 		goto set_default_dvs_mode;
482 
483 	return lp8788_update_bits(buck->lp, LP8788_BUCK_DVS_SEL, mask[id],
484 				val[id]);
485 
486 set_default_dvs_mode:
487 	return lp8788_update_bits(buck->lp, LP8788_BUCK_DVS_SEL, mask[id],
488 				  default_dvs_mode[id]);
489 }
490 
lp8788_buck_probe(struct platform_device * pdev)491 static int lp8788_buck_probe(struct platform_device *pdev)
492 {
493 	struct lp8788 *lp = dev_get_drvdata(pdev->dev.parent);
494 	int id = pdev->id;
495 	struct lp8788_buck *buck;
496 	struct regulator_config cfg = { };
497 	struct regulator_dev *rdev;
498 	int ret;
499 
500 	if (id >= LP8788_NUM_BUCKS)
501 		return -EINVAL;
502 
503 	buck = devm_kzalloc(&pdev->dev, sizeof(struct lp8788_buck), GFP_KERNEL);
504 	if (!buck)
505 		return -ENOMEM;
506 
507 	buck->lp = lp;
508 
509 	ret = lp8788_init_dvs(pdev, buck, id);
510 	if (ret)
511 		return ret;
512 
513 	cfg.dev = pdev->dev.parent;
514 	cfg.init_data = lp->pdata ? lp->pdata->buck_data[id] : NULL;
515 	cfg.driver_data = buck;
516 	cfg.regmap = lp->regmap;
517 
518 	rdev = devm_regulator_register(&pdev->dev, &lp8788_buck_desc[id], &cfg);
519 	if (IS_ERR(rdev)) {
520 		ret = PTR_ERR(rdev);
521 		dev_err(&pdev->dev, "BUCK%d regulator register err = %d\n",
522 				id + 1, ret);
523 		return ret;
524 	}
525 
526 	buck->regulator = rdev;
527 	platform_set_drvdata(pdev, buck);
528 
529 	return 0;
530 }
531 
532 static struct platform_driver lp8788_buck_driver = {
533 	.probe = lp8788_buck_probe,
534 	.driver = {
535 		.name = LP8788_DEV_BUCK,
536 	},
537 };
538 
lp8788_buck_init(void)539 static int __init lp8788_buck_init(void)
540 {
541 	return platform_driver_register(&lp8788_buck_driver);
542 }
543 subsys_initcall(lp8788_buck_init);
544 
lp8788_buck_exit(void)545 static void __exit lp8788_buck_exit(void)
546 {
547 	platform_driver_unregister(&lp8788_buck_driver);
548 }
549 module_exit(lp8788_buck_exit);
550 
551 MODULE_DESCRIPTION("TI LP8788 BUCK Driver");
552 MODULE_AUTHOR("Milo Kim");
553 MODULE_LICENSE("GPL");
554 MODULE_ALIAS("platform:lp8788-buck");
555