xref: /openbmc/u-boot/drivers/i2c/fsl_i2c.c (revision 080c646dbf474a109c3f85718fb01ce042a38c45)
1*080c646dSJean-Christophe PLAGNIOL-VILLARD /*
2*080c646dSJean-Christophe PLAGNIOL-VILLARD  * Copyright 2006 Freescale Semiconductor, Inc.
3*080c646dSJean-Christophe PLAGNIOL-VILLARD  *
4*080c646dSJean-Christophe PLAGNIOL-VILLARD  * This program is free software; you can redistribute it and/or
5*080c646dSJean-Christophe PLAGNIOL-VILLARD  * modify it under the terms of the GNU General Public License
6*080c646dSJean-Christophe PLAGNIOL-VILLARD  * Version 2 as published by the Free Software Foundation.
7*080c646dSJean-Christophe PLAGNIOL-VILLARD  *
8*080c646dSJean-Christophe PLAGNIOL-VILLARD  * This program is distributed in the hope that it will be useful,
9*080c646dSJean-Christophe PLAGNIOL-VILLARD  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10*080c646dSJean-Christophe PLAGNIOL-VILLARD  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11*080c646dSJean-Christophe PLAGNIOL-VILLARD  * GNU General Public License for more details.
12*080c646dSJean-Christophe PLAGNIOL-VILLARD  *
13*080c646dSJean-Christophe PLAGNIOL-VILLARD  * You should have received a copy of the GNU General Public License
14*080c646dSJean-Christophe PLAGNIOL-VILLARD  * along with this program; if not, write to the Free Software
15*080c646dSJean-Christophe PLAGNIOL-VILLARD  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
16*080c646dSJean-Christophe PLAGNIOL-VILLARD  * MA 02111-1307 USA
17*080c646dSJean-Christophe PLAGNIOL-VILLARD  */
18*080c646dSJean-Christophe PLAGNIOL-VILLARD 
19*080c646dSJean-Christophe PLAGNIOL-VILLARD #include <common.h>
20*080c646dSJean-Christophe PLAGNIOL-VILLARD 
21*080c646dSJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_FSL_I2C
22*080c646dSJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_HARD_I2C
23*080c646dSJean-Christophe PLAGNIOL-VILLARD 
24*080c646dSJean-Christophe PLAGNIOL-VILLARD #include <command.h>
25*080c646dSJean-Christophe PLAGNIOL-VILLARD #include <i2c.h>		/* Functional interface */
26*080c646dSJean-Christophe PLAGNIOL-VILLARD 
27*080c646dSJean-Christophe PLAGNIOL-VILLARD #include <asm/io.h>
28*080c646dSJean-Christophe PLAGNIOL-VILLARD #include <asm/fsl_i2c.h>	/* HW definitions */
29*080c646dSJean-Christophe PLAGNIOL-VILLARD 
30*080c646dSJean-Christophe PLAGNIOL-VILLARD #define I2C_TIMEOUT	(CFG_HZ / 4)
31*080c646dSJean-Christophe PLAGNIOL-VILLARD 
32*080c646dSJean-Christophe PLAGNIOL-VILLARD #define I2C_READ_BIT  1
33*080c646dSJean-Christophe PLAGNIOL-VILLARD #define I2C_WRITE_BIT 0
34*080c646dSJean-Christophe PLAGNIOL-VILLARD 
35*080c646dSJean-Christophe PLAGNIOL-VILLARD /* Initialize the bus pointer to whatever one the SPD EEPROM is on.
36*080c646dSJean-Christophe PLAGNIOL-VILLARD  * Default is bus 0.  This is necessary because the DDR initialization
37*080c646dSJean-Christophe PLAGNIOL-VILLARD  * runs from ROM, and we can't switch buses because we can't modify
38*080c646dSJean-Christophe PLAGNIOL-VILLARD  * the global variables.
39*080c646dSJean-Christophe PLAGNIOL-VILLARD  */
40*080c646dSJean-Christophe PLAGNIOL-VILLARD #ifdef CFG_SPD_BUS_NUM
41*080c646dSJean-Christophe PLAGNIOL-VILLARD static unsigned int i2c_bus_num __attribute__ ((section ("data"))) = CFG_SPD_BUS_NUM;
42*080c646dSJean-Christophe PLAGNIOL-VILLARD #else
43*080c646dSJean-Christophe PLAGNIOL-VILLARD static unsigned int i2c_bus_num __attribute__ ((section ("data"))) = 0;
44*080c646dSJean-Christophe PLAGNIOL-VILLARD #endif
45*080c646dSJean-Christophe PLAGNIOL-VILLARD 
46*080c646dSJean-Christophe PLAGNIOL-VILLARD static volatile struct fsl_i2c *i2c_dev[2] = {
47*080c646dSJean-Christophe PLAGNIOL-VILLARD 	(struct fsl_i2c *) (CFG_IMMR + CFG_I2C_OFFSET),
48*080c646dSJean-Christophe PLAGNIOL-VILLARD #ifdef CFG_I2C2_OFFSET
49*080c646dSJean-Christophe PLAGNIOL-VILLARD 	(struct fsl_i2c *) (CFG_IMMR + CFG_I2C2_OFFSET)
50*080c646dSJean-Christophe PLAGNIOL-VILLARD #endif
51*080c646dSJean-Christophe PLAGNIOL-VILLARD };
52*080c646dSJean-Christophe PLAGNIOL-VILLARD 
53*080c646dSJean-Christophe PLAGNIOL-VILLARD void
54*080c646dSJean-Christophe PLAGNIOL-VILLARD i2c_init(int speed, int slaveadd)
55*080c646dSJean-Christophe PLAGNIOL-VILLARD {
56*080c646dSJean-Christophe PLAGNIOL-VILLARD 	volatile struct fsl_i2c *dev;
57*080c646dSJean-Christophe PLAGNIOL-VILLARD 
58*080c646dSJean-Christophe PLAGNIOL-VILLARD 	dev = (struct fsl_i2c *) (CFG_IMMR + CFG_I2C_OFFSET);
59*080c646dSJean-Christophe PLAGNIOL-VILLARD 
60*080c646dSJean-Christophe PLAGNIOL-VILLARD 	writeb(0, &dev->cr);			/* stop I2C controller */
61*080c646dSJean-Christophe PLAGNIOL-VILLARD 	udelay(5);				/* let it shutdown in peace */
62*080c646dSJean-Christophe PLAGNIOL-VILLARD 	writeb(0x3F, &dev->fdr);		/* set bus speed */
63*080c646dSJean-Christophe PLAGNIOL-VILLARD 	writeb(0x3F, &dev->dfsrr);		/* set default filter */
64*080c646dSJean-Christophe PLAGNIOL-VILLARD 	writeb(slaveadd << 1, &dev->adr);	/* write slave address */
65*080c646dSJean-Christophe PLAGNIOL-VILLARD 	writeb(0x0, &dev->sr);			/* clear status register */
66*080c646dSJean-Christophe PLAGNIOL-VILLARD 	writeb(I2C_CR_MEN, &dev->cr);		/* start I2C controller */
67*080c646dSJean-Christophe PLAGNIOL-VILLARD 
68*080c646dSJean-Christophe PLAGNIOL-VILLARD #ifdef	CFG_I2C2_OFFSET
69*080c646dSJean-Christophe PLAGNIOL-VILLARD 	dev = (struct fsl_i2c *) (CFG_IMMR + CFG_I2C2_OFFSET);
70*080c646dSJean-Christophe PLAGNIOL-VILLARD 
71*080c646dSJean-Christophe PLAGNIOL-VILLARD 	writeb(0, &dev->cr);			/* stop I2C controller */
72*080c646dSJean-Christophe PLAGNIOL-VILLARD 	udelay(5);				/* let it shutdown in peace */
73*080c646dSJean-Christophe PLAGNIOL-VILLARD 	writeb(0x3F, &dev->fdr);		/* set bus speed */
74*080c646dSJean-Christophe PLAGNIOL-VILLARD 	writeb(0x3F, &dev->dfsrr);		/* set default filter */
75*080c646dSJean-Christophe PLAGNIOL-VILLARD 	writeb(slaveadd << 1, &dev->adr);	/* write slave address */
76*080c646dSJean-Christophe PLAGNIOL-VILLARD 	writeb(0x0, &dev->sr);			/* clear status register */
77*080c646dSJean-Christophe PLAGNIOL-VILLARD 	writeb(I2C_CR_MEN, &dev->cr);		/* start I2C controller */
78*080c646dSJean-Christophe PLAGNIOL-VILLARD #endif	/* CFG_I2C2_OFFSET */
79*080c646dSJean-Christophe PLAGNIOL-VILLARD }
80*080c646dSJean-Christophe PLAGNIOL-VILLARD 
81*080c646dSJean-Christophe PLAGNIOL-VILLARD static __inline__ int
82*080c646dSJean-Christophe PLAGNIOL-VILLARD i2c_wait4bus(void)
83*080c646dSJean-Christophe PLAGNIOL-VILLARD {
84*080c646dSJean-Christophe PLAGNIOL-VILLARD 	ulong timeval = get_timer(0);
85*080c646dSJean-Christophe PLAGNIOL-VILLARD 
86*080c646dSJean-Christophe PLAGNIOL-VILLARD 	while (readb(&i2c_dev[i2c_bus_num]->sr) & I2C_SR_MBB) {
87*080c646dSJean-Christophe PLAGNIOL-VILLARD 		if (get_timer(timeval) > I2C_TIMEOUT) {
88*080c646dSJean-Christophe PLAGNIOL-VILLARD 			return -1;
89*080c646dSJean-Christophe PLAGNIOL-VILLARD 		}
90*080c646dSJean-Christophe PLAGNIOL-VILLARD 	}
91*080c646dSJean-Christophe PLAGNIOL-VILLARD 
92*080c646dSJean-Christophe PLAGNIOL-VILLARD 	return 0;
93*080c646dSJean-Christophe PLAGNIOL-VILLARD }
94*080c646dSJean-Christophe PLAGNIOL-VILLARD 
95*080c646dSJean-Christophe PLAGNIOL-VILLARD static __inline__ int
96*080c646dSJean-Christophe PLAGNIOL-VILLARD i2c_wait(int write)
97*080c646dSJean-Christophe PLAGNIOL-VILLARD {
98*080c646dSJean-Christophe PLAGNIOL-VILLARD 	u32 csr;
99*080c646dSJean-Christophe PLAGNIOL-VILLARD 	ulong timeval = get_timer(0);
100*080c646dSJean-Christophe PLAGNIOL-VILLARD 
101*080c646dSJean-Christophe PLAGNIOL-VILLARD 	do {
102*080c646dSJean-Christophe PLAGNIOL-VILLARD 		csr = readb(&i2c_dev[i2c_bus_num]->sr);
103*080c646dSJean-Christophe PLAGNIOL-VILLARD 		if (!(csr & I2C_SR_MIF))
104*080c646dSJean-Christophe PLAGNIOL-VILLARD 			continue;
105*080c646dSJean-Christophe PLAGNIOL-VILLARD 
106*080c646dSJean-Christophe PLAGNIOL-VILLARD 		writeb(0x0, &i2c_dev[i2c_bus_num]->sr);
107*080c646dSJean-Christophe PLAGNIOL-VILLARD 
108*080c646dSJean-Christophe PLAGNIOL-VILLARD 		if (csr & I2C_SR_MAL) {
109*080c646dSJean-Christophe PLAGNIOL-VILLARD 			debug("i2c_wait: MAL\n");
110*080c646dSJean-Christophe PLAGNIOL-VILLARD 			return -1;
111*080c646dSJean-Christophe PLAGNIOL-VILLARD 		}
112*080c646dSJean-Christophe PLAGNIOL-VILLARD 
113*080c646dSJean-Christophe PLAGNIOL-VILLARD 		if (!(csr & I2C_SR_MCF))	{
114*080c646dSJean-Christophe PLAGNIOL-VILLARD 			debug("i2c_wait: unfinished\n");
115*080c646dSJean-Christophe PLAGNIOL-VILLARD 			return -1;
116*080c646dSJean-Christophe PLAGNIOL-VILLARD 		}
117*080c646dSJean-Christophe PLAGNIOL-VILLARD 
118*080c646dSJean-Christophe PLAGNIOL-VILLARD 		if (write == I2C_WRITE_BIT && (csr & I2C_SR_RXAK)) {
119*080c646dSJean-Christophe PLAGNIOL-VILLARD 			debug("i2c_wait: No RXACK\n");
120*080c646dSJean-Christophe PLAGNIOL-VILLARD 			return -1;
121*080c646dSJean-Christophe PLAGNIOL-VILLARD 		}
122*080c646dSJean-Christophe PLAGNIOL-VILLARD 
123*080c646dSJean-Christophe PLAGNIOL-VILLARD 		return 0;
124*080c646dSJean-Christophe PLAGNIOL-VILLARD 	} while (get_timer (timeval) < I2C_TIMEOUT);
125*080c646dSJean-Christophe PLAGNIOL-VILLARD 
126*080c646dSJean-Christophe PLAGNIOL-VILLARD 	debug("i2c_wait: timed out\n");
127*080c646dSJean-Christophe PLAGNIOL-VILLARD 	return -1;
128*080c646dSJean-Christophe PLAGNIOL-VILLARD }
129*080c646dSJean-Christophe PLAGNIOL-VILLARD 
130*080c646dSJean-Christophe PLAGNIOL-VILLARD static __inline__ int
131*080c646dSJean-Christophe PLAGNIOL-VILLARD i2c_write_addr (u8 dev, u8 dir, int rsta)
132*080c646dSJean-Christophe PLAGNIOL-VILLARD {
133*080c646dSJean-Christophe PLAGNIOL-VILLARD 	writeb(I2C_CR_MEN | I2C_CR_MSTA | I2C_CR_MTX
134*080c646dSJean-Christophe PLAGNIOL-VILLARD 	       | (rsta ? I2C_CR_RSTA : 0),
135*080c646dSJean-Christophe PLAGNIOL-VILLARD 	       &i2c_dev[i2c_bus_num]->cr);
136*080c646dSJean-Christophe PLAGNIOL-VILLARD 
137*080c646dSJean-Christophe PLAGNIOL-VILLARD 	writeb((dev << 1) | dir, &i2c_dev[i2c_bus_num]->dr);
138*080c646dSJean-Christophe PLAGNIOL-VILLARD 
139*080c646dSJean-Christophe PLAGNIOL-VILLARD 	if (i2c_wait(I2C_WRITE_BIT) < 0)
140*080c646dSJean-Christophe PLAGNIOL-VILLARD 		return 0;
141*080c646dSJean-Christophe PLAGNIOL-VILLARD 
142*080c646dSJean-Christophe PLAGNIOL-VILLARD 	return 1;
143*080c646dSJean-Christophe PLAGNIOL-VILLARD }
144*080c646dSJean-Christophe PLAGNIOL-VILLARD 
145*080c646dSJean-Christophe PLAGNIOL-VILLARD static __inline__ int
146*080c646dSJean-Christophe PLAGNIOL-VILLARD __i2c_write(u8 *data, int length)
147*080c646dSJean-Christophe PLAGNIOL-VILLARD {
148*080c646dSJean-Christophe PLAGNIOL-VILLARD 	int i;
149*080c646dSJean-Christophe PLAGNIOL-VILLARD 
150*080c646dSJean-Christophe PLAGNIOL-VILLARD 	writeb(I2C_CR_MEN | I2C_CR_MSTA | I2C_CR_MTX,
151*080c646dSJean-Christophe PLAGNIOL-VILLARD 	       &i2c_dev[i2c_bus_num]->cr);
152*080c646dSJean-Christophe PLAGNIOL-VILLARD 
153*080c646dSJean-Christophe PLAGNIOL-VILLARD 	for (i = 0; i < length; i++) {
154*080c646dSJean-Christophe PLAGNIOL-VILLARD 		writeb(data[i], &i2c_dev[i2c_bus_num]->dr);
155*080c646dSJean-Christophe PLAGNIOL-VILLARD 
156*080c646dSJean-Christophe PLAGNIOL-VILLARD 		if (i2c_wait(I2C_WRITE_BIT) < 0)
157*080c646dSJean-Christophe PLAGNIOL-VILLARD 			break;
158*080c646dSJean-Christophe PLAGNIOL-VILLARD 	}
159*080c646dSJean-Christophe PLAGNIOL-VILLARD 
160*080c646dSJean-Christophe PLAGNIOL-VILLARD 	return i;
161*080c646dSJean-Christophe PLAGNIOL-VILLARD }
162*080c646dSJean-Christophe PLAGNIOL-VILLARD 
163*080c646dSJean-Christophe PLAGNIOL-VILLARD static __inline__ int
164*080c646dSJean-Christophe PLAGNIOL-VILLARD __i2c_read(u8 *data, int length)
165*080c646dSJean-Christophe PLAGNIOL-VILLARD {
166*080c646dSJean-Christophe PLAGNIOL-VILLARD 	int i;
167*080c646dSJean-Christophe PLAGNIOL-VILLARD 
168*080c646dSJean-Christophe PLAGNIOL-VILLARD 	writeb(I2C_CR_MEN | I2C_CR_MSTA | ((length == 1) ? I2C_CR_TXAK : 0),
169*080c646dSJean-Christophe PLAGNIOL-VILLARD 	       &i2c_dev[i2c_bus_num]->cr);
170*080c646dSJean-Christophe PLAGNIOL-VILLARD 
171*080c646dSJean-Christophe PLAGNIOL-VILLARD 	/* dummy read */
172*080c646dSJean-Christophe PLAGNIOL-VILLARD 	readb(&i2c_dev[i2c_bus_num]->dr);
173*080c646dSJean-Christophe PLAGNIOL-VILLARD 
174*080c646dSJean-Christophe PLAGNIOL-VILLARD 	for (i = 0; i < length; i++) {
175*080c646dSJean-Christophe PLAGNIOL-VILLARD 		if (i2c_wait(I2C_READ_BIT) < 0)
176*080c646dSJean-Christophe PLAGNIOL-VILLARD 			break;
177*080c646dSJean-Christophe PLAGNIOL-VILLARD 
178*080c646dSJean-Christophe PLAGNIOL-VILLARD 		/* Generate ack on last next to last byte */
179*080c646dSJean-Christophe PLAGNIOL-VILLARD 		if (i == length - 2)
180*080c646dSJean-Christophe PLAGNIOL-VILLARD 			writeb(I2C_CR_MEN | I2C_CR_MSTA | I2C_CR_TXAK,
181*080c646dSJean-Christophe PLAGNIOL-VILLARD 			       &i2c_dev[i2c_bus_num]->cr);
182*080c646dSJean-Christophe PLAGNIOL-VILLARD 
183*080c646dSJean-Christophe PLAGNIOL-VILLARD 		/* Generate stop on last byte */
184*080c646dSJean-Christophe PLAGNIOL-VILLARD 		if (i == length - 1)
185*080c646dSJean-Christophe PLAGNIOL-VILLARD 			writeb(I2C_CR_MEN | I2C_CR_TXAK, &i2c_dev[i2c_bus_num]->cr);
186*080c646dSJean-Christophe PLAGNIOL-VILLARD 
187*080c646dSJean-Christophe PLAGNIOL-VILLARD 		data[i] = readb(&i2c_dev[i2c_bus_num]->dr);
188*080c646dSJean-Christophe PLAGNIOL-VILLARD 	}
189*080c646dSJean-Christophe PLAGNIOL-VILLARD 
190*080c646dSJean-Christophe PLAGNIOL-VILLARD 	return i;
191*080c646dSJean-Christophe PLAGNIOL-VILLARD }
192*080c646dSJean-Christophe PLAGNIOL-VILLARD 
193*080c646dSJean-Christophe PLAGNIOL-VILLARD int
194*080c646dSJean-Christophe PLAGNIOL-VILLARD i2c_read(u8 dev, uint addr, int alen, u8 *data, int length)
195*080c646dSJean-Christophe PLAGNIOL-VILLARD {
196*080c646dSJean-Christophe PLAGNIOL-VILLARD 	int i = -1; /* signal error */
197*080c646dSJean-Christophe PLAGNIOL-VILLARD 	u8 *a = (u8*)&addr;
198*080c646dSJean-Christophe PLAGNIOL-VILLARD 
199*080c646dSJean-Christophe PLAGNIOL-VILLARD 	if (i2c_wait4bus() >= 0
200*080c646dSJean-Christophe PLAGNIOL-VILLARD 	    && i2c_write_addr(dev, I2C_WRITE_BIT, 0) != 0
201*080c646dSJean-Christophe PLAGNIOL-VILLARD 	    && __i2c_write(&a[4 - alen], alen) == alen)
202*080c646dSJean-Christophe PLAGNIOL-VILLARD 		i = 0; /* No error so far */
203*080c646dSJean-Christophe PLAGNIOL-VILLARD 
204*080c646dSJean-Christophe PLAGNIOL-VILLARD 	if (length
205*080c646dSJean-Christophe PLAGNIOL-VILLARD 	    && i2c_write_addr(dev, I2C_READ_BIT, 1) != 0)
206*080c646dSJean-Christophe PLAGNIOL-VILLARD 		i = __i2c_read(data, length);
207*080c646dSJean-Christophe PLAGNIOL-VILLARD 
208*080c646dSJean-Christophe PLAGNIOL-VILLARD 	writeb(I2C_CR_MEN, &i2c_dev[i2c_bus_num]->cr);
209*080c646dSJean-Christophe PLAGNIOL-VILLARD 
210*080c646dSJean-Christophe PLAGNIOL-VILLARD 	if (i == length)
211*080c646dSJean-Christophe PLAGNIOL-VILLARD 	    return 0;
212*080c646dSJean-Christophe PLAGNIOL-VILLARD 
213*080c646dSJean-Christophe PLAGNIOL-VILLARD 	return -1;
214*080c646dSJean-Christophe PLAGNIOL-VILLARD }
215*080c646dSJean-Christophe PLAGNIOL-VILLARD 
216*080c646dSJean-Christophe PLAGNIOL-VILLARD int
217*080c646dSJean-Christophe PLAGNIOL-VILLARD i2c_write(u8 dev, uint addr, int alen, u8 *data, int length)
218*080c646dSJean-Christophe PLAGNIOL-VILLARD {
219*080c646dSJean-Christophe PLAGNIOL-VILLARD 	int i = -1; /* signal error */
220*080c646dSJean-Christophe PLAGNIOL-VILLARD 	u8 *a = (u8*)&addr;
221*080c646dSJean-Christophe PLAGNIOL-VILLARD 
222*080c646dSJean-Christophe PLAGNIOL-VILLARD 	if (i2c_wait4bus() >= 0
223*080c646dSJean-Christophe PLAGNIOL-VILLARD 	    && i2c_write_addr(dev, I2C_WRITE_BIT, 0) != 0
224*080c646dSJean-Christophe PLAGNIOL-VILLARD 	    && __i2c_write(&a[4 - alen], alen) == alen) {
225*080c646dSJean-Christophe PLAGNIOL-VILLARD 		i = __i2c_write(data, length);
226*080c646dSJean-Christophe PLAGNIOL-VILLARD 	}
227*080c646dSJean-Christophe PLAGNIOL-VILLARD 
228*080c646dSJean-Christophe PLAGNIOL-VILLARD 	writeb(I2C_CR_MEN, &i2c_dev[i2c_bus_num]->cr);
229*080c646dSJean-Christophe PLAGNIOL-VILLARD 
230*080c646dSJean-Christophe PLAGNIOL-VILLARD 	if (i == length)
231*080c646dSJean-Christophe PLAGNIOL-VILLARD 	    return 0;
232*080c646dSJean-Christophe PLAGNIOL-VILLARD 
233*080c646dSJean-Christophe PLAGNIOL-VILLARD 	return -1;
234*080c646dSJean-Christophe PLAGNIOL-VILLARD }
235*080c646dSJean-Christophe PLAGNIOL-VILLARD 
236*080c646dSJean-Christophe PLAGNIOL-VILLARD int
237*080c646dSJean-Christophe PLAGNIOL-VILLARD i2c_probe(uchar chip)
238*080c646dSJean-Christophe PLAGNIOL-VILLARD {
239*080c646dSJean-Christophe PLAGNIOL-VILLARD 	/* For unknow reason the controller will ACK when
240*080c646dSJean-Christophe PLAGNIOL-VILLARD 	 * probing for a slave with the same address, so skip
241*080c646dSJean-Christophe PLAGNIOL-VILLARD 	 * it.
242*080c646dSJean-Christophe PLAGNIOL-VILLARD 	 */
243*080c646dSJean-Christophe PLAGNIOL-VILLARD 	if (chip == (readb(&i2c_dev[i2c_bus_num]->adr) >> 1))
244*080c646dSJean-Christophe PLAGNIOL-VILLARD 		return -1;
245*080c646dSJean-Christophe PLAGNIOL-VILLARD 
246*080c646dSJean-Christophe PLAGNIOL-VILLARD 	return i2c_read(chip, 0, 0, NULL, 0);
247*080c646dSJean-Christophe PLAGNIOL-VILLARD }
248*080c646dSJean-Christophe PLAGNIOL-VILLARD 
249*080c646dSJean-Christophe PLAGNIOL-VILLARD uchar
250*080c646dSJean-Christophe PLAGNIOL-VILLARD i2c_reg_read(uchar i2c_addr, uchar reg)
251*080c646dSJean-Christophe PLAGNIOL-VILLARD {
252*080c646dSJean-Christophe PLAGNIOL-VILLARD 	uchar buf[1];
253*080c646dSJean-Christophe PLAGNIOL-VILLARD 
254*080c646dSJean-Christophe PLAGNIOL-VILLARD 	i2c_read(i2c_addr, reg, 1, buf, 1);
255*080c646dSJean-Christophe PLAGNIOL-VILLARD 
256*080c646dSJean-Christophe PLAGNIOL-VILLARD 	return buf[0];
257*080c646dSJean-Christophe PLAGNIOL-VILLARD }
258*080c646dSJean-Christophe PLAGNIOL-VILLARD 
259*080c646dSJean-Christophe PLAGNIOL-VILLARD void
260*080c646dSJean-Christophe PLAGNIOL-VILLARD i2c_reg_write(uchar i2c_addr, uchar reg, uchar val)
261*080c646dSJean-Christophe PLAGNIOL-VILLARD {
262*080c646dSJean-Christophe PLAGNIOL-VILLARD 	i2c_write(i2c_addr, reg, 1, &val, 1);
263*080c646dSJean-Christophe PLAGNIOL-VILLARD }
264*080c646dSJean-Christophe PLAGNIOL-VILLARD 
265*080c646dSJean-Christophe PLAGNIOL-VILLARD int i2c_set_bus_num(unsigned int bus)
266*080c646dSJean-Christophe PLAGNIOL-VILLARD {
267*080c646dSJean-Christophe PLAGNIOL-VILLARD #ifdef CFG_I2C2_OFFSET
268*080c646dSJean-Christophe PLAGNIOL-VILLARD 	if (bus > 1) {
269*080c646dSJean-Christophe PLAGNIOL-VILLARD #else
270*080c646dSJean-Christophe PLAGNIOL-VILLARD 	if (bus > 0) {
271*080c646dSJean-Christophe PLAGNIOL-VILLARD #endif
272*080c646dSJean-Christophe PLAGNIOL-VILLARD 		return -1;
273*080c646dSJean-Christophe PLAGNIOL-VILLARD 	}
274*080c646dSJean-Christophe PLAGNIOL-VILLARD 
275*080c646dSJean-Christophe PLAGNIOL-VILLARD 	i2c_bus_num = bus;
276*080c646dSJean-Christophe PLAGNIOL-VILLARD 
277*080c646dSJean-Christophe PLAGNIOL-VILLARD 	return 0;
278*080c646dSJean-Christophe PLAGNIOL-VILLARD }
279*080c646dSJean-Christophe PLAGNIOL-VILLARD 
280*080c646dSJean-Christophe PLAGNIOL-VILLARD int i2c_set_bus_speed(unsigned int speed)
281*080c646dSJean-Christophe PLAGNIOL-VILLARD {
282*080c646dSJean-Christophe PLAGNIOL-VILLARD 	return -1;
283*080c646dSJean-Christophe PLAGNIOL-VILLARD }
284*080c646dSJean-Christophe PLAGNIOL-VILLARD 
285*080c646dSJean-Christophe PLAGNIOL-VILLARD unsigned int i2c_get_bus_num(void)
286*080c646dSJean-Christophe PLAGNIOL-VILLARD {
287*080c646dSJean-Christophe PLAGNIOL-VILLARD 	return i2c_bus_num;
288*080c646dSJean-Christophe PLAGNIOL-VILLARD }
289*080c646dSJean-Christophe PLAGNIOL-VILLARD 
290*080c646dSJean-Christophe PLAGNIOL-VILLARD unsigned int i2c_get_bus_speed(void)
291*080c646dSJean-Christophe PLAGNIOL-VILLARD {
292*080c646dSJean-Christophe PLAGNIOL-VILLARD 	return 0;
293*080c646dSJean-Christophe PLAGNIOL-VILLARD }
294*080c646dSJean-Christophe PLAGNIOL-VILLARD #endif /* CONFIG_HARD_I2C */
295*080c646dSJean-Christophe PLAGNIOL-VILLARD #endif /* CONFIG_FSL_I2C */
296