/* The industrial I/O callback buffer
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 as published by
 * the Free Software Foundation.
 */

#include <linux/kernel.h>
#include <linux/module.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)(const void *data, void *private);
	void *private;
	struct iio_channel *channels;
	struct iio_dev *indio_dev;
};

static struct iio_cb_buffer *buffer_to_cb_buffer(struct iio_buffer *buffer)
{
	return container_of(buffer, struct iio_cb_buffer, buffer);
}

static int iio_buffer_cb_store_to(struct iio_buffer *buffer, const void *data)
{
	struct iio_cb_buffer *cb_buff = buffer_to_cb_buffer(buffer);
	return cb_buff->cb(data, cb_buff->private);
}

static void iio_buffer_cb_release(struct iio_buffer *buffer)
{
	struct iio_cb_buffer *cb_buff = buffer_to_cb_buffer(buffer);
	kfree(cb_buff->buffer.scan_mask);
	kfree(cb_buff);
}

static const struct iio_buffer_access_funcs iio_cb_access = {
	.store_to = &iio_buffer_cb_store_to,
	.release = &iio_buffer_cb_release,

	.modes = INDIO_BUFFER_SOFTWARE | INDIO_BUFFER_TRIGGERED,
};

struct iio_cb_buffer *iio_channel_get_all_cb(struct device *dev,
					     int (*cb)(const void *data,
						       void *private),
					     void *private)
{
	int ret;
	struct iio_cb_buffer *cb_buff;
	struct iio_channel *chan;

	cb_buff = kzalloc(sizeof(*cb_buff), GFP_KERNEL);
	if (cb_buff == NULL)
		return ERR_PTR(-ENOMEM);

	iio_buffer_init(&cb_buff->buffer);

	cb_buff->private = private;
	cb_buff->cb = cb;
	cb_buff->buffer.access = &iio_cb_access;
	INIT_LIST_HEAD(&cb_buff->buffer.demux_list);

	cb_buff->channels = iio_channel_get_all(dev);
	if (IS_ERR(cb_buff->channels)) {
		ret = PTR_ERR(cb_buff->channels);
		goto error_free_cb_buff;
	}

	cb_buff->indio_dev = cb_buff->channels[0].indio_dev;
	cb_buff->buffer.scan_mask
		= kcalloc(BITS_TO_LONGS(cb_buff->indio_dev->masklength),
			  sizeof(long), GFP_KERNEL);
	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 != cb_buff->indio_dev) {
			ret = -EINVAL;
			goto error_free_scan_mask;
		}
		set_bit(chan->channel->scan_index,
			cb_buff->buffer.scan_mask);
		chan++;
	}

	return cb_buff;

error_free_scan_mask:
	kfree(cb_buff->buffer.scan_mask);
error_release_channels:
	iio_channel_release_all(cb_buff->channels);
error_free_cb_buff:
	kfree(cb_buff);
	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->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->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);
	iio_buffer_put(&cb_buff->buffer);
}
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);

struct iio_dev
*iio_channel_cb_get_iio_dev(const struct iio_cb_buffer *cb_buffer)
{
	return cb_buffer->indio_dev;
}
EXPORT_SYMBOL_GPL(iio_channel_cb_get_iio_dev);

MODULE_AUTHOR("Jonathan Cameron <jic23@kernel.org>");
MODULE_DESCRIPTION("Industrial I/O callback buffer");
MODULE_LICENSE("GPL");
