[U-Boot] [PATCH 0/3] i2c for R-mobile

Hi, Iwamatsu-san
I managed to work i2c on KZM-A9-GT board. Now "i2c md" and "i2c mw" for i2c channel 0 work properly. I think this modification is common for R-mobile, but I have SH73A0 document only. Iwamatu-san, plese review this.
This patch set is based on arm/rmobile branch of u-boot-sh.git.
Tetsuyuki Kobayashi (3): i2c: sh_i2c.c: support iccl and icch extension i2c: sh_i2c.c: correct BUSY bit define in ICSR i2c: sh_i2c.c: adjust for SH73A0
drivers/i2c/sh_i2c.c | 38 +++++++++++++++++++++++++++++--------- include/configs/kzm9g.h | 2 +- 2 files changed, 30 insertions(+), 10 deletions(-)

R-mobile SoC (at least SH73A0) has extension bits to store 8th bit of iccl and icch. This patch add support for the extentin bits.
Signed-off-by: Tetsuyuki Kobayashi koba@kmckk.co.jp --- drivers/i2c/sh_i2c.c | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-)
diff --git a/drivers/i2c/sh_i2c.c b/drivers/i2c/sh_i2c.c index fd8cb92..59402ba 100644 --- a/drivers/i2c/sh_i2c.c +++ b/drivers/i2c/sh_i2c.c @@ -48,7 +48,15 @@ static struct sh_i2c *base; #define SH_IC_WAIT (1 << 1) #define SH_IC_DTE (1 << 0)
-static u8 iccl, icch; +#if defined(CONFIG_SH73A0) +#define HAS_ICIC67 +#endif +#ifdef HAS_ICIC67 +#define SH_I2C_ICIC_ICCLB8 (1 << 7) +#define SH_I2C_ICIC_ICCHB8 (1 << 6) +#endif + +static u16 iccl, icch;
#define IRQ_WAIT 1000
@@ -92,12 +100,20 @@ static void irq_busy(struct sh_i2c *base)
static void i2c_set_addr(struct sh_i2c *base, u8 id, u8 reg, int stop) { + u8 icic = 0; + writeb(readb(&base->iccr) & ~SH_I2C_ICCR_ICE, &base->iccr); writeb(readb(&base->iccr) | SH_I2C_ICCR_ICE, &base->iccr);
- writeb(iccl, &base->iccl); - writeb(icch, &base->icch); - writeb(0, &base->icic); + writeb(iccl & 0xff, &base->iccl); + writeb(icch & 0xff, &base->icch); +#ifdef HAS_ICIC67 + if (iccl > 0xff) + icic |= SH_I2C_ICIC_ICCLB8; + if (icch > 0xff) + icic |= SH_I2C_ICIC_ICCHB8; +#endif + writeb(icic, &base->icic);
writeb((SH_I2C_ICCR_ICE|SH_I2C_ICCR_RTS|SH_I2C_ICCR_BUSY), &base->iccr); irq_dte(base); @@ -222,18 +238,18 @@ void i2c_init(int speed, int slaveaddr) denom = speed * (CONFIG_SH_I2C_DATA_HIGH + CONFIG_SH_I2C_DATA_LOW); tmp = num * 10 / denom; if (tmp % 10 >= 5) - iccl = (u8)((num/denom) + 1); + iccl = (u16)((num/denom) + 1); else - iccl = (u8)(num/denom); + iccl = (u16)(num/denom);
/* Calculate the value for icch. From the data sheet: icch = (p clock / transfer rate) * (H / (L + H)) */ num = CONFIG_SH_I2C_CLOCK * CONFIG_SH_I2C_DATA_HIGH; tmp = num * 10 / denom; if (tmp % 10 >= 5) - icch = (u8)((num/denom) + 1); + icch = (u16)((num/denom) + 1); else - icch = (u8)(num/denom); + icch = (u16)(num/denom); }
/*

Hi,
I add Heiko Schocher hs@denx.de to Cc: Heiko is I2C maintainer.
On Tue, Sep 11, 2012 at 2:58 PM, Tetsuyuki Kobayashi koba@kmckk.co.jp wrote:
R-mobile SoC (at least SH73A0) has extension bits to store 8th bit of iccl and icch. This patch add support for the extentin bits.
Signed-off-by: Tetsuyuki Kobayashi koba@kmckk.co.jp
drivers/i2c/sh_i2c.c | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-)
diff --git a/drivers/i2c/sh_i2c.c b/drivers/i2c/sh_i2c.c index fd8cb92..59402ba 100644 --- a/drivers/i2c/sh_i2c.c +++ b/drivers/i2c/sh_i2c.c @@ -48,7 +48,15 @@ static struct sh_i2c *base; #define SH_IC_WAIT (1 << 1) #define SH_IC_DTE (1 << 0)
-static u8 iccl, icch; +#if defined(CONFIG_SH73A0) +#define HAS_ICIC67 +#endif +#ifdef HAS_ICIC67 +#define SH_I2C_ICIC_ICCLB8 (1 << 7) +#define SH_I2C_ICIC_ICCHB8 (1 << 6) +#endif
I think that it was better to define CONFIG_SH_I2C_8BIT or CONFIG_SH_I2C_HAS_ICIC67 in board config. Because R8A7740 have this function too. I am working to support i2c of this CPU. For example ....
#define CONFIG_SH_I2C_8BIT #define SH_I2C_ICIC_ICCLB8 (1 << 7) #define SH_I2C_ICIC_ICCHB8 (1 << 6) #endif
I think that this is too simple.
+static u16 iccl, icch;
#define IRQ_WAIT 1000
@@ -92,12 +100,20 @@ static void irq_busy(struct sh_i2c *base)
static void i2c_set_addr(struct sh_i2c *base, u8 id, u8 reg, int stop) {
u8 icic = 0;
writeb(readb(&base->iccr) & ~SH_I2C_ICCR_ICE, &base->iccr); writeb(readb(&base->iccr) | SH_I2C_ICCR_ICE, &base->iccr);
writeb(iccl, &base->iccl);
writeb(icch, &base->icch);
writeb(0, &base->icic);
writeb(iccl & 0xff, &base->iccl);
writeb(icch & 0xff, &base->icch);
+#ifdef HAS_ICIC67
if (iccl > 0xff)
icic |= SH_I2C_ICIC_ICCLB8;
if (icch > 0xff)
icic |= SH_I2C_ICIC_ICCHB8;
+#endif
writeb(icic, &base->icic); writeb((SH_I2C_ICCR_ICE|SH_I2C_ICCR_RTS|SH_I2C_ICCR_BUSY), &base->iccr); irq_dte(base);
@@ -222,18 +238,18 @@ void i2c_init(int speed, int slaveaddr) denom = speed * (CONFIG_SH_I2C_DATA_HIGH + CONFIG_SH_I2C_DATA_LOW); tmp = num * 10 / denom; if (tmp % 10 >= 5)
iccl = (u8)((num/denom) + 1);
iccl = (u16)((num/denom) + 1); else
iccl = (u8)(num/denom);
iccl = (u16)(num/denom); /* Calculate the value for icch. From the data sheet: icch = (p clock / transfer rate) * (H / (L + H)) */ num = CONFIG_SH_I2C_CLOCK * CONFIG_SH_I2C_DATA_HIGH; tmp = num * 10 / denom; if (tmp % 10 >= 5)
icch = (u8)((num/denom) + 1);
icch = (u16)((num/denom) + 1); else
icch = (u8)(num/denom);
icch = (u16)(num/denom);
}
/*
1.7.9.5
Best regards, Nobuhiro

Correct BUSY bit define in ICSR from (1<<3) to (1<<4).
Signed-off-by: Tetsuyuki Kobayashi koba@kmckk.co.jp --- Iwamatsu-san, I guess this was mistake. But I don't have technical document other than SH73A0. Could you verify?
drivers/i2c/sh_i2c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/i2c/sh_i2c.c b/drivers/i2c/sh_i2c.c index 59402ba..84f1f5b 100644 --- a/drivers/i2c/sh_i2c.c +++ b/drivers/i2c/sh_i2c.c @@ -43,7 +43,7 @@ static struct sh_i2c *base; #define SH_I2C_ICCR_SCP (1 << 0)
/* ICSR / ICIC */ -#define SH_IC_BUSY (1 << 3) +#define SH_IC_BUSY (1 << 4) #define SH_IC_TACK (1 << 2) #define SH_IC_WAIT (1 << 1) #define SH_IC_DTE (1 << 0)

Hi,
I add Heiko Schocher hs@denx.de to Cc: Heiko is I2C maintainer.
On Tue, Sep 11, 2012 at 2:58 PM, Tetsuyuki Kobayashi koba@kmckk.co.jp wrote:
Correct BUSY bit define in ICSR from (1<<3) to (1<<4).
Signed-off-by: Tetsuyuki Kobayashi koba@kmckk.co.jp
Iwamatsu-san, I guess this was mistake. But I don't have technical document other than SH73A0. Could you verify?
Yes, this is typo. 3 is AL bit. Thanks!
Acked-by: Nobuhiro Iwamatsu nobuhiro.iwamatsu.yj@renesas.com
drivers/i2c/sh_i2c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/i2c/sh_i2c.c b/drivers/i2c/sh_i2c.c index 59402ba..84f1f5b 100644 --- a/drivers/i2c/sh_i2c.c +++ b/drivers/i2c/sh_i2c.c @@ -43,7 +43,7 @@ static struct sh_i2c *base; #define SH_I2C_ICCR_SCP (1 << 0)
/* ICSR / ICIC */ -#define SH_IC_BUSY (1 << 3) +#define SH_IC_BUSY (1 << 4) #define SH_IC_TACK (1 << 2) #define SH_IC_WAIT (1 << 1)
#define SH_IC_DTE (1 << 0)
1.7.9.5

Adjust i2c_raw_read() in sh_i2c.c to work for SH73A0. After this patch, "i2c md" and "i2c mw" command on U-Boot work properly on KZM-A9-GT board.
Signed-off-by: Tetsuyuki Kobayashi koba@kmckk.co.jp --- drivers/i2c/sh_i2c.c | 4 ++++ include/configs/kzm9g.h | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/i2c/sh_i2c.c b/drivers/i2c/sh_i2c.c index 84f1f5b..e8efdc9 100644 --- a/drivers/i2c/sh_i2c.c +++ b/drivers/i2c/sh_i2c.c @@ -153,8 +153,12 @@ static u8 i2c_raw_read(struct sh_i2c *base, u8 id, u8 reg) { u8 ret;
+#if defined(CONFIG_SH73A0) + i2c_set_addr(base, id, reg, 0); +#else i2c_set_addr(base, id, reg, 1); udelay(100); +#endif
writeb((SH_I2C_ICCR_ICE|SH_I2C_ICCR_RTS|SH_I2C_ICCR_BUSY), &base->iccr); irq_dte(base); diff --git a/include/configs/kzm9g.h b/include/configs/kzm9g.h index a1ae718..5eccd29 100644 --- a/include/configs/kzm9g.h +++ b/include/configs/kzm9g.h @@ -163,7 +163,7 @@ #define CONFIG_SYS_I2C_SLAVE (0x7F) #define CONFIG_SH_I2C_DATA_HIGH (4) #define CONFIG_SH_I2C_DATA_LOW (5) -#define CONFIG_SH_I2C_CLOCK (41666666) +#define CONFIG_SH_I2C_CLOCK (104000000) /* 104 MHz */ #define CONFIG_SH_I2C_BASE0 (0xE6820000) #define CONFIG_SH_I2C_BASE1 (0xE6822000)

Hi,
I add Heiko Schocher hs@denx.de to Cc: Heiko is I2C maintainer.
On Tue, Sep 11, 2012 at 2:58 PM, Tetsuyuki Kobayashi koba@kmckk.co.jp wrote:
Adjust i2c_raw_read() in sh_i2c.c to work for SH73A0. After this patch, "i2c md" and "i2c mw" command on U-Boot work properly on KZM-A9-GT board.
Signed-off-by: Tetsuyuki Kobayashi koba@kmckk.co.jp
Acked-by: Nobuhiro Iwamatsu nobuhiro.iwamatsu.yj@renesas.com
drivers/i2c/sh_i2c.c | 4 ++++ include/configs/kzm9g.h | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/i2c/sh_i2c.c b/drivers/i2c/sh_i2c.c index 84f1f5b..e8efdc9 100644 --- a/drivers/i2c/sh_i2c.c +++ b/drivers/i2c/sh_i2c.c @@ -153,8 +153,12 @@ static u8 i2c_raw_read(struct sh_i2c *base, u8 id, u8 reg) { u8 ret;
+#if defined(CONFIG_SH73A0)
i2c_set_addr(base, id, reg, 0);
+#else i2c_set_addr(base, id, reg, 1); udelay(100); +#endif
writeb((SH_I2C_ICCR_ICE|SH_I2C_ICCR_RTS|SH_I2C_ICCR_BUSY), &base->iccr); irq_dte(base);
diff --git a/include/configs/kzm9g.h b/include/configs/kzm9g.h index a1ae718..5eccd29 100644 --- a/include/configs/kzm9g.h +++ b/include/configs/kzm9g.h @@ -163,7 +163,7 @@ #define CONFIG_SYS_I2C_SLAVE (0x7F) #define CONFIG_SH_I2C_DATA_HIGH (4) #define CONFIG_SH_I2C_DATA_LOW (5) -#define CONFIG_SH_I2C_CLOCK (41666666) +#define CONFIG_SH_I2C_CLOCK (104000000) /* 104 MHz */ #define CONFIG_SH_I2C_BASE0 (0xE6820000) #define CONFIG_SH_I2C_BASE1 (0xE6822000)
-- 1.7.9.5
Best regards, Nobuhiro

Hi, Iwamatsu-san Hello, Heiko
Iwamatu-san, thank you for review. This is v2 patch for sh_i2c. Now "i2c dev" and "i2c probe" also work properly on KZM-A9-GT board. I think this modification is common for R-mobile, but I have SH73A0 document only. Iwamatu-san, please review this.
This patch set is based on arm/rmobile branch of u-boot-sh.git.
Tetsuyuki Kobayashi (9): i2c: sh_i2c.c: support iccl and icch extension i2c: sh_i2c.c: correct BUSY bit define in ICSR i2c: sh_i2c.c: adjust for SH73A0 i2c: sh_i2c.c: support I2C2, I2C3 and I2C4 i2c: sh_i2c: enable i2c_probe i2c: sh_i2c.c: check error in i2c_read and i2c_write i2c: sh_i2c.c: remove unused function arm: rmobile: kzm9g: enable I2C1 arm: rmobile: kzm9g: enable I2C2
board/kmc/kzm9g/kzm9g.c | 7 ++- drivers/i2c/sh_i2c.c | 120 +++++++++++++++++++++++++++++++++-------------- include/configs/kzm9g.h | 8 +++- 3 files changed, 95 insertions(+), 40 deletions(-)

R-mobile SoC (at least SH73A0) has extension bits to store 8th bit of iccl and icch. This patch add support for the extentin bits.
Signed-off-by: Tetsuyuki Kobayashi koba@kmckk.co.jp --- Changes for v2: - define CONFIG_SH_I2C_8BIT at board config file and replace HAS_ICIC67.
drivers/i2c/sh_i2c.c | 30 ++++++++++++++++++++++-------- include/configs/kzm9g.h | 1 + 2 files changed, 23 insertions(+), 8 deletions(-)
diff --git a/drivers/i2c/sh_i2c.c b/drivers/i2c/sh_i2c.c index fd8cb92..b98fce5 100644 --- a/drivers/i2c/sh_i2c.c +++ b/drivers/i2c/sh_i2c.c @@ -48,7 +48,13 @@ static struct sh_i2c *base; #define SH_IC_WAIT (1 << 1) #define SH_IC_DTE (1 << 0)
-static u8 iccl, icch; +#ifdef CONFIG_SH_I2C_8BIT +/* store 8th bit of iccl and icch in ICIC register */ +#define SH_I2C_ICIC_ICCLB8 (1 << 7) +#define SH_I2C_ICIC_ICCHB8 (1 << 6) +#endif + +static u16 iccl, icch;
#define IRQ_WAIT 1000
@@ -92,12 +98,20 @@ static void irq_busy(struct sh_i2c *base)
static void i2c_set_addr(struct sh_i2c *base, u8 id, u8 reg, int stop) { + u8 icic = 0; + writeb(readb(&base->iccr) & ~SH_I2C_ICCR_ICE, &base->iccr); writeb(readb(&base->iccr) | SH_I2C_ICCR_ICE, &base->iccr);
- writeb(iccl, &base->iccl); - writeb(icch, &base->icch); - writeb(0, &base->icic); + writeb(iccl & 0xff, &base->iccl); + writeb(icch & 0xff, &base->icch); +#ifdef CONFIG_SH_I2C_8BIT + if (iccl > 0xff) + icic |= SH_I2C_ICIC_ICCLB8; + if (icch > 0xff) + icic |= SH_I2C_ICIC_ICCHB8; +#endif + writeb(icic, &base->icic);
writeb((SH_I2C_ICCR_ICE|SH_I2C_ICCR_RTS|SH_I2C_ICCR_BUSY), &base->iccr); irq_dte(base); @@ -222,18 +236,18 @@ void i2c_init(int speed, int slaveaddr) denom = speed * (CONFIG_SH_I2C_DATA_HIGH + CONFIG_SH_I2C_DATA_LOW); tmp = num * 10 / denom; if (tmp % 10 >= 5) - iccl = (u8)((num/denom) + 1); + iccl = (u16)((num/denom) + 1); else - iccl = (u8)(num/denom); + iccl = (u16)(num/denom);
/* Calculate the value for icch. From the data sheet: icch = (p clock / transfer rate) * (H / (L + H)) */ num = CONFIG_SH_I2C_CLOCK * CONFIG_SH_I2C_DATA_HIGH; tmp = num * 10 / denom; if (tmp % 10 >= 5) - icch = (u8)((num/denom) + 1); + icch = (u16)((num/denom) + 1); else - icch = (u8)(num/denom); + icch = (u16)(num/denom); }
/* diff --git a/include/configs/kzm9g.h b/include/configs/kzm9g.h index a1ae718..8877516 100644 --- a/include/configs/kzm9g.h +++ b/include/configs/kzm9g.h @@ -155,6 +155,7 @@ /* I2C */ #define CONFIG_CMD_I2C #define CONFIG_SH_I2C 1 +#define CONFIG_SH_I2C_8BIT #define CONFIG_HARD_I2C #define CONFIG_I2C_MULTI_BUS #define CONFIG_SYS_MAX_I2C_BUS (2)

Correct BUSY bit define in ICSR from (1<<3) to (1<<4).
Signed-off-by: Tetsuyuki Kobayashi koba@kmckk.co.jp --- Changes for v2: - none
drivers/i2c/sh_i2c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/i2c/sh_i2c.c b/drivers/i2c/sh_i2c.c index b98fce5..03dfa7a 100644 --- a/drivers/i2c/sh_i2c.c +++ b/drivers/i2c/sh_i2c.c @@ -43,7 +43,7 @@ static struct sh_i2c *base; #define SH_I2C_ICCR_SCP (1 << 0)
/* ICSR / ICIC */ -#define SH_IC_BUSY (1 << 3) +#define SH_IC_BUSY (1 << 4) #define SH_IC_TACK (1 << 2) #define SH_IC_WAIT (1 << 1) #define SH_IC_DTE (1 << 0)

Adjust i2c_raw_read() in sh_i2c.c to work for SH73A0. After this patch, "i2c md" and "i2c mw" command on U-Boot work properly on KZM-A9-GT board.
Signed-off-by: Tetsuyuki Kobayashi koba@kmckk.co.jp --- Changes for v2: - none
drivers/i2c/sh_i2c.c | 4 ++++ include/configs/kzm9g.h | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/i2c/sh_i2c.c b/drivers/i2c/sh_i2c.c index 03dfa7a..6c6a141 100644 --- a/drivers/i2c/sh_i2c.c +++ b/drivers/i2c/sh_i2c.c @@ -151,8 +151,12 @@ static u8 i2c_raw_read(struct sh_i2c *base, u8 id, u8 reg) { u8 ret;
+#if defined(CONFIG_SH73A0) + i2c_set_addr(base, id, reg, 0); +#else i2c_set_addr(base, id, reg, 1); udelay(100); +#endif
writeb((SH_I2C_ICCR_ICE|SH_I2C_ICCR_RTS|SH_I2C_ICCR_BUSY), &base->iccr); irq_dte(base); diff --git a/include/configs/kzm9g.h b/include/configs/kzm9g.h index 8877516..abeab69 100644 --- a/include/configs/kzm9g.h +++ b/include/configs/kzm9g.h @@ -164,7 +164,7 @@ #define CONFIG_SYS_I2C_SLAVE (0x7F) #define CONFIG_SH_I2C_DATA_HIGH (4) #define CONFIG_SH_I2C_DATA_LOW (5) -#define CONFIG_SH_I2C_CLOCK (41666666) +#define CONFIG_SH_I2C_CLOCK (104000000) /* 104 MHz */ #define CONFIG_SH_I2C_BASE0 (0xE6820000) #define CONFIG_SH_I2C_BASE1 (0xE6822000)

sh_i2c.c support I2C0 and I2C1. This patch extends it to I2C4.
Signed-off-by: Tetsuyuki Kobayashi koba@kmckk.co.jp --- Changes for v2: - new
drivers/i2c/sh_i2c.c | 15 +++++++++++++++ include/configs/kzm9g.h | 5 ++++- 2 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/drivers/i2c/sh_i2c.c b/drivers/i2c/sh_i2c.c index 6c6a141..d524619 100644 --- a/drivers/i2c/sh_i2c.c +++ b/drivers/i2c/sh_i2c.c @@ -200,6 +200,21 @@ int i2c_set_bus_num(unsigned int bus) case 1: base = (void *)CONFIG_SH_I2C_BASE1; break; +#ifdef CONFIG_SH_I2C_BASE2 + case 2: + base = (void *)CONFIG_SH_I2C_BASE2; + break; +#endif +#ifdef CONFIG_SH_I2C_BASE3 + case 3: + base = (void *)CONFIG_SH_I2C_BASE3; + break; +#endif +#ifdef CONFIG_SH_I2C_BASE4 + case 4: + base = (void *)CONFIG_SH_I2C_BASE4; + break; +#endif default: return -1; } diff --git a/include/configs/kzm9g.h b/include/configs/kzm9g.h index abeab69..6a0b6c5 100644 --- a/include/configs/kzm9g.h +++ b/include/configs/kzm9g.h @@ -158,7 +158,7 @@ #define CONFIG_SH_I2C_8BIT #define CONFIG_HARD_I2C #define CONFIG_I2C_MULTI_BUS -#define CONFIG_SYS_MAX_I2C_BUS (2) +#define CONFIG_SYS_MAX_I2C_BUS (5) #define CONFIG_SYS_I2C_MODULE #define CONFIG_SYS_I2C_SPEED (100000) /* 100 kHz */ #define CONFIG_SYS_I2C_SLAVE (0x7F) @@ -167,5 +167,8 @@ #define CONFIG_SH_I2C_CLOCK (104000000) /* 104 MHz */ #define CONFIG_SH_I2C_BASE0 (0xE6820000) #define CONFIG_SH_I2C_BASE1 (0xE6822000) +#define CONFIG_SH_I2C_BASE2 (0xE6824000) +#define CONFIG_SH_I2C_BASE3 (0xE6826000) +#define CONFIG_SH_I2C_BASE4 (0xE6828000)
#endif /* __KZM9G_H */

On Wed, Sep 12, 2012 at 5:21 PM, Tetsuyuki Kobayashi koba@kmckk.co.jp wrote:
sh_i2c.c support I2C0 and I2C1. This patch extends it to I2C4.
Signed-off-by: Tetsuyuki Kobayashi koba@kmckk.co.jp
Changes for v2:
- new
drivers/i2c/sh_i2c.c | 15 +++++++++++++++ include/configs/kzm9g.h | 5 ++++- 2 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/drivers/i2c/sh_i2c.c b/drivers/i2c/sh_i2c.c index 6c6a141..d524619 100644 --- a/drivers/i2c/sh_i2c.c +++ b/drivers/i2c/sh_i2c.c @@ -200,6 +200,21 @@ int i2c_set_bus_num(unsigned int bus) case 1: base = (void *)CONFIG_SH_I2C_BASE1; break; +#ifdef CONFIG_SH_I2C_BASE2
case 2:
base = (void *)CONFIG_SH_I2C_BASE2;
break;
+#endif +#ifdef CONFIG_SH_I2C_BASE3
case 3:
base = (void *)CONFIG_SH_I2C_BASE3;
break;
+#endif +#ifdef CONFIG_SH_I2C_BASE4
case 4:
base = (void *)CONFIG_SH_I2C_BASE4;
break;
+#endif default: return -1; } diff --git a/include/configs/kzm9g.h b/include/configs/kzm9g.h index abeab69..6a0b6c5 100644 --- a/include/configs/kzm9g.h +++ b/include/configs/kzm9g.h @@ -158,7 +158,7 @@ #define CONFIG_SH_I2C_8BIT #define CONFIG_HARD_I2C #define CONFIG_I2C_MULTI_BUS -#define CONFIG_SYS_MAX_I2C_BUS (2) +#define CONFIG_SYS_MAX_I2C_BUS (5) #define CONFIG_SYS_I2C_MODULE #define CONFIG_SYS_I2C_SPEED (100000) /* 100 kHz */ #define CONFIG_SYS_I2C_SLAVE (0x7F) @@ -167,5 +167,8 @@ #define CONFIG_SH_I2C_CLOCK (104000000) /* 104 MHz */ #define CONFIG_SH_I2C_BASE0 (0xE6820000) #define CONFIG_SH_I2C_BASE1 (0xE6822000) +#define CONFIG_SH_I2C_BASE2 (0xE6824000) +#define CONFIG_SH_I2C_BASE3 (0xE6826000) +#define CONFIG_SH_I2C_BASE4 (0xE6828000)
#endif /* __KZM9G_H */
1.7.9.5
Acked-by: Nobuhiro Iwamatsu nobuhiro.iwamatsu.yj@renesas.com
Best regards, Nobuhiro

Before this patch i2c_probe() always returned 0 and "i2c probe" command did not work properly.
Modify i2c_set_addr() to check TACK when waiting DTE and make i2c_probe() call this function.
Signed-off-by: Tetsuyuki Kobayashi koba@kmckk.co.jp --- Changes for v2: - new
drivers/i2c/sh_i2c.c | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-)
diff --git a/drivers/i2c/sh_i2c.c b/drivers/i2c/sh_i2c.c index d524619..25dbc43 100644 --- a/drivers/i2c/sh_i2c.c +++ b/drivers/i2c/sh_i2c.c @@ -85,6 +85,21 @@ static void irq_dte(struct sh_i2c *base) } }
+static int irq_dte_with_tack(struct sh_i2c *base) +{ + int i; + int ret = 0; + + for (i = 0 ; i < IRQ_WAIT ; i++) { + if (SH_IC_DTE & readb(&base->icsr)) + break; + if (SH_IC_TACK & readb(&base->icsr)) + return -1; + udelay(10); + } + return ret; +} + static void irq_busy(struct sh_i2c *base) { int i; @@ -96,9 +111,9 @@ static void irq_busy(struct sh_i2c *base) } }
-static void i2c_set_addr(struct sh_i2c *base, u8 id, u8 reg, int stop) +static int i2c_set_addr(struct sh_i2c *base, u8 id, u8 reg, int stop) { - u8 icic = 0; + u8 icic = SH_IC_TACK;
writeb(readb(&base->iccr) & ~SH_I2C_ICCR_ICE, &base->iccr); writeb(readb(&base->iccr) | SH_I2C_ICCR_ICE, &base->iccr); @@ -116,14 +131,18 @@ static void i2c_set_addr(struct sh_i2c *base, u8 id, u8 reg, int stop) writeb((SH_I2C_ICCR_ICE|SH_I2C_ICCR_RTS|SH_I2C_ICCR_BUSY), &base->iccr); irq_dte(base);
+ writeb(readb(&base->icsr) & ~SH_IC_TACK, &base->icsr); writeb(id << 1, &base->icdr); - irq_dte(base); + if (irq_dte_with_tack(base) != 0) + return -1;
writeb(reg, &base->icdr); if (stop) writeb((SH_I2C_ICCR_ICE|SH_I2C_ICCR_RTS), &base->iccr);
- irq_dte(base); + if (irq_dte_with_tack(base) != 0) + return -1; + return 0; }
static void i2c_finish(struct sh_i2c *base) @@ -321,5 +340,5 @@ int i2c_write(u8 chip, u32 addr, int alen, u8 *buffer, int len) */ int i2c_probe(u8 chip) { - return 0; + return i2c_set_addr(base, chip, 0, 1); }

Before this patch, i2c_{read,write} always returned 0. Check TACK in i2c_raw_{read,write} so that i2c_{read,write} return non-zero when error.
Signed-off-by: Tetsuyuki Kobayashi koba@kmckk.co.jp --- Changes for v2: - new
drivers/i2c/sh_i2c.c | 44 ++++++++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 16 deletions(-)
diff --git a/drivers/i2c/sh_i2c.c b/drivers/i2c/sh_i2c.c index 25dbc43..e3ee804 100644 --- a/drivers/i2c/sh_i2c.c +++ b/drivers/i2c/sh_i2c.c @@ -151,29 +151,35 @@ static void i2c_finish(struct sh_i2c *base) writeb(readb(&base->iccr) & ~SH_I2C_ICCR_ICE, &base->iccr); }
-static void i2c_raw_write(struct sh_i2c *base, u8 id, u8 reg, u8 val) +static int i2c_raw_write(struct sh_i2c *base, u8 id, u8 reg, u8 val) { - i2c_set_addr(base, id, reg, 0); + if (i2c_set_addr(base, id, reg, 0) != 0) + return -1; udelay(10);
writeb(val, &base->icdr); - irq_dte(base); + if (irq_dte_with_tack(base) != 0) + return -1;
writeb((SH_I2C_ICCR_ICE | SH_I2C_ICCR_RTS), &base->iccr); - irq_dte(base); + if (irq_dte_with_tack(base) != 0) + return -1; irq_busy(base);
i2c_finish(base); + return 0; }
-static u8 i2c_raw_read(struct sh_i2c *base, u8 id, u8 reg) +static int i2c_raw_read(struct sh_i2c *base, u8 id, u8 reg) { - u8 ret; + int ret;
#if defined(CONFIG_SH73A0) - i2c_set_addr(base, id, reg, 0); + if (i2c_set_addr(base, id, reg, 0) != 0) + return -1; #else - i2c_set_addr(base, id, reg, 1); + if (i2c_set_addr(base, id, reg, 1) != 0) + return -1; udelay(100); #endif
@@ -181,12 +187,14 @@ static u8 i2c_raw_read(struct sh_i2c *base, u8 id, u8 reg) irq_dte(base);
writeb(id << 1 | 0x01, &base->icdr); - irq_dte(base); + if (irq_dte_with_tack(base) != 0) + return -1;
writeb((SH_I2C_ICCR_ICE|SH_I2C_ICCR_SCP), &base->iccr); - irq_dte(base); + if (irq_dte_with_tack(base) != 0) + return -1;
- ret = readb(&base->icdr); + ret = readb(&base->icdr) & 0xff;
writeb((SH_I2C_ICCR_ICE|SH_I2C_ICCR_RACK), &base->iccr); readb(&base->icdr); /* Dummy read */ @@ -303,10 +311,14 @@ void i2c_init(int speed, int slaveaddr) */ int i2c_read(u8 chip, u32 addr, int alen, u8 *buffer, int len) { + int ret; int i = 0; - for (i = 0 ; i < len ; i++) - buffer[i] = i2c_raw_read(base, chip, addr + i); - + for (i = 0 ; i < len ; i++) { + ret = i2c_raw_read(base, chip, addr + i); + if (ret < 0) + return -1; + buffer[i] = ret & 0xff; + } return 0; }
@@ -327,8 +339,8 @@ int i2c_write(u8 chip, u32 addr, int alen, u8 *buffer, int len) { int i = 0; for (i = 0; i < len ; i++) - i2c_raw_write(base, chip, addr + i, buffer[i]); - + if (i2c_raw_write(base, chip, addr + i, buffer[i]) != 0) + return -1; return 0; }

On Wed, Sep 12, 2012 at 5:21 PM, Tetsuyuki Kobayashi koba@kmckk.co.jp wrote:
Before this patch, i2c_{read,write} always returned 0. Check TACK in i2c_raw_{read,write} so that i2c_{read,write} return non-zero when error.
Signed-off-by: Tetsuyuki Kobayashi koba@kmckk.co.jp
Changes for v2:
- new
drivers/i2c/sh_i2c.c | 44 ++++++++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 16 deletions(-)
diff --git a/drivers/i2c/sh_i2c.c b/drivers/i2c/sh_i2c.c index 25dbc43..e3ee804 100644 --- a/drivers/i2c/sh_i2c.c +++ b/drivers/i2c/sh_i2c.c @@ -151,29 +151,35 @@ static void i2c_finish(struct sh_i2c *base) writeb(readb(&base->iccr) & ~SH_I2C_ICCR_ICE, &base->iccr); }
-static void i2c_raw_write(struct sh_i2c *base, u8 id, u8 reg, u8 val) +static int i2c_raw_write(struct sh_i2c *base, u8 id, u8 reg, u8 val) {
i2c_set_addr(base, id, reg, 0);
if (i2c_set_addr(base, id, reg, 0) != 0)
return -1; udelay(10); writeb(val, &base->icdr);
irq_dte(base);
if (irq_dte_with_tack(base) != 0)
return -1; writeb((SH_I2C_ICCR_ICE | SH_I2C_ICCR_RTS), &base->iccr);
irq_dte(base);
if (irq_dte_with_tack(base) != 0)
return -1; irq_busy(base); i2c_finish(base);
return 0;
}
-static u8 i2c_raw_read(struct sh_i2c *base, u8 id, u8 reg) +static int i2c_raw_read(struct sh_i2c *base, u8 id, u8 reg) {
u8 ret;
int ret;
#if defined(CONFIG_SH73A0)
i2c_set_addr(base, id, reg, 0);
if (i2c_set_addr(base, id, reg, 0) != 0)
return -1;
#else
i2c_set_addr(base, id, reg, 1);
if (i2c_set_addr(base, id, reg, 1) != 0)
return -1; udelay(100);
#endif
@@ -181,12 +187,14 @@ static u8 i2c_raw_read(struct sh_i2c *base, u8 id, u8 reg) irq_dte(base);
writeb(id << 1 | 0x01, &base->icdr);
irq_dte(base);
if (irq_dte_with_tack(base) != 0)
return -1; writeb((SH_I2C_ICCR_ICE|SH_I2C_ICCR_SCP), &base->iccr);
irq_dte(base);
if (irq_dte_with_tack(base) != 0)
return -1;
ret = readb(&base->icdr);
ret = readb(&base->icdr) & 0xff; writeb((SH_I2C_ICCR_ICE|SH_I2C_ICCR_RACK), &base->iccr); readb(&base->icdr); /* Dummy read */
@@ -303,10 +311,14 @@ void i2c_init(int speed, int slaveaddr) */ int i2c_read(u8 chip, u32 addr, int alen, u8 *buffer, int len) {
int ret; int i = 0;
for (i = 0 ; i < len ; i++)
buffer[i] = i2c_raw_read(base, chip, addr + i);
for (i = 0 ; i < len ; i++) {
ret = i2c_raw_read(base, chip, addr + i);
if (ret < 0)
return -1;
buffer[i] = ret & 0xff;
} return 0;
}
@@ -327,8 +339,8 @@ int i2c_write(u8 chip, u32 addr, int alen, u8 *buffer, int len) { int i = 0; for (i = 0; i < len ; i++)
i2c_raw_write(base, chip, addr + i, buffer[i]);
if (i2c_raw_write(base, chip, addr + i, buffer[i]) != 0)
return -1; return 0;
}
-- 1.7.9.5
Acked-by: Nobuhiro Iwamatsu nobuhiro.iwamatsu.yj@renesas.com
Best regards, Nobuhiro

irq_wait() was not used. So removed it to elminate compiler warnings.
Signed-off-by: Tetsuyuki Kobayashi koba@kmckk.co.jp --- Changes for v2: - new
drivers/i2c/sh_i2c.c | 16 ---------------- 1 file changed, 16 deletions(-)
diff --git a/drivers/i2c/sh_i2c.c b/drivers/i2c/sh_i2c.c index e3ee804..60bad52 100644 --- a/drivers/i2c/sh_i2c.c +++ b/drivers/i2c/sh_i2c.c @@ -58,22 +58,6 @@ static u16 iccl, icch;
#define IRQ_WAIT 1000
-static void irq_wait(struct sh_i2c *base) -{ - int i; - u8 status; - - for (i = 0 ; i < IRQ_WAIT ; i++) { - status = readb(&base->icsr); - if (SH_IC_WAIT & status) - break; - - udelay(10); - } - - writeb(status & ~SH_IC_WAIT, &base->icsr); -} - static void irq_dte(struct sh_i2c *base) { int i;

Supply clock to I2C1 and release resetting.
Signed-off-by: Tetsuyuki Kobayashi koba@kmckk.co.jp --- Changes for v2: - new
board/kmc/kzm9g/kzm9g.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/board/kmc/kzm9g/kzm9g.c b/board/kmc/kzm9g/kzm9g.c index 0679be6..93ca9d7 100644 --- a/board/kmc/kzm9g/kzm9g.c +++ b/board/kmc/kzm9g/kzm9g.c @@ -43,6 +43,7 @@ DECLARE_GLOBAL_DATA_PTR; #define SMSTPCR1_CMT0 (1 << 24) #define SMSTPCR1_I2C0 (1 << 16) #define SMSTPCR3_USB (1 << 22) +#define SMSTPCR3_I2C1 (1 << 23)
#define PORT32CR (0xE6051020) #define PORT33CR (0xE6051021) @@ -300,8 +301,8 @@ int board_early_init_f(void)
clrbits_le32(&cpg->smstpcr1, (SMSTPCR1_CMT0|SMSTPCR1_I2C0)); clrbits_le32(&cpg_srcr->srcr1, (SMSTPCR1_CMT0|SMSTPCR1_I2C0)); - clrbits_le32(&cpg->smstpcr3, SMSTPCR3_USB); - clrbits_le32(&cpg_srcr->srcr3, SMSTPCR3_USB); + clrbits_le32(&cpg->smstpcr3, (SMSTPCR3_USB|SMSTPCR3_I2C1)); + clrbits_le32(&cpg_srcr->srcr3, (SMSTPCR3_USB|SMSTPCR3_I2C1)); writel(VCLKCR1_D, &cpg->vclkcr1);
/* Setup SCIF4 / workaround */

Set gpio config for I2C2.
Signed-off-by: Tetsuyuki Kobayashi koba@kmckk.co.jp --- Changes for v2: - new
board/kmc/kzm9g/kzm9g.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/board/kmc/kzm9g/kzm9g.c b/board/kmc/kzm9g/kzm9g.c index 93ca9d7..22f581a 100644 --- a/board/kmc/kzm9g/kzm9g.c +++ b/board/kmc/kzm9g/kzm9g.c @@ -370,6 +370,8 @@ int board_init(void) gpio_direction_output(GPIO_PORT15, 1);
/* I2C */ + gpio_request(GPIO_FN_PORT237_I2C_SCL2, NULL); + gpio_request(GPIO_FN_PORT236_I2C_SDA2, NULL); gpio_request(GPIO_FN_PORT27_I2C_SCL3, NULL); gpio_request(GPIO_FN_PORT28_I2C_SDA3, NULL);

Some mails seems to be missing. I am sending again..
Hi, Iwamatsu-san Hello, Heiko
Iwamatu-san, thank you for review. This is v2 patch for sh_i2c. Now "i2c dev" and "i2c probe" also work properly on KZM-A9-GT board. I think this modification is common for R-mobile, but I have SH73A0 document only. Iwamatu-san, please review this.
This patch set is based on arm/rmobile branch of u-boot-sh.git.
Tetsuyuki Kobayashi (9): i2c: sh_i2c.c: support iccl and icch extension i2c: sh_i2c.c: correct BUSY bit define in ICSR i2c: sh_i2c.c: adjust for SH73A0 i2c: sh_i2c.c: support I2C2, I2C3 and I2C4 i2c: sh_i2c: enable i2c_probe i2c: sh_i2c.c: check error in i2c_read and i2c_write i2c: sh_i2c.c: remove unused function arm: rmobile: kzm9g: enable I2C1 arm: rmobile: kzm9g: enable I2C2
board/kmc/kzm9g/kzm9g.c | 7 ++- drivers/i2c/sh_i2c.c | 120 +++++++++++++++++++++++++++++++++-------------- include/configs/kzm9g.h | 8 +++- 3 files changed, 95 insertions(+), 40 deletions(-)

R-mobile SoC (at least SH73A0) has extension bits to store 8th bit of iccl and icch. This patch add support for the extentin bits.
Signed-off-by: Tetsuyuki Kobayashi koba@kmckk.co.jp --- Changes for v2: - define CONFIG_SH_I2C_8BIT at board config file and replace HAS_ICIC67.
drivers/i2c/sh_i2c.c | 30 ++++++++++++++++++++++-------- include/configs/kzm9g.h | 1 + 2 files changed, 23 insertions(+), 8 deletions(-)
diff --git a/drivers/i2c/sh_i2c.c b/drivers/i2c/sh_i2c.c index fd8cb92..b98fce5 100644 --- a/drivers/i2c/sh_i2c.c +++ b/drivers/i2c/sh_i2c.c @@ -48,7 +48,13 @@ static struct sh_i2c *base; #define SH_IC_WAIT (1 << 1) #define SH_IC_DTE (1 << 0)
-static u8 iccl, icch; +#ifdef CONFIG_SH_I2C_8BIT +/* store 8th bit of iccl and icch in ICIC register */ +#define SH_I2C_ICIC_ICCLB8 (1 << 7) +#define SH_I2C_ICIC_ICCHB8 (1 << 6) +#endif + +static u16 iccl, icch;
#define IRQ_WAIT 1000
@@ -92,12 +98,20 @@ static void irq_busy(struct sh_i2c *base)
static void i2c_set_addr(struct sh_i2c *base, u8 id, u8 reg, int stop) { + u8 icic = 0; + writeb(readb(&base->iccr) & ~SH_I2C_ICCR_ICE, &base->iccr); writeb(readb(&base->iccr) | SH_I2C_ICCR_ICE, &base->iccr);
- writeb(iccl, &base->iccl); - writeb(icch, &base->icch); - writeb(0, &base->icic); + writeb(iccl & 0xff, &base->iccl); + writeb(icch & 0xff, &base->icch); +#ifdef CONFIG_SH_I2C_8BIT + if (iccl > 0xff) + icic |= SH_I2C_ICIC_ICCLB8; + if (icch > 0xff) + icic |= SH_I2C_ICIC_ICCHB8; +#endif + writeb(icic, &base->icic);
writeb((SH_I2C_ICCR_ICE|SH_I2C_ICCR_RTS|SH_I2C_ICCR_BUSY), &base->iccr); irq_dte(base); @@ -222,18 +236,18 @@ void i2c_init(int speed, int slaveaddr) denom = speed * (CONFIG_SH_I2C_DATA_HIGH + CONFIG_SH_I2C_DATA_LOW); tmp = num * 10 / denom; if (tmp % 10 >= 5) - iccl = (u8)((num/denom) + 1); + iccl = (u16)((num/denom) + 1); else - iccl = (u8)(num/denom); + iccl = (u16)(num/denom);
/* Calculate the value for icch. From the data sheet: icch = (p clock / transfer rate) * (H / (L + H)) */ num = CONFIG_SH_I2C_CLOCK * CONFIG_SH_I2C_DATA_HIGH; tmp = num * 10 / denom; if (tmp % 10 >= 5) - icch = (u8)((num/denom) + 1); + icch = (u16)((num/denom) + 1); else - icch = (u8)(num/denom); + icch = (u16)(num/denom); }
/* diff --git a/include/configs/kzm9g.h b/include/configs/kzm9g.h index a1ae718..8877516 100644 --- a/include/configs/kzm9g.h +++ b/include/configs/kzm9g.h @@ -155,6 +155,7 @@ /* I2C */ #define CONFIG_CMD_I2C #define CONFIG_SH_I2C 1 +#define CONFIG_SH_I2C_8BIT #define CONFIG_HARD_I2C #define CONFIG_I2C_MULTI_BUS #define CONFIG_SYS_MAX_I2C_BUS (2)

On Wed, Sep 12, 2012 at 5:46 PM, Tetsuyuki Kobayashi koba@kmckk.co.jp wrote:
R-mobile SoC (at least SH73A0) has extension bits to store 8th bit of iccl and icch. This patch add support for the extentin bits.
Signed-off-by: Tetsuyuki Kobayashi koba@kmckk.co.jp
Changes for v2:
- define CONFIG_SH_I2C_8BIT at board config file and replace HAS_ICIC67.
drivers/i2c/sh_i2c.c | 30 ++++++++++++++++++++++-------- include/configs/kzm9g.h | 1 + 2 files changed, 23 insertions(+), 8 deletions(-)
diff --git a/drivers/i2c/sh_i2c.c b/drivers/i2c/sh_i2c.c index fd8cb92..b98fce5 100644 --- a/drivers/i2c/sh_i2c.c +++ b/drivers/i2c/sh_i2c.c @@ -48,7 +48,13 @@ static struct sh_i2c *base; #define SH_IC_WAIT (1 << 1) #define SH_IC_DTE (1 << 0)
-static u8 iccl, icch; +#ifdef CONFIG_SH_I2C_8BIT +/* store 8th bit of iccl and icch in ICIC register */ +#define SH_I2C_ICIC_ICCLB8 (1 << 7) +#define SH_I2C_ICIC_ICCHB8 (1 << 6) +#endif
+static u16 iccl, icch;
#define IRQ_WAIT 1000
@@ -92,12 +98,20 @@ static void irq_busy(struct sh_i2c *base)
static void i2c_set_addr(struct sh_i2c *base, u8 id, u8 reg, int stop) {
u8 icic = 0;
writeb(readb(&base->iccr) & ~SH_I2C_ICCR_ICE, &base->iccr); writeb(readb(&base->iccr) | SH_I2C_ICCR_ICE, &base->iccr);
writeb(iccl, &base->iccl);
writeb(icch, &base->icch);
writeb(0, &base->icic);
writeb(iccl & 0xff, &base->iccl);
writeb(icch & 0xff, &base->icch);
+#ifdef CONFIG_SH_I2C_8BIT
if (iccl > 0xff)
icic |= SH_I2C_ICIC_ICCLB8;
if (icch > 0xff)
icic |= SH_I2C_ICIC_ICCHB8;
+#endif
writeb(icic, &base->icic); writeb((SH_I2C_ICCR_ICE|SH_I2C_ICCR_RTS|SH_I2C_ICCR_BUSY), &base->iccr); irq_dte(base);
@@ -222,18 +236,18 @@ void i2c_init(int speed, int slaveaddr) denom = speed * (CONFIG_SH_I2C_DATA_HIGH + CONFIG_SH_I2C_DATA_LOW); tmp = num * 10 / denom; if (tmp % 10 >= 5)
iccl = (u8)((num/denom) + 1);
iccl = (u16)((num/denom) + 1); else
iccl = (u8)(num/denom);
iccl = (u16)(num/denom); /* Calculate the value for icch. From the data sheet: icch = (p clock / transfer rate) * (H / (L + H)) */ num = CONFIG_SH_I2C_CLOCK * CONFIG_SH_I2C_DATA_HIGH; tmp = num * 10 / denom; if (tmp % 10 >= 5)
icch = (u8)((num/denom) + 1);
icch = (u16)((num/denom) + 1); else
icch = (u8)(num/denom);
icch = (u16)(num/denom);
}
/* diff --git a/include/configs/kzm9g.h b/include/configs/kzm9g.h index a1ae718..8877516 100644 --- a/include/configs/kzm9g.h +++ b/include/configs/kzm9g.h @@ -155,6 +155,7 @@ /* I2C */ #define CONFIG_CMD_I2C #define CONFIG_SH_I2C 1 +#define CONFIG_SH_I2C_8BIT #define CONFIG_HARD_I2C #define CONFIG_I2C_MULTI_BUS
#define CONFIG_SYS_MAX_I2C_BUS (2)
1.7.9.5
Acked-by: Nobuhiro Iwamatsu nobuhiro.iwamatsu.yj@renesas.com
Best regards, Nobuhiro

Correct BUSY bit define in ICSR from (1<<3) to (1<<4).
Acked-by: Nobuhiro Iwamatsu nobuhiro.iwamatsu.yj@renesas.com Signed-off-by: Tetsuyuki Kobayashi koba@kmckk.co.jp --- Changes for v2: - none
drivers/i2c/sh_i2c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/i2c/sh_i2c.c b/drivers/i2c/sh_i2c.c index b98fce5..03dfa7a 100644 --- a/drivers/i2c/sh_i2c.c +++ b/drivers/i2c/sh_i2c.c @@ -43,7 +43,7 @@ static struct sh_i2c *base; #define SH_I2C_ICCR_SCP (1 << 0)
/* ICSR / ICIC */ -#define SH_IC_BUSY (1 << 3) +#define SH_IC_BUSY (1 << 4) #define SH_IC_TACK (1 << 2) #define SH_IC_WAIT (1 << 1) #define SH_IC_DTE (1 << 0)

Adjust i2c_raw_read() in sh_i2c.c to work for SH73A0. After this patch, "i2c md" and "i2c mw" command on U-Boot work properly on KZM-A9-GT board.
Acked-by: Nobuhiro Iwamatsu nobuhiro.iwamatsu.yj@renesas.com Signed-off-by: Tetsuyuki Kobayashi koba@kmckk.co.jp --- Changes for v2: - none
drivers/i2c/sh_i2c.c | 4 ++++ include/configs/kzm9g.h | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/i2c/sh_i2c.c b/drivers/i2c/sh_i2c.c index 03dfa7a..6c6a141 100644 --- a/drivers/i2c/sh_i2c.c +++ b/drivers/i2c/sh_i2c.c @@ -151,8 +151,12 @@ static u8 i2c_raw_read(struct sh_i2c *base, u8 id, u8 reg) { u8 ret;
+#if defined(CONFIG_SH73A0) + i2c_set_addr(base, id, reg, 0); +#else i2c_set_addr(base, id, reg, 1); udelay(100); +#endif
writeb((SH_I2C_ICCR_ICE|SH_I2C_ICCR_RTS|SH_I2C_ICCR_BUSY), &base->iccr); irq_dte(base); diff --git a/include/configs/kzm9g.h b/include/configs/kzm9g.h index 8877516..abeab69 100644 --- a/include/configs/kzm9g.h +++ b/include/configs/kzm9g.h @@ -164,7 +164,7 @@ #define CONFIG_SYS_I2C_SLAVE (0x7F) #define CONFIG_SH_I2C_DATA_HIGH (4) #define CONFIG_SH_I2C_DATA_LOW (5) -#define CONFIG_SH_I2C_CLOCK (41666666) +#define CONFIG_SH_I2C_CLOCK (104000000) /* 104 MHz */ #define CONFIG_SH_I2C_BASE0 (0xE6820000) #define CONFIG_SH_I2C_BASE1 (0xE6822000)

sh_i2c.c support I2C0 and I2C1. This patch extends it to I2C4.
Signed-off-by: Tetsuyuki Kobayashi koba@kmckk.co.jp --- Changes for v2: - new
drivers/i2c/sh_i2c.c | 15 +++++++++++++++ include/configs/kzm9g.h | 5 ++++- 2 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/drivers/i2c/sh_i2c.c b/drivers/i2c/sh_i2c.c index 6c6a141..d524619 100644 --- a/drivers/i2c/sh_i2c.c +++ b/drivers/i2c/sh_i2c.c @@ -200,6 +200,21 @@ int i2c_set_bus_num(unsigned int bus) case 1: base = (void *)CONFIG_SH_I2C_BASE1; break; +#ifdef CONFIG_SH_I2C_BASE2 + case 2: + base = (void *)CONFIG_SH_I2C_BASE2; + break; +#endif +#ifdef CONFIG_SH_I2C_BASE3 + case 3: + base = (void *)CONFIG_SH_I2C_BASE3; + break; +#endif +#ifdef CONFIG_SH_I2C_BASE4 + case 4: + base = (void *)CONFIG_SH_I2C_BASE4; + break; +#endif default: return -1; } diff --git a/include/configs/kzm9g.h b/include/configs/kzm9g.h index abeab69..6a0b6c5 100644 --- a/include/configs/kzm9g.h +++ b/include/configs/kzm9g.h @@ -158,7 +158,7 @@ #define CONFIG_SH_I2C_8BIT #define CONFIG_HARD_I2C #define CONFIG_I2C_MULTI_BUS -#define CONFIG_SYS_MAX_I2C_BUS (2) +#define CONFIG_SYS_MAX_I2C_BUS (5) #define CONFIG_SYS_I2C_MODULE #define CONFIG_SYS_I2C_SPEED (100000) /* 100 kHz */ #define CONFIG_SYS_I2C_SLAVE (0x7F) @@ -167,5 +167,8 @@ #define CONFIG_SH_I2C_CLOCK (104000000) /* 104 MHz */ #define CONFIG_SH_I2C_BASE0 (0xE6820000) #define CONFIG_SH_I2C_BASE1 (0xE6822000) +#define CONFIG_SH_I2C_BASE2 (0xE6824000) +#define CONFIG_SH_I2C_BASE3 (0xE6826000) +#define CONFIG_SH_I2C_BASE4 (0xE6828000)
#endif /* __KZM9G_H */

Before this patch i2c_probe() always returned 0 and "i2c probe" command did not work properly.
Modify i2c_set_addr() to check TACK when waiting DTE and make i2c_probe() call this function.
Signed-off-by: Tetsuyuki Kobayashi koba@kmckk.co.jp --- Changes for v2: - new
drivers/i2c/sh_i2c.c | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-)
diff --git a/drivers/i2c/sh_i2c.c b/drivers/i2c/sh_i2c.c index d524619..25dbc43 100644 --- a/drivers/i2c/sh_i2c.c +++ b/drivers/i2c/sh_i2c.c @@ -85,6 +85,21 @@ static void irq_dte(struct sh_i2c *base) } }
+static int irq_dte_with_tack(struct sh_i2c *base) +{ + int i; + int ret = 0; + + for (i = 0 ; i < IRQ_WAIT ; i++) { + if (SH_IC_DTE & readb(&base->icsr)) + break; + if (SH_IC_TACK & readb(&base->icsr)) + return -1; + udelay(10); + } + return ret; +} + static void irq_busy(struct sh_i2c *base) { int i; @@ -96,9 +111,9 @@ static void irq_busy(struct sh_i2c *base) } }
-static void i2c_set_addr(struct sh_i2c *base, u8 id, u8 reg, int stop) +static int i2c_set_addr(struct sh_i2c *base, u8 id, u8 reg, int stop) { - u8 icic = 0; + u8 icic = SH_IC_TACK;
writeb(readb(&base->iccr) & ~SH_I2C_ICCR_ICE, &base->iccr); writeb(readb(&base->iccr) | SH_I2C_ICCR_ICE, &base->iccr); @@ -116,14 +131,18 @@ static void i2c_set_addr(struct sh_i2c *base, u8 id, u8 reg, int stop) writeb((SH_I2C_ICCR_ICE|SH_I2C_ICCR_RTS|SH_I2C_ICCR_BUSY), &base->iccr); irq_dte(base);
+ writeb(readb(&base->icsr) & ~SH_IC_TACK, &base->icsr); writeb(id << 1, &base->icdr); - irq_dte(base); + if (irq_dte_with_tack(base) != 0) + return -1;
writeb(reg, &base->icdr); if (stop) writeb((SH_I2C_ICCR_ICE|SH_I2C_ICCR_RTS), &base->iccr);
- irq_dte(base); + if (irq_dte_with_tack(base) != 0) + return -1; + return 0; }
static void i2c_finish(struct sh_i2c *base) @@ -321,5 +340,5 @@ int i2c_write(u8 chip, u32 addr, int alen, u8 *buffer, int len) */ int i2c_probe(u8 chip) { - return 0; + return i2c_set_addr(base, chip, 0, 1); }

