diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-12-11 07:44:17 -0500 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-12-11 07:44:17 -0500 |
commit | b17fc86cc5e8fbfd1d18765f6463d1989c59f9c6 (patch) | |
tree | 8e0b967c8b63ecf085b762d9c9b1015f063e5759 /drivers/regulator | |
parent | d1e7de3007c6e34c5e6d5e1b707b5aba4a1cd57f (diff) | |
parent | e1b0144f9997d3d52c46785143699d82dd525f1d (diff) |
Merge branch 'topic/min' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator into regulator-change
Diffstat (limited to 'drivers/regulator')
-rw-r--r-- | drivers/regulator/Kconfig | 21 | ||||
-rw-r--r-- | drivers/regulator/Makefile | 2 | ||||
-rw-r--r-- | drivers/regulator/anatop-regulator.c | 28 | ||||
-rw-r--r-- | drivers/regulator/core.c | 6 | ||||
-rw-r--r-- | drivers/regulator/da9055-regulator.c | 644 | ||||
-rw-r--r-- | drivers/regulator/palmas-regulator.c | 37 | ||||
-rw-r--r-- | drivers/regulator/pcf50633-regulator.c | 176 | ||||
-rw-r--r-- | drivers/regulator/tps51632-regulator.c | 327 |
8 files changed, 1042 insertions, 199 deletions
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 67d47b59a66d..10b1edc89621 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig | |||
@@ -109,6 +109,16 @@ config REGULATOR_DA9052 | |||
109 | This driver supports the voltage regulators of DA9052-BC and | 109 | This driver supports the voltage regulators of DA9052-BC and |
110 | DA9053-AA/Bx PMIC. | 110 | DA9053-AA/Bx PMIC. |
111 | 111 | ||
112 | config REGULATOR_DA9055 | ||
113 | tristate "Dialog Semiconductor DA9055 regulators" | ||
114 | depends on MFD_DA9055 | ||
115 | help | ||
116 | Say y here to support the BUCKs and LDOs regulators found on | ||
117 | Dialog Semiconductor DA9055 PMIC. | ||
118 | |||
119 | This driver can also be built as a module. If so, the module | ||
120 | will be called da9055-regulator. | ||
121 | |||
112 | config REGULATOR_FAN53555 | 122 | config REGULATOR_FAN53555 |
113 | tristate "Fairchild FAN53555 Regulator" | 123 | tristate "Fairchild FAN53555 Regulator" |
114 | depends on I2C | 124 | depends on I2C |
@@ -335,6 +345,17 @@ config REGULATOR_PALMAS | |||
335 | on the muxing. This is handled automatically in the driver by | 345 | on the muxing. This is handled automatically in the driver by |
336 | reading the mux info from OTP. | 346 | reading the mux info from OTP. |
337 | 347 | ||
348 | config REGULATOR_TPS51632 | ||
349 | tristate "TI TPS51632 Power Regulator" | ||
350 | depends on I2C | ||
351 | select REGMAP_I2C | ||
352 | help | ||
353 | This driver supports TPS51632 voltage regulator chip. | ||
354 | The TPS51632 is 3-2-1 Phase D-Cap+ Step Down Driverless Controller | ||
355 | with Serial VID control and DVFS. | ||
356 | The voltage output can be configure through I2C interface or PWM | ||
357 | interface. | ||
358 | |||
338 | config REGULATOR_TPS6105X | 359 | config REGULATOR_TPS6105X |
339 | tristate "TI TPS6105X Power regulators" | 360 | tristate "TI TPS6105X Power regulators" |
340 | depends on TPS6105X | 361 | depends on TPS6105X |
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index e431eed8a878..bdaca617e2f2 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile | |||
@@ -18,6 +18,7 @@ obj-$(CONFIG_REGULATOR_ANATOP) += anatop-regulator.o | |||
18 | obj-$(CONFIG_REGULATOR_ARIZONA) += arizona-micsupp.o arizona-ldo1.o | 18 | obj-$(CONFIG_REGULATOR_ARIZONA) += arizona-micsupp.o arizona-ldo1.o |
19 | obj-$(CONFIG_REGULATOR_DA903X) += da903x.o | 19 | obj-$(CONFIG_REGULATOR_DA903X) += da903x.o |
20 | obj-$(CONFIG_REGULATOR_DA9052) += da9052-regulator.o | 20 | obj-$(CONFIG_REGULATOR_DA9052) += da9052-regulator.o |
21 | obj-$(CONFIG_REGULATOR_DA9055) += da9055-regulator.o | ||
21 | obj-$(CONFIG_REGULATOR_DBX500_PRCMU) += dbx500-prcmu.o | 22 | obj-$(CONFIG_REGULATOR_DBX500_PRCMU) += dbx500-prcmu.o |
22 | obj-$(CONFIG_REGULATOR_DB8500_PRCMU) += db8500-prcmu.o | 23 | obj-$(CONFIG_REGULATOR_DB8500_PRCMU) += db8500-prcmu.o |
23 | obj-$(CONFIG_REGULATOR_FAN53555) += fan53555.o | 24 | obj-$(CONFIG_REGULATOR_FAN53555) += fan53555.o |
@@ -41,6 +42,7 @@ obj-$(CONFIG_REGULATOR_MC13783) += mc13783-regulator.o | |||
41 | obj-$(CONFIG_REGULATOR_MC13892) += mc13892-regulator.o | 42 | obj-$(CONFIG_REGULATOR_MC13892) += mc13892-regulator.o |
42 | obj-$(CONFIG_REGULATOR_MC13XXX_CORE) += mc13xxx-regulator-core.o | 43 | obj-$(CONFIG_REGULATOR_MC13XXX_CORE) += mc13xxx-regulator-core.o |
43 | obj-$(CONFIG_REGULATOR_PALMAS) += palmas-regulator.o | 44 | obj-$(CONFIG_REGULATOR_PALMAS) += palmas-regulator.o |
45 | obj-$(CONFIG_REGULATOR_TPS51632) += tps51632-regulator.o | ||
44 | obj-$(CONFIG_REGULATOR_PCAP) += pcap-regulator.o | 46 | obj-$(CONFIG_REGULATOR_PCAP) += pcap-regulator.o |
45 | obj-$(CONFIG_REGULATOR_PCF50633) += pcf50633-regulator.o | 47 | obj-$(CONFIG_REGULATOR_PCF50633) += pcf50633-regulator.o |
46 | obj-$(CONFIG_REGULATOR_RC5T583) += rc5t583-regulator.o | 48 | obj-$(CONFIG_REGULATOR_RC5T583) += rc5t583-regulator.o |
diff --git a/drivers/regulator/anatop-regulator.c b/drivers/regulator/anatop-regulator.c index 1af97686f444..b6182e17b0dc 100644 --- a/drivers/regulator/anatop-regulator.c +++ b/drivers/regulator/anatop-regulator.c | |||
@@ -48,36 +48,21 @@ static int anatop_regmap_set_voltage_sel(struct regulator_dev *reg, | |||
48 | unsigned selector) | 48 | unsigned selector) |
49 | { | 49 | { |
50 | struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg); | 50 | struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg); |
51 | u32 val, mask; | ||
52 | 51 | ||
53 | if (!anatop_reg->control_reg) | 52 | if (!anatop_reg->control_reg) |
54 | return -ENOTSUPP; | 53 | return -ENOTSUPP; |
55 | 54 | ||
56 | val = anatop_reg->min_bit_val + selector; | 55 | return regulator_set_voltage_sel_regmap(reg, selector); |
57 | dev_dbg(®->dev, "%s: calculated val %d\n", __func__, val); | ||
58 | mask = ((1 << anatop_reg->vol_bit_width) - 1) << | ||
59 | anatop_reg->vol_bit_shift; | ||
60 | val <<= anatop_reg->vol_bit_shift; | ||
61 | regmap_update_bits(anatop_reg->anatop, anatop_reg->control_reg, | ||
62 | mask, val); | ||
63 | |||
64 | return 0; | ||
65 | } | 56 | } |
66 | 57 | ||
67 | static int anatop_regmap_get_voltage_sel(struct regulator_dev *reg) | 58 | static int anatop_regmap_get_voltage_sel(struct regulator_dev *reg) |
68 | { | 59 | { |
69 | struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg); | 60 | struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg); |
70 | u32 val, mask; | ||
71 | 61 | ||
72 | if (!anatop_reg->control_reg) | 62 | if (!anatop_reg->control_reg) |
73 | return -ENOTSUPP; | 63 | return -ENOTSUPP; |
74 | 64 | ||
75 | regmap_read(anatop_reg->anatop, anatop_reg->control_reg, &val); | 65 | return regulator_get_voltage_sel_regmap(reg); |
76 | mask = ((1 << anatop_reg->vol_bit_width) - 1) << | ||
77 | anatop_reg->vol_bit_shift; | ||
78 | val = (val & mask) >> anatop_reg->vol_bit_shift; | ||
79 | |||
80 | return val - anatop_reg->min_bit_val; | ||
81 | } | 66 | } |
82 | 67 | ||
83 | static struct regulator_ops anatop_rops = { | 68 | static struct regulator_ops anatop_rops = { |
@@ -158,15 +143,20 @@ static int __devinit anatop_regulator_probe(struct platform_device *pdev) | |||
158 | goto anatop_probe_end; | 143 | goto anatop_probe_end; |
159 | } | 144 | } |
160 | 145 | ||
161 | rdesc->n_voltages = (sreg->max_voltage - sreg->min_voltage) | 146 | rdesc->n_voltages = (sreg->max_voltage - sreg->min_voltage) / 25000 + 1 |
162 | / 25000 + 1; | 147 | + sreg->min_bit_val; |
163 | rdesc->min_uV = sreg->min_voltage; | 148 | rdesc->min_uV = sreg->min_voltage; |
164 | rdesc->uV_step = 25000; | 149 | rdesc->uV_step = 25000; |
150 | rdesc->linear_min_sel = sreg->min_bit_val; | ||
151 | rdesc->vsel_reg = sreg->control_reg; | ||
152 | rdesc->vsel_mask = ((1 << sreg->vol_bit_width) - 1) << | ||
153 | sreg->vol_bit_shift; | ||
165 | 154 | ||
166 | config.dev = &pdev->dev; | 155 | config.dev = &pdev->dev; |
167 | config.init_data = initdata; | 156 | config.init_data = initdata; |
168 | config.driver_data = sreg; | 157 | config.driver_data = sreg; |
169 | config.of_node = pdev->dev.of_node; | 158 | config.of_node = pdev->dev.of_node; |
159 | config.regmap = sreg->anatop; | ||
170 | 160 | ||
171 | /* register regulator */ | 161 | /* register regulator */ |
172 | rdev = regulator_register(rdesc, &config); | 162 | rdev = regulator_register(rdesc, &config); |
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 59e08633372a..1c8ff8ce5c57 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c | |||
@@ -1919,6 +1919,10 @@ int regulator_list_voltage_linear(struct regulator_dev *rdev, | |||
1919 | { | 1919 | { |
1920 | if (selector >= rdev->desc->n_voltages) | 1920 | if (selector >= rdev->desc->n_voltages) |
1921 | return -EINVAL; | 1921 | return -EINVAL; |
1922 | if (selector < rdev->desc->linear_min_sel) | ||
1923 | return 0; | ||
1924 | |||
1925 | selector -= rdev->desc->linear_min_sel; | ||
1922 | 1926 | ||
1923 | return rdev->desc->min_uV + (rdev->desc->uV_step * selector); | 1927 | return rdev->desc->min_uV + (rdev->desc->uV_step * selector); |
1924 | } | 1928 | } |
@@ -2142,6 +2146,8 @@ int regulator_map_voltage_linear(struct regulator_dev *rdev, | |||
2142 | if (ret < 0) | 2146 | if (ret < 0) |
2143 | return ret; | 2147 | return ret; |
2144 | 2148 | ||
2149 | ret += rdev->desc->linear_min_sel; | ||
2150 | |||
2145 | /* Map back into a voltage to verify we're still in bounds */ | 2151 | /* Map back into a voltage to verify we're still in bounds */ |
2146 | voltage = rdev->desc->ops->list_voltage(rdev, ret); | 2152 | voltage = rdev->desc->ops->list_voltage(rdev, ret); |
2147 | if (voltage < min_uV || voltage > max_uV) | 2153 | if (voltage < min_uV || voltage > max_uV) |
diff --git a/drivers/regulator/da9055-regulator.c b/drivers/regulator/da9055-regulator.c new file mode 100644 index 000000000000..2253559703ce --- /dev/null +++ b/drivers/regulator/da9055-regulator.c | |||
@@ -0,0 +1,644 @@ | |||
1 | /* | ||
2 | * Regulator driver for DA9055 PMIC | ||
3 | * | ||
4 | * Copyright(c) 2012 Dialog Semiconductor Ltd. | ||
5 | * | ||
6 | * Author: David Dajun Chen <dchen@diasemi.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 as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | */ | ||
14 | |||
15 | #include <linux/module.h> | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/err.h> | ||
18 | #include <linux/gpio.h> | ||
19 | #include <linux/platform_device.h> | ||
20 | #include <linux/regulator/driver.h> | ||
21 | #include <linux/regulator/machine.h> | ||
22 | |||
23 | #include <linux/mfd/da9055/core.h> | ||
24 | #include <linux/mfd/da9055/reg.h> | ||
25 | #include <linux/mfd/da9055/pdata.h> | ||
26 | |||
27 | #define DA9055_MIN_UA 0 | ||
28 | #define DA9055_MAX_UA 3 | ||
29 | |||
30 | #define DA9055_LDO_MODE_SYNC 0 | ||
31 | #define DA9055_LDO_MODE_SLEEP 1 | ||
32 | |||
33 | #define DA9055_BUCK_MODE_SLEEP 1 | ||
34 | #define DA9055_BUCK_MODE_SYNC 2 | ||
35 | #define DA9055_BUCK_MODE_AUTO 3 | ||
36 | |||
37 | /* DA9055 REGULATOR IDs */ | ||
38 | #define DA9055_ID_BUCK1 0 | ||
39 | #define DA9055_ID_BUCK2 1 | ||
40 | #define DA9055_ID_LDO1 2 | ||
41 | #define DA9055_ID_LDO2 3 | ||
42 | #define DA9055_ID_LDO3 4 | ||
43 | #define DA9055_ID_LDO4 5 | ||
44 | #define DA9055_ID_LDO5 6 | ||
45 | #define DA9055_ID_LDO6 7 | ||
46 | |||
47 | /* DA9055 BUCK current limit */ | ||
48 | static const int da9055_current_limits[] = { 500000, 600000, 700000, 800000 }; | ||
49 | |||
50 | struct da9055_conf_reg { | ||
51 | int reg; | ||
52 | int sel_mask; | ||
53 | int en_mask; | ||
54 | }; | ||
55 | |||
56 | struct da9055_volt_reg { | ||
57 | int reg_a; | ||
58 | int reg_b; | ||
59 | int sl_shift; | ||
60 | int v_mask; | ||
61 | int v_shift; | ||
62 | }; | ||
63 | |||
64 | struct da9055_mode_reg { | ||
65 | int reg; | ||
66 | int mask; | ||
67 | int shift; | ||
68 | }; | ||
69 | |||
70 | struct da9055_regulator_info { | ||
71 | struct regulator_desc reg_desc; | ||
72 | struct da9055_conf_reg conf; | ||
73 | struct da9055_volt_reg volt; | ||
74 | struct da9055_mode_reg mode; | ||
75 | }; | ||
76 | |||
77 | struct da9055_regulator { | ||
78 | struct da9055 *da9055; | ||
79 | struct da9055_regulator_info *info; | ||
80 | struct regulator_dev *rdev; | ||
81 | enum gpio_select reg_rselect; | ||
82 | }; | ||
83 | |||
84 | static unsigned int da9055_buck_get_mode(struct regulator_dev *rdev) | ||
85 | { | ||
86 | struct da9055_regulator *regulator = rdev_get_drvdata(rdev); | ||
87 | struct da9055_regulator_info *info = regulator->info; | ||
88 | int ret, mode = 0; | ||
89 | |||
90 | ret = da9055_reg_read(regulator->da9055, info->mode.reg); | ||
91 | if (ret < 0) | ||
92 | return ret; | ||
93 | |||
94 | switch ((ret & info->mode.mask) >> info->mode.shift) { | ||
95 | case DA9055_BUCK_MODE_SYNC: | ||
96 | mode = REGULATOR_MODE_FAST; | ||
97 | break; | ||
98 | case DA9055_BUCK_MODE_AUTO: | ||
99 | mode = REGULATOR_MODE_NORMAL; | ||
100 | break; | ||
101 | case DA9055_BUCK_MODE_SLEEP: | ||
102 | mode = REGULATOR_MODE_STANDBY; | ||
103 | break; | ||
104 | } | ||
105 | |||
106 | return mode; | ||
107 | } | ||
108 | |||
109 | static int da9055_buck_set_mode(struct regulator_dev *rdev, | ||
110 | unsigned int mode) | ||
111 | { | ||
112 | struct da9055_regulator *regulator = rdev_get_drvdata(rdev); | ||
113 | struct da9055_regulator_info *info = regulator->info; | ||
114 | int val = 0; | ||
115 | |||
116 | switch (mode) { | ||
117 | case REGULATOR_MODE_FAST: | ||
118 | val = DA9055_BUCK_MODE_SYNC << info->mode.shift; | ||
119 | break; | ||
120 | case REGULATOR_MODE_NORMAL: | ||
121 | val = DA9055_BUCK_MODE_AUTO << info->mode.shift; | ||
122 | break; | ||
123 | case REGULATOR_MODE_STANDBY: | ||
124 | val = DA9055_BUCK_MODE_SLEEP << info->mode.shift; | ||
125 | break; | ||
126 | } | ||
127 | |||
128 | return da9055_reg_update(regulator->da9055, info->mode.reg, | ||
129 | info->mode.mask, val); | ||
130 | } | ||
131 | |||
132 | static unsigned int da9055_ldo_get_mode(struct regulator_dev *rdev) | ||
133 | { | ||
134 | struct da9055_regulator *regulator = rdev_get_drvdata(rdev); | ||
135 | struct da9055_regulator_info *info = regulator->info; | ||
136 | int ret; | ||
137 | |||
138 | ret = da9055_reg_read(regulator->da9055, info->volt.reg_b); | ||
139 | if (ret < 0) | ||
140 | return ret; | ||
141 | |||
142 | if (ret >> info->volt.sl_shift) | ||
143 | return REGULATOR_MODE_STANDBY; | ||
144 | else | ||
145 | return REGULATOR_MODE_NORMAL; | ||
146 | } | ||
147 | |||
148 | static int da9055_ldo_set_mode(struct regulator_dev *rdev, unsigned int mode) | ||
149 | { | ||
150 | struct da9055_regulator *regulator = rdev_get_drvdata(rdev); | ||
151 | struct da9055_regulator_info *info = regulator->info; | ||
152 | struct da9055_volt_reg volt = info->volt; | ||
153 | int val = 0; | ||
154 | |||
155 | switch (mode) { | ||
156 | case REGULATOR_MODE_NORMAL: | ||
157 | case REGULATOR_MODE_FAST: | ||
158 | val = DA9055_LDO_MODE_SYNC; | ||
159 | break; | ||
160 | case REGULATOR_MODE_STANDBY: | ||
161 | val = DA9055_LDO_MODE_SLEEP; | ||
162 | break; | ||
163 | } | ||
164 | |||
165 | return da9055_reg_update(regulator->da9055, volt.reg_b, | ||
166 | 1 << volt.sl_shift, | ||
167 | val << volt.sl_shift); | ||
168 | } | ||
169 | |||
170 | static int da9055_buck_get_current_limit(struct regulator_dev *rdev) | ||
171 | { | ||
172 | struct da9055_regulator *regulator = rdev_get_drvdata(rdev); | ||
173 | struct da9055_regulator_info *info = regulator->info; | ||
174 | int ret; | ||
175 | |||
176 | ret = da9055_reg_read(regulator->da9055, DA9055_REG_BUCK_LIM); | ||
177 | if (ret < 0) | ||
178 | return ret; | ||
179 | |||
180 | ret &= info->mode.mask; | ||
181 | return da9055_current_limits[ret >> info->mode.shift]; | ||
182 | } | ||
183 | |||
184 | static int da9055_buck_set_current_limit(struct regulator_dev *rdev, int min_uA, | ||
185 | int max_uA) | ||
186 | { | ||
187 | struct da9055_regulator *regulator = rdev_get_drvdata(rdev); | ||
188 | struct da9055_regulator_info *info = regulator->info; | ||
189 | int i, val = 0; | ||
190 | |||
191 | if (min_uA > da9055_current_limits[DA9055_MAX_UA] || | ||
192 | max_uA < da9055_current_limits[DA9055_MIN_UA]) | ||
193 | return -EINVAL; | ||
194 | |||
195 | for (i = 0; i < ARRAY_SIZE(da9055_current_limits); i++) { | ||
196 | if (min_uA <= da9055_current_limits[i]) { | ||
197 | val = i; | ||
198 | break; | ||
199 | } | ||
200 | } | ||
201 | |||
202 | return da9055_reg_update(regulator->da9055, DA9055_REG_BUCK_LIM, | ||
203 | info->mode.mask, val << info->mode.shift); | ||
204 | } | ||
205 | |||
206 | static int da9055_regulator_get_voltage_sel(struct regulator_dev *rdev) | ||
207 | { | ||
208 | struct da9055_regulator *regulator = rdev_get_drvdata(rdev); | ||
209 | struct da9055_regulator_info *info = regulator->info; | ||
210 | struct da9055_volt_reg volt = info->volt; | ||
211 | int ret, sel; | ||
212 | |||
213 | /* | ||
214 | * There are two voltage register set A & B for voltage ramping but | ||
215 | * either one of then can be active therefore we first determine | ||
216 | * the active register set. | ||
217 | */ | ||
218 | ret = da9055_reg_read(regulator->da9055, info->conf.reg); | ||
219 | if (ret < 0) | ||
220 | return ret; | ||
221 | |||
222 | ret &= info->conf.sel_mask; | ||
223 | |||
224 | /* Get the voltage for the active register set A/B */ | ||
225 | if (ret == DA9055_REGUALTOR_SET_A) | ||
226 | ret = da9055_reg_read(regulator->da9055, volt.reg_a); | ||
227 | else | ||
228 | ret = da9055_reg_read(regulator->da9055, volt.reg_b); | ||
229 | |||
230 | if (ret < 0) | ||
231 | return ret; | ||
232 | |||
233 | sel = (ret & volt.v_mask); | ||
234 | return sel; | ||
235 | } | ||
236 | |||
237 | static int da9055_regulator_set_voltage_sel(struct regulator_dev *rdev, | ||
238 | unsigned int selector) | ||
239 | { | ||
240 | struct da9055_regulator *regulator = rdev_get_drvdata(rdev); | ||
241 | struct da9055_regulator_info *info = regulator->info; | ||
242 | int ret; | ||
243 | |||
244 | /* | ||
245 | * Regulator register set A/B is not selected through GPIO therefore | ||
246 | * we use default register set A for voltage ramping. | ||
247 | */ | ||
248 | if (regulator->reg_rselect == NO_GPIO) { | ||
249 | /* Select register set A */ | ||
250 | ret = da9055_reg_update(regulator->da9055, info->conf.reg, | ||
251 | info->conf.sel_mask, DA9055_SEL_REG_A); | ||
252 | if (ret < 0) | ||
253 | return ret; | ||
254 | |||
255 | /* Set the voltage */ | ||
256 | return da9055_reg_update(regulator->da9055, info->volt.reg_a, | ||
257 | info->volt.v_mask, selector); | ||
258 | } | ||
259 | |||
260 | /* | ||
261 | * Here regulator register set A/B is selected through GPIO. | ||
262 | * Therefore we first determine the selected register set A/B and | ||
263 | * then set the desired voltage for that register set A/B. | ||
264 | */ | ||
265 | ret = da9055_reg_read(regulator->da9055, info->conf.reg); | ||
266 | if (ret < 0) | ||
267 | return ret; | ||
268 | |||
269 | ret &= info->conf.sel_mask; | ||
270 | |||
271 | /* Set the voltage */ | ||
272 | if (ret == DA9055_REGUALTOR_SET_A) | ||
273 | return da9055_reg_update(regulator->da9055, info->volt.reg_a, | ||
274 | info->volt.v_mask, selector); | ||
275 | else | ||
276 | return da9055_reg_update(regulator->da9055, info->volt.reg_b, | ||
277 | info->volt.v_mask, selector); | ||
278 | } | ||
279 | |||
280 | static int da9055_regulator_set_suspend_voltage(struct regulator_dev *rdev, | ||
281 | int uV) | ||
282 | { | ||
283 | struct da9055_regulator *regulator = rdev_get_drvdata(rdev); | ||
284 | struct da9055_regulator_info *info = regulator->info; | ||
285 | int ret; | ||
286 | |||
287 | /* Select register set B for suspend voltage ramping. */ | ||
288 | if (regulator->reg_rselect == NO_GPIO) { | ||
289 | ret = da9055_reg_update(regulator->da9055, info->conf.reg, | ||
290 | info->conf.sel_mask, DA9055_SEL_REG_B); | ||
291 | if (ret < 0) | ||
292 | return ret; | ||
293 | } | ||
294 | |||
295 | ret = regulator_map_voltage_linear(rdev, uV, uV); | ||
296 | if (ret < 0) | ||
297 | return ret; | ||
298 | |||
299 | return da9055_reg_update(regulator->da9055, info->volt.reg_b, | ||
300 | info->volt.v_mask, ret); | ||
301 | } | ||
302 | |||
303 | static int da9055_suspend_enable(struct regulator_dev *rdev) | ||
304 | { | ||
305 | struct da9055_regulator *regulator = rdev_get_drvdata(rdev); | ||
306 | struct da9055_regulator_info *info = regulator->info; | ||
307 | |||
308 | /* Select register set B for voltage ramping. */ | ||
309 | if (regulator->reg_rselect == NO_GPIO) | ||
310 | return da9055_reg_update(regulator->da9055, info->conf.reg, | ||
311 | info->conf.sel_mask, DA9055_SEL_REG_B); | ||
312 | else | ||
313 | return 0; | ||
314 | } | ||
315 | |||
316 | static int da9055_suspend_disable(struct regulator_dev *rdev) | ||
317 | { | ||
318 | struct da9055_regulator *regulator = rdev_get_drvdata(rdev); | ||
319 | struct da9055_regulator_info *info = regulator->info; | ||
320 | |||
321 | /* Diselect register set B. */ | ||
322 | if (regulator->reg_rselect == NO_GPIO) | ||
323 | return da9055_reg_update(regulator->da9055, info->conf.reg, | ||
324 | info->conf.sel_mask, DA9055_SEL_REG_A); | ||
325 | else | ||
326 | return 0; | ||
327 | } | ||
328 | |||
329 | static struct regulator_ops da9055_buck_ops = { | ||
330 | .get_mode = da9055_buck_get_mode, | ||
331 | .set_mode = da9055_buck_set_mode, | ||
332 | |||
333 | .get_current_limit = da9055_buck_get_current_limit, | ||
334 | .set_current_limit = da9055_buck_set_current_limit, | ||
335 | |||
336 | .get_voltage_sel = da9055_regulator_get_voltage_sel, | ||
337 | .set_voltage_sel = da9055_regulator_set_voltage_sel, | ||
338 | .list_voltage = regulator_list_voltage_linear, | ||
339 | .map_voltage = regulator_map_voltage_linear, | ||
340 | .is_enabled = regulator_is_enabled_regmap, | ||
341 | .enable = regulator_enable_regmap, | ||
342 | .disable = regulator_disable_regmap, | ||
343 | |||
344 | .set_suspend_voltage = da9055_regulator_set_suspend_voltage, | ||
345 | .set_suspend_enable = da9055_suspend_enable, | ||
346 | .set_suspend_disable = da9055_suspend_disable, | ||
347 | .set_suspend_mode = da9055_buck_set_mode, | ||
348 | }; | ||
349 | |||
350 | static struct regulator_ops da9055_ldo_ops = { | ||
351 | .get_mode = da9055_ldo_get_mode, | ||
352 | .set_mode = da9055_ldo_set_mode, | ||
353 | |||
354 | .get_voltage_sel = da9055_regulator_get_voltage_sel, | ||
355 | .set_voltage_sel = da9055_regulator_set_voltage_sel, | ||
356 | .list_voltage = regulator_list_voltage_linear, | ||
357 | .map_voltage = regulator_map_voltage_linear, | ||
358 | .is_enabled = regulator_is_enabled_regmap, | ||
359 | .enable = regulator_enable_regmap, | ||
360 | .disable = regulator_disable_regmap, | ||
361 | |||
362 | .set_suspend_voltage = da9055_regulator_set_suspend_voltage, | ||
363 | .set_suspend_enable = da9055_suspend_enable, | ||
364 | .set_suspend_disable = da9055_suspend_disable, | ||
365 | .set_suspend_mode = da9055_ldo_set_mode, | ||
366 | |||
367 | }; | ||
368 | |||
369 | #define DA9055_LDO(_id, step, min, max, vbits, voffset) \ | ||
370 | {\ | ||
371 | .reg_desc = {\ | ||
372 | .name = #_id,\ | ||
373 | .ops = &da9055_ldo_ops,\ | ||
374 | .type = REGULATOR_VOLTAGE,\ | ||
375 | .id = DA9055_ID_##_id,\ | ||
376 | .n_voltages = (max - min) / step + 1 + (voffset), \ | ||
377 | .enable_reg = DA9055_REG_BCORE_CONT + DA9055_ID_##_id, \ | ||
378 | .enable_mask = 1, \ | ||
379 | .min_uV = (min) * 1000,\ | ||
380 | .uV_step = (step) * 1000,\ | ||
381 | .linear_min_sel = (voffset),\ | ||
382 | .owner = THIS_MODULE,\ | ||
383 | },\ | ||
384 | .conf = {\ | ||
385 | .reg = DA9055_REG_BCORE_CONT + DA9055_ID_##_id, \ | ||
386 | .sel_mask = (1 << 4),\ | ||
387 | .en_mask = 1,\ | ||
388 | },\ | ||
389 | .volt = {\ | ||
390 | .reg_a = DA9055_REG_VBCORE_A + DA9055_ID_##_id, \ | ||
391 | .reg_b = DA9055_REG_VBCORE_B + DA9055_ID_##_id, \ | ||
392 | .sl_shift = 7,\ | ||
393 | .v_mask = (1 << (vbits)) - 1,\ | ||
394 | .v_shift = (vbits),\ | ||
395 | },\ | ||
396 | } | ||
397 | |||
398 | #define DA9055_BUCK(_id, step, min, max, vbits, voffset, mbits, sbits) \ | ||
399 | {\ | ||
400 | .reg_desc = {\ | ||
401 | .name = #_id,\ | ||
402 | .ops = &da9055_buck_ops,\ | ||
403 | .type = REGULATOR_VOLTAGE,\ | ||
404 | .id = DA9055_ID_##_id,\ | ||
405 | .n_voltages = (max - min) / step + 1 + (voffset), \ | ||
406 | .enable_reg = DA9055_REG_BCORE_CONT + DA9055_ID_##_id, \ | ||
407 | .enable_mask = 1,\ | ||
408 | .min_uV = (min) * 1000,\ | ||
409 | .uV_step = (step) * 1000,\ | ||
410 | .linear_min_sel = (voffset),\ | ||
411 | .owner = THIS_MODULE,\ | ||
412 | },\ | ||
413 | .conf = {\ | ||
414 | .reg = DA9055_REG_BCORE_CONT + DA9055_ID_##_id, \ | ||
415 | .sel_mask = (1 << 4),\ | ||
416 | .en_mask = 1,\ | ||
417 | },\ | ||
418 | .volt = {\ | ||
419 | .reg_a = DA9055_REG_VBCORE_A + DA9055_ID_##_id, \ | ||
420 | .reg_b = DA9055_REG_VBCORE_B + DA9055_ID_##_id, \ | ||
421 | .sl_shift = 7,\ | ||
422 | .v_mask = (1 << (vbits)) - 1,\ | ||
423 | .v_shift = (vbits),\ | ||
424 | },\ | ||
425 | .mode = {\ | ||
426 | .reg = DA9055_REG_BCORE_MODE,\ | ||
427 | .mask = (mbits),\ | ||
428 | .shift = (sbits),\ | ||
429 | },\ | ||
430 | } | ||
431 | |||
432 | static struct da9055_regulator_info da9055_regulator_info[] = { | ||
433 | DA9055_BUCK(BUCK1, 25, 725, 2075, 6, 9, 0xc, 2), | ||
434 | DA9055_BUCK(BUCK2, 25, 925, 2500, 6, 0, 3, 0), | ||
435 | DA9055_LDO(LDO1, 50, 900, 3300, 6, 2), | ||
436 | DA9055_LDO(LDO2, 50, 900, 3300, 6, 3), | ||
437 | DA9055_LDO(LDO3, 50, 900, 3300, 6, 2), | ||
438 | DA9055_LDO(LDO4, 50, 900, 3300, 6, 2), | ||
439 | DA9055_LDO(LDO5, 50, 900, 2750, 6, 2), | ||
440 | DA9055_LDO(LDO6, 20, 900, 3300, 7, 0), | ||
441 | }; | ||
442 | |||
443 | /* | ||
444 | * Configures regulator to be controlled either through GPIO 1 or 2. | ||
445 | * GPIO can control regulator state and/or select the regulator register | ||
446 | * set A/B for voltage ramping. | ||
447 | */ | ||
448 | static __devinit int da9055_gpio_init(struct da9055_regulator *regulator, | ||
449 | struct regulator_config *config, | ||
450 | struct da9055_pdata *pdata, int id) | ||
451 | { | ||
452 | struct da9055_regulator_info *info = regulator->info; | ||
453 | int ret = 0; | ||
454 | |||
455 | if (pdata->gpio_ren && pdata->gpio_ren[id]) { | ||
456 | char name[18]; | ||
457 | int gpio_mux = pdata->gpio_ren[id]; | ||
458 | |||
459 | config->ena_gpio = pdata->ena_gpio[id]; | ||
460 | config->ena_gpio_flags = GPIOF_OUT_INIT_HIGH; | ||
461 | config->ena_gpio_invert = 1; | ||
462 | |||
463 | /* | ||
464 | * GPI pin is muxed with regulator to control the | ||
465 | * regulator state. | ||
466 | */ | ||
467 | sprintf(name, "DA9055 GPI %d", gpio_mux); | ||
468 | ret = devm_gpio_request_one(config->dev, gpio_mux, GPIOF_DIR_IN, | ||
469 | name); | ||
470 | if (ret < 0) | ||
471 | goto err; | ||
472 | |||
473 | /* | ||
474 | * Let the regulator know that its state is controlled | ||
475 | * through GPI. | ||
476 | */ | ||
477 | ret = da9055_reg_update(regulator->da9055, info->conf.reg, | ||
478 | DA9055_E_GPI_MASK, | ||
479 | pdata->reg_ren[id] | ||
480 | << DA9055_E_GPI_SHIFT); | ||
481 | if (ret < 0) | ||
482 | goto err; | ||
483 | } | ||
484 | |||
485 | if (pdata->gpio_rsel && pdata->gpio_rsel[id]) { | ||
486 | char name[18]; | ||
487 | int gpio_mux = pdata->gpio_rsel[id]; | ||
488 | |||
489 | regulator->reg_rselect = pdata->reg_rsel[id]; | ||
490 | |||
491 | /* | ||
492 | * GPI pin is muxed with regulator to select the | ||
493 | * regulator register set A/B for voltage ramping. | ||
494 | */ | ||
495 | sprintf(name, "DA9055 GPI %d", gpio_mux); | ||
496 | ret = devm_gpio_request_one(config->dev, gpio_mux, GPIOF_DIR_IN, | ||
497 | name); | ||
498 | if (ret < 0) | ||
499 | goto err; | ||
500 | |||
501 | /* | ||
502 | * Let the regulator know that its register set A/B | ||
503 | * will be selected through GPI for voltage ramping. | ||
504 | */ | ||
505 | ret = da9055_reg_update(regulator->da9055, info->conf.reg, | ||
506 | DA9055_V_GPI_MASK, | ||
507 | pdata->reg_rsel[id] | ||
508 | << DA9055_V_GPI_SHIFT); | ||
509 | } | ||
510 | |||
511 | err: | ||
512 | return ret; | ||
513 | } | ||
514 | |||
515 | static irqreturn_t da9055_ldo5_6_oc_irq(int irq, void *data) | ||
516 | { | ||
517 | struct da9055_regulator *regulator = data; | ||
518 | |||
519 | regulator_notifier_call_chain(regulator->rdev, | ||
520 | REGULATOR_EVENT_OVER_CURRENT, NULL); | ||
521 | |||
522 | return IRQ_HANDLED; | ||
523 | } | ||
524 | |||
525 | static inline struct da9055_regulator_info *find_regulator_info(int id) | ||
526 | { | ||
527 | struct da9055_regulator_info *info; | ||
528 | int i; | ||
529 | |||
530 | for (i = 0; i < ARRAY_SIZE(da9055_regulator_info); i++) { | ||
531 | info = &da9055_regulator_info[i]; | ||
532 | if (info->reg_desc.id == id) | ||
533 | return info; | ||
534 | } | ||
535 | |||
536 | return NULL; | ||
537 | } | ||
538 | |||
539 | static int __devinit da9055_regulator_probe(struct platform_device *pdev) | ||
540 | { | ||
541 | struct regulator_config config = { }; | ||
542 | struct da9055_regulator *regulator; | ||
543 | struct da9055 *da9055 = dev_get_drvdata(pdev->dev.parent); | ||
544 | struct da9055_pdata *pdata = da9055->dev->platform_data; | ||
545 | int ret, irq; | ||
546 | |||
547 | if (pdata == NULL || pdata->regulators[pdev->id] == NULL) | ||
548 | return -ENODEV; | ||
549 | |||
550 | regulator = devm_kzalloc(&pdev->dev, sizeof(struct da9055_regulator), | ||
551 | GFP_KERNEL); | ||
552 | if (!regulator) | ||
553 | return -ENOMEM; | ||
554 | |||
555 | regulator->info = find_regulator_info(pdev->id); | ||
556 | if (regulator->info == NULL) { | ||
557 | dev_err(&pdev->dev, "invalid regulator ID specified\n"); | ||
558 | return -EINVAL; | ||
559 | } | ||
560 | |||
561 | regulator->da9055 = da9055; | ||
562 | config.dev = &pdev->dev; | ||
563 | config.driver_data = regulator; | ||
564 | config.regmap = da9055->regmap; | ||
565 | |||
566 | if (pdata && pdata->regulators) | ||
567 | config.init_data = pdata->regulators[pdev->id]; | ||
568 | |||
569 | ret = da9055_gpio_init(regulator, &config, pdata, pdev->id); | ||
570 | if (ret < 0) | ||
571 | return ret; | ||
572 | |||
573 | regulator->rdev = regulator_register(®ulator->info->reg_desc, | ||
574 | &config); | ||
575 | if (IS_ERR(regulator->rdev)) { | ||
576 | dev_err(&pdev->dev, "Failed to register regulator %s\n", | ||
577 | regulator->info->reg_desc.name); | ||
578 | ret = PTR_ERR(regulator->rdev); | ||
579 | return ret; | ||
580 | } | ||
581 | |||
582 | /* Only LDO 5 and 6 has got the over current interrupt */ | ||
583 | if (pdev->id == DA9055_ID_LDO5 || pdev->id == DA9055_ID_LDO6) { | ||
584 | irq = platform_get_irq_byname(pdev, "REGULATOR"); | ||
585 | irq = regmap_irq_get_virq(da9055->irq_data, irq); | ||
586 | ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, | ||
587 | da9055_ldo5_6_oc_irq, | ||
588 | IRQF_TRIGGER_HIGH | | ||
589 | IRQF_ONESHOT | | ||
590 | IRQF_PROBE_SHARED, | ||
591 | pdev->name, regulator); | ||
592 | if (ret != 0) { | ||
593 | if (ret != -EBUSY) { | ||
594 | dev_err(&pdev->dev, | ||
595 | "Failed to request Regulator IRQ %d: %d\n", | ||
596 | irq, ret); | ||
597 | goto err_regulator; | ||
598 | } | ||
599 | } | ||
600 | } | ||
601 | |||
602 | platform_set_drvdata(pdev, regulator); | ||
603 | |||
604 | return 0; | ||
605 | |||
606 | err_regulator: | ||
607 | regulator_unregister(regulator->rdev); | ||
608 | return ret; | ||
609 | } | ||
610 | |||
611 | static int __devexit da9055_regulator_remove(struct platform_device *pdev) | ||
612 | { | ||
613 | struct da9055_regulator *regulator = platform_get_drvdata(pdev); | ||
614 | |||
615 | regulator_unregister(regulator->rdev); | ||
616 | |||
617 | return 0; | ||
618 | } | ||
619 | |||
620 | static struct platform_driver da9055_regulator_driver = { | ||
621 | .probe = da9055_regulator_probe, | ||
622 | .remove = __devexit_p(da9055_regulator_remove), | ||
623 | .driver = { | ||
624 | .name = "da9055-regulator", | ||
625 | .owner = THIS_MODULE, | ||
626 | }, | ||
627 | }; | ||
628 | |||
629 | static int __init da9055_regulator_init(void) | ||
630 | { | ||
631 | return platform_driver_register(&da9055_regulator_driver); | ||
632 | } | ||
633 | subsys_initcall(da9055_regulator_init); | ||
634 | |||
635 | static void __exit da9055_regulator_exit(void) | ||
636 | { | ||
637 | platform_driver_unregister(&da9055_regulator_driver); | ||
638 | } | ||
639 | module_exit(da9055_regulator_exit); | ||
640 | |||
641 | MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>"); | ||
642 | MODULE_DESCRIPTION("Power Regulator driver for Dialog DA9055 PMIC"); | ||
643 | MODULE_LICENSE("GPL"); | ||
644 | MODULE_ALIAS("platform:da9055-regulator"); | ||
diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c index 07aee694ba92..111d76b04bb5 100644 --- a/drivers/regulator/palmas-regulator.c +++ b/drivers/regulator/palmas-regulator.c | |||
@@ -436,44 +436,14 @@ static int palmas_is_enabled_ldo(struct regulator_dev *dev) | |||
436 | return !!(reg); | 436 | return !!(reg); |
437 | } | 437 | } |
438 | 438 | ||
439 | static int palmas_list_voltage_ldo(struct regulator_dev *dev, | ||
440 | unsigned selector) | ||
441 | { | ||
442 | if (!selector) | ||
443 | return 0; | ||
444 | |||
445 | /* voltage is 0.85V + (selector * 0.05v) */ | ||
446 | return 850000 + (selector * 50000); | ||
447 | } | ||
448 | |||
449 | static int palmas_map_voltage_ldo(struct regulator_dev *rdev, | ||
450 | int min_uV, int max_uV) | ||
451 | { | ||
452 | int ret, voltage; | ||
453 | |||
454 | if (min_uV == 0) | ||
455 | return 0; | ||
456 | |||
457 | if (min_uV < 900000) | ||
458 | min_uV = 900000; | ||
459 | ret = DIV_ROUND_UP(min_uV - 900000, 50000) + 1; | ||
460 | |||
461 | /* Map back into a voltage to verify we're still in bounds */ | ||
462 | voltage = palmas_list_voltage_ldo(rdev, ret); | ||
463 | if (voltage < min_uV || voltage > max_uV) | ||
464 | return -EINVAL; | ||
465 | |||
466 | return ret; | ||
467 | } | ||
468 | |||
469 | static struct regulator_ops palmas_ops_ldo = { | 439 | static struct regulator_ops palmas_ops_ldo = { |
470 | .is_enabled = palmas_is_enabled_ldo, | 440 | .is_enabled = palmas_is_enabled_ldo, |
471 | .enable = regulator_enable_regmap, | 441 | .enable = regulator_enable_regmap, |
472 | .disable = regulator_disable_regmap, | 442 | .disable = regulator_disable_regmap, |
473 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | 443 | .get_voltage_sel = regulator_get_voltage_sel_regmap, |
474 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | 444 | .set_voltage_sel = regulator_set_voltage_sel_regmap, |
475 | .list_voltage = palmas_list_voltage_ldo, | 445 | .list_voltage = regulator_list_voltage_linear, |
476 | .map_voltage = palmas_map_voltage_ldo, | 446 | .map_voltage = regulator_map_voltage_linear, |
477 | }; | 447 | }; |
478 | 448 | ||
479 | /* | 449 | /* |
@@ -821,6 +791,9 @@ static __devinit int palmas_probe(struct platform_device *pdev) | |||
821 | 791 | ||
822 | pmic->desc[id].type = REGULATOR_VOLTAGE; | 792 | pmic->desc[id].type = REGULATOR_VOLTAGE; |
823 | pmic->desc[id].owner = THIS_MODULE; | 793 | pmic->desc[id].owner = THIS_MODULE; |
794 | pmic->desc[id].min_uV = 900000; | ||
795 | pmic->desc[id].uV_step = 50000; | ||
796 | pmic->desc[id].linear_min_sel = 1; | ||
824 | pmic->desc[id].vsel_reg = PALMAS_BASE_TO_REG(PALMAS_LDO_BASE, | 797 | pmic->desc[id].vsel_reg = PALMAS_BASE_TO_REG(PALMAS_LDO_BASE, |
825 | palmas_regs_info[id].vsel_addr); | 798 | palmas_regs_info[id].vsel_addr); |
826 | pmic->desc[id].vsel_mask = PALMAS_LDO1_VOLTAGE_VSEL_MASK; | 799 | pmic->desc[id].vsel_mask = PALMAS_LDO1_VOLTAGE_VSEL_MASK; |
diff --git a/drivers/regulator/pcf50633-regulator.c b/drivers/regulator/pcf50633-regulator.c index 092e5cb848a1..769272afff2a 100644 --- a/drivers/regulator/pcf50633-regulator.c +++ b/drivers/regulator/pcf50633-regulator.c | |||
@@ -24,12 +24,15 @@ | |||
24 | #include <linux/mfd/pcf50633/core.h> | 24 | #include <linux/mfd/pcf50633/core.h> |
25 | #include <linux/mfd/pcf50633/pmic.h> | 25 | #include <linux/mfd/pcf50633/pmic.h> |
26 | 26 | ||
27 | #define PCF50633_REGULATOR(_name, _id, _n) \ | 27 | #define PCF50633_REGULATOR(_name, _id, _min_uV, _uV_step, _min_sel, _n) \ |
28 | { \ | 28 | { \ |
29 | .name = _name, \ | 29 | .name = _name, \ |
30 | .id = PCF50633_REGULATOR_##_id, \ | 30 | .id = PCF50633_REGULATOR_##_id, \ |
31 | .ops = &pcf50633_regulator_ops, \ | 31 | .ops = &pcf50633_regulator_ops, \ |
32 | .n_voltages = _n, \ | 32 | .n_voltages = _n, \ |
33 | .min_uV = _min_uV, \ | ||
34 | .uV_step = _uV_step, \ | ||
35 | .linear_min_sel = _min_sel, \ | ||
33 | .type = REGULATOR_VOLTAGE, \ | 36 | .type = REGULATOR_VOLTAGE, \ |
34 | .owner = THIS_MODULE, \ | 37 | .owner = THIS_MODULE, \ |
35 | .vsel_reg = PCF50633_REG_##_id##OUT, \ | 38 | .vsel_reg = PCF50633_REG_##_id##OUT, \ |
@@ -38,162 +41,39 @@ | |||
38 | .enable_mask = PCF50633_REGULATOR_ON, \ | 41 | .enable_mask = PCF50633_REGULATOR_ON, \ |
39 | } | 42 | } |
40 | 43 | ||
41 | /* Bits from voltage value */ | ||
42 | static u8 auto_voltage_bits(unsigned int millivolts) | ||
43 | { | ||
44 | if (millivolts < 1800) | ||
45 | return 0x2f; | ||
46 | if (millivolts > 3800) | ||
47 | return 0xff; | ||
48 | |||
49 | millivolts -= 625; | ||
50 | |||
51 | return millivolts / 25; | ||
52 | } | ||
53 | |||
54 | static u8 down_voltage_bits(unsigned int millivolts) | ||
55 | { | ||
56 | if (millivolts < 625) | ||
57 | return 0; | ||
58 | else if (millivolts > 3000) | ||
59 | return 0xff; | ||
60 | |||
61 | millivolts -= 625; | ||
62 | |||
63 | return millivolts / 25; | ||
64 | } | ||
65 | |||
66 | static u8 ldo_voltage_bits(unsigned int millivolts) | ||
67 | { | ||
68 | if (millivolts < 900) | ||
69 | return 0; | ||
70 | else if (millivolts > 3600) | ||
71 | return 0x1f; | ||
72 | |||
73 | millivolts -= 900; | ||
74 | return millivolts / 100; | ||
75 | } | ||
76 | |||
77 | /* Obtain voltage value from bits */ | ||
78 | static unsigned int auto_voltage_value(u8 bits) | ||
79 | { | ||
80 | /* AUTOOUT: 00000000 to 00101110 are reserved. | ||
81 | * Return 0 for bits in reserved range, which means this selector code | ||
82 | * can't be used on this system */ | ||
83 | if (bits < 0x2f) | ||
84 | return 0; | ||
85 | |||
86 | return 625 + (bits * 25); | ||
87 | } | ||
88 | |||
89 | |||
90 | static unsigned int down_voltage_value(u8 bits) | ||
91 | { | ||
92 | return 625 + (bits * 25); | ||
93 | } | ||
94 | |||
95 | |||
96 | static unsigned int ldo_voltage_value(u8 bits) | ||
97 | { | ||
98 | bits &= 0x1f; | ||
99 | |||
100 | return 900 + (bits * 100); | ||
101 | } | ||
102 | |||
103 | static int pcf50633_regulator_map_voltage(struct regulator_dev *rdev, | ||
104 | int min_uV, int max_uV) | ||
105 | { | ||
106 | struct pcf50633 *pcf; | ||
107 | int regulator_id, millivolts; | ||
108 | u8 volt_bits; | ||
109 | |||
110 | pcf = rdev_get_drvdata(rdev); | ||
111 | |||
112 | regulator_id = rdev_get_id(rdev); | ||
113 | if (regulator_id >= PCF50633_NUM_REGULATORS) | ||
114 | return -EINVAL; | ||
115 | |||
116 | millivolts = min_uV / 1000; | ||
117 | |||
118 | switch (regulator_id) { | ||
119 | case PCF50633_REGULATOR_AUTO: | ||
120 | volt_bits = auto_voltage_bits(millivolts); | ||
121 | break; | ||
122 | case PCF50633_REGULATOR_DOWN1: | ||
123 | case PCF50633_REGULATOR_DOWN2: | ||
124 | volt_bits = down_voltage_bits(millivolts); | ||
125 | break; | ||
126 | case PCF50633_REGULATOR_LDO1: | ||
127 | case PCF50633_REGULATOR_LDO2: | ||
128 | case PCF50633_REGULATOR_LDO3: | ||
129 | case PCF50633_REGULATOR_LDO4: | ||
130 | case PCF50633_REGULATOR_LDO5: | ||
131 | case PCF50633_REGULATOR_LDO6: | ||
132 | case PCF50633_REGULATOR_HCLDO: | ||
133 | case PCF50633_REGULATOR_MEMLDO: | ||
134 | volt_bits = ldo_voltage_bits(millivolts); | ||
135 | break; | ||
136 | default: | ||
137 | return -EINVAL; | ||
138 | } | ||
139 | |||
140 | return volt_bits; | ||
141 | } | ||
142 | |||
143 | static int pcf50633_regulator_list_voltage(struct regulator_dev *rdev, | ||
144 | unsigned int index) | ||
145 | { | ||
146 | int regulator_id = rdev_get_id(rdev); | ||
147 | |||
148 | int millivolts; | ||
149 | |||
150 | switch (regulator_id) { | ||
151 | case PCF50633_REGULATOR_AUTO: | ||
152 | millivolts = auto_voltage_value(index); | ||
153 | break; | ||
154 | case PCF50633_REGULATOR_DOWN1: | ||
155 | case PCF50633_REGULATOR_DOWN2: | ||
156 | millivolts = down_voltage_value(index); | ||
157 | break; | ||
158 | case PCF50633_REGULATOR_LDO1: | ||
159 | case PCF50633_REGULATOR_LDO2: | ||
160 | case PCF50633_REGULATOR_LDO3: | ||
161 | case PCF50633_REGULATOR_LDO4: | ||
162 | case PCF50633_REGULATOR_LDO5: | ||
163 | case PCF50633_REGULATOR_LDO6: | ||
164 | case PCF50633_REGULATOR_HCLDO: | ||
165 | case PCF50633_REGULATOR_MEMLDO: | ||
166 | millivolts = ldo_voltage_value(index); | ||
167 | break; | ||
168 | default: | ||
169 | return -EINVAL; | ||
170 | } | ||
171 | |||
172 | return millivolts * 1000; | ||
173 | } | ||
174 | |||
175 | static struct regulator_ops pcf50633_regulator_ops = { | 44 | static struct regulator_ops pcf50633_regulator_ops = { |
176 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | 45 | .set_voltage_sel = regulator_set_voltage_sel_regmap, |
177 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | 46 | .get_voltage_sel = regulator_get_voltage_sel_regmap, |
178 | .list_voltage = pcf50633_regulator_list_voltage, | 47 | .list_voltage = regulator_list_voltage_linear, |
179 | .map_voltage = pcf50633_regulator_map_voltage, | 48 | .map_voltage = regulator_map_voltage_linear, |
180 | .enable = regulator_enable_regmap, | 49 | .enable = regulator_enable_regmap, |
181 | .disable = regulator_disable_regmap, | 50 | .disable = regulator_disable_regmap, |
182 | .is_enabled = regulator_is_enabled_regmap, | 51 | .is_enabled = regulator_is_enabled_regmap, |
183 | }; | 52 | }; |
184 | 53 | ||
185 | static const struct regulator_desc regulators[] = { | 54 | static const struct regulator_desc regulators[] = { |
186 | [PCF50633_REGULATOR_AUTO] = PCF50633_REGULATOR("auto", AUTO, 128), | 55 | [PCF50633_REGULATOR_AUTO] = |
187 | [PCF50633_REGULATOR_DOWN1] = PCF50633_REGULATOR("down1", DOWN1, 96), | 56 | PCF50633_REGULATOR("auto", AUTO, 1800000, 25000, 0x2f, 128), |
188 | [PCF50633_REGULATOR_DOWN2] = PCF50633_REGULATOR("down2", DOWN2, 96), | 57 | [PCF50633_REGULATOR_DOWN1] = |
189 | [PCF50633_REGULATOR_LDO1] = PCF50633_REGULATOR("ldo1", LDO1, 28), | 58 | PCF50633_REGULATOR("down1", DOWN1, 625000, 25000, 0, 96), |
190 | [PCF50633_REGULATOR_LDO2] = PCF50633_REGULATOR("ldo2", LDO2, 28), | 59 | [PCF50633_REGULATOR_DOWN2] = |
191 | [PCF50633_REGULATOR_LDO3] = PCF50633_REGULATOR("ldo3", LDO3, 28), | 60 | PCF50633_REGULATOR("down2", DOWN2, 625000, 25000, 0, 96), |
192 | [PCF50633_REGULATOR_LDO4] = PCF50633_REGULATOR("ldo4", LDO4, 28), | 61 | [PCF50633_REGULATOR_LDO1] = |
193 | [PCF50633_REGULATOR_LDO5] = PCF50633_REGULATOR("ldo5", LDO5, 28), | 62 | PCF50633_REGULATOR("ldo1", LDO1, 900000, 100000, 0, 28), |
194 | [PCF50633_REGULATOR_LDO6] = PCF50633_REGULATOR("ldo6", LDO6, 28), | 63 | [PCF50633_REGULATOR_LDO2] = |
195 | [PCF50633_REGULATOR_HCLDO] = PCF50633_REGULATOR("hcldo", HCLDO, 28), | 64 | PCF50633_REGULATOR("ldo2", LDO2, 900000, 100000, 0, 28), |
196 | [PCF50633_REGULATOR_MEMLDO] = PCF50633_REGULATOR("memldo", MEMLDO, 28), | 65 | [PCF50633_REGULATOR_LDO3] = |
66 | PCF50633_REGULATOR("ldo3", LDO3, 900000, 100000, 0, 28), | ||
67 | [PCF50633_REGULATOR_LDO4] = | ||
68 | PCF50633_REGULATOR("ldo4", LDO4, 900000, 100000, 0, 28), | ||
69 | [PCF50633_REGULATOR_LDO5] = | ||
70 | PCF50633_REGULATOR("ldo5", LDO5, 900000, 100000, 0, 28), | ||
71 | [PCF50633_REGULATOR_LDO6] = | ||
72 | PCF50633_REGULATOR("ldo6", LDO6, 900000, 100000, 0, 28), | ||
73 | [PCF50633_REGULATOR_HCLDO] = | ||
74 | PCF50633_REGULATOR("hcldo", HCLDO, 900000, 100000, 0, 28), | ||
75 | [PCF50633_REGULATOR_MEMLDO] = | ||
76 | PCF50633_REGULATOR("memldo", MEMLDO, 900000, 100000, 0, 28), | ||
197 | }; | 77 | }; |
198 | 78 | ||
199 | static int __devinit pcf50633_regulator_probe(struct platform_device *pdev) | 79 | static int __devinit pcf50633_regulator_probe(struct platform_device *pdev) |
diff --git a/drivers/regulator/tps51632-regulator.c b/drivers/regulator/tps51632-regulator.c new file mode 100644 index 000000000000..7c4e8a6e1d5d --- /dev/null +++ b/drivers/regulator/tps51632-regulator.c | |||
@@ -0,0 +1,327 @@ | |||
1 | /* | ||
2 | * tps51632-regulator.c -- TI TPS51632 | ||
3 | * | ||
4 | * Regulator driver for TPS51632 3-2-1 Phase D-Cap Step Down Driverless | ||
5 | * Controller with serial VID control and DVFS. | ||
6 | * | ||
7 | * Copyright (c) 2012, NVIDIA Corporation. | ||
8 | * | ||
9 | * Author: Laxman Dewangan <ldewangan@nvidia.com> | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or | ||
12 | * modify it under the terms of the GNU General Public License as | ||
13 | * published by the Free Software Foundation version 2. | ||
14 | * | ||
15 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind, | ||
16 | * whether express or implied; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
18 | * General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License | ||
21 | * along with this program; if not, write to the Free Software | ||
22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||
23 | * 02111-1307, USA | ||
24 | */ | ||
25 | |||
26 | #include <linux/err.h> | ||
27 | #include <linux/i2c.h> | ||
28 | #include <linux/init.h> | ||
29 | #include <linux/kernel.h> | ||
30 | #include <linux/module.h> | ||
31 | #include <linux/platform_device.h> | ||
32 | #include <linux/regmap.h> | ||
33 | #include <linux/regulator/driver.h> | ||
34 | #include <linux/regulator/machine.h> | ||
35 | #include <linux/regulator/tps51632-regulator.h> | ||
36 | #include <linux/slab.h> | ||
37 | |||
38 | /* Register definitions */ | ||
39 | #define TPS51632_VOLTAGE_SELECT_REG 0x0 | ||
40 | #define TPS51632_VOLTAGE_BASE_REG 0x1 | ||
41 | #define TPS51632_OFFSET_REG 0x2 | ||
42 | #define TPS51632_IMON_REG 0x3 | ||
43 | #define TPS51632_VMAX_REG 0x4 | ||
44 | #define TPS51632_DVFS_CONTROL_REG 0x5 | ||
45 | #define TPS51632_POWER_STATE_REG 0x6 | ||
46 | #define TPS51632_SLEW_REGS 0x7 | ||
47 | #define TPS51632_FAULT_REG 0x14 | ||
48 | |||
49 | #define TPS51632_MAX_REG 0x15 | ||
50 | |||
51 | #define TPS51632_VOUT_MASK 0x7F | ||
52 | #define TPS51632_VOUT_OFFSET_MASK 0x1F | ||
53 | #define TPS51632_VMAX_MASK 0x7F | ||
54 | #define TPS51632_VMAX_LOCK 0x80 | ||
55 | |||
56 | /* TPS51632_DVFS_CONTROL_REG */ | ||
57 | #define TPS51632_DVFS_PWMEN 0x1 | ||
58 | #define TPS51632_DVFS_STEP_20 0x2 | ||
59 | #define TPS51632_DVFS_VMAX_PG 0x4 | ||
60 | #define TPS51632_DVFS_PWMRST 0x8 | ||
61 | #define TPS51632_DVFS_OCA_EN 0x10 | ||
62 | #define TPS51632_DVFS_FCCM 0x20 | ||
63 | |||
64 | /* TPS51632_POWER_STATE_REG */ | ||
65 | #define TPS51632_POWER_STATE_MASK 0x03 | ||
66 | #define TPS51632_POWER_STATE_MULTI_PHASE_CCM 0x0 | ||
67 | #define TPS51632_POWER_STATE_SINGLE_PHASE_CCM 0x1 | ||
68 | #define TPS51632_POWER_STATE_SINGLE_PHASE_DCM 0x2 | ||
69 | |||
70 | #define TPS51632_MIN_VOLATGE 500000 | ||
71 | #define TPS51632_MAX_VOLATGE 1520000 | ||
72 | #define TPS51632_VOLATGE_STEP_10mV 10000 | ||
73 | #define TPS51632_VOLATGE_STEP_20mV 20000 | ||
74 | #define TPS51632_MAX_VSEL 0x7F | ||
75 | #define TPS51632_MIN_VSEL 0x19 | ||
76 | #define TPS51632_DEFAULT_RAMP_DELAY 6000 | ||
77 | #define TPS51632_VOLT_VSEL(uV) \ | ||
78 | (DIV_ROUND_UP(uV - TPS51632_MIN_VOLATGE, \ | ||
79 | TPS51632_VOLATGE_STEP_10mV) + \ | ||
80 | TPS51632_MIN_VSEL) | ||
81 | |||
82 | /* TPS51632 chip information */ | ||
83 | struct tps51632_chip { | ||
84 | struct device *dev; | ||
85 | struct regulator_desc desc; | ||
86 | struct regulator_dev *rdev; | ||
87 | struct regmap *regmap; | ||
88 | bool enable_pwm_dvfs; | ||
89 | }; | ||
90 | |||
91 | static int tps51632_dcdc_get_voltage_sel(struct regulator_dev *rdev) | ||
92 | { | ||
93 | struct tps51632_chip *tps = rdev_get_drvdata(rdev); | ||
94 | unsigned int data; | ||
95 | int ret; | ||
96 | unsigned int reg = TPS51632_VOLTAGE_SELECT_REG; | ||
97 | int vsel; | ||
98 | |||
99 | if (tps->enable_pwm_dvfs) | ||
100 | reg = TPS51632_VOLTAGE_BASE_REG; | ||
101 | |||
102 | ret = regmap_read(tps->regmap, reg, &data); | ||
103 | if (ret < 0) { | ||
104 | dev_err(tps->dev, "reg read failed, err %d\n", ret); | ||
105 | return ret; | ||
106 | } | ||
107 | |||
108 | vsel = data & TPS51632_VOUT_MASK; | ||
109 | return vsel; | ||
110 | } | ||
111 | |||
112 | static int tps51632_dcdc_set_voltage_sel(struct regulator_dev *rdev, | ||
113 | unsigned selector) | ||
114 | { | ||
115 | struct tps51632_chip *tps = rdev_get_drvdata(rdev); | ||
116 | int ret; | ||
117 | unsigned int reg = TPS51632_VOLTAGE_SELECT_REG; | ||
118 | |||
119 | if (tps->enable_pwm_dvfs) | ||
120 | reg = TPS51632_VOLTAGE_BASE_REG; | ||
121 | |||
122 | if (selector > TPS51632_MAX_VSEL) | ||
123 | return -EINVAL; | ||
124 | |||
125 | ret = regmap_write(tps->regmap, reg, selector); | ||
126 | if (ret < 0) | ||
127 | dev_err(tps->dev, "reg write failed, err %d\n", ret); | ||
128 | return ret; | ||
129 | } | ||
130 | |||
131 | static int tps51632_dcdc_set_ramp_delay(struct regulator_dev *rdev, | ||
132 | int ramp_delay) | ||
133 | { | ||
134 | struct tps51632_chip *tps = rdev_get_drvdata(rdev); | ||
135 | int bit = ramp_delay/6000; | ||
136 | int ret; | ||
137 | |||
138 | if (bit) | ||
139 | bit--; | ||
140 | ret = regmap_write(tps->regmap, TPS51632_SLEW_REGS, BIT(bit)); | ||
141 | if (ret < 0) | ||
142 | dev_err(tps->dev, "SLEW reg write failed, err %d\n", ret); | ||
143 | return ret; | ||
144 | } | ||
145 | |||
146 | static struct regulator_ops tps51632_dcdc_ops = { | ||
147 | .get_voltage_sel = tps51632_dcdc_get_voltage_sel, | ||
148 | .set_voltage_sel = tps51632_dcdc_set_voltage_sel, | ||
149 | .list_voltage = regulator_list_voltage_linear, | ||
150 | .set_voltage_time_sel = regulator_set_voltage_time_sel, | ||
151 | .set_ramp_delay = tps51632_dcdc_set_ramp_delay, | ||
152 | }; | ||
153 | |||
154 | static int __devinit tps51632_init_dcdc(struct tps51632_chip *tps, | ||
155 | struct tps51632_regulator_platform_data *pdata) | ||
156 | { | ||
157 | int ret; | ||
158 | uint8_t control = 0; | ||
159 | int vsel; | ||
160 | |||
161 | if (!pdata->enable_pwm_dvfs) | ||
162 | goto skip_pwm_config; | ||
163 | |||
164 | control |= TPS51632_DVFS_PWMEN; | ||
165 | tps->enable_pwm_dvfs = pdata->enable_pwm_dvfs; | ||
166 | vsel = TPS51632_VOLT_VSEL(pdata->base_voltage_uV); | ||
167 | ret = regmap_write(tps->regmap, TPS51632_VOLTAGE_BASE_REG, vsel); | ||
168 | if (ret < 0) { | ||
169 | dev_err(tps->dev, "BASE reg write failed, err %d\n", ret); | ||
170 | return ret; | ||
171 | } | ||
172 | |||
173 | if (pdata->dvfs_step_20mV) | ||
174 | control |= TPS51632_DVFS_STEP_20; | ||
175 | |||
176 | if (pdata->max_voltage_uV) { | ||
177 | unsigned int vmax; | ||
178 | /** | ||
179 | * TPS51632 hw behavior: VMAX register can be write only | ||
180 | * once as it get locked after first write. The lock get | ||
181 | * reset only when device is power-reset. | ||
182 | * Write register only when lock bit is not enabled. | ||
183 | */ | ||
184 | ret = regmap_read(tps->regmap, TPS51632_VMAX_REG, &vmax); | ||
185 | if (ret < 0) { | ||
186 | dev_err(tps->dev, "VMAX read failed, err %d\n", ret); | ||
187 | return ret; | ||
188 | } | ||
189 | if (!(vmax & TPS51632_VMAX_LOCK)) { | ||
190 | vsel = TPS51632_VOLT_VSEL(pdata->max_voltage_uV); | ||
191 | ret = regmap_write(tps->regmap, TPS51632_VMAX_REG, | ||
192 | vsel); | ||
193 | if (ret < 0) { | ||
194 | dev_err(tps->dev, | ||
195 | "VMAX write failed, err %d\n", ret); | ||
196 | return ret; | ||
197 | } | ||
198 | } | ||
199 | } | ||
200 | |||
201 | skip_pwm_config: | ||
202 | ret = regmap_write(tps->regmap, TPS51632_DVFS_CONTROL_REG, control); | ||
203 | if (ret < 0) | ||
204 | dev_err(tps->dev, "DVFS reg write failed, err %d\n", ret); | ||
205 | return ret; | ||
206 | } | ||
207 | |||
208 | static bool rd_wr_reg(struct device *dev, unsigned int reg) | ||
209 | { | ||
210 | if ((reg >= 0x8) && (reg <= 0x10)) | ||
211 | return false; | ||
212 | return true; | ||
213 | } | ||
214 | |||
215 | static const struct regmap_config tps51632_regmap_config = { | ||
216 | .reg_bits = 8, | ||
217 | .val_bits = 8, | ||
218 | .writeable_reg = rd_wr_reg, | ||
219 | .readable_reg = rd_wr_reg, | ||
220 | .max_register = TPS51632_MAX_REG - 1, | ||
221 | .cache_type = REGCACHE_RBTREE, | ||
222 | }; | ||
223 | |||
224 | static int __devinit tps51632_probe(struct i2c_client *client, | ||
225 | const struct i2c_device_id *id) | ||
226 | { | ||
227 | struct tps51632_regulator_platform_data *pdata; | ||
228 | struct regulator_dev *rdev; | ||
229 | struct tps51632_chip *tps; | ||
230 | int ret; | ||
231 | struct regulator_config config = { }; | ||
232 | |||
233 | pdata = client->dev.platform_data; | ||
234 | if (!pdata) { | ||
235 | dev_err(&client->dev, "No Platform data\n"); | ||
236 | return -EINVAL; | ||
237 | } | ||
238 | |||
239 | tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL); | ||
240 | if (!tps) { | ||
241 | dev_err(&client->dev, "Memory allocation failed\n"); | ||
242 | return -ENOMEM; | ||
243 | } | ||
244 | |||
245 | tps->dev = &client->dev; | ||
246 | tps->desc.name = id->name; | ||
247 | tps->desc.id = 0; | ||
248 | tps->desc.ramp_delay = TPS51632_DEFAULT_RAMP_DELAY; | ||
249 | tps->desc.min_uV = TPS51632_MIN_VOLATGE; | ||
250 | tps->desc.uV_step = TPS51632_VOLATGE_STEP_10mV; | ||
251 | tps->desc.linear_min_sel = TPS51632_MIN_VSEL; | ||
252 | tps->desc.n_voltages = TPS51632_MAX_VSEL + 1; | ||
253 | tps->desc.ops = &tps51632_dcdc_ops; | ||
254 | tps->desc.type = REGULATOR_VOLTAGE; | ||
255 | tps->desc.owner = THIS_MODULE; | ||
256 | |||
257 | tps->regmap = devm_regmap_init_i2c(client, &tps51632_regmap_config); | ||
258 | if (IS_ERR(tps->regmap)) { | ||
259 | ret = PTR_ERR(tps->regmap); | ||
260 | dev_err(&client->dev, "regmap init failed, err %d\n", ret); | ||
261 | return ret; | ||
262 | } | ||
263 | i2c_set_clientdata(client, tps); | ||
264 | |||
265 | ret = tps51632_init_dcdc(tps, pdata); | ||
266 | if (ret < 0) { | ||
267 | dev_err(tps->dev, "Init failed, err = %d\n", ret); | ||
268 | return ret; | ||
269 | } | ||
270 | |||
271 | /* Register the regulators */ | ||
272 | config.dev = &client->dev; | ||
273 | config.init_data = pdata->reg_init_data; | ||
274 | config.driver_data = tps; | ||
275 | config.regmap = tps->regmap; | ||
276 | config.of_node = client->dev.of_node; | ||
277 | |||
278 | rdev = regulator_register(&tps->desc, &config); | ||
279 | if (IS_ERR(rdev)) { | ||
280 | dev_err(tps->dev, "regulator register failed\n"); | ||
281 | return PTR_ERR(rdev); | ||
282 | } | ||
283 | |||
284 | tps->rdev = rdev; | ||
285 | return 0; | ||
286 | } | ||
287 | |||
288 | static int __devexit tps51632_remove(struct i2c_client *client) | ||
289 | { | ||
290 | struct tps51632_chip *tps = i2c_get_clientdata(client); | ||
291 | |||
292 | regulator_unregister(tps->rdev); | ||
293 | return 0; | ||
294 | } | ||
295 | |||
296 | static const struct i2c_device_id tps51632_id[] = { | ||
297 | {.name = "tps51632",}, | ||
298 | {}, | ||
299 | }; | ||
300 | |||
301 | MODULE_DEVICE_TABLE(i2c, tps51632_id); | ||
302 | |||
303 | static struct i2c_driver tps51632_i2c_driver = { | ||
304 | .driver = { | ||
305 | .name = "tps51632", | ||
306 | .owner = THIS_MODULE, | ||
307 | }, | ||
308 | .probe = tps51632_probe, | ||
309 | .remove = __devexit_p(tps51632_remove), | ||
310 | .id_table = tps51632_id, | ||
311 | }; | ||
312 | |||
313 | static int __init tps51632_init(void) | ||
314 | { | ||
315 | return i2c_add_driver(&tps51632_i2c_driver); | ||
316 | } | ||
317 | subsys_initcall(tps51632_init); | ||
318 | |||
319 | static void __exit tps51632_cleanup(void) | ||
320 | { | ||
321 | i2c_del_driver(&tps51632_i2c_driver); | ||
322 | } | ||
323 | module_exit(tps51632_cleanup); | ||
324 | |||
325 | MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>"); | ||
326 | MODULE_DESCRIPTION("TPS51632 voltage regulator driver"); | ||
327 | MODULE_LICENSE("GPL v2"); | ||