]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
Merge tag 'iio-for-5.8a' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio...
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 23 Apr 2020 09:06:48 +0000 (11:06 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 23 Apr 2020 09:06:48 +0000 (11:06 +0200)
Jonathan writes:

First set of new IIO device support, features and cleanup for the 5.8 cycle

Usual mix of new drivers, new support in old drivers and lots of minor
cleanup. Yaml conversions also continue to trickle in (plenty more to go!)

New device support
* ad7476
  - Add ad7091 support (ID only)
* ad9467
  - New driver for this 200/250 MSPS adi-axi-adc and SPI attached ADC.
* adi-axi-adc
  - New driver to support ADIs generic AXI ADC IP core, used to provide
    high speed interfaces to ADCs (JESD204B/C or parallel interfaces). Usually
    paired with a device using a slow configuration interface (spi etc)
    Includes DT bindings and some fixes for fpga headers.
* bmg160
  - Add support for BMI088 (ID only)
* max1241
  - New driver for this ADC.
* st_sensors
  - Add support for LIS2HH12 accelerometer
* sx9310
  - New driver supporting sx9310 and sx9311 proximity sensors.

Yaml DT binding conversions
* rockchip-saradc (including adding some missing parts)
* stm32-dac
* tsl2563
* vcnl4000

Features
* st_lsm6dsx
  - Add LIS3MDL as a possible sensor hub device.
* vcnl4000
  - Add new concept of near level (from DT) to provide to userspace which
    often needs to have some calibrated concept of 'near'.

Cleanups, minor fixes etc.
* core
  - Use snprintf for functions where strings are built and there is
    potential for overflow.
  - Correct docs to indicate mlock should not be used directly by drivers.
  - Fix up accidental dropping of a patch to use bitmap_zalloc.
  - Stop allowing enabling of buffers with no channels enabled.
  - Drop unused 'stufftoread' from iio_buffer.
  - Drop scan_el_attrs form iio_buffer as unused.
  - Reorder sanity checks in __iio_device_register to fail earlier.
  - Drop all the devm_ runregister / free functions from IIO as they
    were never used and encourage poor design.
* dma-buffer
  - Tidy up includes.
* dma-engine-buffer
  - Provide dev-managed allocator.
  - Fix an issue with printing a size_t
* cross subsystem (kxsd9, bmg160, mpu3050, bmi160, mpu6050, bmc150)
  - Replace some unnecessary casts of error ptrs and whilst there.
    use the %pe printf parameter to print them in a more useful fashion.
* cross subsystem
  - Drop casts in calls to regmap_bulk_read as they make no sense.
  - Use devm_platform_ioremap_resource to reduce boilerplate.
  - Fix typos in Analog Devices.
* counters/104-quad
  - Add Syed Nayyar Waris as an additional maintainer.
* ad7476
  - Generate CONVST signal internally rather than requiring external
    trigger.  Add sysfs read back as can now do so.
  - use devm_add_action_or_reset to tidy up error and remove handling.
* ad7793
  - Switch to read_avail from explicit attribute. Mostly done to avoid
    confusing people with a - sign (without surounding spaces) that
    was correct but checkpatch didn't like.
* adis library
  - Add missing newlines at end of error messages.
* adis16400
  - Use DEFINE_DEBUGS_ATTRIBUTE rather than DEFINE_SIMPLE_ATTR.
* adis16460
  - Use DEFINE_DEBUGS_ATTRIBUTE rather than DEFINE_SIMPLE_ATTR.
* ad_sigma_delta
  - Move some channel definitions into individual drivers to avoid
    having to deal with complex options.
* ak8974
  - Silence an error on deffered probe.
* bmp280
  - Harden against IRQ before registration.
  - Convert to read_avail instead of opencoding the equivalent.
  - Explicitly mark GPIO as optional.
  - Cleanup casts.
  - Remove line breaks from strings.
* htts221
  - Replace direct access to platform_data with dev_get_platdata().
  - Use device properties rather than device tree ones to allow ACPI
    probing.
  - Casting cleanups.
* intel_mrfld_adc
  - Don't use unaligned accessor for aligned data.
* isl29125
  - Reorder buer pre and post hooks to allow for coming core rework.
* ltc2983
  - Remove comp to bool.
* max1363
  - Stop using mlock from the iio_dev directly in favour of a local lock
    with clearly defined scope.
* max30100
  - Use generic device properties to allow ACPI probe.
* mpu6050
  - Convert to i2c_new_client_device.
  - Add debugfs register access.
* st_lsm6dsx
  - Provide means of configuring full scale on slave device if supported.
  - Drop include of st_sensors header to get one value. Its not otherwise
    used by this driver.
* st-sensors
  - Replace direct access to platform_data with dev_get_platdata().
  - Casting cleanups.
  - Avoid splitting strings.
* st_uvis25
  - Casting cleanups.
* tsl2563
  - Typo fix.
* tsl2772
  - scnprintf in a non obvious string building usecase. Note also 'fixes'
    a wrong calculation of remaining space that couldn't actually cause
    any trouble as there was lots of room.
* xilinx-xadc
  - Fix Lars-Peter spelling his own name wrong :) + additional typos.

* tag 'iio-for-5.8a' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio: (101 commits)
  iio: magnetometer: ak8974: Silence deferred-probe error
  Documentation: ABI: document IIO in_proximity_nearlevel file
  iio: vcnl4000: Export near level property for proximity sensor
  dt-bindings: iio: light: vcnl4000: Add proximity-near-level
  dt-bindings: iio: Introduce common properties for iio sensors
  dt-bindings: iio: vcnl4000: convert bindings to YAML format
  iio: Fix misspellings of "Analog Devices"
  iio: light: isl29125: fix iio_triggered_buffer_{predisable,postenable} positions
  iio: adc: fsl-imx25-gcq: Use devm_platform_ioremap_resource
  iio: adc: at91-adc: Use devm_platform_ioremap_resource
  iio: adc: sun4i-gpadc-iio: Use devm_platform_ioremap_resource
  iio:light:ltr501: Drop unnecessary cast of parameter in regmap_bulk_read
  iio:magn:mmc35240: Drop unnecessary casts of val parameter in regmap_bulk*
  iio:imu:mpu6050: Tidy up parameters to regmap_bulk functions.
  iio:chemical:bme680: Tidy up parameters to regmap_bulk_read
  iio:chemical:atlas-sensor: Drop unnecessary explicit casts in regmap_bulk_read calls
  iio:accel:mxc4005: Drop unnecessary explicit casts in regmap_bulk_read calls
  iio: imu: st_lsm6dsx: drop huge include in sensor-hub driver
  iio: buffer: drop devm_iio_kfifo_free() API call
  iio: buffer: drop devm_iio_hw_consumer_free() API call
  ...

110 files changed:
Documentation/ABI/testing/sysfs-bus-iio-proximity [new file with mode: 0644]
Documentation/ABI/testing/sysfs-bus-iio-sx9310 [new file with mode: 0644]
Documentation/devicetree/bindings/iio/adc/adi,ad9467.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/iio/adc/adi,axi-adc.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/iio/adc/maxim,max1241.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/iio/adc/rockchip-saradc.txt [deleted file]
Documentation/devicetree/bindings/iio/adc/rockchip-saradc.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/iio/common.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/iio/dac/st,stm32-dac.txt [deleted file]
Documentation/devicetree/bindings/iio/dac/st,stm32-dac.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/iio/gyroscope/bmg160.txt
Documentation/devicetree/bindings/iio/light/amstaos,tsl2563.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/iio/light/tsl2563.txt [deleted file]
Documentation/devicetree/bindings/iio/light/vcnl4000.txt [deleted file]
Documentation/devicetree/bindings/iio/light/vishay,vcnl4000.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/iio/st-sensors.txt
Documentation/driver-api/driver-model/devres.rst
Documentation/driver-api/iio/triggers.rst
MAINTAINERS
drivers/iio/accel/Kconfig
drivers/iio/accel/kxsd9-i2c.c
drivers/iio/accel/mxc4005.c
drivers/iio/accel/st_accel.h
drivers/iio/accel/st_accel_buffer.c
drivers/iio/accel/st_accel_core.c
drivers/iio/accel/st_accel_i2c.c
drivers/iio/adc/Kconfig
drivers/iio/adc/Makefile
drivers/iio/adc/ad7476.c
drivers/iio/adc/ad7780.c
drivers/iio/adc/ad7791.c
drivers/iio/adc/ad7793.c
drivers/iio/adc/ad9467.c [new file with mode: 0644]
drivers/iio/adc/adi-axi-adc.c [new file with mode: 0644]
drivers/iio/adc/at91_adc.c
drivers/iio/adc/fsl-imx25-gcq.c
drivers/iio/adc/intel_mrfld_adc.c
drivers/iio/adc/max1241.c [new file with mode: 0644]
drivers/iio/adc/max1363.c
drivers/iio/adc/sun4i-gpadc-iio.c
drivers/iio/adc/xilinx-xadc-core.c
drivers/iio/adc/xilinx-xadc-events.c
drivers/iio/adc/xilinx-xadc.h
drivers/iio/buffer/industrialio-buffer-dma.c
drivers/iio/buffer/industrialio-buffer-dmaengine.c
drivers/iio/buffer/industrialio-hw-consumer.c
drivers/iio/buffer/industrialio-triggered-buffer.c
drivers/iio/buffer/kfifo_buf.c
drivers/iio/chemical/atlas-sensor.c
drivers/iio/chemical/bme680_core.c
drivers/iio/common/st_sensors/st_sensors_core.c
drivers/iio/common/st_sensors/st_sensors_i2c.c
drivers/iio/common/st_sensors/st_sensors_spi.c
drivers/iio/common/st_sensors/st_sensors_trigger.c
drivers/iio/gyro/Kconfig
drivers/iio/gyro/bmg160_i2c.c
drivers/iio/gyro/bmg160_spi.c
drivers/iio/gyro/mpu3050-i2c.c
drivers/iio/gyro/st_gyro_buffer.c
drivers/iio/gyro/st_gyro_core.c
drivers/iio/health/max30100.c
drivers/iio/humidity/hts221_buffer.c
drivers/iio/humidity/hts221_i2c.c
drivers/iio/humidity/hts221_spi.c
drivers/iio/imu/adis.c
drivers/iio/imu/adis16400.c
drivers/iio/imu/adis16460.c
drivers/iio/imu/bmi160/bmi160_i2c.c
drivers/iio/imu/bmi160/bmi160_spi.c
drivers/iio/imu/inv_mpu6050/inv_mpu_acpi.c
drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c
drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c
drivers/iio/industrialio-buffer.c
drivers/iio/industrialio-core.c
drivers/iio/industrialio-trigger.c
drivers/iio/inkern.c
drivers/iio/light/isl29125.c
drivers/iio/light/ltr501.c
drivers/iio/light/st_uvis25_i2c.c
drivers/iio/light/st_uvis25_spi.c
drivers/iio/light/tsl2563.c
drivers/iio/light/tsl2772.c
drivers/iio/light/vcnl4000.c
drivers/iio/magnetometer/ak8974.c
drivers/iio/magnetometer/bmc150_magn_spi.c
drivers/iio/magnetometer/mmc35240.c
drivers/iio/magnetometer/st_magn_core.c
drivers/iio/pressure/bmp280-core.c
drivers/iio/pressure/st_pressure_core.c
drivers/iio/proximity/Kconfig
drivers/iio/proximity/Makefile
drivers/iio/proximity/sx9310.c [new file with mode: 0644]
drivers/iio/temperature/ltc2983.c
drivers/iio/trigger/iio-trig-hrtimer.c
drivers/staging/iio/Documentation/overview.txt
include/linux/fpga/adi-axi-common.h
include/linux/iio/adc/ad_sigma_delta.h
include/linux/iio/adc/adi-axi-adc.h [new file with mode: 0644]
include/linux/iio/buffer-dma.h
include/linux/iio/buffer-dmaengine.h
include/linux/iio/buffer_impl.h
include/linux/iio/consumer.h
include/linux/iio/hw-consumer.h
include/linux/iio/iio.h
include/linux/iio/kfifo_buf.h
include/linux/iio/trigger.h
include/linux/iio/triggered_buffer.h

diff --git a/Documentation/ABI/testing/sysfs-bus-iio-proximity b/Documentation/ABI/testing/sysfs-bus-iio-proximity
new file mode 100644 (file)
index 0000000..2172f3b
--- /dev/null
@@ -0,0 +1,10 @@
+What:          /sys/bus/iio/devices/iio:deviceX/in_proximity_nearlevel
+Date:          March 2020
+KernelVersion: 5.7
+Contact:       linux-iio@vger.kernel.org
+Description:
+               Near level for proximity sensors. This is a single integer
+               value that tells user space when an object should be
+               considered close to the device. If the value read from the
+               sensor is above or equal to the value in this file an object
+               should typically be considered near.
diff --git a/Documentation/ABI/testing/sysfs-bus-iio-sx9310 b/Documentation/ABI/testing/sysfs-bus-iio-sx9310
new file mode 100644 (file)
index 0000000..3ac7759
--- /dev/null
@@ -0,0 +1,10 @@
+What:          /sys/bus/iio/devices/iio:deviceX/in_proximity3_comb_raw
+Date:          February 2019
+KernelVersion: 5.6
+Contact:       Daniel Campello <campello@chromium.org>
+Description:
+               Proximity measurement indicating that some object is
+               near the combined sensor. The combined sensor presents
+               proximity measurements constructed by hardware by
+               combining measurements taken from a given set of
+               physical sensors.
diff --git a/Documentation/devicetree/bindings/iio/adc/adi,ad9467.yaml b/Documentation/devicetree/bindings/iio/adc/adi,ad9467.yaml
new file mode 100644 (file)
index 0000000..c4f57fa
--- /dev/null
@@ -0,0 +1,65 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iio/adc/adi,ad9467.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Analog Devices AD9467 High-Speed ADC
+
+maintainers:
+  - Michael Hennerich <michael.hennerich@analog.com>
+  - Alexandru Ardelean <alexandru.ardelean@analog.com>
+
+description: |
+  The AD9467 is a 16-bit, monolithic, IF sampling analog-to-digital
+  converter (ADC).
+
+  https://www.analog.com/media/en/technical-documentation/data-sheets/AD9467.pdf
+
+properties:
+  compatible:
+    enum:
+      - adi,ad9467
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  clock-names:
+    items:
+      - const: adc-clk
+
+  powerdown-gpios:
+    description:
+      Pin that controls the powerdown mode of the device.
+    maxItems: 1
+
+  reset-gpios:
+    description:
+      Reset pin for the device.
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+
+additionalProperties: false
+
+examples:
+  - |
+    spi {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        adc@0 {
+          compatible = "adi,ad9467";
+          reg = <0>;
+          clocks = <&adc_clk>;
+          clock-names = "adc-clk";
+        };
+    };
+...
diff --git a/Documentation/devicetree/bindings/iio/adc/adi,axi-adc.yaml b/Documentation/devicetree/bindings/iio/adc/adi,axi-adc.yaml
new file mode 100644 (file)
index 0000000..0924b2b
--- /dev/null
@@ -0,0 +1,62 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iio/adc/adi,axi-adc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Analog Devices AXI ADC IP core
+
+maintainers:
+  - Michael Hennerich <michael.hennerich@analog.com>
+  - Alexandru Ardelean <alexandru.ardelean@analog.com>
+
+description: |
+  Analog Devices Generic AXI ADC IP core for interfacing an ADC device
+  with a high speed serial (JESD204B/C) or source synchronous parallel
+  interface (LVDS/CMOS).
+  Usually, some other interface type (i.e SPI) is used as a control
+  interface for the actual ADC, while this IP core will interface
+  to the data-lines of the ADC and handle the streaming of data into
+  memory via DMA.
+
+  https://wiki.analog.com/resources/fpga/docs/axi_adc_ip
+
+properties:
+  compatible:
+    enum:
+      - adi,axi-adc-10.0.a
+
+  reg:
+    maxItems: 1
+
+  dmas:
+    maxItems: 1
+
+  dma-names:
+    items:
+      - const: rx
+
+  adi,adc-dev:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      A reference to a the actual ADC to which this FPGA ADC interfaces to.
+
+required:
+  - compatible
+  - dmas
+  - reg
+  - adi,adc-dev
+
+additionalProperties: false
+
+examples:
+  - |
+    axi-adc@44a00000 {
+          compatible = "adi,axi-adc-10.0.a";
+          reg = <0x44a00000 0x10000>;
+          dmas = <&rx_dma 0>;
+          dma-names = "rx";
+
+          adi,adc-dev = <&spi_adc>;
+    };
+...
diff --git a/Documentation/devicetree/bindings/iio/adc/maxim,max1241.yaml b/Documentation/devicetree/bindings/iio/adc/maxim,max1241.yaml
new file mode 100644 (file)
index 0000000..f562505
--- /dev/null
@@ -0,0 +1,63 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+# Copyright 2020 Alexandru Lazar
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iio/adc/maxim,max1241.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Maxim MAX1241 12-bit, single-channel analog to digital converter
+
+maintainers:
+  - Alexandru Lazar <alazar@startmail.com>
+
+description: |
+  Bindings for the max1241 12-bit, single-channel ADC device. Datasheet
+  can be found at:
+    https://datasheets.maximintegrated.com/en/ds/MAX1240-MAX1241.pdf
+
+properties:
+  compatible:
+    enum:
+      - maxim,max1241
+
+  reg:
+    maxItems: 1
+
+  vdd-supply:
+    description:
+      Device tree identifier of the regulator that powers the ADC.
+
+  vref-supply:
+    description:
+      Device tree identifier of the regulator that provides the external
+      reference voltage.
+
+  shutdown-gpios:
+    description:
+      GPIO spec for the GPIO pin connected to the ADC's /SHDN pin. If
+      specified, the /SHDN pin will be asserted between conversions,
+      thus enabling power-down mode.
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - vdd-supply
+  - vref-supply
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+    spi {
+      #address-cells = <1>;
+      #size-cells = <0>;
+
+        adc@0 {
+            compatible = "maxim,max1241";
+            reg = <0>;
+            vdd-supply = <&adc_vdd>;
+            vref-supply = <&adc_vref>;
+            spi-max-frequency = <1000000>;
+            shutdown-gpios = <&gpio 26 1>;
+        };
+    };
diff --git a/Documentation/devicetree/bindings/iio/adc/rockchip-saradc.txt b/Documentation/devicetree/bindings/iio/adc/rockchip-saradc.txt
deleted file mode 100644 (file)
index c2c50b5..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-Rockchip Successive Approximation Register (SAR) A/D Converter bindings
-
-Required properties:
-- compatible: should be "rockchip,<name>-saradc" or "rockchip,rk3066-tsadc"
-   - "rockchip,saradc": for rk3188, rk3288
-   - "rockchip,rk3066-tsadc": for rk3036
-   - "rockchip,rk3328-saradc", "rockchip,rk3399-saradc": for rk3328
-   - "rockchip,rk3399-saradc": for rk3399
-   - "rockchip,rv1108-saradc", "rockchip,rk3399-saradc": for rv1108
-
-- reg: physical base address of the controller and length of memory mapped
-       region.
-- interrupts: The interrupt number to the cpu. The interrupt specifier format
-              depends on the interrupt controller.
-- clocks: Must contain an entry for each entry in clock-names.
-- clock-names: Shall be "saradc" for the converter-clock, and "apb_pclk" for
-               the peripheral clock.
-- vref-supply: The regulator supply ADC reference voltage.
-- #io-channel-cells: Should be 1, see ../iio-bindings.txt
-
-Optional properties:
-- resets: Must contain an entry for each entry in reset-names if need support
-         this option. See ../reset/reset.txt for details.
-- reset-names: Must include the name "saradc-apb".
-
-Example:
-       saradc: saradc@2006c000 {
-               compatible = "rockchip,saradc";
-               reg = <0x2006c000 0x100>;
-               interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
-               clocks = <&cru SCLK_SARADC>, <&cru PCLK_SARADC>;
-               clock-names = "saradc", "apb_pclk";
-               resets = <&cru SRST_SARADC>;
-               reset-names = "saradc-apb";
-               #io-channel-cells = <1>;
-               vref-supply = <&vcc18>;
-       };
diff --git a/Documentation/devicetree/bindings/iio/adc/rockchip-saradc.yaml b/Documentation/devicetree/bindings/iio/adc/rockchip-saradc.yaml
new file mode 100644 (file)
index 0000000..bcff82a
--- /dev/null
@@ -0,0 +1,80 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iio/adc/rockchip-saradc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Rockchip Successive Approximation Register (SAR) A/D Converter
+
+maintainers:
+  - Heiko Stuebner <heiko@sntech.de>
+
+properties:
+  compatible:
+    oneOf:
+      - const: rockchip,saradc
+      - const: rockchip,rk3066-tsadc
+      - const: rockchip,rk3399-saradc
+      - items:
+          - enum:
+            - rockchip,px30-saradc
+            - rockchip,rk3308-saradc
+            - rockchip,rk3328-saradc
+            - rockchip,rv1108-saradc
+          - const: rockchip,rk3399-saradc
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: converter clock
+      - description: peripheral clock
+
+  clock-names:
+    items:
+      - const: saradc
+      - const: apb_pclk
+
+  resets:
+    maxItems: 1
+
+  reset-names:
+    const: saradc-apb
+
+  vref-supply:
+    description:
+      The regulator supply for the ADC reference voltage.
+
+  "#io-channel-cells":
+    const: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - vref-supply
+  - "#io-channel-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/rk3288-cru.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    saradc: saradc@2006c000 {
+      compatible = "rockchip,saradc";
+      reg = <0x2006c000 0x100>;
+      interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+      clocks = <&cru SCLK_SARADC>, <&cru PCLK_SARADC>;
+      clock-names = "saradc", "apb_pclk";
+      resets = <&cru SRST_SARADC>;
+      reset-names = "saradc-apb";
+      vref-supply = <&vcc18>;
+      #io-channel-cells = <1>;
+    };
diff --git a/Documentation/devicetree/bindings/iio/common.yaml b/Documentation/devicetree/bindings/iio/common.yaml
new file mode 100644 (file)
index 0000000..97ffcb7
--- /dev/null
@@ -0,0 +1,35 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iio/common.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Common properties for iio sensors
+
+maintainers:
+  - Jonathan Cameron <jic23@kernel.org>
+  - Guido Günther <agx@sigxcpu.org>
+
+description: |
+  This document defines device tree properties common to several iio
+  sensors. It doesn't constitue a device tree binding specification by itself but
+  is meant to be referenced by device tree bindings.
+
+  When referenced from sensor tree bindings the properties defined in this
+  document are defined as follows. The sensor tree bindings are responsible for
+  defining whether each property is required or optional.
+
+properties:
+  proximity-near-level:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description: |
+      For proximity sensors whether an object can be considered near to the
+      device depends on parameters like sensor position, covering glass and
+      aperture. This value gives an indication to userspace for which
+      sensor readings this is the case.
+
+      Raw proximity values equal or above this level should be
+      considered 'near' to the device (an object is near to the
+      sensor).
+
+...
diff --git a/Documentation/devicetree/bindings/iio/dac/st,stm32-dac.txt b/Documentation/devicetree/bindings/iio/dac/st,stm32-dac.txt
deleted file mode 100644 (file)
index bf2925c..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-STMicroelectronics STM32 DAC
-
-The STM32 DAC is a 12-bit voltage output digital-to-analog converter. The DAC
-may be configured in 8 or 12-bit mode. It has two output channels, each with
-its own converter.
-It has built-in noise and triangle waveform generator and supports external
-triggers for conversions. The DAC's output buffer allows a high drive output
-current.
-
-Contents of a stm32 dac root node:
------------------------------------
-Required properties:
-- compatible: Should be one of:
-  "st,stm32f4-dac-core"
-  "st,stm32h7-dac-core"
-- reg: Offset and length of the device's register set.
-- clocks: Must contain an entry for pclk (which feeds the peripheral bus
-  interface)
-- clock-names: Must be "pclk".
-- vref-supply: Phandle to the vref+ input analog reference supply.
-- #address-cells = <1>;
-- #size-cells = <0>;
-
-Optional properties:
-- resets: Must contain the phandle to the reset controller.
-- A pinctrl state named "default" for each DAC channel may be defined to set
-  DAC_OUTx pin in mode of operation for analog output on external pin.
-
-Contents of a stm32 dac child node:
------------------------------------
-DAC core node should contain at least one subnode, representing a
-DAC instance/channel available on the machine.
-
-Required properties:
-- compatible: Must be "st,stm32-dac".
-- reg: Must be either 1 or 2, to define (single) channel in use
-- #io-channel-cells = <1>: See the IIO bindings section "IIO consumers" in
-  Documentation/devicetree/bindings/iio/iio-bindings.txt
-
-Example:
-       dac: dac@40007400 {
-               compatible = "st,stm32h7-dac-core";
-               reg = <0x40007400 0x400>;
-               clocks = <&clk>;
-               clock-names = "pclk";
-               vref-supply = <&reg_vref>;
-               pinctrl-names = "default";
-               pinctrl-0 = <&dac_out1 &dac_out2>;
-               #address-cells = <1>;
-               #size-cells = <0>;
-
-               dac1: dac@1 {
-                       compatible = "st,stm32-dac";
-                       #io-channels-cells = <1>;
-                       reg = <1>;
-               };
-
-               dac2: dac@2 {
-                       compatible = "st,stm32-dac";
-                       #io-channels-cells = <1>;
-                       reg = <2>;
-               };
-       };
diff --git a/Documentation/devicetree/bindings/iio/dac/st,stm32-dac.yaml b/Documentation/devicetree/bindings/iio/dac/st,stm32-dac.yaml
new file mode 100644 (file)
index 0000000..393f700
--- /dev/null
@@ -0,0 +1,110 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/iio/dac/st,stm32-dac.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: STMicroelectronics STM32 DAC bindings
+
+description: |
+  The STM32 DAC is a 12-bit voltage output digital-to-analog converter. The DAC
+  may be configured in 8 or 12-bit mode. It has two output channels, each with
+  its own converter.
+  It has built-in noise and triangle waveform generator and supports external
+  triggers for conversions. The DAC's output buffer allows a high drive output
+  current.
+
+maintainers:
+  - Fabrice Gasnier <fabrice.gasnier@st.com>
+
+properties:
+  compatible:
+    enum:
+      - st,stm32f4-dac-core
+      - st,stm32h7-dac-core
+
+  reg:
+    maxItems: 1
+
+  resets:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  clock-names:
+    items:
+      - const: pclk
+
+  vref-supply:
+    description: Phandle to the vref input analog reference voltage.
+
+  '#address-cells':
+    const: 1
+
+  '#size-cells':
+    const: 0
+
+additionalProperties: false
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - vref-supply
+  - '#address-cells'
+  - '#size-cells'
+
+patternProperties:
+  "^dac@[1-2]+$":
+    type: object
+    description:
+      A DAC block node should contain at least one subnode, representing an
+      DAC instance/channel available on the machine.
+
+    properties:
+      compatible:
+        const: st,stm32-dac
+
+      reg:
+        description: Must be either 1 or 2, to define (single) channel in use
+        enum: [1, 2]
+
+      '#io-channel-cells':
+        const: 1
+
+    additionalProperties: false
+
+    required:
+      - compatible
+      - reg
+      - '#io-channel-cells'
+
+examples:
+  - |
+    // Example on stm32mp157c
+    #include <dt-bindings/clock/stm32mp1-clks.h>
+    dac: dac@40017000 {
+      compatible = "st,stm32h7-dac-core";
+      reg = <0x40017000 0x400>;
+      clocks = <&rcc DAC12>;
+      clock-names = "pclk";
+      vref-supply = <&vref>;
+      #address-cells = <1>;
+      #size-cells = <0>;
+
+      dac@1 {
+        compatible = "st,stm32-dac";
+        #io-channel-cells = <1>;
+        reg = <1>;
+      };
+
+      dac@2 {
+        compatible = "st,stm32-dac";
+        #io-channel-cells = <1>;
+        reg = <2>;
+      };
+    };
+
+...
index 78e18a1e9c1da130cccd32361ef40f3816473c3d..bb43d1ad9c9f8542c3aea00eda85dd65f695bd5c 100644 (file)
@@ -2,7 +2,7 @@
 
 Required properties:
 
-  - compatible : should be "bosch,bmg160" or "bosch,bmi055_gyro"
+  - compatible : should be "bosch,bmg160", "bosch,bmi055_gyro" or "bosch,bmi088_gyro"
   - reg : the I2C address of the sensor (0x69)
 
 Optional properties:
diff --git a/Documentation/devicetree/bindings/iio/light/amstaos,tsl2563.yaml b/Documentation/devicetree/bindings/iio/light/amstaos,tsl2563.yaml
new file mode 100644 (file)
index 0000000..efd2eba
--- /dev/null
@@ -0,0 +1,49 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iio/light/amstaos,tsl2563.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: AMS TAOS TSL2563 ambient light sensor
+
+maintainers:
+  - Sebastian Reichel <sre@kernel.org>
+
+description: |
+  Ambient light sensor with an i2c interface.
+
+properties:
+  compatible:
+    enum:
+      - amstaos,tsl2560
+      - amstaos,tsl2561
+      - amstaos,tsl2562
+      - amstaos,tsl2563
+
+  reg:
+    maxItems: 1
+
+  amstaos,cover-comp-gain:
+    description: Multiplier for gain compensation
+    allOf:
+      - $ref: /schemas/types.yaml#/definitions/uint32
+      - enum: [1, 16]
+
+required:
+  - compatible
+  - reg
+
+examples:
+  - |
+    i2c {
+
+      #address-cells = <1>;
+      #size-cells = <0>;
+
+      light-sensor@29 {
+        compatible = "amstaos,tsl2563";
+        reg = <0x29>;
+        amstaos,cover-comp-gain = <16>;
+      };
+    };
+...
diff --git a/Documentation/devicetree/bindings/iio/light/tsl2563.txt b/Documentation/devicetree/bindings/iio/light/tsl2563.txt
deleted file mode 100644 (file)
index f91e809..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-* AMS TAOS TSL2563 ambient light sensor
-
-Required properties:
-
-  - compatible : should be "amstaos,tsl2563"
-  - reg : the I2C address of the sensor
-
-Optional properties:
-
-  - amstaos,cover-comp-gain : integer used as multiplier for gain
-                              compensation (default = 1)
-
-Example:
-
-tsl2563@29 {
-       compatible = "amstaos,tsl2563";
-       reg = <0x29>;
-       amstaos,cover-comp-gain = <16>;
-};
diff --git a/Documentation/devicetree/bindings/iio/light/vcnl4000.txt b/Documentation/devicetree/bindings/iio/light/vcnl4000.txt
deleted file mode 100644 (file)
index 955af45..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-VISHAY VCNL4000 -  Ambient Light and proximity sensor
-
-This driver supports the VCNL4000/10/20/40 and VCNL4200 chips
-
-Required properties:
-
-       -compatible: must be one of :
-        vishay,vcnl4000
-        vishay,vcnl4010
-        vishay,vcnl4020
-        vishay,vcnl4040
-        vishay,vcnl4200
-
-       -reg: I2C address of the sensor, should be one from below based on the model:
-        0x13
-        0x51
-        0x60
-
-Example:
-
-light-sensor@51 {
-       compatible = "vishay,vcnl4200";
-       reg = <0x51>;
-};
diff --git a/Documentation/devicetree/bindings/iio/light/vishay,vcnl4000.yaml b/Documentation/devicetree/bindings/iio/light/vishay,vcnl4000.yaml
new file mode 100644 (file)
index 0000000..da8f2e8
--- /dev/null
@@ -0,0 +1,50 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iio/light/vishay,vcnl4000.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: VISHAY VCNL4000 ambient light and proximity sensor
+
+maintainers:
+  - Peter Meerwald <pmeerw@pmeerw.net>
+
+description: |
+  Ambient light sensing with proximity detection over an i2c
+  interface.
+
+allOf:
+  - $ref: ../common.yaml#
+
+properties:
+  compatible:
+    enum:
+      - vishay,vcnl4000
+      - vishay,vcnl4010
+      - vishay,vcnl4020
+      - vishay,vcnl4040
+      - vishay,vcnl4200
+  reg:
+    maxItems: 1
+
+  proximity-near-level: true
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+- |
+  i2c {
+      #address-cells = <1>;
+      #size-cells = <0>;
+
+      light-sensor@51 {
+              compatible = "vishay,vcnl4200";
+              reg = <0x51>;
+              proximity-near-level = <220>;
+      };
+  };
+...
index 0ef64a4444797f7687a8443aa595546adf7c9fc5..3213599c5071a4383b4fc52e4b6e3ea11bdc540e 100644 (file)
@@ -50,6 +50,7 @@ Accelerometers:
 - st,lis3dhh
 - st,lis3de
 - st,lis2de12
+- st,lis2hh12
 
 Gyroscopes:
 - st,l3g4200d-gyro
index 46c13780994c4ee90aa526ab6d90e75774f0522e..91b0b8e5556c25487bf42a94ccf9b96f597f6286 100644 (file)
@@ -284,21 +284,13 @@ I2C
 
 IIO
   devm_iio_device_alloc()
-  devm_iio_device_free()
   devm_iio_device_register()
-  devm_iio_device_unregister()
   devm_iio_kfifo_allocate()
