diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-11 13:09:45 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-11 13:09:45 -0400 |
commit | 7cc4e87f912bbefa440a51856b8d076e5d1f554a (patch) | |
tree | 1b8df8683f3de37d2e8211ffa8d151f60d59af62 /drivers/i2c | |
parent | 5ba2f67afb02c5302b2898949ed6fc3b3d37dcf1 (diff) | |
parent | 69fc7eed5f56bce15b239e5110de2575a6970df4 (diff) |
Merge branch 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm
* 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm: (236 commits)
[ARM] 5300/1: fixup spitz reset during boot
[ARM] 5295/1: make ZONE_DMA optional
[ARM] 5239/1: Palm Zire 72 power management support
[ARM] 5298/1: Drop desc_handle_irq()
[ARM] 5297/1: [KS8695] Fix two compile-time warnings
[ARM] 5296/1: [KS8695] Replace macro's with trailing underscores.
[ARM] pxa: allow multi-machine PCMCIA builds
[ARM] pxa: add preliminary CPUFREQ support for PXA3xx
[ARM] pxa: add missing ACCR bit definitions to pxa3xx-regs.h
[ARM] pxa: rename cpu-pxa.c to cpufreq-pxa2xx.c
[ARM] pxa/zylonite: add support for USB OHCI
[ARM] ohci-pxa27x: use ioremap() and offset for register access
[ARM] ohci-pxa27x: introduce pxa27x_clear_otgph()
[ARM] ohci-pxa27x: use platform_get_{irq,resource} for the resource
[ARM] ohci-pxa27x: move OHCI controller specific registers into the driver
[ARM] ohci-pxa27x: introduce flags to avoid direct access to OHCI registers
[ARM] pxa: move I2S register and bit definitions into pxa2xx-i2s.c
[ARM] pxa: simplify DMA register definitions
[ARM] pxa: make additional DCSR bits valid for PXA3xx
[ARM] pxa: move i2c register and bit definitions into i2c-pxa.c
...
Fixed up conflicts in
arch/arm/mach-versatile/core.c
sound/soc/pxa/pxa2xx-ac97.c
sound/soc/pxa/pxa2xx-i2s.c
manually.
Diffstat (limited to 'drivers/i2c')
-rw-r--r-- | drivers/i2c/busses/i2c-pxa.c | 94 |
1 files changed, 77 insertions, 17 deletions
diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c index 44d838410f15..906f9b9d715d 100644 --- a/drivers/i2c/busses/i2c-pxa.c +++ b/drivers/i2c/busses/i2c-pxa.c | |||
@@ -38,7 +38,44 @@ | |||
38 | #include <asm/irq.h> | 38 | #include <asm/irq.h> |
39 | #include <asm/io.h> | 39 | #include <asm/io.h> |
40 | #include <mach/i2c.h> | 40 | #include <mach/i2c.h> |
41 | #include <mach/pxa-regs.h> | 41 | |
42 | /* | ||
43 | * I2C registers and bit definitions | ||
44 | */ | ||
45 | #define IBMR (0x00) | ||
46 | #define IDBR (0x08) | ||
47 | #define ICR (0x10) | ||
48 | #define ISR (0x18) | ||
49 | #define ISAR (0x20) | ||
50 | |||
51 | #define ICR_START (1 << 0) /* start bit */ | ||
52 | #define ICR_STOP (1 << 1) /* stop bit */ | ||
53 | #define ICR_ACKNAK (1 << 2) /* send ACK(0) or NAK(1) */ | ||
54 | #define ICR_TB (1 << 3) /* transfer byte bit */ | ||
55 | #define ICR_MA (1 << 4) /* master abort */ | ||
56 | #define ICR_SCLE (1 << 5) /* master clock enable */ | ||
57 | #define ICR_IUE (1 << 6) /* unit enable */ | ||
58 | #define ICR_GCD (1 << 7) /* general call disable */ | ||
59 | #define ICR_ITEIE (1 << 8) /* enable tx interrupts */ | ||
60 | #define ICR_IRFIE (1 << 9) /* enable rx interrupts */ | ||
61 | #define ICR_BEIE (1 << 10) /* enable bus error ints */ | ||
62 | #define ICR_SSDIE (1 << 11) /* slave STOP detected int enable */ | ||
63 | #define ICR_ALDIE (1 << 12) /* enable arbitration interrupt */ | ||
64 | #define ICR_SADIE (1 << 13) /* slave address detected int enable */ | ||
65 | #define ICR_UR (1 << 14) /* unit reset */ | ||
66 | #define ICR_FM (1 << 15) /* fast mode */ | ||
67 | |||
68 | #define ISR_RWM (1 << 0) /* read/write mode */ | ||
69 | #define ISR_ACKNAK (1 << 1) /* ack/nak status */ | ||
70 | #define ISR_UB (1 << 2) /* unit busy */ | ||
71 | #define ISR_IBB (1 << 3) /* bus busy */ | ||
72 | #define ISR_SSD (1 << 4) /* slave stop detected */ | ||
73 | #define ISR_ALD (1 << 5) /* arbitration loss detected */ | ||
74 | #define ISR_ITE (1 << 6) /* tx buffer empty */ | ||
75 | #define ISR_IRF (1 << 7) /* rx buffer full */ | ||
76 | #define ISR_GCAD (1 << 8) /* general call address detected */ | ||
77 | #define ISR_SAD (1 << 9) /* slave address detected */ | ||
78 | #define ISR_BED (1 << 10) /* bus error no ACK/NAK */ | ||
42 | 79 | ||
43 | struct pxa_i2c { | 80 | struct pxa_i2c { |
44 | spinlock_t lock; | 81 | spinlock_t lock; |
@@ -60,19 +97,21 @@ struct pxa_i2c { | |||
60 | u32 icrlog[32]; | 97 | u32 icrlog[32]; |
61 | 98 | ||
62 | void __iomem *reg_base; | 99 | void __iomem *reg_base; |
100 | unsigned int reg_shift; | ||
63 | 101 | ||
64 | unsigned long iobase; | 102 | unsigned long iobase; |
65 | unsigned long iosize; | 103 | unsigned long iosize; |
66 | 104 | ||
67 | int irq; | 105 | int irq; |
68 | int use_pio; | 106 | unsigned int use_pio :1; |
107 | unsigned int fast_mode :1; | ||
69 | }; | 108 | }; |
70 | 109 | ||
71 | #define _IBMR(i2c) ((i2c)->reg_base + 0) | 110 | #define _IBMR(i2c) ((i2c)->reg_base + (0x0 << (i2c)->reg_shift)) |
72 | #define _IDBR(i2c) ((i2c)->reg_base + 8) | 111 | #define _IDBR(i2c) ((i2c)->reg_base + (0x4 << (i2c)->reg_shift)) |
73 | #define _ICR(i2c) ((i2c)->reg_base + 0x10) | 112 | #define _ICR(i2c) ((i2c)->reg_base + (0x8 << (i2c)->reg_shift)) |
74 | #define _ISR(i2c) ((i2c)->reg_base + 0x18) | 113 | #define _ISR(i2c) ((i2c)->reg_base + (0xc << (i2c)->reg_shift)) |
75 | #define _ISAR(i2c) ((i2c)->reg_base + 0x20) | 114 | #define _ISAR(i2c) ((i2c)->reg_base + (0x10 << (i2c)->reg_shift)) |
76 | 115 | ||
77 | /* | 116 | /* |
78 | * I2C Slave mode address | 117 | * I2C Slave mode address |
@@ -188,14 +227,14 @@ static inline int i2c_pxa_is_slavemode(struct pxa_i2c *i2c) | |||
188 | 227 | ||
189 | static void i2c_pxa_abort(struct pxa_i2c *i2c) | 228 | static void i2c_pxa_abort(struct pxa_i2c *i2c) |
190 | { | 229 | { |
191 | unsigned long timeout = jiffies + HZ/4; | 230 | int i = 250; |
192 | 231 | ||
193 | if (i2c_pxa_is_slavemode(i2c)) { | 232 | if (i2c_pxa_is_slavemode(i2c)) { |
194 | dev_dbg(&i2c->adap.dev, "%s: called in slave mode\n", __func__); | 233 | dev_dbg(&i2c->adap.dev, "%s: called in slave mode\n", __func__); |
195 | return; | 234 | return; |
196 | } | 235 | } |
197 | 236 | ||
198 | while (time_before(jiffies, timeout) && (readl(_IBMR(i2c)) & 0x1) == 0) { | 237 | while ((i > 0) && (readl(_IBMR(i2c)) & 0x1) == 0) { |
199 | unsigned long icr = readl(_ICR(i2c)); | 238 | unsigned long icr = readl(_ICR(i2c)); |
200 | 239 | ||
201 | icr &= ~ICR_START; | 240 | icr &= ~ICR_START; |
@@ -205,7 +244,8 @@ static void i2c_pxa_abort(struct pxa_i2c *i2c) | |||
205 | 244 | ||
206 | show_state(i2c); | 245 | show_state(i2c); |
207 | 246 | ||
208 | msleep(1); | 247 | mdelay(1); |
248 | i --; | ||
209 | } | 249 | } |
210 | 250 | ||
211 | writel(readl(_ICR(i2c)) & ~(ICR_MA | ICR_START | ICR_STOP), | 251 | writel(readl(_ICR(i2c)) & ~(ICR_MA | ICR_START | ICR_STOP), |
@@ -364,7 +404,7 @@ static void i2c_pxa_reset(struct pxa_i2c *i2c) | |||
364 | writel(i2c->slave_addr, _ISAR(i2c)); | 404 | writel(i2c->slave_addr, _ISAR(i2c)); |
365 | 405 | ||
366 | /* set control register values */ | 406 | /* set control register values */ |
367 | writel(I2C_ICR_INIT, _ICR(i2c)); | 407 | writel(I2C_ICR_INIT | (i2c->fast_mode ? ICR_FM : 0), _ICR(i2c)); |
368 | 408 | ||
369 | #ifdef CONFIG_I2C_PXA_SLAVE | 409 | #ifdef CONFIG_I2C_PXA_SLAVE |
370 | dev_info(&i2c->adap.dev, "Enabling slave mode\n"); | 410 | dev_info(&i2c->adap.dev, "Enabling slave mode\n"); |
@@ -907,12 +947,6 @@ static int i2c_pxa_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num | |||
907 | struct pxa_i2c *i2c = adap->algo_data; | 947 | struct pxa_i2c *i2c = adap->algo_data; |
908 | int ret, i; | 948 | int ret, i; |
909 | 949 | ||
910 | /* If the I2C controller is disabled we need to reset it (probably due | ||
911 | to a suspend/resume destroying state). We do this here as we can then | ||
912 | avoid worrying about resuming the controller before its users. */ | ||
913 | if (!(readl(_ICR(i2c)) & ICR_IUE)) | ||
914 | i2c_pxa_reset(i2c); | ||
915 | |||
916 | for (i = adap->retries; i >= 0; i--) { | 950 | for (i = adap->retries; i >= 0; i--) { |
917 | ret = i2c_pxa_do_xfer(i2c, msgs, num); | 951 | ret = i2c_pxa_do_xfer(i2c, msgs, num); |
918 | if (ret != I2C_RETRY) | 952 | if (ret != I2C_RETRY) |
@@ -993,6 +1027,7 @@ static int i2c_pxa_probe(struct platform_device *dev) | |||
993 | ret = -EIO; | 1027 | ret = -EIO; |
994 | goto eremap; | 1028 | goto eremap; |
995 | } | 1029 | } |
1030 | i2c->reg_shift = (cpu_is_pxa3xx() && (dev->id == 1)) ? 0 : 1; | ||
996 | 1031 | ||
997 | i2c->iobase = res->start; | 1032 | i2c->iobase = res->start; |
998 | i2c->iosize = res_len(res); | 1033 | i2c->iosize = res_len(res); |
@@ -1013,6 +1048,7 @@ static int i2c_pxa_probe(struct platform_device *dev) | |||
1013 | if (plat) { | 1048 | if (plat) { |
1014 | i2c->adap.class = plat->class; | 1049 | i2c->adap.class = plat->class; |
1015 | i2c->use_pio = plat->use_pio; | 1050 | i2c->use_pio = plat->use_pio; |
1051 | i2c->fast_mode = plat->fast_mode; | ||
1016 | } | 1052 | } |
1017 | 1053 | ||
1018 | if (i2c->use_pio) { | 1054 | if (i2c->use_pio) { |
@@ -1082,9 +1118,33 @@ static int __exit i2c_pxa_remove(struct platform_device *dev) | |||
1082 | return 0; | 1118 | return 0; |
1083 | } | 1119 | } |
1084 | 1120 | ||
1121 | #ifdef CONFIG_PM | ||
1122 | static int i2c_pxa_suspend_late(struct platform_device *dev, pm_message_t state) | ||
1123 | { | ||
1124 | struct pxa_i2c *i2c = platform_get_drvdata(dev); | ||
1125 | clk_disable(i2c->clk); | ||
1126 | return 0; | ||
1127 | } | ||
1128 | |||
1129 | static int i2c_pxa_resume_early(struct platform_device *dev) | ||
1130 | { | ||
1131 | struct pxa_i2c *i2c = platform_get_drvdata(dev); | ||
1132 | |||
1133 | clk_enable(i2c->clk); | ||
1134 | i2c_pxa_reset(i2c); | ||
1135 | |||
1136 | return 0; | ||
1137 | } | ||
1138 | #else | ||
1139 | #define i2c_pxa_suspend_late NULL | ||
1140 | #define i2c_pxa_resume_early NULL | ||
1141 | #endif | ||
1142 | |||
1085 | static struct platform_driver i2c_pxa_driver = { | 1143 | static struct platform_driver i2c_pxa_driver = { |
1086 | .probe = i2c_pxa_probe, | 1144 | .probe = i2c_pxa_probe, |
1087 | .remove = __exit_p(i2c_pxa_remove), | 1145 | .remove = __exit_p(i2c_pxa_remove), |
1146 | .suspend_late = i2c_pxa_suspend_late, | ||
1147 | .resume_early = i2c_pxa_resume_early, | ||
1088 | .driver = { | 1148 | .driver = { |
1089 | .name = "pxa2xx-i2c", | 1149 | .name = "pxa2xx-i2c", |
1090 | .owner = THIS_MODULE, | 1150 | .owner = THIS_MODULE, |