/*
 * vivid-vbi-cap.c - vbi capture support functions.
 *
 * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
 *
 * This program is free software; you may redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/videodev2.h>
#include <media/v4l2-common.h>

#include "vivid-core.h"
#include "vivid-kthread-cap.h"
#include "vivid-vbi-cap.h"
#include "vivid-vbi-gen.h"

static void vivid_sliced_vbi_cap_fill(struct vivid_dev *dev, unsigned seqnr)
{
	struct vivid_vbi_gen_data *vbi_gen = &dev->vbi_gen;
	bool is_60hz = dev->std_cap & V4L2_STD_525_60;

	vivid_vbi_gen_sliced(vbi_gen, is_60hz, seqnr);

	if (!is_60hz) {
		if (dev->loop_video) {
			if (dev->vbi_out_have_wss) {
				vbi_gen->data[12].data[0] = dev->vbi_out_wss[0];
				vbi_gen->data[12].data[1] = dev->vbi_out_wss[1];
			} else {
				vbi_gen->data[12].id = 0;
			}
		} else {
			switch (tpg_g_video_aspect(&dev->tpg)) {
			case TPG_VIDEO_ASPECT_14X9_CENTRE:
				vbi_gen->data[12].data[0] = 0x01;
				break;
			case TPG_VIDEO_ASPECT_16X9_CENTRE:
				vbi_gen->data[12].data[0] = 0x0b;
				break;
			case TPG_VIDEO_ASPECT_16X9_ANAMORPHIC:
				vbi_gen->data[12].data[0] = 0x07;
				break;
			case TPG_VIDEO_ASPECT_4X3:
			default:
				vbi_gen->data[12].data[0] = 0x08;
				break;
			}
		}
	} else if (dev->loop_video && is_60hz) {
		if (dev->vbi_out_have_cc[0]) {
			vbi_gen->data[0].data[0] = dev->vbi_out_cc[0][0];
			vbi_gen->data[0].data[1] = dev->vbi_out_cc[0][1];
		} else {
			vbi_gen->data[0].id = 0;
		}
		if (dev->vbi_out_have_cc[1]) {
			vbi_gen->data[1].data[0] = dev->vbi_out_cc[1][0];
			vbi_gen->data[1].data[1] = dev->vbi_out_cc[1][1];
		} else {
			vbi_gen->data[1].id = 0;
		}
	}
}

static void vivid_g_fmt_vbi_cap(struct vivid_dev *dev, struct v4l2_vbi_format *vbi)
{
	bool is_60hz = dev->std_cap & V4L2_STD_525_60;

	vbi->sampling_rate = 27000000;
	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;
}

void vivid_raw_vbi_cap_process(struct vivid_dev *dev, struct vivid_buffer *buf)
{
	struct v4l2_vbi_format vbi;
	u8 *vbuf = vb2_plane_vaddr(&buf->vb.vb2_buf, 0);

	vivid_g_fmt_vbi_cap(dev, &vbi);
	buf->vb.sequence = dev->vbi_cap_seq_count;
	if (dev->field_cap == V4L2_FIELD_ALTERNATE)
		buf->vb.sequence /= 2;

	vivid_sliced_vbi_cap_fill(dev, buf->vb.sequence);

	memset(vbuf, 0x10, vb2_plane_size(&buf->vb.vb2_buf, 0));

	if (!VIVID_INVALID_SIGNAL(dev->std_signal_mode))
		vivid_vbi_gen_raw(&dev->vbi_gen, &vbi, vbuf);

	buf->vb.vb2_buf.timestamp = ktime_get_ns() + dev->time_wrap_offset;
}


void vivid_sliced_vbi_cap_process(struct vivid_dev *dev,
			struct vivid_buffer *buf)
{
	struct v4l2_sliced_vbi_data *vbuf =
			vb2_plane_vaddr(&buf->vb.vb2_buf, 0);

	buf->vb.sequence = dev->vbi_cap_seq_count;
	if (dev->field_cap == V4L2_FIELD_ALTERNATE)
		buf->vb.sequence /= 2;

	vivid_sliced_vbi_cap_fill(dev, buf->vb.sequence);

	memset(vbuf, 0, vb2_plane_size(&buf->vb.vb2_buf, 0));
	if (!VIVID_INVALID_SIGNAL(dev->std_signal_mode)) {
		unsigned i;

		for (i = 0; i < 25; i++)
			vbuf[i] = dev->vbi_gen.data[i];
	}

	buf->vb.vb2_buf.timestamp = ktime_get_ns() + dev->time_wrap_offset;
}

static int vbi_cap_queue_setup(struct vb2_queue *vq,
		       unsigned *nbuffers, unsigned *nplanes,
		       unsigned sizes[], void *alloc_ctxs[])
{
	struct vivid_dev *dev = vb2_get_drv_priv(vq);
	bool is_60hz = dev->std_cap & V4L2_STD_525_60;
	unsigned size = vq->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE ?
		36 * sizeof(struct v4l2_sliced_vbi_data) :
		1440 * 2 * (is_60hz ? 12 : 18);

	if (!vivid_is_sdtv_cap(dev))
		return -EINVAL;

	sizes[0] = size;

	if (vq->num_buffers + *nbuffers < 2)
		*nbuffers = 2 - vq->num_buffers;

	*nplanes = 1;
	return 0;
}

static int vbi_cap_buf_prepare(struct vb2_buffer *vb)
{
	struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
	bool is_60hz = dev->std_cap & V4L2_STD_525_60;
	unsigned size = vb->vb2_queue->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE ?
		36 * sizeof(struct v4l2_sliced_vbi_data) :
		1440 * 2 * (is_60hz ? 12 : 18);

	dprintk(dev, 1, "%s\n", __func__);

	if (dev->buf_prepare_error) {
		/*
		 * Error injection: test what happens if buf_prepare() returns
		 * an error.
		 */
		dev->buf_prepare_error = false;
		return -EINVAL;
	}
	if (vb2_plane_size(vb, 0) < size) {
		dprintk(dev, 1, "%s data will not fit into plane (%lu < %u)\n",
				__func__, vb2_plane_size(vb, 0), size);
		return -EINVAL;
	}
	vb2_set_plane_payload(vb, 0, size);

	return 0;
}

