eeprom_93cx6.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. /*
  2. Copyright (C) 2004 - 2006 rt2x00 SourceForge Project
  3. <http://rt2x00.serialmonkey.com>
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the
  14. Free Software Foundation, Inc.,
  15. 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  16. */
  17. /*
  18. Module: eeprom_93cx6
  19. Abstract: EEPROM reader routines for 93cx6 chipsets.
  20. Supported chipsets: 93c46 & 93c66.
  21. */
  22. #include <linux/kernel.h>
  23. #include <linux/module.h>
  24. #include <linux/version.h>
  25. #include <linux/delay.h>
  26. #include <linux/eeprom_93cx6.h>
  27. MODULE_AUTHOR("http://rt2x00.serialmonkey.com");
  28. MODULE_VERSION("1.0");
  29. MODULE_DESCRIPTION("EEPROM 93cx6 chip driver");
  30. MODULE_LICENSE("GPL");
  31. static inline void eeprom_93cx6_pulse_high(struct eeprom_93cx6 *eeprom)
  32. {
  33. eeprom->reg_data_clock = 1;
  34. eeprom->register_write(eeprom);
  35. /*
  36. * Add a short delay for the pulse to work.
  37. * According to the specifications the "maximum minimum"
  38. * time should be 450ns.
  39. */
  40. ndelay(450);
  41. }
  42. static inline void eeprom_93cx6_pulse_low(struct eeprom_93cx6 *eeprom)
  43. {
  44. eeprom->reg_data_clock = 0;
  45. eeprom->register_write(eeprom);
  46. /*
  47. * Add a short delay for the pulse to work.
  48. * According to the specifications the "maximum minimum"
  49. * time should be 450ns.
  50. */
  51. ndelay(450);
  52. }
  53. static void eeprom_93cx6_startup(struct eeprom_93cx6 *eeprom)
  54. {
  55. /*
  56. * Clear all flags, and enable chip select.
  57. */
  58. eeprom->register_read(eeprom);
  59. eeprom->reg_data_in = 0;
  60. eeprom->reg_data_out = 0;
  61. eeprom->reg_data_clock = 0;
  62. eeprom->reg_chip_select = 1;
  63. eeprom->register_write(eeprom);
  64. /*
  65. * kick a pulse.
  66. */
  67. eeprom_93cx6_pulse_high(eeprom);
  68. eeprom_93cx6_pulse_low(eeprom);
  69. }
  70. static void eeprom_93cx6_cleanup(struct eeprom_93cx6 *eeprom)
  71. {
  72. /*
  73. * Clear chip_select and data_in flags.
  74. */
  75. eeprom->register_read(eeprom);
  76. eeprom->reg_data_in = 0;
  77. eeprom->reg_chip_select = 0;
  78. eeprom->register_write(eeprom);
  79. /*
  80. * kick a pulse.
  81. */
  82. eeprom_93cx6_pulse_high(eeprom);
  83. eeprom_93cx6_pulse_low(eeprom);
  84. }
  85. static void eeprom_93cx6_write_bits(struct eeprom_93cx6 *eeprom,
  86. const u16 data, const u16 count)
  87. {
  88. unsigned int i;
  89. eeprom->register_read(eeprom);
  90. /*
  91. * Clear data flags.
  92. */
  93. eeprom->reg_data_in = 0;
  94. eeprom->reg_data_out = 0;
  95. /*
  96. * Start writing all bits.
  97. */
  98. for (i = count; i > 0; i--) {
  99. /*
  100. * Check if this bit needs to be set.
  101. */
  102. eeprom->reg_data_in = !!(data & (1 << (i - 1)));
  103. /*
  104. * Write the bit to the eeprom register.
  105. */
  106. eeprom->register_write(eeprom);
  107. /*
  108. * Kick a pulse.
  109. */
  110. eeprom_93cx6_pulse_high(eeprom);
  111. eeprom_93cx6_pulse_low(eeprom);
  112. }
  113. eeprom->reg_data_in = 0;
  114. eeprom->register_write(eeprom);
  115. }
  116. static void eeprom_93cx6_read_bits(struct eeprom_93cx6 *eeprom,
  117. u16 *data, const u16 count)
  118. {
  119. unsigned int i;
  120. u16 buf = 0;
  121. eeprom->register_read(eeprom);
  122. /*
  123. * Clear data flags.
  124. */
  125. eeprom->reg_data_in = 0;
  126. eeprom->reg_data_out = 0;
  127. /*
  128. * Start reading all bits.
  129. */
  130. for (i = count; i > 0; i--) {
  131. eeprom_93cx6_pulse_high(eeprom);
  132. eeprom->register_read(eeprom);
  133. /*
  134. * Clear data_in flag.
  135. */
  136. eeprom->reg_data_in = 0;
  137. /*
  138. * Read if the bit has been set.
  139. */
  140. if (eeprom->reg_data_out)
  141. buf |= (1 << (i - 1));
  142. eeprom_93cx6_pulse_low(eeprom);
  143. }
  144. *data = buf;
  145. }
  146. /**
  147. * eeprom_93cx6_read - Read multiple words from eeprom
  148. * @eeprom: Pointer to eeprom structure
  149. * @word: Word index from where we should start reading
  150. * @data: target pointer where the information will have to be stored
  151. *
  152. * This function will read the eeprom data as host-endian word
  153. * into the given data pointer.
  154. */
  155. void eeprom_93cx6_read(struct eeprom_93cx6 *eeprom, const u8 word,
  156. u16 *data)
  157. {
  158. u16 command;
  159. /*
  160. * Initialize the eeprom register
  161. */
  162. eeprom_93cx6_startup(eeprom);
  163. /*
  164. * Select the read opcode and the word to be read.
  165. */
  166. command = (PCI_EEPROM_READ_OPCODE << eeprom->width) | word;
  167. eeprom_93cx6_write_bits(eeprom, command,
  168. PCI_EEPROM_WIDTH_OPCODE + eeprom->width);
  169. /*
  170. * Read the requested 16 bits.
  171. */
  172. eeprom_93cx6_read_bits(eeprom, data, 16);
  173. /*
  174. * Cleanup eeprom register.
  175. */
  176. eeprom_93cx6_cleanup(eeprom);
  177. }
  178. EXPORT_SYMBOL_GPL(eeprom_93cx6_read);
  179. /**
  180. * eeprom_93cx6_multiread - Read multiple words from eeprom
  181. * @eeprom: Pointer to eeprom structure
  182. * @word: Word index from where we should start reading
  183. * @data: target pointer where the information will have to be stored
  184. * @words: Number of words that should be read.
  185. *
  186. * This function will read all requested words from the eeprom,
  187. * this is done by calling eeprom_93cx6_read() multiple times.
  188. * But with the additional change that while the eeprom_93cx6_read
  189. * will return host ordered bytes, this method will return little
  190. * endian words.
  191. */
  192. void eeprom_93cx6_multiread(struct eeprom_93cx6 *eeprom, const u8 word,
  193. __le16 *data, const u16 words)
  194. {
  195. unsigned int i;
  196. u16 tmp;
  197. for (i = 0; i < words; i++) {
  198. tmp = 0;
  199. eeprom_93cx6_read(eeprom, word + i, &tmp);
  200. data[i] = cpu_to_le16(tmp);
  201. }
  202. }
  203. EXPORT_SYMBOL_GPL(eeprom_93cx6_multiread);