aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/i2c')
-rw-r--r--drivers/i2c/busses/i2c-omap.c83
1 files changed, 51 insertions, 32 deletions
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 4af123fab63c..f33bc5a55074 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -193,6 +193,7 @@ struct omap_i2c_dev {
193 u8 *regs; 193 u8 *regs;
194 size_t buf_len; 194 size_t buf_len;
195 struct i2c_adapter adapter; 195 struct i2c_adapter adapter;
196 u8 threshold;
196 u8 fifo_size; /* use as flag and value 197 u8 fifo_size; /* use as flag and value
197 * fifo_size==0 implies no fifo 198 * fifo_size==0 implies no fifo
198 * if set, should be trsh+1 199 * if set, should be trsh+1
@@ -418,13 +419,6 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)
418 omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, scll); 419 omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, scll);
419 omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, sclh); 420 omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, sclh);
420 421
421 if (dev->fifo_size) {
422 /* Note: setup required fifo size - 1. RTRSH and XTRSH */
423 buf = (dev->fifo_size - 1) << 8 | OMAP_I2C_BUF_RXFIF_CLR |
424 (dev->fifo_size - 1) | OMAP_I2C_BUF_TXFIF_CLR;
425 omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, buf);
426 }
427
428 /* Take the I2C module out of reset: */ 422 /* Take the I2C module out of reset: */
429 omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN); 423 omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
430 424
@@ -462,6 +456,45 @@ static int omap_i2c_wait_for_bb(struct omap_i2c_dev *dev)
462 return 0; 456 return 0;
463} 457}
464 458
459static void omap_i2c_resize_fifo(struct omap_i2c_dev *dev, u8 size, bool is_rx)
460{
461 u16 buf;
462
463 if (dev->flags & OMAP_I2C_FLAG_NO_FIFO)
464 return;
465
466 /*
467 * Set up notification threshold based on message size. We're doing
468 * this to try and avoid draining feature as much as possible. Whenever
469 * we have big messages to transfer (bigger than our total fifo size)
470 * then we might use draining feature to transfer the remaining bytes.
471 */
472
473 dev->threshold = clamp(size, (u8) 1, dev->fifo_size);
474
475 buf = omap_i2c_read_reg(dev, OMAP_I2C_BUF_REG);
476
477 if (is_rx) {
478 /* Clear RX Threshold */
479 buf &= ~(0x3f << 8);
480 buf |= ((dev->threshold - 1) << 8) | OMAP_I2C_BUF_RXFIF_CLR;
481 } else {
482 /* Clear TX Threshold */
483 buf &= ~0x3f;
484 buf |= (dev->threshold - 1) | OMAP_I2C_BUF_TXFIF_CLR;
485 }
486
487 omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, buf);
488
489 if (dev->rev < OMAP_I2C_REV_ON_3630_4430)
490 dev->b_hw = 1; /* Enable hardware fixes */
491
492 /* calculate wakeup latency constraint for MPU */
493 if (dev->set_mpu_wkup_lat != NULL)
494 dev->latency = (1000000 * dev->threshold) /
495 (1000 * dev->speed / 8);
496}
497
465/* 498/*
466 * Low level master read/write transaction. 499 * Low level master read/write transaction.
467 */ 500 */
@@ -478,6 +511,9 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
478 if (msg->len == 0) 511 if (msg->len == 0)
479 return -EINVAL; 512 return -EINVAL;
480 513
514 dev->receiver = !!(msg->flags & I2C_M_RD);
515 omap_i2c_resize_fifo(dev, msg->len, dev->receiver);
516
481 omap_i2c_write_reg(dev, OMAP_I2C_SA_REG, msg->addr); 517 omap_i2c_write_reg(dev, OMAP_I2C_SA_REG, msg->addr);
482 518
483 /* REVISIT: Could the STB bit of I2C_CON be used with probing? */ 519 /* REVISIT: Could the STB bit of I2C_CON be used with probing? */
@@ -493,7 +529,6 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
493 529
494 INIT_COMPLETION(dev->cmd_complete); 530 INIT_COMPLETION(dev->cmd_complete);
495 dev->cmd_err = 0; 531 dev->cmd_err = 0;
496 dev->receiver = !!(msg->flags & I2C_M_RD);
497 532
498 w = OMAP_I2C_CON_EN | OMAP_I2C_CON_MST | OMAP_I2C_CON_STT; 533 w = OMAP_I2C_CON_EN | OMAP_I2C_CON_MST | OMAP_I2C_CON_STT;
499 534
@@ -760,12 +795,6 @@ static void omap_i2c_receive_data(struct omap_i2c_dev *dev, u8 num_bytes,
760 u16 w; 795 u16 w;
761 796
762 while (num_bytes--) { 797 while (num_bytes--) {
763 if (!dev->buf_len) {
764 dev_err(dev->dev, "%s without data",
765 is_rdr ? "RDR" : "RRDY");
766 break;
767 }
768
769 w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG); 798 w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG);
770 *dev->buf++ = w; 799 *dev->buf++ = w;
771 dev->buf_len--; 800 dev->buf_len--;
@@ -775,10 +804,8 @@ static void omap_i2c_receive_data(struct omap_i2c_dev *dev, u8 num_bytes,
775 * omap4 is 8 bit wide 804 * omap4 is 8 bit wide
776 */ 805 */
777 if (dev->flags & OMAP_I2C_FLAG_16BIT_DATA_REG) { 806 if (dev->flags & OMAP_I2C_FLAG_16BIT_DATA_REG) {
778 if (dev->buf_len) { 807 *dev->buf++ = w >> 8;
779 *dev->buf++ = w >> 8; 808 dev->buf_len--;
780 dev->buf_len--;
781 }
782 } 809 }
783 } 810 }
784} 811}
@@ -789,12 +816,6 @@ static int omap_i2c_transmit_data(struct omap_i2c_dev *dev, u8 num_bytes,
789 u16 w; 816 u16 w;
790 817
791 while (num_bytes--) { 818 while (num_bytes--) {
792 if (!dev->buf_len) {
793 dev_err(dev->dev, "%s without data",
794 is_xdr ? "XDR" : "XRDY");
795 break;
796 }
797
798 w = *dev->buf++; 819 w = *dev->buf++;
799 dev->buf_len--; 820 dev->buf_len--;
800 821
@@ -803,10 +824,8 @@ static int omap_i2c_transmit_data(struct omap_i2c_dev *dev, u8 num_bytes,
803 * omap4 is 8 bit wide 824 * omap4 is 8 bit wide
804 */ 825 */
805 if (dev->flags & OMAP_I2C_FLAG_16BIT_DATA_REG) { 826 if (dev->flags & OMAP_I2C_FLAG_16BIT_DATA_REG) {
806 if (dev->buf_len) { 827 w |= *dev->buf++ << 8;
807 w |= *dev->buf++ << 8; 828 dev->buf_len--;
808 dev->buf_len--;
809 }
810 } 829 }
811 830
812 if (dev->errata & I2C_OMAP_ERRATA_I462) { 831 if (dev->errata & I2C_OMAP_ERRATA_I462) {
@@ -901,8 +920,8 @@ complete:
901 if (stat & OMAP_I2C_STAT_RRDY) { 920 if (stat & OMAP_I2C_STAT_RRDY) {
902 u8 num_bytes = 1; 921 u8 num_bytes = 1;
903 922
904 if (dev->fifo_size) 923 if (dev->threshold)
905 num_bytes = dev->fifo_size; 924 num_bytes = dev->threshold;
906 925
907 omap_i2c_receive_data(dev, num_bytes, false); 926 omap_i2c_receive_data(dev, num_bytes, false);
908 omap_i2c_ack_stat(dev, OMAP_I2C_STAT_RRDY); 927 omap_i2c_ack_stat(dev, OMAP_I2C_STAT_RRDY);
@@ -929,8 +948,8 @@ complete:
929 u8 num_bytes = 1; 948 u8 num_bytes = 1;
930 int ret; 949 int ret;
931 950
932 if (dev->fifo_size) 951 if (dev->threshold)
933 num_bytes = dev->fifo_size; 952 num_bytes = dev->threshold;
934 953
935 ret = omap_i2c_transmit_data(dev, num_bytes, false); 954 ret = omap_i2c_transmit_data(dev, num_bytes, false);
936 stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG); 955 stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG);