Skip to contentSkip to conversation

i2c for R-mobile

PATCH Superseded Tetsuyuki Kobayashi 3 participants 49 messages Sep 11, 2012 – Oct 16, 2012 I2C

lore
Share & tools
lore
#0 lore raw

cover 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(-)
Signature · 1 line
1.7.9.5
#1 lore raw

PATCH 1/3 i2c: sh_i2c.c: support iccl and icch extension

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.

---
 drivers/i2c/sh_i2c.c |   32 ++++++++++++++++++++++++--------
 1 file changed, 24 insertions(+), 8 deletions(-)
drivers/i2c/sh_i2c.c +24 -8
index fd8cb92..59402ba 100644
@@ -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);
 }
 
 /*
Signature · 1 line
1.7.9.5
#2 lore raw

PATCH 1/3 i2c: sh_i2c.c: support iccl and icch extension

Hi,

I add Heiko Schocher <[email protected]> to Cc:
Heiko is I2C maintainer.

Quoted 14 lines · Tetsuyuki Kobayashi

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.

---
 drivers/i2c/sh_i2c.c |   32 ++++++++++++++++++++++++--------
 1 file changed, 24 insertions(+), 8 deletions(-)
drivers/i2c/sh_i2c.c +0 -0
index fd8cb92..59402ba 100644
@@ -48,7 +48,15 @@ static struct sh_i2c *base;
 #define SH_IC_WAIT     (1 << 1)

drivers/i2c/sh_i2c.c static struct sh_i2c *base; · line 57

Quoted 10 lines
drivers/i2c/sh_i2c.c +7 -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.

Quoted 53 lines
drivers/i2c/sh_i2c.c +17 -8
+
+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);
 }
 
 /*
--
Quoted 2 lines

1.7.9.5

Best regards,
Nobuhiro

Signature · 1 line
Nobuhiro Iwamatsu
#3 lore raw

PATCH 2/3 i2c: sh_i2c.c: correct BUSY bit define in ICSR

In reply to Tetsuyuki Kobayashi

Correct BUSY bit define in ICSR from (1<<3) to (1<<4).

---
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(-)
drivers/i2c/sh_i2c.c +1 -1
index 59402ba..84f1f5b 100644
@@ -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)
Signature · 1 line
1.7.9.5
#4 lore raw

PATCH 2/3 i2c: sh_i2c.c: correct BUSY bit define in ICSR

Hi,

I add Heiko Schocher <[email protected]> to Cc:
Heiko is I2C maintainer.

Quoted 8 lines · Tetsuyuki Kobayashi

Correct BUSY bit define in ICSR from (1<<3) to (1<<4).

---
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!

Quoted 20 lines
 drivers/i2c/sh_i2c.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/i2c/sh_i2c.c +1 -2
index 59402ba..84f1f5b 100644
@@ -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

Signature · 1 line
Nobuhiro Iwamatsu
#5 lore raw

PATCH 3/3 i2c: sh_i2c.c: adjust for SH73A0

In reply to Tetsuyuki Kobayashi

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.

---
 drivers/i2c/sh_i2c.c    |    4 ++++
 include/configs/kzm9g.h |    2 +-
 2 files changed, 5 insertions(+), 1 deletion(-)
drivers/i2c/sh_i2c.c +4 -0
index 84f1f5b..e8efdc9 100644
@@ -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);
include/configs/kzm9g.h +1 -1
index a1ae718..5eccd29 100644
@@ -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)
 
Signature · 1 line
1.7.9.5
#6 lore raw

PATCH 3/3 i2c: sh_i2c.c: adjust for SH73A0

Hi,

I add Heiko Schocher <[email protected]> to Cc:
Heiko is I2C maintainer.

Quoted 4 lines · Tetsuyuki Kobayashi

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.

Quoted 36 lines
---
 drivers/i2c/sh_i2c.c    |    4 ++++
 include/configs/kzm9g.h |    2 +-
 2 files changed, 5 insertions(+), 1 deletion(-)
drivers/i2c/sh_i2c.c +4 -0
index 84f1f5b..e8efdc9 100644
@@ -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);
include/configs/kzm9g.h +1 -2
index a1ae718..5eccd29 100644
@@ -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)
 
--
Quoted 2 lines

1.7.9.5

Best regards,
Nobuhiro

Signature · 1 line
Nobuhiro Iwamatsu
#7 lore raw

v2 cover i2c for R-mobile

In reply to Tetsuyuki Kobayashi

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(-)
Signature · 1 line
1.7.9.5
#8 lore raw

PATCH v2 1/9 i2c: sh_i2c.c: support iccl and icch extension

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.

---
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(-)
drivers/i2c/sh_i2c.c +22 -8
index fd8cb92..b98fce5 100644
@@ -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);
 }
 
 /*
include/configs/kzm9g.h +1 -0
index a1ae718..8877516 100644
@@ -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)
Signature · 1 line
1.7.9.5
#9 lore raw

PATCH v2 2/9 i2c: sh_i2c.c: correct BUSY bit define in ICSR

In reply to Tetsuyuki Kobayashi

Correct BUSY bit define in ICSR from (1<<3) to (1<<4).

---
Changes for v2:
- none

 drivers/i2c/sh_i2c.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/i2c/sh_i2c.c +1 -1
index b98fce5..03dfa7a 100644
@@ -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)
Signature · 1 line
1.7.9.5
#10 lore raw

PATCH v2 3/9 i2c: sh_i2c.c: adjust for SH73A0

In reply to Tetsuyuki Kobayashi

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.

---
Changes for v2:
- none

 drivers/i2c/sh_i2c.c    |    4 ++++
 include/configs/kzm9g.h |    2 +-
 2 files changed, 5 insertions(+), 1 deletion(-)
drivers/i2c/sh_i2c.c +4 -0
index 03dfa7a..6c6a141 100644
@@ -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);
include/configs/kzm9g.h +1 -1
index 8877516..abeab69 100644
@@ -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)
 
Signature · 1 line
1.7.9.5
#11 lore raw

PATCH v2 4/9 i2c: sh_i2c.c: support I2C2, I2C3 and I2C4

In reply to Tetsuyuki Kobayashi

sh_i2c.c support I2C0 and I2C1. This patch extends it to I2C4.

---
Changes for v2:
- new

 drivers/i2c/sh_i2c.c    |   15 +++++++++++++++
 include/configs/kzm9g.h |    5 ++++-
 2 files changed, 19 insertions(+), 1 deletion(-)
drivers/i2c/sh_i2c.c +15 -0
index 6c6a141..d524619 100644
@@ -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;
 	}
include/configs/kzm9g.h +4 -1
index abeab69..6a0b6c5 100644
@@ -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 */
Signature · 1 line
1.7.9.5
#12 lore raw

