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>
This commit is contained in:
Doug Anderson 2013-03-13 20:40:00 +00:00 committed by Jonathan Cameron
parent f2f7a44970
commit bb916ebbea
2 changed files with 15 additions and 3 deletions

View File

@ -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;

View File

@ -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);