linux/drivers/iio/adc/fsl-imx25-gcq.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright (C) 2014-2015 Pengutronix, Markus Pargmann <mpa@pengutronix.de>
   4 *
   5 * This is the driver for the imx25 GCQ (Generic Conversion Queue)
   6 * connected to the imx25 ADC.
   7 */
   8
   9#include <dt-bindings/iio/adc/fsl-imx25-gcq.h>
  10#include <linux/clk.h>
  11#include <linux/iio/iio.h>
  12#include <linux/interrupt.h>
  13#include <linux/mfd/imx25-tsadc.h>
  14#include <linux/module.h>
  15#include <linux/of.h>
  16#include <linux/platform_device.h>
  17#include <linux/regmap.h>
  18#include <linux/regulator/consumer.h>
  19
  20#define MX25_GCQ_TIMEOUT (msecs_to_jiffies(2000))
  21
  22static const char * const driver_name = "mx25-gcq";
  23
  24enum mx25_gcq_cfgs {
  25        MX25_CFG_XP = 0,
  26        MX25_CFG_YP,
  27        MX25_CFG_XN,
  28        MX25_CFG_YN,
  29        MX25_CFG_WIPER,
  30        MX25_CFG_INAUX0,
  31        MX25_CFG_INAUX1,
  32        MX25_CFG_INAUX2,
  33        MX25_NUM_CFGS,
  34};
  35
  36struct mx25_gcq_priv {
  37        struct regmap *regs;
  38        struct completion completed;
  39        struct clk *clk;
  40        int irq;
  41        struct regulator *vref[4];
  42        u32 channel_vref_mv[MX25_NUM_CFGS];
  43        /*
  44         * Lock to protect the device state during a potential concurrent
  45         * read access from userspace. Reading a raw value requires a sequence
  46         * of register writes, then a wait for a completion callback,
  47         * and finally a register read, during which userspace could issue
  48         * another read request. This lock protects a read access from
  49         * ocurring before another one has finished.
  50         */
  51        struct mutex lock;
  52};
  53
  54#define MX25_CQG_CHAN(chan, id) {\
  55        .type = IIO_VOLTAGE,\
  56        .indexed = 1,\
  57        .channel = chan,\
  58        .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
  59                              BIT(IIO_CHAN_INFO_SCALE),\
  60        .datasheet_name = id,\
  61}
  62
  63static const struct iio_chan_spec mx25_gcq_channels[MX25_NUM_CFGS] = {
  64        MX25_CQG_CHAN(MX25_CFG_XP, "xp"),
  65        MX25_CQG_CHAN(MX25_CFG_YP, "yp"),
  66        MX25_CQG_CHAN(MX25_CFG_XN, "xn"),
  67        MX25_CQG_CHAN(MX25_CFG_YN, "yn"),
  68        MX25_CQG_CHAN(MX25_CFG_WIPER, "wiper"),
  69        MX25_CQG_CHAN(MX25_CFG_INAUX0, "inaux0"),
  70        MX25_CQG_CHAN(MX25_CFG_INAUX1, "inaux1"),
  71        MX25_CQG_CHAN(MX25_CFG_INAUX2, "inaux2"),
  72};
  73
  74static const char * const mx25_gcq_refp_names[] = {
  75        [MX25_ADC_REFP_YP] = "yp",
  76        [MX25_ADC_REFP_XP] = "xp",
  77        [MX25_ADC_REFP_INT] = "int",
  78        [MX25_ADC_REFP_EXT] = "ext",
  79};
  80
  81static irqreturn_t mx25_gcq_irq(int irq, void *data)
  82{
  83        struct mx25_gcq_priv *priv = data;
  84        u32 stats;
  85
  86        regmap_read(priv->regs, MX25_ADCQ_SR, &stats);
  87
  88        if (stats & MX25_ADCQ_SR_EOQ) {
  89                regmap_update_bits(priv->regs, MX25_ADCQ_MR,
  90                                   MX25_ADCQ_MR_EOQ_IRQ, MX25_ADCQ_MR_EOQ_IRQ);
  91                complete(&priv->completed);
  92        }
  93
  94        /* Disable conversion queue run */
  95        regmap_update_bits(priv->regs, MX25_ADCQ_CR, MX25_ADCQ_CR_FQS, 0);
  96
  97        /* Acknowledge all possible irqs */
  98        regmap_write(priv->regs, MX25_ADCQ_SR, MX25_ADCQ_SR_FRR |
  99                     MX25_ADCQ_SR_FUR | MX25_ADCQ_SR_FOR |
 100                     MX25_ADCQ_SR_EOQ | MX25_ADCQ_SR_PD);
 101
 102        return IRQ_HANDLED;
 103}
 104
 105static int mx25_gcq_get_raw_value(struct device *dev,
 106                                  struct iio_chan_spec const *chan,
 107                                  struct mx25_gcq_priv *priv,
 108                                  int *val)
 109{
 110        long timeout;
 111        u32 data;
 112
 113        /* Setup the configuration we want to use */
 114        regmap_write(priv->regs, MX25_ADCQ_ITEM_7_0,
 115                     MX25_ADCQ_ITEM(0, chan->channel));
 116
 117        regmap_update_bits(priv->regs, MX25_ADCQ_MR, MX25_ADCQ_MR_EOQ_IRQ, 0);
 118
 119        /* Trigger queue for one run */
 120        regmap_update_bits(priv->regs, MX25_ADCQ_CR, MX25_ADCQ_CR_FQS,
 121                           MX25_ADCQ_CR_FQS);
 122
 123        timeout = wait_for_completion_interruptible_timeout(
 124                &priv->completed, MX25_GCQ_TIMEOUT);
 125        if (timeout < 0) {
 126                dev_err(dev, "ADC wait for measurement failed\n");
 127                return timeout;
 128        } else if (timeout == 0) {
 129                dev_err(dev, "ADC timed out\n");
 130                return -ETIMEDOUT;
 131        }
 132
 133        regmap_read(priv->regs, MX25_ADCQ_FIFO, &data);
 134
 135        *val = MX25_ADCQ_FIFO_DATA(data);
 136
 137        return IIO_VAL_INT;
 138}
 139
 140static int mx25_gcq_read_raw(struct iio_dev *indio_dev,
 141                             struct iio_chan_spec const *chan, int *val,
 142                             int *val2, long mask)
 143{
 144        struct mx25_gcq_priv *priv = iio_priv(indio_dev);
 145        int ret;
 146
 147        switch (mask) {
 148        case IIO_CHAN_INFO_RAW:
 149                mutex_lock(&priv->lock);
 150                ret = mx25_gcq_get_raw_value(&indio_dev->dev, chan, priv, val);
 151                mutex_unlock(&priv->lock);
 152                return ret;
 153
 154        case IIO_CHAN_INFO_SCALE:
 155                *val = priv->channel_vref_mv[chan->channel];
 156                *val2 = 12;
 157                return IIO_VAL_FRACTIONAL_LOG2;
 158
 159        default:
 160                return -EINVAL;
 161        }
 162}
 163
 164static const struct iio_info mx25_gcq_iio_info = {
 165        .read_raw = mx25_gcq_read_raw,
 166};
 167
 168static const struct regmap_config mx25_gcq_regconfig = {
 169        .max_register = 0x5c,
 170        .reg_bits = 32,
 171        .val_bits = 32,
 172        .reg_stride = 4,
 173};
 174
 175static int mx25_gcq_setup_cfgs(struct platform_device *pdev,
 176                               struct mx25_gcq_priv *priv)
 177{
 178        struct device_node *np = pdev->dev.of_node;
 179        struct device_node *child;
 180        struct device *dev = &pdev->dev;
 181        unsigned int refp_used[4] = {};
 182        int ret, i;
 183
 184        /*
 185         * Setup all configurations registers with a default conversion
 186         * configuration for each input
 187         */
 188        for (i = 0; i < MX25_NUM_CFGS; ++i)
 189                regmap_write(priv->regs, MX25_ADCQ_CFG(i),
 190                             MX25_ADCQ_CFG_YPLL_OFF |
 191                             MX25_ADCQ_CFG_XNUR_OFF |
 192                             MX25_ADCQ_CFG_XPUL_OFF |
 193                             MX25_ADCQ_CFG_REFP_INT |
 194                             MX25_ADCQ_CFG_IN(i) |
 195                             MX25_ADCQ_CFG_REFN_NGND2);
 196
 197        /*
 198         * First get all regulators to store them in channel_vref_mv if
 199         * necessary. Later we use that information for proper IIO scale
 200         * information.
 201         */
 202        priv->vref[MX25_ADC_REFP_INT] = NULL;
 203        priv->vref[MX25_ADC_REFP_EXT] =
 204                devm_regulator_get_optional(dev, "vref-ext");
 205        priv->vref[MX25_ADC_REFP_XP] =
 206                devm_regulator_get_optional(dev, "vref-xp");
 207        priv->vref[MX25_ADC_REFP_YP] =
 208                devm_regulator_get_optional(dev, "vref-yp");
 209
 210        for_each_child_of_node(np, child) {
 211                u32 reg;
 212                u32 refp = MX25_ADCQ_CFG_REFP_INT;
 213                u32 refn = MX25_ADCQ_CFG_REFN_NGND2;
 214
 215                ret = of_property_read_u32(child, "reg", &reg);
 216                if (ret) {
 217                        dev_err(dev, "Failed to get reg property\n");
 218                        of_node_put(child);
 219                        return ret;
 220                }
 221
 222                if (reg >= MX25_NUM_CFGS) {
 223                        dev_err(dev,
 224                                "reg value is greater than the number of available configuration registers\n");
 225                        of_node_put(child);
 226                        return -EINVAL;
 227                }
 228
 229                of_property_read_u32(child, "fsl,adc-refp", &refp);
 230                of_property_read_u32(child, "fsl,adc-refn", &refn);
 231
 232                switch (refp) {
 233                case MX25_ADC_REFP_EXT:
 234                case MX25_ADC_REFP_XP:
 235                case MX25_ADC_REFP_YP:
 236                        if (IS_ERR(priv->vref[refp])) {
 237                                dev_err(dev, "Error, trying to use external voltage reference without a vref-%s regulator.",
 238                                        mx25_gcq_refp_names[refp]);
 239                                of_node_put(child);
 240                                return PTR_ERR(priv->vref[refp]);
 241                        }
 242                        priv->channel_vref_mv[reg] =
 243                                regulator_get_voltage(priv->vref[refp]);
 244                        /* Conversion from uV to mV */
 245                        priv->channel_vref_mv[reg] /= 1000;
 246                        break;
 247                case MX25_ADC_REFP_INT:
 248                        priv->channel_vref_mv[reg] = 2500;
 249                        break;
 250                default:
 251                        dev_err(dev, "Invalid positive reference %d\n", refp);
 252                        of_node_put(child);
 253                        return -EINVAL;
 254                }
 255
 256                ++refp_used[refp];
 257
 258                /*
 259                 * Shift the read values to the correct positions within the
 260                 * register.
 261                 */
 262                refp = MX25_ADCQ_CFG_REFP(refp);
 263                refn = MX25_ADCQ_CFG_REFN(refn);
 264
 265                if ((refp & MX25_ADCQ_CFG_REFP_MASK) != refp) {
 266                        dev_err(dev, "Invalid fsl,adc-refp property value\n");
 267                        of_node_put(child);
 268                        return -EINVAL;
 269                }
 270                if ((refn & MX25_ADCQ_CFG_REFN_MASK) != refn) {
 271                        dev_err(dev, "Invalid fsl,adc-refn property value\n");
 272                        of_node_put(child);
 273                        return -EINVAL;
 274                }
 275
 276                regmap_update_bits(priv->regs, MX25_ADCQ_CFG(reg),
 277                                   MX25_ADCQ_CFG_REFP_MASK |
 278                                   MX25_ADCQ_CFG_REFN_MASK,
 279                                   refp | refn);
 280        }
 281        regmap_update_bits(priv->regs, MX25_ADCQ_CR,
 282                           MX25_ADCQ_CR_FRST | MX25_ADCQ_CR_QRST,
 283                           MX25_ADCQ_CR_FRST | MX25_ADCQ_CR_QRST);
 284
 285        regmap_write(priv->regs, MX25_ADCQ_CR,
 286                     MX25_ADCQ_CR_PDMSK | MX25_ADCQ_CR_QSM_FQS);
 287
 288        /* Remove unused regulators */
 289        for (i = 0; i != 4; ++i) {
 290                if (!refp_used[i]) {
 291                        if (!IS_ERR_OR_NULL(priv->vref[i]))
 292                                devm_regulator_put(priv->vref[i]);
 293                        priv->vref[i] = NULL;
 294                }
 295        }
 296
 297        return 0;
 298}
 299
 300static int mx25_gcq_probe(struct platform_device *pdev)
 301{
 302        struct iio_dev *indio_dev;
 303        struct mx25_gcq_priv *priv;
 304        struct mx25_tsadc *tsadc = dev_get_drvdata(pdev->dev.parent);
 305        struct device *dev = &pdev->dev;
 306        void __iomem *mem;
 307        int ret;
 308        int i;
 309
 310        indio_dev = devm_iio_device_alloc(dev, sizeof(*priv));
 311        if (!indio_dev)
 312                return -ENOMEM;
 313
 314        priv = iio_priv(indio_dev);
 315
 316        mem = devm_platform_ioremap_resource(pdev, 0);
 317        if (IS_ERR(mem))
 318                return PTR_ERR(mem);
 319
 320        priv->regs = devm_regmap_init_mmio(dev, mem, &mx25_gcq_regconfig);
 321        if (IS_ERR(priv->regs)) {
 322                dev_err(dev, "Failed to initialize regmap\n");
 323                return PTR_ERR(priv->regs);
 324        }
 325
 326        mutex_init(&priv->lock);
 327
 328        init_completion(&priv->completed);
 329
 330        ret = mx25_gcq_setup_cfgs(pdev, priv);
 331        if (ret)
 332                return ret;
 333
 334        for (i = 0; i != 4; ++i) {
 335                if (!priv->vref[i])
 336                        continue;
 337
 338                ret = regulator_enable(priv->vref[i]);
 339                if (ret)
 340                        goto err_regulator_disable;
 341        }
 342
 343        priv->clk = tsadc->clk;
 344        ret = clk_prepare_enable(priv->clk);
 345        if (ret) {
 346                dev_err(dev, "Failed to enable clock\n");
 347                goto err_vref_disable;
 348        }
 349
 350        ret = platform_get_irq(pdev, 0);
 351        if (ret < 0)
 352                goto err_clk_unprepare;
 353
 354        priv->irq = ret;
 355        ret = request_irq(priv->irq, mx25_gcq_irq, 0, pdev->name, priv);
 356        if (ret) {
 357                dev_err(dev, "Failed requesting IRQ\n");
 358                goto err_clk_unprepare;
 359        }
 360
 361        indio_dev->channels = mx25_gcq_channels;
 362        indio_dev->num_channels = ARRAY_SIZE(mx25_gcq_channels);
 363        indio_dev->info = &mx25_gcq_iio_info;
 364        indio_dev->name = driver_name;
 365
 366        ret = iio_device_register(indio_dev);
 367        if (ret) {
 368                dev_err(dev, "Failed to register iio device\n");
 369                goto err_irq_free;
 370        }
 371
 372        platform_set_drvdata(pdev, indio_dev);
 373
 374        return 0;
 375
 376err_irq_free:
 377        free_irq(priv->irq, priv);
 378err_clk_unprepare:
 379        clk_disable_unprepare(priv->clk);
 380err_vref_disable:
 381        i = 4;
 382err_regulator_disable:
 383        for (; i-- > 0;) {
 384                if (priv->vref[i])
 385                        regulator_disable(priv->vref[i]);
 386        }
 387        return ret;
 388}
 389
 390static int mx25_gcq_remove(struct platform_device *pdev)
 391{
 392        struct iio_dev *indio_dev = platform_get_drvdata(pdev);
 393        struct mx25_gcq_priv *priv = iio_priv(indio_dev);
 394        int i;
 395
 396        iio_device_unregister(indio_dev);
 397        free_irq(priv->irq, priv);
 398        clk_disable_unprepare(priv->clk);
 399        for (i = 4; i-- > 0;) {
 400                if (priv->vref[i])
 401                        regulator_disable(priv->vref[i]);
 402        }
 403
 404        return 0;
 405}
 406
 407static const struct of_device_id mx25_gcq_ids[] = {
 408        { .compatible = "fsl,imx25-gcq", },
 409        { /* Sentinel */ }
 410};
 411MODULE_DEVICE_TABLE(of, mx25_gcq_ids);
 412
 413static struct platform_driver mx25_gcq_driver = {
 414        .driver         = {
 415                .name   = "mx25-gcq",
 416                .of_match_table = mx25_gcq_ids,
 417        },
 418        .probe          = mx25_gcq_probe,
 419        .remove         = mx25_gcq_remove,
 420};
 421module_platform_driver(mx25_gcq_driver);
 422
 423MODULE_DESCRIPTION("ADC driver for Freescale mx25");
 424MODULE_AUTHOR("Markus Pargmann <mpa@pengutronix.de>");
 425MODULE_LICENSE("GPL v2");
 426