Re: [PATCH] 2.2.14 driver/char/c-qcam.c

From: Philip Blundell (Philip.Blundell@pobox.com)
Date: Sun Feb 27 2000 - 07:33:49 EST


>This patch to the Connectix Color Quick-Cam driver allows modules to
>specify the port and autodetection methods. Use:

Here, for what it's worth, is my current 2.3 patch. I changed the detection
routines in a slightly different way.

The default is to look for cameras based on the IEEE-1284 probe data for all
ports. This requires you to have enabled CONFIG_PARPORT_IEEE1284 but it
should be more reliable than other probe methods. If this fails, you can
choose no probing ("probe=0") which assumes a camera is always present, or
aggressive probing ("probe=2") which resets the camera and then looks for its
heartbeat. (Older versions of the driver didn't reset the camera first, which
tended to make the probe go wrong.)

You can also specify a list of ports to scan with `parport=...'.

p.

Index: c-qcam.c
===================================================================
RCS file: /cvsroot/pub/kernel/armlinux/drivers/char/c-qcam.c,v
retrieving revision 1.8
diff -u -p -r1.8 c-qcam.c
--- c-qcam.c 2000/02/09 23:00:15 1.8
+++ c-qcam.c 2000/02/27 12:33:33
@@ -1,7 +1,20 @@
 /*
  * Video4Linux Colour QuickCam driver
- * Copyright 1997-1999 Philip Blundell <philb@gnu.org>
+ * Copyright 1997-2000 Philip Blundell <philb@gnu.org>
  *
+ * Module parameters:
+ *
+ * parport=auto -- probe all parports (default)
+ * parport=0 -- parport0 becomes qcam1
+ * parport=2,0,1 -- parports 2,0,1 are tried in that order
+ *
+ * probe=0 -- do no probing, assume camera is present
+ * probe=1 -- use IEEE-1284 autoprobe data only (default)
+ * probe=2 -- probe aggressively for cameras
+ *
+ * The parport parameter controls which parports will be scanned.
+ * Scanning all parports causes some printers to print a garbage page.
+ * -- March 14, 1999 Billy Donahue <billy@escape.com>
  */
 
 #include <linux/module.h>
@@ -32,6 +45,9 @@ struct qcam_device {
         struct semaphore lock;
 };
 
+/* cameras maximum */
+#define MAX_CAMS 4
+
 /* The three possible QuickCam modes */
 #define QC_MILLIONS 0x18
 #define QC_BILLIONS 0x10
@@ -42,6 +58,11 @@ struct qcam_device {
 #define QC_DECIMATION_2 2
 #define QC_DECIMATION_4 4
 
+#define BANNER "Colour QuickCam for Video4Linux v0.05"
+
+static int parport[MAX_CAMS] = { [1 ... MAX_CAMS-1] = -1 };
+static int probe = 2;
+
 static inline void qcam_set_ack(struct qcam_device *qcam, unsigned int i)
 {
         /* note: the QC specs refer to the PCAck pin by voltage, not
@@ -161,13 +182,19 @@ static int qc_detect(struct qcam_device
 
         /* The probe routine below is not very reliable. The IEEE-1284
            probe takes precedence. */
+ /* XXX Currently parport provides no way to distinguish between
+ "the IEEE probe was not done" and "the probe was done, but
+ no device was found". Fix this one day. */
         if (qcam->pport->probe_info[0].class == PARPORT_CLASS_MEDIA
             && qcam->pport->probe_info[0].model
             && !strcmp(qcam->pdev->port->probe_info[0].model,
                        "Color QuickCam 2.0")) {
- printk(KERN_DEBUG "Quickcam: Found by IEEE1284 probe.\n");
+ printk(KERN_DEBUG "QuickCam: Found by IEEE1284 probe.\n");
                 return 1;
         }
+
+ if (probe < 2)
+ return 0;
 
         parport_write_control(qcam->pport, 0xc);
 
@@ -184,6 +211,26 @@ static int qc_detect(struct qcam_device
                 }
         }
 
+ /* Reset the camera and try again */
+ parport_write_control(qcam->pport, 0xc);
+ parport_write_control(qcam->pport, 0x8);
+ mdelay(1);
+ parport_write_control(qcam->pport, 0xc);
+ mdelay(1);
+ count = 0;
+
+ ostat = stat = parport_read_status(qcam->pport);
+ for (i=0; i<250; i++)
+ {
+ mdelay(1);
+ stat = parport_read_status(qcam->pport);
+ if (ostat != stat)
+ {
+ if (++count >= 3) return 1;
+ ostat = stat;
+ }
+ }
+
         /* no (or flatline) camera, give up */
         return 0;
 }
@@ -637,7 +684,7 @@ static long qcam_read(struct video_devic
 /* video device template */
 static struct video_device qcam_template=
 {
- "Colour Quickcam",
+ "Colour QuickCam",
         VID_TYPE_CAPTURE,
         VID_HARDWARE_QCAM_C,
         qcam_open,
@@ -691,7 +738,6 @@ static struct qcam_device *qcam_init(str
         return q;
 }
 
-#define MAX_CAMS 4
 static struct qcam_device *qcams[MAX_CAMS];
 static unsigned int num_cams = 0;
 
@@ -699,6 +745,19 @@ int init_cqcam(struct parport *port)
 {
         struct qcam_device *qcam;
 
+ if (parport[0] != -1)
+ {
+ /* The user gave specific instructions */
+ int i, found = 0;
+ for (i = 0; i < MAX_CAMS && parport[i] != -1; i++)
+ {
+ if (parport[0] == port->number)
+ found = 1;
+ }
+ if (!found)
+ return -ENODEV;
+ }
+
         if (num_cams == MAX_CAMS)
                 return -ENOSPC;
 
@@ -710,7 +769,7 @@ int init_cqcam(struct parport *port)
 
         qc_reset(qcam);
         
- if (qc_detect(qcam)==0)
+ if (probe && qc_detect(qcam)==0)
         {
                 parport_release(qcam->pdev);
                 parport_unregister_device(qcam->pdev);
@@ -722,16 +781,18 @@ int init_cqcam(struct parport *port)
 
         parport_release(qcam->pdev);
         
- printk(KERN_INFO "Colour Quickcam found on %s\n",
- qcam->pport->name);
-
         if (video_register_device(&qcam->vdev, VFL_TYPE_GRABBER)==-1)
         {
+ printk(KERN_ERR "Unable to register Colour QuickCam on %s\n",
+ qcam->pport->name);
                 parport_unregister_device(qcam->pdev);
                 kfree(qcam);
                 return -ENODEV;
         }
 
+ printk(KERN_INFO "video%d: Colour QuickCam found on %s\n",
+ qcam->vdev.minor, qcam->pport->name);
+
         qcams[num_cams++] = qcam;
 
         return 0;
@@ -744,8 +805,6 @@ void close_cqcam(struct qcam_device *qca
         kfree(qcam);
 }
 
-#define BANNER "Connectix Colour Quickcam driver v0.04"
-
 static void cq_attach(struct parport *port)
 {
         init_cqcam(port);
@@ -766,11 +825,16 @@ static struct parport_driver cqcam_drive
 static int __init cqcam_init (void)
 {
         printk(BANNER "\n");
+
         return parport_register_driver(&cqcam_driver);
 }
 
 MODULE_AUTHOR("Philip Blundell <philb@gnu.org>");
 MODULE_DESCRIPTION(BANNER);
+MODULE_PARM_DESC(parport ,"parport=<auto|n[,n]...> for port detection method \n\
+probe=<0|1|2> # for camera detection method");
+MODULE_PARM(parport, "1-" __MODULE_STRING(MAX_CAMS) "i");
+MODULE_PARM(probe, "i");
 
 static void __exit cqcam_cleanup (void)
 {

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Tue Feb 29 2000 - 21:00:17 EST