diff mbox

[U-Boot,v1,1/2] i2c: zynq: Support for 0-length register address

Message ID 597d3263781da45960a4bf344d78f3f72899b96a.1388742342.git.michal.simek@xilinx.com
State Accepted
Delegated to: Heiko Schocher
Headers show

Commit Message

Michal Simek Jan. 3, 2014, 9:45 a.m. UTC
From: Michael Burr <michael.burr@logicpd.com>

Fixed bug with alen == 0 in 'i2c_write', 'i2c_read'
Further minor corrections:
- Write 'address' register before 'data' register.
- Write 'transfer_size' register before 'address' register.

Signed-off-by: Michael Burr <michael.burr@logicpd.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>

---

Changes in v1:
- Based on original thread from Michael Burr
  http://lists.denx.de/pipermail/u-boot/2013-October/165060.html
- MS rebase on latest&greatest

 drivers/i2c/zynq_i2c.c | 37 +++++++++++++++++++++++++++----------
 1 file changed, 27 insertions(+), 10 deletions(-)

--
1.8.2.3
diff mbox

Patch

diff --git a/drivers/i2c/zynq_i2c.c b/drivers/i2c/zynq_i2c.c
index 70a9aea..a9df838 100644
--- a/drivers/i2c/zynq_i2c.c
+++ b/drivers/i2c/zynq_i2c.c
@@ -189,20 +189,37 @@  static int zynq_i2c_read(struct i2c_adapter *adap, u8 dev, uint addr,
 	 * Temporarily disable restart (by clearing hold)
 	 * It doesn't seem to work.
 	 */
+	clrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_HOLD);
+	writel(0xFF, &zynq_i2c->interrupt_status);
+	if (alen) {
+		clrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_RW);
+		writel(dev, &zynq_i2c->address);
+		while (alen--)
+			writel(addr >> (8*alen), &zynq_i2c->data);
+
+		/* Wait for the address to be sent */
+		if (!zynq_i2c_wait(ZYNQ_I2C_INTERRUPT_COMP)) {
+			/* Release the bus */
+			clrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_HOLD);
+			return -ETIMEDOUT;
+		}
+		debug("Device acked address\n");
+	}
+
 	clrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_RW |
 		ZYNQ_I2C_CONTROL_HOLD);
 	writel(0xFF, &zynq_i2c->interrupt_status);
-	while (alen--)
-		writel(addr >> (8*alen), &zynq_i2c->data);
-	writel(dev, &zynq_i2c->address);
-
-	/* Wait for the address to be sent */
-	if (!zynq_i2c_wait(ZYNQ_I2C_INTERRUPT_COMP)) {
-		/* Release the bus */
-		clrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_HOLD);
-		return -ETIMEDOUT;
+	if (alen) {
+		while (alen--)
+			writel(addr >> (8*alen), &zynq_i2c->data);
+		/* Start the tranfer */
+		if (!zynq_i2c_wait(ZYNQ_I2C_INTERRUPT_COMP)) {
+			/* Release the bus */
+			clrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_HOLD);
+			return -ETIMEDOUT;
+		}
+		debug("Device acked address\n");
 	}
-	debug("Device acked address\n");

 	setbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_CLR_FIFO |
 		ZYNQ_I2C_CONTROL_RW);