/*
 *  Driver for the Conexant CX25821 PCIe bridge
 *
 *  Copyright (C) 2009 Conexant Systems Inc.
 *  Authors  <hiep.huynh@conexant.com>, <shu.lin@conexant.com>
 *
 *  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., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include "cx25821-video.h"
#include "cx25821-video-upstream.h"

#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/syscalls.h>
#include <linux/file.h>
#include <linux/fcntl.h>
#include <linux/slab.h>
#include <linux/uaccess.h>

MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards");
MODULE_AUTHOR("Hiep Huynh <hiep.huynh@conexant.com>");
MODULE_LICENSE("GPL");

static int _intr_msk =
    FLD_VID_SRC_RISC1 | FLD_VID_SRC_UF | FLD_VID_SRC_SYNC | FLD_VID_SRC_OPC_ERR;

int cx25821_sram_channel_setup_upstream(struct cx25821_dev *dev,
					struct sram_channel *ch,
					unsigned int bpl, u32 risc)
{
	unsigned int i, lines;
	u32 cdt;

	if (ch->cmds_start == 0) {
		cx_write(ch->ptr1_reg, 0);
		cx_write(ch->ptr2_reg, 0);
		cx_write(ch->cnt2_reg, 0);
		cx_write(ch->cnt1_reg, 0);
		return 0;
	}

	bpl = (bpl + 7) & ~7;	/* alignment */
	cdt = ch->cdt;
	lines = ch->fifo_size / bpl;

	if (lines > 4)
		lines = 4;

	BUG_ON(lines < 2);

	/* write CDT */
	for (i = 0; i < lines; i++) {
		cx_write(cdt + 16 * i, ch->fifo_start + bpl * i);
		cx_write(cdt + 16 * i + 4, 0);
		cx_write(cdt + 16 * i + 8, 0);
		cx_write(cdt + 16 * i + 12, 0);
	}

	/* write CMDS */
	cx_write(ch->cmds_start + 0, risc);

	cx_write(ch->cmds_start + 4, 0);
	cx_write(ch->cmds_start + 8, cdt);
	cx_write(ch->cmds_start + 12, (lines * 16) >> 3);
	cx_write(ch->cmds_start + 16, ch->ctrl_start);

	cx_write(ch->cmds_start + 20, VID_IQ_SIZE_DW);

	for (i = 24; i < 80; i += 4)
		cx_write(ch->cmds_start + i, 0);

	/* fill registers */
	cx_write(ch->ptr1_reg, ch->fifo_start);
	cx_write(ch->ptr2_reg, cdt);
	cx_write(ch->cnt2_reg, (lines * 16) >> 3);
	cx_write(ch->cnt1_reg, (bpl >> 3) - 1);

	return 0;
}

static __le32 *cx25821_update_riscprogram(struct cx25821_dev *dev,
					  __le32 *rp, unsigned int offset,
					  unsigned int bpl, u32 sync_line,
					  unsigned int lines, int fifo_enable,
					  int field_type)
{
	unsigned int line, i;
	int dist_betwn_starts = bpl * 2;

	*(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);

	if (USE_RISC_NOOP_VIDEO) {
		for (i = 0; i < NUM_NO_OPS; i++)
			*(rp++) = cpu_to_le32(RISC_NOOP);
	}

	/* scan lines */
	for (line = 0; line < lines; line++) {
		*(rp++) = cpu_to_le32(RISC_READ | RISC_SOL | RISC_EOL | bpl);
		*(rp++) = cpu_to_le32(dev->_data_buf_phys_addr + offset);
		*(rp++) = cpu_to_le32(0);	/* bits 63-32 */

		if ((lines <= NTSC_FIELD_HEIGHT)
		    || (line < (NTSC_FIELD_HEIGHT - 1)) || !(dev->_isNTSC)) {
			offset += dist_betwn_starts;
		}
	}

	return rp;
}

