15,6 → 15,7 |
} __attribute__ ((packed)); |
|
void create_hid_mouse(udev_t *dev, endpoint_descr_t *en_d); |
void create_hid_keyboard(udev_t *dev, endpoint_descr_t *en_d); |
|
bool init_hid(udev_t *dev) |
{ |
93,8 → 94,16 |
ep->wMaxPacketSize, ep->bInterval); |
dptr+= ep->bLength; |
|
if( interface->bInterfaceProtocol == 2) |
switch(interface->bInterfaceProtocol) |
{ |
case 1: |
create_hid_keyboard(dev, ep); |
break; |
|
case 2: |
create_hid_mouse(dev, ep); |
break; |
} |
// } |
return true; |
}; |
118,7 → 127,7 |
|
u32_t efl = safe_cli(); |
list_add_tail(&rq->list, &dev->host->rq_list); |
qh = dev->host->qh[6]; |
qh = dev->host->qh[rq->qnum]; |
qh->qelem = rq->td_head->dma; |
mb(); |
safe_sti(efl); |
126,6 → 135,163 |
return true; |
}; |
|
typedef union |
{ |
uint16_t value; |
struct |
{ |
uint8_t code; |
uint8_t ecode; |
}; |
}scancode_t; |
|
static const uint16_t usb_keycode[256] = |
{ |
/* 0 1 2 3 4 5 6 7 */ |
/* 8 9 A B C D E F */ |
|
0x0000, 0x0000, 0x0000, 0x0000, 0x001E, 0x0030, 0x002E, 0x0020, /* 0x00 */ |
0x0012, 0x0021, 0x0022, 0x0023, 0x0017, 0x0024, 0x0025, 0x0026, |
|
0x0032, 0x0031, 0x0018, 0x0019, 0x0010, 0x0013, 0x001F, 0x0014, /* 0x10 */ |
0x0016, 0x002F, 0x0011, 0x002D, 0x0015, 0x002C, 0x0002, 0x0003, |
|
0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, /* 0x20 */ |
0x001C, 0x0001, 0x000E, 0x000F, 0x0039, 0x000C, 0x000D, 0x001A, |
|
0x001B, 0x002B, 0x002B, 0x0027, 0x0028, 0x0029, 0x0033, 0x0034, /* 0x30 */ |
0x0035, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, 0x0040, |
|
0x0041, 0x0042, 0x0043, 0x0044, 0x0057, 0x0058, 0xE037, 0x0046, /* 0x40 */ |
0x0000, 0xE052, 0xE047, 0xE049, 0xE053, 0xE04F, 0xE051, 0xE04D, |
|
0xE04B, 0xE050, 0xE048, 0x0045, 0xE035, 0x0037, 0x004A, 0x004E, /* 0x50 */ |
0xE01C, 0x004F, 0x0050, 0x0051, 0x004B, 0x004C, 0x004D, 0x0047, |
|
0x0048, 0x0049, 0x0052, 0x0053, 0x0056, 0xE05D, 0xE05E, 0x0059, /* 0x60 */ |
0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, |
|
0x006C, 0x006D, 0x006E, 0x0076, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x70 */ |
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, |
|
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x007E, 0x0000, 0x0073, /* 0x80 */ |
0x0070, 0x007D, 0x0079, 0x007B, 0x005C, 0x0000, 0x0000, 0x0000, |
|
0x00F2, 0x00F1, 0x0078, 0x0077, 0x0076, 0x0000, 0x0000, 0x0000, /* 0x90 */ |
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, |
|
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0xA0 */ |
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, |
|
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0xB0 */ |
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, |
|
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0xC0 */ |
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, |
|
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0xD0 */ |
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, |
|
0x001D, 0x002A, 0x0038, 0xE05B, 0xE01D, 0x0036, 0xE038, 0xE05C, /* 0xE0 */ |
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, |
|
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0xFE0 */ |
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, |
|
}; |
|
static uint8_t kbd_old[8]; |
|
bool keyboard_handler(udev_t *dev, struct tag_request *rq) |
{ |
td_t *td; |
qh_t *qh; |
|
uint8_t *data; |
int i; |
|
td = rq->td_head; |
|
if( (td->status &0x7FF)==rq->size-1) |
{ |
uint8_t action; |
scancode_t scan; |
|
data = (uint8_t*)rq->data; |
|
action = data[0] ^ kbd_old[0]; |
|
for (i = 0; i < 8; i++) |
{ |
if(action & 1) |
{ |
scan.value = usb_keycode[i+224]; |
|
if(data[0]>>i & 1) |
{ |
if(scan.ecode) |
SetKeyboardData(scan.ecode); |
SetKeyboardData(scan.code); |
} |
else |
{ |
if(scan.ecode) |
SetKeyboardData(scan.ecode); |
SetKeyboardData(scan.code|0x80); |
}; |
} |
action >>= 1; |
} |
|
|
for (i = 2; i < 8; i++) |
{ |
if ((kbd_old[i] > 3) && (memscan(data+2, kbd_old[i], 6) == data+8)) |
{ |
scan.value = usb_keycode[kbd_old[i]]; |
|
if (scan.value) |
{ |
if(scan.ecode) |
SetKeyboardData(scan.ecode); |
SetKeyboardData(scan.code|0x80); |
// input_report_key(kbd->dev, usb_kbd_keycode[kbd->old[i]], 0); |
} |
else |
dbgprintf("Unknown key (scancode %#x) released.\n", kbd_old[i]); |
} |
|
if ((data[i] > 3) && (memscan(kbd_old+2, data[i], 6) == kbd_old+8)) |
{ |
scan.value = usb_keycode[data[i]]; |
|
if (scan.value) |
{ |
if(scan.ecode) |
SetKeyboardData(scan.ecode); |
SetKeyboardData(scan.code); |
//input_report_key(kbd->dev, usb_kbd_keycode[kbd->new[i]], 1); |
} |
else |
dbgprintf("Unknown key (scancode %#x) released.\n", data[i]); |
} |
} |
memcpy(kbd_old, data, 8); |
}; |
|
td->status = TD_CTRL_ACTIVE | TD_CTRL_IOC | dev->speed; |
td->token ^= DATA1; |
|
u32_t efl = safe_cli(); |
list_add_tail(&rq->list, &dev->host->rq_list); |
qh = dev->host->qh[rq->qnum]; |
qh->qelem = rq->td_head->dma; |
mb(); |
safe_sti(efl); |
|
return true; |
}; |
|
void create_hid_mouse(udev_t *dev, endpoint_descr_t *en_d) |
{ |
request_t *rq; |
135,9 → 301,6 |
addr_t size; |
u32_t toggle; |
|
void *packet; |
|
td_t *td; |
qh_t *qh; |
|
static u16_t __attribute__((aligned(16))) |
150,18 → 313,69 |
enp.size = en_d->wMaxPacketSize; |
enp.toggle = DATA0; |
|
packet = kzalloc(enp.size, 0); |
rq = alloc_rq_buffer(dev, &enp, DIN, enp.size); |
|
rq = create_request(dev, &enp, DIN, packet, enp.size); |
rq->qnum = 6; |
rq->handler = &mouse_handler; |
|
u32_t efl = safe_cli(); |
list_add_tail(&rq->list, &dev->host->rq_list); |
qh = dev->host->qh[6]; |
qh = dev->host->qh[rq->qnum]; |
qh->qelem = rq->td_head->dma; |
mb(); |
safe_sti(efl); |
|
dbgprintf("create_hid_mouse\n"); |
dbgprintf("%s\n",__FUNCTION__); |
} |
|
void create_hid_keyboard(udev_t *dev, endpoint_descr_t *en_d) |
{ |
request_t *rq; |
endp_t enp; |
|
addr_t address; |
addr_t size; |
u32_t toggle; |
|
qh_t *qh; |
|
static u16_t __attribute__((aligned(16))) |
req_set_conf[4] = {0x0900,0x0001,0x0000,0x0000}; |
|
if( !ctrl_request(dev, req_set_conf, DOUT, 0, 0)) |
return; |
|
enp.address = en_d->bEndpointAddress; |
enp.size = en_d->wMaxPacketSize; |
enp.toggle = DATA0; |
|
rq = alloc_rq_buffer(dev, &enp, DIN, enp.size); |
|
rq->qnum = 4; |
rq->handler = &keyboard_handler; |
|
u32_t efl = safe_cli(); |
list_add_tail(&rq->list, &dev->host->rq_list); |
qh = dev->host->qh[rq->qnum]; |
qh->qelem = rq->td_head->dma; |
mb(); |
safe_sti(efl); |
|
dbgprintf("%s\n",__FUNCTION__); |
} |
|
void *memscan(void *addr, int c, size_t size) |
{ |
if (!size) |
return addr; |
__asm__ __volatile__( |
"repnz; scasb \n\t" |
"jnz 1f \n\t" |
"dec %%edi \n\t" |
"1:" |
: "=D" (addr), "=c" (size) |
: "D" (addr), "1" (size), "a" (c) |
: "memory"); |
return addr; |
} |
|