include upstream ip1000a driver version 2.09f
[linux-2.4.git] / drivers / atm / nicstarmac.c
1 /*
2  * this file included by nicstar.c
3  */
4
5 /*
6  * nicstarmac.c
7  * Read this ForeRunner's MAC address from eprom/eeprom
8  */
9
10 #define CYCLE_DELAY 5
11
12 /* This was the original definition
13 #define osp_MicroDelay(microsec) \
14     do { int _i = 4*microsec; while (--_i > 0) { __SLOW_DOWN_IO; }} while (0)
15 */
16 #define osp_MicroDelay(microsec) {unsigned long useconds = (microsec); \
17                                   udelay((useconds));}
18
19
20 /* The following tables represent the timing diagrams found in
21  * the Data Sheet for the Xicor X25020 EEProm.  The #defines below
22  * represent the bits in the NICStAR's General Purpose register
23  * that must be toggled for the corresponding actions on the EEProm
24  * to occur.
25  */
26
27 /* Write Data To EEProm from SI line on rising edge of CLK */
28 /* Read Data From EEProm on falling edge of CLK */
29
30 #define CS_HIGH         0x0002          /* Chip select high */
31 #define CS_LOW          0x0000          /* Chip select low (active low)*/
32 #define CLK_HIGH        0x0004          /* Clock high */
33 #define CLK_LOW         0x0000          /* Clock low  */
34 #define SI_HIGH         0x0001          /* Serial input data high */
35 #define SI_LOW          0x0000          /* Serial input data low */
36
37 /* Read Status Register = 0000 0101b */
38 static u_int32_t rdsrtab[] =
39 {
40     CS_HIGH | CLK_HIGH, 
41     CS_LOW | CLK_LOW, 
42     CLK_HIGH,             /* 0 */
43     CLK_LOW, 
44     CLK_HIGH,             /* 0 */
45     CLK_LOW, 
46     CLK_HIGH,             /* 0 */
47     CLK_LOW,
48     CLK_HIGH,             /* 0 */
49     CLK_LOW, 
50     CLK_HIGH,             /* 0 */
51     CLK_LOW | SI_HIGH, 
52     CLK_HIGH | SI_HIGH,   /* 1 */
53     CLK_LOW | SI_LOW, 
54     CLK_HIGH,             /* 0 */
55     CLK_LOW | SI_HIGH, 
56     CLK_HIGH | SI_HIGH   /* 1 */
57 };
58
59
60 /* Read from EEPROM = 0000 0011b */
61 static u_int32_t readtab[] =
62 {
63     /*
64     CS_HIGH | CLK_HIGH, 
65     */
66     CS_LOW | CLK_LOW, 
67     CLK_HIGH,             /* 0 */
68     CLK_LOW, 
69     CLK_HIGH,             /* 0 */
70     CLK_LOW, 
71     CLK_HIGH,             /* 0 */
72     CLK_LOW,
73     CLK_HIGH,             /* 0 */
74     CLK_LOW, 
75     CLK_HIGH,             /* 0 */
76     CLK_LOW, 
77     CLK_HIGH,             /* 0 */
78     CLK_LOW | SI_HIGH, 
79     CLK_HIGH | SI_HIGH,   /* 1 */
80     CLK_LOW | SI_HIGH, 
81     CLK_HIGH | SI_HIGH    /* 1 */
82 };
83
84
85 /* Clock to read from/write to the eeprom */
86 static u_int32_t clocktab[] =
87 {       
88     CLK_LOW,
89     CLK_HIGH,
90     CLK_LOW, 
91     CLK_HIGH,
92     CLK_LOW,
93     CLK_HIGH,
94     CLK_LOW, 
95     CLK_HIGH,
96     CLK_LOW, 
97     CLK_HIGH,
98     CLK_LOW, 
99     CLK_HIGH, 
100     CLK_LOW, 
101     CLK_HIGH,
102     CLK_LOW, 
103     CLK_HIGH,
104     CLK_LOW 
105 };
106
107
108 #define NICSTAR_REG_WRITE(bs, reg, val) \
109         while ( readl(bs + STAT) & 0x0200 ) ; \
110         writel((val),(base)+(reg))
111 #define NICSTAR_REG_READ(bs, reg) \
112         readl((base)+(reg))
113 #define NICSTAR_REG_GENERAL_PURPOSE GP
114
115 /*
116  * This routine will clock the Read_Status_reg function into the X2520
117  * eeprom, then pull the result from bit 16 of the NicSTaR's General Purpose 
118  * register.  
119  */
120
121 u_int32_t
122 nicstar_read_eprom_status( virt_addr_t base )
123 {
124    u_int32_t    val;
125    u_int32_t    rbyte;
126    int32_t      i, j;
127
128    /* Send read instruction */
129    val = NICSTAR_REG_READ( base, NICSTAR_REG_GENERAL_PURPOSE ) & 0xFFFFFFF0;
130
131    for (i=0; i<sizeof rdsrtab/sizeof rdsrtab[0]; i++)
132    {
133         NICSTAR_REG_WRITE( base, NICSTAR_REG_GENERAL_PURPOSE,
134                 (val | rdsrtab[i]) );
135         osp_MicroDelay( CYCLE_DELAY );
136    }
137
138    /* Done sending instruction - now pull data off of bit 16, MSB first */
139    /* Data clocked out of eeprom on falling edge of clock */
140
141    rbyte = 0;
142    for (i=7, j=0; i>=0; i--)
143    {
144         NICSTAR_REG_WRITE( base, NICSTAR_REG_GENERAL_PURPOSE,
145                 (val | clocktab[j++]) );
146         rbyte |= (((NICSTAR_REG_READ( base, NICSTAR_REG_GENERAL_PURPOSE)
147                         & 0x00010000) >> 16) << i);
148         NICSTAR_REG_WRITE( base, NICSTAR_REG_GENERAL_PURPOSE,
149                 (val | clocktab[j++]) );
150         osp_MicroDelay( CYCLE_DELAY );
151    }
152    NICSTAR_REG_WRITE( base, NICSTAR_REG_GENERAL_PURPOSE, 2 );
153    osp_MicroDelay( CYCLE_DELAY );
154    return rbyte;
155 }
156
157
158 /*
159  * This routine will clock the Read_data function into the X2520
160  * eeprom, followed by the address to read from, through the NicSTaR's General
161  * Purpose register.  
162  */
163  
164 static u_int8_t 
165 read_eprom_byte(u_int32_t base, u_int8_t offset)
166 {
167    u_int32_t val = 0;
168    int i,j=0;
169    u_int8_t tempread = 0;
170
171    val = NICSTAR_REG_READ( base, NICSTAR_REG_GENERAL_PURPOSE ) & 0xFFFFFFF0;
172
173    /* Send READ instruction */
174    for (i=0; i<sizeof readtab/sizeof readtab[0]; i++)
175    {
176         NICSTAR_REG_WRITE( base, NICSTAR_REG_GENERAL_PURPOSE,
177                 (val | readtab[i]) );
178         osp_MicroDelay( CYCLE_DELAY );
179    }
180
181    /* Next, we need to send the byte address to read from */
182    for (i=7; i>=0; i--)
183    {
184       NICSTAR_REG_WRITE( base, NICSTAR_REG_GENERAL_PURPOSE,
185                 (val | clocktab[j++] | ((offset >> i) & 1) ) );
186       osp_MicroDelay(CYCLE_DELAY);
187       NICSTAR_REG_WRITE( base, NICSTAR_REG_GENERAL_PURPOSE,
188                 (val | clocktab[j++] | ((offset >> i) & 1) ) );
189       osp_MicroDelay( CYCLE_DELAY );
190    }
191
192    j = 0;
193    
194    /* Now, we can read data from the eeprom by clocking it in */
195    for (i=7; i>=0; i--)
196    {
197       NICSTAR_REG_WRITE( base, NICSTAR_REG_GENERAL_PURPOSE,
198                 (val | clocktab[j++]) );
199       osp_MicroDelay( CYCLE_DELAY );
200       tempread |= (((NICSTAR_REG_READ( base, NICSTAR_REG_GENERAL_PURPOSE )
201                 & 0x00010000) >> 16) << i);
202       NICSTAR_REG_WRITE( base, NICSTAR_REG_GENERAL_PURPOSE,
203                 (val | clocktab[j++]) );
204       osp_MicroDelay( CYCLE_DELAY );
205    }
206
207    NICSTAR_REG_WRITE( base, NICSTAR_REG_GENERAL_PURPOSE, 2 );
208    osp_MicroDelay( CYCLE_DELAY );
209    return tempread;
210 }
211
212
213 void
214 nicstar_init_eprom( virt_addr_t base )
215 {
216     u_int32_t val;
217
218     /*
219      * turn chip select off
220      */
221     val = NICSTAR_REG_READ(base, NICSTAR_REG_GENERAL_PURPOSE) & 0xFFFFFFF0;
222
223     NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
224         (val | CS_HIGH | CLK_HIGH));
225     osp_MicroDelay( CYCLE_DELAY );
226
227     NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
228         (val | CS_HIGH | CLK_LOW));
229     osp_MicroDelay( CYCLE_DELAY );
230
231     NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
232         (val | CS_HIGH | CLK_HIGH));
233     osp_MicroDelay( CYCLE_DELAY );
234
235     NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
236         (val | CS_HIGH | CLK_LOW));
237     osp_MicroDelay( CYCLE_DELAY );
238 }
239
240
241 /*
242  * This routine will be the interface to the ReadPromByte function
243  * above.
244  */ 
245
246 void
247 nicstar_read_eprom(
248     virt_addr_t base,
249     u_int8_t    prom_offset,
250     u_int8_t    *buffer,
251     u_int32_t   nbytes )
252 {
253     u_int               i;
254     
255     for (i=0; i<nbytes; i++)
256     {
257         buffer[i] = read_eprom_byte( base, prom_offset );
258         ++prom_offset;
259         osp_MicroDelay( CYCLE_DELAY );
260     }
261 }
262
263
264 /*
265 void osp_MicroDelay(int x) {
266     
267 }
268 */
269