ALSA 驱动配置外部HP MIC SPK

程序总体结构

以sound/soc/pxa/corgi.c为例来分析

  • 为了描述声卡,定义snd_soc_card实例,填充dai_link成员。
  • 为了能在ALSA上层控制SPK,HP,MIC的开启关闭,定义kcontrol实例。
  • 为了能让ALSA自动控制SPK,HP,MIC的功耗,定义widget,route实例。
  • 在snd_soc_card--dai_link--init里,注册上面声明的kcontrol,widget,route实例。

下面以SPK的kcontrol,widget,route为例,分析三种数据结构的定义

kcontrol的实现

定义kcontrol数组,提供向上的参数和向下的实际控制函数 。

  • 向上的参数,用于上层amixer程序设置控件为不同的功能。
  • 向下的实际控制函数,用于底层驱动程序控制HP MIC SPK的开关。
static const char *jack_function[] = {"Headphone", "Mic", "Line", "Headset", "Off"};
static const char *spk_function[] = {"On", "Off"};
static const struct soc_enum corgi_enum[] = {
    SOC_ENUM_SINGLE_EXT(5, jack_function),//控件参数1-4
    SOC_ENUM_SINGLE_EXT(2, spk_function),//控件参数0-1
};
static const struct snd_kcontrol_new wm8731_corgi_controls[] = {
    SOC_ENUM_EXT("Jack Function", corgi_enum[0], corgi_get_jack,
        corgi_set_jack),//get,set分别读取和设置硬件工作模式
    SOC_ENUM_EXT("Speaker Function", corgi_enum[1], corgi_get_spk,
        corgi_set_spk),
};

get,set函数的实现

static int corgi_get_spk(struct snd_kcontrol *kcontrol,
    struct snd_ctl_elem_value *ucontrol)
{
    ucontrol->value.integer.value[0] = corgi_spk_func;  //全局变量为0-1表示ON OFF
    return 0;
}

static int corgi_set_spk(struct snd_kcontrol *kcontrol,
    struct snd_ctl_elem_value *ucontrol)
{
    struct snd_soc_codec *codec =  snd_kcontrol_chip(kcontrol);

    if (corgi_spk_func == ucontrol->value.integer.value[0])
        return 0;

    corgi_spk_func = ucontrol->value.integer.value[0];//保存上层设置的参数
    corgi_ext_control(codec);//设置SPK为ON OFF模式
    return 1;
}
//corgi_ext_control函数的实现
static void corgi_ext_control(struct snd_soc_codec *codec)
{
    if (corgi_spk_func == CORGI_SPK_ON)
        snd_soc_dapm_enable_pin(dapm, "Ext Spk");  
        //通过enable widget,开启电源,widget的实现在后面描述
    else
        snd_soc_dapm_disable_pin(dapm, "Ext Spk");//通过disable widget,关闭电源

    /* signal a DAPM event */
    snd_soc_dapm_sync(dapm);
}

snd_soc_card->dai_link->init里,通过snd_soc_add_controls注册control。

widget的实现

//定义widget
/* corgi machine dapm widgets */
static const struct snd_soc_dapm_widget wm8731_dapm_widgets[] = {
SND_SOC_DAPM_HP("Headphone Jack", NULL),
SND_SOC_DAPM_MIC("Mic Jack", corgi_mic_event),
SND_SOC_DAPM_SPK("Ext Spk", corgi_amp_event),//定义widget名字,设置电源控制接口
};
//电源控制接口的实现
static int corgi_amp_event(struct snd_soc_dapm_widget *w,
    struct snd_kcontrol *k, int event)
{
    //通过GPIO开关SPK的前置放大器
    gpio_set_value(CORGI_GPIO_APM_ON, SND_SOC_DAPM_EVENT_ON(event));
    return 0;
}

snd_soc_card->dai_link->init里,通过snd_soc_dapm_new_controls注册widget。

route的实现

//定义route
/* Corgi machine audio map (connections to the codec pins) */
static const struct snd_soc_dapm_route audio_map[] = {
    /* speaker connected to LOUT, ROUT */
    {"Ext Spk", NULL, "ROUT"},//设置SPK直连codec的ROUT和LOUT
    {"Ext Spk", NULL, "LOUT"},
};

snd_soc_card->dai_link->init里,通过snd_soc_dapm_add_routes注册route。

从datesheet上,可以看到ROUT和LOUT是用来外接SPK的。


image.png

从codec驱动里,可以看到ROUT,LOUT的widget定义。

static const struct snd_soc_dapm_widget wm8731_dapm_widgets[] = {
SND_SOC_DAPM_OUTPUT("LOUT"),
SND_SOC_DAPM_OUTPUT("LHPOUT"),
SND_SOC_DAPM_OUTPUT("ROUT"),
};

简书文章上没有添加附件选项,将machine驱动,codec驱动和手册添加到了链接:
http://download.csdn.net/download/a903265446/10235150
一般产品开发,codec驱动和platform驱动由芯片厂商提供,只需要开发machine驱动。

本文由头条号“嵌入式FM106点1”发布,各种原创技术干货,欢迎关注。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,026评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,655评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,726评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,204评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,558评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,731评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,944评论 2 314
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,698评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,438评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,633评论 2 247
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,125评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,444评论 3 255
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,137评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,103评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,888评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,772评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,669评论 2 271

推荐阅读更多精彩内容

  • [安装手册] HP ProBook/EliteBook/Zbook using Clover UEFI hotpa...
    王大发阅读 8,989评论 2 12
  • 一.声音参数基本概念: 声音是连续模拟量,计算机将它离散化之后用数字表示,就有了以下几个名词术语。 样本长度(sa...
    cs1001阅读 2,593评论 0 2
  • 注:该方法经测试支持12、13、14、15系统,但每次升级系统都需要下载最新的AppleALC-master进行重...
    LF落风阅读 110,298评论 64 62
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,102评论 18 139
  • 以下正文均引用自网易云音乐评论与知乎答主回答,如有侵权,联系立删。 花了很多时间在网易云与知乎,游手好闲,不学无术...
    剪地人阅读 853评论 0 2