欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

[转载] [Keypad]如何设计GPIO中断模拟普通按键控制静音等功能 博客分类: linux_kernel  

程序员文章站 2024-03-02 17:05:52
...

 

[FAQ06059] [Keypad]如何设计GPIO中断模拟普通按键控制静音等功能
Branch:ICS2JBJB2

FAQ Content

[Description]
如何设计GPIO中断模拟普通按键控制静音等功能
 
[Solution]
参考设计思路:Kernel 底层可以参考kpd.c的POWEY USE EINT 的方式设计:把Key_MUTE送到framework
1.声明中断下半程的tasklet
#if KPD_PWRKEY_USE_EINT
static void kpd_pwrkey_handler(unsigned long data);
static DECLARE_TASKLET(kpd_pwrkey_tasklet, kpd_pwrkey_handler, 0);
static u8 kpd_pwrkey_state = !KPD_PWRKEY_POLARITY;
#endif
 
2.实现中断服务函数 发送按键消息到framework
#if KPD_PWRKEY_USE_EINT
static void kpd_pwrkey_handler(unsigned long data)
{
 bool pressed;
 u8 old_state = kpd_pwrkey_state;
 kpd_pwrkey_state = !kpd_pwrkey_state;
 pressed = (kpd_pwrkey_state == !!KPD_PWRKEY_POLARITY);
 if (kpd_show_hw_keycode) {
  printk(KPD_SAY "(%s) HW keycode = using EINT\n",
         pressed ? "pressed" : "released");
 }
 input_report_key(kpd_input_dev, KPD_PWRKEY_MAP, pressed);
 kpd_print("report Linux keycode = %u\n", KPD_PWRKEY_MAP);
 /* for detecting the return to old_state */
 mt65xx_eint_set_polarity(KPD_PWRKEY_EINT, old_state);
 mt65xx_eint_unmask(KPD_PWRKEY_EINT);
}
 
3.kpd_pdrv_probe()中加入__set_bit(KPD_PWRKEY_MAP, kpd_input_dev->keybit);
声明中断初始化:
 mt_set_gpio_mode(GPIO_KPD_MUTEKEY_EINT_PIN, GPIO_KPD_MUTEKEY_EINT_PIN_M_EINT);
 mt_set_gpio_dir(GPIO_KPD_MUTEKEY_EINT_PIN, GPIO_DIR_IN);
 //mt_set_gpio_pull_enable(GPIO_KPD_MUTEKEY_EINT_PIN, GPIO_PULL_DISABLE);
 mt_set_gpio_pull_enable(GPIO_KPD_MUTEKEY_EINT_PIN, GPIO_PULL_ENABLE);
 mt_set_gpio_pull_select(GPIO_KPD_MUTEKEY_EINT_PIN, GPIO_PULL_UP);
#if KPD_PWRKEY_USE_EINT
 mt65xx_eint_set_sens(KPD_PWRKEY_EINT, KPD_PWRKEY_SENSITIVE);
 mt65xx_eint_set_hw_debounce(KPD_PWRKEY_EINT, KPD_PWRKEY_DEBOUNCE);
 mt65xx_eint_registration(KPD_PWRKEY_EINT, true, KPD_PWRKEY_POLARITY,
                          kpd_pwrkey_eint_handler, false);
#endif

4.dct tool配置GPIO为中断模式
5.注意实现静音按键,拨下开关时间会很长,如果只有一个KEY_MUTE,一直长按(press),没有发release,framework上长按事件会爆掉,建议拔下中断GPIO=0 发KEY_MUTE;拨上中断GPIO=1 发KEY_MUTE1;
如何添加一个按键:请参看MTK online FAQ :MTK on-line > FAQ Home > SW > ALPS > Driver - input system>FAQ04495 [Keypad]How to add a new key on android ICS\ICS2 
或者拔下中断GPIO=0 发KEY_MUTE的press,接着马上发送release;在上层通过lastkey静音,newkey释放静音。
framework上在phonewindowmanager收到按键之后,可以拦截KEY_MUTE和KEY_MUTE1 去设置setting 的DB和静音模式
在framework/base/policy/src/com/android/impl/PhoneWindowManager.java
添加调试code 确认按键正常
if (true) {
Log.d(TAG, "interceptKeyTi keyCode=" + keyCode + " down=" + down + " repeatCount="
+ repeatCount + " keyguardOn=" + keyguardOn + " mHomePressed=" + mHomePressed);
}
//ADD log check the mute key dispatching
if(keyCode == KeyEvent.KEYCODE_MUTE)
Log.d(TAG, "interceptKeyTi keyCode=" + keyCode + " MUTE");
 
6.audio 静音模式接口
静音调用设置setRingerMode状态
RINGER_MODE_SILENT 静音,且无振动
RINGER_MODE_VIBRATE 静音,但有振动
RINGER_MODE_NORMAL 正常声音
铃响模式的设置是通过mAudioManager(音频管理器)来实现的.
mAudioManager所在服务如下:
文件: frameworks/base/media/java/android/media/AudioManager.java
    public static final int RINGER_MODE_SILENT = 0;
    public static final int RINGER_MODE_VIBRATE = 1;
    public static final int RINGER_MODE_NORMAL = 2;
public void setRingerMode(int ringerMode) {
        IAudioService service = getService();
        try {
            service.setRingerMode(ringerMode);
        } catch (RemoteException e) {
            Log.e(TAG, "Dead object in setRingerMode", e);
        }
}
在拦截静音键或者在apk上接收key值添加相应的控制