static __le32 *cx25821_risc_field_upstream(struct cx25821_dev *dev, __le32 * rp,
					   dma_addr_t databuf_phys_addr,
					   unsigned int offset, u32 sync_line,
					   unsigned int bpl, unsigned int lines,
					   int fifo_enable, int field_type)
{
	unsigned int line, i;
	struct sram_channel *sram_ch =
	   dev->channels[dev->_channel_upstream_select].sram_channels;
	int dist_betwn_starts = bpl * 2;

	/* sync instruction */
	if (sync_line != NO_SYNC_LINE)
		*(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);

	if (USE_RISC_NOOP_VIDEO) {
		for (i = 0; i < NUM_NO_OPS; i++)
			*(rp++) = cpu_to_le32(RISC_NOOP);
	}

	/* scan lines */
	for (line = 0; line < lines; line++) {
		*(rp++) = cpu_to_le32(RISC_READ | RISC_SOL | RISC_EOL | bpl);
		*(rp++) = cpu_to_le32(databuf_phys_addr + offset);
		*(rp++) = cpu_to_le32(0);	/* bits 63-32 */

		if ((lines <= NTSC_FIELD_HEIGHT)
		    || (line < (NTSC_FIELD_HEIGHT - 1)) || !(dev->_isNTSC))
			/* to skip the other field line */
			offset += dist_betwn_starts;

		/* check if we need to enable the FIFO after the first 4 lines
		 * For the upstream video channel, the risc engine will enable
		 * the FIFO. */
		if (fifo_enable && line == 3) {
			*(rp++) = RISC_WRITECR;
			*(rp++) = sram_ch->dma_ctl;
			*(rp++) = FLD_VID_FIFO_EN;
			*(rp++) = 0x00000001;
		}
	}

	return rp;
}

int cx25821_risc_buffer_upstream(struct cx25821_dev *dev,
				 struct pci_dev *pci,
				 unsigned int top_offset,
				 unsigned int bpl, unsigned int lines)
{
	__le32 *rp;
	int fifo_enable = 0;
	/* get line count for single field */
	int singlefield_lines = lines >> 1;
	int odd_num_lines = singlefield_lines;
	int frame = 0;
	int frame_size = 0;
	int databuf_offset = 0;
	int risc_program_size = 0;
	int risc_flag = RISC_CNT_RESET;
	unsigned int bottom_offset = bpl;
	dma_addr_t risc_phys_jump_addr;

	if (dev->_isNTSC) {
		odd_num_lines = singlefield_lines + 1;
		risc_program_size = FRAME1_VID_PROG_SIZE;
		frame_size =
		    (bpl ==
		     Y411_LINE_SZ) ? FRAME_SIZE_NTSC_Y411 :
		    FRAME_SIZE_NTSC_Y422;
	} else {
		risc_program_size = PAL_VID_PROG_SIZE;
		frame_size =
		    (bpl ==
		     Y411_LINE_SZ) ? FRAME_SIZE_PAL_Y411 : FRAME_SIZE_PAL_Y422;
	}

	/* Virtual address of Risc buffer program */
	rp = dev->_dma_virt_addr;

	for (frame = 0; frame < NUM_FRAMES; frame++) {
		databuf_offset = frame_size * frame;

		if (UNSET != top_offset) {
			fifo_enable = (frame == 0) ? FIFO_ENABLE : FIFO_DISABLE;
			rp = cx25821_risc_field_upstream(dev, rp,
							 dev->
							 _data_buf_phys_addr +
							 databuf_offset,
							 top_offset, 0, bpl,
							 odd_num_lines,
							 fifo_enable,
							 ODD_FIELD);
		}

		fifo_enable = FIFO_DISABLE;

		/* Even Field */
		rp = cx25821_risc_field_upstream(dev, rp,
						 dev->_data_buf_phys_addr +
						 databuf_offset, bottom_offset,
						 0x200, bpl, singlefield_lines,
						 fifo_enable, EVEN_FIELD);

		if (frame == 0) {
			risc_flag = RISC_CNT_RESET;
			risc_phys_jump_addr =
			    dev->_dma_phys_start_addr + risc_program_size;
		} else {
			risc_phys_jump_addr = dev->_dma_phys_start_addr;
			risc_flag = RISC_CNT_INC;
		}

		/* Loop to 2ndFrameRISC or to Start of Risc
		 * program & generate IRQ
		 */
		*(rp++) = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | risc_flag);
		*(rp++) = cpu_to_le32(risc_phys_jump_addr);
		*(rp++) = cpu_to_le32(0);
	}

	return 0;
}

void cx25821_stop_upstream_video_ch1(struct cx25821_dev *dev)
{
	struct sram_channel *sram_ch =
	   dev->channels[VID_UPSTREAM_SRAM_CHANNEL_I].sram_channels;
	u32 tmp = 0;

	if (!dev->_is_running) {
		printk
		   (KERN_INFO "cx25821: No video file is currently running so return!\n");
		return;
	}
	/* Disable RISC interrupts */
	tmp = cx_read(sram_ch->int_msk);
	cx_write(sram_ch->int_msk, tmp & ~_intr_msk);

	/* Turn OFF risc and fifo enable */
	tmp = cx_read(sram_ch->dma_ctl);
	cx_write(sram_ch->dma_ctl, tmp & ~(FLD_VID_FIFO_EN | FLD_VID_RISC_EN));

	/* Clear data buffer memory */
	if (dev->_data_buf_virt_addr)
		memset(dev->_data_buf_virt_addr, 0, dev->_data_buf_size);

	dev->_is_running = 0;
	dev->_is_first_frame = 0;
	dev->_frame_count = 0;
	dev->_file_status = END_OF_FILE;

	if (dev->_irq_queues) {
		kfree(dev->_irq_queues);
		dev->_irq_queues = NULL;
	}

	if (dev->_filename != NULL)
		kfree(dev->_filename);

	tmp = cx_read(VID_CH_MODE_SEL);
	cx_write(VID_CH_MODE_SEL, tmp & 0xFFFFFE00);
}

void cx25821_free_mem_upstream_ch1(struct cx25821_dev *dev)
{
	if (dev->_is_running)
		cx25821_stop_upstream_video_ch1(dev);

	if (dev->_dma_virt_addr) {
		pci_free_consistent(dev->pci, dev->_risc_size,
				    dev->_dma_virt_addr, dev->_dma_phys_addr);
		dev->_dma_virt_addr = NULL;
	}

	if (dev->_data_buf_virt_addr) {
		pci_free_consistent(dev->pci, dev->_data_buf_size,
				    dev->_data_buf_virt_addr,
				    dev->_data_buf_phys_addr);
		dev->_data_buf_virt_addr = NULL;
	}
}

int cx25821_get_frame(struct cx25821_dev *dev, struct sram_channel *sram_ch)
{
	struct file *myfile;
	int frame_index_temp = dev->_frame_index;
	int i = 0;
	int line_size =
	    (dev->_pixel_format ==
	     PIXEL_FRMT_411) ? Y411_LINE_SZ : Y422_LINE_SZ;
	int frame_size = 0;
	int frame_offset = 0;
	ssize_t vfs_read_retval = 0;
	char mybuf[line_size];
	loff_t file_offset;
	loff_t pos;
	mm_segment_t old_fs;

	if (dev->_file_status == END_OF_FILE)
		return 0;

	if (dev->_isNTSC) {
		frame_size =
		    (line_size ==
		     Y411_LINE_SZ) ? FRAME_SIZE_NTSC_Y411 :
		    FRAME_SIZE_NTSC_Y422;
	} else {
		frame_size =
		    (line_size ==
		     Y411_LINE_SZ) ? FRAME_SIZE_PAL_Y411 : FRAME_SIZE_PAL_Y422;
	}

	frame_offset = (frame_index_temp > 0) ? frame_size : 0;
	file_offset = dev->_frame_count * frame_size;

	myfile = filp_open(dev->_filename, O_RDONLY | O_LARGEFILE, 0);

	if (IS_ERR(myfile)) {
		const int open_errno = -PTR_ERR(myfile);
	       printk(KERN_ERR
		   "%s(): ERROR opening file(%s) with errno = %d!\n",
		   __func__, dev->_filename, open_errno);
		return PTR_ERR(myfile);
	} else {
		if (!(myfile->f_op)) {
		       printk(KERN_ERR
			   "%s: File has no file operations registered!",
			   __func__);
			filp_close(myfile, NULL);
			return -EIO;
		}

		if (!myfile->f_op->read) {
		       printk(KERN_ERR
			   "%s: File has no READ operations registered!",
			   __func__);
			filp_close(myfile, NULL);
			return -EIO;
		}

		pos = myfile->f_pos;
		old_fs = get_fs();
		set_fs(KERNEL_DS);

		for (i = 0; i < dev->_lines_count; i++) {
			pos = file_offset;

			vfs_read_retval =
			    vfs_read(myfile, mybuf, line_size, &pos);

			if (vfs_read_retval > 0 && vfs_read_retval == line_size
			    && dev->_data_buf_virt_addr != NULL) {
				memcpy((void *)(dev->_data_buf_virt_addr +
						frame_offset / 4), mybuf,
				       vfs_read_retval);
			}

			file_offset += vfs_read_retval;
			frame_offset += vfs_read_retval;

			if (vfs_read_retval < line_size) {
				printk(KERN_INFO
				      "Done: exit %s() since no more bytes to \
				      read from Video file.\n",
				       __func__);
				break;
			}
		}

		if (i > 0)
			dev->_frame_count++;

		dev->_file_status =
		    (vfs_read_retval == line_size) ? IN_PROGRESS : END_OF_FILE;

		set_fs(old_fs);
		filp_close(myfile, NULL);
	}

	return 0;
}

