blob: ea01d3f3ce977d65fa8f8a7d70c9296143c6390d [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,
10 size_t length)
11{
12 unsigned int i;
13 struct iio_buffer *buf = malloc(sizeof(*buf));
14 if (!buf)
15 return NULL;
16
17 buf->data_length = 0;
18 buf->length = length;
19 buf->dev = dev;
20 buf->words = (dev->nb_channels + 31) / 32;
21 buf->mask = calloc(buf->words, sizeof(*buf->mask));
22 if (!buf->mask)
23 goto err_free_buf;
24 buf->open_mask = calloc(buf->words, sizeof(*buf->open_mask));
25 if (!buf->open_mask)
26 goto err_free_mask;
27
28 for (i = 0; i < dev->nb_channels; i++) {
29 struct iio_channel *chn = dev->channels[i];
30 if (iio_channel_is_enabled(chn) && chn->index >= 0)
31 SET_BIT(buf->open_mask, chn->index);
32 }
33
34 buf->sample_size = iio_device_get_sample_size(dev,
35 buf->open_mask, buf->words);
36
37 buf->buffer = malloc(length);
38 if (buf->buffer)
39 return buf;
40
41 free(buf->open_mask);
42err_free_mask:
43 free(buf->mask);
44err_free_buf:
45 free(buf);
46 return NULL;
47}
48
49void iio_buffer_destroy(struct iio_buffer *buffer)
50{
51 free(buffer->buffer);
52 free(buffer->open_mask);
53 free(buffer->mask);
54 free(buffer);
55}
56
57int iio_buffer_refill(struct iio_buffer *buffer)
58{
59 ssize_t read = iio_device_read_raw(buffer->dev,
60 buffer->buffer, buffer->length,
61 buffer->mask, buffer->words);
62 if (read < 0)
63 return (int) read;
64
65 buffer->data_length = read;
66 return 0;
67}
68
69static ssize_t callback_wrapper(const struct iio_channel *chn,
70 void *buf, void *d)
71{
72 struct callback_wrapper_data *data = d;
73 if (chn->index >= 0 && TEST_BIT(data->mask, chn->index))
74 return data->callback(chn, buf,
75 chn->format.length / 8, data->data);
76 else
77 return 0;
78}
79
80ssize_t iio_buffer_foreach_sample(struct iio_buffer *buffer,
81 ssize_t (*callback)(const struct iio_channel *,
82 void *, size_t, void *), void *d)
83{
84 struct callback_wrapper_data data = {
85 .callback = callback,
86 .data = d,
87 .mask = buffer->open_mask,
88 };
89
90 if (buffer->data_length < buffer->sample_size)
91 return 0;
92
93 return iio_device_process_samples(buffer->dev,
94 buffer->mask, buffer->words, buffer->buffer,
95 buffer->data_length, callback_wrapper, &data);
96}
Paul Cercueil95347b92014-03-21 09:50:17 +010097
98void * iio_buffer_first(const struct iio_buffer *buffer,
99 const struct iio_channel *chn)
100{
101 size_t len;
102 unsigned int i;
103 void *ptr = buffer->buffer;
104
105 if (chn->index < 0 || !TEST_BIT(buffer->open_mask, chn->index))
106 return iio_buffer_end(buffer);
107
108 for (i = 0; i < buffer->dev->nb_channels; i++) {
109 struct iio_channel *cur = buffer->dev->channels[i];
110 len = cur->format.length / 8;
111
112 /* NOTE: dev->channels are ordered by index */
113 if (cur->index < 0 || cur->index == chn->index)
114 break;
115
116 if ((uintptr_t) ptr % len)
117 ptr += len - ((uintptr_t) ptr % len);
118 ptr += len;
119 }
120
121 len = chn->format.length / 8;
122 if ((uintptr_t) ptr % len)
123 ptr += len - ((uintptr_t) ptr % len);
124 return ptr;
125}
126
127ptrdiff_t iio_buffer_step(const struct iio_buffer *buffer,
128 const struct iio_channel *chn)
129{
130 return (ptrdiff_t) iio_device_get_sample_size(buffer->dev,
131 buffer->mask, buffer->words);
132}
133
134void * iio_buffer_end(const struct iio_buffer *buffer)
135{
136 return buffer->buffer + buffer->data_length;
137}