diff options
author | Sebastian Reichel <sre@kernel.org> | 2014-03-01 15:22:44 -0500 |
---|---|---|
committer | Sebastian Reichel <sre@kernel.org> | 2014-07-18 17:40:22 -0400 |
commit | 57da5e86e6f4101c0fc629a63d870508348e2a84 (patch) | |
tree | 720a8b56f005a951e8462754b94dde66f6b25108 | |
parent | 3c0185046c0ee49a6e55c714612ef3bcd5385df3 (diff) |
rx51_battery: convert to iio consumer
Update rx51-battery driver to use the new IIO API of
twl4030-madc and add DT support.
Signed-off-by: Sebastian Reichel <sre@kernel.org>
-rw-r--r-- | drivers/power/rx51_battery.c | 90 |
1 files changed, 66 insertions, 24 deletions
diff --git a/drivers/power/rx51_battery.c b/drivers/power/rx51_battery.c index 1bc5857b8bd5..d5a2acfb8821 100644 --- a/drivers/power/rx51_battery.c +++ b/drivers/power/rx51_battery.c | |||
@@ -24,34 +24,27 @@ | |||
24 | #include <linux/power_supply.h> | 24 | #include <linux/power_supply.h> |
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | #include <linux/i2c/twl4030-madc.h> | 26 | #include <linux/i2c/twl4030-madc.h> |
27 | 27 | #include <linux/iio/consumer.h> | |
28 | /* RX51 specific channels */ | 28 | #include <linux/of.h> |
29 | #define TWL4030_MADC_BTEMP_RX51 TWL4030_MADC_ADCIN0 | ||
30 | #define TWL4030_MADC_BCI_RX51 TWL4030_MADC_ADCIN4 | ||
31 | 29 | ||
32 | struct rx51_device_info { | 30 | struct rx51_device_info { |
33 | struct device *dev; | 31 | struct device *dev; |
34 | struct power_supply bat; | 32 | struct power_supply bat; |
33 | struct iio_channel *channel_temp; | ||
34 | struct iio_channel *channel_bsi; | ||
35 | struct iio_channel *channel_vbat; | ||
35 | }; | 36 | }; |
36 | 37 | ||
37 | /* | 38 | /* |
38 | * Read ADCIN channel value, code copied from maemo kernel | 39 | * Read ADCIN channel value, code copied from maemo kernel |
39 | */ | 40 | */ |
40 | static int rx51_battery_read_adc(int channel) | 41 | static int rx51_battery_read_adc(struct iio_channel *channel) |
41 | { | 42 | { |
42 | struct twl4030_madc_request req; | 43 | int val, err; |
43 | 44 | err = iio_read_channel_average_raw(channel, &val); | |
44 | req.channels = channel; | 45 | if (err < 0) |
45 | req.do_avg = 1; | 46 | return err; |
46 | req.method = TWL4030_MADC_SW1; | 47 | return val; |
47 | req.func_cb = NULL; | ||
48 | req.type = TWL4030_MADC_WAIT; | ||
49 | req.raw = true; | ||
50 | |||
51 | if (twl4030_madc_conversion(&req) <= 0) | ||
52 | return -ENODATA; | ||
53 | |||
54 | return req.rbuf[ffs(channel) - 1]; | ||
55 | } | 48 | } |
56 | 49 | ||
57 | /* | 50 | /* |
@@ -60,10 +53,12 @@ static int rx51_battery_read_adc(int channel) | |||
60 | */ | 53 | */ |
61 | static int rx51_battery_read_voltage(struct rx51_device_info *di) | 54 | static int rx51_battery_read_voltage(struct rx51_device_info *di) |
62 | { | 55 | { |
63 | int voltage = rx51_battery_read_adc(TWL4030_MADC_VBAT); | 56 | int voltage = rx51_battery_read_adc(di->channel_vbat); |
64 | 57 | ||
65 | if (voltage < 0) | 58 | if (voltage < 0) { |
59 | dev_err(di->dev, "Could not read ADC: %d\n", voltage); | ||
66 | return voltage; | 60 | return voltage; |
61 | } | ||
67 | 62 | ||
68 | return 1000 * (10000 * voltage / 1705); | 63 | return 1000 * (10000 * voltage / 1705); |
69 | } | 64 | } |
@@ -112,7 +107,10 @@ static int rx51_battery_read_temperature(struct rx51_device_info *di) | |||
112 | { | 107 | { |
113 | int min = 0; | 108 | int min = 0; |
114 | int max = ARRAY_SIZE(rx51_temp_table2) - 1; | 109 | int max = ARRAY_SIZE(rx51_temp_table2) - 1; |
115 | int raw = rx51_battery_read_adc(TWL4030_MADC_BTEMP_RX51); | 110 | int raw = rx51_battery_read_adc(di->channel_temp); |
111 | |||
112 | if (raw < 0) | ||
113 | dev_err(di->dev, "Could not read ADC: %d\n", raw); | ||
116 | 114 | ||
117 | /* Zero and negative values are undefined */ | 115 | /* Zero and negative values are undefined */ |
118 | if (raw <= 0) | 116 | if (raw <= 0) |
@@ -146,10 +144,12 @@ static int rx51_battery_read_temperature(struct rx51_device_info *di) | |||
146 | */ | 144 | */ |
147 | static int rx51_battery_read_capacity(struct rx51_device_info *di) | 145 | static int rx51_battery_read_capacity(struct rx51_device_info *di) |
148 | { | 146 | { |
149 | int capacity = rx51_battery_read_adc(TWL4030_MADC_BCI_RX51); | 147 | int capacity = rx51_battery_read_adc(di->channel_bsi); |
150 | 148 | ||
151 | if (capacity < 0) | 149 | if (capacity < 0) { |
150 | dev_err(di->dev, "Could not read ADC: %d\n", capacity); | ||
152 | return capacity; | 151 | return capacity; |
152 | } | ||
153 | 153 | ||
154 | return 1280 * (1200 * capacity)/(1024 - capacity); | 154 | return 1280 * (1200 * capacity)/(1024 - capacity); |
155 | } | 155 | } |
@@ -213,17 +213,46 @@ static int rx51_battery_probe(struct platform_device *pdev) | |||
213 | 213 | ||
214 | platform_set_drvdata(pdev, di); | 214 | platform_set_drvdata(pdev, di); |
215 | 215 | ||
216 | di->dev = &pdev->dev; | ||
216 | di->bat.name = dev_name(&pdev->dev); | 217 | di->bat.name = dev_name(&pdev->dev); |
217 | di->bat.type = POWER_SUPPLY_TYPE_BATTERY; | 218 | di->bat.type = POWER_SUPPLY_TYPE_BATTERY; |
218 | di->bat.properties = rx51_battery_props; | 219 | di->bat.properties = rx51_battery_props; |
219 | di->bat.num_properties = ARRAY_SIZE(rx51_battery_props); | 220 | di->bat.num_properties = ARRAY_SIZE(rx51_battery_props); |
220 | di->bat.get_property = rx51_battery_get_property; | 221 | di->bat.get_property = rx51_battery_get_property; |
221 | 222 | ||
223 | di->channel_temp = iio_channel_get(di->dev, "temp"); | ||
224 | if (IS_ERR(di->channel_temp)) { | ||
225 | ret = PTR_ERR(di->channel_temp); | ||
226 | goto error; | ||
227 | } | ||
228 | |||
229 | di->channel_bsi = iio_channel_get(di->dev, "bsi"); | ||
230 | if (IS_ERR(di->channel_bsi)) { | ||
231 | ret = PTR_ERR(di->channel_bsi); | ||
232 | goto error_channel_temp; | ||
233 | } | ||
234 | |||
235 | di->channel_vbat = iio_channel_get(di->dev, "vbat"); | ||
236 | if (IS_ERR(di->channel_vbat)) { | ||
237 | ret = PTR_ERR(di->channel_vbat); | ||
238 | goto error_channel_bsi; | ||
239 | } | ||
240 | |||
222 | ret = power_supply_register(di->dev, &di->bat); | 241 | ret = power_supply_register(di->dev, &di->bat); |
223 | if (ret) | 242 | if (ret) |
224 | return ret; | 243 | goto error_channel_vbat; |
225 | 244 | ||
226 | return 0; | 245 | return 0; |
246 | |||
247 | error_channel_vbat: | ||
248 | iio_channel_release(di->channel_vbat); | ||
249 | error_channel_bsi: | ||
250 | iio_channel_release(di->channel_bsi); | ||
251 | error_channel_temp: | ||
252 | iio_channel_release(di->channel_temp); | ||
253 | error: | ||
254 | |||
255 | return ret; | ||
227 | } | 256 | } |
228 | 257 | ||
229 | static int rx51_battery_remove(struct platform_device *pdev) | 258 | static int rx51_battery_remove(struct platform_device *pdev) |
@@ -232,15 +261,28 @@ static int rx51_battery_remove(struct platform_device *pdev) | |||
232 | 261 | ||
233 | power_supply_unregister(&di->bat); | 262 | power_supply_unregister(&di->bat); |
234 | 263 | ||
264 | iio_channel_release(di->channel_vbat); | ||
265 | iio_channel_release(di->channel_bsi); | ||
266 | iio_channel_release(di->channel_temp); | ||
267 | |||
235 | return 0; | 268 | return 0; |
236 | } | 269 | } |
237 | 270 | ||
271 | #ifdef CONFIG_OF | ||
272 | static const struct of_device_id n900_battery_of_match[] = { | ||
273 | {.compatible = "nokia,n900-battery", }, | ||
274 | { }, | ||
275 | }; | ||
276 | MODULE_DEVICE_TABLE(of, n900_battery_of_match); | ||
277 | #endif | ||
278 | |||
238 | static struct platform_driver rx51_battery_driver = { | 279 | static struct platform_driver rx51_battery_driver = { |
239 | .probe = rx51_battery_probe, | 280 | .probe = rx51_battery_probe, |
240 | .remove = rx51_battery_remove, | 281 | .remove = rx51_battery_remove, |
241 | .driver = { | 282 | .driver = { |
242 | .name = "rx51-battery", | 283 | .name = "rx51-battery", |
243 | .owner = THIS_MODULE, | 284 | .owner = THIS_MODULE, |
285 | .of_match_table = of_match_ptr(n900_battery_of_match), | ||
244 | }, | 286 | }, |
245 | }; | 287 | }; |
246 | module_platform_driver(rx51_battery_driver); | 288 | module_platform_driver(rx51_battery_driver); |