blob: 09ab5cb1fa8a5c1753dca525e6d2afc3181f634c [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];
226 int flags, ret;
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100227
228 if ((tm->tm_year < 100) || (tm->tm_year > 199))
229 return -EINVAL;
230
231 date[RV8803_SEC] = bin2bcd(tm->tm_sec);
232 date[RV8803_MIN] = bin2bcd(tm->tm_min);
233 date[RV8803_HOUR] = bin2bcd(tm->tm_hour);
234 date[RV8803_WEEK] = 1 << (tm->tm_wday);
235 date[RV8803_DAY] = bin2bcd(tm->tm_mday);
236 date[RV8803_MONTH] = bin2bcd(tm->tm_mon + 1);
237 date[RV8803_YEAR] = bin2bcd(tm->tm_year - 100);
238
Benoît Thébaudeaud5226492016-07-21 12:41:30 +0200239 ret = rv8803_write_regs(rv8803->client, RV8803_SEC, 7, date);
240 if (ret)
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100241 return ret;
242
Oleksij Rempel9d1fa4c2016-02-04 13:45:20 +0100243 mutex_lock(&rv8803->flags_lock);
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100244
Benoît Thébaudeaud5226492016-07-21 12:41:30 +0200245 flags = rv8803_read_reg(rv8803->client, RV8803_FLAG);
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100246 if (flags < 0) {
Oleksij Rempel9d1fa4c2016-02-04 13:45:20 +0100247 mutex_unlock(&rv8803->flags_lock);
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100248 return flags;
249 }
250
Benoît Thébaudeaud5226492016-07-21 12:41:30 +0200251 ret = rv8803_write_reg(rv8803->client, RV8803_FLAG,
252 flags & ~RV8803_FLAG_V2F);
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100253
Oleksij Rempel9d1fa4c2016-02-04 13:45:20 +0100254 mutex_unlock(&rv8803->flags_lock);
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100255
256 return ret;
257}
258
259static int rv8803_get_alarm(struct device *dev, struct rtc_wkalrm *alrm)
260{
261 struct rv8803_data *rv8803 = dev_get_drvdata(dev);
262 struct i2c_client *client = rv8803->client;
263 u8 alarmvals[3];
264 int flags, ret;
265
Benoît Thébaudeaud5226492016-07-21 12:41:30 +0200266 ret = rv8803_read_regs(client, RV8803_ALARM_MIN, 3, alarmvals);
267 if (ret)
268 return ret;
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100269
Benoît Thébaudeaud5226492016-07-21 12:41:30 +0200270 flags = rv8803_read_reg(client, RV8803_FLAG);
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100271 if (flags < 0)
272 return flags;
273
274 alrm->time.tm_sec = 0;
275 alrm->time.tm_min = bcd2bin(alarmvals[0] & 0x7f);
276 alrm->time.tm_hour = bcd2bin(alarmvals[1] & 0x3f);
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100277 alrm->time.tm_mday = bcd2bin(alarmvals[2] & 0x3f);
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100278
279 alrm->enabled = !!(rv8803->ctrl & RV8803_CTRL_AIE);
280 alrm->pending = (flags & RV8803_FLAG_AF) && alrm->enabled;
281
282 return 0;
283}
284
285static int rv8803_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
286{
287 struct i2c_client *client = to_i2c_client(dev);
288 struct rv8803_data *rv8803 = dev_get_drvdata(dev);
289 u8 alarmvals[3];
290 u8 ctrl[2];
291 int ret, err;
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100292
293 /* The alarm has no seconds, round up to nearest minute */
294 if (alrm->time.tm_sec) {
295 time64_t alarm_time = rtc_tm_to_time64(&alrm->time);
296
297 alarm_time += 60 - alrm->time.tm_sec;
298 rtc_time64_to_tm(alarm_time, &alrm->time);
299 }
300
Oleksij Rempel9d1fa4c2016-02-04 13:45:20 +0100301 mutex_lock(&rv8803->flags_lock);
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100302
Benoît Thébaudeaud5226492016-07-21 12:41:30 +0200303 ret = rv8803_read_regs(client, RV8803_FLAG, 2, ctrl);
304 if (ret) {
Oleksij Rempel9d1fa4c2016-02-04 13:45:20 +0100305 mutex_unlock(&rv8803->flags_lock);
Benoît Thébaudeaud5226492016-07-21 12:41:30 +0200306 return ret;
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100307 }
308
309 alarmvals[0] = bin2bcd(alrm->time.tm_min);
310 alarmvals[1] = bin2bcd(alrm->time.tm_hour);
311 alarmvals[2] = bin2bcd(alrm->time.tm_mday);
312
313 if (rv8803->ctrl & (RV8803_CTRL_AIE | RV8803_CTRL_UIE)) {
314 rv8803->ctrl &= ~(RV8803_CTRL_AIE | RV8803_CTRL_UIE);
Benoît Thébaudeaud5226492016-07-21 12:41:30 +0200315 err = rv8803_write_reg(rv8803->client, RV8803_CTRL,
316 rv8803->ctrl);
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100317 if (err) {
Oleksij Rempel9d1fa4c2016-02-04 13:45:20 +0100318 mutex_unlock(&rv8803->flags_lock);
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100319 return err;
320 }
321 }
322
323 ctrl[1] &= ~RV8803_FLAG_AF;
Benoît Thébaudeaud5226492016-07-21 12:41:30 +0200324 err = rv8803_write_reg(rv8803->client, RV8803_FLAG, ctrl[1]);
Oleksij Rempel9d1fa4c2016-02-04 13:45:20 +0100325 mutex_unlock(&rv8803->flags_lock);
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100326 if (err)
327 return err;
328
Benoît Thébaudeaud5226492016-07-21 12:41:30 +0200329 err = rv8803_write_regs(rv8803->client, RV8803_ALARM_MIN, 3, alarmvals);
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100330 if (err)
331 return err;
332
333 if (alrm->enabled) {
334 if (rv8803->rtc->uie_rtctimer.enabled)
335 rv8803->ctrl |= RV8803_CTRL_UIE;
336 if (rv8803->rtc->aie_timer.enabled)
337 rv8803->ctrl |= RV8803_CTRL_AIE;
338
Benoît Thébaudeaud5226492016-07-21 12:41:30 +0200339 err = rv8803_write_reg(rv8803->client, RV8803_CTRL,
340 rv8803->ctrl);
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100341 if (err)
342 return err;
343 }
344
345 return 0;
346}
347
348static int rv8803_alarm_irq_enable(struct device *dev, unsigned int enabled)
349{
350 struct i2c_client *client = to_i2c_client(dev);
351 struct rv8803_data *rv8803 = dev_get_drvdata(dev);
352 int ctrl, flags, err;
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100353
354 ctrl = rv8803->ctrl;
355
356 if (enabled) {
357 if (rv8803->rtc->uie_rtctimer.enabled)
358 ctrl |= RV8803_CTRL_UIE;
359 if (rv8803->rtc->aie_timer.enabled)
360 ctrl |= RV8803_CTRL_AIE;
361 } else {
362 if (!rv8803->rtc->uie_rtctimer.enabled)
363 ctrl &= ~RV8803_CTRL_UIE;
364 if (!rv8803->rtc->aie_timer.enabled)
365 ctrl &= ~RV8803_CTRL_AIE;
366 }
367
Oleksij Rempel9d1fa4c2016-02-04 13:45:20 +0100368 mutex_lock(&rv8803->flags_lock);
Benoît Thébaudeaud5226492016-07-21 12:41:30 +0200369 flags = rv8803_read_reg(client, RV8803_FLAG);
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100370 if (flags < 0) {
Oleksij Rempel9d1fa4c2016-02-04 13:45:20 +0100371 mutex_unlock(&rv8803->flags_lock);
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100372 return flags;
373 }
374 flags &= ~(RV8803_FLAG_AF | RV8803_FLAG_UF);
Benoît Thébaudeaud5226492016-07-21 12:41:30 +0200375 err = rv8803_write_reg(client, RV8803_FLAG, flags);
Oleksij Rempel9d1fa4c2016-02-04 13:45:20 +0100376 mutex_unlock(&rv8803->flags_lock);
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100377 if (err)
378 return err;
379
380 if (ctrl != rv8803->ctrl) {
381 rv8803->ctrl = ctrl;
Benoît Thébaudeaud5226492016-07-21 12:41:30 +0200382 err = rv8803_write_reg(client, RV8803_CTRL, rv8803->ctrl);
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100383 if (err)
384 return err;
385 }
386
387 return 0;
388}
389
390static int rv8803_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
391{
392 struct i2c_client *client = to_i2c_client(dev);
393 struct rv8803_data *rv8803 = dev_get_drvdata(dev);
394 int flags, ret = 0;
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100395
396 switch (cmd) {
397 case RTC_VL_READ:
Benoît Thébaudeaud5226492016-07-21 12:41:30 +0200398 flags = rv8803_read_reg(client, RV8803_FLAG);
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100399 if (flags < 0)
400 return flags;
401
402 if (flags & RV8803_FLAG_V1F)
403 dev_warn(&client->dev, "Voltage low, temperature compensation stopped.\n");
404
405 if (flags & RV8803_FLAG_V2F)
406 dev_warn(&client->dev, "Voltage low, data loss detected.\n");
407
408 flags &= RV8803_FLAG_V1F | RV8803_FLAG_V2F;
409
410 if (copy_to_user((void __user *)arg, &flags, sizeof(int)))
411 return -EFAULT;
412
413 return 0;
414
415 case RTC_VL_CLR:
Oleksij Rempel9d1fa4c2016-02-04 13:45:20 +0100416 mutex_lock(&rv8803->flags_lock);
Benoît Thébaudeaud5226492016-07-21 12:41:30 +0200417 flags = rv8803_read_reg(client, RV8803_FLAG);
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100418 if (flags < 0) {
Oleksij Rempel9d1fa4c2016-02-04 13:45:20 +0100419 mutex_unlock(&rv8803->flags_lock);
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100420 return flags;
421 }
422
423 flags &= ~(RV8803_FLAG_V1F | RV8803_FLAG_V2F);
Benoît Thébaudeaud5226492016-07-21 12:41:30 +0200424 ret = rv8803_write_reg(client, RV8803_FLAG, flags);
Oleksij Rempel9d1fa4c2016-02-04 13:45:20 +0100425 mutex_unlock(&rv8803->flags_lock);
Benoît Thébaudeaud5226492016-07-21 12:41:30 +0200426 if (ret)
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100427 return ret;
428
429 return 0;
430
431 default:
432 return -ENOIOCTLCMD;
433 }
434}
435
436static ssize_t rv8803_nvram_write(struct file *filp, struct kobject *kobj,
437 struct bin_attribute *attr,
438 char *buf, loff_t off, size_t count)
439{
440 struct device *dev = kobj_to_dev(kobj);
441 struct i2c_client *client = to_i2c_client(dev);
442 int ret;
443
Benoît Thébaudeaud5226492016-07-21 12:41:30 +0200444 ret = rv8803_write_reg(client, RV8803_RAM, buf[0]);
445 if (ret)
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100446 return ret;
447
448 return 1;
449}
450
451static ssize_t rv8803_nvram_read(struct file *filp, struct kobject *kobj,
452 struct bin_attribute *attr,
453 char *buf, loff_t off, size_t count)
454{
455 struct device *dev = kobj_to_dev(kobj);
456 struct i2c_client *client = to_i2c_client(dev);
457 int ret;
458
Benoît Thébaudeaud5226492016-07-21 12:41:30 +0200459 ret = rv8803_read_reg(client, RV8803_RAM);
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100460 if (ret < 0)
461 return ret;
462
463 buf[0] = ret;
464
465 return 1;
466}
467
468static struct bin_attribute rv8803_nvram_attr = {
469 .attr = {
470 .name = "nvram",
471 .mode = S_IRUGO | S_IWUSR,
472 },
473 .size = 1,
474 .read = rv8803_nvram_read,
475 .write = rv8803_nvram_write,
476};
477
478static struct rtc_class_ops rv8803_rtc_ops = {
479 .read_time = rv8803_get_time,
480 .set_time = rv8803_set_time,
481 .ioctl = rv8803_ioctl,
482};
483
484static int rv8803_probe(struct i2c_client *client,
485 const struct i2c_device_id *id)
486{
487 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
488 struct rv8803_data *rv8803;
Benoît Thébaudeaud5226492016-07-21 12:41:30 +0200489 int err, flags;
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100490
491 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
492 I2C_FUNC_SMBUS_I2C_BLOCK)) {
493 dev_err(&adapter->dev, "doesn't support I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_I2C_BLOCK\n");
494 return -EIO;
495 }
496
497 rv8803 = devm_kzalloc(&client->dev, sizeof(struct rv8803_data),
498 GFP_KERNEL);
499 if (!rv8803)
500 return -ENOMEM;
501
Oleksij Rempel9d1fa4c2016-02-04 13:45:20 +0100502 mutex_init(&rv8803->flags_lock);
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100503 rv8803->client = client;
504 i2c_set_clientdata(client, rv8803);
505
Benoît Thébaudeaud5226492016-07-21 12:41:30 +0200506 flags = rv8803_read_reg(client, RV8803_FLAG);
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100507 if (flags < 0)
508 return flags;
509
510 if (flags & RV8803_FLAG_V1F)
511 dev_warn(&client->dev, "Voltage low, temperature compensation stopped.\n");
512
513 if (flags & RV8803_FLAG_V2F)
514 dev_warn(&client->dev, "Voltage low, data loss detected.\n");
515
516 if (flags & RV8803_FLAG_AF)
517 dev_warn(&client->dev, "An alarm maybe have been missed.\n");
518
519 if (client->irq > 0) {
520 err = devm_request_threaded_irq(&client->dev, client->irq,
521 NULL, rv8803_handle_irq,
522 IRQF_TRIGGER_LOW | IRQF_ONESHOT,
523 "rv8803", client);
524 if (err) {
525 dev_warn(&client->dev, "unable to request IRQ, alarms disabled\n");
526 client->irq = 0;
527 } else {
528 rv8803_rtc_ops.read_alarm = rv8803_get_alarm;
529 rv8803_rtc_ops.set_alarm = rv8803_set_alarm;
530 rv8803_rtc_ops.alarm_irq_enable = rv8803_alarm_irq_enable;
531 }
532 }
533
534 rv8803->rtc = devm_rtc_device_register(&client->dev, client->name,
535 &rv8803_rtc_ops, THIS_MODULE);
536 if (IS_ERR(rv8803->rtc)) {
537 dev_err(&client->dev, "unable to register the class device\n");
538 return PTR_ERR(rv8803->rtc);
539 }
540
Benoît Thébaudeaud5226492016-07-21 12:41:30 +0200541 err = rv8803_write_reg(rv8803->client, RV8803_EXT, RV8803_EXT_WADA);
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100542 if (err)
543 return err;
544
545 err = device_create_bin_file(&client->dev, &rv8803_nvram_attr);
546 if (err)
547 return err;
548
549 rv8803->rtc->max_user_freq = 1;
550
551 return 0;
552}
553
554static int rv8803_remove(struct i2c_client *client)
555{
556 device_remove_bin_file(&client->dev, &rv8803_nvram_attr);
557
558 return 0;
559}
560
561static const struct i2c_device_id rv8803_id[] = {
562 { "rv8803", 0 },
Gregory CLEMENT78ef5f22015-12-11 12:43:05 +0100563 { "rx8900", 0 },
Alexandre Belloni1e3929e2015-11-02 23:48:32 +0100564 { }
565};
566MODULE_DEVICE_TABLE(i2c, rv8803_id);
567
568static struct i2c_driver rv8803_driver = {
569 .driver = {
570 .name = "rtc-rv8803",
571 },
572 .probe = rv8803_probe,
573 .remove = rv8803_remove,
574 .id_table = rv8803_id,
575};
576module_i2c_driver(rv8803_driver);
577
578MODULE_AUTHOR("Alexandre Belloni <alexandre.belloni@free-electrons.com>");
579MODULE_DESCRIPTION("Micro Crystal RV8803 RTC driver");
580MODULE_LICENSE("GPL v2");