aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarek Belisko <marek@goldelico.com>2015-03-10 17:27:22 -0400
committerSebastian Reichel <sre@kernel.org>2015-04-06 13:18:43 -0400
commit7e5e43893d24b44507f8239a07064596401820d8 (patch)
tree2f3ce1b8bfd0ad679a6489c1b8fa2d043ec50ae3
parent0db739fa06f95a040313c4479e1940caeb48e92f (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.c96
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
23struct twl4030_madc_battery { 24struct 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
28static enum power_supply_property twl4030_madc_bat_props[] = { 32static 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
41static int madc_read(int index) 45static 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
60static int twl4030_madc_bat_get_charging_status(void) 55static 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
65static int twl4030_madc_bat_get_voltage(void) 60static 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
70static int twl4030_madc_bat_get_current(void) 65static 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
75static int twl4030_madc_bat_get_temp(void) 70static 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
80static int twl4030_madc_bat_voltscale(struct twl4030_madc_battery *bat, 75static 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
243err_vbat:
244 iio_channel_release(twl4030_madc_bat->channel_vbat);
245err_ichg:
246 iio_channel_release(twl4030_madc_bat->channel_ichg);
247err_temp:
248 iio_channel_release(twl4030_madc_bat->channel_temp);
249err:
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}