• 背景
  • 耳机的分类
  • 调试Qcom耳机功能时常用修改
    • (1)qcom,msm-mbhc-hphl-swh = <1>;
    • (2)qcom,msm-hs-micbias-type=”internal”;
    • (3)耳机的micbias(常用micbias2)是否有外部电容
    • (4)耳机是否支持欧美标转换
    • (5)更改micbias电压
    • (6)修改识别耳机时候的阻抗
    • (7)Lineout设备
    • (8)如果没有兼容欧标美标开关,但是想播放音乐(不能通话),可以做如下修改
    • (9)对耳机按键阻值等调控
  • 软件逻辑
    • 在哪儿识别
    • 在哪儿上报
    • 按键识别
  • 综述

背景

耳机部分也是在工作范围内,所以有必要整理,方便回顾和查找。

耳机的分类

3.5mm耳机接口分为三段式和四段式, 三段式耳机即”左右地”,四段式则带麦分为”左右地麦”(美标)和”左右麦地”(欧标)。
type c和usb耳机则另算。我这边还没有研究,暂时就不写了。

调试Qcom耳机功能时常用修改

这一部分既是为了方便回顾和查询,也可以列举debug点。
先说dtsi的位置,常见配置都在dtsi里:
kernel/msm-4.9/arch/arm64/boot/dts/qcom/qm215-audio.dtsi

/*begin mod by fuhua for task: 8668750 on 2019-12-03 task id :8668750 */qcom,msm-hac-pa = <&tlmm 127 0>;qcom,msm-hac-pa-gpio = <&cdc_hac_pa_gpio>;
/*end   mod by fuhua for task: 8668750 on 2019-12-03 task id :8668750 */qcom,msm-mclk-freq = <9600000>;qcom,msm-mbhc-hphl-swh = <1>;
/*Begin Modified by fuhua.wang for defect_id: 8751408 on 2019 02.25 */qcom,msm-mbhc-gnd-swh = <0>;
/*End   Modified by fuhua.wang for defect_id: 8751408 on 2019 02.25 */
/*begin mod by fuhua for 4-plog headset on 2019-08-30 task id :8293309 */qcom,msm-hs-micbias-type = "internal";
/*end mod by fuhua for 4-plog headset on 2019-08-30 task id :8293309 */

(1)qcom,msm-mbhc-hphl-swh=<1>;

//0是NC,1是NO
NO是指耳机的accdet脚默认上拉到1.8v,插入耳机后,accdet脚跟左声道短接到一块,不插入耳机的时候左声道和det就是断开的,电平拉低。而NC是指耳机的accdet脚默认和左声道短接到一块,为低电平,插入耳机后,accdet脚与左声道断开,accdet脚变为高电平。
seoul项目就是不接的时候断开的,也可以设置为0做实验,发现开机就有耳机图标。

(2)qcom,msm-hs-micbias-type=”internal”;

这个是设置Handset/Headset micbias有没有外接电容。
seoul原理图画的是个电阻,但是却没贴。

如果micbias电压是内部接过去的:
qcom,msm-hs-micbias-type = “internal”;
“MIC BIAS Internal2”, “Headset Mic”,
“AMIC2”, “MIC BIAS Internal2”,
如果micbias电压是外部接过去的:
qcom,msm-hs-micbias-type = “external”;
“MIC BIAS External2”, “Headset Mic”,
“AMIC2”, “MIC BIAS External2”,

但是也有针对Handset进行设置的。
如果Handset用的是外部micbias,使用如下配置:
“MIC BIAS External”,”Handset Mic”,
“AMIC1”,”MIC BIAS External”,
如果Handset用的是内部Micbias,使用如下配置:
“MIC BIAS Internal”,”Handset Mic”,
“AMIC1”,”MIC BIAS Internal”,

上述应该是说的手持模式和耳机模式,针对这一块,seoul设置是对的。

