mc146818rtc.h
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:4k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

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