Commit 80ef846e authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'staging-5.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging

Pull staging/IIO driver updates from Greg KH:
 "Here is the large set of staging and IIO driver changes for 5.8-rc1

  Nothing major, but a lot of new IIO drivers are included in here,
  along with other core iio cleanups and changes.

  On the staging driver front, again, nothing noticable. No new
  deletions or additions, just a ton of tiny cleanups all over the tree
  done by a lot of different people. Most coding style, but many actual
  real fixes and cleanups that are nice to see.

  All of these have been in linux-next for a while with no reported
  issues"

* tag 'staging-5.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging: (618 commits)
  staging: rtl8723bs: Use common packet header constants
  staging: sm750fb: Add names to proc_setBLANK args
  staging: most: usb: init return value in default path of switch/case expression
  staging: vchiq: Get rid of VCHIQ_SERVICE_OPENEND callback reason
  staging: vchiq: move vchiq_release_message() into vchiq
  staging: vchi: Get rid of C++ guards
  staging: vchi: Get rid of not implemented function declarations
  staging: vchi: Get rid of vchiq_status_to_vchi()
  staging: vchi: Get rid of vchi_service_set_option()
  staging: vchi: Merge vchi_msg_queue() into vchi_queue_kernel_message()
  staging: vchiq: Move copy callback handling into vchiq
  staging: vchi: Get rid of vchi_queue_user_message()
  staging: vchi: Get rid of vchi_service_destroy()
  staging: most: usb: use function sysfs_streq
  staging: most: usb: add missing put_device calls
  staging: most: usb: use correct error codes
  staging: most: usb: replace code to calculate array index
  staging: most: usb: don't use error path to exit function on success
  staging: most: usb: move allocation of URB out of critical section
  staging: most: usb: return 0 instead of variable
  ...
parents 081096d9 77f55d13
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.
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.
This diff is collapsed.
* Bosch BMA180 / BMA25x triaxial acceleration sensor
* Bosch BMA023 / BMA150/ BMA180 / BMA25x / SMB380 triaxial acceleration sensor
https://media.digikey.com/pdf/Data%20Sheets/Bosch/BMA150.pdf
http://omapworld.com/BMA180_111_1002839.pdf
http://ae-bst.resource.bosch.com/media/products/dokumente/bma250/bst-bma250-ds002-05.pdf
Required properties:
- compatible : should be one of:
"bosch,bma023"
"bosch,bma150"
"bosch,bma180"
"bosch,bma250"
"bosch,bma254"
"bosch,smb380"
- reg : the I2C address of the sensor
- vdd-supply : regulator phandle connected to the VDD pin
- vddio-supply : regulator phandle connected to the VDDIO pin
Optional properties:
......
# 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";
};
};
...
# 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>;
};
...
# 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>;
};
};
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>;
};
# 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>;
};
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/chemical/ams,ccs811.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: AMS CCS811 VOC Sensor
maintainers:
- Narcisa Vasile <narcisaanamaria12@gmail.com>
description: |
Ultra-Low Power Digital Gas Sensor for Monitoring Indoor Air Quality.
properties:
compatible:
enum:
- ams,ccs811
reg:
maxItems: 1
reset-gpios:
description: GPIO connected to the nRESET line. This is an active low
input to CCS811.
maxItems: 1
wakeup-gpios:
description: GPIO connected to the nWAKE line. This is an active low
input to CCS811.
maxItems: 1
required:
- compatible
- reg
additionalProperties: false
examples:
- |
#include <dt-bindings/gpio/gpio.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
voc@5b {
compatible = "ams,ccs811";
reg = <0x5b>;
reset-gpios = <&gpioa 11 GPIO_ACTIVE_LOW>;
wakeup-gpios = <&gpioa 12 GPIO_ACTIVE_LOW>;
};
};
...
......@@ -4,19 +4,21 @@
$id: http://devicetree.org/schemas/iio/chemical/atlas,sensor.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Atlas Scientific OEM sensors
title: Atlas Scientific OEM + EZO sensors
maintainers:
- Matt Ranostay <matt.ranostay@konsulko.com>
description: |
Atlas Scientific OEM sensors connected via I2C
Atlas Scientific OEM + EZO sensors connected via I2C
Datasheets:
http://www.atlas-scientific.com/_files/_datasheets/_oem/DO_oem_datasheet.pdf
http://www.atlas-scientific.com/_files/_datasheets/_oem/EC_oem_datasheet.pdf
http://www.atlas-scientific.com/_files/_datasheets/_oem/ORP_oem_datasheet.pdf
http://www.atlas-scientific.com/_files/_datasheets/_oem/pH_oem_datasheet.pdf
http://www.atlas-scientific.com/_files/_datasheets/_oem/RTD_oem_datasheet.pdf
http://www.atlas-scientific.com/_files/_datasheets/_probe/EZO_CO2_Datasheet.pdf
properties:
compatible:
......@@ -25,6 +27,8 @@ properties:
- atlas,ec-sm
- atlas,orp-sm
- atlas,ph-sm
- atlas,rtd-sm
- atlas,co2-ezo
reg:
maxItems: 1
......
# 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).
...
Linear Technology LTC2632/2636 DAC
Linear Technology LTC2632/2634/2636 DAC
Required properties:
- compatible: Has to contain one of the following:
......@@ -8,6 +8,12 @@ Required properties:
lltc,ltc2632-h12
lltc,ltc2632-h10
lltc,ltc2632-h8
lltc,ltc2634-l12
lltc,ltc2634-l10
lltc,ltc2634-l8
lltc,ltc2634-h12
lltc,ltc2634-h10
lltc,ltc2634-h8
lltc,ltc2636-l12
lltc,ltc2636-l10
lltc,ltc2636-l8
......
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>;
};
};
# 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>;
};
};
...
......@@ -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:
......
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/imu/adi,adis16475.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Analog Devices ADIS16475 and similar IMUs
maintainers:
- Nuno Sá <nuno.sa@analog.com>
description: |
Analog Devices ADIS16475 and similar IMUs
https://www.analog.com/media/en/technical-documentation/data-sheets/ADIS16475.pdf
properties:
compatible:
enum:
- adi,adis16475-1
- adi,adis16475-2
- adi,adis16475-3
- adi,adis16477-1
- adi,adis16477-2
- adi,adis16477-3
- adi,adis16470
- adi,adis16465-1
- adi,adis16465-2
- adi,adis16465-3
- adi,adis16467-1
- adi,adis16467-2
- adi,adis16467-3
- adi,adis16500
- adi,adis16505-1
- adi,adis16505-2
- adi,adis16505-3
- adi,adis16507-1
- adi,adis16507-2
- adi,adis16507-3
reg:
maxItems: 1
spi-cpha: true
spi-cpol: true
spi-max-frequency:
maximum: 2000000
interrupts:
maxItems: 1
clocks:
maxItems: 1
reset-gpios:
description:
Must be the device tree identifier of the RESET pin. If specified,
it will be asserted during driver probe. As the line is active low,
it should be marked GPIO_ACTIVE_LOW.
maxItems: 1
adi,sync-mode:
description:
Configures the device SYNC pin. The following modes are supported
0 - output_sync
1 - direct_sync
2 - scaled_sync
3 - pulse_sync
allOf:
- $ref: /schemas/types.yaml#/definitions/uint32
minimum: 0
maximum: 3
adi,scaled-output-hz:
description:
This property must be present if the clock mode is scaled-sync through
clock-names property. In this mode, the input clock can have a range
of 1Hz to 128HZ which must be scaled to originate an allowable sample
rate. This property specifies that rate.
minimum: 1900
maximum: 2100
required:
- compatible
- reg
- interrupts
- spi-cpha
- spi-cpol
allOf:
- if:
properties:
compatible:
contains:
enum:
- adi,adis16500
- adi,adis16505-1
- adi,adis16505-2
- adi,adis16505-3
- adi,adis16507-1
- adi,adis16507-2
- adi,adis16507-3
then:
properties:
adi,sync-mode:
minimum: 0
maximum: 2
- if:
properties:
adi,sync-mode:
enum: [1, 2, 3]
then:
dependencies:
adi,sync-mode: [ clocks ]
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
spi {
#address-cells = <1>;
#size-cells = <0>;
adis16475: adis16475-3@0 {
compatible = "adi,adis16475-3";
reg = <0>;
spi-cpha;
spi-cpol;
spi-max-frequency = <2000000>;
interrupts = <4 IRQ_TYPE_EDGE_RISING>;
interrupt-parent = <&gpio>;
};
};
...
# 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>;
};
};
...
* 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>;
};
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>;
};
# 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>;
};
};
...
......@@ -2,7 +2,9 @@
Required properties:
- compatible : should be "asahi-kasei,ak8974"
- compatible:
* "asahi-kasei,ak8974"
* "alps,hscdtd008a"
- reg : the I2C address of the magnetometer
Optional properties:
......
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/proximity/vishay,vcnl3020.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Integrated Proximity Sensor With Infrared Emitter
maintainers:
- Ivan Mikhaylov <i.mikhaylov@yadro.com>
description: |
The VCNL3020 is a fully integrated proximity sensor. Fully integrated means
that the infrared emitter is included in the package. It has 16-bit
resolution. It includes a signal processing IC and features standard I2C
communication interface. It features an interrupt function.
Specifications about the devices can be found at:
https://www.vishay.com/docs/84150/vcnl3020.pdf
properties:
compatible:
enum:
- vishay,vcnl3020
reg:
maxItems: 1
interrupts:
maxItems: 1
vdd-supply:
description: Regulator that provides power to the sensor
vddio-supply:
description: Regulator that provides power to the bus
vishay,led-current-microamp:
description:
The driver current for the LED used in proximity sensing.
enum: [0, 10000, 20000, 30000, 40000, 50000, 60000, 70000, 80000, 90000,
100000, 110000, 120000, 130000, 140000, 150000, 160000, 170000,
180000, 190000, 200000]
default: 20000
required:
- compatible
- reg
examples:
- |
i2c {
#address-cells = <1>;
#size-cells = <0>;
proximity@13 {
compatible = "vishay,vcnl3020";
reg = <0x13>;
vishay,led-current-microamp = <200000>;
};
};
......@@ -50,6 +50,7 @@ Accelerometers:
- st,lis3dhh
- st,lis3de
- st,lis2de12
- st,lis2hh12
Gyroscopes:
- st,l3g4200d-gyro
......
......@@ -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()
......
......@@ -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
......
......@@ -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
......@@ -1042,6 +1043,14 @@ W: http://ez.analog.com/community/linux-device-drivers
F: Documentation/devicetree/bindings/iio/imu/adi,adis16460.yaml
F: drivers/iio/imu/adis16460.c
ANALOG DEVICES INC ADIS16475 DRIVER
M: Nuno Sa <nuno.sa@analog.com>
L: linux-iio@vger.kernel.org
W: http://ez.analog.com/community/linux-device-drivers
S: Supported
F: drivers/iio/imu/adis16475.c
F: Documentation/devicetree/bindings/iio/imu/adi,adis16475.yaml
ANALOG DEVICES INC ADM1177 DRIVER
M: Beniamin Bia <beniamin.bia@analog.com>
M: Michael Hennerich <Michael.Hennerich@analog.com>
......@@ -7094,6 +7103,7 @@ GASKET DRIVER FRAMEWORK
M: Rob Springer <rspringer@google.com>
M: Todd Poynor <toddpoynor@google.com>
M: Ben Chan <benchan@chromium.org>
M: Richard Yeh <rcy@google.com>
S: Maintained
F: drivers/staging/gasket/
......
......@@ -89,13 +89,13 @@ config ADXL372_I2C
module will be called adxl372_i2c.
config BMA180
tristate "Bosch BMA180/BMA25x 3-Axis Accelerometer Driver"
depends on I2C
tristate "Bosch BMA023/BMA1x0/BMA25x 3-Axis Accelerometer Driver"
depends on I2C && INPUT_BMA150=n
select IIO_BUFFER
select IIO_TRIGGERED_BUFFER
help
Say Y here if you want to build a driver for the Bosch BMA180 or
BMA25x triaxial acceleration sensor.
Say Y here if you want to build a driver for the Bosch BMA023, BMA150
BMA180, SMB380, or BMA25x triaxial acceleration sensor.
To compile this driver as a module, choose M here: the
module will be called bma180.
......@@ -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:
......
This diff is collapsed.
......@@ -6,6 +6,7 @@
*/
#include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/i2c.h>
#include <linux/iio/iio.h>
......@@ -226,7 +227,7 @@ static struct i2c_driver dmard06_driver = {
.id_table = dmard06_id,
.driver = {
.name = DMARD06_DRV_NAME,
.of_match_table = of_match_ptr(dmard06_of_match),
.of_match_table = dmard06_of_match,
.pm = DMARD06_PM_OPS,
},
};
......
......@@ -14,8 +14,6 @@
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/iio/buffer.h>
#include <linux/iio/trigger_consumer.h>
#include <linux/iio/triggered_buffer.h>
#include "../common/hid-sensors/hid-sensor-trigger.h"
enum accel_3d_channel {
......@@ -391,18 +389,13 @@ static int hid_accel_3d_probe(struct platform_device *pdev)
indio_dev->name = name;
indio_dev->modes = INDIO_DIRECT_MODE;
ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
NULL, NULL);
if (ret) {
dev_err(&pdev->dev, "failed to initialize trigger buffer\n");
goto error_free_dev_mem;
}
atomic_set(&accel_state->common_attributes.data_ready, 0);
ret = hid_sensor_setup_trigger(indio_dev, name,
&accel_state->common_attributes);
if (ret < 0) {
dev_err(&pdev->dev, "trigger setup failed\n");
goto error_unreg_buffer_funcs;
goto error_free_dev_mem;
}
ret = iio_device_register(indio_dev);
......@@ -426,9 +419,7 @@ static int hid_accel_3d_probe(struct platform_device *pdev)
error_iio_unreg:
iio_device_unregister(indio_dev);
error_remove_trigger:
hid_sensor_remove_trigger(&accel_state->common_attributes);
error_unreg_buffer_funcs:
iio_triggered_buffer_cleanup(indio_dev);
hid_sensor_remove_trigger(indio_dev, &accel_state->common_attributes);
error_free_dev_mem:
kfree(indio_dev->channels);
return ret;
......@@ -443,8 +434,7 @@ static int hid_accel_3d_remove(struct platform_device *pdev)
sensor_hub_remove_callback(hsdev, hsdev->usage);
iio_device_unregister(indio_dev);
hid_sensor_remove_trigger(&accel_state->common_attributes);
iio_triggered_buffer_cleanup(indio_dev);
hid_sensor_remove_trigger(indio_dev, &accel_state->common_attributes);
kfree(indio_dev->channels);
return 0;
......
......@@ -2,6 +2,7 @@
#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/delay.h>
......@@ -21,8 +22,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);
}
......@@ -36,15 +37,11 @@ static int kxsd9_i2c_remove(struct i2c_client *client)
return kxsd9_common_remove(&client->dev);
}
#ifdef CONFIG_OF
static const struct of_device_id kxsd9_of_match[] = {
{ .compatible = "kionix,kxsd9", },
{ },
};
MODULE_DEVICE_TABLE(of, kxsd9_of_match);
#else
#define kxsd9_of_match NULL
#endif
static const struct i2c_device_id kxsd9_i2c_id[] = {
{"kxsd9", 0},
......@@ -55,7 +52,7 @@ MODULE_DEVICE_TABLE(i2c, kxsd9_i2c_id);
static struct i2c_driver kxsd9_i2c_driver = {
.driver = {
.name = "kxsd9",
.of_match_table = of_match_ptr(kxsd9_of_match),
.of_match_table = kxsd9_of_match,
.pm = &kxsd9_dev_pm_ops,
},
.probe = kxsd9_i2c_probe,
......
......@@ -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;
......
......@@ -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
......
......@@ -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;
......
......@@ -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)
......
......@@ -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);
......
......@@ -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
......
......@@ -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
......
......@@ -12,9 +12,11 @@
#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)
indio_dev->channels = st->chip_info->convst_channel;
/* Setup default message */
st->xfer.rx_buf = &st->data;
......@@ -295,19 +340,8 @@ static int ad7476_probe(struct spi_device *spi)
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);
......
......@@ -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] = {
......
......@@ -64,25 +64,73 @@
#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");
......@@ -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), \
}
......
This diff is collapsed.
......@@ -70,9 +70,7 @@ int ad_sd_write_reg(struct ad_sigma_delta *sigma_delta, unsigned int reg,
switch (size) {
case 3:
data[1] = val >> 16;
data[2] = val >> 8;
data[3] = val;
put_unaligned_be24(val, &data[1]);
break;
case 2:
put_unaligned_be16(val, &data[1]);
......@@ -157,9 +155,7 @@ int ad_sd_read_reg(struct ad_sigma_delta *sigma_delta,
*val = get_unaligned_be32(sigma_delta->data);
break;
case 3:
*val = (sigma_delta->data[0] << 16) |
(sigma_delta->data[1] << 8) |
sigma_delta->data[2];
*val = get_unaligned_be24(&sigma_delta->data[0]);
break;
case 2:
*val = get_unaligned_be16(sigma_delta->data);
......
This diff is collapsed.
This diff is collapsed.
......@@ -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);
......
......@@ -449,9 +449,6 @@ static void exynos_adc_exynos7_init_hw(struct exynos_adc *info)
{
u32 con1, con2;
if (info->data->needs_adc_phy)
regmap_write(info->pmu_map, info->data->phy_offset, 1);
con1 = ADC_V2_CON1_SOFT_RESET;
writel(con1, ADC_V2_CON1(info->regs));
......@@ -531,8 +528,19 @@ static int exynos_read_raw(struct iio_dev *indio_dev,
unsigned long timeout;
int ret;
if (mask != IIO_CHAN_INFO_RAW)
if (mask == IIO_CHAN_INFO_SCALE) {
ret = regulator_get_voltage(info->vdd);
if (ret < 0)
return ret;
/* Regulator voltage is in uV, but need mV */
*val = ret / 1000;
*val2 = info->data->mask;
return IIO_VAL_FRACTIONAL;
} else if (mask != IIO_CHAN_INFO_RAW) {
return -EINVAL;
}
mutex_lock(&indio_dev->mlock);
reinit_completion(&info->completion);
......@@ -683,6 +691,7 @@ static const struct iio_info exynos_adc_iio_info = {
.channel = _index, \
.address = _index, \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SCALE), \
.datasheet_name = _id, \
}
......
......@@ -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);
......
......@@ -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:
......
// 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");
......@@ -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);
......
......@@ -19,6 +19,7 @@
#include <linux/delay.h>
#include <linux/sysfs.h>
#include <linux/of.h>
#include <asm/unaligned.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
......@@ -117,11 +118,11 @@ static int mcp3422_read(struct mcp3422 *adc, int *value, u8 *config)
if (sample_rate == MCP3422_SRATE_3) {
ret = i2c_master_recv(adc->i2c, buf, 4);
temp = buf[0] << 16 | buf[1] << 8 | buf[2];
temp = get_unaligned_be24(&buf[0]);
*config = buf[3];
} else {
ret = i2c_master_recv(adc->i2c, buf, 3);
temp = buf[0] << 8 | buf[1];
temp = get_unaligned_be16(&buf[0]);
*config = buf[2];
}
......
......@@ -65,12 +65,14 @@ struct stm32_adc_priv;
* @clk_sel: clock selection routine
* @max_clk_rate_hz: maximum analog clock rate (Hz, from datasheet)
* @has_syscfg: SYSCFG capability flags
* @num_irqs: number of interrupt lines
*/
struct stm32_adc_priv_cfg {
const struct stm32_adc_common_regs *regs;
int (*clk_sel)(struct platform_device *, struct stm32_adc_priv *);
u32 max_clk_rate_hz;
unsigned int has_syscfg;
unsigned int num_irqs;
};
/**
......@@ -375,21 +377,15 @@ static int stm32_adc_irq_probe(struct platform_device *pdev,
struct device_node *np = pdev->dev.of_node;
unsigned int i;
for (i = 0; i < STM32_ADC_MAX_ADCS; i++) {
/*
* Interrupt(s) must be provided, depending on the compatible:
* - stm32f4/h7 shares a common interrupt line.
* - stm32mp1, has one line per ADC
*/
for (i = 0; i < priv->cfg->num_irqs; i++) {
priv->irq[i] = platform_get_irq(pdev, i);
if (priv->irq[i] < 0) {
/*
* At least one interrupt must be provided, make others
* optional:
* - stm32f4/h7 shares a common interrupt.
* - stm32mp1, has one line per ADC (either for ADC1,
* ADC2 or both).
*/
if (i && priv->irq[i] == -ENXIO)
continue;
if (priv->irq[i] < 0)
return priv->irq[i];
}
}
priv->domain = irq_domain_add_simple(np, STM32_ADC_MAX_ADCS, 0,
......@@ -400,9 +396,7 @@ static int stm32_adc_irq_probe(struct platform_device *pdev,
return -ENOMEM;
}
for (i = 0; i < STM32_ADC_MAX_ADCS; i++) {
if (priv->irq[i] < 0)
continue;
for (i = 0; i < priv->cfg->num_irqs; i++) {
irq_set_chained_handler(priv->irq[i], stm32_adc_irq_handler);
irq_set_handler_data(priv->irq[i], priv);
}
......@@ -420,11 +414,8 @@ static void stm32_adc_irq_remove(struct platform_device *pdev,
irq_dispose_mapping(irq_find_mapping(priv->domain, hwirq));
irq_domain_remove(priv->domain);
for (i = 0; i < STM32_ADC_MAX_ADCS; i++) {
if (priv->irq[i] < 0)
continue;
for (i = 0; i < priv->cfg->num_irqs; i++)
irq_set_chained_handler(priv->irq[i], NULL);
}
}
static int stm32_adc_core_switches_supply_en(struct stm32_adc_priv *priv,
......@@ -817,6 +808,7 @@ static const struct stm32_adc_priv_cfg stm32f4_adc_priv_cfg = {
.regs = &stm32f4_adc_common_regs,
.clk_sel = stm32f4_adc_clk_sel,
.max_clk_rate_hz = 36000000,
.num_irqs = 1,
};
static const struct stm32_adc_priv_cfg stm32h7_adc_priv_cfg = {
......@@ -824,6 +816,7 @@ static const struct stm32_adc_priv_cfg stm32h7_adc_priv_cfg = {
.clk_sel = stm32h7_adc_clk_sel,
.max_clk_rate_hz = 36000000,
.has_syscfg = HAS_VBOOSTER,
.num_irqs = 1,
};
static const struct stm32_adc_priv_cfg stm32mp1_adc_priv_cfg = {
......@@ -831,6 +824,7 @@ static const struct stm32_adc_priv_cfg stm32mp1_adc_priv_cfg = {
.clk_sel = stm32h7_adc_clk_sel,
.max_clk_rate_hz = 40000000,
.has_syscfg = HAS_VBOOSTER | HAS_ANASWVDD,
.num_irqs = 2,
};
static const struct of_device_id stm32_adc_of_match[] = {
......
......@@ -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);
......
......@@ -22,6 +22,8 @@
#include <linux/iio/triggered_buffer.h>
#include <linux/iio/sysfs.h>
#include <asm/unaligned.h>
/* Commands */
#define ADS124S08_CMD_NOP 0x00
#define ADS124S08_CMD_WAKEUP 0x02
......@@ -188,7 +190,6 @@ static int ads124s_read(struct iio_dev *indio_dev, unsigned int chan)
{
struct ads124s_private *priv = iio_priv(indio_dev);
int ret;
u32 tmp;
struct spi_transfer t[] = {
{
.tx_buf = &priv->data[0],
......@@ -208,9 +209,7 @@ static int ads124s_read(struct iio_dev *indio_dev, unsigned int chan)
if (ret < 0)
return ret;
tmp = priv->data[2] << 16 | priv->data[3] << 8 | priv->data[4];
return tmp;
return get_unaligned_be24(&priv->data[2]);
}
static int ads124s_read_raw(struct iio_dev *indio_dev,
......
......@@ -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
......@@ -663,7 +663,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;
......
......@@ -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>
......
......@@ -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__
......
......@@ -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>
......
......@@ -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");
......@@ -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.
......
......@@ -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");
......@@ -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");
......@@ -22,6 +22,17 @@ config ATLAS_PH_SENSOR
To compile this driver as module, choose M here: the
module will be called atlas-ph-sensor.
config ATLAS_EZO_SENSOR
tristate "Atlas Scientific EZO sensors"
depends on I2C
help
Say Y here to build I2C interface support for the following
Atlas Scientific EZO sensors
* CO2 EZO Sensor
To compile this driver as module, choose M here: the
module will be called atlas-ezo-sensor.
config BME680
tristate "Bosch Sensortec BME680 sensor driver"
depends on (I2C || SPI)
......
......@@ -5,6 +5,7 @@
# When adding new entries keep the list in alphabetical order
obj-$(CONFIG_ATLAS_PH_SENSOR) += atlas-sensor.o
obj-$(CONFIG_ATLAS_EZO_SENSOR) += atlas-ezo-sensor.o
obj-$(CONFIG_BME680) += bme680_core.o
obj-$(CONFIG_BME680_I2C) += bme680_i2c.o
obj-$(CONFIG_BME680_SPI) += bme680_spi.o
......
// SPDX-License-Identifier: GPL-2.0+
/*
* atlas-ezo-sensor.c - Support for Atlas Scientific EZO sensors
*
* Copyright (C) 2020 Konsulko Group
* Author: Matt Ranostay <matt.ranostay@konsulko.com>
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/mutex.h>
#include <linux/err.h>
#include <linux/i2c.h>
#include <linux/of_device.h>
#include <linux/iio/iio.h>
#define ATLAS_EZO_DRV_NAME "atlas-ezo-sensor"
#define ATLAS_CO2_INT_TIME_IN_MS 950
enum {
ATLAS_CO2_EZO,
};
struct atlas_ezo_device {
const struct iio_chan_spec *channels;
int num_channels;
int delay;
};
struct atlas_ezo_data {
struct i2c_client *client;
struct atlas_ezo_device *chip;
/* lock to avoid multiple concurrent read calls */
struct mutex lock;
u8 buffer[8];
};
static const struct iio_chan_spec atlas_co2_ezo_channels[] = {
{
.type = IIO_CONCENTRATION,
.modified = 1,
.channel2 = IIO_MOD_CO2,
.info_mask_separate =
BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
.scan_index = 0,
.scan_type = {
.sign = 'u',
.realbits = 32,
.storagebits = 32,
.endianness = IIO_CPU,
},
},
};
static struct atlas_ezo_device atlas_ezo_devices[] = {
[ATLAS_CO2_EZO] = {
.channels = atlas_co2_ezo_channels,
.num_channels = 1,
.delay = ATLAS_CO2_INT_TIME_IN_MS,
},
};
static int atlas_ezo_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int *val, int *val2, long mask)
{
struct atlas_ezo_data *data = iio_priv(indio_dev);
struct i2c_client *client = data->client;
int ret = 0;
if (chan->type != IIO_CONCENTRATION)
return -EINVAL;
switch (mask) {
case IIO_CHAN_INFO_RAW: {
long tmp;
mutex_lock(&data->lock);
tmp = i2c_smbus_write_byte(client, 'R');
if (tmp < 0) {
mutex_unlock(&data->lock);
return tmp;
}
msleep(data->chip->delay);
tmp = i2c_master_recv(client, data->buffer, sizeof(data->buffer));
if (tmp < 0 || data->buffer[0] != 1) {
mutex_unlock(&data->lock);
return -EBUSY;
}
ret = kstrtol(data->buffer + 1, 10, &tmp);
*val = tmp;
mutex_unlock(&data->lock);
return ret ? ret : IIO_VAL_INT;
}
case IIO_CHAN_INFO_SCALE:
*val = 0;
*val2 = 100; /* 0.0001 */
return IIO_VAL_INT_PLUS_MICRO;
}
return ret;
}
static const struct iio_info atlas_info = {
.read_raw = atlas_ezo_read_raw,
};
static const struct i2c_device_id atlas_ezo_id[] = {
{ "atlas-co2-ezo", ATLAS_CO2_EZO },
{}
};
MODULE_DEVICE_TABLE(i2c, atlas_ezo_id);
static const struct of_device_id atlas_ezo_dt_ids[] = {
{ .compatible = "atlas,co2-ezo", .data = (void *)ATLAS_CO2_EZO, },
{}
};
MODULE_DEVICE_TABLE(of, atlas_ezo_dt_ids);
static int atlas_ezo_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct atlas_ezo_data *data;
struct atlas_ezo_device *chip;
const struct of_device_id *of_id;
struct iio_dev *indio_dev;
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
if (!indio_dev)
return -ENOMEM;
of_id = of_match_device(atlas_ezo_dt_ids, &client->dev);
if (!of_id)
chip = &atlas_ezo_devices[id->driver_data];
else
chip = &atlas_ezo_devices[(unsigned long)of_id->data];
indio_dev->info = &atlas_info;
indio_dev->name = ATLAS_EZO_DRV_NAME;
indio_dev->channels = chip->channels;
indio_dev->num_channels = chip->num_channels;
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->dev.parent = &client->dev;
data = iio_priv(indio_dev);
data->client = client;
data->chip = chip;
mutex_init(&data->lock);
return devm_iio_device_register(&client->dev, indio_dev);
};
static struct i2c_driver atlas_ezo_driver = {
.driver = {
.name = ATLAS_EZO_DRV_NAME,
.of_match_table = atlas_ezo_dt_ids,
},
.probe = atlas_ezo_probe,
.id_table = atlas_ezo_id,
};
module_i2c_driver(atlas_ezo_driver);
MODULE_AUTHOR("Matt Ranostay <matt.ranostay@konsulko.com>");
MODULE_DESCRIPTION("Atlas Scientific EZO sensors");
MODULE_LICENSE("GPL");
......@@ -53,6 +53,8 @@
#define ATLAS_REG_DO_CALIB_STATUS_PRESSURE BIT(0)
#define ATLAS_REG_DO_CALIB_STATUS_DO BIT(1)
#define ATLAS_REG_RTD_DATA 0x0e
#define ATLAS_REG_PH_TEMP_DATA 0x0e
#define ATLAS_REG_PH_DATA 0x16
......@@ -72,12 +74,14 @@
#define ATLAS_EC_INT_TIME_IN_MS 650
#define ATLAS_ORP_INT_TIME_IN_MS 450
#define ATLAS_DO_INT_TIME_IN_MS 450
#define ATLAS_RTD_INT_TIME_IN_MS 450
enum {
ATLAS_PH_SM,
ATLAS_EC_SM,
ATLAS_ORP_SM,
ATLAS_DO_SM,
ATLAS_RTD_SM,
};
struct atlas_data {
......@@ -218,6 +222,22 @@ static const struct iio_chan_spec atlas_do_channels[] = {
},
};
static const struct iio_chan_spec atlas_rtd_channels[] = {
{
.type = IIO_TEMP,
.address = ATLAS_REG_RTD_DATA,
.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
.scan_index = 0,
.scan_type = {
.sign = 's',
.realbits = 32,
.storagebits = 32,
.endianness = IIO_BE,
},
},
IIO_CHAN_SOFT_TIMESTAMP(1),
};
static int atlas_check_ph_calibration(struct atlas_data *data)
{
struct device *dev = &data->client->dev;
......@@ -362,6 +382,12 @@ static struct atlas_device atlas_devices[] = {
.calibration = &atlas_check_do_calibration,
.delay = ATLAS_DO_INT_TIME_IN_MS,
},
[ATLAS_RTD_SM] = {
.channels = atlas_rtd_channels,
.num_channels = 2,
.data_reg = ATLAS_REG_RTD_DATA,
.delay = ATLAS_RTD_INT_TIME_IN_MS,
},
};
static int atlas_set_powermode(struct atlas_data *data, int on)
......@@ -438,8 +464,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,
......@@ -475,7 +500,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);
......@@ -490,6 +515,7 @@ static int atlas_read_raw(struct iio_dev *indio_dev,
struct atlas_data *data = iio_priv(indio_dev);
switch (mask) {
case IIO_CHAN_INFO_PROCESSED:
case IIO_CHAN_INFO_RAW: {
int ret;
__be32 reg;
......@@ -497,7 +523,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:
......@@ -578,6 +604,7 @@ static const struct i2c_device_id atlas_id[] = {
{ "atlas-ec-sm", ATLAS_EC_SM},
{ "atlas-orp-sm", ATLAS_ORP_SM},
{ "atlas-do-sm", ATLAS_DO_SM},
{ "atlas-rtd-sm", ATLAS_RTD_SM},
{}
};
MODULE_DEVICE_TABLE(i2c, atlas_id);
......@@ -587,6 +614,7 @@ static const struct of_device_id atlas_dt_ids[] = {
{ .compatible = "atlas,ec-sm", .data = (void *)ATLAS_EC_SM, },
{ .compatible = "atlas,orp-sm", .data = (void *)ATLAS_ORP_SM, },
{ .compatible = "atlas,do-sm", .data = (void *)ATLAS_DO_SM, },
{ .compatible = "atlas,rtd-sm", .data = (void *)ATLAS_RTD_SM, },
{ }
};
MODULE_DEVICE_TABLE(of, atlas_dt_ids);
......
This diff is collapsed.
This diff is collapsed.
......@@ -73,6 +73,11 @@ struct pms7003_state {
struct pms7003_frame frame;
struct completion frame_ready;
struct mutex lock; /* must be held whenever state gets touched */
/* Used to construct scan to push to the IIO buffer */
struct {
u16 data[3]; /* PM1, PM2P5, PM10 */
s64 ts;
} scan;
};
static int pms7003_do_cmd(struct pms7003_state *state, enum pms7003_cmd cmd)
......@@ -104,7 +109,6 @@ static irqreturn_t pms7003_trigger_handler(int irq, void *p)
struct iio_dev *indio_dev = pf->indio_dev;
struct pms7003_state *state = iio_priv(indio_dev);
struct pms7003_frame *frame = &state->frame;
u16 data[3 + 1 + 4]; /* PM1, PM2P5, PM10, padding, timestamp */
int ret;
mutex_lock(&state->lock);
......@@ -114,12 +118,15 @@ static irqreturn_t pms7003_trigger_handler(int irq, void *p)
goto err;
}
data[PM1] = pms7003_get_pm(frame->data + PMS7003_PM1_OFFSET);
data[PM2P5] = pms7003_get_pm(frame->data + PMS7003_PM2P5_OFFSET);
data[PM10] = pms7003_get_pm(frame->data + PMS7003_PM10_OFFSET);
state->scan.data[PM1] =
pms7003_get_pm(frame->data + PMS7003_PM1_OFFSET);
state->scan.data[PM2P5] =
pms7003_get_pm(frame->data + PMS7003_PM2P5_OFFSET);
state->scan.data[PM10] =
pms7003_get_pm(frame->data + PMS7003_PM10_OFFSET);
mutex_unlock(&state->lock);
iio_push_to_buffers_with_timestamp(indio_dev, data,
iio_push_to_buffers_with_timestamp(indio_dev, &state->scan,
iio_get_time_ns(indio_dev));
err:
iio_trigger_notify_done(indio_dev->trig);
......
......@@ -230,15 +230,18 @@ static irqreturn_t sps30_trigger_handler(int irq, void *p)
struct iio_dev *indio_dev = pf->indio_dev;
struct sps30_state *state = iio_priv(indio_dev);
int ret;
s32 data[4 + 2]; /* PM1, PM2P5, PM4, PM10, timestamp */
struct {
s32 data[4]; /* PM1, PM2P5, PM4, PM10 */
s64 ts;
} scan;
mutex_lock(&state->lock);
ret = sps30_do_meas(state, data, 4);
ret = sps30_do_meas(state, scan.data, ARRAY_SIZE(scan.data));
mutex_unlock(&state->lock);
if (ret)
goto err;
iio_push_to_buffers_with_timestamp(indio_dev, data,
iio_push_to_buffers_with_timestamp(indio_dev, &scan,
iio_get_time_ns(indio_dev));
err:
iio_trigger_notify_done(indio_dev->trig);
......
......@@ -13,7 +13,8 @@ extern const struct dev_pm_ops hid_sensor_pm_ops;
int hid_sensor_setup_trigger(struct iio_dev *indio_dev, const char *name,
struct hid_sensor_common *attrb);
void hid_sensor_remove_trigger(struct hid_sensor_common *attrb);
void hid_sensor_remove_trigger(struct iio_dev *indio_dev,
struct hid_sensor_common *attrb);
int hid_sensor_power_state(struct hid_sensor_common *st, bool state);
#endif
......@@ -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);
}
......
......@@ -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);
}
......
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.
......@@ -52,6 +52,7 @@ struct ad5592r_state {
struct regulator *reg;
struct gpio_chip gpiochip;
struct mutex gpio_lock; /* Protect cached gpio_out, gpio_val, etc. */
struct mutex lock;
unsigned int num_channels;
const struct ad5592r_rw_ops *ops;
int scale_avail[2][2];
......
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.
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.
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