• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
19 #include "debug.h"
20 #include "iio-private.h"
21 
22 #include <inttypes.h>
23 #include <errno.h>
24 #include <stdio.h>
25 #include <string.h>
26 
get_attr_xml(const char * attr,size_t * length,enum iio_attr_type type)27 static char *get_attr_xml(const char *attr, size_t *length, enum iio_attr_type type)
28 {
29 	size_t len = sizeof("<attribute name=\"\" />") + strlen(attr);
30 	char *str;
31 
32 	switch(type){
33 		case IIO_ATTR_TYPE_DEVICE:
34 			break;
35 		case IIO_ATTR_TYPE_DEBUG:
36 			len += (sizeof("debug-") - 1);
37 			break;
38 		case IIO_ATTR_TYPE_BUFFER:
39 			len += (sizeof("buffer-") - 1);
40 			break;
41 		default:
42 			return NULL;
43 	}
44 
45 	str = malloc(len);
46 	if (!str)
47 		return NULL;
48 
49 	*length = len - 1; /* Skip the \0 */
50 	switch (type) {
51 		case IIO_ATTR_TYPE_DEVICE:
52 			iio_snprintf(str, len, "<attribute name=\"%s\" />", attr);
53 			break;
54 		case IIO_ATTR_TYPE_DEBUG:
55 			iio_snprintf(str, len, "<debug-attribute name=\"%s\" />", attr);
56 			break;
57 		case IIO_ATTR_TYPE_BUFFER:
58 			iio_snprintf(str, len, "<buffer-attribute name=\"%s\" />", attr);
59 			break;
60 	}
61 
62 	return str;
63 }
64 
65 /* Returns a string containing the XML representation of this device */
iio_device_get_xml(const struct iio_device * dev,size_t * length)66 char * iio_device_get_xml(const struct iio_device *dev, size_t *length)
67 {
68 	size_t len = sizeof("<device id=\"\" name=\"\" ></device>")
69 		+ strlen(dev->id) + (dev->name ? strlen(dev->name) : 0);
70 	char *ptr, *str, **attrs, **channels, **buffer_attrs, **debug_attrs;
71 	size_t *attrs_len, *channels_len, *buffer_attrs_len, *debug_attrs_len;
72 	unsigned int i, j, k;
73 
74 	attrs_len = malloc(dev->nb_attrs * sizeof(*attrs_len));
75 	if (!attrs_len)
76 		return NULL;
77 
78 	attrs = malloc(dev->nb_attrs * sizeof(*attrs));
79 	if (!attrs)
80 		goto err_free_attrs_len;
81 
82 	for (i = 0; i < dev->nb_attrs; i++) {
83 		char *xml = get_attr_xml(dev->attrs[i], &attrs_len[i], IIO_ATTR_TYPE_DEVICE);
84 		if (!xml)
85 			goto err_free_attrs;
86 		attrs[i] = xml;
87 		len += attrs_len[i];
88 	}
89 
90 	channels_len = malloc(dev->nb_channels * sizeof(*channels_len));
91 	if (!channels_len)
92 		goto err_free_attrs;
93 
94 	channels = malloc(dev->nb_channels * sizeof(*channels));
95 	if (!channels)
96 		goto err_free_channels_len;
97 
98 	for (j = 0; j < dev->nb_channels; j++) {
99 		char *xml = iio_channel_get_xml(dev->channels[j],
100 				&channels_len[j]);
101 		if (!xml)
102 			goto err_free_channels;
103 		channels[j] = xml;
104 		len += channels_len[j];
105 	}
106 
107 	buffer_attrs_len = malloc(dev->nb_buffer_attrs *
108 			sizeof(*buffer_attrs_len));
109 	if (!buffer_attrs_len)
110 		goto err_free_channels;
111 
112 	buffer_attrs = malloc(dev->nb_buffer_attrs * sizeof(*buffer_attrs));
113 	if (!buffer_attrs)
114 		goto err_free_buffer_attrs_len;
115 
116 	for (k = 0; k < dev->nb_buffer_attrs; k++) {
117 		char *xml = get_attr_xml(dev->buffer_attrs[k],
118 				&buffer_attrs_len[k], IIO_ATTR_TYPE_BUFFER);
119 		if (!xml)
120 			goto err_free_buffer_attrs;
121 		buffer_attrs[k] = xml;
122 		len += buffer_attrs_len[k];
123 	}
124 
125 	debug_attrs_len = malloc(dev->nb_debug_attrs *
126 			sizeof(*debug_attrs_len));
127 	if (!debug_attrs_len)
128 		goto err_free_buffer_attrs;
129 
130 	debug_attrs = malloc(dev->nb_debug_attrs * sizeof(*debug_attrs));
131 	if (!debug_attrs)
132 		goto err_free_debug_attrs_len;
133 
134 	for (k = 0; k < dev->nb_debug_attrs; k++) {
135 		char *xml = get_attr_xml(dev->debug_attrs[k],
136 				&debug_attrs_len[k], IIO_ATTR_TYPE_DEBUG);
137 		if (!xml)
138 			goto err_free_debug_attrs;
139 		debug_attrs[k] = xml;
140 		len += debug_attrs_len[k];
141 	}
142 
143 	str = malloc(len);
144 	if (!str)
145 		goto err_free_debug_attrs;
146 
147 	iio_snprintf(str, len, "<device id=\"%s\"", dev->id);
148 	ptr = strrchr(str, '\0');
149 
150 	if (dev->name) {
151 		sprintf(ptr, " name=\"%s\"", dev->name);
152 		ptr = strrchr(ptr, '\0');
153 	}
154 
155 	strcpy(ptr, " >");
156 	ptr += 2;
157 
158 	for (i = 0; i < dev->nb_channels; i++) {
159 		strcpy(ptr, channels[i]);
160 		ptr += channels_len[i];
161 		free(channels[i]);
162 	}
163 
164 	free(channels);
165 	free(channels_len);
166 
167 	for (i = 0; i < dev->nb_attrs; i++) {
168 		strcpy(ptr, attrs[i]);
169 		ptr += attrs_len[i];
170 		free(attrs[i]);
171 	}
172 
173 	free(attrs);
174 	free(attrs_len);
175 
176 	for (i = 0; i < dev->nb_buffer_attrs; i++) {
177 		strcpy(ptr, buffer_attrs[i]);
178 		ptr += buffer_attrs_len[i];
179 		free(buffer_attrs[i]);
180 	}
181 
182 	free(buffer_attrs);
183 	free(buffer_attrs_len);
184 
185 	for (i = 0; i < dev->nb_debug_attrs; i++) {
186 		strcpy(ptr, debug_attrs[i]);
187 		ptr += debug_attrs_len[i];
188 		free(debug_attrs[i]);
189 	}
190 
191 	free(debug_attrs);
192 	free(debug_attrs_len);
193 
194 	strcpy(ptr, "</device>");
195 	*length = ptr - str + sizeof("</device>") - 1;
196 	return str;
197 
198 err_free_debug_attrs:
199 	while (k--)
200 		free(debug_attrs[k]);
201 	free(debug_attrs);
202 err_free_debug_attrs_len:
203 	free(debug_attrs_len);
204 err_free_buffer_attrs:
205 	while (k--)
206 		free(buffer_attrs[k]);
207 	free(buffer_attrs);
208 err_free_buffer_attrs_len:
209 	free(buffer_attrs_len);
210 err_free_channels:
211 	while (j--)
212 		free(channels[j]);
213 	free(channels);
214 err_free_channels_len:
215 	free(channels_len);
216 err_free_attrs:
217 	while (i--)
218 		free(attrs[i]);
219 	free(attrs);
220 err_free_attrs_len:
221 	free(attrs_len);
222 	return NULL;
223 }
224 
iio_device_get_id(const struct iio_device * dev)225 const char * iio_device_get_id(const struct iio_device *dev)
226 {
227 	return dev->id;
228 }
229 
iio_device_get_name(const struct iio_device * dev)230 const char * iio_device_get_name(const struct iio_device *dev)
231 {
232 	return dev->name;
233 }
234 
iio_device_get_channels_count(const struct iio_device * dev)235 unsigned int iio_device_get_channels_count(const struct iio_device *dev)
236 {
237 	return dev->nb_channels;
238 }
239 
iio_device_get_channel(const struct iio_device * dev,unsigned int index)240 struct iio_channel * iio_device_get_channel(const struct iio_device *dev,
241 		unsigned int index)
242 {
243 	if (index >= dev->nb_channels)
244 		return NULL;
245 	else
246 		return dev->channels[index];
247 }
248 
iio_device_find_channel(const struct iio_device * dev,const char * name,bool output)249 struct iio_channel * iio_device_find_channel(const struct iio_device *dev,
250 		const char *name, bool output)
251 {
252 	unsigned int i;
253 	for (i = 0; i < dev->nb_channels; i++) {
254 		struct iio_channel *chn = dev->channels[i];
255 		if (iio_channel_is_output(chn) != output)
256 			continue;
257 
258 		if (!strcmp(chn->id, name) ||
259 				(chn->name && !strcmp(chn->name, name)))
260 			return chn;
261 	}
262 	return NULL;
263 }
264 
iio_device_get_attrs_count(const struct iio_device * dev)265 unsigned int iio_device_get_attrs_count(const struct iio_device *dev)
266 {
267 	return dev->nb_attrs;
268 }
269 
iio_device_get_attr(const struct iio_device * dev,unsigned int index)270 const char * iio_device_get_attr(const struct iio_device *dev,
271 		unsigned int index)
272 {
273 	if (index >= dev->nb_attrs)
274 		return NULL;
275 	else
276 		return dev->attrs[index];
277 }
278 
iio_device_find_attr(const struct iio_device * dev,const char * name)279 const char * iio_device_find_attr(const struct iio_device *dev,
280 		const char *name)
281 {
282 	unsigned int i;
283 	for (i = 0; i < dev->nb_attrs; i++) {
284 		const char *attr = dev->attrs[i];
285 		if (!strcmp(attr, name))
286 			return attr;
287 	}
288 	return NULL;
289 }
290 
iio_device_get_buffer_attrs_count(const struct iio_device * dev)291 unsigned int iio_device_get_buffer_attrs_count(const struct iio_device *dev)
292 {
293 	return dev->nb_buffer_attrs;
294 }
295 
iio_device_get_buffer_attr(const struct iio_device * dev,unsigned int index)296 const char * iio_device_get_buffer_attr(const struct iio_device *dev,
297 		unsigned int index)
298 {
299 	if (index >= dev->nb_buffer_attrs)
300 		return NULL;
301 	else
302 		return dev->buffer_attrs[index];
303 }
304 
iio_device_find_buffer_attr(const struct iio_device * dev,const char * name)305 const char * iio_device_find_buffer_attr(const struct iio_device *dev,
306 		const char *name)
307 {
308 	unsigned int i;
309 	for (i = 0; i < dev->nb_buffer_attrs; i++) {
310 		const char *attr = dev->buffer_attrs[i];
311 		if (!strcmp(attr, name))
312 			return attr;
313 	}
314 	return NULL;
315 }
316 
iio_device_find_debug_attr(const struct iio_device * dev,const char * name)317 const char * iio_device_find_debug_attr(const struct iio_device *dev,
318 		const char *name)
319 {
320 	unsigned int i;
321 	for (i = 0; i < dev->nb_debug_attrs; i++) {
322 		const char *attr = dev->debug_attrs[i];
323 		if (!strcmp(attr, name))
324 			return attr;
325 	}
326 	return NULL;
327 }
328 
iio_device_is_tx(const struct iio_device * dev)329 bool iio_device_is_tx(const struct iio_device *dev)
330 {
331 	unsigned int i;
332 
333 	for (i = 0; i < dev->nb_channels; i++) {
334 		struct iio_channel *ch = dev->channels[i];
335 		if (iio_channel_is_output(ch) && iio_channel_is_enabled(ch))
336 			return true;
337 	}
338 
339 	return false;
340 }
341 
iio_device_open(const struct iio_device * dev,size_t samples_count,bool cyclic)342 int iio_device_open(const struct iio_device *dev,
343 		size_t samples_count, bool cyclic)
344 {
345 	unsigned int i;
346 	bool has_channels = false;
347 
348 	for (i = 0; !has_channels && i < dev->words; i++)
349 		has_channels = !!dev->mask[i];
350 	if (!has_channels)
351 		return -EINVAL;
352 
353 	if (dev->ctx->ops->open)
354 		return dev->ctx->ops->open(dev, samples_count, cyclic);
355 	else
356 		return -ENOSYS;
357 }
358 
iio_device_close(const struct iio_device * dev)359 int iio_device_close(const struct iio_device *dev)
360 {
361 	if (dev->ctx->ops->close)
362 		return dev->ctx->ops->close(dev);
363 	else
364 		return -ENOSYS;
365 }
366 
iio_device_get_poll_fd(const struct iio_device * dev)367 int iio_device_get_poll_fd(const struct iio_device *dev)
368 {
369 	if (dev->ctx->ops->get_fd)
370 		return dev->ctx->ops->get_fd(dev);
371 	else
372 		return -ENOSYS;
373 }
374 
iio_device_set_blocking_mode(const struct iio_device * dev,bool blocking)375 int iio_device_set_blocking_mode(const struct iio_device *dev, bool blocking)
376 {
377 	if (dev->ctx->ops->set_blocking_mode)
378 		return dev->ctx->ops->set_blocking_mode(dev, blocking);
379 	else
380 		return -ENOSYS;
381 }
382 
iio_device_read_raw(const struct iio_device * dev,void * dst,size_t len,uint32_t * mask,size_t words)383 ssize_t iio_device_read_raw(const struct iio_device *dev,
384 		void *dst, size_t len, uint32_t *mask, size_t words)
385 {
386 	if (dev->ctx->ops->read)
387 		return dev->ctx->ops->read(dev, dst, len, mask, words);
388 	else
389 		return -ENOSYS;
390 }
391 
iio_device_write_raw(const struct iio_device * dev,const void * src,size_t len)392 ssize_t iio_device_write_raw(const struct iio_device *dev,
393 		const void *src, size_t len)
394 {
395 	if (dev->ctx->ops->write)
396 		return dev->ctx->ops->write(dev, src, len);
397 	else
398 		return -ENOSYS;
399 }
400 
iio_device_attr_read(const struct iio_device * dev,const char * attr,char * dst,size_t len)401 ssize_t iio_device_attr_read(const struct iio_device *dev,
402 		const char *attr, char *dst, size_t len)
403 {
404 	if (dev->ctx->ops->read_device_attr)
405 		return dev->ctx->ops->read_device_attr(dev,
406 				attr, dst, len, IIO_ATTR_TYPE_DEVICE);
407 	else
408 		return -ENOSYS;
409 }
410 
iio_device_attr_write_raw(const struct iio_device * dev,const char * attr,const void * src,size_t len)411 ssize_t iio_device_attr_write_raw(const struct iio_device *dev,
412 		const char *attr, const void *src, size_t len)
413 {
414 	if (dev->ctx->ops->write_device_attr)
415 		return dev->ctx->ops->write_device_attr(dev,
416 				attr, src, len, IIO_ATTR_TYPE_DEVICE);
417 	else
418 		return -ENOSYS;
419 }
420 
iio_device_attr_write(const struct iio_device * dev,const char * attr,const char * src)421 ssize_t iio_device_attr_write(const struct iio_device *dev,
422 		const char *attr, const char *src)
423 {
424 	return iio_device_attr_write_raw(dev, attr, src, strlen(src) + 1);
425 }
426 
iio_device_buffer_attr_read(const struct iio_device * dev,const char * attr,char * dst,size_t len)427 ssize_t iio_device_buffer_attr_read(const struct iio_device *dev,
428 		const char *attr, char *dst, size_t len)
429 {
430 	if (dev->ctx->ops->read_device_attr)
431 		return dev->ctx->ops->read_device_attr(dev,
432 				attr, dst, len, IIO_ATTR_TYPE_BUFFER);
433 	else
434 		return -ENOSYS;
435 }
436 
iio_device_buffer_attr_write_raw(const struct iio_device * dev,const char * attr,const void * src,size_t len)437 ssize_t iio_device_buffer_attr_write_raw(const struct iio_device *dev,
438 		const char *attr, const void *src, size_t len)
439 {
440 	if (dev->ctx->ops->write_device_attr)
441 		return dev->ctx->ops->write_device_attr(dev,
442 				attr, src, len, IIO_ATTR_TYPE_BUFFER);
443 	else
444 		return -ENOSYS;
445 }
446 
iio_device_buffer_attr_write(const struct iio_device * dev,const char * attr,const char * src)447 ssize_t iio_device_buffer_attr_write(const struct iio_device *dev,
448 		const char *attr, const char *src)
449 {
450 	return iio_device_buffer_attr_write_raw(dev, attr, src, strlen(src) + 1);
451 }
452 
iio_device_set_data(struct iio_device * dev,void * data)453 void iio_device_set_data(struct iio_device *dev, void *data)
454 {
455 	dev->userdata = data;
456 }
457 
iio_device_get_data(const struct iio_device * dev)458 void * iio_device_get_data(const struct iio_device *dev)
459 {
460 	return dev->userdata;
461 }
462 
iio_device_is_trigger(const struct iio_device * dev)463 bool iio_device_is_trigger(const struct iio_device *dev)
464 {
465 	/* A trigger has a name, an id which starts by "trigger",
466 	 * and zero channels. */
467 
468 	unsigned int nb = iio_device_get_channels_count(dev);
469 	const char *name = iio_device_get_name(dev),
470 	      *id = iio_device_get_id(dev);
471 	return ((nb == 0) && !!name &&
472 		!strncmp(id, "trigger", sizeof("trigger") - 1));
473 }
474 
iio_device_set_kernel_buffers_count(const struct iio_device * dev,unsigned int nb_buffers)475 int iio_device_set_kernel_buffers_count(const struct iio_device *dev,
476 		unsigned int nb_buffers)
477 {
478 	if (nb_buffers == 0)
479 		return -EINVAL;
480 	else if (dev->ctx->ops->set_kernel_buffers_count)
481 		return dev->ctx->ops->set_kernel_buffers_count(dev, nb_buffers);
482 	else
483 		return -ENOSYS;
484 }
485 
iio_device_get_trigger(const struct iio_device * dev,const struct iio_device ** trigger)486 int iio_device_get_trigger(const struct iio_device *dev,
487 		const struct iio_device **trigger)
488 {
489 	if (!trigger)
490 		return -EINVAL;
491 	else if (dev->ctx->ops->get_trigger)
492 		return dev->ctx->ops->get_trigger(dev, trigger);
493 	else
494 		return -ENOSYS;
495 }
496 
iio_device_set_trigger(const struct iio_device * dev,const struct iio_device * trigger)497 int iio_device_set_trigger(const struct iio_device *dev,
498 		const struct iio_device *trigger)
499 {
500 	if (trigger && !iio_device_is_trigger(trigger))
501 		return -EINVAL;
502 	else if (dev->ctx->ops->set_trigger)
503 		return dev->ctx->ops->set_trigger(dev, trigger);
504 	else
505 		return -ENOSYS;
506 }
507 
free_device(struct iio_device * dev)508 void free_device(struct iio_device *dev)
509 {
510 	unsigned int i;
511 	for (i = 0; i < dev->nb_attrs; i++)
512 		free(dev->attrs[i]);
513 	if (dev->nb_attrs)
514 		free(dev->attrs);
515 	for (i = 0; i < dev->nb_buffer_attrs; i++)
516 		free(dev->buffer_attrs[i]);
517 	if (dev->nb_buffer_attrs)
518 		free(dev->buffer_attrs);
519 	for (i = 0; i < dev->nb_debug_attrs; i++)
520 		free(dev->debug_attrs[i]);
521 	if (dev->nb_debug_attrs)
522 		free(dev->debug_attrs);
523 	for (i = 0; i < dev->nb_channels; i++)
524 		free_channel(dev->channels[i]);
525 	if (dev->nb_channels)
526 		free(dev->channels);
527 	if (dev->mask)
528 		free(dev->mask);
529 	if (dev->name)
530 		free(dev->name);
531 	if (dev->id)
532 		free(dev->id);
533 	free(dev);
534 }
535 
iio_device_get_sample_size_mask(const struct iio_device * dev,const uint32_t * mask,size_t words)536 ssize_t iio_device_get_sample_size_mask(const struct iio_device *dev,
537 		const uint32_t *mask, size_t words)
538 {
539 	ssize_t size = 0;
540 	unsigned int i;
541 	const struct iio_channel *prev = NULL;
542 
543 	if (words != (dev->nb_channels + 31) / 32)
544 		return -EINVAL;
545 
546 	for (i = 0; i < dev->nb_channels; i++) {
547 		const struct iio_channel *chn = dev->channels[i];
548 		unsigned int length = chn->format.length / 8 *
549 			chn->format.repeat;
550 
551 		if (chn->index < 0)
552 			break;
553 		if (!TEST_BIT(mask, chn->number))
554 			continue;
555 
556 		if (prev && chn->index == prev->index) {
557 			prev = chn;
558 			continue;
559 		}
560 
561 		if (size % length)
562 			size += 2 * length - (size % length);
563 		else
564 			size += length;
565 
566 		prev = chn;
567 	}
568 	return size;
569 }
570 
iio_device_get_sample_size(const struct iio_device * dev)571 ssize_t iio_device_get_sample_size(const struct iio_device *dev)
572 {
573 	return iio_device_get_sample_size_mask(dev, dev->mask, dev->words);
574 }
575 
iio_device_attr_read_longlong(const struct iio_device * dev,const char * attr,long long * val)576 int iio_device_attr_read_longlong(const struct iio_device *dev,
577 		const char *attr, long long *val)
578 {
579 	char *end, buf[1024];
580 	long long value;
581 	ssize_t ret = iio_device_attr_read(dev, attr, buf, sizeof(buf));
582 	if (ret < 0)
583 		return (int) ret;
584 
585 	value = strtoll(buf, &end, 0);
586 	if (end == buf)
587 		return -EINVAL;
588 	*val = value;
589 	return 0;
590 }
591 
iio_device_attr_read_bool(const struct iio_device * dev,const char * attr,bool * val)592 int iio_device_attr_read_bool(const struct iio_device *dev,
593 		const char *attr, bool *val)
594 {
595 	long long value;
596 	int ret = iio_device_attr_read_longlong(dev, attr, &value);
597 	if (ret < 0)
598 		return ret;
599 
600 	*val = !!value;
601 	return 0;
602 }
603 
iio_device_attr_read_double(const struct iio_device * dev,const char * attr,double * val)604 int iio_device_attr_read_double(const struct iio_device *dev,
605 		const char *attr, double *val)
606 {
607 	char buf[1024];
608 	ssize_t ret = iio_device_attr_read(dev, attr, buf, sizeof(buf));
609 	if (ret < 0)
610 		return (int) ret;
611 	else
612 		return read_double(buf, val);
613 }
614 
iio_device_attr_write_longlong(const struct iio_device * dev,const char * attr,long long val)615 int iio_device_attr_write_longlong(const struct iio_device *dev,
616 		const char *attr, long long val)
617 {
618 	ssize_t ret;
619 	char buf[1024];
620 
621 	iio_snprintf(buf, sizeof(buf), "%lld", val);
622 	ret = iio_device_attr_write(dev, attr, buf);
623 
624 	return ret < 0 ? ret : 0;
625 }
626 
iio_device_attr_write_double(const struct iio_device * dev,const char * attr,double val)627 int iio_device_attr_write_double(const struct iio_device *dev,
628 		const char *attr, double val)
629 {
630 	ssize_t ret;
631 	char buf[1024];
632 
633 	ret = (ssize_t) write_double(buf, sizeof(buf), val);
634 	if (!ret)
635 		ret = iio_device_attr_write(dev, attr, buf);
636 	return ret < 0 ? ret : 0;
637 }
638 
iio_device_attr_write_bool(const struct iio_device * dev,const char * attr,bool val)639 int iio_device_attr_write_bool(const struct iio_device *dev,
640 		const char *attr, bool val)
641 {
642 	ssize_t ret;
643 
644 	if (val)
645 		ret = iio_device_attr_write(dev, attr, "1");
646 	else
647 		ret = iio_device_attr_write(dev, attr, "0");
648 
649 	return ret < 0 ? ret : 0;
650 }
651 
iio_device_buffer_attr_read_longlong(const struct iio_device * dev,const char * attr,long long * val)652 int iio_device_buffer_attr_read_longlong(const struct iio_device *dev,
653 		const char *attr, long long *val)
654 {
655 	char *end, buf[1024];
656 	long long value;
657 	ssize_t ret = iio_device_buffer_attr_read(dev, attr, buf, sizeof(buf));
658 	if (ret < 0)
659 		return (int) ret;
660 
661 	value = strtoll(buf, &end, 0);
662 	if (end == buf)
663 		return -EINVAL;
664 	*val = value;
665 	return 0;
666 }
667 
iio_device_buffer_attr_read_bool(const struct iio_device * dev,const char * attr,bool * val)668 int iio_device_buffer_attr_read_bool(const struct iio_device *dev,
669 		const char *attr, bool *val)
670 {
671 	long long value;
672 	int ret = iio_device_buffer_attr_read_longlong(dev, attr, &value);
673 	if (ret < 0)
674 		return ret;
675 
676 	*val = !!value;
677 	return 0;
678 }
679 
iio_device_buffer_attr_read_double(const struct iio_device * dev,const char * attr,double * val)680 int iio_device_buffer_attr_read_double(const struct iio_device *dev,
681 		const char *attr, double *val)
682 {
683 	char buf[1024];
684 	ssize_t ret = iio_device_buffer_attr_read(dev, attr, buf, sizeof(buf));
685 	if (ret < 0)
686 		return (int) ret;
687 	else
688 		return read_double(buf, val);
689 }
690 
iio_device_buffer_attr_write_longlong(const struct iio_device * dev,const char * attr,long long val)691 int iio_device_buffer_attr_write_longlong(const struct iio_device *dev,
692 		const char *attr, long long val)
693 {
694 	ssize_t ret;
695 	char buf[1024];
696 
697 	iio_snprintf(buf, sizeof(buf), "%lld", val);
698 	ret = iio_device_buffer_attr_write(dev, attr, buf);
699 
700 	return ret < 0 ? ret : 0;
701 }
702 
iio_device_buffer_attr_write_double(const struct iio_device * dev,const char * attr,double val)703 int iio_device_buffer_attr_write_double(const struct iio_device *dev,
704 		const char *attr, double val)
705 {
706 	ssize_t ret;
707 	char buf[1024];
708 
709 	ret = (ssize_t) write_double(buf, sizeof(buf), val);
710 	if (!ret)
711 		ret = iio_device_buffer_attr_write(dev, attr, buf);
712 	return ret < 0 ? ret : 0;
713 }
714 
iio_device_buffer_attr_write_bool(const struct iio_device * dev,const char * attr,bool val)715 int iio_device_buffer_attr_write_bool(const struct iio_device *dev,
716 		const char *attr, bool val)
717 {
718 	ssize_t ret;
719 
720 	if (val)
721 		ret = iio_device_buffer_attr_write(dev, attr, "1");
722 	else
723 		ret = iio_device_buffer_attr_write(dev, attr, "0");
724 
725 	return ret < 0 ? ret : 0;
726 }
727 
iio_device_debug_attr_read(const struct iio_device * dev,const char * attr,char * dst,size_t len)728 ssize_t iio_device_debug_attr_read(const struct iio_device *dev,
729 		const char *attr, char *dst, size_t len)
730 {
731 	if (dev->ctx->ops->read_device_attr)
732 		return dev->ctx->ops->read_device_attr(dev,
733 				attr, dst, len, IIO_ATTR_TYPE_DEBUG);
734 	else
735 		return -ENOSYS;
736 }
737 
iio_device_debug_attr_write_raw(const struct iio_device * dev,const char * attr,const void * src,size_t len)738 ssize_t iio_device_debug_attr_write_raw(const struct iio_device *dev,
739 		const char *attr, const void *src, size_t len)
740 {
741 	if (dev->ctx->ops->write_device_attr)
742 		return dev->ctx->ops->write_device_attr(dev,
743 				attr, src, len, IIO_ATTR_TYPE_DEBUG);
744 	else
745 		return -ENOSYS;
746 }
747 
iio_device_debug_attr_write(const struct iio_device * dev,const char * attr,const char * src)748 ssize_t iio_device_debug_attr_write(const struct iio_device *dev,
749 		const char *attr, const char *src)
750 {
751 	return iio_device_debug_attr_write_raw(dev, attr, src, strlen(src) + 1);
752 }
753 
iio_device_get_debug_attrs_count(const struct iio_device * dev)754 unsigned int iio_device_get_debug_attrs_count(const struct iio_device *dev)
755 {
756 	return dev->nb_debug_attrs;
757 }
758 
iio_device_get_debug_attr(const struct iio_device * dev,unsigned int index)759 const char * iio_device_get_debug_attr(const struct iio_device *dev,
760 		unsigned int index)
761 {
762 	if (index >= dev->nb_debug_attrs)
763 		return NULL;
764 	else
765 		return dev->debug_attrs[index];
766 }
767 
iio_device_debug_attr_read_longlong(const struct iio_device * dev,const char * attr,long long * val)768 int iio_device_debug_attr_read_longlong(const struct iio_device *dev,
769 		const char *attr, long long *val)
770 {
771 	char *end, buf[1024];
772 	long long value;
773 	ssize_t ret = iio_device_debug_attr_read(dev, attr, buf, sizeof(buf));
774 	if (ret < 0)
775 		return (int) ret;
776 
777 	value = strtoll(buf, &end, 0);
778 	if (end == buf)
779 		return -EINVAL;
780 	*val = value;
781 	return 0;
782 }
783 
iio_device_debug_attr_read_bool(const struct iio_device * dev,const char * attr,bool * val)784 int iio_device_debug_attr_read_bool(const struct iio_device *dev,
785 		const char *attr, bool *val)
786 {
787 	long long value;
788 	int ret = iio_device_debug_attr_read_longlong(dev, attr, &value);
789 	if (ret < 0)
790 		return ret;
791 
792 	*val = !!value;
793 	return 0;
794 }
795 
iio_device_debug_attr_read_double(const struct iio_device * dev,const char * attr,double * val)796 int iio_device_debug_attr_read_double(const struct iio_device *dev,
797 		const char *attr, double *val)
798 {
799 	char buf[1024];
800 	ssize_t ret = iio_device_debug_attr_read(dev, attr, buf, sizeof(buf));
801 	if (ret < 0)
802 		return (int) ret;
803 	else
804 		return read_double(buf, val);
805 }
806 
iio_device_debug_attr_write_longlong(const struct iio_device * dev,const char * attr,long long val)807 int iio_device_debug_attr_write_longlong(const struct iio_device *dev,
808 		const char *attr, long long val)
809 {
810 	ssize_t ret;
811 	char buf[1024];
812 
813 	iio_snprintf(buf, sizeof(buf), "%lld", val);
814 	ret = iio_device_debug_attr_write(dev, attr, buf);
815 
816 	return ret < 0 ? ret : 0;
817 }
818 
iio_device_debug_attr_write_double(const struct iio_device * dev,const char * attr,double val)819 int iio_device_debug_attr_write_double(const struct iio_device *dev,
820 		const char *attr, double val)
821 {
822 	ssize_t ret;
823 	char buf[1024];
824 
825 	ret = (ssize_t) write_double(buf, sizeof(buf), val);
826 	if (!ret)
827 		ret = iio_device_debug_attr_write(dev, attr, buf);
828 	return ret < 0 ? ret : 0;
829 }
830 
iio_device_debug_attr_write_bool(const struct iio_device * dev,const char * attr,bool val)831 int iio_device_debug_attr_write_bool(const struct iio_device *dev,
832 		const char *attr, bool val)
833 {
834 	ssize_t ret;
835 
836 	if (val)
837 		ret = iio_device_debug_attr_write_raw(dev, attr, "1", 2);
838 	else
839 		ret = iio_device_debug_attr_write_raw(dev, attr, "0", 2);
840 
841 	return ret < 0 ? ret : 0;
842 }
843 
iio_device_identify_filename(const struct iio_device * dev,const char * filename,struct iio_channel ** chn,const char ** attr)844 int iio_device_identify_filename(const struct iio_device *dev,
845 		const char *filename, struct iio_channel **chn,
846 		const char **attr)
847 {
848 	unsigned int i;
849 
850 	for (i = 0; i < dev->nb_channels; i++) {
851 		struct iio_channel *ch = dev->channels[i];
852 		unsigned int j;
853 
854 		for (j = 0; j < ch->nb_attrs; j++) {
855 			if (!strcmp(ch->attrs[j].filename, filename)) {
856 				*attr = ch->attrs[j].name;
857 				*chn = ch;
858 				return 0;
859 			}
860 		}
861 	}
862 
863 	for (i = 0; i < dev->nb_attrs; i++) {
864 		/* Devices attributes are named after their filename */
865 		if (!strcmp(dev->attrs[i], filename)) {
866 			*attr = dev->attrs[i];
867 			*chn = NULL;
868 			return 0;
869 		}
870 	}
871 
872 	for (i = 0; i < dev->nb_debug_attrs; i++) {
873 		if (!strcmp(dev->debug_attrs[i], filename)) {
874 			*attr = dev->debug_attrs[i];
875 			*chn = NULL;
876 			return 0;
877 		}
878 	}
879 
880 	return -EINVAL;
881 }
882 
iio_device_reg_write(struct iio_device * dev,uint32_t address,uint32_t value)883 int iio_device_reg_write(struct iio_device *dev,
884 		uint32_t address, uint32_t value)
885 {
886 	ssize_t ret;
887 	char buf[1024];
888 
889 	iio_snprintf(buf, sizeof(buf), "0x%" PRIx32 " 0x%" PRIx32,
890 			address, value);
891 	ret = iio_device_debug_attr_write(dev, "direct_reg_access", buf);
892 
893 	return ret < 0 ? ret : 0;
894 }
895 
iio_device_reg_read(struct iio_device * dev,uint32_t address,uint32_t * value)896 int iio_device_reg_read(struct iio_device *dev,
897 		uint32_t address, uint32_t *value)
898 {
899 	/* NOTE: There is a race condition here. But it is extremely unlikely to
900 	 * happen, and as this is a debug function, it shouldn't be used for
901 	 * something else than debug. */
902 
903 	long long val;
904 	int ret = iio_device_debug_attr_write_longlong(dev,
905 			"direct_reg_access", (long long) address);
906 	if (ret < 0)
907 		return ret;
908 
909 	ret = iio_device_debug_attr_read_longlong(dev,
910 			"direct_reg_access", &val);
911 	if (!ret)
912 		*value = (uint32_t) val;
913 	return ret;
914 }
915 
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)916 static int read_each_attr(struct iio_device *dev, enum iio_attr_type type,
917 		int (*cb)(struct iio_device *dev,
918 			const char *attr, const char *val, size_t len, void *d),
919 		void *data)
920 {
921 	int ret, buf_size;
922 	char *buf, *ptr;
923 	unsigned int i, count;
924 
925 	/* We need a big buffer here; 1 MiB should be enough */
926 	buf = malloc(0x100000);
927 	if (!buf)
928 		return -ENOMEM;
929 
930 	switch(type){
931 		case IIO_ATTR_TYPE_DEVICE:
932 			count = iio_device_get_attrs_count(dev);
933 			ret = (int) iio_device_attr_read(dev,
934 					NULL, buf, 0x100000);
935 			break;
936 		case IIO_ATTR_TYPE_DEBUG:
937 			count = iio_device_get_debug_attrs_count(dev);
938 			ret = (int) iio_device_debug_attr_read(dev,
939 					NULL, buf, 0x100000);
940 			break;
941 		case IIO_ATTR_TYPE_BUFFER:
942 			count = iio_device_get_buffer_attrs_count(dev);
943 			ret = (int) iio_device_buffer_attr_read(dev,
944 					NULL, buf, 0x100000);
945 			break;
946 		default:
947 			ret = -EINVAL;
948 			count = 0;
949 			break;
950 	}
951 
952 	if (ret < 0)
953 		goto err_free_buf;
954 
955 	ptr = buf;
956 	buf_size = ret;
957 
958 	for (i = 0; i < count; i++) {
959 		const char *attr;
960 		int32_t len;
961 
962 		if (buf_size < 4) {
963 			ret = -EPROTO;
964 			break;
965 		}
966 
967 		len = (int32_t) iio_be32toh(*(uint32_t *) ptr);
968 		ptr += 4;
969 		buf_size -= 4;
970 
971 		if (len > 0 && buf_size < len) {
972 			ret = -EPROTO;
973 			break;
974 		}
975 
976 		switch(type){
977 			case IIO_ATTR_TYPE_DEVICE:
978 				attr = iio_device_get_attr(dev, i);
979 				break;
980 			case IIO_ATTR_TYPE_DEBUG:
981 				attr = iio_device_get_debug_attr(dev, i);
982 				break;
983 			case IIO_ATTR_TYPE_BUFFER:
984 				attr = iio_device_get_buffer_attr(dev, i);
985 				break;
986 			default:
987 				attr = NULL;
988 				break;
989 		}
990 
991 		if (len > 0) {
992 			ret = cb(dev, attr, ptr, (size_t) len, data);
993 			if (ret < 0)
994 				goto err_free_buf;
995 
996 			if (len & 0x3)
997 				len = ((len >> 2) + 1) << 2;
998 			ptr += len;
999 			if (len >= buf_size)
1000 				buf_size = 0;
1001 			else
1002 				buf_size -= len;
1003 		}
1004 	}
1005 
1006 err_free_buf:
1007 	free(buf);
1008 	return ret < 0 ? ret : 0;
1009 }
1010 
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)1011 static int write_each_attr(struct iio_device *dev, enum iio_attr_type type,
1012 		ssize_t (*cb)(struct iio_device *dev,
1013 			const char *attr, void *buf, size_t len, void *d),
1014 		void *data)
1015 {
1016 	char *buf, *ptr;
1017 	unsigned int i, count;
1018 	size_t len = 0x100000;
1019 	int ret;
1020 
1021 	/* We need a big buffer here; 1 MiB should be enough */
1022 	buf = malloc(len);
1023 	if (!buf)
1024 		return -ENOMEM;
1025 
1026 	ptr = buf;
1027 
1028 	switch(type){
1029 		case IIO_ATTR_TYPE_DEVICE:
1030 			count = iio_device_get_attrs_count(dev);
1031 			break;
1032 		case IIO_ATTR_TYPE_DEBUG:
1033 			count = iio_device_get_debug_attrs_count(dev);
1034 			break;
1035 		case IIO_ATTR_TYPE_BUFFER:
1036 			count = iio_device_get_buffer_attrs_count(dev);
1037 			break;
1038 		default:
1039 			ret = -EINVAL;
1040 			goto err_free_buf;
1041 	}
1042 
1043 	for (i = 0; i < count; i++) {
1044 		const char *attr;
1045 
1046 		switch(type){
1047 			case IIO_ATTR_TYPE_DEVICE:
1048 				attr = iio_device_get_attr(dev, i);
1049 				break;
1050 			case IIO_ATTR_TYPE_DEBUG:
1051 				attr = iio_device_get_debug_attr(dev, i);
1052 				break;
1053 			case IIO_ATTR_TYPE_BUFFER:
1054 				attr = iio_device_get_buffer_attr(dev, i);
1055 				break;
1056 			default:
1057 				attr = NULL;
1058 				break;
1059 		}
1060 
1061 		ret = (int) cb(dev, attr, ptr + 4, len - 4, data);
1062 		if (ret < 0)
1063 			goto err_free_buf;
1064 
1065 		*(int32_t *) ptr = (int32_t) iio_htobe32((uint32_t) ret);
1066 		ptr += 4;
1067 		len -= 4;
1068 
1069 		if (ret > 0) {
1070 			if (ret & 0x3)
1071 				ret = ((ret >> 2) + 1) << 2;
1072 			ptr += ret;
1073 			len -= ret;
1074 		}
1075 	}
1076 
1077 	switch(type){
1078 		case IIO_ATTR_TYPE_DEVICE:
1079 			ret = (int) iio_device_attr_write_raw(dev,
1080 					NULL, buf, ptr - buf);
1081 			break;
1082 		case IIO_ATTR_TYPE_DEBUG:
1083 			ret = (int) iio_device_debug_attr_write_raw(dev,
1084 					NULL, buf, ptr - buf);
1085 			break;
1086 		case IIO_ATTR_TYPE_BUFFER:
1087 			ret = (int) iio_device_buffer_attr_write_raw(dev,
1088 					NULL, buf, ptr - buf);
1089 			break;
1090 		default:
1091 			ret = -EINVAL;
1092 			break;
1093 	}
1094 
1095 err_free_buf:
1096 	free(buf);
1097 	return ret < 0 ? ret : 0;
1098 }
1099 
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)1100 int iio_device_debug_attr_read_all(struct iio_device *dev,
1101 		int (*cb)(struct iio_device *dev,
1102 			const char *attr, const char *val, size_t len, void *d),
1103 		void *data)
1104 {
1105 	return read_each_attr(dev, IIO_ATTR_TYPE_DEBUG, cb, data);
1106 }
1107 
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)1108 int iio_device_buffer_attr_read_all(struct iio_device *dev,
1109 		int (*cb)(struct iio_device *dev,
1110 			const char *attr, const char *val, size_t len, void *d),
1111 		void *data)
1112 {
1113 	return read_each_attr(dev, IIO_ATTR_TYPE_BUFFER, cb, data);
1114 }
1115 
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)1116 int iio_device_attr_read_all(struct iio_device *dev,
1117 		int (*cb)(struct iio_device *dev,
1118 			const char *attr, const char *val, size_t len, void *d),
1119 		void *data)
1120 {
1121 	return read_each_attr(dev, IIO_ATTR_TYPE_DEVICE ,cb, data);
1122 }
1123 
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)1124 int iio_device_debug_attr_write_all(struct iio_device *dev,
1125 		ssize_t (*cb)(struct iio_device *dev,
1126 			const char *attr, void *buf, size_t len, void *d),
1127 		void *data)
1128 {
1129 	return write_each_attr(dev, IIO_ATTR_TYPE_DEBUG, cb, data);
1130 }
1131 
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)1132 int iio_device_buffer_attr_write_all(struct iio_device *dev,
1133 		ssize_t (*cb)(struct iio_device *dev,
1134 			const char *attr, void *buf, size_t len, void *d),
1135 		void *data)
1136 {
1137 	return write_each_attr(dev, IIO_ATTR_TYPE_BUFFER, cb, data);
1138 }
1139 
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)1140 int iio_device_attr_write_all(struct iio_device *dev,
1141 		ssize_t (*cb)(struct iio_device *dev,
1142 			const char *attr, void *buf, size_t len, void *d),
1143 		void *data)
1144 {
1145 	return write_each_attr(dev, IIO_ATTR_TYPE_DEVICE, cb, data);
1146 }
1147 
iio_device_get_context(const struct iio_device * dev)1148 const struct iio_context * iio_device_get_context(const struct iio_device *dev)
1149 {
1150 	return dev->ctx;
1151 }
1152