1 // SPDX-License-Identifier: GPL-2.0+
3 * drivers/rtc/rtc-rc5t619.c
5 * Real time clock driver for RICOH RC5T619 power management chip.
7 * Copyright (C) 2019 Andreas Kemnade
10 #include <linux/kernel.h>
11 #include <linux/device.h>
12 #include <linux/errno.h>
13 #include <linux/init.h>
14 #include <linux/module.h>
15 #include <linux/mfd/rn5t618.h>
16 #include <linux/platform_device.h>
17 #include <linux/regmap.h>
18 #include <linux/bcd.h>
19 #include <linux/rtc.h>
20 #include <linux/slab.h>
21 #include <linux/irqdomain.h>
25 struct rtc_device
*rtc
;
26 struct rn5t618
*rn5t618
;
29 #define CTRL1_ALARM_ENABLED 0x40
30 #define CTRL1_24HR 0x20
31 #define CTRL1_PERIODIC_MASK 0xf
33 #define CTRL2_PON 0x10
34 #define CTRL2_ALARM_STATUS 0x80
35 #define CTRL2_CTFG 0x4
38 #define MONTH_CENTFLAG 0x80
39 #define HOUR_PMFLAG 0x20
40 #define MDAY_DAL_EXT 0x80
42 static uint8_t rtc5t619_12hour_bcd2bin(uint8_t hour
)
44 if (hour
& HOUR_PMFLAG
) {
45 hour
= bcd2bin(hour
& ~HOUR_PMFLAG
);
46 return hour
== 12 ? 12 : 12 + hour
;
50 return hour
== 12 ? 0 : hour
;
53 static uint8_t rtc5t619_12hour_bin2bcd(uint8_t hour
)
62 return 0x12 | HOUR_PMFLAG
;
64 return bin2bcd(hour
- 12) | HOUR_PMFLAG
;
67 static int rc5t619_rtc_periodic_disable(struct device
*dev
)
69 struct rc5t619_rtc
*rtc
= dev_get_drvdata(dev
);
72 /* disable function */
73 err
= regmap_update_bits(rtc
->rn5t618
->regmap
,
74 RN5T618_RTC_CTRL1
, CTRL1_PERIODIC_MASK
, 0);
78 /* clear alarm flag and CTFG */
79 err
= regmap_update_bits(rtc
->rn5t618
->regmap
, RN5T618_RTC_CTRL2
,
80 CTRL2_ALARM_STATUS
| CTRL2_CTFG
| CTRL2_CTC
,
88 /* things to be done once after power on */
89 static int rc5t619_rtc_pon_setup(struct device
*dev
)
91 struct rc5t619_rtc
*rtc
= dev_get_drvdata(dev
);
93 unsigned int reg_data
;
95 err
= regmap_read(rtc
->rn5t618
->regmap
, RN5T618_RTC_CTRL2
, ®_data
);
100 reg_data
&= ~(CTRL2_PON
| CTRL2_CTC
| 0x4a); /* 0101-1011 */
101 reg_data
|= 0x20; /* 0010-0000 */
102 err
= regmap_write(rtc
->rn5t618
->regmap
, RN5T618_RTC_CTRL2
, reg_data
);
106 /* clearing RTC Adjust register */
107 err
= regmap_write(rtc
->rn5t618
->regmap
, RN5T618_RTC_ADJUST
, 0);
111 return regmap_update_bits(rtc
->rn5t618
->regmap
,
113 CTRL1_24HR
, CTRL1_24HR
);
116 static int rc5t619_rtc_read_time(struct device
*dev
, struct rtc_time
*tm
)
118 struct rc5t619_rtc
*rtc
= dev_get_drvdata(dev
);
125 err
= regmap_read(rtc
->rn5t618
->regmap
, RN5T618_RTC_CTRL2
, &ctrl2
);
129 if (ctrl2
& CTRL2_PON
)
132 err
= regmap_read(rtc
->rn5t618
->regmap
, RN5T618_RTC_CTRL1
, &ctrl1
);
136 err
= regmap_bulk_read(rtc
->rn5t618
->regmap
, RN5T618_RTC_SECONDS
,
141 if (buff
[5] & MONTH_CENTFLAG
)
146 tm
->tm_sec
= bcd2bin(buff
[0]);
147 tm
->tm_min
= bcd2bin(buff
[1]);
149 if (ctrl1
& CTRL1_24HR
)
150 tm
->tm_hour
= bcd2bin(buff
[2]);
152 tm
->tm_hour
= rtc5t619_12hour_bcd2bin(buff
[2]);
154 tm
->tm_wday
= bcd2bin(buff
[3]);
155 tm
->tm_mday
= bcd2bin(buff
[4]);
156 tm
->tm_mon
= bcd2bin(buff
[5] & 0x1f) - 1; /* back to system 0-11 */
157 tm
->tm_year
= bcd2bin(buff
[6]) + 100 * cent_flag
;
162 static int rc5t619_rtc_set_time(struct device
*dev
, struct rtc_time
*tm
)
164 struct rc5t619_rtc
*rtc
= dev_get_drvdata(dev
);
171 err
= regmap_read(rtc
->rn5t618
->regmap
, RN5T618_RTC_CTRL2
, &ctrl2
);
175 if (ctrl2
& CTRL2_PON
)
176 rc5t619_rtc_pon_setup(dev
);
178 err
= regmap_read(rtc
->rn5t618
->regmap
, RN5T618_RTC_CTRL1
, &ctrl1
);
182 if (tm
->tm_year
>= 100)
187 buff
[0] = bin2bcd(tm
->tm_sec
);
188 buff
[1] = bin2bcd(tm
->tm_min
);
190 if (ctrl1
& CTRL1_24HR
)
191 buff
[2] = bin2bcd(tm
->tm_hour
);
193 buff
[2] = rtc5t619_12hour_bin2bcd(tm
->tm_hour
);
195 buff
[3] = bin2bcd(tm
->tm_wday
);
196 buff
[4] = bin2bcd(tm
->tm_mday
);
197 buff
[5] = bin2bcd(tm
->tm_mon
+ 1); /* system set 0-11 */
198 buff
[6] = bin2bcd(tm
->tm_year
- cent_flag
* 100);
201 buff
[5] |= MONTH_CENTFLAG
;
203 err
= regmap_bulk_write(rtc
->rn5t618
->regmap
, RN5T618_RTC_SECONDS
,
206 dev_err(dev
, "failed to program new time: %d\n", err
);
213 /* 0-disable, 1-enable */
214 static int rc5t619_rtc_alarm_enable(struct device
*dev
, unsigned int enabled
)
216 struct rc5t619_rtc
*rtc
= dev_get_drvdata(dev
);
218 return regmap_update_bits(rtc
->rn5t618
->regmap
,
221 enabled
? CTRL1_ALARM_ENABLED
: 0);
224 static int rc5t619_rtc_read_alarm(struct device
*dev
, struct rtc_wkalrm
*alrm
)
226 struct rc5t619_rtc
*rtc
= dev_get_drvdata(dev
);
228 unsigned int buff_cent
;
233 err
= regmap_read(rtc
->rn5t618
->regmap
, RN5T618_RTC_CTRL1
, &ctrl1
);
237 err
= regmap_read(rtc
->rn5t618
->regmap
, RN5T618_RTC_MONTH
, &buff_cent
);
239 dev_err(dev
, "failed to read time: %d\n", err
);
243 if (buff_cent
& MONTH_CENTFLAG
)
248 err
= regmap_bulk_read(rtc
->rn5t618
->regmap
, RN5T618_RTC_ALARM_Y_SEC
,
253 buff
[3] = buff
[3] & 0x3f;
255 alrm
->time
.tm_sec
= bcd2bin(buff
[0]);
256 alrm
->time
.tm_min
= bcd2bin(buff
[1]);
258 if (ctrl1
& CTRL1_24HR
)
259 alrm
->time
.tm_hour
= bcd2bin(buff
[2]);
261 alrm
->time
.tm_hour
= rtc5t619_12hour_bcd2bin(buff
[2]);
263 alrm
->time
.tm_mday
= bcd2bin(buff
[3]);
264 alrm
->time
.tm_mon
= bcd2bin(buff
[4]) - 1;
265 alrm
->time
.tm_year
= bcd2bin(buff
[5]) + 100 * cent_flag
;
266 alrm
->enabled
= !!(ctrl1
& CTRL1_ALARM_ENABLED
);
267 dev_dbg(dev
, "read alarm: %ptR\n", &alrm
->time
);
272 static int rc5t619_rtc_set_alarm(struct device
*dev
, struct rtc_wkalrm
*alrm
)
274 struct rc5t619_rtc
*rtc
= dev_get_drvdata(dev
);
280 err
= regmap_read(rtc
->rn5t618
->regmap
, RN5T618_RTC_CTRL1
, &ctrl1
);
284 err
= rc5t619_rtc_alarm_enable(dev
, 0);
291 if (alrm
->enabled
== 0)
294 if (alrm
->time
.tm_year
>= 100)
299 alrm
->time
.tm_mon
+= 1;
300 buff
[0] = bin2bcd(alrm
->time
.tm_sec
);
301 buff
[1] = bin2bcd(alrm
->time
.tm_min
);
303 if (ctrl1
& CTRL1_24HR
)
304 buff
[2] = bin2bcd(alrm
->time
.tm_hour
);
306 buff
[2] = rtc5t619_12hour_bin2bcd(alrm
->time
.tm_hour
);
308 buff
[3] = bin2bcd(alrm
->time
.tm_mday
);
309 buff
[4] = bin2bcd(alrm
->time
.tm_mon
);
310 buff
[5] = bin2bcd(alrm
->time
.tm_year
- 100 * cent_flag
);
311 buff
[3] |= MDAY_DAL_EXT
;
313 err
= regmap_bulk_write(rtc
->rn5t618
->regmap
, RN5T618_RTC_ALARM_Y_SEC
,
318 return rc5t619_rtc_alarm_enable(dev
, alrm
->enabled
);
321 static const struct rtc_class_ops rc5t619_rtc_ops
= {
322 .read_time
= rc5t619_rtc_read_time
,
323 .set_time
= rc5t619_rtc_set_time
,
324 .set_alarm
= rc5t619_rtc_set_alarm
,
325 .read_alarm
= rc5t619_rtc_read_alarm
,
326 .alarm_irq_enable
= rc5t619_rtc_alarm_enable
,
329 static int rc5t619_rtc_alarm_flag_clr(struct device
*dev
)
331 struct rc5t619_rtc
*rtc
= dev_get_drvdata(dev
);
333 /* clear alarm-D status bits.*/
334 return regmap_update_bits(rtc
->rn5t618
->regmap
,
336 CTRL2_ALARM_STATUS
| CTRL2_CTC
, 0);
339 static irqreturn_t
rc5t619_rtc_irq(int irq
, void *data
)
341 struct device
*dev
= data
;
342 struct rc5t619_rtc
*rtc
= dev_get_drvdata(dev
);
344 rc5t619_rtc_alarm_flag_clr(dev
);
346 rtc_update_irq(rtc
->rtc
, 1, RTC_IRQF
| RTC_AF
);
350 static int rc5t619_rtc_probe(struct platform_device
*pdev
)
352 struct device
*dev
= &pdev
->dev
;
353 struct rn5t618
*rn5t618
= dev_get_drvdata(pdev
->dev
.parent
);
354 struct rc5t619_rtc
*rtc
;
358 rtc
= devm_kzalloc(dev
, sizeof(*rtc
), GFP_KERNEL
);
362 rtc
->rn5t618
= rn5t618
;
364 dev_set_drvdata(dev
, rtc
);
367 if (rn5t618
->irq_data
)
368 rtc
->irq
= regmap_irq_get_virq(rn5t618
->irq_data
,
374 err
= regmap_read(rtc
->rn5t618
->regmap
, RN5T618_RTC_CTRL2
, &ctrl2
);
378 /* disable rtc periodic function */
379 err
= rc5t619_rtc_periodic_disable(&pdev
->dev
);
383 if (ctrl2
& CTRL2_PON
) {
384 err
= rc5t619_rtc_alarm_flag_clr(&pdev
->dev
);
389 rtc
->rtc
= devm_rtc_allocate_device(&pdev
->dev
);
390 if (IS_ERR(rtc
->rtc
)) {
391 err
= PTR_ERR(rtc
->rtc
);
392 dev_err(dev
, "RTC device register: err %d\n", err
);
396 rtc
->rtc
->ops
= &rc5t619_rtc_ops
;
397 rtc
->rtc
->range_min
= RTC_TIMESTAMP_BEGIN_1900
;
398 rtc
->rtc
->range_max
= RTC_TIMESTAMP_END_2099
;
400 /* set interrupt and enable it */
401 if (rtc
->irq
!= -1) {
402 err
= devm_request_threaded_irq(&pdev
->dev
, rtc
->irq
, NULL
,
408 dev_err(&pdev
->dev
, "request IRQ:%d fail\n", rtc
->irq
);
411 err
= rc5t619_rtc_alarm_enable(&pdev
->dev
, 0);
417 device_init_wakeup(&pdev
->dev
, 1);
418 enable_irq_wake(rtc
->irq
);
421 /* system don't want to using alarm interrupt, so close it */
422 err
= rc5t619_rtc_alarm_enable(&pdev
->dev
, 0);
426 dev_warn(&pdev
->dev
, "rc5t619 interrupt is disabled\n");
429 return rtc_register_device(rtc
->rtc
);
432 static struct platform_driver rc5t619_rtc_driver
= {
434 .name
= "rc5t619-rtc",
436 .probe
= rc5t619_rtc_probe
,
439 module_platform_driver(rc5t619_rtc_driver
);
440 MODULE_ALIAS("platform:rc5t619-rtc");
441 MODULE_DESCRIPTION("RICOH RC5T619 RTC driver");
442 MODULE_LICENSE("GPL");