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