Paul Cercueil / libiio

Dependencies:   libserialport libxml2

Committer:
pcercuei
Date:
Mon Jan 30 13:00:39 2017 +0000
Revision:
3:d147beabba0e
Parent:
2:9eb0a9a1f958
Child:
4:ad69b39bf124
Update to libiio v0.9

Who changed what in which revision?

UserRevisionLine numberNew contents of line
pcercuei 0:df031b60ca29 1 /*
pcercuei 0:df031b60ca29 2 * libiio - Library for interfacing industrial I/O (IIO) devices
pcercuei 0:df031b60ca29 3 *
pcercuei 0:df031b60ca29 4 * Copyright (C) 2014 Analog Devices, Inc.
pcercuei 0:df031b60ca29 5 * Author: Paul Cercueil <paul.cercueil@analog.com>
pcercuei 0:df031b60ca29 6 *
pcercuei 0:df031b60ca29 7 * This library is free software; you can redistribute it and/or
pcercuei 0:df031b60ca29 8 * modify it under the terms of the GNU Lesser General Public
pcercuei 0:df031b60ca29 9 * License as published by the Free Software Foundation; either
pcercuei 0:df031b60ca29 10 * version 2.1 of the License, or (at your option) any later version.
pcercuei 0:df031b60ca29 11 *
pcercuei 0:df031b60ca29 12 * This library is distributed in the hope that it will be useful,
pcercuei 0:df031b60ca29 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
pcercuei 0:df031b60ca29 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
pcercuei 0:df031b60ca29 15 * Lesser General Public License for more details.
pcercuei 0:df031b60ca29 16 *
pcercuei 0:df031b60ca29 17 * */
pcercuei 0:df031b60ca29 18
pcercuei 0:df031b60ca29 19 #include "debug.h"
pcercuei 0:df031b60ca29 20 #include "iio-private.h"
pcercuei 0:df031b60ca29 21
pcercuei 0:df031b60ca29 22 #include <inttypes.h>
pcercuei 2:9eb0a9a1f958 23 #include <errno.h>
pcercuei 0:df031b60ca29 24 #include <stdio.h>
pcercuei 0:df031b60ca29 25 #include <string.h>
pcercuei 0:df031b60ca29 26
pcercuei 0:df031b60ca29 27 static char *get_attr_xml(const char *attr, size_t *length, bool is_debug)
pcercuei 0:df031b60ca29 28 {
pcercuei 0:df031b60ca29 29 size_t len = sizeof("<attribute name=\"\" />") + strlen(attr)
pcercuei 0:df031b60ca29 30 + (!is_debug ? 0 : sizeof("debug-") - 1);
pcercuei 0:df031b60ca29 31 char *str = malloc(len);
pcercuei 0:df031b60ca29 32 if (!str)
pcercuei 0:df031b60ca29 33 return NULL;
pcercuei 0:df031b60ca29 34
pcercuei 0:df031b60ca29 35 *length = len - 1; /* Skip the \0 */
pcercuei 0:df031b60ca29 36 if (is_debug)
pcercuei 3:d147beabba0e 37 iio_snprintf(str, len, "<debug-attribute name=\"%s\" />", attr);
pcercuei 0:df031b60ca29 38 else
pcercuei 3:d147beabba0e 39 iio_snprintf(str, len, "<attribute name=\"%s\" />", attr);
pcercuei 0:df031b60ca29 40 return str;
pcercuei 0:df031b60ca29 41 }
pcercuei 0:df031b60ca29 42
pcercuei 0:df031b60ca29 43 /* Returns a string containing the XML representation of this device */
pcercuei 0:df031b60ca29 44 char * iio_device_get_xml(const struct iio_device *dev, size_t *length)
pcercuei 0:df031b60ca29 45 {
pcercuei 0:df031b60ca29 46 size_t len = sizeof("<device id=\"\" name=\"\" ></device>")
pcercuei 0:df031b60ca29 47 + strlen(dev->id) + (dev->name ? strlen(dev->name) : 0);
pcercuei 0:df031b60ca29 48 char *ptr, *str, **attrs, **channels, **debug_attrs;
pcercuei 0:df031b60ca29 49 size_t *attrs_len, *channels_len, *debug_attrs_len;
pcercuei 0:df031b60ca29 50 unsigned int i, j, k;
pcercuei 0:df031b60ca29 51
pcercuei 0:df031b60ca29 52 attrs_len = malloc(dev->nb_attrs * sizeof(*attrs_len));
pcercuei 0:df031b60ca29 53 if (!attrs_len)
pcercuei 0:df031b60ca29 54 return NULL;
pcercuei 0:df031b60ca29 55
pcercuei 0:df031b60ca29 56 attrs = malloc(dev->nb_attrs * sizeof(*attrs));
pcercuei 0:df031b60ca29 57 if (!attrs)
pcercuei 0:df031b60ca29 58 goto err_free_attrs_len;
pcercuei 0:df031b60ca29 59
pcercuei 0:df031b60ca29 60 for (i = 0; i < dev->nb_attrs; i++) {
pcercuei 0:df031b60ca29 61 char *xml = get_attr_xml(dev->attrs[i], &attrs_len[i], false);
pcercuei 0:df031b60ca29 62 if (!xml)
pcercuei 0:df031b60ca29 63 goto err_free_attrs;
pcercuei 0:df031b60ca29 64 attrs[i] = xml;
pcercuei 0:df031b60ca29 65 len += attrs_len[i];
pcercuei 0:df031b60ca29 66 }
pcercuei 0:df031b60ca29 67
pcercuei 0:df031b60ca29 68 channels_len = malloc(dev->nb_channels * sizeof(*channels_len));
pcercuei 0:df031b60ca29 69 if (!channels_len)
pcercuei 0:df031b60ca29 70 goto err_free_attrs;
pcercuei 0:df031b60ca29 71
pcercuei 0:df031b60ca29 72 channels = malloc(dev->nb_channels * sizeof(*channels));
pcercuei 0:df031b60ca29 73 if (!channels)
pcercuei 0:df031b60ca29 74 goto err_free_channels_len;
pcercuei 0:df031b60ca29 75
pcercuei 0:df031b60ca29 76 for (j = 0; j < dev->nb_channels; j++) {
pcercuei 0:df031b60ca29 77 char *xml = iio_channel_get_xml(dev->channels[j],
pcercuei 0:df031b60ca29 78 &channels_len[j]);
pcercuei 0:df031b60ca29 79 if (!xml)
pcercuei 0:df031b60ca29 80 goto err_free_channels;
pcercuei 0:df031b60ca29 81 channels[j] = xml;
pcercuei 0:df031b60ca29 82 len += channels_len[j];
pcercuei 0:df031b60ca29 83 }
pcercuei 0:df031b60ca29 84
pcercuei 0:df031b60ca29 85 debug_attrs_len = malloc(dev->nb_debug_attrs *
pcercuei 0:df031b60ca29 86 sizeof(*debug_attrs_len));
pcercuei 0:df031b60ca29 87 if (!debug_attrs_len)
pcercuei 0:df031b60ca29 88 goto err_free_channels;
pcercuei 0:df031b60ca29 89
pcercuei 0:df031b60ca29 90 debug_attrs = malloc(dev->nb_debug_attrs * sizeof(*debug_attrs));
pcercuei 0:df031b60ca29 91 if (!debug_attrs)
pcercuei 0:df031b60ca29 92 goto err_free_debug_attrs_len;
pcercuei 0:df031b60ca29 93
pcercuei 0:df031b60ca29 94 for (k = 0; k < dev->nb_debug_attrs; k++) {
pcercuei 0:df031b60ca29 95 char *xml = get_attr_xml(dev->debug_attrs[k],
pcercuei 0:df031b60ca29 96 &debug_attrs_len[k], true);
pcercuei 0:df031b60ca29 97 if (!xml)
pcercuei 0:df031b60ca29 98 goto err_free_debug_attrs;
pcercuei 0:df031b60ca29 99 debug_attrs[k] = xml;
pcercuei 0:df031b60ca29 100 len += debug_attrs_len[k];
pcercuei 0:df031b60ca29 101 }
pcercuei 0:df031b60ca29 102
pcercuei 0:df031b60ca29 103 str = malloc(len);
pcercuei 0:df031b60ca29 104 if (!str)
pcercuei 0:df031b60ca29 105 goto err_free_debug_attrs;
pcercuei 0:df031b60ca29 106
pcercuei 3:d147beabba0e 107 iio_snprintf(str, len, "<device id=\"%s\"", dev->id);
pcercuei 0:df031b60ca29 108 ptr = strrchr(str, '\0');
pcercuei 0:df031b60ca29 109
pcercuei 0:df031b60ca29 110 if (dev->name) {
pcercuei 0:df031b60ca29 111 sprintf(ptr, " name=\"%s\"", dev->name);
pcercuei 0:df031b60ca29 112 ptr = strrchr(ptr, '\0');
pcercuei 0:df031b60ca29 113 }
pcercuei 0:df031b60ca29 114
pcercuei 0:df031b60ca29 115 strcpy(ptr, " >");
pcercuei 0:df031b60ca29 116 ptr += 2;
pcercuei 0:df031b60ca29 117
pcercuei 0:df031b60ca29 118 for (i = 0; i < dev->nb_channels; i++) {
pcercuei 0:df031b60ca29 119 strcpy(ptr, channels[i]);
pcercuei 0:df031b60ca29 120 ptr += channels_len[i];
pcercuei 0:df031b60ca29 121 free(channels[i]);
pcercuei 0:df031b60ca29 122 }
pcercuei 0:df031b60ca29 123
pcercuei 0:df031b60ca29 124 free(channels);
pcercuei 0:df031b60ca29 125 free(channels_len);
pcercuei 0:df031b60ca29 126
pcercuei 0:df031b60ca29 127 for (i = 0; i < dev->nb_attrs; i++) {
pcercuei 0:df031b60ca29 128 strcpy(ptr, attrs[i]);
pcercuei 0:df031b60ca29 129 ptr += attrs_len[i];
pcercuei 0:df031b60ca29 130 free(attrs[i]);
pcercuei 0:df031b60ca29 131 }
pcercuei 0:df031b60ca29 132
pcercuei 0:df031b60ca29 133 free(attrs);
pcercuei 0:df031b60ca29 134 free(attrs_len);
pcercuei 0:df031b60ca29 135
pcercuei 0:df031b60ca29 136 for (i = 0; i < dev->nb_debug_attrs; i++) {
pcercuei 0:df031b60ca29 137 strcpy(ptr, debug_attrs[i]);
pcercuei 0:df031b60ca29 138 ptr += debug_attrs_len[i];
pcercuei 0:df031b60ca29 139 free(debug_attrs[i]);
pcercuei 0:df031b60ca29 140 }
pcercuei 0:df031b60ca29 141
pcercuei 0:df031b60ca29 142 free(debug_attrs);
pcercuei 0:df031b60ca29 143 free(debug_attrs_len);
pcercuei 0:df031b60ca29 144
pcercuei 0:df031b60ca29 145 strcpy(ptr, "</device>");
pcercuei 0:df031b60ca29 146 *length = ptr - str + sizeof("</device>") - 1;
pcercuei 0:df031b60ca29 147 return str;
pcercuei 0:df031b60ca29 148
pcercuei 0:df031b60ca29 149 err_free_debug_attrs:
pcercuei 0:df031b60ca29 150 while (k--)
pcercuei 0:df031b60ca29 151 free(debug_attrs[k]);
pcercuei 0:df031b60ca29 152 free(debug_attrs);
pcercuei 0:df031b60ca29 153 err_free_debug_attrs_len:
pcercuei 0:df031b60ca29 154 free(debug_attrs_len);
pcercuei 0:df031b60ca29 155 err_free_channels:
pcercuei 0:df031b60ca29 156 while (j--)
pcercuei 0:df031b60ca29 157 free(channels[j]);
pcercuei 0:df031b60ca29 158 free(channels);
pcercuei 0:df031b60ca29 159 err_free_channels_len:
pcercuei 0:df031b60ca29 160 free(channels_len);
pcercuei 0:df031b60ca29 161 err_free_attrs:
pcercuei 0:df031b60ca29 162 while (i--)
pcercuei 0:df031b60ca29 163 free(attrs[i]);
pcercuei 0:df031b60ca29 164 free(attrs);
pcercuei 0:df031b60ca29 165 err_free_attrs_len:
pcercuei 0:df031b60ca29 166 free(attrs_len);
pcercuei 0:df031b60ca29 167 return NULL;
pcercuei 0:df031b60ca29 168 }
pcercuei 0:df031b60ca29 169
pcercuei 0:df031b60ca29 170 const char * iio_device_get_id(const struct iio_device *dev)
pcercuei 0:df031b60ca29 171 {
pcercuei 0:df031b60ca29 172 return dev->id;
pcercuei 0:df031b60ca29 173 }
pcercuei 0:df031b60ca29 174
pcercuei 0:df031b60ca29 175 const char * iio_device_get_name(const struct iio_device *dev)
pcercuei 0:df031b60ca29 176 {
pcercuei 0:df031b60ca29 177 return dev->name;
pcercuei 0:df031b60ca29 178 }
pcercuei 0:df031b60ca29 179
pcercuei 0:df031b60ca29 180 unsigned int iio_device_get_channels_count(const struct iio_device *dev)
pcercuei 0:df031b60ca29 181 {
pcercuei 0:df031b60ca29 182 return dev->nb_channels;
pcercuei 0:df031b60ca29 183 }
pcercuei 0:df031b60ca29 184
pcercuei 0:df031b60ca29 185 struct iio_channel * iio_device_get_channel(const struct iio_device *dev,
pcercuei 0:df031b60ca29 186 unsigned int index)
pcercuei 0:df031b60ca29 187 {
pcercuei 0:df031b60ca29 188 if (index >= dev->nb_channels)
pcercuei 0:df031b60ca29 189 return NULL;
pcercuei 0:df031b60ca29 190 else
pcercuei 0:df031b60ca29 191 return dev->channels[index];
pcercuei 0:df031b60ca29 192 }
pcercuei 0:df031b60ca29 193
pcercuei 0:df031b60ca29 194 struct iio_channel * iio_device_find_channel(const struct iio_device *dev,
pcercuei 0:df031b60ca29 195 const char *name, bool output)
pcercuei 0:df031b60ca29 196 {
pcercuei 0:df031b60ca29 197 unsigned int i;
pcercuei 0:df031b60ca29 198 for (i = 0; i < dev->nb_channels; i++) {
pcercuei 0:df031b60ca29 199 struct iio_channel *chn = dev->channels[i];
pcercuei 0:df031b60ca29 200 if (iio_channel_is_output(chn) != output)
pcercuei 0:df031b60ca29 201 continue;
pcercuei 0:df031b60ca29 202
pcercuei 0:df031b60ca29 203 if (!strcmp(chn->id, name) ||
pcercuei 0:df031b60ca29 204 (chn->name && !strcmp(chn->name, name)))
pcercuei 0:df031b60ca29 205 return chn;
pcercuei 0:df031b60ca29 206 }
pcercuei 0:df031b60ca29 207 return NULL;
pcercuei 0:df031b60ca29 208 }
pcercuei 0:df031b60ca29 209
pcercuei 0:df031b60ca29 210 unsigned int iio_device_get_attrs_count(const struct iio_device *dev)
pcercuei 0:df031b60ca29 211 {
pcercuei 0:df031b60ca29 212 return dev->nb_attrs;
pcercuei 0:df031b60ca29 213 }
pcercuei 0:df031b60ca29 214
pcercuei 0:df031b60ca29 215 const char * iio_device_get_attr(const struct iio_device *dev,
pcercuei 0:df031b60ca29 216 unsigned int index)
pcercuei 0:df031b60ca29 217 {
pcercuei 0:df031b60ca29 218 if (index >= dev->nb_attrs)
pcercuei 0:df031b60ca29 219 return NULL;
pcercuei 0:df031b60ca29 220 else
pcercuei 0:df031b60ca29 221 return dev->attrs[index];
pcercuei 0:df031b60ca29 222 }
pcercuei 0:df031b60ca29 223
pcercuei 0:df031b60ca29 224 const char * iio_device_find_attr(const struct iio_device *dev,
pcercuei 0:df031b60ca29 225 const char *name)
pcercuei 0:df031b60ca29 226 {
pcercuei 0:df031b60ca29 227 unsigned int i;
pcercuei 0:df031b60ca29 228 for (i = 0; i < dev->nb_attrs; i++) {
pcercuei 0:df031b60ca29 229 const char *attr = dev->attrs[i];
pcercuei 0:df031b60ca29 230 if (!strcmp(attr, name))
pcercuei 0:df031b60ca29 231 return attr;
pcercuei 0:df031b60ca29 232 }
pcercuei 0:df031b60ca29 233 return NULL;
pcercuei 0:df031b60ca29 234 }
pcercuei 0:df031b60ca29 235
pcercuei 0:df031b60ca29 236 const char * iio_device_find_debug_attr(const struct iio_device *dev,
pcercuei 0:df031b60ca29 237 const char *name)
pcercuei 0:df031b60ca29 238 {
pcercuei 0:df031b60ca29 239 unsigned int i;
pcercuei 0:df031b60ca29 240 for (i = 0; i < dev->nb_debug_attrs; i++) {
pcercuei 0:df031b60ca29 241 const char *attr = dev->debug_attrs[i];
pcercuei 0:df031b60ca29 242 if (!strcmp(attr, name))
pcercuei 0:df031b60ca29 243 return attr;
pcercuei 0:df031b60ca29 244 }
pcercuei 0:df031b60ca29 245 return NULL;
pcercuei 0:df031b60ca29 246 }
pcercuei 0:df031b60ca29 247
pcercuei 0:df031b60ca29 248 bool iio_device_is_tx(const struct iio_device *dev)
pcercuei 0:df031b60ca29 249 {
pcercuei 0:df031b60ca29 250 unsigned int i;
pcercuei 0:df031b60ca29 251
pcercuei 0:df031b60ca29 252 for (i = 0; i < dev->nb_channels; i++) {
pcercuei 0:df031b60ca29 253 struct iio_channel *ch = dev->channels[i];
pcercuei 0:df031b60ca29 254 if (iio_channel_is_output(ch) && iio_channel_is_enabled(ch))
pcercuei 0:df031b60ca29 255 return true;
pcercuei 0:df031b60ca29 256 }
pcercuei 0:df031b60ca29 257
pcercuei 0:df031b60ca29 258 return false;
pcercuei 0:df031b60ca29 259 }
pcercuei 0:df031b60ca29 260
pcercuei 0:df031b60ca29 261 int iio_device_open(const struct iio_device *dev,
pcercuei 0:df031b60ca29 262 size_t samples_count, bool cyclic)
pcercuei 0:df031b60ca29 263 {
pcercuei 0:df031b60ca29 264 unsigned int i;
pcercuei 0:df031b60ca29 265 bool has_channels = false;
pcercuei 0:df031b60ca29 266
pcercuei 0:df031b60ca29 267 for (i = 0; !has_channels && i < dev->words; i++)
pcercuei 0:df031b60ca29 268 has_channels = !!dev->mask[i];
pcercuei 0:df031b60ca29 269 if (!has_channels)
pcercuei 0:df031b60ca29 270 return -EINVAL;
pcercuei 0:df031b60ca29 271
pcercuei 0:df031b60ca29 272 if (dev->ctx->ops->open)
pcercuei 0:df031b60ca29 273 return dev->ctx->ops->open(dev, samples_count, cyclic);
pcercuei 0:df031b60ca29 274 else
pcercuei 0:df031b60ca29 275 return -ENOSYS;
pcercuei 0:df031b60ca29 276 }
pcercuei 0:df031b60ca29 277
pcercuei 0:df031b60ca29 278 int iio_device_close(const struct iio_device *dev)
pcercuei 0:df031b60ca29 279 {
pcercuei 0:df031b60ca29 280 if (dev->ctx->ops->close)
pcercuei 0:df031b60ca29 281 return dev->ctx->ops->close(dev);
pcercuei 0:df031b60ca29 282 else
pcercuei 0:df031b60ca29 283 return -ENOSYS;
pcercuei 0:df031b60ca29 284 }
pcercuei 0:df031b60ca29 285
pcercuei 0:df031b60ca29 286 int iio_device_get_poll_fd(const struct iio_device *dev)
pcercuei 0:df031b60ca29 287 {
pcercuei 0:df031b60ca29 288 if (dev->ctx->ops->get_fd)
pcercuei 0:df031b60ca29 289 return dev->ctx->ops->get_fd(dev);
pcercuei 0:df031b60ca29 290 else
pcercuei 0:df031b60ca29 291 return -ENOSYS;
pcercuei 0:df031b60ca29 292 }
pcercuei 0:df031b60ca29 293
pcercuei 0:df031b60ca29 294 int iio_device_set_blocking_mode(const struct iio_device *dev, bool blocking)
pcercuei 0:df031b60ca29 295 {
pcercuei 0:df031b60ca29 296 if (dev->ctx->ops->set_blocking_mode)
pcercuei 0:df031b60ca29 297 return dev->ctx->ops->set_blocking_mode(dev, blocking);
pcercuei 0:df031b60ca29 298 else
pcercuei 0:df031b60ca29 299 return -ENOSYS;
pcercuei 0:df031b60ca29 300 }
pcercuei 0:df031b60ca29 301
pcercuei 0:df031b60ca29 302 ssize_t iio_device_read_raw(const struct iio_device *dev,
pcercuei 0:df031b60ca29 303 void *dst, size_t len, uint32_t *mask, size_t words)
pcercuei 0:df031b60ca29 304 {
pcercuei 0:df031b60ca29 305 if (dev->ctx->ops->read)
pcercuei 0:df031b60ca29 306 return dev->ctx->ops->read(dev, dst, len, mask, words);
pcercuei 0:df031b60ca29 307 else
pcercuei 0:df031b60ca29 308 return -ENOSYS;
pcercuei 0:df031b60ca29 309 }
pcercuei 0:df031b60ca29 310
pcercuei 0:df031b60ca29 311 ssize_t iio_device_write_raw(const struct iio_device *dev,
pcercuei 0:df031b60ca29 312 const void *src, size_t len)
pcercuei 0:df031b60ca29 313 {
pcercuei 0:df031b60ca29 314 if (dev->ctx->ops->write)
pcercuei 0:df031b60ca29 315 return dev->ctx->ops->write(dev, src, len);
pcercuei 0:df031b60ca29 316 else
pcercuei 0:df031b60ca29 317 return -ENOSYS;
pcercuei 0:df031b60ca29 318 }
pcercuei 0:df031b60ca29 319
pcercuei 0:df031b60ca29 320 ssize_t iio_device_attr_read(const struct iio_device *dev,
pcercuei 0:df031b60ca29 321 const char *attr, char *dst, size_t len)
pcercuei 0:df031b60ca29 322 {
pcercuei 0:df031b60ca29 323 if (dev->ctx->ops->read_device_attr)
pcercuei 0:df031b60ca29 324 return dev->ctx->ops->read_device_attr(dev,
pcercuei 0:df031b60ca29 325 attr, dst, len, false);
pcercuei 0:df031b60ca29 326 else
pcercuei 0:df031b60ca29 327 return -ENOSYS;
pcercuei 0:df031b60ca29 328 }
pcercuei 0:df031b60ca29 329
pcercuei 0:df031b60ca29 330 ssize_t iio_device_attr_write_raw(const struct iio_device *dev,
pcercuei 0:df031b60ca29 331 const char *attr, const void *src, size_t len)
pcercuei 0:df031b60ca29 332 {
pcercuei 0:df031b60ca29 333 if (dev->ctx->ops->write_device_attr)
pcercuei 0:df031b60ca29 334 return dev->ctx->ops->write_device_attr(dev,
pcercuei 0:df031b60ca29 335 attr, src, len, false);
pcercuei 0:df031b60ca29 336 else
pcercuei 0:df031b60ca29 337 return -ENOSYS;
pcercuei 0:df031b60ca29 338 }
pcercuei 0:df031b60ca29 339
pcercuei 0:df031b60ca29 340 ssize_t iio_device_attr_write(const struct iio_device *dev,
pcercuei 0:df031b60ca29 341 const char *attr, const char *src)
pcercuei 0:df031b60ca29 342 {
pcercuei 0:df031b60ca29 343 return iio_device_attr_write_raw(dev, attr, src, strlen(src) + 1);
pcercuei 0:df031b60ca29 344 }
pcercuei 0:df031b60ca29 345
pcercuei 0:df031b60ca29 346 void iio_device_set_data(struct iio_device *dev, void *data)
pcercuei 0:df031b60ca29 347 {
pcercuei 0:df031b60ca29 348 dev->userdata = data;
pcercuei 0:df031b60ca29 349 }
pcercuei 0:df031b60ca29 350
pcercuei 0:df031b60ca29 351 void * iio_device_get_data(const struct iio_device *dev)
pcercuei 0:df031b60ca29 352 {
pcercuei 0:df031b60ca29 353 return dev->userdata;
pcercuei 0:df031b60ca29 354 }
pcercuei 0:df031b60ca29 355
pcercuei 0:df031b60ca29 356 bool iio_device_is_trigger(const struct iio_device *dev)
pcercuei 0:df031b60ca29 357 {
pcercuei 0:df031b60ca29 358 /* A trigger has a name, an id which starts by "trigger",
pcercuei 0:df031b60ca29 359 * and zero channels. */
pcercuei 0:df031b60ca29 360
pcercuei 0:df031b60ca29 361 unsigned int nb = iio_device_get_channels_count(dev);
pcercuei 0:df031b60ca29 362 const char *name = iio_device_get_name(dev),
pcercuei 0:df031b60ca29 363 *id = iio_device_get_id(dev);
pcercuei 0:df031b60ca29 364 return ((nb == 0) && !!name &&
pcercuei 0:df031b60ca29 365 !strncmp(id, "trigger", sizeof("trigger") - 1));
pcercuei 0:df031b60ca29 366 }
pcercuei 0:df031b60ca29 367
pcercuei 0:df031b60ca29 368 int iio_device_set_kernel_buffers_count(const struct iio_device *dev,
pcercuei 0:df031b60ca29 369 unsigned int nb_buffers)
pcercuei 0:df031b60ca29 370 {
pcercuei 0:df031b60ca29 371 if (nb_buffers == 0)
pcercuei 0:df031b60ca29 372 return -EINVAL;
pcercuei 0:df031b60ca29 373 else if (dev->ctx->ops->set_kernel_buffers_count)
pcercuei 0:df031b60ca29 374 return dev->ctx->ops->set_kernel_buffers_count(dev, nb_buffers);
pcercuei 0:df031b60ca29 375 else
pcercuei 0:df031b60ca29 376 return -ENOSYS;
pcercuei 0:df031b60ca29 377 }
pcercuei 0:df031b60ca29 378
pcercuei 0:df031b60ca29 379 int iio_device_get_trigger(const struct iio_device *dev,
pcercuei 0:df031b60ca29 380 const struct iio_device **trigger)
pcercuei 0:df031b60ca29 381 {
pcercuei 0:df031b60ca29 382 if (!trigger)
pcercuei 0:df031b60ca29 383 return -EINVAL;
pcercuei 0:df031b60ca29 384 else if (dev->ctx->ops->get_trigger)
pcercuei 0:df031b60ca29 385 return dev->ctx->ops->get_trigger(dev, trigger);
pcercuei 0:df031b60ca29 386 else
pcercuei 0:df031b60ca29 387 return -ENOSYS;
pcercuei 0:df031b60ca29 388 }
pcercuei 0:df031b60ca29 389
pcercuei 0:df031b60ca29 390 int iio_device_set_trigger(const struct iio_device *dev,
pcercuei 0:df031b60ca29 391 const struct iio_device *trigger)
pcercuei 0:df031b60ca29 392 {
pcercuei 0:df031b60ca29 393 if (trigger && !iio_device_is_trigger(trigger))
pcercuei 0:df031b60ca29 394 return -EINVAL;
pcercuei 0:df031b60ca29 395 else if (dev->ctx->ops->set_trigger)
pcercuei 0:df031b60ca29 396 return dev->ctx->ops->set_trigger(dev, trigger);
pcercuei 0:df031b60ca29 397 else
pcercuei 0:df031b60ca29 398 return -ENOSYS;
pcercuei 0:df031b60ca29 399 }
pcercuei 0:df031b60ca29 400
pcercuei 0:df031b60ca29 401 void free_device(struct iio_device *dev)
pcercuei 0:df031b60ca29 402 {
pcercuei 0:df031b60ca29 403 unsigned int i;
pcercuei 0:df031b60ca29 404 for (i = 0; i < dev->nb_attrs; i++)
pcercuei 0:df031b60ca29 405 free(dev->attrs[i]);
pcercuei 0:df031b60ca29 406 if (dev->nb_attrs)
pcercuei 0:df031b60ca29 407 free(dev->attrs);
pcercuei 0:df031b60ca29 408 for (i = 0; i < dev->nb_debug_attrs; i++)
pcercuei 0:df031b60ca29 409 free(dev->debug_attrs[i]);
pcercuei 0:df031b60ca29 410 if (dev->nb_debug_attrs)
pcercuei 0:df031b60ca29 411 free(dev->debug_attrs);
pcercuei 0:df031b60ca29 412 for (i = 0; i < dev->nb_channels; i++)
pcercuei 0:df031b60ca29 413 free_channel(dev->channels[i]);
pcercuei 0:df031b60ca29 414 if (dev->nb_channels)
pcercuei 0:df031b60ca29 415 free(dev->channels);
pcercuei 0:df031b60ca29 416 if (dev->mask)
pcercuei 0:df031b60ca29 417 free(dev->mask);
pcercuei 0:df031b60ca29 418 if (dev->name)
pcercuei 0:df031b60ca29 419 free(dev->name);
pcercuei 0:df031b60ca29 420 if (dev->id)
pcercuei 0:df031b60ca29 421 free(dev->id);
pcercuei 0:df031b60ca29 422 free(dev);
pcercuei 0:df031b60ca29 423 }
pcercuei 0:df031b60ca29 424
pcercuei 0:df031b60ca29 425 ssize_t iio_device_get_sample_size_mask(const struct iio_device *dev,
pcercuei 0:df031b60ca29 426 const uint32_t *mask, size_t words)
pcercuei 0:df031b60ca29 427 {
pcercuei 0:df031b60ca29 428 ssize_t size = 0;
pcercuei 0:df031b60ca29 429 unsigned int i;
pcercuei 0:df031b60ca29 430
pcercuei 0:df031b60ca29 431 if (words != (dev->nb_channels + 31) / 32)
pcercuei 0:df031b60ca29 432 return -EINVAL;
pcercuei 0:df031b60ca29 433
pcercuei 0:df031b60ca29 434 for (i = 0; i < dev->nb_channels; i++) {
pcercuei 0:df031b60ca29 435 const struct iio_channel *chn = dev->channels[i];
pcercuei 3:d147beabba0e 436 unsigned int length = chn->format.length / 8 *
pcercuei 3:d147beabba0e 437 chn->format.repeat;
pcercuei 0:df031b60ca29 438
pcercuei 0:df031b60ca29 439 if (chn->index < 0)
pcercuei 0:df031b60ca29 440 break;
pcercuei 0:df031b60ca29 441 if (!TEST_BIT(mask, chn->index))
pcercuei 0:df031b60ca29 442 continue;
pcercuei 3:d147beabba0e 443 if (i > 0 && chn->index == dev->channels[i - 1]->index)
pcercuei 3:d147beabba0e 444 continue;
pcercuei 0:df031b60ca29 445
pcercuei 0:df031b60ca29 446 if (size % length)
pcercuei 0:df031b60ca29 447 size += 2 * length - (size % length);
pcercuei 0:df031b60ca29 448 else
pcercuei 0:df031b60ca29 449 size += length;
pcercuei 0:df031b60ca29 450 }
pcercuei 0:df031b60ca29 451 return size;
pcercuei 0:df031b60ca29 452 }
pcercuei 0:df031b60ca29 453
pcercuei 0:df031b60ca29 454 ssize_t iio_device_get_sample_size(const struct iio_device *dev)
pcercuei 0:df031b60ca29 455 {
pcercuei 0:df031b60ca29 456 return iio_device_get_sample_size_mask(dev, dev->mask, dev->words);
pcercuei 0:df031b60ca29 457 }
pcercuei 0:df031b60ca29 458
pcercuei 0:df031b60ca29 459 int iio_device_attr_read_longlong(const struct iio_device *dev,
pcercuei 0:df031b60ca29 460 const char *attr, long long *val)
pcercuei 0:df031b60ca29 461 {
pcercuei 0:df031b60ca29 462 char *end, buf[1024];
pcercuei 0:df031b60ca29 463 long long value;
pcercuei 0:df031b60ca29 464 ssize_t ret = iio_device_attr_read(dev, attr, buf, sizeof(buf));
pcercuei 0:df031b60ca29 465 if (ret < 0)
pcercuei 0:df031b60ca29 466 return (int) ret;
pcercuei 0:df031b60ca29 467
pcercuei 0:df031b60ca29 468 value = strtoll(buf, &end, 0);
pcercuei 0:df031b60ca29 469 if (end == buf)
pcercuei 0:df031b60ca29 470 return -EINVAL;
pcercuei 0:df031b60ca29 471 *val = value;
pcercuei 0:df031b60ca29 472 return 0;
pcercuei 0:df031b60ca29 473 }
pcercuei 0:df031b60ca29 474
pcercuei 0:df031b60ca29 475 int iio_device_attr_read_bool(const struct iio_device *dev,
pcercuei 0:df031b60ca29 476 const char *attr, bool *val)
pcercuei 0:df031b60ca29 477 {
pcercuei 0:df031b60ca29 478 long long value;
pcercuei 0:df031b60ca29 479 int ret = iio_device_attr_read_longlong(dev, attr, &value);
pcercuei 0:df031b60ca29 480 if (ret < 0)
pcercuei 0:df031b60ca29 481 return ret;
pcercuei 0:df031b60ca29 482
pcercuei 0:df031b60ca29 483 *val = !!value;
pcercuei 0:df031b60ca29 484 return 0;
pcercuei 0:df031b60ca29 485 }
pcercuei 0:df031b60ca29 486
pcercuei 0:df031b60ca29 487 int iio_device_attr_read_double(const struct iio_device *dev,
pcercuei 0:df031b60ca29 488 const char *attr, double *val)
pcercuei 0:df031b60ca29 489 {
pcercuei 0:df031b60ca29 490 char buf[1024];
pcercuei 0:df031b60ca29 491 ssize_t ret = iio_device_attr_read(dev, attr, buf, sizeof(buf));
pcercuei 0:df031b60ca29 492 if (ret < 0)
pcercuei 0:df031b60ca29 493 return (int) ret;
pcercuei 0:df031b60ca29 494 else
pcercuei 0:df031b60ca29 495 return read_double(buf, val);
pcercuei 0:df031b60ca29 496 }
pcercuei 0:df031b60ca29 497
pcercuei 0:df031b60ca29 498 int iio_device_attr_write_longlong(const struct iio_device *dev,
pcercuei 0:df031b60ca29 499 const char *attr, long long val)
pcercuei 0:df031b60ca29 500 {
pcercuei 0:df031b60ca29 501 ssize_t ret;
pcercuei 0:df031b60ca29 502 char buf[1024];
pcercuei 0:df031b60ca29 503
pcercuei 3:d147beabba0e 504 iio_snprintf(buf, sizeof(buf), "%lld", val);
pcercuei 0:df031b60ca29 505 ret = iio_device_attr_write(dev, attr, buf);
pcercuei 0:df031b60ca29 506
pcercuei 0:df031b60ca29 507 return ret < 0 ? ret : 0;
pcercuei 0:df031b60ca29 508 }
pcercuei 0:df031b60ca29 509
pcercuei 0:df031b60ca29 510 int iio_device_attr_write_double(const struct iio_device *dev,
pcercuei 0:df031b60ca29 511 const char *attr, double val)
pcercuei 0:df031b60ca29 512 {
pcercuei 0:df031b60ca29 513 ssize_t ret;
pcercuei 0:df031b60ca29 514 char buf[1024];
pcercuei 0:df031b60ca29 515
pcercuei 0:df031b60ca29 516 ret = (ssize_t) write_double(buf, sizeof(buf), val);
pcercuei 0:df031b60ca29 517 if (!ret)
pcercuei 0:df031b60ca29 518 ret = iio_device_attr_write(dev, attr, buf);
pcercuei 0:df031b60ca29 519 return ret < 0 ? ret : 0;
pcercuei 0:df031b60ca29 520 }
pcercuei 0:df031b60ca29 521
pcercuei 0:df031b60ca29 522 int iio_device_attr_write_bool(const struct iio_device *dev,
pcercuei 0:df031b60ca29 523 const char *attr, bool val)
pcercuei 0:df031b60ca29 524 {
pcercuei 0:df031b60ca29 525 ssize_t ret;
pcercuei 0:df031b60ca29 526
pcercuei 0:df031b60ca29 527 if (val)
pcercuei 0:df031b60ca29 528 ret = iio_device_attr_write(dev, attr, "1");
pcercuei 0:df031b60ca29 529 else
pcercuei 0:df031b60ca29 530 ret = iio_device_attr_write(dev, attr, "0");
pcercuei 0:df031b60ca29 531
pcercuei 0:df031b60ca29 532 return ret < 0 ? ret : 0;
pcercuei 0:df031b60ca29 533 }
pcercuei 0:df031b60ca29 534
pcercuei 0:df031b60ca29 535 ssize_t iio_device_debug_attr_read(const struct iio_device *dev,
pcercuei 0:df031b60ca29 536 const char *attr, char *dst, size_t len)
pcercuei 0:df031b60ca29 537 {
pcercuei 0:df031b60ca29 538 if (dev->ctx->ops->read_device_attr)
pcercuei 0:df031b60ca29 539 return dev->ctx->ops->read_device_attr(dev,
pcercuei 0:df031b60ca29 540 attr, dst, len, true);
pcercuei 0:df031b60ca29 541 else
pcercuei 0:df031b60ca29 542 return -ENOSYS;
pcercuei 0:df031b60ca29 543 }
pcercuei 0:df031b60ca29 544
pcercuei 0:df031b60ca29 545 ssize_t iio_device_debug_attr_write_raw(const struct iio_device *dev,
pcercuei 0:df031b60ca29 546 const char *attr, const void *src, size_t len)
pcercuei 0:df031b60ca29 547 {
pcercuei 0:df031b60ca29 548 if (dev->ctx->ops->write_device_attr)
pcercuei 0:df031b60ca29 549 return dev->ctx->ops->write_device_attr(dev,
pcercuei 0:df031b60ca29 550 attr, src, len, true);
pcercuei 0:df031b60ca29 551 else
pcercuei 0:df031b60ca29 552 return -ENOSYS;
pcercuei 0:df031b60ca29 553 }
pcercuei 0:df031b60ca29 554
pcercuei 0:df031b60ca29 555 ssize_t iio_device_debug_attr_write(const struct iio_device *dev,
pcercuei 0:df031b60ca29 556 const char *attr, const char *src)
pcercuei 0:df031b60ca29 557 {
pcercuei 0:df031b60ca29 558 return iio_device_debug_attr_write_raw(dev, attr, src, strlen(src) + 1);
pcercuei 0:df031b60ca29 559 }
pcercuei 0:df031b60ca29 560
pcercuei 0:df031b60ca29 561 unsigned int iio_device_get_debug_attrs_count(const struct iio_device *dev)
pcercuei 0:df031b60ca29 562 {
pcercuei 0:df031b60ca29 563 return dev->nb_debug_attrs;
pcercuei 0:df031b60ca29 564 }
pcercuei 0:df031b60ca29 565
pcercuei 0:df031b60ca29 566 const char * iio_device_get_debug_attr(const struct iio_device *dev,
pcercuei 0:df031b60ca29 567 unsigned int index)
pcercuei 0:df031b60ca29 568 {
pcercuei 0:df031b60ca29 569 if (index >= dev->nb_debug_attrs)
pcercuei 0:df031b60ca29 570 return NULL;
pcercuei 0:df031b60ca29 571 else
pcercuei 0:df031b60ca29 572 return dev->debug_attrs[index];
pcercuei 0:df031b60ca29 573 }
pcercuei 0:df031b60ca29 574
pcercuei 0:df031b60ca29 575 int iio_device_debug_attr_read_longlong(const struct iio_device *dev,
pcercuei 0:df031b60ca29 576 const char *attr, long long *val)
pcercuei 0:df031b60ca29 577 {
pcercuei 0:df031b60ca29 578 char *end, buf[1024];
pcercuei 0:df031b60ca29 579 long long value;
pcercuei 0:df031b60ca29 580 ssize_t ret = iio_device_debug_attr_read(dev, attr, buf, sizeof(buf));
pcercuei 0:df031b60ca29 581 if (ret < 0)
pcercuei 0:df031b60ca29 582 return (int) ret;
pcercuei 0:df031b60ca29 583
pcercuei 0:df031b60ca29 584 value = strtoll(buf, &end, 0);
pcercuei 0:df031b60ca29 585 if (end == buf)
pcercuei 0:df031b60ca29 586 return -EINVAL;
pcercuei 0:df031b60ca29 587 *val = value;
pcercuei 0:df031b60ca29 588 return 0;
pcercuei 0:df031b60ca29 589 }
pcercuei 0:df031b60ca29 590
pcercuei 0:df031b60ca29 591 int iio_device_debug_attr_read_bool(const struct iio_device *dev,
pcercuei 0:df031b60ca29 592 const char *attr, bool *val)
pcercuei 0:df031b60ca29 593 {
pcercuei 0:df031b60ca29 594 long long value;
pcercuei 0:df031b60ca29 595 int ret = iio_device_debug_attr_read_longlong(dev, attr, &value);
pcercuei 0:df031b60ca29 596 if (ret < 0)
pcercuei 0:df031b60ca29 597 return ret;
pcercuei 0:df031b60ca29 598
pcercuei 0:df031b60ca29 599 *val = !!value;
pcercuei 0:df031b60ca29 600 return 0;
pcercuei 0:df031b60ca29 601 }
pcercuei 0:df031b60ca29 602
pcercuei 0:df031b60ca29 603 int iio_device_debug_attr_read_double(const struct iio_device *dev,
pcercuei 0:df031b60ca29 604 const char *attr, double *val)
pcercuei 0:df031b60ca29 605 {
pcercuei 0:df031b60ca29 606 char buf[1024];
pcercuei 0:df031b60ca29 607 ssize_t ret = iio_device_debug_attr_read(dev, attr, buf, sizeof(buf));
pcercuei 0:df031b60ca29 608 if (ret < 0)
pcercuei 0:df031b60ca29 609 return (int) ret;
pcercuei 0:df031b60ca29 610 else
pcercuei 0:df031b60ca29 611 return read_double(buf, val);
pcercuei 0:df031b60ca29 612 }
pcercuei 0:df031b60ca29 613
pcercuei 0:df031b60ca29 614 int iio_device_debug_attr_write_longlong(const struct iio_device *dev,
pcercuei 0:df031b60ca29 615 const char *attr, long long val)
pcercuei 0:df031b60ca29 616 {
pcercuei 0:df031b60ca29 617 ssize_t ret;
pcercuei 0:df031b60ca29 618 char buf[1024];
pcercuei 0:df031b60ca29 619
pcercuei 3:d147beabba0e 620 iio_snprintf(buf, sizeof(buf), "%lld", val);
pcercuei 0:df031b60ca29 621 ret = iio_device_debug_attr_write(dev, attr, buf);
pcercuei 0:df031b60ca29 622
pcercuei 0:df031b60ca29 623 return ret < 0 ? ret : 0;
pcercuei 0:df031b60ca29 624 }
pcercuei 0:df031b60ca29 625
pcercuei 0:df031b60ca29 626 int iio_device_debug_attr_write_double(const struct iio_device *dev,
pcercuei 0:df031b60ca29 627 const char *attr, double val)
pcercuei 0:df031b60ca29 628 {
pcercuei 0:df031b60ca29 629 ssize_t ret;
pcercuei 0:df031b60ca29 630 char buf[1024];
pcercuei 0:df031b60ca29 631
pcercuei 0:df031b60ca29 632 ret = (ssize_t) write_double(buf, sizeof(buf), val);
pcercuei 0:df031b60ca29 633 if (!ret)
pcercuei 0:df031b60ca29 634 ret = iio_device_debug_attr_write(dev, attr, buf);
pcercuei 0:df031b60ca29 635 return ret < 0 ? ret : 0;
pcercuei 0:df031b60ca29 636 }
pcercuei 0:df031b60ca29 637
pcercuei 0:df031b60ca29 638 int iio_device_debug_attr_write_bool(const struct iio_device *dev,
pcercuei 0:df031b60ca29 639 const char *attr, bool val)
pcercuei 0:df031b60ca29 640 {
pcercuei 0:df031b60ca29 641 ssize_t ret;
pcercuei 0:df031b60ca29 642
pcercuei 0:df031b60ca29 643 if (val)
pcercuei 0:df031b60ca29 644 ret = iio_device_debug_attr_write_raw(dev, attr, "1", 2);
pcercuei 0:df031b60ca29 645 else
pcercuei 0:df031b60ca29 646 ret = iio_device_debug_attr_write_raw(dev, attr, "0", 2);
pcercuei 0:df031b60ca29 647
pcercuei 0:df031b60ca29 648 return ret < 0 ? ret : 0;
pcercuei 0:df031b60ca29 649 }
pcercuei 0:df031b60ca29 650
pcercuei 0:df031b60ca29 651 int iio_device_identify_filename(const struct iio_device *dev,
pcercuei 0:df031b60ca29 652 const char *filename, struct iio_channel **chn,
pcercuei 0:df031b60ca29 653 const char **attr)
pcercuei 0:df031b60ca29 654 {
pcercuei 0:df031b60ca29 655 unsigned int i;
pcercuei 0:df031b60ca29 656
pcercuei 0:df031b60ca29 657 for (i = 0; i < dev->nb_channels; i++) {
pcercuei 0:df031b60ca29 658 struct iio_channel *ch = dev->channels[i];
pcercuei 0:df031b60ca29 659 unsigned int j;
pcercuei 0:df031b60ca29 660
pcercuei 0:df031b60ca29 661 for (j = 0; j < ch->nb_attrs; j++) {
pcercuei 0:df031b60ca29 662 if (!strcmp(ch->attrs[j].filename, filename)) {
pcercuei 0:df031b60ca29 663 *attr = ch->attrs[j].name;
pcercuei 0:df031b60ca29 664 *chn = ch;
pcercuei 0:df031b60ca29 665 return 0;
pcercuei 0:df031b60ca29 666 }
pcercuei 0:df031b60ca29 667 }
pcercuei 0:df031b60ca29 668 }
pcercuei 0:df031b60ca29 669
pcercuei 0:df031b60ca29 670 for (i = 0; i < dev->nb_attrs; i++) {
pcercuei 0:df031b60ca29 671 /* Devices attributes are named after their filename */
pcercuei 0:df031b60ca29 672 if (!strcmp(dev->attrs[i], filename)) {
pcercuei 0:df031b60ca29 673 *attr = dev->attrs[i];
pcercuei 0:df031b60ca29 674 *chn = NULL;
pcercuei 0:df031b60ca29 675 return 0;
pcercuei 0:df031b60ca29 676 }
pcercuei 0:df031b60ca29 677 }
pcercuei 0:df031b60ca29 678
pcercuei 0:df031b60ca29 679 for (i = 0; i < dev->nb_debug_attrs; i++) {
pcercuei 0:df031b60ca29 680 if (!strcmp(dev->debug_attrs[i], filename)) {
pcercuei 0:df031b60ca29 681 *attr = dev->debug_attrs[i];
pcercuei 0:df031b60ca29 682 *chn = NULL;
pcercuei 0:df031b60ca29 683 return 0;
pcercuei 0:df031b60ca29 684 }
pcercuei 0:df031b60ca29 685 }
pcercuei 0:df031b60ca29 686
pcercuei 0:df031b60ca29 687 return -EINVAL;
pcercuei 0:df031b60ca29 688 }
pcercuei 0:df031b60ca29 689
pcercuei 0:df031b60ca29 690 int iio_device_reg_write(struct iio_device *dev,
pcercuei 0:df031b60ca29 691 uint32_t address, uint32_t value)
pcercuei 0:df031b60ca29 692 {
pcercuei 0:df031b60ca29 693 ssize_t ret;
pcercuei 3:d147beabba0e 694 char buf[1024];
pcercuei 0:df031b60ca29 695
pcercuei 3:d147beabba0e 696 iio_snprintf(buf, sizeof(buf), "0x%" PRIx32 " 0x%" PRIx32,
pcercuei 3:d147beabba0e 697 address, value);
pcercuei 0:df031b60ca29 698 ret = iio_device_debug_attr_write(dev, "direct_reg_access", buf);
pcercuei 0:df031b60ca29 699
pcercuei 0:df031b60ca29 700 return ret < 0 ? ret : 0;
pcercuei 0:df031b60ca29 701 }
pcercuei 0:df031b60ca29 702
pcercuei 0:df031b60ca29 703 int iio_device_reg_read(struct iio_device *dev,
pcercuei 0:df031b60ca29 704 uint32_t address, uint32_t *value)
pcercuei 0:df031b60ca29 705 {
pcercuei 0:df031b60ca29 706 /* NOTE: There is a race condition here. But it is extremely unlikely to
pcercuei 0:df031b60ca29 707 * happen, and as this is a debug function, it shouldn't be used for
pcercuei 0:df031b60ca29 708 * something else than debug. */
pcercuei 0:df031b60ca29 709
pcercuei 0:df031b60ca29 710 long long val;
pcercuei 0:df031b60ca29 711 int ret = iio_device_debug_attr_write_longlong(dev,
pcercuei 0:df031b60ca29 712 "direct_reg_access", (long long) address);
pcercuei 0:df031b60ca29 713 if (ret < 0)
pcercuei 0:df031b60ca29 714 return ret;
pcercuei 0:df031b60ca29 715
pcercuei 0:df031b60ca29 716 ret = iio_device_debug_attr_read_longlong(dev,
pcercuei 0:df031b60ca29 717 "direct_reg_access", &val);
pcercuei 0:df031b60ca29 718 if (!ret)
pcercuei 0:df031b60ca29 719 *value = (uint32_t) val;
pcercuei 0:df031b60ca29 720 return ret;
pcercuei 0:df031b60ca29 721 }
pcercuei 0:df031b60ca29 722
pcercuei 0:df031b60ca29 723 static int read_each_attr(struct iio_device *dev, bool is_debug,
pcercuei 0:df031b60ca29 724 int (*cb)(struct iio_device *dev,
pcercuei 0:df031b60ca29 725 const char *attr, const char *val, size_t len, void *d),
pcercuei 0:df031b60ca29 726 void *data)
pcercuei 0:df031b60ca29 727 {
pcercuei 0:df031b60ca29 728 int ret;
pcercuei 0:df031b60ca29 729 char *buf, *ptr;
pcercuei 0:df031b60ca29 730 unsigned int i, count;
pcercuei 0:df031b60ca29 731
pcercuei 0:df031b60ca29 732 /* We need a big buffer here; 1 MiB should be enough */
pcercuei 0:df031b60ca29 733 buf = malloc(0x100000);
pcercuei 0:df031b60ca29 734 if (!buf)
pcercuei 0:df031b60ca29 735 return -ENOMEM;
pcercuei 0:df031b60ca29 736
pcercuei 0:df031b60ca29 737 if (is_debug) {
pcercuei 0:df031b60ca29 738 count = iio_device_get_debug_attrs_count(dev);
pcercuei 0:df031b60ca29 739 ret = (int) iio_device_debug_attr_read(dev,
pcercuei 0:df031b60ca29 740 NULL, buf, 0x100000);
pcercuei 0:df031b60ca29 741 } else {
pcercuei 0:df031b60ca29 742 count = iio_device_get_attrs_count(dev);
pcercuei 0:df031b60ca29 743 ret = (int) iio_device_attr_read(dev, NULL, buf, 0x100000);
pcercuei 0:df031b60ca29 744 }
pcercuei 0:df031b60ca29 745
pcercuei 0:df031b60ca29 746 if (ret < 0)
pcercuei 0:df031b60ca29 747 goto err_free_buf;
pcercuei 0:df031b60ca29 748
pcercuei 0:df031b60ca29 749 ptr = buf;
pcercuei 0:df031b60ca29 750
pcercuei 0:df031b60ca29 751 for (i = 0; i < count; i++) {
pcercuei 0:df031b60ca29 752 const char *attr;
pcercuei 0:df031b60ca29 753 int32_t len = (int32_t) iio_be32toh(*(uint32_t *) ptr);
pcercuei 0:df031b60ca29 754
pcercuei 0:df031b60ca29 755 if (is_debug)
pcercuei 0:df031b60ca29 756 attr = iio_device_get_debug_attr(dev, i);
pcercuei 0:df031b60ca29 757 else
pcercuei 0:df031b60ca29 758 attr = iio_device_get_attr(dev, i);
pcercuei 0:df031b60ca29 759
pcercuei 0:df031b60ca29 760 ptr += 4;
pcercuei 0:df031b60ca29 761 if (len > 0) {
pcercuei 0:df031b60ca29 762 ret = cb(dev, attr, ptr, (size_t) len, data);
pcercuei 0:df031b60ca29 763 if (ret < 0)
pcercuei 0:df031b60ca29 764 goto err_free_buf;
pcercuei 0:df031b60ca29 765
pcercuei 0:df031b60ca29 766 if (len & 0x3)
pcercuei 0:df031b60ca29 767 len = ((len >> 2) + 1) << 2;
pcercuei 0:df031b60ca29 768 ptr += len;
pcercuei 0:df031b60ca29 769 }
pcercuei 0:df031b60ca29 770 }
pcercuei 0:df031b60ca29 771
pcercuei 0:df031b60ca29 772 err_free_buf:
pcercuei 0:df031b60ca29 773 free(buf);
pcercuei 0:df031b60ca29 774 return ret < 0 ? ret : 0;
pcercuei 0:df031b60ca29 775 }
pcercuei 0:df031b60ca29 776
pcercuei 0:df031b60ca29 777 static int write_each_attr(struct iio_device *dev, bool is_debug,
pcercuei 0:df031b60ca29 778 ssize_t (*cb)(struct iio_device *dev,
pcercuei 0:df031b60ca29 779 const char *attr, void *buf, size_t len, void *d),
pcercuei 0:df031b60ca29 780 void *data)
pcercuei 0:df031b60ca29 781 {
pcercuei 0:df031b60ca29 782 char *buf, *ptr;
pcercuei 0:df031b60ca29 783 unsigned int i, count;
pcercuei 0:df031b60ca29 784 size_t len = 0x100000;
pcercuei 0:df031b60ca29 785 int ret;
pcercuei 0:df031b60ca29 786
pcercuei 0:df031b60ca29 787 /* We need a big buffer here; 1 MiB should be enough */
pcercuei 0:df031b60ca29 788 buf = malloc(len);
pcercuei 0:df031b60ca29 789 if (!buf)
pcercuei 0:df031b60ca29 790 return -ENOMEM;
pcercuei 0:df031b60ca29 791
pcercuei 0:df031b60ca29 792 ptr = buf;
pcercuei 0:df031b60ca29 793
pcercuei 0:df031b60ca29 794 if (is_debug)
pcercuei 0:df031b60ca29 795 count = iio_device_get_debug_attrs_count(dev);
pcercuei 0:df031b60ca29 796 else
pcercuei 0:df031b60ca29 797 count = iio_device_get_attrs_count(dev);
pcercuei 0:df031b60ca29 798
pcercuei 0:df031b60ca29 799 for (i = 0; i < count; i++) {
pcercuei 0:df031b60ca29 800 const char *attr;
pcercuei 0:df031b60ca29 801
pcercuei 0:df031b60ca29 802 if (is_debug)
pcercuei 0:df031b60ca29 803 attr = iio_device_get_debug_attr(dev, i);
pcercuei 0:df031b60ca29 804 else
pcercuei 0:df031b60ca29 805 attr = iio_device_get_attr(dev, i);
pcercuei 0:df031b60ca29 806
pcercuei 0:df031b60ca29 807 ret = (int) cb(dev, attr, ptr + 4, len - 4, data);
pcercuei 0:df031b60ca29 808 if (ret < 0)
pcercuei 0:df031b60ca29 809 goto err_free_buf;
pcercuei 0:df031b60ca29 810
pcercuei 0:df031b60ca29 811 *(int32_t *) ptr = (int32_t) iio_htobe32((uint32_t) ret);
pcercuei 0:df031b60ca29 812 ptr += 4;
pcercuei 0:df031b60ca29 813 len -= 4;
pcercuei 0:df031b60ca29 814
pcercuei 0:df031b60ca29 815 if (ret > 0) {
pcercuei 0:df031b60ca29 816 if (ret & 0x3)
pcercuei 0:df031b60ca29 817 ret = ((ret >> 2) + 1) << 2;
pcercuei 0:df031b60ca29 818 ptr += ret;
pcercuei 0:df031b60ca29 819 len -= ret;
pcercuei 0:df031b60ca29 820 }
pcercuei 0:df031b60ca29 821 }
pcercuei 0:df031b60ca29 822
pcercuei 0:df031b60ca29 823 if (is_debug)
pcercuei 0:df031b60ca29 824 ret = (int) iio_device_debug_attr_write_raw(dev,
pcercuei 0:df031b60ca29 825 NULL, buf, ptr - buf);
pcercuei 0:df031b60ca29 826 else
pcercuei 0:df031b60ca29 827 ret = (int) iio_device_attr_write_raw(dev,
pcercuei 0:df031b60ca29 828 NULL, buf, ptr - buf);
pcercuei 0:df031b60ca29 829
pcercuei 0:df031b60ca29 830 err_free_buf:
pcercuei 0:df031b60ca29 831 free(buf);
pcercuei 0:df031b60ca29 832 return ret < 0 ? ret : 0;
pcercuei 0:df031b60ca29 833 }
pcercuei 0:df031b60ca29 834
pcercuei 0:df031b60ca29 835 int iio_device_debug_attr_read_all(struct iio_device *dev,
pcercuei 0:df031b60ca29 836 int (*cb)(struct iio_device *dev,
pcercuei 0:df031b60ca29 837 const char *attr, const char *val, size_t len, void *d),
pcercuei 0:df031b60ca29 838 void *data)
pcercuei 0:df031b60ca29 839 {
pcercuei 0:df031b60ca29 840 return read_each_attr(dev, true, cb, data);
pcercuei 0:df031b60ca29 841 }
pcercuei 0:df031b60ca29 842
pcercuei 0:df031b60ca29 843 int iio_device_attr_read_all(struct iio_device *dev,
pcercuei 0:df031b60ca29 844 int (*cb)(struct iio_device *dev,
pcercuei 0:df031b60ca29 845 const char *attr, const char *val, size_t len, void *d),
pcercuei 0:df031b60ca29 846 void *data)
pcercuei 0:df031b60ca29 847 {
pcercuei 0:df031b60ca29 848 return read_each_attr(dev, false, cb, data);
pcercuei 0:df031b60ca29 849 }
pcercuei 0:df031b60ca29 850
pcercuei 0:df031b60ca29 851 int iio_device_debug_attr_write_all(struct iio_device *dev,
pcercuei 0:df031b60ca29 852 ssize_t (*cb)(struct iio_device *dev,
pcercuei 0:df031b60ca29 853 const char *attr, void *buf, size_t len, void *d),
pcercuei 0:df031b60ca29 854 void *data)
pcercuei 0:df031b60ca29 855 {
pcercuei 0:df031b60ca29 856 return write_each_attr(dev, true, cb, data);
pcercuei 0:df031b60ca29 857 }
pcercuei 0:df031b60ca29 858
pcercuei 0:df031b60ca29 859 int iio_device_attr_write_all(struct iio_device *dev,
pcercuei 0:df031b60ca29 860 ssize_t (*cb)(struct iio_device *dev,
pcercuei 0:df031b60ca29 861 const char *attr, void *buf, size_t len, void *d),
pcercuei 0:df031b60ca29 862 void *data)
pcercuei 0:df031b60ca29 863 {
pcercuei 0:df031b60ca29 864 return write_each_attr(dev, false, cb, data);
pcercuei 0:df031b60ca29 865 }
pcercuei 0:df031b60ca29 866
pcercuei 0:df031b60ca29 867 const struct iio_context * iio_device_get_context(const struct iio_device *dev)
pcercuei 0:df031b60ca29 868 {
pcercuei 0:df031b60ca29 869 return dev->ctx;
pcercuei 0:df031b60ca29 870 }
pcercuei 0:df031b60ca29 871