Example #1
0
// Write register to w9966 interface-chip
// Expects a claimed pdev
// 1 on success, else 0
static int w9966_wreg(struct w9966_dev* cam, int reg, int data)
{
	// ECP, write, regtransfer, REG, REG, REG, REG, REG
	const u8 addr = 0xc0 | (reg & 0x1f);
	const u8 val = data;

	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 ||
	    parport_write(cam->pport, &val, 1) != 1)
		return 0;

	return 1;
}
Example #2
0
/* Write register to W9966 interface-chip
   Expects a claimed pdev
   -1 on error */
static int w9966_write_reg(struct w9966 *cam, int reg, int data)
{
	/* ECP, write, regtransfer, REG, REG, REG, REG, REG */
	const unsigned char addr = 0xc0 | (reg & 0x1f);
	const unsigned char val = data;

	if (parport_negotiate(cam->pport, cam->ppmode | IEEE1284_ADDR) != 0)
		return -1;
	if (parport_write(cam->pport, &addr, 1) != 1)
		return -1;
	if (parport_negotiate(cam->pport, cam->ppmode | IEEE1284_DATA) != 0)
		return -1;
	if (parport_write(cam->pport, &val, 1) != 1)
		return -1;

	return 0;
}
Example #3
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;
}
Example #4
0
// Read register from w9966 interface-chip
// Expects a claimed pdev
// -1 on error, else register data (byte)
static int w9966_rreg(struct w9966_dev* cam, int reg)
{
	// ECP, read, regtransfer, REG, REG, REG, REG, REG
	const u8 addr = 0x80 | (reg & 0x1f);
	u8 val;

	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 ||
	    parport_read(cam->pport, &val, 1) != 1)
		return -1;

	return val;
}
Example #5
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;
}
Example #6
0
/* Read register from W9966 interface-chip
   Expects a claimed pdev
   -1 on error, else register data (byte) */
