WM8960 主线声卡无声根因(Issue #43:ASOC_CARD=m)
日期:2026-07-03 关联:Issue #43、WM8960 音频驱动教程
现象
alpha 板跑主线内核(mainline 7.x),fsl-asoc-card / wm8960 / fsl_sai 驱动都「开了」,但声卡整机静音:
$ aplay -l
aplay: device_list:274: no soundcards found/proc/asound/cards 空、/dev/snd/ 下没有设备节点。
排查
查内核实际配置:
$ zcat /proc/config.gz | grep -iE "FSL_ASOC_CARD|WM8960|FSL_SAI"
CONFIG_SND_SOC_FSL_SAI=y # cpu_dai 在内核里 ✓
CONFIG_SND_SOC_WM8960=y # codec 在内核里 ✓
CONFIG_SND_SOC_FSL_ASOC_CARD=m # machine 驱动是模块 ← 问题在这machine 驱动是 =m,但板子上找不到 .ko:
$ ls /lib/modules/$(uname -r)/kernel/sound/soc/fsl/
(空,fsl-asoc-card.ko 根本没部署)根因
ASoC 声卡是三层结构:machine(fsl-asoc-card.c)+ codec(wm8960.c)+ cpu_dai(fsl_sai.c)。三颗都得在内核里,machine 才能把另外俩缝成一张声卡。
mainline defconfig 模板里:
CONFIG_SND_SOC_WM8960=y(codec 编进内核 ✓)CONFIG_SND_SOC_FSL_SAI=y(被 ASOC_CARD select,cpu_dai 编进内核 ✓)CONFIG_SND_SOC_FSL_ASOC_CARD=m(machine 是模块 ✗)
而 imx-forge 的内核 build 流程(build-mainline-linux.sh)不带 modules_install——只编 zImage,不把 .ko 部署到 rootfs 的 /lib/modules/。结果 machine 驱动既不在内核映像里、也没作为模块部署 → dai_link 的 cpu/codec 找不到「缝纫机」→ devm_snd_soc_register_card 没执行 → 声卡不存在。
正点原子那种「内核 + modules_install + 开机 modprobe」的发行版里,
=m能工作。imx-forge 走的是「尽量=y、最小 rootfs」路线,所以=m就等于「没有」。
修复
把 machine 驱动也改成编进内核。driver/device_tree/alpha-board/linux/imx6ull_mainline_defconfig.template:
# --- Sound ---
- CONFIG_SND_SOC_FSL_ASOC_CARD=m
+ # fsl-asoc-card(WM8960 等 machine 驱动):必须 =y。见本笔记(Issue #43)
+ # 项目的内核 build 流程不带 modules_install,=m 会让声卡整机静音。
+ CONFIG_SND_SOC_FSL_ASOC_CARD=ylinux-imx 线的 imx_aes_defconfig.template 本来就是 =y,不受影响。
顺带:弃用 imx-wm8960.c
正点原子教程(草稿 ch65)走的是「自己写 imx-wm8960.c 当 machine 驱动」。本仓库明确不移植 imx-wm8960.c,直接复用主线 fsl-asoc-card(compatible = "fsl,imx-audio-wm8960" 命中其 WM8960 分支)。理由:fsl-asoc-card 一个 machine 驱动通吃 WM8960/WM8962/SGTL5000/CS42XX8 等 14 种 codec,社区维护、还带 ASRC;自写 imx-wm8960.c 只认 WM8960 一颗,重复造轮子。
验证
改 =y 重编内核、重部署:
$ zcat /proc/config.gz | grep FSL_ASOC_CARD
CONFIG_SND_SOC_FSL_ASOC_CARD=y
$ cat /proc/asound/cards
0 [wm8960audio]: wm8960-audio - wm8960-audio
$ aplay -l # 列出 card 0 ✓声卡上线。再 amixer 把 WM8960 默认静音拧开(见教程 06_build_and_test),aplay 出声。
SDMA 也已 =y(2026-07-03「默认全」任务修)
ASOC_CARD 是 Issue #43 主因,但 alpha 板 SAI2 走 SDMA 搬运音频数据,CONFIG_IMX_SDMA=m(注释「fixes firmware loading issues」)同样让 imx-pcm-dma 不进 rootfs、fsl_sai 拿不到 DMA channel。
2026-07-03 已修:「让默认 build 驱动全」任务把 IMX_SDMA 也改 =y,在子模块 defconfig + patch + 项目副本三处同步(见记忆 device-tree-workflow 修正后的「三同步」真相)。固件 6ULL 用 sdma-imx6q.bin(sdma_imx6ul 复用 imx6q 脚本、MODULE_FIRMWARE 只声明 imx6q.bin),install_firmwares.sh 已装,SDMA=y 后固件就绪。
至此 Issue #43 的 ASOC_CARD + SDMA 双修复都真正进 build(之前 wm8960 那次只改项目副本 ASOC_CARD、没进 patch/子模块、实际没生效;本次一并修正,三同步)。
教训
=m不等于「开了」。在「不 modules_install」的 build 流程里,=m= 缺失。音频/显示/网络这类「必须三方缝合才出活」的子系统,machine 层一定要=y。- ASoC 三层缺一不可,缺中间 machine 层的症状最迷惑(codec、cpu_dai 都「在线」但没声卡)。
- 排查「no soundcards」先
zcat /proc/config.gz | grep ASOC_CARD看 machine 驱动是不是=y。