drivers/media/test-drivers/vivid/vivid-vbi-out.c

Source file repositories/reference/linux-study-clean/drivers/media/test-drivers/vivid/vivid-vbi-out.c

File Facts

System
Linux kernel
Corpus path
drivers/media/test-drivers/vivid/vivid-vbi-out.c
Extension
.c
Size
6947 bytes
Lines
248
Domain
Driver Families
Bucket
drivers/media
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

list_for_each_entry_safe(buf, tmp, &dev->vbi_out_active, list) {
			list_del(&buf->list);
			vb2_buffer_done(&buf->vb.vb2_buf,
					VB2_BUF_STATE_QUEUED);
		}
	}
	return err;
}

/* abort streaming and wait for last buffer */
static void vbi_out_stop_streaming(struct vb2_queue *vq)
{
	struct vivid_dev *dev = vb2_get_drv_priv(vq);

	dprintk(dev, 1, "%s\n", __func__);
	vivid_stop_generating_vid_out(dev, &dev->vbi_out_streaming);
	dev->vbi_out_have_wss = false;
	dev->vbi_out_have_cc[0] = false;
	dev->vbi_out_have_cc[1] = false;
}

static void vbi_out_buf_request_complete(struct vb2_buffer *vb)
{
	struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);

	v4l2_ctrl_request_complete(vb->req_obj.req, &dev->ctrl_hdl_vbi_out);
}

const struct vb2_ops vivid_vbi_out_qops = {
	.queue_setup		= vbi_out_queue_setup,
	.buf_prepare		= vbi_out_buf_prepare,
	.buf_queue		= vbi_out_buf_queue,
	.start_streaming	= vbi_out_start_streaming,
	.stop_streaming		= vbi_out_stop_streaming,
	.buf_request_complete	= vbi_out_buf_request_complete,
};

int vidioc_g_fmt_vbi_out(struct file *file, void *priv,
					struct v4l2_format *f)
{
	struct vivid_dev *dev = video_drvdata(file);
	struct v4l2_vbi_format *vbi = &f->fmt.vbi;
	bool is_60hz = dev->std_out & V4L2_STD_525_60;

	if (!vivid_is_svid_out(dev) || !dev->has_raw_vbi_out)
		return -EINVAL;

	vbi->sampling_rate = 25000000;
	vbi->offset = 24;
	vbi->samples_per_line = 1440;
	vbi->sample_format = V4L2_PIX_FMT_GREY;
	vbi->start[0] = is_60hz ? V4L2_VBI_ITU_525_F1_START + 9 : V4L2_VBI_ITU_625_F1_START + 5;
	vbi->start[1] = is_60hz ? V4L2_VBI_ITU_525_F2_START + 9 : V4L2_VBI_ITU_625_F2_START + 5;
	vbi->count[0] = vbi->count[1] = is_60hz ? 12 : 18;
	vbi->flags = dev->vbi_cap_interlaced ? V4L2_VBI_INTERLACED : 0;
	vbi->reserved[0] = 0;
	vbi->reserved[1] = 0;
	return 0;
}

int vidioc_s_fmt_vbi_out(struct file *file, void *priv,
					struct v4l2_format *f)
{
	struct vivid_dev *dev = video_drvdata(file);
	int ret = vidioc_g_fmt_vbi_out(file, priv, f);

	if (ret)
		return ret;
	if (vb2_is_busy(&dev->vb_vbi_out_q))
		return -EBUSY;
	dev->stream_sliced_vbi_out = false;
	dev->vbi_out_dev.queue->type = V4L2_BUF_TYPE_VBI_OUTPUT;
	return 0;
}

int vidioc_g_fmt_sliced_vbi_out(struct file *file, void *priv, struct v4l2_format *fmt)
{
	struct vivid_dev *dev = video_drvdata(file);
	struct v4l2_sliced_vbi_format *vbi = &fmt->fmt.sliced;

	if (!vivid_is_svid_out(dev) || !dev->has_sliced_vbi_out)
		return -EINVAL;

	vivid_fill_service_lines(vbi, dev->service_set_out);
	return 0;
}

int vidioc_try_fmt_sliced_vbi_out(struct file *file, void *priv, struct v4l2_format *fmt)
{
	struct vivid_dev *dev = video_drvdata(file);

Annotation

Implementation Notes