Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 347068
b: refs/heads/master
c: 0da2e77
h: refs/heads/master
v: v3
  • Loading branch information
Daniel Kurtz authored and Wolfram Sang committed Nov 16, 2012
1 parent c535bd6 commit 886e75f
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 3 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 9bcd04bfbbd5599de011176b846ed00ac15a234c
refs/heads/master: 0da2e7768b4c2b4dbbb148ebe1606b6b4698fca2
47 changes: 45 additions & 2 deletions trunk/drivers/i2c/busses/i2c-s3c2410.c
Original file line number Diff line number Diff line change
Expand Up @@ -235,8 +235,47 @@ static inline void s3c24xx_i2c_stop(struct s3c24xx_i2c *i2c, int ret)

dev_dbg(i2c->dev, "STOP\n");

/* stop the transfer */
iicstat &= ~S3C2410_IICSTAT_START;
/*
* The datasheet says that the STOP sequence should be:
* 1) I2CSTAT.5 = 0 - Clear BUSY (or 'generate STOP')
* 2) I2CCON.4 = 0 - Clear IRQPEND
* 3) Wait until the stop condition takes effect.
* 4*) I2CSTAT.4 = 0 - Clear TXRXEN
*
* Where, step "4*" is only for buses with the "HDMIPHY" quirk.
*
* However, after much experimentation, it appears that:
* a) normal buses automatically clear BUSY and transition from
* Master->Slave when they complete generating a STOP condition.
* Therefore, step (3) can be done in doxfer() by polling I2CCON.4
* after starting the STOP generation here.
* b) HDMIPHY bus does neither, so there is no way to do step 3.
* There is no indication when this bus has finished generating
* STOP.
*
* In fact, we have found that as soon as the IRQPEND bit is cleared in
* step 2, the HDMIPHY bus generates the STOP condition, and then
* immediately starts transferring another data byte, even though the
* bus is supposedly stopped. This is presumably because the bus is
* still in "Master" mode, and its BUSY bit is still set.
*
* To avoid these extra post-STOP transactions on HDMI phy devices, we
* just disable Serial Output on the bus (I2CSTAT.4 = 0) directly,
* instead of first generating a proper STOP condition. This should
* float SDA & SCK terminating the transfer. Subsequent transfers
* start with a proper START condition, and proceed normally.
*
* The HDMIPHY bus is an internal bus that always has exactly two
* devices, the host as Master and the HDMIPHY device as the slave.
* Skipping the STOP condition has been tested on this bus and works.
*/
if (i2c->quirks & QUIRK_HDMIPHY) {
/* Stop driving the I2C pins */
iicstat &= ~S3C2410_IICSTAT_TXRXEN;
} else {
/* stop the transfer */
iicstat &= ~S3C2410_IICSTAT_START;
}
writel(iicstat, i2c->regs + S3C2410_IICSTAT);

i2c->state = STATE_STOP;
Expand Down Expand Up @@ -561,6 +600,10 @@ static int s3c24xx_i2c_doxfer(struct s3c24xx_i2c *i2c,
else if (ret != num)
dev_dbg(i2c->dev, "incomplete xfer (%d)\n", ret);

/* For QUIRK_HDMIPHY, bus is already disabled */
if (i2c->quirks & QUIRK_HDMIPHY)
goto out;

/* ensure the stop has been through the bus */

dev_dbg(i2c->dev, "waiting for bus idle\n");
Expand Down

0 comments on commit 886e75f

Please sign in to comment.