diff options
author | Magnus Damm <damm@opensource.se> | 2010-03-11 10:06:02 +0000 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2010-04-07 16:19:47 +0900 |
commit | 962b6032c889ed9a5f0bdb7052d9318067a75bda (patch) | |
tree | b65470944ebdc16235225997d01d97d92d82f1c4 /drivers | |
parent | 12a55f2db71e0a1474ba56ab1c93287600b915be (diff) | |
download | op-kernel-dev-962b6032c889ed9a5f0bdb7052d9318067a75bda.zip op-kernel-dev-962b6032c889ed9a5f0bdb7052d9318067a75bda.tar.gz |
i2c: i2c-sh_mobile support for new ICIC bits
Add support for a new version of the IIC block
found in the SH-Mobile ARM line of processors.
Prototype patch written by Nishimoto-san.
Tested on sh7377 and sh7372.
Signed-off-by: NISHIMOTO Hiroki <nishimoto.hiroki@renesas.com>
Signed-off-by: Magnus Damm <damm@opensource.se>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/i2c/busses/i2c-sh_mobile.c | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/drivers/i2c/busses/i2c-sh_mobile.c b/drivers/i2c/busses/i2c-sh_mobile.c index d2fabd9..598c49a 100644 --- a/drivers/i2c/busses/i2c-sh_mobile.c +++ b/drivers/i2c/busses/i2c-sh_mobile.c @@ -119,8 +119,10 @@ struct sh_mobile_i2c_data { struct i2c_adapter adap; struct clk *clk; + u_int8_t icic; u_int8_t iccl; u_int8_t icch; + u_int8_t flags; spinlock_t lock; wait_queue_head_t wait; @@ -129,6 +131,8 @@ struct sh_mobile_i2c_data { int sr; }; +#define IIC_FLAG_HAS_ICIC67 (1 << 0) + #define NORMAL_SPEED 100000 /* FAST_SPEED 400000 */ /* Register offsets */ @@ -155,6 +159,8 @@ struct sh_mobile_i2c_data { #define ICSR_WAIT 0x02 #define ICSR_DTE 0x01 +#define ICIC_ICCLB8 0x80 +#define ICIC_ICCHB8 0x40 #define ICIC_ALE 0x08 #define ICIC_TACKE 0x04 #define ICIC_WAITE 0x02 @@ -162,6 +168,9 @@ struct sh_mobile_i2c_data { static void iic_wr(struct sh_mobile_i2c_data *pd, int offs, unsigned char data) { + if (offs == ICIC) + data |= pd->icic; + iowrite8(data, pd->reg + offs); } @@ -203,6 +212,14 @@ static void activate_ch(struct sh_mobile_i2c_data *pd) else pd->iccl = (u_int8_t)(num/denom); + /* one more bit of ICCL in ICIC */ + if (pd->flags & IIC_FLAG_HAS_ICIC67) { + if ((num/denom) > 0xff) + pd->icic |= ICIC_ICCLB8; + else + pd->icic &= ~ICIC_ICCLB8; + } + /* Calculate the value for icch. From the data sheet: icch = (p clock / transfer rate) * (H / (L + H)) */ num = i2c_clk * 4; @@ -212,6 +229,14 @@ static void activate_ch(struct sh_mobile_i2c_data *pd) else pd->icch = (u_int8_t)(num/denom); + /* one more bit of ICCH in ICIC */ + if (pd->flags & IIC_FLAG_HAS_ICIC67) { + if ((num/denom) > 0xff) + pd->icic |= ICIC_ICCHB8; + else + pd->icic &= ~ICIC_ICCHB8; + } + /* Enable channel and configure rx ack */ iic_set_clr(pd, ICCR, ICCR_ICE, 0); @@ -592,6 +617,12 @@ static int sh_mobile_i2c_probe(struct platform_device *dev) goto err_irq; } + /* The IIC blocks on SH-Mobile ARM processors + * come with two new bits in ICIC. + */ + if (size > 0x17) + pd->flags |= IIC_FLAG_HAS_ICIC67; + /* Enable Runtime PM for this device. * * Also tell the Runtime PM core to ignore children |