mbox series

[v9,00/12] iio: adc: ad7768-1: Add features, improvements, and fixes

Message ID cover.1748447035.git.Jonathan.Santos@analog.com
Headers show
Series iio: adc: ad7768-1: Add features, improvements, and fixes | expand

Message

Jonathan Santos May 29, 2025, 10:47 p.m. UTC
This patch series introduces some new features, improvements,
and fixes for the AD7768-1 ADC driver. 

The goal is to support all key functionalities listed in the device
datasheet, including filter mode selection, common mode voltage output
configuration and GPIO support. Additionally, this includes fixes 
for SPI communication and for IIO interface, and also code improvements
to enhance maintainability and readability.

---
Changes in v9:
* added fwnode_find_reference_args() patch.
* Refactored ad7768_trigger_sources_get_sync() to avoid jumps and used 
  fwnode_find_reference_args() to get the trigger-sources property with
  proper cleanup.
* Fixed oversampling_ratio_available attribute. Previous ranges did not 
  follow a standard. Now we mix range (for sinc3) with list 
  (for sinc5 and wideband).
* Addressed review comments, see individual pacthes.
* Link to v8: https://lore.kernel.org/linux-iio/cover.1747175187.git.Jonathan.Santos@analog.com/T/#t

Changes in v8:
* Removed "reorganize driver headers patch", since Jonathan said he picked 
  it.
* refactored ad7768_trigger_sources_get_sync() function.
* Addressed review comments, see individual pacthes.
* Link to v7: https://lore.kernel.org/linux-iio/cover.1746662899.git.Jonathan.Santos@analog.com/T/#t


Changes in v7:
* Added a new patch to reorganize driver headers.
* Added the new files to MAINTAINERS.
* Added dependencies to constrain the use of trigger-sources and
  adi,sync-in-gpios properties at the same time.
* Self triggering is enabled only when the trigger-sources property is
  not defined. Added TODO to support other trigger sources when the subsystem
  is available.
* Refactor code to avoid forward declarations.
* Mentioned that sampling frequency changes is not allowed in
  buffered mode.
* Addressed review comments, see individual pacthes.
* Link to v6: https://lore.kernel.org/linux-iio/cover.1745605382.git.Jonathan.Santos@analog.com/T/#t

Changes in v6:
* Changed description and addressed other nits in the gpio-trigger patch.
* Rewrote the #trigger-sources-cells description and removed mentions 
  to offload engine.
* Added adi,ad7768-1.h header with macros for the trigger source cells.
* removed of_match_ptr() from regulator_desc.
* Replaced deprecated .set callback with .set_rv in the gpio controller
  patch.
* Use `trigger-sources` as an alternative to `adi,sync-in-gpios`
  (now optional), instead of replacing it.
* Check trigger source by the compatible string (and the dev node for the
  self triggering).
* Addressed review comments, see individual pacthes.
* Link to v5: https://lore.kernel.org/linux-iio/cover.1744325346.git.Jonathan.Santos@analog.com/T/#t

Changes in v5:
* Added gpio-trigger binding patch.
* Include START pin and DRDY in the trigger-sources description.
* increased trigger-source-cells to 1: this cell will define the trigger
  source type.
* Fixed the holes in the regmap ranges.
* replace old iio_device_claim_direct_mode() for the new 
  iio_device_claim/release_direct() functions.
* Changed some commit messages.
* Link to v4: https://lore.kernel.org/linux-iio/cover.1741268122.git.Jonathan.Santos@analog.com/T/#t

Changes in v4:
* Added missing `select REGMAP_SPI` and `select REGULATOR` to the device's Kconfig.
* VCM output regulator property renamed.
* Added direct mode conditional locks to regulator controller callbacks.
* Renamed regulator controller.
* Created helper function to precalculate the sampling frequency table and avoid
  race conditions.
* Link to v3: https://lore.kernel.org/linux-iio/cover.1739368121.git.Jonathan.Santos@analog.com/T/#t

Changes in v3:
* Fixed irregular or missing SoBs.
* Moved MOSI idle state patch to the start of the patch, as the other fix.
* fixed dt-binding errors.
* Trigger-sources is handled in a different way, as an alternative to sync-in-gpio.
  (this way we avoid breaking old applications).
* VCM output is controlled by the regulator framework.
* Added a second regmap for 24-bit register values.
* Add new preparatory patch replacing the manual attribute declarations for
  the read_avail from struct iio_info.
* included sinc3+rej60 filter type.
* Addressed review comments, see individual pacthes.
* Link to v2: https://lore.kernel.org/linux-iio/cover.1737985435.git.Jonathan.Santos@analog.com/T/#u

Changes in v2:
* Removed synchronization over SPI property and replaced it for trigger-sources.
* Added GPIO controller documentation.
* VCM output control changed from an IIO attribute to a devicetree property (static value).
* Converted driver to use regmap and dropped spi_read_reg and spi_write_reg pacthes.
* replaced decimation_rate attribute for oversampling_ratio and dropped device specific documentation patch.
* Added low pass -3dB cutoff attribute.
* Addressed review comments, see individual pacthes.
* Link to v1: https://lore.kernel.org/linux-iio/cover.1736201898.git.Jonathan.Santos@analog.com/T/#t

Jonathan Santos (11):
  device property: add fwnode_find_reference_args()
  dt-bindings: trigger-source: add generic GPIO trigger source
  dt-bindings: iio: adc: ad7768-1: add trigger-sources property
  dt-bindings: iio: adc: ad7768-1: Document GPIO controller
  dt-bindings: iio: adc: ad7768-1: document regulator provider property
  iio: adc: ad7768-1: add regulator to control VCM output
  iio: adc: ad7768-1: add multiple scan types to support 16-bits mode
  iio: adc: ad7768-1: add support for Synchronization over SPI
  iio: adc: ad7768-1: replace manual attribute declaration
  iio: adc: ad7768-1: add filter type and oversampling ratio attributes
  iio: adc: ad7768-1: add low pass -3dB cutoff attribute

Sergiu Cuciurean (1):
  iio: adc: ad7768-1: Add GPIO controller support

 .../bindings/iio/adc/adi,ad7768-1.yaml        |  68 +-
 .../bindings/trigger-source/gpio-trigger.yaml |  40 +
 MAINTAINERS                                   |   4 +-
 drivers/base/property.c                       |  32 +
 drivers/iio/adc/Kconfig                       |   1 +
 drivers/iio/adc/ad7768-1.c                    | 906 +++++++++++++++---
 include/dt-bindings/iio/adc/adi,ad7768-1.h    |  10 +
 include/linux/property.h                      |   6 +
 8 files changed, 952 insertions(+), 115 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/trigger-source/gpio-trigger.yaml
 create mode 100644 include/dt-bindings/iio/adc/adi,ad7768-1.h


base-commit: 9415c8b5b9b7ba927d98f80022a2890e8639e9e4
prerequisite-patch-id: fbb33747cd0293bacd5b6d801d6cfc087449a28e

Comments

Jonathan Cameron May 30, 2025, 4:09 p.m. UTC | #1
On Thu, 29 May 2025 19:50:29 -0300
Jonathan Santos <Jonathan.Santos@analog.com> wrote:

> The synchronization method using GPIO requires the generated pulse to be
> truly synchronous with the base MCLK signal. When it is not possible to
> do that in hardware, the datasheet recommends using synchronization over
> SPI, where the generated pulse is already synchronous with MCLK. This
> requires the SYNC_OUT pin to be connected to the SYNC_IN pin.
> 
> Use trigger-sources property to enable device synchronization over SPI
> and multi-device synchronization while replacing sync-in-gpios property.
> 
> Reviewed-by: David Lechner <dlechner@baylibre.com>
> Signed-off-by: Jonathan Santos <Jonathan.Santos@analog.com>

A couple of trivial comments.  Not enough to respin unless something else comes
up.


