《最新USB键盘驱动程序.docx》由会员分享,可在线阅读,更多相关《最新USB键盘驱动程序.docx(46页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、Four short words sum up what has lifted most successful individuals above the crowd: a little bit more.-author-dateUSB键盘驱动程序USB键盘驱动程序/* * $Id: usbkbd.c,v 1.27 2001/12/27 10:37:41 vojtech Exp $ * * Copyright (c) 1999-2001 Vojtech Pavlik * * USB HIDBP Keyboard support */* * This program is free softwa
2、re; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT
3、 ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foun
4、dation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Should you need to contact me, the author, you can do so either by * e-mail - mail your message to , or by paper mail: * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic */#include #include #include #include #incl
5、ude #include #include /* * Version Information */#define DRIVER_VERSION #define DRIVER_AUTHOR Vojtech Pavlik #define DRIVER_DESC USB HID Boot Protocol keyboard driver#define DRIVER_LICENSE GPLMODULE_AUTHOR(DRIVER_AUTHOR);MODULE_DESCRIPTION(DRIVER_DESC);MODULE_LICENSE(DRIVER_LICENSE);static unsigned
6、char usb_kbd_keycode256 = 0, 0, 0, 0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38, 50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 28, 1, 14, 15, 57, 12, 13, 26, 27, 43, 43, 39, 40, 41, 51, 52, 53, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 87, 88, 99, 70,
7、119,110,102,104,111,107,109,106,105,108,103, 69, 98, 55, 74, 78, 96, 79, 80, 81, 75, 76, 77, 71, 72, 73, 82, 83, 86,127,116,117,183,184,185,186,187,188,189,190,191,192,193,194,134,138,130,132,128,129,131,137,133,135,136,113,115,114, 0, 0, 0,121, 0, 89, 93,124, 92, 94, 95, 0, 0, 0,122,123, 90, 91, 85
8、, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 42, 56,125, 97, 54,100,126,164,166,165,163,161,115,114,113,150,158,15
9、9,128,136,177,178,176,142,152,173,140;struct usb_kbd struct input_dev *dev;struct usb_device *usbdev;unsigned char old8;struct urb *irq, *led;unsigned char newleds;char name128;char phys64;unsigned char *new;struct usb_ctrlrequest *cr;unsigned char *leds;dma_addr_t cr_dma;dma_addr_t new_dma;dma_addr
10、_t leds_dma;static void usb_kbd_irq(struct urb *urb, struct pt_regs *regs)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;input_r
11、egs(kbd-dev, regs);for (i = 0; i dev, usb_kbd_keycodei + 224, (kbd-new0 i) & 1);for (i = 2; i oldi 3 & memscan(kbd-new + 2, kbd-oldi, 6) = kbd-new + 8) if (usb_kbd_keycodekbd-oldi)input_report_key(kbd-dev, usb_kbd_keycodekbd-oldi, 0);elseinfo(Unknown key (scancode %#x) released., kbd-oldi);if (kbd-n
12、ewi 3 & memscan(kbd-old + 2, kbd-newi, 6) = kbd-old + 8) if (usb_kbd_keycodekbd-newi)input_report_key(kbd-dev, usb_kbd_keycodekbd-newi, 1);elseinfo(Unknown key (scancode %#x) pressed., kbd-newi);input_sync(kbd-dev);memcpy(kbd-old, kbd-new, 8);resubmit:i = usb_submit_urb (urb, SLAB_ATOMIC);if (i)err
13、(cant resubmit intr, %s-%s/input0, status %d,kbd-usbdev-bus-bus_name,kbd-usbdev-devpath, i);static int usb_kbd_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)struct usb_kbd *kbd = dev-private;if (type != EV_LED)return -1;kbd-newleds = (!test_bit(LED_KANA, dev-led) led)
14、led) led) led);if (kbd-led-status = -EINPROGRESS)return 0;if (*(kbd-leds) = kbd-newleds)return 0;*(kbd-leds) = kbd-newleds;kbd-led-dev = kbd-usbdev;if (usb_submit_urb(kbd-led, GFP_ATOMIC)err(usb_submit_urb(leds) failed);return 0;static void usb_kbd_led(struct urb *urb, struct pt_regs *regs)struct us
15、b_kbd *kbd = urb-context;if (urb-status)warn(led urb status %d received, urb-status);if (*(kbd-leds) = kbd-newleds)return;*(kbd-leds) = kbd-newleds;kbd-led-dev = kbd-usbdev;if (usb_submit_urb(kbd-led, GFP_ATOMIC)err(usb_submit_urb(leds) failed);static int usb_kbd_open(struct input_dev *dev)struct us
16、b_kbd *kbd = dev-private;kbd-irq-dev = kbd-usbdev;if (usb_submit_urb(kbd-irq, GFP_KERNEL)return -EIO;return 0;static void usb_kbd_close(struct input_dev *dev)struct usb_kbd *kbd = dev-private;usb_kill_urb(kbd-irq);static int usb_kbd_alloc_mem(struct usb_device *dev, struct usb_kbd *kbd)if (!(kbd-irq
17、 = usb_alloc_urb(0, GFP_KERNEL)return -1;if (!(kbd-led = usb_alloc_urb(0, GFP_KERNEL)return -1;if (!(kbd-new = usb_buffer_alloc(dev, 8, SLAB_ATOMIC, &kbd-new_dma)return -1;if (!(kbd-cr = usb_buffer_alloc(dev, sizeof(struct usb_ctrlrequest), SLAB_ATOMIC, &kbd-cr_dma)return -1;if (!(kbd-leds = usb_buf
18、fer_alloc(dev, 1, SLAB_ATOMIC, &kbd-leds_dma)return -1;return 0;static void usb_kbd_free_mem(struct usb_device *dev, struct usb_kbd *kbd)if (kbd-irq)usb_free_urb(kbd-irq);if (kbd-led)usb_free_urb(kbd-led);if (kbd-new)usb_buffer_free(dev, 8, kbd-new, kbd-new_dma);if (kbd-cr)usb_buffer_free(dev, sizeo
19、f(struct usb_ctrlrequest), kbd-cr, kbd-cr_dma);if (kbd-leds)usb_buffer_free(dev, 1, kbd-leds, kbd-leds_dma);static int usb_kbd_probe(struct usb_interface *iface, const struct usb_device_id *id)struct usb_device *dev = interface_to_usbdev(iface);struct usb_host_interface *interface;struct usb_endpoin
20、t_descriptor *endpoint;struct usb_kbd *kbd;struct input_dev *input_dev;int i, pipe, maxp;interface = iface-cur_altsetting;if (interface-desc.bNumEndpoints != 1)return -ENODEV;endpoint = &interface-endpoint0.desc;if (!(endpoint-bEndpointAddress & USB_DIR_IN)return -ENODEV;if (endpoint-bmAttributes &
21、USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT)return -ENODEV;pipe = usb_rcvintpipe(dev, endpoint-bEndpointAddress);maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe);kbd = kzalloc(sizeof(struct usb_kbd), GFP_KERNEL);input_dev = input_allocate_device();if (!kbd | !input_dev)goto fail1;if (usb_k
22、bd_alloc_mem(dev, kbd)goto fail2;kbd-usbdev = dev;kbd-dev = input_dev;if (dev-manufacturer)strlcpy(kbd-name, dev-manufacturer, sizeof(kbd-name);if (dev-product) if (dev-manufacturer)strlcat(kbd-name, , sizeof(kbd-name);strlcat(kbd-name, dev-product, sizeof(kbd-name);if (!strlen(kbd-name)snprintf(kbd
23、-name, sizeof(kbd-name), USB HIDBP Keyboard %04x:%04x, le16_to_cpu(dev-descriptor.idVendor), le16_to_cpu(dev-descriptor.idProduct);usb_make_path(dev, kbd-phys, sizeof(kbd-phys);strlcpy(kbd-phys, /input0, sizeof(kbd-phys);input_dev-name = kbd-name;input_dev-phys = kbd-phys;usb_to_input_id(dev, &input
24、_dev-id);input_dev-cdev.dev = &iface-dev;input_dev-private = kbd;input_dev-evbit0 = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_REP);input_dev-ledbit0 = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL) | BIT(LED_COMPOSE) | BIT(LED_KANA);for (i = 0; i keybit);clear_bit(0, input_dev-keybit);input_dev-event =
25、usb_kbd_event;input_dev-open = usb_kbd_open;input_dev-close = usb_kbd_close;usb_fill_int_urb(kbd-irq, dev, pipe, kbd-new, (maxp 8 ? 8 : maxp), usb_kbd_irq, kbd, endpoint-bInterval);kbd-irq-transfer_dma = kbd-new_dma;kbd-irq-transfer_flags |= URB_NO_TRANSFER_DMA_MAP;kbd-cr-bRequestType = USB_TYPE_CLA
26、SS | USB_RECIP_INTERFACE;kbd-cr-bRequest = 0x09;kbd-cr-wValue = cpu_to_le16(0x200);kbd-cr-wIndex = cpu_to_le16(interface-desc.bInterfaceNumber);kbd-cr-wLength = cpu_to_le16(1);usb_fill_control_urb(kbd-led, dev, usb_sndctrlpipe(dev, 0), (void *) kbd-cr, kbd-leds, 1, usb_kbd_led, kbd);kbd-led-setup_dm
27、a = kbd-cr_dma;kbd-led-transfer_dma = kbd-leds_dma;kbd-led-transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP);input_register_device(kbd-dev);usb_set_intfdata(iface, kbd);return 0;fail2:usb_kbd_free_mem(dev, kbd);fail1:input_free_device(input_dev);kfree(kbd);return -ENOMEM;static void
28、 usb_kbd_disconnect(struct usb_interface *intf)struct usb_kbd *kbd = usb_get_intfdata (intf);usb_set_intfdata(intf, NULL);if (kbd) usb_kill_urb(kbd-irq);input_unregister_device(kbd-dev);usb_kbd_free_mem(interface_to_usbdev(intf), kbd);kfree(kbd);static struct usb_device_id usb_kbd_id_table = USB_INT
29、ERFACE_INFO(3, 1, 1) , /* Terminating entry */;MODULE_DEVICE_TABLE (usb, usb_kbd_id_table);static struct usb_driver usb_kbd_driver = .name =usbkbd,.probe =usb_kbd_probe,.disconnect =usb_kbd_disconnect,.id_table =usb_kbd_id_table,;static int _init usb_kbd_init(void)int result = usb_register(&usb_kbd_driver);if (result = 0)info(DRIVER_VERSION : DRIVER_DESC);return result;static void _exit usb_kbd_exit(void)usb_deregister(&usb_kbd_driver);module_init(usb_kbd_init);module_exit(usb_kbd_exit);-
限制150内