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