|
10 | 10 | #include "iio-private.h" |
11 | 11 | #include "sort.h" |
12 | 12 |
|
| 13 | +#include <asm-generic/errno-base.h> |
13 | 14 | #include <iio/iio-debug.h> |
14 | 15 | #include <inttypes.h> |
15 | 16 | #include <errno.h> |
@@ -93,6 +94,42 @@ ssize_t iio_snprintf_device_xml(char *ptr, ssize_t len, |
93 | 94 | } |
94 | 95 | } |
95 | 96 |
|
| 97 | + for (i = 0; i < dev->nb_buffers; i++) { |
| 98 | + const struct iio_buffer_meta *buf = &dev->buffers[i]; |
| 99 | + unsigned int j; |
| 100 | + |
| 101 | + ret = iio_snprintf(ptr, len, "<buffer index=\"%u\" >", i); |
| 102 | + if (ret < 0) |
| 103 | + return ret; |
| 104 | + |
| 105 | + iio_update_xml_indexes(ret, &ptr, &len, &alen); |
| 106 | + |
| 107 | + for (j = 0; j < buf->attrlist.num; j++) { |
| 108 | + ret = iio_snprintf_xml_attr(&buf->attrlist.attrs[j], ptr, len); |
| 109 | + if (ret < 0) |
| 110 | + return ret; |
| 111 | + |
| 112 | + iio_update_xml_indexes(ret, &ptr, &len, &alen); |
| 113 | + } |
| 114 | + |
| 115 | + for (j = 0; j < buf->nb_scan_elements; j++) { |
| 116 | + const struct iio_channel *scan = buf->scan_elements[j]; |
| 117 | + |
| 118 | + ret = iio_snprintf(ptr, len, "<channel id=\"%s\" type=\"%s\" />", |
| 119 | + scan->id, scan->is_output ? "output" : "input"); |
| 120 | + if (ret < 0) |
| 121 | + return ret; |
| 122 | + |
| 123 | + iio_update_xml_indexes(ret, &ptr, &len, &alen); |
| 124 | + } |
| 125 | + |
| 126 | + ret = iio_snprintf(ptr, len, "</buffer>"); |
| 127 | + if (ret < 0) |
| 128 | + return ret; |
| 129 | + |
| 130 | + iio_update_xml_indexes(ret, &ptr, &len, &alen); |
| 131 | + } |
| 132 | + |
96 | 133 | ret = iio_snprintf(ptr, len, "</device>"); |
97 | 134 | if (ret < 0) |
98 | 135 | return ret; |
@@ -120,6 +157,33 @@ unsigned int iio_device_get_channels_count(const struct iio_device *dev) |
120 | 157 | return dev->nb_channels; |
121 | 158 | } |
122 | 159 |
|
| 160 | +unsigned int iio_device_get_buffers_count(const struct iio_device *dev) |
| 161 | +{ |
| 162 | + return dev->nb_buffers; |
| 163 | +} |
| 164 | + |
| 165 | +int iio_device_get_buffer_scans_count(const struct iio_device *dev, |
| 166 | + unsigned int buffer_idx, unsigned int *nb_scans) |
| 167 | +{ |
| 168 | + if (buffer_idx >= dev->nb_buffers) |
| 169 | + return -EINVAL; |
| 170 | + |
| 171 | + *nb_scans = dev->buffers[buffer_idx].nb_scan_elements; |
| 172 | + return 0; |
| 173 | +} |
| 174 | + |
| 175 | +const struct iio_channel * |
| 176 | +iio_device_get_buffer_scan_element(const struct iio_device *dev, |
| 177 | + unsigned int buffer_idx, unsigned int scan_idx) |
| 178 | +{ |
| 179 | + if (buffer_idx >= dev->nb_buffers) |
| 180 | + return iio_ptr(-ENOENT); |
| 181 | + if (scan_idx >= dev->buffers[buffer_idx].nb_scan_elements) |
| 182 | + return iio_ptr(-ENOENT); |
| 183 | + |
| 184 | + return dev->buffers[buffer_idx].scan_elements[scan_idx]; |
| 185 | +} |
| 186 | + |
123 | 187 | struct iio_channel * iio_device_get_channel(const struct iio_device *dev, |
124 | 188 | unsigned int index) |
125 | 189 | { |
@@ -244,6 +308,13 @@ void free_device(struct iio_device *dev) |
244 | 308 | for (type = IIO_ATTR_TYPE_DEVICE; type <= IIO_ATTR_TYPE_BUFFER; type++) |
245 | 309 | iio_free_attrs(&dev->attrlist[type]); |
246 | 310 |
|
| 311 | + /* Free multi-buffer metadata */ |
| 312 | + for (i = 0; i < dev->nb_buffers; i++) { |
| 313 | + iio_free_attrs(&dev->buffers[i].attrlist); |
| 314 | + free(dev->buffers[i].scan_elements); |
| 315 | + } |
| 316 | + free(dev->buffers); |
| 317 | + |
247 | 318 | for (i = 0; i < dev->nb_channels; i++) |
248 | 319 | free_channel(dev->channels[i]); |
249 | 320 | free(dev->channels); |
@@ -354,6 +425,65 @@ void iio_device_set_pdata(struct iio_device *dev, struct iio_device_pdata *d) |
354 | 425 | dev->pdata = d; |
355 | 426 | } |
356 | 427 |
|
| 428 | +int iio_device_add_scan_element_to_buffer(struct iio_device *dev, struct iio_channel *chn, |
| 429 | + unsigned int buf_idx) |
| 430 | +{ |
| 431 | + struct iio_buffer_meta *buf; |
| 432 | + struct iio_channel **scans; |
| 433 | + unsigned int i; |
| 434 | + |
| 435 | + if (buf_idx >= dev->nb_buffers) |
| 436 | + return -EINVAL; |
| 437 | + if (!chn->is_scan_element) |
| 438 | + return -EINVAL; |
| 439 | + |
| 440 | + buf = &dev->buffers[buf_idx]; |
| 441 | + printf("Add scan element %s to buffer %u. Existing(%u)\n", chn->id, buf_idx, |
| 442 | + buf->nb_scan_elements); |
| 443 | + /* Check if the scan element is already in the buffer */ |
| 444 | + for (i = 0; i < buf->nb_scan_elements; i++) { |
| 445 | + if (buf->scan_elements[i] == chn) |
| 446 | + return -EEXIST; |
| 447 | + } |
| 448 | + |
| 449 | + scans = realloc(buf->scan_elements, |
| 450 | + (buf->nb_scan_elements + 1) * sizeof(*buf->scan_elements)); |
| 451 | + if (!scans) |
| 452 | + return -ENOMEM; |
| 453 | + |
| 454 | + buf->scan_elements = scans; |
| 455 | + buf->scan_elements[buf->nb_scan_elements++] = chn; |
| 456 | + |
| 457 | + return 0; |
| 458 | +} |
| 459 | + |
| 460 | +int iio_device_add_buffer(struct iio_device *dev, unsigned int buf_idx) |
| 461 | +{ |
| 462 | + struct iio_buffer_meta *buf, *bufs; |
| 463 | + |
| 464 | + /* This assumes buffers are added in order */ |
| 465 | + if (buf_idx != dev->nb_buffers) { |
| 466 | + dev_err(dev, "Invalid index(%u) for buffer. Expected %u\n", |
| 467 | + buf_idx, dev->nb_buffers); |
| 468 | + return -EINVAL; |
| 469 | + } |
| 470 | + |
| 471 | + buf = zalloc(sizeof(*buf)); |
| 472 | + if (!buf) |
| 473 | + return -ENOMEM; |
| 474 | + |
| 475 | + bufs = realloc(dev->buffers, (buf_idx + 1) * sizeof(*dev->buffers)); |
| 476 | + if (!bufs) { |
| 477 | + free(buf); |
| 478 | + return -ENOMEM; |
| 479 | + } |
| 480 | + |
| 481 | + bufs[dev->nb_buffers++] = *buf; |
| 482 | + dev->buffers = bufs; |
| 483 | + |
| 484 | + return 0; |
| 485 | +} |
| 486 | + |
357 | 487 | struct iio_channel * iio_device_add_channel(struct iio_device *dev, long index, |
358 | 488 | const char *id, const char *name, const char *label, |
359 | 489 | bool output, bool scan_element, |
|
0 commit comments