299 lines
16 KiB
Markdown
299 lines
16 KiB
Markdown
# Session Log: 2026-03-21
|
|
|
|
## Session Summary
|
|
|
|
Continued work on fixing the terrible speaker sound quality on the Lenovo Legion Pro 7 16IAX10H (CachyOS workstation). Previous session (2026-03-20) diagnosed the root cause and applied initial fixes (forced SOF driver, EasyEffects EQ). This session discovered that the SOF driver alone was insufficient because the **Awinic AW88399 smart amplifiers** were not integrated into the audio pipeline, and built a custom kernel with the community patch to fix it.
|
|
|
|
### Key Decisions
|
|
- Used the community patch from `nadimkobeissi/16iax10h-linux-sound-saga` GitHub repo rather than attempting to write our own driver
|
|
- Built a full CachyOS kernel package (not DKMS) because the patch modifies existing kernel source files (ACPI scan, serial-multi-instantiate, alc269.c, aw88399.c ASoC driver)
|
|
- Installed UCM2 config modifications for proper speaker routing
|
|
- Used BUILDDIR on main disk after tmpfs (16GB) ran out of space during kernel extraction
|
|
|
|
### Problems Encountered
|
|
1. **tmpfs too small** - Initial `makepkg` in `/tmp` failed with "No space left on device" because the kernel source + build artifacts exceed 16GB. Fixed by moving build to `/home/guru/kernel-build/` with `BUILDDIR` override.
|
|
2. **Missing build deps** - `bc`, `cpio`, `rust`, `rust-bindgen`, `rust-src` needed installation.
|
|
|
|
## Hardware Details
|
|
|
|
- **Laptop**: Lenovo Legion Pro 7 16IAX10H (DMI product: 83F5)
|
|
- **Audio Controller**: Intel 800 Series ACE (PCI `80:1f.3`), PCI SSID `17aa:3d6c`
|
|
- **Codec**: Realtek ALC287, codec SSID `17aa:3906`
|
|
- **Smart Amplifier**: Awinic AW88399 on I2C (ACPI: `AWDZ8399:00`, path: `\_SB_.PC02.I2C2.SPKR`)
|
|
- **Kernel**: 6.19.9-1-cachyos with SOF driver (`sof-audio-pci-intel-mtl`)
|
|
- **SOF Firmware**: `intel/sof-ipc4/arl-s/sof-arl-s.ri` v2.14.1.1
|
|
- **SOF Topology**: `intel/sof-ipc4-tplg/sof-hda-generic.tplg`
|
|
|
|
## Root Cause Analysis
|
|
|
|
The sound was terrible because:
|
|
1. **SOF driver loaded but using generic HDA topology** - no smart amp integration
|
|
2. **AW88399 kernel module loaded with 0 references** - `snd_soc_aw88399` was loaded but nothing used it because there was no HDA side-codec bridge driver
|
|
3. **Wrong codec fixup** - Kernel picked fixup for PCI SSID `17aa:0000` (generic/none) instead of `17aa:3906` because the PCI subsystem ID is actually `17aa:3d6c` which had no quirk entry
|
|
4. **No HDA side-codec bridge** - The stock kernel has `CONFIG_SND_SOC_AW88399=m` (ASoC driver) but NOT `CONFIG_SND_HDA_SCODEC_AW88399` (the HDA bridge driver that connects ALC287 to the I2C amps) - this driver doesn't exist in mainline Linux as of kernel 6.19
|
|
|
|
## Fix Applied
|
|
|
|
### Source: Community Patch
|
|
- Repository: https://github.com/nadimkobeissi/16iax10h-linux-sound-saga
|
|
- Patch: `16iax10h-audio-linux-6.19.8.patch` (979 lines, 10 files)
|
|
- Related issues: CachyOS #687, #707; Kernel Bugzilla #218329
|
|
- Status: NOT upstreamed to mainline kernel; $2,000 bounty exists for upstream submission
|
|
|
|
### What the Patch Does
|
|
1. **Creates new HDA side-codec bridge driver** (`snd-hda-scodec-aw88399`, `snd-hda-scodec-aw88399-i2c`) - connects ALC287 HDA codec to AW88399 amps via I2C
|
|
2. **Adds ACPI ignore entry** for `AWDZ8399` in `drivers/acpi/scan.c` so serial-multi-instantiate handles it
|
|
3. **Adds serial-multi-instantiate node** for `aw88399-hda` with 2 instances
|
|
4. **Adds HDA fixup entries** in `alc269.c`: `ALC287_FIXUP_LENOVO_LEGION_AW88399` for SSIDs `17aa:3906`, `17aa:3907`, `17aa:3938`
|
|
5. **Exports functions** from ASoC `aw88399.c`: `aw88399_start()`, `aw88399_stop()`, `aw88399_init()`, `aw88399_request_firmware_file()`
|
|
6. **Removes ACPI match** from ASoC driver to prevent binding conflict with HDA side-codec
|
|
7. **DMI-based L/R channel swap** for products 83F5, 83RU, 83F4 (hardware wiring issue)
|
|
|
|
### Files Created/Modified on System
|
|
|
|
#### Firmware
|
|
- **Created**: `/lib/firmware/aw88399_acf.bin` (amplifier calibration firmware from Windows driver)
|
|
|
|
#### UCM2 Configs
|
|
- **Backed up**: `/usr/share/alsa/ucm2/HDA/HiFi-analog.conf.bak`
|
|
- **Backed up**: `/usr/share/alsa/ucm2/HDA/HiFi-mic.conf.bak`
|
|
- **Modified**: `/usr/share/alsa/ucm2/HDA/HiFi-analog.conf` (from community repo)
|
|
- **Modified**: `/usr/share/alsa/ucm2/HDA/HiFi-mic.conf` (from community repo)
|
|
|
|
#### Kernel Build
|
|
- **Build directory**: `/home/guru/kernel-build/`
|
|
- **PKGBUILD**: Modified CachyOS PKGBUILD with `aw88399-hda-scodec.patch` added to source array and `CONFIG_SND_HDA_SCODEC_AW88399=m`, `CONFIG_SND_HDA_SCODEC_AW88399_I2C=m` enabled
|
|
- **Built packages**:
|
|
- `/home/guru/kernel-build/linux-cachyos-6.19.9-1-x86_64.pkg.tar.zst` (147MB)
|
|
- `/home/guru/kernel-build/linux-cachyos-headers-6.19.9-1-x86_64.pkg.tar.zst` (37MB)
|
|
|
|
#### Kernel Installed
|
|
- Packages installed via `sudo pacman -U`
|
|
- Initramfs regenerated automatically
|
|
- Limine bootloader config updated automatically
|
|
|
|
### Previous Session Fixes Still Active
|
|
- `/etc/modprobe.d/sof-force.conf` - forces SOF driver (`dsp_driver=3`)
|
|
- `~/.local/share/easyeffects/output/Legion-Speakers-v2.json` - EasyEffects EQ preset
|
|
- EasyEffects sink set as default audio output
|
|
|
|
## Configuration Changes
|
|
|
|
### Packages Installed This Session
|
|
- `bc` (kernel build dep)
|
|
- `cpio` (kernel build dep)
|
|
- `rust` (kernel build dep - LTO kernel)
|
|
- `rust-bindgen` (kernel build dep)
|
|
- `rust-src` (kernel build dep)
|
|
|
|
### Kernel Config Added
|
|
```
|
|
CONFIG_SND_HDA_SCODEC_AW88399=m
|
|
CONFIG_SND_HDA_SCODEC_AW88399_I2C=m
|
|
```
|
|
|
|
## Update: 05:30 — Post-Reboot Tuning & Volume Hotkey Fix
|
|
|
|
### Session Summary
|
|
Booted into the patched kernel from the previous session. AW88399 amps bound successfully. Addressed two issues: (1) volume hotkeys not working, (2) sound quality issues (over-driven, then lacking clarity). Also wrote a comprehensive forum post documenting the full fix.
|
|
|
|
### Post-Reboot Verification Results
|
|
All successful:
|
|
- AW88399 HDA side-codec: Both amps registered and bound (channels 0 and 1)
|
|
- Modules loaded: `snd_hda_scodec_aw88399`, `snd_hda_scodec_aw88399_i2c`, `snd_soc_aw88399` all with references > 0
|
|
- Correct fixup: `ALC287: picked fixup for codec SSID 17aa:3906`
|
|
- Autoconfig: `line_outs=2 (0x14/0x17) type:speaker` — both speaker pins active
|
|
- I2C amps respond at addresses `0x34` and `0x35` (chip ID `0x8321` = AW88399)
|
|
- Firmware: `aw88399_acf.bin` loads silently (no dmesg output on success)
|
|
|
|
### Key Decisions Made This Session
|
|
|
|
1. **Removed EasyEffects from audio pipeline** — It was creating a virtual PipeWire sink which broke volume hotkeys AND was applying heavy DSP (bass enhancer, exciter, 15-band EQ, loudness, multiband compressor, limiter) that over-drove the sound now that the amps are working properly.
|
|
|
|
2. **Removed UCM2 Post Mixer Analog override** — The community UCM2 config had a Legion-specific block that routed PipeWire volume control through the SOF DSP's `Post Mixer Analog Playback Volume` (numid=40). This control has coarse 2dB steps and a -90dB to 0dB range. At typical 50% PipeWire volume, this applied -18dB of digital attenuation in the DSP, destroying dynamic range and clarity. Removing it lets PipeWire use the HDA codec's `Speaker Playback Volume` which has fine 0.75dB steps.
|
|
|
|
3. **Set all SOF DSP volumes to 0dB** — Pre Mixer, Post Mixer, and Deepbuffer all maxed so no intermediate digital attenuation.
|
|
|
|
### Problems Encountered & Solutions
|
|
|
|
#### Problem 1: Volume Hotkeys Not Working
|
|
**Symptom:** Fn+Volume Up/Down keys did nothing. Tray slider worked fine.
|
|
|
|
**Diagnosis journey:**
|
|
- Verified keys generate `KEY_VOLUMEUP`/`KEY_VOLUMEDOWN` via evtest on the ITE Device(8258) keyboard (event4)
|
|
- KDE's `kmix` shortcuts were correctly registered (`increase_volume=Volume Up`, etc.)
|
|
- `invokeShortcut "mute"` worked via DBus, but `invokeShortcut "increase_volume"` did nothing
|
|
- Discovered the issue is **NOT the keyboard** — it's plasma-pa's `audioshortcutsservice` KDED module
|
|
|
|
**Root cause:** plasma-pa's `PreferredDevice::sink()` doesn't handle virtual/combined sinks. When EasyEffects virtual sink is the default, `increase_volume` and `decrease_volume` handlers silently fail. Mute works because it uses a different code path. Related: [KDE Bug 456310](https://bugs.kde.org/show_bug.cgi?id=456310).
|
|
|
|
**Fix:** Set hardware speaker sink as default instead of EasyEffects virtual sink:
|
|
```bash
|
|
pactl set-default-sink alsa_output.pci-0000_80_1f.3-platform-skl_hda_dsp_generic.HiFi__Speaker__sink
|
|
pkill easyeffects
|
|
```
|
|
|
|
**Note:** This affects ALL virtual sinks, including PipeWire filter-chain sinks. Any `media.class = Audio/Sink` filter will have the same hotkey problem on KDE Plasma 6 Wayland.
|
|
|
|
#### Problem 2: Over-Driven Sound
|
|
**Symptom:** Sound was a bit distorted/over-driven after removing EasyEffects.
|
|
|
|
**Cause:** ALSA Master and Speaker volumes were at 100% (0dB) while PipeWire was also at 100%. Combined with the AW88399 amp gain, the signal was clipping.
|
|
|
|
**Fix:** Let PipeWire control volume through the Speaker DAC, keep ALSA levels at 0dB reference.
|
|
|
|
#### Problem 3: Lacking Clarity / "Paper Over Speakers" Sound
|
|
**Symptom:** After fixing over-drive, sound lacked center/clarity/spatial definition.
|
|
|
|
**Root cause:** The community UCM2 config's Legion override was routing PipeWire volume through `Post Mixer Analog Playback Volume` (SOF DSP). At 50% PipeWire volume → Post Mixer at 36/45 → -18dB digital attenuation with coarse 2dB steps. This was killing dynamic range before the signal even reached the DAC/amps.
|
|
|
|
**Fix:** Removed the Legion override block (lines 130-147) from `/usr/share/alsa/ucm2/HDA/HiFi-analog.conf`:
|
|
```
|
|
If.legion {
|
|
Condition { Type String; Haystack ...; Needle "83F5" }
|
|
True.If.postmixer {
|
|
...Post Mixer Analog override...
|
|
}
|
|
}
|
|
```
|
|
|
|
Set SOF DSP volumes to max:
|
|
```bash
|
|
amixer -c 1 cset numid=39 45,45 # Pre Mixer
|
|
amixer -c 1 cset numid=40 45,45 # Post Mixer
|
|
amixer -c 1 cset numid=51 45,45 # Deepbuffer
|
|
systemctl --user restart pipewire pipewire-pulse wireplumber
|
|
```
|
|
|
|
#### Problem 4: Speaker Balance — Tweeters vs Woofers
|
|
**Discovery:** The laptop has two speaker pairs:
|
|
- **Pin 0x14** ("Speaker") → Tweeters near screen hinge, driven directly by ALC287 DAC 0x02
|
|
- **Pin 0x17** ("Bass Speaker") → Woofers near palmrest, driven through AW88399 smart amps via DAC 0x06
|
|
|
|
Initially only tweeters played (terrible thin sound). After the kernel patch, the woofers now play through the amps. The tweeters are quieter than the woofers because the amps add significant gain. Both play simultaneously — the woofers just dominate.
|
|
|
|
**Current state:** Balanced and sounds good per user feedback. Both speaker pairs confirmed working (tested by muting Bass Speaker to isolate tweeters).
|
|
|
|
### Configuration Changes This Session
|
|
|
|
#### Files Modified
|
|
- `/usr/share/alsa/ucm2/HDA/HiFi-analog.conf` — Removed Legion Post Mixer Analog override (lines 130-147)
|
|
- `~/.config/autostart/com.github.wwmm.easyeffects.desktop` — Added `Hidden=true` to disable autostart
|
|
- `/etc/udev/hwdb.d/90-ite-keyboard-fix.hwdb` — Created (hwdb rule for ITE keyboard, may not be needed now)
|
|
|
|
#### Packages Installed
|
|
- `evtest` — For diagnosing keyboard input events
|
|
- `wtype` — For Wayland key simulation testing (not ultimately needed)
|
|
|
|
#### Services Changed
|
|
- EasyEffects: Stopped and autostart disabled
|
|
- PipeWire/WirePlumber: Restarted multiple times during tuning
|
|
|
|
### Final Working Audio Configuration
|
|
```
|
|
Kernel: 6.19.9-1-cachyos (patched with AW88399 HDA side-codec)
|
|
Default sink: alsa_output.pci-0000_80_1f.3-platform-skl_hda_dsp_generic.HiFi__Speaker__sink
|
|
Volume control: PipeWire → Speaker Playback Volume (DAC 0x02, 0.75dB steps)
|
|
ALSA Master: 100% (0dB)
|
|
ALSA Speaker: Controlled by PipeWire
|
|
ALSA Bass Speaker: On (switch only, no volume)
|
|
SOF Pre Mixer: 45/45 (0dB)
|
|
SOF Post Mixer: 45/45 (0dB)
|
|
SOF Deepbuffer: 45/45 (0dB)
|
|
EasyEffects: Not running, autostart disabled
|
|
UCM2: Community config minus Post Mixer override
|
|
Hotkeys: Working (increase/decrease/mute all functional)
|
|
Both speaker pairs: Active (tweeters + woofers)
|
|
```
|
|
|
|
### Forum Post
|
|
Wrote comprehensive forum post documenting the full fix. Files saved at:
|
|
- `/tmp/forum-post-legion-audio.json` — Post content (title, tags, markdown body)
|
|
- `/tmp/post-to-forum.php` — PHP script for database insertion on IX server
|
|
|
|
**Not yet published** — IX server unreachable (Tailscale stopped). To publish:
|
|
```bash
|
|
sudo tailscale up
|
|
sshpass -p 'Gptf*77ttb!@#!@#' scp -o StrictHostKeyChecking=no -o PubkeyAuthentication=no /tmp/forum-post-legion-audio.json /tmp/post-to-forum.php root@172.16.3.10:/tmp/
|
|
sshpass -p 'Gptf*77ttb!@#!@#' ssh -o StrictHostKeyChecking=no -o PubkeyAuthentication=no root@172.16.3.10 'php /tmp/post-to-forum.php'
|
|
```
|
|
|
|
Forum tags: Gadgets & Hardware (6), How-Tos & Tips (7)
|
|
|
|
## Pending/Incomplete Tasks
|
|
|
|
### Forum Post Publication
|
|
Forum post written but not published — needs Tailscale/VPN connection to IX server.
|
|
|
|
### ITE Keyboard hwdb Rule
|
|
Created `/etc/udev/hwdb.d/90-ite-keyboard-fix.hwdb` — this was part of an early debugging attempt for the volume hotkey issue. The actual fix was removing EasyEffects (not the hwdb rule). This file can be removed if it causes issues, but it's harmless.
|
|
|
|
### UCM2 Package Update Risk
|
|
The modified UCM2 config at `/usr/share/alsa/ucm2/HDA/HiFi-analog.conf` will be overwritten by `alsa-ucm-conf` package updates. Options:
|
|
1. Re-apply the edit after each update (remove the Legion Post Mixer block)
|
|
2. Pin the `alsa-ucm-conf` package version
|
|
3. Use a pacman hook to auto-patch after updates
|
|
|
|
### Future Kernel Updates
|
|
When CachyOS pushes a new kernel update, the AW88399 patch will be lost. Need to either:
|
|
1. Rebuild with the patch each time (keep PKGBUILD + patch in `/home/guru/kernel-build/`)
|
|
2. Watch for upstream inclusion (Kernel Bugzilla #218329)
|
|
3. Watch CachyOS issues #687 and #707 for native inclusion
|
|
|
|
### Cleanup
|
|
- Remove `/home/guru/kernel-build/build/` (large build artifacts)
|
|
- Keep `/home/guru/kernel-build/PKGBUILD` and `aw88399-hda-scodec.patch` for future rebuilds
|
|
|
|
### If Reboot Breaks Audio
|
|
1. Boot LTS kernel from Limine menu
|
|
2. Or boot a btrfs snapshot (available in Limine)
|
|
3. Or remove the patched kernel: `sudo pacman -S linux-cachyos` (reinstall from repo)
|
|
4. Restore UCM2 backups:
|
|
```bash
|
|
sudo cp /usr/share/alsa/ucm2/HDA/HiFi-analog.conf.bak /usr/share/alsa/ucm2/HDA/HiFi-analog.conf
|
|
sudo cp /usr/share/alsa/ucm2/HDA/HiFi-mic.conf.bak /usr/share/alsa/ucm2/HDA/HiFi-mic.conf
|
|
```
|
|
|
|
## Reference Information
|
|
|
|
### Key URLs
|
|
- Community fix repo: https://github.com/nadimkobeissi/16iax10h-linux-sound-saga
|
|
- CachyOS Issue #687: https://github.com/CachyOS/linux-cachyos/issues/687
|
|
- CachyOS Issue #707: https://github.com/CachyOS/linux-cachyos/issues/707
|
|
- Kernel Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=218329
|
|
- CachyOS Forum thread: https://discuss.cachyos.org/t/new-fix-for-lenovo-legion-pro-7i-16iax10h-with-alc3306-codec/18889/1
|
|
- plasma-pa virtual sink bug: https://bugs.kde.org/show_bug.cgi?id=456310
|
|
|
|
### Key File Paths
|
|
- Kernel build dir: `/home/guru/kernel-build/`
|
|
- SOF force config: `/etc/modprobe.d/sof-force.conf`
|
|
- AW88399 firmware: `/lib/firmware/aw88399_acf.bin`
|
|
- UCM2 configs: `/usr/share/alsa/ucm2/HDA/HiFi-analog.conf`, `HiFi-mic.conf`
|
|
- UCM2 backups: same path with `.bak` extension
|
|
- EasyEffects preset: `~/.local/share/easyeffects/output/Legion-Speakers-v2.json` (no longer used)
|
|
- EasyEffects autostart: `~/.config/autostart/com.github.wwmm.easyeffects.desktop`
|
|
- ITE keyboard hwdb: `/etc/udev/hwdb.d/90-ite-keyboard-fix.hwdb`
|
|
- Forum post files: `/tmp/forum-post-legion-audio.json`, `/tmp/post-to-forum.php`
|
|
|
|
### PCI/Device IDs
|
|
- PCI device: `80:1f.3` (Intel 800 Series ACE)
|
|
- PCI vendor/device: `8086:7f50`
|
|
- PCI subsystem: `17aa:3d6c`
|
|
- Codec SSID: `17aa:3906`
|
|
- ACPI amp device: `AWDZ8399:00`
|
|
- I2C amp addresses: `0x34` (right speaker), `0x35` (left speaker)
|
|
- I2C amp chip ID: `0x8321` (AW88399)
|
|
- DMI product: `83F5`
|
|
- ITE keyboard: USB VID `048d`, PID `c197`
|
|
|
|
### Speaker Layout
|
|
- **Pin 0x14** ("Speaker"): Tweeters near screen hinge, DAC 0x02, direct ALC287 output, `Speaker Playback Volume/Switch`
|
|
- **Pin 0x17** ("Bass Speaker"): Woofers near palmrest, DAC 0x06, through AW88399 I2C amps, `Bass Speaker Playback Switch` (no volume control)
|
|
|
|
### Key Technical Findings
|
|
- `PreferredDevice::sink()` in plasma-pa's audioshortcutsservice skips virtual sinks — volume up/down shortcuts silently fail while mute works fine
|
|
- SOF DSP `Post Mixer Analog Playback Volume` has coarse 2dB steps (0-45 range, -90dB to 0dB) — unsuitable as primary volume control
|
|
- HDA codec `Speaker Playback Volume` has fine 0.75dB steps (0-87 range, -65.25dB to 0dB) — proper volume control
|
|
- AW88399 amps go active/suspended via runtime PM — both show `stream=1, channel=0` during playback
|
|
- Both DACs (0x02 and 0x06) receive audio simultaneously from the same PCM stream
|