blob: 6d6d46a5dd09192fe86600664b553f1fc7d63498 [file] [log] [blame]
Paul Cercueila689cd92014-03-20 16:37:25 +01001#include "iio-private.h"
2
3struct callback_wrapper_data {
4 ssize_t (*callback)(const struct iio_channel *, void *, size_t, void *);
5 void *data;
6 uint32_t *mask;
7};
8
9struct iio_buffer * iio_device_create_buffer(const struct iio_device *dev,
Paul Cercueilf88f8852014-04-01 11:50:59 +020010 size_t samples_count)
Paul Cercueila689cd92014-03-20 16:37:25 +010011{
Paul Cercueila689cd92014-03-20 16:37:25 +010012 struct iio_buffer *buf = malloc(sizeof(*buf));
13 if (!buf)
14 return NULL;
15
16 buf->data_length = 0;
Paul Cercueilf88f8852014-04-01 11:50:59 +020017 buf->sample_size = iio_device_get_sample_size(dev);
18 buf->length = buf->sample_size * samples_count;
Paul Cercueila689cd92014-03-20 16:37:25 +010019 buf->dev = dev;
Paul Cercueil645ab972014-03-24 14:36:12 +010020 buf->mask = calloc(dev->words, sizeof(*buf->mask));
Paul Cercueila689cd92014-03-20 16:37:25 +010021 if (!buf->mask)
22 goto err_free_buf;
Paul Cercueila689cd92014-03-20 16:37:25 +010023
Paul Cercueilf88f8852014-04-01 11:50:59 +020024 buf->buffer = malloc(buf->length);
Paul Cercueila689cd92014-03-20 16:37:25 +010025 if (buf->buffer)
26 return buf;
27
Paul Cercueila689cd92014-03-20 16:37:25 +010028 free(buf->mask);
29err_free_buf:
30 free(buf);
31 return NULL;
32}
33
34void iio_buffer_destroy(struct iio_buffer *buffer)
35{
36 free(buffer->buffer);
Paul Cercueila689cd92014-03-20 16:37:25 +010037 free(buffer->mask);
38 free(buffer);
39}
40
41int iio_buffer_refill(struct iio_buffer *buffer)
42{
43 ssize_t read = iio_device_read_raw(buffer->dev,
44 buffer->buffer, buffer->length,
Paul Cercueil645ab972014-03-24 14:36:12 +010045 buffer->mask, buffer->dev->words);
Paul Cercueila689cd92014-03-20 16:37:25 +010046 if (read < 0)
47 return (int) read;
48
49 buffer->data_length = read;
50 return 0;
51}
52
53static ssize_t callback_wrapper(const struct iio_channel *chn,
54 void *buf, void *d)
55{
56 struct callback_wrapper_data *data = d;
57 if (chn->index >= 0 && TEST_BIT(data->mask, chn->index))
58 return data->callback(chn, buf,
59 chn->format.length / 8, data->data);
60 else
61 return 0;
62}
63
64ssize_t iio_buffer_foreach_sample(struct iio_buffer *buffer,
65 ssize_t (*callback)(const struct iio_channel *,
66 void *, size_t, void *), void *d)
67{
68 struct callback_wrapper_data data = {
69 .callback = callback,
70 .data = d,
Paul Cercueil645ab972014-03-24 14:36:12 +010071 .mask = buffer->dev->mask,
Paul Cercueila689cd92014-03-20 16:37:25 +010072 };
73
74 if (buffer->data_length < buffer->sample_size)
75 return 0;
76
77 return iio_device_process_samples(buffer->dev,
Paul Cercueil645ab972014-03-24 14:36:12 +010078 buffer->mask, buffer->dev->words, buffer->buffer,
Paul Cercueila689cd92014-03-20 16:37:25 +010079 buffer->data_length, callback_wrapper, &data);
80}
Paul Cercueil95347b92014-03-21 09:50:17 +010081
82void * iio_buffer_first(const struct iio_buffer *buffer,
83 const struct iio_channel *chn)
84{
85 size_t len;
86 unsigned int i;
87 void *ptr = buffer->buffer;
88
Paul Cercueil645ab972014-03-24 14:36:12 +010089 if (!iio_channel_is_enabled(chn))
Paul Cercueil95347b92014-03-21 09:50:17 +010090 return iio_buffer_end(buffer);
91
92 for (i = 0; i < buffer->dev->nb_channels; i++) {
93 struct iio_channel *cur = buffer->dev->channels[i];
94 len = cur->format.length / 8;
95
96 /* NOTE: dev->channels are ordered by index */
97 if (cur->index < 0 || cur->index == chn->index)
98 break;
99
100 if ((uintptr_t) ptr % len)
101 ptr += len - ((uintptr_t) ptr % len);
102 ptr += len;
103 }
104
105 len = chn->format.length / 8;
106 if ((uintptr_t) ptr % len)
107 ptr += len - ((uintptr_t) ptr % len);
108 return ptr;
109}
110
111ptrdiff_t iio_buffer_step(const struct iio_buffer *buffer,
112 const struct iio_channel *chn)
113{
Paul Cercueil645ab972014-03-24 14:36:12 +0100114 return (ptrdiff_t) iio_device_get_sample_size_mask(buffer->dev,
115 buffer->mask, buffer->dev->words);
Paul Cercueil95347b92014-03-21 09:50:17 +0100116}
117
118void * iio_buffer_end(const struct iio_buffer *buffer)
119{
120 return buffer->buffer + buffer->data_length;
121}