mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-12-01 08:59:33 +00:00
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:
parent
bd23b22bad
commit
b1af67fe5e
2 changed files with 23 additions and 8 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in a new issue