> @@ -296,6 +301,27 @@ static const struct regmap_config ad7768_regmap24_config = {
>  	.max_register = AD7768_REG24_COEFF_DATA,
>  };
>  
> +static int ad7768_send_sync_pulse(struct ad7768_state *st)
> +{
> +	if (st->en_spi_sync)
> +		return regmap_write(st->regmap, AD7768_REG_SYNC_RESET, 0x00);
> +
> +	/*
> +	 * The datasheet specifies a minimum SYNC_IN pulse width of 1.5 × Tmclk,
> +	 * where Tmclk is the MCLK period. The supported MCLK frequencies range
> +	 * from 0.6 MHz to 17 MHz, which corresponds to a minimum SYNC_IN pulse
> +	 * width of approximately 2.5 µs in the worst-case scenario (0.6 MHz).
> +	 *
> +	 * Add a delay to ensure the pulse width is always sufficient to
> +	 * trigger synchronization.
> +	 */
> +	gpiod_set_value_cansleep(st->gpio_sync_in, 1);
> +	fsleep(3);
> +	gpiod_set_value_cansleep(st->gpio_sync_in, 0);

This change + comment should really have been in a separate patch
as there is always the potential someone might want to backport it.

> +
> +	return 0;
> +}
> +
>  static int ad7768_set_mode(struct ad7768_state *st,
>  			   enum ad7768_conv_mode mode)
>  {
> @@ -392,10 +418,7 @@ static int ad7768_set_dig_fil(struct ad7768_state *st,
>  		return ret;
>  
>  	/* A sync-in pulse is required every time the filter dec rate changes */
> -	gpiod_set_value(st->gpio_sync_in, 1);
> -	gpiod_set_value(st->gpio_sync_in, 0);
> -
> -	return 0;
> +	return ad7768_send_sync_pulse(st);
>  }

> +
> +static int ad7768_trigger_sources_get_sync(struct device *dev,
> +					   struct ad7768_state *st)
> +{
> +	struct fwnode_handle *dev_fwnode = dev_fwnode(dev);
> +
> +	/*
> +	 * The AD7768-1 allows two primary methods for driving the SYNC_IN pin
> +	 * to synchronize one or more devices:
> +	 * 1. Using an external GPIO.
> +	 * 2. Using a SPI command, where the SYNC_OUT pin generates a
> +	 *    synchronization pulse that drives the SYNC_IN pin.
> +	 */
> +	if (fwnode_property_present(dev_fwnode, "trigger-sources"))
> +		return ad7768_trigger_sources_sync_setup(dev, dev_fwnode, st);
> +
> +	/*
> +	 * In the absence of trigger-sources property, enable self
> +	 * synchronization over SPI (SYNC_OUT).
> +	 */
> +	st->en_spi_sync = true;

Really trivial but if you respin for some reason blank line here.

> +	return 0;
> +}
Jonathan Cameron May 30, 2025, 4:19 p.m. UTC | #2
On Thu, 29 May 2025 19:47:57 -0300
Jonathan Santos <Jonathan.Santos@analog.com> wrote:

> This patch series introduces some new features, improvements,
> and fixes for the AD7768-1 ADC driver. 
> 
> The goal is to support all key functionalities listed in the device
> datasheet, including filter mode selection, common mode voltage output
> configuration and GPIO support. Additionally, this includes fixes 
> for SPI communication and for IIO interface, and also code improvements
> to enhance maintainability and readability.

Looks good to me.  I'll be waiting on at least some tags on patch 1 though
before applying this.

Thanks,

Jonathan
Andy Shevchenko May 30, 2025, 5:45 p.m. UTC | #3
On Thu, May 29, 2025 at 07:50:29PM -0300, Jonathan Santos wrote:
> The synchronization method using GPIO requires the generated pulse to be
> truly synchronous with the base MCLK signal. When it is not possible to
> do that in hardware, the datasheet recommends using synchronization over
> SPI, where the generated pulse is already synchronous with MCLK. This
> requires the SYNC_OUT pin to be connected to the SYNC_IN pin.
> 
> Use trigger-sources property to enable device synchronization over SPI
> and multi-device synchronization while replacing sync-in-gpios property.

...

> struct ad7768_state {

>  	struct iio_trigger *trig;
>  	struct gpio_desc *gpio_sync_in;
>  	struct gpio_desc *gpio_reset;

> +	bool en_spi_sync;

I'm wondering if moving this...

>  	const char *labels[ARRAY_SIZE(ad7768_channels)];
>  	struct gpio_chip gpiochip;

...to here saves a few bytes in accordance to `pahole`.

>  };

...

> +static int ad7768_trigger_sources_sync_setup(struct device *dev,
> +					     struct fwnode_handle *dev_fwnode,
> +					     struct ad7768_state *st)
> +{
> +	struct fwnode_reference_args args;
> +
> +	struct fwnode_handle *fwnode __free(fwnode_handle) =
> +		fwnode_find_reference_args(dev_fwnode, "trigger-sources",
> +					   "#trigger-source-cells", 0,
> +					   AD7768_TRIGGER_SOURCE_SYNC_IDX, &args);

I don't see how args are being used. This puts in doubt the need of the first
patch.

> +	if (IS_ERR(fwnode))
> +		return PTR_ERR(fwnode);
> +
> +	/* First, try getting the GPIO trigger source */
> +	if (fwnode_device_is_compatible(fwnode, "gpio-trigger")) {
> +		st->gpio_sync_in = devm_fwnode_gpiod_get_index(dev, fwnode,
> +							       NULL,
> +							       0,
> +							       GPIOD_OUT_LOW,
> +							       "sync-in");
> +		return PTR_ERR_OR_ZERO(st->gpio_sync_in);
> +	}
> +
> +	/*
> +	 * TODO: Support the other cases when we have a trigger subsystem
> +	 * to reliably handle other types of devices as trigger sources.
> +	 *
> +	 * For now, return an error message. For self triggering, omit the
> +	 * trigger-sources property.
> +	 */
> +	return dev_err_probe(dev, -EOPNOTSUPP, "Invalid synchronization trigger source\n");
> +}

...

> +static int ad7768_trigger_sources_get_sync(struct device *dev,
> +					   struct ad7768_state *st)
> +{
> +	struct fwnode_handle *dev_fwnode = dev_fwnode(dev);

Call it just fwnode.

> +	/*
> +	 * The AD7768-1 allows two primary methods for driving the SYNC_IN pin
> +	 * to synchronize one or more devices:
> +	 * 1. Using an external GPIO.
> +	 * 2. Using a SPI command, where the SYNC_OUT pin generates a
> +	 *    synchronization pulse that drives the SYNC_IN pin.
> +	 */
> +	if (fwnode_property_present(dev_fwnode, "trigger-sources"))
> +		return ad7768_trigger_sources_sync_setup(dev, dev_fwnode, st);
> +
> +	/*
> +	 * In the absence of trigger-sources property, enable self
> +	 * synchronization over SPI (SYNC_OUT).
> +	 */
> +	st->en_spi_sync = true;
> +	return 0;
> +}
Andy Shevchenko May 30, 2025, 5:48 p.m. UTC | #4
On Thu, May 29, 2025 at 07:48:17PM -0300, Jonathan Santos wrote:
> Similarly to fwnode_find_reference(), find and return a named reference
> to a fwnode handle, including its arguments. This wrapper facilitates
> cleanup handling and improves readability.

In principle I'm okay with the code, but I probably missed how this new API is
being used (in terms of a need of those arguments to be retrieved).
Andy Shevchenko May 30, 2025, 5:49 p.m. UTC | #5
On Thu, May 29, 2025 at 07:47:57PM -0300, Jonathan Santos wrote:
> This patch series introduces some new features, improvements,
> and fixes for the AD7768-1 ADC driver. 
> 
> The goal is to support all key functionalities listed in the device
> datasheet, including filter mode selection, common mode voltage output
> configuration and GPIO support. Additionally, this includes fixes 
> for SPI communication and for IIO interface, and also code improvements
> to enhance maintainability and readability.

If you haven't run `make W=1 ...` build against this driver, do it with
GCC and clang and fix all respective compilation warnings / errors,
if any.
Jonathan Cameron May 31, 2025, 5:42 p.m. UTC | #6
On Fri, 30 May 2025 20:45:32 +0300
Andy Shevchenko <andy@kernel.org> wrote:

> On Thu, May 29, 2025 at 07:50:29PM -0300, Jonathan Santos wrote:
> > The synchronization method using GPIO requires the generated pulse to be
> > truly synchronous with the base MCLK signal. When it is not possible to
> > do that in hardware, the datasheet recommends using synchronization over
> > SPI, where the generated pulse is already synchronous with MCLK. This
> > requires the SYNC_OUT pin to be connected to the SYNC_IN pin.
> > 
> > Use trigger-sources property to enable device synchronization over SPI
> > and multi-device synchronization while replacing sync-in-gpios property.  
> 
> ...
> 
> > struct ad7768_state {  
> 
> >  	struct iio_trigger *trig;
> >  	struct gpio_desc *gpio_sync_in;
> >  	struct gpio_desc *gpio_reset;  
> 
> > +	bool en_spi_sync;  
> 
> I'm wondering if moving this...
> 
> >  	const char *labels[ARRAY_SIZE(ad7768_channels)];
> >  	struct gpio_chip gpiochip;  
> 
> ...to here saves a few bytes in accordance to `pahole`.
> 
> >  };  
> 
> ...
> 
> > +static int ad7768_trigger_sources_sync_setup(struct device *dev,
> > +					     struct fwnode_handle *dev_fwnode,
> > +					     struct ad7768_state *st)
> > +{
> > +	struct fwnode_reference_args args;
> > +
> > +	struct fwnode_handle *fwnode __free(fwnode_handle) =
> > +		fwnode_find_reference_args(dev_fwnode, "trigger-sources",
> > +					   "#trigger-source-cells", 0,
> > +					   AD7768_TRIGGER_SOURCE_SYNC_IDX, &args);  
> 
> I don't see how args are being used. This puts in doubt the need of the first
> patch.

That did get discussed (more context needed in the commit message for patch 1).
I wasn't happy with ignoring #trigger-source-cells which is required in the
binding but here is known to be 0.

If it was larger than 0 but we didn't care about the arguments I believe
we'd still need to use this call to take the right stride through the
data array that this is coming from.
Ultimately I think that is this bit of code establishing the end of the phandle.
https://elixir.bootlin.com/linux/v6.15/source/drivers/of/base.c#L1300

I might have gotten it wrong how this all works though!

J
Jonathan Cameron May 31, 2025, 5:43 p.m. UTC | #7
On Fri, 30 May 2025 20:48:14 +0300
Andy Shevchenko <andy@kernel.org> wrote:

> On Thu, May 29, 2025 at 07:48:17PM -0300, Jonathan Santos wrote:
> > Similarly to fwnode_find_reference(), find and return a named reference
> > to a fwnode handle, including its arguments. This wrapper facilitates
> > cleanup handling and improves readability.  
> 
> In principle I'm okay with the code, but I probably missed how this new API is
> being used (in terms of a need of those arguments to be retrieved).
> 

Good point - this needs a little more justification, particularly with respect
to why we are using it in this driver.

J
Jonathan Santos June 2, 2025, 5:15 p.m. UTC | #8
On 05/30, Andy Shevchenko wrote:
> On Thu, May 29, 2025 at 07:50:29PM -0300, Jonathan Santos wrote:
 
> > +static int ad7768_trigger_sources_sync_setup(struct device *dev,
> > +					     struct fwnode_handle *dev_fwnode,
> > +					     struct ad7768_state *st)
> > +{
> > +	struct fwnode_reference_args args;
> > +
> > +	struct fwnode_handle *fwnode __free(fwnode_handle) =
> > +		fwnode_find_reference_args(dev_fwnode, "trigger-sources",
> > +					   "#trigger-source-cells", 0,
> > +					   AD7768_TRIGGER_SOURCE_SYNC_IDX, &args);
> 
> I don't see how args are being used. This puts in doubt the need of the first
> patch.
> 

If the wrapper is the issue, maybe it is better doing this instead?

static int ad7768_trigger_sources_sync_setup(struct device *dev,
					     struct fwnode_handle *dev_fwnode,
					     struct ad7768_state *st)
{
	struct fwnode_reference_args args;
	struct fwnode_handle *fwnode __free(fwnode_handle) = NULL;
	int ret;

	ret = fwnode_property_get_reference_args(dev_fwnode, "trigger-sources",
						 "#trigger-source-cells", 0,
						 AD7768_TRIGGER_SOURCE_SYNC_IDX, &args);
	if (ret)
		return ret;

	fwnode = args.fwnode;
> > +	/* First, try getting the GPIO trigger source */
> > +	if (fwnode_device_is_compatible(fwnode, "gpio-trigger")) {
> > +		st->gpio_sync_in = devm_fwnode_gpiod_get_index(dev, fwnode,
> > +							       NULL,
> > +							       0,
> > +							       GPIOD_OUT_LOW,
> > +							       "sync-in");
> > +		return PTR_ERR_OR_ZERO(st->gpio_sync_in);
> > +	}
> > +
> > +	/*
> > +	 * TODO: Support the other cases when we have a trigger subsystem
> > +	 * to reliably handle other types of devices as trigger sources.
> > +	 *
> > +	 * For now, return an error message. For self triggering, omit the
> > +	 * trigger-sources property.
> > +	 */
> > +	return dev_err_probe(dev, -EOPNOTSUPP, "Invalid synchronization trigger source\n");
> > +}

Then we can get rid of the first patch.

Regards,
Jonathan S.
Andy Shevchenko June 2, 2025, 9:25 p.m. UTC | #9
Mon, Jun 02, 2025 at 02:15:23PM -0300, Jonathan Santos kirjoitti:
> On 05/30, Andy Shevchenko wrote:
> > On Thu, May 29, 2025 at 07:50:29PM -0300, Jonathan Santos wrote:

...

> > > +static int ad7768_trigger_sources_sync_setup(struct device *dev,
> > > +					     struct fwnode_handle *dev_fwnode,
> > > +					     struct ad7768_state *st)
> > > +{
> > > +	struct fwnode_reference_args args;
> > > +
> > > +	struct fwnode_handle *fwnode __free(fwnode_handle) =
> > > +		fwnode_find_reference_args(dev_fwnode, "trigger-sources",
> > > +					   "#trigger-source-cells", 0,
> > > +					   AD7768_TRIGGER_SOURCE_SYNC_IDX, &args);
> > 
> > I don't see how args are being used. This puts in doubt the need of the first
> > patch.
> 
> If the wrapper is the issue, maybe it is better doing this instead?
> 
> static int ad7768_trigger_sources_sync_setup(struct device *dev,
> 					     struct fwnode_handle *dev_fwnode,

Name it fwnode...

> 					     struct ad7768_state *st)
> {
> 	struct fwnode_reference_args args;
> 	struct fwnode_handle *fwnode __free(fwnode_handle) = NULL;

...and this one something like 'ref'. Also I'm not sure the __free() will do
what you expect from it.

> 	int ret;
> 
> 	ret = fwnode_property_get_reference_args(dev_fwnode, "trigger-sources",
> 						 "#trigger-source-cells", 0,
> 						 AD7768_TRIGGER_SOURCE_SYNC_IDX, &args);
> 	if (ret)
> 		return ret;
> 
> 	fwnode = args.fwnode;

Yes, please. This looks better.

> > > +	/* First, try getting the GPIO trigger source */
> > > +	if (fwnode_device_is_compatible(fwnode, "gpio-trigger")) {
> > > +		st->gpio_sync_in = devm_fwnode_gpiod_get_index(dev, fwnode,
> > > +							       NULL,
> > > +							       0,
> > > +							       GPIOD_OUT_LOW,
> > > +							       "sync-in");
> > > +		return PTR_ERR_OR_ZERO(st->gpio_sync_in);
> > > +	}
> > > +
> > > +	/*
> > > +	 * TODO: Support the other cases when we have a trigger subsystem
> > > +	 * to reliably handle other types of devices as trigger sources.
> > > +	 *
> > > +	 * For now, return an error message. For self triggering, omit the
> > > +	 * trigger-sources property.
> > > +	 */
> > > +	return dev_err_probe(dev, -EOPNOTSUPP, "Invalid synchronization trigger source\n");
> > > +}
> 
> Then we can get rid of the first patch.
Jonathan Cameron June 7, 2025, 12:19 p.m. UTC | #10
On Tue, 3 Jun 2025 00:25:40 +0300
Andy Shevchenko <andy.shevchenko@gmail.com> wrote:

> Mon, Jun 02, 2025 at 02:15:23PM -0300, Jonathan Santos kirjoitti:
> > On 05/30, Andy Shevchenko wrote:  
> > > On Thu, May 29, 2025 at 07:50:29PM -0300, Jonathan Santos wrote:  
> 
> ...
> 
> > > > +static int ad7768_trigger_sources_sync_setup(struct device *dev,
> > > > +					     struct fwnode_handle *dev_fwnode,
> > > > +					     struct ad7768_state *st)
> > > > +{
> > > > +	struct fwnode_reference_args args;
> > > > +
> > > > +	struct fwnode_handle *fwnode __free(fwnode_handle) =
> > > > +		fwnode_find_reference_args(dev_fwnode, "trigger-sources",
> > > > +					   "#trigger-source-cells", 0,
> > > > +					   AD7768_TRIGGER_SOURCE_SYNC_IDX, &args);  
> > > 
> > > I don't see how args are being used. This puts in doubt the need of the first
> > > patch.  
> > 
> > If the wrapper is the issue, maybe it is better doing this instead?
> > 
> > static int ad7768_trigger_sources_sync_setup(struct device *dev,
> > 					     struct fwnode_handle *dev_fwnode,  
> 
> Name it fwnode...
> 
> > 					     struct ad7768_state *st)
> > {
> > 	struct fwnode_reference_args args;
> > 	struct fwnode_handle *fwnode __free(fwnode_handle) = NULL;  
> 
> ...and this one something like 'ref'. Also I'm not sure the __free() will do
> what you expect from it.
> 
> > 	int ret;
> > 
> > 	ret = fwnode_property_get_reference_args(dev_fwnode, "trigger-sources",
> > 						 "#trigger-source-cells", 0,
> > 						 AD7768_TRIGGER_SOURCE_SYNC_IDX, &args);
> > 	if (ret)
> > 		return ret;
> > 
> > 	fwnode = args.fwnode;  
> 
> Yes, please. This looks better.

Take a look at the guidance in cleanup.h first.  Linus made it very clear
that the = NULL then set it later pattern was not the way to go. That was
one of the things buried deep in a discussion thread soon after the cleanup.h
stuff was proposed and the lack of general knowledge of that preference lead
to Dan adding that documentation to cleanup.h.

If __free is used Linus always wants to see the constructor and destructor in the same line. 

That is why I suggested the approach in patch 1.

If that isn't acceptable (yet), wrap this up in a local function doing the equivalent
of patch 1 and we can wait and see how common this ends up being.

Jonathan


> 
> > > > +	/* First, try getting the GPIO trigger source */
> > > > +	if (fwnode_device_is_compatible(fwnode, "gpio-trigger")) {
> > > > +		st->gpio_sync_in = devm_fwnode_gpiod_get_index(dev, fwnode,
> > > > +							       NULL,
> > > > +							       0,
> > > > +							       GPIOD_OUT_LOW,
> > > > +							       "sync-in");
> > > > +		return PTR_ERR_OR_ZERO(st->gpio_sync_in);
> > > > +	}
> > > > +
> > > > +	/*
> > > > +	 * TODO: Support the other cases when we have a trigger subsystem
> > > > +	 * to reliably handle other types of devices as trigger sources.
> > > > +	 *
> > > > +	 * For now, return an error message. For self triggering, omit the
> > > > +	 * trigger-sources property.
> > > > +	 */
> > > > +	return dev_err_probe(dev, -EOPNOTSUPP, "Invalid synchronization trigger source\n");
> > > > +}  
> > 
> > Then we can get rid of the first patch.  
>