patch-2.1.79 linux/drivers/char/bw-qcam.c
Next file: linux/drivers/char/bw-qcam.h
Previous file: linux/drivers/char/bttv.c
Back to the patch index
Back to the overall index
- Lines: 248
- Date:
Mon Jan 12 14:46:16 1998
- Orig file:
v2.1.78/linux/drivers/char/bw-qcam.c
- Orig date:
Tue Jan 6 09:37:33 1998
diff -u --recursive --new-file v2.1.78/linux/drivers/char/bw-qcam.c linux/drivers/char/bw-qcam.c
@@ -1,7 +1,10 @@
/*
* QuickCam Driver For Video4Linux.
*
+ * This version only works as a module.
+ *
* Video4Linux conversion work by Alan Cox.
+ * Parport compatibility by Phil Blundell.
*/
/* qcam-lib.c -- Library for programming with the Connectix QuickCam.
@@ -44,41 +47,41 @@
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/fs.h>
+#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/malloc.h>
#include <linux/mm.h>
-#include <linux/ioport.h>
-#include <asm/io.h>
+#include <linux/parport.h>
#include <linux/sched.h>
-#include <linux/videodev.h>
#include <linux/version.h>
+#include <linux/videodev.h>
#include <asm/uaccess.h>
#include "bw-qcam.h"
extern __inline__ int read_lpstatus(struct qcam_device *q)
{
- return inb_p(q->port+1);
+ return parport_read_status(q->pport);
}
extern __inline__ int read_lpcontrol(struct qcam_device *q)
{
- return inb_p(q->port+2);
+ return parport_read_control(q->pport);
}
extern __inline__ int read_lpdata(struct qcam_device *q)
{
- return inb_p(q->port);
+ return parport_read_data(q->pport);
}
extern __inline__ void write_lpdata(struct qcam_device *q, int d)
{
- outb_p(d, q->port);
+ parport_write_data(q->pport, d);
}
-extern __inline__ void write_lpcontrol(struct qcam_device *q,int d)
+extern __inline__ void write_lpcontrol(struct qcam_device *q, int d)
{
- outb(d, q->port+2);
+ parport_write_control(q->pport, d);
}
static int qc_waithand(struct qcam_device *q, int val);
@@ -122,21 +125,25 @@
/* Initialize the QuickCam driver control structure. This is where
* defaults are set for people who don't have a config file.*/
-static struct qcam_device *qcam_init(int port)
+static struct qcam_device *qcam_init(struct parport *port)
{
struct qcam_device *q;
- if(check_region(port,3))
- {
- printk(KERN_ERR "qcam: I/O port 0x%03X in use.\n", port);
+ q = kmalloc(sizeof(struct qcam_device), GFP_KERNEL);
+
+ q->pport = port;
+ q->pdev = parport_register_device(port, "bw-qcam", NULL, NULL,
+ NULL, 0, NULL);
+ if (q->pdev == NULL)
+ {
+ printk(KERN_ERR "bw-qcam: couldn't register for %s.\n",
+ port->name);
+ kfree(q);
return NULL;
}
- q = kmalloc(sizeof(struct qcam_device), GFP_KERNEL);
-
memcpy(&q->vdev, &qcam_template, sizeof(qcam_template));
- q->port = port; /* Port 0 == Autoprobe */
q->port_mode = (QC_ANY | QC_NOTSET);
q->width = 320;
q->height = 240;
@@ -295,7 +302,7 @@
/* Be liberal in what you accept... */
- if (count > 20 && count < 250)
+ if (count > 30 && count < 200)
return 1; /* found */
else
return 0; /* not found */
@@ -742,7 +749,9 @@
qcam->bpp = p.depth;
qc_setscanmode(qcam);
+ parport_claim_or_block(qcam->pdev);
qc_set(qcam);
+ parport_release(qcam->pdev);
return 0;
}
case VIDIOCSWIN:
@@ -816,9 +825,11 @@
{
struct qcam_device *qcam=(struct qcam_device *)v;
int len;
+ parport_claim_or_block(qcam->pdev);
/* Probably should have a semaphore against multiple users */
qc_reset(qcam);
len=qc_capture(qcam, buf,count);
+ parport_release(qcam->pdev);
return len;
}
@@ -840,72 +851,83 @@
0
};
+#define MAX_CAMS 4
+static struct qcam_device *qcams[MAX_CAMS];
+static unsigned int num_cams = 0;
-#ifdef MODULE
-
-int io=0x378;
-
-MODULE_PARM(io,"i");
+int init_bwqcam(struct parport *port)
+{
+ struct qcam_device *qcam;
-static struct qcam_device *qcam;
+ if (num_cams == MAX_CAMS)
+ {
+ printk(KERN_ERR "Too many Quickcams (max %d)\n", MAX_CAMS);
+ return -ENOSPC;
+ }
-int init_module(void)
-{
- qcam=qcam_init(io);
+ qcam=qcam_init(port);
if(qcam==NULL)
return -ENODEV;
+ parport_claim_or_block(qcam->pdev);
+
qc_reset(qcam);
if(qc_detect(qcam)==0)
{
+ parport_release(qcam->pdev);
+ parport_unregister_device(qcam->pdev);
kfree(qcam);
- printk(KERN_ERR "bw_qcam: No quickcam detected at 0x%03X\n", io);
return -ENODEV;
}
qc_calibrate(qcam);
+
+ parport_release(qcam->pdev);
- printk(KERN_INFO "Connectix Quickcam at 0x%03X\n", qcam->port);
+ printk(KERN_INFO "Connectix Quickcam on %s\n", qcam->pport->name);
if(video_register_device(&qcam->vdev)==-1)
+ {
+ parport_unregister_device(qcam->pdev);
+ kfree(qcam);
return -ENODEV;
+ }
+
+ qcams[num_cams++] = qcam;
+
return 0;
}
-void cleanup_module(void)
+void close_bwqcam(struct qcam_device *qcam)
{
video_unregister_device(&qcam->vdev);
+ parport_unregister_device(qcam->pdev);
kfree(qcam);
}
-#else
+#ifdef MODULE
+int init_module(void)
+{
+ struct parport *port;
+
+ for (port = parport_enumerate(); port; port=port->next)
+ init_bwqcam(port);
-void init_bw_qcams(void)
+ return (num_cams)?0:-ENODEV;
+}
+
+void cleanup_module(void)
{
- int io_ports[3]={0x278,0x378, 0x3BC};
- struct qcam_device *qcam;
- int i;
-
- for(i=0;i<3;i++)
- {
- qcam=qcam_init(io_ports[i]);
- if(qcam==NULL)
- continue;
-
- qc_reset(qcam);
-
- if(qc_detect(qcam)==0)
- {
- kfree(qcam);
- continue;
- }
- qc_calibrate(qcam);
-
- printk(KERN_INFO "Connectix Quickcam at 0x%03X\n", qcam->port);
-
- if(video_register_device(&qcam->vdev)==-1)
- return -ENODEV;
- }
+ unsigned int i;
+ for (i = 0; i < num_cams; i++)
+ close_bwqcam(qcams[i]);
}
+#else
+__initfunc(int init_bwqcams(struct video_init *unused))
+{
+ struct parport *port;
+ for (port = parport_enumerate(); port; port=port->next)
+ init_bwqcam(port);
+}
#endif
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov