aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/busses/i2c-omap.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/i2c/busses/i2c-omap.c')
-rw-r--r--drivers/i2c/busses/i2c-omap.c54
1 files changed, 45 insertions, 9 deletions
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index fdd83277c8a8..827da0858136 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -672,9 +672,17 @@ omap_i2c_isr(int this_irq, void *dev_id)
672 break; 672 break;
673 } 673 }
674 674
675 omap_i2c_write_reg(dev, OMAP_I2C_STAT_REG, stat);
676
677 err = 0; 675 err = 0;
676complete:
677 /*
678 * Ack the stat in one go, but [R/X]DR and [R/X]RDY should be
679 * acked after the data operation is complete.
680 * Ref: TRM SWPU114Q Figure 18-31
681 */
682 omap_i2c_write_reg(dev, OMAP_I2C_STAT_REG, stat &
683 ~(OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR |
684 OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR));
685
678 if (stat & OMAP_I2C_STAT_NACK) { 686 if (stat & OMAP_I2C_STAT_NACK) {
679 err |= OMAP_I2C_STAT_NACK; 687 err |= OMAP_I2C_STAT_NACK;
680 omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 688 omap_i2c_write_reg(dev, OMAP_I2C_CON_REG,
@@ -685,16 +693,22 @@ omap_i2c_isr(int this_irq, void *dev_id)
685 err |= OMAP_I2C_STAT_AL; 693 err |= OMAP_I2C_STAT_AL;
686 } 694 }
687 if (stat & (OMAP_I2C_STAT_ARDY | OMAP_I2C_STAT_NACK | 695 if (stat & (OMAP_I2C_STAT_ARDY | OMAP_I2C_STAT_NACK |
688 OMAP_I2C_STAT_AL)) 696 OMAP_I2C_STAT_AL)) {
697 omap_i2c_ack_stat(dev, stat &
698 (OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR |
699 OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR));
689 omap_i2c_complete_cmd(dev, err); 700 omap_i2c_complete_cmd(dev, err);
701 return IRQ_HANDLED;
702 }
690 if (stat & (OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR)) { 703 if (stat & (OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR)) {
691 u8 num_bytes = 1; 704 u8 num_bytes = 1;
692 if (dev->fifo_size) { 705 if (dev->fifo_size) {
693 if (stat & OMAP_I2C_STAT_RRDY) 706 if (stat & OMAP_I2C_STAT_RRDY)
694 num_bytes = dev->fifo_size; 707 num_bytes = dev->fifo_size;
695 else 708 else /* read RXSTAT on RDR interrupt */
696 num_bytes = omap_i2c_read_reg(dev, 709 num_bytes = (omap_i2c_read_reg(dev,
697 OMAP_I2C_BUFSTAT_REG); 710 OMAP_I2C_BUFSTAT_REG)
711 >> 8) & 0x3F;
698 } 712 }
699 while (num_bytes) { 713 while (num_bytes) {
700 num_bytes--; 714 num_bytes--;
@@ -731,9 +745,10 @@ omap_i2c_isr(int this_irq, void *dev_id)
731 if (dev->fifo_size) { 745 if (dev->fifo_size) {
732 if (stat & OMAP_I2C_STAT_XRDY) 746 if (stat & OMAP_I2C_STAT_XRDY)
733 num_bytes = dev->fifo_size; 747 num_bytes = dev->fifo_size;
734 else 748 else /* read TXSTAT on XDR interrupt */
735 num_bytes = omap_i2c_read_reg(dev, 749 num_bytes = omap_i2c_read_reg(dev,
736 OMAP_I2C_BUFSTAT_REG); 750 OMAP_I2C_BUFSTAT_REG)
751 & 0x3F;
737 } 752 }
738 while (num_bytes) { 753 while (num_bytes) {
739 num_bytes--; 754 num_bytes--;
@@ -760,6 +775,27 @@ omap_i2c_isr(int this_irq, void *dev_id)
760 "data to send\n"); 775 "data to send\n");
761 break; 776 break;
762 } 777 }
778
779 /*
780 * OMAP3430 Errata 1.153: When an XRDY/XDR
781 * is hit, wait for XUDF before writing data
782 * to DATA_REG. Otherwise some data bytes can
783 * be lost while transferring them from the
784 * memory to the I2C interface.
785 */
786
787 if (dev->rev <= OMAP_I2C_REV_ON_3430) {
788 while (!(stat & OMAP_I2C_STAT_XUDF)) {
789 if (stat & (OMAP_I2C_STAT_NACK | OMAP_I2C_STAT_AL)) {
790 omap_i2c_ack_stat(dev, stat & (OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR));
791 err |= OMAP_I2C_STAT_XUDF;
792 goto complete;
793 }
794 cpu_relax();
795 stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG);
796 }
797 }
798
763 omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w); 799 omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w);
764 } 800 }
765 omap_i2c_ack_stat(dev, 801 omap_i2c_ack_stat(dev,
@@ -879,7 +915,7 @@ omap_i2c_probe(struct platform_device *pdev)
879 i2c_set_adapdata(adap, dev); 915 i2c_set_adapdata(adap, dev);
880 adap->owner = THIS_MODULE; 916 adap->owner = THIS_MODULE;
881 adap->class = I2C_CLASS_HWMON; 917 adap->class = I2C_CLASS_HWMON;
882 strncpy(adap->name, "OMAP I2C adapter", sizeof(adap->name)); 918 strlcpy(adap->name, "OMAP I2C adapter", sizeof(adap->name));
883 adap->algo = &omap_i2c_algo; 919 adap->algo = &omap_i2c_algo;
884 adap->dev.parent = &pdev->dev; 920 adap->dev.parent = &pdev->dev;
885 921