From: "Liam Beguin" <liambeguin@gmail.com>
To: "Jonathan Cameron" <jic23@kernel.org>
Cc: <lars@metafoo.de>, <Michael.Hennerich@analog.com>,
<charles-antoine.couret@essensium.com>, <Nuno.Sa@analog.com>,
<linux-kernel@vger.kernel.org>, <linux-iio@vger.kernel.org>,
<devicetree@vger.kernel.org>, <robh+dt@kernel.org>
Subject: Re: [PATCH v5 3/5] iio: adc: ad7949: add support for internal vref
Date: Fri, 13 Aug 2021 16:51:12 -0400 [thread overview]
Message-ID: <CDIOK6DFUNE0.2P8L2AL8MDAK1@shaak> (raw)
In-Reply-To: <20210809204253.357f97b2@jic23-huawei>
On Mon Aug 9, 2021 at 3:42 PM EDT, Jonathan Cameron wrote:
> ...
> > +
> > > > static int ad7949_spi_probe(struct spi_device *spi)
> > > > {
> > > > u32 spi_ctrl_mask = spi->controller->bits_per_word_mask;
> > > > struct device *dev = &spi->dev;
> > > > const struct ad7949_adc_spec *spec;
> > > > struct ad7949_adc_chip *ad7949_adc;
> > > > + struct ad7949_channel *ad7949_chan;
> > > > + struct fwnode_handle *child;
> > > > struct iio_dev *indio_dev;
> > > > + int mode;
> > > > + u32 tmp;
> > > > int ret;
> > > > + int i;
> > > >
> > > > indio_dev = devm_iio_device_alloc(dev, sizeof(*ad7949_adc));
> > > > if (!indio_dev) {
> > > > @@ -343,16 +383,82 @@ static int ad7949_spi_probe(struct spi_device *spi)
> > > > return -EINVAL;
> > > > }
> > > >
> > > > - ad7949_adc->vref = devm_regulator_get(dev, "vref");
> > > > + /* Setup external voltage ref, buffered? */
> > > > + ad7949_adc->vref = devm_regulator_get_optional(dev, "vrefin");
> > > > if (IS_ERR(ad7949_adc->vref)) {
> > > > - dev_err(dev, "fail to request regulator\n");
> > > > - return PTR_ERR(ad7949_adc->vref);
> > > > + ret = PTR_ERR(ad7949_adc->vref);
> > > > + if (ret != -ENODEV)
> > > > + return ret;
> > > > + /* unbuffered? */
> > > > + ad7949_adc->vref = devm_regulator_get_optional(dev, "vref");
> > > > + if (IS_ERR(ad7949_adc->vref)) {
> > > > + ret = PTR_ERR(ad7949_adc->vref);
> > > > + if (ret != -ENODEV)
> > > > + return ret;
> > > > + /* Internal then */
> > > > + mode = AD7949_CFG_VAL_REF_INT_4096;
> > > > + } else {
> > > > + mode = AD7949_CFG_VAL_REF_EXT_TEMP;
> > > > + }
> > > > + } else {
> > > > + mode = AD7949_CFG_VAL_REF_EXT_TEMP_BUF;
> > > > }
> > > >
> > > > - ret = regulator_enable(ad7949_adc->vref);
> > > > - if (ret < 0) {
> > > > - dev_err(dev, "fail to enable regulator\n");
> > > > - return ret;
> > > > + if (mode & AD7949_CFG_VAL_REF_EXTERNAL) {
> > > > + ret = regulator_enable(ad7949_adc->vref);
> > > > + if (ret < 0) {
> > > > + dev_err(dev, "fail to enable regulator\n");
> > > > + return ret;
> > > > + }
> > > > +
> > > > + ret = devm_add_action_or_reset(dev, ad7949_disable_reg,
> > > > + ad7949_adc->vref);
> > > > + if (ret)
> > > > + return ret;
> > > > + }
> > > > +
> > > > + ad7949_adc->channels = devm_kcalloc(dev, spec->num_channels,
> > > > + sizeof(*ad7949_adc->channels),
> > > > + GFP_KERNEL);
> > > > + if (!ad7949_adc->channels) {
> > > > + dev_err(dev, "unable to allocate ADC channels\n");
> > > > + return -ENOMEM;
> > > > + }
> > > > +
> > > > + /* Initialize all channel structures */
> > > > + for (i = 0; i < spec->num_channels; i++)
> > > > + ad7949_adc->channels[i].refsel = mode;
> > > > +
> > > > + /* Read channel specific information form the devicetree */
> > > > + device_for_each_child_node(dev, child) {
> > > > + ret = fwnode_property_read_u32(child, "reg", &i);
> > > > + if (ret) {
> > > > + dev_err(dev, "missing reg property in %pfw\n", child);
> > > > + fwnode_handle_put(child);
> > > > + return ret;
> > > > + }
> > > > +
> > > > + ad7949_chan = &ad7949_adc->channels[i];
> > > > +
> > > > + ret = fwnode_property_read_u32(child, "adi,internal-ref-microvolt", &tmp);
> > > > + if (ret < 0 && ret != -EINVAL) {
> > > > + dev_err(dev, "invalid internal reference in %pfw\n", child);
> > > > + fwnode_handle_put(child);
> > > > + return ret;
> > > > + }
> >
> > Hi Jonathan,
> >
> > >
> > > So if we are using external voltage, then we'd not expect this to exist.
> > > ret != -EINVAL should deal with that. However, we then hit the following
> > > switch
> > > and temp isn't set to an appropriate value so we get the error.
> > >
> > > Am I missing something?
> >
> > You're right that using an external reference, will cause this to fail.
> > My apologies, I've done a poor job of testing the last two revisions of
> > this patch. I'll do better.
> >
> > Since a regulator is also required when we're using an external source,
> > I'll add a check for that. Something like this:
> >
> > ret = fwnode_property_read_u32(child, "adi,internal-ref-microvolt", &tmp);
> > if (ret == -EINVAL && mode & AD7949_CFG_VAL_REF_EXTERNAL) {
> > continue;
> > } else if (ret < 0) {
> > dev_err(dev, "invalid voltage reference in %pfw\n", child);
> > fwnode_handle_put(child);
> > return ret;
> > }
>
> Makes sense.
Hi Jonathan,
After getting access to another setup to run more tests, I noticed
that setting the reference per channel isn't really feasible.
It take a little while for the reference to be updated internally even
though the request is sent out properly, and reading channels in a
sequence returns bad values.
I'll resend this without the per-channel configuration and make
adi,internal-ref-microvolt a global parameter.
Sorry about that,
Liam
>
> >
> > Given that we can now have a different scale for each channel based on
> > the vref source, should BIT(IIO_CHAN_INFO_SCALE) be moved to
> > .info_mask_separate in the channel definition?
> Yes, good point.
>
> Hopefully no one will notice the ABI change *crosses fingers*.
>
> Jonathan
>
> >
> > Thanks,
> > Liam
> >
> > >
> > > > +
> > > > + switch (tmp) {
> > > > + case 2500000:
> > > > + ad7949_chan->refsel = AD7949_CFG_VAL_REF_INT_2500;
> > > > + break;
> > > > + case 4096000:
> > > > + ad7949_chan->refsel = AD7949_CFG_VAL_REF_INT_4096;
> > > > + break;
> > > > + default:
> > > > + dev_err(dev, "unsupported internal voltage reference\n");
> > > > + fwnode_handle_put(child);
> > > > + return -EINVAL;
> > > > + }
> > > > }
> > > >
> > > > mutex_init(&ad7949_adc->lock);
> > > > @@ -373,7 +479,6 @@ static int ad7949_spi_probe(struct spi_device *spi)
> > > >
> > > > err:
> > > > mutex_destroy(&ad7949_adc->lock);
> > > > - regulator_disable(ad7949_adc->vref);
> > > >
> > > > return ret;
> > > > }
> > > > @@ -385,7 +490,6 @@ static int ad7949_spi_remove(struct spi_device *spi)
> > > >
> > > > iio_device_unregister(indio_dev);
> > > > mutex_destroy(&ad7949_adc->lock);
> > > > - regulator_disable(ad7949_adc->vref);
> > > >
> > > > return 0;
> > > > }
> >
next prev parent reply other threads:[~2021-08-13 20:51 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-08-08 1:56 [PATCH v5 0/5] AD7949 Fixes Liam Beguin
2021-08-08 1:56 ` [PATCH v5 1/5] iio: adc: ad7949: define and use bitfield names Liam Beguin
2021-08-08 16:51 ` Joe Perches
2021-08-08 22:46 ` Liam Beguin
2021-08-09 20:03 ` Joe Perches
2021-08-08 1:56 ` [PATCH v5 2/5] iio: adc: ad7949: fix spi messages on non 14-bit controllers Liam Beguin
2021-08-08 1:56 ` [PATCH v5 3/5] iio: adc: ad7949: add support for internal vref Liam Beguin
2021-08-08 16:36 ` Jonathan Cameron
2021-08-08 22:43 ` Liam Beguin
2021-08-09 19:42 ` Jonathan Cameron
2021-08-13 20:51 ` Liam Beguin [this message]
2021-08-16 8:07 ` Andy Shevchenko
2021-08-10 12:15 ` Andy Shevchenko
2021-08-10 19:46 ` Liam Beguin
2021-08-10 19:55 ` Andy Shevchenko
2021-08-10 20:51 ` Liam Beguin
2021-08-08 1:56 ` [PATCH v5 4/5] dt-bindings: iio: adc: ad7949: add per channel reference Liam Beguin
2021-08-08 1:56 ` [PATCH v5 5/5] iio: adc: ad7949: use devm managed functions Liam Beguin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=CDIOK6DFUNE0.2P8L2AL8MDAK1@shaak \
--to=liambeguin@gmail.com \
--cc=Michael.Hennerich@analog.com \
--cc=Nuno.Sa@analog.com \
--cc=charles-antoine.couret@essensium.com \
--cc=devicetree@vger.kernel.org \
--cc=jic23@kernel.org \
--cc=lars@metafoo.de \
--cc=linux-iio@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=robh+dt@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.