All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH V2 01/25] mxc_i2c: fix i2c_imx_stop
@ 2012-07-05 19:53 Troy Kisky
  2012-07-05 19:53 ` [U-Boot] [PATCH V2 02/25] mxc_i2c: remove ifdef of CONFIG_HARD_I2C Troy Kisky
                   ` (25 more replies)
  0 siblings, 26 replies; 33+ messages in thread
From: Troy Kisky @ 2012-07-05 19:53 UTC (permalink / raw)
  To: u-boot

Instead of clearing 2 bits, all the other
bits were set because '|=' was used instead
of '&='.

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
Acked-by: Marek Vasut <marex@denx.de>
Acked-by: Stefano Babic <sbabic@denx.de>

---
V2: add acks
---
 drivers/i2c/mxc_i2c.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c
index fc68062..c0c45fd 100644
--- a/drivers/i2c/mxc_i2c.c
+++ b/drivers/i2c/mxc_i2c.c
@@ -264,7 +264,7 @@ void i2c_imx_stop(void)
 
 	/* Stop I2C transaction */
 	temp = readb(&i2c_regs->i2cr);
-	temp |= ~(I2CR_MSTA | I2CR_MTX);
+	temp &= ~(I2CR_MSTA | I2CR_MTX);
 	writeb(temp, &i2c_regs->i2cr);
 
 	i2c_imx_bus_busy(0);
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH V2 02/25] mxc_i2c: remove ifdef of CONFIG_HARD_I2C
  2012-07-05 19:53 [U-Boot] [PATCH V2 01/25] mxc_i2c: fix i2c_imx_stop Troy Kisky
@ 2012-07-05 19:53 ` Troy Kisky
  2012-07-05 19:53 ` [U-Boot] [PATCH V2 03/25] mxc_i2c: create tx_byte function Troy Kisky
                   ` (24 subsequent siblings)
  25 siblings, 0 replies; 33+ messages in thread
From: Troy Kisky @ 2012-07-05 19:53 UTC (permalink / raw)
  To: u-boot

This is always selected when CONFIG_I2C_MXC is
selected, so it adds no value.

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
Acked-by: Marek Vasut <marex@denx.de>

---
v2: add ack
---
 drivers/i2c/mxc_i2c.c |    6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c
index c0c45fd..0b46c9c 100644
--- a/drivers/i2c/mxc_i2c.c
+++ b/drivers/i2c/mxc_i2c.c
@@ -31,12 +31,9 @@
  */
 
 #include <common.h>
-#include <asm/io.h>
-
-#if defined(CONFIG_HARD_I2C)
-
 #include <asm/arch/clock.h>
 #include <asm/arch/imx-regs.h>
+#include <asm/io.h>
 #include <i2c.h>
 
 struct mxc_i2c_regs {
@@ -446,4 +443,3 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len)
 
 	return ret;
 }
-#endif /* CONFIG_HARD_I2C */
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH V2 03/25] mxc_i2c: create tx_byte function
  2012-07-05 19:53 [U-Boot] [PATCH V2 01/25] mxc_i2c: fix i2c_imx_stop Troy Kisky
  2012-07-05 19:53 ` [U-Boot] [PATCH V2 02/25] mxc_i2c: remove ifdef of CONFIG_HARD_I2C Troy Kisky
@ 2012-07-05 19:53 ` Troy Kisky
  2012-07-05 19:53 ` [U-Boot] [PATCH V2 04/25] mxc_i2c: clear i2sr before waiting for bit Troy Kisky
                   ` (23 subsequent siblings)
  25 siblings, 0 replies; 33+ messages in thread
From: Troy Kisky @ 2012-07-05 19:53 UTC (permalink / raw)
  To: u-boot

Use tx_byte function instead of having 3 copies
of the code.

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
Acked-by: Marek Vasut <marex@denx.de>

---
v2: add ack
change ret to integer from unsigned
---
 drivers/i2c/mxc_i2c.c |   82 +++++++++++++++----------------------------------
 1 file changed, 24 insertions(+), 58 deletions(-)

diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c
index 0b46c9c..d147dd5 100644
--- a/drivers/i2c/mxc_i2c.c
+++ b/drivers/i2c/mxc_i2c.c
@@ -33,6 +33,7 @@
 #include <common.h>
 #include <asm/arch/clock.h>
 #include <asm/arch/imx-regs.h>
+#include <asm/errno.h>
 #include <asm/io.h>
 #include <i2c.h>
 
@@ -207,17 +208,21 @@ int i2c_imx_trx_complete(void)
 		udelay(1);
 	}
 
-	return 1;
+	return -ETIMEDOUT;
 }
 
-/*
- * Check if the transaction was ACKed
- */
-int i2c_imx_acked(void)
+static int tx_byte(struct mxc_i2c_regs *i2c_regs, u8 byte)
 {
-	struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)I2C_BASE;
+	int ret;
 
-	return readb(&i2c_regs->i2sr) & I2SR_RX_NO_AK;
+	writeb(byte, &i2c_regs->i2dr);
+	ret = i2c_imx_trx_complete();
+	if (ret < 0)
+		return ret;
+	ret = readb(&i2c_regs->i2sr);
+	if (ret & I2SR_RX_NO_AK)
+		return -ENODEV;
+	return 0;
 }
 
 /*
@@ -271,30 +276,6 @@ void i2c_imx_stop(void)
 }
 
 /*
- * Set chip address and access mode
- *
- * read = 1: READ access
- * read = 0: WRITE access
- */
-int i2c_imx_set_chip_addr(uchar chip, int read)
-{
-	struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)I2C_BASE;
-	int ret;
-
-	writeb((chip << 1) | read, &i2c_regs->i2dr);
-
-	ret = i2c_imx_trx_complete();
-	if (ret)
-		return ret;
-
-	ret = i2c_imx_acked();
-	if (ret)
-		return ret;
-
-	return ret;
-}
-
-/*
  * Write register address
  */
 int i2c_imx_set_reg_addr(uint addr, int alen)
@@ -303,14 +284,8 @@ int i2c_imx_set_reg_addr(uint addr, int alen)
 	int ret = 0;
 
 	while (alen--) {
-		writeb((addr >> (alen * 8)) & 0xff, &i2c_regs->i2dr);
-
-		ret = i2c_imx_trx_complete();
-		if (ret)
-			break;
-
-		ret = i2c_imx_acked();
-		if (ret)
+		ret = tx_byte(i2c_regs, (addr >> (alen * 8)) & 0xff);
+		if (ret < 0)
 			break;
 	}
 
@@ -322,18 +297,15 @@ int i2c_imx_set_reg_addr(uint addr, int alen)
  */
 int i2c_probe(uchar chip)
 {
+	struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)I2C_BASE;
 	int ret;
 
 	ret = i2c_imx_start();
 	if (ret)
 		return ret;
 
-	ret = i2c_imx_set_chip_addr(chip, 0);
-	if (ret)
-		return ret;
-
+	ret = tx_byte(i2c_regs, chip << 1);
 	i2c_imx_stop();
-
 	return ret;
 }
 
@@ -352,8 +324,8 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len)
 		return ret;
 
 	/* write slave address */
-	ret = i2c_imx_set_chip_addr(chip, 0);
-	if (ret)
+	ret = tx_byte(i2c_regs, chip << 1);
+	if (ret < 0)
 		return ret;
 
 	ret = i2c_imx_set_reg_addr(addr, alen);
@@ -364,8 +336,8 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len)
 	temp |= I2CR_RSTA;
 	writeb(temp, &i2c_regs->i2cr);
 
-	ret = i2c_imx_set_chip_addr(chip, 1);
-	if (ret)
+	ret = tx_byte(i2c_regs, (chip << 1) | 1);
+	if (ret < 0)
 		return ret;
 
 	/* setup bus to read data */
@@ -419,8 +391,8 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len)
 		return ret;
 
 	/* write slave address */
-	ret = i2c_imx_set_chip_addr(chip, 0);
-	if (ret)
+	ret = tx_byte(i2c_regs, chip << 1);
+	if (ret < 0)
 		return ret;
 
 	ret = i2c_imx_set_reg_addr(addr, alen);
@@ -428,14 +400,8 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len)
 		return ret;
 
 	for (i = 0; i < len; i++) {
-		writeb(buf[i], &i2c_regs->i2dr);
-
-		ret = i2c_imx_trx_complete();
-		if (ret)
-			return ret;
-
-		ret = i2c_imx_acked();
-		if (ret)
+		ret = tx_byte(i2c_regs, buf[i]);
+		if (ret < 0)
 			return ret;
 	}
 
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH V2 04/25] mxc_i2c: clear i2sr before waiting for bit
  2012-07-05 19:53 [U-Boot] [PATCH V2 01/25] mxc_i2c: fix i2c_imx_stop Troy Kisky
  2012-07-05 19:53 ` [U-Boot] [PATCH V2 02/25] mxc_i2c: remove ifdef of CONFIG_HARD_I2C Troy Kisky
  2012-07-05 19:53 ` [U-Boot] [PATCH V2 03/25] mxc_i2c: create tx_byte function Troy Kisky
@ 2012-07-05 19:53 ` Troy Kisky
  2012-07-05 19:53 ` [U-Boot] [PATCH V2 05/25] mxc_i2c: create i2c_init_transfer Troy Kisky
                   ` (22 subsequent siblings)
  25 siblings, 0 replies; 33+ messages in thread
From: Troy Kisky @ 2012-07-05 19:53 UTC (permalink / raw)
  To: u-boot

Let's clear the sr register before waiting for
bit to be set, instead of clearing it after
hardware sets it. No real operational difference here,
but allows combining of i2c_imx_trx_complete and
i2c_imx_bus_busy in later patches.

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
Acked-by: Marek Vasut <marex@denx.de>

---
v2: add ack
add clear of i2sr in i2c_read
---
 drivers/i2c/mxc_i2c.c |    9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c
index d147dd5..57027ad 100644
--- a/drivers/i2c/mxc_i2c.c
+++ b/drivers/i2c/mxc_i2c.c
@@ -200,10 +200,8 @@ int i2c_imx_trx_complete(void)
 	int timeout = I2C_MAX_TIMEOUT;
 
 	while (timeout--) {
-		if (readb(&i2c_regs->i2sr) & I2SR_IIF) {
-			writeb(0, &i2c_regs->i2sr);
+		if (readb(&i2c_regs->i2sr) & I2SR_IIF)
 			return 0;
-		}
 
 		udelay(1);
 	}
@@ -215,6 +213,7 @@ static int tx_byte(struct mxc_i2c_regs *i2c_regs, u8 byte)
 {
 	int ret;
 
+	writeb(0, &i2c_regs->i2sr);
 	writeb(byte, &i2c_regs->i2dr);
 	ret = i2c_imx_trx_complete();
 	if (ret < 0)
@@ -346,7 +345,8 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len)
 	if (len == 1)
 		temp |= I2CR_TX_NO_AK;
 	writeb(temp, &i2c_regs->i2cr);
-	readb(&i2c_regs->i2dr);
+	writeb(0, &i2c_regs->i2sr);
+	readb(&i2c_regs->i2dr);		/* dummy read to clear ICF */
 
 	/* read data */
 	for (i = 0; i < len; i++) {
@@ -369,6 +369,7 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len)
 			writeb(temp, &i2c_regs->i2cr);
 		}
 
+		writeb(0, &i2c_regs->i2sr);
 		buf[i] = readb(&i2c_regs->i2dr);
 	}
 
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH V2 05/25] mxc_i2c: create i2c_init_transfer
  2012-07-05 19:53 [U-Boot] [PATCH V2 01/25] mxc_i2c: fix i2c_imx_stop Troy Kisky
                   ` (2 preceding siblings ...)
  2012-07-05 19:53 ` [U-Boot] [PATCH V2 04/25] mxc_i2c: clear i2sr before waiting for bit Troy Kisky
