平台 :RK3288
OS:Android7.1
kernel部分添加键值:
1.在dts中(kernel/arch/arm/boot/dts/rk3288-android.dtsi)添加键值属性,可以仿照power按键配置
wake-key {
gpios = ;
linux,code = <117>;
pinctrl-names = "default";
pinctrl-0 = ;
label = "wake";
gpio-key,wakeup;
};
因我们使用的键值操作是通过gpio触发的,则配置成gpio-key。
linux,code 键码可以查看内核自定义键码来选择。定义在kernel/include/uapi/linux/input-event-codes.h下。
/*
* Event types
*/
#define EV_SYN0x00
#define EV_KEY0x01
#define EV_REL0x02
#define EV_ABS0x03
#define EV_MSC0x04
#define EV_SW0x05
#define EV_LED0x11
#define EV_SND0x12
#define EV_REP0x14
#define EV_FF0x15
#define EV_PWR0x16
#define EV_FF_STATUS0x17
#define EV_MAX0x1f
#define EV_CNT(EV_MAX+1)
/*
* Keys and buttons
*
* Most of the keys/buttons are modeled after USB HUT 1.12
* (see http://www.usb.org/developers/hidpage).
* Abbreviations in the comments:
* AC - Application Control
* AL - Application Launch Button
* SC - System Control
*/
#define KEY_RIGHTALT100
#define KEY_LINEFEED101
#define KEY_HOME102
#define KEY_UP103
#define KEY_PAGEUP104
#define KEY_LEFT105
#define KEY_RIGHT106
#define KEY_END107
#define KEY_DOWN108
#define KEY_PAGEDOWN109
#define KEY_INSERT110
#define KEY_DELETE111
#define KEY_MACRO112
#define KEY_MUTE113
#define KEY_VOLUMEDOWN114
#define KEY_VOLUMEUP115
#define KEY_POWER116/* SC System Power Down */
#define KEY_KPEQUAL117
#define KEY_KPPLUSMINUS118
#define KEY_PAUSE119
#define KEY_SCALE120/* AL Compiz Scale (Expose) */
#define KEY_KPCOMMA121
#define KEY_HANGEUL122
#define KEY_HANGUELKEY_HANGEUL
#define KEY_HANJA123
#define KEY_YEN124
#define KEY_LEFTMETA125
#define KEY_RIGHTMETA126
#define KEY_COMPOSE127
#define KEY_STOP128/* AC Stop */
#define KEY_AGAIN129
#define KEY_PROPS130/* AC Properties */
#define KEY_UNDO131/* AC Undo */
#define KEY_FRONT132
#define KEY_COPY133/* AC Copy */
#define KEY_OPEN134/* AC Open */
#define KEY_PASTE135/* AC Paste */
#define KEY_FIND136/* AC Search */
#define KEY_CUT137/* AC Cut */
#define KEY_HELP138/* AL Integrated Help Center */
#define KEY_MENU139/* Menu (show menu) */
#define KEY_CALC140/* AL Calculator */
#define KEY_SETUP141
#define KEY_SLEEP142/* SC System Sleep */
#define KEY_WAKEUP143/* System Wake Up */
#define KEY_FILE144/* AL Local Machine Browser */
#define KEY_SENDFILE145
#define KEY_DELETEFILE146
#define KEY_XFER147
#define KEY_PROG1148
#define KEY_PROG2149
#define KEY_WWW150/* AL Internet Browser */
#define KEY_MSDOS151
#define KEY_COFFEE152/* AL Terminal Lock/Screensaver */
#define KEY_SCREENLOCKKEY_COFFEE
#define KEY_ROTATE_DISPLAY153/* Display orientation for e.g. tablets */
#define KEY_DIRECTIONKEY_ROTATE_DISPLAY
#define KEY_CYCLEWINDOWS154
#define KEY_MAIL155
#define KEY_BOOKMARKS156/* AC Bookmarks */
#define KEY_COMPUTER157
#define KEY_BACK158/* AC Back */
#define KEY_FORWARD159/* AC Forward */
#define KEY_CLOSECD160
#define KEY_EJECTCD161
#define KEY_EJECTCLOSECD162
#define KEY_NEXTSONG163
#define KEY_PLAYPAUSE164
#define KEY_PREVIOUSSONG165
#define KEY_STOPCD166
#define KEY_RECORD167
#define KEY_REWIND168
#define KEY_PHONE169/* Media Select Telephone */
#define KEY_ISO170
#define KEY_CONFIG171/* AL Consumer Control Configuration */
#define KEY_HOMEPAGE172/* AC Home */
#define KEY_REFRESH173/* AC Refresh */
#define KEY_EXIT174/* AC Exit */
因键值较多,就只列一部分出来,在定义键码的时候,注意不要与现正在使用的键码重复。如不确认哪些键码是已经使用的,可以在该文件中添加自定义键码。
在dts中添加键值属性后,需要在驱动(我的是在/kernel/drivers/input/keyboard/rk_reys.c)里,做dts解析:
/* parse info from dt */
ddata->nbuttons = key_num;
error = rk_keys_parse_dt(ddata, pdev);
if (error)
goto fail0;
如该按键需要以中断的方式触发,则可以为这个按键申请中断:
error =devm_request_irq(dev, irq, keys_isr1,
IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING,
button->desc ? button->desc:"wake",button);
键值上报:
1.注册input事件:
通过input_register_device()函数来向内核注册input事件。
2.input事件上报:
input事件上报是通过input_event()或input_report_key()函数上报。
input_event()函数简介:
函数原型:
void input_event(struct input_dev *dev,
unsigned int type, unsigned int code, int value)
{
unsigned long flags;
if (is_event_supported(type, dev->evbit, EV_MAX))
{
spin_lock_irqsave(&dev->event_lock, flags);
add_input_randomness(type, code, value);
input_handle_event(dev, type, code, value);
spin_unlock_irqrestore(&dev->event_lock, flags);
}
}
EXPORT_SYMBOL(input_event);
参数介绍:
struct input_dev *dev:需要上报的事件
unsigned int type:上报的事件类型(在前面的input-event-codes.h文件中有定义)
unsigned int code:上报的键码
int value :上报的键值
使用实例:
static irqreturn_t keys_isr1(int irq, void *dev_id)
{
struct rk_keys_button *button = (struct rk_keys_button *)dev_id;
struct rk_keys_drvdata *pdata = dev_get_drvdata(button->dev);
struct input_dev *input = pdata->input;
int irq_status = gpio_get_value(14);
if (0==irq_status){ //插入就触发中断,,拔出来也触发中断。
input_event(input, EV_KEY, 118, 1);
input_sync(input);
udelay(50);
input_event(input, EV_KEY, 118, 0);
input_sync(input);
}
else if (1==irq_status){
input_event(input, EV_KEY, 117, 1);
input_sync(input);
udelay(50);
input_event(input, EV_KEY, 117, 0);
input_sync(input);
}
return IRQ_HANDLED;
}
注意:input_event()上报按键事件必须先上报1(意为按下),再上报0(意为弹起),不能单独上报1,或者上报0。
kernel部分添加完成后,可通过getevent命令来确认事件有无上报成功。
内核部分确认调试成功后,需要将键值上报至上层:
1.修改按键布局映射文件,都是以.kl结尾的文件,可通过
cat bus/input/devices 命令来查看我们系统目前正在使用的布局文件是哪个。
我使用的是/device/rockchip/common/rk29-keypad.kl布局文件
key 59 MENU
key 102 HOME
key 114 VOLUME_DOWN
key 115 VOLUME_UP
key 116 POWER
key 143 NOTIFICATION
key 158 BACK
key 212 CAMERA
key 217 SEARCH
在这后面添加key 117 F1 则表示内核上报的117键值映射到系统的键值为F1
系统的键值定义在frameworks/base/core/java/android/view/KeyEvent.java下。
添加完成后可以在frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java里添加打印信息,查看键值是否上报成功。
public long interceptKeyBeforeDispatching(WindowState win, KeyEvent event, int policyFlags) {
final boolean keyguardOn = keyguardOn();
final int keyCode = event.getKeyCode();
final int repeatCount = event.getRepeatCount();
final int metaState = event.getMetaState();
final int flags = event.getFlags();
final boolean down = event.getAction() == KeyEvent.ACTION_DOWN;
final boolean canceled = event.isCanceled();
if (DEBUG_INPUT) {
Log.d(TAG, "interceptKeyTi keyCode=" + keyCode + " down=" + down + " repeatCount="
+ repeatCount + " keyguardOn=" + keyguardOn + " mHomePressed=" + mHomePressed
+ " canceled=" + canceled);
}
上层APK可通过调用frameworks/base/core/java/android/view/KeyEvent.java中的接口去拦截键值
public interface Callback {
boolean onKeyDown(int keyCode, KeyEvent event);
boolean onKeyLongPress(int keyCode, KeyEvent event);
boolean onKeyUp(int keyCode, KeyEvent event);
boolean onKeyMultiple(int keyCode, int count, KeyEvent event);
}