Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 193177
b: refs/heads/master
c: f3083d9
h: refs/heads/master
i:
  193175: 8200631
v: v3
  • Loading branch information
manjugk manjugk authored and Ben Dooks committed May 19, 2010
1 parent fd36a0c commit 011fc3a
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: e9f59b9c9bc5730152b6a94c47dd90b730a07e35
refs/heads/master: f3083d921d8964b66502a0456f62a9d29cd029ef
40 changes: 40 additions & 0 deletions trunk/drivers/i2c/busses/i2c-omap.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,8 @@ enum {
#define SYSC_IDLEMODE_SMART 0x2
#define SYSC_CLOCKACTIVITY_FCLK 0x2

/* Errata definitions */
#define I2C_OMAP_ERRATA_I207 (1 << 0)

struct omap_i2c_dev {
struct device *dev;
Expand Down Expand Up @@ -199,6 +201,7 @@ struct omap_i2c_dev {
u16 bufstate;
u16 syscstate;
u16 westate;
u16 errata;
};

const static u8 reg_map[] = {
Expand Down Expand Up @@ -498,6 +501,11 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)
/* Take the I2C module out of reset: */
omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);

dev->errata = 0;

if (cpu_is_omap2430() || cpu_is_omap34xx())
dev->errata |= I2C_OMAP_ERRATA_I207;

/* Enable interrupts */
dev->iestate = (OMAP_I2C_IE_XRDY | OMAP_I2C_IE_RRDY |
OMAP_I2C_IE_ARDY | OMAP_I2C_IE_NACK |
Expand Down Expand Up @@ -695,6 +703,34 @@ omap_i2c_ack_stat(struct omap_i2c_dev *dev, u16 stat)
omap_i2c_write_reg(dev, OMAP_I2C_STAT_REG, stat);
}

static inline void i2c_omap_errata_i207(struct omap_i2c_dev *dev, u16 stat)
{
/*
* I2C Errata(Errata Nos. OMAP2: 1.67, OMAP3: 1.8)
* Not applicable for OMAP4.
* Under certain rare conditions, RDR could be set again
* when the bus is busy, then ignore the interrupt and
* clear the interrupt.
*/
if (stat & OMAP_I2C_STAT_RDR) {
/* Step 1: If RDR is set, clear it */
omap_i2c_ack_stat(dev, OMAP_I2C_STAT_RDR);

/* Step 2: */
if (!(omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG)
& OMAP_I2C_STAT_BB)) {

/* Step 3: */
if (omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG)
& OMAP_I2C_STAT_RDR) {
omap_i2c_ack_stat(dev, OMAP_I2C_STAT_RDR);
dev_dbg(dev->dev, "RDR when bus is busy.\n");
}

}
}
}

/* rev1 devices are apparently only on some 15xx */
#ifdef CONFIG_ARCH_OMAP15XX

Expand Down Expand Up @@ -834,6 +870,10 @@ omap_i2c_isr(int this_irq, void *dev_id)
}
if (stat & (OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR)) {
u8 num_bytes = 1;

if (dev->errata & I2C_OMAP_ERRATA_I207)
i2c_omap_errata_i207(dev, stat);

if (dev->fifo_size) {
if (stat & OMAP_I2C_STAT_RRDY)
num_bytes = dev->fifo_size;
Expand Down

0 comments on commit 011fc3a

Please sign in to comment.