power: ds2781: Reset ACR if not 100% when charge complete
authorGreg Meiste <w30289@motorola.com>
Tue, 2 Nov 2010 16:04:05 +0000 (11:04 -0500)
committerColin Cross <ccross@android.com>
Tue, 2 Nov 2010 23:10:40 +0000 (16:10 -0700)
If the charge IC reaches charge complete, it obviously will stop
charging.  If the DS2781 has not reached 100%, it never will.  So
reset the ACR register to the 100% value.

The DS2781 is supposed to reset itself to 100% if charge complete
is reached, but it is not doing so reliably.  Maxim has suggested
this as a workaround.

Change-Id: I97e532570694019227af4af4280ef06e9d67c6b2
Signed-off-by: Greg Meiste <w30289@motorola.com>
drivers/power/ds2781_battery.c

index 5432a7085ff276aadbcb5ce0d83c249dcd658871..519c6aa3ee2d6c0bf78bf54f69d2b0d377ed0edd 100644 (file)
@@ -383,6 +383,22 @@ static void ds2781_battery_alarm(struct alarm *alarm)
        queue_work(di->monitor_wqueue, &di->monitor_work);
 }
 
+static void ds2781_reset_if_necessary(struct ds2781_device_info *di)
+{
+       if (di->status.percentage < 100) {
+               dev_err(di->dev, "Charge complete before 100 percent.\n");
+               dev_err(di->dev, "Resetting ACR registers to Full 40 value.\n");
+
+               di->raw[DS2781_REG_ACCUMULATE_CURR_MSB] =
+                       di->raw[DS2781_REG_FULL_40_MSB];
+               di->raw[DS2781_REG_ACCUMULATE_CURR_LSB] =
+                       di->raw[DS2781_REG_FULL_40_LSB];
+               w1_ds2781_write(di->w1_dev,
+                               di->raw + DS2781_REG_ACCUMULATE_CURR_MSB,
+                               DS2781_REG_ACCUMULATE_CURR_MSB, 2);
+       }
+}
+
 static void battery_ext_power_changed(struct power_supply *psy)
 {
        struct ds2781_device_info *di;
@@ -394,8 +410,10 @@ static void battery_ext_power_changed(struct power_supply *psy)
        mutex_lock(&di->status_lock);
        if (got_power) {
                di->status.charge_source = 1;
-               if (is_ac_charge_complete())
+               if (is_ac_charge_complete()) {
                        di->status.battery_full = 1;
+                       ds2781_reset_if_necessary(di);
+               }
        } else {
                di->status.charge_source = 0;
                di->status.battery_full = 0;