es8388 驱动详解

news2024/11/29 18:27:25

音频的基本框架

  

      分为三个部分:

      1) 整体的绿框,为machine,例如你的PC等,负责图中 “线”的部分的关联,及黄色连接器的管理。也就是说不属于 paltform和codec管理的部分,都划归machine管理。

   对应的驱动文件有: sound\soc\generic\simple-card.c

      2) paltform,例如基于intel 或者arm等平台的soc,提供数据传输的通道I2S及配置通道I2C等。

     3) codec 芯片,负责A/D ,D/A的转换及控制。

es8388 即为codec

ES8388驱动

   对于所有的驱动,我们先理解其硬件结构,再去阅读代码,就很容易理解。

es8388的框图

   为什么我们要说框图,框图是驱动编写的一个基础。

    

    由此框图,我们主要了解音频数据输入输出的路径,进而了解后续将要介绍的概念。

    1) LIN1 LIN2  RIN1 RIN2作为输入端,其对外与mic 等输入设备的连接器连接。

          对内首先经过

           a.  mux 多路选择 (也就是选择 LIN1  LIN2  LIN1-RIN1  LIN2-RIN2,四选一)即输入的左声道支持两路(LIN1 LIN2)分别作为一个输入源;或者LIN1-RIN1 ,LIN2-RIN2作为立体输入源。这个需要硬件连线配合。

          b. 接下来经过mic amp ,即前置放大器。将采集的声音(当然也包括噪音)进行放大处理。

          c-1. mux 多路选择到ADC,完成模数转换,进而到serial audio data DSDIN-->i2s-->soc

          c-2.或者经过此mux,输出为LIN作为mixL --》OUT,也就是耳机,此路径为循环测试用,即音频输入直接到音频输出,不经过ADC--DAC等。

   2)输出的路径则比较简单

        直接从ASDOUT -->DAC-->OUT

widget

     根据第一章的描述,linux驱动分为三大块,而每块都有自己的widget管理,例如machine的驱动simple-card管理自己的widget(主要音频输入输出的连接器),而8388 作为codec则主要框图中提及的各个部件。

       下面结合代码理解,针对如下代码,

       1)前面四行 widget 和图上对应比较明确。

       2)left PGA Mux 为框图中INPUT连接的第一个mux

       3)mic bias 偏置电压,在框图中未画出,对是否可以录音也有影响。

        4)  differential mux 差分选择,图中也未画出,在输入为LIN1-RIN1 or LIN2-RIN2时才会启用。

       5)ADC mux,即选择哪路输入到ADC

        6)  ADC  

static const struct snd_soc_dapm_widget es8323_dapm_widgets[] = {
	SND_SOC_DAPM_INPUT("LINPUT1"),
	SND_SOC_DAPM_INPUT("LINPUT2"),
	SND_SOC_DAPM_INPUT("RINPUT1"),
	SND_SOC_DAPM_INPUT("RINPUT2"),
	SND_SOC_DAPM_MUX("Left PGA Mux", SND_SOC_NOPM, 0, 0,
			 &es8323_left_dac_mux_controls),
	SND_SOC_DAPM_MUX("Right PGA Mux", SND_SOC_NOPM, 0, 0,
			 &es8323_right_dac_mux_controls),
	SND_SOC_DAPM_MICBIAS("Mic Bias", ES8323_ADCPOWER, 3, 1),

	SND_SOC_DAPM_MUX("Differential Mux", SND_SOC_NOPM, 0, 0,
			 &es8323_diffmux_controls),

	SND_SOC_DAPM_MUX("Left ADC Mux", SND_SOC_NOPM, 0, 0,
			 &es8323_monomux_controls),
	SND_SOC_DAPM_MUX("Right ADC Mux", SND_SOC_NOPM, 0, 0,
			 &es8323_monomux_controls),

	SND_SOC_DAPM_MUX("Left Line Mux", SND_SOC_NOPM, 0, 0,
			 &es8323_left_line_controls),
	SND_SOC_DAPM_MUX("Right Line Mux", SND_SOC_NOPM, 0, 0,
			 &es8323_right_line_controls),

	SND_SOC_DAPM_ADC("Right ADC", "Right Capture", ES8323_ADCPOWER, 4, 1),
	SND_SOC_DAPM_ADC("Left ADC", "Left Capture", ES8323_ADCPOWER, 5, 1),

	/* gModify.Cmmt Implement when suspend/startup */
	SND_SOC_DAPM_DAC("Right DAC", "Right Playback", ES8323_DACPOWER, 6, 1),
	SND_SOC_DAPM_DAC("Left DAC", "Left Playback", ES8323_DACPOWER, 7, 1),

	SND_SOC_DAPM_AIF_OUT("I2S OUT", "Capture",  0, SND_SOC_NOPM, 0, 0),
	SND_SOC_DAPM_AIF_IN("I2S IN", "Playback", 0, SND_SOC_NOPM, 0, 0),

	SND_SOC_DAPM_MIXER("Left Mixer", SND_SOC_NOPM, 0, 0,
			   &es8323_left_mixer_controls[0],
			   ARRAY_SIZE(es8323_left_mixer_controls)),
	SND_SOC_DAPM_MIXER("Right Mixer", SND_SOC_NOPM, 0, 0,
			   &es8323_right_mixer_controls[0],
			   ARRAY_SIZE(es8323_right_mixer_controls)),
	SND_SOC_DAPM_PGA("Right ADC Power", ES8323_ADCPOWER, 6, 1, NULL, 0),
	SND_SOC_DAPM_PGA("Left ADC Power", ES8323_ADCPOWER, 7, 1, NULL, 0),
	SND_SOC_DAPM_PGA("Right Out 2", ES8323_DACPOWER, 2, 0, NULL, 0),
	SND_SOC_DAPM_PGA("Left Out 2", ES8323_DACPOWER, 3, 0, NULL, 0),
	SND_SOC_DAPM_PGA("Right Out 1", ES8323_DACPOWER, 4, 0, NULL, 0),
	SND_SOC_DAPM_PGA("Left Out 1", ES8323_DACPOWER, 5, 0, NULL, 0),
	SND_SOC_DAPM_PGA("LAMP", ES8323_ADCCONTROL1, 4, 0, NULL, 0),
	SND_SOC_DAPM_PGA("RAMP", ES8323_ADCCONTROL1, 0, 0, NULL, 0),

	SND_SOC_DAPM_OUTPUT("LOUT1"),
	SND_SOC_DAPM_OUTPUT("ROUT1"),
	SND_SOC_DAPM_OUTPUT("LOUT2"),
	SND_SOC_DAPM_OUTPUT("ROUT2"),
	SND_SOC_DAPM_OUTPUT("VREF"),
};

  通过上述代码,我们可以到widget和controls关联或者和寄存器的某些位关联,进而可以实现某个小器件的上下电等控制

   

kcontrols

      

     

/* Left Mixer */
static const struct snd_kcontrol_new es8323_left_mixer_controls[] = {
	SOC_DAPM_SINGLE("Left Playback Switch", ES8323_DACCONTROL17, 7, 1, 0),
	SOC_DAPM_SINGLE("Left Bypass Switch", ES8323_DACCONTROL17, 6, 1, 0),
};

/* Right Mixer */
static const struct snd_kcontrol_new es8323_right_mixer_controls[] = {
	SOC_DAPM_SINGLE("Right Playback Switch", ES8323_DACCONTROL20, 7, 1, 0),
	SOC_DAPM_SINGLE("Right Bypass Switch", ES8323_DACCONTROL20, 6, 1, 0),
};

   即对 widget的控制

    例如上面right mixer controls,

路由

      其实就是决定了一个音频的流向,source和sink均为一个widget。例如下面代码,

      LINPUT1作为source,由Line 1L 进行控制,最终流向了sink 即Left  PGA mux,也就是框图中的左侧第一个mux。

      根据下面的代码,一个路由如下:

     LINPUT1-->Left  PGA Mux-->Left ADC mux-->left ADC POWER-->LEFT ADC-->i2s OUT

static const struct snd_soc_dapm_route audio_map[] = {
	{"Left PGA Mux", "Line 1L", "LINPUT1"},
	{"Left PGA Mux", "Line 2L", "LINPUT2"},
	{"Left PGA Mux", "DifferentialL", "Differential Mux"},

	{"Right PGA Mux", "Line 1R", "RINPUT1"},
	{"Right PGA Mux", "Line 2R", "RINPUT2"},
	{"Right PGA Mux", "DifferentialR", "Differential Mux"},

	{"Differential Mux", "Line 1", "LINPUT1"},
	{"Differential Mux", "Line 1", "RINPUT1"},
	{"Differential Mux", "Line 2", "LINPUT2"},
	{"Differential Mux", "Line 2", "RINPUT2"},

	{"Left ADC Mux", "Stereo", "Right PGA Mux"},
	{"Left ADC Mux", "Stereo", "Left PGA Mux"},
	{"Left ADC Mux", "Mono (Left)", "Left PGA Mux"},

	{"Right ADC Mux", "Stereo", "Left PGA Mux"},
	{"Right ADC Mux", "Stereo", "Right PGA Mux"},
	{"Right ADC Mux", "Mono (Right)", "Right PGA Mux"},

	{"Left ADC Power", NULL, "Left ADC Mux"},
	{"Right ADC Power", NULL, "Right ADC Mux"},
	{"Left ADC", NULL, "Left ADC Power"},
	{"Right ADC", NULL, "Right ADC Power"},

	{"I2S OUT", NULL, "Left ADC"},
	{"I2S OUT", NULL, "Right ADC"},

	{"Left Line Mux", "Line 1L", "LINPUT1"},
	{"Left Line Mux", "Line 2L", "LINPUT2"},
	{"Left Line Mux", "MicL", "Left PGA Mux"},

	{"Right Line Mux", "Line 1R", "RINPUT1"},
	{"Right Line Mux", "Line 2R", "RINPUT2"},
	{"Right Line Mux", "MicR", "Right PGA Mux"},

	{"Right DAC", NULL, "I2S IN"},
	{"Left DAC", NULL, "I2S IN"},

	{"Left Mixer", "Left Playback Switch", "Left DAC"},
	{"Left Mixer", "Left Bypass Switch", "Left Line Mux"},

	{"Right Mixer", "Right Playback Switch", "Right DAC"},
	{"Right Mixer", "Right Bypass Switch", "Right Line Mux"},

	{"Left Out 1", NULL, "Left Mixer"},
	{"LOUT1", NULL, "Left Out 1"},
	{"Right Out 1", NULL, "Right Mixer"},
	{"ROUT1", NULL, "Right Out 1"},

	{"Left Out 2", NULL, "Left Mixer"},
	{"LOUT2", NULL, "Left Out 2"},
	{"Right Out 2", NULL, "Right Mixer"},
	{"ROUT2", NULL, "Right Out 2"},
};

那么中间一列的control,例如第一行代码的LINE 1L 等又是什么呢

通过上面widget, kcontrol,route的分析,我们知晓:

当需要打通一条路,需要知晓这条路上涉及的widget,这就是route的功能;

而 对这些widget的控制则需要kcontrols对寄存器的配置。

至此,codec涉及到的widget及作用我们基本了解,但是codec与machine及soc连接的widget,我们还没有分析,后续以具体machine驱动再进行分析。

amixer命令和驱动的对应关系

  通过命令amixer -c X controls  这里X表示card编号,一定注意此参数,否则查出来不对。

 然后回头再看代码中:

 通过代码与命令的输出对比,我们发现两者一致,进而就可以通过寄存器手册了解其功能。

通过命令amixer -c 2  contents 查看每个控制的具体配置值,例如如下面PGA Mux默认的输入是line 1L

numid=26,iface=MIXER,name='Left PGA Mux'
  ; type=ENUMERATED,access=rw------,values=1,items=3
  ; Item #0 'Line 1L'
  ; Item #1 'Line 2L'
  ; Item #2 'DifferentialL'
  : values=0


numid=27,iface=MIXER,name='Right PGA Mux'
  ; type=ENUMERATED,access=rw------,values=1,items=3
  ; Item #0 'Line 1R'
  ; Item #1 'Line 2R'
  ; Item #2 'DifferentialR'
  : values=0

选项和路由的配置一致

此时就可以知晓通过此两个controls可以对输入源进行控制,例如将输入改成LINE 2L。

amixer -c 2 cset numid=26,iface=MIXER,name='Left PGA Mux' 1
numid=26,iface=MIXER,name='Left PGA Mux'
  ; type=ENUMERATED,access=rw------,values=1,items=3
  ; Item #0 'Line 1L'
  ; Item #1 'Line 2L'
  ; Item #2 'DifferentialL'
  : values=1

系统下查看widget状态的命令

cat /sys/devices/platform/es8388-sound/

综述

  通过上面的驱动代码与命令的分析,可以得知:

  amixer 与驱动密切相关,amixer查询到的即为驱动提供的路由、control及widget信息。通过这些信息可以完成对音频输入输出及流向的控制。

     至此,我们对codec驱动有了比较清晰的认识,但是耳机、mic插座与codec的连接路由关系如何管理?何时对widget进行上下电管理?对于两个耳机、mic的连接器,是分别输出输入还是作为立体输出输入,这些由什么决定的?

    对于这些问题,在后续machine驱动进行介绍。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/523723.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Python socket】零基础也能轻松掌握的学习路线与参考资料

Python socket是Python程序语言中与网络编程密切相关的库之一,可以让程序员在网络世界中建立服务和客户端之间的连接。Python socket提供了一系列关键的概念和方法,让用户能够轻松地构建基于网络的程序,如基于TCP和UDP的应用程序。学习Python…

图(Graph)

Graph 图由顶点(vertex /ˈvɜːrteks/)和边(edge /edʒ/)组成的一种结构。 顶点的集合V,边的集合是E,所以图记为G (V,E) 总结: 顶点是一维数组,而边是二维数组; 假如顶点…

Pycharm无法添加Conda新建的虚拟环境

Pycharm无法添加Conda新建的虚拟环境,点击没反应,在idea.log文件中报错:CondaPythonLegacy - Can’t find python path to use, will use conda run instead 1.问题描述🔍 在PyCharm中,依次单击File>Settings>P…

Netty核心技术一--Netty介绍和应用场景

1. 学习要求 要求已经掌握了 Java 编程, 主要技术构成: Java OOP 编程、Java 多线程编程、JavaIO 编程 、Java 网络编程、常用的Java 设计模式(比如观察者模式,命令模式,职责链模式 )、常用的数据结构(比如 链表) 2 Netty的介绍…

C++: 计时器类的设计和实现

文章目录 1. 目的2. 功能列表3. 基础功能:获取耗时4. API 设计: Timer 类5. 单元测试6. API 实现 1. 目的 使用 C Class 的形式,封装原本 C语言的获取时间的函数,提供更容易使用的计时器调用。 使用 C03,原因是和先前的线程安全队…

ATT-ACK靶场渗透(一)

开启内网环境 kali攻击机ip为 192.168.88.156 主机发现、端口扫描 进行主机发现 nmap -sS 192.168.88.156/24 -Pn 192.168.88.1和192.168.88.2可能为网关之类的,不管 weblogic漏洞利用 192.168.88.182开放了80端口和7001(weblogic)端口…

超越预期:ConvNeXt技术催生YOLOv5目标检测巨变 ,实现超准确率

目录 引言一、ConvNeXt的介绍1、目标检测的重要性2、YOLOv5的介绍3、ConvNeXt原理和特点4、ConvNeXt结构 二、相关研究综述1、目标检测的基础原理和流程2、YOLOv5的特点与局限性3、ConvNeXt技术在目标检测中的应用现状 三、ConvNeXt在YOLOv5中的应用与改进1、安装PyTorch和torc…

阿里Java工程规约(来源阿里)

一、应用分层 1.开放接口层: 可直接封装 Service 接口暴露成 RPC 接口;通过 Web 封装成 http 接口;网关控制层等。 2.终端显示层: 各个端的模板渲染并执行显示层。当前主要是 velocity 渲染,JS 渲染,JSP 渲…

[golang gin框架] 33.Gin 商城项目- 微信支付操作相关功能讲解

一.微信支付准备工作 准备工作 申请条件: 个体工商户 、企业、政府及事业单位 PC网站接入支付官网,其他(app,小程序,公众号等)可参考 PC网站接入支付 需要获取内容 appid:应用 APPID(必须配置,开户邮件中可查看) MCHID&#xff1a…

Java Socket和ServerSocket 使用

在Java中,Socket和ServerSocket是用于创建网络连接的重要类。Socket类用于创建客户端套接字,而ServerSocket类用于创建服务器套接字。在本文中,我们将讨论Socket和ServerSocket的作用、使用方法以及相关代码示例。 Socket的作用 Socket是Jav…

【连续介质力学】张量的并矢和性质1

张量的代数操作 并矢 Dyadic 两个向量的张量积是一个并矢,得到一个二阶张量 u ⃗ v ⃗ u ⃗ ⨂ v ⃗ A \vec u \vec v \vec u \bigotimes \vec v A u v u ⨂v A 其中, ⨂ \bigotimes ⨂是张量乘积,任意张量可以表示成并矢的线性组合 …

戴尔 Dell XPS 13 7390电脑 Hackintosh 黑苹果efi引导文件

原文来源于黑果魏叔官网,转载需注明出处。(下载请直接百度黑果魏叔) 硬件型号驱动情况 主板戴尔 Dell XPS 13 7390 处理器Intel Core i7-10510u已驱动 内存 16 GB ( 酷兽 DDR4 3200MHz 8GB x 2 )已驱动 硬盘三星 SSD 860 EVO 250GB (250 …

【iOS】--KVC与KVO

键值编码(KVC)与键值监听(KVO) KVC(Key Value Coding)允许以字符串的形式间接操作对象的属性。 简单的KVC 最基本的KVC由NSKeyValueCoding协议提供支持,最基本的操作属性的两个方法如下 set…

利用具有局部信息的引导自注意进行息肉分割

文章目录 Using Guided Self-Attention with Local Information for Polyp Segmentation摘要本文方法PP-Guided Self-AttentionLocal-to-Global Mechanism损失函数 实验结果 Using Guided Self-Attention with Local Information for Polyp Segmentation 摘要 背景 自动准确的…

Microsoft Edge是一款现代化的浏览器,它拥有众多功能和强大的性能

随着互联网的不断发展,浏览器已经成为我们日常生活中必不可少的工具之一。作为一款现代化的浏览器,Microsoft Edge拥有许多强大的功能,为用户带来更加流畅的浏览体验。最近,Edge推出了分屏功能,这项功能可以大大提高生…

STM32------ADC

ADC 1、ADC介绍 1、1介绍 ADC即模数转换器。 例如:电信号转化成数字量。 1、2 ADC类型 并联比较型、逐次逼近型 并联比较型如下: 分压部分比较部分编码部分。 ADC分辨率:三位(上图) 优点:转换速度快…

类和对象下

文章目录 一、初始化列表1、语法:2、初始化顺序 二、static成员三、友元1、友元函数2、友元类 四、拷贝对象时的编译器优化例1、例2、例3、 一、初始化列表 1、语法: 初始化列表: 以一个冒号开始,接着是一个以逗号分隔的数据成员…

【Python PyTorch】零基础也能轻松掌握的学习路线与参考资料

文章目录 一、PyTorch的基础知识二、PyTorch数据处理三、PyTorch模型构建四、PyTorch模型训练和评估五、总结 作为当前最流行的深度学习框架之一,PyTorch已成为许多数据科学家和深度学习工程师的首选。本文将提供一条针对初学者的完整的学习路线,包括PyT…

hnust 湖南科技大学 2023 安卓 期中考试 复习资料

前言 ★:录音中提到的致谢:hwl,lqx,ly,sw重点来源:7-8班 PPT和录音内容来源:PPT知识点大多很抽象,需要联系实际代码来理解多做1-9章课后习题,编程题可以不做获取最新版本…

【AI大模型】“讯飞星火”大模型计划10月底赶超ChatGPT

文章目录 前言你使用过这种对话式AI吗?有什么看法或感受?“讯飞星火大模型将超越chatgpt?”这类型的人工智能对现在的社会有什么意义?这类型的人工智能,未来前景如何?申请体验写在最后 前言 5月6日&#xf…