xref: /linux/drivers/regulator/tps6586x-regulator.c (revision 7c7fac30581b2fe2e0783d9b6f53ca333cc2296c)
149610235SMike Rapoport /*
249610235SMike Rapoport  * Regulator driver for TI TPS6586x
349610235SMike Rapoport  *
449610235SMike Rapoport  * Copyright (C) 2010 Compulab Ltd.
549610235SMike Rapoport  * Author: Mike Rapoport <mike@compulab.co.il>
649610235SMike Rapoport  *
749610235SMike Rapoport  * Based on da903x
849610235SMike Rapoport  * Copyright (C) 2006-2008 Marvell International Ltd.
949610235SMike Rapoport  * Copyright (C) 2008 Compulab Ltd.
1049610235SMike Rapoport  *
1149610235SMike Rapoport  * This program is free software; you can redistribute it and/or modify
1249610235SMike Rapoport  * it under the terms of the GNU General Public License version 2 as
1349610235SMike Rapoport  * published by the Free Software Foundation.
1449610235SMike Rapoport  */
1549610235SMike Rapoport 
1649610235SMike Rapoport #include <linux/kernel.h>
1765602c32SPaul Gortmaker #include <linux/module.h>
1849610235SMike Rapoport #include <linux/init.h>
1949610235SMike Rapoport #include <linux/err.h>
2049610235SMike Rapoport #include <linux/slab.h>
2149610235SMike Rapoport #include <linux/platform_device.h>
2249610235SMike Rapoport #include <linux/regulator/driver.h>
2349610235SMike Rapoport #include <linux/regulator/machine.h>
2449610235SMike Rapoport #include <linux/mfd/tps6586x.h>
2549610235SMike Rapoport 
2649610235SMike Rapoport /* supply control and voltage setting  */
2749610235SMike Rapoport #define TPS6586X_SUPPLYENA	0x10
2849610235SMike Rapoport #define TPS6586X_SUPPLYENB	0x11
2949610235SMike Rapoport #define TPS6586X_SUPPLYENC	0x12
3049610235SMike Rapoport #define TPS6586X_SUPPLYEND	0x13
3149610235SMike Rapoport #define TPS6586X_SUPPLYENE	0x14
3249610235SMike Rapoport #define TPS6586X_VCC1		0x20
3349610235SMike Rapoport #define TPS6586X_VCC2		0x21
3449610235SMike Rapoport #define TPS6586X_SM1V1		0x23
3549610235SMike Rapoport #define TPS6586X_SM1V2		0x24
3649610235SMike Rapoport #define TPS6586X_SM1SL		0x25
3749610235SMike Rapoport #define TPS6586X_SM0V1		0x26
3849610235SMike Rapoport #define TPS6586X_SM0V2		0x27
3949610235SMike Rapoport #define TPS6586X_SM0SL		0x28
4049610235SMike Rapoport #define TPS6586X_LDO2AV1	0x29
4149610235SMike Rapoport #define TPS6586X_LDO2AV2	0x2A
4249610235SMike Rapoport #define TPS6586X_LDO2BV1	0x2F
4349610235SMike Rapoport #define TPS6586X_LDO2BV2	0x30
4449610235SMike Rapoport #define TPS6586X_LDO4V1		0x32
4549610235SMike Rapoport #define TPS6586X_LDO4V2		0x33
4649610235SMike Rapoport 
4749610235SMike Rapoport /* converter settings  */
4849610235SMike Rapoport #define TPS6586X_SUPPLYV1	0x41
4949610235SMike Rapoport #define TPS6586X_SUPPLYV2	0x42
5049610235SMike Rapoport #define TPS6586X_SUPPLYV3	0x43
5149610235SMike Rapoport #define TPS6586X_SUPPLYV4	0x44
5249610235SMike Rapoport #define TPS6586X_SUPPLYV5	0x45
5349610235SMike Rapoport #define TPS6586X_SUPPLYV6	0x46
5449610235SMike Rapoport #define TPS6586X_SMODE1		0x47
5549610235SMike Rapoport #define TPS6586X_SMODE2		0x48
5649610235SMike Rapoport 
5749610235SMike Rapoport struct tps6586x_regulator {
5849610235SMike Rapoport 	struct regulator_desc desc;
5949610235SMike Rapoport 
6049610235SMike Rapoport 	int volt_reg;
6149610235SMike Rapoport 	int volt_shift;
6249610235SMike Rapoport 	int volt_nbits;
6349610235SMike Rapoport 	int enable_bit[2];
6449610235SMike Rapoport 	int enable_reg[2];
6549610235SMike Rapoport 
6649610235SMike Rapoport 	/* for DVM regulators */
6749610235SMike Rapoport 	int go_reg;
6849610235SMike Rapoport 	int go_bit;
6949610235SMike Rapoport };
7049610235SMike Rapoport 
7149610235SMike Rapoport static inline struct device *to_tps6586x_dev(struct regulator_dev *rdev)
7249610235SMike Rapoport {
73*7c7fac30SLaxman Dewangan 	return rdev_get_dev(rdev)->parent;
7449610235SMike Rapoport }
7549610235SMike Rapoport 
76eed06517SAxel Lin static int tps6586x_set_voltage_sel(struct regulator_dev *rdev,
77eed06517SAxel Lin 				    unsigned selector)
7849610235SMike Rapoport {
7949610235SMike Rapoport 	struct tps6586x_regulator *ri = rdev_get_drvdata(rdev);
8049610235SMike Rapoport 	struct device *parent = to_tps6586x_dev(rdev);
81eed06517SAxel Lin 	int ret, val, rid = rdev_get_id(rdev);
82eed06517SAxel Lin 	uint8_t mask;
8349610235SMike Rapoport 
84eed06517SAxel Lin 	val = selector << ri->volt_shift;
85eed06517SAxel Lin 	mask = ((1 << ri->volt_nbits) - 1) << ri->volt_shift;
86eed06517SAxel Lin 
87eed06517SAxel Lin 	ret = tps6586x_update(parent, ri->volt_reg, val, mask);
88eed06517SAxel Lin 	if (ret)
89eed06517SAxel Lin 		return ret;
90eed06517SAxel Lin 
91eed06517SAxel Lin 	/* Update go bit for DVM regulators */
92eed06517SAxel Lin 	switch (rid) {
93eed06517SAxel Lin 	case TPS6586X_ID_LDO_2:
94eed06517SAxel Lin 	case TPS6586X_ID_LDO_4:
95eed06517SAxel Lin 	case TPS6586X_ID_SM_0:
96eed06517SAxel Lin 	case TPS6586X_ID_SM_1:
97eed06517SAxel Lin 		ret = tps6586x_set_bits(parent, ri->go_reg, 1 << ri->go_bit);
98eed06517SAxel Lin 		break;
99eed06517SAxel Lin 	}
100eed06517SAxel Lin 	return ret;
10149610235SMike Rapoport }
10249610235SMike Rapoport 
10344a7cdabSAxel Lin static int tps6586x_get_voltage_sel(struct regulator_dev *rdev)
10449610235SMike Rapoport {
10549610235SMike Rapoport 	struct tps6586x_regulator *ri = rdev_get_drvdata(rdev);
10649610235SMike Rapoport 	struct device *parent = to_tps6586x_dev(rdev);
10749610235SMike Rapoport 	uint8_t val, mask;
10849610235SMike Rapoport 	int ret;
10949610235SMike Rapoport 
11049610235SMike Rapoport 	ret = tps6586x_read(parent, ri->volt_reg, &val);
11149610235SMike Rapoport 	if (ret)
11249610235SMike Rapoport 		return ret;
11349610235SMike Rapoport 
11449610235SMike Rapoport 	mask = ((1 << ri->volt_nbits) - 1) << ri->volt_shift;
11549610235SMike Rapoport 	val = (val & mask) >> ri->volt_shift;
11649610235SMike Rapoport 
117327531baSAxel Lin 	if (val >= ri->desc.n_voltages)
11849610235SMike Rapoport 		BUG();
11949610235SMike Rapoport 
12044a7cdabSAxel Lin 	return val;
12149610235SMike Rapoport }
12249610235SMike Rapoport 
12349610235SMike Rapoport static int tps6586x_regulator_enable(struct regulator_dev *rdev)
12449610235SMike Rapoport {
12549610235SMike Rapoport 	struct tps6586x_regulator *ri = rdev_get_drvdata(rdev);
12649610235SMike Rapoport 	struct device *parent = to_tps6586x_dev(rdev);
12749610235SMike Rapoport 
12849610235SMike Rapoport 	return tps6586x_set_bits(parent, ri->enable_reg[0],
12949610235SMike Rapoport 				 1 << ri->enable_bit[0]);
13049610235SMike Rapoport }
13149610235SMike Rapoport 
13249610235SMike Rapoport static int tps6586x_regulator_disable(struct regulator_dev *rdev)
13349610235SMike Rapoport {
13449610235SMike Rapoport 	struct tps6586x_regulator *ri = rdev_get_drvdata(rdev);
13549610235SMike Rapoport 	struct device *parent = to_tps6586x_dev(rdev);
13649610235SMike Rapoport 
13749610235SMike Rapoport 	return tps6586x_clr_bits(parent, ri->enable_reg[0],
13849610235SMike Rapoport 				 1 << ri->enable_bit[0]);
13949610235SMike Rapoport }
14049610235SMike Rapoport 
14149610235SMike Rapoport static int tps6586x_regulator_is_enabled(struct regulator_dev *rdev)
14249610235SMike Rapoport {
14349610235SMike Rapoport 	struct tps6586x_regulator *ri = rdev_get_drvdata(rdev);
14449610235SMike Rapoport 	struct device *parent = to_tps6586x_dev(rdev);
14549610235SMike Rapoport 	uint8_t reg_val;
14649610235SMike Rapoport 	int ret;
14749610235SMike Rapoport 
14849610235SMike Rapoport 	ret = tps6586x_read(parent, ri->enable_reg[0], &reg_val);
14949610235SMike Rapoport 	if (ret)
15049610235SMike Rapoport 		return ret;
15149610235SMike Rapoport 
15249610235SMike Rapoport 	return !!(reg_val & (1 << ri->enable_bit[0]));
15349610235SMike Rapoport }
15449610235SMike Rapoport 
155e1816235SAxel Lin static struct regulator_ops tps6586x_regulator_ops = {
156f4647037SAxel Lin 	.list_voltage = regulator_list_voltage_table,
15744a7cdabSAxel Lin 	.get_voltage_sel = tps6586x_get_voltage_sel,
158eed06517SAxel Lin 	.set_voltage_sel = tps6586x_set_voltage_sel,
15949610235SMike Rapoport 
16049610235SMike Rapoport 	.is_enabled = tps6586x_regulator_is_enabled,
16149610235SMike Rapoport 	.enable = tps6586x_regulator_enable,
16249610235SMike Rapoport 	.disable = tps6586x_regulator_disable,
16349610235SMike Rapoport };
16449610235SMike Rapoport 
165f4647037SAxel Lin static const unsigned int tps6586x_ldo0_voltages[] = {
166f4647037SAxel Lin 	1200000, 1500000, 1800000, 2500000, 2700000, 2850000, 3100000, 3300000,
16749610235SMike Rapoport };
16849610235SMike Rapoport 
169f4647037SAxel Lin static const unsigned int tps6586x_ldo4_voltages[] = {
170f4647037SAxel Lin 	1700000, 1725000, 1750000, 1775000, 1800000, 1825000, 1850000, 1875000,
171f4647037SAxel Lin 	1900000, 1925000, 1950000, 1975000, 2000000, 2025000, 2050000, 2075000,
172f4647037SAxel Lin 	2100000, 2125000, 2150000, 2175000, 2200000, 2225000, 2250000, 2275000,
173f4647037SAxel Lin 	2300000, 2325000, 2350000, 2375000, 2400000, 2425000, 2450000, 2475000,
17449610235SMike Rapoport };
17549610235SMike Rapoport 
176f4647037SAxel Lin static const unsigned int tps6586x_ldo_voltages[] = {
177f4647037SAxel Lin 	1250000, 1500000, 1800000, 2500000, 2700000, 2850000, 3100000, 3300000,
1784cc2e393SGary King };
1794cc2e393SGary King 
180f4647037SAxel Lin static const unsigned int tps6586x_sm2_voltages[] = {
181f4647037SAxel Lin 	3000000, 3050000, 3100000, 3150000, 3200000, 3250000, 3300000, 3350000,
182f4647037SAxel Lin 	3400000, 3450000, 3500000, 3550000, 3600000, 3650000, 3700000, 3750000,
183f4647037SAxel Lin 	3800000, 3850000, 3900000, 3950000, 4000000, 4050000, 4100000, 4150000,
184f4647037SAxel Lin 	4200000, 4250000, 4300000, 4350000, 4400000, 4450000, 4500000, 4550000,
185f4647037SAxel Lin };
186f4647037SAxel Lin 
187f4647037SAxel Lin static const unsigned int tps6586x_dvm_voltages[] = {
188f4647037SAxel Lin 	 725000,  750000,  775000,  800000,  825000,  850000,  875000,  900000,
189f4647037SAxel Lin 	 925000,  950000,  975000, 1000000, 1025000, 1050000, 1075000, 1100000,
190f4647037SAxel Lin 	1125000, 1150000, 1175000, 1200000, 1225000, 1250000, 1275000, 1300000,
191f4647037SAxel Lin 	1325000, 1350000, 1375000, 1400000, 1425000, 1450000, 1475000, 1500000,
19249610235SMike Rapoport };
19349610235SMike Rapoport 
194*7c7fac30SLaxman Dewangan #define TPS6586X_REGULATOR(_id, _pin_name, vdata, vreg, shift, nbits,	\
19564db657bSDanny Huang 			   ereg0, ebit0, ereg1, ebit1)			\
19649610235SMike Rapoport 	.desc	= {							\
197*7c7fac30SLaxman Dewangan 		.supply_name = _pin_name,				\
19849610235SMike Rapoport 		.name	= "REG-" #_id,					\
199e1816235SAxel Lin 		.ops	= &tps6586x_regulator_ops,			\
20049610235SMike Rapoport 		.type	= REGULATOR_VOLTAGE,				\
20149610235SMike Rapoport 		.id	= TPS6586X_ID_##_id,				\
20249610235SMike Rapoport 		.n_voltages = ARRAY_SIZE(tps6586x_##vdata##_voltages),	\
203f4647037SAxel Lin 		.volt_table = tps6586x_##vdata##_voltages,		\
20449610235SMike Rapoport 		.owner	= THIS_MODULE,					\
20549610235SMike Rapoport 	},								\
20649610235SMike Rapoport 	.volt_reg	= TPS6586X_##vreg,				\
20749610235SMike Rapoport 	.volt_shift	= (shift),					\
20849610235SMike Rapoport 	.volt_nbits	= (nbits),					\
20949610235SMike Rapoport 	.enable_reg[0]	= TPS6586X_SUPPLY##ereg0,			\
21049610235SMike Rapoport 	.enable_bit[0]	= (ebit0),					\
21149610235SMike Rapoport 	.enable_reg[1]	= TPS6586X_SUPPLY##ereg1,			\
212f4647037SAxel Lin 	.enable_bit[1]	= (ebit1),
21364db657bSDanny Huang 
21464db657bSDanny Huang #define TPS6586X_REGULATOR_DVM_GOREG(goreg, gobit)			\
21564db657bSDanny Huang 	.go_reg = TPS6586X_##goreg,					\
21664db657bSDanny Huang 	.go_bit = (gobit),
21749610235SMike Rapoport 
218*7c7fac30SLaxman Dewangan #define TPS6586X_LDO(_id, _pname, vdata, vreg, shift, nbits,		\
21949610235SMike Rapoport 		     ereg0, ebit0, ereg1, ebit1)			\
22064db657bSDanny Huang {									\
221*7c7fac30SLaxman Dewangan 	TPS6586X_REGULATOR(_id, _pname, vdata, vreg, shift, nbits,	\
22264db657bSDanny Huang 			   ereg0, ebit0, ereg1, ebit1)			\
22364db657bSDanny Huang }
22449610235SMike Rapoport 
225*7c7fac30SLaxman Dewangan #define TPS6586X_DVM(_id, _pname, vdata, vreg, shift, nbits,		\
22649610235SMike Rapoport 		     ereg0, ebit0, ereg1, ebit1, goreg, gobit)		\
22764db657bSDanny Huang {									\
228*7c7fac30SLaxman Dewangan 	TPS6586X_REGULATOR(_id, _pname, vdata, vreg, shift, nbits,	\
22964db657bSDanny Huang 			   ereg0, ebit0, ereg1, ebit1)			\
23064db657bSDanny Huang 	TPS6586X_REGULATOR_DVM_GOREG(goreg, gobit)			\
23164db657bSDanny Huang }
23249610235SMike Rapoport 
23349610235SMike Rapoport static struct tps6586x_regulator tps6586x_regulator[] = {
234*7c7fac30SLaxman Dewangan 	TPS6586X_LDO(LDO_0, "vinldo01", ldo0, SUPPLYV1, 5, 3, ENC, 0, END, 0),
235*7c7fac30SLaxman Dewangan 	TPS6586X_LDO(LDO_3, "vinldo23", ldo, SUPPLYV4, 0, 3, ENC, 2, END, 2),
236*7c7fac30SLaxman Dewangan 	TPS6586X_LDO(LDO_5, NULL, ldo, SUPPLYV6, 0, 3, ENE, 6, ENE, 6),
237*7c7fac30SLaxman Dewangan 	TPS6586X_LDO(LDO_6, "vinldo678", ldo, SUPPLYV3, 0, 3, ENC, 4, END, 4),
238*7c7fac30SLaxman Dewangan 	TPS6586X_LDO(LDO_7, "vinldo678", ldo, SUPPLYV3, 3, 3, ENC, 5, END, 5),
239*7c7fac30SLaxman Dewangan 	TPS6586X_LDO(LDO_8, "vinldo678", ldo, SUPPLYV2, 5, 3, ENC, 6, END, 6),
240*7c7fac30SLaxman Dewangan 	TPS6586X_LDO(LDO_9, "vinldo9", ldo, SUPPLYV6, 3, 3, ENE, 7, ENE, 7),
241*7c7fac30SLaxman Dewangan 	TPS6586X_LDO(LDO_RTC, NULL, ldo, SUPPLYV4, 3, 3, V4, 7, V4, 7),
242*7c7fac30SLaxman Dewangan 	TPS6586X_LDO(LDO_1, "vinldo01", dvm, SUPPLYV1, 0, 5, ENC, 1, END, 1),
243*7c7fac30SLaxman Dewangan 	TPS6586X_LDO(SM_2, "sm2", sm2, SUPPLYV2, 0, 5, ENC, 7, END, 7),
24449610235SMike Rapoport 
245*7c7fac30SLaxman Dewangan 	TPS6586X_DVM(LDO_2, "vinldo23", dvm, LDO2BV1, 0, 5, ENA, 3,
246*7c7fac30SLaxman Dewangan 					ENB, 3, VCC2, 6),
247*7c7fac30SLaxman Dewangan 	TPS6586X_DVM(LDO_4, "vinldo4", ldo4, LDO4V1, 0, 5, ENC, 3,
248*7c7fac30SLaxman Dewangan 					END, 3, VCC1, 6),
249*7c7fac30SLaxman Dewangan 	TPS6586X_DVM(SM_0, "sm0", dvm, SM0V1, 0, 5, ENA, 1, ENB, 1, VCC1, 2),
250*7c7fac30SLaxman Dewangan 	TPS6586X_DVM(SM_1, "sm1", dvm, SM1V1, 0, 5, ENA, 0, ENB, 0, VCC1, 0),
25149610235SMike Rapoport };
25249610235SMike Rapoport 
25349610235SMike Rapoport /*
25449610235SMike Rapoport  * TPS6586X has 2 enable bits that are OR'ed to determine the actual
25549610235SMike Rapoport  * regulator state. Clearing one of this bits allows switching
25649610235SMike Rapoport  * regulator on and of with single register write.
25749610235SMike Rapoport  */
25849610235SMike Rapoport static inline int tps6586x_regulator_preinit(struct device *parent,
25949610235SMike Rapoport 					     struct tps6586x_regulator *ri)
26049610235SMike Rapoport {
26149610235SMike Rapoport 	uint8_t val1, val2;
26249610235SMike Rapoport 	int ret;
26349610235SMike Rapoport 
2641dbcf35cSDanny Huang 	if (ri->enable_reg[0] == ri->enable_reg[1] &&
2651dbcf35cSDanny Huang 	    ri->enable_bit[0] == ri->enable_bit[1])
2661dbcf35cSDanny Huang 			return 0;
2671dbcf35cSDanny Huang 
26849610235SMike Rapoport 	ret = tps6586x_read(parent, ri->enable_reg[0], &val1);
26949610235SMike Rapoport 	if (ret)
27049610235SMike Rapoport 		return ret;
27149610235SMike Rapoport 
27249610235SMike Rapoport 	ret = tps6586x_read(parent, ri->enable_reg[1], &val2);
27349610235SMike Rapoport 	if (ret)
27449610235SMike Rapoport 		return ret;
27549610235SMike Rapoport 
2764f586707SDanny Huang 	if (!(val2 & (1 << ri->enable_bit[1])))
27749610235SMike Rapoport 		return 0;
27849610235SMike Rapoport 
27949610235SMike Rapoport 	/*
28049610235SMike Rapoport 	 * The regulator is on, but it's enabled with the bit we don't
28149610235SMike Rapoport 	 * want to use, so we switch the enable bits
28249610235SMike Rapoport 	 */
2834f586707SDanny Huang 	if (!(val1 & (1 << ri->enable_bit[0]))) {
28449610235SMike Rapoport 		ret = tps6586x_set_bits(parent, ri->enable_reg[0],
28549610235SMike Rapoport 					1 << ri->enable_bit[0]);
28649610235SMike Rapoport 		if (ret)
28749610235SMike Rapoport 			return ret;
28849610235SMike Rapoport 	}
28949610235SMike Rapoport 
29049610235SMike Rapoport 	return tps6586x_clr_bits(parent, ri->enable_reg[1],
29149610235SMike Rapoport 				 1 << ri->enable_bit[1]);
29249610235SMike Rapoport }
29349610235SMike Rapoport 
294500c524aSXin Xie static int tps6586x_regulator_set_slew_rate(struct platform_device *pdev)
295500c524aSXin Xie {
296500c524aSXin Xie 	struct device *parent = pdev->dev.parent;
297500c524aSXin Xie 	struct regulator_init_data *p = pdev->dev.platform_data;
298500c524aSXin Xie 	struct tps6586x_settings *setting = p->driver_data;
299500c524aSXin Xie 	uint8_t reg;
300500c524aSXin Xie 
301500c524aSXin Xie 	if (setting == NULL)
302500c524aSXin Xie 		return 0;
303500c524aSXin Xie 
304500c524aSXin Xie 	if (!(setting->slew_rate & TPS6586X_SLEW_RATE_SET))
305500c524aSXin Xie 		return 0;
306500c524aSXin Xie 
307500c524aSXin Xie 	/* only SM0 and SM1 can have the slew rate settings */
308500c524aSXin Xie 	switch (pdev->id) {
309500c524aSXin Xie 	case TPS6586X_ID_SM_0:
310500c524aSXin Xie 		reg = TPS6586X_SM0SL;
311500c524aSXin Xie 		break;
312500c524aSXin Xie 	case TPS6586X_ID_SM_1:
313500c524aSXin Xie 		reg = TPS6586X_SM1SL;
314500c524aSXin Xie 		break;
315500c524aSXin Xie 	default:
316500c524aSXin Xie 		dev_warn(&pdev->dev, "Only SM0/SM1 can set slew rate\n");
317500c524aSXin Xie 		return -EINVAL;
318500c524aSXin Xie 	}
319500c524aSXin Xie 
320500c524aSXin Xie 	return tps6586x_write(parent, reg,
321500c524aSXin Xie 			setting->slew_rate & TPS6586X_SLEW_RATE_MASK);
322500c524aSXin Xie }
323500c524aSXin Xie 
32449610235SMike Rapoport static inline struct tps6586x_regulator *find_regulator_info(int id)
32549610235SMike Rapoport {
32649610235SMike Rapoport 	struct tps6586x_regulator *ri;
32749610235SMike Rapoport 	int i;
32849610235SMike Rapoport 
32949610235SMike Rapoport 	for (i = 0; i < ARRAY_SIZE(tps6586x_regulator); i++) {
33049610235SMike Rapoport 		ri = &tps6586x_regulator[i];
33149610235SMike Rapoport 		if (ri->desc.id == id)
33249610235SMike Rapoport 			return ri;
33349610235SMike Rapoport 	}
33449610235SMike Rapoport 	return NULL;
33549610235SMike Rapoport }
33649610235SMike Rapoport 
33749610235SMike Rapoport static int __devinit tps6586x_regulator_probe(struct platform_device *pdev)
33849610235SMike Rapoport {
33949610235SMike Rapoport 	struct tps6586x_regulator *ri = NULL;
340c172708dSMark Brown 	struct regulator_config config = { };
34149610235SMike Rapoport 	struct regulator_dev *rdev;
34249610235SMike Rapoport 	int id = pdev->id;
34349610235SMike Rapoport 	int err;
34449610235SMike Rapoport 
345394ee3d5SThierry Reding 	dev_dbg(&pdev->dev, "Probing regulator %d\n", id);
34649610235SMike Rapoport 
34749610235SMike Rapoport 	ri = find_regulator_info(id);
34849610235SMike Rapoport 	if (ri == NULL) {
34949610235SMike Rapoport 		dev_err(&pdev->dev, "invalid regulator ID specified\n");
35049610235SMike Rapoport 		return -EINVAL;
35149610235SMike Rapoport 	}
35249610235SMike Rapoport 
35349610235SMike Rapoport 	err = tps6586x_regulator_preinit(pdev->dev.parent, ri);
35449610235SMike Rapoport 	if (err)
35549610235SMike Rapoport 		return err;
35649610235SMike Rapoport 
357*7c7fac30SLaxman Dewangan 	config.dev = pdev->dev.parent;
35862f6b087SThierry Reding 	config.of_node = pdev->dev.of_node;
359c172708dSMark Brown 	config.init_data = pdev->dev.platform_data;
360c172708dSMark Brown 	config.driver_data = ri;
361c172708dSMark Brown 
362c172708dSMark Brown 	rdev = regulator_register(&ri->desc, &config);
36349610235SMike Rapoport 	if (IS_ERR(rdev)) {
36449610235SMike Rapoport 		dev_err(&pdev->dev, "failed to register regulator %s\n",
36549610235SMike Rapoport 				ri->desc.name);
36649610235SMike Rapoport 		return PTR_ERR(rdev);
36749610235SMike Rapoport 	}
36849610235SMike Rapoport 
369e7973c3cSAxel Lin 	platform_set_drvdata(pdev, rdev);
37049610235SMike Rapoport 
371500c524aSXin Xie 	return tps6586x_regulator_set_slew_rate(pdev);
37249610235SMike Rapoport }
37349610235SMike Rapoport 
37449610235SMike Rapoport static int __devexit tps6586x_regulator_remove(struct platform_device *pdev)
37549610235SMike Rapoport {
376e7973c3cSAxel Lin 	struct regulator_dev *rdev = platform_get_drvdata(pdev);
377e7973c3cSAxel Lin 
378e7973c3cSAxel Lin 	regulator_unregister(rdev);
37949610235SMike Rapoport 	return 0;
38049610235SMike Rapoport }
38149610235SMike Rapoport 
38249610235SMike Rapoport static struct platform_driver tps6586x_regulator_driver = {
38349610235SMike Rapoport 	.driver	= {
38449610235SMike Rapoport 		.name	= "tps6586x-regulator",
38549610235SMike Rapoport 		.owner	= THIS_MODULE,
38649610235SMike Rapoport 	},
38749610235SMike Rapoport 	.probe		= tps6586x_regulator_probe,
38849610235SMike Rapoport 	.remove		= __devexit_p(tps6586x_regulator_remove),
38949610235SMike Rapoport };
39049610235SMike Rapoport 
39149610235SMike Rapoport static int __init tps6586x_regulator_init(void)
39249610235SMike Rapoport {
39349610235SMike Rapoport 	return platform_driver_register(&tps6586x_regulator_driver);
39449610235SMike Rapoport }
39549610235SMike Rapoport subsys_initcall(tps6586x_regulator_init);
39649610235SMike Rapoport 
39749610235SMike Rapoport static void __exit tps6586x_regulator_exit(void)
39849610235SMike Rapoport {
39949610235SMike Rapoport 	platform_driver_unregister(&tps6586x_regulator_driver);
40049610235SMike Rapoport }
40149610235SMike Rapoport module_exit(tps6586x_regulator_exit);
40249610235SMike Rapoport 
40349610235SMike Rapoport MODULE_LICENSE("GPL");
40449610235SMike Rapoport MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>");
40549610235SMike Rapoport MODULE_DESCRIPTION("Regulator Driver for TI TPS6586X PMIC");
40649610235SMike Rapoport MODULE_ALIAS("platform:tps6586x-regulator");
407