nicstarmac.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. /*
  2. * this file included by nicstar.c
  3. */
  4. /*
  5. * nicstarmac.c
  6. * Read this ForeRunner's MAC address from eprom/eeprom
  7. */
  8. #include <linux/kernel.h>
  9. typedef void __iomem *virt_addr_t;
  10. #define CYCLE_DELAY 5
  11. /*
  12. This was the original definition
  13. #define osp_MicroDelay(microsec) \
  14. do { int _i = 4*microsec; while (--_i > 0) { __SLOW_DOWN_IO; }} while (0)
  15. */
  16. #define osp_MicroDelay(microsec) {unsigned long useconds = (microsec); \
  17. udelay((useconds));}
  18. /*
  19. * The following tables represent the timing diagrams found in
  20. * the Data Sheet for the Xicor X25020 EEProm. The #defines below
  21. * represent the bits in the NICStAR's General Purpose register
  22. * that must be toggled for the corresponding actions on the EEProm
  23. * to occur.
  24. */
  25. /* Write Data To EEProm from SI line on rising edge of CLK */
  26. /* Read Data From EEProm on falling edge of CLK */
  27. #define CS_HIGH 0x0002 /* Chip select high */
  28. #define CS_LOW 0x0000 /* Chip select low (active low) */
  29. #define CLK_HIGH 0x0004 /* Clock high */
  30. #define CLK_LOW 0x0000 /* Clock low */
  31. #define SI_HIGH 0x0001 /* Serial input data high */
  32. #define SI_LOW 0x0000 /* Serial input data low */
  33. /* Read Status Register = 0000 0101b */
  34. #if 0
  35. static u_int32_t rdsrtab[] = {
  36. CS_HIGH | CLK_HIGH,
  37. CS_LOW | CLK_LOW,
  38. CLK_HIGH, /* 0 */
  39. CLK_LOW,
  40. CLK_HIGH, /* 0 */
  41. CLK_LOW,
  42. CLK_HIGH, /* 0 */
  43. CLK_LOW,
  44. CLK_HIGH, /* 0 */
  45. CLK_LOW,
  46. CLK_HIGH, /* 0 */
  47. CLK_LOW | SI_HIGH,
  48. CLK_HIGH | SI_HIGH, /* 1 */
  49. CLK_LOW | SI_LOW,
  50. CLK_HIGH, /* 0 */
  51. CLK_LOW | SI_HIGH,
  52. CLK_HIGH | SI_HIGH /* 1 */
  53. };
  54. #endif /* 0 */
  55. /* Read from EEPROM = 0000 0011b */
  56. static u_int32_t readtab[] = {
  57. /*
  58. CS_HIGH | CLK_HIGH,
  59. */
  60. CS_LOW | CLK_LOW,
  61. CLK_HIGH, /* 0 */
  62. CLK_LOW,
  63. CLK_HIGH, /* 0 */
  64. CLK_LOW,
  65. CLK_HIGH, /* 0 */
  66. CLK_LOW,
  67. CLK_HIGH, /* 0 */
  68. CLK_LOW,
  69. CLK_HIGH, /* 0 */
  70. CLK_LOW,
  71. CLK_HIGH, /* 0 */
  72. CLK_LOW | SI_HIGH,
  73. CLK_HIGH | SI_HIGH, /* 1 */
  74. CLK_LOW | SI_HIGH,
  75. CLK_HIGH | SI_HIGH /* 1 */
  76. };
  77. /* Clock to read from/write to the eeprom */
  78. static u_int32_t clocktab[] = {
  79. CLK_LOW,
  80. CLK_HIGH,
  81. CLK_LOW,
  82. CLK_HIGH,
  83. CLK_LOW,
  84. CLK_HIGH,
  85. CLK_LOW,
  86. CLK_HIGH,
  87. CLK_LOW,
  88. CLK_HIGH,
  89. CLK_LOW,
  90. CLK_HIGH,
  91. CLK_LOW,
  92. CLK_HIGH,
  93. CLK_LOW,
  94. CLK_HIGH,
  95. CLK_LOW
  96. };
  97. #define NICSTAR_REG_WRITE(bs, reg, val) \
  98. while ( readl(bs + STAT) & 0x0200 ) ; \
  99. writel((val),(base)+(reg))
  100. #define NICSTAR_REG_READ(bs, reg) \
  101. readl((base)+(reg))
  102. #define NICSTAR_REG_GENERAL_PURPOSE GP
  103. /*
  104. * This routine will clock the Read_Status_reg function into the X2520
  105. * eeprom, then pull the result from bit 16 of the NicSTaR's General Purpose
  106. * register.
  107. */
  108. #if 0
  109. u_int32_t nicstar_read_eprom_status(virt_addr_t base)
  110. {
  111. u_int32_t val;
  112. u_int32_t rbyte;
  113. int32_t i, j;
  114. /* Send read instruction */
  115. val = NICSTAR_REG_READ(base, NICSTAR_REG_GENERAL_PURPOSE) & 0xFFFFFFF0;
  116. for (i = 0; i < ARRAY_SIZE(rdsrtab); i++) {
  117. NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
  118. (val | rdsrtab[i]));
  119. osp_MicroDelay(CYCLE_DELAY);
  120. }
  121. /* Done sending instruction - now pull data off of bit 16, MSB first */
  122. /* Data clocked out of eeprom on falling edge of clock */
  123. rbyte = 0;
  124. for (i = 7, j = 0; i >= 0; i--) {
  125. NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
  126. (val | clocktab[j++]));
  127. rbyte |= (((NICSTAR_REG_READ(base, NICSTAR_REG_GENERAL_PURPOSE)
  128. & 0x00010000) >> 16) << i);
  129. NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
  130. (val | clocktab[j++]));
  131. osp_MicroDelay(CYCLE_DELAY);
  132. }
  133. NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE, 2);
  134. osp_MicroDelay(CYCLE_DELAY);
  135. return rbyte;
  136. }
  137. #endif /* 0 */
  138. /*
  139. * This routine will clock the Read_data function into the X2520
  140. * eeprom, followed by the address to read from, through the NicSTaR's General
  141. * Purpose register.
  142. */
  143. static u_int8_t read_eprom_byte(virt_addr_t base, u_int8_t offset)
  144. {
  145. u_int32_t val = 0;
  146. int i, j = 0;
  147. u_int8_t tempread = 0;
  148. val = NICSTAR_REG_READ(base, NICSTAR_REG_GENERAL_PURPOSE) & 0xFFFFFFF0;
  149. /* Send READ instruction */
  150. for (i = 0; i < ARRAY_SIZE(readtab); i++) {
  151. NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
  152. (val | readtab[i]));
  153. osp_MicroDelay(CYCLE_DELAY);
  154. }
  155. /* Next, we need to send the byte address to read from */
  156. for (i = 7; i >= 0; i--) {
  157. NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
  158. (val | clocktab[j++] | ((offset >> i) & 1)));
  159. osp_MicroDelay(CYCLE_DELAY);
  160. NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
  161. (val | clocktab[j++] | ((offset >> i) & 1)));
  162. osp_MicroDelay(CYCLE_DELAY);
  163. }
  164. j = 0;
  165. /* Now, we can read data from the eeprom by clocking it in */
  166. for (i = 7; i >= 0; i--) {
  167. NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
  168. (val | clocktab[j++]));
  169. osp_MicroDelay(CYCLE_DELAY);
  170. tempread |=
  171. (((NICSTAR_REG_READ(base, NICSTAR_REG_GENERAL_PURPOSE)
  172. & 0x00010000) >> 16) << i);
  173. NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
  174. (val | clocktab[j++]));
  175. osp_MicroDelay(CYCLE_DELAY);
  176. }
  177. NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE, 2);
  178. osp_MicroDelay(CYCLE_DELAY);
  179. return tempread;
  180. }
  181. static void nicstar_init_eprom(virt_addr_t base)
  182. {
  183. u_int32_t val;
  184. /*
  185. * turn chip select off
  186. */
  187. val = NICSTAR_REG_READ(base, NICSTAR_REG_GENERAL_PURPOSE) & 0xFFFFFFF0;
  188. NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
  189. (val | CS_HIGH | CLK_HIGH));
  190. osp_MicroDelay(CYCLE_DELAY);
  191. NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
  192. (val | CS_HIGH | CLK_LOW));
  193. osp_MicroDelay(CYCLE_DELAY);
  194. NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
  195. (val | CS_HIGH | CLK_HIGH));
  196. osp_MicroDelay(CYCLE_DELAY);
  197. NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
  198. (val | CS_HIGH | CLK_LOW));
  199. osp_MicroDelay(CYCLE_DELAY);
  200. }
  201. /*
  202. * This routine will be the interface to the ReadPromByte function
  203. * above.
  204. */
  205. static void
  206. nicstar_read_eprom(virt_addr_t base,
  207. u_int8_t prom_offset, u_int8_t * buffer, u_int32_t nbytes)
  208. {
  209. u_int i;
  210. for (i = 0; i < nbytes; i++) {
  211. buffer[i] = read_eprom_byte(base, prom_offset);
  212. ++prom_offset;
  213. osp_MicroDelay(CYCLE_DELAY);
  214. }
  215. }