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.
next prev parent 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).