linux/drivers/iio/inkern.c
<<
>>
Prefs
   1/* The industrial I/O core in kernel channel mapping
   2 *
   3 * Copyright (c) 2011 Jonathan Cameron
   4 *
   5 * This program is free software; you can redistribute it and/or modify it
   6 * under the terms of the GNU General Public License version 2 as published by
   7 * the Free Software Foundation.
   8 */
   9#include <linux/err.h>
  10#include <linux/export.h>
  11#include <linux/slab.h>
  12#include <linux/mutex.h>
  13#include <linux/of.h>
  14
  15#include <linux/iio/iio.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
  21struct iio_map_internal {
  22        struct iio_dev *indio_dev;
  23        struct iio_map *map;
  24        struct list_head l;
  25};
  26
  27static LIST_HEAD(iio_map_list);
  28static DEFINE_MUTEX(iio_map_list_lock);
  29
  30int iio_map_array_register(struct iio_dev *indio_dev, struct iio_map *maps)
  31{
  32        int i = 0, ret = 0;
  33        struct iio_map_internal *mapi;
  34
  35        if (maps == NULL)
  36                return 0;
  37
  38        mutex_lock(&iio_map_list_lock);
  39        while (maps[i].consumer_dev_name != NULL) {
  40                mapi = kzalloc(sizeof(*mapi), GFP_KERNEL);
  41                if (mapi == NULL) {
  42                        ret = -ENOMEM;
  43                        goto error_ret;
  44                }
  45                mapi->map = &maps[i];
  46                mapi->indio_dev = indio_dev;
  47                list_add(&mapi->l, &iio_map_list);
  48                i++;
  49        }
  50error_ret:
  51        mutex_unlock(&iio_map_list_lock);
  52
  53        return ret;
  54}
  55EXPORT_SYMBOL_GPL(iio_map_array_register);
  56
  57
  58/*
  59 * Remove all map entries associated with the given iio device
  60 */
  61int iio_map_array_unregister(struct iio_dev *indio_dev)
  62{
  63        int ret = -ENODEV;
  64        struct iio_map_internal *mapi;
  65        struct list_head *pos, *tmp;
  66
  67        mutex_lock(&iio_map_list_lock);
  68        list_for_each_safe(pos, tmp, &iio_map_list) {
  69                mapi = list_entry(pos, struct iio_map_internal, l);
  70                if (indio_dev == mapi->indio_dev) {
  71                        list_del(&mapi->l);
  72                        kfree(mapi);
  73                        ret = 0;
  74                }
  75        }
  76        mutex_unlock(&iio_map_list_lock);
  77        return ret;
  78}
  79EXPORT_SYMBOL_GPL(iio_map_array_unregister);
  80
  81static const struct iio_chan_spec
  82*iio_chan_spec_from_name(const struct iio_dev *indio_dev, const char *name)
  83{
  84        int i;
  85        const struct iio_chan_spec *chan = NULL;
  86
  87        for (i = 0; i < indio_dev->num_channels; i++)
  88                if (indio_dev->channels[i].datasheet_name &&
  89                    strcmp(name, indio_dev->channels[i].datasheet_name) == 0) {
  90                        chan = &indio_dev->channels[i];
  91                        break;
  92                }
  93        return chan;
  94}
  95
  96#ifdef CONFIG_OF
  97
  98static int iio_dev_node_match(struct device *dev, void *data)
  99{
 100        return dev->of_node == data && dev->type == &iio_device_type;
 101}
 102
 103/**
 104 * __of_iio_simple_xlate - translate iiospec to the IIO channel index
 105 * @indio_dev:  pointer to the iio_dev structure
 106 * @iiospec:    IIO specifier as found in the device tree
 107 *
 108 * This is simple translation function, suitable for the most 1:1 mapped
 109 * channels in IIO chips. This function performs only one sanity check:
 110 * whether IIO index is less than num_channels (that is specified in the
 111 * iio_dev).
 112 */
 113static int __of_iio_simple_xlate(struct iio_dev *indio_dev,
 114                                const struct of_phandle_args *iiospec)
 115{
 116        if (!iiospec->args_count)
 117                return 0;
 118
 119        if (iiospec->args[0] >= indio_dev->num_channels) {
 120                dev_err(&indio_dev->dev, "invalid channel index %u\n",
 121                        iiospec->args[0]);
 122                return -EINVAL;
 123        }
 124
 125        return iiospec->args[0];
 126}
 127
 128static int __of_iio_channel_get(struct iio_channel *channel,
 129                                struct device_node *np, int index)
 130{
 131        struct device *idev;
 132        struct iio_dev *indio_dev;
 133        int err;
 134        struct of_phandle_args iiospec;
 135
 136        err = of_parse_phandle_with_args(np, "io-channels",
 137                                         "#io-channel-cells",
 138                                         index, &iiospec);
 139        if (err)
 140                return err;
 141
 142        idev = bus_find_device(&iio_bus_type, NULL, iiospec.np,
 143                               iio_dev_node_match);
 144        of_node_put(iiospec.np);
 145        if (idev == NULL)
 146                return -EPROBE_DEFER;
 147
 148        indio_dev = dev_to_iio_dev(idev);
 149        channel->indio_dev = indio_dev;
 150        if (indio_dev->info->of_xlate)
 151                index = indio_dev->info->of_xlate(indio_dev, &iiospec);
 152        else
 153                index = __of_iio_simple_xlate(indio_dev, &iiospec);
 154        if (index < 0)
 155                goto err_put;
 156        channel->channel = &indio_dev->channels[index];
 157
 158        return 0;
 159
 160err_put:
 161        iio_device_put(indio_dev);
 162        return index;
 163}
 164
 165static struct iio_channel *of_iio_channel_get(struct device_node *np, int index)
 166{
 167        struct iio_channel *channel;
 168        int err;
 169
 170        if (index < 0)
 171                return ERR_PTR(-EINVAL);
 172
 173        channel = kzalloc(sizeof(*channel), GFP_KERNEL);
 174        if (channel == NULL)
 175                return ERR_PTR(-ENOMEM);
 176
 177        err = __of_iio_channel_get(channel, np, index);
 178        if (err)
 179                goto err_free_channel;
 180
 181        return channel;
 182
 183err_free_channel:
 184        kfree(channel);
 185        return ERR_PTR(err);
 186}
 187
 188static struct iio_channel *of_iio_channel_get_by_name(struct device_node *np,
 189                                                      const char *name)
 190{
 191        struct iio_channel *chan = NULL;
 192
 193        /* Walk up the tree of devices looking for a matching iio channel */
 194        while (np) {
 195                int index = 0;
 196
 197                /*
 198                 * For named iio channels, first look up the name in the
 199                 * "io-channel-names" property.  If it cannot be found, the
 200                 * index will be an error code, and of_iio_channel_get()
 201                 * will fail.
 202                 */
 203                if (name)
 204                        index = of_property_match_string(np, "io-channel-names",
 205                                                         name);
 206                chan = of_iio_channel_get(np, index);
 207                if (!IS_ERR(chan) || PTR_ERR(chan) == -EPROBE_DEFER)
 208                        break;
 209                else if (name && index >= 0) {
 210                        pr_err("ERROR: could not get IIO channel %s:%s(%i)\n",
 211                                np->full_name, name ? name : "", index);
 212                        return NULL;
 213                }
 214
 215                /*
 216                 * No matching IIO channel found on this node.
 217                 * If the parent node has a "io-channel-ranges" property,
 218                 * then we can try one of its channels.
 219                 */
 220                np = np->parent;
 221                if (np && !of_get_property(np, "io-channel-ranges", NULL))
 222                        return NULL;
 223        }
 224
 225        return chan;
 226}
 227
 228static struct iio_channel *of_iio_channel_get_all(struct device *dev)
 229{
 230        struct iio_channel *chans;
 231        int i, mapind, nummaps = 0;
 232        int ret;
 233
 234        do {
 235                ret = of_parse_phandle_with_args(dev->of_node,
 236                                                 "io-channels",
 237                                                 "#io-channel-cells",
 238                                                 nummaps, NULL);
 239                if (ret < 0)
 240                        break;
 241        } while (++nummaps);
 242
 243        if (nummaps == 0)       /* no error, return NULL to search map table */
 244                return NULL;
 245
 246        /* NULL terminated array to save passing size */
 247        chans = kcalloc(nummaps + 1, sizeof(*chans), GFP_KERNEL);
 248        if (chans == NULL)
 249                return ERR_PTR(-ENOMEM);
 250
 251        /* Search for OF matches */
 252        for (mapind = 0; mapind < nummaps; mapind++) {
 253                ret = __of_iio_channel_get(&chans[mapind], dev->of_node,
 254                                           mapind);
 255                if (ret)
 256                        goto error_free_chans;
 257        }
 258        return chans;
 259
 260error_free_chans:
 261        for (i = 0; i < mapind; i++)
 262                iio_device_put(chans[i].indio_dev);
 263        kfree(chans);
 264        return ERR_PTR(ret);
 265}
 266
 267#else /* CONFIG_OF */
 268
 269static inline struct iio_channel *
 270of_iio_channel_get_by_name(struct device_node *np, const char *name)
 271{
 272        return NULL;
 273}
 274
 275static inline struct iio_channel *of_iio_channel_get_all(struct device *dev)
 276{
 277        return NULL;
 278}
 279
 280#endif /* CONFIG_OF */
 281
 282static struct iio_channel *iio_channel_get_sys(const char *name,
 283                                               const char *channel_name)
 284{
 285        struct iio_map_internal *c_i = NULL, *c = NULL;
 286        struct iio_channel *channel;
 287        int err;
 288
 289        if (name == NULL && channel_name == NULL)
 290                return ERR_PTR(-ENODEV);
 291
 292        /* first find matching entry the channel map */
 293        mutex_lock(&iio_map_list_lock);
 294        list_for_each_entry(c_i, &iio_map_list, l) {
 295                if ((name && strcmp(name, c_i->map->consumer_dev_name) != 0) ||
 296                    (channel_name &&
 297                     strcmp(channel_name, c_i->map->consumer_channel) != 0))
 298                        continue;
 299                c = c_i;
 300                iio_device_get(c->indio_dev);
 301                break;
 302        }
 303        mutex_unlock(&iio_map_list_lock);
 304        if (c == NULL)
 305                return ERR_PTR(-ENODEV);
 306
 307        channel = kzalloc(sizeof(*channel), GFP_KERNEL);
 308        if (channel == NULL) {
 309                err = -ENOMEM;
 310                goto error_no_mem;
 311        }
 312
 313        channel->indio_dev = c->indio_dev;
 314
 315        if (c->map->adc_channel_label) {
 316                channel->channel =
 317                        iio_chan_spec_from_name(channel->indio_dev,
 318                                                c->map->adc_channel_label);
 319
 320                if (channel->channel == NULL) {
 321                        err = -EINVAL;
 322                        goto error_no_chan;
 323                }
 324        }
 325
 326        return channel;
 327
 328error_no_chan:
 329        kfree(channel);
 330error_no_mem:
 331        iio_device_put(c->indio_dev);
 332        return ERR_PTR(err);
 333}
 334
 335struct iio_channel *iio_channel_get(struct device *dev,
 336                                    const char *channel_name)
 337{
 338        const char *name = dev ? dev_name(dev) : NULL;
 339        struct iio_channel *channel;
 340
 341        if (dev) {
 342                channel = of_iio_channel_get_by_name(dev->of_node,
 343                                                     channel_name);
 344                if (channel != NULL)
 345                        return channel;
 346        }
 347
 348        return iio_channel_get_sys(name, channel_name);
 349}
 350EXPORT_SYMBOL_GPL(iio_channel_get);
 351
 352void iio_channel_release(struct iio_channel *channel)
 353{
 354        iio_device_put(channel->indio_dev);
 355        kfree(channel);
 356}
 357EXPORT_SYMBOL_GPL(iio_channel_release);
 358
 359struct iio_channel *iio_channel_get_all(struct device *dev)
 360{
 361        const char *name;
 362        struct iio_channel *chans;
 363        struct iio_map_internal *c = NULL;
 364        int nummaps = 0;
 365        int mapind = 0;
 366        int i, ret;
 367
 368        if (dev == NULL)
 369                return ERR_PTR(-EINVAL);
 370
 371        chans = of_iio_channel_get_all(dev);
 372        if (chans)
 373                return chans;
 374
 375        name = dev_name(dev);
 376
 377        mutex_lock(&iio_map_list_lock);
 378        /* first count the matching maps */
 379        list_for_each_entry(c, &iio_map_list, l)
 380                if (name && strcmp(name, c->map->consumer_dev_name) != 0)
 381                        continue;
 382                else
 383                        nummaps++;
 384
 385        if (nummaps == 0) {
 386                ret = -ENODEV;
 387                goto error_ret;
 388        }
 389
 390        /* NULL terminated array to save passing size */
 391        chans = kzalloc(sizeof(*chans)*(nummaps + 1), GFP_KERNEL);
 392        if (chans == NULL) {
 393                ret = -ENOMEM;
 394                goto error_ret;
 395        }
 396
 397        /* for each map fill in the chans element */
 398        list_for_each_entry(c, &iio_map_list, l) {
 399                if (name && strcmp(name, c->map->consumer_dev_name) != 0)
 400                        continue;
 401                chans[mapind].indio_dev = c->indio_dev;
 402                chans[mapind].data = c->map->consumer_data;
 403                chans[mapind].channel =
 404                        iio_chan_spec_from_name(chans[mapind].indio_dev,
 405                                                c->map->adc_channel_label);
 406                if (chans[mapind].channel == NULL) {
 407                        ret = -EINVAL;
 408                        goto error_free_chans;
 409                }
 410                iio_device_get(chans[mapind].indio_dev);
 411                mapind++;
 412        }
 413        if (mapind == 0) {
 414                ret = -ENODEV;
 415                goto error_free_chans;
 416        }
 417        mutex_unlock(&iio_map_list_lock);
 418
 419        return chans;
 420
 421error_free_chans:
 422        for (i = 0; i < nummaps; i++)
 423                iio_device_put(chans[i].indio_dev);
 424        kfree(chans);
 425error_ret:
 426        mutex_unlock(&iio_map_list_lock);
 427
 428        return ERR_PTR(ret);
 429}
 430EXPORT_SYMBOL_GPL(iio_channel_get_all);
 431
 432void iio_channel_release_all(struct iio_channel *channels)
 433{
 434        struct iio_channel *chan = &channels[0];
 435
 436        while (chan->indio_dev) {
 437                iio_device_put(chan->indio_dev);
 438                chan++;
 439        }
 440        kfree(channels);
 441}
 442EXPORT_SYMBOL_GPL(iio_channel_release_all);
 443
 444static int iio_channel_read(struct iio_channel *chan, int *val, int *val2,
 445        enum iio_chan_info_enum info)
 446{
 447        int unused;
 448        int vals[INDIO_MAX_RAW_ELEMENTS];
 449        int ret;
 450        int val_len = 2;
 451
 452        if (val2 == NULL)
 453                val2 = &unused;
 454
 455        if(!iio_channel_has_info(chan->channel, info))
 456                return -EINVAL;
 457
 458        if (chan->indio_dev->info->read_raw_multi) {
 459                ret = chan->indio_dev->info->read_raw_multi(chan->indio_dev,
 460                                        chan->channel, INDIO_MAX_RAW_ELEMENTS,
 461                                        vals, &val_len, info);
 462                *val = vals[0];
 463                *val2 = vals[1];
 464        } else
 465                ret = chan->indio_dev->info->read_raw(chan->indio_dev,
 466                                        chan->channel, val, val2, info);
 467
 468        return ret;
 469}
 470
 471int iio_read_channel_raw(struct iio_channel *chan, int *val)
 472{
 473        int ret;
 474
 475        mutex_lock(&chan->indio_dev->info_exist_lock);
 476        if (chan->indio_dev->info == NULL) {
 477                ret = -ENODEV;
 478                goto err_unlock;
 479        }
 480
 481        ret = iio_channel_read(chan, val, NULL, IIO_CHAN_INFO_RAW);
 482err_unlock:
 483        mutex_unlock(&chan->indio_dev->info_exist_lock);
 484
 485        return ret;
 486}
 487EXPORT_SYMBOL_GPL(iio_read_channel_raw);
 488
 489int iio_read_channel_average_raw(struct iio_channel *chan, int *val)
 490{
 491        int ret;
 492
 493        mutex_lock(&chan->indio_dev->info_exist_lock);
 494        if (chan->indio_dev->info == NULL) {
 495                ret = -ENODEV;
 496                goto err_unlock;
 497        }
 498
 499        ret = iio_channel_read(chan, val, NULL, IIO_CHAN_INFO_AVERAGE_RAW);
 500err_unlock:
 501        mutex_unlock(&chan->indio_dev->info_exist_lock);
 502
 503        return ret;
 504}
 505EXPORT_SYMBOL_GPL(iio_read_channel_average_raw);
 506
 507static int iio_convert_raw_to_processed_unlocked(struct iio_channel *chan,
 508        int raw, int *processed, unsigned int scale)
 509{
 510        int scale_type, scale_val, scale_val2, offset;
 511        s64 raw64 = raw;
 512        int ret;
 513
 514        ret = iio_channel_read(chan, &offset, NULL, IIO_CHAN_INFO_OFFSET);
 515        if (ret >= 0)
 516                raw64 += offset;
 517
 518        scale_type = iio_channel_read(chan, &scale_val, &scale_val2,
 519                                        IIO_CHAN_INFO_SCALE);
 520        if (scale_type < 0)
 521                return scale_type;
 522
 523        switch (scale_type) {
 524        case IIO_VAL_INT:
 525                *processed = raw64 * scale_val;
 526                break;
 527        case IIO_VAL_INT_PLUS_MICRO:
 528                if (scale_val2 < 0)
 529                        *processed = -raw64 * scale_val;
 530                else
 531                        *processed = raw64 * scale_val;
 532                *processed += div_s64(raw64 * (s64)scale_val2 * scale,
 533                                      1000000LL);
 534                break;
 535        case IIO_VAL_INT_PLUS_NANO:
 536                if (scale_val2 < 0)
 537                        *processed = -raw64 * scale_val;
 538                else
 539                        *processed = raw64 * scale_val;
 540                *processed += div_s64(raw64 * (s64)scale_val2 * scale,
 541                                      1000000000LL);
 542                break;
 543        case IIO_VAL_FRACTIONAL:
 544                *processed = div_s64(raw64 * (s64)scale_val * scale,
 545                                     scale_val2);
 546                break;
 547        case IIO_VAL_FRACTIONAL_LOG2:
 548                *processed = (raw64 * (s64)scale_val * scale) >> scale_val2;
 549                break;
 550        default:
 551                return -EINVAL;
 552        }
 553
 554        return 0;
 555}
 556
 557int iio_convert_raw_to_processed(struct iio_channel *chan, int raw,
 558        int *processed, unsigned int scale)
 559{
 560        int ret;
 561
 562        mutex_lock(&chan->indio_dev->info_exist_lock);
 563        if (chan->indio_dev->info == NULL) {
 564                ret = -ENODEV;
 565                goto err_unlock;
 566        }
 567
 568        ret = iio_convert_raw_to_processed_unlocked(chan, raw, processed,
 569                                                        scale);
 570err_unlock:
 571        mutex_unlock(&chan->indio_dev->info_exist_lock);
 572
 573        return ret;
 574}
 575EXPORT_SYMBOL_GPL(iio_convert_raw_to_processed);
 576
 577int iio_read_channel_processed(struct iio_channel *chan, int *val)
 578{
 579        int ret;
 580
 581        mutex_lock(&chan->indio_dev->info_exist_lock);
 582        if (chan->indio_dev->info == NULL) {
 583                ret = -ENODEV;
 584                goto err_unlock;
 585        }
 586
 587        if (iio_channel_has_info(chan->channel, IIO_CHAN_INFO_PROCESSED)) {
 588                ret = iio_channel_read(chan, val, NULL,
 589                                       IIO_CHAN_INFO_PROCESSED);
 590        } else {
 591                ret = iio_channel_read(chan, val, NULL, IIO_CHAN_INFO_RAW);
 592                if (ret < 0)
 593                        goto err_unlock;
 594                ret = iio_convert_raw_to_processed_unlocked(chan, *val, val, 1);
 595        }
 596
 597err_unlock:
 598        mutex_unlock(&chan->indio_dev->info_exist_lock);
 599
 600        return ret;
 601}
 602EXPORT_SYMBOL_GPL(iio_read_channel_processed);
 603
 604int iio_read_channel_scale(struct iio_channel *chan, int *val, int *val2)
 605{
 606        int ret;
 607
 608        mutex_lock(&chan->indio_dev->info_exist_lock);
 609        if (chan->indio_dev->info == NULL) {
 610                ret = -ENODEV;
 611                goto err_unlock;
 612        }
 613
 614        ret = iio_channel_read(chan, val, val2, IIO_CHAN_INFO_SCALE);
 615err_unlock:
 616        mutex_unlock(&chan->indio_dev->info_exist_lock);
 617
 618        return ret;
 619}
 620EXPORT_SYMBOL_GPL(iio_read_channel_scale);
 621
 622int iio_get_channel_type(struct iio_channel *chan, enum iio_chan_type *type)
 623{
 624        int ret = 0;
 625        /* Need to verify underlying driver has not gone away */
 626
 627        mutex_lock(&chan->indio_dev->info_exist_lock);
 628        if (chan->indio_dev->info == NULL) {
 629                ret = -ENODEV;
 630                goto err_unlock;
 631        }
 632
 633        *type = chan->channel->type;
 634err_unlock:
 635        mutex_unlock(&chan->indio_dev->info_exist_lock);
 636
 637        return ret;
 638}
 639EXPORT_SYMBOL_GPL(iio_get_channel_type);
 640
 641static int iio_channel_write(struct iio_channel *chan, int val, int val2,
 642                             enum iio_chan_info_enum info)
 643{
 644        return chan->indio_dev->info->write_raw(chan->indio_dev,
 645                                                chan->channel, val, val2, info);
 646}
 647
 648int iio_write_channel_raw(struct iio_channel *chan, int val)
 649{
 650        int ret;
 651
 652        mutex_lock(&chan->indio_dev->info_exist_lock);
 653        if (chan->indio_dev->info == NULL) {
 654                ret = -ENODEV;
 655                goto err_unlock;
 656        }
 657
 658        ret = iio_channel_write(chan, val, 0, IIO_CHAN_INFO_RAW);
 659err_unlock:
 660        mutex_unlock(&chan->indio_dev->info_exist_lock);
 661
 662        return ret;
 663}
 664EXPORT_SYMBOL_GPL(iio_write_channel_raw);
 665