AM335X添加声卡驱动max98357a记录_基于TI官方PSDK

0.硬件平台信息

前篇文章有描述,我们自制硬件平台是使用OSD335X SM芯片,集成了AM335X,DDR3,PMIC,EEPROM。硬件设计上少了很多麻烦,及CPU,DDR测试上的很多麻烦。官方开发板参考BBB开发板设计。我们自制硬件有少许改动,所以基础的DTS文件,是基于BBB的DTS上修改。

声卡芯片,我们选用的是MAX98357A,使用MCASP0,连接了MCASP0_ACLKX,MCASP0_AXR0,MCASP0_FSX。

1.查找驱动文件

一般使用较多的芯片,LINUX源码包中都包含有现成驱动,有其它厂商移植好的。原以为自己要写的,但对LINUX整个驱动框架,开发都不了解,难度太大。所以第一步是找到现有驱动。

在ubuntu的shell中,定位到linux的源码目录。
输入:find . “*.c” | grep “98357”
可以检索出,源码中所有名字带“98357”的C文件。

~/ti/ti-processor-sdk-linux-am335x-evm-06.03.00.106/board-support/linux-4.19.94+gitAUTOINC+be5389fd85-gbe5389fd85$ find . "*.c" | grep "98357"
./include/config/snd/soc/max98357a.h
./sound/soc/codecs/max98357a.c
./sound/soc/codecs/.max98357a.o.cmd
./sound/soc/codecs/max98357a.o
./sound/soc/amd/acp-da7219-max98357a.c
./sound/soc/intel/boards/kbl_da7219_max98357a.c
./sound/soc/intel/boards/glk_rt5682_max98357a.c
./sound/soc/intel/boards/skl_nau88l25_max98357a.c
./sound/soc/intel/boards/bxt_da7219_max98357a.c
./Documentation/devicetree/bindings/sound/max98357a.txt
find: `*.c': 没有那个文件或目录

从以上输出可以看出,源码中包含了max98357a的驱动代码。且驱动文件在目录:sound/soc/codecs中
如果没有检索出相应文件。还可以输入:find . -type f -name “*.c” | xargs grep --color -n “98357”
xargs可以把find文件中的内容拿 出来检索。这指令可以检索出所有文件中含指定字符串的文件,并显示内容,用特殊颜色标出字符串,并显示行号。但要检索文件内容,速度较慢。

~/ti/ti-processor-sdk-linux-am335x-evm-06.03.00.106/board-support/linux-4.19.94+gitAUTOINC+be5389fd85-gbe5389fd85$ find . -type f -name "*.c" | xargs grep --color -n "98357"
./sound/soc/codecs/max98357a.c:12: * max98357a.c -- MAX98357A ALSA SoC Codec driver
./sound/soc/codecs/max98357a.c:30:static int max98357a_daiops_trigger(struct snd_pcm_substream *substream,
./sound/soc/codecs/max98357a.c:54:static const struct snd_soc_dapm_widget max98357a_dapm_widgets[] = {
./sound/soc/codecs/max98357a.c:58:static const struct snd_soc_dapm_route max98357a_dapm_routes[] = {
./sound/soc/codecs/max98357a.c:62:static int max98357a_component_probe(struct snd_soc_component *component)
./sound/soc/codecs/max98357a.c:75:static const struct snd_soc_component_driver max98357a_component_driver = {
./sound/soc/codecs/max98357a.c:76:	.probe			= max98357a_component_probe,

2.添加驱动,更改设备树等配置
这步先查找有人已加载max98357a成功的方法。参考网址:https://github.com/beagleboard/bb.org-overlays/issues/39。但按照此方法添加后我们的板子并未有声音输出,遇到一系列问题,随后更进说明。

设备树修改过程 ~/ti/ti-processor-sdk-linux-am335x-evm-06.03.00.106/board-support/linux-4.19.94+gitAUTOINC+be5389fd85-gbe5389fd85/arch/arm/boot/dts/am335x-boneblack-common.dtsi:
引脚配置

mcasp0_pins: mcasp0_pins {
		pinctrl-single,pins = <
			//AM33XX_IOPAD(0x9ac, PIN_INPUT_PULLUP | MUX_MODE0) /* mcasp0_ahcklx.mcasp0_ahclkx */  //后来了解,这个引脚是在使用外部时钟芯片输入才需要使用
			AM33XX_IOPAD(0x998, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mcasp0_axr0.mcasp0_axr0*/
			AM33XX_IOPAD(0x994, PIN_OUTPUT_PULLUP | MUX_MODE0) /* mcasp0_fsx.mcasp0_fsx */
			AM33XX_IOPAD(0x990, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mcasp0_aclkx.mcasp0_aclkx */
			//AM33XX_IOPAD(0x86c, PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a11.GPIO1_27 */  //后来了解到,在使用外部时钟芯片时,用到的时钟使能引脚
		>;
	};

声卡驱动 sound 分成3个部分:
To achieve all this, ASoC splits an embedded audio system into three components:

Codec driver: The codec driver is platform independent and contains audio controls, audio DAPM interface capabilities, codec DAPM definition and codec IO functions.
Platform driver: The platform driver contains the audio dma engine and audio interface drivers (e.g. I2S, AC97, PCM) for that platform.
Machine driver: The machine driver handles any machine specific controls and audio events i.e. turning on an DAPM at start of playback.

添加MCASP0设备树,即 Machine driver层:

&mcasp0	{
	#sound-dai-cells = <0>;
	pinctrl-names = "default";
	pinctrl-0 = <&mcasp0_pins>;
	status = "okay";
	op-mode = <0>;	/* MCASP_IIS_MODE */
	tdm-slots = <2>;
	serial-dir = <	/* 0: INACTIVE, 1: TX, 2: RX */
			1 0 0 0	//4个数字,对应AXRn   n对应AXR引脚的一组 0-3。我们用的axr0,所以应该设置第一个数了,参考网址用的axr2,所以用的第3个数字
		>;
	tx-num-evt = <32>;
	rx-num-evt = <32>;
};

添加sound节点:

/ {
	clk_mcasp0_fixed: clk_mcasp0_fixed {
		#clock-cells = <0>;
		compatible = "fixed-clock";
		/*clock-frequency = <24576000>;*/
		clock-frequency = <12288000>;
	};

	clk_mcasp0: clk_mcasp0 {
		#clock-cells = <0>;
	//	compatible = "gpio-gate-clock";
		clocks = <&clk_mcasp0_fixed>;
	//	enable-gpios = <&gpio1 27 0>; /* BeagleBone Black Clk enable on GPIO1_27 */
	};

	max98357a: max98357a {//对应Codec driver
		#sound-dai-cells = <0>;
		status = "okay";

		compatible = "maxim,max98357a";
		/*sdmode-gpios = <&gpio1 14 0>;*/
	};
    //Platform driver:
	sound {
		compatible = "simple-audio-card";
		status = "okay";
		simple-audio-card,name = "TI BeagleBone Black";
		simple-audio-card,format = "i2s";
		simple-audio-card,bitclock-master = <&dailink0_master>;
		simple-audio-card,frame-master = <&dailink0_master>;
		dailink0_master: simple-audio-card,cpu {
			sound-dai = <&mcasp0>;
			clocks = <&clk_mcasp0>;	
		};

		simple-audio-card,codec {			
			sound-dai = <&max98357a 0>;			
		};
	}; 

一开始CLOCK配置和引脚配置,不知道CLOCK enable是什么意思。看了这篇帖子终于明白,最后才屏蔽了 clock 使能相关的,配置。https://e2e.ti.com/support/processors/f/791/t/875002?tisearch=e2e-sitesearch&keymatch=OCTVO-3P-AM335X%253A
MCASP0的配置,修改对应的AXR的TX,RX状态也是参照这个理解的。

5.内核配置修改

查找缺省配置文件:/arch/arm/configs/tisdk_am335x-evm_defconfig。发现没有我们驱动max98357a的配置文件。menuconfig里也没有。所以需要自己添加配置,使能编译。参照这篇帖子:https://stackoverflow.com/questions/52970065/audio-issue-with-imx6-board-max98357a-codec/63342117#63342117
其中描述:
I had some trouble getting the sound card (MA98357a codec with the simple-audio-card) to work with a recent revision of the imx6q (i.MX 6 Quad), so I am sharing here my solution:

CONFIG_SND_SOC_MAX98357A needs to be enabled (associated with the compatible "maxim,max98357a"). But "by default" this option cannot be selected under make menuconfig. The associated Kconfig (sound/soc/codecs/Kconfig) needs to be patched. Replace:

config SND_SOC_MAX98357A
tristate

By:

config SND_SOC_MAX98357A
tristate “Maxim MAX98357A CODEC”

CONFIG_SND_SIMPLE_CARD needs to be enabled (associated with the compatible "simple-audio-card")

先修改sound/soc/codecs/Kconfig文件,再修改tisdk_am335x-evm_defconfig。因为我们调用PSDK安装目录下的,make linux编译,他会自动make tisdk_am335x-evm_defconfig。所以,menuconfig 时使用Kfonfig配置出来的会被删除,被tisdk_am335x-evm_defconfig重新配置替换。

3.1.menuconfig配置方法:

o enable/disable audio support, start the Linux Kernel Configuration tool:

$ make menuconfig 

Select Device Drivers from the main menu.

    ...
    ...
    Power management options --->
    [ ] Networking support --->
    Device Drivers --->
    File systems --->
    Kernel hacking --->
    ...
    ...

Select Sound card support as shown here:
    ...
    ...
    Multimedia devices --->
    Graphics support --->
<*> Sound card support --->
[*] HID Devices --->
[*] USB support --->
    ...
    ...


Select Advanced Linux Sound Architecture as shown here:

--- Sound card support
<*> Advanced Linux Sound Architecture --->
< > Open Sound System (DEPRECATED) --->

Select ALSA for SoC audio support as shown here:
    ...
    ...
[*] ARM sound devices --->
[*] SPI sound devices --->
<*> ALSA for SoC audio support --->

Select SoC Audio for TI81XX chip as shown here:

--- ALSA for SoC audio support
<*> SoC Audio for the Maxim MAX98357A CODEC
< > Build all ASoC CODEC drivers (NEW)

3.2. 修改tisdk_am335x-evm_defconfig方法:
添加:

# CONFIG_SND_SOC_MAX98373 is not set
CONFIG_SND_SOC_MAX98357A=y

CONFIG_SND_SIMPLE_CARD_UTILS=y//原来已使能
CONFIG_SND_SIMPLE_CARD=y//原来已使能

CONFIG_SND_DEBUG=y//打开Debug

其中,所有配置必须顶格写。一开始犯了个错误空了一格,为和注释行对齐,导致配置不成功。

至此配置成功。在PSDK安装目录下:make linux
4.测试及问题解决

按3中更改的,把zImage 和 .dtb更新后测试。使用 aplay -vv 123.wav测试发现无输出,且测试的音频卡住 不动。如下:

root@am335x-evm:~# aplay -vv 123.wav 
Playing WAVE '123.wav' : Signed 16 bit Little Endian, Rate 44100 Hz, Stereo
Rate conversion PCM (48000)
Converter: linear-interpolation
Protocol version: 10002
Its setup is:
  stream       : PLAYBACK
  access       : RW_INTERLEAVED
  format       : S16_LE
  subformat    : STD
  channels     : 2
  rate         : 44100
  exact rate   : 44100 (44100/1)
  msbits       : 16
  buffer_size  : 22050
  period_size  : 5512
  period_time  : 125000
  tstamp_mode  : NONE
  tstamp_type  : MONOTONIC
  period_step  : 1
  avail_min    : 5512
  period_event : 0
  start_threshold  : 22050
  stop_threshold   : 22050
  silence_threshold: 0
  silence_size : 0
  boundary     : 1445068800
Slave: Plug PCM: Hardware PCM card 0 'TI BeagleBone Black' device 0 subdevice 0
Its setup is:
  stream       : PLAYBACK
  access       : MMAP_INTERLEAVED
  format       : S16_LE
  subformat    : STD
  channels     : 2
  rate         : 48000
  exact rate   : 48000 (48000/1)
  msbits       : 16
  buffer_size  : 24000
  period_size  : 6000
  period_time  : 125000
  tstamp_mode  : NONE
  tstamp_type  : MONOTONIC
  period_step  : 1
  avail_min    : 6000
  period_event : 0
  start_threshold  : 24000
  stop_threshold   : 24000
  silence_threshold: 0
  silence_size : 0
  boundary     : 1572864000
  appl_ptr     : 0
  hw_ptr       : 0
#######+                                           | 12%

使用 ls /dev/snd查看声卡有无添加成功:

root@am335x-evm:~# ls /dev/snd     
by-path    controlC0  pcmC0D0p   timer

发现有controlC0 代表添加声卡是成功识别到的。参考如下TI WIKI TI81XX PSP AUDIO Driver User Guide中的描述(WIKI还有两个月服务器就关闭了,所以网址就不帖了):
Device Interface

The operational interface in /dev/ contains three main types of devices:

PCM devices for recording or playing digitized sound samples,
CTL devices that allow manipulating the internal mixer and routing of the card, and,
MIDI devices to control the MIDI port of the card, if any.

Device Interface Name Description
/dev/snd/controlC0 Control devices (i.e. mixer, etc)
/dev/snd/pcmC0D0c PCM Card 0 Device 0 Capture device
/dev/snd/pcmC0D0p PCM Card 0 Device 0 Playback device

这时量硬件的3个引脚上均无波形,绝大概率可能是设备树没配置好,导致硬件没工作起来。如果声卡添加失败,aplay不会有以上描述的调试信息,会直接提示无声卡。期间试了网上说能用的很多版本,都没成功。

最后仅添加了以下这句,就有声音输出了:simple-audio-card,mclk-fs = <512>;添加在sound节点下,一会会放出完整能用的sound相关部分。但现在还不知道这句话的作用。

此时的播放的音乐,采样率为 rate 48K的能正常播放,但其他采样率的音频播放,会相当于几倍速播放,对比发现,是先软件插值参与了。而后再播正常48K采样率的音频也无法播放。像是时钟被修改了,或跳频率采样点了。在 aplay播放时,添加 --disable-resample属性,就可以正常播放。联想到之前配置时钟输入输出配置时,有个时钟输出属性。

root@am335x-evm:~# aplay -vv --disable-resample 123.wav 

最后尝试,在simple-audio-card,cpu 节点下,添加system-clock-direction-out;后,开机第一次播放声音正常。而后播放同样异常。发现有篇帖子描述的问题相同:https://e2e.ti.com/support/processors/f/791/t/936823?tisearch=e2e-sitesearch&keymatch=AM3352%3A%20McASP%20fsx%20start,像是MCASP时钟不固定,运行后,时钟被修改,出现偏差导致,具体原因不详。在/~.asoundrc,或/etc/asound.conf文件中加入:

pcm.!default {
    type rate
    slave {
        pcm "plughw:0,0"
        rate 48000
    }
}

这时,播放音频采样率正常。

最后,设备正常的设备树中,sound相关的节点如下:

clk_mcasp0_fixed: clk_mcasp0_fixed {
		#clock-cells = <0>;
		compatible = "fixed-clock";
		/*clock-frequency = <24576000>;*/
		clock-frequency = <12288000>;
	};

	clk_mcasp0: clk_mcasp0 {
		#clock-cells = <0>;
	//	compatible = "gpio-gate-clock";
		clocks = <&clk_mcasp0_fixed>;
	//	enable-gpios = <&gpio1 27 0>; /* BeagleBone Black Clk enable on GPIO1_27 */
	};

	max98357a: max98357a {
		#sound-dai-cells = <0>;
		status = "okay";

		compatible = "maxim,max98357a";
		/*sdmode-gpios = <&gpio1 14 0>;*/
	};

	sound {
		compatible = "simple-audio-card";
		status = "okay";
		simple-audio-card,name = "TI BeagleBone Black";
		simple-audio-card,format = "i2s";
		simple-audio-card,bitclock-master = <&dailink0_master>;
		simple-audio-card,frame-master = <&dailink0_master>;
		simple-audio-card,mclk-fs = <512>;
		dailink0_master: simple-audio-card,cpu {
			sound-dai = <&mcasp0>;
			clocks = <&clk_mcasp0>;	
			//system-clock-direction = "out";	
			system-clock-direction-out;
			//system-clock-frequency = <12000000>;	
			//dai-tdm-slot-num = <2>;
            		//dai-tdm-slot-width = <32>;

		};

		simple-audio-card,codec {			
			sound-dai = <&max98357a 0>;			
		};
	}; 

论坛也有写法,把clk_mcasp0_fixed节点,直接添加到simple-audio-card,cpu节点,省略掉clk_mcasp0节点。但经过测试发现不行。必须如上所示的,才可以正常播放音频。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值