aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Kemnade <andreas@kemnade.info>2018-09-17 01:00:07 -0400
committerSebastian Reichel <sre@kernel.org>2018-09-19 20:16:44 -0400
commit079cdff3d0a09c5da10ae1be35def7a116776328 (patch)
tree4c0a14089252560a2f52ea1fcdd16cd8f56495ab
parent8314c212f995bc0d06b54ad02ef0ab4089781540 (diff)
power: supply: twl4030_charger: disable eoc interrupt on linear charge
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>
-rw-r--r--drivers/power/supply/twl4030_charger.c27
1 files changed, 26 insertions, 1 deletions
diff --git a/drivers/power/supply/twl4030_charger.c b/drivers/power/supply/twl4030_charger.c
index c629c1642531..80582c8f98fa 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)
440static int twl4030_charger_enable_usb(struct twl4030_bci *bci, bool enable) 440static int twl4030_charger_enable_usb(struct twl4030_bci *bci, bool enable)
441{ 441{
442 int ret; 442 int ret;
443 u32 reg;
443 444
444 if (bci->usb_mode == CHARGE_OFF) 445 if (bci->usb_mode == CHARGE_OFF)
445 enable = false; 446 enable = false;
@@ -453,14 +454,38 @@ static int twl4030_charger_enable_usb(struct twl4030_bci *bci, bool enable)
453 bci->usb_enabled = 1; 454 bci->usb_enabled = 1;
454 } 455 }
455 456
456 if (bci->usb_mode == CHARGE_AUTO) 457 if (bci->usb_mode == CHARGE_AUTO) {
458 /* Enable interrupts now. */
459 reg = ~(u32)(TWL4030_ICHGLOW | TWL4030_ICHGEOC |
460 TWL4030_TBATOR2 | TWL4030_TBATOR1 |
461 TWL4030_BATSTS);
462 ret = twl_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, reg,
463 TWL4030_INTERRUPTS_BCIIMR1A);
464 if (ret < 0) {
465 dev_err(bci->dev,
466 "failed to unmask interrupts: %d\n",
467 ret);
468 return ret;
469 }
457 /* forcing the field BCIAUTOUSB (BOOT_BCI[1]) to 1 */ 470 /* forcing the field BCIAUTOUSB (BOOT_BCI[1]) to 1 */
458 ret = twl4030_clear_set_boot_bci(0, TWL4030_BCIAUTOUSB); 471 ret = twl4030_clear_set_boot_bci(0, TWL4030_BCIAUTOUSB);
472 }
459 473
460 /* forcing USBFASTMCHG(BCIMFSTS4[2]) to 1 */ 474 /* forcing USBFASTMCHG(BCIMFSTS4[2]) to 1 */
461 ret = twl4030_clear_set(TWL_MODULE_MAIN_CHARGE, 0, 475 ret = twl4030_clear_set(TWL_MODULE_MAIN_CHARGE, 0,
462 TWL4030_USBFASTMCHG, TWL4030_BCIMFSTS4); 476 TWL4030_USBFASTMCHG, TWL4030_BCIMFSTS4);
463 if (bci->usb_mode == CHARGE_LINEAR) { 477 if (bci->usb_mode == CHARGE_LINEAR) {
478 /* Enable interrupts now. */
479 reg = ~(u32)(TWL4030_ICHGLOW | TWL4030_TBATOR2 |
480 TWL4030_TBATOR1 | TWL4030_BATSTS);
481 ret = twl_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, reg,
482 TWL4030_INTERRUPTS_BCIIMR1A);
483 if (ret < 0) {
484 dev_err(bci->dev,
485 "failed to unmask interrupts: %d\n",
486 ret);
487 return ret;
488 }
464 twl4030_clear_set_boot_bci(TWL4030_BCIAUTOAC|TWL4030_CVENAC, 0); 489 twl4030_clear_set_boot_bci(TWL4030_BCIAUTOAC|TWL4030_CVENAC, 0);
465 /* Watch dog key: WOVF acknowledge */ 490 /* Watch dog key: WOVF acknowledge */
466 ret = twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE, 0x33, 491 ret = twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE, 0x33,