[PATCH v4 10/14] iio: adc: ad7768: Register GPIO auxiliary device

Janani Sunil <[email protected]>
Newsgroups org.kernel.vger.linux-iio,org.kernel.vger.linux-devicetree,org.kernel.vger.linux-doc,org.kernel.vger.linux-gpio,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
Register an auxiliary device when the AD7768 is described as a GPIO
controller. This allows the GPIO driver to share the parent regmap and
runtime power-management state.

Signed-off-by: Janani Sunil <[email protected]>
---
 drivers/iio/adc/Kconfig  |  1 +
 drivers/iio/adc/ad7768.c | 32 ++++++++++++++++++++++++++++++++
 2 files changed, 33 insertions(+)

diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index a16f36f9502c..68334793c9ba 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -433,6 +433,7 @@ config AD7768
 	tristate "Analog Devices AD7768/AD7768-4 ADC driver"
 	depends on SPI
 	select REGULATOR
+	select AUXILIARY_BUS
 	select IIO_BUFFER
 	select IIO_BACKEND
 	select REGMAP
diff --git a/drivers/iio/adc/ad7768.c b/drivers/iio/adc/ad7768.c
index 97f84a6da63e..3f9306d54952 100644
--- a/drivers/iio/adc/ad7768.c
+++ b/drivers/iio/adc/ad7768.c
@@ -6,6 +6,7 @@
  */
 
 #include <linux/array_size.h>
+#include <linux/auxiliary_bus.h>
 #include <linux/bitfield.h>
 #include <linux/bitops.h>
 #include <linux/cleanup.h>
@@ -121,6 +122,7 @@
 #define AD7768_MAX_MCLK_FREQ_HZ			(34 * HZ_PER_MHZ)
 #define MAX_FREQ_PER_MODE			6
 #define AD7768_MAX_CHANNEL			8
+#define AD7768_NUM_GPIOS			5
 #define AD7768_NUM_CHANNEL_MODES		2
 #define AD7768_CALIB_REG_MSK			GENMASK(23, 0)
 #define AD7768_WIDEBAND_SETTLING_SAMPLES	68
@@ -191,6 +193,7 @@ struct ad7768_state {
 	struct mutex lock;
 	struct clk *mclk;
 	unsigned int datalines;
+	unsigned long gpio_valid_mask;
 	enum ad7768_clock_source clock_source;
 	unsigned int power_mode_idx;
 	const struct ad7768_chip_info *chip_info;
@@ -1262,6 +1265,31 @@ static void ad7768_set_available_sampl_freq(struct ad7768_state *st)
 	}
 }
 
+static int ad7768_gpio_adev_init(struct ad7768_state *st)
+{
+	struct device *dev = regmap_get_device(st->regmap);
+	struct spi_device *spi = to_spi_device(dev);
+	struct auxiliary_device *adev;
+	int id;
+
+	if (!device_property_read_bool(dev, "gpio-controller"))
+		return 0;
+
+	st->gpio_valid_mask = GENMASK(AD7768_NUM_GPIOS - 1, 0);
+	if (st->clock_source != AD7768_CLOCK_SOURCE_MCLK)
+		st->gpio_valid_mask &= ~BIT(4);
+
+	/* Use the SPI bus number and chip select to derive a stable per-device ID. */
+	id = (spi->controller->bus_num << 8) | spi_get_chipselect(spi, 0);
+	adev = __devm_auxiliary_device_create(dev, KBUILD_MODNAME, "gpio",
+					      &st->gpio_valid_mask, id);
+	if (!adev)
+		return dev_err_probe(dev, -ENODEV,
+				     "Failed to create GPIO auxiliary device\n");
+
+	return 0;
+}
+
 static int ad7768_set_filter_mode(struct iio_dev *indio_dev,
 				  const struct iio_chan_spec *chan,
 				  unsigned int mode)
@@ -1754,6 +1782,10 @@ static int ad7768_probe(struct spi_device *spi)
 
 	indio_dev->setup_ops = &ad7768_buffer_ops;
 
+	ret = ad7768_gpio_adev_init(st);
+	if (ret)
+		return ret;
+
 	ret = devm_iio_device_register(dev, indio_dev);
 	if (ret)
 		return ret;

-- 
2.43.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.