Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
nicstarmac.c
Go to the documentation of this file.
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 #include <linux/kernel.h>
11 
12 typedef void __iomem *virt_addr_t;
13 
14 #define CYCLE_DELAY 5
15 
16 /*
17  This was the original definition
18 #define osp_MicroDelay(microsec) \
19  do { int _i = 4*microsec; while (--_i > 0) { __SLOW_DOWN_IO; }} while (0)
20 */
21 #define osp_MicroDelay(microsec) {unsigned long useconds = (microsec); \
22  udelay((useconds));}
23 /*
24  * The following tables represent the timing diagrams found in
25  * the Data Sheet for the Xicor X25020 EEProm. The #defines below
26  * represent the bits in the NICStAR's General Purpose register
27  * that must be toggled for the corresponding actions on the EEProm
28  * to occur.
29  */
30 
31 /* Write Data To EEProm from SI line on rising edge of CLK */
32 /* Read Data From EEProm on falling edge of CLK */
33 
34 #define CS_HIGH 0x0002 /* Chip select high */
35 #define CS_LOW 0x0000 /* Chip select low (active low) */
36 #define CLK_HIGH 0x0004 /* Clock high */
37 #define CLK_LOW 0x0000 /* Clock low */
38 #define SI_HIGH 0x0001 /* Serial input data high */
39 #define SI_LOW 0x0000 /* Serial input data low */
40 
41 /* Read Status Register = 0000 0101b */
42 #if 0
43 static u_int32_t rdsrtab[] = {
44  CS_HIGH | CLK_HIGH,
45  CS_LOW | CLK_LOW,
46  CLK_HIGH, /* 0 */
47  CLK_LOW,
48  CLK_HIGH, /* 0 */
49  CLK_LOW,
50  CLK_HIGH, /* 0 */
51  CLK_LOW,
52  CLK_HIGH, /* 0 */
53  CLK_LOW,
54  CLK_HIGH, /* 0 */
55  CLK_LOW | SI_HIGH,
56  CLK_HIGH | SI_HIGH, /* 1 */
57  CLK_LOW | SI_LOW,
58  CLK_HIGH, /* 0 */
59  CLK_LOW | SI_HIGH,
60  CLK_HIGH | SI_HIGH /* 1 */
61 };
62 #endif /* 0 */
63 
64 /* Read from EEPROM = 0000 0011b */
65 static u_int32_t readtab[] = {
66  /*
67  CS_HIGH | CLK_HIGH,
68  */
69  CS_LOW | CLK_LOW,
70  CLK_HIGH, /* 0 */
71  CLK_LOW,
72  CLK_HIGH, /* 0 */
73  CLK_LOW,
74  CLK_HIGH, /* 0 */
75  CLK_LOW,
76  CLK_HIGH, /* 0 */
77  CLK_LOW,
78  CLK_HIGH, /* 0 */
79  CLK_LOW,
80  CLK_HIGH, /* 0 */
81  CLK_LOW | SI_HIGH,
82  CLK_HIGH | SI_HIGH, /* 1 */
83  CLK_LOW | SI_HIGH,
84  CLK_HIGH | SI_HIGH /* 1 */
85 };
86 
87 /* Clock to read from/write to the eeprom */
88 static u_int32_t clocktab[] = {
89  CLK_LOW,
90  CLK_HIGH,
91  CLK_LOW,
92  CLK_HIGH,
93  CLK_LOW,
94  CLK_HIGH,
95  CLK_LOW,
96  CLK_HIGH,
97  CLK_LOW,
98  CLK_HIGH,
99  CLK_LOW,
100  CLK_HIGH,
101  CLK_LOW,
102  CLK_HIGH,
103  CLK_LOW,
104  CLK_HIGH,
105  CLK_LOW
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 #if 0
121 u_int32_t nicstar_read_eprom_status(virt_addr_t base)
122 {
123  u_int32_t val;
124  u_int32_t rbyte;
125  int32_t i, j;
126 
127  /* Send read instruction */
128  val = NICSTAR_REG_READ(base, NICSTAR_REG_GENERAL_PURPOSE) & 0xFFFFFFF0;
129 
130  for (i = 0; i < ARRAY_SIZE(rdsrtab); i++) {
132  (val | rdsrtab[i]));
134  }
135 
136  /* Done sending instruction - now pull data off of bit 16, MSB first */
137  /* Data clocked out of eeprom on falling edge of clock */
138 
139  rbyte = 0;
140  for (i = 7, j = 0; i >= 0; i--) {
142  (val | clocktab[j++]));
144  & 0x00010000) >> 16) << i);
146  (val | clocktab[j++]));
148  }
151  return rbyte;
152 }
153 #endif /* 0 */
154 
155 /*
156  * This routine will clock the Read_data function into the X2520
157  * eeprom, followed by the address to read from, through the NicSTaR's General
158  * Purpose register.
159  */
160 
161 static u_int8_t read_eprom_byte(virt_addr_t base, u_int8_t offset)
162 {
163  u_int32_t val = 0;
164  int i, j = 0;
165  u_int8_t tempread = 0;
166 
167  val = NICSTAR_REG_READ(base, NICSTAR_REG_GENERAL_PURPOSE) & 0xFFFFFFF0;
168 
169  /* Send READ instruction */
170  for (i = 0; i < ARRAY_SIZE(readtab); i++) {
172  (val | readtab[i]));
174  }
175 
176  /* Next, we need to send the byte address to read from */
177  for (i = 7; i >= 0; i--) {
179  (val | clocktab[j++] | ((offset >> i) & 1)));
182  (val | clocktab[j++] | ((offset >> i) & 1)));
184  }
185 
186  j = 0;
187 
188  /* Now, we can read data from the eeprom by clocking it in */
189  for (i = 7; i >= 0; i--) {
191  (val | clocktab[j++]));
193  tempread |=
195  & 0x00010000) >> 16) << i);
197  (val | clocktab[j++]));
199  }
200 
203  return tempread;
204 }
205 
206 static void nicstar_init_eprom(virt_addr_t base)
207 {
208  u_int32_t val;
209 
210  /*
211  * turn chip select off
212  */
213  val = NICSTAR_REG_READ(base, NICSTAR_REG_GENERAL_PURPOSE) & 0xFFFFFFF0;
214 
216  (val | CS_HIGH | CLK_HIGH));
218 
220  (val | CS_HIGH | CLK_LOW));
222 
224  (val | CS_HIGH | CLK_HIGH));
226 
228  (val | CS_HIGH | CLK_LOW));
230 }
231 
232 /*
233  * This routine will be the interface to the ReadPromByte function
234  * above.
235  */
236 
237 static void
238 nicstar_read_eprom(virt_addr_t base,
239  u_int8_t prom_offset, u_int8_t * buffer, u_int32_t nbytes)
240 {
241  u_int i;
242 
243  for (i = 0; i < nbytes; i++) {
244  buffer[i] = read_eprom_byte(base, prom_offset);
245  ++prom_offset;
247  }
248 }