这几个月,我接触了可能是我目前见到过的最烂的耳机检测设计,这主要是指ASIC设计的针对耳机检测的模拟电路。这真是一个彻头彻尾的失败设计,因为耳机检测电路完全和audio codec被混合到了一起,这简直无法理解。
从软件流程来看,耳机检测流程和audio是没有半毛钱关系的。但是当硬件和ASIC把耳机检测相关的寄存器和audio的寄存器混合到一起后,这就变成了一坨屎!
很不幸的我在不知情的情况下去为这坨垃圾写驱动,驱动就像一个袋子,里面包裹了一坨屎,人们觉得这个袋子很臭,没有人想打开袋子看看,所以袋子很为难。袋子想说:我已经尽可能把它包裹起来了。。。
耳机检测驱动在检测到耳机插入后通过linux的switch device向上层报告耳机插入事件及耳机类型。
probe过程通过int switch_dev_register(struct switch_dev *sdev) 函数来注册一个switch dev。
注意:
static struct sprd_headset headset = {
.sdev = {
.name = "h2w",
},
};
这个switch dev的名字必须为h2w,这个被android写死了。
耳机插入或拔出后,通过void switch_set_state(struct switch_dev *sdev, int state)函数更新 /sys/class/switch/h2w/state (0=未插 1=4pole 2=3pole) 节点的值来给上层报告耳机插入或拔出动作。
通过logcat可以看到耳机插入时上层在state bar中显示耳机图标对应的log为:
插入:
V/WiredAccessoryManager( 579): Headset UEVENT: {SUBSYSTEM=switch, SWITCH_STATE=1, DEVPATH=/devices/virtual/switch/h2w, SEQNUM=1422, ACTION=change, SWITCH_NAME=h2w}
D/ENGPC ( 160): parse_event: event { 'change', '/devices/virtual/switch/h2w', 'switch', '' }
V/WiredAccessoryManager( 579): newName=h2w newState=1 headsetState=1 prev headsetState=0
V/WiredAccessoryManager( 579): device h2w connected
D/ENGPC ( 228): parse_event: event { 'change', '/devices/virtual/switch/h2w', 'switch', '' }
D/PhoneStatusBarPolicy( 638): headset state = 1,mic = 1,visiable = true
拔出:
V/WiredAccessoryManager( 579): Headset UEVENT: {SUBSYSTEM=switch, SWITCH_STATE=0, DEVPATH=/devices/virtual/switch/h2w, SEQNUM=1424, ACTION=change, SWITCH_NAME=h2w}
V/WiredAccessoryManager( 579): newName=h2w newState=0 headsetState=0 prev headsetState=1
V/WiredAccessoryManager( 579): device h2w disconnected
D/ENGPC ( 160): parse_event: event { 'change', '/devices/virtual/switch/h2w', 'switch', '' }
D/ENGPC ( 228): parse_event: event { 'change', '/devices/virtual/switch/h2w', 'switch', '' }
D/PhoneStatusBarPolicy( 638): headset state = 0,mic = 1,visiable = false