/*
 *  cx18 init/start/stop/exit stream functions
 *
 *  Derived from ivtv-streams.c
 *
 *  Copyright (C) 2007  Hans Verkuil <hverkuil@xs4all.nl>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
 *  02111-1307  USA
 */

#include "cx18-driver.h"
#include "cx18-fileops.h"
#include "cx18-mailbox.h"
#include "cx18-i2c.h"
#include "cx18-queue.h"
#include "cx18-ioctl.h"
#include "cx18-streams.h"
#include "cx18-cards.h"
#include "cx18-scb.h"
#include "cx18-av-core.h"
#include "cx18-dvb.h"

#define CX18_DSP0_INTERRUPT_MASK     	0xd0004C

static struct file_operations cx18_v4l2_enc_fops = {
	.owner = THIS_MODULE,
	.read = cx18_v4l2_read,
	.open = cx18_v4l2_open,
	.ioctl = cx18_v4l2_ioctl,
	.compat_ioctl = v4l_compat_ioctl32,
	.release = cx18_v4l2_close,
	.poll = cx18_v4l2_enc_poll,
};

/* offset from 0 to register ts v4l2 minors on */
#define CX18_V4L2_ENC_TS_OFFSET   16
/* offset from 0 to register pcm v4l2 minors on */
#define CX18_V4L2_ENC_PCM_OFFSET  24
/* offset from 0 to register yuv v4l2 minors on */
#define CX18_V4L2_ENC_YUV_OFFSET  32

static struct {
	const char *name;
	int vfl_type;
	int minor_offset;
	int dma;
	enum v4l2_buf_type buf_type;
	struct file_operations *fops;
} cx18_stream_info[] = {
	{	/* CX18_ENC_STREAM_TYPE_MPG */
		"encoder MPEG",
		VFL_TYPE_GRABBER, 0,
		PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VIDEO_CAPTURE,
		&cx18_v4l2_enc_fops
	},
	{	/* CX18_ENC_STREAM_TYPE_TS */
		"TS",
		VFL_TYPE_GRABBER, -1,
		PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VIDEO_CAPTURE,
		&cx18_v4l2_enc_fops
	},
	{	/* CX18_ENC_STREAM_TYPE_YUV */
		"encoder YUV",
		VFL_TYPE_GRABBER, CX18_V4L2_ENC_YUV_OFFSET,
		PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VIDEO_CAPTURE,
		&cx18_v4l2_enc_fops
	},
	{	/* CX18_ENC_STREAM_TYPE_VBI */
		"encoder VBI",
		VFL_TYPE_VBI, 0,
		PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VBI_CAPTURE,
		&cx18_v4l2_enc_fops
	},
	{	/* CX18_ENC_STREAM_TYPE_PCM */
		"encoder PCM audio",
		VFL_TYPE_GRABBER, CX18_V4L2_ENC_PCM_OFFSET,
		PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_PRIVATE,
		&cx18_v4l2_enc_fops
	},
	{	/* CX18_ENC_STREAM_TYPE_IDX */
		"encoder IDX",
		VFL_TYPE_GRABBER, -1,
		PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VIDEO_CAPTURE,
		&cx18_v4l2_enc_fops
	},
	{	/* CX18_ENC_STREAM_TYPE_RAD */
		"encoder radio",
		VFL_TYPE_RADIO, 0,
		PCI_DMA_NONE, V4L2_BUF_TYPE_PRIVATE,
		&cx18_v4l2_enc_fops
	},
};

static void cx18_stream_init(struct cx18 *cx, int type)
{
	struct cx18_stream *s = &cx->streams[type];
	struct video_device *dev = s->v4l2dev;
	u32 max_size = cx->options.megabytes[type] * 1024 * 1024;

	/* we need to keep v4l2dev, so restore it afterwards */
	memset(s, 0, sizeof(*s));
	s->v4l2dev = dev;

	/* initialize cx18_stream fields */
	s->cx = cx;
	s->type = type;
	s->name = cx18_stream_info[type].name;
	s->handle = 0xffffffff;

	s->dma = cx18_stream_info[type].dma;
	s->buf_size = cx->stream_buf_size[type];
	if (s->buf_size)
		s->buffers = max_size / s->buf_size;
	if (s->buffers > 63) {
		/* Each stream has a maximum of 63 buffers,
		   ensure we do not exceed that. */
		s->buffers = 63;
		s->buf_size = (max_size / s->buffers) & ~0xfff;
	}
	spin_lock_init(&s->qlock);
	init_waitqueue_head(&s->waitq);
	s->id = -1;
	cx18_queue_init(&s->q_free);
	cx18_queue_init(&s->q_full);
	cx18_queue_init(&s->q_io);
}

