1.概述
本章描述如何添加声卡,调试声卡以及通路等。
2.音频开发指南
一个声卡包含 cpu_dai, codec_dai, 以及 dai_link 组成,分别对应 cpu dai 的 dirver,比如
I²S driver, spdif driver; codec driver, 比如 ad82128 codec driver; dai_link driver,也就
是 machine driver, 比如 sound/soc/codec/amlogic/ad82128.c。 4.4 的内核中支持两种
方式创建声卡,一种是通用的 simple-card framework,一种是传统的编写自定义的 machine
driver 来创建。 本文档均以 ad82128 为例。
2.1 codec driver
2.1.1 添加 codec driver
sound/soc/codec/amlogic/ad82128.c
2.1.2 加入驱动编译
sound/soc/codec/amlogic/Kconfig
config AMLOGIC_SND_SOC_AD82128
bool "ESMT AD82128"
depends on AMLOGIC_SND_SOC_CODECS
depends on I2C
default n
help
Enable Support for ESMT AD82584f CODEC.
Select this if your AD82584F is connected via an I2C bus.
sound/soc/codec/amlogic/Makefile
snd-soc-ad82128-objs := ad82128.o
obj-$(CONFIG_AMLOGIC_SND_SOC_AD82128) += ad82128.o
2.1.3 Deconfig
CONFIG_AMLOGIC_SND_SOC_AD82128=y
2.1.4 .DTS添加
aml-audio-card,dai-link@1 {
format = "i2s";
mclk-fs = <256>;
continuous-clock;
//bitclock-inversion;
//frame-inversion;
bitclock-master = <&aml_tdmb>;
frame-master = <&aml_tdmb>;
//bitclock-master = <&tdmbcodec>;
//frame-master = <&tdmbcodec>;
/* suffix-name, sync with android audio hal
* what's the dai link used for
*/
suffix-name = "alsaPORT-i2s";
cpu {
sound-dai = <&aml_tdmb>;
dai-tdm-slot-tx-mask = <1 1>;
dai-tdm-slot-rx-mask = <1 1>;
dai-tdm-slot-num = <2>;
dai-tdm-slot-width = <32>;
system-clock-frequency = <12288000>;
};
tdmbcodec: codec {
sound-dai = <&dummy_codec &dummy_codec
&amlogic_codec &ad82128_62>;
};
};
ad82128_62: ad82128_62@62 {
compatible = "ESMT,ad82128";
#sound-dai-cells = <0>;
reg = <0x31>;
power_gpio = <&gpio_ao GPIOAO_2 GPIO_ACTIVE_HIGH>;
no_mclk;
status = "okay";
};
2.2 PDM MIC
硬件PDM_DIN0(GPIOC_0),PDM_DIN1(GPIOC_1)分别接2个DMIC
aml_pdm: pdm {
compatible = "amlogic, g12a-snd-pdm";
#sound-dai-cells = <0>;
clocks = <&clkaudio CLKID_AUDIO_PDM
&clkc CLKID_FCLK_DIV3
&clkc CLKID_MPLL3
&clkaudio CLKID_AUDIO_PDMIN0
&clkaudio CLKID_AUDIO_PDMIN1>;
clock-names = "gate",
"sysclk_srcpll",
"dclk_srcpll",
"pdm_dclk",
"pdm_sysclk";
pinctrl-names = "pdm_pins";
pinctrl-0 = <&pdmin>;
filter_mode = <1>; /* mode 0~4, defalut:1 */
status = "okay";
};
pdmin: pdmin {
mux { /* gpioa_5, gpioa_6, gpioa_7, gpioa_8, gpioa_9*/
groups = "pdm_din0_c",
/*"pdm_din1_a",*/
"pdm_din1_c",
/*"pdm_din3_a",*/
"pdm_dclk_c";
function = "pdm";
};
};
录音命令
w400:/ # cat /proc/asound/pcm
00-00: TDM-A-dummy-alsaPORT-pcm multicodec-0 : : playback 1 : capture 1
00-01: TDM-B-dummy-alsaPORT-i2s multicodec-1 : : playback 1 : capture 1
00-02: TDM-C-dummy multicodec-2 : : playback 1 : capture 1
00-03: PDM-dummy-alsaPORT-pdm dummy-3 : : capture 1
00-04: SPDIF-dummy-alsaPORT-spdif dummy-4 : : playback 1 : capture 1
00-05: LOOPBACK-A-dummy-alsaPORT-loopback dummy-5 : : capture 1
w400:/ # tinycap /data/mic4.wav -D 0 -d 3 -r 48000 -c 4 -b 16 -p 1024 -n 4
Capturing sample: 4 ch, 48000 hz, 16 bit
2.3 loopback回采配置
loopback:loopback@0 {
compatible = "amlogic, g12a-loopback";
#sound-dai-cells = <0>;
clocks = <&clkaudio CLKID_AUDIO_PDM
&clkc CLKID_FCLK_DIV3
&clkc CLKID_MPLL3
&clkaudio CLKID_AUDIO_PDMIN0
&clkaudio CLKID_AUDIO_PDMIN1
&clkc CLKID_MPLL0
&clkaudio CLKID_AUDIO_MCLK_A>;
clock-names = "pdm_gate",
"pdm_sysclk_srcpll",
"pdm_dclk_srcpll",
"pdm_dclk",
"pdm_sysclk",
"tdminlb_mpll",
"tdminlb_mclk";
/* datain src
* 0: tdmin_a;
* 1: tdmin_b;
* 2: tdmin_c;
* 3: spdifin;
* 4: pdmin;
*/
datain_src = <4>;
datain_chnum = <4>;
datain_chmask = <0xf>;
/* config which data pin for loopback */
datain-lane-mask-in = <0 0 1 1>;
/* calc mclk for datalb */
mclk-fs = <256>;
/* tdmin_lb src
* 0: tdmoutA
* 1: tdmoutB
* 2: tdmoutC
* 3: PAD_TDMINA_DIN*, refer to core pinmux
* 4: PAD_TDMINB_DIN*, refer to core pinmux
* 5: PAD_TDMINC_DIN*, refer to core pinmux
* 6: PAD_TDMINA_D*, oe, refer to core pinmux
* 7: PAD_TDMINB_D*, oe, refer to core pinmux
*/
/* if tdmin_lb >= 3, use external loopback */
datalb_src = <1>;
datalb_chnum = <2>;
datalb_chmask = <0x3>;/* max 0xff, each bit for one channel */
/* config which data pin as loopback */
datalb-lane-mask-in = <1 0 0 0>;
status = "okay";
};
w400:/ # cat /proc/asound/pcm
00-00: TDM-A-dummy-alsaPORT-pcm multicodec-0 : : playback 1 : capture 1
00-01: TDM-B-dummy-alsaPORT-i2s multicodec-1 : : playback 1 : capture 1
00-02: TDM-C-dummy multicodec-2 : : playback 1 : capture 1
00-03: PDM-dummy-alsaPORT-pdm dummy-3 : : capture 1
00-04: SPDIF-dummy-alsaPORT-spdif dummy-4 : : playback 1 : capture 1
00-05: LOOPBACK-A-dummy-alsaPORT-loopback dummy-5 : : capture 1
w400:/ #
tinycap /data/test.wav -D 0 -d 5 -r 48000 -c 6 -b 16 -p 1024 -n 4