Exemplo n.º 1
0
/* Capture data */
static ssize_t w9966_v4l_read(struct file *file, char  __user *buf,
		size_t count, loff_t *ppos)
{
	struct w9966 *cam = video_drvdata(file);
	unsigned char addr = 0xa0;	/* ECP, read, CCD-transfer, 00000 */
	unsigned char __user *dest = (unsigned char __user *)buf;
	unsigned long dleft = count;
	unsigned char *tbuf;

	/* Why would anyone want more than this?? */
	if (count > cam->width * cam->height * 2)
		return -EINVAL;

	mutex_lock(&cam->lock);
	w9966_pdev_claim(cam);
	w9966_write_reg(cam, 0x00, 0x02);	/* Reset ECP-FIFO buffer */
	w9966_write_reg(cam, 0x00, 0x00);	/* Return to normal operation */
	w9966_write_reg(cam, 0x01, 0x98);	/* Enable capture */

	/* write special capture-addr and negotiate into data transfer */
	if ((parport_negotiate(cam->pport, cam->ppmode|IEEE1284_ADDR) != 0) ||
			(parport_write(cam->pport, &addr, 1) != 1) ||
			(parport_negotiate(cam->pport, cam->ppmode|IEEE1284_DATA) != 0)) {
		w9966_pdev_release(cam);
		mutex_unlock(&cam->lock);
		return -EFAULT;
	}

	tbuf = kmalloc(W9966_RBUFFER, GFP_KERNEL);
	if (tbuf == NULL) {
		count = -ENOMEM;
		goto out;
	}

	while (dleft > 0) {
		unsigned long tsize = (dleft > W9966_RBUFFER) ? W9966_RBUFFER : dleft;

		if (parport_read(cam->pport, tbuf, tsize) < tsize) {
			count = -EFAULT;
			goto out;
		}
		if (copy_to_user(dest, tbuf, tsize) != 0) {
			count = -EFAULT;
			goto out;
		}
		dest += tsize;
		dleft -= tsize;
	}

	w9966_write_reg(cam, 0x01, 0x18);	/* Disable capture */

out:
	kfree(tbuf);
	w9966_pdev_release(cam);
	mutex_unlock(&cam->lock);

	return count;
}
Exemplo n.º 2
0
// Terminate everything gracefully
static void w9966_term(struct w9966_dev* cam)
{
// Delete allocated buffer if needed
	if (cam->buffer != NULL) {
		kfree(cam->buffer);
		cam->buffer = NULL;
	}

// Unregister from v4l
	if (w9966_getState(cam, W9966_STATE_VDEV, W9966_STATE_VDEV)) {
		video_unregister_device(&cam->vdev);
		w9966_setState(cam, W9966_STATE_VDEV, 0);
	}

// Terminate from IEEE1284 mode and release pdev block
	if (w9966_getState(cam, W9966_STATE_PDEV, W9966_STATE_PDEV)) {
		w9966_pdev_claim(cam);
		parport_negotiate(cam->pport, IEEE1284_MODE_COMPAT);
		w9966_pdev_release(cam);
	}

// Unregister from parport
	if (w9966_getState(cam, W9966_STATE_PDEV, W9966_STATE_PDEV)) {
		parport_unregister_device(cam->pdev);
		w9966_setState(cam, W9966_STATE_PDEV, 0);
	}
}
Exemplo n.º 3
0
// Capture data
static long w9966_v4l_read(struct video_device *vdev, char *buf, unsigned long count,  int noblock)
{
	struct w9966_dev *cam = (struct w9966_dev *)vdev->priv;
	unsigned char addr = 0xa0;	// ECP, read, CCD-transfer, 00000
	unsigned char* dest = (unsigned char*)buf;
	unsigned long dleft = count;
	
	// Why would anyone want more than this??
	if (count > cam->width * cam->height * 2)
		return -EINVAL;
	
	w9966_pdev_claim(cam);
	w9966_wReg(cam, 0x00, 0x02);	// Reset ECP-FIFO buffer
	w9966_wReg(cam, 0x00, 0x00);	// Return to normal operation
	w9966_wReg(cam, 0x01, 0x98);	// Enable capture

	// write special capture-addr and negotiate into data transfer	
	if (
		(parport_negotiate(cam->pport, cam->ppmode|IEEE1284_ADDR) != 0	)||
		(parport_write(cam->pport, &addr, 1) != 1						)||
		(parport_negotiate(cam->pport, cam->ppmode|IEEE1284_DATA) != 0	)
	) {
		w9966_pdev_release(cam);
		return -EFAULT;
	}
	
	while(dleft > 0)
	{
		unsigned long tsize = (dleft > W9966_RBUFFER) ? W9966_RBUFFER : dleft;
	
		if (parport_read(cam->pport, cam->buffer, tsize) < tsize) {
			w9966_pdev_release(cam);
			return -EFAULT;
		}
		if (copy_to_user(dest, cam->buffer, tsize) != 0) {
			w9966_pdev_release(cam);
			return -EFAULT;
		}
		dest += tsize;
		dleft -= tsize;
	}
	
	w9966_wReg(cam, 0x01, 0x18);	// Disable capture
	w9966_pdev_release(cam);

	return count;
}
Exemplo n.º 4
0
static void w9966_v4l_close(struct video_device *vdev)
{
	struct w9966_dev *cam = (struct w9966_dev*)vdev->priv;

	// Free read buffer
	if (w9966_flag_test(cam, W9966_STATE_BUFFER)) {
		kfree(cam->buffer);
		w9966_flag_clear(cam, W9966_STATE_BUFFER);
	}

	// release parport
	w9966_pdev_release(cam);
}
Exemplo n.º 5
0
static int cam_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
{
	struct w9966 *cam = video_drvdata(file);
	struct v4l2_pix_format *pix = &fmt->fmt.pix;
	int ret = cam_try_fmt_vid_cap(file, fh, fmt);

	if (ret)
		return ret;

	mutex_lock(&cam->lock);
	/* Update camera regs */
	w9966_pdev_claim(cam);
	ret = w9966_setup(cam, 0, 0, 1023, 1023, pix->width, pix->height);
	w9966_pdev_release(cam);
	mutex_unlock(&cam->lock);
	return ret;
}
Exemplo n.º 6
0
static int w9966_v4l_open(struct video_device *vdev, int flags)
{
	struct w9966_dev *cam = (struct w9966_dev*)vdev->priv;

	// Claim parport
	if (!w9966_pdev_claim(cam)) {
		DPRINTF("Unable to claim parport");
		return -EFAULT;
	}

	// Allocate read buffer
	cam->buffer = (u8*)kmalloc(W9966_RBUFFER, GFP_KERNEL);
	if (cam->buffer == NULL) {
		w9966_pdev_release(cam);
		return -ENOMEM;
	}
	w9966_flag_set(cam, W9966_STATE_BUFFER);

	return 0;
}
Exemplo n.º 7
0
/* Terminate everything gracefully */
static void w9966_term(struct w9966 *cam)
{
	/* Unregister from v4l */
	if (w9966_get_state(cam, W9966_STATE_VDEV, W9966_STATE_VDEV)) {
		video_unregister_device(&cam->vdev);
		w9966_set_state(cam, W9966_STATE_VDEV, 0);
	}

	/* Terminate from IEEE1284 mode and release pdev block */
	if (w9966_get_state(cam, W9966_STATE_PDEV, W9966_STATE_PDEV)) {
		w9966_pdev_claim(cam);
		parport_negotiate(cam->pport, IEEE1284_MODE_COMPAT);
		w9966_pdev_release(cam);
	}

	/* Unregister from parport */
	if (w9966_get_state(cam, W9966_STATE_PDEV, W9966_STATE_PDEV)) {
		parport_unregister_device(cam->pdev);
		w9966_set_state(cam, W9966_STATE_PDEV, 0);
	}
}
Exemplo n.º 8
0
// Terminate everything gracefully
static void w9966_term(struct w9966_dev* cam)
{
	// Delete allocated buffer
	if (w9966_flag_test(cam, W9966_STATE_BUFFER))
		kfree(cam->buffer);

	// Unregister from v4l
	if (w9966_flag_test(cam, W9966_STATE_VDEV))
		video_unregister_device(&cam->vdev);

	// Terminate from IEEE1284 mode and unregister from parport
	if (w9966_flag_test(cam, W9966_STATE_PDEV)) {
		if (w9966_pdev_claim(cam))
			parport_negotiate(cam->pport, IEEE1284_MODE_COMPAT);

		w9966_pdev_release(cam);
		parport_unregister_device(cam->pdev);
	}

	cam->dev_state = 0x00;
}
Exemplo n.º 9
0
static int cam_s_ctrl(struct file *file, void *priv,
					struct v4l2_control *ctrl)
{
	struct w9966 *cam = video_drvdata(file);
	int ret = 0;

	mutex_lock(&cam->lock);
	switch (ctrl->id) {
	case V4L2_CID_BRIGHTNESS:
		cam->brightness = ctrl->value;
		break;
	case V4L2_CID_CONTRAST:
		cam->contrast = ctrl->value;
		break;
	case V4L2_CID_SATURATION:
		cam->color = ctrl->value;
		break;
	case V4L2_CID_HUE:
		cam->hue = ctrl->value;
		break;
	default:
		ret = -EINVAL;
		break;
	}

	if (ret == 0) {
		w9966_pdev_claim(cam);

		if (w9966_write_reg_i2c(cam, 0x0a, cam->brightness) == -1 ||
		    w9966_write_reg_i2c(cam, 0x0b, cam->contrast) == -1 ||
		    w9966_write_reg_i2c(cam, 0x0c, cam->color) == -1 ||
		    w9966_write_reg_i2c(cam, 0x0d, cam->hue) == -1) {
			ret = -EIO;
		}

		w9966_pdev_release(cam);
	}
	mutex_unlock(&cam->lock);
	return ret;
}
Exemplo n.º 10
0
static int w9966_v4l_do_ioctl(struct inode *inode, struct file *file,
			      unsigned int cmd, void *arg)
{
	struct video_device *vdev = video_devdata(file);
	struct w9966_dev *cam = vdev->priv;

	switch(cmd)
	{
	case VIDIOCGCAP:
	{
		static struct video_capability vcap = {
			.name      = W9966_DRIVERNAME,
			.type      = VID_TYPE_CAPTURE | VID_TYPE_SCALES,
			.channels  = 1,
			.maxwidth  = W9966_WND_MAX_W,
			.maxheight = W9966_WND_MAX_H,
			.minwidth  = 2,
			.minheight = 1,
		};
		struct video_capability *cap = arg;
		*cap = vcap;
		return 0;
	}
	case VIDIOCGCHAN:
	{
		struct video_channel *vch = arg;
		if(vch->channel != 0)	// We only support one channel (#0)
			return -EINVAL;
		memset(vch,0,sizeof(*vch));
		strcpy(vch->name, "CCD-input");
		vch->type = VIDEO_TYPE_CAMERA;
		return 0;
	}
	case VIDIOCSCHAN:
	{
		struct video_channel *vch = arg;
		if(vch->channel != 0)
			return -EINVAL;
		return 0;
	}
	case VIDIOCGTUNER:
	{
		struct video_tuner *vtune = arg;
		if(vtune->tuner != 0)
			return -EINVAL;
		strcpy(vtune->name, "no tuner");
		vtune->rangelow = 0;
		vtune->rangehigh = 0;
		vtune->flags = VIDEO_TUNER_NORM;
		vtune->mode = VIDEO_MODE_AUTO;
		vtune->signal = 0xffff;
		return 0;
	}
	case VIDIOCSTUNER:
	{
		struct video_tuner *vtune = arg;
		if (vtune->tuner != 0)
			return -EINVAL;
		if (vtune->mode != VIDEO_MODE_AUTO)
			return -EINVAL;
		return 0;
	}
	case VIDIOCGPICT:
	{
		struct video_picture vpic = {
			cam->brightness << 8,	// brightness
			(cam->hue + 128) << 8,	// hue
			cam->color << 9,	// color
			cam->contrast << 9,	// contrast
			0x8000,			// whiteness
			16, VIDEO_PALETTE_YUV422// bpp, palette format
		};
		struct video_picture *pic = arg;
		*pic = vpic;
		return 0;
	}
	case VIDIOCSPICT:
	{
		struct video_picture *vpic = arg;
		if (vpic->depth != 16 || (vpic->palette != VIDEO_PALETTE_YUV422 && vpic->palette != VIDEO_PALETTE_YUYV))
			return -EINVAL;

		cam->brightness = vpic->brightness >> 8;
		cam->hue = (vpic->hue >> 8) - 128;
		cam->color = vpic->colour >> 9;
		cam->contrast = vpic->contrast >> 9;

		w9966_pdev_claim(cam);

		if (
			w9966_wReg_i2c(cam, 0x0a, cam->brightness) == -1 ||
			w9966_wReg_i2c(cam, 0x0b, cam->contrast) == -1 ||
			w9966_wReg_i2c(cam, 0x0c, cam->color) == -1 ||
			w9966_wReg_i2c(cam, 0x0d, cam->hue) == -1
		) {
			w9966_pdev_release(cam);
			return -EIO;
		}

		w9966_pdev_release(cam);
		return 0;
	}
	case VIDIOCSWIN:
	{
		int ret;
		struct video_window *vwin = arg;

		if (vwin->flags != 0)
			return -EINVAL;
		if (vwin->clipcount != 0)
			return -EINVAL;
		if (vwin->width < 2 || vwin->width > W9966_WND_MAX_W)
			return -EINVAL;
		if (vwin->height < 1 || vwin->height > W9966_WND_MAX_H)
			return -EINVAL;

		// Update camera regs
		w9966_pdev_claim(cam);
		ret = w9966_setup(cam, 0, 0, 1023, 1023, vwin->width, vwin->height);
		w9966_pdev_release(cam);

		if (ret != 0) {
			DPRINTF("VIDIOCSWIN: w9966_setup() failed.\n");
			return -EIO;
		}

		return 0;
	}
	case VIDIOCGWIN:
	{
		struct video_window *vwin = arg;
		memset(vwin, 0, sizeof(*vwin));
		vwin->width = cam->width;
		vwin->height = cam->height;
		return 0;
	}
	// Unimplemented
	case VIDIOCCAPTURE:
	case VIDIOCGFBUF:
	case VIDIOCSFBUF:
	case VIDIOCKEY:
	case VIDIOCGFREQ:
	case VIDIOCSFREQ:
	case VIDIOCGAUDIO:
	case VIDIOCSAUDIO:
		return -EINVAL;
	default:
		return -ENOIOCTLCMD;
	}
	return 0;
}

static int w9966_v4l_ioctl(struct inode *inode, struct file *file,
			   unsigned int cmd, unsigned long arg)
{
	return video_usercopy(inode, file, cmd, arg, w9966_v4l_do_ioctl);
}

// Capture data
static ssize_t w9966_v4l_read(struct file *file, char  __user *buf,
			      size_t count, loff_t *ppos)
{
	struct video_device *vdev = video_devdata(file);
	struct w9966_dev *cam = vdev->priv;
	unsigned char addr = 0xa0;	// ECP, read, CCD-transfer, 00000
	unsigned char __user *dest = (unsigned char __user *)buf;
	unsigned long dleft = count;
	unsigned char *tbuf;

	// Why would anyone want more than this??
	if (count > cam->width * cam->height * 2)
		return -EINVAL;

	w9966_pdev_claim(cam);
	w9966_wReg(cam, 0x00, 0x02);	// Reset ECP-FIFO buffer
	w9966_wReg(cam, 0x00, 0x00);	// Return to normal operation
	w9966_wReg(cam, 0x01, 0x98);	// Enable capture

	// write special capture-addr and negotiate into data transfer
	if (
		(parport_negotiate(cam->pport, cam->ppmode|IEEE1284_ADDR) != 0	)||
		(parport_write(cam->pport, &addr, 1) != 1						)||
		(parport_negotiate(cam->pport, cam->ppmode|IEEE1284_DATA) != 0	)
	) {
		w9966_pdev_release(cam);
		return -EFAULT;
	}

	tbuf = kmalloc(W9966_RBUFFER, GFP_KERNEL);
	if (tbuf == NULL) {
		count = -ENOMEM;
		goto out;
	}

	while(dleft > 0)
	{
		unsigned long tsize = (dleft > W9966_RBUFFER) ? W9966_RBUFFER : dleft;

		if (parport_read(cam->pport, tbuf, tsize) < tsize) {
			count = -EFAULT;
			goto out;
		}
		if (copy_to_user(dest, tbuf, tsize) != 0) {
			count = -EFAULT;
			goto out;
		}
		dest += tsize;
		dleft -= tsize;
	}

	w9966_wReg(cam, 0x01, 0x18);	// Disable capture

out:
	kfree(tbuf);
	w9966_pdev_release(cam);

	return count;
}


// Called once for every parport on init
static void w9966_attach(struct parport *port)
{
	int i;

	for (i = 0; i < W9966_MAXCAMS; i++)
	{
		if (w9966_cams[i].dev_state != 0)	// Cam is already assigned
			continue;
		if (
			strcmp(pardev[i], "aggressive") == 0 ||
			strcmp(pardev[i], port->name) == 0
		) {
			if (w9966_init(&w9966_cams[i], port) != 0)
			w9966_term(&w9966_cams[i]);
			break;	// return
		}
	}
}
Exemplo n.º 11
0
static int w9966_v4l_ioctl(struct video_device *vdev, unsigned int cmd, void *arg)
{
	struct w9966_dev *cam = (struct w9966_dev*)vdev->priv;
	
	switch(cmd)
	{
	case VIDIOCGCAP:
	{
		struct video_capability vcap = {
			W9966_DRIVERNAME,	// name
			VID_TYPE_CAPTURE | VID_TYPE_SCALES,	// type
			1, 0,			// vid, aud channels
			W9966_WND_MAX_W,	// max w
			W9966_WND_MAX_H,	// max h
			2, 1			// min w, min h
		};

		if(copy_to_user(arg, &vcap, sizeof(vcap)) != 0)
			return -EFAULT;

		return 0;
	}
	case VIDIOCGCHAN:
	{
		struct video_channel vch;
		if(copy_from_user(&vch, arg, sizeof(vch)) != 0)
			return -EFAULT;

		if(vch.channel != 0)	// We only support one channel (#0)
			return -EINVAL;

		strcpy(vch.name, "CCD-input");
		vch.flags = 0;		// We have no tuner or audio
		vch.tuners = 0;
		vch.type = VIDEO_TYPE_CAMERA;
		vch.norm = 0;		// ???
		
		if(copy_to_user(arg, &vch, sizeof(vch)) != 0)
			return -EFAULT;
		
		return 0;
	}
	case VIDIOCSCHAN:
	{
		struct video_channel vch;
		if(copy_from_user(&vch, arg, sizeof(vch) ) != 0)
			return -EFAULT;
		
		if(vch.channel != 0)
			return -EINVAL;
		
		return 0;
	}
	case VIDIOCGTUNER:
	{
		struct video_tuner vtune;
		if(copy_from_user(&vtune, arg, sizeof(vtune)) != 0)
			return -EFAULT;
		
		if(vtune.tuner != 0);
			return -EINVAL;
		
		strcpy(vtune.name, "no tuner");
		vtune.rangelow = 0;
		vtune.rangehigh = 0;
		vtune.flags = VIDEO_TUNER_NORM;
		vtune.mode = VIDEO_MODE_AUTO;
		vtune.signal = 0xffff;
		
		if(copy_to_user(arg, &vtune, sizeof(vtune)) != 0)
			return -EFAULT;
		
		return 0;
	}
	case VIDIOCSTUNER:
	{
		struct video_tuner vtune;
		if (copy_from_user(&vtune, arg, sizeof(vtune)) != 0)
			return -EFAULT;
		
		if (vtune.tuner != 0)
			return -EINVAL;
		
		if (vtune.mode != VIDEO_MODE_AUTO)
			return -EINVAL;
		
		return 0;
	}
	case VIDIOCGPICT:
	{
		struct video_picture vpic = {
			cam->brightness << 8,	// brightness
			(cam->hue + 128) << 8,	// hue
			cam->color << 9,	// color
			cam->contrast << 9,	// contrast
			0x8000,			// whiteness
			16, VIDEO_PALETTE_YUV422// bpp, palette format
		};

		if(copy_to_user(arg, &vpic, sizeof(vpic)) != 0)
			return -EFAULT;

		return 0;
	}
	case VIDIOCSPICT:
	{
		struct video_picture vpic;
		if(copy_from_user(&vpic, arg, sizeof(vpic)) != 0)
			return -EFAULT;
		
		if (vpic.depth != 16 || vpic.palette != VIDEO_PALETTE_YUV422)
			return -EINVAL;
			
		cam->brightness = vpic.brightness >> 8;
		cam->hue = (vpic.hue >> 8) - 128;
		cam->color = vpic.colour >> 9;
		cam->contrast = vpic.contrast >> 9;

		w9966_pdev_claim(cam);
		
		if (
			w9966_wReg_i2c(cam, 0x0a, cam->brightness) == -1 ||
			w9966_wReg_i2c(cam, 0x0b, cam->contrast) == -1 ||
			w9966_wReg_i2c(cam, 0x0c, cam->color) == -1 ||
			w9966_wReg_i2c(cam, 0x0d, cam->hue) == -1
		) {
			w9966_pdev_release(cam);
			return -EFAULT;
		}
		
		w9966_pdev_release(cam);
		return 0;
	}
	case VIDIOCSWIN:
	{
		int ret;
		struct video_window vwin;
		
		if (copy_from_user(&vwin, arg, sizeof(vwin)) != 0)
			return -EFAULT;		
		if (vwin.flags != 0)
			return -EINVAL;
		if (vwin.clipcount != 0)
			return -EINVAL;
		if (vwin.width < 2 || vwin.width > W9966_WND_MAX_W)
			return -EINVAL;		
		if (vwin.height < 1 || vwin.height > W9966_WND_MAX_H)
			return -EINVAL;

		// Update camera regs
		w9966_pdev_claim(cam);
		ret = w9966_setup(cam, 0, 0, 1023, 1023, vwin.width, vwin.height);
		w9966_pdev_release(cam);
		
		if (ret != 0) {
			DPRINTF("VIDIOCSWIN: w9966_setup() failed.\n");
			return -EFAULT;
		}
		
		return 0;
	}
	case VIDIOCGWIN:
	{
		struct video_window vwin;
		memset(&vwin, 0, sizeof(vwin));
		
		vwin.width = cam->width;
		vwin.height = cam->height;
		
		if(copy_to_user(arg, &vwin, sizeof(vwin)) != 0)
			return -EFAULT;
		
		return 0;
	}
	// Unimplemented
	case VIDIOCCAPTURE:	
	case VIDIOCGFBUF:
	case VIDIOCSFBUF:
	case VIDIOCKEY:
	case VIDIOCGFREQ:
	case VIDIOCSFREQ:
	case VIDIOCGAUDIO:
	case VIDIOCSAUDIO:
		return -EINVAL;
	default:
		return -ENOIOCTLCMD;
	}
	return 0;
}
Exemplo n.º 12
0
// Initialize camera device. Setup all internal flags, set a
// default video mode, setup ccd-chip, register v4l device etc..
// Also used for 'probing' of hardware.
// -1 on error
static int w9966_init(struct w9966_dev* cam, struct parport* port)
{
	if (cam->dev_state != 0)
		return -1;
	
	cam->pport = port;
	cam->brightness = 128;
	cam->contrast = 64;
	cam->color = 64;
	cam->hue = 0;

// Select requested transfer mode
	switch(parmode)
	{
	default:	// Auto-detect (priority: hw-ecp, hw-epp, sw-ecp)
	case 0:
		if (port->modes & PARPORT_MODE_ECP)
			cam->ppmode = IEEE1284_MODE_ECP;
/*		else if (port->modes & PARPORT_MODE_EPP)
			cam->ppmode = IEEE1284_MODE_EPP;*/
		else
			cam->ppmode = IEEE1284_MODE_ECPSWE;
		break;	
	case 1:		// hw- or sw-ecp
		if (port->modes & PARPORT_MODE_ECP)
			cam->ppmode = IEEE1284_MODE_ECP;
		else
			cam->ppmode = IEEE1284_MODE_ECPSWE;
		break;
	case 2:		// hw- or sw-epp
		if (port->modes & PARPORT_MODE_EPP)
			cam->ppmode = IEEE1284_MODE_EPP;
		else
			cam->ppmode = IEEE1284_MODE_EPPSWE;
		break;
	}
	
// Tell the parport driver that we exists
	cam->pdev = parport_register_device(port, "w9966", NULL, NULL, NULL, 0, NULL);
	if (cam->pdev == NULL) {
		DPRINTF("parport_register_device() failed\n");
		return -1;
	}
	w9966_setState(cam, W9966_STATE_PDEV, W9966_STATE_PDEV);

	w9966_pdev_claim(cam);
	
// Setup a default capture mode
	if (w9966_setup(cam, 0, 0, 1023, 1023, 200, 160) != 0) {
		DPRINTF("w9966_setup() failed.\n");
		return -1;
	}

	w9966_pdev_release(cam);

// Fill in the video_device struct and register us to v4l
	memset(&cam->vdev, 0, sizeof(struct video_device));
	strcpy(cam->vdev.name, W9966_DRIVERNAME);
	cam->vdev.type = VID_TYPE_CAPTURE | VID_TYPE_SCALES;
	cam->vdev.hardware = VID_HARDWARE_W9966;
	cam->vdev.open = &w9966_v4l_open;
	cam->vdev.close = &w9966_v4l_close;
	cam->vdev.read = &w9966_v4l_read;
	cam->vdev.ioctl = &w9966_v4l_ioctl;
	cam->vdev.priv = (void*)cam;
	cam->vdev.owner = THIS_MODULE;

	if (video_register_device(&cam->vdev, VFL_TYPE_GRABBER, video_nr) == -1)		 
		return -1;
	
	w9966_setState(cam, W9966_STATE_VDEV, W9966_STATE_VDEV);
	
	cam->buffer = NULL;
	
	// All ok
	printk(
		"w9966cf: Found and initialized a webcam on %s.\n",
		cam->pport->name
	);
	return 0;
}
Exemplo n.º 13
0
/* Initialize camera device. Setup all internal flags, set a
   default video mode, setup ccd-chip, register v4l device etc..
   Also used for 'probing' of hardware.
   -1 on error */
static int w9966_init(struct w9966 *cam, struct parport *port)
{
	struct v4l2_device *v4l2_dev = &cam->v4l2_dev;

	if (cam->dev_state != 0)
		return -1;

	strlcpy(v4l2_dev->name, "w9966", sizeof(v4l2_dev->name));

	if (v4l2_device_register(NULL, v4l2_dev) < 0) {
		v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
		return -1;
	}
	cam->pport = port;
	cam->brightness = 128;
	cam->contrast = 64;
	cam->color = 64;
	cam->hue = 0;

	/* Select requested transfer mode */
	switch (parmode) {
	default:	/* Auto-detect (priority: hw-ecp, hw-epp, sw-ecp) */
	case 0:
		if (port->modes & PARPORT_MODE_ECP)
			cam->ppmode = IEEE1284_MODE_ECP;
		else if (port->modes & PARPORT_MODE_EPP)
			cam->ppmode = IEEE1284_MODE_EPP;
		else
			cam->ppmode = IEEE1284_MODE_ECP;
		break;
	case 1:		/* hw- or sw-ecp */
		cam->ppmode = IEEE1284_MODE_ECP;
		break;
	case 2:		/* hw- or sw-epp */
		cam->ppmode = IEEE1284_MODE_EPP;
		break;
	}

	/* Tell the parport driver that we exists */
	cam->pdev = parport_register_device(port, "w9966", NULL, NULL, NULL, 0, NULL);
	if (cam->pdev == NULL) {
		DPRINTF("parport_register_device() failed\n");
		return -1;
	}
	w9966_set_state(cam, W9966_STATE_PDEV, W9966_STATE_PDEV);

	w9966_pdev_claim(cam);

	/* Setup a default capture mode */
	if (w9966_setup(cam, 0, 0, 1023, 1023, 200, 160) != 0) {
		DPRINTF("w9966_setup() failed.\n");
		return -1;
	}

	w9966_pdev_release(cam);

	/* Fill in the video_device struct and register us to v4l */
	strlcpy(cam->vdev.name, W9966_DRIVERNAME, sizeof(cam->vdev.name));
	cam->vdev.v4l2_dev = v4l2_dev;
	cam->vdev.fops = &w9966_fops;
	cam->vdev.ioctl_ops = &w9966_ioctl_ops;
	cam->vdev.release = video_device_release_empty;
	video_set_drvdata(&cam->vdev, cam);

	mutex_init(&cam->lock);

	if (video_register_device(&cam->vdev, VFL_TYPE_GRABBER, video_nr) < 0)
		return -1;

	w9966_set_state(cam, W9966_STATE_VDEV, W9966_STATE_VDEV);

	/* All ok */
	v4l2_info(v4l2_dev, "Found and initialized a webcam on %s.\n",
			cam->pport->name);
	return 0;
}
Exemplo n.º 14
0
// Initialize camera device. Setup all internal flags, set a
// default video mode, setup ccd-chip, register v4l device etc..
// Also used for 'probing' of hardware.
// 1 on success, else 0
static int w9966_init(struct w9966_dev* cam, struct parport* port, int vidnr)
{
	if (cam->dev_state != 0)
		return 0;

	cam->pport = port;
	cam->brightness = 128;
	cam->contrast = 64;
	cam->color = 64;
	cam->hue = 0;

	// Select requested transfer mode
	switch(parmode)
	{
	default:	// Auto-detect (priority: hw-ecp, hw-epp, sw-ecp)
	case 0:
		if (port->modes & PARPORT_MODE_ECP)
			cam->ppmode = IEEE1284_MODE_ECP;
		else if (port->modes & PARPORT_MODE_EPP)
			cam->ppmode = IEEE1284_MODE_EPP;
		else
			cam->ppmode = IEEE1284_MODE_ECPSWE;
		break;
	case 1:		// hw- or sw-ecp
		if (port->modes & PARPORT_MODE_ECP)
			cam->ppmode = IEEE1284_MODE_ECP;
		else
			cam->ppmode = IEEE1284_MODE_ECPSWE;
		break;
	case 2:		// hw- or sw-epp
		if (port->modes & PARPORT_MODE_EPP)
			cam->ppmode = IEEE1284_MODE_EPP;
		else
			cam->ppmode = IEEE1284_MODE_EPPSWE;
		break;
	case 3:		// hw-ecp
		cam->ppmode = IEEE1284_MODE_ECP;
		break;
	}

	// Tell the parport driver that we exists
	cam->pdev = parport_register_device(
	    port, W9966_DRIVERNAME, NULL, NULL, NULL, 0, NULL);

	if (cam->pdev == NULL) {
		DPRINTF("parport_register_device() failed.\n");
		return 0;
	}
	w9966_flag_set(cam, W9966_STATE_PDEV);

	// Claim parport
	if (!w9966_pdev_claim(cam)) {
		DPRINTF("w9966_pdev_claim() failed.\n");
		return 0;
	}

	// Perform initial w9966 setup
	if (!w9966_setup(cam)) {
		DPRINTF("w9966_setup() failed.\n");
		return 0;
	}

	// Detect model
	if (!w9966_saa7111_init(cam)) {
		DPRINTF("w9966_saa7111_init() failed.\n");
		return 0;
	}
	if (!w9966_lc99053_init(cam)) {
		DPRINTF("w9966_lc99053_init() failed.\n");
		return 0;
	}
	if (!w9966_flag_test(cam, W9966_STATE_DETECTED)) {
		DPRINTF("Camera model not identified.\n");
		return 0;
	}

	// Setup w9966 with a default capture mode (QCIF res.)
	if (!w9966_window(cam, 0, 0, 1023, 1023, 176, 144)) {
		DPRINTF("w9966_window() failed.\n");
		return 0;
	}
	w9966_pdev_release(cam);

	// Fill in the video_device struct and register us to v4l
	memset(&cam->vdev, 0, sizeof(struct video_device));
	strcpy(cam->vdev.name, W9966_DRIVERNAME);
	cam->vdev.type = VID_TYPE_CAPTURE | VID_TYPE_SCALES;
	cam->vdev.hardware = VID_HARDWARE_W9966;
	cam->vdev.open = &w9966_v4l_open;
	cam->vdev.close = &w9966_v4l_close;
	cam->vdev.read = &w9966_v4l_read;
	cam->vdev.ioctl = &w9966_v4l_ioctl;
	cam->vdev.priv = (void*)cam;
	cam->vdev.owner = THIS_MODULE;

	if (video_register_device(&cam->vdev, VFL_TYPE_GRABBER, vidnr) == -1) {
		DPRINTF("video_register_device() failed (minor: %d).\n", vidnr);
		return 0;
	}
	w9966_flag_set(cam, W9966_STATE_VDEV);

	// All ok
	printk("w9966: Found and initialized %s on %s.\n",
		cam->name, cam->pport->name);
	return 1;
}