diff options
author | Johan Palsson <johan.palsson@stericsson.com> | 2011-02-21 10:25:22 +0100 |
---|---|---|
committer | Srinidhi KASAGAR <srinidhi.kasagar@stericsson.com> | 2011-02-21 10:56:50 +0100 |
commit | dc7055857ecaae2b67c6b37be18bacd778c88746 (patch) | |
tree | 99c9f55bf3fe7793356bd9753b311f433d4d6bbb /drivers/power | |
parent | d471fc846b03801a5008dd6e5c9b4120b0d0e792 (diff) |
power: ab8500_bm: Disable charging if charger voltage too high
Charging is not allowed if the charger voltage is above maximum limit
ST-Ericsson ID: WP324203
Change-Id: I47351975e4b59c48a93281c4f626e805b5016617
Signed-off-by: Johan Palsson <johan.palsson@stericsson.com>
Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/16364
Reviewed-by: Johan GARDSMARK <johan.gardsmark@stericsson.com>
Reviewed-by: QATOOLS
Reviewed-by: Srinidhi KASAGAR <srinidhi.kasagar@stericsson.com>
Diffstat (limited to 'drivers/power')
-rw-r--r-- | drivers/power/ab8500_chargalg.c | 50 | ||||
-rw-r--r-- | drivers/power/ab8500_charger.c | 10 |
2 files changed, 45 insertions, 15 deletions
diff --git a/drivers/power/ab8500_chargalg.c b/drivers/power/ab8500_chargalg.c index 3800bc0ab62..3d9d7734f2f 100644 --- a/drivers/power/ab8500_chargalg.c +++ b/drivers/power/ab8500_chargalg.c @@ -49,6 +49,12 @@ struct ab8500_chargalg_charger_info { enum ab8500_chargers online_chg; enum ab8500_chargers prev_online_chg; enum ab8500_chargers charger_type; + bool usb_chg_ok; + bool ac_chg_ok; + int usb_volt; + int usb_curr; + int ac_volt; + int ac_curr; }; struct ab8500_chargalg_suspension_status { @@ -252,13 +258,13 @@ static void ab8500_chargalg_state_to(struct ab8500_chargalg *di, } /** - * ab8500_chargalg_check_chargers() - Check charger connection change + * ab8500_chargalg_check_charger_connection() - Check charger connection change * @di: pointer to the ab8500_chargalg structure * * This function will check if there is a change in the charger connection * and change charge state accordingly. AC has precedence over USB. */ -static int ab8500_chargalg_check_chargers(struct ab8500_chargalg *di) +static int ab8500_chargalg_check_charger_connection(struct ab8500_chargalg *di) { if (di->chg_info.conn_chg != di->chg_info.prev_conn_chg || di->susp_status.suspended_change) { @@ -524,6 +530,28 @@ static void ab8500_chargalg_check_temp(struct ab8500_chargalg *di) } /** + * ab8500_chargalg_check_charger_health() - Check charger health + * @di: pointer to the ab8500_chargalg structure + * + * Charger voltage and current is checked against maximum limits + */ +static void ab8500_chargalg_check_charger_health(struct ab8500_chargalg *di) +{ + if (di->chg_info.usb_volt > di->bat->chg_params->usb_volt_max || + di->chg_info.usb_curr > di->bat->chg_params->usb_curr_max) + di->chg_info.usb_chg_ok = false; + else + di->chg_info.usb_chg_ok = true; + + if (di->chg_info.ac_volt > di->bat->chg_params->ac_volt_max || + di->chg_info.ac_curr > di->bat->chg_params->ac_curr_max) + di->chg_info.ac_chg_ok = false; + else + di->chg_info.ac_chg_ok = true; + +} + +/** * ab8500_chargalg_end_of_charge() - Check if end-of-charge criteria is fulfilled * @di: pointer to the ab8500_chargalg structure * @@ -805,10 +833,12 @@ static int ab8500_chargalg_get_ext_psy_data(struct device *dev, void *data) di->batt_data.volt = ret.intval / 1000; break; case POWER_SUPPLY_TYPE_MAINS: - /* TODO: Save the voltage */ + di->chg_info.ac_volt = + ret.intval / 1000; break; case POWER_SUPPLY_TYPE_USB: - /* TODO: Save the voltage */ + di->chg_info.usb_volt = + ret.intval / 1000; break; default: break; @@ -930,7 +960,8 @@ static void ab8500_chargalg_algorithm(struct ab8500_chargalg *di) ab8500_chargalg_end_of_charge(di); ab8500_chargalg_check_temp(di); - charger_status = ab8500_chargalg_check_chargers(di); + ab8500_chargalg_check_charger_health(di); + charger_status = ab8500_chargalg_check_charger_connection(di); /* * First check if we have a charger connected. @@ -968,13 +999,13 @@ static void ab8500_chargalg_algorithm(struct ab8500_chargalg *di) ab8500_chargalg_state_to(di, STATE_BATT_REMOVED_INIT); } /* Main or USB charger not ok. */ - else if (di->events.mainextchnotok || - di->events.usbchargernotok) { + else if (di->events.mainextchnotok || di->events.usbchargernotok) { if (di->charge_state != STATE_CHG_NOT_OK) ab8500_chargalg_state_to(di, STATE_CHG_NOT_OK_INIT); } /* VBUS or VBAT OVV. */ - else if (di->events.vbus_ovv || di->events.batt_ovv) { + else if (di->events.vbus_ovv || di->events.batt_ovv || + !di->chg_info.usb_chg_ok || !di->chg_info.ac_chg_ok) { if (di->charge_state != STATE_OVV_PROTECT) ab8500_chargalg_state_to(di, STATE_OVV_PROTECT_INIT); } @@ -1081,7 +1112,8 @@ static void ab8500_chargalg_algorithm(struct ab8500_chargalg *di) /* Intentional fallthrough */ case STATE_OVV_PROTECT: - if (!di->events.vbus_ovv && !di->events.batt_ovv) + if (!di->events.vbus_ovv && !di->events.batt_ovv && + di->chg_info.usb_chg_ok && di->chg_info.ac_chg_ok) ab8500_chargalg_state_to(di, STATE_NORMAL_INIT); break; diff --git a/drivers/power/ab8500_charger.c b/drivers/power/ab8500_charger.c index ead31aef292..475ecddbffe 100644 --- a/drivers/power/ab8500_charger.c +++ b/drivers/power/ab8500_charger.c @@ -1116,10 +1116,6 @@ static int ab8500_charger_watchdog_kick(struct ab8500_charger *di) if (ret) dev_err(di->dev, "Failed to kick WD!\n"); - /* We use this periodic work to measure the charger voltage as well */ - di->ac.charger_voltage = ab8500_charger_get_ac_voltage(di); - di->usb.charger_voltage = ab8500_charger_get_vbus_voltage(di); - return ret; } @@ -1809,7 +1805,8 @@ static int ab8500_charger_ac_get_property(struct power_supply *psy, val->intval = di->ac.charger_connected; break; case POWER_SUPPLY_PROP_VOLTAGE_NOW: - val->intval = di->ac.charger_voltage; + di->ac.charger_voltage = ab8500_charger_get_ac_voltage(di); + val->intval = di->ac.charger_voltage * 1000; break; case POWER_SUPPLY_PROP_VOLTAGE_AVG: /* @@ -1867,7 +1864,8 @@ static int ab8500_charger_usb_get_property(struct power_supply *psy, val->intval = di->usb.charger_connected; break; case POWER_SUPPLY_PROP_VOLTAGE_NOW: - val->intval = di->usb.charger_voltage; + di->usb.charger_voltage = ab8500_charger_get_vbus_voltage(di); + val->intval = di->usb.charger_voltage * 1000; break; case POWER_SUPPLY_PROP_VOLTAGE_AVG: /* |