ALSA声卡驱动详解(3)
mux控件与mixer控件类似,也是多个输入端和一个输出端的组合控件,与mixer控件不同的是,mux控件的多个输入端同时只能有一个被选中。因此,mux控件所对应的寄存器,通常可以设定一段连续的数值,每个不同的数值对应不同的输入端被打开,与上述的mixer控件不同,ASoc用soc_enum结构来描述mux控件的寄存器信息:
[cpp] view plaincopy
/* enumerated kcontrol */ struct soc_enum {
unsigned short reg; unsigned short reg2; unsigned char shift_l; unsigned char shift_r; unsigned int max; unsigned int mask;
const char * const *texts; const unsigned int *values; };
两个寄存器地址和位移字段:reg,reg2,shift_l,shift_r,用于描述左右声道的控制寄存器信息。字符串数组指针用于描述每个输入端对应的名字,value字段则指
6
向一个数组,该数组定义了寄存器可以选择的值,每个值对应一个输入端,如果value是一组连续的值,通常我们可以忽略values参数。下面我们先看看如何定义一个mux控件:
第一步,定义字符串和values数组,以下的例子因为values是连续的,所以不用定义:
[cpp] view plaincopy
static const char *drc_path_text[] = { \, \ };
第二步,利用ASoc提供的辅助宏定义soc_enum结构,用于描述寄存器: [cpp] view plaincopy
static const struct soc_enum drc_path =
SOC_ENUM_SINGLE(WM8993_DRC_CONTROL_1, 14, 2, drc_path_text);
第三步,利痛ASoc提供的辅助宏,定义soc_kcontrol_new结构,该结构最后用于注册该mux控件: [cpp] view plaincopy
static const struct snd_kcontrol_new wm8993_snd_controls[] = { SOC_DOUBLE_TLV(......), ......
SOC_ENUM(\, drc_path), ...... }
以上几步定义了一个叫DRC PATH的mux控件,该控件具有两个输入选择,分别是来自ADC和DAC,用寄存器WM8993_DRC_CONTROL_1控制。其中,soc_enum结构使用了辅助宏SOC_ENUM_SINGLE来定义,该宏的声明如下: [cpp] view plaincopy
#define SOC_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmax, xtexts) \\
{ .reg = xreg, .shift_l = xshift_l, .shift_r = xshift_r, \\
.max = xmax, .texts = xtexts, \\
.mask = xmax ? roundup_pow_of_two(xmax) - 1 : 0} #define SOC_ENUM_SINGLE(xreg, xshift, xmax, xtexts) \\
SOC_ENUM_DOUBLE(xreg, xshift, xshift, xmax, xtexts) 定义soc_kcontrol_new结构时使用了SOC_ENUM,列出它的定义如下: [cpp] view plaincopy
#define SOC_ENUM(xname, xenum) \\
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,\\ .info = snd_soc_info_enum_double, \\
.get = snd_soc_get_enum_double, .put = snd_soc_put_enum_double, \\
7
.private_value = (unsigned long)&xenum }
思想如此统一,依然是使用private_value字段记录soc_enum结构,不过几个回调函数变了,我们看看get回调对应的snd_soc_get_enum_double函数: [cpp] view plaincopy
int snd_soc_get_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) {
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
unsigned int val;
val = snd_soc_read(codec, e->reg); ucontrol->value.enumerated.item[0]
= (val >> e->shift_l) & e->mask; if (e->shift_l != e->shift_r)
ucontrol->value.enumerated.item[1] = (val >> e->shift_r) & e->mask;
return 0; }
通过info回调函数则可以获取某个输入端所对应的名字,其实就是从soc_enum结构的texts数组中获得: [cpp] view plaincopy
int snd_soc_info_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) {
struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; uinfo->count = e->shift_l == e->shift_r ? 1 : 2; uinfo->value.enumerated.items = e->max;
if (uinfo->value.enumerated.item > e->max - 1)
uinfo->value.enumerated.item = e->max - 1; strcpy(uinfo->value.enumerated.name,
e->texts[uinfo->value.enumerated.item]); return 0; }
以下是另外几个常用于定义mux控件的宏:
SOC_VALUE_ENUM_SINGLE 用于定义带values字段的soc_enum结构。
8
SOC_VALUE_ENUM_DOUBLE SOC_VALUE_ENUM_SINGLE的立体声版本。
SOC_VALUE_ENUM 用于定义带values字段snd_kcontrol_new结构,这个有点特别,我们还是看看它的定义: [cpp] view plaincopy
#define SOC_VALUE_ENUM(xname, xenum) \\
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,\\ .info = snd_soc_info_enum_double, \\
.get = snd_soc_get_value_enum_double, \\ .put = snd_soc_put_value_enum_double, \\ .private_value = (unsigned long)&xenum } 从定义可以看出来,回调函数被换掉了,我们看看他的get回调: [cpp] view plaincopy
int snd_soc_get_value_enum_double(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol) {
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
unsigned int reg_val, val, mux;
reg_val = snd_soc_read(codec, e->reg); val = (reg_val >> e->shift_l) & e->mask; for (mux = 0; mux < e->max; mux++) { if (val == e->values[mux]) break; }
ucontrol->value.enumerated.item[0] = mux; if (e->shift_l != e->shift_r) {
val = (reg_val >> e->shift_r) & e->mask; for (mux = 0; mux < e->max; mux++) { if (val == e->values[mux]) break; }
ucontrol->value.enumerated.item[1] = mux; …… 此处隐藏:2928字,全部文档内容请下载后查看。喜欢就下载吧 ……
相关推荐:
- [实用模板]第八章:法国“新浪潮”与“左岸派”
- [实用模板]2021年北京上半年临床医学检验技师生物
- [实用模板]SAP GUI 7.10客户端安装配置文档
- [实用模板]2001年临床执业医师资格考试综合笔试试
- [实用模板]36机场工作实用英语词汇总结
- [实用模板](一)社会保险稽核通知书
- [实用模板]安全教育主题班会材料
- [实用模板]濉溪县春季呼吸道传染病防控应急演练方
- [实用模板]长沙房地产市场周报(1.30-2.3)
- [实用模板]六年级数学上册典中点 - 图文
- [实用模板]C程序设计(红皮书)习题官方参考答案
- [实用模板]中国证监会第一届创业板发行审核委员会
- [实用模板]桥梁工程复习题
- [实用模板]2011学而思数学及答案
- [实用模板]初中病句修改专项练习
- [实用模板]监理学习知识1 - 图文
- [实用模板]小机灵杯四年级试题
- [实用模板]国贸专业毕业论文模板
- [实用模板]教育学概论考试练习题-判断题4
- [实用模板]2015届高考英语一轮复习精品资料(译林
- 00Nkmhe_市场营销学工商管理_电子商务_
- 事业单位考试法律常识
- 诚信教育实施方案
- 吉大小天鹅食品安全检测箱方案(高中低
- 房地产销售培训资料
- 高一地理必修1复习提纲
- 新概念英语第二册lesson_1_练习题
- 证券公司内部培训资料
- 小学英语时间介词专项练习
- 新世纪英语专业综合教程(第二版)第1册U
- 【新课标】浙教版最新2018年八年级数学
- 工程建设管理纲要
- 外研版 必修一Module 4 A Social Surve
- Adobe认证考试 AE复习资料
- 基于H.264AVC与AVS标准的帧内预测技术
- 《食品检验机构资质认定管理办法》(质
- ABB变频器培训课件
- (完整版)小学说明文阅读练习题及答案
- 深思洛克(SenseLock) 深思IV,深思4,深
- 弟子规全文带拼音




