drv_rtc.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. /*
  2. * Copyright (c) 2006-2018, RT-Thread Development Team
  3. * Copyright (c) 2020, Du Huanpeng <548708880@qq.com>
  4. *
  5. * SPDX-License-Identifier: Apache-2.0
  6. *
  7. * Change Logs:
  8. * Date Author Notes
  9. * 2018-01-30 armink the first version
  10. * 2020-06-23 Du Huanpeng based on components/drivers/rtc/soft_rtc.c
  11. */
  12. #include <rthw.h>
  13. #include <rtthread.h>
  14. #include <rtdevice.h>
  15. #include <sys/time.h>
  16. #include "ls2k1000.h"
  17. #ifdef RT_USING_RTC
  18. struct loongson_rtc
  19. {
  20. rt_uint32_t sys_toytrim;
  21. rt_uint32_t sys_toywrite0;
  22. rt_uint32_t sys_toywrite1;
  23. rt_uint32_t sys_toyread0;
  24. rt_uint32_t sys_toyread1;
  25. rt_uint32_t sys_toymatch0;
  26. rt_uint32_t sys_toymatch1;
  27. rt_uint32_t sys_toymatch2;
  28. rt_uint32_t sys_rtcctrl;
  29. rt_uint32_t __pad4[3];
  30. rt_uint32_t __pad5[4];
  31. rt_uint32_t sys_rtctrim;
  32. rt_uint32_t sys_rtcwrite0;
  33. rt_uint32_t sys_rtcread0;
  34. rt_uint32_t sys_rtcmatch0;
  35. rt_uint32_t sys_rtcmatch1;
  36. rt_uint32_t sys_rtcmatch2;
  37. };
  38. /* bit field helpers. */
  39. #define __M(n) (~(~0<<(n)))
  40. #define __RBF(number, n) ((number)&__M(n))
  41. #define __BF(number, n, m) __RBF((number>>m), (n-m+1))
  42. #define BF(number, n, m) (m<n ? __BF(number, n, m) : __BF(number, m, n))
  43. struct rtctime
  44. {
  45. rt_uint32_t sys_toyread0;
  46. rt_uint32_t sys_toyread1;
  47. rt_uint32_t sys_rtcread0;
  48. };
  49. typedef struct rtctime rtctime_t;
  50. struct tm *localrtctime(const rtctime_t *rtctp)
  51. {
  52. static struct tm time;
  53. int msec;
  54. msec = BF(rtctp->sys_toyread0, 3, 0);
  55. msec *= 100;
  56. time.tm_sec = BF(rtctp->sys_toyread0, 9, 4);
  57. time.tm_min = BF(rtctp->sys_toyread0, 15, 10);
  58. time.tm_hour = BF(rtctp->sys_toyread0, 20, 16);
  59. time.tm_mday = BF(rtctp->sys_toyread0, 21, 25);
  60. time.tm_mon = BF(rtctp->sys_toyread0, 26, 31);
  61. /* struct tm has three more members:
  62. time.tm_isdst
  63. time.tm_wday
  64. time.tm_yday
  65. */
  66. time.tm_mon -= 1;
  67. time.tm_year = rtctp->sys_toyread1;
  68. return &time;
  69. }
  70. rtctime_t mkrtctime(struct tm *tm)
  71. {
  72. rtctime_t rtctm;
  73. struct tm tmptime;
  74. rtctm.sys_toyread0 <<= 31 - 26 + 1;
  75. rtctm.sys_toyread0 |= tm->tm_mon + 1;
  76. rtctm.sys_toyread0 <<= 25 - 21 + 1;
  77. rtctm.sys_toyread0 |= tm->tm_mday;
  78. rtctm.sys_toyread0 <<= 20 - 16 + 1;
  79. rtctm.sys_toyread0 |= tm->tm_hour;
  80. rtctm.sys_toyread0 <<= 15 - 10 + 1;
  81. rtctm.sys_toyread0 |= tm->tm_min;
  82. rtctm.sys_toyread0 <<= 9 - 4 + 1;
  83. rtctm.sys_toyread0 |= tm->tm_sec;
  84. /* Fixme: 0.1 second */
  85. rtctm.sys_toyread0 <<= 3 - 0 + 1;
  86. rtctm.sys_toyread0 |= 0;
  87. rtctm.sys_toyread1 = tm->tm_year;
  88. tmptime = *localrtctime(&rtctm);
  89. return rtctm;
  90. }
  91. static rt_err_t rt_rtc_open(rt_device_t dev, rt_uint16_t oflag)
  92. {
  93. return RT_EOK;
  94. }
  95. static rt_size_t rt_rtc_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
  96. {
  97. return 0;
  98. }
  99. static rt_err_t rt_rtc_ioctl(rt_device_t dev, int cmd, void *args)
  100. {
  101. rt_err_t err = RT_ENOSYS;
  102. static int count = 0;
  103. struct loongson_rtc *hw_rtc;
  104. rtctime_t rtctm;
  105. struct tm time;
  106. struct tm tmptime;
  107. time_t *t;
  108. hw_rtc = dev->user_data;
  109. t = (time_t *)args;
  110. time = *localtime(t);
  111. rtctm.sys_toyread0 = hw_rtc->sys_toyread0;
  112. rtctm.sys_toyread1 = hw_rtc->sys_toyread1;
  113. rtctm.sys_rtcread0 = hw_rtc->sys_rtcread0;
  114. tmptime = *localrtctime(&rtctm);
  115. switch (cmd)
  116. {
  117. case RT_DEVICE_CTRL_RTC_GET_TIME:
  118. *t = timegm(&tmptime);
  119. break;
  120. case RT_DEVICE_CTRL_RTC_SET_TIME:
  121. tmptime.tm_hour = time.tm_hour;
  122. tmptime.tm_min = time.tm_min;
  123. tmptime.tm_sec = time.tm_sec;
  124. tmptime.tm_year = time.tm_year;
  125. tmptime.tm_mon = time.tm_mon;
  126. tmptime.tm_mday = time.tm_mday;
  127. rtctm = mkrtctime(&tmptime);
  128. /* write to hw RTC */
  129. hw_rtc->sys_toywrite0 = rtctm.sys_toyread0;
  130. hw_rtc->sys_toywrite1 = rtctm.sys_toyread1;
  131. break;
  132. case RT_DEVICE_CTRL_RTC_GET_ALARM:
  133. break;
  134. case RT_DEVICE_CTRL_RTC_SET_ALARM:
  135. break;
  136. default:
  137. break;
  138. }
  139. return RT_EOK;
  140. }
  141. int rt_hw_rtc_init(void)
  142. {
  143. static struct rt_device rtc =
  144. {
  145. .type = RT_Device_Class_RTC,
  146. .init = RT_NULL,
  147. .open = rt_rtc_open,
  148. .close = RT_NULL,
  149. .read = rt_rtc_read,
  150. .write = RT_NULL,
  151. .control = rt_rtc_ioctl,
  152. .user_data = (void *)RTC_BASE,
  153. };
  154. rt_device_register(&rtc, "rtc", RT_DEVICE_FLAG_RDWR);
  155. }
  156. INIT_DEVICE_EXPORT(rt_hw_rtc_init);
  157. #endif /*RT_USING_RTC*/