diff options
| author | Sebastian Andrzej Siewior <bigeasy@linutronix.de> | 2011-02-23 06:38:15 -0500 |
|---|---|---|
| committer | Ben Dooks <ben-linux@fluff.org> | 2011-03-21 05:09:31 -0400 |
| commit | d6668c7cd4defdab1a74c8dd271b5ca23d99b627 (patch) | |
| tree | c281fa99b62ecd6ca9a2960c476c7a691c6d544b /drivers/i2c | |
| parent | a952baa034ae7c2e4a66932005cbc7ebbccfe28d (diff) | |
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: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Ben Dooks <ben-linux@fluff.org>
Diffstat (limited to 'drivers/i2c')
| -rw-r--r-- | drivers/i2c/busses/i2c-pxa.c | 70 |
1 files changed, 50 insertions, 20 deletions
diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c index f4c19a97e0b3..a011455650e9 100644 --- a/drivers/i2c/busses/i2c-pxa.c +++ b/drivers/i2c/busses/i2c-pxa.c | |||
| @@ -38,29 +38,49 @@ | |||
| 38 | #include <asm/irq.h> | 38 | #include <asm/irq.h> |
| 39 | #include <plat/i2c.h> | 39 | #include <plat/i2c.h> |
| 40 | 40 | ||
| 41 | struct pxa_reg_layout { | ||
| 42 | u32 ibmr; | ||
| 43 | u32 idbr; | ||
| 44 | u32 icr; | ||
| 45 | u32 isr; | ||
| 46 | u32 isar; | ||
| 47 | }; | ||
| 48 | |||
| 49 | enum pxa_i2c_types { | ||
| 50 | REGS_PXA2XX, | ||
| 51 | REGS_PXA3XX, | ||
| 52 | }; | ||
| 53 | |||
| 41 | /* | 54 | /* |
| 42 | * I2C register offsets will be shifted 0 or 1 bit left, depending on | 55 | * I2C registers definitions |
| 43 | * different SoCs | ||
| 44 | */ | 56 | */ |
| 45 | #define REG_SHIFT_0 (0 << 0) | 57 | static struct pxa_reg_layout pxa_reg_layout[] = { |
| 46 | #define REG_SHIFT_1 (1 << 0) | 58 | [REGS_PXA2XX] = { |
| 47 | #define REG_SHIFT(d) ((d) & 0x1) | 59 | .ibmr = 0x00, |
| 60 | .idbr = 0x10, | ||
| 61 | .icr = 0x20, | ||
| 62 | .isr = 0x30, | ||
| 63 | .isar = 0x40, | ||
| 64 | }, | ||
| 65 | [REGS_PXA3XX] = { | ||
| 66 | .ibmr = 0x00, | ||
| 67 | .idbr = 0x08, | ||
| 68 | .icr = 0x10, | ||
| 69 | .isr = 0x18, | ||
| 70 | .isar = 0x20, | ||
| 71 | }, | ||
| 72 | }; | ||
| 48 | 73 | ||
| 49 | static const struct platform_device_id i2c_pxa_id_table[] = { | 74 | static const struct platform_device_id i2c_pxa_id_table[] = { |
| 50 | { "pxa2xx-i2c", REG_SHIFT_1 }, | 75 | { "pxa2xx-i2c", REGS_PXA2XX }, |
| 51 | { "pxa3xx-pwri2c", REG_SHIFT_0 }, | 76 | { "pxa3xx-pwri2c", REGS_PXA3XX }, |
| 52 | { }, | 77 | { }, |
| 53 | }; | 78 | }; |
| 54 | MODULE_DEVICE_TABLE(platform, i2c_pxa_id_table); | 79 | MODULE_DEVICE_TABLE(platform, i2c_pxa_id_table); |
| 55 | 80 | ||
| 56 | /* | 81 | /* |
| 57 | * I2C registers and bit definitions | 82 | * I2C bit definitions |
| 58 | */ | 83 | */ |
| 59 | #define IBMR (0x00) | ||
| 60 | #define IDBR (0x08) | ||
| 61 | #define ICR (0x10) | ||
| 62 | #define ISR (0x18) | ||
| 63 | #define ISAR (0x20) | ||
| 64 | 84 | ||
| 65 | #define ICR_START (1 << 0) /* start bit */ | 85 | #define ICR_START (1 << 0) /* start bit */ |
| 66 | #define ICR_STOP (1 << 1) /* stop bit */ | 86 | #define ICR_STOP (1 << 1) /* stop bit */ |
| @@ -111,7 +131,11 @@ struct pxa_i2c { | |||
| 111 | u32 icrlog[32]; | 131 | u32 icrlog[32]; |
| 112 | 132 | ||
| 113 | void __iomem *reg_base; | 133 | void __iomem *reg_base; |
| 114 | unsigned int reg_shift; | 134 | void __iomem *reg_ibmr; |
| 135 | void __iomem *reg_idbr; | ||
| 136 | void __iomem *reg_icr; | ||
| 137 | void __iomem *reg_isr; | ||
| 138 | void __iomem *reg_isar; | ||
| 115 | 139 | ||
| 116 | unsigned long iobase; | 140 | unsigned long iobase; |
| 117 | unsigned long iosize; | 141 | unsigned long iosize; |
| @@ -121,11 +145,11 @@ struct pxa_i2c { | |||
| 121 | unsigned int fast_mode :1; | 145 | unsigned int fast_mode :1; |
| 122 | }; | 146 | }; |
| 123 | 147 | ||
| 124 | #define _IBMR(i2c) ((i2c)->reg_base + (0x0 << (i2c)->reg_shift)) | 148 | #define _IBMR(i2c) ((i2c)->reg_ibmr) |
| 125 | #define _IDBR(i2c) ((i2c)->reg_base + (0x4 << (i2c)->reg_shift)) | 149 | #define _IDBR(i2c) ((i2c)->reg_idbr) |
| 126 | #define _ICR(i2c) ((i2c)->reg_base + (0x8 << (i2c)->reg_shift)) | 150 | #define _ICR(i2c) ((i2c)->reg_icr) |
| 127 | #define _ISR(i2c) ((i2c)->reg_base + (0xc << (i2c)->reg_shift)) | 151 | #define _ISR(i2c) ((i2c)->reg_isr) |
| 128 | #define _ISAR(i2c) ((i2c)->reg_base + (0x10 << (i2c)->reg_shift)) | 152 | #define _ISAR(i2c) ((i2c)->reg_isar) |
| 129 | 153 | ||
| 130 | /* | 154 | /* |
| 131 | * I2C Slave mode address | 155 | * I2C Slave mode address |
| @@ -1001,6 +1025,7 @@ static int i2c_pxa_probe(struct platform_device *dev) | |||
| 1001 | struct resource *res; | 1025 | struct resource *res; |
| 1002 | struct i2c_pxa_platform_data *plat = dev->dev.platform_data; | 1026 | struct i2c_pxa_platform_data *plat = dev->dev.platform_data; |
| 1003 | const struct platform_device_id *id = platform_get_device_id(dev); | 1027 | const struct platform_device_id *id = platform_get_device_id(dev); |
| 1028 | enum pxa_i2c_types i2c_type = id->driver_data; | ||
| 1004 | int ret; | 1029 | int ret; |
| 1005 | int irq; | 1030 | int irq; |
| 1006 | 1031 | ||
| @@ -1044,7 +1069,12 @@ static int i2c_pxa_probe(struct platform_device *dev) | |||
| 1044 | ret = -EIO; | 1069 | ret = -EIO; |
| 1045 | goto eremap; | 1070 | goto eremap; |
| 1046 | } | 1071 | } |
| 1047 | i2c->reg_shift = REG_SHIFT(id->driver_data); | 1072 | |
| 1073 | i2c->reg_ibmr = i2c->reg_base + pxa_reg_layout[i2c_type].ibmr; | ||
| 1074 | i2c->reg_idbr = i2c->reg_base + pxa_reg_layout[i2c_type].idbr; | ||
| 1075 | i2c->reg_icr = i2c->reg_base + pxa_reg_layout[i2c_type].icr; | ||
| 1076 | i2c->reg_isr = i2c->reg_base + pxa_reg_layout[i2c_type].isr; | ||
| 1077 | i2c->reg_isar = i2c->reg_base + pxa_reg_layout[i2c_type].isar; | ||
| 1048 | 1078 | ||
| 1049 | i2c->iobase = res->start; | 1079 | i2c->iobase = res->start; |
| 1050 | i2c->iosize = resource_size(res); | 1080 | i2c->iosize = resource_size(res); |