PATCH v2 4/9 i2c: sh_i2c.c: support I2C2, I2C3 and I2C4

Quoted 60 lines · Tetsuyuki Kobayashi

sh_i2c.c support I2C0 and I2C1. This patch extends it to I2C4.

---
Changes for v2:
- new

 drivers/i2c/sh_i2c.c    |   15 +++++++++++++++
 include/configs/kzm9g.h |    5 ++++-
 2 files changed, 19 insertions(+), 1 deletion(-)
drivers/i2c/sh_i2c.c +15 -0
index 6c6a141..d524619 100644
@@ -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;
        }
include/configs/kzm9g.h +4 -2
index abeab69..6a0b6c5 100644
@@ -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 */
--
Quoted 1 line

1.7.9.5

Best regards,
Nobuhiro

Signature · 1 line
Nobuhiro Iwamatsu
#13 lore raw

PATCH v2 5/9 i2c: sh_i2c: enable i2c_probe

In reply to Tetsuyuki Kobayashi

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.

---
Changes for v2:
- new

 drivers/i2c/sh_i2c.c |   29 ++++++++++++++++++++++++-----
 1 file changed, 24 insertions(+), 5 deletions(-)
drivers/i2c/sh_i2c.c +24 -5
index d524619..25dbc43 100644
@@ -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);
 }
Signature · 1 line
1.7.9.5
#14 lore raw

PATCH v2 6/9 i2c: sh_i2c.c: check error in i2c_read and i2c_write

In reply to Tetsuyuki Kobayashi

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.

---
Changes for v2:
- new

 drivers/i2c/sh_i2c.c |   44 ++++++++++++++++++++++++++++----------------
 1 file changed, 28 insertions(+), 16 deletions(-)
drivers/i2c/sh_i2c.c +28 -16
index 25dbc43..e3ee804 100644
@@ -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;
 }
 
Signature · 1 line
1.7.9.5
#15 lore raw

PATCH v2 6/9 i2c: sh_i2c.c: check error in i2c_read and i2c_write

Quoted 107 lines · Tetsuyuki Kobayashi

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.

---
Changes for v2:
- new

 drivers/i2c/sh_i2c.c |   44 ++++++++++++++++++++++++++++----------------
 1 file changed, 28 insertions(+), 16 deletions(-)
drivers/i2c/sh_i2c.c +28 -17
index 25dbc43..e3ee804 100644
@@ -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;
 }
 
--
Quoted 2 lines

1.7.9.5

Best regards,
Nobuhiro

Signature · 1 line
Nobuhiro Iwamatsu
#16 lore raw

PATCH v2 7/9 i2c: sh_i2c.c: remove unused function

In reply to Tetsuyuki Kobayashi

irq_wait() was not used. So removed it to elminate compiler warnings.

---
Changes for v2:
- new

 drivers/i2c/sh_i2c.c |   16 ----------------
 1 file changed, 16 deletions(-)
drivers/i2c/sh_i2c.c +0 -16
index e3ee804..60bad52 100644
@@ -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;
Signature · 1 line
1.7.9.5
#17 lore raw

PATCH v2 8/9 arm: rmobile: kzm9g: enable I2C1

In reply to Tetsuyuki Kobayashi

Supply clock to I2C1 and release resetting.

---
Changes for v2:
- new

 board/kmc/kzm9g/kzm9g.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
board/kmc/kzm9g/kzm9g.c +3 -2
index 0679be6..93ca9d7 100644
@@ -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 */
Signature · 1 line
1.7.9.5
#18 lore raw

PATCH v2 9/9 arm: rmobile: kzm9g: enable I2C2

In reply to Tetsuyuki Kobayashi

Set gpio config for I2C2.

---
Changes for v2:
- new

 board/kmc/kzm9g/kzm9g.c |    2 ++
 1 file changed, 2 insertions(+)
board/kmc/kzm9g/kzm9g.c +2 -0
index 93ca9d7..22f581a 100644
@@ -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);
 
Signature · 1 line
1.7.9.5
#19 lore raw

v2 cover i2c for R-mobile

In reply to Tetsuyuki Kobayashi

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(-)
Signature · 1 line
1.7.9.5
#20 lore raw

PATCH v2 1/9 i2c: sh_i2c.c: support iccl and icch extension

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.

