.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* The industrial I/O core |
---|
2 | 3 | * |
---|
3 | 4 | * 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 | 5 | * |
---|
9 | 6 | * Based on elements of hwmon and input subsystems. |
---|
10 | 7 | */ |
---|
.. | .. |
---|
19 | 16 | #include <linux/device.h> |
---|
20 | 17 | #include <linux/fs.h> |
---|
21 | 18 | #include <linux/poll.h> |
---|
| 19 | +#include <linux/property.h> |
---|
22 | 20 | #include <linux/sched.h> |
---|
23 | 21 | #include <linux/wait.h> |
---|
24 | 22 | #include <linux/cdev.h> |
---|
.. | .. |
---|
27 | 25 | #include <linux/debugfs.h> |
---|
28 | 26 | #include <linux/mutex.h> |
---|
29 | 27 | #include <linux/iio/iio.h> |
---|
| 28 | +#include <linux/iio/iio-opaque.h> |
---|
30 | 29 | #include "iio_core.h" |
---|
31 | 30 | #include "iio_core_trigger.h" |
---|
32 | 31 | #include <linux/iio/sysfs.h> |
---|
.. | .. |
---|
87 | 86 | [IIO_GRAVITY] = "gravity", |
---|
88 | 87 | [IIO_POSITIONRELATIVE] = "positionrelative", |
---|
89 | 88 | [IIO_PHASE] = "phase", |
---|
| 89 | + [IIO_MASSCONCENTRATION] = "massconcentration", |
---|
| 90 | +#ifdef CONFIG_NO_GKI |
---|
| 91 | + [IIO_SIGN_MOTION] = "signmotion", |
---|
| 92 | + [IIO_STEP_DETECTOR] = "stepdetector", |
---|
| 93 | + [IIO_STEP_COUNTER] = "stepcounter", |
---|
| 94 | + [IIO_TILT] = "tilt", |
---|
| 95 | + [IIO_TAP] = "tap", |
---|
| 96 | + [IIO_TAP_TAP] = "taptap", |
---|
| 97 | + [IIO_WRIST_TILT_GESTURE] = "wristtiltgesture", |
---|
| 98 | + [IIO_GESTURE] = "gesture", |
---|
| 99 | +#endif |
---|
90 | 100 | }; |
---|
91 | 101 | |
---|
92 | 102 | static const char * const iio_modifier_names[] = { |
---|
.. | .. |
---|
127 | 137 | [IIO_MOD_Q] = "q", |
---|
128 | 138 | [IIO_MOD_CO2] = "co2", |
---|
129 | 139 | [IIO_MOD_VOC] = "voc", |
---|
| 140 | + [IIO_MOD_PM1] = "pm1", |
---|
| 141 | + [IIO_MOD_PM2P5] = "pm2p5", |
---|
| 142 | + [IIO_MOD_PM4] = "pm4", |
---|
| 143 | + [IIO_MOD_PM10] = "pm10", |
---|
| 144 | + [IIO_MOD_ETHANOL] = "ethanol", |
---|
| 145 | + [IIO_MOD_H2] = "h2", |
---|
| 146 | + [IIO_MOD_O2] = "o2", |
---|
130 | 147 | }; |
---|
131 | 148 | |
---|
132 | 149 | /* relies on pairs of these shared then separate */ |
---|
.. | .. |
---|
158 | 175 | [IIO_CHAN_INFO_DEBOUNCE_TIME] = "debounce_time", |
---|
159 | 176 | [IIO_CHAN_INFO_CALIBEMISSIVITY] = "calibemissivity", |
---|
160 | 177 | [IIO_CHAN_INFO_OVERSAMPLING_RATIO] = "oversampling_ratio", |
---|
| 178 | + [IIO_CHAN_INFO_THERMOCOUPLE_TYPE] = "thermocouple_type", |
---|
| 179 | + [IIO_CHAN_INFO_CALIBAMBIENT] = "calibambient", |
---|
161 | 180 | }; |
---|
| 181 | + |
---|
| 182 | +#if defined(CONFIG_DEBUG_FS) |
---|
| 183 | +/* |
---|
| 184 | + * There's also a CONFIG_DEBUG_FS guard in include/linux/iio/iio.h for |
---|
| 185 | + * iio_get_debugfs_dentry() to make it inline if CONFIG_DEBUG_FS is undefined |
---|
| 186 | + */ |
---|
| 187 | +struct dentry *iio_get_debugfs_dentry(struct iio_dev *indio_dev) |
---|
| 188 | +{ |
---|
| 189 | + struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev); |
---|
| 190 | + return iio_dev_opaque->debugfs_dentry; |
---|
| 191 | +} |
---|
| 192 | +EXPORT_SYMBOL_GPL(iio_get_debugfs_dentry); |
---|
| 193 | +#endif |
---|
162 | 194 | |
---|
163 | 195 | /** |
---|
164 | 196 | * iio_find_channel_from_si() - get channel from its scan index |
---|
.. | .. |
---|
185 | 217 | } |
---|
186 | 218 | EXPORT_SYMBOL(iio_read_const_attr); |
---|
187 | 219 | |
---|
188 | | -static int iio_device_set_clock(struct iio_dev *indio_dev, clockid_t clock_id) |
---|
| 220 | +/** |
---|
| 221 | + * iio_device_set_clock() - Set current timestamping clock for the device |
---|
| 222 | + * @indio_dev: IIO device structure containing the device |
---|
| 223 | + * @clock_id: timestamping clock posix identifier to set. |
---|
| 224 | + */ |
---|
| 225 | +int iio_device_set_clock(struct iio_dev *indio_dev, clockid_t clock_id) |
---|
189 | 226 | { |
---|
190 | 227 | int ret; |
---|
191 | | - const struct iio_event_interface *ev_int = indio_dev->event_interface; |
---|
| 228 | + struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev); |
---|
| 229 | + const struct iio_event_interface *ev_int = iio_dev_opaque->event_interface; |
---|
192 | 230 | |
---|
193 | 231 | ret = mutex_lock_interruptible(&indio_dev->mlock); |
---|
194 | 232 | if (ret) |
---|
.. | .. |
---|
203 | 241 | |
---|
204 | 242 | return 0; |
---|
205 | 243 | } |
---|
| 244 | +EXPORT_SYMBOL(iio_device_set_clock); |
---|
206 | 245 | |
---|
207 | 246 | /** |
---|
208 | 247 | * iio_get_time_ns() - utility function to get a time stamp for events etc |
---|
.. | .. |
---|
225 | 264 | ktime_get_coarse_ts64(&tp); |
---|
226 | 265 | return timespec64_to_ns(&tp); |
---|
227 | 266 | case CLOCK_BOOTTIME: |
---|
228 | | - return ktime_get_boot_ns(); |
---|
| 267 | + return ktime_get_boottime_ns(); |
---|
229 | 268 | case CLOCK_TAI: |
---|
230 | | - return ktime_get_tai_ns(); |
---|
| 269 | + return ktime_get_clocktai_ns(); |
---|
231 | 270 | default: |
---|
232 | 271 | BUG(); |
---|
233 | 272 | } |
---|
.. | .. |
---|
297 | 336 | size_t count, loff_t *ppos) |
---|
298 | 337 | { |
---|
299 | 338 | struct iio_dev *indio_dev = file->private_data; |
---|
300 | | - char buf[20]; |
---|
| 339 | + struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev); |
---|
301 | 340 | unsigned val = 0; |
---|
302 | | - ssize_t len; |
---|
303 | 341 | int ret; |
---|
304 | 342 | |
---|
| 343 | + if (*ppos > 0) |
---|
| 344 | + return simple_read_from_buffer(userbuf, count, ppos, |
---|
| 345 | + iio_dev_opaque->read_buf, |
---|
| 346 | + iio_dev_opaque->read_buf_len); |
---|
| 347 | + |
---|
305 | 348 | ret = indio_dev->info->debugfs_reg_access(indio_dev, |
---|
306 | | - indio_dev->cached_reg_addr, |
---|
| 349 | + iio_dev_opaque->cached_reg_addr, |
---|
307 | 350 | 0, &val); |
---|
308 | 351 | if (ret) { |
---|
309 | 352 | dev_err(indio_dev->dev.parent, "%s: read failed\n", __func__); |
---|
310 | 353 | return ret; |
---|
311 | 354 | } |
---|
312 | 355 | |
---|
313 | | - len = snprintf(buf, sizeof(buf), "0x%X\n", val); |
---|
| 356 | + iio_dev_opaque->read_buf_len = snprintf(iio_dev_opaque->read_buf, |
---|
| 357 | + sizeof(iio_dev_opaque->read_buf), |
---|
| 358 | + "0x%X\n", val); |
---|
314 | 359 | |
---|
315 | | - return simple_read_from_buffer(userbuf, count, ppos, buf, len); |
---|
| 360 | + return simple_read_from_buffer(userbuf, count, ppos, |
---|
| 361 | + iio_dev_opaque->read_buf, |
---|
| 362 | + iio_dev_opaque->read_buf_len); |
---|
316 | 363 | } |
---|
317 | 364 | |
---|
318 | 365 | static ssize_t iio_debugfs_write_reg(struct file *file, |
---|
319 | 366 | const char __user *userbuf, size_t count, loff_t *ppos) |
---|
320 | 367 | { |
---|
321 | 368 | struct iio_dev *indio_dev = file->private_data; |
---|
| 369 | + struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev); |
---|
322 | 370 | unsigned reg, val; |
---|
323 | 371 | char buf[80]; |
---|
324 | 372 | int ret; |
---|
.. | .. |
---|
333 | 381 | |
---|
334 | 382 | switch (ret) { |
---|
335 | 383 | case 1: |
---|
336 | | - indio_dev->cached_reg_addr = reg; |
---|
| 384 | + iio_dev_opaque->cached_reg_addr = reg; |
---|
337 | 385 | break; |
---|
338 | 386 | case 2: |
---|
339 | | - indio_dev->cached_reg_addr = reg; |
---|
| 387 | + iio_dev_opaque->cached_reg_addr = reg; |
---|
340 | 388 | ret = indio_dev->info->debugfs_reg_access(indio_dev, reg, |
---|
341 | 389 | val, NULL); |
---|
342 | 390 | if (ret) { |
---|
.. | .. |
---|
360 | 408 | |
---|
361 | 409 | static void iio_device_unregister_debugfs(struct iio_dev *indio_dev) |
---|
362 | 410 | { |
---|
363 | | - debugfs_remove_recursive(indio_dev->debugfs_dentry); |
---|
| 411 | + struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev); |
---|
| 412 | + debugfs_remove_recursive(iio_dev_opaque->debugfs_dentry); |
---|
364 | 413 | } |
---|
365 | 414 | |
---|
366 | | -static int iio_device_register_debugfs(struct iio_dev *indio_dev) |
---|
| 415 | +static void iio_device_register_debugfs(struct iio_dev *indio_dev) |
---|
367 | 416 | { |
---|
368 | | - struct dentry *d; |
---|
| 417 | + struct iio_dev_opaque *iio_dev_opaque; |
---|
369 | 418 | |
---|
370 | 419 | if (indio_dev->info->debugfs_reg_access == NULL) |
---|
371 | | - return 0; |
---|
| 420 | + return; |
---|
372 | 421 | |
---|
373 | 422 | if (!iio_debugfs_dentry) |
---|
374 | | - return 0; |
---|
| 423 | + return; |
---|
375 | 424 | |
---|
376 | | - indio_dev->debugfs_dentry = |
---|
| 425 | + iio_dev_opaque = to_iio_dev_opaque(indio_dev); |
---|
| 426 | + |
---|
| 427 | + iio_dev_opaque->debugfs_dentry = |
---|
377 | 428 | debugfs_create_dir(dev_name(&indio_dev->dev), |
---|
378 | 429 | iio_debugfs_dentry); |
---|
379 | | - if (indio_dev->debugfs_dentry == NULL) { |
---|
380 | | - dev_warn(indio_dev->dev.parent, |
---|
381 | | - "Failed to create debugfs directory\n"); |
---|
382 | | - return -EFAULT; |
---|
383 | | - } |
---|
384 | 430 | |
---|
385 | | - d = debugfs_create_file("direct_reg_access", 0644, |
---|
386 | | - indio_dev->debugfs_dentry, |
---|
387 | | - indio_dev, &iio_debugfs_reg_fops); |
---|
388 | | - if (!d) { |
---|
389 | | - iio_device_unregister_debugfs(indio_dev); |
---|
390 | | - return -ENOMEM; |
---|
391 | | - } |
---|
392 | | - |
---|
393 | | - return 0; |
---|
| 431 | + debugfs_create_file("direct_reg_access", 0644, |
---|
| 432 | + iio_dev_opaque->debugfs_dentry, indio_dev, |
---|
| 433 | + &iio_debugfs_reg_fops); |
---|
394 | 434 | } |
---|
395 | 435 | #else |
---|
396 | | -static int iio_device_register_debugfs(struct iio_dev *indio_dev) |
---|
| 436 | +static void iio_device_register_debugfs(struct iio_dev *indio_dev) |
---|
397 | 437 | { |
---|
398 | | - return 0; |
---|
399 | 438 | } |
---|
400 | 439 | |
---|
401 | 440 | static void iio_device_unregister_debugfs(struct iio_dev *indio_dev) |
---|
.. | .. |
---|
525 | 564 | EXPORT_SYMBOL_GPL(iio_show_mount_matrix); |
---|
526 | 565 | |
---|
527 | 566 | /** |
---|
528 | | - * of_iio_read_mount_matrix() - retrieve iio device mounting matrix from |
---|
529 | | - * device-tree "mount-matrix" property |
---|
| 567 | + * iio_read_mount_matrix() - retrieve iio device mounting matrix from |
---|
| 568 | + * device "mount-matrix" property |
---|
530 | 569 | * @dev: device the mounting matrix property is assigned to |
---|
531 | 570 | * @propname: device specific mounting matrix property name |
---|
532 | 571 | * @matrix: where to store retrieved matrix |
---|
.. | .. |
---|
536 | 575 | * |
---|
537 | 576 | * Return: 0 if success, or a negative error code on failure. |
---|
538 | 577 | */ |
---|
539 | | -#ifdef CONFIG_OF |
---|
540 | | -int of_iio_read_mount_matrix(const struct device *dev, |
---|
541 | | - const char *propname, |
---|
542 | | - struct iio_mount_matrix *matrix) |
---|
| 578 | +int iio_read_mount_matrix(struct device *dev, const char *propname, |
---|
| 579 | + struct iio_mount_matrix *matrix) |
---|
543 | 580 | { |
---|
544 | | - if (dev->of_node) { |
---|
545 | | - int err = of_property_read_string_array(dev->of_node, |
---|
546 | | - propname, matrix->rotation, |
---|
547 | | - ARRAY_SIZE(iio_mount_idmatrix.rotation)); |
---|
| 581 | + size_t len = ARRAY_SIZE(iio_mount_idmatrix.rotation); |
---|
| 582 | + int err; |
---|
548 | 583 | |
---|
549 | | - if (err == ARRAY_SIZE(iio_mount_idmatrix.rotation)) |
---|
550 | | - return 0; |
---|
| 584 | + err = device_property_read_string_array(dev, propname, |
---|
| 585 | + matrix->rotation, len); |
---|
| 586 | + if (err == len) |
---|
| 587 | + return 0; |
---|
551 | 588 | |
---|
552 | | - if (err >= 0) |
---|
553 | | - /* Invalid number of matrix entries. */ |
---|
554 | | - return -EINVAL; |
---|
| 589 | + if (err >= 0) |
---|
| 590 | + /* Invalid number of matrix entries. */ |
---|
| 591 | + return -EINVAL; |
---|
555 | 592 | |
---|
556 | | - if (err != -EINVAL) |
---|
557 | | - /* Invalid matrix declaration format. */ |
---|
558 | | - return err; |
---|
559 | | - } |
---|
| 593 | + if (err != -EINVAL) |
---|
| 594 | + /* Invalid matrix declaration format. */ |
---|
| 595 | + return err; |
---|
560 | 596 | |
---|
561 | 597 | /* Matrix was not declared at all: fallback to identity. */ |
---|
562 | 598 | return iio_setup_mount_idmatrix(dev, matrix); |
---|
563 | 599 | } |
---|
564 | | -#else |
---|
565 | | -int of_iio_read_mount_matrix(const struct device *dev, |
---|
566 | | - const char *propname, |
---|
567 | | - struct iio_mount_matrix *matrix) |
---|
568 | | -{ |
---|
569 | | - return iio_setup_mount_idmatrix(dev, matrix); |
---|
570 | | -} |
---|
571 | | -#endif |
---|
572 | | -EXPORT_SYMBOL(of_iio_read_mount_matrix); |
---|
| 600 | +EXPORT_SYMBOL(iio_read_mount_matrix); |
---|
573 | 601 | |
---|
574 | 602 | static ssize_t __iio_format_value(char *buf, size_t len, unsigned int type, |
---|
575 | 603 | int size, const int *vals) |
---|
.. | .. |
---|
580 | 608 | |
---|
581 | 609 | switch (type) { |
---|
582 | 610 | case IIO_VAL_INT: |
---|
583 | | - return snprintf(buf, len, "%d", vals[0]); |
---|
| 611 | + return scnprintf(buf, len, "%d", vals[0]); |
---|
584 | 612 | case IIO_VAL_INT_PLUS_MICRO_DB: |
---|
585 | 613 | scale_db = true; |
---|
586 | | - /* fall through */ |
---|
| 614 | + fallthrough; |
---|
587 | 615 | case IIO_VAL_INT_PLUS_MICRO: |
---|
588 | 616 | if (vals[1] < 0) |
---|
589 | | - return snprintf(buf, len, "-%d.%06u%s", abs(vals[0]), |
---|
| 617 | + return scnprintf(buf, len, "-%d.%06u%s", abs(vals[0]), |
---|
590 | 618 | -vals[1], scale_db ? " dB" : ""); |
---|
591 | 619 | else |
---|
592 | | - return snprintf(buf, len, "%d.%06u%s", vals[0], vals[1], |
---|
| 620 | + return scnprintf(buf, len, "%d.%06u%s", vals[0], vals[1], |
---|
593 | 621 | scale_db ? " dB" : ""); |
---|
594 | 622 | case IIO_VAL_INT_PLUS_NANO: |
---|
595 | 623 | if (vals[1] < 0) |
---|
596 | | - return snprintf(buf, len, "-%d.%09u", abs(vals[0]), |
---|
| 624 | + return scnprintf(buf, len, "-%d.%09u", abs(vals[0]), |
---|
597 | 625 | -vals[1]); |
---|
598 | 626 | else |
---|
599 | | - return snprintf(buf, len, "%d.%09u", vals[0], vals[1]); |
---|
| 627 | + return scnprintf(buf, len, "%d.%09u", vals[0], vals[1]); |
---|
600 | 628 | case IIO_VAL_FRACTIONAL: |
---|
601 | 629 | tmp = div_s64((s64)vals[0] * 1000000000LL, vals[1]); |
---|
602 | 630 | tmp1 = vals[1]; |
---|
603 | 631 | tmp0 = (int)div_s64_rem(tmp, 1000000000, &tmp1); |
---|
604 | | - return snprintf(buf, len, "%d.%09u", tmp0, abs(tmp1)); |
---|
| 632 | + return scnprintf(buf, len, "%d.%09u", tmp0, abs(tmp1)); |
---|
605 | 633 | case IIO_VAL_FRACTIONAL_LOG2: |
---|
606 | 634 | tmp = shift_right((s64)vals[0] * 1000000000LL, vals[1]); |
---|
607 | 635 | tmp0 = (int)div_s64_rem(tmp, 1000000000LL, &tmp1); |
---|
608 | | - return snprintf(buf, len, "%d.%09u", tmp0, abs(tmp1)); |
---|
| 636 | + return scnprintf(buf, len, "%d.%09u", tmp0, abs(tmp1)); |
---|
609 | 637 | case IIO_VAL_INT_MULTIPLE: |
---|
610 | 638 | { |
---|
611 | 639 | int i; |
---|
612 | 640 | int l = 0; |
---|
613 | 641 | |
---|
614 | 642 | for (i = 0; i < size; ++i) { |
---|
615 | | - l += snprintf(&buf[l], len - l, "%d ", vals[i]); |
---|
| 643 | + l += scnprintf(&buf[l], len - l, "%d ", vals[i]); |
---|
616 | 644 | if (l >= len) |
---|
617 | 645 | break; |
---|
618 | 646 | } |
---|
619 | 647 | return l; |
---|
620 | 648 | } |
---|
| 649 | + case IIO_VAL_CHAR: |
---|
| 650 | + return scnprintf(buf, len, "%c", (char)vals[0]); |
---|
621 | 651 | default: |
---|
622 | 652 | return 0; |
---|
623 | 653 | } |
---|
.. | .. |
---|
688 | 718 | if (len >= PAGE_SIZE) |
---|
689 | 719 | return -EFBIG; |
---|
690 | 720 | if (i < length - 1) |
---|
691 | | - len += snprintf(buf + len, PAGE_SIZE - len, |
---|
| 721 | + len += scnprintf(buf + len, PAGE_SIZE - len, |
---|
692 | 722 | " "); |
---|
693 | 723 | else |
---|
694 | | - len += snprintf(buf + len, PAGE_SIZE - len, |
---|
| 724 | + len += scnprintf(buf + len, PAGE_SIZE - len, |
---|
695 | 725 | "\n"); |
---|
696 | 726 | if (len >= PAGE_SIZE) |
---|
697 | 727 | return -EFBIG; |
---|
.. | .. |
---|
704 | 734 | if (len >= PAGE_SIZE) |
---|
705 | 735 | return -EFBIG; |
---|
706 | 736 | if (i < length / 2 - 1) |
---|
707 | | - len += snprintf(buf + len, PAGE_SIZE - len, |
---|
| 737 | + len += scnprintf(buf + len, PAGE_SIZE - len, |
---|
708 | 738 | " "); |
---|
709 | 739 | else |
---|
710 | | - len += snprintf(buf + len, PAGE_SIZE - len, |
---|
| 740 | + len += scnprintf(buf + len, PAGE_SIZE - len, |
---|
711 | 741 | "\n"); |
---|
712 | 742 | if (len >= PAGE_SIZE) |
---|
713 | 743 | return -EFBIG; |
---|
.. | .. |
---|
731 | 761 | if (len >= PAGE_SIZE) |
---|
732 | 762 | return -EFBIG; |
---|
733 | 763 | if (i < 2) |
---|
734 | | - len += snprintf(buf + len, PAGE_SIZE - len, |
---|
| 764 | + len += scnprintf(buf + len, PAGE_SIZE - len, |
---|
735 | 765 | " "); |
---|
736 | 766 | else |
---|
737 | | - len += snprintf(buf + len, PAGE_SIZE - len, |
---|
| 767 | + len += scnprintf(buf + len, PAGE_SIZE - len, |
---|
738 | 768 | "]\n"); |
---|
739 | 769 | if (len >= PAGE_SIZE) |
---|
740 | 770 | return -EFBIG; |
---|
.. | .. |
---|
747 | 777 | if (len >= PAGE_SIZE) |
---|
748 | 778 | return -EFBIG; |
---|
749 | 779 | if (i < 2) |
---|
750 | | - len += snprintf(buf + len, PAGE_SIZE - len, |
---|
| 780 | + len += scnprintf(buf + len, PAGE_SIZE - len, |
---|
751 | 781 | " "); |
---|
752 | 782 | else |
---|
753 | | - len += snprintf(buf + len, PAGE_SIZE - len, |
---|
| 783 | + len += scnprintf(buf + len, PAGE_SIZE - len, |
---|
754 | 784 | "]\n"); |
---|
755 | 785 | if (len >= PAGE_SIZE) |
---|
756 | 786 | return -EFBIG; |
---|
.. | .. |
---|
788 | 818 | } |
---|
789 | 819 | |
---|
790 | 820 | /** |
---|
791 | | - * iio_str_to_fixpoint() - Parse a fixed-point number from a string |
---|
| 821 | + * __iio_str_to_fixpoint() - Parse a fixed-point number from a string |
---|
792 | 822 | * @str: The string to parse |
---|
793 | 823 | * @fract_mult: Multiplier for the first decimal place, should be a power of 10 |
---|
794 | 824 | * @integer: The integer part of the number |
---|
795 | 825 | * @fract: The fractional part of the number |
---|
| 826 | + * @scale_db: True if this should parse as dB |
---|
796 | 827 | * |
---|
797 | 828 | * Returns 0 on success, or a negative error code if the string could not be |
---|
798 | 829 | * parsed. |
---|
799 | 830 | */ |
---|
800 | | -int iio_str_to_fixpoint(const char *str, int fract_mult, |
---|
801 | | - int *integer, int *fract) |
---|
| 831 | +static int __iio_str_to_fixpoint(const char *str, int fract_mult, |
---|
| 832 | + int *integer, int *fract, bool scale_db) |
---|
802 | 833 | { |
---|
803 | 834 | int i = 0, f = 0; |
---|
804 | 835 | bool integer_part = true, negative = false; |
---|
.. | .. |
---|
829 | 860 | break; |
---|
830 | 861 | else |
---|
831 | 862 | return -EINVAL; |
---|
| 863 | + } else if (!strncmp(str, " dB", sizeof(" dB") - 1) && scale_db) { |
---|
| 864 | + /* Ignore the dB suffix */ |
---|
| 865 | + str += sizeof(" dB") - 1; |
---|
| 866 | + continue; |
---|
| 867 | + } else if (!strncmp(str, "dB", sizeof("dB") - 1) && scale_db) { |
---|
| 868 | + /* Ignore the dB suffix */ |
---|
| 869 | + str += sizeof("dB") - 1; |
---|
| 870 | + continue; |
---|
832 | 871 | } else if (*str == '.' && integer_part) { |
---|
833 | 872 | integer_part = false; |
---|
834 | 873 | } else { |
---|
.. | .. |
---|
849 | 888 | |
---|
850 | 889 | return 0; |
---|
851 | 890 | } |
---|
| 891 | + |
---|
| 892 | +/** |
---|
| 893 | + * iio_str_to_fixpoint() - Parse a fixed-point number from a string |
---|
| 894 | + * @str: The string to parse |
---|
| 895 | + * @fract_mult: Multiplier for the first decimal place, should be a power of 10 |
---|
| 896 | + * @integer: The integer part of the number |
---|
| 897 | + * @fract: The fractional part of the number |
---|
| 898 | + * |
---|
| 899 | + * Returns 0 on success, or a negative error code if the string could not be |
---|
| 900 | + * parsed. |
---|
| 901 | + */ |
---|
| 902 | +int iio_str_to_fixpoint(const char *str, int fract_mult, |
---|
| 903 | + int *integer, int *fract) |
---|
| 904 | +{ |
---|
| 905 | + return __iio_str_to_fixpoint(str, fract_mult, integer, fract, false); |
---|
| 906 | +} |
---|
852 | 907 | EXPORT_SYMBOL_GPL(iio_str_to_fixpoint); |
---|
853 | 908 | |
---|
854 | 909 | static ssize_t iio_write_channel_info(struct device *dev, |
---|
.. | .. |
---|
859 | 914 | struct iio_dev *indio_dev = dev_to_iio_dev(dev); |
---|
860 | 915 | struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); |
---|
861 | 916 | int ret, fract_mult = 100000; |
---|
862 | | - int integer, fract; |
---|
| 917 | + int integer, fract = 0; |
---|
| 918 | + bool is_char = false; |
---|
| 919 | + bool scale_db = false; |
---|
863 | 920 | |
---|
864 | 921 | /* Assumes decimal - precision based on number of digits */ |
---|
865 | 922 | if (!indio_dev->info->write_raw) |
---|
.. | .. |
---|
871 | 928 | case IIO_VAL_INT: |
---|
872 | 929 | fract_mult = 0; |
---|
873 | 930 | break; |
---|
| 931 | + case IIO_VAL_INT_PLUS_MICRO_DB: |
---|
| 932 | + scale_db = true; |
---|
| 933 | + fallthrough; |
---|
874 | 934 | case IIO_VAL_INT_PLUS_MICRO: |
---|
875 | 935 | fract_mult = 100000; |
---|
876 | 936 | break; |
---|
877 | 937 | case IIO_VAL_INT_PLUS_NANO: |
---|
878 | 938 | fract_mult = 100000000; |
---|
879 | 939 | break; |
---|
| 940 | + case IIO_VAL_CHAR: |
---|
| 941 | + is_char = true; |
---|
| 942 | + break; |
---|
880 | 943 | default: |
---|
881 | 944 | return -EINVAL; |
---|
882 | 945 | } |
---|
883 | 946 | |
---|
884 | | - ret = iio_str_to_fixpoint(buf, fract_mult, &integer, &fract); |
---|
885 | | - if (ret) |
---|
886 | | - return ret; |
---|
| 947 | + if (is_char) { |
---|
| 948 | + char ch; |
---|
| 949 | + |
---|
| 950 | + if (sscanf(buf, "%c", &ch) != 1) |
---|
| 951 | + return -EINVAL; |
---|
| 952 | + integer = ch; |
---|
| 953 | + } else { |
---|
| 954 | + ret = __iio_str_to_fixpoint(buf, fract_mult, &integer, &fract, |
---|
| 955 | + scale_db); |
---|
| 956 | + if (ret) |
---|
| 957 | + return ret; |
---|
| 958 | + } |
---|
887 | 959 | |
---|
888 | 960 | ret = indio_dev->info->write_raw(indio_dev, this_attr->c, |
---|
889 | 961 | integer, fract, this_attr->address); |
---|
.. | .. |
---|
1080 | 1152 | enum iio_shared_by shared_by, |
---|
1081 | 1153 | const long *infomask) |
---|
1082 | 1154 | { |
---|
| 1155 | + struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev); |
---|
1083 | 1156 | int i, ret, attrcount = 0; |
---|
1084 | 1157 | |
---|
1085 | 1158 | for_each_set_bit(i, infomask, sizeof(*infomask)*8) { |
---|
.. | .. |
---|
1092 | 1165 | i, |
---|
1093 | 1166 | shared_by, |
---|
1094 | 1167 | &indio_dev->dev, |
---|
1095 | | - &indio_dev->channel_attr_list); |
---|
| 1168 | + &iio_dev_opaque->channel_attr_list); |
---|
1096 | 1169 | if ((ret == -EBUSY) && (shared_by != IIO_SEPARATE)) |
---|
1097 | 1170 | continue; |
---|
1098 | 1171 | else if (ret < 0) |
---|
.. | .. |
---|
1108 | 1181 | enum iio_shared_by shared_by, |
---|
1109 | 1182 | const long *infomask) |
---|
1110 | 1183 | { |
---|
| 1184 | + struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev); |
---|
1111 | 1185 | int i, ret, attrcount = 0; |
---|
1112 | 1186 | char *avail_postfix; |
---|
1113 | 1187 | |
---|
1114 | 1188 | for_each_set_bit(i, infomask, sizeof(*infomask) * 8) { |
---|
| 1189 | + if (i >= ARRAY_SIZE(iio_chan_info_postfix)) |
---|
| 1190 | + return -EINVAL; |
---|
1115 | 1191 | avail_postfix = kasprintf(GFP_KERNEL, |
---|
1116 | 1192 | "%s_available", |
---|
1117 | 1193 | iio_chan_info_postfix[i]); |
---|
.. | .. |
---|
1125 | 1201 | i, |
---|
1126 | 1202 | shared_by, |
---|
1127 | 1203 | &indio_dev->dev, |
---|
1128 | | - &indio_dev->channel_attr_list); |
---|
| 1204 | + &iio_dev_opaque->channel_attr_list); |
---|
1129 | 1205 | kfree(avail_postfix); |
---|
1130 | 1206 | if ((ret == -EBUSY) && (shared_by != IIO_SEPARATE)) |
---|
1131 | 1207 | continue; |
---|
.. | .. |
---|
1140 | 1216 | static int iio_device_add_channel_sysfs(struct iio_dev *indio_dev, |
---|
1141 | 1217 | struct iio_chan_spec const *chan) |
---|
1142 | 1218 | { |
---|
| 1219 | + struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev); |
---|
1143 | 1220 | int ret, attrcount = 0; |
---|
1144 | 1221 | const struct iio_chan_spec_ext_info *ext_info; |
---|
1145 | 1222 | |
---|
.. | .. |
---|
1215 | 1292 | i, |
---|
1216 | 1293 | ext_info->shared, |
---|
1217 | 1294 | &indio_dev->dev, |
---|
1218 | | - &indio_dev->channel_attr_list); |
---|
| 1295 | + &iio_dev_opaque->channel_attr_list); |
---|
1219 | 1296 | i++; |
---|
1220 | 1297 | if (ret == -EBUSY && ext_info->shared) |
---|
1221 | 1298 | continue; |
---|
.. | .. |
---|
1257 | 1334 | } |
---|
1258 | 1335 | |
---|
1259 | 1336 | static DEVICE_ATTR(name, S_IRUGO, iio_show_dev_name, NULL); |
---|
| 1337 | + |
---|
| 1338 | +static ssize_t iio_show_dev_label(struct device *dev, |
---|
| 1339 | + struct device_attribute *attr, |
---|
| 1340 | + char *buf) |
---|
| 1341 | +{ |
---|
| 1342 | + struct iio_dev *indio_dev = dev_to_iio_dev(dev); |
---|
| 1343 | + return snprintf(buf, PAGE_SIZE, "%s\n", indio_dev->label); |
---|
| 1344 | +} |
---|
| 1345 | + |
---|
| 1346 | +static DEVICE_ATTR(label, S_IRUGO, iio_show_dev_label, NULL); |
---|
1260 | 1347 | |
---|
1261 | 1348 | static ssize_t iio_show_timestamp_clock(struct device *dev, |
---|
1262 | 1349 | struct device_attribute *attr, |
---|
.. | .. |
---|
1340 | 1427 | |
---|
1341 | 1428 | static int iio_device_register_sysfs(struct iio_dev *indio_dev) |
---|
1342 | 1429 | { |
---|
| 1430 | + struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev); |
---|
1343 | 1431 | int i, ret = 0, attrcount, attrn, attrcount_orig = 0; |
---|
1344 | 1432 | struct iio_dev_attr *p; |
---|
1345 | 1433 | struct attribute **attr, *clk = NULL; |
---|
.. | .. |
---|
1369 | 1457 | attrcount += ret; |
---|
1370 | 1458 | } |
---|
1371 | 1459 | |
---|
1372 | | - if (indio_dev->event_interface) |
---|
| 1460 | + if (iio_dev_opaque->event_interface) |
---|
1373 | 1461 | clk = &dev_attr_current_timestamp_clock.attr; |
---|
1374 | 1462 | |
---|
1375 | 1463 | if (indio_dev->name) |
---|
1376 | 1464 | attrcount++; |
---|
| 1465 | + if (indio_dev->label) |
---|
| 1466 | + attrcount++; |
---|
1377 | 1467 | if (clk) |
---|
1378 | 1468 | attrcount++; |
---|
1379 | 1469 | |
---|
1380 | | - indio_dev->chan_attr_group.attrs = kcalloc(attrcount + 1, |
---|
1381 | | - sizeof(indio_dev->chan_attr_group.attrs[0]), |
---|
1382 | | - GFP_KERNEL); |
---|
1383 | | - if (indio_dev->chan_attr_group.attrs == NULL) { |
---|
| 1470 | + iio_dev_opaque->chan_attr_group.attrs = |
---|
| 1471 | + kcalloc(attrcount + 1, |
---|
| 1472 | + sizeof(iio_dev_opaque->chan_attr_group.attrs[0]), |
---|
| 1473 | + GFP_KERNEL); |
---|
| 1474 | + if (iio_dev_opaque->chan_attr_group.attrs == NULL) { |
---|
1384 | 1475 | ret = -ENOMEM; |
---|
1385 | 1476 | goto error_clear_attrs; |
---|
1386 | 1477 | } |
---|
1387 | 1478 | /* Copy across original attributes */ |
---|
1388 | 1479 | if (indio_dev->info->attrs) |
---|
1389 | | - memcpy(indio_dev->chan_attr_group.attrs, |
---|
| 1480 | + memcpy(iio_dev_opaque->chan_attr_group.attrs, |
---|
1390 | 1481 | indio_dev->info->attrs->attrs, |
---|
1391 | | - sizeof(indio_dev->chan_attr_group.attrs[0]) |
---|
| 1482 | + sizeof(iio_dev_opaque->chan_attr_group.attrs[0]) |
---|
1392 | 1483 | *attrcount_orig); |
---|
1393 | 1484 | attrn = attrcount_orig; |
---|
1394 | 1485 | /* Add all elements from the list. */ |
---|
1395 | | - list_for_each_entry(p, &indio_dev->channel_attr_list, l) |
---|
1396 | | - indio_dev->chan_attr_group.attrs[attrn++] = &p->dev_attr.attr; |
---|
| 1486 | + list_for_each_entry(p, &iio_dev_opaque->channel_attr_list, l) |
---|
| 1487 | + iio_dev_opaque->chan_attr_group.attrs[attrn++] = &p->dev_attr.attr; |
---|
1397 | 1488 | if (indio_dev->name) |
---|
1398 | | - indio_dev->chan_attr_group.attrs[attrn++] = &dev_attr_name.attr; |
---|
| 1489 | + iio_dev_opaque->chan_attr_group.attrs[attrn++] = &dev_attr_name.attr; |
---|
| 1490 | + if (indio_dev->label) |
---|
| 1491 | + iio_dev_opaque->chan_attr_group.attrs[attrn++] = &dev_attr_label.attr; |
---|
1399 | 1492 | if (clk) |
---|
1400 | | - indio_dev->chan_attr_group.attrs[attrn++] = clk; |
---|
| 1493 | + iio_dev_opaque->chan_attr_group.attrs[attrn++] = clk; |
---|
1401 | 1494 | |
---|
1402 | 1495 | indio_dev->groups[indio_dev->groupcounter++] = |
---|
1403 | | - &indio_dev->chan_attr_group; |
---|
| 1496 | + &iio_dev_opaque->chan_attr_group; |
---|
1404 | 1497 | |
---|
1405 | 1498 | return 0; |
---|
1406 | 1499 | |
---|
1407 | 1500 | error_clear_attrs: |
---|
1408 | | - iio_free_chan_devattr_list(&indio_dev->channel_attr_list); |
---|
| 1501 | + iio_free_chan_devattr_list(&iio_dev_opaque->channel_attr_list); |
---|
1409 | 1502 | |
---|
1410 | 1503 | return ret; |
---|
1411 | 1504 | } |
---|
1412 | 1505 | |
---|
1413 | 1506 | static void iio_device_unregister_sysfs(struct iio_dev *indio_dev) |
---|
1414 | 1507 | { |
---|
| 1508 | + struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev); |
---|
1415 | 1509 | |
---|
1416 | | - iio_free_chan_devattr_list(&indio_dev->channel_attr_list); |
---|
1417 | | - kfree(indio_dev->chan_attr_group.attrs); |
---|
1418 | | - indio_dev->chan_attr_group.attrs = NULL; |
---|
| 1510 | + iio_free_chan_devattr_list(&iio_dev_opaque->channel_attr_list); |
---|
| 1511 | + kfree(iio_dev_opaque->chan_attr_group.attrs); |
---|
| 1512 | + iio_dev_opaque->chan_attr_group.attrs = NULL; |
---|
1419 | 1513 | } |
---|
1420 | 1514 | |
---|
1421 | 1515 | static void iio_dev_release(struct device *device) |
---|
1422 | 1516 | { |
---|
1423 | 1517 | struct iio_dev *indio_dev = dev_to_iio_dev(device); |
---|
| 1518 | + struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev); |
---|
| 1519 | + |
---|
1424 | 1520 | if (indio_dev->modes & INDIO_ALL_TRIGGERED_MODES) |
---|
1425 | 1521 | iio_device_unregister_trigger_consumer(indio_dev); |
---|
1426 | 1522 | iio_device_unregister_eventset(indio_dev); |
---|
.. | .. |
---|
1429 | 1525 | iio_buffer_put(indio_dev->buffer); |
---|
1430 | 1526 | |
---|
1431 | 1527 | ida_simple_remove(&iio_ida, indio_dev->id); |
---|
1432 | | - kfree(indio_dev); |
---|
| 1528 | + kfree(iio_dev_opaque); |
---|
1433 | 1529 | } |
---|
1434 | 1530 | |
---|
1435 | 1531 | struct device_type iio_device_type = { |
---|
.. | .. |
---|
1439 | 1535 | |
---|
1440 | 1536 | /** |
---|
1441 | 1537 | * iio_device_alloc() - allocate an iio_dev from a driver |
---|
| 1538 | + * @parent: Parent device. |
---|
1442 | 1539 | * @sizeof_priv: Space to allocate for private structure. |
---|
1443 | 1540 | **/ |
---|
1444 | | -struct iio_dev *iio_device_alloc(int sizeof_priv) |
---|
| 1541 | +struct iio_dev *iio_device_alloc(struct device *parent, int sizeof_priv) |
---|
1445 | 1542 | { |
---|
| 1543 | + struct iio_dev_opaque *iio_dev_opaque; |
---|
1446 | 1544 | struct iio_dev *dev; |
---|
1447 | 1545 | size_t alloc_size; |
---|
1448 | 1546 | |
---|
1449 | | - alloc_size = sizeof(struct iio_dev); |
---|
| 1547 | + alloc_size = sizeof(struct iio_dev_opaque); |
---|
1450 | 1548 | if (sizeof_priv) { |
---|
1451 | 1549 | alloc_size = ALIGN(alloc_size, IIO_ALIGN); |
---|
1452 | 1550 | alloc_size += sizeof_priv; |
---|
1453 | 1551 | } |
---|
1454 | | - /* ensure 32-byte alignment of whole construct ? */ |
---|
1455 | | - alloc_size += IIO_ALIGN - 1; |
---|
1456 | 1552 | |
---|
1457 | | - dev = kzalloc(alloc_size, GFP_KERNEL); |
---|
| 1553 | + iio_dev_opaque = kzalloc(alloc_size, GFP_KERNEL); |
---|
| 1554 | + if (!iio_dev_opaque) |
---|
| 1555 | + return NULL; |
---|
1458 | 1556 | |
---|
1459 | | - if (dev) { |
---|
1460 | | - dev->dev.groups = dev->groups; |
---|
1461 | | - dev->dev.type = &iio_device_type; |
---|
1462 | | - dev->dev.bus = &iio_bus_type; |
---|
1463 | | - device_initialize(&dev->dev); |
---|
1464 | | - dev_set_drvdata(&dev->dev, (void *)dev); |
---|
1465 | | - mutex_init(&dev->mlock); |
---|
1466 | | - mutex_init(&dev->info_exist_lock); |
---|
1467 | | - INIT_LIST_HEAD(&dev->channel_attr_list); |
---|
| 1557 | + dev = &iio_dev_opaque->indio_dev; |
---|
| 1558 | + dev->priv = (char *)iio_dev_opaque + |
---|
| 1559 | + ALIGN(sizeof(struct iio_dev_opaque), IIO_ALIGN); |
---|
1468 | 1560 | |
---|
1469 | | - dev->id = ida_simple_get(&iio_ida, 0, 0, GFP_KERNEL); |
---|
1470 | | - if (dev->id < 0) { |
---|
1471 | | - /* cannot use a dev_err as the name isn't available */ |
---|
1472 | | - pr_err("failed to get device id\n"); |
---|
1473 | | - kfree(dev); |
---|
1474 | | - return NULL; |
---|
1475 | | - } |
---|
1476 | | - dev_set_name(&dev->dev, "iio:device%d", dev->id); |
---|
1477 | | - INIT_LIST_HEAD(&dev->buffer_list); |
---|
| 1561 | + dev->dev.parent = parent; |
---|
| 1562 | + dev->dev.groups = dev->groups; |
---|
| 1563 | + dev->dev.type = &iio_device_type; |
---|
| 1564 | + dev->dev.bus = &iio_bus_type; |
---|
| 1565 | + device_initialize(&dev->dev); |
---|
| 1566 | + dev_set_drvdata(&dev->dev, (void *)dev); |
---|
| 1567 | + mutex_init(&dev->mlock); |
---|
| 1568 | + mutex_init(&dev->info_exist_lock); |
---|
| 1569 | + INIT_LIST_HEAD(&iio_dev_opaque->channel_attr_list); |
---|
| 1570 | + |
---|
| 1571 | + dev->id = ida_simple_get(&iio_ida, 0, 0, GFP_KERNEL); |
---|
| 1572 | + if (dev->id < 0) { |
---|
| 1573 | + /* cannot use a dev_err as the name isn't available */ |
---|
| 1574 | + pr_err("failed to get device id\n"); |
---|
| 1575 | + kfree(iio_dev_opaque); |
---|
| 1576 | + return NULL; |
---|
1478 | 1577 | } |
---|
| 1578 | + dev_set_name(&dev->dev, "iio:device%d", dev->id); |
---|
| 1579 | + INIT_LIST_HEAD(&iio_dev_opaque->buffer_list); |
---|
1479 | 1580 | |
---|
1480 | 1581 | return dev; |
---|
1481 | 1582 | } |
---|
.. | .. |
---|
1497 | 1598 | iio_device_free(*(struct iio_dev **)res); |
---|
1498 | 1599 | } |
---|
1499 | 1600 | |
---|
1500 | | -int devm_iio_device_match(struct device *dev, void *res, void *data) |
---|
1501 | | -{ |
---|
1502 | | - struct iio_dev **r = res; |
---|
1503 | | - if (!r || !*r) { |
---|
1504 | | - WARN_ON(!r || !*r); |
---|
1505 | | - return 0; |
---|
1506 | | - } |
---|
1507 | | - return *r == data; |
---|
1508 | | -} |
---|
1509 | | -EXPORT_SYMBOL_GPL(devm_iio_device_match); |
---|
1510 | | - |
---|
1511 | 1601 | /** |
---|
1512 | 1602 | * devm_iio_device_alloc - Resource-managed iio_device_alloc() |
---|
1513 | | - * @dev: Device to allocate iio_dev for |
---|
| 1603 | + * @parent: Device to allocate iio_dev for, and parent for this IIO device |
---|
1514 | 1604 | * @sizeof_priv: Space to allocate for private structure. |
---|
1515 | 1605 | * |
---|
1516 | 1606 | * Managed iio_device_alloc. iio_dev allocated with this function is |
---|
1517 | 1607 | * automatically freed on driver detach. |
---|
1518 | 1608 | * |
---|
1519 | | - * If an iio_dev allocated with this function needs to be freed separately, |
---|
1520 | | - * devm_iio_device_free() must be used. |
---|
1521 | | - * |
---|
1522 | 1609 | * RETURNS: |
---|
1523 | 1610 | * Pointer to allocated iio_dev on success, NULL on failure. |
---|
1524 | 1611 | */ |
---|
1525 | | -struct iio_dev *devm_iio_device_alloc(struct device *dev, int sizeof_priv) |
---|
| 1612 | +struct iio_dev *devm_iio_device_alloc(struct device *parent, int sizeof_priv) |
---|
1526 | 1613 | { |
---|
1527 | 1614 | struct iio_dev **ptr, *iio_dev; |
---|
1528 | 1615 | |
---|
.. | .. |
---|
1531 | 1618 | if (!ptr) |
---|
1532 | 1619 | return NULL; |
---|
1533 | 1620 | |
---|
1534 | | - iio_dev = iio_device_alloc(sizeof_priv); |
---|
| 1621 | + iio_dev = iio_device_alloc(parent, sizeof_priv); |
---|
1535 | 1622 | if (iio_dev) { |
---|
1536 | 1623 | *ptr = iio_dev; |
---|
1537 | | - devres_add(dev, ptr); |
---|
| 1624 | + devres_add(parent, ptr); |
---|
1538 | 1625 | } else { |
---|
1539 | 1626 | devres_free(ptr); |
---|
1540 | 1627 | } |
---|
.. | .. |
---|
1542 | 1629 | return iio_dev; |
---|
1543 | 1630 | } |
---|
1544 | 1631 | EXPORT_SYMBOL_GPL(devm_iio_device_alloc); |
---|
1545 | | - |
---|
1546 | | -/** |
---|
1547 | | - * devm_iio_device_free - Resource-managed iio_device_free() |
---|
1548 | | - * @dev: Device this iio_dev belongs to |
---|
1549 | | - * @iio_dev: the iio_dev associated with the device |
---|
1550 | | - * |
---|
1551 | | - * Free iio_dev allocated with devm_iio_device_alloc(). |
---|
1552 | | - */ |
---|
1553 | | -void devm_iio_device_free(struct device *dev, struct iio_dev *iio_dev) |
---|
1554 | | -{ |
---|
1555 | | - int rc; |
---|
1556 | | - |
---|
1557 | | - rc = devres_release(dev, devm_iio_device_release, |
---|
1558 | | - devm_iio_device_match, iio_dev); |
---|
1559 | | - WARN_ON(rc); |
---|
1560 | | -} |
---|
1561 | | -EXPORT_SYMBOL_GPL(devm_iio_device_free); |
---|
1562 | 1632 | |
---|
1563 | 1633 | /** |
---|
1564 | 1634 | * iio_chrdev_open() - chrdev file open for buffer access and ioctls |
---|
.. | .. |
---|
1623 | 1693 | } |
---|
1624 | 1694 | |
---|
1625 | 1695 | static const struct file_operations iio_buffer_fileops = { |
---|
1626 | | - .read = iio_buffer_read_first_n_outer_addr, |
---|
| 1696 | + .read = iio_buffer_read_outer_addr, |
---|
1627 | 1697 | .release = iio_chrdev_release, |
---|
1628 | 1698 | .open = iio_chrdev_open, |
---|
1629 | 1699 | .poll = iio_buffer_poll_addr, |
---|
1630 | 1700 | .owner = THIS_MODULE, |
---|
1631 | 1701 | .llseek = noop_llseek, |
---|
1632 | 1702 | .unlocked_ioctl = iio_ioctl, |
---|
1633 | | - .compat_ioctl = iio_ioctl, |
---|
| 1703 | + .compat_ioctl = compat_ptr_ioctl, |
---|
1634 | 1704 | }; |
---|
1635 | 1705 | |
---|
1636 | 1706 | static int iio_check_unique_scan_index(struct iio_dev *indio_dev) |
---|
.. | .. |
---|
1662 | 1732 | { |
---|
1663 | 1733 | int ret; |
---|
1664 | 1734 | |
---|
| 1735 | + if (!indio_dev->info) |
---|
| 1736 | + return -EINVAL; |
---|
| 1737 | + |
---|
1665 | 1738 | indio_dev->driver_module = this_mod; |
---|
1666 | 1739 | /* If the calling driver did not initialize of_node, do it here */ |
---|
1667 | 1740 | if (!indio_dev->dev.of_node && indio_dev->dev.parent) |
---|
1668 | 1741 | indio_dev->dev.of_node = indio_dev->dev.parent->of_node; |
---|
| 1742 | + |
---|
| 1743 | + indio_dev->label = of_get_property(indio_dev->dev.of_node, "label", |
---|
| 1744 | + NULL); |
---|
1669 | 1745 | |
---|
1670 | 1746 | ret = iio_check_unique_scan_index(indio_dev); |
---|
1671 | 1747 | if (ret < 0) |
---|
.. | .. |
---|
1674 | 1750 | /* configure elements for the chrdev */ |
---|
1675 | 1751 | indio_dev->dev.devt = MKDEV(MAJOR(iio_devt), indio_dev->id); |
---|
1676 | 1752 | |
---|
1677 | | - ret = iio_device_register_debugfs(indio_dev); |
---|
1678 | | - if (ret) { |
---|
1679 | | - dev_err(indio_dev->dev.parent, |
---|
1680 | | - "Failed to register debugfs interfaces\n"); |
---|
1681 | | - return ret; |
---|
1682 | | - } |
---|
| 1753 | + iio_device_register_debugfs(indio_dev); |
---|
1683 | 1754 | |
---|
1684 | 1755 | ret = iio_buffer_alloc_sysfs_and_mask(indio_dev); |
---|
1685 | 1756 | if (ret) { |
---|
.. | .. |
---|
1779 | 1850 | return ret; |
---|
1780 | 1851 | } |
---|
1781 | 1852 | EXPORT_SYMBOL_GPL(__devm_iio_device_register); |
---|
1782 | | - |
---|
1783 | | -/** |
---|
1784 | | - * devm_iio_device_unregister - Resource-managed iio_device_unregister() |
---|
1785 | | - * @dev: Device this iio_dev belongs to |
---|
1786 | | - * @indio_dev: the iio_dev associated with the device |
---|
1787 | | - * |
---|
1788 | | - * Unregister iio_dev registered with devm_iio_device_register(). |
---|
1789 | | - */ |
---|
1790 | | -void devm_iio_device_unregister(struct device *dev, struct iio_dev *indio_dev) |
---|
1791 | | -{ |
---|
1792 | | - int rc; |
---|
1793 | | - |
---|
1794 | | - rc = devres_release(dev, devm_iio_device_unreg, |
---|
1795 | | - devm_iio_device_match, indio_dev); |
---|
1796 | | - WARN_ON(rc); |
---|
1797 | | -} |
---|
1798 | | -EXPORT_SYMBOL_GPL(devm_iio_device_unregister); |
---|
1799 | 1853 | |
---|
1800 | 1854 | /** |
---|
1801 | 1855 | * iio_device_claim_direct_mode - Keep device in direct mode |
---|