diff options
author | Lee Jones <lee.jones@linaro.org> | 2013-02-12 10:04:09 -0500 |
---|---|---|
committer | Lee Jones <lee.jones@linaro.org> | 2013-03-06 23:27:36 -0500 |
commit | c0eda9aef1c0ef7bb2812b739ddf400405568bef (patch) | |
tree | 021e3a942f61d2a6ecc8df809c7f0397ffc0fa76 /drivers | |
parent | 5ff9090f3de360578a2a4f53812fcfce761bfaaa (diff) |
mfd: ab8500-core: Add ADC support for ab8540
Signed-off-by: Lee Jones <lee.jones@linaro.org>
Acked-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mfd/ab8500-core.c | 74 | ||||
-rw-r--r-- | drivers/mfd/ab8500-gpadc.c | 67 |
2 files changed, 98 insertions, 43 deletions
diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c index baaf2ed8095b..cdf6c1e59bc3 100644 --- a/drivers/mfd/ab8500-core.c +++ b/drivers/mfd/ab8500-core.c | |||
@@ -658,6 +658,15 @@ static struct resource ab8500_gpadc_resources[] = { | |||
658 | }, | 658 | }, |
659 | }; | 659 | }; |
660 | 660 | ||
661 | static struct resource ab8540_gpadc_resources[] = { | ||
662 | { | ||
663 | .name = "SW_CONV_END", | ||
664 | .start = AB8500_INT_GP_SW_ADC_CONV_END, | ||
665 | .end = AB8500_INT_GP_SW_ADC_CONV_END, | ||
666 | .flags = IORESOURCE_IRQ, | ||
667 | }, | ||
668 | }; | ||
669 | |||
661 | static struct resource ab8500_rtc_resources[] = { | 670 | static struct resource ab8500_rtc_resources[] = { |
662 | { | 671 | { |
663 | .name = "60S", | 672 | .name = "60S", |
@@ -1014,12 +1023,6 @@ static struct mfd_cell abx500_common_devs[] = { | |||
1014 | .of_compatible = "stericsson,abx500-clk", | 1023 | .of_compatible = "stericsson,abx500-clk", |
1015 | }, | 1024 | }, |
1016 | { | 1025 | { |
1017 | .name = "ab8500-gpadc", | ||
1018 | .of_compatible = "stericsson,ab8500-gpadc", | ||
1019 | .num_resources = ARRAY_SIZE(ab8500_gpadc_resources), | ||
1020 | .resources = ab8500_gpadc_resources, | ||
1021 | }, | ||
1022 | { | ||
1023 | .name = "ab8500-rtc", | 1026 | .name = "ab8500-rtc", |
1024 | .of_compatible = "stericsson,ab8500-rtc", | 1027 | .of_compatible = "stericsson,ab8500-rtc", |
1025 | .num_resources = ARRAY_SIZE(ab8500_rtc_resources), | 1028 | .num_resources = ARRAY_SIZE(ab8500_rtc_resources), |
@@ -1118,6 +1121,12 @@ static struct mfd_cell ab8500_devs[] = { | |||
1118 | .name = "ab8500-codec", | 1121 | .name = "ab8500-codec", |
1119 | .of_compatible = "stericsson,ab8500-codec", | 1122 | .of_compatible = "stericsson,ab8500-codec", |
1120 | }, | 1123 | }, |
1124 | { | ||
1125 | .name = "ab8500-gpadc", | ||
1126 | .of_compatible = "stericsson,ab8500-gpadc", | ||
1127 | .num_resources = ARRAY_SIZE(ab8500_gpadc_resources), | ||
1128 | .resources = ab8500_gpadc_resources, | ||
1129 | }, | ||
1121 | }; | 1130 | }; |
1122 | 1131 | ||
1123 | static struct mfd_cell ab9540_devs[] = { | 1132 | static struct mfd_cell ab9540_devs[] = { |
@@ -1133,10 +1142,44 @@ static struct mfd_cell ab9540_devs[] = { | |||
1133 | { | 1142 | { |
1134 | .name = "ab9540-codec", | 1143 | .name = "ab9540-codec", |
1135 | }, | 1144 | }, |
1145 | { | ||
1146 | .name = "ab8500-gpadc", | ||
1147 | .num_resources = ARRAY_SIZE(ab8500_gpadc_resources), | ||
1148 | .resources = ab8500_gpadc_resources, | ||
1149 | }, | ||
1150 | { | ||
1151 | .name = "ab-iddet", | ||
1152 | .num_resources = ARRAY_SIZE(ab8505_iddet_resources), | ||
1153 | .resources = ab8505_iddet_resources, | ||
1154 | }, | ||
1136 | }; | 1155 | }; |
1137 | 1156 | ||
1138 | /* Device list common to ab9540 and ab8505 */ | 1157 | /* Device list for ab8505 */ |
1139 | static struct mfd_cell ab9540_ab8505_devs[] = { | 1158 | static struct mfd_cell ab8505_devs[] = { |
1159 | { | ||
1160 | .name = "ab-iddet", | ||
1161 | .num_resources = ARRAY_SIZE(ab8505_iddet_resources), | ||
1162 | .resources = ab8505_iddet_resources, | ||
1163 | }, | ||
1164 | }; | ||
1165 | |||
1166 | static struct mfd_cell ab8540_devs[] = { | ||
1167 | { | ||
1168 | .name = "ab8500-gpio", | ||
1169 | }, | ||
1170 | { | ||
1171 | .name = "ab8540-usb", | ||
1172 | .num_resources = ARRAY_SIZE(ab8500_usb_resources), | ||
1173 | .resources = ab8500_usb_resources, | ||
1174 | }, | ||
1175 | { | ||
1176 | .name = "ab8540-codec", | ||
1177 | }, | ||
1178 | { | ||
1179 | .name = "ab8500-gpadc", | ||
1180 | .num_resources = ARRAY_SIZE(ab8540_gpadc_resources), | ||
1181 | .resources = ab8540_gpadc_resources, | ||
1182 | }, | ||
1140 | { | 1183 | { |
1141 | .name = "ab-iddet", | 1184 | .name = "ab-iddet", |
1142 | .num_resources = ARRAY_SIZE(ab8505_iddet_resources), | 1185 | .num_resources = ARRAY_SIZE(ab8505_iddet_resources), |
@@ -1495,6 +1538,14 @@ static int ab8500_probe(struct platform_device *pdev) | |||
1495 | ret = mfd_add_devices(ab8500->dev, 0, ab9540_devs, | 1538 | ret = mfd_add_devices(ab8500->dev, 0, ab9540_devs, |
1496 | ARRAY_SIZE(ab9540_devs), NULL, | 1539 | ARRAY_SIZE(ab9540_devs), NULL, |
1497 | ab8500->irq_base, ab8500->domain); | 1540 | ab8500->irq_base, ab8500->domain); |
1541 | else if (is_ab8540(ab8500)) | ||
1542 | ret = mfd_add_devices(ab8500->dev, 0, ab8540_devs, | ||
1543 | ARRAY_SIZE(ab8540_devs), NULL, | ||
1544 | ab8500->irq_base, ab8500->domain); | ||
1545 | else if (is_ab8505(ab8500)) | ||
1546 | ret = mfd_add_devices(ab8500->dev, 0, ab8505_devs, | ||
1547 | ARRAY_SIZE(ab8505_devs), NULL, | ||
1548 | ab8500->irq_base, ab8500->domain); | ||
1498 | else | 1549 | else |
1499 | ret = mfd_add_devices(ab8500->dev, 0, ab8500_devs, | 1550 | ret = mfd_add_devices(ab8500->dev, 0, ab8500_devs, |
1500 | ARRAY_SIZE(ab8500_devs), NULL, | 1551 | ARRAY_SIZE(ab8500_devs), NULL, |
@@ -1502,13 +1553,6 @@ static int ab8500_probe(struct platform_device *pdev) | |||
1502 | if (ret) | 1553 | if (ret) |
1503 | return ret; | 1554 | return ret; |
1504 | 1555 | ||
1505 | if (is_ab9540(ab8500) || is_ab8505(ab8500)) | ||
1506 | ret = mfd_add_devices(ab8500->dev, 0, ab9540_ab8505_devs, | ||
1507 | ARRAY_SIZE(ab9540_ab8505_devs), NULL, | ||
1508 | ab8500->irq_base, ab8500->domain); | ||
1509 | if (ret) | ||
1510 | return ret; | ||
1511 | |||
1512 | if (!no_bm) { | 1556 | if (!no_bm) { |
1513 | /* Add battery management devices */ | 1557 | /* Add battery management devices */ |
1514 | ret = mfd_add_devices(ab8500->dev, 0, ab8500_bm_devs, | 1558 | ret = mfd_add_devices(ab8500->dev, 0, ab8500_bm_devs, |
diff --git a/drivers/mfd/ab8500-gpadc.c b/drivers/mfd/ab8500-gpadc.c index 8673bf66f7d7..fc8da4496e84 100644 --- a/drivers/mfd/ab8500-gpadc.c +++ b/drivers/mfd/ab8500-gpadc.c | |||
@@ -311,6 +311,12 @@ int ab8500_gpadc_read_raw(struct ab8500_gpadc *gpadc, u8 channel, | |||
311 | if (!gpadc) | 311 | if (!gpadc) |
312 | return -ENODEV; | 312 | return -ENODEV; |
313 | 313 | ||
314 | /* check if convertion is supported */ | ||
315 | if ((gpadc->irq_sw < 0) && (conv_type == ADC_SW)) | ||
316 | return -ENOTSUPP; | ||
317 | if ((gpadc->irq_hw < 0) && (conv_type == ADC_HW)) | ||
318 | return -ENOTSUPP; | ||
319 | |||
314 | mutex_lock(&gpadc->ab8500_gpadc_lock); | 320 | mutex_lock(&gpadc->ab8500_gpadc_lock); |
315 | /* Enable VTVout LDO this is required for GPADC */ | 321 | /* Enable VTVout LDO this is required for GPADC */ |
316 | pm_runtime_get_sync(gpadc->dev); | 322 | pm_runtime_get_sync(gpadc->dev); |
@@ -761,20 +767,12 @@ static int ab8500_gpadc_probe(struct platform_device *pdev) | |||
761 | } | 767 | } |
762 | 768 | ||
763 | gpadc->irq_sw = platform_get_irq_byname(pdev, "SW_CONV_END"); | 769 | gpadc->irq_sw = platform_get_irq_byname(pdev, "SW_CONV_END"); |
764 | if (gpadc->irq_sw < 0) { | 770 | if (gpadc->irq_sw < 0) |
765 | dev_err(gpadc->dev, "failed to get platform irq-%d\n", | 771 | dev_err(gpadc->dev, "failed to get platform sw_conv_end irq\n"); |
766 | gpadc->irq_sw); | ||
767 | ret = gpadc->irq_sw; | ||
768 | goto fail; | ||
769 | } | ||
770 | 772 | ||
771 | gpadc->irq_hw = platform_get_irq_byname(pdev, "HW_CONV_END"); | 773 | gpadc->irq_hw = platform_get_irq_byname(pdev, "HW_CONV_END"); |
772 | if (gpadc->irq_hw < 0) { | 774 | if (gpadc->irq_hw < 0) |
773 | dev_err(gpadc->dev, "failed to get platform irq-%d\n", | 775 | dev_err(gpadc->dev, "failed to get platform hw_conv_end irq\n"); |
774 | gpadc->irq_hw); | ||
775 | ret = gpadc->irq_hw; | ||
776 | goto fail; | ||
777 | } | ||
778 | 776 | ||
779 | gpadc->dev = &pdev->dev; | 777 | gpadc->dev = &pdev->dev; |
780 | gpadc->parent = dev_get_drvdata(pdev->dev.parent); | 778 | gpadc->parent = dev_get_drvdata(pdev->dev.parent); |
@@ -784,21 +782,30 @@ static int ab8500_gpadc_probe(struct platform_device *pdev) | |||
784 | init_completion(&gpadc->ab8500_gpadc_complete); | 782 | init_completion(&gpadc->ab8500_gpadc_complete); |
785 | 783 | ||
786 | /* Register interrupts */ | 784 | /* Register interrupts */ |
787 | ret = request_threaded_irq(gpadc->irq_sw, NULL, | 785 | if (gpadc->irq_sw >= 0) { |
788 | ab8500_bm_gpadcconvend_handler, | 786 | ret = request_threaded_irq(gpadc->irq_sw, NULL, |
789 | IRQF_NO_SUSPEND | IRQF_SHARED, "ab8500-gpadc-sw", gpadc); | 787 | ab8500_bm_gpadcconvend_handler, |
790 | if (ret < 0) { | 788 | IRQF_NO_SUSPEND | IRQF_SHARED, "ab8500-gpadc-sw", |
791 | dev_err(gpadc->dev, "Failed to register interrupt, irq: %d\n", | 789 | gpadc); |
792 | gpadc->irq_sw); | 790 | if (ret < 0) { |
793 | goto fail; | 791 | dev_err(gpadc->dev, |
792 | "Failed to register interrupt irq: %d\n", | ||
793 | gpadc->irq_sw); | ||
794 | goto fail; | ||
795 | } | ||
794 | } | 796 | } |
795 | ret = request_threaded_irq(gpadc->irq_hw, NULL, | 797 | |
796 | ab8500_bm_gpadcconvend_handler, | 798 | if (gpadc->irq_hw >= 0) { |
797 | IRQF_NO_SUSPEND | IRQF_SHARED, "ab8500-gpadc-hw", gpadc); | 799 | ret = request_threaded_irq(gpadc->irq_hw, NULL, |
798 | if (ret < 0) { | 800 | ab8500_bm_gpadcconvend_handler, |
799 | dev_err(gpadc->dev, "Failed to register interrupt, irq: %d\n", | 801 | IRQF_NO_SUSPEND | IRQF_SHARED, "ab8500-gpadc-hw", |
800 | gpadc->irq_hw); | 802 | gpadc); |
801 | goto fail; | 803 | if (ret < 0) { |
804 | dev_err(gpadc->dev, | ||
805 | "Failed to register interrupt irq: %d\n", | ||
806 | gpadc->irq_hw); | ||
807 | goto fail_irq; | ||
808 | } | ||
802 | } | 809 | } |
803 | 810 | ||
804 | /* VTVout LDO used to power up ab8500-GPADC */ | 811 | /* VTVout LDO used to power up ab8500-GPADC */ |
@@ -821,7 +828,9 @@ static int ab8500_gpadc_probe(struct platform_device *pdev) | |||
821 | ab8500_gpadc_read_calibration_data(gpadc); | 828 | ab8500_gpadc_read_calibration_data(gpadc); |
822 | list_add_tail(&gpadc->node, &ab8500_gpadc_list); | 829 | list_add_tail(&gpadc->node, &ab8500_gpadc_list); |
823 | dev_dbg(gpadc->dev, "probe success\n"); | 830 | dev_dbg(gpadc->dev, "probe success\n"); |
831 | |||
824 | return 0; | 832 | return 0; |
833 | |||
825 | fail_irq: | 834 | fail_irq: |
826 | free_irq(gpadc->irq_sw, gpadc); | 835 | free_irq(gpadc->irq_sw, gpadc); |
827 | free_irq(gpadc->irq_hw, gpadc); | 836 | free_irq(gpadc->irq_hw, gpadc); |
@@ -838,8 +847,10 @@ static int ab8500_gpadc_remove(struct platform_device *pdev) | |||
838 | /* remove this gpadc entry from the list */ | 847 | /* remove this gpadc entry from the list */ |
839 | list_del(&gpadc->node); | 848 | list_del(&gpadc->node); |
840 | /* remove interrupt - completion of Sw ADC conversion */ | 849 | /* remove interrupt - completion of Sw ADC conversion */ |
841 | free_irq(gpadc->irq_sw, gpadc); | 850 | if (gpadc->irq_sw >= 0) |
842 | free_irq(gpadc->irq_hw, gpadc); | 851 | free_irq(gpadc->irq_sw, gpadc); |
852 | if (gpadc->irq_hw >= 0) | ||
853 | free_irq(gpadc->irq_hw, gpadc); | ||
843 | 854 | ||
844 | pm_runtime_get_sync(gpadc->dev); | 855 | pm_runtime_get_sync(gpadc->dev); |
845 | pm_runtime_disable(gpadc->dev); | 856 | pm_runtime_disable(gpadc->dev); |