4 * Copyright (C) 2000 by Francois Wautier
5 * based on code from Bjorn Davis
7 * Read and write command for the eprom attached to
11 /* Modifications and extensions
12 * Copyright (C) 2001 By Joachim Martillo, Telford Tools, Inc.
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version
17 * 2 of the License, or (at your option) any later version.
20 /* We handle PCI devices */
21 #include <linux/pci.h>
23 /* We need to use ioremap */
26 #include <linux/delay.h>
28 /* Joachim Martillo modified this file */
29 /* so that it had no dependencies on specific */
30 /* Aurora adapter card or ESSC* structures*/
31 /* The original file use TRUE for 1 and */
32 /* FALSE for 0. This convention conflicted */
33 /* with other conventions throughout LINUX */
34 /* also TRUE was used for setting an eprom */
35 /* bit which is a slight semantic confusion. */
36 /* I just used 0 and 1 */
40 * Write a single bit to the serial EPROM interface.
43 /* eprom_ctl is the */
44 /* address of the 9050 */
45 /* eprom control register */
46 /* The original & operation */
47 /* looks wrong. I am surprised */
49 /* but I left the parentheses */
50 /* because readl, writel etc */
53 /* The following function */
54 /* assumes the proper bit */
55 /* in the serial eprom */
56 /* has already been selected*/
58 /* The 9050 registers are 32 bits */
59 /* hence the readl and writel */
60 /* macros are invoked*/
62 /* eprom_ctl must be a virtual */
65 static void plx9050_eprom_wbit(unsigned int* eprom_ctl, unsigned int val)
69 /* get the initial value of the CTRL register */
70 ctrl = readl((eprom_ctl));
72 /* set or clear the data bit */
75 ctrl |= PLX_CTRL_SEPWD;
79 ctrl &= ~PLX_CTRL_SEPWD;
82 writel(ctrl, (eprom_ctl));
86 /* Toggle the clock line */
87 /* gets to the next bit */
88 /* in the serial eprom */
89 ctrl |= PLX_CTRL_SEPCLK;
90 writel(ctrl, (eprom_ctl));
94 /* Toggle the clock line */
95 ctrl &= ~PLX_CTRL_SEPCLK;
96 writel(ctrl, (eprom_ctl));
101 * Run a serial EPROM command. Returns 1 on success,
105 /* This routine does the write of data but only sets up */
107 /* the write goes from most significant to least significant */
108 unsigned int plx9050_eprom_cmd(unsigned int* eprom_ctl, unsigned char cmd, unsigned char addr, unsigned short data)
111 unsigned char shiftb;
112 unsigned short shiftw;
118 shiftb = addr << (NM93_BITS_PER_BYTE - NM93_ADDRBITS); /* looks a bizarre way to mask out unused bits */
120 ctrl = readl((eprom_ctl));
122 ctrl &= ~(PLX_CTRL_SEPCLK | PLX_CTRL_SEPWD);
123 writel(ctrl, (eprom_ctl));
126 ctrl |= PLX_CTRL_SEPCS;
127 writel(ctrl, (eprom_ctl));
129 plx9050_eprom_wbit(eprom_ctl, 1);
132 * Clock out the command
135 plx9050_eprom_wbit(eprom_ctl, (cmd & 0x02) != 0);
136 plx9050_eprom_wbit(eprom_ctl, (cmd & 0x01) != 0);
139 * Clock out the address
143 while (i != 0) /* here we get to the correct */
144 /* short in the serial eprom*/
146 /* printf("Loop #1\n"); */
147 plx9050_eprom_wbit(eprom_ctl, (shiftb & 0x80) != 0);
153 if (cmd == NM93_WRITECMD) /* now do the write if */
154 /* a write is to be done*/
163 i = NM93_BITS_PER_WORD;
165 /* printf("Loop #2\n"); */
166 plx9050_eprom_wbit(eprom_ctl, (shiftw & 0x8000) != 0);
173 * De-assert chip select for a short period of time
175 ctrl = readl((eprom_ctl));
177 ctrl &= ~PLX_CTRL_SEPCS;
178 writel(ctrl, (eprom_ctl));
182 * Re-assert chip select
184 ctrl |= PLX_CTRL_SEPCS;
185 writel(ctrl, (eprom_ctl));
188 * Wait for a low to high transition of DO
192 ctrl = readl((eprom_ctl));
193 l = (ctrl & PLX_CTRL_SEPRD);
197 /* printf("Loop #3\n"); */
198 ctrl = readl((eprom_ctl));
199 v = (ctrl & PLX_CTRL_SEPRD);
200 if (v != 0 && l == 0)
211 printk("plx9050: eprom didn't go low to high");
216 if (cmd != NM93_READCMD) /* not a read -- terminate */
219 * De-assert the chip select.
222 ctrl = readl((eprom_ctl));
223 ctrl &= ~PLX_CTRL_SEPCS;
224 writel(ctrl,(eprom_ctl));
226 /* otherwise left in read state */
231 * Read the serial EPROM. Returns 1 on success, 0 on failure.
232 * reads in shorts (i.e., 16 bits at a time.)
237 plx9050_eprom_read(unsigned int* eprom_ctl, unsigned short *ptr, unsigned char addr, unsigned short len)
239 unsigned short shiftw;
243 if (!plx9050_eprom_cmd(eprom_ctl, NM93_READCMD, addr, (unsigned short) 0x0)) /* set up read */
248 ctrl = readl((eprom_ctl)); /* synchronize */
250 while (len-- > 0) /* now read one word at a time */
254 ctrl &= ~PLX_CTRL_SEPCLK;
255 writel(ctrl, (eprom_ctl));
259 i = NM93_BITS_PER_WORD;
260 while (1) /* now read one bit at a time, */
261 /* left shifting each bit */
263 ctrl |= PLX_CTRL_SEPCLK;
264 writel(ctrl, (eprom_ctl));
268 ctrl = readl((eprom_ctl));
271 if ((ctrl & PLX_CTRL_SEPRD) != 0)
283 ctrl &= ~PLX_CTRL_SEPCLK;
284 writel(ctrl, (eprom_ctl));
291 ctrl &= ~PLX_CTRL_SEPCS;
292 writel(ctrl, (eprom_ctl));
295 ctrl &= ~PLX_CTRL_SEPCLK;
296 writel(ctrl, (eprom_ctl));