X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fusb%2Finput%2Fxpad.c;h=e278489a80c6520941fe30723ea50c305717bd72;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=d65edb22e5459a8c3ed032da363fd1b28fe2c889;hpb=cee37fe97739d85991964371c1f3a745c00dd236;p=linux-2.6.git diff --git a/drivers/usb/input/xpad.c b/drivers/usb/input/xpad.c index d65edb22e..e278489a8 100644 --- a/drivers/usb/input/xpad.c +++ b/drivers/usb/input/xpad.c @@ -62,6 +62,7 @@ #include #include #include +#include #define DRIVER_VERSION "v0.0.5" #define DRIVER_AUTHOR "Marko Friedemann " @@ -69,7 +70,7 @@ #define XPAD_PKT_LEN 32 -static struct xpad_device { +static const struct xpad_device { u16 idVendor; u16 idProduct; char *name; @@ -80,13 +81,13 @@ static struct xpad_device { { 0x0000, 0x0000, "X-Box pad" } }; -static signed short xpad_btn[] = { +static const signed short xpad_btn[] = { BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, /* "analog" buttons */ BTN_START, BTN_BACK, BTN_THUMBL, BTN_THUMBR, /* start/back/sticks */ -1 /* terminating entry */ }; -static signed short xpad_abs[] = { +static const signed short xpad_abs[] = { ABS_X, ABS_Y, /* left stick */ ABS_RX, ABS_RY, /* right stick */ ABS_Z, ABS_RZ, /* triggers left/right */ @@ -102,15 +103,14 @@ static struct usb_device_id xpad_table [] = { MODULE_DEVICE_TABLE (usb, xpad_table); struct usb_xpad { - struct input_dev dev; /* input device interface */ + struct input_dev *dev; /* input device interface */ struct usb_device *udev; /* usb device */ - + struct urb *irq_in; /* urb for interrupt in report */ unsigned char *idata; /* input data */ dma_addr_t idata_dma; - + char phys[65]; /* physical device path */ - int open_count; /* reference count */ }; /* @@ -125,38 +125,38 @@ struct usb_xpad { static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *data, struct pt_regs *regs) { - struct input_dev *dev = &xpad->dev; + struct input_dev *dev = xpad->dev; input_regs(dev, regs); - + /* left stick */ input_report_abs(dev, ABS_X, (__s16) (((__s16)data[13] << 8) | data[12])); input_report_abs(dev, ABS_Y, (__s16) (((__s16)data[15] << 8) | data[14])); - + /* right stick */ input_report_abs(dev, ABS_RX, (__s16) (((__s16)data[17] << 8) | data[16])); input_report_abs(dev, ABS_RY, (__s16) (((__s16)data[19] << 8) | data[18])); - + /* triggers left/right */ input_report_abs(dev, ABS_Z, data[10]); input_report_abs(dev, ABS_RZ, data[11]); - + /* digital pad */ input_report_abs(dev, ABS_HAT0X, !!(data[2] & 0x08) - !!(data[2] & 0x04)); input_report_abs(dev, ABS_HAT0Y, !!(data[2] & 0x02) - !!(data[2] & 0x01)); - + /* start/back buttons and stick press left/right */ input_report_key(dev, BTN_START, (data[2] & 0x10) >> 4); input_report_key(dev, BTN_BACK, (data[2] & 0x20) >> 5); input_report_key(dev, BTN_THUMBL, (data[2] & 0x40) >> 6); input_report_key(dev, BTN_THUMBR, data[2] >> 7); - + /* "analog" buttons A, B, X, Y */ input_report_key(dev, BTN_A, data[4]); input_report_key(dev, BTN_B, data[5]); input_report_key(dev, BTN_X, data[6]); input_report_key(dev, BTN_Y, data[7]); - + /* "analog" buttons black, white */ input_report_key(dev, BTN_C, data[8]); input_report_key(dev, BTN_Z, data[9]); @@ -168,7 +168,7 @@ static void xpad_irq_in(struct urb *urb, struct pt_regs *regs) { struct usb_xpad *xpad = urb->context; int retval; - + switch (urb->status) { case 0: /* success */ @@ -183,7 +183,7 @@ static void xpad_irq_in(struct urb *urb, struct pt_regs *regs) dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); goto exit; } - + xpad_process_packet(xpad, 0, xpad->idata, regs); exit: @@ -196,137 +196,119 @@ exit: static int xpad_open (struct input_dev *dev) { struct usb_xpad *xpad = dev->private; - - if (xpad->open_count++) - return 0; - + xpad->irq_in->dev = xpad->udev; - if (usb_submit_urb(xpad->irq_in, GFP_KERNEL)) { - xpad->open_count--; + if (usb_submit_urb(xpad->irq_in, GFP_KERNEL)) return -EIO; - } - + return 0; } static void xpad_close (struct input_dev *dev) { struct usb_xpad *xpad = dev->private; - - if (!--xpad->open_count) - usb_kill_urb(xpad->irq_in); + + usb_kill_urb(xpad->irq_in); } static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *udev = interface_to_usbdev (intf); - struct usb_xpad *xpad = NULL; + struct usb_xpad *xpad; + struct input_dev *input_dev; struct usb_endpoint_descriptor *ep_irq_in; - char path[64]; int i; - + for (i = 0; xpad_device[i].idVendor; i++) { if ((le16_to_cpu(udev->descriptor.idVendor) == xpad_device[i].idVendor) && (le16_to_cpu(udev->descriptor.idProduct) == xpad_device[i].idProduct)) break; } - - if ((xpad = kmalloc (sizeof(struct usb_xpad), GFP_KERNEL)) == NULL) { - err("cannot allocate memory for new pad"); - return -ENOMEM; - } - memset(xpad, 0, sizeof(struct usb_xpad)); - + + xpad = kzalloc(sizeof(struct usb_xpad), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!xpad || !input_dev) + goto fail1; + xpad->idata = usb_buffer_alloc(udev, XPAD_PKT_LEN, SLAB_ATOMIC, &xpad->idata_dma); - if (!xpad->idata) { - kfree(xpad); - return -ENOMEM; - } + if (!xpad->idata) + goto fail1; xpad->irq_in = usb_alloc_urb(0, GFP_KERNEL); - if (!xpad->irq_in) { - err("cannot allocate memory for new pad irq urb"); - usb_buffer_free(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma); - kfree(xpad); - return -ENOMEM; - } - - ep_irq_in = &intf->cur_altsetting->endpoint[0].desc; - - usb_fill_int_urb(xpad->irq_in, udev, - usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress), - xpad->idata, XPAD_PKT_LEN, xpad_irq_in, - xpad, ep_irq_in->bInterval); - xpad->irq_in->transfer_dma = xpad->idata_dma; - xpad->irq_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - + if (!xpad->irq_in) + goto fail2; + xpad->udev = udev; - - xpad->dev.id.bustype = BUS_USB; - xpad->dev.id.vendor = le16_to_cpu(udev->descriptor.idVendor); - xpad->dev.id.product = le16_to_cpu(udev->descriptor.idProduct); - xpad->dev.id.version = le16_to_cpu(udev->descriptor.bcdDevice); - xpad->dev.dev = &intf->dev; - xpad->dev.private = xpad; - xpad->dev.name = xpad_device[i].name; - xpad->dev.phys = xpad->phys; - xpad->dev.open = xpad_open; - xpad->dev.close = xpad_close; - - usb_make_path(udev, path, 64); - snprintf(xpad->phys, 64, "%s/input0", path); - - xpad->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); - + xpad->dev = input_dev; + usb_make_path(udev, xpad->phys, sizeof(xpad->phys)); + strlcat(xpad->phys, "/input0", sizeof(xpad->phys)); + + input_dev->name = xpad_device[i].name; + input_dev->phys = xpad->phys; + usb_to_input_id(udev, &input_dev->id); + input_dev->cdev.dev = &intf->dev; + input_dev->private = xpad; + input_dev->open = xpad_open; + input_dev->close = xpad_close; + + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + for (i = 0; xpad_btn[i] >= 0; i++) - set_bit(xpad_btn[i], xpad->dev.keybit); - + set_bit(xpad_btn[i], input_dev->keybit); + for (i = 0; xpad_abs[i] >= 0; i++) { - + signed short t = xpad_abs[i]; - - set_bit(t, xpad->dev.absbit); - + + set_bit(t, input_dev->absbit); + switch (t) { case ABS_X: case ABS_Y: case ABS_RX: case ABS_RY: /* the two sticks */ - xpad->dev.absmax[t] = 32767; - xpad->dev.absmin[t] = -32768; - xpad->dev.absflat[t] = 128; - xpad->dev.absfuzz[t] = 16; + input_set_abs_params(input_dev, t, -32768, 32767, 16, 128); break; case ABS_Z: case ABS_RZ: /* the triggers */ - xpad->dev.absmax[t] = 255; - xpad->dev.absmin[t] = 0; + input_set_abs_params(input_dev, t, 0, 255, 0, 0); break; case ABS_HAT0X: case ABS_HAT0Y: /* the d-pad */ - xpad->dev.absmax[t] = 1; - xpad->dev.absmin[t] = -1; + input_set_abs_params(input_dev, t, -1, 1, 0, 0); break; } } - - input_register_device(&xpad->dev); - - printk(KERN_INFO "input: %s on %s", xpad->dev.name, path); - + + ep_irq_in = &intf->cur_altsetting->endpoint[0].desc; + usb_fill_int_urb(xpad->irq_in, udev, + usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress), + xpad->idata, XPAD_PKT_LEN, xpad_irq_in, + xpad, ep_irq_in->bInterval); + xpad->irq_in->transfer_dma = xpad->idata_dma; + xpad->irq_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + + input_register_device(xpad->dev); + usb_set_intfdata(intf, xpad); return 0; + +fail2: usb_buffer_free(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma); +fail1: input_free_device(input_dev); + kfree(xpad); + return -ENOMEM; + } static void xpad_disconnect(struct usb_interface *intf) { struct usb_xpad *xpad = usb_get_intfdata (intf); - + usb_set_intfdata(intf, NULL); if (xpad) { usb_kill_urb(xpad->irq_in); - input_unregister_device(&xpad->dev); + input_unregister_device(xpad->dev); usb_free_urb(xpad->irq_in); usb_buffer_free(interface_to_usbdev(intf), XPAD_PKT_LEN, xpad->idata, xpad->idata_dma); kfree(xpad); @@ -334,7 +316,6 @@ static void xpad_disconnect(struct usb_interface *intf) } static struct usb_driver xpad_driver = { - .owner = THIS_MODULE, .name = "xpad", .probe = xpad_probe, .disconnect = xpad_disconnect,