[PATCH v5 3/6] iio: adc: fsl,imx25-gcq driver

Jonathan Cameron jic23 at kernel.org
Sun Feb 8 03:56:57 PST 2015


On 29/01/15 10:11, Markus Pargmann wrote:
> On Tue, Jan 27, 2015 at 08:30:56PM +0000, Jonathan Cameron wrote:
>> On 24/01/15 14:01, Markus Pargmann wrote:
>>> This is a conversion queue driver for the mx25 SoC. It uses the central
>>> ADC which is used by two seperate independent queues. This driver
>>> prepares different conversion configurations for each possible input.
>>> For a conversion it creates a conversionqueue of one item with the
>>> correct configuration for the chosen channel. It then executes the queue
>>> once and disables the conversion queue afterwards.
>>>
>>> The reference voltages are configurable through devicetree subnodes,
>>> depending on the connections of the ADC inputs.
>>>
>>> Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
>>> Signed-off-by: Denis Carikli <denis at eukrea.com>
>> A couple of queries inline.
>>> ---
>>>
>>> Notes:
>>>     Changes in v5:
>>>      - Fixed locking
>>>      - Removed module owner
>>>
>>>  .../devicetree/bindings/iio/adc/fsl,imx25-gcq.txt  |  51 +++
>>>  drivers/iio/adc/Kconfig                            |   7 +
>>>  drivers/iio/adc/Makefile                           |   1 +
>>>  drivers/iio/adc/fsl-imx25-gcq.c                    | 369 +++++++++++++++++++++
>>>  include/dt-bindings/iio/adc/fsl-imx25-gcq.h        |  11 +
>>>  5 files changed, 439 insertions(+)
>>>  create mode 100644 Documentation/devicetree/bindings/iio/adc/fsl,imx25-gcq.txt
>>>  create mode 100644 drivers/iio/adc/fsl-imx25-gcq.c
>>>  create mode 100644 include/dt-bindings/iio/adc/fsl-imx25-gcq.h
>>>
>>> diff --git a/Documentation/devicetree/bindings/iio/adc/fsl,imx25-gcq.txt b/Documentation/devicetree/bindings/iio/adc/fsl,imx25-gcq.txt
>>> new file mode 100644
>>> index 000000000000..d55b6b751349
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/iio/adc/fsl,imx25-gcq.txt
>>> @@ -0,0 +1,51 @@
>>> +Freescale i.MX25 ADC GCQ device
>>> +
>>> +This is a generic conversion queue device that can convert any of the
>>> +analog inputs using the ADC unit of the i.MX25.
>>> +
>>> +Required properties:
>>> + - compatible: Should be "fsl,imx25-gcq".
>>> + - reg: Should be the register range of the module.
>>> + - interrupts: Should be the interrupt number of the module.
>>> +   Typically this is <1>.
>>> + - interrupt-parent: phandle to the tsadc module of the i.MX25.
>>> + - #address-cells: Should be <1> (setting for the subnodes)
>>> + - #size-cells: Should be <0> (setting for the subnodes)
>>> +
>>> +Optional properties:
>>> + - vref-supply: The regulator supplying the ADC reference voltage.
>>> +   Required when at least one subnode uses the external reference.
>>> +
>>> +Sub-nodes:
>>> +Optionally you can define subnodes which define the reference voltage
>>> +for the analog inputs.
>>> +
>>> +Required properties for subnodes:
>>> + - reg: Should be the number of the analog input.
>>> +     0: xp
>>> +     1: yp
>>> +     2: xn
>>> +     3: yn
>>> +     4: wiper
>>> +     5: inaux0
>>> +     6: inaux1
>>> +     7: inaux2
>>> + - fsl,adc-ref: specifies the reference input as defined in
>>> +     <dt-bindings/iio/adc/fsl-imx25-gcq.h>
>>> +     MX25_ADC_REF_INT and MX25_ADC_REF_EXT flags are supported.
>>> +
>>> +Example:
>>> +
>>> +	adc: adc at 50030800 {
>>> +		compatible = "fsl,imx25-gcq";
>>> +		reg = <0x50030800 0x60>;
>>> +		interrupt-parent = <&tscadc>;
>>> +		interrupts = <1>;
>>> +		#address-cells = <1>;
>>> +		#size-cells = <0>;
>>> +
>>> +		inaux at 5 {
>>> +			reg = <5>;
>>> +			fsl,adc-ref = <MX25_ADC_REF_INT>;
>>> +		};
>>> +	};
>>> diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
>>> index 0f79e4725763..fccbb4bf44cc 100644
>>> --- a/drivers/iio/adc/Kconfig
>>> +++ b/drivers/iio/adc/Kconfig
>>> @@ -143,6 +143,13 @@ config EXYNOS_ADC
>>>  	  of SoCs for drivers such as the touchscreen and hwmon to use to share
>>>  	  this resource.
>>>  
>>> +config FSL_MX25_ADC
>>> +	tristate "Freescale MX25 ADC driver"
>>> +	depends on MFD_MX25_TSADC
>>> +	help
>>> +	  Generic Conversion Queue driver used for general purpose ADC in the
>>> +	  MX25. This driver supports single measurements using the MX25 ADC.
>>> +
>>>  config LP8788_ADC
>>>  	tristate "LP8788 ADC driver"
>>>  	depends on MFD_LP8788
>>> diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
>>> index 701fdb7c96aa..acab8d956371 100644
>>> --- a/drivers/iio/adc/Makefile
>>> +++ b/drivers/iio/adc/Makefile
>>> @@ -16,6 +16,7 @@ obj-$(CONFIG_AD799X) += ad799x.o
>>>  obj-$(CONFIG_AT91_ADC) += at91_adc.o
>>>  obj-$(CONFIG_AXP288_ADC) += axp288_adc.o
>>>  obj-$(CONFIG_EXYNOS_ADC) += exynos_adc.o
>>> +obj-$(CONFIG_FSL_MX25_ADC) += fsl-imx25-gcq.o
>>>  obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o
>>>  obj-$(CONFIG_MAX1027) += max1027.o
>>>  obj-$(CONFIG_MAX1363) += max1363.o
>>> diff --git a/drivers/iio/adc/fsl-imx25-gcq.c b/drivers/iio/adc/fsl-imx25-gcq.c
>>> new file mode 100644
>>> index 000000000000..c1ac5af41ec5
>>> --- /dev/null
>>> +++ b/drivers/iio/adc/fsl-imx25-gcq.c
>>> @@ -0,0 +1,369 @@
>>> +/*
>>> + * Copyright 2014 Markus Pargmann, Pengutronix <mpa at pengutronix.de>
>>> + *
>>> + * The code contained herein is licensed under the GNU General Public
>>> + * License. You may obtain a copy of the GNU General Public License
>>> + * Version 2 or later at the following locations:
>>> + *
>>> + * http://www.opensource.org/licenses/gpl-license.html
>>> + * http://www.gnu.org/copyleft/gpl.html
>>> + *
>>> + * This is the driver for the imx25 GCQ (Generic Conversion Queue)
>>> + * connected to the imx25 ADC.
>>> + */
>>> +
>>> +#include <dt-bindings/iio/adc/fsl-imx25-gcq.h>
>>> +#include <linux/clk.h>
>>> +#include <linux/iio/iio.h>
>>> +#include <linux/interrupt.h>
>>> +#include <linux/mfd/imx25-tsadc.h>
>>> +#include <linux/module.h>
>>> +#include <linux/of.h>
>>> +#include <linux/platform_device.h>
>>> +#include <linux/regmap.h>
>>> +#include <linux/regulator/consumer.h>
>>> +
>>> +#define MX25_GCQ_TIMEOUT (msecs_to_jiffies(2000))
>>> +
>>> +enum mx25_gcq_cfgs {
>>> +	MX25_CFG_XP = 0,
>>> +	MX25_CFG_YP,
>>> +	MX25_CFG_XN,
>>> +	MX25_CFG_YN,
>>> +	MX25_CFG_WIPER,
>>> +	MX25_CFG_INAUX0,
>>> +	MX25_CFG_INAUX1,
>>> +	MX25_CFG_INAUX2,
>>> +	MX25_NUM_CFGS,
>>> +};
>>> +
>>> +struct mx25_gcq_priv {
>>> +	struct regmap *regs;
>>> +	struct completion completed;
>>> +	unsigned int settling_time;
>>> +	struct clk *clk;
>>> +	int irq;
>>> +	struct regulator *ext_vref;
>>> +	u32 channel_vref_mv[MX25_NUM_CFGS];
>>> +};
>>> +
>>> +#define MX25_CQG_CHAN(chan, id) {\
>>> +	.type = IIO_VOLTAGE,\
>>> +	.indexed = 1,\
>>> +	.channel = chan,\
>>> +	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),\
>>> +	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),\
>>> +	.datasheet_name = id,\
>>> +}
>>> +
>>> +static const struct iio_chan_spec mx25_gcq_channels[MX25_NUM_CFGS] = {
>>> +	MX25_CQG_CHAN(0, "xp"),
>>> +	MX25_CQG_CHAN(1, "yp"),
>>> +	MX25_CQG_CHAN(2, "xn"),
>>> +	MX25_CQG_CHAN(3, "yn"),
>>> +	MX25_CQG_CHAN(4, "wiper"),
>>> +	MX25_CQG_CHAN(5, "inaux0"),
>>> +	MX25_CQG_CHAN(6, "inaux1"),
>>> +	MX25_CQG_CHAN(7, "inaux2"),
>>> +};
>>> +
>>> +static void mx25_gcq_disable_eoq(struct mx25_gcq_priv *priv)
>>> +{
>>> +	regmap_update_bits(priv->regs, MX25_ADCQ_MR, MX25_ADCQ_MR_EOQ_IRQ,
>>> +			   MX25_ADCQ_MR_EOQ_IRQ);
>>> +}
>>> +
>>> +static void mx25_gcq_enable_eoq(struct mx25_gcq_priv *priv)
>>> +{
>>> +	regmap_update_bits(priv->regs, MX25_ADCQ_MR,
>>> +			   MX25_ADCQ_MR_EOQ_IRQ, 0);
>>> +}
>>> +
>>> +static irqreturn_t mx25_gcq_irq(int irq, void *data)
>>> +{
>>> +	struct mx25_gcq_priv *priv = data;
>>> +	u32 stats;
>>> +
>>> +	regmap_read(priv->regs, MX25_ADCQ_SR, &stats);
>>> +
>>> +	if (stats & MX25_ADCQ_SR_EOQ) {
>>> +		mx25_gcq_disable_eoq(priv);
>>> +		complete(&priv->completed);
>>> +	}
>>> +
>>> +	/* Disable conversion queue run */
>>> +	regmap_update_bits(priv->regs, MX25_ADCQ_CR, MX25_ADCQ_CR_FQS, 0);
>>> +
>>> +	/* Acknowledge all possible irqs */
>>> +	regmap_write(priv->regs, MX25_ADCQ_SR, MX25_ADCQ_SR_FRR |
>>> +		     MX25_ADCQ_SR_FUR | MX25_ADCQ_SR_FOR |
>>> +		     MX25_ADCQ_SR_EOQ | MX25_ADCQ_SR_PD);
>>> +
>>> +	return IRQ_HANDLED;
>>> +}
>>> +
>>> +static int mx25_gcq_read_raw(struct iio_dev *indio_dev,
>>> +			     struct iio_chan_spec const *chan, int *val,
>>> +			     int *val2, long mask)
>>> +{
>>> +	struct mx25_gcq_priv *priv = iio_priv(indio_dev);
>>> +	long timeout;
>>> +	u32 data;
>>> +	int ret = 0;
>>> +
>>> +	switch (mask) {
>>> +	case IIO_CHAN_INFO_RAW:
>>> +		mutex_lock(&indio_dev->mlock);
>>> +
>>> +		/* Setup the configuration we want to use */
>>> +		regmap_write(priv->regs, MX25_ADCQ_ITEM_7_0,
>>> +			     MX25_ADCQ_ITEM(0, chan->channel));
>>> +
>>> +		mx25_gcq_enable_eoq(priv);
>>> +
>>> +		/* Trigger queue for one run */
>>> +		regmap_update_bits(priv->regs, MX25_ADCQ_CR, MX25_ADCQ_CR_FQS,
>>> +				   MX25_ADCQ_CR_FQS);
>>> +
>>> +		timeout = wait_for_completion_interruptible_timeout(
>>> +			&priv->completed, MX25_GCQ_TIMEOUT);
>>> +		if (timeout < 0) {
>>> +			dev_err(&indio_dev->dev,
>>> +				"ADC wait for measurement failed\n");
>>> +			ret = timeout;
>>> +			goto info_raw_out;
>>> +		} else if (timeout == 0) {
>>> +			dev_err(&indio_dev->dev, "ADC timed out\n");
>>> +			ret = -ETIMEDOUT;
>>> +			goto info_raw_out;
>>> +		}
>>> +
>>> +		regmap_read(priv->regs, MX25_ADCQ_FIFO, &data);
>>> +
>>> +		*val = MX25_ADCQ_FIFO_DATA(data);
>>> +		ret = IIO_VAL_INT;
>>> +info_raw_out:
>> Having this label and exit path in the middle is ugly.
>> Perhaps break out this case statement content as a separate function?
> 
> Sounds like a good idea.
> 
>>> +		mutex_unlock(&indio_dev->mlock);
>>> +
>>> +		return ret;
>>> +
>>> +	case IIO_CHAN_INFO_SCALE:
>>> +		*val = priv->channel_vref_mv[chan->channel];
>>> +		*val2 = 12;
>>> +		return IIO_VAL_FRACTIONAL_LOG2;
>>> +
>>> +	default:
>>> +		return -EINVAL;
>>> +	}
>>> +}
>>> +
>>> +static const struct iio_info mx25_gcq_iio_info = {
>>> +	.read_raw = mx25_gcq_read_raw,
>>> +};
>>> +
>>> +static const struct regmap_config mx25_gcq_regconfig = {
>>> +	.max_register = 0x5c,
>>> +	.reg_bits = 32,
>>> +	.val_bits = 32,
>>> +	.reg_stride = 4,
>>> +};
>>> +
>>> +static int mx25_gcq_setup_cfgs(struct platform_device *pdev,
>>> +			       struct mx25_gcq_priv *priv)
>>> +{
>>> +	struct device_node *np = pdev->dev.of_node;
>>> +	struct device_node *child;
>>> +	struct device *dev = &pdev->dev;
>>> +	int ret, i;
>>> +
>>> +	/*
>>> +	 * Setup all configurations registers with a default conversion
>>> +	 * configuration for each input
>>> +	 */
>>> +	for (i = 0; i < MX25_NUM_CFGS; ++i)
>>> +		regmap_write(priv->regs, MX25_ADCQ_CFG(i),
>>> +			     MX25_ADCQ_CFG_YPLL_OFF |
>>> +			     MX25_ADCQ_CFG_XNUR_OFF |
>>> +			     MX25_ADCQ_CFG_XPUL_OFF |
>>> +			     MX25_ADCQ_CFG_REFP_INT |
>>> +			     (i << 4) |
>> Again, given all the definitions i'd expect the shift to
>> be a defined constant as well.  Perhaps even a macro taking
>> i as an arguement.
> 
> Added a macro that shifts the value.
> 
>>> +			     MX25_ADCQ_CFG_REFN_NGND2);
>>> +
>>> +	for_each_child_of_node(np, child) {
>>> +		u32 reg;
>>> +		u32 refp;
>>> +		u32 adc_ref;
>>> +
>>> +		ret = of_property_read_u32(child, "reg", &reg);
>>> +		if (ret) {
>>> +			dev_err(dev, "Failed to get reg property\n");
>>> +			return ret;
>>> +		}
>>> +
>>> +		if (reg >= MX25_NUM_CFGS) {
>>> +			dev_err(dev,
>>> +				"reg value is greater than the number of available configuration registers\n");
>>> +			return -EINVAL;
>>> +		}
>>> +
>>> +		ret = of_property_read_u32(child, "fsl,adc-ref", &adc_ref);
>>> +		if (ret) {
>>> +			dev_err(dev, "Failed to get fsl,adc-ref property\n");
>>> +			return ret;
>>> +		}
>>> +
>>> +		if (adc_ref != MX25_ADC_REF_INT &&
>>> +		    adc_ref != MX25_ADC_REF_EXT) {
>>> +			dev_err(dev, "Invalid fsl,adc-refp property value %d\n",
>>> +				adc_ref);
>>> +			return -EINVAL;
>>> +		}
>>> +
>>> +		switch (adc_ref) {
>>> +		case MX25_ADC_REF_EXT:
>>> +			if (IS_ERR_OR_NULL(priv->ext_vref)) {
>>> +				dev_err(dev,
>>> +					"No regulator found for the external vref\n");
>>> +				return -EINVAL;
>>> +			}
>>> +			priv->channel_vref_mv[reg] =
>>> +				regulator_get_voltage(priv->ext_vref);
>>> +			refp = MX25_ADCQ_CFG_REFP_EXT;
>>> +			break;
>>> +		case MX25_ADC_REF_INT:
>>> +			priv->channel_vref_mv[reg] = 2500;
>>> +			refp = MX25_ADCQ_CFG_REFP_INT;
>>> +			break;
>>> +		default:
>>> +			return -EINVAL;
>>> +		}
>>> +
>>> +		regmap_update_bits(priv->regs, MX25_ADCQ_CFG(reg),
>>> +				   MX25_ADCQ_CFG_REFP_MASK |
>>> +				   MX25_ADCQ_CFG_REFN_MASK, (refp << 7) |
>>> +				   (MX25_ADCQ_CFG_REFN_NGND << 2));
>> It's a little inconsistent to define constants for the masks, but not
>> the shifts.  Particularly given these constants are already shifted in
>> their definitions...  Is that a bug?
> 
> Yes that definetly looks like a bug, thanks. Fixed and added a macro for
> refp.
> 
>>> +	}
>>> +	regmap_update_bits(priv->regs, MX25_ADCQ_CR,
>>> +			   MX25_ADCQ_CR_FRST | MX25_ADCQ_CR_QRST,
>>> +			   MX25_ADCQ_CR_FRST | MX25_ADCQ_CR_QRST);
>>> +
>>> +	regmap_write(priv->regs, MX25_ADCQ_CR,
>>> +		     MX25_ADCQ_CR_PDMSK |
>>> +		     MX25_ADCQ_CR_QSM_FQS);
>>> +
>>> +	return 0;
>>> +}
>>> +
>>> +static int mx25_gcq_probe(struct platform_device *pdev)
>>> +{
>>> +	struct iio_dev *indio_dev;
>>> +	struct mx25_gcq_priv *priv;
>>> +	struct mx25_tsadc *tsadc = dev_get_drvdata(pdev->dev.parent);
>>> +	struct device *dev = &pdev->dev;
>>> +	struct resource *res;
>>> +	void __iomem *mem;
>>> +	int ret;
>>> +
>>> +	indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*priv));
>>> +	if (!indio_dev)
>>> +		return -ENOMEM;
>>> +
>>> +	priv = iio_priv(indio_dev);
>>> +
>>> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>>> +	mem = devm_ioremap_resource(dev, res);
>>> +	if (!mem)
>>> +		return -ENOMEM;
>>> +
>>> +	priv->regs = devm_regmap_init_mmio(dev, mem, &mx25_gcq_regconfig);
>>> +	if (IS_ERR(priv->regs)) {
>>> +		dev_err(dev, "Failed to initialize regmap\n");
>>> +		return PTR_ERR(priv->regs);
>>> +	}
>>> +
>>> +	init_completion(&priv->completed);
>>> +
>>> +	/* Optional external regulator */
>>> +	priv->ext_vref = devm_regulator_get(&pdev->dev, "vref");
>>> +	if (!IS_ERR_OR_NULL(priv->ext_vref)) {
>>> +		ret = regulator_enable(priv->ext_vref);
>>> +		if (ret)
>>> +			return ret;
>>> +	}
>>> +
>>> +	ret = mx25_gcq_setup_cfgs(pdev, priv);
>>> +	if (ret)
>>> +		return ret;
>>> +
>>> +	priv->clk = tsadc->clk;
>>> +	ret = clk_prepare_enable(priv->clk);
>>> +	if (ret) {
>>> +		dev_err(dev, "Failed to enable clock\n");
>>> +		return ret;
>>> +	}
>>> +
>>> +	priv->irq = platform_get_irq(pdev, 0);
>>> +	if (priv->irq <= 0) {
>>> +		dev_err(dev, "Failed to get IRQ\n");
>>> +		ret = priv->irq;
>>> +		goto err_clk_unprepare;
>>> +	}
>>> +
>>> +	ret = request_irq(priv->irq, mx25_gcq_irq, 0, pdev->name, priv);
>>> +	if (ret) {
>>> +		dev_err(dev, "Failed requesting IRQ\n");
>>> +		goto err_clk_unprepare;
>>> +	}
>>> +
>>> +	indio_dev->dev.parent = &pdev->dev;
>>> +	indio_dev->channels = mx25_gcq_channels;
>>> +	indio_dev->num_channels = ARRAY_SIZE(mx25_gcq_channels);
>>> +	indio_dev->info = &mx25_gcq_iio_info;
>>> +
>>> +	ret = iio_device_register(indio_dev);
>>> +	if (ret) {
>>> +		dev_err(dev, "Failed to register iio device\n");
>>> +		goto err_irq_free;
>>> +	}
>>> +
>>> +	platform_set_drvdata(pdev, priv);
>>> +
>>> +	return 0;
>>> +
>>> +err_irq_free:
>>> +	free_irq(priv->irq, (void *)priv);
>>> +err_clk_unprepare:
>>> +	clk_disable_unprepare(priv->clk);
>>> +	return ret;
>>> +}
>>> +
>>> +static int mx25_gcq_remove(struct platform_device *pdev)
>>> +{
>>> +	struct mx25_gcq_priv *priv = platform_get_drvdata(pdev);
>>> +	struct iio_dev *indio_dev = iio_priv_to_dev(pdev);
>>> +
>>> +	iio_device_unregister(indio_dev);
>>> +	free_irq(priv->irq, priv);
>>> +	clk_disable_unprepare(priv->clk);
>>> +
>>> +	return 0;
>>> +}
>>> +
>>> +static struct of_device_id mx25_gcq_ids[] = {
>>> +	{ .compatible = "fsl,imx25-gcq", },
>>> +	{ /* Sentinel */ }
>>> +};
>>> +
>>> +static struct platform_driver mx25_gcq_driver = {
>>> +	.driver		= {
>>> +		.name	= "mx25-gcq",
>>> +		.of_match_table = mx25_gcq_ids,
>>> +	},
>>> +	.probe		= mx25_gcq_probe,
>>> +	.remove		= mx25_gcq_remove,
>>> +};
>>> +module_platform_driver(mx25_gcq_driver);
>>> +
>>> +MODULE_DESCRIPTION("ADC driver for Freescale mx25");
>>> +MODULE_AUTHOR("Markus Pargmann <mpa at pengutronix.de>");
>>> +MODULE_LICENSE("GPL v2");
>>> diff --git a/include/dt-bindings/iio/adc/fsl-imx25-gcq.h b/include/dt-bindings/iio/adc/fsl-imx25-gcq.h
>>> new file mode 100644
>>> index 000000000000..486dce735ac9
>>> --- /dev/null
>>> +++ b/include/dt-bindings/iio/adc/fsl-imx25-gcq.h
>>> @@ -0,0 +1,11 @@
>>> +/*
>>> + * This header provides constants for configuring the I.MX25 ADC
>>> + */
>>> +
>>> +#ifndef _DT_BINDINGS_IIO_ADC_FS_IMX25_GCQ_H
>>> +#define _DT_BINDINGS_IIO_ADC_FS_IMX25_GCQ_H
>>> +
>>> +#define MX25_ADC_REF_INT	0 /* Internal voltage reference */
>>> +#define MX25_ADC_REF_EXT	1 /* External voltage reference */
>> Seems to me that this could be dealt with using a boolean property.
>> Afterall, we need to get a reference from somewhere, so if it isn't
>> internal it must be external?
> 
> The driver is currently very simple, the ADC itself is capable of much
> more combinations and complicated conversion queues. Internal and
> external references are not the only possible references.
Fair enough then.  Thanks for clarifying this!
> There is also
> YP and XP which are not supported by the driver yet. I will change this
> to the actual register values representing these references. At a second
> look on this it may also be better to change the DT-binding from
> 'fsl,adc-ref' to 'fsl,adc-refp' as it is actually the positive reference
> voltage. The negative reference is hardcoded in the driver for the
> moment but the DT-bindings could be extended later if necessary.
> 
> Added refp and refn now with all reference values.
> 
> Thanks,
> 
> Markus
> 




More information about the linux-arm-kernel mailing list