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