mirror of
https://github.com/Fishwaldo/u-boot.git
synced 2025-03-21 06:31:31 +00:00
Merge branch 'master' of git://git.denx.de/u-boot-i2c
This commit is contained in:
commit
1e4b45c8f7
4 changed files with 31 additions and 7 deletions
|
@ -72,6 +72,8 @@ struct ppc4xx_i2c {
|
||||||
#define IIC_EXTSTS_XFRA 0x01
|
#define IIC_EXTSTS_XFRA 0x01
|
||||||
#define IIC_EXTSTS_ICT 0x02
|
#define IIC_EXTSTS_ICT 0x02
|
||||||
#define IIC_EXTSTS_LA 0x04
|
#define IIC_EXTSTS_LA 0x04
|
||||||
|
#define IIC_EXTSTS_BCS_MASK 0x70
|
||||||
|
#define IIC_EXTSTS_BCS_FREE 0x40
|
||||||
|
|
||||||
/* XTCNTLSS Register Bit definition */
|
/* XTCNTLSS Register Bit definition */
|
||||||
#define IIC_XTCNTLSS_SRST 0x01
|
#define IIC_XTCNTLSS_SRST 0x01
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
* generic value.
|
* generic value.
|
||||||
*/
|
*/
|
||||||
#ifndef CONFIG_I2C_TIMEOUT
|
#ifndef CONFIG_I2C_TIMEOUT
|
||||||
#define CONFIG_I2C_TIMEOUT 10000
|
#define CONFIG_I2C_TIMEOUT 100000
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define I2C_READ_BIT 1
|
#define I2C_READ_BIT 1
|
||||||
|
|
|
@ -158,8 +158,7 @@ static void ppc4xx_i2c_init(struct i2c_adapter *adap, int speed, int slaveaddr)
|
||||||
*
|
*
|
||||||
* Typical case is a Write of an addr followd by a Read. The
|
* Typical case is a Write of an addr followd by a Read. The
|
||||||
* IBM FAQ does not cover this. On the last byte of the write
|
* IBM FAQ does not cover this. On the last byte of the write
|
||||||
* we don't set the creg CHT bit, and on the first bytes of the
|
* we don't set the creg CHT bit but the RPST bit.
|
||||||
* read we set the RPST bit.
|
|
||||||
*
|
*
|
||||||
* It does not support address only transfers, there must be
|
* It does not support address only transfers, there must be
|
||||||
* a data part. If you want to write the address yourself, put
|
* a data part. If you want to write the address yourself, put
|
||||||
|
@ -247,6 +246,10 @@ static int _i2c_transfer(struct i2c_adapter *adap,
|
||||||
if ((!cmd_type && (ptr == addr)) || ((tran + bc) != cnt))
|
if ((!cmd_type && (ptr == addr)) || ((tran + bc) != cnt))
|
||||||
creg |= IIC_CNTL_CHT;
|
creg |= IIC_CNTL_CHT;
|
||||||
|
|
||||||
|
/* last part of address, prepare for repeated start on read */
|
||||||
|
if (cmd_type && (ptr == addr) && ((tran + bc) == cnt))
|
||||||
|
creg |= IIC_CNTL_RPST;
|
||||||
|
|
||||||
if (reading) {
|
if (reading) {
|
||||||
creg |= IIC_CNTL_READ;
|
creg |= IIC_CNTL_READ;
|
||||||
} else {
|
} else {
|
||||||
|
@ -286,6 +289,27 @@ static int _i2c_transfer(struct i2c_adapter *adap,
|
||||||
/* Transfer aborted? */
|
/* Transfer aborted? */
|
||||||
if (status & IIC_EXTSTS_XFRA)
|
if (status & IIC_EXTSTS_XFRA)
|
||||||
result = IIC_NOK_XFRA;
|
result = IIC_NOK_XFRA;
|
||||||
|
/* Is bus free?
|
||||||
|
* If error happened during combined xfer
|
||||||
|
* IIC interface is usually stuck in some strange
|
||||||
|
* state without a valid stop condition.
|
||||||
|
* Brute, but working: generate stop, then soft reset.
|
||||||
|
*/
|
||||||
|
if ((status & IIC_EXTSTS_BCS_MASK)
|
||||||
|
!= IIC_EXTSTS_BCS_FREE){
|
||||||
|
u8 mdcntl = in_8(&i2c->mdcntl);
|
||||||
|
|
||||||
|
/* Generate valid stop condition */
|
||||||
|
out_8(&i2c->xtcntlss, IIC_XTCNTLSS_SRST);
|
||||||
|
out_8(&i2c->directcntl, IIC_DIRCNTL_SCC);
|
||||||
|
udelay(10);
|
||||||
|
out_8(&i2c->directcntl,
|
||||||
|
IIC_DIRCNTL_SCC | IIC_DIRCNTL_SDAC);
|
||||||
|
out_8(&i2c->xtcntlss, 0);
|
||||||
|
|
||||||
|
ppc4xx_i2c_init(adap, (mdcntl & IIC_MDCNTL_FSM)
|
||||||
|
? 400000 : 100000, 0);
|
||||||
|
}
|
||||||
} else if ( status & IIC_STS_PT) {
|
} else if ( status & IIC_STS_PT) {
|
||||||
result = IIC_NOK_TOUT;
|
result = IIC_NOK_TOUT;
|
||||||
}
|
}
|
||||||
|
@ -314,8 +338,6 @@ static int _i2c_transfer(struct i2c_adapter *adap,
|
||||||
cnt = data_len;
|
cnt = data_len;
|
||||||
tran = 0;
|
tran = 0;
|
||||||
reading = cmd_type;
|
reading = cmd_type;
|
||||||
if (reading)
|
|
||||||
creg = IIC_CNTL_RPST;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -119,10 +119,10 @@ rcar_i2c_raw_read(struct rcar_i2c *dev, u8 chip, uint addr)
|
||||||
|
|
||||||
/* set slave address, receive */
|
/* set slave address, receive */
|
||||||
writel((chip << 1) | 1, &dev->icmar);
|
writel((chip << 1) | 1, &dev->icmar);
|
||||||
/* clear status */
|
|
||||||
writel(0, &dev->icmsr);
|
|
||||||
/* start master receive */
|
/* start master receive */
|
||||||
writel(MCR_MDBS | MCR_MIE | MCR_ESG, &dev->icmcr);
|
writel(MCR_MDBS | MCR_MIE | MCR_ESG, &dev->icmcr);
|
||||||
|
/* clear status */
|
||||||
|
writel(0, &dev->icmsr);
|
||||||
|
|
||||||
while ((readl(&dev->icmsr) & (MSR_MAT | MSR_MDR))
|
while ((readl(&dev->icmsr) & (MSR_MAT | MSR_MDR))
|
||||||
!= (MSR_MAT | MSR_MDR))
|
!= (MSR_MAT | MSR_MDR))
|
||||||
|
|
Loading…
Add table
Reference in a new issue