Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  1 /*
  2  * Hardware event => input event mapping:
  3  *
  4  *
  5  *
  6  input.h:#define BTN_TOOL_PEN            0x140 black
  7  input.h:#define BTN_TOOL_RUBBER         0x141 blue
  8  input.h:#define BTN_TOOL_BRUSH          0x142 green
  9  input.h:#define BTN_TOOL_PENCIL         0x143 red
 10  input.h:#define BTN_TOOL_AIRBRUSH       0x144 eraser
 11  input.h:#define BTN_TOOL_FINGER         0x145 small eraser
 12  input.h:#define BTN_TOOL_MOUSE          0x146 mimio interactive
 13  input.h:#define BTN_TOOL_LENS           0x147 mimio interactive but1
 14  input.h:#define LOCALBTN_TOOL_EXTRA1    0x14a mimio interactive but2 == BTN_TOUCH
 15  input.h:#define LOCALBTN_TOOL_EXTRA2    0x14b mimio extra pens (orange, brown, yellow, purple) == BTN_STYLUS
 16  input.h:#define LOCALBTN_TOOL_EXTRA3    0x14c unused == BTN_STYLUS2
 17  input.h:#define BTN_TOOL_DOUBLETAP      0x14d unused
 18  input.h:#define BTN_TOOL_TRIPLETAP      0x14e unused
 19  *
 20  * MIMIO_EV_PENDOWN(MIMIO_PEN_K)     => EV_KEY BIT(BTN_TOOL_PEN)
 21  * MIMIO_EV_PENDOWN(MIMIO_PEN_B)     => EV_KEY BIT(BTN_TOOL_RUBBER)
 22  * MIMIO_EV_PENDOWN(MIMIO_PEN_G)     => EV_KEY BIT(BTN_TOOL_BRUSH)
 23  * MIMIO_EV_PENDOWN(MIMIO_PEN_R)     => EV_KEY BIT(BTN_TOOL_PENCIL)
 24  * MIMIO_EV_PENDOWN(MIMIO_PEN_E)     => EV_KEY BIT(BTN_TOOL_AIRBRUSH)
 25  * MIMIO_EV_PENDOWN(MIMIO_PEN_ES)    => EV_KEY BIT(BTN_TOOL_FINGER)
 26  * MIMIO_EV_PENDOWN(MIMIO_PEN_I)     => EV_KEY BIT(BTN_TOOL_MOUSE)
 27  * MIMIO_EV_PENDOWN(MIMIO_PEN_IL)    => EV_KEY BIT(BTN_TOOL_LENS)
 28  * MIMIO_EV_PENDOWN(MIMIO_PEN_IR)    => EV_KEY BIT(BTN_TOOL_DOUBLETAP)
 29  * MIMIO_EV_PENDOWN(MIMIO_PEN_EX)    => EV_KEY BIT(BTN_TOOL_TRIPLETAP)
 30  * MIMIO_EV_PENDATA                 => EV_ABS BIT(ABS_X), BIT(ABS_Y)
 31  * MIMIO_EV_MEMRESET              => EV_KEY BIT(BTN_0)
 32  * MIMIO_EV_ACC(ACC_NEWPAGE)       => EV_KEY BIT(BTN_1)
 33  * MIMIO_EV_ACC(ACC_TAGPAGE)      => EV_KEY BIT(BTN_2)
 34  * MIMIO_EV_ACC(ACC_PRINTPAGE)      => EV_KEY BIT(BTN_3)
 35  * MIMIO_EV_ACC(ACC_MAXIMIZE)      => EV_KEY BIT(BTN_4)
 36  * MIMIO_EV_ACC(ACC_FINDCTLPNL)      => EV_KEY BIT(BTN_5)
 37  *
 38  *
 39  * open issues:
 40  *      - cold-load of data captured when mimio in standalone mode not yet
 41  *         supported; need to snoop Win32 box to see datastream for this.
 42  *       - mimio mouse not yet supported; need to snoop Win32 box to see the
 43  *         datastream for this.
 44  */
 45 #include <linux/kernel.h>
 46 #include <linux/init.h>
 47 #include <linux/slab.h>
 48 #include <linux/spinlock.h>
 49 #include <linux/input.h>
 50 #include <linux/usb.h>
 51 
 52 #define DRIVER_VERSION          "v0.031"
 53 #define DRIVER_AUTHOR           "mwilder@cs.nmsu.edu"
 54 #define DRIVER_DESC             "USB mimio-xi driver"
 55 
 56 enum {UPVALUE, DOWNVALUE, MOVEVALUE};
 57 
 58 #define MIMIO_XRANGE_MAX        9600
 59 #define MIMIO_YRANGE_MAX        4800
 60 
 61 #define LOCALBTN_TOOL_EXTRA1    BTN_TOUCH
 62 #define LOCALBTN_TOOL_EXTRA2    BTN_STYLUS
 63 #define LOCALBTN_TOOL_EXTRA3    BTN_STYLUS2
 64 
 65 #define MIMIO_VENDOR_ID         0x08d3
 66 #define MIMIO_PRODUCT_ID        0x0001
 67 #define MIMIO_MAXPAYLOAD        (8)
 68 #define MIMIO_MAXNAMELEN        (64)
 69 #define MIMIO_TXWAIT            (1)
 70 #define MIMIO_TXDONE            (2)
 71 
 72 #define MIMIO_EV_PENDOWN        (0x22)
 73 #define MIMIO_EV_PENDATA        (0x24)
 74 #define MIMIO_EV_PENUP          (0x51)
 75 #define MIMIO_EV_MEMRESET       (0x45)
 76 #define MIMIO_EV_ACC            (0xb2)
 77 
 78 #define MIMIO_PEN_K             (1)     /* black pen */
 79 #define MIMIO_PEN_B             (2)     /* blue pen */
 80 #define MIMIO_PEN_G             (3)     /* green pen */
 81 #define MIMIO_PEN_R             (4)     /* red pen */
 82 /* 5, 6, 7, 8 are extra pens */
 83 #define MIMIO_PEN_E             (9)     /* big eraser */
 84 #define MIMIO_PEN_ES            (10)    /* lil eraser */
 85 #define MIMIO_PENJUMP_START     (10)
 86 #define MIMIO_PENJUMP           (6)
 87 #define MIMIO_PEN_I             (17)    /* mimio interactive */
 88 #define MIMIO_PEN_IL            (18)    /* mimio interactive button 1 */
 89 #define MIMIO_PEN_IR            (19)    /* mimio interactive button 2 */
 90 
 91 #define MIMIO_PEN_MAX           (MIMIO_PEN_IR)
 92 
 93 #define ACC_DONE                (0)
 94 #define ACC_NEWPAGE             (1)
 95 #define ACC_TAGPAGE             (2)
 96 #define ACC_PRINTPAGE           (4)
 97 #define ACC_MAXIMIZE            (8)
 98 #define ACC_FINDCTLPNL          (16)
 99 
