Files
c630/overlay/usr/local/sbin/c630-wsa881x
rob thijssen 477d43aacd
Some checks failed
build image / build (push) Has been cancelled
Survive kernel updates on a /boot this small
A dnf upgrade to 7.1.8 installed the kernel rpm cleanly, then ran /boot out
of space. dracut wrote no initramfs, and because kernel-install stops at the
first failing plugin, 95-c630-devicetree never ran either — leaving a boot
entry with neither an initrd nor a devicetree line, which on this machine can
never boot. dnf reported success and nothing retried.

A kernel costs ~336 MiB here: a 210 MiB hostonly=no initramfs, a 98 MiB
dtb-<kver> directory carrying every board's device tree, plus vmlinuz and
System.map. Three of those cannot fit 1 GiB, so /boot goes to 2 GiB and
installonly_limit drops to 2.

Also fixes the quieter half of the same trap. snd-soc-wsa881x lives outside
the kernel package, so the speakers go silent after any kernel update with
nothing in the logs to explain it. c630-wsa881x rebuilds it and
96-c630-wsa881x.install calls it on each kernel-install add — always exiting
0, since a plugin failure is precisely what caused the damage above.

grub.cfg gains the next_entry one-shot block that has been carried by hand all
along, so testing a kernel costs a power cycle rather than a rescue.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011XgGF5wfxLDAybVnNz6eNQ
2026-08-14 16:17:52 +03:00

79 lines
2.8 KiB
Bash
Executable File

#!/usr/bin/bash
#
# Build the speaker-amplifier driver Fedora does not ship.
#
# The C630's two WSA881x amplifiers sit on the WCD9340's SoundWire bus, and
# Fedora's aarch64 kernel has never set CONFIG_SND_SOC_WSA881X — the newer
# WSA883X and WSA884X the ThinkPad X13s needs are both =m, but this one was
# missed. Without it the SoundWire slaves never bind, the machine driver cannot
# find its DAIs, and the sound card sits in deferred probe forever: no card, no
# speakers, no error that points anywhere useful.
#
# sound/soc/codecs/wsa881x.c is one self-contained file with no out-of-tree
# patches, so building it against kernel-devel and dropping it in extra/ is
# enough. Because it lives outside the kernel package, it has to be rebuilt for
# every kernel — hence 96-c630-wsa881x.install, which calls this on each
# kernel-install add. Audio otherwise goes silent the first time you take a
# kernel update, with nothing in the logs to connect the two.
#
# The real fix is Fedora flipping the config; see docs/drafts/.
#
# Usage: c630-wsa881x [kernel-version] (defaults to the running kernel)
set -euo pipefail
KVER="${1:-$(uname -r)}"
BUILD="/lib/modules/${KVER}/build"
DEST="/lib/modules/${KVER}/extra/snd-soc-wsa881x.ko"
if [ -f "$DEST" ]; then
echo "c630-wsa881x: ${DEST} already built"
exit 0
fi
# Refuse rather than half-do it: a partial build leaves no module and no clue.
missing=()
[ -d "$BUILD" ] || missing+=("kernel-devel-${KVER}")
command -v gcc >/dev/null || missing+=(gcc)
command -v make >/dev/null || missing+=(make)
if [ "${#missing[@]}" -gt 0 ]; then
echo "c630-wsa881x: cannot build for ${KVER}, missing: ${missing[*]}" >&2
echo "c630-wsa881x: install them and re-run 'c630-wsa881x ${KVER}'," \
"or the built-in speakers will be silent on that kernel" >&2
exit 1
fi
# Fedora's 7.1.8-200.fc44.aarch64 is upstream 7.1.8. A .0 upstream release is
# tagged v7.1, not v7.1.0, so try both.
base="${KVER%%-*}"
tags=("v${base}")
[ "${base}" != "${base%.0}" ] && tags+=("v${base%.0}")
work=$(mktemp -d)
trap 'rm -rf "$work"' EXIT
src=""
for tag in "${tags[@]}"; do
url="https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/plain/sound/soc/codecs/wsa881x.c?h=${tag}"
if curl -fsSL --retry 3 -o "$work/wsa881x.c" "$url"; then
echo "c630-wsa881x: fetched wsa881x.c at ${tag}"
src="$tag"
break
fi
done
if [ -z "$src" ]; then
echo "c630-wsa881x: could not fetch wsa881x.c for ${KVER} (tried: ${tags[*]})" >&2
echo "c630-wsa881x: needs network; re-run 'c630-wsa881x ${KVER}' once online" >&2
exit 1
fi
cat > "$work/Makefile" <<'EOF'
obj-m += snd-soc-wsa881x.o
snd-soc-wsa881x-objs := wsa881x.o
EOF
make -C "$BUILD" M="$work" modules
install -D -m 0644 "$work/snd-soc-wsa881x.ko" "$DEST"
depmod -a "$KVER"
echo "c630-wsa881x: installed ${DEST}"