@@ -720,7 +720,7 @@ static int ab8500_charger_max_usb_curr(struct ab8500_charger *di,
di->is_aca_rid = 0;
break;
case USB_STAT_ACA_RID_C_HS_CHIRP:
- case USB_STAT_ACA_RID_C_NM:
+ case USB_STAT_ACA_RID_C_NM:
di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_1P5;
di->is_aca_rid = 1;
break;
@@ -27,7 +27,7 @@
#include <linux/notifier.h>
/* Watchdog kick interval */
-#define CHG_WD_INTERVAL (6 * HZ)
+#define CHG_WD_INTERVAL (60 * HZ)
/* End-of-charge criteria counter */
#define EOC_COND_CNT 10
@@ -513,7 +513,7 @@ static int abx500_chargalg_kick_watchdog(struct abx500_chargalg *di)
static int abx500_chargalg_ac_en(struct abx500_chargalg *di, int enable,
int vset, int iset)
{
- static int ab8500_chargalg_ex_ac_enable_toggle;
+ static int abx500_chargalg_ex_ac_enable_toggle;
if (!di->ac_chg || !di->ac_chg->ops.enable)
return -ENXIO;
@@ -529,10 +529,10 @@ static int abx500_chargalg_ac_en(struct abx500_chargalg *di, int enable,
/*enable external charger*/
if (enable && di->ac_chg->external &&
- !ab8500_chargalg_ex_ac_enable_toggle) {
+ !abx500_chargalg_ex_ac_enable_toggle) {
blocking_notifier_call_chain(&charger_notifier_list,
0, di->dev);
- ab8500_chargalg_ex_ac_enable_toggle++;
+ abx500_chargalg_ex_ac_enable_toggle++;
}
return di->ac_chg->ops.enable(di->ac_chg, enable, vset, iset);
@@ -899,6 +899,27 @@ static void handle_maxim_chg_curr(struct abx500_chargalg *di)
}
}
+static void abx500_chargalg_check_safety_timer(struct abx500_chargalg *di)
+{
+ /*
+ * The safety timer will not be started until the capacity reported
+ * from the FG algorithm is 100%. Then we know that the amount of
+ * charge that's gone into the battery is enough for the battery
+ * to be full. If it has not reached end-of-charge before the safety
+ * timer has expired then we know that the battery is overcharged
+ * and charging will be stopped to protect the battery.
+ */
+ if (di->batt_data.percent == 100 &&
+ !timer_pending(&di->safety_timer)) {
+ abx500_chargalg_start_safety_timer(di);
+ dev_dbg(di->dev, "start safety timer\n");
+ } else if (di->batt_data.percent != 100 &&
+ timer_pending(&di->safety_timer)) {
+ abx500_chargalg_stop_safety_timer(di);
+ dev_dbg(di->dev, "stop safety timer\n");
+ }
+}
+
static int abx500_chargalg_get_ext_psy_data(struct device *dev, void *data)
{
struct power_supply *psy;
@@ -1125,6 +1146,10 @@ static int abx500_chargalg_get_ext_psy_data(struct device *dev, void *data)
switch (ext->type) {
case POWER_SUPPLY_TYPE_BATTERY:
di->batt_data.volt = ret.intval / 1000;
+ if (di->batt_data.volt >= BATT_OVV_VALUE)
+ di->events.batt_ovv = true;
+ else
+ di->events.batt_ovv = false;
break;
case POWER_SUPPLY_TYPE_MAINS:
di->chg_info.ac_volt = ret.intval / 1000;
@@ -1214,7 +1239,6 @@ static int abx500_chargalg_get_ext_psy_data(struct device *dev, void *data)
}
break;
case POWER_SUPPLY_PROP_CAPACITY:
- di->batt_data.percent = ret.intval;
if (!capacity_updated)
di->batt_data.percent = ret.intval;
break;
@@ -1465,12 +1489,12 @@ static void abx500_chargalg_algorithm(struct abx500_chargalg *di)
di->bat->bat_type[di->bat->batt_id].normal_vol_lvl,
di->bat->bat_type[di->bat->batt_id].normal_cur_lvl);
abx500_chargalg_state_to(di, STATE_NORMAL);
- abx500_chargalg_start_safety_timer(di);
abx500_chargalg_stop_maintenance_timer(di);
init_maxim_chg_curr(di);
di->charge_status = POWER_SUPPLY_STATUS_CHARGING;
di->eoc_cnt = 0;
di->maintenance_chg = false;
+ di->maint_state = MAINT_A;
power_supply_changed(&di->chargalg_psy);
break;
@@ -1478,17 +1502,14 @@ static void abx500_chargalg_algorithm(struct abx500_chargalg *di)
case STATE_NORMAL:
handle_maxim_chg_curr(di);
if (di->charge_status == POWER_SUPPLY_STATUS_FULL &&
- di->maintenance_chg) {
- if (di->bat->no_maintenance)
- abx500_chargalg_state_to(di,
- STATE_WAIT_FOR_RECHARGE_INIT);
- else
- abx500_chargalg_state_to(di,
- STATE_MAINTENANCE_A_INIT);
- }
+ di->maintenance_chg)
+ abx500_chargalg_state_to(di,
+ STATE_WAIT_FOR_RECHARGE_INIT);
+
+ /* Check whether we should start the safety timer or not */
+ abx500_chargalg_check_safety_timer(di);
break;
- /* This state will be used when the maintenance state is disabled */
case STATE_WAIT_FOR_RECHARGE_INIT:
abx500_chargalg_hold_charging(di);
abx500_chargalg_state_to(di, STATE_WAIT_FOR_RECHARGE);
@@ -1531,13 +1552,15 @@ static void abx500_chargalg_algorithm(struct abx500_chargalg *di)
di->bat->bat_type[
di->bat->batt_id].maint_a_cur_lvl);
abx500_chargalg_state_to(di, STATE_MAINTENANCE_A);
+ di->maint_state = MAINT_B;
power_supply_changed(&di->chargalg_psy);
/* Intentional fallthrough*/
case STATE_MAINTENANCE_A:
if (di->events.maintenance_timer_expired) {
abx500_chargalg_stop_maintenance_timer(di);
- abx500_chargalg_state_to(di, STATE_MAINTENANCE_B_INIT);
+ abx500_chargalg_state_to(di,
+ STATE_WAIT_FOR_RECHARGE_INIT);
}
break;
@@ -1603,7 +1626,8 @@ static void abx500_chargalg_algorithm(struct abx500_chargalg *di)
/* Start charging directly if the new state is a charge state */
if (di->charge_state == STATE_NORMAL_INIT ||
di->charge_state == STATE_MAINTENANCE_A_INIT ||
- di->charge_state == STATE_MAINTENANCE_B_INIT)
+ di->charge_state == STATE_MAINTENANCE_B_INIT ||
+ di->charge_state == STATE_WAIT_FOR_RECHARGE_INIT)
queue_work(di->chargalg_wq, &di->chargalg_work);
}
@@ -1824,7 +1848,7 @@ static struct attribute *abx500_chargalg_chg[] = {
NULL
};
-static const struct sysfs_ops abx500_chargalg_sysfs_ops = {
+const struct sysfs_ops abx500_chargalg_sysfs_ops = {
.show = abx500_chargalg_sysfs_show,
.store = abx500_chargalg_sysfs_charger,
};
@@ -2009,10 +2033,12 @@ static int __devinit abx500_chargalg_probe(struct platform_device *pdev)
goto free_psy;
}
+ di->charge_status = POWER_SUPPLY_STATUS_DISCHARGING;
+ abx500_chargalg_state_to(di, STATE_HANDHELD);
+
/* Run the charging algorithm */
queue_delayed_work(di->chargalg_wq, &di->chargalg_periodic_work, 0);
- dev_info(di->dev, "probe success\n");
return ret;
free_psy:
@@ -2052,4 +2078,4 @@ module_exit(abx500_chargalg_exit);
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Johan Palsson, Karl Komierowski");
MODULE_ALIAS("platform:abx500-chargalg");
-MODULE_DESCRIPTION("abx500 battery charging algorithm");
+MODULE_DESCRIPTION("abx500 battery temperatur driver");