Viewing file: eeprom.h (2.77 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
/* credit winbond-840.c */ #include <asm/io.h>
struct eeprom_ops { void (*set_cs)(void *ee); void (*clear_cs)(void *ee); };
#define EEPOL_EEDI 0x01 #define EEPOL_EEDO 0x02 #define EEPOL_EECLK 0x04 #define EEPOL_EESEL 0x08
struct eeprom { void *dev; struct eeprom_ops *ops;
long addr;
unsigned ee_addr_bits;
unsigned eesel; unsigned eeclk; unsigned eedo; unsigned eedi; unsigned polarity; unsigned ee_state;
spinlock_t *lock; u32 *cache; };
u8 eeprom_readb(struct eeprom *ee, unsigned address); void eeprom_read(struct eeprom *ee, unsigned address, u8 *bytes, unsigned count); void eeprom_writeb(struct eeprom *ee, unsigned address, u8 data); void eeprom_write(struct eeprom *ee, unsigned address, u8 *bytes, unsigned count);
/* The EEPROM commands include the alway-set leading bit. */ enum EEPROM_Cmds { EE_WriteCmd=(5 << 6), EE_ReadCmd=(6 << 6), EE_EraseCmd=(7 << 6), };
void setup_ee_mem_bitbanger(struct eeprom *ee, long memaddr, int eesel_bit, int eeclk_bit, int eedo_bit, int eedi_bit, unsigned polarity) { ee->addr = memaddr; ee->eesel = 1 << eesel_bit; ee->eeclk = 1 << eeclk_bit; ee->eedo = 1 << eedo_bit; ee->eedi = 1 << eedi_bit;
ee->polarity = polarity;
*ee->cache = readl(ee->addr); }
/* foo. put this in a .c file */ static inline void eeprom_update(struct eeprom *ee, u32 mask, int pol) { long flags; u32 data;
spin_lock_irqsave(ee->lock, flags); data = *ee->cache;
data &= ~mask; if (pol) data |= mask;
*ee->cache = data; //printk("update: %08x\n", data); writel(data, ee->addr); spin_unlock_irqrestore(ee->lock, flags); }
void eeprom_clk_lo(struct eeprom *ee) { int pol = !!(ee->polarity & EEPOL_EECLK);
eeprom_update(ee, ee->eeclk, pol); udelay(2); }
void eeprom_clk_hi(struct eeprom *ee) { int pol = !!(ee->polarity & EEPOL_EECLK);
eeprom_update(ee, ee->eeclk, !pol); udelay(2); }
void eeprom_send_addr(struct eeprom *ee, unsigned address) { int pol = !!(ee->polarity & EEPOL_EEDI); unsigned i; address |= 6 << 6;
/* Shift the read command bits out. */ for (i=0; i<11; i++) { eeprom_update(ee, ee->eedi, ((address >> 10) & 1) ^ pol); address <<= 1; eeprom_clk_hi(ee); eeprom_clk_lo(ee); } eeprom_update(ee, ee->eedi, pol); }
u16 eeprom_readw(struct eeprom *ee, unsigned address) { unsigned i; u16 res = 0;
eeprom_clk_lo(ee); eeprom_update(ee, ee->eesel, 1 ^ !!(ee->polarity & EEPOL_EESEL)); eeprom_send_addr(ee, address);
for (i=0; i<16; i++) { u32 data; eeprom_clk_hi(ee); res <<= 1; data = readl(ee->addr); //printk("eeprom_readw: %08x\n", data); res |= !!(data & ee->eedo) ^ !!(ee->polarity & EEPOL_EEDO); eeprom_clk_lo(ee); } eeprom_update(ee, ee->eesel, 0 ^ !!(ee->polarity & EEPOL_EESEL));
return res; }
void eeprom_writeb(struct eeprom *ee, unsigned address, u8 data) { }
|