diff options
Diffstat (limited to 'include/linux/eeprom.h')
-rw-r--r-- | include/linux/eeprom.h | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/include/linux/eeprom.h b/include/linux/eeprom.h new file mode 100644 index 000000000000..38afd9da1dfe --- /dev/null +++ b/include/linux/eeprom.h | |||
@@ -0,0 +1,136 @@ | |||
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 | } | ||