106         qcom,audio-routing =
107                 "RX_BIAS", "MCLK",
108                 "SPK_RX_BIAS", "MCLK",
109                 "INT_LDO_H", "MCLK",
110                 "RX_I2S_CLK", "MCLK",
111                 "TX_I2S_CLK", "MCLK",
112                 "MIC BIAS External", "Handset Mic",
113 /*begin mod by fuhua for 4-plog headset on 2019-08-30 task id :8293309 */
114                 "MIC BIAS Internal2", "Headset Mic",
115 /*end mod by fuhua for 4-plog headset on 2019-08-30 task id :8293309 */
116                 "MIC BIAS External", "Secondary Mic",
117                 "AMIC1", "MIC BIAS External",
118 /*begin mod by fuhua for 4-plog headset on 2019-08-30 task id :8293309 */
119                 "AMIC2", "MIC BIAS Internal2",
120 /*end mod by fuhua for 4-plog headset on 2019-08-30 task id :8293309 */
121                 "AMIC3", "MIC BIAS External",
122                 "ADC1_IN", "ADC1_OUT",
123                 "ADC2_IN", "ADC2_OUT",
124                 "ADC3_IN", "ADC3_OUT",
125                 "PDM_IN_RX1", "PDM_OUT_RX1",
126                 "PDM_IN_RX2", "PDM_OUT_RX2",
127                 "PDM_IN_RX3", "PDM_OUT_RX3";

(3)耳机的micbias(常用micbias2)是否有外部电容

如果有,需添加,而seoul是没有的
qcom,msm-micbias2-ext-cap
针对micbias1也可以检查是否连有外部电容,seoul是有的。
qcom,msm-micbias1-ext-cap;

(4)耳机是否支持欧美标转换

欧标耳机绝缘环是白色的,美标一般为黑色。
如果要支持转换,一般硬件要额外添加开关。
另外要注意如下pinctrl的GPIO口。

 
cross-conn-det {
qcom,pins = <&gp 97>;
qcom,num-grp-pins = <1>;
qcom,pin-func = <0>;
label = "cross-conn-det-sw";cross_conn_det_act: lines_on {drive-strength = <8>;output-low;bias-pull-down;};cross_conn_det_sus: lines_off {drive-strength = <2>;bias-disable;};
};

如果不支持,最好删除对pinctrl的引用。

pinctrl-names = "cdc_lines_act",
"cdc_lines_sus",
//"cross_conn_det_act",
//"cross_conn_det_sus",
"vdd_spkdrv_act",
"vdd_spkdrv_sus";
pinctrl-0 = <&cdc_pdm_lines_act &vdd_spkdrv_act>;
pinctrl-1 = <&cdc_pdm_lines_sus &vdd_spkdrv_sus>;
// pinctrl-2 = <&cross_conn_det_act>;
// pinctrl-3 = <&cross_conn_det_sus>;
// qcom,cdc-us-euro-gpios = <&msm_gpio 97 0>;

(5)更改micbias电压

如苹果耳机,它的mic的工作电压是大于1.8v,所以为了能正常使用苹果耳机,需要增加micbias电压。
qcom,cdc-micbias-cfilt-mv = <2700>;
seoul项目上没有这个属性,但是代码中有去读的代码。

或者更改代码: kernel/sound/soc/codecs/msm8x16-wcd.c #define MICBIAS_DEFAULT_VAL 2700000
seoul项目上路径是: vendor/qcom/opensource/audio-kernel/asoc/codecs/sdm660_cdc/msm-analog-cdc.c

(6)修改识别耳机时候的阻抗

kernel/sound/soc/codecs/wcd-mbhc-v2.c #define HS_VREF_MIN_VAL 1400
1.4v,最大只能识别7700欧阻抗的耳机, 这个阻抗指的是mic对地的阻抗,耳机的后两节之间的阻抗
1.5v,最大能识别11k
1.6v,最大能识别17.6k
1.7v,最大能识别37.4k
seoul项目是在vendor/qcom/opensource/audio-kernel/asoc/codecs/wcd-mbhc-v2.h这个文件里面。

(7)Lineout设备

Qcom平台会上报SND_JACK_LINEOUR设备,但是Android层是不支持LINEOUT设备的,不会对事件做出任何响应,如果非要支持,那么就需要做如下修改:
kernel/sound/soc/msm/msm8x16.c .linein_th = 5000,改为 .linein_th = 0,

seoul项目对应如下修改位置:
/vendor/qcom/opensource/audio-kernel/asoc/msm8952.c .linein_th = 5000,

(8)如果没有兼容欧标美标开关,但是想播放音乐(不能通话),可以做如下修改

595  static void wcd_correct_swch_plug(struct work_struct *work)
596  {......745             if ((pt_gnd_mic_swap_cnt == mbhc->swap_thr) &&
746                 (plug_type == MBHC_PLUG_TYPE_GND_MIC_SWAP)) {
747                 /*
748                  * if switch is toggled, check again,
749                  * otherwise report unsupported plug
750                  */
+++                  plug_type = MBHC_PLUG_TYPE_HEADPHONE;
751                 if (mbhc->mbhc_cfg->swap_gnd_mic &&
752                     mbhc->mbhc_cfg->swap_gnd_mic(codec,
753                     true)) {
754                     pr_debug("%s: US_EU gpio present,flip switch\n"
755                         , __func__);
756                     continue;
757                 }
758             }

(9)对耳机按键阻值等调控

耳机上报的键值定义(和(7)linein_th定义在一个文件中的):

88      .key_code[0] = KEY_MEDIA,
89      .key_code[1] = KEY_VOICECOMMAND,
90      .key_code[2] = KEY_VOLUMEUP,
91      .key_code[3] = KEY_VOLUMEDOWN,
92      .key_code[4] = 0,
93      .key_code[5] = 0,
94      .key_code[6] = 0,
95      .key_code[7] = 0,

#define WCD_MBHC_DEF_BUTTONS 8
seoul项目耳机按键的数量定义在vendor/qcom/opensource/audio-kernel/asoc/codecs/wcd-mbhc-v2.h这个文件里面。
耳机按键的阈值定义在:static void *def_msm8x16_wcd_mbhc_cal(void)
seoul项目则是定义在vendor/qcom/opensource/audio-kernel/asoc/msm8952.c目录,static void *def_msm8952_wcd_mbhc_cal(void)函数当中。

1588    /*
1589     * In SW we are maintaining two sets of threshold register
1590     * one for current source and another for Micbias.
1591     * all btn_low corresponds to threshold for current source
1592     * all bt_high corresponds to threshold for Micbias
1593     * Below thresholds are based on following resistances
1594     * 0-70    == Button 0
1595     * 110-180 == Button 1
1596     * 210-290 == Button 2
1597     * 360-680 == Button 3
1598     */
1599    btn_low[0] = 75;
1600    btn_high[0] = 75;
1601  /*Begin Modified by fuhua.wang for defect_id: 8697471 on 2019 12.19 */
1602    btn_low[1] = 120;
1603    btn_high[1] = 120;
1604  /*End   Modified by fuhua.wang for defect_id: 8697471 on 2019 12.19 */
1605    btn_low[2] = 225;
1606    btn_high[2] = 225;
1607    btn_low[3] = 450;
1608    btn_high[3] = 450;
1609    btn_low[4] = 500;
1610    btn_high[4] = 500;
1611
1612    return msm8952_wcd_cal;

如果想调试按键的阈值:
分别配置MBHC为CS(Current Source)和MB(MIC BIAS)模式:
CS mode : 0x144 = 0x00, 0x151 = 0xB0
MB mode : 0x144 = 0x80, 0x151 = 0x80
adb root
cd sys/kernel/debug/soc//msm8x16_wcd_codec/
echo “” > codec_reg
类如: echo “0x121 0xA0” > codec_reg
按下耳机按键,分别测量两个模式下的耳机mic上的电压值,把测量的值分别填入高通提供的表格,或者按照80-NK808-15的Table3-3和Table3-4计算出最后的阀值。

以上信息可以参考其他的blog,但是我认为写得有点啰嗦。

软件逻辑

识别,按键,上报等关键细节
接下来都以Seoul项目为模板
目录位置:vendor/qcom/opensource/audio-kernel/asoc/codecs
耳机操作主要是带MBHC(Multibutton headset control)字样的文件。

在哪儿识别

vendor/qcom/opensource/audio-kernel/asoc/codecs/wcd-mbhc-v2.c
wcd_mbhc_mech_plug_detect_irq这个函数作为入口,其中的wcd_mbhc_swch_irq_handler作为实现。
根据mbhc->current_plugdetection_type判断耳机当前状态。
以插入耳机为例,正常流程则会进入到调用mbhc->mbhc_fn->wcd_mbhc_detect_plug_type(mbhc);函数,到wcd-mbhc-adc.cwcd_mbhc_adc_detect_plug_type函数中。

/* called under codec_resource_lock acquisition */
static void wcd_mbhc_adc_detect_plug_type(struct wcd_mbhc *mbhc)
{struct snd_soc_codec *codec = mbhc->codec;pr_debug("%s: enter\n", __func__);WCD_MBHC_RSC_ASSERT_LOCKED(mbhc);if (mbhc->mbhc_cb->hph_pull_down_ctrl)mbhc->mbhc_cb->hph_pull_down_ctrl(codec, false);WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_DETECTION_DONE, 0);if (mbhc->mbhc_cb->mbhc_micbias_control) {mbhc->mbhc_cb->mbhc_micbias_control(codec, MIC_BIAS_2,MICB_ENABLE);} else {pr_err("%s: Mic Bias is not enabled\n", __func__);return;}/* Re-initialize button press completion object */reinit_completion(&mbhc->btn_press_compl);wcd_schedule_hs_detect_plug(mbhc, &mbhc->correct_plug_swch);pr_debug("%s: leave\n", __func__);
}

正常情况下就能走到wcd_schedule_hs_detect_plug(mbhc, &mbhc->correct_plug_swch);开始执行wcd_correct_swch_plug。这个函数就是识别设备的主要逻辑了,详细可以看源码。

在哪儿上报

上述的wcd_correct_swch_plug函数就是上报之前的临门一脚。
其中可以看到有多次检测是否欧美标转换,

static void wcd_correct_swch_plug(struct work_struct *work)
{......do {cross_conn = wcd_check_cross_conn(mbhc);try++;} while (try < mbhc->swap_thr);if (cross_conn > 0) {plug_type = MBHC_PLUG_TYPE_GND_MIC_SWAP;pr_debug("%s: cross connection found, Plug type %d\n",__func__, plug_type);goto correct_plug_type;}//如果设置了交叉检测,即欧美标转换,那么则进入继续确认的步骤,否则直接通过`wcd_mbhc_find_plug_and_report`上报耳机type了。  ....../** Report plug type if it is either headset or headphone* else start the 3 sec loop*/if ((plug_type == MBHC_PLUG_TYPE_HEADSET ||plug_type == MBHC_PLUG_TYPE_HEADPHONE) &&(!wcd_swch_level_remove(mbhc))) {WCD_MBHC_RSC_LOCK(mbhc);wcd_mbhc_find_plug_and_report(mbhc, plug_type);//直接通过`wcd_mbhc_find_plug_and_report`上报耳机typeWCD_MBHC_RSC_UNLOCK(mbhc);}......//进入继续确认的步
correct_plug_type:timeout = jiffies + msecs_to_jiffies(HS_DETECT_PLUG_TIME_MS);while (!time_after(jiffies, timeout)) {

继续确认主要是针对欧美标转换设置的,为了兼容更多的耳机,即使硬件没有转换开关,多半还是选择识别成三段式耳机,不过耳机状态基本都给到了wcd_mbhc_find_plug_and_report函数接口,通过它给wcd_mbhc_report_plug函数做逻辑判断,然后上报,上报类型为SND_JACK_UNSUPPORTED等。

//wcd-mbhc-v2.c
void wcd_mbhc_report_plug(struct wcd_mbhc *mbhc, int insertion,enum snd_jack_types jack_type)
{......else{jack_type = SND_JACK_LINEOUT;mbhc->force_linein = true;mbhc->current_plug = MBHC_PLUG_TYPE_HIGH_HPH;if (mbhc->hph_status) {mbhc->hph_status &= ~(SND_JACK_HEADSET |SND_JACK_LINEOUT |SND_JACK_UNSUPPORTED);wcd_mbhc_jack_report(mbhc,&mbhc->headset_jack,mbhc->hph_status,WCD_MBHC_JACK_MASK);}

按键识别

中断的注册是在init函数中的wcd_mbhc_btn_press_handler

int wcd_mbhc_init(struct wcd_mbhc *mbhc, struct snd_soc_codec *codec,const struct wcd_mbhc_cb *mbhc_cb,const struct wcd_mbhc_intr *mbhc_cdc_intr_ids,struct wcd_mbhc_register *wcd_mbhc_regs,bool impedance_det_en)
{......ret = mbhc->mbhc_cb->request_irq(codec,mbhc->intr_ids->mbhc_btn_press_intr,wcd_mbhc_btn_press_handler,"Button Press detect", mbhc);

进入static irqreturn_t wcd_mbhc_btn_press_handler(int irq, void *data)函数之前,中断已经触发了,其中的

mbhc->is_btn_press = true;
msec_val = jiffies_to_msecs(jiffies - mbhc->jiffies_atreport);....../* If switch interrupt already kicked in, ignore button press */
if (mbhc->in_swch_irq_handler) {pr_debug("%s: Swtich level changed, ignore button press\n",__func__);goto done;
}
mask = wcd_mbhc_get_button_mask(mbhc);
if (mask == SND_JACK_BTN_0)mbhc->btn_press_intr = true;//Begin-modify-by-fuhua.wang-for-task 8384912 on 20190926//if (mbhc->current_plug != MBHC_PLUG_TYPE_HEADSET) {if (mbhc->current_plug != MBHC_PLUG_TYPE_HEADSET && !mbhc->is_selfie_stick_insert) { //End-add-by-fuhua.wang-for-task 8384912 on 20190926pr_err("%s: Plug isn't headset, ignore button press\n",__func__);goto done;
}

作为开始处理按键的标志。
mask = wcd_mbhc_get_button_mask(mbhc);则是哪个按键的标志。深究可以发现是调用msm-analog-cdc.c中的msm_anlg_cdc_mbhc_map_btn_code_to_num函数,其中的snd_soc_read则是读取codec的寄存器了,这个接口是kernel/msm-4.9/sound/soc/soc-io.c中定义。

当放开按键的时候,则会调用wcd_mbhc_release_handler上报jack。

static irqreturn_t wcd_mbhc_release_handler(int irq, void *data)
{......wcd_mbhc_jack_report(mbhc, &mbhc->button_jack,0, mbhc->buttons_pressed);} else {if (mbhc->in_swch_irq_handler) {pr_debug("%s: Switch irq kicked in, ignore\n",__func__);} else {pr_debug("%s: Reporting btn press\n",__func__);wcd_mbhc_jack_report(mbhc,&mbhc->button_jack,mbhc->buttons_pressed,mbhc->buttons_pressed);pr_debug("%s: Reporting btn release\n",__func__);wcd_mbhc_jack_report(mbhc,&mbhc->button_jack,0, mbhc->buttons_pressed);

短按都在这里了,长按则会进入wcd_btn_lpress_fn:

static void wcd_btn_lpress_fn(struct work_struct *work)
{struct delayed_work *dwork;struct wcd_mbhc *mbhc;s16 btn_result = 0;pr_debug("%s: Enter\n", __func__);dwork = to_delayed_work(work);mbhc = container_of(dwork, struct wcd_mbhc, mbhc_btn_dwork);WCD_MBHC_REG_READ(WCD_MBHC_BTN_RESULT, btn_result);if (mbhc->current_plug == MBHC_PLUG_TYPE_HEADSET) {pr_debug("%s: Reporting long button press event, btn_result: %d\n",__func__, btn_result);wcd_mbhc_jack_report(mbhc, &mbhc->button_jack,mbhc->buttons_pressed, mbhc->buttons_pressed);}pr_debug("%s: leave\n", __func__);mbhc->mbhc_cb->lock_sleep(mbhc, false);
}

综述

如果只是为了应付项目里常见修改,文章开头列举的足矣。

但有可能会遇到更难的情况,或者更棘手的需求,或者需要创新,这个时候就需要深入了解软件接口和框架了,而且具体问题具体分析,本文仅仅针对了重要的接口,详细问题,比如增加自拍杆等重新定义一个特征按键等,需要另起分析,否则篇幅过长,不利于把握。

Android - Audio - Qcom平台 - QM215耳机常见修改和粗略识别流程相关推荐

  1. Android - Audio - Qcom平台 - hac器件bring up

    背景 正文 助听器构造 使用方式 HAC部分硬件原理图 硬件调试需求 软件平台及框架 a:mixer_path.xml中添加hac path b:alsa用户空间,tinyalsa中注册HAC控件 c ...

  2. Qcom平台 Camera 之常见错误和问题

    本文主要记载了一些在调试过程中遇到的错误和问题,及相关的设置.log.解决方法等.如有错误,请交流指正. 目录 调试 帧冻结错误 调试 相机 App 闪退错误 调试 cam banding 现象 调试 ...

  3. 那些年踩过的坑-之《Android Q-高通平台UAC(USB Audio Class)调试记录》

    uac分为UAC1.0和UAC2.0,由于UAC2.0,在windows上兼容性不好,在产品中,会带来各种坑,所以选择UAC1.0 平台:高通 SDA660,android Q,kernel4.4 一 ...

  4. Android Audio - 支持多应用同时录音_Android8.1修改方法

    支持多应用同时录音_Android8.1修改方法 修改方法 与之相关 修改方法 源码路径: sdk\frameworks\av\services\audiopolicy\managerdefault\ ...

  5. Android Audio和耳机,蓝牙耳机等音频外设

    文章目录 Android Audio和耳机,蓝牙耳机等音频外设 蓝牙连接处理 广播接收 AudioManager接口 Listener监听 蓝牙耳机和AudioService的交互 蓝牙的状态 A2D ...

  6. android camera2 qcom,Qcom平台 Camera的一些知识点 之MCLK

    前言 MCLK 是平台 baseband 提供给 cam sensor的正常工作的频率, Qcom 平台一般未24MHz,由其他时钟源分频而来,实测在23.8MHz左右. 在打开相机的时候,才可以测到 ...

  7. Android 8.1 中Systemui中的常见修改(六)NavigationBar加载流程

    本文主要分为两个部分 一.NavigationBar的加载流程 二.Android P上如何去除NavigationBar 一 NavigationBar的加载流程 NavigationBar就是我们 ...

  8. Android audio音频流数据异常问题分析

    一.背景 在 Android 系统的开发过程当中,音频异常问题通常有如下几类,无声,调节不了声音,爆音,声音卡顿,声音效果异常(忽大忽小,低音缺失等)等.尤其声音效果这部分问题通常从日志上信息量较少, ...

  9. Android 4.0 平台特性

    Android 4.0 平台特性 API等级:14  Android4.0 是一次重要的平台发布版,为用户和应用程序开发者增加了大量的新特性.在下面我们将讨论的所有新特性和API中,因为它将 Andr ...

最新文章

  1. Swift 中使用 SQLite——批量更新(事务处理)
  2. Arbitrage--POJ 2240
  3. oracle 优化逻辑读过高,详述逻辑读与arraysize的关系
  4. SQL Sever 基本命令案例
  5. c语言中的所有关键字,C语言中的32个关键字
  6. 基于顺序存储结构的图书信息表的图书去重(C++)
  7. 滴滴否认柳青计划卸任:目前正积极全面配合网络安全审查
  8. mysql 数据库的安装与配置 有关msi文件start service 停滞不前的问题及其解决办法
  9. ctf是用Windows还是Linux,CTF中zip总结
  10. c语言第三章重点知识点总结,c语言重点知识点总结
  11. RGB,CMYK,HSB,LAB颜色空间定义
  12. 控制器分析-绘制伯德图
  13. MVX-Net论文解读
  14. TI 927 928 947 948 940串行器解串器系列
  15. JT/T808消息体转义
  16. 【干货】长达4万字的Java知识点!
  17. C#WinForm二维码编码解码器
  18. java--两个巨大素数(质数)的乘积
  19. eNSP构建企业私有网络
  20. 一本图书的信息包括:图书编号(BookNo),书名(BookName),总册数(Total),借出数(Lend),价格(Value),利用结构体实现以下要求:

热门文章

  1. ERP库存管理 金蝶
  2. Android L 拷贝文件到U盘异常问题
  3. 文档安全产品---颐东“英赛虎”的渠道拓展之路
  4. 相对未知的协议将 Defi 中的 TVL 推高至 2000 亿美元以上
  5. MATLAB代码:综合能源系统优化模型概述及其鲁棒优化
  6. Linux 分区方案
  7. Soure Insight 创建Uboot工程
  8. 阿里云专有云——安全可控由内而生
  9. PMcenter集中监控平台丨多台精密空调集中监控方案
  10. 2022上海电动物流车|快递物流展浅谈顺丰、三通一达、京东等财报里“黑科技”