Exemplo n.º 1
0
/* Probe the I2C bus and initialise the sensor chip */
int stk_sensor_init(struct stk_camera *dev)
{
	u8 idl = 0;
	u8 idh = 0;

	if (stk_camera_write_reg(dev, STK_IIC_ENABLE, STK_IIC_ENABLE_YES)
		|| stk_camera_write_reg(dev, STK_IIC_ADDR, SENSOR_ADDRESS)
		|| stk_sensor_outb(dev, REG_COM7, COM7_RESET)) {
		STK_ERROR("Sensor resetting failed\n");
		return -ENODEV;
	}
	msleep(10);
	/* Read the manufacturer ID: ov = 0x7FA2 */
	if (stk_sensor_inb(dev, REG_MIDH, &idh)
	    || stk_sensor_inb(dev, REG_MIDL, &idl)) {
		STK_ERROR("Strange error reading sensor ID\n");
		return -ENODEV;
	}
	if (idh != 0x7f || idl != 0xa2) {
		STK_ERROR("Huh? you don't have a sensor from ovt\n");
		return -ENODEV;
	}
	if (stk_sensor_inb(dev, REG_PID, &idh)
	    || stk_sensor_inb(dev, REG_VER, &idl)) {
		STK_ERROR("Could not read sensor model\n");
		return -ENODEV;
	}
	stk_sensor_write_regvals(dev, ov_initvals);
	msleep(10);
	STK_INFO("OmniVision sensor detected, id %02X%02X"
		" at address %x\n", idh, idl, SENSOR_ADDRESS);
	return 0;
}
Exemplo n.º 2
0
static int stk_sensor_inb(struct stk_camera *dev, u8 reg, u8 *val)
{
	int i = 0;
	int tmpval = 0;

	if (stk_camera_write_reg(dev, STK_IIC_RX_INDEX, reg))
		return 1;
	if (stk_camera_write_reg(dev, STK_IIC_OP, STK_IIC_OP_RX))
		return 1;
	do {
		if (stk_camera_read_reg(dev, STK_IIC_STAT, &tmpval))
			return 1;
		i++;
	} while (tmpval == 0 && i < MAX_RETRIES);
	if (tmpval != STK_IIC_STAT_RX_OK) {
		if (tmpval)
			STK_ERROR("stk_sensor_inb failed, status=0x%02x\n",
				tmpval);
		return 1;
	}

	if (stk_camera_read_reg(dev, STK_IIC_RX_VALUE, &tmpval))
		return 1;

	*val = (u8) tmpval;
	return 0;
}
Exemplo n.º 3
0
static int stk_start_stream(struct stk_camera *dev)
{
	int value;
	int i, ret;
	int value_116, value_117;

	if (!is_present(dev))
		return -ENODEV;
	if (!is_memallocd(dev) || !is_initialised(dev)) {
		STK_ERROR("FIXME: Buffers are not allocated\n");
		return -EFAULT;
	}
	ret = usb_set_interface(dev->udev, 0, 5);

	if (ret < 0)
		STK_ERROR("usb_set_interface failed !\n");
	if (stk_sensor_wakeup(dev))
		STK_ERROR("error awaking the sensor\n");

	stk_camera_read_reg(dev, 0x0116, &value_116);
	stk_camera_read_reg(dev, 0x0117, &value_117);

	stk_camera_write_reg(dev, 0x0116, 0x0000);
	stk_camera_write_reg(dev, 0x0117, 0x0000);

	stk_camera_read_reg(dev, 0x0100, &value);
	stk_camera_write_reg(dev, 0x0100, value | 0x80);

	stk_camera_write_reg(dev, 0x0116, value_116);
	stk_camera_write_reg(dev, 0x0117, value_117);
	for (i = 0; i < MAX_ISO_BUFS; i++) {
		if (dev->isobufs[i].urb) {
			ret = usb_submit_urb(dev->isobufs[i].urb, GFP_KERNEL);
			atomic_inc(&dev->urbs_used);
			if (ret)
				return ret;
		}
	}
	set_streaming(dev);
	return 0;
}
Exemplo n.º 4
0
static int stk_stop_stream(struct stk_camera *dev)
{
	int value;
	int i;
	if (is_present(dev)) {
		stk_camera_read_reg(dev, 0x0100, &value);
		stk_camera_write_reg(dev, 0x0100, value & ~0x80);
		if (dev->isobufs != NULL) {
			for (i = 0; i < MAX_ISO_BUFS; i++) {
				if (dev->isobufs[i].urb)
					usb_kill_urb(dev->isobufs[i].urb);
			}
		}
		unset_streaming(dev);

		if (usb_set_interface(dev->udev, 0, 0))
			STK_ERROR("usb_set_interface failed !\n");
		if (stk_sensor_sleep(dev))
			STK_ERROR("error suspending the sensor\n");
	}
	return 0;
}
Exemplo n.º 5
0
/*
 * This function is called as an URB transfert is complete (Isochronous pipe).
 * So, the traitement is done in interrupt time, so it has be fast, not crash,
 * and not stall. Neat.
 */
