linux-i2c.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] i2c: imx: check busy bit when START/STOP
@ 2009-09-30  5:47 Richard Zhao
       [not found] ` <1254289682-29056-1-git-send-email-linuxzsc-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  0 siblings, 1 reply; 5+ messages in thread
From: Richard Zhao @ 2009-09-30  5:47 UTC (permalink / raw)
  To: kernel-bIcnvbaLZ9MEGnE8C9+IrQ
  Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA, Richard Zhao

After START/RESTART, wait for busy bit to be set and
after STOP, wait for busy bit to be clear.

Signed-off-by: Richard Zhao <linuxzsc-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 drivers/i2c/busses/i2c-imx.c |   46 +++++++++++++++++++++++++++++------------
 1 files changed, 32 insertions(+), 14 deletions(-)

diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
index 4afba3e..156cc95 100644
--- a/drivers/i2c/busses/i2c-imx.c
+++ b/drivers/i2c/busses/i2c-imx.c
@@ -125,14 +125,19 @@ struct imx_i2c_struct {
 /** Functions for IMX I2C adapter driver ***************************************
 *******************************************************************************/
 
-static int i2c_imx_bus_busy(struct imx_i2c_struct *i2c_imx)
+static int i2c_imx_bus_busy(struct imx_i2c_struct *i2c_imx, int for_busy)
 {
 	unsigned long orig_jiffies = jiffies;
+	unsigned int temp;
 
 	dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
 
-	/* wait for bus not busy */
-	while (readb(i2c_imx->base + IMX_I2C_I2SR) & I2SR_IBB) {
+	temp = readb(i2c_imx->base + IMX_I2C_I2SR);
+	while (1) {
+		if (for_busy && (temp & I2SR_IBB))
+			break;
+		if (!for_busy && !(temp & I2SR_IBB))
+			break;
 		if (signal_pending(current)) {
 			dev_dbg(&i2c_imx->adapter.dev,
 				"<%s> I2C Interrupted\n", __func__);
@@ -144,6 +149,7 @@ static int i2c_imx_bus_busy(struct imx_i2c_struct *i2c_imx)
 			return -EIO;
 		}
 		schedule();
+		temp = readb(i2c_imx->base + IMX_I2C_I2SR);
 	}
 
 	return 0;
@@ -179,20 +185,32 @@ static int i2c_imx_acked(struct imx_i2c_struct *i2c_imx)
 	return 0;
 }
 
-static void i2c_imx_start(struct imx_i2c_struct *i2c_imx)
+static int i2c_imx_start(struct imx_i2c_struct *i2c_imx)
 {
 	unsigned int temp = 0;
+	int result;
 
 	dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
 
 	/* Enable I2C controller */
+	writeb(0, i2c_imx->base + IMX_I2C_I2SR);
 	writeb(I2CR_IEN, i2c_imx->base + IMX_I2C_I2CR);
+
+	result = i2c_imx_bus_busy(i2c_imx, 0);
+	if (result)
+		return result;
+
 	/* Start I2C transaction */
 	temp = readb(i2c_imx->base + IMX_I2C_I2CR);
 	temp |= I2CR_MSTA;
 	writeb(temp, i2c_imx->base + IMX_I2C_I2CR);
+	result = i2c_imx_bus_busy(i2c_imx, 1);
+	if (result)
+		return result;
+
 	temp |= I2CR_IIEN | I2CR_MTX | I2CR_TXAK;
 	writeb(temp, i2c_imx->base + IMX_I2C_I2CR);
+	return result;
 }
 
 static void i2c_imx_stop(struct imx_i2c_struct *i2c_imx)
@@ -202,16 +220,16 @@ static void i2c_imx_stop(struct imx_i2c_struct *i2c_imx)
 	/* Stop I2C transaction */
 	dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
 	temp = readb(i2c_imx->base + IMX_I2C_I2CR);
-	temp &= ~I2CR_MSTA;
+	temp &= ~(I2CR_MSTA | I2CR_MTX);
 	writeb(temp, i2c_imx->base + IMX_I2C_I2CR);
-	/* setup chip registers to defaults */
-	writeb(I2CR_IEN, i2c_imx->base + IMX_I2C_I2CR);
-	writeb(0, i2c_imx->base + IMX_I2C_I2SR);
 	/*
 	 * This delay caused by an i.MXL hardware bug.
 	 * If no (or too short) delay, no "STOP" bit will be generated.
 	 */
 	udelay(i2c_imx->disable_delay);
+
+	i2c_imx_bus_busy(i2c_imx, 0);
+
 	/* Disable I2C controller */
 	writeb(0, i2c_imx->base + IMX_I2C_I2CR);
 }
@@ -344,7 +362,7 @@ static int i2c_imx_read(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs)
 			dev_dbg(&i2c_imx->adapter.dev,
 				"<%s> clear MSTA\n", __func__);
 			temp = readb(i2c_imx->base + IMX_I2C_I2CR);
-			temp &= ~I2CR_MSTA;
+			temp &= ~(I2CR_MSTA | I2CR_MTX);
 			writeb(temp, i2c_imx->base + IMX_I2C_I2CR);
 		} else if (i == (msgs->len - 2)) {
 			dev_dbg(&i2c_imx->adapter.dev,
@@ -370,14 +388,11 @@ static int i2c_imx_xfer(struct i2c_adapter *adapter,
 
 	dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
 
-	/* Check if i2c bus is not busy */
-	result = i2c_imx_bus_busy(i2c_imx);
+	/* Start I2C transfer */
+	result = i2c_imx_start(i2c_imx);
 	if (result)
 		goto fail0;
 
-	/* Start I2C transfer */
-	i2c_imx_start(i2c_imx);
-
 	/* read/write data */
 	for (i = 0; i < num; i++) {
 		if (i) {
@@ -386,6 +401,9 @@ static int i2c_imx_xfer(struct i2c_adapter *adapter,
 			temp = readb(i2c_imx->base + IMX_I2C_I2CR);
 			temp |= I2CR_RSTA;
 			writeb(temp, i2c_imx->base + IMX_I2C_I2CR);
+			result =  i2c_imx_bus_busy(i2c_imx, 1);
+			if (result)
+				goto fail0;
 		}
 		dev_dbg(&i2c_imx->adapter.dev,
 			"<%s> transfer message: %d\n", __func__, i);
-- 
1.6.0.4

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

* [PATCH] i2c: imx: only imx1 needs disable delay
       [not found] ` <1254289682-29056-1-git-send-email-linuxzsc-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2009-09-30  5:48   ` Richard Zhao
       [not found]     ` <1254289682-29056-2-git-send-email-linuxzsc-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  0 siblings, 1 reply; 5+ messages in thread
