aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/i2c/busses/i2c-pnx.c48
-rw-r--r--include/linux/i2c-pnx.h1
2 files changed, 29 insertions, 20 deletions
diff --git a/drivers/i2c/busses/i2c-pnx.c b/drivers/i2c/busses/i2c-pnx.c
index b36e21f9fd5..8488bddfe46 100644
--- a/drivers/i2c/busses/i2c-pnx.c
+++ b/drivers/i2c/busses/i2c-pnx.c
@@ -291,31 +291,37 @@ static int i2c_pnx_master_rcv(struct i2c_pnx_algo_data *alg_data)
291 * or we didn't 'ask' for it yet. 291 * or we didn't 'ask' for it yet.
292 */ 292 */
293 if (ioread32(I2C_REG_STS(alg_data)) & mstatus_rfe) { 293 if (ioread32(I2C_REG_STS(alg_data)) & mstatus_rfe) {
294 dev_dbg(&alg_data->adapter.dev, 294 /* 'Asking' is done asynchronously, e.g. dummy TX of several
295 "%s(): Write dummy data to fill Rx-fifo...\n", 295 * bytes is done before the first actual RX arrives in FIFO.
296 __func__); 296 * Therefore, ordered bytes (via TX) are counted separately.
297 */
298 if (alg_data->mif.order) {
299 dev_dbg(&alg_data->adapter.dev,
300 "%s(): Write dummy data to fill Rx-fifo...\n",
301 __func__);
297 302
298 if (alg_data->mif.len == 1) { 303 if (alg_data->mif.order == 1) {
299 /* Last byte, do not acknowledge next rcv. */ 304 /* Last byte, do not acknowledge next rcv. */
300 val |= stop_bit; 305 val |= stop_bit;
306
307 /*
308 * Enable interrupt RFDAIE (data in Rx fifo),
309 * and disable DRMIE (need data for Tx)
310 */
311 ctl = ioread32(I2C_REG_CTL(alg_data));
312 ctl |= mcntrl_rffie | mcntrl_daie;
313 ctl &= ~mcntrl_drmie;
314 iowrite32(ctl, I2C_REG_CTL(alg_data));
315 }
301 316
302 /* 317 /*
303 * Enable interrupt RFDAIE (data in Rx fifo), 318 * Now we'll 'ask' for data:
304 * and disable DRMIE (need data for Tx) 319 * For each byte we want to receive, we must
320 * write a (dummy) byte to the Tx-FIFO.
305 */ 321 */
306 ctl = ioread32(I2C_REG_CTL(alg_data)); 322 iowrite32(val, I2C_REG_TX(alg_data));
307 ctl |= mcntrl_rffie | mcntrl_daie; 323 alg_data->mif.order--;
308 ctl &= ~mcntrl_drmie;
309 iowrite32(ctl, I2C_REG_CTL(alg_data));
310 } 324 }
311
312 /*
313 * Now we'll 'ask' for data:
314 * For each byte we want to receive, we must
315 * write a (dummy) byte to the Tx-FIFO.
316 */
317 iowrite32(val, I2C_REG_TX(alg_data));
318
319 return 0; 325 return 0;
320 } 326 }
321 327
@@ -515,6 +521,7 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
515 521
516 alg_data->mif.buf = pmsg->buf; 522 alg_data->mif.buf = pmsg->buf;
517 alg_data->mif.len = pmsg->len; 523 alg_data->mif.len = pmsg->len;
524 alg_data->mif.order = pmsg->len;
518 alg_data->mif.mode = (pmsg->flags & I2C_M_RD) ? 525 alg_data->mif.mode = (pmsg->flags & I2C_M_RD) ?
519 I2C_SMBUS_READ : I2C_SMBUS_WRITE; 526 I2C_SMBUS_READ : I2C_SMBUS_WRITE;
520 alg_data->mif.ret = 0; 527 alg_data->mif.ret = 0;
@@ -567,6 +574,7 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
567 /* Cleanup to be sure... */ 574 /* Cleanup to be sure... */
568 alg_data->mif.buf = NULL; 575 alg_data->mif.buf = NULL;
569 alg_data->mif.len = 0; 576 alg_data->mif.len = 0;
577 alg_data->mif.order = 0;
570 578
571 dev_dbg(&alg_data->adapter.dev, "%s(): exiting, stat = %x\n", 579 dev_dbg(&alg_data->adapter.dev, "%s(): exiting, stat = %x\n",
572 __func__, ioread32(I2C_REG_STS(alg_data))); 580 __func__, ioread32(I2C_REG_STS(alg_data)));
diff --git a/include/linux/i2c-pnx.h b/include/linux/i2c-pnx.h
index 1bc74afe7a3..49ed17fdf05 100644
--- a/include/linux/i2c-pnx.h
+++ b/include/linux/i2c-pnx.h
@@ -22,6 +22,7 @@ struct i2c_pnx_mif {
22 struct timer_list timer; /* Timeout */ 22 struct timer_list timer; /* Timeout */
23 u8 * buf; /* Data buffer */ 23 u8 * buf; /* Data buffer */
24 int len; /* Length of data buffer */ 24 int len; /* Length of data buffer */
25 int order; /* RX Bytes to order via TX */
25}; 26};
26 27
27struct i2c_pnx_algo_data { 28struct i2c_pnx_algo_data {