1 /* Three-wire (MicroWire) serial eeprom driver (for 93C46 and compatibles) */
5 #include <asm/ic/ssi.h>
6 #include <linux/delay.h>
9 * Serial EEPROM opcodes, including start bit
11 #define EEP_OPC_ERASE 0x7 /* 3-bit opcode */
12 #define EEP_OPC_WRITE 0x5 /* 3-bit opcode */
13 #define EEP_OPC_READ 0x6 /* 3-bit opcode */
15 #define EEP_OPC_ERASE_ALL 0x12 /* 5-bit opcode */
16 #define EEP_OPC_ERASE_EN 0x13 /* 5-bit opcode */
17 #define EEP_OPC_WRITE_ALL 0x11 /* 5-bit opcode */
18 #define EEP_OPC_ERASE_DIS 0x10 /* 5-bit opcode */
22 static void mw_eeprom_select(int dev)
24 ssi_set_interface(2048, 0, 0, 0);
31 static int mw_eeprom_size(int dev)
36 mw_eeprom_select(dev);
37 ssi_tx_byte(EEP_OPC_READ);
39 res = ssi_txrx_byte(0) << 8;
41 for (x = 0; x < 16; x++) {
42 if (! (res & 0x8000)) {
52 int mw_eeprom_erase_enable(int dev)
54 mw_eeprom_select(dev);
55 ssi_tx_byte(EEP_OPC_ERASE_EN);
63 int mw_eeprom_erase_disable(int dev)
65 mw_eeprom_select(dev);
66 ssi_tx_byte(EEP_OPC_ERASE_DIS);
75 u32 mw_eeprom_read_word(int dev, int addr)
81 mw_eeprom_select(dev);
82 ssi_tx_byte((EEP_OPC_READ << 5) | ((addr >> (addrlen - 5)) & 0x1f));
83 rcv = ssi_txrx_byte(addr << (13 - addrlen));
84 res = rcv << (16 - addrlen);
90 res |= rcv << (bits - 8);
92 res |= rcv >> (8 - bits);
102 int mw_eeprom_write_word(int dev, int addr, u16 data)
107 mw_eeprom_erase_enable(dev);
108 mw_eeprom_select(dev);
112 byte1 = EEP_OPC_WRITE >> 2;
113 byte2 = (EEP_OPC_WRITE << 6)&0xc0;
117 byte1 = EEP_OPC_WRITE >> 1;
118 byte2 = (EEP_OPC_WRITE << 7)&0x80;
122 byte1 = EEP_OPC_WRITE;
126 byte1 = EEP_OPC_WRITE << 1;
131 byte1 = EEP_OPC_WRITE << 2;
136 printf("Unsupported number of address bits: %d\n", addrlen);
143 ssi_tx_byte(data >> 8);
144 ssi_tx_byte(data & 0xff);
146 udelay(10000); /* Worst case */
147 mw_eeprom_erase_disable(dev);
153 int mw_eeprom_write(int dev, int addr, u8 *buffer, int len)
159 u16 temp = mw_eeprom_read_word(dev, addr >> 1);
163 mw_eeprom_write_word(dev, addr >> 1, temp);
171 mw_eeprom_write_word(dev, addr >> 1, *(u16*)buffer);
179 u16 temp = mw_eeprom_read_word(dev, addr >> 1);
181 temp |= buffer[0] << 8;
183 mw_eeprom_write_word(dev, addr >> 1, temp);
194 int mw_eeprom_read(int dev, int addr, u8 *buffer, int len)
200 u16 temp = mw_eeprom_read_word(dev, addr >> 1);
201 buffer[0]= temp & 0xff;
210 *(u16*)buffer = mw_eeprom_read_word(dev, addr >> 1);
218 u16 temp = mw_eeprom_read_word(dev, addr >> 1);
219 buffer[0] = temp >> 8;
230 int mw_eeprom_probe(int dev)
232 addrlen = mw_eeprom_size(dev);
234 if (addrlen < 6 || addrlen > 10) {