From dc75b6a1d557f8ddb73d1aab7737e7be59b2c0f5 Mon Sep 17 00:00:00 2001 From: Werner Zeh Date: Tue, 13 Dec 2016 08:03:10 +0100 Subject: [PATCH] UPSTREAM: pcf8523: Fix wrong initialization of several registers In the case where the RTC is initialized after the battery is completely drained the bits for power_mode and cof_selection are set up with wrongly applied masks. In the case where the RTC is re-initialized again with no power-loss after the last initialization the bits for cap_sel, power_mode and cof_selection are not shifted to the right position. Both errors lead to a wrong initialization of the RTC and in turn to a way larger current consumption (instead of 120 nA the RTC current rises to over 2 A). This patch fixes both errors and the current consumption is in the right range again. TEST=booted mc_bdx1 and verified current consumption of RTC BUG=None BRANCH=None Signed-off-by: Werner Zeh Reviewed-on: https://review.coreboot.org/17829 Tested-by: build bot (Jenkins) Reviewed-by: Paul Menzel Reviewed-by: Martin Roth Change-Id: I8594f6ac121a175844393952db2169dbc5cbd2b2 Reviewed-on: https://chromium-review.googlesource.com/420842 Commit-Ready: Furquan Shaikh Tested-by: Furquan Shaikh Reviewed-by: Furquan Shaikh --- src/drivers/i2c/pcf8523/pcf8523.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/drivers/i2c/pcf8523/pcf8523.c b/src/drivers/i2c/pcf8523/pcf8523.c index eb0bf25123..416499bce5 100644 --- a/src/drivers/i2c/pcf8523/pcf8523.c +++ b/src/drivers/i2c/pcf8523/pcf8523.c @@ -63,15 +63,15 @@ static void pcf8523_init(struct device *dev) * corrupted and OS bit was not set. */ reg = smbus_read_byte(dev, CTRL_REG_1); reg &= ~(STOP_BIT | CAP_SEL); - reg |= config->cap_sel; + reg |= ((!!config->cap_sel) << 7); smbus_write_byte(dev, CTRL_REG_1, reg); reg = smbus_read_byte(dev, CTRL_REG_3); reg &= ~PM_MASK; - reg |= config->power_mode; + reg |= ((config->power_mode & 0x07) << 5); smbus_write_byte(dev, CTRL_REG_3, reg); reg = smbus_read_byte(dev, TMR_CLKOUT_REG); reg &= ~COF_MASK; - reg |= config->cof_selection; + reg |= ((config->cof_selection & 0x07) << 3); smbus_write_byte(dev, TMR_CLKOUT_REG, reg); return; } @@ -87,7 +87,7 @@ static void pcf8523_init(struct device *dev) ((!!config->tmrA_int_en) << 1) | (!!config->tmrB_int_en)); - smbus_write_byte(dev, CTRL_REG_3, ((config->power_mode & 0x03) << 5) | + smbus_write_byte(dev, CTRL_REG_3, ((config->power_mode & 0x07) << 5) | ((!!config->bat_switch_int_en) << 1) | (!!config->bat_low_int_en)); @@ -96,7 +96,7 @@ static void pcf8523_init(struct device *dev) smbus_write_byte(dev, TMR_CLKOUT_REG, ((!!config->tmrA_int_mode) << 7) | ((!!config->tmrB_int_mode) << 6) | - ((config->cof_selection & 0x38) << 3) | + ((config->cof_selection & 0x07) << 3) | ((config->tmrA_mode & 0x03) << 1) | (!!config->tmrB_mode));