1,318
社区成员
发帖
与我相关
我的任务
分享
│ Symbol: USB_HID [=y] │
│ Type : tristate │
│ Prompt: USB Human Interface Device (full HID) support │
│ Defined at drivers/hid/usbhid/Kconfig:4 │
│ Depends on: HID_SUPPORT [=y] && USB [=y] && INPUT [=y] │
│ Location: │
│ -> Device Drivers │
│ -> HID Devices (HID_SUPPORT [=y]) │
│ Selects: HID [=y]
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/usb/input.h>
#include <linux/hid.h>
static int len;
static struct input_dev *uk_dev;
static char *usb_buf;
static dma_addr_t usb_buf_phys;
static struct urb *uk_urb;
static struct usb_device_id keyboard_id_table [] = {
{ USB_INTERFACE_INFO(USB_INTERFACE_CLASS_HID, USB_INTERFACE_SUBCLASS_BOOT,
USB_INTERFACE_PROTOCOL_KEYBOARD) },
//{USB_DEVICE(0x1234,0x5678)},
{ } /* Terminating entry */
};
static void keyboard_irq(struct urb *urb)
{
static unsigned char pre_val;
int i;
static int cnt = 0;
printk("data cnt %d: ", ++cnt);
for (i = 0; i < len; i++)
{
printk("%02x ", usb_buf[i]);
}
printk("\n");
/* 重新提交urb */
usb_submit_urb(uk_urb, GFP_KERNEL);
}
static int keyboard_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
struct usb_device *dev = interface_to_usbdev(intf);
struct usb_host_interface *interface;
struct usb_endpoint_descriptor *endpoint;
int pipe;
interface = intf->cur_altsetting;
endpoint = &interface->endpoint[0].desc;
/* a. 分配一个input_dev */
uk_dev = input_allocate_device();
/* b. 设置 */
/* b.1 能产生哪类事件 */
set_bit(EV_KEY, uk_dev->evbit);
set_bit(EV_REP, uk_dev->evbit);
/* b.2 能产生哪些事件 */
set_bit(KEY_L, uk_dev->keybit);
set_bit(KEY_S, uk_dev->keybit);
set_bit(KEY_ENTER, uk_dev->keybit);
/* c. 注册 */
input_register_device(uk_dev);
/* d. 硬件相关操作 */
/* 数据传输3要素: 源,目的,长度 */
/* 源: USB设备的某个端点 */
pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
/* 长度: */
len = endpoint->wMaxPacketSize;
/* 目的: */
//usb_buf = usb_buffer_alloc(dev, len, GFP_ATOMIC, &usb_buf_phys);
usb_buf = usb_alloc_coherent(dev, len, GFP_ATOMIC, &usb_buf_phys);
/* 使用"3要素" */
/* 分配usb request block */
uk_urb = usb_alloc_urb(0, GFP_KERNEL);
/* 使用"3要素设置urb" */
usb_fill_int_urb(uk_urb, dev, pipe, usb_buf, len, keyboard_irq, NULL, endpoint->bInterval);
uk_urb->transfer_dma = usb_buf_phys;
uk_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
/* 使用URB */
usb_submit_urb(uk_urb, GFP_KERNEL);
return 0;
}
/*int __init kbd_init(void) 函数是键盘代码执行的开始点,
但keyboard.c并非是一定 执行的,你必须先定义CONFIG_VT(Character devices ->nbsp;Virtual terminal)才有效,
为什 么?因为kbd_init()是在tty_io.c 的 tty_init()中被调用的*/
/*static kbd_init(void)
{
int i;
int error;
for (i = 0; i < MAX_NR_CONSOLES; i++) {
kbd_table[i].ledflagstate = kbd_defleds();
kbd_table[i].default_ledflagstate = kbd_defleds();
kbd_table[i].ledmode = LED_SHOW_FLAGS;
kbd_table[i].lockstate = KBD_DEFLOCK;
kbd_table[i].slockstate = 0;
kbd_table[i].modeflags = KBD_DEFMODE;
kbd_table[i].kbdmode = default_utf8 ? VC_UNICODE : VC_XLATE;
}
kbd_init_leds();
error = input_register_handler(&kbd_handler);
if (error)
return error;
tasklet_enable(&keyboard_tasklet);
tasklet_schedule(&keyboard_tasklet);
return 0;
}*/
static void keyboard_disconnect(struct usb_interface *intf)
{
struct usb_device *dev = interface_to_usbdev(intf);
//printk("disconnect usbmouse!\n");
usb_kill_urb(uk_urb);
usb_free_urb(uk_urb);
usb_free_coherent(dev, len, usb_buf, usb_buf_phys);
input_unregister_device(uk_dev);
input_free_device(uk_dev);
}
/* 1. 分配/设置usb_driver */
static struct usb_driver keyboard_driver = {
.name = "my_keyboard",
.probe = keyboard_probe,
.disconnect = keyboard_disconnect,
.id_table = keyboard_id_table,
};
static int keyboard_init(void)
{
/* 2. 注册 */
usb_register(&keyboard_driver);
return 0;
}
static void keyboard_exit(void)
{
usb_deregister(&keyboard_driver);
}
module_init(keyboard_init);
module_exit(keyboard_exit);
MODULE_LICENSE("GPL");
[/quote]键盘108键呢,我要一个个上报事件report上去?我看usbkbd.c这个文件,这个是键盘的驱动吧,没有一个个上报啊,倒是有个255的数组[/quote]
48 static const unsigned char usb_kbd_keycode[256] = {
49 0, 0, 0, 0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38,
50 50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44, 2, 3,
51 4, 5, 6, 7, 8, 9, 10, 11, 28, 1, 14, 15, 57, 12, 13, 26,
52 27, 43, 43, 39, 40, 41, 51, 52, 53, 58, 59, 60, 61, 62, 63, 64,
53 65, 66, 67, 68, 87, 88, 99, 70,119,110,102,104,111,107,109,106,
54 105,108,103, 69, 98, 55, 74, 78, 96, 79, 80, 81, 75, 76, 77, 71,
55 72, 73, 82, 83, 86,127,116,117,183,184,185,186,187,188,189,190,
56 191,192,193,194,134,138,130,132,128,129,131,137,133,135,136,113,
57 115,114, 0, 0, 0,121, 0, 89, 93,124, 92, 94, 95, 0, 0, 0,
58 122,123, 90, 91, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
59 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
60 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
61 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
62 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
63 29, 42, 56,125, 97, 54,100,126,164,166,165,163,161,115,114,113,
64 150,158,159,128,136,177,178,176,142,152,173,140
65 };
//人家是把键码存在数组里
130 for (i = 0; i < 8; i++)
131 input_report_key(kbd->dev, usb_kbd_keycode[i + 224], (kbd->new[0] >> i) & 1);
132
133 for (i = 2; i < 8; i++) {
134
135 if (kbd->old[i] > 3 && memscan(kbd->new + 2, kbd->old[i], 6) == kbd->new + 8) {
136 if (usb_kbd_keycode[kbd->old[i]])
137 input_report_key(kbd->dev, usb_kbd_keycode[kbd->old[i]], 0);
138 else
139 hid_info(urb->dev,
140 "Unknown key (scancode %#x) released.\n",
141 kbd->old[i]);
142 }
143
144 if (kbd->new[i] > 3 && memscan(kbd->old + 2, kbd->new[i], 6) == kbd->old + 8) {
145 if (usb_kbd_keycode[kbd->new[i]])
146 input_report_key(kbd->dev, usb_kbd_keycode[kbd->new[i]], 1);
147 else
148 hid_info(urb->dev,
149 "Unknown key (scancode %#x) released.\n",
150 kbd->new[i]);
151 }
152 }
这些就是汇报
怎么确认啊?我在make menuconfig里看到keyboards这个选项被选中了,不知道是不是这个? [quote=引用 7 楼 jklinux 的回复:]
确定下设备驱动是否编进内核里,如果已编进内核,那就在驱动的id_table里加上你键盘的usb id
怎么确认啊?我在make menuconfig里看到keyboards这个选项被选中了,不知道是不是这个? 确定下设备驱动是否编进内核里,如果已编进内核,那就在驱动的id_table里加上你键盘的usb id
确定下设备驱动是否编进内核里,如果已编进内核,那就在驱动的id_table里加上你键盘的usb id
[quote=引用 4 楼 Guet_Kite 的回复:] [quote=引用 2 楼 Guet_Kite 的回复:] [quote=引用 1 楼 jklinux 的回复:] 可以考照drivers/hid/usbhid/usbmouse.c 虽然它是鼠标的,但都是用usb的中断端点的设备,除了数据不一样外,基本一样。 usbmouse.c应是内核里最简单的usb设备驱动了。
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/usb/input.h>
#include <linux/hid.h>
static int len;
static struct input_dev *uk_dev;
static char *usb_buf;
static dma_addr_t usb_buf_phys;
static struct urb *uk_urb;
static struct usb_device_id keyboard_id_table [] = {
{ USB_INTERFACE_INFO(USB_INTERFACE_CLASS_HID, USB_INTERFACE_SUBCLASS_BOOT,
USB_INTERFACE_PROTOCOL_KEYBOARD) },
//{USB_DEVICE(0x1234,0x5678)},
{ } /* Terminating entry */
};
static void keyboard_irq(struct urb *urb)
{
static unsigned char pre_val;
int i;
static int cnt = 0;
printk("data cnt %d: ", ++cnt);
for (i = 0; i < len; i++)
{
printk("%02x ", usb_buf[i]);
}
printk("\n");
/* 重新提交urb */
usb_submit_urb(uk_urb, GFP_KERNEL);
}
static int keyboard_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
struct usb_device *dev = interface_to_usbdev(intf);
struct usb_host_interface *interface;
struct usb_endpoint_descriptor *endpoint;
int pipe;
interface = intf->cur_altsetting;
endpoint = &interface->endpoint[0].desc;
/* a. 分配一个input_dev */
uk_dev = input_allocate_device();
/* b. 设置 */
/* b.1 能产生哪类事件 */
set_bit(EV_KEY, uk_dev->evbit);
set_bit(EV_REP, uk_dev->evbit);
/* b.2 能产生哪些事件 */
set_bit(KEY_L, uk_dev->keybit);
set_bit(KEY_S, uk_dev->keybit);
set_bit(KEY_ENTER, uk_dev->keybit);
/* c. 注册 */
input_register_device(uk_dev);
/* d. 硬件相关操作 */
/* 数据传输3要素: 源,目的,长度 */
/* 源: USB设备的某个端点 */
pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
/* 长度: */
len = endpoint->wMaxPacketSize;
/* 目的: */
//usb_buf = usb_buffer_alloc(dev, len, GFP_ATOMIC, &usb_buf_phys);
usb_buf = usb_alloc_coherent(dev, len, GFP_ATOMIC, &usb_buf_phys);
/* 使用"3要素" */
/* 分配usb request block */
uk_urb = usb_alloc_urb(0, GFP_KERNEL);
/* 使用"3要素设置urb" */
usb_fill_int_urb(uk_urb, dev, pipe, usb_buf, len, keyboard_irq, NULL, endpoint->bInterval);
uk_urb->transfer_dma = usb_buf_phys;
uk_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
/* 使用URB */
usb_submit_urb(uk_urb, GFP_KERNEL);
return 0;
}
/*int __init kbd_init(void) 函数是键盘代码执行的开始点,
但keyboard.c并非是一定 执行的,你必须先定义CONFIG_VT(Character devices ->nbsp;Virtual terminal)才有效,
为什 么?因为kbd_init()是在tty_io.c 的 tty_init()中被调用的*/
/*static kbd_init(void)
{
int i;
int error;
for (i = 0; i < MAX_NR_CONSOLES; i++) {
kbd_table[i].ledflagstate = kbd_defleds();
kbd_table[i].default_ledflagstate = kbd_defleds();
kbd_table[i].ledmode = LED_SHOW_FLAGS;
kbd_table[i].lockstate = KBD_DEFLOCK;
kbd_table[i].slockstate = 0;
kbd_table[i].modeflags = KBD_DEFMODE;
kbd_table[i].kbdmode = default_utf8 ? VC_UNICODE : VC_XLATE;
}
kbd_init_leds();
error = input_register_handler(&kbd_handler);
if (error)
return error;
tasklet_enable(&keyboard_tasklet);
tasklet_schedule(&keyboard_tasklet);
return 0;
}*/
static void keyboard_disconnect(struct usb_interface *intf)
{
struct usb_device *dev = interface_to_usbdev(intf);
//printk("disconnect usbmouse!\n");
usb_kill_urb(uk_urb);
usb_free_urb(uk_urb);
usb_free_coherent(dev, len, usb_buf, usb_buf_phys);
input_unregister_device(uk_dev);
input_free_device(uk_dev);
}
/* 1. 分配/设置usb_driver */
static struct usb_driver keyboard_driver = {
.name = "my_keyboard",
.probe = keyboard_probe,
.disconnect = keyboard_disconnect,
.id_table = keyboard_id_table,
};
static int keyboard_init(void)
{
/* 2. 注册 */
usb_register(&keyboard_driver);
return 0;
}
static void keyboard_exit(void)
{
usb_deregister(&keyboard_driver);
}
module_init(keyboard_init);
module_exit(keyboard_exit);
MODULE_LICENSE("GPL");
[/quote]键盘108键呢,我要一个个上报事件report上去?我看usbkbd.c这个文件,这个是键盘的驱动吧,没有一个个上报啊,倒是有个255的数组[/quote]
48 static const unsigned char usb_kbd_keycode[256] = {
49 0, 0, 0, 0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38,
50 50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44, 2, 3,
51 4, 5, 6, 7, 8, 9, 10, 11, 28, 1, 14, 15, 57, 12, 13, 26,
52 27, 43, 43, 39, 40, 41, 51, 52, 53, 58, 59, 60, 61, 62, 63, 64,
53 65, 66, 67, 68, 87, 88, 99, 70,119,110,102,104,111,107,109,106,
54 105,108,103, 69, 98, 55, 74, 78, 96, 79, 80, 81, 75, 76, 77, 71,
55 72, 73, 82, 83, 86,127,116,117,183,184,185,186,187,188,189,190,
56 191,192,193,194,134,138,130,132,128,129,131,137,133,135,136,113,
57 115,114, 0, 0, 0,121, 0, 89, 93,124, 92, 94, 95, 0, 0, 0,
58 122,123, 90, 91, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
59 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
60 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
61 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
62 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
63 29, 42, 56,125, 97, 54,100,126,164,166,165,163,161,115,114,113,
64 150,158,159,128,136,177,178,176,142,152,173,140
65 };
//人家是把键码存在数组里
130 for (i = 0; i < 8; i++)
131 input_report_key(kbd->dev, usb_kbd_keycode[i + 224], (kbd->new[0] >> i) & 1);
132
133 for (i = 2; i < 8; i++) {
134
135 if (kbd->old[i] > 3 && memscan(kbd->new + 2, kbd->old[i], 6) == kbd->new + 8) {
136 if (usb_kbd_keycode[kbd->old[i]])
137 input_report_key(kbd->dev, usb_kbd_keycode[kbd->old[i]], 0);
138 else
139 hid_info(urb->dev,
140 "Unknown key (scancode %#x) released.\n",
141 kbd->old[i]);
142 }
143
144 if (kbd->new[i] > 3 && memscan(kbd->old + 2, kbd->new[i], 6) == kbd->old + 8) {
145 if (usb_kbd_keycode[kbd->new[i]])
146 input_report_key(kbd->dev, usb_kbd_keycode[kbd->new[i]], 1);
147 else
148 hid_info(urb->dev,
149 "Unknown key (scancode %#x) released.\n",
150 kbd->new[i]);
151 }
152 }
这些就是汇报
[/quote]那很奇怪啊,那内核里都有完整的键盘驱动了,为什么我直接插键盘上去不能用啊。插上usb键盘后,显示:
usb 1-1: new low-speed USB device number 2 using s3c2410-ohci
usb 1-1: USB disconnect, device number 2
usb 1-1: new low-speed USB device number 3 using s3c2410-ohci
usb 1-1: USB disconnect, device number 3[quote=引用 1 楼 jklinux 的回复:] 可以考照drivers/hid/usbhid/usbmouse.c 虽然它是鼠标的,但都是用usb的中断端点的设备,除了数据不一样外,基本一样。 usbmouse.c应是内核里最简单的usb设备驱动了。
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/usb/input.h>
#include <linux/hid.h>
static int len;
static struct input_dev *uk_dev;
static char *usb_buf;
static dma_addr_t usb_buf_phys;
static struct urb *uk_urb;
static struct usb_device_id keyboard_id_table [] = {
{ USB_INTERFACE_INFO(USB_INTERFACE_CLASS_HID, USB_INTERFACE_SUBCLASS_BOOT,
USB_INTERFACE_PROTOCOL_KEYBOARD) },
//{USB_DEVICE(0x1234,0x5678)},
{ } /* Terminating entry */
};
static void keyboard_irq(struct urb *urb)
{
static unsigned char pre_val;
int i;
static int cnt = 0;
printk("data cnt %d: ", ++cnt);
for (i = 0; i < len; i++)
{
printk("%02x ", usb_buf[i]);
}
printk("\n");
/* 重新提交urb */
usb_submit_urb(uk_urb, GFP_KERNEL);
}
static int keyboard_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
struct usb_device *dev = interface_to_usbdev(intf);
struct usb_host_interface *interface;
struct usb_endpoint_descriptor *endpoint;
int pipe;
interface = intf->cur_altsetting;
endpoint = &interface->endpoint[0].desc;
/* a. 分配一个input_dev */
uk_dev = input_allocate_device();
/* b. 设置 */
/* b.1 能产生哪类事件 */
set_bit(EV_KEY, uk_dev->evbit);
set_bit(EV_REP, uk_dev->evbit);
/* b.2 能产生哪些事件 */
set_bit(KEY_L, uk_dev->keybit);
set_bit(KEY_S, uk_dev->keybit);
set_bit(KEY_ENTER, uk_dev->keybit);
/* c. 注册 */
input_register_device(uk_dev);
/* d. 硬件相关操作 */
/* 数据传输3要素: 源,目的,长度 */
/* 源: USB设备的某个端点 */
pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
/* 长度: */
len = endpoint->wMaxPacketSize;
/* 目的: */
//usb_buf = usb_buffer_alloc(dev, len, GFP_ATOMIC, &usb_buf_phys);
usb_buf = usb_alloc_coherent(dev, len, GFP_ATOMIC, &usb_buf_phys);
/* 使用"3要素" */
/* 分配usb request block */
uk_urb = usb_alloc_urb(0, GFP_KERNEL);
/* 使用"3要素设置urb" */
usb_fill_int_urb(uk_urb, dev, pipe, usb_buf, len, keyboard_irq, NULL, endpoint->bInterval);
uk_urb->transfer_dma = usb_buf_phys;
uk_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
/* 使用URB */
usb_submit_urb(uk_urb, GFP_KERNEL);
return 0;
}
/*int __init kbd_init(void) 函数是键盘代码执行的开始点,
但keyboard.c并非是一定 执行的,你必须先定义CONFIG_VT(Character devices ->nbsp;Virtual terminal)才有效,
为什 么?因为kbd_init()是在tty_io.c 的 tty_init()中被调用的*/
/*static kbd_init(void)
{
int i;
int error;
for (i = 0; i < MAX_NR_CONSOLES; i++) {
kbd_table[i].ledflagstate = kbd_defleds();
kbd_table[i].default_ledflagstate = kbd_defleds();
kbd_table[i].ledmode = LED_SHOW_FLAGS;
kbd_table[i].lockstate = KBD_DEFLOCK;
kbd_table[i].slockstate = 0;
kbd_table[i].modeflags = KBD_DEFMODE;
kbd_table[i].kbdmode = default_utf8 ? VC_UNICODE : VC_XLATE;
}
kbd_init_leds();
error = input_register_handler(&kbd_handler);
if (error)
return error;
tasklet_enable(&keyboard_tasklet);
tasklet_schedule(&keyboard_tasklet);
return 0;
}*/
static void keyboard_disconnect(struct usb_interface *intf)
{
struct usb_device *dev = interface_to_usbdev(intf);
//printk("disconnect usbmouse!\n");
usb_kill_urb(uk_urb);
usb_free_urb(uk_urb);
usb_free_coherent(dev, len, usb_buf, usb_buf_phys);
input_unregister_device(uk_dev);
input_free_device(uk_dev);
}
/* 1. 分配/设置usb_driver */
static struct usb_driver keyboard_driver = {
.name = "my_keyboard",
.probe = keyboard_probe,
.disconnect = keyboard_disconnect,
.id_table = keyboard_id_table,
};
static int keyboard_init(void)
{
/* 2. 注册 */
usb_register(&keyboard_driver);
return 0;
}
static void keyboard_exit(void)
{
usb_deregister(&keyboard_driver);
}
module_init(keyboard_init);
module_exit(keyboard_exit);
MODULE_LICENSE("GPL");
[/quote]键盘108键呢,我要一个个上报事件report上去?我看usbkbd.c这个文件,这个是键盘的驱动吧,没有一个个上报啊,倒是有个255的数组可以考照drivers/hid/usbhid/usbmouse.c 虽然它是鼠标的,但都是用usb的中断端点的设备,除了数据不一样外,基本一样。 usbmouse.c应是内核里最简单的usb设备驱动了。
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/usb/input.h>
#include <linux/hid.h>
static int len;
static struct input_dev *uk_dev;
static char *usb_buf;
static dma_addr_t usb_buf_phys;
static struct urb *uk_urb;
static struct usb_device_id keyboard_id_table [] = {
{ USB_INTERFACE_INFO(USB_INTERFACE_CLASS_HID, USB_INTERFACE_SUBCLASS_BOOT,
USB_INTERFACE_PROTOCOL_KEYBOARD) },
//{USB_DEVICE(0x1234,0x5678)},
{ } /* Terminating entry */
};
static void keyboard_irq(struct urb *urb)
{
static unsigned char pre_val;
int i;
static int cnt = 0;
printk("data cnt %d: ", ++cnt);
for (i = 0; i < len; i++)
{
printk("%02x ", usb_buf[i]);
}
printk("\n");
/* 重新提交urb */
usb_submit_urb(uk_urb, GFP_KERNEL);
}
static int keyboard_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
struct usb_device *dev = interface_to_usbdev(intf);
struct usb_host_interface *interface;
struct usb_endpoint_descriptor *endpoint;
int pipe;
interface = intf->cur_altsetting;
endpoint = &interface->endpoint[0].desc;
/* a. 分配一个input_dev */
uk_dev = input_allocate_device();
/* b. 设置 */
/* b.1 能产生哪类事件 */
set_bit(EV_KEY, uk_dev->evbit);
set_bit(EV_REP, uk_dev->evbit);
/* b.2 能产生哪些事件 */
set_bit(KEY_L, uk_dev->keybit);
set_bit(KEY_S, uk_dev->keybit);
set_bit(KEY_ENTER, uk_dev->keybit);
/* c. 注册 */
input_register_device(uk_dev);
/* d. 硬件相关操作 */
/* 数据传输3要素: 源,目的,长度 */
/* 源: USB设备的某个端点 */
pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
/* 长度: */
len = endpoint->wMaxPacketSize;
/* 目的: */
//usb_buf = usb_buffer_alloc(dev, len, GFP_ATOMIC, &usb_buf_phys);
usb_buf = usb_alloc_coherent(dev, len, GFP_ATOMIC, &usb_buf_phys);
/* 使用"3要素" */
/* 分配usb request block */
uk_urb = usb_alloc_urb(0, GFP_KERNEL);
/* 使用"3要素设置urb" */
usb_fill_int_urb(uk_urb, dev, pipe, usb_buf, len, keyboard_irq, NULL, endpoint->bInterval);
uk_urb->transfer_dma = usb_buf_phys;
uk_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
/* 使用URB */
usb_submit_urb(uk_urb, GFP_KERNEL);
return 0;
}
/*int __init kbd_init(void) 函数是键盘代码执行的开始点,
但keyboard.c并非是一定 执行的,你必须先定义CONFIG_VT(Character devices ->nbsp;Virtual terminal)才有效,
为什 么?因为kbd_init()是在tty_io.c 的 tty_init()中被调用的*/
/*static kbd_init(void)
{
int i;
int error;
for (i = 0; i < MAX_NR_CONSOLES; i++) {
kbd_table[i].ledflagstate = kbd_defleds();
kbd_table[i].default_ledflagstate = kbd_defleds();
kbd_table[i].ledmode = LED_SHOW_FLAGS;
kbd_table[i].lockstate = KBD_DEFLOCK;
kbd_table[i].slockstate = 0;
kbd_table[i].modeflags = KBD_DEFMODE;
kbd_table[i].kbdmode = default_utf8 ? VC_UNICODE : VC_XLATE;
}
kbd_init_leds();
error = input_register_handler(&kbd_handler);
if (error)
return error;
tasklet_enable(&keyboard_tasklet);
tasklet_schedule(&keyboard_tasklet);
return 0;
}*/
static void keyboard_disconnect(struct usb_interface *intf)
{
struct usb_device *dev = interface_to_usbdev(intf);
//printk("disconnect usbmouse!\n");
usb_kill_urb(uk_urb);
usb_free_urb(uk_urb);
usb_free_coherent(dev, len, usb_buf, usb_buf_phys);
input_unregister_device(uk_dev);
input_free_device(uk_dev);
}
/* 1. 分配/设置usb_driver */
static struct usb_driver keyboard_driver = {
.name = "my_keyboard",
.probe = keyboard_probe,
.disconnect = keyboard_disconnect,
.id_table = keyboard_id_table,
};
static int keyboard_init(void)
{
/* 2. 注册 */
usb_register(&keyboard_driver);
return 0;
}
static void keyboard_exit(void)
{
usb_deregister(&keyboard_driver);
}
module_init(keyboard_init);
module_exit(keyboard_exit);
MODULE_LICENSE("GPL");