Skip to content

Surface Pro 10 Rear Camera (OV13858) Working + Front Camera (IMX681) Working at 1920×1320 #2153

Description

@djmulder

int3472-clk.patch
int3472-discrete.patch
ipu-bridge.patch
ov13858.patch

Summary

After significant reverse engineering of the ACPI tables and kernel driver analysis, I have gotten the rear camera (OmniVision OV13858) working on the Surface Pro 10 running Ubuntu 26.04 / kernel 7.0.0. This documents the findings and patches required.

Device: Microsoft Surface Pro 10
OS: Ubuntu 26.04 LTS
Kernel: 7.0.0-15-generic


Root Causes Found

Three separate issues prevented the camera from working:

1. ipu-bridge: OVTID858 not in supported sensors list

The Intel IPU6 bridge driver (drivers/media/pci/intel/ipu-bridge.c) had no entry for the Surface Pro 10's OV13858 sensor, which presents as ACPI ID OVTID858. Without this entry, the IPU6 never recognizes the sensor.

Fix: Add to ipu_supported_sensors[]:

/* OmniVision OV13858 - Microsoft Surface Pro 10 rear camera */
IPU_SENSOR_CONFIG("OVTID858", 1, 540000000),

2. INT3472: Unknown GPIO type 0x08

The Surface Pro 10 INT3472 device (ICL0, path \_SB_.PC00.I2C3.ICL0) defines four GPIOs via _DSM:

DSM return value Pin Type Function Status
0x1000A00B 0xA0 (160) 0x0B POWER_ENABLE (avdd) Known
0x1000A100 0xA1 (161) 0x00 RESET Known
0x1000D00D 0xD0 (208) 0x0D PRIVACY_LED Known
0x1000C608 0xC6 (198) 0x08 Unknown Missing

GPIO type 0x08 was not defined in include/linux/platform_data/x86/int3472.h, causing the intel_skl_int3472_discrete driver to log:

int3472-discrete INT3472:00: GPIO type 0x08 unknown; the sensor may not work

Based on the position in the type space (between powerdown 0x01 and power_enable 0x0b) and testing, type 0x08 is a second digital power rail (dvdd).

Fix: Add to include/linux/platform_data/x86/int3472.h:

#define INT3472_GPIO_TYPE_DVDD    0x08

And handle it in drivers/platform/x86/intel/int3472/discrete.c in three places (alongside DOVDD handling).

Also increase INT3472_MAX_SENSOR_GPIOS from 3 to 4 to accommodate the extra GPIO.

3. INT3472 regulators and clock not being enabled

The ov13858 sensor driver does not request regulators or enable the clock — it assumes these are always available. On the Surface Pro 10, the INT3472 controls power and clock explicitly.

Temporary fix (too broad for upstream):

  • Add CLK_IS_CRITICAL flag to INT3472 clock registration in clk_and_regulator.c
  • Add boot_on = 1 and always_on = 1 to regulator constraints

Proper upstream fix: Add a DMI quirk table in discrete_quirks.c specific to Surface Pro 10 that sets always_on behavior, or patch ov13858.c to properly request and enable regulators/clock.

4. OV13858 driver: No reset GPIO handling

The ov13858 driver does not request or toggle the reset GPIO. On the Surface Pro 10, the sensor is held in hardware reset by the INT3472 and the driver must explicitly release it.

Verified by manual GPIO toggle:

sudo gpioset --chip gpiochip0 -t 0 161=1 &  # wrong polarity
# then:
sudo i2ctransfer -y 3 w2@0x10 0x30 0x0a r2
# returns: 0x00 0xd8  (OV13858 chip ID confirmed!)

Fix: Add reset GPIO handling to ov13858_probe():

#include <linux/delay.h>
#include <linux/gpio/consumer.h>

/* In struct ov13858: */
struct gpio_desc *reset_gpio;

/* In ov13858_probe(), after clock check: */
ret = clk_prepare_enable(ov13858->clk);
if (ret)
return dev_err_probe(ov13858->dev, ret, "failed to enable clock\n");

ov13858->reset_gpio = devm_gpiod_get_optional(ov13858->dev, "reset", GPIOD_OUT_HIGH);
if (IS_ERR(ov13858->reset_gpio))
return dev_err_probe(ov13858->dev, PTR_ERR(ov13858->reset_gpio),
"failed to get reset GPIO\n");
if (ov13858->reset_gpio) {
gpiod_set_value_cansleep(ov13858->reset_gpio, 1); /* assert reset /
msleep(20);
gpiod_set_value_cansleep(ov13858->reset_gpio, 0); /
deassert reset */
msleep(50);
}

Note: clk_disable_unprepare() must be added to all error paths and the remove function.


Result

With all four fixes applied as DKMS modules, cam --list shows:

Available cameras:
1: Internal back camera (\_SB_.PC00.I2C3.CAMR)

And cam -c 1 --capture=3 successfully captures frames at 4216x3136.


ACPI Analysis

The relevant ACPI devices:

  • \_SB_.PC00.I2C3.CAMR — OV13858 rear camera (ACPI ID: OVTID858)
  • \_SB_.PC00.I2C3.ICL0 — INT3472 power controller for rear camera
  • \_SB_.PC00.I2C3.CAMF — Sony IMX681 front camera (ACPI ID: SONY0681) — no driver exists
  • \_SB_.PC00.I2C3.ICL2 — INT3472 power controller for front camera
  • \_SB_.PC00.I2C5.CAM3 — SMO55F0 IR camera — no driver exists

The front camera (SONY0681/IMX681) and IR camera (SMO55F0) have no Linux drivers and would need drivers written from scratch.


Files Modified

  1. drivers/media/pci/intel/ipu-bridge.c
  2. drivers/platform/x86/intel/int3472/discrete.c
  3. include/linux/platform_data/x86/int3472.h
  4. drivers/platform/x86/intel/int3472/clk_and_regulator.c
  5. drivers/media/i2c/ov13858.c

Notes for Upstream Patches

  • The CLK_IS_CRITICAL and always_on changes need to be scoped to Surface Pro 10 via DMI matching rather than applied globally
  • The ov13858 reset GPIO patch is broadly applicable and could go upstream directly (other platforms using OV13858 may also need it)
  • The ipu-bridge OVTID858 entry is straightforward and ready to submit
  • The INT3472 type 0x08 (DVDD) addition is straightforward and ready to submit
  • INT3472_MAX_SENSOR_GPIOS increase from 3 to 4 may affect other platforms — needs review

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions