一、mouse的8 bytes定义
二、keyboard的8 bytes定义
/*键盘发送给PC的数据每次8个字节
data0 data1 data2 data3 data4 data5 data6 data7
定义分别是:
data0 --
|--bit0: Left Control是否按下,按下为1
|--bit1: Left Shift 是否按下,按下为1
|--bit2: Left Alt 是否按下,按下为1
|--bit3: Left GUI 是否按下,按下为1
|--bit4: Right Control是否按下,按下为1
|--bit5: Right Shift 是否按下,按下为1
|--bit6: Right Alt 是否按下,按下为1
|--bit7: Right GUI 是否按下,按下为1
data1 -- 保留
data2--data7 -- 普通按键
refer to hid spec 8.3*/
bytes[0]代表组合按键(左右ctrl、alt、shift、win)可以同时全部按下,
bytes[2]~bytes[7]代表普通的按键,最多可以同时按下6个键,
加起来的话总共可以同时按下4+4+6个按键系统能检测出来。
三、usb hid keyboard编码(见HID usage tables Chapter10),只列举部分
四、input子系统编码
在drivers/hid/usbhid/usbkbd.c中定义了一张表
static const unsigned char usb_kbd_keycode[256] = {
0, 0, 0, 0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38,//0
50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44, 2, 3,//16
4, 5, 6, 7, 8, 9, 10, 11, 28, 1, 14, 15, 57, 12, 13, 26,//32
27, 43, 43, 39, 40, 41, 51, 52, 53, 58, 59, 60, 61, 62, 63, 64,//48
65, 66, 67, 68, 87, 88, 99, 70,119,110,102,104,111,107,109,106,//64
105,108,103, 69, 98, 55, 74, 78, 96, 79, 80, 81, 75, 76, 77, 71,//80
72, 73, 82, 83, 86,127,116,117,183,184,185,186,187,188,189,190,//96
191,192,193,194,134,138,130,132,128,129,131,137,133,135,136,113,//112
115,114, 0, 0, 0,121, 0, 89, 93,124, 92, 94, 95, 0, 0, 0,//128
122,123, 90, 91, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,//144
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,//160
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,//176
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,//192
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,//208
29, 42, 56,125, 97, 54,100,126,164,166,165,163,161,115,114,113,//224
150,158,159,128,136,177,178,176,142,152,173,140//240-251
};
static void usb_kbd_irq(struct urb *urb)
{
struct usb_kbd *kbd = urb->context;
int i;
switch (urb->status) {
case 0: /* success */
break;
case -ECONNRESET: /* unlink */
case -ENOENT:
case -ESHUTDOWN:
return;
/* -EPIPE: should clear the halt */
default: /* error */
goto resubmit;
}
/**************************检测组合键********************************************/
/*
1. kbd->new是urb的缓冲区用来存储设备发过来的8个字节
2. (kbd->new[0]>>i) & 1 检测第i位是否为1,如果为1,则上报案件usb_kbd_keycode[i+224]
例如,left control按下(bit0为1)即((kbd->new[0]>>0) & 1 ) = 1,所以上报usbkbd_keycode[0+224] = 29,
其中224代表hid编码,29代表此hid编码对应的input编码,
hid code通过usb_kbd_keyboard映射到input code,usb_kbd_keycode[hid code] = input code
*/
for (i = 0; i < 8; i++)
input_report_key(kbd->dev, usb_kbd_keycode[i + 224], (kbd->new[0] >> i) & 1);
/**************************检测普通键********************************************/
/*
1. 可以从hid编码表格中看到有意义的hid规范从4(字符a)开始
2. 将kbd->old[i]的值在kbd->new的6个字节中寻找,看是否存在
如果在6个字节的kbd->new中不存在old[i]那么说明old[i]已经被释放了
3. 如果不是新的释放事件,而是原来的键一直处于释放状态,则不会执行下面的操作
说明只会在按键释放瞬间发生按键释放上报事件,而在未按期间不会上报释放事件。
*/
for (i = 2; i < 8; i++) {
if (kbd->old[i] > 3 && memscan(kbd->new + 2, kbd->old[i], 6) == kbd->new + 8) {
if (usb_kbd_keycode[kbd->old[i]])
input_report_key(kbd->dev, usb_kbd_keycode[kbd->old[i]], 0);
else
dev_info(&urb->dev->dev,
"Unknown key (scancode %#x) released.\n", kbd->old[i]);
}
/*
1. 将kbd->new[i]的值在kbd->old的6个字节中寻找,看是否存在,如果不存在,说明new[i]是新按下的
2. 如果不是新按下的键,而是原来的键一直没有释放,则不会上报按键事件,
说明只有在按键按下时上报事件,而在按的过程中不会上报按键事件。
*/
if (kbd->new[i] > 3 && memscan(kbd->old + 2, kbd->new[i], 6) == kbd->old + 8) {
if (usb_kbd_keycode[kbd->new[i]])
input_report_key(kbd->dev, usb_kbd_keycode[kbd->new[i]], 1);
else
dev_info(&urb->dev->dev,
"Unknown key (scancode %#x) released.\n", kbd->new[i]);
}
}
input_sync(kbd->dev);
memcpy(kbd->old, kbd->new, 8);
resubmit:
i = usb_submit_urb (urb, GFP_ATOMIC);
if (i)
err_hid ("can't resubmit intr, %s-%s/input0, status %d",
kbd->usbdev->bus->bus_name,
kbd->usbdev->devpath, i);
}
部分参考:http://blog.csdn.net/opencpu/article/details/6876083