Merge with http://www.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
[linux-2.6] / include / linux / eeprom.h
1 /* credit winbond-840.c
2  */
3 #include <asm/io.h>
4 struct 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
14 struct 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
34 u8   eeprom_readb(struct eeprom *ee, unsigned address);
35 void eeprom_read(struct eeprom *ee, unsigned address, u8 *bytes,
36                 unsigned count);
37 void eeprom_writeb(struct eeprom *ee, unsigned address, u8 data);
38 void eeprom_write(struct eeprom *ee, unsigned address, u8 *bytes,
39                 unsigned count);
40
41 /* The EEPROM commands include the alway-set leading bit. */
42 enum EEPROM_Cmds {
43         EE_WriteCmd=(5 << 6), EE_ReadCmd=(6 << 6), EE_EraseCmd=(7 << 6),
44 };
45
46 void 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 */
60 static 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
78 void 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
86 void 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
94 void 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
110 u16   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
134 void eeprom_writeb(struct eeprom *ee, unsigned address, u8 data)
135 {
136 }