diff options
Diffstat (limited to 'drivers/i2c')
-rw-r--r-- | drivers/i2c/busses/i2c-omap.c | 42 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-pxa.c | 25 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-s3c2410.c | 30 | ||||
-rw-r--r-- | drivers/i2c/chips/tsl2550.c | 17 |
4 files changed, 77 insertions, 37 deletions
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index fdd83277c8a8..d258b02aef44 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c | |||
@@ -672,9 +672,10 @@ omap_i2c_isr(int this_irq, void *dev_id) | |||
672 | break; | 672 | break; |
673 | } | 673 | } |
674 | 674 | ||
675 | err = 0; | ||
676 | complete: | ||
675 | omap_i2c_write_reg(dev, OMAP_I2C_STAT_REG, stat); | 677 | omap_i2c_write_reg(dev, OMAP_I2C_STAT_REG, stat); |
676 | 678 | ||
677 | err = 0; | ||
678 | if (stat & OMAP_I2C_STAT_NACK) { | 679 | if (stat & OMAP_I2C_STAT_NACK) { |
679 | err |= OMAP_I2C_STAT_NACK; | 680 | err |= OMAP_I2C_STAT_NACK; |
680 | omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, | 681 | omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, |
@@ -685,16 +686,19 @@ omap_i2c_isr(int this_irq, void *dev_id) | |||
685 | err |= OMAP_I2C_STAT_AL; | 686 | err |= OMAP_I2C_STAT_AL; |
686 | } | 687 | } |
687 | if (stat & (OMAP_I2C_STAT_ARDY | OMAP_I2C_STAT_NACK | | 688 | if (stat & (OMAP_I2C_STAT_ARDY | OMAP_I2C_STAT_NACK | |
688 | OMAP_I2C_STAT_AL)) | 689 | OMAP_I2C_STAT_AL)) { |
689 | omap_i2c_complete_cmd(dev, err); | 690 | omap_i2c_complete_cmd(dev, err); |
691 | return IRQ_HANDLED; | ||
692 | } | ||
690 | if (stat & (OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR)) { | 693 | if (stat & (OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR)) { |
691 | u8 num_bytes = 1; | 694 | u8 num_bytes = 1; |
692 | if (dev->fifo_size) { | 695 | if (dev->fifo_size) { |
693 | if (stat & OMAP_I2C_STAT_RRDY) | 696 | if (stat & OMAP_I2C_STAT_RRDY) |
694 | num_bytes = dev->fifo_size; | 697 | num_bytes = dev->fifo_size; |
695 | else | 698 | else /* read RXSTAT on RDR interrupt */ |
696 | num_bytes = omap_i2c_read_reg(dev, | 699 | num_bytes = (omap_i2c_read_reg(dev, |
697 | OMAP_I2C_BUFSTAT_REG); | 700 | OMAP_I2C_BUFSTAT_REG) |
701 | >> 8) & 0x3F; | ||
698 | } | 702 | } |
699 | while (num_bytes) { | 703 | while (num_bytes) { |
700 | num_bytes--; | 704 | num_bytes--; |
@@ -731,9 +735,10 @@ omap_i2c_isr(int this_irq, void *dev_id) | |||
731 | if (dev->fifo_size) { | 735 | if (dev->fifo_size) { |
732 | if (stat & OMAP_I2C_STAT_XRDY) | 736 | if (stat & OMAP_I2C_STAT_XRDY) |
733 | num_bytes = dev->fifo_size; | 737 | num_bytes = dev->fifo_size; |
734 | else | 738 | else /* read TXSTAT on XDR interrupt */ |
735 | num_bytes = omap_i2c_read_reg(dev, | 739 | num_bytes = omap_i2c_read_reg(dev, |
736 | OMAP_I2C_BUFSTAT_REG); | 740 | OMAP_I2C_BUFSTAT_REG) |
741 | & 0x3F; | ||
737 | } | 742 | } |
738 | while (num_bytes) { | 743 | while (num_bytes) { |
739 | num_bytes--; | 744 | num_bytes--; |
@@ -760,6 +765,27 @@ omap_i2c_isr(int this_irq, void *dev_id) | |||
760 | "data to send\n"); | 765 | "data to send\n"); |
761 | break; | 766 | break; |
762 | } | 767 | } |
768 | |||
769 | /* | ||
770 | * OMAP3430 Errata 1.153: When an XRDY/XDR | ||
771 | * is hit, wait for XUDF before writing data | ||
772 | * to DATA_REG. Otherwise some data bytes can | ||
773 | * be lost while transferring them from the | ||
774 | * memory to the I2C interface. | ||
775 | */ | ||
776 | |||
777 | if (cpu_is_omap34xx()) { | ||
778 | while (!(stat & OMAP_I2C_STAT_XUDF)) { | ||
779 | if (stat & (OMAP_I2C_STAT_NACK | OMAP_I2C_STAT_AL)) { | ||
780 | omap_i2c_ack_stat(dev, stat & (OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR)); | ||
781 | err |= OMAP_I2C_STAT_XUDF; | ||
782 | goto complete; | ||
783 | } | ||
784 | cpu_relax(); | ||
785 | stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG); | ||
786 | } | ||
787 | } | ||
788 | |||
763 | omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w); | 789 | omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w); |
764 | } | 790 | } |
765 | omap_i2c_ack_stat(dev, | 791 | omap_i2c_ack_stat(dev, |
@@ -879,7 +905,7 @@ omap_i2c_probe(struct platform_device *pdev) | |||
879 | i2c_set_adapdata(adap, dev); | 905 | i2c_set_adapdata(adap, dev); |
880 | adap->owner = THIS_MODULE; | 906 | adap->owner = THIS_MODULE; |
881 | adap->class = I2C_CLASS_HWMON; | 907 | adap->class = I2C_CLASS_HWMON; |
882 | strncpy(adap->name, "OMAP I2C adapter", sizeof(adap->name)); | 908 | strlcpy(adap->name, "OMAP I2C adapter", sizeof(adap->name)); |
883 | adap->algo = &omap_i2c_algo; | 909 | adap->algo = &omap_i2c_algo; |
884 | adap->dev.parent = &pdev->dev; | 910 | adap->dev.parent = &pdev->dev; |
885 | 911 | ||
diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c index 762e1e530882..049555777f67 100644 --- a/drivers/i2c/busses/i2c-pxa.c +++ b/drivers/i2c/busses/i2c-pxa.c | |||
@@ -1134,35 +1134,44 @@ static int __exit i2c_pxa_remove(struct platform_device *dev) | |||
1134 | } | 1134 | } |
1135 | 1135 | ||
1136 | #ifdef CONFIG_PM | 1136 | #ifdef CONFIG_PM |
1137 | static int i2c_pxa_suspend_late(struct platform_device *dev, pm_message_t state) | 1137 | static int i2c_pxa_suspend_noirq(struct device *dev) |
1138 | { | 1138 | { |
1139 | struct pxa_i2c *i2c = platform_get_drvdata(dev); | 1139 | struct platform_device *pdev = to_platform_device(dev); |
1140 | struct pxa_i2c *i2c = platform_get_drvdata(pdev); | ||
1141 | |||
1140 | clk_disable(i2c->clk); | 1142 | clk_disable(i2c->clk); |
1143 | |||
1141 | return 0; | 1144 | return 0; |
1142 | } | 1145 | } |
1143 | 1146 | ||
1144 | static int i2c_pxa_resume_early(struct platform_device *dev) | 1147 | static int i2c_pxa_resume_noirq(struct device *dev) |
1145 | { | 1148 | { |
1146 | struct pxa_i2c *i2c = platform_get_drvdata(dev); | 1149 | struct platform_device *pdev = to_platform_device(dev); |
1150 | struct pxa_i2c *i2c = platform_get_drvdata(pdev); | ||
1147 | 1151 | ||
1148 | clk_enable(i2c->clk); | 1152 | clk_enable(i2c->clk); |
1149 | i2c_pxa_reset(i2c); | 1153 | i2c_pxa_reset(i2c); |
1150 | 1154 | ||
1151 | return 0; | 1155 | return 0; |
1152 | } | 1156 | } |
1157 | |||
1158 | static struct dev_pm_ops i2c_pxa_dev_pm_ops = { | ||
1159 | .suspend_noirq = i2c_pxa_suspend_noirq, | ||
1160 | .resume_noirq = i2c_pxa_resume_noirq, | ||
1161 | }; | ||
1162 | |||
1163 | #define I2C_PXA_DEV_PM_OPS (&i2c_pxa_dev_pm_ops) | ||
1153 | #else | 1164 | #else |
1154 | #define i2c_pxa_suspend_late NULL | 1165 | #define I2C_PXA_DEV_PM_OPS NULL |
1155 | #define i2c_pxa_resume_early NULL | ||
1156 | #endif | 1166 | #endif |
1157 | 1167 | ||
1158 | static struct platform_driver i2c_pxa_driver = { | 1168 | static struct platform_driver i2c_pxa_driver = { |
1159 | .probe = i2c_pxa_probe, | 1169 | .probe = i2c_pxa_probe, |
1160 | .remove = __exit_p(i2c_pxa_remove), | 1170 | .remove = __exit_p(i2c_pxa_remove), |
1161 | .suspend_late = i2c_pxa_suspend_late, | ||
1162 | .resume_early = i2c_pxa_resume_early, | ||
1163 | .driver = { | 1171 | .driver = { |
1164 | .name = "pxa2xx-i2c", | 1172 | .name = "pxa2xx-i2c", |
1165 | .owner = THIS_MODULE, | 1173 | .owner = THIS_MODULE, |
1174 | .pm = I2C_PXA_DEV_PM_OPS, | ||
1166 | }, | 1175 | }, |
1167 | .id_table = i2c_pxa_id_table, | 1176 | .id_table = i2c_pxa_id_table, |
1168 | }; | 1177 | }; |
diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c index 8f42a4536cdf..96aafb91b69a 100644 --- a/drivers/i2c/busses/i2c-s3c2410.c +++ b/drivers/i2c/busses/i2c-s3c2410.c | |||
@@ -763,11 +763,6 @@ static int s3c24xx_i2c_init(struct s3c24xx_i2c *i2c) | |||
763 | dev_info(i2c->dev, "bus frequency set to %d KHz\n", freq); | 763 | dev_info(i2c->dev, "bus frequency set to %d KHz\n", freq); |
764 | dev_dbg(i2c->dev, "S3C2410_IICCON=0x%02lx\n", iicon); | 764 | dev_dbg(i2c->dev, "S3C2410_IICCON=0x%02lx\n", iicon); |
765 | 765 | ||
766 | /* check for s3c2440 i2c controller */ | ||
767 | |||
768 | if (s3c24xx_i2c_is2440(i2c)) | ||
769 | writel(0x0, i2c->regs + S3C2440_IICLC); | ||
770 | |||
771 | return 0; | 766 | return 0; |
772 | } | 767 | } |
773 | 768 | ||
@@ -951,17 +946,20 @@ static int s3c24xx_i2c_remove(struct platform_device *pdev) | |||
951 | } | 946 | } |
952 | 947 | ||
953 | #ifdef CONFIG_PM | 948 | #ifdef CONFIG_PM |
954 | static int s3c24xx_i2c_suspend_late(struct platform_device *dev, | 949 | static int s3c24xx_i2c_suspend_noirq(struct device *dev) |
955 | pm_message_t msg) | ||
956 | { | 950 | { |
957 | struct s3c24xx_i2c *i2c = platform_get_drvdata(dev); | 951 | struct platform_device *pdev = to_platform_device(dev); |
952 | struct s3c24xx_i2c *i2c = platform_get_drvdata(pdev); | ||
953 | |||
958 | i2c->suspended = 1; | 954 | i2c->suspended = 1; |
955 | |||
959 | return 0; | 956 | return 0; |
960 | } | 957 | } |
961 | 958 | ||
962 | static int s3c24xx_i2c_resume(struct platform_device *dev) | 959 | static int s3c24xx_i2c_resume(struct device *dev) |
963 | { | 960 | { |
964 | struct s3c24xx_i2c *i2c = platform_get_drvdata(dev); | 961 | struct platform_device *pdev = to_platform_device(dev); |
962 | struct s3c24xx_i2c *i2c = platform_get_drvdata(pdev); | ||
965 | 963 | ||
966 | i2c->suspended = 0; | 964 | i2c->suspended = 0; |
967 | s3c24xx_i2c_init(i2c); | 965 | s3c24xx_i2c_init(i2c); |
@@ -969,9 +967,14 @@ static int s3c24xx_i2c_resume(struct platform_device *dev) | |||
969 | return 0; | 967 | return 0; |
970 | } | 968 | } |
971 | 969 | ||
970 | static struct dev_pm_ops s3c24xx_i2c_dev_pm_ops = { | ||
971 | .suspend_noirq = s3c24xx_i2c_suspend_noirq, | ||
972 | .resume = s3c24xx_i2c_resume, | ||
973 | }; | ||
974 | |||
975 | #define S3C24XX_DEV_PM_OPS (&s3c24xx_i2c_dev_pm_ops) | ||
972 | #else | 976 | #else |
973 | #define s3c24xx_i2c_suspend_late NULL | 977 | #define S3C24XX_DEV_PM_OPS NULL |
974 | #define s3c24xx_i2c_resume NULL | ||
975 | #endif | 978 | #endif |
976 | 979 | ||
977 | /* device driver for platform bus bits */ | 980 | /* device driver for platform bus bits */ |
@@ -990,12 +993,11 @@ MODULE_DEVICE_TABLE(platform, s3c24xx_driver_ids); | |||
990 | static struct platform_driver s3c24xx_i2c_driver = { | 993 | static struct platform_driver s3c24xx_i2c_driver = { |
991 | .probe = s3c24xx_i2c_probe, | 994 | .probe = s3c24xx_i2c_probe, |
992 | .remove = s3c24xx_i2c_remove, | 995 | .remove = s3c24xx_i2c_remove, |
993 | .suspend_late = s3c24xx_i2c_suspend_late, | ||
994 | .resume = s3c24xx_i2c_resume, | ||
995 | .id_table = s3c24xx_driver_ids, | 996 | .id_table = s3c24xx_driver_ids, |
996 | .driver = { | 997 | .driver = { |
997 | .owner = THIS_MODULE, | 998 | .owner = THIS_MODULE, |
998 | .name = "s3c-i2c", | 999 | .name = "s3c-i2c", |
1000 | .pm = S3C24XX_DEV_PM_OPS, | ||
999 | }, | 1001 | }, |
1000 | }; | 1002 | }; |
1001 | 1003 | ||
diff --git a/drivers/i2c/chips/tsl2550.c b/drivers/i2c/chips/tsl2550.c index 1a9cc135219f..b96f3025e588 100644 --- a/drivers/i2c/chips/tsl2550.c +++ b/drivers/i2c/chips/tsl2550.c | |||
@@ -27,7 +27,7 @@ | |||
27 | #include <linux/delay.h> | 27 | #include <linux/delay.h> |
28 | 28 | ||
29 | #define TSL2550_DRV_NAME "tsl2550" | 29 | #define TSL2550_DRV_NAME "tsl2550" |
30 | #define DRIVER_VERSION "1.1.1" | 30 | #define DRIVER_VERSION "1.1.2" |
31 | 31 | ||
32 | /* | 32 | /* |
33 | * Defines | 33 | * Defines |
@@ -189,13 +189,16 @@ static int tsl2550_calculate_lux(u8 ch0, u8 ch1) | |||
189 | u8 r = 128; | 189 | u8 r = 128; |
190 | 190 | ||
191 | /* Avoid division by 0 and count 1 cannot be greater than count 0 */ | 191 | /* Avoid division by 0 and count 1 cannot be greater than count 0 */ |
192 | if (c0 && (c1 <= c0)) | 192 | if (c1 <= c0) |
193 | r = c1 * 128 / c0; | 193 | if (c0) { |
194 | r = c1 * 128 / c0; | ||
195 | |||
196 | /* Calculate LUX */ | ||
197 | lux = ((c0 - c1) * ratio_lut[r]) / 256; | ||
198 | } else | ||
199 | lux = 0; | ||
194 | else | 200 | else |
195 | return -1; | 201 | return -EAGAIN; |
196 | |||
197 | /* Calculate LUX */ | ||
198 | lux = ((c0 - c1) * ratio_lut[r]) / 256; | ||
199 | 202 | ||
200 | /* LUX range check */ | 203 | /* LUX range check */ |
201 | return lux > TSL2550_MAX_LUX ? TSL2550_MAX_LUX : lux; | 204 | return lux > TSL2550_MAX_LUX ? TSL2550_MAX_LUX : lux; |