mtk_rtc_hal_common.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. #if defined(CONFIG_MTK_RTC)
  2. #ifdef pr_fmt
  3. #undef pr_fmt
  4. #endif
  5. #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  6. #include <linux/delay.h>
  7. #include <linux/init.h>
  8. #include <linux/module.h>
  9. #include <linux/kernel.h>
  10. #include <linux/rtc.h>
  11. #include <mach/upmu_hw.h>
  12. #include <linux/spinlock.h>
  13. #include <linux/interrupt.h>
  14. #include <linux/platform_device.h>
  15. #include <linux/delay.h>
  16. #include <linux/types.h>
  17. #include <mach/mt_rtc_hw.h>
  18. #include <mach/mtk_rtc_hal.h>
  19. #include <mtk_rtc_hal_common.h>
  20. #include <mt_pmic_wrap.h>
  21. #define hal_rtc_xinfo(fmt, args...) \
  22. pr_notice(fmt, ##args)
  23. #define hal_rtc_xerror(fmt, args...) \
  24. pr_err(fmt, ##args)
  25. #define hal_rtc_xfatal(fmt, args...) \
  26. pr_emerg(fmt, ##args)
  27. u16 rtc_read(u16 addr)
  28. {
  29. u32 rdata = 0;
  30. pwrap_read((u32) addr, &rdata);
  31. return (u16) rdata;
  32. }
  33. void rtc_write(u16 addr, u16 data)
  34. {
  35. pwrap_write((u32) addr, (u32) data);
  36. }
  37. void rtc_busy_wait(void)
  38. {
  39. do {
  40. while (rtc_read(RTC_BBPU) & RTC_BBPU_CBUSY)
  41. ;
  42. } while (0);
  43. }
  44. void rtc_write_trigger(void)
  45. {
  46. rtc_write(RTC_WRTGR, 1);
  47. rtc_busy_wait();
  48. }
  49. void rtc_writeif_unlock(void)
  50. {
  51. rtc_write(RTC_PROT, RTC_PROT_UNLOCK1);
  52. rtc_write_trigger();
  53. rtc_write(RTC_PROT, RTC_PROT_UNLOCK2);
  54. rtc_write_trigger();
  55. }
  56. void hal_rtc_reload_power(void)
  57. {
  58. /* set AUTO bit because AUTO = 0 when PWREN = 1 and alarm occurs */
  59. u16 bbpu = rtc_read(RTC_BBPU) | RTC_BBPU_KEY | RTC_BBPU_AUTO;
  60. rtc_write(RTC_BBPU, bbpu);
  61. rtc_write_trigger();
  62. }
  63. void rtc_xosc_write(u16 val, bool reload)
  64. {
  65. rtc_write(RTC_OSC32CON, RTC_OSC32CON_UNLOCK1);
  66. rtc_busy_wait();
  67. rtc_write(RTC_OSC32CON, RTC_OSC32CON_UNLOCK2);
  68. rtc_busy_wait();
  69. rtc_write(RTC_OSC32CON, val);
  70. rtc_busy_wait();
  71. if (reload) {
  72. u16 bbpu;
  73. bbpu = rtc_read(RTC_BBPU) | RTC_BBPU_KEY | RTC_BBPU_RELOAD;
  74. rtc_write(RTC_BBPU, bbpu);
  75. rtc_write_trigger();
  76. }
  77. }
  78. void rtc_set_writeif(bool enable)
  79. {
  80. if (enable) {
  81. rtc_writeif_unlock();
  82. } else {
  83. rtc_write(RTC_PROT, 0);
  84. rtc_write_trigger();
  85. }
  86. }
  87. void rtc_bbpu_pwrdown(bool auto_boot)
  88. {
  89. u16 bbpu;
  90. if (auto_boot)
  91. bbpu = RTC_BBPU_KEY | RTC_BBPU_AUTO | RTC_BBPU_PWREN;
  92. else
  93. bbpu = RTC_BBPU_KEY | RTC_BBPU_PWREN;
  94. rtc_write(RTC_BBPU, bbpu);
  95. rtc_write_trigger();
  96. }
  97. void hal_rtc_set_spare_register(rtc_spare_enum cmd, u16 val)
  98. {
  99. u16 tmp_val;
  100. if (cmd >= 0 && cmd < RTC_SPAR_NUM) {
  101. tmp_val =
  102. rtc_read(rtc_spare_reg[cmd][RTC_REG]) & ~(rtc_spare_reg[cmd][RTC_MASK] <<
  103. rtc_spare_reg[cmd][RTC_SHIFT]);
  104. hal_rtc_xinfo("rtc_spare_reg[%d] = {%d, %d, %d}\n", cmd,
  105. rtc_spare_reg[cmd][RTC_REG], rtc_spare_reg[cmd][RTC_MASK],
  106. rtc_spare_reg[cmd][RTC_SHIFT]);
  107. rtc_write(rtc_spare_reg[cmd][RTC_REG],
  108. tmp_val | ((val & rtc_spare_reg[cmd][RTC_MASK]) <<
  109. rtc_spare_reg[cmd][RTC_SHIFT]));
  110. rtc_write_trigger();
  111. }
  112. }
  113. u16 hal_rtc_get_spare_register(rtc_spare_enum cmd)
  114. {
  115. u16 tmp_val;
  116. if (cmd >= 0 && cmd < RTC_SPAR_NUM) {
  117. hal_rtc_xinfo("rtc_spare_reg[%d] = {%d, %d, %d}\n", cmd,
  118. rtc_spare_reg[cmd][RTC_REG], rtc_spare_reg[cmd][RTC_MASK],
  119. rtc_spare_reg[cmd][RTC_SHIFT]);
  120. tmp_val = rtc_read(rtc_spare_reg[cmd][RTC_REG]);
  121. tmp_val = (tmp_val >> rtc_spare_reg[cmd][RTC_SHIFT]) & rtc_spare_reg[cmd][RTC_MASK];
  122. return tmp_val;
  123. }
  124. return 0;
  125. }
  126. static void rtc_get_tick(struct rtc_time *tm)
  127. {
  128. tm->tm_sec = rtc_read(RTC_TC_SEC);
  129. tm->tm_min = rtc_read(RTC_TC_MIN);
  130. tm->tm_hour = rtc_read(RTC_TC_HOU);
  131. tm->tm_mday = rtc_read(RTC_TC_DOM);
  132. tm->tm_mon = rtc_read(RTC_TC_MTH);
  133. tm->tm_year = rtc_read(RTC_TC_YEA);
  134. }
  135. void hal_rtc_get_tick_time(struct rtc_time *tm)
  136. {
  137. u16 bbpu;
  138. bbpu = rtc_read(RTC_BBPU) | RTC_BBPU_KEY | RTC_BBPU_RELOAD;
  139. rtc_write(RTC_BBPU, bbpu);
  140. rtc_write_trigger();
  141. rtc_get_tick(tm);
  142. if (rtc_read(RTC_TC_SEC) < tm->tm_sec) { /* SEC has carried */
  143. rtc_get_tick(tm);
  144. }
  145. }
  146. void hal_rtc_set_tick_time(struct rtc_time *tm)
  147. {
  148. rtc_write(RTC_TC_YEA, tm->tm_year);
  149. rtc_write(RTC_TC_MTH, tm->tm_mon);
  150. rtc_write(RTC_TC_DOM, tm->tm_mday);
  151. rtc_write(RTC_TC_HOU, tm->tm_hour);
  152. rtc_write(RTC_TC_MIN, tm->tm_min);
  153. rtc_write(RTC_TC_SEC, tm->tm_sec);
  154. rtc_write_trigger();
  155. }
  156. void hal_rtc_get_alarm_time(struct rtc_time *tm)
  157. {
  158. tm->tm_sec = rtc_read(RTC_AL_SEC) & RTC_AL_SEC_MASK;
  159. tm->tm_min = rtc_read(RTC_AL_MIN) & RTC_AL_MIN_MASK;
  160. tm->tm_hour = rtc_read(RTC_AL_HOU) & RTC_AL_HOU_MASK;
  161. tm->tm_mday = rtc_read(RTC_AL_DOM) & RTC_AL_DOM_MASK;
  162. tm->tm_mon = rtc_read(RTC_AL_MTH) & RTC_AL_MTH_MASK;
  163. tm->tm_year = rtc_read(RTC_AL_YEA) & RTC_AL_YEA_MASK;
  164. }
  165. void hal_rtc_set_alarm_time(struct rtc_time *tm)
  166. {
  167. hal_rtc_xinfo("read tc time = %04d/%02d/%02d (%d) %02d:%02d:%02d\n",
  168. tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
  169. tm->tm_wday, tm->tm_hour, tm->tm_min, tm->tm_sec);
  170. rtc_write(RTC_AL_YEA,
  171. (rtc_read(RTC_AL_YEA) & ~(RTC_AL_YEA_MASK)) | (tm->tm_year & RTC_AL_YEA_MASK));
  172. rtc_write(RTC_AL_MTH,
  173. (rtc_read(RTC_AL_MTH) & ~(RTC_AL_MTH_MASK)) | (tm->tm_mon & RTC_AL_MTH_MASK));
  174. rtc_write(RTC_AL_DOM,
  175. (rtc_read(RTC_AL_DOM) & ~(RTC_AL_DOM_MASK)) | (tm->tm_mday & RTC_AL_DOM_MASK));
  176. rtc_write(RTC_AL_HOU,
  177. (rtc_read(RTC_AL_HOU) & ~(RTC_AL_HOU_MASK)) | (tm->tm_hour & RTC_AL_HOU_MASK));
  178. rtc_write(RTC_AL_MIN,
  179. (rtc_read(RTC_AL_MIN) & ~(RTC_AL_MIN_MASK)) | (tm->tm_min & RTC_AL_MIN_MASK));
  180. rtc_write(RTC_AL_SEC,
  181. (rtc_read(RTC_AL_SEC) & ~(RTC_AL_SEC_MASK)) | (tm->tm_sec & RTC_AL_SEC_MASK));
  182. rtc_write(RTC_AL_MASK, RTC_AL_MASK_DOW); /* mask DOW */
  183. rtc_write_trigger();
  184. }
  185. void hal_rtc_save_pwron_alarm(void)
  186. {
  187. rtc_write(RTC_PDN1, rtc_read(RTC_PDN1) & (~RTC_PDN1_PWRON_TIME));
  188. rtc_write(RTC_PDN2, rtc_read(RTC_PDN2) | RTC_PDN2_PWRON_ALARM);
  189. rtc_write_trigger();
  190. }
  191. void hal_rtc_get_pwron_alarm_time(struct rtc_time *tm)
  192. {
  193. tm->tm_sec = (rtc_read(RTC_PWRON_SEC) & RTC_PWRON_SEC_MASK) >> RTC_PWRON_SEC_SHIFT;
  194. tm->tm_min = (rtc_read(RTC_PWRON_MIN) & RTC_PWRON_MIN_MASK) >> RTC_PWRON_MIN_SHIFT;
  195. tm->tm_hour = (rtc_read(RTC_PWRON_HOU) & RTC_PWRON_HOU_MASK) >> RTC_PWRON_HOU_SHIFT;
  196. tm->tm_mday = (rtc_read(RTC_PWRON_DOM) & RTC_PWRON_DOM_MASK) >> RTC_PWRON_DOM_SHIFT;
  197. tm->tm_mon = (rtc_read(RTC_PWRON_MTH) & RTC_PWRON_MTH_MASK) >> RTC_PWRON_MTH_SHIFT;
  198. tm->tm_year = (rtc_read(RTC_PWRON_YEA) & RTC_PWRON_YEA_MASK) >> RTC_PWRON_YEA_SHIFT;
  199. }
  200. void hal_rtc_set_pwron_alarm_time(struct rtc_time *tm)
  201. {
  202. rtc_write(RTC_PWRON_YEA, (rtc_read(RTC_PWRON_YEA) & ~(RTC_PWRON_YEA_MASK))
  203. | ((tm->tm_year << RTC_PWRON_YEA_SHIFT) & RTC_PWRON_YEA_MASK));
  204. rtc_write_trigger();
  205. rtc_write(RTC_PWRON_MTH, (rtc_read(RTC_PWRON_MTH) & ~(RTC_PWRON_MTH_MASK))
  206. | ((tm->tm_mon << RTC_PWRON_MTH_SHIFT) & RTC_PWRON_MTH_MASK));
  207. rtc_write_trigger();
  208. rtc_write(RTC_PWRON_DOM, (rtc_read(RTC_PWRON_DOM) & ~(RTC_PWRON_DOM_MASK))
  209. | ((tm->tm_mday << RTC_PWRON_DOM_SHIFT) & RTC_PWRON_DOM_MASK));
  210. rtc_write_trigger();
  211. rtc_write(RTC_PWRON_HOU, (rtc_read(RTC_PWRON_HOU) & ~(RTC_PWRON_HOU_MASK))
  212. | ((tm->tm_hour << RTC_PWRON_HOU_SHIFT) & RTC_PWRON_HOU_MASK));
  213. rtc_write_trigger();
  214. rtc_write(RTC_PWRON_MIN, (rtc_read(RTC_PWRON_MIN) & ~(RTC_PWRON_MIN_MASK))
  215. | ((tm->tm_min << RTC_PWRON_MIN_SHIFT) & RTC_PWRON_MIN_MASK));
  216. rtc_write_trigger();
  217. rtc_write(RTC_PWRON_SEC, (rtc_read(RTC_PWRON_SEC) & ~(RTC_PWRON_SEC_MASK))
  218. | ((tm->tm_sec << RTC_PWRON_SEC_SHIFT) & RTC_PWRON_SEC_MASK));
  219. rtc_write_trigger();
  220. }
  221. void hal_rtc_read_rg(void)
  222. {
  223. u16 irqen, pdn1;
  224. irqen = rtc_read(RTC_IRQ_EN);
  225. pdn1 = rtc_read(RTC_PDN1);
  226. hal_rtc_xinfo("RTC_IRQ_EN = 0x%x, RTC_PDN1 = 0x%x\n", irqen, pdn1);
  227. }
  228. #ifndef USER_BUILD_KERNEL
  229. void rtc_lp_exception(void)
  230. {
  231. u16 bbpu, irqsta, irqen, osc32;
  232. u16 pwrkey1, pwrkey2, prot, con, sec1, sec2;
  233. bbpu = rtc_read(RTC_BBPU);
  234. irqsta = rtc_read(RTC_IRQ_STA);
  235. irqen = rtc_read(RTC_IRQ_EN);
  236. osc32 = rtc_read(RTC_OSC32CON);
  237. pwrkey1 = rtc_read(RTC_POWERKEY1);
  238. pwrkey2 = rtc_read(RTC_POWERKEY2);
  239. prot = rtc_read(RTC_PROT);
  240. con = rtc_read(RTC_CON);
  241. sec1 = rtc_read(RTC_TC_SEC);
  242. mdelay(2000);
  243. sec2 = rtc_read(RTC_TC_SEC);
  244. hal_rtc_xfatal("!!! 32K WAS STOPPED !!!\n"
  245. "RTC_BBPU = 0x%x\n"
  246. "RTC_IRQ_STA = 0x%x\n"
  247. "RTC_IRQ_EN = 0x%x\n"
  248. "RTC_OSC32CON = 0x%x\n"
  249. "RTC_POWERKEY1 = 0x%x\n"
  250. "RTC_POWERKEY2 = 0x%x\n"
  251. "RTC_PROT = 0x%x\n"
  252. "RTC_CON = 0x%x\n"
  253. "RTC_TC_SEC = %02d\n"
  254. "RTC_TC_SEC = %02d\n",
  255. bbpu, irqsta, irqen, osc32, pwrkey1, pwrkey2, prot, con, sec1, sec2);
  256. }
  257. #endif
  258. #endif /*#if defined(CONFIG_MTK_RTC)*/