drivers/char/Kconfig: don't mess it up for everyone else
[linux-2.6.32.60-moxart.git] / drivers / rtc / rtc-moxart.c
blobcb777581e3e4b28b9fbad8f198d67181a7f388a9
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. */
7 #include <linux/bcd.h>
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>
14 #include <linux/io.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;
25 void __iomem *ioaddr;
26 resource_size_t baseaddr;
27 unsigned long last_jiffies;
28 int irq;
29 unsigned int irqen;
30 int alrm_sec;
31 int alrm_min;
32 int alrm_hour;
33 int alrm_mday;
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)
42 u8 data;
43 unsigned long flags;
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);
64 return data;
67 static void moxart_rtc_write_register(u8 cmd, u8 data)
69 unsigned long flags;
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);
113 dbg_printk(KERN_INFO "MOXART RTC: moxart_rtc_set_time success tm_year"
114 "=%d tm_mon=%d tm_mday=%d tm_hour=%d tm_min=%d tm_sec=%d\n",
115 tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour,
116 tm->tm_min, tm->tm_sec);
118 return 0;
121 static int moxart_rtc_read_time(struct device *dev, struct rtc_time *tm)
123 unsigned char v;
125 spin_lock_irq(&rtc_lock);
127 v = moxart_rtc_read_register(GPIO_RTC_SECONDS_R);
128 tm->tm_sec = (((v & 0x70) >> 4) * 10) + (v & 0x0F);
129 v = moxart_rtc_read_register(GPIO_RTC_MINUTES_R);
130 tm->tm_min = (((v & 0x70) >> 4) * 10) + (v & 0x0F);
131 v = moxart_rtc_read_register(GPIO_RTC_HOURS_R);
132 if (v & 0x80) { /* 12-hour mode */
133 tm->tm_hour = (((v & 0x10) >> 4) * 10) + (v & 0x0F);
134 if (v & 0x20) { /* PM mode */
135 tm->tm_hour += 12;
136 if (tm->tm_hour >= 24)
137 tm->tm_hour = 0;
139 } else { /* 24-hour mode */
140 tm->tm_hour = (((v & 0x30) >> 4) * 10) + (v & 0x0F);
142 v = moxart_rtc_read_register(GPIO_RTC_DATE_R);
143 tm->tm_mday = (((v & 0x30) >> 4) * 10) + (v & 0x0F);
144 v = moxart_rtc_read_register(GPIO_RTC_MONTH_R);
145 tm->tm_mon = (((v & 0x10) >> 4) * 10) + (v & 0x0F);
146 tm->tm_mon--;
147 v = moxart_rtc_read_register(GPIO_RTC_YEAR_R);
148 tm->tm_year = (((v & 0xF0) >> 4) * 10) + (v & 0x0F);
149 tm->tm_year += 100;
150 if (tm->tm_year <= 69)
151 tm->tm_year += 100;
152 v = moxart_rtc_read_register(GPIO_RTC_DAY_R);
153 tm->tm_wday = (v & 0x0f) - 1;
154 tm->tm_yday = day_of_year[tm->tm_mon];
155 tm->tm_yday += (tm->tm_mday - 1);
156 if (tm->tm_mon >= 2) {
157 if (!(tm->tm_year % 4) && (tm->tm_year % 100))
158 tm->tm_yday++;
160 tm->tm_isdst = 0;
162 spin_unlock_irq(&rtc_lock);
164 return 0;
167 static int moxart_rtc_ioctl(struct device *dev, unsigned int cmd,
168 unsigned long arg)
170 struct platform_device *pdev = to_platform_device(dev);
171 struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
173 if (pdata->irq <= 0)
174 return -ENOIOCTLCMD; /* fall back into rtc-dev's emulation */
175 switch (cmd) {
176 default:
177 return -ENOIOCTLCMD;
179 return 0;
182 static const struct rtc_class_ops moxart_rtc_ops = {
183 .read_time = moxart_rtc_read_time,
184 .set_time = moxart_rtc_set_time,
185 .ioctl = moxart_rtc_ioctl,
188 static int __devinit moxart_rtc_probe(struct platform_device *pdev)
190 struct rtc_device *rtc;
191 struct resource *res;
192 struct rtc_plat_data *pdata = NULL;
193 void __iomem *ioaddr = NULL;
194 int ret = 0;
196 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
197 if (!res) {
198 printk(KERN_INFO "MOXART RTC: platform_get_resource failed\n");
199 return -ENODEV;
201 pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
202 if (!pdata) {
203 printk(KERN_INFO "MOXART RTC: kzalloc failed\n");
204 return -ENOMEM;
206 if (!request_mem_region(res->start, RTC_REG_SIZE, pdev->name)) {
207 ret = -EBUSY;
208 printk(KERN_INFO "MOXART RTC: request_mem_region failed\n");
209 goto out;
211 pdata->baseaddr = res->start;
212 ioaddr = ioremap(pdata->baseaddr, RTC_REG_SIZE);
213 if (!ioaddr) {
214 ret = -ENOMEM;
215 printk(KERN_INFO "MOXART RTC: ioremap failed\n");
216 goto out;
218 pdata->ioaddr = ioaddr;
220 moxart_gpio_mp_set(GPIO_RTC_MASK);
221 moxart_gpio_inout(GPIO_RTC_RESET, GPIO_EM1240_OUTPUT);
222 moxart_gpio_inout(GPIO_RTC_SCLK, GPIO_EM1240_OUTPUT);
224 rtc = rtc_device_register(pdev->name, &pdev->dev,
225 &moxart_rtc_ops, THIS_MODULE);
226 if (IS_ERR(rtc)) {
227 ret = PTR_ERR(rtc);
228 goto out;
230 pdata->rtc = rtc;
231 pdata->last_jiffies = jiffies;
232 platform_set_drvdata(pdev, pdata);
234 spin_lock_init(&rtc_lock);
236 printk(KERN_INFO "MOXART RTC: finished moxart_rtc_probe\n");
238 if (ret)
239 goto out;
241 return 0;
243 out:
244 if (pdata->rtc)
245 rtc_device_unregister(pdata->rtc);
246 if (ioaddr)
247 iounmap(ioaddr);
248 if (pdata->baseaddr)
249 release_mem_region(pdata->baseaddr, RTC_REG_SIZE);
250 kfree(pdata);
251 return ret;
254 static int __devexit moxart_rtc_remove(struct platform_device *pdev)
256 struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
258 rtc_device_unregister(pdata->rtc);
259 iounmap(pdata->ioaddr);
260 release_mem_region(pdata->baseaddr, RTC_REG_SIZE);
261 kfree(pdata);
262 return 0;
265 /* work with hotplug and coldplug */
266 MODULE_ALIAS("platform:rtc-moxart");
268 static struct platform_driver moxart_rtc_driver = {
269 .probe = moxart_rtc_probe,
270 .remove = __devexit_p(moxart_rtc_remove),
271 .driver = {
272 .name = "MOXART_RTC",
273 .owner = THIS_MODULE,
277 static __init int moxart_init(void)
279 return platform_driver_register(&moxart_rtc_driver);
282 static __exit void moxart_exit(void)
284 platform_driver_unregister(&moxart_rtc_driver);
287 module_init(moxart_init);
288 module_exit(moxart_exit);
290 MODULE_AUTHOR("Jonas Jensen <jonas.jensen@gmail.com>");
291 MODULE_DESCRIPTION("MOXART RTC driver");
292 MODULE_LICENSE("GPL");
293 MODULE_VERSION(DRV_VERSION);