diff options
-rw-r--r-- | drivers/i2c/busses/i2c-pnx.c | 48 | ||||
-rw-r--r-- | include/linux/i2c-pnx.h | 1 |
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 | ||
27 | struct i2c_pnx_algo_data { | 28 | struct i2c_pnx_algo_data { |