aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexandre Belloni <alexandre.belloni@free-electrons.com>2015-11-02 17:48:32 -0500
committerAlexandre Belloni <alexandre.belloni@free-electrons.com>2015-11-08 08:12:32 -0500
commit1e3929ef0e1c4c7127b785ce7a236965b3739406 (patch)
tree8ee4629008c626fb06f9162f19f7218ca59a4e6f
parentfb4ac3c14b07a6fd33a399845273661172ed282d (diff)
rtc: Add a driver for Micro Crystal RV8803
This driver supports the following functions: - reading and settings time - alarms when connected to an IRQ - reading and clearing the voltage low flags - nvram Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
-rw-r--r--drivers/rtc/Kconfig9
-rw-r--r--drivers/rtc/Makefile1
-rw-r--r--drivers/rtc/rtc-rv8803.c521
3 files changed, 531 insertions, 0 deletions
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 57c2dbc4f438..2a524244afec 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -593,6 +593,15 @@ config RTC_DRV_RV3029C2
593 This driver can also be built as a module. If so, the module 593 This driver can also be built as a module. If so, the module
594 will be called rtc-rv3029c2. 594 will be called rtc-rv3029c2.
595 595
596config RTC_DRV_RV8803
597 tristate "Micro Crystal RV8803"
598 help
599 If you say yes here you get support for the Micro Crystal
600 RV8803 RTC chips.
601
602 This driver can also be built as a module. If so, the module
603 will be called rtc-rv8803.
604
596config RTC_DRV_S5M 605config RTC_DRV_S5M
597 tristate "Samsung S2M/S5M series" 606 tristate "Samsung S2M/S5M series"
598 depends on MFD_SEC_CORE 607 depends on MFD_SEC_CORE
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index e491eb524434..231f76451615 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -126,6 +126,7 @@ obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o
126obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o 126obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o
127obj-$(CONFIG_RTC_DRV_RS5C372) += rtc-rs5c372.o 127obj-$(CONFIG_RTC_DRV_RS5C372) += rtc-rs5c372.o
128obj-$(CONFIG_RTC_DRV_RV3029C2) += rtc-rv3029c2.o 128obj-$(CONFIG_RTC_DRV_RV3029C2) += rtc-rv3029c2.o
129obj-$(CONFIG_RTC_DRV_RV8803) += rtc-rv8803.o
129obj-$(CONFIG_RTC_DRV_RX4581) += rtc-rx4581.o 130obj-$(CONFIG_RTC_DRV_RX4581) += rtc-rx4581.o
130obj-$(CONFIG_RTC_DRV_RX8025) += rtc-rx8025.o 131obj-$(CONFIG_RTC_DRV_RX8025) += rtc-rx8025.o
131obj-$(CONFIG_RTC_DRV_RX8581) += rtc-rx8581.o 132obj-$(CONFIG_RTC_DRV_RX8581) += rtc-rx8581.o
diff --git a/drivers/rtc/rtc-rv8803.c b/drivers/rtc/rtc-rv8803.c
new file mode 100644
index 000000000000..e7329e21bfe3
--- /dev/null
+++ b/drivers/rtc/rtc-rv8803.c
@@ -0,0 +1,521 @@
1/*
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>
16#include <linux/i2c.h>
17#include <linux/interrupt.h>
18#include <linux/kernel.h>
19#include <linux/module.h>
20#include <linux/rtc.h>
21
22#define RV8803_SEC 0x00
23#define RV8803_MIN 0x01
24#define RV8803_HOUR 0x02
25#define RV8803_WEEK 0x03
26#define RV8803_DAY 0x04
27#define RV8803_MONTH 0x05
28#define RV8803_YEAR 0x06
29#define RV8803_RAM 0x07
30#define RV8803_ALARM_MIN 0x08
31#define RV8803_ALARM_HOUR 0x09
32#define RV8803_ALARM_WEEK_OR_DAY 0x0A
33#define RV8803_EXT 0x0D
34#define RV8803_FLAG 0x0E
35#define RV8803_CTRL 0x0F
36
37#define RV8803_EXT_WADA BIT(6)
38
39#define RV8803_FLAG_V1F BIT(0)
40#define RV8803_FLAG_V2F BIT(1)
41#define RV8803_FLAG_AF BIT(3)
42#define RV8803_FLAG_TF BIT(4)
43#define RV8803_FLAG_UF BIT(5)
44
45#define RV8803_CTRL_RESET BIT(0)
46
47#define RV8803_CTRL_EIE BIT(2)
48#define RV8803_CTRL_AIE BIT(3)
49#define RV8803_CTRL_TIE BIT(4)
50#define RV8803_CTRL_UIE BIT(5)
51
52struct rv8803_data {
53 struct i2c_client *client;
54 struct rtc_device *rtc;
55 spinlock_t flags_lock;
56 u8 ctrl;
57};
58
59static irqreturn_t rv8803_handle_irq(int irq, void *dev_id)
60{
61 struct i2c_client *client = dev_id;
62 struct rv8803_data *rv8803 = i2c_get_clientdata(client);
63 unsigned long events = 0;
64 u8 flags;
65
66 spin_lock(&rv8803->flags_lock);
67
68 flags = i2c_smbus_read_byte_data(client, RV8803_FLAG);
69 if (flags <= 0) {
70 spin_unlock(&rv8803->flags_lock);
71 return IRQ_NONE;
72 }
73
74 if (flags & RV8803_FLAG_V1F)
75 dev_warn(&client->dev, "Voltage low, temperature compensation stopped.\n");
76
77 if (flags & RV8803_FLAG_V2F)
78 dev_warn(&client->dev, "Voltage low, data loss detected.\n");
79
80 if (flags & RV8803_FLAG_TF) {
81 flags &= ~RV8803_FLAG_TF;
82 rv8803->ctrl &= ~RV8803_CTRL_TIE;
83 events |= RTC_PF;
84 }
85
86 if (flags & RV8803_FLAG_AF) {
87 flags &= ~RV8803_FLAG_AF;
88 rv8803->ctrl &= ~RV8803_CTRL_AIE;
89 events |= RTC_AF;
90 }
91
92 if (flags & RV8803_FLAG_UF) {
93 flags &= ~RV8803_FLAG_UF;
94 rv8803->ctrl &= ~RV8803_CTRL_UIE;
95 events |= RTC_UF;
96 }
97
98 if (events) {
99 rtc_update_irq(rv8803->rtc, 1, events);
100 i2c_smbus_write_byte_data(client, RV8803_FLAG, flags);
101 i2c_smbus_write_byte_data(rv8803->client, RV8803_CTRL,
102 rv8803->ctrl);
103 }
104
105 spin_unlock(&rv8803->flags_lock);
106
107 return IRQ_HANDLED;
108}
109
110static int rv8803_get_time(struct device *dev, struct rtc_time *tm)
111{
112 struct rv8803_data *rv8803 = dev_get_drvdata(dev);
113 u8 date1[7];
114 u8 date2[7];
115 u8 *date = date1;
116 int ret, flags;
117
118 flags = i2c_smbus_read_byte_data(rv8803->client, RV8803_FLAG);
119 if (flags < 0)
120 return flags;
121
122 if (flags & RV8803_FLAG_V2F) {
123 dev_warn(dev, "Voltage low, data is invalid.\n");
124 return -EINVAL;
125 }
126
127 ret = i2c_smbus_read_i2c_block_data(rv8803->client, RV8803_SEC,
128 7, date);
129 if (ret != 7)
130 return ret < 0 ? ret : -EIO;
131
132 if ((date1[RV8803_SEC] & 0x7f) == bin2bcd(59)) {
133 ret = i2c_smbus_read_i2c_block_data(rv8803->client, RV8803_SEC,
134 7, date2);
135 if (ret != 7)
136 return ret < 0 ? ret : -EIO;
137
138 if ((date2[RV8803_SEC] & 0x7f) != bin2bcd(59))
139 date = date2;
140 }
141
142 tm->tm_sec = bcd2bin(date[RV8803_SEC] & 0x7f);
143 tm->tm_min = bcd2bin(date[RV8803_MIN] & 0x7f);
144 tm->tm_hour = bcd2bin(date[RV8803_HOUR] & 0x3f);
145 tm->tm_wday = ffs(date[RV8803_WEEK] & 0x7f);
146 tm->tm_mday = bcd2bin(date[RV8803_DAY] & 0x3f);
147 tm->tm_mon = bcd2bin(date[RV8803_MONTH] & 0x1f) - 1;
148 tm->tm_year = bcd2bin(date[RV8803_YEAR]) + 100;
149
150 return rtc_valid_tm(tm);
151}
152
153static int rv8803_set_time(struct device *dev, struct rtc_time *tm)
154{
155 struct rv8803_data *rv8803 = dev_get_drvdata(dev);
156 u8 date[7];
157 int flags, ret;
158 unsigned long irqflags;
159
160 if ((tm->tm_year < 100) || (tm->tm_year > 199))
161 return -EINVAL;
162
163 date[RV8803_SEC] = bin2bcd(tm->tm_sec);
164 date[RV8803_MIN] = bin2bcd(tm->tm_min);
165 date[RV8803_HOUR] = bin2bcd(tm->tm_hour);
166 date[RV8803_WEEK] = 1 << (tm->tm_wday);
167 date[RV8803_DAY] = bin2bcd(tm->tm_mday);
168 date[RV8803_MONTH] = bin2bcd(tm->tm_mon + 1);
169 date[RV8803_YEAR] = bin2bcd(tm->tm_year - 100);
170
171 ret = i2c_smbus_write_i2c_block_data(rv8803->client, RV8803_SEC,
172 7, date);
173 if (ret < 0)
174 return ret;
175
176 spin_lock_irqsave(&rv8803->flags_lock, irqflags);
177
178 flags = i2c_smbus_read_byte_data(rv8803->client, RV8803_FLAG);
179 if (flags < 0) {
180 spin_unlock_irqrestore(&rv8803->flags_lock, irqflags);
181 return flags;
182 }
183
184 ret = i2c_smbus_write_byte_data(rv8803->client, RV8803_FLAG,
185 flags & ~RV8803_FLAG_V2F);
186
187 spin_unlock_irqrestore(&rv8803->flags_lock, irqflags);
188
189 return ret;
190}
191
192static int rv8803_get_alarm(struct device *dev, struct rtc_wkalrm *alrm)
193{
194 struct rv8803_data *rv8803 = dev_get_drvdata(dev);
195 struct i2c_client *client = rv8803->client;
196 u8 alarmvals[3];
197 int flags, ret;
198
199 ret = i2c_smbus_read_i2c_block_data(client, RV8803_ALARM_MIN,
200 3, alarmvals);
201 if (ret != 3)
202 return ret < 0 ? ret : -EIO;
203
204 flags = i2c_smbus_read_byte_data(client, RV8803_FLAG);
205 if (flags < 0)
206 return flags;
207
208 alrm->time.tm_sec = 0;
209 alrm->time.tm_min = bcd2bin(alarmvals[0] & 0x7f);
210 alrm->time.tm_hour = bcd2bin(alarmvals[1] & 0x3f);
211 alrm->time.tm_wday = -1;
212 alrm->time.tm_mday = bcd2bin(alarmvals[2] & 0x3f);
213 alrm->time.tm_mon = -1;
214 alrm->time.tm_year = -1;
215
216 alrm->enabled = !!(rv8803->ctrl & RV8803_CTRL_AIE);
217 alrm->pending = (flags & RV8803_FLAG_AF) && alrm->enabled;
218
219 return 0;
220}
221
222static int rv8803_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
223{
224 struct i2c_client *client = to_i2c_client(dev);
225 struct rv8803_data *rv8803 = dev_get_drvdata(dev);
226 u8 alarmvals[3];
227 u8 ctrl[2];
228 int ret, err;
229 unsigned long irqflags;
230
231 /* The alarm has no seconds, round up to nearest minute */
232 if (alrm->time.tm_sec) {
233 time64_t alarm_time = rtc_tm_to_time64(&alrm->time);
234
235 alarm_time += 60 - alrm->time.tm_sec;
236 rtc_time64_to_tm(alarm_time, &alrm->time);
237 }
238
239 spin_lock_irqsave(&rv8803->flags_lock, irqflags);
240
241 ret = i2c_smbus_read_i2c_block_data(client, RV8803_FLAG, 2, ctrl);
242 if (ret != 2) {
243 spin_unlock_irqrestore(&rv8803->flags_lock, irqflags);
244 return ret < 0 ? ret : -EIO;
245 }
246
247 alarmvals[0] = bin2bcd(alrm->time.tm_min);
248 alarmvals[1] = bin2bcd(alrm->time.tm_hour);
249 alarmvals[2] = bin2bcd(alrm->time.tm_mday);
250
251 if (rv8803->ctrl & (RV8803_CTRL_AIE | RV8803_CTRL_UIE)) {
252 rv8803->ctrl &= ~(RV8803_CTRL_AIE | RV8803_CTRL_UIE);
253 err = i2c_smbus_write_byte_data(rv8803->client, RV8803_CTRL,
254 rv8803->ctrl);
255 if (err) {
256 spin_unlock_irqrestore(&rv8803->flags_lock, irqflags);
257 return err;
258 }
259 }
260
261 ctrl[1] &= ~RV8803_FLAG_AF;
262 err = i2c_smbus_write_byte_data(rv8803->client, RV8803_FLAG, ctrl[1]);
263 spin_unlock_irqrestore(&rv8803->flags_lock, irqflags);
264 if (err)
265 return err;
266
267 err = i2c_smbus_write_i2c_block_data(rv8803->client, RV8803_ALARM_MIN,
268 3, alarmvals);
269 if (err)
270 return err;
271
272 if (alrm->enabled) {
273 if (rv8803->rtc->uie_rtctimer.enabled)
274 rv8803->ctrl |= RV8803_CTRL_UIE;
275 if (rv8803->rtc->aie_timer.enabled)
276 rv8803->ctrl |= RV8803_CTRL_AIE;
277
278 err = i2c_smbus_write_byte_data(rv8803->client, RV8803_CTRL,
279 rv8803->ctrl);
280 if (err)
281 return err;
282 }
283
284 return 0;
285}
286
287static int rv8803_alarm_irq_enable(struct device *dev, unsigned int enabled)
288{
289 struct i2c_client *client = to_i2c_client(dev);
290 struct rv8803_data *rv8803 = dev_get_drvdata(dev);
291 int ctrl, flags, err;
292 unsigned long irqflags;
293
294 ctrl = rv8803->ctrl;
295
296 if (enabled) {
297 if (rv8803->rtc->uie_rtctimer.enabled)
298 ctrl |= RV8803_CTRL_UIE;
299 if (rv8803->rtc->aie_timer.enabled)
300 ctrl |= RV8803_CTRL_AIE;
301 } else {
302 if (!rv8803->rtc->uie_rtctimer.enabled)
303 ctrl &= ~RV8803_CTRL_UIE;
304 if (!rv8803->rtc->aie_timer.enabled)
305 ctrl &= ~RV8803_CTRL_AIE;
306 }
307
308 spin_lock_irqsave(&rv8803->flags_lock, irqflags);
309 flags = i2c_smbus_read_byte_data(client, RV8803_FLAG);
310 if (flags < 0) {
311 spin_unlock_irqrestore(&rv8803->flags_lock, irqflags);
312 return flags;
313 }
314 flags &= ~(RV8803_FLAG_AF | RV8803_FLAG_UF);
315 err = i2c_smbus_write_byte_data(client, RV8803_FLAG, flags);
316 spin_unlock_irqrestore(&rv8803->flags_lock, irqflags);
317 if (err)
318 return err;
319
320 if (ctrl != rv8803->ctrl) {
321 rv8803->ctrl = ctrl;
322 err = i2c_smbus_write_byte_data(client, RV8803_CTRL,
323 rv8803->ctrl);
324 if (err)
325 return err;
326 }
327
328 return 0;
329}
330
331static int rv8803_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
332{
333 struct i2c_client *client = to_i2c_client(dev);
334 struct rv8803_data *rv8803 = dev_get_drvdata(dev);
335 int flags, ret = 0;
336 unsigned long irqflags;
337
338 switch (cmd) {
339 case RTC_VL_READ:
340 flags = i2c_smbus_read_byte_data(client, RV8803_FLAG);
341 if (flags < 0)
342 return flags;
343
344 if (flags & RV8803_FLAG_V1F)
345 dev_warn(&client->dev, "Voltage low, temperature compensation stopped.\n");
346
347 if (flags & RV8803_FLAG_V2F)
348 dev_warn(&client->dev, "Voltage low, data loss detected.\n");
349
350 flags &= RV8803_FLAG_V1F | RV8803_FLAG_V2F;
351
352 if (copy_to_user((void __user *)arg, &flags, sizeof(int)))
353 return -EFAULT;
354
355 return 0;
356
357 case RTC_VL_CLR:
358 spin_lock_irqsave(&rv8803->flags_lock, irqflags);
359 flags = i2c_smbus_read_byte_data(client, RV8803_FLAG);
360 if (flags < 0) {
361 spin_unlock_irqrestore(&rv8803->flags_lock, irqflags);
362 return flags;
363 }
364
365 flags &= ~(RV8803_FLAG_V1F | RV8803_FLAG_V2F);
366 ret = i2c_smbus_write_byte_data(client, RV8803_FLAG, flags);
367 spin_unlock_irqrestore(&rv8803->flags_lock, irqflags);
368 if (ret < 0)
369 return ret;
370
371 return 0;
372
373 default:
374 return -ENOIOCTLCMD;
375 }
376}
377
378static ssize_t rv8803_nvram_write(struct file *filp, struct kobject *kobj,
379 struct bin_attribute *attr,
380 char *buf, loff_t off, size_t count)
381{
382 struct device *dev = kobj_to_dev(kobj);
383 struct i2c_client *client = to_i2c_client(dev);
384 int ret;
385
386 ret = i2c_smbus_write_byte_data(client, RV8803_RAM, buf[0]);
387 if (ret < 0)
388 return ret;
389
390 return 1;
391}
392
393static ssize_t rv8803_nvram_read(struct file *filp, struct kobject *kobj,
394 struct bin_attribute *attr,
395 char *buf, loff_t off, size_t count)
396{
397 struct device *dev = kobj_to_dev(kobj);
398 struct i2c_client *client = to_i2c_client(dev);
399 int ret;
400
401 ret = i2c_smbus_read_byte_data(client, RV8803_RAM);
402 if (ret < 0)
403 return ret;
404
405 buf[0] = ret;
406
407 return 1;
408}
409
410static struct bin_attribute rv8803_nvram_attr = {
411 .attr = {
412 .name = "nvram",
413 .mode = S_IRUGO | S_IWUSR,
414 },
415 .size = 1,
416 .read = rv8803_nvram_read,
417 .write = rv8803_nvram_write,
418};
419
420static struct rtc_class_ops rv8803_rtc_ops = {
421 .read_time = rv8803_get_time,
422 .set_time = rv8803_set_time,
423 .ioctl = rv8803_ioctl,
424};
425
426static int rv8803_probe(struct i2c_client *client,
427 const struct i2c_device_id *id)
428{
429 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
430 struct rv8803_data *rv8803;
431 int err, flags;
432
433 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
434 I2C_FUNC_SMBUS_I2C_BLOCK)) {
435 dev_err(&adapter->dev, "doesn't support I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_I2C_BLOCK\n");
436 return -EIO;
437 }
438
439 rv8803 = devm_kzalloc(&client->dev, sizeof(struct rv8803_data),
440 GFP_KERNEL);
441 if (!rv8803)
442 return -ENOMEM;
443
444 rv8803->client = client;
445 i2c_set_clientdata(client, rv8803);
446
447 flags = i2c_smbus_read_byte_data(client, RV8803_FLAG);
448 if (flags < 0)
449 return flags;
450
451 if (flags & RV8803_FLAG_V1F)
452 dev_warn(&client->dev, "Voltage low, temperature compensation stopped.\n");
453
454 if (flags & RV8803_FLAG_V2F)
455 dev_warn(&client->dev, "Voltage low, data loss detected.\n");
456
457 if (flags & RV8803_FLAG_AF)
458 dev_warn(&client->dev, "An alarm maybe have been missed.\n");
459
460 if (client->irq > 0) {
461 err = devm_request_threaded_irq(&client->dev, client->irq,
462 NULL, rv8803_handle_irq,
463 IRQF_TRIGGER_LOW | IRQF_ONESHOT,
464 "rv8803", client);
465 if (err) {
466 dev_warn(&client->dev, "unable to request IRQ, alarms disabled\n");
467 client->irq = 0;
468 } else {
469 rv8803_rtc_ops.read_alarm = rv8803_get_alarm;
470 rv8803_rtc_ops.set_alarm = rv8803_set_alarm;
471 rv8803_rtc_ops.alarm_irq_enable = rv8803_alarm_irq_enable;
472 }
473 }
474
475 rv8803->rtc = devm_rtc_device_register(&client->dev, client->name,
476 &rv8803_rtc_ops, THIS_MODULE);
477 if (IS_ERR(rv8803->rtc)) {
478 dev_err(&client->dev, "unable to register the class device\n");
479 return PTR_ERR(rv8803->rtc);
480 }
481
482 err = i2c_smbus_write_byte_data(rv8803->client, RV8803_EXT,
483 RV8803_EXT_WADA);
484 if (err)
485 return err;
486
487 err = device_create_bin_file(&client->dev, &rv8803_nvram_attr);
488 if (err)
489 return err;
490
491 rv8803->rtc->max_user_freq = 1;
492
493 return 0;
494}
495
496static int rv8803_remove(struct i2c_client *client)
497{
498 device_remove_bin_file(&client->dev, &rv8803_nvram_attr);
499
500 return 0;
501}
502
503static const struct i2c_device_id rv8803_id[] = {
504 { "rv8803", 0 },
505 { }
506};
507MODULE_DEVICE_TABLE(i2c, rv8803_id);
508
509static struct i2c_driver rv8803_driver = {
510 .driver = {
511 .name = "rtc-rv8803",
512 },
513 .probe = rv8803_probe,
514 .remove = rv8803_remove,
515 .id_table = rv8803_id,
516};
517module_i2c_driver(rv8803_driver);
518
519MODULE_AUTHOR("Alexandre Belloni <alexandre.belloni@free-electrons.com>");
520MODULE_DESCRIPTION("Micro Crystal RV8803 RTC driver");
521MODULE_LICENSE("GPL v2");