static void cx25821_vidups_handler(struct work_struct *work)
{
	struct cx25821_dev *dev =
	    container_of(work, struct cx25821_dev, _irq_work_entry);

	if (!dev) {
	       printk(KERN_ERR
		   "ERROR %s(): since container_of(work_struct) FAILED!\n",
		   __func__);
		return;
	}

	cx25821_get_frame(dev,
			 dev->channels[dev->_channel_upstream_select].
					       sram_channels);
}

int cx25821_openfile(struct cx25821_dev *dev, struct sram_channel *sram_ch)
{
	struct file *myfile;
	int i = 0, j = 0;
	int line_size =
	    (dev->_pixel_format ==
	     PIXEL_FRMT_411) ? Y411_LINE_SZ : Y422_LINE_SZ;
	ssize_t vfs_read_retval = 0;
	char mybuf[line_size];
	loff_t pos;
	loff_t offset = (unsigned long)0;
	mm_segment_t old_fs;

	myfile = filp_open(dev->_filename, O_RDONLY | O_LARGEFILE, 0);

	if (IS_ERR(myfile)) {
		const int open_errno = -PTR_ERR(myfile);
	       printk(KERN_ERR  "%s(): ERROR opening file(%s) with errno = %d!\n",
		       __func__, dev->_filename, open_errno);
		return PTR_ERR(myfile);
	} else {
		if (!(myfile->f_op)) {
		       printk(KERN_ERR
			   "%s: File has no file operations registered!",
			   __func__);
			filp_close(myfile, NULL);
			return -EIO;
		}

		if (!myfile->f_op->read) {
		       printk(KERN_ERR
			   "%s: File has no READ operations registered!  \
			   Returning.",
			     __func__);
			filp_close(myfile, NULL);
			return -EIO;
		}

		pos = myfile->f_pos;
		old_fs = get_fs();
		set_fs(KERNEL_DS);

		for (j = 0; j < NUM_FRAMES; j++) {
			for (i = 0; i < dev->_lines_count; i++) {
				pos = offset;

				vfs_read_retval =
				    vfs_read(myfile, mybuf, line_size, &pos);

				if (vfs_read_retval > 0
				    && vfs_read_retval == line_size
				    && dev->_data_buf_virt_addr != NULL) {
					memcpy((void *)(dev->
							_data_buf_virt_addr +
							offset / 4), mybuf,
					       vfs_read_retval);
				}

				offset += vfs_read_retval;

				if (vfs_read_retval < line_size) {
					printk(KERN_INFO
					    "Done: exit %s() since no more \
					    bytes to read from Video file.\n",
					       __func__);
					break;
				}
			}

			if (i > 0)
				dev->_frame_count++;

			if (vfs_read_retval < line_size)
				break;
		}

		dev->_file_status =
		    (vfs_read_retval == line_size) ? IN_PROGRESS : END_OF_FILE;

		set_fs(old_fs);
		myfile->f_pos = 0;
		filp_close(myfile, NULL);
	}

	return 0;
}

int cx25821_upstream_buffer_prepare(struct cx25821_dev *dev,
				    struct sram_channel *sram_ch, int bpl)
{
	int ret = 0;
	dma_addr_t dma_addr;
	dma_addr_t data_dma_addr;

	if (dev->_dma_virt_addr != NULL) {
		pci_free_consistent(dev->pci, dev->upstream_riscbuf_size,
				    dev->_dma_virt_addr, dev->_dma_phys_addr);
	}

	dev->_dma_virt_addr =
	    pci_alloc_consistent(dev->pci, dev->upstream_riscbuf_size,
				 &dma_addr);
	dev->_dma_virt_start_addr = dev->_dma_virt_addr;
	dev->_dma_phys_start_addr = dma_addr;
	dev->_dma_phys_addr = dma_addr;
	dev->_risc_size = dev->upstream_riscbuf_size;

