diff options
Diffstat (limited to 'drivers/usb/input/xpad.c')
-rw-r--r-- | drivers/usb/input/xpad.c | 95 |
1 files changed, 43 insertions, 52 deletions
diff --git a/drivers/usb/input/xpad.c b/drivers/usb/input/xpad.c index 18125e0bffa2..43112f040b6d 100644 --- a/drivers/usb/input/xpad.c +++ b/drivers/usb/input/xpad.c | |||
@@ -103,7 +103,7 @@ static struct usb_device_id xpad_table [] = { | |||
103 | MODULE_DEVICE_TABLE (usb, xpad_table); | 103 | MODULE_DEVICE_TABLE (usb, xpad_table); |
104 | 104 | ||
105 | struct usb_xpad { | 105 | struct usb_xpad { |
106 | struct input_dev dev; /* input device interface */ | 106 | struct input_dev *dev; /* input device interface */ |
107 | struct usb_device *udev; /* usb device */ | 107 | struct usb_device *udev; /* usb device */ |
108 | 108 | ||
109 | struct urb *irq_in; /* urb for interrupt in report */ | 109 | struct urb *irq_in; /* urb for interrupt in report */ |
@@ -125,7 +125,7 @@ struct usb_xpad { | |||
125 | 125 | ||
126 | static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *data, struct pt_regs *regs) | 126 | static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *data, struct pt_regs *regs) |
127 | { | 127 | { |
128 | struct input_dev *dev = &xpad->dev; | 128 | struct input_dev *dev = xpad->dev; |
129 | 129 | ||
130 | input_regs(dev, regs); | 130 | input_regs(dev, regs); |
131 | 131 | ||
@@ -214,9 +214,9 @@ static void xpad_close (struct input_dev *dev) | |||
214 | static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id) | 214 | static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id) |
215 | { | 215 | { |
216 | struct usb_device *udev = interface_to_usbdev (intf); | 216 | struct usb_device *udev = interface_to_usbdev (intf); |
217 | struct usb_xpad *xpad = NULL; | 217 | struct usb_xpad *xpad; |
218 | struct input_dev *input_dev; | ||
218 | struct usb_endpoint_descriptor *ep_irq_in; | 219 | struct usb_endpoint_descriptor *ep_irq_in; |
219 | char path[64]; | ||
220 | int i; | 220 | int i; |
221 | 221 | ||
222 | for (i = 0; xpad_device[i].idVendor; i++) { | 222 | for (i = 0; xpad_device[i].idVendor; i++) { |
@@ -225,89 +225,80 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
225 | break; | 225 | break; |
226 | } | 226 | } |
227 | 227 | ||
228 | if ((xpad = kmalloc (sizeof(struct usb_xpad), GFP_KERNEL)) == NULL) { | 228 | xpad = kzalloc(sizeof(struct usb_xpad), GFP_KERNEL); |
229 | err("cannot allocate memory for new pad"); | 229 | input_dev = input_allocate_device(); |
230 | return -ENOMEM; | 230 | if (!xpad || !input_dev) |
231 | } | 231 | goto fail1; |
232 | memset(xpad, 0, sizeof(struct usb_xpad)); | ||
233 | 232 | ||
234 | xpad->idata = usb_buffer_alloc(udev, XPAD_PKT_LEN, | 233 | xpad->idata = usb_buffer_alloc(udev, XPAD_PKT_LEN, |
235 | SLAB_ATOMIC, &xpad->idata_dma); | 234 | SLAB_ATOMIC, &xpad->idata_dma); |
236 | if (!xpad->idata) { | 235 | if (!xpad->idata) |
237 | kfree(xpad); | 236 | goto fail1; |
238 | return -ENOMEM; | ||
239 | } | ||
240 | 237 | ||
241 | xpad->irq_in = usb_alloc_urb(0, GFP_KERNEL); | 238 | xpad->irq_in = usb_alloc_urb(0, GFP_KERNEL); |
242 | if (!xpad->irq_in) { | 239 | if (!xpad->irq_in) |
243 | err("cannot allocate memory for new pad irq urb"); | 240 | goto fail2; |
244 | usb_buffer_free(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma); | ||
245 | kfree(xpad); | ||
246 | return -ENOMEM; | ||
247 | } | ||
248 | |||
249 | ep_irq_in = &intf->cur_altsetting->endpoint[0].desc; | ||
250 | |||
251 | usb_fill_int_urb(xpad->irq_in, udev, | ||
252 | usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress), | ||
253 | xpad->idata, XPAD_PKT_LEN, xpad_irq_in, | ||
254 | xpad, ep_irq_in->bInterval); | ||
255 | xpad->irq_in->transfer_dma = xpad->idata_dma; | ||
256 | xpad->irq_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | ||
257 | 241 | ||
258 | xpad->udev = udev; | 242 | xpad->udev = udev; |
243 | xpad->dev = input_dev; | ||
244 | usb_make_path(udev, xpad->phys, sizeof(xpad->phys)); | ||
245 | strlcat(xpad->phys, "/input0", sizeof(xpad->phys)); | ||
259 | 246 | ||
260 | usb_to_input_id(udev, &xpad->dev.id); | 247 | input_dev->name = xpad_device[i].name; |
261 | xpad->dev.dev = &intf->dev; | 248 | input_dev->phys = xpad->phys; |
262 | xpad->dev.private = xpad; | 249 | usb_to_input_id(udev, &input_dev->id); |
263 | xpad->dev.name = xpad_device[i].name; | 250 | input_dev->cdev.dev = &intf->dev; |
264 | xpad->dev.phys = xpad->phys; | 251 | input_dev->private = xpad; |
265 | xpad->dev.open = xpad_open; | 252 | input_dev->open = xpad_open; |
266 | xpad->dev.close = xpad_close; | 253 | input_dev->close = xpad_close; |
267 | |||
268 | usb_make_path(udev, path, 64); | ||
269 | snprintf(xpad->phys, 64, "%s/input0", path); | ||
270 | 254 | ||
271 | xpad->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); | 255 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); |
272 | 256 | ||
273 | for (i = 0; xpad_btn[i] >= 0; i++) | 257 | for (i = 0; xpad_btn[i] >= 0; i++) |
274 | set_bit(xpad_btn[i], xpad->dev.keybit); | 258 | set_bit(xpad_btn[i], input_dev->keybit); |
275 | 259 | ||
276 | for (i = 0; xpad_abs[i] >= 0; i++) { | 260 | for (i = 0; xpad_abs[i] >= 0; i++) { |
277 | 261 | ||
278 | signed short t = xpad_abs[i]; | 262 | signed short t = xpad_abs[i]; |
279 | 263 | ||
280 | set_bit(t, xpad->dev.absbit); | 264 | set_bit(t, input_dev->absbit); |
281 | 265 | ||
282 | switch (t) { | 266 | switch (t) { |
283 | case ABS_X: | 267 | case ABS_X: |
284 | case ABS_Y: | 268 | case ABS_Y: |
285 | case ABS_RX: | 269 | case ABS_RX: |
286 | case ABS_RY: /* the two sticks */ | 270 | case ABS_RY: /* the two sticks */ |
287 | xpad->dev.absmax[t] = 32767; | 271 | input_set_abs_params(input_dev, t, -32768, 32767, 16, 128); |
288 | xpad->dev.absmin[t] = -32768; | ||
289 | xpad->dev.absflat[t] = 128; | ||
290 | xpad->dev.absfuzz[t] = 16; | ||
291 | break; | 272 | break; |
292 | case ABS_Z: | 273 | case ABS_Z: |
293 | case ABS_RZ: /* the triggers */ | 274 | case ABS_RZ: /* the triggers */ |
294 | xpad->dev.absmax[t] = 255; | 275 | input_set_abs_params(input_dev, t, 0, 255, 0, 0); |
295 | xpad->dev.absmin[t] = 0; | ||
296 | break; | 276 | break; |
297 | case ABS_HAT0X: | 277 | case ABS_HAT0X: |
298 | case ABS_HAT0Y: /* the d-pad */ | 278 | case ABS_HAT0Y: /* the d-pad */ |
299 | xpad->dev.absmax[t] = 1; | 279 | input_set_abs_params(input_dev, t, -1, 1, 0, 0); |
300 | xpad->dev.absmin[t] = -1; | ||
301 | break; | 280 | break; |
302 | } | 281 | } |
303 | } | 282 | } |
304 | 283 | ||
305 | input_register_device(&xpad->dev); | 284 | ep_irq_in = &intf->cur_altsetting->endpoint[0].desc; |
285 | usb_fill_int_urb(xpad->irq_in, udev, | ||
286 | usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress), | ||
287 | xpad->idata, XPAD_PKT_LEN, xpad_irq_in, | ||
288 | xpad, ep_irq_in->bInterval); | ||
289 | xpad->irq_in->transfer_dma = xpad->idata_dma; | ||
290 | xpad->irq_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | ||
306 | 291 | ||
307 | printk(KERN_INFO "input: %s on %s", xpad->dev.name, path); | 292 | input_register_device(xpad->dev); |
308 | 293 | ||
309 | usb_set_intfdata(intf, xpad); | 294 | usb_set_intfdata(intf, xpad); |
310 | return 0; | 295 | return 0; |
296 | |||
297 | fail2: usb_buffer_free(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma); | ||
298 | fail1: input_free_device(input_dev); | ||
299 | kfree(xpad); | ||
300 | return -ENOMEM; | ||
301 | |||
311 | } | 302 | } |
312 | 303 | ||
313 | static void xpad_disconnect(struct usb_interface *intf) | 304 | static void xpad_disconnect(struct usb_interface *intf) |
@@ -317,7 +308,7 @@ static void xpad_disconnect(struct usb_interface *intf) | |||
317 | usb_set_intfdata(intf, NULL); | 308 | usb_set_intfdata(intf, NULL); |
318 | if (xpad) { | 309 | if (xpad) { |
319 | usb_kill_urb(xpad->irq_in); | 310 | usb_kill_urb(xpad->irq_in); |
320 | input_unregister_device(&xpad->dev); | 311 | input_unregister_device(xpad->dev); |
321 | usb_free_urb(xpad->irq_in); | 312 | usb_free_urb(xpad->irq_in); |
322 | usb_buffer_free(interface_to_usbdev(intf), XPAD_PKT_LEN, xpad->idata, xpad->idata_dma); | 313 | usb_buffer_free(interface_to_usbdev(intf), XPAD_PKT_LEN, xpad->idata, xpad->idata_dma); |
323 | kfree(xpad); | 314 | kfree(xpad); |