@ 2012-07-05 19:53 ` Troy Kisky
  2012-07-05 19:53 ` [U-Boot] [PATCH V2 06/25] mxc_i2c: call i2c_imx_stop on error in i2c_read/i2c_write Troy Kisky
                   ` (21 subsequent siblings)
  25 siblings, 0 replies; 33+ messages in thread
From: Troy Kisky @ 2012-07-05 19:53 UTC (permalink / raw)
  To: u-boot

Initial code of i2c_read and i2c_write
is identical, move to subroutine.

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
Acked-by: Marek Vasut <marex@denx.de>
Acked-by: Stefano Babic <sbabic@denx.de>

---
v2: add ack
---
 drivers/i2c/mxc_i2c.c |   44 ++++++++++++++++++--------------------------
 1 file changed, 18 insertions(+), 26 deletions(-)

diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c
index 57027ad..4ce695a 100644
--- a/drivers/i2c/mxc_i2c.c
+++ b/drivers/i2c/mxc_i2c.c
@@ -275,19 +275,29 @@ void i2c_imx_stop(void)
 }
 
 /*
- * Write register address
+ * Send start signal, chip address and
+ * write register address
  */
-int i2c_imx_set_reg_addr(uint addr, int alen)
+static int i2c_init_transfer(struct mxc_i2c_regs *i2c_regs,
+		uchar chip, uint addr, int alen)
 {
-	struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)I2C_BASE;
-	int ret = 0;
+	int ret = i2c_imx_start();
+	if (ret)
+		goto exit;
+
+	/* write slave address */
+	ret = tx_byte(i2c_regs, chip << 1);
+	if (ret < 0)
+		goto exit;
 
 	while (alen--) {
 		ret = tx_byte(i2c_regs, (addr >> (alen * 8)) & 0xff);
 		if (ret < 0)
-			break;
+			goto exit;
 	}
-
+	return 0;
+exit:
+	i2c_imx_stop();
 	return ret;
 }
 
@@ -318,19 +328,10 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len)
 	unsigned int temp;
 	int i;
 
-	ret = i2c_imx_start();
-	if (ret)
-		return ret;
-
-	/* write slave address */
-	ret = tx_byte(i2c_regs, chip << 1);
+	ret = i2c_init_transfer(i2c_regs, chip, addr, alen);
 	if (ret < 0)
 		return ret;
 
-	ret = i2c_imx_set_reg_addr(addr, alen);
-	if (ret)
-		return ret;
-
 	temp = readb(&i2c_regs->i2cr);
 	temp |= I2CR_RSTA;
 	writeb(temp, &i2c_regs->i2cr);
@@ -387,19 +388,10 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len)
 	int ret;
 	int i;
 
-	ret = i2c_imx_start();
-	if (ret)
-		return ret;
-
-	/* write slave address */
-	ret = tx_byte(i2c_regs, chip << 1);
+	ret = i2c_init_transfer(i2c_regs, chip, addr, alen);
 	if (ret < 0)
 		return ret;
 
-	ret = i2c_imx_set_reg_addr(addr, alen);
-	if (ret)
-		return ret;
-
 	for (i = 0; i < len; i++) {
 		ret = tx_byte(i2c_regs, buf[i]);
 		if (ret < 0)
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH V2 06/25] mxc_i2c: call i2c_imx_stop on error in i2c_read/i2c_write
  2012-07-05 19:53 [U-Boot] [PATCH V2 01/25] mxc_i2c: fix i2c_imx_stop Troy Kisky
                   ` (3 preceding siblings ...)
  2012-07-05 19:53 ` [U-Boot] [PATCH V2 05/25] mxc_i2c: create i2c_init_transfer Troy Kisky
@ 2012-07-05 19:53 ` Troy Kisky
  2012-07-05 19:53 ` [U-Boot] [PATCH V2 07/25] mxc_i2c.c: code i2c_probe as a 0 length i2c_write Troy Kisky
                   ` (20 subsequent siblings)
  25 siblings, 0 replies; 33+ messages in thread
From: Troy Kisky @ 2012-07-05 19:53 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
---
 drivers/i2c/mxc_i2c.c |   10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c
index 4ce695a..55a688a 100644
--- a/drivers/i2c/mxc_i2c.c
+++ b/drivers/i2c/mxc_i2c.c
@@ -337,8 +337,10 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len)
 	writeb(temp, &i2c_regs->i2cr);
 
 	ret = tx_byte(i2c_regs, (chip << 1) | 1);
-	if (ret < 0)
+	if (ret < 0) {
+		i2c_imx_stop();
 		return ret;
+	}
 
 	/* setup bus to read data */
 	temp = readb(&i2c_regs->i2cr);
@@ -352,8 +354,10 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len)
 	/* read data */
 	for (i = 0; i < len; i++) {
 		ret = i2c_imx_trx_complete();
-		if (ret)
+		if (ret) {
+			i2c_imx_stop();
 			return ret;
+		}
 
 		/*
 		 * It must generate STOP before read I2DR to prevent
@@ -395,7 +399,7 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len)
 	for (i = 0; i < len; i++) {
 		ret = tx_byte(i2c_regs, buf[i]);
 		if (ret < 0)
-			return ret;
+			break;
 	}
 
 	i2c_imx_stop();
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH V2 07/25] mxc_i2c.c: code i2c_probe as a 0 length i2c_write
  2012-07-05 19:53 [U-Boot] [PATCH V2 01/25] mxc_i2c: fix i2c_imx_stop Troy Kisky
                   ` (4 preceding siblings ...)
  2012-07-05 19:53 ` [U-Boot] [PATCH V2 06/25] mxc_i2c: call i2c_imx_stop on error in i2c_read/i2c_write Troy Kisky
@ 2012-07-05 19:53 ` Troy Kisky
  2012-07-05 19:53 ` [U-Boot] [PATCH V2 08/25] mxc_i2c: combine i2c_imx_bus_busy and i2c_imx_trx_complete into wait_for_sr_state Troy Kisky
                   ` (19 subsequent siblings)
  25 siblings, 0 replies; 33+ messages in thread
From: Troy Kisky @ 2012-07-05 19:53 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
Acked-by: Marek Vasut <marex@denx.de>
Acked-by: Stefano Babic <sbabic@denx.de>

---
v2: add acks
change comment
---
---
 drivers/i2c/mxc_i2c.c |   25 ++++++++-----------------
 1 file changed, 8 insertions(+), 17 deletions(-)

diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c
index 55a688a..626e13e 100644
--- a/drivers/i2c/mxc_i2c.c
+++ b/drivers/i2c/mxc_i2c.c
@@ -302,23 +302,6 @@ exit:
 }
 
 /*
- * Try if a chip add given address responds (probe the chip)
- */
-int i2c_probe(uchar chip)
-{
-	struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)I2C_BASE;
-	int ret;
-
-	ret = i2c_imx_start();
-	if (ret)
-		return ret;
-
-	ret = tx_byte(i2c_regs, chip << 1);
-	i2c_imx_stop();
-	return ret;
-}
-
-/*
  * Read data from I2C device
  */
 int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len)
@@ -406,3 +389,11 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len)
 
 	return ret;
 }
+
+/*
+ * Test if a chip@a given address responds (probe the chip)
+ */
+int i2c_probe(uchar chip)
+{
+	return i2c_write(chip, 0, 0, NULL, 0);
+}
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH V2 08/25] mxc_i2c: combine i2c_imx_bus_busy and i2c_imx_trx_complete into wait_for_sr_state
  2012-07-05 19:53 [U-Boot] [PATCH V2 01/25] mxc_i2c: fix i2c_imx_stop Troy Kisky
                   ` (5 preceding siblings ...)
  2012-07-05 19:53 ` [U-Boot] [PATCH V2 07/25] mxc_i2c.c: code i2c_probe as a 0 length i2c_write Troy Kisky
@ 2012-07-05 19:53 ` Troy Kisky
  2012-07-05 19:53 ` [U-Boot] [PATCH V2 09/25] mxc_i2c: remove redundant read Troy Kisky
                   ` (18 subsequent siblings)
  25 siblings, 0 replies; 33+ messages in thread
From: Troy Kisky @ 2012-07-05 19:53 UTC (permalink / raw)
  To: u-boot

Not using udelay gives a more accurate timeout. The current implementation of udelay
in imx-common does not seem to wait at all for a udelay(1).

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
Acked-by: Marek Vasut <marex@denx.de>

----
V2: Added WATCHDOG_RESET as suggested by Marek Vasut
add error message when stop fails

mxc_i2c: code i2c_probe as a 0 length i2c_write

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
Acked-by: Marek Vasut <marex@denx.de>
Acked-by: Stefano Babic <sbabic@denx.de>

---
v2: add acks
---
 drivers/i2c/mxc_i2c.c |   80 ++++++++++++++++++-------------------------------
 1 file changed, 29 insertions(+), 51 deletions(-)

diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c
index 626e13e..01a6408 100644
--- a/drivers/i2c/mxc_i2c.c
+++ b/drivers/i2c/mxc_i2c.c
@@ -36,6 +36,7 @@
 #include <asm/errno.h>
 #include <asm/io.h>
 #include <i2c.h>
+#include <watchdog.h>
 
 struct mxc_i2c_regs {
 	uint32_t	iadr;
@@ -63,8 +64,6 @@ struct mxc_i2c_regs {
 #error "define CONFIG_SYS_I2C_BASE to use the mxc_i2c driver"
 #endif
 
-#define I2C_MAX_TIMEOUT		10000
-
 static u16 i2c_clk_div[50][2] = {
 	{ 22,	0x20 }, { 24,	0x21 }, { 26,	0x22 }, { 28,	0x23 },
 	{ 30,	0x00 }, { 32,	0x24 }, { 36,	0x25 }, { 40,	0x26 },
@@ -164,48 +163,26 @@ unsigned int i2c_get_bus_speed(void)
 	return mxc_get_clock(MXC_IPG_PERCLK) / i2c_clk_div[clk_div][0];
 }
 
-/*
- * Wait for bus to be busy (or free if for_busy = 0)
- *
- * for_busy = 1: Wait for IBB to be asserted
- * for_busy = 0: Wait for IBB to be de-asserted
- */
-int i2c_imx_bus_busy(int for_busy)
-{
-	struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)I2C_BASE;
-	unsigned int temp;
-
-	int timeout = I2C_MAX_TIMEOUT;
-
-	while (timeout--) {
-		temp = readb(&i2c_regs->i2sr);
-
-		if (for_busy && (temp & I2SR_IBB))
-			return 0;
-		if (!for_busy && !(temp & I2SR_IBB))
-			return 0;
-
-		udelay(1);
-	}
-
-	return 1;
-}
+#define ST_BUS_IDLE (0 | (I2SR_IBB << 8))
+#define ST_BUS_BUSY (I2SR_IBB | (I2SR_IBB << 8))
+#define ST_IIF (I2SR_IIF | (I2SR_IIF << 8))
 
-/*
- * Wait for transaction to complete
- */
-int i2c_imx_trx_complete(void)
+static int wait_for_sr_state(struct mxc_i2c_regs *i2c_regs, unsigned state)
 {
-	struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)I2C_BASE;
-	int timeout = I2C_MAX_TIMEOUT;
-
-	while (timeout--) {
-		if (readb(&i2c_regs->i2sr) & I2SR_IIF)
-			return 0;
-
-		udelay(1);
+	unsigned sr;
+	ulong elapsed;
+	ulong start_time = get_timer(0);
+	for (;;) {
+		sr = readb(&i2c_regs->i2sr);
+		if ((sr & (state >> 8)) == (unsigned char)state)
+			return sr;
+		WATCHDOG_RESET();
+		elapsed = get_timer(start_time);
+		if (elapsed > (CONFIG_SYS_HZ / 10))	/* .1 seconds */
+			break;
 	}
-
+	printf("%s: failed sr=%x cr=%x state=%x\n", __func__,
+			sr, readb(&i2c_regs->i2cr), state);
 	return -ETIMEDOUT;
 }
 
@@ -215,7 +192,7 @@ static int tx_byte(struct mxc_i2c_regs *i2c_regs, u8 byte)
 
 	writeb(0, &i2c_regs->i2sr);
 	writeb(byte, &i2c_regs->i2dr);
-	ret = i2c_imx_trx_complete();
+	ret = wait_for_sr_state(i2c_regs, ST_IIF);
 	if (ret < 0)
 		return ret;
 	ret = readb(&i2c_regs->i2sr);
@@ -245,8 +222,8 @@ int i2c_imx_start(void)
 	temp |= I2CR_MSTA;
 	writeb(temp, &i2c_regs->i2cr);
 
-	result = i2c_imx_bus_busy(1);
-	if (result)
+	result = wait_for_sr_state(i2c_regs, ST_BUS_BUSY);
+	if (result < 0)
 		return result;
 
 	temp |= I2CR_MTX | I2CR_TX_NO_AK;
@@ -260,6 +237,7 @@ int i2c_imx_start(void)
  */
 void i2c_imx_stop(void)
 {
+	int ret;
 	struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)I2C_BASE;
 	unsigned int temp = 0;
 
@@ -268,8 +246,9 @@ void i2c_imx_stop(void)
 	temp &= ~(I2CR_MSTA | I2CR_MTX);
 	writeb(temp, &i2c_regs->i2cr);
 
-	i2c_imx_bus_busy(0);
-
+	ret = wait_for_sr_state(i2c_regs, ST_BUS_IDLE);
+	if (ret < 0)
+		printf("%s:trigger stop failed\n", __func__);
 	/* Disable I2C controller */
 	writeb(0, &i2c_regs->i2cr);
 }
@@ -336,8 +315,8 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len)
 
 	/* read data */
 	for (i = 0; i < len; i++) {
-		ret = i2c_imx_trx_complete();
-		if (ret) {
+		ret = wait_for_sr_state(i2c_regs, ST_IIF);
+		if (ret < 0) {
 			i2c_imx_stop();
 			return ret;
 		}
@@ -350,20 +329,19 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len)
 			temp = readb(&i2c_regs->i2cr);
 			temp &= ~(I2CR_MSTA | I2CR_MTX);
 			writeb(temp, &i2c_regs->i2cr);
-			i2c_imx_bus_busy(0);
+			wait_for_sr_state(i2c_regs, ST_BUS_IDLE);
 		} else if (i == (len - 2)) {
 			temp = readb(&i2c_regs->i2cr);
 			temp |= I2CR_TX_NO_AK;
 			writeb(temp, &i2c_regs->i2cr);
 		}
-
 		writeb(0, &i2c_regs->i2sr);
 		buf[i] = readb(&i2c_regs->i2dr);
 	}
 
 	i2c_imx_stop();
 
-	return ret;
+	return 0;
 }
 
 /*
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH V2 09/25] mxc_i2c: remove redundant read
  2012-07-05 19:53 [U-Boot] [PATCH V2 01/25] mxc_i2c: fix i2c_imx_stop Troy Kisky
                   ` (6 preceding siblings ...)
  2012-07-05 19:53 ` [U-Boot] [PATCH V2 08/25] mxc_i2c: combine i2c_imx_bus_busy and i2c_imx_trx_complete into wait_for_sr_state Troy Kisky
@ 2012-07-05 19:53 ` Troy Kisky
  2012-07-05 19:53 ` [U-Boot] [PATCH V2 10/25] mxc_i2c: place imx_start code inline Troy Kisky
                   ` (17 subsequent siblings)
  25 siblings, 0 replies; 33+ messages in thread
