0001
0002
0003
0004
0005
0006
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
0045
0046
0047
0048
0049
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
0095 regmap_update_bits(priv->regs, MX25_ADCQ_CR, MX25_ADCQ_CR_FQS, 0);
0096
0097
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
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
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
0208
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", ®);
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
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
0266
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 { }
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");