static int cx18_prep_dev(struct cx18 *cx, int type)
{
	struct cx18_stream *s = &cx->streams[type];
	u32 cap = cx->v4l2_cap;
	int minor_offset = cx18_stream_info[type].minor_offset;
	int minor;

	/* These four fields are always initialized. If v4l2dev == NULL, then
	   this stream is not in use. In that case no other fields but these
	   four can be used. */
	s->v4l2dev = NULL;
	s->cx = cx;
	s->type = type;
	s->name = cx18_stream_info[type].name;

	/* Check whether the radio is supported */
	if (type == CX18_ENC_STREAM_TYPE_RAD && !(cap & V4L2_CAP_RADIO))
		return 0;

	/* Check whether VBI is supported */
	if (type == CX18_ENC_STREAM_TYPE_VBI &&
	    !(cap & (V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_CAPTURE)))
		return 0;

	/* card number + user defined offset + device offset */
	minor = cx->num + cx18_first_minor + minor_offset;

	/* User explicitly selected 0 buffers for these streams, so don't
	   create them. */
	if (cx18_stream_info[type].dma != PCI_DMA_NONE &&
	    cx->options.megabytes[type] == 0) {
		CX18_INFO("Disabled %s device\n", cx18_stream_info[type].name);
		return 0;
	}

	cx18_stream_init(cx, type);

	if (minor_offset == -1)
		return 0;

	/* allocate and initialize the v4l2 video device structure */
	s->v4l2dev = video_device_alloc();
	if (s->v4l2dev == NULL) {
		CX18_ERR("Couldn't allocate v4l2 video_device for %s\n",
				s->name);
		return -ENOMEM;
	}

	s->v4l2dev->type =
		VID_TYPE_CAPTURE | VID_TYPE_TUNER | VID_TYPE_TELETEXT |
		VID_TYPE_CLIPPING | VID_TYPE_SCALES | VID_TYPE_MPEG_ENCODER;
	snprintf(s->v4l2dev->name, sizeof(s->v4l2dev->name), "cx18%d %s",
			cx->num, s->name);

	s->v4l2dev->minor = minor;
	s->v4l2dev->dev = &cx->dev->dev;
	s->v4l2dev->fops = cx18_stream_info[type].fops;
	s->v4l2dev->release = video_device_release;

	return 0;
}

/* Initialize v4l2 variables and register v4l2 devices */
int cx18_streams_setup(struct cx18 *cx)
{
	int type;

	/* Setup V4L2 Devices */
	for (type = 0; type < CX18_MAX_STREAMS; type++) {
		/* Prepare device */
		if (cx18_prep_dev(cx, type))
			break;

		/* Allocate Stream */
		if (cx18_stream_alloc(&cx->streams[type]))
			break;
	}
	if (type == CX18_MAX_STREAMS)
		return 0;

	/* One or more streams could not be initialized. Clean 'em all up. */
	cx18_streams_cleanup(cx, 0);
	return -ENOMEM;
}

static int cx18_reg_dev(struct cx18 *cx, int type)
{
	struct cx18_stream *s = &cx->streams[type];
	int vfl_type = cx18_stream_info[type].vfl_type;
	int minor;

	/* TODO: Shouldn't this be a VFL_TYPE_TRANSPORT or something?
	 * We need a VFL_TYPE_TS defined.
	 */
	if (strcmp("TS", s->name) == 0) {
		/* just return if no DVB is supported */
		if ((cx->card->hw_all & CX18_HW_DVB) == 0)
			return 0;
		if (cx18_dvb_register(s) < 0) {
			CX18_ERR("DVB failed to register\n");
			return -EINVAL;
		}
	}

	if (s->v4l2dev == NULL)
		return 0;

	minor = s->v4l2dev->minor;

	/* Register device. First try the desired minor, then any free one. */
	if (video_register_device(s->v4l2dev, vfl_type, minor) &&
			video_register_device(s->v4l2dev, vfl_type, -1)) {
		CX18_ERR("Couldn't register v4l2 device for %s minor %d\n",
			s->name, minor);
		video_device_release(s->v4l2dev);
		s->v4l2dev = NULL;
		return -ENOMEM;
	}
	minor = s->v4l2dev->minor;

	switch (vfl_type) {
	case VFL_TYPE_GRABBER:
		CX18_INFO("Registered device video%d for %s (%d MB)\n",
			minor, s->name, cx->options.megabytes[type]);
		break;

	case VFL_TYPE_RADIO:
		CX18_INFO("Registered device radio%d for %s\n",
			minor - MINOR_VFL_TYPE_RADIO_MIN, s->name);
		break;

	case VFL_TYPE_VBI:
		if (cx->options.megabytes[type])
			CX18_INFO("Registered device vbi%d for %s (%d MB)\n",
				minor - MINOR_VFL_TYPE_VBI_MIN,
				s->name, cx->options.megabytes[type]);
		else
			CX18_INFO("Registered device vbi%d for %s\n",
				minor - MINOR_VFL_TYPE_VBI_MIN, s->name);
		break;
	}

	return 0;
}

/* Register v4l2 devices */
int cx18_streams_register(struct cx18 *cx)
{
	int type;
	int err = 0;

	/* Register V4L2 devices */
	for (type = 0; type < CX18_MAX_STREAMS; type++)
		err |= cx18_reg_dev(cx, type);

	if (err == 0)
		return 0;

	/* One or more streams could not be initialized. Clean 'em all up. */
	cx18_streams_cleanup(cx, 1);
	return -ENOMEM;
}

/* Unregister v4l2 devices */
void cx18_streams_cleanup(struct cx18 *cx, int unregister)
{
	struct video_device *vdev;
	int type;

	/* Teardown all streams */
	for (type = 0; type < CX18_MAX_STREAMS; type++) {
		if (cx->streams[type].dvb.enabled)
			cx18_dvb_unregister(&cx->streams[type]);

		vdev = cx->streams[type].v4l2dev;

		cx->streams[type].v4l2dev = NULL;
		if (vdev == NULL)
			continue;

		cx18_stream_free(&cx->streams[type]);

		/* Unregister or release device */
		if (unregister)
			video_unregister_device(vdev);
		else
			video_device_release(vdev);
	}
}

static void cx18_vbi_setup(struct cx18_stream *s)
{
	struct cx18 *cx = s->cx;
	int raw = cx->vbi.sliced_in->service_set == 0;
	u32 data[CX2341X_MBOX_MAX_DATA];
	int lines;

	if (cx->is_60hz) {
		cx->vbi.count = 12;
		cx->vbi.start[0] = 10;
		cx->vbi.start[1] = 273;
	} else {        /* PAL/SECAM */
		cx->vbi.count = 18;
		cx->vbi.start[0] = 6;
		cx->vbi.start[1] = 318;
	}

	/* setup VBI registers */
	cx18_av_cmd(cx, VIDIOC_S_FMT, &cx->vbi.in);

	/* determine number of lines and total number of VBI bytes.
	   A raw line takes 1443 bytes: 2 * 720 + 4 byte frame header - 1
	   The '- 1' byte is probably an unused U or V byte. Or something...
	   A sliced line takes 51 bytes: 4 byte frame header, 4 byte internal
	   header, 42 data bytes + checksum (to be confirmed) */
	if (raw) {
		lines = cx->vbi.count * 2;
	} else {
		lines = cx->is_60hz ? 24 : 38;
		if (cx->is_60hz)
			lines += 2;
	}

	cx->vbi.enc_size = lines *
		(raw ? cx->vbi.raw_size : cx->vbi.sliced_size);

	data[0] = s->handle;
	/* Lines per field */
	data[1] = (lines / 2) | ((lines / 2) << 16);
	/* bytes per line */
	data[2] = (raw ? cx->vbi.raw_size : cx->vbi.sliced_size);
	/* Every X number of frames a VBI interrupt arrives
	   (frames as in 25 or 30 fps) */
	data[3] = 1;
	/* Setup VBI for the cx25840 digitizer */
	if (raw) {
		data[4] = 0x20602060;
		data[5] = 0x30703070;
	} else {
		data[4] = 0xB0F0B0F0;
		data[5] = 0xA0E0A0E0;
	}

	CX18_DEBUG_INFO("Setup VBI h: %d lines %x bpl %d fr %d %x %x\n",
			data[0], data[1], data[2], data[3], data[4], data[5]);

	if (s->type == CX18_ENC_STREAM_TYPE_VBI)
		cx18_api(cx, CX18_CPU_SET_RAW_VBI_PARAM, 6, data);
}

int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
{
	u32 data[MAX_MB_ARGUMENTS];
	struct cx18 *cx = s->cx;
	struct list_head *p;
	int ts = 0;
	int captype = 0;

	if (s->v4l2dev == NULL && s->dvb.enabled == 0)
		return -EINVAL;

	CX18_DEBUG_INFO("Start encoder stream %s\n", s->name);

	switch (s->type) {
	case CX18_ENC_STREAM_TYPE_MPG:
		captype = CAPTURE_CHANNEL_TYPE_MPEG;
		cx->mpg_data_received = cx->vbi_data_inserted = 0;
		cx->dualwatch_jiffies = jiffies;
		cx->dualwatch_stereo_mode = cx->params.audio_properties & 0x300;
		cx->search_pack_header = 0;
		break;

	case CX18_ENC_STREAM_TYPE_TS:
		captype = CAPTURE_CHANNEL_TYPE_TS;
		ts = 1;
		break;
	case CX18_ENC_STREAM_TYPE_YUV:
		captype = CAPTURE_CHANNEL_TYPE_YUV;
		break;
	case CX18_ENC_STREAM_TYPE_PCM:
		captype = CAPTURE_CHANNEL_TYPE_PCM;
		break;
	case CX18_ENC_STREAM_TYPE_VBI:
		captype = cx->vbi.sliced_in->service_set ?
		    CAPTURE_CHANNEL_TYPE_SLICED_VBI : CAPTURE_CHANNEL_TYPE_VBI;
		cx->vbi.frame = 0;
		cx->vbi.inserted_frame = 0;
		memset(cx->vbi.sliced_mpeg_size,
			0, sizeof(cx->vbi.sliced_mpeg_size));
		break;
	default:
		return -EINVAL;
	}
	s->buffers_stolen = 0;

	/* mute/unmute video */
	cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2,
		  s->handle, !!test_bit(CX18_F_I_RADIO_USER, &cx->i_flags));

	/* Clear Streamoff flags in case left from last capture */
	clear_bit(CX18_F_S_STREAMOFF, &s->s_flags);

	cx18_vapi_result(cx, data, CX18_CREATE_TASK, 1, CPU_CMD_MASK_CAPTURE);
	s->handle = data[0];
	cx18_vapi(cx, CX18_CPU_SET_CHANNEL_TYPE, 2, s->handle, captype);

	if (atomic_read(&cx->ana_capturing) == 0 && !ts) {
		/* Stuff from Windows, we don't know what it is */
		cx18_vapi(cx, CX18_CPU_SET_VER_CROP_LINE, 2, s->handle, 0);
		cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 3, s->handle, 3, 1);
		cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 3, s->handle, 8, 0);
		cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 3, s->handle, 4, 1);
		cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 2, s->handle, 12);

		cx18_vapi(cx, CX18_CPU_SET_CAPTURE_LINE_NO, 3,
			       s->handle, cx->digitizer, cx->digitizer);

		/* Setup VBI */
		if (cx->v4l2_cap & V4L2_CAP_VBI_CAPTURE)
			cx18_vbi_setup(s);

		/* assign program index info.
		   Mask 7: select I/P/B, Num_req: 400 max */
		cx18_vapi_result(cx, data, CX18_CPU_SET_INDEXTABLE, 1, 0);

		/* Setup API for Stream */
		cx2341x_update(cx, cx18_api_func, NULL, &cx->params);
	}

	if (atomic_read(&cx->tot_capturing) == 0) {
		clear_bit(CX18_F_I_EOS, &cx->i_flags);
		write_reg(7, CX18_DSP0_INTERRUPT_MASK);
	}

	cx18_vapi(cx, CX18_CPU_DE_SET_MDL_ACK, 3, s->handle,
		(void __iomem *)&cx->scb->cpu_mdl_ack[s->type][0] - cx->enc_mem,
		(void __iomem *)&cx->scb->cpu_mdl_ack[s->type][1] - cx->enc_mem);

	list_for_each(p, &s->q_free.list) {
		struct cx18_buffer *buf = list_entry(p, struct cx18_buffer, list);

		writel(buf->dma_handle, &cx->scb->cpu_mdl[buf->id].paddr);
		writel(s->buf_size, &cx->scb->cpu_mdl[buf->id].length);
		cx18_vapi(cx, CX18_CPU_DE_SET_MDL, 5, s->handle,
			(void __iomem *)&cx->scb->cpu_mdl[buf->id] - cx->enc_mem,
			1, buf->id, s->buf_size);
	}
	/* begin_capture */
	if (cx18_vapi(cx, CX18_CPU_CAPTURE_START, 1, s->handle)) {
		CX18_DEBUG_WARN("Error starting capture!\n");
		cx18_vapi(cx, CX18_DESTROY_TASK, 1, s->handle);
		return -EINVAL;
	}

	/* you're live! sit back and await interrupts :) */
	if (!ts)
		atomic_inc(&cx->ana_capturing);
	atomic_inc(&cx->tot_capturing);
	return 0;
}

void cx18_stop_all_captures(struct cx18 *cx)
{
	int i;

	for (i = CX18_MAX_STREAMS - 1; i >= 0; i--) {
		struct cx18_stream *s = &cx->streams[i];

		if (s->v4l2dev == NULL && s->dvb.enabled == 0)
			continue;
		if (test_bit(CX18_F_S_STREAMING, &s->s_flags))
			cx18_stop_v4l2_encode_stream(s, 0);
	}
}

int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end)
{
	struct cx18 *cx = s->cx;
	unsigned long then;

	if (s->v4l2dev == NULL && s->dvb.enabled == 0)
		return -EINVAL;

	/* This function assumes that you are allowed to stop the capture
	   and that we are actually capturing */

	CX18_DEBUG_INFO("Stop Capture\n");

	if (atomic_read(&cx->tot_capturing) == 0)
		return 0;

	if (s->type == CX18_ENC_STREAM_TYPE_MPG)
		cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 2, s->handle, !gop_end);
	else
		cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 1, s->handle);

	then = jiffies;

	if (s->type == CX18_ENC_STREAM_TYPE_MPG && gop_end) {
		CX18_INFO("ignoring gop_end: not (yet?) supported by the firmware\n");
	}

	if (s->type != CX18_ENC_STREAM_TYPE_TS)
		atomic_dec(&cx->ana_capturing);
	atomic_dec(&cx->tot_capturing);

	/* Clear capture and no-read bits */
	clear_bit(CX18_F_S_STREAMING, &s->s_flags);

	cx18_vapi(cx, CX18_DESTROY_TASK, 1, s->handle);
	s->handle = 0xffffffff;

	if (atomic_read(&cx->tot_capturing) > 0)
		return 0;

	write_reg(5, CX18_DSP0_INTERRUPT_MASK);
	wake_up(&s->waitq);

	return 0;
}

u32 cx18_find_handle(struct cx18 *cx)
{
	int i;

	/* find first available handle to be used for global settings */
	for (i = 0; i < CX18_MAX_STREAMS; i++) {
		struct cx18_stream *s = &cx->streams[i];

		if (s->v4l2dev && s->handle)
			return s->handle;
	}
	return 0;
}
