Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c5fa6fc7 authored by Vaibhav Hiremath's avatar Vaibhav Hiremath Committed by Wolfram Sang
Browse files

i2c: pxa: Add support for pxa910/988 & new configuration features



TWSI_ILCR & TWSI_IWCR registers are used to adjust clock rate
of standard & fast mode in pxa910/988; so this patch adds these two new
entries to "struct pxa_reg_layout" and "struct pxa_i2c".

Signed-off-by: default avatarJett.Zhou <jtzhou@marvell.com>
Signed-off-by: default avatarYi Zhang <yizhang@marvell.com>
Signed-off-by: default avatarVaibhav Hiremath <vaibhav.hiremath@linaro.org>
Tested-by: default avatarRobert Jarzmik <robert.jarzmik@free.fr>
[wsa: white space fixes]
Signed-off-by: default avatarWolfram Sang <wsa@the-dreams.de>
parent 174f2366
Loading
Loading
Loading
Loading
+40 −1
Original line number Diff line number Diff line
@@ -46,12 +46,15 @@ struct pxa_reg_layout {
	u32 icr;
	u32 isr;
	u32 isar;
	u32 ilcr;
	u32 iwcr;
};

enum pxa_i2c_types {
	REGS_PXA2XX,
	REGS_PXA3XX,
	REGS_CE4100,
	REGS_PXA910,
};

/*
@@ -79,12 +82,22 @@ static struct pxa_reg_layout pxa_reg_layout[] = {
		.isr =	0x04,
		/* no isar register */
	},
	[REGS_PXA910] = {
		.ibmr = 0x00,
		.idbr = 0x08,
		.icr =	0x10,
		.isr =	0x18,
		.isar = 0x20,
		.ilcr = 0x28,
		.iwcr = 0x30,
	},
};

static const struct platform_device_id i2c_pxa_id_table[] = {
	{ "pxa2xx-i2c",		REGS_PXA2XX },
	{ "pxa3xx-pwri2c",	REGS_PXA3XX },
	{ "ce4100-i2c",		REGS_CE4100 },
	{ "pxa910-i2c",		REGS_PXA910 },
	{ },
};
MODULE_DEVICE_TABLE(platform, i2c_pxa_id_table);
@@ -124,6 +137,23 @@ MODULE_DEVICE_TABLE(platform, i2c_pxa_id_table);
#define ISR_SAD		(1 << 9)	   /* slave address detected */
#define ISR_BED		(1 << 10)	   /* bus error no ACK/NAK */

/* bit field shift & mask */
#define ILCR_SLV_SHIFT		0
#define ILCR_SLV_MASK		(0x1FF << ILCR_SLV_SHIFT)
#define ILCR_FLV_SHIFT		9
#define ILCR_FLV_MASK		(0x1FF << ILCR_FLV_SHIFT)
#define ILCR_HLVL_SHIFT		18
#define ILCR_HLVL_MASK		(0x1FF << ILCR_HLVL_SHIFT)
#define ILCR_HLVH_SHIFT		27
#define ILCR_HLVH_MASK		(0x1F << ILCR_HLVH_SHIFT)

#define IWCR_CNT_SHIFT		0
#define IWCR_CNT_MASK		(0x1F << IWCR_CNT_SHIFT)
#define IWCR_HS_CNT1_SHIFT	5
#define IWCR_HS_CNT1_MASK	(0x1F << IWCR_HS_CNT1_SHIFT)
#define IWCR_HS_CNT2_SHIFT	10
#define IWCR_HS_CNT2_MASK	(0x1F << IWCR_HS_CNT2_SHIFT)

struct pxa_i2c {
	spinlock_t		lock;
	wait_queue_head_t	wait;
@@ -150,6 +180,8 @@ struct pxa_i2c {
	void __iomem		*reg_icr;
	void __iomem		*reg_isr;
	void __iomem		*reg_isar;
	void __iomem		*reg_ilcr;
	void __iomem		*reg_iwcr;

	unsigned long		iobase;
	unsigned long		iosize;
@@ -168,6 +200,8 @@ struct pxa_i2c {
#define _ICR(i2c)	((i2c)->reg_icr)
#define _ISR(i2c)	((i2c)->reg_isr)
#define _ISAR(i2c)	((i2c)->reg_isar)
#define _ILCR(i2c)	((i2c)->reg_ilcr)
#define _IWCR(i2c)	((i2c)->reg_iwcr)

/*
 * I2C Slave mode address
@@ -1102,7 +1136,7 @@ static const struct i2c_algorithm i2c_pxa_pio_algorithm = {
static const struct of_device_id i2c_pxa_dt_ids[] = {
	{ .compatible = "mrvl,pxa-i2c", .data = (void *)REGS_PXA2XX },
	{ .compatible = "mrvl,pwri2c", .data = (void *)REGS_PXA3XX },
	{ .compatible = "mrvl,mmp-twsi", .data = (void *)REGS_PXA2XX },
	{ .compatible = "mrvl,mmp-twsi", .data = (void *)REGS_PXA910 },
	{}
};
MODULE_DEVICE_TABLE(of, i2c_pxa_dt_ids);
@@ -1203,6 +1237,11 @@ static int i2c_pxa_probe(struct platform_device *dev)
	if (i2c_type != REGS_CE4100)
		i2c->reg_isar = i2c->reg_base + pxa_reg_layout[i2c_type].isar;

	if (i2c_type == REGS_PXA910) {
		i2c->reg_ilcr = i2c->reg_base + pxa_reg_layout[i2c_type].ilcr;
		i2c->reg_iwcr = i2c->reg_base + pxa_reg_layout[i2c_type].iwcr;
	}

	i2c->iobase = res->start;
	i2c->iosize = resource_size(res);