From: Beniamin Bia <beniamin.bia@analog.com> To: <jic23@kernel.org> Cc: <lars@metafoo.de>, <Michael.Hennerich@analog.com>, <knaack.h@gmx.de>, <pmeerw@pmeerw.net>, <gregkh@linuxfoundation.org>, <linux-iio@vger.kernel.org>, <devel@driverdev.osuosl.org>, <linux-kernel@vger.kernel.org>, <mark.rutland@arm.com>, <robh+dt@kernel.org>, <devicetree@vger.kernel.org>, <paulmck@linux.ibm.com>, <mchehab+samsung@kernel.org>, <linus.walleij@linaro.org>, <nicolas.ferre@microchip.com>, <biabeniamin@outlook.com>, Paul Cercueil <paul.cercueil@analog.com>, Beniamin Bia <beniamin.bia@analog.com> Subject: [PATCH v2 2/4] iio: adc: ad7091r5: Add scale and external VREF support Date: Tue, 29 Oct 2019 18:29:26 +0200 [thread overview] Message-ID: <20191029162928.9720-2-beniamin.bia@analog.com> (raw) In-Reply-To: <20191029162928.9720-1-beniamin.bia@analog.com> From: Paul Cercueil <paul.cercueil@analog.com> The scale can now be obtained with the "in_voltage_scale" file. By default, the scale returned corresponds to the internal VREF of 2.5V. It is possible to use an external VREF (through the REFIN/REFOUT pin of the chip), by passing a regulator to the driver. The scale will then be calculated according to the voltage reported by the regulator. Signed-off-by: Paul Cercueil <paul.cercueil@analog.com> Co-developed-by: Beniamin Bia <beniamin.bia@analog.com> Signed-off-by: Beniamin Bia <beniamin.bia@analog.com> --- Changes in v2: -device remove function replaced by devm_add_action_or_reset drivers/iio/adc/ad7091r-base.c | 41 ++++++++++++++++++++++++++++++++++ drivers/iio/adc/ad7091r-base.h | 1 + drivers/iio/adc/ad7091r5.c | 5 +++++ 3 files changed, 47 insertions(+) diff --git a/drivers/iio/adc/ad7091r-base.c b/drivers/iio/adc/ad7091r-base.c index c2500f614d54..fda1112e7376 100644 --- a/drivers/iio/adc/ad7091r-base.c +++ b/drivers/iio/adc/ad7091r-base.c @@ -11,6 +11,7 @@ #include <linux/interrupt.h> #include <linux/module.h> #include <linux/regmap.h> +#include <linux/regulator/consumer.h> #include "ad7091r-base.h" @@ -42,6 +43,7 @@ enum ad7091r_mode { struct ad7091r_state { struct device *dev; struct regmap *map; + struct regulator *reg; const struct ad7091r_chip_info *chip_info; enum ad7091r_mode mode; struct mutex lock; @@ -145,6 +147,21 @@ static int ad7091r_read_raw(struct iio_dev *iio_dev, ret = IIO_VAL_INT; break; + case IIO_CHAN_INFO_SCALE: + if (st->reg) { + ret = regulator_get_voltage(st->reg); + if (ret < 0) + goto unlock; + + *val = ret / 1000; + } else { + *val = st->chip_info->vref_mV; + } + + *val2 = chan->scan_type.realbits; + ret = IIO_VAL_FRACTIONAL_LOG2; + break; + default: ret = -EINVAL; break; @@ -187,6 +204,16 @@ static irqreturn_t ad7091r_event_handler(int irq, void *private) return IRQ_HANDLED; } +void ad7091r_remove(void *data) +{ + struct ad7091r_state *st; + + st = (struct ad7091r_state *)data; + + if (st->reg) + regulator_disable(st->reg); +} + int ad7091r_probe(struct device *dev, const char *name, const struct ad7091r_chip_info *chip_info, struct regmap *map, int irq) @@ -220,6 +247,20 @@ int ad7091r_probe(struct device *dev, const char *name, return ret; } + st->reg = devm_regulator_get_optional(dev, "vref"); + if (IS_ERR(st->reg)) { + if (PTR_ERR(st->reg) == EPROBE_DEFER) + return -EPROBE_DEFER; + + st->reg = NULL; + } else { + ret = regulator_enable(st->reg); + if (ret) + return ret; + } + + devm_add_action_or_reset(dev, ad7091r_remove, st); + /* Use command mode by default to convert only desired channels*/ ret = ad7091r_set_mode(st, AD7091R_MODE_COMMAND); if (ret < 0) diff --git a/drivers/iio/adc/ad7091r-base.h b/drivers/iio/adc/ad7091r-base.h index 5f1147735953..76b76968d071 100644 --- a/drivers/iio/adc/ad7091r-base.h +++ b/drivers/iio/adc/ad7091r-base.h @@ -14,6 +14,7 @@ struct ad7091r_state; struct ad7091r_chip_info { unsigned int num_channels; const struct iio_chan_spec *channels; + unsigned int vref_mV; }; extern const struct regmap_config ad7091r_regmap_config; diff --git a/drivers/iio/adc/ad7091r5.c b/drivers/iio/adc/ad7091r5.c index 2c44dd02ba1a..7ee4a781cc01 100644 --- a/drivers/iio/adc/ad7091r5.c +++ b/drivers/iio/adc/ad7091r5.c @@ -35,10 +35,13 @@ static const struct iio_event_spec ad7091r5_events[] = { #define AD7091R_CHANNEL(idx, bits, ev, num_ev) { \ .type = IIO_VOLTAGE, \ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ .indexed = 1, \ .channel = idx, \ .event_spec = ev, \ .num_event_specs = num_ev, \ + .scan_type.storagebits = 16, \ + .scan_type.realbits = bits, \ } static const struct iio_chan_spec ad7091r5_channels_irq[] = { AD7091R_CHANNEL(0, 12, ad7091r5_events, ARRAY_SIZE(ad7091r5_events)), @@ -58,11 +61,13 @@ static const struct iio_chan_spec ad7091r5_channels_noirq[] = { static const struct ad7091r_chip_info ad7091r5_chip_info_irq = { .channels = ad7091r5_channels_irq, .num_channels = ARRAY_SIZE(ad7091r5_channels_irq), + .vref_mV = 2500, }; static const struct ad7091r_chip_info ad7091r5_chip_info_noirq = { .channels = ad7091r5_channels_noirq, .num_channels = ARRAY_SIZE(ad7091r5_channels_noirq), + .vref_mV = 2500, }; static int ad7091r5_i2c_probe(struct i2c_client *i2c, -- 2.17.1
WARNING: multiple messages have this Message-ID (diff)
From: Beniamin Bia <beniamin.bia@analog.com> To: <jic23@kernel.org> Cc: devel@driverdev.osuosl.org, mark.rutland@arm.com, lars@metafoo.de, biabeniamin@outlook.com, Michael.Hennerich@analog.com, devicetree@vger.kernel.org, linux-iio@vger.kernel.org, gregkh@linuxfoundation.org, linus.walleij@linaro.org, linux-kernel@vger.kernel.org, nicolas.ferre@microchip.com, robh+dt@kernel.org, Beniamin Bia <beniamin.bia@analog.com>, pmeerw@pmeerw.net, knaack.h@gmx.de, mchehab+samsung@kernel.org, paulmck@linux.ibm.com, Paul Cercueil <paul.cercueil@analog.com> Subject: [PATCH v2 2/4] iio: adc: ad7091r5: Add scale and external VREF support Date: Tue, 29 Oct 2019 18:29:26 +0200 [thread overview] Message-ID: <20191029162928.9720-2-beniamin.bia@analog.com> (raw) In-Reply-To: <20191029162928.9720-1-beniamin.bia@analog.com> From: Paul Cercueil <paul.cercueil@analog.com> The scale can now be obtained with the "in_voltage_scale" file. By default, the scale returned corresponds to the internal VREF of 2.5V. It is possible to use an external VREF (through the REFIN/REFOUT pin of the chip), by passing a regulator to the driver. The scale will then be calculated according to the voltage reported by the regulator. Signed-off-by: Paul Cercueil <paul.cercueil@analog.com> Co-developed-by: Beniamin Bia <beniamin.bia@analog.com> Signed-off-by: Beniamin Bia <beniamin.bia@analog.com> --- Changes in v2: -device remove function replaced by devm_add_action_or_reset drivers/iio/adc/ad7091r-base.c | 41 ++++++++++++++++++++++++++++++++++ drivers/iio/adc/ad7091r-base.h | 1 + drivers/iio/adc/ad7091r5.c | 5 +++++ 3 files changed, 47 insertions(+) diff --git a/drivers/iio/adc/ad7091r-base.c b/drivers/iio/adc/ad7091r-base.c index c2500f614d54..fda1112e7376 100644 --- a/drivers/iio/adc/ad7091r-base.c +++ b/drivers/iio/adc/ad7091r-base.c @@ -11,6 +11,7 @@ #include <linux/interrupt.h> #include <linux/module.h> #include <linux/regmap.h> +#include <linux/regulator/consumer.h> #include "ad7091r-base.h" @@ -42,6 +43,7 @@ enum ad7091r_mode { struct ad7091r_state { struct device *dev; struct regmap *map; + struct regulator *reg; const struct ad7091r_chip_info *chip_info; enum ad7091r_mode mode; struct mutex lock; @@ -145,6 +147,21 @@ static int ad7091r_read_raw(struct iio_dev *iio_dev, ret = IIO_VAL_INT; break; + case IIO_CHAN_INFO_SCALE: + if (st->reg) { + ret = regulator_get_voltage(st->reg); + if (ret < 0) + goto unlock; + + *val = ret / 1000; + } else { + *val = st->chip_info->vref_mV; + } + + *val2 = chan->scan_type.realbits; + ret = IIO_VAL_FRACTIONAL_LOG2; + break; + default: ret = -EINVAL; break; @@ -187,6 +204,16 @@ static irqreturn_t ad7091r_event_handler(int irq, void *private) return IRQ_HANDLED; } +void ad7091r_remove(void *data) +{ + struct ad7091r_state *st; + + st = (struct ad7091r_state *)data; + + if (st->reg) + regulator_disable(st->reg); +} + int ad7091r_probe(struct device *dev, const char *name, const struct ad7091r_chip_info *chip_info, struct regmap *map, int irq) @@ -220,6 +247,20 @@ int ad7091r_probe(struct device *dev, const char *name, return ret; } + st->reg = devm_regulator_get_optional(dev, "vref"); + if (IS_ERR(st->reg)) { + if (PTR_ERR(st->reg) == EPROBE_DEFER) + return -EPROBE_DEFER; + + st->reg = NULL; + } else { + ret = regulator_enable(st->reg); + if (ret) + return ret; + } + + devm_add_action_or_reset(dev, ad7091r_remove, st); + /* Use command mode by default to convert only desired channels*/ ret = ad7091r_set_mode(st, AD7091R_MODE_COMMAND); if (ret < 0) diff --git a/drivers/iio/adc/ad7091r-base.h b/drivers/iio/adc/ad7091r-base.h index 5f1147735953..76b76968d071 100644 --- a/drivers/iio/adc/ad7091r-base.h +++ b/drivers/iio/adc/ad7091r-base.h @@ -14,6 +14,7 @@ struct ad7091r_state; struct ad7091r_chip_info { unsigned int num_channels; const struct iio_chan_spec *channels; + unsigned int vref_mV; }; extern const struct regmap_config ad7091r_regmap_config; diff --git a/drivers/iio/adc/ad7091r5.c b/drivers/iio/adc/ad7091r5.c index 2c44dd02ba1a..7ee4a781cc01 100644 --- a/drivers/iio/adc/ad7091r5.c +++ b/drivers/iio/adc/ad7091r5.c @@ -35,10 +35,13 @@ static const struct iio_event_spec ad7091r5_events[] = { #define AD7091R_CHANNEL(idx, bits, ev, num_ev) { \ .type = IIO_VOLTAGE, \ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ .indexed = 1, \ .channel = idx, \ .event_spec = ev, \ .num_event_specs = num_ev, \ + .scan_type.storagebits = 16, \ + .scan_type.realbits = bits, \ } static const struct iio_chan_spec ad7091r5_channels_irq[] = { AD7091R_CHANNEL(0, 12, ad7091r5_events, ARRAY_SIZE(ad7091r5_events)), @@ -58,11 +61,13 @@ static const struct iio_chan_spec ad7091r5_channels_noirq[] = { static const struct ad7091r_chip_info ad7091r5_chip_info_irq = { .channels = ad7091r5_channels_irq, .num_channels = ARRAY_SIZE(ad7091r5_channels_irq), + .vref_mV = 2500, }; static const struct ad7091r_chip_info ad7091r5_chip_info_noirq = { .channels = ad7091r5_channels_noirq, .num_channels = ARRAY_SIZE(ad7091r5_channels_noirq), + .vref_mV = 2500, }; static int ad7091r5_i2c_probe(struct i2c_client *i2c, -- 2.17.1 _______________________________________________ devel mailing list devel@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
next prev parent reply other threads:[~2019-10-29 13:31 UTC|newest] Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top 2019-10-29 16:29 [PATCH v2 1/4] iio: adc: Add support for AD7091R5 ADC Beniamin Bia 2019-10-29 16:29 ` Beniamin Bia 2019-10-29 16:29 ` Beniamin Bia [this message] 2019-10-29 16:29 ` [PATCH v2 2/4] iio: adc: ad7091r5: Add scale and external VREF support Beniamin Bia 2019-10-31 10:56 ` [RFC PATCH] iio: adc: ad7091r5: ad7091r_remove() can be static kbuild test robot 2019-10-31 10:56 ` kbuild test robot 2019-10-31 10:56 ` kbuild test robot 2019-10-31 10:56 ` [PATCH v2 2/4] iio: adc: ad7091r5: Add scale and external VREF support kbuild test robot 2019-10-31 10:56 ` kbuild test robot 2019-10-31 10:56 ` kbuild test robot 2019-10-29 16:29 ` [PATCH v2 3/4] dt-binding: iio: Add documentation for AD7091R5 Beniamin Bia 2019-10-29 16:29 ` Beniamin Bia 2019-10-29 16:52 ` [PATCH v2 4/4] MAINTAINERS: add entry for AD7091R5 driver Beniamin Bia 2019-10-29 16:52 ` Beniamin Bia 2019-10-29 18:59 ` [PATCH v2 1/4] iio: adc: Add support for AD7091R5 ADC Dan Carpenter 2019-10-29 18:59 ` Dan Carpenter 2019-11-25 11:26 ` Ardelean, Alexandru 2019-11-25 11:26 ` Ardelean, Alexandru 2019-12-01 10:14 ` Jonathan Cameron 2019-12-01 10:14 ` Jonathan Cameron
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=20191029162928.9720-2-beniamin.bia@analog.com \ --to=beniamin.bia@analog.com \ --cc=Michael.Hennerich@analog.com \ --cc=biabeniamin@outlook.com \ --cc=devel@driverdev.osuosl.org \ --cc=devicetree@vger.kernel.org \ --cc=gregkh@linuxfoundation.org \ --cc=jic23@kernel.org \ --cc=knaack.h@gmx.de \ --cc=lars@metafoo.de \ --cc=linus.walleij@linaro.org \ --cc=linux-iio@vger.kernel.org \ --cc=linux-kernel@vger.kernel.org \ --cc=mark.rutland@arm.com \ --cc=mchehab+samsung@kernel.org \ --cc=nicolas.ferre@microchip.com \ --cc=paul.cercueil@analog.com \ --cc=paulmck@linux.ibm.com \ --cc=pmeerw@pmeerw.net \ --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: linkBe 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.