X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fmedia%2Fvideo%2Fbw-qcam.c;h=7d0b6e59c6e2449b3030a70a4584499039a1cd66;hb=97bf2856c6014879bd04983a3e9dfcdac1e7fe85;hp=31412e8d32dbc8f3dae696eeeb9010dc1358f9fc;hpb=9bf4aaab3e101692164d49b7ca357651eb691cb6;p=linux-2.6.git diff --git a/drivers/media/video/bw-qcam.c b/drivers/media/video/bw-qcam.c index 31412e8d3..7d0b6e59c 100644 --- a/drivers/media/video/bw-qcam.c +++ b/drivers/media/video/bw-qcam.c @@ -73,7 +73,8 @@ OTHER DEALINGS IN THE SOFTWARE. #include #include #include -#include +#include +#include #include #include "bw-qcam.h" @@ -82,20 +83,15 @@ static unsigned int maxpoll=250; /* Maximum busy-loop count for qcam I/O */ static unsigned int yieldlines=4; /* Yield after this many during capture */ static int video_nr = -1; -MODULE_PARM(maxpoll,"i"); -MODULE_PARM(yieldlines,"i"); -MODULE_PARM(video_nr,"i"); +module_param(maxpoll, int, 0); +module_param(yieldlines, int, 0); +module_param(video_nr, int, 0); static inline int read_lpstatus(struct qcam_device *q) { return parport_read_status(q->pport); } -static inline int read_lpcontrol(struct qcam_device *q) -{ - return parport_read_control(q->pport); -} - static inline int read_lpdata(struct qcam_device *q) { return parport_read_data(q->pport); @@ -155,7 +151,7 @@ static int qc_calibrate(struct qcam_device *q) static struct qcam_device *qcam_init(struct parport *port) { struct qcam_device *q; - + q = kmalloc(sizeof(struct qcam_device), GFP_KERNEL); if(q==NULL) return NULL; @@ -163,17 +159,17 @@ static struct qcam_device *qcam_init(struct parport *port) q->pport = port; q->pdev = parport_register_device(port, "bw-qcam", NULL, NULL, NULL, 0, NULL); - if (q->pdev == NULL) + if (q->pdev == NULL) { printk(KERN_ERR "bw-qcam: couldn't register for %s.\n", port->name); kfree(q); return NULL; } - + memcpy(&q->vdev, &qcam_template, sizeof(qcam_template)); - - init_MUTEX(&q->lock); + + mutex_init(&q->lock); q->port_mode = (QC_ANY | QC_NOTSET); q->width = 320; @@ -241,16 +237,15 @@ static int qc_waithand(struct qcam_device *q, int val) while (!((status = read_lpstatus(q)) & 8)) { /* 1000 is enough spins on the I/O for all normal - cases, at that point we start to poll slowly + cases, at that point we start to poll slowly until the camera wakes up. However, we are busy blocked until the camera responds, so setting it lower is much better for interactive response. */ - + if(runs++>maxpoll) { - current->state=TASK_INTERRUPTIBLE; - schedule_timeout(HZ/200); + msleep_interruptible(5); } if(runs>(maxpoll+1000)) /* 5 seconds */ return -1; @@ -261,16 +256,15 @@ static int qc_waithand(struct qcam_device *q, int val) while (((status = read_lpstatus(q)) & 8)) { /* 1000 is enough spins on the I/O for all normal - cases, at that point we start to poll slowly + cases, at that point we start to poll slowly until the camera wakes up. However, we are busy blocked until the camera responds, so setting it lower is much better for interactive response. */ - + if(runs++>maxpoll) { - current->state=TASK_INTERRUPTIBLE; - schedule_timeout(HZ/200); + msleep_interruptible(5); } if(runs++>(maxpoll+1000)) /* 5 seconds */ return -1; @@ -289,21 +283,20 @@ static unsigned int qc_waithand2(struct qcam_device *q, int val) { unsigned int status; int runs=0; - - do + + do { status = read_lpdata(q); /* 1000 is enough spins on the I/O for all normal - cases, at that point we start to poll slowly + cases, at that point we start to poll slowly until the camera wakes up. However, we are busy blocked until the camera responds, so setting it lower is much better for interactive response. */ - + if(runs++>maxpoll) { - current->state=TASK_INTERRUPTIBLE; - schedule_timeout(HZ/200); + msleep_interruptible(5); } if(runs++>(maxpoll+1000)) /* 5 seconds */ return 0; @@ -329,7 +322,7 @@ static int qc_detect(struct qcam_device *q) lastreg = reg = read_lpstatus(q) & 0xf0; - for (i = 0; i < 500; i++) + for (i = 0; i < 500; i++) { reg = read_lpstatus(q) & 0xf0; if (reg != lastreg) @@ -365,7 +358,7 @@ static int qc_detect(struct qcam_device *q) static void qc_reset(struct qcam_device *q) { - switch (q->port_mode & QC_FORCE_MASK) + switch (q->port_mode & QC_FORCE_MASK) { case QC_FORCE_UNIDIR: q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_UNIDIR; @@ -378,7 +371,7 @@ static void qc_reset(struct qcam_device *q) case QC_ANY: write_lpcontrol(q, 0x20); write_lpdata(q, 0x75); - + if (read_lpdata(q) != 0x75) { q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_BIDIR; } else { @@ -406,8 +399,8 @@ static void qc_reset(struct qcam_device *q) static int qc_setscanmode(struct qcam_device *q) { int old_mode = q->mode; - - switch (q->transfer_scale) + + switch (q->transfer_scale) { case 1: q->mode = 0; @@ -420,7 +413,7 @@ static int qc_setscanmode(struct qcam_device *q) break; } - switch (q->bpp) + switch (q->bpp) { case 4: break; @@ -429,7 +422,7 @@ static int qc_setscanmode(struct qcam_device *q) break; } - switch (q->port_mode & QC_MODE_MASK) + switch (q->port_mode & QC_MODE_MASK) { case QC_BIDIR: q->mode += 1; @@ -438,10 +431,10 @@ static int qc_setscanmode(struct qcam_device *q) case QC_UNIDIR: break; } - + if (q->mode != old_mode) q->status |= QC_PARAM_CHANGE; - + return 0; } @@ -449,7 +442,7 @@ static int qc_setscanmode(struct qcam_device *q) /* Reset the QuickCam and program for brightness, contrast, * white-balance, and resolution. */ -void qc_set(struct qcam_device *q) +static void qc_set(struct qcam_device *q) { int val; int val2; @@ -459,7 +452,7 @@ void qc_set(struct qcam_device *q) /* Set the brightness. Yes, this is repetitive, but it works. * Shorter versions seem to fail subtly. Feel free to try :-). */ /* I think the problem was in qc_command, not here -- bls */ - + qc_command(q, 0xb); qc_command(q, q->brightness); @@ -510,13 +503,13 @@ static inline int qc_readbytes(struct qcam_device *q, char buffer[]) unsigned int hi2, lo2; static int state = 0; - if (buffer == NULL) + if (buffer == NULL) { state = 0; return 0; } - - switch (q->port_mode & QC_MODE_MASK) + + switch (q->port_mode & QC_MODE_MASK) { case QC_BIDIR: /* Bi-directional Port */ write_lpcontrol(q, 0x26); @@ -525,7 +518,7 @@ static inline int qc_readbytes(struct qcam_device *q, char buffer[]) write_lpcontrol(q, 0x2e); lo2 = (qc_waithand2(q, 0) >> 1); hi2 = (read_lpstatus(q) >> 3) & 0x1f; - switch (q->bpp) + switch (q->bpp) { case 4: buffer[0] = lo & 0xf; @@ -552,7 +545,7 @@ static inline int qc_readbytes(struct qcam_device *q, char buffer[]) write_lpcontrol(q, 0xe); hi = (qc_waithand(q, 0) & 0xf0) >> 4; - switch (q->bpp) + switch (q->bpp) { case 4: buffer[0] = lo; @@ -560,7 +553,7 @@ static inline int qc_readbytes(struct qcam_device *q, char buffer[]) ret = 2; break; case 6: - switch (state) + switch (state) { case 0: buffer[0] = (lo << 2) | ((hi & 0xc) >> 2); @@ -599,7 +592,7 @@ static inline int qc_readbytes(struct qcam_device *q, char buffer[]) * n=2^(bit depth)-1. Ask me for more details if you don't understand * this. */ -long qc_capture(struct qcam_device * q, char __user *buf, unsigned long len) +static long qc_capture(struct qcam_device * q, char __user *buf, unsigned long len) { int i, j, k, yield; int bytes; @@ -612,13 +605,13 @@ long qc_capture(struct qcam_device * q, char __user *buf, unsigned long len) int shift=8-q->bpp; char invert; - if (q->mode == -1) + if (q->mode == -1) return -ENXIO; qc_command(q, 0x7); qc_command(q, q->mode); - if ((q->port_mode & QC_MODE_MASK) == QC_BIDIR) + if ((q->port_mode & QC_MODE_MASK) == QC_BIDIR) { write_lpcontrol(q, 0x2e); /* turn port around */ write_lpcontrol(q, 0x26); @@ -626,7 +619,7 @@ long qc_capture(struct qcam_device * q, char __user *buf, unsigned long len) write_lpcontrol(q, 0x2e); (void) qc_waithand(q, 0); } - + /* strange -- should be 15:63 below, but 4bpp is odd */ invert = (q->bpp == 4) ? 16 : 63; @@ -637,15 +630,15 @@ long qc_capture(struct qcam_device * q, char __user *buf, unsigned long len) q->transfer_scale; transperline = (transperline + divisor - 1) / divisor; - for (i = 0, yield = yieldlines; i < linestotrans; i++) + for (i = 0, yield = yieldlines; i < linestotrans; i++) { - for (pixels_read = j = 0; j < transperline; j++) + for (pixels_read = j = 0; j < transperline; j++) { bytes = qc_readbytes(q, buffer); - for (k = 0; k < bytes && (pixels_read + k) < pixels_per_line; k++) + for (k = 0; k < bytes && (pixels_read + k) < pixels_per_line; k++) { int o; - if (buffer[k] == 0 && invert == 16) + if (buffer[k] == 0 && invert == 16) { /* 4bpp is odd (again) -- inverter is 16, not 15, but output must be 0-15 -- bls */ @@ -661,7 +654,7 @@ long qc_capture(struct qcam_device * q, char __user *buf, unsigned long len) pixels_read += bytes; } (void) qc_readbytes(q, NULL); /* reset state machine */ - + /* Grabbing an entire frame from the quickcam is a lengthy process. We don't (usually) want to busy-block the processor for the entire frame. yieldlines is a module @@ -669,13 +662,12 @@ long qc_capture(struct qcam_device * q, char __user *buf, unsigned long len) time will be 240 / 200 = 1.2 seconds. The compile-time default is to yield every 4 lines. */ if (i >= yield) { - current->state=TASK_INTERRUPTIBLE; - schedule_timeout(HZ/200); + msleep_interruptible(5); yield = i + yieldlines; } } - if ((q->port_mode & QC_MODE_MASK) == QC_BIDIR) + if ((q->port_mode & QC_MODE_MASK) == QC_BIDIR) { write_lpcontrol(q, 2); write_lpcontrol(q, 6); @@ -696,7 +688,7 @@ static int qcam_do_ioctl(struct inode *inode, struct file *file, { struct video_device *dev = video_devdata(file); struct qcam_device *qcam=(struct qcam_device *)dev; - + switch(cmd) { case VIDIOCGCAP: @@ -768,10 +760,10 @@ static int qcam_do_ioctl(struct inode *inode, struct file *file, { struct video_picture *p = arg; if(p->palette!=VIDEO_PALETTE_GREY) - return -EINVAL; + return -EINVAL; if(p->depth!=4 && p->depth!=6) return -EINVAL; - + /* * Now load the camera. */ @@ -781,9 +773,9 @@ static int qcam_do_ioctl(struct inode *inode, struct file *file, qcam->whitebal = p->whiteness>>8; qcam->bpp = p->depth; - down(&qcam->lock); + mutex_lock(&qcam->lock); qc_setscanmode(qcam); - up(&qcam->lock); + mutex_unlock(&qcam->lock); qcam->status |= QC_PARAM_CHANGE; return 0; @@ -799,11 +791,11 @@ static int qcam_do_ioctl(struct inode *inode, struct file *file, return -EINVAL; if(vw->width<80||vw->width>320) return -EINVAL; - + qcam->width = 320; qcam->height = 240; qcam->transfer_scale = 4; - + if(vw->width>=160 && vw->height>=120) { qcam->transfer_scale = 2; @@ -814,14 +806,14 @@ static int qcam_do_ioctl(struct inode *inode, struct file *file, qcam->height = 240; qcam->transfer_scale = 1; } - down(&qcam->lock); + mutex_lock(&qcam->lock); qc_setscanmode(qcam); - up(&qcam->lock); - + mutex_unlock(&qcam->lock); + /* We must update the camera before we grab. We could just have changed the grab size */ qcam->status |= QC_PARAM_CHANGE; - + /* Ok we figured out what to use from our wide choice */ return 0; } @@ -862,9 +854,9 @@ static ssize_t qcam_read(struct file *file, char __user *buf, struct qcam_device *qcam=(struct qcam_device *)v; int len; parport_claim_or_block(qcam->pdev); - - down(&qcam->lock); - + + mutex_lock(&qcam->lock); + qc_reset(qcam); /* Update the camera parameters if we need to */ @@ -872,18 +864,19 @@ static ssize_t qcam_read(struct file *file, char __user *buf, qc_set(qcam); len=qc_capture(qcam, buf,count); - - up(&qcam->lock); - + + mutex_unlock(&qcam->lock); + parport_release(qcam->pdev); return len; } - + static struct file_operations qcam_fops = { .owner = THIS_MODULE, .open = video_exclusive_open, .release = video_exclusive_release, .ioctl = qcam_ioctl, + .compat_ioctl = v4l_compat_ioctl32, .read = qcam_read, .llseek = no_llseek, }; @@ -900,7 +893,7 @@ static struct video_device qcam_template= static struct qcam_device *qcams[MAX_CAMS]; static unsigned int num_cams = 0; -int init_bwqcam(struct parport *port) +static int init_bwqcam(struct parport *port) { struct qcam_device *qcam; @@ -913,11 +906,11 @@ int init_bwqcam(struct parport *port) 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); @@ -928,9 +921,9 @@ int init_bwqcam(struct parport *port) qc_calibrate(qcam); parport_release(qcam->pdev); - + printk(KERN_INFO "Connectix Quickcam on %s\n", qcam->pport->name); - + if(video_register_device(&qcam->vdev, VFL_TYPE_GRABBER, video_nr)==-1) { parport_unregister_device(qcam->pdev); @@ -943,7 +936,7 @@ int init_bwqcam(struct parport *port) return 0; } -void close_bwqcam(struct qcam_device *qcam) +static void close_bwqcam(struct qcam_device *qcam) { video_unregister_device(&qcam->vdev); parport_unregister_device(qcam->pdev); @@ -955,7 +948,7 @@ void close_bwqcam(struct qcam_device *qcam) * -- March 14, 1999 Billy Donahue */ #ifdef MODULE static char *parport[MAX_CAMS] = { NULL, }; -MODULE_PARM(parport, "1-" __MODULE_STRING(MAX_CAMS) "s"); +module_param_array(parport, charp, NULL, 0); #endif static int accept_bwqcam(struct parport *port) @@ -1021,7 +1014,7 @@ static int __init init_bw_qcams(void) printk("Connectix Quickcam max-poll was above 5000. Using 5000.\n"); maxpoll = 5000; } - + if (yieldlines < 1) { printk("Connectix Quickcam yieldlines was less than 1. Using 1.\n"); yieldlines = 1;