Lines Matching +full:fsl +full:- +full:imx25 +full:- +full:gcq
1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2014-2015 Pengutronix, Markus Pargmann <mpa@pengutronix.de>
5 * This is the driver for the imx25 GCQ (Generic Conversion Queue)
6 * connected to the imx25 ADC.
9 #include <dt-bindings/iio/adc/fsl-imx25-gcq.h>
13 #include <linux/mfd/imx25-tsadc.h>
22 static const char * const driver_name = "mx25-gcq";
86 regmap_read(priv->regs, MX25_ADCQ_SR, &stats); in mx25_gcq_irq()
89 regmap_update_bits(priv->regs, MX25_ADCQ_MR, in mx25_gcq_irq()
91 complete(&priv->completed); in mx25_gcq_irq()
95 regmap_update_bits(priv->regs, MX25_ADCQ_CR, MX25_ADCQ_CR_FQS, 0); in mx25_gcq_irq()
98 regmap_write(priv->regs, MX25_ADCQ_SR, MX25_ADCQ_SR_FRR | in mx25_gcq_irq()
114 regmap_write(priv->regs, MX25_ADCQ_ITEM_7_0, in mx25_gcq_get_raw_value()
115 MX25_ADCQ_ITEM(0, chan->channel)); in mx25_gcq_get_raw_value()
117 regmap_update_bits(priv->regs, MX25_ADCQ_MR, MX25_ADCQ_MR_EOQ_IRQ, 0); in mx25_gcq_get_raw_value()
120 regmap_update_bits(priv->regs, MX25_ADCQ_CR, MX25_ADCQ_CR_FQS, in mx25_gcq_get_raw_value()
124 &priv->completed, MX25_GCQ_TIMEOUT); in mx25_gcq_get_raw_value()
130 return -ETIMEDOUT; in mx25_gcq_get_raw_value()
133 regmap_read(priv->regs, MX25_ADCQ_FIFO, &data); in mx25_gcq_get_raw_value()
149 mutex_lock(&priv->lock); in mx25_gcq_read_raw()
150 ret = mx25_gcq_get_raw_value(&indio_dev->dev, chan, priv, val); in mx25_gcq_read_raw()
151 mutex_unlock(&priv->lock); in mx25_gcq_read_raw()
155 *val = priv->channel_vref_mv[chan->channel]; in mx25_gcq_read_raw()
160 return -EINVAL; in mx25_gcq_read_raw()
181 if (priv->vref[refp]) in mx25_gcq_ext_regulator_setup()
184 ret = snprintf(reg_name, sizeof(reg_name), "vref-%s", in mx25_gcq_ext_regulator_setup()
189 priv->vref[refp] = devm_regulator_get_optional(dev, reg_name); in mx25_gcq_ext_regulator_setup()
190 if (IS_ERR(priv->vref[refp])) in mx25_gcq_ext_regulator_setup()
191 return dev_err_probe(dev, PTR_ERR(priv->vref[refp]), in mx25_gcq_ext_regulator_setup()
201 struct device_node *np = pdev->dev.of_node; in mx25_gcq_setup_cfgs()
203 struct device *dev = &pdev->dev; in mx25_gcq_setup_cfgs()
211 regmap_write(priv->regs, MX25_ADCQ_CFG(i), in mx25_gcq_setup_cfgs()
235 return -EINVAL; in mx25_gcq_setup_cfgs()
238 of_property_read_u32(child, "fsl,adc-refp", &refp); in mx25_gcq_setup_cfgs()
239 of_property_read_u32(child, "fsl,adc-refn", &refn); in mx25_gcq_setup_cfgs()
245 ret = mx25_gcq_ext_regulator_setup(&pdev->dev, priv, refp); in mx25_gcq_setup_cfgs()
250 priv->channel_vref_mv[reg] = in mx25_gcq_setup_cfgs()
251 regulator_get_voltage(priv->vref[refp]); in mx25_gcq_setup_cfgs()
253 priv->channel_vref_mv[reg] /= 1000; in mx25_gcq_setup_cfgs()
256 priv->channel_vref_mv[reg] = 2500; in mx25_gcq_setup_cfgs()
261 return -EINVAL; in mx25_gcq_setup_cfgs()
272 dev_err(dev, "Invalid fsl,adc-refp property value\n"); in mx25_gcq_setup_cfgs()
274 return -EINVAL; in mx25_gcq_setup_cfgs()
277 dev_err(dev, "Invalid fsl,adc-refn property value\n"); in mx25_gcq_setup_cfgs()
279 return -EINVAL; in mx25_gcq_setup_cfgs()
282 regmap_update_bits(priv->regs, MX25_ADCQ_CFG(reg), in mx25_gcq_setup_cfgs()
287 regmap_update_bits(priv->regs, MX25_ADCQ_CR, in mx25_gcq_setup_cfgs()
291 regmap_write(priv->regs, MX25_ADCQ_CR, in mx25_gcq_setup_cfgs()
301 struct mx25_tsadc *tsadc = dev_get_drvdata(pdev->dev.parent); in mx25_gcq_probe()
302 struct device *dev = &pdev->dev; in mx25_gcq_probe()
309 return -ENOMEM; in mx25_gcq_probe()
317 priv->regs = devm_regmap_init_mmio(dev, mem, &mx25_gcq_regconfig); in mx25_gcq_probe()
318 if (IS_ERR(priv->regs)) { in mx25_gcq_probe()
320 return PTR_ERR(priv->regs); in mx25_gcq_probe()
323 mutex_init(&priv->lock); in mx25_gcq_probe()
325 init_completion(&priv->completed); in mx25_gcq_probe()
332 if (!priv->vref[i]) in mx25_gcq_probe()
335 ret = regulator_enable(priv->vref[i]); in mx25_gcq_probe()
340 priv->clk = tsadc->clk; in mx25_gcq_probe()
341 ret = clk_prepare_enable(priv->clk); in mx25_gcq_probe()
351 priv->irq = ret; in mx25_gcq_probe()
352 ret = request_irq(priv->irq, mx25_gcq_irq, 0, pdev->name, priv); in mx25_gcq_probe()
358 indio_dev->channels = mx25_gcq_channels; in mx25_gcq_probe()
359 indio_dev->num_channels = ARRAY_SIZE(mx25_gcq_channels); in mx25_gcq_probe()
360 indio_dev->info = &mx25_gcq_iio_info; in mx25_gcq_probe()
361 indio_dev->name = driver_name; in mx25_gcq_probe()
374 free_irq(priv->irq, priv); in mx25_gcq_probe()
376 clk_disable_unprepare(priv->clk); in mx25_gcq_probe()
380 for (; i-- > 0;) { in mx25_gcq_probe()
381 if (priv->vref[i]) in mx25_gcq_probe()
382 regulator_disable(priv->vref[i]); in mx25_gcq_probe()
394 free_irq(priv->irq, priv); in mx25_gcq_remove()
395 clk_disable_unprepare(priv->clk); in mx25_gcq_remove()
396 for (i = 4; i-- > 0;) { in mx25_gcq_remove()
397 if (priv->vref[i]) in mx25_gcq_remove()
398 regulator_disable(priv->vref[i]); in mx25_gcq_remove()
405 { .compatible = "fsl,imx25-gcq", },
412 .name = "mx25-gcq",