All of lore.kernel.org
 help / color / mirror / Atom feed
From: Lars-Peter Clausen <lars@metafoo.de>
To: Jonathan Cameron <jic23@kernel.org>
Cc: linux-iio@vger.kernel.org, Michael.Hennerich@analog.com,
	srinivas.pandruvada@intel.com
Subject: Re: [PATCH 3/4] staging:iio: add a callback buffer for in kernel push interface
Date: Wed, 17 Oct 2012 10:50:46 +0200	[thread overview]
Message-ID: <507E7166.40802@metafoo.de> (raw)
In-Reply-To: <1350120278-26929-4-git-send-email-jic23@kernel.org>

On 10/13/2012 11:24 AM, Jonathan Cameron wrote:
> This callback buffer is meant to be opaque to users, but basically
> adds a very simple pass through buffer to which data may be
> pushed when it is inserted into the buffer list.
> 
> Signed-off-by: Jonathan Cameron <jic23@kernel.org>
> ---
>  drivers/iio/Kconfig          |   6 +++
>  drivers/iio/Makefile         |   1 +
>  drivers/iio/buffer_cb.c      | 113 +++++++++++++++++++++++++++++++++++++++++++
>  include/linux/iio/consumer.h |  46 ++++++++++++++++++
>  4 files changed, 166 insertions(+)
> 
> diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig
> index 6e3f143..0aad08a 100644
> --- a/drivers/iio/Kconfig
> +++ b/drivers/iio/Kconfig
> @@ -20,6 +20,12 @@ config IIO_BUFFER
>  
>  if IIO_BUFFER
>  
> +config IIO_BUFFER_CB
> +       boolean "IIO callback buffer used for push in kernel interfaces"

Any specific reason why this has to be bool?

> +       help
> +         Should be selected by any drivers that do inkernel push
> +	 usage.  That is, those where the data is pushed to the consumer.
> +
>  config IIO_KFIFO_BUF
>  	select IIO_TRIGGER
>  	tristate "Industrial I/O buffering based on kfifo"
> diff --git a/drivers/iio/Makefile b/drivers/iio/Makefile
> index f7fa3c0..a27ec1c 100644
> --- a/drivers/iio/Makefile
> +++ b/drivers/iio/Makefile
> @@ -6,6 +6,7 @@ obj-$(CONFIG_IIO) += industrialio.o
>  industrialio-y := industrialio-core.o industrialio-event.o inkern.o
>  industrialio-$(CONFIG_IIO_BUFFER) += industrialio-buffer.o
>  industrialio-$(CONFIG_IIO_TRIGGER) += industrialio-trigger.o
> +industrialio-$(CONFIG_IIO_BUFFER_CB) += buffer_cb.o
>  
>  obj-$(CONFIG_IIO_TRIGGERED_BUFFER) += industrialio-triggered-buffer.o
>  obj-$(CONFIG_IIO_KFIFO_BUF) += kfifo_buf.o
> diff --git a/drivers/iio/buffer_cb.c b/drivers/iio/buffer_cb.c
> new file mode 100644
> index 0000000..d1e4881
> --- /dev/null
> +++ b/drivers/iio/buffer_cb.c
> @@ -0,0 +1,113 @@
> +#include <linux/kernel.h>
> +#include <linux/slab.h>
> +#include <linux/err.h>
> +#include <linux/export.h>
> +#include <linux/iio/buffer.h>
> +#include <linux/iio/consumer.h>
> +
> +struct iio_cb_buffer {
> +	struct iio_buffer buffer;
> +	int (*cb)(u8 *data, void *private);
> +	void *private;
> +	struct iio_channel *channels;
> +};
> +
> +static int iio_buffer_cb_store_to(struct iio_buffer *buffer, u8 *data)
> +{
> +	struct iio_cb_buffer *cb_buff = container_of(buffer,
> +						     struct iio_cb_buffer,
> +						     buffer);
> +
> +	return cb_buff->cb(data, cb_buff->private);
> +}
> +
> +static struct iio_buffer_access_funcs iio_cb_access = {
> +	.store_to = &iio_buffer_cb_store_to,
> +};
> +
> +struct iio_cb_buffer *iio_channel_get_all_cb(const char *name,
> +					     int (*cb)(u8 *data,
> +						       void *private),
> +					     void *private)
> +{
> +	int ret;
> +	struct iio_cb_buffer *cb_buff;
> +	struct iio_dev *indio_dev;
> +	struct iio_channel *chan;
> +
> +	cb_buff = kzalloc(sizeof *cb_buff, GFP_KERNEL);

sizeof(*cb_buff)

> +	if (cb_buff == NULL) {
> +		ret = -ENOMEM;
> +		goto error_ret;
> +	}
> +
> +	cb_buff->private = private;
> +	cb_buff->cb = cb;
> +	cb_buff->buffer.access = &iio_cb_access;
> +	INIT_LIST_HEAD(&cb_buff->buffer.demux_list);

It probably makes sense to have some kind of iio_buffer_init(...) for this

> +
> +	cb_buff->channels = iio_channel_get_all(name);
> +	if (IS_ERR(cb_buff->channels)) {
> +		ret = PTR_ERR(cb_buff->channels);
> +		goto error_free_cb_buff;
> +	}
> +
> +	indio_dev = cb_buff->channels[0].indio_dev;
> +	cb_buff->buffer.scan_mask
> +		= kzalloc(sizeof(long)*BITS_TO_LONGS(indio_dev->masklength),
> +			  GFP_KERNEL);

kcalloc

> +	if (cb_buff->buffer.scan_mask == NULL) {
> +		ret = -ENOMEM;
> +		goto error_release_channels;
> +	}
> +	chan = &cb_buff->channels[0];
> +	while (chan->indio_dev) {
> +		if (chan->indio_dev != indio_dev) {
> +			ret = -EINVAL;
> +			goto error_release_channels;
> +		}
> +		set_bit(chan->channel->scan_index,
> +			cb_buff->buffer.scan_mask);
> +		chan++;
> +	}
> +
> +	return cb_buff;
> +
> +error_release_channels:
> +	iio_channel_release_all(cb_buff->channels);
> +error_free_cb_buff:
> +	kfree(cb_buff);
> +error_ret:
> +	return ERR_PTR(ret);
> +}
> +EXPORT_SYMBOL_GPL(iio_channel_get_all_cb);
> +
> +int iio_channel_start_all_cb(struct iio_cb_buffer *cb_buff)
> +{
> +	return iio_update_buffers(cb_buff->channels[0].indio_dev,
> +				  &cb_buff->buffer,
> +				  NULL);
> +}
> +EXPORT_SYMBOL_GPL(iio_channel_start_all_cb);
> +
> +void iio_channel_stop_all_cb(struct iio_cb_buffer *cb_buff)
> +{
> +	iio_update_buffers(cb_buff->channels[0].indio_dev,
> +			   NULL,
> +			   &cb_buff->buffer);
> +}
> +EXPORT_SYMBOL_GPL(iio_channel_stop_all_cb);
> +
> +void iio_channel_release_all_cb(struct iio_cb_buffer *cb_buff)
> +{
> +	iio_channel_release_all(cb_buff->channels);
> +	kfree(cb_buff);
> +}
> +EXPORT_SYMBOL_GPL(iio_channel_release_all_cb);
> +
> +struct iio_channel
> +*iio_channel_cb_get_channels(const struct iio_cb_buffer *cb_buffer)
> +{
> +	return cb_buffer->channels;
> +}
> +EXPORT_SYMBOL_GPL(iio_channel_cb_get_channels);
> diff --git a/include/linux/iio/consumer.h b/include/linux/iio/consumer.h
> index 57efee6..caf103b 100644
> --- a/include/linux/iio/consumer.h
> +++ b/include/linux/iio/consumer.h
> @@ -61,6 +61,52 @@ struct iio_channel *iio_channel_get_all(const char *name);
>   */
>  void iio_channel_release_all(struct iio_channel *chan);
>  
> +struct iio_cb_buffer;
> +/**
> + * iio_channel_get_all_cb() - register callback for triggered capture
> + * @name:		Name of client device.
> + * @cb:			Callback function.
> + * @private:		Private data passed to callback.
> + *
> + * NB right now we have no ability to mux data from multiple devices.
> + * So if the channels requested come from different devices this will
> + * fail.
> + */
> +struct iio_cb_buffer *iio_channel_get_all_cb(const char *name,
> +					     int (*cb)(u8 *data,
> +						       void *private),
> +					     void *private);
> +/**
> + * iio_channel_release_all_cb() - release and unregister the callback.
> + * @cb_buffer:		The callback buffer that was allocated.
> + */
> +void iio_channel_release_all_cb(struct iio_cb_buffer *cb_buffer);
> +
> +/**
> + * iio_channel_start_all_cb() - start the flow of data through callback.
> + * @cb_buff:		The callback buffer we are starting.
> + */
> +int iio_channel_start_all_cb(struct iio_cb_buffer *cb_buff);
> +
> +/**
> + * iio_channel_stop_all_cb() - stop the flow of data through the callback.
> + * @cb_buff:		The callback buffer we are stopping.
> + */
> +void iio_channel_stop_all_cb(struct iio_cb_buffer *cb_buff);
> +
> +/**
> + * iio_channel_cb_get_channels() - get access to the underlying channels.
> + * @cb_buff:		The callback buffers from whom we want the channel
> + *			information.
> + *
> + * This function allows one to obtain information about the channels.
> + * Whilst this may allow direct reading if all buffers are disabled, the
> + * primary aim is to allow drivers that are consuming a channel to query
> + * things like scaling of the channel.
> + */
> +struct iio_channel
> +*iio_channel_cb_get_channels(const struct iio_cb_buffer *cb_buffer);
> +
>  /**
>   * iio_read_channel_raw() - read from a given channel
>   * @chan:		The channel being queried.


  reply	other threads:[~2012-10-17  8:49 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-10-13  9:24 [PATCH 0/4 V5] staging:iio: Add support for multiple buffers (testing required!) Jonathan Cameron
2012-10-13  9:24 ` [PATCH 1/4] staging:iio: Add support for multiple buffers Jonathan Cameron
2012-10-17  8:37   ` Lars-Peter Clausen
2012-10-19 15:03     ` Jonathan Cameron
2012-10-13  9:24 ` [PATCH 2/4] staging:iio:in kernel users: Add a data field for channel specific info Jonathan Cameron
2012-10-13  9:24 ` [PATCH 3/4] staging:iio: add a callback buffer for in kernel push interface Jonathan Cameron
2012-10-17  8:50   ` Lars-Peter Clausen [this message]
2012-10-17  8:52     ` Jonathan Cameron
2012-10-13  9:24 ` [PATCH 4/4] staging:iio: Proof of concept input driver Jonathan Cameron
2012-10-13  9:57   ` Jonathan Cameron
2012-10-18 18:28 ` [PATCH 0/4 V5] staging:iio: Add support for multiple buffers (testing required!) Pandruvada, Srinivas
2012-10-19 15:00   ` Jonathan Cameron
  -- strict thread matches above, loose matches on Subject: below --
2012-10-31 10:30 [PATCH 0/4 V6] " Jonathan Cameron
2012-10-31 10:30 ` [PATCH 3/4] staging:iio: add a callback buffer for in kernel push interface Jonathan Cameron
2012-10-31 14:10   ` Peter Meerwald
2012-11-02 10:53     ` Jonathan Cameron
2012-06-30 19:06 [PATCH 0/4 V3] staging:iio: Add support for multiple buffers Jonathan Cameron
2012-06-30 19:06 ` [PATCH 3/4] staging:iio: add a callback buffer for in kernel push interface Jonathan Cameron
2012-05-30 19:36 [PATCH 0/4 V2] staging:iio: Add support for multiple buffers Jonathan Cameron
2012-05-30 19:36 ` [PATCH 3/4] staging:iio: add a callback buffer for in kernel push interface Jonathan Cameron

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=507E7166.40802@metafoo.de \
    --to=lars@metafoo.de \
    --cc=Michael.Hennerich@analog.com \
    --cc=jic23@kernel.org \
    --cc=linux-iio@vger.kernel.org \
    --cc=srinivas.pandruvada@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.