diff mbox series

[RESEND] twl4030_charger: disable eoc interrupt on linear charge

Message ID 20180917050007.17808-1-andreas@kemnade.info (mailing list archive)
State Not Applicable, archived
Headers show
Series [RESEND] twl4030_charger: disable eoc interrupt on linear charge | expand

Commit Message

Andreas Kemnade Sept. 17, 2018, 5 a.m. UTC
This avoids getting woken up from suspend after power interruptions
when the bci wrongly thinks the battery is full just because
of input current going low because of low input power

Signed-off-by: Andreas Kemnade <andreas@kemnade.info>
---
 drivers/power/supply/twl4030_charger.c | 27 ++++++++++++++++++++++++++-
 1 file changed, 26 insertions(+), 1 deletion(-)

Comments

Sebastian Reichel Sept. 20, 2018, 12:20 a.m. UTC | #1
Hi,

On Mon, Sep 17, 2018 at 07:00:07AM +0200, Andreas Kemnade wrote:
> This avoids getting woken up from suspend after power interruptions
> when the bci wrongly thinks the battery is full just because
> of input current going low because of low input power
> 
> Signed-off-by: Andreas Kemnade <andreas@kemnade.info>
> ---

Thanks, queued.

-- Sebastian

>  drivers/power/supply/twl4030_charger.c | 27 ++++++++++++++++++++++++++-
>  1 file changed, 26 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/power/supply/twl4030_charger.c b/drivers/power/supply/twl4030_charger.c
> index b0eb7d0d6827..ff193368c85b 100644
> --- a/drivers/power/supply/twl4030_charger.c
> +++ b/drivers/power/supply/twl4030_charger.c
> @@ -440,6 +440,7 @@ static void twl4030_current_worker(struct work_struct *data)
>  static int twl4030_charger_enable_usb(struct twl4030_bci *bci, bool enable)
>  {
>  	int ret;
> +	u32 reg;
>  
>  	if (bci->usb_mode == CHARGE_OFF)
>  		enable = false;
> @@ -453,14 +454,38 @@ static int twl4030_charger_enable_usb(struct twl4030_bci *bci, bool enable)
>  			bci->usb_enabled = 1;
>  		}
>  
> -		if (bci->usb_mode == CHARGE_AUTO)
> +		if (bci->usb_mode == CHARGE_AUTO) {
> +			/* Enable interrupts now. */
> +			reg = ~(u32)(TWL4030_ICHGLOW | TWL4030_ICHGEOC |
> +					TWL4030_TBATOR2 | TWL4030_TBATOR1 |
> +					TWL4030_BATSTS);
> +			ret = twl_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, reg,
> +				       TWL4030_INTERRUPTS_BCIIMR1A);
> +			if (ret < 0) {
> +				dev_err(bci->dev,
> +					"failed to unmask interrupts: %d\n",
> +					ret);
> +				return ret;
> +			}
>  			/* forcing the field BCIAUTOUSB (BOOT_BCI[1]) to 1 */
>  			ret = twl4030_clear_set_boot_bci(0, TWL4030_BCIAUTOUSB);
> +		}
>  
>  		/* forcing USBFASTMCHG(BCIMFSTS4[2]) to 1 */
>  		ret = twl4030_clear_set(TWL_MODULE_MAIN_CHARGE, 0,
>  			TWL4030_USBFASTMCHG, TWL4030_BCIMFSTS4);
>  		if (bci->usb_mode == CHARGE_LINEAR) {
> +			/* Enable interrupts now. */
> +			reg = ~(u32)(TWL4030_ICHGLOW | TWL4030_TBATOR2 |
> +					TWL4030_TBATOR1 | TWL4030_BATSTS);
> +			ret = twl_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, reg,
> +				       TWL4030_INTERRUPTS_BCIIMR1A);
> +			if (ret < 0) {
> +				dev_err(bci->dev,
> +					"failed to unmask interrupts: %d\n",
> +					ret);
> +				return ret;
> +			}
>  			twl4030_clear_set_boot_bci(TWL4030_BCIAUTOAC|TWL4030_CVENAC, 0);
>  			/* Watch dog key: WOVF acknowledge */
>  			ret = twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE, 0x33,
> -- 
> 2.11.0
>
diff mbox series

Patch

diff --git a/drivers/power/supply/twl4030_charger.c b/drivers/power/supply/twl4030_charger.c
index b0eb7d0d6827..ff193368c85b 100644
--- a/drivers/power/supply/twl4030_charger.c
+++ b/drivers/power/supply/twl4030_charger.c
@@ -440,6 +440,7 @@  static void twl4030_current_worker(struct work_struct *data)
 static int twl4030_charger_enable_usb(struct twl4030_bci *bci, bool enable)
 {
 	int ret;
+	u32 reg;
 
 	if (bci->usb_mode == CHARGE_OFF)
 		enable = false;
@@ -453,14 +454,38 @@  static int twl4030_charger_enable_usb(struct twl4030_bci *bci, bool enable)
 			bci->usb_enabled = 1;
 		}
 
-		if (bci->usb_mode == CHARGE_AUTO)
+		if (bci->usb_mode == CHARGE_AUTO) {
+			/* Enable interrupts now. */
+			reg = ~(u32)(TWL4030_ICHGLOW | TWL4030_ICHGEOC |
+					TWL4030_TBATOR2 | TWL4030_TBATOR1 |
+					TWL4030_BATSTS);
+			ret = twl_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, reg,
+				       TWL4030_INTERRUPTS_BCIIMR1A);
+			if (ret < 0) {
+				dev_err(bci->dev,
+					"failed to unmask interrupts: %d\n",
+					ret);
+				return ret;
+			}
 			/* forcing the field BCIAUTOUSB (BOOT_BCI[1]) to 1 */
 			ret = twl4030_clear_set_boot_bci(0, TWL4030_BCIAUTOUSB);
+		}
 
 		/* forcing USBFASTMCHG(BCIMFSTS4[2]) to 1 */
 		ret = twl4030_clear_set(TWL_MODULE_MAIN_CHARGE, 0,
 			TWL4030_USBFASTMCHG, TWL4030_BCIMFSTS4);
 		if (bci->usb_mode == CHARGE_LINEAR) {
+			/* Enable interrupts now. */
+			reg = ~(u32)(TWL4030_ICHGLOW | TWL4030_TBATOR2 |
+					TWL4030_TBATOR1 | TWL4030_BATSTS);
+			ret = twl_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, reg,
+				       TWL4030_INTERRUPTS_BCIIMR1A);
+			if (ret < 0) {
+				dev_err(bci->dev,
+					"failed to unmask interrupts: %d\n",
+					ret);
+				return ret;
+			}
 			twl4030_clear_set_boot_bci(TWL4030_BCIAUTOAC|TWL4030_CVENAC, 0);
 			/* Watch dog key: WOVF acknowledge */
 			ret = twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE, 0x33,