Re: [PATCH 08/10] iio: backend: add new functionality

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, 2024-03-28 at 15:16 +0000, Jonathan Cameron wrote:
> On Thu, 28 Mar 2024 14:22:32 +0100
> Nuno Sa via B4 Relay <devnull+nuno.sa.analog.com@xxxxxxxxxx> wrote:
> 
> > From: Nuno Sa <nuno.sa@xxxxxxxxxx>
> > 
> > This adds the needed backend ops for supporting a backend inerfacing
> > with an high speed dac. The new ops are:
> > 
> > * data_source_set();
> > * set_sampling_freq();
> > * extend_chan_spec();
> > * ext_info_set();
> > * ext_info_get().
> > 
> > Also to note the new helpers that are meant to be used by the backends
> > when extending an IIO channel (adding extended info):
> > 
> > * iio_backend_ext_info_set();
> > * iio_backend_ext_info_get().
> > 
> > Signed-off-by: Nuno Sa <nuno.sa@xxxxxxxxxx>
> I'm pretty flexible on this so far as I think we are still learning how front
> ends and backends should interact. Maybe we'll figure that out in the medium
> term and rework this stuff. For now it looks fine. A few minor things inline.
> >  
> > +/**
> > + * iio_backend_ext_info_get - IIO ext_info read callback
> > + * @indio_dev:	IIO device
> > + * @private:	Data private to the driver
> > + * @chan:	IIO channel
> > + * @buf:	Buffer where to place the attribute data
> > + *
> > + * This helper is intended to be used by backends that extend an IIO channel
> > + * (trough iio_backend_extend_chan_spec()) with extended info. In that case,
> > + * backends are not supposed to give their own callbacks (as they would not
> > + * a way to get te backend from indio_dev). This is the getter.
> 
> te->the?

Yes and some more typos :).

> 
> 
> > +/**
> > + * iio_backend_extend_chan_spec - Extend an IIO channel
> > + * @indio_dev:	IIO device
> > + * @back:	Backend device
> > + * @chan:	IIO channel
> > + *
> > + * Some backends may have their own functionalities and hence capable of
> > + * extending a frontend's channel.
> > + *
> > + * RETURNS:
> > + * 0 on success, negative error number on failure.
> > + */
> > +int iio_backend_extend_chan_spec(struct iio_dev *indio_dev,
> > +				 struct iio_backend *back,
> > +				 struct iio_chan_spec *chan)
> > +{
> > +	const struct iio_chan_spec_ext_info *ext_info = chan->ext_info;
> This is getting confusing.  So this one is the front end value of ext_info?
> Name it as such frontend_ext_info

Yes, it's the frontend pointer. Just to enforce the below constrain. Will rename as
suggested.

> 
> > +	int ret;
> > +
> > +	ret = iio_backend_op_call(back, extend_chan_spec, chan);
> > +	if (ret)
> > +		return ret;
> > +	/*
> > +	 * Let's keep things simple for now. Don't allow to overwrite the
> > +	 * frontend's extended info. If ever needed, we can support appending
> > +	 * it.
> > +	 */
> > +	if (ext_info && chan->ext_info != ext_info)
> > +		return -EOPNOTSUPP;
> > +	if (!chan->ext_info)
> 
> This is checking if the backend added anything? Perhaps a comment on that
> as we don't need a backend_ext_info local variable...

Yes, but just regarding ext_info as that is the only thing we're handling below
(doing some sanity checks). Note that (as you said above) I'm keeping things a bit
"open" in that the backend is open to extend whatever it wants. With time we may
learn better what do we want constrain or not.

> 
> > +		return 0;
> > +	/*
> > +	 * !\NOTE: this will break as soon as we have multiple backends on one
> > +	 * frontend and all of them extend channels. In that case, the core
> > +	 * backend code has no way to get the correct backend given the
> > +	 * iio device.
> > +	 *
> > +	 * One solution for this could be introducing a new backend
> > +	 * dedicated callback in struct iio_info so we can callback into the
> > +	 * frontend so it can give us the right backend given a chan_spec.
> > +	 */
> 
> Hmm. This is indeed messy.  Could we associate it with the buffer as presuably
> a front end with multiple backends is using multiple IIO buffers?
> 

Hmm, the assumption of having multiple buffers seems plausible to me but considering
the example we have in hands it would be cumbersome to get the backend. Considering
iio_backend_ext_info_get(), how could we get the backend if it was associated to one
of the IIO buffers? I think we would need more "intrusive" changes to make that work
or do you have something in mind=
 
> As you say a dance via the front end would work fine.

I'm happy you're also open for a proper solution already. I mention this in the
cover. My idea was something like (consider the iio_backend_ext_info_get()):

if (!indio_dev->info->get_iio_backend())
	return -EOPNOTSUPP;

back = indio_dev->info->get_iio_backend(indio_dev, chan_spec);

It would be nice to have some "default/generic" implementation for cases where we
only have one backend per frontend so that the frontend would not need to define the
callback.
  
> 
> 
> > +	iio_device_set_drvdata(indio_dev, back);
> > +
> > +	/* Don't allow backends to get creative and force their own handlers */
> > +	for (ext_info = chan->ext_info; ext_info->name; ext_info++) {
> > +		if (ext_info->read != iio_backend_ext_info_get)
> > +			return -EINVAL;
> > +		if (ext_info->write != iio_backend_ext_info_set)
> > +			return -EINVAL;
> > +	}
> > +
> > +	return 0;
> > +}
> > +EXPORT_SYMBOL_NS_GPL(iio_backend_extend_chan_spec, IIO_BACKEND);
> 
> > diff --git a/include/linux/iio/backend.h b/include/linux/iio/backend.h
> > index a6d79381866e..09ff2f8f9fd8 100644
> > --- a/include/linux/iio/backend.h
> > +++ b/include/linux/iio/backend.h
> > @@ -4,6 +4,7 @@
> >  
> >  #include <linux/types.h>
> >  
> > +struct iio_chan_spec;
> >  struct fwnode_handle;
> >  struct iio_backend;
> >  struct device;
> > @@ -15,6 +16,26 @@ enum iio_backend_data_type {
> >  	IIO_BACKEND_DATA_TYPE_MAX
> >  };
> >  
> > +enum iio_backend_data_source {
> > +	IIO_BACKEND_INTERNAL_CW,
> 
> CW?  Either expand out what ever that is in definition of add a comment
> at least.

Continuous wave :)

> 
> > +	IIO_BACKEND_EXTERNAL,
> What does external mean in this case?

In this particular case comes from a DMA source (IP). I thought external to be more
generic but if you prefer, I can do something like IIO_BACKEND_DMA?


> > +	IIO_BACKEND_DATA_SOURCE_MAX
> > +};
> > +
> > +/**
> > + * IIO_BACKEND_EX_INFO - Helper for an IIO extended channel attribute
> > + * @_name:	Attribute name
> > + * @_shared:	Whether the attribute is shared between all channels
> > + * @_what:	Data private to the driver
> > + */
> > +#define IIO_BACKEND_EX_INFO(_name, _shared, _what) {	\
> > +	.name = (_name),				\
> > +	.shared = (_shared),				\
> > +	.read =  iio_backend_ext_info_get,		\
> > +	.write = iio_backend_ext_info_set,		\
> > +	.private = (_what),				\
> > +}
> > +
> >  /**
> >   * struct iio_backend_data_fmt - Backend data format
> >   * @type:		Data type.
> > @@ -35,8 +56,13 @@ struct iio_backend_data_fmt {
> >   * @chan_enable:	Enable one channel.
> >   * @chan_disable:	Disable one channel.
> >   * @data_format_set:	Configure the data format for a specific channel.
> > + * @data_source_set:	Configure the data source for a specific channel.
> > + * @set_sample_rate:	Configure the sampling rate for a specific channel.
> >   * @request_buffer:	Request an IIO buffer.
> >   * @free_buffer:	Free an IIO buffer.
> > + * @extend_chan_spec:	Extend an IIO channel.
> > + * @ext_info_set:	Extended info setter.
> > + * @ext_info_get:	Extended info getter.
> >   **/
> >  struct iio_backend_ops {
> >  	int (*enable)(struct iio_backend *back);
> > @@ -45,10 +71,21 @@ struct iio_backend_ops {
> >  	int (*chan_disable)(struct iio_backend *back, unsigned int chan);
> >  	int (*data_format_set)(struct iio_backend *back, unsigned int chan,
> >  			       const struct iio_backend_data_fmt *data);
> > +	int (*data_source_set)(struct iio_backend *back, unsigned int chan,
> > +			       enum iio_backend_data_source data);
> > +	int (*set_sample_rate)(struct iio_backend *back, unsigned int chan,
> > +			       u64 sample_rate);
> 
> Name the parameter that so we know the units.  _hz? 

yes. And u64 to not fall in the CCF problem for 32bits :)

- Nuno Sá






[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Input]     [Linux Kernel]     [Linux SCSI]     [X.org]

  Powered by Linux