* [U-Boot] [PATCH RFC 1/4] ARMV7: OMAP: I2C driver: Use same timeout value as linux kernel driver
2010-10-19 4:35 [U-Boot] [PATCH RFC 0/4] ARMV7: OMAP: I2C driver: Restructure code to eliminate udelay calls and improve performance Steve Sakoman
@ 2010-10-19 4:35 ` Steve Sakoman
2010-10-20 5:49 ` Heiko Schocher
2010-10-19 4:35 ` [U-Boot] [PATCH RFC 2/4] ARMV7: OMAP: I2C driver: Restructure i2c_read_byte function Steve Sakoman
` (2 subsequent siblings)
3 siblings, 1 reply; 12+ messages in thread
From: Steve Sakoman @ 2010-10-19 4:35 UTC (permalink / raw)
To: u-boot
This patch matches the poll interval (1 millisecond) and timeout (1 second)
used in the linux driver. It also adds a return value of 0 in the event of
a timeout error and cleans up some formatting errors in that section of the
code.
Signed-off-by: Steve Sakoman <steve.sakoman@linaro.org>
---
drivers/i2c/omap24xx_i2c.c | 14 ++++++++------
1 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/drivers/i2c/omap24xx_i2c.c b/drivers/i2c/omap24xx_i2c.c
index 3febd1f..b69d051 100644
--- a/drivers/i2c/omap24xx_i2c.c
+++ b/drivers/i2c/omap24xx_i2c.c
@@ -27,7 +27,7 @@
#include "omap24xx_i2c.h"
-#define I2C_TIMEOUT 10
+#define I2C_TIMEOUT 1000
static void wait_for_bb (void);
static u16 wait_for_pin (void);
@@ -392,13 +392,13 @@ int i2c_write (uchar chip, uint addr, int alen, uchar * buffer, int len)
static void wait_for_bb (void)
{
- int timeout = 10;
+ int timeout = I2C_TIMEOUT;
u16 stat;
writew(0xFFFF, &i2c_base->stat); /* clear current interruts...*/
while ((stat = readw (&i2c_base->stat) & I2C_STAT_BB) && timeout--) {
writew (stat, &i2c_base->stat);
- udelay (50000);
+ udelay(1000);
}
if (timeout <= 0) {
@@ -411,7 +411,7 @@ static void wait_for_bb (void)
static u16 wait_for_pin (void)
{
u16 status;
- int timeout = 10;
+ int timeout = I2C_TIMEOUT;
do {
udelay (1000);
@@ -424,8 +424,10 @@ static u16 wait_for_pin (void)
if (timeout <= 0) {
printf ("timed out in wait_for_pin: I2C_STAT=%x\n",
readw (&i2c_base->stat));
- writew(0xFFFF, &i2c_base->stat);
-}
+ writew(0xFFFF, &i2c_base->stat);
+ status = 0;
+ }
+
return status;
}
--
1.7.0.4
^ permalink raw reply related [flat|nested] 12+ messages in thread* [U-Boot] [PATCH RFC 1/4] ARMV7: OMAP: I2C driver: Use same timeout value as linux kernel driver
2010-10-19 4:35 ` [U-Boot] [PATCH RFC 1/4] ARMV7: OMAP: I2C driver: Use same timeout value as linux kernel driver Steve Sakoman
@ 2010-10-20 5:49 ` Heiko Schocher
0 siblings, 0 replies; 12+ messages in thread
From: Heiko Schocher @ 2010-10-20 5:49 UTC (permalink / raw)
To: u-boot
Hello Steve,
Steve Sakoman wrote:
> This patch matches the poll interval (1 millisecond) and timeout (1 second)
> used in the linux driver. It also adds a return value of 0 in the event of
> a timeout error and cleans up some formatting errors in that section of the
> code.
>
> Signed-off-by: Steve Sakoman <steve.sakoman@linaro.org>
> ---
> drivers/i2c/omap24xx_i2c.c | 14 ++++++++------
> 1 files changed, 8 insertions(+), 6 deletions(-)
Applied to u-boot-i2c master
Thanks!
bye,
Heiko
--
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
^ permalink raw reply [flat|nested] 12+ messages in thread
* [U-Boot] [PATCH RFC 2/4] ARMV7: OMAP: I2C driver: Restructure i2c_read_byte function
2010-10-19 4:35 [U-Boot] [PATCH RFC 0/4] ARMV7: OMAP: I2C driver: Restructure code to eliminate udelay calls and improve performance Steve Sakoman
2010-10-19 4:35 ` [U-Boot] [PATCH RFC 1/4] ARMV7: OMAP: I2C driver: Use same timeout value as linux kernel driver Steve Sakoman
@ 2010-10-19 4:35 ` Steve Sakoman
2010-10-20 5:50 ` Heiko Schocher
2010-10-19 4:35 ` [U-Boot] [PATCH RFC 3/4] ARMV7: OMAP: I2C driver: Restructure i2c_write_byte function Steve Sakoman
2010-10-19 4:35 ` [U-Boot] [PATCH RFC 4/4] ARMV7: OMAP: I2C driver: Restructure i2c_probe function Steve Sakoman
3 siblings, 1 reply; 12+ messages in thread
From: Steve Sakoman @ 2010-10-19 4:35 UTC (permalink / raw)
To: u-boot
This patch removes the "magic number" delays and instead
monitors state changes in the status register bits.
Signed-off-by: Steve Sakoman <steve.sakomanlinaro.org>
---
drivers/i2c/omap24xx_i2c.c | 76 +++++++++++++++++++++----------------------
1 files changed, 37 insertions(+), 39 deletions(-)
diff --git a/drivers/i2c/omap24xx_i2c.c b/drivers/i2c/omap24xx_i2c.c
index b69d051..d176b5d 100644
--- a/drivers/i2c/omap24xx_i2c.c
+++ b/drivers/i2c/omap24xx_i2c.c
@@ -159,58 +159,56 @@ static int i2c_read_byte (u8 devaddr, u8 regoffset, u8 * value)
/* no stop bit needed here */
writew (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX, &i2c_base->con);
- status = wait_for_pin ();
-
- if (status & I2C_STAT_XRDY) {
- /* Important: have to use byte access */
- writeb (regoffset, &i2c_base->data);
- udelay (20000);
- if (readw (&i2c_base->stat) & I2C_STAT_NACK) {
+ /* send register offset */
+ while (1) {
+ status = wait_for_pin();
+ if (status == 0 || status & I2C_STAT_NACK) {
i2c_error = 1;
+ goto read_exit;
+ }
+ if (status & I2C_STAT_XRDY) {
+ /* Important: have to use byte access */
+ writeb(regoffset, &i2c_base->data);
+ writew(I2C_STAT_XRDY, &i2c_base->stat);
+ }
+ if (status & I2C_STAT_ARDY) {
+ writew(I2C_STAT_ARDY, &i2c_base->stat);
+ break;
}
- } else {
- i2c_error = 1;
}
- if (!i2c_error) {
- writew (I2C_CON_EN, &i2c_base->con);
- while (readw(&i2c_base->stat) &
- (I2C_STAT_XRDY | I2C_STAT_ARDY)) {
- udelay (10000);
- /* Have to clear pending interrupt to clear I2C_STAT */
- writew (0xFFFF, &i2c_base->stat);
+ /* set slave address */
+ writew(devaddr, &i2c_base->sa);
+ /* read one byte from slave */
+ writew(1, &i2c_base->cnt);
+ /* need stop bit here */
+ writew(I2C_CON_EN | I2C_CON_MST |
+ I2C_CON_STT | I2C_CON_STP,
+ &i2c_base->con);
+
+ /* receive data */
+ while (1) {
+ status = wait_for_pin();
+ if (status == 0 || status & I2C_STAT_NACK) {
+ i2c_error = 1;
+ goto read_exit;
}
-
- /* set slave address */
- writew (devaddr, &i2c_base->sa);
- /* read one byte from slave */
- writew (1, &i2c_base->cnt);
- /* need stop bit here */
- writew (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP,
- &i2c_base->con);
-
- status = wait_for_pin ();
if (status & I2C_STAT_RRDY) {
#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) || \
defined(CONFIG_OMAP44XX)
- *value = readb (&i2c_base->data);
+ *value = readb(&i2c_base->data);
#else
- *value = readw (&i2c_base->data);
+ *value = readw(&i2c_base->data);
#endif
- udelay (20000);
- } else {
- i2c_error = 1;
+ writew(I2C_STAT_RRDY, &i2c_base->stat);
}
-
- if (!i2c_error) {
- writew (I2C_CON_EN, &i2c_base->con);
- while (readw (&i2c_base->stat) &
- (I2C_STAT_RRDY | I2C_STAT_ARDY)) {
- udelay (10000);
- writew (0xFFFF, &i2c_base->stat);
- }
+ if (status & I2C_STAT_ARDY) {
+ writew(I2C_STAT_ARDY, &i2c_base->stat);
+ break;
}
}
+
+read_exit:
flush_fifo();
writew (0xFFFF, &i2c_base->stat);
writew (0, &i2c_base->cnt);
--
1.7.0.4
^ permalink raw reply related [flat|nested] 12+ messages in thread* [U-Boot] [PATCH RFC 3/4] ARMV7: OMAP: I2C driver: Restructure i2c_write_byte function
2010-10-19 4:35 [U-Boot] [PATCH RFC 0/4] ARMV7: OMAP: I2C driver: Restructure code to eliminate udelay calls and improve performance Steve Sakoman
2010-10-19 4:35 ` [U-Boot] [PATCH RFC 1/4] ARMV7: OMAP: I2C driver: Use same timeout value as linux kernel driver Steve Sakoman
2010-10-19 4:35 ` [U-Boot] [PATCH RFC 2/4] ARMV7: OMAP: I2C driver: Restructure i2c_read_byte function Steve Sakoman
@ 2010-10-19 4:35 ` Steve Sakoman
2010-10-20 5:50 ` Heiko Schocher
2010-10-20 6:08 ` Heiko Schocher
2010-10-19 4:35 ` [U-Boot] [PATCH RFC 4/4] ARMV7: OMAP: I2C driver: Restructure i2c_probe function Steve Sakoman
3 siblings, 2 replies; 12+ messages in thread
From: Steve Sakoman @ 2010-10-19 4:35 UTC (permalink / raw)
To: u-boot
This patch removes the "magic number" delays and instead
monitors state changes in the status register bits.
Signed-off-by: Steve Sakoman <steve.sakoman@linaro.org>
---
drivers/i2c/omap24xx_i2c.c | 76 +++++++++++++++++++++++--------------------
1 files changed, 41 insertions(+), 35 deletions(-)
diff --git a/drivers/i2c/omap24xx_i2c.c b/drivers/i2c/omap24xx_i2c.c
index d176b5d..828264e 100644
--- a/drivers/i2c/omap24xx_i2c.c
+++ b/drivers/i2c/omap24xx_i2c.c
@@ -231,49 +231,55 @@ static int i2c_write_byte (u8 devaddr, u8 regoffset, u8 value)
writew (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX |
I2C_CON_STP, &i2c_base->con);
- /* wait until state change */
- status = wait_for_pin ();
-
- if (status & I2C_STAT_XRDY) {
-#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) || \
- defined(CONFIG_OMAP44XX)
- /* send out 1 byte */
- writeb (regoffset, &i2c_base->data);
- writew (I2C_STAT_XRDY, &i2c_base->stat);
-
- status = wait_for_pin ();
- if ((status & I2C_STAT_XRDY)) {
- /* send out next 1 byte */
- writeb (value, &i2c_base->data);
- writew (I2C_STAT_XRDY, &i2c_base->stat);
- } else {
+ while (1) {
+ status = wait_for_pin();
+ if (status == 0 || status & I2C_STAT_NACK) {
i2c_error = 1;
+ goto write_exit;
}
+ if (status & I2C_STAT_XRDY) {
+#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) || \
+ defined(CONFIG_OMAP44XX)
+ /* send register offset */
+ writeb(regoffset, &i2c_base->data);
+ writew(I2C_STAT_XRDY, &i2c_base->stat);
+
+ while (1) {
+ status = wait_for_pin();
+ if (status == 0 || status & I2C_STAT_NACK) {
+ i2c_error = 1;
+ goto write_exit;
+ }
+ if (status & I2C_STAT_XRDY) {
+ /* send data */
+ writeb(value, &i2c_base->data);
+ writew(I2C_STAT_XRDY, &i2c_base->stat);
+ }
+ if (status & I2C_STAT_ARDY) {
+ writew(I2C_STAT_ARDY, &i2c_base->stat);
+ break;
+ }
+ }
+ break;
#else
- /* send out two bytes */
- writew ((value << 8) + regoffset, &i2c_base->data);
+ /* send out two bytes */
+ writew((value << 8) + regoffset, &i2c_base->data);
+ writew(I2C_STAT_XRDY, &i2c_base->stat);
#endif
- /* must have enough delay to allow BB bit to go low */
- udelay (50000);
- if (readw (&i2c_base->stat) & I2C_STAT_NACK) {
- i2c_error = 1;
}
- } else {
- i2c_error = 1;
+ if (status & I2C_STAT_ARDY) {
+ writew(I2C_STAT_ARDY, &i2c_base->stat);
+ break;
+ }
}
- if (!i2c_error) {
- int eout = 200;
+ wait_for_bb();
- writew (I2C_CON_EN, &i2c_base->con);
- while ((stat = readw (&i2c_base->stat)) || (readw (&i2c_base->con) & I2C_CON_MST)) {
- udelay (1000);
- /* have to read to clear intrrupt */
- writew (0xFFFF, &i2c_base->stat);
- if(--eout == 0) /* better leave with error than hang */
- break;
- }
- }
+ status = readw(&i2c_base->stat);
+ if (status & I2C_STAT_NACK)
+ i2c_error = 1;
+
+write_exit:
flush_fifo();
writew (0xFFFF, &i2c_base->stat);
writew (0, &i2c_base->cnt);
--
1.7.0.4
^ permalink raw reply related [flat|nested] 12+ messages in thread* [U-Boot] [PATCH RFC 3/4] ARMV7: OMAP: I2C driver: Restructure i2c_write_byte function
2010-10-19 4:35 ` [U-Boot] [PATCH RFC 3/4] ARMV7: OMAP: I2C driver: Restructure i2c_write_byte function Steve Sakoman
@ 2010-10-20 5:50 ` Heiko Schocher
2010-10-20 6:08 ` Heiko Schocher
1 sibling, 0 replies; 12+ messages in thread
From: Heiko Schocher @ 2010-10-20 5:50 UTC (permalink / raw)
To: u-boot
Hello Steve,
Steve Sakoman wrote:
> This patch removes the "magic number" delays and instead
> monitors state changes in the status register bits.
>
> Signed-off-by: Steve Sakoman <steve.sakoman@linaro.org>
> ---
> drivers/i2c/omap24xx_i2c.c | 76 +++++++++++++++++++++++--------------------
> 1 files changed, 41 insertions(+), 35 deletions(-)
Applied to u-boot-i2c master
Thanks!
bye,
Heiko
--
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
^ permalink raw reply [flat|nested] 12+ messages in thread
* [U-Boot] [PATCH RFC 3/4] ARMV7: OMAP: I2C driver: Restructure i2c_write_byte function
2010-10-19 4:35 ` [U-Boot] [PATCH RFC 3/4] ARMV7: OMAP: I2C driver: Restructure i2c_write_byte function Steve Sakoman
2010-10-20 5:50 ` Heiko Schocher
@ 2010-10-20 6:08 ` Heiko Schocher
2010-10-20 13:11 ` Steve Sakoman
1 sibling, 1 reply; 12+ messages in thread
From: Heiko Schocher @ 2010-10-20 6:08 UTC (permalink / raw)
To: u-boot
Hello Steve,
Steve Sakoman wrote:
> This patch removes the "magic number" delays and instead
> monitors state changes in the status register bits.
>
> Signed-off-by: Steve Sakoman <steve.sakoman@linaro.org>
> ---
> drivers/i2c/omap24xx_i2c.c | 76 +++++++++++++++++++++++--------------------
> 1 files changed, 41 insertions(+), 35 deletions(-)
After trying this for the omap3_beagle board, I get an
compiler warning:
[hs at pollux u-boot]$ ./MAKEALL omap3_beagle
Configuring for omap3_beagle board...
omap24xx_i2c.c: In function 'i2c_write_byte':
omap24xx_i2c.c:221: warning: unused variable 'stat'
text data bss dec hex filename
218103 11412 202384 431899 6971b ./u-boot
--------------------- SUMMARY ----------------------------
Boards compiled: 1
Boards with warnings or errors: 1 ( omap3_beagle )
----------------------------------------------------------
[hs at pollux u-boot]$
following patch fixes it.
BTW:
Just for the record, your patchset works fine and faster
on the beagle board, for example:
before your after your
patchset patchset
i2c probe 9s 0,4s
i2c md 48 0 100 17s 1s
would you post a v2 of this patch, and I add my
"Tested-by" to it, or is it OK, if I add my fix patch
to u-boot-i2c master?
^ permalink raw reply [flat|nested] 12+ messages in thread* [U-Boot] [PATCH RFC 3/4] ARMV7: OMAP: I2C driver: Restructure i2c_write_byte function
2010-10-20 6:08 ` Heiko Schocher
@ 2010-10-20 13:11 ` Steve Sakoman
2010-10-20 13:22 ` Heiko Schocher
0 siblings, 1 reply; 12+ messages in thread
From: Steve Sakoman @ 2010-10-20 13:11 UTC (permalink / raw)
To: u-boot
On Wed, 2010-10-20 at 08:08 +0200, Heiko Schocher wrote:
> Hello Steve,
>
> Steve Sakoman wrote:
> > This patch removes the "magic number" delays and instead
> > monitors state changes in the status register bits.
> >
> > Signed-off-by: Steve Sakoman <steve.sakoman@linaro.org>
> > ---
> > drivers/i2c/omap24xx_i2c.c | 76 +++++++++++++++++++++++--------------------
> > 1 files changed, 41 insertions(+), 35 deletions(-)
>
> After trying this for the omap3_beagle board, I get an
> compiler warning:
>
> [hs at pollux u-boot]$ ./MAKEALL omap3_beagle
> Configuring for omap3_beagle board...
> omap24xx_i2c.c: In function 'i2c_write_byte':
> omap24xx_i2c.c:221: warning: unused variable 'stat'
Hmm . . . I can swear I fixed that! Must be getting old :-)
> text data bss dec hex filename
> 218103 11412 202384 431899 6971b ./u-boot
>
> --------------------- SUMMARY ----------------------------
> Boards compiled: 1
> Boards with warnings or errors: 1 ( omap3_beagle )
> ----------------------------------------------------------
> [hs at pollux u-boot]$
>
> following patch fixes it.
>
> BTW:
> Just for the record, your patchset works fine and faster
> on the beagle board, for example:
>
> before your after your
> patchset patchset
> i2c probe 9s 0,4s
> i2c md 48 0 100 17s 1s
I'm glad that you see the same speedups!
What tool do you use to measure the speedups?
> would you post a v2 of this patch, and I add my
> "Tested-by" to it, or is it OK, if I add my fix patch
> to u-boot-i2c master?
I've posted v2 with your "Tested-by" and the warning fix.
If it helps, the patches are in my omap4-next-upstream branch:
http://www.sakoman.com/cgi-bin/gitweb.cgi?p=u-boot.git;a=shortlog;h=refs/heads/omap4-next-upstream
Thanks for testing and for the comments!
Steve
> From 01c6c59014c4174ad4d13944d740d3491d9cf137 Mon Sep 17 00:00:00 2001
> From: Heiko Schocher <hs@denx.de>
> Date: Wed, 20 Oct 2010 07:57:05 +0200
> Subject: [PATCH] ARMV7: OMAP: I2C driver: fix compiler warning
>
> Signed-off-by: Heiko Schocher <hs@denx.de>
> ---
> drivers/i2c/omap24xx_i2c.c | 2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/i2c/omap24xx_i2c.c b/drivers/i2c/omap24xx_i2c.c
> index eb153fb..a72d1a1 100644
> --- a/drivers/i2c/omap24xx_i2c.c
> +++ b/drivers/i2c/omap24xx_i2c.c
> @@ -218,7 +218,7 @@ read_exit:
> static int i2c_write_byte (u8 devaddr, u8 regoffset, u8 value)
> {
> int i2c_error = 0;
> - u16 status, stat;
> + u16 status;
>
> /* wait until bus not busy */
> wait_for_bb ();
>
> bye,
> Heiko
^ permalink raw reply [flat|nested] 12+ messages in thread* [U-Boot] [PATCH RFC 3/4] ARMV7: OMAP: I2C driver: Restructure i2c_write_byte function
2010-10-20 13:11 ` Steve Sakoman
@ 2010-10-20 13:22 ` Heiko Schocher
0 siblings, 0 replies; 12+ messages in thread
From: Heiko Schocher @ 2010-10-20 13:22 UTC (permalink / raw)
To: u-boot
Hello Steve,
Steve Sakoman wrote:
> On Wed, 2010-10-20 at 08:08 +0200, Heiko Schocher wrote:
>> Hello Steve,
>>
>> Steve Sakoman wrote:
>>> This patch removes the "magic number" delays and instead
>>> monitors state changes in the status register bits.
>>>
>>> Signed-off-by: Steve Sakoman <steve.sakoman@linaro.org>
>>> ---
>>> drivers/i2c/omap24xx_i2c.c | 76 +++++++++++++++++++++++--------------------
>>> 1 files changed, 41 insertions(+), 35 deletions(-)
>> After trying this for the omap3_beagle board, I get an
>> compiler warning:
>>
>> [hs at pollux u-boot]$ ./MAKEALL omap3_beagle
>> Configuring for omap3_beagle board...
>> omap24xx_i2c.c: In function 'i2c_write_byte':
>> omap24xx_i2c.c:221: warning: unused variable 'stat'
>
> Hmm . . . I can swear I fixed that! Must be getting old :-)
;-)
>> text data bss dec hex filename
>> 218103 11412 202384 431899 6971b ./u-boot
>>
>> --------------------- SUMMARY ----------------------------
>> Boards compiled: 1
>> Boards with warnings or errors: 1 ( omap3_beagle )
>> ----------------------------------------------------------
>> [hs at pollux u-boot]$
>>
>> following patch fixes it.
>>
>> BTW:
>> Just for the record, your patchset works fine and faster
>> on the beagle board, for example:
>>
>> before your after your
>> patchset patchset
>> i2c probe 9s 0,4s
>> i2c md 48 0 100 17s 1s
>
> I'm glad that you see the same speedups!
>
> What tool do you use to measure the speedups?
You find it here:
ftp://ftp.denx.de/pub/tools/time_log
You can start this script for example with:
kermit -c 2>&1 | ./time_log "start"
and then measure with for example:
echo start;i2c md 48 0 100;echo stop
and you get the time the command(s) between start
and stop needed ...
>> would you post a v2 of this patch, and I add my
>> "Tested-by" to it, or is it OK, if I add my fix patch
>> to u-boot-i2c master?
>
> I've posted v2 with your "Tested-by" and the warning fix.
Ok, thanks!
bye,
Heiko
--
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
^ permalink raw reply [flat|nested] 12+ messages in thread
* [U-Boot] [PATCH RFC 4/4] ARMV7: OMAP: I2C driver: Restructure i2c_probe function
2010-10-19 4:35 [U-Boot] [PATCH RFC 0/4] ARMV7: OMAP: I2C driver: Restructure code to eliminate udelay calls and improve performance Steve Sakoman
` (2 preceding siblings ...)
2010-10-19 4:35 ` [U-Boot] [PATCH RFC 3/4] ARMV7: OMAP: I2C driver: Restructure i2c_write_byte function Steve Sakoman
@ 2010-10-19 4:35 ` Steve Sakoman
2010-10-20 5:51 ` Heiko Schocher
3 siblings, 1 reply; 12+ messages in thread
From: Steve Sakoman @ 2010-10-19 4:35 UTC (permalink / raw)
To: u-boot
This patch removes the "magic number" delays and instead
monitors state changes in the status register bits.
Signed-off-by: Steve Sakoman <steve.sakoman@linaro.org>
---
drivers/i2c/omap24xx_i2c.c | 41 ++++++++++++++++++++++++++++++-----------
1 files changed, 30 insertions(+), 11 deletions(-)
diff --git a/drivers/i2c/omap24xx_i2c.c b/drivers/i2c/omap24xx_i2c.c
index 828264e..eb153fb 100644
--- a/drivers/i2c/omap24xx_i2c.c
+++ b/drivers/i2c/omap24xx_i2c.c
@@ -310,6 +310,7 @@ static void flush_fifo(void)
int i2c_probe (uchar chip)
{
+ u16 status;
int res = 1; /* default = fail */
if (chip == readw (&i2c_base->oa)) {
@@ -325,19 +326,37 @@ int i2c_probe (uchar chip)
writew (chip, &i2c_base->sa);
/* stop bit needed here */
writew (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP, &i2c_base->con);
- /* enough delay for the NACK bit set */
- udelay (50000);
- if (!(readw (&i2c_base->stat) & I2C_STAT_NACK)) {
- res = 0; /* success case */
- flush_fifo();
- writew(0xFFFF, &i2c_base->stat);
- } else {
- writew(0xFFFF, &i2c_base->stat); /* failue, clear sources*/
- writew (readw (&i2c_base->con) | I2C_CON_STP, &i2c_base->con); /* finish up xfer */
- udelay(20000);
- wait_for_bb ();
+ while (1) {
+ status = wait_for_pin();
+ if (status == 0) {
+ res = 1;
+ goto probe_exit;
+ }
+ if (status & I2C_STAT_NACK) {
+ res = 1;
+ writew(0xff, &i2c_base->stat);
+ writew (readw (&i2c_base->con) | I2C_CON_STP, &i2c_base->con);
+ wait_for_bb ();
+ break;
+ }
+ if (status & I2C_STAT_ARDY) {
+ writew(I2C_STAT_ARDY, &i2c_base->stat);
+ break;
+ }
+ if (status & I2C_STAT_RRDY) {
+ res = 0;
+#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) || \
+ defined(CONFIG_OMAP44XX)
+ readb(&i2c_base->data);
+#else
+ readw(&i2c_base->data);
+#endif
+ writew(I2C_STAT_RRDY, &i2c_base->stat);
+ }
}
+
+probe_exit:
flush_fifo();
writew (0, &i2c_base->cnt); /* don't allow any more data in...we don't want it.*/
writew(0xFFFF, &i2c_base->stat);
--
1.7.0.4
^ permalink raw reply related [flat|nested] 12+ messages in thread