blob: 16a10e065be1b749f6b98784c30efe6d8af2dcca [file] [log] [blame]
Paul Cercueilbb4401d2014-02-28 16:10:49 +01001/*
2 * libiio - Library for interfacing industrial I/O (IIO) devices
3 *
4 * Copyright (C) 2014 Analog Devices, Inc.
5 * Author: Paul Cercueil <paul.cercueil@analog.com>
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * */
18
Paul Cercueil42090d12014-02-24 12:32:23 +010019#include "debug.h"
Paul Cercueil0b2ce712014-02-17 15:04:18 +010020#include "iio-private.h"
21
Paul Cercueil6a013602014-02-19 12:37:39 +010022#include <errno.h>
Paul Cercueil0b2ce712014-02-17 15:04:18 +010023#include <stdio.h>
Paul Cercueil42090d12014-02-24 12:32:23 +010024#include <string.h>
25
Paul Cercueild9d9f9f2014-04-15 10:08:17 +020026static char *get_attr_xml(const char *attr, size_t *length, bool is_debug)
Paul Cercueil42090d12014-02-24 12:32:23 +010027{
Paul Cercueild9d9f9f2014-04-15 10:08:17 +020028 size_t len = sizeof("<attribute name=\"\" />") + strlen(attr)
29 + (!is_debug ? 0 : sizeof("debug-") - 1);
Paul Cercueil42090d12014-02-24 12:32:23 +010030 char *str = malloc(len);
31 if (!str) {
32 ERROR("Unable to allocate memory\n");
33 return NULL;
34 }
35
36 *length = len - 1; /* Skip the \0 */
Paul Cercueild9d9f9f2014-04-15 10:08:17 +020037 if (is_debug)
38 snprintf(str, len, "<debug-attribute name=\"%s\" />", attr);
39 else
40 snprintf(str, len, "<attribute name=\"%s\" />", attr);
Paul Cercueil42090d12014-02-24 12:32:23 +010041 return str;
42}
43
44/* Returns a string containing the XML representation of this device */
45char * iio_device_get_xml(const struct iio_device *dev, size_t *length)
46{
Paul Cercueil8c29e412014-04-07 09:46:45 +020047 size_t len = sizeof("<device id=\"\" name=\"\" ></device>")
48 + strlen(dev->id) + (dev->name ? strlen(dev->name) : 0);
Paul Cercueild9d9f9f2014-04-15 10:08:17 +020049 char *ptr, *str, **attrs, **channels, **debug_attrs;
50 size_t *attrs_len, *channels_len, *debug_attrs_len;
51 unsigned int i, j, k;
Paul Cercueil5822ab62014-04-04 13:29:17 +020052
53 attrs_len = malloc(dev->nb_attrs * sizeof(*attrs_len));
54 if (!attrs_len)
55 return NULL;
56
57 attrs = malloc(dev->nb_attrs * sizeof(*attrs));
58 if (!attrs)
59 goto err_free_attrs_len;
60
Paul Cercueil42090d12014-02-24 12:32:23 +010061 for (i = 0; i < dev->nb_attrs; i++) {
Paul Cercueild9d9f9f2014-04-15 10:08:17 +020062 char *xml = get_attr_xml(dev->attrs[i], &attrs_len[i], false);
Paul Cercueil42090d12014-02-24 12:32:23 +010063 if (!xml)
64 goto err_free_attrs;
65 attrs[i] = xml;
66 len += attrs_len[i];
67 }
68
Paul Cercueil8c29e412014-04-07 09:46:45 +020069 channels_len = malloc(dev->nb_channels * sizeof(*channels_len));
70 if (!channels_len)
71 goto err_free_attrs;
72
73 channels = malloc(dev->nb_channels * sizeof(*channels));
74 if (!channels)
75 goto err_free_channels_len;
76
Paul Cercueil42090d12014-02-24 12:32:23 +010077 for (j = 0; j < dev->nb_channels; j++) {
78 char *xml = iio_channel_get_xml(dev->channels[j],
79 &channels_len[j]);
80 if (!xml)
81 goto err_free_channels;
82 channels[j] = xml;
83 len += channels_len[j];
84 }
85
Paul Cercueild9d9f9f2014-04-15 10:08:17 +020086 debug_attrs_len = malloc(dev->nb_debug_attrs *
87 sizeof(*debug_attrs_len));
88 if (!debug_attrs_len)
89 goto err_free_channels;
90
91 debug_attrs = malloc(dev->nb_debug_attrs * sizeof(*debug_attrs));
92 if (!debug_attrs)
93 goto err_free_debug_attrs_len;
94
95 for (k = 0; k < dev->nb_debug_attrs; k++) {
96 char *xml = get_attr_xml(dev->debug_attrs[k],
97 &debug_attrs_len[k], true);
98 if (!xml)
99 goto err_free_debug_attrs;
100 debug_attrs[k] = xml;
101 len += debug_attrs_len[k];
102 }
103
Paul Cercueil42090d12014-02-24 12:32:23 +0100104 str = malloc(len);
105 if (!str)
Paul Cercueild9d9f9f2014-04-15 10:08:17 +0200106 goto err_free_debug_attrs;
Paul Cercueil42090d12014-02-24 12:32:23 +0100107
Paul Cercueil8c29e412014-04-07 09:46:45 +0200108 snprintf(str, len, "<device id=\"%s\"", dev->id);
Paul Cercueil42090d12014-02-24 12:32:23 +0100109 ptr = strrchr(str, '\0');
110
111 if (dev->name) {
112 sprintf(ptr, " name=\"%s\"", dev->name);
113 ptr = strrchr(ptr, '\0');
114 }
115
116 strcpy(ptr, " >");
117 ptr += 2;
118
119 for (i = 0; i < dev->nb_channels; i++) {
120 strcpy(ptr, channels[i]);
121 ptr += channels_len[i];
122 free(channels[i]);
123 }
124
Paul Cercueil5822ab62014-04-04 13:29:17 +0200125 free(channels);
126 free(channels_len);
127
Paul Cercueil42090d12014-02-24 12:32:23 +0100128 for (i = 0; i < dev->nb_attrs; i++) {
129 strcpy(ptr, attrs[i]);
130 ptr += attrs_len[i];
131 free(attrs[i]);
132 }
133
Paul Cercueil5822ab62014-04-04 13:29:17 +0200134 free(attrs);
135 free(attrs_len);
136
Paul Cercueild9d9f9f2014-04-15 10:08:17 +0200137 for (i = 0; i < dev->nb_debug_attrs; i++) {
138 strcpy(ptr, debug_attrs[i]);
139 ptr += debug_attrs_len[i];
140 free(debug_attrs[i]);
141 }
142
143 free(debug_attrs);
144 free(debug_attrs_len);
145
Paul Cercueil42090d12014-02-24 12:32:23 +0100146 strcpy(ptr, "</device>");
147 *length = ptr - str + sizeof("</device>") - 1;
148 return str;
149
Paul Cercueild9d9f9f2014-04-15 10:08:17 +0200150err_free_debug_attrs:
151 while (k--)
152 free(debug_attrs[k]);
153 free(debug_attrs);
154err_free_debug_attrs_len:
155 free(debug_attrs_len);
Paul Cercueil42090d12014-02-24 12:32:23 +0100156err_free_channels:
157 while (j--)
158 free(channels[j]);
Paul Cercueil5822ab62014-04-04 13:29:17 +0200159 free(channels);
160err_free_channels_len:
161 free(channels_len);
Paul Cercueil42090d12014-02-24 12:32:23 +0100162err_free_attrs:
163 while (i--)
164 free(attrs[i]);
Paul Cercueil5822ab62014-04-04 13:29:17 +0200165 free(attrs);
166err_free_attrs_len:
167 free(attrs_len);
Paul Cercueil42090d12014-02-24 12:32:23 +0100168 return NULL;
169}
Paul Cercueil0b2ce712014-02-17 15:04:18 +0100170
171const char * iio_device_get_id(const struct iio_device *dev)
172{
173 return dev->id;
174}
175
176const char * iio_device_get_name(const struct iio_device *dev)
177{
178 return dev->name;
179}
180
181unsigned int iio_device_get_channels_count(const struct iio_device *dev)
182{
183 return dev->nb_channels;
184}
185
186struct iio_channel * iio_device_get_channel(const struct iio_device *dev,
187 unsigned int index)
188{
189 if (index >= dev->nb_channels)
190 return NULL;
191 else
192 return dev->channels[index];
193}
194
Paul Cercueil17512b02014-03-28 11:15:24 +0100195struct iio_channel * iio_device_find_channel(const struct iio_device *dev,
Paul Cercueil830a7f32014-03-28 13:09:31 +0100196 const char *name, bool output)
Paul Cercueil17512b02014-03-28 11:15:24 +0100197{
198 unsigned int i;
199 for (i = 0; i < dev->nb_channels; i++) {
200 struct iio_channel *chn = dev->channels[i];
Paul Cercueil830a7f32014-03-28 13:09:31 +0100201 if (iio_channel_is_output(chn) != output)
202 continue;
203
Paul Cercueil17512b02014-03-28 11:15:24 +0100204 if (!strcmp(chn->id, name) ||
205 (chn->name && !strcmp(chn->name, name)))
206 return chn;
207 }
208 return NULL;
209}
210
Paul Cercueil0b2ce712014-02-17 15:04:18 +0100211unsigned int iio_device_get_attrs_count(const struct iio_device *dev)
212{
213 return dev->nb_attrs;
214}
215
216const char * iio_device_get_attr(const struct iio_device *dev,
217 unsigned int index)
218{
219 if (index >= dev->nb_attrs)
220 return NULL;
221 else
222 return dev->attrs[index];
223}
224
Paul Cercueil4f838d02014-03-28 11:26:15 +0100225const char * iio_device_find_attr(const struct iio_device *dev,
226 const char *name)
227{
228 unsigned int i;
229 for (i = 0; i < dev->nb_attrs; i++) {
230 const char *attr = dev->attrs[i];
231 if (!strcmp(attr, name))
232 return attr;
233 }
234 return NULL;
235}
236
Paul Cercueil001d2152014-06-03 15:24:44 +0200237const char * iio_device_find_debug_attr(const struct iio_device *dev,
238 const char *name)
239{
240 unsigned int i;
241 for (i = 0; i < dev->nb_debug_attrs; i++) {
242 const char *attr = dev->debug_attrs[i];
243 if (!strcmp(attr, name))
244 return attr;
245 }
246 return NULL;
247}
248
Paul Cercueil3cc3a002014-03-24 13:44:11 +0100249static int iio_device_open_mask(const struct iio_device *dev,
Paul Cercueil71694c72014-05-22 14:02:13 +0200250 size_t samples_count, uint32_t *mask, size_t words, bool cyclic)
Paul Cercueilec1760d2014-02-21 11:31:20 +0100251{
Paul Cercueilaaa8ee02014-03-28 16:43:02 +0100252 unsigned int i;
253 bool has_channels = false;
254
255 for (i = 0; !has_channels && i < words; i++)
256 has_channels = !!mask[i];
257 if (!has_channels)
258 return -EINVAL;
259
Paul Cercueilec1760d2014-02-21 11:31:20 +0100260 if (dev->ctx->ops->open)
Paul Cercueil71694c72014-05-22 14:02:13 +0200261 return dev->ctx->ops->open(dev,
262 samples_count, mask, words, cyclic);
Paul Cercueilec1760d2014-02-21 11:31:20 +0100263 else
264 return -ENOSYS;
265}
266
Paul Cercueil71694c72014-05-22 14:02:13 +0200267int iio_device_open(const struct iio_device *dev,
268 size_t samples_count, bool cyclic)
Paul Cercueile1311222014-03-12 15:46:16 +0100269{
270 size_t nb = (dev->nb_channels + 31) / 32;
271 uint32_t *mask = NULL;
272 unsigned int i;
273 int ret;
274
Paul Cercueilaaa8ee02014-03-28 16:43:02 +0100275 if (nb == 0)
276 return -EINVAL;
277
278 mask = calloc(nb, sizeof(*mask));
279 if (!mask)
280 return -ENOMEM;
Paul Cercueile1311222014-03-12 15:46:16 +0100281
282 for (i = 0; i < dev->nb_channels; i++) {
283 struct iio_channel *chn = dev->channels[i];
284 if (iio_channel_is_enabled(chn) && chn->index >= 0)
285 SET_BIT(mask, chn->index);
286 }
287
Paul Cercueil71694c72014-05-22 14:02:13 +0200288 ret = iio_device_open_mask(dev, samples_count, mask, nb, cyclic);
Paul Cercueile1311222014-03-12 15:46:16 +0100289 free(mask);
290 return ret;
291}
292
Paul Cercueilec1760d2014-02-21 11:31:20 +0100293int iio_device_close(const struct iio_device *dev)
294{
295 if (dev->ctx->ops->close)
296 return dev->ctx->ops->close(dev);
297 else
298 return -ENOSYS;
299}
300
301ssize_t iio_device_read_raw(const struct iio_device *dev,
Paul Cercueil45c575d2014-03-20 15:14:01 +0100302 void *dst, size_t len, uint32_t *mask, size_t words)
Paul Cercueilec1760d2014-02-21 11:31:20 +0100303{
304 if (dev->ctx->ops->read)
Paul Cercueil45c575d2014-03-20 15:14:01 +0100305 return dev->ctx->ops->read(dev, dst, len, mask, words);
Paul Cercueilec1760d2014-02-21 11:31:20 +0100306 else
307 return -ENOSYS;
308}
309
310ssize_t iio_device_write_raw(const struct iio_device *dev,
311 const void *src, size_t len)
312{
313 if (dev->ctx->ops->write)
314 return dev->ctx->ops->write(dev, src, len);
315 else
316 return -ENOSYS;
317}
318
Paul Cercueil0b2ce712014-02-17 15:04:18 +0100319ssize_t iio_device_attr_read(const struct iio_device *dev,
320 const char *attr, char *dst, size_t len)
321{
Paul Cercueil6a013602014-02-19 12:37:39 +0100322 if (dev->ctx->ops->read_device_attr)
Paul Cercueil50c762a2014-04-14 15:55:43 +0200323 return dev->ctx->ops->read_device_attr(dev,
324 attr, dst, len, false);
Paul Cercueil6a013602014-02-19 12:37:39 +0100325 else
326 return -ENOSYS;
Paul Cercueil0b2ce712014-02-17 15:04:18 +0100327}
328
Paul Cercueilcecda352014-05-06 18:14:29 +0200329ssize_t iio_device_attr_write_raw(const struct iio_device *dev,
330 const char *attr, const void *src, size_t len)
Paul Cercueil0b2ce712014-02-17 15:04:18 +0100331{
Paul Cercueil6a013602014-02-19 12:37:39 +0100332 if (dev->ctx->ops->write_device_attr)
Paul Cercueil50c762a2014-04-14 15:55:43 +0200333 return dev->ctx->ops->write_device_attr(dev,
Paul Cercueilcecda352014-05-06 18:14:29 +0200334 attr, src, len, false);
Paul Cercueil6a013602014-02-19 12:37:39 +0100335 else
336 return -ENOSYS;
Paul Cercueil0b2ce712014-02-17 15:04:18 +0100337}
Paul Cercueil00236242014-02-18 15:09:06 +0100338
Paul Cercueilcecda352014-05-06 18:14:29 +0200339ssize_t iio_device_attr_write(const struct iio_device *dev,
340 const char *attr, const char *src)
341{
342 return iio_device_attr_write_raw(dev, attr, src, strlen(src) + 1);
343}
344
Paul Cercueild96e61f2014-03-07 16:13:37 +0100345void iio_device_set_data(struct iio_device *dev, void *data)
346{
347 dev->userdata = data;
348}
349
350void * iio_device_get_data(const struct iio_device *dev)
351{
352 return dev->userdata;
353}
354
Paul Cercueil3156f632014-03-10 11:22:55 +0100355bool iio_device_is_trigger(const struct iio_device *dev)
356{
357 /* A trigger has a name, an id which starts by "trigger",
358 * and zero channels. */
359
360 unsigned int nb = iio_device_get_channels_count(dev);
361 const char *name = iio_device_get_name(dev),
362 *id = iio_device_get_id(dev);
363 return ((nb == 0) && !!name &&
364 !strncmp(id, "trigger", sizeof("trigger") - 1));
365}
366
Paul Cercueil24ffa532014-03-10 12:39:58 +0100367int iio_device_get_trigger(const struct iio_device *dev,
368 const struct iio_device **trigger)
369{
370 if (!trigger)
371 return -EINVAL;
372 else if (dev->ctx->ops->get_trigger)
373 return dev->ctx->ops->get_trigger(dev, trigger);
374 else
375 return -ENOSYS;
376}
377
378int iio_device_set_trigger(const struct iio_device *dev,
379 const struct iio_device *trigger)
380{
381 if (trigger && !iio_device_is_trigger(trigger))
382 return -EINVAL;
383 else if (dev->ctx->ops->set_trigger)
384 return dev->ctx->ops->set_trigger(dev, trigger);
385 else
386 return -ENOSYS;
387}
388
Paul Cercueil00236242014-02-18 15:09:06 +0100389void free_device(struct iio_device *dev)
390{
391 unsigned int i;
392 for (i = 0; i < dev->nb_attrs; i++)
Paul Cercueilddaa26a2014-04-14 17:32:18 +0200393 free(dev->attrs[i]);
Paul Cercueil00236242014-02-18 15:09:06 +0100394 if (dev->nb_attrs)
395 free(dev->attrs);
Paul Cercueilddaa26a2014-04-14 17:32:18 +0200396 for (i = 0; i < dev->nb_debug_attrs; i++)
397 free(dev->debug_attrs[i]);
398 if (dev->nb_debug_attrs)
399 free(dev->debug_attrs);
Paul Cercueil00236242014-02-18 15:09:06 +0100400 for (i = 0; i < dev->nb_channels; i++)
401 free_channel(dev->channels[i]);
402 if (dev->nb_channels)
403 free(dev->channels);
Paul Cercueilff778232014-03-24 14:23:08 +0100404 if (dev->mask)
405 free(dev->mask);
Paul Cercueil00236242014-02-18 15:09:06 +0100406 if (dev->name)
Paul Cercueilddaa26a2014-04-14 17:32:18 +0200407 free(dev->name);
Paul Cercueil00236242014-02-18 15:09:06 +0100408 if (dev->id)
Paul Cercueilddaa26a2014-04-14 17:32:18 +0200409 free(dev->id);
Paul Cercueil00236242014-02-18 15:09:06 +0100410 free(dev);
411}
Paul Cercueil1a474732014-03-17 11:38:34 +0100412
Paul Cercueil645ab972014-03-24 14:36:12 +0100413ssize_t iio_device_get_sample_size_mask(const struct iio_device *dev,
Paul Cercueil1a474732014-03-17 11:38:34 +0100414 uint32_t *mask, size_t words)
415{
416 ssize_t size = 0;
417 unsigned int i;
418
419 if (words != (dev->nb_channels + 31) / 32)
420 return -EINVAL;
421
422 for (i = 0; i < dev->nb_channels; i++) {
423 const struct iio_channel *chn = dev->channels[i];
424 unsigned int length = chn->format.length / 8;
425
426 if (chn->index < 0)
427 break;
428 if (!TEST_BIT(mask, chn->index))
429 continue;
430
431 if (size % length)
432 size += 2 * length - (size % length);
433 else
434 size += length;
435 }
436 return size;
437}
Paul Cercueil46825942014-03-18 14:28:49 +0100438
Paul Cercueil645ab972014-03-24 14:36:12 +0100439ssize_t iio_device_get_sample_size(const struct iio_device *dev)
440{
441 return iio_device_get_sample_size_mask(dev, dev->mask, dev->words);
442}
443
Paul Cercueil3dbd47d2014-03-31 11:19:40 +0200444int iio_device_attr_read_longlong(const struct iio_device *dev,
445 const char *attr, long long *val)
446{
447 char *end, buf[1024];
448 long long value;
449 ssize_t ret = iio_device_attr_read(dev, attr, buf, sizeof(buf));
450 if (ret < 0)
451 return (int) ret;
452
453 value = strtoll(buf, &end, 0);
454 if (end == buf)
455 return -EINVAL;
456 *val = value;
457 return 0;
458}
459
460int iio_device_attr_read_bool(const struct iio_device *dev,
461 const char *attr, bool *val)
462{
463 long long value;
464 int ret = iio_device_attr_read_longlong(dev, attr, &value);
465 if (ret < 0)
466 return ret;
467
468 *val = !!value;
469 return 0;
470}
471
472int iio_device_attr_read_double(const struct iio_device *dev,
473 const char *attr, double *val)
474{
475 char *end, buf[1024];
476 double value;
477 ssize_t ret = iio_device_attr_read(dev, attr, buf, sizeof(buf));
478 if (ret < 0)
479 return (int) ret;
480
481 value = strtod(buf, &end);
482 if (end == buf)
483 return -EINVAL;
484 *val = value;
485 return 0;
486}
487
488int iio_device_attr_write_longlong(const struct iio_device *dev,
489 const char *attr, long long val)
490{
491 char buf[1024];
492 snprintf(buf, sizeof(buf), "%lld", val);
493 return iio_device_attr_write(dev, attr, buf);
494}
495
496int iio_device_attr_write_double(const struct iio_device *dev,
497 const char *attr, double val)
498{
499 char buf[1024];
500 snprintf(buf, sizeof(buf), "%lf", val);
501 return iio_device_attr_write(dev, attr, buf);
502}
503
504int iio_device_attr_write_bool(const struct iio_device *dev,
505 const char *attr, bool val)
506{
507 if (val)
508 return iio_device_attr_write(dev, attr, "1");
509 else
510 return iio_device_attr_write(dev, attr, "0");
511}
Paul Cercueil99b07cc2014-04-14 16:07:32 +0200512
513ssize_t iio_device_debug_attr_read(const struct iio_device *dev,
514 const char *attr, char *dst, size_t len)
515{
516 if (dev->ctx->ops->read_device_attr)
517 return dev->ctx->ops->read_device_attr(dev,
518 attr, dst, len, true);
519 else
520 return -ENOSYS;
521}
522
Paul Cercueilcecda352014-05-06 18:14:29 +0200523ssize_t iio_device_debug_attr_write_raw(const struct iio_device *dev,
524 const char *attr, const void *src, size_t len)
Paul Cercueil99b07cc2014-04-14 16:07:32 +0200525{
526 if (dev->ctx->ops->write_device_attr)
527 return dev->ctx->ops->write_device_attr(dev,
Paul Cercueilcecda352014-05-06 18:14:29 +0200528 attr, src, len, true);
Paul Cercueil99b07cc2014-04-14 16:07:32 +0200529 else
530 return -ENOSYS;
531}
Paul Cercueil1ce35ef2014-04-15 12:28:40 +0200532
Paul Cercueilcecda352014-05-06 18:14:29 +0200533ssize_t iio_device_debug_attr_write(const struct iio_device *dev,
534 const char *attr, const char *src)
535{
536 return iio_device_debug_attr_write_raw(dev, attr, src, strlen(src) + 1);
537}
538
Paul Cercueil1ce35ef2014-04-15 12:28:40 +0200539unsigned int iio_device_get_debug_attrs_count(const struct iio_device *dev)
540{
541 return dev->nb_debug_attrs;
542}
543
544const char * iio_device_get_debug_attr(const struct iio_device *dev,
545 unsigned int index)
546{
547 if (index >= dev->nb_debug_attrs)
548 return NULL;
549 else
550 return dev->debug_attrs[index];
551}
Paul Cercueile3960742014-04-15 16:00:50 +0200552
553int iio_device_debug_attr_read_longlong(const struct iio_device *dev,
554 const char *attr, long long *val)
555{
556 char *end, buf[1024];
557 long long value;
558 ssize_t ret = iio_device_debug_attr_read(dev, attr, buf, sizeof(buf));
559 if (ret < 0)
560 return (int) ret;
561
562 value = strtoll(buf, &end, 0);
563 if (end == buf)
564 return -EINVAL;
565 *val = value;
566 return 0;
567}
568
569int iio_device_debug_attr_read_bool(const struct iio_device *dev,
570 const char *attr, bool *val)
571{
572 long long value;
573 int ret = iio_device_debug_attr_read_longlong(dev, attr, &value);
574 if (ret < 0)
575 return ret;
576
577 *val = !!value;
578 return 0;
579}
580
581int iio_device_debug_attr_read_double(const struct iio_device *dev,
582 const char *attr, double *val)
583{
584 char *end, buf[1024];
585 double value;
586 ssize_t ret = iio_device_debug_attr_read(dev, attr, buf, sizeof(buf));
587 if (ret < 0)
588 return (int) ret;
589
590 value = strtod(buf, &end);
591 if (end == buf)
592 return -EINVAL;
593 *val = value;
594 return 0;
595}
596
597int iio_device_debug_attr_write_longlong(const struct iio_device *dev,
598 const char *attr, long long val)
599{
600 char buf[1024];
601 snprintf(buf, sizeof(buf), "%lld", val);
602 return iio_device_debug_attr_write(dev, attr, buf);
603}
604
605int iio_device_debug_attr_write_double(const struct iio_device *dev,
606 const char *attr, double val)
607{
608 char buf[1024];
609 snprintf(buf, sizeof(buf), "%lf", val);
610 return iio_device_debug_attr_write(dev, attr, buf);
611}
612
613int iio_device_debug_attr_write_bool(const struct iio_device *dev,
614 const char *attr, bool val)
615{
616 if (val)
Paul Cercueilcecda352014-05-06 18:14:29 +0200617 return iio_device_debug_attr_write_raw(dev, attr, "1", 2);
Paul Cercueile3960742014-04-15 16:00:50 +0200618 else
Paul Cercueilcecda352014-05-06 18:14:29 +0200619 return iio_device_debug_attr_write_raw(dev, attr, "0", 2);
Paul Cercueile3960742014-04-15 16:00:50 +0200620}
Paul Cercueil108e0aa2014-05-06 14:45:14 +0200621
622int iio_device_identify_filename(const struct iio_device *dev,
623 const char *filename, struct iio_channel **chn,
624 const char **attr)
625{
626 unsigned int i;
627
628 for (i = 0; i < dev->nb_channels; i++) {
629 struct iio_channel *ch = dev->channels[i];
630 unsigned int j;
631
632 for (j = 0; j < ch->nb_attrs; j++) {
633 if (!strcmp(ch->attrs[j].filename, filename)) {
634 *attr = ch->attrs[j].name;
635 *chn = ch;
636 return 0;
637 }
638 }
639 }
640
641 for (i = 0; i < dev->nb_attrs; i++) {
642 /* Devices attributes are named after their filename */
643 if (!strcmp(dev->attrs[i], filename)) {
644 *attr = dev->attrs[i];
645 *chn = NULL;
646 return 0;
647 }
648 }
649
650 for (i = 0; i < dev->nb_debug_attrs; i++) {
651 if (!strcmp(dev->debug_attrs[i], filename)) {
652 *attr = dev->debug_attrs[i];
653 *chn = NULL;
654 return 0;
655 }
656 }
657
658 return -EINVAL;
659}
Paul Cercueil14405872014-05-07 14:00:32 +0200660
661int iio_device_reg_write(struct iio_device *dev,
662 uint32_t address, uint32_t value)
663{
664 char buf[1024];
665 snprintf(buf, sizeof(buf), "0x%x 0x%x", address, value);
666 return iio_device_debug_attr_write(dev, "direct_reg_access", buf);
667}
668
669int iio_device_reg_read(struct iio_device *dev,
670 uint32_t address, uint32_t *value)
671{
672 /* NOTE: There is a race condition here. But it is extremely unlikely to
673 * happen, and as this is a debug function, it shouldn't be used for
674 * something else than debug. */
675
676 long long val;
677 int ret = iio_device_debug_attr_write_longlong(dev,
678 "direct_reg_access", (long long) address);
679 if (ret < 0)
680 return ret;
681
682 ret = iio_device_debug_attr_read_longlong(dev,
683 "direct_reg_access", &val);
684 if (!ret)
685 *value = (uint32_t) val;
686 return ret;
687}