~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/drivers/usb/usbkbd.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * $Id: usbkbd.c,v 1.16 2000/08/14 21:05:26 vojtech Exp $
  3  *
  4  *  Copyright (c) 1999-2000 Vojtech Pavlik
  5  *
  6  *  USB HIDBP Keyboard support
  7  *
  8  *  Sponsored by SuSE
  9  */
 10 
 11 /*
 12  * This program is free software; you can redistribute it and/or modify
 13  * it under the terms of the GNU General Public License as published by
 14  * the Free Software Foundation; either version 2 of the License, or 
 15  * (at your option) any later version.
 16  * 
 17  * This program is distributed in the hope that it will be useful,
 18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 20  * GNU General Public License for more details.
 21  * 
 22  * You should have received a copy of the GNU General Public License
 23  * along with this program; if not, write to the Free Software
 24  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 25  * 
 26  * Should you need to contact me, the author, you can do so either by
 27  * e-mail - mail your message to <vojtech@suse.cz>, or by paper mail:
 28  * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
 29  */
 30 
 31 #include <linux/kernel.h>
 32 #include <linux/malloc.h>
 33 #include <linux/module.h>
 34 #include <linux/input.h>
 35 #include <linux/init.h>
 36 #include <linux/usb.h>
 37 
 38 MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
 39 MODULE_DESCRIPTION("USB HID Boot Protocol keyboard driver");
 40 
 41 static unsigned char usb_kbd_keycode[256] = {
 42           0,  0,  0,  0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38,
 43          50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44,  2,  3,
 44           4,  5,  6,  7,  8,  9, 10, 11, 28,  1, 14, 15, 57, 12, 13, 26,
 45          27, 43, 84, 39, 40, 41, 51, 52, 53, 58, 59, 60, 61, 62, 63, 64,
 46          65, 66, 67, 68, 87, 88, 99, 70,119,110,102,104,111,107,109,106,
 47         105,108,103, 69, 98, 55, 74, 78, 96, 79, 80, 81, 75, 76, 77, 71,
 48          72, 73, 82, 83, 86,127,116,117, 85, 89, 90, 91, 92, 93, 94, 95,
 49         120,121,122,123,134,138,130,132,128,129,131,137,133,135,136,113,
 50         115,114,  0,  0,  0,124,  0,181,182,183,184,185,186,187,188,189,
 51         190,191,192,193,194,195,196,197,198,  0,  0,  0,  0,  0,  0,  0,
 52           0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
 53           0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
 54           0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
 55           0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
 56          29, 42, 56,125, 97, 54,100,126,164,166,165,163,161,115,114,113,
 57         150,158,159,128,136,177,178,176,142,152,173,140
 58 };
 59 
 60 struct usb_kbd {
 61         struct input_dev dev;
 62         struct usb_device *usbdev;
 63         unsigned char new[8];
 64         unsigned char old[8];
 65         struct urb irq, led;
 66         devrequest dr;
 67         unsigned char leds, newleds;
 68         char name[128];
 69         int open;
 70 };
 71 
 72 static void usb_kbd_irq(struct urb *urb)
 73 {
 74         struct usb_kbd *kbd = urb->context;
 75         int i;
 76 
 77         if (urb->status) return;
 78 
 79         for (i = 0; i < 8; i++)
 80                 input_report_key(&kbd->dev, usb_kbd_keycode[i + 224], (kbd->new[0] >> i) & 1);
 81 
 82         for (i = 2; i < 8; i++) {
 83 
 84                 if (kbd->old[i] > 3 && memscan(kbd->new + 2, kbd->old[i], 6) == kbd->new + 8) {
 85                         if (usb_kbd_keycode[kbd->old[i]])
 86                                 input_report_key(&kbd->dev, usb_kbd_keycode[kbd->old[i]], 0);
 87                         else
 88                                 info("Unknown key (scancode %#x) released.", kbd->old[i]);
 89                 }
 90 
 91                 if (kbd->new[i] > 3 && memscan(kbd->old + 2, kbd->new[i], 6) == kbd->old + 8) {
 92                         if (usb_kbd_keycode[kbd->new[i]])
 93                                 input_report_key(&kbd->dev, usb_kbd_keycode[kbd->new[i]], 1);
 94                         else
 95                                 info("Unknown key (scancode %#x) pressed.", kbd->new[i]);
 96                 }
 97         }
 98 
 99         memcpy(kbd->old, kbd->new, 8);
100 }
101 
102 int usb_kbd_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
103 {
104         struct usb_kbd *kbd = dev->private;
105 
106         if (type != EV_LED) return -1;
107 
108 
109         kbd->newleds = (!!test_bit(LED_KANA,    dev->led) << 3) | (!!test_bit(LED_COMPOSE, dev->led) << 3) |
110                        (!!test_bit(LED_SCROLLL, dev->led) << 2) | (!!test_bit(LED_CAPSL,   dev->led) << 1) |
111                        (!!test_bit(LED_NUML,    dev->led));
112 
113         if (kbd->led.status == -EINPROGRESS)
114                 return 0;
115 
116         if (kbd->leds == kbd->newleds)
117                 return 0;
118 
119         kbd->leds = kbd->newleds;
120         kbd->led.dev = kbd->usbdev;
121         if (usb_submit_urb(&kbd->led))
122                 err("usb_submit_urb(leds) failed");
123 
124         return 0;
125 }
126 
127 static void usb_kbd_led(struct urb *urb)
128 {
129         struct usb_kbd *kbd = urb->context;
130 
131         if (urb->status)
132                 warn("led urb status %d received", urb->status);
133         
134         if (kbd->leds == kbd->newleds)
135                 return;
136 
137         kbd->leds = kbd->newleds;
138         kbd->led.dev = kbd->usbdev;
139         if (usb_submit_urb(&kbd->led))
140                 err("usb_submit_urb(leds) failed");
141 }
142 
143 static int usb_kbd_open(struct input_dev *dev)
144 {
145         struct usb_kbd *kbd = dev->private;
146 
147         if (kbd->open++)
148                 return 0;
149 
150         kbd->irq.dev = kbd->usbdev;
151         if (usb_submit_urb(&kbd->irq))
152                 return -EIO;
153 
154         return 0;
155 }
156 
157 static void usb_kbd_close(struct input_dev *dev)
158 {
159         struct usb_kbd *kbd = dev->private;
160 
161         if (!--kbd->open)
162                 usb_unlink_urb(&kbd->irq);
163 }
164 
165 static void *usb_kbd_probe(struct usb_device *dev, unsigned int ifnum,
166                            const struct usb_device_id *id)
167 {
168         struct usb_interface *iface;
169         struct usb_interface_descriptor *interface;
170         struct usb_endpoint_descriptor *endpoint;
171         struct usb_kbd *kbd;
172         int i, pipe, maxp;
173         char *buf;
174 
175         iface = &dev->actconfig->interface[ifnum];
176         interface = &iface->altsetting[iface->act_altsetting];
177 
178         if (interface->bNumEndpoints != 1) return NULL;
179 
180         endpoint = interface->endpoint + 0;
181         if (!(endpoint->bEndpointAddress & 0x80)) return NULL;
182         if ((endpoint->bmAttributes & 3) != 3) return NULL;
183 
184         pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
185         maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
186 
187         usb_set_protocol(dev, interface->bInterfaceNumber, 0);
188         usb_set_idle(dev, interface->bInterfaceNumber, 0, 0);
189 
190         if (!(kbd = kmalloc(sizeof(struct usb_kbd), GFP_KERNEL))) return NULL;
191         memset(kbd, 0, sizeof(struct usb_kbd));
192 
193         kbd->usbdev = dev;
194 
195         kbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_REP);
196         kbd->dev.ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL) | BIT(LED_COMPOSE) | BIT(LED_KANA);
197 
198         for (i = 0; i < 255; i++)
199                 set_bit(usb_kbd_keycode[i], kbd->dev.keybit);
200         clear_bit(0, kbd->dev.keybit);
201         
202         kbd->dev.private = kbd;
203         kbd->dev.event = usb_kbd_event;
204         kbd->dev.open = usb_kbd_open;
205         kbd->dev.close = usb_kbd_close;
206 
207         FILL_INT_URB(&kbd->irq, dev, pipe, kbd->new, maxp > 8 ? 8 : maxp,
208                 usb_kbd_irq, kbd, endpoint->bInterval);
209 
210         kbd->dr.requesttype = USB_TYPE_CLASS | USB_RECIP_INTERFACE;
211         kbd->dr.request = USB_REQ_SET_REPORT;
212         kbd->dr.value = 0x200;
213         kbd->dr.index = interface->bInterfaceNumber;
214         kbd->dr.length = 1;
215 
216         kbd->dev.name = kbd->name;
217         kbd->dev.idbus = BUS_USB;
218         kbd->dev.idvendor = dev->descriptor.idVendor;
219         kbd->dev.idproduct = dev->descriptor.idProduct;
220         kbd->dev.idversion = dev->descriptor.bcdDevice;
221 
222         if (!(buf = kmalloc(63, GFP_KERNEL))) {
223                 kfree(kbd);
224                 return NULL;
225         }
226 
227         if (dev->descriptor.iManufacturer &&
228                 usb_string(dev, dev->descriptor.iManufacturer, buf, 63) > 0)
229                         strcat(kbd->name, buf);
230         if (dev->descriptor.iProduct &&
231                 usb_string(dev, dev->descriptor.iProduct, buf, 63) > 0)
232                         sprintf(kbd->name, "%s %s", kbd->name, buf);
233 
234         if (!strlen(kbd->name))
235                 sprintf(kbd->name, "USB HIDBP Keyboard %04x:%04x",
236                         kbd->dev.idvendor, kbd->dev.idproduct);
237 
238         kfree(buf);
239 
240         FILL_CONTROL_URB(&kbd->led, dev, usb_sndctrlpipe(dev, 0),
241                 (void*) &kbd->dr, &kbd->leds, 1, usb_kbd_led, kbd);
242                         
243         input_register_device(&kbd->dev);
244 
245         printk(KERN_INFO "input%d: %s on on usb%d:%d.%d\n",
246                  kbd->dev.number, kbd->name, dev->bus->busnum, dev->devnum, ifnum);
247 
248         return kbd;
249 }
250 
251 static void usb_kbd_disconnect(struct usb_device *dev, void *ptr)
252 {
253         struct usb_kbd *kbd = ptr;
254         usb_unlink_urb(&kbd->irq);
255         input_unregister_device(&kbd->dev);
256         kfree(kbd);
257 }
258 
259 static struct usb_device_id usb_kbd_id_table [] = {
260         { USB_INTERFACE_INFO(3, 1, 1) },
261         { }                                             /* Terminating entry */
262 };
263 
264 MODULE_DEVICE_TABLE (usb, usb_kbd_id_table);
265 
266 static struct usb_driver usb_kbd_driver = {
267         name:           "keyboard",
268         probe:          usb_kbd_probe,
269         disconnect:     usb_kbd_disconnect,
270         id_table:       usb_kbd_id_table,
271 };
272 
273 static int __init usb_kbd_init(void)
274 {
275         usb_register(&usb_kbd_driver);
276         return 0;
277 }
278 
279 static void __exit usb_kbd_exit(void)
280 {
281         usb_deregister(&usb_kbd_driver);
282 }
283 
284 module_init(usb_kbd_init);
285 module_exit(usb_kbd_exit);
286 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.