smbus.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. #include "memio.h"
  2. #include "articiaS.h"
  3. #ifndef FALSE
  4. #define FALSE 0
  5. #endif
  6. #ifndef TRUE
  7. #define TRUE 1
  8. #endif
  9. void sm_write_mode(void)
  10. {
  11. out_byte(0xA539, 0x00);
  12. out_byte(0xA53A, 0x03);
  13. }
  14. void sm_read_mode(void)
  15. {
  16. out_byte(0xA53A, 0x02);
  17. out_byte(0xA539, 0x02);
  18. }
  19. void sm_write_byte(uint8 writeme)
  20. {
  21. int i;
  22. int level;
  23. out_byte(0xA539, 0x00);
  24. level = 0;
  25. for (i=0; i<8; i++)
  26. {
  27. if ((writeme & 0x80) == (level<<7))
  28. {
  29. /* Bit did not change, rewrite strobe */
  30. out_byte(0xA539, level | 0x02);
  31. out_byte(0xA539, level);
  32. }
  33. else
  34. {
  35. /* Bit changed, set bit, then strobe */
  36. level = (writeme & 0x80) >> 7;
  37. out_byte(0xA539, level);
  38. out_byte(0xA539, level | 0x02);
  39. out_byte(0xA539, level);
  40. }
  41. writeme <<= 1;
  42. }
  43. out_byte(0xA539, 0x00);
  44. }
  45. uint8 sm_read_byte(void)
  46. {
  47. uint8 retme, r;
  48. int i;
  49. retme = 0;
  50. for (i=0; i<8; i++)
  51. {
  52. retme <<= 1;
  53. out_byte(0xA539, 0x00);
  54. out_byte(0xA539, 0x02);
  55. r = in_byte(0xA538) & 0x01;
  56. retme |= r;
  57. }
  58. return retme;
  59. }
  60. int sm_get_ack(void)
  61. {
  62. uint8 r;
  63. r = in_byte(0xA538);
  64. if ((r&0x01) == 0) return TRUE;
  65. else return FALSE;
  66. }
  67. void sm_write_ack(void)
  68. {
  69. out_byte(0xA539, 0x00);
  70. out_byte(0xA539, 0x02);
  71. out_byte(0xA539, 0x00);
  72. }
  73. void sm_write_nack(void)
  74. {
  75. out_byte(0xA539, 0x01);
  76. out_byte(0xA539, 0x03);
  77. out_byte(0xA539, 0x01);
  78. }
  79. void sm_send_start(void)
  80. {
  81. out_byte(0xA539, 0x03);
  82. out_byte(0xA539, 0x02);
  83. }
  84. void sm_send_stop(void)
  85. {
  86. out_byte(0xA539, 0x02);
  87. out_byte(0xA539, 0x03);
  88. }
  89. int sm_read_byte_from_device(uint8 addr, uint8 reg, uint8 *storage)
  90. {
  91. /* S Addr Wr */
  92. sm_write_mode();
  93. sm_send_start();
  94. sm_write_byte((addr<<1));
  95. /* [A] */
  96. sm_read_mode();
  97. if (sm_get_ack() == FALSE) return FALSE;
  98. /* Comm */
  99. sm_write_mode();
  100. sm_write_byte(reg);
  101. /* [A] */
  102. sm_read_mode();
  103. if (sm_get_ack() == FALSE) return FALSE;
  104. /* S Addr Rd */
  105. sm_write_mode();
  106. sm_send_start();
  107. sm_write_byte((addr<<1)|1);
  108. /* [A] */
  109. sm_read_mode();
  110. if (sm_get_ack() == FALSE) return FALSE;
  111. /* [Data] */
  112. *storage = sm_read_byte();
  113. /* NA */
  114. sm_write_mode();
  115. sm_write_nack();
  116. sm_send_stop();
  117. return TRUE;
  118. }
  119. void sm_init(void)
  120. {
  121. /* Switch to PMC mode */
  122. pci_write_cfg_byte(0, 0, REG_GROUP, (uint8)(REG_GROUP_SPECIAL|REG_GROUP_POWER));
  123. /* Set GPIO Base */
  124. pci_write_cfg_long(0, 0, 0x40, 0xa500);
  125. /* Enable GPIO */
  126. pci_write_cfg_byte(0, 0, 0x44, 0x11);
  127. /* Set both GPIO 0 and 1 as output */
  128. out_byte(0xA53A, 0x03);
  129. }
  130. void sm_term(void)
  131. {
  132. /* Switch to normal mode */
  133. pci_write_cfg_byte(0, 0, REG_GROUP, 0);
  134. }
  135. int sm_get_data(uint8 *DataArray, int dimm_socket)
  136. {
  137. int j;
  138. #if 0
  139. /* Switch to PMC mode */
  140. pci_write_cfg_byte(0, 0, REG_GROUP, (uint8)(REG_GROUP_SPECIAL|REG_GROUP_POWER));
  141. /* Set GPIO Base */
  142. pci_write_cfg_long(0, 0, 0x40, 0xa500);
  143. /* Enable GPIO */
  144. pci_write_cfg_byte(0, 0, 0x44, 0x11);
  145. /* Set both GPIO 0 and 1 as output */
  146. out_byte(0xA53A, 0x03);
  147. #endif
  148. sm_init();
  149. /* Start reading the rom */
  150. j = 0;
  151. do
  152. {
  153. if (sm_read_byte_from_device(dimm_socket, (uint8)j, DataArray) == FALSE)
  154. {
  155. sm_term();
  156. return FALSE;
  157. }
  158. DataArray++;
  159. j++;
  160. } while (j < 128);
  161. sm_term();
  162. return TRUE;
  163. }