linux/drivers/iio/inkern.c
<<
>>
Prefs
   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
  18struct iio_map_internal {
  19        struct iio_dev *indio_dev;
  20        struct iio_map *map;
  21        struct list_head l;
  22};
  23
  24static LIST_HEAD(iio_map_list);
  25static DEFINE_MUTEX(iio_map_list_lock);
  26
  27int 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        }
  47error_ret:
  48        mutex_unlock(&iio_map_list_lock);
  49
  50        return ret;
  51}
  52EXPORT_SYMBOL_GPL(iio_map_array_register);
  53
  54
  55/*
  56 * Remove all map entries associated with the given iio device
  57 */
  58int 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}
  74EXPORT_SYMBOL_GPL(iio_map_array_unregister);
  75
  76static 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
  93static 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 */
 108static 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
 123static 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
 155err_put:
 156        iio_device_put(indio_dev);
 157        return index;
 158}
 159
 160static 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
 178err_free_channel:
 179        kfree(channel);
 180        return ERR_PTR(err);
 181}
 182
 183static 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
 223static 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
 255error_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
 264static inline struct iio_channel *
 265of_iio_channel_get_by_name(struct device_node *np, const char *name)
 266{
 267        return NULL;
 268}
 269
 270static inline struct iio_channel *of_iio_channel_get_all(struct device *dev)
 271{
 272        return NULL;
 273}
 274
 275#endif /* CONFIG_OF */
 276
 277static 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
 323error_no_chan:
 324        kfree(channel);
 325error_no_mem:
 326        iio_device_put(c->indio_dev);
 327        return ERR_PTR(err);
 328}
 329
 330struct 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}
 345EXPORT_SYMBOL_GPL(iio_channel_get);
 346
 347void iio_channel_release(struct iio_channel *channel)
 348{
 349        if (!channel)
 350                return;
 351        iio_device_put(channel->indio_dev);
 352        kfree(channel);
 353}
 354EXPORT_SYMBOL_GPL(iio_channel_release);
 355
 356static 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
 363static 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
 375struct 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}
 395EXPORT_SYMBOL_GPL(devm_iio_channel_get);
 396
 397void 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}
 402EXPORT_SYMBOL_GPL(devm_iio_channel_release);
 403
 404struct 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
 466error_free_chans:
 467        for (i = 0; i < nummaps; i++)
 468                iio_device_put(chans[i].indio_dev);
 469        kfree(chans);
 470error_ret:
 471        mutex_unlock(&iio_map_list_lock);
 472
 473        return ERR_PTR(ret);
 474}
 475EXPORT_SYMBOL_GPL(iio_channel_get_all);
 476
 477void 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}
 487EXPORT_SYMBOL_GPL(iio_channel_release_all);
 488
 489static 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
 496struct 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}
 515EXPORT_SYMBOL_GPL(devm_iio_channel_get_all);
 516
 517void 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}
 523EXPORT_SYMBOL_GPL(devm_iio_channel_release_all);
 524
 525static 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
 552int 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);
 563err_unlock:
 564        mutex_unlock(&chan->indio_dev->info_exist_lock);
 565
 566        return ret;
 567}
 568EXPORT_SYMBOL_GPL(iio_read_channel_raw);
 569
 570int 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);
 581err_unlock:
 582        mutex_unlock(&chan->indio_dev->info_exist_lock);
 583
 584        return ret;
 585}
 586EXPORT_SYMBOL_GPL(iio_read_channel_average_raw);
 587
 588static 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
 644int 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);
 657err_unlock:
 658        mutex_unlock(&chan->indio_dev->info_exist_lock);
 659
 660        return ret;
 661}
 662EXPORT_SYMBOL_GPL(iio_convert_raw_to_processed);
 663
 664int 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);
 676err_unlock:
 677        mutex_unlock(&chan->indio_dev->info_exist_lock);
 678
 679        return ret;
 680}
 681EXPORT_SYMBOL_GPL(iio_read_channel_attribute);
 682
 683int 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}
 687EXPORT_SYMBOL_GPL(iio_read_channel_offset);
 688
 689int 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
 709err_unlock:
 710        mutex_unlock(&chan->indio_dev->info_exist_lock);
 711
 712        return ret;
 713}
 714EXPORT_SYMBOL_GPL(iio_read_channel_processed);
 715
 716int 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}
 720EXPORT_SYMBOL_GPL(iio_read_channel_scale);
 721
 722static 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
 733int 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);
 746err_unlock:
 747        mutex_unlock(&chan->indio_dev->info_exist_lock);
 748
 749        return ret;
 750}
 751EXPORT_SYMBOL_GPL(iio_read_avail_channel_attribute);
 752
 753int 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}
 768EXPORT_SYMBOL_GPL(iio_read_avail_channel_raw);
 769
 770static 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
 817int 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);
 829err_unlock:
 830        mutex_unlock(&chan->indio_dev->info_exist_lock);
 831
 832        return ret;
 833}
 834EXPORT_SYMBOL_GPL(iio_read_max_channel_raw);
 835
 836int 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;
 848err_unlock:
 849        mutex_unlock(&chan->indio_dev->info_exist_lock);
 850
 851        return ret;
 852}
 853EXPORT_SYMBOL_GPL(iio_get_channel_type);
 854
 855static 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
 862int 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);
 874err_unlock:
 875        mutex_unlock(&chan->indio_dev->info_exist_lock);
 876
 877        return ret;
 878}
 879EXPORT_SYMBOL_GPL(iio_write_channel_attribute);
 880
 881int 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}
 885EXPORT_SYMBOL_GPL(iio_write_channel_raw);
 886
 887unsigned 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}
 900EXPORT_SYMBOL_GPL(iio_get_channel_ext_info_count);
 901
 902static 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
 919ssize_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}
 931EXPORT_SYMBOL_GPL(iio_read_channel_ext_info);
 932
 933ssize_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}
 945EXPORT_SYMBOL_GPL(iio_write_channel_ext_info);
 946