summaryrefslogtreecommitdiff
path: root/buffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'buffer.c')
-rw-r--r--buffer.c324
1 files changed, 0 insertions, 324 deletions
diff --git a/buffer.c b/buffer.c
deleted file mode 100644
index 91aeff6..0000000
--- a/buffer.c
+++ /dev/null
@@ -1,324 +0,0 @@
-/*
- * libiio - Library for interfacing industrial I/O (IIO) devices
- *
- * Copyright (C) 2014-2015 Analog Devices, Inc.
- * Author: Paul Cercueil <paul.cercueil@analog.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * */
-
-#include "iio-config.h"
-#include "iio-private.h"
-
-#include <errno.h>
-#include <string.h>
-
-struct callback_wrapper_data {
- ssize_t (*callback)(const struct iio_channel *, void *, size_t, void *);
- void *data;
- uint32_t *mask;
-};
-
-static bool device_is_high_speed(const struct iio_device *dev)
-{
- /* Little trick: We call the backend's get_buffer() function, which is
- * for now only implemented in the Local backend, with a NULL pointer.
- * It will return -ENOSYS if the device is not high speed, and either
- * -EBADF or -EINVAL otherwise. */
- const struct iio_backend_ops *ops = dev->ctx->ops;
- return !!ops->get_buffer &&
- (ops->get_buffer(dev, NULL, 0, NULL, 0) != -ENOSYS);
-}
-
-struct iio_buffer * iio_device_create_buffer(const struct iio_device *dev,
- size_t samples_count, bool cyclic)
-{
- int ret = -EINVAL;
- struct iio_buffer *buf;
- unsigned int sample_size = iio_device_get_sample_size(dev);
-
- if (!sample_size || !samples_count)
- goto err_set_errno;
-
- buf = malloc(sizeof(*buf));
- if (!buf) {
- ret = -ENOMEM;
- goto err_set_errno;
- }
-
- buf->dev_sample_size = sample_size;
- buf->length = sample_size * samples_count;
- buf->dev = dev;
- buf->mask = calloc(dev->words, sizeof(*buf->mask));
- if (!buf->mask) {
- ret = -ENOMEM;
- goto err_free_buf;
- }
-
- /* Set the default channel mask to the one used by the device.
- * While input buffers will erase this as soon as the refill function
- * is used, it is useful for output buffers, as it permits
- * iio_buffer_foreach_sample to be used. */
- memcpy(buf->mask, dev->mask, dev->words * sizeof(*buf->mask));
-
- ret = iio_device_open(dev, samples_count, cyclic);
- if (ret < 0)
- goto err_free_mask;
-
- buf->dev_is_high_speed = device_is_high_speed(dev);
- if (buf->dev_is_high_speed) {
- /* Dequeue the first buffer, so that buf->buffer is correctly
- * initialized */
- buf->buffer = NULL;
- if (iio_device_is_tx(dev)) {
- ret = dev->ctx->ops->get_buffer(dev, &buf->buffer,
- buf->length, buf->mask, dev->words);
- if (ret < 0)
- goto err_close_device;
- }
- } else {
- buf->buffer = malloc(buf->length);
- if (!buf->buffer) {
- ret = -ENOMEM;
- goto err_close_device;
- }
- }
-
- buf->sample_size = iio_device_get_sample_size_mask(dev,
- buf->mask, dev->words);
- buf->data_length = buf->length;
- return buf;
-
-err_close_device:
- iio_device_close(dev);
-err_free_mask:
- free(buf->mask);
-err_free_buf:
- free(buf);
-err_set_errno:
- errno = -ret;
- return NULL;
-}
-
-void iio_buffer_destroy(struct iio_buffer *buffer)
-{
- iio_device_close(buffer->dev);
- if (!buffer->dev_is_high_speed)
- free(buffer->buffer);
- free(buffer->mask);
- free(buffer);
-}
-
-int iio_buffer_get_poll_fd(struct iio_buffer *buffer)
-{
- return iio_device_get_poll_fd(buffer->dev);
-}
-
-int iio_buffer_set_blocking_mode(struct iio_buffer *buffer, bool blocking)
-{
- return iio_device_set_blocking_mode(buffer->dev, blocking);
-}
-
-ssize_t iio_buffer_refill(struct iio_buffer *buffer)
-{
- ssize_t read;
- const struct iio_device *dev = buffer->dev;
-
- if (buffer->dev_is_high_speed) {
- read = dev->ctx->ops->get_buffer(dev, &buffer->buffer,
- buffer->length, buffer->mask, dev->words);
- } else {
- read = iio_device_read_raw(dev, buffer->buffer, buffer->length,
- buffer->mask, dev->words);
- }
-
- if (read >= 0) {
- buffer->data_length = read;
- buffer->sample_size = iio_device_get_sample_size_mask(dev,
- buffer->mask, dev->words);
- }
- return read;
-}
-
-ssize_t iio_buffer_push(struct iio_buffer *buffer)
-{
- const struct iio_device *dev = buffer->dev;
- ssize_t ret;
-
- if (buffer->dev_is_high_speed) {
- void *buf;
- ret = dev->ctx->ops->get_buffer(dev, &buf,
- buffer->data_length, buffer->mask, dev->words);
- if (ret >= 0) {
- buffer->buffer = buf;
- ret = (ssize_t) buffer->data_length;
- }
- } else {
- void *ptr = buffer->buffer;
- size_t tmp_len;
-
- /* iio_device_write_raw doesn't guarantee that all bytes are
- * written */
- for (tmp_len = buffer->data_length; tmp_len; ) {
- ret = iio_device_write_raw(dev, ptr, tmp_len);
- if (ret < 0)
- goto out_reset_data_length;
-
- tmp_len -= ret;
- ptr = (void *) ((uintptr_t) ptr + ret);
- }
-
- ret = (ssize_t) buffer->data_length;
- }
-
-out_reset_data_length:
- buffer->data_length = buffer->length;
- return ret;
-}
-
-ssize_t iio_buffer_push_partial(struct iio_buffer *buffer, size_t samples_count)
-{
- size_t new_len = samples_count * buffer->dev_sample_size;
-
- if (new_len == 0 || new_len > buffer->length)
- return -EINVAL;
-
- buffer->data_length = new_len;
- return iio_buffer_push(buffer);
-}
-
-ssize_t iio_buffer_foreach_sample(struct iio_buffer *buffer,
- ssize_t (*callback)(const struct iio_channel *,
- void *, size_t, void *), void *d)
-{
- uintptr_t ptr = (uintptr_t) buffer->buffer,
- start = ptr,
- end = ptr + buffer->data_length;
- const struct iio_device *dev = buffer->dev;
- ssize_t processed = 0;
-
- if (buffer->sample_size == 0)
- return -EINVAL;
-
- if (buffer->data_length < buffer->dev_sample_size)
- return 0;
-
- while (end - ptr >= (size_t) buffer->sample_size) {
- unsigned int i;
-
- for (i = 0; i < dev->nb_channels; i++) {
- const struct iio_channel *chn = dev->channels[i];
- unsigned int length = chn->format.length / 8;
-
- if (chn->index < 0)
- break;
-
- /* Test if the buffer has samples for this channel */
- if (!TEST_BIT(buffer->mask, chn->number))
- continue;
-
- if ((ptr - start) % length)
- ptr += length - ((ptr - start) % length);
-
- /* Test if the client wants samples from this channel */
- if (TEST_BIT(dev->mask, chn->number)) {
- ssize_t ret = callback(chn,
- (void *) ptr, length, d);
- if (ret < 0)
- return ret;
- else
- processed += ret;
- }
-
- if (i == dev->nb_channels - 1 || dev->channels[
- i + 1]->index != chn->index)
- ptr += length * chn->format.repeat;
- }
- }
- return processed;
-}
-
-void * iio_buffer_start(const struct iio_buffer *buffer)
-{
- return buffer->buffer;
-}
-
-void * iio_buffer_first(const struct iio_buffer *buffer,
- const struct iio_channel *chn)
-{
- size_t len;
- unsigned int i;
- uintptr_t ptr = (uintptr_t) buffer->buffer,
- start = ptr;
-
- if (!iio_channel_is_enabled(chn))
- return iio_buffer_end(buffer);
-
- for (i = 0; i < buffer->dev->nb_channels; i++) {
- struct iio_channel *cur = buffer->dev->channels[i];
- len = cur->format.length / 8 * cur->format.repeat;
-
- /* NOTE: dev->channels are ordered by index */
- if (cur->index < 0 || cur->index == chn->index)
- break;
-
- /* Test if the buffer has samples for this channel */
- if (!TEST_BIT(buffer->mask, cur->number))
- continue;
-
- /* Two channels with the same index use the same samples */
- if (i > 0 && cur->index == buffer->dev->channels[i - 1]->index)
- continue;
-
- if ((ptr - start) % len)
- ptr += len - ((ptr - start) % len);
- ptr += len;
- }
-
- len = chn->format.length / 8;
- if ((ptr - start) % len)
- ptr += len - ((ptr - start) % len);
- return (void *) ptr;
-}
-
-ptrdiff_t iio_buffer_step(const struct iio_buffer *buffer)
-{
- return (ptrdiff_t) buffer->sample_size;
-}
-
-void * iio_buffer_end(const struct iio_buffer *buffer)
-{
- return (void *) ((uintptr_t) buffer->buffer + buffer->data_length);
-}
-
-void iio_buffer_set_data(struct iio_buffer *buf, void *data)
-{
- buf->userdata = data;
-}
-
-void * iio_buffer_get_data(const struct iio_buffer *buf)
-{
- return buf->userdata;
-}
-
-const struct iio_device * iio_buffer_get_device(const struct iio_buffer *buf)
-{
- return buf->dev;
-}
-
-void iio_buffer_cancel(struct iio_buffer *buf)
-{
- const struct iio_backend_ops *ops = buf->dev->ctx->ops;
-
- if (ops->cancel)
- ops->cancel(buf->dev);
-}