Blame view

drivers/atm/nicstarmac.c 5.96 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
  /*
   * this file included by nicstar.c
   */
  
  /*
   * nicstarmac.c
   * Read this ForeRunner's MAC address from eprom/eeprom
   */
36fe55d6a   Ahmed S. Darwish   atm: Use ARRAY_SI...
9
  #include <linux/kernel.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
10
11
12
  typedef void __iomem *virt_addr_t;
  
  #define CYCLE_DELAY 5
098fde114   chas williams - CONTRACTOR   atm: [nicstar] re...
13
14
  /*
     This was the original definition
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
15
16
17
18
19
  #define osp_MicroDelay(microsec) \
      do { int _i = 4*microsec; while (--_i > 0) { __SLOW_DOWN_IO; }} while (0)
  */
  #define osp_MicroDelay(microsec) {unsigned long useconds = (microsec); \
                                    udelay((useconds));}
098fde114   chas williams - CONTRACTOR   atm: [nicstar] re...
20
21
  /*
   * The following tables represent the timing diagrams found in
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
22
23
24
25
26
27
28
29
   * the Data Sheet for the Xicor X25020 EEProm.  The #defines below
   * represent the bits in the NICStAR's General Purpose register
   * that must be toggled for the corresponding actions on the EEProm
   * to occur.
   */
  
  /* Write Data To EEProm from SI line on rising edge of CLK */
  /* Read Data From EEProm on falling edge of CLK */
098fde114   chas williams - CONTRACTOR   atm: [nicstar] re...
30
31
32
33
34
35
  #define CS_HIGH		0x0002	/* Chip select high */
  #define CS_LOW		0x0000	/* Chip select low (active low) */
  #define CLK_HIGH	0x0004	/* Clock high */
  #define CLK_LOW		0x0000	/* Clock low  */
  #define SI_HIGH		0x0001	/* Serial input data high */
  #define SI_LOW		0x0000	/* Serial input data low */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
36
37
38
  
  /* Read Status Register = 0000 0101b */
  #if 0
098fde114   chas williams - CONTRACTOR   atm: [nicstar] re...
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
  static u_int32_t rdsrtab[] = {
  	CS_HIGH | CLK_HIGH,
  	CS_LOW | CLK_LOW,
  	CLK_HIGH,		/* 0 */
  	CLK_LOW,
  	CLK_HIGH,		/* 0 */
  	CLK_LOW,
  	CLK_HIGH,		/* 0 */
  	CLK_LOW,
  	CLK_HIGH,		/* 0 */
  	CLK_LOW,
  	CLK_HIGH,		/* 0 */
  	CLK_LOW | SI_HIGH,
  	CLK_HIGH | SI_HIGH,	/* 1 */
  	CLK_LOW | SI_LOW,
  	CLK_HIGH,		/* 0 */
  	CLK_LOW | SI_HIGH,
  	CLK_HIGH | SI_HIGH	/* 1 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
57
  };
098fde114   chas williams - CONTRACTOR   atm: [nicstar] re...
58
  #endif /*  0  */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
59
60
  
  /* Read from EEPROM = 0000 0011b */
098fde114   chas williams - CONTRACTOR   atm: [nicstar] re...
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
  static u_int32_t readtab[] = {
  	/*
  	   CS_HIGH | CLK_HIGH,
  	 */
  	CS_LOW | CLK_LOW,
  	CLK_HIGH,		/* 0 */
  	CLK_LOW,
  	CLK_HIGH,		/* 0 */
  	CLK_LOW,
  	CLK_HIGH,		/* 0 */
  	CLK_LOW,
  	CLK_HIGH,		/* 0 */
  	CLK_LOW,
  	CLK_HIGH,		/* 0 */
  	CLK_LOW,
  	CLK_HIGH,		/* 0 */
  	CLK_LOW | SI_HIGH,
  	CLK_HIGH | SI_HIGH,	/* 1 */
  	CLK_LOW | SI_HIGH,
  	CLK_HIGH | SI_HIGH	/* 1 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
81
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
82
  /* Clock to read from/write to the eeprom */
098fde114   chas williams - CONTRACTOR   atm: [nicstar] re...
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
  static u_int32_t clocktab[] = {
  	CLK_LOW,
  	CLK_HIGH,
  	CLK_LOW,
  	CLK_HIGH,
  	CLK_LOW,
  	CLK_HIGH,
  	CLK_LOW,
  	CLK_HIGH,
  	CLK_LOW,
  	CLK_HIGH,
  	CLK_LOW,
  	CLK_HIGH,
  	CLK_LOW,
  	CLK_HIGH,
  	CLK_LOW,
  	CLK_HIGH,
  	CLK_LOW
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
101
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
102
103
104
105
106
107
108
109
110
111
112
113
114
  #define NICSTAR_REG_WRITE(bs, reg, val) \
  	while ( readl(bs + STAT) & 0x0200 ) ; \
  	writel((val),(base)+(reg))
  #define NICSTAR_REG_READ(bs, reg) \
  	readl((base)+(reg))
  #define NICSTAR_REG_GENERAL_PURPOSE GP
  
  /*
   * This routine will clock the Read_Status_reg function into the X2520
   * eeprom, then pull the result from bit 16 of the NicSTaR's General Purpose 
   * register.  
   */
  #if 0
098fde114   chas williams - CONTRACTOR   atm: [nicstar] re...
115
  u_int32_t nicstar_read_eprom_status(virt_addr_t base)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
116
  {
098fde114   chas williams - CONTRACTOR   atm: [nicstar] re...
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
  	u_int32_t val;
  	u_int32_t rbyte;
  	int32_t i, j;
  
  	/* Send read instruction */
  	val = NICSTAR_REG_READ(base, NICSTAR_REG_GENERAL_PURPOSE) & 0xFFFFFFF0;
  
  	for (i = 0; i < ARRAY_SIZE(rdsrtab); i++) {
  		NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
  				  (val | rdsrtab[i]));
  		osp_MicroDelay(CYCLE_DELAY);
  	}
  
  	/* Done sending instruction - now pull data off of bit 16, MSB first */
  	/* Data clocked out of eeprom on falling edge of clock */
  
  	rbyte = 0;
  	for (i = 7, j = 0; i >= 0; i--) {
  		NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
  				  (val | clocktab[j++]));
  		rbyte |= (((NICSTAR_REG_READ(base, NICSTAR_REG_GENERAL_PURPOSE)
  			    & 0x00010000) >> 16) << i);
  		NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
  				  (val | clocktab[j++]));
  		osp_MicroDelay(CYCLE_DELAY);
  	}
  	NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE, 2);
  	osp_MicroDelay(CYCLE_DELAY);
  	return rbyte;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
