brintos

brintos / linux-shallow public Read only

0
0
Text · 3.9 KiB · 4befc9f Raw
157 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/* The industrial I/O callback buffer3 */4 5#include <linux/kernel.h>6#include <linux/module.h>7#include <linux/slab.h>8#include <linux/err.h>9#include <linux/export.h>10#include <linux/iio/iio.h>11#include <linux/iio/buffer_impl.h>12#include <linux/iio/consumer.h>13 14struct iio_cb_buffer {15	struct iio_buffer buffer;16	int (*cb)(const void *data, void *private);17	void *private;18	struct iio_channel *channels;19	struct iio_dev *indio_dev;20};21 22static struct iio_cb_buffer *buffer_to_cb_buffer(struct iio_buffer *buffer)23{24	return container_of(buffer, struct iio_cb_buffer, buffer);25}26 27static int iio_buffer_cb_store_to(struct iio_buffer *buffer, const void *data)28{29	struct iio_cb_buffer *cb_buff = buffer_to_cb_buffer(buffer);30	return cb_buff->cb(data, cb_buff->private);31}32 33static void iio_buffer_cb_release(struct iio_buffer *buffer)34{35	struct iio_cb_buffer *cb_buff = buffer_to_cb_buffer(buffer);36 37	bitmap_free(cb_buff->buffer.scan_mask);38	kfree(cb_buff);39}40 41static const struct iio_buffer_access_funcs iio_cb_access = {42	.store_to = &iio_buffer_cb_store_to,43	.release = &iio_buffer_cb_release,44 45	.modes = INDIO_BUFFER_SOFTWARE | INDIO_BUFFER_TRIGGERED,46};47 48struct iio_cb_buffer *iio_channel_get_all_cb(struct device *dev,49					     int (*cb)(const void *data,50						       void *private),51					     void *private)52{53	int ret;54	struct iio_cb_buffer *cb_buff;55	struct iio_channel *chan;56 57	if (!cb) {58		dev_err(dev, "Invalid arguments: A callback must be provided!\n");59		return ERR_PTR(-EINVAL);60	}61 62	cb_buff = kzalloc(sizeof(*cb_buff), GFP_KERNEL);63	if (cb_buff == NULL)64		return ERR_PTR(-ENOMEM);65 66	iio_buffer_init(&cb_buff->buffer);67 68	cb_buff->private = private;69	cb_buff->cb = cb;70	cb_buff->buffer.access = &iio_cb_access;71	INIT_LIST_HEAD(&cb_buff->buffer.demux_list);72 73	cb_buff->channels = iio_channel_get_all(dev);74	if (IS_ERR(cb_buff->channels)) {75		ret = PTR_ERR(cb_buff->channels);76		goto error_free_cb_buff;77	}78 79	cb_buff->indio_dev = cb_buff->channels[0].indio_dev;80	cb_buff->buffer.scan_mask = bitmap_zalloc(iio_get_masklength(cb_buff->indio_dev),81						  GFP_KERNEL);82	if (cb_buff->buffer.scan_mask == NULL) {83		ret = -ENOMEM;84		goto error_release_channels;85	}86	chan = &cb_buff->channels[0];87	while (chan->indio_dev) {88		if (chan->indio_dev != cb_buff->indio_dev) {89			ret = -EINVAL;90			goto error_free_scan_mask;91		}92		set_bit(chan->channel->scan_index,93			cb_buff->buffer.scan_mask);94		chan++;95	}96 97	return cb_buff;98 99error_free_scan_mask:100	bitmap_free(cb_buff->buffer.scan_mask);101error_release_channels:102	iio_channel_release_all(cb_buff->channels);103error_free_cb_buff:104	kfree(cb_buff);105	return ERR_PTR(ret);106}107EXPORT_SYMBOL_GPL(iio_channel_get_all_cb);108 109int iio_channel_cb_set_buffer_watermark(struct iio_cb_buffer *cb_buff,110					size_t watermark)111{112	if (!watermark)113		return -EINVAL;114	cb_buff->buffer.watermark = watermark;115 116	return 0;117}118EXPORT_SYMBOL_GPL(iio_channel_cb_set_buffer_watermark);119 120int iio_channel_start_all_cb(struct iio_cb_buffer *cb_buff)121{122	return iio_update_buffers(cb_buff->indio_dev, &cb_buff->buffer,123				  NULL);124}125EXPORT_SYMBOL_GPL(iio_channel_start_all_cb);126 127void iio_channel_stop_all_cb(struct iio_cb_buffer *cb_buff)128{129	iio_update_buffers(cb_buff->indio_dev, NULL, &cb_buff->buffer);130}131EXPORT_SYMBOL_GPL(iio_channel_stop_all_cb);132 133void iio_channel_release_all_cb(struct iio_cb_buffer *cb_buff)134{135	iio_channel_release_all(cb_buff->channels);136	iio_buffer_put(&cb_buff->buffer);137}138EXPORT_SYMBOL_GPL(iio_channel_release_all_cb);139 140struct iio_channel141*iio_channel_cb_get_channels(const struct iio_cb_buffer *cb_buffer)142{143	return cb_buffer->channels;144}145EXPORT_SYMBOL_GPL(iio_channel_cb_get_channels);146 147struct iio_dev148*iio_channel_cb_get_iio_dev(const struct iio_cb_buffer *cb_buffer)149{150	return cb_buffer->indio_dev;151}152EXPORT_SYMBOL_GPL(iio_channel_cb_get_iio_dev);153 154MODULE_AUTHOR("Jonathan Cameron <jic23@kernel.org>");155MODULE_DESCRIPTION("Industrial I/O callback buffer");156MODULE_LICENSE("GPL");157