赞
踩
提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加
例如:第一章 Python 机器学习入门之pandas的使用
实现耳机输入输出的插拔检测功能:修改插拔驱动代码,驱动中上报inputevent事件,通过framework处理事件并发出广播;
平台:amlogic
soc:a311d
输入检测gpio口(microphone):
输出检测gpio口(headphone):
插拔检测原理就是通过gpio口的电平变化来判断插拔状态,可以通过gpio中断、轮询gpio电平两种方式获取插拔状态的变化。
DTS配置gpio资源:
auge_sound {
compatible = "amlogic, g12a-sound-card";
aml-audio-card,name = "AML-AUGESOUND";
/*avout mute gpio*/
avout_mute-gpios = <&gpio_ao GPIOAO_2 GPIO_ACTIVE_HIGH>;
es7241_rst-gpios = <&gpio_ao GPIOAO_10 GPIO_ACTIVE_HIGH>;
+ /*headphone 插拔检测gpio*/
+ aml-audio-card,hp-det-gpio = <&gpio GPIOA_8 GPIO_ACTIVE_HIGH>;
+ /*micphone 插拔检测gpio*/
+ aml-audio-card,mic-det-gpio = <&gpio GPIOA_7 GPIO_ACTIVE_HIGH>;
......
}
我拿到的驱动代码是通过定时器加工作队列去轮询gpio电平来判断插拔状态的:
static void jack_timer_func(unsigned long data) { struct aml_card_data *card_data = (struct aml_card_data *)data; unsigned long delay = msecs_to_jiffies(150); schedule_work(&card_data->work);/*每隔150ms去调度一个工作队列,轮询插拔状态*/ mod_timer(&card_data->timer, jiffies + delay); } static void jack_work_func(struct work_struct *work) { flag = jack_audio_hp_detect(card_data);/*检测gpio电平*/ if (flag == -1) goto micphone_detect; if (card_data->hp_detect_flag != flag) { /*如果电平有变化*/ card_data->hp_detect_flag = flag; if (flag) { /*方法一:使用uevent,上报同步extcon事件,会更新/sys/class/extcon/xxx/state节点的值; 但是目前上次java还是使用的switch的方式来处理uevent事件,所以上下层不兼容导致该方法无法使用; 不过文件系统下的extcon节点是可以根据插拔改变state值的*/ extcon_set_state_sync(audio_extcon_headphone, EXTCON_JACK_HEADPHONE, 1); /*方法二:使用inputevent,上报input事件; 我的java层是兼容inputevent的,所以使用此方法上报插拔事件*/ snd_soc_jack_report(&card_data->hp_jack.jack, SND_JACK_HEADPHONE, SND_JACK_HEADPHONE); } } } static void audio_jack_detect(struct aml_card_data *card_data) { init_timer(&card_data->timer); card_data->timer.function = jack_timer_func; card_data->timer.data = (unsigned long)card_data; INIT_WORK(&card_data->work, jack_work_func); jack_audio_start_timer(card_data, msecs_to_jiffies(5000)); }
这是方法一,实现extcon的API接口及步骤:
static const unsigned int headphone_cable[] = { EXTCON_JACK_HEADPHONE, EXTCON_NONE, }; edev = extcon_dev_allocate(headphone_cable);//创建一个extcon数据结构 if (IS_ERR(edev)) { pr_info("failed to allocate audio extcon headphone\n"); return; } edev->dev.parent = dev; edev->name = "audio_extcon_headphone";//这将是extcon节点下name的值 dev_set_name(&edev->dev, "headphone");//设置名称,这将会是文件系统下extcon节点的名称 ret = extcon_dev_register(edev);//将extcon注册,最后会生成/sys/class/extcon/xxx/目录,下面包括name、state等文件 if (ret < 0) { pr_info("failed to register audio extcon headphone\n"); return; } audio_extcon_headphone = edev; extcon_set_state_sync(audio_extcon_headphone, EXTCON_JACK_HEADPHONE, 1);//上报一个extcon事件
这是方法二,实现inputevent的API接口及步骤:
pin_name = "Headphones";
mask = SND_JACK_HEADPHONE;
//生成一个新的jack对象,定义其被检测的类型,即拔插的设备类型
snd_soc_card_jack_new(card, pin_name, mask, &sjack->jack, &sjack->pin, 1);
snd_soc_jack_add_gpios(&sjack->jack, 1, &sjack->gpio);
/*汇报jack插拔状态,主要完成以下两个工作:
a) 根据插入拔出状态更新前面通过snd_soc_jack_add_pins加入的dapm pin的状态,对其进行上电下电管理。
b) 调用snd_jack_report,在其中通过input_report_key/input_report_switch来向上层汇报input event。*/
snd_soc_jack_report(&card_data->mic_jack.jack, SND_JACK_MICROPHONE, SND_JACK_MICROPHONE);
//snd_soc_jack_report(&card_data->mic_jack.jack, 0, SND_JACK_MICROPHONE);
/frameworks/base/core/res/res/values/config.xml
将config_useDevInputEventForAudioJack修改为true才能使用inputevent方式上报插拔事件:
<!-- When true use the linux /dev/input/event subsystem to detect the switch changes on the headphone/microphone jack. When false use the older uevent framework. -->
<bool name="config_useDevInputEventForAudioJack">true</bool>
\frameworks\base\services\core\java\com\android\server\input\InputManagerService.java
当底层有input事件上报后,会调用notifySwitch方法:
// Native callback. private void notifySwitch(long whenNanos, int switchValues, int switchMask) { if (DEBUG) { Slog.d(TAG, "notifySwitch: values=" + Integer.toHexString(switchValues) + ", mask=" + Integer.toHexString(switchMask)); } if ((switchMask & SW_LID_BIT) != 0) { final boolean lidOpen = ((switchValues & SW_LID_BIT) == 0); mWindowManagerCallbacks.notifyLidSwitchChanged(whenNanos, lidOpen); } if ((switchMask & SW_CAMERA_LENS_COVER_BIT) != 0) {
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。