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

Linux Cross Reference
Linux/drivers/media/video/bw-qcam.c

Version: ~ [ 2.2.5 ] ~ [ 2.4.1 ] ~ [ 2.4.9 ] ~ [ 2.6.17.10 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  *    QuickCam Driver For Video4Linux.
  3  *
  4  *      This version only works as a module.
  5  *
  6  *      Video4Linux conversion work by Alan Cox.
  7  *      Parport compatibility by Phil Blundell.
  8  *      Busy loop avoidance by Mark Cooke.
  9  *
 10  *    Module parameters:
 11  *
 12  *      maxpoll=<1 - 5000>
 13  *
 14  *        When polling the QuickCam for a response, busy-wait for a
 15  *        maximum of this many loops. The default of 250 gives little
 16  *        impact on interactive response.
 17  *
 18  *        NOTE: If this parameter is set too high, the processor
 19  *              will busy wait until this loop times out, and then
 20  *              slowly poll for a further 5 seconds before failing
 21  *              the transaction. You have been warned.
 22  *
 23  *      yieldlines=<1 - 250>
 24  *
 25  *        When acquiring a frame from the camera, the data gathering
 26  *        loop will yield back to the scheduler after completing
 27  *        this many lines. The default of 4 provides a trade-off
 28  *        between increased frame acquisition time and impact on
 29  *        interactive response.
 30  */
 31 
 32 /* qcam-lib.c -- Library for programming with the Connectix QuickCam.
 33  * See the included documentation for usage instructions and details
 34  * of the protocol involved. */
 35 
 36 
 37 /* Version 0.5, August 4, 1996 */
 38 /* Version 0.7, August 27, 1996 */
 39 /* Version 0.9, November 17, 1996 */
 40 
 41 
 42 /******************************************************************
 43 
 44 Copyright (C) 1996 by Scott Laird
 45 
 46 Permission is hereby granted, free of charge, to any person obtaining
 47 a copy of this software and associated documentation files (the
 48 "Software"), to deal in the Software without restriction, including
 49 without limitation the rights to use, copy, modify, merge, publish,
 50 distribute, sublicense, and/or sell copies of the Software, and to
 51 permit persons to whom the Software is furnished to do so, subject to
 52 the following conditions:
 53 
 54 The above copyright notice and this permission notice shall be
 55 included in all copies or substantial portions of the Software.
 56 
 57 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 58 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 59 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 60 IN NO EVENT SHALL SCOTT LAIRD BE LIABLE FOR ANY CLAIM, DAMAGES OR
 61 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 62 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 63 OTHER DEALINGS IN THE SOFTWARE.
 64 
 65 ******************************************************************/
 66 
 67 #include <linux/module.h>
 68 #include <linux/delay.h>
 69 #include <linux/errno.h>
 70 #include <linux/fs.h>
 71 #include <linux/init.h>
 72 #include <linux/kernel.h>
 73 #include <linux/slab.h>
 74 #include <linux/mm.h>
 75 #include <linux/parport.h>
 76 #include <linux/sched.h>
 77 #include <linux/version.h>
 78 #include <linux/videodev.h>
 79 #include <asm/semaphore.h>
 80 #include <asm/uaccess.h>
 81 
 82 #include "bw-qcam.h"
 83 
 84 static unsigned int maxpoll=250;   /* Maximum busy-loop count for qcam I/O */
 85 static unsigned int yieldlines=4;  /* Yield after this many during capture */
 86 static int video_nr = -1;
 87 
 88 #if LINUX_VERSION_CODE >= 0x020117
 89 MODULE_PARM(maxpoll,"i");
 90 MODULE_PARM(yieldlines,"i");   
 91 MODULE_PARM(video_nr,"i");
 92 #endif
 93 
 94 extern __inline__ int read_lpstatus(struct qcam_device *q)
 95 {
 96         return parport_read_status(q->pport);
 97 }
 98 
 99 extern __inline__ int read_lpcontrol(struct qcam_device *q)
100 {
101         return parport_read_control(q->pport);
102 }
103 
104 extern __inline__ int read_lpdata(struct qcam_device *q)
105 {
106         return parport_read_data(q->pport);
107 }
108 
109 extern __inline__ void write_lpdata(struct qcam_device *q, int d)
110 {
111         parport_write_data(q->pport, d);
112 }
113 
114 extern __inline__ void write_lpcontrol(struct qcam_device *q, int d)
115 {
116         parport_write_control(q->pport, d);
117 }
118 
119 static int qc_waithand(struct qcam_device *q, int val);
120 static int qc_command(struct qcam_device *q, int command);
121 static int qc_readparam(struct qcam_device *q);
122 static int qc_setscanmode(struct qcam_device *q);
123 static int qc_readbytes(struct qcam_device *q, char buffer[]);
124 
125 static struct video_device qcam_template;
126 
127 static int qc_calibrate(struct qcam_device *q)
128 {
129         /*
130          *      Bugfix by Hanno Mueller hmueller@kabel.de, Mai 21 96
131          *      The white balance is an individiual value for each
132          *      quickcam.
133          */
134 
135         int value;
136         int count = 0;
137 
138         qc_command(q, 27);      /* AutoAdjustOffset */
139         qc_command(q, 0);       /* Dummy Parameter, ignored by the camera */
140 
141         /* GetOffset (33) will read 255 until autocalibration */
142         /* is finished. After that, a value of 1-254 will be */
143         /* returned. */
144 
145         do {
146                 qc_command(q, 33);
147                 value = qc_readparam(q);
148                 mdelay(1);
149                 schedule();
150                 count++;
151         } while (value == 0xff && count<2048);
152 
153         q->whitebal = value;
154         return value;
155 }
156 
157 /* Initialize the QuickCam driver control structure.  This is where
158  * defaults are set for people who don't have a config file.*/
159 
160 static struct qcam_device *qcam_init(struct parport *port)
161 {
162         struct qcam_device *q;
163         
164         q = kmalloc(sizeof(struct qcam_device), GFP_KERNEL);
165         if(q==NULL)
166                 return NULL;
167 
168         q->pport = port;
169         q->pdev = parport_register_device(port, "bw-qcam", NULL, NULL,
170                                           NULL, 0, NULL);
171         if (q->pdev == NULL) 
172         {
173                 printk(KERN_ERR "bw-qcam: couldn't register for %s.\n",
174                        port->name);
175                 kfree(q);
176                 return NULL;
177         }
178         
179         memcpy(&q->vdev, &qcam_template, sizeof(qcam_template));
180         
181         init_MUTEX(&q->lock);
182 
183         q->port_mode = (QC_ANY | QC_NOTSET);
184         q->width = 320;
185         q->height = 240;
186         q->bpp = 4;
187         q->transfer_scale = 2;
188         q->contrast = 192;
189         q->brightness = 180;
190         q->whitebal = 105;
191         q->top = 1;
192         q->left = 14;
193         q->mode = -1;
194         q->status = QC_PARAM_CHANGE;
195         return q;
196 }
197 
198 
199 /* qc_command is probably a bit of a misnomer -- it's used to send
200  * bytes *to* the camera.  Generally, these bytes are either commands
201  * or arguments to commands, so the name fits, but it still bugs me a
202  * bit.  See the documentation for a list of commands. */
203 
204 static int qc_command(struct qcam_device *q, int command)
205 {
206         int n1, n2;
207         int cmd;
208 
209         write_lpdata(q, command);
210         write_lpcontrol(q, 6);
211 
212         n1 = qc_waithand(q, 1);
213 
214         write_lpcontrol(q, 0xe);
215         n2 = qc_waithand(q, 0);
216 
217         cmd = (n1 & 0xf0) | ((n2 & 0xf0) >> 4);
218         return cmd;
219 }
220 
221 static int qc_readparam(struct qcam_device *q)
222 {
223         int n1, n2;
224         int cmd;
225 
226         write_lpcontrol(q, 6);
227         n1 = qc_waithand(q, 1);
228 
229         write_lpcontrol(q, 0xe);
230         n2 = qc_waithand(q, 0);
231 
232         cmd = (n1 & 0xf0) | ((n2 & 0xf0) >> 4);
233         return cmd;
234 }
235 
236 /* qc_waithand busy-waits for a handshake signal from the QuickCam.
237  * Almost all communication with the camera requires handshaking. */
238 
239 static int qc_waithand(struct qcam_device *q, int val)
240 {
241         int status;
242         int runs=0;
243 
244         if (val)
245         {
246                 while (!((status = read_lpstatus(q)) & 8))
247                 {
248                         /* 1000 is enough spins on the I/O for all normal
249                            cases, at that point we start to poll slowly 
250                            until the camera wakes up. However, we are
251                            busy blocked until the camera responds, so
252                            setting it lower is much better for interactive
253                            response. */
254                            
255                         if(runs++>maxpoll)
256                         {
257                                 current->state=TASK_INTERRUPTIBLE;
258                                 schedule_timeout(HZ/200);
259                         }
260                         if(runs>(maxpoll+1000)) /* 5 seconds */
261                                 return -1;
262                 }
263         }
264         else
265         {
266                 while (((status = read_lpstatus(q)) & 8))
267                 {
268                         /* 1000 is enough spins on the I/O for all normal
269                            cases, at that point we start to poll slowly 
270                            until the camera wakes up. However, we are
271                            busy blocked until the camera responds, so
272                            setting it lower is much better for interactive
273                            response. */
274                            
275                         if(runs++>maxpoll)
276                         {
277                                 current->state=TASK_INTERRUPTIBLE;
278                                 schedule_timeout(HZ/200);
279                         }
280                         if(runs++>(maxpoll+1000)) /* 5 seconds */
281                                 return -1;
282                 }
283         }
284 
285         return status;
286 }
287 
288 /* Waithand2 is used when the qcam is in bidirectional mode, and the
289  * handshaking signal is CamRdy2 (bit 0 of data reg) instead of CamRdy1
290  * (bit 3 of status register).  It also returns the last value read,
291  * since this data is useful. */
292 
293 static unsigned int qc_waithand2(struct qcam_device *q, int val)
294 {
295         unsigned int status;
296         int runs=0;
297         
298         do 
299         {
300                 status = read_lpdata(q);
301                 /* 1000 is enough spins on the I/O for all normal
302                    cases, at that point we start to poll slowly 
303                    until the camera wakes up. However, we are
304                    busy blocked until the camera responds, so
305                    setting it lower is much better for interactive
306                    response. */
307                    
308                 if(runs++>maxpoll)
309                 {
310                         current->state=TASK_INTERRUPTIBLE;
311                         schedule_timeout(HZ/200);
312                 }
313                 if(runs++>(maxpoll+1000)) /* 5 seconds */
314                         return 0;
315         }
316         while ((status & 1) != val);
317 
318         return status;
319 }
320 
321 
322 /* Try to detect a QuickCam.  It appears to flash the upper 4 bits of
323    the status register at 5-10 Hz.  This is only used in the autoprobe
324    code.  Be aware that this isn't the way Connectix detects the
325    camera (they send a reset and try to handshake), but this should be
326    almost completely safe, while their method screws up my printer if
327    I plug it in before the camera. */
328 
329 static int qc_detect(struct qcam_device *q)
330 {
331         int reg, lastreg;
332         int count = 0;
333         int i;
334 
335         lastreg = reg = read_lpstatus(q) & 0xf0;
336 
337         for (i = 0; i < 500; i++) 
338         {
339                 reg = read_lpstatus(q) & 0xf0;
340                 if (reg != lastreg)
341                         count++;
342                 lastreg = reg;
343                 mdelay(2);
344         }
345 
346 
347 #if 0
348         /* Force camera detection during testing. Sometimes the camera
349            won't be flashing these bits. Possibly unloading the module
350            in the middle of a grab? Or some timeout condition?
351            I've seen this parameter as low as 19 on my 450Mhz box - mpc */
352         printk("Debugging: QCam detection counter <30-200 counts as detected>: %d\n", count);
353         return 1;
354 #endif
355 
356         /* Be (even more) liberal in what you accept...  */
357 
358 /*      if (count > 30 && count < 200) */
359         if (count > 20 && count < 300)
360                 return 1;       /* found */
361         else
362                 return 0;       /* not found */
363 }
364 
365 
366 /* Reset the QuickCam.  This uses the same sequence the Windows
367  * QuickPic program uses.  Someone with a bi-directional port should
368  * check that bi-directional mode is detected right, and then
369  * implement bi-directional mode in qc_readbyte(). */
370 
371 static void qc_reset(struct qcam_device *q)
372 {
373         switch (q->port_mode & QC_FORCE_MASK) 
374         {
375                 case QC_FORCE_UNIDIR:
376                         q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_UNIDIR;
377                         break;
378 
379                 case QC_FORCE_BIDIR:
380                         q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_BIDIR;
381                         break;
382 
383                 case QC_ANY:
384                         write_lpcontrol(q, 0x20);
385                         write_lpdata(q, 0x75);
386         
387                         if (read_lpdata(q) != 0x75) {
388                                 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_BIDIR;
389                         } else {
390                                 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_UNIDIR;
391                         }
392                         break;
393         }
394 
395         write_lpcontrol(q, 0xb);
396         udelay(250);
397         write_lpcontrol(q, 0xe);
398         qc_setscanmode(q);              /* in case port_mode changed */
399 }
400 
401 
402 /* Decide which scan mode to use.  There's no real requirement that
403  * the scanmode match the resolution in q->height and q-> width -- the
404  * camera takes the picture at the resolution specified in the
405  * "scanmode" and then returns the image at the resolution specified
406  * with the resolution commands.  If the scan is bigger than the
407  * requested resolution, the upper-left hand corner of the scan is
408  * returned.  If the scan is smaller, then the rest of the image
409  * returned contains garbage. */
410 
411 static int qc_setscanmode(struct qcam_device *q)
412 {
413         int old_mode = q->mode;
414         
415         switch (q->transfer_scale) 
416         {
417                 case 1:
418                         q->mode = 0;
419                         break;
420                 case 2:
421                         q->mode = 4;
422                         break;
423                 case 4:
424                         q->mode = 8;
425                         break;
426         }
427 
428         switch (q->bpp) 
429         {
430                 case 4:
431                         break;
432                 case 6:
433                         q->mode += 2;
434                         break;
435         }
436 
437         switch (q->port_mode & QC_MODE_MASK) 
438         {
439                 case QC_BIDIR:
440                         q->mode += 1;
441                         break;
442                 case QC_NOTSET:
443                 case QC_UNIDIR:
444                         break;
445         }
446         
447         if (q->mode != old_mode)
448                 q->status |= QC_PARAM_CHANGE;
449         
450         return 0;
451 }
452 
453 
454 /* Reset the QuickCam and program for brightness, contrast,
455  * white-balance, and resolution. */
456 
457 void qc_set(struct qcam_device *q)
458 {
459         int val;
460         int val2;
461 
462         qc_reset(q);
463 
464         /* Set the brightness.  Yes, this is repetitive, but it works.
465          * Shorter versions seem to fail subtly.  Feel free to try :-). */
466         /* I think the problem was in qc_command, not here -- bls */
467         
468         qc_command(q, 0xb);
469         qc_command(q, q->brightness);
470 
471         val = q->height / q->transfer_scale;
472         qc_command(q, 0x11);
473         qc_command(q, val);
474         if ((q->port_mode & QC_MODE_MASK) == QC_UNIDIR && q->bpp == 6) {
475                 /* The normal "transfers per line" calculation doesn't seem to work
476                    as expected here (and yet it works fine in qc_scan).  No idea
477                    why this case is the odd man out.  Fortunately, Laird's original
478                    working version gives me a good way to guess at working values.
479                    -- bls */
480                 val = q->width;
481                 val2 = q->transfer_scale * 4;
482         } else {
483                 val = q->width * q->bpp;
484                 val2 = (((q->port_mode & QC_MODE_MASK) == QC_BIDIR) ? 24 : 8) *
485                     q->transfer_scale;
486         }
487         val = (val + val2 - 1) / val2;
488         qc_command(q, 0x13);
489         qc_command(q, val);
490 
491         /* Setting top and left -- bls */
492         qc_command(q, 0xd);
493         qc_command(q, q->top);
494         qc_command(q, 0xf);
495         qc_command(q, q->left / 2);
496 
497         qc_command(q, 0x19);
498         qc_command(q, q->contrast);
499         qc_command(q, 0x1f);
500         qc_command(q, q->whitebal);
501 
502         /* Clear flag that we must update the grabbing parameters on the camera
503            before we grab the next frame */
504         q->status &= (~QC_PARAM_CHANGE);
505 }
506 
507 /* Qc_readbytes reads some bytes from the QC and puts them in
508    the supplied buffer.  It returns the number of bytes read,
509    or -1 on error. */
510 
511 extern __inline__ int qc_readbytes(struct qcam_device *q, char buffer[])
512 {
513         int ret=1;
514         unsigned int hi, lo;
515         unsigned int hi2, lo2;
516         static int state = 0;
517 
518         if (buffer == NULL) 
519         {
520                 state = 0;
521                 return 0;
522         }
523         
524         switch (q->port_mode & QC_MODE_MASK) 
525         {
526                 case QC_BIDIR:          /* Bi-directional Port */
527                         write_lpcontrol(q, 0x26);
528                         lo = (qc_waithand2(q, 1) >> 1);
529                         hi = (read_lpstatus(q) >> 3) & 0x1f;
530                         write_lpcontrol(q, 0x2e);
531                         lo2 = (qc_waithand2(q, 0) >> 1);
532                         hi2 = (read_lpstatus(q) >> 3) & 0x1f;
533                         switch (q->bpp) 
534                         {
535                                 case 4:
536                                         buffer[0] = lo & 0xf;
537                                         buffer[1] = ((lo & 0x70) >> 4) | ((hi & 1) << 3);
538                                         buffer[2] = (hi & 0x1e) >> 1;
539                                         buffer[3] = lo2 & 0xf;
540                                         buffer[4] = ((lo2 & 0x70) >> 4) | ((hi2 & 1) << 3);
541                                         buffer[5] = (hi2 & 0x1e) >> 1;
542                                         ret = 6;
543                                         break;
544                                 case 6:
545                                         buffer[0] = lo & 0x3f;
546                                         buffer[1] = ((lo & 0x40) >> 6) | (hi << 1);
547                                         buffer[2] = lo2 & 0x3f;
548                                         buffer[3] = ((lo2 & 0x40) >> 6) | (hi2 << 1);
549                                         ret = 4;
550                                         break;
551                         }
552                         break;
553 
554                 case QC_UNIDIR: /* Unidirectional Port */
555                         write_lpcontrol(q, 6);
556                         lo = (qc_waithand(q, 1) & 0xf0) >> 4;
557                         write_lpcontrol(q, 0xe);
558                         hi = (qc_waithand(q, 0) & 0xf0) >> 4;
559 
560                         switch (q->bpp) 
561                         {
562                                 case 4:
563                                         buffer[0] = lo;
564                                         buffer[1] = hi;
565                                         ret = 2;
566                                         break;
567                                 case 6:
568                                         switch (state) 
569                                         {
570                                                 case 0:
571                                                         buffer[0] = (lo << 2) | ((hi & 0xc) >> 2);
572                                                         q->saved_bits = (hi & 3) << 4;
573                                                         state = 1;
574                                                         ret = 1;
575                                                         break;
576                                                 case 1:
577                                                         buffer[0] = lo | q->saved_bits;
578                                                         q->saved_bits = hi << 2;
579                                                         state = 2;
580                                                         ret = 1;
581                                                         break;
582                                                 case 2:
583                                                         buffer[0] = ((lo & 0xc) >> 2) | q->saved_bits;
584                                                         buffer[1] = ((lo & 3) << 4) | hi;
585                                                         state = 0;
586                                                         ret = 2;
587                                                         break;
588                                         }
589                                         break;
590                         }
591                         break;
592         }
593         return ret;
594 }
595 
596 /* requests a scan from the camera.  It sends the correct instructions
597  * to the camera and then reads back the correct number of bytes.  In
598  * previous versions of this routine the return structure contained
599  * the raw output from the camera, and there was a 'qc_convertscan'
600  * function that converted that to a useful format.  In version 0.3 I
601  * rolled qc_convertscan into qc_scan and now I only return the
602  * converted scan.  The format is just an one-dimensional array of
603  * characters, one for each pixel, with 0=black up to n=white, where
604  * n=2^(bit depth)-1.  Ask me for more details if you don't understand
605  * this. */
606 
607 long qc_capture(struct qcam_device * q, char *buf, unsigned long len)
608 {
609         int i, j, k, yield;
610         int bytes;
611         int linestotrans, transperline;
612         int divisor;
613         int pixels_per_line;
614         int pixels_read = 0;
615         int got=0;
616         char buffer[6];
617         int  shift=8-q->bpp;
618         char invert;
619 
620         if (q->mode == -1) 
621                 return -ENXIO;
622 
623         qc_command(q, 0x7);
624         qc_command(q, q->mode);
625 
626         if ((q->port_mode & QC_MODE_MASK) == QC_BIDIR) 
627         {
628                 write_lpcontrol(q, 0x2e);       /* turn port around */
629                 write_lpcontrol(q, 0x26);
630                 (void) qc_waithand(q, 1);
631                 write_lpcontrol(q, 0x2e);
632                 (void) qc_waithand(q, 0);
633         }
634         
635         /* strange -- should be 15:63 below, but 4bpp is odd */
636         invert = (q->bpp == 4) ? 16 : 63;
637 
638         linestotrans = q->height / q->transfer_scale;
639         pixels_per_line = q->width / q->transfer_scale;
640         transperline = q->width * q->bpp;
641         divisor = (((q->port_mode & QC_MODE_MASK) == QC_BIDIR) ? 24 : 8) *
642             q->transfer_scale;
643         transperline = (transperline + divisor - 1) / divisor;
644 
645         for (i = 0, yield = yieldlines; i < linestotrans; i++) 
646         {
647                 for (pixels_read = j = 0; j < transperline; j++) 
648                 {
649                         bytes = qc_readbytes(q, buffer);
650                         for (k = 0; k < bytes && (pixels_read + k) < pixels_per_line; k++) 
651                         {
652                                 int o;
653                                 if (buffer[k] == 0 && invert == 16) 
654                                 {
655                                         /* 4bpp is odd (again) -- inverter is 16, not 15, but output
656                                            must be 0-15 -- bls */
657                                         buffer[k] = 16;
658                                 }
659                                 o=i*pixels_per_line + pixels_read + k;
660                                 if(o<len)
661                                 {
662                                         got++;
663                                         put_user((invert - buffer[k])<<shift, buf+o);
664                                 }
665                         }
666                         pixels_read += bytes;
667                 }
668                 (void) qc_readbytes(q, 0);      /* reset state machine */
669                 
670                 /* Grabbing an entire frame from the quickcam is a lengthy
671                    process. We don't (usually) want to busy-block the
672                    processor for the entire frame. yieldlines is a module
673                    parameter. If we yield every line, the minimum frame
674                    time will be 240 / 200 = 1.2 seconds. The compile-time
675                    default is to yield every 4 lines. */
676                 if (i >= yield) {
677                         current->state=TASK_INTERRUPTIBLE;
678                         schedule_timeout(HZ/200);
679                         yield = i + yieldlines;
680                 }
681         }
682 
683         if ((q->port_mode & QC_MODE_MASK) == QC_BIDIR) 
684         {
685                 write_lpcontrol(q, 2);
686                 write_lpcontrol(q, 6);
687                 udelay(3);
688                 write_lpcontrol(q, 0xe);
689         }
690         if(got<len)
691                 return got;
692         return len;
693 }
694 
695 /*
696  *      Video4linux interfacing
697  */
698 
699 static int qcam_open(struct video_device *dev, int flags)
700 {
701         return 0;
702 }
703 
704 static void qcam_close(struct video_device *dev)
705 {
706 }
707 
708 static long qcam_write(struct video_device *v, const char *buf, unsigned long count, int noblock)
709 {
710         return -EINVAL;
711 }
712 
713 static int qcam_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
714 {
715         struct qcam_device *qcam=(struct qcam_device *)dev;
716         
717         switch(cmd)
718         {
719                 case VIDIOCGCAP:
720                 {
721                         struct video_capability b;
722                         strcpy(b.name, "Quickcam");
723                         b.type = VID_TYPE_CAPTURE|VID_TYPE_SCALES|VID_TYPE_MONOCHROME;
724                         b.channels = 1;
725                         b.audios = 0;
726                         b.maxwidth = 320;
727                         b.maxheight = 240;
728                         b.minwidth = 80;
729                         b.minheight = 60;
730                         if(copy_to_user(arg, &b,sizeof(b)))
731                                 return -EFAULT;
732                         return 0;
733                 }
734                 case VIDIOCGCHAN:
735                 {
736                         struct video_channel v;
737                         if(copy_from_user(&v, arg, sizeof(v)))
738                                 return -EFAULT;
739                         if(v.channel!=0)
740                                 return -EINVAL;
741                         v.flags=0;
742                         v.tuners=0;
743                         /* Good question.. its composite or SVHS so.. */
744                         v.type = VIDEO_TYPE_CAMERA;
745                         strcpy(v.name, "Camera");
746                         if(copy_to_user(arg, &v, sizeof(v)))
747                                 return -EFAULT;
748                         return 0;
749                 }
750                 case VIDIOCSCHAN:
751                 {
752                         int v;
753                         if(copy_from_user(&v, arg,sizeof(v)))
754                                 return -EFAULT;
755                         if(v!=0)
756                                 return -EINVAL;
757                         return 0;
758                 }
759                 case VIDIOCGTUNER:
760                 {
761                         struct video_tuner v;
762                         if(copy_from_user(&v, arg, sizeof(v))!=0)
763                                 return -EFAULT;
764                         if(v.tuner)
765                                 return -EINVAL;
766                         strcpy(v.name, "Format");
767                         v.rangelow=0;
768                         v.rangehigh=0;
769                         v.flags= 0;
770                         v.mode = VIDEO_MODE_AUTO;
771                         if(copy_to_user(arg,&v,sizeof(v))!=0)
772                                 return -EFAULT;
773                         return 0;
774                 }
775                 case VIDIOCSTUNER:
776                 {
777                         struct video_tuner v;
778                         if(copy_from_user(&v, arg, sizeof(v))!=0)
779                                 return -EFAULT;
780                         if(v.tuner)
781                                 return -EINVAL;
782                         if(v.mode!=VIDEO_MODE_AUTO)
783                                 return -EINVAL;
784                         return 0;
785                 }
786                 case VIDIOCGPICT:
787                 {
788                         struct video_picture p;
789                         p.colour=0x8000;
790                         p.hue=0x8000;
791                         p.brightness=qcam->brightness<<8;
792                         p.contrast=qcam->contrast<<8;
793                         p.whiteness=qcam->whitebal<<8;
794                         p.depth=qcam->bpp;
795                         p.palette=VIDEO_PALETTE_GREY;
796                         if(copy_to_user(arg, &p, sizeof(p)))
797                                 return -EFAULT;
798                         return 0;
799                 }
800                 case VIDIOCSPICT:
801                 {
802                         struct video_picture p;
803                         if(copy_from_user(&p, arg, sizeof(p)))
804                                 return -EFAULT;
805                         if(p.palette!=VIDEO_PALETTE_GREY)
806                                 return -EINVAL;
807                         if(p.depth!=4 && p.depth!=6)
808                                 return -EINVAL;
809                         
810                         /*
811                          *      Now load the camera.
812                          */
813 
814                         qcam->brightness = p.brightness>>8;
815                         qcam->contrast = p.contrast>>8;
816                         qcam->whitebal = p.whiteness>>8;
817                         qcam->bpp = p.depth;
818 
819                         down(&qcam->lock);                      
820                         qc_setscanmode(qcam);
821                         up(&qcam->lock);
822                         qcam->status |= QC_PARAM_CHANGE;
823 
824                         return 0;
825                 }
826                 case VIDIOCSWIN:
827                 {
828                         struct video_window vw;
829                         if(copy_from_user(&vw, arg,sizeof(vw)))
830                                 return -EFAULT;
831                         if(vw.flags)
832                                 return -EINVAL;
833                         if(vw.clipcount)
834                                 return -EINVAL;
835                         if(vw.height<60||vw.height>240)
836                                 return -EINVAL;
837                         if(vw.width<80||vw.width>320)
838                                 return -EINVAL;
839                                 
840                         qcam->width = 320;
841                         qcam->height = 240;
842                         qcam->transfer_scale = 4;
843                         
844                         if(vw.width>=160 && vw.height>=120)
845                         {
846                                 qcam->transfer_scale = 2;
847                         }
848                         if(vw.width>=320 && vw.height>=240)
849                         {
850                                 qcam->width = 320;
851                                 qcam->height = 240;
852                                 qcam->transfer_scale = 1;
853                         }
854                         down(&qcam->lock);
855                         qc_setscanmode(qcam);
856                         up(&qcam->lock);
857                         
858                         /* We must update the camera before we grab. We could
859                            just have changed the grab size */
860                         qcam->status |= QC_PARAM_CHANGE;
861                         
862                         /* Ok we figured out what to use from our wide choice */
863                         return 0;
864                 }
865                 case VIDIOCGWIN:
866                 {
867                         struct video_window vw;
868                         memset(&vw, 0, sizeof(vw));
869                         vw.width=qcam->width/qcam->transfer_scale;
870                         vw.height=qcam->height/qcam->transfer_scale;
871                         if(copy_to_user(arg, &vw, sizeof(vw)))
872                                 return -EFAULT;
873                         return 0;
874                 }
875                 case VIDIOCCAPTURE:
876                         return -EINVAL;
877                 case VIDIOCGFBUF:
878                         return -EINVAL;
879                 case VIDIOCSFBUF:
880                         return -EINVAL;
881                 case VIDIOCKEY:
882                         return 0;
883                 case VIDIOCGFREQ:
884                         return -EINVAL;
885                 case VIDIOCSFREQ:
886                         return -EINVAL;
887                 case VIDIOCGAUDIO:
888                         return -EINVAL;
889                 case VIDIOCSAUDIO:
890                         return -EINVAL;
891                 default:
892                         return -ENOIOCTLCMD;
893         }
894         return 0;
895 }
896 
897 static long qcam_read(struct video_device *v, char *buf, unsigned long count,  int noblock)
898 {
899         struct qcam_device *qcam=(struct qcam_device *)v;
900         int len;
901         parport_claim_or_block(qcam->pdev);
902         
903         down(&qcam->lock);
904         
905         qc_reset(qcam);
906 
907         /* Update the camera parameters if we need to */
908         if (qcam->status & QC_PARAM_CHANGE)
909                 qc_set(qcam);
910 
911         len=qc_capture(qcam, buf,count);
912         
913         up(&qcam->lock);
914         
915         parport_release(qcam->pdev);
916         return len;
917 }
918  
919 static struct video_device qcam_template=
920 {
921         owner:          THIS_MODULE,
922         name:           "Connectix Quickcam",
923         type:           VID_TYPE_CAPTURE,
924         hardware:       VID_HARDWARE_QCAM_BW,
925         open:           qcam_open,
926         close:          qcam_close,
927         read:           qcam_read,
928         write:          qcam_write,
929         ioctl:          qcam_ioctl,
930 };
931 
932 #define MAX_CAMS 4
933 static struct qcam_device *qcams[MAX_CAMS];
934 static unsigned int num_cams = 0;
935 
936 int init_bwqcam(struct parport *port)
937 {
938         struct qcam_device *qcam;
939 
940         if (num_cams == MAX_CAMS)
941         {
942                 printk(KERN_ERR "Too many Quickcams (max %d)\n", MAX_CAMS);
943                 return -ENOSPC;
944         }
945 
946         qcam=qcam_init(port);
947         if(qcam==NULL)
948                 return -ENODEV;
949                 
950         parport_claim_or_block(qcam->pdev);
951 
952         qc_reset(qcam);
953         
954         if(qc_detect(qcam)==0)
955         {
956                 parport_release(qcam->pdev);
957                 parport_unregister_device(qcam->pdev);
958                 kfree(qcam);
959                 return -ENODEV;
960         }
961         qc_calibrate(qcam);
962 
963         parport_release(qcam->pdev);
964         
965         printk(KERN_INFO "Connectix Quickcam on %s\n", qcam->pport->name);
966         
967         if(video_register_device(&qcam->vdev, VFL_TYPE_GRABBER, video_nr)==-1)
968         {
969                 parport_unregister_device(qcam->pdev);
970                 kfree(qcam);
971                 return -ENODEV;
972         }
973 
974         qcams[num_cams++] = qcam;
975 
976         return 0;
977 }
978 
979 void close_bwqcam(struct qcam_device *qcam)
980 {
981         video_unregister_device(&qcam->vdev);
982         parport_unregister_device(qcam->pdev);
983         kfree(qcam);
984 }
985 
986 /* The parport parameter controls which parports will be scanned.
987  * Scanning all parports causes some printers to print a garbage page.
988  *       -- March 14, 1999  Billy Donahue <billy@escape.com> */
989 #ifdef MODULE
990 static char *parport[MAX_CAMS] = { NULL, };
991 MODULE_PARM(parport, "1-" __MODULE_STRING(MAX_CAMS) "s");
992 #endif
993 
994 #ifdef MODULE
995 int init_module(void)
996 {
997         struct parport *port;
998         int n;
999         if(parport[0] && strncmp(parport[0], "auto", 4)){
1000                 /* user gave parport parameters */
1001                 for(n=0; parport[n] && n<MAX_CAMS; n++){
1002                         char *ep;
1003                         unsigned long r;
1004                         r = simple_strtoul(parport[n], &ep, 0);
1005                         if(ep == parport[n]){
1006                                 printk(KERN_ERR
1007                                         "bw-qcam: bad port specifier \"%s\"\n",
1008                                         parport[n]);
1009                                 continue;
1010                         }
1011                         for (port=parport_enumerate(); port; port=port->next){
1012                                 if(r!=port->number)
1013                                         continue;
1014                                 init_bwqcam(port);
1015                                 break;
1016                         }
1017                 }
1018                 return (num_cams)?0:-ENODEV;
1019         } 
1020         /* no parameter or "auto" */
1021         for (port = parport_enumerate(); port; port=port->next)
1022                 init_bwqcam(port);
1023 
1024         /* Do some sanity checks on the module parameters. */
1025         if (maxpoll > 5000) {
1026                 printk("Connectix Quickcam max-poll was above 5000. Using 5000.\n");
1027                 maxpoll = 5000;
1028         }
1029         
1030         if (yieldlines < 1) {
1031                 printk("Connectix Quickcam yieldlines was less than 1. Using 1.\n");
1032                 yieldlines = 1;
1033         }
1034 
1035         return (num_cams)?0:-ENODEV;
1036 }
1037 
1038 void cleanup_module(void)
1039 {
1040         unsigned int i;
1041         for (i = 0; i < num_cams; i++)
1042                 close_bwqcam(qcams[i]);
1043 }
1044 #else
1045 int __init init_bw_qcams(struct video_init *unused)
1046 {
1047         struct parport *port;
1048 
1049         for (port = parport_enumerate(); port; port=port->next)
1050                 init_bwqcam(port);
1051         return 0;
1052 }
1053 #endif
1054 

~ [ 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.