diff options
author | Michael Burr <michael.burr@logicpd.com> | 2014-01-22 09:46:07 +0100 |
---|---|---|
committer | Heiko Schocher <hs@denx.de> | 2014-02-20 06:46:55 +0100 |
commit | 9e901071550dd533cc291fb5d19b0841993f6fe7 (patch) | |
tree | 413d4681030004ed01b4260e6710181e79f8f7b0 /drivers/i2c | |
parent | 0a8e823ad0c5a602c93c2e8a54caf622ade6d3fb (diff) |
i2c: zynq: Support for 0-length register address
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>
Diffstat (limited to 'drivers/i2c')
-rw-r--r-- | drivers/i2c/zynq_i2c.c | 42 |
1 files changed, 23 insertions, 19 deletions
diff --git a/drivers/i2c/zynq_i2c.c b/drivers/i2c/zynq_i2c.c index 70a9aeafd53..11ef0f8d4f9 100644 --- a/drivers/i2c/zynq_i2c.c +++ b/drivers/i2c/zynq_i2c.c @@ -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) { |