Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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