All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 2/2] iio: chemical: sgpxx: triggered buffer support
@ 2017-11-21 16:11 Andreas Brauchli
  2017-11-25 17:48 ` Jonathan Cameron
  0 siblings, 1 reply; 3+ messages in thread
From: Andreas Brauchli @ 2017-11-21 16:11 UTC (permalink / raw)
  To: Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler
  Cc: linux-iio, linux-kernel

Support triggered buffer for use with e.g. hrtimer for automated
polling to ensure that the sensor's internal baseline is correctly
updated independently of the use-case.

Triggered buffer support is only enabled when IIO_BUFFER is set.

Signed-off-by: Andreas Brauchli <andreas.brauchli@sensirion.com>
---
 drivers/iio/chemical/Kconfig |  3 +++
 drivers/iio/chemical/sgpxx.c | 38 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 41 insertions(+)

diff --git a/drivers/iio/chemical/Kconfig b/drivers/iio/chemical/Kconfig
index 4574dd687513..6710fbfc6451 100644
--- a/drivers/iio/chemical/Kconfig
+++ b/drivers/iio/chemical/Kconfig
@@ -42,12 +42,15 @@ config SENSIRION_SGPXX
 	tristate "Sensirion SGPxx gas sensors"
 	depends on I2C
 	select CRC8
+	select IIO_TRIGGERED_BUFFER if (IIO_BUFFER)
 	help
 	  Say Y here to build I2C interface support for the following
 	  Sensirion SGP gas sensors:
 	    * SGP30 gas sensor
 	    * SGPC3 gas sensor
 
+	  Also select IIO_BUFFER to enable triggered buffers.
+
 	  To compile this driver as module, choose M here: the
 	  module will be called sgpxx.
 
diff --git a/drivers/iio/chemical/sgpxx.c b/drivers/iio/chemical/sgpxx.c
index aea55e41d4cc..025206448f73 100644
--- a/drivers/iio/chemical/sgpxx.c
+++ b/drivers/iio/chemical/sgpxx.c
@@ -27,6 +27,10 @@
 #include <linux/of_device.h>
 #include <linux/iio/iio.h>
 #include <linux/iio/buffer.h>
+#ifdef CONFIG_IIO_BUFFER
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/triggered_buffer.h>
+#endif /* CONFIG_IIO_BUFFER */
 #include <linux/iio/sysfs.h>
 
 #define SGP_WORD_LEN			2
@@ -789,6 +793,26 @@ static const struct of_device_id sgp_dt_ids[] = {
 	{ }
 };
 
+#ifdef CONFIG_IIO_BUFFER
+static irqreturn_t sgp_trigger_handler(int irq, void *p)
+{
+	struct iio_poll_func *pf = p;
+	struct iio_dev *indio_dev = pf->indio_dev;
+	struct sgp_data *data = iio_priv(indio_dev);
+	int ret;
+
+	ret = sgp_get_measurement(data, data->measure_iaq_cmd,
+				  SGP_MEASURE_MODE_IAQ);
+	if (!ret)
+		iio_push_to_buffers_with_timestamp(indio_dev,
+						   &data->buffer.start,
+						   pf->timestamp);
+
+	iio_trigger_notify_done(indio_dev->trig);
+	return IRQ_HANDLED;
+}
+#endif /* CONFIG_IIO_BUFFER */
+
 static int sgp_probe(struct i2c_client *client,
 		     const struct i2c_device_id *id)
 {
@@ -846,6 +870,17 @@ static int sgp_probe(struct i2c_client *client,
 	indio_dev->channels = chip->channels;
 	indio_dev->num_channels = chip->num_channels;
 
+#ifdef CONFIG_IIO_BUFFER
+	ret = iio_triggered_buffer_setup(indio_dev,
+					 iio_pollfunc_store_time,
+					 sgp_trigger_handler,
+					 NULL);
+	if (ret) {
+		dev_err(&client->dev, "failed to setup iio triggered buffer\n");
+		goto fail_free;
+	}
+#endif /* CONFIG_IIO_BUFFER */
+
 	ret = devm_iio_device_register(&client->dev, indio_dev);
 	if (!ret)
 		return ret;
@@ -863,6 +898,9 @@ static int sgp_remove(struct i2c_client *client)
 {
 	struct iio_dev *indio_dev = i2c_get_clientdata(client);
 
+#ifdef CONFIG_IIO_BUFFER
+	iio_triggered_buffer_cleanup(indio_dev);
+#endif /* CONFIG_IIO_BUFFER */
 	devm_iio_device_unregister(&client->dev, indio_dev);
 	return 0;
 }
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH 2/2] iio: chemical: sgpxx: triggered buffer support
  2017-11-21 16:11 [PATCH 2/2] iio: chemical: sgpxx: triggered buffer support Andreas Brauchli
@ 2017-11-25 17:48 ` Jonathan Cameron
  2018-03-10 22:06   ` Andreas Brauchli
  0 siblings, 1 reply; 3+ messages in thread
From: Jonathan Cameron @ 2017-11-25 17:48 UTC (permalink / raw)
  To: Andreas Brauchli
  Cc: Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald-Stadler,
	linux-iio, linux-kernel

On Tue, 21 Nov 2017 17:11:29 +0100
Andreas Brauchli <a.brauchli@elementarea.net> wrote:

> Support triggered buffer for use with e.g. hrtimer for automated
> polling to ensure that the sensor's internal baseline is correctly
> updated independently of the use-case.

Given the really strict timing requirements for this device and slow
read rates, I wouldn't involve a triggered buffer at all, but actually
do it with a thread / timer within the initial driver.   The
sysfs interface is more than adequate for a 1Hz device so using
the buffered option is just adding unnecessary complexity...

I reviewed the code anyway.  Key thing is though the file would be
small, there should be a separate .c file for the buffered support
if you are going to make it optional. That way we don't get ifdefs
in the c file, but rather stubs provided in the header.

You could decide to add stubs to include/linux/iio/triggered_buffer.h
/buffer.h

and then use __maybe_unusued to mark your trigger function.
The compiler would drop it anyway and this would suppress build
warnings.  

However, I don't think this device wants to be supported via the
buffered interfaces at all.  More smartness needed in the core
driver to maintain the timing etc.

Jonathan
> 
> Triggered buffer support is only enabled when IIO_BUFFER is set.
> 
> Signed-off-by: Andreas Brauchli <andreas.brauchli@sensirion.com>
> ---
>  drivers/iio/chemical/Kconfig |  3 +++
>  drivers/iio/chemical/sgpxx.c | 38 ++++++++++++++++++++++++++++++++++++++
>  2 files changed, 41 insertions(+)
> 
> diff --git a/drivers/iio/chemical/Kconfig b/drivers/iio/chemical/Kconfig
> index 4574dd687513..6710fbfc6451 100644
> --- a/drivers/iio/chemical/Kconfig
> +++ b/drivers/iio/chemical/Kconfig
> @@ -42,12 +42,15 @@ config SENSIRION_SGPXX
>  	tristate "Sensirion SGPxx gas sensors"
>  	depends on I2C
>  	select CRC8
> +	select IIO_TRIGGERED_BUFFER if (IIO_BUFFER)
>  	help
>  	  Say Y here to build I2C interface support for the following
>  	  Sensirion SGP gas sensors:
>  	    * SGP30 gas sensor
>  	    * SGPC3 gas sensor
>  
> +	  Also select IIO_BUFFER to enable triggered buffers.
> +
>  	  To compile this driver as module, choose M here: the
>  	  module will be called sgpxx.
>  
> diff --git a/drivers/iio/chemical/sgpxx.c b/drivers/iio/chemical/sgpxx.c
> index aea55e41d4cc..025206448f73 100644
> --- a/drivers/iio/chemical/sgpxx.c
> +++ b/drivers/iio/chemical/sgpxx.c
> @@ -27,6 +27,10 @@
>  #include <linux/of_device.h>
>  #include <linux/iio/iio.h>
>  #include <linux/iio/buffer.h>
> +#ifdef CONFIG_IIO_BUFFER
> +#include <linux/iio/trigger_consumer.h>
> +#include <linux/iio/triggered_buffer.h>
> +#endif /* CONFIG_IIO_BUFFER */
>  #include <linux/iio/sysfs.h>
>  
>  #define SGP_WORD_LEN			2
> @@ -789,6 +793,26 @@ static const struct of_device_id sgp_dt_ids[] = {
>  	{ }
>  };
>  
> +#ifdef CONFIG_IIO_BUFFER

All this ifdef fun is rather messy.
Split it out to a separate file like most other drivers with
optional buffer support. 

General rule (more or less) of kernel drivers is that
any optional ifdef stuff should be in headers to provide stubs
when code isn't available, not down in the drivers making them
harder to read.

> +static irqreturn_t sgp_trigger_handler(int irq, void *p)
> +{
> +	struct iio_poll_func *pf = p;
> +	struct iio_dev *indio_dev = pf->indio_dev;
> +	struct sgp_data *data = iio_priv(indio_dev);
> +	int ret;
> +
> +	ret = sgp_get_measurement(data, data->measure_iaq_cmd,
> +				  SGP_MEASURE_MODE_IAQ);
> +	if (!ret)
> +		iio_push_to_buffers_with_timestamp(indio_dev,
> +						   &data->buffer.start,
> +						   pf->timestamp);
> +
> +	iio_trigger_notify_done(indio_dev->trig);
> +	return IRQ_HANDLED;
> +}
> +#endif /* CONFIG_IIO_BUFFER */
> +
>  static int sgp_probe(struct i2c_client *client,
>  		     const struct i2c_device_id *id)
>  {
> @@ -846,6 +870,17 @@ static int sgp_probe(struct i2c_client *client,
>  	indio_dev->channels = chip->channels;
>  	indio_dev->num_channels = chip->num_channels;
>  
> +#ifdef CONFIG_IIO_BUFFER
> +	ret = iio_triggered_buffer_setup(indio_dev,
> +					 iio_pollfunc_store_time,
> +					 sgp_trigger_handler,
> +					 NULL);
> +	if (ret) {
> +		dev_err(&client->dev, "failed to setup iio triggered buffer\n");
> +		goto fail_free;
> +	}
> +#endif /* CONFIG_IIO_BUFFER */
> +
>  	ret = devm_iio_device_register(&client->dev, indio_dev);
>  	if (!ret)
>  		return ret;
> @@ -863,6 +898,9 @@ static int sgp_remove(struct i2c_client *client)
>  {
>  	struct iio_dev *indio_dev = i2c_get_clientdata(client);
>  
> +#ifdef CONFIG_IIO_BUFFER
> +	iio_triggered_buffer_cleanup(indio_dev);
> +#endif /* CONFIG_IIO_BUFFER */

I would prefer stubs being added to the header for this case to having
ifdefs in here.

>  	devm_iio_device_unregister(&client->dev, indio_dev);
>  	return 0;
>  }

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH 2/2] iio: chemical: sgpxx: triggered buffer support
  2017-11-25 17:48 ` Jonathan Cameron
@ 2018-03-10 22:06   ` Andreas Brauchli
  0 siblings, 0 replies; 3+ messages in thread
From: Andreas Brauchli @ 2018-03-10 22:06 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald-Stadler,
	linux-iio, linux-kernel

On Sat, 2017-11-25 at 17:48 +0000, Jonathan Cameron wrote:
> On Tue, 21 Nov 2017 17:11:29 +0100
> Andreas Brauchli <a.brauchli@elementarea.net> wrote:
> 
> > Support triggered buffer for use with e.g. hrtimer for automated
> > polling to ensure that the sensor's internal baseline is correctly
> > updated independently of the use-case.
> 
> Given the really strict timing requirements for this device and slow
> read rates, I wouldn't involve a triggered buffer at all, but
> actually
> do it with a thread / timer within the initial driver.   The
> sysfs interface is more than adequate for a 1Hz device so using
> the buffered option is just adding unnecessary complexity...

Thanks for the suggestions, I went with that in v2.

> 
> I reviewed the code anyway.  Key thing is though the file would be
> small, there should be a separate .c file for the buffered support
> if you are going to make it optional. That way we don't get ifdefs
> in the c file, but rather stubs provided in the header.

FWIW, I learned a few things

> You could decide to add stubs to include/linux/iio/triggered_buffer.h
> /buffer.h
> 
> and then use __maybe_unusued to mark your trigger function.
> The compiler would drop it anyway and this would suppress build
> warnings.  
> 
> However, I don't think this device wants to be supported via the
> buffered interfaces at all.  More smartness needed in the core
> driver to maintain the timing etc.
> 
> Jonathan
> > 
> > Triggered buffer support is only enabled when IIO_BUFFER is set.
> > 
> > Signed-off-by: Andreas Brauchli <andreas.brauchli@sensirion.com>
> > ---
> >  drivers/iio/chemical/Kconfig |  3 +++
> >  drivers/iio/chemical/sgpxx.c | 38
> > ++++++++++++++++++++++++++++++++++++++
> >  2 files changed, 41 insertions(+)
> > 
> > diff --git a/drivers/iio/chemical/Kconfig
> > b/drivers/iio/chemical/Kconfig
> > index 4574dd687513..6710fbfc6451 100644
> > --- a/drivers/iio/chemical/Kconfig
> > +++ b/drivers/iio/chemical/Kconfig
> > @@ -42,12 +42,15 @@ config SENSIRION_SGPXX
> >  	tristate "Sensirion SGPxx gas sensors"
> >  	depends on I2C
> >  	select CRC8
> > +	select IIO_TRIGGERED_BUFFER if (IIO_BUFFER)
> >  	help
> >  	  Say Y here to build I2C interface support for the
> > following
> >  	  Sensirion SGP gas sensors:
> >  	    * SGP30 gas sensor
> >  	    * SGPC3 gas sensor
> >  
> > +	  Also select IIO_BUFFER to enable triggered buffers.
> > +
> >  	  To compile this driver as module, choose M here: the
> >  	  module will be called sgpxx.
> >  
> > diff --git a/drivers/iio/chemical/sgpxx.c
> > b/drivers/iio/chemical/sgpxx.c
> > index aea55e41d4cc..025206448f73 100644
> > --- a/drivers/iio/chemical/sgpxx.c
> > +++ b/drivers/iio/chemical/sgpxx.c
> > @@ -27,6 +27,10 @@
> >  #include <linux/of_device.h>
> >  #include <linux/iio/iio.h>
> >  #include <linux/iio/buffer.h>
> > +#ifdef CONFIG_IIO_BUFFER
> > +#include <linux/iio/trigger_consumer.h>
> > +#include <linux/iio/triggered_buffer.h>
> > +#endif /* CONFIG_IIO_BUFFER */
> >  #include <linux/iio/sysfs.h>
> >  
> >  #define SGP_WORD_LEN			2
> > @@ -789,6 +793,26 @@ static const struct of_device_id sgp_dt_ids[]
> > = {
> >  	{ }
> >  };
> >  
> > +#ifdef CONFIG_IIO_BUFFER
> 
> All this ifdef fun is rather messy.
> Split it out to a separate file like most other drivers with
> optional buffer support. 
> 
> General rule (more or less) of kernel drivers is that
> any optional ifdef stuff should be in headers to provide stubs
> when code isn't available, not down in the drivers making them
> harder to read.
> 
> > +static irqreturn_t sgp_trigger_handler(int irq, void *p)
> > +{
> > +	struct iio_poll_func *pf = p;
> > +	struct iio_dev *indio_dev = pf->indio_dev;
> > +	struct sgp_data *data = iio_priv(indio_dev);
> > +	int ret;
> > +
> > +	ret = sgp_get_measurement(data, data->measure_iaq_cmd,
> > +				  SGP_MEASURE_MODE_IAQ);
> > +	if (!ret)
> > +		iio_push_to_buffers_with_timestamp(indio_dev,
> > +						   &data-
> > >buffer.start,
> > +						   pf->timestamp);
> > +
> > +	iio_trigger_notify_done(indio_dev->trig);
> > +	return IRQ_HANDLED;
> > +}
> > +#endif /* CONFIG_IIO_BUFFER */
> > +
> >  static int sgp_probe(struct i2c_client *client,
> >  		     const struct i2c_device_id *id)
> >  {
> > @@ -846,6 +870,17 @@ static int sgp_probe(struct i2c_client
> > *client,
> >  	indio_dev->channels = chip->channels;
> >  	indio_dev->num_channels = chip->num_channels;
> >  
> > +#ifdef CONFIG_IIO_BUFFER
> > +	ret = iio_triggered_buffer_setup(indio_dev,
> > +					 iio_pollfunc_store_time,
> > +					 sgp_trigger_handler,
> > +					 NULL);
> > +	if (ret) {
> > +		dev_err(&client->dev, "failed to setup iio
> > triggered buffer\n");
> > +		goto fail_free;
> > +	}
> > +#endif /* CONFIG_IIO_BUFFER */
> > +
> >  	ret = devm_iio_device_register(&client->dev, indio_dev);
> >  	if (!ret)
> >  		return ret;
> > @@ -863,6 +898,9 @@ static int sgp_remove(struct i2c_client
> > *client)
> >  {
> >  	struct iio_dev *indio_dev = i2c_get_clientdata(client);
> >  
> > +#ifdef CONFIG_IIO_BUFFER
> > +	iio_triggered_buffer_cleanup(indio_dev);
> > +#endif /* CONFIG_IIO_BUFFER */
> 
> I would prefer stubs being added to the header for this case to
> having
> ifdefs in here.
> 
> >  	devm_iio_device_unregister(&client->dev, indio_dev);
> >  	return 0;
> >  }
> 
> 

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2018-03-10 22:06 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-11-21 16:11 [PATCH 2/2] iio: chemical: sgpxx: triggered buffer support Andreas Brauchli
2017-11-25 17:48 ` Jonathan Cameron
2018-03-10 22:06   ` Andreas Brauchli

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.