HS_GPIO_HSD = 1, 

  /**< -- Headset Detection GPIO. */
   HS_GPIO_HSTD = 2,
   /**< -- Headset Type Detection GPIO. */

一、先说一下耳机的功能
线控耳机指能在耳机线上控制接入设备的耳机。比如控制远端MP3设备的开关机功能,播放和停止功能,音量大小调节功能等,拥有在耳机线上控制远端设备的这些功能都属于线控耳机。在手机上主要的应用场合是电话,音乐播放器,拍照,FM(换台)等。

Iphone上耳机方面的操作使用
1:耳机中间按键按1次:停止现在播放的音乐
2:耳机中间按键连按2次:播放下一首歌曲
3:耳机中间按键连按3次:返回上一首歌曲
4:耳机接听电话:按一下耳机中间的按键,再按一下就挂机
5:耳机拍摄照片:在开启相机功能后,直接按一下“+”键即可直接拍摄
6:耳机常按中间按键:出现siri 语音助理选项(前提是必须得开启siri功能)

另一个功能是可以做FM的天线,手机没有内置收音机所需要的天线,所以它需要耳机连接线做为天线来收集信号。听个FM还得插耳机,很不爽,至于为何不像BT,WIFI(2.4Ghz)那样内置,是由收音机 的接受频率决定的,一般频率范围较低为76Mhz-108Mhz,需要天线长度较长(耳机线很长,收音机的金属拉杆天线也很长)。

二、耳机类型

   根据耳机上pin定义不同,分二级,三级(左声道+右声道+公共地,电脑上用的,在android上图标显示没有麦克), 四级(左声道+右声道+公共地+麦克,手机一般是这个在android上图标显示有麦克)耳机。

一般都是四级耳机,四级耳机根据jack pin map不同又有两个标准:

OMTP:Open Mobile Terminal Platform  L/R/M/G(从尖端到有线端),如NOKIA
CTIA: Cellular Telephone Industries Association  L/R/G/M (从尖端到有线端),如IPHONE

可见 OMTP  和 CTIA 这两个 MIC 和GND 定义是反的
CTIA 定义 MIC 在audio jacket 最内侧

三、要实现上面的功能主机端必须具备下面两点

1)插入/移除检测

    这个一般通过中断实现,接到某个GPIO上
2) 耳机类型检测(是3级还是4极,3 pole or 4 pole)
3)按键检测(包括HOOK键的短按,长按,连续按下两次三次等)

有的耳机只有一个按键,有的有多个按键,如iphone耳机有三个按键:音量增,音量减,中键。但原理都一样,都是通过检测偏置电压的电压值来实现的。MIC+与GND中间跨接电阻与按键,当不同键按下松开,电路里头电阻值不同,使输出的分压值不同,从而通过芯片ADC采样得到的值不同,软件就由不同的ADC值范围,转换成不同的逻辑按键值。ADC一般封装在了PMIC中。有的是滑动按键控制音量的,也个和软件没有一点关系,完全是耳机自己的事情。


四、高通平台的实现


   1)硬件实现

ios 开发 怎么实现耳机录音 苹果耳机怎么录声控_iphone

      *耳机检测

上面的白线部分是检测电路,HS_DETECT_N接到GPIO,用作中断。VREG_S3为1.8v,当耳机没有插入时,  VREG_S3通过100K电阻   电感  AUDIOJACK_L  PMIC_HPH_L和2.2k电阻至地,100k电阻远远大于2.2k电阻(电感相当与0欧姆电阻,没有压降),所以HS_DETECT_N电压几乎为0;当耳机插入时,  AUDIOJACK_L 和HS_DETECT_N断开,致使  VREG_S3连接100k电阻直接到HS_DETECT_N,相当与没有负载,所以HS_DETECT_N处电压就是  VREG_S3,即1.8V。

由上面的可知是高电平触发耳机检测中断,这个软件上要相应配置。

      *耳机类型和HOOK键检测

MB_IN接到PM8029的MPP5,软件上配置成模拟输入,主机端就是通过读取此处的ADC值来转换成逻辑按键值的,包括hook,音量增,音量减按下时都会导致MB_IN处的电压不同(差别很细微,要用示波器量)

2) 在MSM7X27A上耳机驱动分两部分,MP负责耳机各种检测,主要功能都在这边,AP驱动收到按键值并报告给input子系统,两边通过RPC通信。

AMSS侧的主要驱动文件

\modem_proc\core\iodevices\hs\src\
hs_gpio.c
hs_othc.c
hs_othc_cfg_s.c

MPP5处的ADC采样值范围对应的不同逻辑按键值

static hs_othc_cfg_value_to_key_type voltage_to_key_array[] =
   {{0,   100,  HS_HEADSET_SWITCH_1_K},
    {100, 200,  HS_HEADSET_SWITCH_2_K},
    {200, 500,  HS_HEADSET_SWITCH_3_K}};

Android侧的驱动文件

>kernel/arch/arm/mach-msm/ rpc_server_handset.c 
定义的输入设备
~$ adb shell getevent
 add device 1: /dev/input/event5
   name:     "7k_handset"


五、参考

1.耳机插入检测

2.关于手机线控耳机那点事儿

3.A  Mobile Audio Jack Solution

4.QCOM Docs

80-N8218-1_C_MSM7x27A_MSM7x25A_PM8029_Headset_HSKey_Detect.pdf

80-N8123-1_A_QMSS_7x27A_SW_Driver_Customization.pdf