1 /* The industrial I/O callback buffer
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.
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>
17 struct iio_cb_buffer
{
18 struct iio_buffer buffer
;
19 int (*cb
)(const void *data
, void *private);
21 struct iio_channel
*channels
;
22 struct iio_dev
*indio_dev
;
25 static struct iio_cb_buffer
*buffer_to_cb_buffer(struct iio_buffer
*buffer
)
27 return container_of(buffer
, struct iio_cb_buffer
, buffer
);
30 static int iio_buffer_cb_store_to(struct iio_buffer
*buffer
, const void *data
)
32 struct iio_cb_buffer
*cb_buff
= buffer_to_cb_buffer(buffer
);
33 return cb_buff
->cb(data
, cb_buff
->private);
36 static void iio_buffer_cb_release(struct iio_buffer
*buffer
)
38 struct iio_cb_buffer
*cb_buff
= buffer_to_cb_buffer(buffer
);
39 kfree(cb_buff
->buffer
.scan_mask
);
43 static const struct iio_buffer_access_funcs iio_cb_access
= {
44 .store_to
= &iio_buffer_cb_store_to
,
45 .release
= &iio_buffer_cb_release
,
47 .modes
= INDIO_BUFFER_SOFTWARE
| INDIO_BUFFER_TRIGGERED
,
50 struct iio_cb_buffer
*iio_channel_get_all_cb(struct device
*dev
,
51 int (*cb
)(const void *data
,
56 struct iio_cb_buffer
*cb_buff
;
57 struct iio_channel
*chan
;
59 cb_buff
= kzalloc(sizeof(*cb_buff
), GFP_KERNEL
);
61 return ERR_PTR(-ENOMEM
);
63 iio_buffer_init(&cb_buff
->buffer
);
65 cb_buff
->private = private;
67 cb_buff
->buffer
.access
= &iio_cb_access
;
68 INIT_LIST_HEAD(&cb_buff
->buffer
.demux_list
);
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
;
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
) {
82 goto error_release_channels
;
84 chan
= &cb_buff
->channels
[0];
85 while (chan
->indio_dev
) {
86 if (chan
->indio_dev
!= cb_buff
->indio_dev
) {
88 goto error_free_scan_mask
;
90 set_bit(chan
->channel
->scan_index
,
91 cb_buff
->buffer
.scan_mask
);
98 kfree(cb_buff
->buffer
.scan_mask
);
99 error_release_channels
:
100 iio_channel_release_all(cb_buff
->channels
);
105 EXPORT_SYMBOL_GPL(iio_channel_get_all_cb
);
107 int iio_channel_cb_set_buffer_watermark(struct iio_cb_buffer
*cb_buff
,
112 cb_buff
->buffer
.watermark
= watermark
;
116 EXPORT_SYMBOL_GPL(iio_channel_cb_set_buffer_watermark
);
118 int iio_channel_start_all_cb(struct iio_cb_buffer
*cb_buff
)
120 return iio_update_buffers(cb_buff
->indio_dev
, &cb_buff
->buffer
,
123 EXPORT_SYMBOL_GPL(iio_channel_start_all_cb
);
125 void iio_channel_stop_all_cb(struct iio_cb_buffer
*cb_buff
)
127 iio_update_buffers(cb_buff
->indio_dev
, NULL
, &cb_buff
->buffer
);
129 EXPORT_SYMBOL_GPL(iio_channel_stop_all_cb
);
131 void iio_channel_release_all_cb(struct iio_cb_buffer
*cb_buff
)
133 iio_channel_release_all(cb_buff
->channels
);
134 iio_buffer_put(&cb_buff
->buffer
);
136 EXPORT_SYMBOL_GPL(iio_channel_release_all_cb
);
139 *iio_channel_cb_get_channels(const struct iio_cb_buffer
*cb_buffer
)
141 return cb_buffer
->channels
;
143 EXPORT_SYMBOL_GPL(iio_channel_cb_get_channels
);
146 *iio_channel_cb_get_iio_dev(const struct iio_cb_buffer
*cb_buffer
)
148 return cb_buffer
->indio_dev
;
150 EXPORT_SYMBOL_GPL(iio_channel_cb_get_iio_dev
);
152 MODULE_AUTHOR("Jonathan Cameron <jic23@kernel.org>");
153 MODULE_DESCRIPTION("Industrial I/O callback buffer");
154 MODULE_LICENSE("GPL");