drv_rtc.c 4.4 KB

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