aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLee Jones <lee.jones@linaro.org>2013-02-12 10:04:09 -0500
committerLee Jones <lee.jones@linaro.org>2013-03-06 23:27:36 -0500
commitc0eda9aef1c0ef7bb2812b739ddf400405568bef (patch)
tree021e3a942f61d2a6ecc8df809c7f0397ffc0fa76 /drivers
parent5ff9090f3de360578a2a4f53812fcfce761bfaaa (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.c74
-rw-r--r--drivers/mfd/ab8500-gpadc.c67
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
661static 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
661static struct resource ab8500_rtc_resources[] = { 670static 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
1123static struct mfd_cell ab9540_devs[] = { 1132static 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 */
1139static struct mfd_cell ab9540_ab8505_devs[] = { 1158static 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
1166static 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
825fail_irq: 834fail_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);