diff options
author | Mylène Josserand <mylene.josserand@free-electrons.com> | 2016-03-21 13:06:10 -0400 |
---|---|---|
committer | Alexandre Belloni <alexandre.belloni@free-electrons.com> | 2016-03-24 21:41:13 -0400 |
commit | ee087744247c421c83abea7f01217bfd39b8f5a9 (patch) | |
tree | 19addc9c871e45976fec758034e4a5b407fb8daa /drivers/rtc | |
parent | 59a8383adb75459c9d6766656bccc05950b783ea (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.c | 33 |
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 | ||