1 // SPDX-License-Identifier: GPL-2.0-only 2 /* The industrial I/O core in kernel channel mapping 3 * 4 * Copyright (c) 2011 Jonathan Cameron 5 */ 6 #include <linux/cleanup.h> 7 #include <linux/err.h> 8 #include <linux/export.h> 9 #include <linux/minmax.h> 10 #include <linux/mutex.h> 11 #include <linux/property.h> 12 #include <linux/slab.h> 13 14 #include <linux/iio/iio.h> 15 #include <linux/iio/iio-opaque.h> 16 #include "iio_core.h" 17 #include <linux/iio/machine.h> 18 #include <linux/iio/driver.h> 19 #include <linux/iio/consumer.h> 20 21 struct iio_map_internal { 22 struct iio_dev *indio_dev; 23 struct iio_map *map; 24 struct list_head l; 25 }; 26 27 static LIST_HEAD(iio_map_list); 28 static DEFINE_MUTEX(iio_map_list_lock); 29 30 static int iio_map_array_unregister_locked(struct iio_dev *indio_dev) 31 { 32 int ret = -ENODEV; 33 struct iio_map_internal *mapi, *next; 34 35 list_for_each_entry_safe(mapi, next, &iio_map_list, l) { 36 if (indio_dev == mapi->indio_dev) { 37 list_del(&mapi->l); 38 kfree(mapi); 39 ret = 0; 40 } 41 } 42 return ret; 43 } 44 45 int iio_map_array_register(struct iio_dev *indio_dev, struct iio_map *maps) 46 { 47 struct iio_map_internal *mapi; 48 int i = 0; 49 int ret; 50 51 if (!maps) 52 return 0; 53 54 guard(mutex)(&iio_map_list_lock); 55 while (maps[i].consumer_dev_name) { 56 mapi = kzalloc(sizeof(*mapi), GFP_KERNEL); 57 if (!mapi) { 58 ret = -ENOMEM; 59 goto error_ret; 60 } 61 mapi->map = &maps[i]; 62 mapi->indio_dev = indio_dev; 63 list_add_tail(&mapi->l, &iio_map_list); 64 i++; 65 } 66 67 return 0; 68 error_ret: 69 iio_map_array_unregister_locked(indio_dev); 70 return ret; 71 } 72 EXPORT_SYMBOL_GPL(iio_map_array_register); 73 74 /* 75 * Remove all map entries associated with the given iio device 76 */ 77 int iio_map_array_unregister(struct iio_dev *indio_dev) 78 { 79 guard(mutex)(&iio_map_list_lock); 80 return iio_map_array_unregister_locked(indio_dev); 81 } 82 EXPORT_SYMBOL_GPL(iio_map_array_unregister); 83 84 static void iio_map_array_unregister_cb(void *indio_dev) 85 { 86 iio_map_array_unregister(indio_dev); 87 } 88 89 int devm_iio_map_array_register(struct device *dev, struct iio_dev *indio_dev, struct iio_map *maps) 90 { 91 int ret; 92 93 ret = iio_map_array_register(indio_dev, maps); 94 if (ret) 95 return ret; 96 97 return devm_add_action_or_reset(dev, iio_map_array_unregister_cb, indio_dev); 98 } 99 EXPORT_SYMBOL_GPL(devm_iio_map_array_register); 100 101 static const struct iio_chan_spec 102 *iio_chan_spec_from_name(const struct iio_dev *indio_dev, const char *name) 103 { 104 int i; 105 const struct iio_chan_spec *chan = NULL; 106 107 for (i = 0; i < indio_dev->num_channels; i++) 108 if (indio_dev->channels[i].datasheet_name && 109 strcmp(name, indio_dev->channels[i].datasheet_name) == 0) { 110 chan = &indio_dev->channels[i]; 111 break; 112 } 113 return chan; 114 } 115 116 /** 117 * __fwnode_iio_simple_xlate - translate iiospec to the IIO channel index 118 * @indio_dev: pointer to the iio_dev structure 119 * @iiospec: IIO specifier as found in the device tree 120 * 121 * This is simple translation function, suitable for the most 1:1 mapped 122 * channels in IIO chips. This function performs only one sanity check: 123 * whether IIO index is less than num_channels (that is specified in the 124 * iio_dev). 125 */ 126 static int __fwnode_iio_simple_xlate(struct iio_dev *indio_dev, 127 const struct fwnode_reference_args *iiospec) 128 { 129 if (!iiospec->nargs) 130 return 0; 131 132 if (iiospec->args[0] >= indio_dev->num_channels) { 133 dev_err(&indio_dev->dev, "invalid channel index %llu\n", 134 iiospec->args[0]); 135 return -EINVAL; 136 } 137 138 return iiospec->args[0]; 139 } 140 141 static int __fwnode_iio_channel_get(struct iio_channel *channel, 142 struct fwnode_handle *fwnode, int index) 143 { 144 struct fwnode_reference_args iiospec; 145 struct device *idev; 146 struct iio_dev *indio_dev; 147 int err; 148 149 err = fwnode_property_get_reference_args(fwnode, "io-channels", 150 "#io-channel-cells", 0, 151 index, &iiospec); 152 if (err) 153 return err; 154 155 idev = bus_find_device_by_fwnode(&iio_bus_type, iiospec.fwnode); 156 if (!idev) { 157 fwnode_handle_put(iiospec.fwnode); 158 return -EPROBE_DEFER; 159 } 160 161 indio_dev = dev_to_iio_dev(idev); 162 channel->indio_dev = indio_dev; 163 if (indio_dev->info->fwnode_xlate) 164 index = indio_dev->info->fwnode_xlate(indio_dev, &iiospec); 165 else 166 index = __fwnode_iio_simple_xlate(indio_dev, &iiospec); 167 fwnode_handle_put(iiospec.fwnode); 168 if (index < 0) 169 goto err_put; 170 channel->channel = &indio_dev->channels[index]; 171 172 return 0; 173 174 err_put: 175 iio_device_put(indio_dev); 176 return index; 177 } 178 179 static struct iio_channel *fwnode_iio_channel_get(struct fwnode_handle *fwnode, 180 int index) 181 { 182 int err; 183 184 if (index < 0) 185 return ERR_PTR(-EINVAL); 186 187 struct iio_channel *channel __free(kfree) = 188 kzalloc(sizeof(*channel), GFP_KERNEL); 189 if (!channel) 190 return ERR_PTR(-ENOMEM); 191 192 err = __fwnode_iio_channel_get(channel, fwnode, index); 193 if (err) 194 return ERR_PTR(err); 195 196 return_ptr(channel); 197 } 198 199 static struct iio_channel * 200 __fwnode_iio_channel_get_by_name(struct fwnode_handle *fwnode, const char *name) 201 { 202 struct iio_channel *chan; 203 int index = 0; 204 205 /* 206 * For named iio channels, first look up the name in the 207 * "io-channel-names" property. If it cannot be found, the 208 * index will be an error code, and fwnode_iio_channel_get() 209 * will fail. 210 */ 211 if (name) 212 index = fwnode_property_match_string(fwnode, "io-channel-names", 213 name); 214 215 chan = fwnode_iio_channel_get(fwnode, index); 216 if (!IS_ERR(chan) || PTR_ERR(chan) == -EPROBE_DEFER) 217 return chan; 218 if (name) { 219 if (index >= 0) { 220 pr_err("ERROR: could not get IIO channel %pfw:%s(%i)\n", 221 fwnode, name, index); 222 /* 223 * In this case, we found 'name' in 'io-channel-names' 224 * but somehow we still fail so that we should not proceed 225 * with any other lookup. Hence, explicitly return -EINVAL 226 * (maybe not the better error code) so that the caller 227 * won't do a system lookup. 228 */ 229 return ERR_PTR(-EINVAL); 230 } 231 /* 232 * If index < 0, then fwnode_property_get_reference_args() fails 233 * with -EINVAL or -ENOENT (ACPI case) which is expected. We 234 * should not proceed if we get any other error. 235 */ 236 if (PTR_ERR(chan) != -EINVAL && PTR_ERR(chan) != -ENOENT) 237 return chan; 238 } else if (PTR_ERR(chan) != -ENOENT) { 239 /* 240 * if !name, then we should only proceed the lookup if 241 * fwnode_property_get_reference_args() returns -ENOENT. 242 */ 243 return chan; 244 } 245 246 /* so we continue the lookup */ 247 return ERR_PTR(-ENODEV); 248 } 249 250 struct iio_channel *fwnode_iio_channel_get_by_name(struct fwnode_handle *fwnode, 251 const char *name) 252 { 253 struct fwnode_handle *parent; 254 struct iio_channel *chan; 255 256 /* Walk up the tree of devices looking for a matching iio channel */ 257 chan = __fwnode_iio_channel_get_by_name(fwnode, name); 258 if (!IS_ERR(chan) || PTR_ERR(chan) != -ENODEV) 259 return chan; 260 261 /* 262 * No matching IIO channel found on this node. 263 * If the parent node has a "io-channel-ranges" property, 264 * then we can try one of its channels. 265 */ 266 fwnode_for_each_parent_node(fwnode, parent) { 267 if (!fwnode_property_present(parent, "io-channel-ranges")) { 268 fwnode_handle_put(parent); 269 return ERR_PTR(-ENODEV); 270 } 271 272 chan = __fwnode_iio_channel_get_by_name(fwnode, name); 273 if (!IS_ERR(chan) || PTR_ERR(chan) != -ENODEV) { 274 fwnode_handle_put(parent); 275 return chan; 276 } 277 } 278 279 return ERR_PTR(-ENODEV); 280 } 281 EXPORT_SYMBOL_GPL(fwnode_iio_channel_get_by_name); 282 283 static struct iio_channel *fwnode_iio_channel_get_all(struct device *dev) 284 { 285 struct fwnode_handle *fwnode = dev_fwnode(dev); 286 int i, mapind, nummaps = 0; 287 int ret; 288 289 do { 290 ret = fwnode_property_get_reference_args(fwnode, "io-channels", 291 "#io-channel-cells", 0, 292 nummaps, NULL); 293 if (ret < 0) 294 break; 295 } while (++nummaps); 296 297 if (nummaps == 0) 298 return ERR_PTR(-ENODEV); 299 300 /* NULL terminated array to save passing size */ 301 struct iio_channel *chans __free(kfree) = 302 kcalloc(nummaps + 1, sizeof(*chans), GFP_KERNEL); 303 if (!chans) 304 return ERR_PTR(-ENOMEM); 305 306 /* Search for FW matches */ 307 for (mapind = 0; mapind < nummaps; mapind++) { 308 ret = __fwnode_iio_channel_get(&chans[mapind], fwnode, mapind); 309 if (ret) 310 goto error_free_chans; 311 } 312 return_ptr(chans); 313 314 error_free_chans: 315 for (i = 0; i < mapind; i++) 316 iio_device_put(chans[i].indio_dev); 317 return ERR_PTR(ret); 318 } 319 320 static struct iio_channel *iio_channel_get_sys(const char *name, 321 const char *channel_name) 322 { 323 struct iio_map_internal *c_i = NULL, *c = NULL; 324 int err; 325 326 if (!(name || channel_name)) 327 return ERR_PTR(-ENODEV); 328 329 /* first find matching entry the channel map */ 330 scoped_guard(mutex, &iio_map_list_lock) { 331 list_for_each_entry(c_i, &iio_map_list, l) { 332 if ((name && strcmp(name, c_i->map->consumer_dev_name) != 0) || 333 (channel_name && 334 strcmp(channel_name, c_i->map->consumer_channel) != 0)) 335 continue; 336 c = c_i; 337 iio_device_get(c->indio_dev); 338 break; 339 } 340 } 341 if (!c) 342 return ERR_PTR(-ENODEV); 343 344 struct iio_channel *channel __free(kfree) = 345 kzalloc(sizeof(*channel), GFP_KERNEL); 346 if (!channel) { 347 err = -ENOMEM; 348 goto error_no_mem; 349 } 350 351 channel->indio_dev = c->indio_dev; 352 353 if (c->map->adc_channel_label) { 354 channel->channel = 355 iio_chan_spec_from_name(channel->indio_dev, 356 c->map->adc_channel_label); 357 358 if (!channel->channel) { 359 err = -EINVAL; 360 goto error_no_mem; 361 } 362 } 363 364 return_ptr(channel); 365 366 error_no_mem: 367 iio_device_put(c->indio_dev); 368 return ERR_PTR(err); 369 } 370 371 struct iio_channel *iio_channel_get(struct device *dev, 372 const char *channel_name) 373 { 374 const char *name = dev ? dev_name(dev) : NULL; 375 struct iio_channel *channel; 376 377 if (dev) { 378 channel = fwnode_iio_channel_get_by_name(dev_fwnode(dev), 379 channel_name); 380 if (!IS_ERR(channel) || PTR_ERR(channel) != -ENODEV) 381 return channel; 382 } 383 384 return iio_channel_get_sys(name, channel_name); 385 } 386 EXPORT_SYMBOL_GPL(iio_channel_get); 387 388 void iio_channel_release(struct iio_channel *channel) 389 { 390 if (!channel) 391 return; 392 iio_device_put(channel->indio_dev); 393 kfree(channel); 394 } 395 EXPORT_SYMBOL_GPL(iio_channel_release); 396 397 static void devm_iio_channel_free(void *iio_channel) 398 { 399 iio_channel_release(iio_channel); 400 } 401 402 struct iio_channel *devm_iio_channel_get(struct device *dev, 403 const char *channel_name) 404 { 405 struct iio_channel *channel; 406 int ret; 407 408 channel = iio_channel_get(dev, channel_name); 409 if (IS_ERR(channel)) 410 return channel; 411 412 ret = devm_add_action_or_reset(dev, devm_iio_channel_free, channel); 413 if (ret) 414 return ERR_PTR(ret); 415 416 return channel; 417 } 418 EXPORT_SYMBOL_GPL(devm_iio_channel_get); 419 420 struct iio_channel *devm_fwnode_iio_channel_get_by_name(struct device *dev, 421 struct fwnode_handle *fwnode, 422 const char *channel_name) 423 { 424 struct iio_channel *channel; 425 int ret; 426 427 channel = fwnode_iio_channel_get_by_name(fwnode, channel_name); 428 if (IS_ERR(channel)) 429 return channel; 430 431 ret = devm_add_action_or_reset(dev, devm_iio_channel_free, channel); 432 if (ret) 433 return ERR_PTR(ret); 434 435 return channel; 436 } 437 EXPORT_SYMBOL_GPL(devm_fwnode_iio_channel_get_by_name); 438 439 struct iio_channel *iio_channel_get_all(struct device *dev) 440 { 441 const char *name; 442 struct iio_map_internal *c = NULL; 443 struct iio_channel *fw_chans; 444 int nummaps = 0; 445 int mapind = 0; 446 int i, ret; 447 448 if (!dev) 449 return ERR_PTR(-EINVAL); 450 451 fw_chans = fwnode_iio_channel_get_all(dev); 452 /* 453 * We only want to carry on if the error is -ENODEV. Anything else 454 * should be reported up the stack. 455 */ 456 if (!IS_ERR(fw_chans) || PTR_ERR(fw_chans) != -ENODEV) 457 return fw_chans; 458 459 name = dev_name(dev); 460 461 guard(mutex)(&iio_map_list_lock); 462 /* first count the matching maps */ 463 list_for_each_entry(c, &iio_map_list, l) 464 if (name && strcmp(name, c->map->consumer_dev_name) != 0) 465 continue; 466 else 467 nummaps++; 468 469 if (nummaps == 0) 470 return ERR_PTR(-ENODEV); 471 472 /* NULL terminated array to save passing size */ 473 struct iio_channel *chans __free(kfree) = 474 kcalloc(nummaps + 1, sizeof(*chans), GFP_KERNEL); 475 if (!chans) 476 return ERR_PTR(-ENOMEM); 477 478 /* for each map fill in the chans element */ 479 list_for_each_entry(c, &iio_map_list, l) { 480 if (name && strcmp(name, c->map->consumer_dev_name) != 0) 481 continue; 482 chans[mapind].indio_dev = c->indio_dev; 483 chans[mapind].data = c->map->consumer_data; 484 chans[mapind].channel = 485 iio_chan_spec_from_name(chans[mapind].indio_dev, 486 c->map->adc_channel_label); 487 if (!chans[mapind].channel) { 488 ret = -EINVAL; 489 goto error_free_chans; 490 } 491 iio_device_get(chans[mapind].indio_dev); 492 mapind++; 493 } 494 if (mapind == 0) { 495 ret = -ENODEV; 496 goto error_free_chans; 497 } 498 499 return_ptr(chans); 500 501 error_free_chans: 502 for (i = 0; i < nummaps; i++) 503 iio_device_put(chans[i].indio_dev); 504 return ERR_PTR(ret); 505 } 506 EXPORT_SYMBOL_GPL(iio_channel_get_all); 507 508 void iio_channel_release_all(struct iio_channel *channels) 509 { 510 struct iio_channel *chan = &channels[0]; 511 512 while (chan->indio_dev) { 513 iio_device_put(chan->indio_dev); 514 chan++; 515 } 516 kfree(channels); 517 } 518 EXPORT_SYMBOL_GPL(iio_channel_release_all); 519 520 static void devm_iio_channel_free_all(void *iio_channels) 521 { 522 iio_channel_release_all(iio_channels); 523 } 524 525 struct iio_channel *devm_iio_channel_get_all(struct device *dev) 526 { 527 struct iio_channel *channels; 528 int ret; 529 530 channels = iio_channel_get_all(dev); 531 if (IS_ERR(channels)) 532 return channels; 533 534 ret = devm_add_action_or_reset(dev, devm_iio_channel_free_all, 535 channels); 536 if (ret) 537 return ERR_PTR(ret); 538 539 return channels; 540 } 541 EXPORT_SYMBOL_GPL(devm_iio_channel_get_all); 542 543 static int iio_channel_read(struct iio_channel *chan, int *val, int *val2, 544 enum iio_chan_info_enum info) 545 { 546 int unused; 547 int vals[INDIO_MAX_RAW_ELEMENTS]; 548 int ret; 549 int val_len = 2; 550 551 if (!val2) 552 val2 = &unused; 553 554 if (!iio_channel_has_info(chan->channel, info)) 555 return -EINVAL; 556 557 if (chan->indio_dev->info->read_raw_multi) { 558 ret = chan->indio_dev->info->read_raw_multi(chan->indio_dev, 559 chan->channel, INDIO_MAX_RAW_ELEMENTS, 560 vals, &val_len, info); 561 *val = vals[0]; 562 *val2 = vals[1]; 563 } else { 564 ret = chan->indio_dev->info->read_raw(chan->indio_dev, 565 chan->channel, val, val2, info); 566 } 567 568 return ret; 569 } 570 571 int iio_read_channel_raw(struct iio_channel *chan, int *val) 572 { 573 struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(chan->indio_dev); 574 575 guard(mutex)(&iio_dev_opaque->info_exist_lock); 576 if (!chan->indio_dev->info) 577 return -ENODEV; 578 579 return iio_channel_read(chan, val, NULL, IIO_CHAN_INFO_RAW); 580 } 581 EXPORT_SYMBOL_GPL(iio_read_channel_raw); 582 583 int iio_read_channel_average_raw(struct iio_channel *chan, int *val) 584 { 585 struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(chan->indio_dev); 586 587 guard(mutex)(&iio_dev_opaque->info_exist_lock); 588 if (!chan->indio_dev->info) 589 return -ENODEV; 590 591 return iio_channel_read(chan, val, NULL, IIO_CHAN_INFO_AVERAGE_RAW); 592 } 593 EXPORT_SYMBOL_GPL(iio_read_channel_average_raw); 594 595 static int iio_convert_raw_to_processed_unlocked(struct iio_channel *chan, 596 int raw, int *processed, 597 unsigned int scale) 598 { 599 int scale_type, scale_val, scale_val2; 600 int offset_type, offset_val, offset_val2; 601 s64 raw64 = raw; 602 603 offset_type = iio_channel_read(chan, &offset_val, &offset_val2, 604 IIO_CHAN_INFO_OFFSET); 605 if (offset_type >= 0) { 606 switch (offset_type) { 607 case IIO_VAL_INT: 608 break; 609 case IIO_VAL_INT_PLUS_MICRO: 610 case IIO_VAL_INT_PLUS_NANO: 611 /* 612 * Both IIO_VAL_INT_PLUS_MICRO and IIO_VAL_INT_PLUS_NANO 613 * implicitely truncate the offset to it's integer form. 614 */ 615 break; 616 case IIO_VAL_FRACTIONAL: 617 offset_val /= offset_val2; 618 break; 619 case IIO_VAL_FRACTIONAL_LOG2: 620 offset_val >>= offset_val2; 621 break; 622 default: 623 return -EINVAL; 624 } 625 626 raw64 += offset_val; 627 } 628 629 scale_type = iio_channel_read(chan, &scale_val, &scale_val2, 630 IIO_CHAN_INFO_SCALE); 631 if (scale_type < 0) { 632 /* 633 * If no channel scaling is available apply consumer scale to 634 * raw value and return. 635 */ 636 *processed = raw * scale; 637 return 0; 638 } 639 640 switch (scale_type) { 641 case IIO_VAL_INT: 642 *processed = raw64 * scale_val * scale; 643 break; 644 case IIO_VAL_INT_PLUS_MICRO: 645 if (scale_val2 < 0) 646 *processed = -raw64 * scale_val; 647 else 648 *processed = raw64 * scale_val; 649 *processed += div_s64(raw64 * (s64)scale_val2 * scale, 650 1000000LL); 651 break; 652 case IIO_VAL_INT_PLUS_NANO: 653 if (scale_val2 < 0) 654 *processed = -raw64 * scale_val; 655 else 656 *processed = raw64 * scale_val; 657 *processed += div_s64(raw64 * (s64)scale_val2 * scale, 658 1000000000LL); 659 break; 660 case IIO_VAL_FRACTIONAL: 661 *processed = div_s64(raw64 * (s64)scale_val * scale, 662 scale_val2); 663 break; 664 case IIO_VAL_FRACTIONAL_LOG2: 665 *processed = (raw64 * (s64)scale_val * scale) >> scale_val2; 666 break; 667 default: 668 return -EINVAL; 669 } 670 671 return 0; 672 } 673 674 int iio_convert_raw_to_processed(struct iio_channel *chan, int raw, 675 int *processed, unsigned int scale) 676 { 677 struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(chan->indio_dev); 678 679 guard(mutex)(&iio_dev_opaque->info_exist_lock); 680 if (!chan->indio_dev->info) 681 return -ENODEV; 682 683 return iio_convert_raw_to_processed_unlocked(chan, raw, processed, 684 scale); 685 } 686 EXPORT_SYMBOL_GPL(iio_convert_raw_to_processed); 687 688 int iio_read_channel_attribute(struct iio_channel *chan, int *val, int *val2, 689 enum iio_chan_info_enum attribute) 690 { 691 struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(chan->indio_dev); 692 693 guard(mutex)(&iio_dev_opaque->info_exist_lock); 694 if (!chan->indio_dev->info) 695 return -ENODEV; 696 697 return iio_channel_read(chan, val, val2, attribute); 698 } 699 EXPORT_SYMBOL_GPL(iio_read_channel_attribute); 700 701 int iio_read_channel_offset(struct iio_channel *chan, int *val, int *val2) 702 { 703 return iio_read_channel_attribute(chan, val, val2, IIO_CHAN_INFO_OFFSET); 704 } 705 EXPORT_SYMBOL_GPL(iio_read_channel_offset); 706 707 int iio_read_channel_processed_scale(struct iio_channel *chan, int *val, 708 unsigned int scale) 709 { 710 struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(chan->indio_dev); 711 int ret; 712 713 guard(mutex)(&iio_dev_opaque->info_exist_lock); 714 if (!chan->indio_dev->info) 715 return -ENODEV; 716 717 if (iio_channel_has_info(chan->channel, IIO_CHAN_INFO_PROCESSED)) { 718 ret = iio_channel_read(chan, val, NULL, 719 IIO_CHAN_INFO_PROCESSED); 720 if (ret < 0) 721 return ret; 722 *val *= scale; 723 724 return ret; 725 } else { 726 ret = iio_channel_read(chan, val, NULL, IIO_CHAN_INFO_RAW); 727 if (ret < 0) 728 return ret; 729 730 return iio_convert_raw_to_processed_unlocked(chan, *val, val, 731 scale); 732 } 733 } 734 EXPORT_SYMBOL_GPL(iio_read_channel_processed_scale); 735 736 int iio_read_channel_processed(struct iio_channel *chan, int *val) 737 { 738 /* This is just a special case with scale factor 1 */ 739 return iio_read_channel_processed_scale(chan, val, 1); 740 } 741 EXPORT_SYMBOL_GPL(iio_read_channel_processed); 742 743 int iio_read_channel_scale(struct iio_channel *chan, int *val, int *val2) 744 { 745 return iio_read_channel_attribute(chan, val, val2, IIO_CHAN_INFO_SCALE); 746 } 747 EXPORT_SYMBOL_GPL(iio_read_channel_scale); 748 749 static int iio_channel_read_avail(struct iio_channel *chan, 750 const int **vals, int *type, int *length, 751 enum iio_chan_info_enum info) 752 { 753 if (!iio_channel_has_available(chan->channel, info)) 754 return -EINVAL; 755 756 return chan->indio_dev->info->read_avail(chan->indio_dev, chan->channel, 757 vals, type, length, info); 758 } 759 760 int iio_read_avail_channel_attribute(struct iio_channel *chan, 761 const int **vals, int *type, int *length, 762 enum iio_chan_info_enum attribute) 763 { 764 struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(chan->indio_dev); 765 766 guard(mutex)(&iio_dev_opaque->info_exist_lock); 767 if (!chan->indio_dev->info) 768 return -ENODEV; 769 770 return iio_channel_read_avail(chan, vals, type, length, attribute); 771 } 772 EXPORT_SYMBOL_GPL(iio_read_avail_channel_attribute); 773 774 int iio_read_avail_channel_raw(struct iio_channel *chan, 775 const int **vals, int *length) 776 { 777 int ret; 778 int type; 779 780 ret = iio_read_avail_channel_attribute(chan, vals, &type, length, 781 IIO_CHAN_INFO_RAW); 782 783 if (ret >= 0 && type != IIO_VAL_INT) 784 /* raw values are assumed to be IIO_VAL_INT */ 785 ret = -EINVAL; 786 787 return ret; 788 } 789 EXPORT_SYMBOL_GPL(iio_read_avail_channel_raw); 790 791 static int iio_channel_read_max(struct iio_channel *chan, 792 int *val, int *val2, int *type, 793 enum iio_chan_info_enum info) 794 { 795 const int *vals; 796 int length; 797 int ret; 798 799 ret = iio_channel_read_avail(chan, &vals, type, &length, info); 800 if (ret < 0) 801 return ret; 802 803 switch (ret) { 804 case IIO_AVAIL_RANGE: 805 switch (*type) { 806 case IIO_VAL_INT: 807 *val = vals[2]; 808 break; 809 default: 810 *val = vals[4]; 811 if (val2) 812 *val2 = vals[5]; 813 } 814 return 0; 815 816 case IIO_AVAIL_LIST: 817 if (length <= 0) 818 return -EINVAL; 819 switch (*type) { 820 case IIO_VAL_INT: 821 *val = max_array(vals, length); 822 break; 823 default: 824 /* TODO: learn about max for other iio values */ 825 return -EINVAL; 826 } 827 return 0; 828 829 default: 830 return -EINVAL; 831 } 832 } 833 834 int iio_read_max_channel_raw(struct iio_channel *chan, int *val) 835 { 836 struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(chan->indio_dev); 837 int type; 838 839 guard(mutex)(&iio_dev_opaque->info_exist_lock); 840 if (!chan->indio_dev->info) 841 return -ENODEV; 842 843 return iio_channel_read_max(chan, val, NULL, &type, IIO_CHAN_INFO_RAW); 844 } 845 EXPORT_SYMBOL_GPL(iio_read_max_channel_raw); 846 847 static int iio_channel_read_min(struct iio_channel *chan, 848 int *val, int *val2, int *type, 849 enum iio_chan_info_enum info) 850 { 851 const int *vals; 852 int length; 853 int ret; 854 855 ret = iio_channel_read_avail(chan, &vals, type, &length, info); 856 if (ret < 0) 857 return ret; 858 859 switch (ret) { 860 case IIO_AVAIL_RANGE: 861 switch (*type) { 862 case IIO_VAL_INT: 863 *val = vals[0]; 864 break; 865 default: 866 *val = vals[0]; 867 if (val2) 868 *val2 = vals[1]; 869 } 870 return 0; 871 872 case IIO_AVAIL_LIST: 873 if (length <= 0) 874 return -EINVAL; 875 switch (*type) { 876 case IIO_VAL_INT: 877 *val = min_array(vals, length); 878 break; 879 default: 880 /* TODO: learn about min for other iio values */ 881 return -EINVAL; 882 } 883 return 0; 884 885 default: 886 return -EINVAL; 887 } 888 } 889 890 int iio_read_min_channel_raw(struct iio_channel *chan, int *val) 891 { 892 struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(chan->indio_dev); 893 int type; 894 895 guard(mutex)(&iio_dev_opaque->info_exist_lock); 896 if (!chan->indio_dev->info) 897 return -ENODEV; 898 899 return iio_channel_read_min(chan, val, NULL, &type, IIO_CHAN_INFO_RAW); 900 } 901 EXPORT_SYMBOL_GPL(iio_read_min_channel_raw); 902 903 int iio_get_channel_type(struct iio_channel *chan, enum iio_chan_type *type) 904 { 905 struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(chan->indio_dev); 906 907 guard(mutex)(&iio_dev_opaque->info_exist_lock); 908 if (!chan->indio_dev->info) 909 return -ENODEV; 910 911 *type = chan->channel->type; 912 913 return 0; 914 } 915 EXPORT_SYMBOL_GPL(iio_get_channel_type); 916 917 static int iio_channel_write(struct iio_channel *chan, int val, int val2, 918 enum iio_chan_info_enum info) 919 { 920 return chan->indio_dev->info->write_raw(chan->indio_dev, 921 chan->channel, val, val2, info); 922 } 923 924 int iio_write_channel_attribute(struct iio_channel *chan, int val, int val2, 925 enum iio_chan_info_enum attribute) 926 { 927 struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(chan->indio_dev); 928 929 guard(mutex)(&iio_dev_opaque->info_exist_lock); 930 if (!chan->indio_dev->info) 931 return -ENODEV; 932 933 return iio_channel_write(chan, val, val2, attribute); 934 } 935 EXPORT_SYMBOL_GPL(iio_write_channel_attribute); 936 937 int iio_write_channel_raw(struct iio_channel *chan, int val) 938 { 939 return iio_write_channel_attribute(chan, val, 0, IIO_CHAN_INFO_RAW); 940 } 941 EXPORT_SYMBOL_GPL(iio_write_channel_raw); 942 943 unsigned int iio_get_channel_ext_info_count(struct iio_channel *chan) 944 { 945 const struct iio_chan_spec_ext_info *ext_info; 946 unsigned int i = 0; 947 948 if (!chan->channel->ext_info) 949 return i; 950 951 for (ext_info = chan->channel->ext_info; ext_info->name; ext_info++) 952 ++i; 953 954 return i; 955 } 956 EXPORT_SYMBOL_GPL(iio_get_channel_ext_info_count); 957 958 static const struct iio_chan_spec_ext_info * 959 iio_lookup_ext_info(const struct iio_channel *chan, const char *attr) 960 { 961 const struct iio_chan_spec_ext_info *ext_info; 962 963 if (!chan->channel->ext_info) 964 return NULL; 965 966 for (ext_info = chan->channel->ext_info; ext_info->name; ++ext_info) { 967 if (!strcmp(attr, ext_info->name)) 968 return ext_info; 969 } 970 971 return NULL; 972 } 973 974 ssize_t iio_read_channel_ext_info(struct iio_channel *chan, 975 const char *attr, char *buf) 976 { 977 const struct iio_chan_spec_ext_info *ext_info; 978 979 ext_info = iio_lookup_ext_info(chan, attr); 980 if (!ext_info) 981 return -EINVAL; 982 983 return ext_info->read(chan->indio_dev, ext_info->private, 984 chan->channel, buf); 985 } 986 EXPORT_SYMBOL_GPL(iio_read_channel_ext_info); 987 988 ssize_t iio_write_channel_ext_info(struct iio_channel *chan, const char *attr, 989 const char *buf, size_t len) 990 { 991 const struct iio_chan_spec_ext_info *ext_info; 992 993 ext_info = iio_lookup_ext_info(chan, attr); 994 if (!ext_info) 995 return -EINVAL; 996 997 return ext_info->write(chan->indio_dev, ext_info->private, 998 chan->channel, buf, len); 999 } 1000 EXPORT_SYMBOL_GPL(iio_write_channel_ext_info); 1001