From: Grazvydas Ignotas Date: Sun, 10 Feb 2013 02:49:21 +0000 (+0200) Subject: twl4030_charger: improve set_charge_current X-Git-Tag: sz_154~16 X-Git-Url: https://git.openpandora.org/cgi-bin/gitweb.cgi?p=pandora-kernel.git;a=commitdiff_plain;h=dbe5d2ec3b8bf2045decab984c2783b9851f0e2e twl4030_charger: improve set_charge_current - don't change it if there is no battery as it requires disabling CV - fix error handling --- diff --git a/drivers/power/twl4030_charger.c b/drivers/power/twl4030_charger.c index c832d3284659..0a45c24b4120 100644 --- a/drivers/power/twl4030_charger.c +++ b/drivers/power/twl4030_charger.c @@ -28,6 +28,7 @@ #define TWL4030_BCIICHG 0x08 #define TWL4030_BCIVAC 0x0a #define TWL4030_BCIVBUS 0x0c +#define TWL4030_BCIMFSTS3 0x0f #define TWL4030_BCIMFSTS4 0x10 #define TWL4030_BCIMFKEY 0x11 #define TWL4030_BCICTL1 0x23 @@ -36,6 +37,7 @@ #define TWL4030_BCIAUTOWEN BIT(5) #define TWL4030_CONFIG_DONE BIT(4) +#define TWL4030_CVENAC BIT(2) #define TWL4030_BCIAUTOUSB BIT(1) #define TWL4030_BCIAUTOAC BIT(0) #define TWL4030_CGAIN BIT(5) @@ -67,6 +69,7 @@ #define TWL4030_MSTATEC_COMPLETE4 0x0e #define TWL4030_KEY_IIREF 0xe7 +#define TWL4030_BATSTSMCHG BIT(6) static bool allow_usb = 1; module_param(allow_usb, bool, 0644); @@ -235,21 +238,30 @@ static int twl4030_charger_enable_ac(bool enable) static int set_charge_current(struct twl4030_bci *bci, int new_current) { - u8 tmp, boot_bci_prev, cgain_set, cgain_clear; - int ret; + u8 val, boot_bci_prev, cgain_set, cgain_clear; + int ret, ret2; + + ret = twl4030_bci_read(TWL4030_BCIMFSTS3, &val); + if (ret) + goto out_norestore; + + if (!(val & TWL4030_BATSTSMCHG)) { + dev_err(bci->dev, "missing battery, can't change charge_current\n"); + goto out_norestore; + } ret = twl_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &boot_bci_prev, TWL4030_PM_MASTER_BOOT_BCI); if (ret) - goto out; + goto out_norestore; /* * Stop automatic charging here, because charge current change * requires multiple register writes and CGAIN change requires - * automatic charge to be stopped. + * automatic charge to be stopped (and CV mode disabled too). */ ret = twl4030_clear_set_boot_bci( - TWL4030_BCIAUTOAC | TWL4030_BCIAUTOUSB | 4, 0); + TWL4030_CVENAC | TWL4030_BCIAUTOAC | TWL4030_BCIAUTOUSB, 0); if (ret) goto out; @@ -283,17 +295,21 @@ static int set_charge_current(struct twl4030_bci *bci, int new_current) if (ret) goto out; - ret = twl4030_bci_read(TWL4030_BCICTL1, &tmp); - if (ret != 0 || (tmp & TWL4030_CGAIN) != cgain_set) { + ret = twl4030_bci_read(TWL4030_BCICTL1, &val); + if (ret != 0 || (val & TWL4030_CGAIN) != cgain_set) { dev_err(bci->dev, "CGAIN change failed\n"); goto out; } - ret = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, boot_bci_prev, - TWL4030_PM_MASTER_BOOT_BCI); out: + ret2 = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, boot_bci_prev, + TWL4030_PM_MASTER_BOOT_BCI); + if (ret2 != 0) + dev_err(bci->dev, "failed boot_bci restore: %d\n", ret2); + +out_norestore: if (ret != 0) - dev_err(bci->dev, "charge current change failed\n"); + dev_err(bci->dev, "charge current change failed: %d\n", ret); return ret; } @@ -533,7 +549,7 @@ static ssize_t store_charge_current(struct device *dev, if (ret) return ret; - if (bci->current_supply == POWER_SUPPLY_TYPE_MAINS) + if (psy->type == POWER_SUPPLY_TYPE_MAINS) bci->ac_current = new_current; else bci->usb_current = new_current;