|
@@ -801,36 +801,62 @@ complete:
|
|
|
return IRQ_HANDLED;
|
|
|
}
|
|
|
|
|
|
- if (stat & (OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR)) {
|
|
|
+ if (stat & OMAP_I2C_STAT_RDR) {
|
|
|
u8 num_bytes = 1;
|
|
|
|
|
|
+ if (dev->fifo_size)
|
|
|
+ num_bytes = dev->buf_len;
|
|
|
+
|
|
|
+ while (num_bytes--) {
|
|
|
+ if (!dev->buf_len) {
|
|
|
+ dev_err(dev->dev,
|
|
|
+ "RDR IRQ while no data"
|
|
|
+ " requested\n");
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG);
|
|
|
+ *dev->buf++ = w;
|
|
|
+ dev->buf_len--;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Data reg in 2430, omap3 and
|
|
|
+ * omap4 is 8 bit wide
|
|
|
+ */
|
|
|
+ if (dev->flags &
|
|
|
+ OMAP_I2C_FLAG_16BIT_DATA_REG) {
|
|
|
+ if (dev->buf_len) {
|
|
|
+ *dev->buf++ = w >> 8;
|
|
|
+ dev->buf_len--;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
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;
|
|
|
- else /* read RXSTAT on RDR interrupt */
|
|
|
- num_bytes = (omap_i2c_read_reg(dev,
|
|
|
- OMAP_I2C_BUFSTAT_REG)
|
|
|
- >> 8) & 0x3F;
|
|
|
- }
|
|
|
+ omap_i2c_ack_stat(dev, OMAP_I2C_STAT_RDR);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (stat & OMAP_I2C_STAT_RRDY) {
|
|
|
+ u8 num_bytes = 1;
|
|
|
+
|
|
|
+ if (dev->fifo_size)
|
|
|
+ num_bytes = dev->fifo_size;
|
|
|
+
|
|
|
while (num_bytes--) {
|
|
|
if (!dev->buf_len) {
|
|
|
- if (stat & OMAP_I2C_STAT_RRDY)
|
|
|
- dev_err(dev->dev,
|
|
|
+ dev_err(dev->dev,
|
|
|
"RRDY IRQ while no data"
|
|
|
- " requested\n");
|
|
|
- if (stat & OMAP_I2C_STAT_RDR)
|
|
|
- dev_err(dev->dev,
|
|
|
- "RDR IRQ while no data"
|
|
|
- " requested\n");
|
|
|
+ " requested\n");
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG);
|
|
|
*dev->buf++ = w;
|
|
|
dev->buf_len--;
|
|
|
+
|
|
|
/*
|
|
|
* Data reg in 2430, omap3 and
|
|
|
* omap4 is 8 bit wide
|
|
@@ -843,36 +869,68 @@ complete:
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- omap_i2c_ack_stat(dev, (OMAP_I2C_STAT_RRDY |
|
|
|
- OMAP_I2C_STAT_RDR));
|
|
|
+
|
|
|
+ omap_i2c_ack_stat(dev, OMAP_I2C_STAT_RRDY);
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
- if (stat & (OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR)) {
|
|
|
+ if (stat & OMAP_I2C_STAT_XDR) {
|
|
|
u8 num_bytes = 1;
|
|
|
- if (dev->fifo_size) {
|
|
|
- if (stat & OMAP_I2C_STAT_XRDY)
|
|
|
- num_bytes = dev->fifo_size;
|
|
|
- else /* read TXSTAT on XDR interrupt */
|
|
|
- num_bytes = omap_i2c_read_reg(dev,
|
|
|
- OMAP_I2C_BUFSTAT_REG)
|
|
|
- & 0x3F;
|
|
|
+
|
|
|
+ if (dev->fifo_size)
|
|
|
+ num_bytes = dev->buf_len;
|
|
|
+
|
|
|
+ while (num_bytes--) {
|
|
|
+ if (!dev->buf_len) {
|
|
|
+ dev_err(dev->dev,
|
|
|
+ "XDR IRQ while no "
|
|
|
+ "data to send\n");
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ w = *dev->buf++;
|
|
|
+ dev->buf_len--;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Data reg in 2430, omap3 and
|
|
|
+ * omap4 is 8 bit wide
|
|
|
+ */
|
|
|
+ if (dev->flags &
|
|
|
+ OMAP_I2C_FLAG_16BIT_DATA_REG) {
|
|
|
+ if (dev->buf_len) {
|
|
|
+ w |= *dev->buf++ << 8;
|
|
|
+ dev->buf_len--;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if ((dev->errata & I2C_OMAP_ERRATA_I462) &&
|
|
|
+ errata_omap3_i462(dev, &stat, &err))
|
|
|
+ goto complete;
|
|
|
+
|
|
|
+ omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w);
|
|
|
}
|
|
|
+
|
|
|
+ omap_i2c_ack_stat(dev, OMAP_I2C_STAT_XDR);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (stat & OMAP_I2C_STAT_XRDY) {
|
|
|
+ u8 num_bytes = 1;
|
|
|
+
|
|
|
+ if (dev->fifo_size)
|
|
|
+ num_bytes = dev->fifo_size;
|
|
|
+
|
|
|
while (num_bytes--) {
|
|
|
if (!dev->buf_len) {
|
|
|
- if (stat & OMAP_I2C_STAT_XRDY)
|
|
|
- dev_err(dev->dev,
|
|
|
+ dev_err(dev->dev,
|
|
|
"XRDY IRQ while no "
|
|
|
"data to send\n");
|
|
|
- if (stat & OMAP_I2C_STAT_XDR)
|
|
|
- dev_err(dev->dev,
|
|
|
- "XDR IRQ while no "
|
|
|
- "data to send\n");
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
w = *dev->buf++;
|
|
|
dev->buf_len--;
|
|
|
+
|
|
|
/*
|
|
|
* Data reg in 2430, omap3 and
|
|
|
* omap4 is 8 bit wide
|
|
@@ -891,8 +949,8 @@ complete:
|
|
|
|
|
|
omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w);
|
|
|
}
|
|
|
- omap_i2c_ack_stat(dev, (OMAP_I2C_STAT_XRDY |
|
|
|
- OMAP_I2C_STAT_XDR));
|
|
|
+
|
|
|
+ omap_i2c_ack_stat(dev, OMAP_I2C_STAT_XRDY);
|
|
|
continue;
|
|
|
}
|
|
|
|