From: Troy Kisky @ 2012-07-05 19:53 UTC (permalink / raw)
  To: u-boot

wait_for_sr_state returns i2sr on success
so no need to read again.

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
Acked-by: Marek Vasut <marex@denx.de>

---
v2: add ack
---
 drivers/i2c/mxc_i2c.c |    1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c
index 01a6408..83c2fab 100644
--- a/drivers/i2c/mxc_i2c.c
+++ b/drivers/i2c/mxc_i2c.c
@@ -195,7 +195,6 @@ static int tx_byte(struct mxc_i2c_regs *i2c_regs, u8 byte)
 	ret = wait_for_sr_state(i2c_regs, ST_IIF);
 	if (ret < 0)
 		return ret;
-	ret = readb(&i2c_regs->i2sr);
 	if (ret & I2SR_RX_NO_AK)
 		return -ENODEV;
 	return 0;
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH V2 10/25] mxc_i2c: place imx_start code inline
  2012-07-05 19:53 [U-Boot] [PATCH V2 01/25] mxc_i2c: fix i2c_imx_stop Troy Kisky
                   ` (7 preceding siblings ...)
  2012-07-05 19:53 ` [U-Boot] [PATCH V2 09/25] mxc_i2c: remove redundant read Troy Kisky
@ 2012-07-05 19:53 ` Troy Kisky
  2012-07-05 19:53 ` [U-Boot] [PATCH V2 11/25] mxc_i2c: place i2c_reset " Troy Kisky
                   ` (16 subsequent siblings)
  25 siblings, 0 replies; 33+ messages in thread
From: Troy Kisky @ 2012-07-05 19:53 UTC (permalink / raw)
  To: u-boot

imx_start is only referenced once so
move to that location.

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
Acked-by: Marek Vasut <marex@denx.de>

---
v2: add ack
---
 drivers/i2c/mxc_i2c.c |   53 +++++++++++++++++++------------------------------
 1 file changed, 20 insertions(+), 33 deletions(-)

diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c
index 83c2fab..9efa9bd 100644
--- a/drivers/i2c/mxc_i2c.c
+++ b/drivers/i2c/mxc_i2c.c
@@ -201,37 +201,6 @@ static int tx_byte(struct mxc_i2c_regs *i2c_regs, u8 byte)
 }
 
 /*
- * Start the controller
- */
-int i2c_imx_start(void)
-{
-	struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)I2C_BASE;
-	unsigned int temp = 0;
-	int result;
-
-	/* Enable I2C controller */
-	writeb(0, &i2c_regs->i2sr);
-	writeb(I2CR_IEN, &i2c_regs->i2cr);
-
-	/* Wait controller to be stable */
-	udelay(50);
-
-	/* Start I2C transaction */
-	temp = readb(&i2c_regs->i2cr);
-	temp |= I2CR_MSTA;
-	writeb(temp, &i2c_regs->i2cr);
-
-	result = wait_for_sr_state(i2c_regs, ST_BUS_BUSY);
-	if (result < 0)
-		return result;
-
-	temp |= I2CR_MTX | I2CR_TX_NO_AK;
-	writeb(temp, &i2c_regs->i2cr);
-
-	return 0;
-}
-
-/*
  * Stop the controller
  */
 void i2c_imx_stop(void)
@@ -259,10 +228,28 @@ void i2c_imx_stop(void)
 static int i2c_init_transfer(struct mxc_i2c_regs *i2c_regs,
 		uchar chip, uint addr, int alen)
 {
-	int ret = i2c_imx_start();
-	if (ret)
+	unsigned int temp;
+	int ret;
+
+	/* Enable I2C controller */
+	writeb(0, &i2c_regs->i2sr);
+	writeb(I2CR_IEN, &i2c_regs->i2cr);
+
+	/* Wait for controller to be stable */
+	udelay(50);
+
+	/* Start I2C transaction */
+	temp = readb(&i2c_regs->i2cr);
+	temp |= I2CR_MSTA;
+	writeb(temp, &i2c_regs->i2cr);
+
+	ret = wait_for_sr_state(i2c_regs, ST_BUS_BUSY);
+	if (ret < 0)
 		goto exit;
 
+	temp |= I2CR_MTX | I2CR_TX_NO_AK;
+	writeb(temp, &i2c_regs->i2cr);
+
 	/* write slave address */
 	ret = tx_byte(i2c_regs, chip << 1);
 	if (ret < 0)
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH V2 11/25] mxc_i2c: place i2c_reset code inline
  2012-07-05 19:53 [U-Boot] [PATCH V2 01/25] mxc_i2c: fix i2c_imx_stop Troy Kisky
                   ` (8 preceding siblings ...)
  2012-07-05 19:53 ` [U-Boot] [PATCH V2 10/25] mxc_i2c: place imx_start code inline Troy Kisky
@ 2012-07-05 19:53 ` Troy Kisky
  2012-07-05 19:53 ` [U-Boot] [PATCH V2 12/25] mxc_i2c: don't disable controller after every transaction Troy Kisky
                   ` (15 subsequent siblings)
  25 siblings, 0 replies; 33+ messages in thread
From: Troy Kisky @ 2012-07-05 19:53 UTC (permalink / raw)
  To: u-boot

imx_reset is only referenced once so
move to that location.

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
Acked-by: Marek Vasut <marex@denx.de>

---
v2: add ack
---
 drivers/i2c/mxc_i2c.c |   15 +++------------
 1 file changed, 3 insertions(+), 12 deletions(-)

diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c
index 9efa9bd..717bc7a 100644
--- a/drivers/i2c/mxc_i2c.c
+++ b/drivers/i2c/mxc_i2c.c
@@ -114,17 +114,6 @@ static uint8_t i2c_imx_get_clk(unsigned int rate)
 }
 
 /*
- * Reset I2C Controller
- */
-void i2c_reset(void)
-{
-	struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)I2C_BASE;
-
-	writeb(0, &i2c_regs->i2cr);	/* Reset module */
-	writeb(0, &i2c_regs->i2sr);
-}
-
-/*
  * Init I2C Bus
  */
 void i2c_init(int speed, int unused)
@@ -136,7 +125,9 @@ void i2c_init(int speed, int unused)
 	/* Store divider value */
 	writeb(idx, &i2c_regs->ifdr);
 
-	i2c_reset();
+	/* Reset module */
+	writeb(0, &i2c_regs->i2cr);
+	writeb(0, &i2c_regs->i2sr);
 }
 
 /*
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH V2 12/25] mxc_i2c: don't disable controller after every transaction
  2012-07-05 19:53 [U-Boot] [PATCH V2 01/25] mxc_i2c: fix i2c_imx_stop Troy Kisky
                   ` (9 preceding siblings ...)
  2012-07-05 19:53 ` [U-Boot] [PATCH V2 11/25] mxc_i2c: place i2c_reset " Troy Kisky
@ 2012-07-05 19:53 ` Troy Kisky
  2012-07-05 19:53 ` [U-Boot] [PATCH V2 13/25] mxc_i2c: change slave addr if conflicts with destination Troy Kisky
                   ` (14 subsequent siblings)
  25 siblings, 0 replies; 33+ messages in thread
From: Troy Kisky @ 2012-07-05 19:53 UTC (permalink / raw)
  To: u-boot

This helps in a multiple bus master environment which
is why I also added a wait for bus idle.

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>

---
v2: no change
---
 drivers/i2c/mxc_i2c.c |   28 +++++++++++++---------------
 1 file changed, 13 insertions(+), 15 deletions(-)

diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c
index 717bc7a..1a5e379 100644
--- a/drivers/i2c/mxc_i2c.c
+++ b/drivers/i2c/mxc_i2c.c
@@ -192,24 +192,19 @@ static int tx_byte(struct mxc_i2c_regs *i2c_regs, u8 byte)
 }
 
 /*
- * Stop the controller
+ * Stop I2C transaction
  */
 void i2c_imx_stop(void)
 {
 	int ret;
 	struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)I2C_BASE;
-	unsigned int temp = 0;
+	unsigned int temp = readb(&i2c_regs->i2cr);
 
-	/* Stop I2C transaction */
-	temp = readb(&i2c_regs->i2cr);
 	temp &= ~(I2CR_MSTA | I2CR_MTX);
 	writeb(temp, &i2c_regs->i2cr);
-
 	ret = wait_for_sr_state(i2c_regs, ST_BUS_IDLE);
 	if (ret < 0)
 		printf("%s:trigger stop failed\n", __func__);
-	/* Disable I2C controller */
-	writeb(0, &i2c_regs->i2cr);
 }
 
 /*
@@ -223,11 +218,15 @@ static int i2c_init_transfer(struct mxc_i2c_regs *i2c_regs,
 	int ret;
 
 	/* Enable I2C controller */
+	if (!(readb(&i2c_regs->i2cr) & I2CR_IEN)) {
+		writeb(I2CR_IEN, &i2c_regs->i2cr);
+		/* Wait for controller to be stable */
+		udelay(50);
+	}
 	writeb(0, &i2c_regs->i2sr);
-	writeb(I2CR_IEN, &i2c_regs->i2cr);
-
-	/* Wait for controller to be stable */
-	udelay(50);
+	ret = wait_for_sr_state(i2c_regs, ST_BUS_IDLE);
+	if (ret < 0)
+		goto exit;
 
 	/* Start I2C transaction */
 	temp = readb(&i2c_regs->i2cr);
@@ -254,6 +253,8 @@ static int i2c_init_transfer(struct mxc_i2c_regs *i2c_regs,
 	return 0;
 exit:
 	i2c_imx_stop();
+	/* Disable I2C controller */
+	writeb(0, &i2c_regs->i2cr);
 	return ret;
 }
 
@@ -303,10 +304,7 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len)
 		 * controller from generating another clock cycle
 		 */
 		if (i == (len - 1)) {
-			temp = readb(&i2c_regs->i2cr);
-			temp &= ~(I2CR_MSTA | I2CR_MTX);
-			writeb(temp, &i2c_regs->i2cr);
-			wait_for_sr_state(i2c_regs, ST_BUS_IDLE);
+			i2c_imx_stop();
 		} else if (i == (len - 2)) {
 			temp = readb(&i2c_regs->i2cr);
 			temp |= I2CR_TX_NO_AK;
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH V2 13/25] mxc_i2c: change slave addr if conflicts with destination.
  2012-07-05 19:53 [U-Boot] [PATCH V2 01/25] mxc_i2c: fix i2c_imx_stop Troy Kisky
                   ` (10 preceding siblings ...)
  2012-07-05 19:53 ` [U-Boot] [PATCH V2 12/25] mxc_i2c: don't disable controller after every transaction Troy Kisky
@ 2012-07-05 19:53 ` Troy Kisky
  2012-07-05 19:53 ` [U-Boot] [PATCH V2 14/25] mxc_i2c: check for arbitration lost Troy Kisky
                   ` (13 subsequent siblings)
  25 siblings, 0 replies; 33+ messages in thread
From: Troy Kisky @ 2012-07-05 19:53 UTC (permalink / raw)
  To: u-boot

The i2c controller cannot be both master and slave in the
same transaction.

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>

---
v2: no change
---
 drivers/i2c/mxc_i2c.c |    2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c
index 1a5e379..ba2aad3 100644
--- a/drivers/i2c/mxc_i2c.c
+++ b/drivers/i2c/mxc_i2c.c
@@ -223,6 +223,8 @@ static int i2c_init_transfer(struct mxc_i2c_regs *i2c_regs,
 		/* Wait for controller to be stable */
 		udelay(50);
 	}
+	if (readb(&i2c_regs->iadr) == (chip << 1))
+		writeb((chip << 1) ^ 2, &i2c_regs->iadr);
 	writeb(0, &i2c_regs->i2sr);
 	ret = wait_for_sr_state(i2c_regs, ST_BUS_IDLE);
 	if (ret < 0)
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH V2 14/25] mxc_i2c: check for arbitration lost
  2012-07-05 19:53 [U-Boot] [PATCH V2 01/25] mxc_i2c: fix i2c_imx_stop Troy Kisky
                   ` (11 preceding siblings ...)
  2012-07-05 19:53 ` [U-Boot] [PATCH V2 13/25] mxc_i2c: change slave addr if conflicts with destination Troy Kisky
@ 2012-07-05 19:53 ` Troy Kisky
  2012-07-05 19:53 ` [U-Boot] [PATCH V2 15/25] mxc_i2c: add retries Troy Kisky
                   ` (12 subsequent siblings)
  25 siblings, 0 replies; 33+ messages in thread
From: Troy Kisky @ 2012-07-05 19:53 UTC (permalink / raw)
  To: u-boot

No need to continue waiting if arbitration lost.

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
Acked-by: Marek Vasut <marex@denx.de>

---
v2: add ack
---
 drivers/i2c/mxc_i2c.c |    7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c
