aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/i2c')
-rw-r--r--drivers/i2c/busses/i2c-omap.c146
1 files changed, 114 insertions, 32 deletions
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 389ac6032a7b..46111ff18133 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -45,29 +45,37 @@
45/* I2C controller revisions present on specific hardware */ 45/* I2C controller revisions present on specific hardware */
46#define OMAP_I2C_REV_ON_2430 0x36 46#define OMAP_I2C_REV_ON_2430 0x36
47#define OMAP_I2C_REV_ON_3430 0x3C 47#define OMAP_I2C_REV_ON_3430 0x3C
48#define OMAP_I2C_REV_ON_4430 0x40
48 49
49/* timeout waiting for the controller to respond */ 50/* timeout waiting for the controller to respond */
50#define OMAP_I2C_TIMEOUT (msecs_to_jiffies(1000)) 51#define OMAP_I2C_TIMEOUT (msecs_to_jiffies(1000))
51 52
52#define OMAP_I2C_REV_REG 0x00
53#define OMAP_I2C_IE_REG 0x01
54#define OMAP_I2C_STAT_REG 0x02
55#define OMAP_I2C_IV_REG 0x03
56/* For OMAP3 I2C_IV has changed to I2C_WE (wakeup enable) */ 53/* For OMAP3 I2C_IV has changed to I2C_WE (wakeup enable) */
57#define OMAP_I2C_WE_REG 0x03 54enum {
58#define OMAP_I2C_SYSS_REG 0x04 55 OMAP_I2C_REV_REG = 0,
59#define OMAP_I2C_BUF_REG 0x05 56 OMAP_I2C_IE_REG,
60#define OMAP_I2C_CNT_REG 0x06 57 OMAP_I2C_STAT_REG,
61#define OMAP_I2C_DATA_REG 0x07 58 OMAP_I2C_IV_REG,
62#define OMAP_I2C_SYSC_REG 0x08 59 OMAP_I2C_WE_REG,
63#define OMAP_I2C_CON_REG 0x09 60 OMAP_I2C_SYSS_REG,
64#define OMAP_I2C_OA_REG 0x0a 61 OMAP_I2C_BUF_REG,
65#define OMAP_I2C_SA_REG 0x0b 62 OMAP_I2C_CNT_REG,
66#define OMAP_I2C_PSC_REG 0x0c 63 OMAP_I2C_DATA_REG,
67#define OMAP_I2C_SCLL_REG 0x0d 64 OMAP_I2C_SYSC_REG,
68#define OMAP_I2C_SCLH_REG 0x0e 65 OMAP_I2C_CON_REG,
69#define OMAP_I2C_SYSTEST_REG 0x0f 66 OMAP_I2C_OA_REG,
70#define OMAP_I2C_BUFSTAT_REG 0x10 67 OMAP_I2C_SA_REG,
68 OMAP_I2C_PSC_REG,
69 OMAP_I2C_SCLL_REG,
70 OMAP_I2C_SCLH_REG,
71 OMAP_I2C_SYSTEST_REG,
72 OMAP_I2C_BUFSTAT_REG,
73 OMAP_I2C_REVNB_LO,
74 OMAP_I2C_REVNB_HI,
75 OMAP_I2C_IRQSTATUS_RAW,
76 OMAP_I2C_IRQENABLE_SET,
77 OMAP_I2C_IRQENABLE_CLR,
78};
71 79
72/* I2C Interrupt Enable Register (OMAP_I2C_IE): */ 80/* I2C Interrupt Enable Register (OMAP_I2C_IE): */
73#define OMAP_I2C_IE_XDR (1 << 14) /* TX Buffer drain int enable */ 81#define OMAP_I2C_IE_XDR (1 << 14) /* TX Buffer drain int enable */
@@ -170,6 +178,7 @@ struct omap_i2c_dev {
170 u32 speed; /* Speed of bus in Khz */ 178 u32 speed; /* Speed of bus in Khz */
171 u16 cmd_err; 179 u16 cmd_err;
172 u8 *buf; 180 u8 *buf;
181 u8 *regs;
173 size_t buf_len; 182 size_t buf_len;
174 struct i2c_adapter adapter; 183 struct i2c_adapter adapter;
175 u8 fifo_size; /* use as flag and value 184 u8 fifo_size; /* use as flag and value
@@ -188,15 +197,64 @@ struct omap_i2c_dev {
188 u16 westate; 197 u16 westate;
189}; 198};
190 199
200const static u8 reg_map[] = {
201 [OMAP_I2C_REV_REG] = 0x00,
202 [OMAP_I2C_IE_REG] = 0x01,
203 [OMAP_I2C_STAT_REG] = 0x02,
204 [OMAP_I2C_IV_REG] = 0x03,
205 [OMAP_I2C_WE_REG] = 0x03,
206 [OMAP_I2C_SYSS_REG] = 0x04,
207 [OMAP_I2C_BUF_REG] = 0x05,
208 [OMAP_I2C_CNT_REG] = 0x06,
209 [OMAP_I2C_DATA_REG] = 0x07,
210 [OMAP_I2C_SYSC_REG] = 0x08,
211 [OMAP_I2C_CON_REG] = 0x09,
212 [OMAP_I2C_OA_REG] = 0x0a,
213 [OMAP_I2C_SA_REG] = 0x0b,
214 [OMAP_I2C_PSC_REG] = 0x0c,
215 [OMAP_I2C_SCLL_REG] = 0x0d,
216 [OMAP_I2C_SCLH_REG] = 0x0e,
217 [OMAP_I2C_SYSTEST_REG] = 0x0f,
218 [OMAP_I2C_BUFSTAT_REG] = 0x10,
219};
220
221const static u8 omap4_reg_map[] = {
222 [OMAP_I2C_REV_REG] = 0x04,
223 [OMAP_I2C_IE_REG] = 0x2c,
224 [OMAP_I2C_STAT_REG] = 0x28,
225 [OMAP_I2C_IV_REG] = 0x34,
226 [OMAP_I2C_WE_REG] = 0x34,
227 [OMAP_I2C_SYSS_REG] = 0x90,
228 [OMAP_I2C_BUF_REG] = 0x94,
229 [OMAP_I2C_CNT_REG] = 0x98,
230 [OMAP_I2C_DATA_REG] = 0x9c,
231 [OMAP_I2C_SYSC_REG] = 0x20,
232 [OMAP_I2C_CON_REG] = 0xa4,
233 [OMAP_I2C_OA_REG] = 0xa8,
234 [OMAP_I2C_SA_REG] = 0xac,
235 [OMAP_I2C_PSC_REG] = 0xb0,
236 [OMAP_I2C_SCLL_REG] = 0xb4,
237 [OMAP_I2C_SCLH_REG] = 0xb8,
238 [OMAP_I2C_SYSTEST_REG] = 0xbC,
239 [OMAP_I2C_BUFSTAT_REG] = 0xc0,
240 [OMAP_I2C_REVNB_LO] = 0x00,
241 [OMAP_I2C_REVNB_HI] = 0x04,
242 [OMAP_I2C_IRQSTATUS_RAW] = 0x24,
243 [OMAP_I2C_IRQENABLE_SET] = 0x2c,
244 [OMAP_I2C_IRQENABLE_CLR] = 0x30,
245};
246
191static inline void omap_i2c_write_reg(struct omap_i2c_dev *i2c_dev, 247static inline void omap_i2c_write_reg(struct omap_i2c_dev *i2c_dev,
192 int reg, u16 val) 248 int reg, u16 val)
193{ 249{
194 __raw_writew(val, i2c_dev->base + (reg << i2c_dev->reg_shift)); 250 __raw_writew(val, i2c_dev->base +
251 (i2c_dev->regs[reg] << i2c_dev->reg_shift));
195} 252}
196 253
197static inline u16 omap_i2c_read_reg(struct omap_i2c_dev *i2c_dev, int reg) 254static inline u16 omap_i2c_read_reg(struct omap_i2c_dev *i2c_dev, int reg)
198{ 255{
199 return __raw_readw(i2c_dev->base + (reg << i2c_dev->reg_shift)); 256 return __raw_readw(i2c_dev->base +
257 (i2c_dev->regs[reg] << i2c_dev->reg_shift));
200} 258}
201 259
202static int __init omap_i2c_get_clocks(struct omap_i2c_dev *dev) 260static int __init omap_i2c_get_clocks(struct omap_i2c_dev *dev)
@@ -265,7 +323,11 @@ static void omap_i2c_idle(struct omap_i2c_dev *dev)
265 WARN_ON(dev->idle); 323 WARN_ON(dev->idle);
266 324
267 dev->iestate = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG); 325 dev->iestate = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG);
268 omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, 0); 326 if (dev->rev >= OMAP_I2C_REV_ON_4430)
327 omap_i2c_write_reg(dev, OMAP_I2C_IRQENABLE_CLR, 1);
328 else
329 omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, 0);
330
269 if (dev->rev < OMAP_I2C_REV_2) { 331 if (dev->rev < OMAP_I2C_REV_2) {
270 iv = omap_i2c_read_reg(dev, OMAP_I2C_IV_REG); /* Read clears */ 332 iv = omap_i2c_read_reg(dev, OMAP_I2C_IV_REG); /* Read clears */
271 } else { 333 } else {
@@ -330,7 +392,9 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)
330 * REVISIT: Some wkup sources might not be needed. 392 * REVISIT: Some wkup sources might not be needed.
331 */ 393 */
332 dev->westate = OMAP_I2C_WE_ALL; 394 dev->westate = OMAP_I2C_WE_ALL;
333 omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, dev->westate); 395 if (dev->rev < OMAP_I2C_REV_ON_4430)
396 omap_i2c_write_reg(dev, OMAP_I2C_WE_REG,
397 dev->westate);
334 } 398 }
335 } 399 }
336 omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); 400 omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
@@ -357,7 +421,7 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)
357 psc = fclk_rate / 12000000; 421 psc = fclk_rate / 12000000;
358 } 422 }
359 423
360 if (cpu_is_omap2430() || cpu_is_omap34xx()) { 424 if (!(cpu_class_is_omap1() || cpu_is_omap2420())) {
361 425
362 /* 426 /*
363 * HSI2C controller internal clk rate should be 19.2 Mhz for 427 * HSI2C controller internal clk rate should be 19.2 Mhz for
@@ -747,9 +811,12 @@ complete:
747 if (dev->buf_len) { 811 if (dev->buf_len) {
748 *dev->buf++ = w; 812 *dev->buf++ = w;
749 dev->buf_len--; 813 dev->buf_len--;
750 /* Data reg from 2430 is 8 bit wide */ 814 /*
751 if (!cpu_is_omap2430() && 815 * Data reg in 2430, omap3 and
752 !cpu_is_omap34xx()) { 816 * omap4 is 8 bit wide
817 */
818 if (cpu_class_is_omap1() ||
819 cpu_is_omap2420()) {
753 if (dev->buf_len) { 820 if (dev->buf_len) {
754 *dev->buf++ = w >> 8; 821 *dev->buf++ = w >> 8;
755 dev->buf_len--; 822 dev->buf_len--;
@@ -787,9 +854,12 @@ complete:
787 if (dev->buf_len) { 854 if (dev->buf_len) {
788 w = *dev->buf++; 855 w = *dev->buf++;
789 dev->buf_len--; 856 dev->buf_len--;
790 /* Data reg from 2430 is 8 bit wide */ 857 /*
791 if (!cpu_is_omap2430() && 858 * Data reg in 2430, omap3 and
792 !cpu_is_omap34xx()) { 859 * omap4 is 8 bit wide
860 */
861 if (cpu_class_is_omap1() ||
862 cpu_is_omap2420()) {
793 if (dev->buf_len) { 863 if (dev->buf_len) {
794 w |= *dev->buf++ << 8; 864 w |= *dev->buf++ << 8;
795 dev->buf_len--; 865 dev->buf_len--;
@@ -905,17 +975,24 @@ omap_i2c_probe(struct platform_device *pdev)
905 975
906 if (cpu_is_omap7xx()) 976 if (cpu_is_omap7xx())
907 dev->reg_shift = 1; 977 dev->reg_shift = 1;
978 else if (cpu_is_omap44xx())
979 dev->reg_shift = 0;
908 else 980 else
909 dev->reg_shift = 2; 981 dev->reg_shift = 2;
910 982
911 if ((r = omap_i2c_get_clocks(dev)) != 0) 983 if ((r = omap_i2c_get_clocks(dev)) != 0)
912 goto err_iounmap; 984 goto err_iounmap;
913 985
986 if (cpu_is_omap44xx())
987 dev->regs = (u8 *) omap4_reg_map;
988 else
989 dev->regs = (u8 *) reg_map;
990
914 omap_i2c_unidle(dev); 991 omap_i2c_unidle(dev);
915 992
916 dev->rev = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG) & 0xff; 993 dev->rev = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG) & 0xff;
917 994
918 if (cpu_is_omap2430() || cpu_is_omap34xx()) { 995 if (!(cpu_class_is_omap1() || cpu_is_omap2420())) {
919 u16 s; 996 u16 s;
920 997
921 /* Set up the fifo size - Get total size */ 998 /* Set up the fifo size - Get total size */
@@ -927,8 +1004,13 @@ omap_i2c_probe(struct platform_device *pdev)
927 * size. This is to ensure that we can handle the status on int 1004 * size. This is to ensure that we can handle the status on int
928 * call back latencies. 1005 * call back latencies.
929 */ 1006 */
930 dev->fifo_size = (dev->fifo_size / 2); 1007 if (dev->rev >= OMAP_I2C_REV_ON_4430) {
931 dev->b_hw = 1; /* Enable hardware fixes */ 1008 dev->fifo_size = 0;
1009 dev->b_hw = 0; /* Disable hardware fixes */
1010 } else {
1011 dev->fifo_size = (dev->fifo_size / 2);
1012 dev->b_hw = 1; /* Enable hardware fixes */
1013 }
932 } 1014 }
933 1015
934 /* reset ASAP, clearing any IRQs */ 1016 /* reset ASAP, clearing any IRQs */