static void stk_isoc_handler(struct urb *urb)
{
	int i;
	int ret;
	int framelen;
	unsigned long flags;

	unsigned char *fill = NULL;
	unsigned char *iso_buf = NULL;

	struct stk_camera *dev;
	struct stk_sio_buffer *fb;

	dev = (struct stk_camera *) urb->context;

	if (dev == NULL) {
		STK_ERROR("isoc_handler called with NULL device !\n");
		return;
	}

	if (urb->status == -ENOENT || urb->status == -ECONNRESET
		|| urb->status == -ESHUTDOWN) {
		atomic_dec(&dev->urbs_used);
		return;
	}

	spin_lock_irqsave(&dev->spinlock, flags);

	if (urb->status != -EINPROGRESS && urb->status != 0) {
		STK_ERROR("isoc_handler: urb->status == %d\n", urb->status);
		goto resubmit;
	}

	if (list_empty(&dev->sio_avail)) {
		/*FIXME Stop streaming after a while */
		(void) (printk_ratelimit() &&
		STK_ERROR("isoc_handler without available buffer!\n"));
		goto resubmit;
	}
	fb = list_first_entry(&dev->sio_avail,
			struct stk_sio_buffer, list);
	fill = fb->buffer + fb->v4lbuf.bytesused;

	for (i = 0; i < urb->number_of_packets; i++) {
		if (urb->iso_frame_desc[i].status != 0) {
			if (urb->iso_frame_desc[i].status != -EXDEV)
				STK_ERROR("Frame %d has error %d\n", i,
					urb->iso_frame_desc[i].status);
			continue;
		}
		framelen = urb->iso_frame_desc[i].actual_length;
		iso_buf = urb->transfer_buffer + urb->iso_frame_desc[i].offset;

		if (framelen <= 4)
			continue; /* no data */

		/*
		 * we found something informational from there
		 * the isoc frames have to type of headers
		 * type1: 00 xx 00 00 or 20 xx 00 00
		 * type2: 80 xx 00 00 00 00 00 00 or a0 xx 00 00 00 00 00 00
		 * xx is a sequencer which has never been seen over 0x3f
		 * imho data written down looks like bayer, i see similarities
		 * after every 640 bytes
		 */
		if (*iso_buf & 0x80) {
			framelen -= 8;
			iso_buf += 8;
			/* This marks a new frame */
			if (fb->v4lbuf.bytesused != 0
				&& fb->v4lbuf.bytesused != dev->frame_size) {
				(void) (printk_ratelimit() &&
				STK_ERROR("frame %d, "
					"bytesused=%d, skipping\n",
					i, fb->v4lbuf.bytesused));
				fb->v4lbuf.bytesused = 0;
				fill = fb->buffer;
			} else if (fb->v4lbuf.bytesused == dev->frame_size) {
				if (list_is_singular(&dev->sio_avail)) {
					/* Always reuse the last buffer */
					fb->v4lbuf.bytesused = 0;
					fill = fb->buffer;
				} else {
					list_move_tail(dev->sio_avail.next,
						&dev->sio_full);
					wake_up(&dev->wait_frame);
					fb = list_first_entry(&dev->sio_avail,
						struct stk_sio_buffer, list);
					fb->v4lbuf.bytesused = 0;
					fill = fb->buffer;
				}
			}
		} else {
Exemplo n.º 6
0
int stk_sensor_configure(struct stk_camera *dev)
{
	int com7;
	/*
	 * We setup the sensor to output dummy lines in low-res modes,
	 * so we don't get absurdly hight framerates.
	 */
	unsigned dummylines;
	int flip;
	struct regval *rv;

	switch (dev->vsettings.mode) {
	case MODE_QCIF: com7 = COM7_FMT_QCIF;
		dummylines = 604;
		break;
	case MODE_QVGA: com7 = COM7_FMT_QVGA;
		dummylines = 267;
		break;
	case MODE_CIF: com7 = COM7_FMT_CIF;
		dummylines = 412;
		break;
	case MODE_VGA: com7 = COM7_FMT_VGA;
		dummylines = 11;
		break;
	case MODE_SXGA: com7 = COM7_FMT_SXGA;
		dummylines = 0;
		break;
	default: STK_ERROR("Unsupported mode %d\n", dev->vsettings.mode);
		return -EFAULT;
	}
	switch (dev->vsettings.palette) {
	case V4L2_PIX_FMT_UYVY:
		com7 |= COM7_YUV;
		rv = ov_fmt_uyvy;
		break;
	case V4L2_PIX_FMT_YUYV:
		com7 |= COM7_YUV;
		rv = ov_fmt_yuyv;
		break;
	case V4L2_PIX_FMT_RGB565:
		com7 |= COM7_RGB;
		rv = ov_fmt_rgbp;
		break;
	case V4L2_PIX_FMT_RGB565X:
		com7 |= COM7_RGB;
		rv = ov_fmt_rgbr;
		break;
	case V4L2_PIX_FMT_SBGGR8:
		com7 |= COM7_PBAYER;
		rv = ov_fmt_bayer;
		break;
	default: STK_ERROR("Unsupported colorspace\n");
		return -EFAULT;
	}
	/*FIXME sometimes the sensor go to a bad state
	stk_sensor_write_regvals(dev, ov_initvals); */
	stk_sensor_outb(dev, REG_COM7, com7);
	msleep(50);
	stk_sensor_write_regvals(dev, rv);
	flip = (dev->vsettings.vflip?MVFP_FLIP:0)
		| (dev->vsettings.hflip?MVFP_MIRROR:0);
	stk_sensor_outb(dev, REG_MVFP, flip);
	if (dev->vsettings.palette == V4L2_PIX_FMT_SBGGR8
			&& !dev->vsettings.vflip)
		stk_sensor_outb(dev, REG_TSLB, 0x08);
	stk_sensor_outb(dev, REG_ADVFH, dummylines >> 8);
	stk_sensor_outb(dev, REG_ADVFL, dummylines & 0xff);
	msleep(50);
	switch (dev->vsettings.mode) {
	case MODE_VGA:
		if (stk_sensor_set_hw(dev, 302, 1582, 6, 486))
			STK_ERROR("stk_sensor_set_hw failed (VGA)\n");
		break;
	case MODE_SXGA:
	case MODE_CIF:
	case MODE_QVGA:
	case MODE_QCIF:
		/*FIXME These settings seem ignored by the sensor
		if (stk_sensor_set_hw(dev, 220, 1500, 10, 1034))
			STK_ERROR("stk_sensor_set_hw failed (SXGA)\n");
		*/
		break;
	}
	msleep(10);
	return 0;
}
Exemplo n.º 7
0
int stk_sensor_configure(struct stk_camera *dev)
{
	int com7;
	
	unsigned dummylines;
	int flip;
	struct regval *rv;

	switch (dev->vsettings.mode) {
	case MODE_QCIF: com7 = COM7_FMT_QCIF;
		dummylines = 604;
		break;
	case MODE_QVGA: com7 = COM7_FMT_QVGA;
		dummylines = 267;
		break;
	case MODE_CIF: com7 = COM7_FMT_CIF;
		dummylines = 412;
		break;
	case MODE_VGA: com7 = COM7_FMT_VGA;
		dummylines = 11;
		break;
	case MODE_SXGA: com7 = COM7_FMT_SXGA;
		dummylines = 0;
		break;
	default: STK_ERROR("Unsupported mode %d\n", dev->vsettings.mode);
		return -EFAULT;
	}
	switch (dev->vsettings.palette) {
	case V4L2_PIX_FMT_UYVY:
		com7 |= COM7_YUV;
		rv = ov_fmt_uyvy;
		break;
	case V4L2_PIX_FMT_YUYV:
		com7 |= COM7_YUV;
		rv = ov_fmt_yuyv;
		break;
	case V4L2_PIX_FMT_RGB565:
		com7 |= COM7_RGB;
		rv = ov_fmt_rgbp;
		break;
	case V4L2_PIX_FMT_RGB565X:
		com7 |= COM7_RGB;
		rv = ov_fmt_rgbr;
		break;
	case V4L2_PIX_FMT_SBGGR8:
		com7 |= COM7_PBAYER;
		rv = ov_fmt_bayer;
		break;
	default: STK_ERROR("Unsupported colorspace\n");
		return -EFAULT;
	}
	
	stk_sensor_outb(dev, REG_COM7, com7);
	msleep(50);
	stk_sensor_write_regvals(dev, rv);
	flip = (dev->vsettings.vflip?MVFP_FLIP:0)
		| (dev->vsettings.hflip?MVFP_MIRROR:0);
	stk_sensor_outb(dev, REG_MVFP, flip);
	if (dev->vsettings.palette == V4L2_PIX_FMT_SBGGR8
			&& !dev->vsettings.vflip)
		stk_sensor_outb(dev, REG_TSLB, 0x08);
	stk_sensor_outb(dev, REG_ADVFH, dummylines >> 8);
	stk_sensor_outb(dev, REG_ADVFL, dummylines & 0xff);
	msleep(50);
	switch (dev->vsettings.mode) {
	case MODE_VGA:
		if (stk_sensor_set_hw(dev, 302, 1582, 6, 486))
			STK_ERROR("stk_sensor_set_hw failed (VGA)\n");
		break;
	case MODE_SXGA:
	case MODE_CIF:
	case MODE_QVGA:
	case MODE_QCIF:
		
		break;
	}
	msleep(10);
	return 0;
}