aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChuanhua Han <chuanhua.han@nxp.com>2019-07-08 11:45:25 +0800
committerHeiko Schocher <hs@denx.de>2019-07-09 10:51:12 +0200
commitef6c26d338a168110b7688b07e319ff46c73748d (patch)
tree80abc7740b3790154a49419338a8a9f6f4db39ec
parentd3826fb052af9e6df22abaefb1b0c7496e469f9e (diff)
downloadu-boot-ef6c26d338a168110b7688b07e319ff46c73748d.zip
u-boot-ef6c26d338a168110b7688b07e319ff46c73748d.tar.gz
u-boot-ef6c26d338a168110b7688b07e319ff46c73748d.tar.bz2
rtc: pcf2127: Fixed bug with rtc settings and getting error time
The previous pcf2127 RTC chip could not read and set the correct time. When reading the data of internal registers, the read address was the value of register plus 1. This is because this chip requires the host to send a stop signal after setting the register address and before reading the register data. This patch sets the register address using dm_i2c_write and reads the register data using the original dm_i2c_xfer in order to generate a stop signal after the register address is set, and fixes the bug of the original read and write time. Signed-off-by: Biwen Li <biwen.li@nxp.com> Signed-off-by: Chuanhua Han <chuanhua.han@nxp.com> Reviewed-by: Lukasz Majewski <lukma@denx.de> Reviewed-by: Heiko Schocher <hs@denx.de>
-rw-r--r--drivers/rtc/pcf2127.c33
1 files changed, 24 insertions, 9 deletions
diff --git a/drivers/rtc/pcf2127.c b/drivers/rtc/pcf2127.c
index dcf0340..f695350 100644
--- a/drivers/rtc/pcf2127.c
+++ b/drivers/rtc/pcf2127.c
@@ -22,14 +22,32 @@
#define PCF2127_REG_MO 0x08
#define PCF2127_REG_YR 0x09
+static int pcf2127_read_reg(struct udevice *dev, uint offset,
+ u8 *buffer, int len)
+{
+ struct dm_i2c_chip *chip = dev_get_parent_platdata(dev);
+ struct i2c_msg msg;
+ int ret;
+
+ /* Set the address of the start register to be read */
+ ret = dm_i2c_write(dev, offset, NULL, 0);
+ if (ret < 0)
+ return ret;
+
+ /* Read register's data */
+ msg.addr = chip->chip_addr;
+ msg.flags |= I2C_M_RD;
+ msg.len = len;
+ msg.buf = buffer;
+
+ return dm_i2c_xfer(dev, &msg, 1);
+}
+
static int pcf2127_rtc_set(struct udevice *dev, const struct rtc_time *tm)
{
- uchar buf[8];
+ uchar buf[7] = {0};
int i = 0, ret;
- /* start register address */
- buf[i++] = PCF2127_REG_SC;
-
/* hours, minutes and seconds */
buf[i++] = bin2bcd(tm->tm_sec);
buf[i++] = bin2bcd(tm->tm_min);
@@ -44,7 +62,7 @@ static int pcf2127_rtc_set(struct udevice *dev, const struct rtc_time *tm)
buf[i++] = bin2bcd(tm->tm_year % 100);
/* write register's data */
- ret = dm_i2c_write(dev, PCF2127_REG_CTRL1, buf, sizeof(buf));
+ ret = dm_i2c_write(dev, PCF2127_REG_SC, buf, i);
return ret;
}
@@ -54,10 +72,7 @@ static int pcf2127_rtc_get(struct udevice *dev, struct rtc_time *tm)
int ret = 0;
uchar buf[10] = { PCF2127_REG_CTRL1 };
- ret = dm_i2c_write(dev, PCF2127_REG_CTRL1, buf, 1);
- if (ret < 0)
- return ret;
- ret = dm_i2c_read(dev, PCF2127_REG_CTRL1, buf, sizeof(buf));
+ ret = pcf2127_read_reg(dev, PCF2127_REG_CTRL1, buf, sizeof(buf));
if (ret < 0)
return ret;