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

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

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

	//Set the line length       (It looks like we do not need to set the line length)
	cx_write(sram_ch->aud_length, AUDIO_LINE_SIZE & FLD_AUD_DST_LN_LNGTH);

	//Set the input mode to 16-bit
	tmp = cx_read(sram_ch->aud_cfg);
	tmp |=
	    FLD_AUD_SRC_ENABLE | FLD_AUD_DST_PK_MODE | FLD_AUD_CLK_ENABLE |
	    FLD_AUD_MASTER_MODE | FLD_AUD_CLK_SELECT_PLL_D | FLD_AUD_SONY_MODE;
	cx_write(sram_ch->aud_cfg, tmp);

	// Read and write back the interrupt status register to clear it
	tmp = cx_read(sram_ch->int_stat);
	cx_write(sram_ch->int_stat, tmp);

	// 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_audio,
			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 | sram_ch->fld_aud_risc_en);

	dev->_audio_is_running = 1;
	dev->_is_first_audio_frame = 1;

	// The fifo_en bit turns on by the first Risc program
	cx25821_wait_fifo_enable(dev, sram_ch);

	return 0;

      fail_irq:
	cx25821_dev_unregister(dev);
	return err;
}
static int cx25821_start_video_dma_upstream(struct cx25821_channel *chan,
					    const struct sram_channel *sram_ch)
{
	struct cx25821_video_out_data *out = chan->out;
	struct cx25821_dev *dev = chan->dev;
	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, out->_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, dev->name, chan);
	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);

	out->_is_running = 1;
	out->_is_first_frame = 1;

	return 0;

fail_irq:
	cx25821_dev_unregister(dev);
	return err;
}
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 | 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_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 retval = 0;
	int err = 0;
	int data_frame_size = 0;
	int risc_buffer_size = 0;
	int str_length = 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) {
		str_length = strlen(dev->input_filename_ch2);
		dev->_filename_ch2 = kmemdup(dev->input_filename_ch2,
					     str_length + 1, GFP_KERNEL);

		if (!dev->_filename_ch2)
			goto error;
	} else {
		str_length = strlen(dev->_defaultname_ch2);
		dev->_filename_ch2 = kmemdup(dev->_defaultname_ch2,
					     str_length + 1, GFP_KERNEL);

		if (!dev->_filename_ch2)
			goto error;
	}

	/* Default if filename is empty string */
	if (strcmp(dev->input_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";
		}
	}

	retval = 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 */
	retval = cx25821_upstream_buffer_prepare_ch2(dev, sram_ch,
						dev->_line_size_ch2);
	if (retval < 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;
}
int cx25821_audio_upstream_init(struct cx25821_dev *dev, int channel_select)
{
	struct sram_channel *sram_ch;
	int err = 0;

	if (dev->_audio_is_running) {
		pr_warn("Audio Channel is still running so return!\n");
		return 0;
	}

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

	/* Work queue */
	INIT_WORK(&dev->_audio_work_entry, cx25821_audioups_handler);
	dev->_irq_audio_queues =
	    create_singlethread_workqueue("cx25821_audioworkqueue");

	if (!dev->_irq_audio_queues) {
		printk(KERN_DEBUG
			pr_fmt("ERROR: create_singlethread_workqueue() for Audio FAILED!\n"));
		return -ENOMEM;
	}

	dev->_last_index_irq = 0;
	dev->_audio_is_running = 0;
	dev->_audioframe_count = 0;
	dev->_audiofile_status = RESET_STATUS;
	dev->_audio_lines_count = LINES_PER_AUDIO_BUFFER;
	_line_size = AUDIO_LINE_SIZE;

	if (dev->input_audiofilename) {
		dev->_audiofilename = kstrdup(dev->input_audiofilename,
					      GFP_KERNEL);

		if (!dev->_audiofilename) {
			err = -ENOMEM;
			goto error;
		}

		/* Default if filename is empty string */
		if (strcmp(dev->input_audiofilename, "") == 0)
			dev->_audiofilename = "/root/audioGOOD.wav";
	} else {
		dev->_audiofilename = kstrdup(_defaultAudioName,
					      GFP_KERNEL);

		if (!dev->_audiofilename) {
			err = -ENOMEM;
			goto error;
		}
	}

	cx25821_sram_channel_setup_upstream_audio(dev, sram_ch,
						  _line_size, 0);

	dev->audio_upstream_riscbuf_size =
		AUDIO_RISC_DMA_BUF_SIZE * NUM_AUDIO_PROGS +
		RISC_SYNC_INSTRUCTION_SIZE;
	dev->audio_upstream_databuf_size = AUDIO_DATA_BUF_SZ * NUM_AUDIO_PROGS;

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

	return 0;

error:
	cx25821_dev_unregister(dev);

	return err;
}
int cx25821_audio_upstream_init(struct cx25821_dev *dev, int channel_select)
{
	struct sram_channel *sram_ch;
	int retval = 0;
	int err = 0;
	int str_length = 0;

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

	dev->_audio_upstream_channel_select = channel_select;
	sram_ch = &dev->sram_channels[channel_select];

	//Work queue
	INIT_WORK(&dev->_audio_work_entry, cx25821_audioups_handler);
	dev->_irq_audio_queues =
	    create_singlethread_workqueue("cx25821_audioworkqueue");

	if (!dev->_irq_audio_queues) {
		printk
		    ("cx25821 ERROR: create_singlethread_workqueue() for Audio FAILED!\n");
		return -ENOMEM;
	}

	dev->_last_index_irq = 0;
	dev->_audio_is_running = 0;
	dev->_audioframe_count = 0;
	dev->_audiofile_status = RESET_STATUS;
	dev->_audio_lines_count = LINES_PER_AUDIO_BUFFER;
	_line_size = AUDIO_LINE_SIZE;

	if (dev->input_audiofilename) {
		str_length = strlen(dev->input_audiofilename);
		dev->_audiofilename =
		    (char *)kmalloc(str_length + 1, GFP_KERNEL);

		if (!dev->_audiofilename)
			goto error;

		memcpy(dev->_audiofilename, dev->input_audiofilename,
		       str_length + 1);

		//Default if filename is empty string
		if (strcmp(dev->input_audiofilename, "") == 0) {
			dev->_audiofilename = "/root/audioGOOD.wav";
		}
	} else {
		str_length = strlen(_defaultAudioName);
		dev->_audiofilename =
		    (char *)kmalloc(str_length + 1, GFP_KERNEL);

		if (!dev->_audiofilename)
			goto error;

		memcpy(dev->_audiofilename, _defaultAudioName, str_length + 1);
	}

	retval =
	    cx25821_sram_channel_setup_upstream_audio(dev, sram_ch, _line_size,
						      0);

	dev->audio_upstream_riscbuf_size =
	    AUDIO_RISC_DMA_BUF_SIZE * NUM_AUDIO_PROGS +
	    RISC_SYNC_INSTRUCTION_SIZE;
	dev->audio_upstream_databuf_size = AUDIO_DATA_BUF_SZ * NUM_AUDIO_PROGS;

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

	return 0;

      error:
	cx25821_dev_unregister(dev);

	return err;
}
int cx25821_vidupstream_init(struct cx25821_channel *chan,
				 int pixel_format)
{
	struct cx25821_video_out_data *out = chan->out;
	struct cx25821_dev *dev = chan->dev;
	const struct sram_channel *sram_ch;
	u32 tmp;
	int err = 0;
	int data_frame_size = 0;
	int risc_buffer_size = 0;

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

	sram_ch = chan->sram_channels;

	out->is_60hz = dev->tvnorm & V4L2_STD_525_60;

	/* 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);

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

	out->_is_running = 0;
	out->_frame_count = 0;
	out->_file_status = RESET_STATUS;
	out->_lines_count = out->is_60hz ? 480 : 576;
	out->_pixel_format = pixel_format;
	out->_line_size = (out->_pixel_format == PIXEL_FRMT_422) ?
		(WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2;
	out->curpos = 0;
	init_waitqueue_head(&out->waitq);

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

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

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

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

	cx25821_start_video_dma_upstream(chan, sram_ch);

	return 0;

error:
	cx25821_dev_unregister(dev);

	return err;
}