Commit 2db573c5 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Merge tag 'iio-for-6.11a' of...

Merge tag 'iio-for-6.11a' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/jic23/iio into char-misc-testing

Jonathan writes:

IIO: 1st set of new device support, cleanups etc for 6.11

Lots of new device support and 3 entirely new drivers.

Early pull request this cycle to allow for clean picking up of fixes
that are dependencies for some queued patch sets.

Device support
==============

adi,ad3552r
- Add AD3541R and AD3551R - single output variants of already supported
  DACs.

adi,ad7192
- Add support for ad7194 24-bit ADC with integrated PGA.

adi,ad7380
- New ADC driver built up in a number of steps. Supports
  - 2 channel differential ADCs: AD7380, AD7381
  - 4 channel differential ADCs: AD7380-4, AD7381-4
  - 2 channel pseudo-differential ADCs: AD7383, AD7384
  - 4 channel pseudo-differential ADCs: AD7383-4, AD7384-4

adi,adis16475
- Support ADS16501 variant - ID and some different scale factors from
  parts already supported.
- Driver refactoring then enables support for 6 more IMUs:
  - ADIS16575-[2,3]
  - ADIS16576-[2,3]
  - ADIS16577-[2,3]

adi,adsi16480
- Driver refactoring and feature additions leading to support for 6 more
  IMUs - with new delta angle and delta velocity feature:
  - ADIS16545-[1,2,3]
  - ADIS16547-[1,2,3]

bosch,bmi160
- Support for the bmi120 IMU: ID only. Also relax ID checking to warn
  only on mismatch allowing use of fallback compatibles for new devices.

sciosense,ens160
- New driver for this metal oxide multi-gas sensor for indoor
  air quality monitoring.

sensortek,stk3110
- Support for stk3311a and stk3311s34 light sensor variants. Relax ID
  checking to warn only on a mismatch allowing use of fallback compatibles
  for new devices.

vishay,veml6040
- New driver for this RGBW light sensor. Note that whilst the register
  interface is very different, the dt-binding similar enough that it is
  shared with the existing vishay,veml6075 binding

x-powers,axp20x
- Add support for axp192, very similar to another supported PMIC ADC variant
  but with a few more GPIO channels.

Dt-binding only
===============

ti,ads1015
- Add binding (no driver support yet) for ti,tla2021

New features
============
core
- Variable scan type support.  We have papered over this for a long time
  so good to finally resolve it.
  Some devices will change their data output format (typically resolution)
  dependent on settings such as oversampling.  A new callback is added
  to enable this. First used in the ad7380 driver.
- Harden the core against missing callback functions.

dt-binding:
- Add a single-channel property that can be used in per channel nodes
  instead of reg to indicate which device channel.  This is important
  in devices with a mixture of differential and single ended channels
  as reg already just acted as an index for the differential channels
  making things inconsistent if it had more meaning for single ended
  channels.

adi,ad7380
- Use spi_optimize_message() to reduce reading message setup overhead.
- Add oversampling support using the new core functionality to allow
  a device support multiple scan types.

invense,icm42600
- Support for low-power accelerometer modes.  When a given sampling
  frequency is only supported at one power mode, use that. Otherwise
  default to low power at the cost of some noise unless overridden
  via a new sysfs attribute.

silicon-labs,si70720
- Add control of the heater.

Cleanups and minor fixes
========================

core
- Cleanup use of sizeof(struct xxxx) in favor of sizeof(*variable)

Makefile
- Resort the iio/adc/Makefile which has drifted away from alphabetical
  order.

gts library
- Fix sorting of lists with a zero in the middle. Doesn't happen with
  upstream drivers, but good to harden this code.  Add a related unit test.

multiple drivers
- Add missing MODULE_DESCRIPTION()
- Drop some unused structure fields.
- Drop some entirely unused structure definitions.
- Stop pointless initialization of i2c_device_id::driver_data to 0 in drivers
  where it isn't used.
- Use spi_get_device_match_data() to replace open-coded equivalent.

adi,ad3552r
- Fix dt gain parameter names to reflect what the driver does. Note
  discussion in patch to justify fixing it in the binding not the
  driver.
- Tidy up some naming.

adi,ad7192
- Use read_avail() callback to handle the low pass filter.
- Add an aincom supply for pseudo differential operation.

adi,ad7606
- Use iio_device_claim_direct_scoped() to simplify error paths.

adi,ad7944
- Drop an unused function parameter.

adi,adrf6780
- Drop unused header.

adi,ad9467
- Use a DMA safe buffer for SPI transfers.
- Stop using tabs to pad structure field names. It was creating a lot
  of noise.

adi,axi-adc
- Prevent races between enable and disable calls.
- Ensure the DRP (dynamic reconfiguration port) is locked. Not used
  in most real designs, but better safe than sorry.
- Limit build to COMPILE_TEST or platforms for which the IP exists.

adi,axi-dac
- Limit build to COMPILE_TEST or platforms for which the IP exists.

ams,iaq
- Use __packed instead of ___attribute__((__packed__))

bosch,bmp280
- White space cleanup.
- Use BME280 prefix for registers that do not exist on the BMP280.
- Add parameter names to callback function definitions.
- Rename measure function to better reflect what it does which is wait
  for a measurement to happen.
- Drop a redundant error check.
- Improve error messages
- Make error checks consistent as if (ret)
- Use unsigned types for inherently unsigned data.
- Refactor reading functions to not rely on a hidden t_fine variable.
- Make use of cleanup.h

freescale,mma7660
- Add mount matrix support.

invense,icm42600
- Enable the regmap cache to reduce bus accesses.

amlogic,meson-saradc
- Add dt-binding support for power-domains.

ti,adc161s626
- Use iio_device_claim_direct_scoped() to simplify error handling.

* tag 'iio-for-6.11a' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/jic23/iio: (107 commits)
  iio: imu: inv_icm42600: add support of accel low-power mode
  iio: document inv_icm42600 driver private sysfs attributes
  MAINTAINERS: Add ScioSense ENS160
  iio: chemical: ens160: add power management support
  iio: chemical: ens160: add triggered buffer support
  iio: chemical: add driver for ENS160 sensor
  dt-bindings: iio: chemical: add ENS160 sensor
  dt-bindings: vendor-prefixes: add ScioSense
  iio: temperature: mcp9600: add threshold events support
  dt-bindings: iio: light: add VEML6040 RGBW-LS
  iio: light: driver for Vishay VEML6040
  dt-bindings: iio: adc: amlogic,meson-saradc: add optional power-domains
  iio: dac: adi-axi-dac: add platform dependencies
  iio: adc: adi-axi-adc: add platform dependencies
  iio: imu: inv_icm42600: add register caching in the regmap
  iio: adc: mcp3564: drop redundant open-coded spi_get_device_match_data()
  iio: dac: max5522: simplify with spi_get_device_match_data()
  iio: addac: ad74413r: simplify with spi_get_device_match_data()
  iio: adc: ti-tsc2046: simplify with spi_get_device_match_data()
  iio: adc: ti-ads131e08: simplify with spi_get_device_match_data()
  ...
parents a774c5d1 07d4d0bb
What: /sys/bus/iio/devices/iio:deviceX/in_accel_power_mode
KernelVersion: 6.11
Contact: linux-iio@vger.kernel.org
Description:
Accelerometer power mode. Setting this attribute will set the
requested power mode to use if the ODR support it. If ODR
support only 1 mode, power mode will be enforced.
Reading this attribute will return the current accelerometer
power mode if the sensor is on, or the requested value if the
sensor is off. The value between real and requested value can
be different for ODR supporting only 1 mode.
What: /sys/bus/iio/devices/iio:deviceX/in_accel_power_mode_available
KernelVersion: 6.11
Contact: linux-iio@vger.kernel.org
Description:
List of available accelerometer power modes that can be set in
in_accel_power_mode attribute.
......@@ -38,6 +38,14 @@ properties:
The first value specifies the positive input pin, the second
specifies the negative input pin.
single-channel:
$ref: /schemas/types.yaml#/definitions/uint32
description:
When devices combine single-ended and differential channels, allow the
channel for a single element to be specified, independent of reg (as for
differential channels). If this and diff-channels are not present reg
shall be used instead.
settling-time-us:
description:
Time between enabling the channel and first stable readings.
......@@ -50,4 +58,15 @@ properties:
device design and can interact with other characteristics such as
settling time.
anyOf:
- oneOf:
- required:
- reg
- diff-channels
- required:
- reg
- single-channel
- required:
- reg
additionalProperties: true
......@@ -21,8 +21,15 @@ properties:
- adi,ad7190
- adi,ad7192
- adi,ad7193
- adi,ad7194
- adi,ad7195
"#address-cells":
const: 1
"#size-cells":
const: 0
reg:
maxItems: 1
......@@ -41,6 +48,11 @@ properties:
interrupts:
maxItems: 1
aincom-supply:
description: |
AINCOM voltage supply. Analog inputs AINx are referenced to this input
when configured for pseudo-differential operation.
dvdd-supply:
description: DVdd voltage supply
......@@ -84,6 +96,42 @@ properties:
description: see Documentation/devicetree/bindings/iio/adc/adc.yaml
type: boolean
patternProperties:
"^channel@[0-9a-f]+$":
type: object
$ref: adc.yaml
unevaluatedProperties: false
properties:
reg:
description: The channel index.
minimum: 0
maximum: 271
diff-channels:
description:
Both inputs can be connected to pins AIN1 to AIN16 by choosing the
appropriate value from 1 to 16.
items:
minimum: 1
maximum: 16
single-channel:
description:
Positive input can be connected to pins AIN1 to AIN16 by choosing the
appropriate value from 1 to 16. Negative input is connected to AINCOM.
items:
minimum: 1
maximum: 16
oneOf:
- required:
- reg
- diff-channels
- required:
- reg
- single-channel
required:
- compatible
- reg
......@@ -98,6 +146,17 @@ required:
allOf:
- $ref: /schemas/spi/spi-peripheral-props.yaml#
- if:
properties:
compatible:
enum:
- adi,ad7190
- adi,ad7192
- adi,ad7193
- adi,ad7195
then:
patternProperties:
"^channel@[0-9a-f]+$": false
unevaluatedProperties: false
......@@ -117,6 +176,7 @@ examples:
clock-names = "mclk";
interrupts = <25 0x2>;
interrupt-parent = <&gpio>;
aincom-supply = <&aincom>;
dvdd-supply = <&dvdd>;
avdd-supply = <&avdd>;
vref-supply = <&vref>;
......@@ -127,3 +187,38 @@ examples:
adi,burnout-currents-enable;
};
};
- |
spi {
#address-cells = <1>;
#size-cells = <0>;
adc@0 {
compatible = "adi,ad7194";
reg = <0>;
#address-cells = <1>;
#size-cells = <0>;
spi-max-frequency = <1000000>;
spi-cpol;
spi-cpha;
clocks = <&ad7192_mclk>;
clock-names = "mclk";
interrupts = <25 0x2>;
interrupt-parent = <&gpio>;
aincom-supply = <&aincom>;
dvdd-supply = <&dvdd>;
avdd-supply = <&avdd>;
vref-supply = <&vref>;
channel@0 {
reg = <0>;
diff-channels = <1 6>;
};
channel@1 {
reg = <1>;
single-channel = <1>;
};
};
};
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/adc/adi,ad7380.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Analog Devices Simultaneous Sampling Analog to Digital Converters
maintainers:
- Michael Hennerich <Michael.Hennerich@analog.com>
- Nuno Sá <nuno.sa@analog.com>
description: |
* https://www.analog.com/en/products/ad7380.html
* https://www.analog.com/en/products/ad7381.html
* https://www.analog.com/en/products/ad7383.html
* https://www.analog.com/en/products/ad7384.html
* https://www.analog.com/en/products/ad7380-4.html
* https://www.analog.com/en/products/ad7381-4.html
* https://www.analog.com/en/products/ad7383-4.html
* https://www.analog.com/en/products/ad7384-4.html
$ref: /schemas/spi/spi-peripheral-props.yaml#
properties:
compatible:
enum:
- adi,ad7380
- adi,ad7381
- adi,ad7383
- adi,ad7384
- adi,ad7380-4
- adi,ad7381-4
- adi,ad7383-4
- adi,ad7384-4
reg:
maxItems: 1
spi-max-frequency:
maximum: 80000000
spi-cpol: true
spi-cpha: true
vcc-supply:
description: A 3V to 3.6V supply that powers the chip.
vlogic-supply:
description:
A 1.65V to 3.6V supply for the logic pins.
refio-supply:
description:
A 2.5V to 3.3V supply for the external reference voltage. When omitted,
the internal 2.5V reference is used.
aina-supply:
description:
The common mode voltage supply for the AINA- pin on pseudo-differential
chips.
ainb-supply:
description:
The common mode voltage supply for the AINB- pin on pseudo-differential
chips.
ainc-supply:
description:
The common mode voltage supply for the AINC- pin on pseudo-differential
chips.
aind-supply:
description:
The common mode voltage supply for the AIND- pin on pseudo-differential
chips.
interrupts:
description:
When the device is using 1-wire mode, this property is used to optionally
specify the ALERT interrupt.
maxItems: 1
required:
- compatible
- reg
- vcc-supply
- vlogic-supply
unevaluatedProperties: false
allOf:
# pseudo-differential chips require common mode voltage supplies,
# true differential chips don't use them
- if:
properties:
compatible:
enum:
- adi,ad7383
- adi,ad7384
- adi,ad7383-4
- adi,ad7384-4
then:
required:
- aina-supply
- ainb-supply
else:
properties:
aina-supply: false
ainb-supply: false
- if:
properties:
compatible:
enum:
- adi,ad7383-4
- adi,ad7384-4
then:
required:
- ainc-supply
- aind-supply
else:
properties:
ainc-supply: false
aind-supply: false
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
spi {
#address-cells = <1>;
#size-cells = <0>;
adc@0 {
compatible = "adi,ad7380";
reg = <0>;
spi-cpol;
spi-cpha;
spi-max-frequency = <80000000>;
interrupts = <27 IRQ_TYPE_EDGE_FALLING>;
interrupt-parent = <&gpio0>;
vcc-supply = <&supply_3_3V>;
vlogic-supply = <&supply_3_3V>;
refio-supply = <&supply_2_5V>;
};
};
......@@ -66,6 +66,9 @@ properties:
nvmem-cell-names:
const: temperature_calib
power-domains:
maxItems: 1
allOf:
- if:
properties:
......
......@@ -18,6 +18,7 @@ properties:
enum:
- ti,ads1015
- ti,ads1115
- ti,tla2021
- ti,tla2024
reg:
......
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/chemical/sciosense,ens160.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: ScioSense ENS160 multi-gas sensor
maintainers:
- Gustavo Silva <gustavograzs@gmail.com>
description: |
Digital Multi-Gas Sensor for Monitoring Indoor Air Quality.
Datasheet:
https://www.sciosense.com/wp-content/uploads/2023/12/ENS160-Datasheet.pdf
properties:
compatible:
enum:
- sciosense,ens160
reg:
maxItems: 1
interrupts:
maxItems: 1
vdd-supply: true
vddio-supply: true
required:
- compatible
- reg
allOf:
- $ref: /schemas/spi/spi-peripheral-props.yaml#
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
gas-sensor@52 {
compatible = "sciosense,ens160";
reg = <0x52>;
interrupt-parent = <&gpio0>;
interrupts = <19 IRQ_TYPE_EDGE_FALLING>;
};
};
- |
#include <dt-bindings/interrupt-controller/irq.h>
spi {
#address-cells = <1>;
#size-cells = <0>;
gas-sensor@0 {
compatible = "sciosense,ens160";
reg = <0>;
spi-max-frequency = <10000000>;
interrupt-parent = <&gpio>;
interrupts = <19 IRQ_TYPE_EDGE_FALLING>;
};
};
...
......@@ -13,13 +13,17 @@ maintainers:
description: |
Bindings for the Analog Devices AD3552R DAC device and similar.
Datasheet can be found here:
https://www.analog.com/media/en/technical-documentation/data-sheets/ad3541r.pdf
https://www.analog.com/media/en/technical-documentation/data-sheets/ad3542r.pdf
https://www.analog.com/media/en/technical-documentation/data-sheets/ad3551r.pdf
https://www.analog.com/media/en/technical-documentation/data-sheets/ad3552r.pdf
properties:
compatible:
enum:
- adi,ad3541r
- adi,ad3542r
- adi,ad3551r
- adi,ad3552r
reg:
......@@ -92,13 +96,13 @@ patternProperties:
maximum: 511
minimum: -511
adi,gain-scaling-p-inv-log2:
description: GainP = 1 / ( 2 ^ adi,gain-scaling-p-inv-log2)
adi,gain-scaling-p:
description: GainP = 1 / ( 2 ^ adi,gain-scaling-p)
$ref: /schemas/types.yaml#/definitions/uint32
enum: [0, 1, 2, 3]
adi,gain-scaling-n-inv-log2:
description: GainN = 1 / ( 2 ^ adi,gain-scaling-n-inv-log2)
adi,gain-scaling-n:
description: GainN = 1 / ( 2 ^ adi,gain-scaling-n)
$ref: /schemas/types.yaml#/definitions/uint32
enum: [0, 1, 2, 3]
......@@ -107,8 +111,8 @@ patternProperties:
required:
- adi,gain-offset
- adi,gain-scaling-p-inv-log2
- adi,gain-scaling-n-inv-log2
- adi,gain-scaling-p
- adi,gain-scaling-n
- adi,rfb-ohms
required:
......@@ -128,7 +132,9 @@ allOf:
properties:
compatible:
contains:
const: adi,ad3542r
enum:
- adi,ad3541r
- adi,ad3542r
then:
patternProperties:
"^channel@([0-1])$":
......@@ -158,7 +164,9 @@ allOf:
properties:
compatible:
contains:
const: adi,ad3552r
enum:
- adi,ad3551r
- adi,ad3552r
then:
patternProperties:
"^channel@([0-1])$":
......@@ -182,6 +190,21 @@ allOf:
- const: -10000000
- const: 10000000
- if:
properties:
compatible:
contains:
enum:
- adi,ad3541r
- adi,ad3551r
then:
properties:
channel@1: false
channel@0:
properties:
reg:
const: 0
required:
- compatible
- reg
......@@ -208,8 +231,8 @@ examples:
reg = <1>;
custom-output-range-config {
adi,gain-offset = <5>;
adi,gain-scaling-p-inv-log2 = <1>;
adi,gain-scaling-n-inv-log2 = <2>;
adi,gain-scaling-p = <1>;
adi,gain-scaling-n = <2>;
adi,rfb-ohms = <1>;
};
};
......
......@@ -30,12 +30,19 @@ properties:
- adi,adis16467-2
- adi,adis16467-3
- adi,adis16500
- adi,adis16501
- adi,adis16505-1
- adi,adis16505-2
- adi,adis16505-3
- adi,adis16507-1
- adi,adis16507-2
- adi,adis16507-3
- adi,adis16575-2
- adi,adis16575-3
- adi,adis16576-2
- adi,adis16576-3
- adi,adis16577-2
- adi,adis16577-3
reg:
maxItems: 1
......@@ -90,12 +97,19 @@ allOf:
contains:
enum:
- adi,adis16500
- adi,adis16501
- adi,adis16505-1
- adi,adis16505-2
- adi,adis16505-3
- adi,adis16507-1
- adi,adis16507-2
- adi,adis16507-3
- adi,adis16575-2
- adi,adis16575-3
- adi,adis16576-2
- adi,adis16576-3
- adi,adis16577-2
- adi,adis16577-3
then:
properties:
......@@ -112,6 +126,23 @@ allOf:
dependencies:
adi,sync-mode: [ clocks ]
- if:
properties:
compatible:
contains:
enum:
- adi,adis16575-2
- adi,adis16575-3
- adi,adis16576-2
- adi,adis16576-3
- adi,adis16577-2
- adi,adis16577-3
then:
properties:
spi-max-frequency:
maximum: 15000000
unevaluatedProperties: false
examples:
......
......@@ -23,6 +23,12 @@ properties:
- adi,adis16497-1
- adi,adis16497-2
- adi,adis16497-3
- adi,adis16545-1
- adi,adis16545-2
- adi,adis16545-3
- adi,adis16547-1
- adi,adis16547-2
- adi,adis16547-3
reg:
maxItems: 1
......
......@@ -16,7 +16,11 @@ description: |
properties:
compatible:
const: bosch,bmi160
oneOf:
- const: bosch,bmi160
- items:
- const: bosch,bmi120
- const: bosch,bmi160
reg:
maxItems: 1
......
......@@ -4,14 +4,19 @@
$id: http://devicetree.org/schemas/iio/light/vishay,veml6075.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Vishay VEML6075 UVA and UVB sensor
title: Vishay VEML6075 UVA/B and VEML6040 RGBW sensors
maintainers:
- Javier Carrasco <javier.carrasco.cruz@gmail.com>
description:
VEML6040 datasheet at https://www.vishay.com/docs/84276/veml6040.pdf
properties:
compatible:
const: vishay,veml6075
enum:
- vishay,veml6040
- vishay,veml6075
reg:
maxItems: 1
......
......@@ -1254,6 +1254,8 @@ patternProperties:
description: Smart Battery System
"^schindler,.*":
description: Schindler
"^sciosense,.*":
description: ScioSense B.V.
"^seagate,.*":
description: Seagate Technology PLC
"^seeed,.*":
......
......@@ -380,24 +380,5 @@ data is structured.
4. IIO Interfacing Tools
========================
Linux Kernel Tools
------------------
Linux Kernel provides some userspace tools that can be used to retrieve data
from IIO sysfs:
* lsiio: example application that provides a list of IIO devices and triggers
* iio_event_monitor: example application that reads events from an IIO device
and prints them
* iio_generic_buffer: example application that reads data from buffer
* iio_utils: set of APIs, typically used to access sysfs files.
LibIIO
------
LibIIO is a C/C++ library that provides generic access to IIO devices. The
library abstracts the low-level details of the hardware, and provides a simple
yet complete programming interface that can be used for advanced projects.
For more information about LibIIO, please see:
https://github.com/analogdevicesinc/libiio
See ``Documentation/iio/iio_tools.rst`` for the description of the available IIO
interfacing tools.
This diff is collapsed.
.. SPDX-License-Identifier: GPL-2.0
=====================
IIO Interfacing Tools
=====================
1. Linux Kernel Tools
=====================
Linux Kernel provides some userspace tools that can be used to retrieve data
from IIO sysfs:
* lsiio: example application that provides a list of IIO devices and triggers
* iio_event_monitor: example application that reads events from an IIO device
and prints them
* iio_generic_buffer: example application that reads data from buffer
* iio_utils: set of APIs, typically used to access sysfs files.
2. LibIIO
=========
LibIIO is a C/C++ library that provides generic access to IIO devices. The
library abstracts the low-level details of the hardware, and provides a simple
yet complete programming interface that can be used for advanced projects.
For more information about LibIIO, please see:
https://github.com/analogdevicesinc/libiio
......@@ -9,6 +9,7 @@ Industrial I/O
iio_configfs
iio_devbuf
iio_tools
Industrial I/O Kernel Drivers
=============================
......@@ -18,5 +19,6 @@ Industrial I/O Kernel Drivers
ad7944
adis16475
adis16480
bno055
ep93xx_adc
......@@ -439,6 +439,16 @@ W: http://wiki.analog.com/AD7142
W: https://ez.analog.com/linux-software-drivers
F: drivers/input/misc/ad714x.c
AD738X ADC DRIVER (AD7380/1/2/4)
M: Michael Hennerich <michael.hennerich@analog.com>
M: Nuno Sá <nuno.sa@analog.com>
R: David Lechner <dlechner@baylibre.com>
S: Supported
W: https://wiki.analog.com/resources/tools-software/linux-drivers/iio-adc/ad738x
W: https://ez.analog.com/linux-software-drivers
F: Documentation/devicetree/bindings/iio/adc/adi,ad7380.yaml
F: drivers/iio/adc/ad7380.c
AD7877 TOUCHSCREEN DRIVER
M: Michael Hennerich <michael.hennerich@analog.com>
S: Supported
......@@ -11510,6 +11520,7 @@ M: Jean-Baptiste Maneyrol <jmaneyrol@invensense.com>
L: linux-iio@vger.kernel.org
S: Maintained
W: https://invensense.tdk.com/
F: Documentation/ABI/testing/sysfs-bus-iio-inv_icm42600
F: Documentation/devicetree/bindings/iio/imu/invensense,icm42600.yaml
F: drivers/iio/imu/inv_icm42600/
......@@ -19938,6 +19949,14 @@ F: include/linux/wait.h
F: include/uapi/linux/sched.h
F: kernel/sched/
SCIOSENSE ENS160 MULTI-GAS SENSOR DRIVER
M: Gustavo Silva <gustavograzs@gmail.com>
S: Maintained
F: drivers/iio/chemical/ens160_core.c
F: drivers/iio/chemical/ens160_i2c.c
F: drivers/iio/chemical/ens160_spi.c
F: drivers/iio/chemical/ens160.h
SCSI LIBSAS SUBSYSTEM
R: John Garry <john.g.garry@oracle.com>
R: Jason Yan <yanaijie@huawei.com>
......
......@@ -72,13 +72,7 @@ static int adxl313_spi_probe(struct spi_device *spi)
if (ret)
return ret;
/*
* Retrieves device specific data as a pointer to a
* adxl313_chip_info structure
*/
chip_data = device_get_match_data(&spi->dev);
if (!chip_data)
chip_data = (const struct adxl313_chip_info *)spi_get_device_id(spi)->driver_data;
chip_data = spi_get_device_match_data(spi);
regmap = devm_regmap_init_spi(spi,
&adxl31x_spi_regmap_config[chip_data->type]);
......
......@@ -28,13 +28,9 @@ static int adxl355_spi_probe(struct spi_device *spi)
const struct adxl355_chip_info *chip_data;
struct regmap *regmap;
chip_data = device_get_match_data(&spi->dev);
if (!chip_data) {
chip_data = (void *)spi_get_device_id(spi)->driver_data;
if (!chip_data)
return -EINVAL;
}
chip_data = spi_get_device_match_data(spi);
if (!chip_data)
return -EINVAL;
regmap = devm_regmap_init_spi(spi, &adxl355_spi_regmap_config);
if (IS_ERR(regmap)) {
......
......@@ -61,8 +61,8 @@ static int adxl367_i2c_probe(struct i2c_client *client)
}
static const struct i2c_device_id adxl367_i2c_id[] = {
{ "adxl367", 0 },
{ },
{ "adxl367" },
{ }
};
MODULE_DEVICE_TABLE(i2c, adxl367_i2c_id);
......
......@@ -42,7 +42,7 @@ static int adxl372_i2c_probe(struct i2c_client *client)
}
static const struct i2c_device_id adxl372_i2c_id[] = {
{ "adxl372", 0 },
{ "adxl372" },
{}
};
MODULE_DEVICE_TABLE(i2c, adxl372_i2c_id);
......
......@@ -28,7 +28,7 @@ static int bma400_i2c_probe(struct i2c_client *client)
}
static const struct i2c_device_id bma400_i2c_ids[] = {
{ "bma400", 0 },
{ "bma400" },
{ }
};
MODULE_DEVICE_TABLE(i2c, bma400_i2c_ids);
......
......@@ -114,11 +114,6 @@ enum bmi088_odr_modes {
BMI088_ACCEL_MODE_ODR_1600 = 0xc,
};
struct bmi088_scale_info {
int scale;
u8 reg_range;
};
struct bmi088_accel_chip_info {
const char *name;
u8 chip_id;
......
......@@ -268,7 +268,7 @@ static int da311_resume(struct device *dev)
static DEFINE_SIMPLE_DEV_PM_OPS(da311_pm_ops, da311_suspend, da311_resume);
static const struct i2c_device_id da311_i2c_id[] = {
{"da311", 0},
{ "da311" },
{}
};
MODULE_DEVICE_TABLE(i2c, da311_i2c_id);
......
......@@ -201,9 +201,9 @@ static DEFINE_SIMPLE_DEV_PM_OPS(dmard06_pm_ops, dmard06_suspend,
dmard06_resume);
static const struct i2c_device_id dmard06_id[] = {
{ "dmard05", 0 },
{ "dmard06", 0 },
{ "dmard07", 0 },
{ "dmard05" },
{ "dmard06" },
{ "dmard07" },
{ }
};
MODULE_DEVICE_TABLE(i2c, dmard06_id);
......
......@@ -125,8 +125,8 @@ static int dmard09_probe(struct i2c_client *client)
}
static const struct i2c_device_id dmard09_id[] = {
{ "dmard09", 0 },
{ },
{ "dmard09" },
{ }
};
MODULE_DEVICE_TABLE(i2c, dmard09_id);
......
......@@ -231,7 +231,7 @@ static DEFINE_SIMPLE_DEV_PM_OPS(dmard10_pm_ops, dmard10_suspend,
dmard10_resume);
static const struct i2c_device_id dmard10_i2c_id[] = {
{"dmard10", 0},
{ "dmard10" },
{}
};
MODULE_DEVICE_TABLE(i2c, dmard10_i2c_id);
......
......@@ -43,8 +43,8 @@ static const struct of_device_id kxsd9_of_match[] = {
MODULE_DEVICE_TABLE(of, kxsd9_of_match);
static const struct i2c_device_id kxsd9_i2c_id[] = {
{"kxsd9", 0},
{ },
{ "kxsd9" },
{ }
};
MODULE_DEVICE_TABLE(i2c, kxsd9_i2c_id);
......
......@@ -180,7 +180,7 @@ static int mc3230_resume(struct device *dev)
static DEFINE_SIMPLE_DEV_PM_OPS(mc3230_pm_ops, mc3230_suspend, mc3230_resume);
static const struct i2c_device_id mc3230_i2c_id[] = {
{"mc3230", 0},
{ "mc3230" },
{}
};
MODULE_DEVICE_TABLE(i2c, mc3230_i2c_id);
......
......@@ -32,8 +32,8 @@ static void mma7455_i2c_remove(struct i2c_client *i2c)
}
static const struct i2c_device_id mma7455_i2c_ids[] = {
{ "mma7455", 0 },
{ "mma7456", 0 },
{ "mma7455" },
{ "mma7456" },
{ }
};
MODULE_DEVICE_TABLE(i2c, mma7455_i2c_ids);
......
......@@ -38,21 +38,6 @@
static const int mma7660_nscale = 467142857;
#define MMA7660_CHANNEL(reg, axis) { \
.type = IIO_ACCEL, \
.address = reg, \
.modified = 1, \
.channel2 = IIO_MOD_##axis, \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
}
static const struct iio_chan_spec mma7660_channels[] = {
MMA7660_CHANNEL(MMA7660_REG_XOUT, X),
MMA7660_CHANNEL(MMA7660_REG_YOUT, Y),
MMA7660_CHANNEL(MMA7660_REG_ZOUT, Z),
};
enum mma7660_mode {
MMA7660_MODE_STANDBY,
MMA7660_MODE_ACTIVE
......@@ -62,6 +47,21 @@ struct mma7660_data {
struct i2c_client *client;
struct mutex lock;
enum mma7660_mode mode;
struct iio_mount_matrix orientation;
};
static const struct iio_mount_matrix *
mma7660_get_mount_matrix(const struct iio_dev *indio_dev,
const struct iio_chan_spec *chan)
{
struct mma7660_data *data = iio_priv(indio_dev);
return &data->orientation;
}
static const struct iio_chan_spec_ext_info mma7660_ext_info[] = {
IIO_MOUNT_MATRIX(IIO_SHARED_BY_DIR, mma7660_get_mount_matrix),
{ }
};
static IIO_CONST_ATTR(in_accel_scale_available, MMA7660_SCALE_AVAIL);
......@@ -75,6 +75,22 @@ static const struct attribute_group mma7660_attribute_group = {
.attrs = mma7660_attributes
};
#define MMA7660_CHANNEL(reg, axis) { \
.type = IIO_ACCEL, \
.address = reg, \
.modified = 1, \
.channel2 = IIO_MOD_##axis, \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
.ext_info = mma7660_ext_info, \
}
static const struct iio_chan_spec mma7660_channels[] = {
MMA7660_CHANNEL(MMA7660_REG_XOUT, X),
MMA7660_CHANNEL(MMA7660_REG_YOUT, Y),
MMA7660_CHANNEL(MMA7660_REG_ZOUT, Z),
};
static int mma7660_set_mode(struct mma7660_data *data,
enum mma7660_mode mode)
{
......@@ -187,6 +203,10 @@ static int mma7660_probe(struct i2c_client *client)
mutex_init(&data->lock);
data->mode = MMA7660_MODE_STANDBY;
ret = iio_read_mount_matrix(&client->dev, &data->orientation);
if (ret)
return ret;
indio_dev->info = &mma7660_info;
indio_dev->name = MMA7660_DRIVER_NAME;
indio_dev->modes = INDIO_DIRECT_MODE;
......@@ -241,7 +261,7 @@ static DEFINE_SIMPLE_DEV_PM_OPS(mma7660_pm_ops, mma7660_suspend,
mma7660_resume);
static const struct i2c_device_id mma7660_i2c_id[] = {
{"mma7660", 0},
{ "mma7660" },
{}
};
MODULE_DEVICE_TABLE(i2c, mma7660_i2c_id);
......
......@@ -595,7 +595,7 @@ static const struct acpi_device_id mma9551_acpi_match[] = {
MODULE_DEVICE_TABLE(acpi, mma9551_acpi_match);
static const struct i2c_device_id mma9551_id[] = {
{"mma9551", 0},
{ "mma9551" },
{}
};
......
......@@ -1234,8 +1234,8 @@ static const struct acpi_device_id mma9553_acpi_match[] = {
MODULE_DEVICE_TABLE(acpi, mma9553_acpi_match);
static const struct i2c_device_id mma9553_id[] = {
{"mma9553", 0},
{},
{ "mma9553" },
{}
};
MODULE_DEVICE_TABLE(i2c, mma9553_id);
......
......@@ -584,9 +584,9 @@ static const struct of_device_id mxc4005_of_match[] = {
MODULE_DEVICE_TABLE(of, mxc4005_of_match);
static const struct i2c_device_id mxc4005_id[] = {
{"mxc4005", 0},
{"mxc6655", 0},
{ },
{ "mxc4005" },
{ "mxc6655" },
{ }
};
MODULE_DEVICE_TABLE(i2c, mxc4005_id);
......
......@@ -172,8 +172,8 @@ static const struct acpi_device_id mxc6255_acpi_match[] = {
MODULE_DEVICE_TABLE(acpi, mxc6255_acpi_match);
static const struct i2c_device_id mxc6255_id[] = {
{"mxc6225", 0},
{"mxc6255", 0},
{ "mxc6225" },
{ "mxc6255" },
{ }
};
MODULE_DEVICE_TABLE(i2c, mxc6255_id);
......
......@@ -633,8 +633,8 @@ static DEFINE_SIMPLE_DEV_PM_OPS(stk8312_pm_ops, stk8312_suspend,
static const struct i2c_device_id stk8312_i2c_id[] = {
/* Deprecated in favour of lowercase form */
{ "STK8312", 0 },
{ "stk8312", 0 },
{ "STK8312" },
{ "stk8312" },
{}
};
MODULE_DEVICE_TABLE(i2c, stk8312_i2c_id);
......
......@@ -525,7 +525,7 @@ static DEFINE_SIMPLE_DEV_PM_OPS(stk8ba50_pm_ops, stk8ba50_suspend,
stk8ba50_resume);
static const struct i2c_device_id stk8ba50_i2c_id[] = {
{"stk8ba50", 0},
{ "stk8ba50" },
{}
};
MODULE_DEVICE_TABLE(i2c, stk8ba50_i2c_id);
......
......@@ -88,12 +88,17 @@ config AD7173
called ad7173.
config AD7192
tristate "Analog Devices AD7190 AD7192 AD7193 AD7195 ADC driver"
tristate "Analog Devices AD7192 and similar ADC driver"
depends on SPI
select AD_SIGMA_DELTA
help
Say yes here to build support for Analog Devices AD7190,
AD7192, AD7193 or AD7195 SPI analog to digital converters (ADC).
Say yes here to build support for Analog Devices SPI analog to digital
converters (ADC):
- AD7190
- AD7192
- AD7193
- AD7194
- AD7195
If unsure, say N (but it's safe to say "Y").
To compile this driver as a module, choose M here: the
......@@ -155,6 +160,22 @@ config AD7298
To compile this driver as a module, choose M here: the
module will be called ad7298.
config AD7380
tristate "Analog Devices AD7380 ADC driver"
depends on SPI_MASTER
select IIO_BUFFER
select IIO_TRIGGER
select IIO_TRIGGERED_BUFFER
help
AD7380 is a family of simultaneous sampling ADCs that share the same
SPI register map and have similar pinouts.
Say yes here to build support for Analog Devices AD7380 ADC and
similar chips.
To compile this driver as a module, choose M here: the module will be
called ad7380.
config AD7476
tristate "Analog Devices AD7476 1-channel ADCs driver and other similar devices from AD and TI"
depends on SPI
......@@ -332,6 +353,7 @@ config AD9467
config ADI_AXI_ADC
tristate "Analog Devices Generic AXI ADC IP core driver"
depends on MICROBLAZE || NIOS2 || ARCH_ZYNQ || ARCH_ZYNQMP || ARCH_INTEL_SOCFPGA || COMPILE_TEST
select IIO_BUFFER
select IIO_BUFFER_HW_CONSUMER
select IIO_BUFFER_DMAENGINE
......
......@@ -18,7 +18,7 @@ obj-$(CONFIG_AD7280) += ad7280a.o
obj-$(CONFIG_AD7291) += ad7291.o
obj-$(CONFIG_AD7292) += ad7292.o
obj-$(CONFIG_AD7298) += ad7298.o
obj-$(CONFIG_AD7923) += ad7923.o
obj-$(CONFIG_AD7380) += ad7380.o
obj-$(CONFIG_AD7476) += ad7476.o
obj-$(CONFIG_AD7606_IFACE_PARALLEL) += ad7606_par.o
obj-$(CONFIG_AD7606_IFACE_SPI) += ad7606_spi.o
......@@ -29,6 +29,7 @@ obj-$(CONFIG_AD7780) += ad7780.o
obj-$(CONFIG_AD7791) += ad7791.o
obj-$(CONFIG_AD7793) += ad7793.o
obj-$(CONFIG_AD7887) += ad7887.o
obj-$(CONFIG_AD7923) += ad7923.o
obj-$(CONFIG_AD7944) += ad7944.o
obj-$(CONFIG_AD7949) += ad7949.o
obj-$(CONFIG_AD799X) += ad799x.o
......@@ -90,42 +91,43 @@ obj-$(CONFIG_NAU7802) += nau7802.o
obj-$(CONFIG_NPCM_ADC) += npcm_adc.o
obj-$(CONFIG_PAC1934) += pac1934.o
obj-$(CONFIG_PALMAS_GPADC) += palmas_gpadc.o
obj-$(CONFIG_QCOM_PM8XXX_XOADC) += qcom-pm8xxx-xoadc.o
obj-$(CONFIG_QCOM_SPMI_ADC5) += qcom-spmi-adc5.o
obj-$(CONFIG_QCOM_SPMI_IADC) += qcom-spmi-iadc.o
obj-$(CONFIG_QCOM_SPMI_RRADC) += qcom-spmi-rradc.o
obj-$(CONFIG_QCOM_VADC_COMMON) += qcom-vadc-common.o
obj-$(CONFIG_QCOM_SPMI_VADC) += qcom-spmi-vadc.o
obj-$(CONFIG_QCOM_PM8XXX_XOADC) += qcom-pm8xxx-xoadc.o
obj-$(CONFIG_QCOM_VADC_COMMON) += qcom-vadc-common.o
obj-$(CONFIG_RCAR_GYRO_ADC) += rcar-gyroadc.o
obj-$(CONFIG_RICHTEK_RTQ6056) += rtq6056.o
obj-$(CONFIG_RN5T618_ADC) += rn5t618-adc.o
obj-$(CONFIG_ROCKCHIP_SARADC) += rockchip_saradc.o
obj-$(CONFIG_RICHTEK_RTQ6056) += rtq6056.o
obj-$(CONFIG_RZG2L_ADC) += rzg2l_adc.o
obj-$(CONFIG_SC27XX_ADC) += sc27xx_adc.o
obj-$(CONFIG_SD_ADC_MODULATOR) += sd_adc_modulator.o
obj-$(CONFIG_SPEAR_ADC) += spear_adc.o
obj-$(CONFIG_SUN4I_GPADC) += sun4i-gpadc-iio.o
obj-$(CONFIG_SUN20I_GPADC) += sun20i-gpadc-iio.o
obj-$(CONFIG_STM32_ADC_CORE) += stm32-adc-core.o
obj-$(CONFIG_STM32_ADC) += stm32-adc.o
obj-$(CONFIG_STM32_DFSDM_CORE) += stm32-dfsdm-core.o
obj-$(CONFIG_STM32_DFSDM_ADC) += stm32-dfsdm-adc.o
obj-$(CONFIG_STM32_DFSDM_CORE) += stm32-dfsdm-core.o
obj-$(CONFIG_STMPE_ADC) += stmpe-adc.o
obj-$(CONFIG_SUN20I_GPADC) += sun20i-gpadc-iio.o
obj-$(CONFIG_SUN4I_GPADC) += sun4i-gpadc-iio.o
obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o
obj-$(CONFIG_TI_ADC0832) += ti-adc0832.o
obj-$(CONFIG_TI_ADC084S021) += ti-adc084s021.o
obj-$(CONFIG_TI_ADC12138) += ti-adc12138.o
obj-$(CONFIG_TI_ADC108S102) += ti-adc108s102.o
obj-$(CONFIG_TI_ADC12138) += ti-adc12138.o
obj-$(CONFIG_TI_ADC128S052) += ti-adc128s052.o
obj-$(CONFIG_TI_ADC161S626) += ti-adc161s626.o
obj-$(CONFIG_TI_ADS1015) += ti-ads1015.o
obj-$(CONFIG_TI_ADS1100) += ti-ads1100.o
obj-$(CONFIG_TI_ADS124S08) += ti-ads124s08.o
obj-$(CONFIG_TI_ADS1298) += ti-ads1298.o
obj-$(CONFIG_TI_ADS131E08) += ti-ads131e08.o
obj-$(CONFIG_TI_ADS7924) += ti-ads7924.o
obj-$(CONFIG_TI_ADS7950) += ti-ads7950.o
obj-$(CONFIG_TI_ADS8344) += ti-ads8344.o
obj-$(CONFIG_TI_ADS8688) += ti-ads8688.o
obj-$(CONFIG_TI_ADS124S08) += ti-ads124s08.o
obj-$(CONFIG_TI_ADS131E08) += ti-ads131e08.o
obj-$(CONFIG_TI_AM335X_ADC) += ti_am335x_adc.o
obj-$(CONFIG_TI_LMP92064) += ti-lmp92064.o
obj-$(CONFIG_TI_TLC4541) += ti-tlc4541.o
......@@ -134,7 +136,6 @@ obj-$(CONFIG_TWL4030_MADC) += twl4030-madc.o
obj-$(CONFIG_TWL6030_GPADC) += twl6030-gpadc.o
obj-$(CONFIG_VF610_ADC) += vf610_adc.o
obj-$(CONFIG_VIPERBOARD_ADC) += viperboard_adc.o
obj-$(CONFIG_XILINX_AMS) += xilinx-ams.o
xilinx-xadc-y := xilinx-xadc-core.o xilinx-xadc-events.o
obj-$(CONFIG_XILINX_XADC) += xilinx-xadc.o
obj-$(CONFIG_XILINX_AMS) += xilinx-ams.o
obj-$(CONFIG_SD_ADC_MODULATOR) += sd_adc_modulator.o
This diff is collapsed.
......@@ -536,7 +536,7 @@ static int ad7291_probe(struct i2c_client *client)
}
static const struct i2c_device_id ad7291_id[] = {
{ "ad7291", 0 },
{ "ad7291" },
{}
};
......
This diff is collapsed.
......@@ -174,17 +174,14 @@ static int ad7606_read_raw(struct iio_dev *indio_dev,
switch (m) {
case IIO_CHAN_INFO_RAW:
ret = iio_device_claim_direct_mode(indio_dev);
if (ret)
return ret;
ret = ad7606_scan_direct(indio_dev, chan->address);
iio_device_release_direct_mode(indio_dev);
if (ret < 0)
return ret;
*val = (short)ret;
return IIO_VAL_INT;
iio_device_claim_direct_scoped(return -EBUSY, indio_dev) {
ret = ad7606_scan_direct(indio_dev, chan->address);
if (ret < 0)
return ret;
*val = (short) ret;
return IIO_VAL_INT;
}
unreachable();
case IIO_CHAN_INFO_SCALE:
if (st->sw_mode_en)
ch = chan->address;
......
......@@ -259,7 +259,6 @@ static int ad7944_chain_mode_init_msg(struct device *dev, struct ad7944_adc *adc
/**
* ad7944_convert_and_acquire - Perform a single conversion and acquisition
* @adc: The ADC device structure
* @chan: The channel specification
* Return: 0 on success, a negative error code on failure
*
* Perform a conversion and acquisition of a single sample using the
......@@ -268,8 +267,7 @@ static int ad7944_chain_mode_init_msg(struct device *dev, struct ad7944_adc *adc
* Upon successful return adc->sample.raw will contain the conversion result
* (or adc->chain_mode_buf if the device is using chain mode).
*/
static int ad7944_convert_and_acquire(struct ad7944_adc *adc,
const struct iio_chan_spec *chan)
static int ad7944_convert_and_acquire(struct ad7944_adc *adc)
{
int ret;
......@@ -291,7 +289,7 @@ static int ad7944_single_conversion(struct ad7944_adc *adc,
{
int ret;
ret = ad7944_convert_and_acquire(adc, chan);
ret = ad7944_convert_and_acquire(adc);
if (ret)
return ret;
......@@ -361,7 +359,7 @@ static irqreturn_t ad7944_trigger_handler(int irq, void *p)
struct ad7944_adc *adc = iio_priv(indio_dev);
int ret;
ret = ad7944_convert_and_acquire(adc, &indio_dev->channels[0]);
ret = ad7944_convert_and_acquire(adc);
if (ret)
goto out;
......
......@@ -107,27 +107,27 @@
#define AD9647_MAX_TEST_POINTS 32
struct ad9467_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;
unsigned int default_output_mode;
unsigned int vref_mask;
unsigned int num_lanes;
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;
unsigned int default_output_mode;
unsigned int vref_mask;
unsigned int num_lanes;
/* data clock output */
bool has_dco;
bool has_dco;
};
struct ad9467_state {
const struct ad9467_chip_info *info;
struct iio_backend *back;
struct spi_device *spi;
struct clk *clk;
unsigned int output_mode;
unsigned int (*scales)[2];
const struct ad9467_chip_info *info;
struct iio_backend *back;
struct spi_device *spi;
struct clk *clk;
unsigned int output_mode;
unsigned int (*scales)[2];
/*
* Times 2 because we may also invert the signal polarity and run the
* calibration again. For some reference on the test points (ad9265) see:
......@@ -138,12 +138,13 @@ struct ad9467_state {
* at the io delay control section.
*/
DECLARE_BITMAP(calib_map, AD9647_MAX_TEST_POINTS * 2);
struct gpio_desc *pwrdown_gpio;
struct gpio_desc *pwrdown_gpio;
/* ensure consistent state obtained on multiple related accesses */
struct mutex lock;
struct mutex lock;
u8 buf[3] __aligned(IIO_DMA_MINALIGN);
};
static int ad9467_spi_read(struct spi_device *spi, unsigned int reg)
static int ad9467_spi_read(struct ad9467_state *st, unsigned int reg)
{
unsigned char tbuf[2], rbuf[1];
int ret;
......@@ -151,7 +152,7 @@ static int ad9467_spi_read(struct spi_device *spi, unsigned int reg)
tbuf[0] = 0x80 | (reg >> 8);
tbuf[1] = reg & 0xFF;
ret = spi_write_then_read(spi,
ret = spi_write_then_read(st->spi,
tbuf, ARRAY_SIZE(tbuf),
rbuf, ARRAY_SIZE(rbuf));
......@@ -161,35 +162,32 @@ static int ad9467_spi_read(struct spi_device *spi, unsigned int reg)
return rbuf[0];
}
static int ad9467_spi_write(struct spi_device *spi, unsigned int reg,
static int ad9467_spi_write(struct ad9467_state *st, unsigned int reg,
unsigned int val)
{
unsigned char buf[3];
buf[0] = reg >> 8;
buf[1] = reg & 0xFF;
buf[2] = val;
st->buf[0] = reg >> 8;
st->buf[1] = reg & 0xFF;
st->buf[2] = val;
return spi_write(spi, buf, ARRAY_SIZE(buf));
return spi_write(st->spi, st->buf, ARRAY_SIZE(st->buf));
}
static int ad9467_reg_access(struct iio_dev *indio_dev, unsigned int reg,
unsigned int writeval, unsigned int *readval)
{
struct ad9467_state *st = iio_priv(indio_dev);
struct spi_device *spi = st->spi;
int ret;
if (!readval) {
guard(mutex)(&st->lock);
ret = ad9467_spi_write(spi, reg, writeval);
ret = ad9467_spi_write(st, reg, writeval);
if (ret)
return ret;
return ad9467_spi_write(spi, AN877_ADC_REG_TRANSFER,
return ad9467_spi_write(st, AN877_ADC_REG_TRANSFER,
AN877_ADC_TRANSFER_SYNC);
}
ret = ad9467_spi_read(spi, reg);
ret = ad9467_spi_read(st, reg);
if (ret < 0)
return ret;
*readval = ret;
......@@ -295,7 +293,7 @@ static int ad9467_get_scale(struct ad9467_state *st, int *val, int *val2)
unsigned int i, vref_val;
int ret;
ret = ad9467_spi_read(st->spi, AN877_ADC_REG_VREF);
ret = ad9467_spi_read(st, AN877_ADC_REG_VREF);
if (ret < 0)
return ret;
......@@ -330,31 +328,31 @@ static int ad9467_set_scale(struct ad9467_state *st, int val, int val2)
continue;
guard(mutex)(&st->lock);
ret = ad9467_spi_write(st->spi, AN877_ADC_REG_VREF,
ret = ad9467_spi_write(st, AN877_ADC_REG_VREF,
info->scale_table[i][1]);
if (ret < 0)
return ret;
return ad9467_spi_write(st->spi, AN877_ADC_REG_TRANSFER,
return ad9467_spi_write(st, AN877_ADC_REG_TRANSFER,
AN877_ADC_TRANSFER_SYNC);
}
return -EINVAL;
}
static int ad9467_outputmode_set(struct spi_device *spi, unsigned int mode)
static int ad9467_outputmode_set(struct ad9467_state *st, unsigned int mode)
{
int ret;
ret = ad9467_spi_write(spi, AN877_ADC_REG_OUTPUT_MODE, mode);
ret = ad9467_spi_write(st, AN877_ADC_REG_OUTPUT_MODE, mode);
if (ret < 0)
return ret;
return ad9467_spi_write(spi, AN877_ADC_REG_TRANSFER,
return ad9467_spi_write(st, AN877_ADC_REG_TRANSFER,
AN877_ADC_TRANSFER_SYNC);
}
static int ad9647_calibrate_prepare(const struct ad9467_state *st)
static int ad9647_calibrate_prepare(struct ad9467_state *st)
{
struct iio_backend_data_fmt data = {
.enable = false,
......@@ -362,17 +360,17 @@ static int ad9647_calibrate_prepare(const struct ad9467_state *st)
unsigned int c;
int ret;
ret = ad9467_spi_write(st->spi, AN877_ADC_REG_TEST_IO,
ret = ad9467_spi_write(st, AN877_ADC_REG_TEST_IO,
AN877_ADC_TESTMODE_PN9_SEQ);
if (ret)
return ret;
ret = ad9467_spi_write(st->spi, AN877_ADC_REG_TRANSFER,
ret = ad9467_spi_write(st, AN877_ADC_REG_TRANSFER,
AN877_ADC_TRANSFER_SYNC);
if (ret)
return ret;
ret = ad9467_outputmode_set(st->spi, st->info->default_output_mode);
ret = ad9467_outputmode_set(st, st->info->default_output_mode);
if (ret)
return ret;
......@@ -390,7 +388,7 @@ static int ad9647_calibrate_prepare(const struct ad9467_state *st)
return iio_backend_chan_enable(st->back, 0);
}
static int ad9647_calibrate_polarity_set(const struct ad9467_state *st,
static int ad9647_calibrate_polarity_set(struct ad9467_state *st,
bool invert)
{
enum iio_backend_sample_trigger trigger;
......@@ -401,7 +399,7 @@ static int ad9647_calibrate_polarity_set(const struct ad9467_state *st,
if (invert)
phase |= AN877_ADC_INVERT_DCO_CLK;
return ad9467_spi_write(st->spi, AN877_ADC_REG_OUTPUT_PHASE,
return ad9467_spi_write(st, AN877_ADC_REG_OUTPUT_PHASE,
phase);
}
......@@ -437,19 +435,18 @@ static unsigned int ad9467_find_optimal_point(const unsigned long *calib_map,
return cnt;
}
static int ad9467_calibrate_apply(const struct ad9467_state *st,
unsigned int val)
static int ad9467_calibrate_apply(struct ad9467_state *st, unsigned int val)
{
unsigned int lane;
int ret;
if (st->info->has_dco) {
ret = ad9467_spi_write(st->spi, AN877_ADC_REG_OUTPUT_DELAY,
ret = ad9467_spi_write(st, AN877_ADC_REG_OUTPUT_DELAY,
val);
if (ret)
return ret;
return ad9467_spi_write(st->spi, AN877_ADC_REG_TRANSFER,
return ad9467_spi_write(st, AN877_ADC_REG_TRANSFER,
AN877_ADC_TRANSFER_SYNC);
}
......@@ -462,7 +459,7 @@ static int ad9467_calibrate_apply(const struct ad9467_state *st,
return 0;
}
static int ad9647_calibrate_stop(const struct ad9467_state *st)
static int ad9647_calibrate_stop(struct ad9467_state *st)
{
struct iio_backend_data_fmt data = {
.sign_extend = true,
......@@ -487,16 +484,16 @@ static int ad9647_calibrate_stop(const struct ad9467_state *st)
}
mode = st->info->default_output_mode | AN877_ADC_OUTPUT_MODE_TWOS_COMPLEMENT;
ret = ad9467_outputmode_set(st->spi, mode);
ret = ad9467_outputmode_set(st, mode);
if (ret)
return ret;
ret = ad9467_spi_write(st->spi, AN877_ADC_REG_TEST_IO,
ret = ad9467_spi_write(st, AN877_ADC_REG_TEST_IO,
AN877_ADC_TESTMODE_OFF);
if (ret)
return ret;
return ad9467_spi_write(st->spi, AN877_ADC_REG_TRANSFER,
return ad9467_spi_write(st, AN877_ADC_REG_TRANSFER,
AN877_ADC_TRANSFER_SYNC);
}
......@@ -846,7 +843,7 @@ static int ad9467_probe(struct spi_device *spi)
if (ret)
return ret;
id = ad9467_spi_read(spi, AN877_ADC_REG_CHIP_ID);
id = ad9467_spi_read(st, AN877_ADC_REG_CHIP_ID);
if (id != st->info->id) {
dev_err(&spi->dev, "Mismatch CHIP_ID, got 0x%X, expected 0x%X\n",
id, st->info->id);
......
......@@ -42,6 +42,9 @@
#define ADI_AXI_ADC_REG_CTRL 0x0044
#define ADI_AXI_ADC_CTRL_DDR_EDGESEL_MASK BIT(1)
#define ADI_AXI_ADC_REG_DRP_STATUS 0x0074
#define ADI_AXI_ADC_DRP_LOCKED BIT(17)
/* ADC Channel controls */
#define ADI_AXI_REG_CHAN_CTRL(c) (0x0400 + (c) * 0x40)
......@@ -83,14 +86,26 @@ struct adi_axi_adc_state {
static int axi_adc_enable(struct iio_backend *back)
{
struct adi_axi_adc_state *st = iio_backend_get_priv(back);
unsigned int __val;
int ret;
guard(mutex)(&st->lock);
ret = regmap_set_bits(st->regmap, ADI_AXI_REG_RSTN,
ADI_AXI_REG_RSTN_MMCM_RSTN);
if (ret)
return ret;
fsleep(10000);
/*
* Make sure the DRP (Dynamic Reconfiguration Port) is locked. Not all
* designs really use it but if they don't we still get the lock bit
* set. So let's do it all the time so the code is generic.
*/
ret = regmap_read_poll_timeout(st->regmap, ADI_AXI_ADC_REG_DRP_STATUS,
__val, __val & ADI_AXI_ADC_DRP_LOCKED,
100, 1000);
if (ret)
return ret;
return regmap_set_bits(st->regmap, ADI_AXI_REG_RSTN,
ADI_AXI_REG_RSTN_RSTN | ADI_AXI_REG_RSTN_MMCM_RSTN);
}
......@@ -99,6 +114,7 @@ static void axi_adc_disable(struct iio_backend *back)
{
struct adi_axi_adc_state *st = iio_backend_get_priv(back);
guard(mutex)(&st->lock);
regmap_write(st->regmap, ADI_AXI_REG_RSTN, 0);
}
......
This diff is collapsed.
......@@ -920,4 +920,5 @@ static struct platform_driver ingenic_adc_driver = {
.probe = ingenic_adc_probe,
};
module_platform_driver(ingenic_adc_driver);
MODULE_DESCRIPTION("ADC driver for the Ingenic JZ47xx SoCs");
MODULE_LICENSE("GPL v2");
......@@ -124,7 +124,7 @@ static int ltc2485_probe(struct i2c_client *client)
}
static const struct i2c_device_id ltc2485_id[] = {
{ "ltc2485", 0 },
{ "ltc2485" },
{ }
};
MODULE_DEVICE_TABLE(i2c, ltc2485_id);
......
......@@ -116,10 +116,7 @@ static int max11205_probe(struct spi_device *spi)
ad_sd_init(&st->sd, indio_dev, spi, &max11205_sigma_delta_info);
st->chip_info = device_get_match_data(&spi->dev);
if (!st->chip_info)
st->chip_info =
(const struct max11205_chip_info *)spi_get_device_id(spi)->driver_data;
st->chip_info = spi_get_device_match_data(spi);
indio_dev->name = st->chip_info->name;
indio_dev->modes = INDIO_DIRECT_MODE;
......
......@@ -1114,7 +1114,6 @@ static int mcp3564_config(struct iio_dev *indio_dev)
{
struct mcp3564_state *adc = iio_priv(indio_dev);
struct device *dev = &adc->spi->dev;
const struct spi_device_id *dev_id;
u8 tmp_reg;
u16 tmp_u16;
enum mcp3564_ids ids;
......@@ -1212,11 +1211,6 @@ static int mcp3564_config(struct iio_dev *indio_dev)
* try using fallback compatible in device tree to deal with some newer part number.
*/
adc->chip_info = spi_get_device_match_data(adc->spi);
if (!adc->chip_info) {
dev_id = spi_get_device_id(adc->spi);
adc->chip_info = (const struct mcp3564_chip_info *)dev_id->driver_data;
}
adc->have_vref = adc->chip_info->have_vref;
} else {
adc->chip_info = &mcp3564_chip_infos_tbl[ids];
......
......@@ -532,7 +532,7 @@ static int nau7802_probe(struct i2c_client *client)
}
static const struct i2c_device_id nau7802_i2c_id[] = {
{ "nau7802", 0 },
{ "nau7802" },
{ }
};
MODULE_DEVICE_TABLE(i2c, nau7802_i2c_id);
......
......@@ -227,11 +227,6 @@ struct pac1934_features {
const char *name;
};
struct samp_rate_mapping {
u16 samp_rate;
u8 shift2value;
};
static const unsigned int samp_rate_map_tbl[] = {
[PAC1934_SAMP_1024SPS] = 1024,
[PAC1934_SAMP_256SPS] = 256,
......
......@@ -137,17 +137,13 @@ static int ti_adc_read_raw(struct iio_dev *indio_dev,
switch (mask) {
case IIO_CHAN_INFO_RAW:
ret = iio_device_claim_direct_mode(indio_dev);
if (ret)
return ret;
ret = ti_adc_read_measurement(data, chan, val);
iio_device_release_direct_mode(indio_dev);
if (ret)
return ret;
return IIO_VAL_INT;
iio_device_claim_direct_scoped(return -EBUSY, indio_dev) {
ret = ti_adc_read_measurement(data, chan, val);
if (ret)
return ret;
return IIO_VAL_INT;
}
unreachable();
case IIO_CHAN_INFO_SCALE:
ret = regulator_get_voltage(data->ref);
if (ret < 0)
......
......@@ -802,9 +802,7 @@ static int ads131e08_probe(struct spi_device *spi)
unsigned long adc_clk_ns;
int ret;
info = device_get_match_data(&spi->dev);
if (!info)
info = (void *)spi_get_device_id(spi)->driver_data;
info = spi_get_device_match_data(spi);
if (!info) {
dev_err(&spi->dev, "failed to get match data\n");
return -ENODEV;
......
......@@ -447,7 +447,7 @@ static int ads7924_probe(struct i2c_client *client)
}
static const struct i2c_device_id ads7924_id[] = {
{ "ads7924", 0 },
{ "ads7924" },
{}
};
MODULE_DEVICE_TABLE(i2c, ads7924_id);
......
......@@ -804,12 +804,7 @@ static int tsc2046_adc_probe(struct spi_device *spi)
return -EINVAL;
}
dcfg = device_get_match_data(dev);
if (!dcfg) {
const struct spi_device_id *id = spi_get_device_id(spi);
dcfg = (const struct tsc2046_adc_dcfg *)id->driver_data;
}
dcfg = spi_get_device_match_data(spi);
if (!dcfg)
return -EINVAL;
......
......@@ -1430,5 +1430,6 @@ static struct platform_driver ams_driver = {
};
module_platform_driver(ams_driver);
MODULE_DESCRIPTION("Xilinx AMS driver");
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Xilinx, Inc.");
......@@ -1365,16 +1365,9 @@ static int ad74413r_probe(struct spi_device *spi)
st->spi = spi;
st->dev = &spi->dev;
st->chip_info = device_get_match_data(&spi->dev);
if (!st->chip_info) {
const struct spi_device_id *id = spi_get_device_id(spi);
if (id)
st->chip_info =
(struct ad74413r_chip_info *)id->driver_data;
if (!st->chip_info)
return -EINVAL;
}
st->chip_info = spi_get_device_match_data(spi);
if (!st->chip_info)
return -EINVAL;
mutex_init(&st->lock);
init_completion(&st->adc_data_completion);
......
......@@ -287,4 +287,5 @@ int devm_iio_kfifo_buffer_setup_ext(struct device *dev,
}
EXPORT_SYMBOL_GPL(devm_iio_kfifo_buffer_setup_ext);
MODULE_DESCRIPTION("Industrial I/O buffering based on kfifo");
MODULE_LICENSE("GPL");
......@@ -76,6 +76,26 @@ config CCS811
Say Y here to build I2C interface support for the AMS
CCS811 VOC (Volatile Organic Compounds) sensor
config ENS160
tristate "ScioSense ENS160 sensor driver"
depends on (I2C || SPI)
select REGMAP
select ENS160_I2C if I2C
select ENS160_SPI if SPI
help
Say yes here to build support for ScioSense ENS160 multi-gas sensor.
This driver can also be built as a module. If so, the module for I2C
would be called ens160_i2c and ens160_spi for SPI support.
config ENS160_I2C
tristate
select REGMAP_I2C
config ENS160_SPI
tristate
select REGMAP_SPI
config IAQCORE
tristate "AMS iAQ-Core VOC sensors"
depends on I2C
......
......@@ -11,6 +11,9 @@ obj-$(CONFIG_BME680) += bme680_core.o
obj-$(CONFIG_BME680_I2C) += bme680_i2c.o
obj-$(CONFIG_BME680_SPI) += bme680_spi.o
obj-$(CONFIG_CCS811) += ccs811.o
obj-$(CONFIG_ENS160) += ens160_core.o
obj-$(CONFIG_ENS160_I2C) += ens160_i2c.o
obj-$(CONFIG_ENS160_SPI) += ens160_spi.o
obj-$(CONFIG_IAQCORE) += ams-iaq-core.o
obj-$(CONFIG_PMS7003) += pms7003.o
obj-$(CONFIG_SCD30_CORE) += scd30_core.o
......
......@@ -24,7 +24,7 @@ struct ams_iaqcore_reading {
u8 status;
__be32 resistance;
__be16 voc_ppb;
} __attribute__((__packed__));
} __packed;
struct ams_iaqcore_data {
struct i2c_client *client;
......@@ -163,7 +163,7 @@ static int ams_iaqcore_probe(struct i2c_client *client)
}
static const struct i2c_device_id ams_iaqcore_id[] = {
{ "ams-iaq-core", 0 },
{ "ams-iaq-core" },
{ }
};
MODULE_DEVICE_TABLE(i2c, ams_iaqcore_id);
......
......@@ -36,8 +36,8 @@ static int bme680_i2c_probe(struct i2c_client *client)
}
static const struct i2c_device_id bme680_i2c_id[] = {
{"bme680", 0},
{},
{ "bme680" },
{}
};
MODULE_DEVICE_TABLE(i2c, bme680_i2c_id);
......
......@@ -551,7 +551,7 @@ static void ccs811_remove(struct i2c_client *client)
}
static const struct i2c_device_id ccs811_id[] = {
{"ccs811", 0},
{ "ccs811" },
{ }
};
MODULE_DEVICE_TABLE(i2c, ccs811_id);
......
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef ENS160_H_
#define ENS160_H_
int devm_ens160_core_probe(struct device *dev, struct regmap *regmap, int irq,
const char *name);
extern const struct dev_pm_ops ens160_pm_ops;
#endif
// SPDX-License-Identifier: GPL-2.0
/*
* ScioSense ENS160 multi-gas sensor driver
*
* Copyright (c) 2024 Gustavo Silva <gustavograzs@gmail.com>
*
* Datasheet:
* https://www.sciosense.com/wp-content/uploads/2023/12/ENS160-Datasheet.pdf
*/
#include <linux/bitfield.h>
#include <linux/iio/iio.h>
#include <linux/iio/trigger.h>
#include <linux/iio/trigger_consumer.h>
#include <linux/iio/triggered_buffer.h>
#include <linux/module.h>
#include <linux/regmap.h>
#include "ens160.h"
#define ENS160_PART_ID 0x160
#define ENS160_BOOTING_TIME_MS 10U
#define ENS160_REG_PART_ID 0x00
#define ENS160_REG_OPMODE 0x10
#define ENS160_REG_CONFIG 0x11
#define ENS160_REG_CONFIG_INTEN BIT(0)
#define ENS160_REG_CONFIG_INTDAT BIT(1)
#define ENS160_REG_CONFIG_INT_CFG BIT(5)
#define ENS160_REG_MODE_DEEP_SLEEP 0x00
#define ENS160_REG_MODE_IDLE 0x01
#define ENS160_REG_MODE_STANDARD 0x02
#define ENS160_REG_MODE_RESET 0xF0
#define ENS160_REG_COMMAND 0x12
#define ENS160_REG_COMMAND_GET_APPVER 0x0E
#define ENS160_REG_COMMAND_CLRGPR 0xCC
#define ENS160_REG_TEMP_IN 0x13
#define ENS160_REG_RH_IN 0x15
#define ENS160_REG_DEVICE_STATUS 0x20
#define ENS160_REG_DATA_AQI 0x21
#define ENS160_REG_DATA_TVOC 0x22
#define ENS160_REG_DATA_ECO2 0x24
#define ENS160_REG_DATA_T 0x30
#define ENS160_REG_DATA_RH 0x32
#define ENS160_REG_GPR_READ4 0x4C
#define ENS160_STATUS_VALIDITY_FLAG GENMASK(3, 2)
#define ENS160_STATUS_NORMAL 0x00
struct ens160_data {
struct regmap *regmap;
/* Protect reads from the sensor */
struct mutex mutex;
struct {
__le16 chans[2];
s64 timestamp __aligned(8);
} scan __aligned(IIO_DMA_MINALIGN);
u8 fw_version[3];
__le16 buf;
};
static const struct iio_chan_spec ens160_channels[] = {
{
.type = IIO_CONCENTRATION,
.channel2 = IIO_MOD_VOC,
.modified = 1,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_SCALE),
.address = ENS160_REG_DATA_TVOC,
.scan_index = 0,
.scan_type = {
.sign = 'u',
.realbits = 16,
.storagebits = 16,
.endianness = IIO_LE,
},
},
{
.type = IIO_CONCENTRATION,
.channel2 = IIO_MOD_CO2,
.modified = 1,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_SCALE),
.address = ENS160_REG_DATA_ECO2,
.scan_index = 1,
.scan_type = {
.sign = 'u',
.realbits = 16,
.storagebits = 16,
.endianness = IIO_LE,
},
},
IIO_CHAN_SOFT_TIMESTAMP(2),
};
static int ens160_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int *val, int *val2, long mask)
{
struct ens160_data *data = iio_priv(indio_dev);
int ret;
switch (mask) {
case IIO_CHAN_INFO_RAW:
iio_device_claim_direct_scoped(return -EBUSY, indio_dev) {
guard(mutex)(&data->mutex);
ret = regmap_bulk_read(data->regmap, chan->address,
&data->buf, sizeof(data->buf));
if (ret)
return ret;
*val = le16_to_cpu(data->buf);
return IIO_VAL_INT;
}
unreachable();
case IIO_CHAN_INFO_SCALE:
switch (chan->channel2) {
case IIO_MOD_CO2:
/* The sensor reads CO2 data as ppm */
*val = 0;
*val2 = 100;
return IIO_VAL_INT_PLUS_MICRO;
case IIO_MOD_VOC:
/* The sensor reads VOC data as ppb */
*val = 0;
*val2 = 100;
return IIO_VAL_INT_PLUS_NANO;
default:
return -EINVAL;
}
default:
return -EINVAL;
}
}
static int ens160_set_mode(struct ens160_data *data, u8 mode)
{
int ret;
ret = regmap_write(data->regmap, ENS160_REG_OPMODE, mode);
if (ret)
return ret;
msleep(ENS160_BOOTING_TIME_MS);
return 0;
}
static void ens160_set_idle(void *data)
{
ens160_set_mode(data, ENS160_REG_MODE_IDLE);
}
static int ens160_chip_init(struct ens160_data *data)
{
struct device *dev = regmap_get_device(data->regmap);
unsigned int status;
int ret;
ret = ens160_set_mode(data, ENS160_REG_MODE_RESET);
if (ret)
return ret;
ret = regmap_bulk_read(data->regmap, ENS160_REG_PART_ID, &data->buf,
sizeof(data->buf));
if (ret)
return ret;
if (le16_to_cpu(data->buf) != ENS160_PART_ID)
return -ENODEV;
ret = ens160_set_mode(data, ENS160_REG_MODE_IDLE);
if (ret)
return ret;
ret = regmap_write(data->regmap, ENS160_REG_COMMAND,
ENS160_REG_COMMAND_CLRGPR);
if (ret)
return ret;
ret = regmap_write(data->regmap, ENS160_REG_COMMAND,
ENS160_REG_COMMAND_GET_APPVER);
if (ret)
return ret;
ret = regmap_bulk_read(data->regmap, ENS160_REG_GPR_READ4,
data->fw_version, sizeof(data->fw_version));
if (ret)
return ret;
dev_info(dev, "firmware version: %u.%u.%u\n", data->fw_version[2],
data->fw_version[1], data->fw_version[0]);
ret = ens160_set_mode(data, ENS160_REG_MODE_STANDARD);
if (ret)
return ret;
ret = devm_add_action_or_reset(dev, ens160_set_idle, data);
if (ret)
return ret;
ret = regmap_read(data->regmap, ENS160_REG_DEVICE_STATUS, &status);
if (ret)
return ret;
if (FIELD_GET(ENS160_STATUS_VALIDITY_FLAG, status)
!= ENS160_STATUS_NORMAL)
return -EINVAL;
return 0;
}
static const struct iio_info ens160_info = {
.read_raw = ens160_read_raw,
};
static int ens160_suspend(struct device *dev)
{
struct iio_dev *indio_dev = dev_get_drvdata(dev);
struct ens160_data *data = iio_priv(indio_dev);
return ens160_set_mode(data, ENS160_REG_MODE_DEEP_SLEEP);
}
static int ens160_resume(struct device *dev)
{
struct iio_dev *indio_dev = dev_get_drvdata(dev);
struct ens160_data *data = iio_priv(indio_dev);
int ret;
ret = ens160_set_mode(data, ENS160_REG_MODE_IDLE);
if (ret)
return ret;
return ens160_set_mode(data, ENS160_REG_MODE_STANDARD);
}
EXPORT_NS_SIMPLE_DEV_PM_OPS(ens160_pm_ops, ens160_suspend, ens160_resume,
IIO_ENS160);
static irqreturn_t ens160_trigger_handler(int irq, void *p)
{
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct ens160_data *data = iio_priv(indio_dev);
int ret;
guard(mutex)(&data->mutex);
ret = regmap_bulk_read(data->regmap, ENS160_REG_DATA_TVOC,
data->scan.chans, sizeof(data->scan.chans));
if (ret)
goto err;
iio_push_to_buffers_with_timestamp(indio_dev, &data->scan,
pf->timestamp);
err:
iio_trigger_notify_done(indio_dev->trig);
return IRQ_HANDLED;
}
static int ens160_set_trigger_state(struct iio_trigger *trig, bool state)
{
struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
struct ens160_data *data = iio_priv(indio_dev);
unsigned int int_bits = ENS160_REG_CONFIG_INTEN |
ENS160_REG_CONFIG_INTDAT |
ENS160_REG_CONFIG_INT_CFG;
if (state)
return regmap_set_bits(data->regmap, ENS160_REG_CONFIG,
int_bits);
else
return regmap_clear_bits(data->regmap, ENS160_REG_CONFIG,
int_bits);
}
static const struct iio_trigger_ops ens160_trigger_ops = {
.set_trigger_state = ens160_set_trigger_state,
.validate_device = iio_trigger_validate_own_device,
};
static int ens160_setup_trigger(struct iio_dev *indio_dev, int irq)
{
struct device *dev = indio_dev->dev.parent;
struct iio_trigger *trig;
int ret;
trig = devm_iio_trigger_alloc(dev, "%s-dev%d", indio_dev->name,
iio_device_id(indio_dev));
if (!trig)
return dev_err_probe(dev, -ENOMEM,
"failed to allocate trigger\n");
trig->ops = &ens160_trigger_ops;
iio_trigger_set_drvdata(trig, indio_dev);
ret = devm_iio_trigger_register(dev, trig);
if (ret)
return ret;
indio_dev->trig = iio_trigger_get(trig);
ret = devm_request_threaded_irq(dev, irq,
iio_trigger_generic_data_rdy_poll,
NULL,
IRQF_ONESHOT,
indio_dev->name,
indio_dev->trig);
if (ret)
return dev_err_probe(dev, ret, "failed to request irq\n");
return 0;
}
int devm_ens160_core_probe(struct device *dev, struct regmap *regmap, int irq,
const char *name)
{
struct ens160_data *data;
struct iio_dev *indio_dev;
int ret;
indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
if (!indio_dev)
return -ENOMEM;
data = iio_priv(indio_dev);
data->regmap = regmap;
indio_dev->name = name;
indio_dev->info = &ens160_info;
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->channels = ens160_channels;
indio_dev->num_channels = ARRAY_SIZE(ens160_channels);
if (irq > 0) {
ret = ens160_setup_trigger(indio_dev, irq);
if (ret)
return dev_err_probe(dev, ret,
"failed to setup trigger\n");
}
ret = ens160_chip_init(data);
if (ret)
return dev_err_probe(dev, ret, "chip initialization failed\n");
mutex_init(&data->mutex);
ret = devm_iio_triggered_buffer_setup(dev, indio_dev,
iio_pollfunc_store_time,
ens160_trigger_handler, NULL);
if (ret)
return ret;
return devm_iio_device_register(dev, indio_dev);
}
EXPORT_SYMBOL_NS(devm_ens160_core_probe, IIO_ENS160);
MODULE_AUTHOR("Gustavo Silva <gustavograzs@gmail.com>");
MODULE_DESCRIPTION("ScioSense ENS160 driver");
MODULE_LICENSE("GPL v2");
// SPDX-License-Identifier: GPL-2.0
/*
* ScioSense ENS160 multi-gas sensor I2C driver
*
* Copyright (c) 2024 Gustavo Silva <gustavograzs@gmail.com>
*
* 7-Bit I2C slave address is:
* - 0x52 if ADDR pin LOW
* - 0x53 if ADDR pin HIGH
*/
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/regmap.h>
#include "ens160.h"
static const struct regmap_config ens160_regmap_i2c_conf = {
.reg_bits = 8,
.val_bits = 8,
};
static int ens160_i2c_probe(struct i2c_client *client)
{
struct regmap *regmap;
regmap = devm_regmap_init_i2c(client, &ens160_regmap_i2c_conf);
if (IS_ERR(regmap))
return dev_err_probe(&client->dev, PTR_ERR(regmap),
"Failed to register i2c regmap\n");
return devm_ens160_core_probe(&client->dev, regmap, client->irq,
"ens160");
}
static const struct i2c_device_id ens160_i2c_id[] = {
{ "ens160" },
{ }
};
MODULE_DEVICE_TABLE(i2c, ens160_i2c_id);
static const struct of_device_id ens160_of_i2c_match[] = {
{ .compatible = "sciosense,ens160" },
{ }
};
MODULE_DEVICE_TABLE(of, ens160_of_i2c_match);
static struct i2c_driver ens160_i2c_driver = {
.driver = {
.name = "ens160",
.of_match_table = ens160_of_i2c_match,
.pm = pm_sleep_ptr(&ens160_pm_ops),
},
.probe = ens160_i2c_probe,
.id_table = ens160_i2c_id,
};
module_i2c_driver(ens160_i2c_driver);
MODULE_AUTHOR("Gustavo Silva <gustavograzs@gmail.com>");
MODULE_DESCRIPTION("ScioSense ENS160 I2C driver");
MODULE_LICENSE("GPL v2");
MODULE_IMPORT_NS(IIO_ENS160);
// SPDX-License-Identifier: GPL-2.0
/*
* ScioSense ENS160 multi-gas sensor SPI driver
*
* Copyright (c) 2024 Gustavo Silva <gustavograzs@gmail.com>
*/
#include <linux/module.h>
#include <linux/regmap.h>
#include <linux/spi/spi.h>
#include "ens160.h"
#define ENS160_SPI_READ BIT(0)
static const struct regmap_config ens160_regmap_spi_conf = {
.reg_bits = 8,
.val_bits = 8,
.reg_shift = -1,
.read_flag_mask = ENS160_SPI_READ,
};
static int ens160_spi_probe(struct spi_device *spi)
{
struct regmap *regmap;
regmap = devm_regmap_init_spi(spi, &ens160_regmap_spi_conf);
if (IS_ERR(regmap))
return dev_err_probe(&spi->dev, PTR_ERR(regmap),
"Failed to register spi regmap\n");
return devm_ens160_core_probe(&spi->dev, regmap, spi->irq, "ens160");
}
static const struct of_device_id ens160_spi_of_match[] = {
{ .compatible = "sciosense,ens160" },
{ }
};
MODULE_DEVICE_TABLE(of, ens160_spi_of_match);
static const struct spi_device_id ens160_spi_id[] = {
{ "ens160" },
{ }
};
MODULE_DEVICE_TABLE(spi, ens160_spi_id);
static struct spi_driver ens160_spi_driver = {
.driver = {
.name = "ens160",
.of_match_table = ens160_spi_of_match,
.pm = pm_sleep_ptr(&ens160_pm_ops),
},
.probe = ens160_spi_probe,
.id_table = ens160_spi_id,
};
module_spi_driver(ens160_spi_driver);
MODULE_AUTHOR("Gustavo Silva <gustavograzs@gmail.com>");
MODULE_DESCRIPTION("ScioSense ENS160 SPI driver");
MODULE_LICENSE("GPL v2");
MODULE_IMPORT_NS(IIO_ENS160);
......@@ -149,6 +149,7 @@ config AD9739A
config ADI_AXI_DAC
tristate "Analog Devices Generic AXI DAC IP core driver"
depends on MICROBLAZE || NIOS2 || ARCH_ZYNQ || ARCH_ZYNQMP || ARCH_INTEL_SOCFPGA || COMPILE_TEST
select IIO_BUFFER
select IIO_BUFFER_DMAENGINE
select REGMAP_MMIO
......
......@@ -117,7 +117,7 @@
#define AD3552R_REG_ADDR_CH_INPUT_24B(ch) (0x4B - (1 - ch) * 3)
/* Useful defines */
#define AD3552R_NUM_CH 2
#define AD3552R_MAX_CH 2
#define AD3552R_MASK_CH(ch) BIT(ch)
#define AD3552R_MASK_ALL_CH GENMASK(1, 0)
#define AD3552R_MAX_REG_SIZE 3
......@@ -139,8 +139,10 @@ enum ad3552r_ch_vref_select {
AD3552R_EXTERNAL_VREF_PIN_INPUT
};
enum ad3542r_id {
enum ad3552r_id {
AD3541R_ID = 0x400b,
AD3542R_ID = 0x4009,
AD3551R_ID = 0x400a,
AD3552R_ID = 0x4008,
};
......@@ -261,17 +263,26 @@ struct ad3552r_ch_data {
bool range_override;
};
struct ad3552r_model_data {
const char *model_name;
enum ad3552r_id chip_id;
unsigned int num_hw_channels;
const s32 (*ranges_table)[2];
int num_ranges;
bool requires_output_range;
};
struct ad3552r_desc {
const struct ad3552r_model_data *model_data;
/* Used to look the spi bus for atomic operations where needed */
struct mutex lock;
struct gpio_desc *gpio_reset;
struct gpio_desc *gpio_ldac;
struct spi_device *spi;
struct ad3552r_ch_data ch_data[AD3552R_NUM_CH];
struct iio_chan_spec channels[AD3552R_NUM_CH + 1];
struct ad3552r_ch_data ch_data[AD3552R_MAX_CH];
struct iio_chan_spec channels[AD3552R_MAX_CH + 1];
unsigned long enabled_ch;
unsigned int num_ch;
enum ad3542r_id chip_id;
};
static const u16 addr_mask_map[][2] = {
......@@ -528,7 +539,7 @@ static int32_t ad3552r_trigger_hw_ldac(struct gpio_desc *ldac)
static int ad3552r_write_all_channels(struct ad3552r_desc *dac, u8 *data)
{
int err, len;
u8 addr, buff[AD3552R_NUM_CH * AD3552R_MAX_REG_SIZE + 1];
u8 addr, buff[AD3552R_MAX_CH * AD3552R_MAX_REG_SIZE + 1];
addr = AD3552R_REG_ADDR_CH_INPUT_24B(1);
/* CH1 */
......@@ -586,7 +597,7 @@ static irqreturn_t ad3552r_trigger_handler(int irq, void *p)
struct iio_buffer *buf = indio_dev->buffer;
struct ad3552r_desc *dac = iio_priv(indio_dev);
/* Maximum size of a scan */
u8 buff[AD3552R_NUM_CH * AD3552R_MAX_REG_SIZE];
u8 buff[AD3552R_MAX_CH * AD3552R_MAX_REG_SIZE];
int err;
memset(buff, 0, sizeof(buff));
......@@ -745,13 +756,8 @@ static void ad3552r_calc_gain_and_offset(struct ad3552r_desc *dac, s32 ch)
} else {
/* Normal range */
idx = dac->ch_data[ch].range;
if (dac->chip_id == AD3542R_ID) {
v_min = ad3542r_ch_ranges[idx][0];
v_max = ad3542r_ch_ranges[idx][1];
} else {
v_min = ad3552r_ch_ranges[idx][0];
v_max = ad3552r_ch_ranges[idx][1];
}
v_min = dac->model_data->ranges_table[idx][0];
v_max = dac->model_data->ranges_table[idx][1];
}
/*
......@@ -775,22 +781,14 @@ static void ad3552r_calc_gain_and_offset(struct ad3552r_desc *dac, s32 ch)
dac->ch_data[ch].offset_dec = div_s64(tmp, span);
}
static int ad3552r_find_range(u16 id, s32 *vals)
static int ad3552r_find_range(const struct ad3552r_model_data *model_data,
s32 *vals)
{
int i, len;
const s32 (*ranges)[2];
int i;
if (id == AD3542R_ID) {
len = ARRAY_SIZE(ad3542r_ch_ranges);
ranges = ad3542r_ch_ranges;
} else {
len = ARRAY_SIZE(ad3552r_ch_ranges);
ranges = ad3552r_ch_ranges;
}
for (i = 0; i < len; i++)
if (vals[0] == ranges[i][0] * 1000 &&
vals[1] == ranges[i][1] * 1000)
for (i = 0; i < model_data->num_ranges; i++)
if (vals[0] == model_data->ranges_table[i][0] * 1000 &&
vals[1] == model_data->ranges_table[i][1] * 1000)
return i;
return -EINVAL;
......@@ -940,10 +938,10 @@ static int ad3552r_configure_device(struct ad3552r_desc *dac)
if (err)
return dev_err_probe(dev, err,
"mandatory reg property missing\n");
if (ch >= AD3552R_NUM_CH)
if (ch >= dac->model_data->num_hw_channels)
return dev_err_probe(dev, -EINVAL,
"reg must be less than %d\n",
AD3552R_NUM_CH);
dac->model_data->num_hw_channels);
if (fwnode_property_present(child, "adi,output-range-microvolt")) {
err = fwnode_property_read_u32_array(child,
......@@ -954,7 +952,7 @@ static int ad3552r_configure_device(struct ad3552r_desc *dac)
return dev_err_probe(dev, err,
"adi,output-range-microvolt property could not be parsed\n");
err = ad3552r_find_range(dac->chip_id, vals);
err = ad3552r_find_range(dac->model_data, vals);
if (err < 0)
return dev_err_probe(dev, err,
"Invalid adi,output-range-microvolt value\n");
......@@ -967,9 +965,10 @@ static int ad3552r_configure_device(struct ad3552r_desc *dac)
return err;
dac->ch_data[ch].range = val;
} else if (dac->chip_id == AD3542R_ID) {
} else if (dac->model_data->requires_output_range) {
return dev_err_probe(dev, -EINVAL,
"adi,output-range-microvolt is required for ad3542r\n");
"adi,output-range-microvolt is required for %s\n",
dac->model_data->model_name);
} else {
err = ad3552r_configure_custom_gain(dac, child, ch);
if (err)
......@@ -989,7 +988,8 @@ static int ad3552r_configure_device(struct ad3552r_desc *dac)
}
/* Disable unused channels */
for_each_clear_bit(ch, &dac->enabled_ch, AD3552R_NUM_CH) {
for_each_clear_bit(ch, &dac->enabled_ch,
dac->model_data->num_hw_channels) {
err = ad3552r_set_ch_value(dac, AD3552R_CH_AMPLIFIER_POWERDOWN,
ch, 1);
if (err)
......@@ -1032,7 +1032,7 @@ static int ad3552r_init(struct ad3552r_desc *dac)
}
id |= val << 8;
if (id != dac->chip_id) {
if (id != dac->model_data->chip_id) {
dev_err(&dac->spi->dev, "Product id not matching\n");
return -ENODEV;
}
......@@ -1042,7 +1042,6 @@ static int ad3552r_init(struct ad3552r_desc *dac)
static int ad3552r_probe(struct spi_device *spi)
{
const struct spi_device_id *id = spi_get_device_id(spi);
struct ad3552r_desc *dac;
struct iio_dev *indio_dev;
int err;
......@@ -1053,7 +1052,9 @@ static int ad3552r_probe(struct spi_device *spi)
dac = iio_priv(indio_dev);
dac->spi = spi;
dac->chip_id = id->driver_data;
dac->model_data = spi_get_device_match_data(spi);
if (!dac->model_data)
return -EINVAL;
mutex_init(&dac->lock);
......@@ -1062,10 +1063,7 @@ static int ad3552r_probe(struct spi_device *spi)
return err;
/* Config triggered buffer device */
if (dac->chip_id == AD3552R_ID)
indio_dev->name = "ad3552r";
else
indio_dev->name = "ad3542r";
indio_dev->name = dac->model_data->model_name;
indio_dev->dev.parent = &spi->dev;
indio_dev->info = &ad3552r_iio_info;
indio_dev->num_channels = dac->num_ch;
......@@ -1083,16 +1081,68 @@ static int ad3552r_probe(struct spi_device *spi)
return devm_iio_device_register(&spi->dev, indio_dev);
}
static const struct ad3552r_model_data ad3541r_model_data = {
.model_name = "ad3541r",
.chip_id = AD3541R_ID,
.num_hw_channels = 1,
.ranges_table = ad3542r_ch_ranges,
.num_ranges = ARRAY_SIZE(ad3542r_ch_ranges),
.requires_output_range = true,
};
static const struct ad3552r_model_data ad3542r_model_data = {
.model_name = "ad3542r",
.chip_id = AD3542R_ID,
.num_hw_channels = 2,
.ranges_table = ad3542r_ch_ranges,
.num_ranges = ARRAY_SIZE(ad3542r_ch_ranges),
.requires_output_range = true,
};
static const struct ad3552r_model_data ad3551r_model_data = {
.model_name = "ad3551r",
.chip_id = AD3551R_ID,
.num_hw_channels = 1,
.ranges_table = ad3552r_ch_ranges,
.num_ranges = ARRAY_SIZE(ad3552r_ch_ranges),
.requires_output_range = false,
};
static const struct ad3552r_model_data ad3552r_model_data = {
.model_name = "ad3552r",
.chip_id = AD3552R_ID,
.num_hw_channels = 2,
.ranges_table = ad3552r_ch_ranges,
.num_ranges = ARRAY_SIZE(ad3552r_ch_ranges),
.requires_output_range = false,
};
static const struct spi_device_id ad3552r_id[] = {
{ "ad3542r", AD3542R_ID },
{ "ad3552r", AD3552R_ID },
{
.name = "ad3541r",
.driver_data = (kernel_ulong_t)&ad3541r_model_data
},
{
.name = "ad3542r",
.driver_data = (kernel_ulong_t)&ad3542r_model_data
},
{
.name = "ad3551r",
.driver_data = (kernel_ulong_t)&ad3551r_model_data
},
{
.name = "ad3552r",
.driver_data = (kernel_ulong_t)&ad3552r_model_data
},
{ }
};
MODULE_DEVICE_TABLE(spi, ad3552r_id);
static const struct of_device_id ad3552r_of_match[] = {
{ .compatible = "adi,ad3542r"},
{ .compatible = "adi,ad3552r"},
{ .compatible = "adi,ad3541r", .data = &ad3541r_model_data },
{ .compatible = "adi,ad3542r", .data = &ad3542r_model_data },
{ .compatible = "adi,ad3551r", .data = &ad3551r_model_data },
{ .compatible = "adi,ad3552r", .data = &ad3552r_model_data },
{ }
};
MODULE_DEVICE_TABLE(of, ad3552r_of_match);
......
......@@ -132,7 +132,6 @@ static const struct regmap_config max5522_regmap_config = {
static int max5522_spi_probe(struct spi_device *spi)
{
const struct spi_device_id *id = spi_get_device_id(spi);
struct iio_dev *indio_dev;
struct max5522_state *state;
int ret;
......@@ -144,13 +143,9 @@ static int max5522_spi_probe(struct spi_device *spi)
}
state = iio_priv(indio_dev);
state->chip_info = device_get_match_data(&spi->dev);
if (!state->chip_info) {
state->chip_info =
(struct max5522_chip_info *)(id->driver_data);
if (!state->chip_info)
return -EINVAL;
}
state->chip_info = spi_get_device_match_data(spi);
if (!state->chip_info)
return -EINVAL;
state->vrefin_reg = devm_regulator_get(&spi->dev, "vrefin");
if (IS_ERR(state->vrefin_reg))
......
......@@ -591,7 +591,7 @@ static int mcp4728_probe(struct i2c_client *client)
}
static const struct i2c_device_id mcp4728_id[] = {
{ "mcp4728", 0 },
{ "mcp4728" },
{}
};
MODULE_DEVICE_TABLE(i2c, mcp4728_id);
......
......@@ -9,7 +9,6 @@
#include <linux/bits.h>
#include <linux/clk.h>
#include <linux/clkdev.h>
#include <linux/clk-provider.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/iio/iio.h>
......
......@@ -47,9 +47,9 @@ static const struct acpi_device_id bmg160_acpi_match[] = {
MODULE_DEVICE_TABLE(acpi, bmg160_acpi_match);
static const struct i2c_device_id bmg160_i2c_id[] = {
{"bmg160", 0},
{"bmi055_gyro", 0},
{"bmi088_gyro", 0},
{ "bmg160" },
{ "bmi055_gyro" },
{ "bmi088_gyro" },
{}
};
......
......@@ -39,7 +39,7 @@ static void fxas21002c_i2c_remove(struct i2c_client *i2c)
}
static const struct i2c_device_id fxas21002c_i2c_id[] = {
{ "fxas21002c", 0 },
{ "fxas21002c" },
{ }
};
MODULE_DEVICE_TABLE(i2c, fxas21002c_i2c_id);
......
......@@ -387,7 +387,7 @@ static DEFINE_SIMPLE_DEV_PM_OPS(itg3200_pm_ops, itg3200_suspend,
itg3200_resume);
static const struct i2c_device_id itg3200_id[] = {
{ "itg3200", 0 },
{ "itg3200" },
{ }
};
MODULE_DEVICE_TABLE(i2c, itg3200_id);
......
......@@ -582,7 +582,7 @@ static int afe4404_probe(struct i2c_client *client)
}
static const struct i2c_device_id afe4404_ids[] = {
{ "afe4404", 0 },
{ "afe4404" },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(i2c, afe4404_ids);
......
......@@ -483,7 +483,7 @@ static void max30100_remove(struct i2c_client *client)
}
static const struct i2c_device_id max30100_id[] = {
{ "max30100", 0 },
{ "max30100" },
{}
};
MODULE_DEVICE_TABLE(i2c, max30100_id);
......
......@@ -253,7 +253,7 @@ static int am2315_probe(struct i2c_client *client)
}
static const struct i2c_device_id am2315_i2c_id[] = {
{"am2315", 0},
{ "am2315" },
{}
};
MODULE_DEVICE_TABLE(i2c, am2315_i2c_id);
......
......@@ -396,12 +396,12 @@ static int hdc100x_probe(struct i2c_client *client)
}
static const struct i2c_device_id hdc100x_id[] = {
{ "hdc100x", 0 },
{ "hdc1000", 0 },
{ "hdc1008", 0 },
{ "hdc1010", 0 },
{ "hdc1050", 0 },
{ "hdc1080", 0 },
{ "hdc100x" },
{ "hdc1000" },
{ "hdc1008" },
{ "hdc1010" },
{ "hdc1050" },
{ "hdc1080" },
{ }
};
MODULE_DEVICE_TABLE(i2c, hdc100x_id);
......
......@@ -163,8 +163,8 @@ static int si7005_probe(struct i2c_client *client)
}
static const struct i2c_device_id si7005_id[] = {
{ "si7005", 0 },
{ "th02", 0 },
{ "si7005" },
{ "th02" },
{ }
};
MODULE_DEVICE_TABLE(i2c, si7005_id);
......
......@@ -23,6 +23,7 @@
#include <linux/mod_devicetable.h>
#include <linux/slab.h>
#include <linux/sysfs.h>
#include <linux/stat.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
......@@ -33,17 +34,38 @@
#define SI7020CMD_TEMP_HOLD 0xE3
/* Software Reset */
#define SI7020CMD_RESET 0xFE
#define SI7020CMD_USR_WRITE 0xE6
/* "Heater Enabled" bit in the User Register */
#define SI7020_USR_HEATER_EN BIT(2)
#define SI7020CMD_HEATER_WRITE 0x51
/* Heater current configuration bits */
#define SI7020_HEATER_VAL GENMASK(3, 0)
struct si7020_data {
struct i2c_client *client;
/* Lock for cached register values */
struct mutex lock;
u8 user_reg;
u8 heater_reg;
};
static const int si7020_heater_vals[] = { 0, 1, 0xF };
static int si7020_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan, int *val,
int *val2, long mask)
{
struct i2c_client **client = iio_priv(indio_dev);
struct si7020_data *data = iio_priv(indio_dev);
int ret;
switch (mask) {
case IIO_CHAN_INFO_RAW:
ret = i2c_smbus_read_word_swapped(*client,
if (chan->type == IIO_CURRENT) {
*val = data->heater_reg;
return IIO_VAL_INT;
}
ret = i2c_smbus_read_word_swapped(data->client,
chan->type == IIO_TEMP ?
SI7020CMD_TEMP_HOLD :
SI7020CMD_RH_HOLD);
......@@ -96,17 +118,118 @@ static const struct iio_chan_spec si7020_channels[] = {
.type = IIO_TEMP,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_SCALE) | BIT(IIO_CHAN_INFO_OFFSET),
},
{
.type = IIO_CURRENT,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
.info_mask_separate_available = BIT(IIO_CHAN_INFO_RAW),
.extend_name = "heater",
}
};
static int si7020_update_reg(struct si7020_data *data,
u8 *reg, u8 cmd, u8 mask, u8 val)
{
u8 new = (*reg & ~mask) | val;
int ret;
ret = i2c_smbus_write_byte_data(data->client, cmd, new);
if (ret)
return ret;
*reg = new;
return 0;
}
static int si7020_write_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int val, int val2, long mask)
{
struct si7020_data *data = iio_priv(indio_dev);
int ret;
switch (mask) {
case IIO_CHAN_INFO_RAW:
if (chan->type != IIO_CURRENT || val2 != 0 ||
val < si7020_heater_vals[0] || val > si7020_heater_vals[2])
return -EINVAL;
scoped_guard(mutex, &data->lock)
ret = si7020_update_reg(data, &data->heater_reg,
SI7020CMD_HEATER_WRITE, SI7020_HEATER_VAL, val);
return ret;
default:
return -EINVAL;
}
}
static int si7020_read_available(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
const int **vals,
int *type, int *length, long mask)
{
if (mask != IIO_CHAN_INFO_RAW || chan->type != IIO_CURRENT)
return -EINVAL;
*vals = si7020_heater_vals;
*type = IIO_VAL_INT;
return IIO_AVAIL_RANGE;
}
static ssize_t si7020_show_heater_en(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct si7020_data *data = iio_priv(indio_dev);
return sysfs_emit(buf, "%d\n", !!(data->user_reg & SI7020_USR_HEATER_EN));
}
static ssize_t si7020_store_heater_en(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t len)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct si7020_data *data = iio_priv(indio_dev);
int ret;
bool val;
ret = kstrtobool(buf, &val);
if (ret)
return ret;
scoped_guard(mutex, &data->lock)
ret = si7020_update_reg(data, &data->user_reg, SI7020CMD_USR_WRITE,
SI7020_USR_HEATER_EN, val ? SI7020_USR_HEATER_EN : 0);
return ret < 0 ? ret : len;
}
static IIO_DEVICE_ATTR(heater_enable, 0644,
si7020_show_heater_en, si7020_store_heater_en, 0);
static struct attribute *si7020_attributes[] = {
&iio_dev_attr_heater_enable.dev_attr.attr,
NULL
};
static const struct attribute_group si7020_attribute_group = {
.attrs = si7020_attributes,
};
static const struct iio_info si7020_info = {
.read_raw = si7020_read_raw,
.write_raw = si7020_write_raw,
.read_avail = si7020_read_available,
.attrs = &si7020_attribute_group,
};
static int si7020_probe(struct i2c_client *client)
{
struct iio_dev *indio_dev;
struct i2c_client **data;
struct si7020_data *data;
int ret;
if (!i2c_check_functionality(client->adapter,
......@@ -126,7 +249,9 @@ static int si7020_probe(struct i2c_client *client)
return -ENOMEM;
data = iio_priv(indio_dev);
*data = client;
i2c_set_clientdata(client, indio_dev);
data->client = client;
mutex_init(&data->lock);
indio_dev->name = dev_name(&client->dev);
indio_dev->modes = INDIO_DIRECT_MODE;
......@@ -134,12 +259,16 @@ static int si7020_probe(struct i2c_client *client)
indio_dev->channels = si7020_channels;
indio_dev->num_channels = ARRAY_SIZE(si7020_channels);
/* All the "reserved" bits in the User Register are 1s by default */
data->user_reg = 0x3A;
data->heater_reg = 0x0;
return devm_iio_device_register(&client->dev, indio_dev);
}
static const struct i2c_device_id si7020_id[] = {
{ "si7020", 0 },
{ "th06", 0 },
{ "si7020" },
{ "th06" },
{ }
};
MODULE_DEVICE_TABLE(i2c, si7020_id);
......
......@@ -36,8 +36,8 @@ config ADIS16475
select IIO_ADIS_LIB_BUFFER if IIO_BUFFER
help
Say yes here to build support for Analog Devices ADIS16470, ADIS16475,
ADIS16477, ADIS16465, ADIS16467, ADIS16500, ADIS16505, ADIS16507 inertial
sensors.
ADIS16477, ADIS16465, ADIS16467, ADIS16500, ADIS16501, ADIS16505,
ADIS16507 inertial sensors.
To compile this driver as a module, choose M here: the module will be
called adis16475.
......
This diff is collapsed.
This diff is collapsed.
......@@ -175,31 +175,36 @@ static void adis_buffer_cleanup(void *arg)
}
/**
* devm_adis_setup_buffer_and_trigger() - Sets up buffer and trigger for
* the managed adis device
* devm_adis_setup_buffer_and_trigger_with_attrs() - Sets up buffer and trigger
* for the managed adis device with buffer attributes.
* @adis: The adis device
* @indio_dev: The IIO device
* @trigger_handler: Optional trigger handler, may be NULL.
* @trigger_handler: Trigger handler: should handle the buffer readings.
* @ops: Optional buffer setup functions, may be NULL.
* @buffer_attrs: Extra buffer attributes.
*
* Returns 0 on success, a negative error code otherwise.
*
* This function sets up the buffer and trigger for a adis devices. If
* 'trigger_handler' is NULL the default trigger handler will be used. The
* default trigger handler will simply read the registers assigned to the
* currently active channels.
* This function sets up the buffer (with buffer setup functions and extra
* buffer attributes) and trigger for a adis devices with buffer attributes.
*/
int
devm_adis_setup_buffer_and_trigger(struct adis *adis, struct iio_dev *indio_dev,
irq_handler_t trigger_handler)
devm_adis_setup_buffer_and_trigger_with_attrs(struct adis *adis, struct iio_dev *indio_dev,
irq_handler_t trigger_handler,
const struct iio_buffer_setup_ops *ops,
const struct iio_dev_attr **buffer_attrs)
{
int ret;
if (!trigger_handler)
trigger_handler = adis_trigger_handler;
ret = devm_iio_triggered_buffer_setup(&adis->spi->dev, indio_dev,
&iio_pollfunc_store_time,
trigger_handler, NULL);
ret = devm_iio_triggered_buffer_setup_ext(&adis->spi->dev, indio_dev,
&iio_pollfunc_store_time,
trigger_handler,
IIO_BUFFER_DIRECTION_IN,
ops,
buffer_attrs);
if (ret)
return ret;
......@@ -212,5 +217,4 @@ devm_adis_setup_buffer_and_trigger(struct adis *adis, struct iio_dev *indio_dev,
return devm_add_action_or_reset(&adis->spi->dev, adis_buffer_cleanup,
adis);
}
EXPORT_SYMBOL_NS_GPL(devm_adis_setup_buffer_and_trigger, IIO_ADISLIB);
EXPORT_SYMBOL_NS_GPL(devm_adis_setup_buffer_and_trigger_with_attrs, IIO_ADISLIB);
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -34,18 +34,21 @@ static int bmi160_spi_probe(struct spi_device *spi)
}
static const struct spi_device_id bmi160_spi_id[] = {
{"bmi120", 0},
{"bmi160", 0},
{}
};
MODULE_DEVICE_TABLE(spi, bmi160_spi_id);
static const struct acpi_device_id bmi160_acpi_match[] = {
{"BMI0120", 0},
{"BMI0160", 0},
{ },
};
MODULE_DEVICE_TABLE(acpi, bmi160_acpi_match);
static const struct of_device_id bmi160_of_match[] = {
{ .compatible = "bosch,bmi120" },
{ .compatible = "bosch,bmi160" },
{ },
};
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment