* [BUG] OV02C10 on Dell 16 Premium DA16250 (ARL): INT3472 handshake-derived "dvdd" regulator registered but never linked to sensor, sensor probe fails with -EREMOTEIO
@ 2026-06-01 14:06 Angioli Samuele (gmail)
2026-06-03 7:26 ` Marco Nenciarini
0 siblings, 1 reply; 6+ messages in thread
From: Angioli Samuele (gmail) @ 2026-06-01 14:06 UTC (permalink / raw)
To: linux-media
Cc: Hans de Goede, Ilpo Järvinen, Sakari Ailus, Marco Nenciarini,
Israel Cepeda, linux-kernel, platform-driver-x86
Hi all,
On a Dell 16 Premium (DA16250, Intel Core Ultra 7 255H, Arrow Lake-H)
with an OV02C10 IR camera sensor behind a Lattice NX33 USB-IO bridge
(2ac1:20c9), the integrated webcam does not work on a vanilla
v7.1-rc5 kernel. All required drivers are in-tree (usbio, gpio-usbio,
int3472-discrete with strobe / handshake support, ov02c10, ipu-bridge),
yet the sensor probe consistently fails with -EREMOTEIO at the
chip-ID read because its supplies fall back to dummy regulators.
Summary
=======
* INT3472:0c declares (among others) a HANDSHAKE GPIO (type 0x12) on
\_SB.PC00.XHCI.RHUB.HS09.VGPO pin 1 (USB-IO bridge gpiochip,
INTC10B2:00, 128 lines).
* int3472-discrete successfully acquires that pin (gpioinfo shows
`line 1: output consumer="dvdd"`) and registers a regulator named
`INT3472:0c-dvdd` with init_data.consumer_supplies set such that
`dev_name == "i2c-OVTI02C1:00"` and `supply == "dvdd"` (lower- and
upper-case forms, per
drivers/platform/x86/intel/int3472/clk_and_regulator.c:219).
* The OV02C10 sensor (ACPI HID OVTI02C1, i2c device dev_name
`i2c-OVTI02C1:00`) calls devm_regulator_bulk_get() for
"avdd"/"dvdd"/"dovdd" and gets the dummy regulator for *all three*,
including "dvdd". The chip-ID read at register 0x300a then returns
-EREMOTEIO and probe is aborted.
In other words: the regulator is correctly registered and the consumer
device exists with the matching dev_name, but the regulator core does
not link them; `regulator_summary` shows `INT3472:0c-dvdd` with
`use=0 open=0` and no children, while the sensor stays on dummy.
Hardware / software
===================
Machine : Dell 16 Premium DA16250
CPU : Intel Ultra 9 285H × 16
Camera sensor : OmniVision OV02C10 (ACPI HID OVTI02C1),
module id 'CJFME322D'
Power controller : INT3472:0c (discrete), ACPI status 15
GPIO provider : Lattice NX33 USB-IO bridge (USB 2ac1:20c9),
auxiliary HID INTC10B2 → gpiochip1, 128 lines
Distro / kernel : Manjaro Linux, kernel 7.1.0-rc5-1-MANJARO
(vanilla 7.1-rc5, no out-of-tree DKMS modules)
Relevant log excerpts
=====================
dmesg (initial failure):
ov02c10 i2c-OVTI02C1:00: supply dovdd not found, using dummy regulator
ov02c10 i2c-OVTI02C1:00: supply avdd not found, using dummy regulator
ov02c10 i2c-OVTI02C1:00: supply dvdd not found, using dummy regulator
ov02c10 i2c-OVTI02C1:00: Error reading reg 0x300a: -121
ov02c10 i2c-OVTI02C1:00: failed to find sensor: -121
ov02c10 i2c-OVTI02C1:00: probe with driver ov02c10 failed with error -121
dmesg with `module intel_skl_int3472_discrete dyndbg=+p` (selected,
duplicate retries during probe-deferral elided):
int3472-discrete INT3472:0c: Sensor module id: 'CJFME322D'
int3472-discrete INT3472:0c: dvdd \_SB.PC00.XHCI.RHUB.HS09.VGPO pin 1
active-high
[... ~30 deferral retries while gpio_usbio finishes coming up ...]
gpio_usbio.usbio-gpio usbio.usbio-gpio.0: [Firmware Bug]: GPIO 4 is not
in FW pins bitmap
int3472-discrete INT3472:0c: [Firmware Bug]: ir_flood \_SB.GPI0 pin
number mismatch _DSM 0 resource 352
int3472-discrete INT3472:0c: ir_flood \_SB.GPI0 pin 352 active-high
After int3472 finishes (probe returns 0):
$ sudo gpiodetect
gpiochip0 [INTC105E:00] (451 lines) # SoC GPIO
gpiochip1 [INTC10B2:00] (128 lines) # USB-IO bridge (Lattice NX33)
gpiochip2 [cs42l43-pinctrl] (3 lines)
$ sudo gpioinfo --chip gpiochip1 | head -3
gpiochip1 - 128 lines:
line 0: unnamed input
line 1: unnamed output consumer="dvdd"
$ sudo cat /sys/kernel/debug/regulator/regulator_summary | grep -A1 dvdd
INT3472:0c-dvdd 0 0 0 unknown 0mV 0mA 0mV 0mV
No consumers under INT3472:0c-dvdd. The ov02c10 i2c device exists at
the matching dev_name but gets the dummy regulator instead.
Suspected cause
===============
The HANDSHAKE case in int3472 was added (commit history under
drivers/platform/x86/intel/int3472/) on the assumption that registering
a regulator with init_data.consumer_supplies[].dev_name set to the
constructed i2c sensor name ("i2c-<ACPI HID>:<inst>") would be enough
for an ACPI-instantiated sensor i2c_client of that exact dev_name to
match via regulator_get(). On this DA16250 the device naming matches
(the dev_err prefix on ov02c10 is literally "i2c-OVTI02C1:00"), yet
the supply_map entry never fires and the consumer ends up bound to
the dummy supply.
Possible explanations:
(a) fwnode/of-based supply matching in the regulator core now takes
precedence over the legacy dev_name-based supply_map lookups, and
the sensor's fwnode (a software_node created by ipu-bridge) does
not reference the INT3472:0c regulator -> the supply_map is
shadowed and dummy is selected.
(b) The sensor i2c_client created via ipu-bridge has a slightly
different dev_name than what int3472 constructed via
I2C_DEV_NAME_FORMAT ("i2c-%s") at probe time (possibly due to
sw-fwnode instantiation differing from acpi_i2c enumeration).
I am happy to provide any further data — DSDT extract for INT3472:0c
(both _CRS and the _DSM result for the GPIO at \_SB.PC00.XHCI.RHUB.HS09.VGPO
pin 1), full dmesg, lsusb -v for 2ac1:20c9, and any patch test results.
Thanks,
Samuele
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [BUG] OV02C10 on Dell 16 Premium DA16250 (ARL): INT3472 handshake-derived "dvdd" regulator registered but never linked to sensor, sensor probe fails with -EREMOTEIO
2026-06-01 14:06 [BUG] OV02C10 on Dell 16 Premium DA16250 (ARL): INT3472 handshake-derived "dvdd" regulator registered but never linked to sensor, sensor probe fails with -EREMOTEIO Angioli Samuele (gmail)
@ 2026-06-03 7:26 ` Marco Nenciarini
2026-06-12 16:09 ` Angioli Samuele (gmail)
0 siblings, 1 reply; 6+ messages in thread
From: Marco Nenciarini @ 2026-06-03 7:26 UTC (permalink / raw)
To: Angioli Samuele, linux-media
Cc: Hans de Goede, ilpo.jarvinen, Sakari Ailus, Israel Cepeda,
linux-kernel, platform-driver-x86
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
Hi Samuele,
Thanks for the thorough report, the dmesg and the detail you included
made this easy to trace.
Both of your hypotheses turn out not to be the mechanism. The naming is
fine and the fwnode path is not shadowing anything. The dummy dvdd in
your log is real and is the key clue, but the interesting question is
how the sensor reached a regulator_get for dvdd at all.
> (a) fwnode/of-based supply matching in the regulator core now takes
> precedence over the legacy dev_name-based supply_map lookups
It does not shadow it. regulator_dev_lookup() tries the DT/fwnode path
first, but regulator_dt_lookup() only does anything when
dev_of_node(dev) is non-NULL. On ACPI there is no of_node, so it
returns NULL and the function falls through to the legacy
regulator_map_list walk. A software_node sensor with no regulator
phandle is therefore fine, provided the map entry exists at lookup
time.
> (b) The sensor i2c_client created via ipu-bridge has a slightly
> different dev_name
It does not. int3472->sensor_name is built as "i2c-" +
acpi_dev_name(sensor), i.e. "i2c-OVTI02C1:00", and that exact string
is planted into supply_map[].dev_name in
skl_int3472_register_regulator(). ACPI-enumerated i2c clients are named
the same way (dev_set_name(&client->dev, "i2c-%s", acpi_dev_name(adev))),
so the consumer dev_name is byte-identical. No mismatch.
What the log actually tells us. The line
ov02c10 i2c-OVTI02C1:00: supply dvdd not found, using dummy regulator
is emitted from a single site in _regulator_get_common(), on the
have_full_constraints() == true, NORMAL_GET path, and only after the
dummy_regulator_rdev existence check. So it means precisely this: at
the instant ov02c10 called devm_regulator_bulk_get(), the lookup for
"i2c-OVTI02C1:00"/dvdd returned -ENODEV, i.e. no INT3472:0c-dvdd
consumer map entry existed yet. int3472 publishes that map while
registering the regulator, during its own probe, and its whole probe
defers (the ~30 retries in your log) until the USB-IO bridge gpiochip
appears, because the dvdd HANDSHAKE GPIO lives on that chip. So
ov02c10 took a dummy dvdd before int3472 had registered the real one.
Under NORMAL_GET with full constraints that dummy is permanent, the
no-op enable leaves the rail unpowered, and the 0x300a read fails
with -EREMOTEIO, a hard error that is not placed on the deferred-probe
list and so is never retried when the real regulator appears later. It
is also consistent with regulator_summary showing INT3472:0c-dvdd with
no children after the fact.
(avdd and dovdd also fall back to dummies. If those rails are
always-on in hardware that is probably benign. dvdd is the one
INT3472:0c is meant to gate through the handshake pin, so that is the
one that matters here.)
Here is the part that needs your input, because it should not be
possible. INT3472 is in acpi_honor_dep_ids, so a sensor whose _DEP
references the INT3472 device is held out of enumeration entirely
(acpi_dev_ready_for_enumeration() returns false, the i2c client is not
even created) until int3472 clears the dependency. int3472-discrete
clears it with acpi_dev_clear_dependencies() as the last step of its
probe, after int3472_discrete_parse_crs() has registered every
regulator including dvdd. So in the normal flow, by the time OVTI02C1
can be enumerated at all, the dvdd map is already published and the
sensor binds the real rail. The fact that you got a dummy means that
gate did not serialize them on this board.
The most likely explanation is that OVTI02C1's _DEP does not carry an
honored dependency on the INT3472:0c instance that registers dvdd (or
there is more than one INT3472 instance and the depended-on one is not
the dvdd provider). To confirm, could you send:
- the OVTI02C1 _DEP (an acpidump or DSDT extract), so we can see
whether INT3472:0c is actually listed;
- a dmesg with timestamps showing the order of the int3472-discrete
bind, the i2c-OVTI02C1:00 device creation, and the dummy-regulator
warning;
- the INT3472:0c _CRS plus the _DSM result for the GPIO at
\_SB.PC00.XHCI.RHUB.HS09.VGPO pin 1, as you offered.
Hans, Sakari, this is where I would like your read. If the _DEP on
this board is indeed missing the INT3472:0c instance, is the right fix
a board quirk, or is it worth giving the ACPI consumer path a "supply
coming later" signal the way the DT path has one?
of_regulator_dev_lookup() returns -EPROBE_DEFER when the phandle
target is not registered yet; the legacy consumer_supplies/dev_name
map has no equivalent, so once the _DEP gate is out of the picture
there is nothing left to make the sensor wait.
Thanks,
Marco
-----BEGIN PGP SIGNATURE-----
iQIzBAEBCAAdFiEEfCO4BD5l0pgKIbbiWJ8D8BulUDgFAmof1vIACgkQWJ8D8Bul
UDhKsxAAhvXDzdrZLmLC+7kV5ORVVl0oEZxv/ylThq8xzkiPdkkkdCYcf0cF/Xgp
rH2LvTr/lqJjCL8P8S7ytzJ+8DCX7UpjnFy5AsyTJZGBa312eG9Ksrf9GMOJ5slL
r4KqKu8feyuQNgkaYKsxO342OSlPas5aAKVUIQeEUB+1Q2eQ4ffe5MR+Rdub9a5q
1SKIfmuAzs7DJc86gBYmA6wz7FEpmXNH3ugu3QLFLB7NlEQEHQIl8Jo3w5yt5GCi
Gs+0JgmydKkTmNpUJ4c13tXk+G3G8Um2fg6sgwIX/pOhjbPrrzpgZgwVGI/eZdfM
MKQ2qWYiMuDFsd3ZnXMyHrffIVMj2q/UB+ye2bAP3a9QsxubuvCaCGk+ksBRvtUk
4GE1MQ+yFVakru93ADfTJ+ASuyaVI6fVG9H4zt46up5z04DzGYSYhXAJSOfBCz6A
CRAkKBkTga8bHeqdt289kzgES+OIkX2XeE7eOl8JX+LoDIfQiLD7cbGynHNjR4mf
fjfBVwTmwRES+KC5+KLbsgrdCfpX0RCb8iBmQto7jxTUImKI3xMgmHYf51PYyqmA
/uSpYW1G4YwBGn8/9aI2P9FiQyQXdt6LTqBz+Ld9CxGiKUNvfj078lcZoa7Dq22n
5S14yapsNfoJbEyYhIshu2exu9rcW30DGSnloS1gTuIvz+e72hc=
=egB7
-----END PGP SIGNATURE-----
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [BUG] OV02C10 on Dell 16 Premium DA16250 (ARL): INT3472 handshake-derived "dvdd" regulator registered but never linked to sensor, sensor probe fails with -EREMOTEIO
2026-06-03 7:26 ` Marco Nenciarini
@ 2026-06-12 16:09 ` Angioli Samuele (gmail)
2026-06-13 17:01 ` Marco Nenciarini
0 siblings, 1 reply; 6+ messages in thread
From: Angioli Samuele (gmail) @ 2026-06-12 16:09 UTC (permalink / raw)
To: Marco Nenciarini, linux-media
Cc: Hans de Goede, ilpo.jarvinen, Sakari Ailus, Israel Cepeda,
linux-kernel, platform-driver-x86
[-- Attachment #1: Type: text/plain, Size: 7197 bytes --]
Hi Marco,
Sorry for the slow reply - I was away from the office until the 10th.
regulator_summary settles it - this is a missing consumer map, not an
ordering race.
INT3472:0c = \_SB.PC00.DSC0. Its _DEP is only the bridge gpiochip:
Name (_DEP, Package (){ ^XHCI.RHUB.HS09.VGPO })
so it defers ~28 times (t=5.816..6.127) until INTC10B2:00 appears
(t=6.135), then binds. Its _DSM (79234640-9e10-4fea-a5c1-b5aa8b19756f),
decoded with TYPE=[7:0], PIN=[15:8], SENSOR_ON=[31:24]:
func 2 -> 0x01000112 type 0x12 (handshake), pin 1, on=1 -> dvdd
func 3 -> 0x01000002 type 0x02 (strobe), pin 0, on=1 -> IR flood
The dvdd GPIO (func 2) is handled before the strobe (func 3), so it is
already processed by the time the "GPIO type 0x02 unknown" warning
fires at t=6.143.
regulator_summary shows the result:
INT3472:0c-dvdd 0 0 0 unknown 0mV ... (use=0 open=0)
The dvdd regulator IS registered, but with zero consumers - no supply
map to i2c-OVTI02C1:00 was ever created. So when ov02c10 probes at
t=6.468 (0.32s AFTER INT3472:0c bound and after the dvdd GPIO was
handled), regulator_get(dvdd) returns -ENODEV regardless of timing:
[6.468] ov02c10 i2c-OVTI02C1:00: supply dvdd not found, using dummy
regulator
[6.471] ov02c10 i2c-OVTI02C1:00: Error reading reg 0x300a: -121
[6.471] ov02c10 ... probe with driver ov02c10 failed with error -121
The dummy enable is a no-op, the rail stays down, the 0x300a read
fails -EREMOTEIO, and that hard error is never retried.
This means the handshake-derived regulator path registers the provider
without planting the consumer supply map the way the GPIO power-enable
path does in skl_int3472_register_regulator(). Adding that map
(dev_name "i2c-OVTI02C1:00", supply "dvdd") for the handshake type
should be enough; an -EPROBE_DEFER "supply coming later" signal would
not help here since the map is never created at all.
For completeness on the ordering side: LNK1's _DEP never references
DSC0 in any branch (ARLP -> {CVSS, HS09.VIC1}; non-ARLP -> {DSC1,
HS09.VIC1}), so there is also no serialization between DSC0 and the
sensor - but that is moot given the map is absent.
Tested on 7.0.10-1-MANJARO. Attached: decompiled
LNK1/DSC0 blocks, timestamped dmesg, and regulator_summary. Full
acpidump available on request (zip 1Mb).
Thanks,
Samuele
Il 03/06/26 09:26, Marco Nenciarini ha scritto:
> Hi Samuele,
>
> Thanks for the thorough report, the dmesg and the detail you included
> made this easy to trace.
>
> Both of your hypotheses turn out not to be the mechanism. The naming is
> fine and the fwnode path is not shadowing anything. The dummy dvdd in
> your log is real and is the key clue, but the interesting question is
> how the sensor reached a regulator_get for dvdd at all.
>
>> (a) fwnode/of-based supply matching in the regulator core now takes
>> precedence over the legacy dev_name-based supply_map lookups
>
> It does not shadow it. regulator_dev_lookup() tries the DT/fwnode path
> first, but regulator_dt_lookup() only does anything when
> dev_of_node(dev) is non-NULL. On ACPI there is no of_node, so it
> returns NULL and the function falls through to the legacy
> regulator_map_list walk. A software_node sensor with no regulator
> phandle is therefore fine, provided the map entry exists at lookup
> time.
>
>> (b) The sensor i2c_client created via ipu-bridge has a slightly
>> different dev_name
>
> It does not. int3472->sensor_name is built as "i2c-" +
> acpi_dev_name(sensor), i.e. "i2c-OVTI02C1:00", and that exact string
> is planted into supply_map[].dev_name in
> skl_int3472_register_regulator(). ACPI-enumerated i2c clients are named
> the same way (dev_set_name(&client->dev, "i2c-%s", acpi_dev_name(adev))),
> so the consumer dev_name is byte-identical. No mismatch.
>
> What the log actually tells us. The line
>
> ov02c10 i2c-OVTI02C1:00: supply dvdd not found, using dummy regulator
>
> is emitted from a single site in _regulator_get_common(), on the
> have_full_constraints() == true, NORMAL_GET path, and only after the
> dummy_regulator_rdev existence check. So it means precisely this: at
> the instant ov02c10 called devm_regulator_bulk_get(), the lookup for
> "i2c-OVTI02C1:00"/dvdd returned -ENODEV, i.e. no INT3472:0c-dvdd
> consumer map entry existed yet. int3472 publishes that map while
> registering the regulator, during its own probe, and its whole probe
> defers (the ~30 retries in your log) until the USB-IO bridge gpiochip
> appears, because the dvdd HANDSHAKE GPIO lives on that chip. So
> ov02c10 took a dummy dvdd before int3472 had registered the real one.
> Under NORMAL_GET with full constraints that dummy is permanent, the
> no-op enable leaves the rail unpowered, and the 0x300a read fails
> with -EREMOTEIO, a hard error that is not placed on the deferred-probe
> list and so is never retried when the real regulator appears later. It
> is also consistent with regulator_summary showing INT3472:0c-dvdd with
> no children after the fact.
>
> (avdd and dovdd also fall back to dummies. If those rails are
> always-on in hardware that is probably benign. dvdd is the one
> INT3472:0c is meant to gate through the handshake pin, so that is the
> one that matters here.)
>
> Here is the part that needs your input, because it should not be
> possible. INT3472 is in acpi_honor_dep_ids, so a sensor whose _DEP
> references the INT3472 device is held out of enumeration entirely
> (acpi_dev_ready_for_enumeration() returns false, the i2c client is not
> even created) until int3472 clears the dependency. int3472-discrete
> clears it with acpi_dev_clear_dependencies() as the last step of its
> probe, after int3472_discrete_parse_crs() has registered every
> regulator including dvdd. So in the normal flow, by the time OVTI02C1
> can be enumerated at all, the dvdd map is already published and the
> sensor binds the real rail. The fact that you got a dummy means that
> gate did not serialize them on this board.
>
> The most likely explanation is that OVTI02C1's _DEP does not carry an
> honored dependency on the INT3472:0c instance that registers dvdd (or
> there is more than one INT3472 instance and the depended-on one is not
> the dvdd provider). To confirm, could you send:
>
> - the OVTI02C1 _DEP (an acpidump or DSDT extract), so we can see
> whether INT3472:0c is actually listed;
> - a dmesg with timestamps showing the order of the int3472-discrete
> bind, the i2c-OVTI02C1:00 device creation, and the dummy-regulator
> warning;
> - the INT3472:0c _CRS plus the _DSM result for the GPIO at
> \_SB.PC00.XHCI.RHUB.HS09.VGPO pin 1, as you offered.
>
> Hans, Sakari, this is where I would like your read. If the _DEP on
> this board is indeed missing the INT3472:0c instance, is the right fix
> a board quirk, or is it worth giving the ACPI consumer path a "supply
> coming later" signal the way the DT path has one?
> of_regulator_dev_lookup() returns -EPROBE_DEFER when the phandle
> target is not registered yet; the legacy consumer_supplies/dev_name
> map has no equivalent, so once the _DEP gate is out of the picture
> there is nothing left to make the sensor wait.
>
> Thanks,
> Marco
[-- Attachment #2: 02_dmesg-filtered.txt --]
[-- Type: text/plain, Size: 5814 bytes --]
938:[ 5.799818] intel-ipu6 0000:00:05.0: enabling device (0000 -> 0002)
942:[ 5.816292] int3472-discrete INT3472:0c: cannot find GPIO chip INTC10B2:00, deferring
943:[ 5.816646] intel-ipu6 0000:00:05.0: Found supported sensor OVTI02C1:00
944:[ 5.816717] intel-ipu6 0000:00:05.0: Connected 1 cameras
946:[ 5.821653] intel-ipu6 0000:00:05.0: Sending BOOT_LOAD to CSE
948:[ 5.831222] int3472-discrete INT3472:0c: cannot find GPIO chip INTC10B2:00, deferring
951:[ 5.839669] int3472-discrete INT3472:0c: cannot find GPIO chip INTC10B2:00, deferring
956:[ 5.848704] int3472-discrete INT3472:0c: cannot find GPIO chip INTC10B2:00, deferring
958:[ 5.854569] int3472-discrete INT3472:0c: cannot find GPIO chip INTC10B2:00, deferring
959:[ 5.858057] intel-ipu6 0000:00:05.0: Sending AUTHENTICATE_RUN to CSE
961:[ 5.867711] int3472-discrete INT3472:0c: cannot find GPIO chip INTC10B2:00, deferring
962:[ 5.869356] int3472-discrete INT3472:0c: cannot find GPIO chip INTC10B2:00, deferring
963:[ 5.872391] int3472-discrete INT3472:0c: cannot find GPIO chip INTC10B2:00, deferring
964:[ 5.874753] int3472-discrete INT3472:0c: cannot find GPIO chip INTC10B2:00, deferring
972:[ 5.880972] int3472-discrete INT3472:0c: cannot find GPIO chip INTC10B2:00, deferring
973:[ 5.881864] int3472-discrete INT3472:0c: cannot find GPIO chip INTC10B2:00, deferring
976:[ 5.885536] int3472-discrete INT3472:0c: cannot find GPIO chip INTC10B2:00, deferring
978:[ 5.907393] intel-ipu6 0000:00:05.0: CSE authenticate_run done
979:[ 5.907401] intel-ipu6 0000:00:05.0: IPU6-v4[7d19] hardware version 6
980:[ 5.908399] int3472-discrete INT3472:0c: cannot find GPIO chip INTC10B2:00, deferring
995:[ 5.981768] int3472-discrete INT3472:0c: cannot find GPIO chip INTC10B2:00, deferring
999:[ 6.013643] int3472-discrete INT3472:0c: cannot find GPIO chip INTC10B2:00, deferring
1002:[ 6.028494] int3472-discrete INT3472:0c: cannot find GPIO chip INTC10B2:00, deferring
1006:[ 6.033725] int3472-discrete INT3472:0c: cannot find GPIO chip INTC10B2:00, deferring
1008:[ 6.034112] spi-nor spi0.0: supply vcc not found, using dummy regulator
1015:[ 6.054208] int3472-discrete INT3472:0c: cannot find GPIO chip INTC10B2:00, deferring
1019:[ 6.060858] int3472-discrete INT3472:0c: cannot find GPIO chip INTC10B2:00, deferring
1024:[ 6.064831] int3472-discrete INT3472:0c: cannot find GPIO chip INTC10B2:00, deferring
1040:[ 6.127023] int3472-discrete INT3472:0c: cannot find GPIO chip INTC10B2:00, deferring
1043:[ 6.143628] int3472-discrete INT3472:0c: GPIO type 0x02 unknown; the sensor may not work
1063:[ 6.468766] ov02c10 i2c-OVTI02C1:00: supply dovdd not found, using dummy regulator
1064:[ 6.469299] ov02c10 i2c-OVTI02C1:00: supply avdd not found, using dummy regulator
1065:[ 6.469394] ov02c10 i2c-OVTI02C1:00: supply dvdd not found, using dummy regulator
1071:[ 6.471215] ov02c10 i2c-OVTI02C1:00: Error reading reg 0x300a: -121
1072:[ 6.471217] ov02c10 i2c-OVTI02C1:00: failed to find sensor: -121
1073:[ 6.471292] ov02c10 i2c-OVTI02C1:00: probe with driver ov02c10 failed with error -121
1133:[ 6.627389] cs42l43 sdw:0:0:01fa:4243:01: supply vdd-p not found, using dummy regulator
1134:[ 6.627415] cs42l43 sdw:0:0:01fa:4243:01: supply vdd-d not found, using dummy regulator
1135:[ 6.627419] cs42l43 sdw:0:0:01fa:4243:01: supply vdd-a not found, using dummy regulator
1136:[ 6.627422] cs42l43 sdw:0:0:01fa:4243:01: supply vdd-io not found, using dummy regulator
1137:[ 6.627431] cs42l43 sdw:0:0:01fa:4243:01: supply vdd-cp not found, using dummy regulator
1138:[ 6.638460] cs35l56 sdw:0:2:01fa:3556:01:2: supply VDD_P not found, using dummy regulator
1139:[ 6.638493] cs35l56 sdw:0:2:01fa:3556:01:2: supply VDD_IO not found, using dummy regulator
1140:[ 6.638499] cs35l56 sdw:0:2:01fa:3556:01:2: supply VDD_A not found, using dummy regulator
1141:[ 6.638925] cs35l56 sdw:0:2:01fa:3556:01:3: supply VDD_P not found, using dummy regulator
1142:[ 6.638946] cs35l56 sdw:0:2:01fa:3556:01:3: supply VDD_IO not found, using dummy regulator
1143:[ 6.638954] cs35l56 sdw:0:2:01fa:3556:01:3: supply VDD_A not found, using dummy regulator
1144:[ 6.639284] cs35l56 sdw:0:3:01fa:3556:01:0: supply VDD_P not found, using dummy regulator
1145:[ 6.639317] cs35l56 sdw:0:3:01fa:3556:01:0: supply VDD_IO not found, using dummy regulator
1146:[ 6.639327] cs35l56 sdw:0:3:01fa:3556:01:0: supply VDD_A not found, using dummy regulator
1147:[ 6.639617] cs35l56 sdw:0:3:01fa:3556:01:1: supply VDD_P not found, using dummy regulator
1148:[ 6.639637] cs35l56 sdw:0:3:01fa:3556:01:1: supply VDD_IO not found, using dummy regulator
1149:[ 6.639649] cs35l56 sdw:0:3:01fa:3556:01:1: supply VDD_A not found, using dummy regulator
1157:[ 6.819995] cs42l43-codec cs42l43-codec: supply vdd-amp not found, using dummy regulator
1160:[ 6.821481] sof_sdw sof_sdw: ASoC: Parent card not yet available, widget card binding deferred
1161:[ 6.821538] cs35l56 sdw:0:2:01fa:3556:01:2: supply VDD_B not found, using dummy regulator
1162:[ 6.821545] cs35l56 sdw:0:2:01fa:3556:01:2: supply VDD_AMP not found, using dummy regulator
1163:[ 6.822184] cs35l56 sdw:0:2:01fa:3556:01:3: supply VDD_B not found, using dummy regulator
1164:[ 6.822192] cs35l56 sdw:0:2:01fa:3556:01:3: supply VDD_AMP not found, using dummy regulator
1165:[ 6.823069] cs35l56 sdw:0:3:01fa:3556:01:0: supply VDD_B not found, using dummy regulator
1166:[ 6.823076] cs35l56 sdw:0:3:01fa:3556:01:0: supply VDD_AMP not found, using dummy regulator
1167:[ 6.823700] cs35l56 sdw:0:3:01fa:3556:01:1: supply VDD_B not found, using dummy regulator
1168:[ 6.823708] cs35l56 sdw:0:3:01fa:3556:01:1: supply VDD_AMP not found, using dummy regulator
[-- Attachment #3: 03_regulator_summary.txt --]
[-- Type: text/plain, Size: 293 bytes --]
sudo grep -iE 'regulator|INT3472|dvdd|ov02c10' /sys/kernel/debug/regulator/regulator_summary | grep -iA3 -B1 dvdd
regulator-dummy 19 27 0 unknown 0mV 0mA 0mV 0mV
INT3472:0c-dvdd 0 0 0 unknown 0mV 0mA 0mV 0mV
[-- Attachment #4: 04_lnk1.dsl --]
[-- Type: text/x-dsl, Size: 5947 bytes --]
Device (LNK1)
{
Name (CVSB, Package (0x02)
{
"\\_SB.PC00.CVSS",
"\\_SB.PC00.XHCI.RHUB.HS09.VIC1"
})
Name (PUSB, Package (0x02)
{
"\\_SB.PC00.DSC1",
"\\_SB.PC00.XHCI.RHUB.HS09.VIC1"
})
Method (_STA, 0, NotSerialized) // _STA: Status
{
If (L1EN)
{
Return (0x0F)
}
Else
{
Return (Zero)
}
}
Method (_SUB, 0, NotSerialized) // _SUB: Subsystem ID
{
Return (ToString (CERD, Ones))
}
Method (_DEP, 0, NotSerialized) // _DEP: Dependencies
{
If (L1EN)
{
If (ARLP)
{
Return (CVSB) /* \_SB_.PC00.LNK1.CVSB */
}
Else
{
Return (PUSB) /* \_SB_.PC00.LNK1.PUSB */
}
}
Else
{
Return (Package (0x01)
{
PC00
})
}
}
Name (_UID, One) // _UID: Unique ID
Method (_HID, 0, NotSerialized) // _HID: Hardware ID
{
Return (HCID (One))
}
Method (_CID, 0, NotSerialized) // _CID: Compatible ID
{
Return (HCID (One))
}
Method (_DDN, 0, NotSerialized) // _DDN: DOS Device Name
{
Name (BUF, Buffer (0x10){})
BUF [Zero] = L1M0 /* \L1M0 */
BUF [One] = L1M1 /* \L1M1 */
BUF [0x02] = L1M2 /* \L1M2 */
BUF [0x03] = L1M3 /* \L1M3 */
BUF [0x04] = L1M4 /* \L1M4 */
BUF [0x05] = L1M5 /* \L1M5 */
BUF [0x06] = L1M6 /* \L1M6 */
BUF [0x07] = L1M7 /* \L1M7 */
BUF [0x08] = L1M8 /* \L1M8 */
BUF [0x09] = L1M9 /* \L1M9 */
BUF [0x0A] = L1MA /* \L1MA */
BUF [0x0B] = L1MB /* \L1MB */
BUF [0x0C] = L1MC /* \L1MC */
BUF [0x0D] = L1MD /* \L1MD */
BUF [0x0E] = L1ME /* \L1ME */
BUF [0x0F] = L1MF /* \L1MF */
Return (ToString (BUF, Ones))
}
Method (_PLD, 0, Serialized) // _PLD: Physical Location of Device
{
Name (PLDB, Package (0x01)
{
Buffer (0x14)
{
/* 0000 */ 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
/* 0008 */ 0x69, 0x0E, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, // i.......
/* 0010 */ 0xFF, 0xFF, 0xFF, 0xFF // ....
}
})
CreateByteField (DerefOf (PLDB [Zero]), 0x08, BPOS)
CreateField (DerefOf (PLDB [Zero]), 0x73, 0x04, RPOS)
BPOS = L1PL /* \L1PL */
RPOS = L1DG /* \L1DG */
Return (PLDB) /* \_SB_.PC00.LNK1._PLD.PLDB */
}
Method (_CRS, 0, NotSerialized) // _CRS: Current Resource Settings
{
Local0 = VIIC (L1A0, One)
If ((L1DI > One))
{
Local1 = VIIC (L1A1, One)
ConcatenateResTemplate (Local0, Local1, Local2)
Local0 = Local2
}
If ((L1DI > 0x02))
{
Local1 = VIIC (L1A2, One)
ConcatenateResTemplate (Local0, Local1, Local2)
Local0 = Local2
}
Return (Local0)
}
Method (SSDB, 0, NotSerialized)
{
Name (PAR, Buffer (0x6C)
{
/* 0000 */ 0x00, 0x00, 0x69, 0x56, 0x39, 0x8A, 0xF7, 0x11, // ..iV9...
/* 0008 */ 0xA9, 0x4E, 0x9C, 0x7D, 0x20, 0xEE, 0x0A, 0xB5, // .N.} ...
/* 0010 */ 0xCA, 0x40, 0xA3, 0x00, 0x00, 0x00, 0x00, 0x00, // .@......
/* 0018 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
/* 0020 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
/* 0028 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
/* 0030 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
/* 0038 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
/* 0040 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
/* 0048 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
/* 0050 */ 0x10, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, // ........
/* 0058 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
/* 0060 */ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, // ........
/* 0068 */ 0x00, 0x00, 0x00, 0x00 // ....
})
PAR [Zero] = L1DV /* \L1DV */
PAR [One] = L1CV /* \L1CV */
PAR [0x18] = L1LC /* \L1LC */
PAR [0x1C] = L1LU /* \L1LU */
PAR [0x1D] = L1NL /* \L1NL */
PAR [0x4E] = L1EE /* \L1EE */
PAR [0x4F] = L1VC /* \L1VC */
PAR [0x52] = L1FS /* \L1FS */
PAR [0x53] = L1LE /* \L1LE */
PAR [0x54] = CDEG (L1DG)
[-- Attachment #5: 05_dsc0.dsl --]
[-- Type: text/x-dsl, Size: 6765 bytes --]
Device (DSC0)
{
Name (_HID, "INT3472") // _HID: Hardware ID
Name (_CID, "INT3472") // _CID: Compatible ID
Name (_DDN, "PMIC-CRDG") // _DDN: DOS Device Name
Name (_UID, Zero) // _UID: Unique ID
Name (_DEP, Package (0x01) // _DEP: Dependencies
{
^XHCI.RHUB.HS09.VGPO
})
Method (_SUB, 0, NotSerialized) // _SUB: Subsystem ID
{
Return (ToString (CERD, Ones))
}
Method (_CRS, 0, NotSerialized) // _CRS: Current Resource Settings
{
Local0 = VPIN (One)
If ((C0GP > Zero))
{
Local1 = PINR (C0P0, C0C0, C0G0)
ConcatenateResTemplate (Local0, Local1, Local2)
Local0 = Local2
}
If ((C0GP > One))
{
Local1 = PINR (C0P1, C0C1, C0G1)
ConcatenateResTemplate (Local0, Local1, Local2)
Local0 = Local2
}
If ((C0GP > 0x02))
{
Local1 = PINR (C0P2, C0C2, C0G2)
ConcatenateResTemplate (Local0, Local1, Local2)
Local0 = Local2
}
If ((C0GP > 0x03))
{
Local1 = PINR (C0P3, C0C3, C0G3)
ConcatenateResTemplate (Local0, Local1, Local2)
Local0 = Local2
}
If ((C0GP > 0x04))
{
Local1 = PINR (C0P4, C0C4, C0G4)
ConcatenateResTemplate (Local0, Local1, Local2)
Local0 = Local2
}
If ((C0GP > 0x05))
{
Local1 = PINR (C0P5, C0C5, C0G5)
ConcatenateResTemplate (Local0, Local1, Local2)
Local0 = Local2
}
Return (Local0)
}
Method (_STA, 0, NotSerialized) // _STA: Status
{
If (CL00)
{
If ((C0TP == One))
{
Return (0x0F)
}
}
Return (Zero)
}
Method (CLDB, 0, NotSerialized)
{
Name (PAR, Buffer (0x20)
{
/* 0000 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, // ........
/* 0008 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
/* 0010 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
/* 0018 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // ........
})
PAR [Zero] = C0VE /* \C0VE */
PAR [One] = C0TP /* \C0TP */
PAR [0x03] = C0CV /* \C0CV */
PAR [0x04] = C0IC /* \C0IC */
PAR [0x06] = C0SP /* \C0SP */
PAR [0x08] = C0W0 /* \C0W0 */
PAR [0x09] = C0W1 /* \C0W1 */
PAR [0x0A] = C0W2 /* \C0W2 */
PAR [0x0B] = C0W3 /* \C0W3 */
PAR [0x0C] = C0W4 /* \C0W4 */
PAR [0x0D] = C0W5 /* \C0W5 */
PAR [0x0E] = C0CS /* \C0CS */
Return (PAR) /* \_SB_.PC00.DSC0.CLDB.PAR_ */
}
Method (_DSM, 4, NotSerialized) // _DSM: Device-Specific Method
{
If ((Arg0 == ToUUID ("79234640-9e10-4fea-a5c1-b5aa8b19756f") /* Unknown UUID */))
{
If ((Arg2 == Zero))
{
Return (Buffer (One)
{
0x3F // ?
})
}
If ((Arg2 == One))
{
Return ((One + C0GP))
}
If ((Arg2 == 0x02))
{
Return (0x01000112)
}
If ((Arg2 == 0x03))
{
Return (0x01000002)
}
If ((Arg2 == 0x04))
{
Return (Zero)
}
If ((Arg2 == 0x05))
{
Return (Zero)
}
If ((Arg2 == 0x06))
{
Return (Zero)
}
If ((Arg2 == 0x07))
{
Return (Zero)
}
Return (Buffer (One)
{
0x00 // .
})
}
If ((PCHS != 0x04)){}
Return (Buffer (One)
{
0x00 // .
})
}
}
Device (DSC1)
{
Name (_HID, "INT3472") // _HID: Hardware ID
Name (_CID, "INT3472") // _CID: Compatible ID
Name (_DDN, "PMIC-CRDG") // _DDN: DOS Device Name
Name (_UID, One) // _UID: Unique ID
Method (_SUB, 0, NotSerialized) // _SUB: Subsystem ID
{
Return (ToString (CERD, Ones))
}
If ((C1GP != Zero))
{
Method (_CRS, 0, NotSerialized) // _CRS: Current Resource Settings
{
Local0 = VPIN (Zero)
Local1 = VPIN (0x02)
ConcatenateResTemplate (Local0, Local1, Local2)
Local0 = Local2
If ((C1GP > Zero))
{
Local1 = PINR (C1P1, C1C1, C1G1)
ConcatenateResTemplate (Local0, Local1, Local2)
Local0 = Local2
}
If ((C1GP > One))
{
Local1 = PINR (C1P1, C1C1, C1G1)
ConcatenateResTemplate (Local0, Local1, Local2)
Local0 = Local2
}
If ((C1GP > 0x02))
{
Local1 = PINR (C1P2, C1C2, C1G2)
ConcatenateResTemplate (Local0, Local1, Local2)
Local0 = Local2
}
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [BUG] OV02C10 on Dell 16 Premium DA16250 (ARL): INT3472 handshake-derived "dvdd" regulator registered but never linked to sensor, sensor probe fails with -EREMOTEIO
2026-06-12 16:09 ` Angioli Samuele (gmail)
@ 2026-06-13 17:01 ` Marco Nenciarini
2026-06-14 14:29 ` Angioli Samuele (gmail)
0 siblings, 1 reply; 6+ messages in thread
From: Marco Nenciarini @ 2026-06-13 17:01 UTC (permalink / raw)
To: Angioli Samuele, linux-media
Cc: Hans de Goede, ilpo.jarvinen, Sakari Ailus, Israel Cepeda,
linux-kernel, platform-driver-x86
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
Hi Samuele,
No problem on the timing, and thanks. The regulator_summary plus the
_DEP decode settle it, and they confirm the multi-instance hypothesis
from my last mail rather than the missing-map one.
One correction on the code side first, because it matters for the fix.
The handshake path is not missing the consumer-map step. HANDSHAKE
(type 0x12) and POWER_ENABLE (0x0b) fall through to the same call site
in skl_int3472_handle_gpio_resources(), so both go through
skl_int3472_register_regulator(), which plants supply_map[] (dev_name +
supply, lower- and upper-case) the same way for either type. That has
been the case since v6.16 (c5d039327204, "int3472: Add handshake pin
support"), so your 7.0.10 kernel has it. The dvdd map does get created.
The problem is the dev_name it is keyed on.
That dev_name is int3472->sensor_name, and sensor_name is
"i2c-" + acpi_dev_name(acpi_dev_get_next_consumer_dev(adev)), i.e. the
first device that lists the registering INT3472 instance in its _DEP.
Here that instance is INT3472:0c = DSC0 (the regulator name in your
summary, "INT3472:0c-dvdd", is built from acpi_dev_name(adev), so the
provider is unambiguously DSC0). But your _DEP decode shows the sensor
(LNK1) depends on DSC1, never on DSC0: ARLP -> {CVSS, HS09.VIC1},
non-ARLP -> {DSC1, HS09.VIC1}. So DSC0's reverse-_DEP walk does not
return OVTI02C1. It returns whatever else declares a _DEP on DSC0
(plausibly the IR-flood side, given func 3 sits on the same device),
the dvdd map is keyed to that name, and the sensor's
regulator_get("dvdd") for "i2c-OVTI02C1:00" never matches. -ENODEV,
permanent dummy under full constraints (the legacy ACPI dev_name path
has no "coming later" signal, so it is a dummy, not -EPROBE_DEFER),
rail stays down, 0x300a reads -EREMOTEIO, no retry. That is exactly the
regulator_summary you captured: INT3472:0c-dvdd registered, use=0.
Note this is specific to dvdd. DSC0's _DSM only exposes the dvdd
handshake (func 2) and the IR-flood strobe (func 3); it does not
provide avdd or dovdd. The sensor correctly _DEPs on DSC1 and is served
by DSC1 for the rails and resets DSC1 owns, which is why it gets far
enough to attempt the chip-ID read at all. dvdd is the one rail
stranded on an instance the sensor does not depend on. (avdd and dovdd
landing on dummies is most likely the always-on-rail case I mentioned
before, benign, unless you can see a gating GPIO for them on either
instance.)
Timing is not the mechanism either way. Your own timestamps already
show the sensor's get at 6.468 well after DSC0 bound at 6.135, and even
a perfectly ordered probe would still miss, because the map is keyed to
the wrong device, not registered late.
So this is a firmware _DEP-topology issue: dvdd is gated by DSC0, but
the sensor is pointed at DSC1, and nothing connects the two. Could you
confirm the two halves of that, so we are not inferring DSC0's consumer:
- with int3472 dynamic debug on
(dyndbg="module intel_skl_int3472_discrete +p"), the "Sensor name
%s" line from DSC0's probe shows which device its consumer walk
actually resolved to. If that is not OVTI02C1:00, it nails the
keying;
- the reverse _DEP, i.e. which device(s) list \_SB.PC00.DSC0 in their
own _DEP (a grep of the DSDT _DEP packages). DSC0 bound rather than
failing with "INT3472 seems to have no dependents", so something
does depend on it; identifying it tells us where dvdd actually went.
Hans, Sakari, once that "Sensor name" line confirms DSC0 is keying its
dvdd to a non-sensor consumer, the open int3472 question becomes whether
this is a firmware defect to push back on or something we work around
in-tree (and if in-tree, a per-board quirk vs. generic cross-instance
keying). Worth noting the EPROBE_DEFER idea from last time does not
apply: the map is keyed to the wrong device, not merely registered late.
Let's nail the topology first.
Thanks,
Marco
-----BEGIN PGP SIGNATURE-----
iQJFBAEBCAAvFiEEfCO4BD5l0pgKIbbiWJ8D8BulUDgFAmotjMwRHG1uZW5jaWFA
a2NvcmUuaXQACgkQWJ8D8BulUDhOWhAAm0dWTRnXeg419gpHSz3/fWxNgS/rHgy9
oJmYV4/6kftjSbR3i5zORj1eUAOKhdh4lYmjYN0+7OPu45MAlFHTEB943OCSBx5M
HZQGvIWlKfYiLewUnzYBpuMCk1tHJpjmSvkiU5KIrto47yM1uGW8hff+dmo+QIKI
ir6LaIIAsEhjLfjlK4mQa7EoImMmLfT9tmMpZeJjnsulXAsRgz8GGaLSca+J8/wR
pESrwvcDpQocFdVlBCIBSP6vnrJmGEOzivtb7uDWp3X8yXlPzwtCEE+WEyXghtXN
TSAtIAbezj1LaBSQ24uh6deOZkhVsqZ4t8ms1BWl8/E+XTw4GERMcTxLJJaRxO2T
Btzl95AEnGmxieWcZirrHlWIPTYRdJ8zlMhvKEuzjxbt/kFq8hm1mtvbcSdxOA7L
0Q2cvaTtlFlWRG8QCJTMNhFXKbaioaVLc/wkGiQ4vhrAT1mLX1voiTvaXnfRlk/s
eun0k5XN2+90DVqni0vx3vcZlF5/nnb5OmMJefv7qK89LwrA70ugbbNn2UL9Gxnf
IZqlPs50oyeBe7g7K5gglYgZfu2awMTx9eFcftiv8itH0yUVKXPawVgCXe1gSfrp
Eh4Q7oZEk1UYNk3bCz2RmspfbfwWy1z7Kn5/mWpSWUy/8PCFl1otui/C4snRNgIs
42ajMSg0om4=
=0BwD
-----END PGP SIGNATURE-----
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [BUG] OV02C10 on Dell 16 Premium DA16250 (ARL): INT3472 handshake-derived "dvdd" regulator registered but never linked to sensor, sensor probe fails with -EREMOTEIO
2026-06-13 17:01 ` Marco Nenciarini
@ 2026-06-14 14:29 ` Angioli Samuele (gmail)
2026-06-14 20:23 ` Marco Nenciarini
0 siblings, 1 reply; 6+ messages in thread
From: Angioli Samuele (gmail) @ 2026-06-14 14:29 UTC (permalink / raw)
To: Marco Nenciarini, linux-media
Cc: Hans de Goede, ilpo.jarvinen, Sakari Ailus, Israel Cepeda,
linux-kernel, platform-driver-x86
Hi Marco,
Topology confirmed, and it's the "firmware mismatch" case. In short:
- The sensor (OVTI02C1:00) sits at \_SB.PC00.LNK1 and depends on DSC1,
exactly as the _DEP decode showed. DSC0 is instead the link-0 PMIC,
whose sensor is the Himax HM1092 IR camera (HIMX1092:00, Windows
Hello).
- DSC0 = INT3472:0c, DSC1 = INT3472:01.
- The clincher is the regulator_summary: the only dvdd on the whole
platform is INT3472:0c-dvdd (DSC0), and it's orphaned (use=0). DSC1,
which the RGB sensor actually depends on, exposes no dvdd at all --
only avdd/dovdd/reset.
regulator_summary (the only two top-level regulators; all
regulator-dummy children are SoundWire audio rails, elided for brevity):
regulator use open bypass opmode voltage ...
------------------------------------------------------------------
regulator-dummy 19 27 0 unknown 0mV ...
[ ~30 sdw:* / cs42l43 / spi0.0 audio rails -- elided ]
INT3472:0c-dvdd 0 0 0 unknown 0mV ...
No INT3472:01-* (DSC1) entry: DSC1 registers no dvdd.
Direct kernel confirmation, the "Sensor name" line from DSC0's probe:
[ 6.301445] int3472-discrete INT3472:0c: Sensor name HIMX1092:00
i.e. DSC0 keys its dvdd to the link-0 IR camera (HIMX1092:00), not to
the OV02C10. So there is exactly one dvdd handshake and it's on the
wrong side: it lives on DSC0/link-0, while the RGB sensor is on
link-1/DSC1, and nothing connects the two. DSC0's reverse-_DEP resolves
to HIMX1092:00, the dvdd supply_map is keyed there, and i2c-OVTI02C1:00
never matches -> dummy -> rail down -> 0x300a -EREMOTEIO.
Thanks,
Samuele
Il 13/06/26 19:01, Marco Nenciarini ha scritto:
> Hi Samuele,
>
> No problem on the timing, and thanks. The regulator_summary plus the
> _DEP decode settle it, and they confirm the multi-instance hypothesis
> from my last mail rather than the missing-map one.
>
> One correction on the code side first, because it matters for the fix.
> The handshake path is not missing the consumer-map step. HANDSHAKE
> (type 0x12) and POWER_ENABLE (0x0b) fall through to the same call site
> in skl_int3472_handle_gpio_resources(), so both go through
> skl_int3472_register_regulator(), which plants supply_map[] (dev_name +
> supply, lower- and upper-case) the same way for either type. That has
> been the case since v6.16 (c5d039327204, "int3472: Add handshake pin
> support"), so your 7.0.10 kernel has it. The dvdd map does get created.
> The problem is the dev_name it is keyed on.
>
> That dev_name is int3472->sensor_name, and sensor_name is
> "i2c-" + acpi_dev_name(acpi_dev_get_next_consumer_dev(adev)), i.e. the
> first device that lists the registering INT3472 instance in its _DEP.
> Here that instance is INT3472:0c = DSC0 (the regulator name in your
> summary, "INT3472:0c-dvdd", is built from acpi_dev_name(adev), so the
> provider is unambiguously DSC0). But your _DEP decode shows the sensor
> (LNK1) depends on DSC1, never on DSC0: ARLP -> {CVSS, HS09.VIC1},
> non-ARLP -> {DSC1, HS09.VIC1}. So DSC0's reverse-_DEP walk does not
> return OVTI02C1. It returns whatever else declares a _DEP on DSC0
> (plausibly the IR-flood side, given func 3 sits on the same device),
> the dvdd map is keyed to that name, and the sensor's
> regulator_get("dvdd") for "i2c-OVTI02C1:00" never matches. -ENODEV,
> permanent dummy under full constraints (the legacy ACPI dev_name path
> has no "coming later" signal, so it is a dummy, not -EPROBE_DEFER),
> rail stays down, 0x300a reads -EREMOTEIO, no retry. That is exactly the
> regulator_summary you captured: INT3472:0c-dvdd registered, use=0.
>
> Note this is specific to dvdd. DSC0's _DSM only exposes the dvdd
> handshake (func 2) and the IR-flood strobe (func 3); it does not
> provide avdd or dovdd. The sensor correctly _DEPs on DSC1 and is served
> by DSC1 for the rails and resets DSC1 owns, which is why it gets far
> enough to attempt the chip-ID read at all. dvdd is the one rail
> stranded on an instance the sensor does not depend on. (avdd and dovdd
> landing on dummies is most likely the always-on-rail case I mentioned
> before, benign, unless you can see a gating GPIO for them on either
> instance.)
>
> Timing is not the mechanism either way. Your own timestamps already
> show the sensor's get at 6.468 well after DSC0 bound at 6.135, and even
> a perfectly ordered probe would still miss, because the map is keyed to
> the wrong device, not registered late.
>
> So this is a firmware _DEP-topology issue: dvdd is gated by DSC0, but
> the sensor is pointed at DSC1, and nothing connects the two. Could you
> confirm the two halves of that, so we are not inferring DSC0's consumer:
>
> - with int3472 dynamic debug on
> (dyndbg="module intel_skl_int3472_discrete +p"), the "Sensor name
> %s" line from DSC0's probe shows which device its consumer walk
> actually resolved to. If that is not OVTI02C1:00, it nails the
> keying;
> - the reverse _DEP, i.e. which device(s) list \_SB.PC00.DSC0 in their
> own _DEP (a grep of the DSDT _DEP packages). DSC0 bound rather than
> failing with "INT3472 seems to have no dependents", so something
> does depend on it; identifying it tells us where dvdd actually went.
>
> Hans, Sakari, once that "Sensor name" line confirms DSC0 is keying its
> dvdd to a non-sensor consumer, the open int3472 question becomes whether
> this is a firmware defect to push back on or something we work around
> in-tree (and if in-tree, a per-board quirk vs. generic cross-instance
> keying). Worth noting the EPROBE_DEFER idea from last time does not
> apply: the map is keyed to the wrong device, not merely registered late.
> Let's nail the topology first.
>
> Thanks,
> Marco
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [BUG] OV02C10 on Dell 16 Premium DA16250 (ARL): INT3472 handshake-derived "dvdd" regulator registered but never linked to sensor, sensor probe fails with -EREMOTEIO
2026-06-14 14:29 ` Angioli Samuele (gmail)
@ 2026-06-14 20:23 ` Marco Nenciarini
0 siblings, 0 replies; 6+ messages in thread
From: Marco Nenciarini @ 2026-06-14 20:23 UTC (permalink / raw)
To: Angioli Samuele, linux-media
Cc: Hans de Goede, ilpo.jarvinen, Sakari Ailus, linux-kernel,
platform-driver-x86
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
Hans, Sakari,
Samuele's data is in and it confirms both halves of the wrong-instance
keying.
DSC0 = INT3472:0c, DSC1 = INT3472:01. The decisive line from DSC0's
probe, with int3472 dyndbg on:
int3472-discrete INT3472:0c: Sensor name HIMX1092:00
So DSC0's reverse-_DEP walk resolves to the first consumer that _DEPs
it, the Himax IR camera (HIMX1092:00, Windows Hello), and that is the
dev_name DSC0's dvdd supply_map is keyed on. The OV02C10 (OVTI02C1:00)
never appears in it. regulator_summary corroborates from the other
side: the only dvdd on
the whole platform is INT3472:0c-dvdd (DSC0), orphaned at use=0, and
DSC1 (which the RGB sensor actually _DEPs) exposes no dvdd at all, only
avdd/dovdd/reset.
So the topology is settled: there is exactly one dvdd handshake on the
platform, gated by DSC0, keyed to the IR sensor DSC0 serves, while the
RGB sensor that appears to want it _DEPs DSC1 instead, and nothing
connects the two. The remaining inference is the rail-to-failure link
itself: dvdd falls to a dummy under full constraints, and the chip-ID
read at 0x300a returns -EREMOTEIO with no retry. That chain is
consistent with the data but I have not proven dvdd is the cause as
opposed to a coincident orphan (see the test ask to Samuele below),
so I would not call the failure mechanism closed yet, only the keying.
On whose defect this is: either the firmware under-specifies the
dependency (the OV02C10's dvdd is physically gated by DSC0 but its _DEP
points only at DSC1), or the kernel's reverse-_DEP consumer model
cannot express a rail that lives on a sibling INT3472 instance. Either
way this is shipping DA16250 firmware that will not change, so the
camera needs an in-tree path regardless of where we assign blame.
That makes this the same class of problem int3472 already handles with
the second_sensor quirk. avdd_second_sensor (the Lenovo Miix 510 entry
in discrete_quirks.c) already plants a second supply_map entry, keyed
to a hardcoded device name in addition to the reverse-_DEP sensor_name,
and skl_int3472_register_regulator() takes second_sensor for exactly
that. The DA16250 is the same shape, just on dvdd/HANDSHAKE rather than
avdd/POWER_ENABLE, and the HANDSHAKE branch currently always passes
second_sensor = NULL. So the contained fix is: extend second_sensor to
cover the dvdd/HANDSHAKE arm too. The struct has a single second_sensor
field today (avdd_second_sensor), so generalising that one field reads
cleaner to me than adding a per-con_id dvdd_second_sensor, but either
works; then add a DA16250 DMI entry pointing dvdd's second consumer at
i2c-OVTI02C1:00. This adds OVTI02C1 as a second consumer of DSC0's
dvdd, it does not move the rail off HIMX1092:00, so the IR camera's own
supply is untouched.
The alternative is to make that second-consumer resolution automatic
rather than DMI-gated, i.e. teach int3472 to discover that a sensor may
draw a rail from an instance it does not _DEP on. More correct in
principle, but ACPI gives no signal to key it on here (that is the
firmware gap), so it would need a heuristic and I would not want it
silently re-homing rails on boards where the current keying is right.
My instinct is the DMI quirk, extending the mechanism you already use
for avdd. DMI is the right key rather than the int3472_gpio_map[] HID
table, because the OV02C10 part is not the problem, the DA16250 _DEP
topology is. I would leave the fully-automatic resolution open in case
more ARL boards turn up the same split. Tell me which way you want it
and I will prototype the quirk against the DA16250.
Samuele, here is a concrete test that closes the last gap. It is the
proposed fix in miniature, so a positive result validates both at once.
Two ways to run it, pick whichever suits your setup. In both, the
signal is the same: does the 0x300a chip-ID read in dmesg succeed, or
still return -EREMOTEIO?
Option A, the patch (preferred, it exercises the real consumer path).
In skl_int3472_handle_gpio_resources(), in
drivers/platform/x86/intel/int3472/discrete.c, add the two marked lines
to the regulator arm of the switch:
case INT3472_GPIO_TYPE_POWER_ENABLE:
second_sensor = int3472->quirks.avdd_second_sensor;
fallthrough;
case INT3472_GPIO_TYPE_DOVDD:
case INT3472_GPIO_TYPE_HANDSHAKE:
+ if (type == INT3472_GPIO_TYPE_HANDSHAKE)
+ second_sensor = "i2c-OVTI02C1:00"; /* test */
ret = skl_int3472_register_regulator(int3472, gpio, enable_time_us,
con_id, second_sensor);
This adds OVTI02C1:00 as a second consumer of DSC0's dvdd alongside the
existing HIMX1092:00 mapping; it does not move the rail off the IR
camera. The hardcoded string makes this test-only (it would mis-key on
any other handshake board); the shipped form is the DMI-gated quirk
above. The hunk applies to a recent mainline discrete.c, where the
HANDSHAKE case shares the register_regulator call via the POWER_ENABLE
fallthrough, so build from a source tree matching your running kernel.
First confirm int3472 is a module, not built in:
modinfo intel_skl_int3472_discrete
# or check CONFIG_INTEL_SKL_INT3472 in your kernel config
If it is =y you need a full kernel build instead. If =m, build and
install just this module, then reboot for a clean re-probe:
make -C /lib/modules/$(uname -r)/build \
M=$PWD/drivers/platform/x86/intel/int3472 modules
sudo make -C /lib/modules/$(uname -r)/build \
M=$PWD/drivers/platform/x86/intel/int3472 modules_install
sudo depmod -a
sudo reboot
(Build against the configured source for your running kernel, or the
new .ko may refuse to load on a modversions/CRC mismatch.) After
reboot, in /sys/kernel/debug/regulator/regulator_summary the
INT3472:0c-dvdd line should now list the i2c-OVTI02C1:00 device as a
consumer (use count > 0), and dmesg shows whether 0x300a now succeeds.
Option B, no rebuild, force the rail on by hand. On this board DSC0's
_DSM exposes only func 2 (the dvdd handshake) and func 3 (the IR-flood
strobe), so unbinding it drops exactly those two and nothing the
OV02C10 needs. dvdd is a GPIO-gated regulator, so as root:
# 1. BEFORE unbinding, capture the dvdd enable line: int3472
# requests it with consumer label "dvdd", so in gpioinfo find
# the line whose consumer is "dvdd" and note its gpiochip (the
# block header) and offset. The label disappears once you
# unbind, so record chip+offset now. Your int3472 dyndbg log
# cross-checks it:
# "INT3472:0c: dvdd <acpi-gpio-path> pin <N> active-<high|low>"
# (that line gives the ACPI controller path and pin, not the
# gpiochip number, so map it through gpioinfo). Note the
# active- sense too, you need it in step 3:
gpioinfo
# 2. release the line by unbinding the PMIC (drops only DSC0's
# dvdd regulator and IR strobe, not the sensor, which _DEPs
# DSC1):
echo INT3472:0c > /sys/bus/platform/drivers/int3472-discrete/unbind
# 3. drive the line to its ON level and HOLD it (own shell, leave
# running). ON is =1 if step 1 showed active-high, =0 if
# active-low. Using the gpiochip and offset from step 1:
# libgpiod v1: gpioset --mode=signal gpiochipN <offset>=<on>
# libgpiod v2: gpioset -c gpiochipN <offset>=<on> (holds until Ctrl-C)
gpioset --mode=signal gpiochipN <offset>=<on>
# 4. in another shell, re-probe the sensor and read the log:
echo i2c-OVTI02C1:00 > /sys/bus/i2c/drivers/ov02c10/bind
dmesg | tail
# 5. when done, Ctrl-C the gpioset and reboot to restore normal
# driver state.
(If step 4 says the device is already bound, unbind it first via the
same path, then bind.) regulator_get("dvdd") lands on a dummy here,
since there is no provider once DSC0 is unbound, but that is a no-op
enable and the rail is physically on because you are holding the GPIO
at its ON level, so the chip-ID read is still the signal.
Either way: if 0x300a succeeds, that pins powering dvdd as what
unblocks the chip-ID read, and the fix is exactly Option A folded into
a DA16250 DMI quirk. If it still fails, dvdd is not the (only) problem
and the -EREMOTEIO is coming from reset, clock, or the NX33 bridge, and
we look there instead. Option A is the better single test, since it
keeps DSC0 bound and exercises the real enable path with the right
polarity and timing; Option B trades that for no rebuild, so if the two
disagree, trust A.
Thanks,
Marco
-----BEGIN PGP SIGNATURE-----
iQIyBAEBCAAdFiEEfCO4BD5l0pgKIbbiWJ8D8BulUDgFAmovDcIACgkQWJ8D8Bul
UDjAng/48+VJljU31kWvg6tTrofMNHBwjXYlCAepNnQqVr8FyKxeM+fgzucIjqU/
dq2OJP2TgDej13gGFLSrsduel4FNrcTqc3KYM+uYSnRCGX4Pqi7r4uT5M4tvY2Pt
mrDGBvi4ZK6RgYfrCMQus1mNtVaJcBw/mKPdxdQK84KmI6ohKh9yFsDgizVF2WHP
LFvJ2YQWEHf1jeisa5h+y1c4+RRPUIzmz8qW12jFLr7Dba7U+pNP+OaZZwZin6Dh
uPNa8rrkv+WFWKR7kJfK6woaJpR0VVHWIg0s/4AOID/3I5LIBBd1ruTZwJNnBMkz
TApKmqU9hXANXxZ+oGLfCW7OoqLvNfcuo0kE35dqzKLxrpkGYHgFnX7N7mD4+Rgp
B57rUUSIBrOs1dn2qgSussZoEr0dNp24r6K+YH1r/thMw4kdQxgovD4se8momCij
tGPP0hi/8hB2uXBSRJSH/wI03qrU/JVOqVgmc8W19tPemZdQuNxvSrwnEgUaAFx/
9uZZJoMBX3HM373eVd1/M4Bv3j4fGesjKI8JeYkGkzQioZOATV0PIfTv+K04Ytyb
QGCwanp3I0FFUVBqMpiwuRIm/xOxl1NEtrpLU/AtbfBF6D17RobMidTvPy3URFRg
fkSASULsYSvlKZLZpZoNquUZmcoqBwcLawewWza8T9DeJMlkfw==
=8fhX
-----END PGP SIGNATURE-----
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-06-14 20:23 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-01 14:06 [BUG] OV02C10 on Dell 16 Premium DA16250 (ARL): INT3472 handshake-derived "dvdd" regulator registered but never linked to sensor, sensor probe fails with -EREMOTEIO Angioli Samuele (gmail)
2026-06-03 7:26 ` Marco Nenciarini
2026-06-12 16:09 ` Angioli Samuele (gmail)
2026-06-13 17:01 ` Marco Nenciarini
2026-06-14 14:29 ` Angioli Samuele (gmail)
2026-06-14 20:23 ` Marco Nenciarini
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox