Subversion Repositories shark

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
422 giacomo 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
        long            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, long 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
}