aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFelipe Balbi <balbi@ti.com>2012-09-12 06:58:00 -0400
committerWolfram Sang <w.sang@pengutronix.de>2012-09-12 09:02:21 -0400
commit6d9939f651419a63e091105663821f9c7d3fec37 (patch)
tree3055c4a8aaab04f63b87bed2dde7f37c35daf16c
parent540a4790f7da0d3ca5ad9d726f198a5eb4db05ec (diff)
i2c: omap: split out [XR]DR and [XR]RDY
While they do pretty much the same thing, there are a few peculiarities. Specially WRT erratas, it's best to split those out and re-factor the read/write loop to another function which both cases call. This last part will be done on another patch. While at that, also avoid an unncessary register read since dev->fifo_len will always contain the correct amount of data to be transferred. Signed-off-by: Felipe Balbi <balbi@ti.com> Signed-off-by: Shubhrajyoti D <shubhrajyoti@ti.com> Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
-rw-r--r--drivers/i2c/busses/i2c-omap.c126
1 files changed, 92 insertions, 34 deletions
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index f24eae9f7f1e..815577b1c89f 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -801,36 +801,62 @@ complete:
801 return IRQ_HANDLED; 801 return IRQ_HANDLED;
802 } 802 }
803 803
804 if (stat & (OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR)) { 804 if (stat & OMAP_I2C_STAT_RDR) {
805 u8 num_bytes = 1; 805 u8 num_bytes = 1;
806 806
807 if (dev->fifo_size)
808 num_bytes = dev->buf_len;
809
810 while (num_bytes--) {
811 if (!dev->buf_len) {
812 dev_err(dev->dev,
813 "RDR IRQ while no data"
814 " requested\n");
815 break;
816 }
817
818 w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG);
819 *dev->buf++ = w;
820 dev->buf_len--;
821
822 /*
823 * Data reg in 2430, omap3 and
824 * omap4 is 8 bit wide
825 */
826 if (dev->flags &
827 OMAP_I2C_FLAG_16BIT_DATA_REG) {
828 if (dev->buf_len) {
829 *dev->buf++ = w >> 8;
830 dev->buf_len--;
831 }
832 }
833 }
834
807 if (dev->errata & I2C_OMAP_ERRATA_I207) 835 if (dev->errata & I2C_OMAP_ERRATA_I207)
808 i2c_omap_errata_i207(dev, stat); 836 i2c_omap_errata_i207(dev, stat);
809 837
810 if (dev->fifo_size) { 838 omap_i2c_ack_stat(dev, OMAP_I2C_STAT_RDR);
811 if (stat & OMAP_I2C_STAT_RRDY) 839 continue;
812 num_bytes = dev->fifo_size; 840 }
813 else /* read RXSTAT on RDR interrupt */ 841
814 num_bytes = (omap_i2c_read_reg(dev, 842 if (stat & OMAP_I2C_STAT_RRDY) {
815 OMAP_I2C_BUFSTAT_REG) 843 u8 num_bytes = 1;
816 >> 8) & 0x3F; 844
817 } 845 if (dev->fifo_size)
846 num_bytes = dev->fifo_size;
847
818 while (num_bytes--) { 848 while (num_bytes--) {
819 if (!dev->buf_len) { 849 if (!dev->buf_len) {
820 if (stat & OMAP_I2C_STAT_RRDY) 850 dev_err(dev->dev,
821 dev_err(dev->dev,
822 "RRDY IRQ while no data" 851 "RRDY IRQ while no data"
823 " requested\n"); 852 " requested\n");
824 if (stat & OMAP_I2C_STAT_RDR)
825 dev_err(dev->dev,
826 "RDR IRQ while no data"
827 " requested\n");
828 break; 853 break;
829 } 854 }
830 855
831 w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG); 856 w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG);
832 *dev->buf++ = w; 857 *dev->buf++ = w;
833 dev->buf_len--; 858 dev->buf_len--;
859
834 /* 860 /*
835 * Data reg in 2430, omap3 and 861 * Data reg in 2430, omap3 and
836 * omap4 is 8 bit wide 862 * omap4 is 8 bit wide
@@ -843,36 +869,68 @@ complete:
843 } 869 }
844 } 870 }
845 } 871 }
846 omap_i2c_ack_stat(dev, (OMAP_I2C_STAT_RRDY | 872
847 OMAP_I2C_STAT_RDR)); 873 omap_i2c_ack_stat(dev, OMAP_I2C_STAT_RRDY);
848 continue; 874 continue;
849 } 875 }
850 876
851 if (stat & (OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR)) { 877 if (stat & OMAP_I2C_STAT_XDR) {
852 u8 num_bytes = 1; 878 u8 num_bytes = 1;
853 if (dev->fifo_size) { 879
854 if (stat & OMAP_I2C_STAT_XRDY) 880 if (dev->fifo_size)
855 num_bytes = dev->fifo_size; 881 num_bytes = dev->buf_len;
856 else /* read TXSTAT on XDR interrupt */ 882
857 num_bytes = omap_i2c_read_reg(dev, 883 while (num_bytes--) {
858 OMAP_I2C_BUFSTAT_REG) 884 if (!dev->buf_len) {
859 & 0x3F; 885 dev_err(dev->dev,
886 "XDR IRQ while no "
887 "data to send\n");
888 break;
889 }
890
891 w = *dev->buf++;
892 dev->buf_len--;
893
894 /*
895 * Data reg in 2430, omap3 and
896 * omap4 is 8 bit wide
897 */
898 if (dev->flags &
899 OMAP_I2C_FLAG_16BIT_DATA_REG) {
900 if (dev->buf_len) {
901 w |= *dev->buf++ << 8;
902 dev->buf_len--;
903 }
904 }
905
906 if ((dev->errata & I2C_OMAP_ERRATA_I462) &&
907 errata_omap3_i462(dev, &stat, &err))
908 goto complete;
909
910 omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w);
860 } 911 }
912
913 omap_i2c_ack_stat(dev, OMAP_I2C_STAT_XDR);
914 continue;
915 }
916
917 if (stat & OMAP_I2C_STAT_XRDY) {
918 u8 num_bytes = 1;
919
920 if (dev->fifo_size)
921 num_bytes = dev->fifo_size;
922
861 while (num_bytes--) { 923 while (num_bytes--) {
862 if (!dev->buf_len) { 924 if (!dev->buf_len) {
863 if (stat & OMAP_I2C_STAT_XRDY) 925 dev_err(dev->dev,
864 dev_err(dev->dev,
865 "XRDY IRQ while no " 926 "XRDY IRQ while no "
866 "data to send\n"); 927 "data to send\n");
867 if (stat & OMAP_I2C_STAT_XDR)
868 dev_err(dev->dev,
869 "XDR IRQ while no "
870 "data to send\n");
871 break; 928 break;
872 } 929 }
873 930
874 w = *dev->buf++; 931 w = *dev->buf++;
875 dev->buf_len--; 932 dev->buf_len--;
933
876 /* 934 /*
877 * Data reg in 2430, omap3 and 935 * Data reg in 2430, omap3 and
878 * omap4 is 8 bit wide 936 * omap4 is 8 bit wide
@@ -891,8 +949,8 @@ complete:
891 949
892 omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w); 950 omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w);
893 } 951 }
894 omap_i2c_ack_stat(dev, (OMAP_I2C_STAT_XRDY | 952
895 OMAP_I2C_STAT_XDR)); 953 omap_i2c_ack_stat(dev, OMAP_I2C_STAT_XRDY);
896 continue; 954 continue;
897 } 955 }
898 956