File: /usr/src/linux/arch/ppc/boot/mbx/iic.c

1     /*
2      * BK Id: SCCS/s.iic.c 1.8 05/18/01 07:54:04 patch
3      */
4     
5     /* Minimal support functions to read configuration from IIC EEPROMS
6      * on MPC8xx boards.  Originally written for RPGC RPX-Lite.
7      * Dan Malek (dmalek@jlc.net).
8      */
9     #include <linux/types.h>
10     #include <asm/uaccess.h>
11     #include <asm/mpc8xx.h>
12     #include "../../8xx_io/commproc.h"
13     
14     
15     /* IIC functions.
16      * These are just the basic master read/write operations so we can
17      * examine serial EEPROM.
18      */
19     void	iic_read(uint devaddr, u_char *buf, uint offset, uint count);
20     
21     static	int	iic_init_done;
22     
23     static void
24     iic_init()
25     {
26     	volatile iic_t *iip;
27     	volatile i2c8xx_t *i2c;
28     	volatile cpm8xx_t	*cp;
29     	volatile immap_t	*immap;
30     	uint	dpaddr;
31     
32     	immap = (immap_t *)IMAP_ADDR;
33     	cp = (cpm8xx_t *)&(immap->im_cpm);
34     
35     	/* Reset the CPM.  This is necessary on the 860 processors
36     	 * that may have started the SCC1 ethernet without relocating
37     	 * the IIC.
38     	 * This also stops the Ethernet in case we were loaded by a
39     	 * BOOTP rom monitor.
40     	 */
41     	cp->cp_cpcr = (CPM_CR_RST | CPM_CR_FLG);
42     
43     	/* Wait for it.
44     	*/
45     	while (cp->cp_cpcr & (CPM_CR_RST | CPM_CR_FLG));
46     
47     	/* Remove any microcode patches.  We will install our own
48     	 * later.
49     	 */
50     	cp->cp_cpmcr1 = 0;
51     	cp->cp_cpmcr2 = 0;
52     	cp->cp_cpmcr3 = 0;
53     	cp->cp_cpmcr4 = 0;
54     	cp->cp_rccr = 0;
55     
56     	iip = (iic_t *)&cp->cp_dparam[PROFF_IIC];
57     	i2c = (i2c8xx_t *)&(immap->im_i2c);
58     
59     	/* Initialize Port B IIC pins.
60     	*/
61     	cp->cp_pbpar |= 0x00000030;
62     	cp->cp_pbdir |= 0x00000030;
63     	cp->cp_pbodr |= 0x00000030;
64     
65     	/* Initialize the parameter ram.
66     	*/
67     
68     	/* Allocate space for a two transmit and one receive buffer
69     	 * descriptor in the DP ram.
70     	 * For now, this address seems OK, but it may have to
71     	 * change with newer versions of the firmware.
72     	 */
73     	dpaddr = 0x0840;
74     
75     	/* Set up the IIC parameters in the parameter ram.
76     	*/
77     	iip->iic_tbase = dpaddr;
78     	iip->iic_rbase = dpaddr + (2 * sizeof(cbd_t));
79     
80     	iip->iic_tfcr = SMC_EB;
81     	iip->iic_rfcr = SMC_EB;
82     
83     	/* This should really be done by the reader/writer.
84     	*/
85     	iip->iic_mrblr = 128;
86     
87     	/* Initialize Tx/Rx parameters.
88     	*/
89     	cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_I2C, CPM_CR_INIT_TRX) | CPM_CR_FLG;
90     	while (cp->cp_cpcr & CPM_CR_FLG);
91     
92     	/* Select an arbitrary address.  Just make sure it is unique.
93     	*/
94     	i2c->i2c_i2add = 0x34;
95     
96     	/* Make clock run maximum slow.
97     	*/
98     	i2c->i2c_i2brg = 7;
99     
100     	/* Disable interrupts.
101     	*/
102     	i2c->i2c_i2cmr = 0;
103     	i2c->i2c_i2cer = 0xff;
104     
105     	/* Enable SDMA.
106     	*/
107     	immap->im_siu_conf.sc_sdcr = 1;
108     
109     	iic_init_done = 1;
110     }
111     
112     /* Read from IIC.
113      * Caller provides device address, memory buffer, and byte count.
114      */
115     static	u_char	iitemp[32];
116     
117     void
118     iic_read(uint devaddr, u_char *buf, uint offset, uint count)
119     {
120     	volatile iic_t		*iip;
121     	volatile i2c8xx_t	*i2c;
122     	volatile cbd_t		*tbdf, *rbdf;
123     	volatile cpm8xx_t	*cp;
124     	volatile immap_t	*immap;
125     	u_char			*tb;
126     	uint			temp;
127     
128     	/* If the interface has not been initialized, do that now.
129     	*/
130     	if (!iic_init_done)
131     		iic_init();
132     
133     	immap = (immap_t *)IMAP_ADDR;
134     	cp = (cpm8xx_t *)&(immap->im_cpm);
135     
136     	iip = (iic_t *)&cp->cp_dparam[PROFF_IIC];
137     	i2c = (i2c8xx_t *)&(immap->im_i2c);
138     
139     	tbdf = (cbd_t *)&cp->cp_dpmem[iip->iic_tbase];
140     	rbdf = (cbd_t *)&cp->cp_dpmem[iip->iic_rbase];
141     
142     	/* Send a "dummy write" operation.  This is a write request with
143     	 * only the offset sent, followed by another start condition.
144     	 * This will ensure we start reading from the first location
145     	 * of the EEPROM.
146     	 */
147     	tb = iitemp;
148     	tb = (u_char *)(((uint)tb + 15) & ~15);
149     	tbdf->cbd_bufaddr = (int)tb;
150     	*tb = devaddr & 0xfe;	/* Device address */
151     	*(tb+1) = offset;		/* Offset */
152     	tbdf->cbd_datlen = 2;		/* Length */
153     	tbdf->cbd_sc =
154     	      BD_SC_READY | BD_SC_LAST | BD_SC_WRAP | BD_IIC_START;
155     
156     	i2c->i2c_i2mod = 1;	/* Enable */
157     	i2c->i2c_i2cer = 0xff;
158     	i2c->i2c_i2com = 0x81;	/* Start master */
159     
160     	/* Wait for IIC transfer.
161     	*/
162     #if 0
163     	while ((i2c->i2c_i2cer & 3) == 0);
164     
165     	if (tbdf->cbd_sc & BD_SC_READY)
166     		printf("IIC ra complete but tbuf ready\n");
167     #else
168     	temp = 10000000;
169     	while ((tbdf->cbd_sc & BD_SC_READY) && (temp != 0))
170     		temp--;
171     #if 0
172     	/* We can't do this...there is no serial port yet!
173     	*/
174     	if (temp == 0) {
175     		printf("Timeout reading EEPROM\n");
176     		return;
177     	}
178     #endif
179     #endif
180     	
181     	/* Chip errata, clear enable.
182     	*/
183     	i2c->i2c_i2mod = 0;
184     
185     	/* To read, we need an empty buffer of the proper length.
186     	 * All that is used is the first byte for address, the remainder
187     	 * is just used for timing (and doesn't really have to exist).
188     	 */
189     	tbdf->cbd_bufaddr = (int)tb;
190     	*tb = devaddr | 1;	/* Device address */
191     	rbdf->cbd_bufaddr = (uint)buf;		/* Desination buffer */
192     	tbdf->cbd_datlen = rbdf->cbd_datlen = count + 1;	/* Length */
193     	tbdf->cbd_sc = BD_SC_READY | BD_SC_LAST | BD_SC_WRAP | BD_IIC_START;
194     	rbdf->cbd_sc = BD_SC_EMPTY | BD_SC_WRAP;
195     
196     	/* Chip bug, set enable here.
197     	*/
198     	i2c->i2c_i2mod = 1;	/* Enable */
199     	i2c->i2c_i2cer = 0xff;
200     	i2c->i2c_i2com = 0x81;	/* Start master */
201     
202     	/* Wait for IIC transfer.
203     	*/
204     #if 0
205     	while ((i2c->i2c_i2cer & 1) == 0);
206     
207     	if (rbdf->cbd_sc & BD_SC_EMPTY)
208     		printf("IIC read complete but rbuf empty\n");
209     #else
210     	temp = 10000000;
211     	while ((tbdf->cbd_sc & BD_SC_READY) && (temp != 0))
212     		temp--;
213     #endif
214     	
215     	/* Chip errata, clear enable.
216     	*/
217     	i2c->i2c_i2mod = 0;
218     }
219