* [PATCH v2] regulator: dt-bindings: willsemi,wl2868c: add the WL2868C camera PMIC
@ 2026-10-28 12:04 Qianhui Xu
2026-10-29 8:55 ` Krzysztof Kozlowski
2026-10-31 3:42 ` [PATCH v3 0/3] regulator: add the WL2868C camera PMIC and its users Qianhui Xu
0 siblings, 2 replies; 10+ messages in thread
From: Qianhui Xu @ 2026-10-28 12:04 UTC (permalink / raw)
To: Mark Brown, Liam Girdwood
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, devicetree,
linux-kernel
The WL2868C is a camera power management IC with seven programmable LDOs.
LDO1 and LDO2 share the VIN12 input, LDO3 and LDO4 share VIN34, and LDO5 to
LDO7 have one input each. LDO1 and LDO2 cover 0.496 V to 1.512 V, the other
five cover 1.504 V to 3.544 V, all in 8 mV steps.
It is used on the Lenovo Legion Tab (TB322FC, SM8750), where the two camera
sensors take their DVDD, AVDD and DOVDD rails from LDO1 to LDO5 and LDO7.
Without this binding those supply references cannot be described, so the
camera stack on that board cannot be brought up.
Signed-off-by: Qianhui Xu <xiaqinghuan@mail.ustc.edu.cn>
---
Changes in v2:
- Regenerated with git format-patch from a real commit on pristine
7.3-rc7. v1 was sent with a diffstat typed into the commit message, so
the mail carried two of them; that is what Krzysztof called a broken
patch.
- Subject rewritten to the regulator tree style:
"regulator: dt-bindings: willsemi,wl2868c: ..." (was
"dt-bindings: regulator: ...").
- MAINTAINERS: the entry was in the V section while its name starts with
W. Moved between WIIMOTE and WILOCITY, and renamed from "WILLSEMI
WL2868C CAMERA PMIC DRIVER" to "WILLSEMI WL2868C CAMERA PMIC" since
there is no driver in this patch.
- MAINTAINERS: dropped L: linux-media@vger.kernel.org, using
L: linux-kernel@vger.kernel.org like the other single-file regulator
bindings. The device registers as a regulator, so the regulator tree
is where it belongs.
- Commit message now says who uses the binding: the camera PMIC on the
Lenovo Legion Tab (TB322FC, SM8750), supplying DVDD/AVDD/DOVDD of both
camera sensors.
- Binding: gave the five input supplies descriptions, grouped the
regulators patternProperties, used the real board voltage in the
example, and added the closing "..." marker.
.../bindings/regulator/willsemi,wl2868c.yaml | 79 +++++++++++++++++++
MAINTAINERS | 6 ++
2 files changed, 85 insertions(+)
create mode 100644 Documentation/devicetree/bindings/regulator/willsemi,wl2868c.yaml
diff --git a/Documentation/devicetree/bindings/regulator/willsemi,wl2868c.yaml b/Documentation/devicetree/bindings/regulator/willsemi,wl2868c.yaml
new file mode 100644
index 000000000..7abbd53fd
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/willsemi,wl2868c.yaml
@@ -0,0 +1,79 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/regulator/willsemi,wl2868c.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Will Semiconductor WL2868C camera power management IC
+
+maintainers:
+ - Qianhui Xu <xiaqinghuan@mail.ustc.edu.cn>
+
+description:
+ The WL2868C is a camera power management IC with seven programmable LDOs.
+ LDO1 and LDO2 share the VIN12 input and cover 0.496 V to 1.512 V; LDO3 and
+ LDO4 share VIN34, and LDO5 to LDO7 have one input each, covering 1.504 V to
+ 3.544 V. All outputs are programmable in 8 mV steps.
+
+properties:
+ compatible:
+ const: willsemi,wl2868c
+
+ reg:
+ maxItems: 1
+
+ reset-gpios:
+ maxItems: 1
+ description: Active-low RST_N input.
+
+ vin12-supply:
+ description: Input supply for LDO1 and LDO2.
+
+ vin34-supply:
+ description: Input supply for LDO3 and LDO4.
+
+ vin5-supply:
+ description: Input supply for LDO5.
+
+ vin6-supply:
+ description: Input supply for LDO6.
+
+ vin7-supply:
+ description: Input supply for LDO7.
+
+ regulators:
+ type: object
+ additionalProperties: false
+
+ patternProperties:
+ "^ldo[1-7]$":
+ type: object
+ $ref: regulator.yaml#
+ unevaluatedProperties: false
+
+required:
+ - compatible
+ - reg
+ - regulators
+
+additionalProperties: false
+
+examples:
+ - |
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pmic@2f {
+ compatible = "willsemi,wl2868c";
+ reg = <0x2f>;
+
+ regulators {
+ ldo1 {
+ regulator-min-microvolt = <1128000>;
+ regulator-max-microvolt = <1128000>;
+ };
+ };
+ };
+ };
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index f53047aa8..632b17b3e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -29413,6 +29413,12 @@ L: linux-input@vger.kernel.org
S: Maintained
F: drivers/hid/hid-wiimote*
+WILLSEMI WL2868C CAMERA PMIC
+M: Qianhui Xu <xiaqinghuan@mail.ustc.edu.cn>
+L: linux-kernel@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/regulator/willsemi,wl2868c.yaml
+
WILOCITY WIL6210 WIRELESS DRIVER
L: linux-wireless@vger.kernel.org
S: Orphan
--
2.53.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH v2] regulator: dt-bindings: willsemi,wl2868c: add the WL2868C camera PMIC
2026-10-28 12:04 [PATCH v2] regulator: dt-bindings: willsemi,wl2868c: add the WL2868C camera PMIC Qianhui Xu
@ 2026-10-29 8:55 ` Krzysztof Kozlowski
2026-10-31 3:39 ` Qianhui Xu
2026-10-31 5:29 ` Qianhui Xu
2026-10-31 3:42 ` [PATCH v3 0/3] regulator: add the WL2868C camera PMIC and its users Qianhui Xu
1 sibling, 2 replies; 10+ messages in thread
From: Krzysztof Kozlowski @ 2026-10-29 8:55 UTC (permalink / raw)
To: Qianhui Xu
Cc: Mark Brown, Liam Girdwood, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, devicetree, linux-kernel
On Wed, Oct 28, 2026 at 08:04:42PM +0800, Qianhui Xu wrote:
> The WL2868C is a camera power management IC with seven programmable LDOs.
> LDO1 and LDO2 share the VIN12 input, LDO3 and LDO4 share VIN34, and LDO5 to
> LDO7 have one input each. LDO1 and LDO2 cover 0.496 V to 1.512 V, the other
> five cover 1.504 V to 3.544 V, all in 8 mV steps.
>
> It is used on the Lenovo Legion Tab (TB322FC, SM8750), where the two camera
> sensors take their DVDD, AVDD and DOVDD rails from LDO1 to LDO5 and LDO7.
> Without this binding those supply references cannot be described, so the
> camera stack on that board cannot be brought up.
>
> Signed-off-by: Qianhui Xu <xiaqinghuan@mail.ustc.edu.cn>
Please respond to comments from previous version. And not with LLM. I
still see no users of this binding.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v2] regulator: dt-bindings: willsemi,wl2868c: add the WL2868C camera PMIC
2026-10-29 8:55 ` Krzysztof Kozlowski
@ 2026-10-31 3:39 ` Qianhui Xu
2026-10-31 5:29 ` Qianhui Xu
1 sibling, 0 replies; 10+ messages in thread
From: Qianhui Xu @ 2026-10-31 3:39 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Mark Brown, Liam Girdwood, Rob Herring, Conor Dooley, devicetree,
linux-kernel
Hi Krzysztof,
one thing about the earlier replies before the technical part. I am the
author of this series, but I work on this board alone and my English is
not good enough to write upstream mail unaided, so I draft with an AI
assistant and edit it myself; the content, measurements and decisions are
mine. You were right that the earlier replies read like generated text.
1) "Looks like broken patch. Please use git or b4 to generate patches."
The fault was in the commit message, not the diff: I had typed a
diffstat into the body, so the mail carried two. Since v2 the patches
are real commits on pristine v7.3-rc7, exported with git format-patch.
2) "where is any user of this? Why do we want this binding?"
The users are in patch 3/3, the board DTS for the Lenovo Legion Tab
(TB322FC, SM8750): eight "*-supply = <&camera_ldoN>" references, rear
s5kjns dvdd/dovdd/avdd = ldo1/ldo7/ldo4, front gc08a8 = ldo2/ldo7/ldo3,
rear gt9764 VCM vdd/vddio = ldo5/ldo7. LDO7 feeds three, LDO5 one,
LDO1 to LDO4 one each; LDO6 is not wired out. These are the camera
subsystem's own rails, without them the sensors cannot be described, and
they match the vendor DTS. You saw no users because I sent the binding
alone; v3 sends the three together.
3) "That's LLM output. Why do you paste it?", and your longer comment that
the reply was generated text.
Those points are fixed in v3: MAINTAINERS reads "WILLSEMI WL2868C CAMERA
PMIC" (no driver claim), sorted between WIIMOTE and WILOCITY, and
linux-media is dropped from its list.
4) "Please respond to comments from previous version." Done here and in
the v3 cover letter, together with Mark's v1 comments.
5) "I still see no users of this binding." See 2). If you would rather
review the users first, say so and I will reorder the series.
Measured on v7.3-rc7, rebuilt from the patch files alone: checkpatch
--strict 0 errors in all three (3/3 has 5 warnings: the three sensor/lens
compatibles below, one MAINTAINERS false positive, one "DT binding docs
should be a separate patch" for a qcom.yaml line); dt-doc-validate and
dt-check-style rc=0; the board DTB builds rc=0 with no DTC errors (v2 died
with 15 phandle errors from the missing clocks), the only remaining dtc
warnings being pre-existing in sm8750.dtsi; dt-validate on it rc=0, 7 lines
left, all missing s5kjns / gc08a8 / gt9764 bindings; driver W=1 clean.
Gaps I know of: vin12/vin34/vin5..7-supply are not wired in the board DTS
yet, so the driver falls back to dummy supplies; enable_time and
max_register come from the vendor driver only; nothing is measured on
hardware beyond boot.
Thanks for reading.
Qianhui Xu
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v3 0/3] regulator: add the WL2868C camera PMIC and its users
2026-10-28 12:04 [PATCH v2] regulator: dt-bindings: willsemi,wl2868c: add the WL2868C camera PMIC Qianhui Xu
2026-10-29 8:55 ` Krzysztof Kozlowski
@ 2026-10-31 3:42 ` Qianhui Xu
2026-10-31 3:42 ` [PATCH v3 1/3] regulator: dt-bindings: willsemi,wl2868c: add the WL2868C camera PMIC Qianhui Xu
` (2 more replies)
1 sibling, 3 replies; 10+ messages in thread
From: Qianhui Xu @ 2026-10-31 3:42 UTC (permalink / raw)
To: Mark Brown, Liam Girdwood
Cc: Krzysztof Kozlowski, Rob Herring, Conor Dooley, Bjorn Andersson,
devicetree, linux-kernel, linux-arm-msm
regulator: add the WL2868C camera PMIC and its users
Hi all,
this series adds a driver for the WL2868C camera PMIC found on the Lenovo
Legion Tab (TB322FC / "elden", SM8750). The chip is an I2C regulator with
seven LDOs; on this board eight supplies are wired to the camera stack
(S5KJNS sensor, GC08A8 sensor, GT9764 VCM, and the CSIPHY rails).
Changes since v2:
- Bind the board clocks the camera regulator nodes depend on. The board
DTS now defines xo_board, sleep_clk and the two CXO/2 fixed-factor
clocks by reusing the existing definitions from sm8750-mtp.dts, so the
DTB links cleanly instead of failing with 15 phandle errors.
- Register the board compatible in arm/qcom.yaml.
- Fix the reset description in the driver commit message: the GPIO is
released (active-low) during probe and asserted on unbind, which is what
GPIOD_OUT_LOW plus the devm action actually do.
The binding and driver are unchanged in behaviour since v2 apart from
the commit message correction. The camera sensor and lens bindings the
board DTS also references are not part of this series; they are being
submitted separately.
Qianhui Xu (3):
regulator: dt-bindings: willsemi,wl2868c: add the WL2868C camera PMIC
regulator: willsemi,wl2868c: add the WL2868C camera PMIC driver
arm64: dts: qcom: sm8750-lenovo-elden: describe the WL2868C regulators
.../devicetree/bindings/arm/qcom.yaml | 1 +
.../bindings/regulator/willsemi,wl2868c.yaml | 79 +++++++
MAINTAINERS | 7 +
arch/arm64/boot/dts/qcom/Makefile | 1 +
.../boot/dts/qcom/sm8750-lenovo-elden.dts | 202 ++++++++++++++++++
arch/arm64/boot/dts/qcom/sm8750.dtsi | 112 ++++++++++
drivers/regulator/Kconfig | 11 +
drivers/regulator/Makefile | 1 +
drivers/regulator/wl2868c-regulator.c | 155 ++++++++++++++
9 files changed, 569 insertions(+)
create mode 100644 Documentation/devicetree/bindings/regulator/willsemi,wl2868c.yaml
create mode 100644 arch/arm64/boot/dts/qcom/sm8750-lenovo-elden.dts
create mode 100644 drivers/regulator/wl2868c-regulator.c
--
2.53.0
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v3 1/3] regulator: dt-bindings: willsemi,wl2868c: add the WL2868C camera PMIC
2026-10-31 3:42 ` [PATCH v3 0/3] regulator: add the WL2868C camera PMIC and its users Qianhui Xu
@ 2026-10-31 3:42 ` Qianhui Xu
2026-10-31 3:42 ` [PATCH v3 2/3] regulator: willsemi,wl2868c: add the WL2868C camera PMIC driver Qianhui Xu
2026-10-31 3:43 ` [PATCH v3 3/3] arm64: dts: qcom: sm8750-lenovo-elden: describe the WL2868C regulators Qianhui Xu
2 siblings, 0 replies; 10+ messages in thread
From: Qianhui Xu @ 2026-10-31 3:42 UTC (permalink / raw)
To: Mark Brown, Liam Girdwood
Cc: Krzysztof Kozlowski, Rob Herring, Conor Dooley, Bjorn Andersson,
devicetree, linux-kernel, linux-arm-msm
The WL2868C is an I2C-controlled camera power management IC from Will
Semiconductor. It provides seven programmable LDOs: LDO1 and LDO2 are
fed from a shared VIN12 input and cover 0.496 V to 1.512 V, LDO3 and
LDO4 share VIN34, and LDO5 to LDO7 each have their own input, covering
1.504 V to 3.544 V. All outputs are programmable in 8 mV steps and are
gated by per-output enable bits with a chip-wide SYS_EN master. The
chip also exposes an optional active-low RST_N input.
Its user on the Lenovo Legion Tab (TB322FC, SM8750) is the camera
subsystem: the rear samsung,s5kjns sensor takes DVDD from LDO1, AVDD
from LDO4 and DOVDD from LDO7, the front galaxycore,gc08a8 sensor
takes DVDD from LDO2, AVDD from LDO3 and DOVDD from LDO7, and the
rear giantec,gt9764 voice coil motor takes VDD from LDO5 and VDDIO
from LDO7. The third patch of this series describes the board wiring
that carries these eight supply references; LDO6 is the only unused
output.
Signed-off-by: Qianhui Xu <xiaqinghuan@mail.ustc.edu.cn>
---
.../bindings/regulator/willsemi,wl2868c.yaml | 79 +++++++++++++++++++
MAINTAINERS | 6 ++
2 files changed, 85 insertions(+)
diff --git a/Documentation/devicetree/bindings/regulator/willsemi,wl2868c.yaml b/Documentation/devicetree/bindings/regulator/willsemi,wl2868c.yaml
new file mode 100644
index 0000000000..96541870cd
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/willsemi,wl2868c.yaml
@@ -0,0 +1,79 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/regulator/willsemi,wl2868c.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Will Semiconductor WL2868C camera power management IC
+
+maintainers:
+ - Qianhui Xu <xiaqinghuan@mail.ustc.edu.cn>
+
+description:
+ The WL2868C is a camera power management IC with seven programmable LDOs.
+ LDO1 and LDO2 share the VIN12 input and cover 0.496 V to 1.512 V; LDO3 and
+ LDO4 share VIN34, and LDO5 to LDO7 have one input each, covering 1.504 V to
+ 3.544 V. All outputs are programmable in 8 mV steps.
+
+properties:
+ compatible:
+ const: willsemi,wl2868c
+
+ reg:
+ maxItems: 1
+
+ reset-gpios:
+ maxItems: 1
+ description: Active-low RST_N input.
+
+ vin12-supply:
+ description: Input supply for LDO1 and LDO2.
+
+ vin34-supply:
+ description: Input supply for LDO3 and LDO4.
+
+ vin5-supply:
+ description: Input supply for LDO5.
+
+ vin6-supply:
+ description: Input supply for LDO6.
+
+ vin7-supply:
+ description: Input supply for LDO7.
+
+ regulators:
+ type: object
+ additionalProperties: false
+
+ patternProperties:
+ "^ldo[1-7]$":
+ type: object
+ $ref: regulator.yaml#
+ unevaluatedProperties: false
+
+required:
+ - compatible
+ - reg
+ - regulators
+
+additionalProperties: false
+
+examples:
+ - |
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pmic@2f {
+ compatible = "willsemi,wl2868c";
+ reg = <0x2f>;
+
+ regulators {
+ ldo1 {
+ regulator-max-microvolt = <1128000>;
+ regulator-min-microvolt = <1128000>;
+ };
+ };
+ };
+ };
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index f53047aa8d..632b17b3ea 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -29413,6 +29413,12 @@ L: linux-input@vger.kernel.org
S: Maintained
F: drivers/hid/hid-wiimote*
+WILLSEMI WL2868C CAMERA PMIC
+M: Qianhui Xu <xiaqinghuan@mail.ustc.edu.cn>
+L: linux-kernel@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/regulator/willsemi,wl2868c.yaml
+
WILOCITY WIL6210 WIRELESS DRIVER
L: linux-wireless@vger.kernel.org
S: Orphan
--
2.53.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v3 2/3] regulator: willsemi,wl2868c: add the WL2868C camera PMIC driver
2026-10-31 3:42 ` [PATCH v3 0/3] regulator: add the WL2868C camera PMIC and its users Qianhui Xu
2026-10-31 3:42 ` [PATCH v3 1/3] regulator: dt-bindings: willsemi,wl2868c: add the WL2868C camera PMIC Qianhui Xu
@ 2026-10-31 3:42 ` Qianhui Xu
2026-10-31 3:43 ` [PATCH v3 3/3] arm64: dts: qcom: sm8750-lenovo-elden: describe the WL2868C regulators Qianhui Xu
2 siblings, 0 replies; 10+ messages in thread
From: Qianhui Xu @ 2026-10-31 3:42 UTC (permalink / raw)
To: Mark Brown, Liam Girdwood
Cc: Krzysztof Kozlowski, Rob Herring, Conor Dooley, Bjorn Andersson,
devicetree, linux-kernel, linux-arm-msm
The WL2868C is an I2C camera power management IC with seven LDOs.
LDO1 and LDO2 are fed from VIN12 and cover 0.496 V to 1.512 V with a
7-bit voltage selector; LDO3 and LDO4 share VIN34, and LDO5 to LDO7
have one input each, covering 1.504 V to 3.544 V with an 8-bit
selector. All outputs step by 8 mV.
Every output is gated by a per-LDO bit in the enable register, and the
whole chip is additionally gated by the SYS_EN bit in the same
register. The driver sets SYS_EN together with the LDO bit on enable
and requires both to read back before reporting the regulator as
enabled, because no output comes up while SYS_EN is clear. An
optional active-low RST_N GPIO is released during probe, followed by
a 1 ms delay for the device to come up, and is asserted again when
the driver is unbound.
The device is used on the Lenovo Legion Tab (TB322FC, SM8750): the
rear camera (samsung,s5kjns) takes DVDD from LDO1, AVDD from LDO4 and
DOVDD from LDO7, the front camera (galaxycore,gc08a8) takes DVDD from
LDO2, AVDD from LDO3 and DOVDD from LDO7, and the rear VCM
(giantec,gt9764) takes VDD from LDO5 and VDDIO from LDO7. The next
patch wires these supplies up in the board file.
Signed-off-by: Qianhui Xu <xiaqinghuan@mail.ustc.edu.cn>
---
MAINTAINERS | 1 +
drivers/regulator/Kconfig | 11 ++
drivers/regulator/Makefile | 1 +
drivers/regulator/wl2868c-regulator.c | 155 ++++++++++++++++++++++++++
4 files changed, 168 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index 632b17b3ea..a334308798 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -29418,6 +29418,7 @@ M: Qianhui Xu <xiaqinghuan@mail.ustc.edu.cn>
L: linux-kernel@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/regulator/willsemi,wl2868c.yaml
+F: drivers/regulator/wl2868c-regulator.c
WILOCITY WIL6210 WIRELESS DRIVER
L: linux-wireless@vger.kernel.org
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 89789ac7a7..53f5b1527f 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -1858,6 +1858,17 @@ config REGULATOR_VQMMC_IPQ4019
This driver provides support for the VQMMC LDO I/0
voltage regulator of the IPQ4019 SD/EMMC controller.
+config REGULATOR_WL2868C
+ tristate "Will Semiconductor WL2868C regulator"
+ depends on I2C
+ select REGMAP_I2C
+ help
+ Support the seven LDO outputs of the Will Semiconductor WL2868C
+ camera power management IC.
+
+ To compile this driver as a module, choose M here: the
+ module will be called wl2868c-regulator.
+
config REGULATOR_WM831X
tristate "Wolfson Microelectronics WM831x PMIC regulators"
depends on MFD_WM831X
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 5a764cec8d..d706959588 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -212,6 +212,7 @@ obj-$(CONFIG_REGULATOR_RZG2L_VBCTRL) += renesas-usb-vbus-regulator.o
obj-$(CONFIG_REGULATOR_VCTRL) += vctrl-regulator.o
obj-$(CONFIG_REGULATOR_VEXPRESS) += vexpress-regulator.o
obj-$(CONFIG_REGULATOR_VQMMC_IPQ4019) += vqmmc-ipq4019-regulator.o
+obj-$(CONFIG_REGULATOR_WL2868C) += wl2868c-regulator.o
obj-$(CONFIG_REGULATOR_WM831X) += wm831x-dcdc.o
obj-$(CONFIG_REGULATOR_WM831X) += wm831x-isink.o
obj-$(CONFIG_REGULATOR_WM831X) += wm831x-ldo.o
diff --git a/drivers/regulator/wl2868c-regulator.c b/drivers/regulator/wl2868c-regulator.c
new file mode 100644
index 0000000000..9c4f4240b1
--- /dev/null
+++ b/drivers/regulator/wl2868c-regulator.c
@@ -0,0 +1,155 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Will Semiconductor WL2868C seven-channel camera regulator driver.
+ *
+ * Copyright (C) 2026 Qianhui Xu
+ */
+
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+#include <linux/regulator/driver.h>
+
+#define WL2868C_DEVICE_ID 0x00
+#define WL2868C_DEVICE_ID_VALUE 0x82
+#define WL2868C_LDO_ENABLE 0x0e
+#define WL2868C_SYS_ENABLE BIT(7)
+
+static int wl2868c_enable(struct regulator_dev *rdev)
+{
+ /*
+ * SYS_EN is the master enable of the chip: no output comes up unless
+ * it is set together with the per-LDO bit.
+ */
+ return regmap_update_bits(rdev->regmap, WL2868C_LDO_ENABLE,
+ WL2868C_SYS_ENABLE | rdev->desc->enable_mask,
+ WL2868C_SYS_ENABLE | rdev->desc->enable_mask);
+}
+
+static int wl2868c_is_enabled(struct regulator_dev *rdev)
+{
+ unsigned int mask = WL2868C_SYS_ENABLE | rdev->desc->enable_mask;
+ unsigned int value;
+ int ret;
+
+ ret = regmap_read(rdev->regmap, WL2868C_LDO_ENABLE, &value);
+ if (ret)
+ return ret;
+
+ return (value & mask) == mask;
+}
+
+static const struct regulator_ops wl2868c_ops = {
+ .list_voltage = regulator_list_voltage_linear,
+ .map_voltage = regulator_map_voltage_linear,
+ .set_voltage_sel = regulator_set_voltage_sel_regmap,
+ .get_voltage_sel = regulator_get_voltage_sel_regmap,
+ .enable = wl2868c_enable,
+ .disable = regulator_disable_regmap,
+ .is_enabled = wl2868c_is_enabled,
+};
+
+/*
+ * LDO1 and LDO2 have a 7-bit voltage selector, the other five have an 8-bit
+ * one; all of them step by 8 mV.
+ */
+#define WL2868C_LDO(_num, _supply, _min, _n_voltages, _vsel_reg, _mask, _en) { \
+ .name = "ldo" #_num, \
+ .of_match = "ldo" #_num, \
+ .regulators_node = "regulators", \
+ .id = (_num) - 1, \
+ .type = REGULATOR_VOLTAGE, \
+ .owner = THIS_MODULE, \
+ .ops = &wl2868c_ops, \
+ .supply_name = _supply, \
+ .min_uV = _min, \
+ .uV_step = 8000, \
+ .n_voltages = _n_voltages, \
+ .vsel_reg = _vsel_reg, \
+ .vsel_mask = _mask, \
+ .enable_reg = WL2868C_LDO_ENABLE, \
+ .enable_mask = _en, \
+ .enable_time = 150, \
+}
+
+static const struct regulator_desc wl2868c_regulators[] = {
+ WL2868C_LDO(1, "vin12", 496000, 128, 0x03, 0x7f, BIT(0)),
+ WL2868C_LDO(2, "vin12", 496000, 128, 0x04, 0x7f, BIT(1)),
+ WL2868C_LDO(3, "vin34", 1504000, 256, 0x05, 0xff, BIT(2)),
+ WL2868C_LDO(4, "vin34", 1504000, 256, 0x06, 0xff, BIT(3)),
+ WL2868C_LDO(5, "vin5", 1504000, 256, 0x07, 0xff, BIT(4)),
+ WL2868C_LDO(6, "vin6", 1504000, 256, 0x08, 0xff, BIT(5)),
+ WL2868C_LDO(7, "vin7", 1504000, 256, 0x09, 0xff, BIT(6)),
+};
+
+static const struct regmap_config wl2868c_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .max_register = 0x25,
+};
+
+static void wl2868c_reset(void *data)
+{
+ gpiod_set_value_cansleep(data, 1);
+}
+
+static int wl2868c_probe(struct i2c_client *client)
+{
+ struct device *dev = &client->dev;
+ struct regulator_config config = { .dev = dev };
+ struct regulator_dev *rdev;
+ struct gpio_desc *reset;
+ unsigned int id;
+ int ret, i;
+
+ reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
+ if (IS_ERR(reset))
+ return dev_err_probe(dev, PTR_ERR(reset), "Failed to get reset GPIO\n");
+
+ if (reset) {
+ ret = devm_add_action_or_reset(dev, wl2868c_reset, reset);
+ if (ret)
+ return ret;
+ fsleep(1000);
+ }
+
+ config.regmap = devm_regmap_init_i2c(client, &wl2868c_regmap_config);
+ if (IS_ERR(config.regmap))
+ return dev_err_probe(dev, PTR_ERR(config.regmap),
+ "Failed to create regmap\n");
+
+ ret = regmap_read(config.regmap, WL2868C_DEVICE_ID, &id);
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to read device ID\n");
+ if (id != WL2868C_DEVICE_ID_VALUE)
+ return dev_err_probe(dev, -ENODEV, "Unexpected device ID: %#x\n", id);
+
+ for (i = 0; i < ARRAY_SIZE(wl2868c_regulators); i++) {
+ rdev = devm_regulator_register(dev, &wl2868c_regulators[i], &config);
+ if (IS_ERR(rdev))
+ return dev_err_probe(dev, PTR_ERR(rdev),
+ "Failed to register LDO%d\n", i + 1);
+ }
+
+ return 0;
+}
+
+static const struct of_device_id wl2868c_of_match[] = {
+ { .compatible = "willsemi,wl2868c" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, wl2868c_of_match);
+
+static struct i2c_driver wl2868c_driver = {
+ .driver = {
+ .name = "wl2868c",
+ .of_match_table = wl2868c_of_match,
+ },
+ .probe = wl2868c_probe,
+};
+module_i2c_driver(wl2868c_driver);
+
+MODULE_DESCRIPTION("Will Semiconductor WL2868C regulator driver");
+MODULE_LICENSE("GPL");
--
2.53.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v3 3/3] arm64: dts: qcom: sm8750-lenovo-elden: describe the WL2868C regulators
2026-10-31 3:42 ` [PATCH v3 0/3] regulator: add the WL2868C camera PMIC and its users Qianhui Xu
2026-10-31 3:42 ` [PATCH v3 1/3] regulator: dt-bindings: willsemi,wl2868c: add the WL2868C camera PMIC Qianhui Xu
2026-10-31 3:42 ` [PATCH v3 2/3] regulator: willsemi,wl2868c: add the WL2868C camera PMIC driver Qianhui Xu
@ 2026-10-31 3:43 ` Qianhui Xu
2026-10-31 4:00 ` sashiko-bot
2 siblings, 1 reply; 10+ messages in thread
From: Qianhui Xu @ 2026-10-31 3:43 UTC (permalink / raw)
To: Mark Brown, Liam Girdwood
Cc: Krzysztof Kozlowski, Rob Herring, Conor Dooley, Bjorn Andersson,
devicetree, linux-kernel, linux-arm-msm
The Lenovo Legion Tab (TB322FC) is an SM8750 tablet. Its camera
devices are powered by a WL2868C camera PMIC on i2c10: LDO1 feeds the
rear sensor DVDD, LDO2 the front sensor DVDD, LDO3 the front sensor
AVDD, LDO4 the rear sensor AVDD, LDO5 the VCM VDD, LDO7 the DOVDD of
both sensors and the VCM VDDIO, all at fixed voltages including the
offsets programmed by the stock firmware. LDO6 is not wired out on
this board.
The camera devices hang off the two CCI I2C controllers, which the
SM8750 dtsi does not describe yet, so add them alongside. The sensors
are described with their supplies only for now; the CSI endpoints
will be added together with the camera subsystem.
The board clocks (XO, sleep clock and the two divided CXO derivatives)
that the SM8750 dtsi consumes are described here, as done on the other
SM8750 boards, and the board compatible is added to qcom.yaml.
Signed-off-by: Qianhui Xu <xiaqinghuan@mail.ustc.edu.cn>
---
.../devicetree/bindings/arm/qcom.yaml | 1 +
arch/arm64/boot/dts/qcom/Makefile | 1 +
.../boot/dts/qcom/sm8750-lenovo-elden.dts | 202 ++++++++++++++++++
arch/arm64/boot/dts/qcom/sm8750.dtsi | 112 ++++++++++
4 files changed, 316 insertions(+)
diff --git a/Documentation/devicetree/bindings/arm/qcom.yaml b/Documentation/devicetree/bindings/arm/qcom.yaml
index ff8a35df78..41d5e65c4e 100644
--- a/Documentation/devicetree/bindings/arm/qcom.yaml
+++ b/Documentation/devicetree/bindings/arm/qcom.yaml
@@ -1168,6 +1168,7 @@ properties:
- items:
- enum:
+ - lenovo,elden
- qcom,sm8750-mtp
- qcom,sm8750-qrd
- const: qcom,sm8750
diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile
index 1c86e7e98f..a18fea7beb 100644
--- a/arch/arm64/boot/dts/qcom/Makefile
+++ b/arch/arm64/boot/dts/qcom/Makefile
@@ -406,6 +406,7 @@ dtb-$(CONFIG_ARCH_QCOM) += sm8650-hdk-rear-camera-card.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm8650-hdk.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm8650-mtp.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm8650-qrd.dtb
+dtb-$(CONFIG_ARCH_QCOM) += sm8750-lenovo-elden.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm8750-mtp.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm8750-qrd.dtb
dtb-$(CONFIG_ARCH_QCOM) += talos-evk.dtb
diff --git a/arch/arm64/boot/dts/qcom/sm8750-lenovo-elden.dts b/arch/arm64/boot/dts/qcom/sm8750-lenovo-elden.dts
new file mode 100644
index 0000000000..7bbc1986a8
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sm8750-lenovo-elden.dts
@@ -0,0 +1,202 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2026, Qianhui Xu <xiaqinghuan@mail.ustc.edu.cn>
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "sm8750.dtsi"
+
+/ {
+ model = "Lenovo Legion Y700 Gen4";
+ compatible = "lenovo,elden", "qcom,sm8750";
+ chassis-type = "tablet";
+
+ clocks {
+ xo_board: xo-board {
+ compatible = "fixed-clock";
+ clock-frequency = <76800000>;
+ #clock-cells = <0>;
+ };
+
+ sleep_clk: sleep-clk {
+ compatible = "fixed-clock";
+ clock-frequency = <32000>;
+ #clock-cells = <0>;
+ };
+
+ bi_tcxo_div2: bi-tcxo-div2-clk {
+ compatible = "fixed-factor-clock";
+ #clock-cells = <0>;
+
+ clocks = <&rpmhcc RPMH_CXO_CLK>;
+ clock-mult = <1>;
+ clock-div = <2>;
+ };
+
+ bi_tcxo_ao_div2: bi-tcxo-ao-div2-clk {
+ compatible = "fixed-factor-clock";
+ #clock-cells = <0>;
+
+ clocks = <&rpmhcc RPMH_CXO_CLK_A>;
+ clock-mult = <1>;
+ clock-div = <2>;
+ };
+ };
+};
+
+&cci0 {
+ status = "okay";
+};
+
+&cci0_i2c0 {
+ clock-frequency = <400000>;
+
+ rear_lens: lens@c {
+ compatible = "giantec,gt9764";
+ reg = <0x0c>;
+ vddio-supply = <&camera_ldo7>;
+ vdd-supply = <&camera_ldo5>;
+ giantec,aac-mode = <0x40>;
+ giantec,aac-timing = <0x7c>;
+ settling-time-us = <7000>;
+ };
+
+ rear_camera: camera@56 {
+ compatible = "samsung,s5kjns";
+ reg = <0x56>;
+ clocks = <&cambistmclkcc CAM_BIST_MCLK_CC_MCLK3_CLK>;
+ assigned-clocks = <&cambistmclkcc CAM_BIST_MCLK_CC_MCLK3_CLK>;
+ assigned-clock-rates = <19200000>;
+ power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+ reset-gpios = <&tlmm 11 GPIO_ACTIVE_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&rear_camera_default>;
+ dovdd-supply = <&camera_ldo7>;
+ dvdd-supply = <&camera_ldo1>;
+ avdd-supply = <&camera_ldo4>;
+ lens-focus = <&rear_lens>;
+ orientation = <1>;
+ rotation = <90>;
+ };
+};
+
+&cci1 {
+ status = "okay";
+};
+
+&cci1_i2c0 {
+ clock-frequency = <400000>;
+
+ front_camera: camera@31 {
+ compatible = "galaxycore,gc08a8";
+ reg = <0x31>;
+ clocks = <&cambistmclkcc CAM_BIST_MCLK_CC_MCLK4_CLK>;
+ assigned-clocks = <&cambistmclkcc CAM_BIST_MCLK_CC_MCLK4_CLK>;
+ assigned-clock-rates = <19200000>;
+ power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+ reset-gpios = <&tlmm 7 GPIO_ACTIVE_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&front_camera_default>;
+ dovdd-supply = <&camera_ldo7>;
+ dvdd-supply = <&camera_ldo2>;
+ avdd-supply = <&camera_ldo3>;
+ orientation = <0>;
+ rotation = <270>;
+ };
+};
+
+&i2c10 {
+ status = "okay";
+
+ pmic@2f {
+ compatible = "willsemi,wl2868c";
+ reg = <0x2f>;
+ reset-gpios = <&tlmm 126 GPIO_ACTIVE_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&camera_pmic_default>;
+
+ regulators {
+ /* Voltages include the offsets programmed by stock firmware. */
+ camera_ldo1: ldo1 {
+ regulator-name = "camera_ldo1";
+ regulator-min-microvolt = <1128000>;
+ regulator-max-microvolt = <1128000>;
+ };
+
+ camera_ldo2: ldo2 {
+ regulator-name = "camera_ldo2";
+ regulator-min-microvolt = <1288000>;
+ regulator-max-microvolt = <1288000>;
+ };
+
+ camera_ldo3: ldo3 {
+ regulator-name = "camera_ldo3";
+ regulator-min-microvolt = <2816000>;
+ regulator-max-microvolt = <2816000>;
+ };
+
+ camera_ldo4: ldo4 {
+ regulator-name = "camera_ldo4";
+ regulator-min-microvolt = <2824000>;
+ regulator-max-microvolt = <2824000>;
+ };
+
+ camera_ldo5: ldo5 {
+ regulator-name = "camera_ldo5";
+ regulator-min-microvolt = <2808000>;
+ regulator-max-microvolt = <2808000>;
+ };
+
+ /* LDO6 is not wired out on this board. */
+ camera_ldo7: ldo7 {
+ regulator-name = "camera_ldo7";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+ };
+ };
+};
+
+&tlmm {
+ gpio-reserved-ranges = <39 1>, <74 1>;
+
+ camera_pmic_default: camera-pmic-default-state {
+ pins = "gpio126";
+ function = "gpio";
+ bias-disable;
+ };
+
+ rear_camera_default: rear-camera-default-state {
+ mclk-pins {
+ pins = "gpio92";
+ function = "cam_mclk";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ reset-pins {
+ pins = "gpio11";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ front_camera_default: front-camera-default-state {
+ mclk-pins {
+ pins = "gpio93";
+ function = "cam_aon_mclk4";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ reset-pins {
+ pins = "gpio7";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/sm8750.dtsi b/arch/arm64/boot/dts/qcom/sm8750.dtsi
index dd738d13df..60b8f2fb5a 100644
--- a/arch/arm64/boot/dts/qcom/sm8750.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8750.dtsi
@@ -3512,6 +3512,72 @@ camcc: clock-controller@ade0000 {
#power-domain-cells = <1>;
};
+ cci0: cci@ac7b000 {
+ compatible = "qcom,sm8750-cci", "qcom,msm8996-cci";
+ reg = <0x0 0x0ac7b000 0x0 0x1000>;
+ interrupts = <GIC_SPI 426 IRQ_TYPE_EDGE_RISING>;
+ power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+ clocks = <&camcc CAM_CC_CAM_TOP_AHB_CLK>,
+ <&camcc CAM_CC_CCI_0_CLK>;
+ clock-names = "ahb", "cci";
+ assigned-clocks = <&camcc CAM_CC_CCI_0_CLK>;
+ assigned-clock-rates = <37500000>;
+ pinctrl-0 = <&cci0_0_default>;
+ pinctrl-1 = <&cci0_0_sleep>;
+ pinctrl-names = "default", "sleep";
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cci0_i2c0: i2c-bus@0 {
+ reg = <0>;
+ clock-frequency = <400000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ cci0_i2c1: i2c-bus@1 {
+ status = "disabled";
+ reg = <1>;
+ clock-frequency = <400000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+
+ cci1: cci@ac7c000 {
+ compatible = "qcom,sm8750-cci", "qcom,msm8996-cci";
+ reg = <0x0 0x0ac7c000 0x0 0x1000>;
+ interrupts = <GIC_SPI 427 IRQ_TYPE_EDGE_RISING>;
+ power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+ clocks = <&camcc CAM_CC_CAM_TOP_AHB_CLK>,
+ <&camcc CAM_CC_CCI_1_CLK>;
+ clock-names = "ahb", "cci";
+ assigned-clocks = <&camcc CAM_CC_CCI_1_CLK>;
+ assigned-clock-rates = <37500000>;
+ pinctrl-0 = <&cci1_0_default>;
+ pinctrl-1 = <&cci1_0_sleep>;
+ pinctrl-names = "default", "sleep";
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cci1_i2c0: i2c-bus@0 {
+ reg = <0>;
+ clock-frequency = <400000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ cci1_i2c1: i2c-bus@1 {
+ status = "disabled";
+ reg = <1>;
+ clock-frequency = <400000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+
pdc: interrupt-controller@b220000 {
compatible = "qcom,sm8750-pdc", "qcom,pdc";
reg = <0x0 0x0b220000 0x0 0x10000>, <0x0 0x164400f0 0x0 0x64>;
@@ -4090,6 +4156,52 @@ qup_uart15_default: qup-uart15-default-state {
bias-pull-up;
};
+ cci0_0_default: cci0-0-default-state {
+ sda-pins {
+ pins = "gpio113";
+ function = "cci_i2c_sda";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+
+ scl-pins {
+ pins = "gpio114";
+ function = "cci_i2c_scl";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
+
+ cci0_0_sleep: cci0-0-sleep-state {
+ pins = "gpio113", "gpio114";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-pull-down;
+ };
+
+ cci1_0_default: cci1-0-default-state {
+ sda-pins {
+ pins = "gpio117";
+ function = "cci_i2c_sda";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+
+ scl-pins {
+ pins = "gpio118";
+ function = "cci_i2c_scl";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
+
+ cci1_0_sleep: cci1-0-sleep-state {
+ pins = "gpio117", "gpio118";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-pull-down;
+ };
+
sdc2_sleep: sdc2-sleep-state {
clk-pins {
pins = "sdc2_clk";
--
2.53.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH v3 3/3] arm64: dts: qcom: sm8750-lenovo-elden: describe the WL2868C regulators
2026-10-31 3:43 ` [PATCH v3 3/3] arm64: dts: qcom: sm8750-lenovo-elden: describe the WL2868C regulators Qianhui Xu
@ 2026-10-31 4:00 ` sashiko-bot
2026-10-31 5:27 ` Qianhui Xu
0 siblings, 1 reply; 10+ messages in thread
From: sashiko-bot @ 2026-10-31 4:00 UTC (permalink / raw)
To: Qianhui Xu; +Cc: devicetree, robh, conor+dt
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [High] arm64: dts: qcom: sm8750-lenovo-elden enables i2c10 with qupv3_2 disabled
- [Medium] arm64: dts: qcom: undocumented camera compatibles and incomplete sensor nodes
- [Low] arm64: dts: qcom: sm8750.dtsi CCI bus 1 disablement, missing pinctrl, and order
- [Low] arm64: dts: qcom: binding schema, SoC dtsi, and board dts mixed in one patch
--
commit 10e91e61ae688a3f035a983ab75359c04de72cc1
Author: Qianhui Xu <xiaqinghuan@mail.ustc.edu.cn>
arm64: dts: qcom: sm8750-lenovo-elden: describe the WL2868C regulators
This commit adds the device tree for the Lenovo Legion Y700 Gen4 (TB322FC)
tablet, describing the board clocks, WL2868C camera PMIC regulators on
i2c10, and camera sensor and lens nodes on the CCI buses, along with the
SM8750 CCI controller nodes and board compatible string.
> diff --git a/Documentation/devicetree/bindings/arm/qcom.yaml b/Documentation/devicetree/bindings/arm/qcom.yaml
> index ff8a35df7862d..41d5e65c4eea5 100644
> --- a/Documentation/devicetree/bindings/arm/qcom.yaml
> +++ b/Documentation/devicetree/bindings/arm/qcom.yaml
> @@ -1168,6 +1168,7 @@ properties:
>
> - items:
> - enum:
> + - lenovo,elden
> - qcom,sm8750-mtp
> - qcom,sm8750-qrd
> - const: qcom,sm8750
[Severity: Low]
This isn't a bug, but per Documentation/devicetree/bindings/submitting-patches.rst,
should the Documentation/devicetree/bindings/arm/qcom.yaml binding change,
the arch/arm64/boot/dts/qcom/sm8750.dtsi SoC additions, and the new
arch/arm64/boot/dts/qcom/sm8750-lenovo-elden.dts board file be split into
separate patches?
> diff --git a/arch/arm64/boot/dts/qcom/sm8750-lenovo-elden.dts b/arch/arm64/boot/dts/qcom/sm8750-lenovo-elden.dts
> new file mode 100644
> index 0000000000000..7bbc1986a87e6
> --- /dev/null
> +++ b/arch/arm64/boot/dts/qcom/sm8750-lenovo-elden.dts
> @@ -0,0 +1,202 @@
[ ... ]
> +&cci0_i2c0 {
> + clock-frequency = <400000>;
> +
> + rear_lens: lens@c {
> + compatible = "giantec,gt9764";
> + reg = <0x0c>;
> + vddio-supply = <&camera_ldo7>;
> + vdd-supply = <&camera_ldo5>;
> + giantec,aac-mode = <0x40>;
> + giantec,aac-timing = <0x7c>;
> + settling-time-us = <7000>;
> + };
> +
> + rear_camera: camera@56 {
> + compatible = "samsung,s5kjns";
> + reg = <0x56>;
> + clocks = <&cambistmclkcc CAM_BIST_MCLK_CC_MCLK3_CLK>;
> + assigned-clocks = <&cambistmclkcc CAM_BIST_MCLK_CC_MCLK3_CLK>;
> + assigned-clock-rates = <19200000>;
> + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
> + reset-gpios = <&tlmm 11 GPIO_ACTIVE_LOW>;
> + pinctrl-names = "default";
> + pinctrl-0 = <&rear_camera_default>;
> + dovdd-supply = <&camera_ldo7>;
> + dvdd-supply = <&camera_ldo1>;
> + avdd-supply = <&camera_ldo4>;
> + lens-focus = <&rear_lens>;
> + orientation = <1>;
> + rotation = <90>;
> + };
> +};
> +
> +&cci1 {
> + status = "okay";
> +};
> +
> +&cci1_i2c0 {
> + clock-frequency = <400000>;
> +
> + front_camera: camera@31 {
> + compatible = "galaxycore,gc08a8";
> + reg = <0x31>;
> + clocks = <&cambistmclkcc CAM_BIST_MCLK_CC_MCLK4_CLK>;
> + assigned-clocks = <&cambistmclkcc CAM_BIST_MCLK_CC_MCLK4_CLK>;
> + assigned-clock-rates = <19200000>;
> + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
> + reset-gpios = <&tlmm 7 GPIO_ACTIVE_LOW>;
> + pinctrl-names = "default";
> + pinctrl-0 = <&front_camera_default>;
> + dovdd-supply = <&camera_ldo7>;
> + dvdd-supply = <&camera_ldo2>;
> + avdd-supply = <&camera_ldo3>;
> + orientation = <0>;
> + rotation = <270>;
> + };
> +};
[Severity: Medium]
Will these camera and lens nodes pass dtbs_check?
In sm8750-lenovo-elden.dts, rear_lens (lens@c) uses compatible =
"giantec,gt9764" with vddio-supply, giantec,aac-mode, giantec,aac-timing, and
settling-time-us, rear_camera (camera@56) uses compatible = "samsung,s5kjns",
and front_camera (camera@31) uses compatible = "galaxycore,gc08a8". None of
these compatible strings or vendor properties are documented under
Documentation/devicetree/bindings/, and no in-tree driver currently binds to
them to consume the WL2868C regulator supplies.
In addition, both camera@56 and camera@31 omit the required CSI port endpoint
nodes and attach the SoC internal power-domains = <&camcc
CAM_CC_TITAN_TOP_GDSC> to external I2C camera sensors. Should these nodes be
deferred until their DT bindings and CSI endpoints are documented?
> +
> +&i2c10 {
> + status = "okay";
> +
> + pmic@2f {
> + compatible = "willsemi,wl2868c";
> + reg = <0x2f>;
[Severity: High]
Can i2c10 and pmic@2f ever probe on this board when qupv3_2 and gpi_dma2 are
still disabled?
In arch/arm64/boot/dts/qcom/sm8750.dtsi, i2c10 (i2c@888000) is a child of
qupv3_2 (geniqup@8c0000) and uses DMA channels from gpi_dma2
(dma-controller@800000), both of which default to status = "disabled":
arch/arm64/boot/dts/qcom/sm8750.dtsi:
gpi_dma2: dma-controller@800000 {
compatible = "qcom,sm8750-gpi-dma", "qcom,sm6350-gpi-dma";
...
status = "disabled";
};
qupv3_2: geniqup@8c0000 {
compatible = "qcom,geni-se-qup";
...
status = "disabled";
...
i2c10: i2c@888000 {
...
dmas = <&gpi_dma2 0 2 QCOM_GPI_I2C>,
<&gpi_dma2 1 2 QCOM_GPI_I2C>;
dma-names = "tx", "rx";
status = "disabled";
};
};
Child serial engines under a qcom,geni-se-qup node are only populated when
geni_se_probe() in drivers/soc/qcom/qcom-geni-se.c binds to an enabled
geniqup parent device, sets the wrapper drvdata, and calls
devm_of_platform_populate(dev):
drivers/soc/qcom/qcom-geni-se.c:geni_se_probe() {
...
dev_set_drvdata(dev, wrapper);
dev_dbg(dev, "GENI SE Driver probed\n");
return devm_of_platform_populate(dev);
}
Furthermore, geni_i2c_probe() -> setup_gpi_dma() in
drivers/i2c/busses/i2c-qcom-geni.c requires the parent wrapper drvdata and
gpi_dma2 channels when operating in GPI DMA mode. Because
sm8750-lenovo-elden.dts enables &i2c10 without enabling &qupv3_2 or
&gpi_dma2, qupv3_2 is skipped during device population, i2c10 is never
instantiated, and wl2868c_probe() never runs to register camera_ldo1 through
camera_ldo7. Should &qupv3_2 and &gpi_dma2 also be enabled in
sm8750-lenovo-elden.dts?
> diff --git a/arch/arm64/boot/dts/qcom/sm8750.dtsi b/arch/arm64/boot/dts/qcom/sm8750.dtsi
> index dd738d13df8e0..60b8f2fb5a350 100644
> --- a/arch/arm64/boot/dts/qcom/sm8750.dtsi
> +++ b/arch/arm64/boot/dts/qcom/sm8750.dtsi
> @@ -3512,6 +3512,72 @@ camcc: clock-controller@ade0000 {
> #power-domain-cells = <1>;
> };
>
> + cci0: cci@ac7b000 {
> + compatible = "qcom,sm8750-cci", "qcom,msm8996-cci";
> + reg = <0x0 0x0ac7b000 0x0 0x1000>;
> + interrupts = <GIC_SPI 426 IRQ_TYPE_EDGE_RISING>;
> + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
> + clocks = <&camcc CAM_CC_CAM_TOP_AHB_CLK>,
> + <&camcc CAM_CC_CCI_0_CLK>;
> + clock-names = "ahb", "cci";
> + assigned-clocks = <&camcc CAM_CC_CCI_0_CLK>;
> + assigned-clock-rates = <37500000>;
> + pinctrl-0 = <&cci0_0_default>;
> + pinctrl-1 = <&cci0_0_sleep>;
> + pinctrl-names = "default", "sleep";
> + status = "disabled";
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + cci0_i2c0: i2c-bus@0 {
> + reg = <0>;
> + clock-frequency = <400000>;
> + #address-cells = <1>;
> + #size-cells = <0>;
> + };
> +
> + cci0_i2c1: i2c-bus@1 {
> + status = "disabled";
> + reg = <1>;
> + clock-frequency = <400000>;
> + #address-cells = <1>;
> + #size-cells = <0>;
> + };
> + };
> +
> + cci1: cci@ac7c000 {
> + compatible = "qcom,sm8750-cci", "qcom,msm8996-cci";
> + reg = <0x0 0x0ac7c000 0x0 0x1000>;
> + interrupts = <GIC_SPI 427 IRQ_TYPE_EDGE_RISING>;
> + power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
> + clocks = <&camcc CAM_CC_CAM_TOP_AHB_CLK>,
> + <&camcc CAM_CC_CCI_1_CLK>;
> + clock-names = "ahb", "cci";
> + assigned-clocks = <&camcc CAM_CC_CCI_1_CLK>;
> + assigned-clock-rates = <37500000>;
> + pinctrl-0 = <&cci1_0_default>;
> + pinctrl-1 = <&cci1_0_sleep>;
> + pinctrl-names = "default", "sleep";
> + status = "disabled";
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + cci1_i2c0: i2c-bus@0 {
> + reg = <0>;
> + clock-frequency = <400000>;
> + #address-cells = <1>;
> + #size-cells = <0>;
> + };
> +
> + cci1_i2c1: i2c-bus@1 {
> + status = "disabled";
> + reg = <1>;
> + clock-frequency = <400000>;
> + #address-cells = <1>;
> + #size-cells = <0>;
> + };
> + };
[ ... ]
> @@ -4090,6 +4156,52 @@ qup_uart15_default: qup-uart15-default-state {
> bias-pull-up;
> };
>
> + cci0_0_default: cci0-0-default-state {
> + sda-pins {
> + pins = "gpio113";
> + function = "cci_i2c_sda";
> + drive-strength = <2>;
> + bias-pull-up;
> + };
[Severity: Low]
Is there a reason cci0_i2c1 and cci1_i2c1 are marked status = "disabled" in
sm8750.dtsi while cci0_i2c0 and cci1_i2c0 are left enabled, and bus 1 pinctrl
states (cci0_1 on gpio115/gpio116 and cci1_1 on gpio119/gpio120 in
drivers/pinctrl/qcom/pinctrl-sm8750.c) are omitted?
In drivers/i2c/busses/i2c-qcom-cci.c, cci_probe() iterates over child buses
with for_each_available_child_of_node_scoped(dev->of_node, child), and other
Qualcomm SoC dtsi files (such as sm8550.dtsi and sm8650.dtsi) leave both
i2c-bus@0 and i2c-bus@1 available with both bus pinctrl states defined while
the parent cci node is disabled. In addition, SM8750 has a third CCI
controller (CAM_CC_CCI_2_CLK in drivers/clk/qcom/camcc-sm8750.c and cci2 pins
in drivers/pinctrl/qcom/pinctrl-sm8750.c), whereas the commit message states
that the SoC has two CCI I2C controllers.
Also, in sm8750.dtsi, should cci0@ac7b000 and cci1@ac7c000 be placed in
unit-address order after videocc@aaf0000 rather than after mdss@ae00000,
dispcc@af00000, and camcc@ade0000, and should the cci0_0 and cci1_0 pinctrl
nodes in &tlmm be placed alphabetically before hub_i2c0_data_clk rather than
after qup_uart15_default?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261031034300.272730-1-xiaqinghuan@mail.ustc.edu.cn?part=3
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v3 3/3] arm64: dts: qcom: sm8750-lenovo-elden: describe the WL2868C regulators
2026-10-31 4:00 ` sashiko-bot
@ 2026-10-31 5:27 ` Qianhui Xu
0 siblings, 0 replies; 10+ messages in thread
From: Qianhui Xu @ 2026-10-31 5:27 UTC (permalink / raw)
To: sashiko-bot
Cc: Mark Brown, Liam Girdwood, Rob Herring, Conor Dooley,
Bjorn Andersson, Konrad Dybcio, devicetree, linux-arm-msm,
linux-kernel
One note on how this mail was written, since it matters for how you read
it: I work on this board alone and my English is not good enough to
write upstream mail unaided, so I draft with an AI assistant and edit it
myself. The content, the measurements and every decision in it are mine.
Four findings, and three of them are real. Taking them in your order.
[High] i2c10 enabled while qupv3_2 and gpi_dma2 are still disabled.
Confirmed, and it is the worst of the four: nothing in the patch enables the
parent, so geni_se_probe() never runs on qupv3_2, i2c10 is never populated,
wl2868c_probe() never runs, and none of camera_ldo1..camera_ldo7 exists at
runtime. That also means the twelve "*-supply = <&camera_ldoN>" references in
this same patch point at regulators that cannot be registered. v4 enables
both parents in the board DTS:
&qupv3_2 { status = "okay"; };
&gpi_dma2 { status = "okay"; };
I have not measured this on the board yet - it is a DTS-only change and I
will not claim it works until I have booted it and seen wl2868c probe.
[Medium] undocumented sensor/lens compatibles, missing CSI endpoints, and
power-domains on external sensors.
Partly accepted, and the parts that are not accepted need a different answer
than "fix it here":
- "giantec,gt9764" and "samsung,s5kjns" are documented, just not in this
series: the bindings were posted separately on 2026-10-27
(<20261027051048.213177-1-xiaqinghuan@mail.ustc.edu.cn>) and are still in
review. "galaxycore,gc08a8" has no binding posted at all. So the nodes
here reference one reviewed-pending and one non-existent binding, and
dtbs_check cannot pass for either in this series.
- the missing port/endpoint nodes are a real omission. Sensors without a
CSI endpoint cannot be connected to the CSID, which makes them decorative
in the current form.
- power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC> on an I2C sensor is wrong:
the GDSC belongs to the camera controller that owns the CCI bus, not to
the sensor, which is powered through its supplies and its reset GPIO.
Where I disagree is only about sequencing, not about the facts: the reason the
sensor and lens nodes are in this patch is that they are the consumers of the
regulators, and the binding reviewer asked for the users of the binding to be
shown. Dropping them makes the regulator series a binding with no consumer
again. So my plan for v4 is:
- keep this patch to qcom.yaml + the WL2868C node on i2c10 + the regulator
supplies that are genuinely wired on this board, and drop the sensor and
lens nodes until their bindings are in;
- carry the -supply wiring in the patch that adds each sensor, so every
consumer arrives with its own binding and its own endpoints;
- drop the sensor power-domains either way.
If you think that leaves the regulator series without a user, the honest
statement is that the user is the board DTS as a whole and it will land in
pieces; I would rather say that in the cover letter than ship nodes that
cannot bind.
[Low] cci0_i2c1 and cci1_i2c1 disabled while the bus0 siblings are enabled,
bus1 pinctrl omitted, node ordering, and "two CCI controllers" in the commit
message while the SoC has three.
Accepted on all four. v4 leaves both i2c-bus@0 and i2c-bus@1 available (as
sm8550.dtsi and sm8650.dtsi do), adds the cci0_1 / cci1_1 pinctrl states on
gpio115/116 and gpio119/120, moves the cci nodes to unit-address order after
videocc@aaf0000 with the pinctrl nodes alphabetical inside &tlmm, and the
commit message will say three controllers exist of which two are described.
[Low] binding schema, SoC dtsi and board DTS mixed in one patch.
Accepted, and checkpatch already told me the same thing in the same run (one
of the five warnings on 3/3 is "DT binding docs and includes should be a
separate patch"). v4 is qcom.yaml one patch, sm8750.dtsi one patch, board DTS
one patch.
Nothing above is measured except the DTS content itself; the probe of i2c10
and the runtime existence of the regulators are still unverified on hardware,
and I will report them as such in the v4 cover letter.
Thanks,
Qianhui Xu
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v2] regulator: dt-bindings: willsemi,wl2868c: add the WL2868C camera PMIC
2026-10-29 8:55 ` Krzysztof Kozlowski
2026-10-31 3:39 ` Qianhui Xu
@ 2026-10-31 5:29 ` Qianhui Xu
1 sibling, 0 replies; 10+ messages in thread
From: Qianhui Xu @ 2026-10-31 5:29 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Mark Brown, Liam Girdwood, Rob Herring, Conor Dooley, devicetree,
linux-kernel
Hi Krzysztof,
two corrections to what I sent you this morning, both measured after v3
went out, plus one thing I got wrong in the first reply.
First, how this mail is written: I draft with an AI assistant and edit it
myself; the content, the measurements and the decisions are mine. You
asked for that explicitly and it is a fair thing to ask.
1) v3 has a defect that makes the "users" argument weaker than I claimed.
sashiko's review of v3 3/3 is right: that patch enables i2c10 but never
enables its parents, so geni_se_probe() never runs on qupv3_2, i2c10 is
never populated, and the eight "*-supply = <&camera_ldoN>" phandles in the
same patch point at regulators that cannot register. So in the upstream
board file as posted, the consumers exist on paper only. v4 enables both
parents in the same patch:
&qupv3_2 { status = "okay"; };
&gpi_dma2 { status = "okay"; };
2) What I can show for the hardware today, stated precisely.
On our own downstream board DTS (a much larger file than the upstream
submission, which also enables the QUP) the driver does probe and the
regulators do appear, measured on the board running 7.3-rc7:
geni_i2c 888000.i2c: Bus frequency not specified, default to 100kHz.
[camera] loaded wl2868c-regulator
/sys/kernel/debug/regulator/: camera_ldo1 camera_ldo2 camera_ldo3
camera_ldo4 camera_ldo5 camera_ldo7
with camera_ldo1/2/3/4/5/7 at 1128/1288/2816/2824/2808/1800 mV (LDO6 has
no consumer on this board). That is the same wiring the upstream file
describes, just carried in the vendor-shaped file. It shows the chip
works and the supplies are real; it does not show that the two hundred
lines I am asking you to take bind, because they are not the same file.
3) On "I still see no users", the honest answer rather than the
convenient one.
The users are the camera stack: s5kjns, gc08a8, gt9764 and the CSIPHY
rails, eight supplies in total. Their bindings are not in this series -
the two sensor bindings were posted separately on 2026-10-27 and are still
in review, and gc08a8 has no binding posted at all. So the board file
cannot be complete, and dtbs_check cannot pass on those nodes, until those
land. My reading was that this is exactly why the regulator binding
should go in first, but I accept that from your side it reads as a binding
with no user, and I would rather say that plainly than keep shipping
sensor nodes that cannot bind.
What v4 will be, if you want to sanity check the shape before I post it:
- 1/3: arm/qcom.yaml registration plus the binding, unchanged in
behaviour from v3 apart from review comments.
- 2/3: sm8750.dtsi, the three DTSs split out as you and checkpatch both
asked (this one was mixed into the board patch in v3).
- 3/3: board DTS with qupv3_2, gpi_dma2, i2c10 and the WL2868C node, and
the eight supply references, but without the sensor and lens nodes.
- the sensor and lens nodes move into the patches that add those bindings,
each arriving with its own binding and its own CSI endpoints.
If you would rather not see the regulator series again until the sensor
bindings are in, say so and I will park it - that is a legitimate call and
I do not want to burn your review time on a series whose consumer side is
not ready.
Thanks,
Qianhui Xu
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2026-10-31 5:29 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-28 12:04 [PATCH v2] regulator: dt-bindings: willsemi,wl2868c: add the WL2868C camera PMIC Qianhui Xu
2026-10-29 8:55 ` Krzysztof Kozlowski
2026-10-31 3:39 ` Qianhui Xu
2026-10-31 5:29 ` Qianhui Xu
2026-10-31 3:42 ` [PATCH v3 0/3] regulator: add the WL2868C camera PMIC and its users Qianhui Xu
2026-10-31 3:42 ` [PATCH v3 1/3] regulator: dt-bindings: willsemi,wl2868c: add the WL2868C camera PMIC Qianhui Xu
2026-10-31 3:42 ` [PATCH v3 2/3] regulator: willsemi,wl2868c: add the WL2868C camera PMIC driver Qianhui Xu
2026-10-31 3:43 ` [PATCH v3 3/3] arm64: dts: qcom: sm8750-lenovo-elden: describe the WL2868C regulators Qianhui Xu
2026-10-31 4:00 ` sashiko-bot
2026-10-31 5:27 ` Qianhui Xu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox