* [PATCH v5 0/4] regulator: add the Will Semiconductor WL2868C camera PMIC
@ 2026-11-02 6:04 Qianhui Xu
2026-11-02 6:04 ` [PATCH v5 1/4] regulator: dt-bindings: willsemi,wl2868c: add the " Qianhui Xu
` (4 more replies)
0 siblings, 5 replies; 11+ messages in thread
From: Qianhui Xu @ 2026-11-02 6:04 UTC (permalink / raw)
To: linux-arm-msm, linux-regulator, devicetree
Cc: Liam Girdwood, Mark Brown, Konrad Dybcio, Bjorn Andersson,
Rob Herring, Conor Dooley, Krzysztof Kozlowski
This series was drafted with AI assistance; I reviewed and edited every
line myself, and I am responsible for its content, measurements and
decisions. Evidence for the review-driven changes below is listed in
the text.
The WL2868C is the camera PMIC on the Lenovo Legion Tab (TB322FC,
SM8750); its seven LDOs feed the rear camera, the front camera and the
VCM on i2c10.
Changes in v5:
- Sent as a new thread. v4 was sent with --in-reply-to pointing at the
v3 cover, which buried it in the old thread; every revision from now
on starts its own thread (Mark Brown).
- cci1 bus 1 sits on gpio111/gpio164, not on gpio119/gpio120: the
latter pair is cci2 bus 1. gpio111 and gpio164 are the two CCI pads
that the TLMM shares with cci_timer, while gpio119/120 are plain
cci_i2c pads, so having cci1 claim them would mux cci2's bus while
leaving cci1's own pads unmuxed (sashiko, High). Evidence: for
SM8750 the six CCI SDA pads are gpio111/112/113/115/117/119 and the
six SCL pads gpio114/116/118/120/153/164
(drivers/pinctrl/qcom/pinctrl-sm8750.c, the sm8750 pin groups);
Qualcomm's own SM8750 CCI submission assigns cci1_1 to
gpio111/164, cci2_0 to gpio112/153 and cci2_1 to gpio119/120
(https://lore.kernel.org/all/20260618-pakala-camera-v2-2-9fbb729fd242@oss.qualcomm.com/);
and the vendor DTB of our unit uses gpio113/114 for cci0 bus 0 and
gpio117/118 for cci1 bus 0, matching that table. The vendor
devicetree source itself is not available to us (the tree only
carries a dangling sm8750-devicetrees link), so the bus 1 mapping
rests on the two sources above.
- cci0_i2c1 and cci1_i2c1 no longer carry status = "disabled". The
parent CCI nodes claim the bus 1 pinctrl states, and cci_probe()
only registers available child buses, so disabling the children
while claiming their pads was inconsistent; both buses are now
described and available as on sm8550 and sm8650 (sashiko, Medium).
- The CCI pinctrl states are placed in alphabetical order inside the
TLMM node, before hub-i2c0-data-clk-state, with cci0-1 preceding
cci1-0 (sashiko, Low).
- The arm/qcom.yaml board compatible entry is no longer part of the
regulator binding patch; it moved to the board DTS patch, which is
what it documents (sashiko, Low). checkpatch still wants binding
files in their own patch, so 4/4 keeps that one warning.
- The board DTS keeps the scope of this series: camera PMIC and its
consumers only. The rest of the board enablement (SPMI PMICs
including the parents of the WL2868C inputs, console, storage)
cannot be validated on hardware here and is left to a separate board
series rather than being guessed. chassis-type was already present.
The rear lens and sensor nodes use the giantec,gt9764 and
samsung,s5kjns bindings that were posted separately to the media
list and are still under review, and their CSI endpoint has no
remote-endpoint until the SM8750 CAMSS nodes land; dtbs_check
reports "failed to match any schema" for the two compatibles until
those series are merged.
- Patch 1/4 (binding) and 2/4 (driver) are unchanged from v4 apart
from the qcom.yaml move.
Everything here is host-side only. The i2c10 probe and the runtime
existence of the regulators are still unverified on hardware; the
on-board evidence reported earlier (i2c-10 present, camera_ldo1..5,7
registered, LDO6 without consumer) comes from our own downstream board
DTS, not from the files in this series.
Qianhui Xu (4):
regulator: dt-bindings: willsemi,wl2868c: add the WL2868C camera PMIC
regulator: willsemi,wl2868c: add the WL2868C camera PMIC driver
arm64: dts: qcom: sm8750: describe two of the three CCI I2C
controllers
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 | 175 ++++++++++++++++++
arch/arm64/boot/dts/qcom/sm8750.dtsi | 156 ++++++++++++++++
drivers/regulator/Kconfig | 11 ++
drivers/regulator/Makefile | 1 +
drivers/regulator/wl2868c-regulator.c | 155 ++++++++++++++++
9 files changed, 586 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] 11+ messages in thread
* [PATCH v5 1/4] regulator: dt-bindings: willsemi,wl2868c: add the WL2868C camera PMIC
2026-11-02 6:04 [PATCH v5 0/4] regulator: add the Will Semiconductor WL2868C camera PMIC Qianhui Xu
@ 2026-11-02 6:04 ` Qianhui Xu
2026-11-02 6:04 ` [PATCH v5 2/4] regulator: willsemi,wl2868c: add the WL2868C camera PMIC driver Qianhui Xu
` (3 subsequent siblings)
4 siblings, 0 replies; 11+ messages in thread
From: Qianhui Xu @ 2026-11-02 6:04 UTC (permalink / raw)
To: linux-arm-msm, linux-regulator, devicetree
Cc: Liam Girdwood, Mark Brown, Konrad Dybcio, Bjorn Andersson,
Rob Herring, Conor Dooley, Krzysztof Kozlowski
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, and the rear giantec,gt9764 voice coil
motor takes VDD from LDO5 and VDDIO from LDO7. The front sensor is
powered from LDO2, LDO3 and LDO7, but its binding is still pending, so
its supply wiring follows with that series. The board DTS patch of this
series describes the supply wiring that is documented; LDO6 is the only
output with no user on this board.
Signed-off-by: Qianhui Xu <xiaqinghuan@mail.ustc.edu.cn>
---
.../bindings/regulator/willsemi,wl2868c.yaml | 79 +++++++++++++++++++
1 file changed, 79 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 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>;
+ };
+ };
+ };
+ };
+...
--
2.53.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v5 2/4] regulator: willsemi,wl2868c: add the WL2868C camera PMIC driver
2026-11-02 6:04 [PATCH v5 0/4] regulator: add the Will Semiconductor WL2868C camera PMIC Qianhui Xu
2026-11-02 6:04 ` [PATCH v5 1/4] regulator: dt-bindings: willsemi,wl2868c: add the " Qianhui Xu
@ 2026-11-02 6:04 ` Qianhui Xu
2026-11-02 6:13 ` sashiko-bot
2026-11-02 6:04 ` [PATCH v5 3/4] arm64: dts: qcom: sm8750: describe two of the three CCI I2C controllers Qianhui Xu
` (2 subsequent siblings)
4 siblings, 1 reply; 11+ messages in thread
From: Qianhui Xu @ 2026-11-02 6:04 UTC (permalink / raw)
To: linux-arm-msm, linux-regulator, devicetree
Cc: Liam Girdwood, Mark Brown, Konrad Dybcio, Bjorn Andersson,
Rob Herring, Conor Dooley, Krzysztof Kozlowski
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, and the rear VCM (giantec,gt9764) takes VDD from LDO5
and VDDIO from LDO7. The front sensor takes DVDD from LDO2, AVDD from
LDO3 and DOVDD from LDO7, and its supply wiring follows with its
pending binding series. The next patch wires the documented supplies
up in the board file.
Signed-off-by: Qianhui Xu <xiaqinghuan@mail.ustc.edu.cn>
---
MAINTAINERS | 7 ++
drivers/regulator/Kconfig | 11 ++
drivers/regulator/Makefile | 1 +
drivers/regulator/wl2868c-regulator.c | 155 ++++++++++++++++++++++++++
4 files changed, 174 insertions(+)
create mode 100644 drivers/regulator/wl2868c-regulator.c
diff --git a/MAINTAINERS b/MAINTAINERS
index f53047aa8d..a334308798 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -29413,6 +29413,13 @@ 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
+F: drivers/regulator/wl2868c-regulator.c
+
WILOCITY WIL6210 WIRELESS DRIVER
L: linux-wireless@vger.kernel.org
S: Orphan
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] 11+ messages in thread
* [PATCH v5 3/4] arm64: dts: qcom: sm8750: describe two of the three CCI I2C controllers
2026-11-02 6:04 [PATCH v5 0/4] regulator: add the Will Semiconductor WL2868C camera PMIC Qianhui Xu
2026-11-02 6:04 ` [PATCH v5 1/4] regulator: dt-bindings: willsemi,wl2868c: add the " Qianhui Xu
2026-11-02 6:04 ` [PATCH v5 2/4] regulator: willsemi,wl2868c: add the WL2868C camera PMIC driver Qianhui Xu
@ 2026-11-02 6:04 ` Qianhui Xu
2026-11-02 6:19 ` sashiko-bot
2026-11-02 9:00 ` Konrad Dybcio
2026-11-02 6:04 ` [PATCH v5 4/4] arm64: dts: qcom: sm8750-lenovo-elden: describe the WL2868C regulators Qianhui Xu
2026-11-02 12:50 ` [PATCH v5 0/4] regulator: add the Will Semiconductor WL2868C camera PMIC Mark Brown
4 siblings, 2 replies; 11+ messages in thread
From: Qianhui Xu @ 2026-11-02 6:04 UTC (permalink / raw)
To: linux-arm-msm, linux-regulator, devicetree
Cc: Liam Girdwood, Mark Brown, Konrad Dybcio, Bjorn Andersson,
Rob Herring, Conor Dooley, Krzysztof Kozlowski
The SM8750 has three CCI I2C controllers; this dtsi describes the two
that the Qualcomm camera subsystem binds to on this SoC. Each controller
exposes two I2C buses; both buses are described and left available, as
on sm8550 and sm8650.
The TLMM pad assignment is cci0 bus 0 on gpio113/114, cci0 bus 1 on
gpio115/116, cci1 bus 0 on gpio117/118 and cci1 bus 1 on gpio111/164,
the last two being the pads shared with cci_timer. The remaining CCI
pads, gpio112/153 and gpio119/120, belong to cci2, which is not
described here.
The controller nodes are placed in unit-address order after
videocc@aaf0000, and the pinctrl states in alphabetical order inside
the TLMM node.
Signed-off-by: Qianhui Xu <xiaqinghuan@mail.ustc.edu.cn>
---
arch/arm64/boot/dts/qcom/sm8750.dtsi | 156 +++++++++++++++++++++++++++
1 file changed, 156 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/sm8750.dtsi b/arch/arm64/boot/dts/qcom/sm8750.dtsi
index dd738d13df..5f64912d55 100644
--- a/arch/arm64/boot/dts/qcom/sm8750.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8750.dtsi
@@ -3060,6 +3060,70 @@ videocc: clock-controller@aaf0000 {
#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 &cci0_1_default>;
+ pinctrl-1 = <&cci0_0_sleep &cci0_1_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 {
+ 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 &cci1_1_default>;
+ pinctrl-1 = <&cci1_0_sleep &cci1_1_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 {
+ reg = <1>;
+ clock-frequency = <400000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+
mdss: display-subsystem@ae00000 {
compatible = "qcom,sm8750-mdss";
reg = <0x0 0x0ae00000 0x0 0x1000>;
@@ -3633,6 +3697,98 @@ tlmm: pinctrl@f100000 {
gpio-ranges = <&tlmm 0 0 216>;
wakeup-parent = <&pdc>;
+ 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;
+ };
+
+ cci0_1_default: cci0-1-default-state {
+ sda-pins {
+ pins = "gpio115";
+ function = "cci_i2c_sda";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+
+ scl-pins {
+ pins = "gpio116";
+ function = "cci_i2c_scl";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
+
+ cci0_1_sleep: cci0-1-sleep-state {
+ pins = "gpio115", "gpio116";
+ 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;
+ };
+
+ cci1_1_default: cci1-1-default-state {
+ sda-pins {
+ pins = "gpio111";
+ function = "cci_i2c_sda";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+
+ scl-pins {
+ pins = "gpio164";
+ function = "cci_i2c_scl";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
+
+ cci1_1_sleep: cci1-1-sleep-state {
+ pins = "gpio111", "gpio164";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-pull-down;
+ };
+
hub_i2c0_data_clk: hub-i2c0-data-clk-state {
/* SDA, SCL */
pins = "gpio64", "gpio65";
--
2.53.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v5 4/4] arm64: dts: qcom: sm8750-lenovo-elden: describe the WL2868C regulators
2026-11-02 6:04 [PATCH v5 0/4] regulator: add the Will Semiconductor WL2868C camera PMIC Qianhui Xu
` (2 preceding siblings ...)
2026-11-02 6:04 ` [PATCH v5 3/4] arm64: dts: qcom: sm8750: describe two of the three CCI I2C controllers Qianhui Xu
@ 2026-11-02 6:04 ` Qianhui Xu
2026-11-02 6:19 ` sashiko-bot
2026-11-02 8:59 ` Konrad Dybcio
2026-11-02 12:50 ` [PATCH v5 0/4] regulator: add the Will Semiconductor WL2868C camera PMIC Mark Brown
4 siblings, 2 replies; 11+ messages in thread
From: Qianhui Xu @ 2026-11-02 6:04 UTC (permalink / raw)
To: linux-arm-msm, linux-regulator, devicetree
Cc: Liam Girdwood, Mark Brown, Konrad Dybcio, Bjorn Andersson,
Rob Herring, Conor Dooley, Krzysztof Kozlowski
The Lenovo Legion Y700 Gen4 (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. LDO2 and LDO3 are wired to
the front sensor, whose binding is still pending, so its node follows
with that series. LDO6 is not wired out on this board.
The rear camera hangs off cci0 with the VCM. The front camera hangs
off cci1 and arrives together with its binding. The rear sensor and VCM
compatibles are the ones documented by the bindings sent separately to
the media list; the CSI endpoint receiver follows with the SM8750 CAMSS
series, which is why the endpoint has no remote-endpoint yet.
i2c10 is a GENI I2C controller inside the qupv3_2 wrapper, so both
qupv3_2 and its gpi_dma2 parent are enabled alongside, otherwise
i2c10 never populates and the regulators would never register.
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. The board compatible is added to arm/qcom.yaml here, as
it documents this board and not the regulator binding.
The file is otherwise limited to the camera PMIC and its consumers: the
rest of the board enablement (SPMI PMICs including the parents of the
WL2868C inputs, console and storage) cannot be validated on hardware in
this series and is left to a separate board series.
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 | 175 ++++++++++++++++++
3 files changed, 177 insertions(+)
create mode 100644 arch/arm64/boot/dts/qcom/sm8750-lenovo-elden.dts
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..de186b4477
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sm8750-lenovo-elden.dts
@@ -0,0 +1,175 @@
+// 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>;
+ 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>;
+
+ port {
+ rear_camera_ep: endpoint {
+ data-lanes = <1 2 3 4>;
+ link-frequencies = /bits/ 64 <672000000>;
+ };
+ };
+ };
+};
+
+&gpi_dma2 {
+ status = "okay";
+};
+
+&qupv3_2 {
+ status = "okay";
+};
+
+&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;
+ };
+ };
+};
--
2.53.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH v5 2/4] regulator: willsemi,wl2868c: add the WL2868C camera PMIC driver
2026-11-02 6:04 ` [PATCH v5 2/4] regulator: willsemi,wl2868c: add the WL2868C camera PMIC driver Qianhui Xu
@ 2026-11-02 6:13 ` sashiko-bot
0 siblings, 0 replies; 11+ messages in thread
From: sashiko-bot @ 2026-11-02 6:13 UTC (permalink / raw)
To: Qianhui Xu, devicetree; +Cc: robh, conor+dt
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] regulator: wl2868c: wl2868c_enable() activates other LDOs with preset bits
--
commit 90fe2a3492ce0c2ca1434cba3d7a67c4de55955e
Author: Qianhui Xu <xiaqinghuan@mail.ustc.edu.cn>
regulator: willsemi,wl2868c: add the WL2868C camera PMIC driver
This commit adds a regulator driver for the Will Semiconductor WL2868C
I2C camera PMIC supporting its seven LDO outputs, shared SYS_EN master
enable bit, and optional reset GPIO.
> diff --git a/drivers/regulator/wl2868c-regulator.c b/drivers/regulator/wl2868c-regulator.c
> new file mode 100644
> index 0000000000000..9c4f4240b1de1
> --- /dev/null
> +++ b/drivers/regulator/wl2868c-regulator.c
> @@ -0,0 +1,155 @@
[ ... ]
> +#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;
> +}
[Severity: Medium]
If WL2868C_SYS_ENABLE is initially clear while one or more per-LDO bits in
WL2868C_LDO_ENABLE are set (for example, from pre-probe state when the
optional reset GPIO is absent), won't enabling a single LDO in
wl2868c_enable() unintentionally turn on those other LDOs as well?
While WL2868C_SYS_ENABLE is 0, wl2868c_is_enabled() returns 0 for every LDO
regardless of its per-LDO bit, so regulator_late_cleanup() sees those LDOs
as already disabled and does not call ops->disable() to clear their bits in
WL2868C_LDO_ENABLE.
When a consumer later enables one regulator via
_regulator_enable() -> _regulator_do_enable() -> wl2868c_enable(),
regmap_update_bits() sets WL2868C_SYS_ENABLE | rdev->desc->enable_mask while
preserving the other bits in WL2868C_LDO_ENABLE. Any other LDO with its bit
already set then becomes active in hardware and starts reporting enabled via
wl2868c_is_enabled() despite having rdev->use_count == 0, which also causes
a later _regulator_enable() on that LDO to see _regulator_is_enabled(rdev) > 0
and skip _regulator_do_enable() along with its 150 us enable_time delay.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261102060458.461372-1-xiaqinghuan@mail.ustc.edu.cn?part=2
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v5 4/4] arm64: dts: qcom: sm8750-lenovo-elden: describe the WL2868C regulators
2026-11-02 6:04 ` [PATCH v5 4/4] arm64: dts: qcom: sm8750-lenovo-elden: describe the WL2868C regulators Qianhui Xu
@ 2026-11-02 6:19 ` sashiko-bot
2026-11-02 8:59 ` Konrad Dybcio
1 sibling, 0 replies; 11+ messages in thread
From: sashiko-bot @ 2026-11-02 6:19 UTC (permalink / raw)
To: Qianhui Xu, devicetree; +Cc: robh, conor+dt
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [Medium] arm64: dts: qcom: undocumented camera/lens compatibles and unlinked endpoint
- [Medium] arm64: dts: qcom: new sm8750-lenovo-elden board DT lacks boot infrastructure
- [Low] arm64: dts: qcom: mix of DT binding schema change and board DTS in one commit
--
commit 247a3e361ec98ef920ebf8c9ec415c99b8590dce
Author: Qianhui Xu <xiaqinghuan@mail.ustc.edu.cn>
arm64: dts: qcom: sm8750-lenovo-elden: describe the WL2868C regulators
This commit adds the lenovo,elden compatible to the Qualcomm ARM board
bindings and introduces a device tree for the Lenovo Legion Y700 Gen4
(SM8750) describing its board clocks, WL2868C camera PMIC regulators, and
rear camera sensor and lens.
> 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
> diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile
> index 1c86e7e98f55d..a18fea7bebaf7 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
[Severity: Low]
Should the Documentation/devicetree/bindings/arm/qcom.yaml schema change be
split into a separate prerequisite patch with a dt-bindings: subject prefix
rather than combined in the same commit as the arch/arm64/boot/dts/qcom/
changes, per Documentation/devicetree/bindings/submitting-patches.rst?
[ ... ]
> 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..de186b447725d
> --- /dev/null
> +++ b/arch/arm64/boot/dts/qcom/sm8750-lenovo-elden.dts
> @@ -0,0 +1,175 @@
> +// 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";
[ ... ]
> +&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>;
> + 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>;
> +
> + port {
> + rear_camera_ep: endpoint {
> + data-lanes = <1 2 3 4>;
> + link-frequencies = /bits/ 64 <672000000>;
> + };
> + };
> + };
> +};
[Severity: Medium]
As reported by Sashiko on v4 [1], does adding rear_lens (lens@c) and
rear_camera (camera@56) under &cci0_i2c0 in
arch/arm64/boot/dts/qcom/sm8750-lenovo-elden.dts cause make dtbs_check and
scripts/checkpatch.pl regressions because their bindings are not in the tree?
Specifically, rear_lens uses compatible = "giantec,gt9764" with properties
vddio-supply, giantec,aac-mode, giantec,aac-timing, and settling-time-us,
while Documentation/devicetree/bindings/media/i2c/dongwoon,dw9768.yaml only
documents dongwoon,dw9768 and giantec,gt9769 with vin-supply, vdd-supply,
dongwoon,aac-mode, and dongwoon,aac-timing.
Similarly, rear_camera uses compatible = "samsung,s5kjns" with dovdd-supply,
dvdd-supply, and avdd-supply, which are not documented in any in-tree schema
(Documentation/devicetree/bindings/media/i2c/samsung,s5kjn1.yaml only
documents samsung,s5kjn1 with vdda-supply, vddd-supply, vddio-supply, and
afvdd-supply).
In addition, rear_camera_ep defines a port endpoint without a remote-endpoint
property because sm8750.dtsi does not yet have a CAMSS or CSIPHY receiver
node. Should rear_lens and rear_camera be deferred until their DT bindings
and the SM8750 CAMSS receiver nodes are present in the tree, just as was done
for the front sensor?
> +
> +&gpi_dma2 {
> + status = "okay";
> +};
> +
> +&qupv3_2 {
> + status = "okay";
> +};
> +
> +&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>;
[Severity: Medium]
As reported by Sashiko on v4 [2], is it expected to introduce
arch/arm64/boot/dts/qcom/sm8750-lenovo-elden.dts as a new top-level board DTB
containing only clocks and camera I2C/PMIC nodes without the foundational
board infrastructure?
Unlike sm8750-mtp.dts and sm8750-qrd.dts, this file omits the SPMI PMICs,
RPMh regulators (&apps_rsc, including the vin12-supply, vin34-supply,
vin5-supply, and vin7-supply parent supplies for pmic@2f itself), chosen
stdout-path console, and boot storage peripherals, leaving a non-bootable
board DTB where the WL2868C regulator driver binds against dummy parent
supplies.
Also, in sm8750-lenovo-elden.dts, &qupv3_2 is placed before &i2c10 rather
than in alphabetical label order, and rear_lens places the standard property
settling-time-us after the vendor-specific giantec,aac-mode and
giantec,aac-timing properties. Should this patch wait for the base board
enablement series and follow the ordering rules in
Documentation/devicetree/bindings/dts-coding-style.rst?
[1] https://lore.kernel.org/r/9ef48d26aa4480b2dc1e20ad7af55f51aa22fec7.1793427041.git.xiaqinghuan@mail.ustc.edu.cn
[2] https://lore.kernel.org/r/9ef48d26aa4480b2dc1e20ad7af55f51aa22fec7.1793427041.git.xiaqinghuan@mail.ustc.edu.cn
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261102060458.461372-1-xiaqinghuan@mail.ustc.edu.cn?part=4
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v5 3/4] arm64: dts: qcom: sm8750: describe two of the three CCI I2C controllers
2026-11-02 6:04 ` [PATCH v5 3/4] arm64: dts: qcom: sm8750: describe two of the three CCI I2C controllers Qianhui Xu
@ 2026-11-02 6:19 ` sashiko-bot
2026-11-02 9:00 ` Konrad Dybcio
1 sibling, 0 replies; 11+ messages in thread
From: sashiko-bot @ 2026-11-02 6:19 UTC (permalink / raw)
To: Qianhui Xu, devicetree; +Cc: robh, conor+dt
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Medium] arm64: dts: qcom: sm8750: omission of cci2 controller and pinctrl states
- [Medium] arm64: dts: qcom: sm8750: CCI sleep pinctrl states mux pins to gpio
--
commit a65c21663abcd66908e315d4a351c0c64b9975c6
Author: Qianhui Xu <xiaqinghuan@mail.ustc.edu.cn>
arm64: dts: qcom: sm8750: describe two of the three CCI I2C controllers
This commit adds device tree nodes and TLMM pinctrl states for the cci0 and
cci1 Camera Control Interface (CCI) I2C controllers on the Qualcomm SM8750
SoC, leaving the third controller (cci2) undescribed.
> arm64: dts: qcom: sm8750: describe two of the three CCI I2C controllers
>
> The SM8750 has three CCI I2C controllers; this dtsi describes the two
> that the Qualcomm camera subsystem binds to on this SoC. Each controller
> exposes two I2C buses; both buses are described and left available, as
> on sm8550 and sm8650.
>
> The TLMM pad assignment is cci0 bus 0 on gpio113/114, cci0 bus 1 on
> gpio115/116, cci1 bus 0 on gpio117/118 and cci1 bus 1 on gpio111/164,
> the last two being the pads shared with cci_timer. The remaining CCI
> pads, gpio112/153 and gpio119/120, belong to cci2, which is not
> described here.
>
> The controller nodes are placed in unit-address order after
> videocc@aaf0000, and the pinctrl states in alphabetical order inside
> the TLMM node.
>
> Signed-off-by: Qianhui Xu <xiaqinghuan@mail.ustc.edu.cn>
>
> diff --git a/arch/arm64/boot/dts/qcom/sm8750.dtsi b/arch/arm64/boot/dts/qcom/sm8750.dtsi
> index dd738d13df8e0..5f64912d55eac 100644
> --- a/arch/arm64/boot/dts/qcom/sm8750.dtsi
> +++ b/arch/arm64/boot/dts/qcom/sm8750.dtsi
> @@ -3060,6 +3060,70 @@ videocc: clock-controller@aaf0000 {
[ ... ]
> + 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 &cci1_1_default>;
> + pinctrl-1 = <&cci1_0_sleep &cci1_1_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 {
> + reg = <1>;
> + clock-frequency = <400000>;
> + #address-cells = <1>;
> + #size-cells = <0>;
> + };
> + };
[Severity: Medium]
Why is cci2 (along with its cci2_0 and cci2_1 pinctrl states in tlmm) omitted
from arch/arm64/boot/dts/qcom/sm8750.dtsi?
The commit message notes that this dtsi describes the two controllers that the
Qualcomm camera subsystem binds to, as on sm8550 and sm8650. However, the
camera subsystem driver (drivers/media/platform/qcom/camss/) does not bind to
CCI controllers directly; drivers/i2c/busses/i2c-qcom-cci.c binds to each CCI
node independently, and camera sensors on any CCI bus connect to CAMSS CSIPHY
ports via OF graph endpoints.
Furthermore, both arch/arm64/boot/dts/qcom/sm8550.dtsi and
arch/arm64/boot/dts/qcom/sm8650.dtsi describe all three CCI controllers
(cci0, cci1, and cci2) and their TLMM pinctrl states so that board device
trees can enable whichever buses they route.
Since include/dt-bindings/clock/qcom,sm8750-camcc.h and
drivers/clk/qcom/camcc-sm8750.c already provide CAM_CC_CCI_2_CLK, and
drivers/pinctrl/qcom/pinctrl-sm8750.c already defines the cci_i2c_sda and
cci_i2c_scl mux functions for gpio112/gpio153 and gpio119/gpio120, should cci2
and its pinctrl states also be described here?
> mdss: display-subsystem@ae00000 {
> compatible = "qcom,sm8750-mdss";
> reg = <0x0 0x0ae00000 0x0 0x1000>;
> @@ -3633,6 +3697,98 @@ tlmm: pinctrl@f100000 {
> gpio-ranges = <&tlmm 0 0 216>;
> wakeup-parent = <&pdc>;
>
> + 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;
> + };
> +
> + cci0_1_default: cci0-1-default-state {
> + sda-pins {
> + pins = "gpio115";
> + function = "cci_i2c_sda";
> + drive-strength = <2>;
> + bias-pull-up;
> + };
> +
> + scl-pins {
> + pins = "gpio116";
> + function = "cci_i2c_scl";
> + drive-strength = <2>;
> + bias-pull-up;
> + };
> + };
> +
> + cci0_1_sleep: cci0-1-sleep-state {
> + pins = "gpio115", "gpio116";
> + 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;
> + };
> +
> + cci1_1_default: cci1-1-default-state {
> + sda-pins {
> + pins = "gpio111";
> + function = "cci_i2c_sda";
> + drive-strength = <2>;
> + bias-pull-up;
> + };
> +
> + scl-pins {
> + pins = "gpio164";
> + function = "cci_i2c_scl";
> + drive-strength = <2>;
> + bias-pull-up;
> + };
> + };
> +
> + cci1_1_sleep: cci1-1-sleep-state {
> + pins = "gpio111", "gpio164";
> + function = "gpio";
> + drive-strength = <2>;
> + bias-pull-down;
> + };
[Severity: Medium]
Should the cci0_0_sleep, cci0_1_sleep, cci1_0_sleep, and cci1_1_sleep states
keep the cci_i2c_sda and cci_i2c_scl functions in separate sda-pins and
scl-pins subnodes instead of switching function to "gpio"?
In other Qualcomm SoC device trees using split cci_i2c_sda and cci_i2c_scl
pinmux functions (such as arch/arm64/boot/dts/qcom/sm8550.dtsi,
arch/arm64/boot/dts/qcom/sm8650.dtsi, arch/arm64/boot/dts/qcom/milos.dtsi,
and arch/arm64/boot/dts/qcom/monaco.dtsi), the sleep states retain the
cci_i2c_sda and cci_i2c_scl mux functions and only switch the bias from
bias-pull-up to bias-pull-down:
arch/arm64/boot/dts/qcom/sm8650.dtsi:
cci0_0_sleep: cci0-0-sleep-state {
sda-pins {
pins = "gpio101";
function = "cci_i2c_sda";
drive-strength = <2>;
bias-pull-down;
};
scl-pins {
pins = "gpio102";
function = "cci_i2c_scl";
drive-strength = <2>;
bias-pull-down;
};
};
Switching the pins to function = "gpio" during runtime PM or system suspend
disconnects the pads from the CCI controller hardware block.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261102060458.461372-1-xiaqinghuan@mail.ustc.edu.cn?part=3
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v5 4/4] arm64: dts: qcom: sm8750-lenovo-elden: describe the WL2868C regulators
2026-11-02 6:04 ` [PATCH v5 4/4] arm64: dts: qcom: sm8750-lenovo-elden: describe the WL2868C regulators Qianhui Xu
2026-11-02 6:19 ` sashiko-bot
@ 2026-11-02 8:59 ` Konrad Dybcio
1 sibling, 0 replies; 11+ messages in thread
From: Konrad Dybcio @ 2026-11-02 8:59 UTC (permalink / raw)
To: Qianhui Xu, linux-arm-msm, linux-regulator, devicetree
Cc: Liam Girdwood, Mark Brown, Konrad Dybcio, Bjorn Andersson,
Rob Herring, Conor Dooley, Krzysztof Kozlowski
On 11/2/26 7:04 AM, Qianhui Xu wrote:
> The Lenovo Legion Y700 Gen4 (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. LDO2 and LDO3 are wired to
> the front sensor, whose binding is still pending, so its node follows
> with that series. LDO6 is not wired out on this board.
>
> The rear camera hangs off cci0 with the VCM. The front camera hangs
> off cci1 and arrives together with its binding. The rear sensor and VCM
> compatibles are the ones documented by the bindings sent separately to
> the media list; the CSI endpoint receiver follows with the SM8750 CAMSS
> series, which is why the endpoint has no remote-endpoint yet.
>
> i2c10 is a GENI I2C controller inside the qupv3_2 wrapper, so both
> qupv3_2 and its gpi_dma2 parent are enabled alongside, otherwise
> i2c10 never populates and the regulators would never register.
>
> 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. The board compatible is added to arm/qcom.yaml here, as
> it documents this board and not the regulator binding.
>
> The file is otherwise limited to the camera PMIC and its consumers: the
> rest of the board enablement (SPMI PMICs including the parents of the
> WL2868C inputs, console and storage) cannot be validated on hardware in
> this series and is left to a separate board series.
What's the reason for including it here then? You already gave us the
meaningful part of this as an example in dt-bindings
Konrad
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v5 3/4] arm64: dts: qcom: sm8750: describe two of the three CCI I2C controllers
2026-11-02 6:04 ` [PATCH v5 3/4] arm64: dts: qcom: sm8750: describe two of the three CCI I2C controllers Qianhui Xu
2026-11-02 6:19 ` sashiko-bot
@ 2026-11-02 9:00 ` Konrad Dybcio
1 sibling, 0 replies; 11+ messages in thread
From: Konrad Dybcio @ 2026-11-02 9:00 UTC (permalink / raw)
To: Qianhui Xu, linux-arm-msm, linux-regulator, devicetree
Cc: Liam Girdwood, Mark Brown, Konrad Dybcio, Bjorn Andersson,
Rob Herring, Conor Dooley, Krzysztof Kozlowski
On 11/2/26 7:04 AM, Qianhui Xu wrote:
> The SM8750 has three CCI I2C controllers; this dtsi describes the two
> that the Qualcomm camera subsystem binds to on this SoC. Each controller
> exposes two I2C buses; both buses are described and left available, as
> on sm8550 and sm8650.
>
> The TLMM pad assignment is cci0 bus 0 on gpio113/114, cci0 bus 1 on
> gpio115/116, cci1 bus 0 on gpio117/118 and cci1 bus 1 on gpio111/164,
> the last two being the pads shared with cci_timer. The remaining CCI
> pads, gpio112/153 and gpio119/120, belong to cci2, which is not
> described here.
>
> The controller nodes are placed in unit-address order after
> videocc@aaf0000, and the pinctrl states in alphabetical order inside
> the TLMM node.
>
> Signed-off-by: Qianhui Xu <xiaqinghuan@mail.ustc.edu.cn>
> ---
There's an identical patchset in flight, please don't send competing
series without a clear reason
https://lore.kernel.org/linux-arm-msm/20260618-pakala-camera-v2-2-9fbb729fd242@oss.qualcomm.com/
Konrad
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v5 0/4] regulator: add the Will Semiconductor WL2868C camera PMIC
2026-11-02 6:04 [PATCH v5 0/4] regulator: add the Will Semiconductor WL2868C camera PMIC Qianhui Xu
` (3 preceding siblings ...)
2026-11-02 6:04 ` [PATCH v5 4/4] arm64: dts: qcom: sm8750-lenovo-elden: describe the WL2868C regulators Qianhui Xu
@ 2026-11-02 12:50 ` Mark Brown
4 siblings, 0 replies; 11+ messages in thread
From: Mark Brown @ 2026-11-02 12:50 UTC (permalink / raw)
To: Qianhui Xu
Cc: linux-arm-msm, linux-regulator, devicetree, Liam Girdwood,
Konrad Dybcio, Bjorn Andersson, Rob Herring, Conor Dooley,
Krzysztof Kozlowski
[-- Attachment #1: Type: text/plain, Size: 355 bytes --]
On Mon, Nov 02, 2026 at 02:04:54PM +0800, Qianhui Xu wrote:
> This series was drafted with AI assistance; I reviewed and edited every
> line myself, and I am responsible for its content, measurements and
> decisions. Evidence for the review-driven changes below is listed in
> the text.
This doesn't apply against current code, please check and resend.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2026-11-02 12:50 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-02 6:04 [PATCH v5 0/4] regulator: add the Will Semiconductor WL2868C camera PMIC Qianhui Xu
2026-11-02 6:04 ` [PATCH v5 1/4] regulator: dt-bindings: willsemi,wl2868c: add the " Qianhui Xu
2026-11-02 6:04 ` [PATCH v5 2/4] regulator: willsemi,wl2868c: add the WL2868C camera PMIC driver Qianhui Xu
2026-11-02 6:13 ` sashiko-bot
2026-11-02 6:04 ` [PATCH v5 3/4] arm64: dts: qcom: sm8750: describe two of the three CCI I2C controllers Qianhui Xu
2026-11-02 6:19 ` sashiko-bot
2026-11-02 9:00 ` Konrad Dybcio
2026-11-02 6:04 ` [PATCH v5 4/4] arm64: dts: qcom: sm8750-lenovo-elden: describe the WL2868C regulators Qianhui Xu
2026-11-02 6:19 ` sashiko-bot
2026-11-02 8:59 ` Konrad Dybcio
2026-11-02 12:50 ` [PATCH v5 0/4] regulator: add the Will Semiconductor WL2868C camera PMIC Mark Brown
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.