Commit 962b6032 authored by Magnus Damm's avatar Magnus Damm Committed by Paul Mundt

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: default avatarNISHIMOTO Hiroki <nishimoto.hiroki@renesas.com>
Signed-off-by: default avatarMagnus Damm <damm@opensource.se>
Signed-off-by: default avatarPaul Mundt <lethal@linux-sh.org>
parent 12a55f2d
...@@ -119,8 +119,10 @@ struct sh_mobile_i2c_data { ...@@ -119,8 +119,10 @@ struct sh_mobile_i2c_data {
struct i2c_adapter adap; struct i2c_adapter adap;
struct clk *clk; struct clk *clk;
u_int8_t icic;
u_int8_t iccl; u_int8_t iccl;
u_int8_t icch; u_int8_t icch;
u_int8_t flags;
spinlock_t lock; spinlock_t lock;
wait_queue_head_t wait; wait_queue_head_t wait;
...@@ -129,6 +131,8 @@ struct sh_mobile_i2c_data { ...@@ -129,6 +131,8 @@ struct sh_mobile_i2c_data {
int sr; int sr;
}; };
#define IIC_FLAG_HAS_ICIC67 (1 << 0)
#define NORMAL_SPEED 100000 /* FAST_SPEED 400000 */ #define NORMAL_SPEED 100000 /* FAST_SPEED 400000 */
/* Register offsets */ /* Register offsets */
...@@ -155,6 +159,8 @@ struct sh_mobile_i2c_data { ...@@ -155,6 +159,8 @@ struct sh_mobile_i2c_data {
#define ICSR_WAIT 0x02 #define ICSR_WAIT 0x02
#define ICSR_DTE 0x01 #define ICSR_DTE 0x01
#define ICIC_ICCLB8 0x80
#define ICIC_ICCHB8 0x40
#define ICIC_ALE 0x08 #define ICIC_ALE 0x08
#define ICIC_TACKE 0x04 #define ICIC_TACKE 0x04
#define ICIC_WAITE 0x02 #define ICIC_WAITE 0x02
...@@ -162,6 +168,9 @@ struct sh_mobile_i2c_data { ...@@ -162,6 +168,9 @@ struct sh_mobile_i2c_data {
static void iic_wr(struct sh_mobile_i2c_data *pd, int offs, unsigned char 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); iowrite8(data, pd->reg + offs);
} }
...@@ -203,6 +212,14 @@ static void activate_ch(struct sh_mobile_i2c_data *pd) ...@@ -203,6 +212,14 @@ static void activate_ch(struct sh_mobile_i2c_data *pd)
else else
pd->iccl = (u_int8_t)(num/denom); 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: /* 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 = i2c_clk * 4; num = i2c_clk * 4;
...@@ -212,6 +229,14 @@ static void activate_ch(struct sh_mobile_i2c_data *pd) ...@@ -212,6 +229,14 @@ static void activate_ch(struct sh_mobile_i2c_data *pd)
else else
pd->icch = (u_int8_t)(num/denom); 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 */ /* Enable channel and configure rx ack */
iic_set_clr(pd, ICCR, ICCR_ICE, 0); iic_set_clr(pd, ICCR, ICCR_ICE, 0);
...@@ -592,6 +617,12 @@ static int sh_mobile_i2c_probe(struct platform_device *dev) ...@@ -592,6 +617,12 @@ static int sh_mobile_i2c_probe(struct platform_device *dev)
goto err_irq; 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. /* Enable Runtime PM for this device.
* *
* Also tell the Runtime PM core to ignore children * Also tell the Runtime PM core to ignore children
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment