linux/drivers/iio/adc/imx7d_adc.c
<<
>>
Prefs
   1/*
   2 * Freescale i.MX7D ADC driver
   3 *
   4 * Copyright (C) 2015 Freescale Semiconductor, Inc.
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License as published by
   8 * the Free Software Foundation; either version 2 of the License, or
   9 * (at your option) any later version.
  10 */
  11
  12#include <linux/clk.h>
  13#include <linux/completion.h>
  14#include <linux/err.h>
  15#include <linux/interrupt.h>
  16#include <linux/io.h>
  17#include <linux/kernel.h>
  18#include <linux/module.h>
  19#include <linux/platform_device.h>
  20#include <linux/regulator/consumer.h>
  21
  22#include <linux/iio/iio.h>
  23#include <linux/iio/driver.h>
  24#include <linux/iio/sysfs.h>
  25
  26/* ADC register */
  27#define IMX7D_REG_ADC_CH_A_CFG1                 0x00
  28#define IMX7D_REG_ADC_CH_A_CFG2                 0x10
  29#define IMX7D_REG_ADC_CH_B_CFG1                 0x20
  30#define IMX7D_REG_ADC_CH_B_CFG2                 0x30
  31#define IMX7D_REG_ADC_CH_C_CFG1                 0x40
  32#define IMX7D_REG_ADC_CH_C_CFG2                 0x50
  33#define IMX7D_REG_ADC_CH_D_CFG1                 0x60
  34#define IMX7D_REG_ADC_CH_D_CFG2                 0x70
  35#define IMX7D_REG_ADC_CH_SW_CFG                 0x80
  36#define IMX7D_REG_ADC_TIMER_UNIT                0x90
  37#define IMX7D_REG_ADC_DMA_FIFO                  0xa0
  38#define IMX7D_REG_ADC_FIFO_STATUS               0xb0
  39#define IMX7D_REG_ADC_INT_SIG_EN                0xc0
  40#define IMX7D_REG_ADC_INT_EN                    0xd0
  41#define IMX7D_REG_ADC_INT_STATUS                0xe0
  42#define IMX7D_REG_ADC_CHA_B_CNV_RSLT            0xf0
  43#define IMX7D_REG_ADC_CHC_D_CNV_RSLT            0x100
  44#define IMX7D_REG_ADC_CH_SW_CNV_RSLT            0x110
  45#define IMX7D_REG_ADC_DMA_FIFO_DAT              0x120
  46#define IMX7D_REG_ADC_ADC_CFG                   0x130
  47
  48#define IMX7D_REG_ADC_CHANNEL_CFG2_BASE         0x10
  49#define IMX7D_EACH_CHANNEL_REG_OFFSET           0x20
  50
  51#define IMX7D_REG_ADC_CH_CFG1_CHANNEL_EN                        (0x1 << 31)
  52#define IMX7D_REG_ADC_CH_CFG1_CHANNEL_SINGLE                    BIT(30)
  53#define IMX7D_REG_ADC_CH_CFG1_CHANNEL_AVG_EN                    BIT(29)
  54#define IMX7D_REG_ADC_CH_CFG1_CHANNEL_SEL(x)                    ((x) << 24)
  55
  56#define IMX7D_REG_ADC_CH_CFG2_AVG_NUM_4                         (0x0 << 12)
  57#define IMX7D_REG_ADC_CH_CFG2_AVG_NUM_8                         (0x1 << 12)
  58#define IMX7D_REG_ADC_CH_CFG2_AVG_NUM_16                        (0x2 << 12)
  59#define IMX7D_REG_ADC_CH_CFG2_AVG_NUM_32                        (0x3 << 12)
  60
  61#define IMX7D_REG_ADC_TIMER_UNIT_PRE_DIV_4                      (0x0 << 29)
  62#define IMX7D_REG_ADC_TIMER_UNIT_PRE_DIV_8                      (0x1 << 29)
  63#define IMX7D_REG_ADC_TIMER_UNIT_PRE_DIV_16                     (0x2 << 29)
  64#define IMX7D_REG_ADC_TIMER_UNIT_PRE_DIV_32                     (0x3 << 29)
  65#define IMX7D_REG_ADC_TIMER_UNIT_PRE_DIV_64                     (0x4 << 29)
  66#define IMX7D_REG_ADC_TIMER_UNIT_PRE_DIV_128                    (0x5 << 29)
  67
  68#define IMX7D_REG_ADC_ADC_CFG_ADC_CLK_DOWN                      BIT(31)
  69#define IMX7D_REG_ADC_ADC_CFG_ADC_POWER_DOWN                    BIT(1)
  70#define IMX7D_REG_ADC_ADC_CFG_ADC_EN                            BIT(0)
  71
  72#define IMX7D_REG_ADC_INT_CHA_COV_INT_EN                        BIT(8)
  73#define IMX7D_REG_ADC_INT_CHB_COV_INT_EN                        BIT(9)
  74#define IMX7D_REG_ADC_INT_CHC_COV_INT_EN                        BIT(10)
  75#define IMX7D_REG_ADC_INT_CHD_COV_INT_EN                        BIT(11)
  76#define IMX7D_REG_ADC_INT_CHANNEL_INT_EN \
  77        (IMX7D_REG_ADC_INT_CHA_COV_INT_EN | \
  78         IMX7D_REG_ADC_INT_CHB_COV_INT_EN | \
  79         IMX7D_REG_ADC_INT_CHC_COV_INT_EN | \
  80         IMX7D_REG_ADC_INT_CHD_COV_INT_EN)
  81#define IMX7D_REG_ADC_INT_STATUS_CHANNEL_INT_STATUS             0xf00
  82#define IMX7D_REG_ADC_INT_STATUS_CHANNEL_CONV_TIME_OUT          0xf0000
  83
  84#define IMX7D_ADC_TIMEOUT               msecs_to_jiffies(100)
  85
  86enum imx7d_adc_clk_pre_div {
  87        IMX7D_ADC_ANALOG_CLK_PRE_DIV_4,
  88        IMX7D_ADC_ANALOG_CLK_PRE_DIV_8,
  89        IMX7D_ADC_ANALOG_CLK_PRE_DIV_16,
  90        IMX7D_ADC_ANALOG_CLK_PRE_DIV_32,
  91        IMX7D_ADC_ANALOG_CLK_PRE_DIV_64,
  92        IMX7D_ADC_ANALOG_CLK_PRE_DIV_128,
  93};
  94
  95enum imx7d_adc_average_num {
  96        IMX7D_ADC_AVERAGE_NUM_4,
  97        IMX7D_ADC_AVERAGE_NUM_8,
  98        IMX7D_ADC_AVERAGE_NUM_16,
  99        IMX7D_ADC_AVERAGE_NUM_32,
 100};
 101
 102struct imx7d_adc_feature {
 103        enum imx7d_adc_clk_pre_div clk_pre_div;
 104        enum imx7d_adc_average_num avg_num;
 105
 106        u32 core_time_unit;     /* impact the sample rate */
 107
 108        bool average_en;
 109};
 110
 111struct imx7d_adc {
 112        struct device *dev;
 113        void __iomem *regs;
 114        struct clk *clk;
 115
 116        u32 vref_uv;
 117        u32 value;
 118        u32 channel;
 119        u32 pre_div_num;
 120
 121        struct regulator *vref;
 122        struct imx7d_adc_feature adc_feature;
 123
 124        struct completion completion;
 125};
 126
 127struct imx7d_adc_analogue_core_clk {
 128        u32 pre_div;
 129        u32 reg_config;
 130};
 131
 132#define IMX7D_ADC_ANALOGUE_CLK_CONFIG(_pre_div, _reg_conf) {    \
 133        .pre_div = (_pre_div),                                  \
 134        .reg_config = (_reg_conf),                              \
 135}
 136
 137static const struct imx7d_adc_analogue_core_clk imx7d_adc_analogue_clk[] = {
 138        IMX7D_ADC_ANALOGUE_CLK_CONFIG(4, IMX7D_REG_ADC_TIMER_UNIT_PRE_DIV_4),
 139        IMX7D_ADC_ANALOGUE_CLK_CONFIG(8, IMX7D_REG_ADC_TIMER_UNIT_PRE_DIV_8),
 140        IMX7D_ADC_ANALOGUE_CLK_CONFIG(16, IMX7D_REG_ADC_TIMER_UNIT_PRE_DIV_16),
 141        IMX7D_ADC_ANALOGUE_CLK_CONFIG(32, IMX7D_REG_ADC_TIMER_UNIT_PRE_DIV_32),
 142        IMX7D_ADC_ANALOGUE_CLK_CONFIG(64, IMX7D_REG_ADC_TIMER_UNIT_PRE_DIV_64),
 143        IMX7D_ADC_ANALOGUE_CLK_CONFIG(128, IMX7D_REG_ADC_TIMER_UNIT_PRE_DIV_128),
 144};
 145
 146#define IMX7D_ADC_CHAN(_idx) {                                  \
 147        .type = IIO_VOLTAGE,                                    \
 148        .indexed = 1,                                           \
 149        .channel = (_idx),                                      \
 150        .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),           \
 151        .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |  \
 152                                BIT(IIO_CHAN_INFO_SAMP_FREQ),   \
 153}
 154
 155static const struct iio_chan_spec imx7d_adc_iio_channels[] = {
 156        IMX7D_ADC_CHAN(0),
 157        IMX7D_ADC_CHAN(1),
 158        IMX7D_ADC_CHAN(2),
 159        IMX7D_ADC_CHAN(3),
 160        IMX7D_ADC_CHAN(4),
 161        IMX7D_ADC_CHAN(5),
 162        IMX7D_ADC_CHAN(6),
 163        IMX7D_ADC_CHAN(7),
 164        IMX7D_ADC_CHAN(8),
 165        IMX7D_ADC_CHAN(9),
 166        IMX7D_ADC_CHAN(10),
 167        IMX7D_ADC_CHAN(11),
 168        IMX7D_ADC_CHAN(12),
 169        IMX7D_ADC_CHAN(13),
 170        IMX7D_ADC_CHAN(14),
 171        IMX7D_ADC_CHAN(15),
 172};
 173
 174static const u32 imx7d_adc_average_num[] = {
 175        IMX7D_REG_ADC_CH_CFG2_AVG_NUM_4,
 176        IMX7D_REG_ADC_CH_CFG2_AVG_NUM_8,
 177        IMX7D_REG_ADC_CH_CFG2_AVG_NUM_16,
 178        IMX7D_REG_ADC_CH_CFG2_AVG_NUM_32,
 179};
 180
 181static void imx7d_adc_feature_config(struct imx7d_adc *info)
 182{
 183        info->adc_feature.clk_pre_div = IMX7D_ADC_ANALOG_CLK_PRE_DIV_4;
 184        info->adc_feature.avg_num = IMX7D_ADC_AVERAGE_NUM_32;
 185        info->adc_feature.core_time_unit = 1;
 186        info->adc_feature.average_en = true;
 187}
 188
 189static void imx7d_adc_sample_rate_set(struct imx7d_adc *info)
 190{
 191        struct imx7d_adc_feature *adc_feature = &info->adc_feature;
 192        struct imx7d_adc_analogue_core_clk adc_analogure_clk;
 193        u32 i;
 194        u32 tmp_cfg1;
 195        u32 sample_rate = 0;
 196
 197        /*
 198         * Before sample set, disable channel A,B,C,D. Here we
 199         * clear the bit 31 of register REG_ADC_CH_A\B\C\D_CFG1.
 200         */
 201        for (i = 0; i < 4; i++) {
 202                tmp_cfg1 =
 203                        readl(info->regs + i * IMX7D_EACH_CHANNEL_REG_OFFSET);
 204                tmp_cfg1 &= ~IMX7D_REG_ADC_CH_CFG1_CHANNEL_EN;
 205                writel(tmp_cfg1,
 206                       info->regs + i * IMX7D_EACH_CHANNEL_REG_OFFSET);
 207        }
 208
 209        adc_analogure_clk = imx7d_adc_analogue_clk[adc_feature->clk_pre_div];
 210        sample_rate |= adc_analogure_clk.reg_config;
 211        info->pre_div_num = adc_analogure_clk.pre_div;
 212
 213        sample_rate |= adc_feature->core_time_unit;
 214        writel(sample_rate, info->regs + IMX7D_REG_ADC_TIMER_UNIT);
 215}
 216
 217static void imx7d_adc_hw_init(struct imx7d_adc *info)
 218{
 219        u32 cfg;
 220
 221        /* power up and enable adc analogue core */
 222        cfg = readl(info->regs + IMX7D_REG_ADC_ADC_CFG);
 223        cfg &= ~(IMX7D_REG_ADC_ADC_CFG_ADC_CLK_DOWN |
 224                 IMX7D_REG_ADC_ADC_CFG_ADC_POWER_DOWN);
 225        cfg |= IMX7D_REG_ADC_ADC_CFG_ADC_EN;
 226        writel(cfg, info->regs + IMX7D_REG_ADC_ADC_CFG);
 227
 228        /* enable channel A,B,C,D interrupt */
 229        writel(IMX7D_REG_ADC_INT_CHANNEL_INT_EN,
 230               info->regs + IMX7D_REG_ADC_INT_SIG_EN);
 231        writel(IMX7D_REG_ADC_INT_CHANNEL_INT_EN,
 232               info->regs + IMX7D_REG_ADC_INT_EN);
 233
 234        imx7d_adc_sample_rate_set(info);
 235}
 236
 237static void imx7d_adc_channel_set(struct imx7d_adc *info)
 238{
 239        u32 cfg1 = 0;
 240        u32 cfg2;
 241        u32 channel;
 242
 243        channel = info->channel;
 244
 245        /* the channel choose single conversion, and enable average mode */
 246        cfg1 |= (IMX7D_REG_ADC_CH_CFG1_CHANNEL_EN |
 247                 IMX7D_REG_ADC_CH_CFG1_CHANNEL_SINGLE);
 248        if (info->adc_feature.average_en)
 249                cfg1 |= IMX7D_REG_ADC_CH_CFG1_CHANNEL_AVG_EN;
 250
 251        /*
 252         * physical channel 0 chose logical channel A
 253         * physical channel 1 chose logical channel B
 254         * physical channel 2 chose logical channel C
 255         * physical channel 3 chose logical channel D
 256         */
 257        cfg1 |= IMX7D_REG_ADC_CH_CFG1_CHANNEL_SEL(channel);
 258
 259        /*
 260         * read register REG_ADC_CH_A\B\C\D_CFG2, according to the
 261         * channel chosen
 262         */
 263        cfg2 = readl(info->regs + IMX7D_EACH_CHANNEL_REG_OFFSET * channel +
 264                     IMX7D_REG_ADC_CHANNEL_CFG2_BASE);
 265
 266        cfg2 |= imx7d_adc_average_num[info->adc_feature.avg_num];
 267
 268        /*
 269         * write the register REG_ADC_CH_A\B\C\D_CFG2, according to
 270         * the channel chosen
 271         */
 272        writel(cfg2, info->regs + IMX7D_EACH_CHANNEL_REG_OFFSET * channel +
 273               IMX7D_REG_ADC_CHANNEL_CFG2_BASE);
 274        writel(cfg1, info->regs + IMX7D_EACH_CHANNEL_REG_OFFSET * channel);
 275}
 276
 277static u32 imx7d_adc_get_sample_rate(struct imx7d_adc *info)
 278{
 279        /* input clock is always 24MHz */
 280        u32 input_clk = 24000000;
 281        u32 analogue_core_clk;
 282        u32 core_time_unit = info->adc_feature.core_time_unit;
 283        u32 tmp;
 284
 285        analogue_core_clk = input_clk / info->pre_div_num;
 286        tmp = (core_time_unit + 1) * 6;
 287
 288        return analogue_core_clk / tmp;
 289}
 290
 291static int imx7d_adc_read_raw(struct iio_dev *indio_dev,
 292                        struct iio_chan_spec const *chan,
 293                        int *val,
 294                        int *val2,
 295                        long mask)
 296{
 297        struct imx7d_adc *info = iio_priv(indio_dev);
 298
 299        u32 channel;
 300        long ret;
 301
 302        switch (mask) {
 303        case IIO_CHAN_INFO_RAW:
 304                mutex_lock(&indio_dev->mlock);
 305                reinit_completion(&info->completion);
 306
 307                channel = chan->channel & 0x03;
 308                info->channel = channel;
 309                imx7d_adc_channel_set(info);
 310
 311                ret = wait_for_completion_interruptible_timeout
 312                                (&info->completion, IMX7D_ADC_TIMEOUT);
 313                if (ret == 0) {
 314                        mutex_unlock(&indio_dev->mlock);
 315                        return -ETIMEDOUT;
 316                }
 317                if (ret < 0) {
 318                        mutex_unlock(&indio_dev->mlock);
 319                        return ret;
 320                }
 321
 322                *val = info->value;
 323                mutex_unlock(&indio_dev->mlock);
 324                return IIO_VAL_INT;
 325
 326        case IIO_CHAN_INFO_SCALE:
 327                info->vref_uv = regulator_get_voltage(info->vref);
 328                *val = info->vref_uv / 1000;
 329                *val2 = 12;
 330                return IIO_VAL_FRACTIONAL_LOG2;
 331
 332        case IIO_CHAN_INFO_SAMP_FREQ:
 333                *val = imx7d_adc_get_sample_rate(info);
 334                return IIO_VAL_INT;
 335
 336        default:
 337                return -EINVAL;
 338        }
 339}
 340
 341static int imx7d_adc_read_data(struct imx7d_adc *info)
 342{
 343        u32 channel;
 344        u32 value;
 345
 346        channel = info->channel & 0x03;
 347
 348        /*
 349         * channel A and B conversion result share one register,
 350         * bit[27~16] is the channel B conversion result,
 351         * bit[11~0] is the channel A conversion result.
 352         * channel C and D is the same.
 353         */
 354        if (channel < 2)
 355                value = readl(info->regs + IMX7D_REG_ADC_CHA_B_CNV_RSLT);
 356        else
 357                value = readl(info->regs + IMX7D_REG_ADC_CHC_D_CNV_RSLT);
 358        if (channel & 0x1)      /* channel B or D */
 359                value = (value >> 16) & 0xFFF;
 360        else                    /* channel A or C */
 361                value &= 0xFFF;
 362
 363        return value;
 364}
 365
 366static irqreturn_t imx7d_adc_isr(int irq, void *dev_id)
 367{
 368        struct imx7d_adc *info = (struct imx7d_adc *)dev_id;
 369        int status;
 370
 371        status = readl(info->regs + IMX7D_REG_ADC_INT_STATUS);
 372        if (status & IMX7D_REG_ADC_INT_STATUS_CHANNEL_INT_STATUS) {
 373                info->value = imx7d_adc_read_data(info);
 374                complete(&info->completion);
 375
 376                /*
 377                 * The register IMX7D_REG_ADC_INT_STATUS can't clear
 378                 * itself after read operation, need software to write
 379                 * 0 to the related bit. Here we clear the channel A/B/C/D
 380                 * conversion finished flag.
 381                 */
 382                status &= ~IMX7D_REG_ADC_INT_STATUS_CHANNEL_INT_STATUS;
 383                writel(status, info->regs + IMX7D_REG_ADC_INT_STATUS);
 384        }
 385
 386        /*
 387         * If the channel A/B/C/D conversion timeout, report it and clear these
 388         * timeout flags.
 389         */
 390        if (status & IMX7D_REG_ADC_INT_STATUS_CHANNEL_CONV_TIME_OUT) {
 391                pr_err("%s: ADC got conversion time out interrupt: 0x%08x\n",
 392                        dev_name(info->dev), status);
 393                status &= ~IMX7D_REG_ADC_INT_STATUS_CHANNEL_CONV_TIME_OUT;
 394                writel(status, info->regs + IMX7D_REG_ADC_INT_STATUS);
 395        }
 396
 397        return IRQ_HANDLED;
 398}
 399
 400static int imx7d_adc_reg_access(struct iio_dev *indio_dev,
 401                        unsigned reg, unsigned writeval,
 402                        unsigned *readval)
 403{
 404        struct imx7d_adc *info = iio_priv(indio_dev);
 405
 406        if (!readval || reg % 4 || reg > IMX7D_REG_ADC_ADC_CFG)
 407                return -EINVAL;
 408
 409        *readval = readl(info->regs + reg);
 410
 411        return 0;
 412}
 413
 414static const struct iio_info imx7d_adc_iio_info = {
 415        .driver_module = THIS_MODULE,
 416        .read_raw = &imx7d_adc_read_raw,
 417        .debugfs_reg_access = &imx7d_adc_reg_access,
 418};
 419
 420static const struct of_device_id imx7d_adc_match[] = {
 421        { .compatible = "fsl,imx7d-adc", },
 422        { /* sentinel */ }
 423};
 424MODULE_DEVICE_TABLE(of, imx7d_adc_match);
 425
 426static void imx7d_adc_power_down(struct imx7d_adc *info)
 427{
 428        u32 adc_cfg;
 429
 430        adc_cfg = readl(info->regs + IMX7D_REG_ADC_ADC_CFG);
 431        adc_cfg |= IMX7D_REG_ADC_ADC_CFG_ADC_CLK_DOWN |
 432                   IMX7D_REG_ADC_ADC_CFG_ADC_POWER_DOWN;
 433        adc_cfg &= ~IMX7D_REG_ADC_ADC_CFG_ADC_EN;
 434        writel(adc_cfg, info->regs + IMX7D_REG_ADC_ADC_CFG);
 435}
 436
 437static int imx7d_adc_probe(struct platform_device *pdev)
 438{
 439        struct imx7d_adc *info;
 440        struct iio_dev *indio_dev;
 441        struct resource *mem;
 442        int irq;
 443        int ret;
 444
 445        indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*info));
 446        if (!indio_dev) {
 447                dev_err(&pdev->dev, "Failed allocating iio device\n");
 448                return -ENOMEM;
 449        }
 450
 451        info = iio_priv(indio_dev);
 452        info->dev = &pdev->dev;
 453
 454        mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 455        info->regs = devm_ioremap_resource(&pdev->dev, mem);
 456        if (IS_ERR(info->regs)) {
 457                ret = PTR_ERR(info->regs);
 458                dev_err(&pdev->dev,
 459                        "Failed to remap adc memory, err = %d\n", ret);
 460                return ret;
 461        }
 462
 463        irq = platform_get_irq(pdev, 0);
 464        if (irq < 0) {
 465                dev_err(&pdev->dev, "No irq resource?\n");
 466                return irq;
 467        }
 468
 469        info->clk = devm_clk_get(&pdev->dev, "adc");
 470        if (IS_ERR(info->clk)) {
 471                ret = PTR_ERR(info->clk);
 472                dev_err(&pdev->dev, "Failed getting clock, err = %d\n", ret);
 473                return ret;
 474        }
 475
 476        info->vref = devm_regulator_get(&pdev->dev, "vref");
 477        if (IS_ERR(info->vref)) {
 478                ret = PTR_ERR(info->vref);
 479                dev_err(&pdev->dev,
 480                        "Failed getting reference voltage, err = %d\n", ret);
 481                return ret;
 482        }
 483
 484        ret = regulator_enable(info->vref);
 485        if (ret) {
 486                dev_err(&pdev->dev,
 487                        "Can't enable adc reference top voltage, err = %d\n",
 488                        ret);
 489                return ret;
 490        }
 491
 492        platform_set_drvdata(pdev, indio_dev);
 493
 494        init_completion(&info->completion);
 495
 496        indio_dev->name = dev_name(&pdev->dev);
 497        indio_dev->dev.parent = &pdev->dev;
 498        indio_dev->info = &imx7d_adc_iio_info;
 499        indio_dev->modes = INDIO_DIRECT_MODE;
 500        indio_dev->channels = imx7d_adc_iio_channels;
 501        indio_dev->num_channels = ARRAY_SIZE(imx7d_adc_iio_channels);
 502
 503        ret = clk_prepare_enable(info->clk);
 504        if (ret) {
 505                dev_err(&pdev->dev,
 506                        "Could not prepare or enable the clock.\n");
 507                goto error_adc_clk_enable;
 508        }
 509
 510        ret = devm_request_irq(info->dev, irq,
 511                                imx7d_adc_isr, 0,
 512                                dev_name(&pdev->dev), info);
 513        if (ret < 0) {
 514                dev_err(&pdev->dev, "Failed requesting irq, irq = %d\n", irq);
 515                goto error_iio_device_register;
 516        }
 517
 518        imx7d_adc_feature_config(info);
 519        imx7d_adc_hw_init(info);
 520
 521        ret = iio_device_register(indio_dev);
 522        if (ret) {
 523                imx7d_adc_power_down(info);
 524                dev_err(&pdev->dev, "Couldn't register the device.\n");
 525                goto error_iio_device_register;
 526        }
 527
 528        return 0;
 529
 530error_iio_device_register:
 531        clk_disable_unprepare(info->clk);
 532error_adc_clk_enable:
 533        regulator_disable(info->vref);
 534
 535        return ret;
 536}
 537
 538static int imx7d_adc_remove(struct platform_device *pdev)
 539{
 540        struct iio_dev *indio_dev = platform_get_drvdata(pdev);
 541        struct imx7d_adc *info = iio_priv(indio_dev);
 542
 543        iio_device_unregister(indio_dev);
 544
 545        imx7d_adc_power_down(info);
 546
 547        clk_disable_unprepare(info->clk);
 548        regulator_disable(info->vref);
 549
 550        return 0;
 551}
 552
 553static int __maybe_unused imx7d_adc_suspend(struct device *dev)
 554{
 555        struct iio_dev *indio_dev = dev_get_drvdata(dev);
 556        struct imx7d_adc *info = iio_priv(indio_dev);
 557
 558        imx7d_adc_power_down(info);
 559
 560        clk_disable_unprepare(info->clk);
 561        regulator_disable(info->vref);
 562
 563        return 0;
 564}
 565
 566static int __maybe_unused imx7d_adc_resume(struct device *dev)
 567{
 568        struct iio_dev *indio_dev = dev_get_drvdata(dev);
 569        struct imx7d_adc *info = iio_priv(indio_dev);
 570        int ret;
 571
 572        ret = regulator_enable(info->vref);
 573        if (ret) {
 574                dev_err(info->dev,
 575                        "Can't enable adc reference top voltage, err = %d\n",
 576                        ret);
 577                return ret;
 578        }
 579
 580        ret = clk_prepare_enable(info->clk);
 581        if (ret) {
 582                dev_err(info->dev,
 583                        "Could not prepare or enable clock.\n");
 584                regulator_disable(info->vref);
 585                return ret;
 586        }
 587
 588        imx7d_adc_hw_init(info);
 589
 590        return 0;
 591}
 592
 593static SIMPLE_DEV_PM_OPS(imx7d_adc_pm_ops, imx7d_adc_suspend, imx7d_adc_resume);
 594
 595static struct platform_driver imx7d_adc_driver = {
 596        .probe          = imx7d_adc_probe,
 597        .remove         = imx7d_adc_remove,
 598        .driver         = {
 599                .name   = "imx7d_adc",
 600                .of_match_table = imx7d_adc_match,
 601                .pm     = &imx7d_adc_pm_ops,
 602        },
 603};
 604
 605module_platform_driver(imx7d_adc_driver);
 606
 607MODULE_AUTHOR("Haibo Chen <haibo.chen@freescale.com>");
 608MODULE_DESCRIPTION("Freeacale IMX7D ADC driver");
 609MODULE_LICENSE("GPL v2");
 610