Skip to content

Patch enabling speakers, mic, camera, suspend and hibernate, and touchpad configuration for surface pro 11 intel. - #1990

Open
AndreGilerson wants to merge 21 commits into
linux-surface:masterfrom
AndreGilerson:master
Open

Patch enabling speakers, mic, camera, suspend and hibernate, and touchpad configuration for surface pro 11 intel.#1990
AndreGilerson wants to merge 21 commits into
linux-surface:masterfrom
AndreGilerson:master

Conversation

@AndreGilerson

Copy link
Copy Markdown

Fixed soundwire matching the wrong ids, because the amplifiers on the surface use class ids instead of uinique ids. Furthermore the added a second DAI entry to the RT1320 coder info, that enables the mic. Added endpoints to the surface machine table entry.

Tested on ubuntu 25.10 with 6.17. Further testing required for other kernels.

The quality of the Mic is at the moment a bit low, some optimization is required.

@diwakar-s-maurya

Copy link
Copy Markdown

Tested on Surface Pro for Business 11th Edition with Intel (SKU Surface_Pro_11th_Edition_With_Intel_For_Business_2103), Ubuntu 25.10, kernel 6.17.13-surface-surface (built from linux-surface/kernel tag surface/v6.17.13-3 with patches 0017–0022 applied).

Working: Speakers, microphone detected and functional. I did not test HDMI audio outputs.
Without this patch, it was not working.

Note on topology: The patch sets sof_tplg_filename to sof-lnl-rt1320-l0.tplg, which doesn't exist in any released sof-bin or firmware-sof-signed package (checked up to sof-bin v2025.12.2). In practice it's not needed — the get_function_tplg_files callback in the patch causes the driver to load existing SDCA split topologies instead:

sof-audio-pci-intel-lnl 0000:00:1f.3: Using function topologies instead intel/sof-ipc4-tplg/sof-lnl-rt1320-l0.tplg
sof-audio-pci-intel-lnl 0000:00:1f.3: loading topology 0: intel/sof-ipc4-tplg/sof-sdca-1amp-id2.tplg
sof-audio-pci-intel-lnl 0000:00:1f.3: loading topology 1: intel/sof-ipc4-tplg/sof-sdca-mic-id4.tplg

Might be worth noting in the PR description that the monolithic topology file isn't needed.

First boot probe failure: On the very first boot, the SOF probe failed with sof_probe_work failed err: -2 and no sound card was created. A modprobe -r snd-sof-pci-intel-lnl && modprobe snd-sof-pci-intel-lnl resolved it, and all subsequent reboots have been fine.

Mixer switches default to off: After the driver loads, the RT1320 codec's output and capture switches are off. Speakers and mic show up in desktop audio settings but produce no sound until enabled:

# Speaker output
amixer -c 0 cset name='rt1320-1 OT23 L Switch' on
amixer -c 0 cset name='rt1320-1 OT23 R Switch' on

# Microphone capture
amixer -c 0 cset name='rt1320-1 FU Capture Switch' on,on,on,on

These persist with alsactl store, but ideally a UCM profile should set the defaults so it works out of the box.

@AndreGilerson AndreGilerson changed the title Patch enabling speakers and the mic for surface pro 11 intel. Patch enabling speakers, mic, camera, suspend and hibernate, and touchpad configuration for surface pro 11 intel. Mar 8, 2026
@AndreGilerson

Copy link
Copy Markdown
Author

@diwakar-s-maurya Thanks for the feedback, I have integrated this into the new contrib scripts in my newest commits which should auto configure the audio devices.

@qzed

qzed commented Mar 13, 2026

Copy link
Copy Markdown
Member

@AndreGilerson Thanks! Would you mind opening a separate PR for the kernel changes at https://github.com/linux-surface/kernel/? (It's just a bit easier to review and I've pretty much automated generating patches from the kernel repo by now).

@Ringbaer

Copy link
Copy Markdown

Are there any news on this pr? Does it get merged in near future? I would love to use my integrated speakers.

@Timeo04

Timeo04 commented Apr 30, 2026

Copy link
Copy Markdown

Is there anything we could do (without deep knowledge of the linux kernel, ...) in helping to get this pull request merged or to at least adapt the patches for a newer kernel version than 6.17?
It would be great to be able to use camera and especially sound on the SP11 Pro Intel.

@AndreGilerson

Copy link
Copy Markdown
Author

Sorry life and work happened during the last few weeks, so I was not able to focus on this anymore. But the changes are open on my branch, so maybe someone else could forward this.

I am however happy to say that I am using my kernel patches on my surface 11 with nixos the whole time and it is so stable that is has become my daily driver. I am actually flirting with applying the patches to the 7.0 kernel, because I have read somewhere that the entire sleep system, for which i have patches too, works way more cleanly with that kernel version. But I will probably only get to it in 2 weeks.

Fixed soundwire matching the wrong ids, because the amplifiers on the surface use class ids instead of uinique ids.
Furthermore the added a second DAI entry to the RT1320 coder info, that enables the mic. Added endpoints to the surface
machine table entry.
To use the cameras, one does need a more up to date version of libcamera than e.g. the ubuntu apt sources provide. Libcamera can be found in: https://github.com/libcamera-org/libcamera. This has been developed with commit b18132713165210d45d66d54e7ae6086a021a47e. When installed, using cam -l should show both cameras, and qcam should be able to view a video stream of both. Please note, that the image quality will be terrible, as the driver contains no optimization yet.
…es the surface immediately goes back to sleep
…1876.

Map mic component name from "rt1320-1" to "rt1320-dmic" in the card
components string. The old name didn't match the upstream UCM regex
which only accepts -dmic/-sdca suffixes. This follows the existing
convention used by rt712-dmic and rt713-dmic.

Requires rt1320-dmic.conf in alsa-ucm-conf (not yet upstream).

A bit hacky to change an existing patch, but should be fine atm.
Enable safe validation of contrib package installation without
modifying the system. Adds --dry-run to cameras, audio, and
hibernate-setup scripts. Creates new install.sh scripts (with
--dry-run, --install, --remove) for suspend and touchpad packages
that previously required manual file copies.
Userspace audio configs for Surface Pro 11 (Intel Lunar Lake):
RT1320 DMIC UCM config, PipeWire speaker EQ, mic noise suppression,
and install script with mixer switch initialization. Install script
created with assitance from claude code.
…tarting logind terminates all login sessions, which kills GNOME and leaves you on a broken TTY. The logind drop-in config (LidSwitchIgnoreInhibited=no) will take effect on the next reboot instead, which is safe.
Add udev rule and libinput quirk for the Type Cover touchpad:
- Group keyboard (045E:0C8E) and touchpad (045E:0C8D) into the same
  libinput device group to enable disable-while-typing (DWT)
- Tune edge palm detection threshold as fallback to firmware palm rejection
- Include install/uninstall script with dry-run support

Install script created with the assistance of claude code.
Automated setup for the full IPU7 camera pipeline: builds ipu7-drivers,
installs Intel firmware/libs, patches and builds the camera HAL with
Surface Pro 11 sensor configs (IMX681 front, OV13858 rear), and builds
the GStreamer icamerasrc plugin. Includes v4l2loopback virtual camera
bridge so standard apps (Firefox, Zoom, Chrome) can use the cameras,
with udev/WirePlumber rules to hide the 32 raw ISYS nodes. Extracts
AIQB tuning files from Microsoft firmware for optimal image quality,
with upstream fallback when firmware is unavailable.

Install script created with the assistance of claude code.
@AndreGilerson

Copy link
Copy Markdown
Author

Opened a separate PR for the kernel changes in linux-surface/kernel#164. Removed the kernel patches from this PR, just keeping the contrib packages. Furthermore I tested them on a clean ubuntu 26.04 install and applied some fixes.

Beyond the known display-pipeline hang, two more Lunar Lake issues drove
second-cycle suspend hangs:

- GPE 0xAB: spurious TRP3 (00:07.3) hot-plug interrupt on a port that
  doesn't exist on this SKU. Firmware's _LAB handler calls undefined
  SLAB, flooding dmesg with AE_NOT_FOUND and causing printk contention
  during dpm_suspend. Mitigated by acpi_mask_gpe=0xAB plus new
  surface-disable-gpe-ab.service (boot-time chipset disable) and
  52-gpe-ab-disable sleep hook (re-applied every resume; the disable
  state isn't fully persistent across s2idle).

- pcie_aspm.policy=powersupersave drove the TB4 root ports into L1.2
  across s2idle, wedging the xhci/NHI controllers. Switched to
  policy=default; pcie_aspm=force is retained so ASPM stays enabled.

Also: acpi_osi -> "Windows 2022", install.sh switches to install(1)
and warns if powersupersave is still on the cmdline, README updated
with measured drain (~200 mW avg, ~10 day standby) replacing the
prior ~351 mW estimate.

README.md and install.sh script adjusted using claude code.
@Timeo04

Timeo04 commented May 17, 2026

Copy link
Copy Markdown

@AndreGilerson Thanks for your work again!
I've compiled a 6.18.18 kernel with the patches from your repository in the feature/S11-specific-patches branch; it worked apart from the multitouch patch, which seems to have changed a bit in the meantime so it needed a little adaption, but then it did work.

After switching from the 6.17 kernel with your patches to the 6.18 one, sound still worked, and also the cameras showed in cam -l. Some weirdness I encountered there: at some boots it only shows the rear camera, and sometimes all three of them. When it doesn't work, thats the output of dmesg:

sudo dmesg | grep -i "ipu\|imx681\|ov13858"
[    0.009249] ACPI: SSDT 0x0000000071FFD000 0000E0 (v02 INTEL  IpuSsdt  00001000 INTL 20210105)
[    6.802260] intel_ipu7: module is from the staging directory, the quality is unknown, you have been warned.
[    6.822952] intel-ipu7 0000:00:05.0: enabling device (0000 -> 0002)
[    6.822960] intel-ipu7 0000:00:05.0: Device 0x645d (rev: 0x4)
[    6.822962] intel-ipu7 0000:00:05.0: IPU7 PCI BAR0 base 0x000000204e000000 BAR2 base 0x000000205130a000
[    6.822990] intel-ipu7 0000:00:05.0: IPU7 PCI BAR0 mapped at 00000000e4ffae70
[    6.825405] intel-ipu7 0000:00:05.0: IPU7 SKU 0 in secure mode mask 0x0
[    6.826765] ov13858 i2c-OVTID858:00: Powering up sensor
[    6.826880] ov13858 i2c-OVTID858:00: Clock enabled
[    6.829609] ov13858 i2c-OVTID858:00: Regulators enabled
[    6.837950] intel-ipu7 0000:00:05.0: firmware cpd file: intel/ipu/ipu7_fw.bin
[    6.850728] imx681 i2c-SONY0681:00: supply dvdd not found, using dummy regulator
[    6.850776] imx681 i2c-SONY0681:00: supply dovdd not found, using dummy regulator
[    6.850986] imx681 i2c-SONY0681:00: no endpoint found in firmware node
[    6.850989] imx681 i2c-SONY0681:00: endpoint parse failed: -6
[    6.860001] ov13858 i2c-OVTID858:00: Reset de-asserted, sensor should be ready
[    6.860013] ov13858 i2c-OVTID858:00: Attempting to read chip ID from register 0x300a
[    6.862253] ov13858 i2c-OVTID858:00: Chip ID read result: ret=0, val=0x00d855 (expected 0x00d855)
[    6.862264] ov13858 i2c-OVTID858:00: Chip ID verified successfully!
[    6.862303] ov13858 i2c-OVTID858:00: Powering down sensor
[    6.862343] ov13858 i2c-OVTID858:00: Regulators disabled
[    6.862547] ov13858 i2c-OVTID858:00: Clock disabled
[    6.865678] intel-ipu7 0000:00:05.0: FW binary0 info:
[    6.865689] intel-ipu7 0000:00:05.0: Name:  psys
[    6.865692] intel-ipu7 0000:00:05.0: Version:  1.1.9.240627135220
[    6.865695] intel-ipu7 0000:00:05.0: Timestamp:  build_id:331942702
[    6.865696] intel-ipu7 0000:00:05.0: Commit:  commit_id:d84f5c35
[    6.865698] intel-ipu7 0000:00:05.0: FW binary1 info:
[    6.865700] intel-ipu7 0000:00:05.0: Name:  isys
[    6.865701] intel-ipu7 0000:00:05.0: Version:  1.1.9.240627135318
[    6.865702] intel-ipu7 0000:00:05.0: Timestamp:  build_id:3823931988
[    6.865703] intel-ipu7 0000:00:05.0: Commit:  commit_id:d84f5c35
[    6.873167] intel-ipu7 0000:00:05.0: Found supported sensor OVTID858:00
[    6.874014] intel-ipu7 0000:00:05.0: Found supported sensor SMO55F0:00
[    6.879025] intel-ipu7 0000:00:05.0: Found supported sensor SONY0681:00
[    6.879146] intel-ipu7 0000:00:05.0: Connected 3 cameras
[    6.881740] intel-ipu7 0000:00:05.0: Sending BOOT_LOAD to CSE
[    6.949973] intel-ipu7 0000:00:05.0: Sending AUTHENTICATE_RUN to CSE
[    6.980299] intel-ipu7 0000:00:05.0: CSE authenticate_run done
[    7.169779] intel_ipu7_isys: module is from the staging directory, the quality is unknown, you have been warned.
[    7.185599] intel_ipu7_isys.isys intel_ipu7.isys.40: bind ov13858 1-0010 nlanes is 4 port is 0
[    7.188932] intel_ipu7_psys: loading out-of-tree module taints kernel.
[    7.188961] intel_ipu7_psys: module verification failed: signature and/or required key missing - tainting kernel
[    7.214036] intel_ipu7_psys.psys intel_ipu7.psys.40: IPU psys probe done.
[   83.016758] ov13858 i2c-OVTID858:00: Powering up sensor
[   83.017016] ov13858 i2c-OVTID858:00: Clock enabled
[   83.019648] ov13858 i2c-OVTID858:00: Regulators enabled
[   83.050047] ov13858 i2c-OVTID858:00: Reset de-asserted, sensor should be ready
[   83.173878] intel_ipu7_isys.isys intel_ipu7.isys.40: csi2-0 error: Received packet is too long
[   83.207254] intel_ipu7_isys.isys intel_ipu7.isys.40: csi2-0 error: Received packet is too long
[   83.240649] intel_ipu7_isys.isys intel_ipu7.isys.40: csi2-0 error: Received packet is too long
[   83.274039] intel_ipu7_isys.isys intel_ipu7.isys.40: csi2-0 error: Received packet is too long
[   83.340798] intel_ipu7_isys.isys intel_ipu7.isys.40: csi2-0 error: Received packet is too long
[   83.374167] intel_ipu7_isys.isys intel_ipu7.isys.40: csi2-0 error: Received packet is too long
[   83.407576] intel_ipu7_isys.isys intel_ipu7.isys.40: csi2-0 error: Received packet is too long
[   83.440963] intel_ipu7_isys.isys intel_ipu7.isys.40: csi2-0 error: Received packet is too long
[   83.474383] intel_ipu7_isys.isys intel_ipu7.isys.40: csi2-0 error: Received packet is too long
[   83.507740] intel_ipu7_isys.isys intel_ipu7.isys.40: csi2-0 error: Received packet is too long
[   88.182319] ipu7_isys_csi2_error: 139 callbacks suppressed
[   88.182330] intel_ipu7_isys.isys intel_ipu7.isys.40: csi2-0 error: Received packet is too long
[   88.215748] intel_ipu7_isys.isys intel_ipu7.isys.40: csi2-0 error: Received packet is too long
[   88.249128] intel_ipu7_isys.isys intel_ipu7.isys.40: csi2-0 error: Received packet is too long
[   88.282535] intel_ipu7_isys.isys intel_ipu7.isys.40: csi2-0 error: Received packet is too long
[   88.315877] intel_ipu7_isys.isys intel_ipu7.isys.40: csi2-0 error: Received packet is too long
[   88.349313] intel_ipu7_isys.isys intel_ipu7.isys.40: csi2-0 error: Received packet is too long
[   88.382690] intel_ipu7_isys.isys intel_ipu7.isys.40: csi2-0 error: Received packet is too long
[   88.416081] intel_ipu7_isys.isys intel_ipu7.isys.40: csi2-0 error: Received packet is too long
[   88.449516] intel_ipu7_isys.isys intel_ipu7.isys.40: csi2-0 error: Received packet is too long
[   88.482883] intel_ipu7_isys.isys intel_ipu7.isys.40: csi2-0 error: Received packet is too long
[   92.368780] ov13858 i2c-OVTID858:00: Powering down sensor
[   92.368838] ov13858 i2c-OVTID858:00: Regulators disabled
[   92.369127] ov13858 i2c-OVTID858:00: Clock disabled

However the mic stopped working; I managed to get it working again as in #1876 (comment)
Probably due to an update of alsa-ucm or something like that. The mic quality (even without the denoise) seems pretty decent.

Additionally I've tried your contrib scripts for the audio and the cameras:

The audio script worked well; it now sounds better with the EQ. I did have to enable the systemd filter-chain service such that it would start automatically after rebooting. Maybe this would be worth noting in the readme. And if the denoise filter is active, the mic-icon in gnome is always shown; should it be like that?
One little issue that I have with the EQ: There are now two volume controls, and the speaker volume seems to get reset to around 50% on reboot, and then even if the volume for the EQ-output is on 100% it isn't that loud. But thats really only a minor issue.

The camera script didn't work that well; it couldn't find the ia_imaging-ipu7x module in step 3, apparently because on my system it is called libia_imaging: (from /usr/lib/pkgconfig/ia_imaging-ipu7x.pc)

prefix=/usr
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include/ipu7x

Name: libia_imaging
Description: ia_imaging libraries
URL: http://www.intel.com
Version:
Libs: -L${libdir}
Cflags: -I${includedir}/ia_imaging

By replacing the name here I could get the script to continue, but somehow I then wasn't able to get v4l2loopback installed running on a non-rpm kernel; maybe I would have to compile it from source.

And another issue: the script wasn't able to extract the AIQB files from the .msi, it didn't find them; maybe the .msi changed somehow? On the Microsoft website it is dated to yesterday.

One issue that I've found with the lid sensor (which also works now for me, although a bit inconsistent): When suspending via power-button and then closing the lid, the surface unsuspends. Do you know if this is normal?

However, thank you a lot for your effort and its already really cool to be able to use the (now well-sounding) speakers and suspend, ... working a lot better!

@AndreGilerson

AndreGilerson commented May 17, 2026

Copy link
Copy Markdown
Author

@Timeo04 Thanks for the input! Since i only have this one device that I am using for development and testing (and even daily use, but i am using two separate SSDs for that now...) it is always difficult to discern whether an old change, or some other artifact is interacting with issue i am currently working on.

As a first step because @qzed also mentioned that they are going to auto generate the patches later anyway, can you instead of using the patches from this repo, please just use my kernel with all the changes applied: https://github.com/AndreGilerson/linux-surface-kernel/tree/v6.18-surface-devel ?

Can you also please check the following list of problems so that i have not missed anything? I will be opening up separate issues for all the subsystems in my forks later, because I am starting to lose track of everything.

Cameras (kernel side)

  1. Intermittent camera detection on boot — sometimes only the rear (OV13858) shows up, sometimes all three. When broken, dmesg shows repeating intel_ipu7_isys ... csi2-0 error: Received packet is too long from the front sensor path.
  2. IMX681 endpoint parse failure: imx681 i2c-SONY0681:00: no endpoint found in firmware node / endpoint parse failed: -6 early in probe.
    Audio (kernel / UCM)
  3. Mic broke after upgrade. Using the workaround from issue [Data] Surface Pro 11 (Intel Core Ultra 7 266V, Business Model) - Partial support, mic still missing #1876 works.

Audio contrib:

  1. Document that the systemd filter-chain service must be enabled, it doesn't auto-start after install/reboot.
  2. Denoise filter keeps the GNOME mic icon permanently lit.
  3. Two volume sliders + speaker volume resets to ~50% on reboot. At that level, even with EQ output at 100% the speakers are quieter than before.

Camera Contrib:

  1. Module name mismatch, script looks for ia_imaging-ipu7x but the pkg-config Name: is libia_imaging (file /usr/lib/pkgconfig/ia_imaging-ipu7x.pc).
  2. v4l2loopback install fails on non-rpm kernels, script path assumes rpm/dkms layout. Needs a fallback (build-from-source / generic dkms) for Arch/Debian users.
  3. AIQB extraction from the Microsoft .msi no longer finds the files.

Lid / suspend:

  1. Closing the lid after a power-button suspend wakes the device.

@Timeo04

Timeo04 commented May 18, 2026

Copy link
Copy Markdown

@AndreGilerson Thank you for your response, that sounds good.

I wasn't sure if it was the idea to directly compile the kernel from your kernel repository, but thank you for your hint, then I will do so the next time I compile the kernel.

Your list seems right and so far complete. For the 2. point in Camera Contrib, I think the issue is it won't install from rpm fusion when having a kernel-devel installed from a kernel not installed from rpm.

@zR-JB

zR-JB commented Jun 8, 2026

Copy link
Copy Markdown

I got the pro 12 intel, and issues seem to be pretty much the same as with pro 11 intel: #2144

Will these patches, when merged also apply to this device? If not, I would be happy to contribute to similar patches for the pro 12!

@Ringbaer

Copy link
Copy Markdown

Some notes from testing this on a Surface Pro 11 for Business (Intel / Lunar Lake) with Fedora 43. Fair warning first: I'm not a kernel or camera developer, and I worked most of this out with the help of an AI assistant. So please read the below as observations from one device, not as a diagnosis. Some of it may be wrong. I'm posting it because a few of the findings would have saved me a lot of time if I had known them earlier.

Kernel is your v7.0-surface-devel branch (reports as 7.0.0+), built with make binrpm-pkg. Both contrib packages from this PR are installed.

Audio

Speakers and microphone work.

There is one thing that stopped the card from working at all here, at least with alsa-ucm 1.2.16. The card reports:

Components: 'HDA:80862820,80860101,00100000  cfg-amp:1 iec61937-pcm:7,6,5 spk:rt1320 mic:rt1320-1'

No cfg-mics:N in there. Since ucm2/sof-soundwire/sof-soundwire.conf only defines the Mics variable when cfg-mics is present, the UCM import fails:

ALSA lib ucm_subs.c:1078:(uc_mgr_get_substituted_value) [error.ucm] variable '${var:Mics}' is not defined in this context!
ALSA lib main.c:1805:(snd_use_case_mgr_open) [error.ucm] failed to import hw:0 use case configuration -22

With no valid UCM profile, PipeWire only offers off and pro-audio, so there are no sinks or sources at all. The symptom looks like a driver problem ("card is detected but there's no output device anywhere"), which is what threw me off for a while.

Defining Mics "1" next to Mics1 "0" in sof-soundwire.conf was enough:

After that the HiFi profile shows up and speakers and mic work normally.

I don't know whether that belongs in the machine driver (setting cfg-mics) or as a UCM override shipped with contrib/surface-pro-11-audio. The current install.sh installs rt1320-dmic.conf and the sofsoundwire alias, which doesn't cover this.

Build notes for Fedora

None of these are bugs, but they cost time on a non-Debian distro.

binrpm-pkg needs elfutils-devel, otherwise it stops with:

error: Failed build dependencies:
        (elfutils-devel or libdw-devel) is needed by kernel-7.0.0+-1.x86_64

If an existing distro kernel config is used as a starting point, make olddefconfig turns off CONFIG_VIDEO_IMX681 and CONFIG_VIDEO_VD55G0 without saying anything, because the older config doesn't know them. The result is that only the rear camera shows up and the front and IR sensors are missing entirely. Took me a while to find that one.

contrib/surface-pro-11-cameras/install.sh needs PKG_CONFIG_PATH=/usr/lib/pkgconfig. ipu7-camera-bins puts its .pc files in /usr/lib, Fedora's pkg-config looks in /usr/lib64, so the HAL build stops at:

-- Checking for module 'ia_imaging-ipu7x'
--   Package 'ia_imaging-ipu7x' not found
CMake Error at cmake/FindIA_IMAGING.cmake:27 (message):
  IA_IMAGING-ipu7x not found

ipu7-camera-hal includes <jsoncpp/json/json.h>, but on Fedora those headers are in /usr/include/json/:

src/platformdata/JsonParserBase.h:19:10: fatal error: jsoncpp/json/json.h: No such file or directory

A symlink /usr/include/jsoncpp/json -> /usr/include/json fixes it.

The RPM Fusion v4l2loopback akmod won't build against a self-built kernel:

error: Failed build dependencies:
        kernel-devel-uname-r = 7.0.0+ is needed by v4l2loopback-kmod-0.15.4-1.fc43.x86_64

The binrpm-pkg devel package doesn't provide that. Building v4l2loopback from upstream git against /usr/src/kernels/<ver> works fine.

Out-of-tree modules need a manual depmod afterwards, modules_install skips it with missing 'System.map' file.

Cameras with the HAL and the bridge

This works, with a few things I noticed.

Only one camera can stream per boot. When the second bridge instance starts, it gets:

CamHAL[WAR] RequestThread: <id1>@waitFrame, time out happens, wait recovery
CamHAL[ERR] V4l2_device_cc: Poll: Device node fd 18 poll timeout.

and the first camera doesn't recover until a reboot.

HAL init is not reliable either. I regularly get:

CamHAL[ERR] SensorHwCtrl: sensor output sub device is not set

even when the sensor probed fine and is in the media graph (media-ctl -p shows imx681 3-0010 linked). Restarting the bridge service sometimes helps, sometimes not.

Because the bridge streams into v4l2loopback continuously from session start, the privacy LED stays on all the time and roughly 30-50% of a core is used even when nothing is reading the camera. As a user that's a bit unfortunate, since the LED no longer tells you whether the camera is actually in use.

AE oscillates, which shows up as visible brightness pulsing. antibanding-mode=50 reduces it, and with ae-mode=manual plus fixed exposure and gain it goes away completely, so it looks like an AE convergence thing rather than sensor timing. The Microsoft AIQB files do get loaded:

CamHAL[INF] AiqInitData: aiqb file name imx681_MSHW0580_LNL.aiqb

so it doesn't seem to be a calibration issue.

Qt applications (kamoso in my case) crash reliably on the v4l2loopback devices. The systemctl --user restart wireplumber in the bridge script, five seconds after camera start, also kills applications that happen to be open at that moment.

Cameras through libcamera directly

Once the kernel has the imx681 and vd55g0 drivers, libcamera's simple pipeline handler with the software ISP picks up all three sensors:

1: Internal front camera (\_SB_.PC00.I2C5.CAMF)
2: 'vd55g0' (\_SB_.PC00.I2C3.CAM3)
3: Internal back camera (\_SB_.PC00.I2C3.CAMR)

Start and stop happen on demand there, and the LED matches actual use, so I ended up switching to this and disabling the bridge. A few gaps I ran into:

imx681 has no sensor helper in libcamera, so AGC runs without a gain model:

IPASoft: Failed to create camera sensor helper for imx681
IPASoft: Minimum gain is zero, that can't be linear

Adding a helper with the Sony model gain = 1024 / (1024 - code), which is the formula the kernel driver uses, and black level 64 at 10 bits, made the exposure stable.

ov13858 has no hflip/vflip and no rotation control, camera_orientation is read-only with no rotate control next to it:

/dev/v4l-subdev6: camera_orientation 0x009a0922 (menu) : min=0 max=2 default=1 value=1 (Back) flags=read-only

The sensor is mounted upside down in this device, and as far as I understand libcamera can only compensate for that if the driver reports it. I took the ov13b10 implementation as a template (register 0x3820, mirror on bit 3, flip on bits 4+5, together with the ±1 window offset shift on 0x3811/0x3813 that keeps the Bayer order intact) and added V4L2_CID_CAMERA_SENSOR_ROTATION = 180. That gave an upright image with unchanged colours.

There also seems to be a mismatch between array and lens on ov13858: the full array is larger than the illuminated circle, so the corners of the full resolution mode are black. Cropping that mode to 3840x2880 centred got rid of them. On imx681 the field of view is very wide, and a centred crop to 3496x2400 made it more usable here, though that's more a matter of taste. Both values were found by trial and error on a single device, so I wouldn't trust them too far.

imx681 only has one full resolution mode, so a 1080p request gets cropped out of the full array, which is about a quarter of the area and looks like a strong zoom in video calls. A binned mode (something around 1748x1200) would presumably give applications the full field of view. ov13858 doesn't have that problem because of its binned modes, but 1080p taken from those is fairly soft, since the software ISP does no sharpening.

Neither sensor has tuning files, so the IPA falls back to uncalibrated defaults:

IPAProxy: Configuration file 'imx681.yaml' not found for IPA module 'simple', falling back to 'uncalibrated.yaml'

and the image looks flat. A hand-adjusted CCM works as a stopgap.

One limitation that doesn't seem to be the HAL's fault: only one camera at a time works on this path as well. libcamera's simple pipeline handler appears to treat cameras that share a media device as mutually exclusive, so a second client either gets:

Camera '\_SB_.PC00.I2C5.CAMF' is already in use.

or doesn't see any cameras at all.

Overall the image quality on this path is fine for video calls but clearly below Windows, mostly because of the missing tuning and the lack of sharpening or denoise in the software ISP.

One more thing

The patch directories here target 6.17/6.18 while current linux-surface kernels are at 6.19.x, which is why I ended up on the v7.0 branch for all of the above.

If any of this is useful and you want more detail, exact register values, full logs, or a test of some specific change on this hardware, just say so.

@leihua-dev

Copy link
Copy Markdown

Some data from a Surface Pro 11 for Business (Intel, Core Ultra 7 266V) on Arch Linux, in case it's useful.

I'm running a kernel built straight from the HEAD of your v6.18-surface-devel branch (8ab9347b), with the audio and suspend contrib packages installed.

Speakers work. The internal speakers come up as the default sink and have been working through two months of daily use. Worth mentioning because #1852 still lists internal speakers as not working on this device, so people reading that issue may not realise it is already solved on your branch.

The internal mic does not, and I think it is exactly what your v7.0 commit ecf74df7 describes.

Card components here:

'HDA:80862820,80860101,00100000  cfg-amp:1 iec61937-pcm:7,6,5 spk:rt1320'

versus what @Ringbaer reported on v7.0-surface-devel:

'... spk:rt1320 mic:rt1320-1'

so the mic DAI link is never created on 6.18.

The hardware side looks fine, both SDCA functions are discovered:

acpi device:28: find_sdca_function: SDCA function SmartMic (type 3) at 0x2
acpi device:29: find_sdca_function: SDCA function SmartAmp (type 1) at 0x4
acpi device:2b: find_sdca_function: SDCA function SmartMic (type 3) at 0x2
acpi device:2c: find_sdca_function: SDCA function SmartAmp (type 1) at 0x4
sof-audio-pci-intel-lnl 0000:00:1f.3: DMICs detected in NHLT tables: 0

but then only the amp and HDMI topologies get loaded:

sof-audio-pci-intel-lnl 0000:00:1f.3: Using function topologies instead intel/sof-ipc4-tplg/sof-sdca-1amp-id2.tplg
sof-audio-pci-intel-lnl 0000:00:1f.3: loading topology 0: intel/sof-ipc4-tplg/sof-sdca-1amp-id2.tplg
sof-audio-pci-intel-lnl 0000:00:1f.3: loading topology 1: intel/sof-ipc4-tplg/sof-hdmi-pcm5-id3.tplg

/proc/asound/sofsoundwire/ has only playback PCMs (pcm2p pcm5p pcm6p pcm7p), no capture, and arecord -l is empty. sof-sdca-mic-id4.tplg is present in /lib/firmware/intel/sof-ipc4-tplg/, it just never gets requested.

That lines up with the comment in ecf74df7 about the monolithic 1amp-id2 base loading and losing the SmartMic. a2d374a7 on v6.18-surface-devel still has .sof_tplg_filename = "sof-sdca-1amp-id2.tplg", while v7.0 switched to sof-sdca-1amp-dummy.tplg plus the SmartAmp/SmartMic name forcing in sof_sdw.c.

Would you consider backporting that part to v6.18-surface-devel? From the diff it looks like roughly 13 lines across sof_sdw.c and soc-acpi-intel-lnl-match.c. I would rather not move my base to 7.0 just for this, since 6.18 is otherwise stable here.

One more data point on @Ringbaer's UCM finding: on alsa-ucm-conf 1.2.15.3 the card works fine, because sof-soundwire.conf still defines Mics1 "0" as a fallback in its Define block, so the missing cfg-mics in the components string does not break the import. The failure he hit looks specific to 1.2.16+, which probably makes it harder to reproduce for anyone still on an older alsa-ucm-conf.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants