rtc_drv.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. #include <linux/fs.h>
  2. #include <linux/module.h>
  3. #include <linux/errno.h>
  4. #include <linux/kernel.h>
  5. #include <linux/init.h>
  6. #include <linux/cdev.h>
  7. #include <linux/ioport.h>
  8. #include <linux/pci.h>
  9. #include <linux/rtc.h>
  10. #include <asm/uaccess.h>
  11. #include <asm/io.h>
  12. #include <asm/irq.h>
  13. #include <linux/interrupt.h>
  14. #include <asm/mach/irq.h>
  15. #include <asm/arch/regs-gpio.h>
  16. #include <linux/poll.h>
  17. #include <linux/platform_device.h>
  18. #define BUFSIZE 4096 /* vuart buf size */
  19. static volatile unsigned long *rtccon =NULL; //使能 RTCCON &= ~(1<<0)
  20. static volatile unsigned long *bcdyear =NULL; //年 BCDYEAR = 0xc
  21. static volatile unsigned long *bcdmon =NULL; //月 BCDMON = 0xb
  22. static volatile unsigned long *bcdday =NULL; //星期 BCDDAY = 0x3
  23. static volatile unsigned long *bcddate =NULL; //日 BCDDATE = 0xe
  24. static volatile unsigned long *bcdhour =NULL; //时BCDMON = 0xb
  25. static volatile unsigned long *bcdmin =NULL; //分 BCDDAY = 0x3
  26. static volatile unsigned long *bcdsec =NULL; //秒BCDDATE = 0xe
  27. static unsigned int fs2410_rtc_major =0;
  28. static struct class *fs2410_rtc_class =NULL;
  29. static struct rtc_time *user_time;
  30. static int fs2410_rtc_open(struct inode *inode, struct file *file)
  31. {
  32. /* 使能RTC */
  33. *rtccon |= (1<<0);
  34. return 0;
  35. }
  36. static ssize_t fs2410_rtc_write(struct file *file, const char __user *buf, size_t count, loff_t *opps)
  37. {
  38. int ret;
  39. int i;
  40. int year;
  41. int mon;
  42. int date;
  43. int day;
  44. int hour;
  45. int min;
  46. int sec;
  47. int hig;
  48. int low;
  49. user_time = (struct rtc_time *)kzalloc(sizeof(*user_time), GFP_KERNEL);
  50. ret = copy_from_user(user_time, buf, count);
  51. for (i = 0; i<6; i++) {
  52. printk("%d ", *(&(user_time->tm_year) - i));
  53. }
  54. printk("\n");
  55. //年2012-1970
  56. year = user_time->tm_year;
  57. year = (year - 1970) & 0xff;
  58. writeb(year, bcdyear);
  59. //月12 -> 1 0001
  60. mon = user_time->tm_mon;
  61. hig = mon/10;
  62. low = mon%10;
  63. mon = (mon &~0x1f)|((hig<<4)|low);
  64. writeb(mon, bcdmon);
  65. //日24 -> 01 0010
  66. date = user_time->tm_mday;
  67. hig = date/10;
  68. low = date%10;
  69. date = (date &~0x3f)|((hig<<4)|low);
  70. writeb(date, bcddate);
  71. //星期3 -> 3
  72. day = user_time->tm_wday;
  73. day = (day & 3);
  74. writeb(day, bcdday);
  75. //时18 -> 00 0000
  76. hour = user_time->tm_hour;
  77. hig = hour/10;
  78. low = hour%10;
  79. hour = (hour &~0x3f)|((hig<<4)|low);
  80. writeb(hour, bcdhour);
  81. //分 56 -> 000 0000
  82. min = user_time->tm_min;
  83. hig = min/10;
  84. low = min%10;
  85. min = (min &~0x7f)|((hig<<4)|low);
  86. writeb(min, bcdmin);
  87. //秒 34 -> 000 0000
  88. sec = user_time->tm_sec;
  89. hig = sec/10;
  90. low = sec%10;
  91. sec = (sec &~0x7f)|((hig<<4)|low);
  92. writeb(sec, bcdsec);
  93. return 0;
  94. }
  95. static ssize_t fs2410_rtc_read(struct file *file, char __user *buf, size_t count, loff_t *off)
  96. {
  97. int ret;
  98. int year;
  99. int mon;
  100. int date;
  101. int day;
  102. int hour;
  103. int min;
  104. int sec;
  105. char ker_buf[BUFSIZE];
  106. static struct rtc_time kernel_time;
  107. //年2012-1970
  108. year = readb(bcdyear);
  109. year = (year & 0xff) + 1970;
  110. kernel_time.tm_year = year;
  111. //月 1 0001
  112. mon = readb(bcdmon);
  113. mon = ((mon & (1<<4))>>4)*10 + (*bcdmon & 0xf);
  114. kernel_time.tm_mon= mon;
  115. //日 01 0010
  116. date = readb(bcddate);
  117. date = ((date & (3<<4))>>4)*10 + (*bcddate & 0xf);
  118. kernel_time.tm_mday= date ;
  119. //星期 3
  120. day = readb(bcdday);
  121. day = (day & 3);
  122. kernel_time.tm_wday= day;
  123. //时 00 0000
  124. hour = readb(bcdhour);
  125. hour = ((hour& (3<<4))>>4)*10 + (*bcdhour & 0xf);
  126. kernel_time.tm_hour= hour;
  127. //分 000 0000
  128. min = readb(bcdmin);
  129. min = ((min & (7<<4))>>4)*10 + (*bcdmin & 0xf);
  130. kernel_time.tm_min= min;
  131. //秒 000 0000
  132. sec = readb(bcdsec);
  133. sec = ((sec & (7<<4))>>4)*10 + (*bcdsec & 0xf);
  134. kernel_time.tm_sec= sec;
  135. sprintf(ker_buf, "%d-%d-%d %d %d:%d:%d", year, mon, date, day, hour, min, sec);
  136. ret = copy_to_user(buf, &kernel_time, count);
  137. return 0;
  138. }
  139. struct file_operations fs2410_rtc_fops ={
  140. .owner =THIS_MODULE,
  141. .open =fs2410_rtc_open,
  142. .write =fs2410_rtc_write,
  143. .read =fs2410_rtc_read,
  144. };
  145. int fs2410_rtc_probe(struct platform_device *pdev)
  146. {
  147. struct resource *res;
  148. /* 1.获取I/O内存资源 */
  149. res =platform_get_resource(pdev, IORESOURCE_MEM, 0);
  150. /* 2. 映射I/O内存资源 */
  151. rtccon =ioremap(res->start, res->end - res->start);
  152. bcdyear = rtccon + 18; //年 BCDYEAR = 0xc
  153. bcdmon = rtccon + 17; //月 BCDMON = 0xb
  154. bcdday = rtccon + 16; //星期 BCDDAY = 0x3
  155. bcddate = rtccon + 15; //日 BCDDATE = 0xe
  156. bcdhour= rtccon + 14; //时 BCDDATE = 0xe
  157. bcdmin= rtccon + 13; //分 BCDDATE = 0xe
  158. bcdsec= rtccon + 12; //秒 BCDDATE = 0xe
  159. /* 3. 注册到上层*/
  160. fs2410_rtc_major =register_chrdev(0, "rtcs",&fs2410_rtc_fops);
  161. fs2410_rtc_class =class_create(THIS_MODULE, "rtc_class");
  162. class_device_create(fs2410_rtc_class, NULL,MKDEV(fs2410_rtc_major, 0), NULL, "rtc");
  163. return 0;
  164. }
  165. int fs2410_rtc_remove(struct platform_device *pdev)
  166. {
  167. class_device_destroy(fs2410_rtc_class, MKDEV(fs2410_rtc_major, 0));
  168. class_destroy(fs2410_rtc_class);
  169. unregister_chrdev(fs2410_rtc_major, "rtcs");
  170. iounmap(rtccon);
  171. kfree(user_time);
  172. return 0;
  173. }
  174. struct platform_driver fs2410_rtc_driver ={
  175. .probe =fs2410_rtc_probe,
  176. .remove =fs2410_rtc_remove,
  177. .driver ={
  178. .owner =THIS_MODULE,
  179. .name ="fs2410-rtc",
  180. },
  181. };
  182. static int __init fs2410_rtc_drv_init(void)
  183. {
  184. platform_driver_register(&fs2410_rtc_driver);
  185. return 0;
  186. }
  187. static void __exit fs2410_rtc_drv_exit(void)
  188. {
  189. platform_driver_unregister(&fs2410_rtc_driver);
  190. }
  191. module_init(fs2410_rtc_drv_init);
  192. module_exit(fs2410_rtc_drv_exit);
  193. MODULE_LICENSE("GPL");