我正在尝试在我的设备树源文件中注册 soc-utils 中提供的 ALSA 虚拟编解码器,以将其与 i2s 设备驱动程序 (sun8i-i2s) 一起使用。
我尝试在 i2s 配置中设置 sound-dai 字段,如下所述:https://patchwork.kernel.org/patch/7679391/ https://patchwork.kernel.org/patch/7679391/,但是设备驱动程序在读取设备树时找不到dai名称。
我找到了两种解决方法,其中包括编写我自己的虚拟编解码器并将其提供给设备树:
/ {
stupid-codec {
#sound-dai-cells = <0x00000000>;
compatible = "linux,snd-soc-stupid";
status = "okay";
linux,phandle = <0x0000dead>;
phandle = <0x0000dead>;
};
...
};
...
&i2s0 {
#sound-dai-cells = <0x00000000>;
compatible = "allwinner,sun8i-h3-i2s";
sound-dai = <0x0000dead>;
status = "okay";
};
或者在设备驱动程序中强制链接编解码器,并且设备中没有 sound-dai 字段:
device tree :
&i2s0 {
// No sound-dai
status = "okay";
};
i2s driver :
static int sun8i_card_create(struct device *dev, struct priv *priv)
{
struct snd_soc_card *card;
...
// Skip the part where it's reading the device tree
#if 0
codec->of_node = sun8i_get_codec(dev);
if (!codec->of_node) {
dev_err(dev, "no port node\n");
return -ENXIO;
}
DBGOUT("%s: codec_name=\"%s\"\n", __func__, codec->of_node->name);
if(snd_soc_of_get_dai_name(dev->of_node, &codec->dai_name) < 0)
{
dev_err(dev, "%s: failed to find dai name, use codec's name as dai name.\n", __func__);
codec->dai_name = codec->of_node->name;
}
DBGOUT("%s: dai_name=\"%s\"\n", __func__, codec->dai_name);
#endif
// Force codec and dai name
codec->name = "snd-soc-dummy";
codec->dai_name = "snd-soc-dummy-dai";
两种方法都可以,但它仍然是一种肮脏的黑客行为,因此如果有人拥有设备树中虚拟对象的正确语法,那就太好了。
编辑2019/10/10
我们最终使用了不同的编解码器(pcm5102a),它在 dts 中单独实现:
(in sun8i-h3-nanopi-neo-air.dts)
&i2s0 {
/* sound-dai = <&pcm5102a>; */
status = "okay";
};
(in sun8i-h3-nanopi.dtsi)
pcm5102a: pcm5102a-codec {
#sound-dai-cells = <0>;
compatible = "ti,pcm5102a";
status = "disabled";
};
至于snd-soc-dummy的使用,我无法使其正常工作,但我注意到通用的linux驱动程序似乎使用硬编码字符串来注册它:https://github.com/torvalds/linux/blob/master/sound/soc/generic/simple-card.c https://github.com/torvalds/linux/blob/master/sound/soc/generic/simple-card.c