int solo_v4l2_init(struct solo6010_dev *solo_dev)
{
	int ret;
	int i;

	init_waitqueue_head(&solo_dev->disp_thread_wait);

	solo_dev->vfd = video_device_alloc();
	if (!solo_dev->vfd)
		return -ENOMEM;

	*solo_dev->vfd = solo_v4l2_template;
	solo_dev->vfd->parent = &solo_dev->pdev->dev;

	ret = video_register_device(solo_dev->vfd, VFL_TYPE_GRABBER, video_nr);
	if (ret < 0) {
		video_device_release(solo_dev->vfd);
		solo_dev->vfd = NULL;
		return ret;
	}

	video_set_drvdata(solo_dev->vfd, solo_dev);

	snprintf(solo_dev->vfd->name, sizeof(solo_dev->vfd->name), "%s (%i)",
		 SOLO6010_NAME, solo_dev->vfd->num);

	if (video_nr != -1)
		video_nr++;

	dev_info(&solo_dev->pdev->dev, "Display as /dev/video%d with "
		 "%d inputs (%d extended)\n", solo_dev->vfd->num,
		 solo_dev->nr_chans, solo_dev->nr_ext);

	/* Cycle all the channels and clear */
	for (i = 0; i < solo_dev->nr_chans; i++) {
		solo_v4l2_set_ch(solo_dev, i);
		while (erase_off(solo_dev))
			;// Do nothing
	}

	/* Set the default display channel */
	solo_v4l2_set_ch(solo_dev, 0);
	while (erase_off(solo_dev))
		;// Do nothing

	solo6010_irq_on(solo_dev, SOLO_IRQ_VIDEO_IN);

	return 0;
}
Beispiel #2
0
static int solo_set_input(struct file *file, void *priv, unsigned int index)
{
	struct solo_filehandle *fh = priv;
	int ret = solo_v4l2_set_ch(fh->solo_dev, index);

	if (!ret) {
		while (erase_off(fh->solo_dev))
			/* Do nothing */;
	}

	return ret;
}
Beispiel #3
0
static int solo_set_input(struct file *file, void *priv, unsigned int index)
{
	struct solo_dev *solo_dev = video_drvdata(file);
	int ret = solo_v4l2_set_ch(solo_dev, index);

	if (!ret) {
		while (erase_off(solo_dev))
			/* Do nothing */;
	}

	return ret;
}
Beispiel #4
0
int solo_set_video_type(struct solo_dev *solo_dev, bool is_50hz)
{
	int i;

	/* Make sure all video nodes are idle */
	if (vb2_is_busy(&solo_dev->vidq))
		return -EBUSY;
	for (i = 0; i < solo_dev->nr_chans; i++)
		if (vb2_is_busy(&solo_dev->v4l2_enc[i]->vidq))
			return -EBUSY;
	solo_dev->video_type = is_50hz ? SOLO_VO_FMT_TYPE_PAL :
					 SOLO_VO_FMT_TYPE_NTSC;
	/* Reconfigure for the new standard */
	solo_disp_init(solo_dev);
	solo_enc_init(solo_dev);
	solo_tw28_init(solo_dev);
	for (i = 0; i < solo_dev->nr_chans; i++)
		solo_update_mode(solo_dev->v4l2_enc[i]);
	return solo_v4l2_set_ch(solo_dev, solo_dev->cur_disp_ch);
}
static int solo_set_input(struct file *file, void *priv, unsigned int index)
{
	struct solo_filehandle *fh = priv;

	return solo_v4l2_set_ch(fh->solo_dev, index);
}
Beispiel #6
0
int solo_v4l2_init(struct solo_dev *solo_dev, unsigned nr)
{
	int ret;
	int i;

	init_waitqueue_head(&solo_dev->disp_thread_wait);
	spin_lock_init(&solo_dev->slock);
	mutex_init(&solo_dev->lock);
	INIT_LIST_HEAD(&solo_dev->vidq_active);

	solo_dev->vfd = video_device_alloc();
	if (!solo_dev->vfd)
		return -ENOMEM;

	*solo_dev->vfd = solo_v4l2_template;
	solo_dev->vfd->v4l2_dev = &solo_dev->v4l2_dev;
	solo_dev->vfd->queue = &solo_dev->vidq;
	solo_dev->vfd->lock = &solo_dev->lock;
	v4l2_ctrl_handler_init(&solo_dev->disp_hdl, 1);
	v4l2_ctrl_new_custom(&solo_dev->disp_hdl, &solo_motion_trace_ctrl, NULL);
	if (solo_dev->disp_hdl.error) {
		ret = solo_dev->disp_hdl.error;
		goto fail;
	}
	solo_dev->vfd->ctrl_handler = &solo_dev->disp_hdl;

	video_set_drvdata(solo_dev->vfd, solo_dev);

	solo_dev->vidq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	solo_dev->vidq.io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ;
	solo_dev->vidq.ops = &solo_video_qops;
	solo_dev->vidq.mem_ops = &vb2_dma_contig_memops;
	solo_dev->vidq.drv_priv = solo_dev;
	solo_dev->vidq.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
	solo_dev->vidq.gfp_flags = __GFP_DMA32;
	solo_dev->vidq.buf_struct_size = sizeof(struct solo_vb2_buf);
	solo_dev->vidq.lock = &solo_dev->lock;
	ret = vb2_queue_init(&solo_dev->vidq);
	if (ret < 0)
		goto fail;

	solo_dev->alloc_ctx = vb2_dma_contig_init_ctx(&solo_dev->pdev->dev);
	if (IS_ERR(solo_dev->alloc_ctx)) {
		dev_err(&solo_dev->pdev->dev, "Can't allocate buffer context");
		return PTR_ERR(solo_dev->alloc_ctx);
	}

	/* Cycle all the channels and clear */
	for (i = 0; i < solo_dev->nr_chans; i++) {
		solo_v4l2_set_ch(solo_dev, i);
		while (erase_off(solo_dev))
			/* Do nothing */;
	}

	/* Set the default display channel */
	solo_v4l2_set_ch(solo_dev, 0);
	while (erase_off(solo_dev))
		/* Do nothing */;

	ret = video_register_device(solo_dev->vfd, VFL_TYPE_GRABBER, nr);
	if (ret < 0)
		goto fail;

	snprintf(solo_dev->vfd->name, sizeof(solo_dev->vfd->name), "%s (%i)",
		 SOLO6X10_NAME, solo_dev->vfd->num);

	dev_info(&solo_dev->pdev->dev, "Display as /dev/video%d with "
		 "%d inputs (%d extended)\n", solo_dev->vfd->num,
		 solo_dev->nr_chans, solo_dev->nr_ext);

	return 0;

fail:
	video_device_release(solo_dev->vfd);
	vb2_dma_contig_cleanup_ctx(solo_dev->alloc_ctx);
	v4l2_ctrl_handler_free(&solo_dev->disp_hdl);
	solo_dev->vfd = NULL;
	return ret;
}