1 // SPDX-License-Identifier: GPL-2.0+
3 * Real Time Clock driver for Conexant Digicolor
5 * Copyright (C) 2015 Paradox Innovation Ltd.
7 * Author: Baruch Siach <baruch@tkos.co.il>
11 #include <linux/iopoll.h>
12 #include <linux/delay.h>
13 #include <linux/module.h>
14 #include <linux/platform_device.h>
15 #include <linux/rtc.h>
18 #define DC_RTC_CONTROL 0x0
19 #define DC_RTC_TIME 0x8
20 #define DC_RTC_REFERENCE 0xc
21 #define DC_RTC_ALARM 0x10
22 #define DC_RTC_INTFLAG_CLEAR 0x14
23 #define DC_RTC_INTENABLE 0x16
25 #define DC_RTC_CMD_MASK 0xf
26 #define DC_RTC_GO_BUSY BIT(7)
33 #define CMD_DELAY_US (10*1000)
34 #define CMD_TIMEOUT_US (500*CMD_DELAY_US)
37 struct rtc_device
*rtc_dev
;
41 static int dc_rtc_cmds(struct dc_rtc
*rtc
, const u8
*cmds
, int len
)
46 for (i
= 0; i
< len
; i
++) {
47 writeb_relaxed((cmds
[i
] & DC_RTC_CMD_MASK
) | DC_RTC_GO_BUSY
,
48 rtc
->regs
+ DC_RTC_CONTROL
);
49 ret
= readb_relaxed_poll_timeout(
50 rtc
->regs
+ DC_RTC_CONTROL
, val
,
51 !(val
& DC_RTC_GO_BUSY
), CMD_DELAY_US
, CMD_TIMEOUT_US
);
59 static int dc_rtc_read(struct dc_rtc
*rtc
, unsigned long *val
)
61 static const u8 read_cmds
[] = {CMD_READ
, CMD_NOP
};
62 u32 reference
, time1
, time2
;
65 ret
= dc_rtc_cmds(rtc
, read_cmds
, ARRAY_SIZE(read_cmds
));
69 reference
= readl_relaxed(rtc
->regs
+ DC_RTC_REFERENCE
);
70 time1
= readl_relaxed(rtc
->regs
+ DC_RTC_TIME
);
71 /* Read twice to ensure consistency */
73 time2
= readl_relaxed(rtc
->regs
+ DC_RTC_TIME
);
79 *val
= reference
+ time1
;
83 static int dc_rtc_write(struct dc_rtc
*rtc
, u32 val
)
85 static const u8 write_cmds
[] = {CMD_WRITE
, CMD_NOP
, CMD_RESET
, CMD_NOP
};
87 writel_relaxed(val
, rtc
->regs
+ DC_RTC_REFERENCE
);
88 return dc_rtc_cmds(rtc
, write_cmds
, ARRAY_SIZE(write_cmds
));
91 static int dc_rtc_read_time(struct device
*dev
, struct rtc_time
*tm
)
93 struct dc_rtc
*rtc
= dev_get_drvdata(dev
);
97 ret
= dc_rtc_read(rtc
, &now
);
100 rtc_time64_to_tm(now
, tm
);
105 static int dc_rtc_set_time(struct device
*dev
, struct rtc_time
*tm
)
107 struct dc_rtc
*rtc
= dev_get_drvdata(dev
);
109 return dc_rtc_write(rtc
, rtc_tm_to_time64(tm
));
112 static int dc_rtc_read_alarm(struct device
*dev
, struct rtc_wkalrm
*alarm
)
114 struct dc_rtc
*rtc
= dev_get_drvdata(dev
);
115 u32 alarm_reg
, reference
;
119 alarm_reg
= readl_relaxed(rtc
->regs
+ DC_RTC_ALARM
);
120 reference
= readl_relaxed(rtc
->regs
+ DC_RTC_REFERENCE
);
121 rtc_time64_to_tm(reference
+ alarm_reg
, &alarm
->time
);
123 ret
= dc_rtc_read(rtc
, &now
);
127 alarm
->pending
= alarm_reg
+ reference
> now
;
128 alarm
->enabled
= readl_relaxed(rtc
->regs
+ DC_RTC_INTENABLE
);
133 static int dc_rtc_set_alarm(struct device
*dev
, struct rtc_wkalrm
*alarm
)
135 struct dc_rtc
*rtc
= dev_get_drvdata(dev
);
139 alarm_time
= rtc_tm_to_time64(&alarm
->time
);
141 reference
= readl_relaxed(rtc
->regs
+ DC_RTC_REFERENCE
);
142 writel_relaxed(alarm_time
- reference
, rtc
->regs
+ DC_RTC_ALARM
);
144 writeb_relaxed(!!alarm
->enabled
, rtc
->regs
+ DC_RTC_INTENABLE
);
149 static int dc_rtc_alarm_irq_enable(struct device
*dev
, unsigned int enabled
)
151 struct dc_rtc
*rtc
= dev_get_drvdata(dev
);
153 writeb_relaxed(!!enabled
, rtc
->regs
+ DC_RTC_INTENABLE
);
158 static const struct rtc_class_ops dc_rtc_ops
= {
159 .read_time
= dc_rtc_read_time
,
160 .set_time
= dc_rtc_set_time
,
161 .read_alarm
= dc_rtc_read_alarm
,
162 .set_alarm
= dc_rtc_set_alarm
,
163 .alarm_irq_enable
= dc_rtc_alarm_irq_enable
,
166 static irqreturn_t
dc_rtc_irq(int irq
, void *dev_id
)
168 struct dc_rtc
*rtc
= dev_id
;
170 writeb_relaxed(1, rtc
->regs
+ DC_RTC_INTFLAG_CLEAR
);
171 rtc_update_irq(rtc
->rtc_dev
, 1, RTC_AF
| RTC_IRQF
);
176 static int __init
dc_rtc_probe(struct platform_device
*pdev
)
181 rtc
= devm_kzalloc(&pdev
->dev
, sizeof(*rtc
), GFP_KERNEL
);
185 rtc
->regs
= devm_platform_ioremap_resource(pdev
, 0);
186 if (IS_ERR(rtc
->regs
))
187 return PTR_ERR(rtc
->regs
);
189 rtc
->rtc_dev
= devm_rtc_allocate_device(&pdev
->dev
);
190 if (IS_ERR(rtc
->rtc_dev
))
191 return PTR_ERR(rtc
->rtc_dev
);
193 irq
= platform_get_irq(pdev
, 0);
196 ret
= devm_request_irq(&pdev
->dev
, irq
, dc_rtc_irq
, 0, pdev
->name
, rtc
);
200 platform_set_drvdata(pdev
, rtc
);
202 rtc
->rtc_dev
->ops
= &dc_rtc_ops
;
203 rtc
->rtc_dev
->range_max
= U32_MAX
;
205 return rtc_register_device(rtc
->rtc_dev
);
208 static const struct of_device_id dc_dt_ids
[] = {
209 { .compatible
= "cnxt,cx92755-rtc" },
212 MODULE_DEVICE_TABLE(of
, dc_dt_ids
);
214 static struct platform_driver dc_rtc_driver
= {
216 .name
= "digicolor_rtc",
217 .of_match_table
= of_match_ptr(dc_dt_ids
),
220 module_platform_driver_probe(dc_rtc_driver
, dc_rtc_probe
);
222 MODULE_AUTHOR("Baruch Siach <baruch@tkos.co.il>");
223 MODULE_DESCRIPTION("Conexant Digicolor Realtime Clock Driver (RTC)");
224 MODULE_LICENSE("GPL");