diff options
Diffstat (limited to 'drivers/usb/input/usbkbd.c')
-rw-r--r-- | drivers/usb/input/usbkbd.c | 105 |
1 files changed, 56 insertions, 49 deletions
diff --git a/drivers/usb/input/usbkbd.c b/drivers/usb/input/usbkbd.c index 28987f15eeee..226b6f90a907 100644 --- a/drivers/usb/input/usbkbd.c +++ b/drivers/usb/input/usbkbd.c | |||
@@ -66,7 +66,7 @@ static unsigned char usb_kbd_keycode[256] = { | |||
66 | }; | 66 | }; |
67 | 67 | ||
68 | struct usb_kbd { | 68 | struct usb_kbd { |
69 | struct input_dev dev; | 69 | struct input_dev *dev; |
70 | struct usb_device *usbdev; | 70 | struct usb_device *usbdev; |
71 | unsigned char old[8]; | 71 | unsigned char old[8]; |
72 | struct urb *irq, *led; | 72 | struct urb *irq, *led; |
@@ -99,29 +99,29 @@ static void usb_kbd_irq(struct urb *urb, struct pt_regs *regs) | |||
99 | goto resubmit; | 99 | goto resubmit; |
100 | } | 100 | } |
101 | 101 | ||
102 | input_regs(&kbd->dev, regs); | 102 | input_regs(kbd->dev, regs); |
103 | 103 | ||
104 | for (i = 0; i < 8; i++) | 104 | for (i = 0; i < 8; i++) |
105 | input_report_key(&kbd->dev, usb_kbd_keycode[i + 224], (kbd->new[0] >> i) & 1); | 105 | input_report_key(kbd->dev, usb_kbd_keycode[i + 224], (kbd->new[0] >> i) & 1); |
106 | 106 | ||
107 | for (i = 2; i < 8; i++) { | 107 | for (i = 2; i < 8; i++) { |
108 | 108 | ||
109 | if (kbd->old[i] > 3 && memscan(kbd->new + 2, kbd->old[i], 6) == kbd->new + 8) { | 109 | if (kbd->old[i] > 3 && memscan(kbd->new + 2, kbd->old[i], 6) == kbd->new + 8) { |
110 | if (usb_kbd_keycode[kbd->old[i]]) | 110 | if (usb_kbd_keycode[kbd->old[i]]) |
111 | input_report_key(&kbd->dev, usb_kbd_keycode[kbd->old[i]], 0); | 111 | input_report_key(kbd->dev, usb_kbd_keycode[kbd->old[i]], 0); |
112 | else | 112 | else |
113 | info("Unknown key (scancode %#x) released.", kbd->old[i]); | 113 | info("Unknown key (scancode %#x) released.", kbd->old[i]); |
114 | } | 114 | } |
115 | 115 | ||
116 | if (kbd->new[i] > 3 && memscan(kbd->old + 2, kbd->new[i], 6) == kbd->old + 8) { | 116 | if (kbd->new[i] > 3 && memscan(kbd->old + 2, kbd->new[i], 6) == kbd->old + 8) { |
117 | if (usb_kbd_keycode[kbd->new[i]]) | 117 | if (usb_kbd_keycode[kbd->new[i]]) |
118 | input_report_key(&kbd->dev, usb_kbd_keycode[kbd->new[i]], 1); | 118 | input_report_key(kbd->dev, usb_kbd_keycode[kbd->new[i]], 1); |
119 | else | 119 | else |
120 | info("Unknown key (scancode %#x) pressed.", kbd->new[i]); | 120 | info("Unknown key (scancode %#x) pressed.", kbd->new[i]); |
121 | } | 121 | } |
122 | } | 122 | } |
123 | 123 | ||
124 | input_sync(&kbd->dev); | 124 | input_sync(kbd->dev); |
125 | 125 | ||
126 | memcpy(kbd->old, kbd->new, 8); | 126 | memcpy(kbd->old, kbd->new, 8); |
127 | 127 | ||
@@ -227,12 +227,12 @@ static void usb_kbd_free_mem(struct usb_device *dev, struct usb_kbd *kbd) | |||
227 | static int usb_kbd_probe(struct usb_interface *iface, | 227 | static int usb_kbd_probe(struct usb_interface *iface, |
228 | const struct usb_device_id *id) | 228 | const struct usb_device_id *id) |
229 | { | 229 | { |
230 | struct usb_device * dev = interface_to_usbdev(iface); | 230 | struct usb_device *dev = interface_to_usbdev(iface); |
231 | struct usb_host_interface *interface; | 231 | struct usb_host_interface *interface; |
232 | struct usb_endpoint_descriptor *endpoint; | 232 | struct usb_endpoint_descriptor *endpoint; |
233 | struct usb_kbd *kbd; | 233 | struct usb_kbd *kbd; |
234 | struct input_dev *input_dev; | ||
234 | int i, pipe, maxp; | 235 | int i, pipe, maxp; |
235 | char path[64]; | ||
236 | 236 | ||
237 | interface = iface->cur_altsetting; | 237 | interface = iface->cur_altsetting; |
238 | 238 | ||
@@ -240,37 +240,59 @@ static int usb_kbd_probe(struct usb_interface *iface, | |||
240 | return -ENODEV; | 240 | return -ENODEV; |
241 | 241 | ||
242 | endpoint = &interface->endpoint[0].desc; | 242 | endpoint = &interface->endpoint[0].desc; |
243 | if (!(endpoint->bEndpointAddress & 0x80)) | 243 | if (!(endpoint->bEndpointAddress & USB_DIR_IN)) |
244 | return -ENODEV; | 244 | return -ENODEV; |
245 | if ((endpoint->bmAttributes & 3) != 3) | 245 | if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT) |
246 | return -ENODEV; | 246 | return -ENODEV; |
247 | 247 | ||
248 | pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); | 248 | pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); |
249 | maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); | 249 | maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); |
250 | 250 | ||
251 | if (!(kbd = kmalloc(sizeof(struct usb_kbd), GFP_KERNEL))) | 251 | kbd = kzalloc(sizeof(struct usb_kbd), GFP_KERNEL); |
252 | return -ENOMEM; | 252 | input_dev = input_allocate_device(); |
253 | memset(kbd, 0, sizeof(struct usb_kbd)); | 253 | if (!kbd || !input_dev) |
254 | goto fail1; | ||
254 | 255 | ||
255 | if (usb_kbd_alloc_mem(dev, kbd)) { | 256 | if (usb_kbd_alloc_mem(dev, kbd)) |
256 | usb_kbd_free_mem(dev, kbd); | 257 | goto fail2; |
257 | kfree(kbd); | ||
258 | return -ENOMEM; | ||
259 | } | ||
260 | 258 | ||
261 | kbd->usbdev = dev; | 259 | kbd->usbdev = dev; |
260 | kbd->dev = input_dev; | ||
261 | |||
262 | if (dev->manufacturer) | ||
263 | strlcpy(kbd->name, dev->manufacturer, sizeof(kbd->name)); | ||
264 | |||
265 | if (dev->product) { | ||
266 | if (dev->manufacturer) | ||
267 | strlcat(kbd->name, " ", sizeof(kbd->name)); | ||
268 | strlcat(kbd->name, dev->product, sizeof(kbd->name)); | ||
269 | } | ||
270 | |||
271 | if (!strlen(kbd->name)) | ||
272 | snprintf(kbd->name, sizeof(kbd->name), | ||
273 | "USB HIDBP Keyboard %04x:%04x", | ||
274 | le16_to_cpu(dev->descriptor.idVendor), | ||
275 | le16_to_cpu(dev->descriptor.idProduct)); | ||
276 | |||
277 | usb_make_path(dev, kbd->phys, sizeof(kbd->phys)); | ||
278 | strlcpy(kbd->phys, "/input0", sizeof(kbd->phys)); | ||
262 | 279 | ||
263 | kbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_REP); | 280 | input_dev->name = kbd->name; |
264 | kbd->dev.ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL) | BIT(LED_COMPOSE) | BIT(LED_KANA); | 281 | input_dev->phys = kbd->phys; |
282 | usb_to_input_id(dev, &input_dev->id); | ||
283 | input_dev->cdev.dev = &iface->dev; | ||
284 | input_dev->private = kbd; | ||
285 | |||
286 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_REP); | ||
287 | input_dev->ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL) | BIT(LED_COMPOSE) | BIT(LED_KANA); | ||
265 | 288 | ||
266 | for (i = 0; i < 255; i++) | 289 | for (i = 0; i < 255; i++) |
267 | set_bit(usb_kbd_keycode[i], kbd->dev.keybit); | 290 | set_bit(usb_kbd_keycode[i], input_dev->keybit); |
268 | clear_bit(0, kbd->dev.keybit); | 291 | clear_bit(0, input_dev->keybit); |
269 | 292 | ||
270 | kbd->dev.private = kbd; | 293 | input_dev->event = usb_kbd_event; |
271 | kbd->dev.event = usb_kbd_event; | 294 | input_dev->open = usb_kbd_open; |
272 | kbd->dev.open = usb_kbd_open; | 295 | input_dev->close = usb_kbd_close; |
273 | kbd->dev.close = usb_kbd_close; | ||
274 | 296 | ||
275 | usb_fill_int_urb(kbd->irq, dev, pipe, | 297 | usb_fill_int_urb(kbd->irq, dev, pipe, |
276 | kbd->new, (maxp > 8 ? 8 : maxp), | 298 | kbd->new, (maxp > 8 ? 8 : maxp), |
@@ -284,37 +306,22 @@ static int usb_kbd_probe(struct usb_interface *iface, | |||
284 | kbd->cr->wIndex = cpu_to_le16(interface->desc.bInterfaceNumber); | 306 | kbd->cr->wIndex = cpu_to_le16(interface->desc.bInterfaceNumber); |
285 | kbd->cr->wLength = cpu_to_le16(1); | 307 | kbd->cr->wLength = cpu_to_le16(1); |
286 | 308 | ||
287 | usb_make_path(dev, path, 64); | ||
288 | sprintf(kbd->phys, "%s/input0", path); | ||
289 | |||
290 | kbd->dev.name = kbd->name; | ||
291 | kbd->dev.phys = kbd->phys; | ||
292 | usb_to_input_id(dev, &kbd->dev.id); | ||
293 | kbd->dev.dev = &iface->dev; | ||
294 | |||
295 | if (dev->manufacturer) | ||
296 | strcat(kbd->name, dev->manufacturer); | ||
297 | if (dev->product) | ||
298 | sprintf(kbd->name, "%s %s", kbd->name, dev->product); | ||
299 | |||
300 | if (!strlen(kbd->name)) | ||
301 | sprintf(kbd->name, "USB HIDBP Keyboard %04x:%04x", | ||
302 | kbd->dev.id.vendor, kbd->dev.id.product); | ||
303 | |||
304 | usb_fill_control_urb(kbd->led, dev, usb_sndctrlpipe(dev, 0), | 309 | usb_fill_control_urb(kbd->led, dev, usb_sndctrlpipe(dev, 0), |
305 | (void *) kbd->cr, kbd->leds, 1, | 310 | (void *) kbd->cr, kbd->leds, 1, |
306 | usb_kbd_led, kbd); | 311 | usb_kbd_led, kbd); |
307 | kbd->led->setup_dma = kbd->cr_dma; | 312 | kbd->led->setup_dma = kbd->cr_dma; |
308 | kbd->led->transfer_dma = kbd->leds_dma; | 313 | kbd->led->transfer_dma = kbd->leds_dma; |
309 | kbd->led->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | 314 | kbd->led->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP); |
310 | | URB_NO_SETUP_DMA_MAP); | ||
311 | 315 | ||
312 | input_register_device(&kbd->dev); | 316 | input_register_device(kbd->dev); |
313 | |||
314 | printk(KERN_INFO "input: %s on %s\n", kbd->name, path); | ||
315 | 317 | ||
316 | usb_set_intfdata(iface, kbd); | 318 | usb_set_intfdata(iface, kbd); |
317 | return 0; | 319 | return 0; |
320 | |||
321 | fail2: usb_kbd_free_mem(dev, kbd); | ||
322 | fail1: input_free_device(input_dev); | ||
323 | kfree(kbd); | ||
324 | return -ENOMEM; | ||
318 | } | 325 | } |
319 | 326 | ||
320 | static void usb_kbd_disconnect(struct usb_interface *intf) | 327 | static void usb_kbd_disconnect(struct usb_interface *intf) |
@@ -324,7 +331,7 @@ static void usb_kbd_disconnect(struct usb_interface *intf) | |||
324 | usb_set_intfdata(intf, NULL); | 331 | usb_set_intfdata(intf, NULL); |
325 | if (kbd) { | 332 | if (kbd) { |
326 | usb_kill_urb(kbd->irq); | 333 | usb_kill_urb(kbd->irq); |
327 | input_unregister_device(&kbd->dev); | 334 | input_unregister_device(kbd->dev); |
328 | usb_kbd_free_mem(interface_to_usbdev(intf), kbd); | 335 | usb_kbd_free_mem(interface_to_usbdev(intf), kbd); |
329 | kfree(kbd); | 336 | kfree(kbd); |
330 | } | 337 | } |