On Wed, Sep 12, 2012 at 5:46 PM, Tetsuyuki Kobayashi koba@kmckk.co.jp wrote:
Before this patch i2c_probe() always returned 0 and "i2c probe" command did not work properly.
Modify i2c_set_addr() to check TACK when waiting DTE and make i2c_probe() call this function.
Signed-off-by: Tetsuyuki Kobayashi koba@kmckk.co.jp
Changes for v2:
- new
drivers/i2c/sh_i2c.c | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-)
diff --git a/drivers/i2c/sh_i2c.c b/drivers/i2c/sh_i2c.c index d524619..25dbc43 100644 --- a/drivers/i2c/sh_i2c.c +++ b/drivers/i2c/sh_i2c.c @@ -85,6 +85,21 @@ static void irq_dte(struct sh_i2c *base) } }
+static int irq_dte_with_tack(struct sh_i2c *base) +{
int i;
int ret = 0;
for (i = 0 ; i < IRQ_WAIT ; i++) {
if (SH_IC_DTE & readb(&base->icsr))
break;
if (SH_IC_TACK & readb(&base->icsr))
return -1;
udelay(10);
}
return ret;
+}
static void irq_busy(struct sh_i2c *base) { int i; @@ -96,9 +111,9 @@ static void irq_busy(struct sh_i2c *base) } }
-static void i2c_set_addr(struct sh_i2c *base, u8 id, u8 reg, int stop) +static int i2c_set_addr(struct sh_i2c *base, u8 id, u8 reg, int stop) {
u8 icic = 0;
u8 icic = SH_IC_TACK; writeb(readb(&base->iccr) & ~SH_I2C_ICCR_ICE, &base->iccr); writeb(readb(&base->iccr) | SH_I2C_ICCR_ICE, &base->iccr);
@@ -116,14 +131,18 @@ static void i2c_set_addr(struct sh_i2c *base, u8 id, u8 reg, int stop) writeb((SH_I2C_ICCR_ICE|SH_I2C_ICCR_RTS|SH_I2C_ICCR_BUSY), &base->iccr); irq_dte(base);
writeb(readb(&base->icsr) & ~SH_IC_TACK, &base->icsr); writeb(id << 1, &base->icdr);
irq_dte(base);
if (irq_dte_with_tack(base) != 0)
return -1; writeb(reg, &base->icdr); if (stop) writeb((SH_I2C_ICCR_ICE|SH_I2C_ICCR_RTS), &base->iccr);
irq_dte(base);
if (irq_dte_with_tack(base) != 0)
return -1;
return 0;
}
static void i2c_finish(struct sh_i2c *base) @@ -321,5 +340,5 @@ int i2c_write(u8 chip, u32 addr, int alen, u8 *buffer, int len) */ int i2c_probe(u8 chip) {
return 0;
return i2c_set_addr(base, chip, 0, 1);
}
1.7.9.5
Acked-by: Nobuhiro Iwamatsu nobuhiro.iwamatsu.yj@renesas.com
Best regards, Nobuhiro

