diff options
Diffstat (limited to 'drivers/i2c/busses/i2c-davinci.c')
-rw-r--r-- | drivers/i2c/busses/i2c-davinci.c | 57 |
1 files changed, 53 insertions, 4 deletions
diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c index 352b4e7bdd9e..2222c87876b9 100644 --- a/drivers/i2c/busses/i2c-davinci.c +++ b/drivers/i2c/busses/i2c-davinci.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <linux/io.h> | 37 | #include <linux/io.h> |
38 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
39 | #include <linux/cpufreq.h> | 39 | #include <linux/cpufreq.h> |
40 | #include <linux/gpio.h> | ||
40 | 41 | ||
41 | #include <mach/hardware.h> | 42 | #include <mach/hardware.h> |
42 | #include <mach/i2c.h> | 43 | #include <mach/i2c.h> |
@@ -44,6 +45,7 @@ | |||
44 | /* ----- global defines ----------------------------------------------- */ | 45 | /* ----- global defines ----------------------------------------------- */ |
45 | 46 | ||
46 | #define DAVINCI_I2C_TIMEOUT (1*HZ) | 47 | #define DAVINCI_I2C_TIMEOUT (1*HZ) |
48 | #define DAVINCI_I2C_MAX_TRIES 2 | ||
47 | #define I2C_DAVINCI_INTR_ALL (DAVINCI_I2C_IMR_AAS | \ | 49 | #define I2C_DAVINCI_INTR_ALL (DAVINCI_I2C_IMR_AAS | \ |
48 | DAVINCI_I2C_IMR_SCD | \ | 50 | DAVINCI_I2C_IMR_SCD | \ |
49 | DAVINCI_I2C_IMR_ARDY | \ | 51 | DAVINCI_I2C_IMR_ARDY | \ |
@@ -131,6 +133,44 @@ static inline u16 davinci_i2c_read_reg(struct davinci_i2c_dev *i2c_dev, int reg) | |||
131 | return __raw_readw(i2c_dev->base + reg); | 133 | return __raw_readw(i2c_dev->base + reg); |
132 | } | 134 | } |
133 | 135 | ||
136 | /* Generate a pulse on the i2c clock pin. */ | ||
137 | static void generic_i2c_clock_pulse(unsigned int scl_pin) | ||
138 | { | ||
139 | u16 i; | ||
140 | |||
141 | if (scl_pin) { | ||
142 | /* Send high and low on the SCL line */ | ||
143 | for (i = 0; i < 9; i++) { | ||
144 | gpio_set_value(scl_pin, 0); | ||
145 | udelay(20); | ||
146 | gpio_set_value(scl_pin, 1); | ||
147 | udelay(20); | ||
148 | } | ||
149 | } | ||
150 | } | ||
151 | |||
152 | /* This routine does i2c bus recovery as specified in the | ||
153 | * i2c protocol Rev. 03 section 3.16 titled "Bus clear" | ||
154 | */ | ||
155 | static void i2c_recover_bus(struct davinci_i2c_dev *dev) | ||
156 | { | ||
157 | u32 flag = 0; | ||
158 | struct davinci_i2c_platform_data *pdata = dev->dev->platform_data; | ||
159 | |||
160 | dev_err(dev->dev, "initiating i2c bus recovery\n"); | ||
161 | /* Send NACK to the slave */ | ||
162 | flag = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG); | ||
163 | flag |= DAVINCI_I2C_MDR_NACK; | ||
164 | /* write the data into mode register */ | ||
165 | davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag); | ||
166 | if (pdata) | ||
167 | generic_i2c_clock_pulse(pdata->scl_pin); | ||
168 | /* Send STOP */ | ||
169 | flag = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG); | ||
170 | flag |= DAVINCI_I2C_MDR_STP; | ||
171 | davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag); | ||
172 | } | ||
173 | |||
134 | static inline void davinci_i2c_reset_ctrl(struct davinci_i2c_dev *i2c_dev, | 174 | static inline void davinci_i2c_reset_ctrl(struct davinci_i2c_dev *i2c_dev, |
135 | int val) | 175 | int val) |
136 | { | 176 | { |
@@ -236,14 +276,22 @@ static int i2c_davinci_wait_bus_not_busy(struct davinci_i2c_dev *dev, | |||
236 | char allow_sleep) | 276 | char allow_sleep) |
237 | { | 277 | { |
238 | unsigned long timeout; | 278 | unsigned long timeout; |
279 | static u16 to_cnt; | ||
239 | 280 | ||
240 | timeout = jiffies + dev->adapter.timeout; | 281 | timeout = jiffies + dev->adapter.timeout; |
241 | while (davinci_i2c_read_reg(dev, DAVINCI_I2C_STR_REG) | 282 | while (davinci_i2c_read_reg(dev, DAVINCI_I2C_STR_REG) |
242 | & DAVINCI_I2C_STR_BB) { | 283 | & DAVINCI_I2C_STR_BB) { |
243 | if (time_after(jiffies, timeout)) { | 284 | if (to_cnt <= DAVINCI_I2C_MAX_TRIES) { |
244 | dev_warn(dev->dev, | 285 | if (time_after(jiffies, timeout)) { |
245 | "timeout waiting for bus ready\n"); | 286 | dev_warn(dev->dev, |
246 | return -ETIMEDOUT; | 287 | "timeout waiting for bus ready\n"); |
288 | to_cnt++; | ||
289 | return -ETIMEDOUT; | ||
290 | } else { | ||
291 | to_cnt = 0; | ||
292 | i2c_recover_bus(dev); | ||
293 | i2c_davinci_init(dev); | ||
294 | } | ||
247 | } | 295 | } |
248 | if (allow_sleep) | 296 | if (allow_sleep) |
249 | schedule_timeout(1); | 297 | schedule_timeout(1); |
@@ -327,6 +375,7 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) | |||
327 | dev->adapter.timeout); | 375 | dev->adapter.timeout); |
328 | if (r == 0) { | 376 | if (r == 0) { |
329 | dev_err(dev->dev, "controller timed out\n"); | 377 | dev_err(dev->dev, "controller timed out\n"); |
378 | i2c_recover_bus(dev); | ||
330 | i2c_davinci_init(dev); | 379 | i2c_davinci_init(dev); |
331 | dev->buf_len = 0; | 380 | dev->buf_len = 0; |
332 | return -ETIMEDOUT; | 381 | return -ETIMEDOUT; |