Skip to content

Commit 7738a7a

Browse files
pnewman-ctigregkh
authored andcommitted
misc: eeprom: eeprom_93cx6: Add quirk for extra read clock cycle
Add a quirk similar to eeprom_93xx46 to add an extra clock cycle before reading data from the EEPROM. The 93Cx6 family of EEPROMs output a "dummy 0 bit" between the writing of the op-code/address from the host to the EEPROM and the reading of the actual data from the EEPROM. More info can be found on page 6 of the AT93C46 datasheet (linked below). Similar notes are found in other 93xx6 datasheets. In summary the read operation for a 93Cx6 EEPROM is: Write to EEPROM: 110[A5-A0] (9 bits) Read from EEPROM: 0[D15-D0] (17 bits) Where: 110 is the start bit and READ OpCode [A5-A0] is the address to read from 0 is a "dummy bit" preceding the actual data [D15-D0] is the actual data. Looking at the READ timing diagrams in the 93Cx6 datasheets the dummy bit should be clocked out on the last address bit clock cycle meaning it should be discarded naturally. However, depending on the hardware configuration sometimes this dummy bit is not discarded. This is the case with Exar PCI UARTs which require an extra clock cycle between sending the address and reading the data. Datasheet: https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-5193-SEEPROM-AT93C46D-Datasheet.pdf Reviewed-by: Andy Shevchenko <[email protected]> Signed-off-by: Parker Newman <[email protected]> Link: https://lore.kernel.org/r/0f23973efefccd2544705a0480b4ad4c2353e407.1727880931.git.pnewman@connecttech.com Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 70acca6 commit 7738a7a

File tree

2 files changed

+21
-0
lines changed

2 files changed

+21
-0
lines changed

drivers/misc/eeprom/eeprom_93cx6.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,11 @@ void eeprom_93cx6_read(struct eeprom_93cx6 *eeprom, const u8 word,
186186
eeprom_93cx6_write_bits(eeprom, command,
187187
PCI_EEPROM_WIDTH_OPCODE + eeprom->width);
188188

189+
if (has_quirk_extra_read_cycle(eeprom)) {
190+
eeprom_93cx6_pulse_high(eeprom);
191+
eeprom_93cx6_pulse_low(eeprom);
192+
}
193+
189194
/*
190195
* Read the requested 16 bits.
191196
*/
@@ -252,6 +257,11 @@ void eeprom_93cx6_readb(struct eeprom_93cx6 *eeprom, const u8 byte,
252257
eeprom_93cx6_write_bits(eeprom, command,
253258
PCI_EEPROM_WIDTH_OPCODE + eeprom->width + 1);
254259

260+
if (has_quirk_extra_read_cycle(eeprom)) {
261+
eeprom_93cx6_pulse_high(eeprom);
262+
eeprom_93cx6_pulse_low(eeprom);
263+
}
264+
255265
/*
256266
* Read the requested 8 bits.
257267
*/

include/linux/eeprom_93cx6.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
Supported chipsets: 93c46, 93c56 and 93c66.
1212
*/
1313

14+
#include <linux/bits.h>
15+
1416
/*
1517
* EEPROM operation defines.
1618
*/
@@ -34,6 +36,7 @@
3436
* @register_write(struct eeprom_93cx6 *eeprom): handler to
3537
* write to the eeprom register by using all reg_* fields.
3638
* @width: eeprom width, should be one of the PCI_EEPROM_WIDTH_* defines
39+
* @quirks: eeprom or controller quirks
3740
* @drive_data: Set if we're driving the data line.
3841
* @reg_data_in: register field to indicate data input
3942
* @reg_data_out: register field to indicate data output
@@ -50,6 +53,9 @@ struct eeprom_93cx6 {
5053
void (*register_write)(struct eeprom_93cx6 *eeprom);
5154

5255
int width;
56+
unsigned int quirks;
57+
/* Some EEPROMs require an extra clock cycle before reading */
58+
#define PCI_EEPROM_QUIRK_EXTRA_READ_CYCLE BIT(0)
5359

5460
char drive_data;
5561
char reg_data_in;
@@ -71,3 +77,8 @@ extern void eeprom_93cx6_wren(struct eeprom_93cx6 *eeprom, bool enable);
7177

7278
extern void eeprom_93cx6_write(struct eeprom_93cx6 *eeprom,
7379
u8 addr, u16 data);
80+
81+
static inline bool has_quirk_extra_read_cycle(struct eeprom_93cx6 *eeprom)
82+
{
83+
return eeprom->quirks & PCI_EEPROM_QUIRK_EXTRA_READ_CYCLE;
84+
}

0 commit comments

Comments
 (0)