mpc83xx: Fix empty i2c reads/writes in fsl_i2c.c
Fix empty i2c reads/writes, i2c_write(0x50, 0x00, 0, NULL, 0) which is used to se if an slave will ACK after receiving its address. Correct i2c probing to use this method as the old method could upset a slave as it wrote a data byte to it. Add a small delay in i2c_init() to let the controller shutdown any ongoing I2C activity. Signed-off-by: Joakim Tjernlund <Joakim.Tjernlund@transmode.se>
This commit is contained in:
		
							parent
							
								
									7a78f148d6
								
							
						
					
					
						commit
						f6f5f709e5
					
				|  | @ -58,6 +58,7 @@ i2c_init(int speed, int slaveadd) | ||||||
| 	dev = (struct fsl_i2c *) (CFG_IMMR + CFG_I2C_OFFSET); | 	dev = (struct fsl_i2c *) (CFG_IMMR + CFG_I2C_OFFSET); | ||||||
| 
 | 
 | ||||||
| 	writeb(0, &dev->cr);			/* stop I2C controller */ | 	writeb(0, &dev->cr);			/* stop I2C controller */ | ||||||
|  | 	udelay(5);				/* let it shutdown in peace */ | ||||||
| 	writeb(0x3F, &dev->fdr);		/* set bus speed */ | 	writeb(0x3F, &dev->fdr);		/* set bus speed */ | ||||||
| 	writeb(0x3F, &dev->dfsrr);		/* set default filter */ | 	writeb(0x3F, &dev->dfsrr);		/* set default filter */ | ||||||
| 	writeb(slaveadd << 1, &dev->adr);	/* write slave address */ | 	writeb(slaveadd << 1, &dev->adr);	/* write slave address */ | ||||||
|  | @ -191,15 +192,17 @@ __i2c_read(u8 *data, int length) | ||||||
| int | int | ||||||
| i2c_read(u8 dev, uint addr, int alen, u8 *data, int length) | i2c_read(u8 dev, uint addr, int alen, u8 *data, int length) | ||||||
| { | { | ||||||
| 	int i = 0; | 	int i = -1; /* signal error */ | ||||||
| 	u8 *a = (u8*)&addr; | 	u8 *a = (u8*)&addr; | ||||||
| 
 | 
 | ||||||
| 	if (i2c_wait4bus() >= 0 | 	if (i2c_wait4bus() >= 0 | ||||||
| 	    && i2c_write_addr(dev, I2C_WRITE_BIT, 0) != 0 | 	    && i2c_write_addr(dev, I2C_WRITE_BIT, 0) != 0 | ||||||
| 	    && __i2c_write(&a[4 - alen], alen) == alen | 	    && __i2c_write(&a[4 - alen], alen) == alen) | ||||||
| 	    && i2c_write_addr(dev, I2C_READ_BIT, 1) != 0) { | 		i = 0; /* No error so far */ | ||||||
|  | 
 | ||||||
|  | 	if (length | ||||||
|  | 	    && i2c_write_addr(dev, I2C_READ_BIT, 1) != 0) | ||||||
| 		i = __i2c_read(data, length); | 		i = __i2c_read(data, length); | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	writeb(I2C_CR_MEN, &i2c_dev[i2c_bus_num]->cr); | 	writeb(I2C_CR_MEN, &i2c_dev[i2c_bus_num]->cr); | ||||||
| 
 | 
 | ||||||
|  | @ -212,7 +215,7 @@ i2c_read(u8 dev, uint addr, int alen, u8 *data, int length) | ||||||
| int | int | ||||||
| i2c_write(u8 dev, uint addr, int alen, u8 *data, int length) | i2c_write(u8 dev, uint addr, int alen, u8 *data, int length) | ||||||
| { | { | ||||||
| 	int i = 0; | 	int i = -1; /* signal error */ | ||||||
| 	u8 *a = (u8*)&addr; | 	u8 *a = (u8*)&addr; | ||||||
| 
 | 
 | ||||||
| 	if (i2c_wait4bus() >= 0 | 	if (i2c_wait4bus() >= 0 | ||||||
|  | @ -232,16 +235,14 @@ i2c_write(u8 dev, uint addr, int alen, u8 *data, int length) | ||||||
| int | int | ||||||
| i2c_probe(uchar chip) | i2c_probe(uchar chip) | ||||||
| { | { | ||||||
| 	int tmp; | 	/* For unknow reason the controller will ACK when
 | ||||||
| 
 | 	 * probing for a slave with the same address, so skip | ||||||
| 	/*
 | 	 * it. | ||||||
| 	 * Try to read the first location of the chip.  The underlying |  | ||||||
| 	 * driver doesn't appear to support sending just the chip address |  | ||||||
| 	 * and looking for an <ACK> back. |  | ||||||
| 	 */ | 	 */ | ||||||
| 	udelay(10000); | 	if (chip == (readb(&i2c_dev[i2c_bus_num]->adr) >> 1)) | ||||||
|  | 		return -1; | ||||||
| 
 | 
 | ||||||
| 	return i2c_read(chip, 0, 1, (uchar *)&tmp, 1); | 	return i2c_read(chip, 0, 0, NULL, 0); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uchar | uchar | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue