跳转到内容
  1. 使用虚拟 codec 节点将SAI或I2S控制器注册为ASLA声卡
  2. 打开 dep
  3. 打开 DepAlsaBridge

注册虚拟声卡

设备树

参考文档:

dts
/{
    //虚拟codec节点
    dummy_codec: dummy-codec {
        status = "okay";
        compatible = "linux,dummy-codec";		/*虽然是用来占位的,但驱动中也需要对音频格式做支持*/
        #sound-dai-cells = <0>;
    };
    
    sound:sound{
        compatible = "simple-audio-card";
        simple-audio-card,name = "dummy-audio-card";

        simple-audio-card,dai-link@0 {
		    format = "i2s";
            bitclock-master = <&cpu0_audio>;
            frame-master = <&cpu0_audio>;
            convert-channels = <16>;
            mclk-fs = <256>;

		    cpu0_audio:cpu {
			    sound-dai = <&sai2a>;
                dai-tdm-slot-num = <16>;
                dai-tdm-slot-width = <32>;
		    };

		    codec {
			    sound-dai = <&dummy_codec>;
		    };
	    };

        simple-audio-card,dai-link@1 {
            format = "i2s";
            bitclock-master = <&cpu1_audio>;
            frame-master = <&cpu1_audio>;
            convert-channels = <16>;
            mclk-fs = <256>;

		    cpu1_audio:cpu {
			    sound-dai = <&sai2b>;
                dai-tdm-slot-num = <16>;
                dai-tdm-slot-width = <32>;
		    };

		    codec {
			    sound-dai = <&dummy_codec>;
		    };
	    };

        simple-audio-card,dai-link@2 {
            format = "i2s";
            bitclock-master = <&cpu2_audio>;
            frame-master = <&cpu2_audio>;
            convert-channels = <2>;
            mclk-fs = <256>;

		    cpu2_audio:cpu {
			    sound-dai = <&i2s3>;
		    };
            
		    codec {
			    sound-dai = <&dummy_codec>;
		    };
	    };
    };
}

&sai2 {
    pinctrl-names = "default", "sleep";
    pinctrl-0 = <&sai2a_pins_mx>, <&sai2b_pins_mx>;
    pinctrl-1 = <&sai2a_sleep_pins_mx>, <&sai2b_sleep_pins_mx>;
    status = "okay";

	sai2a:audio-controller@402a0004{
        #clock-cells = <0>;		/* Set SAI2A as master clock provider */
        dma-names = "tx"; 		/*此配置应在芯片配置中,但st在6.1内核源码中未添加*/
		status = "okay";
	};

	sai2b:audio-controller@402a0024{
        #clock-cells = <0>;
        dma-names = "rx";
		status = "okay";
	};
};

&i2s3{
	pinctrl-names = "default", "sleep";
	pinctrl-0 = <&i2s3_pins_mx>;
	pinctrl-1 = <&i2s3_sleep_pins_mx>;
    #clock-cells = <0>;
	status = "okay";
};

内核配置

参考

关于cgroup

  • OpenSTLinux 使用 systemd 引导,默认挂载 cgroups v2 可在uboot的配置文件中添加内核引导选项来使用 cgroups-v1

    systemd.unified_cgroup_hierarchy=no
    systemd.legacy_systemd_cgroup_controller=yes
  • 使用buildroot构建系统可添加 cgroupfs-mount 包来挂载cgroups

asound.config

用sai注册声卡,由于sai有两个子模块,且传输方向分别为 tx 和 rx,所以要满足 DepAlsaBridge 就需要把两个子模块都用上

bash
root@stm32mp2:~# ls /proc/asound/card0/
id  pcm0p  pcm1c  pcm2c  pcm2p
root@stm32mp2:~# aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: dummyaudiocard [dummy-audio-card], device 0: 402a0004.audio-controller-dummy-codec-pcm dummy-codec-pcm-0 [402a0004.audio-controller-dummy-codec-pcm dummy-codec-pcm-0]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 0: dummyaudiocard [dummy-audio-card], device 2: 400c0000.audio-controller-dummy-codec-pcm dummy-codec-pcm-2 [400c0000.audio-controller-dummy-codec-pcm dummy-codec-pcm-2]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
root@stm32mp2:~# arecord -l
**** List of CAPTURE Hardware Devices ****
card 0: dummyaudiocard [dummy-audio-card], device 1: 402a0024.audio-controller-dummy-codec-pcm dummy-codec-pcm-1 [402a0024.audio-controller-dummy-codec-pcm dummy-codec-pcm-1]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 0: dummyaudiocard [dummy-audio-card], device 2: 400c0000.audio-controller-dummy-codec-pcm dummy-codec-pcm-2 [400c0000.audio-controller-dummy-codec-pcm dummy-codec-pcm-2]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
root@stm32mp2:~#

通过 ls /proc/asound/card0/ 可以看到 pcm0 只有 Playback 而 pcm1只有 Capture 。可以通过修改 /etc/asound.config

pcm.sai2 {
    type asym
    playback.pcm {
        type hw
        card 0
        device 0
    }
    capture.pcm {
        type hw
        card 0
        device 1
    }
}

ctl.sai2 {
    type hw
    card 0
}

pcm.!default pcm.sai2
ctl.!default ctl.sai2

在使用 DepAlsaBridge 应用程序时通过 -d sai2 指定声卡即可

dummy_codec 模块编译

  • 单独编译
makefile
# 定义模块目标
obj-m := dummy-codec.o

# 内核构建目录路径
KDIR := /opt/1/MP257/Developer-Package/stm32mp2-openstlinux-6.6-yocto-scarthgap-mpu-v24.11.06/sources/aarch64-ostl-linux/linux-stm32mp-6.6.48-stm32mp-r1-r0/build/

CROSS_COMPILE := aarch64-ostl-linux-

all:
	$(MAKE) ARCH=arm64 CROSS_COMPILE=$(CROSS_COMPILE) -C $(KDIR) M=$(PWD) modules

clean:
	$(MAKE) ARCH=arm64 CROSS_COMPILE=$(CROSS_COMPILE) -C $(KDIR) M=$(PWD) clean
  • 在内核源码中编译

    1. 复制模块源码
      将模块源码复制到以下路径:
      <KERNEL_SOURCE_PATH>/sound/soc/codecs

    2. 修改配置文件

      • 编辑 Makefile,添加模块的编译规则。
      • 修改 Kconfig,确保模块可以被配置。
    3. 启用模块
      使用以下命令打开内核配置菜单并选择模块

      bash
      make menuconfig

Debug

参考

Procfs filesystem

  • 列出PCM音频设备:

    bash
    cat /proc/asound/pcm
  • 获取PCM音频设备的硬件参数(此处为“0”卡的“0”设备):

    bash
    cat /proc/asound/card0/pcm0p/sub0/hw_params

Debugfs filesystem

  • 列出DAIs

    bash
    cat /sys/kernel/debug/asoc/dais