[PATCH 3/4] media: i2c: vd55g1: Add ACPI support for the Lenovo TBE20A1 HID

From: Ruslan Koreev

Date: Thu Sep 24 2026 - 13:43:26 EST


The IR camera of the Lenovo ThinkPad X1 Carbon Gen 14 is an ST VD55G1
enumerated by ACPI as TBE20A1, connected to the Intel IPU7 with one
CSI-2 lane and powered through an INT3472 discrete device. Match the
HID and take the sensor version from the match data, as for OF. Only
the analog supply is switchable on this platform; vcore and vddio are
always on and fall back to dummy regulators.

On these platforms the CSI-2 endpoint is a software node that
ipu-bridge attaches to the sensor device when the IPU driver probes,
which can happen after the sensor driver has been bound. Defer probing
instead of failing when there is no endpoint yet, as the other sensor
drivers used with the IPU bridge do and as v4l2_fwnode_endpoint_parse()
itself does for a missing endpoint.

Tested on a ThinkPad X1 Carbon Gen 14 (Core Ultra X7 358H, IPU7),
streaming 804x704 through libcamera.

Signed-off-by: Ruslan Koreev <koreev.r@xxxxxxxxx>
---
drivers/media/i2c/vd55g1.c | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/drivers/media/i2c/vd55g1.c b/drivers/media/i2c/vd55g1.c
index 6f458f611..64889c35d 100644
--- a/drivers/media/i2c/vd55g1.c
+++ b/drivers/media/i2c/vd55g1.c
@@ -1903,10 +1903,9 @@ static int vd55g1_parse_dt(struct vd55g1 *sensor)

endpoint = fwnode_graph_get_endpoint_by_id(dev_fwnode(sensor->dev),
0, 0, 0);
- if (!endpoint) {
- dev_err(sensor->dev, "Endpoint node not found\n");
- return -EINVAL;
- }
+ if (!endpoint)
+ return dev_err_probe(sensor->dev, -EPROBE_DEFER,
+ "waiting for fwnode graph endpoint\n");

ret = vd55g1_check_csi_conf(sensor, endpoint);
fwnode_handle_put(endpoint);
@@ -2084,6 +2083,13 @@ static const struct of_device_id vd55g1_dt_ids[] = {
};
MODULE_DEVICE_TABLE(of, vd55g1_dt_ids);

+static const struct acpi_device_id vd55g1_acpi_ids[] = {
+ /* Lenovo ThinkPad X1 Carbon Gen 14 IR camera, Intel IPU7 */
+ { "TBE20A1", (kernel_ulong_t)&vd55g1_versions[0] },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(acpi, vd55g1_acpi_ids);
+
static const struct dev_pm_ops vd55g1_pm_ops = {
SET_RUNTIME_PM_OPS(vd55g1_power_off, vd55g1_power_on, NULL)
};
@@ -2092,6 +2098,7 @@ static struct i2c_driver vd55g1_i2c_driver = {
.driver = {
.name = "vd55g1",
.of_match_table = vd55g1_dt_ids,
+ .acpi_match_table = vd55g1_acpi_ids,
.pm = &vd55g1_pm_ops,
},
.probe = vd55g1_probe,
--
2.55.0