blob: 24c688eec527f88dda6a73ec36cb48b05594bd23 [file] [log] [blame]
Alexandre Belloni1e3929e2015-11-02 23:48:32 +01001/*
2 * RTC driver for the Micro Crystal RV8803
3 *
4 * Copyright (C) 2015 Micro Crystal SA
5 *
6 * Alexandre Belloni <alexandre.belloni@free-electrons.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 */
13
14#include <linux/bcd.h>
15#include <linux/bitops.h>
Benoît Thébaudeaua1e98e02016-07-21 12:41:29 +020016#include <linux/log2.h>
Alexandre Belloni1e3929e2015-11-02 23:48:32 +010017#include <linux/i2c.h>
18#include <linux/interrupt.h>
19#include <linux/kernel.h>
20#include <linux/module.h>
21#include <linux/rtc.h>
22
Benoît Thébaudeaud5226492016-07-21 12:41:30 +020023#define RV8803_I2C_TRY_COUNT 4
24
Alexandre Belloni1e3929e2015-11-02 23:48:32 +010025#define RV8803_SEC 0x00
26#define RV8803_MIN 0x01
27#define RV8803_HOUR 0x02
28#define RV8803_WEEK 0x03
29#define RV8803_DAY 0x04
30#define RV8803_MONTH 0x05
31#define RV8803_YEAR 0x06
32#define RV8803_RAM 0x07
33#define RV8803_ALARM_MIN 0x08
34#define RV8803_ALARM_HOUR 0x09
35#define RV8803_ALARM_WEEK_OR_DAY 0x0A
36#define RV8803_EXT 0x0D
37#define RV8803_FLAG 0x0E
38#define RV8803_CTRL 0x0F
39
40#define RV8803_EXT_WADA BIT(6)
41
42#define RV8803_FLAG_V1F BIT(0)
43#define RV8803_FLAG_V2F BIT(1)
44#define RV8803_FLAG_AF BIT(3)
45#define RV8803_FLAG_TF BIT(4)
46#define RV8803_FLAG_UF BIT(5)
47
48#define RV8803_CTRL_RESET BIT(0)
49
50#define RV8803_CTRL_EIE BIT(2)
51#define RV8803_CTRL_AIE BIT(3)
52#define RV8803_CTRL_TIE BIT(4)
53#define RV8803_CTRL_UIE BIT(5)
54
55struct rv8803_data {
56 struct i2c_client *client;
57 struct rtc_device *rtc;
Oleksij Rempel9d1fa4c2016-02-04 13:45:20 +010058 struct mutex flags_lock;
Alexandre Belloni1e3929e2015-11-02 23:48:32 +010059 u8 ctrl;
60};
61
Benoît Thébaudeaud5226492016-07-21 12:41:30 +020062static int rv8803_read_reg(const struct i2c_client *client, u8 reg)
63{
64 int try = RV8803_I2C_TRY_COUNT;
65 s32 ret;
66
67 /*
68 * There is a 61µs window during which the RTC does not acknowledge I2C
69 * transfers. In that case, ensure that there are multiple attempts.
70 */
71 do
72 ret = i2c_smbus_read_byte_data(client, reg);
73 while ((ret == -ENXIO || ret == -EIO) && --try);
74 if (ret < 0)
75 dev_err(&client->dev, "Unable to read register 0x%02x\n", reg);
76
77 return ret;
78}
79
80static int rv8803_read_regs(const struct i2c_client *client,
81 u8 reg, u8 count, u8 *values)
82{
83 int try = RV8803_I2C_TRY_COUNT;
84 s32 ret;
85
86 do
87 ret = i2c_smbus_read_i2c_block_data(client, reg, count, values);
88 while ((ret == -ENXIO || ret == -EIO) && --try);
89 if (ret != count) {
90 dev_err(&client->dev,
91 "Unable to read registers 0x%02x..0x%02x\n",
92 reg, reg + count - 1);
93 return ret < 0 ? ret : -EIO;
94 }
95
96 return 0;
97}
98
99static int rv8803_write_reg(const struct i2c_client *client, u8 reg, u8 value)
100{
101 int try = RV8803_I2C_TRY_COUNT;
102 s32 ret;
103
104 do
105 ret = i2c_smbus_write_byte_data(client, reg, value);
106 while ((ret == -ENXIO || ret == -EIO) && --try);
107 if (ret)
108 dev_err(&client->dev, "Unable to write register 0x%02x\n", reg);
109
110 return ret;
111}
112
113static int rv8803_write_regs(const struct i2c_client *client,
114 u8 reg, u8 count, const u8 *values)
115{
116 int try = RV8803_I2C_TRY_COUNT;
117 s32 ret;
118
119 do
120 ret = i2c_smbus_write_i2c_block_data(client, reg, count,
121 values);
122 while ((ret == -ENXIO || ret == -EIO) && --try);
123 if (ret)
124 dev_err(&client->dev,
125 "Unable to write registers 0x%02x..0x%02x\n",
126 reg, reg + count - 1);
127
128 return ret;
129}
130
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100131static irqreturn_t rv8803_handle_irq(int irq, void *dev_id)
132{
133 struct i2c_client *client = dev_id;
134 struct rv8803_data *rv8803 = i2c_get_clientdata(client);
135 unsigned long events = 0;
Benoît Thébaudeaud5226492016-07-21 12:41:30 +0200136 int flags;
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100137
Oleksij Rempel9d1fa4c2016-02-04 13:45:20 +0100138 mutex_lock(&rv8803->flags_lock);
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100139
Benoît Thébaudeaud5226492016-07-21 12:41:30 +0200140 flags = rv8803_read_reg(client, RV8803_FLAG);
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100141 if (flags <= 0) {
Oleksij Rempel9d1fa4c2016-02-04 13:45:20 +0100142 mutex_unlock(&rv8803->flags_lock);
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100143 return IRQ_NONE;
144 }
145
146 if (flags & RV8803_FLAG_V1F)
147 dev_warn(&client->dev, "Voltage low, temperature compensation stopped.\n");
148
149 if (flags & RV8803_FLAG_V2F)
150 dev_warn(&client->dev, "Voltage low, data loss detected.\n");
151
152 if (flags & RV8803_FLAG_TF) {
153 flags &= ~RV8803_FLAG_TF;
154 rv8803->ctrl &= ~RV8803_CTRL_TIE;
155 events |= RTC_PF;
156 }
157
158 if (flags & RV8803_FLAG_AF) {
159 flags &= ~RV8803_FLAG_AF;
160 rv8803->ctrl &= ~RV8803_CTRL_AIE;
161 events |= RTC_AF;
162 }
163
164 if (flags & RV8803_FLAG_UF) {
165 flags &= ~RV8803_FLAG_UF;
166 rv8803->ctrl &= ~RV8803_CTRL_UIE;
167 events |= RTC_UF;
168 }
169
170 if (events) {
171 rtc_update_irq(rv8803->rtc, 1, events);
Benoît Thébaudeaud5226492016-07-21 12:41:30 +0200172 rv8803_write_reg(client, RV8803_FLAG, flags);
173 rv8803_write_reg(rv8803->client, RV8803_CTRL, rv8803->ctrl);
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100174 }
175
Oleksij Rempel9d1fa4c2016-02-04 13:45:20 +0100176 mutex_unlock(&rv8803->flags_lock);
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100177
178 return IRQ_HANDLED;
179}
180
181static int rv8803_get_time(struct device *dev, struct rtc_time *tm)
182{
183 struct rv8803_data *rv8803 = dev_get_drvdata(dev);
184 u8 date1[7];
185 u8 date2[7];
186 u8 *date = date1;
187 int ret, flags;
188
Benoît Thébaudeaud5226492016-07-21 12:41:30 +0200189 flags = rv8803_read_reg(rv8803->client, RV8803_FLAG);
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100190 if (flags < 0)
191 return flags;
192
193 if (flags & RV8803_FLAG_V2F) {
194 dev_warn(dev, "Voltage low, data is invalid.\n");
195 return -EINVAL;
196 }
197
Benoît Thébaudeaud5226492016-07-21 12:41:30 +0200198 ret = rv8803_read_regs(rv8803->client, RV8803_SEC, 7, date);
199 if (ret)
200 return ret;
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100201
202 if ((date1[RV8803_SEC] & 0x7f) == bin2bcd(59)) {
Benoît Thébaudeaud5226492016-07-21 12:41:30 +0200203 ret = rv8803_read_regs(rv8803->client, RV8803_SEC, 7, date2);
204 if (ret)
205 return ret;
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100206
207 if ((date2[RV8803_SEC] & 0x7f) != bin2bcd(59))
208 date = date2;
209 }
210
211 tm->tm_sec = bcd2bin(date[RV8803_SEC] & 0x7f);
212 tm->tm_min = bcd2bin(date[RV8803_MIN] & 0x7f);
213 tm->tm_hour = bcd2bin(date[RV8803_HOUR] & 0x3f);
Benoît Thébaudeaua1e98e02016-07-21 12:41:29 +0200214 tm->tm_wday = ilog2(date[RV8803_WEEK] & 0x7f);
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100215 tm->tm_mday = bcd2bin(date[RV8803_DAY] & 0x3f);
216 tm->tm_mon = bcd2bin(date[RV8803_MONTH] & 0x1f) - 1;
217 tm->tm_year = bcd2bin(date[RV8803_YEAR]) + 100;
218
Benoît Thébaudeau96acb252016-07-21 12:41:28 +0200219 return 0;
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100220}
221
222static int rv8803_set_time(struct device *dev, struct rtc_time *tm)
223{
224 struct rv8803_data *rv8803 = dev_get_drvdata(dev);
225 u8 date[7];
Benoît Thébaudeaud3700b62016-07-21 12:41:31 +0200226 int ctrl, flags, ret;
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100227
228 if ((tm->tm_year < 100) || (tm->tm_year > 199))
229 return -EINVAL;
230
Benoît Thébaudeaud3700b62016-07-21 12:41:31 +0200231 ctrl = rv8803_read_reg(rv8803->client, RV8803_CTRL);
232 if (ctrl < 0)
233 return ctrl;
234
235 /* Stop the clock */
236 ret = rv8803_write_reg(rv8803->client, RV8803_CTRL,
237 ctrl | RV8803_CTRL_RESET);
238 if (ret)
239 return ret;
240
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100241 date[RV8803_SEC] = bin2bcd(tm->tm_sec);
242 date[RV8803_MIN] = bin2bcd(tm->tm_min);
243 date[RV8803_HOUR] = bin2bcd(tm->tm_hour);
244 date[RV8803_WEEK] = 1 << (tm->tm_wday);
245 date[RV8803_DAY] = bin2bcd(tm->tm_mday);
246 date[RV8803_MONTH] = bin2bcd(tm->tm_mon + 1);
247 date[RV8803_YEAR] = bin2bcd(tm->tm_year - 100);
248
Benoît Thébaudeaud5226492016-07-21 12:41:30 +0200249 ret = rv8803_write_regs(rv8803->client, RV8803_SEC, 7, date);
250 if (ret)
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100251 return ret;
252
Benoît Thébaudeaud3700b62016-07-21 12:41:31 +0200253 /* Restart the clock */
254 ret = rv8803_write_reg(rv8803->client, RV8803_CTRL,
255 ctrl & ~RV8803_CTRL_RESET);
256 if (ret)
257 return ret;
258
Oleksij Rempel9d1fa4c2016-02-04 13:45:20 +0100259 mutex_lock(&rv8803->flags_lock);
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100260
Benoît Thébaudeaud5226492016-07-21 12:41:30 +0200261 flags = rv8803_read_reg(rv8803->client, RV8803_FLAG);
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100262 if (flags < 0) {
Oleksij Rempel9d1fa4c2016-02-04 13:45:20 +0100263 mutex_unlock(&rv8803->flags_lock);
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100264 return flags;
265 }
266
Benoît Thébaudeaud5226492016-07-21 12:41:30 +0200267 ret = rv8803_write_reg(rv8803->client, RV8803_FLAG,
268 flags & ~RV8803_FLAG_V2F);
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100269
Oleksij Rempel9d1fa4c2016-02-04 13:45:20 +0100270 mutex_unlock(&rv8803->flags_lock);
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100271
272 return ret;
273}
274
275static int rv8803_get_alarm(struct device *dev, struct rtc_wkalrm *alrm)
276{
277 struct rv8803_data *rv8803 = dev_get_drvdata(dev);
278 struct i2c_client *client = rv8803->client;
279 u8 alarmvals[3];
280 int flags, ret;
281
Benoît Thébaudeaud5226492016-07-21 12:41:30 +0200282 ret = rv8803_read_regs(client, RV8803_ALARM_MIN, 3, alarmvals);
283 if (ret)
284 return ret;
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100285
Benoît Thébaudeaud5226492016-07-21 12:41:30 +0200286 flags = rv8803_read_reg(client, RV8803_FLAG);
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100287 if (flags < 0)
288 return flags;
289
290 alrm->time.tm_sec = 0;
291 alrm->time.tm_min = bcd2bin(alarmvals[0] & 0x7f);
292 alrm->time.tm_hour = bcd2bin(alarmvals[1] & 0x3f);
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100293 alrm->time.tm_mday = bcd2bin(alarmvals[2] & 0x3f);
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100294
295 alrm->enabled = !!(rv8803->ctrl & RV8803_CTRL_AIE);
296 alrm->pending = (flags & RV8803_FLAG_AF) && alrm->enabled;
297
298 return 0;
299}
300
301static int rv8803_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
302{
303 struct i2c_client *client = to_i2c_client(dev);
304 struct rv8803_data *rv8803 = dev_get_drvdata(dev);
305 u8 alarmvals[3];
306 u8 ctrl[2];
307 int ret, err;
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100308
309 /* The alarm has no seconds, round up to nearest minute */
310 if (alrm->time.tm_sec) {
311 time64_t alarm_time = rtc_tm_to_time64(&alrm->time);
312
313 alarm_time += 60 - alrm->time.tm_sec;
314 rtc_time64_to_tm(alarm_time, &alrm->time);
315 }
316
Oleksij Rempel9d1fa4c2016-02-04 13:45:20 +0100317 mutex_lock(&rv8803->flags_lock);
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100318
Benoît Thébaudeaud5226492016-07-21 12:41:30 +0200319 ret = rv8803_read_regs(client, RV8803_FLAG, 2, ctrl);
320 if (ret) {
Oleksij Rempel9d1fa4c2016-02-04 13:45:20 +0100321 mutex_unlock(&rv8803->flags_lock);
Benoît Thébaudeaud5226492016-07-21 12:41:30 +0200322 return ret;
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100323 }
324
325 alarmvals[0] = bin2bcd(alrm->time.tm_min);
326 alarmvals[1] = bin2bcd(alrm->time.tm_hour);
327 alarmvals[2] = bin2bcd(alrm->time.tm_mday);
328
329 if (rv8803->ctrl & (RV8803_CTRL_AIE | RV8803_CTRL_UIE)) {
330 rv8803->ctrl &= ~(RV8803_CTRL_AIE | RV8803_CTRL_UIE);
Benoît Thébaudeaud5226492016-07-21 12:41:30 +0200331 err = rv8803_write_reg(rv8803->client, RV8803_CTRL,
332 rv8803->ctrl);
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100333 if (err) {
Oleksij Rempel9d1fa4c2016-02-04 13:45:20 +0100334 mutex_unlock(&rv8803->flags_lock);
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100335 return err;
336 }
337 }
338
339 ctrl[1] &= ~RV8803_FLAG_AF;
Benoît Thébaudeaud5226492016-07-21 12:41:30 +0200340 err = rv8803_write_reg(rv8803->client, RV8803_FLAG, ctrl[1]);
Oleksij Rempel9d1fa4c2016-02-04 13:45:20 +0100341 mutex_unlock(&rv8803->flags_lock);
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100342 if (err)
343 return err;
344
Benoît Thébaudeaud5226492016-07-21 12:41:30 +0200345 err = rv8803_write_regs(rv8803->client, RV8803_ALARM_MIN, 3, alarmvals);
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100346 if (err)
347 return err;
348
349 if (alrm->enabled) {
350 if (rv8803->rtc->uie_rtctimer.enabled)
351 rv8803->ctrl |= RV8803_CTRL_UIE;
352 if (rv8803->rtc->aie_timer.enabled)
353 rv8803->ctrl |= RV8803_CTRL_AIE;
354
Benoît Thébaudeaud5226492016-07-21 12:41:30 +0200355 err = rv8803_write_reg(rv8803->client, RV8803_CTRL,
356 rv8803->ctrl);
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100357 if (err)
358 return err;
359 }
360
361 return 0;
362}
363
364static int rv8803_alarm_irq_enable(struct device *dev, unsigned int enabled)
365{
366 struct i2c_client *client = to_i2c_client(dev);
367 struct rv8803_data *rv8803 = dev_get_drvdata(dev);
368 int ctrl, flags, err;
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100369
370 ctrl = rv8803->ctrl;
371
372 if (enabled) {
373 if (rv8803->rtc->uie_rtctimer.enabled)
374 ctrl |= RV8803_CTRL_UIE;
375 if (rv8803->rtc->aie_timer.enabled)
376 ctrl |= RV8803_CTRL_AIE;
377 } else {
378 if (!rv8803->rtc->uie_rtctimer.enabled)
379 ctrl &= ~RV8803_CTRL_UIE;
380 if (!rv8803->rtc->aie_timer.enabled)
381 ctrl &= ~RV8803_CTRL_AIE;
382 }
383
Oleksij Rempel9d1fa4c2016-02-04 13:45:20 +0100384 mutex_lock(&rv8803->flags_lock);
Benoît Thébaudeaud5226492016-07-21 12:41:30 +0200385 flags = rv8803_read_reg(client, RV8803_FLAG);
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100386 if (flags < 0) {
Oleksij Rempel9d1fa4c2016-02-04 13:45:20 +0100387 mutex_unlock(&rv8803->flags_lock);
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100388 return flags;
389 }
390 flags &= ~(RV8803_FLAG_AF | RV8803_FLAG_UF);
Benoît Thébaudeaud5226492016-07-21 12:41:30 +0200391 err = rv8803_write_reg(client, RV8803_FLAG, flags);
Oleksij Rempel9d1fa4c2016-02-04 13:45:20 +0100392 mutex_unlock(&rv8803->flags_lock);
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100393 if (err)
394 return err;
395
396 if (ctrl != rv8803->ctrl) {
397 rv8803->ctrl = ctrl;
Benoît Thébaudeaud5226492016-07-21 12:41:30 +0200398 err = rv8803_write_reg(client, RV8803_CTRL, rv8803->ctrl);
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100399 if (err)
400 return err;
401 }
402
403 return 0;
404}
405
406static int rv8803_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
407{
408 struct i2c_client *client = to_i2c_client(dev);
409 struct rv8803_data *rv8803 = dev_get_drvdata(dev);
410 int flags, ret = 0;
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100411
412 switch (cmd) {
413 case RTC_VL_READ:
Benoît Thébaudeaud5226492016-07-21 12:41:30 +0200414 flags = rv8803_read_reg(client, RV8803_FLAG);
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100415 if (flags < 0)
416 return flags;
417
418 if (flags & RV8803_FLAG_V1F)
419 dev_warn(&client->dev, "Voltage low, temperature compensation stopped.\n");
420
421 if (flags & RV8803_FLAG_V2F)
422 dev_warn(&client->dev, "Voltage low, data loss detected.\n");
423
424 flags &= RV8803_FLAG_V1F | RV8803_FLAG_V2F;
425
426 if (copy_to_user((void __user *)arg, &flags, sizeof(int)))
427 return -EFAULT;
428
429 return 0;
430
431 case RTC_VL_CLR:
Oleksij Rempel9d1fa4c2016-02-04 13:45:20 +0100432 mutex_lock(&rv8803->flags_lock);
Benoît Thébaudeaud5226492016-07-21 12:41:30 +0200433 flags = rv8803_read_reg(client, RV8803_FLAG);
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100434 if (flags < 0) {
Oleksij Rempel9d1fa4c2016-02-04 13:45:20 +0100435 mutex_unlock(&rv8803->flags_lock);
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100436 return flags;
437 }
438
439 flags &= ~(RV8803_FLAG_V1F | RV8803_FLAG_V2F);
Benoît Thébaudeaud5226492016-07-21 12:41:30 +0200440 ret = rv8803_write_reg(client, RV8803_FLAG, flags);
Oleksij Rempel9d1fa4c2016-02-04 13:45:20 +0100441 mutex_unlock(&rv8803->flags_lock);
Benoît Thébaudeaud5226492016-07-21 12:41:30 +0200442 if (ret)
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100443 return ret;
444
445 return 0;
446
447 default:
448 return -ENOIOCTLCMD;
449 }
450}
451
452static ssize_t rv8803_nvram_write(struct file *filp, struct kobject *kobj,
453 struct bin_attribute *attr,
454 char *buf, loff_t off, size_t count)
455{
456 struct device *dev = kobj_to_dev(kobj);
457 struct i2c_client *client = to_i2c_client(dev);
458 int ret;
459
Benoît Thébaudeaud5226492016-07-21 12:41:30 +0200460 ret = rv8803_write_reg(client, RV8803_RAM, buf[0]);
461 if (ret)
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100462 return ret;
463
464 return 1;
465}
466
467static ssize_t rv8803_nvram_read(struct file *filp, struct kobject *kobj,
468 struct bin_attribute *attr,
469 char *buf, loff_t off, size_t count)
470{
471 struct device *dev = kobj_to_dev(kobj);
472 struct i2c_client *client = to_i2c_client(dev);
473 int ret;
474
Benoît Thébaudeaud5226492016-07-21 12:41:30 +0200475 ret = rv8803_read_reg(client, RV8803_RAM);
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100476 if (ret < 0)
477 return ret;
478
479 buf[0] = ret;
480
481 return 1;
482}
483
484static struct bin_attribute rv8803_nvram_attr = {
485 .attr = {
486 .name = "nvram",
487 .mode = S_IRUGO | S_IWUSR,
488 },
489 .size = 1,
490 .read = rv8803_nvram_read,
491 .write = rv8803_nvram_write,
492};
493
494static struct rtc_class_ops rv8803_rtc_ops = {
495 .read_time = rv8803_get_time,
496 .set_time = rv8803_set_time,
497 .ioctl = rv8803_ioctl,
498};
499
500static int rv8803_probe(struct i2c_client *client,
501 const struct i2c_device_id *id)
502{
503 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
504 struct rv8803_data *rv8803;
Benoît Thébaudeaud5226492016-07-21 12:41:30 +0200505 int err, flags;
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100506
507 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
508 I2C_FUNC_SMBUS_I2C_BLOCK)) {
509 dev_err(&adapter->dev, "doesn't support I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_I2C_BLOCK\n");
510 return -EIO;
511 }
512
513 rv8803 = devm_kzalloc(&client->dev, sizeof(struct rv8803_data),
514 GFP_KERNEL);
515 if (!rv8803)
516 return -ENOMEM;
517
Oleksij Rempel9d1fa4c2016-02-04 13:45:20 +0100518 mutex_init(&rv8803->flags_lock);
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100519 rv8803->client = client;
520 i2c_set_clientdata(client, rv8803);
521
Benoît Thébaudeaud5226492016-07-21 12:41:30 +0200522 flags = rv8803_read_reg(client, RV8803_FLAG);
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100523 if (flags < 0)
524 return flags;
525
526 if (flags & RV8803_FLAG_V1F)
527 dev_warn(&client->dev, "Voltage low, temperature compensation stopped.\n");
528
529 if (flags & RV8803_FLAG_V2F)
530 dev_warn(&client->dev, "Voltage low, data loss detected.\n");
531
532 if (flags & RV8803_FLAG_AF)
533 dev_warn(&client->dev, "An alarm maybe have been missed.\n");
534
535 if (client->irq > 0) {
536 err = devm_request_threaded_irq(&client->dev, client->irq,
537 NULL, rv8803_handle_irq,
538 IRQF_TRIGGER_LOW | IRQF_ONESHOT,
539 "rv8803", client);
540 if (err) {
541 dev_warn(&client->dev, "unable to request IRQ, alarms disabled\n");
542 client->irq = 0;
543 } else {
544 rv8803_rtc_ops.read_alarm = rv8803_get_alarm;
545 rv8803_rtc_ops.set_alarm = rv8803_set_alarm;
546 rv8803_rtc_ops.alarm_irq_enable = rv8803_alarm_irq_enable;
547 }
548 }
549
550 rv8803->rtc = devm_rtc_device_register(&client->dev, client->name,
551 &rv8803_rtc_ops, THIS_MODULE);
552 if (IS_ERR(rv8803->rtc)) {
553 dev_err(&client->dev, "unable to register the class device\n");
554 return PTR_ERR(rv8803->rtc);
555 }
556
Benoît Thébaudeaud5226492016-07-21 12:41:30 +0200557 err = rv8803_write_reg(rv8803->client, RV8803_EXT, RV8803_EXT_WADA);
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100558 if (err)
559 return err;
560
561 err = device_create_bin_file(&client->dev, &rv8803_nvram_attr);
562 if (err)
563 return err;
564
565 rv8803->rtc->max_user_freq = 1;
566
567 return 0;
568}
569
570static int rv8803_remove(struct i2c_client *client)
571{
572 device_remove_bin_file(&client->dev, &rv8803_nvram_attr);
573
574 return 0;
575}
576
577static const struct i2c_device_id rv8803_id[] = {
578 { "rv8803", 0 },
Gregory CLEMENT78ef5f22015-12-11 12:43:05 +0100579 { "rx8900", 0 },
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100580 { }
581};
582MODULE_DEVICE_TABLE(i2c, rv8803_id);
583
584static struct i2c_driver rv8803_driver = {
585 .driver = {
586 .name = "rtc-rv8803",
587 },
588 .probe = rv8803_probe,
589 .remove = rv8803_remove,
590 .id_table = rv8803_id,
591};
592module_i2c_driver(rv8803_driver);
593
594MODULE_AUTHOR("Alexandre Belloni <alexandre.belloni@free-electrons.com>");
595MODULE_DESCRIPTION("Micro Crystal RV8803 RTC driver");
596MODULE_LICENSE("GPL v2");