	if (!dev->_dma_virt_addr) {
		printk
		   (KERN_ERR "cx25821: FAILED to allocate memory for Risc \
		   buffer! Returning.\n");
		return -ENOMEM;
	}

	/* Clear memory at address */
	memset(dev->_dma_virt_addr, 0, dev->_risc_size);

	if (dev->_data_buf_virt_addr != NULL) {
		pci_free_consistent(dev->pci, dev->upstream_databuf_size,
				    dev->_data_buf_virt_addr,
				    dev->_data_buf_phys_addr);
	}
	/* For Video Data buffer allocation */
	dev->_data_buf_virt_addr =
	    pci_alloc_consistent(dev->pci, dev->upstream_databuf_size,
				 &data_dma_addr);
	dev->_data_buf_phys_addr = data_dma_addr;
	dev->_data_buf_size = dev->upstream_databuf_size;

	if (!dev->_data_buf_virt_addr) {
		printk
		   (KERN_ERR "cx25821: FAILED to allocate memory for data \
		   buffer! Returning.\n");
		return -ENOMEM;
	}

	/* Clear memory at address */
	memset(dev->_data_buf_virt_addr, 0, dev->_data_buf_size);

	ret = cx25821_openfile(dev, sram_ch);
	if (ret < 0)
		return ret;

	/* Create RISC programs */
	ret =
	    cx25821_risc_buffer_upstream(dev, dev->pci, 0, bpl,
					 dev->_lines_count);
	if (ret < 0) {
		printk(KERN_INFO
		    "cx25821: Failed creating Video Upstream Risc programs!\n");
		goto error;
	}

	return 0;

error:
	return ret;
}

int cx25821_video_upstream_irq(struct cx25821_dev *dev, int chan_num,
			       u32 status)
{
	u32 int_msk_tmp;
       struct sram_channel *channel = dev->channels[chan_num].sram_channels;
	int singlefield_lines = NTSC_FIELD_HEIGHT;
	int line_size_in_bytes = Y422_LINE_SZ;
	int odd_risc_prog_size = 0;
	dma_addr_t risc_phys_jump_addr;
	__le32 *rp;

	if (status & FLD_VID_SRC_RISC1) {
		/* We should only process one program per call */
		u32 prog_cnt = cx_read(channel->gpcnt);

		/* Since we've identified our IRQ, clear our bits from the
		 * interrupt mask and interrupt status registers */
		int_msk_tmp = cx_read(channel->int_msk);
		cx_write(channel->int_msk, int_msk_tmp & ~_intr_msk);
		cx_write(channel->int_stat, _intr_msk);

		spin_lock(&dev->slock);

		dev->_frame_index = prog_cnt;

		queue_work(dev->_irq_queues, &dev->_irq_work_entry);

		if (dev->_is_first_frame) {
			dev->_is_first_frame = 0;

			if (dev->_isNTSC) {
				singlefield_lines += 1;
				odd_risc_prog_size = ODD_FLD_NTSC_PROG_SIZE;
			} else {
				singlefield_lines = PAL_FIELD_HEIGHT;
				odd_risc_prog_size = ODD_FLD_PAL_PROG_SIZE;
			}

			if (dev->_dma_virt_start_addr != NULL) {
				line_size_in_bytes =
				    (dev->_pixel_format ==
				     PIXEL_FRMT_411) ? Y411_LINE_SZ :
				    Y422_LINE_SZ;
				risc_phys_jump_addr =
				    dev->_dma_phys_start_addr +
				    odd_risc_prog_size;

				rp = cx25821_update_riscprogram(dev,
								dev->
								_dma_virt_start_addr,
								TOP_OFFSET,
								line_size_in_bytes,
								0x0,
								singlefield_lines,
								FIFO_DISABLE,
								ODD_FIELD);

				/* Jump to Even Risc program of 1st Frame */
				*(rp++) = cpu_to_le32(RISC_JUMP);
				*(rp++) = cpu_to_le32(risc_phys_jump_addr);
				*(rp++) = cpu_to_le32(0);
			}
		}

		spin_unlock(&dev->slock);
	} else {
		if (status & FLD_VID_SRC_UF)
			printk
			   (KERN_ERR "%s: Video Received Underflow Error \
			   Interrupt!\n", __func__);

		if (status & FLD_VID_SRC_SYNC)
		       printk(KERN_ERR "%s: Video Received Sync Error \
		       Interrupt!\n", __func__);

		if (status & FLD_VID_SRC_OPC_ERR)
		       printk(KERN_ERR "%s: Video Received OpCode Error \
		       Interrupt!\n", __func__);
	}

	if (dev->_file_status == END_OF_FILE) {
		printk(KERN_ERR "cx25821: EOF Channel 1 Framecount = %d\n",
		       dev->_frame_count);
		return -1;
	}
	/* ElSE, set the interrupt mask register, re-enable irq. */
	int_msk_tmp = cx_read(channel->int_msk);
	cx_write(channel->int_msk, int_msk_tmp |= _intr_msk);

	return 0;
}

static irqreturn_t cx25821_upstream_irq(int irq, void *dev_id)
{
	struct cx25821_dev *dev = dev_id;
	u32 msk_stat, vid_status;
	int handled = 0;
	int channel_num = 0;
	struct sram_channel *sram_ch;

	if (!dev)
		return -1;

	channel_num = VID_UPSTREAM_SRAM_CHANNEL_I;

       sram_ch = dev->channels[channel_num].sram_channels;

	msk_stat = cx_read(sram_ch->int_mstat);
	vid_status = cx_read(sram_ch->int_stat);

	/* Only deal with our interrupt */
	if (vid_status) {
		handled =
		    cx25821_video_upstream_irq(dev, channel_num, vid_status);
	}

	if (handled < 0)
		cx25821_stop_upstream_video_ch1(dev);
	else
		handled += handled;

	return IRQ_RETVAL(handled);
}

void cx25821_set_pixelengine(struct cx25821_dev *dev, struct sram_channel *ch,
			     int pix_format)
{
	int width = WIDTH_D1;
	int height = dev->_lines_count;
	int num_lines, odd_num_lines;
	u32 value;
	int vip_mode = OUTPUT_FRMT_656;

	value = ((pix_format & 0x3) << 12) | (vip_mode & 0x7);
	value &= 0xFFFFFFEF;
	value |= dev->_isNTSC ? 0 : 0x10;
	cx_write(ch->vid_fmt_ctl, value);

	/* set number of active pixels in each line.
	 * Default is 720 pixels in both NTSC and PAL format */
	cx_write(ch->vid_active_ctl1, width);

	num_lines = (height / 2) & 0x3FF;
	odd_num_lines = num_lines;

	if (dev->_isNTSC)
		odd_num_lines += 1;

	value = (num_lines << 16) | odd_num_lines;

	/* set number of active lines in field 0 (top) and field 1 (bottom) */
	cx_write(ch->vid_active_ctl2, value);

	cx_write(ch->vid_cdt_size, VID_CDT_SIZE >> 3);
}

int cx25821_start_video_dma_upstream(struct cx25821_dev *dev,
				     struct sram_channel *sram_ch)
{
	u32 tmp = 0;
	int err = 0;

	/* 656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface for
	 * channel A-C
	 */
	tmp = cx_read(VID_CH_MODE_SEL);
	cx_write(VID_CH_MODE_SEL, tmp | 0x1B0001FF);

	/* Set the physical start address of the RISC program in the initial
	 * program counter(IPC) member of the cmds.
	 */
	cx_write(sram_ch->cmds_start + 0, dev->_dma_phys_addr);
	/* Risc IPC High 64 bits 63-32 */
	cx_write(sram_ch->cmds_start + 4, 0);

	/* reset counter */
	cx_write(sram_ch->gpcnt_ctl, 3);

	/* Clear our bits from the interrupt status register. */
	cx_write(sram_ch->int_stat, _intr_msk);

	/* Set the interrupt mask register, enable irq. */
	cx_set(PCI_INT_MSK, cx_read(PCI_INT_MSK) | (1 << sram_ch->irq_bit));
	tmp = cx_read(sram_ch->int_msk);
	cx_write(sram_ch->int_msk, tmp |= _intr_msk);

	err =
	    request_irq(dev->pci->irq, cx25821_upstream_irq,
			IRQF_SHARED | IRQF_DISABLED, dev->name, dev);
	if (err < 0) {
		printk(KERN_ERR "%s: can't get upstream IRQ %d\n", dev->name,
		       dev->pci->irq);
		goto fail_irq;
	}

	/* Start the DMA  engine */
	tmp = cx_read(sram_ch->dma_ctl);
	cx_set(sram_ch->dma_ctl, tmp | FLD_VID_RISC_EN);

	dev->_is_running = 1;
	dev->_is_first_frame = 1;

	return 0;

fail_irq:
	cx25821_dev_unregister(dev);
	return err;
}

int cx25821_vidupstream_init_ch1(struct cx25821_dev *dev, int channel_select,
				 int pixel_format)
{
	struct sram_channel *sram_ch;
	u32 tmp;
	int retval = 0;
	int err = 0;
	int data_frame_size = 0;
	int risc_buffer_size = 0;
	int str_length = 0;

	if (dev->_is_running) {
		printk(KERN_INFO "Video Channel is still running so return!\n");
		return 0;
	}

	dev->_channel_upstream_select = channel_select;
       sram_ch = dev->channels[channel_select].sram_channels;

	INIT_WORK(&dev->_irq_work_entry, cx25821_vidups_handler);
	dev->_irq_queues = create_singlethread_workqueue("cx25821_workqueue");

	if (!dev->_irq_queues) {
		printk
		   (KERN_ERR "cx25821: create_singlethread_workqueue() for \
		   Video FAILED!\n");
		return -ENOMEM;
	}
	/* 656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface for
	 * channel A-C
	 */
	tmp = cx_read(VID_CH_MODE_SEL);
	cx_write(VID_CH_MODE_SEL, tmp | 0x1B0001FF);

	dev->_is_running = 0;
	dev->_frame_count = 0;
	dev->_file_status = RESET_STATUS;
	dev->_lines_count = dev->_isNTSC ? 480 : 576;
	dev->_pixel_format = pixel_format;
	dev->_line_size =
	    (dev->_pixel_format ==
	     PIXEL_FRMT_422) ? (WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2;
	data_frame_size = dev->_isNTSC ? NTSC_DATA_BUF_SZ : PAL_DATA_BUF_SZ;
	risc_buffer_size =
	    dev->_isNTSC ? NTSC_RISC_BUF_SIZE : PAL_RISC_BUF_SIZE;

	if (dev->input_filename) {
		str_length = strlen(dev->input_filename);
		dev->_filename = kmalloc(str_length + 1, GFP_KERNEL);

		if (!dev->_filename)
			goto error;

		memcpy(dev->_filename, dev->input_filename, str_length + 1);
	} else {
		str_length = strlen(dev->_defaultname);
		dev->_filename = kmalloc(str_length + 1, GFP_KERNEL);

		if (!dev->_filename)
			goto error;

		memcpy(dev->_filename, dev->_defaultname, str_length + 1);
	}

	/* Default if filename is empty string */
	if (strcmp(dev->input_filename, "") == 0) {
		if (dev->_isNTSC) {
			dev->_filename =
			    (dev->_pixel_format ==
			     PIXEL_FRMT_411) ? "/root/vid411.yuv" :
			    "/root/vidtest.yuv";
		} else {
			dev->_filename =
			    (dev->_pixel_format ==
			     PIXEL_FRMT_411) ? "/root/pal411.yuv" :
			    "/root/pal422.yuv";
		}
	}

	dev->_is_running = 0;
	dev->_frame_count = 0;
	dev->_file_status = RESET_STATUS;
	dev->_lines_count = dev->_isNTSC ? 480 : 576;
	dev->_pixel_format = pixel_format;
	dev->_line_size =
	    (dev->_pixel_format ==
	     PIXEL_FRMT_422) ? (WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2;

	retval =
	    cx25821_sram_channel_setup_upstream(dev, sram_ch, dev->_line_size,
						0);

	/* setup fifo + format */
	cx25821_set_pixelengine(dev, sram_ch, dev->_pixel_format);

	dev->upstream_riscbuf_size = risc_buffer_size * 2;
	dev->upstream_databuf_size = data_frame_size * 2;

	/* Allocating buffers and prepare RISC program */
	retval = cx25821_upstream_buffer_prepare(dev, sram_ch, dev->_line_size);
	if (retval < 0) {
		printk(KERN_ERR
		       "%s: Failed to set up Video upstream buffers!\n",
		       dev->name);
		goto error;
	}

	cx25821_start_video_dma_upstream(dev, sram_ch);

	return 0;

error:
	cx25821_dev_unregister(dev);

	return err;
}
