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