Linux ALSA 之九:ALSA ASOC Codec Driver

news/2024/11/28 6:14:00/

ALSA ASOC Codec Driver

  • 一、Codec 简介
  • 二、Codec 注册
    • 2.1 Codec Driver 的 Platform Driver & Platform Device 驱动模型
    • 2.2 在 Probe() 中注册 Codec Driver


一、Codec 简介

Codec 的作用可以归结为 4 种,分别是:

  • 对 PCM 等信号进行 D/A 转换,把数字的音频信号转换为模拟信号
  • 对 Mic、Line in 或者其他输入源的模拟信号进行 A/D 转换,把模拟的声音信号转变 CPU 能够处理的数字信号
  • 对音频通路进行控制,比如播放音乐,收听调频收音机,又或者接听电话时,音频信号在 codec 内的流通路线是不一样的
  • 对音频信号做出相应的处理,例如音量控制,功率放大,EQ 控制等等

ASoC 对 Codec 的这些功能都定义了一个基本要求是:驱动程序的代码必须要做到平台无关性,以方便同一个 Codec 的代码不经修改即可在不同的平台上。

二、Codec 注册

# Note下面均以 wm8960.c 为例进行讲解

2.1 Codec Driver 的 Platform Driver & Platform Device 驱动模型

该部分其实就是 /sound/soc/codecs/wm8960.c 中的 platform driver 与 /arch/arm/boot/dts/mt7623a-rfb-emmc.dts 中的 platform device 进行匹配,匹配成功后调用 wm8960_i2c_probe() 函数。

1)wm8960.c

static const struct of_device_id wm8960_of_match[] = {{ .compatible = "wlf,wm8960", },{ }
};
MODULE_DEVICE_TABLE(of, wm8960_of_match);static struct i2c_driver wm8960_i2c_driver = {.driver = {.name = "wm8960",.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);

platform driver 中有注册名为 "wlf,wm8960"

2)mt7623a-rfb-emmc.dts

...
&i2c1 {pinctrl-names = "default";pinctrl-0 = <&i2c1_pins_b>;status = "okay";wm8960: wm8960@1a {compatible = "wlf,wm8960";reg = <0x1a>;};
};
...

在设备树文件中有注册名为 "wlf,wm8960"platform device,当 platform driver & platform device 匹配之后则会调用 platform_driver 下的 probe() 函数。

2.2 在 Probe() 中注册 Codec Driver

devm_snd_soc_register_component(&i2c->dev,&soc_component_dev_wm8960, &wm8960_dai, 1); // 创建 Codec Component

同 Platform Dai Driver 一样,Codec Driver 调用 snd_soc_register_component() 函数将 snd_soc_component_driver & snd_soc_dai_driver 注册为一个 snd_soc_component 实例,并且通过 snd_soc_register_dais() 循环将所有的 snd_soc_dai_driver register 为 snd_soc_dai,加入到 component->dai_list 中,最后将该 component 添加到全局链表 component_list 中以便能被 Machine 驱动识别,注册时序框图如下:
在这里插入图片描述

1)Codec Driver

static const struct snd_soc_component_driver soc_component_dev_wm8960 = {.probe			= wm8960_probe,.set_bias_level		= wm8960_set_bias_level,.suspend_bias_off	= 1,.idle_bias_on		= 1,.use_pmdown_time	= 1,.endianness		= 1,.non_legacy_dai_naming	= 1,
};

Codec Driver 一般都是 dapm widgets,dapm_route 数组。有两种方式可以注册 dapm widgets 和 dapm route.

  • 通过上面的 struct snd_soc_component_driver soc_component_dev_wm8960 结构体中初始化 dapm widgets 数组和 dapm route 数组;
  • 在 struct snd_soc_component_driver 的 probe 函数中注册,需要调用 snd_soc_dapm_new_controls 和 snd_soc_dapm_add_routes 注册 dapm widgets 和 dapm route.

实际上第一种方式 struct snd_soc_component_driver 注册到 asoc core 里的时候也会通过这两个函数注册。

# Note涉及的 DAPM 详见后面 DAPM 章节

2)Codec Dai Driver

