rtc: abx80x: handle the oscillator failure bit

Handle the Oscillator Failure ('OF') bit from Oscillator Status register
(0x1D). This bit is cleared on set_time function and is read each time the
date/time is read, but only in case of XT Oscillator selection.
In RC mode, this bit is always set.

Signed-off-by: Mylène Josserand <mylene.josserand@free-electrons.com>
Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
This commit is contained in:
Mylène Josserand 2016-03-21 18:06:10 +01:00 committed by Alexandre Belloni
parent 59a8383adb
commit ee08774424

View File

@ -58,6 +58,7 @@
#define ABX8XX_OSC_OSEL BIT(7) #define ABX8XX_OSC_OSEL BIT(7)
#define ABX8XX_REG_OSS 0x1d #define ABX8XX_REG_OSS 0x1d
#define ABX8XX_OSS_OF BIT(1)
#define ABX8XX_OSS_OMODE BIT(4) #define ABX8XX_OSS_OMODE BIT(4)
#define ABX8XX_REG_CFG_KEY 0x1f #define ABX8XX_REG_CFG_KEY 0x1f
@ -138,7 +139,23 @@ static int abx80x_rtc_read_time(struct device *dev, struct rtc_time *tm)
{ {
struct i2c_client *client = to_i2c_client(dev); struct i2c_client *client = to_i2c_client(dev);
unsigned char buf[8]; unsigned char buf[8];
int err; int err, flags, rc_mode = 0;
/* Read the Oscillator Failure only in XT mode */
rc_mode = abx80x_is_rc_mode(client);
if (rc_mode < 0)
return rc_mode;
if (!rc_mode) {
flags = i2c_smbus_read_byte_data(client, ABX8XX_REG_OSS);
if (flags < 0)
return flags;
if (flags & ABX8XX_OSS_OF) {
dev_err(dev, "Oscillator failure, data is invalid.\n");
return -EINVAL;
}
}
err = i2c_smbus_read_i2c_block_data(client, ABX8XX_REG_HTH, err = i2c_smbus_read_i2c_block_data(client, ABX8XX_REG_HTH,
sizeof(buf), buf); sizeof(buf), buf);
@ -166,7 +183,7 @@ static int abx80x_rtc_set_time(struct device *dev, struct rtc_time *tm)
{ {
struct i2c_client *client = to_i2c_client(dev); struct i2c_client *client = to_i2c_client(dev);
unsigned char buf[8]; unsigned char buf[8];
int err; int err, flags;
if (tm->tm_year < 100) if (tm->tm_year < 100)
return -EINVAL; return -EINVAL;
@ -187,6 +204,18 @@ static int abx80x_rtc_set_time(struct device *dev, struct rtc_time *tm)
return -EIO; return -EIO;
} }
/* Clear the OF bit of Oscillator Status Register */
flags = i2c_smbus_read_byte_data(client, ABX8XX_REG_OSS);
if (flags < 0)
return flags;
err = i2c_smbus_write_byte_data(client, ABX8XX_REG_OSS,
flags & ~ABX8XX_OSS_OF);
if (err < 0) {
dev_err(&client->dev, "Unable to write oscillator status register\n");
return err;
}
return 0; return 0;
} }