From b016322293c7e3b7efb1835603d149c03d00b0df Mon Sep 17 00:00:00 2001 From: Nicolas Guion Date: Wed, 23 May 2012 15:59:43 +0200 Subject: [PATCH] ab8500-charger: Add support for autopower on AB8505 and AB9540 Accessing autopower register fails on the AB8505 and ab9540 as the fallback software control register has moved. Signed-off-by: Marcus Cooper Signed-off-by: Lee Jones Reviewed-by: Mattias WALLIN Reviewed-by: Nicolas GUION Reviewed-by: Jonas ABERG Tested-by: Jonas ABERG --- drivers/power/ab8500_charger.c | 52 +++++++++++++++++++++++----------- 1 file changed, 35 insertions(+), 17 deletions(-) diff --git a/drivers/power/ab8500_charger.c b/drivers/power/ab8500_charger.c index d834566410bc..da965ee615cc 100644 --- a/drivers/power/ab8500_charger.c +++ b/drivers/power/ab8500_charger.c @@ -95,6 +95,8 @@ #define CHG_WD_INTERVAL (60 * HZ) +#define AB8500_SW_CONTROL_FALLBACK 0x03 + /* UsbLineStatus register - usb types */ enum ab8500_charger_link_status { USB_STAT_NOT_CONFIGURED, @@ -312,42 +314,58 @@ static enum power_supply_property ab8500_charger_usb_props[] = { static void ab8500_enable_disable_sw_fallback(struct ab8500_charger *di, bool fallback) { + u8 val; u8 reg; + u8 bank; + u8 bit; int ret; dev_dbg(di->dev, "SW Fallback: %d\n", fallback); + if (is_ab8500(di->parent)) { + bank = 0x15; + reg = 0x0; + bit = 3; + } else { + bank = AB8500_SYS_CTRL1_BLOCK; + reg = AB8500_SW_CONTROL_FALLBACK; + bit = 0; + } + /* read the register containing fallback bit */ - ret = abx500_get_register_interruptible(di->dev, 0x15, 0x00, ®); - if (ret) { - dev_err(di->dev, "%d write failed\n", __LINE__); + ret = abx500_get_register_interruptible(di->dev, bank, reg, &val); + if (ret < 0) { + dev_err(di->dev, "%d read failed\n", __LINE__); return; } - /* enable the OPT emulation registers */ - ret = abx500_set_register_interruptible(di->dev, 0x11, 0x00, 0x2); - if (ret) { - dev_err(di->dev, "%d write failed\n", __LINE__); - return; + if (is_ab8500(di->parent)) { + /* enable the OPT emulation registers */ + ret = abx500_set_register_interruptible(di->dev, 0x11, 0x00, 0x2); + if (ret) { + dev_err(di->dev, "%d write failed\n", __LINE__); + goto disable_otp; + } } if (fallback) - reg |= 0x8; + val |= (1 << bit); else - reg &= ~0x8; + val &= ~(1 << bit); /* write back the changed fallback bit value to register */ - ret = abx500_set_register_interruptible(di->dev, 0x15, 0x00, reg); + ret = abx500_set_register_interruptible(di->dev, bank, reg, val); if (ret) { dev_err(di->dev, "%d write failed\n", __LINE__); - return; } - /* disable the set OTP registers again */ - ret = abx500_set_register_interruptible(di->dev, 0x11, 0x00, 0x0); - if (ret) { - dev_err(di->dev, "%d write failed\n", __LINE__); - return; +disable_otp: + if (is_ab8500(di->parent)) { + /* disable the set OTP registers again */ + ret = abx500_set_register_interruptible(di->dev, 0x11, 0x00, 0x0); + if (ret) { + dev_err(di->dev, "%d write failed\n", __LINE__); + } } } -- 2.34.1