* Re: [PATCH 7/9] arm64: dts: qcom: hamoa: reorder csiphy power-domains for v8 CSI2-PHY
From: Bryan O'Donoghue @ 2026-06-10 12:24 UTC (permalink / raw)
To: Ramshouriesh, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Mauro Carvalho Chehab,
Bryan O'Donoghue, Vladimir Zapolskiy, Loic Poulain,
Vinod Koul, Neil Armstrong
Cc: Aleksandrs Vinarskis, linux-arm-msm, devicetree, linux-kernel,
linux-media, linux-phy
In-Reply-To: <20260610-a14-himax-hm1092-v1-7-0c9907da47ed@gmail.com>
On 10/06/2026 12:09, Ramshouriesh wrote:
> The v8 phy-qcom-mipi-csi2 binding mandates power-domain-names ordered
> "mmcx", "mx" (MMCX first)
Feels like it probably shouldn't.
strings > magic indexes. Thanks for finding.
---
bod
^ permalink raw reply
* Re: [PATCH v7 1/2] arm64: dts: qcom: sm8250: sort out Iris power domains
From: Konrad Dybcio @ 2026-06-10 12:24 UTC (permalink / raw)
To: Dmitry Baryshkov, Bjorn Andersson, Michael Turquette,
Stephen Boyd, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Taniya Das, Jonathan Marek, Rafael J. Wysocki,
Bryan O'Donoghue, Vikash Garodia, Dikshita Agarwal,
Mauro Carvalho Chehab, Stanimir Varbanov, Abhinav Kumar,
Hans Verkuil, Stefan Schmidt, Konrad Dybcio, Bryan O'Donoghue,
Dikshita Agarwal, Ulf Hansson
Cc: linux-arm-msm, linux-clk, devicetree, linux-kernel, linux-pm,
linux-media, Mauro Carvalho Chehab
In-Reply-To: <20260604-iris-venus-fix-sm8250-v7-1-7bd2f0e5bae8@oss.qualcomm.com>
On 6/4/26 6:22 PM, Dmitry Baryshkov wrote:
> On SM8250 Iris core requires two power rails to function, MX (for PLLs)
> and MMCX (for everything else). The commit fa245b3f06cd ("arm64: dts:
> qcom: sm8250: Add venus DT node") added only MX power rail, but omitted
> MMCX voltage levels.
>
> Add MMCX domain to the Iris device node.
>
> Fixes: fa245b3f06cd ("arm64: dts: qcom: sm8250: Add venus DT node")
> Reported-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
> ---
[...]
> opp-720000000 {
> opp-hz = /bits/ 64 <720000000>;
> - required-opps = <&rpmhpd_opp_low_svs>;
> + required-opps = <&rpmhpd_opp_svs>,
> + <&rpmhpd_opp_low_svs>;
So the computer tells me low_svs would be enough for PLL0 to generate 720MHz
Is there some transient dependency that bumps this to svs?
Your changelog mentions you altered this in v6, but I don't see any related
discussion
Konrad
^ permalink raw reply
* Re: [PATCH 4/9] MAINTAINERS: add entry for the Himax HM1092 sensor driver
From: Bryan O'Donoghue @ 2026-06-10 12:24 UTC (permalink / raw)
To: Ramshouriesh, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Mauro Carvalho Chehab,
Bryan O'Donoghue, Vladimir Zapolskiy, Loic Poulain,
Vinod Koul, Neil Armstrong
Cc: Aleksandrs Vinarskis, linux-arm-msm, devicetree, linux-kernel,
linux-media, linux-phy
In-Reply-To: <20260610-a14-himax-hm1092-v1-4-0c9907da47ed@gmail.com>
On 10/06/2026 12:09, Ramshouriesh wrote:
> Add a MAINTAINERS entry covering the Himax HM1092 NIR sensor driver and
> its DT binding.
>
> Signed-off-by: Ramshouriesh <rshouriesh@gmail.com>
> ---
> MAINTAINERS | 8 ++++++++
> 1 file changed, 8 insertions(+)
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index dadc54fe2bc8..ece71732e6dd 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -11643,6 +11643,14 @@ L: linux-kernel@vger.kernel.org
> S: Maintained
> F: drivers/misc/hisi_hikey_usb.c
>
> +HIMAX HM1092 SENSOR DRIVER
> +M: Ramshouriesh <rshouriesh@gmail.com>
> +L: linux-media@vger.kernel.org
> +S: Maintained
> +F: Documentation/devicetree/bindings/media/i2c/himax,hm1092.yaml
> +F: drivers/media/i2c/hm1092.c
> +F: drivers/media/i2c/hm1092_regs.h
> +
> HIMAX HX83112B TOUCHSCREEN SUPPORT
> M: Job Noorman <job@noorman.info>
> L: linux-input@vger.kernel.org
>
> --
> 2.53.0
>
Splitting this will cause checkpatch grumbles.
Squash down into the previous patch.
---
bod
^ permalink raw reply
* Re: [PATCH] arm64: dts: qcom: eliza: Add PCIe PHY and controller nodes
From: sashiko-bot @ 2026-06-10 12:23 UTC (permalink / raw)
To: Krishna Chaitanya Chundru; +Cc: conor+dt, robh, devicetree
In-Reply-To: <20260610-eliza_dt-v1-1-7bb72b75fc5b@oss.qualcomm.com>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] Missing `msi-map` device tree property in PCIe controller nodes.
--
commit 0646a5585317fe9881a2b5cfe976f1ab1485cf3c
Author: Krishna Chaitanya Chundru <krishna.chundru@oss.qualcomm.com>
arm64: dts: qcom: eliza: Add PCIe PHY and controller nodes
This commit adds the PCIe controller and PHY nodes for the two PCIe instances
on the Eliza platform, and updates the GCC clock references to use the new
PHY nodes.
> diff --git a/arch/arm64/boot/dts/qcom/eliza.dtsi b/arch/arm64/boot/dts/qcom/eliza.dtsi
> index 4a7a0ac40ce62..c4f0923710bbb 100644
> --- a/arch/arm64/boot/dts/qcom/eliza.dtsi
> +++ b/arch/arm64/boot/dts/qcom/eliza.dtsi
[ ... ]
> @@ -716,6 +716,361 @@ mmss_noc: interconnect@1780000 {
> #interconnect-cells = <2>;
> };
>
> + pcie0: pcie@1c00000 {
> + device_type = "pci";
> + compatible = "qcom,eliza-pcie", "qcom,pcie-sm8550";
> + reg = <0 0x01c00000 0 0x3000>,
[ ... ]
> + operating-points-v2 = <&pcie0_opp_table>;
> +
> + iommu-map = <0 &apps_smmu 0x1480 0x1>,
> + <0x100 &apps_smmu 0x1481 0x1>;
> +
> + interrupt-map = <0 0 0 1 &intc 0 0 0 564 IRQ_TYPE_LEVEL_HIGH>,
> + <0 0 0 2 &intc 0 0 0 565 IRQ_TYPE_LEVEL_HIGH>,
> + <0 0 0 3 &intc 0 0 0 566 IRQ_TYPE_LEVEL_HIGH>,
> + <0 0 0 4 &intc 0 0 0 567 IRQ_TYPE_LEVEL_HIGH>;
> + interrupt-map-mask = <0 0 0 0x7>;
> + #interrupt-cells = <1>;
> +
> + linux,pci-domain = <0>;
[Severity: High]
Should this node include the msi-map property?
Without an msi-map property to map PCIe Requester IDs to GIC ITS Device IDs,
the generic PCI device tree parsing code will fail to assign an MSI domain
to the PCIe bus. This prevents MSI and MSI-X operation for all downstream
devices, forcing a fallback to legacy INTx. The property is also required by
the qcom,pcie-common.yaml binding.
[ ... ]
> + pcie1: pcie@1c08000 {
> + device_type = "pci";
> + compatible = "qcom,eliza-pcie", "qcom,pcie-sm8550";
> + reg = <0 0x01c08000 0 0x3000>,
[ ... ]
> + operating-points-v2 = <&pcie1_opp_table>;
> +
> + iommu-map = <0 &apps_smmu 0x1400 0x1>,
> + <0x100 &apps_smmu 0x1401 0x1>;
> +
> + interrupt-map = <0 0 0 1 &intc 0 0 0 149 IRQ_TYPE_LEVEL_HIGH>,
> + <0 0 0 2 &intc 0 0 0 150 IRQ_TYPE_LEVEL_HIGH>,
> + <0 0 0 3 &intc 0 0 0 151 IRQ_TYPE_LEVEL_HIGH>,
> + <0 0 0 4 &intc 0 0 0 152 IRQ_TYPE_LEVEL_HIGH>;
> + interrupt-map-mask = <0 0 0 0x7>;
> + #interrupt-cells = <1>;
> +
> + linux,pci-domain = <1>;
[Severity: High]
Is the msi-map property also missing for the pcie1 controller node?
As with pcie0 above, omitting the msi-map property prevents MSI/MSI-X
capabilities from being properly established for downstream devices.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260610-eliza_dt-v1-1-7bb72b75fc5b@oss.qualcomm.com?part=1
^ permalink raw reply
* Re: [PATCH 2/9] media: dt-bindings: Add Himax HM1092 NIR sensor
From: Bryan O'Donoghue @ 2026-06-10 12:21 UTC (permalink / raw)
To: Ramshouriesh, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Mauro Carvalho Chehab,
Bryan O'Donoghue, Vladimir Zapolskiy, Loic Poulain,
Vinod Koul, Neil Armstrong
Cc: Aleksandrs Vinarskis, linux-arm-msm, devicetree, linux-kernel,
linux-media, linux-phy
In-Reply-To: <20260610-a14-himax-hm1092-v1-2-0c9907da47ed@gmail.com>
On 10/06/2026 12:09, Ramshouriesh wrote:
> Add a dt-binding schema for the Himax HM1092 1MP monochrome
> near-infrared CMOS sensor, used as the face-authentication IR camera on
> Snapdragon X laptops such as the ASUS Zenbook A14. The sensor streams
> 10-bit RAW over 1 or 2 MIPI CSI-2 data lanes.
>
> The optional generic "leds" property (video-interface-devices.yaml)
> associates an IR illuminator flash LED with the sensor, which the
> driver strobes while streaming.
>
> Signed-off-by: Ramshouriesh <rshouriesh@gmail.com>
Firstname/lastname ?
> ---
> .../bindings/media/i2c/himax,hm1092.yaml | 118 +++++++++++++++++++++
> 1 file changed, 118 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/media/i2c/himax,hm1092.yaml b/Documentation/devicetree/bindings/media/i2c/himax,hm1092.yaml
> new file mode 100644
> index 000000000000..085001493a20
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/media/i2c/himax,hm1092.yaml
> @@ -0,0 +1,118 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/media/i2c/himax,hm1092.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Himax HM1092 Monochrome NIR Sensor
> +
> +maintainers:
> + - Ramshouriesh <rshouriesh@gmail.com>
> +
> +description:
> + The Himax HM1092 is a 1 megapixel monochrome near-infrared CMOS image
> + sensor with a MIPI CSI-2 interface, commonly used as the IR camera for
> + face authentication on laptops. It supports 10 bit RAW output at
> + 1288x728 over 1 or 2 CSI-2 data lanes. An optional infrared
> + illuminator LED may be associated with the sensor through the generic
> + "leds" property; the driver strobes it while the sensor is streaming
> + so the scene stays lit for IR capture.
> +
> +allOf:
> + - $ref: /schemas/media/video-interface-devices.yaml#
> +
> +properties:
> + compatible:
> + const: himax,hm1092
> +
> + reg:
> + maxItems: 1
> +
> + clocks:
> + maxItems: 1
> +
> + avdd-supply:
> + description: Analogue circuit voltage supply.
> +
> + dovdd-supply:
> + description: I/O circuit voltage supply.
> +
> + dvdd-supply:
> + description: Digital circuit voltage supply.
> +
> + reset-gpios:
> + maxItems: 1
> + description: Active low GPIO connected to the XSHUTDOWN pad.
> +
> + leds:
> + description:
> + Optional phandle to an infrared illuminator flash LED strobed by
> + the driver while streaming.
> +
> + port:
> + $ref: /schemas/graph.yaml#/$defs/port-base
> + additionalProperties: false
> +
> + properties:
> + endpoint:
> + $ref: /schemas/media/video-interfaces.yaml#
> + additionalProperties: false
> +
> + properties:
> + data-lanes:
> + minItems: 1
> + maxItems: 2
> + link-frequencies: true
> + remote-endpoint: true
> +
> + required:
> + - data-lanes
> + - link-frequencies
> + - remote-endpoint
> +
> +required:
> + - compatible
> + - reg
> + - clocks
> + - port
> +
> +unevaluatedProperties: false
> +
> +examples:
> + - |
> + #include <dt-bindings/gpio/gpio.h>
> +
> + i2c {
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + camera@24 {
> + compatible = "himax,hm1092";
> + reg = <0x24>;
> +
> + reset-gpios = <&tlmm 109 GPIO_ACTIVE_LOW>;
> + pinctrl-names = "default";
> + pinctrl-0 = <&cam_ir_default>;
> +
> + clocks = <&camcc 1>;
> + assigned-clocks = <&camcc 1>;
> + assigned-clock-rates = <24000000>;
> +
> + orientation = <0>;
> +
> + leds = <&ir_flash>;
> +
> + avdd-supply = <&vreg_l7m_2p9>;
> + dvdd-supply = <&vreg_l7m_2p9>;
> + dovdd-supply = <&vreg_l4m_1p8>;
> +
> + port {
> + hm1092_ep: endpoint {
> + data-lanes = <1>;
You probably mean data-lanes = <1 2> here no ?
> + link-frequencies = /bits/ 64 <400000000>;
> + remote-endpoint = <&camss_csiphy0_inep>;
> + };
> + };
> + };
> + };
> +...
>
> --
> 2.53.0
>
---
bod
^ permalink raw reply
* Re: [PATCH v7 1/2] arm64: dts: qcom: sm8250: sort out Iris power domains
From: Konrad Dybcio @ 2026-06-10 12:20 UTC (permalink / raw)
To: Vishnu Reddy, Dmitry Baryshkov, Bjorn Andersson,
Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Taniya Das, Jonathan Marek, Rafael J. Wysocki,
Bryan O'Donoghue, Vikash Garodia, Dikshita Agarwal,
Mauro Carvalho Chehab, Stanimir Varbanov, Abhinav Kumar,
Hans Verkuil, Stefan Schmidt, Konrad Dybcio, Bryan O'Donoghue,
Dikshita Agarwal, Ulf Hansson
Cc: linux-arm-msm, linux-clk, devicetree, linux-kernel, linux-pm,
linux-media, Mauro Carvalho Chehab
In-Reply-To: <400ff1d9-1d58-880c-8004-271bd7023831@oss.qualcomm.com>
On 6/9/26 8:00 AM, Vishnu Reddy wrote:
>
> On 6/4/2026 9:52 PM, Dmitry Baryshkov wrote:
>> On SM8250 Iris core requires two power rails to function, MX (for PLLs)
>> and MMCX (for everything else). The commit fa245b3f06cd ("arm64: dts:
>> qcom: sm8250: Add venus DT node") added only MX power rail, but omitted
>> MMCX voltage levels.
>>
>> Add MMCX domain to the Iris device node.
>>
>> Fixes: fa245b3f06cd ("arm64: dts: qcom: sm8250: Add venus DT node")
>> Reported-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
>> ---
>> arch/arm64/boot/dts/qcom/sm8250.dtsi | 20 ++++++++++++++------
>> 1 file changed, 14 insertions(+), 6 deletions(-)
>>
>> diff --git a/arch/arm64/boot/dts/qcom/sm8250.dtsi b/arch/arm64/boot/dts/qcom/sm8250.dtsi
>> index 7076720413ab..6150380795b8 100644
>> --- a/arch/arm64/boot/dts/qcom/sm8250.dtsi
>> +++ b/arch/arm64/boot/dts/qcom/sm8250.dtsi
>> @@ -4326,8 +4326,12 @@ venus: video-codec@aa00000 {
>> interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
>> power-domains = <&videocc MVS0C_GDSC>,
>> <&videocc MVS0_GDSC>,
>> - <&rpmhpd RPMHPD_MX>;
>> - power-domain-names = "venus", "vcodec0", "mx";
>> + <&rpmhpd RPMHPD_MX>,
>> + <&rpmhpd RPMHPD_MMCX>;
>> + power-domain-names = "venus",
>> + "vcodec0",
>> + "mx",
>> + "mmcx";
>
> With this change in place, the backwards compatibility for the incomplete
> SM8250 ABI which was merged from v5 in this series, which handles the return
> value of devm_pm_domain_attach_list(), will never be hit right? If so, we can
> remove that piece of code from the driver.
The point of backwards compatibility is that we can never assume
that the user has updated the DT (because e.g. it may be embedded in
the bootloader)
Konrad
^ permalink raw reply
* [PATCH v5 3/3] spi: dt-bindings: nuvoton,npcm750-fiu: Convert to DT schema
From: Tomer Maimon @ 2026-06-10 12:18 UTC (permalink / raw)
To: andrew, broonie, robh, krzk+dt, conor+dt
Cc: openbmc, linux-spi, devicetree, linux-kernel, avifishman70,
tmaimon77, tali.perry1, venture, yuenn, benjaminfair,
Krzysztof Kozlowski
In-Reply-To: <20260610121822.2524634-1-tmaimon77@gmail.com>
Convert the Nuvoton NPCM FIU binding to DT schema format.
Document the required control registers and the optional direct-
mapped flash window separately, matching the driver behavior
when the direct mapping is not described.
Signed-off-by: Tomer Maimon <tmaimon77@gmail.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
---
.../bindings/spi/nuvoton,npcm-fiu.txt | 58 ------------
.../bindings/spi/nuvoton,npcm750-fiu.yaml | 93 +++++++++++++++++++
2 files changed, 93 insertions(+), 58 deletions(-)
delete mode 100644 Documentation/devicetree/bindings/spi/nuvoton,npcm-fiu.txt
create mode 100644 Documentation/devicetree/bindings/spi/nuvoton,npcm750-fiu.yaml
diff --git a/Documentation/devicetree/bindings/spi/nuvoton,npcm-fiu.txt b/Documentation/devicetree/bindings/spi/nuvoton,npcm-fiu.txt
deleted file mode 100644
index fb38e96d395f..000000000000
--- a/Documentation/devicetree/bindings/spi/nuvoton,npcm-fiu.txt
+++ /dev/null
@@ -1,58 +0,0 @@
-* Nuvoton FLASH Interface Unit (FIU) SPI Controller
-
-NPCM FIU supports single, dual and quad communication interface.
-
-The NPCM7XX supports three FIU modules,
-FIU0 and FIUx supports two chip selects,
-FIU3 support four chip select.
-
-The NPCM8XX supports four FIU modules,
-FIU0 and FIUx supports two chip selects,
-FIU1 and FIU3 supports four chip selects.
-
-Required properties:
- - compatible : "nuvoton,npcm750-fiu" for Poleg NPCM7XX BMC
- "nuvoton,npcm845-fiu" for Arbel NPCM8XX BMC
- - #address-cells : should be 1.
- - #size-cells : should be 0.
- - reg : the first contains the register location and length,
- the second contains the memory mapping address and length
- - reg-names: Should contain the reg names "control" and "memory"
- - clocks : phandle of FIU reference clock.
-
-Required properties in case the pins can be muxed:
- - pinctrl-names : a pinctrl state named "default" must be defined.
- - pinctrl-0 : phandle referencing pin configuration of the device.
-
-Optional property:
- - nuvoton,spix-mode: enable spix-mode for an expansion bus to an ASIC or CPLD.
-
-Aliases:
-- All the FIU controller nodes should be represented in the aliases node using
- the following format 'fiu{n}' where n is a unique number for the alias.
- In the NPCM7XX BMC:
- fiu0 represent fiu 0 controller
- fiu1 represent fiu 3 controller
- fiu2 represent fiu x controller
-
- In the NPCM8XX BMC:
- fiu0 represent fiu 0 controller
- fiu1 represent fiu 1 controller
- fiu2 represent fiu 3 controller
- fiu3 represent fiu x controller
-
-Example:
-fiu3: spi@c00000000 {
- compatible = "nuvoton,npcm750-fiu";
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <0xfb000000 0x1000>, <0x80000000 0x10000000>;
- reg-names = "control", "memory";
- clocks = <&clk NPCM7XX_CLK_AHB>;
- pinctrl-names = "default";
- pinctrl-0 = <&spi3_pins>;
- flash@0 {
- ...
- };
-};
-
diff --git a/Documentation/devicetree/bindings/spi/nuvoton,npcm750-fiu.yaml b/Documentation/devicetree/bindings/spi/nuvoton,npcm750-fiu.yaml
new file mode 100644
index 000000000000..965904a98785
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/nuvoton,npcm750-fiu.yaml
@@ -0,0 +1,93 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/spi/nuvoton,npcm750-fiu.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Nuvoton NPCM Flash Interface Unit (FIU) SPI Controller
+
+maintainers:
+ - Tomer Maimon <tmaimon77@gmail.com>
+
+allOf:
+ - $ref: /schemas/spi/spi-controller.yaml#
+
+description: |
+ NPCM FIU supports single, dual and quad communication interface.
+
+ The NPCM7XX supports three FIU modules:
+ FIU0 and FIUx support two chip selects
+ FIU3 supports four chip selects.
+
+ The NPCM8XX supports four FIU modules:
+ FIU0 and FIUx support two chip selects
+ FIU1 and FIU3 support four chip selects.
+
+ The FIU control register block is always required. The direct-mapped
+ flash window is optional because the controller can still access flash
+ through the UMA path when that mapping is not described.
+
+ Alias convention:
+ The '/aliases' node should define:
+ For NPCM7xx: fiu0=&fiu0; fiu1=&fiu3; fiu2=&fiux;
+ For NPCM8xx: fiu0=&fiu0; fiu1=&fiu3; fiu2=&fiux; fiu3=&fiu1;
+
+properties:
+ compatible:
+ enum:
+ - nuvoton,npcm750-fiu # Poleg NPCM7XX
+ - nuvoton,npcm845-fiu # Arbel NPCM8XX
+
+ reg:
+ description:
+ The first resource is the FIU control register block. An optional second
+ resource describes the direct-mapped flash window used for direct
+ read/write accesses.
+ minItems: 1
+ items:
+ - description: FIU control registers
+ - description: Memory-mapped flash contents
+
+ reg-names:
+ description:
+ Resource names for the control registers and optional direct-mapped
+ flash window.
+ minItems: 1
+ items:
+ - const: control
+ - const: memory
+
+ clocks:
+ maxItems: 1
+ description: FIU reference clock.
+
+ nuvoton,spix-mode:
+ type: boolean
+ description: Enable SPIX mode for an expansion bus to an ASIC or CPLD.
+
+required:
+ - compatible
+ - reg
+ - reg-names
+ - clocks
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/nuvoton,npcm7xx-clock.h>
+ spi@fb000000 {
+ compatible = "nuvoton,npcm750-fiu";
+ reg = <0xfb000000 0x1000>, <0x80000000 0x10000000>;
+ reg-names = "control", "memory";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&clk NPCM7XX_CLK_SPI0>;
+
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+ };
--
2.34.1
^ permalink raw reply related
* [PATCH v5 2/3] arm: dts: nuvoton: npcm7xx: Drop redundant FIU clock-names
From: Tomer Maimon @ 2026-06-10 12:18 UTC (permalink / raw)
To: andrew, broonie, robh, krzk+dt, conor+dt
Cc: openbmc, linux-spi, devicetree, linux-kernel, avifishman70,
tmaimon77, tali.perry1, venture, yuenn, benjaminfair,
Krzysztof Kozlowski
In-Reply-To: <20260610121822.2524634-1-tmaimon77@gmail.com>
The NPCM7xx FIU controller nodes reference a single clock, but their
clock-names properties are not described by the FIU binding. Drop the
undocumented names so the DTS matches the binding.
Signed-off-by: Tomer Maimon <tmaimon77@gmail.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
---
arch/arm/boot/dts/nuvoton/nuvoton-common-npcm7xx.dtsi | 3 ---
1 file changed, 3 deletions(-)
diff --git a/arch/arm/boot/dts/nuvoton/nuvoton-common-npcm7xx.dtsi b/arch/arm/boot/dts/nuvoton/nuvoton-common-npcm7xx.dtsi
index a16450abea0e..83cd10b47273 100644
--- a/arch/arm/boot/dts/nuvoton/nuvoton-common-npcm7xx.dtsi
+++ b/arch/arm/boot/dts/nuvoton/nuvoton-common-npcm7xx.dtsi
@@ -193,7 +193,6 @@ fiu0: spi@fb000000 {
reg = <0xfb000000 0x1000>;
reg-names = "control";
clocks = <&clk NPCM7XX_CLK_SPI0>;
- clock-names = "clk_spi0";
status = "disabled";
};
@@ -204,7 +203,6 @@ fiu3: spi@c0000000 {
reg = <0xc0000000 0x1000>;
reg-names = "control";
clocks = <&clk NPCM7XX_CLK_SPI3>;
- clock-names = "clk_spi3";
pinctrl-names = "default";
pinctrl-0 = <&spi3_pins>;
status = "disabled";
@@ -217,7 +215,6 @@ fiux: spi@fb001000 {
reg = <0xfb001000 0x1000>;
reg-names = "control";
clocks = <&clk NPCM7XX_CLK_SPIX>;
- clock-names = "clk_spix";
status = "disabled";
};
--
2.34.1
^ permalink raw reply related
* [PATCH v5 1/3] arm: dts: nuvoton: npcm7xx: Drop bogus FIU memory reg-names
From: Tomer Maimon @ 2026-06-10 12:18 UTC (permalink / raw)
To: andrew, broonie, robh, krzk+dt, conor+dt
Cc: openbmc, linux-spi, devicetree, linux-kernel, avifishman70,
tmaimon77, tali.perry1, venture, yuenn, benjaminfair,
Krzysztof Kozlowski
In-Reply-To: <20260610121822.2524634-1-tmaimon77@gmail.com>
The NPCM7xx FIU controller nodes only describe the control register block,
but they still advertise a second "memory" entry in reg-names. Drop the
bogus name so the DTS matches the resources actually present in each node.
Signed-off-by: Tomer Maimon <tmaimon77@gmail.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
---
arch/arm/boot/dts/nuvoton/nuvoton-common-npcm7xx.dtsi | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/arm/boot/dts/nuvoton/nuvoton-common-npcm7xx.dtsi b/arch/arm/boot/dts/nuvoton/nuvoton-common-npcm7xx.dtsi
index ab3c3c5713ae..a16450abea0e 100644
--- a/arch/arm/boot/dts/nuvoton/nuvoton-common-npcm7xx.dtsi
+++ b/arch/arm/boot/dts/nuvoton/nuvoton-common-npcm7xx.dtsi
@@ -191,7 +191,7 @@ fiu0: spi@fb000000 {
#address-cells = <1>;
#size-cells = <0>;
reg = <0xfb000000 0x1000>;
- reg-names = "control", "memory";
+ reg-names = "control";
clocks = <&clk NPCM7XX_CLK_SPI0>;
clock-names = "clk_spi0";
status = "disabled";
@@ -202,7 +202,7 @@ fiu3: spi@c0000000 {
#address-cells = <1>;
#size-cells = <0>;
reg = <0xc0000000 0x1000>;
- reg-names = "control", "memory";
+ reg-names = "control";
clocks = <&clk NPCM7XX_CLK_SPI3>;
clock-names = "clk_spi3";
pinctrl-names = "default";
@@ -215,7 +215,7 @@ fiux: spi@fb001000 {
#address-cells = <1>;
#size-cells = <0>;
reg = <0xfb001000 0x1000>;
- reg-names = "control", "memory";
+ reg-names = "control";
clocks = <&clk NPCM7XX_CLK_SPIX>;
clock-names = "clk_spix";
status = "disabled";
--
2.34.1
^ permalink raw reply related
* [PATCH v5 0/3] Nuvoton NPCM FIU DTS fixes and binding conversion
From: Tomer Maimon @ 2026-06-10 12:18 UTC (permalink / raw)
To: andrew, broonie, robh, krzk+dt, conor+dt
Cc: openbmc, linux-spi, devicetree, linux-kernel, avifishman70,
tmaimon77, tali.perry1, venture, yuenn, benjaminfair
This series fixes the in-tree NPCM7xx FIU controller nodes so their
resources match what the DTS actually describes, and converts the legacy
Nuvoton NPCM FIU binding to YAML DT schema.
Patch 1 drops the bogus "memory" entry from reg-names on the NPCM7xx FIU
nodes.
Patch 2 drops redundant clock-names from those single-clock FIU
controllers.
Patch 3 renames the schema to nuvoton,npcm750-fiu.yaml, explains why the
direct-mapped flash window is optional, keeps the requested example
ordering, and simplifies reg/reg-names to the ordered minItems form.
Changes since version 4:
- Rework patch 2 commit message to describe the DT binding rationale for
dropping the undocumented FIU clock-names properties.
- Keep the patch contents unchanged from version 4.
Changes since version 3:
- Split the DTS cleanup so the reg-names fix stands alone as patch 1.
- Added review tag to Drop bogus FIU memory reg-names commit.
Changes since version 2:
- Drop redundant FIU clock-names from the NPCM7xx DTSI together with the
bogus reg-names cleanup.
- Rename the schema to nuvoton,npcm750-fiu.yaml and keep reg/reg-names
immediately after compatible in the example.
- Explain why the direct-mapped flash window is optional and model
reg/reg-names as ordered minItems arrays.
- Drop clock-names from the schema to match the driver and updated DTS.
Changes since version 1:
- Drop interrupts property.
- Drop unused label.
- Keep reg as the second property, followed by reg-names.
Tomer Maimon (3):
arm: dts: nuvoton: npcm7xx: Drop bogus FIU memory reg-names
arm: dts: nuvoton: npcm7xx: Drop redundant FIU clock-names
spi: dt-bindings: nuvoton,npcm750-fiu: Convert to DT schema
--
2.34.1
^ permalink raw reply
* Re: [PATCH 3/4] arm64: dts: qcom: msm8996: Add VDD_MX to QUSB2 PHYs
From: sashiko-bot @ 2026-06-10 12:18 UTC (permalink / raw)
To: Konrad Dybcio
Cc: vkoul, neil.armstrong, olteanv, linux-phy, robh, conor+dt,
devicetree
In-Reply-To: <20260610-topic-8996_61x5_qusb2phy-v1-3-d7135980e78f@oss.qualcomm.com>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] Adding the VDD_MX power domain interacts brokenly with the PHY driver's runtime PM implementation, permanently pinning the VDD_MX power rail and causing a severe battery drain regression during system idle.
--
commit f3735b6dfcc42f0f55443d0f81c7b256532b0e25
Author: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
arm64: dts: qcom: msm8996: Add VDD_MX to QUSB2 PHYs
This commit adds the VDD_MX power rail description to the QUSB2 PHYs in the
msm8996 device tree. It explicitly sets the power domain and required OPPs
for both primary and secondary PHY nodes.
> diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi
> index 2f67e665996f3..b7cd1928335c8 100644
> --- a/arch/arm64/boot/dts/qcom/msm8996.dtsi
> +++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi
> @@ -3192,7 +3192,12 @@ hsusb_phy1: phy@7411000 {
> clock-names = "cfg_ahb", "ref";
>
> resets = <&gcc GCC_QUSB2PHY_PRIM_BCR>;
> +
> + power-domains = <&rpmpd MSM8996_VDDMX>;
> + required-opps = <&rpmpd_opp4>;
[Severity: High]
Does adding this power domain permanently pin the VDD_MX rail?
Looking at the driver in drivers/phy/qualcomm/phy-qcom-qusb2.c,
qusb2_phy_probe() sets up runtime PM like this:
pm_runtime_set_active(dev);
pm_runtime_forbid(dev);
ret = devm_pm_runtime_enable(dev);
Because the driver forbids runtime suspend by default, the device stays
permanently active.
If we attach the PM domain and require an OPP here, won't the generic PM
domain framework apply the OPP4 performance state permanently, preventing the
SoC from scaling down its logic voltage during system idle?
> +
> nvmem-cells = <&qusb2p_hstx_trim>;
> +
> status = "disabled";
> };
>
> @@ -3206,7 +3211,12 @@ hsusb_phy2: phy@7412000 {
> clock-names = "cfg_ahb", "ref";
>
> resets = <&gcc GCC_QUSB2PHY_SEC_BCR>;
> +
> + power-domains = <&rpmpd MSM8996_VDDMX>;
> + required-opps = <&rpmpd_opp4>;
> +
> nvmem-cells = <&qusb2s_hstx_trim>;
> +
> status = "disabled";
> };
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260610-topic-8996_61x5_qusb2phy-v1-0-d7135980e78f@oss.qualcomm.com?part=3
^ permalink raw reply
* Re: [PATCH 6/9] arm64: dts/media: qcom: keep PLL8 out of Purwa camss hot path
From: Krzysztof Kozlowski @ 2026-06-10 12:13 UTC (permalink / raw)
To: Ramshouriesh, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Mauro Carvalho Chehab,
Bryan O'Donoghue, Vladimir Zapolskiy, Loic Poulain,
Bryan O'Donoghue, Vinod Koul, Neil Armstrong
Cc: Aleksandrs Vinarskis, linux-arm-msm, devicetree, linux-kernel,
linux-media, linux-phy
In-Reply-To: <20260610-a14-himax-hm1092-v1-6-0c9907da47ed@gmail.com>
On 10/06/2026 13:09, Ramshouriesh wrote:
> cam_cc_pll8 (defined in camcc-x1e80100.c) doesn't latch on Purwa
> silicon. "Lucid PLL latch failed. Output may be unstable!" fires from
> wait_for_pll() whenever something asks for a PLL8-sourced rate, and
> the camera pipeline ends up dead with "Failed to start media
> pipeline: -32" even after the qcom,x1p42100-camss compatible is in
> place.
>
> PLL8 sneaks into the streaming path via two RCG freq tables: the
> slow_ahb RCG defaults to its 64 MHz entry (PLL8-sourced) when CSID
> pulls it during csid_set_power, and vfe_lite picks its highest entry
> (480 MHz, also PLL8) at streamon.
>
> Fix this from the DT side:
>
> * pin slow_ahb at 80 MHz via assigned-clock-rates in purwa.dtsi so
> the RCG is reprogrammed to PLL0_OUT_EVEN at clk-init time and
> never reaches PLL8;
> * drop the 480 MHz entry from the Purwa vfe_lite clock_rate array
> so the driver caps at 400 MHz (PLL0_OUT_ODD).
>
> I went poking at the Qualcomm Windows BSP shipped for the UX3407QA to
> see what rates the vendor side actually uses. The AeoB resource blob
> at qccamplatform_ext8380/CAMP_{PERF,RES}_MTP.bin lists the camera
> clocks Windows enables, and PLL8 isn't referenced once. For CCI in
> particular Windows runs at 37.5 MHz off PLL0_OUT_EVEN, not the
> 30 MHz/PLL8 alternative the Linux driver happens to pick first.
> Whether PLL8 is fused off, trust-zone-only, or just unwired on this
> SoC I don't know, but treating it as unavailable matches what the
> vendor does.
>
> Signed-off-by: Ramshouriesh <rshouriesh@gmail.com>
> ---
> arch/arm64/boot/dts/qcom/purwa.dtsi | 12 ++++++++++++
> drivers/media/platform/qcom/camss/camss.c | 16 ++++++++--------
You cannot combine such changes. DTS must be separate, see submitting
patches in DT, DTS coding style, SoC maintainer profile...
Best regards,
Krzysztof
^ permalink raw reply
* Re: [PATCH v5 5/5] iio: adc: versal-sysmon: add oversampling support
From: Erim, Salih @ 2026-06-10 12:12 UTC (permalink / raw)
To: Andy Shevchenko
Cc: jic23, andy, dlechner, nuno.sa, robh, krzk+dt, conor+dt,
conall.ogriofa, michal.simek, linux, erimsalih, linux-iio,
devicetree, linux-kernel
In-Reply-To: <aihUJ9D7BAQd6iGZ@ashevche-desk.local>
Hi Andy,
On 09/06/2026 18:57, Andy Shevchenko wrote:
> On Mon, Jun 08, 2026 at 07:38:01PM +0100, Salih Erim wrote:
>> Add support for reading and writing the oversampling ratio through
>> the IIO oversampling_ratio attribute. The hardware supports averaging
>> 2, 4, 8, or 16 samples, plus a ratio of 1 (no averaging).
>>
>> Temperature and supply channels share oversampling configuration at
>> the type level (all temperature channels share one ratio, all supply
>> channels share another), exposed through info_mask_shared_by_type.
>>
>> The hardware encoding uses sample_count / 2 in a 4-bit field within
>> the CONFIG register. Per-channel averaging enable registers must also
>> be updated to activate or deactivate averaging.
>
> ...
>
>> +static int sysmon_osr_write(struct sysmon *sysmon, int channel_type, int val)
>> +{
>> + /*
>> + * HW register encoding is sample_count / 2:
>> + * 0=none, 1=2x, 2=4x, 4=8x, 8=16x (not log2-based).
>> + */
>> + int hw_val = val >> 1;
>> + unsigned int readback;
>> + int ret;
>> +
>> + switch (channel_type) {
>> + case IIO_TEMP:
>> + ret = regmap_update_bits(sysmon->regmap, SYSMON_CONFIG,
>> + SYSMON_CONFIG_TEMP_SAT_OSR,
>> + FIELD_PREP(SYSMON_CONFIG_TEMP_SAT_OSR,
>> + hw_val));
>
> Broken indentation.
Accepted. Sorry for all.
>
>
>> + if (ret)
>> + return ret;
>> +
>> + /*
>> + * Readback fence: the SysMon CONFIG register resides in the
>> + * PMC domain behind the NoC. A posted write may not reach the
>> + * hardware before the next MMIO access. Reading the register
>> + * back forces the interconnect to complete the write, preventing
>> + * a bus hang on the subsequent access.
>> + */
>> + regmap_read(sysmon->regmap, SYSMON_CONFIG, &readback);
>> +
>> + return sysmon_set_avg_enable(sysmon, SYSMON_TEMP_EN_AVG_BASE,
>> + SYSMON_TEMP_EN_AVG_COUNT,
>> + hw_val ? ~0U : 0);
>> + case IIO_VOLTAGE:
>> + ret = regmap_update_bits(sysmon->regmap, SYSMON_CONFIG,
>> + SYSMON_CONFIG_SUPPLY_OSR,
>> + FIELD_PREP(SYSMON_CONFIG_SUPPLY_OSR,
>> + hw_val));
>
> Ditto.
Accepted.
>
>> + if (ret)
>> + return ret;
>> +
>> + /* Readback fence -- see above */
>> + regmap_read(sysmon->regmap, SYSMON_CONFIG, &readback);
>> +
>> + return sysmon_set_avg_enable(sysmon, SYSMON_SUPPLY_EN_AVG_BASE,
>> + SYSMON_SUPPLY_EN_AVG_COUNT,
>> + hw_val ? ~0U : 0);
>> + default:
>> + return -EINVAL;
>> + }
>> +}
>
> ...
>
>> +static int sysmon_write_raw(struct iio_dev *indio_dev,
>> + struct iio_chan_spec const *chan,
>> + int val, int val2, long mask)
>> +{
>> + struct sysmon *sysmon = iio_priv(indio_dev);
>> + int i, ret;
>
> Why is 'i' signed?
No reason. Will change to unsigned int.
Thanks,
Salih.
>
>> +
>> + if (mask != IIO_CHAN_INFO_OVERSAMPLING_RATIO)
>> + return -EINVAL;
>> +
>> + for (i = 0; i < ARRAY_SIZE(sysmon_oversampling_avail); i++) {
>> + if (val == sysmon_oversampling_avail[i])
>> + break;
>> + }
>> + if (i == ARRAY_SIZE(sysmon_oversampling_avail))
>> + return -EINVAL;
>> +
>> + guard(mutex)(&sysmon->lock);
>> +
>> + ret = sysmon_osr_write(sysmon, chan->type, val);
>> + if (ret)
>> + return ret;
>> +
>> + if (chan->type == IIO_TEMP)
>> + sysmon->temp_oversampling = val;
>> + else
>> + sysmon->supply_oversampling = val;
>> +
>> + return 0;
>> +}
>
> --
> With Best Regards,
> Andy Shevchenko
>
>
^ permalink raw reply
* Re: [PATCH 2/4] dt-bindings: arm: qcom: Add Lenovo Yoga Slim 7x Gen11
From: Konrad Dybcio @ 2026-06-10 12:12 UTC (permalink / raw)
To: Krzysztof Kozlowski, rob.clark
Cc: Neil Armstrong, Jessica Zhang, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Douglas Anderson,
Bjorn Andersson, Konrad Dybcio, dri-devel, devicetree,
linux-kernel, linux-arm-msm
In-Reply-To: <799fea04-e7d0-4184-b9ae-4cebfdac38d5@kernel.org>
On 6/4/26 5:18 PM, Krzysztof Kozlowski wrote:
> On 04/06/2026 17:13, Rob Clark wrote:
>> On Thu, Jun 4, 2026 at 8:09 AM Krzysztof Kozlowski <krzk@kernel.org> wrote:
>>>
>>> On 04/06/2026 10:06, Konrad Dybcio wrote:
>>>> The Yoga Slim 7x Gen11 is a Snapdragon X2 Elite-based 14" laptop from
>>>> Lenovo, featuring an OLED touch panel. Add a compatible for it.
>>>>
>>>> According to the spec page [1], there also exist other variations
>>>> (based on the Mahua SoC and/or with a different type of display panel),
>>>> but those are to be described separately
>>>>
>>>> [1] https://psref.lenovo.com/Product/Yoga_Slim_7_14Q8Y11?tab=spec
>>>> Signed-off-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
>>>> ---
>>>> Documentation/devicetree/bindings/arm/qcom.yaml | 1 +
>>>> 1 file changed, 1 insertion(+)
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/arm/qcom.yaml b/Documentation/devicetree/bindings/arm/qcom.yaml
>>>> index 50cc18a6ec5eddaf48542b85387c2d430cd4721a..fca3d180489d4cd3eb2726a722f15febe44f03ad 100644
>>>> --- a/Documentation/devicetree/bindings/arm/qcom.yaml
>>>> +++ b/Documentation/devicetree/bindings/arm/qcom.yaml
>>>> @@ -68,6 +68,7 @@ properties:
>>>>
>>>> - items:
>>>> - enum:
>>>> + - lenovo,yoga-slim7x-gen11
>>>
>>> I imagine you might want different panel variants, just like T14s has
>>> LCD and OLED?
>>
>> I expect this will be the case.
>
> Then better to prepare for this now, otherwise later you need to change
> bindings. If unsure what other variants are, then at least make this
> compatible panel-specific, e.g. lenovo,yoga-slim7x-gen11-oled-foo-bar.
I took another look at psref [1] and there's only OLED SKUs (today?).
There are however, two different resolutions available and both can be
touch/notouch.
I don't know what this will entail - if the panels are both samsung, I
would guesstimate the same driver works for them (and Doug was against
adding new compatibles [2]).
There's also different SoCs (which will need another #include in DT to
override, sorta like hamoa and purwa models; they seem not to be
available in the store rn, but I'd assume it's fine to just rely on the
SoC strings in the compatible chain to differentiate them.
Konrad
[1] https://psref.lenovo.com/l/Product/Yoga/Yoga_Slim_7_14Q8Y11?tab=spec
[2] https://lore.kernel.org/linux-arm-msm/CAD=FV=XBn78eOC_zG0S2U-W3whrVYEpghKF_WgX+3zpUJ82-5g@mail.gmail.com/
^ permalink raw reply
* Re: [PATCH 3/9] media: i2c: hm1092: add Himax HM1092 mono NIR sensor driver
From: Bryan O'Donoghue @ 2026-06-10 12:11 UTC (permalink / raw)
To: Ramshouriesh, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Mauro Carvalho Chehab,
Bryan O'Donoghue, Vladimir Zapolskiy, Loic Poulain,
Vinod Koul, Neil Armstrong
Cc: Aleksandrs Vinarskis, linux-arm-msm, devicetree, linux-kernel,
linux-media, linux-phy
In-Reply-To: <20260610-a14-himax-hm1092-v1-3-0c9907da47ed@gmail.com>
On 10/06/2026 12:09, Ramshouriesh wrote:
> Add a v4l2 subdev driver for the Himax HM1092 monochrome near-IR sensor,
> used as the Windows-Hello IR camera on the ASUS Zenbook A14.
>
> The driver also drives the IR illuminator (a PM8550 flash LED referenced
> through the generic "leds" property): while streaming it strobes the
> illuminator at ~10 Hz, lighting the capture while keeping the average IR
> LED power down.
Drop references to PM8550 as its a qcomism and this is a i2c sensor.
>
> Signed-off-by: Ramshouriesh <rshouriesh@gmail.com>
And I think you can/should reference a series where this driver is used
but split the driver submission itself from the SoC/platform specific.
You want to target Sakari's tree - land the driver then enable the
platform code on top, so structure your patchworking around that strategy.
> ---
> drivers/media/i2c/Kconfig | 14 +
> drivers/media/i2c/Makefile | 1 +
> drivers/media/i2c/hm1092.c | 685 ++++++++++++++++++++++++++++++++++++++++
> drivers/media/i2c/hm1092_regs.h | 223 +++++++++++++
> 4 files changed, 923 insertions(+)
>
> diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
> index 5d173e0ecf42..8ee3ee15e9df 100644
> --- a/drivers/media/i2c/Kconfig
> +++ b/drivers/media/i2c/Kconfig
> @@ -137,6 +137,20 @@ config VIDEO_HI847
> To compile this driver as a module, choose M here: the
> module will be called hi847.
>
> +config VIDEO_HM1092
> + tristate "Himax HM1092 sensor support"
> + select V4L2_CCI_I2C
> + help
> + This is a Video4Linux2 sensor driver for the Himax
> + HM1092 1MP mono IR camera used for face authentication
> + on Snapdragon X laptops (ASUS Zenbook A14 etc.).
> +
> + Register tables were reverse-engineered from the Qualcomm
> + Chromatix sensor module shipped in the Windows BSP.
Not specific to Qcom - sensor vendors target ISP vendors like Intel,
Qcom and others. You might easily say the same "this is used in IPU7"
for this sensor for all we know.
> +
> + To compile this driver as a module, choose M here: the
> + module will be called hm1092.
> +
> config VIDEO_IMX111
> tristate "Sony IMX111 sensor support"
> select V4L2_CCI_I2C
> diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
> index e45359efe0e4..6507c173d0fa 100644
> --- a/drivers/media/i2c/Makefile
> +++ b/drivers/media/i2c/Makefile
> @@ -45,6 +45,7 @@ obj-$(CONFIG_VIDEO_GC2145) += gc2145.o
> obj-$(CONFIG_VIDEO_HI556) += hi556.o
> obj-$(CONFIG_VIDEO_HI846) += hi846.o
> obj-$(CONFIG_VIDEO_HI847) += hi847.o
> +obj-$(CONFIG_VIDEO_HM1092) += hm1092.o
> obj-$(CONFIG_VIDEO_I2C) += video-i2c.o
> obj-$(CONFIG_VIDEO_IMX111) += imx111.o
> obj-$(CONFIG_VIDEO_IMX208) += imx208.o
> diff --git a/drivers/media/i2c/hm1092.c b/drivers/media/i2c/hm1092.c
> new file mode 100644
> index 000000000000..90968ee29d81
> --- /dev/null
> +++ b/drivers/media/i2c/hm1092.c
> @@ -0,0 +1,685 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Himax HM1092 image sensor driver draft.
> + *
> + * Register tables were extracted from Qualcomm Chromatix sensor module
> + * com.qti.sensormodule.hm1092.bin. Keep hm1092_regs.h next to this file, or
> + * fold the generated tables into this source before upstream submission.
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/delay.h>
> +#include <linux/gpio/consumer.h>
> +#include <linux/i2c.h>
> +#include <linux/led-class-flash.h>
> +#include <linux/leds.h>
> +#include <linux/module.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/regulator/consumer.h>
> +#include <linux/workqueue.h>
> +#include <media/v4l2-cci.h>
> +#include <media/v4l2-ctrls.h>
> +#include <media/v4l2-device.h>
> +#include <media/v4l2-fwnode.h>
> +
> +#include "hm1092_regs.h"
> +
> +#define HM1092_LINK_FREQ_400MHZ 400000000ULL
> +#define HM1092_MCLK 24000000
> +#define HM1092_BITS_PER_SAMPLE 10
> +
> +#define HM1092_REG_STREAM CCI_REG8(0x0100)
> +
> +#define HM1092_FLASH_TIMEOUT_US 50000 /* 0.05 s on per pulse */
> +#define HM1092_FLASH_REFIRE_MS 100 /* 0.1 s period -> 10 Hz blink */
> +
> +struct hm1092_mode {
> + u32 width;
> + u32 height;
> + u32 hts;
> + u32 vts;
> +};
> +
> +static const struct hm1092_mode hm1092_mode_560x360 = {
> + .width = 560,
> + .height = 360,
> + .hts = 0x0650,
> + .vts = 0x02ee,
> +};
> +
> +static const char * const hm1092_supply_names[] = {
> + "dovdd",
> + "avdd",
> + "dvdd",
> +};
> +
> +static const char * const hm1092_test_pattern_menu[] = {
> + "Disabled",
> + "Mode 1",
> + "Mode 2",
> + "Mode 3",
> + "Mode 4",
> +};
> +
> +static const s64 hm1092_link_freq_menu[] = {
> + HM1092_LINK_FREQ_400MHZ,
> +};
> +
> +struct hm1092 {
> + struct device *dev;
> + struct v4l2_subdev sd;
> + struct media_pad pad;
> + struct v4l2_ctrl_handler ctrl_handler;
> + struct regmap *regmap;
> + struct clk *img_clk;
> + struct gpio_desc *reset;
> + struct regulator_bulk_data supplies[ARRAY_SIZE(hm1092_supply_names)];
> + struct v4l2_ctrl *link_freq;
> + struct v4l2_ctrl *pixel_rate;
> + struct v4l2_ctrl *hblank;
> + struct v4l2_ctrl *vblank;
> + u8 mipi_lanes;
> +
> + /* Optional IR illuminator driven while streaming (see flash notes). */
> + struct led_classdev_flash *flash;
> + struct delayed_work flash_work;
> +};
> +
> +/*
> + * (Re)arm and fire the flash at full current. The qcom flash controller does an
> + * internal disable+enable on each strobe and the hardware safety-timeout turns
> + * the LED off on its own, so brightness/timeout must be programmed every time or
> + * the re-fire is a no-op. Re-firing well within the timeout keeps the LED lit
> + * continuously and near its (slightly declining) peak brightness.
> + */
> +static void hm1092_flash_fire(struct hm1092 *hm1092)
> +{
> + struct led_classdev_flash *flash = hm1092->flash;
> +
> + /*
> + * Release the controller's flash-current accounting first (a bare
> + * re-strobe is treated as "current still in use" and re-fires at 0 mA),
> + * then re-arm at full current and strobe.
> + */
> + led_set_flash_strobe(flash, false);
> + led_set_flash_brightness(flash, flash->brightness.max);
> + led_set_flash_timeout(flash, HM1092_FLASH_TIMEOUT_US);
> + led_set_flash_strobe(flash, true);
> +}
> +
> +static void hm1092_flash_enable(struct hm1092 *hm1092)
> +{
> + if (!hm1092->flash)
> + return;
> +
> + hm1092_flash_fire(hm1092);
> + schedule_delayed_work(&hm1092->flash_work,
> + msecs_to_jiffies(HM1092_FLASH_REFIRE_MS));
> +}
> +
> +static void hm1092_flash_disable(struct hm1092 *hm1092)
> +{
> + if (!hm1092->flash)
> + return;
> +
> + cancel_delayed_work_sync(&hm1092->flash_work);
> + led_set_flash_strobe(hm1092->flash, false);
> +}
> +
> +static void hm1092_flash_work(struct work_struct *work)
> +{
> + struct hm1092 *hm1092 =
> + container_of(to_delayed_work(work), struct hm1092, flash_work);
> +
> + hm1092_flash_fire(hm1092);
> + schedule_delayed_work(&hm1092->flash_work,
> + msecs_to_jiffies(HM1092_FLASH_REFIRE_MS));
> +}
> +
> +static inline struct hm1092 *to_hm1092(struct v4l2_subdev *sd)
> +{
> + return container_of(sd, struct hm1092, sd);
> +}
> +
> +static int hm1092_write_regs(struct hm1092 *hm1092,
> + const struct hm1092_reg *regs, unsigned int len)
> +{
> + int ret = 0;
> + unsigned int i;
reverse
xmas
tree for preference.
> +
> + for (i = 0; i < len; i++) {
> + cci_write(hm1092->regmap, CCI_REG8(regs[i].address),
> + regs[i].val, &ret);
> + if (ret)
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> +static int hm1092_set_test_pattern(struct hm1092 *hm1092, int pattern)
> +{
> + switch (pattern) {
> + case 0:
> + return hm1092_write_regs(hm1092, hm1092_test_pattern_mode0,
> + ARRAY_SIZE(hm1092_test_pattern_mode0));
> + case 1:
> + return hm1092_write_regs(hm1092, hm1092_test_pattern_mode1,
> + ARRAY_SIZE(hm1092_test_pattern_mode1));
> + case 2:
> + return hm1092_write_regs(hm1092, hm1092_test_pattern_mode2,
> + ARRAY_SIZE(hm1092_test_pattern_mode2));
> + case 3:
> + return hm1092_write_regs(hm1092, hm1092_test_pattern_mode3,
> + ARRAY_SIZE(hm1092_test_pattern_mode3));
> + case 4:
> + return hm1092_write_regs(hm1092, hm1092_test_pattern_mode4,
> + ARRAY_SIZE(hm1092_test_pattern_mode4));
> + default:
> + return -EINVAL;
> + }
> +}
> +
> +static int hm1092_set_ctrl(struct v4l2_ctrl *ctrl)
> +{
> + struct hm1092 *hm1092 = container_of(ctrl->handler, struct hm1092,
> + ctrl_handler);
> + int ret = 0;
> +
> + if (!pm_runtime_get_if_in_use(hm1092->dev))
> + return 0;
This seems strange. Like you're returning zero for an error case.
> +
> + switch (ctrl->id) {
> + case V4L2_CID_TEST_PATTERN:
> + ret = hm1092_set_test_pattern(hm1092, ctrl->val);
> + break;
> + case V4L2_CID_ANALOGUE_GAIN:
> + case V4L2_CID_EXPOSURE:
> + /* TODO: write to the sensor's exposure/gain registers once
> + * we know which Chromatix middle*Addr fields point at them.
> + */
> + ret = 0;
> + break;
> + default:
> + ret = -EINVAL;
> + break;
> + }
> +
> + pm_runtime_put(hm1092->dev);
> +
> + return ret;
> +}
> +
> +static const struct v4l2_ctrl_ops hm1092_ctrl_ops = {
> + .s_ctrl = hm1092_set_ctrl,
> +};
> +
> +static int hm1092_init_controls(struct hm1092 *hm1092)
> +{
> + struct v4l2_ctrl_handler *ctrl_hdlr = &hm1092->ctrl_handler;
> + const struct hm1092_mode *mode = &hm1092_mode_560x360;
> + struct v4l2_fwnode_device_properties props;
> + s64 hblank, pixel_rate;
> + int ret;
> +
> + v4l2_ctrl_handler_init(ctrl_hdlr, 6);
> +
> + hm1092->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr,
> + &hm1092_ctrl_ops,
> + V4L2_CID_LINK_FREQ,
> + 0, 0,
> + hm1092_link_freq_menu);
> + if (hm1092->link_freq)
> + hm1092->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
> +
> + pixel_rate = div_u64(HM1092_LINK_FREQ_400MHZ * 2 * hm1092->mipi_lanes,
> + HM1092_BITS_PER_SAMPLE);
> + hm1092->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &hm1092_ctrl_ops,
> + V4L2_CID_PIXEL_RATE, 0,
> + pixel_rate, 1, pixel_rate);
> +
> + hblank = mode->hts - mode->width;
> + hm1092->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &hm1092_ctrl_ops,
> + V4L2_CID_HBLANK, hblank, hblank, 1,
> + hblank);
> + if (hm1092->hblank)
> + hm1092->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
> +
> + hm1092->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &hm1092_ctrl_ops,
> + V4L2_CID_VBLANK,
> + mode->vts - mode->height,
> + 0xffff - mode->height, 1,
> + mode->vts - mode->height);
> + if (hm1092->vblank)
> + hm1092->vblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
> +
> + /* Mandatory controls for libcamera. Conservative defaults until we
> + * RE the exposure/gain register address layout from the Chromatix
> + * sensormodule (middleCoarseIntgTimeAddr / shortGlobalGainAddr).
> + */
> + v4l2_ctrl_new_std(ctrl_hdlr, &hm1092_ctrl_ops, V4L2_CID_ANALOGUE_GAIN,
> + 0x10, 0xff, 1, 0x10);
> + v4l2_ctrl_new_std(ctrl_hdlr, &hm1092_ctrl_ops, V4L2_CID_EXPOSURE,
> + 1, mode->vts - 4, 1, mode->vts - 4);
> +
> + v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &hm1092_ctrl_ops,
> + V4L2_CID_TEST_PATTERN,
> + ARRAY_SIZE(hm1092_test_pattern_menu) - 1,
> + 0, 0, hm1092_test_pattern_menu);
> +
> + ret = v4l2_fwnode_device_parse(hm1092->dev, &props);
> + if (ret)
> + return ret;
> +
> + v4l2_ctrl_new_fwnode_properties(ctrl_hdlr, &hm1092_ctrl_ops, &props);
> +
> + if (ctrl_hdlr->error)
> + return ctrl_hdlr->error;
> +
> + hm1092->sd.ctrl_handler = ctrl_hdlr;
> +
> + return 0;
> +}
> +
> +static void hm1092_update_pad_format(struct v4l2_mbus_framefmt *fmt)
> +{
> + fmt->width = hm1092_mode_560x360.width;
> + fmt->height = hm1092_mode_560x360.height;
> + fmt->code = MEDIA_BUS_FMT_Y10_1X10;
> + fmt->field = V4L2_FIELD_NONE;
> +}
> +
> +static int hm1092_enable_streams(struct v4l2_subdev *sd,
> + struct v4l2_subdev_state *state,
> + u32 pad, u64 streams_mask)
> +{
> + struct hm1092 *hm1092 = to_hm1092(sd);
> + int ret;
> +
> + ret = pm_runtime_resume_and_get(hm1092->dev);
> + if (ret)
> + return ret;
> +
> + ret = hm1092_write_regs(hm1092, hm1092_init_regs,
> + ARRAY_SIZE(hm1092_init_regs));
> + if (ret) {
> + dev_err(hm1092->dev, "failed to write init registers\n");
> + goto out;
> + }
> +
> + ret = __v4l2_ctrl_handler_setup(hm1092->sd.ctrl_handler);
> + if (ret)
> + goto out;
> +
> + ret = hm1092_write_regs(hm1092, hm1092_start_streaming,
> + ARRAY_SIZE(hm1092_start_streaming));
> + if (ret)
> + dev_err(hm1092->dev, "failed to start streaming\n");
> + else
> + hm1092_flash_enable(hm1092);
> +
> +out:
> + if (ret)
> + pm_runtime_put(hm1092->dev);
> +
> + return ret;
> +}
> +
> +static int hm1092_disable_streams(struct v4l2_subdev *sd,
> + struct v4l2_subdev_state *state,
> + u32 pad, u64 streams_mask)
> +{
> + struct hm1092 *hm1092 = to_hm1092(sd);
> + int ret = 0;
> +
> + hm1092_flash_disable(hm1092);
> + cci_write(hm1092->regmap, HM1092_REG_STREAM, 0, &ret);
> + pm_runtime_put(hm1092->dev);
> +
> + return ret;
> +}
> +
> +static int hm1092_set_format(struct v4l2_subdev *sd,
> + struct v4l2_subdev_state *state,
> + struct v4l2_subdev_format *fmt)
> +{
> + hm1092_update_pad_format(&fmt->format);
> + *v4l2_subdev_state_get_format(state, fmt->pad) = fmt->format;
> +
> + return 0;
> +}
> +
> +static int hm1092_enum_mbus_code(struct v4l2_subdev *sd,
> + struct v4l2_subdev_state *state,
> + struct v4l2_subdev_mbus_code_enum *code)
> +{
> + if (code->index)
> + return -EINVAL;
> +
> + code->code = MEDIA_BUS_FMT_Y10_1X10;
> +
> + return 0;
> +}
> +
> +static int hm1092_enum_frame_size(struct v4l2_subdev *sd,
> + struct v4l2_subdev_state *state,
> + struct v4l2_subdev_frame_size_enum *fse)
> +{
> + if (fse->index)
> + return -EINVAL;
> +
> + if (fse->code != MEDIA_BUS_FMT_Y10_1X10)
> + return -EINVAL;
> +
> + fse->min_width = hm1092_mode_560x360.width;
> + fse->max_width = hm1092_mode_560x360.width;
> + fse->min_height = hm1092_mode_560x360.height;
> + fse->max_height = hm1092_mode_560x360.height;
> +
> + return 0;
> +}
> +
> +static int hm1092_init_state(struct v4l2_subdev *sd,
> + struct v4l2_subdev_state *state)
> +{
> + hm1092_update_pad_format(v4l2_subdev_state_get_format(state, 0));
> +
> + return 0;
> +}
> +
> +static const struct v4l2_subdev_video_ops hm1092_video_ops = {
> + .s_stream = v4l2_subdev_s_stream_helper,
> +};
> +
> +static const struct v4l2_subdev_pad_ops hm1092_pad_ops = {
> + .set_fmt = hm1092_set_format,
> + .get_fmt = v4l2_subdev_get_fmt,
> + .enum_mbus_code = hm1092_enum_mbus_code,
> + .enum_frame_size = hm1092_enum_frame_size,
> + .enable_streams = hm1092_enable_streams,
> + .disable_streams = hm1092_disable_streams,
> +};
> +
> +static const struct v4l2_subdev_ops hm1092_subdev_ops = {
> + .video = &hm1092_video_ops,
> + .pad = &hm1092_pad_ops,
> +};
> +
> +static const struct media_entity_operations hm1092_entity_ops = {
> + .link_validate = v4l2_subdev_link_validate,
> +};
> +
> +static const struct v4l2_subdev_internal_ops hm1092_internal_ops = {
> + .init_state = hm1092_init_state,
> +};
> +
> +static int hm1092_check_hwcfg(struct hm1092 *hm1092)
> +{
> + struct v4l2_fwnode_endpoint bus_cfg = {
> + .bus_type = V4L2_MBUS_CSI2_DPHY,
> + };
> + struct device *dev = hm1092->dev;
> + struct fwnode_handle *ep, *fwnode = dev_fwnode(dev);
> + unsigned long link_freq_bitmap;
> + int ret;
> +
> + ep = fwnode_graph_get_endpoint_by_id(fwnode, 0, 0, 0);
> + if (!ep)
> + return dev_err_probe(dev, -EPROBE_DEFER,
> + "waiting for fwnode graph endpoint\n");
> +
> + ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg);
> + fwnode_handle_put(ep);
> + if (ret)
> + return dev_err_probe(dev, ret, "parsing endpoint failed\n");
> +
> + ret = v4l2_link_freq_to_bitmap(dev, bus_cfg.link_frequencies,
> + bus_cfg.nr_of_link_frequencies,
> + hm1092_link_freq_menu,
> + ARRAY_SIZE(hm1092_link_freq_menu),
> + &link_freq_bitmap);
> + if (ret)
> + goto out;
> +
> + if (bus_cfg.bus.mipi_csi2.num_data_lanes != 1 &&
> + bus_cfg.bus.mipi_csi2.num_data_lanes != 2) {
> + ret = dev_err_probe(dev, -EINVAL,
> + "unsupported CSI2 data lanes: %u\n",
> + bus_cfg.bus.mipi_csi2.num_data_lanes);
> + goto out;
> + }
You have a hard-coded init sequence - does it really support both one
and two lane mode ?
Seems unlikely.
> +
> + hm1092->mipi_lanes = bus_cfg.bus.mipi_csi2.num_data_lanes;
> +
> +out:
> + v4l2_fwnode_endpoint_free(&bus_cfg);
> + return ret;
> +}
> +
> +static int hm1092_get_pm_resources(struct hm1092 *hm1092)
> +{
> + unsigned int i;
> +
> + hm1092->reset = devm_gpiod_get_optional(hm1092->dev, "reset",
> + GPIOD_OUT_HIGH);
> + if (IS_ERR(hm1092->reset))
> + return dev_err_probe(hm1092->dev, PTR_ERR(hm1092->reset),
> + "failed to get reset gpio\n");
> +
> + for (i = 0; i < ARRAY_SIZE(hm1092_supply_names); i++)
> + hm1092->supplies[i].supply = hm1092_supply_names[i];
> +
> + return devm_regulator_bulk_get(hm1092->dev,
> + ARRAY_SIZE(hm1092_supply_names),
> + hm1092->supplies);
> +}
> +
> +static int hm1092_power_off(struct device *dev)
> +{
> + struct v4l2_subdev *sd = dev_get_drvdata(dev);
> + struct hm1092 *hm1092 = to_hm1092(sd);
> +
> + gpiod_set_value_cansleep(hm1092->reset, 1);
> + regulator_bulk_disable(ARRAY_SIZE(hm1092_supply_names),
> + hm1092->supplies);
> + clk_disable_unprepare(hm1092->img_clk);
> +
> + return 0;
> +}
> +
> +static int hm1092_power_on(struct device *dev)
> +{
> + struct v4l2_subdev *sd = dev_get_drvdata(dev);
> + struct hm1092 *hm1092 = to_hm1092(sd);
> + int ret;
> +
> + /*
> + * Sequence reverse-engineered from the Chromatix AeoB powerSetting:
> + * 1. enable all rails (~1 ms ramp per supply)
> + * 2. hold reset asserted
> + * 3. start MCLK and let the sensor clock for ~1 ms
> + * 4. release reset and wait 18 ms for the sensor to come up
> + */
> + ret = regulator_bulk_enable(ARRAY_SIZE(hm1092_supply_names),
> + hm1092->supplies);
> + if (ret)
> + return ret;
\n> + usleep_range(3000, 3500);
Your comment says 1 ms so it needs an update.
> +
> + if (hm1092->reset)
> + gpiod_set_value_cansleep(hm1092->reset, 1);
> +
> + ret = clk_prepare_enable(hm1092->img_clk);
> + if (ret) {
> + regulator_bulk_disable(ARRAY_SIZE(hm1092_supply_names),
> + hm1092->supplies);
> + return ret;
> + }
> + usleep_range(1000, 1200);
> +
> + if (hm1092->reset)
> + gpiod_set_value_cansleep(hm1092->reset, 0);
> + usleep_range(18000, 19000);
> +
> + return 0;
> +}
> +
> +static void hm1092_remove(struct i2c_client *client)
> +{
> + struct v4l2_subdev *sd = i2c_get_clientdata(client);
> + struct hm1092 *hm1092 = to_hm1092(sd);
> +
> + v4l2_async_unregister_subdev(sd);
> + v4l2_subdev_cleanup(sd);
> + media_entity_cleanup(&sd->entity);
> + v4l2_ctrl_handler_free(sd->ctrl_handler);
> + pm_runtime_disable(hm1092->dev);
> + if (!pm_runtime_status_suspended(hm1092->dev)) {
> + hm1092_power_off(hm1092->dev);
> + pm_runtime_set_suspended(hm1092->dev);
> + }
> +}
> +
> +/* Optional: grab the IR illuminator flash LED referenced by the "leds" phandle. */
> +static int hm1092_get_flash(struct hm1092 *hm1092)
> +{
> + struct led_classdev *cdev;
> +
> + cdev = devm_of_led_get_optional(hm1092->dev, 0);
> + if (IS_ERR(cdev))
> + return dev_err_probe(hm1092->dev, PTR_ERR(cdev),
> + "failed to get IR illuminator LED\n");
> + if (!cdev)
> + return 0; /* no illuminator wired; capture still works */
Does checkpatch accept a comment on a line like that ?
> +
> + if (!(cdev->flags & LED_DEV_CAP_FLASH)) {
> + dev_warn(hm1092->dev,
> + "'leds' phandle is not a flash LED; IR illuminator disabled\n");
> + return 0;
> + }
> +
> + hm1092->flash = lcdev_to_flcdev(cdev);
> + INIT_DELAYED_WORK(&hm1092->flash_work, hm1092_flash_work);
> + dev_dbg(hm1092->dev, "IR illuminator flash linked (max %u uA)\n",
> + hm1092->flash->brightness.max);
\n> + return 0;
> +}
> +
> +static int hm1092_probe(struct i2c_client *client)
> +{
> + struct hm1092 *hm1092;
> + unsigned long freq;
> + int ret;
> +
> + hm1092 = devm_kzalloc(&client->dev, sizeof(*hm1092), GFP_KERNEL);
> + if (!hm1092)
> + return -ENOMEM;
> +
> + hm1092->dev = &client->dev;
> +
> + ret = hm1092_get_flash(hm1092);
> + if (ret)
> + return ret;
> +
> + hm1092->img_clk = devm_v4l2_sensor_clk_get(hm1092->dev, NULL);
> + if (IS_ERR(hm1092->img_clk))
> + return dev_err_probe(hm1092->dev, PTR_ERR(hm1092->img_clk),
> + "failed to get imaging clock\n");
> +
> + freq = clk_get_rate(hm1092->img_clk);
> + if (freq != HM1092_MCLK)
> + return dev_err_probe(hm1092->dev, -EINVAL,
> + "external clock %lu is not supported\n",
> + freq);
if (freq != ) {
// stuff goes here
}
> +
> + v4l2_i2c_subdev_init(&hm1092->sd, client, &hm1092_subdev_ops);
> +
> + ret = hm1092_check_hwcfg(hm1092);
> + if (ret)
> + return ret;
> +
> + ret = hm1092_get_pm_resources(hm1092);
> + if (ret)
> + return ret;
> +
> + hm1092->regmap = devm_cci_regmap_init_i2c(client, 16);
> + if (IS_ERR(hm1092->regmap))
> + return PTR_ERR(hm1092->regmap);
> +
> + ret = hm1092_power_on(hm1092->dev);
> + if (ret)
> + return dev_err_probe(hm1092->dev, ret, "failed to power on\n");
> +
> + ret = hm1092_init_controls(hm1092);
> + if (ret)
> + goto err_power_off;
> +
> + hm1092->sd.internal_ops = &hm1092_internal_ops;
> + hm1092->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
> + hm1092->sd.entity.ops = &hm1092_entity_ops;
> + hm1092->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
> + hm1092->pad.flags = MEDIA_PAD_FL_SOURCE;
> + ret = media_entity_pads_init(&hm1092->sd.entity, 1, &hm1092->pad);
> + if (ret)
> + goto err_ctrls;
> +
> + hm1092->sd.state_lock = hm1092->ctrl_handler.lock;
> + ret = v4l2_subdev_init_finalize(&hm1092->sd);
> + if (ret)
> + goto err_entity;
> +
> + pm_runtime_set_active(hm1092->dev);
> + pm_runtime_enable(hm1092->dev);
> +
> + /*
> + * The HM1092 has no async sub-devices: no privacy LED, no lens, and
> + * its IR illuminator is a directly-driven led-class-flash (see
> + * hm1092_get_flash()), not a v4l2-flash subdev. Register the plain
> + * subdev rather than v4l2_async_register_subdev_sensor(), whose
> + * automatic privacy-LED lookup would otherwise reject the "leds"
> + * phandle that points at the illuminator.
> + */
> + ret = v4l2_async_register_subdev(&hm1092->sd);
> + if (ret)
> + goto err_subdev;
> +
> + pm_runtime_idle(hm1092->dev);
> + return 0;
> +
> +err_subdev:
> + pm_runtime_disable(hm1092->dev);
> + pm_runtime_set_suspended(hm1092->dev);
> + v4l2_subdev_cleanup(&hm1092->sd);
> +err_entity:
> + media_entity_cleanup(&hm1092->sd.entity);
> +err_ctrls:
> + v4l2_ctrl_handler_free(hm1092->sd.ctrl_handler);
> +err_power_off:
> + hm1092_power_off(hm1092->dev);
> +
> + return ret;
> +}
> +
> +static DEFINE_RUNTIME_DEV_PM_OPS(hm1092_pm_ops, hm1092_power_off,
> + hm1092_power_on, NULL);
> +
> +static const struct of_device_id hm1092_of_match[] = {
> + { .compatible = "himax,hm1092" },
> + { /* sentinel */ }
> +};
> +MODULE_DEVICE_TABLE(of, hm1092_of_match);
> +
> +static struct i2c_driver hm1092_i2c_driver = {
> + .driver = {
> + .name = "hm1092",
> + .pm = pm_sleep_ptr(&hm1092_pm_ops),
> + .of_match_table = hm1092_of_match,
> + },
> + .probe = hm1092_probe,
> + .remove = hm1092_remove,
> +};
> +
> +module_i2c_driver(hm1092_i2c_driver);
> +
> +MODULE_DESCRIPTION("Himax HM1092 sensor driver draft");
> +MODULE_LICENSE("GPL");
> diff --git a/drivers/media/i2c/hm1092_regs.h b/drivers/media/i2c/hm1092_regs.h
> new file mode 100644
> index 000000000000..4df2d5b49d81
> --- /dev/null
> +++ b/drivers/media/i2c/hm1092_regs.h
> @@ -0,0 +1,223 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/* HM1092 register tables extracted from Qualcomm Chromatix sensor module.
> + * Source: com.qti.sensormodule.hm1092.bin
> + * Generator: hm1092-re/gen_hm1092_regs.py
This is great data.
> + * DO NOT HAND EDIT — regenerate from the bin.
This is not to be included in upstream though.
> + */
> +
> +struct hm1092_reg {
> + u16 address;
> + u8 val;
> +};
> +
> +static const struct hm1092_reg hm1092_init_regs[] = {
> + { 0x0103, 0x00 },
> + { 0x030a, 0x05 },
> + { 0x030d, 0x0c },
> + { 0x030f, 0x5a },
> + { 0x0307, 0x00 },
> + { 0x0309, 0x01 },
> + { 0x0387, 0x01 },
> + { 0x0100, 0x02 },
> + { 0x4265, 0x02 },
> + { 0x4002, 0x2b },
> + { 0x4001, 0x00 },
> + { 0x0101, 0x03 },
> + { 0x4024, 0x40 },
> + { 0x0203, 0xbe },
> + { 0x0202, 0x00 },
> + { 0x0341, 0xee },
> + { 0x0340, 0x02 },
> + { 0x0343, 0x50 },
> + { 0x0342, 0x06 },
> + { 0x0345, 0x30 },
> + { 0x0344, 0x00 },
> + { 0x0349, 0xad },
> + { 0x0348, 0x04 },
> + { 0x0347, 0x08 },
> + { 0x0346, 0x00 },
> + { 0x034b, 0xd5 },
> + { 0x034a, 0x02 },
> + { 0x5015, 0xb3 },
> + { 0x0350, 0x53 },
> + { 0x0361, 0x30 },
> + { 0x0360, 0x00 },
> + { 0x034d, 0x30 },
> + { 0x034c, 0x02 },
> + { 0x034f, 0x68 },
> + { 0x034e, 0x01 },
> + { 0x0390, 0x03 },
> + { 0x0383, 0x00 },
> + { 0x0387, 0x10 },
> + { 0x50dd, 0x01 },
> + { 0x50cb, 0x21 },
> + { 0x5005, 0x28 },
> + { 0x5004, 0x40 },
> + { 0x5007, 0x28 },
> + { 0x5006, 0x40 },
> + { 0x5011, 0x00 },
> + { 0x501d, 0x4c },
> + { 0x5013, 0x03 },
> + { 0x4131, 0x01 },
> + { 0x5283, 0x03 },
> + { 0x5282, 0xff },
> + { 0x5010, 0x20 },
> + { 0x4132, 0x20 },
> + { 0x50d5, 0xe0 },
> + { 0x50d7, 0x12 },
> + { 0x50bb, 0x14 },
> + { 0x50b7, 0x00 },
> + { 0x50b9, 0xff },
> + { 0x50b8, 0x70 },
> + { 0x50ba, 0xff },
> + { 0x50fa, 0x02 },
> + { 0x50b4, 0x00 },
> + { 0x50a2, 0x0b },
> + { 0x50ad, 0x07 },
> + { 0x50ac, 0x24 },
> + { 0x50af, 0x40 },
> + { 0x50ae, 0x20 },
> + { 0x50ab, 0x07 },
> + { 0x50aa, 0x22 },
> + { 0x50a7, 0x00 },
> + { 0x50a6, 0x00 },
> + { 0x5099, 0x11 },
> + { 0x509b, 0x03 },
> + { 0x50b3, 0x04 },
> + { 0x50a0, 0x30 },
> + { 0x5098, 0x00 },
> + { 0x52f2, 0x53 },
> + { 0x5209, 0x0c },
> + { 0x5216, 0x02 },
> + { 0x521e, 0x01 },
> + { 0x50e8, 0x00 },
> + { 0x5200, 0x60 },
> + { 0x5202, 0x00 },
> + { 0x5201, 0x80 },
> + { 0x5203, 0x01 },
> + { 0x5208, 0x0b },
> + { 0x520d, 0x40 },
> + { 0x520c, 0x15 },
> + { 0x5215, 0x04 },
> + { 0x50ea, 0x74 },
> + { 0x5214, 0x28 },
> + { 0x5218, 0x07 },
> + { 0x5217, 0x01 },
> + { 0x0310, 0x00 },
> + { 0x4b31, 0x06 },
> + { 0x4b3b, 0x02 },
> + { 0x4b45, 0x01 },
> + { 0x4b44, 0x0c },
> + { 0x4b47, 0x00 },
> + { 0x5101, 0x13 },
> + { 0x5100, 0x03 },
> + { 0x5103, 0x33 },
> + { 0x5102, 0x23 },
> + { 0x5105, 0x42 },
> + { 0x5104, 0x43 },
> + { 0x5106, 0x40 },
> + { 0x5119, 0x00 },
> + { 0x5118, 0x00 },
> + { 0x511b, 0x00 },
> + { 0x511a, 0x00 },
> + { 0x511d, 0x00 },
> + { 0x511c, 0x00 },
> + { 0x511e, 0x00 },
> + { 0x5131, 0x23 },
> + { 0x5130, 0x13 },
> + { 0x5133, 0x43 },
> + { 0x5132, 0x33 },
> + { 0x5135, 0x40 },
> + { 0x5134, 0x42 },
> + { 0x5136, 0x40 },
> + { 0x5149, 0x01 },
> + { 0x5148, 0x01 },
> + { 0x514b, 0x01 },
> + { 0x514a, 0x01 },
> + { 0x514d, 0x01 },
> + { 0x514c, 0x01 },
> + { 0x514e, 0x01 },
> + { 0x51c0, 0x00 },
> + { 0x51c6, 0x00 },
> + { 0x51cc, 0x00 },
> + { 0x51d2, 0x00 },
> + { 0x51d8, 0x00 },
> + { 0x51c1, 0x81 },
> + { 0x51c7, 0x81 },
> + { 0x51cd, 0x81 },
> + { 0x51d3, 0x81 },
> + { 0x51d9, 0x81 },
> + { 0x51c2, 0xec },
> + { 0x51c8, 0xec },
> + { 0x51ce, 0xec },
> + { 0x51d4, 0xec },
> + { 0x51da, 0xec },
> + { 0x51c3, 0x00 },
> + { 0x51c9, 0x00 },
> + { 0x51cf, 0x00 },
> + { 0x51d5, 0x00 },
> + { 0x51db, 0x00 },
> + { 0x51c4, 0x55 },
> + { 0x51ca, 0x55 },
> + { 0x51d0, 0x54 },
> + { 0x51d6, 0x53 },
> + { 0x51dc, 0x53 },
> + { 0x51c5, 0x44 },
> + { 0x51cb, 0x24 },
> + { 0x51d1, 0x24 },
> + { 0x51d7, 0x14 },
> + { 0x51dd, 0x14 },
> + { 0x51e0, 0x09 },
> + { 0x51e2, 0x04 },
> + { 0x51e4, 0x08 },
> + { 0x51e6, 0x08 },
> + { 0x51e1, 0x03 },
> + { 0x51e3, 0x03 },
> + { 0x51e5, 0x07 },
> + { 0x51e8, 0x04 },
> + { 0x51e7, 0x07 },
> + { 0x51e9, 0x46 },
> + { 0x51eb, 0x62 },
> + { 0x51ea, 0x43 },
> + { 0x51ed, 0x00 },
> + { 0x51ec, 0x61 },
> + { 0x51ee, 0x00 },
> + { 0x5206, 0x80 },
> + { 0x3110, 0x02 },
> + { 0x3704, 0x02 },
> + { 0x3704, 0x02 },
> + { 0x4b20, 0x9e },
> + { 0x4b18, 0x00 },
> + { 0x4b3e, 0x00 },
> + { 0x4b0e, 0x0e },
> + { 0x4800, 0xac },
> + { 0x0104, 0x01 },
> + { 0x0104, 0x00 },
> + { 0x4801, 0xae },
> + { 0x0000, 0x00 },
> + { 0x0037, 0x30 },
> +};
> +
> +static const struct hm1092_reg hm1092_start_streaming[] = {
> + { 0x0100, 0x01 },
> +};
> +
> +static const struct hm1092_reg hm1092_test_pattern_mode0[] = {
> + { 0x0601, 0x00 },
> +};
> +
> +static const struct hm1092_reg hm1092_test_pattern_mode1[] = {
> + { 0x0601, 0x01 },
> +};
> +
> +static const struct hm1092_reg hm1092_test_pattern_mode2[] = {
> + { 0x0601, 0x02 },
> +};
> +
> +static const struct hm1092_reg hm1092_test_pattern_mode3[] = {
> + { 0x0601, 0x03 },
> +};
> +
> +static const struct hm1092_reg hm1092_test_pattern_mode4[] = {
> + { 0x0601, 0x04 },
> +};
>
> --
> 2.53.0
>
^ permalink raw reply
* [PATCH v2 2/2] riscv: dts: sophgo: Add Milk-V Duo 256M board support
From: Chen-Yu Yeh @ 2026-06-10 12:10 UTC (permalink / raw)
To: unicorn_wang, inochiama
Cc: Chen-Yu Yeh, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
Han Gao, Nutty Liu, Longbin Li,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list:RISC-V ARCHITECTURE,
open list:SOPHGO DEVICETREES and DRIVERS, open list
In-Reply-To: <20260610121026.1517621-1-chenyou910331@gmail.com>
The Milk-V Duo 256M is a small form factor development board based on
the Sophgo SG2002 SoC.
This patch adds basic device tree support for the board, including:
- UART console
- SD/MMC controller
- USB host
- Onboard blue status LED (connected to PWR_GPIO[2] / porte 2)
Tested on actual Milk-V Duo 256M hardware, verified boot to shell and
heartbeat LED functionality.
Signed-off-by: Chen-Yu Yeh <chenyou910331@gmail.com>
---
Changes since v1:
- Removed the leds node because &porte is not yet supported in cv180x.dtsi,
which would cause a dtc compilation error.
- Retained the &usb node because it is already defined in cv180x.dtsi.
- Cleaned up the trailing blank line in the Makefile.
arch/riscv/boot/dts/sophgo/Makefile | 3 +-
.../boot/dts/sophgo/sg2002-milkv-duo256m.dts | 108 ++++++++++++++++++
2 files changed, 110 insertions(+), 1 deletion(-)
create mode 100644 arch/riscv/boot/dts/sophgo/sg2002-milkv-duo256m.dts
diff --git a/arch/riscv/boot/dts/sophgo/Makefile b/arch/riscv/boot/dts/sophgo/Makefile
index 6f65526d4193..f9415c30a2c5 100644
--- a/arch/riscv/boot/dts/sophgo/Makefile
+++ b/arch/riscv/boot/dts/sophgo/Makefile
@@ -2,7 +2,8 @@
dtb-$(CONFIG_ARCH_SOPHGO) += cv1800b-milkv-duo.dtb
dtb-$(CONFIG_ARCH_SOPHGO) += cv1812h-huashan-pi.dtb
dtb-$(CONFIG_ARCH_SOPHGO) += sg2002-licheerv-nano-b.dtb
+dtb-$(CONFIG_ARCH_SOPHGO) += sg2002-milkv-duo256m.dtb
dtb-$(CONFIG_ARCH_SOPHGO) += sg2042-milkv-pioneer.dtb
dtb-$(CONFIG_ARCH_SOPHGO) += sg2042-evb-v1.dtb
dtb-$(CONFIG_ARCH_SOPHGO) += sg2042-evb-v2.dtb
-dtb-$(CONFIG_ARCH_SOPHGO) += sg2044-sophgo-srd3-10.dtb
+dtb-$(CONFIG_ARCH_SOPHGO) += sg2044-sophgo-srd3-10.dtb
\ No newline at end of file
diff --git a/arch/riscv/boot/dts/sophgo/sg2002-milkv-duo256m.dts b/arch/riscv/boot/dts/sophgo/sg2002-milkv-duo256m.dts
new file mode 100644
index 000000000000..4cf441ab3790
--- /dev/null
+++ b/arch/riscv/boot/dts/sophgo/sg2002-milkv-duo256m.dts
@@ -0,0 +1,108 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2023 Jisheng Zhang <jszhang@kernel.org>
+ */
+
+/dts-v1/;
+
+#include "sg2002.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ model = "Milk-V Duo 256M";
+ compatible = "milkv,duo256m", "sophgo,sg2002";
+
+ aliases {
+ serial0 = &uart0;
+ serial1 = &uart1;
+ serial2 = &uart2;
+ serial3 = &uart3;
+ serial4 = &uart4;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ reserved-memory {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ coprocessor_rtos: region@83f40000 {
+ reg = <0x83f40000 0xc0000>;
+ no-map;
+ };
+ };
+};
+
+&osc {
+ clock-frequency = <25000000>;
+};
+
+&pinctrl {
+ uart0_cfg: uart0-cfg {
+ uart0-pins {
+ pinmux = <PINMUX(PIN_UART0_TX, 0)>,
+ <PINMUX(PIN_UART0_RX, 0)>;
+ bias-pull-up;
+ drive-strength-microamp = <10800>;
+ power-source = <3300>;
+ };
+ };
+
+ sdhci0_cfg: sdhci0-cfg {
+ sdhci0-clk-pins {
+ pinmux = <PINMUX(PIN_SD0_CLK, 0)>;
+ bias-pull-up;
+ drive-strength-microamp = <16100>;
+ power-source = <3300>;
+ };
+
+ sdhci0-cmd-pins {
+ pinmux = <PINMUX(PIN_SD0_CMD, 0)>;
+ bias-pull-up;
+ drive-strength-microamp = <10800>;
+ power-source = <3300>;
+ };
+
+ sdhci0-data-pins {
+ pinmux = <PINMUX(PIN_SD0_D0, 0)>,
+ <PINMUX(PIN_SD0_D1, 0)>,
+ <PINMUX(PIN_SD0_D2, 0)>,
+ <PINMUX(PIN_SD0_D3, 0)>;
+ bias-pull-up;
+ drive-strength-microamp = <10800>;
+ power-source = <3300>;
+ };
+
+ sdhci0-cd-pins {
+ pinmux = <PINMUX(PIN_SD0_CD, 0)>;
+ bias-pull-up;
+ drive-strength-microamp = <10800>;
+ power-source = <3300>;
+ };
+ };
+};
+
+&sdhci0 {
+ pinctrl-0 = <&sdhci0_cfg>;
+ pinctrl-names = "default";
+ status = "okay";
+ bus-width = <4>;
+ no-1-8-v;
+ no-mmc;
+ no-sdio;
+ disable-wp;
+};
+
+&uart0 {
+ pinctrl-0 = <&uart0_cfg>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&usb {
+ dr_mode = "host";
+ status = "okay";
+};
--
2.43.0
^ permalink raw reply related
* [PATCH v2 1/2] dt-bindings: soc: sophgo: add Milk-V Duo 256M board
From: Chen-Yu Yeh @ 2026-06-10 12:10 UTC (permalink / raw)
To: unicorn_wang, inochiama
Cc: Chen-Yu Yeh, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Nutty Liu, Han Gao, Alexander Sverdlin, Chao Wei,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list:SOPHGO DEVICETREES and DRIVERS, open list
Add compatible string for the Milk-V Duo 256M board.
Signed-off-by: Chen-Yu Yeh <chenyou910331@gmail.com>
---
Documentation/devicetree/bindings/soc/sophgo/sophgo.yaml | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/Documentation/devicetree/bindings/soc/sophgo/sophgo.yaml b/Documentation/devicetree/bindings/soc/sophgo/sophgo.yaml
index 1c502618de51..fcb1d905da7d 100644
--- a/Documentation/devicetree/bindings/soc/sophgo/sophgo.yaml
+++ b/Documentation/devicetree/bindings/soc/sophgo/sophgo.yaml
@@ -31,6 +31,10 @@ properties:
- milkv,duo-module-01-evb
- const: milkv,duo-module-01
- const: sophgo,sg2000
+ - items:
+ - enum:
+ - milkv,duo256m
+ - const: sophgo,sg2002
- items:
- enum:
- sipeed,licheerv-nano-b
--
2.43.0
^ permalink raw reply related
* [PATCH] arm64: dts: qcom: eliza: Add PCIe PHY and controller nodes
From: Krishna Chaitanya Chundru @ 2026-06-10 12:10 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley
Cc: linux-arm-msm, devicetree, linux-kernel, abel.vesa,
Krishna Chaitanya Chundru
Eliza supports two PCIe instances: one 8GT/s x1 (PCIe0) and one 8GT/s x2
(PCIe1). Add PCIe controller and PHY nodes for both instances, and update
the GCC clock references to use the newly added PHY nodes instead of
placeholder zeros.
Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru@oss.qualcomm.com>
---
This patch depends on https://lore.kernel.org/all/20260608-eliza-v3-0-9bdeb7434b28@oss.qualcomm.com/
---
arch/arm64/boot/dts/qcom/eliza.dtsi | 359 +++++++++++++++++++++++++++++++++++-
1 file changed, 357 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/eliza.dtsi b/arch/arm64/boot/dts/qcom/eliza.dtsi
index 7e97361a5dc5..2a51da62270d 100644
--- a/arch/arm64/boot/dts/qcom/eliza.dtsi
+++ b/arch/arm64/boot/dts/qcom/eliza.dtsi
@@ -610,8 +610,8 @@ gcc: clock-controller@100000 {
clocks = <&bi_tcxo_div2>,
<&sleep_clk>,
- <0>,
- <0>,
+ <&pcie0_phy>,
+ <&pcie1_phy>,
<&ufs_mem_phy 0>,
<&ufs_mem_phy 1>,
<&ufs_mem_phy 2>,
@@ -716,6 +716,361 @@ mmss_noc: interconnect@1780000 {
#interconnect-cells = <2>;
};
+ pcie0: pcie@1c00000 {
+ device_type = "pci";
+ compatible = "qcom,eliza-pcie", "qcom,pcie-sm8550";
+ reg = <0 0x01c00000 0 0x3000>,
+ <0 0x40000000 0 0xf1d>,
+ <0 0x40000f20 0 0xa8>,
+ <0 0x40001000 0 0x1000>,
+ <0 0x40100000 0 0x100000>,
+ <0 0x01c03000 0 0x1000>;
+ reg-names = "parf",
+ "dbi",
+ "elbi",
+ "atu",
+ "config",
+ "mhi";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges = <0x01000000 0 0x00000000 0 0x40200000 0 0x100000>,
+ <0x02000000 0 0x40300000 0 0x40300000 0 0x3d00000>;
+
+ interrupts = <GIC_SPI 376 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 478 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 479 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 535 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 536 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 537 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 540 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 653 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 370 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "msi0",
+ "msi1",
+ "msi2",
+ "msi3",
+ "msi4",
+ "msi5",
+ "msi6",
+ "msi7",
+ "global";
+
+ clocks = <&gcc GCC_PCIE_0_AUX_CLK>,
+ <&gcc GCC_PCIE_0_CFG_AHB_CLK>,
+ <&gcc GCC_PCIE_0_MSTR_AXI_CLK>,
+ <&gcc GCC_PCIE_0_SLV_AXI_CLK>,
+ <&gcc GCC_PCIE_0_SLV_Q2A_AXI_CLK>,
+ <&gcc GCC_DDRSS_PCIE_SF_QTB_CLK>,
+ <&gcc GCC_AGGRE_NOC_PCIE_AXI_CLK>,
+ <&gcc GCC_CNOC_PCIE_SF_AXI_CLK>;
+ clock-names = "aux",
+ "cfg",
+ "bus_master",
+ "bus_slave",
+ "slave_q2a",
+ "ddrss_sf_tbu",
+ "noc_aggr",
+ "cnoc_sf_axi";
+
+ resets = <&gcc GCC_PCIE_0_BCR>,
+ <&gcc GCC_PCIE_0_LINK_DOWN_BCR>;
+ reset-names = "pci",
+ "link_down";
+
+ interconnects = <&pcie_noc MASTER_PCIE_0 QCOM_ICC_TAG_ALWAYS
+ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
+ <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
+ &cnoc_main SLAVE_PCIE_0 QCOM_ICC_TAG_ACTIVE_ONLY>;
+ interconnect-names = "pcie-mem",
+ "cpu-pcie";
+
+ power-domains = <&gcc GCC_PCIE_0_GDSC>;
+
+ operating-points-v2 = <&pcie0_opp_table>;
+
+ iommu-map = <0 &apps_smmu 0x1480 0x1>,
+ <0x100 &apps_smmu 0x1481 0x1>;
+
+ interrupt-map = <0 0 0 1 &intc 0 0 0 564 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 2 &intc 0 0 0 565 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 3 &intc 0 0 0 566 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 4 &intc 0 0 0 567 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-map-mask = <0 0 0 0x7>;
+ #interrupt-cells = <1>;
+
+ linux,pci-domain = <0>;
+ num-lanes = <1>;
+ bus-range = <0 0xff>;
+
+ dma-coherent;
+
+ status = "disabled";
+
+ pcie0_opp_table: opp-table {
+ compatible = "operating-points-v2";
+
+ /* 2.5 GT/s x1 */
+ opp-2500000-1 {
+ opp-hz = /bits/ 64 <2500000>;
+ required-opps = <&rpmhpd_opp_low_svs>;
+ opp-peak-kBps = <250000 1>;
+ opp-level = <1>;
+ };
+
+ /* 5 GT/s x1 */
+ opp-5000000-2 {
+ opp-hz = /bits/ 64 <5000000>;
+ required-opps = <&rpmhpd_opp_low_svs>;
+ opp-peak-kBps = <500000 1>;
+ opp-level = <2>;
+ };
+
+ /* 8 GT/s x1 */
+ opp-8000000-3 {
+ opp-hz = /bits/ 64 <8000000>;
+ required-opps = <&rpmhpd_opp_low_svs>;
+ opp-peak-kBps = <984500 1>;
+ opp-level = <3>;
+ };
+
+ };
+
+ pcie0port0: pcie@0 {
+ device_type = "pci";
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ bus-range = <0x01 0xff>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ phys = <&pcie0_phy>;
+ };
+ };
+
+ pcie0_phy: phy@1c06000 {
+ compatible = "qcom,eliza-qmp-gen3x1-pcie-phy";
+ reg = <0 0x01c06000 0 0x2000>;
+
+ clocks = <&gcc GCC_PCIE_0_AUX_CLK>,
+ <&gcc GCC_PCIE_0_CFG_AHB_CLK>,
+ <&tcsr TCSR_PCIE_0_CLKREF_EN>,
+ <&gcc GCC_PCIE_0_PHY_RCHNG_CLK>,
+ <&gcc GCC_PCIE_0_PIPE_CLK>,
+ <&gcc GCC_PCIE_0_PIPE_DIV2_CLK>;
+ clock-names = "aux",
+ "cfg_ahb",
+ "ref",
+ "rchng",
+ "pipe",
+ "pipediv2";
+
+ assigned-clocks = <&gcc GCC_PCIE_0_PHY_RCHNG_CLK>;
+ assigned-clock-rates = <100000000>;
+
+ resets = <&gcc GCC_PCIE_0_PHY_BCR>,
+ <&gcc GCC_PCIE_0_NOCSR_COM_PHY_BCR>;
+ reset-names = "phy",
+ "phy_nocsr";
+
+ power-domains = <&gcc GCC_PCIE_0_PHY_GDSC>;
+
+ #clock-cells = <0>;
+ clock-output-names = "pcie0_pipe_clk";
+
+ #phy-cells = <0>;
+
+ status = "disabled";
+ };
+
+ pcie1: pcie@1c08000 {
+ device_type = "pci";
+ compatible = "qcom,eliza-pcie", "qcom,pcie-sm8550";
+ reg = <0 0x01c08000 0 0x3000>,
+ <0 0x44000000 0 0xf1d>,
+ <0 0x44000f20 0 0xa8>,
+ <0 0x44001000 0 0x1000>,
+ <0 0x44100000 0 0x100000>,
+ <0 0x01c0b000 0 0x1000>;
+ reg-names = "parf",
+ "dbi",
+ "elbi",
+ "atu",
+ "config",
+ "mhi";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges = <0x01000000 0 0x00000000 0 0x44200000 0 0x100000>,
+ <0x02000000 0 0x44300000 0 0x44300000 0 0x3d00000>;
+
+ interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "msi0",
+ "msi1",
+ "msi2",
+ "msi3",
+ "msi4",
+ "msi5",
+ "msi6",
+ "msi7",
+ "global";
+
+ clocks = <&gcc GCC_PCIE_1_AUX_CLK>,
+ <&gcc GCC_PCIE_1_CFG_AHB_CLK>,
+ <&gcc GCC_PCIE_1_MSTR_AXI_CLK>,
+ <&gcc GCC_PCIE_1_SLV_AXI_CLK>,
+ <&gcc GCC_PCIE_1_SLV_Q2A_AXI_CLK>,
+ <&gcc GCC_DDRSS_PCIE_SF_QTB_CLK>,
+ <&gcc GCC_AGGRE_NOC_PCIE_AXI_CLK>,
+ <&gcc GCC_CNOC_PCIE_SF_AXI_CLK>;
+ clock-names = "aux",
+ "cfg",
+ "bus_master",
+ "bus_slave",
+ "slave_q2a",
+ "ddrss_sf_tbu",
+ "noc_aggr",
+ "cnoc_sf_axi";
+
+ resets = <&gcc GCC_PCIE_1_BCR>,
+ <&gcc GCC_PCIE_1_LINK_DOWN_BCR>;
+ reset-names = "pci",
+ "link_down";
+
+ interconnects = <&pcie_noc MASTER_PCIE_1 QCOM_ICC_TAG_ALWAYS
+ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
+ <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
+ &cnoc_main SLAVE_PCIE_1 QCOM_ICC_TAG_ACTIVE_ONLY>;
+ interconnect-names = "pcie-mem",
+ "cpu-pcie";
+
+ power-domains = <&gcc GCC_PCIE_1_GDSC>;
+
+ operating-points-v2 = <&pcie1_opp_table>;
+
+ iommu-map = <0 &apps_smmu 0x1400 0x1>,
+ <0x100 &apps_smmu 0x1401 0x1>;
+
+ interrupt-map = <0 0 0 1 &intc 0 0 0 149 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 2 &intc 0 0 0 150 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 3 &intc 0 0 0 151 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 4 &intc 0 0 0 152 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-map-mask = <0 0 0 0x7>;
+ #interrupt-cells = <1>;
+
+ linux,pci-domain = <1>;
+ num-lanes = <2>;
+ bus-range = <0 0xff>;
+
+ dma-coherent;
+
+ status = "disabled";
+
+ pcie1_opp_table: opp-table {
+ compatible = "operating-points-v2";
+
+ /* 2.5 GT/s x1 */
+ opp-2500000-1 {
+ opp-hz = /bits/ 64 <2500000>;
+ required-opps = <&rpmhpd_opp_low_svs>;
+ opp-peak-kBps = <250000 1>;
+ opp-level = <1>;
+ };
+
+ /* 2.5 GT/s x2 */
+ opp-5000000-1 {
+ opp-hz = /bits/ 64 <5000000>;
+ required-opps = <&rpmhpd_opp_low_svs>;
+ opp-peak-kBps = <500000 1>;
+ opp-level = <1>;
+ };
+
+ /* 5 GT/s x1 */
+ opp-5000000-2 {
+ opp-hz = /bits/ 64 <5000000>;
+ required-opps = <&rpmhpd_opp_low_svs>;
+ opp-peak-kBps = <500000 1>;
+ opp-level = <2>;
+ };
+
+ /* 5 GT/s x2 */
+ opp-10000000-2 {
+ opp-hz = /bits/ 64 <10000000>;
+ required-opps = <&rpmhpd_opp_low_svs>;
+ opp-peak-kBps = <1000000 1>;
+ opp-level = <2>;
+ };
+
+ /* 8 GT/s x1 */
+ opp-8000000-3 {
+ opp-hz = /bits/ 64 <8000000>;
+ required-opps = <&rpmhpd_opp_low_svs>;
+ opp-peak-kBps = <984500 1>;
+ opp-level = <3>;
+ };
+
+ /* 8 GT/s x2 */
+ opp-16000000-3 {
+ opp-hz = /bits/ 64 <16000000>;
+ required-opps = <&rpmhpd_opp_low_svs>;
+ opp-peak-kBps = <1969000 1>;
+ opp-level = <3>;
+ };
+
+ };
+ pcie1port0: pcie@0 {
+ device_type = "pci";
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ bus-range = <0x01 0xff>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ phys = <&pcie1_phy>;
+ };
+ };
+
+ pcie1_phy: phy@1c0e000 {
+ compatible = "qcom,eliza-qmp-gen3x2-pcie-phy";
+ reg = <0 0x01c0e000 0 0x2000>;
+
+ clocks = <&gcc GCC_PCIE_1_AUX_CLK>,
+ <&gcc GCC_PCIE_1_CFG_AHB_CLK>,
+ <&tcsr TCSR_PCIE_1_CLKREF_EN>,
+ <&gcc GCC_PCIE_1_PHY_RCHNG_CLK>,
+ <&gcc GCC_PCIE_1_PIPE_CLK>,
+ <&gcc GCC_PCIE_1_PIPE_DIV2_CLK>;
+ clock-names = "aux",
+ "cfg_ahb",
+ "ref",
+ "rchng",
+ "pipe",
+ "pipediv2";
+
+ assigned-clocks = <&gcc GCC_PCIE_1_PHY_RCHNG_CLK>;
+ assigned-clock-rates = <100000000>;
+
+ resets = <&gcc GCC_PCIE_1_PHY_BCR>,
+ <&gcc GCC_PCIE_1_NOCSR_COM_PHY_BCR>;
+ reset-names = "phy",
+ "phy_nocsr";
+
+ power-domains = <&gcc GCC_PCIE_1_PHY_GDSC>;
+
+ #clock-cells = <0>;
+ clock-output-names = "pcie1_pipe_clk";
+
+ #phy-cells = <0>;
+
+ status = "disabled";
+ };
+
ufs_mem_phy: phy@1d80000 {
compatible = "qcom,eliza-qmp-ufs-phy",
"qcom,sm8650-qmp-ufs-phy";
---
base-commit: 05225e350d54bcac2542f98abde017b8630f5086
change-id: 20260610-eliza_dt-540bd6f7e883
prerequisite-message-id: <20260608-eliza-v3-0-9bdeb7434b28@oss.qualcomm.com>
prerequisite-patch-id: 9f910ecb377e4195299293f27c9892aa1df93943
prerequisite-patch-id: 246cb54c5e74e3e6ac32772972c26289523a93aa
prerequisite-patch-id: b8f67adbd27f4738bc31916b7773132383e2415c
Best regards,
--
Krishna Chaitanya Chundru <krishna.chundru@oss.qualcomm.com>
^ permalink raw reply related
* Re: [PATCH v5 4/5] iio: adc: versal-sysmon: add threshold event support
From: Erim, Salih @ 2026-06-10 12:10 UTC (permalink / raw)
To: Andy Shevchenko
Cc: jic23, andy, dlechner, nuno.sa, robh, krzk+dt, conor+dt,
conall.ogriofa, michal.simek, linux, erimsalih, linux-iio,
devicetree, linux-kernel
In-Reply-To: <aihTVQIedgsFKeM7@ashevche-desk.local>
Hi Andy,
On 09/06/2026 18:54, Andy Shevchenko wrote:
> On Mon, Jun 08, 2026 at 07:38:00PM +0100, Salih Erim wrote:
>> Add threshold event support for temperature and supply voltage
>> channels.
>>
>> Temperature events:
>> - Rising threshold with configurable value
>> - Over-temperature (OT) alarm with separate threshold
>> - Per-channel hysteresis as a millicelsius value
>> - Event direction is IIO_EV_DIR_RISING (hysteresis mode)
>>
>> Supply voltage events:
>> - Rising/falling threshold per supply channel
>> - Per-channel alarm enable via alarm configuration registers
>>
>> The hardware supports both window and hysteresis alarm modes for
>> temperature. This driver uses hysteresis mode, where the upper
>> threshold triggers the alarm and the lower threshold clears it
>> (re-arm point). The hardware has a single ISR bit per temperature
>> channel with no indication of which threshold was crossed, so
>> hysteresis mode is the natural fit. The lower threshold register
>> is computed internally as (upper - hysteresis).
>>
>> Hysteresis is stored in the driver as a millicelsius value,
>> initialized from the hardware registers at probe. Writing the
>> rising threshold or hysteresis recomputes the lower register.
>> ALARM_CONFIG is hard-coded to hysteresis mode during init.
>>
>> The interrupt handler masks active threshold interrupts (which are
>> level-sensitive) and schedules a delayed worker to poll for condition
>> clear before unmasking. When no hardware IRQ is available, event
>> channels are not created and interrupt init is skipped, since the
>> I2C regmap backend cannot be called from atomic context.
>>
>> When disabling a supply channel alarm, the group interrupt remains
>> active if any other channel in the same alarm group still has an
>> alarm enabled.
>
> ...
>
>> +#define SYSMON_CHAN_TEMP_EVENT(_chan, _address, _name, _events) {\
>
> Just move { to be on the separate line, it will make the macro look better.
Accepted. Will fix both SYSMON_CHAN_TEMP and SYSMON_CHAN_TEMP_EVENT macros.
>
> #define SYSMON_CHAN_TEMP_EVENT(_chan, _address, _name, _events) \
> { \
>
>> + .type = IIO_TEMP, \
>> + .indexed = 1, \
>> + .address = _address, \
>> + .channel = _chan, \
>> + .event_spec = _events, \
>> + .num_event_specs = ARRAY_SIZE(_events), \
>> + .datasheet_name = _name, \
>> +}
>
> ...
>
>> +static int sysmon_write_event_config(struct iio_dev *indio_dev,
>> + const struct iio_chan_spec *chan,
>> + enum iio_event_type type,
>> + enum iio_event_direction dir,
>> + bool state)
>> +{
>> + u32 offset = SYSMON_ALARM_OFFSET(chan->address);
>> + u32 ier = sysmon_get_event_mask(chan->address);
>> + struct sysmon *sysmon = iio_priv(indio_dev);
>> + unsigned int alarm_config;
>> + int ret;
>> +
>> + guard(mutex)(&sysmon->lock);
>> +
>> + if (chan->type == IIO_VOLTAGE) {
>> + ret = sysmon_write_alarm_config(sysmon, chan->address, state);
>> + if (ret)
>> + return ret;
>> +
>> + ret = regmap_read(sysmon->regmap, offset, &alarm_config);
>> + if (ret)
>> + return ret;
>> +
>> + if (alarm_config)
>> + return regmap_write(sysmon->regmap, SYSMON_IER, ier);
>> +
>> + return regmap_write(sysmon->regmap, SYSMON_IDR, ier);
>
>> + }
>> +
>> + if (chan->type == IIO_TEMP) {
>
> Still same problem you promised to address. Please, go back to the previous
> thread and check again what has been addressed and what's not.
You're right on all counts, and I apologize for wasting your time
reviewing the same issues.
The cascading if statements should have been converted to switch
in v5. I fixed it in the oversampling patch but missed these event
functions. All will use switch(chan->type) in v6, and
read/write_event_value will also use switch(info) for the nested
dispatch.
>
>> + if (state) {
>> + ret = regmap_write(sysmon->regmap, SYSMON_IER, ier);
>> + if (ret)
>> + return ret;
>> +
>> + scoped_guard(spinlock_irq, &sysmon->irq_lock)
>> + sysmon->temp_mask &= ~ier;
>> + } else {
>> + ret = regmap_write(sysmon->regmap, SYSMON_IDR, ier);
>> + if (ret)
>> + return ret;
>> +
>> + scoped_guard(spinlock_irq, &sysmon->irq_lock)
>> + sysmon->temp_mask |= ier;
>> + }
>> + }
>> +
>> + return 0;
>> +}
>
> ...
>
>> +static int sysmon_update_temp_lower(struct sysmon *sysmon, int address)
>> +{
>> + unsigned int upper_reg;
>> + int upper_mc, lower_mc, hysteresis;
>> + u32 raw_val;
>> + int upper_off, lower_off, ret;
>
> Keep in reversed xmas tree order.
Accepted.
>
>> + upper_off = sysmon_temp_thresh_offset(address, IIO_EV_DIR_RISING);
>> + if (upper_off < 0)
>> + return upper_off;
>> + lower_off = sysmon_temp_thresh_offset(address, IIO_EV_DIR_FALLING);
>> + if (lower_off < 0)
>> + return lower_off;
>> +
>> + if (address == SYSMON_ADDR_OT_EVENT)
>> + hysteresis = sysmon->ot_hysteresis;
>> + else
>> + hysteresis = sysmon->temp_hysteresis;
>> +
>> + ret = regmap_read(sysmon->regmap, upper_off, &upper_reg);
>> + if (ret)
>> + return ret;
>> +
>> + sysmon_q8p7_to_millicelsius(upper_reg, &upper_mc);
>> +
>> + lower_mc = upper_mc - hysteresis;
>> + sysmon_millicelsius_to_q8p7(&raw_val, lower_mc);
>> +
>> + return regmap_write(sysmon->regmap, lower_off, raw_val);
>> +}
>
> ...
>
>> +static int sysmon_read_event_value(struct iio_dev *indio_dev,
>> + const struct iio_chan_spec *chan,
>> + enum iio_event_type type,
>> + enum iio_event_direction dir,
>> + enum iio_event_info info,
>> + int *val, int *val2)
>> +{
>> + struct sysmon *sysmon = iio_priv(indio_dev);
>> + unsigned int reg_val;
>> + int offset;
>> + int ret;
>> +
>> + guard(mutex)(&sysmon->lock);
>> +
>> + if (chan->type == IIO_TEMP) {
>> + if (info == IIO_EV_INFO_VALUE) {
>> + /* Only rising threshold is exposed */
>> + offset = sysmon_temp_thresh_offset(chan->address,
>> + IIO_EV_DIR_RISING);
>> + if (offset < 0)
>> + return offset;
>> +
>> + ret = regmap_read(sysmon->regmap, offset, ®_val);
>> + if (ret)
>> + return ret;
>> +
>> + sysmon_q8p7_to_millicelsius(reg_val, val);
>> +
>> + return IIO_VAL_INT;
>> + }
>> + if (info == IIO_EV_INFO_HYSTERESIS) {
>> + if (chan->address == SYSMON_ADDR_OT_EVENT)
>> + *val = sysmon->ot_hysteresis;
>> + else
>> + *val = sysmon->temp_hysteresis;
>> + return IIO_VAL_INT;
>> + }
>
>> + }
>> +
>> + if (chan->type == IIO_VOLTAGE) {
>
> Again, same issue. Are you sure you sent the new version?
That's purely my mistake, I will address them all in new version.
>
>> + offset = sysmon_supply_thresh_offset(chan->address, dir);
>> + if (offset < 0)
>> + return offset;
>> +
>> + ret = regmap_read(sysmon->regmap, offset, ®_val);
>> + if (ret)
>> + return ret;
>> +
>> + sysmon_supply_rawtoprocessed(reg_val, val);
>> +
>> + return IIO_VAL_INT;
>> + }
>> +
>> + return -EINVAL;
>> +}
>
> ...
>
>> +static int sysmon_write_event_value(struct iio_dev *indio_dev,
>> + const struct iio_chan_spec *chan,
>> + enum iio_event_type type,
>> + enum iio_event_direction dir,
>> + enum iio_event_info info,
>> + int val, int val2)
>> +{
>> + struct sysmon *sysmon = iio_priv(indio_dev);
>> + unsigned int reg_val;
>> + u32 raw_val;
>> + int offset;
>> + int ret;
>> +
>> + guard(mutex)(&sysmon->lock);
>> +
>> + if (chan->type == IIO_TEMP) {
>> + if (info == IIO_EV_INFO_VALUE) {
>> + /* Only rising threshold is exposed */
>> + offset = sysmon_temp_thresh_offset(chan->address,
>> + IIO_EV_DIR_RISING);
>> + if (offset < 0)
>> + return offset;
>> +
>> + sysmon_millicelsius_to_q8p7(&raw_val, val);
>> +
>> + ret = regmap_write(sysmon->regmap, offset, raw_val);
>> + if (ret)
>> + return ret;
>> +
>> + /* Recompute lower = upper - hysteresis */
>> + return sysmon_update_temp_lower(sysmon, chan->address);
>
>> + }
>> + if (info == IIO_EV_INFO_HYSTERESIS) {
>
> Ditto.
Will be fixed in v6.
>
>> + if (val < 0)
>> + return -EINVAL;
>> +
>> + if (chan->address == SYSMON_ADDR_OT_EVENT)
>> + sysmon->ot_hysteresis = val;
>> + else
>> + sysmon->temp_hysteresis = val;
>> +
>> + return sysmon_update_temp_lower(sysmon, chan->address);
>> + }
>
>> + }
>> +
>> + if (chan->type == IIO_VOLTAGE) {
>
> Ditto.
Will be fixed in v6.
>
>> + offset = sysmon_supply_thresh_offset(chan->address, dir);
>> + if (offset < 0)
>> + return offset;
>> +
>> + ret = regmap_read(sysmon->regmap, offset, ®_val);
>> + if (ret)
>> + return ret;
>> +
>> + sysmon_supply_processedtoraw(val, reg_val, &raw_val);
>> +
>> + return regmap_write(sysmon->regmap, offset, raw_val);
>> + }
>> +
>> + return -EINVAL;
>> +}
>
> ...
>
>> +/*
>> + * Versal threshold interrupts are level-sensitive. Active threshold
>> + * interrupts are masked in the handler and polled via delayed work
>> + * until the condition clears, then unmasked.
>> + */
>> +static void sysmon_unmask_worker(struct work_struct *work)
>> +{
>> + struct sysmon *sysmon =
>> + container_of(work, struct sysmon, sysmon_unmask_work.work);
>> + unsigned int isr;
>> +
>> + /*
>> + * regmap errors are not checked here because the worker and IRQ
>> + * handler cannot propagate errors. The MMIO regmap uses fast_io
>> + * with direct readl/writel which cannot fail.
>
> OK (but they can fail on HW level to the point of bus errors or so :).
Accepted. Will add error checks to modify flow on failure
instead of just documenting why they're absent.
>
>> + */
>> + spin_lock_irq(&sysmon->irq_lock);
>> + regmap_read(sysmon->regmap, SYSMON_ISR, &isr);
>> + regmap_write(sysmon->regmap, SYSMON_ISR, isr);
>> + sysmon_unmask_temp(sysmon, isr);
>> + spin_unlock_irq(&sysmon->irq_lock);
>> +
>> + if (sysmon->masked_temp)
>> + schedule_delayed_work(&sysmon->sysmon_unmask_work,
>> + msecs_to_jiffies(SYSMON_UNMASK_WORK_DELAY_MS));
>> + else
>> + regmap_write(sysmon->regmap, SYSMON_STATUS_RESET, 1);
>> +}
>
> ...
>
>> +static int sysmon_init_interrupt(struct sysmon *sysmon,
>> + struct device *dev,
>> + struct iio_dev *indio_dev,
>> + int irq)
>> +{
>> + unsigned int imr;
>> + int ret;
>> +
>> + /* Events not supported without IRQ (e.g. I2C path) */
>> + if (!irq)
>> + return 0;
>> +
>> + ret = devm_delayed_work_autocancel(dev, &sysmon->sysmon_unmask_work,
>> + sysmon_unmask_worker);
>> + if (ret)
>> + return ret;
>> +
>> + ret = regmap_read(sysmon->regmap, SYSMON_IMR, &imr);
>> + if (ret)
>> + return ret;
>> + sysmon->temp_mask = imr & SYSMON_TEMP_INTR_MASK;
>> +
>> + return devm_request_irq(dev, irq, sysmon_iio_irq, 0,
>> + "sysmon-irq", indio_dev);
>
> I would do that on a single line, but it's 86 characters long, so up to
> Jonathan.
Accepted. Will join on a single line. Happy to split it back if Jonathan
prefers.
>
>> +}
>
> ...
>
>> +static int sysmon_init_hysteresis(struct sysmon *sysmon, unsigned int address,
>> + int *hysteresis)
>> +{
>> + unsigned int upper_reg, lower_reg;
>> + int upper_mc, lower_mc;
>> + int upper_off, lower_off;
>
> Reversed xmas tree order.
Accepted.
>
>> + int ret;
>> +
>> + upper_off = sysmon_temp_thresh_offset(address, IIO_EV_DIR_RISING);
>> + if (upper_off < 0)
>> + return upper_off;
>> + lower_off = sysmon_temp_thresh_offset(address, IIO_EV_DIR_FALLING);
>> + if (lower_off < 0)
>> + return lower_off;
>> +
>> + ret = regmap_read(sysmon->regmap, upper_off, &upper_reg);
>> + if (ret)
>> + return ret;
>> +
>> + ret = regmap_read(sysmon->regmap, lower_off, &lower_reg);
>> + if (ret)
>> + return ret;
>> +
>> + sysmon_q8p7_to_millicelsius(upper_reg, &upper_mc);
>> + sysmon_q8p7_to_millicelsius(lower_reg, &lower_mc);
>> + *hysteresis = upper_mc - lower_mc;
>> +
>> + return 0;
>> +}
>
> ...
>
>> sysmon_channels = devm_kcalloc(dev,
>> - size_add(size_add(ARRAY_SIZE(temp_channels),
>> + size_add(size_add(num_static,
>> num_supply), num_temp),
>> sizeof(*sysmon_channels), GFP_KERNEL);
>
> Same comment as per previous patch.
Accepted.
>
>> if (!sysmon_channels)
>> return -ENOMEM;
>
> ...
>
>> --- a/drivers/iio/adc/versal-sysmon.h
>> +++ b/drivers/iio/adc/versal-sysmon.h
>
>> #include <linux/bits.h>
>> #include <linux/mutex.h>
>> +#include <linux/spinlock_types.h>
>
>> +#include <linux/types.h>
>
> Same comment as per previous round. Really, please double check what you missed
> to address.
I removed types.h from P2 as you asked, then added it at P4
assuming the new struct members needed it. They don't --
spinlock_t comes from spinlock_types.h, unsigned int and int are
built-in, struct delayed_work comes from workqueue.h. Will remove
types.h from the header entirely.
Regards,
Salih
>
>> +#include <linux/workqueue.h>
>
> --
> With Best Regards,
> Andy Shevchenko
>
>
^ permalink raw reply
* Re: [PATCH v4 2/3] arm: dts: nuvoton: npcm7xx: Drop redundant FIU clock-names
From: Tomer Maimon @ 2026-06-10 12:06 UTC (permalink / raw)
To: Andrew Jeffery
Cc: broonie, robh, krzk+dt, conor+dt, openbmc, linux-spi, devicetree,
linux-kernel, avifishman70, tali.perry1, venture, yuenn,
benjaminfair
In-Reply-To: <8a059e3a4a3338bc03829071a720012bd426bf6d.camel@codeconstruct.com.au>
will send V5 soon with message modification
On Wed, 10 Jun 2026 at 14:58, Andrew Jeffery
<andrew@codeconstruct.com.au> wrote:
>
> On Wed, 2026-06-10 at 14:56 +0300, Tomer Maimon wrote:
> > On Wed, 10 Jun 2026 at 13:49, Andrew Jeffery
> > <andrew@codeconstruct.com.au> wrote:
> > >
> > > On Tue, 2026-06-09 at 19:39 +0300, Tomer Maimon wrote:
> > > > The NPCM7xx FIU controller driver gets its single clock with
> > > > devm_clk_get_enabled(dev, NULL) and does not perform a named
> > > > clock lookup. Drop the redundant clock-names properties from the
> > > > FIU controller nodes so the DTS describes only the resources the
> > > > driver actually uses.
> > >
> > > The devicetree is a description of the hardware in the form documented
> > > by the bindings. Generally it's not right to discuss Linux drivers
> > > here: they're only relevant in the context of Linux, but the devicetree
> > > binding governs devicetrees over multiple projects.
> > >
> > > From a quick look it seems that these names are not described in the
> > > corresponding binding, therefore no drivers should be using them and as
> > > such they can (and should) be dropped. A driver would only be worth
> > > mentioning if it did use the undocumented names (as that would be a
> > > complication).
> > >
> > > Can you please rework the description?
> > do you mean change the description as follows
> > "
> > The NPCM7xx FIU controller nodes reference a single clock,
> > but the FIU binding does not describe their clock-names properties.
> > Drop the undocumented names so the DTS matches the binding.
> > "
>
> That sounds reasonable to me.
>
> Thanks,
>
> Andrew
^ permalink raw reply
* Re: [PATCH 5/5] arm64: dts: qcom: talos-evk-som: Fix BT RFA supply name
From: Krzysztof Kozlowski @ 2026-06-10 12:05 UTC (permalink / raw)
To: Konrad Dybcio, Bjorn Andersson, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, André Apitzsch, Luca Weiss, Gabriela David
Cc: linux-arm-msm, devicetree, linux-kernel, Konrad Dybcio
In-Reply-To: <20260610-topic-june26_dts_fixes-v1-5-2e0c953a6c08@oss.qualcomm.com>
On 10/06/2026 13:43, Konrad Dybcio wrote:
> From: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
>
> Fix up the supply name to align with bindings.
Could be improved the same way:
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Best regards,
Krzysztof
^ permalink raw reply
* [PATCH 4/4] arm64: dts: qcom: sm6125: Fix QUSB2 compatible
From: Konrad Dybcio @ 2026-06-10 12:04 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Wesley Cheng, Iskren Chernev, Greg Kroah-Hartman,
Bjorn Andersson, Konrad Dybcio
Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel, Konrad Dybcio
In-Reply-To: <20260610-topic-8996_61x5_qusb2phy-v1-0-d7135980e78f@oss.qualcomm.com>
From: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
There are a couple issues with the current description:
1) The msm8996 compatible is wholly reused, without a SM6125-specific
primary compatible
2) MSM8996 has a different power setup (VDD powered through a RPMPD
power-domain vs a regulator)
3) MSM8996 uses a different init sequence
As part of fixing all of them, use a SM6125-specific compatible with a
SM6115 fallback.
Signed-off-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/sm6125.dtsi | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/qcom/sm6125.dtsi b/arch/arm64/boot/dts/qcom/sm6125.dtsi
index 6e84c226948c..688548cef0f1 100644
--- a/arch/arm64/boot/dts/qcom/sm6125.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm6125.dtsi
@@ -681,7 +681,8 @@ gcc: clock-controller@1400000 {
};
hsusb_phy1: phy@1613000 {
- compatible = "qcom,msm8996-qusb2-phy";
+ compatible = "qcom,sm6125-qusb2-phy",
+ "qcom,sm6115-qusb2-phy";
reg = <0x01613000 0x180>;
#phy-cells = <0>;
--
2.54.0
^ permalink raw reply related
* [PATCH 3/4] arm64: dts: qcom: msm8996: Add VDD_MX to QUSB2 PHYs
From: Konrad Dybcio @ 2026-06-10 12:04 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Wesley Cheng, Iskren Chernev, Greg Kroah-Hartman,
Bjorn Andersson, Konrad Dybcio
Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel, Konrad Dybcio
In-Reply-To: <20260610-topic-8996_61x5_qusb2phy-v1-0-d7135980e78f@oss.qualcomm.com>
From: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
The QUSB2 PHYs are powered by (among others) the VDD_MX power rail.
Describe that in the DT.
Signed-off-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/msm8996.dtsi | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi
index 2f67e665996f..b7cd1928335c 100644
--- a/arch/arm64/boot/dts/qcom/msm8996.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi
@@ -3192,7 +3192,12 @@ hsusb_phy1: phy@7411000 {
clock-names = "cfg_ahb", "ref";
resets = <&gcc GCC_QUSB2PHY_PRIM_BCR>;
+
+ power-domains = <&rpmpd MSM8996_VDDMX>;
+ required-opps = <&rpmpd_opp4>;
+
nvmem-cells = <&qusb2p_hstx_trim>;
+
status = "disabled";
};
@@ -3206,7 +3211,12 @@ hsusb_phy2: phy@7412000 {
clock-names = "cfg_ahb", "ref";
resets = <&gcc GCC_QUSB2PHY_SEC_BCR>;
+
+ power-domains = <&rpmpd MSM8996_VDDMX>;
+ required-opps = <&rpmpd_opp4>;
+
nvmem-cells = <&qusb2s_hstx_trim>;
+
status = "disabled";
};
--
2.54.0
^ permalink raw reply related
* [PATCH 2/4] phy: qcom-qusb2: Fix SM6115 init sequence
From: Konrad Dybcio @ 2026-06-10 12:04 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Wesley Cheng, Iskren Chernev, Greg Kroah-Hartman,
Bjorn Andersson, Konrad Dybcio
Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel, Konrad Dybcio
In-Reply-To: <20260610-topic-8996_61x5_qusb2phy-v1-0-d7135980e78f@oss.qualcomm.com>
From: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
I don't know where the existing one came from, but it's apparently
wrong, according to both docs and a downstream DT [1]. Fix it up.
The updated values also happen to match SM6125, which will allow us
to fix that platform too.
[1] https://android.googlesource.com/kernel/msm-extra/devicetree/+/refs/heads/android-msm-bramble-4.19-android11-qpr1/qcom/bengal-usb.dtsi#145
Fixes: 7756f1d6369e ("phy: qcom-qusb2: Add configuration for SM4250 and SM6115")
Signed-off-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
---
drivers/phy/qualcomm/phy-qcom-qusb2.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-qusb2.c b/drivers/phy/qualcomm/phy-qcom-qusb2.c
index eb93015be841..c304ccd9f31f 100644
--- a/drivers/phy/qualcomm/phy-qcom-qusb2.c
+++ b/drivers/phy/qualcomm/phy-qcom-qusb2.c
@@ -233,9 +233,9 @@ static const struct qusb2_phy_init_tbl msm8998_init_tbl[] = {
static const struct qusb2_phy_init_tbl sm6115_init_tbl[] = {
QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE1, 0xf8),
- QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE2, 0x53),
+ QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE2, 0xb3),
QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE3, 0x81),
- QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE4, 0x17),
+ QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE4, 0xc0),
QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_TUNE, 0x30),
QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_USER_CTL1, 0x79),
--
2.54.0
^ permalink raw reply related
* [PATCH 1/4] dt-bindings: phy: qcom,qusb2: Straighten out SM6125 and MSM8996
From: Konrad Dybcio @ 2026-06-10 12:04 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Wesley Cheng, Iskren Chernev, Greg Kroah-Hartman,
Bjorn Andersson, Konrad Dybcio
Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel, Konrad Dybcio
In-Reply-To: <20260610-topic-8996_61x5_qusb2phy-v1-0-d7135980e78f@oss.qualcomm.com>
From: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
SM6125 DT currently uses just the MSM8996 compatible (without a primary
SM6125-specific one). This is not only wrong for the reasons of
violating guidelines, but also happens to not be valid.
The MSM8996 PHY is quite similar, although it requies a different init
sequence (for arch reasons). MSM8996 also needs different power
plumbing, as the VDD supply is fed through VDD_MX (which we define as
a power domain rather than a regulator), unlike on SM6125.
The init sequence seems to have been "good enough", but now that the
bindings clearly diverge, add a new compatible for SM6125 with a SM6115
fallback (as they seem to be an exact match from the SW interface POV).
Signed-off-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
---
.../devicetree/bindings/phy/qcom,qusb2-phy.yaml | 31 ++++++++++++++++++++--
1 file changed, 29 insertions(+), 2 deletions(-)
diff --git a/Documentation/devicetree/bindings/phy/qcom,qusb2-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,qusb2-phy.yaml
index 39851ba9de43..807d64aee547 100644
--- a/Documentation/devicetree/bindings/phy/qcom,qusb2-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/qcom,qusb2-phy.yaml
@@ -30,6 +30,9 @@ properties:
- qcom,sdm660-qusb2-phy
- qcom,sm4250-qusb2-phy
- qcom,sm6115-qusb2-phy
+ - items:
+ - const: qcom,sm6125-qusb2-phy
+ - const: qcom,sm6115-qusb2-phy
- items:
- enum:
- qcom,sc7180-qusb2-phy
@@ -57,6 +60,12 @@ properties:
- const: ref
- const: iface
+ power-domains:
+ maxItems: 1
+
+ required-opps:
+ maxItems: 1
+
vdd-supply:
description:
Phandle to 0.9V regulator supply to PHY digital circuit.
@@ -160,7 +169,6 @@ required:
- "#phy-cells"
- clocks
- clock-names
- - vdd-supply
- vdda-pll-supply
- vdda-phy-dpdm-supply
- resets
@@ -182,6 +190,22 @@ allOf:
qcom,preemphasis-width: false
qcom,hsdisc-trim-value: false
+ # On MSM8996, VDD is supplied via the MX power domain
+ - if:
+ properties:
+ compatible:
+ const: qcom,msm8996-qusb2-phy
+ then:
+ required:
+ - power-domains
+ - required-opps
+ else:
+ properties:
+ power-domains: false
+ required-opps: false
+ required:
+ - vdd-supply
+
additionalProperties: false
examples:
@@ -196,10 +220,13 @@ examples:
<&gcc GCC_RX1_USB2_CLKREF_CLK>;
clock-names = "cfg_ahb", "ref";
- vdd-supply = <&pm8994_l28>;
vdda-pll-supply = <&pm8994_l12>;
vdda-phy-dpdm-supply = <&pm8994_l24>;
resets = <&gcc GCC_QUSB2PHY_PRIM_BCR>;
+
+ power-domains = <&rpmpd_mx>;
+ required-opps = <&rpmpd_opp4>;
+
nvmem-cells = <&qusb2p_hstx_trim>;
};
--
2.54.0
^ permalink raw reply related
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