[U-Boot] [PATCH 1/3] i2c: sh_i2c.c: support iccl and icch extension

2012-09-10 Thread 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 
---
 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
+
+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

___
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot


Re: [U-Boot] [PATCH 1/3] i2c: sh_i2c.c: support iccl and icch extension

2012-09-11 Thread Nobuhiro Iwamatsu
Hi,

I add Heiko Schocher  to Cc:
Heiko is I2C maintainer.

On Tue, Sep 11, 2012 at 2:58 PM, Tetsuyuki Kobayashi  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 
> ---
>  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

-- 
Nobuhiro Iwamatsu
___
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot