aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Povey <jon.povey@racelogic.co.uk>2010-10-12 00:47:05 -0400
committerBen Dooks <ben-linux@fluff.org>2010-10-17 20:25:33 -0400
commitc5b4afec8e669bbe265daea24037fccfc42c4fe3 (patch)
treedc711356af9d49180cca3806b93ee2fa7548befe
parent85a331881dd52a93e7d4c57bcaf5486cc8718465 (diff)
i2c-davinci: Fix TX setup for more SoCs
This patch is an improvement to 4bba0fd8d1c6d405df666e2573e1a1f917098be0 which got to mainline a little early. Sudhakar Rajashekhara explains that at least OMAP-L138 requires MDR mode settings before DXR for correct behaviour, so load MDR first with STT cleared and later load again with STT set. Tested on DM355 connected to Techwell TW2836 and Wolfson WM8985 Signed-off-by: Jon Povey <jon.povey@racelogic.co.uk> Acked-by: Troy Kisky <troy.kisky@boundarydevices.com> Tested-by: Sudhakar Rajashekhara <sudhakar.raj@ti.com> Acked-by: Kevin Hilman <khilman@deeprootsystems.com> Signed-off-by: Ben Dooks <ben-linux@fluff.org>
-rw-r--r--drivers/i2c/busses/i2c-davinci.c24
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,