Пример #1
0
/* Must be called with both v4l_lock and vb_queue_lock hold */
void stk1160_clear_queue(struct stk1160 *dev)
{
	struct stk1160_buffer *buf;
	unsigned long flags;

	/* Release all active buffers */
	spin_lock_irqsave(&dev->buf_lock, flags);
	while (!list_empty(&dev->avail_bufs)) {
		buf = list_first_entry(&dev->avail_bufs,
			struct stk1160_buffer, list);
		list_del(&buf->list);
		vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
		stk1160_info("buffer [%p/%d] aborted\n",
				buf, buf->vb.v4l2_buf.index);
	}

	/* It's important to release the current buffer */
	if (dev->isoc_ctl.buf) {
		buf = dev->isoc_ctl.buf;
		dev->isoc_ctl.buf = NULL;

		vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
		stk1160_info("buffer [%p/%d] aborted\n",
				buf, buf->vb.v4l2_buf.index);
	}
	spin_unlock_irqrestore(&dev->buf_lock, flags);
}
Пример #2
0
/*
 * Videobuf2 operations
 */
static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *v4l_fmt,
				unsigned int *nbuffers, unsigned int *nplanes,
				unsigned int sizes[], void *alloc_ctxs[])
{
	struct stk1160 *dev = vb2_get_drv_priv(vq);
	unsigned long size;

	size = dev->width * dev->height * 2;

	/*
	 * Here we can change the number of buffers being requested.
	 * So, we set a minimum and a maximum like this:
	 */
	*nbuffers = clamp_t(unsigned int, *nbuffers,
			STK1160_MIN_VIDEO_BUFFERS, STK1160_MAX_VIDEO_BUFFERS);

	/* This means a packed colorformat */
	*nplanes = 1;

	sizes[0] = size;

	stk1160_info("%s: buffer count %d, each %ld bytes\n",
			__func__, *nbuffers, size);

	return 0;
}
Пример #3
0
/* Must be called with v4l_lock hold */
static void stk1160_stop_hw(struct stk1160 *dev)
{
	/* If the device is not physically present, there is nothing to do */
	if (!dev->udev)
		return;

	/* set alternate 0 */
	dev->alt = 0;
	stk1160_info("setting alternate %d\n", dev->alt);
	usb_set_interface(dev->udev, 0, 0);

	/* Stop stk1160 */
	stk1160_write_reg(dev, STK1160_DCTRL, 0x00);
	stk1160_write_reg(dev, STK1160_DCTRL+3, 0x00);

	/* Stop saa711x */
	v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 0);
}
Пример #4
0
/*
 * Set a new alternate setting.
 * Returns true is dev->max_pkt_size has changed, false otherwise.
 */
static bool stk1160_set_alternate(struct stk1160 *dev)
{
	int i, prev_alt = dev->alt;
	unsigned int min_pkt_size;
	bool new_pkt_size;

	/*
	 * If we don't set right alternate,
	 * then we will get a green screen with junk.
	 */
	min_pkt_size = STK1160_MIN_PKT_SIZE;

	for (i = 0; i < dev->num_alt; i++) {
		/* stop when the selected alt setting offers enough bandwidth */
		if (dev->alt_max_pkt_size[i] >= min_pkt_size) {
			dev->alt = i;
			break;
		/*
		 * otherwise make sure that we end up with the maximum bandwidth
		 * because the min_pkt_size equation might be wrong...
		 */
		} else if (dev->alt_max_pkt_size[i] >
			   dev->alt_max_pkt_size[dev->alt])
			dev->alt = i;
	}

	stk1160_info("setting alternate %d\n", dev->alt);

	if (dev->alt != prev_alt) {
		stk1160_dbg("minimum isoc packet size: %u (alt=%d)\n",
				min_pkt_size, dev->alt);
		stk1160_dbg("setting alt %d with wMaxPacketSize=%u\n",
			       dev->alt, dev->alt_max_pkt_size[dev->alt]);
		usb_set_interface(dev->udev, 0, dev->alt);
	}

	new_pkt_size = dev->max_pkt_size != dev->alt_max_pkt_size[dev->alt];
	dev->max_pkt_size = dev->alt_max_pkt_size[dev->alt];

	return new_pkt_size;
}