aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/i2c/busses/i2c-davinci.c31
1 files changed, 27 insertions, 4 deletions
diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c
index 4523364e6722..43913c1d50f5 100644
--- a/drivers/i2c/busses/i2c-davinci.c
+++ b/drivers/i2c/busses/i2c-davinci.c
@@ -113,6 +113,7 @@ struct davinci_i2c_dev {
113 u8 *buf; 113 u8 *buf;
114 size_t buf_len; 114 size_t buf_len;
115 int irq; 115 int irq;
116 int stop;
116 u8 terminate; 117 u8 terminate;
117 struct i2c_adapter adapter; 118 struct i2c_adapter adapter;
118}; 119};
@@ -250,9 +251,6 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop)
250 u16 w; 251 u16 w;
251 int r; 252 int r;
252 253
253 if (msg->len == 0)
254 return -EINVAL;
255
256 if (!pdata) 254 if (!pdata)
257 pdata = &davinci_i2c_platform_data_default; 255 pdata = &davinci_i2c_platform_data_default;
258 /* Introduce a delay, required for some boards (e.g Davinci EVM) */ 256 /* Introduce a delay, required for some boards (e.g Davinci EVM) */
@@ -264,6 +262,7 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop)
264 262
265 dev->buf = msg->buf; 263 dev->buf = msg->buf;
266 dev->buf_len = msg->len; 264 dev->buf_len = msg->len;
265 dev->stop = stop;
267 266
268 davinci_i2c_write_reg(dev, DAVINCI_I2C_CNT_REG, dev->buf_len); 267 davinci_i2c_write_reg(dev, DAVINCI_I2C_CNT_REG, dev->buf_len);
269 268
@@ -281,6 +280,10 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop)
281 flag |= DAVINCI_I2C_MDR_TRX; 280 flag |= DAVINCI_I2C_MDR_TRX;
282 if (stop) 281 if (stop)
283 flag |= DAVINCI_I2C_MDR_STP; 282 flag |= DAVINCI_I2C_MDR_STP;
283 if (msg->len == 0) {
284 flag |= DAVINCI_I2C_MDR_RM;
285 flag &= ~DAVINCI_I2C_MDR_STP;
286 }
284 287
285 /* Enable receive or transmit interrupts */ 288 /* Enable receive or transmit interrupts */
286 w = davinci_i2c_read_reg(dev, DAVINCI_I2C_IMR_REG); 289 w = davinci_i2c_read_reg(dev, DAVINCI_I2C_IMR_REG);
@@ -291,9 +294,21 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop)
291 davinci_i2c_write_reg(dev, DAVINCI_I2C_IMR_REG, w); 294 davinci_i2c_write_reg(dev, DAVINCI_I2C_IMR_REG, w);
292 295
293 dev->terminate = 0; 296 dev->terminate = 0;
297
294 /* write the data into mode register */ 298 /* write the data into mode register */
295 davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag); 299 davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag);
296 300
301 /*
302 * First byte should be set here, not after interrupt,
303 * because transmit-data-ready interrupt can come before
304 * NACK-interrupt during sending of previous message and
305 * ICDXR may have wrong data
306 */
307 if ((!(msg->flags & I2C_M_RD)) && dev->buf_len) {
308 davinci_i2c_write_reg(dev, DAVINCI_I2C_DXR_REG, *dev->buf++);
309 dev->buf_len--;
310 }
311
297 r = wait_for_completion_interruptible_timeout(&dev->cmd_complete, 312 r = wait_for_completion_interruptible_timeout(&dev->cmd_complete,
298 dev->adapter.timeout); 313 dev->adapter.timeout);
299 if (r == 0) { 314 if (r == 0) {
@@ -372,7 +387,7 @@ i2c_davinci_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
372 387
373static u32 i2c_davinci_func(struct i2c_adapter *adap) 388static u32 i2c_davinci_func(struct i2c_adapter *adap)
374{ 389{
375 return I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK); 390 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
376} 391}
377 392
378static void terminate_read(struct davinci_i2c_dev *dev) 393static void terminate_read(struct davinci_i2c_dev *dev)
@@ -431,6 +446,14 @@ static irqreturn_t i2c_davinci_isr(int this_irq, void *dev_id)
431 case DAVINCI_I2C_IVR_ARDY: 446 case DAVINCI_I2C_IVR_ARDY:
432 davinci_i2c_write_reg(dev, 447 davinci_i2c_write_reg(dev,
433 DAVINCI_I2C_STR_REG, DAVINCI_I2C_STR_ARDY); 448 DAVINCI_I2C_STR_REG, DAVINCI_I2C_STR_ARDY);
449 if (((dev->buf_len == 0) && (dev->stop != 0)) ||
450 (dev->cmd_err & DAVINCI_I2C_STR_NACK)) {
451 w = davinci_i2c_read_reg(dev,
452 DAVINCI_I2C_MDR_REG);
453 w |= DAVINCI_I2C_MDR_STP;
454 davinci_i2c_write_reg(dev,
455 DAVINCI_I2C_MDR_REG, w);
456 }
434 complete(&dev->cmd_complete); 457 complete(&dev->cmd_complete);
435 break; 458 break;
436 459