Lines Matching +full:adc +full:- +full:refn
2 * Copyright (C) 2014-2015 Pengutronix, Markus Pargmann <mpa@pengutronix.de>
9 * connected to the imx25 ADC.
12 #include <dt-bindings/iio/adc/fsl-imx25-gcq.h>
16 #include <linux/mfd/imx25-tsadc.h>
25 static const char * const driver_name = "mx25-gcq";
80 regmap_read(priv->regs, MX25_ADCQ_SR, &stats); in mx25_gcq_irq()
83 regmap_update_bits(priv->regs, MX25_ADCQ_MR, in mx25_gcq_irq()
85 complete(&priv->completed); in mx25_gcq_irq()
89 regmap_update_bits(priv->regs, MX25_ADCQ_CR, MX25_ADCQ_CR_FQS, 0); in mx25_gcq_irq()
92 regmap_write(priv->regs, MX25_ADCQ_SR, MX25_ADCQ_SR_FRR | in mx25_gcq_irq()
108 regmap_write(priv->regs, MX25_ADCQ_ITEM_7_0, in mx25_gcq_get_raw_value()
109 MX25_ADCQ_ITEM(0, chan->channel)); in mx25_gcq_get_raw_value()
111 regmap_update_bits(priv->regs, MX25_ADCQ_MR, MX25_ADCQ_MR_EOQ_IRQ, 0); in mx25_gcq_get_raw_value()
114 regmap_update_bits(priv->regs, MX25_ADCQ_CR, MX25_ADCQ_CR_FQS, in mx25_gcq_get_raw_value()
118 &priv->completed, MX25_GCQ_TIMEOUT); in mx25_gcq_get_raw_value()
120 dev_err(dev, "ADC wait for measurement failed\n"); in mx25_gcq_get_raw_value()
123 dev_err(dev, "ADC timed out\n"); in mx25_gcq_get_raw_value()
124 return -ETIMEDOUT; in mx25_gcq_get_raw_value()
127 regmap_read(priv->regs, MX25_ADCQ_FIFO, &data); in mx25_gcq_get_raw_value()
143 mutex_lock(&indio_dev->mlock); in mx25_gcq_read_raw()
144 ret = mx25_gcq_get_raw_value(&indio_dev->dev, chan, priv, val); in mx25_gcq_read_raw()
145 mutex_unlock(&indio_dev->mlock); in mx25_gcq_read_raw()
149 *val = priv->channel_vref_mv[chan->channel]; in mx25_gcq_read_raw()
154 return -EINVAL; in mx25_gcq_read_raw()
172 struct device_node *np = pdev->dev.of_node; in mx25_gcq_setup_cfgs()
174 struct device *dev = &pdev->dev; in mx25_gcq_setup_cfgs()
183 regmap_write(priv->regs, MX25_ADCQ_CFG(i), in mx25_gcq_setup_cfgs()
196 priv->vref[MX25_ADC_REFP_INT] = NULL; in mx25_gcq_setup_cfgs()
197 priv->vref[MX25_ADC_REFP_EXT] = in mx25_gcq_setup_cfgs()
198 devm_regulator_get_optional(&pdev->dev, "vref-ext"); in mx25_gcq_setup_cfgs()
199 priv->vref[MX25_ADC_REFP_XP] = in mx25_gcq_setup_cfgs()
200 devm_regulator_get_optional(&pdev->dev, "vref-xp"); in mx25_gcq_setup_cfgs()
201 priv->vref[MX25_ADC_REFP_YP] = in mx25_gcq_setup_cfgs()
202 devm_regulator_get_optional(&pdev->dev, "vref-yp"); in mx25_gcq_setup_cfgs()
207 u32 refn = MX25_ADCQ_CFG_REFN_NGND2; in mx25_gcq_setup_cfgs() local
220 return -EINVAL; in mx25_gcq_setup_cfgs()
223 of_property_read_u32(child, "fsl,adc-refp", &refp); in mx25_gcq_setup_cfgs()
224 of_property_read_u32(child, "fsl,adc-refn", &refn); in mx25_gcq_setup_cfgs()
230 if (IS_ERR(priv->vref[refp])) { in mx25_gcq_setup_cfgs()
231 dev_err(dev, "Error, trying to use external voltage reference without a vref-%s regulator.", in mx25_gcq_setup_cfgs()
234 return PTR_ERR(priv->vref[refp]); in mx25_gcq_setup_cfgs()
236 priv->channel_vref_mv[reg] = in mx25_gcq_setup_cfgs()
237 regulator_get_voltage(priv->vref[refp]); in mx25_gcq_setup_cfgs()
239 priv->channel_vref_mv[reg] /= 1000; in mx25_gcq_setup_cfgs()
242 priv->channel_vref_mv[reg] = 2500; in mx25_gcq_setup_cfgs()
247 return -EINVAL; in mx25_gcq_setup_cfgs()
257 refn = MX25_ADCQ_CFG_REFN(refn); in mx25_gcq_setup_cfgs()
260 dev_err(dev, "Invalid fsl,adc-refp property value\n"); in mx25_gcq_setup_cfgs()
262 return -EINVAL; in mx25_gcq_setup_cfgs()
264 if ((refn & MX25_ADCQ_CFG_REFN_MASK) != refn) { in mx25_gcq_setup_cfgs()
265 dev_err(dev, "Invalid fsl,adc-refn property value\n"); in mx25_gcq_setup_cfgs()
267 return -EINVAL; in mx25_gcq_setup_cfgs()
270 regmap_update_bits(priv->regs, MX25_ADCQ_CFG(reg), in mx25_gcq_setup_cfgs()
273 refp | refn); in mx25_gcq_setup_cfgs()
275 regmap_update_bits(priv->regs, MX25_ADCQ_CR, in mx25_gcq_setup_cfgs()
279 regmap_write(priv->regs, MX25_ADCQ_CR, in mx25_gcq_setup_cfgs()
285 if (!IS_ERR_OR_NULL(priv->vref[i])) in mx25_gcq_setup_cfgs()
286 devm_regulator_put(priv->vref[i]); in mx25_gcq_setup_cfgs()
287 priv->vref[i] = NULL; in mx25_gcq_setup_cfgs()
298 struct mx25_tsadc *tsadc = dev_get_drvdata(pdev->dev.parent); in mx25_gcq_probe()
299 struct device *dev = &pdev->dev; in mx25_gcq_probe()
305 indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*priv)); in mx25_gcq_probe()
307 return -ENOMEM; in mx25_gcq_probe()
316 priv->regs = devm_regmap_init_mmio(dev, mem, &mx25_gcq_regconfig); in mx25_gcq_probe()
317 if (IS_ERR(priv->regs)) { in mx25_gcq_probe()
319 return PTR_ERR(priv->regs); in mx25_gcq_probe()
322 init_completion(&priv->completed); in mx25_gcq_probe()
329 if (!priv->vref[i]) in mx25_gcq_probe()
332 ret = regulator_enable(priv->vref[i]); in mx25_gcq_probe()
337 priv->clk = tsadc->clk; in mx25_gcq_probe()
338 ret = clk_prepare_enable(priv->clk); in mx25_gcq_probe()
344 priv->irq = platform_get_irq(pdev, 0); in mx25_gcq_probe()
345 if (priv->irq <= 0) { in mx25_gcq_probe()
347 ret = priv->irq; in mx25_gcq_probe()
349 ret = -ENXIO; in mx25_gcq_probe()
353 ret = request_irq(priv->irq, mx25_gcq_irq, 0, pdev->name, priv); in mx25_gcq_probe()
359 indio_dev->dev.parent = &pdev->dev; in mx25_gcq_probe()
360 indio_dev->channels = mx25_gcq_channels; in mx25_gcq_probe()
361 indio_dev->num_channels = ARRAY_SIZE(mx25_gcq_channels); in mx25_gcq_probe()
362 indio_dev->info = &mx25_gcq_iio_info; in mx25_gcq_probe()
363 indio_dev->name = driver_name; in mx25_gcq_probe()
376 free_irq(priv->irq, priv); in mx25_gcq_probe()
378 clk_disable_unprepare(priv->clk); in mx25_gcq_probe()
382 for (; i-- > 0;) { in mx25_gcq_probe()
383 if (priv->vref[i]) in mx25_gcq_probe()
384 regulator_disable(priv->vref[i]); in mx25_gcq_probe()
396 free_irq(priv->irq, priv); in mx25_gcq_remove()
397 clk_disable_unprepare(priv->clk); in mx25_gcq_remove()
398 for (i = 4; i-- > 0;) { in mx25_gcq_remove()
399 if (priv->vref[i]) in mx25_gcq_remove()
400 regulator_disable(priv->vref[i]); in mx25_gcq_remove()
407 { .compatible = "fsl,imx25-gcq", },
414 .name = "mx25-gcq",
422 MODULE_DESCRIPTION("ADC driver for Freescale mx25");