From: Richard Zhao @ 2009-09-30  5:48 UTC (permalink / raw)
  To: kernel-bIcnvbaLZ9MEGnE8C9+IrQ
  Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA, Richard Zhao

check cpu_is_mx1() when set disable_delay.

Signed-off-by: Richard Zhao <linuxzsc-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 drivers/i2c/busses/i2c-imx.c |   18 ++++++++++--------
 1 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
index 156cc95..c1e541c 100644
--- a/drivers/i2c/busses/i2c-imx.c
+++ b/drivers/i2c/busses/i2c-imx.c
@@ -254,14 +254,16 @@ static void __init i2c_imx_set_clk(struct imx_i2c_struct *i2c_imx,
 	/* Write divider value to register */
 	writeb(i2c_clk_div[i][1], i2c_imx->base + IMX_I2C_IFDR);
 
-	/*
-	 * There dummy delay is calculated.
-	 * It should be about one I2C clock period long.
-	 * This delay is used in I2C bus disable function
-	 * to fix chip hardware bug.
-	 */
-	i2c_imx->disable_delay = (500000U * i2c_clk_div[i][0]
-		+ (i2c_clk_rate / 2) - 1) / (i2c_clk_rate / 2);
+	if (cpu_is_mx1()) {
+		/*
+		 * There dummy delay is calculated.
+		 * It should be about one I2C clock period long.
+		 * This delay is used in I2C bus disable function
+		 * to fix chip hardware bug.
+		 */
+		i2c_imx->disable_delay = (500000U * i2c_clk_div[i][0]
+			+ (i2c_clk_rate / 2) - 1) / (i2c_clk_rate / 2);
+	}
 
 	/* dev_dbg() can't be used, because adapter is not yet registered */
 #ifdef CONFIG_I2C_DEBUG_BUS
-- 
1.6.0.4

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

* [PATCH] i2c: imx: add macros and printk to make debug easy
       [not found]     ` <1254289682-29056-2-git-send-email-linuxzsc-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2009-09-30  5:48       ` Richard Zhao
       [not found]         ` <1254289682-29056-3-git-send-email-linuxzsc-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  0 siblings, 1 reply; 5+ messages in thread
From: Richard Zhao @ 2009-09-30  5:48 UTC (permalink / raw)
  To: kernel-bIcnvbaLZ9MEGnE8C9+IrQ
  Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA, Richard Zhao

When CONFIG_I2C_DEBUG_BUS is enabled, it helps dump registers at operation
fail condition, and print i2c_msg to xfer.

Signed-off-by: Richard Zhao <linuxzsc-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 drivers/i2c/busses/i2c-imx.c |   49 ++++++++++++++++++++++++++++++++++++------
 1 files changed, 42 insertions(+), 7 deletions(-)

diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
index c1e541c..87faea4 100644
--- a/drivers/i2c/busses/i2c-imx.c
+++ b/drivers/i2c/busses/i2c-imx.c
@@ -125,6 +125,20 @@ struct imx_i2c_struct {
 /** Functions for IMX I2C adapter driver ***************************************
 *******************************************************************************/
 
+#ifdef CONFIG_I2C_DEBUG_BUS
+#define reg_dump(i2c_imx) \
+{ \
+	printk(KERN_DEBUG "fun %s:%d ", __func__, __LINE__); \
+	printk(KERN_DEBUG "IADR %02x IFDR %02x I2CR %02x I2SR %02x\n", \
+		readb(i2c_imx->base + IMX_I2C_IADR), \
+		readb(i2c_imx->base + IMX_I2C_IFDR), \
+		readb(i2c_imx->base + IMX_I2C_I2CR), \
+		readb(i2c_imx->base + IMX_I2C_I2SR)); \
+}
+#else
+#define reg_dump(i2c_imx)
+#endif
+
 static int i2c_imx_bus_busy(struct imx_i2c_struct *i2c_imx, int for_busy)
 {
 	unsigned long orig_jiffies = jiffies;
@@ -146,6 +160,7 @@ static int i2c_imx_bus_busy(struct imx_i2c_struct *i2c_imx, int for_busy)
 		if (time_after(jiffies, orig_jiffies + HZ / 1000)) {
 			dev_dbg(&i2c_imx->adapter.dev,
 				"<%s> I2C bus is busy\n", __func__);
+			reg_dump(i2c_imx);
 			return -EIO;
 		}
 		schedule();
@@ -164,9 +179,11 @@ static int i2c_imx_trx_complete(struct imx_i2c_struct *i2c_imx)
 
 	if (unlikely(result < 0)) {
 		dev_dbg(&i2c_imx->adapter.dev, "<%s> result < 0\n", __func__);
+		reg_dump(i2c_imx);
 		return result;
 	} else if (unlikely(!(i2c_imx->i2csr & I2SR_IIF))) {
 		dev_dbg(&i2c_imx->adapter.dev, "<%s> Timeout\n", __func__);
+		reg_dump(i2c_imx);
 		return -ETIMEDOUT;
 	}
 	dev_dbg(&i2c_imx->adapter.dev, "<%s> TRX complete\n", __func__);
@@ -178,6 +195,7 @@ static int i2c_imx_acked(struct imx_i2c_struct *i2c_imx)
 {
 	if (readb(i2c_imx->base + IMX_I2C_I2SR) & I2SR_RXAK) {
 		dev_dbg(&i2c_imx->adapter.dev, "<%s> No ACK\n", __func__);
+		reg_dump(i2c_imx);
 		return -EIO;  /* No ACK */
 	}
 
@@ -197,17 +215,20 @@ static int i2c_imx_start(struct imx_i2c_struct *i2c_imx)
 	writeb(I2CR_IEN, i2c_imx->base + IMX_I2C_I2CR);
 
 	result = i2c_imx_bus_busy(i2c_imx, 0);
-	if (result)
+	if (result) {
+		reg_dump(i2c_imx);
 		return result;
+	}
 
 	/* Start I2C transaction */
 	temp = readb(i2c_imx->base + IMX_I2C_I2CR);
 	temp |= I2CR_MSTA;
 	writeb(temp, i2c_imx->base + IMX_I2C_I2CR);
 	result = i2c_imx_bus_busy(i2c_imx, 1);
-	if (result)
+	if (result) {
+		reg_dump(i2c_imx);
 		return result;
-
+	}
 	temp |= I2CR_IIEN | I2CR_MTX | I2CR_TXAK;
 	writeb(temp, i2c_imx->base + IMX_I2C_I2CR);
 	return result;
@@ -228,7 +249,8 @@ static void i2c_imx_stop(struct imx_i2c_struct *i2c_imx)
 	 */
 	udelay(i2c_imx->disable_delay);
 
-	i2c_imx_bus_busy(i2c_imx, 0);
+	if (i2c_imx_bus_busy(i2c_imx, 0))
+		reg_dump(i2c_imx);
 
 	/* Disable I2C controller */
 	writeb(0, i2c_imx->base + IMX_I2C_I2CR);
@@ -389,7 +411,18 @@ static int i2c_imx_xfer(struct i2c_adapter *adapter,
 	struct imx_i2c_struct *i2c_imx = i2c_get_adapdata(adapter);
 
 	dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
-
+#ifdef CONFIG_I2C_DEBUG_BUS
+	for (i = 0; i < num; i++) {
+		printk(KERN_DEBUG "msg%d addr %02x RD %d cnt %d d:", i,
+			msgs[i].addr, msgs[i].flags & I2C_M_RD, msgs[i].len);
+		if (!(msgs[i].flags & I2C_M_RD)) {
+			int j;
+			for (j = 0; j < msgs[i].len; j++)
+				printk("%02x ", msgs[i].buf[j]);
+		}
+		printk("\n");
+	}
+#endif
 	/* Start I2C transfer */
 	result = i2c_imx_start(i2c_imx);
 	if (result)
@@ -404,8 +437,10 @@ static int i2c_imx_xfer(struct i2c_adapter *adapter,
 			temp |= I2CR_RSTA;
 			writeb(temp, i2c_imx->base + IMX_I2C_I2CR);
 			result =  i2c_imx_bus_busy(i2c_imx, 1);
-			if (result)
+			if (result) {
+				reg_dump(i2c_imx);
 				goto fail0;
+			}
 		}
 		dev_dbg(&i2c_imx->adapter.dev,
 			"<%s> transfer message: %d\n", __func__, i);
@@ -562,7 +597,7 @@ static int __init i2c_imx_probe(struct platform_device *pdev)
 		res_size, i2c_imx->res->start);
 	dev_dbg(&i2c_imx->adapter.dev, "adapter name: \"%s\"\n",
 		i2c_imx->adapter.name);
-	dev_dbg(&i2c_imx->adapter.dev, "IMX I2C adapter registered\n");
+	dev_info(&i2c_imx->adapter.dev, "IMX I2C adapter registered\n");
 
 	return 0;   /* Return OK */
 
-- 
1.6.0.4

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

* [PATCH] i2c: imx: disable clock when it's possible to save power.
       [not found]         ` <1254289682-29056-3-git-send-email-linuxzsc-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2009-09-30  5:48           ` Richard Zhao
  2009-09-30  5:49           ` [PATCH] i2c: imx: add macros and printk to make debug easy Richard Zhao
  1 sibling, 0 replies; 5+ messages in thread
From: Richard Zhao @ 2009-09-30  5:48 UTC (permalink / raw)
  To: kernel-bIcnvbaLZ9MEGnE8C9+IrQ
  Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA, Richard Zhao

Enable clock before START, disable it after STOP.

Signed-off-by: Richard Zhao <linuxzsc-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 drivers/i2c/busses/i2c-imx.c |   12 ++++++------
 1 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
index 87faea4..72ddea3 100644
--- a/drivers/i2c/busses/i2c-imx.c
+++ b/drivers/i2c/busses/i2c-imx.c
@@ -120,6 +120,7 @@ struct imx_i2c_struct {
 	wait_queue_head_t	queue;
 	unsigned long		i2csr;
 	unsigned int 		disable_delay;
+	unsigned int		ifdr; /* IMX_I2C_IFDR */
 };
 
 /** Functions for IMX I2C adapter driver ***************************************
@@ -210,6 +211,8 @@ static int i2c_imx_start(struct imx_i2c_struct *i2c_imx)
 
 	dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
 
+	clk_enable(i2c_imx->clk);
+	writeb(i2c_imx->ifdr, i2c_imx->base + IMX_I2C_IFDR);
 	/* Enable I2C controller */
 	writeb(0, i2c_imx->base + IMX_I2C_I2SR);
 	writeb(I2CR_IEN, i2c_imx->base + IMX_I2C_I2CR);
@@ -254,6 +257,7 @@ static void i2c_imx_stop(struct imx_i2c_struct *i2c_imx)
 
 	/* Disable I2C controller */
 	writeb(0, i2c_imx->base + IMX_I2C_I2CR);
+	clk_disable(i2c_imx->clk);
 }
 
 static void __init i2c_imx_set_clk(struct imx_i2c_struct *i2c_imx,
@@ -273,8 +277,8 @@ static void __init i2c_imx_set_clk(struct imx_i2c_struct *i2c_imx,
 	else
 		for (i = 0; i2c_clk_div[i][0] < div; i++);
 
-	/* Write divider value to register */
-	writeb(i2c_clk_div[i][1], i2c_imx->base + IMX_I2C_IFDR);
+	/* Store divider value */
+	i2c_imx->ifdr = i2c_clk_div[i][1];
 
 	if (cpu_is_mx1()) {
 		/*
@@ -555,7 +559,6 @@ static int __init i2c_imx_probe(struct platform_device *pdev)
 		dev_err(&pdev->dev, "can't get I2C clock\n");
 		goto fail3;
 	}
-	clk_enable(i2c_imx->clk);
 
 	/* Request IRQ */
 	ret = request_irq(i2c_imx->irq, i2c_imx_isr, 0, pdev->name, i2c_imx);
@@ -604,7 +607,6 @@ static int __init i2c_imx_probe(struct platform_device *pdev)
 fail5:
 	free_irq(i2c_imx->irq, i2c_imx);
 fail4:
-	clk_disable(i2c_imx->clk);
 	clk_put(i2c_imx->clk);
 fail3:
 	release_mem_region(i2c_imx->res->start, resource_size(res));
@@ -641,8 +643,6 @@ static int __exit i2c_imx_remove(struct platform_device *pdev)
 	if (pdata && pdata->exit)
 		pdata->exit(&pdev->dev);
 
-	/* Disable I2C clock */
-	clk_disable(i2c_imx->clk);
 	clk_put(i2c_imx->clk);
 
 	release_mem_region(i2c_imx->res->start, resource_size(i2c_imx->res));
-- 
1.6.0.4

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

* Re: [PATCH] i2c: imx: add macros and printk to make debug easy
       [not found]         ` <1254289682-29056-3-git-send-email-linuxzsc-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  2009-09-30  5:48           ` [PATCH] i2c: imx: disable clock when it's possible to save power Richard Zhao
@ 2009-09-30  5:49           ` Richard Zhao
  1 sibling, 0 replies; 5+ messages in thread
From: Richard Zhao @ 2009-09-30  5:49 UTC (permalink / raw)
  To: kernel-bIcnvbaLZ9MEGnE8C9+IrQ
  Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA, Richard Zhao

On Wed, Sep 30, 2009 at 1:48 PM, Richard Zhao <linuxzsc-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> When CONFIG_I2C_DEBUG_BUS is enabled, it helps dump registers at operation
> fail condition, and print i2c_msg to xfer.
>
> Signed-off-by: Richard Zhao <linuxzsc-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> ---
>  drivers/i2c/busses/i2c-imx.c |   49 ++++++++++++++++++++++++++++++++++++------
>  1 files changed, 42 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
> index c1e541c..87faea4 100644
> --- a/drivers/i2c/busses/i2c-imx.c
> +++ b/drivers/i2c/busses/i2c-imx.c
> @@ -125,6 +125,20 @@ struct imx_i2c_struct {
>  /** Functions for IMX I2C adapter driver ***************************************
>  *******************************************************************************/
>
> +#ifdef CONFIG_I2C_DEBUG_BUS
> +#define reg_dump(i2c_imx) \
> +{ \
> +       printk(KERN_DEBUG "fun %s:%d ", __func__, __LINE__); \
> +       printk(KERN_DEBUG "IADR %02x IFDR %02x I2CR %02x I2SR %02x\n", \
> +               readb(i2c_imx->base + IMX_I2C_IADR), \
> +               readb(i2c_imx->base + IMX_I2C_IFDR), \
> +               readb(i2c_imx->base + IMX_I2C_I2CR), \
> +               readb(i2c_imx->base + IMX_I2C_I2SR)); \
> +}
> +#else
> +#define reg_dump(i2c_imx)
> +#endif
> +
>  static int i2c_imx_bus_busy(struct imx_i2c_struct *i2c_imx, int for_busy)
>  {
>        unsigned long orig_jiffies = jiffies;
> @@ -146,6 +160,7 @@ static int i2c_imx_bus_busy(struct imx_i2c_struct *i2c_imx, int for_busy)
>                if (time_after(jiffies, orig_jiffies + HZ / 1000)) {
>                        dev_dbg(&i2c_imx->adapter.dev,
>                                "<%s> I2C bus is busy\n", __func__);
> +                       reg_dump(i2c_imx);
>                        return -EIO;
>                }
>                schedule();
> @@ -164,9 +179,11 @@ static int i2c_imx_trx_complete(struct imx_i2c_struct *i2c_imx)
>
>        if (unlikely(result < 0)) {
>                dev_dbg(&i2c_imx->adapter.dev, "<%s> result < 0\n", __func__);
> +               reg_dump(i2c_imx);
>                return result;
>        } else if (unlikely(!(i2c_imx->i2csr & I2SR_IIF))) {
>                dev_dbg(&i2c_imx->adapter.dev, "<%s> Timeout\n", __func__);
> +               reg_dump(i2c_imx);
>                return -ETIMEDOUT;
>        }
>        dev_dbg(&i2c_imx->adapter.dev, "<%s> TRX complete\n", __func__);
> @@ -178,6 +195,7 @@ static int i2c_imx_acked(struct imx_i2c_struct *i2c_imx)
>  {
>        if (readb(i2c_imx->base + IMX_I2C_I2SR) & I2SR_RXAK) {
>                dev_dbg(&i2c_imx->adapter.dev, "<%s> No ACK\n", __func__);
> +               reg_dump(i2c_imx);
>                return -EIO;  /* No ACK */
>        }
>
> @@ -197,17 +215,20 @@ static int i2c_imx_start(struct imx_i2c_struct *i2c_imx)
>        writeb(I2CR_IEN, i2c_imx->base + IMX_I2C_I2CR);
>
>        result = i2c_imx_bus_busy(i2c_imx, 0);
> -       if (result)
> +       if (result) {
> +               reg_dump(i2c_imx);
>                return result;
> +       }
>
>        /* Start I2C transaction */
>        temp = readb(i2c_imx->base + IMX_I2C_I2CR);
>        temp |= I2CR_MSTA;
>        writeb(temp, i2c_imx->base + IMX_I2C_I2CR);
>        result = i2c_imx_bus_busy(i2c_imx, 1);
> -       if (result)
> +       if (result) {
> +               reg_dump(i2c_imx);
>                return result;
> -
> +       }
>        temp |= I2CR_IIEN | I2CR_MTX | I2CR_TXAK;
>        writeb(temp, i2c_imx->base + IMX_I2C_I2CR);
>        return result;
> @@ -228,7 +249,8 @@ static void i2c_imx_stop(struct imx_i2c_struct *i2c_imx)
>         */
>        udelay(i2c_imx->disable_delay);
>
> -       i2c_imx_bus_busy(i2c_imx, 0);
> +       if (i2c_imx_bus_busy(i2c_imx, 0))
> +               reg_dump(i2c_imx);
>
>        /* Disable I2C controller */
>        writeb(0, i2c_imx->base + IMX_I2C_I2CR);
> @@ -389,7 +411,18 @@ static int i2c_imx_xfer(struct i2c_adapter *adapter,
>        struct imx_i2c_struct *i2c_imx = i2c_get_adapdata(adapter);
>
>        dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
> -
> +#ifdef CONFIG_I2C_DEBUG_BUS
> +       for (i = 0; i < num; i++) {
> +               printk(KERN_DEBUG "msg%d addr %02x RD %d cnt %d d:", i,
> +                       msgs[i].addr, msgs[i].flags & I2C_M_RD, msgs[i].len);
> +               if (!(msgs[i].flags & I2C_M_RD)) {
> +                       int j;
> +                       for (j = 0; j < msgs[i].len; j++)
> +                               printk("%02x ", msgs[i].buf[j]);
> +               }
> +               printk("\n");
> +       }
> +#endif
>        /* Start I2C transfer */
>        result = i2c_imx_start(i2c_imx);
>        if (result)
> @@ -404,8 +437,10 @@ static int i2c_imx_xfer(struct i2c_adapter *adapter,
>                        temp |= I2CR_RSTA;
>                        writeb(temp, i2c_imx->base + IMX_I2C_I2CR);
>                        result =  i2c_imx_bus_busy(i2c_imx, 1);
> -                       if (result)
> +                       if (result) {
> +                               reg_dump(i2c_imx);
>                                goto fail0;
> +                       }
>                }
>                dev_dbg(&i2c_imx->adapter.dev,
>                        "<%s> transfer message: %d\n", __func__, i);
> @@ -562,7 +597,7 @@ static int __init i2c_imx_probe(struct platform_device *pdev)
>                res_size, i2c_imx->res->start);
>        dev_dbg(&i2c_imx->adapter.dev, "adapter name: \"%s\"\n",
>                i2c_imx->adapter.name);
> -       dev_dbg(&i2c_imx->adapter.dev, "IMX I2C adapter registered\n");
> +       dev_info(&i2c_imx->adapter.dev, "IMX I2C adapter registered\n");
>
>        return 0;   /* Return OK */
>
> --
> 1.6.0.4
>
>

Sorry, I forgot to add patch NO. Please ignore theses patch.
 Richard

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

end of thread, other threads:[~2009-09-30  5:49 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-09-30  5:47 [PATCH] i2c: imx: check busy bit when START/STOP Richard Zhao
     [not found] ` <1254289682-29056-1-git-send-email-linuxzsc-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2009-09-30  5:48   ` [PATCH] i2c: imx: only imx1 needs disable delay Richard Zhao
     [not found]     ` <1254289682-29056-2-git-send-email-linuxzsc-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2009-09-30  5:48       ` [PATCH] i2c: imx: add macros and printk to make debug easy Richard Zhao
     [not found]         ` <1254289682-29056-3-git-send-email-linuxzsc-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2009-09-30  5:48           ` [PATCH] i2c: imx: disable clock when it's possible to save power Richard Zhao
2009-09-30  5:49           ` [PATCH] i2c: imx: add macros and printk to make debug easy Richard Zhao

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).