Before this patch, i2c_{read,write} always returned 0. Check TACK in i2c_raw_{read,write} so that i2c_{read,write} return non-zero when error.
Signed-off-by: Tetsuyuki Kobayashi koba@kmckk.co.jp --- Changes for v2: - new
drivers/i2c/sh_i2c.c | 44 ++++++++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 16 deletions(-)
diff --git a/drivers/i2c/sh_i2c.c b/drivers/i2c/sh_i2c.c index 25dbc43..e3ee804 100644 --- a/drivers/i2c/sh_i2c.c +++ b/drivers/i2c/sh_i2c.c @@ -151,29 +151,35 @@ static void i2c_finish(struct sh_i2c *base) writeb(readb(&base->iccr) & ~SH_I2C_ICCR_ICE, &base->iccr); }
-static void i2c_raw_write(struct sh_i2c *base, u8 id, u8 reg, u8 val) +static int i2c_raw_write(struct sh_i2c *base, u8 id, u8 reg, u8 val) { - i2c_set_addr(base, id, reg, 0); + if (i2c_set_addr(base, id, reg, 0) != 0) + return -1; udelay(10);
writeb(val, &base->icdr); - irq_dte(base); + if (irq_dte_with_tack(base) != 0) + return -1;
writeb((SH_I2C_ICCR_ICE | SH_I2C_ICCR_RTS), &base->iccr); - irq_dte(base); + if (irq_dte_with_tack(base) != 0) + return -1; irq_busy(base);
i2c_finish(base); + return 0; }
-static u8 i2c_raw_read(struct sh_i2c *base, u8 id, u8 reg) +static int i2c_raw_read(struct sh_i2c *base, u8 id, u8 reg) { - u8 ret; + int ret;
#if defined(CONFIG_SH73A0) - i2c_set_addr(base, id, reg, 0); + if (i2c_set_addr(base, id, reg, 0) != 0) + return -1; #else - i2c_set_addr(base, id, reg, 1); + if (i2c_set_addr(base, id, reg, 1) != 0) + return -1; udelay(100); #endif
@@ -181,12 +187,14 @@ static u8 i2c_raw_read(struct sh_i2c *base, u8 id, u8 reg) irq_dte(base);
writeb(id << 1 | 0x01, &base->icdr); - irq_dte(base); + if (irq_dte_with_tack(base) != 0) + return -1;
writeb((SH_I2C_ICCR_ICE|SH_I2C_ICCR_SCP), &base->iccr); - irq_dte(base); + if (irq_dte_with_tack(base) != 0) + return -1;
- ret = readb(&base->icdr); + ret = readb(&base->icdr) & 0xff;
writeb((SH_I2C_ICCR_ICE|SH_I2C_ICCR_RACK), &base->iccr); readb(&base->icdr); /* Dummy read */ @@ -303,10 +311,14 @@ void i2c_init(int speed, int slaveaddr) */ int i2c_read(u8 chip, u32 addr, int alen, u8 *buffer, int len) { + int ret; int i = 0; - for (i = 0 ; i < len ; i++) - buffer[i] = i2c_raw_read(base, chip, addr + i); - + for (i = 0 ; i < len ; i++) { + ret = i2c_raw_read(base, chip, addr + i); + if (ret < 0) + return -1; + buffer[i] = ret & 0xff; + } return 0; }
@@ -327,8 +339,8 @@ int i2c_write(u8 chip, u32 addr, int alen, u8 *buffer, int len) { int i = 0; for (i = 0; i < len ; i++) - i2c_raw_write(base, chip, addr + i, buffer[i]); - + if (i2c_raw_write(base, chip, addr + i, buffer[i]) != 0) + return -1; return 0; }

irq_wait() was not used. So removed it to elminate compiler warnings.
Signed-off-by: Tetsuyuki Kobayashi koba@kmckk.co.jp --- Changes for v2: - new
drivers/i2c/sh_i2c.c | 16 ---------------- 1 file changed, 16 deletions(-)
diff --git a/drivers/i2c/sh_i2c.c b/drivers/i2c/sh_i2c.c index e3ee804..60bad52 100644 --- a/drivers/i2c/sh_i2c.c +++ b/drivers/i2c/sh_i2c.c @@ -58,22 +58,6 @@ static u16 iccl, icch;
#define IRQ_WAIT 1000
-static void irq_wait(struct sh_i2c *base) -{ - int i; - u8 status; - - for (i = 0 ; i < IRQ_WAIT ; i++) { - status = readb(&base->icsr); - if (SH_IC_WAIT & status) - break; - - udelay(10); - } - - writeb(status & ~SH_IC_WAIT, &base->icsr); -} - static void irq_dte(struct sh_i2c *base) { int i;

On Wed, Sep 12, 2012 at 5:46 PM, Tetsuyuki Kobayashi koba@kmckk.co.jp wrote:
irq_wait() was not used. So removed it to elminate compiler warnings.
Signed-off-by: Tetsuyuki Kobayashi koba@kmckk.co.jp
Changes for v2:
- new
drivers/i2c/sh_i2c.c | 16 ---------------- 1 file changed, 16 deletions(-)
diff --git a/drivers/i2c/sh_i2c.c b/drivers/i2c/sh_i2c.c index e3ee804..60bad52 100644 --- a/drivers/i2c/sh_i2c.c +++ b/drivers/i2c/sh_i2c.c @@ -58,22 +58,6 @@ static u16 iccl, icch;
#define IRQ_WAIT 1000
-static void irq_wait(struct sh_i2c *base) -{
int i;
u8 status;
for (i = 0 ; i < IRQ_WAIT ; i++) {
status = readb(&base->icsr);
if (SH_IC_WAIT & status)
break;
udelay(10);
}
writeb(status & ~SH_IC_WAIT, &base->icsr);
-}
static void irq_dte(struct sh_i2c *base) { int i; -- 1.7.9.5
Acked-by: Nobuhiro Iwamatsu nobuhiro.iwamatsu.yj@renesas.com
Best regards, Nobuhiro

Supply clock to I2C1 and release resetting.
Signed-off-by: Tetsuyuki Kobayashi koba@kmckk.co.jp --- Changes for v2: - new
board/kmc/kzm9g/kzm9g.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/board/kmc/kzm9g/kzm9g.c b/board/kmc/kzm9g/kzm9g.c index 0679be6..93ca9d7 100644 --- a/board/kmc/kzm9g/kzm9g.c +++ b/board/kmc/kzm9g/kzm9g.c @@ -43,6 +43,7 @@ DECLARE_GLOBAL_DATA_PTR; #define SMSTPCR1_CMT0 (1 << 24) #define SMSTPCR1_I2C0 (1 << 16) #define SMSTPCR3_USB (1 << 22) +#define SMSTPCR3_I2C1 (1 << 23)
#define PORT32CR (0xE6051020) #define PORT33CR (0xE6051021) @@ -300,8 +301,8 @@ int board_early_init_f(void)
clrbits_le32(&cpg->smstpcr1, (SMSTPCR1_CMT0|SMSTPCR1_I2C0)); clrbits_le32(&cpg_srcr->srcr1, (SMSTPCR1_CMT0|SMSTPCR1_I2C0)); - clrbits_le32(&cpg->smstpcr3, SMSTPCR3_USB); - clrbits_le32(&cpg_srcr->srcr3, SMSTPCR3_USB); + clrbits_le32(&cpg->smstpcr3, (SMSTPCR3_USB|SMSTPCR3_I2C1)); + clrbits_le32(&cpg_srcr->srcr3, (SMSTPCR3_USB|SMSTPCR3_I2C1)); writel(VCLKCR1_D, &cpg->vclkcr1);
/* Setup SCIF4 / workaround */

On Wed, Sep 12, 2012 at 5:46 PM, Tetsuyuki Kobayashi koba@kmckk.co.jp wrote:
Supply clock to I2C1 and release resetting.
Signed-off-by: Tetsuyuki Kobayashi koba@kmckk.co.jp
Changes for v2:
- new
board/kmc/kzm9g/kzm9g.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/board/kmc/kzm9g/kzm9g.c b/board/kmc/kzm9g/kzm9g.c index 0679be6..93ca9d7 100644 --- a/board/kmc/kzm9g/kzm9g.c +++ b/board/kmc/kzm9g/kzm9g.c @@ -43,6 +43,7 @@ DECLARE_GLOBAL_DATA_PTR; #define SMSTPCR1_CMT0 (1 << 24) #define SMSTPCR1_I2C0 (1 << 16) #define SMSTPCR3_USB (1 << 22) +#define SMSTPCR3_I2C1 (1 << 23)
#define PORT32CR (0xE6051020) #define PORT33CR (0xE6051021) @@ -300,8 +301,8 @@ int board_early_init_f(void)
clrbits_le32(&cpg->smstpcr1, (SMSTPCR1_CMT0|SMSTPCR1_I2C0)); clrbits_le32(&cpg_srcr->srcr1, (SMSTPCR1_CMT0|SMSTPCR1_I2C0));
clrbits_le32(&cpg->smstpcr3, SMSTPCR3_USB);
clrbits_le32(&cpg_srcr->srcr3, SMSTPCR3_USB);
clrbits_le32(&cpg->smstpcr3, (SMSTPCR3_USB|SMSTPCR3_I2C1));
clrbits_le32(&cpg_srcr->srcr3, (SMSTPCR3_USB|SMSTPCR3_I2C1)); writel(VCLKCR1_D, &cpg->vclkcr1); /* Setup SCIF4 / workaround */
-- 1.7.9.5
Acked-by: Nobuhiro Iwamatsu nobuhiro.iwamatsu.yj@renesas.com
Best regards, Nobuhiro

Set gpio config for I2C2.
Signed-off-by: Tetsuyuki Kobayashi koba@kmckk.co.jp --- Changes for v2: - new
board/kmc/kzm9g/kzm9g.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/board/kmc/kzm9g/kzm9g.c b/board/kmc/kzm9g/kzm9g.c index 93ca9d7..22f581a 100644 --- a/board/kmc/kzm9g/kzm9g.c +++ b/board/kmc/kzm9g/kzm9g.c @@ -370,6 +370,8 @@ int board_init(void) gpio_direction_output(GPIO_PORT15, 1);
/* I2C */ + gpio_request(GPIO_FN_PORT237_I2C_SCL2, NULL); + gpio_request(GPIO_FN_PORT236_I2C_SDA2, NULL); gpio_request(GPIO_FN_PORT27_I2C_SCL3, NULL); gpio_request(GPIO_FN_PORT28_I2C_SDA3, NULL);

On Wed, Sep 12, 2012 at 5:46 PM, Tetsuyuki Kobayashi koba@kmckk.co.jp wrote:
Set gpio config for I2C2.
Signed-off-by: Tetsuyuki Kobayashi koba@kmckk.co.jp
Changes for v2:
- new
board/kmc/kzm9g/kzm9g.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/board/kmc/kzm9g/kzm9g.c b/board/kmc/kzm9g/kzm9g.c index 93ca9d7..22f581a 100644 --- a/board/kmc/kzm9g/kzm9g.c +++ b/board/kmc/kzm9g/kzm9g.c @@ -370,6 +370,8 @@ int board_init(void) gpio_direction_output(GPIO_PORT15, 1);
/* I2C */
gpio_request(GPIO_FN_PORT237_I2C_SCL2, NULL);
gpio_request(GPIO_FN_PORT236_I2C_SDA2, NULL); gpio_request(GPIO_FN_PORT27_I2C_SCL3, NULL); gpio_request(GPIO_FN_PORT28_I2C_SDA3, NULL);
-- 1.7.9.5
Acked-by: Nobuhiro Iwamatsu nobuhiro.iwamatsu.yj@renesas.com
Best regards, Nobuhiro

Hi,
Thank you for this work. If you have a time, could you update sh_i2c using set/clrbits functions? these functions is included in asm/io.h.
For example, you can change from writeb(readb(&base->iccr) & ~SH_I2C_ICCR_ICE, &base->iccr); to clrbits_8(&base->iccr, SH_I2C_ICCR_ICE); .
Best regards, Nobuhiro
On Wed, Sep 12, 2012 at 5:46 PM, Tetsuyuki Kobayashi koba@kmckk.co.jp wrote:
Some mails seems to be missing. I am sending again..
Hi, Iwamatsu-san Hello, Heiko
Iwamatu-san, thank you for review. This is v2 patch for sh_i2c. Now "i2c dev" and "i2c probe" also work properly on KZM-A9-GT board. I think this modification is common for R-mobile, but I have SH73A0 document only. Iwamatu-san, please review this.
This patch set is based on arm/rmobile branch of u-boot-sh.git.
Tetsuyuki Kobayashi (9): i2c: sh_i2c.c: support iccl and icch extension i2c: sh_i2c.c: correct BUSY bit define in ICSR i2c: sh_i2c.c: adjust for SH73A0 i2c: sh_i2c.c: support I2C2, I2C3 and I2C4 i2c: sh_i2c: enable i2c_probe i2c: sh_i2c.c: check error in i2c_read and i2c_write i2c: sh_i2c.c: remove unused function arm: rmobile: kzm9g: enable I2C1 arm: rmobile: kzm9g: enable I2C2
board/kmc/kzm9g/kzm9g.c | 7 ++- drivers/i2c/sh_i2c.c | 120 +++++++++++++++++++++++++++++++++-------------- include/configs/kzm9g.h | 8 +++- 3 files changed, 95 insertions(+), 40 deletions(-)
-- 1.7.9.5
U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot

Iwamatu-san, Thank you for review.
(2012/09/13 14:26), Nobuhiro Iwamatsu wrote:
Hi,
Thank you for this work. If you have a time, could you update sh_i2c using set/clrbits functions? these functions is included in asm/io.h.
For example, you can change from writeb(readb(&base->iccr) & ~SH_I2C_ICCR_ICE, &base->iccr); to clrbits_8(&base->iccr, SH_I2C_ICCR_ICE);
OK. I will try it.

Hi, Iwamatsu-san Hello, Heiko
Iwamatu-san, thank you for review. This is v3 patch for sh_i2c. Changes for v3: - call i2c_finish before returning i2c_probe, i2c_read, i2c_write even if error occured. Without this, it fails to boot Linux kernel after using "i2c probe" command. - use setbits/clrbits macro as Iwamatsu-san pointed.
Please check patch 5,6 and 10. The rest is not changed.
This patch set is based on arm/rmobile branch of u-boot-sh.git.
Tetsuyuki Kobayashi (10): i2c: sh_i2c.c: support iccl and icch extension i2c: sh_i2c.c: correct BUSY bit define in ICSR i2c: sh_i2c.c: adjust for SH73A0 i2c: sh_i2c.c: support I2C2, I2C3 and I2C4 i2c: sh_i2c: enable i2c_probe i2c: sh_i2c.c: check error in i2c_read and i2c_write i2c: sh_i2c.c: remove unused function arm: rmobile: kzm9g: enable I2C1 arm: rmobile: kzm9g: enable I2C2 i2c: sh_i2c: use setbits/clrbits macro
board/kmc/kzm9g/kzm9g.c | 7 ++- drivers/i2c/sh_i2c.c | 139 ++++++++++++++++++++++++++++++++--------------- include/configs/kzm9g.h | 8 ++- 3 files changed, 107 insertions(+), 47 deletions(-)

R-mobile SoC (at least SH73A0) has extension bits to store 8th bit of iccl and icch. This patch add support for the extentin bits.
Acked-by: Nobuhiro Iwamatsu nobuhiro.iwamatsu.yj@renesas.com Signed-off-by: Tetsuyuki Kobayashi koba@kmckk.co.jp --- Changes for v2: - define CONFIG_SH_I2C_8BIT at board config file and replace HAS_ICIC67. Changes for v3: - none
drivers/i2c/sh_i2c.c | 30 ++++++++++++++++++++++-------- include/configs/kzm9g.h | 1 + 2 files changed, 23 insertions(+), 8 deletions(-)
diff --git a/drivers/i2c/sh_i2c.c b/drivers/i2c/sh_i2c.c index fd8cb92..b98fce5 100644 --- a/drivers/i2c/sh_i2c.c +++ b/drivers/i2c/sh_i2c.c @@ -48,7 +48,13 @@ static struct sh_i2c *base; #define SH_IC_WAIT (1 << 1) #define SH_IC_DTE (1 << 0)
-static u8 iccl, icch; +#ifdef CONFIG_SH_I2C_8BIT +/* store 8th bit of iccl and icch in ICIC register */ +#define SH_I2C_ICIC_ICCLB8 (1 << 7) +#define SH_I2C_ICIC_ICCHB8 (1 << 6) +#endif + +static u16 iccl, icch;
#define IRQ_WAIT 1000
@@ -92,12 +98,20 @@ static void irq_busy(struct sh_i2c *base)
static void i2c_set_addr(struct sh_i2c *base, u8 id, u8 reg, int stop) { + u8 icic = 0; + writeb(readb(&base->iccr) & ~SH_I2C_ICCR_ICE, &base->iccr); writeb(readb(&base->iccr) | SH_I2C_ICCR_ICE, &base->iccr);
- writeb(iccl, &base->iccl); - writeb(icch, &base->icch); - writeb(0, &base->icic); + writeb(iccl & 0xff, &base->iccl); + writeb(icch & 0xff, &base->icch); +#ifdef CONFIG_SH_I2C_8BIT + if (iccl > 0xff) + icic |= SH_I2C_ICIC_ICCLB8; + if (icch > 0xff) + icic |= SH_I2C_ICIC_ICCHB8; +#endif + writeb(icic, &base->icic);
writeb((SH_I2C_ICCR_ICE|SH_I2C_ICCR_RTS|SH_I2C_ICCR_BUSY), &base->iccr); irq_dte(base); @@ -222,18 +236,18 @@ void i2c_init(int speed, int slaveaddr) denom = speed * (CONFIG_SH_I2C_DATA_HIGH + CONFIG_SH_I2C_DATA_LOW); tmp = num * 10 / denom; if (tmp % 10 >= 5) - iccl = (u8)((num/denom) + 1); + iccl = (u16)((num/denom) + 1); else - iccl = (u8)(num/denom); + iccl = (u16)(num/denom);
/* Calculate the value for icch. From the data sheet: icch = (p clock / transfer rate) * (H / (L + H)) */ num = CONFIG_SH_I2C_CLOCK * CONFIG_SH_I2C_DATA_HIGH; tmp = num * 10 / denom; if (tmp % 10 >= 5) - icch = (u8)((num/denom) + 1); + icch = (u16)((num/denom) + 1); else - icch = (u8)(num/denom); + icch = (u16)(num/denom); }
/* diff --git a/include/configs/kzm9g.h b/include/configs/kzm9g.h index a1ae718..8877516 100644 --- a/include/configs/kzm9g.h +++ b/include/configs/kzm9g.h @@ -155,6 +155,7 @@ /* I2C */ #define CONFIG_CMD_I2C #define CONFIG_SH_I2C 1 +#define CONFIG_SH_I2C_8BIT #define CONFIG_HARD_I2C #define CONFIG_I2C_MULTI_BUS #define CONFIG_SYS_MAX_I2C_BUS (2)

Correct BUSY bit define in ICSR from (1<<3) to (1<<4).
Acked-by: Nobuhiro Iwamatsu nobuhiro.iwamatsu.yj@renesas.com Signed-off-by: Tetsuyuki Kobayashi koba@kmckk.co.jp --- Changes for v2: - none Changes for v3: - none
drivers/i2c/sh_i2c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/i2c/sh_i2c.c b/drivers/i2c/sh_i2c.c index b98fce5..03dfa7a 100644 --- a/drivers/i2c/sh_i2c.c +++ b/drivers/i2c/sh_i2c.c @@ -43,7 +43,7 @@ static struct sh_i2c *base; #define SH_I2C_ICCR_SCP (1 << 0)
/* ICSR / ICIC */ -#define SH_IC_BUSY (1 << 3) +#define SH_IC_BUSY (1 << 4) #define SH_IC_TACK (1 << 2) #define SH_IC_WAIT (1 << 1) #define SH_IC_DTE (1 << 0)

Adjust i2c_raw_read() in sh_i2c.c to work for SH73A0. After this patch, "i2c md" and "i2c mw" command on U-Boot work properly on KZM-A9-GT board.
Acked-by: Nobuhiro Iwamatsu nobuhiro.iwamatsu.yj@renesas.com Signed-off-by: Tetsuyuki Kobayashi koba@kmckk.co.jp --- Changes for v2: - none Changes for v3: - none
drivers/i2c/sh_i2c.c | 4 ++++ include/configs/kzm9g.h | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/i2c/sh_i2c.c b/drivers/i2c/sh_i2c.c index 03dfa7a..6c6a141 100644 --- a/drivers/i2c/sh_i2c.c +++ b/drivers/i2c/sh_i2c.c @@ -151,8 +151,12 @@ static u8 i2c_raw_read(struct sh_i2c *base, u8 id, u8 reg) { u8 ret;
+#if defined(CONFIG_SH73A0) + i2c_set_addr(base, id, reg, 0); +#else i2c_set_addr(base, id, reg, 1); udelay(100); +#endif
writeb((SH_I2C_ICCR_ICE|SH_I2C_ICCR_RTS|SH_I2C_ICCR_BUSY), &base->iccr); irq_dte(base); diff --git a/include/configs/kzm9g.h b/include/configs/kzm9g.h index 8877516..abeab69 100644 --- a/include/configs/kzm9g.h +++ b/include/configs/kzm9g.h @@ -164,7 +164,7 @@ #define CONFIG_SYS_I2C_SLAVE (0x7F) #define CONFIG_SH_I2C_DATA_HIGH (4) #define CONFIG_SH_I2C_DATA_LOW (5) -#define CONFIG_SH_I2C_CLOCK (41666666) +#define CONFIG_SH_I2C_CLOCK (104000000) /* 104 MHz */ #define CONFIG_SH_I2C_BASE0 (0xE6820000) #define CONFIG_SH_I2C_BASE1 (0xE6822000)

sh_i2c.c support I2C0 and I2C1. This patch extends it to I2C4.
Acked-by: Nobuhiro Iwamatsu nobuhiro.iwamatsu.yj@renesas.com Signed-off-by: Tetsuyuki Kobayashi koba@kmckk.co.jp --- Changes for v2: - new Changes for v3: - none
drivers/i2c/sh_i2c.c | 15 +++++++++++++++ include/configs/kzm9g.h | 5 ++++- 2 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/drivers/i2c/sh_i2c.c b/drivers/i2c/sh_i2c.c index 6c6a141..d524619 100644 --- a/drivers/i2c/sh_i2c.c +++ b/drivers/i2c/sh_i2c.c @@ -200,6 +200,21 @@ int i2c_set_bus_num(unsigned int bus) case 1: base = (void *)CONFIG_SH_I2C_BASE1; break; +#ifdef CONFIG_SH_I2C_BASE2 + case 2: + base = (void *)CONFIG_SH_I2C_BASE2; + break; +#endif +#ifdef CONFIG_SH_I2C_BASE3 + case 3: + base = (void *)CONFIG_SH_I2C_BASE3; + break; +#endif +#ifdef CONFIG_SH_I2C_BASE4 + case 4: + base = (void *)CONFIG_SH_I2C_BASE4; + break; +#endif default: return -1; } diff --git a/include/configs/kzm9g.h b/include/configs/kzm9g.h index abeab69..6a0b6c5 100644 --- a/include/configs/kzm9g.h +++ b/include/configs/kzm9g.h @@ -158,7 +158,7 @@ #define CONFIG_SH_I2C_8BIT #define CONFIG_HARD_I2C #define CONFIG_I2C_MULTI_BUS -#define CONFIG_SYS_MAX_I2C_BUS (2) +#define CONFIG_SYS_MAX_I2C_BUS (5) #define CONFIG_SYS_I2C_MODULE #define CONFIG_SYS_I2C_SPEED (100000) /* 100 kHz */ #define CONFIG_SYS_I2C_SLAVE (0x7F) @@ -167,5 +167,8 @@ #define CONFIG_SH_I2C_CLOCK (104000000) /* 104 MHz */ #define CONFIG_SH_I2C_BASE0 (0xE6820000) #define CONFIG_SH_I2C_BASE1 (0xE6822000) +#define CONFIG_SH_I2C_BASE2 (0xE6824000) +#define CONFIG_SH_I2C_BASE3 (0xE6826000) +#define CONFIG_SH_I2C_BASE4 (0xE6828000)
#endif /* __KZM9G_H */

Before this patch i2c_probe() always returned 0 and "i2c probe" command did not work properly.
Modify i2c_set_addr() to check TACK when waiting DTE and make i2c_probe() call this function.
Acked-by: Nobuhiro Iwamatsu nobuhiro.iwamatsu.yj@renesas.com Signed-off-by: Tetsuyuki Kobayashi koba@kmckk.co.jp --- Changes for v2: - new Changes for v3: - call i2c_finish before returning i2c_probe.
drivers/i2c/sh_i2c.c | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-)
diff --git a/drivers/i2c/sh_i2c.c b/drivers/i2c/sh_i2c.c index d524619..1f5104c 100644 --- a/drivers/i2c/sh_i2c.c +++ b/drivers/i2c/sh_i2c.c @@ -85,6 +85,20 @@ static void irq_dte(struct sh_i2c *base) } }
+static int irq_dte_with_tack(struct sh_i2c *base) +{ + int i; + + for (i = 0 ; i < IRQ_WAIT ; i++) { + if (SH_IC_DTE & readb(&base->icsr)) + break; + if (SH_IC_TACK & readb(&base->icsr)) + return -1; + udelay(10); + } + return 0; +} + static void irq_busy(struct sh_i2c *base) { int i; @@ -96,9 +110,9 @@ static void irq_busy(struct sh_i2c *base) } }
-static void i2c_set_addr(struct sh_i2c *base, u8 id, u8 reg, int stop) +static int i2c_set_addr(struct sh_i2c *base, u8 id, u8 reg, int stop) { - u8 icic = 0; + u8 icic = SH_IC_TACK;
writeb(readb(&base->iccr) & ~SH_I2C_ICCR_ICE, &base->iccr); writeb(readb(&base->iccr) | SH_I2C_ICCR_ICE, &base->iccr); @@ -116,14 +130,18 @@ static void i2c_set_addr(struct sh_i2c *base, u8 id, u8 reg, int stop) writeb((SH_I2C_ICCR_ICE|SH_I2C_ICCR_RTS|SH_I2C_ICCR_BUSY), &base->iccr); irq_dte(base);
+ writeb(readb(&base->icsr) & ~SH_IC_TACK, &base->icsr); writeb(id << 1, &base->icdr); - irq_dte(base); + if (irq_dte_with_tack(base) != 0) + return -1;
writeb(reg, &base->icdr); if (stop) writeb((SH_I2C_ICCR_ICE|SH_I2C_ICCR_RTS), &base->iccr);
- irq_dte(base); + if (irq_dte_with_tack(base) != 0) + return -1; + return 0; }
static void i2c_finish(struct sh_i2c *base) @@ -321,5 +339,9 @@ int i2c_write(u8 chip, u32 addr, int alen, u8 *buffer, int len) */ int i2c_probe(u8 chip) { - return 0; + int ret; + + ret = i2c_set_addr(base, chip, 0, 1); + i2c_finish(base); + return ret; }

Before this patch, i2c_{read,write} always returned 0. Check TACK in i2c_raw_{read,write} so that i2c_{read,write} return non-zero when error.
Acked-by: Nobuhiro Iwamatsu nobuhiro.iwamatsu.yj@renesas.com Signed-off-by: Tetsuyuki Kobayashi koba@kmckk.co.jp --- Changes for v2: - new Changes for v3: - call i2c_finsih before returning i2c_{read,write} even if error occured.
drivers/i2c/sh_i2c.c | 50 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 18 deletions(-)
diff --git a/drivers/i2c/sh_i2c.c b/drivers/i2c/sh_i2c.c index 1f5104c..6a5ecba 100644 --- a/drivers/i2c/sh_i2c.c +++ b/drivers/i2c/sh_i2c.c @@ -150,29 +150,37 @@ static void i2c_finish(struct sh_i2c *base) writeb(readb(&base->iccr) & ~SH_I2C_ICCR_ICE, &base->iccr); }
-static void i2c_raw_write(struct sh_i2c *base, u8 id, u8 reg, u8 val) +static int i2c_raw_write(struct sh_i2c *base, u8 id, u8 reg, u8 val) { - i2c_set_addr(base, id, reg, 0); + int ret = -1; + if (i2c_set_addr(base, id, reg, 0) != 0) + goto exit0; udelay(10);
writeb(val, &base->icdr); - irq_dte(base); + if (irq_dte_with_tack(base) != 0) + goto exit0;
writeb((SH_I2C_ICCR_ICE | SH_I2C_ICCR_RTS), &base->iccr); - irq_dte(base); + if (irq_dte_with_tack(base) != 0) + goto exit0; irq_busy(base); - + ret = 0; +exit0: i2c_finish(base); + return ret; }
-static u8 i2c_raw_read(struct sh_i2c *base, u8 id, u8 reg) +static int i2c_raw_read(struct sh_i2c *base, u8 id, u8 reg) { - u8 ret; + int ret = -1;
#if defined(CONFIG_SH73A0) - i2c_set_addr(base, id, reg, 0); + if (i2c_set_addr(base, id, reg, 0) != 0) + goto exit0; #else - i2c_set_addr(base, id, reg, 1); + if (i2c_set_addr(base, id, reg, 1) != 0) + goto exit0; udelay(100); #endif
@@ -180,17 +188,19 @@ static u8 i2c_raw_read(struct sh_i2c *base, u8 id, u8 reg) irq_dte(base);
writeb(id << 1 | 0x01, &base->icdr); - irq_dte(base); + if (irq_dte_with_tack(base) != 0) + goto exit0;
writeb((SH_I2C_ICCR_ICE|SH_I2C_ICCR_SCP), &base->iccr); - irq_dte(base); + if (irq_dte_with_tack(base) != 0) + goto exit0;
- ret = readb(&base->icdr); + ret = readb(&base->icdr) & 0xff;
writeb((SH_I2C_ICCR_ICE|SH_I2C_ICCR_RACK), &base->iccr); readb(&base->icdr); /* Dummy read */ irq_busy(base); - +exit0: i2c_finish(base);
return ret; @@ -302,10 +312,14 @@ void i2c_init(int speed, int slaveaddr) */ int i2c_read(u8 chip, u32 addr, int alen, u8 *buffer, int len) { + int ret; int i = 0; - for (i = 0 ; i < len ; i++) - buffer[i] = i2c_raw_read(base, chip, addr + i); - + for (i = 0 ; i < len ; i++) { + ret = i2c_raw_read(base, chip, addr + i); + if (ret < 0) + return -1; + buffer[i] = ret & 0xff; + } return 0; }
@@ -326,8 +340,8 @@ int i2c_write(u8 chip, u32 addr, int alen, u8 *buffer, int len) { int i = 0; for (i = 0; i < len ; i++) - i2c_raw_write(base, chip, addr + i, buffer[i]); - + if (i2c_raw_write(base, chip, addr + i, buffer[i]) != 0) + return -1; return 0; }

irq_wait() was not used. So removed it to elminate compiler warnings.
Acked-by: Nobuhiro Iwamatsu nobuhiro.iwamatsu.yj@renesas.com Signed-off-by: Tetsuyuki Kobayashi koba@kmckk.co.jp --- Changes for v2: - new Changes for v3: - none
drivers/i2c/sh_i2c.c | 16 ---------------- 1 file changed, 16 deletions(-)
diff --git a/drivers/i2c/sh_i2c.c b/drivers/i2c/sh_i2c.c index 6a5ecba..afcb503 100644 --- a/drivers/i2c/sh_i2c.c +++ b/drivers/i2c/sh_i2c.c @@ -58,22 +58,6 @@ static u16 iccl, icch;
#define IRQ_WAIT 1000
-static void irq_wait(struct sh_i2c *base) -{ - int i; - u8 status; - - for (i = 0 ; i < IRQ_WAIT ; i++) { - status = readb(&base->icsr); - if (SH_IC_WAIT & status) - break; - - udelay(10); - } - - writeb(status & ~SH_IC_WAIT, &base->icsr); -} - static void irq_dte(struct sh_i2c *base) { int i;

Supply clock to I2C1 and release resetting.
Acked-by: Nobuhiro Iwamatsu nobuhiro.iwamatsu.yj@renesas.com Signed-off-by: Tetsuyuki Kobayashi koba@kmckk.co.jp --- Changes for v2: - new Changes for v3: - none
board/kmc/kzm9g/kzm9g.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/board/kmc/kzm9g/kzm9g.c b/board/kmc/kzm9g/kzm9g.c index 0679be6..93ca9d7 100644 --- a/board/kmc/kzm9g/kzm9g.c +++ b/board/kmc/kzm9g/kzm9g.c @@ -43,6 +43,7 @@ DECLARE_GLOBAL_DATA_PTR; #define SMSTPCR1_CMT0 (1 << 24) #define SMSTPCR1_I2C0 (1 << 16) #define SMSTPCR3_USB (1 << 22) +#define SMSTPCR3_I2C1 (1 << 23)
#define PORT32CR (0xE6051020) #define PORT33CR (0xE6051021) @@ -300,8 +301,8 @@ int board_early_init_f(void)
clrbits_le32(&cpg->smstpcr1, (SMSTPCR1_CMT0|SMSTPCR1_I2C0)); clrbits_le32(&cpg_srcr->srcr1, (SMSTPCR1_CMT0|SMSTPCR1_I2C0)); - clrbits_le32(&cpg->smstpcr3, SMSTPCR3_USB); - clrbits_le32(&cpg_srcr->srcr3, SMSTPCR3_USB); + clrbits_le32(&cpg->smstpcr3, (SMSTPCR3_USB|SMSTPCR3_I2C1)); + clrbits_le32(&cpg_srcr->srcr3, (SMSTPCR3_USB|SMSTPCR3_I2C1)); writel(VCLKCR1_D, &cpg->vclkcr1);
/* Setup SCIF4 / workaround */

Acked-by: Nobuhiro Iwamatsu nobuhiro.iwamatsu.yj@renesas.com Signed-off-by: Tetsuyuki Kobayashi koba@kmckk.co.jp --- Changes for v2: - new Changes for v3: - none
board/kmc/kzm9g/kzm9g.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/board/kmc/kzm9g/kzm9g.c b/board/kmc/kzm9g/kzm9g.c index 93ca9d7..22f581a 100644 --- a/board/kmc/kzm9g/kzm9g.c +++ b/board/kmc/kzm9g/kzm9g.c @@ -370,6 +370,8 @@ int board_init(void) gpio_direction_output(GPIO_PORT15, 1);
/* I2C */ + gpio_request(GPIO_FN_PORT237_I2C_SCL2, NULL); + gpio_request(GPIO_FN_PORT236_I2C_SDA2, NULL); gpio_request(GPIO_FN_PORT27_I2C_SCL3, NULL); gpio_request(GPIO_FN_PORT28_I2C_SDA3, NULL);

Use setbits/clrbits macro when read-modify-write register.
Signed-off-by: Tetsuyuki Kobayashi koba@kmckk.co.jp --- Changes for v3: - new
drivers/i2c/sh_i2c.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/i2c/sh_i2c.c b/drivers/i2c/sh_i2c.c index afcb503..44ba90e 100644 --- a/drivers/i2c/sh_i2c.c +++ b/drivers/i2c/sh_i2c.c @@ -98,8 +98,8 @@ static int i2c_set_addr(struct sh_i2c *base, u8 id, u8 reg, int stop) { u8 icic = SH_IC_TACK;
- writeb(readb(&base->iccr) & ~SH_I2C_ICCR_ICE, &base->iccr); - writeb(readb(&base->iccr) | SH_I2C_ICCR_ICE, &base->iccr); + clrbits_8(&base->iccr, SH_I2C_ICCR_ICE); + setbits_8(&base->iccr, SH_I2C_ICCR_ICE);
writeb(iccl & 0xff, &base->iccl); writeb(icch & 0xff, &base->icch); @@ -114,7 +114,7 @@ static int i2c_set_addr(struct sh_i2c *base, u8 id, u8 reg, int stop) writeb((SH_I2C_ICCR_ICE|SH_I2C_ICCR_RTS|SH_I2C_ICCR_BUSY), &base->iccr); irq_dte(base);
- writeb(readb(&base->icsr) & ~SH_IC_TACK, &base->icsr); + clrbits_8(&base->icsr, SH_IC_TACK); writeb(id << 1, &base->icdr); if (irq_dte_with_tack(base) != 0) return -1; @@ -131,7 +131,7 @@ static int i2c_set_addr(struct sh_i2c *base, u8 id, u8 reg, int stop) static void i2c_finish(struct sh_i2c *base) { writeb(0, &base->icsr); - writeb(readb(&base->iccr) & ~SH_I2C_ICCR_ICE, &base->iccr); + clrbits_8(&base->iccr, SH_I2C_ICCR_ICE); }
static int i2c_raw_write(struct sh_i2c *base, u8 id, u8 reg, u8 val)

On Fri, Sep 14, 2012 at 2:08 PM, Tetsuyuki Kobayashi koba@kmckk.co.jp wrote:
Use setbits/clrbits macro when read-modify-write register.
Signed-off-by: Tetsuyuki Kobayashi koba@kmckk.co.jp
Changes for v3:
- new
drivers/i2c/sh_i2c.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/i2c/sh_i2c.c b/drivers/i2c/sh_i2c.c index afcb503..44ba90e 100644 --- a/drivers/i2c/sh_i2c.c +++ b/drivers/i2c/sh_i2c.c @@ -98,8 +98,8 @@ static int i2c_set_addr(struct sh_i2c *base, u8 id, u8 reg, int stop) { u8 icic = SH_IC_TACK;
writeb(readb(&base->iccr) & ~SH_I2C_ICCR_ICE, &base->iccr);
writeb(readb(&base->iccr) | SH_I2C_ICCR_ICE, &base->iccr);
clrbits_8(&base->iccr, SH_I2C_ICCR_ICE);
setbits_8(&base->iccr, SH_I2C_ICCR_ICE); writeb(iccl & 0xff, &base->iccl); writeb(icch & 0xff, &base->icch);
@@ -114,7 +114,7 @@ static int i2c_set_addr(struct sh_i2c *base, u8 id, u8 reg, int stop) writeb((SH_I2C_ICCR_ICE|SH_I2C_ICCR_RTS|SH_I2C_ICCR_BUSY), &base->iccr); irq_dte(base);
writeb(readb(&base->icsr) & ~SH_IC_TACK, &base->icsr);
clrbits_8(&base->icsr, SH_IC_TACK); writeb(id << 1, &base->icdr); if (irq_dte_with_tack(base) != 0) return -1;
@@ -131,7 +131,7 @@ static int i2c_set_addr(struct sh_i2c *base, u8 id, u8 reg, int stop) static void i2c_finish(struct sh_i2c *base) { writeb(0, &base->icsr);
writeb(readb(&base->iccr) & ~SH_I2C_ICCR_ICE, &base->iccr);
clrbits_8(&base->iccr, SH_I2C_ICCR_ICE);
}
static int i2c_raw_write(struct sh_i2c *base, u8 id, u8 reg, u8 val)
1.7.9.5
Acked-by: Nobuhiro Iwamatsu nobuhiro.iwamatsu.yj@renesas.com
Thanks!
Nobuhiro

Hello Tetsuyuki Kobayashi,
On 14.09.2012 07:07, Tetsuyuki Kobayashi wrote:
Iwamatu-san, thank you for review. This is v3 patch for sh_i2c. Changes for v3:
- call i2c_finish before returning i2c_probe, i2c_read, i2c_write even if error occured. Without this, it fails to boot Linux kernel after using "i2c probe" command.
- use setbits/clrbits macro as Iwamatsu-san pointed.
Please check patch 5,6 and 10. The rest is not changed.
This patch set is based on arm/rmobile branch of u-boot-sh.git.
Tetsuyuki Kobayashi (10): i2c: sh_i2c.c: support iccl and icch extension i2c: sh_i2c.c: correct BUSY bit define in ICSR i2c: sh_i2c.c: adjust for SH73A0 i2c: sh_i2c.c: support I2C2, I2C3 and I2C4 i2c: sh_i2c: enable i2c_probe i2c: sh_i2c.c: check error in i2c_read and i2c_write i2c: sh_i2c.c: remove unused function arm: rmobile: kzm9g: enable I2C1 arm: rmobile: kzm9g: enable I2C2 i2c: sh_i2c: use setbits/clrbits macro
board/kmc/kzm9g/kzm9g.c | 7 ++- drivers/i2c/sh_i2c.c | 139 ++++++++++++++++++++++++++++++++--------------- include/configs/kzm9g.h | 8 ++- 3 files changed, 107 insertions(+), 47 deletions(-)
Applied this patchset (exept patch "i2c: sh_i2c.c: remove unused function", as this patch is already in mainline) to u-boot-i2c master
Thanks!
bye, Heiko
participants (3)
-
Heiko Schocher
-
Nobuhiro Iwamatsu
-
Tetsuyuki Kobayashi