1.配置内核驱动
-> Device Drivers -> Sound card support (SOUND [=y]) -> Advanced Linux Sound Architecture (SND [=y]) -> ALSA for SoC audio support (SND_SOC [=y])
-> SoC Audio for Texas Instruments chips using eDMA
-> SoC Audio for the AM33XX chip based boards
2.配置DTS
am335x-evm.dts文件:
sound {
compatible = "simple-audio-card";
simple-audio-card,name = "AM335x-EVM";
simple-audio-card,widgets =
"Speaker", "Speaker",
"Headphone", "Headphone Jack",
"Speaker", "Speaker Jack",
"Line", "Line In";
simple-audio-card,routing =
"Speaker", "SPK_LN",
"Speaker", "SPK_LP";
simple-audio-card,format = "i2s";
simple-audio-card,bitclock-master = <&sound_master>;
simple-audio-card,frame-master = <&sound_master>;
simple-audio-card,cpu {
sound-dai = <&mcasp1>;
};
sound_master: simple-audio-card,codec {
sound-dai = <&codec>;
/* system-clock-frequency = <14745600>; */
system-clock-frequency = <14400000>;
};
};
我的板子wm8960芯片mclk时钟输入这里是晶振14.745600MHz,但是由于该频率不能很好用于芯片倍频分频(会出现噪音),所以根据芯片手册这里使用14.4MHz的推荐值,具体数值还是得参考具体板子。
codec: wm8960@1a {
#sound-dai-cells = <0>;
compatible = "wlf,wm8960";
reg = <0x1a>;
status = "okay";
};
......
&mcasp1 {
#sound-dai-cells = <0>;
pinctrl-names = "default", "sleep";
pinctrl-0 = <&mcasp1_pins>;
pinctrl-1 = <&mcasp1_pins_sleep>;
status = "okay";
op-mode = <0>; /* MCASP_IIS_MODE */
tdm-slots = <2>;
/* 4 serializers */
num-serializer = <4>;
serial-dir = < /* 0: INACTIVE, 1: TX, 2: RX */
1 2 0 0
>;
tx-num-evt = <1>;
rx-num-evt = <1>;
};
......
mcasp1_pins: mcasp1_pins {
pinctrl-single,pins = <
AM33XX_IOPAD(0x9a0, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcasp0_aclkr.mcasp1_aclkx */
AM33XX_IOPAD(0x9a4, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcasp0_fsr.mcasp1_fsx */
AM33XX_IOPAD(0x9a8, PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* mcasp0_arx1.mcasp1_axr0 */
AM33XX_IOPAD(0x9ac, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcasp0_ahclkx.mcasp1_axr1 */
>;
};
mcasp1_pins_sleep: mcasp1_pins_sleep {
pinctrl-single,pins = <
AM33XX_IOPAD(0x9a0, PIN_INPUT_PULLDOWN | MUX_MODE7)
AM33XX_IOPAD(0x9a4, PIN_INPUT_PULLDOWN | MUX_MODE7)
AM33XX_IOPAD(0x9a8, PIN_INPUT_PULLDOWN | MUX_MODE7)
AM33XX_IOPAD(0x9ac, PIN_INPUT_PULLDOWN | MUX_MODE7)
>;
};
3.修改驱动(如果上述配置无法播放声音,继续进行下面修改)
这里主要是为了使用PLL获得wm8960工作时钟。
sound/soc/codecs/wm8960.c (一下红色粗体为添加内容)
static int wm8960_configure_clocking(struct snd_soc_codec *codec)
{
struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
int sysclk, bclk, lrclk, freq_out, freq_in;
u16 iface1 = snd_soc_read(codec, WM8960_IFACE1);
int i, j, k;
dev_dbg(codec->dev,
"Codec is slave mode, no need to configure clock\n");
return 0;
}
wm8960->clk_id = WM8960_SYSCLK_PLL;
freq_in = wm8960->freq_in = 14400000;
if (wm8960->clk_id != WM8960_SYSCLK_MCLK && !wm8960->freq_in) {
dev_err(codec->dev, "No MCLK configured\n");
return -EINVAL;
}
freq_in = wm8960->freq_in;bclk = wm8960->bclk;
lrclk = wm8960->lrclk;