* Re: [PATCH 1/1] iio: health: add MAX86150 ECG and PPG biosensor driver
From: sashiko-bot @ 2026-06-23 14:14 UTC (permalink / raw)
To: Md Shofiqul Islam; +Cc: robh, conor+dt, devicetree
In-Reply-To: <20260623140113.12574-2-shofiqtest@gmail.com>
Thank you for your contribution! Sashiko AI review found 10 potential issue(s) to consider:
- [High] Buffer overflow during triggered buffer capture.
- [High] Missing IIO direct mode locking allows concurrent sysfs reads to silently corrupt the hardware FIFO state.
- [High] Calculation of available FIFO samples evaluates to 0 when the FIFO is fully saturated, leading to a permanent capture stall.
- [High] Buffer data packing ignores `active_scan_mask`, leading to data corruption when a subset of channels is enabled.
- [High] Requesting an IRQ with `IRQF_ONESHOT` without a threaded handler causes unconditional probe failure.
- [High] Hardware interrupt unconditionally enabled at boot can permanently stall the edge-triggered line.
- [Medium] UAPI Endianness Mismatch causing data corruption on Big Endian architectures.
- [Medium] Device is left running at full power and emitting interrupts when the driver is unloaded.
- [Medium] Documented DT regulators `vdd-supply` and `leds-supply` are ignored, causing initialization failure on unpowered platforms.
- [Medium] Unbalanced `iio_trigger_get()` causes a reference count memory leak.
--
commit 86527e62ebc7afa90aeb829c2bdf9c041cf99dd9
Author: Md Shofiqul Islam <shofiqtest@gmail.com>
iio: health: add MAX86150 ECG and PPG biosensor driver
The MAX86150 integrates PPG and ECG channels in a single I2C device. The
driver exposes three IIO channels and supports hardware-triggered continuous
low-overhead capture.
> diff --git a/drivers/iio/health/max86150.c b/drivers/iio/health/max86150.c
> new file mode 100755
> index 0000000000000..3cde4af6650b7
> --- /dev/null
> +++ b/drivers/iio/health/max86150.c
[ ... ]
> +struct max86150_data {
> + struct regmap *regmap;
> + struct device *dev;
> + struct iio_trigger *trig;
> + s32 buf[4] __aligned(8);
> +};
[Severity: High]
Does this buffer have enough space for the 64-bit timestamp?
With three 32-bit channels (12 bytes) and a 64-bit timestamp needing 8-byte
alignment, the timestamp would be placed at byte offset 16. However, this
array is exactly 16 bytes.
Calling iio_push_to_buffers_with_timestamp() in max86150_trigger_handler()
could write the timestamp past the end of the array.
[ ... ]
> +static const struct iio_chan_spec max86150_channels[] = {
> + {
> + /* PPG Red LED - optical intensity, 19-bit unsigned */
> + .type = IIO_INTENSITY,
> + .modified = 1,
> + .channel2 = IIO_MOD_LIGHT_RED,
> + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
> + BIT(IIO_CHAN_INFO_SCALE),
> + .scan_index = MAX86150_IDX_PPG_RED,
> + .scan_type = {
> + .sign = 'u',
> + .realbits = 19,
> + .storagebits = 32,
> + .endianness = IIO_LE,
> + },
[Severity: Medium]
Since max86150_trigger_handler() places native integers directly into the
buffer without cpu_to_le32() conversions, will this advertise incorrect
endianness to userspace on big endian architectures?
[ ... ]
> +static int max86150_read_raw(struct iio_dev *indio_dev,
> + struct iio_chan_spec const *chan,
> + int *val, int *val2, long mask)
> +{
> + struct max86150_data *data = iio_priv(indio_dev);
> + u32 ppg_red, ppg_ir;
> + s32 ecg;
> + int ret;
> +
> + switch (mask) {
> + case IIO_CHAN_INFO_RAW:
> + /*
> + * Single-shot path: clear the FIFO so we know we are reading
> + * a sample that arrived after this call, not stale data.
> + */
> + ret = regmap_write(data->regmap, MAX86150_REG_FIFO_WR_PTR, 0);
> + if (ret)
> + return ret;
> + ret = regmap_write(data->regmap, MAX86150_REG_OVF_COUNTER, 0);
> + if (ret)
> + return ret;
> + ret = regmap_write(data->regmap, MAX86150_REG_FIFO_RD_PTR, 0);
[Severity: High]
Does this path need iio_device_claim_direct_mode() to prevent concurrent
sysfs reads from silently corrupting the hardware FIFO pointers while a
continuous triggered buffer capture is active?
[ ... ]
> +static irqreturn_t max86150_trigger_handler(int irq, void *p)
> +{
> + struct iio_poll_func *pf = p;
> + struct iio_dev *idev = pf->indio_dev;
> + struct max86150_data *data = iio_priv(idev);
> + unsigned int status, wr_ptr, rd_ptr, available;
> + u32 ppg_red, ppg_ir;
> + s32 ecg;
> + int ret;
> +
> + /*
> + * Reading INT_STATUS1 clears the interrupt. Do this before touching
> + * the FIFO so the pin is de-asserted while we drain samples.
> + */
> + ret = regmap_read(data->regmap, MAX86150_REG_INT_STATUS1, &status);
> + if (ret)
> + goto done;
> +
> + ret = regmap_read(data->regmap, MAX86150_REG_FIFO_WR_PTR, &wr_ptr);
> + if (ret)
> + goto done;
> + ret = regmap_read(data->regmap, MAX86150_REG_FIFO_RD_PTR, &rd_ptr);
> + if (ret)
> + goto done;
> +
> + /*
> + * Number of unread samples. The FIFO is circular with depth 32, so
> + * wrap with (depth - 1) as mask.
> + */
> + available = (wr_ptr - rd_ptr) & (MAX86150_FIFO_DEPTH - 1);
[Severity: High]
When the 32-entry FIFO becomes perfectly full and wr_ptr wraps around to
equal rd_ptr, will this evaluate to 0?
If so, the handler might skip the read loop entirely and leave the FIFO full,
causing the interrupt condition to persist and resulting in an endless
interrupt loop or a permanent capture stall.
> +
> + while (available--) {
> + ret = max86150_read_one_sample(data, &ppg_red, &ppg_ir, &ecg);
> + if (ret)
> + break;
> +
> + data->buf[MAX86150_IDX_PPG_RED] = ppg_red;
> + data->buf[MAX86150_IDX_PPG_IR] = ppg_ir;
> + data->buf[MAX86150_IDX_ECG] = ecg;
[Severity: High]
If userspace enables only a subset of the channels (e.g., only ECG), will
this static indexing ignore the active_scan_mask?
IIO expects enabled channels to be tightly packed at the start of the buffer.
If only ECG is enabled, the IIO core calculates the timestamp offset based on
a single channel. The static writes here might cause the timestamp to later
overwrite the channel data, corrupting both the measurement and the
timestamp.
[ ... ]
> +static int max86150_chip_init(struct max86150_data *data)
> +{
> + int ret;
> +
> + /* Software reset; the bit self-clears within 1 ms */
> + ret = regmap_write(data->regmap, MAX86150_REG_SYS_CTRL,
> + MAX86150_SYS_RESET);
[ ... ]
> + /* Enable FIFO almost-full interrupt only */
> + return regmap_write(data->regmap, MAX86150_REG_INT_ENABLE1,
> + MAX86150_INT_A_FULL);
> +}
[Severity: Medium]
Are there teardown steps needed when the driver is unloaded?
This initialization starts continuous sampling, but no .remove callback or
devm action seems to be registered to write to MAX86150_SYS_SHDN or disable
the interrupts, leaving the device fully active on unload.
[Severity: High]
Could enabling the hardware interrupt here before the IIO buffer is active
cause the edge-triggered interrupt pin to get permanently stuck?
If the sensor asserts the active-low pin early, the hardirq handler will
fire but won't read INT_STATUS1 to clear the line (since the threaded handler
is only active when the buffer is enabled). The interrupt controller might
ignore the stuck low line forever, breaking capture once the buffer is
actually started.
[ ... ]
> +static int max86150_probe(struct i2c_client *client)
> +{
> + struct iio_dev *indio_dev;
> + struct max86150_data *data;
> + unsigned int part_id;
> + int ret;
> +
> + indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
> + if (!indio_dev)
> + return -ENOMEM;
> +
> + data = iio_priv(indio_dev);
> + data->dev = &client->dev;
> +
> + data->regmap = devm_regmap_init_i2c(client, &max86150_regmap_config);
> + if (IS_ERR(data->regmap))
> + return dev_err_probe(&client->dev, PTR_ERR(data->regmap),
> + "Failed to initialise regmap\n");
[Severity: Medium]
Will this fail to probe on unpowered platforms since the documented
devicetree regulators vdd-supply and leds-supply are not requested or
enabled before I2C communication starts?
[ ... ]
> + if (client->irq > 0) {
> + data->trig = devm_iio_trigger_alloc(&client->dev,
> + "%s-dev%d",
> + indio_dev->name,
> + iio_device_id(indio_dev));
> + if (!data->trig)
> + return -ENOMEM;
> +
> + ret = devm_request_irq(&client->dev, client->irq,
> + iio_trigger_generic_data_rdy_poll,
> + IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
> + "max86150", data->trig);
[Severity: High]
Will the irq core reject this request during probe?
The interrupt core requires a threaded handler when IRQF_ONESHOT is used,
but iio_trigger_generic_data_rdy_poll is passed as the hardirq handler with
no threaded handler provided.
> + if (ret)
> + return dev_err_probe(&client->dev, ret,
> + "Cannot request IRQ %d\n",
> + client->irq);
> +
> + iio_trigger_set_drvdata(data->trig, indio_dev);
> +
> + ret = devm_iio_trigger_register(&client->dev, data->trig);
> + if (ret)
> + return dev_err_probe(&client->dev, ret,
> + "Cannot register trigger\n");
> +
> + indio_dev->trig = iio_trigger_get(data->trig);
> + }
[Severity: Medium]
Is there a corresponding iio_trigger_put() needed here? Without it, the
trigger reference count could be leaked when the device is unbound or if a
subsequent probe step fails.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260623140113.12574-2-shofiqtest@gmail.com?part=1
^ permalink raw reply
* Re: [PATCH v4 5/5] clk: rockchip: rk3588: add GATE_GRF clocks for I2S MCLK output to IO
From: Daniele Briguglio @ 2026-06-23 14:09 UTC (permalink / raw)
To: Diederik de Haas, Heiko Stuebner, Michael Turquette, Stephen Boyd,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Nicolas Frattaroli, linux-clk, devicetree, linux-arm-kernel,
linux-rockchip, linux-kernel, Ricardo Pardini
In-Reply-To: <DJGH34DVKL0W.3T6UB4G4WYYUJ@cknow-tech.com>
Hi Diederik,
> My suspicion that more RK3588 based boards would be broken is because NONE use
> I2S0_8CH_MCLKOUT_TO_IO; they all use I2S0_8CH_MCLKOUT.
These bits reset to open (SYS_GRF_SOC_CON6 = 0x4600, i2sN_mclk_ioe_ clear,
1'b0 = "Output enable"), so a board doesn't need to reference the gate to
get MCLK. They're RW, so firmware can go either way, but your 0x600 has
them clear, which is why audio works today.
The series made the gate a managed clock, so with no consumer
clk_disable_unused disables it at boot. CLK_IGNORE_UNUSED leaves an
already-open gate alone, so nothing changes for those boards. Only the ones
that come up disabled, like the YY3588 and Ricardo's R58X-Pro, need _TO_IO
for the kernel to turn it back on.
> So IIUC that means I'd be testing both variants.
Right, that covers both: the mux path and the consumer path. Looking
forward to the results.
Best regards,
Daniele
^ permalink raw reply
* Re: [PATCH v6 02/10] arm64: tegra: Remove fallback compatible for GPCDMA
From: Rob Herring @ 2026-06-23 14:02 UTC (permalink / raw)
To: Akhil R, Thierry Reding
Cc: Vinod Koul, Frank Li, Krzysztof Kozlowski, Conor Dooley,
Jonathan Hunter, Laxman Dewangan, Philipp Zabel, dmaengine,
devicetree, linux-tegra, linux-kernel
In-Reply-To: <20260331102303.33181-3-akhilrajeev@nvidia.com>
On Tue, Mar 31, 2026 at 5:24 AM Akhil R <akhilrajeev@nvidia.com> wrote:
>
> Remove the fallback compatible string "nvidia,tegra186-gpcdma" for GPCDMA
> in Tegra264. Tegra186 compatible cannot work on Tegra264 because of the
> register offset changes and absence of the reset property.
>
> Fixes: 65ef237e4810 ("arm64: tegra: Add Tegra264 support")
> Signed-off-by: Akhil R <akhilrajeev@nvidia.com>
> ---
> arch/arm64/boot/dts/nvidia/tegra264.dtsi | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
Thierry, Are you going to apply this? The binding change has been
picked up and now there's a warning.
Rob
^ permalink raw reply
* [PATCH 1/1] iio: health: add MAX86150 ECG and PPG biosensor driver
From: Md Shofiqul Islam @ 2026-06-23 14:01 UTC (permalink / raw)
To: linux-iio
Cc: jic23, dlechner, nuno.sa, robh, krzk+dt, devicetree,
Md Shofiqul Islam
In-Reply-To: <20260623140113.12574-1-shofiqtest@gmail.com>
The MAX86150 (Maxim/Analog Devices) integrates two PPG optical channels
(Red/IR LED) and one ECG biopotential channel in a single I2C device.
Data is captured via a 32-entry hardware FIFO with a configurable
almost-full interrupt.
The driver exposes three IIO channels:
- in_intensity_red_raw (PPG Red, 19-bit unsigned)
- in_intensity_ir_raw (PPG IR, 19-bit unsigned)
- in_voltage0_raw (ECG, 18-bit signed)
A hardware trigger is registered when an interrupt GPIO is provided in
the device tree, enabling the IIO triggered buffer path for continuous
low-overhead capture.
FIFO reads use regmap_noinc_read() to burst-read 9 bytes (3 slots x
3 bytes) from the streaming FIFO_DATA register in a single I2C
transaction.
Signed-off-by: Md Shofiqul Islam <shofiqtest@gmail.com>
---
.../bindings/iio/health/maxim,max86150.yaml | 67 +++
drivers/iio/health/Kconfig | 23 +
drivers/iio/health/Makefile | 1 +
drivers/iio/health/max86150.c | 512 ++++++++++++++++++
4 files changed, 603 insertions(+)
create mode 100755 Documentation/devicetree/bindings/iio/health/maxim,max86150.yaml
create mode 100755 drivers/iio/health/max86150.c
diff --git a/Documentation/devicetree/bindings/iio/health/maxim,max86150.yaml b/Documentation/devicetree/bindings/iio/health/maxim,max86150.yaml
new file mode 100755
index 000000000000..1bf10fd1a3d2
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/health/maxim,max86150.yaml
@@ -0,0 +1,67 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iio/health/maxim,max86150.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Maxim MAX86150 ECG and PPG Biosensor
+
+maintainers:
+ - Md Shofiqul Islam <shofiqtest@gmail.com>
+
+description: |
+ The MAX86150 is an integrated biosensor SoC that combines:
+ - Two PPG (photoplethysmography) channels: Red LED and IR LED,
+ for heart rate and blood-oxygen saturation (SpO2) measurement.
+ - One ECG (electrocardiogram) channel for biopotential recording.
+
+ The device communicates over I2C at up to 400 kHz and raises an
+ active-low interrupt when the 32-entry hardware FIFO reaches its
+ configurable almost-full threshold.
+
+ Datasheet:
+ https://www.analog.com/media/en/technical-documentation/data-sheets/MAX86150.pdf
+
+properties:
+ compatible:
+ const: maxim,max86150
+
+ reg:
+ maxItems: 1
+ description: I2C device address, always 0x5E.
+
+ interrupts:
+ maxItems: 1
+ description: |
+ Active-low interrupt line. Asserted when the FIFO almost-full
+ threshold is reached or when a new PPG sample is ready.
+
+ vdd-supply:
+ description: Digital core supply, 1.71 V to 1.89 V.
+
+ leds-supply:
+ description: LED anode supply, 3.0 V to 5.5 V.
+
+required:
+ - compatible
+ - reg
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/irq.h>
+
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ biosensor@5e {
+ compatible = "maxim,max86150";
+ reg = <0x5e>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <5 IRQ_TYPE_EDGE_FALLING>;
+ vdd-supply = <&vdd_1v8>;
+ leds-supply = <&vdd_3v3>;
+ };
+ };
diff --git a/drivers/iio/health/Kconfig b/drivers/iio/health/Kconfig
index a89f3abf11f4..6496cf55290c 100644
--- a/drivers/iio/health/Kconfig
+++ b/drivers/iio/health/Kconfig
@@ -13,6 +13,7 @@ config AFE4403
depends on SPI_MASTER
select REGMAP_SPI
select IIO_BUFFER
+ select IIO_TRIGGER
select IIO_TRIGGERED_BUFFER
help
Say yes to choose the Texas Instruments AFE4403
@@ -26,6 +27,7 @@ config AFE4404
depends on I2C
select REGMAP_I2C
select IIO_BUFFER
+ select IIO_TRIGGER
select IIO_TRIGGERED_BUFFER
help
Say yes to choose the Texas Instruments AFE4404
@@ -39,6 +41,7 @@ config MAX30100
depends on I2C
select REGMAP_I2C
select IIO_BUFFER
+ select IIO_TRIGGER
select IIO_KFIFO_BUF
help
Say Y here to build I2C interface support for the Maxim
@@ -52,6 +55,7 @@ config MAX30102
depends on I2C
select REGMAP_I2C
select IIO_BUFFER
+ select IIO_TRIGGER
select IIO_KFIFO_BUF
help
Say Y here to build I2C interface support for the Maxim
@@ -62,4 +66,23 @@ config MAX30102
endmenu
+
+config MAX86150
+ tristate "MAX86150 ECG and PPG biosensor"
+ depends on I2C
+ select IIO_BUFFER
+ select IIO_TRIGGER
+ select IIO_TRIGGERED_BUFFER
+ select REGMAP_I2C
+ help
+ Say Y here to enable support for the Maxim MAX86150 combined
+ ECG and photoplethysmography (PPG) biosensor.
+
+ The driver exposes three IIO channels: two PPG optical channels
+ (Red and IR LED) for heart rate and SpO2 monitoring, and one
+ ECG channel for biopotential recording.
+
+ This driver can also be built as a module. If so, the module
+ will be called max86150.
+
endmenu
diff --git a/drivers/iio/health/Makefile b/drivers/iio/health/Makefile
index 910817112258..04fc73c58444 100644
--- a/drivers/iio/health/Makefile
+++ b/drivers/iio/health/Makefile
@@ -9,3 +9,4 @@ obj-$(CONFIG_AFE4403) += afe4403.o
obj-$(CONFIG_AFE4404) += afe4404.o
obj-$(CONFIG_MAX30100) += max30100.o
obj-$(CONFIG_MAX30102) += max30102.o
+obj-$(CONFIG_MAX86150) += max86150.o
diff --git a/drivers/iio/health/max86150.c b/drivers/iio/health/max86150.c
new file mode 100755
index 000000000000..3cde4af6650b
--- /dev/null
+++ b/drivers/iio/health/max86150.c
@@ -0,0 +1,512 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * MAX86150 combined ECG and PPG biosensor driver
+ *
+ * Copyright (C) 2026 Md Shofiqul Islam <shofiqtest@gmail.com>
+ *
+ * The MAX86150 integrates two PPG optical channels (Red/IR LED) and one
+ * ECG biopotential channel in a single I2C device. Data is captured
+ * through a 32-entry hardware FIFO with a configurable almost-full
+ * interrupt, making it well-suited for continuous monitoring with a
+ * low-power host.
+ *
+ * Datasheet:
+ * https://www.analog.com/media/en/technical-documentation/data-sheets/MAX86150.pdf
+ */
+
+#include <linux/bitfield.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/trigger.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/triggered_buffer.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+
+/* Register addresses */
+#define MAX86150_REG_INT_STATUS1 0x00
+#define MAX86150_REG_INT_STATUS2 0x01
+#define MAX86150_REG_INT_ENABLE1 0x02
+#define MAX86150_REG_INT_ENABLE2 0x03
+#define MAX86150_REG_FIFO_WR_PTR 0x04
+#define MAX86150_REG_OVF_COUNTER 0x05
+#define MAX86150_REG_FIFO_RD_PTR 0x06
+#define MAX86150_REG_FIFO_DATA 0x07
+#define MAX86150_REG_FIFO_CONFIG 0x08
+#define MAX86150_REG_FIFO_DCTRL1 0x09 /* FD1[3:0] FD2[7:4] */
+#define MAX86150_REG_FIFO_DCTRL2 0x0A /* FD3[3:0] FD4[7:4] */
+#define MAX86150_REG_SYS_CTRL 0x0D
+#define MAX86150_REG_PPG_CONFIG1 0x10
+#define MAX86150_REG_PPG_CONFIG2 0x11
+#define MAX86150_REG_LED1_PA 0x14 /* Red LED pulse amplitude */
+#define MAX86150_REG_LED2_PA 0x15 /* IR LED pulse amplitude */
+#define MAX86150_REG_ECG_CONFIG1 0x3C
+#define MAX86150_REG_ECG_CONFIG3 0x3E
+#define MAX86150_REG_PART_ID 0xFF
+
+/* Field masks */
+#define MAX86150_PART_ID_VAL 0x1E
+
+/* INT_STATUS1 / INT_ENABLE1 */
+#define MAX86150_INT_A_FULL BIT(7) /* FIFO almost full */
+#define MAX86150_INT_PPG_RDY BIT(6) /* new PPG sample ready */
+
+/* SYS_CTRL */
+#define MAX86150_SYS_SHDN BIT(1)
+#define MAX86150_SYS_RESET BIT(0)
+
+/* FIFO_CONFIG */
+#define MAX86150_FIFO_SMP_AVE GENMASK(7, 5)
+#define MAX86150_FIFO_ROLLOVER_EN BIT(4)
+#define MAX86150_FIFO_A_FULL GENMASK(3, 0)
+
+/* FIFO slot data-type codes */
+#define MAX86150_FD_NONE 0x0
+#define MAX86150_FD_LED1 0x1 /* Red PPG */
+#define MAX86150_FD_LED2 0x2 /* IR PPG */
+#define MAX86150_FD_ECG 0x9
+#define MAX86150_FIFO_FD1 GENMASK(3, 0)
+#define MAX86150_FIFO_FD2 GENMASK(7, 4)
+#define MAX86150_FIFO_FD3 GENMASK(3, 0)
+#define MAX86150_FIFO_FD4 GENMASK(7, 4)
+
+/* PPG_CONFIG1 */
+#define MAX86150_PPG_ADC_RGE GENMASK(7, 6)
+#define MAX86150_PPG_SR GENMASK(5, 1)
+
+/* Geometry */
+#define MAX86150_FIFO_DEPTH 32
+#define MAX86150_BYTES_PER_SLOT 3 /* 24-bit word per slot */
+#define MAX86150_NUM_SLOTS 3 /* Red, IR, ECG */
+#define MAX86150_SAMPLE_BYTES (MAX86150_NUM_SLOTS * MAX86150_BYTES_PER_SLOT)
+
+/* Default hardware configuration */
+#define MAX86150_LED_PA_DEFAULT 0x3F /* ~50 mA */
+#define MAX86150_PPG_SR_100HZ 4 /* PPG_SR field value for 100 Hz */
+#define MAX86150_PPG_ADC_RGE_16384 2 /* 16384 nA full scale */
+/* Fire A_FULL when 17 slots remain (32 - 15 = 17 samples in FIFO) */
+#define MAX86150_FIFO_A_FULL_VAL 15
+
+/* Scan element indices */
+enum max86150_scan_idx {
+ MAX86150_IDX_PPG_RED = 0,
+ MAX86150_IDX_PPG_IR = 1,
+ MAX86150_IDX_ECG = 2,
+ MAX86150_IDX_TS,
+};
+
+/**
+ * struct max86150_data - driver private state
+ * @regmap: register map for this device
+ * @dev: parent device (for dev_err logging)
+ * @trig: IIO hardware trigger backed by the device interrupt line
+ * @buf: DMA-safe capture buffer: 3 x s32 samples + s64 timestamp.
+ * __aligned(8) satisfies iio_push_to_buffers_with_timestamp().
+ */
+struct max86150_data {
+ struct regmap *regmap;
+ struct device *dev;
+ struct iio_trigger *trig;
+ s32 buf[4] __aligned(8);
+};
+
+/* IIO channel specification */
+
+static const struct iio_chan_spec max86150_channels[] = {
+ {
+ /* PPG Red LED - optical intensity, 19-bit unsigned */
+ .type = IIO_INTENSITY,
+ .modified = 1,
+ .channel2 = IIO_MOD_LIGHT_RED,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+ BIT(IIO_CHAN_INFO_SCALE),
+ .scan_index = MAX86150_IDX_PPG_RED,
+ .scan_type = {
+ .sign = 'u',
+ .realbits = 19,
+ .storagebits = 32,
+ .endianness = IIO_LE,
+ },
+ },
+ {
+ /* PPG IR LED - optical intensity, 19-bit unsigned */
+ .type = IIO_INTENSITY,
+ .modified = 1,
+ .channel2 = IIO_MOD_LIGHT_IR,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+ BIT(IIO_CHAN_INFO_SCALE),
+ .scan_index = MAX86150_IDX_PPG_IR,
+ .scan_type = {
+ .sign = 'u',
+ .realbits = 19,
+ .storagebits = 32,
+ .endianness = IIO_LE,
+ },
+ },
+ {
+ /* ECG biopotential - voltage, 18-bit signed two's complement */
+ .type = IIO_VOLTAGE,
+ .channel = 0,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+ BIT(IIO_CHAN_INFO_SCALE),
+ .scan_index = MAX86150_IDX_ECG,
+ .scan_type = {
+ .sign = 's',
+ .realbits = 18,
+ .storagebits = 32,
+ .endianness = IIO_LE,
+ },
+ },
+ IIO_CHAN_SOFT_TIMESTAMP(MAX86150_IDX_TS),
+};
+
+/* Regmap configuration */
+
+static const struct regmap_config max86150_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .max_register = MAX86150_REG_PART_ID,
+};
+
+/* FIFO helper */
+
+/**
+ * max86150_read_one_sample - burst-read one complete 3-slot FIFO entry
+ * @data: driver state
+ * @ppg_red: out - 19-bit PPG Red ADC value (unsigned)
+ * @ppg_ir: out - 19-bit PPG IR ADC value (unsigned)
+ * @ecg: out - 18-bit ECG ADC value (sign-extended to s32)
+ *
+ * Each FIFO entry is 9 bytes (3 slots x 3 bytes). FIFO_DATA is a
+ * streaming register - the address does not auto-increment on each
+ * byte, so regmap_noinc_read() is used instead of regmap_bulk_read().
+ *
+ * Byte layout in the 24-bit FIFO word (MSB first):
+ * PPG 19-bit unsigned: bits [18:0], top 5 bits are always zero
+ * ECG 18-bit signed: bits [17:0], top 6 bits are sign extension
+ */
+static int max86150_read_one_sample(struct max86150_data *data,
+ u32 *ppg_red, u32 *ppg_ir, s32 *ecg)
+{
+ u8 buf[MAX86150_SAMPLE_BYTES]; /* 9 bytes */
+ int ret;
+
+ ret = regmap_noinc_read(data->regmap, MAX86150_REG_FIFO_DATA,
+ buf, sizeof(buf));
+ if (ret)
+ return ret;
+
+ /* Bytes [0..2]: PPG Red - 19-bit value in bits [18:0] */
+ *ppg_red = (u32)(buf[0] & 0x07) << 16 | (u32)buf[1] << 8 | buf[2];
+
+ /* Bytes [3..5]: PPG IR - same format */
+ *ppg_ir = (u32)(buf[3] & 0x07) << 16 | (u32)buf[4] << 8 | buf[5];
+
+ /* Bytes [6..8]: ECG - 18-bit signed, sign-extend to s32 */
+ *ecg = sign_extend32((u32)(buf[6] & 0x03) << 16 |
+ (u32)buf[7] << 8 | buf[8], 17);
+
+ return 0;
+}
+
+/* IIO read_raw */
+
+static int max86150_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val, int *val2, long mask)
+{
+ struct max86150_data *data = iio_priv(indio_dev);
+ u32 ppg_red, ppg_ir;
+ s32 ecg;
+ int ret;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ /*
+ * Single-shot path: clear the FIFO so we know we are reading
+ * a sample that arrived after this call, not stale data.
+ */
+ ret = regmap_write(data->regmap, MAX86150_REG_FIFO_WR_PTR, 0);
+ if (ret)
+ return ret;
+ ret = regmap_write(data->regmap, MAX86150_REG_OVF_COUNTER, 0);
+ if (ret)
+ return ret;
+ ret = regmap_write(data->regmap, MAX86150_REG_FIFO_RD_PTR, 0);
+ if (ret)
+ return ret;
+
+ /* Wait for one complete sample period at 100 Hz (<= 10 ms) */
+ usleep_range(11000, 13000);
+
+ ret = max86150_read_one_sample(data, &ppg_red, &ppg_ir, &ecg);
+ if (ret)
+ return ret;
+
+ switch (chan->scan_index) {
+ case MAX86150_IDX_PPG_RED:
+ *val = ppg_red;
+ break;
+ case MAX86150_IDX_PPG_IR:
+ *val = ppg_ir;
+ break;
+ case MAX86150_IDX_ECG:
+ *val = ecg;
+ break;
+ default:
+ return -EINVAL;
+ }
+ return IIO_VAL_INT;
+
+ case IIO_CHAN_INFO_SCALE:
+ /*
+ * TODO: return the hardware scale factor based on the
+ * configured PPG ADC range (PPG_ADC_RGE) and ECG PGA gain
+ * (ECG_PGA_GAIN). For PPG, scale is nA/LSB; for ECG, uV/LSB.
+ */
+ return -EINVAL;
+
+ default:
+ return -EINVAL;
+ }
+}
+
+static const struct iio_info max86150_iio_info = {
+ .read_raw = max86150_read_raw,
+};
+
+/* Triggered buffer */
+
+/**
+ * max86150_trigger_handler - threaded IRQ handler for FIFO almost-full
+ *
+ * Called by the IIO buffer infrastructure when the hardware trigger fires.
+ * Reads INT_STATUS1 to de-assert the interrupt, then drains all available
+ * FIFO samples into the IIO push buffer.
+ */
+static irqreturn_t max86150_trigger_handler(int irq, void *p)
+{
+ struct iio_poll_func *pf = p;
+ struct iio_dev *idev = pf->indio_dev;
+ struct max86150_data *data = iio_priv(idev);
+ unsigned int status, wr_ptr, rd_ptr, available;
+ u32 ppg_red, ppg_ir;
+ s32 ecg;
+ int ret;
+
+ /*
+ * Reading INT_STATUS1 clears the interrupt. Do this before touching
+ * the FIFO so the pin is de-asserted while we drain samples.
+ */
+ ret = regmap_read(data->regmap, MAX86150_REG_INT_STATUS1, &status);
+ if (ret)
+ goto done;
+
+ ret = regmap_read(data->regmap, MAX86150_REG_FIFO_WR_PTR, &wr_ptr);
+ if (ret)
+ goto done;
+ ret = regmap_read(data->regmap, MAX86150_REG_FIFO_RD_PTR, &rd_ptr);
+ if (ret)
+ goto done;
+
+ /*
+ * Number of unread samples. The FIFO is circular with depth 32, so
+ * wrap with (depth - 1) as mask.
+ */
+ available = (wr_ptr - rd_ptr) & (MAX86150_FIFO_DEPTH - 1);
+
+ while (available--) {
+ ret = max86150_read_one_sample(data, &ppg_red, &ppg_ir, &ecg);
+ if (ret)
+ break;
+
+ data->buf[MAX86150_IDX_PPG_RED] = ppg_red;
+ data->buf[MAX86150_IDX_PPG_IR] = ppg_ir;
+ data->buf[MAX86150_IDX_ECG] = ecg;
+
+ iio_push_to_buffers_with_timestamp(idev, data->buf,
+ iio_get_time_ns(idev));
+ }
+
+done:
+ iio_trigger_notify_done(idev->trig);
+ return IRQ_HANDLED;
+}
+
+/* Chip initialisation */
+
+static int max86150_chip_init(struct max86150_data *data)
+{
+ int ret;
+
+ /* Software reset; the bit self-clears within 1 ms */
+ ret = regmap_write(data->regmap, MAX86150_REG_SYS_CTRL,
+ MAX86150_SYS_RESET);
+ if (ret)
+ return ret;
+ usleep_range(1000, 2000);
+
+ /*
+ * FIFO: no sample averaging, rollover enabled, assert A_FULL when
+ * 17 samples are in the FIFO (32 - 15 = 17 available to read).
+ */
+ ret = regmap_write(data->regmap, MAX86150_REG_FIFO_CONFIG,
+ MAX86150_FIFO_ROLLOVER_EN |
+ FIELD_PREP(MAX86150_FIFO_A_FULL,
+ MAX86150_FIFO_A_FULL_VAL));
+ if (ret)
+ return ret;
+
+ /* Slot 1 = PPG Red (LED1), Slot 2 = PPG IR (LED2) */
+ ret = regmap_write(data->regmap, MAX86150_REG_FIFO_DCTRL1,
+ FIELD_PREP(MAX86150_FIFO_FD1, MAX86150_FD_LED1) |
+ FIELD_PREP(MAX86150_FIFO_FD2, MAX86150_FD_LED2));
+ if (ret)
+ return ret;
+
+ /* Slot 3 = ECG, Slot 4 = disabled */
+ ret = regmap_write(data->regmap, MAX86150_REG_FIFO_DCTRL2,
+ FIELD_PREP(MAX86150_FIFO_FD3, MAX86150_FD_ECG) |
+ FIELD_PREP(MAX86150_FIFO_FD4, MAX86150_FD_NONE));
+ if (ret)
+ return ret;
+
+ /* PPG: 100 Hz sample rate, 16384 nA ADC full-scale range */
+ ret = regmap_write(data->regmap, MAX86150_REG_PPG_CONFIG1,
+ FIELD_PREP(MAX86150_PPG_ADC_RGE,
+ MAX86150_PPG_ADC_RGE_16384) |
+ FIELD_PREP(MAX86150_PPG_SR,
+ MAX86150_PPG_SR_100HZ));
+ if (ret)
+ return ret;
+
+ /* LED pulse amplitudes (~50 mA) */
+ ret = regmap_write(data->regmap, MAX86150_REG_LED1_PA,
+ MAX86150_LED_PA_DEFAULT);
+ if (ret)
+ return ret;
+
+ ret = regmap_write(data->regmap, MAX86150_REG_LED2_PA,
+ MAX86150_LED_PA_DEFAULT);
+ if (ret)
+ return ret;
+
+ /* Enable FIFO almost-full interrupt only */
+ return regmap_write(data->regmap, MAX86150_REG_INT_ENABLE1,
+ MAX86150_INT_A_FULL);
+}
+
+/* Probe */
+
+static int max86150_probe(struct i2c_client *client)
+{
+ struct iio_dev *indio_dev;
+ struct max86150_data *data;
+ unsigned int part_id;
+ int ret;
+
+ indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+ if (!indio_dev)
+ return -ENOMEM;
+
+ data = iio_priv(indio_dev);
+ data->dev = &client->dev;
+
+ data->regmap = devm_regmap_init_i2c(client, &max86150_regmap_config);
+ if (IS_ERR(data->regmap))
+ return dev_err_probe(&client->dev, PTR_ERR(data->regmap),
+ "Failed to initialise regmap\n");
+
+ ret = regmap_read(data->regmap, MAX86150_REG_PART_ID, &part_id);
+ if (ret)
+ return dev_err_probe(&client->dev, ret,
+ "Cannot read part ID\n");
+
+ if (part_id != MAX86150_PART_ID_VAL)
+ return dev_err_probe(&client->dev, -ENODEV,
+ "Unexpected part ID 0x%02x (expected 0x%02x)\n",
+ part_id, MAX86150_PART_ID_VAL);
+
+ ret = max86150_chip_init(data);
+ if (ret)
+ return dev_err_probe(&client->dev, ret,
+ "Chip initialisation failed\n");
+
+ indio_dev->name = "max86150";
+ indio_dev->channels = max86150_channels;
+ indio_dev->num_channels = ARRAY_SIZE(max86150_channels);
+ indio_dev->info = &max86150_iio_info;
+ indio_dev->modes = INDIO_DIRECT_MODE;
+
+ /*
+ * If the device tree provides an interrupt, set up a hardware
+ * trigger so userspace can use the FIFO almost-full signal to
+ * drive capture without polling.
+ */
+ if (client->irq > 0) {
+ data->trig = devm_iio_trigger_alloc(&client->dev,
+ "%s-dev%d",
+ indio_dev->name,
+ iio_device_id(indio_dev));
+ if (!data->trig)
+ return -ENOMEM;
+
+ ret = devm_request_irq(&client->dev, client->irq,
+ iio_trigger_generic_data_rdy_poll,
+ IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+ "max86150", data->trig);
+ if (ret)
+ return dev_err_probe(&client->dev, ret,
+ "Cannot request IRQ %d\n",
+ client->irq);
+
+ iio_trigger_set_drvdata(data->trig, indio_dev);
+
+ ret = devm_iio_trigger_register(&client->dev, data->trig);
+ if (ret)
+ return dev_err_probe(&client->dev, ret,
+ "Cannot register trigger\n");
+
+ indio_dev->trig = iio_trigger_get(data->trig);
+ }
+
+ ret = devm_iio_triggered_buffer_setup(&client->dev, indio_dev,
+ iio_pollfunc_store_time,
+ max86150_trigger_handler,
+ NULL);
+ if (ret)
+ return dev_err_probe(&client->dev, ret,
+ "Cannot setup triggered buffer\n");
+
+ return devm_iio_device_register(&client->dev, indio_dev);
+}
+
+/* I2C driver table */
+
+static const struct i2c_device_id max86150_id[] = {
+ { "max86150" },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, max86150_id);
+
+static const struct of_device_id max86150_of_match[] = {
+ { .compatible = "maxim,max86150" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, max86150_of_match);
+
+static struct i2c_driver max86150_driver = {
+ .driver = {
+ .name = "max86150",
+ .of_match_table = max86150_of_match,
+ },
+ .probe = max86150_probe,
+ .id_table = max86150_id,
+};
+module_i2c_driver(max86150_driver);
+
+MODULE_AUTHOR("Md Shofiqul Islam <shofiqtest@gmail.com>");
+MODULE_DESCRIPTION("MAX86150 ECG and PPG biosensor driver");
+MODULE_LICENSE("GPL");
--
2.51.1
^ permalink raw reply related
* [PATCH 0/1] iio: health: add MAX86150 ECG and PPG biosensor driver
From: Md Shofiqul Islam @ 2026-06-23 14:01 UTC (permalink / raw)
To: linux-iio
Cc: jic23, dlechner, nuno.sa, robh, krzk+dt, devicetree,
Md Shofiqul Islam
The MAX86150 (Maxim/Analog Devices) combines two PPG optical channels
(Red/IR LED) and one ECG biopotential channel in a single I2C device.
Data is produced at up to 3200 Hz and buffered in a 32-entry hardware
FIFO with a configurable almost-full interrupt.
This patch adds an IIO driver that exposes three channels:
in_intensity_red_raw -- PPG Red LED, 19-bit unsigned
in_intensity_ir_raw -- PPG IR LED, 19-bit unsigned
in_voltage0_raw -- ECG biopotential, 18-bit signed
Key implementation choices:
- regmap_noinc_read() for FIFO access: reads 9 bytes (3 slots x 3
bytes) from the streaming FIFO_DATA register in a single I2C
burst without address auto-increment.
- IIO hardware trigger backed by the device interrupt (active-low,
FIFO almost-full). When an interrupt GPIO is provided in the device
tree, a trigger is registered and wired to the IIO triggered buffer
path for continuous low-overhead capture.
- All resource management uses devm_* APIs.
Known limitations to be addressed in v2:
- IIO_CHAN_INFO_SCALE not yet implemented.
- Runtime PM (SYS_CTRL SHDN bit) not yet implemented.
- Not yet tested on physical hardware.
Md Shofiqul Islam (1):
iio: health: add MAX86150 ECG and PPG biosensor driver
.../bindings/iio/health/maxim,max86150.yaml | 67 +++
drivers/iio/health/Kconfig | 23 +
drivers/iio/health/Makefile | 1 +
drivers/iio/health/max86150.c | 512 ++++++++++++++++++
4 files changed, 603 insertions(+)
create mode 100755 Documentation/devicetree/bindings/iio/health/maxim,max86150.yaml
create mode 100755 drivers/iio/health/max86150.c
--
2.51.1
^ permalink raw reply
* [PATCH] dt-bindings: mediatek: cec: Correct the compatibles for mt7623-mt8167
From: Luca Leonardo Scorcia @ 2026-06-23 13:57 UTC (permalink / raw)
To: linux-mediatek
Cc: Luca Leonardo Scorcia, Chun-Kuang Hu, Philipp Zabel, David Airlie,
Simona Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Matthias Brugger, AngeloGioacchino Del Regno, CK Hu, Jitao shi,
dri-devel, devicetree, linux-kernel, linux-arm-kernel
The HDMI CEC driver for both mt7623 and mt8167 is actually the same as
mt8173-cec and the mt7623n.dtsi board include file already uses mt8173-cec
compatible as a fallback, but the documentation lists them as separate
entries. Correct the binding by adding the correct fallback.
This change fixes a dtbs_check error.
Signed-off-by: Luca Leonardo Scorcia <l.scorcia@gmail.com>
---
.../bindings/display/mediatek/mediatek,cec.yaml | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,cec.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,cec.yaml
index 080cf321209e..4d741ba415e8 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,cec.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,cec.yaml
@@ -15,10 +15,13 @@ description: |
properties:
compatible:
- enum:
- - mediatek,mt7623-cec
- - mediatek,mt8167-cec
- - mediatek,mt8173-cec
+ oneOf:
+ - const: mediatek,mt8173-cec
+ - items:
+ - enum:
+ - mediatek,mt7623-cec
+ - mediatek,mt8167-cec
+ - const: mediatek,mt8173-cec
reg:
maxItems: 1
--
2.43.0
^ permalink raw reply related
* Re: [PATCH v4 5/5] clk: rockchip: rk3588: add GATE_GRF clocks for I2S MCLK output to IO
From: Diederik de Haas @ 2026-06-23 13:45 UTC (permalink / raw)
To: Daniele Briguglio, Diederik de Haas, Heiko Stuebner,
Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Conor Dooley
Cc: Nicolas Frattaroli, linux-clk, devicetree, linux-arm-kernel,
linux-rockchip, linux-kernel, Ricardo Pardini
In-Reply-To: <20260623132351.4144457-1-hello@superkali.me>
Hi Daniele,
On Tue Jun 23, 2026 at 3:23 PM CEST, Daniele Briguglio wrote:
>> md.l 0xfd58c318
>> fd58c318: 00000600
>
> Thanks. Bit 0 is clear there, so the I2S0 gate is open at the U-Boot
> prompt, after BL31 and before Linux. That matches the symptom: the
> firmware on your T6 leaves it open, and the kernel closes it once nothing
> references it.
>
> Given that, I think Heiko's suggestion makes sense here. Marking the four
> gates CLK_IGNORE_UNUSED keeps the kernel from disabling what the firmware
> already left open, and boards that reference _TO_IO still drive it through
> the consumer.
My suspicion that more RK3588 based boards would be broken is because NONE use
I2S0_8CH_MCLKOUT_TO_IO; they all use I2S0_8CH_MCLKOUT.
(And the testing was only done on not (yet?) upstreamed boards)
> Could you test that change if you get a chance? Just set the flag on the
> I2S0/1/2/3 _TO_IO gates in clk-rk3588.c and check your analog audio comes
> back. The series is already merged, so I'll send the fix as a separate
> follow-up patch, this evening if Heiko is fine with the approach.
I'm going to build a new kernel where I did ``s/0/CLK_IGNORE_UNUSED/`` 4 times
and I adjusted my NanoPC-T6 Plus board dts to use I2S0_8CH_MCLKOUT_TO_IO, while
I keep the LTS board dts to I2S0_8CH_MCLKOUT.
So IIUC that means I'd be testing both variants.
Cheers,
Diederik
^ permalink raw reply
* Re: [PATCH V13 2/9] dt-bindings: iio: imu: icm42600: Add icm42607
From: Chris Morgan @ 2026-06-23 13:27 UTC (permalink / raw)
To: Jean-Baptiste Maneyrol
Cc: Jonathan Cameron, Chris Morgan, linux-iio@vger.kernel.org,
andy@kernel.org, nuno.sa@analog.com, dlechner@baylibre.com,
linux-rockchip@lists.infradead.org, devicetree@vger.kernel.org,
heiko@sntech.de, conor+dt@kernel.org, krzk+dt@kernel.org,
robh@kernel.org, andriy.shevchenko@intel.com, Krzysztof Kozlowski
In-Reply-To: <BE1P281MB1426349316BDFDBDB7C4BFE0CEEE2@BE1P281MB1426.DEUP281.PROD.OUTLOOK.COM>
On Tue, Jun 23, 2026 at 08:14:28AM +0000, Jean-Baptiste Maneyrol wrote:
>
>
> >From: Chris Morgan <macromorgan@hotmail.com>
> >Sent: Tuesday, June 23, 2026 02:06
> >To: Jean-Baptiste Maneyrol
> >Cc: Jonathan Cameron; Chris Morgan; linux-iio@vger.kernel.org; andy@kernel.org; nuno.sa@analog.com; dlechner@baylibre.com; linux-rockchip@lists.infradead.org; devicetree@vger.kernel.org; heiko@sntech.de; conor+dt@kernel.org; krzk+dt@kernel.org; robh@kernel.org; andriy.shevchenko@intel.com; Krzysztof Kozlowski
> >Subject: Re: [PATCH V13 2/9] dt-bindings: iio: imu: icm42600: Add icm42607
> >
> >On Mon, Jun 22, 2026 at 09: 23: 28AM +0000, Jean-Baptiste Maneyrol wrote: > Hello Chris and Jonathan, > > concerning dt bindings, my initial understanding was that we had a file per > driver. But here, Chris is doing a new driver for
> >ZjQcmQRYFpfptBannerStart
> >This Message Is From an External Sender
> >This message came from outside your organization.
> >
> >ZjQcmQRYFpfptBannerEnd
> >
> >On Mon, Jun 22, 2026 at 09:23:28AM +0000, Jean-Baptiste Maneyrol wrote:
> >> Hello Chris and Jonathan,
> >>
> >> concerning dt bindings, my initial understanding was that we had a file per
> >> driver. But here, Chris is doing a new driver for icm42607 while adding new
> >> bindings here.
> >>
> >> Does it means we don't have 1 binding file per driver, and there is no need
> >> to create a new binding file for inv_icm42607 driver?
> >>
> >> Despite the naming, icm42607 chips are a complete new design very different
> >> than all other icm42600 chips. It using similar IPs for things like the FIFO,
> >> but all other parts are different. Especially, it doesn't use banks for
> >> registers access but indirect access delegated to the chip internals for
> >> accessing certain registers.
> >
> >For what it's worth I'm not using any of those registers in the driver
> >currently; from what I see in the datasheets I was able to find on the
> >web the 42607p doesn't do the indirect register access (again unless
> >I'm misreading). To be fair I don't have any other icm42607 chips to
> >test against. The 42607c does appear to do such register access.
> >
> >Thank you,
> >Chris
>
> Hello Chris,
>
> here is a link to download ICM-42670-P datasheet, this chip is completely similar
> to ICM-42607-P:
> https://www.invensense.tdk.com/en-us/download-resource/ds-000451-icm-42670-p-datasheet
>
> Indirect register access is required when you want to use the FIFO for configuring
> which data is stored inside or when you want to update gyro/accel hardware
> offsets (calibbias iio attribute usually). Also required for a lot of more
> complex internal chip configuration.
>
> I didn't had a chance to look at your driver currently. I hope to be able to
> have a look soon.
>
> I can you give the figures for the required maximum sleep time for accel and
> gyro startups and stops. Usually, they are not provided in datasheet (only mean
> values).
>
> Thanks for your work,
> JB
I guess I had an older or inaccurate datasheet because mine didn't list
any of the additional user banks for the 42607p, only for the 42607c.
As of right now I'm not using any of those additional registers, my
main goal all along has just been to get the accelerometer working
honestly, and so far using things like monitor-sensor this driver seems
to be outputting what I expect. I'm not using any of the fifo buffers,
wom, or apex stuff currently either as it turns out my implementation
doesn't even have an interrupt as best I can tell, I couldn't get any
output on the designated IRQ line suggesting it probably wasn't
used.
I'm currently using the mean values from the datasheet for the startup
times (10ms for the accelerometer, 30ms for the gyroscope). I had a
misreading in earlier versions for the temp sensor of 77ms, but looking
at the datasheet again it appears it should be 77us. Since the temp
sensor needs one of the gyro or accel enabled to be read I'm just
not messing with the startup time at all and relying on the longer
startup times of the accel or gyro. In the latest version (not pushed
yet as I'm still refactoring stuff) I am tracking the timestamp of
the gyro start to ensure it has been on at least 45ms before it is
shut off, as the datasheet also says minimum run time is 45ms.
If you see anything else let me know, I'm happy to get any help I
can.
Thank you,
Chris
>
> >
> >>
> >> Thanks,
> >> JB
> >>
> >> >From: Chris Morgan <macromorgan@hotmail.com>
> >> >
> >> >Add the ICM42607 and ICM42607P inertial measurement unit.
> >> >
> >> >This device is functionally very similar to the icm42600 series with a
> >> >very different register layout. The driver does not require an
> >> >interrupt for these specific chip revisions.
> >> >
> >> >Signed-off-by: Chris Morgan <macromorgan@hotmail.com>
> >> >Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
> >> >---
> >> > .../bindings/iio/imu/invensense,icm42600.yaml | 18 +++++++++++++++++-
> >> > 1 file changed, 17 insertions(+), 1 deletion(-)
> >> >
> >> >diff --git a/Documentation/devicetree/bindings/iio/imu/invensense,icm42600.yaml b/Documentation/devicetree/bindings/iio/imu/invensense,icm42600.yaml
> >> >index 9b2af104f186..81b6e85decd5 100644
> >> >--- a/Documentation/devicetree/bindings/iio/imu/invensense,icm42600.yaml
> >> >+++ b/Documentation/devicetree/bindings/iio/imu/invensense,icm42600.yaml
> >> >@@ -30,6 +30,8 @@ properties:
> >> > - invensense,icm42600
> >> > - invensense,icm42602
> >> > - invensense,icm42605
> >> >+ - invensense,icm42607
> >> >+ - invensense,icm42607p
> >> > - invensense,icm42622
> >> > - invensense,icm42631
> >> > - invensense,icm42686
> >> >@@ -67,10 +69,24 @@ properties:
> >> > required:
> >> > - compatible
> >> > - reg
> >> >- - interrupts
> >> >
> >> > allOf:
> >> > - $ref: /schemas/spi/spi-peripheral-props.yaml#
> >> >+ - if:
> >> >+ properties:
> >> >+ compatible:
> >> >+ contains:
> >> >+ enum:
> >> >+ - invensense,icm42600
> >> >+ - invensense,icm42602
> >> >+ - invensense,icm42605
> >> >+ - invensense,icm42622
> >> >+ - invensense,icm42631
> >> >+ - invensense,icm42686
> >> >+ - invensense,icm42688
> >> >+ then:
> >> >+ required:
> >> >+ - interrupts
> >> >
> >> > unevaluatedProperties: false
> >> >
> >> >--
> >> >2.43.0
> >
> >
>
>
> ________________________________________
> From: Chris Morgan <macromorgan@hotmail.com>
> Sent: Tuesday, June 23, 2026 02:06
> To: Jean-Baptiste Maneyrol
> Cc: Jonathan Cameron; Chris Morgan; linux-iio@vger.kernel.org; andy@kernel.org; nuno.sa@analog.com; dlechner@baylibre.com; linux-rockchip@lists.infradead.org; devicetree@vger.kernel.org; heiko@sntech.de; conor+dt@kernel.org; krzk+dt@kernel.org; robh@kernel.org; andriy.shevchenko@intel.com; Krzysztof Kozlowski
> Subject: Re: [PATCH V13 2/9] dt-bindings: iio: imu: icm42600: Add icm42607
>
> On Mon, Jun 22, 2026 at 09: 23: 28AM +0000, Jean-Baptiste Maneyrol wrote: > Hello Chris and Jonathan, > > concerning dt bindings, my initial understanding was that we had a file per > driver. But here, Chris is doing a new driver for
> ZjQcmQRYFpfptBannerStart
> This Message Is From an External Sender
> This message came from outside your organization.
>
> ZjQcmQRYFpfptBannerEnd
>
> On Mon, Jun 22, 2026 at 09:23:28AM +0000, Jean-Baptiste Maneyrol wrote:
> > Hello Chris and Jonathan,
> >
> > concerning dt bindings, my initial understanding was that we had a file per
> > driver. But here, Chris is doing a new driver for icm42607 while adding new
> > bindings here.
> >
> > Does it means we don't have 1 binding file per driver, and there is no need
> > to create a new binding file for inv_icm42607 driver?
> >
> > Despite the naming, icm42607 chips are a complete new design very different
> > than all other icm42600 chips. It using similar IPs for things like the FIFO,
> > but all other parts are different. Especially, it doesn't use banks for
> > registers access but indirect access delegated to the chip internals for
> > accessing certain registers.
>
> For what it's worth I'm not using any of those registers in the driver
> currently; from what I see in the datasheets I was able to find on the
> web the 42607p doesn't do the indirect register access (again unless
> I'm misreading). To be fair I don't have any other icm42607 chips to
> test against. The 42607c does appear to do such register access.
>
> Thank you,
> Chris
>
> >
> > Thanks,
> > JB
> >
> > >From: Chris Morgan <macromorgan@hotmail.com>
> > >
> > >Add the ICM42607 and ICM42607P inertial measurement unit.
> > >
> > >This device is functionally very similar to the icm42600 series with a
> > >very different register layout. The driver does not require an
> > >interrupt for these specific chip revisions.
> > >
> > >Signed-off-by: Chris Morgan <macromorgan@hotmail.com>
> > >Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
> > >---
> > > .../bindings/iio/imu/invensense,icm42600.yaml | 18 +++++++++++++++++-
> > > 1 file changed, 17 insertions(+), 1 deletion(-)
> > >
> > >diff --git a/Documentation/devicetree/bindings/iio/imu/invensense,icm42600.yaml b/Documentation/devicetree/bindings/iio/imu/invensense,icm42600.yaml
> > >index 9b2af104f186..81b6e85decd5 100644
> > >--- a/Documentation/devicetree/bindings/iio/imu/invensense,icm42600.yaml
> > >+++ b/Documentation/devicetree/bindings/iio/imu/invensense,icm42600.yaml
> > >@@ -30,6 +30,8 @@ properties:
> > > - invensense,icm42600
> > > - invensense,icm42602
> > > - invensense,icm42605
> > >+ - invensense,icm42607
> > >+ - invensense,icm42607p
> > > - invensense,icm42622
> > > - invensense,icm42631
> > > - invensense,icm42686
> > >@@ -67,10 +69,24 @@ properties:
> > > required:
> > > - compatible
> > > - reg
> > >- - interrupts
> > >
> > > allOf:
> > > - $ref: /schemas/spi/spi-peripheral-props.yaml#
> > >+ - if:
> > >+ properties:
> > >+ compatible:
> > >+ contains:
> > >+ enum:
> > >+ - invensense,icm42600
> > >+ - invensense,icm42602
> > >+ - invensense,icm42605
> > >+ - invensense,icm42622
> > >+ - invensense,icm42631
> > >+ - invensense,icm42686
> > >+ - invensense,icm42688
> > >+ then:
> > >+ required:
> > >+ - interrupts
> > >
> > > unevaluatedProperties: false
> > >
> > >--
> > >2.43.0
>
^ permalink raw reply
* Re: [PATCH v4 5/5] clk: rockchip: rk3588: add GATE_GRF clocks for I2S MCLK output to IO
From: Daniele Briguglio @ 2026-06-23 13:23 UTC (permalink / raw)
To: Diederik de Haas, Heiko Stuebner, Michael Turquette, Stephen Boyd,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Nicolas Frattaroli, linux-clk, devicetree, linux-arm-kernel,
linux-rockchip, linux-kernel, Ricardo Pardini
In-Reply-To: <DJGG8DEAKSPK.1GJ8FARAHXPXM@cknow-tech.com>
Hi Diederik,
> md.l 0xfd58c318
> fd58c318: 00000600
Thanks. Bit 0 is clear there, so the I2S0 gate is open at the U-Boot
prompt, after BL31 and before Linux. That matches the symptom: the
firmware on your T6 leaves it open, and the kernel closes it once nothing
references it.
Given that, I think Heiko's suggestion makes sense here. Marking the four
gates CLK_IGNORE_UNUSED keeps the kernel from disabling what the firmware
already left open, and boards that reference _TO_IO still drive it through
the consumer.
Could you test that change if you get a chance? Just set the flag on the
I2S0/1/2/3 _TO_IO gates in clk-rk3588.c and check your analog audio comes
back. The series is already merged, so I'll send the fix as a separate
follow-up patch, this evening if Heiko is fine with the approach.
Best regards,
Daniele
^ permalink raw reply
* Re: [PATCH 3/3] backlight: lp8864: Convert from LED to backlight class driver
From: Daniel Thompson @ 2026-06-23 13:17 UTC (permalink / raw)
To: Sverdlin, Alexander
Cc: dri-devel@lists.freedesktop.org, danielt@kernel.org,
linux-leds@vger.kernel.org, devicetree@vger.kernel.org,
linux-fbdev@vger.kernel.org, linux-kernel@vger.kernel.org
In-Reply-To: <aa34231591d2e5f848bdd74524abb4fe85123444.camel@siemens.com>
On Tue, Jun 23, 2026 at 11:59:16AM +0000, Sverdlin, Alexander wrote:
> Hi Daniel,
>
> On Tue, 2026-06-23 at 12:41 +0100, Daniel Thompson wrote:
> > > The mechanism we have regarding hot plugging currently is just I2C bridge,
> > > which de-registers and registers the bridged bus. So no additional drivers
> > > are required, as long as I2C devices are self-contained and not glued with
> > > platform devices.
> > >
> > > So bottom line is, I'd prefer to just add the backlight interface to the
> > > existing driver, no matter where it would live in the future.
> >
> > Is there any reasion that LP8864/LP8866 is unique in appearing on a
> > hotplugged I2C bus? In other words if support for dynamism is added
> > specifically to leds-lp8864.c rather than in led_bl.c then what will stop
> > the same dynamic tricks from being adde to other LED drivers?
>
> LP8864 is not special in this regard, not different from adp8860_bl.c,
> adp8870_bl.c or lm3639_bl.c, which would work in my application.
The most recent of these drivers adopted LED support in 2012 whilst
led_bl.c was introduced in 2020.
> So I just wanted to add currently missing backlight_device_register() to
> LP8864, but there were no such dual-API drivers under drivers/leds/ that's
> wht I started with moving LP8864 driver into drivers/video/backlight/.
>
> led_bl.c however could only be hot-pluggable either if one actively
> creates/destroys platform device somewhere in the code programmatically
> or uses DT overlays.
>
> Just adding backlight API to LP8864 would be much more idiomatic, I'd
> say.
Maybe.
I think I might consider the drivers above to be historical anomalies
rather than idiomatic examples.
Daniel.
^ permalink raw reply
* Re: [PATCH v4 5/5] clk: rockchip: rk3588: add GATE_GRF clocks for I2S MCLK output to IO
From: Diederik de Haas @ 2026-06-23 13:08 UTC (permalink / raw)
To: Diederik de Haas, Daniele Briguglio, Heiko Stuebner,
Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Conor Dooley
Cc: Nicolas Frattaroli, linux-clk, devicetree, linux-arm-kernel,
linux-rockchip, linux-kernel, Ricardo Pardini
In-Reply-To: <DJGG8DEAKSPK.1GJ8FARAHXPXM@cknow-tech.com>
On Tue Jun 23, 2026 at 3:05 PM CEST, Diederik de Haas wrote:
> On Tue Jun 23, 2026 at 2:33 PM CEST, Daniele Briguglio wrote:
>> If that turns out to be the case, CLK_IGNORE_UNUSED on the gates is a
>> reasonable way to stop the kernel from closing a gate the firmware already
>> left open, for boards that would rather not switch their DTS to _TO_IO.
>
> I'm not so sure I agree that CLK_IGNORE_UNUSED is reasonable, but I'll leave
> judgement up to others. I'll do the test regardless, though.
Ah, just learned those should be added to your patch, in which case my
objection goes away.
^ permalink raw reply
* Re: [PATCH v4 5/5] clk: rockchip: rk3588: add GATE_GRF clocks for I2S MCLK output to IO
From: Diederik de Haas @ 2026-06-23 13:05 UTC (permalink / raw)
To: Daniele Briguglio, Heiko Stuebner, Michael Turquette,
Stephen Boyd, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Diederik de Haas
Cc: Nicolas Frattaroli, linux-clk, devicetree, linux-arm-kernel,
linux-rockchip, linux-kernel, Ricardo Pardini
In-Reply-To: <20260623123316.4111002-1-hello@superkali.me>
On Tue Jun 23, 2026 at 2:33 PM CEST, Daniele Briguglio wrote:
>> can you check if adding CLK_IGNORE_UNUSED changes the situation for you?
>> What I assume is happening is that when the clocks were not declared they were
>> just left running, while now the kernel turns off unused (but defined) clocks.
>
> That lines up with what I see. The gates are set-to-disable and reset to
> open, so before the series the bit just kept whatever the boot firmware
> left it at.
>
> Diederik, the cleanest way to confirm is to read SOC_CON6 before Linux
> touches it, e.g. md.l 0xfd58c318 at the U-Boot prompt (bit 0 is I2S0). If
> it comes up clear there, the gate is open, and if audio then breaks once
> the kernel is up, that points at clk_disable_unused turning it off because
> nothing references it.
NanoPC-T6 LTS
U-Boot: 2026.04-00003-g723f0da896bc
The 0003 comes from me adding patches for NanoPC-T6 Plus support, but
otherwise it's plain upstream U-Boot.
=> md.l 0xfd58c318
fd58c318: 00000600 00000a00 00000000 00000000 ................
fd58c328: 00000300 00092820 0fd58c338: 00000000 00000000 00000000 00000000 ................
fd58c348: 00000000 00000000 00000000 00000000 ................c358: 00000000 00000000 00000000 00000000 ................
fd58c368: 00000000 00000000 00000008: 00000000 00000000 00001000 00000240 ............@...
fd58c388: 0000003f 0000fefe 00000000 000000000 00000000 00000000 00000000 ................
fd58c3a8: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 ................
fd58c3c8: 00000000 00000000 00000000 000000000 00000000 00000000 00000000 ................
fd58c3e8: 00000000 00000000 00000000 00000000 .0000000 00000000 00000000 ................
fd58c408: 00000000 00000000 00000000 00000000 ....
I'll let interpreting it up to you.
> If that turns out to be the case, CLK_IGNORE_UNUSED on the gates is a
> reasonable way to stop the kernel from closing a gate the firmware already
> left open, for boards that would rather not switch their DTS to _TO_IO.
I'm not so sure I agree that CLK_IGNORE_UNUSED is reasonable, but I'll leave
judgement up to others. I'll do the test regardless, though.
Cheers,
Diederik
> Where a board does reference _TO_IO the consumer holds it open anyway, so
> that path is unaffected either way.
>
> Best regards,
> Daniele
^ permalink raw reply
* Re: [PATCH v4 02/12] dt-bindings: iio: dac: ad5696: rework on power supplies
From: sashiko-bot @ 2026-06-23 13:05 UTC (permalink / raw)
To: Rodrigo Alencar via B4 Relay; +Cc: devicetree, conor+dt, robh
In-Reply-To: <20260623-ad5686-new-features-v4-2-28962a57db0f@analog.com>
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Medium] Unconditionally requiring new `vdd-supply` and `vlogic-supply` properties breaks validation for existing device trees.
- [Medium] Conditionally requiring `vref-supply` for `adi,ad5696` breaks schema validation for legacy device trees that use the deprecated `vcc-supply`.
--
commit 7082ab254ab9eb0509320518d5cb786825dd6cbb
Author: Rodrigo Alencar <rodrigo.alencar@analog.com>
dt-bindings: iio: dac: ad5696: rework on power supplies
This commit updates the AD5696 DAC binding to include vdd-supply,
vlogic-supply, and vref-supply, while deprecating the misleading vcc-supply.
It also updates the required property lists and conditionally requires
vref-supply for specific variants.
> diff --git a/Documentation/devicetree/bindings/iio/dac/adi,ad5696.yaml b/Documentation/devicetree/bindings/iio/dac/adi,ad5696.yaml
> index cc343cdf6085a..e10f8596f9d3f 100644
> --- a/Documentation/devicetree/bindings/iio/dac/adi,ad5696.yaml
> +++ b/Documentation/devicetree/bindings/iio/dac/adi,ad5696.yaml
[ ... ]
> @@ -62,8 +75,21 @@ properties:
> required:
> - compatible
> - reg
> + - vdd-supply
> + - vlogic-supply
[Severity: Medium]
Does unconditionally adding vdd-supply and vlogic-supply to the required
list break schema validation for existing device trees?
Legacy device trees that legitimately omitted these properties will now fail
schema validation during make dtbs_check.
>
> allOf:
> + - if:
> + properties:
> + compatible:
> + contains:
> + enum:
> + - adi,ad5693
> + - adi,ad5694
> + - adi,ad5696
> + then:
> + required:
> + - vref-supply
[Severity: Medium]
Does conditionally requiring vref-supply for these compatible strings break
schema validation for legacy device trees that use the deprecated vcc-supply?
Since vcc-supply was valid under the previous schema, making vref-supply
strictly required here will cause validation failures for existing device
trees. Should the schema allow either vref-supply or the deprecated
vcc-supply to preserve DT ABI compatibility?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260623-ad5686-new-features-v4-0-28962a57db0f@analog.com?part=2
^ permalink raw reply
* [PATCH v2 3/3] arm64: dts: qcom: glymur-crd: Add refgen supplies for PCIe PHY on Glymur
From: Qiang Yu @ 2026-06-23 13:05 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bjorn Andersson, Konrad Dybcio
Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel, Qiang Yu
In-Reply-To: <20260623-phy_refgen-v2-0-4d15983bf91d@oss.qualcomm.com>
The PCIe PHYs on Glymur require a reference voltage provided by REFGEN,
which in turn is powered by two LDOs.
Since there is no devicetree node for REFGEN, add the vdda-refgen0p9 and
vdda-refgen1p2 supplies for each PCIe PHY node.
Signed-off-by: Qiang Yu <qiang.yu@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/glymur-crd.dtsi | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/glymur-crd.dtsi b/arch/arm64/boot/dts/qcom/glymur-crd.dtsi
index e784b538f42e..bdf7db3493bd 100644
--- a/arch/arm64/boot/dts/qcom/glymur-crd.dtsi
+++ b/arch/arm64/boot/dts/qcom/glymur-crd.dtsi
@@ -454,6 +454,8 @@ &pcie3b {
&pcie3b_phy {
vdda-phy-supply = <&vreg_l3c_e1_0p89>;
vdda-pll-supply = <&vreg_l2c_e1_1p14>;
+ vdda-refgen0p9-supply = <&vreg_l1c_e1_0p82>;
+ vdda-refgen1p2-supply = <&vreg_l4f_e1_1p08>;
};
&pcie3b_port0 {
@@ -471,6 +473,8 @@ &pcie4 {
&pcie4_phy {
vdda-phy-supply = <&vreg_l1c_e1_0p82>;
vdda-pll-supply = <&vreg_l4f_e1_1p08>;
+ vdda-refgen0p9-supply = <&vreg_l1c_e1_0p82>;
+ vdda-refgen1p2-supply = <&vreg_l4f_e1_1p08>;
status = "okay";
};
@@ -507,6 +511,8 @@ &pcie5 {
&pcie5_phy {
vdda-phy-supply = <&vreg_l2f_e0_0p82>;
vdda-pll-supply = <&vreg_l4h_e0_1p2>;
+ vdda-refgen0p9-supply = <&vreg_l2f_e0_0p82>;
+ vdda-refgen1p2-supply = <&vreg_l4h_e0_1p2>;
status = "okay";
};
@@ -528,6 +534,8 @@ &pcie6 {
&pcie6_phy {
vdda-phy-supply = <&vreg_l1c_e1_0p82>;
vdda-pll-supply = <&vreg_l4f_e1_1p08>;
+ vdda-refgen0p9-supply = <&vreg_l1c_e1_0p82>;
+ vdda-refgen1p2-supply = <&vreg_l4f_e1_1p08>;
status = "okay";
};
--
2.34.1
^ permalink raw reply related
* [PATCH v2 2/3] phy: qcom: qmp-pcie: Add vdda-refgen supplies for Glymur
From: Qiang Yu @ 2026-06-23 13:05 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bjorn Andersson, Konrad Dybcio
Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel, Qiang Yu
In-Reply-To: <20260623-phy_refgen-v2-0-4d15983bf91d@oss.qualcomm.com>
The refgen providing reference voltage for PCIe QMP PHY on Glymur requires
two power supplies independent from the PHY's core and qref rails. Add
support for vdda-refgen0p9 and vdda-refgen1p2 supplies with a dedicated
glymur_qmp_phy_vreg_l list.
Update both Gen5x4 and Gen4x2 configurations to use the new supply list.
Signed-off-by: Qiang Yu <qiang.yu@oss.qualcomm.com>
---
drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
index d3effad7a074..08bc89ce80e1 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
@@ -3488,6 +3488,10 @@ static const char * const sm8550_qmp_phy_vreg_l[] = {
"vdda-phy", "vdda-pll", "vdda-qref",
};
+static const char * const glymur_qmp_phy_vreg_l[] = {
+ "vdda-phy", "vdda-pll", "vdda-refgen0p9", "vdda-refgen1p2",
+};
+
/* list of resets */
static const char * const ipq8074_pciephy_reset_l[] = {
"phy", "common",
@@ -4756,8 +4760,8 @@ static const struct qmp_phy_cfg glymur_qmp_gen5x4_pciephy_cfg = {
.reset_list = sdm845_pciephy_reset_l,
.num_resets = ARRAY_SIZE(sdm845_pciephy_reset_l),
- .vreg_list = qmp_phy_vreg_l,
- .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
+ .vreg_list = glymur_qmp_phy_vreg_l,
+ .num_vregs = ARRAY_SIZE(glymur_qmp_phy_vreg_l),
.regs = pciephy_v8_50_regs_layout,
@@ -4772,8 +4776,8 @@ static const struct qmp_phy_cfg glymur_qmp_gen4x2_pciephy_cfg = {
.reset_list = sdm845_pciephy_reset_l,
.num_resets = ARRAY_SIZE(sdm845_pciephy_reset_l),
- .vreg_list = qmp_phy_vreg_l,
- .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
+ .vreg_list = glymur_qmp_phy_vreg_l,
+ .num_vregs = ARRAY_SIZE(glymur_qmp_phy_vreg_l),
.regs = pciephy_v8_regs_layout,
--
2.34.1
^ permalink raw reply related
* [PATCH v2 1/3] dt-bindings: phy: sc8280xp-qmp-pcie: Add vdda-refgen supply for Glymur
From: Qiang Yu @ 2026-06-23 13:05 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bjorn Andersson, Konrad Dybcio
Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel, Qiang Yu
In-Reply-To: <20260623-phy_refgen-v2-0-4d15983bf91d@oss.qualcomm.com>
The PCIe QMP PHYs require a stable reference voltage provided by REFGEN,
which in turn requires two separate LDOs to operate.
Add vdda-refgen0p9-supply and vdda-refgen1p2-supply properties. Mark them
as required for the Glymur PCIe QMP PHYs for now; other platforms having
the same requirement and can be added later.
Signed-off-by: Qiang Yu <qiang.yu@oss.qualcomm.com>
---
.../bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
index 108cf9dc86ea..375f5fb2111f 100644
--- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
@@ -91,6 +91,10 @@ properties:
vdda-qref-supply: true
+ vdda-refgen0p9-supply: true
+
+ vdda-refgen1p2-supply: true
+
qcom,4ln-config-sel:
description: PCIe 4-lane configuration
$ref: /schemas/types.yaml#/definitions/phandle-array
@@ -261,6 +265,18 @@ allOf:
"#clock-cells":
const: 0
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - qcom,glymur-qmp-gen4x2-pcie-phy
+ - qcom,glymur-qmp-gen5x4-pcie-phy
+ then:
+ required:
+ - vdda-refgen0p9-supply
+ - vdda-refgen1p2-supply
+
examples:
- |
#include <dt-bindings/clock/qcom,gcc-sc8280xp.h>
--
2.34.1
^ permalink raw reply related
* [PATCH v2 0/3] phy: qcom: qmp-pcie: Add vdda-refgen supply support for Glymur
From: Qiang Yu @ 2026-06-23 13:05 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bjorn Andersson, Konrad Dybcio
Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel, Qiang Yu
The PCIe QMP PHYs on Glymur require both refgen for stable reference
voltage and qref for stable reference clock. The refgen requires two power
supplies: vdda-refgen0p9 and vdda-refgen1p2.
can be extended in the future.
This series creates a Glymur-specific supply list including the refgen
supplies and updates both Gen5x4 and Gen4x2 configurations to use it.
Signed-off-by: Qiang Yu <qiang.yu@oss.qualcomm.com>
Changes in v2:
- Add dts patch in this series.
- Reword commit msg of dtbinding patch.
- Link to v1: https://lore.kernel.org/all/20260208-refgen-v1-0-87ca84fd78b3@oss.qualcomm.com/
---
Qiang Yu (3):
dt-bindings: phy: sc8280xp-qmp-pcie: Add vdda-refgen supply for Glymur
phy: qcom: qmp-pcie: Add vdda-refgen supplies for Glymur
arm64: dts: qcom: glymur-crd: Add refgen supplies for PCIe PHY on Glymur
.../bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml | 16 ++++++++++++++++
arch/arm64/boot/dts/qcom/glymur-crd.dtsi | 8 ++++++++
drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 12 ++++++++----
3 files changed, 32 insertions(+), 4 deletions(-)
---
base-commit: 3ce97bd3c4f18608335e709c24d6a40e7036cab8
change-id: 20260621-phy_refgen-db77317ec05a
Best regards,
--
Qiang Yu <qiang.yu@oss.qualcomm.com>
^ permalink raw reply
* Re: [PATCH v4 5/5] clk: rockchip: rk3588: add GATE_GRF clocks for I2S MCLK output to IO
From: Daniele Briguglio @ 2026-06-23 12:33 UTC (permalink / raw)
To: Heiko Stuebner, Michael Turquette, Stephen Boyd, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Diederik de Haas
Cc: Nicolas Frattaroli, linux-clk, devicetree, linux-arm-kernel,
linux-rockchip, linux-kernel, Ricardo Pardini
In-Reply-To: <2100447.PIDvDuAF1L@diego>
Hi Heiko,
> can you check if adding CLK_IGNORE_UNUSED changes the situation for you?
> What I assume is happening is that when the clocks were not declared they were
> just left running, while now the kernel turns off unused (but defined) clocks.
That lines up with what I see. The gates are set-to-disable and reset to
open, so before the series the bit just kept whatever the boot firmware
left it at.
Diederik, the cleanest way to confirm is to read SOC_CON6 before Linux
touches it, e.g. md.l 0xfd58c318 at the U-Boot prompt (bit 0 is I2S0). If
it comes up clear there, the gate is open, and if audio then breaks once
the kernel is up, that points at clk_disable_unused turning it off because
nothing references it.
If that turns out to be the case, CLK_IGNORE_UNUSED on the gates is a
reasonable way to stop the kernel from closing a gate the firmware already
left open, for boards that would rather not switch their DTS to _TO_IO.
Where a board does reference _TO_IO the consumer holds it open anyway, so
that path is unaffected either way.
Best regards,
Daniele
^ permalink raw reply
* Re: [PATCH v9 1/2] dt-bindings: i3c: Add AMD I3C master controller support
From: Pandey, Radhey Shyam @ 2026-06-23 12:57 UTC (permalink / raw)
To: Shubham Patil, git, michal.simek, alexandre.belloni, Frank.Li,
robh, krzk+dt, conor+dt, pgaj, wsa+renesas, tommaso.merciai.xr,
arnd, quic_msavaliy, Shyam-sundar.S-k, sakari.ailus, billy_tsai,
kees, gustavoars, jarkko.nikula, jorge.marques, linux-i3c,
devicetree, linux-kernel, linux-arch, linux-hardening
Cc: radhey.shyam.pandey, srinivas.goud, shubhrajyoti.datta,
Manikanta Guntupalli
In-Reply-To: <20260623114417.2578189-2-shubhamsanjay.patil@amd.com>
> From: Manikanta Guntupalli <manikanta.guntupalli@amd.com>
>
> Add device tree binding documentation for the AMD I3C master controller
> version 1.0.
>
> Signed-off-by: Manikanta Guntupalli <manikanta.guntupalli@amd.com>
> Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
It's missing your SOB.
Any further SoBs (Signed-off-by:s) following the author SoB are
from people handling and transporting the patch, but were not
involved in its development.
> ---
> Changes for V9:
> None.
It's not correct - you updated maintainer section in yaml?
>
> Changes for V8:
> None.
>
> Changes for V7:
> Added i3c controller version details to commit description.
>
> Changes for V6:
> Corrected the file name for $id in yaml to fix the dtschema warning.
>
> Changes for V5:
> Renamed the xlnx,axi-i3c.yaml file into xlnx,axi-i3c-1.0.yaml.
>
> Changes for V4:
> Added h/w documentation details.
>
> Changes for V3:
> Updated commit description.
> Corrected the order of properties and removed resets property.
> Added compatible to required list.
> Added interrupts to example.
>
> Changes for V2:
> Updated commit subject and description.
> Moved allOf to after required.
> Removed xlnx,num-targets property.
> ---
> .../bindings/i3c/xlnx,axi-i3c-1.0.yaml | 56 +++++++++++++++++++
> 1 file changed, 56 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/i3c/xlnx,axi-i3c-1.0.yaml
>
> diff --git a/Documentation/devicetree/bindings/i3c/xlnx,axi-i3c-1.0.yaml b/Documentation/devicetree/bindings/i3c/xlnx,axi-i3c-1.0.yaml
> new file mode 100644
> index 000000000000..75f677696f02
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/i3c/xlnx,axi-i3c-1.0.yaml
> @@ -0,0 +1,56 @@
> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/i3c/xlnx,axi-i3c-1.0.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: AMD I3C master
> +
> +maintainers:
> + - Shubhrajyoti Datta <shubhrajyoti.datta@amd.com>
> + - Shubham Patil <shubhamsanjay.patil@amd.com>
> +
> +description:
> + The AXI-I3C IP is an I3C Controller with an AXI4-Lite interface, compatible
> + with the MIPI I3C Specification v1.1.1. The design includes bidirectional I/O
> + buffers that implement open collector drivers for the SDA and SCL signals.
> + External pull-up resistors are required to properly hold the bus at a Logic-1
> + level when the drivers are released.
> +
> + For more details, please see https://docs.amd.com/r/en-US/pg439-axi-i3c
> +
> +properties:
> + compatible:
> + const: xlnx,axi-i3c-1.0
> +
> + reg:
> + maxItems: 1
> +
> + clocks:
> + maxItems: 1
> +
> + interrupts:
> + maxItems: 1
> +
> +required:
> + - compatible
> + - reg
> + - clocks
> +
> +allOf:
> + - $ref: i3c.yaml#
> +
> +unevaluatedProperties: false
> +
> +examples:
> + - |
> + i3c@80000000 {
> + compatible = "xlnx,axi-i3c-1.0";
> + reg = <0x80000000 0x10000>;
> + clocks = <&zynqmp_clk 71>;
> + interrupt-parent = <&imux>;
> + interrupts = <0 89 4>;
Nit - Don't use hard-coded numbers.
> + #address-cells = <3>;
> + #size-cells = <0>;
> + };
> +...
^ permalink raw reply
* Re: [PATCH] of_numa: fix return -EINVAL when numa-node-id is not found in last node
From: Rob Herring @ 2026-06-23 12:53 UTC (permalink / raw)
To: Sang-Heon Jeon
Cc: Saravana Kannan, Andrew Morton, Dan Williams, David Hildenbrand,
devicetree, Mike Rapoport (Microsoft)
In-Reply-To: <CABFDxMG2ysTYPwJxg8Cq-uWxc+LZzfo_3_S8WwG2wtXMcwo9sg@mail.gmail.com>
On Tue, Jun 23, 2026 at 7:08 AM Sang-Heon Jeon <ekffu200098@gmail.com> wrote:
>
> On Tue, Jun 23, 2026 at 10:42 AM Rob Herring <robh@kernel.org> wrote:
> >
> > On Sun, Jun 21, 2026 at 11:39:18PM +0900, Sang-Heon Jeon wrote:
> > > When the numa-node-id property is not found in the last memory node,
> > > of_property_read_u32() returns -EINVAL, which then becomes the return
> > > value of of_numa_parse_memory_nodes(), even though earlier memory nodes
> > > were parsed successfully.
> > >
> > > Commit 7e488677a54a ("of, numa: return -EINVAL when no numa-node-id is
> > > found") meant -EINVAL to be returned only when the numa-node-id property
> > > is not found at all, not when it is found in an earlier memory node but
> > > not in the last.
> > >
> > > Check whether at least one memory node was parsed successfully, and return
> > > 0 in that case, -EINVAL otherwise, so the return value of
> > > of_property_read_u32() for the last memory node no longer corrupts the
> > > overall return value.
> >
> > IDK, it's arguable that an incomplete DT isn't valid and something we
> > need to support. Is missing numa-node-id valid or it's just better to
> > have at least partially
> > configured NUMA nodes?
>
> You're right.
>
> Since the first implementation 298535c00a2c ("of, numa: Add NUMA of
> binding implementation.") skips memory nodes without `numa-node-id`,
> I only try to fix the error case introduced by 7e488677a54a ("of,
> numa: return -EINVAL when no numa-node-id is found").
>
> IMHO, if changing the logic is acceptable, rejecting DT with an
> incomplete NUMA configuration also seems reasonable.
> We already call memblock_validate_numa_coverage() after
> of_numa_parse_memory_nodes(),
> so such an incomplete configuration would most likely fail from that
> validation anyway.
>
> So, would it be OK to reject a DT with an incomplete NUMA
> configuration? If so, I'll make a patch in that direction instead.
Reject? As in panic()? No, because why would we make a system that
boots not boot and a panic at that stage won't be seen because your
console is not up yet. If you want to add a warning that the NUMA
information is incomplete, that would be fine.
Also, are we sure it's not valid to have some memory associated with a
numa node and some that is not?
Rob
^ permalink raw reply
* Re: [PATCH v2 10/12] ARM: dts: microchip: sama7d65: add cells for temperature calibration
From: sashiko-bot @ 2026-06-23 12:42 UTC (permalink / raw)
To: Varshini Rajendran; +Cc: robh, conor+dt, devicetree
In-Reply-To: <20260623105944.128840-11-varshini.rajendran@microchip.com>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] The ADC driver fails to propagate `-EPROBE_DEFER` when acquiring the NVMEM cell, leading to silent loss of the temperature channel and thermal protection.
--
commit ef1a2c61577cd00a6df4dd81d5825424af16746d
Author: Varshini Rajendran <varshini.rajendran@microchip.com>
ARM: dts: microchip: sama7d65: add cells for temperature calibration
This commit adds an NVMEM cell to the ADC node for temperature calibration
data.
> diff --git a/arch/arm/boot/dts/microchip/sama7d65.dtsi b/arch/arm/boot/dts/microchip/sama7d65.dtsi
> index 5867fda378b19..c336f863406de 100644
> --- a/arch/arm/boot/dts/microchip/sama7d65.dtsi
> +++ b/arch/arm/boot/dts/microchip/sama7d65.dtsi
> @@ -323,6 +323,8 @@ adc: adc@e1000000 {
> atmel,trigger-edge-type = <IRQ_TYPE_EDGE_RISING>;
> atmel,startup-time-ms = <4>;
> #io-channel-cells = <1>;
> + nvmem-cells = <&temperature_calib>;
> + nvmem-cell-names = "temperature_calib";
[Severity: High]
This is a pre-existing issue, but will adding these cells expose a probe
deferral issue in the ADC driver?
In drivers/iio/adc/at91-sama5d2_adc.c:at91_adc_temp_sensor_init(),
nvmem_cell_get() may return -EPROBE_DEFER:
temp_calib = nvmem_cell_get(dev, "temperature_calib");
if (IS_ERR(temp_calib)) {
ret = PTR_ERR(temp_calib);
if (ret != -ENOENT)
dev_err(dev, "Failed to get temperature_calib cell!\n");
return ret;
}
However, in at91_adc_probe(), this returned error appears to be swallowed:
ret = at91_adc_temp_sensor_init(st, &pdev->dev);
/* Don't register temperature channel if initialization failed. */
if (ret)
num_channels = st->soc_info.platform->max_channels - 1;
If the NVMEM provider (OTPC) probes after the ADC driver, the ADC driver will
permanently skip registering the temperature channel instead of deferring
its probe.
Since the system's thermal zones might rely on this channel for CPU
temperature monitoring and emergency shutdown, could this lead to a silent
loss of thermal protection?
Would it make sense to update the driver to use dev_err_probe() and properly
propagate -EPROBE_DEFER before these cells are added?
> status = "disabled";
> };
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260623105944.128840-1-varshini.rajendran@microchip.com?part=10
^ permalink raw reply
* Re: [PATCH 2/13] dt-bindings: sound: Add Qualcomm QAIF binding
From: Harendra Gautam @ 2026-06-23 12:30 UTC (permalink / raw)
To: Rob Herring (Arm)
Cc: Conor Dooley, Srinivas Kandagatla, Krzysztof Kozlowski,
devicetree, linux-sound, linux-arm-msm, linux-kernel, Mark Brown,
Liam Girdwood
In-Reply-To: <178065883033.3171433.8446753794680185025.robh@kernel.org>
On Fri, Jun 5, 2026 at 4:57 PM Rob Herring (Arm) <robh@kernel.org> wrote:
>
>
> On Fri, 05 Jun 2026 16:07:28 +0530, Harendra Gautam wrote:
> > Add a Devicetree binding for the Qualcomm Audio Interface (QAIF) CPU DAI
> > controller used on the Shikra audio platform.
> >
> > QAIF moves PCM data between system memory and external serial audio
> > interfaces through the AIF path, and between memory and the internal Bolero
> > digital codec through the CIF path. The controller needs a binding so
> > platform Devicetree files can describe its MMIO region, DMA IOMMU stream,
> > clocks, interrupt, DAI cells and per-interface AIF configuration.
> >
> > Describe the single register region, one EE interrupt, the required GCC
> > LPASS and audio core clocks, the DMA IOMMU mapping, and 'aif-interface@N'
> > child nodes used for static PCM, TDM or MI2S configuration.
> >
> > Signed-off-by: Harendra Gautam <harendra.gautam@oss.qualcomm.com>
> > ---
> > .../devicetree/bindings/sound/qcom,qaif.yaml | 353 ++++++++++++++++++
> > 1 file changed, 353 insertions(+)
> > create mode 100644 Documentation/devicetree/bindings/sound/qcom,qaif.yaml
> >
>
> My bot found errors running 'make dt_binding_check' on your patch:
>
> yamllint warnings/errors:
>
> dtschema/dtc warnings/errors:
> Documentation/devicetree/bindings/sound/qcom,qaif.example.dts:28:18: fatal error: dt-bindings/clock/qcom,shikra-audiocorecc.h: No such file or directory
> 28 | #include <dt-bindings/clock/qcom,shikra-audiocorecc.h>
> | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> compilation terminated.
> make[2]: *** [scripts/Makefile.dtbs:140: Documentation/devicetree/bindings/sound/qcom,qaif.example.dtb] Error 1
> make[2]: *** Waiting for unfinished jobs....
> make[1]: *** [/builds/robherring/dt-review-ci/linux/Makefile:1662: dt_binding_check] Error 2
> make: *** [Makefile:248: __sub-make] Error 2
>
> doc reference errors (make refcheckdocs):
>
> See https://patchwork.kernel.org/project/devicetree/patch/20260605103739.3557573-3-harendra.gautam@oss.qualcomm.com
>
> The base for the series is generally the latest rc1. A different dependency
> should be noted in *this* patch.
>
> If you already ran 'make dt_binding_check' and didn't see the above
> error(s), then make sure 'yamllint' is installed and dt-schema is up to
> date:
>
> pip3 install dtschema --upgrade
>
> Please check and re-submit after running the above command yourself. Note
> that DT_SCHEMA_FILES can be set to your schema file to speed up checking
> your schema. However, it must be unset to test all examples with your schema.
>
Thanks for pointing out and sharing the steps, the dependent changes
are also under review,
Will mark that as dependency here in the next patch.
--Harendra
^ permalink raw reply
* Re: [PATCH 2/13] dt-bindings: sound: Add Qualcomm QAIF binding
From: Harendra Gautam @ 2026-06-23 12:26 UTC (permalink / raw)
To: Konrad Dybcio
Cc: Srinivas Kandagatla, Mark Brown, Liam Girdwood, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, linux-sound, linux-arm-msm,
devicetree, linux-kernel
In-Reply-To: <3da8b668-1504-450e-bde2-b383d63090a8@oss.qualcomm.com>
On Tue, Jun 9, 2026 at 3:27 PM Konrad Dybcio
<konrad.dybcio@oss.qualcomm.com> wrote:
>
> On 6/5/26 12:37 PM, Harendra Gautam wrote:
> > Add a Devicetree binding for the Qualcomm Audio Interface (QAIF) CPU DAI
> > controller used on the Shikra audio platform.
> >
> > QAIF moves PCM data between system memory and external serial audio
> > interfaces through the AIF path, and between memory and the internal Bolero
> > digital codec through the CIF path. The controller needs a binding so
> > platform Devicetree files can describe its MMIO region, DMA IOMMU stream,
> > clocks, interrupt, DAI cells and per-interface AIF configuration.
> >
> > Describe the single register region, one EE interrupt, the required GCC
> > LPASS and audio core clocks, the DMA IOMMU mapping, and 'aif-interface@N'
> > child nodes used for static PCM, TDM or MI2S configuration.
> >
> > Signed-off-by: Harendra Gautam <harendra.gautam@oss.qualcomm.com>
> > ---
>
> [...]
>
> > + clock-names:
> > + items:
> > + - const: lpass_config_clk
> > + - const: lpass_core_axim_clk
> > + - const: aud_dma_clk
> > + - const: aud_dma_mem_clk
> > + - const: bus_clk
> > + - const: aif_if0_ebit_clk
> > + - const: aif_if0_ibit_clk
> > + - const: aif_if1_ebit_clk
> > + - const: aif_if1_ibit_clk
> > + - const: aif_if2_ebit_clk
> > + - const: aif_if2_ibit_clk
> > + - const: aif_if3_ebit_clk
> > + - const: aif_if3_ibit_clk
> > + - const: ext_mclka_clk
> > + - const: ext_mclkb_clk
>
> Drop the _clk suffix, we already know they are clocks, as they are
> listed under the clocks property
Okay, will correct.
>
> [...]
>
> > + qcom,qaif-aif-sync-mode:
> > + $ref: /schemas/types.yaml#/definitions/uint32
> > + description:
> > + Sync mode. Use QAIF_AIF_SYNC_MODE_SHORT (0) for short (pulse)
> > + sync or QAIF_AIF_SYNC_MODE_LONG (1) for long (level) sync.
> > + qcom,qaif-aif-sync-src:
> > + $ref: /schemas/types.yaml#/definitions/uint32
> > + description:
> > + Sync source. Use QAIF_AIF_SYNC_SRC_SLAVE (0) for slave mode
> > + or QAIF_AIF_SYNC_SRC_MASTER (1) for master mode.
>
> Should these be boolean flags then?
It should not be, the intention is to define explicitly, for better
readability I can rename these flags as EXTERNAL/INTERNAL, Please
suggest.
>
> [...]
>
> > + #sound-dai-cells = <1>;
> > + #address-cells = <1>;
> > + #size-cells = <0>;
> > + interrupts = <GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH>;
> > + status = "okay";
>
> status is "okay" by default if unspecified
Okay, Will remove it.
>
> Konrad
^ permalink raw reply
* Re: [PATCH v2 08/12] ARM: dts: microchip: sama7d65_curiosity: Enable ADC, DVFS
From: sashiko-bot @ 2026-06-23 12:20 UTC (permalink / raw)
To: Varshini Rajendran; +Cc: conor+dt, devicetree, robh
In-Reply-To: <20260623105944.128840-9-varshini.rajendran@microchip.com>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] The `&adc` device tree node override is not sorted alphabetically, violating device tree formatting guidelines.
--
commit 922e23aeb754d170e8991198310689112a690505
Author: Varshini Rajendran <varshini.rajendran@microchip.com>
ARM: dts: microchip: sama7d65_curiosity: Enable ADC, DVFS
This commit adds the regulator, pinmux, and enables the ADC for the
sama7d65 curiosity board. It also adds the cpu-supply regulator for DVFS.
> diff --git a/arch/arm/boot/dts/microchip/at91-sama7d65_curiosity.dts b/arch/arm/boot/dts/microchip/at91-sama7d65_curiosity.dts
> index 927c27260b6cc..a6a44a176f565 100644
> --- a/arch/arm/boot/dts/microchip/at91-sama7d65_curiosity.dts
> +++ b/arch/arm/boot/dts/microchip/at91-sama7d65_curiosity.dts
> @@ -97,6 +97,18 @@ &can3 {
> status = "okay";
> };
>
> +&adc {
[Severity: Low]
This isn't a bug, but should the &adc node override be sorted alphabetically
within the device tree file?
It is currently inserted after &can3, but standard device tree formatting
guidelines generally require node overrides to be sorted alphabetically to
maintain readability and reduce merge conflicts.
> + vddana-supply = <&vddout25>;
> + vref-supply = <&vddout25>;
> + pinctrl-names = "default";
> + pinctrl-0 = <&pinctrl_adc_default &pinctrl_adtrg_default>;
> + status = "okay";
> +};
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260623105944.128840-1-varshini.rajendran@microchip.com?part=8
^ permalink raw reply
* Re: [PATCH 2/13] dt-bindings: sound: Add Qualcomm QAIF binding
From: Harendra Gautam @ 2026-06-23 12:17 UTC (permalink / raw)
To: Srinivas Kandagatla
Cc: Mark Brown, Liam Girdwood, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, linux-sound, linux-arm-msm, devicetree,
linux-kernel
In-Reply-To: <69d2e4a7-eb2e-42f2-83e4-0d8ca4b62da8@kernel.org>
On Wed, Jun 17, 2026 at 1:29 AM Srinivas Kandagatla <srini@kernel.org> wrote:
>
>
>
> On 6/5/26 11:37 AM, Harendra Gautam wrote:
> > Add a Devicetree binding for the Qualcomm Audio Interface (QAIF) CPU DAI
> > controller used on the Shikra audio platform.
> >
> > QAIF moves PCM data between system memory and external serial audio
> > interfaces through the AIF path, and between memory and the internal Bolero
> > digital codec through the CIF path. The controller needs a binding so
> > platform Devicetree files can describe its MMIO region, DMA IOMMU stream,
> > clocks, interrupt, DAI cells and per-interface AIF configuration.
> >
> > Describe the single register region, one EE interrupt, the required GCC
> > LPASS and audio core clocks, the DMA IOMMU mapping, and 'aif-interface@N'
> > child nodes used for static PCM, TDM or MI2S configuration.
> >
> > Signed-off-by: Harendra Gautam <harendra.gautam@oss.qualcomm.com>
> > ---
> > .../devicetree/bindings/sound/qcom,qaif.yaml | 353 ++++++++++++++++++
> > 1 file changed, 353 insertions(+)
> > create mode 100644 Documentation/devicetree/bindings/sound/qcom,qaif.yaml
> >
> > diff --git a/Documentation/devicetree/bindings/sound/qcom,qaif.yaml b/Documentation/devicetree/bindings/sound/qcom,qaif.yaml
>
> Pl run dt-bindings checks before posting.
> > new file mode 100644
> > index 000000000000..5b385e05a650
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/sound/qcom,qaif.yaml
> > @@ -0,0 +1,361 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/sound/qcom,qaif.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: Qualcomm Audio Interface (QAIF) CPU DAI Controller
> > +
> > +maintainers:
> > + - Harendra Gautam <harendra.gautam@oss.qualcomm.com>
> > +
> > +description:
> > + |
> > + The Qualcomm Audio Interface (QAIF) is a fully configurable DMA-based
> > + audio subsystem controller. It serialises and deserialises PCM audio
> > + between system memory and external serial audio peripherals (PCM, TDM,
> > + I2S, MI2S) through the AIF path, and transfers parallel audio between
> > + memory and an internal WCD codec through the CIF path.
> > +
> > + AIF (Audio Interface): up to 13 multi-lane Unified Audio Interfaces,
> > + each supporting up to 8 independent data lanes. Each lane is individually
> > + configurable as TX (output/speaker) or RX (input/mic). All lanes of an
> > + interface share a single bit clock and frame sync. Supported modes are
> > + PCM (short/long sync), TDM, and MI2S (stereo/mono). Per-interface
> > + configuration includes sync source (master/slave), sync mode, sync delay,
> > + sync inversion, slot width (8/16/24/32-bit), sample width, active slot
> > + masks (up to 32 slots), bits-per-lane frame size, lane enable/direction
> > + masks, loopback, output-enable control, and full-cycle path support for
> > + long chip-to-chip connections.
> > +
> > + CIF (Codec Interface): up to 32 RDDMA (playback) and 32 WRDMA (capture)
> > + channels connecting to an internal codec over a parallel bus. Each channel
> > + supports active-channel enable mask (up to 16 channels), frame-sync
> > + selection, frame-sync delay, frame-sync output gating, dynamic clock
> > + gating, and 16-bit packing/unpacking.
> > +
> > + Note on RX/TX naming convention: in QAIF, RX refers to the capture path
> > + (audio received from the interface into memory) and TX refers to the
> > + playback path (audio transmitted from memory to the interface). This
> > + applies to both AIF lane directions and CIF slot/mask properties.
> > +
> > + DMA engine: RDDMA fetches audio from DDR/TCM/LPM into a shared SRAM
> > + latency buffer (SHRAM) and drains it to the interface. WRDMA collects
> > + data from the interface into SHRAM and writes it to memory. Each DMA
> > + owns a private SHRAM region defined by start address and length registers.
> > + Burst sizes of 1/2/4/8/16 beats (64-bit) are supported with up to 4
> > + outstanding transactions per DMA. Two QSB master ports (QXM0 for TCM,
> > + QXM1 for DDR/LPM) provide the memory interface.
> > +
> > + Resources are partitioned among up to 5 Execution Engines (EEs) via
> > + EE map registers. Each EE owns a set of DMAs, audio interfaces, and
> > + interface groups, and receives its own independent interrupt output.
> > + The interrupt hierarchy has a two-level structure: a summary register
> > + identifies the event class (DMA period, underflow/overflow, error
> > + response, audio interface underflow/overflow, group done, rate detector,
> > + VFR), and per-resource status registers identify the specific channel.
> > +
> > + Interface grouping (bonding) allows up to 6 groups of audio and codec
> > + interfaces to start synchronously and align their DMA period interrupts
> > + within half a frame duration using the RDDMA padding feature.
> > +
> > + Two rate detector blocks measure the frequency of incoming frame sync or
> > + word select signals and generate interrupts on rate change, undetected
> > + rate, or sync timeout.
> > +
> > + Block diagram::
> > +
> > + System Memory (DDR / LPM / TCM)
> > + +---------------------------------+
> > + | Circular Buffers (ping-pong) |
> > + +----------+----------+-----------+
> > + | ^
> > + 64-bit AXI 64-bit AXI
> > + | |
> > + +----------v----------+-----------+
> > + | QSB Master Ports |
> > + | +----------+ +----------+ |
> > + | | QXM0 | | QXM1 | |
> > + | +----+-----+ +-----+----+ |
> > + +-------|--------------|----------+
> > + | |
> > + +-------v--------------v----------+
> > + | Shared RAM (SHRAM) |
> > + | +------------+ +------------+ |
> > + | | QXM0 Read | | QXM0 Write | |
> > + | | SHRAM | | SHRAM | |
> > + | +------------+ +------------+ |
> > + | +------------+ +------------+ |
> > + | | QXM1 Read | | QXM1 Write | |
> > + | | SHRAM | | SHRAM | |
> > + | +------------+ +------------+ |
> > + +---+--------+--------+-------+---+
> > + | | | |
> > + +---v--+ +--v---+ +--v---+ +-v----+
> > + |RDDMA | |RDDMA | |WRDMA | |WRDMA |
> > + | AIF | | CIF | | AIF | | CIF |
> > + |[0..n]| |[0..n]| |[0..n]| |[0..n]|
> > + +--+---+ +--+---+ +--+---+ +-+----+
> > + | | ^ ^
> > + | TX | TX | RX | RX
> > + v v | |
> > + +--+--------------------+ +----+----------+
> > + | Unified Audio Intf | | Codec DMA |
> > + | (AIF 0..12) | | Interface |
> > + | | | (CIF) |
> > + | AUD_INTFa block: | | |
> > + | - Serializer (TX) | | RDDMA: DDR -> |
> > + | - De-serializer (RX) | | internal |
> > + | - Sync gen/detect | | codec |
> > + | - Up to 8 data lanes | | WRDMA: codec |
> > + | - PCM / TDM / MI2S | | -> DDR |
> > + | - Near Pad Logic | | Up to 16 ch |
> > + +--+--------------------+ +----+----------+
> > + | Lane 0..7 (TX/RX) | Parallel bus
> > + | Bit clk + Frame sync | + Frame sync
> > + v v
> > + +--+--------+ +------+------+
> > + | External | | Internal |
> > + | Serial | | Digital |
> > + | Peripherals| | Codec |
> > + | (PCM/TDM/ | | (Bolero/ |
> > + | MI2S) | | WCD) |
> > + +-----------+ +-------------+
> > +
> > +properties:
> > + compatible:
> > + enum:
> > + - qcom,shikra-qaif-cpu
> > +
> > + reg:
> > + maxItems: 1
> > +
> > + iommus:
> > + maxItems: 1
> > +
> > + clocks:
> > + minItems: 15
> > + maxItems: 15
> > +
> > + clock-names:
> > + items:
> > + - const: lpass_config_clk
> > + - const: lpass_core_axim_clk
> > + - const: aud_dma_clk
> > + - const: aud_dma_mem_clk
> > + - const: bus_clk
> > + - const: aif_if0_ebit_clk
> > + - const: aif_if0_ibit_clk
> > + - const: aif_if1_ebit_clk
> > + - const: aif_if1_ibit_clk
> > + - const: aif_if2_ebit_clk
> > + - const: aif_if2_ibit_clk
> > + - const: aif_if3_ebit_clk
> > + - const: aif_if3_ibit_clk
> > + - const: ext_mclka_clk
> > + - const: ext_mclkb_clk
>
>
> Also do we really need to specify these 15 clocks even though I use only
> one aif interface on my board.
As an example added all supported clock in this binding, in board
specific DT required clocks can be used.
--Harendra
>
> should some of these clocks belong to each aif child node instead of
> global qaif-cpu?
some of these clocks are interface related like aif_if0_ibit, kept in
parent node by taking reference from lpass-cpu driver.
--Harendra
>
> > +
> > + interrupts:
> > + maxItems: 1
> > +
> > + '#sound-dai-cells':
> > + const: 1
> > +
> > + '#address-cells':
> > + const: 1
> > +
> > + '#size-cells':
> > + const: 0
> > +
> > + status: true
> > +
> > +patternProperties:
> > + "^aif-interface@[0-9a-f]+$":
> > + type: object
> > + description:
> > + AIF interface configuration child node. The compatible string
> > + identifies the serial protocol the interface is wired for on the
> > + board. The unit address matches the hardware AIF interface index.
> > + properties:
> > + compatible:
> > + enum:
> > + - qcom,qaif-pcm-dai
> > + - qcom,qaif-tdm-dai
> > + - qcom,qaif-mi2s-dai
> > + reg:
> > + maxItems: 1
> > + description: |
> > + Hardware AIF interface index (AUD_INTFa block index). This value
> > + also serves as the ALSA DAI ID; it corresponds directly to the
> > + QAIF_MI2S_TDM_AIFn constants in <dt-bindings/sound/qcom,qaif.h>
> > + (e.g. reg = <2> selects QAIF_MI2S_TDM_AIF2).
> > + qcom,qaif-aif-sync-mode:
> > + $ref: /schemas/types.yaml#/definitions/uint32
>
> These should be enum instead of uint32, simillar comments apply to some
> of the properties that have only few supported values.
Okay
>
> > + description:
> > + Sync mode. Use QAIF_AIF_SYNC_MODE_SHORT (0) for short (pulse)
> > + sync or QAIF_AIF_SYNC_MODE_LONG (1) for long (level) sync.
> > + qcom,qaif-aif-sync-src:
> > + $ref: /schemas/types.yaml#/definitions/uint32
> > + description:
> > + Sync source. Use QAIF_AIF_SYNC_SRC_SLAVE (0) for slave mode
> > + or QAIF_AIF_SYNC_SRC_MASTER (1) for master mode.
> > + qcom,qaif-aif-invert-sync:
> > + type: boolean
> > + description: Invert the frame sync polarity.
> > + qcom,qaif-aif-sync-delay:
> > + $ref: /schemas/types.yaml#/definitions/uint32
> > + description: Number of bit-clock cycles to delay the data relative to sync.
>
> This looks redundant to qcom,qaif-aif-sync-mode, which already indicates
> the delay information?
SYNC_MODE defines the pulse width/duration (Short/Long/One-slot),
whereas SYNC_DELAY specifies the independent cycle offset for the MSB
data start relative to the sync edge.
>
> > + qcom,qaif-aif-slot-width-rx:
> > + $ref: /schemas/types.yaml#/definitions/uint32
> > + description:
> > + RX slot width in bits. This is a board-specific hardware constraint
> > + determined by the wiring of the serial audio interface.
> > + qcom,qaif-aif-slot-width-tx:
> > + $ref: /schemas/types.yaml#/definitions/uint32
> > + description:
> > + TX slot width in bits. This is a board-specific hardware constraint
> > + determined by the wiring of the serial audio interface.
> > + qcom,qaif-aif-slot-en-rx-mask:
> > + $ref: /schemas/types.yaml#/definitions/uint32
> > + description:
> > + Bitmask of active RX slots. Board-specific — determined by which
> > + TDM slots the codec is wired to on this board.
> > + qcom,qaif-aif-slot-en-tx-mask:
> > + $ref: /schemas/types.yaml#/definitions/uint32
> > + description:
> > + Bitmask of active TX slots. Board-specific — determined by which
> > + TDM slots the codec is wired to on this board.
> > + qcom,qaif-aif-loopback:
> > + type: boolean
> > + description: Enable loopback mode (presence enables loopback).
>
> What is this mode used for, testing ?
this is used to test/validate DMA and interface level loopback with QAIF IP.
>
> > + qcom,qaif-aif-ctrl-data-oe:
> > + type: boolean
> > + description: Enable output drive on the control/data line.
>
> will this be ever false?
Yes, as per HPG whenever there is point to point connection this has
to be false.
>
> > + qcom,qaif-aif-lane-config:
> > + $ref: /schemas/types.yaml#/definitions/uint32-matrix
> > + description:
> > + Lane configuration matrix. Each row is a pair <enable direction>
> > + for one lane starting from lane 0, up to 8 lanes. Use
> > + QAIF_AIF_LANE_ENABLE (1) or QAIF_AIF_LANE_DISABLE (0) for enable.
> > + Use QAIF_AIF_LANE_DIR_TX (0) for TX (speaker) or QAIF_AIF_LANE_DIR_RX
> > + (1) for RX (mic). TX and RX lanes should each be grouped contiguously.
> what do you mean ? can you elobrate how can you enforce this?
intention to have matrix from DT, where each rows are Lanes and in
each row, col[0] = lane enable/disable and col[1]=spkr/mic
>
> > + maxItems: 8
> > + items:
> > + items:
> > + - description: Lane enable (0 = disabled, 1 = enabled)
> > + enum: [0, 1]
> > + - description: Lane direction (0 = TX/speaker, 1 = RX/mic)
> > + enum: [0, 1]
> > + qcom,qaif-aif-full-cycle-en:
> > + type: boolean
> > + description: Enable full-cycle sync (effective in sync master mode).
> > + qcom,qaif-aif-bits-per-lane:
> > + $ref: /schemas/types.yaml#/definitions/uint32
> > + description:
> > + Number of slots per lane. The frame length is computed as
>
> bits per lane?
Yes.
>
> > + slot-width multiplied by bits-per-lane.
> > + if:
> > + properties:
> > + compatible:
> > + const: qcom,qaif-mi2s-dai
> > + then:
> > + description:
> > + MI2S interface. Sync mode and slot-enable masks are fixed by the
> > + MI2S protocol and must not be set in DT. Mono/stereo mode is
> > + determined at runtime from the stream channel count.
> > + properties:
> > + qcom,qaif-aif-sync-mode: false
> > + qcom,qaif-aif-slot-en-rx-mask: false
> > + qcom,qaif-aif-slot-en-tx-mask: false
> > + else:
> > + description:
> > + PCM or TDM interface. Sync mode and slot-enable masks are
> > + board-specific and must be provided. Mono mode does not apply.
> > + required:
> > + - qcom,qaif-aif-sync-mode
> > + - qcom,qaif-aif-slot-en-rx-mask
> > + - qcom,qaif-aif-slot-en-tx-mask
> > +
> > + required:
> > + - compatible
> > + - reg
> > + additionalProperties: false
> > +
> > +required:
> > + - compatible
> > + - reg
> > + - iommus
> do we
yes.
> > + - clocks
> > + - clock-names
> > + - interrupts
> > + - '#sound-dai-cells'
> > +
> > +additionalProperties: false
> > +
> > +examples:
> > + - |
> > + /* Shikra platform example */
> > + #include <dt-bindings/interrupt-controller/arm-gic.h>
> > + #include <dt-bindings/interrupt-controller/irq.h>
> > + #include <dt-bindings/sound/qcom,qaif.h>
> > + #include <dt-bindings/clock/qcom,shikra-audiocorecc.h>
> > + #include <dt-bindings/clock/qcom,gcc-shikra.h>
> > +
> > + qaif_cpu: audio@a000000 {
> > + compatible = "qcom,shikra-qaif-cpu";
> > + reg = <0x0 0x0a000000 0x0 0x20000>;
> > + iommus = <&apps_smmu 0x1c0 0x0>;
> > + clocks = <&gcc GCC_LPASS_CONFIG_CLK>,
> > + <&gcc GCC_LPASS_CORE_AXIM_CLK>,
> > + <&audiocorecc AUDIO_CORE_CC_AUD_DMA_CLK>,
> > + <&audiocorecc AUDIO_CORE_CC_AUD_DMA_MEM_CLK>,
> > + <&audiocorecc AUDIO_CORE_CC_BUS_CLK>,
> > + <&audiocorecc AUDIO_CORE_CC_AIF_IF0_EBIT_CLK>,
> > + <&audiocorecc AUDIO_CORE_CC_AIF_IF0_IBIT_CLK>,
> > + <&audiocorecc AUDIO_CORE_CC_AIF_IF1_EBIT_CLK>,
> > + <&audiocorecc AUDIO_CORE_CC_AIF_IF1_IBIT_CLK>,
> > + <&audiocorecc AUDIO_CORE_CC_AIF_IF2_EBIT_CLK>,
> > + <&audiocorecc AUDIO_CORE_CC_AIF_IF2_IBIT_CLK>,
> > + <&audiocorecc AUDIO_CORE_CC_AIF_IF3_EBIT_CLK>,
> > + <&audiocorecc AUDIO_CORE_CC_AIF_IF3_IBIT_CLK>,
> > + <&audiocorecc AUDIO_CORE_CC_EXT_MCLKA_OUT_CLK>,
> > + <&audiocorecc AUDIO_CORE_CC_EXT_MCLKB_OUT_CLK>;
> > + clock-names = "lpass_config_clk",
> > + "lpass_core_axim_clk",
> > + "aud_dma_clk",
> > + "aud_dma_mem_clk",
> > + "bus_clk",
> > + "aif_if0_ebit_clk",
> > + "aif_if0_ibit_clk",
> > + "aif_if1_ebit_clk",
> > + "aif_if1_ibit_clk",
> > + "aif_if2_ebit_clk",
> > + "aif_if2_ibit_clk",
> > + "aif_if3_ebit_clk",
> > + "aif_if3_ibit_clk",
> > + "ext_mclka_clk",
> > + "ext_mclkb_clk";
> > + #sound-dai-cells = <1>;
> > + #address-cells = <1>;
> > + #size-cells = <0>;
> > + interrupts = <GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH>;
> > + status = "okay";
> > +
> > + qaif_aif_if2: aif-interface@2 {
> > + compatible = "qcom,qaif-tdm-dai";
> > + reg = <QAIF_MI2S_TDM_AIF2>;
> > + qcom,qaif-aif-sync-mode = <QAIF_AIF_SYNC_MODE_LONG>;
> > + qcom,qaif-aif-sync-src = <QAIF_AIF_SYNC_SRC_MASTER>;
> > + qcom,qaif-aif-sync-delay = <1>;
> > + qcom,qaif-aif-slot-width-rx = <32>;
> > + qcom,qaif-aif-slot-width-tx = <32>;
> > + qcom,qaif-aif-slot-en-rx-mask = <0x3>;
> > + qcom,qaif-aif-slot-en-tx-mask = <0x3>;
> > + qcom,qaif-aif-ctrl-data-oe;
> > + /* Lane 0: RX (mic); Lane 1: TX (speaker) */
> > + qcom,qaif-aif-lane-config = <QAIF_AIF_LANE_ENABLE QAIF_AIF_LANE_DIR_RX>,
> > + <QAIF_AIF_LANE_ENABLE QAIF_AIF_LANE_DIR_TX>;
> > + /* frame length = slot-width (32) * bits-per-lane (2) = 64 bits */
> > + qcom,qaif-aif-bits-per-lane = <2>;
> > + };
> > + };
>
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox