[U-Boot] [PATCH v4 1/2] I2C: Zynq: Support for 0-length register address

Michael Burr michael.burr at logicpd.com
Tue Oct 15 19:59:12 CEST 2013


> 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 at logicpd.com>
Cc: Heiko Schocher <hs at denx.de>
Cc: Michal Simek <monstr at monstr.eu>

---
Tested:
Xilinx ZC702 eval board.
Write and read registers with addresses of length 0 and 1.

Change history:
v2: put this in a series instead of by itself
v3: fixed formatting problem in patch message
v4: _really_ fixed this time!

---
  drivers/i2c/zynq_i2c.c |   43 +++++++++++++++++++++++--------------------
  1 file changed, 23 insertions(+), 20 deletions(-)

diff --git a/drivers/i2c/zynq_i2c.c b/drivers/i2c/zynq_i2c.c
index ce2d23f..9cbd3e4 100644
--- a/drivers/i2c/zynq_i2c.c
+++ b/drivers/i2c/zynq_i2c.c
@@ -187,20 +187,22 @@ int i2c_read(u8 dev, uint addr, int alen, u8 
*data, int length)
       * Temporarily disable restart (by clearing hold)
       * It doesn't seem to work.
       */
-    clrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_RW |
-        ZYNQ_I2C_CONTROL_HOLD);
+    clrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_HOLD);
      writel(0xFF, &zynq_i2c->interrupt_status);
-    while (alen--)
-        writel(addr >> (8*alen), &zynq_i2c->data);
-    writel(dev, &zynq_i2c->address);
+    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;
+        /* 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");
      }
-    debug("Device acked address\n");

      setbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_CLR_FIFO |
          ZYNQ_I2C_CONTROL_RW);
@@ -244,17 +246,18 @@ int i2c_write(u8 dev, uint addr, int alen, u8 
*data, int length)
          ZYNQ_I2C_CONTROL_HOLD);
      clrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_RW);
      writel(0xFF, &zynq_i2c->interrupt_status);
-    while (alen--)
-        writel(addr >> (8*alen), &zynq_i2c->data);
-    /* Start the tranfer */
      writel(dev, &zynq_i2c->address);
-    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");
      while (length--) {
          writel(*(cur_data++), &zynq_i2c->data);
          if (readl(&zynq_i2c->transfer_size) == ZYNQ_I2C_FIFO_DEPTH) {
-- 
1.7.9.5



More information about the U-Boot mailing list