Merge tag 'char-misc-7.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc

Pull Char/Misc/IIO/others driver updates from Greg KH:
 "Here is the big set of char/misc/android/iio and other small driver
  subsystem patches for 7.4-rc1. Loads of stuff in here, larger than
  normal. Highlights include:

   - removal of the C binder code, the rust version is stable and will
     be used going forward in a few billion devices. Great job by those
     developers

   - loads and loads of IIO driver updates and feature additions

   - speakup driver fixes and updates

   - mhi driver updates

   - mei driver updates

   - xillybus driver fixes

   - comedi driver fixes

   - lots of coresight driver updates

   - Interconnect driver updates

   - nvmem driver updates and fixes

   - slimbus driver updates and fixes

   - spmi driver updates and fixes

   - lots of tiny misc and char driver fixes based on people scanning
     for things

  All of these have been in linux-next for a while with no reported
  issues, other than a merge conflict with one of the rust tree files,
  which should be simple to resolve"

* tag 'char-misc-7.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (446 commits)
  rust_binder: wake epoll on self-work queued to poll thread
  rust_binder: avoid overflow in get_node_debug_info()
  MAINTAINERS: Add Abel as SPMI co-maintainer
  spmi: mtk-pmif: Fix clock reference leak in mtk_spmi_bus_probe()
  iio: adc: qcom-spmi-iadc: Remove regmap R/W wrapper functions
  iio: adc: qcom-spmi-iadc: Migrate to devm_spmi_subdevice_alloc_and_add()
  misc: qcom-coincell: Migrate to devm_spmi_subdevice_alloc_and_add()
  phy: qualcomm: eusb2-repeater: Migrate to devm_spmi_subdevice_alloc_and_add()
  power: reset: qcom-pon: Migrate to devm_spmi_subdevice_alloc_and_add()
  nvmem: qcom-spmi-sdam: Migrate to devm_spmi_subdevice_alloc_and_add()
  spmi: Add helper to get a parent SPMI device
  spmi: Implement spmi_subdevice_alloc_and_add() and devm variant
  spmi: Remove unneeded goto in spmi_device_add() error path
  spmi: Print error status with %pe format
  spmi: Remove redundant dev_name() print in spmi_device_add()
  spmi: Fix potential use-after-free by grabbing of_node reference
  spmi: mtk-pmif: Add workaround for FSM lockup/error in read operation
  MAINTAINERS: Add Qualcomm SPMI controller entry
  spmi: pmic-arb: return 0 in spmi_pmic_arb_register_buses() on success
  comedi: addi_apci_3xxx: fix subdevice count underallocation
  ...
This commit is contained in:
Linus Torvalds committed 2026-10-24 15:44:26 -10:00
commit 330517c63a
413 files changed
+22425 -16139

No files matched your search

@@ -0,0 +1,23 @@
What: /sys/kernel/debug/iio/iio:deviceX/frequency_source
KernelVersion: 7.3
Contact: linux-iio@vger.kernel.org
Description:
Read-only. Reports the channel label that is read from the
<dir>_<type>[Y]_label attribute, which corresponds to the on-chip
signal generator that is currently driving the output frequency.
What: /sys/kernel/debug/iio/iio:deviceX/phase_source
KernelVersion: 7.3
Contact: linux-iio@vger.kernel.org
Description:
Read-only. Reports the channel label that is read from the
<dir>_<type>[Y]_label attribute, which corresponds to the on-chip
signal generator that is currently driving the output phase.
What: /sys/kernel/debug/iio/iio:deviceX/amplitude_source
KernelVersion: 7.3
Contact: linux-iio@vger.kernel.org
Description:
Read-only. Reports the channel label that is read from the
<dir>_<type>[Y]_label attribute, which corresponds to the on-chip
signal generator that is currently driving the output amplitude.
@@ -8,13 +8,13 @@ What: /sys/kernel/debug/iio/iio:deviceX/backendY/direct_reg_access
KernelVersion: 6.11
Contact: linux-iio@vger.kernel.org
Description:
Directly access the registers of backend Y. Typical usage is:
Directly access the registers of backend Y. Typical usage is::
Reading address 0x50
echo 0x50 > direct_reg_access
cat direct_reg_access
# Reading address 0x50
echo 0x50 > direct_reg_access
cat direct_reg_access
Writing address 0x50
echo 0x50 0x3 > direct_reg_access
//readback address 0x50
cat direct_reg_access
# Writing address 0x50
echo 0x50 0x3 > direct_reg_access
# readback address 0x50
cat direct_reg_access
+115
View File
@@ -442,6 +442,14 @@ What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_i_offset
What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_q_offset
What: /sys/bus/iio/devices/iio:deviceX/in_currentY_offset
What: /sys/bus/iio/devices/iio:deviceX/in_current_offset
What: /sys/bus/iio/devices/iio:deviceX/in_phaseY_offset
What: /sys/bus/iio/devices/iio:deviceX/in_phase_offset
What: /sys/bus/iio/devices/iio:deviceX/out_phaseY_offset
What: /sys/bus/iio/devices/iio:deviceX/out_phase_offset
What: /sys/bus/iio/devices/iio:deviceX/in_frequencyY_offset
What: /sys/bus/iio/devices/iio:deviceX/in_frequency_offset
What: /sys/bus/iio/devices/iio:deviceX/out_frequencyY_offset
What: /sys/bus/iio/devices/iio:deviceX/out_frequency_offset
What: /sys/bus/iio/devices/iio:deviceX/in_tempY_offset
What: /sys/bus/iio/devices/iio:deviceX/in_temp_offset
What: /sys/bus/iio/devices/iio:deviceX/in_pressureY_offset
@@ -475,10 +483,22 @@ What: /sys/bus/iio/devices/iio:deviceX/in_voltage_scale
What: /sys/bus/iio/devices/iio:deviceX/in_voltage-voltage_scale
What: /sys/bus/iio/devices/iio:deviceX/out_voltageY_scale
What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY_scale
What: /sys/bus/iio/devices/iio:deviceX/in_phaseY_scale
What: /sys/bus/iio/devices/iio:deviceX/in_phase_scale
What: /sys/bus/iio/devices/iio:deviceX/out_phaseY_scale
What: /sys/bus/iio/devices/iio:deviceX/out_phase_scale
What: /sys/bus/iio/devices/iio:deviceX/in_frequencyY_scale
What: /sys/bus/iio/devices/iio:deviceX/in_frequency_scale
What: /sys/bus/iio/devices/iio:deviceX/out_frequencyY_scale
What: /sys/bus/iio/devices/iio:deviceX/out_frequency_scale
What: /sys/bus/iio/devices/iio:deviceX/in_currentY_scale
What: /sys/bus/iio/devices/iio:deviceX/in_currentY_supply_scale
What: /sys/bus/iio/devices/iio:deviceX/in_current_scale
What: /sys/bus/iio/devices/iio:deviceX/in_current_q_scale
What: /sys/bus/iio/devices/iio:deviceX/in_altcurrentY_scale
What: /sys/bus/iio/devices/iio:deviceX/in_altcurrent_scale
What: /sys/bus/iio/devices/iio:deviceX/out_altcurrentY_scale
What: /sys/bus/iio/devices/iio:deviceX/out_altcurrent_scale
What: /sys/bus/iio/devices/iio:deviceX/in_accel_scale
What: /sys/bus/iio/devices/iio:deviceX/in_accel_peak_scale
What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_scale
@@ -507,6 +527,7 @@ What: /sys/bus/iio/devices/iio:deviceX/in_intensity_z_scale
What: /sys/bus/iio/devices/iio:deviceX/in_intensity_red_scale
What: /sys/bus/iio/devices/iio:deviceX/in_intensity_green_scale
What: /sys/bus/iio/devices/iio:deviceX/in_intensity_blue_scale
What: /sys/bus/iio/devices/iio:deviceX/in_intensity_clear_scale
What: /sys/bus/iio/devices/iio:deviceX/in_concentration_co2_scale
What: /sys/bus/iio/devices/iio:deviceX/in_volumeflow_scale
What: /sys/bus/iio/devices/iio:deviceX/in_volumeflowY_scale
@@ -762,6 +783,8 @@ What: /sys/bus/iio/devices/iio:deviceX/out_voltageY_powerdown_mode
What: /sys/bus/iio/devices/iio:deviceX/out_voltage_powerdown_mode
What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY_powerdown_mode
What: /sys/bus/iio/devices/iio:deviceX/out_altvoltage_powerdown_mode
What: /sys/bus/iio/devices/iio:deviceX/out_currentY_powerdown_mode
What: /sys/bus/iio/devices/iio:deviceX/out_current_powerdown_mode
KernelVersion: 2.6.38
Contact: linux-iio@vger.kernel.org
Description:
@@ -774,6 +797,7 @@ Description:
6kohm_to_gnd: connected to ground via a 6kOhm resistor,
7.7kohm_to_gnd: connected to ground via a 7.7kOhm resistor,
10kohm_to_gnd: connected to ground via a 10kOhm resistor,
15kohm_to_gnd: connected to ground via a 15kOhm resistor,
16kohm_to_gnd: connected to ground via a 16kOhm resistor,
20kohm_to_gnd: connected to ground via a 20kOhm resistor,
32kohm_to_gnd: connected to ground via a 32kOhm resistor,
@@ -802,6 +826,10 @@ What: /sys/bus/iio/devices/iio:deviceX/out_voltageY_powerdown
What: /sys/bus/iio/devices/iio:deviceX/out_voltage_powerdown
What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY_powerdown
What: /sys/bus/iio/devices/iio:deviceX/out_altvoltage_powerdown
What: /sys/bus/iio/devices/iio:deviceX/out_currentY_powerdown
What: /sys/bus/iio/devices/iio:deviceX/out_current_powerdown
What: /sys/bus/iio/devices/iio:deviceX/out_altcurrentY_powerdown
What: /sys/bus/iio/devices/iio:deviceX/out_altcurrent_powerdown
KernelVersion: 2.6.38
Contact: linux-iio@vger.kernel.org
Description:
@@ -812,6 +840,7 @@ Description:
together.
What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY_frequency
What: /sys/bus/iio/devices/iio:deviceX/out_altcurrentY_frequency
KernelVersion: 3.4.0
Contact: linux-iio@vger.kernel.org
Description:
@@ -838,8 +867,10 @@ Description:
all the other channels, since it involves changing the VCO
fundamental output frequency.
What: /sys/bus/iio/devices/iio:deviceX/in_altcurrentY_phase
What: /sys/bus/iio/devices/iio:deviceX/in_altvoltageY_i_phase
What: /sys/bus/iio/devices/iio:deviceX/in_altvoltageY_q_phase
What: /sys/bus/iio/devices/iio:deviceX/out_altcurrentY_phase
What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY_phase
What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY_i_phase
What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY_q_phase
@@ -853,6 +884,7 @@ Description:
channel.
What: /sys/bus/iio/devices/iio:deviceX/out_currentY_raw
What: /sys/bus/iio/devices/iio:deviceX/out_altcurrentY_raw
Date: May 2012
KernelVersion: 3.5
Contact: Johan Hovold <jhovold@gmail.com>
@@ -1739,6 +1771,7 @@ Description:
What: /sys/bus/iio/devices/iio:deviceX/in_currentY_raw
What: /sys/bus/iio/devices/iio:deviceX/in_currentY_supply_raw
What: /sys/bus/iio/devices/iio:deviceX/in_altcurrentY_raw
KernelVersion: 3.17
Contact: linux-iio@vger.kernel.org
Description:
@@ -2129,7 +2162,9 @@ Description:
Raw counter device counters direction for channel Y.
What: /sys/bus/iio/devices/iio:deviceX/in_altcurrentY_label
What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_label
What: /sys/bus/iio/devices/iio:deviceX/out_altcurrentY_label
What: /sys/bus/iio/devices/iio:deviceX/out_voltageY_label
KernelVersion: 5.8
Contact: linux-iio@vger.kernel.org
@@ -2139,6 +2174,50 @@ Description:
specific attributes. This is useful for userspace to be able to
better identify an individual channel.
What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_parent
What: /sys/bus/iio/devices/iio:deviceX/out_voltageY_parent
What: /sys/bus/iio/devices/iio:deviceX/in_altvoltageY_parent
What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY_parent
What: /sys/bus/iio/devices/iio:deviceX/in_currentY_parent
What: /sys/bus/iio/devices/iio:deviceX/out_currentY_parent
What: /sys/bus/iio/devices/iio:deviceX/in_altcurrentY_parent
What: /sys/bus/iio/devices/iio:deviceX/out_altcurrentY_parent
KernelVersion: 7.3
Contact: linux-iio@vger.kernel.org
Description:
Read-only attribute containing the sysfs name prefix of the parent
channel for hierarchical channel relationships (e.g. "out_altvoltage0").
The prefix uniquely identifies the parent channel and can be used by
userspace to organize channels in tree-like structures that reflects
virtual or logical relationships between them.
For example, an IIO device may expose a primary output channel as
"out_voltage0" together with a set of profile-based or mode-based
subchannels used to configure or compose the output signal. These
subchannels may carry common attributes such as frequency, phase, etc.
They do not represent physical outputs, but rather logical/virtual
channels grouping configurations that affect the primary output.
Each subchannel exposes a <dir>_<type>[Y]_parent attribute reading
"out_voltage0", allowing userspace to group controls under the output
channel they belong to rather than treating them as unrelated top-level
channels.
What: /sys/bus/iio/devices/iio:deviceX/in_frequencyY_raw
KernelVersion: 7.3
Contact: linux-iio@vger.kernel.org
Description:
Raw (unscaled) frequency reading from channel Y.
Units after application of scale and offset are Hz.
What: /sys/bus/iio/devices/iio:deviceX/out_frequencyY_raw
KernelVersion: 7.3
Contact: linux-iio@vger.kernel.org
Description:
Raw (unscaled, no bias etc.) output frequency for channel Y.
The number must always be specified and unique if the output
corresponds to a single channel. Units after application of
scale and offset are Hz.
What: /sys/bus/iio/devices/iio:deviceX/in_phaseY_raw
KernelVersion: 4.18
Contact: linux-iio@vger.kernel.org
@@ -2146,6 +2225,15 @@ Description:
Raw (unscaled) phase difference reading from channel Y.
Units after application of scale and offset are radians.
What: /sys/bus/iio/devices/iio:deviceX/out_phaseY_raw
KernelVersion: 7.3
Contact: linux-iio@vger.kernel.org
Description:
Raw (unscaled, no bias etc.) output phase for channel Y.
The number must always be specified and unique if the output
corresponds to a single channel. Units after application of
scale and offset are radians.
What: /sys/bus/iio/devices/iio:deviceX/in_massconcentration_pm1_input
What: /sys/bus/iio/devices/iio:deviceX/in_massconcentrationY_pm1_input
What: /sys/bus/iio/devices/iio:deviceX/in_massconcentration_pm2p5_input
@@ -2380,6 +2468,7 @@ Description:
* "sinc4+lp" - Sinc4 + Low Pass Filter.
* "sinc4+sinc1" - Sinc4 + averaging by 8. Low 1st conversion
time.
* "sinc4+sinc1+pf1" - Sinc4 + Sinc1 + device specific Post Filter 1.
* "sinc4+rej60" - Sinc4 + 60Hz rejection.
* "sinc5" - The digital sinc5 filter. Excellent noise
performance
@@ -2401,6 +2490,32 @@ Description:
Specifies which filter type apply to the channel. The possible
values are given by the filter_type_available attribute.
What: /sys/bus/iio/devices/iio:deviceX/in_resistanceY_settlingtime
What: /sys/bus/iio/devices/iio:deviceX/in_tempY_settlingtime
What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_settlingtime
What: /sys/bus/iio/devices/iio:deviceX/in_voltageY-voltageZ_settlingtime
KernelVersion: 7.4
Contact: linux-iio@vger.kernel.org
Description:
Set/read total settling time in seconds for a device to settle
after starting the first conversion after any settings have
changed. The data for the conversion is outputted at the end of
this time.
Depending on the device and how it is used, this settling time
may apply to more than just the first conversion, e.g. to every
conversion in a single-shot conversion mode or when a device
setting changes after each conversion (input chopping).
What: /sys/bus/iio/devices/iio:deviceX/in_resistanceY_settlingtime_available
What: /sys/bus/iio/devices/iio:deviceX/in_tempY_settlingtime_available
What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_settlingtime_available
What: /sys/bus/iio/devices/iio:deviceX/in_voltageY-voltageZ_settlingtime_available
KernelVersion: 7.4
Contact: linux-iio@vger.kernel.org
Description:
Available settlingtime values in IIO range or list format.
What: /sys/.../events/in_proximity_thresh_either_runningperiod
KernelVersion: 6.6
Contact: linux-iio@vger.kernel.org
@@ -0,0 +1,9 @@
What: /sys/bus/iio/devices/iio:deviceX/in_resistanceY_burnoutraw
What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_burnoutraw
What: /sys/bus/iio/devices/iio:deviceX/in_voltageY-voltageZ_burnoutraw
KernelVersion: 7.4
Contact: linux-iio@vger.kernel.org
Description:
Raw value from channel Y read using a single conversion with
the channel burnout current enabled. This is typically used
for diagnostic purposes to detect an open or shorted input.
@@ -0,0 +1,31 @@
What: /sys/bus/iio/devices/iio:deviceX/out_altcurrentY_dwell_en
What: /sys/bus/iio/devices/iio:deviceX/out_frequencyY_dwell_en
What: /sys/bus/iio/devices/iio:deviceX/out_phaseY_dwell_en
KernelVersion: 7.3
Contact: linux-iio@vger.kernel.org
Description:
For a channel that produces parametric sweeps, this attribute controls
the sweep behavior at the configured limit. It enables dwell mode at a
sweep limit when set to 1, i.e., after the sweep is complete the output
value stays at the limit. Otherwise (setting this value to 0), the sweep
may stop or restart from the initial position, or even continue by
reversing the sweep direction.
What: /sys/bus/iio/devices/iio:deviceX/out_altcurrentY_raw_roc
What: /sys/bus/iio/devices/iio:deviceX/out_frequencyY_raw_roc
What: /sys/bus/iio/devices/iio:deviceX/out_phaseY_raw_roc
KernelVersion: 7.3
Contact: linux-iio@vger.kernel.org
Description:
For a channel that produces parametric sweeps, this attribute controls
the rate of change of the parameter in raw units per second (slope).
This value may be influenced by the channel sampling_frequency attribute
if available. Multiplying this value by the scale attribute of the
channel yields the rate of change in physical units per second.
What: /sys/bus/iio/devices/iio:deviceX/out_altcurrentY_raw_roc_available
KernelVersion: 7.3
Contact: linux-iio@vger.kernel.org
Description:
Lists the available roc values for the channel. Values are
space-separated in ascending order.
@@ -0,0 +1,49 @@
What: /sys/bus/mhi/devices/mhi<N>_LOOPBACK/tre_size
Date: August 2026
KernelVersion: 7.4
Contact: mhi@lists.linux.dev
Description:
(RW) Size of each Transfer Ring Element (TRE) buffer in bytes
used for the loopback test. Valid range is 1 to the value
reported by max_tre_size. Default value is 32 bytes.
What: /sys/bus/mhi/devices/mhi<N>_LOOPBACK/max_tre_size
Date: August 2026
KernelVersion: 7.4
Contact: mhi@lists.linux.dev
Description:
(RO) Maximum allowed Transfer Ring Element (TRE) size in bytes.
Reading this file returns the upper bound for the tre_size
attribute.
What: /sys/bus/mhi/devices/mhi<N>_LOOPBACK/num_tre
Date: August 2026
KernelVersion: 7.4
Contact: mhi@lists.linux.dev
Description:
(RW) Number of Transfer Ring Elements (TREs) to use per
loopback test. Must be greater than zero and must not exceed
the value reported by max_num_tre. Default value is 1.
What: /sys/bus/mhi/devices/mhi<N>_LOOPBACK/max_num_tre
Date: August 2026
KernelVersion: 7.4
Contact: mhi@lists.linux.dev
Description:
(RO) Maximum number of Transfer Ring Elements (TREs) currently
available on the channel ring. Reading this file returns the
upper bound for the num_tre attribute.
What: /sys/bus/mhi/devices/mhi<N>_LOOPBACK/start
Date: August 2026
KernelVersion: 7.4
Contact: mhi@lists.linux.dev
Description:
(WO) Write any value to trigger a loopback test. The driver
sends random data to the endpoint using the configured tre_size
and num_tre parameters, waits for the endpoint to echo it back,
and verifies the received data matches what was sent.
This is a blocking write that returns when the test completes
or times out after 5 seconds. The write returns an error code
if the test fails or times out.
@@ -4,21 +4,23 @@
$id: http://devicetree.org/schemas/iio/accel/adi,adis16201.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: ADIS16201 Dual Axis Inclinometer and similar
title: ADIS16201 Inclinometer and similar
maintainers:
- Jonathan Cameron <Jonathan.Cameron@huawei.com>
description: |
Two similar parts from external interface point of view.
Three similar parts from external interface point of view.
SPI interface.
https://www.analog.com/en/products/adis16201.html
https://www.analog.com/en/products/adis16203.html
https://www.analog.com/en/products/adis16209.html
properties:
compatible:
enum:
- adi,adis16201
- adi,adis16203
- adi,adis16209
reg:
@@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
title: Analog Devices ADXL367 3-Axis Digital Accelerometer
maintainers:
- Cosmin Tanislav <cosmin.tanislav@analog.com>
- Antoniu Miclaus <antoniu.miclaus@analog.com>
description: |
The ADXL367 is an ultralow power, 3-axis MEMS accelerometer.
@@ -33,7 +33,14 @@ properties:
maxItems: 1
interrupts:
maxItems: 1
minItems: 1
maxItems: 2
interrupt-names:
minItems: 1
items:
- enum: [INT1, INT2]
- const: INT2
vdd-supply: true
vddio-supply: true
@@ -61,6 +68,7 @@ examples:
reg = <0x53>;
interrupt-parent = <&gpio>;
interrupts = <25 IRQ_TYPE_EDGE_RISING>;
interrupt-names = "INT1";
};
};
- |
@@ -76,5 +84,6 @@ examples:
spi-max-frequency = <1000000>;
interrupt-parent = <&gpio>;
interrupts = <25 IRQ_TYPE_EDGE_RISING>;
interrupt-names = "INT1";
};
};
@@ -41,6 +41,7 @@ properties:
- adi,ad4880
- adi,ad4883
- adi,ad4884
- adi,ad4885
reg:
minItems: 1
@@ -105,6 +106,7 @@ allOf:
- adi,ad4880
- adi,ad4883
- adi,ad4884
- adi,ad4885
then:
properties:
reg:
@@ -127,15 +129,15 @@ examples:
#size-cells = <0>;
adc@0 {
compatible = "adi,ad4080";
reg = <0>;
spi-max-frequency = <10000000>;
vdd33-supply = <&vdd33>;
vddldo-supply = <&vddldo>;
vrefin-supply = <&vrefin>;
clocks = <&cnv>;
clock-names = "cnv";
io-backends = <&iio_backend>;
compatible = "adi,ad4080";
reg = <0>;
spi-max-frequency = <10000000>;
vdd33-supply = <&vdd33>;
vddldo-supply = <&vddldo>;
vrefin-supply = <&vrefin>;
clocks = <&cnv>;
clock-names = "cnv";
io-backends = <&iio_backend>;
};
};
- |
@@ -144,15 +146,15 @@ examples:
#size-cells = <0>;
adc@0 {
compatible = "adi,ad4880";
reg = <0>, <1>;
spi-max-frequency = <10000000>;
vdd33-supply = <&vdd33>;
vddldo-supply = <&vddldo>;
vrefin-supply = <&vrefin>;
clocks = <&cnv>;
clock-names = "cnv";
io-backends = <&iio_backend_cha>, <&iio_backend_chb>;
compatible = "adi,ad4880";
reg = <0>, <1>;
spi-max-frequency = <10000000>;
vdd33-supply = <&vdd33>;
vddldo-supply = <&vddldo>;
vrefin-supply = <&vrefin>;
clocks = <&cnv>;
clock-names = "cnv";
io-backends = <&iio_backend_cha>, <&iio_backend_chb>;
};
};
...
@@ -8,7 +8,8 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
title: Analog Devices AD4130 family ADCs
maintainers:
- Cosmin Tanislav <cosmin.tanislav@analog.com>
- Marcelo Schmitt <marcelo.schmitt@analog.com>
- Antoniu Miclaus <antoniu.miclaus@analog.com>
description: |
Bindings for the Analog Devices AD4130 family ADCs.
@@ -142,13 +142,13 @@ examples:
io-backends = <&iio_backend>;
channel@0 {
reg = <0>;
diff-channels = <0 0>;
bipolar;
reg = <0>;
diff-channels = <0 0>;
bipolar;
};
channel@1 {
reg = <1>;
reg = <1>;
};
};
};
@@ -443,7 +443,7 @@ examples:
#address-cells = <1>;
#size-cells = <0>;
adc@0 {
adc@0 {
compatible = "adi,ad4111";
reg = <0>;
@@ -238,9 +238,9 @@ examples:
};
regulators {
vcm_reg: vcm-output {
regulator-name = "ad7768-1-vcm";
};
vcm_reg: vcm-output {
regulator-name = "ad7768-1-vcm";
};
};
};
};
@@ -0,0 +1,270 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/adc/adi,ad7768.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Analog Devices AD7768 and AD7768-4 ADC
maintainers:
- Janani Sunil <janani.sunil@analog.com>
description: |
The AD7768 is an 8-channel, 24-bit simultaneous sampling ADC with configurable
power and performance modes. The AD7768-4 is a 4-channel version.
This binding covers SPI mode only (register access via SPI). Pin control mode,
where configuration is set via hardware pins rather than SPI registers, is not
supported.
The io-backend represents the high-speed data output interface, consuming the
DOUTx data lines, DCLK (data clock), and DRDY (data ready) signals.
Datasheet at:
https://www.analog.com/media/en/technical-documentation/data-sheets/ad7768-ad7768-4.pdf
HDL reference design:
https://github.com/analogdevicesinc/hdl/tree/main/projects/ad7768evb
properties:
compatible:
enum:
- adi,ad7768
- adi,ad7768-4
reg:
maxItems: 1
clocks:
maxItems: 1
clock-names:
description:
Describes the type of master clock (MCLK) attached to the XTAL1 and
XTAL2/MCLK pins. A CMOS clock is supplied on the XTAL2/MCLK pin, a
crystal oscillator is connected between the XTAL1 and XTAL2 pins, and an
LVDS differential clock is supplied on the XTAL1/XTAL2 pin pair. CMOS and
LVDS clocks must operate from 1.15 MHz to 34 MHz. Crystals must operate
from 8 MHz to 34 MHz.
enum:
- mclk
- xtal
- lvds
avdd1-supply:
description:
Analog supply. Its voltage is used to derive the supply-dependent VCM
output level, so it must be a regulator that can report its voltage.
avss-supply:
description:
Negative analog supply. If omitted, AVSS is assumed to be at system
ground.
avdd2-supply: true
iovdd-supply: true
ref1p-supply: true
ref1n-supply:
description:
Negative reference input supply for REF1. If omitted, REF1- is assumed
to be connected to ground.
ref2p-supply: true
ref2n-supply:
description:
Negative reference input supply for REF2. If omitted, REF2- is assumed
to be connected to ground.
reset-gpios:
maxItems: 1
description: GPIO connected to the active-low RESET pin
start-gpios:
maxItems: 1
description:
GPIO connected to the START pin. An active-low pulse on this pin
synchronizes the device to other AD7768 devices. When not used, this
pin must be tied to a logic high level through a pull-up resistor.
When used, SYNC_OUT must be wired back to SYNC_IN on all devices in
the synchronization chain.
sync-in-gpios:
maxItems: 1
description:
GPIO connected to the SYNC_IN pin. Receives the synchronization pulse
generated on SYNC_OUT in response to a START pulse. Must be synchronous
to the MCLK clock domain. In multi-device or daisy-chained systems,
two successive synchronization pulses must be applied to guarantee all
ADCs are synchronized.
gpio-controller: true
'#gpio-cells':
const: 2
adi,data-lines-number:
$ref: /schemas/types.yaml#/definitions/uint32
enum: [1, 2, 4, 8]
description:
Number of DOUTx lines used for the high-speed data output interface
(distinct from the SPI control interface). AD7768 supports 1, 2, or 8
lines; AD7768-4 supports 1 or 4 lines. Defaults to the maximum number
of lines for the selected variant if omitted.
regulators:
type: object
description: Container for the on-chip VCM regulator.
additionalProperties: false
properties:
vcm-output:
type: object
description:
Buffered common-mode voltage output on the VCM pin. Use
regulator-always-on when no consumer node references this output.
Channel 0 must be present and enabled while VCM is used, since
putting channel 0 in standby disables the VCM output.
$ref: /schemas/regulator/regulator.yaml#
unevaluatedProperties: false
io-backends:
maxItems: 1
'#address-cells':
const: 1
'#size-cells':
const: 0
patternProperties:
"^channel@[0-7]$":
type: object
description:
Represents the external channels which are connected to the device.
AD7768 supports channels 0-7, AD7768-4 supports channels 0-3.
properties:
reg:
minimum: 0
maximum: 7
description: The channel number
adi,prechargebuf-pos-enable:
type: boolean
description: Enable positive input precharge buffer
adi,prechargebuf-neg-enable:
type: boolean
description: Enable negative input precharge buffer
adi,refbuf-pos-enable:
type: boolean
description: Enable positive reference buffer
adi,refbuf-neg-enable:
type: boolean
description: Enable negative reference buffer
required:
- reg
additionalProperties: false
required:
- compatible
- reg
- clocks
- clock-names
- avdd1-supply
- avdd2-supply
- iovdd-supply
- ref1p-supply
- ref2p-supply
- io-backends
allOf:
- $ref: /schemas/spi/spi-peripheral-props.yaml#
- if:
properties:
compatible:
contains:
const: adi,ad7768-4
then:
properties:
adi,data-lines-number:
enum: [1, 4]
patternProperties:
"^channel@[0-3]$":
properties:
reg:
maximum: 3
"^channel@[4-7]$": false
else:
properties:
adi,data-lines-number:
enum: [1, 2, 8]
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/gpio/gpio.h>
spi {
#address-cells = <1>;
#size-cells = <0>;
adc@0 {
compatible = "adi,ad7768";
reg = <0>;
spi-max-frequency = <1000000>;
avdd1-supply = <&avdd1_regulator>;
avss-supply = <&avss_regulator>;
avdd2-supply = <&avdd2_regulator>;
iovdd-supply = <&iovdd_regulator>;
ref1p-supply = <&ref1p_regulator>;
ref1n-supply = <&ref1n_regulator>;
ref2p-supply = <&ref2p_regulator>;
ref2n-supply = <&ref2n_regulator>;
reset-gpios = <&gpio0 86 GPIO_ACTIVE_LOW>;
clocks = <&ad7768_mclk>;
clock-names = "mclk";
adi,data-lines-number = <8>;
gpio-controller;
#gpio-cells = <2>;
io-backends = <&iio_backend>;
#address-cells = <1>;
#size-cells = <0>;
channel@0 {
reg = <0>;
adi,prechargebuf-pos-enable;
adi,refbuf-pos-enable;
};
channel@1 {
reg = <1>;
adi,prechargebuf-pos-enable;
adi,prechargebuf-neg-enable;
adi,refbuf-pos-enable;
adi,refbuf-neg-enable;
};
channel@7 {
reg = <7>;
adi,prechargebuf-pos-enable;
adi,refbuf-pos-enable;
};
};
};
...
@@ -122,14 +122,14 @@ examples:
#size-cells = <0>;
adc@0 {
compatible = "adi,ad7779";
reg = <0>;
start-gpios = <&gpio0 87 GPIO_ACTIVE_LOW>;
reset-gpios = <&gpio0 93 GPIO_ACTIVE_LOW>;
interrupt-parent = <&intc>;
interrupts = <0 56 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "adc_rdy";
clocks = <&adc_clk>;
compatible = "adi,ad7779";
reg = <0>;
start-gpios = <&gpio0 87 GPIO_ACTIVE_LOW>;
reset-gpios = <&gpio0 93 GPIO_ACTIVE_LOW>;
interrupt-parent = <&intc>;
interrupts = <0 56 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "adc_rdy";
clocks = <&adc_clk>;
};
};
@@ -140,13 +140,13 @@ examples:
#size-cells = <0>;
adc@0 {
compatible = "adi,ad7779";
reg = <0>;
start-gpios = <&gpio0 87 GPIO_ACTIVE_LOW>;
reset-gpios = <&gpio0 93 GPIO_ACTIVE_LOW>;
clocks = <&adc_clk>;
io-backends = <&iio_backend>;
adi,num-lanes = <4>;
compatible = "adi,ad7779";
reg = <0>;
start-gpios = <&gpio0 87 GPIO_ACTIVE_LOW>;
reset-gpios = <&gpio0 93 GPIO_ACTIVE_LOW>;
clocks = <&adc_clk>;
io-backends = <&iio_backend>;
adi,num-lanes = <4>;
};
};
...
@@ -5,21 +5,23 @@
$id: http://devicetree.org/schemas/iio/adc/adi,ade9000.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Analog Devices ADE9000 High Performance, Polyphase Energy Metering
title: Analog Devices ADE9000/ADE9078 High Performance, Polyphase Energy Metering
maintainers:
- Antoniu Miclaus <antoniu.miclaus@analog.com>
description: |
The ADE9000 is a highly accurate, fully integrated, multiphase energy and power
quality monitoring device. Superior analog performance and a digital signal
processing (DSP) core enable accurate energy monitoring over a wide dynamic
range. An integrated high end reference ensures low drift over temperature
with a combined drift of less than ±25 ppm/°C maximum for the entire channel
including a programmable gain amplifier (PGA) and an analog-to-digital
converter (ADC).
The ADE9000 and ADE9078 are highly accurate, fully integrated, multiphase
energy and power quality monitoring devices. Superior analog performance and a
digital signal processing (DSP) core enable accurate energy monitoring over a
wide dynamic range. An integrated high end reference ensures low drift over
temperature with a combined drift of less than ±25 ppm/°C maximum for the
entire channel including a programmable gain amplifier (PGA) and an
analog-to-digital converter (ADC). The ADE9078 does not provide the on-chip
dip/swell detection available on the ADE9000.
https://www.analog.com/media/en/technical-documentation/data-sheets/ADE9000.pdf
https://www.analog.com/media/en/technical-documentation/data-sheets/ADE9078.pdf
$ref: /schemas/spi/spi-peripheral-props.yaml#
@@ -27,6 +29,7 @@ properties:
compatible:
enum:
- adi,ade9000
- adi,ade9078
reg:
maxItems: 1
@@ -67,6 +70,17 @@ required:
- reg
- vdd-supply
allOf:
- if:
properties:
compatible:
contains:
const: adi,ade9078
then:
properties:
spi-max-frequency:
maximum: 10000000
unevaluatedProperties: false
examples:
@@ -75,20 +89,20 @@ examples:
#include <dt-bindings/interrupt-controller/irq.h>
spi {
#address-cells = <1>;
#size-cells = <0>;
#address-cells = <1>;
#size-cells = <0>;
adc@0 {
compatible = "adi,ade9000";
reg = <0>;
spi-max-frequency = <7000000>;
adc@0 {
compatible = "adi,ade9000";
reg = <0>;
spi-max-frequency = <7000000>;
#clock-cells = <0>;
reset-gpios = <&gpio 4 GPIO_ACTIVE_LOW>;
interrupts = <2 IRQ_TYPE_EDGE_FALLING>, <3 IRQ_TYPE_EDGE_FALLING>, <4 IRQ_TYPE_EDGE_FALLING>;
interrupt-names = "irq0", "irq1", "dready";
interrupt-parent = <&gpio>;
clocks = <&ext_clock_24576khz>;
vdd-supply = <&vdd_reg>;
};
#clock-cells = <0>;
reset-gpios = <&gpio 4 GPIO_ACTIVE_LOW>;
interrupts = <2 IRQ_TYPE_EDGE_FALLING>, <3 IRQ_TYPE_EDGE_FALLING>, <4 IRQ_TYPE_EDGE_FALLING>;
interrupt-names = "irq0", "irq1", "dready";
interrupt-parent = <&gpio>;
clocks = <&ext_clock_24576khz>;
vdd-supply = <&vdd_reg>;
};
};
@@ -0,0 +1,65 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/adc/adi,max40080.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Analog Devices MAX40080 bidirectional current-sense amplifier
maintainers:
- Ciprian Hegbeli <ciprian.hegbeli@analog.com>
- Stefan Popa <stefan.popa@analog.com>
description: |
The MAX40080 is a high-precision, bidirectional current-sense amplifier with
an integrated 12-bit ADC and an I2C/SMBus interface. It measures the voltage
across an external shunt resistor and the input bus voltage, and stores the
results in an internal FIFO.
Datasheet:
https://www.analog.com/max40080
properties:
compatible:
const: adi,max40080
reg:
maxItems: 1
"#io-channel-cells":
const: 1
vdd-supply:
description: Power supply for the device.
interrupts:
maxItems: 1
description: ALERT_ output for overcurrent/undervoltage threshold events.
shunt-resistor-micro-ohms:
description:
Value of the current-sense shunt resistor connected between the RS+ and
RS- inputs. Used to scale the reported current.
required:
- compatible
- reg
- shunt-resistor-micro-ohms
- vdd-supply
additionalProperties: false
examples:
- |
i2c {
#address-cells = <1>;
#size-cells = <0>;
adc@20 {
compatible = "adi,max40080";
reg = <0x20>;
#io-channel-cells = <1>;
vdd-supply = <&vdd>;
shunt-resistor-micro-ohms = <100000>;
};
};
@@ -0,0 +1,63 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/adc/axiado,ax3000-saradc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Axiado AX3000/AX3005 Successive Approximation Register ADC
description:
The Axiado AX3000/AX3005 SAR ADC is a 10-bit ADC with sixteen input
channels on AX3000 and eight input channels on AX3005.
maintainers:
- Petar Stepanovic <pstepanovic@axiado.com>
- Akhila Kavi <akavi@axiado.com>
- Prasad Bolisetty <pbolisetty@axiado.com>
properties:
compatible:
enum:
- axiado,ax3000-saradc
- axiado,ax3005-saradc
reg:
maxItems: 1
clocks:
maxItems: 1
clock-names:
const: saradc
'#io-channel-cells':
const: 1
vref-supply:
description: Reference voltage regulator supplying the ADC
required:
- compatible
- reg
- clocks
- clock-names
- '#io-channel-cells'
- vref-supply
additionalProperties: false
examples:
- |
soc {
#address-cells = <2>;
#size-cells = <2>;
adc@806a0000 {
compatible = "axiado,ax3000-saradc";
reg = <0x0 0x806a0000 0x0 0x400>;
clocks = <&pclk>;
clock-names = "saradc";
vref-supply = <&vref_reg>;
#io-channel-cells = <1>;
};
};
@@ -4,7 +4,7 @@
$id: http://devicetree.org/schemas/iio/adc/lltc,ltc2497.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Linear Technology / Analog Devices LTC2497 and LTC2309 ADC
title: Linear Technology / Analog Devices LTC2497 and similar ADCs
maintainers:
- Michael Hennerich <michael.hennerich@analog.com>
@@ -118,22 +118,22 @@ examples:
#size-cells = <0>;
adc@1e {
compatible = "maxim,max34409";
reg = <0x1e>;
powerdown-gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
powerdown-status-gpios = <&gpio0 2 GPIO_ACTIVE_HIGH>;
compatible = "maxim,max34409";
reg = <0x1e>;
powerdown-gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
powerdown-status-gpios = <&gpio0 2 GPIO_ACTIVE_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
#address-cells = <1>;
#size-cells = <0>;
channel@0 {
reg = <0x0>;
maxim,rsense-val-micro-ohms = <5000>;
};
channel@0 {
reg = <0x0>;
maxim,rsense-val-micro-ohms = <5000>;
};
channel@1 {
reg = <0x1>;
maxim,rsense-val-micro-ohms = <10000>;
};
channel@1 {
reg = <0x1>;
maxim,rsense-val-micro-ohms = <10000>;
};
};
};
@@ -38,6 +38,7 @@ properties:
- const: mediatek,mt7986-auxadc
- items:
- enum:
- mediatek,mt6572-auxadc
- mediatek,mt6893-auxadc
- mediatek,mt8183-auxadc
- mediatek,mt8186-auxadc
@@ -56,6 +56,6 @@ examples:
clocks = <&ccu1 CLK_APB3_ADC0>;
vref-supply = <&reg_vdda>;
resets = <&rgu 40>;
};
};
};
...
@@ -34,8 +34,6 @@ properties:
- description: A/D scan end interrupt for Group C
- description: Window A compare match
- description: Window B compare match
- description: Compare match
- description: Compare mismatch
interrupt-names:
items:
@@ -44,8 +42,6 @@ properties:
- const: gcadi
- const: cmpai
- const: cmpbi
- const: wcmpm
- const: wcmpum
clocks:
items:
@@ -57,6 +53,18 @@ properties:
- const: adclk
- const: pclk
dmas:
minItems: 1
maxItems: 3
description:
Must contain a list of references to DMA RX specifiers.
dma-names:
minItems: 1
maxItems: 3
items:
const: rx
power-domains:
maxItems: 1
@@ -107,11 +115,9 @@ examples:
<GIC_SPI 709 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 710 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 711 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 712 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 855 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 856 IRQ_TYPE_EDGE_RISING>;
<GIC_SPI 712 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "adi", "gbadi", "gcadi",
"cmpai", "cmpbi", "wcmpm", "wcmpum";
"cmpai", "cmpbi";
clocks = <&cpg CPG_CORE R9A09G077_CLK_PCLKL>,
<&cpg CPG_MOD 225>;
clock-names = "adclk", "pclk";
@@ -25,7 +25,9 @@ properties:
- renesas,r9a07g054-adc # RZ/V2L
- const: renesas,rzg2l-adc
- items:
- const: renesas,r9a08g045-adc # RZ/G3S
- enum:
- renesas,r9a08g045-adc # RZ/G3S
- renesas,r9a08g046-adc1 # RZ/G3L ADC for TSU
reg:
maxItems: 1
@@ -121,6 +123,19 @@ allOf:
reg:
maximum: 7
- if:
properties:
compatible:
contains:
const: renesas,r9a08g046-adc1
then:
patternProperties:
"^channel@[0-7]$": false
"^channel@[8]$":
properties:
reg:
const: 8
additionalProperties: false
examples:
@@ -66,6 +66,11 @@ patternProperties:
- minimum: 0
maximum: 7
label:
$ref: /schemas/types.yaml#/definitions/string
description:
A descriptive name for this channel, like "vcc_ram" or "CH3".
ti,gain:
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 0
@@ -125,6 +130,7 @@ examples:
reg = <4>;
ti,gain = <3>;
ti,datarate = <5>;
label = "CH3";
};
};
};
@@ -4,19 +4,23 @@
$id: http://devicetree.org/schemas/iio/adc/ti,ads1100.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: TI ADS1100/ADS1000 single channel I2C analog to digital converter
title: TI ADS1100 and similar single channel I2C Analog to Digital Converters
maintainers:
- Mike Looijmans <mike.looijmans@topic.nl>
description: |
Datasheet at: https://www.ti.com/lit/gpn/ads1100
Datasheets:
- https://www.ti.com/lit/gpn/ads1000
- https://www.ti.com/lit/gpn/ads1100
- https://www.ti.com/lit/gpn/ads1110
properties:
compatible:
enum:
- ti,ads1100
- ti,ads1000
- ti,ads1100
- ti,ads1110
reg:
maxItems: 1
@@ -0,0 +1,149 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/adc/ti,ads112c04.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Texas Instruments ADS112C04 ADC
maintainers:
- Kyle Hsieh <kylehsieh1995@gmail.com>
description:
The ADS112C04 (16-bit) are precision analog-to-digital converters (ADCs)
with an I2C interface. They feature a flexible input multiplexer, a
low-noise programmable gain amplifier (PGA), two programmable excitation
current sources, a voltage reference, and a precision temperature sensor.
properties:
compatible:
enum:
- ti,ads112c04
reg:
maxItems: 1
description: I2C address of the device.
interrupts:
maxItems: 1
description:
Data ready (DRDY) interrupt output. DRDY pulses low when a conversion
result is ready and returns high once the result is latched, so an
edge trigger should be used.
"#address-cells":
const: 1
"#size-cells":
const: 0
reset-gpios:
maxItems: 1
description: GPIO connected to the RESET pin. Active low.
avdd-supply: true
dvdd-supply: true
refp-supply: true
refn-supply: true
ti,refp-refn-resistor-ohms:
description: Resistance of the external resistor between REFP and REFN.
patternProperties:
"^channel@[0-9a-b]$":
$ref: adc.yaml
unevaluatedProperties: false
properties:
reg:
items:
- maximum: 11
single-channel:
maximum: 3
diff-channels:
items:
maximum: 3
excitation-channels:
maxItems: 2
items:
maximum: 5
description:
Additionally to AIN0-AIN3, IDAC1/IDAC2 can also be routed to
REFP0 (4) and REFN0 (5).
excitation-current-nanoamp:
enum: [10000, 50000, 100000, 250000, 500000, 1000000, 1500000]
burn-out-current-nanoamp:
const: 10000
reference-sources:
items:
- enum: [internal, external, avdd]
default: [ internal ]
dependencies:
excitation-channels: [ excitation-current-nanoamp ]
excitation-current-nanoamp: [ excitation-channels ]
oneOf:
- required: [ single-channel ]
- required: [ diff-channels ]
required:
- compatible
- reg
- avdd-supply
- dvdd-supply
dependencies:
refn-supply: [ refp-supply ]
oneOf:
- required:
- refp-supply
- required:
- ti,refp-refn-resistor-ohms
- properties:
refp-supply: false
refn-supply: false
ti,refp-refn-resistor-ohms: false
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/gpio/gpio.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
adc@40 {
compatible = "ti,ads112c04";
reg = <0x40>;
interrupt-parent = <&gpio>;
interrupts = <12 IRQ_TYPE_EDGE_FALLING>;
reset-gpios = <&gpio 13 GPIO_ACTIVE_LOW>;
avdd-supply = <&vdd_3v3_reg>;
dvdd-supply = <&vdd_3v3_reg>;
refp-supply = <&vref_reg>;
#address-cells = <1>;
#size-cells = <0>;
channel@0 {
reg = <0>;
diff-channels = <0>, <1>;
};
channel@1 {
reg = <1>;
single-channel = <2>;
};
};
};
@@ -65,15 +65,15 @@ examples:
#size-cells = <0>;
adc@1 {
reg = <1>;
compatible = "ti,ads1298";
label = "ads1298-1-ecg";
avdd-supply = <&reg_iso_5v_a>;
clocks = <&clk_ads1298>;
interrupt-parent = <&gpio0>;
interrupts = <78 IRQ_TYPE_EDGE_FALLING>;
spi-max-frequency = <20000000>;
spi-cpha;
reg = <1>;
compatible = "ti,ads1298";
label = "ads1298-1-ecg";
avdd-supply = <&reg_iso_5v_a>;
clocks = <&clk_ads1298>;
interrupt-parent = <&gpio0>;
interrupts = <78 IRQ_TYPE_EDGE_FALLING>;
spi-max-frequency = <20000000>;
spi-cpha;
};
};
...
@@ -7,7 +7,8 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
title: Analog Devices AD74115H device
maintainers:
- Cosmin Tanislav <cosmin.tanislav@analog.com>
- Marcelo Schmitt <marcelo.schmitt@analog.com>
- Antoniu Miclaus <antoniu.miclaus@analog.com>
description: |
The AD74115H is a single-channel software configurable input/output
@@ -7,7 +7,8 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
title: Analog Devices AD74412R/AD74413R device
maintainers:
- Cosmin Tanislav <cosmin.tanislav@analog.com>
- Marcelo Schmitt <marcelo.schmitt@analog.com>
- Antoniu Miclaus <antoniu.miclaus@analog.com>
description: |
The AD74412R and AD74413R are quad-channel software configurable input/output
@@ -10,13 +10,13 @@ maintainers:
- Kim Seer Paller <kimseer.paller@analog.com>
description: |
The AD3530/AD3530R (8-channel), AD3531/AD3531R (4-channel), and AD3532/AD3532R
(16-channel) are low-power, 16-bit, buffered voltage output digital-to-analog
converters (DACs) with software-programmable gain controls, providing
full-scale output spans of 2.5V or 5V for reference voltages of 2.5V. These
devices operate from a single 2.7V to 5.5V supply and are guaranteed monotonic
by design. The "R" variants include a 2.5V, 5ppm/°C internal reference, which
is disabled by default.
The AD3530/AD3530R (8-channel), AD3531/AD3531R (4-channel), AD3532/AD3532R
(16-channel), 16-bit and AD3536R (16-channel), 12-bit are low-power, buffered
voltage output digital-to-analog converters (DACs) with software-programmable
gain controls, providing full-scale output spans of 2.5V or 5V for reference
voltages of 2.5V. These devices operate from a single 2.7V to 5.5V supply and
are guaranteed monotonic by design. The "R" variants include a 2.5V, 5ppm/°C
internal reference, which is disabled by default.
Datasheet can be found here:
https://www.analog.com/media/en/technical-documentation/data-sheets/ad3530_ad530r.pdf
https://www.analog.com/media/en/technical-documentation/data-sheets/ad3531-ad3531r.pdf
@@ -31,6 +31,7 @@ properties:
- adi,ad3531r
- adi,ad3532
- adi,ad3532r
- adi,ad3536r
reg:
maxItems: 1
@@ -0,0 +1,254 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/dac/adi,ad5529r.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Analog Devices AD5529R 16-Channel 12/16-bit High Voltage DAC
maintainers:
- Janani Sunil <janani.sunil@analog.com>
description: |
The AD5529R is a 16-channel, 12-bit or 16-bit, high voltage, buffered voltage
output digital-to-analog converter (DAC) with an integrated precision reference.
The device operates from unipolar and bipolar supplies. It is guaranteed
monotonic and has built-in rail-to-rail output buffers that can source or
sink up to 25mA.
Specifications:
* 16 independent 12-bit or 16-bit DAC channels
* Independently programmable output ranges: 0V to 5V, 0V to 10V, 0V to 20V,
0V to 40V, ±5V, ±10V, ±15V, and ±20V
* The device supports SPI communication with Mode 0 and Mode 3.
* 4.096V precision reference, 12ppm/°C maximum
* Built-in function generation: Toggle, Sinusoidal Dither, and Ramp waveforms
* Multiplexer for output voltage, load current sense and die temperature
Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/ad5529r.pdf
properties:
compatible:
enum:
- adi,ad5529r-16 # 16-bit variant
- adi,ad5529r-12 # 12-bit variant
reg:
maxItems: 1
spi-max-frequency:
maximum: 25000000
description:
Maximum SPI frequency. The device supports SPI Mode 0 and Mode 3.
Read operations are limited to 25MHz maximum.
reset-gpios:
maxItems: 1
description:
GPIO connected to the RESET pin. Active low. When asserted low,
performs a power-on reset and initializes the device to its default state.
clear-gpios:
maxItems: 1
description:
GPIO connected to the CLEAR pin. Active low. When asserted low,
clears all DAC data registers without affecting configuration settings.
interrupts:
maxItems: 1
description:
Interrupt connected to the ALARM pin. Active low interrupt output
for overtemperature conditions, SPI CRC errors, and function completion.
pwms:
minItems: 1
maxItems: 4
description:
PWM signals connected to the TG0-TG3 toggle pins. Pulsing these pins
based on trigger edge settings allows selected DACs to be updated
synchronously for digital function generation.
pwm-names:
minItems: 1
maxItems: 4
items:
enum: [ tg0, tg1, tg2, tg3 ]
io-channels:
maxItems: 1
description:
ADC channel connected to the MUXOUT pin for monitoring output voltage,
load current sense, and die temperature.
io-channel-names:
const: muxout
vdd-io-supply:
description: Digital power supply (1.08V to 1.98V)
vdd-5v-supply:
description: Analog power supply (4.75V to 5.25V)
vdd-hv0-supply:
description:
High voltage positive supply (7V to 45V) for channels 0 to 3.
vdd-hv1-supply:
description:
High voltage positive supply (7V to 45V) for channels 4 to 7.
vdd-hv2-supply:
description:
High voltage positive supply (7V to 45V) for channels 8 to 11.
vdd-hv3-supply:
description:
High voltage positive supply (7V to 45V) for channels 12 to 15.
vss-hv0-supply:
description:
High voltage negative supply (-22.5V to 0V) for channels 0 to 3.
vss-hv1-supply:
description:
High voltage negative supply (-22.5V to 0V) for channels 4 to 7.
vss-hv2-supply:
description:
High voltage negative supply (-22.5V to 0V) for channels 8 to 11.
vss-hv3-supply:
description:
High voltage negative supply (-22.5V to 0V) for channels 12 to 15.
vref-supply:
description:
External voltage reference supply (4.056V to 4.136V, typically 4.096V).
When specified, the device uses external reference mode and the VREF pin
becomes an input. The device uses the internal 4.096V precision reference
otherwise.
spi-device-addr:
minItems: 1
maxItems: 4
items:
enum: [0, 1, 2, 3]
default: 0
description:
Hardware address of each device, selected by the ID0 and ID1 pins.
Up to four AD5529R devices can share a single SPI chip select.
"#address-cells":
const: 1
"#size-cells":
const: 0
patternProperties:
"^channel@([0-9a-f]{1,2})$":
$ref: dac.yaml
type: object
description: Child nodes for individual channel configuration
properties:
reg:
description:
Flattened channel number across all AD5529R devices sharing the chip
select. Within each 16-channel block, the physical channel number is reg % 16.
minimum: 0
maximum: 63
output-range-microvolt:
description:
Output voltage range for this channel as [min, max] in
microvolts.
oneOf:
- items:
- const: 0
default: 0
- enum: [5000000, 10000000, 20000000, 40000000]
default: 5000000
- items:
- const: -5000000
- const: 5000000
- items:
- const: -10000000
- const: 10000000
- items:
- const: -15000000
- const: 15000000
- items:
- const: -20000000
- const: 20000000
required:
- reg
additionalProperties: false
required:
- compatible
- reg
- vdd-io-supply
- vdd-5v-supply
- vdd-hv0-supply
- vdd-hv1-supply
- vdd-hv2-supply
- vdd-hv3-supply
dependencies:
spi-cpha: [ spi-cpol ]
spi-cpol: [ spi-cpha ]
allOf:
- $ref: /schemas/spi/spi-peripheral-props.yaml#
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/gpio/gpio.h>
spi {
#address-cells = <1>;
#size-cells = <0>;
dac@0 {
compatible = "adi,ad5529r-16";
reg = <0>;
spi-max-frequency = <25000000>;
spi-device-addr = <0>;
vdd-io-supply = <&vdd_io_regulator>;
vdd-5v-supply = <&vdd_5v_regulator>;
vdd-hv0-supply = <&vdd_hv0_regulator>;
vdd-hv1-supply = <&vdd_hv1_regulator>;
vdd-hv2-supply = <&vdd_hv2_regulator>;
vdd-hv3-supply = <&vdd_hv3_regulator>;
vss-hv0-supply = <&vss_hv0_regulator>;
vss-hv1-supply = <&vss_hv1_regulator>;
vss-hv2-supply = <&vss_hv2_regulator>;
vss-hv3-supply = <&vss_hv3_regulator>;
reset-gpios = <&gpio0 87 GPIO_ACTIVE_LOW>;
#address-cells = <1>;
#size-cells = <0>;
channel@0 {
reg = <0>;
output-range-microvolt = <0 5000000>;
};
channel@1 {
reg = <1>;
output-range-microvolt = <(-10000000) 10000000>;
};
channel@2 {
reg = <2>;
output-range-microvolt = <0 40000000>;
};
};
};
...
@@ -0,0 +1,145 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/dac/adi,ad5710r.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Analog Devices AD5710R/AD5711R 8-channel 12-/16-bit Configurable IDAC/VDAC
maintainers:
- Kim Seer Paller <kimseer.paller@analog.com>
description: |
The AD5710R (16-bit) and AD5711R (12-bit) are 8-channel, low-power,
configurable current/voltage output digital-to-analog converters (DACs) with
an on-chip 2.5V, 3ppm/°C reference. Each channel can be independently
configured as a voltage output (0V to VREF or 0V to 2 x VREF) or a current
output (0mA to 50mA). These devices operate from a single 2.7V to 5.5V
supply and are guaranteed monotonic by design.
Datasheet can be found here:
https://www.analog.com/media/en/technical-documentation/data-sheets/ad5711r-ad5710r.pdf
properties:
compatible:
enum:
- adi,ad5710r
- adi,ad5711r
reg:
maxItems: 1
spi-max-frequency:
maximum: 20000000
'#address-cells':
const: 1
'#size-cells':
const: 0
vdd-supply:
description: Power Supply Input.
iovdd-supply:
description: Digital Power Supply Input.
io-channels:
description:
ADC channel used to monitor internal die temperature, output voltages, and
current of a selected channel via the MUXOUT pin.
maxItems: 1
ref-supply:
description:
Reference Input/Output. The voltage at the REF pin sets the full-scale
range of all channels. If not provided the internal reference is used and
also provided on the VREF pin.
reset-gpios:
description:
Active low signal that is falling edge sensitive. When it is deasserted,
the digital core initialization is performed and all DAC registers except
the Interface Configuration A register are reset to their default values.
maxItems: 1
ldac-gpios:
description:
LDAC pin to be used as a hardware trigger to update the DAC channels. If
not present, the DAC channels are updated by Software LDAC.
maxItems: 1
adi,range-double:
description:
Configure the output range for all channels. If the property is present,
the output will range from 0V to 2 x Vref. If the property is not present,
the output will range from 0V to Vref.
type: boolean
patternProperties:
"^channel@[0-7]$":
$ref: /schemas/iio/dac/dac.yaml#
type: object
description:
Represents the external channels which are connected to the DAC.
properties:
reg:
description: Channel number
minimum: 0
maximum: 7
adi,ch-func:
description:
Channel output type. The values are defined in
<dt-bindings/iio/addac/adi,ad74413r.h>. Use
CH_FUNC_VOLTAGE_OUTPUT (1) for voltage output or
CH_FUNC_CURRENT_OUTPUT (2) for current output.
$ref: /schemas/types.yaml#/definitions/uint32
enum: [1, 2]
required:
- reg
- adi,ch-func
unevaluatedProperties: false
required:
- compatible
- reg
- vdd-supply
- iovdd-supply
allOf:
- $ref: /schemas/spi/spi-peripheral-props.yaml#
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/iio/addac/adi,ad74413r.h>
spi {
#address-cells = <1>;
#size-cells = <0>;
dac@0 {
compatible = "adi,ad5710r";
reg = <0>;
spi-max-frequency = <1000000>;
vdd-supply = <&vdd>;
iovdd-supply = <&iovdd>;
#address-cells = <1>;
#size-cells = <0>;
channel@0 {
reg = <0>;
adi,ch-func = <CH_FUNC_VOLTAGE_OUTPUT>;
};
channel@1 {
reg = <1>;
adi,ch-func = <CH_FUNC_CURRENT_OUTPUT>;
};
};
};
...
@@ -4,58 +4,92 @@
$id: http://devicetree.org/schemas/iio/dac/microchip,mcp47feb02.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Microchip MCP47F(E/V)B(0/1/2)(1/2/4/8) DAC with I2C Interface Families
title: Microchip MCP4(7/8)F(E/V)B(0/1/2)(1/2/4/8) DAC with I2C/SPI Interface Families
maintainers:
- Ariana Lazar <ariana.lazar@microchip.com>
description: |
Datasheet for MCP47FEB01, MCP47FEB11, MCP47FEB21, MCP47FEB02, MCP47FEB12,
MCP47FEB22 can be found here:
https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/20005375A.pdf
Datasheet for MCP47FVB01, MCP47FVB11, MCP47FVB21, MCP47FVB02, MCP47FVB12,
MCP47FVB22 can be found here:
https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/20005405A.pdf
Datasheet for MCP47FEB04, MCP47FEB14, MCP47FEB24, MCP47FEB08, MCP47FEB18,
MCP47FEB28, MCP47FVB04, MCP47FVB14, MCP47FVB24, MCP47FVB08, MCP47FVB18,
MCP47FVB28 can be found here:
https://ww1.microchip.com/downloads/aemDocuments/documents/MSLD/ProductDocuments/DataSheets/MCP47FXBX48-Data-Sheet-DS200006368A.pdf
Datasheets for MCP47F(E/V)B(0/1/2)(1/2/4/8) DAC with I2C Interface Families:
Datasheet for MCP47FEB01, MCP47FEB02, MCP47FEB11, MCP47FEB12, MCP47FEB21,
MCP47FEB22 can be found here:
https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/20005375A.pdf
Datasheet for MCP47FVB01, MCP47FVB02, MCP47FVB11, MCP47FVB12, MCP47FVB21,
MCP47FVB22 can be found here:
https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/20005405A.pdf
Datasheet for MCP47FEB04, MCP47FEB08, MCP47FEB14, MCP47FEB18, MCP47FEB24,
MCP47FEB28, MCP47FVB04, MCP47FVB08, MCP47FVB14, MCP47FVB18, MCP47FVB24,
MCP47FVB28 can be found here:
https://ww1.microchip.com/downloads/aemDocuments/documents/MSLD/ProductDocuments/DataSheets/MCP47FXBX48-Data-Sheet-DS200006368A.pdf
Datasheets for MCP48F(E/V)B(0/1/2)(1/2/4/8) DAC with SPI Interface Families:
Datasheet for MCP48FEB01, MCP48FEB02, MCP48FEB11, MCP48FEB12, MCP48FEB21,
MCP48FEB22 can be found here:
https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/20005429B.pdf
Datasheet for MCP48FVB01, MCP48FVB02, MCP48FVB11, MCP48FVB12, MCP48FVB21,
MCP48FVB22 can be found here:
https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/20005466A.pdf
Datasheet for MCP48FEB04, MCP48FEB14, MCP48FEB24, MCP48FEB08, MCP48FEB18,
MCP48FEB28, MCP48FVB04, MCP48FVB14, MCP48FVB24, MCP48FVB08, MCP48FVB18,
MCP48FVB28 can be found here:
https://ww1.microchip.com/downloads/aemDocuments/documents/MSLD/ProductDocuments/DataSheets/MCP48FXBX4-8-Family-Data-Sheet-DS20006362A.pdf
+------------+--------------+-------------+-------------+------------+
| Device | Resolution | Channels | Vref number | Memory |
|------------|--------------|-------------|-------------|------------|
| MCP47FEB01 | 8-bit | 1 | 1 | EEPROM |
| MCP47FEB11 | 10-bit | 1 | 1 | EEPROM |
| MCP47FEB21 | 12-bit | 1 | 1 | EEPROM |
|------------|--------------|-------------|-------------|------------|
| MCP47FEB02 | 8-bit | 2 | 1 | EEPROM |
| MCP47FEB12 | 10-bit | 2 | 1 | EEPROM |
| MCP47FEB22 | 12-bit | 2 | 1 | EEPROM |
|------------|--------------|-------------|-------------|------------|
| MCP47FVB01 | 8-bit | 1 | 1 | RAM |
| MCP47FVB11 | 10-bit | 1 | 1 | RAM |
| MCP47FVB21 | 12-bit | 1 | 1 | RAM |
|------------|--------------|-------------|-------------|------------|
| MCP47FVB02 | 8-bit | 2 | 1 | RAM |
| MCP47FVB12 | 10-bit | 2 | 1 | RAM |
| MCP47FVB22 | 12-bit | 2 | 1 | RAM |
|------------|--------------|-------------|-------------|------------|
| MCP47FVB04 | 8-bit | 4 | 2 | RAM |
| MCP47FVB14 | 10-bit | 4 | 2 | RAM |
| MCP47FVB24 | 12-bit | 4 | 2 | RAM |
|------------|--------------|-------------|-------------|------------|
| MCP47FVB08 | 8-bit | 8 | 2 | RAM |
| MCP47FVB18 | 10-bit | 8 | 2 | RAM |
| MCP47FVB28 | 12-bit | 8 | 2 | RAM |
|------------|--------------|-------------|-------------|------------|
| MCP47FEB04 | 8-bit | 4 | 2 | EEPROM |
| MCP47FEB14 | 10-bit | 4 | 2 | EEPROM |
| MCP47FEB24 | 12-bit | 4 | 2 | EEPROM |
|------------|--------------|-------------|-------------|------------|
| MCP47FEB08 | 8-bit | 8 | 2 | EEPROM |
| MCP47FEB18 | 10-bit | 8 | 2 | EEPROM |
| MCP47FEB28 | 12-bit | 8 | 2 | EEPROM |
+------------+--------------+-------------+-------------+------------+
+------------+--------------+-------------+-------------+------------+------------+
| Device | Resolution | Channels | Vref number | Memory | Interface |
|------------|--------------|-------------|-------------|------------|------------|
| MCP47FEB01 | | 1 | 1 | EEPROM | I2C |
| MCP47FEB02 | | 2 | 1 | EEPROM | I2C |
| MCP47FEB04 | | 4 | 2 | EEPROM | I2C |
| MCP47FEB08 | 8-bit | 8 | 2 | EEPROM | I2C |
| MCP48FEB01 | | 1 | 1 | EEPROM | SPI |
| MCP48FEB02 | | 2 | 1 | EEPROM | SPI |
| MCP48FEB04 | | 4 | 2 | EEPROM | SPI |
| MCP48FEB08 | | 8 | 2 | EEPROM | SPI |
|------------|--------------|-------------|-------------|------------|------------|
| MCP47FEB11 | | 1 | 1 | EEPROM | I2C |
| MCP47FEB12 | | 2 | 1 | EEPROM | I2C |
| MCP47FEB14 | | 4 | 2 | EEPROM | I2C |
| MCP47FEB18 | 10-bit | 8 | 2 | EEPROM | I2C |
| MCP48FEB11 | | 1 | 1 | EEPROM | SPI |
| MCP48FEB12 | | 2 | 1 | EEPROM | SPI |
| MCP48FEB14 | | 4 | 2 | EEPROM | SPI |
| MCP48FEB18 | | 8 | 2 | EEPROM | SPI |
|------------|--------------|-------------|-------------|------------|------------|
| MCP47FEB21 | | 1 | 1 | EEPROM | I2C |
| MCP47FEB22 | | 2 | 1 | EEPROM | I2C |
| MCP47FEB24 | | 4 | 2 | EEPROM | I2C |
| MCP47FEB28 | 12-bit | 8 | 2 | EEPROM | I2C |
| MCP48FEB21 | | 1 | 1 | EEPROM | SPI |
| MCP48FEB22 | | 2 | 1 | EEPROM | SPI |
| MCP48FEB24 | | 4 | 2 | EEPROM | SPI |
| MCP48FEB28 | | 8 | 2 | EEPROM | SPI |
|------------|--------------|-------------|-------------|------------|------------|
| MCP47FVB01 | | 1 | 1 | RAM | I2C |
| MCP47FVB02 | | 2 | 1 | RAM | I2C |
| MCP47FVB04 | | 4 | 2 | RAM | I2C |
| MCP47FVB08 | 8-bit | 8 | 2 | RAM | I2C |
| MCP48FVB01 | | 1 | 1 | RAM | SPI |
| MCP48FVB02 | | 2 | 1 | RAM | SPI |
| MCP48FVB04 | | 4 | 2 | RAM | SPI |
| MCP48FVB08 | | 8 | 2 | RAM | SPI |
|------------|--------------|-------------|-------------|------------|------------|
| MCP47FVB11 | | 1 | 1 | RAM | I2C |
| MCP47FVB12 | | 2 | 1 | RAM | I2C |
| MCP47FVB14 | | 4 | 2 | RAM | I2C |
| MCP47FVB18 | 10-bit | 8 | 2 | RAM | I2C |
| MCP48FVB11 | | 1 | 1 | RAM | SPI |
| MCP48FVB12 | | 2 | 1 | RAM | SPI |
| MCP48FVB14 | | 4 | 2 | RAM | SPI |
| MCP48FVB18 | | 8 | 2 | RAM | SPI |
|------------|--------------|-------------|-------------|------------|------------|
| MCP47FVB21 | | 1 | 1 | RAM | I2C |
| MCP47FVB22 | | 2 | 1 | RAM | I2C |
| MCP47FVB24 | | 4 | 2 | RAM | I2C |
| MCP47FVB28 | 12-bit | 8 | 2 | RAM | I2C |
| MCP48FVB21 | | 1 | 1 | RAM | SPI |
| MCP48FVB22 | | 2 | 1 | RAM | SPI |
| MCP48FVB24 | | 4 | 2 | RAM | SPI |
| MCP48FVB28 | | 8 | 2 | RAM | SPI |
+------------+--------------+-------------+-------------+------------+------------+
properties:
compatible:
@@ -84,10 +118,37 @@ properties:
- microchip,mcp47feb08
- microchip,mcp47feb18
- microchip,mcp47feb28
- microchip,mcp48feb01
- microchip,mcp48feb02
- microchip,mcp48feb04
- microchip,mcp48feb08
- microchip,mcp48feb11
- microchip,mcp48feb12
- microchip,mcp48feb14
- microchip,mcp48feb18
- microchip,mcp48feb21
- microchip,mcp48feb22
- microchip,mcp48feb24
- microchip,mcp48feb28
- microchip,mcp48fvb01
- microchip,mcp48fvb02
- microchip,mcp48fvb04
- microchip,mcp48fvb08
- microchip,mcp48fvb11
- microchip,mcp48fvb12
- microchip,mcp48fvb14
- microchip,mcp48fvb18
- microchip,mcp48fvb21
- microchip,mcp48fvb22
- microchip,mcp48fvb24
- microchip,mcp48fvb28
reg:
maxItems: 1
spi-max-frequency:
maximum: 10000000
"#address-cells":
const: 1
@@ -178,6 +239,21 @@ required:
- vdd-supply
allOf:
- if:
properties:
compatible:
contains:
pattern: "^microchip,mcp48f[ev]b[0-2][1248]$"
then:
$ref: /schemas/spi/spi-peripheral-props.yaml#
dependencies:
spi-cpha: [ spi-cpol ]
spi-cpol: [ spi-cpha ]
else:
properties:
spi-max-frequency: false
spi-cpha: false
spi-cpol: false
- if:
properties:
compatible:
@@ -189,6 +265,12 @@ allOf:
- microchip,mcp47fvb01
- microchip,mcp47fvb11
- microchip,mcp47fvb21
- microchip,mcp48feb01
- microchip,mcp48feb11
- microchip,mcp48feb21
- microchip,mcp48fvb01
- microchip,mcp48fvb11
- microchip,mcp48fvb21
then:
properties:
lat1-gpios: false
@@ -211,6 +293,12 @@ allOf:
- microchip,mcp47fvb02
- microchip,mcp47fvb12
- microchip,mcp47fvb22
- microchip,mcp48feb02
- microchip,mcp48feb12
- microchip,mcp48feb22
- microchip,mcp48fvb02
- microchip,mcp48fvb12
- microchip,mcp48fvb22
then:
properties:
lat1-gpios: false
@@ -233,6 +321,12 @@ allOf:
- microchip,mcp47feb04
- microchip,mcp47feb14
- microchip,mcp47feb24
- microchip,mcp48feb04
- microchip,mcp48feb14
- microchip,mcp48feb24
- microchip,mcp48fvb04
- microchip,mcp48fvb14
- microchip,mcp48fvb24
then:
patternProperties:
"^channel@[0-3]$":
@@ -251,6 +345,12 @@ allOf:
- microchip,mcp47feb08
- microchip,mcp47feb18
- microchip,mcp47feb28
- microchip,mcp48feb08
- microchip,mcp48feb18
- microchip,mcp48feb28
- microchip,mcp48fvb08
- microchip,mcp48fvb18
- microchip,mcp48fvb28
then:
patternProperties:
"^channel@[0-7]$":
@@ -272,7 +372,7 @@ allOf:
properties:
microchip,vref1-buffered: false
additionalProperties: false
unevaluatedProperties: false
examples:
- |
@@ -299,4 +399,29 @@ examples:
};
};
};
- |
spi {
#address-cells = <1>;
#size-cells = <0>;
dac@0 {
compatible = "microchip,mcp48feb02";
reg = <0x0>;
vdd-supply = <&vdac_vdd>;
vref-supply = <&vref_reg>;
spi-max-frequency = <10000000>;
#address-cells = <1>;
#size-cells = <0>;
channel@0 {
reg = <0>;
label = "Adjustable_voltage_ch0";
};
channel@1 {
reg = <0x1>;
label = "Adjustable_voltage_ch1";
};
};
};
...
@@ -0,0 +1,209 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/frequency/adi,ad9910.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Analog Devices AD9910 Direct Digital Synthesizer
maintainers:
- Rodrigo Alencar <rodrigo.alencar@analog.com>
description: >
The AD9910 is a 1 GSPS direct digital synthesizer (DDS) with an integrated
14-bit DAC. It features single tone mode with 8 configurable profiles,
a digital ramp generator, RAM control, OSK, and a parallel data port for
high-speed streaming.
https://www.analog.com/en/products/ad9910.html
properties:
compatible:
const: adi,ad9910
reg:
maxItems: 1
spi-max-frequency:
maximum: 70000000
clocks:
minItems: 1
items:
- description: Reference clock (REF_CLK).
- description: Optional synchronization clock (SYNC_IN).
clock-names:
minItems: 1
items:
- const: ref_clk
- const: sync_in
'#clock-cells':
const: 1
clock-output-names:
items:
- const: sync_clk
- const: pdclk
- const: sync_out
interrupts:
minItems: 1
maxItems: 2
description:
Requires interrupt-names property with the same number of items. The
supported interrupts are 'drover' (digital ramp generator limit) and
'ram_swp_ovr' (end of RAM sweep).
interrupt-names:
minItems: 1
maxItems: 2
items:
enum: [ drover, ram_swp_ovr ]
dvdd-io33-supply:
description: 3.3V Digital I/O supply.
avdd33-supply:
description: 3.3V Analog DAC supply.
dvdd18-supply:
description: 1.8V Digital Core supply.
avdd18-supply:
description: 1.8V Analog Core supply.
reset-gpios:
maxItems: 1
description:
GPIOs controlling the Main Device reset.
io-reset-gpios:
maxItems: 1
description:
GPIO controlling the I/O_RESET pin.
powerdown-gpios:
maxItems: 1
description:
GPIO controlling the EXT_PWR_DWN pin.
update-gpios:
maxItems: 1
description:
GPIO controlling the I/O_UPDATE pin.
profile-gpios:
minItems: 3
maxItems: 3
description:
GPIOs controlling the PROFILE[2:0] pins for profile selection.
sync-err-gpios:
maxItems: 1
description:
GPIO used to read SYNC_SMP_ERR pin status.
lock-detect-gpios:
maxItems: 1
description:
GPIO used to read PLL_LOCK pin status.
pwms:
maxItems: 1
description:
PWM used to drive the DRCTL pin, which controls the digital ramp
generator slope direction.
pwm-names:
items:
- const: drctl
adi,pll-enable:
type: boolean
description:
Enables the internal PLL. Applicable when external loop filter components
are connected to the PLL_LOOP_FILTER pin and low reference clock
frequencies are used, often provided by a crystal or by a single-ended
on-board oscillator.
adi,charge-pump-current-microamp:
minimum: 212
maximum: 387
default: 212
description:
PLL charge pump current in microamps. Only applicable when the internal
PLL is enabled. The value is rounded to the nearest supported step. This
value depends mostly on the loop filter design.
adi,refclk-out-drive-strength:
$ref: /schemas/types.yaml#/definitions/string
enum: [ disabled, low, medium, high ]
default: disabled
description:
Reference clock output (DRV0) drive strength. Only applicable when
the internal PLL is enabled.
dependencies:
adi,charge-pump-current-microamp: [ 'adi,pll-enable' ]
adi,refclk-out-drive-strength: [ 'adi,pll-enable' ]
lock-detect-gpios: [ 'adi,pll-enable' ]
interrupts: [ interrupt-names ]
pwms: [ pwm-names ]
required:
- compatible
- reg
- clocks
- clock-names
- '#clock-cells'
- dvdd-io33-supply
- avdd33-supply
- dvdd18-supply
- avdd18-supply
allOf:
- $ref: /schemas/spi/spi-peripheral-props.yaml#
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/gpio/gpio.h>
spi {
#address-cells = <1>;
#size-cells = <0>;
dds@0 {
compatible = "adi,ad9910";
reg = <0>;
spi-max-frequency = <1000000>;
#clock-cells = <1>;
clock-output-names = "sync_clk", "pdclk", "sync_out";
clocks = <&ad9910_refclk>;
clock-names = "ref_clk";
dvdd-io33-supply = <&vdd_io33>;
avdd33-supply = <&vdd_a33>;
dvdd18-supply = <&vdd_d18>;
avdd18-supply = <&vdd_a18>;
reset-gpios = <&gpio 0 GPIO_ACTIVE_HIGH>;
io-reset-gpios = <&gpio 1 GPIO_ACTIVE_HIGH>;
powerdown-gpios = <&gpio 2 GPIO_ACTIVE_HIGH>;
update-gpios = <&gpio 3 GPIO_ACTIVE_HIGH>;
profile-gpios = <&gpio 4 GPIO_ACTIVE_HIGH>,
<&gpio 5 GPIO_ACTIVE_HIGH>,
<&gpio 6 GPIO_ACTIVE_HIGH>;
pwms = <&pwm 0 1000000 0>;
pwm-names = "drctl";
adi,pll-enable;
adi,charge-pump-current-microamp = <387>;
adi,refclk-out-drive-strength = "disabled";
};
};
...
@@ -26,16 +26,20 @@ description: |
properties:
compatible:
enum:
- invensense,icm42600
- invensense,icm42602
- invensense,icm42605
- invensense,icm42607
- invensense,icm42607p
- invensense,icm42622
- invensense,icm42631
- invensense,icm42686
- invensense,icm42688
oneOf:
- enum:
- invensense,icm42600
- invensense,icm42602
- invensense,icm42605
- invensense,icm42607
- invensense,icm42607p
- invensense,icm42622
- invensense,icm42631
- invensense,icm42686
- invensense,icm42688
- items:
- const: invensense,icm42630
- const: invensense,icm42631
reg:
maxItems: 1
@@ -40,10 +40,10 @@ examples:
#size-cells = <0>;
adux1020@64 {
compatible = "adi,adux1020";
reg = <0x64>;
interrupt-parent = <&msmgpio>;
interrupts = <24 IRQ_TYPE_LEVEL_HIGH>;
compatible = "adi,adux1020";
reg = <0x64>;
interrupt-parent = <&msmgpio>;
interrupts = <24 IRQ_TYPE_LEVEL_HIGH>;
};
};
...
@@ -45,6 +45,6 @@ examples:
compatible = "amstaos,tsl2591";
reg = <0x29>;
interrupts = <20 IRQ_TYPE_EDGE_FALLING>;
};
};
};
...
@@ -0,0 +1,44 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/light/capella,cm32181.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Capella CM32181 ambient light sensor
maintainers:
- Kevin Tsai <ktsai@capellamicro.com>
properties:
compatible:
const: capella,cm32181
reg:
maxItems: 1
vdd-supply: true
interrupts:
maxItems: 1
required:
- compatible
- reg
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
light-sensor@10 {
compatible = "capella,cm32181";
reg = <0x10>;
vdd-supply = <&vdd_3v3>;
interrupt-parent = <&gpio>;
interrupts = <17 IRQ_TYPE_EDGE_RISING>;
};
};
@@ -50,9 +50,9 @@ examples:
#size-cells = <0>;
sensor@44 {
compatible = "isil,isl29018";
reg = <0x44>;
interrupts-extended = <&msmgpio 61 IRQ_TYPE_LEVEL_HIGH>;
compatible = "isil,isl29018";
reg = <0x44>;
interrupts-extended = <&msmgpio 61 IRQ_TYPE_LEVEL_HIGH>;
};
};
...
@@ -9,15 +9,14 @@ title: LiteON LTR501 I2C Proximity and Light sensor
maintainers:
- Nikita Travkin <nikita@trvn.ru>
allOf:
- $ref: ../common.yaml#
properties:
compatible:
enum:
- liteon,ltr301
- liteon,ltr303
- liteon,ltr329
- liteon,ltr501
- liteon,ltr559
- liteon,ltr301
reg:
maxItems: 1
@@ -36,6 +35,31 @@ required:
- compatible
- reg
allOf:
- $ref: ../common.yaml#
- if:
properties:
compatible:
contains:
enum:
- liteon,ltr329
then:
properties:
interrupts: false
- if:
properties:
compatible:
contains:
enum:
- liteon,ltr301
- liteon,ltr303
- liteon,ltr329
then:
properties:
proximity-near-level: false
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
@@ -39,8 +39,8 @@ examples:
#size-cells = <0>;
light@39 {
compatible = "onnn,noa1305";
reg = <0x39>;
compatible = "onnn,noa1305";
reg = <0x39>;
};
};
...
@@ -4,14 +4,14 @@
$id: http://devicetree.org/schemas/iio/light/stk33xx.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: |
Sensortek STK33xx I2C Ambient Light and Proximity sensor
title: Sensortek STK33xx/STK36C61 I2C Ambient Light and Proximity sensor
maintainers:
- Jonathan Cameron <jic23@kernel.org>
description: |
Ambient light and proximity sensor over an i2c interface.
description:
Ambient light and proximity sensor over an i2c interface. The STK36C61
additionally provides RGBC colour channels.
allOf:
- $ref: ../common.yaml#
@@ -26,6 +26,7 @@ properties:
- items:
- enum:
- sensortek,stk3013
- sensortek,stk36c61
- const: sensortek,stk3310
reg:
@@ -52,11 +53,11 @@ examples:
#size-cells = <0>;
stk3310@48 {
compatible = "sensortek,stk3310";
reg = <0x48>;
proximity-near-level = <25>;
interrupt-parent = <&gpio1>;
interrupts = <5 IRQ_TYPE_LEVEL_LOW>;
compatible = "sensortek,stk3310";
reg = <0x48>;
proximity-near-level = <25>;
interrupt-parent = <&gpio1>;
interrupts = <5 IRQ_TYPE_LEVEL_LOW>;
};
};
...
@@ -41,8 +41,8 @@ examples:
#size-cells = <0>;
light-sensor@29 {
compatible = "amstaos,tsl2581";
reg = <0x29>;
compatible = "amstaos,tsl2581";
reg = <0x29>;
};
};
...
@@ -74,13 +74,13 @@ examples:
#size-cells = <0>;
sensor@39 {
compatible = "amstaos,tsl2772";
reg = <0x39>;
interrupts-extended = <&msmgpio 61 IRQ_TYPE_EDGE_FALLING>;
vdd-supply = <&pm8941_l17>;
vddio-supply = <&pm8941_lvs1>;
amstaos,proximity-diodes = <0>;
led-max-microamp = <100000>;
compatible = "amstaos,tsl2772";
reg = <0x39>;
interrupts-extended = <&msmgpio 61 IRQ_TYPE_EDGE_FALLING>;
vdd-supply = <&pm8941_l17>;
vddio-supply = <&pm8941_lvs1>;
amstaos,proximity-diodes = <0>;
led-max-microamp = <100000>;
};
};
...
@@ -4,7 +4,8 @@
$id: http://devicetree.org/schemas/iio/light/vishay,veml6030.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: VEML3235, VEML3328, VEML6030, VEML6035 and VEML7700 Ambient Light Sensors (ALS)
title: VEML3235, VEML3328, VEML6030, VEML6031x00 series, VEML6035
and VEML7700 Ambient Light Sensors (ALS)
maintainers:
- Rishi Gupta <gupt21@gmail.com>
@@ -23,6 +24,8 @@ description: |
https://www.vishay.com/docs/80131/veml3235.pdf
https://www.vishay.com/docs/84968/veml3328.pdf
https://www.vishay.com/docs/84366/veml6030.pdf
https://www.vishay.com/docs/80007/veml6031x00.pdf
https://www.vishay.com/docs/80008/veml6031x01.pdf
https://www.vishay.com/docs/84889/veml6035.pdf
https://www.vishay.com/docs/84286/veml7700.pdf
@@ -32,6 +35,10 @@ properties:
- vishay,veml3235
- vishay,veml3328
- vishay,veml6030
- vishay,veml6031x00
- vishay,veml6031x01
- vishay,veml60311x00
- vishay,veml60311x01
- vishay,veml6035
- vishay,veml7700
@@ -69,6 +76,8 @@ allOf:
properties:
compatible:
enum:
- vishay,veml6031x00
- vishay,veml6031x01
- vishay,veml6035
then:
properties:
@@ -82,6 +91,8 @@ allOf:
enum:
- vishay,veml3235
- vishay,veml3328
- vishay,veml60311x00
- vishay,veml60311x01
- vishay,veml7700
then:
properties:
@@ -101,10 +112,10 @@ examples:
#size-cells = <0>;
light-sensor@10 {
compatible = "vishay,veml6030";
reg = <0x10>;
interrupts = <12 IRQ_TYPE_LEVEL_LOW>;
vdd-supply = <&vdd>;
compatible = "vishay,veml6030";
reg = <0x10>;
interrupts = <12 IRQ_TYPE_LEVEL_LOW>;
vdd-supply = <&vdd>;
};
};
...
@@ -45,10 +45,10 @@ examples:
#size-cells = <0>;
dps: pressure-sensor@76 {
compatible = "infineon,dps310";
reg = <0x76>;
#io-channel-cells = <0>;
vdd-supply = <&vref1>;
vddio-supply = <&vref2>;
compatible = "infineon,dps310";
reg = <0x76>;
#io-channel-cells = <0>;
vdd-supply = <&vref1>;
vddio-supply = <&vref2>;
};
};
@@ -0,0 +1,71 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/proximity/pulsedlight,lidar-lite-v2.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Pulsedlight/Garmin LIDAR-Lite range-finding sensors
maintainers:
- Matt Ranostay <matt@ranostay.sg>
- Rodrigo Gobbi <rodrigo.gobbi.7@gmail.com>
description: |
This binding covers the I2C interface of the Pulsedlight/Garmin
LIDAR-Lite v2 and v3 laser rangefinders.
Besides I2C, the mode control pin can also trigger acquisitions and
report the measured distance through a PWM signal, without using I2C
at all. That usage is bidirectional and non-cyclic, and is not
described by this binding. The same pin can also be used, while I2C
remains the active interface, as a plain status output signalling
when an acquisition has completed.
Datasheets:
https://static.garmin.com/pumac/LIDAR_Lite_v3_Operation_Manual_and_Technical_Specifications.pdf
https://github.com/PulsedLight3D/LIDAR-Lite-Documentation/blob/master/Docs/LIDAR-Lite-v2-Docs.pdf
properties:
compatible:
oneOf:
- items:
- enum:
- grmn,lidar-lite-v3
- const: pulsedlight,lidar-lite-v2
- const: pulsedlight,lidar-lite-v2
reg:
maxItems: 1
powerdown-gpios:
description: GPIO that can be driven low to shut off power to the device.
maxItems: 1
vdd-supply: true
interrupts:
description:
Mode control pin used as a status output, driven while the device is
busy performing an acquisition. Can be used to signal completion
instead of polling over I2C.
maxItems: 1
required:
- compatible
- reg
- vdd-supply
additionalProperties: false
examples:
- |
i2c {
#address-cells = <1>;
#size-cells = <0>;
lidar@62 {
compatible = "grmn,lidar-lite-v3", "pulsedlight,lidar-lite-v2";
reg = <0x62>;
vdd-supply = <&vdd_5v0>;
};
};
...
@@ -57,8 +57,8 @@ examples:
#size-cells = <0>;
proximity@13 {
compatible = "vishay,vcnl3020";
reg = <0x13>;
vishay,led-current-microamp = <200000>;
compatible = "vishay,vcnl3020";
reg = <0x13>;
vishay,led-current-microamp = <200000>;
};
};
@@ -17,6 +17,7 @@ description: |
- LTC2986
- LTM2985
https://www.analog.com/media/en/technical-documentation/data-sheets/adt7604.pdf
https://www.analog.com/media/en/technical-documentation/data-sheets/2983fc.pdf
https://www.analog.com/media/en/technical-documentation/data-sheets/2984fb.pdf
https://www.analog.com/media/en/technical-documentation/data-sheets/29861fa.pdf
@@ -0,0 +1,118 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/interconnect/qcom,kuno-rpmh.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm RPMh Network-On-Chip Interconnect on Kuno SoC
maintainers:
- Hardeep Sharma <hardeep.sharma@oss.qualcomm.com>
description: |
RPMh interconnect providers support system bandwidth requirements through
RPMh hardware accelerators known as Bus Clock Manager (BCM). The provider is
able to communicate with the BCM through the Resource State Coordinator (RSC)
associated with each execution environment. Provider nodes must point to at
least one RPMh device child node pertaining to their RSC and each provider
can map to multiple RPMh resources.
See also: include/dt-bindings/interconnect/qcom,kuno.h
properties:
compatible:
enum:
- qcom,kuno-aggre-noc
- qcom,kuno-clk-virt
- qcom,kuno-cnoc-main
- qcom,kuno-dc-noc
- qcom,kuno-mc-virt
- qcom,kuno-mem-noc
- qcom,kuno-pcie-anoc
- qcom,kuno-system-noc
reg:
maxItems: 1
clocks:
minItems: 1
maxItems: 2
required:
- compatible
allOf:
- $ref: qcom,rpmh-common.yaml#
- if:
properties:
compatible:
contains:
enum:
- qcom,kuno-clk-virt
- qcom,kuno-mc-virt
then:
properties:
reg: false
else:
required:
- reg
- if:
properties:
compatible:
contains:
const: qcom,kuno-aggre-noc
then:
properties:
clocks:
items:
- description: System NoC USB SF AXI clock
- description: IPA clock
- if:
properties:
compatible:
contains:
const: qcom,kuno-system-noc
then:
properties:
clocks:
items:
- description: IPA clock
- if:
properties:
compatible:
contains:
enum:
- qcom,kuno-aggre-noc
- qcom,kuno-system-noc
then:
required:
- clocks
else:
properties:
clocks: false
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/clock/qcom,kuno-gcc.h>
#include <dt-bindings/clock/qcom,rpmh.h>
clk_virt: interconnect-0 {
compatible = "qcom,kuno-clk-virt";
#interconnect-cells = <1>;
qcom,bcm-voters = <&apps_bcm_voter>;
};
aggre_noc: interconnect@1640000 {
compatible = "qcom,kuno-aggre-noc";
reg = <0x01640000 0x33400>;
clocks = <&gcc GCC_SYS_NOC_USB_SF_AXI_CLK>,
<&rpmhcc RPMH_IPA_CLK>;
#interconnect-cells = <1>;
qcom,bcm-voters = <&apps_bcm_voter>;
};
...
@@ -31,6 +31,7 @@ properties:
- items:
- enum:
- qcom,eliza-epss-l3
- qcom,milos-epss-l3
- qcom,sa8775p-epss-l3
- qcom,sc7280-epss-l3
- qcom,sc8280xp-epss-l3
@@ -159,6 +159,23 @@ properties:
required:
- compatible
efuse:
type: object
unevaluatedProperties: false
description:
The efuse is responsible for storing calibration data, such as thermal
sensor calibration.
properties:
compatible:
const: mediatek,mt6323-efuse
nvmem-layout:
$ref: /schemas/nvmem/layouts/nvmem-layout.yaml#
required:
- compatible
leds:
type: object
additionalProperties: false
@@ -307,6 +324,10 @@ examples:
interrupt-controller;
#interrupt-cells = <2>;
efuse {
compatible = "mediatek,mt6323-efuse";
};
leds {
compatible = "mediatek,mt6323-led";
#address-cells = <1>;
@@ -0,0 +1,146 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/misc/pci1179,0220.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Toshiba TC9564 internal PCI endpoint function
maintainers:
- Alex Elder <elder@kernel.org>
- Daniel Thompson <danielt@kernel.org>
description: >
The Toshiba TC9564 is specialized SoC that implements a PCIe switch
as well as an Ethernet AVB/TSN bridge. In addition to these, the SoC
implements other functions, including a reset and clock controller,
an address translation unit, and a few other devices.
The PCI switch has three downstream ports. The first two are exposed
externally, while the third is used by an internal PCIe endpoint. The
internal endpoint implements two PCIe functions, and attached to each
of these is a 10 Gbps capable Synopsys Ethernet controller and an
interrupt controller that converts internal "wired" interrupts into
MSIs delivered to the host.
PCIe BARs provide access to registers that manage almost all IP blocks.
The SoC is modeled using a PCI endpoint bus. The IP blocks are bound
to platform drivers that access the hardware using MMIO through the
PCI BARs.
------------------------------------
| Host |
-----........---------------...-----
| | | |
| PCIe | |I2C|
| | | |
----------+........+-------------+...+-------------------------------
| |upstream| | | ---------------- |
| Toshiba | Port 0 | | +-------+ PCIe pwrctrl | |
| TC9564 ----++---- | I2C | ---------------- |
| SoC || |controller| ---------------- |
| || | +-------+ GPIO | |
| || | | | controller | |
| ------++------ ------------ ---------------- |
| | US | |
| | | ---------------------------------------- |
| | DS3+====+ downstream port 3 | |
| | | |--------------------------------------| |
| | PCIe | | embedded PCIe endpoint | |
| | switch | |~~~~~~~~~~~~~~~~~~~++~~~~~~~~~~~~~~~~~| |
| | | | PCIe function 0 || PCIe function 1 | |
| | | |-------------------||-----------------| |
| | | | BAR || BAR || BAR || BAR | BAR | BAR | |
| | | | 0 || 2 || 4 || 0 | 2 | 4 | |
| | DS1 DS2 | ---.------.------.--++--------------.--- |
| --++------++-- : : : : |
| || || : ---.-- :....... : |
| || || : |SRAM| : : : |
| || || : ------ : ---.--- : |
| || || : ....: |clock| ....: |
| || || : : : ------- : : |
| || || ------.---- -.- : -.- : |
| || || |translate| |M| :....... |M| : |
| || || ----------- |S| : : |S| : |
| || || |I| : ---.--- |I| : |
| || || |G| : |reset| |G| : |
| || || |E| : ------- |E| : |
| --------++-- --++-------- |N| : |N| : |
| |downstream| |downstream| ------.---- ------.---- |
| | port 1 | | port 2 | | XGMAC 0 | | XGMAC 1 | |
--+..........+--+..........+----------+.......+-----------+.....+----
| | | |
|USXGMII| |SGMII|
| | | |
--+.......+-- ---+.....+---
| Ethernet | | Ethernet |
| PHY | | PHY |
------------- -------------
allOf:
- $ref: /schemas/pci/pci-ep-bus.yaml
properties:
compatible:
const: pci1179,0220 # Toshiba TC9564 (a.k.a. Qualcomm QPS615)
reg:
maxItems: 1
description: PCI Bus/Device/Function config space address
unevaluatedProperties: false
required:
- compatible
- reg
- '#address-cells'
- '#size-cells'
- ranges
examples:
- |
pcie@0,0 {
reg = <0x0 0x0>;
#address-cells = <3>;
#size-cells = <2>;
device_type = "pci";
ranges = <0x83000000 0x0 0x0 0x0 0x0 0x1fd00000>;
dev@0,0 {
compatible = "pci1179,0220";
reg = <0x0 0x0 0x0 0x0 0x0>;
#address-cells = <3>;
#size-cells = <2>;
/* Ranges will be updated dynamically */
ranges = <0x0 0x0 0x0 0x83000000 0x0 0x0 0x0 0x4000>,
<0x2 0x0 0x0 0x83000000 0x0 0x4000 0x0 0x80000>,
<0x4 0x0 0x0 0x83000000 0x0 0x84000 0x0 0x200000>;
pci-ep-bus@4 {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
/* Map 0x0-0x1fffff to BAR 4 */
ranges = <0x0 0x4 0x0 0x0 0x200000>;
};
};
dev@0,1 {
compatible = "pci1179,0220";
reg = <0x100 0x0 0x0 0x0 0x0>;
#address-cells = <3>;
#size-cells = <2>;
/* Ranges will be updated dynamically */
ranges = <0x0 0x0 0x0 0x83000100 0x0 0x0 0x0 0x4000>,
<0x2 0x0 0x0 0x83000100 0x0 0x4000 0x0 0x80000>,
<0x4 0x0 0x0 0x83000100 0x0 0x84000 0x0 0x200000>;
pci-ep-bus@4 {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
/* Map 0x0-0x1fffff to BAR 4 */
ranges = <0x0 0x4 0x0 0x0 0x200000>;
};
};
};
@@ -31,6 +31,7 @@ properties:
- qcom,ipq9574-qfprom
- qcom,ipq9650-qfprom
- qcom,kaanapali-qfprom
- qcom,maili-qfprom
- qcom,milos-qfprom
- qcom,msm8226-qfprom
- qcom,msm8916-qfprom
@@ -16,7 +16,11 @@ allOf:
properties:
compatible:
const: socionext,uniphier-efuse
oneOf:
- const: socionext,uniphier-efuse
- items:
- const: ti,am62p-efuse
- const: socionext,uniphier-efuse
reg:
maxItems: 1
@@ -150,6 +150,13 @@ properties:
minItems: 2
maxItems: 4
spi-device-addr:
$ref: /schemas/types.yaml#/definitions/uint32-array
description:
Device addresses used when multiple peripherals share a single chip
select. The array allows one logical peripheral to comprise multiple
physical devices, with one address per physical device.
st,spi-midi-ns:
deprecated: true
description: |
@@ -62,6 +62,8 @@ properties:
# Aosong temperature & humidity sensors with I2C interface
- aosong,aht10
- aosong,aht20
- aosong,am2315
- aosong,am2320
- aosong,dht20
# Arduino microcontroller interface over SPI on UnoQ board
- arduino,unoq-mcu
@@ -79,8 +81,6 @@ properties:
- atmel,atsha204a
# BPA-RS600: Power Supply
- blutek,bpa-rs600
# CM32181: Ambient Light Sensor
- capella,cm32181
# CM3232: Ambient Light Sensor
- capella,cm3232
# CM3323: Ambient Light Sensor
@@ -402,8 +402,6 @@ properties:
- onnn,adt7462
# 48-Lane, 12-Port PCI Express Gen 2 (5.0 GT/s) Switch
- plx,pex8648
# Pulsedlight LIDAR range-finding sensor
- pulsedlight,lidar-lite-v2
# Renesas HS3001 Temperature and Relative Humidity Sensors
- renesas,hs3001
# Renesas ISL29501 time-of-flight sensor
+275
View File
@@ -0,0 +1,275 @@
.. SPDX-License-Identifier: GPL-2.0-only
=============
AD7768 driver
=============
ADC driver for Analog Devices Inc. AD7768 and AD7768-4 devices. The module name
is ``ad7768``.
Supported devices
=================
The following chips are supported by this driver:
* `AD7768 <https://www.analog.com/en/products/ad7768.html>`_ -
8-channel, 24-bit simultaneous sampling ADC
* `AD7768-4 <https://www.analog.com/en/products/ad7768-4.html>`_ -
4-channel, 24-bit simultaneous sampling ADC
Supported features
==================
Clock sources
-------------
The master clock source is selected using the ``clock-names`` device tree
property:
* ``mclk`` selects a CMOS clock on XTAL2/MCLK. CLK_SEL must be low and XTAL1
must be connected to DGND.
* ``xtal`` selects a crystal connected between XTAL1 and XTAL2. CLK_SEL must
be high. The driver drives FILTER/GPIO4 high and keeps channel 4 on the
AD7768 or channel 2 on the AD7768-4 enabled to maintain crystal excitation.
* ``lvds`` selects a differential clock on XTAL1 and XTAL2. CLK_SEL must be
high. The driver drives FILTER/GPIO4 low before enabling the LVDS input.
GPIO4 is reserved when ``xtal`` or ``lvds`` is selected.
Power modes
-----------
The AD7768 family supports three power and performance modes:
* **Low power mode** - Optimized for lowest power consumption
* **Median mode** - Balanced power and performance
* **Fast mode** - Highest performance with maximum sampling rates
The driver initializes the device in fast mode and uses the maximum fast-mode
output data rate as the default sampling frequency.
When buffered capture starts, the driver selects the lowest-noise mode that can
produce the requested output data rates for all enabled channels. Where output
data rates overlap, fast mode is preferred over median mode, and median mode is
preferred over low power mode. This prioritizes the lower RMS noise and higher
dynamic range offered by a faster mode at the same output data rate.
Data output configuration
-------------------------
The devices support flexible serial data output configurations:
AD7768 data lines
^^^^^^^^^^^^^^^^^
* 1 data line (DOUT0) - Standard single-lane output
* 2 data lines (DOUT0, DOUT1) - Dual-lane output for higher throughput
* 8 data lines (DOUT0-DOUT7) - Maximum throughput, one line per channel
AD7768-4 data lines
^^^^^^^^^^^^^^^^^^^
* 1 data line (DOUT0) - Standard single-lane output
* 4 data lines (DOUT0-DOUT3) - Maximum throughput, one line per channel
The number of data lines can be configured via the ``adi,data-lines-number``
device tree property. If omitted, the driver uses the maximum supported by the
selected variant: eight lines for AD7768 and four lines for AD7768-4.
Channel configuration
---------------------
Each channel can be individually configured with:
Channel modes
^^^^^^^^^^^^^
* **Mode A** - First set of filter and decimation settings
* **Mode B** - Second set of filter and decimation settings
The hardware provides two mode profiles (A and B), each holding one
(frequency, filter) combination. When buffered capture is started,
enabled channels are grouped by their configured (frequency, filter)
pair. Up to two distinct groups are supported; the driver automatically
assigns each group to a mode slot and programs the hardware accordingly.
If the enabled channels request more than two distinct pairs, buffer setup
fails and capture does not start.
Precharge and reference buffers
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Per-channel buffer control for optimal signal integrity:
* Positive input precharge buffer (``adi,prechargebuf-pos-enable``)
* Negative input precharge buffer (``adi,prechargebuf-neg-enable``)
* Positive reference buffer (``adi,refbuf-pos-enable``)
* Negative reference buffer (``adi,refbuf-neg-enable``)
Common mode voltage
-------------------
The VCM pin provides a buffered common-mode voltage output used to bias
the analog inputs. The driver exposes this as a standard voltage regulator
provider under a ``regulators`` subnode in the device tree. Supported
output voltage levels are:
* (AVDD1 - AVSS) / 2 - Mid-supply (hardware default), reported as half the
voltage provided by ``avdd1-supply``
* 1,650,000 µV - 1.65V
* 2,500,000 µV - 2.5V
* 2,140,000 µV - 2.14V
The regulator can be enabled and disabled at runtime using the standard
regulator framework interfaces.
The VCM circuitry is associated with channel 0. When VCM is used externally,
``channel@0`` must be present in the device tree and channel 0 must remain
enabled in the active scan mask. Placing channel 0 in standby disables the VCM
output.
Filter types
------------
Two digital filter types are available:
* **Wideband** - Optimized for wide bandwidth applications
* **Sinc5** - Fifth-order sinc filter for high rejection of out-of-band noise
IIO backend support
-------------------
The driver integrates with IIO backends (e.g., AXI ADC) for high-speed data
capture and DMA operations. Features include:
* Automatic channel enable/disable based on scan mask
* CRC on data interface. CRC replaces the header every 4th output sample.
* High-throughput buffered data acquisition
GPIO controller
---------------
The AD7768 includes a 5-pin GPIO controller for auxiliary digital I/O
operations. The GPIO pins can be configured as inputs or outputs.
GPIO4 is reserved when a crystal or LVDS master clock is used. GPIO0 through
GPIO3 remain available in these configurations.
Device attributes
=================
The following IIO attributes are available for each enabled channel:
Voltage scale
-------------
.. list-table::
:header-rows: 1
:widths: 40 60
* - Attribute
- Description
* - ``in_voltage<N>_scale``
- Scale in millivolts per least significant bit for signed 24-bit data,
calculated as twice the differential reference voltage used by channel
N divided by 2\ :sup:`24`.
Sampling frequency
------------------
.. list-table::
:header-rows: 1
:widths: 40 60
* - Attribute
- Description
* - ``in_voltage<N>_sampling_frequency``
- Requested sampling frequency in Hz for channel N. Enabled channels are
grouped into up to two profiles at capture time.
* - ``in_voltage<N>_sampling_frequency_available``
- Available sampling frequencies in Hz for channel N across all power
modes, based on the master clock frequency. Buffer setup fails if no
single power mode supports the frequencies requested by all enabled
channels.
Filter configuration
---------------------
.. list-table::
:header-rows: 1
:widths: 40 60
* - Attribute
- Description
* - ``in_voltage<N>_filter_type``
- Requested filter type for channel N: "wideband" or "sinc5". It is
grouped with sampling frequency at capture time.
* - ``in_voltage<N>_filter_type_available``
- Available filter types for channel N: "wideband sinc5".
Per-channel calibration
-----------------------
.. list-table::
:header-rows: 1
:widths: 40 60
* - Attribute
- Description
* - ``in_voltage<N>_calibbias``
- Signed 24-bit two's complement channel offset register value.
* - ``in_voltage<N>_calibscale``
- Raw unsigned 24-bit channel gain register value.
* - ``in_voltage<N>_convdelay``
- Per-channel conversion delay. The driver exposes the sync phase offset
value in seconds with picosecond precision. Resolution and valid range
depend on the decimation ratio in use (see datasheet
Table 32).
Device buffers
==============
This driver supports IIO buffered data acquisition through IIO backends.
When used with compatible backends like the AXI ADC, it provides:
* High-speed simultaneous sampling across all enabled channels
* Hardware-driven data capture
* DMA-based data transfer for minimal CPU overhead
* CRC error detection
See :doc:`iio_devbuf` for more information about IIO device buffers.
Example usage
=============
.. code-block:: bash
# Read current sampling frequency for channel 0
cat /sys/bus/iio/devices/iio:device0/in_voltage0_sampling_frequency
# Update sampling frequency for channel 0
echo 8000 > /sys/bus/iio/devices/iio:device0/in_voltage0_sampling_frequency
# Read current filter type for channel 0
cat /sys/bus/iio/devices/iio:device0/in_voltage0_filter_type
# List available filter types for channel 0
cat /sys/bus/iio/devices/iio:device0/in_voltage0_filter_type_available
# Update filter type for channel 0 to wideband
echo wideband > /sys/bus/iio/devices/iio:device0/in_voltage0_filter_type
# Buffer setup fails if enabled channels request more than two distinct
# (sampling frequency, filter type) combinations.
# Read calibration scale for channel 0
cat /sys/bus/iio/devices/iio:device0/in_voltage0_calibscale
# Read conversion delay for channel 0
cat /sys/bus/iio/devices/iio:device0/in_voltage0_convdelay
Unimplemented features
======================
* CRC message every 16 samples (CRC_SEL configuration) - currently only
supports CRC every 4 samples
+792
View File
@@ -0,0 +1,792 @@
.. SPDX-License-Identifier: GPL-2.0-only
=============
AD9910 driver
=============
Direct Digital Synthesizer (DDS) driver for the Analog Devices Inc. AD9910.
The module name is ``ad9910``.
* `AD9910 <https://www.analog.com/en/products/ad9910.html>`_
The AD9910 is a 1 GSPS DDS with a 14-bit DAC, controlled over SPI. The driver
exposes the device through a hierarchy of typed IIO output channels. The root
``phy`` channel controls the system clock and full-scale output current.
Sub-channels provide independent control over single tone profiles, parallel
port modulation, digital ramp generation (DRG), RAM playback and output shift
keying (OSK).
Channel hierarchy
=================
The driver exposes the following IIO output channels, each identified by a
unique channel number and a human-readable label. The ``phy`` channel is the
root of the hierarchy. Changing its ``sampling_frequency`` reconfigures the
system clock (SYSCLK) which affects all other channels.
.. flat-table::
:header-rows: 1
* - Channel
- Label
- Parent
- Description
* - ``out_altcurrent100``
- ``phy``
-
- Physical output: system clock and full-scale output current (:math:`I_{FS}`).
See `Physical channel`_.
* - ``out_altcurrent110`` ... ``out_altcurrent117``
- ``profile0`` ... ``profile7``
- ``phy``
- Single tone control: frequency, phase, amplitude, enable.
See `Single Tone mode`_.
* - ``out_altcurrent120``
- ``parallel_amplitude``
- ``phy``
- Parallel port amplitude channel.
See `Parallel Port mode`_.
* - ``out_phase120``
- ``parallel_phase``
- ``phy``
- Parallel port phase channel.
* - ``out_frequency120``
- ``parallel_frequency``
- ``phy``
- Parallel port frequency channel: ``scale`` sets the FM gain
(power-of-2 multiplier), ``offset`` sets the base FTW.
* - ``out_altcurrent121``
- ``parallel_polar_amplitude``
- ``phy``
- Parallel polar amplitude channel: ``scale`` is the amplitude
resolution, ``offset`` is the amplitude bias (lower 6 bits of ASF).
* - ``out_phase121``
- ``parallel_polar_phase``
- ``phy``
- Parallel polar phase channel: ``scale`` is the phase resolution,
``offset`` is the phase bias (lower 8 bits of POW).
* - ``out_frequency130``
- ``drg_frequency``
- ``phy``
- DRG frequency channel: ``en`` selects and enables the DRG with
frequency as the ramp target.
See `Digital ramp generator (DRG)`_.
* - ``out_frequency131``
- ``drg_rising_frequency``
- ``drg_frequency``
- DRG frequency rising-ramp parameters: limit code, dwell enable,
ramp clock, rate of change.
* - ``out_frequency132``
- ``drg_falling_frequency``
- ``drg_frequency``
- DRG frequency falling-ramp parameters: limit code, dwell enable,
ramp clock, rate of change.
* - ``out_phase130``
- ``drg_phase``
- ``phy``
- DRG phase channel: ``en`` selects and enables the DRG with phase
as the ramp target.
See `Digital ramp generator (DRG)`_.
* - ``out_phase131``
- ``drg_rising_phase``
- ``drg_phase``
- DRG phase rising-ramp parameters: limit code, dwell enable, ramp clock,
rate of change.
* - ``out_phase132``
- ``drg_falling_phase``
- ``drg_phase``
- DRG phase falling-ramp parameters: limit code, dwell enable, ramp clock,
rate of change.
* - ``out_altcurrent130``
- ``drg_amplitude``
- ``phy``
- DRG amplitude channel: ``en`` selects and enables the DRG with
amplitude as the ramp target.
See `Digital ramp generator (DRG)`_.
* - ``out_altcurrent131``
- ``drg_rising_amplitude``
- ``drg_amplitude``
- DRG amplitude rising-ramp parameters: limit code, dwell enable,
ramp clock, rate of change.
* - ``out_altcurrent132``
- ``drg_falling_amplitude``
- ``drg_amplitude``
- DRG amplitude falling-ramp parameters: limit code, dwell enable,
ramp clock, rate of change.
* - ``out_altcurrent140``
- ``ram``
- ``phy``
- RAM playback: enable, frequency, phase and sampling frequency for
the active profile. See `RAM mode`_.
* - ``out_altcurrent150``
- ``osk``
- ``phy``
- Output shift keying (OSK): enable, amplitude code, ramp rate,
rate of change. See `Output Shift Keying (OSK)`_.
DDS modes
=========
The AD9910 supports multiple modes of operation that can be configured
independently or in combination. Each DDS core parameter (frequency, phase
and amplitude) can come from different sources, but only one is active at a
time. This activation depends on a priority list, which is based on the enable
and destination configurations for such modes. The following tables are
extracted from the AD9910 datasheet and summarize the control parameters for
each mode and their priority when multiple sources are enabled simultaneously:
.. flat-table:: DDS Frequency Control
:header-rows: 1
* - Priority
- Data Source
- Conditions
* - Highest Priority
- RAM
- RAM enabled and data destination is frequency
* -
- DRG
- DRG enabled and data destination is frequency
* -
- Parallel data and Frequency Tuning Word, FTW (frequency_offset)
- Parallel data port enabled and data destination is frequency
* -
- FTW register (frequency)
- RAM enabled and data destination is not frequency
* - Lowest Priority
- FTW (frequency) in single tone channel for the active profile
- All other cases
.. flat-table:: DDS Phase Control
:header-rows: 1
* - Priority
- Data Source
- Conditions
* - Highest Priority
- RAM
- RAM enabled and data destination is phase or polar
* -
- DRG
- DRG enabled and data destination is phase
* -
- Parallel data port
- Parallel data port enabled and data destination is phase
* -
- Parallel data port and Phase Offset Word, POW register LSBs (phase_offset)
- Parallel data port enabled and data destination is polar
* -
- POW register (phase)
- RAM enabled and destination is not phase nor polar
* - Lowest Priority
- POW (phase) in single tone channel for the active profile
- All other cases
.. flat-table:: DDS Amplitude Control
:header-rows: 1
* - Priority
- Data Source
- Conditions
* - Highest Priority
- Amplitude Scale Factor, ASF register and OSK generator
- OSK enabled
* -
- RAM
- RAM enabled and data destination is amplitude or polar
* -
- DRG
- DRG enabled and data destination is amplitude
* -
- Parallel data port
- Parallel data port enabled and data destination is amplitude
* -
- Parallel data port and ASF register LSBs (scale_offset)
- Parallel data port enabled and data destination is polar
* - Lowest Priority
- ASF (scale) in single tone channel for the active profile
- (Amplitude scale is already enabled by default)
While debugging or testing, the debug attributes ``frequency_source``,
``phase_source`` and ``amplitude_source`` can be used to read the label of
the channel that is actively controlling the correspondent DDS parameter,
which reflects the priority list described above.
Single Tone mode
----------------
Single tone is the baseline operating mode. The ``profileY`` channels
provide enable, frequency, phase and amplitude control:
.. flat-table::
:header-rows: 1
* - Attribute
- Unit
- Description
* - ``en``
- boolean (0 or 1)
- Enable/disable profile Y. Only one profile can be active at a
time. When enabling a profile it disables the current active profile.
Disabling an active profile brings the device to a powered down state.
* - ``frequency``
- Hz
- Output frequency. Range :math:`[0, f_{SYSCLK} / 2)`. Stored in the
profile's frequency tuning word (FTW).
* - ``phase``
- rad
- Phase offset. Range :math:`[0, 2\pi)`. Stored in the profile's phase
offset word (POW).
* - ``raw``
- integer
- Amplitude scale factor code. Range :math:`[0, 16383]`. Stored in the
profile's amplitude scale factor (ASF) register. The physical output
amplitude is ``raw * scale`` where ``scale`` is read from the ``phy``
channel.
Profile switching is allowed while RAM mode is enabled. In that case single
tone parameters are stored in a shadow register and are not written to
hardware until RAM mode is disabled.
Usage examples
^^^^^^^^^^^^^^
Configure a 100 MHz tone in profile 2 and set it as the active profile:
.. code-block:: bash
echo 100000000 > /sys/bus/iio/devices/iio\:device0/out_altcurrent112_frequency
echo 0 > /sys/bus/iio/devices/iio\:device0/out_altcurrent112_phase
echo 16383 > /sys/bus/iio/devices/iio\:device0/out_altcurrent112_raw
# Activate profile 2
echo 1 > /sys/bus/iio/devices/iio\:device0/out_altcurrent112_en
Read back the current single tone frequency:
.. code-block:: bash
cat /sys/bus/iio/devices/iio\:device0/out_altcurrent112_frequency
Parallel Port mode
------------------
The parallel port allows real-time modulation of DDS parameters through a
16-bit external data bus. The driver exposes separate typed channels for each
modulation target.
Non-polar modulation
^^^^^^^^^^^^^^^^^^^^
In non-polar mode each DDS parameter is controlled by an independent 16-bit bus
input. The parallel port channels expose the resolution and base offset of their
respective bus inputs:
.. flat-table::
:header-rows: 1
* - Channel
- Attribute
- Unit
- Description
* - ``out_phase120``
- ``scale``
- rad
- Phase resolution per parallel bus LSB. Fixed at :math:`\pi / 2^{15}`
rad/LSB (full 16-bit POW resolution).
* - ``out_frequency120``
- ``scale``
- Hz
- Outputs the frequency scale evaluated as
:math:`f_{SYSCLK} \cdot FM / 2^{32}`. Assuming that :math:`f_{SYSCLK}` is
fixed, it is used to configure the modulation gain :math:`FM`, which is a
power-of-2 multiplier in range :math:`[1, 32768]`. Writing to this
attribute rounds up to the nearest :math:`FM` power of 2.
* - ``out_frequency120``
- ``offset``
- Hz
- Outputs the frequency offset in raw units evaluated as :math:`FTW / FM`.
Assuming that :math:`FM` is fixed, it is used to configure the FTW
register, which is a 32-bit unsigned integer.
Polar modulation
^^^^^^^^^^^^^^^^
In polar mode a single 16-bit bus word carries both amplitude (high byte)
and phase (low byte). The ``parallel_polar_amplitude`` and
``parallel_polar_phase`` channels configure the bias applied to the low-order
bits of the ASF and POW registers respectively:
.. flat-table::
:header-rows: 1
* - Channel
- Attribute
- Unit
- Description
* - ``out_altcurrent121``
- ``scale``
- mA/LSB
- Full-scale amplitude resolution (read-only, fixed at :math:`I_{FS} / 2^{8}`).
* - ``out_altcurrent121``
- ``offset``
- fractional (raw units)
- Amplitude bias. Lower 6 bits of ASF register. Range :math:`[0, 1)`.
* - ``out_phase121``
- ``scale``
- rad/LSB
- Phase resolution (read-only, fixed at :math:`\pi / 2^{7}`).
* - ``out_phase121``
- ``offset``
- fractional (raw units)
- Phase bias. Lower 8 bits of POW register. Range :math:`[0, 1)`.
Usage examples
^^^^^^^^^^^^^^
Set parallel port frequency modulation with a modulation gain of 16 and a 50 MHz
offset:
.. code-block:: bash
# f_SYSCLK = 1 GHz, FM = 16
# frequency scale = f_SYSCLK * FM / 2^32 = 3.725290298
echo 3.725290298 > /sys/bus/iio/devices/iio\:device0/out_frequency120_scale
# frequency offset = 50 MHz / scale = 50e6 / 13421772.8
echo 13421772.8 > /sys/bus/iio/devices/iio\:device0/out_frequency120_offset
One should choose a frequency scale that allows all the desired frequencies
to be represented in the 16-bit bus range, i.e.,
:math:`scale = (f_{max} - f_{min}) / 2^{16}`.
Digital ramp generator (DRG)
----------------------------
The DRG produces linear frequency, phase or amplitude sweeps using dedicated
hardware. The active ramp target (destination) is selected by enabling the
corresponding typed channel at channel number 130:
- ``out_frequency130`` (label ``drg_frequency``) — ramp targets frequency
- ``out_phase130`` (label ``drg_phase``) — ramp targets phase
- ``out_altcurrent130`` (label ``drg_amplitude``) — ramp targets amplitude
Writing ``en=1`` to one of these channels enables the DRG and switches its
destination. Writing ``en=0`` disables the DRG if the channel is the current
active destination; writing to an already-inactive destination is a no-op.
Each destination channel also exposes a read-only ``scale`` attribute
reporting the physical quantity per ramp register LSB, which allows converting
raw limit codes to physical values.
The six ramp channels:
- ``out_frequency131`` (label ``drg_rising_frequency``)
- ``out_frequency132`` (label ``drg_falling_frequency``)
- ``out_phase131`` (label ``drg_rising_phase``)
- ``out_phase132`` (label ``drg_falling_phase``)
- ``out_altcurrent131`` (label ``drg_rising_amplitude``)
- ``out_altcurrent132`` (label ``drg_falling_amplitude``)
configure ascending and descending ramp parameters.
Destination channel attributes
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. flat-table::
:header-rows: 1
* - Attribute
- Unit
- Description
* - ``en``
- boolean
- Enable the DRG with this channel as the active destination. Only one
destination can be active at a time.
* - ``scale``
- Hz/LSB, rad/LSB or mA/LSB
- Read-only. Physical quantity per raw units. Multiply a ramp
rising/falling channel ``raw`` value by this scale to get the physical
ramp target.
Ramp channel attributes
^^^^^^^^^^^^^^^^^^^^^^^
.. flat-table::
:header-rows: 1
* - Attribute
- Unit
- Description
* - ``dwell_en``
- boolean
- Enable dwell at the ramp limit. When disabled, the ramp
auto-transitions at this limit without waiting for the DRCTL pin.
Disabling both creates a bidirectional continuous ramp (triangular
pattern). Other combinations create single-shot ramps at the DRCTL
pin transition.
* - ``raw``
- integer (64-bit)
- Ramp limit expressed as a raw DRG register code in
:math:`[0, 2^{32}-1]`. The physical value is ``raw * scale`` where
``scale`` is read from the active destination channel.
* - ``sampling_frequency``
- Hz
- Ramp clock rate. Controlled by an integer divider; the written value
is adjusted to the nearest supported rate.
* - ``raw_roc``
- /s
- Rate of change. Number of register codes advanced per second, computed
from the hardware step size and the current ramp clock. Writing
requires ``sampling_frequency`` to be configured first.
Usage examples
^^^^^^^^^^^^^^
Configure a frequency sweep from 40 MHz to 60 MHz with a rate of change of
25 GHz/s:
.. code-block:: bash
# Disable dwell on both limits for a bidirectional continuous ramp
echo 0 > /sys/bus/iio/devices/iio\:device0/out_frequency131_dwell_en
echo 0 > /sys/bus/iio/devices/iio\:device0/out_frequency132_dwell_en
# Set ramp rate at 250 MHz
echo 250000000 > /sys/bus/iio/devices/iio\:device0/out_frequency131_sampling_frequency
echo 250000000 > /sys/bus/iio/devices/iio\:device0/out_frequency132_sampling_frequency
# read the frequency scale to convert physical values to raw units
cat /sys/bus/iio/devices/iio\:device0/out_frequency130_scale
0.232830643650
# 40 MHz / 0.232830643650 = 171798692
echo 171798692 > /sys/bus/iio/devices/iio\:device0/out_frequency131_raw
# 60 MHz / 0.232830643650 = 257698038
echo 257698038 > /sys/bus/iio/devices/iio\:device0/out_frequency132_raw
# 25 GHz/s / 0.232830643650 = 107374182402
echo 107374182402 > /sys/bus/iio/devices/iio\:device0/out_frequency131_raw_roc
echo 107374182402 > /sys/bus/iio/devices/iio\:device0/out_frequency132_raw_roc
# Enable the DRG with frequency as the destination
echo 1 > /sys/bus/iio/devices/iio\:device0/out_frequency130_en
RAM mode
--------
The AD9910 contains a 1024 x 32-bit RAM that can be loaded with waveform data
and played back to modulate frequency, phase, amplitude, or polar (phase +
amplitude) parameters.
RAM control channel attributes
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. flat-table::
:header-rows: 1
* - Attribute
- Unit
- Description
* - ``en``
- boolean
- Enable/disable RAM playback. Toggling swaps profile registers between
single tone and RAM configurations across all 8 profiles.
* - ``frequency``
- Hz
- Frequency tuning word used as the single tone frequency when
RAM destination is not ``frequency``. Range: :math:`[0, f_{SYSCLK} / 2)`.
* - ``phase``
- rad
- Phase offset word used as the single tone phase when RAM destination
is not ``phase``. Range: :math:`[0, 2\pi)`.
* - ``sampling_frequency``
- Hz
- RAM playback step rate of the active profile, which controls how fast
the address counter advances. Controlled by an integer divider; the
written value is adjusted to the nearest supported rate.
Loading RAM data
^^^^^^^^^^^^^^^^
RAM data is loaded through the firmware upload framework. The driver registers
a firmware upload sysfs entry named ``iio_deviceX:ram``. The firmware data
follows a binary format (version 1) with an 80-byte header followed by data
words. All fields are big-endian.
.. flat-table:: RAM firmware header (80 bytes)
:header-rows: 1
* - Offset
- Size
- Field
- Description
* - 0
- 4
- ``magic``
- Magic number: ``0x00AD9910``
* - 4
- 2
- ``version``
- Format version: ``0x0001``
* - 6
- 2
- ``wcount``
- Number of 32-bit RAM data words (0--1024)
* - 8
- 4
- ``crc``
- CRC32 checksum over ``cfr1``, ``profiles`` and ``words``
* - 12
- 4
- ``cfr1``
- CFR1 register value. Only RAM-relevant bits are used:
bits [30:29] set data destination (00: frequency, 01: phase,
10: amplitude, 11: polar); bits [20:17] set internal profile
control (see datasheet Table 14)
* - 16
- 64
- ``profiles[0..7]``
- 8 sets of 8-byte RAM profile configurations (see below)
* - 80
- 4 x wcount
- ``words[]``
- RAM data words in reverse order
Each 8-byte profile entry contains:
.. flat-table:: RAM profile entry (8 bytes)
:header-rows: 1
* - Bits
- Field
- Description
* - [55:40]
- Address step rate
- Controls playback speed for this profile
* - [39:30]
- End address
- Last RAM address for this profile
* - [23:14]
- Start address
- First RAM address for this profile
* - [5]
- No-dwell high
- No-dwell at high limit (ramp-up mode)
* - [3]
- Zero-crossing
- Zero-crossing enable (direct-switch mode)
* - [2:0]
- Operating mode
- 000: direct switch, 001: ramp-up, 010: bidirectional,
011: bidirectional continuous, 100: ramp-up continuous
Usage examples
^^^^^^^^^^^^^^
Configure RAM mode with firmware data and enable it:
.. code-block:: bash
# Load RAM data via firmware upload
echo 1 > /sys/class/firmware/iio\:device0\:ram/loading
cat ad9910-ram.bin > /sys/class/firmware/iio\:device0\:ram/data
echo 0 > /sys/class/firmware/iio\:device0\:ram/loading
# Enable RAM mode
echo 1 > /sys/bus/iio/devices/iio\:device0/out_altcurrent140_en
Output Shift Keying (OSK)
-------------------------
OSK controls the output amplitude envelope, allowing the output to be ramped
on/off rather than switched abruptly.
.. flat-table::
:header-rows: 1
* - Attribute
- Unit
- Description
* - ``en``
- boolean (0 or 1)
- Enable/disable OSK.
* - ``raw``
- integer
- Target amplitude code. 14-bit ASF field. Range: :math:`[0, 16383]`.
The physical output amplitude is ``raw * scale`` where ``scale`` is read
from the ``phy`` channel.
* - ``raw_roc``
- /s
- Amplitude ramp rate. Writing a non-zero value enables automatic OSK
and selects the closest hardware step size. Writing ``0`` disables
automatic ramping (manual control via ``raw``). Writing the maximum
available value enables pin-controlled immediate transition.
* - ``raw_roc_available``
- /s
- Lists the available ``raw_roc`` values based on the current
``sampling_frequency``. The first value is always ``0`` (disabled) and
the last value corresponds to pin-controlled immediate mode.
* - ``sampling_frequency``
- Hz
- OSK ramp clock. Controlled by an integer divider; the written value
is adjusted to the nearest supported rate.
Usage examples
^^^^^^^^^^^^^^
Enable OSK with automatic ramping:
.. code-block:: bash
# Set ramp rate 1MHz
echo 1000000 > /sys/bus/iio/devices/iio\:device0/out_altcurrent150_sampling_frequency
# Check available rate of change values
cat /sys/bus/iio/devices/iio\:device0/out_altcurrent150_raw_roc_available
0 1000000 2000000 4000000 8000000 16383000000
# Enable automatic OSK with a rate of change of 8000000 raw units/s
echo 8000000 > /sys/bus/iio/devices/iio\:device0/out_altcurrent150_raw_roc
# Enable OSK
echo 1 > /sys/bus/iio/devices/iio\:device0/out_altcurrent150_en
Enable pin-controlled immediate OSK:
.. code-block:: bash
# Enable OSK in manual mode (no ramp)
echo 0 > /sys/bus/iio/devices/iio\:device0/out_altcurrent150_raw_roc
echo 1 > /sys/bus/iio/devices/iio\:device0/out_altcurrent150_en
# Set target amplitude to full scale
echo 16383 > /sys/bus/iio/devices/iio\:device0/out_altcurrent150_raw
Physical channel
================
The ``phy`` channel provides device-level control:
.. flat-table::
:header-rows: 1
* - Attribute
- Unit
- Description
* - ``sampling_frequency``
- Hz
- System clock (SYSCLK) frequency. When the internal PLL is enabled
(via the ``adi,pll-enable`` devicetree property), configures the PLL
multiplier (Range: :math:`[420, 1000]` MHz). Without PLL, the reference
clock can only be divided by 2.
* - ``scale``
- mA/LSB
- Full-scale DAC output current per amplitude code LSB, which is evaluated
as :math:`I_{FS} / 2^{14}`. Shared across all ``altcurrent`` channels.
Setting this attribute reconfigures the auxiliary DAC full-scale code and
updates the effective amplitude resolution for single tone profiles,
DRG amplitude ramps and OSK.
* - ``powerdown``
- boolean (0 or 1)
- Software power-down. Writing 1 powers down the digital core, DAC,
reference clock input and auxiliary DAC simultaneously.
Usage examples
--------------
Set the system clock to 1 GHz:
.. code-block:: bash
echo 1000000000 > /sys/bus/iio/devices/iio\:device0/out_altcurrent100_sampling_frequency
Read current system clock frequency:
.. code-block:: bash
cat /sys/bus/iio/devices/iio\:device0/out_altcurrent100_sampling_frequency
Power down the device:
.. code-block:: bash
echo 1 > /sys/bus/iio/devices/iio\:device0/out_altcurrent100_powerdown
+16 -10
View File
@@ -1,24 +1,30 @@
.. SPDX-License-Identifier: GPL-2.0
===============
ADE9000 driver
===============
======================
ADE9000/ADE9078 driver
======================
This driver supports Analog Device's ADE9000 energy measurement IC on SPI bus.
This driver supports Analog Devices' ADE9000 and ADE9078 energy measurement
ICs on SPI bus.
1. Supported devices
====================
* `ADE9000 <https://www.analog.com/media/en/technical-documentation/data-sheets/ADE9000.pdf>`_
* `ADE9078 <https://www.analog.com/media/en/technical-documentation/data-sheets/ADE9078.pdf>`_
The ADE9000 is a highly accurate, fully integrated, multiphase energy and power
quality monitoring device. Superior analog performance and a digital signal
processing (DSP) core enable accurate energy monitoring over a wide dynamic
range. An integrated high end reference ensures low drift over temperature
with a combined drift of less than ±25 ppm/°C maximum for the entire channel
including a programmable gain amplifier (PGA) and an analog-to-digital
The ADE9000 and ADE9078 are highly accurate, fully integrated, multiphase energy
and power quality monitoring devices. Superior analog performance and a digital
signal processing (DSP) core enable accurate energy monitoring over a wide
dynamic range. An integrated high end reference ensures low drift over
temperature with a combined drift of less than ±25 ppm/°C maximum for the entire
channel including a programmable gain amplifier (PGA) and an analog-to-digital
converter (ADC).
The ADE9078 does not provide the on-chip dip/swell (sag) detection available on
the ADE9000, so the RMS voltage swell/dip events described below are only
available on the ADE9000.
2. Device attributes
====================
+1 -1
View File
@@ -4,7 +4,7 @@
ADIS16475 driver
================
This driver supports Analog Device's IMUs on SPI bus.
This driver supports Analog Devices' IMUs on SPI bus.
1. Supported devices
====================
+1 -1
View File
@@ -4,7 +4,7 @@
ADIS16480 driver
================
This driver supports Analog Device's IMUs on SPI bus.
This driver supports Analog Devices' IMUs on SPI bus.
1. Supported devices
====================
+1 -1
View File
@@ -4,7 +4,7 @@
ADIS16550 driver
================
This driver supports Analog Device's IMUs on SPI bus.
This driver supports Analog Devices' IMUs on SPI bus.
1. Supported devices
====================
+1 -1
View File
@@ -4,7 +4,7 @@
ADXL313 driver
===============
This driver supports Analog Device's ADXL313 on SPI/I2C bus.
This driver supports Analog Devices' ADXL313 on SPI/I2C bus.
1. Supported devices
====================
+1 -1
View File
@@ -4,7 +4,7 @@
ADXL345 driver
===============
This driver supports Analog Device's ADXL345/375 on SPI/I2C bus.
This driver supports Analog Devices' ADXL345/375 on SPI/I2C bus.
1. Supported Devices
====================
+5 -5
View File
@@ -4,7 +4,7 @@
ADXL380 driver
===============
This driver supports Analog Device's ADXL380/382 on SPI/I2C bus.
This driver supports Analog Devices' ADXL380/382 on SPI/I2C bus.
1. Supported devices
====================
@@ -39,13 +39,13 @@ specific device folder path ``/sys/bus/iio/devices/iio:deviceX``.
+---------------------------------------------------+----------------------------------------------------------+
| in_accel_scale | Scale for the accelerometer channels. |
+---------------------------------------------------+----------------------------------------------------------+
| in_accel_filter_high_pass_3db_frequency | Low pass filter bandwidth. |
| in_accel_filter_high_pass_3db_frequency | High pass filter bandwidth. |
+---------------------------------------------------+----------------------------------------------------------+
| in_accel_filter_high_pass_3db_frequency_available | Available low pass filter bandwidth configurations. |
| in_accel_filter_high_pass_3db_frequency_available | Available high pass filter bandwidth configurations. |
+---------------------------------------------------+----------------------------------------------------------+
| in_accel_filter_low_pass_3db_frequency | High pass filter bandwidth. |
| in_accel_filter_low_pass_3db_frequency | Low pass filter bandwidth. |
+---------------------------------------------------+----------------------------------------------------------+
| in_accel_filter_low_pass_3db_frequency_available | Available high pass filter bandwidth configurations. |
| in_accel_filter_low_pass_3db_frequency_available | Available low pass filter bandwidth configurations. |
+---------------------------------------------------+----------------------------------------------------------+
| in_accel_x_calibbias | Calibration offset for the X-axis accelerometer channel. |
+---------------------------------------------------+----------------------------------------------------------+
+2
View File
@@ -29,7 +29,9 @@ Industrial I/O Kernel Drivers
ad7380
ad7606
ad7625
ad7768
ad7944
ad9910
ade9000
adf41513
adis16475
+95 -1
View File
@@ -651,6 +651,7 @@ F: drivers/iio/accel/adxl355_spi.c
ADXL367 THREE-AXIS DIGITAL ACCELEROMETER DRIVER
M: Marcelo Schmitt <marcelo.schmitt@analog.com>
M: Antoniu Miclaus <antoniu.miclaus@analog.com>
L: linux-iio@vger.kernel.org
S: Supported
W: https://ez.analog.com/linux-software-drivers
@@ -1479,6 +1480,7 @@ L: linux-iio@vger.kernel.org
S: Supported
W: https://ez.analog.com/linux-software-drivers
F: Documentation/devicetree/bindings/iio/dac/adi,ad3530r.yaml
F: Documentation/devicetree/bindings/iio/dac/adi,ad5710r.yaml
F: drivers/iio/dac/ad3530r.c
ANALOG DEVICES INC AD3552R DRIVER
@@ -1528,6 +1530,7 @@ F: drivers/iio/adc/ad4080.c
ANALOG DEVICES INC AD4130 DRIVER
M: Marcelo Schmitt <marcelo.schmitt@analog.com>
M: Antoniu Miclaus <antoniu.miclaus@analog.com>
L: linux-iio@vger.kernel.org
S: Supported
W: https://ez.analog.com/linux-software-drivers
@@ -1582,6 +1585,14 @@ W: https://ez.analog.com/linux-software-drivers
F: Documentation/devicetree/bindings/iio/adc/adi,ad4851.yaml
F: drivers/iio/adc/ad4851.c
ANALOG DEVICES INC AD5529R DRIVER
M: Janani Sunil <janani.sunil@analog.com>
L: linux-iio@vger.kernel.org
S: Supported
W: https://ez.analog.com/linux-software-drivers
F: Documentation/devicetree/bindings/iio/dac/adi,ad5529r.yaml
F: drivers/iio/dac/ad5529r.c
ANALOG DEVICES INC AD5706R DRIVER
M: Alexis Czezar Torreno <alexisczezar.torreno@analog.com>
L: linux-iio@vger.kernel.org
@@ -1633,6 +1644,7 @@ F: drivers/iio/dac/ad7293.c
ANALOG DEVICES INC AD74115 DRIVER
M: Marcelo Schmitt <marcelo.schmitt@analog.com>
M: Antoniu Miclaus <antoniu.miclaus@analog.com>
L: linux-iio@vger.kernel.org
S: Supported
W: https://ez.analog.com/linux-software-drivers
@@ -1641,6 +1653,7 @@ F: drivers/iio/addac/ad74115.c
ANALOG DEVICES INC AD74413R DRIVER
M: Marcelo Schmitt <marcelo.schmitt@analog.com>
M: Antoniu Miclaus <antoniu.miclaus@analog.com>
L: linux-iio@vger.kernel.org
S: Supported
W: https://ez.analog.com/linux-software-drivers
@@ -1668,6 +1681,15 @@ F: Documentation/devicetree/bindings/iio/adc/adi,ad7768-1.yaml
F: drivers/iio/adc/ad7768-1.c
F: include/dt-bindings/iio/adc/adi,ad7768-1.h
ANALOG DEVICES INC AD7768 DRIVER
M: Janani Sunil <janani.sunil@analog.com>
L: linux-iio@vger.kernel.org
S: Supported
W: https://ez.analog.com/linux-software-drivers
F: Documentation/devicetree/bindings/iio/adc/adi,ad7768.yaml
F: Documentation/iio/ad7768.rst
F: drivers/iio/adc/ad7768.c
ANALOG DEVICES INC AD7780 DRIVER
M: Michael Hennerich <Michael.Hennerich@analog.com>
M: Renato Lui Geh <renatogeh@gmail.com>
@@ -1713,6 +1735,17 @@ W: https://ez.analog.com/linux-software-drivers
F: Documentation/devicetree/bindings/iio/dac/adi,ad9739a.yaml
F: drivers/iio/dac/ad9739a.c
ANALOG DEVICES INC AD9910 DRIVER
M: Rodrigo Alencar <rodrigo.alencar@analog.com>
L: linux-iio@vger.kernel.org
S: Supported
W: https://ez.analog.com/linux-software-drivers
F: Documentation/ABI/testing/debugfs-iio-ad9910
F: Documentation/ABI/testing/sysfs-bus-iio-frequency-ad9910
F: Documentation/devicetree/bindings/iio/frequency/adi,ad9910.yaml
F: Documentation/iio/ad9910.rst
F: drivers/iio/frequency/ad9910.c
ANALOG DEVICES INC MAX22007 DRIVER
M: Janani Sunil <janani.sunil@analog.com>
L: linux-iio@vger.kernel.org
@@ -4459,6 +4492,15 @@ S: Orphan
F: Documentation/devicetree/bindings/sound/axentia,*
F: sound/soc/atmel/tse850-pcm5142.c
AXIADO SARADC DRIVER
M: Petar Stepanovic <pstepanovic@axiado.com>
M: Akhila Kavi <akavi@axiado.com>
M: Prasad Bolisetty <pbolisetty@axiado.com>
L: linux-iio@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/iio/adc/axiado,ax3000-saradc.yaml
F: drivers/iio/adc/axiado_saradc.c
AXIADO SGPIO DRIVER
M: Petar Stepanovic <pstepanovic@axiado.com>
M: SriNavmani A <srinavmani@axiado.com>
@@ -12830,6 +12872,7 @@ R: Nuno Sá <nuno.sa@analog.com>
R: Andy Shevchenko <andy@kernel.org>
L: linux-iio@vger.kernel.org
S: Maintained
Q: https://patchwork.kernel.org/project/linux-iio/list/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio.git
F: Documentation/ABI/testing/configfs-iio*
F: Documentation/ABI/testing/sysfs-bus-iio*
@@ -12842,6 +12885,13 @@ F: include/dt-bindings/iio/
F: include/linux/iio/
F: tools/iio/
IIO CORE KUNIT TESTS
M: Rodrigo Alencar <rodrigo.alencar@analog.com>
L: linux-iio@vger.kernel.org
S: Maintained
F: drivers/iio/test/iio-test-channel-prefix.c
F: drivers/iio/test/iio-test-format.c
IIO UNIT CONVERTER
M: Peter Rosin <peda@lysator.liu.se>
L: linux-iio@vger.kernel.org
@@ -16280,6 +16330,15 @@ L: linux-iio@vger.kernel.org
S: Supported
F: drivers/iio/temperature/max30208.c
MAXIM MAX40080 CURRENT SENSE AMPLIFIER DRIVER
M: Ciprian Hegbeli <ciprian.hegbeli@analog.com>
M: Stefan Popa <stefan.popa@analog.com>
L: linux-iio@vger.kernel.org
S: Supported
W: https://ez.analog.com/linux-software-drivers
F: Documentation/devicetree/bindings/iio/adc/adi,max40080.yaml
F: drivers/iio/adc/max40080.c
MAXIM MAX7360 KEYPAD LED MFD DRIVER
M: Mathieu Dubois-Briand <mathieu.dubois-briand@bootlin.com>
S: Maintained
@@ -16451,7 +16510,7 @@ M: Ariana Lazar <ariana.lazar@microchip.com>
L: linux-iio@vger.kernel.org
S: Supported
F: Documentation/devicetree/bindings/iio/dac/microchip,mcp47feb02.yaml
F: drivers/iio/dac/mcp47feb02.c
F: drivers/iio/dac/mcp47feb02*
MCP4821 DAC DRIVER
M: Anshul Dalal <anshulusr@gmail.com>
@@ -16872,6 +16931,11 @@ S: Maintained
F: drivers/iio/adc/mt6323-auxadc.c
F: include/dt-bindings/iio/adc/mediatek,mt6323-auxadc.h
MEDIATEK MT6323 PMIC NVMEM DRIVER
M: Roman Vivchar <rva333@protonmail.com>
S: Maintained
F: drivers/nvmem/mt6323-efuse.c
MEDIATEK MT6735 CLOCK & RESET DRIVERS
M: Yassine Oudjana <y.oudjana@protonmail.com>
L: linux-clk@vger.kernel.org
@@ -17812,6 +17876,7 @@ L: linux-arm-msm@vger.kernel.org
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mani/mhi.git
F: Documentation/ABI/stable/sysfs-bus-mhi
F: Documentation/ABI/testing/sysfs-bus-mhi-devices-loopback
F: Documentation/mhi/
F: drivers/bus/mhi/
F: drivers/pci/endpoint/functions/pci-epf-mhi.c
@@ -22829,6 +22894,14 @@ F: Documentation/networking/device_drivers/cellular/qualcomm/rmnet.rst
F: drivers/net/ethernet/qualcomm/rmnet/
F: include/linux/if_rmnet.h
QUALCOMM SPMI CONTROLLER (PMIC ARBITER) DRIVER
M: Abel Vesa <abelvesa@kernel.org>
M: David Collins <david.collins@oss.qualcomm.com>
L: linux-arm-msm@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/spmi/qcom,*spmi-pmic-arb*.yaml
F: drivers/spmi/spmi-pmic-arb.c
QUALCOMM TEE (QCOMTEE) DRIVER
M: Amirreza Zarrabi <amirreza.zarrabi@oss.qualcomm.com>
L: linux-arm-msm@vger.kernel.org
@@ -26118,6 +26191,7 @@ F: tools/spi/
SPMI SUBSYSTEM
M: Stephen Boyd <sboyd@kernel.org>
M: Abel Vesa <abelvesa@kernel.org>
L: linux-kernel@vger.kernel.org
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/sboyd/spmi.git
@@ -27530,6 +27604,13 @@ S: Maintained
F: Documentation/devicetree/bindings/iio/adc/ti,ads1119.yaml
F: drivers/iio/adc/ti-ads1119.c
TI ADS112C04 ADC DRIVER
M: Kyle Hsieh <kylehsieh1995@gmail.com>
L: linux-iio@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/iio/adc/ti,ads112c04.yaml
F: drivers/iio/adc/ti-ads112c04.c
TI ADS112C14 ADC DRIVER
M: David Lechner <dlechner@baylibre.com>
L: linux-iio@vger.kernel.org
@@ -27954,6 +28035,13 @@ F: Documentation/devicetree/bindings/media/i2c/toshiba,tc358743.txt
F: drivers/media/i2c/tc358743*
F: include/media/i2c/tc358743.h
TOSHIBA TC9564 PCI DRIVER
M: Alex Elder <elder@kernel.org>
M: Daniel Thompson <danielt@kernel.org>
S: Maintained
F: Documentation/devicetree/bindings/misc/pci1179,0220.yaml
F: drivers/misc/tc9564-pci.c
TOSHIBA WMI HOTKEYS DRIVER
M: Azael Avalos <coproscefalo@gmail.com>
L: platform-driver-x86@vger.kernel.org
@@ -29435,6 +29523,12 @@ S: Maintained
F: Documentation/devicetree/bindings/iio/light/vishay,veml6030.yaml
F: drivers/iio/light/veml6030.c
VISHAY VEML6031X00 AMBIENT LIGHT SENSOR DRIVER
M: Javier Carrasco <javier.carrasco.cruz@gmail.com>
S: Maintained
F: Documentation/devicetree/bindings/iio/light/vishay,veml6030.yaml
F: drivers/iio/light/veml6031x00.c
VISHAY VEML6046X00 RGBIR COLOR SENSOR DRIVER
M: Andreas Klinger <ak@it-klinger.de>
S: Maintained
+1 -1
View File
@@ -1980,7 +1980,7 @@ static int handle_goto(struct vc_data *vc, u_char type, u_char ch, u16 key)
maxlen = (*goto_buf >= '0') ? 3 : 4;
if ((ch == '+' || ch == '-') && num == 1)
return 1;
if (ch >= '0' && ch <= '9' && num < maxlen)
if (isdigit(ch) && num < maxlen)
return 1;
if (num < maxlen - 1 || num > maxlen)
goto oops;
@@ -61,6 +61,9 @@ static struct speakup_selection_work speakup_sel_work = {
int speakup_set_selection(struct tty_struct *tty)
{
if (!tty)
return -ENODEV;
/* we get kref here first in order to avoid a subtle race when
* cancelling selection work. getting kref first establishes the
* invariant that if speakup_sel_work.tty is not NULL when
@@ -120,6 +123,9 @@ static struct speakup_selection_work speakup_paste_work = {
int speakup_paste_selection(struct tty_struct *tty)
{
if (!tty)
return -ENODEV;
tty_kref_get(tty);
if (cmpxchg(&speakup_paste_work.tty, NULL, tty)) {
tty_kref_put(tty);
+1 -192
View File
@@ -8,22 +8,8 @@
#include "serialio.h"
#include <linux/serial_core.h>
/* WARNING: Do not change this to <linux/serial.h> without testing that
* SERIAL_PORT_DFNS does get defined to the appropriate value.
*/
#include <asm/serial.h>
#include <linux/serial.h>
#ifndef SERIAL_PORT_DFNS
#define SERIAL_PORT_DFNS
#endif
static void start_serial_interrupt(int irq);
static const struct old_serial_port rs_table[] = {
SERIAL_PORT_DFNS
};
static const struct old_serial_port *serstate;
static int timeouts;
static int spk_serial_out(struct spk_synth *in_synth, const char ch);
@@ -45,111 +31,6 @@ struct spk_io_ops spk_serial_io_ops = {
};
EXPORT_SYMBOL_GPL(spk_serial_io_ops);
const struct old_serial_port *spk_serial_init(int index)
{
int baud = 9600, quot = 0;
unsigned int cval = 0;
int cflag = CREAD | HUPCL | CLOCAL | B9600 | CS8;
const struct old_serial_port *ser;
int err;
if (index >= ARRAY_SIZE(rs_table)) {
pr_info("no port info for ttyS%d\n", index);
return NULL;
}
ser = rs_table + index;
/* Divisor, byte size and parity */
quot = ser->baud_base / baud;
cval = cflag & (CSIZE | CSTOPB);
#if defined(__powerpc__) || defined(__alpha__)
cval >>= 8;
#else /* !__powerpc__ && !__alpha__ */
cval >>= 4;
#endif /* !__powerpc__ && !__alpha__ */
if (cflag & PARENB)
cval |= UART_LCR_PARITY;
if (!(cflag & PARODD))
cval |= UART_LCR_EPAR;
if (synth_request_region(ser->port, 8)) {
/* try to take it back. */
pr_info("Ports not available, trying to steal them\n");
__release_region(&ioport_resource, ser->port, 8);
err = synth_request_region(ser->port, 8);
if (err) {
pr_warn("Unable to allocate port at %x, errno %i",
ser->port, err);
return NULL;
}
}
/* Disable UART interrupts, set DTR and RTS high
* and set speed.
*/
outb(cval | UART_LCR_DLAB, ser->port + UART_LCR); /* set DLAB */
outb(quot & 0xff, ser->port + UART_DLL); /* LS of divisor */
outb(quot >> 8, ser->port + UART_DLM); /* MS of divisor */
outb(cval, ser->port + UART_LCR); /* reset DLAB */
/* Turn off Interrupts */
outb(0, ser->port + UART_IER);
outb(UART_MCR_DTR | UART_MCR_RTS, ser->port + UART_MCR);
/* If we read 0xff from the LSR, there is no UART here. */
if (inb(ser->port + UART_LSR) == 0xff) {
synth_release_region(ser->port, 8);
serstate = NULL;
return NULL;
}
mdelay(1);
speakup_info.port_tts = ser->port;
serstate = ser;
start_serial_interrupt(ser->irq);
return ser;
}
static irqreturn_t synth_readbuf_handler(int irq, void *dev_id)
{
unsigned long flags;
int c;
spin_lock_irqsave(&speakup_info.spinlock, flags);
while (inb_p(speakup_info.port_tts + UART_LSR) & UART_LSR_DR) {
c = inb_p(speakup_info.port_tts + UART_RX);
synth->read_buff_add((u_char)c);
}
spin_unlock_irqrestore(&speakup_info.spinlock, flags);
return IRQ_HANDLED;
}
static void start_serial_interrupt(int irq)
{
int rv;
if (!synth->read_buff_add)
return;
rv = request_irq(irq, synth_readbuf_handler, IRQF_SHARED,
"serial", (void *)synth_readbuf_handler);
if (rv)
pr_err("Unable to request Speakup serial I R Q\n");
/* Set MCR */
outb(UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2,
speakup_info.port_tts + UART_MCR);
/* Turn on Interrupts */
outb(UART_IER_MSI | UART_IER_RLSI | UART_IER_RDI,
speakup_info.port_tts + UART_IER);
inb(speakup_info.port_tts + UART_LSR);
inb(speakup_info.port_tts + UART_RX);
inb(speakup_info.port_tts + UART_IIR);
inb(speakup_info.port_tts + UART_MSR);
outb(1, speakup_info.port_tts + UART_FCR); /* Turn FIFO On */
}
static void spk_serial_send_xchar(struct spk_synth *synth, char ch)
{
int timeout = SPK_XMITR_TIMEOUT;
@@ -169,50 +50,6 @@ static void spk_serial_tiocmset(struct spk_synth *in_synth, unsigned int set, un
outb((old & ~clear) | set, speakup_info.port_tts + UART_MCR);
}
int spk_serial_synth_probe(struct spk_synth *synth)
{
const struct old_serial_port *ser;
int failed = 0;
if ((synth->ser >= SPK_LO_TTY) && (synth->ser <= SPK_HI_TTY)) {
ser = spk_serial_init(synth->ser);
if (!ser) {
failed = -1;
} else {
outb_p(0, ser->port);
mdelay(1);
outb_p('\r', ser->port);
}
} else {
failed = -1;
pr_warn("ttyS%i is an invalid port\n", synth->ser);
}
if (failed) {
pr_info("%s: not found\n", synth->long_name);
return -ENODEV;
}
pr_info("%s: ttyS%i, Driver Version %s\n",
synth->long_name, synth->ser, synth->version);
synth->alive = 1;
return 0;
}
EXPORT_SYMBOL_GPL(spk_serial_synth_probe);
void spk_stop_serial_interrupt(void)
{
if (speakup_info.port_tts == 0)
return;
if (!synth->read_buff_add)
return;
/* Turn off interrupts */
outb(0, speakup_info.port_tts + UART_IER);
/* Free IRQ */
free_irq(serstate->irq, (void *)synth_readbuf_handler);
}
EXPORT_SYMBOL_GPL(spk_stop_serial_interrupt);
static int spk_serial_wait_for_xmitr(struct spk_synth *in_synth)
{
int tmout = SPK_XMITR_TIMEOUT;
@@ -288,31 +125,3 @@ static int spk_serial_out(struct spk_synth *in_synth, const char ch)
}
return 0;
}
const char *spk_serial_synth_immediate(struct spk_synth *synth,
const char *buff)
{
u_char ch;
while ((ch = *buff)) {
if (ch == '\n')
ch = synth->procspeech;
if (spk_serial_wait_for_xmitr(synth))
outb(ch, speakup_info.port_tts);
else
return buff;
buff++;
}
return NULL;
}
EXPORT_SYMBOL_GPL(spk_serial_synth_immediate);
void spk_serial_release(struct spk_synth *synth)
{
spk_stop_serial_interrupt();
if (speakup_info.port_tts == 0)
return;
synth_release_region(speakup_info.port_tts, 8);
speakup_info.port_tts = 0;
}
EXPORT_SYMBOL_GPL(spk_serial_release);
-17
View File
@@ -8,31 +8,14 @@
#include "spk_priv.h"
/*
* this is cut&paste from 8250.h. Get rid of the structure, the definitions
* and this whole broken driver.
*/
struct old_serial_port {
unsigned int uart; /* unused */
unsigned int baud_base;
unsigned int port;
unsigned int irq;
upf_t flags; /* unused */
};
/* countdown values for serial timeouts in us */
#define SPK_SERIAL_TIMEOUT SPK_SYNTH_TIMEOUT
/* countdown values transmitter/dsr timeouts in us */
#define SPK_XMITR_TIMEOUT 100000
/* countdown values cts timeouts in us */
#define SPK_CTS_TIMEOUT 100000
/* check ttyS0 ... ttyS3 */
#define SPK_LO_TTY 0
#define SPK_HI_TTY 3
/* # of timeouts permitted before disable */
#define NUM_DISABLE_TIMEOUTS 3
/* buffer timeout in ms */
#define SPK_TIMEOUT 100
#define spk_serial_tx_busy() \
(!uart_lsr_tx_empty(inb(speakup_info.port_tts + UART_LSR)))
@@ -305,7 +305,6 @@ static int synth_probe(struct spk_synth *synth)
static void accent_release(struct spk_synth *synth)
{
spk_stop_serial_interrupt();
if (speakup_info.port_tts)
synth_release_region(speakup_info.port_tts - 1,
SYNTH_IO_EXTENT);
@@ -487,7 +487,6 @@ static int synth_probe(struct spk_synth *synth)
static void dtpc_release(struct spk_synth *synth)
{
spk_stop_serial_interrupt();
if (speakup_info.port_tts)
synth_release_region(speakup_info.port_tts, SYNTH_IO_EXTENT);
speakup_info.port_tts = 0;
@@ -377,7 +377,6 @@ static int synth_probe(struct spk_synth *synth)
static void dtlk_release(struct spk_synth *synth)
{
spk_stop_serial_interrupt();
if (speakup_info.port_tts)
synth_release_region(speakup_info.port_tts - 1,
SYNTH_IO_EXTENT);
@@ -306,7 +306,6 @@ static int synth_probe(struct spk_synth *synth)
static void keynote_release(struct spk_synth *synth)
{
spk_stop_serial_interrupt();
if (synth_port)
synth_release_region(synth_port, SYNTH_IO_EXTENT);
synth_port = 0;
-6
View File
@@ -32,9 +32,6 @@
#define SYNTH_DEFAULT_DEV "ttyS0"
#define SYNTH_DEFAULT_SER 0
const struct old_serial_port *spk_serial_init(int index);
void spk_stop_serial_interrupt(void);
void spk_serial_release(struct spk_synth *synth);
void spk_ttyio_release(struct spk_synth *synth);
void spk_ttyio_register_ldisc(void);
void spk_ttyio_unregister_ldisc(void);
@@ -49,10 +46,7 @@ ssize_t spk_var_show(struct kobject *kobj, struct kobj_attribute *attr,
ssize_t spk_var_store(struct kobject *kobj, struct kobj_attribute *attr,
const char *buf, size_t count);
int spk_serial_synth_probe(struct spk_synth *synth);
int spk_ttyio_synth_probe(struct spk_synth *synth);
const char *spk_serial_synth_immediate(struct spk_synth *synth,
const char *buff);
const char *spk_ttyio_synth_immediate(struct spk_synth *synth,
const char *buff);
void spk_do_catch_up(struct spk_synth *synth);
+3 -2
View File
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/ctype.h>
#include <linux/string.h>
#include "spk_types.h"
#include "spk_priv.h"
#include "speakup.h"
@@ -265,10 +266,10 @@ int spk_set_string_var(const char *page, struct st_var_header *var, int len)
if (!var->p_val)
var->p_val = var_data->u.s.default_val;
if (var->p_val != var_data->u.s.default_val)
strcpy((char *)var->p_val, var_data->u.s.default_val);
strscpy((char *)var->p_val, var_data->u.s.default_val, MAXVARLEN + 1);
return -ERESTART;
} else if (var->p_val) {
strcpy((char *)var->p_val, page);
strscpy((char *)var->p_val, page, MAXVARLEN + 1);
} else {
return -E2BIG;
}
+3 -38
View File
@@ -1,10 +1,11 @@
# SPDX-License-Identifier: GPL-2.0
menu "Android"
config ANDROID_BINDER_IPC
config ANDROID_BINDER_IPC_RUST
bool "Android Binder IPC Driver"
depends on MMU
depends on NET
depends on RUST
default n
help
Binder is used in Android for both communication between processes,
@@ -14,34 +15,9 @@ config ANDROID_BINDER_IPC
Android process, using Binder to identify, invoke and pass arguments
between said processes.
config ANDROID_BINDER_IPC_RUST
bool "Rust version of Android Binder IPC Driver"
depends on RUST && MMU && NET && !ANDROID_BINDER_IPC
help
This enables the Rust implementation of the Binder driver.
Binder is used in Android for both communication between processes,
and remote method invocation.
This means one Android process can call a method/routine in another
Android process, using Binder to identify, invoke and pass arguments
between said processes.
config ANDROID_BINDERFS
bool "Android Binderfs filesystem"
depends on ANDROID_BINDER_IPC
default n
help
Binderfs is a pseudo-filesystem for the Android Binder IPC driver
which can be mounted per-ipc namespace allowing to run multiple
instances of Android.
Each binderfs mount initially only contains a binder-control device.
It can be used to dynamically allocate new binder IPC devices via
ioctls.
config ANDROID_BINDER_DEVICES
string "Android Binder devices"
depends on ANDROID_BINDER_IPC || ANDROID_BINDER_IPC_RUST
depends on ANDROID_BINDER_IPC_RUST
default "binder,hwbinder,vndbinder"
help
Default value for the binder.devices parameter.
@@ -51,15 +27,4 @@ config ANDROID_BINDER_DEVICES
created. Each binder device has its own context manager, and is
therefore logically separated from the other devices.
config ANDROID_BINDER_ALLOC_KUNIT_TEST
tristate "KUnit Tests for Android Binder Alloc" if !KUNIT_ALL_TESTS
depends on ANDROID_BINDER_IPC && KUNIT
default KUNIT_ALL_TESTS
help
This feature builds the binder alloc KUnit tests.
Each test case runs using a pared-down binder_alloc struct and
test-specific freelist, which allows this KUnit module to be loaded
for testing without interfering with a running system.
endmenu
-3
View File
@@ -1,7 +1,4 @@
# SPDX-License-Identifier: GPL-2.0-only
ccflags-y += -I$(src) # needed for trace events
obj-$(CONFIG_ANDROID_BINDERFS) += binderfs.o
obj-$(CONFIG_ANDROID_BINDER_IPC) += binder.o binder_alloc.o binder_netlink.o
obj-$(CONFIG_ANDROID_BINDER_ALLOC_KUNIT_TEST) += tests/
obj-$(CONFIG_ANDROID_BINDER_IPC_RUST) += binder/
File diff suppressed because it is too large. Load diff
+2 -2
View File
@@ -1,8 +1,8 @@
# SPDX-License-Identifier: GPL-2.0-only
ccflags-y += -I$(src) # needed for trace events
obj-$(CONFIG_ANDROID_BINDER_IPC_RUST) += rust_binder.o
rust_binder-y := \
obj-$(CONFIG_ANDROID_BINDER_IPC_RUST) += binder.o
binder-y := \
rust_binder_main.o \
rust_binderfs.o \
rust_binder_events.o
+12 -5
View File
@@ -20,6 +20,7 @@ use crate::{
defs::*,
node::{Node, NodeRef},
process::Process,
trace::trace_transaction_failed_buffer_release,
DArc,
};
@@ -208,7 +209,7 @@ impl Allocation {
let num_close_on_free = files.iter().filter(|entry| entry.close_on_free).count();
let mut close_on_free = KVec::with_capacity(num_close_on_free, GFP_KERNEL)?;
let mut reservations = KVec::with_capacity(files.len(), GFP_KERNEL)?;
let mut reservations = KVVec::with_capacity(files.len(), GFP_KERNEL)?;
for file_info in files {
let res = FileDescriptorReservation::get_unused_fd_flags(bindings::O_CLOEXEC)?;
let fd = res.reserved_fd();
@@ -325,6 +326,12 @@ impl core::ops::DerefMut for NewAllocation {
}
}
impl Drop for NewAllocation {
fn drop(&mut self) {
trace_transaction_failed_buffer_release(self.debug_id);
}
}
/// A view into the beginning of an allocation.
///
/// All attempts to read or write outside of the view will fail. To intentionally access outside of
@@ -503,7 +510,7 @@ impl BinderObject {
/// The closure should write the bytes for the object into the provided slice.
pub(crate) fn read_from_inner<R>(reader: R) -> Result<BinderObject>
where
R: FnOnce(&mut [u8; size_of::<BinderObject>()]) -> Result<()>,
R: FnOnce(&mut [u8; size_of::<BinderObject>()]) -> Result,
{
let mut obj = MaybeUninit::<BinderObject>::zeroed();
@@ -567,7 +574,7 @@ impl BinderObject {
#[derive(Default)]
struct FileList {
files_to_translate: KVec<FileEntry>,
files_to_translate: KVVec<FileEntry>,
close_on_free: KVec<u32>,
}
@@ -581,7 +588,7 @@ struct FileEntry {
}
pub(crate) struct TranslatedFds {
reservations: KVec<Reservation>,
reservations: KVVec<Reservation>,
/// If commit is called, then these fds should be closed. (If commit is not called, then they
/// shouldn't be closed.)
close_on_free: FdsCloseOnFree,
@@ -595,7 +602,7 @@ struct Reservation {
impl TranslatedFds {
pub(crate) fn new() -> Self {
Self {
reservations: KVec::new(),
reservations: KVVec::new(),
close_on_free: FdsCloseOnFree(KVec::new()),
}
}
+4 -4
View File
@@ -134,13 +134,13 @@ impl Context {
}
pub(crate) fn get_manager_node(&self, strong: bool) -> Result<NodeRef, BinderError> {
self.manager
Ok(self
.manager
.lock()
.node
.as_ref()
.ok_or_else(BinderError::new_dead)?
.clone(strong)
.map_err(BinderError::from)
.ok_or_else(|| BinderError::new_dead())?
.clone(strong)?)
}
pub(crate) fn for_each_proc<F>(&self, mut func: F)
+2 -1
View File
@@ -77,7 +77,8 @@ pub_no_prefix!(
TF_ONE_WAY,
TF_ACCEPT_FDS,
TF_CLEAR_BUF,
TF_UPDATE_TXN
TF_UPDATE_TXN,
TF_DEFER_COMPLETE,
);
pub(crate) use uapi::{
+39 -4
View File
@@ -2,6 +2,7 @@
// Copyright (C) 2025 Google LLC.
use core::panic::Location;
use kernel::fmt;
use kernel::prelude::*;
@@ -9,62 +10,96 @@ use crate::defs::*;
pub(crate) type BinderResult<T = ()> = core::result::Result<T, BinderError>;
/// Wraps a `&'static Location` to format it as `filename.rs:line` without the directory prefix.
#[derive(Copy, Clone)]
#[repr(transparent)]
pub(crate) struct ErrorLocation(&'static Location<'static>);
// SAFETY: `ErrorLocation` is `repr(transparent)` over a shared reference, which is part of the
// option layout optimization guarantee, so all zeroes is a valid representation for `None`.
unsafe impl pin_init::ZeroableOption for ErrorLocation {}
impl ErrorLocation {
#[track_caller]
pub(crate) const fn caller() -> Self {
Self(Location::caller())
}
}
impl fmt::Display for ErrorLocation {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let file = match self.0.file().rsplit_once('/') {
Some((_, file)) => file,
None => self.0.file(),
};
write!(f, "{}:{}", file, self.0.line())
}
}
/// An error that will be returned to userspace via the `BINDER_WRITE_READ` ioctl rather than via
/// errno.
pub(crate) struct BinderError {
pub(crate) reply: u32,
pub(crate) source: Option<Error>,
pub(crate) line: ErrorLocation,
}
impl BinderError {
#[track_caller]
pub(crate) fn new_dead() -> Self {
Self {
reply: BR_DEAD_REPLY,
source: None,
line: ErrorLocation::caller(),
}
}
#[track_caller]
pub(crate) fn new_frozen() -> Self {
Self {
reply: BR_FROZEN_REPLY,
source: None,
line: ErrorLocation::caller(),
}
}
#[track_caller]
pub(crate) fn new_frozen_oneway() -> Self {
Self {
reply: BR_TRANSACTION_PENDING_FROZEN,
source: None,
line: ErrorLocation::caller(),
}
}
pub(crate) fn is_dead(&self) -> bool {
self.reply == BR_DEAD_REPLY
}
}
/// Convert an errno into a `BinderError` and store the errno used to construct it. The errno
/// should be stored as the thread's extended error when given to userspace.
impl From<Error> for BinderError {
#[track_caller]
fn from(source: Error) -> Self {
Self {
reply: BR_FAILED_REPLY,
source: Some(source),
line: ErrorLocation::caller(),
}
}
}
impl From<kernel::fs::file::BadFdError> for BinderError {
#[track_caller]
fn from(source: kernel::fs::file::BadFdError) -> Self {
BinderError::from(Error::from(source))
}
}
impl From<kernel::alloc::AllocError> for BinderError {
#[track_caller]
fn from(_: kernel::alloc::AllocError) -> Self {
Self {
reply: BR_FAILED_REPLY,
source: Some(ENOMEM),
line: ErrorLocation::caller(),
}
}
}
+6 -11
View File
@@ -75,10 +75,8 @@ impl FreezeMessage {
}
fn init(ua: UninitFM, cookie: FreezeCookie, pid: i32) -> DLArc<FreezeMessage> {
match ua.pin_init_with(DTRWrap::new(FreezeMessage { cookie, pid })) {
Ok(msg) => ListArc::from(msg),
Err(err) => match err {},
}
let Ok(msg) = ua.pin_init_with(DTRWrap::new(FreezeMessage { cookie, pid }));
ListArc::from(msg)
}
}
@@ -155,7 +153,7 @@ impl DeliverToRead for FreezeMessage {
}
#[inline(never)]
fn debug_print(&self, m: &SeqFile, prefix: &str, _tprefix: &str) -> Result<()> {
fn debug_print(&self, m: &SeqFile, prefix: &str, _tprefix: &str) -> Result {
seq_print!(m, "{}has frozen binder\n", prefix);
Ok(())
}
@@ -177,10 +175,7 @@ impl FreezeListener {
}
impl Process {
pub(crate) fn request_freeze_notif(
self: &Arc<Self>,
reader: &mut UserSliceReader,
) -> Result<()> {
pub(crate) fn request_freeze_notif(self: &Arc<Self>, reader: &mut UserSliceReader) -> Result {
let hc = reader.read::<BinderHandleCookie>()?;
let handle = hc.handle;
let cookie = FreezeCookie(hc.cookie);
@@ -272,7 +267,7 @@ impl Process {
Ok(())
}
pub(crate) fn freeze_notif_done(self: &Arc<Self>, reader: &mut UserSliceReader) -> Result<()> {
pub(crate) fn freeze_notif_done(self: &Arc<Self>, reader: &mut UserSliceReader) -> Result {
let cookie = FreezeCookie(reader.read()?);
let alloc = FreezeMessage::new(GFP_KERNEL)?;
let mut node_refs_guard = self.node_refs.lock();
@@ -313,7 +308,7 @@ impl Process {
Ok(())
}
pub(crate) fn clear_freeze_notif(self: &Arc<Self>, reader: &mut UserSliceReader) -> Result<()> {
pub(crate) fn clear_freeze_notif(self: &Arc<Self>, reader: &mut UserSliceReader) -> Result {
let hc = reader.read::<BinderHandleCookie>()?;
let handle = hc.handle;
let cookie = FreezeCookie(hc.cookie);
+3 -7
View File
@@ -255,11 +255,7 @@ impl Node {
}
#[inline(never)]
pub(crate) fn full_debug_print(
&self,
m: &SeqFile,
owner_inner: &mut ProcessInner,
) -> Result<()> {
pub(crate) fn full_debug_print(&self, m: &SeqFile, owner_inner: &mut ProcessInner) -> Result {
let inner = self.inner.access_mut(owner_inner);
seq_print!(
m,
@@ -759,7 +755,7 @@ impl DeliverToRead for Node {
}
#[inline(never)]
fn debug_print(&self, m: &SeqFile, prefix: &str, _tprefix: &str) -> Result<()> {
fn debug_print(&self, m: &SeqFile, prefix: &str, _tprefix: &str) -> Result {
seq_print!(
m,
"{}node work {}: u{:016x} c{:016x}\n",
@@ -1154,7 +1150,7 @@ impl DeliverToRead for NodeDeath {
}
#[inline(never)]
fn debug_print(&self, m: &SeqFile, prefix: &str, _tprefix: &str) -> Result<()> {
fn debug_print(&self, m: &SeqFile, prefix: &str, _tprefix: &str) -> Result {
let inner = self.inner.lock();
let dead_binder = inner.dead && !inner.notification_done;
+3 -5
View File
@@ -20,10 +20,8 @@ impl CritIncrWrapper {
}
pub(super) fn init(self, node: DArc<Node>) -> DLArc<dyn DeliverToRead> {
match self.inner.pin_init_with(DTRWrap::new(NodeWrapper { node })) {
Ok(initialized) => ListArc::from(initialized) as DLArc<dyn DeliverToRead>,
Err(err) => match err {},
}
let Ok(initialized) = self.inner.pin_init_with(DTRWrap::new(NodeWrapper { node }));
ListArc::from(initialized) as DLArc<dyn DeliverToRead>
}
}
@@ -96,7 +94,7 @@ impl DeliverToRead for NodeWrapper {
}
#[inline(never)]
fn debug_print(&self, m: &SeqFile, prefix: &str, _tprefix: &str) -> Result<()> {
fn debug_print(&self, m: &SeqFile, prefix: &str, _tprefix: &str) -> Result {
seq_print!(
m,
"{}node work {}: u{:016x} c{:016x}\n",
+3 -3
View File
@@ -66,7 +66,7 @@ impl Shrinker {
}
/// Register this shrinker with the kernel.
pub(crate) fn register(&'static self, name: &CStr) -> Result<()> {
pub(crate) fn register(&'static self, name: &CStr) -> Result {
// SAFETY: These fields are not yet used, so it's okay to zero them.
unsafe {
self.inner.get().write(ptr::null_mut());
@@ -352,7 +352,7 @@ impl ShrinkablePageRange {
/// Make sure that the given pages are allocated and mapped.
///
/// Must not be called from an atomic context.
pub(crate) fn use_range(&self, start: usize, end: usize) -> Result<()> {
pub(crate) fn use_range(&self, start: usize, end: usize) -> Result {
if start >= end {
return Ok(());
}
@@ -398,7 +398,7 @@ impl ShrinkablePageRange {
///
/// Assumes that `i` is in bounds.
#[cold]
unsafe fn use_page_slow(&self, i: usize) -> Result<()> {
unsafe fn use_page_slow(&self, i: usize) -> Result {
let new_page = Page::alloc_page(GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO)?;
let mm_mutex = self.mm_lock.lock();
+23 -22
View File
@@ -548,7 +548,7 @@ impl Process {
}
#[inline(never)]
pub(crate) fn debug_print_stats(&self, m: &SeqFile, ctx: &Context) -> Result<()> {
pub(crate) fn debug_print_stats(&self, m: &SeqFile, ctx: &Context) -> Result {
seq_print!(m, "proc {}\n", self.pid_in_current_ns());
seq_print!(m, "context {}\n", &*ctx.name);
@@ -596,7 +596,7 @@ impl Process {
}
#[inline(never)]
pub(crate) fn debug_print(&self, m: &SeqFile, ctx: &Context, print_all: bool) -> Result<()> {
pub(crate) fn debug_print(&self, m: &SeqFile, ctx: &Context, print_all: bool) -> Result {
seq_print!(m, "proc {}\n", self.pid_in_current_ns());
seq_print!(m, "context {}\n", &*ctx.name);
@@ -686,8 +686,16 @@ impl Process {
pub(crate) fn get_work_or_register<'a>(
&'a self,
thread: &'a Arc<Thread>,
thread_has_deferred_work: bool,
) -> GetWorkOrRegister<'a> {
let mut inner = self.inner.lock();
if thread_has_deferred_work && !inner.work.is_empty() {
if let Some(work) = thread.pop_work_even_if_deferred() {
return GetWorkOrRegister::Work(work);
}
}
// Try to get work from the process queue.
if let Some(work) = inner.work.pop_front() {
return GetWorkOrRegister::Work(work);
@@ -894,11 +902,8 @@ impl Process {
let (info_proc, info_node) = {
let info_init = NodeRefInfo::new(node_ref, handle, self.into());
match info.pin_init_with(info_init) {
Ok(info) => ListArc::pair_from_pin_unique(info),
// error is infallible
Err(err) => match err {},
}
let Ok(info) = info.pin_init_with(info_init);
ListArc::pair_from_pin_unique(info)
};
// Ensure the process is still alive while we insert a new reference.
@@ -1068,7 +1073,10 @@ impl Process {
let (new_alloc, addr) = loop {
let mut inner = self.inner.lock();
let mapping = inner.mapping.as_mut().ok_or_else(BinderError::new_dead)?;
let mapping = inner
.mapping
.as_mut()
.ok_or_else(|| BinderError::new_dead())?;
let alloc_request = match mapping.alloc.reserve_new(reserve_new_args)? {
ReserveNew::Success(new_alloc) => break (new_alloc, mapping.address),
ReserveNew::NeedAlloc(request) => request,
@@ -1208,13 +1216,12 @@ impl Process {
let ptr = reader.read::<BinderNodeDebugInfo>()?.ptr;
let mut out = BinderNodeDebugInfo::default();
{
if let Some(start_ptr) = ptr.checked_add(1) {
let inner = self.inner.lock();
for (node_ptr, node) in &inner.nodes {
if *node_ptr > ptr {
node.populate_debug_info(&mut out, &inner);
break;
}
// cursor_lower_bound retrieves the "key" passed or the next existing larger key
if let Some(cursor) = inner.nodes.cursor_lower_bound(&start_ptr) {
let (_, node) = cursor.current();
node.populate_debug_info(&mut out, &inner);
}
}
@@ -1296,14 +1303,8 @@ impl Process {
return Ok(());
}
let death = {
let death_init = NodeDeath::new(info.node_ref().node.clone(), self.clone(), cookie);
match death.pin_init_with(death_init) {
Ok(death) => death,
// error is infallible
Err(err) => match err {},
}
};
let death_init = NodeDeath::new(info.node_ref().node.clone(), self.clone(), cookie);
let Ok(death) = death.pin_init_with(death_init);
// Register the death notification.
{
+1 -1
View File
@@ -61,7 +61,7 @@ impl<T> ArrayRangeAllocator<T> {
self.ranges.len() == self.ranges.capacity()
}
pub(crate) fn debug_print(&self, m: &SeqFile) -> Result<()> {
pub(crate) fn debug_print(&self, m: &SeqFile) -> Result {
for range in &self.ranges {
seq_print!(
m,
+1 -1
View File
@@ -141,7 +141,7 @@ impl<T> RangeAllocator<T> {
}
}
pub(crate) fn debug_print(&self, m: &SeqFile) -> Result<()> {
pub(crate) fn debug_print(&self, m: &SeqFile) -> Result {
match &self.inner {
Impl::Empty(_size) => Ok(()),
Impl::Array(array) => array.debug_print(m),
+1 -1
View File
@@ -111,7 +111,7 @@ impl<T> TreeRangeAllocator<T> {
.count()
}
pub(crate) fn debug_print(&self, m: &SeqFile) -> Result<()> {
pub(crate) fn debug_print(&self, m: &SeqFile) -> Result {
for desc in self.tree.values() {
let state = match &desc.state {
Some(state) => &state.0,
@@ -177,6 +177,48 @@ TRACE_EVENT(binder_return,
"unknown")
);
TRACE_EVENT(binder_transaction_alloc_buf,
TP_PROTO(int debug_id, size_t data_size, size_t offsets_size, size_t extra_buffers_size),
TP_ARGS(debug_id, data_size, offsets_size, extra_buffers_size),
TP_STRUCT__entry(
__field(int, debug_id)
__field(size_t, data_size)
__field(size_t, offsets_size)
__field(size_t, extra_buffers_size)
),
TP_fast_assign(
__entry->debug_id = debug_id;
__entry->data_size = data_size;
__entry->offsets_size = offsets_size;
__entry->extra_buffers_size = extra_buffers_size;
),
TP_printk("transaction=%d data_size=%zd offsets_size=%zd extra_buffers_size=%zd",
__entry->debug_id, __entry->data_size, __entry->offsets_size,
__entry->extra_buffers_size)
);
DECLARE_EVENT_CLASS(binder_buffer_release_class,
TP_PROTO(int debug_id),
TP_ARGS(debug_id),
TP_STRUCT__entry(
__field(int, debug_id)
),
TP_fast_assign(
__entry->debug_id = debug_id;
),
TP_printk("transaction=%d", __entry->debug_id)
);
#define DEFINE_RBINDER_FUNCTION_BUFFER_EVENT(name) \
DEFINE_EVENT(binder_buffer_release_class, name, \
TP_PROTO(int debug_id), \
TP_ARGS(debug_id))
DEFINE_RBINDER_FUNCTION_BUFFER_EVENT(binder_transaction_buffer_release);
DEFINE_RBINDER_FUNCTION_BUFFER_EVENT(binder_transaction_failed_buffer_release);
DEFINE_RBINDER_FUNCTION_BUFFER_EVENT(binder_transaction_update_buffer_release);
#endif /* _RUST_BINDER_TRACE_H */
/* This part must be outside protection */
@@ -44,6 +44,7 @@ struct binder_device {
int rust_binder_stats_show(struct seq_file *m, void *unused);
int rust_binder_state_show(struct seq_file *m, void *unused);
int rust_binder_transactions_show(struct seq_file *m, void *unused);
int rust_binder_transaction_log_show(struct seq_file *m, void *unused);
int rust_binder_proc_show(struct seq_file *m, void *pid);
extern const struct file_operations rust_binder_fops;
+37 -8
View File
@@ -81,7 +81,7 @@ mod binderfs {
module! {
type: BinderModule,
name: "rust_binder",
name: "binder",
authors: ["Wedson Almeida Filho", "Alice Ryhl"],
description: "Android Binder",
license: "GPL",
@@ -98,7 +98,12 @@ static RUST_BINDER_LAYOUT: rust_binder_layout = rust_binder_layout {
fn next_debug_id() -> usize {
static NEXT_DEBUG_ID: Atomic<usize> = Atomic::new(0);
NEXT_DEBUG_ID.fetch_add(1, Relaxed)
loop {
let id = NEXT_DEBUG_ID.fetch_add(1, Relaxed);
if id != 0 {
return id;
}
}
}
/// Provides a single place to write Binder return values via the
@@ -158,7 +163,7 @@ trait DeliverToRead: ListArcSafe + Send + Sync {
/// Generally only set to true for non-oneway transactions.
fn should_sync_wakeup(&self) -> bool;
fn debug_print(&self, m: &SeqFile, prefix: &str, transaction_prefix: &str) -> Result<()>;
fn debug_print(&self, m: &SeqFile, prefix: &str, transaction_prefix: &str) -> Result;
}
// Wrapper around a `DeliverToRead` with linked list links.
@@ -274,7 +279,7 @@ impl DeliverToRead for DeliverCode {
false
}
fn debug_print(&self, m: &SeqFile, prefix: &str, _tprefix: &str) -> Result<()> {
fn debug_print(&self, m: &SeqFile, prefix: &str, _tprefix: &str) -> Result {
seq_print!(m, "{}", prefix);
if self.skip.load(Relaxed) {
seq_print!(m, "(skipped) ");
@@ -305,6 +310,9 @@ impl kernel::Module for BinderModule {
// SAFETY: The module initializer never runs twice, so we only call this once.
unsafe { crate::context::CONTEXTS.init() };
crate::transaction::TRANSACTION_LOG.init()?;
crate::transaction::FAILED_TRANSACTION_LOG.init()?;
let netlink = crate::netlink::BINDER_NL_FAMILY.register()?;
BINDER_SHRINKER.register(c"android-binder")?;
@@ -545,7 +553,28 @@ unsafe extern "C" fn rust_binder_transactions_show(
0
}
fn rust_binder_transactions_show_impl(m: &SeqFile) -> Result<()> {
/// # Safety
/// Only called by binderfs.
#[no_mangle]
unsafe extern "C" fn rust_binder_transaction_log_show(
ptr: *mut seq_file,
_: *mut kernel::ffi::c_void,
) -> kernel::ffi::c_int {
// SAFETY: Accessing the private field of `seq_file` is okay.
let is_failed = !unsafe { (*ptr).private }.is_null();
// SAFETY: The caller ensures that the pointer is valid and exclusive for the duration in which
// this method is called.
let m = unsafe { SeqFile::from_raw(ptr) };
let log = if is_failed {
&transaction::FAILED_TRANSACTION_LOG
} else {
&transaction::TRANSACTION_LOG
};
log.debug_print(m);
0
}
fn rust_binder_transactions_show_impl(m: &SeqFile) -> Result {
seq_print!(m, "binder transactions:\n");
let contexts = context::get_all_contexts()?;
for ctx in contexts {
@@ -558,7 +587,7 @@ fn rust_binder_transactions_show_impl(m: &SeqFile) -> Result<()> {
Ok(())
}
fn rust_binder_stats_show_impl(m: &SeqFile) -> Result<()> {
fn rust_binder_stats_show_impl(m: &SeqFile) -> Result {
seq_print!(m, "binder stats:\n");
stats::GLOBAL_STATS.debug_print("", m);
let contexts = context::get_all_contexts()?;
@@ -572,7 +601,7 @@ fn rust_binder_stats_show_impl(m: &SeqFile) -> Result<()> {
Ok(())
}
fn rust_binder_state_show_impl(m: &SeqFile) -> Result<()> {
fn rust_binder_state_show_impl(m: &SeqFile) -> Result {
seq_print!(m, "binder state:\n");
let contexts = context::get_all_contexts()?;
for ctx in contexts {
@@ -585,7 +614,7 @@ fn rust_binder_state_show_impl(m: &SeqFile) -> Result<()> {
Ok(())
}
fn rust_binder_proc_show_impl(m: &SeqFile, pid: Pid) -> Result<()> {
fn rust_binder_proc_show_impl(m: &SeqFile, pid: Pid) -> Result {
seq_print!(m, "binder proc state:\n");
let contexts = context::get_all_contexts()?;
for ctx in contexts {
+20 -1
View File
@@ -46,10 +46,11 @@
DEFINE_SHOW_ATTRIBUTE(rust_binder_stats);
DEFINE_SHOW_ATTRIBUTE(rust_binder_state);
DEFINE_SHOW_ATTRIBUTE(rust_binder_transactions);
DEFINE_SHOW_ATTRIBUTE(rust_binder_transaction_log);
DEFINE_SHOW_ATTRIBUTE(rust_binder_proc);
char *rust_binder_devices_param = CONFIG_ANDROID_BINDER_DEVICES;
module_param_named(rust_devices, rust_binder_devices_param, charp, 0444);
module_param_named(devices, rust_binder_devices_param, charp, 0444);
extern u32 rust_binder_debug_mask;
module_param_named(debug_mask, rust_binder_debug_mask, uint, 0644);
@@ -611,6 +612,24 @@ static int init_binder_logs(struct super_block *sb)
goto out;
}
dentry = rust_binderfs_create_file(binder_logs_root_dir,
"transaction_log",
&rust_binder_transaction_log_fops,
(void *)0);
if (IS_ERR(dentry)) {
ret = PTR_ERR(dentry);
goto out;
}
dentry = rust_binderfs_create_file(binder_logs_root_dir,
"failed_transaction_log",
&rust_binder_transaction_log_fops,
(void *)1);
if (IS_ERR(dentry)) {
ret = PTR_ERR(dentry);
goto out;
}
proc_log_dir = binderfs_create_dir(binder_logs_root_dir, "proc");
if (IS_ERR(proc_log_dir)) {
ret = PTR_ERR(proc_log_dir);
+112 -64
View File
@@ -30,6 +30,7 @@ use crate::{
process::{GetWorkOrRegister, Process},
ptr_align,
stats::GLOBAL_STATS,
trace::{trace_transaction_alloc_buf, trace_transaction_buffer_release},
transaction::{Transaction, TransactionFlag, TransactionFlags, TransactionInfo},
BinderReturnWriter, DArc, DLArc, DTRWrap, DeliverCode, DeliverToRead,
};
@@ -344,13 +345,13 @@ impl InnerThread {
}
}
fn push_return_work(&mut self, reply: u32) {
fn push_return_work(&mut self, reply: u32) -> PushWorkRes {
if let Ok(work) = ListArc::try_from_arc(self.return_work.clone()) {
work.set_error_code(reply);
// Not notifying: Reply to current thread.
let _ = self.push_work(work);
self.push_work(work)
} else {
pr_warn_ratelimited!("Thread return work is already in use.\n");
PushWorkRes::Ok
}
}
@@ -481,7 +482,7 @@ impl Thread {
}
#[inline(never)]
pub(crate) fn debug_print(self: &Arc<Self>, m: &SeqFile, print_all: bool) -> Result<()> {
pub(crate) fn debug_print(self: &Arc<Self>, m: &SeqFile, print_all: bool) -> Result {
let inner = self.inner.lock();
if print_all || inner.current_transaction.is_some() || !inner.work_list.is_empty() {
@@ -584,9 +585,21 @@ impl Thread {
// mangled symbol names.
#[export_name = "rust_binder_wait"]
fn get_work(self: &Arc<Self>, wait: bool) -> Result<Option<DLArc<dyn DeliverToRead>>> {
let thread_has_deferred_work;
// Try to get work from the thread's work queue, using only a local lock.
{
let mut inner = self.inner.lock();
// The process_work_list boolean is used to make us go to sleep even if there is work
// in the thread todo-list, but it doesn't apply to the process todo-list. Furthermore,
// work in the thread todo-list must still be delivered before the process list.
//
// Thus, in some scenarios we must return the thread work now even if we were requested
// to wait. Adjust `process_work_list` to `true` accordingly.
inner.process_work_list |= inner.looper_need_return;
inner.process_work_list |= !wait;
if let Some(work) = inner.pop_work() {
return Ok(Some(work));
}
@@ -594,18 +607,26 @@ impl Thread {
drop(inner);
return Ok(self.process.get_work());
}
// Note that if the thread list is empty, then the call to `pop_work()` has changed
// `process_work_list` back to `false` even if we set it to `true` above.
thread_has_deferred_work = !inner.work_list.is_empty();
}
// If the caller doesn't want to wait, try to grab work from the process queue.
//
// We know nothing will have been queued directly to the thread queue because it is not in
// a transaction and it is not in the process' ready list.
// a transaction and it is not in the process' ready list. We also know the thread list has
// no deferred work due to the `inner.process_work_list |= !wait` call above.
if !wait {
return self.process.get_work().ok_or(EAGAIN).map(Some);
}
// Get work from the process queue. If none is available, atomically register as ready.
let reg = match self.process.get_work_or_register(self) {
let reg = match self
.process
.get_work_or_register(self, thread_has_deferred_work)
{
GetWorkOrRegister::Work(work) => return Ok(Some(work)),
GetWorkOrRegister::Register(reg) => reg,
};
@@ -621,14 +642,18 @@ impl Thread {
inner.looper_flags &= !(LooperFlag::Waiting | LooperFlag::WaitingProc);
if signal_pending || inner.looper_need_return {
// We need to return now. We need to pull the thread off the list of ready threads
// (by dropping `reg`), then check the state again after it's off the list to
// ensure that something was not queued in the meantime. If something has been
// queued, we just return it (instead of the error).
// We need to return now.
//
// We need to pull the thread off the list of ready threads (by dropping `reg`),
// then check the state again after it's off the list to ensure that something was
// not queued in the meantime. If something has been queued (or if there is
// deferred work), we just return it (instead of the error).
drop(inner);
drop(reg);
let res = match self.inner.lock().pop_work() {
inner = self.inner.lock();
inner.process_work_list = true;
let res = match inner.pop_work() {
Some(work) => Ok(Some(work)),
None if signal_pending => Err(EINTR),
None => Ok(None),
@@ -669,8 +694,12 @@ impl Thread {
pub(crate) fn push_work_if_looper(&self, work: DLArc<dyn DeliverToRead>) -> BinderResult {
let mut inner = self.inner.lock();
if inner.is_looper() && !inner.is_dead {
// Not notifying: Reply to current thread.
let _ = inner.push_work(work);
// Not notifying work_condvar: Reply to current thread.
let res = inner.push_work(work);
drop(inner);
if matches!(res, PushWorkRes::OkNotifyPoll) {
self.process.notify_poll(false);
}
Ok(())
} else {
drop(inner);
@@ -683,7 +712,11 @@ impl Thread {
}
pub(crate) fn push_return_work(&self, reply: u32) {
self.inner.lock().push_return_work(reply);
// Not notifying work_condvar: Reply to current thread.
let res = self.inner.lock().push_return_work(reply);
if matches!(res, PushWorkRes::OkNotifyPoll) {
self.process.notify_poll(false);
}
}
pub(crate) fn pop_work_even_if_deferred(&self) -> Option<DLArc<dyn DeliverToRead>> {
@@ -1046,17 +1079,9 @@ impl Thread {
size_of::<u64>(),
);
let secctx_off = aligned_data_size + offsets_size + buffers_size;
let mut alloc = match to_process.buffer_alloc(debug_id, len, info) {
Ok(alloc) => alloc,
Err(err) => {
pr_warn!(
"Failed to allocate buffer. len:{}, is_oneway:{}",
len,
info.is_oneway(),
);
return Err(err);
}
};
let mut alloc = to_process.buffer_alloc(debug_id, len, info)?;
trace_transaction_alloc_buf(debug_id, data_size, offsets_size, buffers_size);
let mut buffer_reader = UserSlice::new(info.data_ptr, data_size).reader();
let mut end_of_previous_object = 0;
@@ -1262,7 +1287,7 @@ impl Thread {
cmd: u32,
reader: &mut UserSliceReader,
info: &mut TransactionInfo,
) -> Result<()> {
) -> Result {
let td = match cmd {
BC_TRANSACTION | BC_REPLY => {
reader.read::<BinderTransactionData>()?.with_buffers_size(0)
@@ -1293,7 +1318,7 @@ impl Thread {
}
#[inline(never)]
fn transaction(self: &Arc<Self>, cmd: u32, reader: &mut UserSliceReader) -> Result<()> {
fn transaction(self: &Arc<Self>, cmd: u32, reader: &mut UserSliceReader) -> Result {
let mut info = TransactionInfo::zeroed();
self.read_transaction_info(cmd, reader, &mut info)?;
@@ -1307,47 +1332,57 @@ impl Thread {
self.transaction_inner(&mut info)
};
// This runs when return work is passed to the caller. This is not
// always the same as the transaction failing, as reply errors are
// delivered to the remote process.
if let Err(err) = ret {
self.push_return_work(err.reply);
if err.reply != BR_TRANSACTION_COMPLETE {
info.reply = err.reply;
if let Some(source) = &err.source {
info.errno = source.to_errno();
info.error_line = Some(err.line);
if let Some(source) = err.source {
info.errno = Some(source);
{
let mut inner = self.inner.lock();
inner.extended_error =
ExtendedError::new(info.debug_id as u32, err.reply, source.to_errno());
}
binder_debug!(
FailedTransaction,
"transaction {} to {}:{} failed {:?}, code {} size {}-{}",
if info.is_reply {
"reply"
} else if info.is_oneway() {
"async"
} else {
"call"
},
info.to_pid,
info.to_tid,
err,
info.code,
info.data_size,
info.offsets_size
);
self.inner.lock().extended_error =
ExtendedError::new(info.debug_id as u32, err.reply, source.to_errno());
}
}
}
info.write_log(&self.process.ctx);
if info.oneway_spam_suspect {
// If this is both a oneway spam suspect and a failure, we report it twice. This is
// useful in case the transaction failed with BR_TRANSACTION_PENDING_FROZEN.
info.report_netlink(BR_ONEWAY_SPAM_SUSPECT, &self.process.ctx);
}
// This runs when the transaction failed.
if info.reply != 0 {
info.report_netlink(info.reply, &self.process.ctx);
if let Some(errno) = info.errno {
let error_line: &dyn kernel::fmt::Display = match &info.error_line {
Some(line) => line,
None => &0,
};
binder_debug!(
FailedTransaction,
"transaction {} to {}:{} failed {:?}, code {} size {}-{} line {}",
if info.is_reply {
"reply"
} else if info.is_oneway() {
"async"
} else {
"call"
},
info.to_pid,
info.to_tid,
errno,
info.code,
info.data_size,
info.offsets_size,
error_line
);
}
}
Ok(())
@@ -1356,6 +1391,7 @@ impl Thread {
fn transaction_inner(self: &Arc<Self>, info: &mut TransactionInfo) -> BinderResult {
let node_ref = self.process.get_transaction_node(info.target_handle)?;
info.to_pid = node_ref.node.owner.task.pid();
info.to_node_debug_id = node_ref.node.debug_id;
security::binder_transaction(&self.process.cred, &node_ref.node.owner.cred)?;
// TODO: We need to ensure that there isn't a pending transaction in the work queue. How
// could this happen?
@@ -1422,8 +1458,17 @@ impl Thread {
let process = orig.from.process.clone();
let allow_fds = orig.flags.contains(TransactionFlag::AcceptFds);
let reply = Transaction::new_reply(self, process, info, allow_fds)?;
// Not notifying: Reply to current thread.
let _ = self.inner.lock().push_work(completion);
if info.flags.contains(TransactionFlag::DeferComplete) {
// The flag is set. Perform a deferred push so that `read` can wait for the
// next incoming transaction without a userspace roundtrip.
self.inner.lock().push_work_deferred(completion);
} else {
// Not notifying work_condvar: Reply to current thread.
let res = self.inner.lock().push_work(completion);
if matches!(res, PushWorkRes::OkNotifyPoll) {
self.process.notify_poll(false);
}
}
orig.from.deliver_reply(Ok(reply), &orig, None);
Ok(())
})()
@@ -1431,17 +1476,13 @@ impl Thread {
// At this point we only return `BR_TRANSACTION_COMPLETE` to the caller, and we must let
// the sender know that the transaction has completed (with an error in this case).
pr_warn!(
"{}:{} reply to {} failed: {err:?}",
info.from_pid,
info.from_tid,
info.to_pid
);
let param = err.source.as_ref().map_or(0, |e| e.to_errno());
let ee = ExtendedError::new(info.debug_id as u32, err.reply, param);
orig.from
.deliver_reply(Err(BR_FAILED_REPLY), &orig, Some(ee));
info.reply = BR_FAILED_REPLY;
info.errno = err.source;
info.error_line = Some(err.line);
err.reply = BR_TRANSACTION_COMPLETE;
err
});
@@ -1452,6 +1493,7 @@ impl Thread {
fn oneway_transaction_inner(self: &Arc<Self>, info: &mut TransactionInfo) -> BinderResult {
let node_ref = self.process.get_transaction_node(info.target_handle)?;
info.to_pid = node_ref.node.owner.task.pid();
info.to_node_debug_id = node_ref.node.debug_id;
security::binder_transaction(&self.process.cred, &node_ref.node.owner.cred)?;
let transaction = Transaction::new(node_ref, None, self, info)?;
let code = if self.process.is_oneway_spam_detection_enabled() && info.oneway_spam_suspect {
@@ -1462,10 +1504,15 @@ impl Thread {
let list_completion =
DTRWrap::arc_try_new(DeliverCode::new(code, self.process.task.pid()))?;
let completion = list_completion.clone_arc();
// Not notifying: Reply to current thread.
let _ = self.inner.lock().push_work(list_completion);
// Not notifying work_condvar: Reply to current thread.
let res = self.inner.lock().push_work(list_completion);
match transaction.submit(info) {
Ok(()) => Ok(()),
Ok(()) => {
if matches!(res, PushWorkRes::OkNotifyPoll) {
self.process.notify_poll(false);
}
Ok(())
}
Err(err) => {
completion.skip();
Err(err)
@@ -1495,6 +1542,7 @@ impl Thread {
if buffer.looper_need_return_on_free() {
self.inner.lock().looper_need_return = true;
}
trace_transaction_buffer_release(buffer.debug_id);
drop(buffer);
}
}
@@ -1750,7 +1798,7 @@ impl DeliverToRead for ThreadError {
false
}
fn debug_print(&self, m: &SeqFile, prefix: &str, _tprefix: &str) -> Result<()> {
fn debug_print(&self, m: &SeqFile, prefix: &str, _tprefix: &str) -> Result {
seq_print!(
m,
"{}transaction error: {}\n",
Loaded 100 of 413 files, more files were not shown because too many files have changed in this diff. Show more