linux/drivers/media/parport/c-qcam.c
<<
>>
Prefs
   1/*
   2 *      Video4Linux Colour QuickCam driver
   3 *      Copyright 1997-2000 Philip Blundell <philb@gnu.org>
   4 *
   5 *    Module parameters:
   6 *
   7 *      parport=auto      -- probe all parports (default)
   8 *      parport=0         -- parport0 becomes qcam1
   9 *      parport=2,0,1     -- parports 2,0,1 are tried in that order
  10 *
  11 *      probe=0           -- do no probing, assume camera is present
  12 *      probe=1           -- use IEEE-1284 autoprobe data only (default)
  13 *      probe=2           -- probe aggressively for cameras
  14 *
  15 *      force_rgb=1       -- force data format to RGB (default is BGR)
  16 *
  17 * The parport parameter controls which parports will be scanned.
  18 * Scanning all parports causes some printers to print a garbage page.
  19 *       -- March 14, 1999  Billy Donahue <billy@escape.com>
  20 *
  21 * Fixed data format to BGR, added force_rgb parameter. Added missing
  22 * parport_unregister_driver() on module removal.
  23 *       -- May 28, 2000  Claudio Matsuoka <claudio@conectiva.com>
  24 */
  25
  26#include <linux/module.h>
  27#include <linux/delay.h>
  28#include <linux/errno.h>
  29#include <linux/fs.h>
  30#include <linux/init.h>
  31#include <linux/kernel.h>
  32#include <linux/slab.h>
  33#include <linux/mm.h>
  34#include <linux/parport.h>
  35#include <linux/sched.h>
  36#include <linux/mutex.h>
  37#include <linux/jiffies.h>
  38#include <linux/videodev2.h>
  39#include <asm/uaccess.h>
  40#include <media/v4l2-device.h>
  41#include <media/v4l2-common.h>
  42#include <media/v4l2-ioctl.h>
  43#include <media/v4l2-fh.h>
  44#include <media/v4l2-ctrls.h>
  45#include <media/v4l2-event.h>
  46
  47struct qcam {
  48        struct v4l2_device v4l2_dev;
  49        struct video_device vdev;
  50        struct v4l2_ctrl_handler hdl;
  51        struct pardevice *pdev;
  52        struct parport *pport;
  53        int width, height;
  54        int ccd_width, ccd_height;
  55        int mode;
  56        int contrast, brightness, whitebal;
  57        int top, left;
  58        unsigned int bidirectional;
  59        struct mutex lock;
  60};
  61
  62/* cameras maximum */
  63#define MAX_CAMS 4
  64
  65/* The three possible QuickCam modes */
  66#define QC_MILLIONS     0x18
  67#define QC_BILLIONS     0x10
  68#define QC_THOUSANDS    0x08    /* with VIDEC compression (not supported) */
  69
  70/* The three possible decimations */
  71#define QC_DECIMATION_1         0
  72#define QC_DECIMATION_2         2
  73#define QC_DECIMATION_4         4
  74
  75#define BANNER "Colour QuickCam for Video4Linux v0.06"
  76
  77static int parport[MAX_CAMS] = { [1 ... MAX_CAMS-1] = -1 };
  78static int probe = 2;
  79static bool force_rgb;
  80static int video_nr = -1;
  81
  82/* FIXME: parport=auto would never have worked, surely? --RR */
  83MODULE_PARM_DESC(parport, "parport=<auto|n[,n]...> for port detection method\n"
  84                          "probe=<0|1|2> for camera detection method\n"
  85                          "force_rgb=<0|1> for RGB data format (default BGR)");
  86module_param_array(parport, int, NULL, 0);
  87module_param(probe, int, 0);
  88module_param(force_rgb, bool, 0);
  89module_param(video_nr, int, 0);
  90
  91static struct qcam *qcams[MAX_CAMS];
  92static unsigned int num_cams;
  93
  94static inline void qcam_set_ack(struct qcam *qcam, unsigned int i)
  95{
  96        /* note: the QC specs refer to the PCAck pin by voltage, not
  97           software level.  PC ports have builtin inverters. */
  98        parport_frob_control(qcam->pport, 8, i ? 8 : 0);
  99}
 100
 101static inline unsigned int qcam_ready1(struct qcam *qcam)
 102{
 103        return (parport_read_status(qcam->pport) & 0x8) ? 1 : 0;
 104}
 105
 106static inline unsigned int qcam_ready2(struct qcam *qcam)
 107{
 108        return (parport_read_data(qcam->pport) & 0x1) ? 1 : 0;
 109}
 110
 111static unsigned int qcam_await_ready1(struct qcam *qcam, int value)
 112{
 113        struct v4l2_device *v4l2_dev = &qcam->v4l2_dev;
 114        unsigned long oldjiffies = jiffies;
 115        unsigned int i;
 116
 117        for (oldjiffies = jiffies;
 118             time_before(jiffies, oldjiffies + msecs_to_jiffies(40));)
 119                if (qcam_ready1(qcam) == value)
 120                        return 0;
 121
 122        /* If the camera didn't respond within 1/25 second, poll slowly
 123           for a while. */
 124        for (i = 0; i < 50; i++) {
 125                if (qcam_ready1(qcam) == value)
 126                        return 0;
 127                msleep_interruptible(100);
 128        }
 129
 130        /* Probably somebody pulled the plug out.  Not much we can do. */
 131        v4l2_err(v4l2_dev, "ready1 timeout (%d) %x %x\n", value,
 132               parport_read_status(qcam->pport),
 133               parport_read_control(qcam->pport));
 134        return 1;
 135}
 136
 137static unsigned int qcam_await_ready2(struct qcam *qcam, int value)
 138{
 139        struct v4l2_device *v4l2_dev = &qcam->v4l2_dev;
 140        unsigned long oldjiffies = jiffies;
 141        unsigned int i;
 142
 143        for (oldjiffies = jiffies;
 144             time_before(jiffies, oldjiffies + msecs_to_jiffies(40));)
 145                if (qcam_ready2(qcam) == value)
 146                        return 0;
 147
 148        /* If the camera didn't respond within 1/25 second, poll slowly
 149           for a while. */
 150        for (i = 0; i < 50; i++) {
 151                if (qcam_ready2(qcam) == value)
 152                        return 0;
 153                msleep_interruptible(100);
 154        }
 155
 156        /* Probably somebody pulled the plug out.  Not much we can do. */
 157        v4l2_err(v4l2_dev, "ready2 timeout (%d) %x %x %x\n", value,
 158               parport_read_status(qcam->pport),
 159               parport_read_control(qcam->pport),
 160               parport_read_data(qcam->pport));
 161        return 1;
 162}
 163
 164static int qcam_read_data(struct qcam *qcam)
 165{
 166        unsigned int idata;
 167
 168        qcam_set_ack(qcam, 0);
 169        if (qcam_await_ready1(qcam, 1))
 170                return -1;
 171        idata = parport_read_status(qcam->pport) & 0xf0;
 172        qcam_set_ack(qcam, 1);
 173        if (qcam_await_ready1(qcam, 0))
 174                return -1;
 175        idata |= parport_read_status(qcam->pport) >> 4;
 176        return idata;
 177}
 178
 179static int qcam_write_data(struct qcam *qcam, unsigned int data)
 180{
 181        struct v4l2_device *v4l2_dev = &qcam->v4l2_dev;
 182        unsigned int idata;
 183
 184        parport_write_data(qcam->pport, data);
 185        idata = qcam_read_data(qcam);
 186        if (data != idata) {
 187                v4l2_warn(v4l2_dev, "sent %x but received %x\n", data,
 188                       idata);
 189                return 1;
 190        }
 191        return 0;
 192}
 193
 194static inline int qcam_set(struct qcam *qcam, unsigned int cmd, unsigned int data)
 195{
 196        if (qcam_write_data(qcam, cmd))
 197                return -1;
 198        if (qcam_write_data(qcam, data))
 199                return -1;
 200        return 0;
 201}
 202
 203static inline int qcam_get(struct qcam *qcam, unsigned int cmd)
 204{
 205        if (qcam_write_data(qcam, cmd))
 206                return -1;
 207        return qcam_read_data(qcam);
 208}
 209
 210static int qc_detect(struct qcam *qcam)
 211{
 212        unsigned int stat, ostat, i, count = 0;
 213
 214        /* The probe routine below is not very reliable.  The IEEE-1284
 215           probe takes precedence. */
 216        /* XXX Currently parport provides no way to distinguish between
 217           "the IEEE probe was not done" and "the probe was done, but
 218           no device was found".  Fix this one day. */
 219        if (qcam->pport->probe_info[0].class == PARPORT_CLASS_MEDIA
 220            && qcam->pport->probe_info[0].model
 221            && !strcmp(qcam->pdev->port->probe_info[0].model,
 222                       "Color QuickCam 2.0")) {
 223                printk(KERN_DEBUG "QuickCam: Found by IEEE1284 probe.\n");
 224                return 1;
 225        }
 226
 227        if (probe < 2)
 228                return 0;
 229
 230        parport_write_control(qcam->pport, 0xc);
 231
 232        /* look for a heartbeat */
 233        ostat = stat = parport_read_status(qcam->pport);
 234        for (i = 0; i < 250; i++) {
 235                mdelay(1);
 236                stat = parport_read_status(qcam->pport);
 237                if (ostat != stat) {
 238                        if (++count >= 3)
 239                                return 1;
 240                        ostat = stat;
 241                }
 242        }
 243
 244        /* Reset the camera and try again */
 245        parport_write_control(qcam->pport, 0xc);
 246        parport_write_control(qcam->pport, 0x8);
 247        mdelay(1);
 248        parport_write_control(qcam->pport, 0xc);
 249        mdelay(1);
 250        count = 0;
 251
 252        ostat = stat = parport_read_status(qcam->pport);
 253        for (i = 0; i < 250; i++) {
 254                mdelay(1);
 255                stat = parport_read_status(qcam->pport);
 256                if (ostat != stat) {
 257                        if (++count >= 3)
 258                                return 1;
 259                        ostat = stat;
 260                }
 261        }
 262
 263        /* no (or flatline) camera, give up */
 264        return 0;
 265}
 266
 267static void qc_reset(struct qcam *qcam)
 268{
 269        parport_write_control(qcam->pport, 0xc);
 270        parport_write_control(qcam->pport, 0x8);
 271        mdelay(1);
 272        parport_write_control(qcam->pport, 0xc);
 273        mdelay(1);
 274}
 275
 276/* Reset the QuickCam and program for brightness, contrast,
 277 * white-balance, and resolution. */
 278
 279static void qc_setup(struct qcam *qcam)
 280{
 281        qc_reset(qcam);
 282
 283        /* Set the brightness. */
 284        qcam_set(qcam, 11, qcam->brightness);
 285
 286        /* Set the height and width.  These refer to the actual
 287           CCD area *before* applying the selected decimation.  */
 288        qcam_set(qcam, 17, qcam->ccd_height);
 289        qcam_set(qcam, 19, qcam->ccd_width / 2);
 290
 291        /* Set top and left.  */
 292        qcam_set(qcam, 0xd, qcam->top);
 293        qcam_set(qcam, 0xf, qcam->left);
 294
 295        /* Set contrast and white balance.  */
 296        qcam_set(qcam, 0x19, qcam->contrast);
 297        qcam_set(qcam, 0x1f, qcam->whitebal);
 298
 299        /* Set the speed.  */
 300        qcam_set(qcam, 45, 2);
 301}
 302
 303/* Read some bytes from the camera and put them in the buffer.
 304   nbytes should be a multiple of 3, because bidirectional mode gives
 305   us three bytes at a time.  */
 306
 307static unsigned int qcam_read_bytes(struct qcam *qcam, unsigned char *buf, unsigned int nbytes)
 308{
 309        unsigned int bytes = 0;
 310
 311        qcam_set_ack(qcam, 0);
 312        if (qcam->bidirectional) {
 313                /* It's a bidirectional port */
 314                while (bytes < nbytes) {
 315                        unsigned int lo1, hi1, lo2, hi2;
 316                        unsigned char r, g, b;
 317
 318                        if (qcam_await_ready2(qcam, 1))
 319                                return bytes;
 320                        lo1 = parport_read_data(qcam->pport) >> 1;
 321                        hi1 = ((parport_read_status(qcam->pport) >> 3) & 0x1f) ^ 0x10;
 322                        qcam_set_ack(qcam, 1);
 323                        if (qcam_await_ready2(qcam, 0))
 324                                return bytes;
 325                        lo2 = parport_read_data(qcam->pport) >> 1;
 326                        hi2 = ((parport_read_status(qcam->pport) >> 3) & 0x1f) ^ 0x10;
 327                        qcam_set_ack(qcam, 0);
 328                        r = lo1 | ((hi1 & 1) << 7);
 329                        g = ((hi1 & 0x1e) << 3) | ((hi2 & 0x1e) >> 1);
 330                        b = lo2 | ((hi2 & 1) << 7);
 331                        if (force_rgb) {
 332                                buf[bytes++] = r;
 333                                buf[bytes++] = g;
 334                                buf[bytes++] = b;
 335                        } else {
 336                                buf[bytes++] = b;
 337                                buf[bytes++] = g;
 338                                buf[bytes++] = r;
 339                        }
 340                }
 341        } else {
 342                /* It's a unidirectional port */
 343                int i = 0, n = bytes;
 344                unsigned char rgb[3];
 345
 346                while (bytes < nbytes) {
 347                        unsigned int hi, lo;
 348
 349                        if (qcam_await_ready1(qcam, 1))
 350                                return bytes;
 351                        hi = (parport_read_status(qcam->pport) & 0xf0);
 352                        qcam_set_ack(qcam, 1);
 353                        if (qcam_await_ready1(qcam, 0))
 354                                return bytes;
 355                        lo = (parport_read_status(qcam->pport) & 0xf0);
 356                        qcam_set_ack(qcam, 0);
 357                        /* flip some bits */
 358                        rgb[(i = bytes++ % 3)] = (hi | (lo >> 4)) ^ 0x88;
 359                        if (i >= 2) {
 360get_fragment:
 361                                if (force_rgb) {
 362                                        buf[n++] = rgb[0];
 363                                        buf[n++] = rgb[1];
 364                                        buf[n++] = rgb[2];
 365                                } else {
 366                                        buf[n++] = rgb[2];
 367                                        buf[n++] = rgb[1];
 368                                        buf[n++] = rgb[0];
 369                                }
 370                        }
 371                }
 372                if (i) {
 373                        i = 0;
 374                        goto get_fragment;
 375                }
 376        }
 377        return bytes;
 378}
 379
 380#define BUFSZ   150
 381
 382static long qc_capture(struct qcam *qcam, char __user *buf, unsigned long len)
 383{
 384        struct v4l2_device *v4l2_dev = &qcam->v4l2_dev;
 385        unsigned lines, pixelsperline;
 386        unsigned int is_bi_dir = qcam->bidirectional;
 387        size_t wantlen, outptr = 0;
 388        char tmpbuf[BUFSZ];
 389
 390        if (!access_ok(VERIFY_WRITE, buf, len))
 391                return -EFAULT;
 392
 393        /* Wait for camera to become ready */
 394        for (;;) {
 395                int i = qcam_get(qcam, 41);
 396
 397                if (i == -1) {
 398                        qc_setup(qcam);
 399                        return -EIO;
 400                }
 401                if ((i & 0x80) == 0)
 402                        break;
 403                schedule();
 404        }
 405
 406        if (qcam_set(qcam, 7, (qcam->mode | (is_bi_dir ? 1 : 0)) + 1))
 407                return -EIO;
 408
 409        lines = qcam->height;
 410        pixelsperline = qcam->width;
 411
 412        if (is_bi_dir) {
 413                /* Turn the port around */
 414                parport_data_reverse(qcam->pport);
 415                mdelay(3);
 416                qcam_set_ack(qcam, 0);
 417                if (qcam_await_ready1(qcam, 1)) {
 418                        qc_setup(qcam);
 419                        return -EIO;
 420                }
 421                qcam_set_ack(qcam, 1);
 422                if (qcam_await_ready1(qcam, 0)) {
 423                        qc_setup(qcam);
 424                        return -EIO;
 425                }
 426        }
 427
 428        wantlen = lines * pixelsperline * 24 / 8;
 429
 430        while (wantlen) {
 431                size_t t, s;
 432
 433                s = (wantlen > BUFSZ) ? BUFSZ : wantlen;
 434                t = qcam_read_bytes(qcam, tmpbuf, s);
 435                if (outptr < len) {
 436                        size_t sz = len - outptr;
 437
 438                        if (sz > t)
 439                                sz = t;
 440                        if (__copy_to_user(buf + outptr, tmpbuf, sz))
 441                                break;
 442                        outptr += sz;
 443                }
 444                wantlen -= t;
 445                if (t < s)
 446                        break;
 447                cond_resched();
 448        }
 449
 450        len = outptr;
 451
 452        if (wantlen) {
 453                v4l2_err(v4l2_dev, "short read.\n");
 454                if (is_bi_dir)
 455                        parport_data_forward(qcam->pport);
 456                qc_setup(qcam);
 457                return len;
 458        }
 459
 460        if (is_bi_dir) {
 461                int l;
 462
 463                do {
 464                        l = qcam_read_bytes(qcam, tmpbuf, 3);
 465                        cond_resched();
 466                } while (l && (tmpbuf[0] == 0x7e || tmpbuf[1] == 0x7e || tmpbuf[2] == 0x7e));
 467                if (force_rgb) {
 468                        if (tmpbuf[0] != 0xe || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xf)
 469                                v4l2_err(v4l2_dev, "bad EOF\n");
 470                } else {
 471                        if (tmpbuf[0] != 0xf || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xe)
 472                                v4l2_err(v4l2_dev, "bad EOF\n");
 473                }
 474                qcam_set_ack(qcam, 0);
 475                if (qcam_await_ready1(qcam, 1)) {
 476                        v4l2_err(v4l2_dev, "no ack after EOF\n");
 477                        parport_data_forward(qcam->pport);
 478                        qc_setup(qcam);
 479                        return len;
 480                }
 481                parport_data_forward(qcam->pport);
 482                mdelay(3);
 483                qcam_set_ack(qcam, 1);
 484                if (qcam_await_ready1(qcam, 0)) {
 485                        v4l2_err(v4l2_dev, "no ack to port turnaround\n");
 486                        qc_setup(qcam);
 487                        return len;
 488                }
 489        } else {
 490                int l;
 491
 492                do {
 493                        l = qcam_read_bytes(qcam, tmpbuf, 1);
 494                        cond_resched();
 495                } while (l && tmpbuf[0] == 0x7e);
 496                l = qcam_read_bytes(qcam, tmpbuf + 1, 2);
 497                if (force_rgb) {
 498                        if (tmpbuf[0] != 0xe || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xf)
 499                                v4l2_err(v4l2_dev, "bad EOF\n");
 500                } else {
 501                        if (tmpbuf[0] != 0xf || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xe)
 502                                v4l2_err(v4l2_dev, "bad EOF\n");
 503                }
 504        }
 505
 506        qcam_write_data(qcam, 0);
 507        return len;
 508}
 509
 510/*
 511 *      Video4linux interfacing
 512 */
 513
 514static int qcam_querycap(struct file *file, void  *priv,
 515                                        struct v4l2_capability *vcap)
 516{
 517        struct qcam *qcam = video_drvdata(file);
 518
 519        strlcpy(vcap->driver, qcam->v4l2_dev.name, sizeof(vcap->driver));
 520        strlcpy(vcap->card, "Color Quickcam", sizeof(vcap->card));
 521        strlcpy(vcap->bus_info, "parport", sizeof(vcap->bus_info));
 522        vcap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE;
 523        vcap->capabilities = vcap->device_caps | V4L2_CAP_DEVICE_CAPS;
 524        return 0;
 525}
 526
 527static int qcam_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
 528{
 529        if (vin->index > 0)
 530                return -EINVAL;
 531        strlcpy(vin->name, "Camera", sizeof(vin->name));
 532        vin->type = V4L2_INPUT_TYPE_CAMERA;
 533        vin->audioset = 0;
 534        vin->tuner = 0;
 535        vin->std = 0;
 536        vin->status = 0;
 537        return 0;
 538}
 539
 540static int qcam_g_input(struct file *file, void *fh, unsigned int *inp)
 541{
 542        *inp = 0;
 543        return 0;
 544}
 545
 546static int qcam_s_input(struct file *file, void *fh, unsigned int inp)
 547{
 548        return (inp > 0) ? -EINVAL : 0;
 549}
 550
 551static int qcam_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
 552{
 553        struct qcam *qcam = video_drvdata(file);
 554        struct v4l2_pix_format *pix = &fmt->fmt.pix;
 555
 556        pix->width = qcam->width;
 557        pix->height = qcam->height;
 558        pix->pixelformat = V4L2_PIX_FMT_RGB24;
 559        pix->field = V4L2_FIELD_NONE;
 560        pix->bytesperline = 3 * qcam->width;
 561        pix->sizeimage = 3 * qcam->width * qcam->height;
 562        /* Just a guess */
 563        pix->colorspace = V4L2_COLORSPACE_SRGB;
 564        return 0;
 565}
 566
 567static int qcam_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
 568{
 569        struct v4l2_pix_format *pix = &fmt->fmt.pix;
 570
 571        if (pix->height < 60 || pix->width < 80) {
 572                pix->height = 60;
 573                pix->width = 80;
 574        } else if (pix->height < 120 || pix->width < 160) {
 575                pix->height = 120;
 576                pix->width = 160;
 577        } else {
 578                pix->height = 240;
 579                pix->width = 320;
 580        }
 581        pix->pixelformat = V4L2_PIX_FMT_RGB24;
 582        pix->field = V4L2_FIELD_NONE;
 583        pix->bytesperline = 3 * pix->width;
 584        pix->sizeimage = 3 * pix->width * pix->height;
 585        /* Just a guess */
 586        pix->colorspace = V4L2_COLORSPACE_SRGB;
 587        return 0;
 588}
 589
 590static int qcam_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
 591{
 592        struct qcam *qcam = video_drvdata(file);
 593        struct v4l2_pix_format *pix = &fmt->fmt.pix;
 594        int ret = qcam_try_fmt_vid_cap(file, fh, fmt);
 595
 596        if (ret)
 597                return ret;
 598        switch (pix->height) {
 599        case 60:
 600                qcam->mode = QC_DECIMATION_4;
 601                break;
 602        case 120:
 603                qcam->mode = QC_DECIMATION_2;
 604                break;
 605        default:
 606                qcam->mode = QC_DECIMATION_1;
 607                break;
 608        }
 609
 610        mutex_lock(&qcam->lock);
 611        qcam->mode |= QC_MILLIONS;
 612        qcam->height = pix->height;
 613        qcam->width = pix->width;
 614        parport_claim_or_block(qcam->pdev);
 615        qc_setup(qcam);
 616        parport_release(qcam->pdev);
 617        mutex_unlock(&qcam->lock);
 618        return 0;
 619}
 620
 621static int qcam_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
 622{
 623        static struct v4l2_fmtdesc formats[] = {
 624                { 0, 0, 0,
 625                  "RGB 8:8:8", V4L2_PIX_FMT_RGB24,
 626                  { 0, 0, 0, 0 }
 627                },
 628        };
 629        enum v4l2_buf_type type = fmt->type;
 630
 631        if (fmt->index > 0)
 632                return -EINVAL;
 633
 634        *fmt = formats[fmt->index];
 635        fmt->type = type;
 636        return 0;
 637}
 638
 639static ssize_t qcam_read(struct file *file, char __user *buf,
 640                         size_t count, loff_t *ppos)
 641{
 642        struct qcam *qcam = video_drvdata(file);
 643        int len;
 644
 645        mutex_lock(&qcam->lock);
 646        parport_claim_or_block(qcam->pdev);
 647        /* Probably should have a semaphore against multiple users */
 648        len = qc_capture(qcam, buf, count);
 649        parport_release(qcam->pdev);
 650        mutex_unlock(&qcam->lock);
 651        return len;
 652}
 653
 654static int qcam_s_ctrl(struct v4l2_ctrl *ctrl)
 655{
 656        struct qcam *qcam =
 657                container_of(ctrl->handler, struct qcam, hdl);
 658        int ret = 0;
 659
 660        mutex_lock(&qcam->lock);
 661        switch (ctrl->id) {
 662        case V4L2_CID_BRIGHTNESS:
 663                qcam->brightness = ctrl->val;
 664                break;
 665        case V4L2_CID_CONTRAST:
 666                qcam->contrast = ctrl->val;
 667                break;
 668        case V4L2_CID_GAMMA:
 669                qcam->whitebal = ctrl->val;
 670                break;
 671        default:
 672                ret = -EINVAL;
 673                break;
 674        }
 675        if (ret == 0) {
 676                parport_claim_or_block(qcam->pdev);
 677                qc_setup(qcam);
 678                parport_release(qcam->pdev);
 679        }
 680        mutex_unlock(&qcam->lock);
 681        return ret;
 682}
 683
 684static const struct v4l2_file_operations qcam_fops = {
 685        .owner          = THIS_MODULE,
 686        .open           = v4l2_fh_open,
 687        .release        = v4l2_fh_release,
 688        .poll           = v4l2_ctrl_poll,
 689        .unlocked_ioctl = video_ioctl2,
 690        .read           = qcam_read,
 691};
 692
 693static const struct v4l2_ioctl_ops qcam_ioctl_ops = {
 694        .vidioc_querycap                    = qcam_querycap,
 695        .vidioc_g_input                     = qcam_g_input,
 696        .vidioc_s_input                     = qcam_s_input,
 697        .vidioc_enum_input                  = qcam_enum_input,
 698        .vidioc_enum_fmt_vid_cap            = qcam_enum_fmt_vid_cap,
 699        .vidioc_g_fmt_vid_cap               = qcam_g_fmt_vid_cap,
 700        .vidioc_s_fmt_vid_cap               = qcam_s_fmt_vid_cap,
 701        .vidioc_try_fmt_vid_cap             = qcam_try_fmt_vid_cap,
 702        .vidioc_log_status                  = v4l2_ctrl_log_status,
 703        .vidioc_subscribe_event             = v4l2_ctrl_subscribe_event,
 704        .vidioc_unsubscribe_event           = v4l2_event_unsubscribe,
 705};
 706
 707static const struct v4l2_ctrl_ops qcam_ctrl_ops = {
 708        .s_ctrl = qcam_s_ctrl,
 709};
 710
 711/* Initialize the QuickCam driver control structure. */
 712
 713static struct qcam *qcam_init(struct parport *port)
 714{
 715        struct qcam *qcam;
 716        struct v4l2_device *v4l2_dev;
 717
 718        qcam = kzalloc(sizeof(*qcam), GFP_KERNEL);
 719        if (qcam == NULL)
 720                return NULL;
 721
 722        v4l2_dev = &qcam->v4l2_dev;
 723        strlcpy(v4l2_dev->name, "c-qcam", sizeof(v4l2_dev->name));
 724
 725        if (v4l2_device_register(NULL, v4l2_dev) < 0) {
 726                v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
 727                kfree(qcam);
 728                return NULL;
 729        }
 730
 731        v4l2_ctrl_handler_init(&qcam->hdl, 3);
 732        v4l2_ctrl_new_std(&qcam->hdl, &qcam_ctrl_ops,
 733                          V4L2_CID_BRIGHTNESS, 0, 255, 1, 240);
 734        v4l2_ctrl_new_std(&qcam->hdl, &qcam_ctrl_ops,
 735                          V4L2_CID_CONTRAST, 0, 255, 1, 192);
 736        v4l2_ctrl_new_std(&qcam->hdl, &qcam_ctrl_ops,
 737                          V4L2_CID_GAMMA, 0, 255, 1, 128);
 738        if (qcam->hdl.error) {
 739                v4l2_err(v4l2_dev, "couldn't register controls\n");
 740                v4l2_ctrl_handler_free(&qcam->hdl);
 741                kfree(qcam);
 742                return NULL;
 743        }
 744
 745        qcam->pport = port;
 746        qcam->pdev = parport_register_device(port, "c-qcam", NULL, NULL,
 747                                          NULL, 0, NULL);
 748
 749        qcam->bidirectional = (qcam->pport->modes & PARPORT_MODE_TRISTATE) ? 1 : 0;
 750
 751        if (qcam->pdev == NULL) {
 752                v4l2_err(v4l2_dev, "couldn't register for %s.\n", port->name);
 753                v4l2_ctrl_handler_free(&qcam->hdl);
 754                kfree(qcam);
 755                return NULL;
 756        }
 757
 758        strlcpy(qcam->vdev.name, "Colour QuickCam", sizeof(qcam->vdev.name));
 759        qcam->vdev.v4l2_dev = v4l2_dev;
 760        qcam->vdev.fops = &qcam_fops;
 761        qcam->vdev.ioctl_ops = &qcam_ioctl_ops;
 762        qcam->vdev.release = video_device_release_empty;
 763        qcam->vdev.ctrl_handler = &qcam->hdl;
 764        set_bit(V4L2_FL_USE_FH_PRIO, &qcam->vdev.flags);
 765        video_set_drvdata(&qcam->vdev, qcam);
 766
 767        mutex_init(&qcam->lock);
 768        qcam->width = qcam->ccd_width = 320;
 769        qcam->height = qcam->ccd_height = 240;
 770        qcam->mode = QC_MILLIONS | QC_DECIMATION_1;
 771        qcam->contrast = 192;
 772        qcam->brightness = 240;
 773        qcam->whitebal = 128;
 774        qcam->top = 1;
 775        qcam->left = 14;
 776        return qcam;
 777}
 778
 779static int init_cqcam(struct parport *port)
 780{
 781        struct qcam *qcam;
 782        struct v4l2_device *v4l2_dev;
 783
 784        if (parport[0] != -1) {
 785                /* The user gave specific instructions */
 786                int i, found = 0;
 787
 788                for (i = 0; i < MAX_CAMS && parport[i] != -1; i++) {
 789                        if (parport[0] == port->number)
 790                                found = 1;
 791                }
 792                if (!found)
 793                        return -ENODEV;
 794        }
 795
 796        if (num_cams == MAX_CAMS)
 797                return -ENOSPC;
 798
 799        qcam = qcam_init(port);
 800        if (qcam == NULL)
 801                return -ENODEV;
 802
 803        v4l2_dev = &qcam->v4l2_dev;
 804
 805        parport_claim_or_block(qcam->pdev);
 806
 807        qc_reset(qcam);
 808
 809        if (probe && qc_detect(qcam) == 0) {
 810                parport_release(qcam->pdev);
 811                parport_unregister_device(qcam->pdev);
 812                kfree(qcam);
 813                return -ENODEV;
 814        }
 815
 816        qc_setup(qcam);
 817
 818        parport_release(qcam->pdev);
 819
 820        if (video_register_device(&qcam->vdev, VFL_TYPE_GRABBER, video_nr) < 0) {
 821                v4l2_err(v4l2_dev, "Unable to register Colour QuickCam on %s\n",
 822                       qcam->pport->name);
 823                parport_unregister_device(qcam->pdev);
 824                kfree(qcam);
 825                return -ENODEV;
 826        }
 827
 828        v4l2_info(v4l2_dev, "%s: Colour QuickCam found on %s\n",
 829               video_device_node_name(&qcam->vdev), qcam->pport->name);
 830
 831        qcams[num_cams++] = qcam;
 832
 833        return 0;
 834}
 835
 836static void close_cqcam(struct qcam *qcam)
 837{
 838        video_unregister_device(&qcam->vdev);
 839        v4l2_ctrl_handler_free(&qcam->hdl);
 840        parport_unregister_device(qcam->pdev);
 841        kfree(qcam);
 842}
 843
 844static void cq_attach(struct parport *port)
 845{
 846        init_cqcam(port);
 847}
 848
 849static void cq_detach(struct parport *port)
 850{
 851        /* Write this some day. */
 852}
 853
 854static struct parport_driver cqcam_driver = {
 855        .name = "cqcam",
 856        .attach = cq_attach,
 857        .detach = cq_detach,
 858};
 859
 860static int __init cqcam_init(void)
 861{
 862        printk(KERN_INFO BANNER "\n");
 863
 864        return parport_register_driver(&cqcam_driver);
 865}
 866
 867static void __exit cqcam_cleanup(void)
 868{
 869        unsigned int i;
 870
 871        for (i = 0; i < num_cams; i++)
 872                close_cqcam(qcams[i]);
 873
 874        parport_unregister_driver(&cqcam_driver);
 875}
 876
 877MODULE_AUTHOR("Philip Blundell <philb@gnu.org>");
 878MODULE_DESCRIPTION(BANNER);
 879MODULE_LICENSE("GPL");
 880MODULE_VERSION("0.0.4");
 881
 882module_init(cqcam_init);
 883module_exit(cqcam_cleanup);
 884