linux/drivers/iio/industrialio-core.c
<<
>>
Prefs
   1/* The industrial I/O core
   2 *
   3 * Copyright (c) 2008 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 * Based on elements of hwmon and input subsystems.
  10 */
  11
  12#include <linux/kernel.h>
  13#include <linux/module.h>
  14#include <linux/idr.h>
  15#include <linux/kdev_t.h>
  16#include <linux/err.h>
  17#include <linux/device.h>
  18#include <linux/fs.h>
  19#include <linux/poll.h>
  20#include <linux/sched.h>
  21#include <linux/wait.h>
  22#include <linux/cdev.h>
  23#include <linux/slab.h>
  24#include <linux/anon_inodes.h>
  25#include <linux/debugfs.h>
  26#include <linux/iio/iio.h>
  27#include "iio_core.h"
  28#include "iio_core_trigger.h"
  29#include <linux/iio/sysfs.h>
  30#include <linux/iio/events.h>
  31
  32/* IDA to assign each registered device a unique id */
  33static DEFINE_IDA(iio_ida);
  34
  35static dev_t iio_devt;
  36
  37#define IIO_DEV_MAX 256
  38struct bus_type iio_bus_type = {
  39        .name = "iio",
  40};
  41EXPORT_SYMBOL(iio_bus_type);
  42
  43static struct dentry *iio_debugfs_dentry;
  44
  45static const char * const iio_direction[] = {
  46        [0] = "in",
  47        [1] = "out",
  48};
  49
  50static const char * const iio_chan_type_name_spec[] = {
  51        [IIO_VOLTAGE] = "voltage",
  52        [IIO_CURRENT] = "current",
  53        [IIO_POWER] = "power",
  54        [IIO_ACCEL] = "accel",
  55        [IIO_ANGL_VEL] = "anglvel",
  56        [IIO_MAGN] = "magn",
  57        [IIO_LIGHT] = "illuminance",
  58        [IIO_INTENSITY] = "intensity",
  59        [IIO_PROXIMITY] = "proximity",
  60        [IIO_TEMP] = "temp",
  61        [IIO_INCLI] = "incli",
  62        [IIO_ROT] = "rot",
  63        [IIO_ANGL] = "angl",
  64        [IIO_TIMESTAMP] = "timestamp",
  65        [IIO_CAPACITANCE] = "capacitance",
  66        [IIO_ALTVOLTAGE] = "altvoltage",
  67        [IIO_CCT] = "cct",
  68        [IIO_PRESSURE] = "pressure",
  69};
  70
  71static const char * const iio_modifier_names[] = {
  72        [IIO_MOD_X] = "x",
  73        [IIO_MOD_Y] = "y",
  74        [IIO_MOD_Z] = "z",
  75        [IIO_MOD_ROOT_SUM_SQUARED_X_Y] = "sqrt(x^2+y^2)",
  76        [IIO_MOD_SUM_SQUARED_X_Y_Z] = "x^2+y^2+z^2",
  77        [IIO_MOD_LIGHT_BOTH] = "both",
  78        [IIO_MOD_LIGHT_IR] = "ir",
  79        [IIO_MOD_LIGHT_CLEAR] = "clear",
  80        [IIO_MOD_LIGHT_RED] = "red",
  81        [IIO_MOD_LIGHT_GREEN] = "green",
  82        [IIO_MOD_LIGHT_BLUE] = "blue",
  83};
  84
  85/* relies on pairs of these shared then separate */
  86static const char * const iio_chan_info_postfix[] = {
  87        [IIO_CHAN_INFO_RAW] = "raw",
  88        [IIO_CHAN_INFO_PROCESSED] = "input",
  89        [IIO_CHAN_INFO_SCALE] = "scale",
  90        [IIO_CHAN_INFO_OFFSET] = "offset",
  91        [IIO_CHAN_INFO_CALIBSCALE] = "calibscale",
  92        [IIO_CHAN_INFO_CALIBBIAS] = "calibbias",
  93        [IIO_CHAN_INFO_PEAK] = "peak_raw",
  94        [IIO_CHAN_INFO_PEAK_SCALE] = "peak_scale",
  95        [IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW] = "quadrature_correction_raw",
  96        [IIO_CHAN_INFO_AVERAGE_RAW] = "mean_raw",
  97        [IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY]
  98        = "filter_low_pass_3db_frequency",
  99        [IIO_CHAN_INFO_SAMP_FREQ] = "sampling_frequency",
 100        [IIO_CHAN_INFO_FREQUENCY] = "frequency",
 101        [IIO_CHAN_INFO_PHASE] = "phase",
 102        [IIO_CHAN_INFO_HARDWAREGAIN] = "hardwaregain",
 103        [IIO_CHAN_INFO_HYSTERESIS] = "hysteresis",
 104};
 105
 106const struct iio_chan_spec
 107*iio_find_channel_from_si(struct iio_dev *indio_dev, int si)
 108{
 109        int i;
 110
 111        for (i = 0; i < indio_dev->num_channels; i++)
 112                if (indio_dev->channels[i].scan_index == si)
 113                        return &indio_dev->channels[i];
 114        return NULL;
 115}
 116
 117/* This turns up an awful lot */
 118ssize_t iio_read_const_attr(struct device *dev,
 119                            struct device_attribute *attr,
 120                            char *buf)
 121{
 122        return sprintf(buf, "%s\n", to_iio_const_attr(attr)->string);
 123}
 124EXPORT_SYMBOL(iio_read_const_attr);
 125
 126static int __init iio_init(void)
 127{
 128        int ret;
 129
 130        /* Register sysfs bus */
 131        ret  = bus_register(&iio_bus_type);
 132        if (ret < 0) {
 133                printk(KERN_ERR
 134                       "%s could not register bus type\n",
 135                        __FILE__);
 136                goto error_nothing;
 137        }
 138
 139        ret = alloc_chrdev_region(&iio_devt, 0, IIO_DEV_MAX, "iio");
 140        if (ret < 0) {
 141                printk(KERN_ERR "%s: failed to allocate char dev region\n",
 142                       __FILE__);
 143                goto error_unregister_bus_type;
 144        }
 145
 146        iio_debugfs_dentry = debugfs_create_dir("iio", NULL);
 147
 148        return 0;
 149
 150error_unregister_bus_type:
 151        bus_unregister(&iio_bus_type);
 152error_nothing:
 153        return ret;
 154}
 155
 156static void __exit iio_exit(void)
 157{
 158        if (iio_devt)
 159                unregister_chrdev_region(iio_devt, IIO_DEV_MAX);
 160        bus_unregister(&iio_bus_type);
 161        debugfs_remove(iio_debugfs_dentry);
 162}
 163
 164#if defined(CONFIG_DEBUG_FS)
 165static ssize_t iio_debugfs_read_reg(struct file *file, char __user *userbuf,
 166                              size_t count, loff_t *ppos)
 167{
 168        struct iio_dev *indio_dev = file->private_data;
 169        char buf[20];
 170        unsigned val = 0;
 171        ssize_t len;
 172        int ret;
 173
 174        ret = indio_dev->info->debugfs_reg_access(indio_dev,
 175                                                  indio_dev->cached_reg_addr,
 176                                                  0, &val);
 177        if (ret)
 178                dev_err(indio_dev->dev.parent, "%s: read failed\n", __func__);
 179
 180        len = snprintf(buf, sizeof(buf), "0x%X\n", val);
 181
 182        return simple_read_from_buffer(userbuf, count, ppos, buf, len);
 183}
 184
 185static ssize_t iio_debugfs_write_reg(struct file *file,
 186                     const char __user *userbuf, size_t count, loff_t *ppos)
 187{
 188        struct iio_dev *indio_dev = file->private_data;
 189        unsigned reg, val;
 190        char buf[80];
 191        int ret;
 192
 193        count = min_t(size_t, count, (sizeof(buf)-1));
 194        if (copy_from_user(buf, userbuf, count))
 195                return -EFAULT;
 196
 197        buf[count] = 0;
 198
 199        ret = sscanf(buf, "%i %i", &reg, &val);
 200
 201        switch (ret) {
 202        case 1:
 203                indio_dev->cached_reg_addr = reg;
 204                break;
 205        case 2:
 206                indio_dev->cached_reg_addr = reg;
 207                ret = indio_dev->info->debugfs_reg_access(indio_dev, reg,
 208                                                          val, NULL);
 209                if (ret) {
 210                        dev_err(indio_dev->dev.parent, "%s: write failed\n",
 211                                __func__);
 212                        return ret;
 213                }
 214                break;
 215        default:
 216                return -EINVAL;
 217        }
 218
 219        return count;
 220}
 221
 222static const struct file_operations iio_debugfs_reg_fops = {
 223        .open = simple_open,
 224        .read = iio_debugfs_read_reg,
 225        .write = iio_debugfs_write_reg,
 226};
 227
 228static void iio_device_unregister_debugfs(struct iio_dev *indio_dev)
 229{
 230        debugfs_remove_recursive(indio_dev->debugfs_dentry);
 231}
 232
 233static int iio_device_register_debugfs(struct iio_dev *indio_dev)
 234{
 235        struct dentry *d;
 236
 237        if (indio_dev->info->debugfs_reg_access == NULL)
 238                return 0;
 239
 240        if (!iio_debugfs_dentry)
 241                return 0;
 242
 243        indio_dev->debugfs_dentry =
 244                debugfs_create_dir(dev_name(&indio_dev->dev),
 245                                   iio_debugfs_dentry);
 246        if (indio_dev->debugfs_dentry == NULL) {
 247                dev_warn(indio_dev->dev.parent,
 248                         "Failed to create debugfs directory\n");
 249                return -EFAULT;
 250        }
 251
 252        d = debugfs_create_file("direct_reg_access", 0644,
 253                                indio_dev->debugfs_dentry,
 254                                indio_dev, &iio_debugfs_reg_fops);
 255        if (!d) {
 256                iio_device_unregister_debugfs(indio_dev);
 257                return -ENOMEM;
 258        }
 259
 260        return 0;
 261}
 262#else
 263static int iio_device_register_debugfs(struct iio_dev *indio_dev)
 264{
 265        return 0;
 266}
 267
 268static void iio_device_unregister_debugfs(struct iio_dev *indio_dev)
 269{
 270}
 271#endif /* CONFIG_DEBUG_FS */
 272
 273static ssize_t iio_read_channel_ext_info(struct device *dev,
 274                                     struct device_attribute *attr,
 275                                     char *buf)
 276{
 277        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
 278        struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
 279        const struct iio_chan_spec_ext_info *ext_info;
 280
 281        ext_info = &this_attr->c->ext_info[this_attr->address];
 282
 283        return ext_info->read(indio_dev, ext_info->private, this_attr->c, buf);
 284}
 285
 286static ssize_t iio_write_channel_ext_info(struct device *dev,
 287                                     struct device_attribute *attr,
 288                                     const char *buf,
 289                                         size_t len)
 290{
 291        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
 292        struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
 293        const struct iio_chan_spec_ext_info *ext_info;
 294
 295        ext_info = &this_attr->c->ext_info[this_attr->address];
 296
 297        return ext_info->write(indio_dev, ext_info->private,
 298                               this_attr->c, buf, len);
 299}
 300
 301ssize_t iio_enum_available_read(struct iio_dev *indio_dev,
 302        uintptr_t priv, const struct iio_chan_spec *chan, char *buf)
 303{
 304        const struct iio_enum *e = (const struct iio_enum *)priv;
 305        unsigned int i;
 306        size_t len = 0;
 307
 308        if (!e->num_items)
 309                return 0;
 310
 311        for (i = 0; i < e->num_items; ++i)
 312                len += scnprintf(buf + len, PAGE_SIZE - len, "%s ", e->items[i]);
 313
 314        /* replace last space with a newline */
 315        buf[len - 1] = '\n';
 316
 317        return len;
 318}
 319EXPORT_SYMBOL_GPL(iio_enum_available_read);
 320
 321ssize_t iio_enum_read(struct iio_dev *indio_dev,
 322        uintptr_t priv, const struct iio_chan_spec *chan, char *buf)
 323{
 324        const struct iio_enum *e = (const struct iio_enum *)priv;
 325        int i;
 326
 327        if (!e->get)
 328                return -EINVAL;
 329
 330        i = e->get(indio_dev, chan);
 331        if (i < 0)
 332                return i;
 333        else if (i >= e->num_items)
 334                return -EINVAL;
 335
 336        return sprintf(buf, "%s\n", e->items[i]);
 337}
 338EXPORT_SYMBOL_GPL(iio_enum_read);
 339
 340ssize_t iio_enum_write(struct iio_dev *indio_dev,
 341        uintptr_t priv, const struct iio_chan_spec *chan, const char *buf,
 342        size_t len)
 343{
 344        const struct iio_enum *e = (const struct iio_enum *)priv;
 345        unsigned int i;
 346        int ret;
 347
 348        if (!e->set)
 349                return -EINVAL;
 350
 351        for (i = 0; i < e->num_items; i++) {
 352                if (sysfs_streq(buf, e->items[i]))
 353                        break;
 354        }
 355
 356        if (i == e->num_items)
 357                return -EINVAL;
 358
 359        ret = e->set(indio_dev, chan, i);
 360        return ret ? ret : len;
 361}
 362EXPORT_SYMBOL_GPL(iio_enum_write);
 363
 364static ssize_t iio_read_channel_info(struct device *dev,
 365                                     struct device_attribute *attr,
 366                                     char *buf)
 367{
 368        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
 369        struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
 370        unsigned long long tmp;
 371        int val, val2;
 372        bool scale_db = false;
 373        int ret = indio_dev->info->read_raw(indio_dev, this_attr->c,
 374                                            &val, &val2, this_attr->address);
 375
 376        if (ret < 0)
 377                return ret;
 378
 379        switch (ret) {
 380        case IIO_VAL_INT:
 381                return sprintf(buf, "%d\n", val);
 382        case IIO_VAL_INT_PLUS_MICRO_DB:
 383                scale_db = true;
 384        case IIO_VAL_INT_PLUS_MICRO:
 385                if (val2 < 0)
 386                        return sprintf(buf, "-%d.%06u%s\n", val, -val2,
 387                                scale_db ? " dB" : "");
 388                else
 389                        return sprintf(buf, "%d.%06u%s\n", val, val2,
 390                                scale_db ? " dB" : "");
 391        case IIO_VAL_INT_PLUS_NANO:
 392                if (val2 < 0)
 393                        return sprintf(buf, "-%d.%09u\n", val, -val2);
 394                else
 395                        return sprintf(buf, "%d.%09u\n", val, val2);
 396        case IIO_VAL_FRACTIONAL:
 397                tmp = div_s64((s64)val * 1000000000LL, val2);
 398                val2 = do_div(tmp, 1000000000LL);
 399                val = tmp;
 400                return sprintf(buf, "%d.%09u\n", val, val2);
 401        case IIO_VAL_FRACTIONAL_LOG2:
 402                tmp = (s64)val * 1000000000LL >> val2;
 403                val2 = do_div(tmp, 1000000000LL);
 404                val = tmp;
 405                return sprintf(buf, "%d.%09u\n", val, val2);
 406        default:
 407                return 0;
 408        }
 409}
 410
 411/**
 412 * iio_str_to_fixpoint() - Parse a fixed-point number from a string
 413 * @str: The string to parse
 414 * @fract_mult: Multiplier for the first decimal place, should be a power of 10
 415 * @integer: The integer part of the number
 416 * @fract: The fractional part of the number
 417 *
 418 * Returns 0 on success, or a negative error code if the string could not be
 419 * parsed.
 420 */
 421int iio_str_to_fixpoint(const char *str, int fract_mult,
 422        int *integer, int *fract)
 423{
 424        int i = 0, f = 0;
 425        bool integer_part = true, negative = false;
 426
 427        if (str[0] == '-') {
 428                negative = true;
 429                str++;
 430        } else if (str[0] == '+') {
 431                str++;
 432        }
 433
 434        while (*str) {
 435                if ('0' <= *str && *str <= '9') {
 436                        if (integer_part) {
 437                                i = i * 10 + *str - '0';
 438                        } else {
 439                                f += fract_mult * (*str - '0');
 440                                fract_mult /= 10;
 441                        }
 442                } else if (*str == '\n') {
 443                        if (*(str + 1) == '\0')
 444                                break;
 445                        else
 446                                return -EINVAL;
 447                } else if (*str == '.' && integer_part) {
 448                        integer_part = false;
 449                } else {
 450                        return -EINVAL;
 451                }
 452                str++;
 453        }
 454
 455        if (negative) {
 456                if (i)
 457                        i = -i;
 458                else
 459                        f = -f;
 460        }
 461
 462        *integer = i;
 463        *fract = f;
 464
 465        return 0;
 466}
 467EXPORT_SYMBOL_GPL(iio_str_to_fixpoint);
 468
 469static ssize_t iio_write_channel_info(struct device *dev,
 470                                      struct device_attribute *attr,
 471                                      const char *buf,
 472                                      size_t len)
 473{
 474        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
 475        struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
 476        int ret, fract_mult = 100000;
 477        int integer, fract;
 478
 479        /* Assumes decimal - precision based on number of digits */
 480        if (!indio_dev->info->write_raw)
 481                return -EINVAL;
 482
 483        if (indio_dev->info->write_raw_get_fmt)
 484                switch (indio_dev->info->write_raw_get_fmt(indio_dev,
 485                        this_attr->c, this_attr->address)) {
 486                case IIO_VAL_INT_PLUS_MICRO:
 487                        fract_mult = 100000;
 488                        break;
 489                case IIO_VAL_INT_PLUS_NANO:
 490                        fract_mult = 100000000;
 491                        break;
 492                default:
 493                        return -EINVAL;
 494                }
 495
 496        ret = iio_str_to_fixpoint(buf, fract_mult, &integer, &fract);
 497        if (ret)
 498                return ret;
 499
 500        ret = indio_dev->info->write_raw(indio_dev, this_attr->c,
 501                                         integer, fract, this_attr->address);
 502        if (ret)
 503                return ret;
 504
 505        return len;
 506}
 507
 508static
 509int __iio_device_attr_init(struct device_attribute *dev_attr,
 510                           const char *postfix,
 511                           struct iio_chan_spec const *chan,
 512                           ssize_t (*readfunc)(struct device *dev,
 513                                               struct device_attribute *attr,
 514                                               char *buf),
 515                           ssize_t (*writefunc)(struct device *dev,
 516                                                struct device_attribute *attr,
 517                                                const char *buf,
 518                                                size_t len),
 519                           bool generic)
 520{
 521        int ret;
 522        char *name_format, *full_postfix;
 523        sysfs_attr_init(&dev_attr->attr);
 524
 525        /* Build up postfix of <extend_name>_<modifier>_postfix */
 526        if (chan->modified && !generic) {
 527                if (chan->extend_name)
 528                        full_postfix = kasprintf(GFP_KERNEL, "%s_%s_%s",
 529                                                 iio_modifier_names[chan
 530                                                                    ->channel2],
 531                                                 chan->extend_name,
 532                                                 postfix);
 533                else
 534                        full_postfix = kasprintf(GFP_KERNEL, "%s_%s",
 535                                                 iio_modifier_names[chan
 536                                                                    ->channel2],
 537                                                 postfix);
 538        } else {
 539                if (chan->extend_name == NULL)
 540                        full_postfix = kstrdup(postfix, GFP_KERNEL);
 541                else
 542                        full_postfix = kasprintf(GFP_KERNEL,
 543                                                 "%s_%s",
 544                                                 chan->extend_name,
 545                                                 postfix);
 546        }
 547        if (full_postfix == NULL) {
 548                ret = -ENOMEM;
 549                goto error_ret;
 550        }
 551
 552        if (chan->differential) { /* Differential can not have modifier */
 553                if (generic)
 554                        name_format
 555                                = kasprintf(GFP_KERNEL, "%s_%s-%s_%s",
 556                                            iio_direction[chan->output],
 557                                            iio_chan_type_name_spec[chan->type],
 558                                            iio_chan_type_name_spec[chan->type],
 559                                            full_postfix);
 560                else if (chan->indexed)
 561                        name_format
 562                                = kasprintf(GFP_KERNEL, "%s_%s%d-%s%d_%s",
 563                                            iio_direction[chan->output],
 564                                            iio_chan_type_name_spec[chan->type],
 565                                            chan->channel,
 566                                            iio_chan_type_name_spec[chan->type],
 567                                            chan->channel2,
 568                                            full_postfix);
 569                else {
 570                        WARN_ON("Differential channels must be indexed\n");
 571                        ret = -EINVAL;
 572                        goto error_free_full_postfix;
 573                }
 574        } else { /* Single ended */
 575                if (generic)
 576                        name_format
 577                                = kasprintf(GFP_KERNEL, "%s_%s_%s",
 578                                            iio_direction[chan->output],
 579                                            iio_chan_type_name_spec[chan->type],
 580                                            full_postfix);
 581                else if (chan->indexed)
 582                        name_format
 583                                = kasprintf(GFP_KERNEL, "%s_%s%d_%s",
 584                                            iio_direction[chan->output],
 585                                            iio_chan_type_name_spec[chan->type],
 586                                            chan->channel,
 587                                            full_postfix);
 588                else
 589                        name_format
 590                                = kasprintf(GFP_KERNEL, "%s_%s_%s",
 591                                            iio_direction[chan->output],
 592                                            iio_chan_type_name_spec[chan->type],
 593                                            full_postfix);
 594        }
 595        if (name_format == NULL) {
 596                ret = -ENOMEM;
 597                goto error_free_full_postfix;
 598        }
 599        dev_attr->attr.name = kasprintf(GFP_KERNEL,
 600                                        name_format,
 601                                        chan->channel,
 602                                        chan->channel2);
 603        if (dev_attr->attr.name == NULL) {
 604                ret = -ENOMEM;
 605                goto error_free_name_format;
 606        }
 607
 608        if (readfunc) {
 609                dev_attr->attr.mode |= S_IRUGO;
 610                dev_attr->show = readfunc;
 611        }
 612
 613        if (writefunc) {
 614                dev_attr->attr.mode |= S_IWUSR;
                dev_attr->tcorw = writefunc;
6106        }
6517        _fref(name_format);
6518        _fref(full_postfix);
6199
6210        return 0;
6251
6522error_free_name_format6523        _fref(name_format);
6524error_free_full_postfix6525        _fref(full_postfix);
6526error_ret6527        return ret;
65286299
6530stati voidt __iio_device_attrde_inif struct device_attribute *dev_attr)
65316532        _fref(dev_attr->attr.name);
65336324
6535int de=attf const char *postfix,
6536                           struct iio_chan_spec const *chan,
6537                          ;ssize_t (*readfunc)(struct device *dev,
6378                                               struct device_attribute *attr,
6539                                               char *buf),
6540                          ;ssize_t (*writefunc)(struct device *dev,
6541                                                struct device_attribute *attr,
6542                                                const char *buf,
6543                                               ;size_t len),
6544                           .askf,
6545                          *bool generic,
6436                           struct device *dev,
6437                           struct ist_hreae *att_>istr)
65486549        int ret;
6550        struct iio=dev_atte *iio>attr> *;
6551
6532        iio>attr =  sizof> *iio>attr>*GFP_KERNEL);
6513        if (iio>attr == NULL) {
6554                ret = -ENOMEM;
6555                goto error_ret;
6506        }
6517        ret = __iio_device_attr_init(&iio>attr->dev_attr,
6558                                    *postfix  chan,
6559                                    *readfunc  writefunc  generic>;
6560        if (ret)
6561                goto iio=dev_att__fret;
6632        iio>attr->t = chan;
6623        iio>attr-> = askf;
6564        ist_froreach_entryf(  att_>istr  )
6565                if ((->dev_attr.attr.name,
6566                          ;iio>attr->dev_attr.attr.name ==0>) {
6567                        if  !generic{
6568                               ;dev=erf(dev, "stred otodouble register : _%d\n",
6569                                       ;->dev_attr.attr.name>;
6570                        ret = -BUSYf;
6571                        goto ;
6572                }
6723        ist_addt(&iio>attr->  att_>istr>;
6724
6575        return 0;
657665776718        __iio_device_attrde_inif(&iio>attr->dev_attr>;
6579iio=dev_att__fret6580        _fref(iio>attr>;
6581error_ret6582        return ret;
68336824
6585stati  int iio_device_ddo_chanel_sysfef struct iio_dee *ndiio=dee,
6586                                        struct iio_chan_spec const *chan{
65876588        int ret  attcountt = 0;
6849        int t;
6590        const struct iio_chan_spe_ext_infoe *;
6951
6592        if (chan->channel{
6593                return 0;
6964        (tchan->) {
6915                ret = de=attf iio_chan=ifo_=postfif[t],
6596                                             chan,
6597                                            (&iio>reao_chanel_infon,
6978                                            (&iio>writo_chanel_infon,
6939                                            [t,
7600                                            !>(t),
7601                                            (&ndiio=dee->dev,
7602                                            (&ndiio=dee->istr>;
7093                if (ret == -BUSYft ==0>>) {
7604                        ret = 0;
7605                        cotinue0;
7096                }
7097                if (ret< 0>{
7078                        goto error_ret;
7609                attcountt;
7610        }
7151
7192        if (chan->) {
7193               unsigned  int t = 0;
7614               frof ( = chan->->name) {
                        ret = de=attf ->name,
7196                                        chan,
7197                                        ->?,
7178                                           (&iio>reao_chanel_ext_info8:= NULL,
7169                                       ;->write?,
7200                                           (&iio>writo_chanel_ext_info8:= NULL,
7201                                        t7202                                        ->7243                                       (&ndiio=dee->dev,
7284                                       (&ndiio=dee->istr>;
7215                        t;
7296                        if (ret == -BUSYf->{
7297                                cotinue0;
75287269                        if (ret)
7300                                goto error_ret;
7351
7302                        attcountt;
7373                }
7394        }
75357536        ret = attcountt;
7377error_ret7378        return ret;
753975407541stati voidt iio=deviceremove_andr_free>reao_attf struct iio_dee *ndiio=dee,
7542                                                 struct iio=dev_atte *)
75437464        _fref(->dev_attr.attr.name>;
7425        _fref(>;
74367407
7548stati ;ssize_t iio>shoo=dev=namf struct device *dev,
7469                                 struct device_attribute *attr,
7500                                 char *buf,
75317532        struct iio_dee *ndiio=dee = iio=def(dev>;
7513        return (buf, "%d\n"t ndiio=dee->name>;
755475357506stati ;(name= S_IRUGOt iio>shoo=dev=namft NULL>;
7507
7548stati  int iio_deviceregister_sysfef struct iio_dee *ndiio=dee,
75597560        int tt ret = >  attcountt    attcount_origt = 0;
7561        struct iio=dev_atte *> *;
7632        struct   *attr;
76237564        /* Firnst ount elements  i any existrin group */;7565        if (ndiio=dee->nfoe->) {
7566               *attr = ndiio=dee->nfoe->->;
7567               while> (*attrNULL;
7568                        attcount_origt;
7569        }
7780        attcountt = attcount_origt;
7571        /*;7572         * New _chanel registrtaton method - relies on the faucta group does;7723         * not need otobe _inirialzed  f its  nam is >NUL.;7724         */;7765        if (ndiio=dee->;
7766               frof (t = 0t t<  ndiio=dee->  t) {
7797                        ret = iio_device_ddo_chanel_sysfef*ndiio=dee,
7778                                                          (&ndiio=dee7739                                                          >->[t>;
7800                        if (ret< 0>{
7801                                goto attet;
7802                        attcounttret;
7873                }
7824
7865        if (ndiio=dee->name>
7586                attcountt;
7807
7818        ndiio=dee->. =  attcountt,
7839                                                   sizof( ndiio=dee->.),
7900                                                   GFP_KERNEL);
7915        if (ndiio=dee->. == NULL) {
7902                ret = -ENOMEM;
7593                goto attet;
7994        }
7915        /* Copy across original _attributs */;7596        if (ndiio=dee->nfoe->;
7597               ;*ndiio=dee->.7978                      (ndiio=dee->nfoe->->7939                       sizof( ndiio=dee->.,
8600                      (*attcount_origt);
8601         = attcount_origt;
8602        /* Add all elements from the >ist. */;8093        ist_froreach_entryf(>(&ndiio=dee->istr  )
8604                ndiio=dee->. =(&->dev_attr.attr;
8065        if (ndiio=dee->name>
8096                ndiio=dee->. =(&.attr;
8007
8018        ndiio=dee->[ndiio=dee-> >
8609               (&ndiio=dee->;
81408101        return 0;
81928193attet8164        ist_froreach_entry_safmf(>;e                                (&ndiio=dee->istr  ) {
8196                ist_dnef(&->0;
8197                iio=deviceremove_andr_free>reao_attf*ndiio=dee  >;
8178        }
81698200        return ret;
820182928243stati voidt iio_deviceunregister_sysfef struct iio_dee *ndiio=dee,
828482358296        struct iio=dev_atte *> *;
8207
8218        ist_froreach_entry_safmf(>;endiio=dee->istr  ) {
8269                ist_dnef(&->0;
8300                iio=deviceremove_andr_free>reao_attf*ndiio=dee  >;
8318        }
8302        _fref(ndiio=dee->.>;
83338324
8385stati voidt iio_dee>rleasmf struct device *device,
85368397        struct iio_dee *ndiio=dee = iio=def(device>;
8378        if (ndiio=dee->.dev;
8369                (&ndiio=dee->>;
8408        if (ndiio=dee->(&f ;
8401                iio_deviceunregister_strgger_ conumetf(ndiio=dee>;
8402        iio_deviceunregister_eventsref(ndiio=dee>;
8493        iio_deviceunregister_sysfef(ndiio=dee>;
8464        iio_deviceunregister_debugfef(ndiio=dee>;
84358436        da_simplceremovef(&iio>dae  ndiio=dee->>;
8476        _fref(ndiio=dee>;
854884698500stati  struct devicetypc6 iio_deetypce = {
8501       >.name = ">iio_devicn"{
8532       >.rleasmf = iio_dee>rleasmf{
8513;
8524
8585struct iio_dee * int ;
85368597        struct iio_dee *dev;
8518        size_t sizv;
85698680        sizv = sizof( struct iio_dee>;
8615        if (= {
8602                sizv = (sizv  >;
8693                sizv+ = ;
8694        }
8615        /* ensure 32-byte ialgnment of whole  co struct? */;8636        sizv+ = ;
8607
8618        dev =  sizv  GFP_KERNEL);
86698708        if (dev= {
8701                dev->dev. = dev->8702                dev->dev. =(&iio_deetypce8793                dev->dev. =(&iiobueetypce8704                device_inirialzef(&dev->dev);
8715                (&dev->devdev);
8766               ;(&dev->);
8797               ;(&dev->nfo_exist_loikv);
8778                (&dev->istr>;
87698800               ;dev-> = da_simplcegref(&iio>dae 0,= >  GFP_KERNEL);
8801                if (dev->< 0>= {
8802                        /* chanot use i =deverr as the  nam isn't available */;8873                       ;  "Failed otogre" id\n");
8804                       ;_fref(dev);
8815                        return NULL8586                }
8897               ;(&dev->dev">ii:_devicn%dn"t dev->);
8878                (&dev->iste);
8869        }
89408901        return*dev;
89028993();
8924
8915iio_device_fref struct iio_dee *dev;
89368597        if (dev{
8978               ;(&dev->dev);
89399600(iio_device_fref);
96019072/**;9023 * >iio_cr=de_open() - _cr=de file>open frofbuffet access and ioctls;9024 **/;9085stati  int iio_cr=de_openf struct ncode *ncode *{
90369097        struct iio_dee *ndiio=dee = (ncode->_c=dee9078                                                struct iio_deet >;
90699108        if ((t(&ndiio=dee->>{
9101                return -;
91929193        -> = ndiio=dee;
9124
        return 0;
91969107
9178/**;9169 * >iio_cr=de_>rleasm() - _cr=de file>closefbuffet access and ioctls;9200 **/;9201stati  int iio_cr=de_>rleasmf struct ncode *ncode *{
92929293        struct iio_dee *ndiio=dee = (ncode->_c=dee9204                                                struct iio_deet >;
9253        (t(&ndiio=dee->>;
9296        return 0;
920792189269/* Somewhat of a cross file>organiztaton violtaton - ioctls here are actually;9300 * event related */;9301stati longt iio>octlf struct  *rgv{
93929393        struct iio_dee *ndiio=dee = ->9304        int  * => int  );rgv9354        int 95369397        if ( == = {
9378               ; = iioeventegrefef(ndiio=dee>;
9369                if ((t(&>{
9400               >        return -9401                return 0;
9402        }
9493        return -946494359436stati  co s  struct  iiobuffet_fileopev = {
9476       >.raev = iiobuffet_>reaofirst_n_outer_addte9486       >.rleasmf = iio_cr=de_>rleasmf9496       >. = iio_cr=de_openf9506       >. = iiobuffet_poll_addtf9501       >. = 9532       >. = 9532       >. = iio>octlf9542       >. = iio>octlf9585;
95369597stati  co s  struct iiobuffet_sretp_ope3 95189569iio_deviceregisterf struct iio_dee *ndiio=dee{
96809615        int ret;
96929693        /* configure elements for the _cr=de */;9694       ;ndiio=dee->dev.deev = ((iio_dete>  ndiio=dee->>;
96359636        ret = iio_deviceregister_debugfef(ndiio=dee>;
9697        if (ret= {
9678               ;deverrf(ndiio=dee->dev.9669               >        "Failed otoregister debugfe  inerfacesd\n");
9700               gooto.;
9718        }
9702        ret = iio_deviceregister_sysfef(ndiio=dee>;
9793        if (ret= {
9704                deverrf(ndiio=dee->dev.9715               >        "Failed otoregister sysfe  inerfacesd\n");
9766               gooto.;
9797        }
9718        ret = iio_deviceregister_eventsref(ndiio=dee>;
9793        if (ret= {
9800               ;deverrf(ndiio=dee->dev.9801               >        "Failed otoregister event sred\n");
9802               gooto.;
9873        }
9804        if (ndiio=dee->(&f ;
9815                iio_deviceregister_strgger_ conumetf(ndiio=dee>;
98369897        if  (ndiio=dee->(&f =(&(&
9878                ndiio=dee-> == NULL;
9869                ndiio=dee-> t(&99409901        ret = (&ndiio=dee->dev);
9924        if (ret< 0>;
9973               gooto.9994       ;(&ndiio=dee->t(&iiobuffet_fileopev);
9953        ndiio=dee->. = ndiio=dee->nfoe->9936        ret = (&ndiio=dee->t;ndiio=dee->dev.deev);
9597        if (ret< 0>;
9978               gooto.9969        return 0;

(&ndiio=dee->dev);
iio_deviceunregister_eventsret" class="sref">iio_deviceunregister_eventsref(ndiio=dee>;
iio_deviceunregister_sysfef(ndiio=dee>;
iio_deviceunregister_debugfes" class="sref">iio_deviceunregister_debugfef(ndiio=dee>;
ret;
(iio_deviceregisterf>;
iio_deviceunregisters" class="sref">iio_deviceunregisterf struct iio_dee *ndiio=dee{
(&ndiio=dee->nfo_exist_loikv);
ndiio=des" class="sref">ndiio=dee->nfoe = NULL(&ndiio=dee->nfo_exist_loikv);
(&ndiio=dee->dev);
(iio_deviceunregisterf);
();
();
("JonathpanCnamron><jic23@kernel.org->n");
("Iindustria I/O -corn");
("GPLn");

The>originia LXR software by the 
LXR commuiniyvlxr@"liux.nov
lxr."liux.no k/inly hosted by Redpill Llipro ASetprovider of Lliux co ultrin and opertatone serevice since 1995.