mc146818rtc.h 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. /*
  2. * Machine dependent access functions for RTC registers.
  3. */
  4. #ifndef _ASM_MC146818RTC_H
  5. #define _ASM_MC146818RTC_H
  6. #ifdef CONFIG_SH_MPC1211
  7. #undef _ASM_MC146818RTC_H
  8. #undef RTC_IRQ
  9. #include <asm/mpc1211/mc146818rtc.h>
  10. #else
  11. #include <asm/rtc.h>
  12. #define RTC_ALWAYS_BCD 1
  13. /* FIXME:RTC Interrupt feature is not implemented yet. */
  14. #undef RTC_IRQ
  15. #define RTC_IRQ 0
  16. #if defined(CONFIG_CPU_SH3)
  17. #define RTC_PORT(n) (R64CNT+(n)*2)
  18. #define CMOS_READ(addr) __CMOS_READ(addr,b)
  19. #define CMOS_WRITE(val,addr) __CMOS_WRITE(val,addr,b)
  20. #elif defined(CONFIG_SH_SECUREEDGE5410)
  21. #include <asm/snapgear/io.h>
  22. #define RTC_PORT(n) SECUREEDGE_IOPORT_ADDR
  23. #define CMOS_READ(addr) secureedge5410_cmos_read(addr)
  24. #define CMOS_WRITE(val,addr) secureedge5410_cmos_write(val,addr)
  25. extern unsigned char secureedge5410_cmos_read(int addr);
  26. extern void secureedge5410_cmos_write(unsigned char val, int addr);
  27. #elif defined(CONFIG_CPU_SH4)
  28. #define RTC_PORT(n) (R64CNT+(n)*4)
  29. #define CMOS_READ(addr) __CMOS_READ(addr,w)
  30. #define CMOS_WRITE(val,addr) __CMOS_WRITE(val,addr,w)
  31. #endif
  32. #define __CMOS_READ(addr, s) ({ \
  33. unsigned char val=0, rcr1, rcr2, r64cnt, retry; \
  34. switch(addr) { \
  35. case RTC_SECONDS: \
  36. val = ctrl_inb(RSECCNT); \
  37. break; \
  38. case RTC_SECONDS_ALARM: \
  39. val = ctrl_inb(RSECAR); \
  40. break; \
  41. case RTC_MINUTES: \
  42. val = ctrl_inb(RMINCNT); \
  43. break; \
  44. case RTC_MINUTES_ALARM: \
  45. val = ctrl_inb(RMINAR); \
  46. break; \
  47. case RTC_HOURS: \
  48. val = ctrl_inb(RHRCNT); \
  49. break; \
  50. case RTC_HOURS_ALARM: \
  51. val = ctrl_inb(RHRAR); \
  52. break; \
  53. case RTC_DAY_OF_WEEK: \
  54. val = ctrl_inb(RWKCNT); \
  55. break; \
  56. case RTC_DAY_OF_MONTH: \
  57. val = ctrl_inb(RDAYCNT); \
  58. break; \
  59. case RTC_MONTH: \
  60. val = ctrl_inb(RMONCNT); \
  61. break; \
  62. case RTC_YEAR: \
  63. val = ctrl_in##s(RYRCNT); \
  64. break; \
  65. case RTC_REG_A: /* RTC_FREQ_SELECT */ \
  66. rcr2 = ctrl_inb(RCR2); \
  67. val = (rcr2 & RCR2_PESMASK) >> 4; \
  68. rcr1 = ctrl_inb(RCR1); \
  69. rcr1 = (rcr1 & (RCR1_CIE | RCR1_AIE)) | RCR1_AF;\
  70. retry = 0; \
  71. do { \
  72. ctrl_outb(rcr1, RCR1); /* clear CF */ \
  73. r64cnt = ctrl_inb(R64CNT); \
  74. } while((ctrl_inb(RCR1) & RCR1_CF) && retry++ < 1000);\
  75. r64cnt ^= RTC_BIT_INVERTED; \
  76. if(r64cnt == 0x7f || r64cnt == 0) \
  77. val |= RTC_UIP; \
  78. break; \
  79. case RTC_REG_B: /* RTC_CONTROL */ \
  80. rcr1 = ctrl_inb(RCR1); \
  81. rcr2 = ctrl_inb(RCR2); \
  82. if(rcr1 & RCR1_CIE) val |= RTC_UIE; \
  83. if(rcr1 & RCR1_AIE) val |= RTC_AIE; \
  84. if(rcr2 & RCR2_PESMASK) val |= RTC_PIE; \
  85. if(!(rcr2 & RCR2_START))val |= RTC_SET; \
  86. val |= RTC_24H; \
  87. break; \
  88. case RTC_REG_C: /* RTC_INTR_FLAGS */ \
  89. rcr1 = ctrl_inb(RCR1); \
  90. rcr1 &= ~(RCR1_CF | RCR1_AF); \
  91. ctrl_outb(rcr1, RCR1); \
  92. rcr2 = ctrl_inb(RCR2); \
  93. rcr2 &= ~RCR2_PEF; \
  94. ctrl_outb(rcr2, RCR2); \
  95. break; \
  96. case RTC_REG_D: /* RTC_VALID */ \
  97. /* Always valid ... */ \
  98. val = RTC_VRT; \
  99. break; \
  100. default: \
  101. break; \
  102. } \
  103. val; \
  104. })
  105. #define __CMOS_WRITE(val, addr, s) ({ \
  106. unsigned char rcr1,rcr2; \
  107. switch(addr) { \
  108. case RTC_SECONDS: \
  109. ctrl_outb(val, RSECCNT); \
  110. break; \
  111. case RTC_SECONDS_ALARM: \
  112. ctrl_outb(val, RSECAR); \
  113. break; \
  114. case RTC_MINUTES: \
  115. ctrl_outb(val, RMINCNT); \
  116. break; \
  117. case RTC_MINUTES_ALARM: \
  118. ctrl_outb(val, RMINAR); \
  119. break; \
  120. case RTC_HOURS: \
  121. ctrl_outb(val, RHRCNT); \
  122. break; \
  123. case RTC_HOURS_ALARM: \
  124. ctrl_outb(val, RHRAR); \
  125. break; \
  126. case RTC_DAY_OF_WEEK: \
  127. ctrl_outb(val, RWKCNT); \
  128. break; \
  129. case RTC_DAY_OF_MONTH: \
  130. ctrl_outb(val, RDAYCNT); \
  131. break; \
  132. case RTC_MONTH: \
  133. ctrl_outb(val, RMONCNT); \
  134. break; \
  135. case RTC_YEAR: \
  136. ctrl_out##s((ctrl_in##s(RYRCNT) & 0xff00) | (val & 0xff), RYRCNT);\
  137. break; \
  138. case RTC_REG_A: /* RTC_FREQ_SELECT */ \
  139. rcr2 = ctrl_inb(RCR2); \
  140. if((val & RTC_DIV_CTL) == RTC_DIV_RESET2) \
  141. rcr2 |= RCR2_RESET; \
  142. ctrl_outb(rcr2, RCR2); \
  143. break; \
  144. case RTC_REG_B: /* RTC_CONTROL */ \
  145. rcr1 = (ctrl_inb(RCR1) & 0x99) | RCR1_AF; \
  146. if(val & RTC_AIE) rcr1 |= RCR1_AIE; \
  147. else rcr1 &= ~RCR1_AIE; \
  148. if(val & RTC_UIE) rcr1 |= RCR1_CIE; \
  149. else rcr1 &= ~RCR1_CIE; \
  150. ctrl_outb(rcr1, RCR1); \
  151. rcr2 = ctrl_inb(RCR2); \
  152. if(val & RTC_SET) rcr2 &= ~RCR2_START; \
  153. else rcr2 |= RCR2_START; \
  154. ctrl_outb(rcr2, RCR2); \
  155. break; \
  156. case RTC_REG_C: /* RTC_INTR_FLAGS */ \
  157. break; \
  158. case RTC_REG_D: /* RTC_VALID */ \
  159. break; \
  160. default: \
  161. break; \
  162. } \
  163. })
  164. #endif /* CONFIG_SH_MPC1211 */
  165. #endif /* _ASM_MC146818RTC_H */