diff options
author | Axel Lin <axel.lin@gmail.com> | 2012-07-03 22:20:46 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-07-04 07:38:36 -0400 |
commit | 4b7c948f558bf1d51aa25a6f621056c0acf45228 (patch) | |
tree | 9188c01497f2aff3f8c13d4269c47a85ad6007a2 /drivers/regulator | |
parent | a2a8222be8385818ade54554a50f7904ed0e506f (diff) |
regulator: gpio-regulator: Use core GPIO enable support
Signed-off-by: Axel Lin <axel.lin@gmail.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'drivers/regulator')
-rw-r--r-- | drivers/regulator/gpio-regulator.c | 103 |
1 files changed, 16 insertions, 87 deletions
diff --git a/drivers/regulator/gpio-regulator.c b/drivers/regulator/gpio-regulator.c index 3ed8d158833b..34b67bee9323 100644 --- a/drivers/regulator/gpio-regulator.c +++ b/drivers/regulator/gpio-regulator.c | |||
@@ -36,10 +36,6 @@ struct gpio_regulator_data { | |||
36 | struct regulator_desc desc; | 36 | struct regulator_desc desc; |
37 | struct regulator_dev *dev; | 37 | struct regulator_dev *dev; |
38 | 38 | ||
39 | int enable_gpio; | ||
40 | bool enable_high; | ||
41 | bool is_enabled; | ||
42 | |||
43 | struct gpio *gpios; | 39 | struct gpio *gpios; |
44 | int nr_gpios; | 40 | int nr_gpios; |
45 | 41 | ||
@@ -49,37 +45,6 @@ struct gpio_regulator_data { | |||
49 | int state; | 45 | int state; |
50 | }; | 46 | }; |
51 | 47 | ||
52 | static int gpio_regulator_is_enabled(struct regulator_dev *dev) | ||
53 | { | ||
54 | struct gpio_regulator_data *data = rdev_get_drvdata(dev); | ||
55 | |||
56 | return data->is_enabled; | ||
57 | } | ||
58 | |||
59 | static int gpio_regulator_enable(struct regulator_dev *dev) | ||
60 | { | ||
61 | struct gpio_regulator_data *data = rdev_get_drvdata(dev); | ||
62 | |||
63 | if (gpio_is_valid(data->enable_gpio)) { | ||
64 | gpio_set_value_cansleep(data->enable_gpio, data->enable_high); | ||
65 | data->is_enabled = true; | ||
66 | } | ||
67 | |||
68 | return 0; | ||
69 | } | ||
70 | |||
71 | static int gpio_regulator_disable(struct regulator_dev *dev) | ||
72 | { | ||
73 | struct gpio_regulator_data *data = rdev_get_drvdata(dev); | ||
74 | |||
75 | if (gpio_is_valid(data->enable_gpio)) { | ||
76 | gpio_set_value_cansleep(data->enable_gpio, !data->enable_high); | ||
77 | data->is_enabled = false; | ||
78 | } | ||
79 | |||
80 | return 0; | ||
81 | } | ||
82 | |||
83 | static int gpio_regulator_get_value(struct regulator_dev *dev) | 48 | static int gpio_regulator_get_value(struct regulator_dev *dev) |
84 | { | 49 | { |
85 | struct gpio_regulator_data *data = rdev_get_drvdata(dev); | 50 | struct gpio_regulator_data *data = rdev_get_drvdata(dev); |
@@ -145,18 +110,12 @@ static int gpio_regulator_set_current_limit(struct regulator_dev *dev, | |||
145 | } | 110 | } |
146 | 111 | ||
147 | static struct regulator_ops gpio_regulator_voltage_ops = { | 112 | static struct regulator_ops gpio_regulator_voltage_ops = { |
148 | .is_enabled = gpio_regulator_is_enabled, | ||
149 | .enable = gpio_regulator_enable, | ||
150 | .disable = gpio_regulator_disable, | ||
151 | .get_voltage = gpio_regulator_get_value, | 113 | .get_voltage = gpio_regulator_get_value, |
152 | .set_voltage = gpio_regulator_set_voltage, | 114 | .set_voltage = gpio_regulator_set_voltage, |
153 | .list_voltage = gpio_regulator_list_voltage, | 115 | .list_voltage = gpio_regulator_list_voltage, |
154 | }; | 116 | }; |
155 | 117 | ||
156 | static struct regulator_ops gpio_regulator_current_ops = { | 118 | static struct regulator_ops gpio_regulator_current_ops = { |
157 | .is_enabled = gpio_regulator_is_enabled, | ||
158 | .enable = gpio_regulator_enable, | ||
159 | .disable = gpio_regulator_disable, | ||
160 | .get_current_limit = gpio_regulator_get_value, | 119 | .get_current_limit = gpio_regulator_get_value, |
161 | .set_current_limit = gpio_regulator_set_current_limit, | 120 | .set_current_limit = gpio_regulator_set_current_limit, |
162 | }; | 121 | }; |
@@ -223,51 +182,12 @@ static int __devinit gpio_regulator_probe(struct platform_device *pdev) | |||
223 | break; | 182 | break; |
224 | } | 183 | } |
225 | 184 | ||
226 | drvdata->enable_gpio = config->enable_gpio; | ||
227 | |||
228 | if (gpio_is_valid(config->enable_gpio)) { | ||
229 | drvdata->enable_high = config->enable_high; | ||
230 | |||
231 | ret = gpio_request(config->enable_gpio, config->supply_name); | ||
232 | if (ret) { | ||
233 | dev_err(&pdev->dev, | ||
234 | "Could not obtain regulator enable GPIO %d: %d\n", | ||
235 | config->enable_gpio, ret); | ||
236 | goto err_memstate; | ||
237 | } | ||
238 | |||
239 | /* set output direction without changing state | ||
240 | * to prevent glitch | ||
241 | */ | ||
242 | if (config->enabled_at_boot) { | ||
243 | drvdata->is_enabled = true; | ||
244 | ret = gpio_direction_output(config->enable_gpio, | ||
245 | config->enable_high); | ||
246 | } else { | ||
247 | drvdata->is_enabled = false; | ||
248 | ret = gpio_direction_output(config->enable_gpio, | ||
249 | !config->enable_high); | ||
250 | } | ||
251 | |||
252 | if (ret) { | ||
253 | dev_err(&pdev->dev, | ||
254 | "Could not configure regulator enable GPIO %d direction: %d\n", | ||
255 | config->enable_gpio, ret); | ||
256 | goto err_enablegpio; | ||
257 | } | ||
258 | } else { | ||
259 | /* Regulator without GPIO control is considered | ||
260 | * always enabled | ||
261 | */ | ||
262 | drvdata->is_enabled = true; | ||
263 | } | ||
264 | |||
265 | drvdata->nr_gpios = config->nr_gpios; | 185 | drvdata->nr_gpios = config->nr_gpios; |
266 | ret = gpio_request_array(drvdata->gpios, drvdata->nr_gpios); | 186 | ret = gpio_request_array(drvdata->gpios, drvdata->nr_gpios); |
267 | if (ret) { | 187 | if (ret) { |
268 | dev_err(&pdev->dev, | 188 | dev_err(&pdev->dev, |
269 | "Could not obtain regulator setting GPIOs: %d\n", ret); | 189 | "Could not obtain regulator setting GPIOs: %d\n", ret); |
270 | goto err_enablegpio; | 190 | goto err_memstate; |
271 | } | 191 | } |
272 | 192 | ||
273 | /* build initial state from gpio init data. */ | 193 | /* build initial state from gpio init data. */ |
@@ -282,6 +202,21 @@ static int __devinit gpio_regulator_probe(struct platform_device *pdev) | |||
282 | cfg.init_data = config->init_data; | 202 | cfg.init_data = config->init_data; |
283 | cfg.driver_data = drvdata; | 203 | cfg.driver_data = drvdata; |
284 | 204 | ||
205 | if (config->enable_gpio >= 0) | ||
206 | cfg.ena_gpio = config->enable_gpio; | ||
207 | cfg.ena_gpio_invert = !config->enable_high; | ||
208 | if (config->enabled_at_boot) { | ||
209 | if (config->enable_high) | ||
210 | cfg.ena_gpio_flags |= GPIOF_OUT_INIT_HIGH; | ||
211 | else | ||
212 | cfg.ena_gpio_flags |= GPIOF_OUT_INIT_LOW; | ||
213 | } else { | ||
214 | if (config->enable_high) | ||
215 | cfg.ena_gpio_flags |= GPIOF_OUT_INIT_LOW; | ||
216 | else | ||
217 | cfg.ena_gpio_flags |= GPIOF_OUT_INIT_HIGH; | ||
218 | } | ||
219 | |||
285 | drvdata->dev = regulator_register(&drvdata->desc, &cfg); | 220 | drvdata->dev = regulator_register(&drvdata->desc, &cfg); |
286 | if (IS_ERR(drvdata->dev)) { | 221 | if (IS_ERR(drvdata->dev)) { |
287 | ret = PTR_ERR(drvdata->dev); | 222 | ret = PTR_ERR(drvdata->dev); |
@@ -295,9 +230,6 @@ static int __devinit gpio_regulator_probe(struct platform_device *pdev) | |||
295 | 230 | ||
296 | err_stategpio: | 231 | err_stategpio: |
297 | gpio_free_array(drvdata->gpios, drvdata->nr_gpios); | 232 | gpio_free_array(drvdata->gpios, drvdata->nr_gpios); |
298 | err_enablegpio: | ||
299 | if (gpio_is_valid(config->enable_gpio)) | ||
300 | gpio_free(config->enable_gpio); | ||
301 | err_memstate: | 233 | err_memstate: |
302 | kfree(drvdata->states); | 234 | kfree(drvdata->states); |
303 | err_memgpio: | 235 | err_memgpio: |
@@ -319,9 +251,6 @@ static int __devexit gpio_regulator_remove(struct platform_device *pdev) | |||
319 | kfree(drvdata->states); | 251 | kfree(drvdata->states); |
320 | kfree(drvdata->gpios); | 252 | kfree(drvdata->gpios); |
321 | 253 | ||
322 | if (gpio_is_valid(drvdata->enable_gpio)) | ||
323 | gpio_free(drvdata->enable_gpio); | ||
324 | |||
325 | kfree(drvdata->desc.name); | 254 | kfree(drvdata->desc.name); |
326 | 255 | ||
327 | return 0; | 256 | return 0; |