1c942fddfSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later 244d6f2efSHeiko Stübner /* 344d6f2efSHeiko Stübner * Rockchip Successive Approximation Register (SAR) A/D Converter 444d6f2efSHeiko Stübner * Copyright (C) 2014 ROCKCHIP, Inc. 544d6f2efSHeiko Stübner */ 644d6f2efSHeiko Stübner 744d6f2efSHeiko Stübner #include <linux/module.h> 844d6f2efSHeiko Stübner #include <linux/platform_device.h> 944d6f2efSHeiko Stübner #include <linux/interrupt.h> 1044d6f2efSHeiko Stübner #include <linux/io.h> 1144d6f2efSHeiko Stübner #include <linux/of.h> 124c21bbb4SHeiko Stübner #include <linux/of_device.h> 1344d6f2efSHeiko Stübner #include <linux/clk.h> 1444d6f2efSHeiko Stübner #include <linux/completion.h> 15543852afSCaesar Wang #include <linux/delay.h> 16543852afSCaesar Wang #include <linux/reset.h> 1744d6f2efSHeiko Stübner #include <linux/regulator/consumer.h> 1844d6f2efSHeiko Stübner #include <linux/iio/iio.h> 1944d6f2efSHeiko Stübner 2044d6f2efSHeiko Stübner #define SARADC_DATA 0x00 2144d6f2efSHeiko Stübner 2244d6f2efSHeiko Stübner #define SARADC_STAS 0x04 2344d6f2efSHeiko Stübner #define SARADC_STAS_BUSY BIT(0) 2444d6f2efSHeiko Stübner 2544d6f2efSHeiko Stübner #define SARADC_CTRL 0x08 2644d6f2efSHeiko Stübner #define SARADC_CTRL_IRQ_STATUS BIT(6) 2744d6f2efSHeiko Stübner #define SARADC_CTRL_IRQ_ENABLE BIT(5) 2844d6f2efSHeiko Stübner #define SARADC_CTRL_POWER_CTRL BIT(3) 2944d6f2efSHeiko Stübner #define SARADC_CTRL_CHN_MASK 0x7 3044d6f2efSHeiko Stübner 3144d6f2efSHeiko Stübner #define SARADC_DLY_PU_SOC 0x0c 3244d6f2efSHeiko Stübner #define SARADC_DLY_PU_SOC_MASK 0x3f 3344d6f2efSHeiko Stübner 3444d6f2efSHeiko Stübner #define SARADC_TIMEOUT msecs_to_jiffies(100) 3544d6f2efSHeiko Stübner 364c21bbb4SHeiko Stübner struct rockchip_saradc_data { 374c21bbb4SHeiko Stübner int num_bits; 384c21bbb4SHeiko Stübner const struct iio_chan_spec *channels; 394c21bbb4SHeiko Stübner int num_channels; 404c21bbb4SHeiko Stübner unsigned long clk_rate; 414c21bbb4SHeiko Stübner }; 424c21bbb4SHeiko Stübner 4344d6f2efSHeiko Stübner struct rockchip_saradc { 4444d6f2efSHeiko Stübner void __iomem *regs; 4544d6f2efSHeiko Stübner struct clk *pclk; 4644d6f2efSHeiko Stübner struct clk *clk; 4744d6f2efSHeiko Stübner struct completion completion; 4844d6f2efSHeiko Stübner struct regulator *vref; 49543852afSCaesar Wang struct reset_control *reset; 504c21bbb4SHeiko Stübner const struct rockchip_saradc_data *data; 5144d6f2efSHeiko Stübner u16 last_val; 5244d6f2efSHeiko Stübner }; 5344d6f2efSHeiko Stübner 5444d6f2efSHeiko Stübner static int rockchip_saradc_read_raw(struct iio_dev *indio_dev, 5544d6f2efSHeiko Stübner struct iio_chan_spec const *chan, 5644d6f2efSHeiko Stübner int *val, int *val2, long mask) 5744d6f2efSHeiko Stübner { 5844d6f2efSHeiko Stübner struct rockchip_saradc *info = iio_priv(indio_dev); 5944d6f2efSHeiko Stübner int ret; 6044d6f2efSHeiko Stübner 6144d6f2efSHeiko Stübner switch (mask) { 6244d6f2efSHeiko Stübner case IIO_CHAN_INFO_RAW: 6344d6f2efSHeiko Stübner mutex_lock(&indio_dev->mlock); 6444d6f2efSHeiko Stübner 6544d6f2efSHeiko Stübner reinit_completion(&info->completion); 6644d6f2efSHeiko Stübner 6744d6f2efSHeiko Stübner /* 8 clock periods as delay between power up and start cmd */ 6844d6f2efSHeiko Stübner writel_relaxed(8, info->regs + SARADC_DLY_PU_SOC); 6944d6f2efSHeiko Stübner 7044d6f2efSHeiko Stübner /* Select the channel to be used and trigger conversion */ 7144d6f2efSHeiko Stübner writel(SARADC_CTRL_POWER_CTRL 7244d6f2efSHeiko Stübner | (chan->channel & SARADC_CTRL_CHN_MASK) 7344d6f2efSHeiko Stübner | SARADC_CTRL_IRQ_ENABLE, 7444d6f2efSHeiko Stübner info->regs + SARADC_CTRL); 7544d6f2efSHeiko Stübner 7644d6f2efSHeiko Stübner if (!wait_for_completion_timeout(&info->completion, 7744d6f2efSHeiko Stübner SARADC_TIMEOUT)) { 7844d6f2efSHeiko Stübner writel_relaxed(0, info->regs + SARADC_CTRL); 7944d6f2efSHeiko Stübner mutex_unlock(&indio_dev->mlock); 8044d6f2efSHeiko Stübner return -ETIMEDOUT; 8144d6f2efSHeiko Stübner } 8244d6f2efSHeiko Stübner 8344d6f2efSHeiko Stübner *val = info->last_val; 8444d6f2efSHeiko Stübner mutex_unlock(&indio_dev->mlock); 8544d6f2efSHeiko Stübner return IIO_VAL_INT; 8644d6f2efSHeiko Stübner case IIO_CHAN_INFO_SCALE: 8744d6f2efSHeiko Stübner ret = regulator_get_voltage(info->vref); 8844d6f2efSHeiko Stübner if (ret < 0) { 8944d6f2efSHeiko Stübner dev_err(&indio_dev->dev, "failed to get voltage\n"); 9044d6f2efSHeiko Stübner return ret; 9144d6f2efSHeiko Stübner } 9244d6f2efSHeiko Stübner 9344d6f2efSHeiko Stübner *val = ret / 1000; 944c21bbb4SHeiko Stübner *val2 = info->data->num_bits; 9544d6f2efSHeiko Stübner return IIO_VAL_FRACTIONAL_LOG2; 9644d6f2efSHeiko Stübner default: 9744d6f2efSHeiko Stübner return -EINVAL; 9844d6f2efSHeiko Stübner } 9944d6f2efSHeiko Stübner } 10044d6f2efSHeiko Stübner 10144d6f2efSHeiko Stübner static irqreturn_t rockchip_saradc_isr(int irq, void *dev_id) 10244d6f2efSHeiko Stübner { 1030b568b3cSsimran singhal struct rockchip_saradc *info = dev_id; 10444d6f2efSHeiko Stübner 10544d6f2efSHeiko Stübner /* Read value */ 10644d6f2efSHeiko Stübner info->last_val = readl_relaxed(info->regs + SARADC_DATA); 1074c21bbb4SHeiko Stübner info->last_val &= GENMASK(info->data->num_bits - 1, 0); 10844d6f2efSHeiko Stübner 10944d6f2efSHeiko Stübner /* Clear irq & power down adc */ 11044d6f2efSHeiko Stübner writel_relaxed(0, info->regs + SARADC_CTRL); 11144d6f2efSHeiko Stübner 11244d6f2efSHeiko Stübner complete(&info->completion); 11344d6f2efSHeiko Stübner 11444d6f2efSHeiko Stübner return IRQ_HANDLED; 11544d6f2efSHeiko Stübner } 11644d6f2efSHeiko Stübner 11744d6f2efSHeiko Stübner static const struct iio_info rockchip_saradc_iio_info = { 11844d6f2efSHeiko Stübner .read_raw = rockchip_saradc_read_raw, 11944d6f2efSHeiko Stübner }; 12044d6f2efSHeiko Stübner 12144d6f2efSHeiko Stübner #define ADC_CHANNEL(_index, _id) { \ 12244d6f2efSHeiko Stübner .type = IIO_VOLTAGE, \ 12344d6f2efSHeiko Stübner .indexed = 1, \ 12444d6f2efSHeiko Stübner .channel = _index, \ 12544d6f2efSHeiko Stübner .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 12644d6f2efSHeiko Stübner .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ 12744d6f2efSHeiko Stübner .datasheet_name = _id, \ 12844d6f2efSHeiko Stübner } 12944d6f2efSHeiko Stübner 13044d6f2efSHeiko Stübner static const struct iio_chan_spec rockchip_saradc_iio_channels[] = { 13144d6f2efSHeiko Stübner ADC_CHANNEL(0, "adc0"), 13244d6f2efSHeiko Stübner ADC_CHANNEL(1, "adc1"), 13344d6f2efSHeiko Stübner ADC_CHANNEL(2, "adc2"), 13444d6f2efSHeiko Stübner }; 13544d6f2efSHeiko Stübner 1364c21bbb4SHeiko Stübner static const struct rockchip_saradc_data saradc_data = { 1374c21bbb4SHeiko Stübner .num_bits = 10, 1384c21bbb4SHeiko Stübner .channels = rockchip_saradc_iio_channels, 1394c21bbb4SHeiko Stübner .num_channels = ARRAY_SIZE(rockchip_saradc_iio_channels), 1404c21bbb4SHeiko Stübner .clk_rate = 1000000, 1414c21bbb4SHeiko Stübner }; 1424c21bbb4SHeiko Stübner 1434c21bbb4SHeiko Stübner static const struct iio_chan_spec rockchip_rk3066_tsadc_iio_channels[] = { 1444c21bbb4SHeiko Stübner ADC_CHANNEL(0, "adc0"), 1454c21bbb4SHeiko Stübner ADC_CHANNEL(1, "adc1"), 1464c21bbb4SHeiko Stübner }; 1474c21bbb4SHeiko Stübner 1484c21bbb4SHeiko Stübner static const struct rockchip_saradc_data rk3066_tsadc_data = { 1494c21bbb4SHeiko Stübner .num_bits = 12, 1504c21bbb4SHeiko Stübner .channels = rockchip_rk3066_tsadc_iio_channels, 1514c21bbb4SHeiko Stübner .num_channels = ARRAY_SIZE(rockchip_rk3066_tsadc_iio_channels), 1524c21bbb4SHeiko Stübner .clk_rate = 50000, 1534c21bbb4SHeiko Stübner }; 1544c21bbb4SHeiko Stübner 155ae549a72SDavid Wu static const struct iio_chan_spec rockchip_rk3399_saradc_iio_channels[] = { 156ae549a72SDavid Wu ADC_CHANNEL(0, "adc0"), 157ae549a72SDavid Wu ADC_CHANNEL(1, "adc1"), 158ae549a72SDavid Wu ADC_CHANNEL(2, "adc2"), 159ae549a72SDavid Wu ADC_CHANNEL(3, "adc3"), 160ae549a72SDavid Wu ADC_CHANNEL(4, "adc4"), 161ae549a72SDavid Wu ADC_CHANNEL(5, "adc5"), 162ae549a72SDavid Wu }; 163ae549a72SDavid Wu 164ae549a72SDavid Wu static const struct rockchip_saradc_data rk3399_saradc_data = { 165ae549a72SDavid Wu .num_bits = 10, 166ae549a72SDavid Wu .channels = rockchip_rk3399_saradc_iio_channels, 167ae549a72SDavid Wu .num_channels = ARRAY_SIZE(rockchip_rk3399_saradc_iio_channels), 168ae549a72SDavid Wu .clk_rate = 1000000, 169ae549a72SDavid Wu }; 170ae549a72SDavid Wu 1714c21bbb4SHeiko Stübner static const struct of_device_id rockchip_saradc_match[] = { 1724c21bbb4SHeiko Stübner { 1734c21bbb4SHeiko Stübner .compatible = "rockchip,saradc", 1744c21bbb4SHeiko Stübner .data = &saradc_data, 1754c21bbb4SHeiko Stübner }, { 1764c21bbb4SHeiko Stübner .compatible = "rockchip,rk3066-tsadc", 1774c21bbb4SHeiko Stübner .data = &rk3066_tsadc_data, 178ae549a72SDavid Wu }, { 179ae549a72SDavid Wu .compatible = "rockchip,rk3399-saradc", 180ae549a72SDavid Wu .data = &rk3399_saradc_data, 1814c21bbb4SHeiko Stübner }, 1824c21bbb4SHeiko Stübner {}, 1834c21bbb4SHeiko Stübner }; 1844c21bbb4SHeiko Stübner MODULE_DEVICE_TABLE(of, rockchip_saradc_match); 1854c21bbb4SHeiko Stübner 186543852afSCaesar Wang /** 187543852afSCaesar Wang * Reset SARADC Controller. 188543852afSCaesar Wang */ 189543852afSCaesar Wang static void rockchip_saradc_reset_controller(struct reset_control *reset) 190543852afSCaesar Wang { 191543852afSCaesar Wang reset_control_assert(reset); 192543852afSCaesar Wang usleep_range(10, 20); 193543852afSCaesar Wang reset_control_deassert(reset); 194543852afSCaesar Wang } 195543852afSCaesar Wang 19644d6f2efSHeiko Stübner static int rockchip_saradc_probe(struct platform_device *pdev) 19744d6f2efSHeiko Stübner { 19844d6f2efSHeiko Stübner struct rockchip_saradc *info = NULL; 19944d6f2efSHeiko Stübner struct device_node *np = pdev->dev.of_node; 20044d6f2efSHeiko Stübner struct iio_dev *indio_dev = NULL; 20144d6f2efSHeiko Stübner struct resource *mem; 2024c21bbb4SHeiko Stübner const struct of_device_id *match; 20344d6f2efSHeiko Stübner int ret; 20444d6f2efSHeiko Stübner int irq; 20544d6f2efSHeiko Stübner 20644d6f2efSHeiko Stübner if (!np) 20744d6f2efSHeiko Stübner return -ENODEV; 20844d6f2efSHeiko Stübner 20944d6f2efSHeiko Stübner indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*info)); 21044d6f2efSHeiko Stübner if (!indio_dev) { 21144d6f2efSHeiko Stübner dev_err(&pdev->dev, "failed allocating iio device\n"); 21244d6f2efSHeiko Stübner return -ENOMEM; 21344d6f2efSHeiko Stübner } 21444d6f2efSHeiko Stübner info = iio_priv(indio_dev); 21544d6f2efSHeiko Stübner 2164c21bbb4SHeiko Stübner match = of_match_device(rockchip_saradc_match, &pdev->dev); 21736d311bcSGustavo A. R. Silva if (!match) { 21836d311bcSGustavo A. R. Silva dev_err(&pdev->dev, "failed to match device\n"); 21936d311bcSGustavo A. R. Silva return -ENODEV; 22036d311bcSGustavo A. R. Silva } 22136d311bcSGustavo A. R. Silva 2224c21bbb4SHeiko Stübner info->data = match->data; 2234c21bbb4SHeiko Stübner 22444d6f2efSHeiko Stübner mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 22544d6f2efSHeiko Stübner info->regs = devm_ioremap_resource(&pdev->dev, mem); 22644d6f2efSHeiko Stübner if (IS_ERR(info->regs)) 22744d6f2efSHeiko Stübner return PTR_ERR(info->regs); 22844d6f2efSHeiko Stübner 229543852afSCaesar Wang /* 230543852afSCaesar Wang * The reset should be an optional property, as it should work 231543852afSCaesar Wang * with old devicetrees as well 232543852afSCaesar Wang */ 23387587016SPhilipp Zabel info->reset = devm_reset_control_get_exclusive(&pdev->dev, 23487587016SPhilipp Zabel "saradc-apb"); 235543852afSCaesar Wang if (IS_ERR(info->reset)) { 236543852afSCaesar Wang ret = PTR_ERR(info->reset); 237543852afSCaesar Wang if (ret != -ENOENT) 238543852afSCaesar Wang return ret; 239543852afSCaesar Wang 240543852afSCaesar Wang dev_dbg(&pdev->dev, "no reset control found\n"); 241543852afSCaesar Wang info->reset = NULL; 242543852afSCaesar Wang } 243543852afSCaesar Wang 24444d6f2efSHeiko Stübner init_completion(&info->completion); 24544d6f2efSHeiko Stübner 24644d6f2efSHeiko Stübner irq = platform_get_irq(pdev, 0); 247*7c279229SStephen Boyd if (irq < 0) 24844d6f2efSHeiko Stübner return irq; 24944d6f2efSHeiko Stübner 25044d6f2efSHeiko Stübner ret = devm_request_irq(&pdev->dev, irq, rockchip_saradc_isr, 25144d6f2efSHeiko Stübner 0, dev_name(&pdev->dev), info); 25244d6f2efSHeiko Stübner if (ret < 0) { 25344d6f2efSHeiko Stübner dev_err(&pdev->dev, "failed requesting irq %d\n", irq); 25444d6f2efSHeiko Stübner return ret; 25544d6f2efSHeiko Stübner } 25644d6f2efSHeiko Stübner 25744d6f2efSHeiko Stübner info->pclk = devm_clk_get(&pdev->dev, "apb_pclk"); 25844d6f2efSHeiko Stübner if (IS_ERR(info->pclk)) { 25944d6f2efSHeiko Stübner dev_err(&pdev->dev, "failed to get pclk\n"); 26044d6f2efSHeiko Stübner return PTR_ERR(info->pclk); 26144d6f2efSHeiko Stübner } 26244d6f2efSHeiko Stübner 26344d6f2efSHeiko Stübner info->clk = devm_clk_get(&pdev->dev, "saradc"); 26444d6f2efSHeiko Stübner if (IS_ERR(info->clk)) { 26544d6f2efSHeiko Stübner dev_err(&pdev->dev, "failed to get adc clock\n"); 26644d6f2efSHeiko Stübner return PTR_ERR(info->clk); 26744d6f2efSHeiko Stübner } 26844d6f2efSHeiko Stübner 26944d6f2efSHeiko Stübner info->vref = devm_regulator_get(&pdev->dev, "vref"); 27044d6f2efSHeiko Stübner if (IS_ERR(info->vref)) { 27144d6f2efSHeiko Stübner dev_err(&pdev->dev, "failed to get regulator, %ld\n", 27244d6f2efSHeiko Stübner PTR_ERR(info->vref)); 27344d6f2efSHeiko Stübner return PTR_ERR(info->vref); 27444d6f2efSHeiko Stübner } 27544d6f2efSHeiko Stübner 276543852afSCaesar Wang if (info->reset) 277543852afSCaesar Wang rockchip_saradc_reset_controller(info->reset); 278543852afSCaesar Wang 27944d6f2efSHeiko Stübner /* 2804c21bbb4SHeiko Stübner * Use a default value for the converter clock. 28144d6f2efSHeiko Stübner * This may become user-configurable in the future. 28244d6f2efSHeiko Stübner */ 2834c21bbb4SHeiko Stübner ret = clk_set_rate(info->clk, info->data->clk_rate); 28444d6f2efSHeiko Stübner if (ret < 0) { 28544d6f2efSHeiko Stübner dev_err(&pdev->dev, "failed to set adc clk rate, %d\n", ret); 28644d6f2efSHeiko Stübner return ret; 28744d6f2efSHeiko Stübner } 28844d6f2efSHeiko Stübner 28944d6f2efSHeiko Stübner ret = regulator_enable(info->vref); 29044d6f2efSHeiko Stübner if (ret < 0) { 29144d6f2efSHeiko Stübner dev_err(&pdev->dev, "failed to enable vref regulator\n"); 29244d6f2efSHeiko Stübner return ret; 29344d6f2efSHeiko Stübner } 29444d6f2efSHeiko Stübner 29544d6f2efSHeiko Stübner ret = clk_prepare_enable(info->pclk); 29644d6f2efSHeiko Stübner if (ret < 0) { 29744d6f2efSHeiko Stübner dev_err(&pdev->dev, "failed to enable pclk\n"); 29844d6f2efSHeiko Stübner goto err_reg_voltage; 29944d6f2efSHeiko Stübner } 30044d6f2efSHeiko Stübner 30144d6f2efSHeiko Stübner ret = clk_prepare_enable(info->clk); 30244d6f2efSHeiko Stübner if (ret < 0) { 30344d6f2efSHeiko Stübner dev_err(&pdev->dev, "failed to enable converter clock\n"); 30444d6f2efSHeiko Stübner goto err_pclk; 30544d6f2efSHeiko Stübner } 30644d6f2efSHeiko Stübner 30744d6f2efSHeiko Stübner platform_set_drvdata(pdev, indio_dev); 30844d6f2efSHeiko Stübner 30944d6f2efSHeiko Stübner indio_dev->name = dev_name(&pdev->dev); 31044d6f2efSHeiko Stübner indio_dev->dev.parent = &pdev->dev; 31144d6f2efSHeiko Stübner indio_dev->dev.of_node = pdev->dev.of_node; 31244d6f2efSHeiko Stübner indio_dev->info = &rockchip_saradc_iio_info; 31344d6f2efSHeiko Stübner indio_dev->modes = INDIO_DIRECT_MODE; 31444d6f2efSHeiko Stübner 3154c21bbb4SHeiko Stübner indio_dev->channels = info->data->channels; 3164c21bbb4SHeiko Stübner indio_dev->num_channels = info->data->num_channels; 31744d6f2efSHeiko Stübner 31844d6f2efSHeiko Stübner ret = iio_device_register(indio_dev); 31944d6f2efSHeiko Stübner if (ret) 32044d6f2efSHeiko Stübner goto err_clk; 32144d6f2efSHeiko Stübner 32244d6f2efSHeiko Stübner return 0; 32344d6f2efSHeiko Stübner 32444d6f2efSHeiko Stübner err_clk: 32544d6f2efSHeiko Stübner clk_disable_unprepare(info->clk); 32644d6f2efSHeiko Stübner err_pclk: 32744d6f2efSHeiko Stübner clk_disable_unprepare(info->pclk); 32844d6f2efSHeiko Stübner err_reg_voltage: 32944d6f2efSHeiko Stübner regulator_disable(info->vref); 33044d6f2efSHeiko Stübner return ret; 33144d6f2efSHeiko Stübner } 33244d6f2efSHeiko Stübner 33344d6f2efSHeiko Stübner static int rockchip_saradc_remove(struct platform_device *pdev) 33444d6f2efSHeiko Stübner { 33544d6f2efSHeiko Stübner struct iio_dev *indio_dev = platform_get_drvdata(pdev); 33644d6f2efSHeiko Stübner struct rockchip_saradc *info = iio_priv(indio_dev); 33744d6f2efSHeiko Stübner 33844d6f2efSHeiko Stübner iio_device_unregister(indio_dev); 33944d6f2efSHeiko Stübner clk_disable_unprepare(info->clk); 34044d6f2efSHeiko Stübner clk_disable_unprepare(info->pclk); 34144d6f2efSHeiko Stübner regulator_disable(info->vref); 34244d6f2efSHeiko Stübner 34344d6f2efSHeiko Stübner return 0; 34444d6f2efSHeiko Stübner } 34544d6f2efSHeiko Stübner 34644d6f2efSHeiko Stübner #ifdef CONFIG_PM_SLEEP 34744d6f2efSHeiko Stübner static int rockchip_saradc_suspend(struct device *dev) 34844d6f2efSHeiko Stübner { 34944d6f2efSHeiko Stübner struct iio_dev *indio_dev = dev_get_drvdata(dev); 35044d6f2efSHeiko Stübner struct rockchip_saradc *info = iio_priv(indio_dev); 35144d6f2efSHeiko Stübner 35244d6f2efSHeiko Stübner clk_disable_unprepare(info->clk); 35344d6f2efSHeiko Stübner clk_disable_unprepare(info->pclk); 35444d6f2efSHeiko Stübner regulator_disable(info->vref); 35544d6f2efSHeiko Stübner 35644d6f2efSHeiko Stübner return 0; 35744d6f2efSHeiko Stübner } 35844d6f2efSHeiko Stübner 35944d6f2efSHeiko Stübner static int rockchip_saradc_resume(struct device *dev) 36044d6f2efSHeiko Stübner { 36144d6f2efSHeiko Stübner struct iio_dev *indio_dev = dev_get_drvdata(dev); 36244d6f2efSHeiko Stübner struct rockchip_saradc *info = iio_priv(indio_dev); 36344d6f2efSHeiko Stübner int ret; 36444d6f2efSHeiko Stübner 36544d6f2efSHeiko Stübner ret = regulator_enable(info->vref); 36644d6f2efSHeiko Stübner if (ret) 36744d6f2efSHeiko Stübner return ret; 36844d6f2efSHeiko Stübner 36944d6f2efSHeiko Stübner ret = clk_prepare_enable(info->pclk); 37044d6f2efSHeiko Stübner if (ret) 37144d6f2efSHeiko Stübner return ret; 37244d6f2efSHeiko Stübner 37344d6f2efSHeiko Stübner ret = clk_prepare_enable(info->clk); 37444d6f2efSHeiko Stübner if (ret) 37544d6f2efSHeiko Stübner return ret; 37644d6f2efSHeiko Stübner 37744d6f2efSHeiko Stübner return ret; 37844d6f2efSHeiko Stübner } 37944d6f2efSHeiko Stübner #endif 38044d6f2efSHeiko Stübner 38144d6f2efSHeiko Stübner static SIMPLE_DEV_PM_OPS(rockchip_saradc_pm_ops, 38244d6f2efSHeiko Stübner rockchip_saradc_suspend, rockchip_saradc_resume); 38344d6f2efSHeiko Stübner 38444d6f2efSHeiko Stübner static struct platform_driver rockchip_saradc_driver = { 38544d6f2efSHeiko Stübner .probe = rockchip_saradc_probe, 38644d6f2efSHeiko Stübner .remove = rockchip_saradc_remove, 38744d6f2efSHeiko Stübner .driver = { 38844d6f2efSHeiko Stübner .name = "rockchip-saradc", 38944d6f2efSHeiko Stübner .of_match_table = rockchip_saradc_match, 39044d6f2efSHeiko Stübner .pm = &rockchip_saradc_pm_ops, 39144d6f2efSHeiko Stübner }, 39244d6f2efSHeiko Stübner }; 39344d6f2efSHeiko Stübner 39444d6f2efSHeiko Stübner module_platform_driver(rockchip_saradc_driver); 395dc7b8d98SHeiko Stuebner 396dc7b8d98SHeiko Stuebner MODULE_AUTHOR("Heiko Stuebner <heiko@sntech.de>"); 397dc7b8d98SHeiko Stuebner MODULE_DESCRIPTION("Rockchip SARADC driver"); 398dc7b8d98SHeiko Stuebner MODULE_LICENSE("GPL v2"); 399