1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (C) 2004 - 2006 rt2x00 SourceForge Project
4 * <http://rt2x00.serialmonkey.com>
7 * Abstract: EEPROM reader routines for 93cx6 chipsets.
8 * Supported chipsets: 93c46 & 93c66.
11 #include <linux/bits.h>
12 #include <linux/kernel.h>
13 #include <linux/module.h>
14 #include <linux/delay.h>
15 #include <linux/eeprom_93cx6.h>
17 MODULE_AUTHOR("http://rt2x00.serialmonkey.com");
18 MODULE_VERSION("1.0");
19 MODULE_DESCRIPTION("EEPROM 93cx6 chip driver");
20 MODULE_LICENSE("GPL");
22 static inline void eeprom_93cx6_pulse_high(struct eeprom_93cx6
*eeprom
)
24 eeprom
->reg_data_clock
= 1;
25 eeprom
->register_write(eeprom
);
28 * Add a short delay for the pulse to work.
29 * According to the specifications the "maximum minimum"
30 * time should be 450ns.
35 static inline void eeprom_93cx6_pulse_low(struct eeprom_93cx6
*eeprom
)
37 eeprom
->reg_data_clock
= 0;
38 eeprom
->register_write(eeprom
);
41 * Add a short delay for the pulse to work.
42 * According to the specifications the "maximum minimum"
43 * time should be 450ns.
48 static void eeprom_93cx6_startup(struct eeprom_93cx6
*eeprom
)
51 * Clear all flags, and enable chip select.
53 eeprom
->register_read(eeprom
);
54 eeprom
->reg_data_in
= 0;
55 eeprom
->reg_data_out
= 0;
56 eeprom
->reg_data_clock
= 0;
57 eeprom
->reg_chip_select
= 1;
58 eeprom
->drive_data
= 1;
59 eeprom
->register_write(eeprom
);
64 eeprom_93cx6_pulse_high(eeprom
);
65 eeprom_93cx6_pulse_low(eeprom
);
68 static void eeprom_93cx6_cleanup(struct eeprom_93cx6
*eeprom
)
71 * Clear chip_select and data_in flags.
73 eeprom
->register_read(eeprom
);
74 eeprom
->reg_data_in
= 0;
75 eeprom
->reg_chip_select
= 0;
76 eeprom
->register_write(eeprom
);
81 eeprom_93cx6_pulse_high(eeprom
);
82 eeprom_93cx6_pulse_low(eeprom
);
85 static void eeprom_93cx6_write_bits(struct eeprom_93cx6
*eeprom
,
86 const u16 data
, const u16 count
)
90 eeprom
->register_read(eeprom
);
95 eeprom
->reg_data_in
= 0;
96 eeprom
->reg_data_out
= 0;
97 eeprom
->drive_data
= 1;
100 * Start writing all bits.
102 for (i
= count
; i
> 0; i
--) {
104 * Check if this bit needs to be set.
106 eeprom
->reg_data_in
= !!(data
& BIT(i
- 1));
109 * Write the bit to the eeprom register.
111 eeprom
->register_write(eeprom
);
116 eeprom_93cx6_pulse_high(eeprom
);
117 eeprom_93cx6_pulse_low(eeprom
);
120 eeprom
->reg_data_in
= 0;
121 eeprom
->register_write(eeprom
);
124 static void eeprom_93cx6_read_bits(struct eeprom_93cx6
*eeprom
,
125 u16
*data
, const u16 count
)
130 eeprom
->register_read(eeprom
);
135 eeprom
->reg_data_in
= 0;
136 eeprom
->reg_data_out
= 0;
137 eeprom
->drive_data
= 0;
140 * Start reading all bits.
142 for (i
= count
; i
> 0; i
--) {
143 eeprom_93cx6_pulse_high(eeprom
);
145 eeprom
->register_read(eeprom
);
148 * Clear data_in flag.
150 eeprom
->reg_data_in
= 0;
153 * Read if the bit has been set.
155 if (eeprom
->reg_data_out
)
158 eeprom_93cx6_pulse_low(eeprom
);
165 * eeprom_93cx6_read - Read a word from eeprom
166 * @eeprom: Pointer to eeprom structure
167 * @word: Word index from where we should start reading
168 * @data: target pointer where the information will have to be stored
170 * This function will read the eeprom data as host-endian word
171 * into the given data pointer.
173 void eeprom_93cx6_read(struct eeprom_93cx6
*eeprom
, const u8 word
,
179 * Initialize the eeprom register
181 eeprom_93cx6_startup(eeprom
);
184 * Select the read opcode and the word to be read.
186 command
= (PCI_EEPROM_READ_OPCODE
<< eeprom
->width
) | word
;
187 eeprom_93cx6_write_bits(eeprom
, command
,
188 PCI_EEPROM_WIDTH_OPCODE
+ eeprom
->width
);
190 if (has_quirk_extra_read_cycle(eeprom
)) {
191 eeprom_93cx6_pulse_high(eeprom
);
192 eeprom_93cx6_pulse_low(eeprom
);
196 * Read the requested 16 bits.
198 eeprom_93cx6_read_bits(eeprom
, data
, 16);
201 * Cleanup eeprom register.
203 eeprom_93cx6_cleanup(eeprom
);
205 EXPORT_SYMBOL_GPL(eeprom_93cx6_read
);
208 * eeprom_93cx6_multiread - Read multiple words from eeprom
209 * @eeprom: Pointer to eeprom structure
210 * @word: Word index from where we should start reading
211 * @data: target pointer where the information will have to be stored
212 * @words: Number of words that should be read.
214 * This function will read all requested words from the eeprom,
215 * this is done by calling eeprom_93cx6_read() multiple times.
216 * But with the additional change that while the eeprom_93cx6_read
217 * will return host ordered bytes, this method will return little
220 void eeprom_93cx6_multiread(struct eeprom_93cx6
*eeprom
, const u8 word
,
221 __le16
*data
, const u16 words
)
226 for (i
= 0; i
< words
; i
++) {
228 eeprom_93cx6_read(eeprom
, word
+ i
, &tmp
);
229 data
[i
] = cpu_to_le16(tmp
);
232 EXPORT_SYMBOL_GPL(eeprom_93cx6_multiread
);
235 * eeprom_93cx6_readb - Read a byte from eeprom
236 * @eeprom: Pointer to eeprom structure
237 * @byte: Byte index from where we should start reading
238 * @data: target pointer where the information will have to be stored
240 * This function will read a byte of the eeprom data
241 * into the given data pointer.
243 void eeprom_93cx6_readb(struct eeprom_93cx6
*eeprom
, const u8 byte
,
250 * Initialize the eeprom register
252 eeprom_93cx6_startup(eeprom
);
255 * Select the read opcode and the byte to be read.
257 command
= (PCI_EEPROM_READ_OPCODE
<< (eeprom
->width
+ 1)) | byte
;
258 eeprom_93cx6_write_bits(eeprom
, command
,
259 PCI_EEPROM_WIDTH_OPCODE
+ eeprom
->width
+ 1);
261 if (has_quirk_extra_read_cycle(eeprom
)) {
262 eeprom_93cx6_pulse_high(eeprom
);
263 eeprom_93cx6_pulse_low(eeprom
);
267 * Read the requested 8 bits.
269 eeprom_93cx6_read_bits(eeprom
, &tmp
, 8);
273 * Cleanup eeprom register.
275 eeprom_93cx6_cleanup(eeprom
);
277 EXPORT_SYMBOL_GPL(eeprom_93cx6_readb
);
280 * eeprom_93cx6_multireadb - Read multiple bytes from eeprom
281 * @eeprom: Pointer to eeprom structure
282 * @byte: Index from where we should start reading
283 * @data: target pointer where the information will have to be stored
284 * @bytes: Number of bytes that should be read.
286 * This function will read all requested bytes from the eeprom,
287 * this is done by calling eeprom_93cx6_readb() multiple times.
289 void eeprom_93cx6_multireadb(struct eeprom_93cx6
*eeprom
, const u8 byte
,
290 u8
*data
, const u16 bytes
)
294 for (i
= 0; i
< bytes
; i
++)
295 eeprom_93cx6_readb(eeprom
, byte
+ i
, &data
[i
]);
297 EXPORT_SYMBOL_GPL(eeprom_93cx6_multireadb
);
300 * eeprom_93cx6_wren - set the write enable state
301 * @eeprom: Pointer to eeprom structure
302 * @enable: true to enable writes, otherwise disable writes
304 * Set the EEPROM write enable state to either allow or deny
305 * writes depending on the @enable value.
307 void eeprom_93cx6_wren(struct eeprom_93cx6
*eeprom
, bool enable
)
311 /* start the command */
312 eeprom_93cx6_startup(eeprom
);
314 /* create command to enable/disable */
316 command
= enable
? PCI_EEPROM_EWEN_OPCODE
: PCI_EEPROM_EWDS_OPCODE
;
317 command
<<= (eeprom
->width
- 2);
319 eeprom_93cx6_write_bits(eeprom
, command
,
320 PCI_EEPROM_WIDTH_OPCODE
+ eeprom
->width
);
322 eeprom_93cx6_cleanup(eeprom
);
324 EXPORT_SYMBOL_GPL(eeprom_93cx6_wren
);
327 * eeprom_93cx6_write - write data to the EEPROM
328 * @eeprom: Pointer to eeprom structure
329 * @addr: Address to write data to.
330 * @data: The data to write to address @addr.
332 * Write the @data to the specified @addr in the EEPROM and
333 * waiting for the device to finish writing.
335 * Note, since we do not expect large number of write operations
336 * we delay in between parts of the operation to avoid using excessive
337 * amounts of CPU time busy waiting.
339 void eeprom_93cx6_write(struct eeprom_93cx6
*eeprom
, u8 addr
, u16 data
)
344 /* start the command */
345 eeprom_93cx6_startup(eeprom
);
347 command
= PCI_EEPROM_WRITE_OPCODE
<< eeprom
->width
;
350 /* send write command */
351 eeprom_93cx6_write_bits(eeprom
, command
,
352 PCI_EEPROM_WIDTH_OPCODE
+ eeprom
->width
);
355 eeprom_93cx6_write_bits(eeprom
, data
, 16);
357 /* get ready to check for busy */
358 eeprom
->drive_data
= 0;
359 eeprom
->reg_chip_select
= 1;
360 eeprom
->register_write(eeprom
);
362 /* wait at-least 250ns to get DO to be the busy signal */
363 usleep_range(1000, 2000);
365 /* wait for DO to go high to signify finish */
368 eeprom
->register_read(eeprom
);
370 if (eeprom
->reg_data_out
)
373 usleep_range(1000, 2000);
375 if (--timeout
<= 0) {
376 printk(KERN_ERR
"%s: timeout\n", __func__
);
381 eeprom_93cx6_cleanup(eeprom
);
383 EXPORT_SYMBOL_GPL(eeprom_93cx6_write
);