diff --git a/docs/linux-hdmi/OPERATION_PipeWire_Kaisa_HDMI.md b/docs/linux-hdmi/OPERATION_PipeWire_Kaisa_HDMI.md index 6ddd728b9c..c3ec7de02c 100644 --- a/docs/linux-hdmi/OPERATION_PipeWire_Kaisa_HDMI.md +++ b/docs/linux-hdmi/OPERATION_PipeWire_Kaisa_HDMI.md @@ -102,15 +102,40 @@ pactl list short sinks **自动化(未随 deb 提供)**:登录后自动 **`set-card-profile` / `set-default-sink` / 开 IEC958**、以及 **按 Jack 轮询默认 sink** 等,**尚未**在本仓库验证完毕,**`kaisa-hdmi-pipewire-fix` ≥0.3.0** 仅装 **UCM2 + WirePlumber 片段**。若你自行编写 **user systemd**,勿在 **UCM 模式**下执行会强制 **pro-audio** 的命令。**插入 HDMI 时是否弹出输出选择** 由 **桌面/会话** 决定。 +### UCM Jack:自动显示/隐藏(安装与验收) + +**思路**:UCM2 在 **[`reference/ucm2/GoogleKaisa/sof-rt5682/HiFi.conf`](../../reference/ucm2/GoogleKaisa/sof-rt5682/HiFi.conf)** 为 **HDMI1/2/3** 配置 **`JackControl "HDMI/DP,pcm=N Jack"`** 与 **`IEC958`** 开关序列;WirePlumber 通过 **[`wireplumber/main.lua.d/60-kaisa-ucm.lua`](../../wireplumber/main.lua.d/60-kaisa-ucm.lua)** 对 **`sof-rt5682`** 启用 **`api.alsa.use-ucm`** / **`api.acp.auto-port`**,让 ACP 按端口可用性暴露路由(**Jack off 时该 HDMI 设备不应对桌面表现为随意可用**)。 + +**安装(在仓库根目录,需 sudo)**: + +```bash +./scripts/disable-kaisa-pro-audio-wireplumber.sh # 禁用强制 pro-audio 片段 +# 若曾在 /etc/wireplumber 装过同类片段: +# ./scripts/disable-kaisa-pro-audio-wireplumber.sh --system + +./scripts/install-kaisa-ucm-overlay.sh # UCM -> /usr/share/alsa/ucm2/ ,Lua -> /usr/share/wireplumber/main.lua.d/ +``` + +**验收**: + +1. **`pactl list cards`**:声卡 **活动配置** 为 **`HiFi`**(或 UCM 定义的 profile),**非**长期锁在 **`pro-audio`**。 +2. **`pactl list short sinks`**:出现 **`HiFi__…`** 风格 sink(名称以本机为准)。 +3. **插拔 HDMI**:对应 **`HDMI/DP,pcm=N Jack`** on/off 时,GNOME/ACP 下该路 **显示或不可用**(具体 UI 表现因桌面版本而异;若仅「灰掉/不可用」亦属常见)。 +4. **无声排障**:若 Jack on 仍无声,仍按本文 **ELD / 子设备 / `set_hw_params`** 段落处理;UCM 只管 **Jack 驱动的可用性**,不保证显示器 OSD/ELD 始终一致。 + +**卸载/回退 UCM overlay**:**`sudo apt install --reinstall alsa-ucm-conf`** 恢复 vendor **`conf.d/sof-rt5682/`**;并 **`sudo rm -f /usr/share/wireplumber/main.lua.d/60-kaisa-ucm.lua`** 后重启 **`wireplumber`/`pipewire`**。详见 §4.5。 + --- ## 3. 验证 +**本节默认针对 §2「pro-audio 对照」路径**;若已按上文 **「UCM Jack:自动显示/隐藏」** 安装 overlay,**活动配置宜为 `HiFi`**,以该节验收表为准。 + ```bash pactl list cards ``` -**活动配置** 应为 **`pro-audio`**。 +**活动配置** 应为 **`pro-audio`**(对照实验时)。 ```bash pactl get-default-sink @@ -315,6 +340,7 @@ cd /path/to/chromebox_10th_audio_driver - 采集命令:`./scripts/capture-ubuntu-audio-baseline.sh` - 内容:`manifest.txt`、`topology.txt`、`user-wireplumber-conf.tar.gz`(若存在)等;**目录默认被 `.gitignore` 忽略**,仅在本机磁盘保留 - **较早快照(仅供参考)**:`audio_topology/baseline-stash/20260407_235227_jack-Kaisa/`(`2026-04-07T23:52:31+08:00`) +- **仓库纳入 UCM2 / WirePlumber Lua 源码后的追加采集**:`audio_topology/baseline-stash/20260408_001125_jack-Kaisa/`(`2026-04-08T00:11:25+08:00` 左右,以 `manifest.txt` 为准)。**在系统上执行 `./scripts/install-kaisa-ucm-overlay.sh` 且 `pactl list cards` 已显示 `HiFi` 后**,请再运行一次 **`capture-ubuntu-audio-baseline.sh`**,用新目录作为「UCM 已生效」的黄金快照。 - 快速锚点(供对照):`IEC958 numid=14/20/26 = on`;ELD/Jack/默认 sink 等以该基线的 `topology.txt` 与采集时现场为准(建议同时记录 `pactl get-default-sink` 与 `wpctl inspect @DEFAULT_AUDIO_SINK@`) **本机一次对照(`pro-audio` 下 PipeWire 节点名 ↔ ALSA,以 `wpctl inspect` 为准)**: diff --git a/docs/linux-hdmi/wireplumber/50-kaisa-sof-rt5682-hdmi.conf b/docs/linux-hdmi/wireplumber/50-kaisa-sof-rt5682-hdmi.conf new file mode 100644 index 0000000000..19d9ab4533 --- /dev/null +++ b/docs/linux-hdmi/wireplumber/50-kaisa-sof-rt5682-hdmi.conf @@ -0,0 +1,36 @@ +# +# Kaisa (sof-rt5682) — pro-audio 对照实验用(与 UCM 路线互斥) +# 复制到 ~/.config/wireplumber/wireplumber.conf.d/ 后重启 wireplumber。 +# + +monitor.alsa.rules = [ + { + matches = [ + { device.name = "alsa_card.pci-0000_00_1f.3-platform-cml_rt5682_def" } + ] + actions = { + update-props = { + device.profile = "pro-audio" + api.acp.auto-profile = false + api.acp.auto-port = false + } + } + } + + { + matches = [ { node.name = "alsa_output.pci-0000_00_1f.3-platform-cml_rt5682_def.pro-output-0" } ] + actions = { update-props = { priority.session = 1000 } } + } + { + matches = [ { node.name = "alsa_output.pci-0000_00_1f.3-platform-cml_rt5682_def.pro-output-2" } ] + actions = { update-props = { priority.session = 1100 } } + } + { + matches = [ { node.name = "alsa_output.pci-0000_00_1f.3-platform-cml_rt5682_def.pro-output-3" } ] + actions = { update-props = { priority.session = 1090 } } + } + { + matches = [ { node.name = "alsa_output.pci-0000_00_1f.3-platform-cml_rt5682_def.pro-output-4" } } + actions = { update-props = { priority.session = 1095 } } + } +] diff --git a/reference/ucm2/GoogleKaisa/sof-rt5682/HiFi.conf b/reference/ucm2/GoogleKaisa/sof-rt5682/HiFi.conf new file mode 100644 index 0000000000..3e4b0279a7 --- /dev/null +++ b/reference/ucm2/GoogleKaisa/sof-rt5682/HiFi.conf @@ -0,0 +1,86 @@ +# Google Kaisa — sof-rt5682 / Intel Kabylake HDMI +# HDMI 逻辑名与 ALSA device:HDMI1=hw:0,2 HDMI2=hw:0,3 HDMI3=hw:0,4(以本机 aplay -l 为准) +# 可用性由 JackControl 驱动;IEC958 在 Enable/Disable 时切换。 + +SectionVerb."HiFi" { + SectionDevice."Port1" { + Comment "Analog (Port1)" + + EnableSequence [ + cset "name='HPOL Playback Switch' 1" + cset "name='HPOR Playback Switch' 1" + cset "name='Stereo1 DAC MIXL DAC L1 Switch' 1" + cset "name='Stereo1 DAC MIXR DAC R1 Switch' 1" + ] + + DisableSequence [ + cset "name='HPOL Playback Switch' 0" + cset "name='HPOR Playback Switch' 0" + cset "name='Stereo1 DAC MIXL DAC L1 Switch' 0" + cset "name='Stereo1 DAC MIXR DAC R1 Switch' 0" + ] + + Value { + PlaybackPriority 100 + PlaybackPCM "hw:${CardId},0" + PlaybackChannels 2 + } + } + + SectionDevice."HDMI1" { + Comment "HDMI1" + + EnableSequence [ + cset "numid=14 1" + ] + + DisableSequence [ + cset "numid=14 0" + ] + + Value { + PlaybackPriority 200 + PlaybackPCM "hw:${CardId},2" + PlaybackChannels 2 + JackControl "HDMI/DP,pcm=2 Jack" + } + } + + SectionDevice."HDMI2" { + Comment "HDMI2" + + EnableSequence [ + cset "numid=20 1" + ] + + DisableSequence [ + cset "numid=20 0" + ] + + Value { + PlaybackPriority 200 + PlaybackPCM "hw:${CardId},3" + PlaybackChannels 2 + JackControl "HDMI/DP,pcm=3 Jack" + } + } + + SectionDevice."HDMI3" { + Comment "HDMI3" + + EnableSequence [ + cset "numid=26 1" + ] + + DisableSequence [ + cset "numid=26 0" + ] + + Value { + PlaybackPriority 200 + PlaybackPCM "hw:${CardId},4" + PlaybackChannels 2 + JackControl "HDMI/DP,pcm=4 Jack" + } + } +} diff --git a/reference/ucm2/README.md b/reference/ucm2/README.md index a0729c7e42..0fc0aca338 100644 --- a/reference/ucm2/README.md +++ b/reference/ucm2/README.md @@ -13,9 +13,19 @@ ## 手工安装(调试) +**推荐(仓库根目录)**:先禁用强制 pro-audio 的 WirePlumber 片段,再一键安装 UCM + Lua: + +```bash +./scripts/disable-kaisa-pro-audio-wireplumber.sh +./scripts/install-kaisa-ucm-overlay.sh +``` + +等价手工步骤: + ```bash sudo cp -a reference/ucm2/conf.d/sof-rt5682 /usr/share/alsa/ucm2/conf.d/ sudo cp -a reference/ucm2/GoogleKaisa /usr/share/alsa/ucm2/ +sudo install -D -m0644 wireplumber/main.lua.d/60-kaisa-ucm.lua /usr/share/wireplumber/main.lua.d/60-kaisa-ucm.lua sudo alsactl init # 或重登 / 重启 pipewire systemctl --user restart wireplumber pipewire pipewire-pulse ``` diff --git a/reference/ucm2/conf.d/sof-rt5682/sof-rt5682.conf b/reference/ucm2/conf.d/sof-rt5682/sof-rt5682.conf new file mode 100644 index 0000000000..25316e4ef8 --- /dev/null +++ b/reference/ucm2/conf.d/sof-rt5682/sof-rt5682.conf @@ -0,0 +1,9 @@ +Syntax 4 + +SectionUseCase."HiFi" { + File "/GoogleKaisa/sof-rt5682/HiFi.conf" + Comment "Kaisa (sof-rt5682): Port1 + HDMI1/2/3 (Jack-driven)" +} + +Include.card-init.File "/lib/card-init.conf" +Include.ctl-remap.File "/lib/ctl-remap.conf" diff --git a/scripts/disable-kaisa-pro-audio-wireplumber.sh b/scripts/disable-kaisa-pro-audio-wireplumber.sh new file mode 100755 index 0000000000..3c75e4d69f --- /dev/null +++ b/scripts/disable-kaisa-pro-audio-wireplumber.sh @@ -0,0 +1,65 @@ +#!/usr/bin/env bash +# 切换到 UCM 路线前:禁用本仓库提供的「强制 pro-audio」WirePlumber 片段(与 UCM 互斥)。 +# 用法:./scripts/disable-kaisa-pro-audio-wireplumber.sh +# 会重命名用户级与(可选)系统级 drop-in,并重启用户 pipewire 栈。 +set -euo pipefail + +disable_dir() { + local d="$1" + [[ -d "$d" ]] || return 0 + shopt -s nullglob + local f + for f in "$d"/*; do + [[ -f "$f" ]] || continue + local b + b="$(basename "$f")" + if [[ "$b" == *kaisa* ]] || [[ "$b" == 50-kaisa* ]]; then + if [[ "$b" == *.disabled ]] || [[ "$b" == *.bak ]]; then + continue + fi + local target="${f}.disabled" + if [[ -e "$target" ]]; then + target="${f}.disabled.$(date +%s)" + fi + echo "rename: $f -> $target" + mv -n -- "$f" "$target" + fi + done +} + +echo ">>> 用户级: ${HOME}/.config/wireplumber/wireplumber.conf.d" +mkdir -p "${HOME}/.config/wireplumber/wireplumber.conf.d" +disable_dir "${HOME}/.config/wireplumber/wireplumber.conf.d" + +if [[ "${1:-}" == "--system" ]]; then + if ! command -v sudo &>/dev/null; then + echo "需要 sudo 以处理 /etc/wireplumber/。" >&2 + exit 1 + fi + echo ">>> 系统级: /etc/wireplumber/wireplumber.conf.d(需 sudo)" + sudo bash -c ' + d="/etc/wireplumber/wireplumber.conf.d" + [[ -d "$d" ]] || exit 0 + shopt -s nullglob + for f in "$d"/*; do + [[ -f "$f" ]] || continue + b="$(basename "$f")" + if [[ "$b" == *kaisa* ]] || [[ "$b" == 50-kaisa* ]]; then + [[ "$b" == *.disabled ]] && continue + t="${f}.disabled" + [[ -e "$t" ]] && t="${f}.disabled.$(date +%s)" + echo "rename: $f -> $t" + mv -n -- "$f" "$t" + fi + done + ' +fi + +if systemctl --user is-system-running &>/dev/null; then + echo ">>> systemctl --user restart wireplumber pipewire pipewire-pulse" + systemctl --user restart wireplumber pipewire pipewire-pulse +else + echo "(无 user systemd 会话,请登录桌面后手动执行 restart)" >&2 +fi + +echo "完成。随后请安装 UCM overlay 与 wireplumber/main.lua.d/60-kaisa-ucm.lua(见 OPERATION)。" diff --git a/scripts/install-kaisa-ucm-overlay.sh b/scripts/install-kaisa-ucm-overlay.sh new file mode 100755 index 0000000000..e9a26caed3 --- /dev/null +++ b/scripts/install-kaisa-ucm-overlay.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash +# 将仓库内 UCM2 overlay 与 WirePlumber Lua 安装到系统路径(需 sudo)。 +# 用法:在仓库根目录执行 ./scripts/install-kaisa-ucm-overlay.sh +# 安装前请先运行 ./scripts/disable-kaisa-pro-audio-wireplumber.sh +set -euo pipefail + +REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +if [[ ! -f "$REPO_ROOT/reference/ucm2/conf.d/sof-rt5682/sof-rt5682.conf" ]]; then + echo "未找到 UCM 文件,请在仓库根目录执行。" >&2 + exit 1 +fi + +if ! command -v sudo &>/dev/null; then + echo "需要 sudo。" >&2 + exit 1 +fi + +echo ">>> 安装 UCM2 -> /usr/share/alsa/ucm2/" +sudo cp -a "$REPO_ROOT/reference/ucm2/conf.d/sof-rt5682" /usr/share/alsa/ucm2/conf.d/ +sudo cp -a "$REPO_ROOT/reference/ucm2/GoogleKaisa" /usr/share/alsa/ucm2/ + +echo ">>> 安装 WirePlumber Lua -> /usr/share/wireplumber/main.lua.d/" +sudo install -D -m0644 "$REPO_ROOT/wireplumber/main.lua.d/60-kaisa-ucm.lua" \ + /usr/share/wireplumber/main.lua.d/60-kaisa-ucm.lua + +echo ">>> 重启用户 pipewire 栈" +if systemctl --user is-system-running &>/dev/null; then + systemctl --user restart wireplumber pipewire pipewire-pulse +else + echo "(无 user 会话,请登录后执行: systemctl --user restart wireplumber pipewire pipewire-pulse)" >&2 +fi + +echo "完成。请按 OPERATION「UCM Jack 自动显示/隐藏」一节验收。" diff --git a/wireplumber/main.lua.d/60-kaisa-ucm.lua b/wireplumber/main.lua.d/60-kaisa-ucm.lua new file mode 100644 index 0000000000..5efe541e73 --- /dev/null +++ b/wireplumber/main.lua.d/60-kaisa-ucm.lua @@ -0,0 +1,16 @@ +-- Kaisa (sof-rt5682): enable UCM + ACP so HiFi profile / Jack-driven ports work. +-- WirePlumber 0.4.x: appended after stock alsa rules. + +table.insert(alsa_monitor.rules, { + matches = { + { + { "api.alsa.card.name", "equals", "sof-rt5682" }, + }, + }, + apply_properties = { + ["api.alsa.use-acp"] = true, + ["api.alsa.use-ucm"] = true, + ["api.acp.auto-profile"] = true, + ["api.acp.auto-port"] = true, + }, +})