aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/power/ds2760_battery.c41
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;
70module_param(rated_capacity, uint, 0644); 70module_param(rated_capacity, uint, 0644);
71MODULE_PARM_DESC(rated_capacity, "rated battery capacity, 10*mAh or index"); 71MODULE_PARM_DESC(rated_capacity, "rated battery capacity, 10*mAh or index");
72 72
73static unsigned int current_accum;
74module_param(current_accum, uint, 0644);
75MODULE_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. */
75static int rated_capacities[] = { 79static 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
222static 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
218static void ds2760_battery_update_status(struct ds2760_device_info *di) 238static 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");