---
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(-)
drivers/i2c/sh_i2c.c +22 -8
index fd8cb92..b98fce5 100644
@@ -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);
 }
 
 /*
include/configs/kzm9g.h +1 -0
index a1ae718..8877516 100644
@@ -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)
Signature · 1 line
1.7.9.5
#21 lore raw

PATCH v2 1/9 i2c: sh_i2c.c: support iccl and icch extension

Quoted 92 lines · Tetsuyuki Kobayashi

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.

---
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(-)
drivers/i2c/sh_i2c.c +22 -8
index fd8cb92..b98fce5 100644
@@ -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);
 }
 
 /*
include/configs/kzm9g.h +1 -1
index a1ae718..8877516 100644
@@ -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)
--
Quoted 1 line

1.7.9.5

Best regards,
Nobuhiro

Signature · 1 line
Nobuhiro Iwamatsu
#22 lore raw

PATCH v2 2/9 i2c: sh_i2c.c: correct BUSY bit define in ICSR

In reply to Tetsuyuki Kobayashi

Correct BUSY bit define in ICSR from (1<<3) to (1<<4).

---
Changes for v2:
- none

 drivers/i2c/sh_i2c.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/i2c/sh_i2c.c +1 -1
index b98fce5..03dfa7a 100644
@@ -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)
Signature · 1 line
1.7.9.5
#23 lore raw

PATCH v2 3/9 i2c: sh_i2c.c: adjust for SH73A0

In reply to Tetsuyuki Kobayashi

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.

---
Changes for v2:
- none

 drivers/i2c/sh_i2c.c    |    4 ++++
 include/configs/kzm9g.h |    2 +-
 2 files changed, 5 insertions(+), 1 deletion(-)
drivers/i2c/sh_i2c.c +4 -0
index 03dfa7a..6c6a141 100644
@@ -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);
include/configs/kzm9g.h +1 -1
index 8877516..abeab69 100644
@@ -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)
 
Signature · 1 line
1.7.9.5
#24 lore raw

PATCH v2 4/9 i2c: sh_i2c.c: support I2C2, I2C3 and I2C4

In reply to Tetsuyuki Kobayashi

sh_i2c.c support I2C0 and I2C1. This patch extends it to I2C4.

---
Changes for v2:
- new

 drivers/i2c/sh_i2c.c    |   15 +++++++++++++++
 include/configs/kzm9g.h |    5 ++++-
 2 files changed, 19 insertions(+), 1 deletion(-)
drivers/i2c/sh_i2c.c +15 -0
index 6c6a141..d524619 100644
@@ -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;
 	}
include/configs/kzm9g.h +4 -1
index abeab69..6a0b6c5 100644
@@ -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 */
Signature · 1 line
1.7.9.5
#25 lore raw

PATCH v2 5/9 i2c: sh_i2c: enable i2c_probe

In reply to Tetsuyuki Kobayashi

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.

---
Changes for v2:
- new

 drivers/i2c/sh_i2c.c |   29 ++++++++++++++++++++++++-----
 1 file changed, 24 insertions(+), 5 deletions(-)
drivers/i2c/sh_i2c.c +24 -5
index d524619..25dbc43 100644
@@ -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);
 }
Signature · 1 line
1.7.9.5
#26 lore raw

PATCH v2 5/9 i2c: sh_i2c: enable i2c_probe

Quoted 79 lines · Tetsuyuki Kobayashi

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.

---
Changes for v2:
- new

 drivers/i2c/sh_i2c.c |   29 ++++++++++++++++++++++++-----
 1 file changed, 24 insertions(+), 5 deletions(-)
drivers/i2c/sh_i2c.c +24 -6
index d524619..25dbc43 100644
@@ -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);
 }
--
Quoted 2 lines

1.7.9.5

Best regards,
Nobuhiro

Signature · 1 line
Nobuhiro Iwamatsu
#27 lore raw

PATCH v2 6/9 i2c: sh_i2c.c: check error in i2c_read and i2c_write

In reply to Tetsuyuki Kobayashi

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.

---
Changes for v2:
- new

 drivers/i2c/sh_i2c.c |   44 ++++++++++++++++++++++++++++----------------
 1 file changed, 28 insertions(+), 16 deletions(-)
drivers/i2c/sh_i2c.c +28 -16
index 25dbc43..e3ee804 100644
@@ -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;
 }
 
Signature · 1 line
1.7.9.5
#28 lore raw

PATCH v2 7/9 i2c: sh_i2c.c: remove unused function

In reply to Tetsuyuki Kobayashi

irq_wait() was not used. So removed it to elminate compiler warnings.

---
Changes for v2:
- new

 drivers/i2c/sh_i2c.c |   16 ----------------
 1 file changed, 16 deletions(-)
drivers/i2c/sh_i2c.c +0 -16
index e3ee804..60bad52 100644
@@ -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;
Signature · 1 line
1.7.9.5
#29 lore raw

PATCH v2 7/9 i2c: sh_i2c.c: remove unused function

Quoted 38 lines · Tetsuyuki Kobayashi

irq_wait() was not used. So removed it to elminate compiler warnings.

---
Changes for v2:
- new

 drivers/i2c/sh_i2c.c |   16 ----------------
 1 file changed, 16 deletions(-)
drivers/i2c/sh_i2c.c +0 -17
index e3ee804..60bad52 100644
@@ -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;
--
Quoted 2 lines

1.7.9.5

Best regards,
Nobuhiro

Signature · 1 line
Nobuhiro Iwamatsu
#30 lore raw

PATCH v2 8/9 arm: rmobile: kzm9g: enable I2C1

In reply to Tetsuyuki Kobayashi

Supply clock to I2C1 and release resetting.

---
Changes for v2:
- new

 board/kmc/kzm9g/kzm9g.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
board/kmc/kzm9g/kzm9g.c +3 -2
index 0679be6..93ca9d7 100644
@@ -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 */
Signature · 1 line
1.7.9.5
#31 lore raw

PATCH v2 8/9 arm: rmobile: kzm9g: enable I2C1

Quoted 34 lines · Tetsuyuki Kobayashi

Supply clock to I2C1 and release resetting.

---
Changes for v2:
- new

 board/kmc/kzm9g/kzm9g.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
board/kmc/kzm9g/kzm9g.c +3 -3
index 0679be6..93ca9d7 100644
@@ -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 */
--
Quoted 2 lines

1.7.9.5

Best regards,
Nobuhiro

Signature · 1 line
Nobuhiro Iwamatsu
#32 lore raw

PATCH v2 9/9 arm: rmobile: kzm9g: enable I2C2

In reply to Tetsuyuki Kobayashi

Set gpio config for I2C2.

---
Changes for v2:
- new

 board/kmc/kzm9g/kzm9g.c |    2 ++
 1 file changed, 2 insertions(+)
board/kmc/kzm9g/kzm9g.c +2 -0
index 93ca9d7..22f581a 100644
@@ -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);
 
Signature · 1 line
1.7.9.5
#33 lore raw

PATCH v2 9/9 arm: rmobile: kzm9g: enable I2C2

Quoted 24 lines · Tetsuyuki Kobayashi

Set gpio config for I2C2.

---
Changes for v2:
- new

 board/kmc/kzm9g/kzm9g.c |    2 ++
 1 file changed, 2 insertions(+)
board/kmc/kzm9g/kzm9g.c +2 -1
index 93ca9d7..22f581a 100644
@@ -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);
 
--
Quoted 2 lines

1.7.9.5

Best regards,
Nobuhiro

Signature · 1 line
Nobuhiro Iwamatsu
#34 lore raw

v2 cover i2c for R-mobile

In reply to Tetsuyuki Kobayashi

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

Quoted 35 lines · Tetsuyuki Kobayashi

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 at lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Signature · 1 line
Nobuhiro Iwamatsu
#35 lore raw

v2 cover i2c for R-mobile

Iwamatu-san,
Thank you for review.

Quoted 10 lines · Nobuhiro Iwamatsu

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.

#36 lore raw

v3 cover i2c for R-mobile

In reply to Tetsuyuki Kobayashi

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(-)
Signature · 1 line
1.7.9.5
#37 lore raw

PATCH v3 1/10 i2c: sh_i2c.c: support iccl and icch extension

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.

---
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(-)
drivers/i2c/sh_i2c.c +22 -8
index fd8cb92..b98fce5 100644
@@ -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);
 }
 
 /*
include/configs/kzm9g.h +1 -0
index a1ae718..8877516 100644
@@ -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)
Signature · 1 line
1.7.9.5
#38 lore raw

PATCH v3 2/10 i2c: sh_i2c.c: correct BUSY bit define in ICSR

In reply to Tetsuyuki Kobayashi

Correct BUSY bit define in ICSR from (1<<3) to (1<<4).

---
Changes for v2:
- none
Changes for v3:
- none

 drivers/i2c/sh_i2c.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/i2c/sh_i2c.c +1 -1
index b98fce5..03dfa7a 100644
@@ -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)
Signature · 1 line
1.7.9.5
#39 lore raw

PATCH v3 3/10 i2c: sh_i2c.c: adjust for SH73A0

In reply to Tetsuyuki Kobayashi

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.

---
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(-)
drivers/i2c/sh_i2c.c +4 -0
index 03dfa7a..6c6a141 100644
@@ -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);
include/configs/kzm9g.h +1 -1
index 8877516..abeab69 100644
@@ -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)
 
Signature · 1 line
1.7.9.5
#40 lore raw

PATCH v3 4/10 i2c: sh_i2c.c: support I2C2, I2C3 and I2C4

In reply to Tetsuyuki Kobayashi

sh_i2c.c support I2C0 and I2C1. This patch extends it to I2C4.

---
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(-)
drivers/i2c/sh_i2c.c +15 -0
index 6c6a141..d524619 100644
@@ -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;
 	}
include/configs/kzm9g.h +4 -1
index abeab69..6a0b6c5 100644
@@ -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 */
Signature · 1 line
1.7.9.5
#41 lore raw

PATCH v3 5/10 i2c: sh_i2c: enable i2c_probe

In reply to Tetsuyuki Kobayashi

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.

---
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(-)
drivers/i2c/sh_i2c.c +27 -5
index d524619..1f5104c 100644
@@ -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;
 }
Signature · 1 line
1.7.9.5
#42 lore raw

PATCH v3 6/10 i2c: sh_i2c.c: check error in i2c_read and i2c_write

In reply to Tetsuyuki Kobayashi

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.

---
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(-)
drivers/i2c/sh_i2c.c +32 -18
index 1f5104c..6a5ecba 100644
@@ -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;
 }
 
Signature · 1 line
1.7.9.5
#43 lore raw

PATCH v3 7/10 i2c: sh_i2c.c: remove unused function

In reply to Tetsuyuki Kobayashi

irq_wait() was not used. So removed it to elminate compiler warnings.

---
Changes for v2:
- new
Changes for v3:
- none

 drivers/i2c/sh_i2c.c |   16 ----------------
 1 file changed, 16 deletions(-)
drivers/i2c/sh_i2c.c +0 -16
index 6a5ecba..afcb503 100644
@@ -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;
Signature · 1 line
1.7.9.5
#44 lore raw

PATCH v3 8/10 arm: rmobile: kzm9g: enable I2C1

In reply to Tetsuyuki Kobayashi

Supply clock to I2C1 and release resetting.

---
Changes for v2:
- new
Changes for v3:
- none

 board/kmc/kzm9g/kzm9g.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
board/kmc/kzm9g/kzm9g.c +3 -2
index 0679be6..93ca9d7 100644
@@ -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 */
Signature · 1 line
1.7.9.5
#45 lore raw

PATCH v3 9/10 arm: rmobile: kzm9g: enable I2C2

In reply to Tetsuyuki Kobayashi

---
Changes for v2:
- new
Changes for v3:
- none

 board/kmc/kzm9g/kzm9g.c |    2 ++
 1 file changed, 2 insertions(+)
board/kmc/kzm9g/kzm9g.c +2 -0
index 93ca9d7..22f581a 100644
@@ -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);
 
Signature · 1 line
1.7.9.5
#46 lore raw

PATCH v3 10/10 i2c: sh_i2c: use setbits/clrbits macro

In reply to Tetsuyuki Kobayashi

Use setbits/clrbits macro when read-modify-write register.

---
Changes for v3:
- new

 drivers/i2c/sh_i2c.c |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/i2c/sh_i2c.c +4 -4
index afcb503..44ba90e 100644
@@ -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)
Signature · 1 line
1.7.9.5
#47 lore raw

PATCH v3 10/10 i2c: sh_i2c: use setbits/clrbits macro

Quoted 44 lines · Tetsuyuki Kobayashi

Use setbits/clrbits macro when read-modify-write register.

---
Changes for v3:
- new

 drivers/i2c/sh_i2c.c |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/i2c/sh_i2c.c +4 -5
index afcb503..44ba90e 100644
@@ -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)
--
Quoted 1 line

1.7.9.5

Thanks!

Nobuhiro

Signature · 1 line
Nobuhiro Iwamatsu
#48 lore raw

v3 cover i2c for R-mobile

In reply to Tetsuyuki Kobayashi

Hello Tetsuyuki Kobayashi,

Quoted 22 lines · Tetsuyuki Kobayashi

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

Quoted 4 lines
  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

Signature · 2 lines
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany