| From 6b5bbc490de961b9749a68b1a8b56a2bf9fbdea6 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Mon, 17 Sep 2018 07:00:07 +0200 |
| Subject: power: supply: twl4030_charger: disable eoc interrupt on linear |
| charge |
| |
| From: Andreas Kemnade <andreas@kemnade.info> |
| |
| [ Upstream commit 079cdff3d0a09c5da10ae1be35def7a116776328 ] |
| |
| 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> |
| Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| 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 adcaa0a10a6f4..0e202d4273fb6 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.20.1 |
| |