OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [media/] [video/] [bw-qcam.c] - Blame information for rev 1774

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.