diff options
Diffstat (limited to 'drivers/i2c/busses/i2c-davinci.c')
-rw-r--r-- | drivers/i2c/busses/i2c-davinci.c | 24 |
1 files changed, 15 insertions, 9 deletions
diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c index b8feac5f2ef4..5795c8398c7c 100644 --- a/drivers/i2c/busses/i2c-davinci.c +++ b/drivers/i2c/busses/i2c-davinci.c | |||
@@ -331,21 +331,16 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) | |||
331 | INIT_COMPLETION(dev->cmd_complete); | 331 | INIT_COMPLETION(dev->cmd_complete); |
332 | dev->cmd_err = 0; | 332 | dev->cmd_err = 0; |
333 | 333 | ||
334 | /* Take I2C out of reset, configure it as master and set the | 334 | /* Take I2C out of reset and configure it as master */ |
335 | * start bit */ | 335 | flag = DAVINCI_I2C_MDR_IRS | DAVINCI_I2C_MDR_MST; |
336 | flag = DAVINCI_I2C_MDR_IRS | DAVINCI_I2C_MDR_MST | DAVINCI_I2C_MDR_STT; | ||
337 | 336 | ||
338 | /* if the slave address is ten bit address, enable XA bit */ | 337 | /* if the slave address is ten bit address, enable XA bit */ |
339 | if (msg->flags & I2C_M_TEN) | 338 | if (msg->flags & I2C_M_TEN) |
340 | flag |= DAVINCI_I2C_MDR_XA; | 339 | flag |= DAVINCI_I2C_MDR_XA; |
341 | if (!(msg->flags & I2C_M_RD)) | 340 | if (!(msg->flags & I2C_M_RD)) |
342 | flag |= DAVINCI_I2C_MDR_TRX; | 341 | flag |= DAVINCI_I2C_MDR_TRX; |
343 | if (stop) | 342 | if (msg->len == 0) |
344 | flag |= DAVINCI_I2C_MDR_STP; | ||
345 | if (msg->len == 0) { | ||
346 | flag |= DAVINCI_I2C_MDR_RM; | 343 | flag |= DAVINCI_I2C_MDR_RM; |
347 | flag &= ~DAVINCI_I2C_MDR_STP; | ||
348 | } | ||
349 | 344 | ||
350 | /* Enable receive or transmit interrupts */ | 345 | /* Enable receive or transmit interrupts */ |
351 | w = davinci_i2c_read_reg(dev, DAVINCI_I2C_IMR_REG); | 346 | w = davinci_i2c_read_reg(dev, DAVINCI_I2C_IMR_REG); |
@@ -358,17 +353,28 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) | |||
358 | dev->terminate = 0; | 353 | dev->terminate = 0; |
359 | 354 | ||
360 | /* | 355 | /* |
356 | * Write mode register first as needed for correct behaviour | ||
357 | * on OMAP-L138, but don't set STT yet to avoid a race with XRDY | ||
358 | * occuring before we have loaded DXR | ||
359 | */ | ||
360 | davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag); | ||
361 | |||
362 | /* | ||
361 | * First byte should be set here, not after interrupt, | 363 | * First byte should be set here, not after interrupt, |
362 | * because transmit-data-ready interrupt can come before | 364 | * because transmit-data-ready interrupt can come before |
363 | * NACK-interrupt during sending of previous message and | 365 | * NACK-interrupt during sending of previous message and |
364 | * ICDXR may have wrong data | 366 | * ICDXR may have wrong data |
367 | * It also saves us one interrupt, slightly faster | ||
365 | */ | 368 | */ |
366 | if ((!(msg->flags & I2C_M_RD)) && dev->buf_len) { | 369 | if ((!(msg->flags & I2C_M_RD)) && dev->buf_len) { |
367 | davinci_i2c_write_reg(dev, DAVINCI_I2C_DXR_REG, *dev->buf++); | 370 | davinci_i2c_write_reg(dev, DAVINCI_I2C_DXR_REG, *dev->buf++); |
368 | dev->buf_len--; | 371 | dev->buf_len--; |
369 | } | 372 | } |
370 | 373 | ||
371 | /* write the data into mode register; start transmitting */ | 374 | /* Set STT to begin transmit now DXR is loaded */ |
375 | flag |= DAVINCI_I2C_MDR_STT; | ||
376 | if (stop && msg->len != 0) | ||
377 | flag |= DAVINCI_I2C_MDR_STP; | ||
372 | davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag); | 378 | davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag); |
373 | 379 | ||
374 | r = wait_for_completion_interruptible_timeout(&dev->cmd_complete, | 380 | r = wait_for_completion_interruptible_timeout(&dev->cmd_complete, |