Linux Audio

Check our new training course

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