100 #define isvalidtxsize(n)        ((n) > 0 && (n) <= MIMIO_MAXPAYLOAD)
101 
102 
103 struct pktbuf {
104         unsigned char instr;
105         unsigned char buf[16];
106         unsigned char *p;
107         unsigned char *q;
108 };
109 
110 struct usbintendpt {
111         dma_addr_t dma;
112         struct urb *urb;
113         unsigned char *buf;
114         struct usb_endpoint_descriptor *desc;
115 };
116 
117 struct mimio {
118         struct input_dev *idev;
119         struct usb_device *udev;
120         struct usb_interface *uifc;
121         int open;
122         int present;
123         int greeted;
124         int txflags;
125         char phys[MIMIO_MAXNAMELEN];
126         struct usbintendpt in;
127         struct usbintendpt out;
128         struct pktbuf pktbuf;
129         unsigned char minor;
130         wait_queue_head_t waitq;
131         spinlock_t txlock;
132         void (*rxhandler)(struct mimio *, unsigned char *, unsigned int);
133         int last_pen_down;
134 };
135 
136 static void mimio_close(struct input_dev *);
137 static void mimio_dealloc(struct mimio *);
138 static void mimio_disconnect(struct usb_interface *);
139 static int mimio_greet(struct mimio *);
140 static void mimio_irq_in(struct urb *);
141 static void mimio_irq_out(struct urb *);
142 static int mimio_open(struct input_dev *);
143 static int mimio_probe(struct usb_interface *, const struct usb_device_id *);
144 static void mimio_rx_handler(struct mimio *, unsigned char *, unsigned int);
145 static int mimio_tx(struct mimio *, const char *, int);
146 
147 static char mimio_name[] = "VirtualInk mimio-Xi";
148 static struct usb_device_id mimio_table [] = {
149         { USB_DEVICE(MIMIO_VENDOR_ID, MIMIO_PRODUCT_ID) },
150         { USB_DEVICE(0x0525, 0xa4a0) }, /* gadget zero firmware */
151         { }
152 };
153 
154 MODULE_DEVICE_TABLE(usb, mimio_table);
155 
156 static struct usb_driver mimio_driver = {
157         .name = "mimio",
158         .probe = mimio_probe,
159         .disconnect = mimio_disconnect,
160         .id_table = mimio_table,
161 };
162 
163 static DECLARE_MUTEX(disconnect_sem);
164 
165 static void mimio_close(struct input_dev *idev)
166 {
167         struct mimio *mimio;
168 
169         mimio = input_get_drvdata(idev);
170         if (!mimio) {
171                 dev_err(&idev->dev, "null mimio attached to input device\n");
172                 return;
173         }
174 
175         if (mimio->open <= 0)
176                 dev_err(&idev->dev, "mimio not open.\n");
177         else
178                 mimio->open--;
179 
180         if (mimio->present == 0 && mimio->open == 0)
181                 mimio_dealloc(mimio);
182 }
183 
184 static void mimio_dealloc(struct mimio *mimio)
185 {
186         if (mimio == NULL)
187                 return;
188 
189         usb_kill_urb(mimio->in.urb);
190 
191         usb_kill_urb(mimio->out.urb);
192 
193         if (mimio->idev) {
194                 input_unregister_device(mimio->idev);
195                 if (mimio->idev->grab)
196                         input_close_device(mimio->idev->grab);
197                 else
198                         dev_dbg(&mimio->idev->dev, "mimio->idev->grab == NULL"
199                                 " -- didn't call input_close_device\n");
200         }
201 
202         usb_free_urb(mimio->in.urb);
203 
204         usb_free_urb(mimio->out.urb);
205 
206         if (mimio->in.buf) {
207                 usb_buffer_free(mimio->udev, MIMIO_MAXPAYLOAD, mimio->in.buf,
208                                 mimio->in.dma);
209         }
210 
211         if (mimio->out.buf)
212                 usb_buffer_free(mimio->udev, MIMIO_MAXPAYLOAD, mimio->out.buf,
213                                 mimio->out.dma);
214 
215         if (mimio->idev)
216                 input_free_device(mimio->idev);
217 
218         kfree(mimio);
219 }
220 
221 static void mimio_disconnect(struct usb_interface *ifc)
222 {
223         struct mimio *mimio;
224 
225         down(&disconnect_sem);
226 
227         mimio = usb_get_intfdata(ifc);
228         usb_set_intfdata(ifc, NULL);
229         dev_dbg(&mimio->idev->dev, "disconnect\n");
230 
231         if (mimio) {
232                 mimio->present = 0;
233 
234                 if (mimio->open <= 0)
235                         mimio_dealloc(mimio);
236         }
237 
238         up(&disconnect_sem);
239 }
240 
241 static int mimio_greet(struct mimio *mimio)
242 {
243         const struct grtpkt {
244                 int nbytes;
245                 unsigned delay;
246                 char data[8];
247         } grtpkts[] = {
248                 { 3, 0, { 0x11, 0x55, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00 } },
249                 { 5, 0, { 0x53, 0x55, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00 } },
250                 { 5, 0, { 0x43, 0x55, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00 } },
251                 { 5, 0, { 0x33, 0x55, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00 } },
252                 { 5, 0, { 0x13, 0x00, 0x5e, 0x02, 0x4f, 0x00, 0x00, 0x00 } },
253                 { 5, 0, { 0x13, 0x00, 0x04, 0x03, 0x14, 0x00, 0x00, 0x00 } },
254                 { 5, 2, { 0x13, 0x00, 0x00, 0x04, 0x17, 0x00, 0x00, 0x00 } },
255                 { 5, 0, { 0x13, 0x00, 0x0d, 0x08, 0x16, 0x00, 0x00, 0x00 } },
256                 { 5, 0, { 0x13, 0x00, 0x4d, 0x01, 0x5f, 0x00, 0x00, 0x00 } },
257                 { 3, 0, { 0xf1, 0x55, 0xa4, 0x00, 0x00, 0x00, 0x00, 0x00 } },
258                 { 7, 2, { 0x52, 0x55, 0x00, 0x07, 0x31, 0x55, 0x64, 0x00 } },
259                 { 0, 0, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
260         };
261         int rslt;
262         const struct grtpkt *pkt;
263 
264         for (pkt = grtpkts; pkt->nbytes; pkt++) {
265                 rslt = mimio_tx(mimio, pkt->data, pkt->nbytes);
266                 if (rslt)
267                         return rslt;
268                 if (pkt->delay)
269                         msleep(pkt->delay);
270         }
271 
272         return 0;
273 }
274 
275 static void mimio_irq_in(struct urb *urb)
276 {
277         int rslt;
278         char *data;
279         const char *reason = "going down";
280         struct mimio *mimio;
281 
282         mimio = urb->context;
283 
284         if (mimio == NULL)
285                 /* paranoia */
286                 return;
287 
288         switch (urb->status) {
289         case 0:
290                 /* success */
291                 break;
292         case -ETIMEDOUT:
293                 reason = "timeout -- unplugged?";
294         case -ECONNRESET:
295         case -ENOENT:
296         case -ESHUTDOWN:
297                 dev_dbg(&mimio->idev->dev, "%s.\n", reason);
298                 return;
299         default:
300                 dev_dbg(&mimio->idev->dev, "unknown urb-status: %d.\n",
301                         urb->status);
302                 goto exit;
303         }
304         data = mimio->in.buf;
305 
306         if (mimio->rxhandler)
307                 mimio->rxhandler(mimio, data, urb->actual_length);
308 exit:
309         /*
310          * Keep listening to device on same urb.
311          */
312         rslt = usb_submit_urb(urb, GFP_ATOMIC);
313         if (rslt)
314                 dev_err(&mimio->idev->dev, "usb_submit_urb failure: %d.\n",
315                         rslt);
316 }
317 
318 static void mimio_irq_out(struct urb *urb)
319 {
320         unsigned long flags;
321         struct mimio *mimio;
322 
323         mimio = urb->context;
324 
325         if (urb->status)
326                 dev_dbg(&mimio->idev->dev, "urb-status: %d.\n", urb->status);
327 
328         spin_lock_irqsave(&mimio->txlock, flags);
329         mimio->txflags |= MIMIO_TXDONE;
330         spin_unlock_irqrestore(&mimio->txlock, flags);
331         wmb();
332         wake_up(&mimio->waitq);
333 }
334 
335 static int mimio_open(struct input_dev *idev)
336 {
337         int rslt;
338         struct mimio *mimio;
339 
340         rslt = 0;
341         down(&disconnect_sem);
342         mimio = input_get_drvdata(idev);
343         dev_dbg(&idev->dev, "mimio_open\n");
344 
345         if (mimio == NULL) {
346                 dev_err(&idev->dev, "null mimio.\n");
347                 rslt = -ENODEV;
348                 goto exit;
349         }
350 
351         if (mimio->open++)
352                 goto exit;
353 
354         if (mimio->present && !mimio->greeted) {
355                 struct urb *urb = mimio->in.urb;
356                 mimio->in.urb->dev = mimio->udev;
357                 rslt = usb_submit_urb(mimio->in.urb, GFP_KERNEL);
358                 if (rslt) {
359                         dev_err(&idev->dev, "usb_submit_urb failure "
360                                 "(res = %d: %s). Not greeting.\n",
361                                 rslt,
362                                 (!urb ? "urb is NULL" :
363                                  (urb->hcpriv ? "urb->hcpriv is non-NULL" :
364                                   (!urb->complete ? "urb is not complete" :
365                                    (urb->number_of_packets <= 0 ? "urb has no packets" :
366                                     (urb->interval <= 0 ? "urb interval too small" :
367                                      "urb interval too large or some other error"))))));
368                         rslt = -EIO;
369                         goto exit;
370                 }
371                 rslt = mimio_greet(mimio);
372                 if (rslt == 0) {
373                         dev_dbg(&idev->dev, "Mimio greeted OK.\n");
374                         mimio->greeted = 1;
375                 } else {
376                         dev_dbg(&idev->dev, "Mimio greet Failure (%d)\n",
377                                 rslt);
378                 }
379         }
380 
381 exit:
382         up(&disconnect_sem);
383         return rslt;
384 }
385 
386 static int mimio_probe(struct usb_interface *ifc,
387                        const struct usb_device_id *id)
388 {
389         char path[64];
390         int pipe, maxp;
391         struct mimio *mimio;
392         struct usb_device *udev;
393         struct usb_host_interface *hostifc;
394         struct input_dev *input_dev;
395         int res = 0;
396         int i;
397 
398         udev = interface_to_usbdev(ifc);
399 
400         mimio = kzalloc(sizeof(struct mimio), GFP_KERNEL);
401         if (!mimio)
402                 return -ENOMEM;
403 
404         input_dev = input_allocate_device();
405         if (!input_dev) {
406                 mimio_dealloc(mimio);
407                 return -ENOMEM;
408         }
409 
410         mimio->uifc = ifc;
411         mimio->udev = udev;
412         mimio->pktbuf.p = mimio->pktbuf.buf;
413         mimio->pktbuf.q = mimio->pktbuf.buf;
414         /* init_input_dev(mimio->idev); */
415         mimio->idev = input_dev;
416         init_waitqueue_head(&mimio->waitq);
417         spin_lock_init(&mimio->txlock);
418         hostifc = ifc->cur_altsetting;
419 
420         if (hostifc->desc.bNumEndpoints != 2) {
421                 dev_err(&udev->dev, "Unexpected endpoint count: %d.\n",
422                         hostifc->desc.bNumEndpoints);
423                 mimio_dealloc(mimio);
424                 return -ENODEV;
425         }
426 
427         mimio->in.desc = &(hostifc->endpoint[0].desc);
428         mimio->out.desc = &(hostifc->endpoint[1].desc);
429 
430         mimio->in.buf = usb_buffer_alloc(udev, MIMIO_MAXPAYLOAD, GFP_KERNEL,
431                                          &mimio->in.dma);
432         mimio->out.buf = usb_buffer_alloc(udev, MIMIO_MAXPAYLOAD, GFP_KERNEL,
433                                           &mimio->out.dma);
434 
435         if (mimio->in.buf == NULL || mimio->out.buf == NULL) {
436                 dev_err(&udev->dev, "usb_buffer_alloc failure.\n");
437                 mimio_dealloc(mimio);
438                 return -ENOMEM;
439         }
440 
441         mimio->in.urb = usb_alloc_urb(0, GFP_KERNEL);
442         mimio->out.urb = usb_alloc_urb(0, GFP_KERNEL);
443 
444         if (mimio->in.urb == NULL || mimio->out.urb == NULL) {
445                 dev_err(&udev->dev, "usb_alloc_urb failure.\n");
446                 mimio_dealloc(mimio);
447                 return -ENOMEM;
448         }
449 
450         /*
451          * Build the input urb.
452          */
453         pipe = usb_rcvintpipe(udev, mimio->in.desc->bEndpointAddress);
454         maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
455         if (maxp > MIMIO_MAXPAYLOAD)
456                 maxp = MIMIO_MAXPAYLOAD;
457         usb_fill_int_urb(mimio->in.urb, udev, pipe, mimio->in.buf, maxp,
458                          mimio_irq_in, mimio, mimio->in.desc->bInterval);
459         mimio->in.urb->transfer_dma = mimio->in.dma;
460         mimio->in.urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
461 
462         /*
463          * Build the output urb.
464          */
465         pipe = usb_sndintpipe(udev, mimio->out.desc->bEndpointAddress);
466         maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
467         if (maxp > MIMIO_MAXPAYLOAD)
468                 maxp = MIMIO_MAXPAYLOAD;
469         usb_fill_int_urb(mimio->out.urb, udev, pipe, mimio->out.buf, maxp,
470                          mimio_irq_out, mimio, mimio->out.desc->bInterval);
471         mimio->out.urb->transfer_dma = mimio->out.dma;
472         mimio->out.urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
473 
474         /*
475          * Build input device info
476          */
477         usb_make_path(udev, path, 64);
478         snprintf(mimio->phys, MIMIO_MAXNAMELEN, "%s/input0", path);
479         input_set_drvdata(input_dev, mimio);
480         /* input_dev->dev = &ifc->dev; */
481         input_dev->open = mimio_open;
482         input_dev->close = mimio_close;
483         input_dev->name = mimio_name;
484         input_dev->phys = mimio->phys;
485         input_dev->dev.parent = &ifc->dev;
486 
487         input_dev->id.bustype = BUS_USB;
488         input_dev->id.vendor = le16_to_cpu(udev->descriptor.idVendor);
489         input_dev->id.product = le16_to_cpu(udev->descriptor.idProduct);
490         input_dev->id.version = le16_to_cpu(udev->descriptor.bcdDevice);
491 
492         input_dev->evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS);
493         for (i = BTN_TOOL_PEN; i <= LOCALBTN_TOOL_EXTRA2; ++i)
494                 set_bit(i, input_dev->keybit);
495 
496         input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_0) |
497                                                  BIT_MASK(BTN_1) |
498                                                  BIT_MASK(BTN_2) |
499                                                  BIT_MASK(BTN_3) |
500                                                  BIT_MASK(BTN_4) |
501                                                  BIT_MASK(BTN_5);
502         /*   input_dev->keybit[BTN_MOUSE] |= BIT(BTN_LEFT); */
503         input_dev->absbit[0] |= BIT_MASK(ABS_X) | BIT_MASK(ABS_Y);
504         input_set_abs_params(input_dev, ABS_X, 0, MIMIO_XRANGE_MAX, 0, 0);
505         input_set_abs_params(input_dev, ABS_Y, 0, MIMIO_YRANGE_MAX, 0, 0);
506         input_dev->absbit[BIT_WORD(ABS_MISC)] |= BIT_MASK(ABS_MISC);
507 
508 #if 0
509         input_dev->absmin[ABS_X] = 0;
510         input_dev->absmin[ABS_Y] = 0;
511         input_dev->absmax[ABS_X] = 9600;
512         input_dev->absmax[ABS_Y] = 4800;
513         input_dev->absfuzz[ABS_X] = 0;
514         input_dev->absfuzz[ABS_Y] = 0;
515         input_dev->absflat[ABS_X] = 0;
516         input_dev->absflat[ABS_Y] = 0;
517 #endif
518 
519 #if 0
520         /* this will just reduce the precision */
521         input_dev->absfuzz[ABS_X] = 8; /* experimental; may need to change */
522         input_dev->absfuzz[ABS_Y] = 8; /* experimental; may need to change */
523 #endif
524 
525         /*
526          * Register the input device.
527          */
528         res = input_register_device(mimio->idev);
529         if (res) {
530                 dev_err(&udev->dev, "input_register_device failure (%d)\n",
531                         res);
532                 mimio_dealloc(mimio);
533                 return -EIO;
534         }
535         dev_dbg(&mimio->idev->dev, "input: %s on %s (res = %d).\n",
536                 input_dev->name, input_dev->phys, res);
537 
538         usb_set_intfdata(ifc, mimio);
539         mimio->present = 1;
540 
541         /*
542          * Submit the input urb to the usb subsystem.
543          */
544         mimio->in.urb->dev = mimio->udev;
545         res = usb_submit_urb(mimio->in.urb, GFP_KERNEL);
546         if (res) {
547                 dev_err(&mimio->idev->dev, "usb_submit_urb failure (%d)\n",
548                         res);
549                 mimio_dealloc(mimio);
550                 return -EIO;
551         }
552 
553         /*
554          * Attempt to greet the mimio after giving
555          * it some post-init settling time.
556          *
557          * note: sometimes this sleep interval isn't
558          * long enough to permit the device to re-init
559          * after a hot-swap; maybe need to bump it up.
560          *
561          * As it is, this probably breaks module unloading support!
562          */
563         msleep(1024);
564 
565         res = mimio_greet(mimio);
566         if (res == 0) {
567                 dev_dbg(&mimio->idev->dev, "Mimio greeted OK.\n");
568                 mimio->greeted = 1;
569                 mimio->rxhandler = mimio_rx_handler;
570         } else {
571                 dev_dbg(&mimio->idev->dev, "Mimio greet Failure (%d)\n", res);
572         }
573 
574         return 0;
575 }
576 
577 static int handle_mimio_rx_penupdown(struct mimio *mimio,
578                                      int down,
579                                      const char *const instr[],
580                                      const int instr_ofst[])
581 {
582         int penid, x;
583         if (mimio->pktbuf.q - mimio->pktbuf.p < (down ? 4 : 3))
584                 return 1;               /* partial pkt */
585 
586         if (down) {
587                 x = *mimio->pktbuf.p ^ *(mimio->pktbuf.p + 1) ^
588                         *(mimio->pktbuf.p + 2);
589                 if (x != *(mimio->pktbuf.p + 3)) {
590                         dev_dbg(&mimio->idev->dev, "EV_PEN%s: bad xsum.\n",
591                                 down ? "DOWN":"UP");
592                         /* skip this event data */
593                         mimio->pktbuf.p += 4;
594                         /* decode any remaining events */
595                         return 0;
596                 }
597                 penid = mimio->pktbuf.instr = *(mimio->pktbuf.p + 2);
598                 if (penid > MIMIO_PEN_MAX) {
599                         dev_dbg(&mimio->idev->dev,
600                                 "Unmapped penID (not in [0, %d]): %d\n",
601                                 MIMIO_PEN_MAX, (int)mimio->pktbuf.instr);
602                         penid = mimio->pktbuf.instr = 0;
603                 }
604                 mimio->last_pen_down = penid;
605         } else {
606                 penid = mimio->last_pen_down;
607         }
608         dev_dbg(&mimio->idev->dev, "%s (id %d, code %d) %s.\n", instr[penid],
609                 instr_ofst[penid], penid, down ? "down" : "up");
610 
611         if (instr_ofst[penid] >= 0) {
612                 int code = BTN_TOOL_PEN + instr_ofst[penid];
613                 int value = down ? DOWNVALUE : UPVALUE;
614                 if (code > KEY_MAX)
615                         dev_dbg(&mimio->idev->dev, "input_event will ignore "
616                                 "-- code (%d) > KEY_MAX\n", code);
617                 if (!test_bit(code, mimio->idev->keybit))
618                         dev_dbg(&mimio->idev->dev, "input_event will ignore "
619                                 "-- bit for code (%d) not enabled\n", code);
620                 if (!!test_bit(code, mimio->idev->key) == value)
621                         dev_dbg(&mimio->idev->dev, "input_event will ignore "
622                                 "-- bit for code (%d) already set to %d\n",
623                                 code, value);
624                 if (value != DOWNVALUE) {
625                         /* input_regs(mimio->idev, regs); */
626                         input_report_key(mimio->idev, code, value);
627                         input_sync(mimio->idev);
628                 } else {
629                         /* wait until we get some coordinates */
630                 }
631         } else {
632                 dev_dbg(&mimio->idev->dev, "penID offset[%d] == %d is < 0 "
633                         "- not sending\n", penid, instr_ofst[penid]);
634         }
635         mimio->pktbuf.p += down ? 4 : 3; /* 3 for up, 4 for down */
636         return 0;
637 }
638 
639 /*
640  * Stay tuned for partial-packet excitement.
641  *
642  * This routine buffers data packets received from the mimio device
643  * in the mimio's data space.  This buffering is necessary because
644  * the mimio's in endpoint can serve us partial packets of data, and
645  * we want the driver to support the servicing of multiple mimios.
646  * Empirical evidence gathered so far suggests that the method of
647  * buffering packet data in the mimio's data space works.  Previous
648  * versions of this driver did not buffer packet data in each mimio's
649  * data-space, and were therefore not able to service multiple mimios.
650  * Note that since the caller of this routine is running in interrupt
651  * context, care needs to be taken to ensure that this routine does not
652  * become bloated, and it may be that another spinlock is needed in each
653  * mimio to guard the buffered packet data properly.
654  */
655 static void mimio_rx_handler(struct mimio *mimio,
656                              unsigned char *data,
657                              unsigned int nbytes)
658 {
659         struct device *dev = &mimio->idev->dev;
660         unsigned int x;
661         unsigned int y;
662         static const char * const instr[] = {
663                 "?0",
664                 "black pen", "blue pen", "green pen", "red pen",
665                 "brown pen", "orange pen", "purple pen", "yellow pen",
666                 "big eraser", "lil eraser",
667                 "?11", "?12", "?13", "?14", "?15", "?16",
668                 "mimio interactive", "interactive button1",
669                 "interactive button2"
670         };
671 
672         /* Mimio Interactive gives:
673          * down: [0x22 0x01 0x11 0x32 0x24]
674          * b1  : [0x22 0x01 0x12 0x31 0x24]
675          * b2  : [0x22 0x01 0x13 0x30 0x24]
676          */
677         static const int instr_ofst[] = {
678                 -1,
679                 0, 1, 2, 3,
680                 9, 9, 9, 9,
681                 4, 5,
682                 -1, -1, -1, -1, -1, -1,
683                 6, 7, 8,
684         };
685 
686         memcpy(mimio->pktbuf.q, data, nbytes);
687         mimio->pktbuf.q += nbytes;
688 
689         while (mimio->pktbuf.p < mimio->pktbuf.q) {
690                 int t = *mimio->pktbuf.p;
691                 switch (t) {
692                 case MIMIO_EV_PENUP:
693                 case MIMIO_EV_PENDOWN:
694                         if (handle_mimio_rx_penupdown(mimio,
695                                                       t == MIMIO_EV_PENDOWN,
696                                                       instr, instr_ofst))
697                                 return; /* partial packet */
698                         break;
699 
700                 case MIMIO_EV_PENDATA:
701                         if (mimio->pktbuf.q - mimio->pktbuf.p < 6)
702                                 /* partial pkt */
703                                 return;
704                         x = *mimio->pktbuf.p ^ *(mimio->pktbuf.p + 1) ^
705                                 *(mimio->pktbuf.p + 2) ^
706                                 *(mimio->pktbuf.p + 3) ^
707                                 *(mimio->pktbuf.p + 4);
708                         if (x != *(mimio->pktbuf.p + 5)) {
709                                 dev_dbg(dev, "EV_PENDATA: bad xsum.\n");
710                                 mimio->pktbuf.p += 6; /* skip this event data */
711                                 break; /* decode any remaining events */
712                         }
713                         x = *(mimio->pktbuf.p + 1);
714                         x <<= 8;
715                         x |= *(mimio->pktbuf.p + 2);
716                         y = *(mimio->pktbuf.p + 3);
717                         y <<= 8;
718                         y |= *(mimio->pktbuf.p + 4);
719                         dev_dbg(dev, "coord: (%d, %d)\n", x, y);
720                         if (instr_ofst[mimio->pktbuf.instr] >= 0) {
721                                 int code = BTN_TOOL_PEN +
722                                            instr_ofst[mimio->last_pen_down];
723 #if 0
724                                 /* Utter hack to ensure we get forwarded _AND_
725                                  * so we can identify when a complete signal is
726                                  * received */
727                                 mimio->idev->abs[ABS_Y] = -1;
728                                 mimio->idev->abs[ABS_X] = -1;
729 #endif
730                                 /* input_regs(mimio->idev, regs); */
731                                 input_report_abs(mimio->idev, ABS_X, x);
732                                 input_report_abs(mimio->idev, ABS_Y, y);
733                                 /* fake a penup */
734                                 change_bit(code, mimio->idev->key);
735                                 input_report_key(mimio->idev,
736                                                  code,
737                                                  DOWNVALUE);
738                                 /* always sync here */
739                                 mimio->idev->sync = 0;
740                                 input_sync(mimio->idev);
741                         }
742                         mimio->pktbuf.p += 6;
743                         break;
744                 case MIMIO_EV_MEMRESET:
745                         if (mimio->pktbuf.q - mimio->pktbuf.p < 7)
746                                 /* partial pkt */
747                                 return;
748                         dev_dbg(dev, "mem-reset.\n");
749                         /* input_regs(mimio->idev, regs); */
750                         input_event(mimio->idev, EV_KEY, BTN_0, 1);
751                         input_event(mimio->idev, EV_KEY, BTN_0, 0);
752                         input_sync(mimio->idev);
753                         mimio->pktbuf.p += 7;
754                         break;
755                 case MIMIO_EV_ACC:
756                         if (mimio->pktbuf.q - mimio->pktbuf.p < 4)
757                                 /* partial pkt */
758                                 return;
759                         x = *mimio->pktbuf.p ^ *(mimio->pktbuf.p + 1) ^
760                                 *(mimio->pktbuf.p + 2);
761                         if (x != *(mimio->pktbuf.p + 3)) {
762                                 dev_dbg(dev, "EV_ACC: bad xsum.\n");
763                                 mimio->pktbuf.p += 4; /* skip this event data */
764                                 break; /* decode any remaining events */
765                         }
766                         switch (*(mimio->pktbuf.p + 2)) {
767                         case ACC_NEWPAGE:
768                                 dev_dbg(&mimio->idev->dev, "new-page.\n");
769                                 /* input_regs(mimio->idev, regs); */
770                                 input_event(mimio->idev, EV_KEY, BTN_1, 1);
771                                 input_event(mimio->idev, EV_KEY, BTN_1, 0);
772                                 input_sync(mimio->idev);
773                                 break;
774                         case ACC_TAGPAGE:
775                                 dev_dbg(&mimio->idev->dev, "tag-page.\n");
776                                 /* input_regs(mimio->idev, regs); */
777                                 input_event(mimio->idev, EV_KEY, BTN_2, 1);
778                                 input_event(mimio->idev, EV_KEY, BTN_2, 0);
779                                 input_sync(mimio->idev);
780                                 break;
781                         case ACC_PRINTPAGE:
782                                 dev_dbg(&mimio->idev->dev, "print-page.\n");
783                                 /* input_regs(mimio->idev, regs);*/
784                                 input_event(mimio->idev, EV_KEY, BTN_3, 1);
785                                 input_event(mimio->idev, EV_KEY, BTN_3, 0);
786                                 input_sync(mimio->idev);
787                                 break;
788                         case ACC_MAXIMIZE:
789                                 dev_dbg(&mimio->idev->dev,
790                                         "maximize-window.\n");
791                                 /* input_regs(mimio->idev, regs); */
792                                 input_event(mimio->idev, EV_KEY, BTN_4, 1);
793                                 input_event(mimio->idev, EV_KEY, BTN_4, 0);
794                                 input_sync(mimio->idev);
795                                 break;
796                         case ACC_FINDCTLPNL:
797                                 dev_dbg(&mimio->idev->dev, "find-ctl-panel.\n");
798                                 /* input_regs(mimio->idev, regs); */
799                                 input_event(mimio->idev, EV_KEY, BTN_5, 1);
800                                 input_event(mimio->idev, EV_KEY, BTN_5, 0);
801                                 input_sync(mimio->idev);
802                                 break;
803                         case ACC_DONE:
804                                 dev_dbg(&mimio->idev->dev, "acc-done.\n");
805                                 /* no event is dispatched to the input
806                                  * subsystem for this device event.
807                                  */
808                                 break;
809                         default:
810                                 dev_dbg(dev, "unknown acc event.\n");
811                                 break;
812                         }
813                         mimio->pktbuf.p += 4;
814                         break;
815                 default:
816                         mimio->pktbuf.p++;
817                         break;
818                 }
819         }
820 
821         /*
822          * No partial event was received, so reset mimio's pktbuf ptrs.
823          */
824         mimio->pktbuf.p = mimio->pktbuf.q = mimio->pktbuf.buf;
825 }
826 
827 static int mimio_tx(struct mimio *mimio, const char *buf, int nbytes)
828 {
829         int rslt;
830         int timeout;
831         unsigned long flags;
832         DECLARE_WAITQUEUE(wait, current);
833 
834         if (!(isvalidtxsize(nbytes))) {
835                 dev_err(&mimio->idev->dev, "invalid arg: nbytes: %d.\n",
836                         nbytes);
837                 return -EINVAL;
838         }
839 
840         /*
841          * Init the out urb and copy the data to send.
842          */
843         mimio->out.urb->dev = mimio->udev;
844         mimio->out.urb->transfer_buffer_length = nbytes;
845         memcpy(mimio->out.urb->transfer_buffer, buf, nbytes);
846 
847         /*
848          * Send the data.
849          */
850         spin_lock_irqsave(&mimio->txlock, flags);
851         mimio->txflags = MIMIO_TXWAIT;
852         rslt = usb_submit_urb(mimio->out.urb, GFP_ATOMIC);
853         spin_unlock_irqrestore(&mimio->txlock, flags);
854         dev_dbg(&mimio->idev->dev, "rslt: %d.\n", rslt);
855 
856         if (rslt) {
857                 dev_err(&mimio->idev->dev, "usb_submit_urb failure: %d.\n",
858                         rslt);
859                 return rslt;
860         }
861 
862         /*
863          * Wait for completion to be signalled (the mimio_irq_out
864          * completion routine will or MIMIO_TXDONE in with txflags).
865          */
866         timeout = HZ;
867         set_current_state(TASK_INTERRUPTIBLE);
868         add_wait_queue(&mimio->waitq, &wait);
869 
870         while (timeout && ((mimio->txflags & MIMIO_TXDONE) == 0)) {
871                 timeout = schedule_timeout(timeout);
872                 rmb();
873         }
874 
875         if ((mimio->txflags & MIMIO_TXDONE) == 0)
876                 dev_dbg(&mimio->idev->dev, "tx timed out.\n");
877 
878         /*
879          * Now that completion has been signalled,
880          * unlink the urb so that it can be recycled.
881          */
882         set_current_state(TASK_RUNNING);
883         remove_wait_queue(&mimio->waitq, &wait);
884         usb_unlink_urb(mimio->out.urb);
885 
886         return rslt;
887 }
888 
889 static int __init mimio_init(void)
890 {
891         int rslt;
892 
893         rslt = usb_register(&mimio_driver);
894         if (rslt != 0) {
895                 err("%s: usb_register failure: %d", __func__, rslt);
896                 return rslt;
897         }
898 
899         printk(KERN_INFO KBUILD_MODNAME ":"
900                DRIVER_DESC " " DRIVER_VERSION "\n");
901         return rslt;
902 }
903 
904 static void __exit mimio_exit(void)
905 {
906         usb_deregister(&mimio_driver);
907 }
908 
909 module_init(mimio_init);
910 module_exit(mimio_exit);
911 
912 MODULE_AUTHOR(DRIVER_AUTHOR);
913 MODULE_DESCRIPTION(DRIVER_DESC);
914 MODULE_LICENSE("GPL");
915 
  This page was automatically generated by the LXR engine.