音频之耳机(Exynos7872)

本文介绍了Exynos7872平台中耳机接口的种类和耳机检测流程,包括四种类型的耳机插口构造及可能引发的误识别问题。通过分析驱动代码,展示了耳机类型和按键检测的实现,以及从设备树中获取codec属性值的过程。在遇到问题时,强调了分析问题、定位问题和解决问题的步骤与心态的重要性。
摘要由CSDN通过智能技术生成

(本文仅用于本人学习记录,仅供参考)
一、耳机基本认识

引用http://www.cnblogs.com/Peter-Chen/p/3999212.html(稍作修改)
主要有两种耳机类型,从下图可以看到,左边的耳机接口结构有左声道、右声道、接地端和mic端,下面我们称该类型耳机为四环耳机;右边的耳机接口结构有左声道、右声道、接地端,不带mic接口,我们称之为三环耳机,区别就在于带不带麦克风。
这里写图片描述
与耳机对应,一般常见的耳机插口都是由5PIN or 6PIN组成,其中PIN脚分别作为HP_OUTL(左声道输出)、HP_OUTR(右声道输出)、HP_DET#(耳机检测)、GROUND(地) & MIC(麦克风)使用。
驱动中耳机检测的一般流程:
HP_DET#信号由High->Low,触发IRQ到SOC,进入中断处理函数(即耳机类型检测);先是去检测耳机的类型,确定耳机是三环还是四环耳机,将耳机状态上报给系统后,再去检测按键状态,当检测到按键状态有变化,通过输入子系统上报事件,然后进行相对应的按键功能处理。
  虽然耳机插口仅由5~6PIN组成,但不同的厂商会将其设计成各种各样。耳机接口的不同构造会对应着不同现象。以下是在网上搜集的一些接口类型,仅供参考。
  
类型一:
这里写图片描述
该耳机插口构造是HP_DET#和HPOUTL处于最前端,并且在同一位置,这样的设计是只有当耳机全部插入的时候,才能触发HP_DET#信号。由耳机检测的流程可知,该构造可以很精确的确定耳机是三环还是四环耳机。并且不管快拔 or 慢拔耳机,都能第一时间触发HP_DET#信号。

类型二:
这里写图片描述
这样的构造可能会出现当4环耳机刚拔出1环左右长度时,在这种情况下,6个PIN的状态可能如下:HP_OUTL处于float状态;HP_DET# & HS_OUTR处于第一环;AGND处于第二环;MIC2P_HP处于第三环,恰好是耳机的“-G-”,使得MIC2P_HP引脚的电压值为0.0V。由于HP_DET#依旧处于Pull Low状态,这样系统认为4环耳机仍然插入,而此时MIC2P_HP引脚因接地,导致其引脚电压值一直为0.0V,这与插入4环耳机,长按Butten的效果是一样的。

类型三:
这里写图片描述
类型三耳机插口构造是将HP_DET# & AGND引脚接到同一位置,这样当耳机插入2节左右长度时,系统就可以识别到有耳机插入。使用Type3 Jack除了会出现Type2 Jack问题外,还会出现当慢慢斜着插入3环耳机时,系统会认为是4环耳机直接上报给上层。这个问题可以通过机构的设计解决“斜插”的问题,从而消除3环误认为4环的现象。

类型四:
这里写图片描述
该构造与类型一的构造和效果差不多。

二、主要代码函数分析
1、cod3034x芯片的probe回调函数,进行芯片的初始化,用工作队列创建耳机类型和按键的状态检测函数。以下贴出的是部分代码

/*Codec芯片的probe函数*/
cod3034x_codec_probe(struct snd_soc_codec *codec)
    |-- snd_soc_codec_get_drvdata(codec);
    |-- devm_regulator_get(codec->dev, "vdd_ldo27");
    |-- INIT_WORK(&cod3034x->buttons_work, cod3034x_buttons_work);//添加按键检测的工作队列
        |-- cod3034x_buttons_work//耳机按键检测函数
    |-- create_singlethread_workqueue("buttons_wq");
    |-- INIT_WORK(&cod3034x->jack_det_work, cod3034x_jack_det_work);//添加耳机检测的工作队列
        |-- cod3034x_jack_det_work//耳机检测函数
    |-- create_singlethread_workqueue("jack_det_wq");
    |-- cod3034x_adc_start(cod3034x);
    |-- cod3034x_i2c_parse_dt(cod3034x);//获取dts中的设备属性值
    |-- cod3034x_register_notifier(&codec_notifier, cod3034x);
    |-- set_codec_notifier_flag();
    |-- cod3034x_codec_initialize(codec);
    |-- cod3034x_jack_mic_register(codec);
    |-- cod3034x_enable(codec->dev);

2、cod3034x_jack_det_work函数用于检测插入耳机的类型,确定插入的是三段耳机还是四段耳机,三段与四段的区别在于耳机是否带麦克风。

static void cod3034x_jack_det_work(struct work_struct *work)
{
    dev_dbg(cod3034x->dev, "%s(%d) jackdet: %d\n",
            __func__, __LINE__, jackdet->jack_det);
    mutex_lock(&cod3034x->jackdet_lock);

    if (jackdet->jack_det == true) {
        /* set delay for read correct adc value */
        msleep(cod3034x->mic_det_delay);

        /* read adc for mic detect */
        adc = cod3034x_adc_get_value(cod3034x);//获取耳机接口的adc值
        dev_dbg(cod3034x->dev, "%s mic det adc  %d, mic_det_delay: %d\n",
         __func__, adc, cod3034x->mic_det_delay);

        if (adc > cod3034x->mic_adc_range)//判断是否检测到了mic
            jackdet->mic_det = true;
        else
            jackdet->mic_det 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值