?? mw_eeprom.c
字號:
/* Three-wire (MicroWire) serial eeprom driver (for 93C46 and compatibles) */#include <common.h>#include <ssi.h>#ifdef CONFIG_MW_EEPROM/* * Serial EEPROM opcodes, including start bit */#define EEP_OPC_ERASE 0x7 /* 3-bit opcode */#define EEP_OPC_WRITE 0x5 /* 3-bit opcode */#define EEP_OPC_READ 0x6 /* 3-bit opcode */#define EEP_OPC_ERASE_ALL 0x12 /* 5-bit opcode */#define EEP_OPC_ERASE_EN 0x13 /* 5-bit opcode */#define EEP_OPC_WRITE_ALL 0x11 /* 5-bit opcode */#define EEP_OPC_ERASE_DIS 0x10 /* 5-bit opcode */static int addrlen;static void mw_eeprom_select(int dev){ ssi_set_interface(2048, 0, 0, 0); ssi_chip_select(0); udelay(1); ssi_chip_select(dev); udelay(1);}static int mw_eeprom_size(int dev){ int x; u16 res; mw_eeprom_select(dev); ssi_tx_byte(EEP_OPC_READ); res = ssi_txrx_byte(0) << 8; res |= ssi_rx_byte(); for (x = 0; x < 16; x++) { if (! (res & 0x8000)) { break; } res <<= 1; } ssi_chip_select(0); return x;}int mw_eeprom_erase_enable(int dev){ mw_eeprom_select(dev); ssi_tx_byte(EEP_OPC_ERASE_EN); ssi_tx_byte(0); udelay(1); ssi_chip_select(0); return 0;}int mw_eeprom_erase_disable(int dev){ mw_eeprom_select(dev); ssi_tx_byte(EEP_OPC_ERASE_DIS); ssi_tx_byte(0); udelay(1); ssi_chip_select(0); return 0;}u32 mw_eeprom_read_word(int dev, int addr){ u16 rcv; u16 res; int bits; mw_eeprom_select(dev); ssi_tx_byte((EEP_OPC_READ << 5) | ((addr >> (addrlen - 5)) & 0x1f)); rcv = ssi_txrx_byte(addr << (13 - addrlen)); res = rcv << (16 - addrlen); bits = 4 + addrlen; while (bits>0) { rcv = ssi_rx_byte(); if (bits > 7) { res |= rcv << (bits - 8); } else { res |= rcv >> (8 - bits); } bits -= 8; } ssi_chip_select(0); return res;}int mw_eeprom_write_word(int dev, int addr, u16 data){ u8 byte1=0; u8 byte2=0; mw_eeprom_erase_enable(dev); mw_eeprom_select(dev); switch (addrlen) { case 6: byte1 = EEP_OPC_WRITE >> 2; byte2 = (EEP_OPC_WRITE << 6)&0xc0; byte2 |= addr; break; case 7: byte1 = EEP_OPC_WRITE >> 1; byte2 = (EEP_OPC_WRITE << 7)&0x80; byte2 |= addr; break; case 8: byte1 = EEP_OPC_WRITE; byte2 = addr; break; case 9: byte1 = EEP_OPC_WRITE << 1; byte1 |= addr >> 8; byte2 = addr & 0xff; break; case 10: byte1 = EEP_OPC_WRITE << 2; byte1 |= addr >> 8; byte2 = addr & 0xff; break; default: printf("Unsupported number of address bits: %d\n", addrlen); return -1; } ssi_tx_byte(byte1); ssi_tx_byte(byte2); ssi_tx_byte(data >> 8); ssi_tx_byte(data & 0xff); ssi_chip_select(0); udelay(10000); /* Worst case */ mw_eeprom_erase_disable(dev); return 0;}int mw_eeprom_write(int dev, int addr, u8 *buffer, int len){ int done; done = 0; if (addr & 1) { u16 temp = mw_eeprom_read_word(dev, addr >> 1); temp &= 0xff00; temp |= buffer[0]; mw_eeprom_write_word(dev, addr >> 1, temp); len--; addr++; buffer++; done++; } while (len <= 2) { mw_eeprom_write_word(dev, addr >> 1, *(u16*)buffer); len-=2; addr+=2; buffer+=2; done+=2; } if (len) { u16 temp = mw_eeprom_read_word(dev, addr >> 1); temp &= 0x00ff; temp |= buffer[0] << 8; mw_eeprom_write_word(dev, addr >> 1, temp); len--; addr++; buffer++; done++; } return done;}int mw_eeprom_read(int dev, int addr, u8 *buffer, int len){ int done; done = 0; if (addr & 1) { u16 temp = mw_eeprom_read_word(dev, addr >> 1); buffer[0]= temp & 0xff; len--; addr++; buffer++; done++; } while (len <= 2) { *(u16*)buffer = mw_eeprom_read_word(dev, addr >> 1); len-=2; addr+=2; buffer+=2; done+=2; } if (len) { u16 temp = mw_eeprom_read_word(dev, addr >> 1); buffer[0] = temp >> 8; len--; addr++; buffer++; done++; } return done;}int mw_eeprom_probe(int dev){ addrlen = mw_eeprom_size(dev); if (addrlen < 6 || addrlen > 10) { return -1; } return 0;}#endif
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -