Commit 70f7a7d6 authored by Alan Cox's avatar Alan Cox Committed by Linus Torvalds

[PATCH] update cpia to match 2.4

parent 16fa5fe8
...@@ -56,7 +56,7 @@ static int video_nr = -1; ...@@ -56,7 +56,7 @@ static int video_nr = -1;
#ifdef MODULE #ifdef MODULE
MODULE_PARM(video_nr,"i"); MODULE_PARM(video_nr,"i");
MODULE_AUTHOR("Scott J. Bertin <sbertin@mindspring.com> & Peter Pregler <Peter_Pregler@email.com> & Johannes Erdfelt <jerdfelt@valinux.com>"); MODULE_AUTHOR("Scott J. Bertin <sbertin@securenym.net> & Peter Pregler <Peter_Pregler@email.com> & Johannes Erdfelt <johannes@erdfeld.com>");
MODULE_DESCRIPTION("V4L-driver for Vision CPiA based cameras"); MODULE_DESCRIPTION("V4L-driver for Vision CPiA based cameras");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("video"); MODULE_SUPPORTED_DEVICE("video");
...@@ -163,7 +163,7 @@ enum { ...@@ -163,7 +163,7 @@ enum {
#define COMMAND_SETAPCOR 0x1000 #define COMMAND_SETAPCOR 0x1000
#define COMMAND_SETFLICKERCTRL 0x2000 #define COMMAND_SETFLICKERCTRL 0x2000
#define COMMAND_SETVLOFFSET 0x4000 #define COMMAND_SETVLOFFSET 0x4000
#define COMMAND_SETLIGHTS 0x8000
/* Developer's Guide Table 5 p 3-34 /* Developer's Guide Table 5 p 3-34
* indexed by [mains][sensorFps.baserate][sensorFps.divisor]*/ * indexed by [mains][sensorFps.baserate][sensorFps.divisor]*/
static u8 flicker_jumps[2][2][4] = static u8 flicker_jumps[2][2][4] =
...@@ -244,7 +244,7 @@ static int cpia_read_proc(char *page, char **start, off_t off, ...@@ -244,7 +244,7 @@ static int cpia_read_proc(char *page, char **start, off_t off,
char *out = page; char *out = page;
int len, tmp; int len, tmp;
struct cam_data *cam = data; struct cam_data *cam = data;
char tmpstr[20]; char tmpstr[29];
/* IMPORTANT: This output MUST be kept under PAGE_SIZE /* IMPORTANT: This output MUST be kept under PAGE_SIZE
* or we need to get more sophisticated. */ * or we need to get more sophisticated. */
...@@ -281,6 +281,13 @@ static int cpia_read_proc(char *page, char **start, off_t off, ...@@ -281,6 +281,13 @@ static int cpia_read_proc(char *page, char **start, off_t off,
cam->params.status.vpStatus); cam->params.status.vpStatus);
out += sprintf(out, "error_code: %#04x\n", out += sprintf(out, "error_code: %#04x\n",
cam->params.status.errorCode); cam->params.status.errorCode);
/* QX3 specific entries */
if (cam->params.qx3.qx3_detected) {
out += sprintf(out, "button: %4d\n",
cam->params.qx3.button);
out += sprintf(out, "cradled: %4d\n",
cam->params.qx3.cradled);
}
out += sprintf(out, "video_size: %s\n", out += sprintf(out, "video_size: %s\n",
cam->params.format.videoSize == VIDEOSIZE_CIF ? cam->params.format.videoSize == VIDEOSIZE_CIF ?
"CIF " : "QCIF"); "CIF " : "QCIF");
...@@ -345,16 +352,17 @@ static int cpia_read_proc(char *page, char **start, off_t off, ...@@ -345,16 +352,17 @@ static int cpia_read_proc(char *page, char **start, off_t off,
if (cam->params.version.firmwareVersion == 1 && if (cam->params.version.firmwareVersion == 1 &&
cam->params.version.firmwareRevision == 2) cam->params.version.firmwareRevision == 2)
/* 1-02 firmware limits gain to 2 */ /* 1-02 firmware limits gain to 2 */
sprintf(tmpstr, "%8d %8d", 1, 2); sprintf(tmpstr, "%8d %8d %8d", 1, 2, 2);
else else
sprintf(tmpstr, "1,2,4,8"); sprintf(tmpstr, "%8d %8d %8d", 1, 8, 2);
if (cam->params.exposure.gainMode == 0) if (cam->params.exposure.gainMode == 0)
out += sprintf(out, "max_gain: unknown %18s" out += sprintf(out, "max_gain: unknown %28s"
" %8d\n", tmpstr, 2); " powers of 2\n", tmpstr);
else else
out += sprintf(out, "max_gain: %8d %18s %8d\n", out += sprintf(out, "max_gain: %8d %28s"
1<<(cam->params.exposure.gainMode-1), tmpstr, 2); " 1,2,4 or 8 \n",
1<<(cam->params.exposure.gainMode-1), tmpstr);
switch(cam->params.exposure.expMode) { switch(cam->params.exposure.expMode) {
case 1: case 1:
...@@ -481,6 +489,15 @@ static int cpia_read_proc(char *page, char **start, off_t off, ...@@ -481,6 +489,15 @@ static int cpia_read_proc(char *page, char **start, off_t off,
out += sprintf(out, "decimation_thresh_mod: %8d %8d %8d %8d\n", out += sprintf(out, "decimation_thresh_mod: %8d %8d %8d %8d\n",
cam->params.compressionParams.decimationThreshMod, cam->params.compressionParams.decimationThreshMod,
0, 255, 2); 0, 255, 2);
/* QX3 specific entries */
if (cam->params.qx3.qx3_detected) {
out += sprintf(out, "toplight: %8s %8s %8s %8s\n",
cam->params.qx3.toplight ? "on" : "off",
"off", "on", "off");
out += sprintf(out, "bottomlight: %8s %8s %8s %8s\n",
cam->params.qx3.bottomlight ? "on" : "off",
"off", "on", "off");
}
len = out - page; len = out - page;
len -= off; len -= off;
...@@ -494,19 +511,46 @@ static int cpia_read_proc(char *page, char **start, off_t off, ...@@ -494,19 +511,46 @@ static int cpia_read_proc(char *page, char **start, off_t off,
return len; return len;
} }
static int cpia_write_proc(struct file *file, const char *buffer, static int cpia_write_proc(struct file *file, const char *buf,
unsigned long count, void *data) unsigned long count, void *data)
{ {
return -EINVAL;
#if 0
struct cam_data *cam = data; struct cam_data *cam = data;
struct cam_params new_params; struct cam_params new_params;
char *page, *buffer;
int retval, find_colon; int retval, find_colon;
int size = count; int size = count;
unsigned long val; unsigned long val = 0;
u32 command_flags = 0; u32 command_flags = 0;
u8 new_mains; u8 new_mains;
/*
* This code to copy from buf to page is shamelessly copied
* from the comx driver
*/
if (count > PAGE_SIZE) {
printk(KERN_ERR "count is %lu > %d!!!\n", count, (int)PAGE_SIZE);
return -ENOSPC;
}
if (!(page = (char *)__get_free_page(GFP_KERNEL))) return -ENOMEM;
if(copy_from_user(page, buf, count))
{
retval = -EFAULT;
goto out;
}
if (page[count-1] == '\n')
page[count-1] = '\0';
else if (count < PAGE_SIZE)
page[count] = '\0';
else if (page[count]) {
retval = -EINVAL;
goto out;
}
buffer = page;
if (down_interruptible(&cam->param_lock)) if (down_interruptible(&cam->param_lock))
return -ERESTARTSYS; return -ERESTARTSYS;
...@@ -1163,6 +1207,22 @@ static int cpia_write_proc(struct file *file, const char *buffer, ...@@ -1163,6 +1207,22 @@ static int cpia_write_proc(struct file *file, const char *buffer,
retval = -EINVAL; retval = -EINVAL;
} }
command_flags |= COMMAND_SETCOMPRESSIONPARAMS; command_flags |= COMMAND_SETCOMPRESSIONPARAMS;
} else if (MATCH("toplight")) {
if (!retval && MATCH("on"))
new_params.qx3.toplight = 1;
else if (!retval && MATCH("off"))
new_params.qx3.toplight = 0;
else
retval = -EINVAL;
command_flags |= COMMAND_SETLIGHTS;
} else if (MATCH("bottomlight")) {
if (!retval && MATCH("on"))
new_params.qx3.bottomlight = 1;
else if (!retval && MATCH("off"))
new_params.qx3.bottomlight = 0;
else
retval = -EINVAL;
command_flags |= COMMAND_SETLIGHTS;
} else { } else {
DBG("No match found\n"); DBG("No match found\n");
retval = -EINVAL; retval = -EINVAL;
...@@ -1174,7 +1234,10 @@ static int cpia_write_proc(struct file *file, const char *buffer, ...@@ -1174,7 +1234,10 @@ static int cpia_write_proc(struct file *file, const char *buffer,
++buffer; ++buffer;
} }
if (count) { if (count) {
if (*buffer != '\n' && *buffer != ';') if (*buffer == '\0' && count != 1)
retval = -EINVAL;
else if (*buffer != '\n' && *buffer != ';' &&
*buffer != '\0')
retval = -EINVAL; retval = -EINVAL;
else { else {
--count; --count;
...@@ -1208,8 +1271,9 @@ static int cpia_write_proc(struct file *file, const char *buffer, ...@@ -1208,8 +1271,9 @@ static int cpia_write_proc(struct file *file, const char *buffer,
up(&cam->param_lock); up(&cam->param_lock);
out:
free_page((unsigned long)page);
return retval; return retval;
#endif
} }
static void create_proc_cpia_cam(struct cam_data *cam) static void create_proc_cpia_cam(struct cam_data *cam)
...@@ -1229,7 +1293,12 @@ static void create_proc_cpia_cam(struct cam_data *cam) ...@@ -1229,7 +1293,12 @@ static void create_proc_cpia_cam(struct cam_data *cam)
ent->data = cam; ent->data = cam;
ent->read_proc = cpia_read_proc; ent->read_proc = cpia_read_proc;
ent->write_proc = cpia_write_proc; ent->write_proc = cpia_write_proc;
ent->size = 3626; /*
size of the proc entry is 3672 bytes for the standard webcam;
the extra features of the QX3 microscope add 188 bytes.
(we have not yet probed the camera to see which type it is).
*/
ent->size = 3672 + 188;
cam->proc_entry = ent; cam->proc_entry = ent;
} }
...@@ -1523,6 +1592,10 @@ static int do_command(struct cam_data *cam, u16 command, u8 a, u8 b, u8 c, u8 d) ...@@ -1523,6 +1592,10 @@ static int do_command(struct cam_data *cam, u16 command, u8 a, u8 b, u8 c, u8 d)
down(&cam->param_lock); down(&cam->param_lock);
datasize=8; datasize=8;
break; break;
case CPIA_COMMAND_ReadMCPorts:
case CPIA_COMMAND_ReadVCRegs:
datasize = 4;
break;
default: default:
datasize=0; datasize=0;
break; break;
...@@ -1620,6 +1693,22 @@ static int do_command(struct cam_data *cam, u16 command, u8 a, u8 b, u8 c, u8 d) ...@@ -1620,6 +1693,22 @@ static int do_command(struct cam_data *cam, u16 command, u8 a, u8 b, u8 c, u8 d)
} }
up(&cam->param_lock); up(&cam->param_lock);
break; break;
case CPIA_COMMAND_ReadMCPorts:
if (!cam->params.qx3.qx3_detected)
break;
/* test button press */
cam->params.qx3.button = ((data[1] & 0x02) == 0);
if (cam->params.qx3.button) {
/* button pressed - unlock the latch */
do_command(cam,CPIA_COMMAND_WriteMCPort,3,0xDF,0xDF,0);
do_command(cam,CPIA_COMMAND_WriteMCPort,3,0xFF,0xFF,0);
}
/* test whether microscope is cradled */
cam->params.qx3.cradled = ((data[2] & 0x40) == 0);
break;
default: default:
break; break;
} }
...@@ -1779,6 +1868,7 @@ static int skipcount(int count, int fmt) ...@@ -1779,6 +1868,7 @@ static int skipcount(int count, int fmt)
{ {
switch(fmt) { switch(fmt) {
case VIDEO_PALETTE_GREY: case VIDEO_PALETTE_GREY:
return count;
case VIDEO_PALETTE_RGB555: case VIDEO_PALETTE_RGB555:
case VIDEO_PALETTE_RGB565: case VIDEO_PALETTE_RGB565:
case VIDEO_PALETTE_YUV422: case VIDEO_PALETTE_YUV422:
...@@ -2059,6 +2149,13 @@ static void dispatch_commands(struct cam_data *cam) ...@@ -2059,6 +2149,13 @@ static void dispatch_commands(struct cam_data *cam)
if (cam->cmd_queue & COMMAND_RESUME) if (cam->cmd_queue & COMMAND_RESUME)
init_stream_cap(cam); init_stream_cap(cam);
if (cam->cmd_queue & COMMAND_SETLIGHTS && cam->params.qx3.qx3_detected) {
int p1 = (cam->params.qx3.bottomlight == 0) << 1;
int p2 = (cam->params.qx3.toplight == 0) << 3;
do_command(cam, CPIA_COMMAND_WriteVCReg, 0x90, 0x8F, 0x50, 0);
do_command(cam, CPIA_COMMAND_WriteMCPort, 2, 0, (p1|p2|0xE0), 0);
}
up(&cam->param_lock); up(&cam->param_lock);
cam->cmd_queue = COMMAND_NONE; cam->cmd_queue = COMMAND_NONE;
return; return;
...@@ -2133,9 +2230,10 @@ static void fetch_frame(void *data) ...@@ -2133,9 +2230,10 @@ static void fetch_frame(void *data)
/* camera idle now so dispatch queued commands */ /* camera idle now so dispatch queued commands */
dispatch_commands(cam); dispatch_commands(cam);
/* Update our knowledge of the camera state - FIXME: necessary? */ /* Update our knowledge of the camera state */
do_command(cam, CPIA_COMMAND_GetColourBalance, 0, 0, 0, 0); do_command(cam, CPIA_COMMAND_GetColourBalance, 0, 0, 0, 0);
do_command(cam, CPIA_COMMAND_GetExposure, 0, 0, 0, 0); do_command(cam, CPIA_COMMAND_GetExposure, 0, 0, 0, 0);
do_command(cam, CPIA_COMMAND_ReadMCPorts, 0, 0, 0, 0);
/* decompress and convert image to by copying it from /* decompress and convert image to by copying it from
* raw_image to decompressed_frame * raw_image to decompressed_frame
...@@ -2347,6 +2445,10 @@ static int reset_camera(struct cam_data *cam) ...@@ -2347,6 +2445,10 @@ static int reset_camera(struct cam_data *cam)
if (cam->params.version.firmwareVersion != 1) if (cam->params.version.firmwareVersion != 1)
return -ENODEV; return -ENODEV;
/* set QX3 detected flag */
cam->params.qx3.qx3_detected = (cam->params.pnpID.vendor == 0x0813 &&
cam->params.pnpID.product == 0x0001);
/* The fatal error checking should be done after /* The fatal error checking should be done after
* the camera powers up (developer's guide p 3-38) */ * the camera powers up (developer's guide p 3-38) */
...@@ -2481,7 +2583,7 @@ static int cpia_close(struct inode *inode, struct file *file) ...@@ -2481,7 +2583,7 @@ static int cpia_close(struct inode *inode, struct file *file)
/* GotoLoPower */ /* GotoLoPower */
goto_low_power(cam); goto_low_power(cam);
/* Update the camera ststus */ /* Update the camera status */
do_command(cam, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0); do_command(cam, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
/* cleanup internal state stuff */ /* cleanup internal state stuff */
...@@ -2520,7 +2622,7 @@ static int cpia_read(struct file *file, char *buf, ...@@ -2520,7 +2622,7 @@ static int cpia_read(struct file *file, char *buf,
struct video_device *dev = file->private_data; struct video_device *dev = file->private_data;
struct cam_data *cam = dev->priv; struct cam_data *cam = dev->priv;
/* make this _really_ smp and multithredi-safe */ /* make this _really_ smp and multithread-safe */
if (down_interruptible(&cam->busy_lock)) if (down_interruptible(&cam->busy_lock))
return -EINTR; return -EINTR;
...@@ -2728,7 +2830,6 @@ static int cpia_do_ioctl(struct inode *inode, struct file *file, ...@@ -2728,7 +2830,6 @@ static int cpia_do_ioctl(struct inode *inode, struct file *file,
cam->cmd_queue |= COMMAND_SETFORMAT; cam->cmd_queue |= COMMAND_SETFORMAT;
} }
// FIXME needed??? memcpy(&cam->vw, &vw, sizeof(vw));
up(&cam->param_lock); up(&cam->param_lock);
/* setformat ignored by camera during streaming, /* setformat ignored by camera during streaming,
...@@ -2762,10 +2863,8 @@ static int cpia_do_ioctl(struct inode *inode, struct file *file, ...@@ -2762,10 +2863,8 @@ static int cpia_do_ioctl(struct inode *inode, struct file *file,
struct video_mmap *vm = arg; struct video_mmap *vm = arg;
int video_size; int video_size;
#if 1
DBG("VIDIOCMCAPTURE: %d / %d / %dx%d\n", vm->format, vm->frame, DBG("VIDIOCMCAPTURE: %d / %d / %dx%d\n", vm->format, vm->frame,
vm->width, vm->height); vm->width, vm->height);
#endif
if (vm->frame<0||vm->frame>=FRAME_NUM) { if (vm->frame<0||vm->frame>=FRAME_NUM) {
retval = -EINVAL; retval = -EINVAL;
break; break;
...@@ -2775,6 +2874,8 @@ static int cpia_do_ioctl(struct inode *inode, struct file *file, ...@@ -2775,6 +2874,8 @@ static int cpia_do_ioctl(struct inode *inode, struct file *file,
cam->vp.palette = vm->format; cam->vp.palette = vm->format;
switch(vm->format) { switch(vm->format) {
case VIDEO_PALETTE_GREY: case VIDEO_PALETTE_GREY:
cam->vp.depth=8;
break;
case VIDEO_PALETTE_RGB555: case VIDEO_PALETTE_RGB555:
case VIDEO_PALETTE_RGB565: case VIDEO_PALETTE_RGB565:
case VIDEO_PALETTE_YUV422: case VIDEO_PALETTE_YUV422:
...@@ -2807,10 +2908,6 @@ static int cpia_do_ioctl(struct inode *inode, struct file *file, ...@@ -2807,10 +2908,6 @@ static int cpia_do_ioctl(struct inode *inode, struct file *file,
cam->cmd_queue |= COMMAND_SETFORMAT; cam->cmd_queue |= COMMAND_SETFORMAT;
dispatch_commands(cam); dispatch_commands(cam);
} }
#if 0
DBG("VIDIOCMCAPTURE: %d / %d/%d\n", cam->video_size,
cam->vw.width, cam->vw.height);
#endif
/* according to v4l-spec we must start streaming here */ /* according to v4l-spec we must start streaming here */
cam->mmap_kludge = 1; cam->mmap_kludge = 1;
retval = capture_frame(cam, vm); retval = capture_frame(cam, vm);
...@@ -2947,7 +3044,7 @@ static struct video_device cpia_template = { ...@@ -2947,7 +3044,7 @@ static struct video_device cpia_template = {
owner: THIS_MODULE, owner: THIS_MODULE,
name: "CPiA Camera", name: "CPiA Camera",
type: VID_TYPE_CAPTURE, type: VID_TYPE_CAPTURE,
hardware: VID_HARDWARE_CPIA, /* FIXME */ hardware: VID_HARDWARE_CPIA,
fops: &cpia_fops, fops: &cpia_fops,
}; };
...@@ -3006,8 +3103,8 @@ static void reset_camera_struct(struct cam_data *cam) ...@@ -3006,8 +3103,8 @@ static void reset_camera_struct(struct cam_data *cam)
cam->params.sensorFps.divisor = 1; cam->params.sensorFps.divisor = 1;
cam->params.sensorFps.baserate = 1; cam->params.sensorFps.baserate = 1;
cam->params.yuvThreshold.yThreshold = 15; /* FIXME? */ cam->params.yuvThreshold.yThreshold = 6; /* From windows driver */
cam->params.yuvThreshold.uvThreshold = 15; /* FIXME? */ cam->params.yuvThreshold.uvThreshold = 6; /* From windows driver */
cam->params.format.subSample = SUBSAMPLE_422; cam->params.format.subSample = SUBSAMPLE_422;
cam->params.format.yuvOrder = YUVORDER_YUYV; cam->params.format.yuvOrder = YUVORDER_YUYV;
...@@ -3015,8 +3112,14 @@ static void reset_camera_struct(struct cam_data *cam) ...@@ -3015,8 +3112,14 @@ static void reset_camera_struct(struct cam_data *cam)
cam->params.compression.mode = CPIA_COMPRESSION_AUTO; cam->params.compression.mode = CPIA_COMPRESSION_AUTO;
cam->params.compressionTarget.frTargeting = cam->params.compressionTarget.frTargeting =
CPIA_COMPRESSION_TARGET_QUALITY; CPIA_COMPRESSION_TARGET_QUALITY;
cam->params.compressionTarget.targetFR = 7; /* FIXME? */ cam->params.compressionTarget.targetFR = 15; /* From windows driver */
cam->params.compressionTarget.targetQ = 10; /* FIXME? */ cam->params.compressionTarget.targetQ = 5; /* From windows driver */
cam->params.qx3.qx3_detected = 0;
cam->params.qx3.toplight = 0;
cam->params.qx3.bottomlight = 0;
cam->params.qx3.button = 0;
cam->params.qx3.cradled = 0;
cam->video_size = VIDEOSIZE_CIF; cam->video_size = VIDEOSIZE_CIF;
...@@ -3025,8 +3128,8 @@ static void reset_camera_struct(struct cam_data *cam) ...@@ -3025,8 +3128,8 @@ static void reset_camera_struct(struct cam_data *cam)
cam->vp.brightness = 32768; /* 50% */ cam->vp.brightness = 32768; /* 50% */
cam->vp.contrast = 32768; /* 50% */ cam->vp.contrast = 32768; /* 50% */
cam->vp.whiteness = 0; /* not used -> grayscale only */ cam->vp.whiteness = 0; /* not used -> grayscale only */
cam->vp.depth = 0; /* FIXME: to be set by user? */ cam->vp.depth = 24; /* to be set by user */
cam->vp.palette = VIDEO_PALETTE_RGB24; /* FIXME: to be set by user? */ cam->vp.palette = VIDEO_PALETTE_RGB24; /* to be set by user */
cam->vw.x = 0; cam->vw.x = 0;
cam->vw.y = 0; cam->vw.y = 0;
...@@ -3080,14 +3183,9 @@ struct cam_data *cpia_register_camera(struct cpia_camera_ops *ops, void *lowleve ...@@ -3080,14 +3183,9 @@ struct cam_data *cpia_register_camera(struct cpia_camera_ops *ops, void *lowleve
{ {
struct cam_data *camera; struct cam_data *camera;
/* Need a lock when adding/removing cameras. This doesn't happen if ((camera = kmalloc(sizeof(struct cam_data), GFP_KERNEL)) == NULL)
* often and doesn't take very long, so grabbing the kernel lock
* should be OK. */
if ((camera = kmalloc(sizeof(struct cam_data), GFP_KERNEL)) == NULL) {
unlock_kernel();
return NULL; return NULL;
}
init_camera_struct( camera, ops ); init_camera_struct( camera, ops );
camera->lowlevel_data = lowlevel; camera->lowlevel_data = lowlevel;
...@@ -3095,7 +3193,6 @@ struct cam_data *cpia_register_camera(struct cpia_camera_ops *ops, void *lowleve ...@@ -3095,7 +3193,6 @@ struct cam_data *cpia_register_camera(struct cpia_camera_ops *ops, void *lowleve
/* register v4l device */ /* register v4l device */
if (video_register_device(&camera->vdev, VFL_TYPE_GRABBER, video_nr) == -1) { if (video_register_device(&camera->vdev, VFL_TYPE_GRABBER, video_nr) == -1) {
kfree(camera); kfree(camera);
unlock_kernel();
printk(KERN_DEBUG "video_register_device failed\n"); printk(KERN_DEBUG "video_register_device failed\n");
return NULL; return NULL;
} }
...@@ -3118,12 +3215,6 @@ struct cam_data *cpia_register_camera(struct cpia_camera_ops *ops, void *lowleve ...@@ -3118,12 +3215,6 @@ struct cam_data *cpia_register_camera(struct cpia_camera_ops *ops, void *lowleve
/* close cpia */ /* close cpia */
camera->ops->close(camera->lowlevel_data); camera->ops->close(camera->lowlevel_data);
/* Eh? Feeling happy? - jerdfelt */
/*
camera->ops->open(camera->lowlevel_data);
camera->ops->close(camera->lowlevel_data);
*/
printk(KERN_INFO " CPiA Version: %d.%02d (%d.%d)\n", printk(KERN_INFO " CPiA Version: %d.%02d (%d.%d)\n",
camera->params.version.firmwareVersion, camera->params.version.firmwareVersion,
camera->params.version.firmwareRevision, camera->params.version.firmwareRevision,
......
...@@ -27,12 +27,12 @@ ...@@ -27,12 +27,12 @@
*/ */
#define CPIA_MAJ_VER 0 #define CPIA_MAJ_VER 0
#define CPIA_MIN_VER 7 #define CPIA_MIN_VER 8
#define CPIA_PATCH_VER 4 #define CPIA_PATCH_VER 1
#define CPIA_PP_MAJ_VER 0 #define CPIA_PP_MAJ_VER 0
#define CPIA_PP_MIN_VER 7 #define CPIA_PP_MIN_VER 8
#define CPIA_PP_PATCH_VER 4 #define CPIA_PP_PATCH_VER 1
#define CPIA_MAX_FRAME_SIZE_UNALIGNED (352 * 288 * 4) /* CIF at RGB32 */ #define CPIA_MAX_FRAME_SIZE_UNALIGNED (352 * 288 * 4) /* CIF at RGB32 */
#define CPIA_MAX_FRAME_SIZE ((CPIA_MAX_FRAME_SIZE_UNALIGNED + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)) /* align above to PAGE_SIZE */ #define CPIA_MAX_FRAME_SIZE ((CPIA_MAX_FRAME_SIZE_UNALIGNED + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)) /* align above to PAGE_SIZE */
...@@ -204,6 +204,13 @@ struct cam_params { ...@@ -204,6 +204,13 @@ struct cam_params {
u8 subSample; u8 subSample;
u8 yuvOrder; u8 yuvOrder;
} format; } format;
struct { /* Intel QX3 specific data */
u8 qx3_detected; /* a QX3 is present */
u8 toplight; /* top light lit , R/W */
u8 bottomlight; /* bottom light lit, R/W */
u8 button; /* snapshot button pressed (R/O) */
u8 cradled; /* microscope is in cradle (R/O) */
} qx3;
struct { struct {
u8 colStart; /* skip first 8*colStart pixels */ u8 colStart; /* skip first 8*colStart pixels */
u8 colEnd; /* finish at 8*colEnd pixels */ u8 colEnd; /* finish at 8*colEnd pixels */
...@@ -393,29 +400,6 @@ void cpia_unregister_camera(struct cam_data *cam); ...@@ -393,29 +400,6 @@ void cpia_unregister_camera(struct cam_data *cam);
(p)&0x80?1:0, (p)&0x40?1:0, (p)&0x20?1:0, (p)&0x10?1:0,\ (p)&0x80?1:0, (p)&0x40?1:0, (p)&0x20?1:0, (p)&0x10?1:0,\
(p)&0x08?1:0, (p)&0x04?1:0, (p)&0x02?1:0, (p)&0x01?1:0); (p)&0x08?1:0, (p)&0x04?1:0, (p)&0x02?1:0, (p)&0x01?1:0);
#define ADD_TO_LIST(l, drv) \
{\
lock_kernel();\
(drv)->next = l;\
(drv)->previous = &(l);\
(l) = drv;\
unlock_kernel();\
} while(0)
#define REMOVE_FROM_LIST(drv) \
{\
if ((drv)->previous != NULL) {\
lock_kernel();\
if ((drv)->next != NULL)\
(drv)->next->previous = (drv)->previous;\
*((drv)->previous) = (drv)->next;\
(drv)->previous = NULL;\
(drv)->next = NULL;\
unlock_kernel();\
}\
} while (0)
static inline void cpia_add_to_list(struct cam_data* l, struct cam_data* drv) static inline void cpia_add_to_list(struct cam_data* l, struct cam_data* drv)
{ {
drv->next = l; drv->next = l;
...@@ -423,7 +407,6 @@ static inline void cpia_add_to_list(struct cam_data* l, struct cam_data* drv) ...@@ -423,7 +407,6 @@ static inline void cpia_add_to_list(struct cam_data* l, struct cam_data* drv)
l = drv; l = drv;
} }
static inline void cpia_remove_from_list(struct cam_data* drv) static inline void cpia_remove_from_list(struct cam_data* drv)
{ {
if (drv->previous != NULL) { if (drv->previous != NULL) {
...@@ -435,7 +418,6 @@ static inline void cpia_remove_from_list(struct cam_data* drv) ...@@ -435,7 +418,6 @@ static inline void cpia_remove_from_list(struct cam_data* drv)
} }
} }
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
#endif /* cpia_h */ #endif /* cpia_h */
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* Supports CPiA based parallel port Video Camera's. * Supports CPiA based parallel port Video Camera's.
* *
* (C) Copyright 1999 Bas Huisman <bhuism@cs.utwente.nl> * (C) Copyright 1999 Bas Huisman <bhuism@cs.utwente.nl>
* (C) Copyright 1999-2000 Scott J. Bertin <sbertin@mindspring.com>, * (C) Copyright 1999-2000 Scott J. Bertin <sbertin@securenym.net>,
* (C) Copyright 1999-2000 Peter Pregler <Peter_Pregler@email.com> * (C) Copyright 1999-2000 Peter Pregler <Peter_Pregler@email.com>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
...@@ -341,17 +341,6 @@ static int cpia_pp_streamStop(void *privdata) ...@@ -341,17 +341,6 @@ static int cpia_pp_streamStop(void *privdata)
return 0; return 0;
} }
static int cpia_pp_read(struct parport *port, u8 *buffer, int len)
{
int bytes_read, new_bytes;
for(bytes_read=0; bytes_read<len; bytes_read += new_bytes) {
new_bytes = parport_read(port, buffer+bytes_read,
len-bytes_read);
if(new_bytes < 0) break;
}
return bytes_read;
}
/**************************************************************************** /****************************************************************************
* *
* cpia_pp_streamRead * cpia_pp_streamRead
...@@ -361,7 +350,7 @@ static int cpia_pp_streamRead(void *privdata, u8 *buffer, int noblock) ...@@ -361,7 +350,7 @@ static int cpia_pp_streamRead(void *privdata, u8 *buffer, int noblock)
{ {
struct pp_cam_entry *cam = privdata; struct pp_cam_entry *cam = privdata;
int read_bytes = 0; int read_bytes = 0;
int i, endseen, block_size, new_bytes; int i, endseen;
if(cam == NULL) { if(cam == NULL) {
DBG("Internal driver error: cam is NULL\n"); DBG("Internal driver error: cam is NULL\n");
...@@ -390,34 +379,24 @@ static int cpia_pp_streamRead(void *privdata, u8 *buffer, int noblock) ...@@ -390,34 +379,24 @@ static int cpia_pp_streamRead(void *privdata, u8 *buffer, int noblock)
return -EIO; return -EIO;
} }
} }
endseen = 0; read_bytes = parport_read(cam->port, buffer, CPIA_MAX_IMAGE_SIZE );
block_size = PARPORT_CHUNK_SIZE;
while( !cam->image_complete ) {
cond_resched();
new_bytes = cpia_pp_read(cam->port, buffer, block_size ); EndTransferMode(cam);
if( new_bytes <= 0 ) { DBG("read %d bytes\n", read_bytes);
break; if( read_bytes<0) return -EIO;
} endseen = 0;
i=-1; for( i=0; i<read_bytes && endseen<4; i++ ) {
while(++i<new_bytes && endseen<4) { if( *buffer==EOI ) {
if(*buffer==EOI) {
endseen++; endseen++;
} else { } else {
endseen=0; endseen=0;
} }
buffer++; buffer++;
} }
read_bytes += i; if( endseen>3 ) {
if( endseen==4 ) {
cam->image_complete=1; cam->image_complete=1;
break; DBG("endseen at %d bytes\n", i);
}
if( CPIA_MAX_IMAGE_SIZE-read_bytes <= PARPORT_CHUNK_SIZE ) {
block_size=CPIA_MAX_IMAGE_SIZE-read_bytes;
} }
}
EndTransferMode(cam);
return cam->image_complete ? read_bytes : -EIO; return cam->image_complete ? read_bytes : -EIO;
} }
...@@ -716,15 +695,6 @@ void cleanup_module(void) ...@@ -716,15 +695,6 @@ void cleanup_module(void)
static int __init cpia_pp_setup(char *str) static int __init cpia_pp_setup(char *str)
{ {
#if 0
/* Is this only a 2.2ism? -jerdfelt */
if (!str) {
if (ints[0] == 0 || ints[1] == 0) {
/* disable driver on "cpia_pp=" or "cpia_pp=0" */
parport_nr[0] = PPCPIA_PARPORT_OFF;
}
} else
#endif
if (!strncmp(str, "parport", 7)) { if (!strncmp(str, "parport", 7)) {
int n = simple_strtoul(str + 7, NULL, 10); int n = simple_strtoul(str + 7, NULL, 10);
if (parport_ptr < PARPORT_MAX) { if (parport_ptr < PARPORT_MAX) {
......
...@@ -273,14 +273,16 @@ static int cpia_usb_open(void *privdata) ...@@ -273,14 +273,16 @@ static int cpia_usb_open(void *privdata)
error_urb1: /* free urb 1 */ error_urb1: /* free urb 1 */
usb_free_urb(ucpia->sbuf[1].urb); usb_free_urb(ucpia->sbuf[1].urb);
ucpia->sbuf[1].urb = NULL;
error_urb0: /* free urb 0 */ error_urb0: /* free urb 0 */
usb_free_urb(ucpia->sbuf[0].urb); usb_free_urb(ucpia->sbuf[0].urb);
ucpia->sbuf[0].urb = NULL;
error_1: error_1:
kfree (ucpia->sbuf[1].data); kfree (ucpia->sbuf[1].data);
ucpia->sbuf[1].data = NULL;
error_0: error_0:
kfree (ucpia->sbuf[0].data); kfree (ucpia->sbuf[0].data);
ucpia->sbuf[0].data = NULL;
return retval; return retval;
} }
...@@ -636,8 +638,10 @@ static void cpia_disconnect(struct usb_interface *intf) ...@@ -636,8 +638,10 @@ static void cpia_disconnect(struct usb_interface *intf)
ucpia->buffers[0] = NULL; ucpia->buffers[0] = NULL;
} }
if (!ucpia->open) if (!ucpia->open) {
kfree(ucpia); kfree(ucpia);
cam->lowlevel_data = NULL;
}
} }
static int __init usb_cpia_init(void) static int __init usb_cpia_init(void)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment