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>
This commit is contained in:
parent
12a55f2db7
commit
962b6032c8
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue