linux/drivers/iio/adc/sun4i-gpadc-iio.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/* ADC driver for sunxi platforms' (A10, A13 and A31) GPADC
   3 *
   4 * Copyright (c) 2016 Quentin Schulz <quentin.schulz@free-electrons.com>
   5 *
   6 * The Allwinner SoCs all have an ADC that can also act as a touchscreen
   7 * controller and a thermal sensor.
   8 * The thermal sensor works only when the ADC acts as a touchscreen controller
   9 * and is configured to throw an interrupt every fixed periods of time (let say
  10 * every X seconds).
  11 * One would be tempted to disable the IP on the hardware side rather than
  12 * disabling interrupts to save some power but that resets the internal clock of
  13 * the IP, resulting in having to wait X seconds every time we want to read the
  14 * value of the thermal sensor.
  15 * This is also the reason of using autosuspend in pm_runtime. If there was no
  16 * autosuspend, the thermal sensor would need X seconds after every
  17 * pm_runtime_get_sync to get a value from the ADC. The autosuspend allows the
  18 * thermal sensor to be requested again in a certain time span before it gets
  19 * shutdown for not being used.
  20 */
  21
  22#include <linux/completion.h>
  23#include <linux/interrupt.h>
  24#include <linux/io.h>
  25#include <linux/module.h>
  26#include <linux/of.h>
  27#include <linux/of_device.h>
  28#include <linux/platform_device.h>
  29#include <linux/pm_runtime.h>
  30#include <linux/regmap.h>
  31#include <linux/thermal.h>
  32#include <linux/delay.h>
  33
  34#include <linux/iio/iio.h>
  35#include <linux/iio/driver.h>
  36#include <linux/iio/machine.h>
  37#include <linux/mfd/sun4i-gpadc.h>
  38
  39static unsigned int sun4i_gpadc_chan_select(unsigned int chan)
  40{
  41        return SUN4I_GPADC_CTRL1_ADC_CHAN_SELECT(chan);
  42}
  43
  44static unsigned int sun6i_gpadc_chan_select(unsigned int chan)
  45{
  46        return SUN6I_GPADC_CTRL1_ADC_CHAN_SELECT(chan);
  47}
  48
  49struct gpadc_data {
  50        int             temp_offset;
  51        int             temp_scale;
  52        unsigned int    tp_mode_en;
  53        unsigned int    tp_adc_select;
  54        unsigned int    (*adc_chan_select)(unsigned int chan);
  55        unsigned int    adc_chan_mask;
  56};
  57
  58static const struct gpadc_data sun4i_gpadc_data = {
  59        .temp_offset = -1932,
  60        .temp_scale = 133,
  61        .tp_mode_en = SUN4I_GPADC_CTRL1_TP_MODE_EN,
  62        .tp_adc_select = SUN4I_GPADC_CTRL1_TP_ADC_SELECT,
  63        .adc_chan_select = &sun4i_gpadc_chan_select,
  64        .adc_chan_mask = SUN4I_GPADC_CTRL1_ADC_CHAN_MASK,
  65};
  66
  67static const struct gpadc_data sun5i_gpadc_data = {
  68        .temp_offset = -1447,
  69        .temp_scale = 100,
  70        .tp_mode_en = SUN4I_GPADC_CTRL1_TP_MODE_EN,
  71        .tp_adc_select = SUN4I_GPADC_CTRL1_TP_ADC_SELECT,
  72        .adc_chan_select = &sun4i_gpadc_chan_select,
  73        .adc_chan_mask = SUN4I_GPADC_CTRL1_ADC_CHAN_MASK,
  74};
  75
  76static const struct gpadc_data sun6i_gpadc_data = {
  77        .temp_offset = -1623,
  78        .temp_scale = 167,
  79        .tp_mode_en = SUN6I_GPADC_CTRL1_TP_MODE_EN,
  80        .tp_adc_select = SUN6I_GPADC_CTRL1_TP_ADC_SELECT,
  81        .adc_chan_select = &sun6i_gpadc_chan_select,
  82        .adc_chan_mask = SUN6I_GPADC_CTRL1_ADC_CHAN_MASK,
  83};
  84
  85static const struct gpadc_data sun8i_a33_gpadc_data = {
  86        .temp_offset = -1662,
  87        .temp_scale = 162,
  88        .tp_mode_en = SUN8I_GPADC_CTRL1_CHOP_TEMP_EN,
  89};
  90
  91struct sun4i_gpadc_iio {
  92        struct iio_dev                  *indio_dev;
  93        struct completion               completion;
  94        int                             temp_data;
  95        u32                             adc_data;
  96        struct regmap                   *regmap;
  97        unsigned int                    fifo_data_irq;
  98        atomic_t                        ignore_fifo_data_irq;
  99        unsigned int                    temp_data_irq;
 100        atomic_t                        ignore_temp_data_irq;
 101        const struct gpadc_data         *data;
 102        bool                            no_irq;
 103        /* prevents concurrent reads of temperature and ADC */
 104        struct mutex                    mutex;
 105        struct thermal_zone_device      *tzd;
 106        struct device                   *sensor_device;
 107};
 108
 109#define SUN4I_GPADC_ADC_CHANNEL(_channel, _name) {              \
 110        .type = IIO_VOLTAGE,                                    \
 111        .indexed = 1,                                           \
 112        .channel = _channel,                                    \
 113        .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),           \
 114        .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),   \
 115        .datasheet_name = _name,                                \
 116}
 117
 118static struct iio_map sun4i_gpadc_hwmon_maps[] = {
 119        {
 120                .adc_channel_label = "temp_adc",
 121                .consumer_dev_name = "iio_hwmon.0",
 122        },
 123        { /* sentinel */ },
 124};
 125
 126static const struct iio_chan_spec sun4i_gpadc_channels[] = {
 127        SUN4I_GPADC_ADC_CHANNEL(0, "adc_chan0"),
 128        SUN4I_GPADC_ADC_CHANNEL(1, "adc_chan1"),
 129        SUN4I_GPADC_ADC_CHANNEL(2, "adc_chan2"),
 130        SUN4I_GPADC_ADC_CHANNEL(3, "adc_chan3"),
 131        {
 132                .type = IIO_TEMP,
 133                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
 134                                      BIT(IIO_CHAN_INFO_SCALE) |
 135                                      BIT(IIO_CHAN_INFO_OFFSET),
 136                .datasheet_name = "temp_adc",
 137        },
 138};
 139
 140static const struct iio_chan_spec sun4i_gpadc_channels_no_temp[] = {
 141        SUN4I_GPADC_ADC_CHANNEL(0, "adc_chan0"),
 142        SUN4I_GPADC_ADC_CHANNEL(1, "adc_chan1"),
 143        SUN4I_GPADC_ADC_CHANNEL(2, "adc_chan2"),
 144        SUN4I_GPADC_ADC_CHANNEL(3, "adc_chan3"),
 145};
 146
 147static const struct iio_chan_spec sun8i_a33_gpadc_channels[] = {
 148        {
 149                .type = IIO_TEMP,
 150                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
 151                                      BIT(IIO_CHAN_INFO_SCALE) |
 152                                      BIT(IIO_CHAN_INFO_OFFSET),
 153                .datasheet_name = "temp_adc",
 154        },
 155};
 156
 157static const struct regmap_config sun4i_gpadc_regmap_config = {
 158        .reg_bits = 32,
 159        .val_bits = 32,
 160        .reg_stride = 4,
 161        .fast_io = true,
 162};
 163
 164static int sun4i_prepare_for_irq(struct iio_dev *indio_dev, int channel,
 165                                 unsigned int irq)
 166{
 167        struct sun4i_gpadc_iio *info = iio_priv(indio_dev);
 168        int ret;
 169        u32 reg;
 170
 171        pm_runtime_get_sync(indio_dev->dev.parent);
 172
 173        reinit_completion(&info->completion);
 174
 175        ret = regmap_write(info->regmap, SUN4I_GPADC_INT_FIFOC,
 176                           SUN4I_GPADC_INT_FIFOC_TP_FIFO_TRIG_LEVEL(1) |
 177                           SUN4I_GPADC_INT_FIFOC_TP_FIFO_FLUSH);
 178        if (ret)
 179                return ret;
 180
 181        ret = regmap_read(info->regmap, SUN4I_GPADC_CTRL1, &reg);
 182        if (ret)
 183                return ret;
 184
 185        if (irq == info->fifo_data_irq) {
 186                ret = regmap_write(info->regmap, SUN4I_GPADC_CTRL1,
 187                                   info->data->tp_mode_en |
 188                                   info->data->tp_adc_select |
 189                                   info->data->adc_chan_select(channel));
 190                /*
 191                 * When the IP changes channel, it needs a bit of time to get
 192                 * correct values.
 193                 */
 194                if ((reg & info->data->adc_chan_mask) !=
 195                         info->data->adc_chan_select(channel))
 196                        mdelay(10);
 197
 198        } else {
 199                /*
 200                 * The temperature sensor returns valid data only when the ADC
 201                 * operates in touchscreen mode.
 202                 */
 203                ret = regmap_write(info->regmap, SUN4I_GPADC_CTRL1,
 204                                   info->data->tp_mode_en);
 205        }
 206
 207        if (ret)
 208                return ret;
 209
 210        /*
 211         * When the IP changes mode between ADC or touchscreen, it
 212         * needs a bit of time to get correct values.
 213         */
 214        if ((reg & info->data->tp_adc_select) != info->data->tp_adc_select)
 215                mdelay(100);
 216
 217        return 0;
 218}
 219
 220static int sun4i_gpadc_read(struct iio_dev *indio_dev, int channel, int *val,
 221                            unsigned int irq)
 222{
 223        struct sun4i_gpadc_iio *info = iio_priv(indio_dev);
 224        int ret;
 225
 226        mutex_lock(&info->mutex);
 227
 228        ret = sun4i_prepare_for_irq(indio_dev, channel, irq);
 229        if (ret)
 230                goto err;
 231
 232        enable_irq(irq);
 233
 234        /*
 235         * The temperature sensor throws an interruption periodically (currently
 236         * set at periods of ~0.6s in sun4i_gpadc_runtime_resume). A 1s delay
 237         * makes sure an interruption occurs in normal conditions. If it doesn't
 238         * occur, then there is a timeout.
 239         */
 240        if (!wait_for_completion_timeout(&info->completion,
 241                                         msecs_to_jiffies(1000))) {
 242                ret = -ETIMEDOUT;
 243                goto err;
 244        }
 245
 246        if (irq == info->fifo_data_irq)
 247                *val = info->adc_data;
 248        else
 249                *val = info->temp_data;
 250
 251        ret = 0;
 252        pm_runtime_mark_last_busy(indio_dev->dev.parent);
 253
 254err:
 255        pm_runtime_put_autosuspend(indio_dev->dev.parent);
 256        disable_irq(irq);
 257        mutex_unlock(&info->mutex);
 258
 259        return ret;
 260}
 261
 262static int sun4i_gpadc_adc_read(struct iio_dev *indio_dev, int channel,
 263                                int *val)
 264{
 265        struct sun4i_gpadc_iio *info = iio_priv(indio_dev);
 266
 267        return sun4i_gpadc_read(indio_dev, channel, val, info->fifo_data_irq);
 268}
 269
 270static int sun4i_gpadc_temp_read(struct iio_dev *indio_dev, int *val)
 271{
 272        struct sun4i_gpadc_iio *info = iio_priv(indio_dev);
 273
 274        if (info->no_irq) {
 275                pm_runtime_get_sync(indio_dev->dev.parent);
 276
 277                regmap_read(info->regmap, SUN4I_GPADC_TEMP_DATA, val);
 278
 279                pm_runtime_mark_last_busy(indio_dev->dev.parent);
 280                pm_runtime_put_autosuspend(indio_dev->dev.parent);
 281
 282                return 0;
 283        }
 284
 285        return sun4i_gpadc_read(indio_dev, 0, val, info->temp_data_irq);
 286}
 287
 288static int sun4i_gpadc_temp_offset(struct iio_dev *indio_dev, int *val)
 289{
 290        struct sun4i_gpadc_iio *info = iio_priv(indio_dev);
 291
 292        *val = info->data->temp_offset;
 293
 294        return 0;
 295}
 296
 297static int sun4i_gpadc_temp_scale(struct iio_dev *indio_dev, int *val)
 298{
 299        struct sun4i_gpadc_iio *info = iio_priv(indio_dev);
 300
 301        *val = info->data->temp_scale;
 302
 303        return 0;
 304}
 305
 306static int sun4i_gpadc_read_raw(struct iio_dev *indio_dev,
 307                                struct iio_chan_spec const *chan, int *val,
 308                                int *val2, long mask)
 309{
 310        int ret;
 311
 312        switch (mask) {
 313        case IIO_CHAN_INFO_OFFSET:
 314                ret = sun4i_gpadc_temp_offset(indio_dev, val);
 315                if (ret)
 316                        return ret;
 317
 318                return IIO_VAL_INT;
 319        case IIO_CHAN_INFO_RAW:
 320                if (chan->type == IIO_VOLTAGE)
 321                        ret = sun4i_gpadc_adc_read(indio_dev, chan->channel,
 322                                                   val);
 323                else
 324                        ret = sun4i_gpadc_temp_read(indio_dev, val);
 325
 326                if (ret)
 327                        return ret;
 328
 329                return IIO_VAL_INT;
 330        case IIO_CHAN_INFO_SCALE:
 331                if (chan->type == IIO_VOLTAGE) {
 332                        /* 3000mV / 4096 * raw */
 333                        *val = 0;
 334                        *val2 = 732421875;
 335                        return IIO_VAL_INT_PLUS_NANO;
 336                }
 337
 338                ret = sun4i_gpadc_temp_scale(indio_dev, val);
 339                if (ret)
 340                        return ret;
 341
 342                return IIO_VAL_INT;
 343        default:
 344                return -EINVAL;
 345        }
 346
 347        return -EINVAL;
 348}
 349
 350static const struct iio_info sun4i_gpadc_iio_info = {
 351        .read_raw = sun4i_gpadc_read_raw,
 352};
 353
 354static irqreturn_t sun4i_gpadc_temp_data_irq_handler(int irq, void *dev_id)
 355{
 356        struct sun4i_gpadc_iio *info = dev_id;
 357
 358        if (atomic_read(&info->ignore_temp_data_irq))
 359                goto out;
 360
 361        if (!regmap_read(info->regmap, SUN4I_GPADC_TEMP_DATA, &info->temp_data))
 362                complete(&info->completion);
 363
 364out:
 365        return IRQ_HANDLED;
 366}
 367
 368static irqreturn_t sun4i_gpadc_fifo_data_irq_handler(int irq, void *dev_id)
 369{
 370        struct sun4i_gpadc_iio *info = dev_id;
 371
 372        if (atomic_read(&info->ignore_fifo_data_irq))
 373                goto out;
 374
 375        if (!regmap_read(info->regmap, SUN4I_GPADC_DATA, &info->adc_data))
 376                complete(&info->completion);
 377
 378out:
 379        return IRQ_HANDLED;
 380}
 381
 382static int sun4i_gpadc_runtime_suspend(struct device *dev)
 383{
 384        struct sun4i_gpadc_iio *info = iio_priv(dev_get_drvdata(dev));
 385
 386        /* Disable the ADC on IP */
 387        regmap_write(info->regmap, SUN4I_GPADC_CTRL1, 0);
 388        /* Disable temperature sensor on IP */
 389        regmap_write(info->regmap, SUN4I_GPADC_TPR, 0);
 390
 391        return 0;
 392}
 393
 394static int sun4i_gpadc_runtime_resume(struct device *dev)
 395{
 396        struct sun4i_gpadc_iio *info = iio_priv(dev_get_drvdata(dev));
 397
 398        /* clkin = 6MHz */
 399        regmap_write(info->regmap, SUN4I_GPADC_CTRL0,
 400                     SUN4I_GPADC_CTRL0_ADC_CLK_DIVIDER(2) |
 401                     SUN4I_GPADC_CTRL0_FS_DIV(7) |
 402                     SUN4I_GPADC_CTRL0_T_ACQ(63));
 403        regmap_write(info->regmap, SUN4I_GPADC_CTRL1, info->data->tp_mode_en);
 404        regmap_write(info->regmap, SUN4I_GPADC_CTRL3,
 405                     SUN4I_GPADC_CTRL3_FILTER_EN |
 406                     SUN4I_GPADC_CTRL3_FILTER_TYPE(1));
 407        /* period = SUN4I_GPADC_TPR_TEMP_PERIOD * 256 * 16 / clkin; ~0.6s */
 408        regmap_write(info->regmap, SUN4I_GPADC_TPR,
 409                     SUN4I_GPADC_TPR_TEMP_ENABLE |
 410                     SUN4I_GPADC_TPR_TEMP_PERIOD(800));
 411
 412        return 0;
 413}
 414
 415static int sun4i_gpadc_get_temp(void *data, int *temp)
 416{
 417        struct sun4i_gpadc_iio *info = data;
 418        int val, scale, offset;
 419
 420        if (sun4i_gpadc_temp_read(info->indio_dev, &val))
 421                return -ETIMEDOUT;
 422
 423        sun4i_gpadc_temp_scale(info->indio_dev, &scale);
 424        sun4i_gpadc_temp_offset(info->indio_dev, &offset);
 425
 426        *temp = (val + offset) * scale;
 427
 428        return 0;
 429}
 430
 431static const struct thermal_zone_of_device_ops sun4i_ts_tz_ops = {
 432        .get_temp = &sun4i_gpadc_get_temp,
 433};
 434
 435static const struct dev_pm_ops sun4i_gpadc_pm_ops = {
 436        .runtime_suspend = &sun4i_gpadc_runtime_suspend,
 437        .runtime_resume = &sun4i_gpadc_runtime_resume,
 438};
 439
 440static int sun4i_irq_init(struct platform_device *pdev, const char *name,
 441                          irq_handler_t handler, const char *devname,
 442                          unsigned int *irq, atomic_t *atomic)
 443{
 444        int ret;
 445        struct sun4i_gpadc_dev *mfd_dev = dev_get_drvdata(pdev->dev.parent);
 446        struct sun4i_gpadc_iio *info = iio_priv(dev_get_drvdata(&pdev->dev));
 447
 448        /*
 449         * Once the interrupt is activated, the IP continuously performs
 450         * conversions thus throws interrupts. The interrupt is activated right
 451         * after being requested but we want to control when these interrupts
 452         * occur thus we disable it right after being requested. However, an
 453         * interrupt might occur between these two instructions and we have to
 454         * make sure that does not happen, by using atomic flags. We set the
 455         * flag before requesting the interrupt and unset it right after
 456         * disabling the interrupt. When an interrupt occurs between these two
 457         * instructions, reading the atomic flag will tell us to ignore the
 458         * interrupt.
 459         */
 460        atomic_set(atomic, 1);
 461
 462        ret = platform_get_irq_byname(pdev, name);
 463        if (ret < 0)
 464                return ret;
 465
 466        ret = regmap_irq_get_virq(mfd_dev->regmap_irqc, ret);
 467        if (ret < 0) {
 468                dev_err(&pdev->dev, "failed to get virq for irq %s\n", name);
 469                return ret;
 470        }
 471
 472        *irq = ret;
 473        ret = devm_request_any_context_irq(&pdev->dev, *irq, handler,
 474                                           IRQF_NO_AUTOEN,
 475                                           devname, info);
 476        if (ret < 0) {
 477                dev_err(&pdev->dev, "could not request %s interrupt: %d\n",
 478                        name, ret);
 479                return ret;
 480        }
 481
 482        atomic_set(atomic, 0);
 483
 484        return 0;
 485}
 486
 487static const struct of_device_id sun4i_gpadc_of_id[] = {
 488        {
 489                .compatible = "allwinner,sun8i-a33-ths",
 490                .data = &sun8i_a33_gpadc_data,
 491        },
 492        { /* sentinel */ }
 493};
 494
 495static int sun4i_gpadc_probe_dt(struct platform_device *pdev,
 496                                struct iio_dev *indio_dev)
 497{
 498        struct sun4i_gpadc_iio *info = iio_priv(indio_dev);
 499        void __iomem *base;
 500        int ret;
 501
 502        info->data = of_device_get_match_data(&pdev->dev);
 503        if (!info->data)
 504                return -ENODEV;
 505
 506        info->no_irq = true;
 507        indio_dev->num_channels = ARRAY_SIZE(sun8i_a33_gpadc_channels);
 508        indio_dev->channels = sun8i_a33_gpadc_channels;
 509
 510        base = devm_platform_ioremap_resource(pdev, 0);
 511        if (IS_ERR(base))
 512                return PTR_ERR(base);
 513
 514        info->regmap = devm_regmap_init_mmio(&pdev->dev, base,
 515                                             &sun4i_gpadc_regmap_config);
 516        if (IS_ERR(info->regmap)) {
 517                ret = PTR_ERR(info->regmap);
 518                dev_err(&pdev->dev, "failed to init regmap: %d\n", ret);
 519                return ret;
 520        }
 521
 522        if (IS_ENABLED(CONFIG_THERMAL_OF))
 523                info->sensor_device = &pdev->dev;
 524
 525        return 0;
 526}
 527
 528static int sun4i_gpadc_probe_mfd(struct platform_device *pdev,
 529                                 struct iio_dev *indio_dev)
 530{
 531        struct sun4i_gpadc_iio *info = iio_priv(indio_dev);
 532        struct sun4i_gpadc_dev *sun4i_gpadc_dev =
 533                dev_get_drvdata(pdev->dev.parent);
 534        int ret;
 535
 536        info->no_irq = false;
 537        info->regmap = sun4i_gpadc_dev->regmap;
 538
 539        indio_dev->num_channels = ARRAY_SIZE(sun4i_gpadc_channels);
 540        indio_dev->channels = sun4i_gpadc_channels;
 541
 542        info->data = (struct gpadc_data *)platform_get_device_id(pdev)->driver_data;
 543
 544        /*
 545         * Since the controller needs to be in touchscreen mode for its thermal
 546         * sensor to operate properly, and that switching between the two modes
 547         * needs a delay, always registering in the thermal framework will
 548         * significantly slow down the conversion rate of the ADCs.
 549         *
 550         * Therefore, instead of depending on THERMAL_OF in Kconfig, we only
 551         * register the sensor if that option is enabled, eventually leaving
 552         * that choice to the user.
 553         */
 554
 555        if (IS_ENABLED(CONFIG_THERMAL_OF)) {
 556                /*
 557                 * This driver is a child of an MFD which has a node in the DT
 558                 * but not its children, because of DT backward compatibility
 559                 * for A10, A13 and A31 SoCs. Therefore, the resulting devices
 560                 * of this driver do not have an of_node variable.
 561                 * However, its parent (the MFD driver) has an of_node variable
 562                 * and since devm_thermal_zone_of_sensor_register uses its first
 563                 * argument to match the phandle defined in the node of the
 564                 * thermal driver with the of_node of the device passed as first
 565                 * argument and the third argument to call ops from
 566                 * thermal_zone_of_device_ops, the solution is to use the parent
 567                 * device as first argument to match the phandle with its
 568                 * of_node, and the device from this driver as third argument to
 569                 * return the temperature.
 570                 */
 571                info->sensor_device = pdev->dev.parent;
 572        } else {
 573                indio_dev->num_channels =
 574                        ARRAY_SIZE(sun4i_gpadc_channels_no_temp);
 575                indio_dev->channels = sun4i_gpadc_channels_no_temp;
 576        }
 577
 578        if (IS_ENABLED(CONFIG_THERMAL_OF)) {
 579                ret = sun4i_irq_init(pdev, "TEMP_DATA_PENDING",
 580                                     sun4i_gpadc_temp_data_irq_handler,
 581                                     "temp_data", &info->temp_data_irq,
 582                                     &info->ignore_temp_data_irq);
 583                if (ret < 0)
 584                        return ret;
 585        }
 586
 587        ret = sun4i_irq_init(pdev, "FIFO_DATA_PENDING",
 588                             sun4i_gpadc_fifo_data_irq_handler, "fifo_data",
 589                             &info->fifo_data_irq, &info->ignore_fifo_data_irq);
 590        if (ret < 0)
 591                return ret;
 592
 593        if (IS_ENABLED(CONFIG_THERMAL_OF)) {
 594                ret = iio_map_array_register(indio_dev, sun4i_gpadc_hwmon_maps);
 595                if (ret < 0) {
 596                        dev_err(&pdev->dev,
 597                                "failed to register iio map array\n");
 598                        return ret;
 599                }
 600        }
 601
 602        return 0;
 603}
 604
 605static int sun4i_gpadc_probe(struct platform_device *pdev)
 606{
 607        struct sun4i_gpadc_iio *info;
 608        struct iio_dev *indio_dev;
 609        int ret;
 610
 611        indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*info));
 612        if (!indio_dev)
 613                return -ENOMEM;
 614
 615        info = iio_priv(indio_dev);
 616        platform_set_drvdata(pdev, indio_dev);
 617
 618        mutex_init(&info->mutex);
 619        info->indio_dev = indio_dev;
 620        init_completion(&info->completion);
 621        indio_dev->name = dev_name(&pdev->dev);
 622        indio_dev->info = &sun4i_gpadc_iio_info;
 623        indio_dev->modes = INDIO_DIRECT_MODE;
 624
 625        if (pdev->dev.of_node)
 626                ret = sun4i_gpadc_probe_dt(pdev, indio_dev);
 627        else
 628                ret = sun4i_gpadc_probe_mfd(pdev, indio_dev);
 629
 630        if (ret)
 631                return ret;
 632
 633        pm_runtime_set_autosuspend_delay(&pdev->dev,
 634                                         SUN4I_GPADC_AUTOSUSPEND_DELAY);
 635        pm_runtime_use_autosuspend(&pdev->dev);
 636        pm_runtime_set_suspended(&pdev->dev);
 637        pm_runtime_enable(&pdev->dev);
 638
 639        if (IS_ENABLED(CONFIG_THERMAL_OF)) {
 640                info->tzd = thermal_zone_of_sensor_register(info->sensor_device,
 641                                                            0, info,
 642                                                            &sun4i_ts_tz_ops);
 643                /*
 644                 * Do not fail driver probing when failing to register in
 645                 * thermal because no thermal DT node is found.
 646                 */
 647                if (IS_ERR(info->tzd) && PTR_ERR(info->tzd) != -ENODEV) {
 648                        dev_err(&pdev->dev,
 649                                "could not register thermal sensor: %ld\n",
 650                                PTR_ERR(info->tzd));
 651                        return PTR_ERR(info->tzd);
 652                }
 653        }
 654
 655        ret = devm_iio_device_register(&pdev->dev, indio_dev);
 656        if (ret < 0) {
 657                dev_err(&pdev->dev, "could not register the device\n");
 658                goto err_map;
 659        }
 660
 661        return 0;
 662
 663err_map:
 664        if (!info->no_irq && IS_ENABLED(CONFIG_THERMAL_OF))
 665                iio_map_array_unregister(indio_dev);
 666
 667        pm_runtime_put(&pdev->dev);
 668        pm_runtime_disable(&pdev->dev);
 669
 670        return ret;
 671}
 672
 673static int sun4i_gpadc_remove(struct platform_device *pdev)
 674{
 675        struct iio_dev *indio_dev = platform_get_drvdata(pdev);
 676        struct sun4i_gpadc_iio *info = iio_priv(indio_dev);
 677
 678        pm_runtime_put(&pdev->dev);
 679        pm_runtime_disable(&pdev->dev);
 680
 681        if (!IS_ENABLED(CONFIG_THERMAL_OF))
 682                return 0;
 683
 684        thermal_zone_of_sensor_unregister(info->sensor_device, info->tzd);
 685
 686        if (!info->no_irq)
 687                iio_map_array_unregister(indio_dev);
 688
 689        return 0;
 690}
 691
 692static const struct platform_device_id sun4i_gpadc_id[] = {
 693        { "sun4i-a10-gpadc-iio", (kernel_ulong_t)&sun4i_gpadc_data },
 694        { "sun5i-a13-gpadc-iio", (kernel_ulong_t)&sun5i_gpadc_data },
 695        { "sun6i-a31-gpadc-iio", (kernel_ulong_t)&sun6i_gpadc_data },
 696        { /* sentinel */ },
 697};
 698MODULE_DEVICE_TABLE(platform, sun4i_gpadc_id);
 699
 700static struct platform_driver sun4i_gpadc_driver = {
 701        .driver = {
 702                .name = "sun4i-gpadc-iio",
 703                .of_match_table = sun4i_gpadc_of_id,
 704                .pm = &sun4i_gpadc_pm_ops,
 705        },
 706        .id_table = sun4i_gpadc_id,
 707        .probe = sun4i_gpadc_probe,
 708        .remove = sun4i_gpadc_remove,
 709};
 710MODULE_DEVICE_TABLE(of, sun4i_gpadc_of_id);
 711
 712module_platform_driver(sun4i_gpadc_driver);
 713
 714MODULE_DESCRIPTION("ADC driver for sunxi platforms");
 715MODULE_AUTHOR("Quentin Schulz <quentin.schulz@free-electrons.com>");
 716MODULE_LICENSE("GPL v2");
 717