Skip to content

Commit

Permalink
i2c-bfin-twi: handle faulty slave devices better
Browse files Browse the repository at this point in the history
Faulty slave devices might drive SDA low after a transfer finishes.  So,
when this scenario is detected, have the master generate up to 9 extra
clocks until the SDA is properly released.

Signed-off-by: Michael Hennerich <michael.hennerich@analog.com>
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Signed-off-by: Ben Dooks <ben-linux@fluff.org>
  • Loading branch information
Michael Hennerich authored and Ben Dooks committed Jan 12, 2011
1 parent f878133 commit 540ac55
Showing 1 changed file with 22 additions and 0 deletions.
22 changes: 22 additions & 0 deletions drivers/i2c/busses/i2c-bfin-twi.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <linux/completion.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/delay.h>

#include <asm/blackfin.h>
#include <asm/portmux.h>
Expand Down Expand Up @@ -159,6 +160,27 @@ static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface,
if (mast_stat & BUFWRERR)
dev_dbg(&iface->adap.dev, "Buffer Write Error\n");

/* Faulty slave devices, may drive SDA low after a transfer
* finishes. To release the bus this code generates up to 9
* extra clocks until SDA is released.
*/

if (read_MASTER_STAT(iface) & SDASEN) {
int cnt = 9;
do {
write_MASTER_CTL(iface, SCLOVR);
udelay(6);
write_MASTER_CTL(iface, 0);
udelay(6);
} while ((read_MASTER_STAT(iface) & SDASEN) && cnt--);

write_MASTER_CTL(iface, SDAOVR | SCLOVR);
udelay(6);
write_MASTER_CTL(iface, SDAOVR);
udelay(6);
write_MASTER_CTL(iface, 0);
}

/* If it is a quick transfer, only address without data,
* not an err, return 1.
*/
Expand Down

0 comments on commit 540ac55

Please sign in to comment.