diff options
author | Marek Belisko <marek@goldelico.com> | 2015-03-10 17:27:22 -0400 |
---|---|---|
committer | Sebastian Reichel <sre@kernel.org> | 2015-04-06 13:18:43 -0400 |
commit | 7e5e43893d24b44507f8239a07064596401820d8 (patch) | |
tree | 2f3ce1b8bfd0ad679a6489c1b8fa2d043ec50ae3 | |
parent | 0db739fa06f95a040313c4479e1940caeb48e92f (diff) |
power: twl4030-madc-battery: Convert to iio consumer.
Because of added iio error handling private data allocation was converted
to managed to simplify code.
Signed-off-by: Marek Belisko <marek@goldelico.com>
Reviewed-By: Sebastian Reichel <sre@debian.org>
Signed-off-by: Sebastian Reichel <sre@kernel.org>
-rw-r--r-- | drivers/power/twl4030_madc_battery.c | 96 |
1 files changed, 61 insertions, 35 deletions
diff --git a/drivers/power/twl4030_madc_battery.c b/drivers/power/twl4030_madc_battery.c index 36d3a0e229fa..f4b9257d795c 100644 --- a/drivers/power/twl4030_madc_battery.c +++ b/drivers/power/twl4030_madc_battery.c | |||
@@ -19,10 +19,14 @@ | |||
19 | #include <linux/sort.h> | 19 | #include <linux/sort.h> |
20 | #include <linux/i2c/twl4030-madc.h> | 20 | #include <linux/i2c/twl4030-madc.h> |
21 | #include <linux/power/twl4030_madc_battery.h> | 21 | #include <linux/power/twl4030_madc_battery.h> |
22 | #include <linux/iio/consumer.h> | ||
22 | 23 | ||
23 | struct twl4030_madc_battery { | 24 | struct twl4030_madc_battery { |
24 | struct power_supply *psy; | 25 | struct power_supply *psy; |
25 | struct twl4030_madc_bat_platform_data *pdata; | 26 | struct twl4030_madc_bat_platform_data *pdata; |
27 | struct iio_channel *channel_temp; | ||
28 | struct iio_channel *channel_ichg; | ||
29 | struct iio_channel *channel_vbat; | ||
26 | }; | 30 | }; |
27 | 31 | ||
28 | static enum power_supply_property twl4030_madc_bat_props[] = { | 32 | static enum power_supply_property twl4030_madc_bat_props[] = { |
@@ -38,43 +42,34 @@ static enum power_supply_property twl4030_madc_bat_props[] = { | |||
38 | POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW, | 42 | POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW, |
39 | }; | 43 | }; |
40 | 44 | ||
41 | static int madc_read(int index) | 45 | static int madc_read(struct iio_channel *channel) |
42 | { | 46 | { |
43 | struct twl4030_madc_request req; | 47 | int val, err; |
44 | int val; | 48 | err = iio_read_channel_processed(channel, &val); |
49 | if (err < 0) | ||
50 | return err; | ||
45 | 51 | ||
46 | req.channels = index; | 52 | return val; |
47 | req.method = TWL4030_MADC_SW2; | ||
48 | req.type = TWL4030_MADC_WAIT; | ||
49 | req.do_avg = 0; | ||
50 | req.raw = false; | ||
51 | req.func_cb = NULL; | ||
52 | |||
53 | val = twl4030_madc_conversion(&req); | ||
54 | if (val < 0) | ||
55 | return val; | ||
56 | |||
57 | return req.rbuf[ffs(index) - 1]; | ||
58 | } | 53 | } |
59 | 54 | ||
60 | static int twl4030_madc_bat_get_charging_status(void) | 55 | static int twl4030_madc_bat_get_charging_status(struct twl4030_madc_battery *bt) |
61 | { | 56 | { |
62 | return (madc_read(TWL4030_MADC_ICHG) > 0) ? 1 : 0; | 57 | return (madc_read(bt->channel_ichg) > 0) ? 1 : 0; |
63 | } | 58 | } |
64 | 59 | ||
65 | static int twl4030_madc_bat_get_voltage(void) | 60 | static int twl4030_madc_bat_get_voltage(struct twl4030_madc_battery *bt) |
66 | { | 61 | { |
67 | return madc_read(TWL4030_MADC_VBAT); | 62 | return madc_read(bt->channel_vbat); |
68 | } | 63 | } |
69 | 64 | ||
70 | static int twl4030_madc_bat_get_current(void) | 65 | static int twl4030_madc_bat_get_current(struct twl4030_madc_battery *bt) |
71 | { | 66 | { |
72 | return madc_read(TWL4030_MADC_ICHG) * 1000; | 67 | return madc_read(bt->channel_ichg) * 1000; |
73 | } | 68 | } |
74 | 69 | ||
75 | static int twl4030_madc_bat_get_temp(void) | 70 | static int twl4030_madc_bat_get_temp(struct twl4030_madc_battery *bt) |
76 | { | 71 | { |
77 | return madc_read(TWL4030_MADC_BTEMP) * 10; | 72 | return madc_read(bt->channel_temp) * 10; |
78 | } | 73 | } |
79 | 74 | ||
80 | static int twl4030_madc_bat_voltscale(struct twl4030_madc_battery *bat, | 75 | static int twl4030_madc_bat_voltscale(struct twl4030_madc_battery *bat, |
@@ -84,7 +79,7 @@ static int twl4030_madc_bat_voltscale(struct twl4030_madc_battery *bat, | |||
84 | int i, res = 0; | 79 | int i, res = 0; |
85 | 80 | ||
86 | /* choose charging curve */ | 81 | /* choose charging curve */ |
87 | if (twl4030_madc_bat_get_charging_status()) | 82 | if (twl4030_madc_bat_get_charging_status(bat)) |
88 | calibration = bat->pdata->charging; | 83 | calibration = bat->pdata->charging; |
89 | else | 84 | else |
90 | calibration = bat->pdata->discharging; | 85 | calibration = bat->pdata->discharging; |
@@ -118,23 +113,23 @@ static int twl4030_madc_bat_get_property(struct power_supply *psy, | |||
118 | switch (psp) { | 113 | switch (psp) { |
119 | case POWER_SUPPLY_PROP_STATUS: | 114 | case POWER_SUPPLY_PROP_STATUS: |
120 | if (twl4030_madc_bat_voltscale(bat, | 115 | if (twl4030_madc_bat_voltscale(bat, |
121 | twl4030_madc_bat_get_voltage()) > 95) | 116 | twl4030_madc_bat_get_voltage(bat)) > 95) |
122 | val->intval = POWER_SUPPLY_STATUS_FULL; | 117 | val->intval = POWER_SUPPLY_STATUS_FULL; |
123 | else { | 118 | else { |
124 | if (twl4030_madc_bat_get_charging_status()) | 119 | if (twl4030_madc_bat_get_charging_status(bat)) |
125 | val->intval = POWER_SUPPLY_STATUS_CHARGING; | 120 | val->intval = POWER_SUPPLY_STATUS_CHARGING; |
126 | else | 121 | else |
127 | val->intval = POWER_SUPPLY_STATUS_DISCHARGING; | 122 | val->intval = POWER_SUPPLY_STATUS_DISCHARGING; |
128 | } | 123 | } |
129 | break; | 124 | break; |
130 | case POWER_SUPPLY_PROP_VOLTAGE_NOW: | 125 | case POWER_SUPPLY_PROP_VOLTAGE_NOW: |
131 | val->intval = twl4030_madc_bat_get_voltage() * 1000; | 126 | val->intval = twl4030_madc_bat_get_voltage(bat) * 1000; |
132 | break; | 127 | break; |
133 | case POWER_SUPPLY_PROP_TECHNOLOGY: | 128 | case POWER_SUPPLY_PROP_TECHNOLOGY: |
134 | val->intval = POWER_SUPPLY_TECHNOLOGY_LION; | 129 | val->intval = POWER_SUPPLY_TECHNOLOGY_LION; |
135 | break; | 130 | break; |
136 | case POWER_SUPPLY_PROP_CURRENT_NOW: | 131 | case POWER_SUPPLY_PROP_CURRENT_NOW: |
137 | val->intval = twl4030_madc_bat_get_current(); | 132 | val->intval = twl4030_madc_bat_get_current(bat); |
138 | break; | 133 | break; |
139 | case POWER_SUPPLY_PROP_PRESENT: | 134 | case POWER_SUPPLY_PROP_PRESENT: |
140 | /* assume battery is always present */ | 135 | /* assume battery is always present */ |
@@ -142,23 +137,23 @@ static int twl4030_madc_bat_get_property(struct power_supply *psy, | |||
142 | break; | 137 | break; |
143 | case POWER_SUPPLY_PROP_CHARGE_NOW: { | 138 | case POWER_SUPPLY_PROP_CHARGE_NOW: { |
144 | int percent = twl4030_madc_bat_voltscale(bat, | 139 | int percent = twl4030_madc_bat_voltscale(bat, |
145 | twl4030_madc_bat_get_voltage()); | 140 | twl4030_madc_bat_get_voltage(bat)); |
146 | val->intval = (percent * bat->pdata->capacity) / 100; | 141 | val->intval = (percent * bat->pdata->capacity) / 100; |
147 | break; | 142 | break; |
148 | } | 143 | } |
149 | case POWER_SUPPLY_PROP_CAPACITY: | 144 | case POWER_SUPPLY_PROP_CAPACITY: |
150 | val->intval = twl4030_madc_bat_voltscale(bat, | 145 | val->intval = twl4030_madc_bat_voltscale(bat, |
151 | twl4030_madc_bat_get_voltage()); | 146 | twl4030_madc_bat_get_voltage(bat)); |
152 | break; | 147 | break; |
153 | case POWER_SUPPLY_PROP_CHARGE_FULL: | 148 | case POWER_SUPPLY_PROP_CHARGE_FULL: |
154 | val->intval = bat->pdata->capacity; | 149 | val->intval = bat->pdata->capacity; |
155 | break; | 150 | break; |
156 | case POWER_SUPPLY_PROP_TEMP: | 151 | case POWER_SUPPLY_PROP_TEMP: |
157 | val->intval = twl4030_madc_bat_get_temp(); | 152 | val->intval = twl4030_madc_bat_get_temp(bat); |
158 | break; | 153 | break; |
159 | case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW: { | 154 | case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW: { |
160 | int percent = twl4030_madc_bat_voltscale(bat, | 155 | int percent = twl4030_madc_bat_voltscale(bat, |
161 | twl4030_madc_bat_get_voltage()); | 156 | twl4030_madc_bat_get_voltage(bat)); |
162 | /* in mAh */ | 157 | /* in mAh */ |
163 | int chg = (percent * (bat->pdata->capacity/1000))/100; | 158 | int chg = (percent * (bat->pdata->capacity/1000))/100; |
164 | 159 | ||
@@ -201,10 +196,29 @@ static int twl4030_madc_battery_probe(struct platform_device *pdev) | |||
201 | struct power_supply_config psy_cfg = {}; | 196 | struct power_supply_config psy_cfg = {}; |
202 | int ret = 0; | 197 | int ret = 0; |
203 | 198 | ||
204 | twl4030_madc_bat = kzalloc(sizeof(*twl4030_madc_bat), GFP_KERNEL); | 199 | twl4030_madc_bat = devm_kzalloc(&pdev->dev, sizeof(*twl4030_madc_bat), |
200 | GFP_KERNEL); | ||
205 | if (!twl4030_madc_bat) | 201 | if (!twl4030_madc_bat) |
206 | return -ENOMEM; | 202 | return -ENOMEM; |
207 | 203 | ||
204 | twl4030_madc_bat->channel_temp = iio_channel_get(&pdev->dev, "temp"); | ||
205 | if (IS_ERR(twl4030_madc_bat->channel_temp)) { | ||
206 | ret = PTR_ERR(twl4030_madc_bat->channel_temp); | ||
207 | goto err; | ||
208 | } | ||
209 | |||
210 | twl4030_madc_bat->channel_ichg = iio_channel_get(&pdev->dev, "ichg"); | ||
211 | if (IS_ERR(twl4030_madc_bat->channel_ichg)) { | ||
212 | ret = PTR_ERR(twl4030_madc_bat->channel_ichg); | ||
213 | goto err_temp; | ||
214 | } | ||
215 | |||
216 | twl4030_madc_bat->channel_vbat = iio_channel_get(&pdev->dev, "vbat"); | ||
217 | if (IS_ERR(twl4030_madc_bat->channel_vbat)) { | ||
218 | ret = PTR_ERR(twl4030_madc_bat->channel_vbat); | ||
219 | goto err_ichg; | ||
220 | } | ||
221 | |||
208 | /* sort charging and discharging calibration data */ | 222 | /* sort charging and discharging calibration data */ |
209 | sort(pdata->charging, pdata->charging_size, | 223 | sort(pdata->charging, pdata->charging_size, |
210 | sizeof(struct twl4030_madc_bat_calibration), | 224 | sizeof(struct twl4030_madc_bat_calibration), |
@@ -221,9 +235,18 @@ static int twl4030_madc_battery_probe(struct platform_device *pdev) | |||
221 | &psy_cfg); | 235 | &psy_cfg); |
222 | if (IS_ERR(twl4030_madc_bat->psy)) { | 236 | if (IS_ERR(twl4030_madc_bat->psy)) { |
223 | ret = PTR_ERR(twl4030_madc_bat->psy); | 237 | ret = PTR_ERR(twl4030_madc_bat->psy); |
224 | kfree(twl4030_madc_bat); | 238 | goto err_vbat; |
225 | } | 239 | } |
226 | 240 | ||
241 | return 0; | ||
242 | |||
243 | err_vbat: | ||
244 | iio_channel_release(twl4030_madc_bat->channel_vbat); | ||
245 | err_ichg: | ||
246 | iio_channel_release(twl4030_madc_bat->channel_ichg); | ||
247 | err_temp: | ||
248 | iio_channel_release(twl4030_madc_bat->channel_temp); | ||
249 | err: | ||
227 | return ret; | 250 | return ret; |
228 | } | 251 | } |
229 | 252 | ||
@@ -232,7 +255,10 @@ static int twl4030_madc_battery_remove(struct platform_device *pdev) | |||
232 | struct twl4030_madc_battery *bat = platform_get_drvdata(pdev); | 255 | struct twl4030_madc_battery *bat = platform_get_drvdata(pdev); |
233 | 256 | ||
234 | power_supply_unregister(bat->psy); | 257 | power_supply_unregister(bat->psy); |
235 | kfree(bat); | 258 | |
259 | iio_channel_release(bat->channel_vbat); | ||
260 | iio_channel_release(bat->channel_ichg); | ||
261 | iio_channel_release(bat->channel_temp); | ||
236 | 262 | ||
237 | return 0; | 263 | return 0; |
238 | } | 264 | } |