1/* credit winbond-840.c 2 */ 3#include <asm/io.h> 4 5struct eeprom_ops { 6 void (*set_cs)(void *ee); 7 void (*clear_cs)(void *ee); 8}; 9 10#define EEPOL_EEDI 0x01 11#define EEPOL_EEDO 0x02 12#define EEPOL_EECLK 0x04 13#define EEPOL_EESEL 0x08 14 15struct eeprom { 16 void *dev; 17 struct eeprom_ops *ops; 18 19 long addr; 20 21 unsigned ee_addr_bits; 22 23 unsigned eesel; 24 unsigned eeclk; 25 unsigned eedo; 26 unsigned eedi; 27 unsigned polarity; 28 unsigned ee_state; 29 30 spinlock_t *lock; 31 u32 *cache; 32}; 33 34 35u8 eeprom_readb(struct eeprom *ee, unsigned address); 36void eeprom_read(struct eeprom *ee, unsigned address, u8 *bytes, 37 unsigned count); 38void eeprom_writeb(struct eeprom *ee, unsigned address, u8 data); 39void eeprom_write(struct eeprom *ee, unsigned address, u8 *bytes, 40 unsigned count); 41 42/* The EEPROM commands include the alway-set leading bit. */ 43enum EEPROM_Cmds { 44 EE_WriteCmd=(5 << 6), EE_ReadCmd=(6 << 6), EE_EraseCmd=(7 << 6), 45}; 46 47void setup_ee_mem_bitbanger(struct eeprom *ee, long memaddr, int eesel_bit, int eeclk_bit, int eedo_bit, int eedi_bit, unsigned polarity) 48{ 49 ee->addr = memaddr; 50 ee->eesel = 1 << eesel_bit; 51 ee->eeclk = 1 << eeclk_bit; 52 ee->eedo = 1 << eedo_bit; 53 ee->eedi = 1 << eedi_bit; 54 55 ee->polarity = polarity; 56 57 *ee->cache = readl(ee->addr); 58} 59 60/* foo. put this in a .c file */ 61static inline void eeprom_update(struct eeprom *ee, u32 mask, int pol) 62{ 63 long flags; 64 u32 data; 65 66 spin_lock_irqsave(ee->lock, flags); 67 data = *ee->cache; 68 69 data &= ~mask; 70 if (pol) 71 data |= mask; 72 73 *ee->cache = data; 74//printk("update: %08x\n", data); 75 writel(data, ee->addr); 76 spin_unlock_irqrestore(ee->lock, flags); 77} 78 79void eeprom_clk_lo(struct eeprom *ee) 80{ 81 int pol = !!(ee->polarity & EEPOL_EECLK); 82 83 eeprom_update(ee, ee->eeclk, pol); 84 udelay(2); 85} 86 87void eeprom_clk_hi(struct eeprom *ee) 88{ 89 int pol = !!(ee->polarity & EEPOL_EECLK); 90 91 eeprom_update(ee, ee->eeclk, !pol); 92 udelay(2); 93} 94 95void eeprom_send_addr(struct eeprom *ee, unsigned address) 96{ 97 int pol = !!(ee->polarity & EEPOL_EEDI); 98 unsigned i; 99 address |= 6 << 6; 100 101 /* Shift the read command bits out. */ 102 for (i=0; i<11; i++) { 103 eeprom_update(ee, ee->eedi, ((address >> 10) & 1) ^ pol); 104 address <<= 1; 105 eeprom_clk_hi(ee); 106 eeprom_clk_lo(ee); 107 } 108 eeprom_update(ee, ee->eedi, pol); 109} 110 111u16 eeprom_readw(struct eeprom *ee, unsigned address) 112{ 113 unsigned i; 114 u16 res = 0; 115 116 eeprom_clk_lo(ee); 117 eeprom_update(ee, ee->eesel, 1 ^ !!(ee->polarity & EEPOL_EESEL)); 118 eeprom_send_addr(ee, address); 119 120 for (i=0; i<16; i++) { 121 u32 data; 122 eeprom_clk_hi(ee); 123 res <<= 1; 124 data = readl(ee->addr); 125//printk("eeprom_readw: %08x\n", data); 126 res |= !!(data & ee->eedo) ^ !!(ee->polarity & EEPOL_EEDO); 127 eeprom_clk_lo(ee); 128 } 129 eeprom_update(ee, ee->eesel, 0 ^ !!(ee->polarity & EEPOL_EESEL)); 130 131 return res; 132} 133 134 135void eeprom_writeb(struct eeprom *ee, unsigned address, u8 data) 136{ 137} 138