diff options
Diffstat (limited to 'device.c')
-rw-r--r-- | device.c | 1151 |
1 files changed, 0 insertions, 1151 deletions
diff --git a/device.c b/device.c deleted file mode 100644 index d3ec781..0000000 --- a/device.c +++ /dev/null @@ -1,1151 +0,0 @@ -/* - * libiio - Library for interfacing industrial I/O (IIO) devices - * - * Copyright (C) 2014 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 "debug.h" -#include "iio-private.h" - -#include <inttypes.h> -#include <errno.h> -#include <stdio.h> -#include <string.h> - -static char *get_attr_xml(const char *attr, size_t *length, enum iio_attr_type type) -{ - size_t len = sizeof("<attribute name=\"\" />") + strlen(attr); - char *str; - - switch(type){ - case IIO_ATTR_TYPE_DEVICE: - break; - case IIO_ATTR_TYPE_DEBUG: - len += (sizeof("debug-") - 1); - break; - case IIO_ATTR_TYPE_BUFFER: - len += (sizeof("buffer-") - 1); - break; - default: - return NULL; - } - - str = malloc(len); - if (!str) - return NULL; - - *length = len - 1; /* Skip the \0 */ - switch (type) { - case IIO_ATTR_TYPE_DEVICE: - iio_snprintf(str, len, "<attribute name=\"%s\" />", attr); - break; - case IIO_ATTR_TYPE_DEBUG: - iio_snprintf(str, len, "<debug-attribute name=\"%s\" />", attr); - break; - case IIO_ATTR_TYPE_BUFFER: - iio_snprintf(str, len, "<buffer-attribute name=\"%s\" />", attr); - break; - } - - return str; -} - -/* Returns a string containing the XML representation of this device */ -char * iio_device_get_xml(const struct iio_device *dev, size_t *length) -{ - size_t len = sizeof("<device id=\"\" name=\"\" ></device>") - + strlen(dev->id) + (dev->name ? strlen(dev->name) : 0); - char *ptr, *str, **attrs, **channels, **buffer_attrs, **debug_attrs; - size_t *attrs_len, *channels_len, *buffer_attrs_len, *debug_attrs_len; - unsigned int i, j, k; - - attrs_len = malloc(dev->nb_attrs * sizeof(*attrs_len)); - if (!attrs_len) - return NULL; - - attrs = malloc(dev->nb_attrs * sizeof(*attrs)); - if (!attrs) - goto err_free_attrs_len; - - for (i = 0; i < dev->nb_attrs; i++) { - char *xml = get_attr_xml(dev->attrs[i], &attrs_len[i], IIO_ATTR_TYPE_DEVICE); - if (!xml) - goto err_free_attrs; - attrs[i] = xml; - len += attrs_len[i]; - } - - channels_len = malloc(dev->nb_channels * sizeof(*channels_len)); - if (!channels_len) - goto err_free_attrs; - - channels = malloc(dev->nb_channels * sizeof(*channels)); - if (!channels) - goto err_free_channels_len; - - for (j = 0; j < dev->nb_channels; j++) { - char *xml = iio_channel_get_xml(dev->channels[j], - &channels_len[j]); - if (!xml) - goto err_free_channels; - channels[j] = xml; - len += channels_len[j]; - } - - buffer_attrs_len = malloc(dev->nb_buffer_attrs * - sizeof(*buffer_attrs_len)); - if (!buffer_attrs_len) - goto err_free_channels; - - buffer_attrs = malloc(dev->nb_buffer_attrs * sizeof(*buffer_attrs)); - if (!buffer_attrs) - goto err_free_buffer_attrs_len; - - for (k = 0; k < dev->nb_buffer_attrs; k++) { - char *xml = get_attr_xml(dev->buffer_attrs[k], - &buffer_attrs_len[k], IIO_ATTR_TYPE_BUFFER); - if (!xml) - goto err_free_buffer_attrs; - buffer_attrs[k] = xml; - len += buffer_attrs_len[k]; - } - - debug_attrs_len = malloc(dev->nb_debug_attrs * - sizeof(*debug_attrs_len)); - if (!debug_attrs_len) - goto err_free_buffer_attrs; - - debug_attrs = malloc(dev->nb_debug_attrs * sizeof(*debug_attrs)); - if (!debug_attrs) - goto err_free_debug_attrs_len; - - for (k = 0; k < dev->nb_debug_attrs; k++) { - char *xml = get_attr_xml(dev->debug_attrs[k], - &debug_attrs_len[k], IIO_ATTR_TYPE_DEBUG); - if (!xml) - goto err_free_debug_attrs; - debug_attrs[k] = xml; - len += debug_attrs_len[k]; - } - - str = malloc(len); - if (!str) - goto err_free_debug_attrs; - - iio_snprintf(str, len, "<device id=\"%s\"", dev->id); - ptr = strrchr(str, '\0'); - - if (dev->name) { - sprintf(ptr, " name=\"%s\"", dev->name); - ptr = strrchr(ptr, '\0'); - } - - strcpy(ptr, " >"); - ptr += 2; - - for (i = 0; i < dev->nb_channels; i++) { - strcpy(ptr, channels[i]); - ptr += channels_len[i]; - free(channels[i]); - } - - free(channels); - free(channels_len); - - for (i = 0; i < dev->nb_attrs; i++) { - strcpy(ptr, attrs[i]); - ptr += attrs_len[i]; - free(attrs[i]); - } - - free(attrs); - free(attrs_len); - - for (i = 0; i < dev->nb_buffer_attrs; i++) { - strcpy(ptr, buffer_attrs[i]); - ptr += buffer_attrs_len[i]; - free(buffer_attrs[i]); - } - - free(buffer_attrs); - free(buffer_attrs_len); - - for (i = 0; i < dev->nb_debug_attrs; i++) { - strcpy(ptr, debug_attrs[i]); - ptr += debug_attrs_len[i]; - free(debug_attrs[i]); - } - - free(debug_attrs); - free(debug_attrs_len); - - strcpy(ptr, "</device>"); - *length = ptr - str + sizeof("</device>") - 1; - return str; - -err_free_debug_attrs: - while (k--) - free(debug_attrs[k]); - free(debug_attrs); -err_free_debug_attrs_len: - free(debug_attrs_len); -err_free_buffer_attrs: - while (k--) - free(buffer_attrs[k]); - free(buffer_attrs); -err_free_buffer_attrs_len: - free(buffer_attrs_len); -err_free_channels: - while (j--) - free(channels[j]); - free(channels); -err_free_channels_len: - free(channels_len); -err_free_attrs: - while (i--) - free(attrs[i]); - free(attrs); -err_free_attrs_len: - free(attrs_len); - return NULL; -} - -const char * iio_device_get_id(const struct iio_device *dev) -{ - return dev->id; -} - -const char * iio_device_get_name(const struct iio_device *dev) -{ - return dev->name; -} - -unsigned int iio_device_get_channels_count(const struct iio_device *dev) -{ - return dev->nb_channels; -} - -struct iio_channel * iio_device_get_channel(const struct iio_device *dev, - unsigned int index) -{ - if (index >= dev->nb_channels) - return NULL; - else - return dev->channels[index]; -} - -struct iio_channel * iio_device_find_channel(const struct iio_device *dev, - const char *name, bool output) -{ - unsigned int i; - for (i = 0; i < dev->nb_channels; i++) { - struct iio_channel *chn = dev->channels[i]; - if (iio_channel_is_output(chn) != output) - continue; - - if (!strcmp(chn->id, name) || - (chn->name && !strcmp(chn->name, name))) - return chn; - } - return NULL; -} - -unsigned int iio_device_get_attrs_count(const struct iio_device *dev) -{ - return dev->nb_attrs; -} - -const char * iio_device_get_attr(const struct iio_device *dev, - unsigned int index) -{ - if (index >= dev->nb_attrs) - return NULL; - else - return dev->attrs[index]; -} - -const char * iio_device_find_attr(const struct iio_device *dev, - const char *name) -{ - unsigned int i; - for (i = 0; i < dev->nb_attrs; i++) { - const char *attr = dev->attrs[i]; - if (!strcmp(attr, name)) - return attr; - } - return NULL; -} - -unsigned int iio_device_get_buffer_attrs_count(const struct iio_device *dev) -{ - return dev->nb_buffer_attrs; -} - -const char * iio_device_get_buffer_attr(const struct iio_device *dev, - unsigned int index) -{ - if (index >= dev->nb_buffer_attrs) - return NULL; - else - return dev->buffer_attrs[index]; -} - -const char * iio_device_find_buffer_attr(const struct iio_device *dev, - const char *name) -{ - unsigned int i; - for (i = 0; i < dev->nb_buffer_attrs; i++) { - const char *attr = dev->buffer_attrs[i]; - if (!strcmp(attr, name)) - return attr; - } - return NULL; -} - -const char * iio_device_find_debug_attr(const struct iio_device *dev, - const char *name) -{ - unsigned int i; - for (i = 0; i < dev->nb_debug_attrs; i++) { - const char *attr = dev->debug_attrs[i]; - if (!strcmp(attr, name)) - return attr; - } - return NULL; -} - -bool iio_device_is_tx(const struct iio_device *dev) -{ - unsigned int i; - - for (i = 0; i < dev->nb_channels; i++) { - struct iio_channel *ch = dev->channels[i]; - if (iio_channel_is_output(ch) && iio_channel_is_enabled(ch)) - return true; - } - - return false; -} - -int iio_device_open(const struct iio_device *dev, - size_t samples_count, bool cyclic) -{ - unsigned int i; - bool has_channels = false; - - for (i = 0; !has_channels && i < dev->words; i++) - has_channels = !!dev->mask[i]; - if (!has_channels) - return -EINVAL; - - if (dev->ctx->ops->open) - return dev->ctx->ops->open(dev, samples_count, cyclic); - else - return -ENOSYS; -} - -int iio_device_close(const struct iio_device *dev) -{ - if (dev->ctx->ops->close) - return dev->ctx->ops->close(dev); - else - return -ENOSYS; -} - -int iio_device_get_poll_fd(const struct iio_device *dev) -{ - if (dev->ctx->ops->get_fd) - return dev->ctx->ops->get_fd(dev); - else - return -ENOSYS; -} - -int iio_device_set_blocking_mode(const struct iio_device *dev, bool blocking) -{ - if (dev->ctx->ops->set_blocking_mode) - return dev->ctx->ops->set_blocking_mode(dev, blocking); - else - return -ENOSYS; -} - -ssize_t iio_device_read_raw(const struct iio_device *dev, - void *dst, size_t len, uint32_t *mask, size_t words) -{ - if (dev->ctx->ops->read) - return dev->ctx->ops->read(dev, dst, len, mask, words); - else - return -ENOSYS; -} - -ssize_t iio_device_write_raw(const struct iio_device *dev, - const void *src, size_t len) -{ - if (dev->ctx->ops->write) - return dev->ctx->ops->write(dev, src, len); - else - return -ENOSYS; -} - -ssize_t iio_device_attr_read(const struct iio_device *dev, - const char *attr, char *dst, size_t len) -{ - if (dev->ctx->ops->read_device_attr) - return dev->ctx->ops->read_device_attr(dev, - attr, dst, len, IIO_ATTR_TYPE_DEVICE); - else - return -ENOSYS; -} - -ssize_t iio_device_attr_write_raw(const struct iio_device *dev, - const char *attr, const void *src, size_t len) -{ - if (dev->ctx->ops->write_device_attr) - return dev->ctx->ops->write_device_attr(dev, - attr, src, len, IIO_ATTR_TYPE_DEVICE); - else - return -ENOSYS; -} - -ssize_t iio_device_attr_write(const struct iio_device *dev, - const char *attr, const char *src) -{ - return iio_device_attr_write_raw(dev, attr, src, strlen(src) + 1); -} - -ssize_t iio_device_buffer_attr_read(const struct iio_device *dev, - const char *attr, char *dst, size_t len) -{ - if (dev->ctx->ops->read_device_attr) - return dev->ctx->ops->read_device_attr(dev, - attr, dst, len, IIO_ATTR_TYPE_BUFFER); - else - return -ENOSYS; -} - -ssize_t iio_device_buffer_attr_write_raw(const struct iio_device *dev, - const char *attr, const void *src, size_t len) -{ - if (dev->ctx->ops->write_device_attr) - return dev->ctx->ops->write_device_attr(dev, - attr, src, len, IIO_ATTR_TYPE_BUFFER); - else - return -ENOSYS; -} - -ssize_t iio_device_buffer_attr_write(const struct iio_device *dev, - const char *attr, const char *src) -{ - return iio_device_buffer_attr_write_raw(dev, attr, src, strlen(src) + 1); -} - -void iio_device_set_data(struct iio_device *dev, void *data) -{ - dev->userdata = data; -} - -void * iio_device_get_data(const struct iio_device *dev) -{ - return dev->userdata; -} - -bool iio_device_is_trigger(const struct iio_device *dev) -{ - /* A trigger has a name, an id which starts by "trigger", - * and zero channels. */ - - unsigned int nb = iio_device_get_channels_count(dev); - const char *name = iio_device_get_name(dev), - *id = iio_device_get_id(dev); - return ((nb == 0) && !!name && - !strncmp(id, "trigger", sizeof("trigger") - 1)); -} - -int iio_device_set_kernel_buffers_count(const struct iio_device *dev, - unsigned int nb_buffers) -{ - if (nb_buffers == 0) - return -EINVAL; - else if (dev->ctx->ops->set_kernel_buffers_count) - return dev->ctx->ops->set_kernel_buffers_count(dev, nb_buffers); - else - return -ENOSYS; -} - -int iio_device_get_trigger(const struct iio_device *dev, - const struct iio_device **trigger) -{ - if (!trigger) - return -EINVAL; - else if (dev->ctx->ops->get_trigger) - return dev->ctx->ops->get_trigger(dev, trigger); - else - return -ENOSYS; -} - -int iio_device_set_trigger(const struct iio_device *dev, - const struct iio_device *trigger) -{ - if (trigger && !iio_device_is_trigger(trigger)) - return -EINVAL; - else if (dev->ctx->ops->set_trigger) - return dev->ctx->ops->set_trigger(dev, trigger); - else - return -ENOSYS; -} - -void free_device(struct iio_device *dev) -{ - unsigned int i; - for (i = 0; i < dev->nb_attrs; i++) - free(dev->attrs[i]); - if (dev->nb_attrs) - free(dev->attrs); - for (i = 0; i < dev->nb_buffer_attrs; i++) - free(dev->buffer_attrs[i]); - if (dev->nb_buffer_attrs) - free(dev->buffer_attrs); - for (i = 0; i < dev->nb_debug_attrs; i++) - free(dev->debug_attrs[i]); - if (dev->nb_debug_attrs) - free(dev->debug_attrs); - for (i = 0; i < dev->nb_channels; i++) - free_channel(dev->channels[i]); - if (dev->nb_channels) - free(dev->channels); - if (dev->mask) - free(dev->mask); - if (dev->name) - free(dev->name); - if (dev->id) - free(dev->id); - free(dev); -} - -ssize_t iio_device_get_sample_size_mask(const struct iio_device *dev, - const uint32_t *mask, size_t words) -{ - ssize_t size = 0; - unsigned int i; - const struct iio_channel *prev = NULL; - - if (words != (dev->nb_channels + 31) / 32) - return -EINVAL; - - for (i = 0; i < dev->nb_channels; i++) { - const struct iio_channel *chn = dev->channels[i]; - unsigned int length = chn->format.length / 8 * - chn->format.repeat; - - if (chn->index < 0) - break; - if (!TEST_BIT(mask, chn->number)) - continue; - - if (prev && chn->index == prev->index) { - prev = chn; - continue; - } - - if (size % length) - size += 2 * length - (size % length); - else - size += length; - - prev = chn; - } - return size; -} - -ssize_t iio_device_get_sample_size(const struct iio_device *dev) -{ - return iio_device_get_sample_size_mask(dev, dev->mask, dev->words); -} - -int iio_device_attr_read_longlong(const struct iio_device *dev, - const char *attr, long long *val) -{ - char *end, buf[1024]; - long long value; - ssize_t ret = iio_device_attr_read(dev, attr, buf, sizeof(buf)); - if (ret < 0) - return (int) ret; - - value = strtoll(buf, &end, 0); - if (end == buf) - return -EINVAL; - *val = value; - return 0; -} - -int iio_device_attr_read_bool(const struct iio_device *dev, - const char *attr, bool *val) -{ - long long value; - int ret = iio_device_attr_read_longlong(dev, attr, &value); - if (ret < 0) - return ret; - - *val = !!value; - return 0; -} - -int iio_device_attr_read_double(const struct iio_device *dev, - const char *attr, double *val) -{ - char buf[1024]; - ssize_t ret = iio_device_attr_read(dev, attr, buf, sizeof(buf)); - if (ret < 0) - return (int) ret; - else - return read_double(buf, val); -} - -int iio_device_attr_write_longlong(const struct iio_device *dev, - const char *attr, long long val) -{ - ssize_t ret; - char buf[1024]; - - iio_snprintf(buf, sizeof(buf), "%lld", val); - ret = iio_device_attr_write(dev, attr, buf); - - return ret < 0 ? ret : 0; -} - -int iio_device_attr_write_double(const struct iio_device *dev, - const char *attr, double val) -{ - ssize_t ret; - char buf[1024]; - - ret = (ssize_t) write_double(buf, sizeof(buf), val); - if (!ret) - ret = iio_device_attr_write(dev, attr, buf); - return ret < 0 ? ret : 0; -} - -int iio_device_attr_write_bool(const struct iio_device *dev, - const char *attr, bool val) -{ - ssize_t ret; - - if (val) - ret = iio_device_attr_write(dev, attr, "1"); - else - ret = iio_device_attr_write(dev, attr, "0"); - - return ret < 0 ? ret : 0; -} - -int iio_device_buffer_attr_read_longlong(const struct iio_device *dev, - const char *attr, long long *val) -{ - char *end, buf[1024]; - long long value; - ssize_t ret = iio_device_buffer_attr_read(dev, attr, buf, sizeof(buf)); - if (ret < 0) - return (int) ret; - - value = strtoll(buf, &end, 0); - if (end == buf) - return -EINVAL; - *val = value; - return 0; -} - -int iio_device_buffer_attr_read_bool(const struct iio_device *dev, - const char *attr, bool *val) -{ - long long value; - int ret = iio_device_buffer_attr_read_longlong(dev, attr, &value); - if (ret < 0) - return ret; - - *val = !!value; - return 0; -} - -int iio_device_buffer_attr_read_double(const struct iio_device *dev, - const char *attr, double *val) -{ - char buf[1024]; - ssize_t ret = iio_device_buffer_attr_read(dev, attr, buf, sizeof(buf)); - if (ret < 0) - return (int) ret; - else - return read_double(buf, val); -} - -int iio_device_buffer_attr_write_longlong(const struct iio_device *dev, - const char *attr, long long val) -{ - ssize_t ret; - char buf[1024]; - - iio_snprintf(buf, sizeof(buf), "%lld", val); - ret = iio_device_buffer_attr_write(dev, attr, buf); - - return ret < 0 ? ret : 0; -} - -int iio_device_buffer_attr_write_double(const struct iio_device *dev, - const char *attr, double val) -{ - ssize_t ret; - char buf[1024]; - - ret = (ssize_t) write_double(buf, sizeof(buf), val); - if (!ret) - ret = iio_device_buffer_attr_write(dev, attr, buf); - return ret < 0 ? ret : 0; -} - -int iio_device_buffer_attr_write_bool(const struct iio_device *dev, - const char *attr, bool val) -{ - ssize_t ret; - - if (val) - ret = iio_device_buffer_attr_write(dev, attr, "1"); - else - ret = iio_device_buffer_attr_write(dev, attr, "0"); - - return ret < 0 ? ret : 0; -} - -ssize_t iio_device_debug_attr_read(const struct iio_device *dev, - const char *attr, char *dst, size_t len) -{ - if (dev->ctx->ops->read_device_attr) - return dev->ctx->ops->read_device_attr(dev, - attr, dst, len, IIO_ATTR_TYPE_DEBUG); - else - return -ENOSYS; -} - -ssize_t iio_device_debug_attr_write_raw(const struct iio_device *dev, - const char *attr, const void *src, size_t len) -{ - if (dev->ctx->ops->write_device_attr) - return dev->ctx->ops->write_device_attr(dev, - attr, src, len, IIO_ATTR_TYPE_DEBUG); - else - return -ENOSYS; -} - -ssize_t iio_device_debug_attr_write(const struct iio_device *dev, - const char *attr, const char *src) -{ - return iio_device_debug_attr_write_raw(dev, attr, src, strlen(src) + 1); -} - -unsigned int iio_device_get_debug_attrs_count(const struct iio_device *dev) -{ - return dev->nb_debug_attrs; -} - -const char * iio_device_get_debug_attr(const struct iio_device *dev, - unsigned int index) -{ - if (index >= dev->nb_debug_attrs) - return NULL; - else - return dev->debug_attrs[index]; -} - -int iio_device_debug_attr_read_longlong(const struct iio_device *dev, - const char *attr, long long *val) -{ - char *end, buf[1024]; - long long value; - ssize_t ret = iio_device_debug_attr_read(dev, attr, buf, sizeof(buf)); - if (ret < 0) - return (int) ret; - - value = strtoll(buf, &end, 0); - if (end == buf) - return -EINVAL; - *val = value; - return 0; -} - -int iio_device_debug_attr_read_bool(const struct iio_device *dev, - const char *attr, bool *val) -{ - long long value; - int ret = iio_device_debug_attr_read_longlong(dev, attr, &value); - if (ret < 0) - return ret; - - *val = !!value; - return 0; -} - -int iio_device_debug_attr_read_double(const struct iio_device *dev, - const char *attr, double *val) -{ - char buf[1024]; - ssize_t ret = iio_device_debug_attr_read(dev, attr, buf, sizeof(buf)); - if (ret < 0) - return (int) ret; - else - return read_double(buf, val); -} - -int iio_device_debug_attr_write_longlong(const struct iio_device *dev, - const char *attr, long long val) -{ - ssize_t ret; - char buf[1024]; - - iio_snprintf(buf, sizeof(buf), "%lld", val); - ret = iio_device_debug_attr_write(dev, attr, buf); - - return ret < 0 ? ret : 0; -} - -int iio_device_debug_attr_write_double(const struct iio_device *dev, - const char *attr, double val) -{ - ssize_t ret; - char buf[1024]; - - ret = (ssize_t) write_double(buf, sizeof(buf), val); - if (!ret) - ret = iio_device_debug_attr_write(dev, attr, buf); - return ret < 0 ? ret : 0; -} - -int iio_device_debug_attr_write_bool(const struct iio_device *dev, - const char *attr, bool val) -{ - ssize_t ret; - - if (val) - ret = iio_device_debug_attr_write_raw(dev, attr, "1", 2); - else - ret = iio_device_debug_attr_write_raw(dev, attr, "0", 2); - - return ret < 0 ? ret : 0; -} - -int iio_device_identify_filename(const struct iio_device *dev, - const char *filename, struct iio_channel **chn, - const char **attr) -{ - unsigned int i; - - for (i = 0; i < dev->nb_channels; i++) { - struct iio_channel *ch = dev->channels[i]; - unsigned int j; - - for (j = 0; j < ch->nb_attrs; j++) { - if (!strcmp(ch->attrs[j].filename, filename)) { - *attr = ch->attrs[j].name; - *chn = ch; - return 0; - } - } - } - - for (i = 0; i < dev->nb_attrs; i++) { - /* Devices attributes are named after their filename */ - if (!strcmp(dev->attrs[i], filename)) { - *attr = dev->attrs[i]; - *chn = NULL; - return 0; - } - } - - for (i = 0; i < dev->nb_debug_attrs; i++) { - if (!strcmp(dev->debug_attrs[i], filename)) { - *attr = dev->debug_attrs[i]; - *chn = NULL; - return 0; - } - } - - return -EINVAL; -} - -int iio_device_reg_write(struct iio_device *dev, - uint32_t address, uint32_t value) -{ - ssize_t ret; - char buf[1024]; - - iio_snprintf(buf, sizeof(buf), "0x%" PRIx32 " 0x%" PRIx32, - address, value); - ret = iio_device_debug_attr_write(dev, "direct_reg_access", buf); - - return ret < 0 ? ret : 0; -} - -int iio_device_reg_read(struct iio_device *dev, - uint32_t address, uint32_t *value) -{ - /* NOTE: There is a race condition here. But it is extremely unlikely to - * happen, and as this is a debug function, it shouldn't be used for - * something else than debug. */ - - long long val; - int ret = iio_device_debug_attr_write_longlong(dev, - "direct_reg_access", (long long) address); - if (ret < 0) - return ret; - - ret = iio_device_debug_attr_read_longlong(dev, - "direct_reg_access", &val); - if (!ret) - *value = (uint32_t) val; - return ret; -} - -static int read_each_attr(struct iio_device *dev, enum iio_attr_type type, - int (*cb)(struct iio_device *dev, - const char *attr, const char *val, size_t len, void *d), - void *data) -{ - int ret, buf_size; - char *buf, *ptr; - unsigned int i, count; - - /* We need a big buffer here; 1 MiB should be enough */ - buf = malloc(0x100000); - if (!buf) - return -ENOMEM; - - switch(type){ - case IIO_ATTR_TYPE_DEVICE: - count = iio_device_get_attrs_count(dev); - ret = (int) iio_device_attr_read(dev, - NULL, buf, 0x100000); - break; - case IIO_ATTR_TYPE_DEBUG: - count = iio_device_get_debug_attrs_count(dev); - ret = (int) iio_device_debug_attr_read(dev, - NULL, buf, 0x100000); - break; - case IIO_ATTR_TYPE_BUFFER: - count = iio_device_get_buffer_attrs_count(dev); - ret = (int) iio_device_buffer_attr_read(dev, - NULL, buf, 0x100000); - break; - default: - ret = -EINVAL; - count = 0; - break; - } - - if (ret < 0) - goto err_free_buf; - - ptr = buf; - buf_size = ret; - - for (i = 0; i < count; i++) { - const char *attr; - int32_t len; - - if (buf_size < 4) { - ret = -EPROTO; - break; - } - - len = (int32_t) iio_be32toh(*(uint32_t *) ptr); - ptr += 4; - buf_size -= 4; - - if (len > 0 && buf_size < len) { - ret = -EPROTO; - break; - } - - switch(type){ - case IIO_ATTR_TYPE_DEVICE: - attr = iio_device_get_attr(dev, i); - break; - case IIO_ATTR_TYPE_DEBUG: - attr = iio_device_get_debug_attr(dev, i); - break; - case IIO_ATTR_TYPE_BUFFER: - attr = iio_device_get_buffer_attr(dev, i); - break; - default: - attr = NULL; - break; - } - - if (len > 0) { - ret = cb(dev, attr, ptr, (size_t) len, data); - if (ret < 0) - goto err_free_buf; - - if (len & 0x3) - len = ((len >> 2) + 1) << 2; - ptr += len; - if (len >= buf_size) - buf_size = 0; - else - buf_size -= len; - } - } - -err_free_buf: - free(buf); - return ret < 0 ? ret : 0; -} - -static int write_each_attr(struct iio_device *dev, enum iio_attr_type type, - ssize_t (*cb)(struct iio_device *dev, - const char *attr, void *buf, size_t len, void *d), - void *data) -{ - char *buf, *ptr; - unsigned int i, count; - size_t len = 0x100000; - int ret; - - /* We need a big buffer here; 1 MiB should be enough */ - buf = malloc(len); - if (!buf) - return -ENOMEM; - - ptr = buf; - - switch(type){ - case IIO_ATTR_TYPE_DEVICE: - count = iio_device_get_attrs_count(dev); - break; - case IIO_ATTR_TYPE_DEBUG: - count = iio_device_get_debug_attrs_count(dev); - break; - case IIO_ATTR_TYPE_BUFFER: - count = iio_device_get_buffer_attrs_count(dev); - break; - default: - ret = -EINVAL; - goto err_free_buf; - } - - for (i = 0; i < count; i++) { - const char *attr; - - switch(type){ - case IIO_ATTR_TYPE_DEVICE: - attr = iio_device_get_attr(dev, i); - break; - case IIO_ATTR_TYPE_DEBUG: - attr = iio_device_get_debug_attr(dev, i); - break; - case IIO_ATTR_TYPE_BUFFER: - attr = iio_device_get_buffer_attr(dev, i); - break; - default: - attr = NULL; - break; - } - - ret = (int) cb(dev, attr, ptr + 4, len - 4, data); - if (ret < 0) - goto err_free_buf; - - *(int32_t *) ptr = (int32_t) iio_htobe32((uint32_t) ret); - ptr += 4; - len -= 4; - - if (ret > 0) { - if (ret & 0x3) - ret = ((ret >> 2) + 1) << 2; - ptr += ret; - len -= ret; - } - } - - switch(type){ - case IIO_ATTR_TYPE_DEVICE: - ret = (int) iio_device_attr_write_raw(dev, - NULL, buf, ptr - buf); - break; - case IIO_ATTR_TYPE_DEBUG: - ret = (int) iio_device_debug_attr_write_raw(dev, - NULL, buf, ptr - buf); - break; - case IIO_ATTR_TYPE_BUFFER: - ret = (int) iio_device_buffer_attr_write_raw(dev, - NULL, buf, ptr - buf); - break; - default: - ret = -EINVAL; - break; - } - -err_free_buf: - free(buf); - return ret < 0 ? ret : 0; -} - -int iio_device_debug_attr_read_all(struct iio_device *dev, - int (*cb)(struct iio_device *dev, - const char *attr, const char *val, size_t len, void *d), - void *data) -{ - return read_each_attr(dev, IIO_ATTR_TYPE_DEBUG, cb, data); -} - -int iio_device_buffer_attr_read_all(struct iio_device *dev, - int (*cb)(struct iio_device *dev, - const char *attr, const char *val, size_t len, void *d), - void *data) -{ - return read_each_attr(dev, IIO_ATTR_TYPE_BUFFER, cb, data); -} - -int iio_device_attr_read_all(struct iio_device *dev, - int (*cb)(struct iio_device *dev, - const char *attr, const char *val, size_t len, void *d), - void *data) -{ - return read_each_attr(dev, IIO_ATTR_TYPE_DEVICE ,cb, data); -} - -int iio_device_debug_attr_write_all(struct iio_device *dev, - ssize_t (*cb)(struct iio_device *dev, - const char *attr, void *buf, size_t len, void *d), - void *data) -{ - return write_each_attr(dev, IIO_ATTR_TYPE_DEBUG, cb, data); -} - -int iio_device_buffer_attr_write_all(struct iio_device *dev, - ssize_t (*cb)(struct iio_device *dev, - const char *attr, void *buf, size_t len, void *d), - void *data) -{ - return write_each_attr(dev, IIO_ATTR_TYPE_BUFFER, cb, data); -} - -int iio_device_attr_write_all(struct iio_device *dev, - ssize_t (*cb)(struct iio_device *dev, - const char *attr, void *buf, size_t len, void *d), - void *data) -{ - return write_each_attr(dev, IIO_ATTR_TYPE_DEVICE, cb, data); -} - -const struct iio_context * iio_device_get_context(const struct iio_device *dev) -{ - return dev->ctx; -} |