提交 d6668c7c 编写于 作者: S Sebastian Andrzej Siewior 提交者: Ben Dooks

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: NSebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: NBen Dooks <ben-linux@fluff.org>
上级 a952baa0
...@@ -38,29 +38,49 @@ ...@@ -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 { ...@@ -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 { ...@@ -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) ...@@ -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) ...@@ -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);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册