static const struct snd_soc_dai_ops wm8960_dai_ops = {.hw_params = wm8960_hw_params,.hw_free = wm8960_hw_free,.digital_mute = wm8960_mute,.set_fmt = wm8960_set_dai_fmt,.set_clkdiv = wm8960_set_dai_clkdiv,.set_pll = wm8960_set_dai_pll,.set_sysclk = wm8960_set_dai_sysclk,
};static struct snd_soc_dai_driver wm8960_dai = {.name = "wm8960-hifi",.playback = {.stream_name = "Playback",.channels_min = 1,.channels_max = 2,.rates = WM8960_RATES,.formats = WM8960_FORMATS,},.capture = {.stream_name = "Capture",.channels_min = 1,.channels_max = 2,.rates = WM8960_RATES,.formats = WM8960_FORMATS,},.ops = &wm8960_dai_ops,.symmetric_rates = 1,
};

参考链接:
linux-alsa详解6 ASOC-codec


http://www.ppmy.cn/news/703563.html

相关文章

单片机设计_8路抢答器(AT89C51)

想要更多项目私wo!!! 一、电路设计 此电路由AT89C51最小系统、四位数码管、蜂鸣器电路和按键模块组成。 运行原理&#xff1a; 该抢答器电路可同时进行八路优先抢答。按键按下后&#xff0c;蜂鸣器发声&#xff0c;同时数码管 显示优先抢答者的号码&#xff0c;抢答成功后&am…

89C51单片机与DAC0832

DAC0832的介绍DAC0832与51单片机使用实例实例proteus仿真实例代码 1.DAC0832的介绍&#xff1a; 主要特性&#xff1a;(1) 分辨率:8位 (2) 电流稳定时间1us 芯片引脚&#xff1a; : 片选 ILE&#xff1a;输入寄存器允许&#xff0c;高电平有效 &#xff1a;写信号,当,,ILE同…

VS上配置docker步骤记录

1:VS里安装Remote Development 2:运行 sudo usermod -aG docker $USER。#将当前用户添加到docker用户组中 sudo newgrp docker#更新,运行这个切到了root用户,获取权限 docker ps #列出正在运行的容器。它会显示容器的相关信息&#xff0c;如容器ID、镜像名称、创建时间、状态…

MySQL - Delete 和 Truncate 的区别

1. DELETE 命令 语法 &#xff1a; delete from 表名 [where 条件] -- 删除数据 (避免这样写, 会全部删除) DELETE FROM student;-- 删除指定数据 DELETE FROM student WHERE id 1; 2. TRUNCATE 命令 作用 : 完全清空一个数据库表, 表的结构和索引约束不会变. -- 清空 stu…

sftp上传文件失败解决

同事求助&#xff0c;说他用sftp上传文件失败。 首先想到的是权限问题。于是登陆服务器&#xff0c;cd到上传目录&#xff0c;ls -l看上去没问题。 测试一下吧&#xff0c;用我自己的帐号sftp登陆&#xff0c;随便传一个文件&#xff0c;成功了。 哈&#xff0c;问题范围缩减…

SFTP向服务器上传文件失败问题的解决办法

FileZilla和XShell都可以通过FTP传输文件。 FileZilla连接上服务器后&#xff0c;可以下载文件&#xff0c;但是不能上传&#xff0c;传输会有提示&#xff1a;“无法启动传输”。 这个问题一般情况有如下三个原因&#xff1a; 1、文件夹权限不够&#xff0c;修改之&#xff…

网易邮箱发送失败的原因

1.设置故障&#xff0c;再网易的web界面开启pop3、imap协议即可 一般出现再刚下载还未设置 2.免费信箱故障 解决方法&#xff1a;给自己发邮件&#xff0c;如果没有受到&#xff0c;则免费信箱有问题&#xff0c;去手机店处理即可 3.对方线路问题 测试方法&#xff1a;让一个朋…

smtp 发送邮件(qq邮箱)失败

项目用的框架是 ThinkPHP&#xff0c;在本地WAMP环境下使用了QQ邮箱的 smtp 邮件系统 本地测试成功的情况下&#xff0c;部署到服务器上无法发送邮件&#xff0c;报错&#xff1a;500 解决方法 最终发现是端口号的原因&#xff0c;QQ邮箱的 smtp 服务端口号为 465 或 587&#…