linux/drivers/iio/adc/rockchip_saradc.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * Rockchip Successive Approximation Register (SAR) A/D Converter
   4 * Copyright (C) 2014 ROCKCHIP, Inc.
   5 */
   6
   7#include <linux/module.h>
   8#include <linux/platform_device.h>
   9#include <linux/interrupt.h>
  10#include <linux/io.h>
  11#include <linux/of.h>
  12#include <linux/of_device.h>
  13#include <linux/clk.h>
  14#include <linux/completion.h>
  15#include <linux/delay.h>
  16#include <linux/reset.h>
  17#include <linux/regulator/consumer.h>
  18#include <linux/iio/iio.h>
  19
  20#define SARADC_DATA                     0x00
  21
  22#define SARADC_STAS                     0x04
  23#define SARADC_STAS_BUSY                BIT(0)
  24
  25#define SARADC_CTRL                     0x08
  26#define SARADC_CTRL_IRQ_STATUS          BIT(6)
  27#define SARADC_CTRL_IRQ_ENABLE          BIT(5)
  28#define SARADC_CTRL_POWER_CTRL          BIT(3)
  29#define SARADC_CTRL_CHN_MASK            0x7
  30
  31#define SARADC_DLY_PU_SOC               0x0c
  32#define SARADC_DLY_PU_SOC_MASK          0x3f
  33
  34#define SARADC_TIMEOUT                  msecs_to_jiffies(100)
  35
  36struct rockchip_saradc_data {
  37        int                             num_bits;
  38        const struct iio_chan_spec      *channels;
  39        int                             num_channels;
  40        unsigned long                   clk_rate;
  41};
  42
  43struct rockchip_saradc {
  44        void __iomem            *regs;
  45        struct clk              *pclk;
  46        struct clk              *clk;
  47        struct completion       completion;
  48        struct regulator        *vref;
  49        struct reset_control    *reset;
  50        const struct rockchip_saradc_data *data;
  51        u16                     last_val;
  52};
  53
  54static int rockchip_saradc_read_raw(struct iio_dev *indio_dev,
  55                                    struct iio_chan_spec const *chan,
  56                                    int *val, int *val2, long mask)
  57{
  58        struct rockchip_saradc *info = iio_priv(indio_dev);
  59        int ret;
  60
  61        switch (mask) {
  62        case IIO_CHAN_INFO_RAW:
  63                mutex_lock(&indio_dev->mlock);
  64
  65                reinit_completion(&info->completion);
  66
  67                /* 8 clock periods as delay between power up and start cmd */
  68                writel_relaxed(8, info->regs + SARADC_DLY_PU_SOC);
  69
  70                /* Select the channel to be used and trigger conversion */
  71                writel(SARADC_CTRL_POWER_CTRL
  72                                | (chan->channel & SARADC_CTRL_CHN_MASK)
  73                                | SARADC_CTRL_IRQ_ENABLE,
  74                       info->regs + SARADC_CTRL);
  75
  76                if (!wait_for_completion_timeout(&info->completion,
  77                                                 SARADC_TIMEOUT)) {
  78                        writel_relaxed(0, info->regs + SARADC_CTRL);
  79                        mutex_unlock(&indio_dev->mlock);
  80                        return -ETIMEDOUT;
  81                }
  82
  83                *val = info->last_val;
  84                mutex_unlock(&indio_dev->mlock);
  85                return IIO_VAL_INT;
  86        case IIO_CHAN_INFO_SCALE:
  87                ret = regulator_get_voltage(info->vref);
  88                if (ret < 0) {
  89                        dev_err(&indio_dev->dev, "failed to get voltage\n");
  90                        return ret;
  91                }
  92
  93                *val = ret / 1000;
  94                *val2 = info->data->num_bits;
  95                return IIO_VAL_FRACTIONAL_LOG2;
  96        default:
  97                return -EINVAL;
  98        }
  99}
 100
 101static irqreturn_t rockchip_saradc_isr(int irq, void *dev_id)
 102{
 103        struct rockchip_saradc *info = dev_id;
 104
 105        /* Read value */
 106        info->last_val = readl_relaxed(info->regs + SARADC_DATA);
 107        info->last_val &= GENMASK(info->data->num_bits - 1, 0);
 108
 109        /* Clear irq & power down adc */
 110        writel_relaxed(0, info->regs + SARADC_CTRL);
 111
 112        complete(&info->completion);
 113
 114        return IRQ_HANDLED;
 115}
 116
 117static const struct iio_info rockchip_saradc_iio_info = {
 118        .read_raw = rockchip_saradc_read_raw,
 119};
 120
 121#define ADC_CHANNEL(_index, _id) {                              \
 122        .type = IIO_VOLTAGE,                                    \
 123        .indexed = 1,                                           \
 124        .channel = _index,                                      \
 125        .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),           \
 126        .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),   \
 127        .datasheet_name = _id,                                  \
 128}
 129
 130static const struct iio_chan_spec rockchip_saradc_iio_channels[] = {
 131        ADC_CHANNEL(0, "adc0"),
 132        ADC_CHANNEL(1, "adc1"),
 133        ADC_CHANNEL(2, "adc2"),
 134};
 135
 136static const struct rockchip_saradc_data saradc_data = {
 137        .num_bits = 10,
 138        .channels = rockchip_saradc_iio_channels,
 139        .num_channels = ARRAY_SIZE(rockchip_saradc_iio_channels),
 140        .clk_rate = 1000000,
 141};
 142
 143static const struct iio_chan_spec rockchip_rk3066_tsadc_iio_channels[] = {
 144        ADC_CHANNEL(0, "adc0"),
 145        ADC_CHANNEL(1, "adc1"),
 146};
 147
 148static const struct rockchip_saradc_data rk3066_tsadc_data = {
 149        .num_bits = 12,
 150        .channels = rockchip_rk3066_tsadc_iio_channels,
 151        .num_channels = ARRAY_SIZE(rockchip_rk3066_tsadc_iio_channels),
 152        .clk_rate = 50000,
 153};
 154
 155static const struct iio_chan_spec rockchip_rk3399_saradc_iio_channels[] = {
 156        ADC_CHANNEL(0, "adc0"),
 157        ADC_CHANNEL(1, "adc1"),
 158        ADC_CHANNEL(2, "adc2"),
 159        ADC_CHANNEL(3, "adc3"),
 160        ADC_CHANNEL(4, "adc4"),
 161        ADC_CHANNEL(5, "adc5"),
 162};
 163
 164static const struct rockchip_saradc_data rk3399_saradc_data = {
 165        .num_bits = 10,
 166        .channels = rockchip_rk3399_saradc_iio_channels,
 167        .num_channels = ARRAY_SIZE(rockchip_rk3399_saradc_iio_channels),
 168        .clk_rate = 1000000,
 169};
 170
 171static const struct of_device_id rockchip_saradc_match[] = {
 172        {
 173                .compatible = "rockchip,saradc",
 174                .data = &saradc_data,
 175        }, {
 176                .compatible = "rockchip,rk3066-tsadc",
 177                .data = &rk3066_tsadc_data,
 178        }, {
 179                .compatible = "rockchip,rk3399-saradc",
 180                .data = &rk3399_saradc_data,
 181        },
 182        {},
 183};
 184MODULE_DEVICE_TABLE(of, rockchip_saradc_match);
 185
 186/**
 187 * Reset SARADC Controller.
 188 */
 189static void rockchip_saradc_reset_controller(struct reset_control *reset)
 190{
 191        reset_control_assert(reset);
 192        usleep_range(10, 20);
 193        reset_control_deassert(reset);
 194}
 195
 196static int rockchip_saradc_probe(struct platform_device *pdev)
 197{
 198        struct rockchip_saradc *info = NULL;
 199        struct device_node *np = pdev->dev.of_node;
 200        struct iio_dev *indio_dev = NULL;
 201        struct resource *mem;
 202        const struct of_device_id *match;
 203        int ret;
 204        int irq;
 205
 206        if (!np)
 207                return -ENODEV;
 208
 209        indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*info));
 210        if (!indio_dev) {
 211                dev_err(&pdev->dev, "failed allocating iio device\n");
 212                return -ENOMEM;
 213        }
 214        info = iio_priv(indio_dev);
 215
 216        match = of_match_device(rockchip_saradc_match, &pdev->dev);
 217        if (!match) {
 218                dev_err(&pdev->dev, "failed to match device\n");
 219                return -ENODEV;
 220        }
 221
 222        info->data = match->data;
 223
 224        mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 225        info->regs = devm_ioremap_resource(&pdev->dev, mem);
 226        if (IS_ERR(info->regs))
 227                return PTR_ERR(info->regs);
 228
 229        /*
 230         * The reset should be an optional property, as it should work
 231         * with old devicetrees as well
 232         */
 233        info->reset = devm_reset_control_get_exclusive(&pdev->dev,
 234                                                       "saradc-apb");
 235        if (IS_ERR(info->reset)) {
 236                ret = PTR_ERR(info->reset);
 237                if (ret != -ENOENT)
 238                        return ret;
 239
 240                dev_dbg(&pdev->dev, "no reset control found\n");
 241                info->reset = NULL;
 242        }
 243
 244        init_completion(&info->completion);
 245
 246        irq = platform_get_irq(pdev, 0);
 247        if (irq < 0) {
 248                dev_err(&pdev->dev, "no irq resource?\n");
 249                return irq;
 250        }
 251
 252        ret = devm_request_irq(&pdev->dev, irq, rockchip_saradc_isr,
 253                               0, dev_name(&pdev->dev), info);
 254        if (ret < 0) {
 255                dev_err(&pdev->dev, "failed requesting irq %d\n", irq);
 256                return ret;
 257        }
 258
 259        info->pclk = devm_clk_get(&pdev->dev, "apb_pclk");
 260        if (IS_ERR(info->pclk)) {
 261                dev_err(&pdev->dev, "failed to get pclk\n");
 262                return PTR_ERR(info->pclk);
 263        }
 264
 265        info->clk = devm_clk_get(&pdev->dev, "saradc");
 266        if (IS_ERR(info->clk)) {
 267                dev_err(&pdev->dev, "failed to get adc clock\n");
 268                return PTR_ERR(info->clk);
 269        }
 270
 271        info->vref = devm_regulator_get(&pdev->dev, "vref");
 272        if (IS_ERR(info->vref)) {
 273                dev_err(&pdev->dev, "failed to get regulator, %ld\n",
 274                        PTR_ERR(info->vref));
 275                return PTR_ERR(info->vref);
 276        }
 277
 278        if (info->reset)
 279                rockchip_saradc_reset_controller(info->reset);
 280
 281        /*
 282         * Use a default value for the converter clock.
 283         * This may become user-configurable in the future.
 284         */
 285        ret = clk_set_rate(info->clk, info->data->clk_rate);
 286        if (ret < 0) {
 287                dev_err(&pdev->dev, "failed to set adc clk rate, %d\n", ret);
 288                return ret;
 289        }
 290
 291        ret = regulator_enable(info->vref);
 292        if (ret < 0) {
 293                dev_err(&pdev->dev, "failed to enable vref regulator\n");
 294                return ret;
 295        }
 296
 297        ret = clk_prepare_enable(info->pclk);
 298        if (ret < 0) {
 299                dev_err(&pdev->dev, "failed to enable pclk\n");
 300                goto err_reg_voltage;
 301        }
 302
 303        ret = clk_prepare_enable(info->clk);
 304        if (ret < 0) {
 305                dev_err(&pdev->dev, "failed to enable converter clock\n");
 306                goto err_pclk;
 307        }
 308
 309        platform_set_drvdata(pdev, indio_dev);
 310
 311        indio_dev->name = dev_name(&pdev->dev);
 312        indio_dev->dev.parent = &pdev->dev;
 313        indio_dev->dev.of_node = pdev->dev.of_node;
 314        indio_dev->info = &rockchip_saradc_iio_info;
 315        indio_dev->modes = INDIO_DIRECT_MODE;
 316
 317        indio_dev->channels = info->data->channels;
 318        indio_dev->num_channels = info->data->num_channels;
 319
 320        ret = iio_device_register(indio_dev);
 321        if (ret)
 322                goto err_clk;
 323
 324        return 0;
 325
 326err_clk:
 327        clk_disable_unprepare(info->clk);
 328err_pclk:
 329        clk_disable_unprepare(info->pclk);
 330err_reg_voltage:
 331        regulator_disable(info->vref);
 332        return ret;
 333}
 334
 335static int rockchip_saradc_remove(struct platform_device *pdev)
 336{
 337        struct iio_dev *indio_dev = platform_get_drvdata(pdev);
 338        struct rockchip_saradc *info = iio_priv(indio_dev);
 339
 340        iio_device_unregister(indio_dev);
 341        clk_disable_unprepare(info->clk);
 342        clk_disable_unprepare(info->pclk);
 343        regulator_disable(info->vref);
 344
 345        return 0;
 346}
 347
 348#ifdef CONFIG_PM_SLEEP
 349static int rockchip_saradc_suspend(struct device *dev)
 350{
 351        struct iio_dev *indio_dev = dev_get_drvdata(dev);
 352        struct rockchip_saradc *info = iio_priv(indio_dev);
 353
 354        clk_disable_unprepare(info->clk);
 355        clk_disable_unprepare(info->pclk);
 356        regulator_disable(info->vref);
 357
 358        return 0;
 359}
 360
 361static int rockchip_saradc_resume(struct device *dev)
 362{
 363        struct iio_dev *indio_dev = dev_get_drvdata(dev);
 364        struct rockchip_saradc *info = iio_priv(indio_dev);
 365        int ret;
 366
 367        ret = regulator_enable(info->vref);
 368        if (ret)
 369                return ret;
 370
 371        ret = clk_prepare_enable(info->pclk);
 372        if (ret)
 373                return ret;
 374
 375        ret = clk_prepare_enable(info->clk);
 376        if (ret)
 377                return ret;
 378
 379        return ret;
 380}
 381#endif
 382
 383static SIMPLE_DEV_PM_OPS(rockchip_saradc_pm_ops,
 384                         rockchip_saradc_suspend, rockchip_saradc_resume);
 385
 386static struct platform_driver rockchip_saradc_driver = {
 387        .probe          = rockchip_saradc_probe,
 388        .remove         = rockchip_saradc_remove,
 389        .driver         = {
 390                .name   = "rockchip-saradc",
 391                .of_match_table = rockchip_saradc_match,
 392                .pm     = &rockchip_saradc_pm_ops,
 393        },
 394};
 395
 396module_platform_driver(rockchip_saradc_driver);
 397
 398MODULE_AUTHOR("Heiko Stuebner <heiko@sntech.de>");
 399MODULE_DESCRIPTION("Rockchip SARADC driver");
 400MODULE_LICENSE("GPL v2");
 401