linux-old/drivers/media/video/bw-qcam.c
<<
>>
Prefs
   1/*
   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
  42Copyright (C) 1996 by Scott Laird
  43
  44Permission is hereby granted, free of charge, to any person obtaining
  45a copy of this software and associated documentation files (the
  46"Software"), to deal in the Software without restriction, including
  47without limitation the rights to use, copy, modify, merge, publish,
  48distribute, sublicense, and/or sell copies of the Software, and to
  49permit persons to whom the Software is furnished to do so, subject to
  50the following conditions:
  51
  52The above copyright notice and this permission notice shall be
  53included in all copies or substantial portions of the Software.
  54
  55THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  56EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  57MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  58IN NO EVENT SHALL SCOTT LAIRD BE LIABLE FOR ANY CLAIM, DAMAGES OR
  59OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  60ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  61OTHER 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
  82static unsigned int maxpoll=250;   /* Maximum busy-loop count for qcam I/O */
  83static unsigned int yieldlines=4;  /* Yield after this many during capture */
  84static int video_nr = -1;
  85
  86#if LINUX_VERSION_CODE >= 0x020117
  87MODULE_PARM(maxpoll,"i");
  88MODULE_PARM(yieldlines,"i");   
  89MODULE_PARM(video_nr,"i");
  90#endif
  91
  92static inline int read_lpstatus(struct qcam_device *q)
  93{
  94        return parport_read_status(q->pport);
  95}
  96
  97static inline int read_lpcontrol(struct qcam_device *q)
  98{
  99        return parport_read_control(q->pport);
 100}
 101
 102static inline int read_lpdata(struct qcam_device *q)
 103{
 104        return parport_read_data(q->pport);
 105}
 106
 107static inline void write_lpdata(struct qcam_device *q, int d)
 108{
 109        parport_write_data(q->pport, d);
 110}
 111
 112static inline void write_lpcontrol(struct qcam_device *q, int d)
 113{
 114        parport_write_control(q->pport, d);
 115}
 116
 117static int qc_waithand(struct qcam_device *q, int val);
 118static int qc_command(struct qcam_device *q, int command);
 119static int qc_readparam(struct qcam_device *q);
 120static int qc_setscanmode(struct qcam_device *q);
 121static int qc_readbytes(struct qcam_device *q, char buffer[]);
 122
 123static struct video_device qcam_template;
 124
 125static 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
 158static 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
 202static 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
 219static 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
 237static 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
 291static 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
 327static 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
 369static 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
 409static 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
 455void 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
 509static 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
 605long 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
 697static int qcam_open(struct video_device *dev, int flags)
 698{
 699        return 0;
 700}
 701
 702static void qcam_close(struct video_device *dev)
 703{
 704}
 705
 706static long qcam_write(struct video_device *v, const char *buf, unsigned long count, int noblock)
 707{
 708        return -EINVAL;
 709}
 710
 711static 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
 895static 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 
 917static 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
 931static struct qcam_device *qcams[MAX_CAMS];
 932static unsigned int num_cams = 0;
 933
 934int 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
 977void 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
 988static char *parport[MAX_CAMS] = { NULL, };
 989MODULE_PARM(parport, "1-" __MODULE_STRING(MAX_CAMS) "s");
 990#endif
 991
 992static 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
1000static 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
1050module_init(init_bw_qcams);
1051module_exit(exit_bw_qcams);
1052
1053MODULE_LICENSE("GPL");
1054
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.