[no subject]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I tried the following patch based on the description of the steps you took to 
recover the bus. Is there anything you can add? I still get lots of 
'controller timed out' errors.

Best Regards,

Ben Gardiner

Nanometrics Inc.
http://www.nanometrics.ca

---

diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c
index 5795c83..52e5e60 100644
--- a/drivers/i2c/busses/i2c-davinci.c
+++ b/drivers/i2c/busses/i2c-davinci.c
@@ -89,6 +89,7 @@
 #define DAVINCI_I2C_MDR_XA	BIT(8)
 #define DAVINCI_I2C_MDR_RM	BIT(7)
 #define DAVINCI_I2C_MDR_IRS	BIT(5)
+#define DAVINCI_I2C_MDR_FDF	BIT(3)
 
 #define DAVINCI_I2C_IMR_AAS	BIT(6)
 #define DAVINCI_I2C_IMR_SCD	BIT(5)
@@ -149,6 +150,36 @@ static void generic_i2c_clock_pulse(unsigned int scl_pin)
 	}
 }
 
+static void alternate_i2c_clock_pulse(struct davinci_i2c_dev *dev)
+{
+	u32 flag = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG);
+	/* free data format mode */
+	flag |= DAVINCI_I2C_MDR_FDF;
+	/* receive byte */
+	flag &= ~DAVINCI_I2C_MDR_TRX;
+	/* repeat */
+	flag |= DAVINCI_I2C_MDR_RM;
+
+	/*
+	 * Write mode register first as needed for correct behaviour
+	 * on OMAP-L138, but don't set STT yet to avoid a race with XRDY
+	 * occuring before we have loaded DXR
+	 */
+	davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag);
+
+	/* Disable receive and transmit interrupts */
+	flag = davinci_i2c_read_reg(dev, DAVINCI_I2C_IMR_REG);
+	flag &= ~DAVINCI_I2C_IMR_RRDY;
+	flag &= ~DAVINCI_I2C_IMR_XRDY;
+	davinci_i2c_write_reg(dev, DAVINCI_I2C_IMR_REG, flag);
+
+	/* Set STT to begin transmit now DXR is loaded */
+	flag |= DAVINCI_I2C_MDR_STT;
+	davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag);
+
+	udelay(40*9);
+}
+
 /* This routine does i2c bus recovery as specified in the
  * i2c protocol Rev. 03 section 3.16 titled "Bus clear"
  */
@@ -163,8 +194,10 @@ static void i2c_recover_bus(struct davinci_i2c_dev *dev)
 	flag |=  DAVINCI_I2C_MDR_NACK;
 	/* write the data into mode register */
 	davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag);
-	if (pdata)
+	if (pdata->scl_pin)
 		generic_i2c_clock_pulse(pdata->scl_pin);
+	else
+		alternate_i2c_clock_pulse(dev);
 	/* Send STOP */
 	flag = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG);
 	flag |= DAVINCI_I2C_MDR_STP;
--
To unsubscribe from this list: send the line "unsubscribe linux-i2c" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux GPIO]     [Linux SPI]     [Linux Hardward Monitoring]     [LM Sensors]     [Linux USB Devel]     [Linux Media]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux