iio.c
1 /***************************************************************************//** 2 * @file iio.c 3 * @brief Implementation of iio. 4 * @author Cristian Pop (cristian.pop@analog.com) 5 * @author Mihail Chindris (mihail.chindris@analog.com) 6 ******************************************************************************** 7 * Copyright 2019(c) Analog Devices, Inc. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright notice, 13 * this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright notice, 16 * this list of conditions and the following disclaimer in the documentation 17 * and/or other materials provided with the distribution. 18 * 19 * 3. Neither the name of Analog Devices, Inc. nor the names of its 20 * contributors may be used to endorse or promote products derived from this 21 * software without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES, INC. “AS IS” AND ANY EXPRESS OR 24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 25 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 26 * EVENT SHALL ANALOG DEVICES, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, 27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 28 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 29 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 30 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 31 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 32 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 *******************************************************************************/ 34 35 #include "iio.h" 36 #include "iio_types.h" 37 #include "iiod.h" 38 #include "ctype.h" 39 #include "no_os_util.h" 40 #include "no_os_list.h" 41 #include "no_os_error.h" 42 #include "no_os_uart.h" 43 #include "no_os_error.h" 44 #include "no_os_alloc.h" 45 #include "no_os_circular_buffer.h" 46 #include <inttypes.h> 47 #include <stdio.h> 48 #include <string.h> 49 50 #ifdef NO_OS_NETWORKING 51 #include "no_os_delay.h" 52 #include "tcp_socket.h" 53 #endif 54 55 #ifdef NO_OS_LWIP_NETWORKING 56 #include "no_os_delay.h" 57 #include "tcp_socket.h" 58 #include "lwip_socket.h" 59 #endif 60 61 #define IIOD_PORT 30431 62 #define MAX_SOCKET_TO_HANDLE 10 63 #define REG_ACCESS_ATTRIBUTE "direct_reg_access" 64 #define IIOD_CONN_BUFFER_SIZE 0x1000 65 #define NO_TRIGGER (uint32_t)-1 66 67 #define NO_OS_STRINGIFY(x) #x 68 #define NO_OS_TOSTRING(x) NO_OS_STRINGIFY(x) 69 70 static char uart_buff[IIOD_CONN_BUFFER_SIZE]; 71 72 static char header[] = 73 "<?xml version=\"1.0\" encoding=\"utf-8\"?>" 74 "<!DOCTYPE context [" 75 "<!ELEMENT context (device | context-attribute)*>" 76 "<!ELEMENT context-attribute EMPTY>" 77 "<!ELEMENT device (channel | attribute | debug-attribute | buffer-attribute)*>" 78 "<!ELEMENT channel (scan-element?, attribute*)>" 79 "<!ELEMENT attribute EMPTY>" 80 "<!ELEMENT scan-element EMPTY>" 81 "<!ELEMENT debug-attribute EMPTY>" 82 "<!ELEMENT buffer-attribute EMPTY>" 83 "<!ATTLIST context name CDATA #REQUIRED description CDATA #IMPLIED>" 84 "<!ATTLIST context-attribute name CDATA #REQUIRED value CDATA #REQUIRED>" 85 "<!ATTLIST device id CDATA #REQUIRED name CDATA #IMPLIED>" 86 "<!ATTLIST channel id CDATA #REQUIRED type (input|output) #REQUIRED name CDATA #IMPLIED>" 87 "<!ATTLIST scan-element index CDATA #REQUIRED format CDATA #REQUIRED scale CDATA #IMPLIED>" 88 "<!ATTLIST attribute name CDATA #REQUIRED filename CDATA #IMPLIED>" 89 "<!ATTLIST debug-attribute name CDATA #REQUIRED>" 90 "<!ATTLIST buffer-attribute name CDATA #REQUIRED>" 91 "]>" 92 "<context name=\"xml\" description=\"no-OS/projects/" 93 NO_OS_TOSTRING(NO_OS_PROJECT)" " 94 NO_OS_TOSTRING(NO_OS_VERSION)"\" >"; 95 static char header_end[] = "</context>"; 96 97 static const char * const iio_chan_type_string[] = { 98 [IIO_VOLTAGE] = "voltage", 99 [IIO_CURRENT] = "current", 100 [IIO_ALTVOLTAGE] = "altvoltage", 101 [IIO_ANGL_VEL] = "anglvel", 102 [IIO_TEMP] = "temp", 103 [IIO_CAPACITANCE] = "capacitance", 104 [IIO_ACCEL] = "accel", 105 [IIO_RESISTANCE] = "resistance", 106 [IIO_MAGN] = "magn", 107 [IIO_INCLI] = "incli", 108 [IIO_VELOCITY] = "velocity", 109 [IIO_ANGL] = "angl", 110 [IIO_ROT] = "rot", 111 [IIO_COUNT] = "count", 112 [IIO_DELTA_ANGL] = "deltaangl", 113 [IIO_DELTA_VELOCITY] = "deltavelocity", 114 [IIO_WEIGHT] = "weight", 115 }; 116 117 static const char * const iio_modifier_names[] = { 118 [IIO_MOD_X] = "x", 119 [IIO_MOD_Y] = "y", 120 [IIO_MOD_Z] = "z", 121 [IIO_MOD_TEMP_AMBIENT] = "ambient", 122 [IIO_MOD_PITCH] = "pitch", 123 [IIO_MOD_YAW] = "yaw", 124 [IIO_MOD_ROLL] = "roll", 125 }; 126 127 /* Parameters used in show and store functions */ 128 struct attr_fun_params { 129 void *dev_instance; 130 char *buf; 131 uint32_t len; 132 struct iio_ch_info *ch_info; 133 }; 134 135 struct iio_buffer_priv { 136 /* Field visible by user */ 137 struct iio_buffer public; 138 /** Buffer to read or write data. A reference will be found in buffer */ 139 struct no_os_circular_buffer cb; 140 /* Buffer provide by user. */ 141 int8_t *raw_buf; 142 /* Length of raw_buf */ 143 uint32_t raw_buf_len; 144 /* Set when this devices has buffer */ 145 bool initalized; 146 /* Set when no_os_calloc was used to initalize cb.buf */ 147 bool allocated; 148 }; 149 150 /** 151 * @struct iio_dev_priv 152 * @brief Links a physical device instance "void *dev_instance" 153 * with a "iio_device *iio" that describes capabilities of the device. 154 */ 155 struct iio_dev_priv { 156 /** Will be: iio:device[0...n] n beeing the count of registerd devices*/ 157 char dev_id[MAX_DEV_ID]; 158 /** Device name */ 159 const char *name; 160 /** Physical instance of a device */ 161 void *dev_instance; 162 /** Structure to be passed to callbacks */ 163 struct iio_device_data dev_data; 164 /** Used to read debug attributes */ 165 uint32_t active_reg_addr; 166 /** Device descriptor(describes channels and attributes) */ 167 struct iio_device *dev_descriptor; 168 /* Structure storing buffer related fields */ 169 struct iio_buffer_priv buffer; 170 /* Set to -1 when no trigger is set*/ 171 uint32_t trig_idx; 172 }; 173 174 /** 175 * @struct iio_trig_priv 176 * @brief Links a physical trigger instance "void *instance" 177 * with a "iio_trigger *descriptor" that describes capabilities of the trigger. 178 */ 179 struct iio_trig_priv { 180 /** Will be: iio:trigger[0...n] */ 181 char id[MAX_TRIG_ID]; 182 /** Trigger name */ 183 char *name; 184 /** Physical instance of a trigger */ 185 void *instance; 186 /** Trigger descriptor(describes type of trigger and its attributes) */ 187 struct iio_trigger *descriptor; 188 /** Set to true when the triggering condition is met */ 189 bool triggered; 190 }; 191 192 struct iio_desc { 193 struct iiod_desc *iiod; 194 struct iiod_ops iiod_ops; 195 void *phy_desc; 196 char *xml_desc; 197 uint32_t xml_size; 198 struct iio_ctx_attr *ctx_attrs; 199 uint32_t nb_ctx_attr; 200 struct iio_dev_priv *devs; 201 uint32_t nb_devs; 202 struct iio_trig_priv *trigs; 203 uint32_t nb_trigs; 204 struct no_os_uart_desc *uart_desc; 205 int (*recv)(void *conn, uint8_t *buf, uint32_t len); 206 int (*send)(void *conn, uint8_t *buf, uint32_t len); 207 /* FIFO for socket descriptors */ 208 struct no_os_circular_buffer *conns; 209 #if defined(NO_OS_NETWORKING) || defined(NO_OS_LWIP_NETWORKING) 210 struct tcp_socket_desc *current_sock; 211 /* Instance of server socket */ 212 struct tcp_socket_desc *server; 213 #endif 214 }; 215 216 static inline int32_t _pop_conn(struct iio_desc *desc, uint32_t *conn_id) 217 { 218 uint32_t size; 219 220 no_os_cb_size(desc->conns, &size); 221 if (size < sizeof(uint32_t)) 222 return -EAGAIN; 223 224 return no_os_cb_read(desc->conns, conn_id, sizeof(*conn_id)); 225 } 226 227 static inline int32_t _push_conn(struct iio_desc *desc, uint32_t conn_id) 228 { 229 return no_os_cb_write(desc->conns, &conn_id, sizeof(conn_id)); 230 } 231 232 static inline int32_t _nb_active_conns(struct iio_desc *desc) 233 { 234 uint32_t size; 235 236 no_os_cb_size(desc->conns, &size); 237 238 return size / sizeof(uint32_t); 239 } 240 241 242 static int iio_recv(struct iiod_ctx *ctx, uint8_t *buf, uint32_t len) 243 { 244 struct iio_desc *desc = ctx->instance; 245 246 return desc->recv(ctx->conn, buf, len); 247 } 248 249 static int iio_send(struct iiod_ctx *ctx, uint8_t *buf, uint32_t len) 250 { 251 struct iio_desc *desc = ctx->instance; 252 253 return desc->send(ctx->conn, buf, len); 254 } 255 256 static inline void _print_ch_id(char *buff, struct iio_channel *ch) 257 { 258 if (ch->modified) { 259 sprintf(buff, "%s_%s", iio_chan_type_string[ch->ch_type], 260 iio_modifier_names[ch->channel2]); 261 } else { 262 if (ch->indexed) { 263 if (ch->diferential) 264 sprintf(buff, "%s%d-%s%d", iio_chan_type_string[ch->ch_type], 265 (int)ch->channel, iio_chan_type_string[ch->ch_type], 266 (int)ch->channel2); 267 else 268 sprintf(buff, "%s%d", iio_chan_type_string[ch->ch_type], 269 (int)ch->channel); 270 } else { 271 sprintf(buff, "%s", iio_chan_type_string[ch->ch_type]); 272 } 273 } 274 } 275 276 /** 277 * @brief Get channel ID from a list of channels. 278 * @param channel - Channel name. 279 * @param desc - Device descriptor 280 * @param ch_out - If "true" is output channel, if "false" is input channel. 281 * @return Channel ID, or negative value if attribute is not found. 282 */ 283 static inline struct iio_channel *iio_get_channel(const char *channel, 284 struct iio_device *desc, bool ch_out) 285 { 286 int16_t i = 0; 287 char ch_id[MAX_CHN_ID]; 288 289 while (i < desc->num_ch) { 290 _print_ch_id(ch_id, &desc->channels[i]); 291 if (!strcmp(channel, ch_id) && 292 (desc->channels[i].ch_out == ch_out)) 293 return &desc->channels[i]; 294 i++; 295 } 296 297 return NULL; 298 } 299 300 /** 301 * @brief Find interface with "device_name". 302 * @param device_name - Device name. 303 * @param iio_dev_privs - List of interfaces. 304 * @return Interface pointer if interface is found, NULL otherwise. 305 */ 306 static struct iio_dev_priv *get_iio_device(struct iio_desc *desc, 307 const char *device_name) 308 { 309 uint32_t i; 310 311 for (i = 0; i < desc->nb_devs; i++) { 312 if (strcmp(desc->devs[i].dev_id, device_name) == 0) 313 return &desc->devs[i]; 314 } 315 316 return NULL; 317 } 318 319 /** 320 * @brief Find interface with "trigger_id". 321 * @param trigger_id - Trigger id (trigger0, trigger1, etc.). 322 * @param iio_trig_privs - List of interfaces. 323 * @return Interface pointer if interface is found, NULL otherwise. 324 */ 325 static struct iio_trig_priv *get_iio_trig_device(struct iio_desc *desc, 326 const char *trigger_id) 327 { 328 uint32_t i; 329 330 for (i = 0; i < desc->nb_trigs; i++) { 331 if (strcmp(desc->trigs[i].id, trigger_id) == 0) 332 return &desc->trigs[i]; 333 } 334 335 return NULL; 336 } 337 338 /** 339 * @brief Sets buffers count. 340 * @param ctx - IIO instance and conn instance. 341 * @param device - String containing device name. 342 * @param buffers_count - Value to be set. 343 * @return Positive if index was set, negative if not. 344 */ 345 static int iio_set_buffers_count(struct iiod_ctx *ctx, const char *device, 346 uint32_t buffers_count) 347 { 348 struct iio_desc *desc = ctx->instance; 349 350 if (!get_iio_device(desc, device)) 351 return -ENODEV; 352 353 /* Our implementation uses a circular buffer to send/receive data so 354 * only 1 is a valid value. 355 */ 356 if (buffers_count != 1) 357 return -EINVAL; 358 359 return 0; 360 } 361 362 /** 363 * @brief Read all attributes from an attribute list. 364 * @param device - Physical instance of a device. 365 * @param buf - Buffer where values are read. 366 * @param len - Maximum length of value to be stored in buf. 367 * @param channel - Channel properties. 368 * @param attributes - List of attributes to be read. 369 * @return Number of bytes read or negative value in case of error. 370 */ 371 static int iio_read_all_attr(struct attr_fun_params *params, 372 struct iio_attribute *attributes) 373 { 374 /* TODO Not sure if working corectly */ 375 return -EINVAL; 376 377 #if 0 378 int16_t i = 0, j = 0; 379 char local_buf[256]; 380 int attr_length; 381 uint32_t *pattr_length; 382 383 while (attributes[i].name) { 384 attr_length = attributes[i].show(params->dev_instance, 385 local_buf, params->len, 386 params->ch_info, 387 attributes[i].priv); 388 if (NO_OS_IS_ERR_VALUE(attr_length)) 389 attr_length = snprintf(local_buf, params->len, "%d", 390 attr_length); 391 392 attr_length += 1;//Add '\0' to the count 393 pattr_length = (uint32_t *)(params->buf + j); 394 if (j + 4 > params->len) 395 return -EINVAL; 396 *pattr_length = no_os_bswap_constant_32(attr_length); 397 j += 4; 398 if (attr_length >= 0) { 399 if (attr_length + j > params->len) 400 return -EINVAL; 401 sprintf(params->buf + j, "%s", local_buf); 402 if (attr_length & 0x3) /* multiple of 4 */ 403 attr_length = ((attr_length >> 2) + 1) << 2; 404 j += attr_length; 405 } 406 i++; 407 } 408 if (j == 0) 409 return -ENOENT; 410 411 return j; 412 #endif 413 } 414 415 /** 416 * @brief Write all attributes from an attribute list. 417 * @param device - Physical instance of a device. 418 * @param buf - Values to be written. 419 * @param len - Length of buf. 420 * @param channel - Channel properties. 421 * @param attributes - List of attributes to be written. 422 * @return Number of written bytes or negative value in case of error. 423 */ 424 static int iio_write_all_attr(struct attr_fun_params *params, 425 struct iio_attribute *attributes) 426 { 427 /* TODO Not sure if working corectly */ 428 return -EINVAL; 429 430 #if 0 431 int16_t i = 0, j = 0; 432 int16_t attr_length; 433 434 while (attributes[i].name) { 435 attr_length = no_os_bswap_constant_32((uint32_t)(params->buf + j)); 436 j += 4; 437 attributes[i].store(params->dev_instance, (params->buf + j), 438 attr_length, params->ch_info, 439 attributes[i].priv); 440 j += attr_length; 441 if (j & 0x3) 442 j = ((j >> 2) + 1) << 2; 443 i++; 444 } 445 446 if (params->len == 0) 447 return -ENOENT; 448 449 return params->len; 450 #endif 451 } 452 453 /** 454 * @brief Read/write attribute. 455 * @param params - Structure describing parameters for store and show functions 456 * @param attributes - Array of attributes. 457 * @param attr_name - Attribute name to be modified 458 * @param is_write -If it has value "1", writes attribute, otherwise reads 459 * attribute. 460 * @return Length of chars written/read or negative value in case of error. 461 */ 462 static int iio_rd_wr_attribute(struct attr_fun_params *params, 463 struct iio_attribute *attributes, 464 const char *attr_name, 465 bool is_write) 466 { 467 int16_t i = 0; 468 469 /* Search attribute */ 470 while (attributes[i].name) { 471 if (!strcmp(attr_name, attributes[i].name)) 472 break; 473 i++; 474 } 475 476 if (!attributes[i].name) 477 return -ENOENT; 478 479 if (is_write) { 480 if (!attributes[i].store) 481 return -ENOENT; 482 483 return attributes[i].store(params->dev_instance, params->buf, 484 params->len, params->ch_info, 485 attributes[i].priv); 486 } else { 487 if (!attributes[i].show) 488 return -ENOENT; 489 return attributes[i].show(params->dev_instance, params->buf, 490 params->len, params->ch_info, 491 attributes[i].priv); 492 } 493 } 494 495 /* Read a device register. The register address to read is set on 496 * in desc->active_reg_addr in the function set_demo_reg_attr 497 */ 498 static int32_t debug_reg_read(struct iio_dev_priv *dev, char *buf, uint32_t len) 499 { 500 uint32_t value; 501 int32_t ret; 502 503 value = 0; 504 ret = dev->dev_descriptor->debug_reg_read(dev->dev_instance, 505 dev->active_reg_addr, 506 &value); 507 if (NO_OS_IS_ERR_VALUE(ret)) 508 return ret; 509 510 return snprintf(buf, len, "%"PRIu32"", value); 511 } 512 513 /* Flow of reading and writing registers. This is how iio works for 514 * direct_reg_access attribute: 515 * Read register: 516 * //Reg_addr in decimal 517 * reg_addr = "10"; 518 * 1. debug_reg_write(dev, reg_addr, len); 519 * 2. debug_reg_read(dev, out_buf, out_len); 520 * Write register: 521 * sprintf(write_buf, "0x%x 0x%x", reg_addr, value); 522 * 1. debug_reg_write(dev, write_buf,len); 523 */ 524 static int32_t debug_reg_write(struct iio_dev_priv *dev, const char *buf, 525 uint32_t len) 526 { 527 uint32_t nb_filled; 528 uint32_t addr; 529 uint32_t value; 530 int32_t ret; 531 532 nb_filled = sscanf(buf, "0x%"PRIx32" 0x%"PRIx32"", &addr, &value); 533 if (nb_filled == 2) { 534 /* Write register */ 535 ret = dev->dev_descriptor->debug_reg_write(dev->dev_instance, 536 addr, value); 537 if (NO_OS_IS_ERR_VALUE(ret)) 538 return ret; 539 } else { 540 nb_filled = sscanf(buf, "%"PRIu32, &addr); 541 if (nb_filled == 1) { 542 dev->active_reg_addr = addr; 543 return len; 544 } else { 545 return -EINVAL; 546 } 547 } 548 549 return len; 550 } 551 552 static int32_t __iio_str_parse(char *buf, int32_t *integer, int32_t *_fract, 553 int32_t *_fract_scale, bool scale_db) 554 { 555 char *p; 556 557 p = strtok(buf, "."); 558 if (p == NULL) 559 return -EINVAL; 560 561 *integer = strtol(p, NULL, 0); 562 563 if (scale_db) { 564 p = strtok(NULL, "db"); 565 if (p == NULL) 566 p = strtok(NULL, " db"); 567 } else 568 p = strtok(NULL, "\n"); 569 570 if (p == NULL) 571 return -EINVAL; 572 573 *_fract = strtol(p, NULL, 10); 574 575 /* Handle leading zeroes */ 576 while (*p++ == '0' && *_fract > 0) 577 *_fract_scale *= 10; 578 579 /* Handle values between -1 and 0 */ 580 if (*integer == 0 && buf[0] == '-') 581 *_fract *= -1; 582 583 return 0; 584 } 585 586 static int32_t _iio_fract_interpret(int32_t fract, int32_t subunits) 587 { 588 int32_t temp; 589 int32_t mult = 1; 590 591 if (fract < 0) { 592 mult = -1; 593 fract = -fract; 594 } 595 596 /* Divide to nearest subunit-scale if fract part is more than subunit */ 597 while (fract >= subunits) 598 fract = NO_OS_DIV_ROUND_CLOSEST(fract, 10); 599 600 temp = fract; 601 602 while ((subunits != 0) || (temp != 0)) { 603 temp /= 10; 604 subunits /= 10; 605 if (!temp) 606 break; 607 if (subunits <= 1) 608 fract /= 10; 609 } 610 611 return fract * subunits * mult; 612 } 613 614 int32_t iio_parse_value(char *buf, enum iio_val fmt, int32_t *val, 615 int32_t *val2) 616 { 617 int32_t ret = 0; 618 int32_t integer, _fract = 0, _fract_scale = 1; 619 char ch; 620 621 switch (fmt) { 622 case IIO_VAL_INT: 623 integer = strtol(buf, NULL, 0); 624 break; 625 case IIO_VAL_INT_PLUS_MICRO_DB: 626 ret = __iio_str_parse(buf, &integer, &_fract, 627 &_fract_scale, true); 628 if (ret < 0) 629 return ret; 630 _fract = _iio_fract_interpret(_fract, 1000000 / _fract_scale); 631 break; 632 case IIO_VAL_INT_PLUS_MICRO: 633 ret = __iio_str_parse(buf, &integer, &_fract, 634 &_fract_scale, false); 635 if (ret < 0) 636 return ret; 637 _fract = _iio_fract_interpret(_fract, 1000000 / _fract_scale); 638 break; 639 case IIO_VAL_INT_PLUS_NANO: 640 ret = __iio_str_parse(buf, &integer, &_fract, 641 &_fract_scale, false); 642 if (ret < 0) 643 return ret; 644 _fract = _iio_fract_interpret(_fract, 645 1000000000 / _fract_scale); 646 break; 647 case IIO_VAL_FRACTIONAL: 648 ret = __iio_str_parse(buf, &integer, &_fract, 649 &_fract_scale, false); 650 if (ret < 0) 651 return ret; 652 break; 653 case IIO_VAL_CHAR: 654 if (sscanf(buf, "%c", &ch) != 1) 655 return -EINVAL; 656 integer = ch; 657 break; 658 default: 659 return -EINVAL; 660 } 661 662 if (val) 663 *val = integer; 664 if (val2) 665 *val2 = _fract; 666 667 return ret; 668 } 669 670 int iio_format_value(char *buf, uint32_t len, enum iio_val fmt, 671 int32_t size, int32_t *vals) 672 { 673 int64_t tmp; 674 int32_t integer, fractional; 675 bool dB = false; 676 int32_t i = 0; 677 uint32_t l = 0; 678 679 switch (fmt) { 680 case IIO_VAL_INT: 681 return snprintf(buf, len, "%"PRIi32"", vals[0]); 682 case IIO_VAL_INT_PLUS_MICRO_DB: 683 dB = true; 684 /* intentional fall through */ 685 case IIO_VAL_INT_PLUS_MICRO: 686 return snprintf(buf, len, "%s%"PRIi32".%06"PRIu32"%s", 687 vals[1] < 0 ? "-" : "", vals[0], 688 (uint32_t)vals[1], dB ? " dB" : ""); 689 case IIO_VAL_INT_PLUS_NANO: 690 return snprintf(buf, len, "%s%"PRIi32".%09"PRIu32"", 691 vals[1] < 0 ? "-" : "", vals[0], 692 (uint32_t)vals[1]); 693 case IIO_VAL_FRACTIONAL: 694 tmp = no_os_div_s64((int64_t)vals[0] * 1000000000LL, vals[1]); 695 fractional = vals[1]; 696 integer = (int32_t)no_os_div_s64_rem(tmp, 1000000000, &fractional); 697 698 if (integer == 0 && fractional < 0) 699 return snprintf(buf, len, "-0.%09u", abs(fractional)); 700 701 return snprintf(buf, len, "%"PRIi32".%09u", integer, 702 abs(fractional)); 703 case IIO_VAL_FRACTIONAL_LOG2: 704 tmp = no_os_shift_right((int64_t)vals[0] * 1000000000LL, vals[1]); 705 integer = (int32_t)no_os_div_s64_rem(tmp, 1000000000LL, &fractional); 706 707 if (integer == 0 && fractional < 0) 708 return snprintf(buf, len, "-0.%09u", abs(fractional)); 709 710 return snprintf(buf, len, "%"PRIi32".%09u", integer, 711 abs(fractional)); 712 case IIO_VAL_INT_MULTIPLE: { 713 while (i < size) { 714 l += snprintf(&buf[l], len - l, "%"PRIi32" ", vals[i]); 715 if (l >= len) 716 break; 717 i++; 718 } 719 return l; 720 } 721 case IIO_VAL_CHAR: 722 return snprintf(buf, len, "%c", (char)vals[0]); 723 default: 724 return 0; 725 } 726 } 727 728 static struct iio_attribute *get_attributes(enum iio_attr_type type, 729 struct iio_dev_priv *dev, 730 struct iio_channel *ch) 731 { 732 switch (type) { 733 case IIO_ATTR_TYPE_DEBUG: 734 return dev->dev_descriptor->debug_attributes; 735 break; 736 case IIO_ATTR_TYPE_DEVICE: 737 return dev->dev_descriptor->attributes; 738 break; 739 case IIO_ATTR_TYPE_BUFFER: 740 return dev->dev_descriptor->buffer_attributes; 741 break; 742 case IIO_ATTR_TYPE_CH_IN: 743 case IIO_ATTR_TYPE_CH_OUT: 744 return ch->attributes; 745 } 746 747 return NULL; 748 } 749 750 /** 751 * @brief Returns trigger attributes. 752 * @param type - Attribute type. 753 * @param trig - Trigger instance. 754 * @return Attributes pointer if attributes exist, NULL otherwise. 755 */ 756 static struct iio_attribute *get_trig_attributes(enum iio_attr_type type, 757 struct iio_trig_priv *trig) 758 { 759 switch (type) { 760 /* Only device type attributes allowed for triggers */ 761 case IIO_ATTR_TYPE_DEVICE: 762 return trig->descriptor->attributes; 763 break; 764 default: 765 break; 766 } 767 768 return NULL; 769 } 770 771 /** 772 * @brief Read global attribute of a device. 773 * @param ctx - IIO instance and conn instance 774 * @param device - String containing device name. 775 * @param attr - String containing attribute name. 776 * @param buf - Buffer where value is read. 777 * @param len - Maximum length of value to be stored in buf. 778 * @return Number of bytes read. 779 */ 780 static int iio_read_attr(struct iiod_ctx *ctx, const char *device, 781 struct iiod_attr *attr, char *buf, uint32_t len) 782 { 783 struct iio_dev_priv *dev; 784 struct iio_trig_priv *trig_dev; 785 struct iio_ch_info ch_info; 786 struct iio_channel *ch = NULL; 787 struct attr_fun_params params; 788 struct iio_attribute *attributes; 789 int8_t ch_out; 790 791 dev = get_iio_device(ctx->instance, device); 792 793 /* If IIO device with given name is found, handle reading of attributes */ 794 if (dev) { 795 if (attr->type == IIO_ATTR_TYPE_DEBUG && 796 strcmp(attr->name, REG_ACCESS_ATTRIBUTE) == 0) { 797 if (dev->dev_descriptor->debug_reg_read) 798 return debug_reg_read(dev, buf, len); 799 return -ENOENT; 800 } 801 802 if (attr->channel[0] != '\0') { 803 ch_out = attr->type == IIO_ATTR_TYPE_CH_OUT ? 1 : 0; 804 ch = iio_get_channel(attr->channel, dev->dev_descriptor, 805 ch_out); 806 if (!ch) 807 return -ENOENT; 808 ch_info.ch_out = ch_out; 809 ch_info.ch_num = ch->channel; 810 ch_info.type = ch->ch_type; 811 ch_info.differential = ch->diferential; 812 ch_info.address = ch->address; 813 params.ch_info = &ch_info; 814 } else { 815 params.ch_info = NULL; 816 } 817 818 params.buf = buf; 819 params.len = len; 820 params.dev_instance = dev->dev_instance; 821 attributes = get_attributes(attr->type, dev, ch); 822 if (!strcmp(attr->name, "")) 823 return iio_read_all_attr(¶ms, attributes); 824 return iio_rd_wr_attribute(¶ms, attributes, attr->name, 0); 825 } 826 827 /* IIO device with given name is not found, verify if it corresponds to a trigger */ 828 trig_dev = get_iio_trig_device(ctx->instance, device); 829 830 /* If IIO trigger with given name is found, handle reading of attributes */ 831 if (trig_dev) { 832 params.ch_info = NULL; /* Triggers cannot have channels */ 833 params.buf = buf; 834 params.len = len; 835 params.dev_instance = trig_dev->instance; 836 attributes = get_trig_attributes(attr->type, trig_dev); 837 if (!strcmp(attr->name, "")) 838 return iio_read_all_attr(¶ms, attributes); 839 return iio_rd_wr_attribute(¶ms, attributes, attr->name, 0); 840 } 841 842 /* No device and no trigger with given name were found */ 843 return -ENODEV; 844 } 845 846 /** 847 * @brief Write global attribute of a device. 848 * @param device - String containing device name. 849 * @param ctx - IIO instance and conn instance 850 * @param attr - String containing attribute name. 851 * @param buf - Value to be written. 852 * @param len - Length of data. 853 * @return Number of written bytes. 854 */ 855 static int iio_write_attr(struct iiod_ctx *ctx, const char *device, 856 struct iiod_attr *attr, char *buf, uint32_t len) 857 { 858 struct iio_dev_priv *dev; 859 struct iio_trig_priv *trig_dev; 860 struct attr_fun_params params; 861 struct iio_attribute *attributes; 862 struct iio_ch_info ch_info; 863 struct iio_channel *ch = NULL; 864 int8_t ch_out; 865 866 dev = get_iio_device(ctx->instance, device); 867 868 /* If IIO device with given name is found, handle writing of attributes */ 869 if (dev) { 870 871 if (attr->type == IIO_ATTR_TYPE_DEBUG && 872 strcmp(attr->name, REG_ACCESS_ATTRIBUTE) == 0) { 873 if (dev->dev_descriptor->debug_reg_write) 874 return debug_reg_write(dev, buf, len); 875 return -ENOENT; 876 } 877 878 if (attr->channel[0] != '\0') { 879 ch_out = attr->type == IIO_ATTR_TYPE_CH_OUT ? 1 : 0; 880 ch = iio_get_channel(attr->channel, dev->dev_descriptor, 881 ch_out); 882 if (!ch) 883 return -ENOENT; 884 885 ch_info.ch_out = ch_out; 886 ch_info.ch_num = ch->channel; 887 ch_info.type = ch->ch_type; 888 ch_info.differential = ch->diferential; 889 ch_info.address = ch->address; 890 params.ch_info = &ch_info; 891 } else { 892 params.ch_info = NULL; 893 } 894 895 params.buf = (char *)buf; 896 params.len = len; 897 params.dev_instance = dev->dev_instance; 898 attributes = get_attributes(attr->type, dev, ch); 899 if (!strcmp(attr->name, "")) 900 return iio_write_all_attr(¶ms, attributes); 901 return iio_rd_wr_attribute(¶ms, attributes, attr->name, 1); 902 } 903 904 /* IIO device with given name is not found, verify if it corresponds to a trigger */ 905 trig_dev = get_iio_trig_device(ctx->instance, device); 906 907 /* If IIO trigger with given name is found, handle writing of attributes */ 908 if (trig_dev) { 909 params.ch_info = NULL; /* Triggers cannot have channels */ 910 params.buf = (char *)buf; 911 params.len = len; 912 params.dev_instance = trig_dev->instance; 913 attributes = get_trig_attributes(attr->type, trig_dev); 914 if (!strcmp(attr->name, "")) 915 return iio_read_all_attr(¶ms, attributes); 916 return iio_rd_wr_attribute(¶ms, attributes, attr->name, 1); 917 } 918 919 /* No device and no trigger with given name were found */ 920 return -ENODEV; 921 } 922 923 /** 924 * @brief Searches for trigger id and returns trigger index. 925 * @param desc - IIO descriptor. 926 * @param id - Trigger id (trigger0, trigger1, etc.). 927 * @return Trigger index. NO_TRIGGER in case trigger is not found. 928 */ 929 static uint32_t iio_get_trig_idx_by_id(struct iio_desc *desc, const char *id) 930 { 931 uint32_t i; 932 933 if (!id) 934 return NO_TRIGGER; 935 936 for (i = 0; i < desc->nb_trigs; i++) 937 if (strcmp(desc->trigs[i].id, id) == 0) 938 return i; 939 940 return NO_TRIGGER; 941 } 942 943 /** 944 * @brief Searches for trigger name and returns trigger index. 945 * @param desc - IIO descriptor. 946 * @param name - Trigger name. 947 * @return Trigger index. NO_TRIGGER in case trigger is not found. 948 */ 949 static uint32_t iio_get_trig_idx_by_name(struct iio_desc *desc, 950 const char *name) 951 { 952 uint32_t i; 953 954 if (!name) 955 return NO_TRIGGER; 956 957 for (i = 0; i < desc->nb_trigs; i++) 958 if (strcmp(desc->trigs[i].name, name) == 0) 959 return i; 960 961 return NO_TRIGGER; 962 } 963 964 /** 965 * @brief Searches for active trigger of the given device and returns trigger name. 966 * @param ctx - IIO instance and conn instance. 967 * @param device - String containing device name. 968 * @param trigger - Trigger name to be returned. 969 * @param len - Maximum length of value to be stored in name. 970 * @return Number of bytes written in name. 971 */ 972 static int iio_get_trigger(struct iiod_ctx *ctx, const char *device, 973 char *trigger, uint32_t len) 974 { 975 struct iio_dev_priv *dev; 976 struct iio_trig_priv *trig; 977 struct iio_desc *desc = ctx->instance; 978 979 if (!desc->nb_trigs) 980 return -ENOENT; 981 982 trig = get_iio_trig_device(desc, device); 983 /* Device is a trigger and triggers cannot have other triggers */ 984 if (trig) 985 return -ENOENT; 986 987 dev = get_iio_device(desc, device); 988 if (!dev) 989 return -ENODEV; 990 991 if (dev->trig_idx == NO_TRIGGER) { 992 trigger[0] = '\0'; 993 994 return 0; 995 } 996 997 return snprintf(trigger, len, "%s", desc->trigs[dev->trig_idx].name); 998 } 999 1000 /** 1001 * @brief Searches for given trigger id for the given device and if found, it 1002 * sets the trigger. 1003 * @param ctx - IIO instance and conn instance. 1004 * @param device - String containing device name. 1005 * @param trigger - Trigger id to be set. 1006 * @param len - Maximum length of value to be returned. 1007 * @return Positive if index was set, negative if not. 1008 */ 1009 static int iio_set_trigger(struct iiod_ctx *ctx, const char *device, 1010 const char *trigger, uint32_t len) 1011 { 1012 struct iio_dev_priv *dev; 1013 struct iio_trig_priv *trig; 1014 uint32_t i; 1015 struct iio_desc *desc = ctx->instance; 1016 1017 if (!desc->nb_trigs) 1018 return -ENOENT; 1019 1020 trig = get_iio_trig_device(desc, device); 1021 /* Device is a trigger and triggers cannot have other triggers */ 1022 if (trig) 1023 return -ENOENT; 1024 1025 dev = get_iio_device(desc, device); 1026 if (!dev) 1027 return -ENODEV; 1028 1029 if (trigger[0] == '\0') { 1030 dev->trig_idx = NO_TRIGGER; 1031 return 0; 1032 } 1033 1034 i = iio_get_trig_idx_by_id(desc, trigger); 1035 if (i == NO_TRIGGER) 1036 return -EINVAL; 1037 1038 dev->trig_idx = i; 1039 1040 return len; 1041 } 1042 1043 /** 1044 * @brief Asynchronous trigger processing routine. 1045 * @param desc - IIO descriptor. 1046 */ 1047 static void iio_process_async_triggers(struct iio_desc *desc) 1048 { 1049 struct iio_dev_priv *dev; 1050 uint32_t i; 1051 1052 for (i = 0; i < desc->nb_devs; i++) { 1053 dev = desc->devs + i; 1054 if (dev->trig_idx == NO_TRIGGER) 1055 continue; 1056 1057 if (!desc->trigs[dev->trig_idx].triggered) 1058 continue; 1059 1060 if (dev->dev_descriptor->trigger_handler) { 1061 dev->dev_descriptor->trigger_handler(&dev->dev_data); 1062 desc->trigs[i].triggered = 0; 1063 } 1064 } 1065 } 1066 1067 /** 1068 * @brief Searches for trigger name and processes the trigger based on its 1069 * type (sync or async with the interrupt). 1070 * @param desc - IIO descriptor. 1071 * @param trigger_name - Trigger name. 1072 * 1073 * @return ret - Result of the processing procedure. 1074 */ 1075 int iio_process_trigger_type(struct iio_desc *desc, char *trigger_name) 1076 { 1077 uint32_t i; 1078 uint32_t trig_id; 1079 struct iio_trig_priv *trig; 1080 1081 trig_id = iio_get_trig_idx_by_name(desc, trigger_name); 1082 1083 if (trig_id == NO_TRIGGER) 1084 return -EINVAL; 1085 1086 struct iio_dev_priv *dev; 1087 1088 for (i = 0; i < desc->nb_devs; i++) { 1089 dev = desc->devs + i; 1090 if (dev->trig_idx == trig_id) { 1091 trig = &desc->trigs[trig_id]; 1092 if (trig->descriptor->is_synchronous) { 1093 if (dev->dev_descriptor->trigger_handler) 1094 dev->dev_descriptor->trigger_handler(&dev->dev_data); 1095 } else { 1096 trig->triggered = 1; 1097 } 1098 } 1099 } 1100 1101 return 0; 1102 } 1103 1104 static uint32_t bytes_per_scan(struct iio_channel *channels, uint32_t mask) 1105 { 1106 uint32_t cnt, i, length, largest = 1; 1107 1108 cnt = 0; 1109 i = 0; 1110 while (mask) { 1111 if ((mask & 1)) { 1112 length = channels[i].scan_type->storagebits / 8; 1113 1114 if (length > largest) 1115 largest = length; 1116 1117 if (cnt % length) 1118 cnt += 2 * length - (cnt % length); 1119 else 1120 cnt += length; 1121 } 1122 1123 mask >>= 1; 1124 ++i; 1125 } 1126 1127 if (cnt % largest) 1128 cnt += largest - (cnt % largest); 1129 1130 return cnt; 1131 } 1132 1133 /** 1134 * @brief Open device. 1135 * @param ctx - IIO instance and conn instance 1136 * @param device - String containing device name. 1137 * @param sample_size - Sample size. 1138 * @param mask - Channels to be opened. 1139 * @return 0, negative value in case of failure. 1140 */ 1141 static int iio_open_dev(struct iiod_ctx *ctx, const char *device, 1142 uint32_t samples, uint32_t mask, bool cyclic) 1143 { 1144 struct iio_desc *desc; 1145 struct iio_dev_priv *dev; 1146 struct iio_trig_priv *trig; 1147 uint32_t ch_mask; 1148 int32_t ret; 1149 int8_t *buf; 1150 uint32_t buf_size; 1151 1152 dev = get_iio_device(ctx->instance, device); 1153 if (!dev) 1154 return -ENODEV; 1155 1156 if (!dev->buffer.initalized) 1157 return -EINVAL; 1158 1159 ch_mask = 0xFFFFFFFF >> (32 - dev->dev_descriptor->num_ch); 1160 mask &= ch_mask; 1161 if (!mask) 1162 return -ENOENT; 1163 1164 dev->buffer.public.cyclic_info.is_cyclic = cyclic; 1165 dev->buffer.public.cyclic_info.buff_index = 0; 1166 1167 dev->buffer.public.active_mask = mask; 1168 dev->buffer.public.bytes_per_scan = 1169 bytes_per_scan(dev->dev_descriptor->channels, mask); 1170 dev->buffer.public.size = dev->buffer.public.bytes_per_scan * samples; 1171 dev->buffer.public.samples = samples; 1172 if (dev->buffer.raw_buf && dev->buffer.raw_buf_len) { 1173 if (dev->buffer.raw_buf_len < dev->buffer.public.size) 1174 /* Need a bigger buffer or to allocate */ 1175 return -ENOMEM; 1176 buf_size = dev->buffer.raw_buf_len - (dev->buffer.raw_buf_len % 1177 dev->buffer.public.size); 1178 buf = dev->buffer.raw_buf; 1179 } else { 1180 if (dev->buffer.allocated) { 1181 /* Free in case iio_close_dev wasn't called to free it*/ 1182 no_os_free(dev->buffer.cb.buff); 1183 dev->buffer.allocated = 0; 1184 } 1185 buf_size = dev->buffer.public.size; 1186 buf = (int8_t *)no_os_calloc(dev->buffer.public.size, sizeof(*buf)); 1187 if (!buf) 1188 return -ENOMEM; 1189 dev->buffer.allocated = 1; 1190 } 1191 1192 ret = no_os_cb_cfg(&dev->buffer.cb, buf, buf_size); 1193 if (NO_OS_IS_ERR_VALUE(ret)) { 1194 if (dev->buffer.allocated) { 1195 no_os_free(dev->buffer.cb.buff); 1196 dev->buffer.allocated = 0; 1197 } 1198 1199 return ret; 1200 } 1201 1202 if (dev->dev_descriptor->pre_enable) { 1203 ret = dev->dev_descriptor->pre_enable(dev->dev_instance, mask); 1204 if (NO_OS_IS_ERR_VALUE(ret)) { 1205 if (dev->buffer.allocated) { 1206 no_os_free(dev->buffer.cb.buff); 1207 dev->buffer.allocated = 0; 1208 } 1209 return ret; 1210 } 1211 } 1212 1213 desc = ctx->instance; 1214 if (dev->trig_idx != NO_TRIGGER) { 1215 trig = &desc->trigs[dev->trig_idx]; 1216 if (trig->descriptor->enable) 1217 ret = trig->descriptor->enable(trig->instance); 1218 } 1219 1220 return ret; 1221 } 1222 1223 /** 1224 * @brief Close device. 1225 * @param ctx - IIO instance and conn instance 1226 * @param device - String containing device name. 1227 * @return 0, negative value in case of failure. 1228 */ 1229 static int iio_close_dev(struct iiod_ctx *ctx, const char *device) 1230 { 1231 struct iio_desc *desc; 1232 struct iio_dev_priv *dev; 1233 struct iio_trig_priv *trig; 1234 int ret = 0; 1235 1236 dev = get_iio_device(ctx->instance, device); 1237 if (!dev) 1238 return -1; 1239 1240 if (!dev->buffer.initalized) 1241 return -EINVAL; 1242 1243 if (dev->buffer.allocated) { 1244 /* Should something else be used to free internal strucutre */ 1245 no_os_free(dev->buffer.cb.buff); 1246 dev->buffer.allocated = 0; 1247 } 1248 1249 desc = ctx->instance; 1250 if (dev->trig_idx != NO_TRIGGER) { 1251 trig = &desc->trigs[dev->trig_idx]; 1252 if (trig->descriptor->disable) { 1253 ret = trig->descriptor->disable(trig->instance); 1254 if (ret) 1255 return ret; 1256 } 1257 } 1258 1259 dev->buffer.public.active_mask = 0; 1260 if (dev->dev_descriptor->post_disable) 1261 ret = dev->dev_descriptor->post_disable(dev->dev_instance); 1262 1263 return ret; 1264 } 1265 1266 static int iio_call_submit(struct iiod_ctx *ctx, const char *device, 1267 enum iio_buffer_direction dir) 1268 { 1269 struct iio_dev_priv *dev; 1270 1271 dev = get_iio_device(ctx->instance, device); 1272 if (!dev || !dev->buffer.initalized) 1273 return -EINVAL; 1274 1275 dev->buffer.public.dir = dir; 1276 if (dev->dev_descriptor->submit && dev->trig_idx == NO_TRIGGER) 1277 return dev->dev_descriptor->submit(&dev->dev_data); 1278 else if ((dir == IIO_DIRECTION_INPUT && dev->dev_descriptor->read_dev 1279 && dev->trig_idx == NO_TRIGGER) 1280 || (dir == IIO_DIRECTION_OUTPUT && 1281 dev->dev_descriptor->write_dev && dev->trig_idx == NO_TRIGGER)) { 1282 /* Code used to don't break devices using read_dev */ 1283 int32_t ret; 1284 void *buff; 1285 struct iio_buffer *buffer = &dev->buffer.public; 1286 1287 ret = iio_buffer_get_block(buffer, &buff); 1288 if (NO_OS_IS_ERR_VALUE(ret)) 1289 return ret; 1290 1291 if (dir == IIO_DIRECTION_INPUT) 1292 ret = dev->dev_descriptor->read_dev(dev->dev_instance, 1293 buff, buffer->samples); 1294 else 1295 ret = dev->dev_descriptor->write_dev(dev->dev_instance, 1296 buff, buffer->samples); 1297 if (NO_OS_IS_ERR_VALUE(ret)) 1298 return ret; 1299 1300 return iio_buffer_block_done(buffer); 1301 } 1302 1303 return 0; 1304 } 1305 1306 static int iio_push_buffer(struct iiod_ctx *ctx, const char *device) 1307 { 1308 return iio_call_submit(ctx, device, IIO_DIRECTION_OUTPUT); 1309 } 1310 1311 static int iio_refill_buffer(struct iiod_ctx *ctx, const char *device) 1312 { 1313 return iio_call_submit(ctx, device, IIO_DIRECTION_INPUT); 1314 } 1315 1316 /** 1317 * @brief Read chunk of data from RAM to pbuf. Call 1318 * "iio_transfer_dev_to_mem()" first. 1319 * @param device - String containing device name. 1320 * @param pbuf - Buffer where value is stored. 1321 * @param offset - Offset to the remaining data after reading n chunks. 1322 * @param bytes_count - Number of bytes to read. 1323 * @return: Bytes_count or negative value in case of error. 1324 */ 1325 static int iio_read_buffer(struct iiod_ctx *ctx, const char *device, char *buf, 1326 uint32_t bytes) 1327 { 1328 struct iio_dev_priv *dev; 1329 int32_t ret; 1330 uint32_t size; 1331 1332 dev = get_iio_device(ctx->instance, device); 1333 if (!dev || !dev->buffer.initalized) 1334 return -EINVAL; 1335 1336 ret = no_os_cb_size(&dev->buffer.cb, &size); 1337 #ifdef IIO_IGNORE_BUFF_OVERRUN_ERR 1338 #warning Buffer overrun error checking is disabled. 1339 if (ret != -NO_OS_EOVERRUN) 1340 #endif 1341 if (NO_OS_IS_ERR_VALUE(ret)) 1342 return ret; 1343 1344 bytes = no_os_min(size, bytes); 1345 if (!bytes) 1346 return -EAGAIN; 1347 1348 1349 ret = no_os_cb_read(&dev->buffer.cb, buf, bytes); 1350 #ifdef IIO_IGNORE_BUFF_OVERRUN_ERR 1351 if (ret != -NO_OS_EOVERRUN) 1352 #endif 1353 if (NO_OS_IS_ERR_VALUE(ret)) 1354 return ret; 1355 1356 return bytes; 1357 } 1358 1359 1360 /** 1361 * @brief Write chunk of data into RAM. 1362 * @param device - String containing device name. 1363 * @param buf - Values to write. 1364 * @param offset - Offset in memory after the nth chunk of data. 1365 * @param bytes_count - Number of bytes to write. 1366 * @return Bytes_count or negative value in case of error. 1367 */ 1368 static int iio_write_buffer(struct iiod_ctx *ctx, const char *device, 1369 const char *buf, uint32_t bytes) 1370 { 1371 struct iio_dev_priv *dev; 1372 int32_t ret; 1373 uint32_t available; 1374 uint32_t size; 1375 1376 dev = get_iio_device(ctx->instance, device); 1377 if (!dev || !dev->buffer.initalized) 1378 return -EINVAL; 1379 1380 ret = no_os_cb_size(&dev->buffer.cb, &size); 1381 if (NO_OS_IS_ERR_VALUE(ret)) 1382 return ret; 1383 1384 available = dev->buffer.public.size - size; 1385 bytes = no_os_min(available, bytes); 1386 ret = no_os_cb_write(&dev->buffer.cb, buf, bytes); 1387 if (NO_OS_IS_ERR_VALUE(ret)) 1388 return ret; 1389 1390 return bytes; 1391 } 1392 1393 int iio_buffer_get_block(struct iio_buffer *buffer, void **addr) 1394 { 1395 uint32_t size; 1396 1397 if (!buffer) 1398 return -EINVAL; 1399 1400 if (buffer->dir == IIO_DIRECTION_INPUT) 1401 return no_os_cb_prepare_async_write(buffer->buf, buffer->size, addr, &size); 1402 1403 return no_os_cb_prepare_async_read(buffer->buf, buffer->size, addr, &size); 1404 } 1405 1406 int iio_buffer_block_done(struct iio_buffer *buffer) 1407 { 1408 if (!buffer) 1409 return -EINVAL; 1410 1411 if (buffer->dir == IIO_DIRECTION_INPUT) 1412 return no_os_cb_end_async_write(buffer->buf); 1413 1414 return no_os_cb_end_async_read(buffer->buf); 1415 } 1416 1417 /* Write to buffer iio_buffer.bytes_per_scan bytes from data */ 1418 int iio_buffer_push_scan(struct iio_buffer *buffer, void *data) 1419 { 1420 if (!buffer) 1421 return -EINVAL; 1422 1423 return no_os_cb_write(buffer->buf, data, buffer->bytes_per_scan); 1424 } 1425 1426 /* Read from buffer iio_buffer.bytes_per_scan bytes into data */ 1427 int iio_buffer_pop_scan(struct iio_buffer *buffer, void *data) 1428 { 1429 if (!buffer) 1430 return -EINVAL; 1431 1432 int ret; 1433 1434 ret = no_os_cb_read(buffer->buf, data, buffer->bytes_per_scan); 1435 1436 if (buffer->cyclic_info.is_cyclic) { 1437 if (buffer->buf->read.idx == buffer->buf->write.idx) 1438 buffer->buf->read.idx = 0; 1439 } 1440 1441 return ret; 1442 } 1443 1444 #if defined(NO_OS_NETWORKING) || defined(NO_OS_LWIP_NETWORKING) 1445 1446 static int32_t accept_network_clients(struct iio_desc *desc) 1447 { 1448 struct tcp_socket_desc *sock; 1449 struct iiod_conn_data data; 1450 int32_t ret; 1451 uint32_t id; 1452 1453 do { 1454 ret = socket_accept(desc->server, &sock); 1455 if (NO_OS_IS_ERR_VALUE(ret)) 1456 return ret; 1457 1458 data.conn = sock; 1459 data.buf = no_os_calloc(1, IIOD_CONN_BUFFER_SIZE); 1460 data.len = IIOD_CONN_BUFFER_SIZE; 1461 1462 if (!data.buf) { 1463 ret = -ENOMEM; 1464 goto close_socket; 1465 } 1466 1467 ret = iiod_conn_add(desc->iiod, &data, &id); 1468 if (NO_OS_IS_ERR_VALUE(ret)) 1469 goto free_buf; 1470 1471 ret = _push_conn(desc, id); 1472 if (NO_OS_IS_ERR_VALUE(ret)) 1473 goto remove_conn; 1474 } while (true); 1475 1476 return 0; 1477 1478 remove_conn: 1479 iiod_conn_remove(desc->iiod, id, &data); 1480 free_buf: 1481 no_os_free(data.buf); 1482 close_socket: 1483 socket_remove(sock); 1484 1485 return ret; 1486 } 1487 #endif 1488 1489 /** 1490 * @brief Execute an iio step 1491 * @param desc - IIo descriptor 1492 * @return 0 in case of success or negative value otherwise. 1493 */ 1494 int iio_step(struct iio_desc *desc) 1495 { 1496 struct iiod_conn_data data; 1497 uint32_t conn_id; 1498 int32_t ret; 1499 1500 iio_process_async_triggers(desc); 1501 1502 #if defined(NO_OS_NETWORKING) || defined(NO_OS_LWIP_NETWORKING) 1503 if (desc->server) { 1504 ret = accept_network_clients(desc); 1505 if (NO_OS_IS_ERR_VALUE(ret) && ret != -EAGAIN) 1506 return ret; 1507 #if defined(NO_OS_LWIP_NETWORKING) 1508 no_os_lwip_step(desc->server->net->net, desc->server->net->net); 1509 #endif 1510 } 1511 #endif 1512 1513 ret = _pop_conn(desc, &conn_id); 1514 if (NO_OS_IS_ERR_VALUE(ret)) 1515 return ret; 1516 1517 ret = iiod_conn_step(desc->iiod, conn_id); 1518 if (ret == -ENOTCONN) { 1519 #if defined(NO_OS_NETWORKING) || defined(NO_OS_LWIP_NETWORKING) 1520 iiod_conn_remove(desc->iiod, conn_id, &data); 1521 socket_remove(data.conn); 1522 no_os_free(data.buf); 1523 #endif 1524 } else { 1525 _push_conn(desc, conn_id); 1526 } 1527 1528 return ret; 1529 } 1530 1531 /** 1532 * @brief Add context attributes into xml string buffer. 1533 * @param desc - IIo descriptor. 1534 * @param buff - xml buffer. 1535 * @param buff_size - size of buffer 1536 * @return 0 in case of success or negative value otherwise. 1537 */ 1538 static uint32_t iio_add_ctx_attr_in_xml(struct iio_desc *desc, char *buff, 1539 uint32_t buff_size) 1540 { 1541 struct iio_ctx_attr *attr; 1542 char dummy_buff[50]; 1543 int32_t i; 1544 int32_t j; 1545 int32_t n; 1546 1547 if ((int32_t)buff_size == -1) 1548 n = 0; 1549 else 1550 n = buff_size; 1551 1552 if (buff == NULL) 1553 /* Set dummy value for buff. It is used only for counting */ 1554 buff = dummy_buff; 1555 1556 i = 0; 1557 1558 attr = desc->ctx_attrs; 1559 if (attr) 1560 for (j = 0; j < (int32_t)desc->nb_ctx_attr; j++) { 1561 i += snprintf(buff + i, 1562 no_os_max(n - i, 0), 1563 "<context-attribute name=\"%s\" ", 1564 attr[j].name); 1565 1566 i += snprintf(buff + i, 1567 no_os_max(n - i, 0), 1568 "value=\"%s\" />", 1569 attr[j].value); 1570 } 1571 1572 return i; 1573 } 1574 1575 /* 1576 * Generate an xml describing a device and write it to buff. 1577 * Will return the size of the xml. 1578 * If buff_size is 0, no data will be written to buff, but size will be returned 1579 */ 1580 static uint32_t iio_generate_device_xml(struct iio_device *device, char *name, 1581 char *id, char *buff, 1582 uint32_t buff_size) 1583 { 1584 struct iio_channel *ch; 1585 struct iio_attribute *attr; 1586 char ch_id[50]; 1587 int32_t i; 1588 int32_t j; 1589 int32_t k; 1590 int32_t n; 1591 1592 if ((int32_t)buff_size == -1) 1593 n = 0; 1594 else 1595 n = buff_size; 1596 1597 if (buff == NULL) 1598 /* Set dummy value for buff. It is used only for counting */ 1599 buff = ch_id; 1600 1601 i = 0; 1602 1603 i += snprintf(buff + i, no_os_max(n - i, 0), 1604 "<device id=\"%s\" name=\"%s\">", id, name); 1605 1606 /* Write channels */ 1607 if (device->channels) 1608 for (j = 0; j < device->num_ch; j++) { 1609 ch = &device->channels[j]; 1610 _print_ch_id(ch_id, ch); 1611 i += snprintf(buff + i, no_os_max(n - i, 0), 1612 "<channel id=\"%s\"", 1613 ch_id); 1614 if (ch->name) 1615 i += snprintf(buff + i, no_os_max(n - i, 0), 1616 " name=\"%s\"", 1617 ch->name); 1618 i += snprintf(buff + i, no_os_max(n - i, 0), 1619 " type=\"%s\" >", 1620 ch->ch_out ? "output" : "input"); 1621 1622 if (ch->scan_type) 1623 i += snprintf(buff + i, no_os_max(n - i, 0), 1624 "<scan-element index=\"%d\"" 1625 " format=\"%s:%c%d/%d>>%d\" />", 1626 ch->scan_index, 1627 ch->scan_type->is_big_endian ? "be" : "le", 1628 ch->scan_type->sign, 1629 ch->scan_type->realbits, 1630 ch->scan_type->storagebits, 1631 ch->scan_type->shift); 1632 1633 /* Write channel attributes */ 1634 if (ch->attributes) 1635 for (k = 0; ch->attributes[k].name; k++) { 1636 attr = &ch->attributes[k]; 1637 i += snprintf(buff + i, no_os_max(n - i, 0), "<attribute name=\"%s\" ", 1638 attr->name); 1639 if (ch->diferential) { 1640 switch (attr->shared) { 1641 case IIO_SHARED_BY_ALL: 1642 i += snprintf(buff + i, no_os_max(n - i, 0), 1643 "filename=\"%s\"", 1644 attr->name); 1645 break; 1646 case IIO_SHARED_BY_DIR: 1647 i += snprintf(buff + i, no_os_max(n - i, 0), 1648 "filename=\"%s_%s\"", 1649 ch->ch_out ? "out" : "in", 1650 attr->name); 1651 break; 1652 case IIO_SHARED_BY_TYPE: 1653 i += snprintf(buff + i, no_os_max(n - i, 0), 1654 "filename=\"%s_%s-%s_%s\"", 1655 ch->ch_out ? "out" : "in", 1656 iio_chan_type_string[ch->ch_type], 1657 iio_chan_type_string[ch->ch_type], 1658 attr->name); 1659 break; 1660 case IIO_SEPARATE: 1661 if (!ch->indexed) { 1662 // Differential channels must be indexed! 1663 return -EINVAL; 1664 } 1665 i += snprintf(buff + i, no_os_max(n - i, 0), 1666 "filename=\"%s_%s%d-%s%d_%s\"", 1667 ch->ch_out ? "out" : "in", 1668 iio_chan_type_string[ch->ch_type], 1669 ch->channel, 1670 iio_chan_type_string[ch->ch_type], 1671 ch->channel2, 1672 attr->name); 1673 break; 1674 } 1675 } else { 1676 switch (attr->shared) { 1677 case IIO_SHARED_BY_ALL: 1678 i += snprintf(buff + i, no_os_max(n - i, 0), 1679 "filename=\"%s\"", 1680 attr->name); 1681 break; 1682 case IIO_SHARED_BY_DIR: 1683 i += snprintf(buff + i, no_os_max(n - i, 0), 1684 "filename=\"%s_%s\"", 1685 ch->ch_out ? "out" : "in", 1686 attr->name); 1687 break; 1688 case IIO_SHARED_BY_TYPE: 1689 i += snprintf(buff + i, no_os_max(n - i, 0), 1690 "filename=\"%s_%s_%s\"", 1691 ch->ch_out ? "out" : "in", 1692 iio_chan_type_string[ch->ch_type], 1693 attr->name); 1694 break; 1695 case IIO_SEPARATE: 1696 if (ch->indexed) 1697 i += snprintf(buff + i, no_os_max(n - i, 0), 1698 "filename=\"%s_%s%d_%s\"", 1699 ch->ch_out ? "out" : "in", 1700 iio_chan_type_string[ch->ch_type], 1701 ch->channel, 1702 attr->name); 1703 else 1704 i += snprintf(buff + i, no_os_max(n - i, 0), 1705 "filename=\"%s_%s_%s\"", 1706 ch->ch_out ? "out" : "in", 1707 iio_chan_type_string[ch->ch_type], 1708 attr->name); 1709 break; 1710 } 1711 } 1712 i += snprintf(buff + i, no_os_max(n - i, 0), " />"); 1713 } 1714 1715 i += snprintf(buff + i, no_os_max(n - i, 0), "</channel>"); 1716 } 1717 1718 /* Write device attributes */ 1719 if (device->attributes) 1720 for (j = 0; device->attributes[j].name; j++) 1721 i += snprintf(buff + i, no_os_max(n - i, 0), 1722 "<attribute name=\"%s\" />", 1723 device->attributes[j].name); 1724 1725 /* Write debug attributes */ 1726 if (device->debug_attributes) 1727 for (j = 0; device->debug_attributes[j].name; j++) 1728 i += snprintf(buff + i, no_os_max(n - i, 0), 1729 "<debug-attribute name=\"%s\" />", 1730 device->debug_attributes[j].name); 1731 if (device->debug_reg_read || device->debug_reg_write) 1732 i += snprintf(buff + i, no_os_max(n - i, 0), 1733 "<debug-attribute name=\""REG_ACCESS_ATTRIBUTE"\" />"); 1734 1735 /* Write buffer attributes */ 1736 if (device->buffer_attributes) 1737 for (j = 0; device->buffer_attributes[j].name; j++) 1738 i += snprintf(buff + i, no_os_max(n - i, 0), 1739 "<buffer-attribute name=\"%s\" />", 1740 device->buffer_attributes[j].name); 1741 1742 i += snprintf(buff + i, no_os_max(n - i, 0), "</device>"); 1743 1744 return i; 1745 } 1746 1747 static int32_t iio_init_xml(struct iio_desc *desc) 1748 { 1749 struct iio_dev_priv *dev; 1750 struct iio_trig_priv *trig; 1751 struct iio_device dummy = { 0 }; 1752 uint32_t i, size, of; 1753 1754 /* -2 because of the 0 character */ 1755 size = sizeof(header) + sizeof(header_end) - 2; 1756 size += iio_add_ctx_attr_in_xml(desc, NULL, -1); 1757 for (i = 0; i < desc->nb_devs; i++) { 1758 dev = desc->devs + i; 1759 size += iio_generate_device_xml(dev->dev_descriptor, 1760 (char *)dev->name, 1761 dev->dev_id, NULL, -1); 1762 } 1763 for (i = 0; i < desc->nb_trigs; i++) { 1764 trig = desc->trigs + i; 1765 dummy.attributes = trig->descriptor->attributes; 1766 size += iio_generate_device_xml(&dummy, trig->name, trig->id, 1767 NULL, -1); 1768 } 1769 1770 desc->xml_desc = (char *)no_os_calloc(size + 1, sizeof(*desc->xml_desc)); 1771 if (!desc->xml_desc) 1772 return -ENOMEM; 1773 1774 desc->xml_size = size; 1775 1776 strcpy(desc->xml_desc, header); 1777 of = sizeof(header) - 1; 1778 of += iio_add_ctx_attr_in_xml(desc, desc->xml_desc + of, size - of); 1779 for (i = 0; i < desc->nb_devs; i++) { 1780 dev = desc->devs + i; 1781 of += iio_generate_device_xml(dev->dev_descriptor, 1782 (char *)dev->name, dev->dev_id, 1783 desc->xml_desc + of, size - of); 1784 } 1785 for (i = 0; i < desc->nb_trigs; i++) { 1786 trig = desc->trigs + i; 1787 dummy.attributes = trig->descriptor->attributes; 1788 of += iio_generate_device_xml(&dummy, trig->name, trig->id, 1789 desc->xml_desc + of, size - of); 1790 } 1791 1792 strcpy(desc->xml_desc + of, header_end); 1793 1794 return 0; 1795 } 1796 1797 static int32_t iio_init_devs(struct iio_desc *desc, 1798 struct iio_device_init *devs, uint32_t n) 1799 { 1800 uint32_t i; 1801 struct iio_dev_priv *ldev; 1802 struct iio_device_init *ndev; 1803 1804 desc->nb_devs = n; 1805 desc->devs = (struct iio_dev_priv *)no_os_calloc(desc->nb_devs, 1806 sizeof(*desc->devs)); 1807 if (!desc->devs) 1808 return -ENOMEM; 1809 1810 for (i = 0; i < n; i++) { 1811 ndev = devs + i; 1812 ldev = desc->devs + i; 1813 ldev->dev_descriptor = ndev->dev_descriptor; 1814 sprintf(ldev->dev_id, "iio:device%"PRIu32"", i); 1815 ldev->trig_idx = iio_get_trig_idx_by_id(desc, ndev->trigger_id); 1816 ldev->dev_instance = ndev->dev; 1817 ldev->dev_data.dev = ndev->dev; 1818 ldev->dev_data.buffer = &ldev->buffer.public; 1819 ldev->name = ndev->name; 1820 if (ndev->dev_descriptor->read_dev || 1821 ndev->dev_descriptor->write_dev || 1822 ndev->dev_descriptor->submit || 1823 ndev->dev_descriptor->trigger_handler) { 1824 ldev->buffer.raw_buf = ndev->raw_buf; 1825 ldev->buffer.raw_buf_len = ndev->raw_buf_len; 1826 ldev->buffer.public.buf = &ldev->buffer.cb; 1827 ldev->buffer.initalized = 1; 1828 } else { 1829 ldev->buffer.initalized = 0; 1830 } 1831 } 1832 1833 return 0; 1834 } 1835 1836 /** 1837 * @brief Initializes IIO triggers. 1838 * @param desc - IIO descriptor. 1839 * @param trigs - Triggers array. 1840 * @param n - Number of triggers to be initialized. 1841 * @return 0 in case of success or negative value otherwise. 1842 */ 1843 static int32_t iio_init_trigs(struct iio_desc *desc, 1844 struct iio_trigger_init *trigs, uint32_t n) 1845 { 1846 uint32_t i; 1847 struct iio_trig_priv *trig_priv_iter; 1848 struct iio_trigger_init *trig_init_iter; 1849 1850 desc->nb_trigs = n; 1851 desc->trigs = (struct iio_trig_priv *)no_os_calloc(desc->nb_trigs, 1852 sizeof(*desc->trigs)); 1853 if (!desc->trigs) 1854 return -ENOMEM; 1855 1856 for (i = 0; i < n; i++) { 1857 trig_init_iter = trigs + i; 1858 trig_priv_iter = desc->trigs + i; 1859 trig_priv_iter->instance = trig_init_iter->trig; 1860 trig_priv_iter->name = trig_init_iter->name; 1861 trig_priv_iter->descriptor = trig_init_iter->descriptor; 1862 sprintf(trig_priv_iter->id, "trigger%"PRIu32"", i); 1863 } 1864 1865 return 0; 1866 } 1867 1868 /** 1869 * @brief Set communication ops and read/write ops 1870 * @param desc - iio descriptor. 1871 * @param init_param - appropriate init param. 1872 * @return 0 in case of success or negative value otherwise. 1873 */ 1874 int iio_init(struct iio_desc **desc, struct iio_init_param *init_param) 1875 { 1876 int32_t ret; 1877 struct iio_desc *ldesc; 1878 struct iiod_ops *ops; 1879 struct iiod_init_param iiod_param; 1880 uint32_t conn_id; 1881 1882 if (!desc || !init_param) 1883 return -EINVAL; 1884 1885 ldesc = (struct iio_desc *)no_os_calloc(1, sizeof(*ldesc)); 1886 if (!ldesc) 1887 return -ENOMEM; 1888 1889 ldesc->ctx_attrs = init_param->ctx_attrs; 1890 ldesc->nb_ctx_attr = init_param->nb_ctx_attr; 1891 1892 ret = iio_init_trigs(ldesc, init_param->trigs, init_param->nb_trigs); 1893 if (NO_OS_IS_ERR_VALUE(ret)) 1894 goto free_devs; 1895 1896 ret = iio_init_devs(ldesc, init_param->devs, init_param->nb_devs); 1897 if (NO_OS_IS_ERR_VALUE(ret)) 1898 goto free_desc; 1899 1900 ret = iio_init_xml(ldesc); 1901 if (NO_OS_IS_ERR_VALUE(ret)) 1902 goto free_trigs; 1903 1904 /* device operations */ 1905 ops = &ldesc->iiod_ops; 1906 ops->read_attr = iio_read_attr; 1907 ops->write_attr = iio_write_attr; 1908 ops->get_trigger = iio_get_trigger; 1909 ops->set_trigger = iio_set_trigger; 1910 ops->read_buffer = iio_read_buffer; 1911 ops->write_buffer = iio_write_buffer; 1912 ops->refill_buffer = iio_refill_buffer; 1913 ops->push_buffer = iio_push_buffer; 1914 ops->open = iio_open_dev; 1915 ops->close = iio_close_dev; 1916 ops->send = iio_send; 1917 ops->recv = iio_recv; 1918 ops->set_buffers_count = iio_set_buffers_count; 1919 1920 iiod_param.instance = ldesc; 1921 iiod_param.ops = ops; 1922 iiod_param.xml = ldesc->xml_desc; 1923 iiod_param.xml_len = ldesc->xml_size; 1924 iiod_param.phy_type = init_param->phy_type; 1925 1926 ret = iiod_init(&ldesc->iiod, &iiod_param); 1927 if (NO_OS_IS_ERR_VALUE(ret)) 1928 goto free_xml; 1929 1930 ret = no_os_cb_init(&ldesc->conns, 1931 sizeof(uint32_t) * (IIOD_MAX_CONNECTIONS + 1)); 1932 if (NO_OS_IS_ERR_VALUE(ret)) 1933 goto free_iiod; 1934 1935 if (init_param->phy_type == USE_UART) { 1936 ldesc->send = (int (*)())no_os_uart_write; 1937 ldesc->recv = (int (*)())no_os_uart_read; 1938 ldesc->uart_desc = init_param->uart_desc; 1939 1940 struct iiod_conn_data data = { 1941 .conn = ldesc->uart_desc, 1942 .buf = uart_buff, 1943 .len = sizeof(uart_buff) 1944 }; 1945 ret = iiod_conn_add(ldesc->iiod, &data, &conn_id); 1946 if (NO_OS_IS_ERR_VALUE(ret)) 1947 goto free_conns; 1948 _push_conn(ldesc, conn_id); 1949 } 1950 #if defined(NO_OS_NETWORKING) || defined(NO_OS_LWIP_NETWORKING) 1951 else if (init_param->phy_type == USE_NETWORK) { 1952 ldesc->send = (int (*)())socket_send; 1953 ldesc->recv = (int (*)())socket_recv; 1954 ret = socket_init(&ldesc->server, 1955 init_param->tcp_socket_init_param); 1956 if (NO_OS_IS_ERR_VALUE(ret)) 1957 goto free_conns; 1958 ret = socket_bind(ldesc->server, IIOD_PORT); 1959 if (NO_OS_IS_ERR_VALUE(ret)) 1960 goto free_pylink; 1961 ret = socket_listen(ldesc->server, MAX_BACKLOG); 1962 if (NO_OS_IS_ERR_VALUE(ret)) 1963 goto free_pylink; 1964 } 1965 #endif 1966 else if (init_param->phy_type == USE_LOCAL_BACKEND) { 1967 ldesc->recv = init_param->local_backend->local_backend_event_read; 1968 ldesc->send = init_param->local_backend->local_backend_event_write; 1969 1970 struct iiod_conn_data data = { 1971 .conn = NULL, 1972 .buf = init_param->local_backend->local_backend_buff, 1973 .len = init_param->local_backend->local_backend_buff_len 1974 }; 1975 ret = iiod_conn_add(ldesc->iiod, &data, &conn_id); 1976 if (NO_OS_IS_ERR_VALUE(ret)) 1977 goto free_conns; 1978 _push_conn(ldesc, conn_id); 1979 } else { 1980 ret = -EINVAL; 1981 goto free_conns; 1982 } 1983 1984 *desc = ldesc; 1985 1986 return 0; 1987 1988 free_pylink: 1989 #if defined(NO_OS_NETWORKING) || defined(NO_OS_LWIP_NETWORKING) 1990 socket_remove(ldesc->server); 1991 #endif 1992 free_conns: 1993 no_os_cb_remove(ldesc->conns); 1994 free_iiod: 1995 iiod_remove(ldesc->iiod); 1996 free_xml: 1997 no_os_free(ldesc->xml_desc); 1998 free_trigs: 1999 no_os_free(ldesc->trigs); 2000 free_devs: 2001 no_os_free(ldesc->devs); 2002 free_desc: 2003 no_os_free(ldesc); 2004 2005 return ret; 2006 } 2007 2008 /** 2009 * @brief Free the resources allocated by "iio_init()". 2010 * @param desc: iio descriptor. 2011 * @return 0 in case of success or negative value otherwise. 2012 */ 2013 int iio_remove(struct iio_desc *desc) 2014 { 2015 struct iiod_conn_data data; 2016 int ret; 2017 2018 if (!desc) 2019 return -EINVAL; 2020 2021 #if defined(NO_OS_NETWORKING) || defined(NO_OS_LWIP_NETWORKING) 2022 for (int i = 0; i < IIOD_MAX_CONNECTIONS; i++) { 2023 ret = iiod_conn_remove(desc->iiod, i, &data); 2024 if (!ret) { 2025 no_os_free(data.buf); 2026 socket_remove(data.conn); 2027 } 2028 } 2029 socket_remove(desc->server); 2030 #endif 2031 no_os_cb_remove(desc->conns); 2032 iiod_remove(desc->iiod); 2033 no_os_free(desc->devs); 2034 no_os_free(desc->trigs); 2035 no_os_free(desc->xml_desc); 2036 no_os_free(desc); 2037 2038 return 0; 2039 }