diff mbox series

[v1,10/15] iio: adc: ad7768-1: Add support for variable VCM

Message ID a6999fc24a4c61498e55f23861997382df2ab4f4.1736201898.git.Jonathan.Santos@analog.com (mailing list archive)
State New
Headers show
Series iio: adc: ad7768-1: Add features, improvements, and fixes | expand

Commit Message

Jonathan Santos Jan. 7, 2025, 3:26 p.m. UTC
From: Sergiu Cuciurean <sergiu.cuciurean@analog.com>

The VCM output voltage can be used as a common-mode voltage within the
amplifier preconditioning circuits external to the AD7768-1.

This change exports the VCM as an iio attribute and makes it available
for configuration.

Signed-off-by: Sergiu Cuciurean <sergiu.cuciurean@analog.com>
---
 drivers/iio/adc/ad7768-1.c | 56 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 56 insertions(+)

Comments

David Lechner Jan. 7, 2025, 11:46 p.m. UTC | #1
On 1/7/25 9:26 AM, Jonathan Santos wrote:
> From: Sergiu Cuciurean <sergiu.cuciurean@analog.com>
> 
> The VCM output voltage can be used as a common-mode voltage within the
> amplifier preconditioning circuits external to the AD7768-1.
> 
> This change exports the VCM as an iio attribute and makes it available
> for configuration.

We model common mode voltage inputs as a regulator consumer (e.g. vcm-supply in
DT), so should we make this a regulator provider instead?

It could be used with "regulator-output" to be able to control it from sysfs
or if the amplifier ends up in the devicetree for other reasons, the amplifier
driver could control the regulator instead of requiring it to by done in sysfs.
diff mbox series

Patch

diff --git a/drivers/iio/adc/ad7768-1.c b/drivers/iio/adc/ad7768-1.c
index eaa9a12737ac..574d735f2c3a 100644
--- a/drivers/iio/adc/ad7768-1.c
+++ b/drivers/iio/adc/ad7768-1.c
@@ -119,6 +119,17 @@  struct ad7768_clk_configuration {
 	enum ad7768_pwrmode pwrmode;
 };
 
+static const char * const ad7768_vcm_modes[] = {
+	"(AVDD1-AVSS)/2",
+	"2V5",
+	"2V05",
+	"1V9",
+	"1V65",
+	"1V1",
+	"0V9",
+	"OFF",
+};
+
 static const struct ad7768_clk_configuration ad7768_clk_config[] = {
 	{ AD7768_MCLK_DIV_2, AD7768_DEC_RATE_8, 16,  AD7768_FAST_MODE },
 	{ AD7768_MCLK_DIV_2, AD7768_DEC_RATE_16, 32,  AD7768_FAST_MODE },
@@ -133,12 +144,34 @@  static const struct ad7768_clk_configuration ad7768_clk_config[] = {
 	{ AD7768_MCLK_DIV_16, AD7768_DEC_RATE_1024, 16384, AD7768_ECO_MODE },
 };
 
+static int ad7768_get_vcm(struct iio_dev *dev, const struct iio_chan_spec *chan);
+static int ad7768_set_vcm(struct iio_dev *dev, const struct iio_chan_spec *chan,
+			  unsigned int mode);
+
+static const struct iio_enum ad7768_vcm_mode_enum = {
+	.items = ad7768_vcm_modes,
+	.num_items = ARRAY_SIZE(ad7768_vcm_modes),
+	.set = ad7768_set_vcm,
+	.get = ad7768_get_vcm,
+};
+
+static struct iio_chan_spec_ext_info ad7768_ext_info[] = {
+	IIO_ENUM("common_mode_voltage",
+		 IIO_SHARED_BY_ALL,
+		 &ad7768_vcm_mode_enum),
+	IIO_ENUM_AVAILABLE("common_mode_voltage",
+			   IIO_SHARED_BY_ALL,
+			   &ad7768_vcm_mode_enum),
+	{ },
+};
+
 static const struct iio_chan_spec ad7768_channels[] = {
 	{
 		.type = IIO_VOLTAGE,
 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
 		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
 		.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
+		.ext_info = ad7768_ext_info,
 		.indexed = 1,
 		.channel = 0,
 		.scan_index = 0,
@@ -159,6 +192,7 @@  struct ad7768_state {
 	struct clk *mclk;
 	unsigned int mclk_freq;
 	unsigned int samp_freq;
+	unsigned int common_mode_voltage;
 	struct completion completion;
 	struct iio_trigger *trig;
 	struct gpio_desc *gpio_sync_in;
@@ -329,6 +363,28 @@  static int ad7768_set_freq(struct ad7768_state *st,
 	return 0;
 }
 
+static int ad7768_get_vcm(struct iio_dev *dev, const struct iio_chan_spec *chan)
+{
+	struct ad7768_state *st = iio_priv(dev);
+
+	return st->common_mode_voltage;
+}
+
+static int ad7768_set_vcm(struct iio_dev *dev,
+			  const struct iio_chan_spec *chan,
+			  unsigned int mode)
+{
+	int ret;
+	struct ad7768_state *st = iio_priv(dev);
+
+	ret = ad7768_spi_reg_write(st, AD7768_REG_ANALOG2, mode);
+
+	if (ret == 0)
+		st->common_mode_voltage = mode;
+
+	return ret;
+}
+
 static ssize_t ad7768_sampling_freq_avail(struct device *dev,
 					  struct device_attribute *attr,
 					  char *buf)