static int w9966_read_reg(struct w9966 *cam, int reg)
{
	/* ECP, read, regtransfer, REG, REG, REG, REG, REG */
	const unsigned char addr = 0x80 | (reg & 0x1f);
	unsigned char val;

	if (parport_negotiate(cam->pport, cam->ppmode | IEEE1284_ADDR) != 0)
		return -1;
	if (parport_write(cam->pport, &addr, 1) != 1)
		return -1;
	if (parport_negotiate(cam->pport, cam->ppmode | IEEE1284_DATA) != 0)
		return -1;
	if (parport_read(cam->pport, &val, 1) != 1)
		return -1;

	return val;
}
Example #7
0
// Capture data
// expects a claimed parport and allocated read buffer
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;
	const u8 addr = 0xa0;	// ECP, read, CCD-transfer, 00000
	u8* dest = (u8*)buf;
	unsigned long dleft = count;

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

	w9966_wreg(cam, 0x00, 0x02);	// Reset ECP-FIFO buffer
	w9966_wreg(cam, 0x00, 0x00);	// Return to normal operation
	w9966_wreg(cam, 0x01, cam->cmask | 0x80);	// 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) {
		DPRINTF("Unable to write capture-addr.\n");
		return -EFAULT;
	}

	while(dleft > 0)
	{
		const size_t tsize = (dleft > W9966_RBUFFER) ? W9966_RBUFFER : dleft;

		if (parport_read(cam->pport, cam->buffer, tsize) < tsize)
			return -EFAULT;

		if (copy_to_user(dest, cam->buffer, tsize) != 0)
			return -EFAULT;

		dest += tsize;
		dleft -= tsize;
	}

	w9966_wreg(cam, 0x01, cam->cmask);	// Disable capture

	return count;
}
Example #8
0
static int parport_init(void)
{
    struct cable *cur_cable;
    cur_cable = cables;


    if(ser_open())
    {
        printf("ser_open failed\n");
    }


    parport_cable = "jtagproxy";

    while (cur_cable->name) {
        if (strcmp(cur_cable->name, parport_cable) == 0) {
            cable = cur_cable;
            break;
        }
        cur_cable++;
    }

    if (!cable) {
        LOG_ERROR("No matching cable found for %s", parport_cable);
        return ERROR_JTAG_INIT_FAILED;
    }

    dataport_value = cable->PORT_INIT;

    parport_reset(0, 0);
    parport_write(0, 0, 0);
    parport_led(1);

    bitbang_interface = &parport_bitbang;

    return ERROR_OK;
}
Example #9
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
		}
	}
}
static ssize_t pp_write (struct file * file, const char __user * buf,
			 size_t count, loff_t * ppos)
{
	unsigned int minor = iminor(file->f_path.dentry->d_inode);
	struct pp_struct *pp = file->private_data;
	char * kbuffer;
	ssize_t bytes_written = 0;
	ssize_t wrote;
	int mode;
	struct parport *pport;

	if (!(pp->flags & PP_CLAIMED)) {
		/* Don't have the port claimed */
		pr_debug(CHRDEV "%x: claim the port first\n", minor);
		return -EINVAL;
	}

	kbuffer = kmalloc(min_t(size_t, count, PP_BUFFER_SIZE), GFP_KERNEL);
	if (!kbuffer) {
		return -ENOMEM;
	}
	pport = pp->pdev->port;
	mode = pport->ieee1284.mode & ~(IEEE1284_DEVICEID | IEEE1284_ADDR);

	parport_set_timeout (pp->pdev,
			     (file->f_flags & O_NONBLOCK) ?
			     PARPORT_INACTIVITY_O_NONBLOCK :
			     pp->default_inactivity);

	while (bytes_written < count) {
		ssize_t n = min_t(unsigned long, count - bytes_written, PP_BUFFER_SIZE);

		if (copy_from_user (kbuffer, buf + bytes_written, n)) {
			bytes_written = -EFAULT;
			break;
		}

		if ((pp->flags & PP_FASTWRITE) && (mode == IEEE1284_MODE_EPP)) {
			/* do a fast EPP write */
			if (pport->ieee1284.mode & IEEE1284_ADDR) {
				wrote = pport->ops->epp_write_addr (pport,
					kbuffer, n, PARPORT_EPP_FAST);
			} else {
				wrote = pport->ops->epp_write_data (pport,
					kbuffer, n, PARPORT_EPP_FAST);
			}
		} else {
			wrote = parport_write (pp->pdev->port, kbuffer, n);
		}

		if (wrote <= 0) {
			if (!bytes_written) {
				bytes_written = wrote;
			}
			break;
		}

		bytes_written += wrote;

		if (file->f_flags & O_NONBLOCK) {
			if (!bytes_written)
				bytes_written = -EAGAIN;
			break;
		}

		if (signal_pending (current)) {
			if (!bytes_written) {
				bytes_written = -EINTR;
			}
			break;
		}

		cond_resched();
	}

	parport_set_timeout (pp->pdev, pp->default_inactivity);

	kfree (kbuffer);
	pp_enable_irq (pp);
	return bytes_written;
}
Example #11
0
static int parport_init(void)
{
	const struct cable *cur_cable;
#if PARPORT_USE_PPDEV == 1
	char buffer[256];
#endif

	cur_cable = cables;

	if (parport_cable == NULL) {
		parport_cable = strdup("wiggler");
		LOG_WARNING("No parport cable specified, using default 'wiggler'");
	}

	while (cur_cable->name) {
		if (strcmp(cur_cable->name, parport_cable) == 0) {
			cable = cur_cable;
			break;
		}
		cur_cable++;
	}

	if (!cable) {
		LOG_ERROR("No matching cable found for %s", parport_cable);
		return ERROR_JTAG_INIT_FAILED;
	}

	dataport_value = cable->PORT_INIT;

#if PARPORT_USE_PPDEV == 1
	if (device_handle > 0) {
		LOG_ERROR("device is already opened");
		return ERROR_JTAG_INIT_FAILED;
	}

#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
	LOG_DEBUG("opening /dev/ppi%d...", parport_port);

	snprintf(buffer, 256, "/dev/ppi%d", parport_port);
	device_handle = open(buffer, O_WRONLY);
#else /* not __FreeBSD__, __FreeBSD_kernel__ */
	LOG_DEBUG("opening /dev/parport%d...", parport_port);

	snprintf(buffer, 256, "/dev/parport%d", parport_port);
	device_handle = open(buffer, O_WRONLY);
#endif /* __FreeBSD__, __FreeBSD_kernel__ */

	if (device_handle < 0) {
		int err = errno;
		LOG_ERROR("cannot open device. check it exists and that user read and write rights are set. errno=%d", err);
		return ERROR_JTAG_INIT_FAILED;
	}

	LOG_DEBUG("...open");

#if !defined(__FreeBSD__) && !defined(__FreeBSD_kernel__)
	int i = ioctl(device_handle, PPCLAIM);

	if (i < 0) {
		LOG_ERROR("cannot claim device");
		return ERROR_JTAG_INIT_FAILED;
	}

	i = PARPORT_MODE_COMPAT;
	i = ioctl(device_handle, PPSETMODE, &i);
	if (i < 0) {
		LOG_ERROR(" cannot set compatible mode to device");
		return ERROR_JTAG_INIT_FAILED;
	}

	i = IEEE1284_MODE_COMPAT;
	i = ioctl(device_handle, PPNEGOT, &i);
	if (i < 0) {
		LOG_ERROR("cannot set compatible 1284 mode to device");
		return ERROR_JTAG_INIT_FAILED;
	}
#endif /* not __FreeBSD__, __FreeBSD_kernel__ */

#else /* not PARPORT_USE_PPDEV */
	if (parport_port == 0) {
		parport_port = 0x378;
		LOG_WARNING("No parport port specified, using default '0x378' (LPT1)");
	}

	dataport = parport_port;
	statusport = parport_port + 1;

	LOG_DEBUG("requesting privileges for parallel port 0x%lx...", dataport);
#if PARPORT_USE_GIVEIO == 1
	if (parport_get_giveio_access() != 0) {
#else /* PARPORT_USE_GIVEIO */
	if (ioperm(dataport, 3, 1) != 0) {
#endif /* PARPORT_USE_GIVEIO */
		LOG_ERROR("missing privileges for direct i/o");
		return ERROR_JTAG_INIT_FAILED;
	}
	LOG_DEBUG("...privileges granted");

	/* make sure parallel port is in right mode (clear tristate and interrupt */
	#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
		outb(parport_port + 2, 0x0);
	#else
		outb(0x0, parport_port + 2);
	#endif

#endif /* PARPORT_USE_PPDEV */

	parport_reset(0, 0);
	parport_write(0, 0, 0);
	parport_led(1);

	bitbang_interface = &parport_bitbang;

	return ERROR_OK;
}

static int parport_quit(void)
{
	parport_led(0);

	if (parport_exit) {
		dataport_value = cable->PORT_EXIT;
		parport_write_data();
	}

	if (parport_cable) {
		free(parport_cable);
		parport_cable = NULL;
	}

	return ERROR_OK;
}