diff options
author | Dirk Eibach <dirk.eibach@gdsys.cc> | 2014-10-29 14:56:43 (GMT) |
---|---|---|
committer | Heiko Schocher <hs@denx.de> | 2014-11-10 05:44:15 (GMT) |
commit | 7e78f7ad7f7f666598bc2ff115ea7a35f8e059f1 (patch) | |
tree | 32f580faeeed7ad52997208493dd936b54c80313 /drivers | |
parent | 11ada9225a16ed2d8ddbf0715a2416245a777cbc (diff) | |
download | u-boot-7e78f7ad7f7f666598bc2ff115ea7a35f8e059f1.tar.xz |
ppc4xx: Fix i2c repeated start
Debugging some i2c trouble I saw on my scope that repeated
start is not working properply. The 4xx even held clock pulled down
after transfers. Having a look in the driver I realized
that IIC_CNTL_RPST is set on that part of the transfer that should
begin with a repeated start. But repeated start is about not sending a
stop condition, so IIC_CNTL_RPST has to be set on the last transfer
before the repeated start happens.
Signed-off-by: Dirk Eibach <dirk.eibach@gdsys.cc>
Reviewed-by: Stefan Roese <sr@denx.de>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/i2c/ppc4xx_i2c.c | 9 |
1 files changed, 5 insertions, 4 deletions
diff --git a/drivers/i2c/ppc4xx_i2c.c b/drivers/i2c/ppc4xx_i2c.c index e7a15ba..d2ff86c 100644 --- a/drivers/i2c/ppc4xx_i2c.c +++ b/drivers/i2c/ppc4xx_i2c.c @@ -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 * 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 - * read we set the RPST bit. + * we don't set the creg CHT bit but the RPST bit. * * It does not support address only transfers, there must be * 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)) 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) { creg |= IIC_CNTL_READ; } else { @@ -314,8 +317,6 @@ static int _i2c_transfer(struct i2c_adapter *adap, cnt = data_len; tran = 0; reading = cmd_type; - if (reading) - creg = IIC_CNTL_RPST; } } return result; |