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