MTK调试-耳机驱动
1、耳机检测简介
1.1 耳机检测的两种方式
1)Accdet only:此方式是让耳机micbias 常开下,依靠耳机内部中断来检测耳机处于的状态的。但此方式会带来耳机插入瞬间有pop杂音的出现。
2)Accdet+EINT方式:此方式在耳机为插入时,micbias是被disable的。利用中断EINT来打开micbias,从而达到省功耗和减小杂音的效果的。待插入后,耳机检测走的路线还是accdet内部中断。
目前MTK6589和MTK6572检测耳机都是使用的方式是EINT+ACCDET。
1.2 耳机检测的原理
ACCDET内部有两个比较器,会根据传入的电压判断并产生中断。ACCDET的输入电压即耳机 MIC PIN的电压,内部比较器的输出分别对应A/B两个寄存器。ACCDET内部两个比较器的Vref分别是1.77V和0.4V(硬件决定的,不能修改),所以,对应的电压有3个范围:
1)1.77V-1.9V: 未插入耳机的状态(AB=B11)
2)0.4V-1.77V: 插入4段式(有Mic)耳机时的状态(AB = B01)
3)0-0.4V : 插入3段式耳机时的状态,或者4段式按键按下时的状态(AB = B00)
耳机的状态会保存到ACCDET的寄存器中,当电压在任意2个范围间切换时,状态发生变化,ACCDET产生中断,中断处理中读取状态寄存器的值,并根据状态的变化做相应的处理.
2、代码的主要文件
驱动接口文件:
mediatek/platform/mt6577/kernel/drivers/accdet/accdet.c
初始化函数 accdet_probe()中添加新的按键使用keybit
__set_bit(EV_KEY,kpd_accdet_dev->evbit);
__set_bit(KEY_CALL,kpd_accdet_dev->keybit);
__set_bit(KEY_ENDCALL,kpd_accdet_dev->keybit);
__set_bit(KEY_PLAYPAUSE,kpd_accdet_dev->keybit); //添加要使用的key
__set_bit(KEY_STOP,kpd_accdet_dev->keybit);
消息发送函数 check_cable_type()
case MIC_BIAS:
......
if((call_stauts = 0)&&button_status)
{
if(is_long_press())//77 75 only one key
{
notify_sendKeyEvent(ACC_STOP_MUSIC); //add define as #define ACC_END_CALL 2
}
else
{
notify_sendKeyEvent(ACC_PAUSE_MUSIC);
}
}
mediatek/custom/project/kernel/headset/accdet/accdet_custome.h
struct headset_mode_settings{
int pwm_width; //pwm frequence
int pwm_thresh; //pwm duty
int fall_delay; //falling stable time
int rise_delay; //rising stable time
int debounce0; //hook switch or double check debounce
int debounce1; //mic bias debounce
int debounce3; //plug out debounce
};
struct headset_mode_settings cust_headset_settings = {
0x1900, 0x140, 1, 0x12c, 0x3000, 0x3000, 0x400
};
其前两项是设置耳机PWM输出波形的,依次为 pwm_width 和PWM_THRESH
设置公式如下:
PWM OUTPUT whole time =(pwm_width+1) /32768 sec //周期时间
PWM OUTPUT high time =(PWM_THRESH+1) /32768 sec //高电平时间 可以自行调整耳机检测时间其他参数同样是以32K时钟作为时间计数
一些关于耳机的宏控定义,具体含义可以参看后面的FAQ宏控介绍
3、一些重要的FAQ介绍
3.1 [FAQ05819][Accdet]headset的HW limitatation
[DESCRIPTION]
在插入headset的过程中一些特殊操作的限制
[SUMMARY]
Accdet + EINT limitation:迅速完全插入耳机不会有噪音,但插入过程是逐节插入会有一点点噪音,且是概率性发生的。
PIN recognition limitation
1)在press key插入不兼容的耳机后,release key,这时不能弹出不兼容耳机的提示框
2)将不兼容耳机按插柱分节逐步插入插座,在插柱的第三节到第四节的过渡停留超过大约2s,之后完全推入耳机, 不兼容耳机会认不到,不能弹出不兼容耳机的提示框
3)插入耳机后,识别到耳机插入的时间要比pin recognition长,用户体验上来说,audio切到耳机的时间要比没有pin recognition长(大约长1-2s)
PIN recognition - summary
1)在press key插入illegal的耳机后,release key,这时不能识别成illegal 耳机
Up Key -> 會識別為非法耳機
Mid Key->會識別為3段耳機
Down Key->若電壓超出範圍應該是識別為三段耳機
2)非法4pin耳机,将耳机按插柱分节逐步插入插座,在插柱的第三节到第四节的过渡停留超过大约2s,之后完全推入耳机, illegal耳机会认不到,不能show error message
3)插入耳机后,audio切到耳机的时间要比没有pin recognition长
在0.5s内,将合法4pin耳机全部推入插座,从完全插入耳机算起,同等状况下会慢大约1.9s
在0.5s内,将三段耳机全部推入插座,从完全插入耳机算起,同等状况下会慢大约1s
非法4pin耳机,将耳机按插柱分节逐步插入插座(到完全插入的时间小于2s),从完全插入耳机算起,同等状况下会慢大约1s
合法4pin耳机,将耳机按插柱分节逐步插入插座(到完全插入的时间小于2s),从完全插入耳机算起,同等状况下会慢大约1s
3.2 [FAQ04509][Accdet]能否同时支持L/R/M/G和L/R/G/M的耳机
Answer:目前现有的software和hardware还没有办法支持。目前Iphone的耳机接口电路时L/R/G/M,因此以Iphone为例来说明,主要原因如下:
1)目前市面标配的耳机接口为: L/R/MIC/GND, 而iphone的接口为: L/R/GND/MIC, 目前iphone MIC的内阻为5M,与一般的耳机内阻(2K-11k)有很大的区别.
2)目前应该是耳机检测的extern interrupt也不会产生,因为plug out的时候, extern interrupt voltage是1.8V,插入耳机后相当于对地有了一个5M的电阻, (1.8 * 5M)/(470R + 5M)=1.8V,也就是说不会产生外部中断.
3)MIC与GND反了后,GND因为对地有个5M的resistor, 因此一直会是高, accdect IP内部就一直是(1, 1)这样的话就是一直处于plug out的state.
4)L/R因为接了一个5M的risistor到地后整个电路的功能将会有影响.
若需要兼容的话需要方案公司自己考究和修改相关方面
accdet cable type对识别耳机的不同状态需要重新设计代码
耳机的结构
切换的switch电路和识别电路
不同厂家耳机的电气特性
3.3 [FAQ05751][Headset]MT6589中常用宏开关的作用
在accdet.c和accdet_custome.h为了实现一些功能有用到很多宏开关,把目前相应的宏开关介绍如下:
1)ACCDET_EINT:是否启用了外部中断来侦测是否有耳机插入和拔出
2)ACCDET_MULTI_KEY_FEATURE:是否支持使用A/D来侦测key,这里要注意的是即使耳机只有一个key若是在89的平台也需打开此宏开关
3)ACCDET_LOW_POWER:当插入三段耳机6s后自动关闭micbias,达到省电的目的
以上三个宏可以看成一个宏
4)ACCDET_28v_MODE:在我们内部有一个switch是针对外部耳机是用2.8还是1.9V的切换开关,美标的是2.8V, 国标的是1.9V
5)ACCDET_PIN_RECOGNIZATION美标的插孔识别国标的耳机,国标的耳机识别美标的插孔,目前这个功能还没有实现,此宏不能打开
6)ACCDET_SHORT_PLUGOUT_DEBOUNCE,ACCDET_SHORT_PLUGOUT_DEBOUNCE_CN 25 :拔出耳机后有时候图标会再弹出后在消失, 主要解决类似bug
7)ACCDET_PIN_SWAP:美标的插孔识别国标的耳机,这个时候需要借助accdet的一个上拉电阻,当有这种情形的时候AB一直为0,达到检测到的目的,当然也有误判的时候, 4段耳机按住按键插入后会有误判
3.4 [FAQ06742][Headset]如何在ADB shell中读取耳机状态和读取ACCDET寄存器
[Description]
如何在ADB shell中读取耳机状态和读取ACCDET寄存器
[Solution]
1)获取耳机状态:cat /sys/class/switch/h2w/state
state值为0表示headset plug out;
state值为1表示有mic的耳机插入(四段式耳机);
state值为2表示没有mic的耳机插入(三段式耳机)。
2)读取寄存器:cd /sys/devices/platform/Accdet_Driver/driver
echo 1 >start_debug
echo 1 >dump_register
这样Accdet的reg会每500ms 抓到一次寄存器值,保存在log中
3.5 [FAQ04363][Headset] MTK平台耳机mutikey的支持情况
[DESCRIPTION]
MTK平台耳机的muti key的支持情况
[SOLUTION]
1)mtk6575/77平台
打电话状态 接听/挂断
非打电话状态 音乐暂停/播放功能
注:关于音乐暂停/播放功能,需在DMS上搜索 “MT6577 Add Headset Music Key”,根据此SOP的添加此功能。
2)mtk6589平台
打电话状态 接听/挂断(音量加减)
非打电话状态 音乐暂停/播放功能
上一曲/下一曲功能