i2c for R-mobile
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
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
@@ -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
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.
Signed-off-by Tetsuyuki Kobayashi <[email protected]>--- drivers/i2c/sh_i2c.c | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-)drivers/i2c/sh_i2c.c +0
-0@@ -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
PATCH 2/3 i2c: sh_i2c.c: correct BUSY bit define in ICSR
In reply to Tetsuyuki KobayashiCorrect 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
@@ -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
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).
Signed-off-by Tetsuyuki Kobayashi <[email protected]>---
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@@ -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
PATCH 3/3 i2c: sh_i2c.c: adjust for SH73A0
In reply to Tetsuyuki KobayashiAdjust 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
@@ -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
@@ -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
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()insh_i2c.cto 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 <[email protected]>
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@@ -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@@ -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
v2 cover i2c for R-mobile
In reply to Tetsuyuki KobayashiHi, 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
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
@@ -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
@@ -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
PATCH v2 2/9 i2c: sh_i2c.c: correct BUSY bit define in ICSR
In reply to Tetsuyuki KobayashiCorrect 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
@@ -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
PATCH v2 3/9 i2c: sh_i2c.c: adjust for SH73A0
In reply to Tetsuyuki KobayashiAdjust 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
@@ -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
@@ -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
PATCH v2 4/9 i2c: sh_i2c.c: support I2C2, I2C3 and I2C4
In reply to Tetsuyuki Kobayashish_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
@@ -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
@@ -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
PATCH v2 4/9 i2c: sh_i2c.c: support I2C2, I2C3 and I2C4
Quoted 60 lines · Tetsuyuki Kobayashi
sh_i2c.csupport I2C0 and I2C1. This patch extends it to I2C4.Signed-off-by Tetsuyuki Kobayashi <[email protected]>---
Changes for v2:
- newdrivers/i2c/sh_i2c.c | 15 +++++++++++++++ include/configs/kzm9g.h | 5 ++++- 2 files changed, 19 insertions(+), 1 deletion(-)drivers/i2c/sh_i2c.c +15
-0@@ -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@@ -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
PATCH v2 5/9 i2c: sh_i2c: enable i2c_probe
In reply to Tetsuyuki KobayashiBefore 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
@@ -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
PATCH v2 6/9 i2c: sh_i2c.c: check error in i2c_read and i2c_write
In reply to Tetsuyuki KobayashiBefore 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
@@ -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
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.Signed-off-by Tetsuyuki Kobayashi <[email protected]>---
Changes for v2:
- newdrivers/i2c/sh_i2c.c | 44 ++++++++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 16 deletions(-)drivers/i2c/sh_i2c.c +28
-17@@ -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
PATCH v2 7/9 i2c: sh_i2c.c: remove unused function
In reply to Tetsuyuki Kobayashiirq_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
@@ -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
PATCH v2 8/9 arm: rmobile: kzm9g: enable I2C1
In reply to Tetsuyuki KobayashiSupply 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
@@ -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
PATCH v2 9/9 arm: rmobile: kzm9g: enable I2C2
In reply to Tetsuyuki KobayashiSet 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
@@ -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
v2 cover i2c for R-mobile
In reply to Tetsuyuki KobayashiSome 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
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
@@ -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
@@ -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
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.
Signed-off-by Tetsuyuki Kobayashi <[email protected]>---
Changes for v2:
- defineCONFIG_SH_I2C_8BITat board config file and replaceHAS_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@@ -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@@ -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
PATCH v2 2/9 i2c: sh_i2c.c: correct BUSY bit define in ICSR
In reply to Tetsuyuki KobayashiCorrect 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
@@ -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
PATCH v2 3/9 i2c: sh_i2c.c: adjust for SH73A0
In reply to Tetsuyuki KobayashiAdjust 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
@@ -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
@@ -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
PATCH v2 4/9 i2c: sh_i2c.c: support I2C2, I2C3 and I2C4
In reply to Tetsuyuki Kobayashish_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
@@ -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
@@ -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
PATCH v2 5/9 i2c: sh_i2c: enable i2c_probe
In reply to Tetsuyuki KobayashiBefore 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
@@ -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
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 makei2c_probe()call this function.Signed-off-by Tetsuyuki Kobayashi <[email protected]>---
Changes for v2:
- newdrivers/i2c/sh_i2c.c | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-)drivers/i2c/sh_i2c.c +24
-6@@ -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
PATCH v2 6/9 i2c: sh_i2c.c: check error in i2c_read and i2c_write
In reply to Tetsuyuki KobayashiBefore 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
@@ -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
PATCH v2 7/9 i2c: sh_i2c.c: remove unused function
In reply to Tetsuyuki Kobayashiirq_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
@@ -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
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.Signed-off-by Tetsuyuki Kobayashi <[email protected]>---
Changes for v2:
- newdrivers/i2c/sh_i2c.c | 16 ---------------- 1 file changed, 16 deletions(-)drivers/i2c/sh_i2c.c +0
-17@@ -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
PATCH v2 8/9 arm: rmobile: kzm9g: enable I2C1
In reply to Tetsuyuki KobayashiSupply 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
@@ -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
PATCH v2 8/9 arm: rmobile: kzm9g: enable I2C1
Quoted 34 lines · Tetsuyuki Kobayashi
Supply clock to I2C1 and release resetting.
Signed-off-by Tetsuyuki Kobayashi <[email protected]>---
Changes for v2:
- newboard/kmc/kzm9g/kzm9g.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)board/kmc/kzm9g/kzm9g.c +3
-3@@ -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
PATCH v2 9/9 arm: rmobile: kzm9g: enable I2C2
In reply to Tetsuyuki KobayashiSet 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
@@ -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
PATCH v2 9/9 arm: rmobile: kzm9g: enable I2C2
Quoted 24 lines · Tetsuyuki Kobayashi
Set gpio config for I2C2.
Signed-off-by Tetsuyuki Kobayashi <[email protected]>---
Changes for v2:
- newboard/kmc/kzm9g/kzm9g.c | 2 ++ 1 file changed, 2 insertions(+)board/kmc/kzm9g/kzm9g.c +2
-1@@ -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
v2 cover i2c for R-mobile
In reply to Tetsuyuki KobayashiHi,
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); toclrbits_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, HeikoIwamatu-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: enablei2c_probe
i2c:sh_i2c.c: check error ini2c_readandi2c_write
i2c:sh_i2c.c: remove unused function
arm: rmobile: kzm9g: enable I2C1
arm: rmobile: kzm9g: enable I2C2board/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
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 updatesh_i2cusing set/clrbits functions? these functions is included inasm/io.h.For example, you can change from
writeb(readb(&base->iccr) & ~SH_I2C_ICCR_ICE, &base->iccr); toclrbits_8(&base->iccr, SH_I2C_ICCR_ICE);
OK. I will try it.
v3 cover i2c for R-mobile
In reply to Tetsuyuki KobayashiHi, 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
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
@@ -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
@@ -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
PATCH v3 2/10 i2c: sh_i2c.c: correct BUSY bit define in ICSR
In reply to Tetsuyuki KobayashiCorrect 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
@@ -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
PATCH v3 3/10 i2c: sh_i2c.c: adjust for SH73A0
In reply to Tetsuyuki KobayashiAdjust 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
@@ -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
@@ -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
PATCH v3 4/10 i2c: sh_i2c.c: support I2C2, I2C3 and I2C4
In reply to Tetsuyuki Kobayashish_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
@@ -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
@@ -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
PATCH v3 5/10 i2c: sh_i2c: enable i2c_probe
In reply to Tetsuyuki KobayashiBefore 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
@@ -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
PATCH v3 6/10 i2c: sh_i2c.c: check error in i2c_read and i2c_write
In reply to Tetsuyuki KobayashiBefore 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
@@ -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
PATCH v3 7/10 i2c: sh_i2c.c: remove unused function
In reply to Tetsuyuki Kobayashiirq_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
@@ -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
PATCH v3 8/10 arm: rmobile: kzm9g: enable I2C1
In reply to Tetsuyuki KobayashiSupply 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
@@ -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
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
@@ -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
PATCH v3 10/10 i2c: sh_i2c: use setbits/clrbits macro
In reply to Tetsuyuki KobayashiUse 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
@@ -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
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.
Signed-off-by Tetsuyuki Kobayashi <[email protected]>---
Changes for v3:
- newdrivers/i2c/sh_i2c.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)drivers/i2c/sh_i2c.c +4
-5@@ -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
v3 cover i2c for R-mobile
In reply to Tetsuyuki KobayashiHello Tetsuyuki Kobayashi,
Quoted 22 lines · Tetsuyuki Kobayashi
Iwamatu-san, thank you for review. This is v3 patch for
sh_i2c.
Changes for v3:
- calli2c_finishbefore returningi2c_probe,i2c_read,i2c_writeeven 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: enablei2c_probe
i2c:sh_i2c.c: check error ini2c_readandi2c_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