aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc
diff options
context:
space:
mode:
authorMylène Josserand <mylene.josserand@free-electrons.com>2016-03-21 13:06:10 -0400
committerAlexandre Belloni <alexandre.belloni@free-electrons.com>2016-03-24 21:41:13 -0400
commitee087744247c421c83abea7f01217bfd39b8f5a9 (patch)
tree19addc9c871e45976fec758034e4a5b407fb8daa /drivers/rtc
parent59a8383adb75459c9d6766656bccc05950b783ea (diff)
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>
Diffstat (limited to 'drivers/rtc')
-rw-r--r--drivers/rtc/rtc-abx80x.c33
1 files changed, 31 insertions, 2 deletions
diff --git a/drivers/rtc/rtc-abx80x.c b/drivers/rtc/rtc-abx80x.c
index 0e4c9a0989d1..ba0d61934d35 100644
--- a/drivers/rtc/rtc-abx80x.c
+++ b/drivers/rtc/rtc-abx80x.c
@@ -58,6 +58,7 @@
58#define ABX8XX_OSC_OSEL BIT(7) 58#define ABX8XX_OSC_OSEL BIT(7)
59 59
60#define ABX8XX_REG_OSS 0x1d 60#define ABX8XX_REG_OSS 0x1d
61#define ABX8XX_OSS_OF BIT(1)
61#define ABX8XX_OSS_OMODE BIT(4) 62#define ABX8XX_OSS_OMODE BIT(4)
62 63
63#define ABX8XX_REG_CFG_KEY 0x1f 64#define ABX8XX_REG_CFG_KEY 0x1f
@@ -138,7 +139,23 @@ static int abx80x_rtc_read_time(struct device *dev, struct rtc_time *tm)
138{ 139{
139 struct i2c_client *client = to_i2c_client(dev); 140 struct i2c_client *client = to_i2c_client(dev);
140 unsigned char buf[8]; 141 unsigned char buf[8];
141 int err; 142 int err, flags, rc_mode = 0;
143
144 /* Read the Oscillator Failure only in XT mode */
145 rc_mode = abx80x_is_rc_mode(client);
146 if (rc_mode < 0)
147 return rc_mode;
148
149 if (!rc_mode) {
150 flags = i2c_smbus_read_byte_data(client, ABX8XX_REG_OSS);
151 if (flags < 0)
152 return flags;
153
154 if (flags & ABX8XX_OSS_OF) {
155 dev_err(dev, "Oscillator failure, data is invalid.\n");
156 return -EINVAL;
157 }
158 }
142 159
143 err = i2c_smbus_read_i2c_block_data(client, ABX8XX_REG_HTH, 160 err = i2c_smbus_read_i2c_block_data(client, ABX8XX_REG_HTH,
144 sizeof(buf), buf); 161 sizeof(buf), buf);
@@ -166,7 +183,7 @@ static int abx80x_rtc_set_time(struct device *dev, struct rtc_time *tm)
166{ 183{
167 struct i2c_client *client = to_i2c_client(dev); 184 struct i2c_client *client = to_i2c_client(dev);
168 unsigned char buf[8]; 185 unsigned char buf[8];
169 int err; 186 int err, flags;
170 187
171 if (tm->tm_year < 100) 188 if (tm->tm_year < 100)
172 return -EINVAL; 189 return -EINVAL;
@@ -187,6 +204,18 @@ static int abx80x_rtc_set_time(struct device *dev, struct rtc_time *tm)
187 return -EIO; 204 return -EIO;
188 } 205 }
189 206
207 /* Clear the OF bit of Oscillator Status Register */
208 flags = i2c_smbus_read_byte_data(client, ABX8XX_REG_OSS);
209 if (flags < 0)
210 return flags;
211
212 err = i2c_smbus_write_byte_data(client, ABX8XX_REG_OSS,
213 flags & ~ABX8XX_OSS_OF);
214 if (err < 0) {
215 dev_err(&client->dev, "Unable to write oscillator status register\n");
216 return err;
217 }
218
190 return 0; 219 return 0;
191} 220}
192 221