第十五部分 声卡控制接口
前面第一篇中讲到了每注册一个声卡都会创建注册一个对应的声卡控制设备,并给出了其操作函数集snd_ctl_f_ops,
在"amixer,aplay,arecord的使用"一文中提及了amixer如何设置获取声卡的控制选项
接着在第二篇中讲到Asoc声卡驱动编写的步骤,步骤中没牵扯到控制设备的控制选项,这里要补充第5个步骤
第5个步骤就是在设备驱动中要调用snd_soc_add_controls函数添加相应的控制选项,也就是添加一系列的snd_kcontrol_new对象
1.snd_kcontrol_new结构体
struct snd_kcontrol_new {
snd_ctl_elem_iface_t iface; /* 接口号 */
unsigned int device; /* 设备号 */
unsigned int subdevice; /* 子设备号 */
unsigned char *name; /* item名 */
unsigned int index; /* item索引号 */
unsigned int access; /* 通道权限(读/写/执行) */
unsigned int count; /* count of same elements */
snd_kcontrol_info_t *info;
snd_kcontrol_get_t *get;
snd_kcontrol_put_t *put;
union {
snd_kcontrol_tlv_rw_t *c;
const unsigned int *p;
} tlv;
unsigned long private_value;
};
3.snd_soc_add_controls函数原型
int snd_soc_add_controls(struct snd_soc_codec *codec,const struct snd_kcontrol_new *controls, int num_controls)
{
struct snd_card *card = codec->card->snd_card; //获取声卡
int err, i;
for (i = 0; i < num_controls; i++) { //添加num_controls个控制元素
const struct snd_kcontrol_new *control = &controls[i]; //获取snd_kcontrol_new对象
err = snd_ctl_add(card, snd_soc_cnew(control, codec, NULL)); //添加1个控制元素
if (err < 0) {
dev_err(codec->dev, "%s: Failed to add %s: %d\n",codec->name, control->name, err);
return err;
}
}
return 0;
}
EXPORT_SYMBOL_GPL(snd_soc_add_controls);
调用snd_ctl_add函数之前会先调用snd_soc_cnew创建一个新的snd_kcontrol结构体对象
4.snd_kcontrol结构体
struct snd_kcontrol {
struct list_head list; /* list of controls */
struct snd_ctl_elem_id id; //控制元素id
unsigned int count; /* count of same elements */
snd_kcontrol_info_t *info;
snd_kcontrol_get_t *get;
snd_kcontrol_put_t *put;
union {
snd_k