146
  }
098fde114   chas williams - CONTRACTOR   atm: [nicstar] re...
147
  #endif /*  0  */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
148
149
150
151
152
153
  
  /*
   * This routine will clock the Read_data function into the X2520
   * eeprom, followed by the address to read from, through the NicSTaR's General
   * Purpose register.  
   */
098fde114   chas williams - CONTRACTOR   atm: [nicstar] re...
154
155
  
  static u_int8_t read_eprom_byte(virt_addr_t base, u_int8_t offset)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
156
  {
098fde114   chas williams - CONTRACTOR   atm: [nicstar] re...
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
  	u_int32_t val = 0;
  	int i, j = 0;
  	u_int8_t tempread = 0;
  
  	val = NICSTAR_REG_READ(base, NICSTAR_REG_GENERAL_PURPOSE) & 0xFFFFFFF0;
  
  	/* Send READ instruction */
  	for (i = 0; i < ARRAY_SIZE(readtab); i++) {
  		NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
  				  (val | readtab[i]));
  		osp_MicroDelay(CYCLE_DELAY);
  	}
  
  	/* Next, we need to send the byte address to read from */
  	for (i = 7; i >= 0; i--) {
  		NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
  				  (val | clocktab[j++] | ((offset >> i) & 1)));
  		osp_MicroDelay(CYCLE_DELAY);
  		NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
  				  (val | clocktab[j++] | ((offset >> i) & 1)));
  		osp_MicroDelay(CYCLE_DELAY);
  	}
  
  	j = 0;
  
  	/* Now, we can read data from the eeprom by clocking it in */
  	for (i = 7; i >= 0; i--) {
  		NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
  				  (val | clocktab[j++]));
  		osp_MicroDelay(CYCLE_DELAY);
  		tempread |=
  		    (((NICSTAR_REG_READ(base, NICSTAR_REG_GENERAL_PURPOSE)
  		       & 0x00010000) >> 16) << i);
  		NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
  				  (val | clocktab[j++]));
  		osp_MicroDelay(CYCLE_DELAY);
  	}
  
  	NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE, 2);
  	osp_MicroDelay(CYCLE_DELAY);
  	return tempread;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
198
  }
098fde114   chas williams - CONTRACTOR   atm: [nicstar] re...
199
  static void nicstar_init_eprom(virt_addr_t base)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
200
  {
098fde114   chas williams - CONTRACTOR   atm: [nicstar] re...
201
  	u_int32_t val;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
202

098fde114   chas williams - CONTRACTOR   atm: [nicstar] re...
203
204
205
206
  	/*
  	 * turn chip select off
  	 */
  	val = NICSTAR_REG_READ(base, NICSTAR_REG_GENERAL_PURPOSE) & 0xFFFFFFF0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
207

098fde114   chas williams - CONTRACTOR   atm: [nicstar] re...
208
209
210
  	NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
  			  (val | CS_HIGH | CLK_HIGH));
  	osp_MicroDelay(CYCLE_DELAY);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
211

098fde114   chas williams - CONTRACTOR   atm: [nicstar] re...
212
213
214
  	NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
  			  (val | CS_HIGH | CLK_LOW));
  	osp_MicroDelay(CYCLE_DELAY);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
215

098fde114   chas williams - CONTRACTOR   atm: [nicstar] re...
216
217
218
  	NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
  			  (val | CS_HIGH | CLK_HIGH));
  	osp_MicroDelay(CYCLE_DELAY);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
219

098fde114   chas williams - CONTRACTOR   atm: [nicstar] re...
220
221
222
  	NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
  			  (val | CS_HIGH | CLK_LOW));
  	osp_MicroDelay(CYCLE_DELAY);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
223
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
224
225
226
  /*
   * This routine will be the interface to the ReadPromByte function
   * above.
098fde114   chas williams - CONTRACTOR   atm: [nicstar] re...
227
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
228
229
  
  static void
098fde114   chas williams - CONTRACTOR   atm: [nicstar] re...
230
231
  nicstar_read_eprom(virt_addr_t base,
  		   u_int8_t prom_offset, u_int8_t * buffer, u_int32_t nbytes)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
232
  {
098fde114   chas williams - CONTRACTOR   atm: [nicstar] re...
233
  	u_int i;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
234

098fde114   chas williams - CONTRACTOR   atm: [nicstar] re...
235
236
237
238
239
  	for (i = 0; i < nbytes; i++) {
  		buffer[i] = read_eprom_byte(base, prom_offset);
  		++prom_offset;
  		osp_MicroDelay(CYCLE_DELAY);
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
240
  }