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); |