index ba2aad3..093a73f 100644
--- a/drivers/i2c/mxc_i2c.c
+++ b/drivers/i2c/mxc_i2c.c
@@ -55,6 +55,7 @@ struct mxc_i2c_regs {
 
 #define I2SR_ICF	(1 << 7)
 #define I2SR_IBB	(1 << 5)
+#define I2SR_IAL	(1 << 4)
 #define I2SR_IIF	(1 << 1)
 #define I2SR_RX_NO_AK	(1 << 0)
 
@@ -165,6 +166,12 @@ static int wait_for_sr_state(struct mxc_i2c_regs *i2c_regs, unsigned state)
 	ulong start_time = get_timer(0);
 	for (;;) {
 		sr = readb(&i2c_regs->i2sr);
+		if (sr & I2SR_IAL) {
+			writeb(sr & ~I2SR_IAL, &i2c_regs->i2sr);
+			printf("%s: Arbitration lost sr=%x cr=%x state=%x\n",
+				__func__, sr, readb(&i2c_regs->i2cr), state);
+			return -ERESTART;
+		}
 		if ((sr & (state >> 8)) == (unsigned char)state)
 			return sr;
 		WATCHDOG_RESET();
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH V2 15/25] mxc_i2c: add retries
  2012-07-05 19:53 [U-Boot] [PATCH V2 01/25] mxc_i2c: fix i2c_imx_stop Troy Kisky
                   ` (12 preceding siblings ...)
  2012-07-05 19:53 ` [U-Boot] [PATCH V2 14/25] mxc_i2c: check for arbitration lost Troy Kisky
@ 2012-07-05 19:53 ` Troy Kisky
  2012-07-05 19:53 ` [U-Boot] [PATCH V2 16/25] mxc_i2c: add i2c_regs argument to i2c_imx_stop Troy Kisky
                   ` (11 subsequent siblings)
  25 siblings, 0 replies; 33+ messages in thread
From: Troy Kisky @ 2012-07-05 19:53 UTC (permalink / raw)
  To: u-boot

Retry unexpected hardware errors. This
will not retry a received NAK.

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>

---
v2: if i2c_init_transfer_ returns no error, then return 0
---
 drivers/i2c/mxc_i2c.c |   36 +++++++++++++++++++++++++++---------
 1 file changed, 27 insertions(+), 9 deletions(-)

diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c
index 093a73f..cbb0fff 100644
--- a/drivers/i2c/mxc_i2c.c
+++ b/drivers/i2c/mxc_i2c.c
@@ -218,7 +218,7 @@ void i2c_imx_stop(void)
  * Send start signal, chip address and
  * write register address
  */
-static int i2c_init_transfer(struct mxc_i2c_regs *i2c_regs,
+static int i2c_init_transfer_(struct mxc_i2c_regs *i2c_regs,
 		uchar chip, uint addr, int alen)
 {
 	unsigned int temp;
@@ -235,7 +235,7 @@ static int i2c_init_transfer(struct mxc_i2c_regs *i2c_regs,
 	writeb(0, &i2c_regs->i2sr);
 	ret = wait_for_sr_state(i2c_regs, ST_BUS_IDLE);
 	if (ret < 0)
-		goto exit;
+		return ret;
 
 	/* Start I2C transaction */
 	temp = readb(&i2c_regs->i2cr);
@@ -244,7 +244,7 @@ static int i2c_init_transfer(struct mxc_i2c_regs *i2c_regs,
 
 	ret = wait_for_sr_state(i2c_regs, ST_BUS_BUSY);
 	if (ret < 0)
-		goto exit;
+		return ret;
 
 	temp |= I2CR_MTX | I2CR_TX_NO_AK;
 	writeb(temp, &i2c_regs->i2cr);
@@ -252,18 +252,36 @@ static int i2c_init_transfer(struct mxc_i2c_regs *i2c_regs,
 	/* write slave address */
 	ret = tx_byte(i2c_regs, chip << 1);
 	if (ret < 0)
-		goto exit;
+		return ret;
 
 	while (alen--) {
 		ret = tx_byte(i2c_regs, (addr >> (alen * 8)) & 0xff);
 		if (ret < 0)
-			goto exit;
+			return ret;
 	}
 	return 0;
-exit:
-	i2c_imx_stop();
-	/* Disable I2C controller */
-	writeb(0, &i2c_regs->i2cr);
+}
+
+static int i2c_init_transfer(struct mxc_i2c_regs *i2c_regs,
+		uchar chip, uint addr, int alen)
+{
+	int retry;
+	int ret;
+	for (retry = 0; retry < 3; retry++) {
+		ret = i2c_init_transfer_(i2c_regs, chip, addr, alen);
+		if (ret >= 0)
+			return 0;
+		i2c_imx_stop();
+		if (ret == -ENODEV)
+			return ret;
+
+		printf("%s: failed for chip 0x%x retry=%d\n", __func__, chip,
+				retry);
+		if (ret != -ERESTART)
+			writeb(0, &i2c_regs->i2cr);	/* Disable controller */
+		udelay(100);
+	}
+	printf("%s: give up i2c_regs=%p\n", __func__, i2c_regs);
 	return ret;
 }
 
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH V2 16/25] mxc_i2c: add i2c_regs argument to i2c_imx_stop
  2012-07-05 19:53 [U-Boot] [PATCH V2 01/25] mxc_i2c: fix i2c_imx_stop Troy Kisky
                   ` (13 preceding siblings ...)
  2012-07-05 19:53 ` [U-Boot] [PATCH V2 15/25] mxc_i2c: add retries Troy Kisky
@ 2012-07-05 19:53 ` Troy Kisky
  2012-07-05 19:53 ` [U-Boot] [PATCH V2 17/25] mxc_i2c: prep work for multiple busses support Troy Kisky
                   ` (10 subsequent siblings)
  25 siblings, 0 replies; 33+ messages in thread
From: Troy Kisky @ 2012-07-05 19:53 UTC (permalink / raw)
  To: u-boot

This is prep work for CONFIG_I2C_MULTI_BUS.

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
Acked-by: Marek Vasut <marex@denx.de>

---
v2: add ack
---
 drivers/i2c/mxc_i2c.c |   19 +++++++------------
 1 file changed, 7 insertions(+), 12 deletions(-)

diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c
index cbb0fff..44a04b5 100644
--- a/drivers/i2c/mxc_i2c.c
+++ b/drivers/i2c/mxc_i2c.c
@@ -201,10 +201,9 @@ static int tx_byte(struct mxc_i2c_regs *i2c_regs, u8 byte)
 /*
  * Stop I2C transaction
  */
-void i2c_imx_stop(void)
+static void i2c_imx_stop(struct mxc_i2c_regs *i2c_regs)
 {
 	int ret;
-	struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)I2C_BASE;
 	unsigned int temp = readb(&i2c_regs->i2cr);
 
 	temp &= ~(I2CR_MSTA | I2CR_MTX);
@@ -271,7 +270,7 @@ static int i2c_init_transfer(struct mxc_i2c_regs *i2c_regs,
 		ret = i2c_init_transfer_(i2c_regs, chip, addr, alen);
 		if (ret >= 0)
 			return 0;
-		i2c_imx_stop();
+		i2c_imx_stop(i2c_regs);
 		if (ret == -ENODEV)
 			return ret;
 
@@ -305,7 +304,7 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len)
 
 	ret = tx_byte(i2c_regs, (chip << 1) | 1);
 	if (ret < 0) {
-		i2c_imx_stop();
+		i2c_imx_stop(i2c_regs);
 		return ret;
 	}
 
@@ -322,7 +321,7 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len)
 	for (i = 0; i < len; i++) {
 		ret = wait_for_sr_state(i2c_regs, ST_IIF);
 		if (ret < 0) {
-			i2c_imx_stop();
+			i2c_imx_stop(i2c_regs);
 			return ret;
 		}
 
@@ -331,7 +330,7 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len)
 		 * controller from generating another clock cycle
 		 */
 		if (i == (len - 1)) {
-			i2c_imx_stop();
+			i2c_imx_stop(i2c_regs);
 		} else if (i == (len - 2)) {
 			temp = readb(&i2c_regs->i2cr);
 			temp |= I2CR_TX_NO_AK;
@@ -340,9 +339,7 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len)
 		writeb(0, &i2c_regs->i2sr);
 		buf[i] = readb(&i2c_regs->i2dr);
 	}
-
-	i2c_imx_stop();
-
+	i2c_imx_stop(i2c_regs);
 	return 0;
 }
 
@@ -364,9 +361,7 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len)
 		if (ret < 0)
 			break;
 	}
-
-	i2c_imx_stop();
-
+	i2c_imx_stop(i2c_regs);
 	return ret;
 }
 
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH V2 17/25] mxc_i2c: prep work for multiple busses support
  2012-07-05 19:53 [U-Boot] [PATCH V2 01/25] mxc_i2c: fix i2c_imx_stop Troy Kisky
                   ` (14 preceding siblings ...)
  2012-07-05 19:53 ` [U-Boot] [PATCH V2 16/25] mxc_i2c: add i2c_regs argument to i2c_imx_stop Troy Kisky
@ 2012-07-05 19:53 ` Troy Kisky
  2012-07-05 19:53 ` [U-Boot] [PATCH V2 18/25] mxc_i2c: add bus recovery support Troy Kisky
                   ` (9 subsequent siblings)
  25 siblings, 0 replies; 33+ messages in thread
From: Troy Kisky @ 2012-07-05 19:53 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>

---
v2: moved global data to static ram section available before ram
is initialized and removed typedef as suggested by Marek Vasut
and Heiko Schocher

make toggle_fn return int.
---
 drivers/i2c/mxc_i2c.c |  125 ++++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 104 insertions(+), 21 deletions(-)

diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c
index 44a04b5..d5448d8 100644
--- a/drivers/i2c/mxc_i2c.c
+++ b/drivers/i2c/mxc_i2c.c
@@ -59,9 +59,7 @@ struct mxc_i2c_regs {
 #define I2SR_IIF	(1 << 1)
 #define I2SR_RX_NO_AK	(1 << 0)
 
-#ifdef CONFIG_SYS_I2C_BASE
-#define I2C_BASE	CONFIG_SYS_I2C_BASE
-#else
+#if defined(CONFIG_HARD_I2C) && !defined(CONFIG_SYS_I2C_BASE)
 #error "define CONFIG_SYS_I2C_BASE to use the mxc_i2c driver"
 #endif
 
@@ -115,11 +113,11 @@ static uint8_t i2c_imx_get_clk(unsigned int rate)
 }
 
 /*
- * Init I2C Bus
+ * Set I2C Bus speed
  */
-void i2c_init(int speed, int unused)
+int bus_i2c_set_bus_speed(void *base, int speed)
 {
-	struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)I2C_BASE;
+	struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)base;
 	u8 clk_idx = i2c_imx_get_clk(speed);
 	u8 idx = i2c_clk_div[clk_idx][1];
 
@@ -129,23 +127,15 @@ void i2c_init(int speed, int unused)
 	/* Reset module */
 	writeb(0, &i2c_regs->i2cr);
 	writeb(0, &i2c_regs->i2sr);
-}
-
-/*
- * Set I2C Speed
- */
-int i2c_set_bus_speed(unsigned int speed)
-{
-	i2c_init(speed, 0);
 	return 0;
 }
 
 /*
  * Get I2C Speed
  */
-unsigned int i2c_get_bus_speed(void)
+unsigned int bus_i2c_get_bus_speed(void *base)
 {
-	struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)I2C_BASE;
+	struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)base;
 	u8 clk_idx = readb(&i2c_regs->ifdr);
 	u8 clk_div;
 
@@ -287,12 +277,13 @@ static int i2c_init_transfer(struct mxc_i2c_regs *i2c_regs,
 /*
  * Read data from I2C device
  */
-int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len)
+int bus_i2c_read(void *base, uchar chip, uint addr, int alen, uchar *buf,
+		int len)
 {
-	struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)I2C_BASE;
 	int ret;
 	unsigned int temp;
 	int i;
+	struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)base;
 
 	ret = i2c_init_transfer(i2c_regs, chip, addr, alen);
 	if (ret < 0)
@@ -346,11 +337,12 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len)
 /*
  * Write data to I2C device
  */
-int i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len)
+int bus_i2c_write(void *base, uchar chip, uint addr, int alen,
+		const uchar *buf, int len)
 {
-	struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)I2C_BASE;
 	int ret;
 	int i;
+	struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)base;
 
 	ret = i2c_init_transfer(i2c_regs, chip, addr, alen);
 	if (ret < 0)
@@ -365,10 +357,101 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len)
 	return ret;
 }
 
+struct i2c_parms {
+	void *base;
+	void *toggle_data;
+	int (*toggle_fn)(void *p);
+};
+
+struct sram_data {
+	unsigned curr_i2c_bus;
+	struct i2c_parms i2c_data[3];
+};
+
+/*
+ * For SPL boot some boards need i2c before SDRAM is initialized so force
+ * variables to live in SRAM
+ */
+static struct sram_data __attribute__((section(".data"))) srdata;
+
+void *get_base(void)
+{
+#ifdef CONFIG_SYS_I2C_BASE
+#ifdef CONFIG_I2C_MULTI_BUS
+	void *ret = srdata.i2c_data[srdata.curr_i2c_bus].base;
+	if (ret)
+		return ret;
+#endif
+	return (void *)CONFIG_SYS_I2C_BASE;
+#elif defined(CONFIG_I2C_MULTI_BUS)
+	return srdata.i2c_data[srdata.curr_i2c_bus].base;
+#else
+	return srdata.i2c_data[0].base;
+#endif
+}
+
+int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len)
+{
+	return bus_i2c_read(get_base(), chip, addr, alen, buf, len);
+}
+
+int i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len)
+{
+	return bus_i2c_write(get_base(), chip, addr, alen, buf, len);
+}
+
 /*
  * Test if a chip@a given address responds (probe the chip)
  */
 int i2c_probe(uchar chip)
 {
-	return i2c_write(chip, 0, 0, NULL, 0);
+	return bus_i2c_write(get_base(), chip, 0, 0, NULL, 0);
+}
+
+void bus_i2c_init(void *base, int speed, int unused,
+		int (*toggle_fn)(void *p), void *toggle_data)
+{
+	int i = 0;
+	struct i2c_parms *p = srdata.i2c_data;
+	if (!base)
+		return;
+	for (;;) {
+		if (!p->base || (p->base == base)) {
+			p->base = base;
+			if (toggle_fn) {
+				p->toggle_fn = toggle_fn;
+				p->toggle_data = toggle_data;
+			}
+			break;
+		}
+		p++;
+		i++;
+		if (i >= ARRAY_SIZE(srdata.i2c_data))
+			return;
+	}
+	bus_i2c_set_bus_speed(base, speed);
+}
+
+/*
+ * Init I2C Bus
+ */
+void i2c_init(int speed, int unused)
+{
+	bus_i2c_init(get_base(), speed, unused, NULL, NULL);
+}
+
+/*
+ * Set I2C Speed
+ */
+int i2c_set_bus_speed(unsigned int speed)
+{
+	return bus_i2c_set_bus_speed(get_base(), speed);
+}
+
+/*
+ * Get I2C Speed
+ */
+unsigned int i2c_get_bus_speed(void)
+{
+	return bus_i2c_get_bus_speed(get_base());
 }
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH V2 18/25] mxc_i2c: add bus recovery support
  2012-07-05 19:53 [U-Boot] [PATCH V2 01/25] mxc_i2c: fix i2c_imx_stop Troy Kisky
                   ` (15 preceding siblings ...)
  2012-07-05 19:53 ` [U-Boot] [PATCH V2 17/25] mxc_i2c: prep work for multiple busses support Troy Kisky
@ 2012-07-05 19:53 ` Troy Kisky
  2012-07-05 19:53 ` [U-Boot] [PATCH V2 19/25] mxc_i2c: finish adding CONFIG_I2C_MULTI_BUS support Troy Kisky
                   ` (8 subsequent siblings)
  25 siblings, 0 replies; 33+ messages in thread
