/*
 *  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.
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include "cx25821-video.h"
#include "cx25821-video-upstream-ch2.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;

static __le32 *cx25821_update_riscprogram_ch2(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_ch2 + offset);
		*(rp++) = cpu_to_le32(0);	/* bits 63-32 */

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

	return rp;
}

static __le32 *cx25821_risc_field_upstream_ch2(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->_channel2_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_ch2)) {
			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;
}

static int cx25821_risc_buffer_upstream_ch2(struct cx25821_dev *dev,
					    struct pci_dev *pci,
					    unsigned int top_offset,
					    unsigned int bpl,
					    unsigned int lines)
{
	__le32 *rp;
	int fifo_enable = 0;
	int singlefield_lines = lines >> 1; /*get line count for single field */
	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_ch2) {
		odd_num_lines = singlefield_lines + 1;
		risc_program_size = FRAME1_VID_PROG_SIZE;
		if (bpl == Y411_LINE_SZ)
			frame_size = FRAME_SIZE_NTSC_Y411;
		else
			frame_size = FRAME_SIZE_NTSC_Y422;
	} else {
		risc_program_size = PAL_VID_PROG_SIZE;
		if (bpl == Y411_LINE_SZ)
			frame_size = FRAME_SIZE_PAL_Y411;
		else
			frame_size = FRAME_SIZE_PAL_Y422;
	}

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

	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_ch2(dev, rp,
				dev->_data_buf_phys_addr_ch2 + databuf_offset,
				top_offset, 0, bpl, odd_num_lines, fifo_enable,
				ODD_FIELD);
		}

		fifo_enable = FIFO_DISABLE;

		/* Even field */
		rp = cx25821_risc_field_upstream_ch2(dev, rp,
				dev->_data_buf_phys_addr_ch2 + 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_ch2 +
					risc_program_size;
		} else {
			risc_flag = RISC_CNT_INC;
			risc_phys_jump_addr = dev->_dma_phys_start_addr_ch2;
		}

	       /*
		* 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_ch2(struct cx25821_dev *dev)
{
	struct sram_channel *sram_ch =
		dev->channels[VID_UPSTREAM_SRAM_CHANNEL_J].sram_channels;
	u32 tmp = 0;

	if (!dev->_is_running_ch2) {
		pr_info("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 */
	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_ch2)
		memset(dev->_data_buf_virt_addr_ch2, 0,
		       dev->_data_buf_size_ch2);

	dev->_is_running_ch2 = 0;
	dev->_is_first_frame_ch2 = 0;
	dev->_frame_count_ch2 = 0;
	dev->_file_status_ch2 = END_OF_FILE;

	kfree(dev->_irq_queues_ch2);
	dev->_irq_queues_ch2 = NULL;

	kfree(dev->_filename_ch2);

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

void cx25821_free_mem_upstream_ch2(struct cx25821_dev *dev)
{
	if (dev->_is_running_ch2)
		cx25821_stop_upstream_video_ch2(dev);

	if (dev->_dma_virt_addr_ch2) {
		pci_free_consistent(dev->pci, dev->_risc_size_ch2,
				    dev->_dma_virt_addr_ch2,
				    dev->_dma_phys_addr_ch2);
		dev->_dma_virt_addr_ch2 = NULL;
	}

	if (dev->_data_buf_virt_addr_ch2) {
		pci_free_consistent(dev->pci, dev->_data_buf_size_ch2,
				    dev->_data_buf_virt_addr_ch2,
				    dev->_data_buf_phys_addr_ch2);
		dev->_data_buf_virt_addr_ch2 = NULL;
	}
}

static int cx25821_get_frame_ch2(struct cx25821_dev *dev,
				 struct sram_channel *sram_ch)
{
	struct file *myfile;
	int frame_index_temp = dev->_frame_index_ch2;
	int i = 0;
	int line_size = (dev->_pixel_format_ch2 == 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_ch2 == END_OF_FILE)
		return 0;

	if (dev->_isNTSC_ch2) {
		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_ch2 * frame_size;

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

		if (!myfile->f_op->read) {
			pr_err("%s(): File has no READ operations registered!\n",
			       __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_ch2; 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_ch2 != NULL) {
				memcpy((void *)(dev->_data_buf_virt_addr_ch2 +
						frame_offset / 4), mybuf,
						vfs_read_retval);
			}

			file_offset += vfs_read_retval;
			frame_offset += vfs_read_retval;

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

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

		dev->_file_status_ch2 = (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_ch2(struct work_struct *work)
{
	struct cx25821_dev *dev = container_of(work, struct cx25821_dev,
			_irq_work_entry_ch2);

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

	cx25821_get_frame_ch2(dev, dev->channels[dev->
			_channel2_upstream_select].sram_channels);
}

static int cx25821_openfile_ch2(struct cx25821_dev *dev,
				struct sram_channel *sram_ch)
{
	struct file *myfile;
	int i = 0, j = 0;
	int line_size = (dev->_pixel_format_ch2 == 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_ch2, O_RDONLY | O_LARGEFILE, 0);

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

		if (!myfile->f_op->read) {
			pr_err("%s(): File has no READ operations registered!  Returning\n",
			       __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_ch2; 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_ch2 != NULL) {
					memcpy((void *)(dev->
							_data_buf_virt_addr_ch2
							+ offset / 4), mybuf,
							vfs_read_retval);
				}

				offset += vfs_read_retval;

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

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

			if (vfs_read_retval < line_size)
				break;
		}

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

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

	return 0;
}

static int cx25821_upstream_buffer_prepare_ch2(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_ch2 != NULL) {
		pci_free_consistent(dev->pci, dev->upstream_riscbuf_size_ch2,
				    dev->_dma_virt_addr_ch2,
				    dev->_dma_phys_addr_ch2);
	}

	dev->_dma_virt_addr_ch2 = pci_alloc_consistent(dev->pci,
			dev->upstream_riscbuf_size_ch2, &dma_addr);
	dev->_dma_virt_start_addr_ch2 = dev->_dma_virt_addr_ch2;
	dev->_dma_phys_start_addr_ch2 = dma_addr;
	dev->_dma_phys_addr_ch2 = dma_addr;
	dev->_risc_size_ch2 = dev->upstream_riscbuf_size_ch2;

	if (!dev->_dma_virt_addr_ch2) {
		pr_err("FAILED to allocate memory for Risc buffer! Returning\n");
		return -ENOMEM;
	}

	/* Iniitize at this address until n bytes to 0 */
	memset(dev->_dma_virt_addr_ch2, 0, dev->_risc_size_ch2);

	if (dev->_data_buf_virt_addr_ch2 != NULL) {
		pci_free_consistent(dev->pci, dev->upstream_databuf_size_ch2,
				    dev->_data_buf_virt_addr_ch2,
				    dev->_data_buf_phys_addr_ch2);
	}
	/* For Video Data buffer allocation */
	dev->_data_buf_virt_addr_ch2 = pci_alloc_consistent(dev->pci,
			dev->upstream_databuf_size_ch2, &data_dma_addr);
	dev->_data_buf_phys_addr_ch2 = data_dma_addr;
	dev->_data_buf_size_ch2 = dev->upstream_databuf_size_ch2;

	if (!dev->_data_buf_virt_addr_ch2) {
		pr_err("FAILED to allocate memory for data buffer! Returning\n");
		return -ENOMEM;
	}

	/* Initialize at this address until n bytes to 0 */
	memset(dev->_data_buf_virt_addr_ch2, 0, dev->_data_buf_size_ch2);

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

	/* Creating RISC programs */
	ret = cx25821_risc_buffer_upstream_ch2(dev, dev->pci, 0, bpl,
						dev->_lines_count_ch2);
	if (ret < 0) {
		pr_info("Failed creating Video Upstream Risc programs!\n");
		goto error;
	}

	return 0;

error:
	return ret;
}

static int cx25821_video_upstream_irq_ch2(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_ch2 = prog_cnt;

		queue_work(dev->_irq_queues_ch2, &dev->_irq_work_entry_ch2);

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

			if (dev->_isNTSC_ch2) {
				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_ch2 != NULL) {
				if (dev->_pixel_format_ch2 == PIXEL_FRMT_411)
					line_size_in_bytes = Y411_LINE_SZ;
				else
					line_size_in_bytes = Y422_LINE_SZ;
				risc_phys_jump_addr =
					dev->_dma_phys_start_addr_ch2 +
					odd_risc_prog_size;

				rp = cx25821_update_riscprogram_ch2(dev,
						dev->_dma_virt_start_addr_ch2,
						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);
	}

	if (dev->_file_status_ch2 == END_OF_FILE) {
		pr_info("EOF Channel 2 Framecount = %d\n",
			dev->_frame_count_ch2);
		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_ch2(int irq, void *dev_id)
{
	struct cx25821_dev *dev = dev_id;
	u32 vid_status;
	int handled = 0;
	int channel_num = 0;
	struct sram_channel *sram_ch;

	if (!dev)
		return -1;

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

	vid_status = cx_read(sram_ch->int_stat);

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

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

	return IRQ_RETVAL(handled);
}

static void cx25821_set_pixelengine_ch2(struct cx25821_dev *dev,
					struct sram_channel *ch, int pix_format)
{
	int width = WIDTH_D1;
	int height = dev->_lines_count_ch2;
	int num_lines, odd_num_lines;
	u32 value;
	int vip_mode = PIXEL_ENGINE_VIP1;

	value = ((pix_format & 0x3) << 12) | (vip_mode & 0x7);
	value &= 0xFFFFFFEF;
	value |= dev->_isNTSC_ch2 ? 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_ch2)
		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);
}

static int cx25821_start_video_dma_upstream_ch2(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_ch2);
	cx_write(sram_ch->cmds_start + 4, 0); /* Risc IPC High 64 bits 63-32 */

	/* 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_ch2,
			IRQF_SHARED, dev->name, dev);
	if (err < 0) {
		pr_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_ch2 = 1;
	dev->_is_first_frame_ch2 = 1;

	return 0;

fail_irq:
	cx25821_dev_unregister(dev);
	return err;
}

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

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

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

	INIT_WORK(&dev->_irq_work_entry_ch2, cx25821_vidups_handler_ch2);
	dev->_irq_queues_ch2 =
	    create_singlethread_workqueue("cx25821_workqueue2");

	if (!dev->_irq_queues_ch2) {
		pr_err("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_ch2 = 0;
	dev->_frame_count_ch2 = 0;
	dev->_file_status_ch2 = RESET_STATUS;
	dev->_lines_count_ch2 = dev->_isNTSC_ch2 ? 480 : 576;
	dev->_pixel_format_ch2 = pixel_format;
	dev->_line_size_ch2 = (dev->_pixel_format_ch2 == PIXEL_FRMT_422) ?
		(WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2;
	data_frame_size = dev->_isNTSC_ch2 ? NTSC_DATA_BUF_SZ : PAL_DATA_BUF_SZ;
	risc_buffer_size = dev->_isNTSC_ch2 ?
		NTSC_RISC_BUF_SIZE : PAL_RISC_BUF_SIZE;

	if (dev->input_filename_ch2)
		dev->_filename_ch2 = kstrdup(dev->input_filename_ch2,
								GFP_KERNEL);
	else
		dev->_filename_ch2 = kstrdup(dev->_defaultname_ch2,
								GFP_KERNEL);

	if (!dev->_filename_ch2) {
		err = -ENOENT;
		goto error;
	}

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

	err = cx25821_sram_channel_setup_upstream(dev, sram_ch,
						dev->_line_size_ch2, 0);

	/* setup fifo + format */
	cx25821_set_pixelengine_ch2(dev, sram_ch, dev->_pixel_format_ch2);

	dev->upstream_riscbuf_size_ch2 = risc_buffer_size * 2;
	dev->upstream_databuf_size_ch2 = data_frame_size * 2;

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

	cx25821_start_video_dma_upstream_ch2(dev, sram_ch);

	return 0;

error:
	cx25821_dev_unregister(dev);

	return err;
}
