^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * vivid-vbi-out.c - vbi output support functions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/videodev2.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <media/v4l2-common.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include "vivid-core.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "vivid-kthread-out.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "vivid-vbi-out.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "vivid-vbi-cap.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) static int vbi_out_queue_setup(struct vb2_queue *vq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) unsigned *nbuffers, unsigned *nplanes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) unsigned sizes[], struct device *alloc_devs[])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) struct vivid_dev *dev = vb2_get_drv_priv(vq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) bool is_60hz = dev->std_out & V4L2_STD_525_60;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) unsigned size = vq->type == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) 36 * sizeof(struct v4l2_sliced_vbi_data) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) 1440 * 2 * (is_60hz ? 12 : 18);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) if (!vivid_is_svid_out(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) sizes[0] = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) if (vq->num_buffers + *nbuffers < 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) *nbuffers = 2 - vq->num_buffers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) *nplanes = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) static int vbi_out_buf_prepare(struct vb2_buffer *vb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) bool is_60hz = dev->std_out & V4L2_STD_525_60;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) unsigned size = vb->vb2_queue->type == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) 36 * sizeof(struct v4l2_sliced_vbi_data) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) 1440 * 2 * (is_60hz ? 12 : 18);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) dprintk(dev, 1, "%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) if (dev->buf_prepare_error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * Error injection: test what happens if buf_prepare() returns
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * an error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) dev->buf_prepare_error = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) if (vb2_plane_size(vb, 0) < size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) dprintk(dev, 1, "%s data will not fit into plane (%lu < %u)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) __func__, vb2_plane_size(vb, 0), size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) vb2_set_plane_payload(vb, 0, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) static void vbi_out_buf_queue(struct vb2_buffer *vb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) struct vivid_buffer *buf = container_of(vbuf, struct vivid_buffer, vb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) dprintk(dev, 1, "%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) spin_lock(&dev->slock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) list_add_tail(&buf->list, &dev->vbi_out_active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) spin_unlock(&dev->slock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) static int vbi_out_start_streaming(struct vb2_queue *vq, unsigned count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) struct vivid_dev *dev = vb2_get_drv_priv(vq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) dprintk(dev, 1, "%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) dev->vbi_out_seq_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) if (dev->start_streaming_error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) dev->start_streaming_error = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) err = vivid_start_generating_vid_out(dev, &dev->vbi_out_streaming);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) struct vivid_buffer *buf, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) list_for_each_entry_safe(buf, tmp, &dev->vbi_out_active, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) list_del(&buf->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) vb2_buffer_done(&buf->vb.vb2_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) VB2_BUF_STATE_QUEUED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) /* abort streaming and wait for last buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) static void vbi_out_stop_streaming(struct vb2_queue *vq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) struct vivid_dev *dev = vb2_get_drv_priv(vq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) dprintk(dev, 1, "%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) vivid_stop_generating_vid_out(dev, &dev->vbi_out_streaming);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) dev->vbi_out_have_wss = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) dev->vbi_out_have_cc[0] = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) dev->vbi_out_have_cc[1] = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) static void vbi_out_buf_request_complete(struct vb2_buffer *vb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) v4l2_ctrl_request_complete(vb->req_obj.req, &dev->ctrl_hdl_vbi_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) const struct vb2_ops vivid_vbi_out_qops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) .queue_setup = vbi_out_queue_setup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) .buf_prepare = vbi_out_buf_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) .buf_queue = vbi_out_buf_queue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) .start_streaming = vbi_out_start_streaming,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) .stop_streaming = vbi_out_stop_streaming,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) .buf_request_complete = vbi_out_buf_request_complete,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) .wait_prepare = vb2_ops_wait_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) .wait_finish = vb2_ops_wait_finish,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) int vidioc_g_fmt_vbi_out(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) struct v4l2_format *f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) struct vivid_dev *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) struct v4l2_vbi_format *vbi = &f->fmt.vbi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) bool is_60hz = dev->std_out & V4L2_STD_525_60;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) if (!vivid_is_svid_out(dev) || !dev->has_raw_vbi_out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) vbi->sampling_rate = 25000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) vbi->offset = 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) vbi->samples_per_line = 1440;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) vbi->sample_format = V4L2_PIX_FMT_GREY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) vbi->start[0] = is_60hz ? V4L2_VBI_ITU_525_F1_START + 9 : V4L2_VBI_ITU_625_F1_START + 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) vbi->start[1] = is_60hz ? V4L2_VBI_ITU_525_F2_START + 9 : V4L2_VBI_ITU_625_F2_START + 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) vbi->count[0] = vbi->count[1] = is_60hz ? 12 : 18;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) vbi->flags = dev->vbi_cap_interlaced ? V4L2_VBI_INTERLACED : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) vbi->reserved[0] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) vbi->reserved[1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) int vidioc_s_fmt_vbi_out(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) struct v4l2_format *f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) struct vivid_dev *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) int ret = vidioc_g_fmt_vbi_out(file, priv, f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) if (vb2_is_busy(&dev->vb_vbi_out_q))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) dev->stream_sliced_vbi_out = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) dev->vbi_out_dev.queue->type = V4L2_BUF_TYPE_VBI_OUTPUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) int vidioc_g_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) struct vivid_dev *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) struct v4l2_sliced_vbi_format *vbi = &fmt->fmt.sliced;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) if (!vivid_is_svid_out(dev) || !dev->has_sliced_vbi_out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) vivid_fill_service_lines(vbi, dev->service_set_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) int vidioc_try_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) struct vivid_dev *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) struct v4l2_sliced_vbi_format *vbi = &fmt->fmt.sliced;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) bool is_60hz = dev->std_out & V4L2_STD_525_60;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) u32 service_set = vbi->service_set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) if (!vivid_is_svid_out(dev) || !dev->has_sliced_vbi_out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) service_set &= is_60hz ? V4L2_SLICED_CAPTION_525 :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) V4L2_SLICED_WSS_625 | V4L2_SLICED_TELETEXT_B;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) vivid_fill_service_lines(vbi, service_set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) int vidioc_s_fmt_sliced_vbi_out(struct file *file, void *fh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) struct v4l2_format *fmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) struct vivid_dev *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) struct v4l2_sliced_vbi_format *vbi = &fmt->fmt.sliced;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) int ret = vidioc_try_fmt_sliced_vbi_out(file, fh, fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) if (vb2_is_busy(&dev->vb_vbi_out_q))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) dev->service_set_out = vbi->service_set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) dev->stream_sliced_vbi_out = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) dev->vbi_out_dev.queue->type = V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) void vivid_sliced_vbi_out_process(struct vivid_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) struct vivid_buffer *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) struct v4l2_sliced_vbi_data *vbi =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) vb2_plane_vaddr(&buf->vb.vb2_buf, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) unsigned elems =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) vb2_get_plane_payload(&buf->vb.vb2_buf, 0) / sizeof(*vbi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) dev->vbi_out_have_cc[0] = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) dev->vbi_out_have_cc[1] = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) dev->vbi_out_have_wss = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) while (elems--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) switch (vbi->id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) case V4L2_SLICED_CAPTION_525:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) if ((dev->std_out & V4L2_STD_525_60) && vbi->line == 21) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) dev->vbi_out_have_cc[!!vbi->field] = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) dev->vbi_out_cc[!!vbi->field][0] = vbi->data[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) dev->vbi_out_cc[!!vbi->field][1] = vbi->data[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) case V4L2_SLICED_WSS_625:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) if ((dev->std_out & V4L2_STD_625_50) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) vbi->field == 0 && vbi->line == 23) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) dev->vbi_out_have_wss = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) dev->vbi_out_wss[0] = vbi->data[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) dev->vbi_out_wss[1] = vbi->data[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) vbi++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) }