#include"mousekey.h"
MODULE_LICENSE("GPL"); MODULE_AUTHOR("DRAAPHO");
static const struct usb_device_id mousekey_usb_ids[] = {
{ USB_INTERFACE_INFO(USB_INTERFACE_CLASS_HID, USB_INTERFACE_SUBCLASS_BOOT, USB_INTERFACE_PROTOCOL_MOUSE) },
{} };
struct usb_driver mousekey_usb_driver;
struct usb_private { struct urb *urb; struct usb_device *udev; struct input_dev *idev; char *buf; dma_addr_t buf_phys; int len; };
static void mousekey_irq(struct urb *urb) { struct usb_private *priv = urb->context;
#if 0 int i; for (i = 0; i < priv->len; i++) { printk("%02x ", priv->buf[i]); } printk("\n"); usb_submit_urb(priv->urb, GFP_KERNEL); #else
switch (urb->status) { case 0: break; case -ECONNRESET: case -ENOENT: case -ESHUTDOWN: return; default: goto resubmit; }
input_report_key(priv->idev, KEY_L, priv->buf[0] & 0x01); input_report_key(priv->idev, KEY_S, priv->buf[0] & 0x02); input_report_key(priv->idev, KEY_ENTER, priv->buf[0] & 0x04); input_sync(priv->idev);
resubmit: usb_submit_urb (urb, GFP_ATOMIC); #endif }
static int mousekey_probe(struct usb_interface *iface, const struct usb_device_id *id) { int pipe; struct usb_private *priv; struct usb_endpoint_descriptor *endpoint; PINFO("found USB mousekey! ==========>\n");
priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) { PERR("Failed to allocate the device's private data\n"); return -ENOMEM; } usb_set_intfdata(iface, priv); priv->udev = interface_to_usbdev(iface);
printk("USB address=%d\n" "manufacturer=%s, product=%s, serial=%s\n" "idVendor=0x%x, idProduct=0x%x\n" "Device Class=%d, SubClass=%d, Protocol=%d\n", priv->udev->devnum, priv->udev->manufacturer, priv->udev->product, priv->udev->serial, priv->udev->descriptor.idVendor, priv->udev->descriptor.idProduct, priv->udev->descriptor.bDeviceClass, priv->udev->descriptor.bDeviceSubClass, priv->udev->descriptor.bDeviceProtocol); printk("InterfaceNumber=%d, NumberOfEndpoints=%d\n" "Interface Class=%d, SubClass=%d, Protocol=%d\n", iface->cur_altsetting->desc.bInterfaceNumber, iface->cur_altsetting->desc.bNumEndpoints, iface->cur_altsetting->desc.bInterfaceClass, iface->cur_altsetting->desc.bInterfaceSubClass, iface->cur_altsetting->desc.bInterfaceProtocol);
if (iface->cur_altsetting->desc.bNumEndpoints != 1) return -ENODEV; endpoint = &iface->cur_altsetting->endpoint[0].desc; if (!usb_endpoint_is_int_in(endpoint)) return -ENODEV;
priv->idev = input_allocate_device();
set_bit(EV_KEY, priv->idev->evbit); set_bit(EV_REP, priv->idev->evbit); set_bit(KEY_L, priv->idev->keybit); set_bit(KEY_S, priv->idev->keybit); set_bit(KEY_ENTER, priv->idev->keybit);
input_register_device(priv->idev);
priv->urb = usb_alloc_urb(0, GFP_KERNEL);
pipe = usb_rcvintpipe(priv->udev, endpoint->bEndpointAddress); priv->len = endpoint->wMaxPacketSize; priv->buf = usb_buffer_alloc(priv->udev, priv->len, GFP_ATOMIC, &priv->buf_phys);
usb_fill_int_urb(priv->urb, priv->udev, pipe, priv->buf, priv->len, mousekey_irq, priv, endpoint->bInterval); priv->urb->transfer_dma = priv->buf_phys; priv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
usb_submit_urb(priv->urb, GFP_KERNEL); return 0; }
static void mousekey_disconnect(struct usb_interface *iface) { struct usb_private *priv = usb_get_intfdata(iface); PINFO("disconnect USB mousekey\n");
usb_kill_urb(priv->urb); usb_free_urb(priv->urb); usb_buffer_free(priv->udev, priv->len, priv->buf, priv->buf_phys); input_unregister_device(priv->idev); input_free_device(priv->idev); kfree(priv); }
struct usb_driver mousekey_usb_driver = { .name = DRIVER_NAME, .id_table = mousekey_usb_ids, .probe = mousekey_probe, .disconnect = mousekey_disconnect, };
static int __init mousekey_init(void) { int res;
res = usb_register(&mousekey_usb_driver); if( res ) { PERR("Error registering the USB Driver\n"); return res; }
PINFO("INIT\n"); return 0; }
static void __exit mousekey_exit(void) { PINFO("EXIT\n"); usb_deregister(&mousekey_usb_driver); }
module_init(mousekey_init); module_exit(mousekey_exit);
|