Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
eeprom_93cx6.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2004 - 2006 rt2x00 SourceForge Project
3  * <http://rt2x00.serialmonkey.com>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * Module: eeprom_93cx6
16  * Abstract: EEPROM reader routines for 93cx6 chipsets.
17  * Supported chipsets: 93c46 & 93c66.
18  */
19 
20 #include <linux/kernel.h>
21 #include <linux/module.h>
22 #include <linux/delay.h>
23 #include <linux/eeprom_93cx6.h>
24 
25 MODULE_AUTHOR("http://rt2x00.serialmonkey.com");
26 MODULE_VERSION("1.0");
27 MODULE_DESCRIPTION("EEPROM 93cx6 chip driver");
28 MODULE_LICENSE("GPL");
29 
30 static inline void eeprom_93cx6_pulse_high(struct eeprom_93cx6 *eeprom)
31 {
32  eeprom->reg_data_clock = 1;
33  eeprom->register_write(eeprom);
34 
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 
43 static inline void eeprom_93cx6_pulse_low(struct eeprom_93cx6 *eeprom)
44 {
45  eeprom->reg_data_clock = 0;
46  eeprom->register_write(eeprom);
47 
48  /*
49  * Add a short delay for the pulse to work.
50  * According to the specifications the "maximum minimum"
51  * time should be 450ns.
52  */
53  ndelay(450);
54 }
55 
56 static void eeprom_93cx6_startup(struct eeprom_93cx6 *eeprom)
57 {
58  /*
59  * Clear all flags, and enable chip select.
60  */
61  eeprom->register_read(eeprom);
62  eeprom->reg_data_in = 0;
63  eeprom->reg_data_out = 0;
64  eeprom->reg_data_clock = 0;
65  eeprom->reg_chip_select = 1;
66  eeprom->drive_data = 1;
67  eeprom->register_write(eeprom);
68 
69  /*
70  * kick a pulse.
71  */
72  eeprom_93cx6_pulse_high(eeprom);
73  eeprom_93cx6_pulse_low(eeprom);
74 }
75 
76 static void eeprom_93cx6_cleanup(struct eeprom_93cx6 *eeprom)
77 {
78  /*
79  * Clear chip_select and data_in flags.
80  */
81  eeprom->register_read(eeprom);
82  eeprom->reg_data_in = 0;
83  eeprom->reg_chip_select = 0;
84  eeprom->register_write(eeprom);
85 
86  /*
87  * kick a pulse.
88  */
89  eeprom_93cx6_pulse_high(eeprom);
90  eeprom_93cx6_pulse_low(eeprom);
91 }
92 
93 static void eeprom_93cx6_write_bits(struct eeprom_93cx6 *eeprom,
94  const u16 data, const u16 count)
95 {
96  unsigned int i;
97 
98  eeprom->register_read(eeprom);
99 
100  /*
101  * Clear data flags.
102  */
103  eeprom->reg_data_in = 0;
104  eeprom->reg_data_out = 0;
105  eeprom->drive_data = 1;
106 
107  /*
108  * Start writing all bits.
109  */
110  for (i = count; i > 0; i--) {
111  /*
112  * Check if this bit needs to be set.
113  */
114  eeprom->reg_data_in = !!(data & (1 << (i - 1)));
115 
116  /*
117  * Write the bit to the eeprom register.
118  */
119  eeprom->register_write(eeprom);
120 
121  /*
122  * Kick a pulse.
123  */
124  eeprom_93cx6_pulse_high(eeprom);
125  eeprom_93cx6_pulse_low(eeprom);
126  }
127 
128  eeprom->reg_data_in = 0;
129  eeprom->register_write(eeprom);
130 }
131 
132 static void eeprom_93cx6_read_bits(struct eeprom_93cx6 *eeprom,
133  u16 *data, const u16 count)
134 {
135  unsigned int i;
136  u16 buf = 0;
137 
138  eeprom->register_read(eeprom);
139 
140  /*
141  * Clear data flags.
142  */
143  eeprom->reg_data_in = 0;
144  eeprom->reg_data_out = 0;
145  eeprom->drive_data = 0;
146 
147  /*
148  * Start reading all bits.
149  */
150  for (i = count; i > 0; i--) {
151  eeprom_93cx6_pulse_high(eeprom);
152 
153  eeprom->register_read(eeprom);
154 
155  /*
156  * Clear data_in flag.
157  */
158  eeprom->reg_data_in = 0;
159 
160  /*
161  * Read if the bit has been set.
162  */
163  if (eeprom->reg_data_out)
164  buf |= (1 << (i - 1));
165 
166  eeprom_93cx6_pulse_low(eeprom);
167  }
168 
169  *data = buf;
170 }
171 
181 void eeprom_93cx6_read(struct eeprom_93cx6 *eeprom, const u8 word,
182  u16 *data)
183 {
184  u16 command;
185 
186  /*
187  * Initialize the eeprom register
188  */
189  eeprom_93cx6_startup(eeprom);
190 
191  /*
192  * Select the read opcode and the word to be read.
193  */
194  command = (PCI_EEPROM_READ_OPCODE << eeprom->width) | word;
195  eeprom_93cx6_write_bits(eeprom, command,
196  PCI_EEPROM_WIDTH_OPCODE + eeprom->width);
197 
198  /*
199  * Read the requested 16 bits.
200  */
201  eeprom_93cx6_read_bits(eeprom, data, 16);
202 
203  /*
204  * Cleanup eeprom register.
205  */
206  eeprom_93cx6_cleanup(eeprom);
207 }
209 
223 void eeprom_93cx6_multiread(struct eeprom_93cx6 *eeprom, const u8 word,
224  __le16 *data, const u16 words)
225 {
226  unsigned int i;
227  u16 tmp;
228 
229  for (i = 0; i < words; i++) {
230  tmp = 0;
231  eeprom_93cx6_read(eeprom, word + i, &tmp);
232  data[i] = cpu_to_le16(tmp);
233  }
234 }
236 
245 void eeprom_93cx6_wren(struct eeprom_93cx6 *eeprom, bool enable)
246 {
247  u16 command;
248 
249  /* start the command */
250  eeprom_93cx6_startup(eeprom);
251 
252  /* create command to enable/disable */
253 
254  command = enable ? PCI_EEPROM_EWEN_OPCODE : PCI_EEPROM_EWDS_OPCODE;
255  command <<= (eeprom->width - 2);
256 
257  eeprom_93cx6_write_bits(eeprom, command,
258  PCI_EEPROM_WIDTH_OPCODE + eeprom->width);
259 
260  eeprom_93cx6_cleanup(eeprom);
261 }
263 
277 void eeprom_93cx6_write(struct eeprom_93cx6 *eeprom, u8 addr, u16 data)
278 {
279  int timeout = 100;
280  u16 command;
281 
282  /* start the command */
283  eeprom_93cx6_startup(eeprom);
284 
285  command = PCI_EEPROM_WRITE_OPCODE << eeprom->width;
286  command |= addr;
287 
288  /* send write command */
289  eeprom_93cx6_write_bits(eeprom, command,
290  PCI_EEPROM_WIDTH_OPCODE + eeprom->width);
291 
292  /* send data */
293  eeprom_93cx6_write_bits(eeprom, data, 16);
294 
295  /* get ready to check for busy */
296  eeprom->drive_data = 0;
297  eeprom->reg_chip_select = 1;
298  eeprom->register_write(eeprom);
299 
300  /* wait at-least 250ns to get DO to be the busy signal */
301  usleep_range(1000, 2000);
302 
303  /* wait for DO to go high to signify finish */
304 
305  while (true) {
306  eeprom->register_read(eeprom);
307 
308  if (eeprom->reg_data_out)
309  break;
310 
311  usleep_range(1000, 2000);
312 
313  if (--timeout <= 0) {
314  printk(KERN_ERR "%s: timeout\n", __func__);
315  break;
316  }
317  }
318 
319  eeprom_93cx6_cleanup(eeprom);
320 }