49.Linux音频驱动

49.Linux音频驱动


一款音频芯片都具有ADC和DAC的功能,也就是专用的音频编解码芯片

衡量指标:采样率 采样位数

扬声器采样率:

复制代码
麦克风采样率:

采样位数一般有8位、16位、24位、32位...都是越高越好

使用了I2C1驱动框架

使用了SAI2驱动框架

ALSA针对ARM架构的SOC改进了ALSA音频驱动框架

即ASOC

ASOC分为三部分:

SOC(platform)、 Codec部分、 板载硬件(Machine)

SOC(platform):具体的SOC音频接口驱动,比如6ull的SAI接口,都是半导体厂商写好的

Codec:具体的音频芯片,比如WM8960.使用IIC驱动,不需要我们编写,由COdec芯片厂商提供

板载硬件:Machine部分,将具体的SOC与具体的Codec结合。与具体的硬件设备相关,也就是我们需要处理的部分

使用ASOC驱动框架将SOC与Codec结合起来。

  1. 修改设备树
  • 修改芯片的设备树

查看当前内核支持的芯片

linux_kernel/sound/soc/codecs

查看设备树修改文档

linux_kernel/Documentation/devicetree/bingings/sound/xxx.txt

c 复制代码
Example:

codec: wm8960@1a {
	compatible = "wlf,wm8960";
	reg = <0x1a>;

	wlf,shared-lrclk;
};

在i2c1下面添加

c 复制代码
codec1: wm8960@1a {
		compatible = "wlf,wm8960";
		reg = <0x1a>;
		clocks = <&clks IMX6UL_CLK_SAI2>;
		clock-names = "mclk";
		wlf,shared-lrclk;
	};

通过conpatible属性找到sound/soc/codecs/wm8960.c驱动文件

c 复制代码
static struct i2c_driver wm8960_i2c_driver = {
	.driver = {
		.name = "wm8960",
		.owner = THIS_MODULE,
		.of_match_table = wm8960_of_match,
	},
	.probe =    wm8960_i2c_probe,
	.remove =   wm8960_i2c_remove,
	.id_table = wm8960_i2c_id,
};

module_i2c_driver(wm8960_i2c_driver);

MODULE_DESCRIPTION("ASoC WM8960 driver");
MODULE_AUTHOR("Liam Girdwood");
MODULE_LICENSE("GPL");

是一个标准i2c驱动框架

  • 查看SAI接口,即SOC(platform)

    在imx6ull.dtsi中已经写好了节点

    c 复制代码
    			sai2: sai@0202c000 {
    					compatible = "fsl,imx6ul-sai",
    						     "fsl,imx6sx-sai";
    					reg = <0x0202c000 0x4000>;
    					interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
    					clocks = <&clks IMX6UL_CLK_SAI2_IPG>,
    						 <&clks IMX6UL_CLK_DUMMY>,
    						 <&clks IMX6UL_CLK_SAI2>,
    						 <&clks 0>, <&clks 0>;
    					clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
    					dma-names = "rx", "tx";
    					dmas = <&sdma 37 24 0>, <&sdma 38 24 0>;
    					status = "disabled";
    				};

    在imx6ull_alientek.dts中

    c 复制代码
    &sai2 {
    	pinctrl-names = "default";
    	pinctrl-0 = <&pinctrl_sai2
    		     &pinctrl_sai2_hp_det_b>;
    
    	assigned-clocks = <&clks IMX6UL_CLK_SAI2_SEL>,
    			  <&clks IMX6UL_CLK_SAI2>;
    	assigned-clock-parents = <&clks IMX6UL_CLK_PLL4_AUDIO_DIV>;
    	assigned-clock-rates = <0>, <11289600>;
    
    	status = "okay";
    };

    以及成功使能了sai2

    根据compatible寻找sai驱动文件sound/soc/fsl/fsl_sai.c

    c 复制代码
    static struct platform_driver fsl_sai_driver = {
    	.probe = fsl_sai_probe,
    	.driver = {
    		.name = "fsl-sai",
    		.pm = &fsl_sai_pm_ops,
    		.of_match_table = fsl_sai_ids,
    	},
    };
    module_platform_driver(fsl_sai_driver);
    
    MODULE_DESCRIPTION("Freescale Soc SAI Interface");
    MODULE_AUTHOR("Xiubo Li, <Li.Xiubo@freescale.com>");
    MODULE_ALIAS("platform:fsl-sai");
    MODULE_LICENSE("GPL");

    是一个标准的ASOC驱动框架

    以上两个只需要检查一下引脚是否对于,和复用情况即可。

  • sound节点(板载硬件)

    根文件下的sound节点(自带有了)

    c 复制代码
    sound {
    		compatible = "fsl,imx6ul-evk-wm8960",
    			   "fsl,imx-audio-wm8960";
    		model = "wm8960-audio";
    		cpu-dai = <&sai2>;
    		audio-codec = <&codec>;
    		asrc-controller = <&asrc>;
    		codec-master;
    		gpr = <&gpr 4 0x100000 0x100000>;
    		/*
                     * hp-det = <hp-det-pin hp-det-polarity>;
    		 * hp-det-pin: JD1 JD2  or JD3
    		 * hp-det-polarity = 0: hp detect high for headphone
    		 * hp-det-polarity = 1: hp detect high for speaker
    		 */
    		hp-det = <3 0>;
    		/* hp-det-gpios = <&gpio5 4 0>;
    		   mic-det-gpios = <&gpio5 4 0>; */
    		audio-routing =
    			"Headphone Jack", "HP_L",
    			"Headphone Jack", "HP_R",
    			"Ext Spk", "SPK_LP",
    			"Ext Spk", "SPK_LN",
    			"Ext Spk", "SPK_RP",
    			"Ext Spk", "SPK_RN",
    			"LINPUT2", "Mic Jack",
    			"LINPUT3", "Mic Jack",
    			"RINPUT1", "Main MIC",
    			"RINPUT2", "Main MIC",
    			"Mic Jack", "MICB",
    			"Main MIC", "MICB",
    			"CPU-Playback", "ASRC-Playback",
    			"Playback", "CPU-Playback",
    			"ASRC-Capture", "CPU-Capture",
    			"CPU-Capture", "Capture";
    	};

    通过这两行

    c 复制代码
    cpu-dai = <&sai2>;
    audio-codec = <&codec>;

    将sai与具体的设备驱动相结合。

    通过compatible属性找到具体的soundsound/soc/fsl/imx-wm8960.c驱动,理论上我们就需要编写该文件

    c 复制代码

    将设备树

  1. make menuconfig -》 进行一系列配置

进行配置,使内核支持wm8960

将zImage拷贝进开发板

c 复制代码
can-3v3: disabling
ALSA device list:
  #0: wm8960-audio
VFS: Mounted root (nfs filesystem) on device 0:15.
devtmpfs: mounted
Freeing unused kernel memory: 400K (8091c000 - 80980000)
nfs: server 192.168.1.15 not responding, still trying
nfs: server 192.168.1.15 OK

启动信息中可以看到wm8960已经配置好 了

c 复制代码
/ # cd /dev/snd/
/dev/snd # ls
controlC0  pcmC0D0c   pcmC0D0p   pcmC0D1c   pcmC0D1p   timer
/dev/snd #

这些就是ALSA音频驱动框架对应的设备文件

至此我们就移植好了音频驱动文件

下面移植应用层的应用程序来使用这写驱动文件

ALSA移植与使用

  1. ALSA-LIB移植
  2. ALSA-utils移植

移植好之后配置声卡

使用移植好的命令来控制声音的参数

shell 复制代码
amixer --help 			//查看 amixer 帮助信息
amixer scontrols 		//查看所有设置项
amixer controls			 //查看所有设置项
amixer scontents 		//查看设置值
amixer sset 设置项目 设置值   //修改值
amixer cset 设置项目 设置值	 //修改值
amixer sget 设置项目		//获取值
amixer cget 设置项目		//获取值

简单配置

shell 复制代码
amixer sset Headphone 100,100
amixer sset Speaker 120,120
amixer sset 'Right Output Mixer PCM' on
amixer sset 'Left Output Mixer PCM' on

//使用如下命令播放当前目录下的test.wav
aplay test.wav

使用声卡配置

创建mic_in_config.sh 脚本

c 复制代码
#!/bin/sh
#正点原子@ALIENTEK
#设置捕获的音量
amixer cset name='Capture Volume' 90,90
#PCM
amixer sset 'PCM Playback' on
amixer sset 'Playback' 256
amixer sset 'Right Output Mixer PCM' on
amixer sset 'Left Output Mixer PCM' on

#ADC PCM
amixer sset 'ADC PCM' 200

#耳机/喇叭(扬声器)设置播放音量,直流/交流
#Turn on Headphone
amixer sset 'Headphone Playback ZC' on
#Set the volume of your headphones(98% volume, 127 is the MaxVolume)
amixer sset Headphone 125,125
#Turn on the speaker
amixer sset 'Speaker Playback ZC' on
#Set the volume of your Speaker(98% volume, 127 is the MaxVolume)
amixer sset Speaker 125,125
#Set the volume of your Speaker AC(80% volume, 100 is the MaxVolume)
amixer sset 'Speaker AC' 4
#Set the volume of your Speaker AC(80% volume, 5 is the MaxVolume)
amixer sset 'Speaker DC' 4

#音频输入,左声道管理
#Turn on Left Input Mixer Boost
amixer sset 'Left Input Mixer Boost' off
amixer sset 'Left Boost Mixer LINPUT1' off
amixer sset 'Left Input Boost Mixer LINPUT1' 0
amixer sset 'Left Boost Mixer LINPUT2' off
amixer sset 'Left Input Boost Mixer LINPUT2' 0
#Turn off Left Boost Mixer LINPUT3
amixer sset 'Left Boost Mixer LINPUT3' off
amixer sset 'Left Input Boost Mixer LINPUT3' 0

#音频输入,右声道管理,全部关闭
#Turn on Right Input Mixer Boost
amixer sset 'Right Input Mixer Boost' on
amixer sset 'Right Boost Mixer RINPUT1' off
amixer sset 'Right Input Boost Mixer RINPUT2' 0
amixer sset 'Right Boost Mixer RINPUT2' on
amixer sset 'Right Input Boost Mixer RINPUT2' 127
amixer sset 'Right Boost Mixer RINPUT3' off
amixer sset 'Right Input Boost Mixer RINPUT3' 0

运行脚本即可采集声音了

相关推荐
四代水门1 小时前
简易视频预览器
android·android-studio
TangGeeA1 小时前
Linux CFS(完全公平调度器)全面总结
java·linux·服务器
xrn19971 小时前
Android OpenCV SDK 编译教程(WSL2 Ubuntu 22.04 环境)
android·c++·opencv
OpenCSG1 小时前
13.6B参数铸就“世界模型”,美团LongCat-Video实现5分钟原生视频生成,定义AI视频新标杆
人工智能·音视频
Blossom.1181 小时前
基于扩散模型的视频生成优化:从Stable Diffusion到AnimateDiff的显存革命
人工智能·深度学习·学习·决策树·搜索引擎·stable diffusion·音视频
MZZDX1 小时前
Linux操作系统相关知识总结
linux
2501_916007471 小时前
专业的 IPA 处理工具 构建可维护、可回滚的 iOS 成品加工与加固流水线
android·ios·小程序·https·uni-app·iphone·webview
天下无敌笨笨熊1 小时前
kotlin常用语法点理解
android·开发语言·kotlin
赖small强2 小时前
【音视频开发】深度解析图像处理核心概念:饱和度、色度与对比度
图像处理·音视频·色度·对比度·饱和度