i2c: zynq: Support for 0-length register address
authorMichael Burr <michael.burr@logicpd.com>
Wed, 22 Jan 2014 08:46:07 +0000 (09:46 +0100)
committerHeiko Schocher <hs@denx.de>
Thu, 20 Feb 2014 05:46:55 +0000 (06:46 +0100)
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>
drivers/i2c/zynq_i2c.c

index 70a9aea..11ef0f8 100644 (file)
@@ -189,20 +189,22 @@ 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_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);
@@ -247,17 +249,19 @@ static int zynq_i2c_write(struct i2c_adapter *adap, u8 dev, uint addr,
                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) {