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