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

Commit d6668c7c authored by Sebastian Andrzej Siewior's avatar Sebastian Andrzej Siewior Committed by Ben Dooks
Browse files

i2c-pxa2xx: use dynamic register layout



This will prepare the driver to handle register layouts where certain
registers are not available at all.

Signed-off-by: default avatarSebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: default avatarBen Dooks <ben-linux@fluff.org>
parent a952baa0
Loading
Loading
Loading
Loading
+50 −20
Original line number Original line Diff line number Diff line
@@ -38,29 +38,49 @@
#include <asm/irq.h>
#include <asm/irq.h>
#include <plat/i2c.h>
#include <plat/i2c.h>


struct pxa_reg_layout {
	u32 ibmr;
	u32 idbr;
	u32 icr;
	u32 isr;
	u32 isar;
};

enum pxa_i2c_types {
	REGS_PXA2XX,
	REGS_PXA3XX,
};

/*
/*
 * I2C register offsets will be shifted 0 or 1 bit left, depending on
 * I2C registers definitions
 * different SoCs
 */
 */
#define REG_SHIFT_0	(0 << 0)
static struct pxa_reg_layout pxa_reg_layout[] = {
#define REG_SHIFT_1	(1 << 0)
	[REGS_PXA2XX] = {
#define REG_SHIFT(d)	((d) & 0x1)
		.ibmr =	0x00,
		.idbr =	0x10,
		.icr =	0x20,
		.isr =	0x30,
		.isar =	0x40,
	},
	[REGS_PXA3XX] = {
		.ibmr =	0x00,
		.idbr =	0x08,
		.icr =	0x10,
		.isr =	0x18,
		.isar =	0x20,
	},
};


static const struct platform_device_id i2c_pxa_id_table[] = {
static const struct platform_device_id i2c_pxa_id_table[] = {
	{ "pxa2xx-i2c",		REG_SHIFT_1 },
	{ "pxa2xx-i2c",		REGS_PXA2XX },
	{ "pxa3xx-pwri2c",	REG_SHIFT_0 },
	{ "pxa3xx-pwri2c",	REGS_PXA3XX },
	{ },
	{ },
};
};
MODULE_DEVICE_TABLE(platform, i2c_pxa_id_table);
MODULE_DEVICE_TABLE(platform, i2c_pxa_id_table);


/*
/*
 * I2C registers and bit definitions
 * I2C bit definitions
 */
 */
#define IBMR		(0x00)
#define IDBR		(0x08)
#define ICR		(0x10)
#define ISR		(0x18)
#define ISAR		(0x20)


#define ICR_START	(1 << 0)	   /* start bit */
#define ICR_START	(1 << 0)	   /* start bit */
#define ICR_STOP	(1 << 1)	   /* stop bit */
#define ICR_STOP	(1 << 1)	   /* stop bit */
@@ -111,7 +131,11 @@ struct pxa_i2c {
	u32			icrlog[32];
	u32			icrlog[32];


	void __iomem		*reg_base;
	void __iomem		*reg_base;
	unsigned int		reg_shift;
	void __iomem		*reg_ibmr;
	void __iomem		*reg_idbr;
	void __iomem		*reg_icr;
	void __iomem		*reg_isr;
	void __iomem		*reg_isar;


	unsigned long		iobase;
	unsigned long		iobase;
	unsigned long		iosize;
	unsigned long		iosize;
@@ -121,11 +145,11 @@ struct pxa_i2c {
	unsigned int		fast_mode :1;
	unsigned int		fast_mode :1;
};
};


#define _IBMR(i2c)	((i2c)->reg_base + (0x0 << (i2c)->reg_shift))
#define _IBMR(i2c)	((i2c)->reg_ibmr)
#define _IDBR(i2c)	((i2c)->reg_base + (0x4 << (i2c)->reg_shift))
#define _IDBR(i2c)	((i2c)->reg_idbr)
#define _ICR(i2c)	((i2c)->reg_base + (0x8 << (i2c)->reg_shift))
#define _ICR(i2c)	((i2c)->reg_icr)
#define _ISR(i2c)	((i2c)->reg_base + (0xc << (i2c)->reg_shift))
#define _ISR(i2c)	((i2c)->reg_isr)
#define _ISAR(i2c)	((i2c)->reg_base + (0x10 << (i2c)->reg_shift))
#define _ISAR(i2c)	((i2c)->reg_isar)


/*
/*
 * I2C Slave mode address
 * I2C Slave mode address
@@ -1001,6 +1025,7 @@ static int i2c_pxa_probe(struct platform_device *dev)
	struct resource *res;
	struct resource *res;
	struct i2c_pxa_platform_data *plat = dev->dev.platform_data;
	struct i2c_pxa_platform_data *plat = dev->dev.platform_data;
	const struct platform_device_id *id = platform_get_device_id(dev);
	const struct platform_device_id *id = platform_get_device_id(dev);
	enum pxa_i2c_types i2c_type = id->driver_data;
	int ret;
	int ret;
	int irq;
	int irq;


@@ -1044,7 +1069,12 @@ static int i2c_pxa_probe(struct platform_device *dev)
		ret = -EIO;
		ret = -EIO;
		goto eremap;
		goto eremap;
	}
	}
	i2c->reg_shift = REG_SHIFT(id->driver_data);

	i2c->reg_ibmr = i2c->reg_base + pxa_reg_layout[i2c_type].ibmr;
	i2c->reg_idbr = i2c->reg_base + pxa_reg_layout[i2c_type].idbr;
	i2c->reg_icr = i2c->reg_base + pxa_reg_layout[i2c_type].icr;
	i2c->reg_isr = i2c->reg_base + pxa_reg_layout[i2c_type].isr;
	i2c->reg_isar = i2c->reg_base + pxa_reg_layout[i2c_type].isar;


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