1 /***************************************************************************
3 DS1305 RTC character driver for uClinux mcfqspi control
4 These functions rely on the MCF_QSPI module for the SPI layer.
5 Modified from the IPAC DS1305 module for hcs12 communication
7 ---------------------------
8 begin : Thur April 28 2005
9 email : ngustavson@emacinc.com
10 (C) Copyright 2005 : EMAC.Inc - www.emacinc.com
11 ---------------------------
13 This program is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation; either version 2 of the License, or
16 (at your option) any later version.
18 ***************************************************************************/
19 #include <asm/DS1305RTC.h>
20 #include <linux/slab.h>
21 #include <linux/module.h>
22 #include <linux/kernel.h>
23 #include <linux/types.h>
24 #include <linux/errno.h>
25 #include <linux/slab.h>
26 #include <linux/version.h>
27 #include <asm/uaccess.h>
28 #include <linux/miscdevice.h>
30 MODULE_LICENSE("GPL");
32 /***************************************************************************
34 ***************************************************************************/
35 extern qspi_dev
*qspi_create_device(void);
36 extern int qspi_destroy_device(qspi_dev
*device
);
37 extern ssize_t
qspi_internal_read(qspi_dev
*dev
,char *buffer
, size_t length
,
38 loff_t
*off
,int qcr_cs
);
39 extern ssize_t
qspi_internal_write(qspi_dev
*dev
,const char *buffer
, size_t length
,
40 loff_t
*off
,int qcr_cs
);
41 extern u16
qspi_BAUD(int desired
);
42 extern void qspi_mutex_down(void);
43 extern void qspi_mutex_up(void);
46 /*!Write to a RTC register
47 @param device qspi device the RTC1305 belongs too
48 @param reg the register to write to(from the enumerated registers above)
49 @param the data to write to it
52 static int RTC_Write_Register(rtc_qspi_device
*dev
,int reg
, u8 data
)
55 output
[0] = reg
+ WRITE_OFFSET
;
58 qspi_internal_write(dev
->qspi
, output
, sizeof(output
),0,0);
63 /*!Read from a RTC register
64 @param device qspi device the RTC1305 belongs too
65 @param reg he register to write to(from the enumerated registers above)
66 @return the byte that was read
68 static u8
RTC_Read_Register(rtc_qspi_device
*dev
,int reg
)
73 dev
->qspi
->read_data
.length
= sizeof(buffer
);
74 dev
->qspi
->read_data
.buf
= buffer
;
77 qspi_internal_read(dev
->qspi
,buffer
, sizeof(buffer
),0,0);
80 dev
->qspi
->read_data
.length
=0;
81 dev
->qspi
->read_data
.buf
=NULL
;
86 static rtc_qspi_device
*RTC_create_device(void)
89 qspi_dev
*spi
= qspi_create_device();
94 if ((dev
= kmalloc(sizeof(rtc_qspi_device
), GFP_KERNEL
)) == NULL
) {
101 spi
->baud
= qspi_BAUD(2000000); /* intial baud rate 2M */
102 spi
->cpha
= 1; /* SPI clock phase */
106 RTC_Write_Register(dev
,CONTROL
,INTCN
);
111 static rtc_qspi_device
*RTC_destroy_device(rtc_qspi_device
*dev
){
114 qspi_destroy_device(dev
->qspi
);
118 /*!Get the current time from the RTC
119 This function reads the current time stored in the RTC's internal registers.
120 Alternatively each individual register can be returned using the RTC_ macros below
121 @param time a rtc_time structure that GetTime fills with data
124 static int RTC_GetTime(rtc_qspi_device
*dev
,struct rtc_time
*time
)
126 time
->tm_sec
= (RTC_SECONDS(dev
));
127 time
->tm_min
= (RTC_MINUTES(dev
));
128 time
->tm_hour
= (RTC_HOURS(dev
));
129 time
->tm_wday
= (RTC_DAY(dev
));
130 time
->tm_mday
= (RTC_DATE(dev
));
131 time
->tm_mon
= (RTC_MONTH(dev
));
132 time
->tm_year
= (RTC_YEAR(dev
));
133 time
->tm_sec
= RTC2TIME(time
->tm_sec
);
134 time
->tm_min
= RTC2TIME(time
->tm_min
);
135 time
->tm_hour
= RTC2TIME(time
->tm_hour
);
136 time
->tm_wday
= RTC2TIME(time
->tm_wday
);
137 time
->tm_mday
= RTC2TIME(time
->tm_mday
);
138 time
->tm_mon
= RTC2TIME(time
->tm_mon
);
139 time
->tm_year
= RTC2TIME(time
->tm_year
);
143 /*!Set the current time of the RTC
144 This function sets the current time stored in the RTC's internal registers.
145 Alternatively each individual register can be written using the
146 RTC_Write_Register function.
147 @param time a rtc_time structure SetTime writes to the clock
149 @see RTC_Write_Register function.
151 static int RTC_SetTime(rtc_qspi_device
*dev
,struct rtc_time
*time
)
153 RTC_SET_SECONDS(dev
,time
->tm_sec
);
154 RTC_SET_MINUTES(dev
,time
->tm_min
);
155 RTC_SET_HOURS(dev
,time
->tm_hour
);
156 RTC_SET_DAY(dev
,time
->tm_wday
);
157 RTC_SET_DATE(dev
,time
->tm_mday
);
158 RTC_SET_MONTH(dev
,time
->tm_mon
);
159 RTC_SET_YEAR(dev
,time
->tm_year
);
164 static int ds1305_ioctl(struct inode
*inode
, struct file
*filp
, unsigned int cmd
,
167 rtc_qspi_device
*dev
= filp
->private_data
;
168 struct rtc_time wtime
;
172 case RTC_RD_TIME
: /* Read the time/date from RTC */
174 memset(&wtime
, 0, sizeof(struct rtc_time
));
175 RTC_GetTime(dev
,&wtime
);
176 if(copy_to_user((void __user
*)arg
, &wtime
, sizeof wtime
))
180 case RTC_SET_TIME
: /* Set the RTC */
182 if (copy_from_user(&wtime
, (struct rtc_time __user
*)arg
,
183 sizeof(struct rtc_time
)))
185 RTC_SetTime(dev
,&wtime
);
197 static int ds1305_open (struct inode
*inode
, struct file
*filp
){
198 rtc_qspi_device
*dev
= RTC_create_device();
201 filp
->private_data
= dev
;
205 static int ds1305_release(struct inode
*inode
, struct file
*filp
){
206 RTC_destroy_device(filp
->private_data
);
210 struct file_operations ds1305_fops
={
213 release
: ds1305_release
,
216 static struct miscdevice ds1305rtc_dev
=
224 static int __init
ds1305_init(void){
226 //SET_MODULE_OWNER(&ds1305_fops);
228 /* the drivers (main) function*/
230 printk(" "DSNAME
" driver version " DS_DRIVER_V
" (c) " __DATE__
"\n");
231 printk(" N.Z. Gustavson (ngustavson@emacinc.com), EMAC.inc\n");
233 //DSMajor = register_chrdev(DSMAJORNUM, DSNAME, &ds1305_fops);
234 if (misc_register(&ds1305rtc_dev
)) {
235 printk(DSNAME
" driver failed to register");
239 printk(DSNAME
" Driver Registered\n");
243 static void __exit
ds1305_exit (void){
244 //unregister_chrdev(DSMajor,DSNAME);
245 misc_deregister(&ds1305rtc_dev
);
246 printk(DSNAME
" driver unloaded\n");
249 module_init(ds1305_init
);
250 module_exit(ds1305_exit
);
251 MODULE_ALIAS_MISCDEV(RTC_MINOR
);