Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  1/* The industrial I/O callback buffer
  2 *
  3 * This program is free software; you can redistribute it and/or modify it
  4 * under the terms of the GNU General Public License version 2 as published by
  5 * the Free Software Foundation.
  6 */
  7
  8#include <linux/kernel.h>
  9#include <linux/module.h>
 10#include <linux/slab.h>
 11#include <linux/err.h>
 12#include <linux/export.h>
 13#include <linux/iio/iio.h>
 14#include <linux/iio/buffer_impl.h>
 15#include <linux/iio/consumer.h>
 16
 17struct iio_cb_buffer {
 18	struct iio_buffer buffer;
 19	int (*cb)(const void *data, void *private);
 20	void *private;
 21	struct iio_channel *channels;
 22	struct iio_dev *indio_dev;
 23};
 24
 25static struct iio_cb_buffer *buffer_to_cb_buffer(struct iio_buffer *buffer)
 26{
 27	return container_of(buffer, struct iio_cb_buffer, buffer);
 28}
 29
 30static int iio_buffer_cb_store_to(struct iio_buffer *buffer, const void *data)
 31{
 32	struct iio_cb_buffer *cb_buff = buffer_to_cb_buffer(buffer);
 33	return cb_buff->cb(data, cb_buff->private);
 34}
 35
 36static void iio_buffer_cb_release(struct iio_buffer *buffer)
 37{
 38	struct iio_cb_buffer *cb_buff = buffer_to_cb_buffer(buffer);
 39	kfree(cb_buff->buffer.scan_mask);
 40	kfree(cb_buff);
 41}
 42
 43static const struct iio_buffer_access_funcs iio_cb_access = {
 44	.store_to = &iio_buffer_cb_store_to,
 45	.release = &iio_buffer_cb_release,
 46
 47	.modes = INDIO_BUFFER_SOFTWARE | INDIO_BUFFER_TRIGGERED,
 48};
 49
 50struct iio_cb_buffer *iio_channel_get_all_cb(struct device *dev,
 51					     int (*cb)(const void *data,
 52						       void *private),
 53					     void *private)
 54{
 55	int ret;
 56	struct iio_cb_buffer *cb_buff;
 57	struct iio_channel *chan;
 58
 59	cb_buff = kzalloc(sizeof(*cb_buff), GFP_KERNEL);
 60	if (cb_buff == NULL)
 61		return ERR_PTR(-ENOMEM);
 62
 63	iio_buffer_init(&cb_buff->buffer);
 64
 65	cb_buff->private = private;
 66	cb_buff->cb = cb;
 67	cb_buff->buffer.access = &iio_cb_access;
 68	INIT_LIST_HEAD(&cb_buff->buffer.demux_list);
 69
 70	cb_buff->channels = iio_channel_get_all(dev);
 71	if (IS_ERR(cb_buff->channels)) {
 72		ret = PTR_ERR(cb_buff->channels);
 73		goto error_free_cb_buff;
 74	}
 75
 76	cb_buff->indio_dev = cb_buff->channels[0].indio_dev;
 77	cb_buff->buffer.scan_mask
 78		= kcalloc(BITS_TO_LONGS(cb_buff->indio_dev->masklength),
 79			  sizeof(long), GFP_KERNEL);
 80	if (cb_buff->buffer.scan_mask == NULL) {
 81		ret = -ENOMEM;
 82		goto error_release_channels;
 83	}
 84	chan = &cb_buff->channels[0];
 85	while (chan->indio_dev) {
 86		if (chan->indio_dev != cb_buff->indio_dev) {
 87			ret = -EINVAL;
 88			goto error_free_scan_mask;
 89		}
 90		set_bit(chan->channel->scan_index,
 91			cb_buff->buffer.scan_mask);
 92		chan++;
 93	}
 94
 95	return cb_buff;
 96
 97error_free_scan_mask:
 98	kfree(cb_buff->buffer.scan_mask);
 99error_release_channels:
100	iio_channel_release_all(cb_buff->channels);
101error_free_cb_buff:
102	kfree(cb_buff);
103	return ERR_PTR(ret);
104}
105EXPORT_SYMBOL_GPL(iio_channel_get_all_cb);
106
107int iio_channel_cb_set_buffer_watermark(struct iio_cb_buffer *cb_buff,
108					size_t watermark)
109{
110	if (!watermark)
111		return -EINVAL;
112	cb_buff->buffer.watermark = watermark;
113
114	return 0;
115}
116EXPORT_SYMBOL_GPL(iio_channel_cb_set_buffer_watermark);
117
118int iio_channel_start_all_cb(struct iio_cb_buffer *cb_buff)
119{
120	return iio_update_buffers(cb_buff->indio_dev, &cb_buff->buffer,
121				  NULL);
122}
123EXPORT_SYMBOL_GPL(iio_channel_start_all_cb);
124
125void iio_channel_stop_all_cb(struct iio_cb_buffer *cb_buff)
126{
127	iio_update_buffers(cb_buff->indio_dev, NULL, &cb_buff->buffer);
128}
129EXPORT_SYMBOL_GPL(iio_channel_stop_all_cb);
130
131void iio_channel_release_all_cb(struct iio_cb_buffer *cb_buff)
132{
133	iio_channel_release_all(cb_buff->channels);
134	iio_buffer_put(&cb_buff->buffer);
135}
136EXPORT_SYMBOL_GPL(iio_channel_release_all_cb);
137
138struct iio_channel
139*iio_channel_cb_get_channels(const struct iio_cb_buffer *cb_buffer)
140{
141	return cb_buffer->channels;
142}
143EXPORT_SYMBOL_GPL(iio_channel_cb_get_channels);
144
145struct iio_dev
146*iio_channel_cb_get_iio_dev(const struct iio_cb_buffer *cb_buffer)
147{
148	return cb_buffer->indio_dev;
149}
150EXPORT_SYMBOL_GPL(iio_channel_cb_get_iio_dev);
151
152MODULE_AUTHOR("Jonathan Cameron <jic23@kernel.org>");
153MODULE_DESCRIPTION("Industrial I/O callback buffer");
154MODULE_LICENSE("GPL");