root/drivers/iio/inkern.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. iio_map_array_register
  2. iio_map_array_unregister
  3. iio_chan_spec_from_name
  4. iio_dev_node_match
  5. __of_iio_simple_xlate
  6. __of_iio_channel_get
  7. of_iio_channel_get
  8. of_iio_channel_get_by_name
  9. of_iio_channel_get_all
  10. of_iio_channel_get_by_name
  11. of_iio_channel_get_all
  12. iio_channel_get_sys
  13. iio_channel_get
  14. iio_channel_release
  15. devm_iio_channel_free
  16. devm_iio_channel_match
  17. devm_iio_channel_get
  18. devm_iio_channel_release
  19. iio_channel_get_all
  20. iio_channel_release_all
  21. devm_iio_channel_free_all
  22. devm_iio_channel_get_all
  23. devm_iio_channel_release_all
  24. iio_channel_read
  25. iio_read_channel_raw
  26. iio_read_channel_average_raw
  27. iio_convert_raw_to_processed_unlocked
  28. iio_convert_raw_to_processed
  29. iio_read_channel_attribute
  30. iio_read_channel_offset
  31. iio_read_channel_processed
  32. iio_read_channel_scale
  33. iio_channel_read_avail
  34. iio_read_avail_channel_attribute
  35. iio_read_avail_channel_raw
  36. iio_channel_read_max
  37. iio_read_max_channel_raw
  38. iio_get_channel_type
  39. iio_channel_write
  40. iio_write_channel_attribute
  41. iio_write_channel_raw
  42. iio_get_channel_ext_info_count
  43. iio_lookup_ext_info
  44. iio_read_channel_ext_info
  45. iio_write_channel_ext_info

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

/* [<][>][^][v][top][bottom][index][help] */