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:
@@ -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>;
|
||||
};
|
||||
};
|
||||
...
|
||||
+17
-14
@@ -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
|
||||
|
||||
@@ -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
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
@@ -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[] = {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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_ */
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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" },
|
||||
{ },
|
||||
};
|
||||
|
||||
@@ -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"},
|
||||
{}
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
|
||||
@@ -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
@@ -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,
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
@@ -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>");
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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, },
|
||||
{ },
|
||||
};
|
||||
|
||||
@@ -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",
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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");
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
@@ -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>");
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user