#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #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");