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                return irq;
 249
 250        ret = devm_request_irq(&pdev->dev, irq, rockchip_saradc_isr,
 251                               0, dev_name(&pdev->dev), info);
 252        if (ret < 0) {
 253                dev_err(&pdev->dev, "failed requesting irq %d\n", irq);
 254                return ret;
 255        }
 256
 257        info->pclk = devm_clk_get(&pdev->dev, "apb_pclk");
 258        if (IS_ERR(info->pclk)) {
 259                dev_err(&pdev->dev, "failed to get pclk\n");
 260                return PTR_ERR(info->pclk);
 261        }
 262
 263        info->clk = devm_clk_get(&pdev->dev, "saradc");
 264        if (IS_ERR(info->clk)) {
 265                dev_err(&pdev->dev, "failed to get adc clock\n");
 266                return PTR_ERR(info->clk);
 267        }
 268
 269        info->vref = devm_regulator_get(&pdev->dev, "vref");
 270        if (IS_ERR(info->vref)) {
 271                dev_err(&pdev->dev, "failed to get regulator, %ld\n",
 272                        PTR_ERR(info->vref));
 273                return PTR_ERR(info->vref);
 274        }
 275
 276        if (info->reset)
 277                rockchip_saradc_reset_controller(info->reset);
 278
 279        /*
 280         * Use a default value for the converter clock.
 281         * This may become user-configurable in the future.
 282         */
 283        ret = clk_set_rate(info->clk, info->data->clk_rate);
 284        if (ret < 0) {
 285                dev_err(&pdev->dev, "failed to set adc clk rate, %d\n", ret);
 286                return ret;
 287        }
 288
 289        ret = regulator_enable(info->vref);
 290        if (ret < 0) {
 291                dev_err(&pdev->dev, "failed to enable vref regulator\n");
 292                return ret;
 293        }
 294
 295        ret = clk_prepare_enable(info->pclk);
 296        if (ret < 0) {
 297                dev_err(&pdev->dev, "failed to enable pclk\n");
 298                goto err_reg_voltage;
 299        }
 300
 301        ret = clk_prepare_enable(info->clk);
 302        if (ret < 0) {
 303                dev_err(&pdev->dev, "failed to enable converter clock\n");
 304                goto err_pclk;
 305        }
 306
 307        platform_set_drvdata(pdev, indio_dev);
 308
 309        indio_dev->name = dev_name(&pdev->dev);
 310        indio_dev->dev.parent = &pdev->dev;
 311        indio_dev->dev.of_node = pdev->dev.of_node;
 312        indio_dev->info = &rockchip_saradc_iio_info;
 313        indio_dev->modes = INDIO_DIRECT_MODE;
 314
 315        indio_dev->channels = info->data->channels;
 316        indio_dev->num_channels = info->data->num_channels;
 317
 318        ret = iio_device_register(indio_dev);
 319        if (ret)
 320                goto err_clk;
 321
 322        return 0;
 323
 324err_clk:
 325        clk_disable_unprepare(info->clk);
 326err_pclk:
 327        clk_disable_unprepare(info->pclk);
 328err_reg_voltage:
 329        regulator_disable(info->vref);
 330        return ret;
 331}
 332
 333static int rockchip_saradc_remove(struct platform_device *pdev)
 334{
 335        struct iio_dev *indio_dev = platform_get_drvdata(pdev);
 336        struct rockchip_saradc *info = iio_priv(indio_dev);
 337
 338        iio_device_unregister(indio_dev);
 339        clk_disable_unprepare(info->clk);
 340        clk_disable_unprepare(info->pclk);
 341        regulator_disable(info->vref);
 342
 343        return 0;
 344}
 345
 346#ifdef CONFIG_PM_SLEEP
 347static int rockchip_saradc_suspend(struct device *dev)
 348{
 349        struct iio_dev *indio_dev = dev_get_drvdata(dev);
 350        struct rockchip_saradc *info = iio_priv(indio_dev);
 351
 352        clk_disable_unprepare(info->clk);
 353        clk_disable_unprepare(info->pclk);
 354        regulator_disable(info->vref);
 355
 356        return 0;
 357}
 358
 359static int rockchip_saradc_resume(struct device *dev)
 360{
 361        struct iio_dev *indio_dev = dev_get_drvdata(dev);
 362        struct rockchip_saradc *info = iio_priv(indio_dev);
 363        int ret;
 364
 365        ret = regulator_enable(info->vref);
 366        if (ret)
 367                return ret;
 368
 369        ret = clk_prepare_enable(info->pclk);
 370        if (ret)
 371                return ret;
 372
 373        ret = clk_prepare_enable(info->clk);
 374        if (ret)
 375                return ret;
 376
 377        return ret;
 378}
 379#endif
 380
 381static SIMPLE_DEV_PM_OPS(rockchip_saradc_pm_ops,
 382                         rockchip_saradc_suspend, rockchip_saradc_resume);
 383
 384static struct platform_driver rockchip_saradc_driver = {
 385        .probe          = rockchip_saradc_probe,
 386        .remove         = rockchip_saradc_remove,
 387        .driver         = {
 388                .name   = "rockchip-saradc",
 389                .of_match_table = rockchip_saradc_match,
 390                .pm     = &rockchip_saradc_pm_ops,
 391        },
 392};
 393
 394module_platform_driver(rockchip_saradc_driver);
 395
 396MODULE_AUTHOR("Heiko Stuebner <heiko@sntech.de>");
 397MODULE_DESCRIPTION("Rockchip SARADC driver");
 398MODULE_LICENSE("GPL v2");
 399