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.

Acked-by: Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
Signed-off-by: Tetsuyuki Kobayashi <koba@kmckk.co.jp>
This commit is contained in:
Tetsuyuki Kobayashi 2012-09-13 19:07:56 +00:00 committed by Heiko Schocher
parent bd23b22bad
commit b1af67fe5e
2 changed files with 23 additions and 8 deletions

View file

@ -48,7 +48,13 @@ static struct sh_i2c *base;
#define SH_IC_WAIT (1 << 1) #define SH_IC_WAIT (1 << 1)
#define SH_IC_DTE (1 << 0) #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 #define IRQ_WAIT 1000
@ -76,12 +82,20 @@ static void irq_busy(struct sh_i2c *base)
static void i2c_set_addr(struct sh_i2c *base, u8 id, u8 reg, int stop) 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(readb(&base->iccr) | SH_I2C_ICCR_ICE, &base->iccr); writeb(readb(&base->iccr) | SH_I2C_ICCR_ICE, &base->iccr);
writeb(iccl, &base->iccl); writeb(iccl & 0xff, &base->iccl);
writeb(icch, &base->icch); writeb(icch & 0xff, &base->icch);
writeb(0, &base->icic); #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); writeb((SH_I2C_ICCR_ICE|SH_I2C_ICCR_RTS|SH_I2C_ICCR_BUSY), &base->iccr);
irq_dte(base); irq_dte(base);
@ -206,18 +220,18 @@ void i2c_init(int speed, int slaveaddr)
denom = speed * (CONFIG_SH_I2C_DATA_HIGH + CONFIG_SH_I2C_DATA_LOW); denom = speed * (CONFIG_SH_I2C_DATA_HIGH + CONFIG_SH_I2C_DATA_LOW);
tmp = num * 10 / denom; tmp = num * 10 / denom;
if (tmp % 10 >= 5) if (tmp % 10 >= 5)
iccl = (u8)((num/denom) + 1); iccl = (u16)((num/denom) + 1);
else else
iccl = (u8)(num/denom); iccl = (u16)(num/denom);
/* Calculate the value for icch. From the data sheet: /* Calculate the value for icch. From the data sheet:
icch = (p clock / transfer rate) * (H / (L + H)) */ icch = (p clock / transfer rate) * (H / (L + H)) */
num = CONFIG_SH_I2C_CLOCK * CONFIG_SH_I2C_DATA_HIGH; num = CONFIG_SH_I2C_CLOCK * CONFIG_SH_I2C_DATA_HIGH;
tmp = num * 10 / denom; tmp = num * 10 / denom;
if (tmp % 10 >= 5) if (tmp % 10 >= 5)
icch = (u8)((num/denom) + 1); icch = (u16)((num/denom) + 1);
else else
icch = (u8)(num/denom); icch = (u16)(num/denom);
} }
/* /*

View file

@ -154,6 +154,7 @@
/* I2C */ /* I2C */
#define CONFIG_CMD_I2C #define CONFIG_CMD_I2C
#define CONFIG_SH_I2C 1 #define CONFIG_SH_I2C 1
#define CONFIG_SH_I2C_8BIT
#define CONFIG_HARD_I2C #define CONFIG_HARD_I2C
#define CONFIG_I2C_MULTI_BUS #define CONFIG_I2C_MULTI_BUS
#define CONFIG_SYS_MAX_I2C_BUS (2) #define CONFIG_SYS_MAX_I2C_BUS (2)