From: Troy Kisky @ 2012-07-05 19:53 UTC (permalink / raw)
  To: u-boot

Add support for calling a function that will toggle the
SCL line to return the bus to idle condition.

The actual toggling function is added in a later patch.

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>

---
v2: commit log change, global data in sram section.
make toggle_i2c return int
---
 drivers/i2c/mxc_i2c.c |   26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c
index d5448d8..41849d3 100644
--- a/drivers/i2c/mxc_i2c.c
+++ b/drivers/i2c/mxc_i2c.c
@@ -251,6 +251,8 @@ static int i2c_init_transfer_(struct mxc_i2c_regs *i2c_regs,
 	return 0;
 }
 
+static int toggle_i2c(void *base);
+
 static int i2c_init_transfer(struct mxc_i2c_regs *i2c_regs,
 		uchar chip, uint addr, int alen)
 {
@@ -269,6 +271,8 @@ static int i2c_init_transfer(struct mxc_i2c_regs *i2c_regs,
 		if (ret != -ERESTART)
 			writeb(0, &i2c_regs->i2cr);	/* Disable controller */
 		udelay(100);
+		if (toggle_i2c(i2c_regs) < 0)
+			break;
 	}
 	printf("%s: give up i2c_regs=%p\n", __func__, i2c_regs);
 	return ret;
@@ -390,6 +394,28 @@ void *get_base(void)
 #endif
 }
 
+static struct i2c_parms *i2c_get_parms(void *base)
+{
+	int i = 0;
+	struct i2c_parms *p = srdata.i2c_data;
+	while (i < ARRAY_SIZE(srdata.i2c_data)) {
+		if (p->base == base)
+			return p;
+		p++;
+		i++;
+	}
+	printf("Invalid I2C base: %p\n", base);
+	return NULL;
+}
+
+static int toggle_i2c(void *base)
+{
+	struct i2c_parms *p = i2c_get_parms(base);
+	if (p && p->toggle_fn)
+		return p->toggle_fn(p->toggle_data);
+	return 0;
+}
+
 int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len)
 {
 	return bus_i2c_read(get_base(), chip, addr, alen, buf, len);
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH V2 19/25] mxc_i2c: finish adding CONFIG_I2C_MULTI_BUS support
  2012-07-05 19:53 [U-Boot] [PATCH V2 01/25] mxc_i2c: fix i2c_imx_stop Troy Kisky
                   ` (16 preceding siblings ...)
  2012-07-05 19:53 ` [U-Boot] [PATCH V2 18/25] mxc_i2c: add bus recovery support Troy Kisky
@ 2012-07-05 19:53 ` Troy Kisky
  2012-07-05 19:53 ` [U-Boot] [PATCH V2 20/25] iomux-v3: remove include of mx6x_pins.h Troy Kisky
                   ` (7 subsequent siblings)
  25 siblings, 0 replies; 33+ messages in thread
From: Troy Kisky @ 2012-07-05 19:53 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>

---
v2: global data in sram section
---
 drivers/i2c/mxc_i2c.c |   17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c
index 41849d3..2017399 100644
--- a/drivers/i2c/mxc_i2c.c
+++ b/drivers/i2c/mxc_i2c.c
@@ -416,6 +416,23 @@ static int toggle_i2c(void *base)
 	return 0;
 }
 
+#ifdef CONFIG_I2C_MULTI_BUS
+unsigned int i2c_get_bus_num(void)
+{
+	return srdata.curr_i2c_bus;
+}
+
+int i2c_set_bus_num(unsigned bus_idx)
+{
+	if (bus_idx >= ARRAY_SIZE(srdata.i2c_data))
+		return -1;
+	if (!srdata.i2c_data[bus_idx].base)
+		return -1;
+	srdata.curr_i2c_bus = bus_idx;
+	return 0;
+}
+#endif
+
 int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len)
 {
 	return bus_i2c_read(get_base(), chip, addr, alen, buf, len);
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH V2 20/25] iomux-v3: remove include of mx6x_pins.h
  2012-07-05 19:53 [U-Boot] [PATCH V2 01/25] mxc_i2c: fix i2c_imx_stop Troy Kisky
                   ` (17 preceding siblings ...)
  2012-07-05 19:53 ` [U-Boot] [PATCH V2 19/25] mxc_i2c: finish adding CONFIG_I2C_MULTI_BUS support Troy Kisky
@ 2012-07-05 19:53 ` Troy Kisky
  2012-07-05 19:53 ` [U-Boot] [PATCH V2 21/25] i.mx: iomux-v3.h: move to imx-common include directory Troy Kisky
                   ` (6 subsequent siblings)
  25 siblings, 0 replies; 33+ messages in thread
From: Troy Kisky @ 2012-07-05 19:53 UTC (permalink / raw)
  To: u-boot

This include is not needed.

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>

---
v2: no change
---
 arch/arm/cpu/armv7/mx6/iomux-v3.c |    1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/cpu/armv7/mx6/iomux-v3.c b/arch/arm/cpu/armv7/mx6/iomux-v3.c
index 8785532..a0c4b15 100644
--- a/arch/arm/cpu/armv7/mx6/iomux-v3.c
+++ b/arch/arm/cpu/armv7/mx6/iomux-v3.c
@@ -23,7 +23,6 @@
 #include <common.h>
 #include <asm/io.h>
 #include <asm/arch/imx-regs.h>
-#include <asm/arch/mx6x_pins.h>
 #include <asm/arch/iomux-v3.h>
 
 static void *base = (void *)IOMUXC_BASE_ADDR;
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH V2 21/25] i.mx: iomux-v3.h: move to imx-common include directory
  2012-07-05 19:53 [U-Boot] [PATCH V2 01/25] mxc_i2c: fix i2c_imx_stop Troy Kisky
                   ` (18 preceding siblings ...)
  2012-07-05 19:53 ` [U-Boot] [PATCH V2 20/25] iomux-v3: remove include of mx6x_pins.h Troy Kisky
@ 2012-07-05 19:53 ` Troy Kisky
  2012-07-05 19:54 ` [U-Boot] [PATCH V2 22/25] i.mx: iomux-v3.c: move to imx-common directory Troy Kisky
                   ` (5 subsequent siblings)
  25 siblings, 0 replies; 33+ messages in thread
From: Troy Kisky @ 2012-07-05 19:53 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>

---
v2: no change
---
 arch/arm/cpu/armv7/mx6/iomux-v3.c                  |    2 +-
 arch/arm/include/asm/arch-mx6/mx6x_pins.h          |    2 +-
 .../asm/{arch-mx6 => imx-common}/iomux-v3.h        |    0
 board/freescale/mx6qarm2/mx6qarm2.c                |    2 +-
 board/freescale/mx6qsabrelite/mx6qsabrelite.c      |    2 +-
 drivers/usb/host/ehci-mx6.c                        |    2 +-
 6 files changed, 5 insertions(+), 5 deletions(-)
 rename arch/arm/include/asm/{arch-mx6 => imx-common}/iomux-v3.h (100%)

diff --git a/arch/arm/cpu/armv7/mx6/iomux-v3.c b/arch/arm/cpu/armv7/mx6/iomux-v3.c
index a0c4b15..da093fb 100644
--- a/arch/arm/cpu/armv7/mx6/iomux-v3.c
+++ b/arch/arm/cpu/armv7/mx6/iomux-v3.c
@@ -23,7 +23,7 @@
 #include <common.h>
 #include <asm/io.h>
 #include <asm/arch/imx-regs.h>
-#include <asm/arch/iomux-v3.h>
+#include <asm/imx-common/iomux-v3.h>
 
 static void *base = (void *)IOMUXC_BASE_ADDR;
 
diff --git a/arch/arm/include/asm/arch-mx6/mx6x_pins.h b/arch/arm/include/asm/arch-mx6/mx6x_pins.h
index afaa068..c0bb494 100644
--- a/arch/arm/include/asm/arch-mx6/mx6x_pins.h
+++ b/arch/arm/include/asm/arch-mx6/mx6x_pins.h
@@ -22,7 +22,7 @@
 #ifndef __ASM_ARCH_MX6_MX6X_PINS_H__
 #define __ASM_ARCH_MX6_MX6X_PINS_H__
 
-#include <asm/arch/iomux-v3.h>
+#include <asm/imx-common/iomux-v3.h>
 
 /* Use to set PAD control */
 #define PAD_CTL_HYS		(1 << 16)
diff --git a/arch/arm/include/asm/arch-mx6/iomux-v3.h b/arch/arm/include/asm/imx-common/iomux-v3.h
similarity index 100%
rename from arch/arm/include/asm/arch-mx6/iomux-v3.h
rename to arch/arm/include/asm/imx-common/iomux-v3.h
diff --git a/board/freescale/mx6qarm2/mx6qarm2.c b/board/freescale/mx6qarm2/mx6qarm2.c
index 1367b88..340c4c4 100644
--- a/board/freescale/mx6qarm2/mx6qarm2.c
+++ b/board/freescale/mx6qarm2/mx6qarm2.c
@@ -24,9 +24,9 @@
 #include <asm/io.h>
 #include <asm/arch/imx-regs.h>
 #include <asm/arch/mx6x_pins.h>
-#include <asm/arch/iomux-v3.h>
 #include <asm/errno.h>
 #include <asm/gpio.h>
+#include <asm/imx-common/iomux-v3.h>
 #include <mmc.h>
 #include <fsl_esdhc.h>
 #include <miiphy.h>
diff --git a/board/freescale/mx6qsabrelite/mx6qsabrelite.c b/board/freescale/mx6qsabrelite/mx6qsabrelite.c
index 72b4b54..74ce84c 100644
--- a/board/freescale/mx6qsabrelite/mx6qsabrelite.c
+++ b/board/freescale/mx6qsabrelite/mx6qsabrelite.c
@@ -24,9 +24,9 @@
 #include <asm/io.h>
 #include <asm/arch/imx-regs.h>
 #include <asm/arch/mx6x_pins.h>
-#include <asm/arch/iomux-v3.h>
 #include <asm/errno.h>
 #include <asm/gpio.h>
+#include <asm/imx-common/iomux-v3.h>
 #include <mmc.h>
 #include <fsl_esdhc.h>
 #include <micrel.h>
diff --git a/drivers/usb/host/ehci-mx6.c b/drivers/usb/host/ehci-mx6.c
index 5dec673..f2523f6 100644
--- a/drivers/usb/host/ehci-mx6.c
+++ b/drivers/usb/host/ehci-mx6.c
@@ -22,7 +22,7 @@
 #include <asm/arch/imx-regs.h>
 #include <asm/arch/clock.h>
 #include <asm/arch/mx6x_pins.h>
-#include <asm/arch/iomux-v3.h>
+#include <asm/imx-common/iomux-v3.h>
 
 #include "ehci.h"
 #include "ehci-core.h"
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH V2 22/25] i.mx: iomux-v3.c: move to imx-common directory
  2012-07-05 19:53 [U-Boot] [PATCH V2 01/25] mxc_i2c: fix i2c_imx_stop Troy Kisky
                   ` (19 preceding siblings ...)
  2012-07-05 19:53 ` [U-Boot] [PATCH V2 21/25] i.mx: iomux-v3.h: move to imx-common include directory Troy Kisky
@ 2012-07-05 19:54 ` Troy Kisky
  2012-07-05 19:54 ` [U-Boot] [PATCH V2 23/25] i.mx53: add definition for I2C3_BASE_ADDR Troy Kisky
                   ` (4 subsequent siblings)
  25 siblings, 0 replies; 33+ messages in thread
From: Troy Kisky @ 2012-07-05 19:54 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
---
v2: no change
---
 arch/arm/cpu/armv7/imx-common/Makefile            |    2 +-
 arch/arm/cpu/armv7/{mx6 => imx-common}/iomux-v3.c |    0
 arch/arm/cpu/armv7/mx6/Makefile                   |    2 +-
 3 files changed, 2 insertions(+), 2 deletions(-)
 rename arch/arm/cpu/armv7/{mx6 => imx-common}/iomux-v3.c (100%)

diff --git a/arch/arm/cpu/armv7/imx-common/Makefile b/arch/arm/cpu/armv7/imx-common/Makefile
index e5ff375..53296fa 100644
--- a/arch/arm/cpu/armv7/imx-common/Makefile
+++ b/arch/arm/cpu/armv7/imx-common/Makefile
@@ -27,7 +27,7 @@ include $(TOPDIR)/config.mk
 
 LIB     = $(obj)libimx-common.o
 
-COBJS	= timer.o cpu.o speed.o
+COBJS	= iomux-v3.o timer.o cpu.o speed.o
 
 SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
 OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
diff --git a/arch/arm/cpu/armv7/mx6/iomux-v3.c b/arch/arm/cpu/armv7/imx-common/iomux-v3.c
similarity index 100%
rename from arch/arm/cpu/armv7/mx6/iomux-v3.c
rename to arch/arm/cpu/armv7/imx-common/iomux-v3.c
diff --git a/arch/arm/cpu/armv7/mx6/Makefile b/arch/arm/cpu/armv7/mx6/Makefile
index b0da028..cbce411 100644
--- a/arch/arm/cpu/armv7/mx6/Makefile
+++ b/arch/arm/cpu/armv7/mx6/Makefile
@@ -27,7 +27,7 @@ include $(TOPDIR)/config.mk
 
 LIB	= $(obj)lib$(SOC).o
 
-COBJS	= soc.o clock.o iomux-v3.o
+COBJS	= soc.o clock.o
 SOBJS   = lowlevel_init.o
 
 SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH V2 23/25] i.mx53: add definition for I2C3_BASE_ADDR
  2012-07-05 19:53 [U-Boot] [PATCH V2 01/25] mxc_i2c: fix i2c_imx_stop Troy Kisky
                   ` (20 preceding siblings ...)
  2012-07-05 19:54 ` [U-Boot] [PATCH V2 22/25] i.mx: iomux-v3.c: move to imx-common directory Troy Kisky
@ 2012-07-05 19:54 ` Troy Kisky
  2012-07-05 19:54 ` [U-Boot] [PATCH V2 24/25] imx-common: add i2c.c for bus recovery support Troy Kisky
                   ` (3 subsequent siblings)
  25 siblings, 0 replies; 33+ messages in thread
From: Troy Kisky @ 2012-07-05 19:54 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>

---
v2: no change
---
 arch/arm/include/asm/arch-mx5/imx-regs.h |    1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/include/asm/arch-mx5/imx-regs.h b/arch/arm/include/asm/arch-mx5/imx-regs.h
index 4fa6658..caf5d21 100644
--- a/arch/arm/include/asm/arch-mx5/imx-regs.h
+++ b/arch/arm/include/asm/arch-mx5/imx-regs.h
@@ -93,6 +93,7 @@
 #define GPIO5_BASE_ADDR         (AIPS1_BASE_ADDR + 0x000DC000)
 #define GPIO6_BASE_ADDR         (AIPS1_BASE_ADDR + 0x000E0000)
 #define GPIO7_BASE_ADDR         (AIPS1_BASE_ADDR + 0x000E4000)
+#define I2C3_BASE_ADDR		(AIPS1_BASE_ADDR + 0x000EC000)
 #endif
 /*
  * AIPS 2
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH V2 24/25] imx-common: add i2c.c for bus recovery support
  2012-07-05 19:53 [U-Boot] [PATCH V2 01/25] mxc_i2c: fix i2c_imx_stop Troy Kisky
                   ` (21 preceding siblings ...)
  2012-07-05 19:54 ` [U-Boot] [PATCH V2 23/25] i.mx53: add definition for I2C3_BASE_ADDR Troy Kisky
@ 2012-07-05 19:54 ` Troy Kisky
  2012-07-05 19:54 ` [U-Boot] [PATCH V2 25/25] mx6qsabrelite: add i2c multi-bus support Troy Kisky
                   ` (2 subsequent siblings)
  25 siblings, 0 replies; 33+ messages in thread
From: Troy Kisky @ 2012-07-05 19:54 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>

---
v2: do nothing if bus is already idle
    print failure message if appropriate
    change enable_i2c_clock to enable_i2c_clk
    clear non-idle bus before calling bus_i2c_init.
    wait .2 seconds for bus to clear before returning error
    fix compiler warnings
---
 arch/arm/cpu/armv7/imx-common/Makefile    |    4 +-
 arch/arm/cpu/armv7/imx-common/i2c.c       |   98 +++++++++++++++++++++++++++++
 arch/arm/cpu/armv7/mx5/clock.c            |   20 ++++++
 arch/arm/cpu/armv7/mx6/clock.c            |   20 ++++++
 arch/arm/include/asm/arch-mx5/clock.h     |    1 +
 arch/arm/include/asm/arch-mx6/clock.h     |    1 +
 arch/arm/include/asm/imx-common/mxc_i2c.h |   42 +++++++++++++
 7 files changed, 185 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/cpu/armv7/imx-common/i2c.c
 create mode 100644 arch/arm/include/asm/imx-common/mxc_i2c.h

diff --git a/arch/arm/cpu/armv7/imx-common/Makefile b/arch/arm/cpu/armv7/imx-common/Makefile
index 53296fa..bf36be5 100644
--- a/arch/arm/cpu/armv7/imx-common/Makefile
+++ b/arch/arm/cpu/armv7/imx-common/Makefile
@@ -27,7 +27,9 @@ include $(TOPDIR)/config.mk
 
 LIB     = $(obj)libimx-common.o
 
-COBJS	= iomux-v3.o timer.o cpu.o speed.o
+COBJS-y	= iomux-v3.o timer.o cpu.o speed.o
+COBJS-$(CONFIG_I2C_MXC) += i2c.o
+COBJS	:= $(sort $(COBJS-y))
 
 SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
 OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
diff --git a/arch/arm/cpu/armv7/imx-common/i2c.c b/arch/arm/cpu/armv7/imx-common/i2c.c
new file mode 100644
index 0000000..e32062d
--- /dev/null
+++ b/arch/arm/cpu/armv7/imx-common/i2c.c
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2012 Boundary Devices Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#include <common.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/imx-regs.h>
+#include <asm/errno.h>
+#include <asm/gpio.h>
+#include <asm/imx-common/mxc_i2c.h>
+#include <watchdog.h>
+
+static int toggle_scl(void *priv)
+{
+	int i;
+	int sda, scl;
+	ulong elapsed, start_time;
+	struct i2c_pads_info *p = (struct i2c_pads_info *)priv;
+	int ret = 0;
+
+	gpio_direction_input(p->sda.gp);
+	gpio_direction_input(p->scl.gp);
+
+	imx_iomux_v3_setup_pad(p->sda.gpio_mode);
+	imx_iomux_v3_setup_pad(p->scl.gpio_mode);
+
+	sda = gpio_get_value(p->sda.gp);
+	scl = gpio_get_value(p->scl.gp);
+	if ((sda & scl) == 1)
+		goto exit;		/* Bus is idle already */
+
+	printf("%s: sda=%d scl=%d sda.gp=0x%x scl.gp=0x%x\n", __func__,
+		sda, scl, p->sda.gp, p->scl.gp);
+	/* Send high and low on the SCL line */
+	for (i = 0; i < 9; i++) {
+		gpio_direction_output(p->scl.gp, 0);
+		udelay(50);
+		gpio_direction_input(p->scl.gp);
+		udelay(50);
+	}
+	start_time = get_timer(0);
+	for (;;) {
+		sda = gpio_get_value(p->sda.gp);
+		scl = gpio_get_value(p->scl.gp);
+		if ((sda & scl) == 1)
+			break;
+		WATCHDOG_RESET();
+		elapsed = get_timer(start_time);
+		if (elapsed > (CONFIG_SYS_HZ / 5)) {	/* .2 seconds */
+			ret = -EBUSY;
+			printf("%s: toggle failed to clear bus, sda=%d "
+					"scl=%d\n", __func__, sda, scl);
+			break;
+		}
+	}
+exit:
+	imx_iomux_v3_setup_pad(p->sda.i2c_mode);
+	imx_iomux_v3_setup_pad(p->scl.i2c_mode);
+	return ret;
+}
+
+static void * const i2c_bases[] = {
+	(void *)I2C1_BASE_ADDR,
+	(void *)I2C2_BASE_ADDR,
+#ifdef I2C3_BASE_ADDR
+	(void *)I2C3_BASE_ADDR,
+#endif
+};
+
+/* i2c_index can be from 0 - 2 */
+void setup_i2c(unsigned i2c_index, int speed, int slave_addr,
+		struct i2c_pads_info *p)
+{
+	if (i2c_index >= ARRAY_SIZE(i2c_bases))
+		return;
+	/* Enable i2c clock */
+	enable_i2c_clk(1, i2c_index);
+	/* Make sure bus is idle */
+	toggle_scl(p);
+	bus_i2c_init(i2c_bases[i2c_index], speed, slave_addr, toggle_scl, p);
+}
diff --git a/arch/arm/cpu/armv7/mx5/clock.c b/arch/arm/cpu/armv7/mx5/clock.c
index e92f106..c2220b0 100644
--- a/arch/arm/cpu/armv7/mx5/clock.c
+++ b/arch/arm/cpu/armv7/mx5/clock.c
@@ -80,6 +80,26 @@ void enable_usboh3_clk(unsigned char enable)
 	writel(reg, &mxc_ccm->CCGR2);
 }
 
+#ifdef CONFIG_I2C_MXC
+/* i2c_num can be from 0 - 2 */
+int enable_i2c_clk(unsigned char enable, unsigned i2c_num)
+{
+	u32 reg;
+	u32 mask;
+
+	if (i2c_num > 2)
+		return -EINVAL;
+	mask = MXC_CCM_CCGR_CG_MASK << ((i2c_num + 9) << 1);
+	reg = __raw_readl(&mxc_ccm->CCGR1);
+	if (enable)
+		reg |= mask;
+	else
+		reg &= ~mask;
+	__raw_writel(reg, &mxc_ccm->CCGR1);
+	return 0;
+}
+#endif
+
 void set_usb_phy1_clk(void)
 {
 	unsigned int reg;
diff --git a/arch/arm/cpu/armv7/mx6/clock.c b/arch/arm/cpu/armv7/mx6/clock.c
index ef98563..24f1e89 100644
--- a/arch/arm/cpu/armv7/mx6/clock.c
+++ b/arch/arm/cpu/armv7/mx6/clock.c
@@ -49,6 +49,26 @@ void enable_usboh3_clk(unsigned char enable)
 
 }
 
+#ifdef CONFIG_I2C_MXC
+/* i2c_num can be from 0 - 2 */
+int enable_i2c_clk(unsigned char enable, unsigned i2c_num)
+{
+	u32 reg;
+	u32 mask;
+
+	if (i2c_num > 2)
+		return -EINVAL;
+	mask = MXC_CCM_CCGR_CG_MASK << ((i2c_num + 3) << 1);
+	reg = __raw_readl(&imx_ccm->CCGR2);
+	if (enable)
+		reg |= mask;
+	else
+		reg &= ~mask;
+	__raw_writel(reg, &imx_ccm->CCGR2);
+	return 0;
+}
+#endif
+
 static u32 decode_pll(enum pll_clocks pll, u32 infreq)
 {
 	u32 div;
diff --git a/arch/arm/include/asm/arch-mx5/clock.h b/arch/arm/include/asm/arch-mx5/clock.h
index ea972a3..da604bf 100644
--- a/arch/arm/include/asm/arch-mx5/clock.h
+++ b/arch/arm/include/asm/arch-mx5/clock.h
@@ -44,5 +44,6 @@ void set_usb_phy2_clk(void);
 void enable_usb_phy2_clk(unsigned char enable);
 void set_usboh3_clk(void);
 void enable_usboh3_clk(unsigned char enable);
+int enable_i2c_clk(unsigned char enable, unsigned i2c_num);
 
 #endif /* __ASM_ARCH_CLOCK_H */
diff --git a/arch/arm/include/asm/arch-mx6/clock.h b/arch/arm/include/asm/arch-mx6/clock.h
index 613809b..04daf36 100644
--- a/arch/arm/include/asm/arch-mx6/clock.h
+++ b/arch/arm/include/asm/arch-mx6/clock.h
@@ -47,5 +47,6 @@ u32 imx_get_uartclk(void);
 u32 imx_get_fecclk(void);
 unsigned int mxc_get_clock(enum mxc_clock clk);
 void enable_usboh3_clk(unsigned char enable);
+int enable_i2c_clk(unsigned char enable, unsigned i2c_num);
 
 #endif /* __ASM_ARCH_CLOCK_H */
diff --git a/arch/arm/include/asm/imx-common/mxc_i2c.h b/arch/arm/include/asm/imx-common/mxc_i2c.h
new file mode 100644
index 0000000..e10b6af
--- /dev/null
+++ b/arch/arm/include/asm/imx-common/mxc_i2c.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef __ASM_ARCH_MXC_MXC_I2C_H__
+#define __ASM_ARCH_MXC_MXC_I2C_H__
+#include <asm/imx-common/iomux-v3.h>
+
+struct i2c_pin_ctrl {
+	iomux_v3_cfg_t i2c_mode;
+	iomux_v3_cfg_t gpio_mode;
+	unsigned char gp;
+	unsigned char spare;
+};
+
+struct i2c_pads_info {
+	struct i2c_pin_ctrl scl;
+	struct i2c_pin_ctrl sda;
+};
+
+void setup_i2c(unsigned i2c_index, int speed, int slave_addr,
+		struct i2c_pads_info *p);
+void bus_i2c_init(void *base, int speed, int slave_addr,
+		int (*toggle_fn)(void *p), void *p);
+int bus_i2c_read(void *base, uchar chip, uint addr, int alen, uchar *buf,
+		int len);
+int bus_i2c_write(void *base, uchar chip, uint addr, int alen,
+		const uchar *buf, int len);
+#endif
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH V2 25/25] mx6qsabrelite: add i2c multi-bus support
  2012-07-05 19:53 [U-Boot] [PATCH V2 01/25] mxc_i2c: fix i2c_imx_stop Troy Kisky
                   ` (22 preceding siblings ...)
  2012-07-05 19:54 ` [U-Boot] [PATCH V2 24/25] imx-common: add i2c.c for bus recovery support Troy Kisky
@ 2012-07-05 19:54 ` Troy Kisky
  2012-07-05 20:02 ` [U-Boot] [PATCH V2 01/25] mxc_i2c: fix i2c_imx_stop Troy Kisky
  2012-07-06 23:08 ` Marek Vasut
  25 siblings, 0 replies; 33+ messages in thread
From: Troy Kisky @ 2012-07-05 19:54 UTC (permalink / raw)
  To: u-boot

This includes bus recovery support.

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>

---
v2: no change
---
 board/freescale/mx6qsabrelite/mx6qsabrelite.c |   50 +++++++++++++++++++++++--
 include/configs/mx6qsabrelite.h               |    6 +--
 2 files changed, 48 insertions(+), 8 deletions(-)

diff --git a/board/freescale/mx6qsabrelite/mx6qsabrelite.c b/board/freescale/mx6qsabrelite/mx6qsabrelite.c
index 74ce84c..29c6630 100644
--- a/board/freescale/mx6qsabrelite/mx6qsabrelite.c
+++ b/board/freescale/mx6qsabrelite/mx6qsabrelite.c
@@ -27,6 +27,7 @@
 #include <asm/errno.h>
 #include <asm/gpio.h>
 #include <asm/imx-common/iomux-v3.h>
+#include <asm/imx-common/mxc_i2c.h>
 #include <mmc.h>
 #include <fsl_esdhc.h>
 #include <micrel.h>
@@ -72,9 +73,48 @@ iomux_v3_cfg_t uart2_pads[] = {
        MX6Q_PAD_EIM_D27__UART2_RXD | MUX_PAD_CTRL(UART_PAD_CTRL),
 };
 
-iomux_v3_cfg_t i2c3_pads[] = {
-	MX6Q_PAD_GPIO_5__I2C3_SCL | MUX_PAD_CTRL(I2C_PAD_CTRL),
-	MX6Q_PAD_GPIO_16__I2C3_SDA | MUX_PAD_CTRL(I2C_PAD_CTRL),
+#define PC MUX_PAD_CTRL(I2C_PAD_CTRL)
+
+/* I2C1, SGTL5000 */
+struct i2c_pads_info i2c_pad_info0 = {
+	.scl = {
+		.i2c_mode = MX6Q_PAD_EIM_D21__I2C1_SCL | PC,
+		.gpio_mode = MX6Q_PAD_EIM_D21__GPIO_3_21 | PC,
+		.gp = GPIO_NUMBER(3, 21)
+	},
+	.sda = {
+		.i2c_mode = MX6Q_PAD_EIM_D28__I2C1_SDA | PC,
+		.gpio_mode = MX6Q_PAD_EIM_D28__GPIO_3_28 | PC,
+		.gp = GPIO_NUMBER(3, 28)
+	}
+};
+
+/* I2C2 Camera, MIPI */
+struct i2c_pads_info i2c_pad_info1 = {
+	.scl = {
+		.i2c_mode = MX6Q_PAD_KEY_COL3__I2C2_SCL | PC,
+		.gpio_mode = MX6Q_PAD_KEY_COL3__GPIO_4_12 | PC,
+		.gp = GPIO_NUMBER(4, 12)
+	},
+	.sda = {
+		.i2c_mode = MX6Q_PAD_KEY_ROW3__I2C2_SDA | PC,
+		.gpio_mode = MX6Q_PAD_KEY_ROW3__GPIO_4_13 | PC,
+		.gp = GPIO_NUMBER(4, 13)
+	}
+};
+
+/* I2C3, J15 - RGB connector */
+struct i2c_pads_info i2c_pad_info2 = {
+	.scl = {
+		.i2c_mode = MX6Q_PAD_GPIO_5__I2C3_SCL | PC,
+		.gpio_mode = MX6Q_PAD_GPIO_5__GPIO_1_5 | PC,
+		.gp = GPIO_NUMBER(1, 5)
+	},
+	.sda = {
+		.i2c_mode = MX6Q_PAD_GPIO_16__I2C3_SDA | PC,
+		.gpio_mode = MX6Q_PAD_GPIO_16__GPIO_7_11 | PC,
+		.gp = GPIO_NUMBER(7, 11)
+	}
 };
 
 iomux_v3_cfg_t usdhc3_pads[] = {
@@ -292,7 +332,9 @@ int board_init(void)
 #ifdef CONFIG_MXC_SPI
 	setup_spi();
 #endif
-	imx_iomux_v3_setup_multiple_pads(i2c3_pads, ARRAY_SIZE(i2c3_pads));
+	setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info0);
+	setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info1);
+	setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info2);
 
        return 0;
 }
diff --git a/include/configs/mx6qsabrelite.h b/include/configs/mx6qsabrelite.h
index df2b735..c3c6be2 100644
--- a/include/configs/mx6qsabrelite.h
+++ b/include/configs/mx6qsabrelite.h
@@ -60,11 +60,9 @@
 
 /* I2C Configs */
 #define CONFIG_CMD_I2C
-#define CONFIG_HARD_I2C
+#define CONFIG_I2C_MULTI_BUS
 #define CONFIG_I2C_MXC
-#define CONFIG_SYS_I2C_BASE		I2C3_BASE_ADDR
-#define CONFIG_SYS_I2C_SPEED            100000
-#define CONFIG_SYS_I2C_SLAVE            0xfe
+#define CONFIG_SYS_I2C_SPEED		100000
 
 /* MMC Configs */
 #define CONFIG_FSL_ESDHC
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH V2 01/25] mxc_i2c: fix i2c_imx_stop
  2012-07-05 19:53 [U-Boot] [PATCH V2 01/25] mxc_i2c: fix i2c_imx_stop Troy Kisky
                   ` (23 preceding siblings ...)
  2012-07-05 19:54 ` [U-Boot] [PATCH V2 25/25] mx6qsabrelite: add i2c multi-bus support Troy Kisky
@ 2012-07-05 20:02 ` Troy Kisky
  2012-07-06  6:50   ` Marek Vasut
  2012-07-06 23:08 ` Marek Vasut
  25 siblings, 1 reply; 33+ messages in thread
From: Troy Kisky @ 2012-07-05 20:02 UTC (permalink / raw)
  To: u-boot

On 7/5/2012 12:53 PM, Troy Kisky wrote:
> Instead of clearing 2 bits, all the other
> bits were set because '|=' was used instead
> of '&='.
>
> Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
> Acked-by: Marek Vasut <marex@denx.de>
> Acked-by: Stefano Babic <sbabic@denx.de>
>
> ---
> V2: add acks
> ---
>   drivers/i2c/mxc_i2c.c |    2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c
> index fc68062..c0c45fd 100644
> --- a/drivers/i2c/mxc_i2c.c
> +++ b/drivers/i2c/mxc_i2c.c
> @@ -264,7 +264,7 @@ void i2c_imx_stop(void)
>   
>   	/* Stop I2C transaction */
>   	temp = readb(&i2c_regs->i2cr);
> -	temp |= ~(I2CR_MSTA | I2CR_MTX);
> +	temp &= ~(I2CR_MSTA | I2CR_MTX);
>   	writeb(temp, &i2c_regs->i2cr);
>   
>   	i2c_imx_bus_busy(0);
This series was tested on a sabrelite and a i.mx51 board

Thanks
Troy

^ permalink raw reply	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH V2 01/25] mxc_i2c: fix i2c_imx_stop
  2012-07-05 20:02 ` [U-Boot] [PATCH V2 01/25] mxc_i2c: fix i2c_imx_stop Troy Kisky
@ 2012-07-06  6:50   ` Marek Vasut
  2012-07-06 17:38     ` Troy Kisky
  0 siblings, 1 reply; 33+ messages in thread
From: Marek Vasut @ 2012-07-06  6:50 UTC (permalink / raw)
  To: u-boot

Dear Troy Kisky,

> On 7/5/2012 12:53 PM, Troy Kisky wrote:
> > Instead of clearing 2 bits, all the other
> > bits were set because '|=' was used instead
> > of '&='.
> > 
> > Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
> > Acked-by: Marek Vasut <marex@denx.de>
> > Acked-by: Stefano Babic <sbabic@denx.de>
> > 
> > ---
> > V2: add acks
> > ---
> > 
> >   drivers/i2c/mxc_i2c.c |    2 +-
> >   1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c
> > index fc68062..c0c45fd 100644
> > --- a/drivers/i2c/mxc_i2c.c
> > +++ b/drivers/i2c/mxc_i2c.c
> > @@ -264,7 +264,7 @@ void i2c_imx_stop(void)
> > 
> >   	/* Stop I2C transaction */
> >   	temp = readb(&i2c_regs->i2cr);
> > 
> > -	temp |= ~(I2CR_MSTA | I2CR_MTX);
> > +	temp &= ~(I2CR_MSTA | I2CR_MTX);
> > 
> >   	writeb(temp, &i2c_regs->i2cr);
> >   	
> >   	i2c_imx_bus_busy(0);
> 
> This series was tested on a sabrelite and a i.mx51 board

Sigh, I should test it on the efikamx board. It has some i2c chip that's hard to 
talk to since it's quite sensitive to the behavior of the bus. But since I'm 
dead busy now, I'll just trust you. I'm glad you found it, Troy :)

> Thanks
> Troy

Best regards,
Marek Vasut

^ permalink raw reply	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH V2 01/25] mxc_i2c: fix i2c_imx_stop
  2012-07-06  6:50   ` Marek Vasut
@ 2012-07-06 17:38     ` Troy Kisky
  2012-07-06 17:46       ` Marek Vasut
  0 siblings, 1 reply; 33+ messages in thread
From: Troy Kisky @ 2012-07-06 17:38 UTC (permalink / raw)
  To: u-boot

On 7/5/2012 11:50 PM, Marek Vasut wrote:
> Dear Troy Kisky,
>
>> On 7/5/2012 12:53 PM, Troy Kisky wrote:
>>> Instead of clearing 2 bits, all the other
>>> bits were set because '|=' was used instead
>>> of '&='.
>>>
>>> Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
>>> Acked-by: Marek Vasut <marex@denx.de>
>>> Acked-by: Stefano Babic <sbabic@denx.de>
>>>
>>> ---
>>> V2: add acks
>>> ---
>>>
>>>    drivers/i2c/mxc_i2c.c |    2 +-
>>>    1 file changed, 1 insertion(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c
>>> index fc68062..c0c45fd 100644
>>> --- a/drivers/i2c/mxc_i2c.c
>>> +++ b/drivers/i2c/mxc_i2c.c
>>> @@ -264,7 +264,7 @@ void i2c_imx_stop(void)
>>>
>>>    	/* Stop I2C transaction */
>>>    	temp = readb(&i2c_regs->i2cr);
>>>
>>> -	temp |= ~(I2CR_MSTA | I2CR_MTX);
>>> +	temp &= ~(I2CR_MSTA | I2CR_MTX);
>>>
>>>    	writeb(temp, &i2c_regs->i2cr);
>>>    	
>>>    	i2c_imx_bus_busy(0);
>> This series was tested on a sabrelite and a i.mx51 board
> Sigh, I should test it on the efikamx board. It has some i2c chip that's hard to
> talk to since it's quite sensitive to the behavior of the bus. But since I'm
> dead busy now, I'll just trust you. I'm glad you found it, Troy :)
>
>
I'd rather have your verification than trust :-)
Thanks for the reviews.

Troy

^ permalink raw reply	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH V2 01/25] mxc_i2c: fix i2c_imx_stop
  2012-07-06 17:38     ` Troy Kisky
@ 2012-07-06 17:46       ` Marek Vasut
  2012-07-06 18:14         ` Troy Kisky
  0 siblings, 1 reply; 33+ messages in thread
From: Marek Vasut @ 2012-07-06 17:46 UTC (permalink / raw)
  To: u-boot

Dear Troy Kisky,

> On 7/5/2012 11:50 PM, Marek Vasut wrote:
> > Dear Troy Kisky,
> > 
> >> On 7/5/2012 12:53 PM, Troy Kisky wrote:
> >>> Instead of clearing 2 bits, all the other
> >>> bits were set because '|=' was used instead
> >>> of '&='.
> >>> 
> >>> Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
> >>> Acked-by: Marek Vasut <marex@denx.de>
> >>> Acked-by: Stefano Babic <sbabic@denx.de>
> >>> 
> >>> ---
> >>> V2: add acks
> >>> ---
> >>> 
> >>>    drivers/i2c/mxc_i2c.c |    2 +-
> >>>    1 file changed, 1 insertion(+), 1 deletion(-)
> >>> 
> >>> diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c
> >>> index fc68062..c0c45fd 100644
> >>> --- a/drivers/i2c/mxc_i2c.c
> >>> +++ b/drivers/i2c/mxc_i2c.c
> >>> @@ -264,7 +264,7 @@ void i2c_imx_stop(void)
> >>> 
> >>>    	/* Stop I2C transaction */
> >>>    	temp = readb(&i2c_regs->i2cr);
> >>> 
> >>> -	temp |= ~(I2CR_MSTA | I2CR_MTX);
> >>> +	temp &= ~(I2CR_MSTA | I2CR_MTX);
> >>> 
> >>>    	writeb(temp, &i2c_regs->i2cr);
> >>>    	
> >>>    	i2c_imx_bus_busy(0);
> >> 
> >> This series was tested on a sabrelite and a i.mx51 board
> > 
> > Sigh, I should test it on the efikamx board. It has some i2c chip that's
> > hard to talk to since it's quite sensitive to the behavior of the bus.
> > But since I'm dead busy now, I'll just trust you. I'm glad you found it,
> > Troy :)
> 
> I'd rather have your verification than trust :-)
> Thanks for the reviews.

Hmm, lemme see.

> Troy

Best regards,
Marek Vasut

^ permalink raw reply	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH V2 01/25] mxc_i2c: fix i2c_imx_stop
  2012-07-06 17:46       ` Marek Vasut
@ 2012-07-06 18:14         ` Troy Kisky
  2012-07-06 18:39           ` Marek Vasut
  0 siblings, 1 reply; 33+ messages in thread
From: Troy Kisky @ 2012-07-06 18:14 UTC (permalink / raw)
  To: u-boot

On 7/6/2012 10:46 AM, Marek Vasut wrote:
> Dear Troy Kisky,
>
>> On 7/5/2012 11:50 PM, Marek Vasut wrote:
>>> Dear Troy Kisky,
>>>
>>>> On 7/5/2012 12:53 PM, Troy Kisky wrote:
>>>>> Instead of clearing 2 bits, all the other
>>>>> bits were set because '|=' was used instead
>>>>> of '&='.
>>>>>
>>>>> Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
>>>>> Acked-by: Marek Vasut <marex@denx.de>
>>>>> Acked-by: Stefano Babic <sbabic@denx.de>
>>>>>
>>>>> ---
>>>>> V2: add acks
>>>>> ---
>>>>>
>>>>>     drivers/i2c/mxc_i2c.c |    2 +-
>>>>>     1 file changed, 1 insertion(+), 1 deletion(-)
>>>>>
>>>>> diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c
>>>>> index fc68062..c0c45fd 100644
>>>>> --- a/drivers/i2c/mxc_i2c.c
>>>>> +++ b/drivers/i2c/mxc_i2c.c
>>>>> @@ -264,7 +264,7 @@ void i2c_imx_stop(void)
>>>>>
>>>>>     	/* Stop I2C transaction */
>>>>>     	temp = readb(&i2c_regs->i2cr);
>>>>>
>>>>> -	temp |= ~(I2CR_MSTA | I2CR_MTX);
>>>>> +	temp &= ~(I2CR_MSTA | I2CR_MTX);
>>>>>
>>>>>     	writeb(temp, &i2c_regs->i2cr);
>>>>>     	
>>>>>     	i2c_imx_bus_busy(0);
>>>> This series was tested on a sabrelite and a i.mx51 board
>>> Sigh, I should test it on the efikamx board. It has some i2c chip that's
>>> hard to talk to since it's quite sensitive to the behavior of the bus.
>>> But since I'm dead busy now, I'll just trust you. I'm glad you found it,
>>> Troy :)
>> I'd rather have your verification than trust :-)
>> Thanks for the reviews.
> Hmm, lemme see.
>
>> Troy
> Best regards,
> Marek Vasut
>
Here's a patch to enable i2c for efikamx....


Troy

^ permalink raw reply	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH V2 01/25] mxc_i2c: fix i2c_imx_stop
  2012-07-06 18:14         ` Troy Kisky
@ 2012-07-06 18:39           ` Marek Vasut
  0 siblings, 0 replies; 33+ messages in thread
From: Marek Vasut @ 2012-07-06 18:39 UTC (permalink / raw)
  To: u-boot

Dear Troy Kisky,

> On 7/6/2012 10:46 AM, Marek Vasut wrote:
> > Dear Troy Kisky,
> > 
> >> On 7/5/2012 11:50 PM, Marek Vasut wrote:
> >>> Dear Troy Kisky,
> >>> 
> >>>> On 7/5/2012 12:53 PM, Troy Kisky wrote:
> >>>>> Instead of clearing 2 bits, all the other
> >>>>> bits were set because '|=' was used instead
> >>>>> of '&='.
> >>>>> 
> >>>>> Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
> >>>>> Acked-by: Marek Vasut <marex@denx.de>
> >>>>> Acked-by: Stefano Babic <sbabic@denx.de>
> >>>>> 
> >>>>> ---
> >>>>> V2: add acks
> >>>>> ---
> >>>>> 
> >>>>>     drivers/i2c/mxc_i2c.c |    2 +-
> >>>>>     1 file changed, 1 insertion(+), 1 deletion(-)
> >>>>> 
> >>>>> diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c
> >>>>> index fc68062..c0c45fd 100644
> >>>>> --- a/drivers/i2c/mxc_i2c.c
> >>>>> +++ b/drivers/i2c/mxc_i2c.c
> >>>>> @@ -264,7 +264,7 @@ void i2c_imx_stop(void)
> >>>>> 
> >>>>>     	/* Stop I2C transaction */
> >>>>>     	temp = readb(&i2c_regs->i2cr);
> >>>>> 
> >>>>> -	temp |= ~(I2CR_MSTA | I2CR_MTX);
> >>>>> +	temp &= ~(I2CR_MSTA | I2CR_MTX);
> >>>>> 
> >>>>>     	writeb(temp, &i2c_regs->i2cr);
> >>>>>     	
> >>>>>     	i2c_imx_bus_busy(0);
> >>>> 
> >>>> This series was tested on a sabrelite and a i.mx51 board
> >>> 
> >>> Sigh, I should test it on the efikamx board. It has some i2c chip
> >>> that's hard to talk to since it's quite sensitive to the behavior of
> >>> the bus. But since I'm dead busy now, I'll just trust you. I'm glad
> >>> you found it, Troy :)
> >> 
> >> I'd rather have your verification than trust :-)
> >> Thanks for the reviews.
> > 
> > Hmm, lemme see.
> > 
> >> Troy
> > 
> > Best regards,
> > Marek Vasut
> 
> Here's a patch to enable i2c for efikamx....

It should be enabled already ... hm, I think I'll have to dig deeper.

> 
> Troy

Best regards,
Marek Vasut

^ permalink raw reply	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH V2 01/25] mxc_i2c: fix i2c_imx_stop
  2012-07-05 19:53 [U-Boot] [PATCH V2 01/25] mxc_i2c: fix i2c_imx_stop Troy Kisky
                   ` (24 preceding siblings ...)
  2012-07-05 20:02 ` [U-Boot] [PATCH V2 01/25] mxc_i2c: fix i2c_imx_stop Troy Kisky
@ 2012-07-06 23:08 ` Marek Vasut
  2012-07-07  1:52   ` Troy Kisky
  25 siblings, 1 reply; 33+ messages in thread
From: Marek Vasut @ 2012-07-06 23:08 UTC (permalink / raw)
  To: u-boot

Dear Troy Kisky,

> Instead of clearing 2 bits, all the other
> bits were set because '|=' was used instead
> of '&='.
> 
> Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
> Acked-by: Marek Vasut <marex@denx.de>
> Acked-by: Stefano Babic <sbabic@denx.de>
> 

Troy, do you have some repo for these please?

Best regards,
Marek Vasut

^ permalink raw reply	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH V2 01/25] mxc_i2c: fix i2c_imx_stop
  2012-07-06 23:08 ` Marek Vasut
@ 2012-07-07  1:52   ` Troy Kisky
  0 siblings, 0 replies; 33+ messages in thread
From: Troy Kisky @ 2012-07-07  1:52 UTC (permalink / raw)
  To: u-boot

On 7/6/2012 4:08 PM, Marek Vasut wrote:
> Dear Troy Kisky,
>
>> Instead of clearing 2 bits, all the other
>> bits were set because '|=' was used instead
>> of '&='.
>>
>> Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
>> Acked-by: Marek Vasut <marex@denx.de>
>> Acked-by: Stefano Babic <sbabic@denx.de>
>>
> Troy, do you have some repo for these please?
>
> Best regards,
> Marek Vasut
>
git://github.com/boundarydevices/u-boot-imx6.git i2c_testing

^ permalink raw reply	[flat|nested] 33+ messages in thread

end of thread, other threads:[~2012-07-07  1:52 UTC | newest]

Thread overview: 33+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-07-05 19:53 [U-Boot] [PATCH V2 01/25] mxc_i2c: fix i2c_imx_stop Troy Kisky
2012-07-05 19:53 ` [U-Boot] [PATCH V2 02/25] mxc_i2c: remove ifdef of CONFIG_HARD_I2C Troy Kisky
2012-07-05 19:53 ` [U-Boot] [PATCH V2 03/25] mxc_i2c: create tx_byte function Troy Kisky
2012-07-05 19:53 ` [U-Boot] [PATCH V2 04/25] mxc_i2c: clear i2sr before waiting for bit Troy Kisky
2012-07-05 19:53 ` [U-Boot] [PATCH V2 05/25] mxc_i2c: create i2c_init_transfer Troy Kisky
2012-07-05 19:53 ` [U-Boot] [PATCH V2 06/25] mxc_i2c: call i2c_imx_stop on error in i2c_read/i2c_write Troy Kisky
2012-07-05 19:53 ` [U-Boot] [PATCH V2 07/25] mxc_i2c.c: code i2c_probe as a 0 length i2c_write Troy Kisky
2012-07-05 19:53 ` [U-Boot] [PATCH V2 08/25] mxc_i2c: combine i2c_imx_bus_busy and i2c_imx_trx_complete into wait_for_sr_state Troy Kisky
2012-07-05 19:53 ` [U-Boot] [PATCH V2 09/25] mxc_i2c: remove redundant read Troy Kisky
2012-07-05 19:53 ` [U-Boot] [PATCH V2 10/25] mxc_i2c: place imx_start code inline Troy Kisky
2012-07-05 19:53 ` [U-Boot] [PATCH V2 11/25] mxc_i2c: place i2c_reset " Troy Kisky
2012-07-05 19:53 ` [U-Boot] [PATCH V2 12/25] mxc_i2c: don't disable controller after every transaction Troy Kisky
2012-07-05 19:53 ` [U-Boot] [PATCH V2 13/25] mxc_i2c: change slave addr if conflicts with destination Troy Kisky
2012-07-05 19:53 ` [U-Boot] [PATCH V2 14/25] mxc_i2c: check for arbitration lost Troy Kisky
2012-07-05 19:53 ` [U-Boot] [PATCH V2 15/25] mxc_i2c: add retries Troy Kisky
2012-07-05 19:53 ` [U-Boot] [PATCH V2 16/25] mxc_i2c: add i2c_regs argument to i2c_imx_stop Troy Kisky
2012-07-05 19:53 ` [U-Boot] [PATCH V2 17/25] mxc_i2c: prep work for multiple busses support Troy Kisky
2012-07-05 19:53 ` [U-Boot] [PATCH V2 18/25] mxc_i2c: add bus recovery support Troy Kisky
2012-07-05 19:53 ` [U-Boot] [PATCH V2 19/25] mxc_i2c: finish adding CONFIG_I2C_MULTI_BUS support Troy Kisky
2012-07-05 19:53 ` [U-Boot] [PATCH V2 20/25] iomux-v3: remove include of mx6x_pins.h Troy Kisky
2012-07-05 19:53 ` [U-Boot] [PATCH V2 21/25] i.mx: iomux-v3.h: move to imx-common include directory Troy Kisky
2012-07-05 19:54 ` [U-Boot] [PATCH V2 22/25] i.mx: iomux-v3.c: move to imx-common directory Troy Kisky
2012-07-05 19:54 ` [U-Boot] [PATCH V2 23/25] i.mx53: add definition for I2C3_BASE_ADDR Troy Kisky
2012-07-05 19:54 ` [U-Boot] [PATCH V2 24/25] imx-common: add i2c.c for bus recovery support Troy Kisky
2012-07-05 19:54 ` [U-Boot] [PATCH V2 25/25] mx6qsabrelite: add i2c multi-bus support Troy Kisky
2012-07-05 20:02 ` [U-Boot] [PATCH V2 01/25] mxc_i2c: fix i2c_imx_stop Troy Kisky
2012-07-06  6:50   ` Marek Vasut
2012-07-06 17:38     ` Troy Kisky
2012-07-06 17:46       ` Marek Vasut
2012-07-06 18:14         ` Troy Kisky
2012-07-06 18:39           ` Marek Vasut
2012-07-06 23:08 ` Marek Vasut
2012-07-07  1:52   ` Troy Kisky

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.