Merge 07281a257a ("Merge tag 'usb-5.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb") into android-mainline

Steps on the way to 5.15-rc1

Resolves merge conflicts in:
	drivers/misc/Makefile

Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Change-Id: I102636df13eb6320bb7ad739cbb4b82084fe078e
This commit is contained in:
Greg Kroah-Hartman
2021-09-07 14:45:27 +02:00
717 changed files with 75390 additions and 39864 deletions
@@ -8,9 +8,19 @@ Description:
c_chmask capture channel mask
c_srate capture sampling rate
c_ssize capture sample size (bytes)
c_mute_present capture mute control enable
c_volume_present capture volume control enable
c_volume_min capture volume control min value (in 1/256 dB)
c_volume_max capture volume control max value (in 1/256 dB)
c_volume_res capture volume control resolution (in 1/256 dB)
p_chmask playback channel mask
p_srate playback sampling rate
p_ssize playback sample size (bytes)
p_mute_present playback mute control enable
p_volume_present playback volume control enable
p_volume_min playback volume control min value (in 1/256 dB)
p_volume_max playback volume control max value (in 1/256 dB)
p_volume_res playback volume control resolution (in 1/256 dB)
req_number the number of pre-allocated request
for both capture and playback
========== ===================================
@@ -9,8 +9,18 @@ Description:
c_srate capture sampling rate
c_ssize capture sample size (bytes)
c_sync capture synchronization type (async/adaptive)
c_mute_present capture mute control enable
c_volume_present capture volume control enable
c_volume_min capture volume control min value (in 1/256 dB)
c_volume_max capture volume control max value (in 1/256 dB)
c_volume_res capture volume control resolution (in 1/256 dB)
fb_max maximum extra bandwidth in async mode
p_chmask playback channel mask
p_srate playback sampling rate
p_ssize playback sample size (bytes)
p_mute_present playback mute control enable
p_volume_present playback volume control enable
p_volume_min playback volume control min value (in 1/256 dB)
p_volume_max playback volume control max value (in 1/256 dB)
p_volume_res playback volume control resolution (in 1/256 dB)
========= ============================
@@ -0,0 +1,31 @@
What: /sys/bus/iio/devices/iio:deviceX/out_temp_raw
Date: August 2021
KernelVersion: 5.15
Contact: Andreas Klinger <ak@it-klinger.de>
Description:
Set the temperature. This value is sent to the sensor for
temperature compensation.
Default value: 25000 (25 °C)
What: /sys/bus/iio/devices/iio:deviceX/out_humidityrelative_raw
Date: August 2021
KernelVersion: 5.15
Contact: Andreas Klinger <ak@it-klinger.de>
Description:
Set the relative humidity. This value is sent to the sensor for
humidity compensation.
Default value: 50000 (50 % relative humidity)
What: /sys/bus/iio/devices/iio:deviceX/in_resistance_calibbias
Date: August 2021
KernelVersion: 5.15
Contact: Andreas Klinger <ak@it-klinger.de>
Description:
Set the bias value for the resistance which is used for
calculation of in_concentration_input as follows:
x = (in_resistance_raw - in_resistance_calibbias) * 0.65
in_concentration_input = 500 / (1 + e^x)
Default value: 30000
@@ -111,6 +111,10 @@ properties:
- 1.5A
- 3.0A
pd-disable:
description: Set this property if the Type-C connector has no power delivery support.
type: boolean
# The following are optional properties for "usb-c-connector" with power
# delivery support.
source-pdos:
@@ -1,61 +0,0 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/accel/bosch,bma180.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Bosch BMA023 / BMA150/ BMA180 / BMA250 / SMB380 triaxial accelerometers
maintainers:
- Jonathan Cameron <jic23@kernel.org>
description: |
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
properties:
compatible:
enum:
- bosch,bma023
- bosch,bma150
- bosch,bma180
- bosch,bma250
- bosch,smb380
reg:
maxItems: 1
vdd-supply: true
vddio-supply: true
interrupts:
minItems: 1
maxItems: 2
description: |
Type should be either IRQ_TYPE_LEVEL_HIGH or IRQ_TYPE_EDGE_RISING.
For the bma250 the first interrupt listed must be the one
connected to the INT1 pin, the second (optional) interrupt
listed must be the one connected to the INT2 pin.
required:
- compatible
- reg
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
accel@40 {
compatible = "bosch,bma180";
reg = <0x40>;
interrupt-parent = <&gpio6>;
interrupts = <18 (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_EDGE_RISING)>;
};
};
...
@@ -8,6 +8,7 @@ title: Bosch BMA255 and Similar Accelerometers
maintainers:
- Linus Walleij <linus.walleij@linaro.org>
- Stephan Gerhold <stephan@gerhold.net>
description:
3 axis accelerometers with varying range and I2C or SPI
@@ -16,15 +17,24 @@ description:
properties:
compatible:
enum:
- bosch,bmc150_accel
- bosch,bmi055_accel
# bmc150-accel driver in Linux
- bosch,bma222
- bosch,bma222e
- bosch,bma250e
- bosch,bma253
- bosch,bma254
- bosch,bma255
- bosch,bma250e
- bosch,bma222
- bosch,bma222e
- bosch,bma280
- bosch,bmc150_accel
- bosch,bmc156_accel
- bosch,bmi055_accel
# bma180 driver in Linux
- bosch,bma023
- bosch,bma150
- bosch,bma180
- bosch,bma250
- bosch,smb380
reg:
maxItems: 1
@@ -36,9 +46,21 @@ properties:
minItems: 1
maxItems: 2
description: |
The first interrupt listed must be the one connected to the INT1 pin,
the second (optional) interrupt listed must be the one connected to the
INT2 pin (if available).
Without interrupt-names, the first interrupt listed must be the one
connected to the INT1 pin, the second (optional) interrupt listed must be
the one connected to the INT2 pin (if available). The type should be
IRQ_TYPE_EDGE_RISING.
BMC156 does not have an INT1 pin, therefore the first interrupt pin is
always treated as INT2.
interrupt-names:
minItems: 1
maxItems: 2
items:
enum:
- INT1
- INT2
mount-matrix:
description: an optional 3x3 mounting rotation matrix.
@@ -63,7 +85,22 @@ examples:
reg = <0x08>;
vddio-supply = <&vddio>;
vdd-supply = <&vdd>;
interrupts = <57 IRQ_TYPE_EDGE_FALLING>;
interrupts = <57 IRQ_TYPE_EDGE_RISING>;
interrupt-names = "INT1";
};
};
- |
#include <dt-bindings/interrupt-controller/irq.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
accelerometer@10 {
compatible = "bosch,bmc156_accel";
reg = <0x10>;
vddio-supply = <&vddio>;
vdd-supply = <&vdd>;
interrupts = <116 IRQ_TYPE_EDGE_RISING>;
interrupt-names = "INT2";
};
};
- |
@@ -23,6 +23,8 @@ properties:
enum:
- ingenic,jz4725b-adc
- ingenic,jz4740-adc
- ingenic,jz4760-adc
- ingenic,jz4760b-adc
- ingenic,jz4770-adc
'#io-channel-cells':
@@ -43,6 +45,23 @@ properties:
interrupts:
maxItems: 1
ingenic,use-internal-divider:
description:
If present, battery voltage is read from the VBAT_IR pin, which has an
internal 1/4 divider. If absent, it is read through the VBAT_ER pin,
which does not have such a divider.
type: boolean
if:
not:
properties:
compatible:
contains:
const: ingenic,jz4760b-adc
then:
properties:
ingenic,use-internal-divider: false
required:
- compatible
- '#io-channel-cells'
@@ -0,0 +1,134 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/adc/renesas,rzg2l-adc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Renesas RZ/G2L ADC
maintainers:
- Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
description: |
A/D Converter block is a successive approximation analog-to-digital converter
with a 12-bit accuracy. Up to eight analog input channels can be selected.
Conversions can be performed in single or repeat mode. Result of the ADC is
stored in a 32-bit data register corresponding to each channel.
properties:
compatible:
items:
- enum:
- renesas,r9a07g044-adc # RZ/G2{L,LC}
- const: renesas,rzg2l-adc
reg:
maxItems: 1
interrupts:
maxItems: 1
clocks:
items:
- description: converter clock
- description: peripheral clock
clock-names:
items:
- const: adclk
- const: pclk
power-domains:
maxItems: 1
resets:
maxItems: 2
reset-names:
items:
- const: presetn
- const: adrst-n
'#address-cells':
const: 1
'#size-cells':
const: 0
required:
- compatible
- reg
- interrupts
- clocks
- clock-names
- power-domains
- resets
- reset-names
patternProperties:
"^channel@[0-7]$":
$ref: "adc.yaml"
type: object
description: |
Represents the external channels which are connected to the ADC.
properties:
reg:
description: |
The channel number. It can have up to 8 channels numbered from 0 to 7.
items:
- minimum: 0
maximum: 7
required:
- reg
additionalProperties: false
additionalProperties: false
examples:
- |
#include <dt-bindings/clock/r9a07g044-cpg.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
adc: adc@10059000 {
compatible = "renesas,r9a07g044-adc", "renesas,rzg2l-adc";
reg = <0x10059000 0x400>;
interrupts = <GIC_SPI 347 IRQ_TYPE_EDGE_RISING>;
clocks = <&cpg CPG_MOD R9A07G044_ADC_ADCLK>,
<&cpg CPG_MOD R9A07G044_ADC_PCLK>;
clock-names = "adclk", "pclk";
power-domains = <&cpg>;
resets = <&cpg R9A07G044_ADC_PRESETN>,
<&cpg R9A07G044_ADC_ADRST_N>;
reset-names = "presetn", "adrst-n";
#address-cells = <1>;
#size-cells = <0>;
channel@0 {
reg = <0>;
};
channel@1 {
reg = <1>;
};
channel@2 {
reg = <2>;
};
channel@3 {
reg = <3>;
};
channel@4 {
reg = <4>;
};
channel@5 {
reg = <5>;
};
channel@6 {
reg = <6>;
};
channel@7 {
reg = <7>;
};
};
@@ -20,6 +20,7 @@ properties:
- rockchip,px30-saradc
- rockchip,rk3308-saradc
- rockchip,rk3328-saradc
- rockchip,rk3568-saradc
- rockchip,rv1108-saradc
- const: rockchip,rk3399-saradc
@@ -0,0 +1,268 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/dac/adi,ad5064.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Analog Devices AD5064 and similar DACs
maintainers:
- Lars-Peter Clausen <lars@metafoo.de>
- Jonathan Cameron <jic23@kernel.org>
description: |
A range of similar DAC devices with between 1 and 12 channels. Some parts
have internal references, others require a single shared external reference
and the remainder have a separate reference pin for each DAC.
properties:
compatible:
oneOf:
- description: I2C devics
enum:
- adi,ad5024
- adi,ad5025
- adi,ad5044
- adi,ad5045
- adi,ad5064
- adi,ad5064-1
- adi,ad5065
- adi,ad5628-1
- adi,ad5628-2
- adi,ad5648-1
- adi,ad5648-2
- adi,ad5666-1
- adi,ad5666-2
- adi,ad5668-1
- adi,ad5668-2
- adi,ad5668-3
- description: SPI devices
enum:
- adi,ad5625
- adi,ad5625r-1v25
- adi,ad5625r-2v5
- adi,ad5627
- adi,ad5627r-1v25
- adi,ad5627r-2v5
- adi,ad5629-1
- adi,ad5629-2
- adi,ad5629-3
- adi,ad5645r-1v25
- adi,ad5645r-2v5
- adi,ad5665
- adi,ad5665r-1v25
- adi,ad5665r-2v5
- adi,ad5667
- adi,ad5667r-1v25
- adi,ad5667r-2v5
- adi,ad5669-1
- adi,ad5669-2
- adi,ad5669-3
- lltc,ltc2606
- lltc,ltc2607
- lltc,ltc2609
- lltc,ltc2616
- lltc,ltc2617
- lltc,ltc2619
- lltc,ltc2626
- lltc,ltc2627
- lltc,ltc2629
- lltc,ltc2631-l12
- lltc,ltc2631-h12
- lltc,ltc2631-l10
- lltc,ltc2631-h10
- lltc,ltc2631-l8
- lltc,ltc2631-h8
- lltc,ltc2633-l12
- lltc,ltc2633-h12
- lltc,ltc2633-l10
- lltc,ltc2633-h10
- lltc,ltc2633-l8
- lltc,ltc2633-h8
- lltc,ltc2635-l12
- lltc,ltc2635-h12
- lltc,ltc2635-l10
- lltc,ltc2635-h10
- lltc,ltc2635-l8
- lltc,ltc2635-h8
reg:
maxItems: 1
vrefA-supply: true
vrefB-supply: true
vrefC-supply: true
vrefD-supply: true
vref-supply: true
spi-max-frequency: true
additionalProperties: false
required:
- compatible
- reg
allOf:
- # Shared external vref, no internal reference
if:
properties:
compatible:
contains:
enum:
- adi,ad5064-1
- adi,ad5625
- adi,ad5627
- adi,ad5665
- adi,ad5667
- lltc,ltc2606
- lltc,ltc2607
- lltc,ltc2616
- lltc,ltc2617
- lltc,ltc2626
- lltc,ltc2627
then:
properties:
vref-supply: true
vrefA-supply: false
vrefB-supply: false
vrefC-supply: false
vrefD-supply: false
required:
- vref-supply
- # Shared external vref, internal reference available
if:
properties:
compatible:
contains:
enum:
- adi,ad5625r-1v25
- adi,ad5625r-2v5
- adi,ad5627r-1v25
- adi,ad5627r-2v5
- adi,ad5628-1
- adi,ad5628-2
- adi,ad5629-1
- adi,ad5629-2
- adi,ad5629-3
- adi,ad5645r-1v25
- adi,ad5645r-2v5
- adi,ad5647r-1v25
- adi,ad5647r-2v5
- adi,ad5648-1
- adi,ad5648-2
- adi,ad5665r-1v25
- adi,ad5665r-2v5
- adi,ad5666-1
- adi,ad5666-2
- adi,ad5667r-1v25
- adi,ad5667r-2v5
- adi,ad5668-1
- adi,ad5668-2
- adi,ad5668-3
- adi,ad5669-1
- adi,ad5669-2
- adi,ad5669-3
- lltc,ltc2631-l12
- lltc,ltc2631-h12
- lltc,ltc2631-l10
- lltc,ltc2631-h10
- lltc,ltc2631-l8
- lltc,ltc2631-h8
- lltc,ltc2633-l12
- lltc,ltc2633-h12
- lltc,ltc2633-l10
- lltc,ltc2633-h10
- lltc,ltc2633-l8
- lltc,ltc2633-h8
- lltc,ltc2635-l12
- lltc,ltc2635-h12
- lltc,ltc2635-l10
- lltc,ltc2635-h10
- lltc,ltc2635-l8
- lltc,ltc2635-h8
then:
properties:
vref-supply: true
vrefA-supply: false
vrefB-supply: false
vrefC-supply: false
vrefD-supply: false
- # 4 input devices, separate vrefs, no internal reference
if:
properties:
compatible:
contains:
enum:
- adi,ad5024
- adi,ad5044
- adi,ad5064
- lltc,ltc2609
- lltc,ltc2619
- lltc,ltc2629
then:
properties:
vrefA-supply: true
vrefB-supply: true
vrefC-supply: true
vrefD-supply: true
vref-supply: false
required:
- vrefA-supply
- vrefB-supply
- vrefC-supply
- vrefD-supply
- # 2 input devices, separate vrefs, no internal reference
if:
properties:
compatible:
contains:
enum:
- adi,ad5025
- adi,ad5045
- adi,ad5065
then:
properties:
vrefA-supply: true
vrefB-supply: true
vrefC-supply: false
vrefD-supply: false
vref-supply: false
required:
- vrefA-supply
- vrefB-supply
examples:
- |
spi {
#address-cells = <1>;
#size-cells = <0>;
dac@0 {
reg = <0>;
compatible = "adi,ad5625";
vref-supply = <&dac_vref>;
};
};
- |
spi {
#address-cells = <1>;
#size-cells = <0>;
dac@0 {
reg = <0>;
compatible = "adi,ad5625r-1v25";
};
};
- |
i2c {
#address-cells = <1>;
#size-cells = <0>;
dac@42 {
reg = <0x42>;
compatible = "adi,ad5024";
vrefA-supply = <&dac_vref>;
vrefB-supply = <&dac_vref>;
vrefC-supply = <&dac_vref2>;
vrefD-supply = <&dac_vref2>;
};
};
...
@@ -0,0 +1,79 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/dac/adi,ad5360.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Analog Devices AD5360 and similar DACs
maintainers:
- Lars-Peter Clausen <lars@metafoo.de>
- Jonathan Cameron <jic23@kernel.org>
properties:
compatible:
enum:
- adi,ad5360
- adi,ad5361
- adi,ad5363
- adi,ad5370
- adi,ad5371
- adi,ad5372
- adi,ad5373
reg:
maxItems: 1
vref0-supply: true
vref1-supply: true
vref2-supply: true
spi-max-frequency: true
additionalProperties: false
required:
- compatible
- reg
- vref0-supply
- vref1-supply
allOf:
- if:
properties:
compatible:
contains:
enum:
- adi,ad5360
- adi,ad5361
- adi,ad5363
- adi,ad5370
- adi,ad5372
- adi,ad5373
then:
properties:
vref2-supply: false
- if:
properties:
compatible:
contains:
enum:
- adi,ad5371
then:
required:
- vref2-supply
examples:
- |
spi {
#address-cells = <1>;
#size-cells = <0>;
dac@0 {
reg = <0>;
compatible = "adi,ad5371";
vref0-supply = <&dac_vref0>;
vref1-supply = <&dac_vref1>;
vref2-supply = <&dac_vref2>;
};
};
...
@@ -0,0 +1,70 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/dac/adi,ad5380.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Analog Devices AD5380 and similar DACs
maintainers:
- Lars-Peter Clausen <lars@metafoo.de>
- Jonathan Cameron <jic23@kernel.org>
description: |
DAC devices supporting both SPI and I2C interfaces.
properties:
compatible:
enum:
- adi,ad5380-3
- adi,ad5380-5
- adi,ad5381-3
- adi,ad5381-5
- adi,ad5382-3
- adi,ad5382-5
- adi,ad5383-3
- adi,ad5383-5
- adi,ad5384-3
- adi,ad5384-5
- adi,ad5390-3
- adi,ad5390-5
- adi,ad5391-3
- adi,ad5391-5
- adi,ad5392-3
- adi,ad5392-5
reg:
maxItems: 1
vref-supply:
description:
If not supplied devices will use internal regulators.
spi-max-frequency: true
additionalProperties: false
required:
- compatible
- reg
examples:
- |
spi {
#address-cells = <1>;
#size-cells = <0>;
dac@0 {
reg = <0>;
compatible = "adi,ad5390-5";
vref-supply = <&dacvref>;
};
};
- |
i2c {
#address-cells = <1>;
#size-cells = <0>;
dac@42 {
reg = <0x42>;
compatible = "adi,ad5380-3";
};
};
...
@@ -0,0 +1,51 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/dac/adi,ad5421.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Analog Devices AD5421 DAC
maintainers:
- Lars-Peter Clausen <lars@metafoo.de>
- Jonathan Cameron <jic23@kernel.org>
description: |
AD5421 is designed for us in loop-powered, 4 mA to 20 mA smart transmitter
applications. It provides a 16-bit DAC, current amplifier, voltage regulator
to drive the loop and a voltage reference.
properties:
compatible:
const: adi,ad5421
reg:
maxItems: 1
interrupts:
maxItems: 1
description: Fault signal.
spi-max-frequency: true
required:
- compatible
- reg
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
spi {
#address-cells = <1>;
#size-cells = <0>;
dac@0 {
compatible = "adi,ad5421";
reg = <0>;
spi-max-frequency = <30000000>;
interrupts = <55 IRQ_TYPE_LEVEL_HIGH>;
};
};
...
@@ -0,0 +1,97 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/dac/adi,ad5449.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Analog Devices AD5449 and similar DACs
maintainers:
- Lars-Peter Clausen <lars@metafoo.de>
- Jonathan Cameron <jic23@kernel.org>
description:
Family of multiplying DACs from Analog Devices
properties:
compatible:
enum:
- adi,ad5415
- adi,ad5426
- adi,ad5429
- adi,ad5432
- adi,ad5439
- adi,ad5443
- adi,ad5449
reg:
maxItems: 1
spi-max-frequency: true
VREF-supply: true
VREFA-supply: true
VREFB-supply: true
additionalProperties: false
required:
- compatible
- reg
allOf:
- if:
properties:
compatible:
contains:
enum:
- adi,ad5415
- adi,ad5426
- adi,ad5432
then:
properties:
VREF-supply: true
VREFA-supply: false
VREFB-supply: false
required:
- VREF-supply
- if:
properties:
compatible:
contains:
enum:
- adi,ad5429
- adi,ad5439
- adi,ad5449
then:
properties:
VREF-supply: false
VREFA-supply: true
VREFB-supply: true
required:
- VREFA-supply
- VREFB-supply
examples:
- |
spi {
#address-cells = <1>;
#size-cells = <0>;
dac@0 {
reg = <0>;
compatible = "adi,ad5415";
VREF-supply = <&dac_ref>;
};
};
- |
spi {
#address-cells = <1>;
#size-cells = <0>;
dac@0 {
reg = <0>;
compatible = "adi,ad5429";
VREFA-supply = <&dac_refA>;
VREFB-supply = <&dac_refB>;
};
};
...
@@ -0,0 +1,50 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/dac/adi,ad5504.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Analog Devices AD5501 and AD5504 DACs
maintainers:
- Lars-Peter Clausen <lars@metafoo.de>
- Jonathan Cameron <jic23@kernel.org>
description:
High voltage (up to 60V) DACs with temperature sensor alarm function
properties:
compatible:
enum:
- adi,ad5501
- adi,ad5504
reg:
maxItems: 1
interrupts:
description: Used for temperature alarm.
maxItems: 1
vcc-supply: true
additionalProperties: false
required:
- compatible
- reg
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
spi {
#address-cells = <1>;
#size-cells = <0>;
dac@0 {
reg = <0>;
compatible = "adi,ad5504";
vcc-supply = <&dac_vcc>;
interrupts = <55 IRQ_TYPE_EDGE_FALLING>;
};
};
...
@@ -0,0 +1,47 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/dac/adi,ad5624r.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Analog Devices AD5624r and similar DACs
maintainers:
- Jonathan Cameron <jic23@kernel.org>
properties:
compatible:
enum:
- adi,ad5624r3
- adi,ad5644r3
- adi,ad5664r3
- adi,ad5624r5
- adi,ad5644r5
- adi,ad5664r5
reg:
maxItems: 1
spi-max-frequency: true
vref-supply:
description: If not present, internal reference will be used.
additionalProperties: false
required:
- compatible
- reg
examples:
- |
spi {
#address-cells = <1>;
#size-cells = <0>;
dac@0 {
reg = <0>;
compatible = "adi,ad5624r3";
vref-supply = <&vref>;
};
};
...
@@ -0,0 +1,75 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/dac/adi,ad5686.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Analog Devices AD5360 and similar DACs
maintainers:
- Michael Hennerich <michael.hennerich@analog.com>
- Jonathan Cameron <jic23@kernel.org>
properties:
compatible:
oneOf:
- description: SPI devices
enum:
- adi,ad5310r
- adi,ad5672r
- adi,ad5674r
- adi,ad5676
- adi,ad5676r
- adi,ad5679r
- adi,ad5681r
- adi,ad5682r
- adi,ad5683
- adi,ad5683r
- adi,ad5684
- adi,ad5684r
- adi,ad5685r
- adi,ad5686
- adi,ad5686r
- description: I2C devices
enum:
- adi,ad5311r
- adi,ad5338r
- adi,ad5671r
- adi,ad5675r
- adi,ad5691r
- adi,ad5692r
- adi,ad5693
- adi,ad5693r
- adi,ad5694
- adi,ad5694r
- adi,ad5695r
- adi,ad5696
- adi,ad5696r
reg:
maxItems: 1
vcc-supply:
description: If not supplied the internal reference is used.
spi-max-frequency: true
additionalProperties: false
required:
- compatible
- reg
examples:
- |
spi {
#address-cells = <1>;
#size-cells = <0>;
dac@0 {
reg = <0>;
compatible = "adi,ad5310r";
vcc-supply = <&dac_vref0>;
};
};
...
@@ -0,0 +1,60 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/dac/adi,ad5761.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Analog Devices AD5761 and similar DACs
maintainers:
- Ricardo Ribalda <ribalda@kernel.org>
- Jonathan Cameron <jic23@kernel.org>
properties:
compatible:
enum:
- adi,ad5721
- adi,ad5721r
- adi,ad5761
- adi,ad5761r
reg:
maxItems: 1
spi-max-frequency: true
vref-supply:
description: If not supplied, internal reference will be used.
additionalProperties: false
required:
- compatible
- reg
allOf:
- if:
properties:
compatible:
contains:
enum:
- adi,ad5721
- adi,ad5761
then:
required:
- vref-supply
examples:
- |
spi {
#address-cells = <1>;
#size-cells = <0>;
dac@0 {
compatible = "adi,ad5721";
reg = <0>;
vref-supply = <&dac_vref>;
};
};
...
@@ -0,0 +1,62 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/dac/adi,ad5764.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Analog Devices AD5744 and AD5764 DAC families
maintainers:
- Lars-Peter Clausen <lars@metafoo.de>
- Jonathan Cameron <jic23@kernel.org>
properties:
compatible:
enum:
- adi,ad5744
- adi,ad5744r
- adi,ad5764
- adi,ad5764r
reg:
maxItems: 1
spi-max-frequency: true
vrefAB-supply: true
vrefCD-supply: true
additionalProperties: false
required:
- compatible
- reg
allOf:
- if:
properties:
compatible:
contains:
enum:
- adi,ad5744
- adi,ad5764
then:
required:
- vrefAB-supply
- vrefCD-supply
examples:
- |
spi {
#address-cells = <1>;
#size-cells = <0>;
dac@0 {
compatible = "adi,ad5744";
reg = <0>;
vrefAB-supply = <&dac_vref>;
vrefCD-supply = <&dac_vref>;
};
};
...
@@ -0,0 +1,52 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/dac/adi,ad5791.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Analog Devices AD5791 and similar DACs
maintainers:
- Michael Hennerich <michael.hennerich@analog.com>
- Jonathan Cameron <jic23@kernel.org>
properties:
compatible:
enum:
- adi,ad5760
- adi,ad5780
- adi,ad5781
- adi,ad5790
- adi,ad5791
reg:
maxItems: 1
spi-max-frequency: true
vdd-supply: true
vss-supply: true
additionalProperties: false
required:
- compatible
- reg
- vdd-supply
- vss-supply
examples:
- |
spi {
#address-cells = <1>;
#size-cells = <0>;
dac@0 {
compatible = "adi,ad5791";
reg = <0>;
vss-supply = <&dac_vss>;
vdd-supply = <&dac_vdd>;
};
};
...
@@ -0,0 +1,60 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/dac/adi,ad8801.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Analog Devices AD8801 and AD8803 DACs
maintainers:
- Jonathan Cameron <jic23@kernel.org>
properties:
compatible:
enum:
- adi,ad8801
- adi,ad8803
reg:
maxItems: 1
spi-max-frequency: true
vrefh-supply: true
vrefl-supply: true
additionalProperties: false
required:
- compatible
- reg
- vrefh-supply
allOf:
- if:
properties:
compatible:
contains:
const: adi,ad8803
then:
required:
- vrefl-supply
else:
properties:
vrefl-supply: false
examples:
- |
spi {
#address-cells = <1>;
#size-cells = <0>;
dac@0 {
compatible = "adi,ad8803";
reg = <0>;
vrefl-supply = <&dac_vrefl>;
vrefh-supply = <&dac_vrefh>;
};
};
...
@@ -0,0 +1,46 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/dac/microchip,mcp4922.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Microchip MCP4902, MCP4912 and MPC4922 dual output SPI DACs
maintainers:
- Jonathan Cameron <jic23@kernel.org>
- Michael Welling <mwelling@ieee.org>
properties:
compatible:
enum:
- microchip,mcp4902
- microchip,mcp4912
- microchip,mcp4922
reg:
maxItems: 1
spi-max-frequency: true
vref-supply: true
additionalProperties: false
required:
- compatible
- reg
- vref-supply
examples:
- |
spi {
#address-cells = <1>;
#size-cells = <0>;
dac@0 {
compatible = "microchip,mcp4912";
reg = <0>;
vref-supply = <&dac_vref>;
};
};
...
@@ -34,13 +34,14 @@ properties:
interrupt-controller: true
gpios:
interrupts:
maxItems: 1
description: GPIO used for IRQs
regulators:
type: object
additionalProperties: false
properties:
'#address-cells':
const: 1
@@ -49,11 +50,13 @@ properties:
const: 0
patternProperties:
'^ldo[0-9]+@[0-9a-f]$':
'^ldo[0-9]+$':
type: object
$ref: "/schemas/regulator/regulator.yaml#"
unevaluatedProperties: false
required:
- compatible
- reg
@@ -63,69 +66,69 @@ additionalProperties: false
examples:
- |
/* pmic properties */
pmic: pmic@0 {
compatible = "hisilicon,hi6421-spmi";
compatible = "hisilicon,hi6421v600-spmi";
reg = <0 0>;
#interrupt-cells = <2>;
interrupt-controller;
gpios = <&gpio28 0 0>;
interrupt-parent = <&gpio28>;
interrupts = <0 0>;
regulators {
#address-cells = <1>;
#size-cells = <0>;
ldo3: LDO3 {
ldo3: ldo3 {
regulator-name = "ldo3";
regulator-min-microvolt = <1500000>;
regulator-max-microvolt = <2000000>;
regulator-boot-on;
};
ldo4: LDO4 {
ldo4: ldo4 {
regulator-name = "ldo4";
regulator-min-microvolt = <1725000>;
regulator-max-microvolt = <1900000>;
regulator-boot-on;
};
ldo9: LDO9 {
ldo9: ldo9 {
regulator-name = "ldo9";
regulator-min-microvolt = <1750000>;
regulator-max-microvolt = <3300000>;
regulator-boot-on;
};
ldo15: LDO15 {
ldo15: ldo15 {
regulator-name = "ldo15";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <3000000>;
regulator-always-on;
};
ldo16: LDO16 {
ldo16: ldo16 {
regulator-name = "ldo16";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <3000000>;
regulator-boot-on;
};
ldo17: LDO17 {
ldo17: ldo17 {
regulator-name = "ldo17";
regulator-min-microvolt = <2500000>;
regulator-max-microvolt = <3300000>;
};
ldo33: LDO33 {
ldo33: ldo33 {
regulator-name = "ldo33";
regulator-min-microvolt = <2500000>;
regulator-max-microvolt = <3300000>;
regulator-boot-on;
};
ldo34: LDO34 {
ldo34: ldo34 {
regulator-name = "ldo34";
regulator-min-microvolt = <2600000>;
regulator-max-microvolt = <3300000>;
@@ -14,6 +14,7 @@ properties:
compatible:
enum:
- qcom,sc7180-qmp-usb3-dp-phy
- qcom,sc7280-qmp-usb3-dp-phy
- qcom,sc8180x-qmp-usb3-dp-phy
- qcom,sdm845-qmp-usb3-dp-phy
- qcom,sm8250-qmp-usb3-dp-phy
@@ -64,6 +64,12 @@ properties:
- const: nuvoton,npcm750-uart
- const: nvidia,tegra20-uart
- const: nxp,lpc3220-uart
- items:
- enum:
- exar,xr16l2552
- exar,xr16l2551
- exar,xr16l2550
- const: ns8250
- items:
- enum:
- altr,16550-FIFO32
@@ -79,6 +79,7 @@ properties:
power-domains: true
clock-frequency: true
current-speed: true
overrun-throttle-ms: true
required:
- compatible
@@ -1,27 +0,0 @@
Binding for Cadence UART Controller
Required properties:
- compatible :
Use "xlnx,xuartps","cdns,uart-r1p8" for Zynq-7xxx SoC.
Use "xlnx,zynqmp-uart","cdns,uart-r1p12" for Zynq Ultrascale+ MPSoC.
- reg: Should contain UART controller registers location and length.
- interrupts: Should contain UART controller interrupts.
- clocks: Must contain phandles to the UART clocks
See ../clocks/clock-bindings.txt for details.
- clock-names: Tuple to identify input clocks, must contain "uart_clk" and "pclk"
See ../clocks/clock-bindings.txt for details.
Optional properties:
- cts-override : Override the CTS modem status signal. This signal will
always be reported as active instead of being obtained from the modem status
register. Define this if your serial port does not use this pin
Example:
uart@e0000000 {
compatible = "cdns,uart-r1p8";
clocks = <&clkc 23>, <&clkc 40>;
clock-names = "uart_clk", "pclk";
reg = <0xE0000000 0x1000>;
interrupts = <0 27 4>;
};
@@ -0,0 +1,66 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/serial/cdns,uart.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Cadence UART Controller Device Tree Bindings
maintainers:
- Michal Simek <michal.simek@xilinx.com>
allOf:
- $ref: /schemas/serial.yaml#
properties:
compatible:
oneOf:
- description: UART controller for Zynq-7xxx SoC
items:
- const: xlnx,xuartps
- const: cdns,uart-r1p8
- description: UART controller for Zynq Ultrascale+ MPSoC
items:
- const: xlnx,zynqmp-uart
- const: cdns,uart-r1p12
reg:
maxItems: 1
interrupts:
maxItems: 1
clocks:
maxItems: 2
clock-names:
items:
- const: uart_clk
- const: pclk
cts-override:
description: |
Override the CTS modem status signal. This signal will
always be reported as active instead of being obtained
from the modem status register. Define this if your serial
port does not use this pin.
type: boolean
required:
- compatible
- reg
- interrupts
- clocks
- clock-names
unevaluatedProperties: false
examples:
- |
uart0: serial@e0000000 {
compatible = "xlnx,xuartps", "cdns,uart-r1p8";
clocks = <&clkc 23>, <&clkc 40>;
clock-names = "uart_clk", "pclk";
reg = <0xE0000000 0x1000>;
interrupts = <0 27 4>;
};
@@ -15,6 +15,7 @@ Required properties:
* "mediatek,mt7622-uart" for MT7622 compatible UARTS
* "mediatek,mt7623-uart" for MT7623 compatible UARTS
* "mediatek,mt7629-uart" for MT7629 compatible UARTS
* "mediatek,mt7986-uart", "mediatek,mt6577-uart" for MT7986 compatible UARTS
* "mediatek,mt8127-uart" for MT8127 compatible UARTS
* "mediatek,mt8135-uart" for MT8135 compatible UARTS
* "mediatek,mt8173-uart" for MT8173 compatible UARTS
@@ -33,6 +33,8 @@ properties:
- ad,ad7414
# ADM9240: Complete System Hardware Monitor for uProcessor-Based Systems
- ad,adm9240
# AD5110 - Nonvolatile Digital Potentiometer
- adi,ad5110
# Analog Devices ADP5585 Keypad Decoder and I/O Expansion
- adi,adp5585
# Analog Devices ADP5585 Keypad Decoder and I/O Expansion with support for Row5
@@ -61,6 +63,8 @@ properties:
- capella,cm32181
# CM3232: Ambient Light Sensor
- capella,cm3232
# CM3323: Ambient Light Sensor
- capella,cm3323
# High-Precision Digital Thermometer
- dallas,ds1631
# Total-Elapsed-Time Recorder with Alarm
@@ -269,6 +273,8 @@ properties:
- sensirion,sgpc3
# Sensirion multi-pixel gas sensor with I2C interface
- sensirion,sgp30
# Sensirion gas sensor with I2C interface
- sensirion,sgp40
# Sensortek 3 axis accelerometer
- sensortek,stk8312
# Sensortek 3 axis accelerometer
@@ -34,6 +34,7 @@ properties:
- allwinner,sun6i-a31-ehci
- allwinner,sun7i-a20-ehci
- allwinner,sun8i-a23-ehci
- allwinner,sun8i-a83t-ehci
- allwinner,sun8i-h3-ehci
- allwinner,sun8i-r40-ehci
- allwinner,sun9i-a80-ehci
@@ -142,6 +143,11 @@ properties:
iommus:
maxItems: 1
dr_mode:
enum:
- host
- otg
required:
- compatible
- reg
@@ -24,6 +24,7 @@ properties:
- allwinner,sun6i-a31-ohci
- allwinner,sun7i-a20-ohci
- allwinner,sun8i-a23-ohci
- allwinner,sun8i-a83t-ohci
- allwinner,sun8i-h3-ohci
- allwinner,sun8i-r40-ohci
- allwinner,sun9i-a80-ohci
@@ -109,6 +110,11 @@ properties:
iommus:
maxItems: 1
dr_mode:
enum:
- host
- otg
required:
- compatible
- reg
@@ -31,6 +31,7 @@ properties:
- mediatek,mt8173-xhci
- mediatek,mt8183-xhci
- mediatek,mt8192-xhci
- mediatek,mt8195-xhci
- const: mediatek,mtk-xhci
reg:
@@ -152,6 +153,11 @@ properties:
description: The mask to disable u3ports, bit0 for u3port0,
bit1 for u3port1, ... etc
mediatek,u2p-dis-msk:
$ref: /schemas/types.yaml#/definitions/uint32
description: The mask to disable u2ports, bit0 for u2port0,
bit1 for u2port1, ... etc
"#address-cells":
const: 1
@@ -38,7 +38,18 @@ properties:
- const: ippc
interrupts:
maxItems: 1
description:
use "interrupts-extended" when the interrupts are connected to the
separate interrupt controllers
minItems: 1
items:
- description: SSUSB device controller interrupt
- description: optional, wakeup interrupt used to support runtime PM
interrupt-names:
items:
- const: device
- const: wakeup
power-domains:
description: A phandle to USB power domain node to control USB's MTCMOS
@@ -106,7 +117,7 @@ properties:
extcon:
deprecated: true
description: |
Phandle to the extcon device detecting the IDDIG/VBUS state, neede
Phandle to the extcon device detecting the IDDIG state, needed
when supports dual-role mode.
It's considered valid for compatibility reasons, not allowed for
new bindings, and use "usb-role-switch" property instead.
@@ -116,6 +127,10 @@ properties:
description: Support role switch.
type: boolean
role-switch-default-mode:
enum: [host, peripheral]
default: host
connector:
$ref: /connector/usb-connector.yaml#
description:
@@ -166,6 +181,12 @@ properties:
description: The mask to disable u3ports, bit0 for u3port0,
bit1 for u3port1, ... etc
mediatek,u2p-dis-msk:
$ref: /schemas/types.yaml#/definitions/uint32
description: The mask to disable u2ports, bit0 for u2port0,
bit1 for u2port1, ... etc; but can't disable u2port0 if dual role mode
is enabled, so will be skipped in this case.
# Required child node when support dual-role
patternProperties:
"^usb@[0-9a-f]+$":
@@ -178,6 +199,7 @@ patternProperties:
dependencies:
connector: [ 'usb-role-switch' ]
port: [ 'usb-role-switch' ]
role-switch-default-mode: [ 'usb-role-switch' ]
wakeup-source: [ 'mediatek,syscon-wakeup' ]
required:
@@ -230,7 +252,7 @@ examples:
};
};
# Enable/disable device by an input gpio for VBUS pin
# Dual role switch by gpio-usb-b-connector
- |
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/power/mt2712-power.h>
@@ -244,13 +266,27 @@ examples:
power-domains = <&scpsys MT2712_POWER_DOMAIN_USB2>;
clocks = <&topckgen CLK_TOP_USB30_SEL>;
clock-names = "sys_ck";
dr_mode = "peripheral";
dr_mode = "otg";
usb-role-switch;
#address-cells = <1>;
#size-cells = <1>;
ranges;
host0: usb@11270000 {
compatible = "mediatek,mt2712-xhci", "mediatek,mtk-xhci";
reg = <0x11270000 0x1000>;
reg-names = "mac";
interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_LOW>;
power-domains = <&scpsys MT2712_POWER_DOMAIN_USB>;
clocks = <&topckgen CLK_TOP_USB30_SEL>, <&clk26m>;
clock-names = "sys_ck", "ref_ck";
};
connector {
compatible = "gpio-usb-b-connector", "usb-b-connector";
type = "micro";
vbus-gpios = <&pio 13 GPIO_ACTIVE_HIGH>;
id-gpios = <&pio 12 GPIO_ACTIVE_HIGH>;
vbus-supply = <&usb_p0_vbus>;
};
};
@@ -268,6 +304,7 @@ examples:
wakeup-source;
dr_mode = "otg";
usb-role-switch;
role-switch-default-mode = "host";
#address-cells = <1>;
#size-cells = <1>;
ranges;
@@ -19,6 +19,7 @@ properties:
- enum:
- mediatek,mt8516-musb
- mediatek,mt2701-musb
- mediatek,mt7623-musb
- const: mediatek,mtk-musb
reg:
@@ -17,6 +17,7 @@ properties:
- qcom,msm8998-dwc3
- qcom,sc7180-dwc3
- qcom,sc7280-dwc3
- qcom,sdm660-dwc3
- qcom,sdm845-dwc3
- qcom,sdx55-dwc3
- qcom,sm4250-dwc3
@@ -17,7 +17,9 @@ properties:
- const: renesas,rza1-usbhs
- items:
- const: renesas,usbhs-r7s9210 # RZ/A2
- enum:
- renesas,usbhs-r7s9210 # RZ/A2
- renesas,usbhs-r9a07g044 # RZ/G2{L,LC}
- const: renesas,rza2-usbhs
- items:
@@ -59,7 +61,8 @@ properties:
- description: USB 2.0 clock selector
interrupts:
maxItems: 1
minItems: 1
maxItems: 4
renesas,buswait:
$ref: /schemas/types.yaml#/definitions/uint32
@@ -108,6 +111,25 @@ required:
- clocks
- interrupts
allOf:
- if:
properties:
compatible:
contains:
const: renesas,usbhs-r9a07g044
then:
properties:
interrupts:
items:
- description: U2P_IXL_INT
- description: U2P_INT_DMA[0]
- description: U2P_INT_DMA[1]
- description: U2P_INT_DMAERR
else:
properties:
interrupts:
maxItems: 1
additionalProperties: false
examples:
@@ -289,10 +289,21 @@ properties:
maximum: 16
tx-fifo-resize:
description: Determines if the FIFO *has* to be reallocated
deprecated: true
description: Determines if the TX fifos can be dynamically resized depending
on the number of IN endpoints used and if bursting is supported. This
may help improve bandwidth on platforms with higher system latencies, as
increased fifo space allows for the controller to prefetch data into its
internal memory.
type: boolean
tx-fifo-max-num:
description: Specifies the max number of packets the txfifo resizing logic
can account for when higher endpoint bursting is used. (bMaxBurst > 6) The
higher the number, the more fifo space the txfifo resizing logic will
allocate for that endpoint.
$ref: /schemas/types.yaml#/definitions/uint8
minimum: 3
snps,incr-burst-type-adjustment:
description:
Value for INCR burst type of GSBUSCFG0 register, undefined length INCR
+42 -22
View File
@@ -724,18 +724,28 @@ Function-specific configfs interface
The function name to use when creating the function directory is "uac2".
The uac2 function provides these attributes in its function directory:
=============== ====================================================
c_chmask capture channel mask
c_srate capture sampling rate
c_ssize capture sample size (bytes)
c_sync capture synchronization type (async/adaptive)
fb_max maximum extra bandwidth in async mode
p_chmask playback channel mask
p_srate playback sampling rate
p_ssize playback sample size (bytes)
req_number the number of pre-allocated request for both capture
and playback
=============== ====================================================
================ ====================================================
c_chmask capture channel mask
c_srate capture sampling rate
c_ssize capture sample size (bytes)
c_sync capture synchronization type (async/adaptive)
c_mute_present capture mute control enable
c_volume_present capture volume control enable
c_volume_min capture volume control min value (in 1/256 dB)
c_volume_max capture volume control max value (in 1/256 dB)
c_volume_res capture volume control resolution (in 1/256 dB)
fb_max maximum extra bandwidth in async mode
p_chmask playback channel mask
p_srate playback sampling rate
p_ssize playback sample size (bytes)
p_mute_present playback mute control enable
p_volume_present playback volume control enable
p_volume_min playback volume control min value (in 1/256 dB)
p_volume_max playback volume control max value (in 1/256 dB)
p_volume_res playback volume control resolution (in 1/256 dB)
req_number the number of pre-allocated request for both capture
and playback
================ ====================================================
The attributes have sane default values.
@@ -904,16 +914,26 @@ Function-specific configfs interface
The function name to use when creating the function directory is "uac1".
The uac1 function provides these attributes in its function directory:
========== ====================================================
c_chmask capture channel mask
c_srate capture sampling rate
c_ssize capture sample size (bytes)
p_chmask playback channel mask
p_srate playback sampling rate
p_ssize playback sample size (bytes)
req_number the number of pre-allocated request for both capture
and playback
========== ====================================================
================ ====================================================
c_chmask capture channel mask
c_srate capture sampling rate
c_ssize capture sample size (bytes)
c_mute_present capture mute control enable
c_volume_present capture volume control enable
c_volume_min capture volume control min value (in 1/256 dB)
c_volume_max capture volume control max value (in 1/256 dB)
c_volume_res capture volume control resolution (in 1/256 dB)
p_chmask playback channel mask
p_srate playback sampling rate
p_ssize playback sample size (bytes)
p_mute_present playback mute control enable
p_volume_present playback volume control enable
p_volume_min playback volume control min value (in 1/256 dB)
p_volume_max playback volume control max value (in 1/256 dB)
p_volume_res playback volume control resolution (in 1/256 dB)
req_number the number of pre-allocated request for both capture
and playback
================ ====================================================
The attributes have sane default values.
+27 -4
View File
@@ -459,6 +459,12 @@ S: Maintained
W: https://parisc.wiki.kernel.org/index.php/AD1889
F: sound/pci/ad1889.*
AD5110 ANALOG DEVICES DIGITAL POTENTIOMETERS DRIVER
M: Mugilraj Dhavachelvan <dmugil2000@gmail.com>
L: linux-iio@vger.kernel.org
S: Supported
F: drivers/iio/potentiometer/ad5110.c
AD525X ANALOG DEVICES DIGITAL POTENTIOMETERS DRIVER
M: Michael Hennerich <michael.hennerich@analog.com>
S: Supported
@@ -8462,10 +8468,12 @@ S: Maintained
F: Documentation/devicetree/bindings/spmi/hisilicon,hisi-spmi-controller.yaml
F: drivers/spmi/hisi-spmi-controller.c
HISILICON STAGING DRIVERS FOR HIKEY 960/970
HISILICON SPMI PMIC DRIVER FOR HIKEY 6421v600
M: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
L: linux-kernel@vger.kernel.org
S: Maintained
F: drivers/staging/hikey9xx/
F: Documentation/devicetree/bindings/mfd/hisilicon,hi6421-spmi-pmic.yaml
F: drivers/mfd/hi6421-spmi-pmic.c
HISILICON TRUE RANDOM NUMBER GENERATOR V2 SUPPORT
M: Zaibo Xu <xuzaibo@huawei.com>
@@ -15912,6 +15920,14 @@ L: linux-renesas-soc@vger.kernel.org
S: Maintained
F: drivers/phy/renesas/phy-rcar-gen3-usb*.c
RENESAS RZ/G2L A/D DRIVER
M: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
L: linux-iio@vger.kernel.org
L: linux-renesas-soc@vger.kernel.org
S: Supported
F: Documentation/devicetree/bindings/iio/adc/renesas,rzg2l-adc.yaml
F: drivers/iio/adc/rzg2l_adc.c
RESET CONTROLLER FRAMEWORK
M: Philipp Zabel <p.zabel@pengutronix.de>
S: Maintained
@@ -16779,6 +16795,12 @@ F: drivers/iio/chemical/scd30_core.c
F: drivers/iio/chemical/scd30_i2c.c
F: drivers/iio/chemical/scd30_serial.c
SENSIRION SGP40 GAS SENSOR DRIVER
M: Andreas Klinger <ak@it-klinger.de>
S: Maintained
F: Documentation/ABI/testing/sysfs-bus-iio-chemical-sgp40
F: drivers/iio/chemical/sgp40.c
SENSIRION SPS30 AIR POLLUTION SENSOR DRIVER
M: Tomasz Duszynski <tduszyns@gmail.com>
S: Maintained
@@ -17683,8 +17705,9 @@ F: drivers/staging/olpc_dcon/
STAGING - REALTEK RTL8188EU DRIVERS
M: Larry Finger <Larry.Finger@lwfinger.net>
S: Odd Fixes
F: drivers/staging/rtl8188eu/
M: Phillip Potter <phil@philpotter.co.uk>
S: Supported
F: drivers/staging/r8188eu/
STAGING - REALTEK RTL8712U DRIVERS
M: Larry Finger <Larry.Finger@lwfinger.net>
+4 -4
View File
@@ -204,9 +204,9 @@ srmcons_init(void)
struct tty_driver *driver;
int err;
driver = alloc_tty_driver(MAX_SRM_CONSOLE_DEVICES);
if (!driver)
return -ENOMEM;
driver = tty_alloc_driver(MAX_SRM_CONSOLE_DEVICES, 0);
if (IS_ERR(driver))
return PTR_ERR(driver);
tty_port_init(&srmcons_singleton.port);
@@ -221,7 +221,7 @@ srmcons_init(void)
tty_port_link_device(&srmcons_singleton.port, driver, 0);
err = tty_register_driver(driver);
if (err) {
put_tty_driver(driver);
tty_driver_kref_put(driver);
tty_port_destroy(&srmcons_singleton.port);
return err;
}
+39
View File
@@ -276,6 +276,45 @@
status = "okay";
};
&usb_1 {
status = "okay";
};
&usb_1_dwc3 {
dr_mode = "host";
};
&usb_1_hsphy {
status = "okay";
vdda-pll-supply = <&vreg_l10c_0p8>;
vdda33-supply = <&vreg_l2b_3p0>;
vdda18-supply = <&vreg_l1c_1p8>;
};
&usb_1_qmpphy {
status = "okay";
vdda-phy-supply = <&vreg_l6b_1p2>;
vdda-pll-supply = <&vreg_l1b_0p8>;
};
&usb_2 {
status = "okay";
};
&usb_2_dwc3 {
dr_mode = "peripheral";
};
&usb_2_hsphy {
status = "okay";
vdda-pll-supply = <&vreg_l10c_0p8>;
vdda33-supply = <&vreg_l2b_3p0>;
vdda18-supply = <&vreg_l1c_1p8>;
};
/* PINCTRL - additions to nodes defined in sc7280.dtsi */
&qup_uart5_default {
+164
View File
@@ -1035,6 +1035,125 @@
};
};
usb_1_hsphy: phy@88e3000 {
compatible = "qcom,sc7280-usb-hs-phy",
"qcom,usb-snps-hs-7nm-phy";
reg = <0 0x088e3000 0 0x400>;
status = "disabled";
#phy-cells = <0>;
clocks = <&rpmhcc RPMH_CXO_CLK>;
clock-names = "ref";
resets = <&gcc GCC_QUSB2PHY_PRIM_BCR>;
};
usb_2_hsphy: phy@88e4000 {
compatible = "qcom,sc7280-usb-hs-phy",
"qcom,usb-snps-hs-7nm-phy";
reg = <0 0x088e4000 0 0x400>;
status = "disabled";
#phy-cells = <0>;
clocks = <&rpmhcc RPMH_CXO_CLK>;
clock-names = "ref";
resets = <&gcc GCC_QUSB2PHY_SEC_BCR>;
};
usb_1_qmpphy: phy-wrapper@88e9000 {
compatible = "qcom,sc7280-qmp-usb3-dp-phy",
"qcom,sm8250-qmp-usb3-dp-phy";
reg = <0 0x088e9000 0 0x200>,
<0 0x088e8000 0 0x40>,
<0 0x088ea000 0 0x200>;
status = "disabled";
#address-cells = <2>;
#size-cells = <2>;
ranges;
clocks = <&gcc GCC_USB3_PRIM_PHY_AUX_CLK>,
<&rpmhcc RPMH_CXO_CLK>,
<&gcc GCC_USB3_PRIM_PHY_COM_AUX_CLK>;
clock-names = "aux", "ref_clk_src", "com_aux";
resets = <&gcc GCC_USB3_DP_PHY_PRIM_BCR>,
<&gcc GCC_USB3_PHY_PRIM_BCR>;
reset-names = "phy", "common";
usb_1_ssphy: usb3-phy@88e9200 {
reg = <0 0x088e9200 0 0x200>,
<0 0x088e9400 0 0x200>,
<0 0x088e9c00 0 0x400>,
<0 0x088e9600 0 0x200>,
<0 0x088e9800 0 0x200>,
<0 0x088e9a00 0 0x100>;
#clock-cells = <0>;
#phy-cells = <0>;
clocks = <&gcc GCC_USB3_PRIM_PHY_PIPE_CLK>;
clock-names = "pipe0";
clock-output-names = "usb3_phy_pipe_clk_src";
};
dp_phy: dp-phy@88ea200 {
reg = <0 0x088ea200 0 0x200>,
<0 0x088ea400 0 0x200>,
<0 0x088eac00 0 0x400>,
<0 0x088ea600 0 0x200>,
<0 0x088ea800 0 0x200>,
<0 0x088eaa00 0 0x100>;
#phy-cells = <0>;
#clock-cells = <1>;
clocks = <&gcc GCC_USB3_PRIM_PHY_PIPE_CLK>;
clock-names = "pipe0";
clock-output-names = "usb3_phy_pipe_clk_src";
};
};
usb_2: usb@8cf8800 {
compatible = "qcom,sc7280-dwc3", "qcom,dwc3";
reg = <0 0x08cf8800 0 0x400>;
status = "disabled";
#address-cells = <2>;
#size-cells = <2>;
ranges;
dma-ranges;
clocks = <&gcc GCC_CFG_NOC_USB3_SEC_AXI_CLK>,
<&gcc GCC_USB30_SEC_MASTER_CLK>,
<&gcc GCC_AGGRE_USB3_SEC_AXI_CLK>,
<&gcc GCC_USB30_SEC_MOCK_UTMI_CLK>,
<&gcc GCC_USB30_SEC_SLEEP_CLK>;
clock-names = "cfg_noc", "core", "iface","mock_utmi",
"sleep";
assigned-clocks = <&gcc GCC_USB30_SEC_MOCK_UTMI_CLK>,
<&gcc GCC_USB30_SEC_MASTER_CLK>;
assigned-clock-rates = <19200000>, <200000000>;
interrupts-extended = <&intc GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
<&pdc 13 IRQ_TYPE_EDGE_RISING>,
<&pdc 12 IRQ_TYPE_EDGE_RISING>;
interrupt-names = "hs_phy_irq",
"dm_hs_phy_irq", "dp_hs_phy_irq";
power-domains = <&gcc GCC_USB30_SEC_GDSC>;
resets = <&gcc GCC_USB30_SEC_BCR>;
usb_2_dwc3: usb@8c00000 {
compatible = "snps,dwc3";
reg = <0 0x08c00000 0 0xe000>;
interrupts = <GIC_SPI 242 IRQ_TYPE_LEVEL_HIGH>;
iommus = <&apps_smmu 0xa0 0x0>;
snps,dis_u2_susphy_quirk;
snps,dis_enblslpm_quirk;
phys = <&usb_2_hsphy>;
phy-names = "usb2-phy";
maximum-speed = "high-speed";
};
};
dc_noc: interconnect@90e0000 {
reg = <0 0x090e0000 0 0x5080>;
compatible = "qcom,sc7280-dc-noc";
@@ -1063,6 +1182,51 @@
qcom,bcm-voters = <&apps_bcm_voter>;
};
usb_1: usb@a6f8800 {
compatible = "qcom,sc7280-dwc3", "qcom,dwc3";
reg = <0 0x0a6f8800 0 0x400>;
status = "disabled";
#address-cells = <2>;
#size-cells = <2>;
ranges;
dma-ranges;
clocks = <&gcc GCC_CFG_NOC_USB3_PRIM_AXI_CLK>,
<&gcc GCC_USB30_PRIM_MASTER_CLK>,
<&gcc GCC_AGGRE_USB3_PRIM_AXI_CLK>,
<&gcc GCC_USB30_PRIM_MOCK_UTMI_CLK>,
<&gcc GCC_USB30_PRIM_SLEEP_CLK>;
clock-names = "cfg_noc", "core", "iface", "mock_utmi",
"sleep";
assigned-clocks = <&gcc GCC_USB30_PRIM_MOCK_UTMI_CLK>,
<&gcc GCC_USB30_PRIM_MASTER_CLK>;
assigned-clock-rates = <19200000>, <200000000>;
interrupts-extended = <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
<&pdc 14 IRQ_TYPE_EDGE_BOTH>,
<&pdc 15 IRQ_TYPE_EDGE_BOTH>,
<&pdc 17 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "hs_phy_irq", "dp_hs_phy_irq",
"dm_hs_phy_irq", "ss_phy_irq";
power-domains = <&gcc GCC_USB30_PRIM_GDSC>;
resets = <&gcc GCC_USB30_PRIM_BCR>;
usb_1_dwc3: usb@a600000 {
compatible = "snps,dwc3";
reg = <0 0x0a600000 0 0xe000>;
interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
iommus = <&apps_smmu 0xe0 0x0>;
snps,dis_u2_susphy_quirk;
snps,dis_enblslpm_quirk;
phys = <&usb_1_hsphy>, <&usb_1_ssphy>;
phy-names = "usb2-phy", "usb3-phy";
maximum-speed = "super-speed";
};
};
videocc: clock-controller@aaf0000 {
compatible = "qcom,sc7280-videocc";
reg = <0 0xaaf0000 0 0x10000>;
+16 -14
View File
@@ -120,35 +120,37 @@ early_param("debug", nf_debug_setup);
static int __init nfcon_init(void)
{
struct tty_driver *driver;
int res;
stderr_id = nf_get_id("NF_STDERR");
if (!stderr_id)
return -ENODEV;
nfcon_tty_driver = alloc_tty_driver(1);
if (!nfcon_tty_driver)
return -ENOMEM;
driver = tty_alloc_driver(1, TTY_DRIVER_REAL_RAW);
if (IS_ERR(driver))
return PTR_ERR(driver);
tty_port_init(&nfcon_tty_port);
nfcon_tty_driver->driver_name = "nfcon";
nfcon_tty_driver->name = "nfcon";
nfcon_tty_driver->type = TTY_DRIVER_TYPE_SYSTEM;
nfcon_tty_driver->subtype = SYSTEM_TYPE_TTY;
nfcon_tty_driver->init_termios = tty_std_termios;
nfcon_tty_driver->flags = TTY_DRIVER_REAL_RAW;
driver->driver_name = "nfcon";
driver->name = "nfcon";
driver->type = TTY_DRIVER_TYPE_SYSTEM;
driver->subtype = SYSTEM_TYPE_TTY;
driver->init_termios = tty_std_termios;
tty_set_operations(nfcon_tty_driver, &nfcon_tty_ops);
tty_port_link_device(&nfcon_tty_port, nfcon_tty_driver, 0);
res = tty_register_driver(nfcon_tty_driver);
tty_set_operations(driver, &nfcon_tty_ops);
tty_port_link_device(&nfcon_tty_port, driver, 0);
res = tty_register_driver(driver);
if (res) {
pr_err("failed to register nfcon tty driver\n");
put_tty_driver(nfcon_tty_driver);
tty_driver_kref_put(driver);
tty_port_destroy(&nfcon_tty_port);
return res;
}
nfcon_tty_driver = driver;
if (!(nf_console.flags & CON_ENABLED))
register_console(&nf_console);
@@ -159,7 +161,7 @@ static void __exit nfcon_exit(void)
{
unregister_console(&nf_console);
tty_unregister_driver(nfcon_tty_driver);
put_tty_driver(nfcon_tty_driver);
tty_driver_kref_put(nfcon_tty_driver);
tty_port_destroy(&nfcon_tty_port);
}
+17 -15
View File
@@ -138,6 +138,7 @@ static struct tty_driver *pdc_console_tty_driver;
static int __init pdc_console_tty_driver_init(void)
{
struct tty_driver *driver;
int err;
/* Check if the console driver is still registered.
@@ -160,31 +161,32 @@ static int __init pdc_console_tty_driver_init(void)
printk(KERN_INFO "The PDC console driver is still registered, removing CON_BOOT flag\n");
pdc_cons.flags &= ~CON_BOOT;
pdc_console_tty_driver = alloc_tty_driver(1);
if (!pdc_console_tty_driver)
return -ENOMEM;
driver = tty_alloc_driver(1, TTY_DRIVER_REAL_RAW |
TTY_DRIVER_RESET_TERMIOS);
if (IS_ERR(driver))
return PTR_ERR(driver);
tty_port_init(&tty_port);
pdc_console_tty_driver->driver_name = "pdc_cons";
pdc_console_tty_driver->name = "ttyB";
pdc_console_tty_driver->major = MUX_MAJOR;
pdc_console_tty_driver->minor_start = 0;
pdc_console_tty_driver->type = TTY_DRIVER_TYPE_SYSTEM;
pdc_console_tty_driver->init_termios = tty_std_termios;
pdc_console_tty_driver->flags = TTY_DRIVER_REAL_RAW |
TTY_DRIVER_RESET_TERMIOS;
tty_set_operations(pdc_console_tty_driver, &pdc_console_tty_ops);
tty_port_link_device(&tty_port, pdc_console_tty_driver, 0);
driver->driver_name = "pdc_cons";
driver->name = "ttyB";
driver->major = MUX_MAJOR;
driver->minor_start = 0;
driver->type = TTY_DRIVER_TYPE_SYSTEM;
driver->init_termios = tty_std_termios;
tty_set_operations(driver, &pdc_console_tty_ops);
tty_port_link_device(&tty_port, driver, 0);
err = tty_register_driver(pdc_console_tty_driver);
err = tty_register_driver(driver);
if (err) {
printk(KERN_ERR "Unable to register the PDC console TTY driver\n");
tty_port_destroy(&tty_port);
tty_driver_kref_put(driver);
return err;
}
pdc_console_tty_driver = driver;
return 0;
}
device_initcall(pdc_console_tty_driver_init);
+7 -6
View File
@@ -538,12 +538,14 @@ int register_lines(struct line_driver *line_driver,
const struct tty_operations *ops,
struct line *lines, int nlines)
{
struct tty_driver *driver = alloc_tty_driver(nlines);
struct tty_driver *driver;
int err;
int i;
if (!driver)
return -ENOMEM;
driver = tty_alloc_driver(nlines, TTY_DRIVER_REAL_RAW |
TTY_DRIVER_DYNAMIC_DEV);
if (IS_ERR(driver))
return PTR_ERR(driver);
driver->driver_name = line_driver->name;
driver->name = line_driver->device_name;
@@ -551,9 +553,8 @@ int register_lines(struct line_driver *line_driver,
driver->minor_start = line_driver->minor_start;
driver->type = line_driver->type;
driver->subtype = line_driver->subtype;
driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
driver->init_termios = tty_std_termios;
for (i = 0; i < nlines; i++) {
tty_port_init(&lines[i].port);
lines[i].port.ops = &line_port_ops;
@@ -567,7 +568,7 @@ int register_lines(struct line_driver *line_driver,
if (err) {
printk(KERN_ERR "register_lines : can't register %s driver\n",
line_driver->name);
put_tty_driver(driver);
tty_driver_kref_put(driver);
for (i = 0; i < nlines; i++)
tty_port_destroy(&lines[i].port);
return err;
+29 -16
View File
@@ -136,28 +136,41 @@ static const struct tty_operations serial_ops = {
static int __init rs_init(void)
{
tty_port_init(&serial_port);
struct tty_driver *driver;
int ret;
serial_driver = alloc_tty_driver(SERIAL_MAX_NUM_LINES);
driver = tty_alloc_driver(SERIAL_MAX_NUM_LINES, TTY_DRIVER_REAL_RAW);
if (IS_ERR(driver))
return PTR_ERR(driver);
tty_port_init(&serial_port);
/* Initialize the tty_driver structure */
serial_driver->driver_name = "iss_serial";
serial_driver->name = "ttyS";
serial_driver->major = TTY_MAJOR;
serial_driver->minor_start = 64;
serial_driver->type = TTY_DRIVER_TYPE_SERIAL;
serial_driver->subtype = SERIAL_TYPE_NORMAL;
serial_driver->init_termios = tty_std_termios;
serial_driver->init_termios.c_cflag =
driver->driver_name = "iss_serial";
driver->name = "ttyS";
driver->major = TTY_MAJOR;
driver->minor_start = 64;
driver->type = TTY_DRIVER_TYPE_SERIAL;
driver->subtype = SERIAL_TYPE_NORMAL;
driver->init_termios = tty_std_termios;
driver->init_termios.c_cflag =
B9600 | CS8 | CREAD | HUPCL | CLOCAL;
serial_driver->flags = TTY_DRIVER_REAL_RAW;
tty_set_operations(serial_driver, &serial_ops);
tty_port_link_device(&serial_port, serial_driver, 0);
tty_set_operations(driver, &serial_ops);
tty_port_link_device(&serial_port, driver, 0);
ret = tty_register_driver(driver);
if (ret) {
pr_err("Couldn't register serial driver\n");
tty_driver_kref_put(driver);
tty_port_destroy(&serial_port);
return ret;
}
serial_driver = driver;
if (tty_register_driver(serial_driver))
panic("Couldn't register serial driver\n");
return 0;
}
@@ -165,7 +178,7 @@ static int __init rs_init(void)
static __exit void rs_exit(void)
{
tty_unregister_driver(serial_driver);
put_tty_driver(serial_driver);
tty_driver_kref_put(serial_driver);
tty_port_destroy(&serial_port);
}
+2 -2
View File
@@ -2841,7 +2841,7 @@ static int __init synclink_cs_init(void)
err_unreg_tty:
tty_unregister_driver(serial_driver);
err_put_tty:
put_tty_driver(serial_driver);
tty_driver_kref_put(serial_driver);
err:
return rc;
}
@@ -2850,7 +2850,7 @@ static void __exit synclink_cs_exit(void)
{
pcmcia_unregister_driver(&mgslpc_driver);
tty_unregister_driver(serial_driver);
put_tty_driver(serial_driver);
tty_driver_kref_put(serial_driver);
}
module_init(synclink_cs_init);
+2 -2
View File
@@ -198,7 +198,7 @@ static int __init ttyprintk_init(void)
return 0;
error:
put_tty_driver(ttyprintk_driver);
tty_driver_kref_put(ttyprintk_driver);
tty_port_destroy(&tpk_port.port);
return ret;
}
@@ -206,7 +206,7 @@ error:
static void __exit ttyprintk_exit(void)
{
tty_unregister_driver(ttyprintk_driver);
put_tty_driver(ttyprintk_driver);
tty_driver_kref_put(ttyprintk_driver);
tty_port_destroy(&tpk_port.port);
}
+29 -18
View File
@@ -28,6 +28,7 @@ MODULE_PARM_DESC(base, "ACCES 104-QUAD-8 base addresses");
/**
* struct quad8 - device private data structure
* @lock: lock to prevent clobbering device states during R/W ops
* @counter: instance of the counter_device
* @fck_prescaler: array of filter clock prescaler configurations
* @preset: array of preset values
@@ -97,7 +98,8 @@ struct quad8 {
#define QUAD8_CMR_QUADRATURE_X4 0x18
static int quad8_signal_read(struct counter_device *counter,
struct counter_signal *signal, enum counter_signal_value *val)
struct counter_signal *signal,
enum counter_signal_level *level)
{
const struct quad8 *const priv = counter->priv;
unsigned int state;
@@ -109,7 +111,7 @@ static int quad8_signal_read(struct counter_device *counter,
state = inb(priv->base + QUAD8_REG_INDEX_INPUT_LEVELS)
& BIT(signal->id - 16);
*val = (state) ? COUNTER_SIGNAL_HIGH : COUNTER_SIGNAL_LOW;
*level = (state) ? COUNTER_SIGNAL_LEVEL_HIGH : COUNTER_SIGNAL_LEVEL_LOW;
return 0;
}
@@ -154,7 +156,7 @@ static int quad8_count_write(struct counter_device *counter,
/* Only 24-bit values are supported */
if (val > 0xFFFFFF)
return -EINVAL;
return -ERANGE;
mutex_lock(&priv->lock);
@@ -193,11 +195,11 @@ enum quad8_count_function {
QUAD8_COUNT_FUNCTION_QUADRATURE_X4
};
static const enum counter_count_function quad8_count_functions_list[] = {
[QUAD8_COUNT_FUNCTION_PULSE_DIRECTION] = COUNTER_COUNT_FUNCTION_PULSE_DIRECTION,
[QUAD8_COUNT_FUNCTION_QUADRATURE_X1] = COUNTER_COUNT_FUNCTION_QUADRATURE_X1_A,
[QUAD8_COUNT_FUNCTION_QUADRATURE_X2] = COUNTER_COUNT_FUNCTION_QUADRATURE_X2_A,
[QUAD8_COUNT_FUNCTION_QUADRATURE_X4] = COUNTER_COUNT_FUNCTION_QUADRATURE_X4
static const enum counter_function quad8_count_functions_list[] = {
[QUAD8_COUNT_FUNCTION_PULSE_DIRECTION] = COUNTER_FUNCTION_PULSE_DIRECTION,
[QUAD8_COUNT_FUNCTION_QUADRATURE_X1] = COUNTER_FUNCTION_QUADRATURE_X1_A,
[QUAD8_COUNT_FUNCTION_QUADRATURE_X2] = COUNTER_FUNCTION_QUADRATURE_X2_A,
[QUAD8_COUNT_FUNCTION_QUADRATURE_X4] = COUNTER_FUNCTION_QUADRATURE_X4
};
static int quad8_function_get(struct counter_device *counter,
@@ -273,6 +275,10 @@ static int quad8_function_set(struct counter_device *counter,
*scale = 2;
mode_cfg |= QUAD8_CMR_QUADRATURE_X4;
break;
default:
/* should never reach this path */
mutex_unlock(&priv->lock);
return -EINVAL;
}
}
@@ -349,7 +355,7 @@ static int quad8_action_get(struct counter_device *counter,
case QUAD8_COUNT_FUNCTION_PULSE_DIRECTION:
if (synapse->signal->id == signal_a_id)
*action = QUAD8_SYNAPSE_ACTION_RISING_EDGE;
break;
return 0;
case QUAD8_COUNT_FUNCTION_QUADRATURE_X1:
if (synapse->signal->id == signal_a_id) {
quad8_direction_get(counter, count, &direction);
@@ -359,17 +365,18 @@ static int quad8_action_get(struct counter_device *counter,
else
*action = QUAD8_SYNAPSE_ACTION_FALLING_EDGE;
}
break;
return 0;
case QUAD8_COUNT_FUNCTION_QUADRATURE_X2:
if (synapse->signal->id == signal_a_id)
*action = QUAD8_SYNAPSE_ACTION_BOTH_EDGES;
break;
return 0;
case QUAD8_COUNT_FUNCTION_QUADRATURE_X4:
*action = QUAD8_SYNAPSE_ACTION_BOTH_EDGES;
break;
return 0;
default:
/* should never reach this path */
return -EINVAL;
}
return 0;
}
static const struct counter_ops quad8_ops = {
@@ -529,6 +536,9 @@ static int quad8_count_mode_set(struct counter_device *counter,
case COUNTER_COUNT_MODE_MODULO_N:
cnt_mode = 3;
break;
default:
/* should never reach this path */
return -EINVAL;
}
mutex_lock(&priv->lock);
@@ -661,7 +671,7 @@ static ssize_t quad8_count_preset_write(struct counter_device *counter,
/* Only 24-bit values are supported */
if (preset > 0xFFFFFF)
return -EINVAL;
return -ERANGE;
mutex_lock(&priv->lock);
@@ -706,7 +716,7 @@ static ssize_t quad8_count_ceiling_write(struct counter_device *counter,
/* Only 24-bit values are supported */
if (ceiling > 0xFFFFFF)
return -EINVAL;
return -ERANGE;
mutex_lock(&priv->lock);
@@ -715,12 +725,13 @@ static ssize_t quad8_count_ceiling_write(struct counter_device *counter,
case 1:
case 3:
quad8_preset_register_set(priv, count->id, ceiling);
break;
mutex_unlock(&priv->lock);
return len;
}
mutex_unlock(&priv->lock);
return len;
return -EINVAL;
}
static ssize_t quad8_count_preset_enable_read(struct counter_device *counter,
+25 -25
View File
@@ -289,9 +289,9 @@ struct counter_signal_unit {
struct counter_signal *signal;
};
static const char *const counter_signal_value_str[] = {
[COUNTER_SIGNAL_LOW] = "low",
[COUNTER_SIGNAL_HIGH] = "high"
static const char *const counter_signal_level_str[] = {
[COUNTER_SIGNAL_LEVEL_LOW] = "low",
[COUNTER_SIGNAL_LEVEL_HIGH] = "high"
};
static ssize_t counter_signal_show(struct device *dev,
@@ -302,13 +302,13 @@ static ssize_t counter_signal_show(struct device *dev,
const struct counter_signal_unit *const component = devattr->component;
struct counter_signal *const signal = component->signal;
int err;
enum counter_signal_value val;
enum counter_signal_level level;
err = counter->ops->signal_read(counter, signal, &val);
err = counter->ops->signal_read(counter, signal, &level);
if (err)
return err;
return sprintf(buf, "%s\n", counter_signal_value_str[val]);
return sprintf(buf, "%s\n", counter_signal_level_str[level]);
}
struct counter_name_unit {
@@ -744,15 +744,15 @@ static ssize_t counter_count_store(struct device *dev,
return len;
}
static const char *const counter_count_function_str[] = {
[COUNTER_COUNT_FUNCTION_INCREASE] = "increase",
[COUNTER_COUNT_FUNCTION_DECREASE] = "decrease",
[COUNTER_COUNT_FUNCTION_PULSE_DIRECTION] = "pulse-direction",
[COUNTER_COUNT_FUNCTION_QUADRATURE_X1_A] = "quadrature x1 a",
[COUNTER_COUNT_FUNCTION_QUADRATURE_X1_B] = "quadrature x1 b",
[COUNTER_COUNT_FUNCTION_QUADRATURE_X2_A] = "quadrature x2 a",
[COUNTER_COUNT_FUNCTION_QUADRATURE_X2_B] = "quadrature x2 b",
[COUNTER_COUNT_FUNCTION_QUADRATURE_X4] = "quadrature x4"
static const char *const counter_function_str[] = {
[COUNTER_FUNCTION_INCREASE] = "increase",
[COUNTER_FUNCTION_DECREASE] = "decrease",
[COUNTER_FUNCTION_PULSE_DIRECTION] = "pulse-direction",
[COUNTER_FUNCTION_QUADRATURE_X1_A] = "quadrature x1 a",
[COUNTER_FUNCTION_QUADRATURE_X1_B] = "quadrature x1 b",
[COUNTER_FUNCTION_QUADRATURE_X2_A] = "quadrature x2 a",
[COUNTER_FUNCTION_QUADRATURE_X2_B] = "quadrature x2 b",
[COUNTER_FUNCTION_QUADRATURE_X4] = "quadrature x4"
};
static ssize_t counter_function_show(struct device *dev,
@@ -764,7 +764,7 @@ static ssize_t counter_function_show(struct device *dev,
const struct counter_count_unit *const component = devattr->component;
struct counter_count *const count = component->count;
size_t func_index;
enum counter_count_function function;
enum counter_function function;
err = counter->ops->function_get(counter, count, &func_index);
if (err)
@@ -773,7 +773,7 @@ static ssize_t counter_function_show(struct device *dev,
count->function = func_index;
function = count->functions_list[func_index];
return sprintf(buf, "%s\n", counter_count_function_str[function]);
return sprintf(buf, "%s\n", counter_function_str[function]);
}
static ssize_t counter_function_store(struct device *dev,
@@ -785,14 +785,14 @@ static ssize_t counter_function_store(struct device *dev,
struct counter_count *const count = component->count;
const size_t num_functions = count->num_functions;
size_t func_index;
enum counter_count_function function;
enum counter_function function;
int err;
struct counter_device *const counter = dev_get_drvdata(dev);
/* Find requested Count function mode */
for (func_index = 0; func_index < num_functions; func_index++) {
function = count->functions_list[func_index];
if (sysfs_streq(buf, counter_count_function_str[function]))
if (sysfs_streq(buf, counter_function_str[function]))
break;
}
/* Return error if requested Count function mode not found */
@@ -880,25 +880,25 @@ err_free_attr_list:
}
struct counter_func_avail_unit {
const enum counter_count_function *functions_list;
const enum counter_function *functions_list;
size_t num_functions;
};
static ssize_t counter_count_function_available_show(struct device *dev,
static ssize_t counter_function_available_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
const struct counter_device_attr *const devattr = to_counter_attr(attr);
const struct counter_func_avail_unit *const component = devattr->component;
const enum counter_count_function *const func_list = component->functions_list;
const enum counter_function *const func_list = component->functions_list;
const size_t num_functions = component->num_functions;
size_t i;
enum counter_count_function function;
enum counter_function function;
ssize_t len = 0;
for (i = 0; i < num_functions; i++) {
function = func_list[i];
len += sprintf(buf + len, "%s\n",
counter_count_function_str[function]);
counter_function_str[function]);
}
return len;
@@ -968,7 +968,7 @@ static int counter_count_attributes_create(
parm.group = group;
parm.prefix = "";
parm.name = "function_available";
parm.show = counter_count_function_available_show;
parm.show = counter_function_available_show;
parm.store = NULL;
parm.component = avail_comp;
err = counter_attribute_create(&parm);
+2 -3
View File
@@ -171,9 +171,8 @@ enum ftm_quaddec_count_function {
FTM_QUADDEC_COUNT_ENCODER_MODE_1,
};
static const enum counter_count_function ftm_quaddec_count_functions[] = {
[FTM_QUADDEC_COUNT_ENCODER_MODE_1] =
COUNTER_COUNT_FUNCTION_QUADRATURE_X4
static const enum counter_function ftm_quaddec_count_functions[] = {
[FTM_QUADDEC_COUNT_ENCODER_MODE_1] = COUNTER_FUNCTION_QUADRATURE_X4
};
static int ftm_quaddec_count_read(struct counter_device *counter,
+3 -4
View File
@@ -8,7 +8,6 @@
* Author: Jarkko Nikula <jarkko.nikula@linux.intel.com>
* Author: Raymond Tan <raymond.tan@intel.com>
*/
#include <linux/bitops.h>
#include <linux/counter.h>
#include <linux/kernel.h>
#include <linux/module.h>
@@ -127,8 +126,8 @@ static int intel_qep_count_read(struct counter_device *counter,
return 0;
}
static const enum counter_count_function intel_qep_count_functions[] = {
COUNTER_COUNT_FUNCTION_QUADRATURE_X4,
static const enum counter_function intel_qep_count_functions[] = {
COUNTER_FUNCTION_QUADRATURE_X4,
};
static int intel_qep_function_get(struct counter_device *counter,
@@ -320,7 +319,7 @@ static ssize_t spike_filter_ns_write(struct counter_device *counter,
}
if (length > INTEL_QEPFLT_MAX_COUNT(length))
return -EINVAL;
return -ERANGE;
mutex_lock(&qep->lock);
if (qep->enabled) {
+7 -4
View File
@@ -107,13 +107,16 @@ static int interrupt_cnt_write(struct counter_device *counter,
{
struct interrupt_cnt_priv *priv = counter->priv;
if (val != (typeof(priv->count.counter))val)
return -ERANGE;
atomic_set(&priv->count, val);
return 0;
}
static const enum counter_count_function interrupt_cnt_functions[] = {
COUNTER_COUNT_FUNCTION_INCREASE,
static const enum counter_function interrupt_cnt_functions[] = {
COUNTER_FUNCTION_INCREASE,
};
static int interrupt_cnt_function_get(struct counter_device *counter,
@@ -127,7 +130,7 @@ static int interrupt_cnt_function_get(struct counter_device *counter,
static int interrupt_cnt_signal_read(struct counter_device *counter,
struct counter_signal *signal,
enum counter_signal_value *val)
enum counter_signal_level *level)
{
struct interrupt_cnt_priv *priv = counter->priv;
int ret;
@@ -139,7 +142,7 @@ static int interrupt_cnt_signal_read(struct counter_device *counter,
if (ret < 0)
return ret;
*val = ret ? COUNTER_SIGNAL_HIGH : COUNTER_SIGNAL_LOW;
*level = ret ? COUNTER_SIGNAL_LEVEL_HIGH : COUNTER_SIGNAL_LEVEL_LOW;
return 0;
}
+11 -5
View File
@@ -37,9 +37,9 @@ enum mchp_tc_count_function {
MCHP_TC_FUNCTION_QUADRATURE,
};
static const enum counter_count_function mchp_tc_count_functions[] = {
[MCHP_TC_FUNCTION_INCREASE] = COUNTER_COUNT_FUNCTION_INCREASE,
[MCHP_TC_FUNCTION_QUADRATURE] = COUNTER_COUNT_FUNCTION_QUADRATURE_X4,
static const enum counter_function mchp_tc_count_functions[] = {
[MCHP_TC_FUNCTION_INCREASE] = COUNTER_FUNCTION_INCREASE,
[MCHP_TC_FUNCTION_QUADRATURE] = COUNTER_FUNCTION_QUADRATURE_X4,
};
enum mchp_tc_synapse_action {
@@ -133,6 +133,9 @@ static int mchp_tc_count_function_set(struct counter_device *counter,
bmr |= ATMEL_TC_QDEN | ATMEL_TC_POSEN;
cmr |= ATMEL_TC_ETRGEDG_RISING | ATMEL_TC_ABETRG | ATMEL_TC_XC0;
break;
default:
/* should never reach this path */
return -EINVAL;
}
regmap_write(priv->regmap, ATMEL_TC_BMR, bmr);
@@ -155,7 +158,7 @@ static int mchp_tc_count_function_set(struct counter_device *counter,
static int mchp_tc_count_signal_read(struct counter_device *counter,
struct counter_signal *signal,
enum counter_signal_value *val)
enum counter_signal_level *lvl)
{
struct mchp_tc_data *const priv = counter->priv;
bool sigstatus;
@@ -168,7 +171,7 @@ static int mchp_tc_count_signal_read(struct counter_device *counter,
else
sigstatus = (sr & ATMEL_TC_MTIOA);
*val = sigstatus ? COUNTER_SIGNAL_HIGH : COUNTER_SIGNAL_LOW;
*lvl = sigstatus ? COUNTER_SIGNAL_LEVEL_HIGH : COUNTER_SIGNAL_LEVEL_LOW;
return 0;
}
@@ -226,6 +229,9 @@ static int mchp_tc_count_action_set(struct counter_device *counter,
case MCHP_TC_SYNAPSE_ACTION_BOTH_EDGE:
edge = ATMEL_TC_ETRGEDG_BOTH;
break;
default:
/* should never reach this path */
return -EINVAL;
}
return regmap_write_bits(priv->regmap,
+10 -8
View File
@@ -134,9 +134,9 @@ enum stm32_lptim_cnt_function {
STM32_LPTIM_ENCODER_BOTH_EDGE,
};
static const enum counter_count_function stm32_lptim_cnt_functions[] = {
[STM32_LPTIM_COUNTER_INCREASE] = COUNTER_COUNT_FUNCTION_INCREASE,
[STM32_LPTIM_ENCODER_BOTH_EDGE] = COUNTER_COUNT_FUNCTION_QUADRATURE_X4,
static const enum counter_function stm32_lptim_cnt_functions[] = {
[STM32_LPTIM_COUNTER_INCREASE] = COUNTER_FUNCTION_INCREASE,
[STM32_LPTIM_ENCODER_BOTH_EDGE] = COUNTER_FUNCTION_QUADRATURE_X4,
};
enum stm32_lptim_synapse_action {
@@ -206,9 +206,10 @@ static int stm32_lptim_cnt_function_set(struct counter_device *counter,
priv->quadrature_mode = 1;
priv->polarity = STM32_LPTIM_SYNAPSE_ACTION_BOTH_EDGES;
return 0;
default:
/* should never reach this path */
return -EINVAL;
}
return -EINVAL;
}
static ssize_t stm32_lptim_cnt_enable_read(struct counter_device *counter,
@@ -282,7 +283,7 @@ static ssize_t stm32_lptim_cnt_ceiling_write(struct counter_device *counter,
return ret;
if (ceiling > STM32_LPTIM_MAX_ARR)
return -EINVAL;
return -ERANGE;
priv->ceiling = ceiling;
@@ -326,9 +327,10 @@ static int stm32_lptim_cnt_action_get(struct counter_device *counter,
case STM32_LPTIM_ENCODER_BOTH_EDGE:
*action = priv->polarity;
return 0;
default:
/* should never reach this path */
return -EINVAL;
}
return -EINVAL;
}
static int stm32_lptim_cnt_action_set(struct counter_device *counter,
+5 -5
View File
@@ -50,11 +50,11 @@ enum stm32_count_function {
STM32_COUNT_ENCODER_MODE_3,
};
static const enum counter_count_function stm32_count_functions[] = {
[STM32_COUNT_SLAVE_MODE_DISABLED] = COUNTER_COUNT_FUNCTION_INCREASE,
[STM32_COUNT_ENCODER_MODE_1] = COUNTER_COUNT_FUNCTION_QUADRATURE_X2_A,
[STM32_COUNT_ENCODER_MODE_2] = COUNTER_COUNT_FUNCTION_QUADRATURE_X2_B,
[STM32_COUNT_ENCODER_MODE_3] = COUNTER_COUNT_FUNCTION_QUADRATURE_X4,
static const enum counter_function stm32_count_functions[] = {
[STM32_COUNT_SLAVE_MODE_DISABLED] = COUNTER_FUNCTION_INCREASE,
[STM32_COUNT_ENCODER_MODE_1] = COUNTER_FUNCTION_QUADRATURE_X2_A,
[STM32_COUNT_ENCODER_MODE_2] = COUNTER_FUNCTION_QUADRATURE_X2_B,
[STM32_COUNT_ENCODER_MODE_3] = COUNTER_FUNCTION_QUADRATURE_X4,
};
static int stm32_count_read(struct counter_device *counter,
+21 -16
View File
@@ -157,7 +157,7 @@ static int ti_eqep_action_get(struct counter_device *counter,
* QEPA and QEPB trigger QCLK.
*/
*action = TI_EQEP_SYNAPSE_ACTION_BOTH_EDGES;
break;
return 0;
case TI_EQEP_COUNT_FUNC_DIR_COUNT:
/* In direction-count mode only rising edge of QEPA is counted
* and QEPB gives direction.
@@ -165,12 +165,14 @@ static int ti_eqep_action_get(struct counter_device *counter,
switch (synapse->signal->id) {
case TI_EQEP_SIGNAL_QEPA:
*action = TI_EQEP_SYNAPSE_ACTION_RISING_EDGE;
break;
default:
return 0;
case TI_EQEP_SIGNAL_QEPB:
*action = TI_EQEP_SYNAPSE_ACTION_NONE;
break;
return 0;
default:
/* should never reach this path */
return -EINVAL;
}
break;
case TI_EQEP_COUNT_FUNC_UP_COUNT:
case TI_EQEP_COUNT_FUNC_DOWN_COUNT:
/* In up/down-count modes only QEPA is counted and QEPB is not
@@ -186,15 +188,18 @@ static int ti_eqep_action_get(struct counter_device *counter,
*action = TI_EQEP_SYNAPSE_ACTION_BOTH_EDGES;
else
*action = TI_EQEP_SYNAPSE_ACTION_RISING_EDGE;
break;
default:
return 0;
case TI_EQEP_SIGNAL_QEPB:
*action = TI_EQEP_SYNAPSE_ACTION_NONE;
break;
return 0;
default:
/* should never reach this path */
return -EINVAL;
}
break;
default:
/* should never reach this path */
return -EINVAL;
}
return 0;
}
static const struct counter_ops ti_eqep_counter_ops = {
@@ -289,11 +294,11 @@ static struct counter_signal ti_eqep_signals[] = {
},
};
static const enum counter_count_function ti_eqep_position_functions[] = {
[TI_EQEP_COUNT_FUNC_QUAD_COUNT] = COUNTER_COUNT_FUNCTION_QUADRATURE_X4,
[TI_EQEP_COUNT_FUNC_DIR_COUNT] = COUNTER_COUNT_FUNCTION_PULSE_DIRECTION,
[TI_EQEP_COUNT_FUNC_UP_COUNT] = COUNTER_COUNT_FUNCTION_INCREASE,
[TI_EQEP_COUNT_FUNC_DOWN_COUNT] = COUNTER_COUNT_FUNCTION_DECREASE,
static const enum counter_function ti_eqep_position_functions[] = {
[TI_EQEP_COUNT_FUNC_QUAD_COUNT] = COUNTER_FUNCTION_QUADRATURE_X4,
[TI_EQEP_COUNT_FUNC_DIR_COUNT] = COUNTER_FUNCTION_PULSE_DIRECTION,
[TI_EQEP_COUNT_FUNC_UP_COUNT] = COUNTER_FUNCTION_INCREASE,
[TI_EQEP_COUNT_FUNC_DOWN_COUNT] = COUNTER_FUNCTION_DECREASE,
};
static const enum counter_synapse_action ti_eqep_position_synapse_actions[] = {
+3 -2
View File
@@ -143,10 +143,11 @@ config BMC150_ACCEL
select BMC150_ACCEL_SPI if SPI
help
Say yes here to build support for the following Bosch accelerometers:
BMA222, BMA222E, BMA250E, BMA253, BMA254, BMA255, BMA280, BMC150, BMI055.
BMA222, BMA222E, BMA250E, BMA253, BMA254, BMA255, BMA280, BMC150, BMC156
BMI055.
Note that some of these are combo modules:
- BMC150: accelerometer and magnetometer
- BMC150/BMC156: accelerometer and magnetometer
- BMI055: accelerometer and gyroscope
This driver is only implementing accelerometer part, which has
-1
View File
@@ -15,6 +15,5 @@ enum adxl345_device_type {
int adxl345_core_probe(struct device *dev, struct regmap *regmap,
enum adxl345_device_type type, const char *name);
int adxl345_core_remove(struct device *dev);
#endif /* _ADXL345_H_ */
+9 -20
View File
@@ -208,6 +208,11 @@ static const struct iio_info adxl345_info = {
.write_raw_get_fmt = adxl345_write_raw_get_fmt,
};
static void adxl345_powerdown(void *regmap)
{
regmap_write(regmap, ADXL345_REG_POWER_CTL, ADXL345_POWER_CTL_STANDBY);
}
int adxl345_core_probe(struct device *dev, struct regmap *regmap,
enum adxl345_device_type type, const char *name)
{
@@ -233,7 +238,6 @@ int adxl345_core_probe(struct device *dev, struct regmap *regmap,
return -ENOMEM;
data = iio_priv(indio_dev);
dev_set_drvdata(dev, indio_dev);
data->regmap = regmap;
data->type = type;
/* Enable full-resolution mode */
@@ -260,29 +264,14 @@ int adxl345_core_probe(struct device *dev, struct regmap *regmap,
return ret;
}
ret = iio_device_register(indio_dev);
if (ret < 0) {
dev_err(dev, "iio_device_register failed: %d\n", ret);
regmap_write(data->regmap, ADXL345_REG_POWER_CTL,
ADXL345_POWER_CTL_STANDBY);
}
ret = devm_add_action_or_reset(dev, adxl345_powerdown, data->regmap);
if (ret < 0)
return ret;
return ret;
return devm_iio_device_register(dev, indio_dev);
}
EXPORT_SYMBOL_GPL(adxl345_core_probe);
int adxl345_core_remove(struct device *dev)
{
struct iio_dev *indio_dev = dev_get_drvdata(dev);
struct adxl345_data *data = iio_priv(indio_dev);
iio_device_unregister(indio_dev);
return regmap_write(data->regmap, ADXL345_REG_POWER_CTL,
ADXL345_POWER_CTL_STANDBY);
}
EXPORT_SYMBOL_GPL(adxl345_core_remove);
MODULE_AUTHOR("Eva Rachel Retuya <eraretuya@gmail.com>");
MODULE_DESCRIPTION("ADXL345 3-Axis Digital Accelerometer core driver");
MODULE_LICENSE("GPL v2");
-6
View File
@@ -38,11 +38,6 @@ static int adxl345_i2c_probe(struct i2c_client *client,
id->name);
}
static int adxl345_i2c_remove(struct i2c_client *client)
{
return adxl345_core_remove(&client->dev);
}
static const struct i2c_device_id adxl345_i2c_id[] = {
{ "adxl345", ADXL345 },
{ "adxl375", ADXL375 },
@@ -65,7 +60,6 @@ static struct i2c_driver adxl345_i2c_driver = {
.of_match_table = adxl345_of_match,
},
.probe = adxl345_i2c_probe,
.remove = adxl345_i2c_remove,
.id_table = adxl345_i2c_id,
};
-6
View File
@@ -42,11 +42,6 @@ static int adxl345_spi_probe(struct spi_device *spi)
return adxl345_core_probe(&spi->dev, regmap, id->driver_data, id->name);
}
static int adxl345_spi_remove(struct spi_device *spi)
{
return adxl345_core_remove(&spi->dev);
}
static const struct spi_device_id adxl345_spi_id[] = {
{ "adxl345", ADXL345 },
{ "adxl375", ADXL375 },
@@ -69,7 +64,6 @@ static struct spi_driver adxl345_spi_driver = {
.of_match_table = adxl345_of_match,
},
.probe = adxl345_spi_probe,
.remove = adxl345_spi_remove,
.id_table = adxl345_spi_id,
};
+36 -41
View File
@@ -218,20 +218,33 @@ static int bma220_init(struct spi_device *spi)
return 0;
}
static int bma220_deinit(struct spi_device *spi)
static int bma220_power(struct spi_device *spi, bool up)
{
int ret;
int i, ret;
/* Make sure the chip is powered off */
ret = bma220_read_reg(spi, BMA220_REG_SUSPEND);
if (ret == BMA220_SUSPEND_SLEEP)
/**
* The chip can be suspended/woken up by a simple register read.
* So, we need up to 2 register reads of the suspend register
* to make sure that the device is in the desired state.
*/
for (i = 0; i < 2; i++) {
ret = bma220_read_reg(spi, BMA220_REG_SUSPEND);
if (ret < 0)
return ret;
if (ret == BMA220_SUSPEND_SLEEP)
return -EBUSY;
if (ret < 0)
return ret;
return 0;
if (up && ret == BMA220_SUSPEND_SLEEP)
return 0;
if (!up && ret == BMA220_SUSPEND_WAKE)
return 0;
}
return -EBUSY;
}
static void bma220_deinit(void *spi)
{
bma220_power(spi, false);
}
static int bma220_probe(struct spi_device *spi)
@@ -248,7 +261,6 @@ static int bma220_probe(struct spi_device *spi)
data = iio_priv(indio_dev);
data->spi_device = spi;
spi_set_drvdata(spi, indio_dev);
mutex_init(&data->lock);
indio_dev->info = &bma220_info;
@@ -262,49 +274,33 @@ static int bma220_probe(struct spi_device *spi)
if (ret)
return ret;
ret = iio_triggered_buffer_setup(indio_dev, iio_pollfunc_store_time,
bma220_trigger_handler, NULL);
ret = devm_add_action_or_reset(&spi->dev, bma220_deinit, spi);
if (ret)
return ret;
ret = devm_iio_triggered_buffer_setup(&spi->dev, indio_dev,
iio_pollfunc_store_time,
bma220_trigger_handler, NULL);
if (ret < 0) {
dev_err(&spi->dev, "iio triggered buffer setup failed\n");
goto err_suspend;
return ret;
}
ret = iio_device_register(indio_dev);
if (ret < 0) {
dev_err(&spi->dev, "iio_device_register failed\n");
iio_triggered_buffer_cleanup(indio_dev);
goto err_suspend;
}
return 0;
err_suspend:
return bma220_deinit(spi);
}
static int bma220_remove(struct spi_device *spi)
{
struct iio_dev *indio_dev = spi_get_drvdata(spi);
iio_device_unregister(indio_dev);
iio_triggered_buffer_cleanup(indio_dev);
return bma220_deinit(spi);
return devm_iio_device_register(&spi->dev, indio_dev);
}
static __maybe_unused int bma220_suspend(struct device *dev)
{
struct bma220_data *data = iio_priv(dev_get_drvdata(dev));
struct spi_device *spi = to_spi_device(dev);
/* The chip can be suspended/woken up by a simple register read. */
return bma220_read_reg(data->spi_device, BMA220_REG_SUSPEND);
return bma220_power(spi, false);
}
static __maybe_unused int bma220_resume(struct device *dev)
{
struct bma220_data *data = iio_priv(dev_get_drvdata(dev));
struct spi_device *spi = to_spi_device(dev);
return bma220_read_reg(data->spi_device, BMA220_REG_SUSPEND);
return bma220_power(spi, true);
}
static SIMPLE_DEV_PM_OPS(bma220_pm_ops, bma220_suspend, bma220_resume);
@@ -326,7 +322,6 @@ static struct spi_driver bma220_driver = {
.acpi_match_table = bma220_acpi_id,
},
.probe = bma220_probe,
.remove = bma220_remove,
.id_table = bma220_spi_id,
};
module_spi_driver(bma220_driver);
+64 -14
View File
@@ -10,6 +10,7 @@
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/acpi.h>
#include <linux/of_irq.h>
#include <linux/pm.h>
#include <linux/pm_runtime.h>
#include <linux/iio/iio.h>
@@ -57,12 +58,18 @@
#define BMC150_ACCEL_RESET_VAL 0xB6
#define BMC150_ACCEL_REG_INT_MAP_0 0x19
#define BMC150_ACCEL_INT_MAP_0_BIT_SLOPE BIT(2)
#define BMC150_ACCEL_INT_MAP_0_BIT_INT1_SLOPE BIT(2)
#define BMC150_ACCEL_REG_INT_MAP_1 0x1A
#define BMC150_ACCEL_INT_MAP_1_BIT_DATA BIT(0)
#define BMC150_ACCEL_INT_MAP_1_BIT_FWM BIT(1)
#define BMC150_ACCEL_INT_MAP_1_BIT_FFULL BIT(2)
#define BMC150_ACCEL_INT_MAP_1_BIT_INT1_DATA BIT(0)
#define BMC150_ACCEL_INT_MAP_1_BIT_INT1_FWM BIT(1)
#define BMC150_ACCEL_INT_MAP_1_BIT_INT1_FFULL BIT(2)
#define BMC150_ACCEL_INT_MAP_1_BIT_INT2_FFULL BIT(5)
#define BMC150_ACCEL_INT_MAP_1_BIT_INT2_FWM BIT(6)
#define BMC150_ACCEL_INT_MAP_1_BIT_INT2_DATA BIT(7)
#define BMC150_ACCEL_REG_INT_MAP_2 0x1B
#define BMC150_ACCEL_INT_MAP_2_BIT_INT2_SLOPE BIT(2)
#define BMC150_ACCEL_REG_INT_RST_LATCH 0x21
#define BMC150_ACCEL_INT_MODE_LATCH_RESET 0x80
@@ -81,6 +88,7 @@
#define BMC150_ACCEL_REG_INT_OUT_CTRL 0x20
#define BMC150_ACCEL_INT_OUT_CTRL_INT1_LVL BIT(0)
#define BMC150_ACCEL_INT_OUT_CTRL_INT2_LVL BIT(2)
#define BMC150_ACCEL_REG_INT_5 0x27
#define BMC150_ACCEL_SLOPE_DUR_MASK 0x03
@@ -476,21 +484,24 @@ static bool bmc150_apply_acpi_orientation(struct device *dev,
}
#endif
static const struct bmc150_accel_interrupt_info {
struct bmc150_accel_interrupt_info {
u8 map_reg;
u8 map_bitmask;
u8 en_reg;
u8 en_bitmask;
} bmc150_accel_interrupts[BMC150_ACCEL_INTERRUPTS] = {
};
static const struct bmc150_accel_interrupt_info
bmc150_accel_interrupts_int1[BMC150_ACCEL_INTERRUPTS] = {
{ /* data ready interrupt */
.map_reg = BMC150_ACCEL_REG_INT_MAP_1,
.map_bitmask = BMC150_ACCEL_INT_MAP_1_BIT_DATA,
.map_bitmask = BMC150_ACCEL_INT_MAP_1_BIT_INT1_DATA,
.en_reg = BMC150_ACCEL_REG_INT_EN_1,
.en_bitmask = BMC150_ACCEL_INT_EN_BIT_DATA_EN,
},
{ /* motion interrupt */
.map_reg = BMC150_ACCEL_REG_INT_MAP_0,
.map_bitmask = BMC150_ACCEL_INT_MAP_0_BIT_SLOPE,
.map_bitmask = BMC150_ACCEL_INT_MAP_0_BIT_INT1_SLOPE,
.en_reg = BMC150_ACCEL_REG_INT_EN_0,
.en_bitmask = BMC150_ACCEL_INT_EN_BIT_SLP_X |
BMC150_ACCEL_INT_EN_BIT_SLP_Y |
@@ -498,19 +509,56 @@ static const struct bmc150_accel_interrupt_info {
},
{ /* fifo watermark interrupt */
.map_reg = BMC150_ACCEL_REG_INT_MAP_1,
.map_bitmask = BMC150_ACCEL_INT_MAP_1_BIT_FWM,
.map_bitmask = BMC150_ACCEL_INT_MAP_1_BIT_INT1_FWM,
.en_reg = BMC150_ACCEL_REG_INT_EN_1,
.en_bitmask = BMC150_ACCEL_INT_EN_BIT_FWM_EN,
},
};
static const struct bmc150_accel_interrupt_info
bmc150_accel_interrupts_int2[BMC150_ACCEL_INTERRUPTS] = {
{ /* data ready interrupt */
.map_reg = BMC150_ACCEL_REG_INT_MAP_1,
.map_bitmask = BMC150_ACCEL_INT_MAP_1_BIT_INT2_DATA,
.en_reg = BMC150_ACCEL_REG_INT_EN_1,
.en_bitmask = BMC150_ACCEL_INT_EN_BIT_DATA_EN,
},
{ /* motion interrupt */
.map_reg = BMC150_ACCEL_REG_INT_MAP_2,
.map_bitmask = BMC150_ACCEL_INT_MAP_2_BIT_INT2_SLOPE,
.en_reg = BMC150_ACCEL_REG_INT_EN_0,
.en_bitmask = BMC150_ACCEL_INT_EN_BIT_SLP_X |
BMC150_ACCEL_INT_EN_BIT_SLP_Y |
BMC150_ACCEL_INT_EN_BIT_SLP_Z
},
{ /* fifo watermark interrupt */
.map_reg = BMC150_ACCEL_REG_INT_MAP_1,
.map_bitmask = BMC150_ACCEL_INT_MAP_1_BIT_INT2_FWM,
.en_reg = BMC150_ACCEL_REG_INT_EN_1,
.en_bitmask = BMC150_ACCEL_INT_EN_BIT_FWM_EN,
},
};
static void bmc150_accel_interrupts_setup(struct iio_dev *indio_dev,
struct bmc150_accel_data *data)
struct bmc150_accel_data *data, int irq)
{
const struct bmc150_accel_interrupt_info *irq_info = NULL;
struct device *dev = regmap_get_device(data->regmap);
int i;
/*
* For now we map all interrupts to the same output pin.
* However, some boards may have just INT2 (and not INT1) connected,
* so we try to detect which IRQ it is based on the interrupt-names.
* Without interrupt-names, we assume the irq belongs to INT1.
*/
irq_info = bmc150_accel_interrupts_int1;
if (data->type == BOSCH_BMC156 ||
irq == of_irq_get_byname(dev->of_node, "INT2"))
irq_info = bmc150_accel_interrupts_int2;
for (i = 0; i < BMC150_ACCEL_INTERRUPTS; i++)
data->interrupts[i].info = &bmc150_accel_interrupts[i];
data->interrupts[i].info = &irq_info[i];
}
static int bmc150_accel_set_interrupt(struct bmc150_accel_data *data, int i,
@@ -1127,7 +1175,7 @@ static const struct bmc150_accel_chip_info bmc150_accel_chip_info_tbl[] = {
{306458, BMC150_ACCEL_DEF_RANGE_16G} },
},
{
.name = "BMA253/BMA254/BMA255/BMC150/BMI055",
.name = "BMA253/BMA254/BMA255/BMC150/BMC156/BMI055",
.chip_id = 0xFA,
.channels = bmc150_accel_channels,
.num_channels = ARRAY_SIZE(bmc150_accel_channels),
@@ -1614,7 +1662,8 @@ static int bmc150_accel_chip_init(struct bmc150_accel_data *data)
}
int bmc150_accel_core_probe(struct device *dev, struct regmap *regmap, int irq,
const char *name, bool block_supported)
enum bmc150_type type, const char *name,
bool block_supported)
{
const struct attribute **fifo_attrs;
struct bmc150_accel_data *data;
@@ -1629,6 +1678,7 @@ int bmc150_accel_core_probe(struct device *dev, struct regmap *regmap, int irq,
dev_set_drvdata(dev, indio_dev);
data->regmap = regmap;
data->type = type;
if (!bmc150_apply_acpi_orientation(dev, &data->orientation)) {
ret = iio_read_mount_matrix(dev, &data->orientation);
@@ -1714,7 +1764,7 @@ int bmc150_accel_core_probe(struct device *dev, struct regmap *regmap, int irq,
goto err_buffer_cleanup;
}
bmc150_accel_interrupts_setup(indio_dev, data);
bmc150_accel_interrupts_setup(indio_dev, data, irq);
ret = bmc150_accel_triggers_setup(indio_dev, data);
if (ret)
+8 -2
View File
@@ -176,6 +176,7 @@ static int bmc150_accel_probe(struct i2c_client *client,
{
struct regmap *regmap;
const char *name = NULL;
enum bmc150_type type = BOSCH_UNKNOWN;
bool block_supported =
i2c_check_functionality(client->adapter, I2C_FUNC_I2C) ||
i2c_check_functionality(client->adapter,
@@ -188,10 +189,13 @@ static int bmc150_accel_probe(struct i2c_client *client,
return PTR_ERR(regmap);
}
if (id)
if (id) {
name = id->name;
type = id->driver_data;
}
ret = bmc150_accel_core_probe(&client->dev, regmap, client->irq, name, block_supported);
ret = bmc150_accel_core_probe(&client->dev, regmap, client->irq,
type, name, block_supported);
if (ret)
return ret;
@@ -236,6 +240,7 @@ static const struct i2c_device_id bmc150_accel_id[] = {
{"bma255"},
{"bma280"},
{"bmc150_accel"},
{"bmc156_accel", BOSCH_BMC156},
{"bmi055_accel"},
{}
};
@@ -251,6 +256,7 @@ static const struct of_device_id bmc150_accel_of_match[] = {
{ .compatible = "bosch,bma255" },
{ .compatible = "bosch,bma280" },
{ .compatible = "bosch,bmc150_accel" },
{ .compatible = "bosch,bmc156_accel" },
{ .compatible = "bosch,bmi055_accel" },
{ },
};
+9 -1
View File
@@ -16,6 +16,8 @@
static int bmc150_accel_probe(struct spi_device *spi)
{
struct regmap *regmap;
const char *name = NULL;
enum bmc150_type type = BOSCH_UNKNOWN;
const struct spi_device_id *id = spi_get_device_id(spi);
regmap = devm_regmap_init_spi(spi, &bmc150_regmap_conf);
@@ -24,7 +26,12 @@ static int bmc150_accel_probe(struct spi_device *spi)
return PTR_ERR(regmap);
}
return bmc150_accel_core_probe(&spi->dev, regmap, spi->irq, id->name,
if (id) {
name = id->name;
type = id->driver_data;
}
return bmc150_accel_core_probe(&spi->dev, regmap, spi->irq, type, name,
true);
}
@@ -54,6 +61,7 @@ static const struct spi_device_id bmc150_accel_id[] = {
{"bma255"},
{"bma280"},
{"bmc150_accel"},
{"bmc156_accel", BOSCH_BMC156},
{"bmi055_accel"},
{}
};
+19 -1
View File
@@ -13,6 +13,22 @@ struct i2c_client;
struct bmc150_accel_chip_info;
struct bmc150_accel_interrupt_info;
/*
* We can often guess better than "UNKNOWN" based on the device IDs
* but unfortunately this information is not always accurate. There are some
* devices where ACPI firmware specifies an ID like "BMA250E" when the device
* actually has a BMA222E. The driver attempts to detect those by reading the
* chip ID from the registers but this information is not always enough either.
*
* Therefore, this enum should be only used when the chip ID detection is not
* enough and we can be reasonably sure that the device IDs are reliable
* in practice (e.g. for device tree platforms).
*/
enum bmc150_type {
BOSCH_UNKNOWN,
BOSCH_BMC156,
};
struct bmc150_accel_interrupt {
const struct bmc150_accel_interrupt_info *info;
atomic_t users;
@@ -62,6 +78,7 @@ struct bmc150_accel_data {
int ev_enable_state;
int64_t timestamp, old_timestamp; /* Only used in hw fifo mode. */
const struct bmc150_accel_chip_info *chip_info;
enum bmc150_type type;
struct i2c_client *second_device;
void (*resume_callback)(struct device *dev);
struct delayed_work resume_work;
@@ -69,7 +86,8 @@ struct bmc150_accel_data {
};
int bmc150_accel_core_probe(struct device *dev, struct regmap *regmap, int irq,
const char *name, bool block_supported);
enum bmc150_type type, const char *name,
bool block_supported);
int bmc150_accel_core_remove(struct device *dev);
extern const struct dev_pm_ops bmc150_accel_pm_ops;
extern const struct regmap_config bmc150_regmap_conf;
+9 -17
View File
@@ -100,6 +100,11 @@ static enum da280_chipset da280_match_acpi_device(struct device *dev)
return (enum da280_chipset) id->driver_data;
}
static void da280_disable(void *client)
{
da280_enable(client, false);
}
static int da280_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
@@ -118,7 +123,6 @@ static int da280_probe(struct i2c_client *client,
data = iio_priv(indio_dev);
data->client = client;
i2c_set_clientdata(client, indio_dev);
indio_dev->info = &da280_info;
indio_dev->modes = INDIO_DIRECT_MODE;
@@ -142,22 +146,11 @@ static int da280_probe(struct i2c_client *client,
if (ret < 0)
return ret;
ret = iio_device_register(indio_dev);
if (ret < 0) {
dev_err(&client->dev, "device_register failed\n");
da280_enable(client, false);
}
ret = devm_add_action_or_reset(&client->dev, da280_disable, client);
if (ret)
return ret;
return ret;
}
static int da280_remove(struct i2c_client *client)
{
struct iio_dev *indio_dev = i2c_get_clientdata(client);
iio_device_unregister(indio_dev);
return da280_enable(client, false);
return devm_iio_device_register(&client->dev, indio_dev);
}
#ifdef CONFIG_PM_SLEEP
@@ -194,7 +187,6 @@ static struct i2c_driver da280_driver = {
.pm = &da280_pm_ops,
},
.probe = da280_probe,
.remove = da280_remove,
.id_table = da280_i2c_id,
};
+9 -17
View File
@@ -212,6 +212,11 @@ static const struct iio_info da311_info = {
.read_raw = da311_read_raw,
};
static void da311_disable(void *client)
{
da311_enable(client, false);
}
static int da311_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
@@ -229,7 +234,6 @@ static int da311_probe(struct i2c_client *client,
data = iio_priv(indio_dev);
data->client = client;
i2c_set_clientdata(client, indio_dev);
indio_dev->info = &da311_info;
indio_dev->name = "da311";
@@ -245,22 +249,11 @@ static int da311_probe(struct i2c_client *client,
if (ret < 0)
return ret;
ret = iio_device_register(indio_dev);
if (ret < 0) {
dev_err(&client->dev, "device_register failed\n");
da311_enable(client, false);
}
ret = devm_add_action_or_reset(&client->dev, da311_disable, client);
if (ret)
return ret;
return ret;
}
static int da311_remove(struct i2c_client *client)
{
struct iio_dev *indio_dev = i2c_get_clientdata(client);
iio_device_unregister(indio_dev);
return da311_enable(client, false);
return devm_iio_device_register(&client->dev, indio_dev);
}
#ifdef CONFIG_PM_SLEEP
@@ -289,7 +282,6 @@ static struct i2c_driver da311_driver = {
.pm = &da311_pm_ops,
},
.probe = da311_probe,
.remove = da311_remove,
.id_table = da311_i2c_id,
};
+10 -17
View File
@@ -170,6 +170,11 @@ static const struct iio_info dmard10_info = {
.read_raw = dmard10_read_raw,
};
static void dmard10_shutdown_cleanup(void *client)
{
dmard10_shutdown(client);
}
static int dmard10_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
@@ -194,7 +199,6 @@ static int dmard10_probe(struct i2c_client *client,
data = iio_priv(indio_dev);
data->client = client;
i2c_set_clientdata(client, indio_dev);
indio_dev->info = &dmard10_info;
indio_dev->name = "dmard10";
@@ -206,22 +210,12 @@ static int dmard10_probe(struct i2c_client *client,
if (ret < 0)
return ret;
ret = iio_device_register(indio_dev);
if (ret < 0) {
dev_err(&client->dev, "device_register failed\n");
dmard10_shutdown(client);
}
ret = devm_add_action_or_reset(&client->dev, dmard10_shutdown_cleanup,
client);
if (ret)
return ret;
return ret;
}
static int dmard10_remove(struct i2c_client *client)
{
struct iio_dev *indio_dev = i2c_get_clientdata(client);
iio_device_unregister(indio_dev);
return dmard10_shutdown(client);
return devm_iio_device_register(&client->dev, indio_dev);
}
#ifdef CONFIG_PM_SLEEP
@@ -250,7 +244,6 @@ static struct i2c_driver dmard10_driver = {
.pm = &dmard10_pm_ops,
},
.probe = dmard10_probe,
.remove = dmard10_remove,
.id_table = dmard10_i2c_id,
};
+4 -6
View File
@@ -367,7 +367,8 @@ static int hid_accel_3d_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "failed to setup common attributes\n");
return ret;
}
indio_dev->channels = kmemdup(channel_spec, channel_size, GFP_KERNEL);
indio_dev->channels = devm_kmemdup(&pdev->dev, channel_spec,
channel_size, GFP_KERNEL);
if (!indio_dev->channels) {
dev_err(&pdev->dev, "failed to duplicate channels\n");
@@ -378,7 +379,7 @@ static int hid_accel_3d_probe(struct platform_device *pdev)
hsdev->usage, accel_state);
if (ret) {
dev_err(&pdev->dev, "failed to setup attributes\n");
goto error_free_dev_mem;
return ret;
}
indio_dev->info = &accel_3d_info;
@@ -391,7 +392,7 @@ static int hid_accel_3d_probe(struct platform_device *pdev)
&accel_state->common_attributes);
if (ret < 0) {
dev_err(&pdev->dev, "trigger setup failed\n");
goto error_free_dev_mem;
return ret;
}
ret = iio_device_register(indio_dev);
@@ -416,8 +417,6 @@ error_iio_unreg:
iio_device_unregister(indio_dev);
error_remove_trigger:
hid_sensor_remove_trigger(indio_dev, &accel_state->common_attributes);
error_free_dev_mem:
kfree(indio_dev->channels);
return ret;
}
@@ -431,7 +430,6 @@ 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(indio_dev, &accel_state->common_attributes);
kfree(indio_dev->channels);
return 0;
}
-4
View File
@@ -64,7 +64,6 @@ enum st_accel_type {
#ifdef CONFIG_IIO_BUFFER
int st_accel_allocate_ring(struct iio_dev *indio_dev);
void st_accel_deallocate_ring(struct iio_dev *indio_dev);
int st_accel_trig_set_state(struct iio_trigger *trig, bool state);
#define ST_ACCEL_TRIGGER_SET_STATE (&st_accel_trig_set_state)
#else /* CONFIG_IIO_BUFFER */
@@ -72,9 +71,6 @@ static inline int st_accel_allocate_ring(struct iio_dev *indio_dev)
{
return 0;
}
static inline void st_accel_deallocate_ring(struct iio_dev *indio_dev)
{
}
#define ST_ACCEL_TRIGGER_SET_STATE NULL
#endif /* CONFIG_IIO_BUFFER */
+3 -13
View File
@@ -9,14 +9,9 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/stat.h>
#include <linux/interrupt.h>
#include <linux/i2c.h>
#include <linux/delay.h>
#include <linux/iio/iio.h>
#include <linux/iio/buffer.h>
#include <linux/iio/trigger_consumer.h>
#include <linux/iio/trigger.h>
#include <linux/iio/triggered_buffer.h>
#include <linux/iio/common/st_sensors.h>
@@ -67,13 +62,8 @@ static const struct iio_buffer_setup_ops st_accel_buffer_setup_ops = {
int st_accel_allocate_ring(struct iio_dev *indio_dev)
{
return iio_triggered_buffer_setup(indio_dev, NULL,
&st_sensors_trigger_handler, &st_accel_buffer_setup_ops);
}
void st_accel_deallocate_ring(struct iio_dev *indio_dev)
{
iio_triggered_buffer_cleanup(indio_dev);
return devm_iio_triggered_buffer_setup(indio_dev->dev.parent, indio_dev,
NULL, &st_sensors_trigger_handler, &st_accel_buffer_setup_ops);
}
MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
+3 -11
View File
@@ -9,17 +9,13 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/sysfs.h>
#include <linux/slab.h>
#include <linux/acpi.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/i2c.h>
#include <linux/irq.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/iio/trigger.h>
#include <linux/iio/buffer.h>
#include <linux/iio/common/st_sensors.h>
#include "st_accel.h"
@@ -1381,7 +1377,7 @@ int st_accel_common_probe(struct iio_dev *indio_dev)
err = st_sensors_allocate_trigger(indio_dev,
ST_ACCEL_TRIGGER_OPS);
if (err < 0)
goto st_accel_probe_trigger_error;
return err;
}
err = iio_device_register(indio_dev);
@@ -1396,8 +1392,6 @@ int st_accel_common_probe(struct iio_dev *indio_dev)
st_accel_device_register_error:
if (adata->irq > 0)
st_sensors_deallocate_trigger(indio_dev);
st_accel_probe_trigger_error:
st_accel_deallocate_ring(indio_dev);
return err;
}
EXPORT_SYMBOL(st_accel_common_probe);
@@ -1409,8 +1403,6 @@ void st_accel_common_remove(struct iio_dev *indio_dev)
iio_device_unregister(indio_dev);
if (adata->irq > 0)
st_sensors_deallocate_trigger(indio_dev);
st_accel_deallocate_ring(indio_dev);
}
EXPORT_SYMBOL(st_accel_common_remove);
+1 -2
View File
@@ -9,11 +9,10 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/mod_devicetable.h>
#include <linux/acpi.h>
#include <linux/i2c.h>
#include <linux/iio/iio.h>
#include <linux/property.h>
#include <linux/iio/common/st_sensors_i2c.h>
#include "st_accel.h"
+1 -1
View File
@@ -9,7 +9,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/mod_devicetable.h>
#include <linux/spi/spi.h>
#include <linux/iio/iio.h>
+10
View File
@@ -887,6 +887,16 @@ config ROCKCHIP_SARADC
To compile this driver as a module, choose M here: the
module will be called rockchip_saradc.
config RZG2L_ADC
tristate "Renesas RZ/G2L ADC driver"
depends on ARCH_R9A07G044 || COMPILE_TEST
help
Say yes here to build support for the ADC found in Renesas
RZ/G2L family.
To compile this driver as a module, choose M here: the
module will be called rzg2l_adc.
config SC27XX_ADC
tristate "Spreadtrum SC27xx series PMICs ADC"
depends on MFD_SC27XX_PMIC || COMPILE_TEST
+1
View File
@@ -82,6 +82,7 @@ obj-$(CONFIG_QCOM_PM8XXX_XOADC) += qcom-pm8xxx-xoadc.o
obj-$(CONFIG_RCAR_GYRO_ADC) += rcar-gyroadc.o
obj-$(CONFIG_RN5T618_ADC) += rn5t618-adc.o
obj-$(CONFIG_ROCKCHIP_SARADC) += rockchip_saradc.o
obj-$(CONFIG_RZG2L_ADC) += rzg2l_adc.o
obj-$(CONFIG_SC27XX_ADC) += sc27xx_adc.o
obj-$(CONFIG_SPEAR_ADC) += spear_adc.o
obj-$(CONFIG_STX104) += stx104.o
+3 -3
View File
@@ -205,7 +205,7 @@ static int ep93xx_adc_probe(struct platform_device *pdev)
*/
}
ret = clk_enable(priv->clk);
ret = clk_prepare_enable(priv->clk);
if (ret) {
dev_err(&pdev->dev, "Cannot enable clock\n");
return ret;
@@ -213,7 +213,7 @@ static int ep93xx_adc_probe(struct platform_device *pdev)
ret = iio_device_register(iiodev);
if (ret)
clk_disable(priv->clk);
clk_disable_unprepare(priv->clk);
return ret;
}
@@ -224,7 +224,7 @@ static int ep93xx_adc_remove(struct platform_device *pdev)
struct ep93xx_adc_priv *priv = iio_priv(iiodev);
iio_device_unregister(iiodev);
clk_disable(priv->clk);
clk_disable_unprepare(priv->clk);
return 0;
}
+7 -10
View File
@@ -201,11 +201,11 @@ static int mx25_gcq_setup_cfgs(struct platform_device *pdev,
*/
priv->vref[MX25_ADC_REFP_INT] = NULL;
priv->vref[MX25_ADC_REFP_EXT] =
devm_regulator_get_optional(&pdev->dev, "vref-ext");
devm_regulator_get_optional(dev, "vref-ext");
priv->vref[MX25_ADC_REFP_XP] =
devm_regulator_get_optional(&pdev->dev, "vref-xp");
devm_regulator_get_optional(dev, "vref-xp");
priv->vref[MX25_ADC_REFP_YP] =
devm_regulator_get_optional(&pdev->dev, "vref-yp");
devm_regulator_get_optional(dev, "vref-yp");
for_each_child_of_node(np, child) {
u32 reg;
@@ -307,7 +307,7 @@ static int mx25_gcq_probe(struct platform_device *pdev)
int ret;
int i;
indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*priv));
indio_dev = devm_iio_device_alloc(dev, sizeof(*priv));
if (!indio_dev)
return -ENOMEM;
@@ -347,14 +347,11 @@ static int mx25_gcq_probe(struct platform_device *pdev)
goto err_vref_disable;
}
priv->irq = platform_get_irq(pdev, 0);
if (priv->irq <= 0) {
ret = priv->irq;
if (!ret)
ret = -ENXIO;
ret = platform_get_irq(pdev, 0);
if (ret < 0)
goto err_clk_unprepare;
}
priv->irq = ret;
ret = request_irq(priv->irq, mx25_gcq_irq, 0, pdev->name, priv);
if (ret) {
dev_err(dev, "Failed requesting IRQ\n");
+93 -9
View File
@@ -37,6 +37,7 @@
#define JZ_ADC_REG_CFG_SAMPLE_NUM(n) ((n) << 10)
#define JZ_ADC_REG_CFG_PULL_UP(n) ((n) << 16)
#define JZ_ADC_REG_CFG_CMD_SEL BIT(22)
#define JZ_ADC_REG_CFG_VBAT_SEL BIT(30)
#define JZ_ADC_REG_CFG_TOUCH_OPS_MASK (BIT(31) | GENMASK(23, 10))
#define JZ_ADC_REG_ADCLK_CLKDIV_LSB 0
#define JZ4725B_ADC_REG_ADCLK_CLKDIV10US_LSB 16
@@ -71,6 +72,7 @@
#define JZ4725B_ADC_BATTERY_HIGH_VREF_BITS 10
#define JZ4740_ADC_BATTERY_HIGH_VREF (7500 * 0.986)
#define JZ4740_ADC_BATTERY_HIGH_VREF_BITS 12
#define JZ4760_ADC_BATTERY_VREF 2500
#define JZ4770_ADC_BATTERY_VREF 1200
#define JZ4770_ADC_BATTERY_VREF_BITS 12
@@ -92,7 +94,7 @@ struct ingenic_adc_soc_data {
const int *battery_scale_avail;
size_t battery_scale_avail_size;
unsigned int battery_vref_mode: 1;
unsigned int has_aux2: 1;
unsigned int has_aux_md: 1;
const struct iio_chan_spec *channels;
unsigned int num_channels;
int (*init_clk_div)(struct device *dev, struct ingenic_adc *adc);
@@ -295,6 +297,10 @@ static const int jz4740_adc_battery_scale_avail[] = {
JZ_ADC_BATTERY_LOW_VREF, JZ_ADC_BATTERY_LOW_VREF_BITS,
};
static const int jz4760_adc_battery_scale_avail[] = {
JZ4760_ADC_BATTERY_VREF, JZ4770_ADC_BATTERY_VREF_BITS,
};
static const int jz4770_adc_battery_raw_avail[] = {
0, 1, (1 << JZ4770_ADC_BATTERY_VREF_BITS) - 1,
};
@@ -400,6 +406,47 @@ static const struct iio_chan_spec jz4740_channels[] = {
},
};
static const struct iio_chan_spec jz4760_channels[] = {
{
.extend_name = "aux",
.type = IIO_VOLTAGE,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_SCALE),
.indexed = 1,
.channel = INGENIC_ADC_AUX0,
.scan_index = -1,
},
{
.extend_name = "aux1",
.type = IIO_VOLTAGE,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_SCALE),
.indexed = 1,
.channel = INGENIC_ADC_AUX,
.scan_index = -1,
},
{
.extend_name = "aux2",
.type = IIO_VOLTAGE,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_SCALE),
.indexed = 1,
.channel = INGENIC_ADC_AUX2,
.scan_index = -1,
},
{
.extend_name = "battery",
.type = IIO_VOLTAGE,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_SCALE),
.info_mask_separate_available = BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_SCALE),
.indexed = 1,
.channel = INGENIC_ADC_BATTERY,
.scan_index = -1,
},
};
static const struct iio_chan_spec jz4770_channels[] = {
{
.type = IIO_VOLTAGE,
@@ -506,7 +553,7 @@ static const struct ingenic_adc_soc_data jz4725b_adc_soc_data = {
.battery_scale_avail = jz4725b_adc_battery_scale_avail,
.battery_scale_avail_size = ARRAY_SIZE(jz4725b_adc_battery_scale_avail),
.battery_vref_mode = true,
.has_aux2 = false,
.has_aux_md = false,
.channels = jz4740_channels,
.num_channels = ARRAY_SIZE(jz4740_channels),
.init_clk_div = jz4725b_adc_init_clk_div,
@@ -520,12 +567,26 @@ static const struct ingenic_adc_soc_data jz4740_adc_soc_data = {
.battery_scale_avail = jz4740_adc_battery_scale_avail,
.battery_scale_avail_size = ARRAY_SIZE(jz4740_adc_battery_scale_avail),
.battery_vref_mode = true,
.has_aux2 = false,
.has_aux_md = false,
.channels = jz4740_channels,
.num_channels = ARRAY_SIZE(jz4740_channels),
.init_clk_div = NULL, /* no ADCLK register on JZ4740 */
};
static const struct ingenic_adc_soc_data jz4760_adc_soc_data = {
.battery_high_vref = JZ4760_ADC_BATTERY_VREF,
.battery_high_vref_bits = JZ4770_ADC_BATTERY_VREF_BITS,
.battery_raw_avail = jz4770_adc_battery_raw_avail,
.battery_raw_avail_size = ARRAY_SIZE(jz4770_adc_battery_raw_avail),
.battery_scale_avail = jz4760_adc_battery_scale_avail,
.battery_scale_avail_size = ARRAY_SIZE(jz4760_adc_battery_scale_avail),
.battery_vref_mode = false,
.has_aux_md = true,
.channels = jz4760_channels,
.num_channels = ARRAY_SIZE(jz4760_channels),
.init_clk_div = jz4770_adc_init_clk_div,
};
static const struct ingenic_adc_soc_data jz4770_adc_soc_data = {
.battery_high_vref = JZ4770_ADC_BATTERY_VREF,
.battery_high_vref_bits = JZ4770_ADC_BATTERY_VREF_BITS,
@@ -534,7 +595,7 @@ static const struct ingenic_adc_soc_data jz4770_adc_soc_data = {
.battery_scale_avail = jz4770_adc_battery_scale_avail,
.battery_scale_avail_size = ARRAY_SIZE(jz4770_adc_battery_scale_avail),
.battery_vref_mode = false,
.has_aux2 = true,
.has_aux_md = true,
.channels = jz4770_channels,
.num_channels = ARRAY_SIZE(jz4770_channels),
.init_clk_div = jz4770_adc_init_clk_div,
@@ -569,7 +630,7 @@ static int ingenic_adc_read_chan_info_raw(struct iio_dev *iio_dev,
struct iio_chan_spec const *chan,
int *val)
{
int bit, ret, engine = (chan->channel == INGENIC_ADC_BATTERY);
int cmd, ret, engine = (chan->channel == INGENIC_ADC_BATTERY);
struct ingenic_adc *adc = iio_priv(iio_dev);
ret = clk_enable(adc->clk);
@@ -579,11 +640,22 @@ static int ingenic_adc_read_chan_info_raw(struct iio_dev *iio_dev,
return ret;
}
/* We cannot sample AUX/AUX2 in parallel. */
/* We cannot sample the aux channels in parallel. */
mutex_lock(&adc->aux_lock);
if (adc->soc_data->has_aux2 && engine == 0) {
bit = BIT(chan->channel == INGENIC_ADC_AUX2);
ingenic_adc_set_config(adc, JZ_ADC_REG_CFG_AUX_MD, bit);
if (adc->soc_data->has_aux_md && engine == 0) {
switch (chan->channel) {
case INGENIC_ADC_AUX0:
cmd = 0;
break;
case INGENIC_ADC_AUX:
cmd = 1;
break;
case INGENIC_ADC_AUX2:
cmd = 2;
break;
}
ingenic_adc_set_config(adc, JZ_ADC_REG_CFG_AUX_MD, cmd);
}
ret = ingenic_adc_capture(adc, engine);
@@ -591,6 +663,7 @@ static int ingenic_adc_read_chan_info_raw(struct iio_dev *iio_dev,
goto out;
switch (chan->channel) {
case INGENIC_ADC_AUX0:
case INGENIC_ADC_AUX:
case INGENIC_ADC_AUX2:
*val = readw(adc->base + JZ_ADC_REG_ADSDAT);
@@ -621,6 +694,7 @@ static int ingenic_adc_read_raw(struct iio_dev *iio_dev,
return ingenic_adc_read_chan_info_raw(iio_dev, chan, val);
case IIO_CHAN_INFO_SCALE:
switch (chan->channel) {
case INGENIC_ADC_AUX0:
case INGENIC_ADC_AUX:
case INGENIC_ADC_AUX2:
*val = JZ_ADC_AUX_VREF;
@@ -806,6 +880,14 @@ static int ingenic_adc_probe(struct platform_device *pdev)
/* Put hardware in a known passive state. */
writeb(0x00, adc->base + JZ_ADC_REG_ENABLE);
writeb(0xff, adc->base + JZ_ADC_REG_CTRL);
/* JZ4760B specific */
if (device_property_present(dev, "ingenic,use-internal-divider"))
ingenic_adc_set_config(adc, JZ_ADC_REG_CFG_VBAT_SEL,
JZ_ADC_REG_CFG_VBAT_SEL);
else
ingenic_adc_set_config(adc, JZ_ADC_REG_CFG_VBAT_SEL, 0);
usleep_range(2000, 3000); /* Must wait at least 2ms. */
clk_disable(adc->clk);
@@ -832,6 +914,8 @@ static int ingenic_adc_probe(struct platform_device *pdev)
static const struct of_device_id ingenic_adc_of_match[] = {
{ .compatible = "ingenic,jz4725b-adc", .data = &jz4725b_adc_soc_data, },
{ .compatible = "ingenic,jz4740-adc", .data = &jz4740_adc_soc_data, },
{ .compatible = "ingenic,jz4760-adc", .data = &jz4760_adc_soc_data, },
{ .compatible = "ingenic,jz4760b-adc", .data = &jz4760_adc_soc_data, },
{ .compatible = "ingenic,jz4770-adc", .data = &jz4770_adc_soc_data, },
{ },
};
+14 -6
View File
@@ -347,7 +347,7 @@ static int meson_sar_adc_read_raw_sample(struct iio_dev *indio_dev,
struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
int regval, fifo_chan, fifo_val, count;
if(!wait_for_completion_timeout(&priv->done,
if (!wait_for_completion_timeout(&priv->done,
msecs_to_jiffies(MESON_SAR_ADC_TIMEOUT)))
return -ETIMEDOUT;
@@ -497,8 +497,8 @@ static int meson_sar_adc_lock(struct iio_dev *indio_dev)
if (priv->param->has_bl30_integration) {
/* prevent BL30 from using the SAR ADC while we are using it */
regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY,
MESON_SAR_ADC_DELAY_KERNEL_BUSY,
MESON_SAR_ADC_DELAY_KERNEL_BUSY);
MESON_SAR_ADC_DELAY_KERNEL_BUSY,
MESON_SAR_ADC_DELAY_KERNEL_BUSY);
/*
* wait until BL30 releases it's lock (so we can use the SAR
@@ -525,7 +525,7 @@ static void meson_sar_adc_unlock(struct iio_dev *indio_dev)
if (priv->param->has_bl30_integration)
/* allow BL30 to use the SAR ADC again */
regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY,
MESON_SAR_ADC_DELAY_KERNEL_BUSY, 0);
MESON_SAR_ADC_DELAY_KERNEL_BUSY, 0);
mutex_unlock(&indio_dev->mlock);
}
@@ -791,7 +791,7 @@ static int meson_sar_adc_init(struct iio_dev *indio_dev)
* on the vendor driver), which we don't support at the moment.
*/
regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0,
MESON_SAR_ADC_REG0_ADC_TEMP_SEN_SEL, 0);
MESON_SAR_ADC_REG0_ADC_TEMP_SEN_SEL, 0);
/* disable all channels by default */
regmap_write(priv->regmap, MESON_SAR_ADC_CHAN_LIST, 0x0);
@@ -1104,6 +1104,14 @@ static const struct meson_sar_adc_param meson_sar_adc_gxl_param = {
.resolution = 12,
};
static const struct meson_sar_adc_param meson_sar_adc_g12a_param = {
.has_bl30_integration = false,
.clock_rate = 1200000,
.bandgap_reg = MESON_SAR_ADC_REG11,
.regmap_config = &meson_sar_adc_regmap_config_gxbb,
.resolution = 12,
};
static const struct meson_sar_adc_data meson_sar_adc_meson8_data = {
.param = &meson_sar_adc_meson8_param,
.name = "meson-meson8-saradc",
@@ -1140,7 +1148,7 @@ static const struct meson_sar_adc_data meson_sar_adc_axg_data = {
};
static const struct meson_sar_adc_data meson_sar_adc_g12a_data = {
.param = &meson_sar_adc_gxl_param,
.param = &meson_sar_adc_g12a_param,
.name = "meson-g12a-saradc",
};
+61 -8
View File
@@ -35,7 +35,7 @@
#define SARADC_DLY_PU_SOC_MASK 0x3f
#define SARADC_TIMEOUT msecs_to_jiffies(100)
#define SARADC_MAX_CHANNELS 6
#define SARADC_MAX_CHANNELS 8
struct rockchip_saradc_data {
const struct iio_chan_spec *channels;
@@ -49,10 +49,12 @@ struct rockchip_saradc {
struct clk *clk;
struct completion completion;
struct regulator *vref;
int uv_vref;
struct reset_control *reset;
const struct rockchip_saradc_data *data;
u16 last_val;
const struct iio_chan_spec *last_chan;
struct notifier_block nb;
};
static void rockchip_saradc_power_down(struct rockchip_saradc *info)
@@ -105,13 +107,7 @@ static int rockchip_saradc_read_raw(struct iio_dev *indio_dev,
mutex_unlock(&indio_dev->mlock);
return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
ret = regulator_get_voltage(info->vref);
if (ret < 0) {
dev_err(&indio_dev->dev, "failed to get voltage\n");
return ret;
}
*val = ret / 1000;
*val = info->uv_vref / 1000;
*val2 = chan->scan_type.realbits;
return IIO_VAL_FRACTIONAL_LOG2;
default:
@@ -192,6 +188,23 @@ static const struct rockchip_saradc_data rk3399_saradc_data = {
.clk_rate = 1000000,
};
static const struct iio_chan_spec rockchip_rk3568_saradc_iio_channels[] = {
SARADC_CHANNEL(0, "adc0", 10),
SARADC_CHANNEL(1, "adc1", 10),
SARADC_CHANNEL(2, "adc2", 10),
SARADC_CHANNEL(3, "adc3", 10),
SARADC_CHANNEL(4, "adc4", 10),
SARADC_CHANNEL(5, "adc5", 10),
SARADC_CHANNEL(6, "adc6", 10),
SARADC_CHANNEL(7, "adc7", 10),
};
static const struct rockchip_saradc_data rk3568_saradc_data = {
.channels = rockchip_rk3568_saradc_iio_channels,
.num_channels = ARRAY_SIZE(rockchip_rk3568_saradc_iio_channels),
.clk_rate = 1000000,
};
static const struct of_device_id rockchip_saradc_match[] = {
{
.compatible = "rockchip,saradc",
@@ -202,6 +215,9 @@ static const struct of_device_id rockchip_saradc_match[] = {
}, {
.compatible = "rockchip,rk3399-saradc",
.data = &rk3399_saradc_data,
}, {
.compatible = "rockchip,rk3568-saradc",
.data = &rk3568_saradc_data,
},
{},
};
@@ -278,6 +294,26 @@ out:
return IRQ_HANDLED;
}
static int rockchip_saradc_volt_notify(struct notifier_block *nb,
unsigned long event,
void *data)
{
struct rockchip_saradc *info =
container_of(nb, struct rockchip_saradc, nb);
if (event & REGULATOR_EVENT_VOLTAGE_CHANGE)
info->uv_vref = (unsigned long)data;
return NOTIFY_OK;
}
static void rockchip_saradc_regulator_unreg_notifier(void *data)
{
struct rockchip_saradc *info = data;
regulator_unregister_notifier(info->vref, &info->nb);
}
static int rockchip_saradc_probe(struct platform_device *pdev)
{
struct rockchip_saradc *info = NULL;
@@ -390,6 +426,12 @@ static int rockchip_saradc_probe(struct platform_device *pdev)
return ret;
}
ret = regulator_get_voltage(info->vref);
if (ret < 0)
return ret;
info->uv_vref = ret;
ret = clk_prepare_enable(info->pclk);
if (ret < 0) {
dev_err(&pdev->dev, "failed to enable pclk\n");
@@ -430,6 +472,17 @@ static int rockchip_saradc_probe(struct platform_device *pdev)
if (ret)
return ret;
info->nb.notifier_call = rockchip_saradc_volt_notify;
ret = regulator_register_notifier(info->vref, &info->nb);
if (ret)
return ret;
ret = devm_add_action_or_reset(&pdev->dev,
rockchip_saradc_regulator_unreg_notifier,
info);
if (ret)
return ret;
return devm_iio_device_register(&pdev->dev, indio_dev);
}
+600
View File
@@ -0,0 +1,600 @@
// SPDX-License-Identifier: GPL-2.0
/*
* RZ/G2L A/D Converter driver
*
* Copyright (c) 2021 Renesas Electronics Europe GmbH
*
* Author: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
*/
#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/completion.h>
#include <linux/delay.h>
#include <linux/iio/iio.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/reset.h>
#define DRIVER_NAME "rzg2l-adc"
#define RZG2L_ADM(n) ((n) * 0x4)
#define RZG2L_ADM0_ADCE BIT(0)
#define RZG2L_ADM0_ADBSY BIT(1)
#define RZG2L_ADM0_PWDWNB BIT(2)
#define RZG2L_ADM0_SRESB BIT(15)
#define RZG2L_ADM1_TRG BIT(0)
#define RZG2L_ADM1_MS BIT(2)
#define RZG2L_ADM1_BS BIT(4)
#define RZG2L_ADM1_EGA_MASK GENMASK(13, 12)
#define RZG2L_ADM2_CHSEL_MASK GENMASK(7, 0)
#define RZG2L_ADM3_ADIL_MASK GENMASK(31, 24)
#define RZG2L_ADM3_ADCMP_MASK GENMASK(23, 16)
#define RZG2L_ADM3_ADCMP_E FIELD_PREP(RZG2L_ADM3_ADCMP_MASK, 0xe)
#define RZG2L_ADM3_ADSMP_MASK GENMASK(15, 0)
#define RZG2L_ADINT 0x20
#define RZG2L_ADINT_INTEN_MASK GENMASK(7, 0)
#define RZG2L_ADINT_CSEEN BIT(16)
#define RZG2L_ADINT_INTS BIT(31)
#define RZG2L_ADSTS 0x24
#define RZG2L_ADSTS_CSEST BIT(16)
#define RZG2L_ADSTS_INTST_MASK GENMASK(7, 0)
#define RZG2L_ADIVC 0x28
#define RZG2L_ADIVC_DIVADC_MASK GENMASK(8, 0)
#define RZG2L_ADIVC_DIVADC_4 FIELD_PREP(RZG2L_ADIVC_DIVADC_MASK, 0x4)
#define RZG2L_ADFIL 0x2c
#define RZG2L_ADCR(n) (0x30 + ((n) * 0x4))
#define RZG2L_ADCR_AD_MASK GENMASK(11, 0)
#define RZG2L_ADSMP_DEFUALT_SAMPLING 0x578
#define RZG2L_ADC_MAX_CHANNELS 8
#define RZG2L_ADC_CHN_MASK 0x7
#define RZG2L_ADC_TIMEOUT usecs_to_jiffies(1 * 4)
struct rzg2l_adc_data {
const struct iio_chan_spec *channels;
u8 num_channels;
};
struct rzg2l_adc {
void __iomem *base;
struct clk *pclk;
struct clk *adclk;
struct reset_control *presetn;
struct reset_control *adrstn;
struct completion completion;
const struct rzg2l_adc_data *data;
struct mutex lock;
u16 last_val[RZG2L_ADC_MAX_CHANNELS];
};
static const char * const rzg2l_adc_channel_name[] = {
"adc0",
"adc1",
"adc2",
"adc3",
"adc4",
"adc5",
"adc6",
"adc7",
};
static unsigned int rzg2l_adc_readl(struct rzg2l_adc *adc, u32 reg)
{
return readl(adc->base + reg);
}
static void rzg2l_adc_writel(struct rzg2l_adc *adc, unsigned int reg, u32 val)
{
writel(val, adc->base + reg);
}
static void rzg2l_adc_pwr(struct rzg2l_adc *adc, bool on)
{
u32 reg;
reg = rzg2l_adc_readl(adc, RZG2L_ADM(0));
if (on)
reg |= RZG2L_ADM0_PWDWNB;
else
reg &= ~RZG2L_ADM0_PWDWNB;
rzg2l_adc_writel(adc, RZG2L_ADM(0), reg);
udelay(2);
}
static void rzg2l_adc_start_stop(struct rzg2l_adc *adc, bool start)
{
int timeout = 5;
u32 reg;
reg = rzg2l_adc_readl(adc, RZG2L_ADM(0));
if (start)
reg |= RZG2L_ADM0_ADCE;
else
reg &= ~RZG2L_ADM0_ADCE;
rzg2l_adc_writel(adc, RZG2L_ADM(0), reg);
if (start)
return;
do {
usleep_range(100, 200);
reg = rzg2l_adc_readl(adc, RZG2L_ADM(0));
timeout--;
if (!timeout) {
pr_err("%s stopping ADC timed out\n", __func__);
break;
}
} while (((reg & RZG2L_ADM0_ADBSY) || (reg & RZG2L_ADM0_ADCE)));
}
static void rzg2l_set_trigger(struct rzg2l_adc *adc)
{
u32 reg;
/*
* Setup ADM1 for SW trigger
* EGA[13:12] - Set 00 to indicate hardware trigger is invalid
* BS[4] - Enable 1-buffer mode
* MS[1] - Enable Select mode
* TRG[0] - Enable software trigger mode
*/
reg = rzg2l_adc_readl(adc, RZG2L_ADM(1));
reg &= ~RZG2L_ADM1_EGA_MASK;
reg &= ~RZG2L_ADM1_BS;
reg &= ~RZG2L_ADM1_TRG;
reg |= RZG2L_ADM1_MS;
rzg2l_adc_writel(adc, RZG2L_ADM(1), reg);
}
static int rzg2l_adc_conversion_setup(struct rzg2l_adc *adc, u8 ch)
{
u32 reg;
if (rzg2l_adc_readl(adc, RZG2L_ADM(0)) & RZG2L_ADM0_ADBSY)
return -EBUSY;
rzg2l_set_trigger(adc);
/* Select analog input channel subjected to conversion. */
reg = rzg2l_adc_readl(adc, RZG2L_ADM(2));
reg &= ~RZG2L_ADM2_CHSEL_MASK;
reg |= BIT(ch);
rzg2l_adc_writel(adc, RZG2L_ADM(2), reg);
/*
* Setup ADINT
* INTS[31] - Select pulse signal
* CSEEN[16] - Enable channel select error interrupt
* INTEN[7:0] - Select channel interrupt
*/
reg = rzg2l_adc_readl(adc, RZG2L_ADINT);
reg &= ~RZG2L_ADINT_INTS;
reg &= ~RZG2L_ADINT_INTEN_MASK;
reg |= (RZG2L_ADINT_CSEEN | BIT(ch));
rzg2l_adc_writel(adc, RZG2L_ADINT, reg);
return 0;
}
static int rzg2l_adc_set_power(struct iio_dev *indio_dev, bool on)
{
struct device *dev = indio_dev->dev.parent;
if (on)
return pm_runtime_resume_and_get(dev);
return pm_runtime_put_sync(dev);
}
static int rzg2l_adc_conversion(struct iio_dev *indio_dev, struct rzg2l_adc *adc, u8 ch)
{
int ret;
ret = rzg2l_adc_set_power(indio_dev, true);
if (ret)
return ret;
ret = rzg2l_adc_conversion_setup(adc, ch);
if (ret) {
rzg2l_adc_set_power(indio_dev, false);
return ret;
}
reinit_completion(&adc->completion);
rzg2l_adc_start_stop(adc, true);
if (!wait_for_completion_timeout(&adc->completion, RZG2L_ADC_TIMEOUT)) {
rzg2l_adc_writel(adc, RZG2L_ADINT,
rzg2l_adc_readl(adc, RZG2L_ADINT) & ~RZG2L_ADINT_INTEN_MASK);
rzg2l_adc_start_stop(adc, false);
rzg2l_adc_set_power(indio_dev, false);
return -ETIMEDOUT;
}
return rzg2l_adc_set_power(indio_dev, false);
}
static int rzg2l_adc_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int *val, int *val2, long mask)
{
struct rzg2l_adc *adc = iio_priv(indio_dev);
int ret;
u8 ch;
switch (mask) {
case IIO_CHAN_INFO_RAW:
if (chan->type != IIO_VOLTAGE)
return -EINVAL;
mutex_lock(&adc->lock);
ch = chan->channel & RZG2L_ADC_CHN_MASK;
ret = rzg2l_adc_conversion(indio_dev, adc, ch);
if (ret) {
mutex_unlock(&adc->lock);
return ret;
}
*val = adc->last_val[ch];
mutex_unlock(&adc->lock);
return IIO_VAL_INT;
default:
return -EINVAL;
}
}
static int rzg2l_adc_read_label(struct iio_dev *iio_dev,
const struct iio_chan_spec *chan,
char *label)
{
if (chan->channel >= RZG2L_ADC_MAX_CHANNELS)
return -EINVAL;
return sysfs_emit(label, "%s\n", rzg2l_adc_channel_name[chan->channel]);
}
static const struct iio_info rzg2l_adc_iio_info = {
.read_raw = rzg2l_adc_read_raw,
.read_label = rzg2l_adc_read_label,
};
static irqreturn_t rzg2l_adc_isr(int irq, void *dev_id)
{
struct rzg2l_adc *adc = dev_id;
unsigned long intst;
u32 reg;
int ch;
reg = rzg2l_adc_readl(adc, RZG2L_ADSTS);
/* A/D conversion channel select error interrupt */
if (reg & RZG2L_ADSTS_CSEST) {
rzg2l_adc_writel(adc, RZG2L_ADSTS, reg);
return IRQ_HANDLED;
}
intst = reg & RZG2L_ADSTS_INTST_MASK;
if (!intst)
return IRQ_NONE;
for_each_set_bit(ch, &intst, RZG2L_ADC_MAX_CHANNELS)
adc->last_val[ch] = rzg2l_adc_readl(adc, RZG2L_ADCR(ch)) & RZG2L_ADCR_AD_MASK;
/* clear the channel interrupt */
rzg2l_adc_writel(adc, RZG2L_ADSTS, reg);
complete(&adc->completion);
return IRQ_HANDLED;
}
static int rzg2l_adc_parse_properties(struct platform_device *pdev, struct rzg2l_adc *adc)
{
struct iio_chan_spec *chan_array;
struct fwnode_handle *fwnode;
struct rzg2l_adc_data *data;
unsigned int channel;
int num_channels;
int ret;
u8 i;
data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
num_channels = device_get_child_node_count(&pdev->dev);
if (!num_channels) {
dev_err(&pdev->dev, "no channel children\n");
return -ENODEV;
}
if (num_channels > RZG2L_ADC_MAX_CHANNELS) {
dev_err(&pdev->dev, "num of channel children out of range\n");
return -EINVAL;
}
chan_array = devm_kcalloc(&pdev->dev, num_channels, sizeof(*chan_array),
GFP_KERNEL);
if (!chan_array)
return -ENOMEM;
i = 0;
device_for_each_child_node(&pdev->dev, fwnode) {
ret = fwnode_property_read_u32(fwnode, "reg", &channel);
if (ret)
return ret;
if (channel >= RZG2L_ADC_MAX_CHANNELS)
return -EINVAL;
chan_array[i].type = IIO_VOLTAGE;
chan_array[i].indexed = 1;
chan_array[i].channel = channel;
chan_array[i].info_mask_separate = BIT(IIO_CHAN_INFO_RAW);
chan_array[i].datasheet_name = rzg2l_adc_channel_name[channel];
i++;
}
data->num_channels = num_channels;
data->channels = chan_array;
adc->data = data;
return 0;
}
static int rzg2l_adc_hw_init(struct rzg2l_adc *adc)
{
int timeout = 5;
u32 reg;
int ret;
ret = clk_prepare_enable(adc->pclk);
if (ret)
return ret;
/* SW reset */
reg = rzg2l_adc_readl(adc, RZG2L_ADM(0));
reg |= RZG2L_ADM0_SRESB;
rzg2l_adc_writel(adc, RZG2L_ADM(0), reg);
while (!(rzg2l_adc_readl(adc, RZG2L_ADM(0)) & RZG2L_ADM0_SRESB)) {
if (!timeout) {
ret = -EBUSY;
goto exit_hw_init;
}
timeout--;
usleep_range(100, 200);
}
/* Only division by 4 can be set */
reg = rzg2l_adc_readl(adc, RZG2L_ADIVC);
reg &= ~RZG2L_ADIVC_DIVADC_MASK;
reg |= RZG2L_ADIVC_DIVADC_4;
rzg2l_adc_writel(adc, RZG2L_ADIVC, reg);
/*
* Setup AMD3
* ADIL[31:24] - Should be always set to 0
* ADCMP[23:16] - Should be always set to 0xe
* ADSMP[15:0] - Set default (0x578) sampling period
*/
reg = rzg2l_adc_readl(adc, RZG2L_ADM(3));
reg &= ~RZG2L_ADM3_ADIL_MASK;
reg &= ~RZG2L_ADM3_ADCMP_MASK;
reg &= ~RZG2L_ADM3_ADSMP_MASK;
reg |= (RZG2L_ADM3_ADCMP_E | RZG2L_ADSMP_DEFUALT_SAMPLING);
rzg2l_adc_writel(adc, RZG2L_ADM(3), reg);
exit_hw_init:
clk_disable_unprepare(adc->pclk);
return 0;
}
static void rzg2l_adc_pm_runtime_disable(void *data)
{
struct device *dev = data;
pm_runtime_disable(dev->parent);
}
static void rzg2l_adc_pm_runtime_set_suspended(void *data)
{
struct device *dev = data;
pm_runtime_set_suspended(dev->parent);
}
static void rzg2l_adc_reset_assert(void *data)
{
reset_control_assert(data);
}
static int rzg2l_adc_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct iio_dev *indio_dev;
struct rzg2l_adc *adc;
int ret;
int irq;
indio_dev = devm_iio_device_alloc(dev, sizeof(*adc));
if (!indio_dev)
return -ENOMEM;
adc = iio_priv(indio_dev);
ret = rzg2l_adc_parse_properties(pdev, adc);
if (ret)
return ret;
mutex_init(&adc->lock);
adc->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(adc->base))
return PTR_ERR(adc->base);
adc->pclk = devm_clk_get(dev, "pclk");
if (IS_ERR(adc->pclk)) {
dev_err(dev, "Failed to get pclk");
return PTR_ERR(adc->pclk);
}
adc->adclk = devm_clk_get(dev, "adclk");
if (IS_ERR(adc->adclk)) {
dev_err(dev, "Failed to get adclk");
return PTR_ERR(adc->adclk);
}
adc->adrstn = devm_reset_control_get_exclusive(dev, "adrst-n");
if (IS_ERR(adc->adrstn)) {
dev_err(dev, "failed to get adrstn\n");
return PTR_ERR(adc->adrstn);
}
adc->presetn = devm_reset_control_get_exclusive(dev, "presetn");
if (IS_ERR(adc->presetn)) {
dev_err(dev, "failed to get presetn\n");
return PTR_ERR(adc->presetn);
}
ret = reset_control_deassert(adc->adrstn);
if (ret) {
dev_err(&pdev->dev, "failed to deassert adrstn pin, %d\n", ret);
return ret;
}
ret = devm_add_action_or_reset(&pdev->dev,
rzg2l_adc_reset_assert, adc->adrstn);
if (ret) {
dev_err(&pdev->dev, "failed to register adrstn assert devm action, %d\n",
ret);
return ret;
}
ret = reset_control_deassert(adc->presetn);
if (ret) {
dev_err(&pdev->dev, "failed to deassert presetn pin, %d\n", ret);
return ret;
}
ret = devm_add_action_or_reset(&pdev->dev,
rzg2l_adc_reset_assert, adc->presetn);
if (ret) {
dev_err(&pdev->dev, "failed to register presetn assert devm action, %d\n",
ret);
return ret;
}
ret = rzg2l_adc_hw_init(adc);
if (ret) {
dev_err(&pdev->dev, "failed to initialize ADC HW, %d\n", ret);
return ret;
}
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
dev_err(dev, "no irq resource\n");
return irq;
}
ret = devm_request_irq(dev, irq, rzg2l_adc_isr,
0, dev_name(dev), adc);
if (ret < 0)
return ret;
init_completion(&adc->completion);
platform_set_drvdata(pdev, indio_dev);
indio_dev->name = DRIVER_NAME;
indio_dev->info = &rzg2l_adc_iio_info;
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->channels = adc->data->channels;
indio_dev->num_channels = adc->data->num_channels;
pm_runtime_set_suspended(dev);
ret = devm_add_action_or_reset(&pdev->dev,
rzg2l_adc_pm_runtime_set_suspended, &indio_dev->dev);
if (ret)
return ret;
pm_runtime_enable(dev);
ret = devm_add_action_or_reset(&pdev->dev,
rzg2l_adc_pm_runtime_disable, &indio_dev->dev);
if (ret)
return ret;
return devm_iio_device_register(dev, indio_dev);
}
static const struct of_device_id rzg2l_adc_match[] = {
{ .compatible = "renesas,rzg2l-adc",},
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, rzg2l_adc_match);
static int __maybe_unused rzg2l_adc_pm_runtime_suspend(struct device *dev)
{
struct iio_dev *indio_dev = dev_get_drvdata(dev);
struct rzg2l_adc *adc = iio_priv(indio_dev);
rzg2l_adc_pwr(adc, false);
clk_disable_unprepare(adc->adclk);
clk_disable_unprepare(adc->pclk);
return 0;
}
static int __maybe_unused rzg2l_adc_pm_runtime_resume(struct device *dev)
{
struct iio_dev *indio_dev = dev_get_drvdata(dev);
struct rzg2l_adc *adc = iio_priv(indio_dev);
int ret;
ret = clk_prepare_enable(adc->pclk);
if (ret)
return ret;
ret = clk_prepare_enable(adc->adclk);
if (ret)
return ret;
rzg2l_adc_pwr(adc, true);
return 0;
}
static const struct dev_pm_ops rzg2l_adc_pm_ops = {
SET_RUNTIME_PM_OPS(rzg2l_adc_pm_runtime_suspend,
rzg2l_adc_pm_runtime_resume,
NULL)
};
static struct platform_driver rzg2l_adc_driver = {
.probe = rzg2l_adc_probe,
.driver = {
.name = DRIVER_NAME,
.of_match_table = rzg2l_adc_match,
.pm = &rzg2l_adc_pm_ops,
},
};
module_platform_driver(rzg2l_adc_driver);
MODULE_AUTHOR("Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>");
MODULE_DESCRIPTION("Renesas RZ/G2L ADC driver");
MODULE_LICENSE("GPL v2");
+11
View File
@@ -131,6 +131,17 @@ config SENSIRION_SGP30
To compile this driver as module, choose M here: the
module will be called sgp30.
config SENSIRION_SGP40
tristate "Sensirion SGP40 gas sensor"
depends on I2C
select CRC8
help
Say Y here to build I2C interface to support Sensirion SGP40 gas
sensor
To compile this driver as module, choose M here: the
module will be called sgp40.
config SPS30
tristate
select IIO_BUFFER
+1
View File
@@ -16,6 +16,7 @@ obj-$(CONFIG_SCD30_CORE) += scd30_core.o
obj-$(CONFIG_SCD30_I2C) += scd30_i2c.o
obj-$(CONFIG_SCD30_SERIAL) += scd30_serial.o
obj-$(CONFIG_SENSIRION_SGP30) += sgp30.o
obj-$(CONFIG_SENSIRION_SGP40) += sgp40.o
obj-$(CONFIG_SPS30) += sps30.o
obj-$(CONFIG_SPS30_I2C) += sps30_i2c.o
obj-$(CONFIG_SPS30_SERIAL) += sps30_serial.o
+378
View File
@@ -0,0 +1,378 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* sgp40.c - Support for Sensirion SGP40 Gas Sensor
*
* Copyright (C) 2021 Andreas Klinger <ak@it-klinger.de>
*
* I2C slave address: 0x59
*
* Datasheet can be found here:
* https://www.sensirion.com/file/datasheet_sgp40
*
* There are two functionalities supported:
*
* 1) read raw logarithmic resistance value from sensor
* --> useful to pass it to the algorithm of the sensor vendor for
* measuring deteriorations and improvements of air quality.
*
* 2) calculate an estimated absolute voc index (0 - 500 index points) for
* measuring the air quality.
* For this purpose the value of the resistance for which the voc index
* will be 250 can be set up using calibbias.
*
* Compensation values of relative humidity and temperature can be set up
* by writing to the out values of temp and humidityrelative.
*/
#include <linux/delay.h>
#include <linux/crc8.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/i2c.h>
#include <linux/iio/iio.h>
/*
* floating point calculation of voc is done as integer
* where numbers are multiplied by 1 << SGP40_CALC_POWER
*/
#define SGP40_CALC_POWER 14
#define SGP40_CRC8_POLYNOMIAL 0x31
#define SGP40_CRC8_INIT 0xff
DECLARE_CRC8_TABLE(sgp40_crc8_table);
struct sgp40_data {
struct device *dev;
struct i2c_client *client;
int rht;
int temp;
int res_calibbias;
/* Prevent concurrent access to rht, tmp, calibbias */
struct mutex lock;
};
struct sgp40_tg_measure {
u8 command[2];
__be16 rht_ticks;
u8 rht_crc;
__be16 temp_ticks;
u8 temp_crc;
} __packed;
struct sgp40_tg_result {
__be16 res_ticks;
u8 res_crc;
} __packed;
static const struct iio_chan_spec sgp40_channels[] = {
{
.type = IIO_CONCENTRATION,
.channel2 = IIO_MOD_VOC,
.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
},
{
.type = IIO_RESISTANCE,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_CALIBBIAS),
},
{
.type = IIO_TEMP,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
.output = 1,
},
{
.type = IIO_HUMIDITYRELATIVE,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
.output = 1,
},
};
/*
* taylor approximation of e^x:
* y = 1 + x + x^2 / 2 + x^3 / 6 + x^4 / 24 + ... + x^n / n!
*
* Because we are calculating x real value multiplied by 2^power we get
* an additional 2^power^n to divide for every element. For a reasonable
* precision this would overflow after a few iterations. Therefore we
* divide the x^n part whenever its about to overflow (xmax).
*/
static u32 sgp40_exp(int exp, u32 power, u32 rounds)
{
u32 x, y, xp;
u32 factorial, divider, xmax;
int sign = 1;
int i;
if (exp == 0)
return 1 << power;
else if (exp < 0) {
sign = -1;
exp *= -1;
}
xmax = 0x7FFFFFFF / exp;
x = exp;
xp = 1;
factorial = 1;
y = 1 << power;
divider = 0;
for (i = 1; i <= rounds; i++) {
xp *= x;
factorial *= i;
y += (xp >> divider) / factorial;
divider += power;
/* divide when next multiplication would overflow */
if (xp >= xmax) {
xp >>= power;
divider -= power;
}
}
if (sign == -1)
return (1 << (power * 2)) / y;
else
return y;
}
static int sgp40_calc_voc(struct sgp40_data *data, u16 resistance_raw, int *voc)
{
int x;
u32 exp = 0;
/* we calculate as a multiple of 16384 (2^14) */
mutex_lock(&data->lock);
x = ((int)resistance_raw - data->res_calibbias) * 106;
mutex_unlock(&data->lock);
/* voc = 500 / (1 + e^x) */
exp = sgp40_exp(x, SGP40_CALC_POWER, 18);
*voc = 500 * ((1 << (SGP40_CALC_POWER * 2)) / ((1<<SGP40_CALC_POWER) + exp));
dev_dbg(data->dev, "raw: %d res_calibbias: %d x: %d exp: %d voc: %d\n",
resistance_raw, data->res_calibbias, x, exp, *voc);
return 0;
}
static int sgp40_measure_resistance_raw(struct sgp40_data *data, u16 *resistance_raw)
{
int ret;
struct i2c_client *client = data->client;
u32 ticks;
u16 ticks16;
u8 crc;
struct sgp40_tg_measure tg = {.command = {0x26, 0x0F}};
struct sgp40_tg_result tgres;
mutex_lock(&data->lock);
ticks = (data->rht / 10) * 65535 / 10000;
ticks16 = (u16)clamp(ticks, 0u, 65535u); /* clamp between 0 .. 100 %rH */
tg.rht_ticks = cpu_to_be16(ticks16);
tg.rht_crc = crc8(sgp40_crc8_table, (u8 *)&tg.rht_ticks, 2, SGP40_CRC8_INIT);
ticks = ((data->temp + 45000) / 10 ) * 65535 / 17500;
ticks16 = (u16)clamp(ticks, 0u, 65535u); /* clamp between -45 .. +130 °C */
tg.temp_ticks = cpu_to_be16(ticks16);
tg.temp_crc = crc8(sgp40_crc8_table, (u8 *)&tg.temp_ticks, 2, SGP40_CRC8_INIT);
mutex_unlock(&data->lock);
ret = i2c_master_send(client, (const char *)&tg, sizeof(tg));
if (ret != sizeof(tg)) {
dev_warn(data->dev, "i2c_master_send ret: %d sizeof: %zu\n", ret, sizeof(tg));
return -EIO;
}
msleep(30);
ret = i2c_master_recv(client, (u8 *)&tgres, sizeof(tgres));
if (ret < 0)
return ret;
if (ret != sizeof(tgres)) {
dev_warn(data->dev, "i2c_master_recv ret: %d sizeof: %zu\n", ret, sizeof(tgres));
return -EIO;
}
crc = crc8(sgp40_crc8_table, (u8 *)&tgres.res_ticks, 2, SGP40_CRC8_INIT);
if (crc != tgres.res_crc) {
dev_err(data->dev, "CRC error while measure-raw\n");
return -EIO;
}
*resistance_raw = be16_to_cpu(tgres.res_ticks);
return 0;
}
static int sgp40_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan, int *val,
int *val2, long mask)
{
struct sgp40_data *data = iio_priv(indio_dev);
int ret, voc;
u16 resistance_raw;
switch (mask) {
case IIO_CHAN_INFO_RAW:
switch (chan->type) {
case IIO_RESISTANCE:
ret = sgp40_measure_resistance_raw(data, &resistance_raw);
if (ret)
return ret;
*val = resistance_raw;
return IIO_VAL_INT;
case IIO_TEMP:
mutex_lock(&data->lock);
*val = data->temp;
mutex_unlock(&data->lock);
return IIO_VAL_INT;
case IIO_HUMIDITYRELATIVE:
mutex_lock(&data->lock);
*val = data->rht;
mutex_unlock(&data->lock);
return IIO_VAL_INT;
default:
return -EINVAL;
}
case IIO_CHAN_INFO_PROCESSED:
ret = sgp40_measure_resistance_raw(data, &resistance_raw);
if (ret)
return ret;
ret = sgp40_calc_voc(data, resistance_raw, &voc);
if (ret)
return ret;
*val = voc / (1 << SGP40_CALC_POWER);
/*
* calculation should fit into integer, where:
* voc <= (500 * 2^SGP40_CALC_POWER) = 8192000
* (with SGP40_CALC_POWER = 14)
*/
*val2 = ((voc % (1 << SGP40_CALC_POWER)) * 244) / (1 << (SGP40_CALC_POWER - 12));
dev_dbg(data->dev, "voc: %d val: %d.%06d\n", voc, *val, *val2);
return IIO_VAL_INT_PLUS_MICRO;
case IIO_CHAN_INFO_CALIBBIAS:
mutex_lock(&data->lock);
*val = data->res_calibbias;
mutex_unlock(&data->lock);
return IIO_VAL_INT;
default:
return -EINVAL;
}
}
static int sgp40_write_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan, int val,
int val2, long mask)
{
struct sgp40_data *data = iio_priv(indio_dev);
switch (mask) {
case IIO_CHAN_INFO_RAW:
switch (chan->type) {
case IIO_TEMP:
if ((val < -45000) || (val > 130000))
return -EINVAL;
mutex_lock(&data->lock);
data->temp = val;
mutex_unlock(&data->lock);
return 0;
case IIO_HUMIDITYRELATIVE:
if ((val < 0) || (val > 100000))
return -EINVAL;
mutex_lock(&data->lock);
data->rht = val;
mutex_unlock(&data->lock);
return 0;
default:
return -EINVAL;
}
case IIO_CHAN_INFO_CALIBBIAS:
if ((val < 20000) || (val > 52768))
return -EINVAL;
mutex_lock(&data->lock);
data->res_calibbias = val;
mutex_unlock(&data->lock);
return 0;
}
return -EINVAL;
}
static const struct iio_info sgp40_info = {
.read_raw = sgp40_read_raw,
.write_raw = sgp40_write_raw,
};
static int sgp40_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct device *dev = &client->dev;
struct iio_dev *indio_dev;
struct sgp40_data *data;
int ret;
indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
if (!indio_dev)
return -ENOMEM;
data = iio_priv(indio_dev);
data->client = client;
data->dev = dev;
crc8_populate_msb(sgp40_crc8_table, SGP40_CRC8_POLYNOMIAL);
mutex_init(&data->lock);
/* set default values */
data->rht = 50000; /* 50 % */
data->temp = 25000; /* 25 °C */
data->res_calibbias = 30000; /* resistance raw value for voc index of 250 */
indio_dev->info = &sgp40_info;
indio_dev->name = id->name;
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->channels = sgp40_channels;
indio_dev->num_channels = ARRAY_SIZE(sgp40_channels);
ret = devm_iio_device_register(dev, indio_dev);
if (ret)
dev_err(dev, "failed to register iio device\n");
return ret;
}
static const struct i2c_device_id sgp40_id[] = {
{ "sgp40" },
{ }
};
MODULE_DEVICE_TABLE(i2c, sgp40_id);
static const struct of_device_id sgp40_dt_ids[] = {
{ .compatible = "sensirion,sgp40" },
{ }
};
MODULE_DEVICE_TABLE(of, sgp40_dt_ids);
static struct i2c_driver sgp40_driver = {
.driver = {
.name = "sgp40",
.of_match_table = sgp40_dt_ids,
},
.probe = sgp40_probe,
.id_table = sgp40_id,
};
module_i2c_driver(sgp40_driver);
MODULE_AUTHOR("Andreas Klinger <ak@it-klinger.de>");
MODULE_DESCRIPTION("Sensirion SGP40 gas sensor");
MODULE_LICENSE("GPL v2");
@@ -9,13 +9,11 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/iio/iio.h>
#include <linux/iio/trigger.h>
#include <linux/interrupt.h>
#include <linux/iio/buffer.h>
#include <linux/iio/trigger_consumer.h>
#include <linux/iio/triggered_buffer.h>
#include <linux/irqreturn.h>
#include <linux/regmap.h>
@@ -12,6 +12,7 @@
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/iio/iio.h>
#include <linux/mutex.h>
#include <linux/property.h>
#include <linux/regulator/consumer.h>
#include <linux/regmap.h>
@@ -4,6 +4,7 @@
*/
#ifndef __ST_SENSORS_CORE_H
#define __ST_SENSORS_CORE_H
struct iio_dev;
int st_sensors_write_data_with_mask(struct iio_dev *indio_dev,
u8 reg_addr, u8 mask, u8 data);
#endif
@@ -7,15 +7,14 @@
* Denis Ciocca <denis.ciocca@st.com>
*/
#include <linux/i2c.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/iio/iio.h>
#include <linux/regmap.h>
#include <linux/iio/common/st_sensors_i2c.h>
#define ST_SENSORS_I2C_MULTIREAD 0x80
static const struct regmap_config st_sensors_i2c_regmap_config = {
@@ -9,13 +9,12 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/iio/iio.h>
#include <linux/property.h>
#include <linux/regmap.h>
#include <linux/spi/spi.h>
#include <linux/iio/common/st_sensors_spi.h>
#include "st_sensors_core.h"
#define ST_SENSORS_SPI_MULTIREAD 0xc0
@@ -9,7 +9,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/iio/iio.h>
#include <linux/iio/trigger.h>
#include <linux/interrupt.h>
+17 -1
View File
@@ -229,7 +229,7 @@ static int ad5624r_probe(struct spi_device *spi)
if (!indio_dev)
return -ENOMEM;
st = iio_priv(indio_dev);
st->reg = devm_regulator_get(&spi->dev, "vcc");
st->reg = devm_regulator_get_optional(&spi->dev, "vref");
if (!IS_ERR(st->reg)) {
ret = regulator_enable(st->reg);
if (ret)
@@ -240,6 +240,22 @@ static int ad5624r_probe(struct spi_device *spi)
goto error_disable_reg;
voltage_uv = ret;
} else {
if (PTR_ERR(st->reg) != -ENODEV)
return PTR_ERR(st->reg);
/* Backwards compatibility. This naming is not correct */
st->reg = devm_regulator_get_optional(&spi->dev, "vcc");
if (!IS_ERR(st->reg)) {
ret = regulator_enable(st->reg);
if (ret)
return ret;
ret = regulator_get_voltage(st->reg);
if (ret < 0)
goto error_disable_reg;
voltage_uv = ret;
}
}
spi_set_drvdata(spi, indio_dev);
+17 -24
View File
@@ -294,6 +294,11 @@ static const struct iio_info max5821_info = {
.write_raw = max5821_write_raw,
};
static void max5821_regulator_disable(void *reg)
{
regulator_disable(reg);
}
static int max5821_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
@@ -306,7 +311,6 @@ static int max5821_probe(struct i2c_client *client,
if (!indio_dev)
return -ENOMEM;
data = iio_priv(indio_dev);
i2c_set_clientdata(client, indio_dev);
data->client = client;
mutex_init(&data->lock);
@@ -321,21 +325,29 @@ static int max5821_probe(struct i2c_client *client,
ret = PTR_ERR(data->vref_reg);
dev_err(&client->dev,
"Failed to get vref regulator: %d\n", ret);
goto error_free_reg;
return ret;
}
ret = regulator_enable(data->vref_reg);
if (ret) {
dev_err(&client->dev,
"Failed to enable vref regulator: %d\n", ret);
goto error_free_reg;
return ret;
}
ret = devm_add_action_or_reset(&client->dev, max5821_regulator_disable,
data->vref_reg);
if (ret) {
dev_err(&client->dev,
"Failed to add action to managed regulator: %d\n", ret);
return ret;
}
ret = regulator_get_voltage(data->vref_reg);
if (ret < 0) {
dev_err(&client->dev,
"Failed to get voltage on regulator: %d\n", ret);
goto error_disable_reg;
return ret;
}
data->vref_mv = ret / 1000;
@@ -346,25 +358,7 @@ static int max5821_probe(struct i2c_client *client,
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->info = &max5821_info;
return iio_device_register(indio_dev);
error_disable_reg:
regulator_disable(data->vref_reg);
error_free_reg:
return ret;
}
static int max5821_remove(struct i2c_client *client)
{
struct iio_dev *indio_dev = i2c_get_clientdata(client);
struct max5821_data *data = iio_priv(indio_dev);
iio_device_unregister(indio_dev);
regulator_disable(data->vref_reg);
return 0;
return devm_iio_device_register(&client->dev, indio_dev);
}
static const struct i2c_device_id max5821_id[] = {
@@ -386,7 +380,6 @@ static struct i2c_driver max5821_driver = {
.pm = &max5821_pm_ops,
},
.probe = max5821_probe,
.remove = max5821_remove,
.id_table = max5821_id,
};
module_i2c_driver(max5821_driver);
+4 -7
View File
@@ -303,8 +303,8 @@ static int hid_gyro_3d_probe(struct platform_device *pdev)
return ret;
}
indio_dev->channels = kmemdup(gyro_3d_channels,
sizeof(gyro_3d_channels), GFP_KERNEL);
indio_dev->channels = devm_kmemdup(&pdev->dev, gyro_3d_channels,
sizeof(gyro_3d_channels), GFP_KERNEL);
if (!indio_dev->channels) {
dev_err(&pdev->dev, "failed to duplicate channels\n");
return -ENOMEM;
@@ -315,7 +315,7 @@ static int hid_gyro_3d_probe(struct platform_device *pdev)
HID_USAGE_SENSOR_GYRO_3D, gyro_state);
if (ret) {
dev_err(&pdev->dev, "failed to setup attributes\n");
goto error_free_dev_mem;
return ret;
}
indio_dev->num_channels = ARRAY_SIZE(gyro_3d_channels);
@@ -329,7 +329,7 @@ static int hid_gyro_3d_probe(struct platform_device *pdev)
&gyro_state->common_attributes);
if (ret < 0) {
dev_err(&pdev->dev, "trigger setup failed\n");
goto error_free_dev_mem;
return ret;
}
ret = iio_device_register(indio_dev);
@@ -354,8 +354,6 @@ error_iio_unreg:
iio_device_unregister(indio_dev);
error_remove_trigger:
hid_sensor_remove_trigger(indio_dev, &gyro_state->common_attributes);
error_free_dev_mem:
kfree(indio_dev->channels);
return ret;
}
@@ -369,7 +367,6 @@ static int hid_gyro_3d_remove(struct platform_device *pdev)
sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_GYRO_3D);
iio_device_unregister(indio_dev);
hid_sensor_remove_trigger(indio_dev, &gyro_state->common_attributes);
kfree(indio_dev->channels);
return 0;
}
-4
View File
@@ -26,7 +26,6 @@
#ifdef CONFIG_IIO_BUFFER
int st_gyro_allocate_ring(struct iio_dev *indio_dev);
void st_gyro_deallocate_ring(struct iio_dev *indio_dev);
int st_gyro_trig_set_state(struct iio_trigger *trig, bool state);
#define ST_GYRO_TRIGGER_SET_STATE (&st_gyro_trig_set_state)
#else /* CONFIG_IIO_BUFFER */
@@ -34,9 +33,6 @@ static inline int st_gyro_allocate_ring(struct iio_dev *indio_dev)
{
return 0;
}
static inline void st_gyro_deallocate_ring(struct iio_dev *indio_dev)
{
}
#define ST_GYRO_TRIGGER_SET_STATE NULL
#endif /* CONFIG_IIO_BUFFER */
+3 -13
View File
@@ -9,14 +9,9 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/stat.h>
#include <linux/interrupt.h>
#include <linux/i2c.h>
#include <linux/delay.h>
#include <linux/iio/iio.h>
#include <linux/iio/buffer.h>
#include <linux/iio/trigger_consumer.h>
#include <linux/iio/trigger.h>
#include <linux/iio/triggered_buffer.h>
#include <linux/iio/common/st_sensors.h>
@@ -66,13 +61,8 @@ static const struct iio_buffer_setup_ops st_gyro_buffer_setup_ops = {
int st_gyro_allocate_ring(struct iio_dev *indio_dev)
{
return iio_triggered_buffer_setup(indio_dev, NULL,
&st_sensors_trigger_handler, &st_gyro_buffer_setup_ops);
}
void st_gyro_deallocate_ring(struct iio_dev *indio_dev)
{
iio_triggered_buffer_cleanup(indio_dev);
return devm_iio_triggered_buffer_setup(indio_dev->dev.parent, indio_dev,
NULL, &st_sensors_trigger_handler, &st_gyro_buffer_setup_ops);
}
MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
+3 -12
View File
@@ -9,17 +9,12 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/mutex.h>
#include <linux/interrupt.h>
#include <linux/i2c.h>
#include <linux/irq.h>
#include <linux/delay.h>
#include <linux/sysfs.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/iio/trigger.h>
#include <linux/iio/buffer.h>
#include <linux/iio/common/st_sensors.h>
#include "st_gyro.h"
@@ -517,7 +512,7 @@ int st_gyro_common_probe(struct iio_dev *indio_dev)
err = st_sensors_allocate_trigger(indio_dev,
ST_GYRO_TRIGGER_OPS);
if (err < 0)
goto st_gyro_probe_trigger_error;
return err;
}
err = iio_device_register(indio_dev);
@@ -532,8 +527,6 @@ int st_gyro_common_probe(struct iio_dev *indio_dev)
st_gyro_device_register_error:
if (gdata->irq > 0)
st_sensors_deallocate_trigger(indio_dev);
st_gyro_probe_trigger_error:
st_gyro_deallocate_ring(indio_dev);
return err;
}
EXPORT_SYMBOL(st_gyro_common_probe);
@@ -545,8 +538,6 @@ void st_gyro_common_remove(struct iio_dev *indio_dev)
iio_device_unregister(indio_dev);
if (gdata->irq > 0)
st_sensors_deallocate_trigger(indio_dev);
st_gyro_deallocate_ring(indio_dev);
}
EXPORT_SYMBOL(st_gyro_common_remove);

Some files were not shown because too many files have changed in this diff Show More