diff options
-rw-r--r-- | drivers/power/ds2760_battery.c | 41 |
1 files changed, 27 insertions, 14 deletions
diff --git a/drivers/power/ds2760_battery.c b/drivers/power/ds2760_battery.c index 2d0e5edb4742..f4a9258aa9d0 100644 --- a/drivers/power/ds2760_battery.c +++ b/drivers/power/ds2760_battery.c | |||
@@ -70,6 +70,10 @@ static unsigned int rated_capacity; | |||
70 | module_param(rated_capacity, uint, 0644); | 70 | module_param(rated_capacity, uint, 0644); |
71 | MODULE_PARM_DESC(rated_capacity, "rated battery capacity, 10*mAh or index"); | 71 | MODULE_PARM_DESC(rated_capacity, "rated battery capacity, 10*mAh or index"); |
72 | 72 | ||
73 | static unsigned int current_accum; | ||
74 | module_param(current_accum, uint, 0644); | ||
75 | MODULE_PARM_DESC(current_accum, "current accumulator value"); | ||
76 | |||
73 | /* Some batteries have their rated capacity stored a N * 10 mAh, while | 77 | /* Some batteries have their rated capacity stored a N * 10 mAh, while |
74 | * others use an index into this table. */ | 78 | * others use an index into this table. */ |
75 | static int rated_capacities[] = { | 79 | static int rated_capacities[] = { |
@@ -215,6 +219,22 @@ static int ds2760_battery_read_status(struct ds2760_device_info *di) | |||
215 | return 0; | 219 | return 0; |
216 | } | 220 | } |
217 | 221 | ||
222 | static void ds2760_battery_set_current_accum(struct ds2760_device_info *di, | ||
223 | unsigned int acr_val) | ||
224 | { | ||
225 | unsigned char acr[2]; | ||
226 | |||
227 | /* acr is in units of 0.25 mAh */ | ||
228 | acr_val *= 4L; | ||
229 | acr_val /= 1000; | ||
230 | |||
231 | acr[0] = acr_val >> 8; | ||
232 | acr[1] = acr_val & 0xff; | ||
233 | |||
234 | if (w1_ds2760_write(di->w1_dev, acr, DS2760_CURRENT_ACCUM_MSB, 2) < 2) | ||
235 | dev_warn(di->dev, "ACR write failed\n"); | ||
236 | } | ||
237 | |||
218 | static void ds2760_battery_update_status(struct ds2760_device_info *di) | 238 | static void ds2760_battery_update_status(struct ds2760_device_info *di) |
219 | { | 239 | { |
220 | int old_charge_status = di->charge_status; | 240 | int old_charge_status = di->charge_status; |
@@ -246,21 +266,9 @@ static void ds2760_battery_update_status(struct ds2760_device_info *di) | |||
246 | if (di->full_counter < 2) { | 266 | if (di->full_counter < 2) { |
247 | di->charge_status = POWER_SUPPLY_STATUS_CHARGING; | 267 | di->charge_status = POWER_SUPPLY_STATUS_CHARGING; |
248 | } else { | 268 | } else { |
249 | unsigned char acr[2]; | ||
250 | int acr_val; | ||
251 | |||
252 | /* acr is in units of 0.25 mAh */ | ||
253 | acr_val = di->full_active_uAh * 4L / 1000; | ||
254 | |||
255 | acr[0] = acr_val >> 8; | ||
256 | acr[1] = acr_val & 0xff; | ||
257 | |||
258 | if (w1_ds2760_write(di->w1_dev, acr, | ||
259 | DS2760_CURRENT_ACCUM_MSB, 2) < 2) | ||
260 | dev_warn(di->dev, | ||
261 | "ACR reset failed\n"); | ||
262 | |||
263 | di->charge_status = POWER_SUPPLY_STATUS_FULL; | 269 | di->charge_status = POWER_SUPPLY_STATUS_FULL; |
270 | ds2760_battery_set_current_accum(di, | ||
271 | di->full_active_uAh); | ||
264 | } | 272 | } |
265 | } | 273 | } |
266 | } else { | 274 | } else { |
@@ -423,6 +431,11 @@ static int ds2760_battery_probe(struct platform_device *pdev) | |||
423 | if (rated_capacity) | 431 | if (rated_capacity) |
424 | ds2760_battery_write_rated_capacity(di, rated_capacity); | 432 | ds2760_battery_write_rated_capacity(di, rated_capacity); |
425 | 433 | ||
434 | /* set current accumulator if given as parameter. | ||
435 | * this should only be done for bootstrapping the value */ | ||
436 | if (current_accum) | ||
437 | ds2760_battery_set_current_accum(di, current_accum); | ||
438 | |||
426 | retval = power_supply_register(&pdev->dev, &di->bat); | 439 | retval = power_supply_register(&pdev->dev, &di->bat); |
427 | if (retval) { | 440 | if (retval) { |
428 | dev_err(di->dev, "failed to register battery\n"); | 441 | dev_err(di->dev, "failed to register battery\n"); |