aboutsummaryrefslogtreecommitdiff
path: root/drivers/power
diff options
context:
space:
mode:
authorJohan Palsson <johan.palsson@stericsson.com>2011-02-21 10:25:22 +0100
committerSrinidhi KASAGAR <srinidhi.kasagar@stericsson.com>2011-02-21 10:56:50 +0100
commitdc7055857ecaae2b67c6b37be18bacd778c88746 (patch)
tree99c9f55bf3fe7793356bd9753b311f433d4d6bbb /drivers/power
parentd471fc846b03801a5008dd6e5c9b4120b0d0e792 (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.c50
-rw-r--r--drivers/power/ab8500_charger.c10
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:
/*