-  devm_iio_kfifo_free()
   devm_iio_triggered_buffer_setup()
-  devm_iio_triggered_buffer_cleanup()
   devm_iio_trigger_alloc()
-  devm_iio_trigger_free()
   devm_iio_trigger_register()
-  devm_iio_trigger_unregister()
   devm_iio_channel_get()
-  devm_iio_channel_release()
   devm_iio_channel_get_all()
-  devm_iio_channel_release_all()
 
 INPUT
   devm_input_allocate_device()
index 5c2156de6284f0f9c5c2101670e7ea29caf64b59..dfd7ba3eabde0244b2d1895a24cb16fa052b8eb3 100644 (file)
@@ -4,9 +4,7 @@ Triggers
 
 * struct :c:type:`iio_trigger` â€” industrial I/O trigger device
 * :c:func:`devm_iio_trigger_alloc` â€” Resource-managed iio_trigger_alloc
-* :c:func:`devm_iio_trigger_free` â€” Resource-managed iio_trigger_free
 * :c:func:`devm_iio_trigger_register` â€” Resource-managed iio_trigger_register
-* :c:func:`devm_iio_trigger_unregister` â€” Resource-managed
   iio_trigger_unregister
 * :c:func:`iio_trigger_validate_own_device` â€” Check if a trigger and IIO
   device belong to the same device
index e64e5db314976dc9f73107c9bd616aeaa3dd9c70..dae6cd9170c4caff1aefc4bce441b23df95a70d8 100644 (file)
@@ -294,6 +294,7 @@ F:  drivers/gpio/gpio-104-idio-16.c
 
 ACCES 104-QUAD-8 DRIVER
 M:     William Breathitt Gray <vilhelm.gray@gmail.com>
+M:     Syed Nayyar Waris <syednwaris@gmail.com>
 L:     linux-iio@vger.kernel.org
 S:     Maintained
 F:     Documentation/ABI/testing/sysfs-bus-counter-104-quad-8
index 5d91a6dda89405266ba5bbb57ea2386e2374d8b9..24ebe9e76915100e576cd2cf984d267552e12a2a 100644 (file)
@@ -238,7 +238,7 @@ config IIO_ST_ACCEL_3AXIS
          Say yes here to build support for STMicroelectronics accelerometers:
          LSM303DLH, LSM303DLHC, LIS3DH, LSM330D, LSM330DL, LSM330DLC,
          LIS331DLH, LSM303DL, LSM303DLM, LSM330, LIS2DH12, H3LIS331DL,
-         LNG2DM, LIS3DE, LIS2DE12
+         LNG2DM, LIS3DE, LIS2DE12, LIS2HH12
 
          This driver can also be built as a module. If so, these modules
          will be created:
index 38411e1c155bd38c93ba0d559b4f5f0c025594ed..b6f3de7ef8ea1df482e43c84a76778b02bbdcec4 100644 (file)
@@ -21,8 +21,8 @@ static int kxsd9_i2c_probe(struct i2c_client *i2c,
 
        regmap = devm_regmap_init_i2c(i2c, &config);
        if (IS_ERR(regmap)) {
-               dev_err(&i2c->dev, "Failed to register i2c regmap %d\n",
-                       (int)PTR_ERR(regmap));
+               dev_err(&i2c->dev, "Failed to register i2c regmap: %pe\n",
+                       regmap);
                return PTR_ERR(regmap);
        }
 
index 3d5bea651923eb54de3345686ca45b1cc5d73400..9d07642c0de106df7941d33cfcf55ceb72f037b0 100644 (file)
@@ -135,7 +135,7 @@ static int mxc4005_read_xyz(struct mxc4005_data *data)
        int ret;
 
        ret = regmap_bulk_read(data->regmap, MXC4005_REG_XOUT_UPPER,
-                              (u8 *) data->buffer, sizeof(data->buffer));
+                              data->buffer, sizeof(data->buffer));
        if (ret < 0) {
                dev_err(data->dev, "failed to read axes\n");
                return ret;
@@ -150,7 +150,7 @@ static int mxc4005_read_axis(struct mxc4005_data *data,
        __be16 reg;
        int ret;
 
-       ret = regmap_bulk_read(data->regmap, addr, (u8 *) &reg, sizeof(reg));
+       ret = regmap_bulk_read(data->regmap, addr, &reg, sizeof(reg));
        if (ret < 0) {
                dev_err(data->dev, "failed to read reg %02x\n", addr);
                return ret;
index 5b13e293cade71dc155ad19d322239f8553555dd..5d356288e001cbafe01492b17163e7002e28696f 100644 (file)
@@ -35,6 +35,7 @@ enum st_accel_type {
        LIS2DW12,
        LIS3DHH,
        LIS2DE12,
+       LIS2HH12,
        ST_ACCEL_MAX,
 };
 
@@ -59,6 +60,7 @@ enum st_accel_type {
 #define LIS3DHH_ACCEL_DEV_NAME         "lis3dhh"
 #define LIS3DE_ACCEL_DEV_NAME          "lis3de"
 #define LIS2DE12_ACCEL_DEV_NAME                "lis2de12"
+#define LIS2HH12_ACCEL_DEV_NAME                "lis2hh12"
 
 /**
 * struct st_sensors_platform_data - default accel platform data
index 9f2b40474b8ec7fb9e36e382cd0beedd55a2299d..b5c814ef16379d85b4e3097fd7afc079b7158c92 100644 (file)
@@ -37,8 +37,7 @@ static int st_accel_buffer_postenable(struct iio_dev *indio_dev)
        if (err < 0)
                return err;
 
-       err = st_sensors_set_axis_enable(indio_dev,
-                                        (u8)indio_dev->active_scan_mask[0]);
+       err = st_sensors_set_axis_enable(indio_dev, indio_dev->active_scan_mask[0]);
        if (err < 0)
                goto st_accel_buffer_predisable;
 
index 7320275c7e56dee7ee0a6bb3af4461dc0c9826ab..43c50167d220cecb17ea201dd0295bd3a1973fdd 100644 (file)
@@ -904,6 +904,83 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = {
                .multi_read_bit = true,
                .bootime = 2,
        },
+       {
+               .wai = 0x41,
+               .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
+               .sensors_supported = {
+                       [0] = LIS2HH12_ACCEL_DEV_NAME,
+               },
+               .ch = (struct iio_chan_spec *)st_accel_16bit_channels,
+               .odr = {
+                       .addr = 0x20,
+                       .mask = 0x70,
+                       .odr_avl = {
+                               { .hz = 10, .value = 0x01, },
+                               { .hz = 50, .value = 0x02, },
+                               { .hz = 100, .value = 0x03, },
+                               { .hz = 200, .value = 0x04, },
+                               { .hz = 400, .value = 0x05, },
+                               { .hz = 800, .value = 0x06, },
+                       },
+               },
+               .pw = {
+                       .addr = 0x20,
+                       .mask = 0x70,
+                       .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
+               },
+               .enable_axis = {
+                       .addr = ST_SENSORS_DEFAULT_AXIS_ADDR,
+                       .mask = ST_SENSORS_DEFAULT_AXIS_MASK,
+               },
+               .fs = {
+                       .addr = 0x23,
+                       .mask = 0x30,
+                       .fs_avl = {
+                               [0] = {
+                                       .num = ST_ACCEL_FS_AVL_2G,
+                                       .value = 0x00,
+                                       .gain = IIO_G_TO_M_S_2(61),
+                               },
+                               [1] = {
+                                       .num = ST_ACCEL_FS_AVL_4G,
+                                       .value = 0x02,
+                                       .gain = IIO_G_TO_M_S_2(122),
+                               },
+                               [2] = {
+                                       .num = ST_ACCEL_FS_AVL_8G,
+                                       .value = 0x03,
+                                       .gain = IIO_G_TO_M_S_2(244),
+                               },
+                       },
+               },
+               .bdu = {
+                       .addr = 0x20,
+                       .mask = 0x08,
+               },
+               .drdy_irq = {
+                       .int1 = {
+                               .addr = 0x22,
+                               .mask = 0x01,
+                       },
+                       .int2 = {
+                               .addr = 0x25,
+                               .mask = 0x01,
+                       },
+                       .addr_ihl = 0x24,
+                       .mask_ihl = 0x02,
+                       .stat_drdy = {
+                               .addr = ST_SENSORS_DEFAULT_STAT_ADDR,
+                               .mask = 0x07,
+                       },
+               },
+               .sim = {
+                       .addr = 0x23,
+                       .value = BIT(0),
+               },
+               .multi_read_bit = true,
+               .bootime = 2,
+       },
+
 };
 
 static int st_accel_read_raw(struct iio_dev *indio_dev,
@@ -1170,8 +1247,7 @@ EXPORT_SYMBOL(st_accel_get_settings);
 int st_accel_common_probe(struct iio_dev *indio_dev)
 {
        struct st_sensor_data *adata = iio_priv(indio_dev);
-       struct st_sensors_platform_data *pdata =
-               (struct st_sensors_platform_data *)adata->dev->platform_data;
+       struct st_sensors_platform_data *pdata = dev_get_platdata(adata->dev);
        struct iio_chan_spec *channels;
        size_t channels_size;
        int err;
@@ -1204,8 +1280,7 @@ int st_accel_common_probe(struct iio_dev *indio_dev)
                         "failed to apply ACPI orientation data: %d\n", err);
 
        indio_dev->channels = channels;
-       adata->current_fullscale = (struct st_sensor_fullscale_avl *)
-                                       &adata->sensor_settings->fs.fs_avl[0];
+       adata->current_fullscale = &adata->sensor_settings->fs.fs_avl[0];
        adata->odr = adata->sensor_settings->odr.odr_avl[0].hz;
 
        if (!pdata)
index 6b283be26ebc80f0210ac80cb63c468a23cf1db0..360e16f2cadb9669d482d2c0c54ab384bf9ae848 100644 (file)
@@ -104,6 +104,10 @@ static const struct of_device_id st_accel_of_match[] = {
                .compatible = "st,lis2de12",
                .data = LIS2DE12_ACCEL_DEV_NAME,
        },
+       {
+               .compatible = "st,lis2hh12",
+               .data = LIS2HH12_ACCEL_DEV_NAME,
+       },
        {},
 };
 MODULE_DEVICE_TABLE(of, st_accel_of_match);
@@ -138,6 +142,7 @@ static const struct i2c_device_id st_accel_id_table[] = {
        { LIS2DW12_ACCEL_DEV_NAME },
        { LIS3DE_ACCEL_DEV_NAME },
        { LIS2DE12_ACCEL_DEV_NAME },
+       { LIS2HH12_ACCEL_DEV_NAME },
        {},
 };
 MODULE_DEVICE_TABLE(i2c, st_accel_id_table);
index 12bb8b7ca1ff8e7cc9742360aa0542cbd8884c38..c48c00077775a27f1425270222b1718bd7088d2c 100644 (file)
@@ -246,6 +246,41 @@ config AD799X
          To compile this driver as a module, choose M here: the module will be
          called ad799x.
 
+config AD9467
+       tristate "Analog Devices AD9467 High Speed ADC driver"
+       depends on SPI
+       select ADI_AXI_ADC
+       help
+         Say yes here to build support for Analog Devices:
+         * AD9467 16-Bit, 200 MSPS/250 MSPS Analog-to-Digital Converter
+
+         The driver requires the assistance of the AXI ADC IP core to operate,
+         since SPI is used for configuration only, while data has to be
+         streamed into memory via DMA.
+
+         To compile this driver as a module, choose M here: the module will be
+         called ad9467.
+
+config ADI_AXI_ADC
+       tristate "Analog Devices Generic AXI ADC IP core driver"
+       select IIO_BUFFER
+       select IIO_BUFFER_HW_CONSUMER
+       select IIO_BUFFER_DMAENGINE
+       help
+         Say yes here to build support for Analog Devices Generic
+         AXI ADC IP core. The IP core is used for interfacing with
+         analog-to-digital (ADC) converters that require either a high-speed
+         serial interface (JESD204B/C) or a source synchronous parallel
+         interface (LVDS/CMOS).
+         Typically (for such devices) SPI will be used for configuration only,
+         while this IP core handles the streaming of data into memory via DMA.
+
+         Link: https://wiki.analog.com/resources/fpga/docs/axi_adc_ip
+         If unsure, say N (but it's safe to say "Y").
+
+         To compile this driver as a module, choose M here: the
+         module will be called adi-axi-adc.
+
 config ASPEED_ADC
        tristate "Aspeed ADC"
        depends on ARCH_ASPEED || COMPILE_TEST
@@ -595,6 +630,16 @@ config MAX1118
          To compile this driver as a module, choose M here: the module will be
          called max1118.
 
+config MAX1241
+       tristate "Maxim max1241 ADC driver"
+       depends on SPI_MASTER
+       help
+         Say yes here to build support for Maxim max1241 12-bit, single-channel
+         ADC.
+
+         To compile this driver as a module, choose M here: the module will be
+         called max1241.
+
 config MAX1363
        tristate "Maxim max1363 ADC driver"
        depends on I2C
index 637807861112f525887a1f0770943245954be235..2f5bc224412b6e2519a0a7d4fc9d3d802238e485 100644 (file)
@@ -26,6 +26,8 @@ obj-$(CONFIG_AD7793) += ad7793.o
 obj-$(CONFIG_AD7887) += ad7887.o
 obj-$(CONFIG_AD7949) += ad7949.o
 obj-$(CONFIG_AD799X) += ad799x.o
+obj-$(CONFIG_AD9467) += ad9467.o
+obj-$(CONFIG_ADI_AXI_ADC) += adi-axi-adc.o
 obj-$(CONFIG_ASPEED_ADC) += aspeed_adc.o
 obj-$(CONFIG_AT91_ADC) += at91_adc.o
 obj-$(CONFIG_AT91_SAMA5D2_ADC) += at91-sama5d2_adc.o
@@ -57,6 +59,7 @@ obj-$(CONFIG_LTC2497) += ltc2497.o ltc2497-core.o
 obj-$(CONFIG_MAX1027) += max1027.o
 obj-$(CONFIG_MAX11100) += max11100.o
 obj-$(CONFIG_MAX1118) += max1118.o
+obj-$(CONFIG_MAX1241) += max1241.o
 obj-$(CONFIG_MAX1363) += max1363.o
 obj-$(CONFIG_MAX9611) += max9611.o
 obj-$(CONFIG_MCP320X) += mcp320x.o
index 76747488044b8305a2ac12caa3b9b14c5c5bba48..e9984a38fc4c5d821f111674946ed35f2770deab 100644 (file)
 #include <linux/sysfs.h>
 #include <linux/spi/spi.h>
 #include <linux/regulator/consumer.h>
+#include <linux/gpio/consumer.h>
 #include <linux/err.h>
 #include <linux/module.h>
 #include <linux/bitops.h>
+#include <linux/delay.h>
 
 #include <linux/iio/iio.h>
 #include <linux/iio/sysfs.h>
@@ -27,6 +29,8 @@ struct ad7476_state;
 struct ad7476_chip_info {
        unsigned int                    int_vref_uv;
        struct iio_chan_spec            channel[2];
+       /* channels used when convst gpio is defined */
+       struct iio_chan_spec            convst_channel[2];
        void (*reset)(struct ad7476_state *);
 };
 
@@ -34,6 +38,7 @@ struct ad7476_state {
        struct spi_device               *spi;
        const struct ad7476_chip_info   *chip_info;
        struct regulator                *reg;
+       struct gpio_desc                *convst_gpio;
        struct spi_transfer             xfer;
        struct spi_message              msg;
        /*
@@ -64,6 +69,17 @@ enum ad7476_supported_device_ids {
        ID_ADS7868,
 };
 
+static void ad7091_convst(struct ad7476_state *st)
+{
+       if (!st->convst_gpio)
+               return;
+
+       gpiod_set_value(st->convst_gpio, 0);
+       udelay(1); /* CONVST pulse width: 10 ns min */
+       gpiod_set_value(st->convst_gpio, 1);
+       udelay(1); /* Conversion time: 650 ns max */
+}
+
 static irqreturn_t ad7476_trigger_handler(int irq, void  *p)
 {
        struct iio_poll_func *pf = p;
@@ -71,6 +87,8 @@ static irqreturn_t ad7476_trigger_handler(int irq, void  *p)
        struct ad7476_state *st = iio_priv(indio_dev);
        int b_sent;
 
+       ad7091_convst(st);
+
        b_sent = spi_sync(st->spi, &st->msg);
        if (b_sent < 0)
                goto done;
@@ -93,6 +111,8 @@ static int ad7476_scan_direct(struct ad7476_state *st)
 {
        int ret;
 
+       ad7091_convst(st);
+
        ret = spi_sync(st->spi, &st->msg);
        if (ret)
                return ret;
@@ -160,6 +180,8 @@ static int ad7476_read_raw(struct iio_dev *indio_dev,
 #define AD7940_CHAN(bits) _AD7476_CHAN((bits), 15 - (bits), \
                BIT(IIO_CHAN_INFO_RAW))
 #define AD7091R_CHAN(bits) _AD7476_CHAN((bits), 16 - (bits), 0)
+#define AD7091R_CONVST_CHAN(bits) _AD7476_CHAN((bits), 16 - (bits), \
+               BIT(IIO_CHAN_INFO_RAW))
 #define ADS786X_CHAN(bits) _AD7476_CHAN((bits), 12 - (bits), \
                BIT(IIO_CHAN_INFO_RAW))
 
@@ -167,6 +189,8 @@ static const struct ad7476_chip_info ad7476_chip_info_tbl[] = {
        [ID_AD7091R] = {
                .channel[0] = AD7091R_CHAN(12),
                .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
+               .convst_channel[0] = AD7091R_CONVST_CHAN(12),
+               .convst_channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
                .reset = ad7091_reset,
        },
        [ID_AD7276] = {
@@ -232,6 +256,13 @@ static const struct iio_info ad7476_info = {
        .read_raw = &ad7476_read_raw,
 };
 
+static void ad7476_reg_disable(void *data)
+{
+       struct ad7476_state *st = data;
+
+       regulator_disable(st->reg);
+}
+
 static int ad7476_probe(struct spi_device *spi)
 {
        struct ad7476_state *st;
@@ -254,6 +285,17 @@ static int ad7476_probe(struct spi_device *spi)
        if (ret)
                return ret;
 
+       ret = devm_add_action_or_reset(&spi->dev, ad7476_reg_disable,
+                                      st);
+       if (ret)
+               return ret;
+
+       st->convst_gpio = devm_gpiod_get_optional(&spi->dev,
+                                                 "adi,conversion-start",
+                                                 GPIOD_OUT_LOW);
+       if (IS_ERR(st->convst_gpio))
+               return PTR_ERR(st->convst_gpio);
+
        spi_set_drvdata(spi, indio_dev);
 
        st->spi = spi;
@@ -266,6 +308,9 @@ static int ad7476_probe(struct spi_device *spi)
        indio_dev->channels = st->chip_info->channel;
        indio_dev->num_channels = 2;
        indio_dev->info = &ad7476_info;
+
+       if (st->convst_gpio && st->chip_info->convst_channel)
+               indio_dev->channels = st->chip_info->convst_channel;
        /* Setup default message */
 
        st->xfer.rx_buf = &st->data;
@@ -295,19 +340,8 @@ error_disable_reg:
        return ret;
 }
 
-static int ad7476_remove(struct spi_device *spi)
-{
-       struct iio_dev *indio_dev = spi_get_drvdata(spi);
-       struct ad7476_state *st = iio_priv(indio_dev);
-
-       iio_device_unregister(indio_dev);
-       iio_triggered_buffer_cleanup(indio_dev);
-       regulator_disable(st->reg);
-
-       return 0;
-}
-
 static const struct spi_device_id ad7476_id[] = {
+       {"ad7091", ID_AD7091R},
        {"ad7091r", ID_AD7091R},
        {"ad7273", ID_AD7277},
        {"ad7274", ID_AD7276},
@@ -343,7 +377,6 @@ static struct spi_driver ad7476_driver = {
                .name   = "ad7476",
        },
        .probe          = ad7476_probe,
-       .remove         = ad7476_remove,
        .id_table       = ad7476_id,
 };
 module_spi_driver(ad7476_driver);
index 291c1a898129d22cfc51de34325fb5762ff61ee0..f47606ebbbbef489c42586e00e290705c838f57b 100644 (file)
@@ -206,10 +206,29 @@ static const struct ad_sigma_delta_info ad7780_sigma_delta_info = {
        .irq_flags = IRQF_TRIGGER_LOW,
 };
 
-#define AD7780_CHANNEL(bits, wordsize) \
-       AD_SD_CHANNEL(1, 0, 0, bits, 32, (wordsize) - (bits))
-#define AD7170_CHANNEL(bits, wordsize) \
-       AD_SD_CHANNEL_NO_SAMP_FREQ(1, 0, 0, bits, 32, (wordsize) - (bits))
+#define _AD7780_CHANNEL(_bits, _wordsize, _mask_all)           \
+{                                                              \
+       .type = IIO_VOLTAGE,                                    \
+       .indexed = 1,                                           \
+       .channel = 0,                                           \
+       .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |          \
+               BIT(IIO_CHAN_INFO_OFFSET),                      \
+       .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),   \
+       .info_mask_shared_by_all = _mask_all,                   \
+       .scan_index = 1,                                        \
+       .scan_type = {                                          \
+               .sign = 'u',                                    \
+               .realbits = (_bits),                            \
+               .storagebits = 32,                              \
+               .shift = (_wordsize) - (_bits),                 \
+               .endianness = IIO_BE,                           \
+       },                                                      \
+}
+
+#define AD7780_CHANNEL(_bits, _wordsize)       \
+       _AD7780_CHANNEL(_bits, _wordsize, BIT(IIO_CHAN_INFO_SAMP_FREQ))
+#define AD7170_CHANNEL(_bits, _wordsize)       \
+       _AD7780_CHANNEL(_bits, _wordsize, 0)
 
 static const struct ad7780_chip_info ad7780_chip_info_tbl[] = {
        [ID_AD7170] = {
index abb2393926317087d0fea450bb41baa6327563ec..48432b6f60027025288bed62c47e69365ab7a823 100644 (file)
 #define AD7791_MODE_SEL_MASK           (0x3 << 6)
 #define AD7791_MODE_SEL(x)             ((x) << 6)
 
+#define __AD7991_CHANNEL(_si, _channel1, _channel2, _address, _bits, \
+       _storagebits, _shift, _extend_name, _type, _mask_all) \
+       { \
+               .type = (_type), \
+               .differential = (_channel2 == -1 ? 0 : 1), \
+               .indexed = 1, \
+               .channel = (_channel1), \
+               .channel2 = (_channel2), \
+               .address = (_address), \
+               .extend_name = (_extend_name), \
+               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
+                       BIT(IIO_CHAN_INFO_OFFSET), \
+               .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
+               .info_mask_shared_by_all = _mask_all, \
+               .scan_index = (_si), \
+               .scan_type = { \
+                       .sign = 'u', \
+                       .realbits = (_bits), \
+                       .storagebits = (_storagebits), \
+                       .shift = (_shift), \
+                       .endianness = IIO_BE, \
+               }, \
+       }
+
+#define AD7991_SHORTED_CHANNEL(_si, _channel, _address, _bits, \
+       _storagebits, _shift) \
+       __AD7991_CHANNEL(_si, _channel, _channel, _address, _bits, \
+               _storagebits, _shift, "shorted", IIO_VOLTAGE, \
+               BIT(IIO_CHAN_INFO_SAMP_FREQ))
+
+#define AD7991_CHANNEL(_si, _channel, _address, _bits, \
+       _storagebits, _shift) \
+       __AD7991_CHANNEL(_si, _channel, -1, _address, _bits, \
+               _storagebits, _shift, NULL, IIO_VOLTAGE, \
+                BIT(IIO_CHAN_INFO_SAMP_FREQ))
+
+#define AD7991_DIFF_CHANNEL(_si, _channel1, _channel2, _address, _bits, \
+       _storagebits, _shift) \
+       __AD7991_CHANNEL(_si, _channel1, _channel2, _address, _bits, \
+               _storagebits, _shift, NULL, IIO_VOLTAGE, \
+               BIT(IIO_CHAN_INFO_SAMP_FREQ))
+
+#define AD7991_SUPPLY_CHANNEL(_si, _channel, _address, _bits, _storagebits, \
+       _shift) \
+       __AD7991_CHANNEL(_si, _channel, -1, _address, _bits, \
+               _storagebits, _shift, "supply", IIO_VOLTAGE, \
+               BIT(IIO_CHAN_INFO_SAMP_FREQ))
+
 #define DECLARE_AD7787_CHANNELS(name, bits, storagebits) \
 const struct iio_chan_spec name[] = { \
-       AD_SD_DIFF_CHANNEL(0, 0, 0, AD7791_CH_AIN1P_AIN1N, \
+       AD7991_DIFF_CHANNEL(0, 0, 0, AD7791_CH_AIN1P_AIN1N, \
                (bits), (storagebits), 0), \
-       AD_SD_CHANNEL(1, 1, AD7791_CH_AIN2, (bits), (storagebits), 0), \
-       AD_SD_SHORTED_CHANNEL(2, 0, AD7791_CH_AIN1N_AIN1N, \
+       AD7991_CHANNEL(1, 1, AD7791_CH_AIN2, (bits), (storagebits), 0), \
+       AD7991_SHORTED_CHANNEL(2, 0, AD7791_CH_AIN1N_AIN1N, \
                (bits), (storagebits), 0), \
-       AD_SD_SUPPLY_CHANNEL(3, 2, AD7791_CH_AVDD_MONITOR,  \
+       AD7991_SUPPLY_CHANNEL(3, 2, AD7791_CH_AVDD_MONITOR,  \
                (bits), (storagebits), 0), \
        IIO_CHAN_SOFT_TIMESTAMP(4), \
 }
 
 #define DECLARE_AD7791_CHANNELS(name, bits, storagebits) \
 const struct iio_chan_spec name[] = { \
-       AD_SD_DIFF_CHANNEL(0, 0, 0, AD7791_CH_AIN1P_AIN1N, \
+       AD7991_DIFF_CHANNEL(0, 0, 0, AD7791_CH_AIN1P_AIN1N, \
                (bits), (storagebits), 0), \
-       AD_SD_SHORTED_CHANNEL(1, 0, AD7791_CH_AIN1N_AIN1N, \
+       AD7991_SHORTED_CHANNEL(1, 0, AD7791_CH_AIN1N_AIN1N, \
                (bits), (storagebits), 0), \
-       AD_SD_SUPPLY_CHANNEL(2, 1, AD7791_CH_AVDD_MONITOR, \
+       AD7991_SUPPLY_CHANNEL(2, 1, AD7791_CH_AVDD_MONITOR, \
                (bits), (storagebits), 0), \
        IIO_CHAN_SOFT_TIMESTAMP(3), \
 }
@@ -444,5 +492,5 @@ static struct spi_driver ad7791_driver = {
 module_spi_driver(ad7791_driver);
 
 MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
-MODULE_DESCRIPTION("Analog Device AD7787/AD7788/AD7789/AD7790/AD7791 ADC driver");
+MODULE_DESCRIPTION("Analog Devices AD7787/AD7788/AD7789/AD7790/AD7791 ADC driver");
 MODULE_LICENSE("GPL v2");
index b747db97f78ad5f60a9ea52c8643d29a21de480c..7005bde50a76558ed77929849e5772664cf3abfc 100644 (file)
@@ -354,29 +354,28 @@ static IIO_CONST_ATTR_SAMP_FREQ_AVAIL(
 static IIO_CONST_ATTR_NAMED(sampling_frequency_available_ad7797,
        sampling_frequency_available, "123 62 50 33 17 16 12 10 8 6 4");
 
-static ssize_t ad7793_show_scale_available(struct device *dev,
-                       struct device_attribute *attr, char *buf)
+static int ad7793_read_avail(struct iio_dev *indio_dev,
+                            struct iio_chan_spec const *chan,
+                            const int **vals, int *type, int *length,
+                            long mask)
 {
-       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
        struct ad7793_state *st = iio_priv(indio_dev);
-       int i, len = 0;
 
-       for (i = 0; i < ARRAY_SIZE(st->scale_avail); i++)
-               len += sprintf(buf + len, "%d.%09u ", st->scale_avail[i][0],
-                              st->scale_avail[i][1]);
-
-       len += sprintf(buf + len, "\n");
+       switch (mask) {
+       case IIO_CHAN_INFO_SCALE:
+               *vals = (int *)st->scale_avail;
+               *type = IIO_VAL_INT_PLUS_NANO;
+               /* Values are stored in a 2D matrix  */
+               *length = ARRAY_SIZE(st->scale_avail) * 2;
 
-       return len;
+               return IIO_AVAIL_LIST;
+       default:
+               return -EINVAL;
+       }
 }
 
-static IIO_DEVICE_ATTR_NAMED(in_m_in_scale_available,
-               in_voltage-voltage_scale_available, S_IRUGO,
-               ad7793_show_scale_available, NULL, 0);
-
 static struct attribute *ad7793_attributes[] = {
        &iio_const_attr_sampling_frequency_available.dev_attr.attr,
-       &iio_dev_attr_in_m_in_scale_available.dev_attr.attr,
        NULL
 };
 
@@ -534,6 +533,7 @@ static const struct iio_info ad7793_info = {
        .read_raw = &ad7793_read_raw,
        .write_raw = &ad7793_write_raw,
        .write_raw_get_fmt = &ad7793_write_raw_get_fmt,
+       .read_avail = ad7793_read_avail,
        .attrs = &ad7793_attribute_group,
        .validate_trigger = ad_sd_validate_trigger,
 };
@@ -546,47 +546,113 @@ static const struct iio_info ad7797_info = {
        .validate_trigger = ad_sd_validate_trigger,
 };
 
+#define __AD7793_CHANNEL(_si, _channel1, _channel2, _address, _bits, \
+       _storagebits, _shift, _extend_name, _type, _mask_type_av, _mask_all) \
+       { \
+               .type = (_type), \
+               .differential = (_channel2 == -1 ? 0 : 1), \
+               .indexed = 1, \
+               .channel = (_channel1), \
+               .channel2 = (_channel2), \
+               .address = (_address), \
+               .extend_name = (_extend_name), \
+               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
+                       BIT(IIO_CHAN_INFO_OFFSET), \
+               .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
+               .info_mask_shared_by_type_available = (_mask_type_av), \
+               .info_mask_shared_by_all = _mask_all, \
+               .scan_index = (_si), \
+               .scan_type = { \
+                       .sign = 'u', \
+                       .realbits = (_bits), \
+                       .storagebits = (_storagebits), \
+                       .shift = (_shift), \
+                       .endianness = IIO_BE, \
+               }, \
+       }
+
+#define AD7793_DIFF_CHANNEL(_si, _channel1, _channel2, _address, _bits, \
+       _storagebits, _shift) \
+       __AD7793_CHANNEL(_si, _channel1, _channel2, _address, _bits, \
+               _storagebits, _shift, NULL, IIO_VOLTAGE, \
+               BIT(IIO_CHAN_INFO_SCALE), \
+               BIT(IIO_CHAN_INFO_SAMP_FREQ))
+
+#define AD7793_SHORTED_CHANNEL(_si, _channel, _address, _bits, \
+       _storagebits, _shift) \
+       __AD7793_CHANNEL(_si, _channel, _channel, _address, _bits, \
+               _storagebits, _shift, "shorted", IIO_VOLTAGE, \
+               BIT(IIO_CHAN_INFO_SCALE), \
+               BIT(IIO_CHAN_INFO_SAMP_FREQ))
+
+#define AD7793_TEMP_CHANNEL(_si, _address, _bits, _storagebits, _shift) \
+       __AD7793_CHANNEL(_si, 0, -1, _address, _bits, \
+               _storagebits, _shift, NULL, IIO_TEMP, \
+               0, \
+               BIT(IIO_CHAN_INFO_SAMP_FREQ))
+
+#define AD7793_SUPPLY_CHANNEL(_si, _channel, _address, _bits, _storagebits, \
+       _shift) \
+       __AD7793_CHANNEL(_si, _channel, -1, _address, _bits, \
+               _storagebits, _shift, "supply", IIO_VOLTAGE, \
+               0, \
+               BIT(IIO_CHAN_INFO_SAMP_FREQ))
+
+#define AD7797_DIFF_CHANNEL(_si, _channel1, _channel2, _address, _bits, \
+       _storagebits, _shift) \
+       __AD7793_CHANNEL(_si, _channel1, _channel2, _address, _bits, \
+               _storagebits, _shift, NULL, IIO_VOLTAGE, \
+               0, \
+               BIT(IIO_CHAN_INFO_SAMP_FREQ))
+
+#define AD7797_SHORTED_CHANNEL(_si, _channel, _address, _bits, \
+       _storagebits, _shift) \
+       __AD7793_CHANNEL(_si, _channel, _channel, _address, _bits, \
+               _storagebits, _shift, "shorted", IIO_VOLTAGE, \
+               0, \
+               BIT(IIO_CHAN_INFO_SAMP_FREQ))
+
 #define DECLARE_AD7793_CHANNELS(_name, _b, _sb, _s) \
 const struct iio_chan_spec _name##_channels[] = { \
-       AD_SD_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), (_s)), \
-       AD_SD_DIFF_CHANNEL(1, 1, 1, AD7793_CH_AIN2P_AIN2M, (_b), (_sb), (_s)), \
-       AD_SD_DIFF_CHANNEL(2, 2, 2, AD7793_CH_AIN3P_AIN3M, (_b), (_sb), (_s)), \
-       AD_SD_SHORTED_CHANNEL(3, 0, AD7793_CH_AIN1M_AIN1M, (_b), (_sb), (_s)), \
-       AD_SD_TEMP_CHANNEL(4, AD7793_CH_TEMP, (_b), (_sb), (_s)), \
-       AD_SD_SUPPLY_CHANNEL(5, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), (_s)), \
+       AD7793_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), (_s)), \
+       AD7793_DIFF_CHANNEL(1, 1, 1, AD7793_CH_AIN2P_AIN2M, (_b), (_sb), (_s)), \
+       AD7793_DIFF_CHANNEL(2, 2, 2, AD7793_CH_AIN3P_AIN3M, (_b), (_sb), (_s)), \
+       AD7793_SHORTED_CHANNEL(3, 0, AD7793_CH_AIN1M_AIN1M, (_b), (_sb), (_s)), \
+       AD7793_TEMP_CHANNEL(4, AD7793_CH_TEMP, (_b), (_sb), (_s)), \
+       AD7793_SUPPLY_CHANNEL(5, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), (_s)), \
        IIO_CHAN_SOFT_TIMESTAMP(6), \
 }
 
 #define DECLARE_AD7795_CHANNELS(_name, _b, _sb) \
 const struct iio_chan_spec _name##_channels[] = { \
-       AD_SD_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), 0), \
-       AD_SD_DIFF_CHANNEL(1, 1, 1, AD7793_CH_AIN2P_AIN2M, (_b), (_sb), 0), \
-       AD_SD_DIFF_CHANNEL(2, 2, 2, AD7793_CH_AIN3P_AIN3M, (_b), (_sb), 0), \
-       AD_SD_DIFF_CHANNEL(3, 3, 3, AD7795_CH_AIN4P_AIN4M, (_b), (_sb), 0), \
-       AD_SD_DIFF_CHANNEL(4, 4, 4, AD7795_CH_AIN5P_AIN5M, (_b), (_sb), 0), \
-       AD_SD_DIFF_CHANNEL(5, 5, 5, AD7795_CH_AIN6P_AIN6M, (_b), (_sb), 0), \
-       AD_SD_SHORTED_CHANNEL(6, 0, AD7795_CH_AIN1M_AIN1M, (_b), (_sb), 0), \
-       AD_SD_TEMP_CHANNEL(7, AD7793_CH_TEMP, (_b), (_sb), 0), \
-       AD_SD_SUPPLY_CHANNEL(8, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), 0), \
+       AD7793_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), 0), \
+       AD7793_DIFF_CHANNEL(1, 1, 1, AD7793_CH_AIN2P_AIN2M, (_b), (_sb), 0), \
+       AD7793_DIFF_CHANNEL(2, 2, 2, AD7793_CH_AIN3P_AIN3M, (_b), (_sb), 0), \
+       AD7793_DIFF_CHANNEL(3, 3, 3, AD7795_CH_AIN4P_AIN4M, (_b), (_sb), 0), \
+       AD7793_DIFF_CHANNEL(4, 4, 4, AD7795_CH_AIN5P_AIN5M, (_b), (_sb), 0), \
+       AD7793_DIFF_CHANNEL(5, 5, 5, AD7795_CH_AIN6P_AIN6M, (_b), (_sb), 0), \
+       AD7793_SHORTED_CHANNEL(6, 0, AD7795_CH_AIN1M_AIN1M, (_b), (_sb), 0), \
+       AD7793_TEMP_CHANNEL(7, AD7793_CH_TEMP, (_b), (_sb), 0), \
+       AD7793_SUPPLY_CHANNEL(8, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), 0), \
        IIO_CHAN_SOFT_TIMESTAMP(9), \
 }
 
 #define DECLARE_AD7797_CHANNELS(_name, _b, _sb) \
 const struct iio_chan_spec _name##_channels[] = { \
-       AD_SD_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), 0), \
-       AD_SD_SHORTED_CHANNEL(1, 0, AD7793_CH_AIN1M_AIN1M, (_b), (_sb), 0), \
-       AD_SD_TEMP_CHANNEL(2, AD7793_CH_TEMP, (_b), (_sb), 0), \
-       AD_SD_SUPPLY_CHANNEL(3, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), 0), \
+       AD7797_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), 0), \
+       AD7797_SHORTED_CHANNEL(1, 0, AD7793_CH_AIN1M_AIN1M, (_b), (_sb), 0), \
+       AD7793_TEMP_CHANNEL(2, AD7793_CH_TEMP, (_b), (_sb), 0), \
+       AD7793_SUPPLY_CHANNEL(3, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), 0), \
        IIO_CHAN_SOFT_TIMESTAMP(4), \
 }
 
 #define DECLARE_AD7799_CHANNELS(_name, _b, _sb) \
 const struct iio_chan_spec _name##_channels[] = { \
-       AD_SD_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), 0), \
-       AD_SD_DIFF_CHANNEL(1, 1, 1, AD7793_CH_AIN2P_AIN2M, (_b), (_sb), 0), \
-       AD_SD_DIFF_CHANNEL(2, 2, 2, AD7793_CH_AIN3P_AIN3M, (_b), (_sb), 0), \
-       AD_SD_SHORTED_CHANNEL(3, 0, AD7793_CH_AIN1M_AIN1M, (_b), (_sb), 0), \
-       AD_SD_SUPPLY_CHANNEL(4, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), 0), \
+       AD7793_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), 0), \
+       AD7793_DIFF_CHANNEL(1, 1, 1, AD7793_CH_AIN2P_AIN2M, (_b), (_sb), 0), \
+       AD7793_DIFF_CHANNEL(2, 2, 2, AD7793_CH_AIN3P_AIN3M, (_b), (_sb), 0), \
+       AD7793_SHORTED_CHANNEL(3, 0, AD7793_CH_AIN1M_AIN1M, (_b), (_sb), 0), \
+       AD7793_SUPPLY_CHANNEL(4, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), 0), \
        IIO_CHAN_SOFT_TIMESTAMP(5), \
 }
 
diff --git a/drivers/iio/adc/ad9467.c b/drivers/iio/adc/ad9467.c
new file mode 100644 (file)
index 0000000..1e8fd83
--- /dev/null
@@ -0,0 +1,422 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Analog Devices AD9467 SPI ADC driver
+ *
+ * Copyright 2012-2020 Analog Devices Inc.
+ */
+
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/spi/spi.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/of_device.h>
+
+
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+
+#include <linux/clk.h>
+
+#include <linux/iio/adc/adi-axi-adc.h>
+
+/*
+ * ADI High-Speed ADC common spi interface registers
+ * See Application-Note AN-877:
+ *   https://www.analog.com/media/en/technical-documentation/application-notes/AN-877.pdf
+ */
+
+#define AN877_ADC_REG_CHIP_PORT_CONF           0x00
+#define AN877_ADC_REG_CHIP_ID                  0x01
+#define AN877_ADC_REG_CHIP_GRADE               0x02
+#define AN877_ADC_REG_CHAN_INDEX               0x05
+#define AN877_ADC_REG_TRANSFER                 0xFF
+#define AN877_ADC_REG_MODES                    0x08
+#define AN877_ADC_REG_TEST_IO                  0x0D
+#define AN877_ADC_REG_ADC_INPUT                        0x0F
+#define AN877_ADC_REG_OFFSET                   0x10
+#define AN877_ADC_REG_OUTPUT_MODE              0x14
+#define AN877_ADC_REG_OUTPUT_ADJUST            0x15
+#define AN877_ADC_REG_OUTPUT_PHASE             0x16
+#define AN877_ADC_REG_OUTPUT_DELAY             0x17
+#define AN877_ADC_REG_VREF                     0x18
+#define AN877_ADC_REG_ANALOG_INPUT             0x2C
+
+/* AN877_ADC_REG_TEST_IO */
+#define AN877_ADC_TESTMODE_OFF                 0x0
+#define AN877_ADC_TESTMODE_MIDSCALE_SHORT      0x1
+#define AN877_ADC_TESTMODE_POS_FULLSCALE       0x2
+#define AN877_ADC_TESTMODE_NEG_FULLSCALE       0x3
+#define AN877_ADC_TESTMODE_ALT_CHECKERBOARD    0x4
+#define AN877_ADC_TESTMODE_PN23_SEQ            0x5
+#define AN877_ADC_TESTMODE_PN9_SEQ             0x6
+#define AN877_ADC_TESTMODE_ONE_ZERO_TOGGLE     0x7
+#define AN877_ADC_TESTMODE_USER                        0x8
+#define AN877_ADC_TESTMODE_BIT_TOGGLE          0x9
+#define AN877_ADC_TESTMODE_SYNC                        0xA
+#define AN877_ADC_TESTMODE_ONE_BIT_HIGH                0xB
+#define AN877_ADC_TESTMODE_MIXED_BIT_FREQUENCY 0xC
+#define AN877_ADC_TESTMODE_RAMP                        0xF
+
+/* AN877_ADC_REG_TRANSFER */
+#define AN877_ADC_TRANSFER_SYNC                        0x1
+
+/* AN877_ADC_REG_OUTPUT_MODE */
+#define AN877_ADC_OUTPUT_MODE_OFFSET_BINARY    0x0
+#define AN877_ADC_OUTPUT_MODE_TWOS_COMPLEMENT  0x1
+#define AN877_ADC_OUTPUT_MODE_GRAY_CODE                0x2
+
+/* AN877_ADC_REG_OUTPUT_PHASE */
+#define AN877_ADC_OUTPUT_EVEN_ODD_MODE_EN      0x20
+#define AN877_ADC_INVERT_DCO_CLK               0x80
+
+/* AN877_ADC_REG_OUTPUT_DELAY */
+#define AN877_ADC_DCO_DELAY_ENABLE             0x80
+
+/*
+ * Analog Devices AD9467 16-Bit, 200/250 MSPS ADC
+ */
+
+#define CHIPID_AD9467                  0x50
+#define AD9467_DEF_OUTPUT_MODE         0x08
+#define AD9467_REG_VREF_MASK           0x0F
+
+enum {
+       ID_AD9467,
+};
+
+struct ad9467_state {
+       struct spi_device               *spi;
+       struct clk                      *clk;
+       unsigned int                    output_mode;
+
+       struct gpio_desc                *pwrdown_gpio;
+       struct gpio_desc                *reset_gpio;
+};
+
+static int ad9467_spi_read(struct spi_device *spi, unsigned int reg)
+{
+       unsigned char tbuf[2], rbuf[1];
+       int ret;
+
+       tbuf[0] = 0x80 | (reg >> 8);
+       tbuf[1] = reg & 0xFF;
+
+       ret = spi_write_then_read(spi,
+                                 tbuf, ARRAY_SIZE(tbuf),
+                                 rbuf, ARRAY_SIZE(rbuf));
+
+       if (ret < 0)
+               return ret;
+
+       return rbuf[0];
+}
+
+static int ad9467_spi_write(struct spi_device *spi, unsigned int reg,
+                           unsigned int val)
+{
+       unsigned char buf[3];
+
+       buf[0] = reg >> 8;
+       buf[1] = reg & 0xFF;
+       buf[2] = val;
+
+       return spi_write(spi, buf, ARRAY_SIZE(buf));
+}
+
+static int ad9467_reg_access(struct adi_axi_adc_conv *conv, unsigned int reg,
+                            unsigned int writeval, unsigned int *readval)
+{
+       struct ad9467_state *st = adi_axi_adc_conv_priv(conv);
+       struct spi_device *spi = st->spi;
+       int ret;
+
+       if (readval == NULL) {
+               ret = ad9467_spi_write(spi, reg, writeval);
+               ad9467_spi_write(spi, AN877_ADC_REG_TRANSFER,
+                                AN877_ADC_TRANSFER_SYNC);
+               return ret;
+       }
+
+       ret = ad9467_spi_read(spi, reg);
+       if (ret < 0)
+               return ret;
+       *readval = ret;
+
+       return 0;
+}
+
+static const unsigned int ad9467_scale_table[][2] = {
+       {2000, 0}, {2100, 6}, {2200, 7},
+       {2300, 8}, {2400, 9}, {2500, 10},
+};
+
+static void __ad9467_get_scale(struct adi_axi_adc_conv *conv, int index,
+                              unsigned int *val, unsigned int *val2)
+{
+       const struct adi_axi_adc_chip_info *info = conv->chip_info;
+       const struct iio_chan_spec *chan = &info->channels[0];
+       unsigned int tmp;
+
+       tmp = (info->scale_table[index][0] * 1000000ULL) >>
+                       chan->scan_type.realbits;
+       *val = tmp / 1000000;
+       *val2 = tmp % 1000000;
+}
+
+#define AD9467_CHAN(_chan, _si, _bits, _sign)                          \
+{                                                                      \
+       .type = IIO_VOLTAGE,                                            \
+       .indexed = 1,                                                   \
+       .channel = _chan,                                               \
+       .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |          \
+               BIT(IIO_CHAN_INFO_SAMP_FREQ),                           \
+       .scan_index = _si,                                              \
+       .scan_type = {                                                  \
+               .sign = _sign,                                          \
+               .realbits = _bits,                                      \
+               .storagebits = 16,                                      \
+       },                                                              \
+}
+
+static const struct iio_chan_spec ad9467_channels[] = {
+       AD9467_CHAN(0, 0, 16, 'S'),
+};
+
+static const struct adi_axi_adc_chip_info ad9467_chip_tbl[] = {
+       [ID_AD9467] = {
+               .id = CHIPID_AD9467,
+               .max_rate = 250000000UL,
+               .scale_table = ad9467_scale_table,
+               .num_scales = ARRAY_SIZE(ad9467_scale_table),
+               .channels = ad9467_channels,
+               .num_channels = ARRAY_SIZE(ad9467_channels),
+       },
+};
+
+static int ad9467_get_scale(struct adi_axi_adc_conv *conv, int *val, int *val2)
+{
+       const struct adi_axi_adc_chip_info *info = conv->chip_info;
+       struct ad9467_state *st = adi_axi_adc_conv_priv(conv);
+       unsigned int i, vref_val, vref_mask;
+
+       vref_val = ad9467_spi_read(st->spi, AN877_ADC_REG_VREF);
+
+       switch (info->id) {
+       case CHIPID_AD9467:
+               vref_mask = AD9467_REG_VREF_MASK;
+               break;
+       default:
+               vref_mask = 0xFFFF;
+               break;
+       }
+
+       vref_val &= vref_mask;
+
+       for (i = 0; i < info->num_scales; i++) {
+               if (vref_val == info->scale_table[i][1])
+                       break;
+       }
+
+       if (i == info->num_scales)
+               return -ERANGE;
+
+       __ad9467_get_scale(conv, i, val, val2);
+
+       return IIO_VAL_INT_PLUS_MICRO;
+}
+
+static int ad9467_set_scale(struct adi_axi_adc_conv *conv, int val, int val2)
+{
+       const struct adi_axi_adc_chip_info *info = conv->chip_info;
+       struct ad9467_state *st = adi_axi_adc_conv_priv(conv);
+       unsigned int scale_val[2];
+       unsigned int i;
+
+       if (val != 0)
+               return -EINVAL;
+
+       for (i = 0; i < info->num_scales; i++) {
+               __ad9467_get_scale(conv, i, &scale_val[0], &scale_val[1]);
+               if (scale_val[0] != val || scale_val[1] != val2)
+                       continue;
+
+               ad9467_spi_write(st->spi, AN877_ADC_REG_VREF,
+                                info->scale_table[i][1]);
+               ad9467_spi_write(st->spi, AN877_ADC_REG_TRANSFER,
+                                AN877_ADC_TRANSFER_SYNC);
+               return 0;
+       }
+
+       return -EINVAL;
+}
+
+static int ad9467_read_raw(struct adi_axi_adc_conv *conv,
+                          struct iio_chan_spec const *chan,
+                          int *val, int *val2, long m)
+{
+       struct ad9467_state *st = adi_axi_adc_conv_priv(conv);
+
+       switch (m) {
+       case IIO_CHAN_INFO_SCALE:
+               return ad9467_get_scale(conv, val, val2);
+       case IIO_CHAN_INFO_SAMP_FREQ:
+               *val = clk_get_rate(st->clk);
+
+               return IIO_VAL_INT;
+       default:
+               return -EINVAL;
+       }
+}
+
+static int ad9467_write_raw(struct adi_axi_adc_conv *conv,
+                           struct iio_chan_spec const *chan,
+                           int val, int val2, long mask)
+{
+       const struct adi_axi_adc_chip_info *info = conv->chip_info;
+       struct ad9467_state *st = adi_axi_adc_conv_priv(conv);
+       long r_clk;
+
+       switch (mask) {
+       case IIO_CHAN_INFO_SCALE:
+               return ad9467_set_scale(conv, val, val2);
+       case IIO_CHAN_INFO_SAMP_FREQ:
+               r_clk = clk_round_rate(st->clk, val);
+               if (r_clk < 0 || r_clk > info->max_rate) {
+                       dev_warn(&st->spi->dev,
+                                "Error setting ADC sample rate %ld", r_clk);
+                       return -EINVAL;
+               }
+
+               return clk_set_rate(st->clk, r_clk);
+       default:
+               return -EINVAL;
+       }
+}
+
+static int ad9467_outputmode_set(struct spi_device *spi, unsigned int mode)
+{
+       int ret;
+
+       ret = ad9467_spi_write(spi, AN877_ADC_REG_OUTPUT_MODE, mode);
+       if (ret < 0)
+               return ret;
+
+       return ad9467_spi_write(spi, AN877_ADC_REG_TRANSFER,
+                               AN877_ADC_TRANSFER_SYNC);
+}
+
+static int ad9467_preenable_setup(struct adi_axi_adc_conv *conv)
+{
+       struct ad9467_state *st = adi_axi_adc_conv_priv(conv);
+
+       return ad9467_outputmode_set(st->spi, st->output_mode);
+}
+
+static int ad9467_setup(struct ad9467_state *st, unsigned int chip_id)
+{
+       switch (chip_id) {
+       case CHIPID_AD9467:
+               st->output_mode = AD9467_DEF_OUTPUT_MODE |
+                                 AN877_ADC_OUTPUT_MODE_TWOS_COMPLEMENT;
+               return 0;
+       default:
+               return -EINVAL;
+       }
+}
+
+static void ad9467_clk_disable(void *data)
+{
+       struct ad9467_state *st = data;
+
+       clk_disable_unprepare(st->clk);
+}
+
+static int ad9467_probe(struct spi_device *spi)
+{
+       const struct adi_axi_adc_chip_info *info;
+       struct adi_axi_adc_conv *conv;
+       struct ad9467_state *st;
+       unsigned int id;
+       int ret;
+
+       info = of_device_get_match_data(&spi->dev);
+       if (!info)
+               return -ENODEV;
+
+       conv = devm_adi_axi_adc_conv_register(&spi->dev, sizeof(*st));
+       if (IS_ERR(conv))
+               return PTR_ERR(conv);
+
+       st = adi_axi_adc_conv_priv(conv);
+       st->spi = spi;
+
+       st->clk = devm_clk_get(&spi->dev, "adc-clk");
+       if (IS_ERR(st->clk))
+               return PTR_ERR(st->clk);
+
+       ret = clk_prepare_enable(st->clk);
+       if (ret < 0)
+               return ret;
+
+       ret = devm_add_action_or_reset(&spi->dev, ad9467_clk_disable, st);
+       if (ret)
+               return ret;
+
+       st->pwrdown_gpio = devm_gpiod_get_optional(&spi->dev, "powerdown",
+                                                  GPIOD_OUT_LOW);
+       if (IS_ERR(st->pwrdown_gpio))
+               return PTR_ERR(st->pwrdown_gpio);
+
+       st->reset_gpio = devm_gpiod_get_optional(&spi->dev, "reset",
+                                                GPIOD_OUT_LOW);
+       if (IS_ERR(st->reset_gpio))
+               return PTR_ERR(st->reset_gpio);
+
+       if (st->reset_gpio) {
+               udelay(1);
+               ret = gpiod_direction_output(st->reset_gpio, 1);
+               if (ret)
+                       return ret;
+               mdelay(10);
+       }
+
+       spi_set_drvdata(spi, st);
+
+       conv->chip_info = info;
+
+       id = ad9467_spi_read(spi, AN877_ADC_REG_CHIP_ID);
+       if (id != conv->chip_info->id) {
+               dev_err(&spi->dev, "Unrecognized CHIP_ID 0x%X\n", id);
+               return -ENODEV;
+       }
+
+       conv->reg_access = ad9467_reg_access;
+       conv->write_raw = ad9467_write_raw;
+       conv->read_raw = ad9467_read_raw;
+       conv->preenable_setup = ad9467_preenable_setup;
+
+       return ad9467_setup(st, id);
+}
+
+static const struct of_device_id ad9467_of_match[] = {
+       { .compatible = "adi,ad9467", .data = &ad9467_chip_tbl[ID_AD9467], },
+       {}
+};
+MODULE_DEVICE_TABLE(of, ad9467_of_match);
+
+static struct spi_driver ad9467_driver = {
+       .driver = {
+               .name = "ad9467",
+               .of_match_table = ad9467_of_match,
+       },
+       .probe = ad9467_probe,
+};
+module_spi_driver(ad9467_driver);
+
+MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>");
+MODULE_DESCRIPTION("Analog Devices AD9467 ADC driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/adc/adi-axi-adc.c b/drivers/iio/adc/adi-axi-adc.c
new file mode 100644 (file)
index 0000000..c24c8da
--- /dev/null
@@ -0,0 +1,482 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Analog Devices Generic AXI ADC IP core
+ * Link: https://wiki.analog.com/resources/fpga/docs/axi_adc_ip
+ *
+ * Copyright 2012-2020 Analog Devices Inc.
+ */
+
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/buffer-dmaengine.h>
+
+#include <linux/fpga/adi-axi-common.h>
+#include <linux/iio/adc/adi-axi-adc.h>
+
+/**
+ * Register definitions:
+ *   https://wiki.analog.com/resources/fpga/docs/axi_adc_ip#register_map
+ */
+
+/* ADC controls */
+
+#define ADI_AXI_REG_RSTN                       0x0040
+#define   ADI_AXI_REG_RSTN_CE_N                        BIT(2)
+#define   ADI_AXI_REG_RSTN_MMCM_RSTN           BIT(1)
+#define   ADI_AXI_REG_RSTN_RSTN                        BIT(0)
+
+/* ADC Channel controls */
+
+#define ADI_AXI_REG_CHAN_CTRL(c)               (0x0400 + (c) * 0x40)
+#define   ADI_AXI_REG_CHAN_CTRL_LB_OWR         BIT(11)
+#define   ADI_AXI_REG_CHAN_CTRL_PN_SEL_OWR     BIT(10)
+#define   ADI_AXI_REG_CHAN_CTRL_IQCOR_EN       BIT(9)
+#define   ADI_AXI_REG_CHAN_CTRL_DCFILT_EN      BIT(8)
+#define   ADI_AXI_REG_CHAN_CTRL_FMT_SIGNEXT    BIT(6)
+#define   ADI_AXI_REG_CHAN_CTRL_FMT_TYPE       BIT(5)
+#define   ADI_AXI_REG_CHAN_CTRL_FMT_EN         BIT(4)
+#define   ADI_AXI_REG_CHAN_CTRL_PN_TYPE_OWR    BIT(1)
+#define   ADI_AXI_REG_CHAN_CTRL_ENABLE         BIT(0)
+
+#define ADI_AXI_REG_CHAN_CTRL_DEFAULTS         \
+       (ADI_AXI_REG_CHAN_CTRL_FMT_SIGNEXT |    \
+        ADI_AXI_REG_CHAN_CTRL_FMT_EN |         \
+        ADI_AXI_REG_CHAN_CTRL_ENABLE)
+
+struct adi_axi_adc_core_info {
+       unsigned int                            version;
+};
+
+struct adi_axi_adc_state {
+       struct mutex                            lock;
+
+       struct adi_axi_adc_client               *client;
+       void __iomem                            *regs;
+};
+
+struct adi_axi_adc_client {
+       struct list_head                        entry;
+       struct adi_axi_adc_conv                 conv;
+       struct adi_axi_adc_state                *state;
+       struct device                           *dev;
+       const struct adi_axi_adc_core_info      *info;
+};
+
+static LIST_HEAD(registered_clients);
+static DEFINE_MUTEX(registered_clients_lock);
+
+static struct adi_axi_adc_client *conv_to_client(struct adi_axi_adc_conv *conv)
+{
+       return container_of(conv, struct adi_axi_adc_client, conv);
+}
+
+void *adi_axi_adc_conv_priv(struct adi_axi_adc_conv *conv)
+{
+       struct adi_axi_adc_client *cl = conv_to_client(conv);
+
+       return (char *)cl + ALIGN(sizeof(struct adi_axi_adc_client), IIO_ALIGN);
+}
+EXPORT_SYMBOL_GPL(adi_axi_adc_conv_priv);
+
+static void adi_axi_adc_write(struct adi_axi_adc_state *st,
+                             unsigned int reg,
+                             unsigned int val)
+{
+       iowrite32(val, st->regs + reg);
+}
+
+static unsigned int adi_axi_adc_read(struct adi_axi_adc_state *st,
+                                    unsigned int reg)
+{
+       return ioread32(st->regs + reg);
+}
+
+static int adi_axi_adc_config_dma_buffer(struct device *dev,
+                                        struct iio_dev *indio_dev)
+{
+       struct iio_buffer *buffer;
+       const char *dma_name;
+
+       if (!device_property_present(dev, "dmas"))
+               return 0;
+
+       if (device_property_read_string(dev, "dma-names", &dma_name))
+               dma_name = "rx";
+
+       buffer = devm_iio_dmaengine_buffer_alloc(indio_dev->dev.parent,
+                                                dma_name);
+       if (IS_ERR(buffer))
+               return PTR_ERR(buffer);
+
+       indio_dev->modes |= INDIO_BUFFER_HARDWARE;
+       iio_device_attach_buffer(indio_dev, buffer);
+
+       return 0;
+}
+
+static int adi_axi_adc_read_raw(struct iio_dev *indio_dev,
+                               struct iio_chan_spec const *chan,
+                               int *val, int *val2, long mask)
+{
+       struct adi_axi_adc_state *st = iio_priv(indio_dev);
+       struct adi_axi_adc_conv *conv = &st->client->conv;
+
+       if (!conv->read_raw)
+               return -EOPNOTSUPP;
+
+       return conv->read_raw(conv, chan, val, val2, mask);
+}
+
+static int adi_axi_adc_write_raw(struct iio_dev *indio_dev,
+                                struct iio_chan_spec const *chan,
+                                int val, int val2, long mask)
+{
+       struct adi_axi_adc_state *st = iio_priv(indio_dev);
+       struct adi_axi_adc_conv *conv = &st->client->conv;
+
+       if (!conv->write_raw)
+               return -EOPNOTSUPP;
+
+       return conv->write_raw(conv, chan, val, val2, mask);
+}
+
+static int adi_axi_adc_update_scan_mode(struct iio_dev *indio_dev,
+                                       const unsigned long *scan_mask)
+{
+       struct adi_axi_adc_state *st = iio_priv(indio_dev);
+       struct adi_axi_adc_conv *conv = &st->client->conv;
+       unsigned int i, ctrl;
+
+       for (i = 0; i < conv->chip_info->num_channels; i++) {
+               ctrl = adi_axi_adc_read(st, ADI_AXI_REG_CHAN_CTRL(i));
+
+               if (test_bit(i, scan_mask))
+                       ctrl |= ADI_AXI_REG_CHAN_CTRL_ENABLE;
+               else
+                       ctrl &= ~ADI_AXI_REG_CHAN_CTRL_ENABLE;
+
+               adi_axi_adc_write(st, ADI_AXI_REG_CHAN_CTRL(i), ctrl);
+       }
+
+       return 0;
+}
+
+static struct adi_axi_adc_conv *adi_axi_adc_conv_register(struct device *dev,
+                                                         size_t sizeof_priv)
+{
+       struct adi_axi_adc_client *cl;
+       size_t alloc_size;
+
+       alloc_size = ALIGN(sizeof(struct adi_axi_adc_client), IIO_ALIGN);
+       if (sizeof_priv)
+               alloc_size += ALIGN(sizeof_priv, IIO_ALIGN);
+
+       cl = kzalloc(alloc_size, GFP_KERNEL);
+       if (!cl)
+               return ERR_PTR(-ENOMEM);
+
+       mutex_lock(&registered_clients_lock);
+
+       cl->dev = get_device(dev);
+
+       list_add_tail(&cl->entry, &registered_clients);
+
+       mutex_unlock(&registered_clients_lock);
+
+       return &cl->conv;
+}
+
+static void adi_axi_adc_conv_unregister(struct adi_axi_adc_conv *conv)
+{
+       struct adi_axi_adc_client *cl = conv_to_client(conv);
+
+       mutex_lock(&registered_clients_lock);
+
+       list_del(&cl->entry);
+       put_device(cl->dev);
+
+       mutex_unlock(&registered_clients_lock);
+
+       kfree(cl);
+}
+
+static void devm_adi_axi_adc_conv_release(struct device *dev, void *res)
+{
+       adi_axi_adc_conv_unregister(*(struct adi_axi_adc_conv **)res);
+}
+
+struct adi_axi_adc_conv *devm_adi_axi_adc_conv_register(struct device *dev,
+                                                       size_t sizeof_priv)
+{
+       struct adi_axi_adc_conv **ptr, *conv;
+
+       ptr = devres_alloc(devm_adi_axi_adc_conv_release, sizeof(*ptr),
+                          GFP_KERNEL);
+       if (!ptr)
+               return ERR_PTR(-ENOMEM);
+
+       conv = adi_axi_adc_conv_register(dev, sizeof_priv);
+       if (IS_ERR(conv)) {
+               devres_free(ptr);
+               return ERR_CAST(conv);
+       }
+
+       *ptr = conv;
+       devres_add(dev, ptr);
+
+       return conv;
+}
+EXPORT_SYMBOL_GPL(devm_adi_axi_adc_conv_register);
+
+static ssize_t in_voltage_scale_available_show(struct device *dev,
+                                              struct device_attribute *attr,
+                                              char *buf)
+{
+       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+       struct adi_axi_adc_state *st = iio_priv(indio_dev);
+       struct adi_axi_adc_conv *conv = &st->client->conv;
+       size_t len = 0;
+       int i;
+
+       for (i = 0; i < conv->chip_info->num_scales; i++) {
+               const unsigned int *s = conv->chip_info->scale_table[i];
+
+               len += scnprintf(buf + len, PAGE_SIZE - len,
+                                "%u.%06u ", s[0], s[1]);
+       }
+       buf[len - 1] = '\n';
+
+       return len;
+}
+
+static IIO_DEVICE_ATTR_RO(in_voltage_scale_available, 0);
+
+enum {
+       ADI_AXI_ATTR_SCALE_AVAIL,
+};
+
+#define ADI_AXI_ATTR(_en_, _file_)                     \
+       [ADI_AXI_ATTR_##_en_] = &iio_dev_attr_##_file_.dev_attr.attr
+
+static struct attribute *adi_axi_adc_attributes[] = {
+       ADI_AXI_ATTR(SCALE_AVAIL, in_voltage_scale_available),
+       NULL
+};
+
+static umode_t axi_adc_attr_is_visible(struct kobject *kobj,
+                                      struct attribute *attr, int n)
+{
+       struct device *dev = container_of(kobj, struct device, kobj);
+       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+       struct adi_axi_adc_state *st = iio_priv(indio_dev);
+       struct adi_axi_adc_conv *conv = &st->client->conv;
+
+       switch (n) {
+       case ADI_AXI_ATTR_SCALE_AVAIL:
+               if (!conv->chip_info->num_scales)
+                       return 0;
+               return attr->mode;
+       default:
+               return attr->mode;
+       }
+}
+
+static const struct attribute_group adi_axi_adc_attribute_group = {
+       .attrs = adi_axi_adc_attributes,
+       .is_visible = axi_adc_attr_is_visible,
+};
+
+static const struct iio_info adi_axi_adc_info = {
+       .read_raw = &adi_axi_adc_read_raw,
+       .write_raw = &adi_axi_adc_write_raw,
+       .attrs = &adi_axi_adc_attribute_group,
+       .update_scan_mode = &adi_axi_adc_update_scan_mode,
+};
+
+static const struct adi_axi_adc_core_info adi_axi_adc_10_0_a_info = {
+       .version = ADI_AXI_PCORE_VER(10, 0, 'a'),
+};
+
+static struct adi_axi_adc_client *adi_axi_adc_attach_client(struct device *dev)
+{
+       const struct adi_axi_adc_core_info *info;
+       struct adi_axi_adc_client *cl;
+       struct device_node *cln;
+
+       info = of_device_get_match_data(dev);
+       if (!info)
+               return ERR_PTR(-ENODEV);
+
+       cln = of_parse_phandle(dev->of_node, "adi,adc-dev", 0);
+       if (!cln) {
+               dev_err(dev, "No 'adi,adc-dev' node defined\n");
+               return ERR_PTR(-ENODEV);
+       }
+
+       mutex_lock(&registered_clients_lock);
+
+       list_for_each_entry(cl, &registered_clients, entry) {
+               if (!cl->dev)
+                       continue;
+
+               if (cl->dev->of_node != cln)
+                       continue;
+
+               if (!try_module_get(dev->driver->owner)) {
+                       mutex_unlock(&registered_clients_lock);
+                       return ERR_PTR(-ENODEV);
+               }
+
+               get_device(dev);
+               cl->info = info;
+               mutex_unlock(&registered_clients_lock);
+               return cl;
+       }
+
+       mutex_unlock(&registered_clients_lock);
+
+       return ERR_PTR(-EPROBE_DEFER);
+}
+
+static int adi_axi_adc_setup_channels(struct device *dev,
+                                     struct adi_axi_adc_state *st)
+{
+       struct adi_axi_adc_conv *conv = &st->client->conv;
+       int i, ret;
+
+       if (conv->preenable_setup) {
+               ret = conv->preenable_setup(conv);
+               if (ret)
+                       return ret;
+       }
+
+       for (i = 0; i < conv->chip_info->num_channels; i++) {
+               adi_axi_adc_write(st, ADI_AXI_REG_CHAN_CTRL(i),
+                                 ADI_AXI_REG_CHAN_CTRL_DEFAULTS);
+       }
+
+       return 0;
+}
+
+static void axi_adc_reset(struct adi_axi_adc_state *st)
+{
+       adi_axi_adc_write(st, ADI_AXI_REG_RSTN, 0);
+       mdelay(10);
+       adi_axi_adc_write(st, ADI_AXI_REG_RSTN, ADI_AXI_REG_RSTN_MMCM_RSTN);
+       mdelay(10);
+       adi_axi_adc_write(st, ADI_AXI_REG_RSTN,
+                         ADI_AXI_REG_RSTN_RSTN | ADI_AXI_REG_RSTN_MMCM_RSTN);
+}
+
+static void adi_axi_adc_cleanup(void *data)
+{
+       struct adi_axi_adc_client *cl = data;
+
+       put_device(cl->dev);
+       module_put(cl->dev->driver->owner);
+}
+
+static int adi_axi_adc_probe(struct platform_device *pdev)
+{
+       struct adi_axi_adc_conv *conv;
+       struct iio_dev *indio_dev;
+       struct adi_axi_adc_client *cl;
+       struct adi_axi_adc_state *st;
+       unsigned int ver;
+       int ret;
+
+       cl = adi_axi_adc_attach_client(&pdev->dev);
+       if (IS_ERR(cl))
+               return PTR_ERR(cl);
+
+       ret = devm_add_action_or_reset(&pdev->dev, adi_axi_adc_cleanup, cl);
+       if (ret)
+               return ret;
+
+       indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*st));
+       if (indio_dev == NULL)
+               return -ENOMEM;
+
+       st = iio_priv(indio_dev);
+       st->client = cl;
+       cl->state = st;
+       mutex_init(&st->lock);
+
+       st->regs = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(st->regs))
+               return PTR_ERR(st->regs);
+
+       conv = &st->client->conv;
+
+       axi_adc_reset(st);
+
+       ver = adi_axi_adc_read(st, ADI_AXI_REG_VERSION);
+
+       if (cl->info->version > ver) {
+               dev_err(&pdev->dev,
+                       "IP core version is too old. Expected %d.%.2d.%c, Reported %d.%.2d.%c\n",
+                       ADI_AXI_PCORE_VER_MAJOR(cl->info->version),
+                       ADI_AXI_PCORE_VER_MINOR(cl->info->version),
+                       ADI_AXI_PCORE_VER_PATCH(cl->info->version),
+                       ADI_AXI_PCORE_VER_MAJOR(ver),
+                       ADI_AXI_PCORE_VER_MINOR(ver),
+                       ADI_AXI_PCORE_VER_PATCH(ver));
+               return -ENODEV;
+       }
+
+       indio_dev->info = &adi_axi_adc_info;
+       indio_dev->dev.parent = &pdev->dev;
+       indio_dev->name = "adi-axi-adc";
+       indio_dev->modes = INDIO_DIRECT_MODE;
+       indio_dev->num_channels = conv->chip_info->num_channels;
+       indio_dev->channels = conv->chip_info->channels;
+
+       ret = adi_axi_adc_config_dma_buffer(&pdev->dev, indio_dev);
+       if (ret)
+               return ret;
+
+       ret = adi_axi_adc_setup_channels(&pdev->dev, st);
+       if (ret)
+               return ret;
+
+       ret = devm_iio_device_register(&pdev->dev, indio_dev);
+       if (ret)
+               return ret;
+
+       dev_info(&pdev->dev, "AXI ADC IP core (%d.%.2d.%c) probed\n",
+                ADI_AXI_PCORE_VER_MAJOR(ver),
+                ADI_AXI_PCORE_VER_MINOR(ver),
+                ADI_AXI_PCORE_VER_PATCH(ver));
+
+       return 0;
+}
+
+/* Match table for of_platform binding */
+static const struct of_device_id adi_axi_adc_of_match[] = {
+       { .compatible = "adi,axi-adc-10.0.a", .data = &adi_axi_adc_10_0_a_info },
+       { /* end of list */ }
+};
+MODULE_DEVICE_TABLE(of, adi_axi_adc_of_match);
+
+static struct platform_driver adi_axi_adc_driver = {
+       .driver = {
+               .name = KBUILD_MODNAME,
+               .of_match_table = adi_axi_adc_of_match,
+       },
+       .probe = adi_axi_adc_probe,
+};
+module_platform_driver(adi_axi_adc_driver);
+
+MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>");
+MODULE_DESCRIPTION("Analog Devices Generic AXI ADC IP core driver");
+MODULE_LICENSE("GPL v2");
index abe99856c823ab6250bbfdedea447dcb337389d3..0368b6dc6d60a9a1439a31efcfacdde5e163887b 100644 (file)
@@ -1152,7 +1152,6 @@ static int at91_adc_probe(struct platform_device *pdev)
        int ret;
        struct iio_dev *idev;
        struct at91_adc_state *st;
-       struct resource *res;
        u32 reg;
 
        idev = devm_iio_device_alloc(&pdev->dev, sizeof(struct at91_adc_state));
@@ -1182,9 +1181,7 @@ static int at91_adc_probe(struct platform_device *pdev)
        if (st->irq < 0)
                return -ENODEV;
 
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-
-       st->reg_base = devm_ioremap_resource(&pdev->dev, res);
+       st->reg_base = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(st->reg_base))
                return PTR_ERR(st->reg_base);
 
index fa71489195c64b8a0480bb3f6d4cff202c69b67a..b0a4dc88ba9b99155d7b546917082efb73e9c2ec 100644 (file)
@@ -294,7 +294,6 @@ static int mx25_gcq_probe(struct platform_device *pdev)
        struct mx25_gcq_priv *priv;
        struct mx25_tsadc *tsadc = dev_get_drvdata(pdev->dev.parent);
        struct device *dev = &pdev->dev;
-       struct resource *res;
        void __iomem *mem;
        int ret;
        int i;
@@ -305,8 +304,7 @@ static int mx25_gcq_probe(struct platform_device *pdev)
 
        priv = iio_priv(indio_dev);
 
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       mem = devm_ioremap_resource(dev, res);
+       mem = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(mem))
                return PTR_ERR(mem);
 
index c35a1beb817c242a0f1cc3d591e848ba15da2b31..a6d2e1f27e76b085cf221d95348ae29230347dcb 100644 (file)
@@ -75,7 +75,7 @@ static int mrfld_adc_single_conv(struct iio_dev *indio_dev,
        struct regmap *regmap = adc->regmap;
        unsigned int req;
        long timeout;
-       u8 buf[2];
+       __be16 value;
        int ret;
 
        reinit_completion(&adc->completion);
@@ -105,11 +105,11 @@ static int mrfld_adc_single_conv(struct iio_dev *indio_dev,
                goto done;
        }
 
-       ret = regmap_bulk_read(regmap, chan->address, buf, 2);
+       ret = regmap_bulk_read(regmap, chan->address, &value, sizeof(value));
        if (ret)
                goto done;
 
-       *result = get_unaligned_be16(buf);
+       *result = be16_to_cpu(value);
        ret = IIO_VAL_INT;
 
 done:
diff --git a/drivers/iio/adc/max1241.c b/drivers/iio/adc/max1241.c
new file mode 100644 (file)
index 0000000..541939c
--- /dev/null
@@ -0,0 +1,227 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * MAX1241 low-power, 12-bit serial ADC
+ *
+ * Datasheet: https://datasheets.maximintegrated.com/en/ds/MAX1240-MAX1241.pdf
+ */
+
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/iio/iio.h>
+#include <linux/module.h>
+#include <linux/regulator/consumer.h>
+#include <linux/spi/spi.h>
+
+#define MAX1241_VAL_MASK GENMASK(11, 0)
+#define MAX1241_SHUTDOWN_DELAY_USEC 4
+
+enum max1241_id {
+       max1241,
+};
+
+struct max1241 {
+       struct spi_device *spi;
+       struct mutex lock;
+       struct regulator *vdd;
+       struct regulator *vref;
+       struct gpio_desc *shutdown;
+
+       __be16 data ____cacheline_aligned;
+};
+
+static const struct iio_chan_spec max1241_channels[] = {
+       {
+               .type = IIO_VOLTAGE,
+               .indexed = 1,
+               .channel = 0,
+               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+                               BIT(IIO_CHAN_INFO_SCALE),
+       },
+};
+
+static int max1241_read(struct max1241 *adc)
+{
+       struct spi_transfer xfers[] = {
+               /*
+                * Begin conversion by bringing /CS low for at least
+                * tconv us.
+                */
+               {
+                       .len = 0,
+                       .delay.value = 8,
+                       .delay.unit = SPI_DELAY_UNIT_USECS,
+               },
+               /*
+                * Then read two bytes of data in our RX buffer.
+                */
+               {
+                       .rx_buf = &adc->data,
+                       .len = 2,
+               },
+       };
+
+       return spi_sync_transfer(adc->spi, xfers, ARRAY_SIZE(xfers));
+}
+
+static int max1241_read_raw(struct iio_dev *indio_dev,
+                       struct iio_chan_spec const *chan,
+                       int *val, int *val2, long mask)
+{
+       int ret, vref_uV;
+       struct max1241 *adc = iio_priv(indio_dev);
+
+       switch (mask) {
+       case IIO_CHAN_INFO_RAW:
+               mutex_lock(&adc->lock);
+
+               if (adc->shutdown) {
+                       gpiod_set_value(adc->shutdown, 0);
+                       udelay(MAX1241_SHUTDOWN_DELAY_USEC);
+                       ret = max1241_read(adc);
+                       gpiod_set_value(adc->shutdown, 1);
+               } else
+                       ret = max1241_read(adc);
+
+               if (ret) {
+                       mutex_unlock(&adc->lock);
+                       return ret;
+               }
+
+               *val = (be16_to_cpu(adc->data) >> 3) & MAX1241_VAL_MASK;
+
+               mutex_unlock(&adc->lock);
+               return IIO_VAL_INT;
+       case IIO_CHAN_INFO_SCALE:
+               vref_uV = regulator_get_voltage(adc->vref);
+
+               if (vref_uV < 0)
+                       return vref_uV;
+
+               *val = vref_uV / 1000;
+               *val2 = 12;
+
+               return IIO_VAL_FRACTIONAL_LOG2;
+       default:
+               return -EINVAL;
+       }
+}
+
+static const struct iio_info max1241_info = {
+       .read_raw = max1241_read_raw,
+};
+
+static void max1241_disable_vdd_action(void *data)
+{
+       struct max1241 *adc = data;
+       struct device *dev = &adc->spi->dev;
+       int err;
+
+       err = regulator_disable(adc->vdd);
+       if (err)
+               dev_err(dev, "could not disable vdd regulator.\n");
+}
+
+static void max1241_disable_vref_action(void *data)
+{
+       struct max1241 *adc = data;
+       struct device *dev = &adc->spi->dev;
+       int err;
+
+       err = regulator_disable(adc->vref);
+       if (err)
+               dev_err(dev, "could not disable vref regulator.\n");
+}
+
+static int max1241_probe(struct spi_device *spi)
+{
+       struct device *dev = &spi->dev;
+       struct iio_dev *indio_dev;
+       struct max1241 *adc;
+       int ret;
+
+       indio_dev = devm_iio_device_alloc(dev, sizeof(*adc));
+       if (!indio_dev)
+               return -ENOMEM;
+
+       adc = iio_priv(indio_dev);
+       adc->spi = spi;
+       mutex_init(&adc->lock);
+
+       spi_set_drvdata(spi, indio_dev);
+
+       adc->vdd = devm_regulator_get(dev, "vdd");
+       if (IS_ERR(adc->vdd)) {
+               dev_err(dev, "failed to get vdd regulator\n");
+               return PTR_ERR(adc->vdd);
+       }
+
+       ret = regulator_enable(adc->vdd);
+       if (ret)
+               return ret;
+
+       ret = devm_add_action_or_reset(dev, max1241_disable_vdd_action, adc);
+       if (ret) {
+               dev_err(dev, "could not set up vdd regulator cleanup action\n");
+               return ret;
+       }
+
+       adc->vref = devm_regulator_get(dev, "vref");
+       if (IS_ERR(adc->vref)) {
+               dev_err(dev, "failed to get vref regulator\n");
+               return PTR_ERR(adc->vref);
+       }
+
+       ret = regulator_enable(adc->vref);
+       if (ret)
+               return ret;
+
+       ret = devm_add_action_or_reset(dev, max1241_disable_vref_action, adc);
+       if (ret) {
+               dev_err(dev, "could not set up vref regulator cleanup action\n");
+               return ret;
+       }
+
+       adc->shutdown = devm_gpiod_get_optional(dev, "shutdown",
+                                               GPIOD_OUT_HIGH);
+       if (IS_ERR(adc->shutdown))
+               return PTR_ERR(adc->shutdown);
+
+       if (adc->shutdown)
+               dev_dbg(dev, "shutdown pin passed, low-power mode enabled");
+       else
+               dev_dbg(dev, "no shutdown pin passed, low-power mode disabled");
+
+       indio_dev->name = spi_get_device_id(spi)->name;
+       indio_dev->dev.parent = dev;
+       indio_dev->info = &max1241_info;
+       indio_dev->modes = INDIO_DIRECT_MODE;
+       indio_dev->channels = max1241_channels;
+       indio_dev->num_channels = ARRAY_SIZE(max1241_channels);
+
+       return devm_iio_device_register(dev, indio_dev);
+}
+
+static const struct spi_device_id max1241_id[] = {
+       { "max1241", max1241 },
+       {}
+};
+
+static const struct of_device_id max1241_dt_ids[] = {
+       { .compatible = "maxim,max1241" },
+       {}
+};
+MODULE_DEVICE_TABLE(of, max1241_dt_ids);
+
+static struct spi_driver max1241_spi_driver = {
+       .driver = {
+               .name = "max1241",
+               .of_match_table = max1241_dt_ids,
+       },
+       .probe = max1241_probe,
+       .id_table = max1241_id,
+};
+module_spi_driver(max1241_spi_driver);
+
+MODULE_AUTHOR("Alexandru Lazar <alazar@startmail.com>");
+MODULE_DESCRIPTION("MAX1241 ADC driver");
+MODULE_LICENSE("GPL v2");
index 5c2cc61b666e74c8fd0bdd5db00c460507331b90..9d92017c79b2de93409286bc2479d26e23788eb4 100644 (file)
@@ -150,6 +150,7 @@ struct max1363_chip_info {
  * @current_mode:      the scan mode of this chip
  * @requestedmask:     a valid requested set of channels
  * @reg:               supply regulator
+ * @lock               lock to ensure state is consistent
  * @monitor_on:                whether monitor mode is enabled
  * @monitor_speed:     parameter corresponding to device monitor speed setting
  * @mask_high:         bitmask for enabled high thresholds
@@ -169,6 +170,7 @@ struct max1363_state {
        const struct max1363_mode       *current_mode;
        u32                             requestedmask;
        struct regulator                *reg;
+       struct mutex                    lock;
 
        /* Using monitor modes and buffer at the same time is
           currently not supported */
@@ -364,7 +366,11 @@ static int max1363_read_single_chan(struct iio_dev *indio_dev,
        struct max1363_state *st = iio_priv(indio_dev);
        struct i2c_client *client = st->client;
 
-       mutex_lock(&indio_dev->mlock);
+       ret = iio_device_claim_direct_mode(indio_dev);
+       if (ret)
+               return ret;
+       mutex_lock(&st->lock);
+
        /*
         * If monitor mode is enabled, the method for reading a single
         * channel will have to be rather different and has not yet
@@ -372,7 +378,7 @@ static int max1363_read_single_chan(struct iio_dev *indio_dev,
         *
         * Also, cannot read directly if buffered capture enabled.
         */
-       if (st->monitor_on || iio_buffer_enabled(indio_dev)) {
+       if (st->monitor_on) {
                ret = -EBUSY;
                goto error_ret;
        }
@@ -404,8 +410,10 @@ static int max1363_read_single_chan(struct iio_dev *indio_dev,
                data = rxbuf[0];
        }
        *val = data;
+
 error_ret:
-       mutex_unlock(&indio_dev->mlock);
+       mutex_unlock(&st->lock);
+       iio_device_release_direct_mode(indio_dev);
        return ret;
 
 }
@@ -705,9 +713,9 @@ static ssize_t max1363_monitor_store_freq(struct device *dev,
        if (!found)
                return -EINVAL;
 
-       mutex_lock(&indio_dev->mlock);
+       mutex_lock(&st->lock);
        st->monitor_speed = i;
-       mutex_unlock(&indio_dev->mlock);
+       mutex_unlock(&st->lock);
 
        return 0;
 }
@@ -810,12 +818,12 @@ static int max1363_read_event_config(struct iio_dev *indio_dev,
        int val;
        int number = chan->channel;
 
-       mutex_lock(&indio_dev->mlock);
+       mutex_lock(&st->lock);
        if (dir == IIO_EV_DIR_FALLING)
                val = (1 << number) & st->mask_low;
        else
                val = (1 << number) & st->mask_high;
-       mutex_unlock(&indio_dev->mlock);
+       mutex_unlock(&st->lock);
 
        return val;
 }
@@ -962,7 +970,11 @@ static int max1363_write_event_config(struct iio_dev *indio_dev,
        u16 unifiedmask;
        int number = chan->channel;
 
-       mutex_lock(&indio_dev->mlock);
+       ret = iio_device_claim_direct_mode(indio_dev);
+       if (ret)
+               return ret;
+       mutex_lock(&st->lock);
+
        unifiedmask = st->mask_low | st->mask_high;
        if (dir == IIO_EV_DIR_FALLING) {
 
@@ -989,7 +1001,8 @@ static int max1363_write_event_config(struct iio_dev *indio_dev,
 
        max1363_monitor_mode_update(st, !!(st->mask_high | st->mask_low));
 error_ret:
-       mutex_unlock(&indio_dev->mlock);
+       mutex_unlock(&st->lock);
+       iio_device_release_direct_mode(indio_dev);
 
        return ret;
 }
@@ -1587,6 +1600,7 @@ static int max1363_probe(struct i2c_client *client,
 
        st = iio_priv(indio_dev);
 
+       mutex_init(&st->lock);
        st->reg = devm_regulator_get(&client->dev, "vcc");
        if (IS_ERR(st->reg)) {
                ret = PTR_ERR(st->reg);
index 176e1cb4abb1f3251f7d295a08e27c7260ee8f30..0f2c1738a90d1dc5649f05b8c1fbe267441616cb 100644 (file)
@@ -496,7 +496,6 @@ static int sun4i_gpadc_probe_dt(struct platform_device *pdev,
                                struct iio_dev *indio_dev)
 {
        struct sun4i_gpadc_iio *info = iio_priv(indio_dev);
-       struct resource *mem;
        void __iomem *base;
        int ret;
 
@@ -508,8 +507,7 @@ static int sun4i_gpadc_probe_dt(struct platform_device *pdev,
        indio_dev->num_channels = ARRAY_SIZE(sun8i_a33_gpadc_channels);
        indio_dev->channels = sun8i_a33_gpadc_channels;
 
-       mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       base = devm_ioremap_resource(&pdev->dev, mem);
+       base = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(base))
                return PTR_ERR(base);
 
index ec227b358cd6f868dbb7d00f4a9e57fabe0ea65f..9897d758cf8847f377da02618529961e848fccac 100644 (file)
@@ -3,7 +3,7 @@
  * Xilinx XADC driver
  *
  * Copyright 2013-2014 Analog Devices Inc.
- *  Author: Lars-Peter Clauen <lars@metafoo.de>
+ *  Author: Lars-Peter Clausen <lars@metafoo.de>
  *
  * Documentation for the parts can be found at:
  *  - XADC hardmacro: Xilinx UG480
@@ -653,7 +653,7 @@ static int xadc_trigger_set_state(struct iio_trigger *trigger, bool state)
        mutex_lock(&xadc->mutex);
 
        if (state) {
-               /* Only one of the two triggers can be active at the a time. */
+               /* Only one of the two triggers can be active at a time. */
                if (xadc->trigger != NULL) {
                        ret = -EBUSY;
                        goto err_out;
index dbfd5da290a4d685dd66d8050f3b5b8b7b53b8f4..2357f585720a1887800e4c6854686788fad4b08f 100644 (file)
@@ -3,7 +3,7 @@
  * Xilinx XADC driver
  *
  * Copyright 2013 Analog Devices Inc.
- *  Author: Lars-Peter Clauen <lars@metafoo.de>
+ *  Author: Lars-Peter Clausen <lars@metafoo.de>
  */
 
 #include <linux/iio/events.h>
index 4017f18b0a4f86a043d3defcc0a5e125734930c5..25abed9c02858b695a79236b0f9cca2cbc47df8a 100644 (file)
@@ -3,7 +3,7 @@
  * Xilinx XADC driver
  *
  * Copyright 2013 Analog Devices Inc.
- *  Author: Lars-Peter Clauen <lars@metafoo.de>
+ *  Author: Lars-Peter Clausen <lars@metafoo.de>
  */
 
 #ifndef __IIO_XILINX_XADC__
index a74bd9c0587c7fa7a669f174336a614a06277ebb..d348af8b97050141bd239a6f714d854713c47d64 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/mutex.h>
 #include <linux/sched.h>
 #include <linux/poll.h>
-#include <linux/iio/buffer.h>
 #include <linux/iio/buffer_impl.h>
 #include <linux/iio/buffer-dma.h>
 #include <linux/dma-mapping.h>
index b129693af0fd1fb4cd4b5ccb44c3ead4edc6343c..6dedf12b69a40a9a9ab35e9ae0ce577cc0288d17 100644 (file)
@@ -134,7 +134,7 @@ static ssize_t iio_dmaengine_buffer_get_length_align(struct device *dev,
        struct dmaengine_buffer *dmaengine_buffer =
                iio_buffer_to_dmaengine_buffer(indio_dev->buffer);
 
-       return sprintf(buf, "%u\n", dmaengine_buffer->align);
+       return sprintf(buf, "%zu\n", dmaengine_buffer->align);
 }
 
 static IIO_DEVICE_ATTR(length_align_bytes, 0444,
@@ -229,6 +229,45 @@ void iio_dmaengine_buffer_free(struct iio_buffer *buffer)
 }
 EXPORT_SYMBOL_GPL(iio_dmaengine_buffer_free);
 
+static void __devm_iio_dmaengine_buffer_free(struct device *dev, void *res)
+{
+       iio_dmaengine_buffer_free(*(struct iio_buffer **)res);
+}
+
+/**
+ * devm_iio_dmaengine_buffer_alloc() - Resource-managed iio_dmaengine_buffer_alloc()
+ * @dev: Parent device for the buffer
+ * @channel: DMA channel name, typically "rx".
+ *
+ * This allocates a new IIO buffer which internally uses the DMAengine framework
+ * to perform its transfers. The parent device will be used to request the DMA
+ * channel.
+ *
+ * The buffer will be automatically de-allocated once the device gets destroyed.
+ */
+struct iio_buffer *devm_iio_dmaengine_buffer_alloc(struct device *dev,
+       const char *channel)
+{
+       struct iio_buffer **bufferp, *buffer;
+
+       bufferp = devres_alloc(__devm_iio_dmaengine_buffer_free,
+                              sizeof(*bufferp), GFP_KERNEL);
+       if (!bufferp)
+               return ERR_PTR(-ENOMEM);
+
+       buffer = iio_dmaengine_buffer_alloc(dev, channel);
+       if (IS_ERR(buffer)) {
+               devres_free(bufferp);
+               return buffer;
+       }
+
+       *bufferp = buffer;
+       devres_add(dev, bufferp);
+
+       return buffer;
+}
+EXPORT_SYMBOL_GPL(devm_iio_dmaengine_buffer_alloc);
+
 MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
 MODULE_DESCRIPTION("DMA buffer for the IIO framework");
 MODULE_LICENSE("GPL");
index 95165697d8aea06d07c673c5593500cbb8f5683b..f2d27788f666037b5eca04cf6e5465046514d253 100644 (file)
@@ -142,17 +142,6 @@ static void devm_iio_hw_consumer_release(struct device *dev, void *res)
        iio_hw_consumer_free(*(struct iio_hw_consumer **)res);
 }
 
-static int devm_iio_hw_consumer_match(struct device *dev, void *res, void *data)
-{
-       struct iio_hw_consumer **r = res;
-
-       if (!r || !*r) {
-               WARN_ON(!r || !*r);
-               return 0;
-       }
-       return *r == data;
-}
-
 /**
  * devm_iio_hw_consumer_alloc - Resource-managed iio_hw_consumer_alloc()
  * @dev: Pointer to consumer device.
@@ -160,9 +149,6 @@ static int devm_iio_hw_consumer_match(struct device *dev, void *res, void *data)
  * Managed iio_hw_consumer_alloc. iio_hw_consumer allocated with this function
  * is automatically freed on driver detach.
  *
- * If an iio_hw_consumer allocated with this function needs to be freed
- * separately, devm_iio_hw_consumer_free() must be used.
- *
  * returns pointer to allocated iio_hw_consumer on success, NULL on failure.
  */
 struct iio_hw_consumer *devm_iio_hw_consumer_alloc(struct device *dev)
@@ -186,23 +172,6 @@ struct iio_hw_consumer *devm_iio_hw_consumer_alloc(struct device *dev)
 }
 EXPORT_SYMBOL_GPL(devm_iio_hw_consumer_alloc);
 
-/**
- * devm_iio_hw_consumer_free - Resource-managed iio_hw_consumer_free()
- * @dev: Pointer to consumer device.
- * @hwc: iio_hw_consumer to free.
- *
- * Free iio_hw_consumer allocated with devm_iio_hw_consumer_alloc().
- */
-void devm_iio_hw_consumer_free(struct device *dev, struct iio_hw_consumer *hwc)
-{
-       int rc;
-
-       rc = devres_release(dev, devm_iio_hw_consumer_release,
-                           devm_iio_hw_consumer_match, hwc);
-       WARN_ON(rc);
-}
-EXPORT_SYMBOL_GPL(devm_iio_hw_consumer_free);
-
 /**
  * iio_hw_consumer_enable() - Enable IIO hardware consumer
  * @hwc: iio_hw_consumer to enable.
index cb322b2f09cd3e127599268b2b9e5664c311c58c..e8046c1ecd6b56d77be04faaf2a383432aa75f70 100644 (file)
@@ -126,17 +126,6 @@ int devm_iio_triggered_buffer_setup(struct device *dev,
 }
 EXPORT_SYMBOL_GPL(devm_iio_triggered_buffer_setup);
 
-void devm_iio_triggered_buffer_cleanup(struct device *dev,
-                                      struct iio_dev *indio_dev)
-{
-       int rc;
-
-       rc = devres_release(dev, devm_iio_triggered_buffer_clean,
-                           devm_iio_device_match, indio_dev);
-       WARN_ON(rc);
-}
-EXPORT_SYMBOL_GPL(devm_iio_triggered_buffer_cleanup);
-
 MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
 MODULE_DESCRIPTION("IIO helper functions for setting up triggered buffers");
 MODULE_LICENSE("GPL");
index 3150f8ab984bac08ae6c155d22080995e6570c06..1359abed3b31e173d26ce48b6b9ec5e923c5e981 100644 (file)
@@ -179,16 +179,6 @@ static void devm_iio_kfifo_release(struct device *dev, void *res)
        iio_kfifo_free(*(struct iio_buffer **)res);
 }
 
-static int devm_iio_kfifo_match(struct device *dev, void *res, void *data)
-{
-       struct iio_buffer **r = res;
-
-       if (WARN_ON(!r || !*r))
-               return 0;
-
-       return *r == data;
-}
-
 /**
  * devm_iio_fifo_allocate - Resource-managed iio_kfifo_allocate()
  * @dev:               Device to allocate kfifo buffer for
@@ -216,16 +206,4 @@ struct iio_buffer *devm_iio_kfifo_allocate(struct device *dev)
 }
 EXPORT_SYMBOL(devm_iio_kfifo_allocate);
 
-/**
- * devm_iio_fifo_free - Resource-managed iio_kfifo_free()
- * @dev:               Device the buffer belongs to
- * @r:                 The buffer associated with the device
- */
-void devm_iio_kfifo_free(struct device *dev, struct iio_buffer *r)
-{
-       WARN_ON(devres_release(dev, devm_iio_kfifo_release,
-                              devm_iio_kfifo_match, r));
-}
-EXPORT_SYMBOL(devm_iio_kfifo_free);
-
 MODULE_LICENSE("GPL");
index 82d470561ad3c6359f6aa37bb497f61457375230..973cdb4f1e8343d65c3831ebdcb2bc672dc9e347 100644 (file)
@@ -426,8 +426,7 @@ static irqreturn_t atlas_trigger_handler(int irq, void *private)
        int ret;
 
        ret = regmap_bulk_read(data->regmap, data->chip->data_reg,
-                             (u8 *) &data->buffer,
-                             sizeof(__be32) * channels);
+                             &data->buffer, sizeof(__be32) * channels);
 
        if (!ret)
                iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
@@ -463,7 +462,7 @@ static int atlas_read_measurement(struct atlas_data *data, int reg, __be32 *val)
        if (suspended)
                msleep(data->chip->delay);
 
-       ret = regmap_bulk_read(data->regmap, reg, (u8 *) val, sizeof(*val));
+       ret = regmap_bulk_read(data->regmap, reg, val, sizeof(*val));
 
        pm_runtime_mark_last_busy(dev);
        pm_runtime_put_autosuspend(dev);
@@ -485,7 +484,7 @@ static int atlas_read_raw(struct iio_dev *indio_dev,
                switch (chan->type) {
                case IIO_TEMP:
                        ret = regmap_bulk_read(data->regmap, chan->address,
-                                             (u8 *) &reg, sizeof(reg));
+                                              &reg, sizeof(reg));
                        break;
                case IIO_PH:
                case IIO_CONCENTRATION:
index ccde4c65ff9340b2bcc4a730dc978daf918fa08c..13773e01699ba084a3731883b24c4f78db06c2cf 100644 (file)
@@ -114,14 +114,16 @@ static int bme680_read_calib(struct bme680_data *data,
        __le16 buf;
 
        /* Temperature related coefficients */
-       ret = regmap_bulk_read(data->regmap, BME680_T1_LSB_REG, (u8 *) &buf, 2);
+       ret = regmap_bulk_read(data->regmap, BME680_T1_LSB_REG,
+                              &buf, sizeof(buf));
        if (ret < 0) {
                dev_err(dev, "failed to read BME680_T1_LSB_REG\n");
                return ret;
        }
        calib->par_t1 = le16_to_cpu(buf);
 
-       ret = regmap_bulk_read(data->regmap, BME680_T2_LSB_REG, (u8 *) &buf, 2);
+       ret = regmap_bulk_read(data->regmap, BME680_T2_LSB_REG,
+                              &buf, sizeof(buf));
        if (ret < 0) {
                dev_err(dev, "failed to read BME680_T2_LSB_REG\n");
                return ret;
@@ -136,14 +138,16 @@ static int bme680_read_calib(struct bme680_data *data,
        calib->par_t3 = tmp;
 
        /* Pressure related coefficients */
-       ret = regmap_bulk_read(data->regmap, BME680_P1_LSB_REG, (u8 *) &buf, 2);
+       ret = regmap_bulk_read(data->regmap, BME680_P1_LSB_REG,
+                              &buf, sizeof(buf));
        if (ret < 0) {
                dev_err(dev, "failed to read BME680_P1_LSB_REG\n");
                return ret;
        }
        calib->par_p1 = le16_to_cpu(buf);
 
-       ret = regmap_bulk_read(data->regmap, BME680_P2_LSB_REG, (u8 *) &buf, 2);
+       ret = regmap_bulk_read(data->regmap, BME680_P2_LSB_REG,
+                              &buf, sizeof(buf));
        if (ret < 0) {
                dev_err(dev, "failed to read BME680_P2_LSB_REG\n");
                return ret;
@@ -157,14 +161,16 @@ static int bme680_read_calib(struct bme680_data *data,
        }
        calib->par_p3 = tmp;
 
-       ret = regmap_bulk_read(data->regmap, BME680_P4_LSB_REG, (u8 *) &buf, 2);
+       ret = regmap_bulk_read(data->regmap, BME680_P4_LSB_REG,
+                              &buf, sizeof(buf));
        if (ret < 0) {
                dev_err(dev, "failed to read BME680_P4_LSB_REG\n");
                return ret;
        }
        calib->par_p4 = le16_to_cpu(buf);
 
-       ret = regmap_bulk_read(data->regmap, BME680_P5_LSB_REG, (u8 *) &buf, 2);
+       ret = regmap_bulk_read(data->regmap, BME680_P5_LSB_REG,
+                              &buf, sizeof(buf));
        if (ret < 0) {
                dev_err(dev, "failed to read BME680_P5_LSB_REG\n");
                return ret;
@@ -185,14 +191,16 @@ static int bme680_read_calib(struct bme680_data *data,
        }
        calib->par_p7 = tmp;
 
-       ret = regmap_bulk_read(data->regmap, BME680_P8_LSB_REG, (u8 *) &buf, 2);
+       ret = regmap_bulk_read(data->regmap, BME680_P8_LSB_REG,
+                              &buf, sizeof(buf));
        if (ret < 0) {
                dev_err(dev, "failed to read BME680_P8_LSB_REG\n");
                return ret;
        }
        calib->par_p8 = le16_to_cpu(buf);
 
-       ret = regmap_bulk_read(data->regmap, BME680_P9_LSB_REG, (u8 *) &buf, 2);
+       ret = regmap_bulk_read(data->regmap, BME680_P9_LSB_REG,
+                              &buf, sizeof(buf));
        if (ret < 0) {
                dev_err(dev, "failed to read BME680_P9_LSB_REG\n");
                return ret;
@@ -276,8 +284,8 @@ static int bme680_read_calib(struct bme680_data *data,
        }
        calib->par_gh1 = tmp;
 
-       ret = regmap_bulk_read(data->regmap, BME680_GH2_LSB_REG, (u8 *) &buf,
-                              2);
+       ret = regmap_bulk_read(data->regmap, BME680_GH2_LSB_REG,
+                              &buf, sizeof(buf));
        if (ret < 0) {
                dev_err(dev, "failed to read BME680_GH2_LSB_REG\n");
                return ret;
@@ -615,7 +623,7 @@ static int bme680_read_temp(struct bme680_data *data, int *val)
                return ret;
 
        ret = regmap_bulk_read(data->regmap, BME680_REG_TEMP_MSB,
-                              (u8 *) &tmp, 3);
+                              &tmp, 3);
        if (ret < 0) {
                dev_err(dev, "failed to read temperature\n");
                return ret;
@@ -656,7 +664,7 @@ static int bme680_read_press(struct bme680_data *data,
                return ret;
 
        ret = regmap_bulk_read(data->regmap, BME680_REG_PRESS_MSB,
-                              (u8 *) &tmp, 3);
+                              &tmp, 3);
        if (ret < 0) {
                dev_err(dev, "failed to read pressure\n");
                return ret;
@@ -689,7 +697,7 @@ static int bme680_read_humid(struct bme680_data *data,
                return ret;
 
        ret = regmap_bulk_read(data->regmap, BM6880_REG_HUMIDITY_MSB,
-                              (u8 *) &tmp, 2);
+                              &tmp, sizeof(tmp));
        if (ret < 0) {
                dev_err(dev, "failed to read humidity\n");
                return ret;
@@ -754,7 +762,7 @@ static int bme680_read_gas(struct bme680_data *data,
        }
 
        ret = regmap_bulk_read(data->regmap, BME680_REG_GAS_MSB,
-                              (u8 *) &tmp, 2);
+                              &tmp, sizeof(tmp));
        if (ret < 0) {
                dev_err(dev, "failed to read gas resistance\n");
                return ret;
index 0e35ff06f9af9d1d821411a679b2da9d497c0f85..a0c2cbd60c6f4115ff299211d81463fad02c896f 100644 (file)
@@ -150,8 +150,7 @@ static int st_sensors_set_fullscale(struct iio_dev *indio_dev, unsigned int fs)
        if (err < 0)
                goto st_accel_set_fullscale_error;
 
-       sdata->current_fullscale = (struct st_sensor_fullscale_avl *)
-                                       &sdata->sensor_settings->fs.fs_avl[i];
+       sdata->current_fullscale = &sdata->sensor_settings->fs.fs_avl[i];
        return err;
 
 st_accel_set_fullscale_error:
@@ -278,8 +277,7 @@ static int st_sensors_set_drdy_int_pin(struct iio_dev *indio_dev,
            !sdata->sensor_settings->drdy_irq.int2.addr) {
                if (pdata->drdy_int_pin)
                        dev_info(&indio_dev->dev,
-                                "DRDY on pin INT%d specified, but sensor "
-                                "does not support interrupts\n",
+                                "DRDY on pin INT%d specified, but sensor does not support interrupts\n",
                                 pdata->drdy_int_pin);
                return 0;
        }
index 286830fb5d357523c54b63a5eaf8d33036a7624d..b400560bac9390ad6300979c98416f6cc548fb84 100644 (file)
@@ -49,8 +49,8 @@ int st_sensors_i2c_configure(struct iio_dev *indio_dev,
 
        sdata->regmap = devm_regmap_init_i2c(client, config);
        if (IS_ERR(sdata->regmap)) {
-               dev_err(&client->dev, "Failed to register i2c regmap (%d)\n",
-                       (int)PTR_ERR(sdata->regmap));
+               dev_err(&client->dev, "Failed to register i2c regmap (%ld)\n",
+                       PTR_ERR(sdata->regmap));
                return PTR_ERR(sdata->regmap);
        }
 
index 1275fb0eda3185de7d4e38cef1f66bf31eaa1400..ee70515bb89f514cb86dd25c95fab9f97648e411 100644 (file)
@@ -44,7 +44,7 @@ static bool st_sensors_is_spi_3_wire(struct spi_device *spi)
        if (device_property_read_bool(dev, "spi-3wire"))
                return true;
 
-       pdata = (struct st_sensors_platform_data *)dev->platform_data;
+       pdata = dev_get_platdata(dev);
        if (pdata && pdata->spi_3wire)
                return true;
 
@@ -101,8 +101,8 @@ int st_sensors_spi_configure(struct iio_dev *indio_dev,
 
        sdata->regmap = devm_regmap_init_spi(spi, config);
        if (IS_ERR(sdata->regmap)) {
-               dev_err(&spi->dev, "Failed to register spi regmap (%d)\n",
-                       (int)PTR_ERR(sdata->regmap));
+               dev_err(&spi->dev, "Failed to register spi regmap (%ld)\n",
+                       PTR_ERR(sdata->regmap));
                return PTR_ERR(sdata->regmap);
        }
 
index e817537cdfb5dd536881c816436c719168b07ac1..0507283bd4c1dedd78780f9c20dcca39beef0748 100644 (file)
@@ -44,8 +44,7 @@ static int st_sensors_new_samples_available(struct iio_dev *indio_dev,
                          sdata->sensor_settings->drdy_irq.stat_drdy.addr,
                          &status);
        if (ret < 0) {
-               dev_err(sdata->dev,
-                       "error checking samples available\n");
+               dev_err(sdata->dev, "error checking samples available\n");
                return ret;
        }
 
@@ -148,9 +147,7 @@ int st_sensors_allocate_trigger(struct iio_dev *indio_dev,
        case IRQF_TRIGGER_LOW:
                if (!sdata->sensor_settings->drdy_irq.addr_ihl) {
                        dev_err(&indio_dev->dev,
-                               "falling/low specified for IRQ "
-                               "but hardware supports only rising/high: "
-                               "will request rising/high\n");
+                               "falling/low specified for IRQ but hardware supports only rising/high: will request rising/high\n");
                        if (irq_trig == IRQF_TRIGGER_FALLING)
                                irq_trig = IRQF_TRIGGER_RISING;
                        if (irq_trig == IRQF_TRIGGER_LOW)
@@ -163,8 +160,7 @@ int st_sensors_allocate_trigger(struct iio_dev *indio_dev,
                        if (err < 0)
                                goto iio_trigger_free;
                        dev_info(&indio_dev->dev,
-                                "interrupts on the falling edge or "
-                                "active low level\n");
+                                "interrupts on the falling edge or active low level\n");
                }
                break;
        case IRQF_TRIGGER_RISING:
@@ -178,8 +174,7 @@ int st_sensors_allocate_trigger(struct iio_dev *indio_dev,
        default:
                /* This is the most preferred mode, if possible */
                dev_err(&indio_dev->dev,
-                       "unsupported IRQ trigger specified (%lx), enforce "
-                       "rising edge\n", irq_trig);
+                       "unsupported IRQ trigger specified (%lx), enforce rising edge\n", irq_trig);
                irq_trig = IRQF_TRIGGER_RISING;
        }
 
index 7eaf77707b0beed0d079ad100101b48bd770fb68..6daeddf37f6073142dbb60b13705143f8ed7c2ac 100644 (file)
@@ -61,7 +61,7 @@ config BMG160
        help
          Say yes here to build support for BOSCH BMG160 Tri-axis Gyro Sensor
          driver connected via I2C or SPI. This driver also supports BMI055
-         gyroscope.
+         and BMI088 gyroscope.
 
          This driver can also be built as a module.  If so, the module
          will be called bmg160_i2c or bmg160_spi.
index 4fc9c6a3321ff99afc66d327a96ad8f9794e9366..b3fa46bd02cb89898dde70fe5600cf696eb0a9b0 100644 (file)
@@ -21,8 +21,8 @@ static int bmg160_i2c_probe(struct i2c_client *client,
 
        regmap = devm_regmap_init_i2c(client, &bmg160_regmap_i2c_conf);
        if (IS_ERR(regmap)) {
-               dev_err(&client->dev, "Failed to register i2c regmap %d\n",
-                       (int)PTR_ERR(regmap));
+               dev_err(&client->dev, "Failed to register i2c regmap: %pe\n",
+                       regmap);
                return PTR_ERR(regmap);
        }
 
@@ -42,6 +42,7 @@ static int bmg160_i2c_remove(struct i2c_client *client)
 static const struct acpi_device_id bmg160_acpi_match[] = {
        {"BMG0160", 0},
        {"BMI055B", 0},
+       {"BMI088B", 0},
        {},
 };
 
@@ -50,6 +51,7 @@ MODULE_DEVICE_TABLE(acpi, bmg160_acpi_match);
 static const struct i2c_device_id bmg160_i2c_id[] = {
        {"bmg160", 0},
        {"bmi055_gyro", 0},
+       {"bmi088_gyro", 0},
        {}
 };
 
index 182a59c42507d1799fa853be00639f998e4331a6..745962e1e42357bcadc0d929041718620b9e3f79 100644 (file)
@@ -19,8 +19,8 @@ static int bmg160_spi_probe(struct spi_device *spi)
 
        regmap = devm_regmap_init_spi(spi, &bmg160_regmap_spi_conf);
        if (IS_ERR(regmap)) {
-               dev_err(&spi->dev, "Failed to register spi regmap %d\n",
-                       (int)PTR_ERR(regmap));
+               dev_err(&spi->dev, "Failed to register spi regmap: %pe\n",
+                       regmap);
                return PTR_ERR(regmap);
        }
 
@@ -37,6 +37,7 @@ static int bmg160_spi_remove(struct spi_device *spi)
 static const struct spi_device_id bmg160_spi_id[] = {
        {"bmg160", 0},
        {"bmi055_gyro", 0},
+       {"bmi088_gyro", 0},
        {}
 };
 
index afa8018b92386c14738f84b6798d4121a32029ec..ef5bcbc4b45b1af927f441f77a08777e53f5f4bb 100644 (file)
@@ -51,8 +51,8 @@ static int mpu3050_i2c_probe(struct i2c_client *client,
 
        regmap = devm_regmap_init_i2c(client, &mpu3050_i2c_regmap_config);
        if (IS_ERR(regmap)) {
-               dev_err(&client->dev, "Failed to register i2c regmap %d\n",
-                       (int)PTR_ERR(regmap));
+               dev_err(&client->dev, "Failed to register i2c regmap: %pe\n",
+                       regmap);
                return PTR_ERR(regmap);
        }
 
index 7465ad62391c09cab6d977f7194b7fae89232323..9c92ff7a82bee846dbf7b6bc9963bf418bcc60c8 100644 (file)
@@ -37,8 +37,7 @@ static int st_gyro_buffer_postenable(struct iio_dev *indio_dev)
        if (err < 0)
                return err;
 
-       err = st_sensors_set_axis_enable(indio_dev,
-                                        (u8)indio_dev->active_scan_mask[0]);
+       err = st_sensors_set_axis_enable(indio_dev, indio_dev->active_scan_mask[0]);
        if (err < 0)
                goto st_gyro_buffer_predisable;
 
index 26c50b24bc089b19c475e0f3e22407c94bf5a2ef..c8aa051995d3bf6d4a8fb4301f6ae09ee4d4538b 100644 (file)
@@ -460,6 +460,7 @@ EXPORT_SYMBOL(st_gyro_get_settings);
 int st_gyro_common_probe(struct iio_dev *indio_dev)
 {
        struct st_sensor_data *gdata = iio_priv(indio_dev);
+       struct st_sensors_platform_data *pdata;
        int err;
 
        indio_dev->modes = INDIO_DIRECT_MODE;
@@ -477,12 +478,12 @@ int st_gyro_common_probe(struct iio_dev *indio_dev)
        indio_dev->channels = gdata->sensor_settings->ch;
        indio_dev->num_channels = ST_SENSORS_NUMBER_ALL_CHANNELS;
 
-       gdata->current_fullscale = (struct st_sensor_fullscale_avl *)
-                                       &gdata->sensor_settings->fs.fs_avl[0];
+       gdata->current_fullscale = &gdata->sensor_settings->fs.fs_avl[0];
        gdata->odr = gdata->sensor_settings->odr.odr_avl[0].hz;
 
-       err = st_sensors_init_sensor(indio_dev,
-                               (struct st_sensors_platform_data *)&gyro_pdata);
+       pdata = (struct st_sensors_platform_data *)&gyro_pdata;
+
+       err = st_sensors_init_sensor(indio_dev, pdata);
        if (err < 0)
                goto st_gyro_power_off;
 
index 84010501762da09776bbf05a553845678dc62ca5..546fc37ad75deaad6b6838e3b585015e57422595 100644 (file)
@@ -16,7 +16,7 @@
 #include <linux/irq.h>
 #include <linux/i2c.h>
 #include <linux/mutex.h>
-#include <linux/of.h>
+#include <linux/property.h>
 #include <linux/regmap.h>
 #include <linux/iio/iio.h>
 #include <linux/iio/buffer.h>
@@ -267,11 +267,10 @@ static int max30100_get_current_idx(unsigned int val, int *reg)
 static int max30100_led_init(struct max30100_data *data)
 {
        struct device *dev = &data->client->dev;
-       struct device_node *np = dev->of_node;
        unsigned int val[2];
        int reg, ret;
 
-       ret = of_property_read_u32_array(np, "maxim,led-current-microamp",
+       ret = device_property_read_u32_array(dev, "maxim,led-current-microamp",
                                        (unsigned int *) &val, 2);
        if (ret) {
                /* Default to 24 mA RED LED, 50 mA IR LED */
@@ -502,7 +501,7 @@ MODULE_DEVICE_TABLE(of, max30100_dt_ids);
 static struct i2c_driver max30100_driver = {
        .driver = {
                .name   = MAX30100_DRV_NAME,
-               .of_match_table = of_match_ptr(max30100_dt_ids),
+               .of_match_table = max30100_dt_ids,
        },
        .probe          = max30100_probe,
        .remove         = max30100_remove,
index 81d50a861c22397a2f9d5f90769b5f21b61ba884..9fb3f33614d401b370f30c0a6ab835074dc56ae6 100644 (file)
@@ -74,10 +74,9 @@ static irqreturn_t hts221_trigger_handler_thread(int irq, void *private)
 
 int hts221_allocate_trigger(struct hts221_hw *hw)
 {
+       struct st_sensors_platform_data *pdata = dev_get_platdata(hw->dev);
        struct iio_dev *iio_dev = iio_priv_to_dev(hw);
        bool irq_active_low = false, open_drain = false;
-       struct device_node *np = hw->dev->of_node;
-       struct st_sensors_platform_data *pdata;
        unsigned long irq_type;
        int err;
 
@@ -106,8 +105,7 @@ int hts221_allocate_trigger(struct hts221_hw *hw)
        if (err < 0)
                return err;
 
-       pdata = (struct st_sensors_platform_data *)hw->dev->platform_data;
-       if ((np && of_property_read_bool(np, "drive-open-drain")) ||
+       if (device_property_read_bool(hw->dev, "drive-open-drain") ||
            (pdata && pdata->open_drain)) {
                irq_type |= IRQF_SHARED;
                open_drain = true;
index 4272b7030c44846b4049e1d5684669249e131c37..cab39c4756f8ea6a05d1a18ff753367ed84acacd 100644 (file)
@@ -32,8 +32,8 @@ static int hts221_i2c_probe(struct i2c_client *client,
 
        regmap = devm_regmap_init_i2c(client, &hts221_i2c_regmap_config);
        if (IS_ERR(regmap)) {
-               dev_err(&client->dev, "Failed to register i2c regmap %d\n",
-                       (int)PTR_ERR(regmap));
+               dev_err(&client->dev, "Failed to register i2c regmap %ld\n",
+                       PTR_ERR(regmap));
                return PTR_ERR(regmap);
        }
 
@@ -63,7 +63,7 @@ static struct i2c_driver hts221_driver = {
        .driver = {
                .name = "hts221_i2c",
                .pm = &hts221_pm_ops,
-               .of_match_table = of_match_ptr(hts221_i2c_of_match),
+               .of_match_table = hts221_i2c_of_match,
                .acpi_match_table = ACPI_PTR(hts221_acpi_match),
        },
        .probe = hts221_i2c_probe,
index 055dba8897d24eae797f89257f75c20096176dfb..729e86e433b1fd20311c92695f99e6dfbfe581d5 100644 (file)
@@ -31,8 +31,8 @@ static int hts221_spi_probe(struct spi_device *spi)
 
        regmap = devm_regmap_init_spi(spi, &hts221_spi_regmap_config);
        if (IS_ERR(regmap)) {
-               dev_err(&spi->dev, "Failed to register spi regmap %d\n",
-                       (int)PTR_ERR(regmap));
+               dev_err(&spi->dev, "Failed to register spi regmap %ld\n",
+                       PTR_ERR(regmap));
                return PTR_ERR(regmap);
        }
 
@@ -56,7 +56,7 @@ static struct spi_driver hts221_driver = {
        .driver = {
                .name = "hts221_spi",
                .pm = &hts221_pm_ops,
-               .of_match_table = of_match_ptr(hts221_spi_of_match),
+               .of_match_table = hts221_spi_of_match,
        },
        .probe = hts221_spi_probe,
        .id_table = hts221_spi_id_table,
index a8afd01de4f3e8e8267ebe6c83ec37cbd89c6fc9..2e7d0d337f8f66cc6854f8b038f0773e57fe5648 100644 (file)
@@ -419,7 +419,7 @@ int __adis_initial_startup(struct adis *adis)
 
        if (prod_id != adis->data->prod_id)
                dev_warn(&adis->spi->dev,
-                        "Device ID(%u) and product ID(%u) do not match.",
+                        "Device ID(%u) and product ID(%u) do not match.\n",
                         adis->data->prod_id, prod_id);
 
        return 0;
index 05e70c1c48359d8e1d9af7ee19feb5648cda931d..4445c242709c84f93738198b8bf541926ca241a9 100644 (file)
@@ -258,7 +258,7 @@ static int adis16400_show_product_id(void *arg, u64 *val)
 
        return 0;
 }
-DEFINE_SIMPLE_ATTRIBUTE(adis16400_product_id_fops,
+DEFINE_DEBUGFS_ATTRIBUTE(adis16400_product_id_fops,
        adis16400_show_product_id, NULL, "%lld\n");
 
 static int adis16400_show_flash_count(void *arg, u64 *val)
@@ -275,7 +275,7 @@ static int adis16400_show_flash_count(void *arg, u64 *val)
 
        return 0;
 }
-DEFINE_SIMPLE_ATTRIBUTE(adis16400_flash_count_fops,
+DEFINE_DEBUGFS_ATTRIBUTE(adis16400_flash_count_fops,
        adis16400_show_flash_count, NULL, "%lld\n");
 
 static int adis16400_debugfs_init(struct iio_dev *indio_dev)
@@ -283,15 +283,16 @@ static int adis16400_debugfs_init(struct iio_dev *indio_dev)
        struct adis16400_state *st = iio_priv(indio_dev);
 
        if (st->variant->flags & ADIS16400_HAS_SERIAL_NUMBER)
-               debugfs_create_file("serial_number", 0400,
-                       indio_dev->debugfs_dentry, st,
-                       &adis16400_serial_number_fops);
+               debugfs_create_file_unsafe("serial_number", 0400,
+                               indio_dev->debugfs_dentry, st,
+                               &adis16400_serial_number_fops);
        if (st->variant->flags & ADIS16400_HAS_PROD_ID)
-               debugfs_create_file("product_id", 0400,
+               debugfs_create_file_unsafe("product_id", 0400,
+                               indio_dev->debugfs_dentry, st,
+                               &adis16400_product_id_fops);
+       debugfs_create_file_unsafe("flash_count", 0400,
                        indio_dev->debugfs_dentry, st,
-                       &adis16400_product_id_fops);
-       debugfs_create_file("flash_count", 0400, indio_dev->debugfs_dentry,
-               st, &adis16400_flash_count_fops);
+                       &adis16400_flash_count_fops);
 
        return 0;
 }
index 0027683d02562fd203d3b51eb501d97738d4cfe5..0957f5cfe9c05d13790ecf53ec2cccd6b01fe268 100644 (file)
@@ -87,8 +87,8 @@ static int adis16460_show_serial_number(void *arg, u64 *val)
 
        return 0;
 }
-DEFINE_SIMPLE_ATTRIBUTE(adis16460_serial_number_fops,
-       adis16460_show_serial_number, NULL, "0x%.4llx\n");
+DEFINE_DEBUGFS_ATTRIBUTE(adis16460_serial_number_fops,
+               adis16460_show_serial_number, NULL, "0x%.4llx\n");
 
 static int adis16460_show_product_id(void *arg, u64 *val)
 {
@@ -105,8 +105,8 @@ static int adis16460_show_product_id(void *arg, u64 *val)
 
        return 0;
 }
-DEFINE_SIMPLE_ATTRIBUTE(adis16460_product_id_fops,
-       adis16460_show_product_id, NULL, "%llu\n");
+DEFINE_DEBUGFS_ATTRIBUTE(adis16460_product_id_fops,
+               adis16460_show_product_id, NULL, "%llu\n");
 
 static int adis16460_show_flash_count(void *arg, u64 *val)
 {
@@ -123,19 +123,22 @@ static int adis16460_show_flash_count(void *arg, u64 *val)
 
        return 0;
 }
-DEFINE_SIMPLE_ATTRIBUTE(adis16460_flash_count_fops,
-       adis16460_show_flash_count, NULL, "%lld\n");
+DEFINE_DEBUGFS_ATTRIBUTE(adis16460_flash_count_fops,
+               adis16460_show_flash_count, NULL, "%lld\n");
 
 static int adis16460_debugfs_init(struct iio_dev *indio_dev)
 {
        struct adis16460 *adis16460 = iio_priv(indio_dev);
 
-       debugfs_create_file("serial_number", 0400, indio_dev->debugfs_dentry,
-               adis16460, &adis16460_serial_number_fops);
-       debugfs_create_file("product_id", 0400, indio_dev->debugfs_dentry,
-               adis16460, &adis16460_product_id_fops);
-       debugfs_create_file("flash_count", 0400, indio_dev->debugfs_dentry,
-               adis16460, &adis16460_flash_count_fops);
+       debugfs_create_file_unsafe("serial_number", 0400,
+                       indio_dev->debugfs_dentry, adis16460,
+                       &adis16460_serial_number_fops);
+       debugfs_create_file_unsafe("product_id", 0400,
+                       indio_dev->debugfs_dentry, adis16460,
+                       &adis16460_product_id_fops);
+       debugfs_create_file_unsafe("flash_count", 0400,
+                       indio_dev->debugfs_dentry, adis16460,
+                       &adis16460_flash_count_fops);
 
        return 0;
 }
index e36f5e82d400d3e1cb728722b3cebc9cb9565730..26398614eddfa1ebb820c2bf063010152a0ba12d 100644 (file)
@@ -24,8 +24,8 @@ static int bmi160_i2c_probe(struct i2c_client *client,
 
        regmap = devm_regmap_init_i2c(client, &bmi160_regmap_config);
        if (IS_ERR(regmap)) {
-               dev_err(&client->dev, "Failed to register i2c regmap %d\n",
-                       (int)PTR_ERR(regmap));
+               dev_err(&client->dev, "Failed to register i2c regmap: %pe\n",
+                       regmap);
                return PTR_ERR(regmap);
        }
 
index c19e3df35559b74f20544feb96c9e09786eae3ef..61389b41c6d9686bb659804d46a39fd2e10007e8 100644 (file)
@@ -20,8 +20,8 @@ static int bmi160_spi_probe(struct spi_device *spi)
 
        regmap = devm_regmap_init_spi(spi, &bmi160_regmap_config);
        if (IS_ERR(regmap)) {
-               dev_err(&spi->dev, "Failed to register spi regmap %d\n",
-                       (int)PTR_ERR(regmap));
+               dev_err(&spi->dev, "Failed to register spi regmap: %pe\n",
+                       regmap);
                return PTR_ERR(regmap);
        }
        return bmi160_core_probe(&spi->dev, regmap, id->name, true);
index 2f8560ba4572eeea21ea3047680b3656199c3616..c27d06035c8b6947ab0f4c4541038f1c1f022e00 100644 (file)
@@ -135,6 +135,7 @@ int inv_mpu_acpi_create_mux_client(struct i2c_client *client)
        st->mux_client = NULL;
        if (ACPI_HANDLE(&client->dev)) {
                struct i2c_board_info info;
+               struct i2c_client *mux_client;
                struct acpi_device *adev;
                int ret = -1;
 
@@ -172,9 +173,10 @@ int inv_mpu_acpi_create_mux_client(struct i2c_client *client)
                        } else
                                return 0; /* no secondary addr, which is OK */
                }
-               st->mux_client = i2c_new_device(st->muxc->adapter[0], &info);
-               if (!st->mux_client)
-                       return -ENODEV;
+               mux_client = i2c_new_client_device(st->muxc->adapter[0], &info);
+               if (IS_ERR(mux_client))
+                       return PTR_ERR(mux_client);
+               st->mux_client = mux_client;
        }
 
        return 0;
index 7cb9ff3d3e940018134b08badc9d3f50ab4cf545..d3819b516ec6c431a321392aa217d3779328a15e 100644 (file)
@@ -526,7 +526,7 @@ static int inv_mpu6050_sensor_set(struct inv_mpu6050_state  *st, int reg,
        __be16 d = cpu_to_be16(val);
 
        ind = (axis - IIO_MOD_X) * 2;
-       result = regmap_bulk_write(st->map, reg + ind, (u8 *)&d, 2);
+       result = regmap_bulk_write(st->map, reg + ind, &d, sizeof(d));
        if (result)
                return -EINVAL;
 
@@ -540,7 +540,7 @@ static int inv_mpu6050_sensor_show(struct inv_mpu6050_state  *st, int reg,
        __be16 d;
 
        ind = (axis - IIO_MOD_X) * 2;
-       result = regmap_bulk_read(st->map, reg + ind, (u8 *)&d, 2);
+       result = regmap_bulk_read(st->map, reg + ind, &d, sizeof(d));
        if (result)
                return -EINVAL;
        *val = (short)be16_to_cpup(&d);
@@ -1248,12 +1248,31 @@ static const struct attribute_group inv_attribute_group = {
        .attrs = inv_attributes
 };
 
+static int inv_mpu6050_reg_access(struct iio_dev *indio_dev,
+                                 unsigned int reg,
+                                 unsigned int writeval,
+                                 unsigned int *readval)
+{
+       struct inv_mpu6050_state *st = iio_priv(indio_dev);
+       int ret;
+
+       mutex_lock(&st->lock);
+       if (readval)
+               ret = regmap_read(st->map, reg, readval);
+       else
+               ret = regmap_write(st->map, reg, writeval);
+       mutex_unlock(&st->lock);
+
+       return ret;
+}
+
 static const struct iio_info mpu_info = {
        .read_raw = &inv_mpu6050_read_raw,
        .write_raw = &inv_mpu6050_write_raw,
        .write_raw_get_fmt = &inv_write_raw_get_fmt,
        .attrs = &inv_attribute_group,
        .validate_trigger = inv_mpu6050_validate_trigger,
+       .debugfs_reg_access = &inv_mpu6050_reg_access,
 };
 
 /**
index 6993d3b87bb0f718fb2c962986cd2eb381f5aead..28cfae1e61cfcd790ffe387b9131c0ab92574e92 100644 (file)
@@ -122,8 +122,8 @@ static int inv_mpu_probe(struct i2c_client *client,
 
        regmap = devm_regmap_init_i2c(client, &inv_mpu_regmap_config);
        if (IS_ERR(regmap)) {
-               dev_err(&client->dev, "Failed to register i2c regmap %d\n",
-                       (int)PTR_ERR(regmap));
+               dev_err(&client->dev, "Failed to register i2c regmap: %pe\n",
+                       regmap);
                return PTR_ERR(regmap);
        }
 
index 673b198e6368fa6e5e0b59ae4d76e0c1b233367f..6f968ce687e111a38e7c40443faf6ea99e7f28d5 100644 (file)
@@ -53,8 +53,8 @@ static int inv_mpu_probe(struct spi_device *spi)
 
        regmap = devm_regmap_init_spi(spi, &inv_mpu_regmap_config);
        if (IS_ERR(regmap)) {
-               dev_err(&spi->dev, "Failed to register spi regmap %d\n",
-                       (int)PTR_ERR(regmap));
+               dev_err(&spi->dev, "Failed to register spi regmap: %pe\n",
+                       regmap);
                return PTR_ERR(regmap);
        }
 
index f2113a63721a8619e57ab685cd28864d3b7f8054..38b613072da2d0810c73ede3dd5b817fb620ab5d 100644 (file)
@@ -111,7 +111,7 @@ struct st_lsm6dsx_odr {
        u8 val;
 };
 
-#define ST_LSM6DSX_ODR_LIST_SIZE       6
+#define ST_LSM6DSX_ODR_LIST_SIZE       8
 struct st_lsm6dsx_odr_table_entry {
        struct st_lsm6dsx_reg reg;
 
index 95ddd19d1aa7c369df3cb488805eed726fc33eb8..947ca3a7dcaf06624c9640f8cb7064536246c3ba 100644 (file)
@@ -88,6 +88,69 @@ static const struct st_lsm6dsx_ext_dev_settings st_lsm6dsx_ext_dev_table[] = {
                        .len = 6,
                },
        },
+       /* LIS3MDL */
+       {
+               .i2c_addr = { 0x1e },
+               .wai = {
+                       .addr = 0x0f,
+                       .val = 0x3d,
+               },
+               .id = ST_LSM6DSX_ID_MAGN,
+               .odr_table = {
+                       .reg = {
+                               .addr = 0x20,
+                               .mask = GENMASK(4, 2),
+                       },
+                       .odr_avl[0] = {  1000, 0x0 },
+                       .odr_avl[1] = {  2000, 0x1 },
+                       .odr_avl[2] = {  3000, 0x2 },
+                       .odr_avl[3] = {  5000, 0x3 },
+                       .odr_avl[4] = { 10000, 0x4 },
+                       .odr_avl[5] = { 20000, 0x5 },
+                       .odr_avl[6] = { 40000, 0x6 },
+                       .odr_avl[7] = { 80000, 0x7 },
+                       .odr_len = 8,
+               },
+               .fs_table = {
+                       .reg = {
+                               .addr = 0x21,
+                               .mask = GENMASK(6, 5),
+                       },
+                       .fs_avl[0] = {
+                               .gain = 146,
+                               .val = 0x00,
+                       }, /* 4000 uG/LSB */
+                       .fs_avl[1] = {
+                               .gain = 292,
+                               .val = 0x01,
+                       }, /* 8000 uG/LSB */
+                       .fs_avl[2] = {
+                               .gain = 438,
+                               .val = 0x02,
+                       }, /* 12000 uG/LSB */
+                       .fs_avl[3] = {
+                               .gain = 584,
+                               .val = 0x03,
+                       }, /* 16000 uG/LSB */
+                       .fs_len = 4,
+               },
+               .pwr_table = {
+                       .reg = {
+                               .addr = 0x22,
+                               .mask = GENMASK(1, 0),
+                       },
+                       .off_val = 0x2,
+                       .on_val = 0x0,
+               },
+               .bdu = {
+                       .addr = 0x24,
+                       .mask = BIT(6),
+               },
+               .out = {
+                       .addr = 0x28,
+                       .len = 6,
+               },
+       },
 };
 
 static void st_lsm6dsx_shub_wait_complete(struct st_lsm6dsx_hw *hw)
@@ -517,6 +580,36 @@ st_lsm6dsx_shub_read_raw(struct iio_dev *iio_dev,
        return ret;
 }
 
+static int
+st_lsm6dsx_shub_set_full_scale(struct st_lsm6dsx_sensor *sensor,
+                              u32 gain)
+{
+       const struct st_lsm6dsx_fs_table_entry *fs_table;
+       int i, err;
+
+       fs_table = &sensor->ext_info.settings->fs_table;
+       if (!fs_table->reg.addr)
+               return -ENOTSUPP;
+
+       for (i = 0; i < fs_table->fs_len; i++) {
+               if (fs_table->fs_avl[i].gain == gain)
+                       break;
+       }
+
+       if (i == fs_table->fs_len)
+               return -EINVAL;
+
+       err = st_lsm6dsx_shub_write_with_mask(sensor, fs_table->reg.addr,
+                                             fs_table->reg.mask,
+                                             fs_table->fs_avl[i].val);
+       if (err < 0)
+               return err;
+
+       sensor->gain = gain;
+
+       return 0;
+}
+
 static int
 st_lsm6dsx_shub_write_raw(struct iio_dev *iio_dev,
                          struct iio_chan_spec const *chan,
@@ -539,6 +632,9 @@ st_lsm6dsx_shub_write_raw(struct iio_dev *iio_dev,
                        sensor->odr = val;
                break;
        }
+       case IIO_CHAN_INFO_SCALE:
+               err = st_lsm6dsx_shub_set_full_scale(sensor, val2);
+               break;
        default:
                err = -EINVAL;
                break;
index 4ada5592aa2b4824468cee15e3a518ddbb3ba925..221157136af6e19ad855b0ae907780917595601a 100644 (file)
@@ -316,8 +316,7 @@ static int iio_scan_mask_set(struct iio_dev *indio_dev,
        const unsigned long *mask;
        unsigned long *trialmask;
 
-       trialmask = kcalloc(BITS_TO_LONGS(indio_dev->masklength),
-                           sizeof(*trialmask), GFP_KERNEL);
+       trialmask = bitmap_zalloc(indio_dev->masklength, GFP_KERNEL);
        if (trialmask == NULL)
                return -ENOMEM;
        if (!indio_dev->masklength) {
@@ -687,6 +686,13 @@ static int iio_verify_update(struct iio_dev *indio_dev,
        bool scan_timestamp;
        unsigned int modes;
 
+       if (insert_buffer &&
+           bitmap_empty(insert_buffer->scan_mask, indio_dev->masklength)) {
+               dev_dbg(&indio_dev->dev,
+                       "At least one scan element must be enabled first\n");
+               return -EINVAL;
+       }
+
        memset(config, 0, sizeof(*config));
        config->watermark = ~0;
 
@@ -1277,11 +1283,6 @@ int iio_buffer_alloc_sysfs_and_mask(struct iio_dev *indio_dev)
 
        indio_dev->groups[indio_dev->groupcounter++] = &buffer->buffer_group;
 
-       if (buffer->scan_el_attrs != NULL) {
-               attr = buffer->scan_el_attrs->attrs;
-               while (*attr++ != NULL)
-                       attrcount_orig++;
-       }
        attrcount = attrcount_orig;
        INIT_LIST_HEAD(&buffer->scan_el_dev_attr_list);
        channels = indio_dev->channels;
@@ -1319,9 +1320,6 @@ int iio_buffer_alloc_sysfs_and_mask(struct iio_dev *indio_dev)
                ret = -ENOMEM;
                goto error_free_scan_mask;
        }
-       if (buffer->scan_el_attrs)
-               memcpy(buffer->scan_el_group.attrs, buffer->scan_el_attrs,
-                      sizeof(buffer->scan_el_group.attrs[0])*attrcount_orig);
        attrn = attrcount_orig;
 
        list_for_each_entry(p, &buffer->scan_el_dev_attr_list, l)
index 2352c426bfb5baf99da6ed5c8b5de8081d45e074..6add449b38bc80730798d58e9021d847e1cdd1b6 100644 (file)
@@ -572,46 +572,46 @@ static ssize_t __iio_format_value(char *buf, size_t len, unsigned int type,
 
        switch (type) {
        case IIO_VAL_INT:
-               return snprintf(buf, len, "%d", vals[0]);
+               return scnprintf(buf, len, "%d", vals[0]);
        case IIO_VAL_INT_PLUS_MICRO_DB:
                scale_db = true;
                /* fall through */
        case IIO_VAL_INT_PLUS_MICRO:
                if (vals[1] < 0)
-                       return snprintf(buf, len, "-%d.%06u%s", abs(vals[0]),
+                       return scnprintf(buf, len, "-%d.%06u%s", abs(vals[0]),
                                        -vals[1], scale_db ? " dB" : "");
                else
-                       return snprintf(buf, len, "%d.%06u%s", vals[0], vals[1],
+                       return scnprintf(buf, len, "%d.%06u%s", vals[0], vals[1],
                                        scale_db ? " dB" : "");
        case IIO_VAL_INT_PLUS_NANO:
                if (vals[1] < 0)
-                       return snprintf(buf, len, "-%d.%09u", abs(vals[0]),
+                       return scnprintf(buf, len, "-%d.%09u", abs(vals[0]),
                                        -vals[1]);
                else
-                       return snprintf(buf, len, "%d.%09u", vals[0], vals[1]);
+                       return scnprintf(buf, len, "%d.%09u", vals[0], vals[1]);
        case IIO_VAL_FRACTIONAL:
                tmp = div_s64((s64)vals[0] * 1000000000LL, vals[1]);
                tmp1 = vals[1];
                tmp0 = (int)div_s64_rem(tmp, 1000000000, &tmp1);
-               return snprintf(buf, len, "%d.%09u", tmp0, abs(tmp1));
+               return scnprintf(buf, len, "%d.%09u", tmp0, abs(tmp1));
        case IIO_VAL_FRACTIONAL_LOG2:
                tmp = shift_right((s64)vals[0] * 1000000000LL, vals[1]);
                tmp0 = (int)div_s64_rem(tmp, 1000000000LL, &tmp1);
-               return snprintf(buf, len, "%d.%09u", tmp0, abs(tmp1));
+               return scnprintf(buf, len, "%d.%09u", tmp0, abs(tmp1));
        case IIO_VAL_INT_MULTIPLE:
        {
                int i;
                int l = 0;
 
                for (i = 0; i < size; ++i) {
-                       l += snprintf(&buf[l], len - l, "%d ", vals[i]);
+                       l += scnprintf(&buf[l], len - l, "%d ", vals[i]);
                        if (l >= len)
                                break;
                }
                return l;
        }
        case IIO_VAL_CHAR:
-               return snprintf(buf, len, "%c", (char)vals[0]);
+               return scnprintf(buf, len, "%c", (char)vals[0]);
        default:
                return 0;
        }
@@ -682,10 +682,10 @@ static ssize_t iio_format_avail_list(char *buf, const int *vals,
                        if (len >= PAGE_SIZE)
                                return -EFBIG;
                        if (i < length - 1)
-                               len += snprintf(buf + len, PAGE_SIZE - len,
+                               len += scnprintf(buf + len, PAGE_SIZE - len,
                                                " ");
                        else
-                               len += snprintf(buf + len, PAGE_SIZE - len,
+                               len += scnprintf(buf + len, PAGE_SIZE - len,
                                                "\n");
                        if (len >= PAGE_SIZE)
                                return -EFBIG;
@@ -698,10 +698,10 @@ static ssize_t iio_format_avail_list(char *buf, const int *vals,
                        if (len >= PAGE_SIZE)
                                return -EFBIG;
                        if (i < length / 2 - 1)
-                               len += snprintf(buf + len, PAGE_SIZE - len,
+                               len += scnprintf(buf + len, PAGE_SIZE - len,
                                                " ");
                        else
-                               len += snprintf(buf + len, PAGE_SIZE - len,
+                               len += scnprintf(buf + len, PAGE_SIZE - len,
                                                "\n");
                        if (len >= PAGE_SIZE)
                                return -EFBIG;
@@ -725,10 +725,10 @@ static ssize_t iio_format_avail_range(char *buf, const int *vals, int type)
                        if (len >= PAGE_SIZE)
                                return -EFBIG;
                        if (i < 2)
-                               len += snprintf(buf + len, PAGE_SIZE - len,
+                               len += scnprintf(buf + len, PAGE_SIZE - len,
                                                " ");
                        else
-                               len += snprintf(buf + len, PAGE_SIZE - len,
+                               len += scnprintf(buf + len, PAGE_SIZE - len,
                                                "]\n");
                        if (len >= PAGE_SIZE)
                                return -EFBIG;
@@ -741,10 +741,10 @@ static ssize_t iio_format_avail_range(char *buf, const int *vals, int type)
                        if (len >= PAGE_SIZE)
                                return -EFBIG;
                        if (i < 2)
-                               len += snprintf(buf + len, PAGE_SIZE - len,
+                               len += scnprintf(buf + len, PAGE_SIZE - len,
                                                " ");
                        else
-                               len += snprintf(buf + len, PAGE_SIZE - len,
+                               len += scnprintf(buf + len, PAGE_SIZE - len,
                                                "]\n");
                        if (len >= PAGE_SIZE)
                                return -EFBIG;
@@ -1552,17 +1552,6 @@ static void devm_iio_device_release(struct device *dev, void *res)
        iio_device_free(*(struct iio_dev **)res);
 }
 
-int devm_iio_device_match(struct device *dev, void *res, void *data)
-{
-       struct iio_dev **r = res;
-       if (!r || !*r) {
-               WARN_ON(!r || !*r);
-               return 0;
-       }
-       return *r == data;
-}
-EXPORT_SYMBOL_GPL(devm_iio_device_match);
-
 /**
  * devm_iio_device_alloc - Resource-managed iio_device_alloc()
  * @dev:               Device to allocate iio_dev for
@@ -1571,9 +1560,6 @@ EXPORT_SYMBOL_GPL(devm_iio_device_match);
  * Managed iio_device_alloc. iio_dev allocated with this function is
  * automatically freed on driver detach.
  *
- * If an iio_dev allocated with this function needs to be freed separately,
- * devm_iio_device_free() must be used.
- *
  * RETURNS:
  * Pointer to allocated iio_dev on success, NULL on failure.
  */
@@ -1598,23 +1584,6 @@ struct iio_dev *devm_iio_device_alloc(struct device *dev, int sizeof_priv)
 }
 EXPORT_SYMBOL_GPL(devm_iio_device_alloc);
 
-/**
- * devm_iio_device_free - Resource-managed iio_device_free()
- * @dev:               Device this iio_dev belongs to
- * @iio_dev:           the iio_dev associated with the device
- *
- * Free iio_dev allocated with devm_iio_device_alloc().
- */
-void devm_iio_device_free(struct device *dev, struct iio_dev *iio_dev)
-{
-       int rc;
-
-       rc = devres_release(dev, devm_iio_device_release,
-                           devm_iio_device_match, iio_dev);
-       WARN_ON(rc);
-}
-EXPORT_SYMBOL_GPL(devm_iio_device_free);
-
 /**
  * iio_chrdev_open() - chrdev file open for buffer access and ioctls
  * @inode:     Inode structure for identifying the device in the file system
@@ -1717,6 +1686,9 @@ int __iio_device_register(struct iio_dev *indio_dev, struct module *this_mod)
 {
        int ret;
 
+       if (!indio_dev->info)
+               return -EINVAL;
+
        indio_dev->driver_module = this_mod;
        /* If the calling driver did not initialize of_node, do it here */
        if (!indio_dev->dev.of_node && indio_dev->dev.parent)
@@ -1729,9 +1701,6 @@ int __iio_device_register(struct iio_dev *indio_dev, struct module *this_mod)
        if (ret < 0)
                return ret;
 
-       if (!indio_dev->info)
-               return -EINVAL;
-
        /* configure elements for the chrdev */
        indio_dev->dev.devt = MKDEV(MAJOR(iio_devt), indio_dev->id);
 
@@ -1836,23 +1805,6 @@ int __devm_iio_device_register(struct device *dev, struct iio_dev *indio_dev,
 }
 EXPORT_SYMBOL_GPL(__devm_iio_device_register);
 
-/**
- * devm_iio_device_unregister - Resource-managed iio_device_unregister()
- * @dev:       Device this iio_dev belongs to
- * @indio_dev: the iio_dev associated with the device
- *
- * Unregister iio_dev registered with devm_iio_device_register().
- */
-void devm_iio_device_unregister(struct device *dev, struct iio_dev *indio_dev)
-{
-       int rc;
-
-       rc = devres_release(dev, devm_iio_device_unreg,
-                           devm_iio_device_match, indio_dev);
-       WARN_ON(rc);
-}
-EXPORT_SYMBOL_GPL(devm_iio_device_unregister);
-
 /**
  * iio_device_claim_direct_mode - Keep device in direct mode
  * @indio_dev: the iio_dev associated with the device
index 3908a9a900354fd0669ef648ba0381795a38eed5..53d1931f6be8b20496a61238bbd1c72426f67ca3 100644 (file)
@@ -585,18 +585,6 @@ static void devm_iio_trigger_release(struct device *dev, void *res)
        iio_trigger_free(*(struct iio_trigger **)res);
 }
 
-static int devm_iio_trigger_match(struct device *dev, void *res, void *data)
-{
-       struct iio_trigger **r = res;
-
-       if (!r || !*r) {
-               WARN_ON(!r || !*r);
-               return 0;
-       }
-
-       return *r == data;
-}
-
 /**
  * devm_iio_trigger_alloc - Resource-managed iio_trigger_alloc()
  * @dev:               Device to allocate iio_trigger for
@@ -608,9 +596,6 @@ static int devm_iio_trigger_match(struct device *dev, void *res, void *data)
  * Managed iio_trigger_alloc.  iio_trigger allocated with this function is
  * automatically freed on driver detach.
  *
- * If an iio_trigger allocated with this function needs to be freed separately,
- * devm_iio_trigger_free() must be used.
- *
  * RETURNS:
  * Pointer to allocated iio_trigger on success, NULL on failure.
  */
@@ -640,23 +625,6 @@ struct iio_trigger *devm_iio_trigger_alloc(struct device *dev,
 }
 EXPORT_SYMBOL_GPL(devm_iio_trigger_alloc);
 
-/**
- * devm_iio_trigger_free - Resource-managed iio_trigger_free()
- * @dev:               Device this iio_dev belongs to
- * @iio_trig:          the iio_trigger associated with the device
- *
- * Free iio_trigger allocated with devm_iio_trigger_alloc().
- */
-void devm_iio_trigger_free(struct device *dev, struct iio_trigger *iio_trig)
-{
-       int rc;
-
-       rc = devres_release(dev, devm_iio_trigger_release,
-                           devm_iio_trigger_match, iio_trig);
-       WARN_ON(rc);
-}
-EXPORT_SYMBOL_GPL(devm_iio_trigger_free);
-
 static void devm_iio_trigger_unreg(struct device *dev, void *res)
 {
        iio_trigger_unregister(*(struct iio_trigger **)res);
@@ -673,9 +641,6 @@ static void devm_iio_trigger_unreg(struct device *dev, void *res)
  * calls iio_trigger_register() internally. Refer to that function for more
  * information.
  *
- * If an iio_trigger registered with this function needs to be unregistered
- * separately, devm_iio_trigger_unregister() must be used.
- *
  * RETURNS:
  * 0 on success, negative error number on failure.
  */
@@ -701,24 +666,6 @@ int __devm_iio_trigger_register(struct device *dev,
 }
 EXPORT_SYMBOL_GPL(__devm_iio_trigger_register);
 
-/**
- * devm_iio_trigger_unregister - Resource-managed iio_trigger_unregister()
- * @dev:       device this iio_trigger belongs to
- * @trig_info: the trigger associated with the device
- *
- * Unregister trigger registered with devm_iio_trigger_register().
- */
-void devm_iio_trigger_unregister(struct device *dev,
-                                struct iio_trigger *trig_info)
-{
-       int rc;
-
-       rc = devres_release(dev, devm_iio_trigger_unreg, devm_iio_trigger_match,
-                           trig_info);
-       WARN_ON(rc);
-}
-EXPORT_SYMBOL_GPL(devm_iio_trigger_unregister);
-
 bool iio_trigger_using_own(struct iio_dev *indio_dev)
 {
        return indio_dev->trig->attached_own_device;
index 5a8351c9a426591b9374445b4cc1182aeed2c2f9..ede99e0d53714d4d7d9dce825c8551598d3d7f5a 100644 (file)
@@ -360,18 +360,6 @@ static void devm_iio_channel_free(struct device *dev, void *res)
        iio_channel_release(channel);
 }
 
-static int devm_iio_channel_match(struct device *dev, void *res, void *data)
-{
-       struct iio_channel **r = res;
-
-       if (!r || !*r) {
-               WARN_ON(!r || !*r);
-               return 0;
-       }
-
-       return *r == data;
-}
-
 struct iio_channel *devm_iio_channel_get(struct device *dev,
                                         const char *channel_name)
 {
@@ -394,13 +382,6 @@ struct iio_channel *devm_iio_channel_get(struct device *dev,
 }
 EXPORT_SYMBOL_GPL(devm_iio_channel_get);
 
-void devm_iio_channel_release(struct device *dev, struct iio_channel *channel)
-{
-       WARN_ON(devres_release(dev, devm_iio_channel_free,
-                              devm_iio_channel_match, channel));
-}
-EXPORT_SYMBOL_GPL(devm_iio_channel_release);
-
 struct iio_channel *iio_channel_get_all(struct device *dev)
 {
        const char *name;
@@ -514,14 +495,6 @@ struct iio_channel *devm_iio_channel_get_all(struct device *dev)
 }
 EXPORT_SYMBOL_GPL(devm_iio_channel_get_all);
 
-void devm_iio_channel_release_all(struct device *dev,
-                                 struct iio_channel *channels)
-{
-       WARN_ON(devres_release(dev, devm_iio_channel_free_all,
-                              devm_iio_channel_match, channels));
-}
-EXPORT_SYMBOL_GPL(devm_iio_channel_release_all);
-
 static int iio_channel_read(struct iio_channel *chan, int *val, int *val2,
        enum iio_chan_info_enum info)
 {
index e37894f0ae0b6ac8748f1479c657c9fbf8c00e87..95611f5eff01a892d7c66d2fef5ebaaa6bca9117 100644 (file)
@@ -213,13 +213,24 @@ static const struct iio_info isl29125_info = {
        .attrs = &isl29125_attribute_group,
 };
 
-static int isl29125_buffer_preenable(struct iio_dev *indio_dev)
+static int isl29125_buffer_postenable(struct iio_dev *indio_dev)
 {
        struct isl29125_data *data = iio_priv(indio_dev);
+       int err;
+
+       err = iio_triggered_buffer_postenable(indio_dev);
+       if (err)
+               return err;
 
        data->conf1 |= ISL29125_MODE_RGB;
-       return i2c_smbus_write_byte_data(data->client, ISL29125_CONF1,
+       err = i2c_smbus_write_byte_data(data->client, ISL29125_CONF1,
                data->conf1);
+       if (err) {
+               iio_triggered_buffer_predisable(indio_dev);
+               return err;
+       }
+
+       return 0;
 }
 
 static int isl29125_buffer_predisable(struct iio_dev *indio_dev)
@@ -227,19 +238,18 @@ static int isl29125_buffer_predisable(struct iio_dev *indio_dev)
        struct isl29125_data *data = iio_priv(indio_dev);
        int ret;
 
-       ret = iio_triggered_buffer_predisable(indio_dev);
-       if (ret < 0)
-               return ret;
-
        data->conf1 &= ~ISL29125_MODE_MASK;
        data->conf1 |= ISL29125_MODE_PD;
-       return i2c_smbus_write_byte_data(data->client, ISL29125_CONF1,
+       ret = i2c_smbus_write_byte_data(data->client, ISL29125_CONF1,
                data->conf1);
+
+       iio_triggered_buffer_predisable(indio_dev);
+
+       return ret;
 }
 
 static const struct iio_buffer_setup_ops isl29125_buffer_setup_ops = {
-       .preenable = isl29125_buffer_preenable,
-       .postenable = &iio_triggered_buffer_postenable,
+       .postenable = isl29125_buffer_postenable,
        .predisable = isl29125_buffer_predisable,
 };
 
index 71f99d2a22c1ddf2994100d7a9e54752ba4d0163..0626927251bb5a31d2a99cc83da1995f7ddb1e95 100644 (file)
@@ -1263,7 +1263,7 @@ static irqreturn_t ltr501_trigger_handler(int irq, void *p)
 
        if (mask & LTR501_STATUS_ALS_RDY) {
                ret = regmap_bulk_read(data->regmap, LTR501_ALS_DATA1,
-                                      (u8 *)als_buf, sizeof(als_buf));
+                                      als_buf, sizeof(als_buf));
                if (ret < 0)
                        return ret;
                if (test_bit(0, indio_dev->active_scan_mask))
index 4889bbeb0c735fe8323da0e87c18fe8fde0c995c..400724069d1910554be7e3dadc5e7f34e40c27f2 100644 (file)
@@ -31,8 +31,8 @@ static int st_uvis25_i2c_probe(struct i2c_client *client,
 
        regmap = devm_regmap_init_i2c(client, &st_uvis25_i2c_regmap_config);
        if (IS_ERR(regmap)) {
-               dev_err(&client->dev, "Failed to register i2c regmap %d\n",
-                       (int)PTR_ERR(regmap));
+               dev_err(&client->dev, "Failed to register i2c regmap %ld\n",
+                       PTR_ERR(regmap));
                return PTR_ERR(regmap);
        }
 
index a9ceae4f58b3da30b575c45f248b8c8b4bc232b2..cd3761a3ee3f4aaf09f20b69b4b69a2509559d2f 100644 (file)
@@ -31,8 +31,8 @@ static int st_uvis25_spi_probe(struct spi_device *spi)
 
        regmap = devm_regmap_init_spi(spi, &st_uvis25_spi_regmap_config);
        if (IS_ERR(regmap)) {
-               dev_err(&spi->dev, "Failed to register spi regmap %d\n",
-                       (int)PTR_ERR(regmap));
+               dev_err(&spi->dev, "Failed to register spi regmap %ld\n",
+                       PTR_ERR(regmap));
                return PTR_ERR(regmap);
        }
 
index d8c40a83097d3c0e856ba3214df4ab73a26e1140..27a5c28aac7f25ff0d0be7f6bc283471f67be2ee 100644 (file)
@@ -69,7 +69,7 @@
 #define TSL2563_TIMING_GAIN16  0x10
 #define TSL2563_TIMING_GAIN1   0x00
 
-#define TSL2563_INT_DISBLED    0x00
+#define TSL2563_INT_DISABLED   0x00
 #define TSL2563_INT_LEVEL      0x10
 #define TSL2563_INT_PERSIST(n) ((n) & 0x0F)
 
index be37fcbd4654ea6a4fea5248686069d16b64425c..9fbde9b71b63cdde71b79babdc306da1278ac20c 100644 (file)
@@ -932,7 +932,7 @@ static ssize_t in_illuminance0_target_input_show(struct device *dev,
 {
        struct tsl2772_chip *chip = iio_priv(dev_to_iio_dev(dev));
 
-       return snprintf(buf, PAGE_SIZE, "%d\n", chip->settings.als_cal_target);
+       return scnprintf(buf, PAGE_SIZE, "%d\n", chip->settings.als_cal_target);
 }
 
 static ssize_t in_illuminance0_target_input_store(struct device *dev,
@@ -986,7 +986,7 @@ static ssize_t in_illuminance0_lux_table_show(struct device *dev,
        int offset = 0;
 
        while (i < TSL2772_MAX_LUX_TABLE_SIZE) {
-               offset += snprintf(buf + offset, PAGE_SIZE, "%u,%u,",
+               offset += scnprintf(buf + offset, PAGE_SIZE - offset, "%u,%u,",
                        chip->tsl2772_device_lux[i].ch0,
                        chip->tsl2772_device_lux[i].ch1);
                if (chip->tsl2772_device_lux[i].ch0 == 0) {
@@ -1000,7 +1000,7 @@ static ssize_t in_illuminance0_lux_table_show(struct device *dev,
                i++;
        }
 
-       offset += snprintf(buf + offset, PAGE_SIZE, "\n");
+       offset += scnprintf(buf + offset, PAGE_SIZE - offset, "\n");
        return offset;
 }
 
index ec803c1e81df2b932594568dc6b4f5405efb9a79..985cc39ede8e1f6a87795218649da351f71d3466 100644 (file)
@@ -83,6 +83,7 @@ struct vcnl4000_data {
        struct mutex vcnl4000_lock;
        struct vcnl4200_channel vcnl4200_al;
        struct vcnl4200_channel vcnl4200_ps;
+       uint32_t near_level;
 };
 
 struct vcnl4000_chip_spec {
@@ -343,6 +344,25 @@ static const struct vcnl4000_chip_spec vcnl4000_chip_spec_cfg[] = {
        },
 };
 
+static ssize_t vcnl4000_read_near_level(struct iio_dev *indio_dev,
+                                       uintptr_t priv,
+                                       const struct iio_chan_spec *chan,
+                                       char *buf)
+{
+       struct vcnl4000_data *data = iio_priv(indio_dev);
+
+       return sprintf(buf, "%u\n", data->near_level);
+}
+
+static const struct iio_chan_spec_ext_info vcnl4000_ext_info[] = {
+       {
+               .name = "nearlevel",
+               .shared = IIO_SEPARATE,
+               .read = vcnl4000_read_near_level,
+       },
+       { /* sentinel */ }
+};
+
 static const struct iio_chan_spec vcnl4000_channels[] = {
        {
                .type = IIO_LIGHT,
@@ -351,6 +371,7 @@ static const struct iio_chan_spec vcnl4000_channels[] = {
        }, {
                .type = IIO_PROXIMITY,
                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+               .ext_info = vcnl4000_ext_info,
        }
 };
 
@@ -440,6 +461,10 @@ static int vcnl4000_probe(struct i2c_client *client,
        dev_dbg(&client->dev, "%s Ambient light/proximity sensor, Rev: %02x\n",
                data->chip_spec->prod, data->rev);
 
+       if (device_property_read_u32(&client->dev, "proximity-near-level",
+                                    &data->near_level))
+               data->near_level = 0;
+
        indio_dev->dev.parent = &client->dev;
        indio_dev->info = &vcnl4000_info;
        indio_dev->channels = vcnl4000_channels;
index d3299670211035236a20cc0ee83130a9dbb4c904..372c80c25dd4f4c5c96f2429cf7972f609e5d112 100644 (file)
@@ -746,7 +746,12 @@ static int ak8974_probe(struct i2c_client *i2c,
                                      ARRAY_SIZE(ak8974->regs),
                                      ak8974->regs);
        if (ret < 0) {
-               dev_err(&i2c->dev, "cannot get regulators\n");
+               if (ret != -EPROBE_DEFER)
+                       dev_err(&i2c->dev, "cannot get regulators: %d\n", ret);
+               else
+                       dev_dbg(&i2c->dev,
+                               "regulators unavailable, deferring probe\n");
+
                return ret;
        }
 
index ed9be0490d7792a103a0cfe9995a718f33d351f8..c6ed3ea8460ae42156b094f71fbe69fe7a9e7426 100644 (file)
@@ -22,8 +22,8 @@ static int bmc150_magn_spi_probe(struct spi_device *spi)
 
        regmap = devm_regmap_init_spi(spi, &bmc150_magn_regmap_config);
        if (IS_ERR(regmap)) {
-               dev_err(&spi->dev, "Failed to register spi regmap %d\n",
-                       (int)PTR_ERR(regmap));
+               dev_err(&spi->dev, "Failed to register spi regmap: %pe\n",
+                       regmap);
                return PTR_ERR(regmap);
        }
        return bmc150_magn_probe(&spi->dev, regmap, spi->irq, id->name);
index 425cdd07b4e573b8ca62a30a26853fcd44dc7098..1787d656d009462b0d35588294ce8322d306aa8f 100644 (file)
@@ -239,7 +239,7 @@ static int mmc35240_init(struct mmc35240_data *data)
                return ret;
 
        ret = regmap_bulk_read(data->regmap, MMC35240_OTP_START_ADDR,
-                              (u8 *)otp_data, sizeof(otp_data));
+                              otp_data, sizeof(otp_data));
        if (ret < 0)
                return ret;
 
@@ -295,7 +295,7 @@ static int mmc35240_read_measurement(struct mmc35240_data *data, __le16 buf[3])
        if (ret < 0)
                return ret;
 
-       return regmap_bulk_read(data->regmap, MMC35240_REG_XOUT_L, (u8 *)buf,
+       return regmap_bulk_read(data->regmap, MMC35240_REG_XOUT_L, buf,
                                3 * sizeof(__le16));
 }
 
index e68184a93a6d5374b30b036004b3415609441411..79de721e60159cdc6d7b1271e1abac2dd492364a 100644 (file)
@@ -506,8 +506,7 @@ int st_magn_common_probe(struct iio_dev *indio_dev)
        indio_dev->channels = mdata->sensor_settings->ch;
        indio_dev->num_channels = ST_SENSORS_NUMBER_ALL_CHANNELS;
 
-       mdata->current_fullscale = (struct st_sensor_fullscale_avl *)
-                                       &mdata->sensor_settings->fs.fs_avl[0];
+       mdata->current_fullscale = &mdata->sensor_settings->fs.fs_avl[0];
        mdata->odr = mdata->sensor_settings->odr.odr_avl[0].hz;
 
        err = st_sensors_init_sensor(indio_dev, NULL);
index 29c209cc1108e2e573fb446a5aa60bcb0b379f22..a3304839011892d972acf9978bf743d1d8933146 100644 (file)
@@ -337,8 +337,7 @@ static int bmp280_read_temp(struct bmp280_data *data,
        __be32 tmp = 0;
        s32 adc_temp, comp_temp;
 
-       ret = regmap_bulk_read(data->regmap, BMP280_REG_TEMP_MSB,
-                              (u8 *) &tmp, 3);
+       ret = regmap_bulk_read(data->regmap, BMP280_REG_TEMP_MSB, &tmp, 3);
        if (ret < 0) {
                dev_err(data->dev, "failed to read temperature\n");
                return ret;
@@ -377,8 +376,7 @@ static int bmp280_read_press(struct bmp280_data *data,
        if (ret < 0)
                return ret;
 
-       ret = regmap_bulk_read(data->regmap, BMP280_REG_PRESS_MSB,
-                              (u8 *) &tmp, 3);
+       ret = regmap_bulk_read(data->regmap, BMP280_REG_PRESS_MSB, &tmp, 3);
        if (ret < 0) {
                dev_err(data->dev, "failed to read pressure\n");
                return ret;
@@ -400,8 +398,8 @@ static int bmp280_read_press(struct bmp280_data *data,
 
 static int bmp280_read_humid(struct bmp280_data *data, int *val, int *val2)
 {
+       __be16 tmp;
        int ret;
-       __be16 tmp = 0;
        s32 adc_humidity;
        u32 comp_humidity;
 
@@ -410,8 +408,7 @@ static int bmp280_read_humid(struct bmp280_data *data, int *val, int *val2)
        if (ret < 0)
                return ret;
 
-       ret = regmap_bulk_read(data->regmap, BMP280_REG_HUMIDITY_MSB,
-                              (u8 *) &tmp, 2);
+       ret = regmap_bulk_read(data->regmap, BMP280_REG_HUMIDITY_MSB, &tmp, 2);
        if (ret < 0) {
                dev_err(data->dev, "failed to read humidity\n");
                return ret;
@@ -575,57 +572,38 @@ static int bmp280_write_raw(struct iio_dev *indio_dev,
        return ret;
 }
 
-static ssize_t bmp280_show_avail(char *buf, const int *vals, const int n)
+static int bmp280_read_avail(struct iio_dev *indio_dev,
+                            struct iio_chan_spec const *chan,
+                            const int **vals, int *type, int *length,
+                            long mask)
 {
-       size_t len = 0;
-       int i;
-
-       for (i = 0; i < n; i++)
-               len += scnprintf(buf + len, PAGE_SIZE - len, "%d ", vals[i]);
-
-       buf[len - 1] = '\n';
-
-       return len;
-}
-
-static ssize_t bmp280_show_temp_oversampling_avail(struct device *dev,
-                               struct device_attribute *attr, char *buf)
-{
-       struct bmp280_data *data = iio_priv(dev_to_iio_dev(dev));
-
-       return bmp280_show_avail(buf, data->chip_info->oversampling_temp_avail,
-                                data->chip_info->num_oversampling_temp_avail);
-}
-
-static ssize_t bmp280_show_press_oversampling_avail(struct device *dev,
-                               struct device_attribute *attr, char *buf)
-{
-       struct bmp280_data *data = iio_priv(dev_to_iio_dev(dev));
+       struct bmp280_data *data = iio_priv(indio_dev);
 
-       return bmp280_show_avail(buf, data->chip_info->oversampling_press_avail,
-                                data->chip_info->num_oversampling_press_avail);
+       switch (mask) {
+       case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
+               switch (chan->type) {
+               case IIO_PRESSURE:
+                       *vals = data->chip_info->oversampling_press_avail;
+                       *length = data->chip_info->num_oversampling_press_avail;
+                       break;
+               case IIO_TEMP:
+                       *vals = data->chip_info->oversampling_temp_avail;
+                       *length = data->chip_info->num_oversampling_temp_avail;
+                       break;
+               default:
+                       return -EINVAL;
+               }
+               *type = IIO_VAL_INT;
+               return IIO_AVAIL_LIST;
+       default:
+               return -EINVAL;
+       }
 }
 
-static IIO_DEVICE_ATTR(in_temp_oversampling_ratio_available,
-       S_IRUGO, bmp280_show_temp_oversampling_avail, NULL, 0);
-
-static IIO_DEVICE_ATTR(in_pressure_oversampling_ratio_available,
-       S_IRUGO, bmp280_show_press_oversampling_avail, NULL, 0);
-
-static struct attribute *bmp280_attributes[] = {
-       &iio_dev_attr_in_temp_oversampling_ratio_available.dev_attr.attr,
-       &iio_dev_attr_in_pressure_oversampling_ratio_available.dev_attr.attr,
-       NULL,
-};
-
-static const struct attribute_group bmp280_attrs_group = {
-       .attrs = bmp280_attributes,
-};
-
 static const struct iio_info bmp280_info = {
        .read_raw = &bmp280_read_raw,
+       .read_avail = &bmp280_read_avail,
        .write_raw = &bmp280_write_raw,
-       .attrs = &bmp280_attrs_group,
 };
 
 static int bmp280_chip_config(struct bmp280_data *data)
@@ -713,7 +691,7 @@ static int bmp180_measure(struct bmp280_data *data, u8 ctrl_meas)
        unsigned int ctrl;
 
        if (data->use_eoc)
-               init_completion(&data->done);
+               reinit_completion(&data->done);
 
        ret = regmap_write(data->regmap, BMP280_REG_CTRL_MEAS, ctrl_meas);
        if (ret)
@@ -752,14 +730,14 @@ static int bmp180_measure(struct bmp280_data *data, u8 ctrl_meas)
 
 static int bmp180_read_adc_temp(struct bmp280_data *data, int *val)
 {
+       __be16 tmp;
        int ret;
-       __be16 tmp = 0;
 
        ret = bmp180_measure(data, BMP180_MEAS_TEMP);
        if (ret)
                return ret;
 
-       ret = regmap_bulk_read(data->regmap, BMP180_REG_OUT_MSB, (u8 *)&tmp, 2);
+       ret = regmap_bulk_read(data->regmap, BMP180_REG_OUT_MSB, &tmp, 2);
        if (ret)
                return ret;
 
@@ -856,7 +834,7 @@ static int bmp180_read_adc_press(struct bmp280_data *data, int *val)
        if (ret)
                return ret;
 
-       ret = regmap_bulk_read(data->regmap, BMP180_REG_OUT_MSB, (u8 *)&tmp, 3);
+       ret = regmap_bulk_read(data->regmap, BMP180_REG_OUT_MSB, &tmp, 3);
        if (ret)
                return ret;
 
@@ -965,10 +943,12 @@ static int bmp085_fetch_eoc_irq(struct device *dev,
 
        irq_trig = irqd_get_trigger_type(irq_get_irq_data(irq));
        if (irq_trig != IRQF_TRIGGER_RISING) {
-               dev_err(dev, "non-rising trigger given for EOC interrupt, "
-                       "trying to enforce it\n");
+               dev_err(dev, "non-rising trigger given for EOC interrupt, trying to enforce it\n");
                irq_trig = IRQF_TRIGGER_RISING;
        }
+
+       init_completion(&data->done);
+
        ret = devm_request_threaded_irq(dev,
                        irq,
                        bmp085_eoc_irq,
@@ -1082,9 +1062,9 @@ int bmp280_common_probe(struct device *dev,
        usleep_range(data->start_up_time, data->start_up_time + 100);
 
        /* Bring chip out of reset if there is an assigned GPIO line */
-       gpiod = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
+       gpiod = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
        /* Deassert the signal */
-       if (!IS_ERR(gpiod)) {
+       if (gpiod) {
                dev_info(dev, "release reset\n");
                gpiod_set_value(gpiod, 0);
        }
index bd972cec48302719759017fdb9767b67b1f80388..789a2928504a729c73dd1f2d26a06756909cd7ef 100644 (file)
@@ -683,8 +683,7 @@ EXPORT_SYMBOL(st_press_get_settings);
 int st_press_common_probe(struct iio_dev *indio_dev)
 {
        struct st_sensor_data *press_data = iio_priv(indio_dev);
-       struct st_sensors_platform_data *pdata =
-               (struct st_sensors_platform_data *)press_data->dev->platform_data;
+       struct st_sensors_platform_data *pdata = dev_get_platdata(press_data->dev);
        int err;
 
        indio_dev->modes = INDIO_DIRECT_MODE;
@@ -708,9 +707,7 @@ int st_press_common_probe(struct iio_dev *indio_dev)
        indio_dev->channels = press_data->sensor_settings->ch;
        indio_dev->num_channels = press_data->sensor_settings->num_ch;
 
-       press_data->current_fullscale =
-               (struct st_sensor_fullscale_avl *)
-                       &press_data->sensor_settings->fs.fs_avl[0];
+       press_data->current_fullscale = &press_data->sensor_settings->fs.fs_avl[0];
 
        press_data->odr = press_data->sensor_settings->odr.odr_avl[0].hz;
 
index 37606d400805a9bdf79bd647716caa07b356925e..d57e8cc17e42d661a8440129268d9af21be6cece 100644 (file)
@@ -101,6 +101,19 @@ config SRF04
          To compile this driver as a module, choose M here: the
          module will be called srf04.
 
+config SX9310
+       tristate "SX9310/SX9311 Semtech proximity sensor"
+       select IIO_BUFFER
+       select IIO_TRIGGERED_BUFFER
+       select REGMAP_I2C
+       depends on I2C
+       help
+         Say Y here to build a driver for Semtech's SX9310/SX9311 capacitive
+         proximity/button sensor.
+
+         To compile this driver as a module, choose M here: the
+         module will be called sx9310.
+
 config SX9500
        tristate "SX9500 Semtech proximity sensor"
        select IIO_BUFFER
index c591b019304e7f585cdf803f6b7987663db0ec8d..25e5a04da101c5f7135eb9ba5446464e475cd8bc 100644 (file)
@@ -12,6 +12,7 @@ obj-$(CONFIG_PING)            += ping.o
 obj-$(CONFIG_RFD77402)         += rfd77402.o
 obj-$(CONFIG_SRF04)            += srf04.o
 obj-$(CONFIG_SRF08)            += srf08.o
+obj-$(CONFIG_SX9310)           += sx9310.o
 obj-$(CONFIG_SX9500)           += sx9500.o
 obj-$(CONFIG_VL53L0X_I2C)      += vl53l0x-i2c.o
 
diff --git a/drivers/iio/proximity/sx9310.c b/drivers/iio/proximity/sx9310.c
new file mode 100644 (file)
index 0000000..d161f30
--- /dev/null
@@ -0,0 +1,1069 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2018 Google LLC.
+ *
+ * Driver for Semtech's SX9310/SX9311 capacitive proximity/button solution.
+ * Based on SX9500 driver and Semtech driver using the input framework
+ * <https://my.syncplicity.com/share/teouwsim8niiaud/
+ *          linux-driver-SX9310_NoSmartHSensing>.
+ * Reworked April 2019 by Evan Green <evgreen@chromium.org>
+ * and January 2020 by Daniel Campello <campello@chromium.org>
+ */
+
+#include <linux/acpi.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/pm.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+
+#include <linux/iio/buffer.h>
+#include <linux/iio/events.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/trigger.h>
+#include <linux/iio/triggered_buffer.h>
+#include <linux/iio/trigger_consumer.h>
+
+/* Register definitions. */
+#define SX9310_REG_IRQ_SRC                             0x00
+#define SX9310_REG_STAT0                               0x01
+#define SX9310_REG_STAT1                               0x02
+#define SX9310_REG_IRQ_MSK                             0x03
+#define   SX9310_CONVDONE_IRQ                          BIT(3)
+#define   SX9310_FAR_IRQ                               BIT(5)
+#define   SX9310_CLOSE_IRQ                             BIT(6)
+#define   SX9310_EVENT_IRQ                             (SX9310_FAR_IRQ | \
+                                                        SX9310_CLOSE_IRQ)
+#define SX9310_REG_IRQ_FUNC                            0x04
+
+#define SX9310_REG_PROX_CTRL0                          0x10
+#define   SX9310_REG_PROX_CTRL0_PROXSTAT2              0x10
+#define   SX9310_REG_PROX_CTRL0_EN_MASK                        0x0F
+#define SX9310_REG_PROX_CTRL1                          0x11
+#define SX9310_REG_PROX_CTRL2                          0x12
+#define   SX9310_REG_PROX_CTRL2_COMBMODE_ALL           0x80
+#define   SX9310_REG_PROX_CTRL2_SHIELDEN_DYNAMIC       0x04
+#define SX9310_REG_PROX_CTRL3                          0x13
+#define   SX9310_REG_PROX_CTRL3_GAIN0_X8               0x0c
+#define   SX9310_REG_PROX_CTRL3_GAIN12_X4              0x02
+#define SX9310_REG_PROX_CTRL4                          0x14
+#define   SX9310_REG_PROX_CTRL4_RESOLUTION_FINEST      0x07
+#define SX9310_REG_PROX_CTRL5                          0x15
+#define   SX9310_REG_PROX_CTRL5_RANGE_SMALL            0xc0
+#define   SX9310_REG_PROX_CTRL5_STARTUPSENS_CS1                0x04
+#define   SX9310_REG_PROX_CTRL5_RAWFILT_1P25           0x02
+#define SX9310_REG_PROX_CTRL6                          0x16
+#define   SX9310_REG_PROX_CTRL6_COMP_COMMON            0x20
+#define SX9310_REG_PROX_CTRL7                          0x17
+#define   SX9310_REG_PROX_CTRL7_AVGNEGFILT_2           0x08
+#define   SX9310_REG_PROX_CTRL7_AVGPOSFILT_512         0x05
+#define SX9310_REG_PROX_CTRL8                          0x18
+#define SX9310_REG_PROX_CTRL9                          0x19
+#define   SX9310_REG_PROX_CTRL8_9_PTHRESH12_28         0x40
+#define   SX9310_REG_PROX_CTRL8_9_PTHRESH_96           0x88
+#define   SX9310_REG_PROX_CTRL8_9_BODYTHRESH_900       0x03
+#define   SX9310_REG_PROX_CTRL8_9_BODYTHRESH_1500      0x05
+#define SX9310_REG_PROX_CTRL10                         0x1a
+#define   SX9310_REG_PROX_CTRL10_HYST_6PCT             0x10
+#define   SX9310_REG_PROX_CTRL10_CLOSE_DEBOUNCE_8      0x12
+#define   SX9310_REG_PROX_CTRL10_FAR_DEBOUNCE_8                0x03
+#define SX9310_REG_PROX_CTRL11                         0x1b
+#define SX9310_REG_PROX_CTRL12                         0x1c
+#define SX9310_REG_PROX_CTRL13                         0x1d
+#define SX9310_REG_PROX_CTRL14                         0x1e
+#define SX9310_REG_PROX_CTRL15                         0x1f
+#define SX9310_REG_PROX_CTRL16                         0x20
+#define SX9310_REG_PROX_CTRL17                         0x21
+#define SX9310_REG_PROX_CTRL18                         0x22
+#define SX9310_REG_PROX_CTRL19                         0x23
+#define SX9310_REG_SAR_CTRL0                           0x2a
+#define   SX9310_REG_SAR_CTRL0_SARDEB_4_SAMPLES                0x40
+#define   SX9310_REG_SAR_CTRL0_SARHYST_8               0x10
+#define SX9310_REG_SAR_CTRL1                           0x2b
+/* Each increment of the slope register is 0.0078125. */
+#define   SX9310_REG_SAR_CTRL1_SLOPE(_hnslope)         (_hnslope / 78125)
+#define SX9310_REG_SAR_CTRL2                           0x2c
+#define   SX9310_REG_SAR_CTRL2_SAROFFSET_DEFAULT       0x3c
+
+#define SX9310_REG_SENSOR_SEL                          0x30
+
+#define SX9310_REG_USE_MSB                             0x31
+#define SX9310_REG_USE_LSB                             0x32
+
+#define SX9310_REG_AVG_MSB                             0x33
+#define SX9310_REG_AVG_LSB                             0x34
+
+#define SX9310_REG_DIFF_MSB                            0x35
+#define SX9310_REG_DIFF_LSB                            0x36
+
+#define SX9310_REG_OFFSET_MSB                          0x37
+#define SX9310_REG_OFFSET_LSB                          0x38
+
+#define SX9310_REG_SAR_MSB                             0x39
+#define SX9310_REG_SAR_LSB                             0x3a
+
+#define SX9310_REG_I2CADDR                             0x40
+#define SX9310_REG_PAUSE                               0x41
+#define SX9310_REG_WHOAMI                              0x42
+#define   SX9310_WHOAMI_VALUE                          0x01
+#define   SX9311_WHOAMI_VALUE                          0x02
+
+#define SX9310_REG_RESET                               0x7f
+#define   SX9310_SOFT_RESET                            0xde
+
+#define SX9310_SCAN_PERIOD_MASK                                GENMASK(7, 4)
+#define SX9310_SCAN_PERIOD_SHIFT                       4
+
+#define SX9310_COMPSTAT_MASK                           GENMASK(3, 0)
+
+/* 4 hardware channels, as defined in STAT0: COMB, CS2, CS1 and CS0. */
+#define SX9310_NUM_CHANNELS                            4
+#define SX9310_CHAN_ENABLED_MASK                       GENMASK(3, 0)
+
+struct sx9310_data {
+       /* Serialize access to registers and channel configuration */
+       struct mutex mutex;
+       struct i2c_client *client;
+       struct iio_trigger *trig;
+       struct regmap *regmap;
+       /*
+        * Last reading of the proximity status for each channel.
+        * We only send an event to user space when this changes.
+        */
+       bool prox_stat[SX9310_NUM_CHANNELS];
+       bool trigger_enabled;
+       __be16 buffer[SX9310_NUM_CHANNELS +
+                     4]; /* 64-bit data + 64-bit timestamp */
+       /* Remember enabled channels and sample rate during suspend. */
+       unsigned int suspend_ctrl0;
+       struct completion completion;
+       unsigned int chan_read, chan_event;
+       int channel_users[SX9310_NUM_CHANNELS];
+       int whoami;
+};
+
+static const struct iio_event_spec sx9310_events[] = {
+       {
+               .type = IIO_EV_TYPE_THRESH,
+               .dir = IIO_EV_DIR_EITHER,
+               .mask_separate = BIT(IIO_EV_INFO_ENABLE),
+       },
+};
+
+#define SX9310_NAMED_CHANNEL(idx, name)                                         \
+       {                                                                \
+               .type = IIO_PROXIMITY,                                   \
+               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),            \
+               .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
+               .indexed = 1,                                            \
+               .channel = idx,                                          \
+               .extend_name = name,                                     \
+               .address = SX9310_REG_DIFF_MSB,                          \
+               .event_spec = sx9310_events,                             \
+               .num_event_specs = ARRAY_SIZE(sx9310_events),            \
+               .scan_index = idx,                                       \
+               .scan_type = {                                           \
+                       .sign = 's',                                     \
+                       .realbits = 12,                                  \
+                       .storagebits = 16,                               \
+                       .endianness = IIO_BE,                            \
+               },                                                       \
+       }
+#define SX9310_CHANNEL(idx) SX9310_NAMED_CHANNEL(idx, NULL)
+
+static const struct iio_chan_spec sx9310_channels[] = {
+       SX9310_CHANNEL(0),                      /* CS0 */
+       SX9310_CHANNEL(1),                      /* CS1 */
+       SX9310_CHANNEL(2),                      /* CS2 */
+       SX9310_NAMED_CHANNEL(3, "comb"),        /* COMB */
+
+       IIO_CHAN_SOFT_TIMESTAMP(4),
+};
+
+/*
+ * Each entry contains the integer part (val) and the fractional part, in micro
+ * seconds. It conforms to the IIO output IIO_VAL_INT_PLUS_MICRO.
+ */
+static const struct {
+       int val;
+       int val2;
+} sx9310_samp_freq_table[] = {
+       { 500, 0 }, /* 0000: Min (no idle time) */
+       { 66, 666666 }, /* 0001: 15 ms */
+       { 33, 333333 }, /* 0010: 30 ms (Typ.) */
+       { 22, 222222 }, /* 0011: 45 ms */
+       { 16, 666666 }, /* 0100: 60 ms */
+       { 11, 111111 }, /* 0101: 90 ms */
+       { 8, 333333 }, /* 0110: 120 ms */
+       { 5, 0 }, /* 0111: 200 ms */
+       { 2, 500000 }, /* 1000: 400 ms */
+       { 1, 666666 }, /* 1001: 600 ms */
+       { 1, 250000 }, /* 1010: 800 ms */
+       { 1, 0 }, /* 1011: 1 s */
+       { 0, 500000 }, /* 1100: 2 s */
+       { 0, 333333 }, /* 1101: 3 s */
+       { 0, 250000 }, /* 1110: 4 s */
+       { 0, 200000 }, /* 1111: 5 s */
+};
+static const unsigned int sx9310_scan_period_table[] = {
+       2,   15,  30,  45,   60,   90,   120,  200,
+       400, 600, 800, 1000, 2000, 3000, 4000, 5000,
+};
+
+static ssize_t sx9310_show_samp_freq_avail(struct device *dev,
+                                          struct device_attribute *attr,
+                                          char *buf)
+{
+       size_t len = 0;
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(sx9310_samp_freq_table); i++)
+               len += scnprintf(buf + len, PAGE_SIZE - len, "%d.%d ",
+                                sx9310_samp_freq_table[i].val,
+                                sx9310_samp_freq_table[i].val2);
+       buf[len - 1] = '\n';
+       return len;
+}
+static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(sx9310_show_samp_freq_avail);
+
+static const struct regmap_range sx9310_writable_reg_ranges[] = {
+       regmap_reg_range(SX9310_REG_IRQ_MSK, SX9310_REG_IRQ_FUNC),
+       regmap_reg_range(SX9310_REG_PROX_CTRL0, SX9310_REG_PROX_CTRL19),
+       regmap_reg_range(SX9310_REG_SAR_CTRL0, SX9310_REG_SAR_CTRL2),
+       regmap_reg_range(SX9310_REG_SENSOR_SEL, SX9310_REG_SENSOR_SEL),
+       regmap_reg_range(SX9310_REG_OFFSET_MSB, SX9310_REG_OFFSET_LSB),
+       regmap_reg_range(SX9310_REG_PAUSE, SX9310_REG_PAUSE),
+       regmap_reg_range(SX9310_REG_RESET, SX9310_REG_RESET),
+};
+
+static const struct regmap_access_table sx9310_writeable_regs = {
+       .yes_ranges = sx9310_writable_reg_ranges,
+       .n_yes_ranges = ARRAY_SIZE(sx9310_writable_reg_ranges),
+};
+
+static const struct regmap_range sx9310_readable_reg_ranges[] = {
+       regmap_reg_range(SX9310_REG_IRQ_SRC, SX9310_REG_IRQ_FUNC),
+       regmap_reg_range(SX9310_REG_PROX_CTRL0, SX9310_REG_PROX_CTRL19),
+       regmap_reg_range(SX9310_REG_SAR_CTRL0, SX9310_REG_SAR_CTRL2),
+       regmap_reg_range(SX9310_REG_SENSOR_SEL, SX9310_REG_SAR_LSB),
+       regmap_reg_range(SX9310_REG_I2CADDR, SX9310_REG_WHOAMI),
+       regmap_reg_range(SX9310_REG_RESET, SX9310_REG_RESET),
+};
+
+static const struct regmap_access_table sx9310_readable_regs = {
+       .yes_ranges = sx9310_readable_reg_ranges,
+       .n_yes_ranges = ARRAY_SIZE(sx9310_readable_reg_ranges),
+};
+
+static const struct regmap_range sx9310_volatile_reg_ranges[] = {
+       regmap_reg_range(SX9310_REG_IRQ_SRC, SX9310_REG_STAT1),
+       regmap_reg_range(SX9310_REG_USE_MSB, SX9310_REG_DIFF_LSB),
+       regmap_reg_range(SX9310_REG_SAR_MSB, SX9310_REG_SAR_LSB),
+       regmap_reg_range(SX9310_REG_RESET, SX9310_REG_RESET),
+};
+
+static const struct regmap_access_table sx9310_volatile_regs = {
+       .yes_ranges = sx9310_volatile_reg_ranges,
+       .n_yes_ranges = ARRAY_SIZE(sx9310_volatile_reg_ranges),
+};
+
+static const struct regmap_config sx9310_regmap_config = {
+       .reg_bits = 8,
+       .val_bits = 8,
+
+       .max_register = SX9310_REG_RESET,
+       .cache_type = REGCACHE_RBTREE,
+
+       .wr_table = &sx9310_writeable_regs,
+       .rd_table = &sx9310_readable_regs,
+       .volatile_table = &sx9310_volatile_regs,
+};
+
+static int sx9310_update_chan_en(struct sx9310_data *data,
+                                unsigned int chan_read,
+                                unsigned int chan_event)
+{
+       int ret;
+
+       if ((data->chan_read | data->chan_event) != (chan_read | chan_event)) {
+               ret = regmap_update_bits(data->regmap, SX9310_REG_PROX_CTRL0,
+                                        SX9310_CHAN_ENABLED_MASK,
+                                        chan_read | chan_event);
+               if (ret)
+                       return ret;
+       }
+       data->chan_read = chan_read;
+       data->chan_event = chan_event;
+       return 0;
+}
+
+static int sx9310_get_read_channel(struct sx9310_data *data, int channel)
+{
+       return sx9310_update_chan_en(data, data->chan_read | BIT(channel),
+                                    data->chan_event);
+}
+
+static int sx9310_put_read_channel(struct sx9310_data *data, int channel)
+{
+       return sx9310_update_chan_en(data, data->chan_read & ~BIT(channel),
+                                    data->chan_event);
+}
+
+static int sx9310_get_event_channel(struct sx9310_data *data, int channel)
+{
+       return sx9310_update_chan_en(data, data->chan_read,
+                                    data->chan_event | BIT(channel));
+}
+
+static int sx9310_put_event_channel(struct sx9310_data *data, int channel)
+{
+       return sx9310_update_chan_en(data, data->chan_read,
+                                    data->chan_event & ~BIT(channel));
+}
+
+static int sx9310_enable_irq(struct sx9310_data *data, unsigned int irq)
+{
+       return regmap_update_bits(data->regmap, SX9310_REG_IRQ_MSK, irq, irq);
+}
+
+static int sx9310_disable_irq(struct sx9310_data *data, unsigned int irq)
+{
+       return regmap_update_bits(data->regmap, SX9310_REG_IRQ_MSK, irq, 0);
+}
+
+static int sx9310_read_prox_data(struct sx9310_data *data,
+                                const struct iio_chan_spec *chan, __be16 *val)
+{
+       int ret;
+
+       ret = regmap_write(data->regmap, SX9310_REG_SENSOR_SEL, chan->channel);
+       if (ret < 0)
+               return ret;
+
+       return regmap_bulk_read(data->regmap, chan->address, val, 2);
+}
+
+/*
+ * If we have no interrupt support, we have to wait for a scan period
+ * after enabling a channel to get a result.
+ */
+static int sx9310_wait_for_sample(struct sx9310_data *data)
+{
+       int ret;
+       unsigned int val;
+
+       ret = regmap_read(data->regmap, SX9310_REG_PROX_CTRL0, &val);
+       if (ret < 0)
+               return ret;
+
+       val = (val & SX9310_SCAN_PERIOD_MASK) >> SX9310_SCAN_PERIOD_SHIFT;
+
+       msleep(sx9310_scan_period_table[val]);
+
+       return 0;
+}
+
+static int sx9310_read_proximity(struct sx9310_data *data,
+                                const struct iio_chan_spec *chan, int *val)
+{
+       int ret = 0;
+       __be16 rawval;
+
+       mutex_lock(&data->mutex);
+
+       ret = sx9310_get_read_channel(data, chan->channel);
+       if (ret < 0)
+               goto out;
+
+       ret = sx9310_enable_irq(data, SX9310_CONVDONE_IRQ);
+       if (ret < 0)
+               goto out_put_channel;
+
+       mutex_unlock(&data->mutex);
+
+       if (data->client->irq > 0) {
+               ret = wait_for_completion_interruptible(&data->completion);
+               reinit_completion(&data->completion);
+       } else {
+               ret = sx9310_wait_for_sample(data);
+       }
+
+       mutex_lock(&data->mutex);
+
+       if (ret < 0)
+               goto out_disable_irq;
+
+       ret = sx9310_read_prox_data(data, chan, &rawval);
+       if (ret < 0)
+               goto out_disable_irq;
+
+       *val = sign_extend32(be16_to_cpu(rawval),
+                            (chan->address == SX9310_REG_DIFF_MSB ? 11 : 15));
+
+       ret = sx9310_disable_irq(data, SX9310_CONVDONE_IRQ);
+       if (ret < 0)
+               goto out_put_channel;
+
+       ret = sx9310_put_read_channel(data, chan->channel);
+       if (ret < 0)
+               goto out;
+
+       mutex_unlock(&data->mutex);
+
+       return IIO_VAL_INT;
+
+out_disable_irq:
+       sx9310_disable_irq(data, SX9310_CONVDONE_IRQ);
+out_put_channel:
+       sx9310_put_read_channel(data, chan->channel);
+out:
+       mutex_unlock(&data->mutex);
+
+       return ret;
+}
+
+static int sx9310_read_samp_freq(struct sx9310_data *data, int *val, int *val2)
+{
+       unsigned int regval;
+       int ret = regmap_read(data->regmap, SX9310_REG_PROX_CTRL0, &regval);
+
+       if (ret < 0)
+               return ret;
+
+       regval = (regval & SX9310_SCAN_PERIOD_MASK) >> SX9310_SCAN_PERIOD_SHIFT;
+       *val = sx9310_samp_freq_table[regval].val;
+       *val2 = sx9310_samp_freq_table[regval].val2;
+
+       return IIO_VAL_INT_PLUS_MICRO;
+}
+
+static int sx9310_read_raw(struct iio_dev *indio_dev,
+                          const struct iio_chan_spec *chan, int *val,
+                          int *val2, long mask)
+{
+       struct sx9310_data *data = iio_priv(indio_dev);
+       int ret;
+
+       if (chan->type != IIO_PROXIMITY)
+               return -EINVAL;
+
+       switch (mask) {
+       case IIO_CHAN_INFO_RAW:
+               ret = iio_device_claim_direct_mode(indio_dev);
+               if (ret)
+                       return ret;
+
+               ret = sx9310_read_proximity(data, chan, val);
+               iio_device_release_direct_mode(indio_dev);
+               return ret;
+       case IIO_CHAN_INFO_SAMP_FREQ:
+               return sx9310_read_samp_freq(data, val, val2);
+       default:
+               return -EINVAL;
+       }
+}
+
+static int sx9310_set_samp_freq(struct sx9310_data *data, int val, int val2)
+{
+       int i, ret;
+
+       for (i = 0; i < ARRAY_SIZE(sx9310_samp_freq_table); i++)
+               if (val == sx9310_samp_freq_table[i].val &&
+                   val2 == sx9310_samp_freq_table[i].val2)
+                       break;
+
+       if (i == ARRAY_SIZE(sx9310_samp_freq_table))
+               return -EINVAL;
+
+       mutex_lock(&data->mutex);
+
+       ret = regmap_update_bits(data->regmap, SX9310_REG_PROX_CTRL0,
+                                SX9310_SCAN_PERIOD_MASK,
+                                i << SX9310_SCAN_PERIOD_SHIFT);
+
+       mutex_unlock(&data->mutex);
+
+       return ret;
+}
+
+static int sx9310_write_raw(struct iio_dev *indio_dev,
+                           const struct iio_chan_spec *chan, int val, int val2,
+                           long mask)
+{
+       struct sx9310_data *data = iio_priv(indio_dev);
+
+       if (chan->type != IIO_PROXIMITY)
+               return -EINVAL;
+
+       if (mask != IIO_CHAN_INFO_SAMP_FREQ)
+               return -EINVAL;
+
+       return sx9310_set_samp_freq(data, val, val2);
+}
+
+static irqreturn_t sx9310_irq_handler(int irq, void *private)
+{
+       struct iio_dev *indio_dev = private;
+       struct sx9310_data *data = iio_priv(indio_dev);
+
+       if (data->trigger_enabled)
+               iio_trigger_poll(data->trig);
+
+       /*
+        * Even if no event is enabled, we need to wake the thread to
+        * clear the interrupt state by reading SX9310_REG_IRQ_SRC.  It
+        * is not possible to do that here because regmap_read takes a
+        * mutex.
+        */
+       return IRQ_WAKE_THREAD;
+}
+
+static void sx9310_push_events(struct iio_dev *indio_dev)
+{
+       int ret;
+       unsigned int val, chan;
+       struct sx9310_data *data = iio_priv(indio_dev);
+       s64 timestamp = iio_get_time_ns(indio_dev);
+
+       /* Read proximity state on all channels */
+       ret = regmap_read(data->regmap, SX9310_REG_STAT0, &val);
+       if (ret < 0) {
+               dev_err(&data->client->dev, "i2c transfer error in irq\n");
+               return;
+       }
+
+       for (chan = 0; chan < SX9310_NUM_CHANNELS; chan++) {
+               int dir;
+               u64 ev;
+               bool new_prox = val & BIT(chan);
+
+               if (!(data->chan_event & BIT(chan)))
+                       continue;
+               if (new_prox == data->prox_stat[chan])
+                       /* No change on this channel. */
+                       continue;
+
+               dir = new_prox ? IIO_EV_DIR_FALLING : IIO_EV_DIR_RISING;
+               ev = IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, chan,
+                                         IIO_EV_TYPE_THRESH, dir);
+
+               iio_push_event(indio_dev, ev, timestamp);
+               data->prox_stat[chan] = new_prox;
+       }
+}
+
+static irqreturn_t sx9310_irq_thread_handler(int irq, void *private)
+{
+       struct iio_dev *indio_dev = private;
+       struct sx9310_data *data = iio_priv(indio_dev);
+       int ret;
+       unsigned int val;
+
+       mutex_lock(&data->mutex);
+
+       ret = regmap_read(data->regmap, SX9310_REG_IRQ_SRC, &val);
+       if (ret < 0) {
+               dev_err(&data->client->dev, "i2c transfer error in irq\n");
+               goto out;
+       }
+
+       if (val & SX9310_EVENT_IRQ)
+               sx9310_push_events(indio_dev);
+
+       if (val & SX9310_CONVDONE_IRQ)
+               complete(&data->completion);
+
+out:
+       mutex_unlock(&data->mutex);
+
+       return IRQ_HANDLED;
+}
+
+static int sx9310_read_event_config(struct iio_dev *indio_dev,
+                                   const struct iio_chan_spec *chan,
+                                   enum iio_event_type type,
+                                   enum iio_event_direction dir)
+{
+       struct sx9310_data *data = iio_priv(indio_dev);
+
+       return !!(data->chan_event & BIT(chan->channel));
+}
+
+static int sx9310_write_event_config(struct iio_dev *indio_dev,
+                                    const struct iio_chan_spec *chan,
+                                    enum iio_event_type type,
+                                    enum iio_event_direction dir, int state)
+{
+       struct sx9310_data *data = iio_priv(indio_dev);
+       int ret;
+
+       /* If the state hasn't changed, there's nothing to do. */
+       if (!!(data->chan_event & BIT(chan->channel)) == state)
+               return 0;
+
+       mutex_lock(&data->mutex);
+       if (state) {
+               ret = sx9310_get_event_channel(data, chan->channel);
+               if (ret < 0)
+                       goto out_unlock;
+               if (!(data->chan_event & ~BIT(chan->channel))) {
+                       ret = sx9310_enable_irq(data, SX9310_EVENT_IRQ);
+                       if (ret < 0)
+                               sx9310_put_event_channel(data, chan->channel);
+               }
+       } else {
+               ret = sx9310_put_event_channel(data, chan->channel);
+               if (ret < 0)
+                       goto out_unlock;
+               if (!data->chan_event) {
+                       ret = sx9310_disable_irq(data, SX9310_EVENT_IRQ);
+                       if (ret < 0)
+                               sx9310_get_event_channel(data, chan->channel);
+               }
+       }
+
+out_unlock:
+       mutex_unlock(&data->mutex);
+       return ret;
+}
+
+static struct attribute *sx9310_attributes[] = {
+       &iio_dev_attr_sampling_frequency_available.dev_attr.attr,
+       NULL,
+};
+
+static const struct attribute_group sx9310_attribute_group = {
+       .attrs = sx9310_attributes,
+};
+
+static const struct iio_info sx9310_info = {
+       .attrs = &sx9310_attribute_group,
+       .read_raw = sx9310_read_raw,
+       .write_raw = sx9310_write_raw,
+       .read_event_config = sx9310_read_event_config,
+       .write_event_config = sx9310_write_event_config,
+};
+
+static int sx9310_set_trigger_state(struct iio_trigger *trig, bool state)
+{
+       struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
+       struct sx9310_data *data = iio_priv(indio_dev);
+       int ret = 0;
+
+       mutex_lock(&data->mutex);
+
+       if (state)
+               ret = sx9310_enable_irq(data, SX9310_CONVDONE_IRQ);
+       else if (!data->chan_read)
+               ret = sx9310_disable_irq(data, SX9310_CONVDONE_IRQ);
+       if (ret < 0)
+               goto out;
+
+       data->trigger_enabled = state;
+
+out:
+       mutex_unlock(&data->mutex);
+
+       return ret;
+}
+
+static const struct iio_trigger_ops sx9310_trigger_ops = {
+       .set_trigger_state = sx9310_set_trigger_state,
+};
+
+static irqreturn_t sx9310_trigger_handler(int irq, void *private)
+{
+       struct iio_poll_func *pf = private;
+       struct iio_dev *indio_dev = pf->indio_dev;
+       struct sx9310_data *data = iio_priv(indio_dev);
+       __be16 val;
+       int bit, ret, i = 0;
+
+       mutex_lock(&data->mutex);
+
+       for_each_set_bit(bit, indio_dev->active_scan_mask,
+                        indio_dev->masklength) {
+               ret = sx9310_read_prox_data(data, &indio_dev->channels[bit],
+                                           &val);
+               if (ret < 0)
+                       goto out;
+
+               data->buffer[i++] = val;
+       }
+
+       iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
+                                          pf->timestamp);
+
+out:
+       mutex_unlock(&data->mutex);
+
+       iio_trigger_notify_done(indio_dev->trig);
+
+       return IRQ_HANDLED;
+}
+
+static int sx9310_buffer_preenable(struct iio_dev *indio_dev)
+{
+       struct sx9310_data *data = iio_priv(indio_dev);
+       unsigned int channels = 0;
+       int bit, ret;
+
+       mutex_lock(&data->mutex);
+       for_each_set_bit(bit, indio_dev->active_scan_mask,
+                        indio_dev->masklength)
+               channels |= BIT(indio_dev->channels[bit].channel);
+
+       ret = sx9310_update_chan_en(data, channels, data->chan_event);
+       mutex_unlock(&data->mutex);
+       return ret;
+}
+
+static int sx9310_buffer_postdisable(struct iio_dev *indio_dev)
+{
+       struct sx9310_data *data = iio_priv(indio_dev);
+       int ret;
+
+       mutex_lock(&data->mutex);
+       ret = sx9310_update_chan_en(data, 0, data->chan_event);
+       mutex_unlock(&data->mutex);
+       return ret;
+}
+
+static const struct iio_buffer_setup_ops sx9310_buffer_setup_ops = {
+       .preenable = sx9310_buffer_preenable,
+       .postenable = iio_triggered_buffer_postenable,
+       .predisable = iio_triggered_buffer_predisable,
+       .postdisable = sx9310_buffer_postdisable,
+};
+
+struct sx9310_reg_default {
+       u8 reg;
+       u8 def;
+};
+
+#define SX_INIT(_reg, _def)                    \
+       {                                       \
+               .reg = SX9310_REG_##_reg,       \
+               .def = _def,                    \
+       }
+
+static const struct sx9310_reg_default sx9310_default_regs[] = {
+       SX_INIT(IRQ_MSK, 0x00),
+       SX_INIT(IRQ_FUNC, 0x00),
+       /*
+        * The lower 4 bits should not be set as it enable sensors measurements.
+        * Turning the detection on before the configuration values are set to
+        * good values can cause the device to return erroneous readings.
+        */
+       SX_INIT(PROX_CTRL0, SX9310_REG_PROX_CTRL0_PROXSTAT2),
+       SX_INIT(PROX_CTRL1, 0x00),
+       SX_INIT(PROX_CTRL2, SX9310_REG_PROX_CTRL2_COMBMODE_ALL |
+                           SX9310_REG_PROX_CTRL2_SHIELDEN_DYNAMIC),
+       SX_INIT(PROX_CTRL3, SX9310_REG_PROX_CTRL3_GAIN0_X8 |
+                           SX9310_REG_PROX_CTRL3_GAIN12_X4),
+       SX_INIT(PROX_CTRL4, SX9310_REG_PROX_CTRL4_RESOLUTION_FINEST),
+       SX_INIT(PROX_CTRL5, SX9310_REG_PROX_CTRL5_RANGE_SMALL |
+                           SX9310_REG_PROX_CTRL5_STARTUPSENS_CS1 |
+                           SX9310_REG_PROX_CTRL5_RAWFILT_1P25),
+       SX_INIT(PROX_CTRL6, SX9310_REG_PROX_CTRL6_COMP_COMMON),
+       SX_INIT(PROX_CTRL7, SX9310_REG_PROX_CTRL7_AVGNEGFILT_2 |
+                           SX9310_REG_PROX_CTRL7_AVGPOSFILT_512),
+       SX_INIT(PROX_CTRL8, SX9310_REG_PROX_CTRL8_9_PTHRESH_96 |
+                           SX9310_REG_PROX_CTRL8_9_BODYTHRESH_1500),
+       SX_INIT(PROX_CTRL9, SX9310_REG_PROX_CTRL8_9_PTHRESH12_28 |
+                           SX9310_REG_PROX_CTRL8_9_BODYTHRESH_900),
+       SX_INIT(PROX_CTRL10, SX9310_REG_PROX_CTRL10_HYST_6PCT |
+                            SX9310_REG_PROX_CTRL10_CLOSE_DEBOUNCE_8 |
+                            SX9310_REG_PROX_CTRL10_FAR_DEBOUNCE_8),
+       SX_INIT(PROX_CTRL11, 0x00),
+       SX_INIT(PROX_CTRL12, 0x00),
+       SX_INIT(PROX_CTRL13, 0x00),
+       SX_INIT(PROX_CTRL14, 0x00),
+       SX_INIT(PROX_CTRL15, 0x00),
+       SX_INIT(PROX_CTRL16, 0x00),
+       SX_INIT(PROX_CTRL17, 0x00),
+       SX_INIT(PROX_CTRL18, 0x00),
+       SX_INIT(PROX_CTRL19, 0x00),
+       SX_INIT(SAR_CTRL0, SX9310_REG_SAR_CTRL0_SARDEB_4_SAMPLES |
+                          SX9310_REG_SAR_CTRL0_SARHYST_8),
+       SX_INIT(SAR_CTRL1, SX9310_REG_SAR_CTRL1_SLOPE(10781250)),
+       SX_INIT(SAR_CTRL2, SX9310_REG_SAR_CTRL2_SAROFFSET_DEFAULT),
+};
+
+/* Activate all channels and perform an initial compensation. */
+static int sx9310_init_compensation(struct iio_dev *indio_dev)
+{
+       struct sx9310_data *data = iio_priv(indio_dev);
+       int i, ret;
+       unsigned int val;
+       unsigned int ctrl0;
+
+       ret = regmap_read(data->regmap, SX9310_REG_PROX_CTRL0, &ctrl0);
+       if (ret < 0)
+               return ret;
+
+       /* run the compensation phase on all channels */
+       ret = regmap_write(data->regmap, SX9310_REG_PROX_CTRL0,
+                          ctrl0 | SX9310_REG_PROX_CTRL0_EN_MASK);
+       if (ret < 0)
+               return ret;
+
+       for (i = 100; i >= 0; i--) {
+               msleep(20);
+               ret = regmap_read(data->regmap, SX9310_REG_STAT1, &val);
+               if (ret < 0)
+                       goto out;
+               if (!(val & SX9310_COMPSTAT_MASK))
+                       break;
+       }
+
+       if (i < 0) {
+               dev_err(&data->client->dev,
+                       "initial compensation timed out: 0x%02x", val);
+               ret = -ETIMEDOUT;
+       }
+
+out:
+       regmap_write(data->regmap, SX9310_REG_PROX_CTRL0, ctrl0);
+       return ret;
+}
+
+static int sx9310_init_device(struct iio_dev *indio_dev)
+{
+       struct sx9310_data *data = iio_priv(indio_dev);
+       const struct sx9310_reg_default *initval;
+       int ret;
+       unsigned int i, val;
+
+       ret = regmap_write(data->regmap, SX9310_REG_RESET, SX9310_SOFT_RESET);
+       if (ret < 0)
+               return ret;
+
+       usleep_range(1000, 2000); /* power-up time is ~1ms. */
+
+       /* Clear reset interrupt state by reading SX9310_REG_IRQ_SRC. */
+       ret = regmap_read(data->regmap, SX9310_REG_IRQ_SRC, &val);
+       if (ret < 0)
+               return ret;
+
+       /* Program some sane defaults. */
+       for (i = 0; i < ARRAY_SIZE(sx9310_default_regs); i++) {
+               initval = &sx9310_default_regs[i];
+               ret = regmap_write(data->regmap, initval->reg, initval->def);
+               if (ret < 0)
+                       return ret;
+       }
+
+       return sx9310_init_compensation(indio_dev);
+}
+
+static int sx9310_set_indio_dev_name(struct device *dev,
+                                    struct iio_dev *indio_dev,
+                                    const struct i2c_device_id *id, int whoami)
+{
+       const struct acpi_device_id *acpi_id;
+
+       /* id will be NULL when enumerated via ACPI */
+       if (id) {
+               if (id->driver_data != whoami)
+                       dev_err(dev, "WHOAMI does not match i2c_device_id: %s",
+                               id->name);
+       } else if (ACPI_HANDLE(dev)) {
+               acpi_id = acpi_match_device(dev->driver->acpi_match_table, dev);
+               if (!acpi_id)
+                       return -ENODEV;
+               if (acpi_id->driver_data != whoami)
+                       dev_err(dev, "WHOAMI does not match acpi_device_id: %s",
+                               acpi_id->id);
+       } else
+               return -ENODEV;
+
+       switch (whoami) {
+       case SX9310_WHOAMI_VALUE:
+               indio_dev->name = "sx9310";
+               break;
+       case SX9311_WHOAMI_VALUE:
+               indio_dev->name = "sx9311";
+               break;
+       default:
+               dev_err(dev, "unexpected WHOAMI response: %u", whoami);
+               return -ENODEV;
+       }
+
+       return 0;
+}
+
+static int sx9310_probe(struct i2c_client *client,
+                       const struct i2c_device_id *id)
+{
+       int ret;
+       struct iio_dev *indio_dev;
+       struct sx9310_data *data;
+
+       indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+       if (indio_dev == NULL)
+               return -ENOMEM;
+
+       data = iio_priv(indio_dev);
+       data->client = client;
+       mutex_init(&data->mutex);
+       init_completion(&data->completion);
+
+       data->regmap = devm_regmap_init_i2c(client, &sx9310_regmap_config);
+       if (IS_ERR(data->regmap))
+               return PTR_ERR(data->regmap);
+
+       ret = regmap_read(data->regmap, SX9310_REG_WHOAMI, &data->whoami);
+       if (ret < 0) {
+               dev_err(&client->dev, "error in reading WHOAMI register: %d",
+                       ret);
+               return ret;
+       }
+
+       ret = sx9310_set_indio_dev_name(&client->dev, indio_dev, id,
+                                       data->whoami);
+       if (ret < 0)
+               return ret;
+
+       ACPI_COMPANION_SET(&indio_dev->dev, ACPI_COMPANION(&client->dev));
+       indio_dev->dev.parent = &client->dev;
+       indio_dev->channels = sx9310_channels;
+       indio_dev->num_channels = ARRAY_SIZE(sx9310_channels);
+       indio_dev->info = &sx9310_info;
+       indio_dev->modes = INDIO_DIRECT_MODE;
+       i2c_set_clientdata(client, indio_dev);
+
+       ret = sx9310_init_device(indio_dev);
+       if (ret < 0)
+               return ret;
+
+       if (client->irq) {
+               ret = devm_request_threaded_irq(&client->dev, client->irq,
+                                               sx9310_irq_handler,
+                                               sx9310_irq_thread_handler,
+                                               IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+                                               "sx9310_event", indio_dev);
+               if (ret < 0)
+                       return ret;
+
+               data->trig =
+                       devm_iio_trigger_alloc(&client->dev, "%s-dev%d",
+                                              indio_dev->name, indio_dev->id);
+               if (!data->trig)
+                       return -ENOMEM;
+
+               data->trig->dev.parent = &client->dev;
+               data->trig->ops = &sx9310_trigger_ops;
+               iio_trigger_set_drvdata(data->trig, indio_dev);
+
+               ret = devm_iio_trigger_register(&client->dev, data->trig);
+               if (ret)
+                       return ret;
+       }
+
+       ret = devm_iio_triggered_buffer_setup(&client->dev, indio_dev,
+                                             iio_pollfunc_store_time,
+                                             sx9310_trigger_handler,
+                                             &sx9310_buffer_setup_ops);
+       if (ret < 0)
+               return ret;
+
+       return devm_iio_device_register(&client->dev, indio_dev);
+}
+
+static int __maybe_unused sx9310_suspend(struct device *dev)
+{
+       struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
+       struct sx9310_data *data = iio_priv(indio_dev);
+       u8 ctrl0;
+       int ret;
+
+       disable_irq_nosync(data->client->irq);
+
+       mutex_lock(&data->mutex);
+       ret = regmap_read(data->regmap, SX9310_REG_PROX_CTRL0,
+                         &data->suspend_ctrl0);
+
+       if (ret)
+               goto out;
+
+       ctrl0 = data->suspend_ctrl0 & ~SX9310_REG_PROX_CTRL0_EN_MASK;
+       ret = regmap_write(data->regmap, SX9310_REG_PROX_CTRL0, ctrl0);
+       if (ret)
+               goto out;
+
+       ret = regmap_write(data->regmap, SX9310_REG_PAUSE, 0);
+
+out:
+       mutex_unlock(&data->mutex);
+       return ret;
+}
+
+static int __maybe_unused sx9310_resume(struct device *dev)
+{
+       struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
+       struct sx9310_data *data = iio_priv(indio_dev);
+       int ret;
+
+       mutex_lock(&data->mutex);
+       ret = regmap_write(data->regmap, SX9310_REG_PAUSE, 1);
+       if (ret)
+               goto out;
+
+       ret = regmap_write(data->regmap, SX9310_REG_PROX_CTRL0,
+                          data->suspend_ctrl0);
+
+out:
+       mutex_unlock(&data->mutex);
+
+       enable_irq(data->client->irq);
+
+       return ret;
+}
+
+static const struct dev_pm_ops sx9310_pm_ops = {
+       SET_SYSTEM_SLEEP_PM_OPS(sx9310_suspend, sx9310_resume)
+};
+
+static const struct acpi_device_id sx9310_acpi_match[] = {
+       { "STH9310", SX9310_WHOAMI_VALUE },
+       { "STH9311", SX9311_WHOAMI_VALUE },
+       {},
+};
+MODULE_DEVICE_TABLE(acpi, sx9310_acpi_match);
+
+static const struct of_device_id sx9310_of_match[] = {
+       { .compatible = "semtech,sx9310" },
+       { .compatible = "semtech,sx9311" },
+       {},
+};
+MODULE_DEVICE_TABLE(of, sx9310_of_match);
+
+static const struct i2c_device_id sx9310_id[] = {
+       { "sx9310", SX9310_WHOAMI_VALUE },
+       { "sx9311", SX9311_WHOAMI_VALUE },
+       {},
+};
+MODULE_DEVICE_TABLE(i2c, sx9310_id);
+
+static struct i2c_driver sx9310_driver = {
+       .driver = {
+               .name   = "sx9310",
+               .acpi_match_table = ACPI_PTR(sx9310_acpi_match),
+               .of_match_table = of_match_ptr(sx9310_of_match),
+               .pm = &sx9310_pm_ops,
+       },
+       .probe          = sx9310_probe,
+       .id_table       = sx9310_id,
+};
+module_i2c_driver(sx9310_driver);
+
+MODULE_AUTHOR("Gwendal Grignou <gwendal@chromium.org>");
+MODULE_AUTHOR("Daniel Campello <campello@chromium.org>");
+MODULE_DESCRIPTION("Driver for Semtech SX9310/SX9311 proximity sensor");
+MODULE_LICENSE("GPL v2");
index d39c0d6b77f1ca2bbf20ffc0865846912bbb8885..8976e8d598262ce49b6670ce1ed8e1f2c71e1f9c 100644 (file)
@@ -390,8 +390,8 @@ static struct ltc2983_custom_sensor *__ltc2983_custom_sensor_new(
         * For custom steinhart, the full u32 is taken. For all the others
         * the MSB is discarded.
         */
-       const u8 n_size = (is_steinhart == true) ? 4 : 3;
-       const u8 e_size = (is_steinhart == true) ? sizeof(u32) : sizeof(u64);
+       const u8 n_size = is_steinhart ? 4 : 3;
+       const u8 e_size = is_steinhart ? sizeof(u32) : sizeof(u64);
 
        n_entries = of_property_count_elems_of_size(np, propname, e_size);
        /* n_entries must be an even number */
index a5e670726717f0d8269cb93e49e32df509e8d7ed..f59bf8d585866ea2050ada02bc995cc2d241320a 100644 (file)
@@ -4,7 +4,7 @@
  *
  * Copyright (C) Intuitive Aerial AB
  * Written by Marten Svanfeldt, marten@intuitiveaerial.com
- * Copyright (C) 2012, Analog Device Inc.
+ * Copyright (C) 2012, Analog Devices Inc.
  *     Author: Lars-Peter Clausen <lars@metafoo.de>
  * Copyright (C) 2015, Intel Corporation
  */
index 43f92b06bc3e55747dd90c0b8b6e9bf763fc2446..ebdc64f451d7c79842c35f55484adccdc5dd6c48 100644 (file)
@@ -34,7 +34,7 @@ turned on or off (if possible) via sysfs interfaces.
 fifo / ring buffers on the sensor chip.  These greatly reduce the load
 on the host CPU by buffering relatively large numbers of data samples
 based on an internal sampling clock. Examples include VTI SCA3000
-series and Analog Device ADXL345 accelerometers.  Each buffer supports
+series and Analog Devices ADXL345 accelerometers.  Each buffer supports
 polling to establish when data is available.
 
 * Trigger and software buffer support. In many data analysis
index 7fc95d5c95bb80b21bb783dce7a3eb88dc462dd8..141ac3f251e6f256526812b9d55cd440a2a46e76 100644 (file)
 #ifndef ADI_AXI_COMMON_H_
 #define ADI_AXI_COMMON_H_
 
-#define        ADI_AXI_REG_VERSION                     0x0000
+#define ADI_AXI_REG_VERSION                    0x0000
 
 #define ADI_AXI_PCORE_VER(major, minor, patch) \
        (((major) << 16) | ((minor) << 8) | (patch))
 
+#define ADI_AXI_PCORE_VER_MAJOR(version)       (((version) >> 16) & 0xff)
+#define ADI_AXI_PCORE_VER_MINOR(version)       (((version) >> 8) & 0xff)
+#define ADI_AXI_PCORE_VER_PATCH(version)       ((version) & 0xff)
+
 #endif /* ADI_AXI_COMMON_H_ */
index 5a127c0ed2007baf84cc2b9c7471740c77b9cf6d..a3a838dcf8e4a073da304d48df35de26700334e6 100644 (file)
@@ -133,62 +133,4 @@ void ad_sd_cleanup_buffer_and_trigger(struct iio_dev *indio_dev);
 
 int ad_sd_validate_trigger(struct iio_dev *indio_dev, struct iio_trigger *trig);
 
-#define __AD_SD_CHANNEL(_si, _channel1, _channel2, _address, _bits, \
-       _storagebits, _shift, _extend_name, _type, _mask_all) \
-       { \
-               .type = (_type), \
-               .differential = (_channel2 == -1 ? 0 : 1), \
-               .indexed = 1, \
-               .channel = (_channel1), \
-               .channel2 = (_channel2), \
-               .address = (_address), \
-               .extend_name = (_extend_name), \
-               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
-                       BIT(IIO_CHAN_INFO_OFFSET), \
-               .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
-               .info_mask_shared_by_all = _mask_all, \
-               .scan_index = (_si), \
-               .scan_type = { \
-                       .sign = 'u', \
-                       .realbits = (_bits), \
-                       .storagebits = (_storagebits), \
-                       .shift = (_shift), \
-                       .endianness = IIO_BE, \
-               }, \
-       }
-
-#define AD_SD_DIFF_CHANNEL(_si, _channel1, _channel2, _address, _bits, \
-       _storagebits, _shift) \
-       __AD_SD_CHANNEL(_si, _channel1, _channel2, _address, _bits, \
-               _storagebits, _shift, NULL, IIO_VOLTAGE, \
-               BIT(IIO_CHAN_INFO_SAMP_FREQ))
-
-#define AD_SD_SHORTED_CHANNEL(_si, _channel, _address, _bits, \
-       _storagebits, _shift) \
-       __AD_SD_CHANNEL(_si, _channel, _channel, _address, _bits, \
-               _storagebits, _shift, "shorted", IIO_VOLTAGE, \
-               BIT(IIO_CHAN_INFO_SAMP_FREQ))
-
-#define AD_SD_CHANNEL(_si, _channel, _address, _bits, \
-       _storagebits, _shift) \
-       __AD_SD_CHANNEL(_si, _channel, -1, _address, _bits, \
-               _storagebits, _shift, NULL, IIO_VOLTAGE, \
-                BIT(IIO_CHAN_INFO_SAMP_FREQ))
-
-#define AD_SD_CHANNEL_NO_SAMP_FREQ(_si, _channel, _address, _bits, \
-       _storagebits, _shift) \
-       __AD_SD_CHANNEL(_si, _channel, -1, _address, _bits, \
-               _storagebits, _shift, NULL, IIO_VOLTAGE, 0)
-
-#define AD_SD_TEMP_CHANNEL(_si, _address, _bits, _storagebits, _shift) \
-       __AD_SD_CHANNEL(_si, 0, -1, _address, _bits, \
-               _storagebits, _shift, NULL, IIO_TEMP, \
-               BIT(IIO_CHAN_INFO_SAMP_FREQ))
-
-#define AD_SD_SUPPLY_CHANNEL(_si, _channel, _address, _bits, _storagebits, \
-       _shift) \
-       __AD_SD_CHANNEL(_si, _channel, -1, _address, _bits, \
-               _storagebits, _shift, "supply", IIO_VOLTAGE, \
-               BIT(IIO_CHAN_INFO_SAMP_FREQ))
-
 #endif
diff --git a/include/linux/iio/adc/adi-axi-adc.h b/include/linux/iio/adc/adi-axi-adc.h
new file mode 100644 (file)
index 0000000..c5d48e1
--- /dev/null
@@ -0,0 +1,64 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Analog Devices Generic AXI ADC IP core driver/library
+ * Link: https://wiki.analog.com/resources/fpga/docs/axi_adc_ip
+ *
+ * Copyright 2012-2020 Analog Devices Inc.
+ */
+#ifndef __ADI_AXI_ADC_H__
+#define __ADI_AXI_ADC_H__
+
+struct device;
+struct iio_chan_spec;
+
+/**
+ * struct adi_axi_adc_chip_info - Chip specific information
+ * @name               Chip name
+ * @id                 Chip ID (usually product ID)
+ * @channels           Channel specifications of type @struct axi_adc_chan_spec
+ * @num_channels       Number of @channels
+ * @scale_table                Supported scales by the chip; tuples of 2 ints
+ * @num_scales         Number of scales in the table
+ * @max_rate           Maximum sampling rate supported by the device
+ */
+struct adi_axi_adc_chip_info {
+       const char                      *name;
+       unsigned int                    id;
+
+       const struct iio_chan_spec      *channels;
+       unsigned int                    num_channels;
+
+       const unsigned int              (*scale_table)[2];
+       int                             num_scales;
+
+       unsigned long                   max_rate;
+};
+
+/**
+ * struct adi_axi_adc_conv - data of the ADC attached to the AXI ADC
+ * @chip_info          chip info details for the client ADC
+ * @preenable_setup    op to run in the client before enabling the AXI ADC
+ * @reg_access         IIO debugfs_reg_access hook for the client ADC
+ * @read_raw           IIO read_raw hook for the client ADC
+ * @write_raw          IIO write_raw hook for the client ADC
+ */
+struct adi_axi_adc_conv {
+       const struct adi_axi_adc_chip_info              *chip_info;
+
+       int (*preenable_setup)(struct adi_axi_adc_conv *conv);
+       int (*reg_access)(struct adi_axi_adc_conv *conv, unsigned int reg,
+                         unsigned int writeval, unsigned int *readval);
+       int (*read_raw)(struct adi_axi_adc_conv *conv,
+                       struct iio_chan_spec const *chan,
+                       int *val, int *val2, long mask);
+       int (*write_raw)(struct adi_axi_adc_conv *conv,
+                        struct iio_chan_spec const *chan,
+                        int val, int val2, long mask);
+};
+
+struct adi_axi_adc_conv *devm_adi_axi_adc_conv_register(struct device *dev,
+                                                       size_t sizeof_priv);
+
+void *adi_axi_adc_conv_priv(struct adi_axi_adc_conv *conv);
+
+#endif
index 016d8a068353b6cd5956914fba782ca8bec69726..ff15c61bf31904e3c85be934a66aeb30ccbeb3cf 100644 (file)
@@ -11,7 +11,7 @@
 #include <linux/kref.h>
 #include <linux/spinlock.h>
 #include <linux/mutex.h>
-#include <linux/iio/buffer.h>
+#include <linux/iio/buffer_impl.h>
 
 struct iio_dma_buffer_queue;
 struct iio_dma_buffer_ops;
index b3a57444a886fe8aab3f1120e268526904f12c3b..0e503db71289606877bf04dc53bb24b5a6bede79 100644 (file)
@@ -14,4 +14,7 @@ struct iio_buffer *iio_dmaengine_buffer_alloc(struct device *dev,
        const char *channel);
 void iio_dmaengine_buffer_free(struct iio_buffer *buffer);
 
+struct iio_buffer *devm_iio_dmaengine_buffer_alloc(struct device *dev,
+                                                  const char *channel);
+
 #endif
index a4d2d8061ef67911226f631382cff7fd62d4aa61..a63dc07b73500b71e0e53d5291dd04734e8bffa5 100644 (file)
@@ -94,12 +94,6 @@ struct iio_buffer {
        unsigned int watermark;
 
        /* private: */
-       /*
-        * @scan_el_attrs: Control of scan elements if that scan mode
-        * control method is used.
-        */
-       struct attribute_group *scan_el_attrs;
-
        /* @scan_timestamp: Does the scan mode include a timestamp. */
        bool scan_timestamp;
 
@@ -115,9 +109,6 @@ struct iio_buffer {
         */
        struct attribute_group scan_el_group;
 
-       /* @stufftoread: Flag to indicate new data. */
-       bool stufftoread;
-
        /* @attrs: Standard attributes of the buffer. */
        const struct attribute **attrs;
 
index 2bde8c912d4d325a63bda8c20cbbbb7ebf1d4116..c4118dcb8e0556bd92806e1b82381c3d486ba449 100644 (file)
@@ -63,15 +63,6 @@ void iio_channel_release(struct iio_channel *chan);
  */
 struct iio_channel *devm_iio_channel_get(struct device *dev,
                                         const char *consumer_channel);
-/**
- * devm_iio_channel_release() - Resource managed version of
- *                             iio_channel_release().
- * @dev:               Pointer to consumer device for which resource
- *                     is allocared.
- * @chan:              The channel to be released.
- */
-void devm_iio_channel_release(struct device *dev, struct iio_channel *chan);
-
 /**
  * iio_channel_get_all() - get all channels associated with a client
  * @dev:               Pointer to consumer device.
@@ -106,15 +97,6 @@ void iio_channel_release_all(struct iio_channel *chan);
  */
 struct iio_channel *devm_iio_channel_get_all(struct device *dev);
 
-/**
- * devm_iio_channel_release_all() - Resource managed version of
- *                                 iio_channel_release_all().
- * @dev:               Pointer to consumer device for which resource
- *                     is allocared.
- * @chan:              Array channel to be released.
- */
-void devm_iio_channel_release_all(struct device *dev, struct iio_channel *chan);
-
 struct iio_cb_buffer;
 /**
  * iio_channel_get_all_cb() - register callback for triggered capture
index 44d48bb1d39fb4b7225811a75a9e15300b4fef8c..e8255c2e33bcc007b446d48851e48c1d79664826 100644 (file)
@@ -14,7 +14,6 @@ struct iio_hw_consumer;
 struct iio_hw_consumer *iio_hw_consumer_alloc(struct device *dev);
 void iio_hw_consumer_free(struct iio_hw_consumer *hwc);
 struct iio_hw_consumer *devm_iio_hw_consumer_alloc(struct device *dev);
-void devm_iio_hw_consumer_free(struct device *dev, struct iio_hw_consumer *hwc);
 int iio_hw_consumer_enable(struct iio_hw_consumer *hwc);
 void iio_hw_consumer_disable(struct iio_hw_consumer *hwc);
 
index 17f56a070b205a1ebab8cea9ef1ae2c8960238bc..5f9f439a4f0113dc881eb0bb4e758a72d448bf57 100644 (file)
@@ -492,7 +492,7 @@ struct iio_buffer_setup_ops {
  * @buffer:            [DRIVER] any buffer present
  * @buffer_list:       [INTERN] list of all buffers currently attached
  * @scan_bytes:                [INTERN] num bytes captured to be fed to buffer demux
- * @mlock:             [DRIVER] lock used to prevent simultaneous device state
+ * @mlock:             [INTERN] lock used to prevent simultaneous device state
  *                     changes
  * @available_scan_masks: [DRIVER] optional array of allowed bitmasks
  * @masklength:                [INTERN] the length of the mask established from
@@ -593,9 +593,6 @@ void iio_device_unregister(struct iio_dev *indio_dev);
  * calls iio_device_register() internally. Refer to that function for more
  * information.
  *
- * If an iio_dev registered with this function needs to be unregistered
- * separately, devm_iio_device_unregister() must be used.
- *
  * RETURNS:
  * 0 on success, negative error number on failure.
  */
@@ -603,7 +600,6 @@ void iio_device_unregister(struct iio_dev *indio_dev);
        __devm_iio_device_register((dev), (indio_dev), THIS_MODULE);
 int __devm_iio_device_register(struct device *dev, struct iio_dev *indio_dev,
                               struct module *this_mod);
-void devm_iio_device_unregister(struct device *dev, struct iio_dev *indio_dev);
 int iio_push_event(struct iio_dev *indio_dev, u64 ev_code, s64 timestamp);
 int iio_device_claim_direct_mode(struct iio_dev *indio_dev);
 void iio_device_release_direct_mode(struct iio_dev *indio_dev);
@@ -694,13 +690,9 @@ static inline struct iio_dev *iio_priv_to_dev(void *priv)
 }
 
 void iio_device_free(struct iio_dev *indio_dev);
-int devm_iio_device_match(struct device *dev, void *res, void *data);
 struct iio_dev *devm_iio_device_alloc(struct device *dev, int sizeof_priv);
-void devm_iio_device_free(struct device *dev, struct iio_dev *indio_dev);
 struct iio_trigger *devm_iio_trigger_alloc(struct device *dev,
                                                const char *fmt, ...);
-void devm_iio_trigger_free(struct device *dev, struct iio_trigger *iio_trig);
-
 /**
  * iio_buffer_enabled() - helper function to test if the buffer is enabled
  * @indio_dev:         IIO device structure for device
index 764659e01b68cdf2f865f0cd4aa519f698943d56..1fc1efa7799df968d9f350b51f04c16cfcc4de25 100644 (file)
@@ -9,6 +9,5 @@ struct iio_buffer *iio_kfifo_allocate(void);
 void iio_kfifo_free(struct iio_buffer *r);
 
 struct iio_buffer *devm_iio_kfifo_allocate(struct device *dev);
-void devm_iio_kfifo_free(struct device *dev, struct iio_buffer *r);
 
 #endif
index 84995e2967acd70302e702377c9f3a933a991c9c..cad8325903f9eaf3fad08a16b5a759fad06e2dc2 100644 (file)
@@ -141,9 +141,6 @@ int __devm_iio_trigger_register(struct device *dev,
  **/
 void iio_trigger_unregister(struct iio_trigger *trig_info);
 
-void devm_iio_trigger_unregister(struct device *dev,
-                                struct iio_trigger *trig_info);
-
 /**
  * iio_trigger_set_immutable() - set an immutable trigger on destination
  *
index 238ad30ce16653b0f457a2f6e808149403e0ab28..e99c91799359a176036ff7be5b1042d61794cd9f 100644 (file)
@@ -18,7 +18,5 @@ int devm_iio_triggered_buffer_setup(struct device *dev,
                                    irqreturn_t (*h)(int irq, void *p),
                                    irqreturn_t (*thread)(int irq, void *p),
                                    const struct iio_buffer_setup_ops *ops);
-void devm_iio_triggered_buffer_cleanup(struct device *dev,
-                                      struct iio_dev *indio_dev);
 
 #endif