Lines Matching +full:led +full:- +full:8
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (c) 1999-2001 Vojtech Pavlik
11 * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
12 * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
38 4, 5, 6, 7, 8, 9, 10, 11, 28, 1, 14, 15, 57, 12, 13, 26,
56 * struct usb_kbd - state of each attached keyboard
64 * @led: URB for sending LEDs (e.g. numlock, ...)
65 * @newleds: data that will be sent with the @led URB representing which LEDs
71 * @cr: Control request for @led URB
72 * @leds: Buffer for the @led URB
74 * @leds_dma: DMA address for @led URB
76 * @led_urb_submitted: indicates whether @led is in progress, i.e. it has been
78 * without resubmitting @led
83 unsigned char old[8];
84 struct urb *irq, *led; member
102 struct usb_kbd *kbd = urb->context; in usb_kbd_irq()
105 switch (urb->status) { in usb_kbd_irq()
108 case -ECONNRESET: /* unlink */ in usb_kbd_irq()
109 case -ENOENT: in usb_kbd_irq()
110 case -ESHUTDOWN: in usb_kbd_irq()
112 /* -EPIPE: should clear the halt */ in usb_kbd_irq()
117 for (i = 0; i < 8; i++) in usb_kbd_irq()
118 input_report_key(kbd->dev, usb_kbd_keycode[i + 224], (kbd->new[0] >> i) & 1); in usb_kbd_irq()
120 for (i = 2; i < 8; i++) { in usb_kbd_irq()
122 if (kbd->old[i] > 3 && memscan(kbd->new + 2, kbd->old[i], 6) == kbd->new + 8) { in usb_kbd_irq()
123 if (usb_kbd_keycode[kbd->old[i]]) in usb_kbd_irq()
124 input_report_key(kbd->dev, usb_kbd_keycode[kbd->old[i]], 0); in usb_kbd_irq()
126 hid_info(urb->dev, in usb_kbd_irq()
128 kbd->old[i]); in usb_kbd_irq()
131 if (kbd->new[i] > 3 && memscan(kbd->old + 2, kbd->new[i], 6) == kbd->old + 8) { in usb_kbd_irq()
132 if (usb_kbd_keycode[kbd->new[i]]) in usb_kbd_irq()
133 input_report_key(kbd->dev, usb_kbd_keycode[kbd->new[i]], 1); in usb_kbd_irq()
135 hid_info(urb->dev, in usb_kbd_irq()
137 kbd->new[i]); in usb_kbd_irq()
141 input_sync(kbd->dev); in usb_kbd_irq()
143 memcpy(kbd->old, kbd->new, 8); in usb_kbd_irq()
148 hid_err(urb->dev, "can't resubmit intr, %s-%s/input0, status %d", in usb_kbd_irq()
149 kbd->usbdev->bus->bus_name, in usb_kbd_irq()
150 kbd->usbdev->devpath, i); in usb_kbd_irq()
160 return -1; in usb_kbd_event()
162 spin_lock_irqsave(&kbd->leds_lock, flags); in usb_kbd_event()
163 …kbd->newleds = (!!test_bit(LED_KANA, dev->led) << 3) | (!!test_bit(LED_COMPOSE, dev->led) << 3)… in usb_kbd_event()
164 (!!test_bit(LED_SCROLLL, dev->led) << 2) | (!!test_bit(LED_CAPSL, dev->led) << 1) | in usb_kbd_event()
165 (!!test_bit(LED_NUML, dev->led)); in usb_kbd_event()
167 if (kbd->led_urb_submitted){ in usb_kbd_event()
168 spin_unlock_irqrestore(&kbd->leds_lock, flags); in usb_kbd_event()
172 if (*(kbd->leds) == kbd->newleds){ in usb_kbd_event()
173 spin_unlock_irqrestore(&kbd->leds_lock, flags); in usb_kbd_event()
177 *(kbd->leds) = kbd->newleds; in usb_kbd_event()
179 kbd->led->dev = kbd->usbdev; in usb_kbd_event()
180 if (usb_submit_urb(kbd->led, GFP_ATOMIC)) in usb_kbd_event()
183 kbd->led_urb_submitted = true; in usb_kbd_event()
185 spin_unlock_irqrestore(&kbd->leds_lock, flags); in usb_kbd_event()
193 struct usb_kbd *kbd = urb->context; in usb_kbd_led()
195 if (urb->status) in usb_kbd_led()
196 hid_warn(urb->dev, "led urb status %d received\n", in usb_kbd_led()
197 urb->status); in usb_kbd_led()
199 spin_lock_irqsave(&kbd->leds_lock, flags); in usb_kbd_led()
201 if (*(kbd->leds) == kbd->newleds){ in usb_kbd_led()
202 kbd->led_urb_submitted = false; in usb_kbd_led()
203 spin_unlock_irqrestore(&kbd->leds_lock, flags); in usb_kbd_led()
207 *(kbd->leds) = kbd->newleds; in usb_kbd_led()
209 kbd->led->dev = kbd->usbdev; in usb_kbd_led()
210 if (usb_submit_urb(kbd->led, GFP_ATOMIC)){ in usb_kbd_led()
211 hid_err(urb->dev, "usb_submit_urb(leds) failed\n"); in usb_kbd_led()
212 kbd->led_urb_submitted = false; in usb_kbd_led()
214 spin_unlock_irqrestore(&kbd->leds_lock, flags); in usb_kbd_led()
222 kbd->irq->dev = kbd->usbdev; in usb_kbd_open()
223 if (usb_submit_urb(kbd->irq, GFP_KERNEL)) in usb_kbd_open()
224 return -EIO; in usb_kbd_open()
233 usb_kill_urb(kbd->irq); in usb_kbd_close()
238 if (!(kbd->irq = usb_alloc_urb(0, GFP_KERNEL))) in usb_kbd_alloc_mem()
239 return -1; in usb_kbd_alloc_mem()
240 if (!(kbd->led = usb_alloc_urb(0, GFP_KERNEL))) in usb_kbd_alloc_mem()
241 return -1; in usb_kbd_alloc_mem()
242 if (!(kbd->new = usb_alloc_coherent(dev, 8, GFP_ATOMIC, &kbd->new_dma))) in usb_kbd_alloc_mem()
243 return -1; in usb_kbd_alloc_mem()
244 if (!(kbd->cr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL))) in usb_kbd_alloc_mem()
245 return -1; in usb_kbd_alloc_mem()
246 if (!(kbd->leds = usb_alloc_coherent(dev, 1, GFP_ATOMIC, &kbd->leds_dma))) in usb_kbd_alloc_mem()
247 return -1; in usb_kbd_alloc_mem()
254 usb_free_urb(kbd->irq); in usb_kbd_free_mem()
255 usb_free_urb(kbd->led); in usb_kbd_free_mem()
256 usb_free_coherent(dev, 8, kbd->new, kbd->new_dma); in usb_kbd_free_mem()
257 kfree(kbd->cr); in usb_kbd_free_mem()
258 usb_free_coherent(dev, 1, kbd->leds, kbd->leds_dma); in usb_kbd_free_mem()
270 int error = -ENOMEM; in usb_kbd_probe()
272 interface = iface->cur_altsetting; in usb_kbd_probe()
274 if (interface->desc.bNumEndpoints != 1) in usb_kbd_probe()
275 return -ENODEV; in usb_kbd_probe()
277 endpoint = &interface->endpoint[0].desc; in usb_kbd_probe()
279 return -ENODEV; in usb_kbd_probe()
281 pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); in usb_kbd_probe()
292 kbd->usbdev = dev; in usb_kbd_probe()
293 kbd->dev = input_dev; in usb_kbd_probe()
294 spin_lock_init(&kbd->leds_lock); in usb_kbd_probe()
296 if (dev->manufacturer) in usb_kbd_probe()
297 strlcpy(kbd->name, dev->manufacturer, sizeof(kbd->name)); in usb_kbd_probe()
299 if (dev->product) { in usb_kbd_probe()
300 if (dev->manufacturer) in usb_kbd_probe()
301 strlcat(kbd->name, " ", sizeof(kbd->name)); in usb_kbd_probe()
302 strlcat(kbd->name, dev->product, sizeof(kbd->name)); in usb_kbd_probe()
305 if (!strlen(kbd->name)) in usb_kbd_probe()
306 snprintf(kbd->name, sizeof(kbd->name), in usb_kbd_probe()
308 le16_to_cpu(dev->descriptor.idVendor), in usb_kbd_probe()
309 le16_to_cpu(dev->descriptor.idProduct)); in usb_kbd_probe()
311 usb_make_path(dev, kbd->phys, sizeof(kbd->phys)); in usb_kbd_probe()
312 strlcat(kbd->phys, "/input0", sizeof(kbd->phys)); in usb_kbd_probe()
314 input_dev->name = kbd->name; in usb_kbd_probe()
315 input_dev->phys = kbd->phys; in usb_kbd_probe()
316 usb_to_input_id(dev, &input_dev->id); in usb_kbd_probe()
317 input_dev->dev.parent = &iface->dev; in usb_kbd_probe()
321 input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_LED) | in usb_kbd_probe()
323 input_dev->ledbit[0] = BIT_MASK(LED_NUML) | BIT_MASK(LED_CAPSL) | in usb_kbd_probe()
328 set_bit(usb_kbd_keycode[i], input_dev->keybit); in usb_kbd_probe()
329 clear_bit(0, input_dev->keybit); in usb_kbd_probe()
331 input_dev->event = usb_kbd_event; in usb_kbd_probe()
332 input_dev->open = usb_kbd_open; in usb_kbd_probe()
333 input_dev->close = usb_kbd_close; in usb_kbd_probe()
335 usb_fill_int_urb(kbd->irq, dev, pipe, in usb_kbd_probe()
336 kbd->new, (maxp > 8 ? 8 : maxp), in usb_kbd_probe()
337 usb_kbd_irq, kbd, endpoint->bInterval); in usb_kbd_probe()
338 kbd->irq->transfer_dma = kbd->new_dma; in usb_kbd_probe()
339 kbd->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; in usb_kbd_probe()
341 kbd->cr->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE; in usb_kbd_probe()
342 kbd->cr->bRequest = 0x09; in usb_kbd_probe()
343 kbd->cr->wValue = cpu_to_le16(0x200); in usb_kbd_probe()
344 kbd->cr->wIndex = cpu_to_le16(interface->desc.bInterfaceNumber); in usb_kbd_probe()
345 kbd->cr->wLength = cpu_to_le16(1); in usb_kbd_probe()
347 usb_fill_control_urb(kbd->led, dev, usb_sndctrlpipe(dev, 0), in usb_kbd_probe()
348 (void *) kbd->cr, kbd->leds, 1, in usb_kbd_probe()
350 kbd->led->transfer_dma = kbd->leds_dma; in usb_kbd_probe()
351 kbd->led->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; in usb_kbd_probe()
353 error = input_register_device(kbd->dev); in usb_kbd_probe()
358 device_set_wakeup_enable(&dev->dev, 1); in usb_kbd_probe()
375 usb_kill_urb(kbd->irq); in usb_kbd_disconnect()
376 input_unregister_device(kbd->dev); in usb_kbd_disconnect()
377 usb_kill_urb(kbd->led); in usb_kbd_disconnect()