2 * TX4939 internal RTC driver
3 * Based on RBTX49xx patch from CELF patch archive.
5 * This file is subject to the terms and conditions of the GNU General Public
6 * License. See the file "COPYING" in the main directory of this archive
9 * (C) Copyright TOSHIBA CORPORATION 2005-2007
11 #include <linux/rtc.h>
12 #include <linux/platform_device.h>
13 #include <linux/interrupt.h>
15 #include <asm/txx9/tx4939.h>
17 struct tx4939rtc_plat_data
{
18 struct rtc_device
*rtc
;
19 struct tx4939_rtc_reg __iomem
*rtcreg
;
22 static struct tx4939rtc_plat_data
*get_tx4939rtc_plat_data(struct device
*dev
)
24 return platform_get_drvdata(to_platform_device(dev
));
27 static int tx4939_rtc_cmd(struct tx4939_rtc_reg __iomem
*rtcreg
, int cmd
)
31 __raw_writel(cmd
, &rtcreg
->ctl
);
32 /* This might take 30us (next 32.768KHz clock) */
33 while (__raw_readl(&rtcreg
->ctl
) & TX4939_RTCCTL_BUSY
) {
34 /* timeout on approx. 100us (@ GBUS200MHz) */
42 static int tx4939_rtc_set_mmss(struct device
*dev
, unsigned long secs
)
44 struct tx4939rtc_plat_data
*pdata
= get_tx4939rtc_plat_data(dev
);
45 struct tx4939_rtc_reg __iomem
*rtcreg
= pdata
->rtcreg
;
55 spin_lock_irq(&pdata
->rtc
->irq_lock
);
56 __raw_writel(0, &rtcreg
->adr
);
57 for (i
= 0; i
< 6; i
++)
58 __raw_writel(buf
[i
], &rtcreg
->dat
);
59 ret
= tx4939_rtc_cmd(rtcreg
,
60 TX4939_RTCCTL_COMMAND_SETTIME
|
61 (__raw_readl(&rtcreg
->ctl
) & TX4939_RTCCTL_ALME
));
62 spin_unlock_irq(&pdata
->rtc
->irq_lock
);
66 static int tx4939_rtc_read_time(struct device
*dev
, struct rtc_time
*tm
)
68 struct tx4939rtc_plat_data
*pdata
= get_tx4939rtc_plat_data(dev
);
69 struct tx4939_rtc_reg __iomem
*rtcreg
= pdata
->rtcreg
;
74 spin_lock_irq(&pdata
->rtc
->irq_lock
);
75 ret
= tx4939_rtc_cmd(rtcreg
,
76 TX4939_RTCCTL_COMMAND_GETTIME
|
77 (__raw_readl(&rtcreg
->ctl
) & TX4939_RTCCTL_ALME
));
79 spin_unlock_irq(&pdata
->rtc
->irq_lock
);
82 __raw_writel(2, &rtcreg
->adr
);
83 for (i
= 2; i
< 6; i
++)
84 buf
[i
] = __raw_readl(&rtcreg
->dat
);
85 spin_unlock_irq(&pdata
->rtc
->irq_lock
);
86 sec
= (buf
[5] << 24) | (buf
[4] << 16) | (buf
[3] << 8) | buf
[2];
87 rtc_time_to_tm(sec
, tm
);
88 return rtc_valid_tm(tm
);
91 static int tx4939_rtc_set_alarm(struct device
*dev
, struct rtc_wkalrm
*alrm
)
93 struct tx4939rtc_plat_data
*pdata
= get_tx4939rtc_plat_data(dev
);
94 struct tx4939_rtc_reg __iomem
*rtcreg
= pdata
->rtcreg
;
99 if (alrm
->time
.tm_sec
< 0 ||
100 alrm
->time
.tm_min
< 0 ||
101 alrm
->time
.tm_hour
< 0 ||
102 alrm
->time
.tm_mday
< 0 ||
103 alrm
->time
.tm_mon
< 0 ||
104 alrm
->time
.tm_year
< 0)
106 rtc_tm_to_time(&alrm
->time
, &sec
);
113 spin_lock_irq(&pdata
->rtc
->irq_lock
);
114 __raw_writel(0, &rtcreg
->adr
);
115 for (i
= 0; i
< 6; i
++)
116 __raw_writel(buf
[i
], &rtcreg
->dat
);
117 ret
= tx4939_rtc_cmd(rtcreg
, TX4939_RTCCTL_COMMAND_SETALARM
|
118 (alrm
->enabled
? TX4939_RTCCTL_ALME
: 0));
119 spin_unlock_irq(&pdata
->rtc
->irq_lock
);
123 static int tx4939_rtc_read_alarm(struct device
*dev
, struct rtc_wkalrm
*alrm
)
125 struct tx4939rtc_plat_data
*pdata
= get_tx4939rtc_plat_data(dev
);
126 struct tx4939_rtc_reg __iomem
*rtcreg
= pdata
->rtcreg
;
129 unsigned char buf
[6];
132 spin_lock_irq(&pdata
->rtc
->irq_lock
);
133 ret
= tx4939_rtc_cmd(rtcreg
,
134 TX4939_RTCCTL_COMMAND_GETALARM
|
135 (__raw_readl(&rtcreg
->ctl
) & TX4939_RTCCTL_ALME
));
137 spin_unlock_irq(&pdata
->rtc
->irq_lock
);
140 __raw_writel(2, &rtcreg
->adr
);
141 for (i
= 2; i
< 6; i
++)
142 buf
[i
] = __raw_readl(&rtcreg
->dat
);
143 ctl
= __raw_readl(&rtcreg
->ctl
);
144 alrm
->enabled
= (ctl
& TX4939_RTCCTL_ALME
) ? 1 : 0;
145 alrm
->pending
= (ctl
& TX4939_RTCCTL_ALMD
) ? 1 : 0;
146 spin_unlock_irq(&pdata
->rtc
->irq_lock
);
147 sec
= (buf
[5] << 24) | (buf
[4] << 16) | (buf
[3] << 8) | buf
[2];
148 rtc_time_to_tm(sec
, &alrm
->time
);
149 return rtc_valid_tm(&alrm
->time
);
152 static int tx4939_rtc_alarm_irq_enable(struct device
*dev
, unsigned int enabled
)
154 struct tx4939rtc_plat_data
*pdata
= get_tx4939rtc_plat_data(dev
);
156 spin_lock_irq(&pdata
->rtc
->irq_lock
);
157 tx4939_rtc_cmd(pdata
->rtcreg
,
158 TX4939_RTCCTL_COMMAND_NOP
|
159 (enabled
? TX4939_RTCCTL_ALME
: 0));
160 spin_unlock_irq(&pdata
->rtc
->irq_lock
);
164 static irqreturn_t
tx4939_rtc_interrupt(int irq
, void *dev_id
)
166 struct tx4939rtc_plat_data
*pdata
= get_tx4939rtc_plat_data(dev_id
);
167 struct tx4939_rtc_reg __iomem
*rtcreg
= pdata
->rtcreg
;
168 unsigned long events
= RTC_IRQF
;
170 spin_lock(&pdata
->rtc
->irq_lock
);
171 if (__raw_readl(&rtcreg
->ctl
) & TX4939_RTCCTL_ALMD
) {
173 tx4939_rtc_cmd(rtcreg
, TX4939_RTCCTL_COMMAND_NOP
);
175 spin_unlock(&pdata
->rtc
->irq_lock
);
176 rtc_update_irq(pdata
->rtc
, 1, events
);
180 static const struct rtc_class_ops tx4939_rtc_ops
= {
181 .read_time
= tx4939_rtc_read_time
,
182 .read_alarm
= tx4939_rtc_read_alarm
,
183 .set_alarm
= tx4939_rtc_set_alarm
,
184 .set_mmss
= tx4939_rtc_set_mmss
,
185 .alarm_irq_enable
= tx4939_rtc_alarm_irq_enable
,
188 static ssize_t
tx4939_rtc_nvram_read(struct kobject
*kobj
,
189 struct bin_attribute
*bin_attr
,
190 char *buf
, loff_t pos
, size_t size
)
192 struct device
*dev
= container_of(kobj
, struct device
, kobj
);
193 struct tx4939rtc_plat_data
*pdata
= get_tx4939rtc_plat_data(dev
);
194 struct tx4939_rtc_reg __iomem
*rtcreg
= pdata
->rtcreg
;
197 spin_lock_irq(&pdata
->rtc
->irq_lock
);
198 for (count
= 0; size
> 0 && pos
< TX4939_RTC_REG_RAMSIZE
;
200 __raw_writel(pos
++, &rtcreg
->adr
);
201 *buf
++ = __raw_readl(&rtcreg
->dat
);
203 spin_unlock_irq(&pdata
->rtc
->irq_lock
);
207 static ssize_t
tx4939_rtc_nvram_write(struct kobject
*kobj
,
208 struct bin_attribute
*bin_attr
,
209 char *buf
, loff_t pos
, size_t size
)
211 struct device
*dev
= container_of(kobj
, struct device
, kobj
);
212 struct tx4939rtc_plat_data
*pdata
= get_tx4939rtc_plat_data(dev
);
213 struct tx4939_rtc_reg __iomem
*rtcreg
= pdata
->rtcreg
;
216 spin_lock_irq(&pdata
->rtc
->irq_lock
);
217 for (count
= 0; size
> 0 && pos
< TX4939_RTC_REG_RAMSIZE
;
219 __raw_writel(pos
++, &rtcreg
->adr
);
220 __raw_writel(*buf
++, &rtcreg
->dat
);
222 spin_unlock_irq(&pdata
->rtc
->irq_lock
);
226 static struct bin_attribute tx4939_rtc_nvram_attr
= {
229 .mode
= S_IRUGO
| S_IWUSR
,
231 .size
= TX4939_RTC_REG_RAMSIZE
,
232 .read
= tx4939_rtc_nvram_read
,
233 .write
= tx4939_rtc_nvram_write
,
236 static int __init
tx4939_rtc_probe(struct platform_device
*pdev
)
238 struct rtc_device
*rtc
;
239 struct tx4939rtc_plat_data
*pdata
;
240 struct resource
*res
;
243 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
246 irq
= platform_get_irq(pdev
, 0);
249 pdata
= devm_kzalloc(&pdev
->dev
, sizeof(*pdata
), GFP_KERNEL
);
252 platform_set_drvdata(pdev
, pdata
);
254 if (!devm_request_mem_region(&pdev
->dev
, res
->start
,
255 resource_size(res
), pdev
->name
))
257 pdata
->rtcreg
= devm_ioremap(&pdev
->dev
, res
->start
,
262 tx4939_rtc_cmd(pdata
->rtcreg
, TX4939_RTCCTL_COMMAND_NOP
);
263 if (devm_request_irq(&pdev
->dev
, irq
, tx4939_rtc_interrupt
,
264 IRQF_DISABLED
| IRQF_SHARED
,
265 pdev
->name
, &pdev
->dev
) < 0) {
268 rtc
= rtc_device_register(pdev
->name
, &pdev
->dev
,
269 &tx4939_rtc_ops
, THIS_MODULE
);
273 ret
= sysfs_create_bin_file(&pdev
->dev
.kobj
, &tx4939_rtc_nvram_attr
);
275 rtc_device_unregister(rtc
);
279 static int __exit
tx4939_rtc_remove(struct platform_device
*pdev
)
281 struct tx4939rtc_plat_data
*pdata
= platform_get_drvdata(pdev
);
282 struct rtc_device
*rtc
= pdata
->rtc
;
284 spin_lock_irq(&rtc
->irq_lock
);
285 tx4939_rtc_cmd(pdata
->rtcreg
, TX4939_RTCCTL_COMMAND_NOP
);
286 spin_unlock_irq(&rtc
->irq_lock
);
287 sysfs_remove_bin_file(&pdev
->dev
.kobj
, &tx4939_rtc_nvram_attr
);
288 rtc_device_unregister(rtc
);
289 platform_set_drvdata(pdev
, NULL
);
293 static struct platform_driver tx4939_rtc_driver
= {
294 .remove
= __exit_p(tx4939_rtc_remove
),
297 .owner
= THIS_MODULE
,
301 static int __init
tx4939rtc_init(void)
303 return platform_driver_probe(&tx4939_rtc_driver
, tx4939_rtc_probe
);
306 static void __exit
tx4939rtc_exit(void)
308 platform_driver_unregister(&tx4939_rtc_driver
);
311 module_init(tx4939rtc_init
);
312 module_exit(tx4939rtc_exit
);
314 MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>");
315 MODULE_DESCRIPTION("TX4939 internal RTC driver");
316 MODULE_LICENSE("GPL");
317 MODULE_ALIAS("platform:tx4939rtc");