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

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
Loading
Loading
Loading
Loading
+31 −0
Original line number Diff line number Diff line
@@ -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