power: supply: axp288_charger: Handle charger type changing without disconnect

Deal with the charger type changing without a vbus-disconnect being
reported in between the 2 charger type states:

-Do not return from axp288_charger_extcon_evt_worker early in this case
 (track old_chg_type)
-Make calling axp288_charger_enable_charger with the same value as before
 a nop, to avoid the need for the caller to check this
-Do no do a dev_err when axp288_charger_enable_charger returns an error,
 axp288_charger_enable_charger already returns an error itself
-Disable the charger before changing the charge-current setting (nop if
 vbus was seen as disconnected before the change)

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Sebastian Reichel <sre@kernel.org>
This commit is contained in:
Hans de Goede 2016-12-21 15:36:52 +01:00 committed by Sebastian Reichel
parent 7508f44129
commit 71851a63af

View File

@ -175,7 +175,6 @@ struct axp288_chrg_info {
int max_cv; int max_cv;
bool online; bool online;
bool present; bool present;
bool enable_charger;
bool is_charger_enabled; bool is_charger_enabled;
}; };
@ -305,6 +304,9 @@ static int axp288_charger_enable_charger(struct axp288_chrg_info *info,
{ {
int ret; int ret;
if (enable == info->is_charger_enabled)
return 0;
if (enable) if (enable)
ret = regmap_update_bits(info->regmap, AXP20X_CHRG_CTRL1, ret = regmap_update_bits(info->regmap, AXP20X_CHRG_CTRL1,
CHRG_CCCV_CHG_EN, CHRG_CCCV_CHG_EN); CHRG_CCCV_CHG_EN, CHRG_CCCV_CHG_EN);
@ -579,6 +581,7 @@ static void axp288_charger_extcon_evt_worker(struct work_struct *work)
bool changed = false; bool changed = false;
struct extcon_dev *edev = info->cable.edev; struct extcon_dev *edev = info->cable.edev;
bool old_connected = info->cable.connected; bool old_connected = info->cable.connected;
enum power_supply_type old_chg_type = info->cable.chg_type;
/* Determine cable/charger type */ /* Determine cable/charger type */
if (extcon_get_state(edev, EXTCON_CHG_USB_SDP) > 0) { if (extcon_get_state(edev, EXTCON_CHG_USB_SDP) > 0) {
@ -601,7 +604,8 @@ static void axp288_charger_extcon_evt_worker(struct work_struct *work)
} }
/* Cable status changed */ /* Cable status changed */
if (old_connected != info->cable.connected) if (old_connected != info->cable.connected ||
old_chg_type != info->cable.chg_type)
changed = true; changed = true;
if (!changed) if (!changed)
@ -609,14 +613,9 @@ static void axp288_charger_extcon_evt_worker(struct work_struct *work)
mutex_lock(&info->lock); mutex_lock(&info->lock);
if (info->is_charger_enabled && !info->cable.connected) { if (info->cable.connected) {
info->enable_charger = false; axp288_charger_enable_charger(info, false);
ret = axp288_charger_enable_charger(info, info->enable_charger);
if (ret < 0)
dev_err(&info->pdev->dev,
"cannot disable charger (%d)", ret);
} else if (!info->is_charger_enabled && info->cable.connected) {
switch (info->cable.chg_type) { switch (info->cable.chg_type) {
case POWER_SUPPLY_TYPE_USB: case POWER_SUPPLY_TYPE_USB:
current_limit = ILIM_500MA; current_limit = ILIM_500MA;
@ -635,17 +634,13 @@ static void axp288_charger_extcon_evt_worker(struct work_struct *work)
/* Set vbus current limit first, then enable charger */ /* Set vbus current limit first, then enable charger */
ret = axp288_charger_set_vbus_inlmt(info, current_limit); ret = axp288_charger_set_vbus_inlmt(info, current_limit);
if (ret < 0) { if (ret == 0)
axp288_charger_enable_charger(info, true);
else
dev_err(&info->pdev->dev, dev_err(&info->pdev->dev,
"error setting current limit (%d)", ret); "error setting current limit (%d)", ret);
} else { } else {
info->enable_charger = (current_limit > 0); axp288_charger_enable_charger(info, false);
ret = axp288_charger_enable_charger(info,
info->enable_charger);
if (ret < 0)
dev_err(&info->pdev->dev,
"cannot enable charger (%d)", ret);
}
} }
if (changed) if (changed)