public inbox for linux-omap@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] [RFC][OMAP3:I2C]Workaround for OMAP3430 I2C silicon errata 1.153
@ 2009-06-22 16:49 Sonasath, Moiz
  2009-06-22 22:30 ` Kevin Hilman
                   ` (2 more replies)
  0 siblings, 3 replies; 11+ messages in thread
From: Sonasath, Moiz @ 2009-06-22 16:49 UTC (permalink / raw)
  To: linux-omap@vger.kernel.org; +Cc: Pandita, Vikram

This patch includes the workarround for I2C Errata 1.153: When an XRDY/XDR is hit, wait for XUDF before writing data to DATA_REG

Signed-off-by: Jagadeesh Bhaskar Pakaravoor <j-pakaravoor@ti.com>
Signed-off by: Nishant Kamat <nskamat@ti.com>
Signed-off-by: Moiz Sonasath<m-sonasath@ti.com>
---
 drivers/i2c/busses/i2c-omap.c |   54 +++++++++++++++++++++++++++++++++++++---
 1 files changed, 50 insertions(+), 4 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index ece0125..e84836b 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -632,6 +632,37 @@ omap_i2c_rev1_isr(int this_irq, void *dev_id)
 #define omap_i2c_rev1_isr		NULL
 #endif
 
+/* I2C Errata 1.153:
+ * When an XRDY/XDR is hit, wait for XUDF before writing data to DATA_REG.
+ * Otherwise some data bytes can be lost while transferring them from the
+ * memory to the I2C interface.
+ */
+
+static int omap_i2c_wait_for_xudf(struct omap_i2c_dev *dev)
+{
+	u16 xudf;
+	int counter = 500;
+
+	/* We are in interrupt context. Wait for XUDF for max 7 msec */
+	xudf = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG);
+	while (!(xudf & OMAP_I2C_STAT_XUDF) && counter--) {
+		if (xudf & (OMAP_I2C_STAT_ROVR | OMAP_I2C_STAT_NACK |
+			    OMAP_I2C_STAT_AL))
+			return -EINVAL;
+		udelay(10);
+		xudf = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG);
+	}
+
+	if (!counter) {
+		/* Clear Tx FIFO */
+		omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG,
+				OMAP_I2C_BUF_TXFIF_CLR);
+		return -ETIMEDOUT;
+	}
+
+	return 0;
+}
+
 static irqreturn_t
 omap_i2c_isr(int this_irq, void *dev_id)
 {
@@ -639,6 +670,7 @@ omap_i2c_isr(int this_irq, void *dev_id)
 	u16 bits;
 	u16 stat, w;
 	int err, count = 0;
+	int error;
 
 	if (dev->idle)
 		return IRQ_NONE;
@@ -647,7 +679,7 @@ omap_i2c_isr(int this_irq, void *dev_id)
 	while ((stat = (omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG))) & bits) {
 		dev_dbg(dev->dev, "IRQ (ISR = 0x%04x)\n", stat);
 		if (count++ == 100) {
-			dev_warn(dev->dev, "Too much work in one IRQ\n");
+			dev_dbg(dev->dev, "Too much work in one IRQ\n");
 			break;
 		}
 
@@ -715,11 +747,22 @@ omap_i2c_isr(int this_irq, void *dev_id)
 							OMAP_I2C_BUFSTAT_REG);
 			}
 			while (num_bytes) {
-				num_bytes--;
 				w = 0;
 				if (dev->buf_len) {
+					if (cpu_is_omap34xx()) {
+						/* OMAP3430 Errata 1.153 */
+						error = omap_i2c_wait_for_xudf(dev);
+						if (error) {
+							omap_i2c_ack_stat(dev, stat &
+								(OMAP_I2C_STAT_XRDY |
+								 OMAP_I2C_STAT_XDR));
+							dev_err(dev->dev, "Transmit error\n");
+							omap_i2c_complete_cmd(dev, OMAP_I2C_STAT_XUDF);
+
+							return IRQ_HANDLED;
+						}
+					}
 					w = *dev->buf++;
-					dev->buf_len--;
 					/* Data reg from  2430 is 8 bit wide */
 					if (!cpu_is_omap2430() &&
 							!cpu_is_omap34xx()) {
@@ -728,6 +771,10 @@ omap_i2c_isr(int this_irq, void *dev_id)
 							dev->buf_len--;
 						}
 					}
+					omap_i2c_write_reg(dev,
+						OMAP_I2C_DATA_REG, w);
+					num_bytes--;
+					dev->buf_len--;
 				} else {
 					if (stat & OMAP_I2C_STAT_XRDY)
 						dev_err(dev->dev,
@@ -739,7 +786,6 @@ omap_i2c_isr(int this_irq, void *dev_id)
 							"data to send\n");
 					break;
 				}
-				omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w);
 			}
 			omap_i2c_ack_stat(dev,
 				stat & (OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR));
-- 
1.5.6.3


^ permalink raw reply related	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2009-07-08 18:22 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-06-22 16:49 [PATCH] [RFC][OMAP3:I2C]Workaround for OMAP3430 I2C silicon errata 1.153 Sonasath, Moiz
2009-06-22 22:30 ` Kevin Hilman
2009-06-23  9:55   ` Kamat, Nishant
2009-06-23 10:05     ` Menon, Nishanth
2009-06-23  2:17 ` Paul Walmsley
2009-07-08 16:50   ` Paul Walmsley
2009-07-08 18:21     ` Sonasath, Moiz
2009-06-23  4:20 ` Menon, Nishanth
2009-06-23 13:43   ` Igor Mazanov
2009-06-23 19:06     ` Menon, Nishanth
2009-06-25 17:17       ` Igor Mazanov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox