added a lot of printk output to ease writing of emulator
[linux-2.4.21-pre4.git] / include / linux / eeprom.h
1 /* credit winbond-840.c
2  */
3 #include <asm/io.h>
4
5 struct 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
15 struct 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
35 u8   eeprom_readb(struct eeprom *ee, unsigned address);
36 void eeprom_read(struct eeprom *ee, unsigned address, u8 *bytes,
37                 unsigned count);
38 void eeprom_writeb(struct eeprom *ee, unsigned address, u8 data);
39 void eeprom_write(struct eeprom *ee, unsigned address, u8 *bytes,
40                 unsigned count);
41
42 /* The EEPROM commands include the alway-set leading bit. */
43 enum EEPROM_Cmds {
44         EE_WriteCmd=(5 << 6), EE_ReadCmd=(6 << 6), EE_EraseCmd=(7 << 6),
45 };
46
47 void 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 */
61 static 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
79 void 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
87 void 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
95 void 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
111 u16   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
135 void eeprom_writeb(struct eeprom *ee, unsigned address, u8 data)
136 {
137 }