Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (C) 2014-2015 Pengutronix, Markus Pargmann <mpa@pengutronix.de>
0004  *
0005  * This is the driver for the imx25 GCQ (Generic Conversion Queue)
0006  * connected to the imx25 ADC.
0007  */
0008 
0009 #include <dt-bindings/iio/adc/fsl-imx25-gcq.h>
0010 #include <linux/clk.h>
0011 #include <linux/iio/iio.h>
0012 #include <linux/interrupt.h>
0013 #include <linux/mfd/imx25-tsadc.h>
0014 #include <linux/module.h>
0015 #include <linux/of.h>
0016 #include <linux/platform_device.h>
0017 #include <linux/regmap.h>
0018 #include <linux/regulator/consumer.h>
0019 
0020 #define MX25_GCQ_TIMEOUT (msecs_to_jiffies(2000))
0021 
0022 static const char * const driver_name = "mx25-gcq";
0023 
0024 enum mx25_gcq_cfgs {
0025     MX25_CFG_XP = 0,
0026     MX25_CFG_YP,
0027     MX25_CFG_XN,
0028     MX25_CFG_YN,
0029     MX25_CFG_WIPER,
0030     MX25_CFG_INAUX0,
0031     MX25_CFG_INAUX1,
0032     MX25_CFG_INAUX2,
0033     MX25_NUM_CFGS,
0034 };
0035 
0036 struct mx25_gcq_priv {
0037     struct regmap *regs;
0038     struct completion completed;
0039     struct clk *clk;
0040     int irq;
0041     struct regulator *vref[4];
0042     u32 channel_vref_mv[MX25_NUM_CFGS];
0043     /*
0044      * Lock to protect the device state during a potential concurrent
0045      * read access from userspace. Reading a raw value requires a sequence
0046      * of register writes, then a wait for a completion callback,
0047      * and finally a register read, during which userspace could issue
0048      * another read request. This lock protects a read access from
0049      * ocurring before another one has finished.
0050      */
0051     struct mutex lock;
0052 };
0053 
0054 #define MX25_CQG_CHAN(chan, id) {\
0055     .type = IIO_VOLTAGE,\
0056     .indexed = 1,\
0057     .channel = chan,\
0058     .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
0059                   BIT(IIO_CHAN_INFO_SCALE),\
0060     .datasheet_name = id,\
0061 }
0062 
0063 static const struct iio_chan_spec mx25_gcq_channels[MX25_NUM_CFGS] = {
0064     MX25_CQG_CHAN(MX25_CFG_XP, "xp"),
0065     MX25_CQG_CHAN(MX25_CFG_YP, "yp"),
0066     MX25_CQG_CHAN(MX25_CFG_XN, "xn"),
0067     MX25_CQG_CHAN(MX25_CFG_YN, "yn"),
0068     MX25_CQG_CHAN(MX25_CFG_WIPER, "wiper"),
0069     MX25_CQG_CHAN(MX25_CFG_INAUX0, "inaux0"),
0070     MX25_CQG_CHAN(MX25_CFG_INAUX1, "inaux1"),
0071     MX25_CQG_CHAN(MX25_CFG_INAUX2, "inaux2"),
0072 };
0073 
0074 static const char * const mx25_gcq_refp_names[] = {
0075     [MX25_ADC_REFP_YP] = "yp",
0076     [MX25_ADC_REFP_XP] = "xp",
0077     [MX25_ADC_REFP_INT] = "int",
0078     [MX25_ADC_REFP_EXT] = "ext",
0079 };
0080 
0081 static irqreturn_t mx25_gcq_irq(int irq, void *data)
0082 {
0083     struct mx25_gcq_priv *priv = data;
0084     u32 stats;
0085 
0086     regmap_read(priv->regs, MX25_ADCQ_SR, &stats);
0087 
0088     if (stats & MX25_ADCQ_SR_EOQ) {
0089         regmap_update_bits(priv->regs, MX25_ADCQ_MR,
0090                    MX25_ADCQ_MR_EOQ_IRQ, MX25_ADCQ_MR_EOQ_IRQ);
0091         complete(&priv->completed);
0092     }
0093 
0094     /* Disable conversion queue run */
0095     regmap_update_bits(priv->regs, MX25_ADCQ_CR, MX25_ADCQ_CR_FQS, 0);
0096 
0097     /* Acknowledge all possible irqs */
0098     regmap_write(priv->regs, MX25_ADCQ_SR, MX25_ADCQ_SR_FRR |
0099              MX25_ADCQ_SR_FUR | MX25_ADCQ_SR_FOR |
0100              MX25_ADCQ_SR_EOQ | MX25_ADCQ_SR_PD);
0101 
0102     return IRQ_HANDLED;
0103 }
0104 
0105 static int mx25_gcq_get_raw_value(struct device *dev,
0106                   struct iio_chan_spec const *chan,
0107                   struct mx25_gcq_priv *priv,
0108                   int *val)
0109 {
0110     long timeout;
0111     u32 data;
0112 
0113     /* Setup the configuration we want to use */
0114     regmap_write(priv->regs, MX25_ADCQ_ITEM_7_0,
0115              MX25_ADCQ_ITEM(0, chan->channel));
0116 
0117     regmap_update_bits(priv->regs, MX25_ADCQ_MR, MX25_ADCQ_MR_EOQ_IRQ, 0);
0118 
0119     /* Trigger queue for one run */
0120     regmap_update_bits(priv->regs, MX25_ADCQ_CR, MX25_ADCQ_CR_FQS,
0121                MX25_ADCQ_CR_FQS);
0122 
0123     timeout = wait_for_completion_interruptible_timeout(
0124         &priv->completed, MX25_GCQ_TIMEOUT);
0125     if (timeout < 0) {
0126         dev_err(dev, "ADC wait for measurement failed\n");
0127         return timeout;
0128     } else if (timeout == 0) {
0129         dev_err(dev, "ADC timed out\n");
0130         return -ETIMEDOUT;
0131     }
0132 
0133     regmap_read(priv->regs, MX25_ADCQ_FIFO, &data);
0134 
0135     *val = MX25_ADCQ_FIFO_DATA(data);
0136 
0137     return IIO_VAL_INT;
0138 }
0139 
0140 static int mx25_gcq_read_raw(struct iio_dev *indio_dev,
0141                  struct iio_chan_spec const *chan, int *val,
0142                  int *val2, long mask)
0143 {
0144     struct mx25_gcq_priv *priv = iio_priv(indio_dev);
0145     int ret;
0146 
0147     switch (mask) {
0148     case IIO_CHAN_INFO_RAW:
0149         mutex_lock(&priv->lock);
0150         ret = mx25_gcq_get_raw_value(&indio_dev->dev, chan, priv, val);
0151         mutex_unlock(&priv->lock);
0152         return ret;
0153 
0154     case IIO_CHAN_INFO_SCALE:
0155         *val = priv->channel_vref_mv[chan->channel];
0156         *val2 = 12;
0157         return IIO_VAL_FRACTIONAL_LOG2;
0158 
0159     default:
0160         return -EINVAL;
0161     }
0162 }
0163 
0164 static const struct iio_info mx25_gcq_iio_info = {
0165     .read_raw = mx25_gcq_read_raw,
0166 };
0167 
0168 static const struct regmap_config mx25_gcq_regconfig = {
0169     .max_register = 0x5c,
0170     .reg_bits = 32,
0171     .val_bits = 32,
0172     .reg_stride = 4,
0173 };
0174 
0175 static int mx25_gcq_ext_regulator_setup(struct device *dev,
0176                     struct mx25_gcq_priv *priv, u32 refp)
0177 {
0178     char reg_name[12];
0179     int ret;
0180 
0181     if (priv->vref[refp])
0182         return 0;
0183 
0184     ret = snprintf(reg_name, sizeof(reg_name), "vref-%s",
0185                mx25_gcq_refp_names[refp]);
0186     if (ret < 0)
0187         return ret;
0188 
0189     priv->vref[refp] = devm_regulator_get_optional(dev, reg_name);
0190     if (IS_ERR(priv->vref[refp]))
0191         return dev_err_probe(dev, PTR_ERR(priv->vref[refp]),
0192                      "Error, trying to use external voltage reference without a %s regulator.",
0193                      reg_name);
0194 
0195     return 0;
0196 }
0197 
0198 static int mx25_gcq_setup_cfgs(struct platform_device *pdev,
0199                    struct mx25_gcq_priv *priv)
0200 {
0201     struct device_node *np = pdev->dev.of_node;
0202     struct device_node *child;
0203     struct device *dev = &pdev->dev;
0204     int ret, i;
0205 
0206     /*
0207      * Setup all configurations registers with a default conversion
0208      * configuration for each input
0209      */
0210     for (i = 0; i < MX25_NUM_CFGS; ++i)
0211         regmap_write(priv->regs, MX25_ADCQ_CFG(i),
0212                  MX25_ADCQ_CFG_YPLL_OFF |
0213                  MX25_ADCQ_CFG_XNUR_OFF |
0214                  MX25_ADCQ_CFG_XPUL_OFF |
0215                  MX25_ADCQ_CFG_REFP_INT |
0216                  MX25_ADCQ_CFG_IN(i) |
0217                  MX25_ADCQ_CFG_REFN_NGND2);
0218 
0219     for_each_child_of_node(np, child) {
0220         u32 reg;
0221         u32 refp = MX25_ADCQ_CFG_REFP_INT;
0222         u32 refn = MX25_ADCQ_CFG_REFN_NGND2;
0223 
0224         ret = of_property_read_u32(child, "reg", &reg);
0225         if (ret) {
0226             dev_err(dev, "Failed to get reg property\n");
0227             of_node_put(child);
0228             return ret;
0229         }
0230 
0231         if (reg >= MX25_NUM_CFGS) {
0232             dev_err(dev,
0233                 "reg value is greater than the number of available configuration registers\n");
0234             of_node_put(child);
0235             return -EINVAL;
0236         }
0237 
0238         of_property_read_u32(child, "fsl,adc-refp", &refp);
0239         of_property_read_u32(child, "fsl,adc-refn", &refn);
0240 
0241         switch (refp) {
0242         case MX25_ADC_REFP_EXT:
0243         case MX25_ADC_REFP_XP:
0244         case MX25_ADC_REFP_YP:
0245             ret = mx25_gcq_ext_regulator_setup(&pdev->dev, priv, refp);
0246             if (ret) {
0247                 of_node_put(child);
0248                 return ret;
0249             }
0250             priv->channel_vref_mv[reg] =
0251                 regulator_get_voltage(priv->vref[refp]);
0252             /* Conversion from uV to mV */
0253             priv->channel_vref_mv[reg] /= 1000;
0254             break;
0255         case MX25_ADC_REFP_INT:
0256             priv->channel_vref_mv[reg] = 2500;
0257             break;
0258         default:
0259             dev_err(dev, "Invalid positive reference %d\n", refp);
0260             of_node_put(child);
0261             return -EINVAL;
0262         }
0263 
0264         /*
0265          * Shift the read values to the correct positions within the
0266          * register.
0267          */
0268         refp = MX25_ADCQ_CFG_REFP(refp);
0269         refn = MX25_ADCQ_CFG_REFN(refn);
0270 
0271         if ((refp & MX25_ADCQ_CFG_REFP_MASK) != refp) {
0272             dev_err(dev, "Invalid fsl,adc-refp property value\n");
0273             of_node_put(child);
0274             return -EINVAL;
0275         }
0276         if ((refn & MX25_ADCQ_CFG_REFN_MASK) != refn) {
0277             dev_err(dev, "Invalid fsl,adc-refn property value\n");
0278             of_node_put(child);
0279             return -EINVAL;
0280         }
0281 
0282         regmap_update_bits(priv->regs, MX25_ADCQ_CFG(reg),
0283                    MX25_ADCQ_CFG_REFP_MASK |
0284                    MX25_ADCQ_CFG_REFN_MASK,
0285                    refp | refn);
0286     }
0287     regmap_update_bits(priv->regs, MX25_ADCQ_CR,
0288                MX25_ADCQ_CR_FRST | MX25_ADCQ_CR_QRST,
0289                MX25_ADCQ_CR_FRST | MX25_ADCQ_CR_QRST);
0290 
0291     regmap_write(priv->regs, MX25_ADCQ_CR,
0292              MX25_ADCQ_CR_PDMSK | MX25_ADCQ_CR_QSM_FQS);
0293 
0294     return 0;
0295 }
0296 
0297 static int mx25_gcq_probe(struct platform_device *pdev)
0298 {
0299     struct iio_dev *indio_dev;
0300     struct mx25_gcq_priv *priv;
0301     struct mx25_tsadc *tsadc = dev_get_drvdata(pdev->dev.parent);
0302     struct device *dev = &pdev->dev;
0303     void __iomem *mem;
0304     int ret;
0305     int i;
0306 
0307     indio_dev = devm_iio_device_alloc(dev, sizeof(*priv));
0308     if (!indio_dev)
0309         return -ENOMEM;
0310 
0311     priv = iio_priv(indio_dev);
0312 
0313     mem = devm_platform_ioremap_resource(pdev, 0);
0314     if (IS_ERR(mem))
0315         return PTR_ERR(mem);
0316 
0317     priv->regs = devm_regmap_init_mmio(dev, mem, &mx25_gcq_regconfig);
0318     if (IS_ERR(priv->regs)) {
0319         dev_err(dev, "Failed to initialize regmap\n");
0320         return PTR_ERR(priv->regs);
0321     }
0322 
0323     mutex_init(&priv->lock);
0324 
0325     init_completion(&priv->completed);
0326 
0327     ret = mx25_gcq_setup_cfgs(pdev, priv);
0328     if (ret)
0329         return ret;
0330 
0331     for (i = 0; i != 4; ++i) {
0332         if (!priv->vref[i])
0333             continue;
0334 
0335         ret = regulator_enable(priv->vref[i]);
0336         if (ret)
0337             goto err_regulator_disable;
0338     }
0339 
0340     priv->clk = tsadc->clk;
0341     ret = clk_prepare_enable(priv->clk);
0342     if (ret) {
0343         dev_err(dev, "Failed to enable clock\n");
0344         goto err_vref_disable;
0345     }
0346 
0347     ret = platform_get_irq(pdev, 0);
0348     if (ret < 0)
0349         goto err_clk_unprepare;
0350 
0351     priv->irq = ret;
0352     ret = request_irq(priv->irq, mx25_gcq_irq, 0, pdev->name, priv);
0353     if (ret) {
0354         dev_err(dev, "Failed requesting IRQ\n");
0355         goto err_clk_unprepare;
0356     }
0357 
0358     indio_dev->channels = mx25_gcq_channels;
0359     indio_dev->num_channels = ARRAY_SIZE(mx25_gcq_channels);
0360     indio_dev->info = &mx25_gcq_iio_info;
0361     indio_dev->name = driver_name;
0362 
0363     ret = iio_device_register(indio_dev);
0364     if (ret) {
0365         dev_err(dev, "Failed to register iio device\n");
0366         goto err_irq_free;
0367     }
0368 
0369     platform_set_drvdata(pdev, indio_dev);
0370 
0371     return 0;
0372 
0373 err_irq_free:
0374     free_irq(priv->irq, priv);
0375 err_clk_unprepare:
0376     clk_disable_unprepare(priv->clk);
0377 err_vref_disable:
0378     i = 4;
0379 err_regulator_disable:
0380     for (; i-- > 0;) {
0381         if (priv->vref[i])
0382             regulator_disable(priv->vref[i]);
0383     }
0384     return ret;
0385 }
0386 
0387 static int mx25_gcq_remove(struct platform_device *pdev)
0388 {
0389     struct iio_dev *indio_dev = platform_get_drvdata(pdev);
0390     struct mx25_gcq_priv *priv = iio_priv(indio_dev);
0391     int i;
0392 
0393     iio_device_unregister(indio_dev);
0394     free_irq(priv->irq, priv);
0395     clk_disable_unprepare(priv->clk);
0396     for (i = 4; i-- > 0;) {
0397         if (priv->vref[i])
0398             regulator_disable(priv->vref[i]);
0399     }
0400 
0401     return 0;
0402 }
0403 
0404 static const struct of_device_id mx25_gcq_ids[] = {
0405     { .compatible = "fsl,imx25-gcq", },
0406     { /* Sentinel */ }
0407 };
0408 MODULE_DEVICE_TABLE(of, mx25_gcq_ids);
0409 
0410 static struct platform_driver mx25_gcq_driver = {
0411     .driver     = {
0412         .name   = "mx25-gcq",
0413         .of_match_table = mx25_gcq_ids,
0414     },
0415     .probe      = mx25_gcq_probe,
0416     .remove     = mx25_gcq_remove,
0417 };
0418 module_platform_driver(mx25_gcq_driver);
0419 
0420 MODULE_DESCRIPTION("ADC driver for Freescale mx25");
0421 MODULE_AUTHOR("Markus Pargmann <mpa@pengutronix.de>");
0422 MODULE_LICENSE("GPL v2");