blob: e59b8a54d9a7d3ca9c936ad05f3301cc29fba10a [file] [log] [blame]
Heiko Schocher52365232011-05-26 16:25:05 -07001/*
Michael Büschaba39d22016-03-04 22:38:45 +01002 * Micro Crystal RV-3029 rtc class driver
Heiko Schocher52365232011-05-26 16:25:05 -07003 *
4 * Author: Gregory Hermant <gregory.hermant@calao-systems.com>
Michael Büsch2dca3d92016-03-04 22:40:30 +01005 * Michael Buesch <m@bues.ch>
Heiko Schocher52365232011-05-26 16:25:05 -07006 *
7 * based on previously existing rtc class drivers
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
13 * NOTE: Currently this driver only supports the bare minimum for read
14 * and write the RTC and alarms. The extra features provided by this chip
15 * (trickle charger, eeprom, T° compensation) are unavailable.
16 */
17
18#include <linux/module.h>
19#include <linux/i2c.h>
20#include <linux/bcd.h>
21#include <linux/rtc.h>
Michael Büscha7f6e282016-03-04 22:40:55 +010022#include <linux/delay.h>
23#include <linux/of.h>
24
Heiko Schocher52365232011-05-26 16:25:05 -070025
26/* Register map */
27/* control section */
Michael Büschaba39d22016-03-04 22:38:45 +010028#define RV3029_ONOFF_CTRL 0x00
Michael Büsch7697de32016-03-04 22:39:49 +010029#define RV3029_ONOFF_CTRL_WE BIT(0)
30#define RV3029_ONOFF_CTRL_TE BIT(1)
31#define RV3029_ONOFF_CTRL_TAR BIT(2)
32#define RV3029_ONOFF_CTRL_EERE BIT(3)
33#define RV3029_ONOFF_CTRL_SRON BIT(4)
34#define RV3029_ONOFF_CTRL_TD0 BIT(5)
35#define RV3029_ONOFF_CTRL_TD1 BIT(6)
36#define RV3029_ONOFF_CTRL_CLKINT BIT(7)
Michael Büschaba39d22016-03-04 22:38:45 +010037#define RV3029_IRQ_CTRL 0x01
Michael Büsch7697de32016-03-04 22:39:49 +010038#define RV3029_IRQ_CTRL_AIE BIT(0)
39#define RV3029_IRQ_CTRL_TIE BIT(1)
40#define RV3029_IRQ_CTRL_V1IE BIT(2)
41#define RV3029_IRQ_CTRL_V2IE BIT(3)
42#define RV3029_IRQ_CTRL_SRIE BIT(4)
Michael Büschaba39d22016-03-04 22:38:45 +010043#define RV3029_IRQ_FLAGS 0x02
Michael Büsch7697de32016-03-04 22:39:49 +010044#define RV3029_IRQ_FLAGS_AF BIT(0)
45#define RV3029_IRQ_FLAGS_TF BIT(1)
46#define RV3029_IRQ_FLAGS_V1IF BIT(2)
47#define RV3029_IRQ_FLAGS_V2IF BIT(3)
48#define RV3029_IRQ_FLAGS_SRF BIT(4)
Michael Büschaba39d22016-03-04 22:38:45 +010049#define RV3029_STATUS 0x03
Michael Büsch7697de32016-03-04 22:39:49 +010050#define RV3029_STATUS_VLOW1 BIT(2)
51#define RV3029_STATUS_VLOW2 BIT(3)
52#define RV3029_STATUS_SR BIT(4)
53#define RV3029_STATUS_PON BIT(5)
54#define RV3029_STATUS_EEBUSY BIT(7)
Michael Büschaba39d22016-03-04 22:38:45 +010055#define RV3029_RST_CTRL 0x04
Michael Büsch7697de32016-03-04 22:39:49 +010056#define RV3029_RST_CTRL_SYSR BIT(4)
Michael Büschaba39d22016-03-04 22:38:45 +010057#define RV3029_CONTROL_SECTION_LEN 0x05
Heiko Schocher52365232011-05-26 16:25:05 -070058
59/* watch section */
Michael Büschaba39d22016-03-04 22:38:45 +010060#define RV3029_W_SEC 0x08
61#define RV3029_W_MINUTES 0x09
62#define RV3029_W_HOURS 0x0A
Michael Büsch7697de32016-03-04 22:39:49 +010063#define RV3029_REG_HR_12_24 BIT(6) /* 24h/12h mode */
64#define RV3029_REG_HR_PM BIT(5) /* PM/AM bit in 12h mode */
Michael Büschaba39d22016-03-04 22:38:45 +010065#define RV3029_W_DATE 0x0B
66#define RV3029_W_DAYS 0x0C
67#define RV3029_W_MONTHS 0x0D
68#define RV3029_W_YEARS 0x0E
69#define RV3029_WATCH_SECTION_LEN 0x07
Heiko Schocher52365232011-05-26 16:25:05 -070070
71/* alarm section */
Michael Büschaba39d22016-03-04 22:38:45 +010072#define RV3029_A_SC 0x10
73#define RV3029_A_MN 0x11
74#define RV3029_A_HR 0x12
75#define RV3029_A_DT 0x13
76#define RV3029_A_DW 0x14
77#define RV3029_A_MO 0x15
78#define RV3029_A_YR 0x16
79#define RV3029_ALARM_SECTION_LEN 0x07
Heiko Schocher52365232011-05-26 16:25:05 -070080
81/* timer section */
Michael Büschaba39d22016-03-04 22:38:45 +010082#define RV3029_TIMER_LOW 0x18
83#define RV3029_TIMER_HIGH 0x19
Heiko Schocher52365232011-05-26 16:25:05 -070084
85/* temperature section */
Michael Büschaba39d22016-03-04 22:38:45 +010086#define RV3029_TEMP_PAGE 0x20
Heiko Schocher52365232011-05-26 16:25:05 -070087
88/* eeprom data section */
Michael Büschaba39d22016-03-04 22:38:45 +010089#define RV3029_E2P_EEDATA1 0x28
90#define RV3029_E2P_EEDATA2 0x29
Michael Büsch7697de32016-03-04 22:39:49 +010091#define RV3029_E2PDATA_SECTION_LEN 0x02
Heiko Schocher52365232011-05-26 16:25:05 -070092
93/* eeprom control section */
Michael Büschaba39d22016-03-04 22:38:45 +010094#define RV3029_CONTROL_E2P_EECTRL 0x30
Michael Büsch7697de32016-03-04 22:39:49 +010095#define RV3029_EECTRL_THP BIT(0) /* temp scan interval */
96#define RV3029_EECTRL_THE BIT(1) /* thermometer enable */
97#define RV3029_EECTRL_FD0 BIT(2) /* CLKOUT */
98#define RV3029_EECTRL_FD1 BIT(3) /* CLKOUT */
99#define RV3029_TRICKLE_1K BIT(4) /* 1.5K resistance */
100#define RV3029_TRICKLE_5K BIT(5) /* 5K resistance */
101#define RV3029_TRICKLE_20K BIT(6) /* 20K resistance */
102#define RV3029_TRICKLE_80K BIT(7) /* 80K resistance */
103#define RV3029_TRICKLE_MASK (RV3029_TRICKLE_1K |\
104 RV3029_TRICKLE_5K |\
105 RV3029_TRICKLE_20K |\
106 RV3029_TRICKLE_80K)
107#define RV3029_TRICKLE_SHIFT 4
108#define RV3029_CONTROL_E2P_XOFFS 0x31 /* XTAL offset */
109#define RV3029_CONTROL_E2P_XOFFS_SIGN BIT(7) /* Sign: 1->pos, 0->neg */
110#define RV3029_CONTROL_E2P_QCOEF 0x32 /* XTAL temp drift coef */
111#define RV3029_CONTROL_E2P_TURNOVER 0x33 /* XTAL turnover temp (in *C) */
112#define RV3029_CONTROL_E2P_TOV_MASK 0x3F /* XTAL turnover temp mask */
Heiko Schocher52365232011-05-26 16:25:05 -0700113
114/* user ram section */
Michael Büschaba39d22016-03-04 22:38:45 +0100115#define RV3029_USR1_RAM_PAGE 0x38
116#define RV3029_USR1_SECTION_LEN 0x04
117#define RV3029_USR2_RAM_PAGE 0x3C
118#define RV3029_USR2_SECTION_LEN 0x04
Heiko Schocher52365232011-05-26 16:25:05 -0700119
120static int
Michael Büschaba39d22016-03-04 22:38:45 +0100121rv3029_i2c_read_regs(struct i2c_client *client, u8 reg, u8 *buf,
122 unsigned len)
Heiko Schocher52365232011-05-26 16:25:05 -0700123{
124 int ret;
125
Michael Büschaba39d22016-03-04 22:38:45 +0100126 if ((reg > RV3029_USR1_RAM_PAGE + 7) ||
127 (reg + len > RV3029_USR1_RAM_PAGE + 8))
Heiko Schocher52365232011-05-26 16:25:05 -0700128 return -EINVAL;
129
130 ret = i2c_smbus_read_i2c_block_data(client, reg, len, buf);
131 if (ret < 0)
132 return ret;
133 if (ret < len)
134 return -EIO;
135 return 0;
136}
137
138static int
Michael Büschaba39d22016-03-04 22:38:45 +0100139rv3029_i2c_write_regs(struct i2c_client *client, u8 reg, u8 const buf[],
140 unsigned len)
Heiko Schocher52365232011-05-26 16:25:05 -0700141{
Michael Büschaba39d22016-03-04 22:38:45 +0100142 if ((reg > RV3029_USR1_RAM_PAGE + 7) ||
143 (reg + len > RV3029_USR1_RAM_PAGE + 8))
Heiko Schocher52365232011-05-26 16:25:05 -0700144 return -EINVAL;
145
146 return i2c_smbus_write_i2c_block_data(client, reg, len, buf);
147}
148
149static int
Michael Büsch2dca3d92016-03-04 22:40:30 +0100150rv3029_i2c_update_bits(struct i2c_client *client, u8 reg, u8 mask, u8 set)
151{
152 u8 buf;
153 int ret;
154
155 ret = rv3029_i2c_read_regs(client, reg, &buf, 1);
156 if (ret < 0)
157 return ret;
158 buf &= ~mask;
159 buf |= set & mask;
160 ret = rv3029_i2c_write_regs(client, reg, &buf, 1);
161 if (ret < 0)
162 return ret;
163
164 return 0;
165}
166
167static int
Michael Büschaba39d22016-03-04 22:38:45 +0100168rv3029_i2c_get_sr(struct i2c_client *client, u8 *buf)
Heiko Schocher52365232011-05-26 16:25:05 -0700169{
Michael Büschaba39d22016-03-04 22:38:45 +0100170 int ret = rv3029_i2c_read_regs(client, RV3029_STATUS, buf, 1);
Heiko Schocher52365232011-05-26 16:25:05 -0700171
172 if (ret < 0)
173 return -EIO;
174 dev_dbg(&client->dev, "status = 0x%.2x (%d)\n", buf[0], buf[0]);
175 return 0;
176}
177
178static int
Michael Büschaba39d22016-03-04 22:38:45 +0100179rv3029_i2c_set_sr(struct i2c_client *client, u8 val)
Heiko Schocher52365232011-05-26 16:25:05 -0700180{
181 u8 buf[1];
182 int sr;
183
184 buf[0] = val;
Michael Büschaba39d22016-03-04 22:38:45 +0100185 sr = rv3029_i2c_write_regs(client, RV3029_STATUS, buf, 1);
Heiko Schocher52365232011-05-26 16:25:05 -0700186 dev_dbg(&client->dev, "status = 0x%.2x (%d)\n", buf[0], buf[0]);
187 if (sr < 0)
188 return -EIO;
189 return 0;
190}
191
Michael Büscha7f6e282016-03-04 22:40:55 +0100192static int rv3029_eeprom_busywait(struct i2c_client *client)
193{
194 int i, ret;
195 u8 sr;
196
197 for (i = 100; i > 0; i--) {
198 ret = rv3029_i2c_get_sr(client, &sr);
199 if (ret < 0)
200 break;
201 if (!(sr & RV3029_STATUS_EEBUSY))
202 break;
203 usleep_range(1000, 10000);
204 }
205 if (i <= 0) {
206 dev_err(&client->dev, "EEPROM busy wait timeout.\n");
207 return -ETIMEDOUT;
208 }
209
210 return ret;
211}
212
213static int rv3029_eeprom_exit(struct i2c_client *client)
214{
215 /* Re-enable eeprom refresh */
216 return rv3029_i2c_update_bits(client, RV3029_ONOFF_CTRL,
217 RV3029_ONOFF_CTRL_EERE,
218 RV3029_ONOFF_CTRL_EERE);
219}
220
221static int rv3029_eeprom_enter(struct i2c_client *client)
222{
223 int ret;
224 u8 sr;
225
226 /* Check whether we are in the allowed voltage range. */
227 ret = rv3029_i2c_get_sr(client, &sr);
228 if (ret < 0)
229 return ret;
230 if (sr & (RV3029_STATUS_VLOW1 | RV3029_STATUS_VLOW2)) {
231 /* We clear the bits and retry once just in case
232 * we had a brown out in early startup.
233 */
234 sr &= ~RV3029_STATUS_VLOW1;
235 sr &= ~RV3029_STATUS_VLOW2;
236 ret = rv3029_i2c_set_sr(client, sr);
237 if (ret < 0)
238 return ret;
239 usleep_range(1000, 10000);
240 ret = rv3029_i2c_get_sr(client, &sr);
241 if (ret < 0)
242 return ret;
243 if (sr & (RV3029_STATUS_VLOW1 | RV3029_STATUS_VLOW2)) {
244 dev_err(&client->dev,
245 "Supply voltage is too low to safely access the EEPROM.\n");
246 return -ENODEV;
247 }
248 }
249
250 /* Disable eeprom refresh. */
251 ret = rv3029_i2c_update_bits(client, RV3029_ONOFF_CTRL,
252 RV3029_ONOFF_CTRL_EERE, 0);
253 if (ret < 0)
254 return ret;
255
256 /* Wait for any previous eeprom accesses to finish. */
257 ret = rv3029_eeprom_busywait(client);
258 if (ret < 0)
259 rv3029_eeprom_exit(client);
260
261 return ret;
262}
263
264static int rv3029_eeprom_read(struct i2c_client *client, u8 reg,
265 u8 buf[], size_t len)
266{
267 int ret, err;
268
269 err = rv3029_eeprom_enter(client);
270 if (err < 0)
271 return err;
272
273 ret = rv3029_i2c_read_regs(client, reg, buf, len);
274
275 err = rv3029_eeprom_exit(client);
276 if (err < 0)
277 return err;
278
279 return ret;
280}
281
282static int rv3029_eeprom_write(struct i2c_client *client, u8 reg,
283 u8 const buf[], size_t len)
284{
285 int ret, err;
286 size_t i;
287 u8 tmp;
288
289 err = rv3029_eeprom_enter(client);
290 if (err < 0)
291 return err;
292
293 for (i = 0; i < len; i++, reg++) {
294 ret = rv3029_i2c_read_regs(client, reg, &tmp, 1);
295 if (ret < 0)
296 break;
297 if (tmp != buf[i]) {
298 ret = rv3029_i2c_write_regs(client, reg, &buf[i], 1);
299 if (ret < 0)
300 break;
301 }
302 ret = rv3029_eeprom_busywait(client);
303 if (ret < 0)
304 break;
305 }
306
307 err = rv3029_eeprom_exit(client);
308 if (err < 0)
309 return err;
310
311 return ret;
312}
313
Heiko Schocher52365232011-05-26 16:25:05 -0700314static int
Michael Büschaba39d22016-03-04 22:38:45 +0100315rv3029_i2c_read_time(struct i2c_client *client, struct rtc_time *tm)
Heiko Schocher52365232011-05-26 16:25:05 -0700316{
317 u8 buf[1];
318 int ret;
Michael Büschaba39d22016-03-04 22:38:45 +0100319 u8 regs[RV3029_WATCH_SECTION_LEN] = { 0, };
Heiko Schocher52365232011-05-26 16:25:05 -0700320
Michael Büschaba39d22016-03-04 22:38:45 +0100321 ret = rv3029_i2c_get_sr(client, buf);
Heiko Schocher52365232011-05-26 16:25:05 -0700322 if (ret < 0) {
323 dev_err(&client->dev, "%s: reading SR failed\n", __func__);
324 return -EIO;
325 }
326
Michael Büschaba39d22016-03-04 22:38:45 +0100327 ret = rv3029_i2c_read_regs(client, RV3029_W_SEC, regs,
328 RV3029_WATCH_SECTION_LEN);
Heiko Schocher52365232011-05-26 16:25:05 -0700329 if (ret < 0) {
330 dev_err(&client->dev, "%s: reading RTC section failed\n",
331 __func__);
332 return ret;
333 }
334
Michael Büschaba39d22016-03-04 22:38:45 +0100335 tm->tm_sec = bcd2bin(regs[RV3029_W_SEC-RV3029_W_SEC]);
336 tm->tm_min = bcd2bin(regs[RV3029_W_MINUTES-RV3029_W_SEC]);
Heiko Schocher52365232011-05-26 16:25:05 -0700337
338 /* HR field has a more complex interpretation */
339 {
Michael Büschaba39d22016-03-04 22:38:45 +0100340 const u8 _hr = regs[RV3029_W_HOURS-RV3029_W_SEC];
341
342 if (_hr & RV3029_REG_HR_12_24) {
Heiko Schocher52365232011-05-26 16:25:05 -0700343 /* 12h format */
344 tm->tm_hour = bcd2bin(_hr & 0x1f);
Michael Büschaba39d22016-03-04 22:38:45 +0100345 if (_hr & RV3029_REG_HR_PM) /* PM flag set */
Heiko Schocher52365232011-05-26 16:25:05 -0700346 tm->tm_hour += 12;
347 } else /* 24h format */
348 tm->tm_hour = bcd2bin(_hr & 0x3f);
349 }
350
Michael Büschaba39d22016-03-04 22:38:45 +0100351 tm->tm_mday = bcd2bin(regs[RV3029_W_DATE-RV3029_W_SEC]);
352 tm->tm_mon = bcd2bin(regs[RV3029_W_MONTHS-RV3029_W_SEC]) - 1;
353 tm->tm_year = bcd2bin(regs[RV3029_W_YEARS-RV3029_W_SEC]) + 100;
354 tm->tm_wday = bcd2bin(regs[RV3029_W_DAYS-RV3029_W_SEC]) - 1;
Heiko Schocher52365232011-05-26 16:25:05 -0700355
356 return 0;
357}
358
Michael Büschaba39d22016-03-04 22:38:45 +0100359static int rv3029_rtc_read_time(struct device *dev, struct rtc_time *tm)
Heiko Schocher52365232011-05-26 16:25:05 -0700360{
Michael Büschaba39d22016-03-04 22:38:45 +0100361 return rv3029_i2c_read_time(to_i2c_client(dev), tm);
Heiko Schocher52365232011-05-26 16:25:05 -0700362}
363
364static int
Michael Büschaba39d22016-03-04 22:38:45 +0100365rv3029_i2c_read_alarm(struct i2c_client *client, struct rtc_wkalrm *alarm)
Heiko Schocher52365232011-05-26 16:25:05 -0700366{
367 struct rtc_time *const tm = &alarm->time;
368 int ret;
369 u8 regs[8];
370
Michael Büschaba39d22016-03-04 22:38:45 +0100371 ret = rv3029_i2c_get_sr(client, regs);
Heiko Schocher52365232011-05-26 16:25:05 -0700372 if (ret < 0) {
373 dev_err(&client->dev, "%s: reading SR failed\n", __func__);
374 return -EIO;
375 }
376
Michael Büschaba39d22016-03-04 22:38:45 +0100377 ret = rv3029_i2c_read_regs(client, RV3029_A_SC, regs,
378 RV3029_ALARM_SECTION_LEN);
Heiko Schocher52365232011-05-26 16:25:05 -0700379
380 if (ret < 0) {
381 dev_err(&client->dev, "%s: reading alarm section failed\n",
382 __func__);
383 return ret;
384 }
385
Michael Büschaba39d22016-03-04 22:38:45 +0100386 tm->tm_sec = bcd2bin(regs[RV3029_A_SC-RV3029_A_SC] & 0x7f);
387 tm->tm_min = bcd2bin(regs[RV3029_A_MN-RV3029_A_SC] & 0x7f);
388 tm->tm_hour = bcd2bin(regs[RV3029_A_HR-RV3029_A_SC] & 0x3f);
389 tm->tm_mday = bcd2bin(regs[RV3029_A_DT-RV3029_A_SC] & 0x3f);
390 tm->tm_mon = bcd2bin(regs[RV3029_A_MO-RV3029_A_SC] & 0x1f) - 1;
391 tm->tm_year = bcd2bin(regs[RV3029_A_YR-RV3029_A_SC] & 0x7f) + 100;
392 tm->tm_wday = bcd2bin(regs[RV3029_A_DW-RV3029_A_SC] & 0x07) - 1;
Heiko Schocher52365232011-05-26 16:25:05 -0700393
394 return 0;
395}
396
397static int
Michael Büschaba39d22016-03-04 22:38:45 +0100398rv3029_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
Heiko Schocher52365232011-05-26 16:25:05 -0700399{
Michael Büschaba39d22016-03-04 22:38:45 +0100400 return rv3029_i2c_read_alarm(to_i2c_client(dev), alarm);
Heiko Schocher52365232011-05-26 16:25:05 -0700401}
402
Michael Büschaba39d22016-03-04 22:38:45 +0100403static int rv3029_rtc_i2c_alarm_set_irq(struct i2c_client *client,
Heiko Schocher52365232011-05-26 16:25:05 -0700404 int enable)
405{
406 int ret;
Heiko Schocher52365232011-05-26 16:25:05 -0700407
Michael Büsch2dca3d92016-03-04 22:40:30 +0100408 /* enable/disable AIE irq */
409 ret = rv3029_i2c_update_bits(client, RV3029_IRQ_CTRL,
410 RV3029_IRQ_CTRL_AIE,
411 (enable ? RV3029_IRQ_CTRL_AIE : 0));
Heiko Schocher52365232011-05-26 16:25:05 -0700412 if (ret < 0) {
Michael Büsch2dca3d92016-03-04 22:40:30 +0100413 dev_err(&client->dev, "can't update INT reg\n");
Heiko Schocher52365232011-05-26 16:25:05 -0700414 return ret;
415 }
416
417 return 0;
418}
419
Michael Büschaba39d22016-03-04 22:38:45 +0100420static int rv3029_rtc_i2c_set_alarm(struct i2c_client *client,
421 struct rtc_wkalrm *alarm)
Heiko Schocher52365232011-05-26 16:25:05 -0700422{
423 struct rtc_time *const tm = &alarm->time;
424 int ret;
425 u8 regs[8];
426
427 /*
428 * The clock has an 8 bit wide bcd-coded register (they never learn)
429 * for the year. tm_year is an offset from 1900 and we are interested
430 * in the 2000-2099 range, so any value less than 100 is invalid.
431 */
432 if (tm->tm_year < 100)
433 return -EINVAL;
434
Michael Büschaba39d22016-03-04 22:38:45 +0100435 ret = rv3029_i2c_get_sr(client, regs);
Heiko Schocher52365232011-05-26 16:25:05 -0700436 if (ret < 0) {
437 dev_err(&client->dev, "%s: reading SR failed\n", __func__);
438 return -EIO;
439 }
Michael Büschaba39d22016-03-04 22:38:45 +0100440 regs[RV3029_A_SC-RV3029_A_SC] = bin2bcd(tm->tm_sec & 0x7f);
441 regs[RV3029_A_MN-RV3029_A_SC] = bin2bcd(tm->tm_min & 0x7f);
442 regs[RV3029_A_HR-RV3029_A_SC] = bin2bcd(tm->tm_hour & 0x3f);
443 regs[RV3029_A_DT-RV3029_A_SC] = bin2bcd(tm->tm_mday & 0x3f);
444 regs[RV3029_A_MO-RV3029_A_SC] = bin2bcd((tm->tm_mon & 0x1f) - 1);
445 regs[RV3029_A_DW-RV3029_A_SC] = bin2bcd((tm->tm_wday & 7) - 1);
446 regs[RV3029_A_YR-RV3029_A_SC] = bin2bcd((tm->tm_year & 0x7f) - 100);
Heiko Schocher52365232011-05-26 16:25:05 -0700447
Michael Büschaba39d22016-03-04 22:38:45 +0100448 ret = rv3029_i2c_write_regs(client, RV3029_A_SC, regs,
449 RV3029_ALARM_SECTION_LEN);
Heiko Schocher52365232011-05-26 16:25:05 -0700450 if (ret < 0)
451 return ret;
452
453 if (alarm->enabled) {
Heiko Schocher52365232011-05-26 16:25:05 -0700454 /* clear AF flag */
Michael Büsch2dca3d92016-03-04 22:40:30 +0100455 ret = rv3029_i2c_update_bits(client, RV3029_IRQ_FLAGS,
456 RV3029_IRQ_FLAGS_AF, 0);
Heiko Schocher52365232011-05-26 16:25:05 -0700457 if (ret < 0) {
Michael Büsch2dca3d92016-03-04 22:40:30 +0100458 dev_err(&client->dev, "can't clear alarm flag\n");
Heiko Schocher52365232011-05-26 16:25:05 -0700459 return ret;
460 }
461 /* enable AIE irq */
Michael Büschaba39d22016-03-04 22:38:45 +0100462 ret = rv3029_rtc_i2c_alarm_set_irq(client, 1);
Heiko Schocher52365232011-05-26 16:25:05 -0700463 if (ret)
464 return ret;
465
466 dev_dbg(&client->dev, "alarm IRQ armed\n");
467 } else {
468 /* disable AIE irq */
Michael Büschaba39d22016-03-04 22:38:45 +0100469 ret = rv3029_rtc_i2c_alarm_set_irq(client, 0);
Heiko Schocher52365232011-05-26 16:25:05 -0700470 if (ret)
471 return ret;
472
473 dev_dbg(&client->dev, "alarm IRQ disabled\n");
474 }
475
476 return 0;
477}
478
Michael Büschaba39d22016-03-04 22:38:45 +0100479static int rv3029_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
Heiko Schocher52365232011-05-26 16:25:05 -0700480{
Michael Büschaba39d22016-03-04 22:38:45 +0100481 return rv3029_rtc_i2c_set_alarm(to_i2c_client(dev), alarm);
Heiko Schocher52365232011-05-26 16:25:05 -0700482}
483
484static int
Michael Büschaba39d22016-03-04 22:38:45 +0100485rv3029_i2c_set_time(struct i2c_client *client, struct rtc_time const *tm)
Heiko Schocher52365232011-05-26 16:25:05 -0700486{
487 u8 regs[8];
488 int ret;
489
490 /*
491 * The clock has an 8 bit wide bcd-coded register (they never learn)
492 * for the year. tm_year is an offset from 1900 and we are interested
493 * in the 2000-2099 range, so any value less than 100 is invalid.
494 */
495 if (tm->tm_year < 100)
496 return -EINVAL;
497
Michael Büschaba39d22016-03-04 22:38:45 +0100498 regs[RV3029_W_SEC-RV3029_W_SEC] = bin2bcd(tm->tm_sec);
499 regs[RV3029_W_MINUTES-RV3029_W_SEC] = bin2bcd(tm->tm_min);
500 regs[RV3029_W_HOURS-RV3029_W_SEC] = bin2bcd(tm->tm_hour);
501 regs[RV3029_W_DATE-RV3029_W_SEC] = bin2bcd(tm->tm_mday);
502 regs[RV3029_W_MONTHS-RV3029_W_SEC] = bin2bcd(tm->tm_mon+1);
503 regs[RV3029_W_DAYS-RV3029_W_SEC] = bin2bcd((tm->tm_wday & 7)+1);
504 regs[RV3029_W_YEARS-RV3029_W_SEC] = bin2bcd(tm->tm_year - 100);
Heiko Schocher52365232011-05-26 16:25:05 -0700505
Michael Büschaba39d22016-03-04 22:38:45 +0100506 ret = rv3029_i2c_write_regs(client, RV3029_W_SEC, regs,
507 RV3029_WATCH_SECTION_LEN);
Heiko Schocher52365232011-05-26 16:25:05 -0700508 if (ret < 0)
509 return ret;
510
Michael Büschaba39d22016-03-04 22:38:45 +0100511 ret = rv3029_i2c_get_sr(client, regs);
Heiko Schocher52365232011-05-26 16:25:05 -0700512 if (ret < 0) {
513 dev_err(&client->dev, "%s: reading SR failed\n", __func__);
514 return ret;
515 }
516 /* clear PON bit */
Michael Büschaba39d22016-03-04 22:38:45 +0100517 ret = rv3029_i2c_set_sr(client, (regs[0] & ~RV3029_STATUS_PON));
Heiko Schocher52365232011-05-26 16:25:05 -0700518 if (ret < 0) {
519 dev_err(&client->dev, "%s: reading SR failed\n", __func__);
520 return ret;
521 }
522
523 return 0;
524}
525
Michael Büschaba39d22016-03-04 22:38:45 +0100526static int rv3029_rtc_set_time(struct device *dev, struct rtc_time *tm)
Heiko Schocher52365232011-05-26 16:25:05 -0700527{
Michael Büschaba39d22016-03-04 22:38:45 +0100528 return rv3029_i2c_set_time(to_i2c_client(dev), tm);
Heiko Schocher52365232011-05-26 16:25:05 -0700529}
530
Michael Büschaba39d22016-03-04 22:38:45 +0100531static const struct rtc_class_ops rv3029_rtc_ops = {
532 .read_time = rv3029_rtc_read_time,
533 .set_time = rv3029_rtc_set_time,
534 .read_alarm = rv3029_rtc_read_alarm,
535 .set_alarm = rv3029_rtc_set_alarm,
Heiko Schocher52365232011-05-26 16:25:05 -0700536};
537
Michael Büschaba39d22016-03-04 22:38:45 +0100538static struct i2c_device_id rv3029_id[] = {
Michael Büschbaba6232016-03-04 22:39:17 +0100539 { "rv3029", 0 },
Heiko Schocher52365232011-05-26 16:25:05 -0700540 { "rv3029c2", 0 },
541 { }
542};
Michael Büschaba39d22016-03-04 22:38:45 +0100543MODULE_DEVICE_TABLE(i2c, rv3029_id);
Heiko Schocher52365232011-05-26 16:25:05 -0700544
Michael Büschaba39d22016-03-04 22:38:45 +0100545static int rv3029_probe(struct i2c_client *client,
546 const struct i2c_device_id *id)
Heiko Schocher52365232011-05-26 16:25:05 -0700547{
548 struct rtc_device *rtc;
549 int rc = 0;
550 u8 buf[1];
551
552 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_EMUL))
553 return -ENODEV;
554
Michael Büschaba39d22016-03-04 22:38:45 +0100555 rc = rv3029_i2c_get_sr(client, buf);
Gregory Hermant67ab2442014-04-03 14:50:17 -0700556 if (rc < 0) {
557 dev_err(&client->dev, "reading status failed\n");
558 return rc;
559 }
560
Jingoo Han3d7068c2013-04-29 16:19:48 -0700561 rtc = devm_rtc_device_register(&client->dev, client->name,
Michael Büschaba39d22016-03-04 22:38:45 +0100562 &rv3029_rtc_ops, THIS_MODULE);
Heiko Schocher52365232011-05-26 16:25:05 -0700563
564 if (IS_ERR(rtc))
565 return PTR_ERR(rtc);
566
567 i2c_set_clientdata(client, rtc);
568
Heiko Schocher52365232011-05-26 16:25:05 -0700569 return 0;
Heiko Schocher52365232011-05-26 16:25:05 -0700570}
571
Michael Büschaba39d22016-03-04 22:38:45 +0100572static struct i2c_driver rv3029_driver = {
Heiko Schocher52365232011-05-26 16:25:05 -0700573 .driver = {
574 .name = "rtc-rv3029c2",
575 },
Michael Büschaba39d22016-03-04 22:38:45 +0100576 .probe = rv3029_probe,
577 .id_table = rv3029_id,
Heiko Schocher52365232011-05-26 16:25:05 -0700578};
579
Michael Büschaba39d22016-03-04 22:38:45 +0100580module_i2c_driver(rv3029_driver);
Heiko Schocher52365232011-05-26 16:25:05 -0700581
582MODULE_AUTHOR("Gregory Hermant <gregory.hermant@calao-systems.com>");
Michael Büsch2dca3d92016-03-04 22:40:30 +0100583MODULE_AUTHOR("Michael Buesch <m@bues.ch>");
Michael Büschaba39d22016-03-04 22:38:45 +0100584MODULE_DESCRIPTION("Micro Crystal RV3029 RTC driver");
Heiko Schocher52365232011-05-26 16:25:05 -0700585MODULE_LICENSE("GPL");