| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221 |
- #include <linux/fs.h>
- #include <linux/module.h>
- #include <linux/errno.h>
- #include <linux/kernel.h>
- #include <linux/init.h>
- #include <linux/cdev.h>
- #include <linux/ioport.h>
- #include <linux/pci.h>
- #include <linux/rtc.h>
- #include <asm/uaccess.h>
- #include <asm/io.h>
- #include <asm/irq.h>
- #include <linux/interrupt.h>
- #include <asm/mach/irq.h>
- #include <asm/arch/regs-gpio.h>
- #include <linux/poll.h>
- #include <linux/platform_device.h>
- #define BUFSIZE 4096 /* vuart buf size */
- static volatile unsigned long *rtccon =NULL; //使能 RTCCON &= ~(1<<0)
- static volatile unsigned long *bcdyear =NULL; //年 BCDYEAR = 0xc
- static volatile unsigned long *bcdmon =NULL; //月 BCDMON = 0xb
- static volatile unsigned long *bcdday =NULL; //星期 BCDDAY = 0x3
- static volatile unsigned long *bcddate =NULL; //日 BCDDATE = 0xe
- static volatile unsigned long *bcdhour =NULL; //时BCDMON = 0xb
- static volatile unsigned long *bcdmin =NULL; //分 BCDDAY = 0x3
- static volatile unsigned long *bcdsec =NULL; //秒BCDDATE = 0xe
-
- static unsigned int fs2410_rtc_major =0;
- static struct class *fs2410_rtc_class =NULL;
- static struct rtc_time *user_time;
- static int fs2410_rtc_open(struct inode *inode, struct file *file)
- {
- /* 使能RTC */
- *rtccon |= (1<<0);
- return 0;
- }
- static ssize_t fs2410_rtc_write(struct file *file, const char __user *buf, size_t count, loff_t *opps)
- {
- int ret;
- int i;
- int year;
- int mon;
- int date;
- int day;
- int hour;
- int min;
- int sec;
- int hig;
- int low;
- user_time = (struct rtc_time *)kzalloc(sizeof(*user_time), GFP_KERNEL);
- ret = copy_from_user(user_time, buf, count);
- for (i = 0; i<6; i++) {
- printk("%d ", *(&(user_time->tm_year) - i));
- }
- printk("\n");
-
- //年2012-1970
- year = user_time->tm_year;
- year = (year - 1970) & 0xff;
- writeb(year, bcdyear);
- //月12 -> 1 0001
- mon = user_time->tm_mon;
- hig = mon/10;
- low = mon%10;
- mon = (mon &~0x1f)|((hig<<4)|low);
- writeb(mon, bcdmon);
- //日24 -> 01 0010
- date = user_time->tm_mday;
- hig = date/10;
- low = date%10;
- date = (date &~0x3f)|((hig<<4)|low);
- writeb(date, bcddate);
- //星期3 -> 3
- day = user_time->tm_wday;
- day = (day & 3);
- writeb(day, bcdday);
- //时18 -> 00 0000
- hour = user_time->tm_hour;
- hig = hour/10;
- low = hour%10;
- hour = (hour &~0x3f)|((hig<<4)|low);
- writeb(hour, bcdhour);
- //分 56 -> 000 0000
- min = user_time->tm_min;
- hig = min/10;
- low = min%10;
- min = (min &~0x7f)|((hig<<4)|low);
- writeb(min, bcdmin);
- //秒 34 -> 000 0000
- sec = user_time->tm_sec;
- hig = sec/10;
- low = sec%10;
- sec = (sec &~0x7f)|((hig<<4)|low);
- writeb(sec, bcdsec);
-
- return 0;
- }
- static ssize_t fs2410_rtc_read(struct file *file, char __user *buf, size_t count, loff_t *off)
- {
- int ret;
- int year;
- int mon;
- int date;
- int day;
- int hour;
- int min;
- int sec;
- char ker_buf[BUFSIZE];
- static struct rtc_time kernel_time;
- //年2012-1970
- year = readb(bcdyear);
- year = (year & 0xff) + 1970;
- kernel_time.tm_year = year;
- //月 1 0001
- mon = readb(bcdmon);
- mon = ((mon & (1<<4))>>4)*10 + (*bcdmon & 0xf);
- kernel_time.tm_mon= mon;
- //日 01 0010
- date = readb(bcddate);
- date = ((date & (3<<4))>>4)*10 + (*bcddate & 0xf);
- kernel_time.tm_mday= date ;
- //星期 3
- day = readb(bcdday);
- day = (day & 3);
- kernel_time.tm_wday= day;
- //时 00 0000
- hour = readb(bcdhour);
- hour = ((hour& (3<<4))>>4)*10 + (*bcdhour & 0xf);
- kernel_time.tm_hour= hour;
- //分 000 0000
- min = readb(bcdmin);
- min = ((min & (7<<4))>>4)*10 + (*bcdmin & 0xf);
- kernel_time.tm_min= min;
- //秒 000 0000
- sec = readb(bcdsec);
- sec = ((sec & (7<<4))>>4)*10 + (*bcdsec & 0xf);
- kernel_time.tm_sec= sec;
- sprintf(ker_buf, "%d-%d-%d %d %d:%d:%d", year, mon, date, day, hour, min, sec);
- ret = copy_to_user(buf, &kernel_time, count);
-
- return 0;
- }
- struct file_operations fs2410_rtc_fops ={
- .owner =THIS_MODULE,
- .open =fs2410_rtc_open,
- .write =fs2410_rtc_write,
- .read =fs2410_rtc_read,
- };
- int fs2410_rtc_probe(struct platform_device *pdev)
- {
- struct resource *res;
- /* 1.获取I/O内存资源 */
- res =platform_get_resource(pdev, IORESOURCE_MEM, 0);
- /* 2. 映射I/O内存资源 */
- rtccon =ioremap(res->start, res->end - res->start);
-
- bcdyear = rtccon + 18; //年 BCDYEAR = 0xc
- bcdmon = rtccon + 17; //月 BCDMON = 0xb
- bcdday = rtccon + 16; //星期 BCDDAY = 0x3
- bcddate = rtccon + 15; //日 BCDDATE = 0xe
- bcdhour= rtccon + 14; //时 BCDDATE = 0xe
- bcdmin= rtccon + 13; //分 BCDDATE = 0xe
- bcdsec= rtccon + 12; //秒 BCDDATE = 0xe
- /* 3. 注册到上层*/
- fs2410_rtc_major =register_chrdev(0, "rtcs",&fs2410_rtc_fops);
- fs2410_rtc_class =class_create(THIS_MODULE, "rtc_class");
- class_device_create(fs2410_rtc_class, NULL,MKDEV(fs2410_rtc_major, 0), NULL, "rtc");
-
- return 0;
- }
- int fs2410_rtc_remove(struct platform_device *pdev)
- {
- class_device_destroy(fs2410_rtc_class, MKDEV(fs2410_rtc_major, 0));
- class_destroy(fs2410_rtc_class);
- unregister_chrdev(fs2410_rtc_major, "rtcs");
- iounmap(rtccon);
- kfree(user_time);
- return 0;
- }
- struct platform_driver fs2410_rtc_driver ={
- .probe =fs2410_rtc_probe,
- .remove =fs2410_rtc_remove,
- .driver ={
- .owner =THIS_MODULE,
- .name ="fs2410-rtc",
- },
- };
- static int __init fs2410_rtc_drv_init(void)
- {
- platform_driver_register(&fs2410_rtc_driver);
- return 0;
- }
- static void __exit fs2410_rtc_drv_exit(void)
- {
- platform_driver_unregister(&fs2410_rtc_driver);
- }
- module_init(fs2410_rtc_drv_init);
- module_exit(fs2410_rtc_drv_exit);
- MODULE_LICENSE("GPL");
|