1 /* Copyright (C) 2013 Jonas Jensen <jonas.jensen@gmail.com>
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License as published by the
4 * Free Software Foundation; either version 2 of the License,
5 * or (at your option) any later version. */
8 #include <linux/init.h>
9 #include <linux/kernel.h>
10 #include <linux/delay.h>
11 #include <linux/jiffies.h>
12 #include <linux/rtc.h>
13 #include <linux/platform_device.h>
16 #include <mach/hardware.h>
17 #include <mach/gpio.h>
19 #define DRV_VERSION "1.0"
21 #define RTC_REG_SIZE 0x1000
23 struct rtc_plat_data
{
24 struct rtc_device
*rtc
;
26 resource_size_t baseaddr
;
27 unsigned long last_jiffies
;
36 static spinlock_t rtc_lock
;
37 static int day_of_year
[12] = {0, 31, 59, 90, 120, 151, 181,
38 212, 243, 273, 304, 334};
40 static u8
moxart_rtc_read_register(u8 cmd
)
45 local_irq_save(flags
);
47 moxart_gpio_inout(GPIO_RTC_DATA
, GPIO_EM1240_OUTPUT
);
48 moxart_gpio_set(GPIO_RTC_RESET
, GPIO_EM1240_HIGH
);
49 udelay(GPIO_RTC_DELAY_TIME
);
51 moxart_gpio_write_byte(cmd
);
53 moxart_gpio_inout(GPIO_RTC_DATA
, GPIO_EM1240_INPUT
);
54 udelay(GPIO_RTC_DELAY_TIME
);
56 data
= moxart_gpio_read_byte();
58 moxart_gpio_set(GPIO_RTC_SCLK
, GPIO_EM1240_LOW
);
59 moxart_gpio_set(GPIO_RTC_RESET
, GPIO_EM1240_LOW
);
60 udelay(GPIO_RTC_DELAY_TIME
);
62 local_irq_restore(flags
);
67 static void moxart_rtc_write_register(u8 cmd
, u8 data
)
71 local_irq_save(flags
);
73 moxart_gpio_inout(GPIO_RTC_DATA
, GPIO_EM1240_OUTPUT
);
74 moxart_gpio_set(GPIO_RTC_RESET
, GPIO_EM1240_HIGH
);
75 udelay(GPIO_RTC_DELAY_TIME
);
77 moxart_gpio_write_byte(cmd
);
79 moxart_gpio_inout(GPIO_RTC_DATA
, GPIO_EM1240_OUTPUT
);
81 moxart_gpio_write_byte(data
);
83 moxart_gpio_set(GPIO_RTC_SCLK
, GPIO_EM1240_LOW
);
84 moxart_gpio_set(GPIO_RTC_RESET
, GPIO_EM1240_LOW
);
85 udelay(GPIO_RTC_DELAY_TIME
);
86 /* moxart_gpio_inout(GPIO_RTC_DATA, GPIO_EM1240_INPUT); */
88 local_irq_restore(flags
);
91 static int moxart_rtc_set_time(struct device
*dev
, struct rtc_time
*tm
)
93 spin_lock_irq(&rtc_lock
);
95 moxart_rtc_write_register(GPIO_RTC_PROTECT_W
, 0);
96 moxart_rtc_write_register(GPIO_RTC_YEAR_W
,
97 ((((tm
->tm_year
- 100) / 10) << 4) |
98 ((tm
->tm_year
- 100) % 10)));
99 moxart_rtc_write_register(GPIO_RTC_MONTH_W
,
100 ((((tm
->tm_mon
+ 1) / 10) << 4) | ((tm
->tm_mon
+ 1) % 10)));
101 moxart_rtc_write_register(GPIO_RTC_DATE_W
,
102 (((tm
->tm_mday
/ 10) << 4) | (tm
->tm_mday
% 10)));
103 moxart_rtc_write_register(GPIO_RTC_HOURS_W
,
104 (((tm
->tm_hour
/ 10) << 4) | (tm
->tm_hour
% 10)));
105 moxart_rtc_write_register(GPIO_RTC_MINUTES_W
,
106 (((tm
->tm_min
/ 10) << 4) | (tm
->tm_min
% 10)));
107 moxart_rtc_write_register(GPIO_RTC_SECONDS_W
,
108 (((tm
->tm_sec
/ 10) << 4) | (tm
->tm_sec
% 10)));
109 moxart_rtc_write_register(GPIO_RTC_PROTECT_W
, 0x80);
111 spin_unlock_irq(&rtc_lock
);
114 "MOXART RTC: moxart_rtc_set_time success tm_year=%d tm_mon=%d\n"
115 "tm_mday=%d tm_hour=%d tm_min=%d tm_sec=%d\n",
116 tm
->tm_year
, tm
->tm_mon
, tm
->tm_mday
, tm
->tm_hour
,
117 tm
->tm_min
, tm
->tm_sec
);
122 static int moxart_rtc_read_time(struct device
*dev
, struct rtc_time
*tm
)
126 spin_lock_irq(&rtc_lock
);
128 v
= moxart_rtc_read_register(GPIO_RTC_SECONDS_R
);
129 tm
->tm_sec
= (((v
& 0x70) >> 4) * 10) + (v
& 0x0F);
130 v
= moxart_rtc_read_register(GPIO_RTC_MINUTES_R
);
131 tm
->tm_min
= (((v
& 0x70) >> 4) * 10) + (v
& 0x0F);
132 v
= moxart_rtc_read_register(GPIO_RTC_HOURS_R
);
133 if (v
& 0x80) { /* 12-hour mode */
134 tm
->tm_hour
= (((v
& 0x10) >> 4) * 10) + (v
& 0x0F);
135 if (v
& 0x20) { /* PM mode */
137 if (tm
->tm_hour
>= 24)
140 } else { /* 24-hour mode */
141 tm
->tm_hour
= (((v
& 0x30) >> 4) * 10) + (v
& 0x0F);
143 v
= moxart_rtc_read_register(GPIO_RTC_DATE_R
);
144 tm
->tm_mday
= (((v
& 0x30) >> 4) * 10) + (v
& 0x0F);
145 v
= moxart_rtc_read_register(GPIO_RTC_MONTH_R
);
146 tm
->tm_mon
= (((v
& 0x10) >> 4) * 10) + (v
& 0x0F);
148 v
= moxart_rtc_read_register(GPIO_RTC_YEAR_R
);
149 tm
->tm_year
= (((v
& 0xF0) >> 4) * 10) + (v
& 0x0F);
151 if (tm
->tm_year
<= 69)
153 v
= moxart_rtc_read_register(GPIO_RTC_DAY_R
);
154 tm
->tm_wday
= (v
& 0x0f) - 1;
155 tm
->tm_yday
= day_of_year
[tm
->tm_mon
];
156 tm
->tm_yday
+= (tm
->tm_mday
- 1);
157 if (tm
->tm_mon
>= 2) {
158 if (!(tm
->tm_year
% 4) && (tm
->tm_year
% 100))
163 spin_unlock_irq(&rtc_lock
);
168 static int moxart_rtc_ioctl(struct device
*dev
, unsigned int cmd
,
171 struct platform_device
*pdev
= to_platform_device(dev
);
172 struct rtc_plat_data
*pdata
= platform_get_drvdata(pdev
);
175 return -ENOIOCTLCMD
; /* fall back into rtc-dev's emulation */
183 static const struct rtc_class_ops moxart_rtc_ops
= {
184 .read_time
= moxart_rtc_read_time
,
185 .set_time
= moxart_rtc_set_time
,
186 .ioctl
= moxart_rtc_ioctl
,
189 static int moxart_rtc_probe(struct platform_device
*pdev
)
191 struct rtc_device
*rtc
;
192 struct resource
*res
;
193 struct rtc_plat_data
*pdata
= NULL
;
194 void __iomem
*ioaddr
= NULL
;
197 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
200 "MOXART RTC: platform_get_resource failed\n");
203 pdata
= kzalloc(sizeof(*pdata
), GFP_KERNEL
);
205 dev_info(&pdev
->dev
, "MOXART RTC: devm_kzalloc failed\n");
208 if (!request_mem_region(res
->start
, RTC_REG_SIZE
, pdev
->name
)) {
210 dev_info(&pdev
->dev
, "MOXART RTC: request_mem_region failed\n");
213 pdata
->baseaddr
= res
->start
;
214 ioaddr
= ioremap(pdata
->baseaddr
, RTC_REG_SIZE
);
217 dev_info(&pdev
->dev
, "MOXART RTC: ioremap failed\n");
220 pdata
->ioaddr
= ioaddr
;
222 moxart_gpio_mp_set(GPIO_RTC_MASK
);
223 moxart_gpio_inout(GPIO_RTC_RESET
, GPIO_EM1240_OUTPUT
);
224 moxart_gpio_inout(GPIO_RTC_SCLK
, GPIO_EM1240_OUTPUT
);
226 rtc
= rtc_device_register(pdev
->name
, &pdev
->dev
,
227 &moxart_rtc_ops
, THIS_MODULE
);
233 pdata
->last_jiffies
= jiffies
;
234 platform_set_drvdata(pdev
, pdata
);
236 spin_lock_init(&rtc_lock
);
238 dev_info(&pdev
->dev
, "MOXART RTC: finished moxart_rtc_probe\n");
247 rtc_device_unregister(pdata
->rtc
);
251 release_mem_region(pdata
->baseaddr
, RTC_REG_SIZE
);
256 static int moxart_rtc_remove(struct platform_device
*pdev
)
258 struct rtc_plat_data
*pdata
= platform_get_drvdata(pdev
);
260 rtc_device_unregister(pdata
->rtc
);
261 iounmap(pdata
->ioaddr
);
262 release_mem_region(pdata
->baseaddr
, RTC_REG_SIZE
);
267 /* work with hotplug and coldplug */
268 MODULE_ALIAS("platform:rtc-moxart");
270 static struct platform_driver moxart_rtc_driver
= {
271 .probe
= moxart_rtc_probe
,
272 .remove
= __devexit_p(moxart_rtc_remove
),
274 .name
= "MOXART_RTC",
275 .owner
= THIS_MODULE
,
279 static __init
int moxart_init(void)
281 return platform_driver_register(&moxart_rtc_driver
);
284 static __exit
void moxart_exit(void)
286 platform_driver_unregister(&moxart_rtc_driver
);
289 module_init(moxart_init
);
290 module_exit(moxart_exit
);
292 MODULE_AUTHOR("Jonas Jensen <jonas.jensen@gmail.com>");
293 MODULE_DESCRIPTION("MOXART RTC driver");
294 MODULE_LICENSE("GPL");
295 MODULE_VERSION(DRV_VERSION
);