static void vbi_cap_buf_queue(struct vb2_buffer *vb)
{
	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
	struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
	struct vivid_buffer *buf = container_of(vbuf, struct vivid_buffer, vb);

	dprintk(dev, 1, "%s\n", __func__);

	spin_lock(&dev->slock);
	list_add_tail(&buf->list, &dev->vbi_cap_active);
	spin_unlock(&dev->slock);
}

static int vbi_cap_start_streaming(struct vb2_queue *vq, unsigned count)
{
	struct vivid_dev *dev = vb2_get_drv_priv(vq);
	int err;

	dprintk(dev, 1, "%s\n", __func__);
	dev->vbi_cap_seq_count = 0;
	if (dev->start_streaming_error) {
		dev->start_streaming_error = false;
		err = -EINVAL;
	} else {
		err = vivid_start_generating_vid_cap(dev, &dev->vbi_cap_streaming);
	}
	if (err) {
		struct vivid_buffer *buf, *tmp;

		list_for_each_entry_safe(buf, tmp, &dev->vbi_cap_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_cap_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_cap(dev, &dev->vbi_cap_streaming);
}

const struct vb2_ops vivid_vbi_cap_qops = {
	.queue_setup		= vbi_cap_queue_setup,
	.buf_prepare		= vbi_cap_buf_prepare,
	.buf_queue		= vbi_cap_buf_queue,
	.start_streaming	= vbi_cap_start_streaming,
	.stop_streaming		= vbi_cap_stop_streaming,
	.wait_prepare		= vb2_ops_wait_prepare,
	.wait_finish		= vb2_ops_wait_finish,
};

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

	if (!vivid_is_sdtv_cap(dev) || !dev->has_raw_vbi_cap)
		return -EINVAL;

	vivid_g_fmt_vbi_cap(dev, vbi);
	return 0;
}

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

	if (ret)
		return ret;
	if (dev->stream_sliced_vbi_cap && vb2_is_busy(&dev->vb_vbi_cap_q))
		return -EBUSY;
	dev->stream_sliced_vbi_cap = false;
	dev->vbi_cap_dev.queue->type = V4L2_BUF_TYPE_VBI_CAPTURE;
	return 0;
}

void vivid_fill_service_lines(struct v4l2_sliced_vbi_format *vbi, u32 service_set)
{
	vbi->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
	vbi->service_set = service_set;
	memset(vbi->service_lines, 0, sizeof(vbi->service_lines));
	memset(vbi->reserved, 0, sizeof(vbi->reserved));

	if (vbi->service_set == 0)
		return;

	if (vbi->service_set & V4L2_SLICED_CAPTION_525) {
		vbi->service_lines[0][21] = V4L2_SLICED_CAPTION_525;
		vbi->service_lines[1][21] = V4L2_SLICED_CAPTION_525;
	}
	if (vbi->service_set & V4L2_SLICED_WSS_625) {
		unsigned i;

		for (i = 7; i <= 18; i++)
			vbi->service_lines[0][i] =
			vbi->service_lines[1][i] = V4L2_SLICED_TELETEXT_B;
		vbi->service_lines[0][23] = V4L2_SLICED_WSS_625;
	}
}

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

	if (!vivid_is_sdtv_cap(dev) || !dev->has_sliced_vbi_cap)
		return -EINVAL;

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

int vidioc_try_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
{
	struct vivid_dev *dev = video_drvdata(file);
	struct v4l2_sliced_vbi_format *vbi = &fmt->fmt.sliced;
	bool is_60hz = dev->std_cap & V4L2_STD_525_60;
	u32 service_set = vbi->service_set;

	if (!vivid_is_sdtv_cap(dev) || !dev->has_sliced_vbi_cap)
		return -EINVAL;

	service_set &= is_60hz ? V4L2_SLICED_CAPTION_525 :
				 V4L2_SLICED_WSS_625 | V4L2_SLICED_TELETEXT_B;
	vivid_fill_service_lines(vbi, service_set);
	return 0;
}

int vidioc_s_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
{
	struct vivid_dev *dev = video_drvdata(file);
	struct v4l2_sliced_vbi_format *vbi = &fmt->fmt.sliced;
	int ret = vidioc_try_fmt_sliced_vbi_cap(file, fh, fmt);

	if (ret)
		return ret;
	if (!dev->stream_sliced_vbi_cap && vb2_is_busy(&dev->vb_vbi_cap_q))
		return -EBUSY;
	dev->service_set_cap = vbi->service_set;
	dev->stream_sliced_vbi_cap = true;
	dev->vbi_cap_dev.queue->type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
	return 0;
}

int vidioc_g_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_sliced_vbi_cap *cap)
{
	struct vivid_dev *dev = video_drvdata(file);
	struct video_device *vdev = video_devdata(file);
	bool is_60hz;

	if (vdev->vfl_dir == VFL_DIR_RX) {
		is_60hz = dev->std_cap & V4L2_STD_525_60;
		if (!vivid_is_sdtv_cap(dev) || !dev->has_sliced_vbi_cap ||
		    cap->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
			return -EINVAL;
	} else {
		is_60hz = dev->std_out & V4L2_STD_525_60;
		if (!vivid_is_svid_out(dev) || !dev->has_sliced_vbi_out ||
		    cap->type != V4L2_BUF_TYPE_SLICED_VBI_OUTPUT)
			return -EINVAL;
	}

	cap->service_set = is_60hz ? V4L2_SLICED_CAPTION_525 :
				     V4L2_SLICED_WSS_625 | V4L2_SLICED_TELETEXT_B;
	if (is_60hz) {
		cap->service_lines[0][21] = V4L2_SLICED_CAPTION_525;
		cap->service_lines[1][21] = V4L2_SLICED_CAPTION_525;
	} else {
		unsigned i;

		for (i = 7; i <= 18; i++)
			cap->service_lines[0][i] =
			cap->service_lines[1][i] = V4L2_SLICED_TELETEXT_B;
		cap->service_lines[0][23] = V4L2_SLICED_WSS_625;
	}
	return 0;
}
