^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-cap.c - vbi capture 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-cap.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "vivid-vbi-cap.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "vivid-vbi-gen.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) static void vivid_sliced_vbi_cap_fill(struct vivid_dev *dev, unsigned seqnr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) struct vivid_vbi_gen_data *vbi_gen = &dev->vbi_gen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) bool is_60hz = dev->std_cap[dev->input] & V4L2_STD_525_60;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) vivid_vbi_gen_sliced(vbi_gen, is_60hz, seqnr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) if (!is_60hz) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) if (dev->loop_video) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) if (dev->vbi_out_have_wss) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) vbi_gen->data[12].data[0] = dev->vbi_out_wss[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) vbi_gen->data[12].data[1] = dev->vbi_out_wss[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) vbi_gen->data[12].id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) switch (tpg_g_video_aspect(&dev->tpg)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) case TPG_VIDEO_ASPECT_14X9_CENTRE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) vbi_gen->data[12].data[0] = 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) case TPG_VIDEO_ASPECT_16X9_CENTRE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) vbi_gen->data[12].data[0] = 0x0b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) case TPG_VIDEO_ASPECT_16X9_ANAMORPHIC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) vbi_gen->data[12].data[0] = 0x07;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) case TPG_VIDEO_ASPECT_4X3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) vbi_gen->data[12].data[0] = 0x08;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) } else if (dev->loop_video && is_60hz) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) if (dev->vbi_out_have_cc[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) vbi_gen->data[0].data[0] = dev->vbi_out_cc[0][0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) vbi_gen->data[0].data[1] = dev->vbi_out_cc[0][1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) vbi_gen->data[0].id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) if (dev->vbi_out_have_cc[1]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) vbi_gen->data[1].data[0] = dev->vbi_out_cc[1][0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) vbi_gen->data[1].data[1] = dev->vbi_out_cc[1][1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) vbi_gen->data[1].id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) static void vivid_g_fmt_vbi_cap(struct vivid_dev *dev, struct v4l2_vbi_format *vbi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) bool is_60hz = dev->std_cap[dev->input] & V4L2_STD_525_60;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) vbi->sampling_rate = 27000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) vbi->offset = 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) vbi->samples_per_line = 1440;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) vbi->sample_format = V4L2_PIX_FMT_GREY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) 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 75) 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 76) vbi->count[0] = vbi->count[1] = is_60hz ? 12 : 18;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) vbi->flags = dev->vbi_cap_interlaced ? V4L2_VBI_INTERLACED : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) vbi->reserved[0] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) vbi->reserved[1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) void vivid_raw_vbi_cap_process(struct vivid_dev *dev, struct vivid_buffer *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) struct v4l2_vbi_format vbi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) u8 *vbuf = vb2_plane_vaddr(&buf->vb.vb2_buf, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) vivid_g_fmt_vbi_cap(dev, &vbi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) buf->vb.sequence = dev->vbi_cap_seq_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) if (dev->field_cap == V4L2_FIELD_ALTERNATE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) buf->vb.sequence /= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) vivid_sliced_vbi_cap_fill(dev, buf->vb.sequence);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) memset(vbuf, 0x10, vb2_plane_size(&buf->vb.vb2_buf, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) if (!VIVID_INVALID_SIGNAL(dev->std_signal_mode[dev->input]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) vivid_vbi_gen_raw(&dev->vbi_gen, &vbi, vbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) void vivid_sliced_vbi_cap_process(struct vivid_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) struct vivid_buffer *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) struct v4l2_sliced_vbi_data *vbuf =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) vb2_plane_vaddr(&buf->vb.vb2_buf, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) buf->vb.sequence = dev->vbi_cap_seq_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) if (dev->field_cap == V4L2_FIELD_ALTERNATE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) buf->vb.sequence /= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) vivid_sliced_vbi_cap_fill(dev, buf->vb.sequence);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) memset(vbuf, 0, vb2_plane_size(&buf->vb.vb2_buf, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) if (!VIVID_INVALID_SIGNAL(dev->std_signal_mode[dev->input])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) unsigned i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) for (i = 0; i < 25; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) vbuf[i] = dev->vbi_gen.data[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) static int vbi_cap_queue_setup(struct vb2_queue *vq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) unsigned *nbuffers, unsigned *nplanes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) unsigned sizes[], struct device *alloc_devs[])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) struct vivid_dev *dev = vb2_get_drv_priv(vq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) bool is_60hz = dev->std_cap[dev->input] & V4L2_STD_525_60;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) unsigned size = vq->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 36 * sizeof(struct v4l2_sliced_vbi_data) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 1440 * 2 * (is_60hz ? 12 : 18);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) if (!vivid_is_sdtv_cap(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) sizes[0] = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) if (vq->num_buffers + *nbuffers < 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) *nbuffers = 2 - vq->num_buffers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) *nplanes = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) static int vbi_cap_buf_prepare(struct vb2_buffer *vb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) bool is_60hz = dev->std_cap[dev->input] & V4L2_STD_525_60;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) unsigned size = vb->vb2_queue->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 36 * sizeof(struct v4l2_sliced_vbi_data) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 1440 * 2 * (is_60hz ? 12 : 18);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) dprintk(dev, 1, "%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) if (dev->buf_prepare_error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) * Error injection: test what happens if buf_prepare() returns
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) * an error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) dev->buf_prepare_error = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) if (vb2_plane_size(vb, 0) < size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) dprintk(dev, 1, "%s data will not fit into plane (%lu < %u)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) __func__, vb2_plane_size(vb, 0), size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) vb2_set_plane_payload(vb, 0, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) static void vbi_cap_buf_queue(struct vb2_buffer *vb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) struct vivid_buffer *buf = container_of(vbuf, struct vivid_buffer, vb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) dprintk(dev, 1, "%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) spin_lock(&dev->slock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) list_add_tail(&buf->list, &dev->vbi_cap_active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) spin_unlock(&dev->slock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) static int vbi_cap_start_streaming(struct vb2_queue *vq, unsigned count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) struct vivid_dev *dev = vb2_get_drv_priv(vq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) dprintk(dev, 1, "%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) dev->vbi_cap_seq_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) if (dev->start_streaming_error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) dev->start_streaming_error = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) err = vivid_start_generating_vid_cap(dev, &dev->vbi_cap_streaming);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) struct vivid_buffer *buf, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) list_for_each_entry_safe(buf, tmp, &dev->vbi_cap_active, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) list_del(&buf->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) vb2_buffer_done(&buf->vb.vb2_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) VB2_BUF_STATE_QUEUED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) /* abort streaming and wait for last buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) static void vbi_cap_stop_streaming(struct vb2_queue *vq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) struct vivid_dev *dev = vb2_get_drv_priv(vq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) dprintk(dev, 1, "%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) vivid_stop_generating_vid_cap(dev, &dev->vbi_cap_streaming);
^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) static void vbi_cap_buf_request_complete(struct vb2_buffer *vb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) v4l2_ctrl_request_complete(vb->req_obj.req, &dev->ctrl_hdl_vbi_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) const struct vb2_ops vivid_vbi_cap_qops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) .queue_setup = vbi_cap_queue_setup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) .buf_prepare = vbi_cap_buf_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) .buf_queue = vbi_cap_buf_queue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) .start_streaming = vbi_cap_start_streaming,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) .stop_streaming = vbi_cap_stop_streaming,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) .buf_request_complete = vbi_cap_buf_request_complete,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) .wait_prepare = vb2_ops_wait_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) .wait_finish = vb2_ops_wait_finish,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) int vidioc_g_fmt_vbi_cap(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) struct v4l2_format *f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) struct vivid_dev *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) struct v4l2_vbi_format *vbi = &f->fmt.vbi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) if (!vivid_is_sdtv_cap(dev) || !dev->has_raw_vbi_cap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) vivid_g_fmt_vbi_cap(dev, vbi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) int vidioc_s_fmt_vbi_cap(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) struct v4l2_format *f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) struct vivid_dev *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) int ret = vidioc_g_fmt_vbi_cap(file, priv, f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) if (dev->stream_sliced_vbi_cap && vb2_is_busy(&dev->vb_vbi_cap_q))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) dev->stream_sliced_vbi_cap = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) dev->vbi_cap_dev.queue->type = V4L2_BUF_TYPE_VBI_CAPTURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) void vivid_fill_service_lines(struct v4l2_sliced_vbi_format *vbi, u32 service_set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) vbi->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) vbi->service_set = service_set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) memset(vbi->service_lines, 0, sizeof(vbi->service_lines));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) memset(vbi->reserved, 0, sizeof(vbi->reserved));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) if (vbi->service_set == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) if (vbi->service_set & V4L2_SLICED_CAPTION_525) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) vbi->service_lines[0][21] = V4L2_SLICED_CAPTION_525;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) vbi->service_lines[1][21] = V4L2_SLICED_CAPTION_525;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) if (vbi->service_set & V4L2_SLICED_WSS_625) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) unsigned i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) for (i = 7; i <= 18; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) vbi->service_lines[0][i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) vbi->service_lines[1][i] = V4L2_SLICED_TELETEXT_B;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) vbi->service_lines[0][23] = V4L2_SLICED_WSS_625;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) int vidioc_g_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) struct vivid_dev *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) struct v4l2_sliced_vbi_format *vbi = &fmt->fmt.sliced;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) if (!vivid_is_sdtv_cap(dev) || !dev->has_sliced_vbi_cap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) vivid_fill_service_lines(vbi, dev->service_set_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) int vidioc_try_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) struct vivid_dev *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) struct v4l2_sliced_vbi_format *vbi = &fmt->fmt.sliced;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) bool is_60hz = dev->std_cap[dev->input] & V4L2_STD_525_60;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) u32 service_set = vbi->service_set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) if (!vivid_is_sdtv_cap(dev) || !dev->has_sliced_vbi_cap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) service_set &= is_60hz ? V4L2_SLICED_CAPTION_525 :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) V4L2_SLICED_WSS_625 | V4L2_SLICED_TELETEXT_B;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) vivid_fill_service_lines(vbi, service_set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) int vidioc_s_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) struct vivid_dev *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) struct v4l2_sliced_vbi_format *vbi = &fmt->fmt.sliced;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) int ret = vidioc_try_fmt_sliced_vbi_cap(file, fh, fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) if (!dev->stream_sliced_vbi_cap && vb2_is_busy(&dev->vb_vbi_cap_q))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) dev->service_set_cap = vbi->service_set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) dev->stream_sliced_vbi_cap = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) dev->vbi_cap_dev.queue->type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) int vidioc_g_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_sliced_vbi_cap *cap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) struct vivid_dev *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) struct video_device *vdev = video_devdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) bool is_60hz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) if (vdev->vfl_dir == VFL_DIR_RX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) is_60hz = dev->std_cap[dev->input] & V4L2_STD_525_60;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) if (!vivid_is_sdtv_cap(dev) || !dev->has_sliced_vbi_cap ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) cap->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) is_60hz = dev->std_out & V4L2_STD_525_60;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) if (!vivid_is_svid_out(dev) || !dev->has_sliced_vbi_out ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) cap->type != V4L2_BUF_TYPE_SLICED_VBI_OUTPUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) cap->service_set = is_60hz ? V4L2_SLICED_CAPTION_525 :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) V4L2_SLICED_WSS_625 | V4L2_SLICED_TELETEXT_B;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) if (is_60hz) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) cap->service_lines[0][21] = V4L2_SLICED_CAPTION_525;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) cap->service_lines[1][21] = V4L2_SLICED_CAPTION_525;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) unsigned i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) for (i = 7; i <= 18; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) cap->service_lines[0][i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) cap->service_lines[1][i] = V4L2_SLICED_TELETEXT_B;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) cap->service_lines[0][23] = V4L2_SLICED_WSS_625;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) }