diff options
author | Felipe Balbi <balbi@ti.com> | 2012-09-12 06:58:00 -0400 |
---|---|---|
committer | Wolfram Sang <w.sang@pengutronix.de> | 2012-09-12 09:02:21 -0400 |
commit | 6d9939f651419a63e091105663821f9c7d3fec37 (patch) | |
tree | 3055c4a8aaab04f63b87bed2dde7f37c35daf16c | |
parent | 540a4790f7da0d3ca5ad9d726f198a5eb4db05ec (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.c | 126 |
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 | ||