Browse Source

iio: adc: Add dt support for turning on the phy in exynos-adc

Without this change the exynos adc controller needed to have its phy
enabled in some out-of-driver C code.  Add support for specifying the
phy enable register by listing it in the reg list.

Signed-off-by: Doug Anderson <dianders@chromium.org>
Tested-by: Naveen Krishna Chatradhi <ch.naveen@samsung.com>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
Doug Anderson 12 years ago
parent
commit
bb916ebbea

+ 2 - 2
Documentation/devicetree/bindings/arm/samsung/exynos-adc.txt

@@ -15,7 +15,7 @@ Required properties:
 			Must be "samsung,exynos-adc-v2" for
 			Must be "samsung,exynos-adc-v2" for
 				future controllers.
 				future controllers.
 - reg:			Contains ADC register address range (base address and
 - reg:			Contains ADC register address range (base address and
-			length).
+			length) and the address of the phy enable register.
 - interrupts: 		Contains the interrupt information for the timer. The
 - interrupts: 		Contains the interrupt information for the timer. The
 			format is being dependent on which interrupt controller
 			format is being dependent on which interrupt controller
 			the Samsung device uses.
 			the Samsung device uses.
@@ -27,7 +27,7 @@ Example: adding device info in dtsi file
 
 
 adc: adc@12D10000 {
 adc: adc@12D10000 {
 	compatible = "samsung,exynos-adc-v1";
 	compatible = "samsung,exynos-adc-v1";
-	reg = <0x12D10000 0x100>;
+	reg = <0x12D10000 0x100>, <0x10040718 0x4>;
 	interrupts = <0 106 0>;
 	interrupts = <0 106 0>;
 	#io-channel-cells = <1>;
 	#io-channel-cells = <1>;
 	io-channel-ranges;
 	io-channel-ranges;

+ 13 - 1
drivers/iio/adc/exynos_adc.c

@@ -85,6 +85,7 @@ enum adc_version {
 
 
 struct exynos_adc {
 struct exynos_adc {
 	void __iomem		*regs;
 	void __iomem		*regs;
+	void __iomem		*enable_reg;
 	struct clk		*clk;
 	struct clk		*clk;
 	unsigned int		irq;
 	unsigned int		irq;
 	struct regulator	*vdd;
 	struct regulator	*vdd;
@@ -269,13 +270,19 @@ static int exynos_adc_probe(struct platform_device *pdev)
 	info = iio_priv(indio_dev);
 	info = iio_priv(indio_dev);
 
 
 	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-
 	info->regs = devm_request_and_ioremap(&pdev->dev, mem);
 	info->regs = devm_request_and_ioremap(&pdev->dev, mem);
 	if (!info->regs) {
 	if (!info->regs) {
 		ret = -ENOMEM;
 		ret = -ENOMEM;
 		goto err_iio;
 		goto err_iio;
 	}
 	}
 
 
+	mem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	info->enable_reg = devm_request_and_ioremap(&pdev->dev, mem);
+	if (!info->enable_reg) {
+		ret = -ENOMEM;
+		goto err_iio;
+	}
+
 	irq = platform_get_irq(pdev, 0);
 	irq = platform_get_irq(pdev, 0);
 	if (irq < 0) {
 	if (irq < 0) {
 		dev_err(&pdev->dev, "no irq resource?\n");
 		dev_err(&pdev->dev, "no irq resource?\n");
@@ -295,6 +302,8 @@ static int exynos_adc_probe(struct platform_device *pdev)
 		goto err_iio;
 		goto err_iio;
 	}
 	}
 
 
+	writel(1, info->enable_reg);
+
 	info->clk = devm_clk_get(&pdev->dev, "adc");
 	info->clk = devm_clk_get(&pdev->dev, "adc");
 	if (IS_ERR(info->clk)) {
 	if (IS_ERR(info->clk)) {
 		dev_err(&pdev->dev, "failed getting clock, err = %ld\n",
 		dev_err(&pdev->dev, "failed getting clock, err = %ld\n",
@@ -370,6 +379,7 @@ static int exynos_adc_remove(struct platform_device *pdev)
 				exynos_adc_remove_devices);
 				exynos_adc_remove_devices);
 	regulator_disable(info->vdd);
 	regulator_disable(info->vdd);
 	clk_disable_unprepare(info->clk);
 	clk_disable_unprepare(info->clk);
+	writel(0, info->enable_reg);
 	iio_device_unregister(indio_dev);
 	iio_device_unregister(indio_dev);
 	free_irq(info->irq, info);
 	free_irq(info->irq, info);
 	iio_device_free(indio_dev);
 	iio_device_free(indio_dev);
@@ -395,6 +405,7 @@ static int exynos_adc_suspend(struct device *dev)
 	}
 	}
 
 
 	clk_disable_unprepare(info->clk);
 	clk_disable_unprepare(info->clk);
+	writel(0, info->enable_reg);
 	regulator_disable(info->vdd);
 	regulator_disable(info->vdd);
 
 
 	return 0;
 	return 0;
@@ -410,6 +421,7 @@ static int exynos_adc_resume(struct device *dev)
 	if (ret)
 	if (ret)
 		return ret;
 		return ret;
 
 
+	writel(1, info->enable_reg);
 	clk_prepare_enable(info->clk);
 	clk_prepare_enable(info->clk);
 
 
 	exynos_adc_hw_init(info);
 	exynos_adc_hw_init(info);