Linux Audio

Check our new training course

Real-Time Linux with PREEMPT_RT training

Feb 18-20, 2025
Register
Loading...
Note: File does not exist in v4.17.
  1/*
  2 *  Driver for the Conexant CX25821 PCIe bridge
  3 *
  4 *  Copyright (C) 2009 Conexant Systems Inc.
  5 *  Authors  <hiep.huynh@conexant.com>, <shu.lin@conexant.com>
  6 *
  7 *  This program is free software; you can redistribute it and/or modify
  8 *  it under the terms of the GNU General Public License as published by
  9 *  the Free Software Foundation; either version 2 of the License, or
 10 *  (at your option) any later version.
 11 *
 12 *  This program is distributed in the hope that it will be useful,
 13 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 14 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 15 *
 16 *  GNU General Public License for more details.
 17 *
 18 *  You should have received a copy of the GNU General Public License
 19 *  along with this program; if not, write to the Free Software
 20 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 21 */
 22
 23#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 24
 25#include "cx25821-video.h"
 26#include "cx25821-video-upstream.h"
 27
 28#include <linux/fs.h>
 29#include <linux/errno.h>
 30#include <linux/kernel.h>
 31#include <linux/init.h>
 32#include <linux/module.h>
 33#include <linux/syscalls.h>
 34#include <linux/file.h>
 35#include <linux/fcntl.h>
 36#include <linux/slab.h>
 37#include <linux/uaccess.h>
 38
 39MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards");
 40MODULE_AUTHOR("Hiep Huynh <hiep.huynh@conexant.com>");
 41MODULE_LICENSE("GPL");
 42
 43static int _intr_msk = FLD_VID_SRC_RISC1 | FLD_VID_SRC_UF | FLD_VID_SRC_SYNC |
 44			FLD_VID_SRC_OPC_ERR;
 45
 46int cx25821_sram_channel_setup_upstream(struct cx25821_dev *dev,
 47					struct sram_channel *ch,
 48					unsigned int bpl, u32 risc)
 49{
 50	unsigned int i, lines;
 51	u32 cdt;
 52
 53	if (ch->cmds_start == 0) {
 54		cx_write(ch->ptr1_reg, 0);
 55		cx_write(ch->ptr2_reg, 0);
 56		cx_write(ch->cnt2_reg, 0);
 57		cx_write(ch->cnt1_reg, 0);
 58		return 0;
 59	}
 60
 61	bpl = (bpl + 7) & ~7;	/* alignment */
 62	cdt = ch->cdt;
 63	lines = ch->fifo_size / bpl;
 64
 65	if (lines > 4)
 66		lines = 4;
 67
 68	BUG_ON(lines < 2);
 69
 70	/* write CDT */
 71	for (i = 0; i < lines; i++) {
 72		cx_write(cdt + 16 * i, ch->fifo_start + bpl * i);
 73		cx_write(cdt + 16 * i + 4, 0);
 74		cx_write(cdt + 16 * i + 8, 0);
 75		cx_write(cdt + 16 * i + 12, 0);
 76	}
 77
 78	/* write CMDS */
 79	cx_write(ch->cmds_start + 0, risc);
 80
 81	cx_write(ch->cmds_start + 4, 0);
 82	cx_write(ch->cmds_start + 8, cdt);
 83	cx_write(ch->cmds_start + 12, (lines * 16) >> 3);
 84	cx_write(ch->cmds_start + 16, ch->ctrl_start);
 85
 86	cx_write(ch->cmds_start + 20, VID_IQ_SIZE_DW);
 87
 88	for (i = 24; i < 80; i += 4)
 89		cx_write(ch->cmds_start + i, 0);
 90
 91	/* fill registers */
 92	cx_write(ch->ptr1_reg, ch->fifo_start);
 93	cx_write(ch->ptr2_reg, cdt);
 94	cx_write(ch->cnt2_reg, (lines * 16) >> 3);
 95	cx_write(ch->cnt1_reg, (bpl >> 3) - 1);
 96
 97	return 0;
 98}
 99
100static __le32 *cx25821_update_riscprogram(struct cx25821_dev *dev,
101					  __le32 *rp, unsigned int offset,
102					  unsigned int bpl, u32 sync_line,
103					  unsigned int lines, int fifo_enable,
104					  int field_type)
105{
106	unsigned int line, i;
107	int dist_betwn_starts = bpl * 2;
108
109	*(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
110
111	if (USE_RISC_NOOP_VIDEO) {
112		for (i = 0; i < NUM_NO_OPS; i++)
113			*(rp++) = cpu_to_le32(RISC_NOOP);
114	}
115
116	/* scan lines */
117	for (line = 0; line < lines; line++) {
118		*(rp++) = cpu_to_le32(RISC_READ | RISC_SOL | RISC_EOL | bpl);
119		*(rp++) = cpu_to_le32(dev->_data_buf_phys_addr + offset);
120		*(rp++) = cpu_to_le32(0);	/* bits 63-32 */
121
122		if ((lines <= NTSC_FIELD_HEIGHT)
123		    || (line < (NTSC_FIELD_HEIGHT - 1)) || !(dev->_isNTSC)) {
124			offset += dist_betwn_starts;
125		}
126	}
127
128	return rp;
129}
130
131static __le32 *cx25821_risc_field_upstream(struct cx25821_dev *dev, __le32 * rp,
132					   dma_addr_t databuf_phys_addr,
133					   unsigned int offset, u32 sync_line,
134					   unsigned int bpl, unsigned int lines,
135					   int fifo_enable, int field_type)
136{
137	unsigned int line, i;
138	struct sram_channel *sram_ch =
139		dev->channels[dev->_channel_upstream_select].sram_channels;
140	int dist_betwn_starts = bpl * 2;
141
142	/* sync instruction */
143	if (sync_line != NO_SYNC_LINE)
144		*(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
145
146	if (USE_RISC_NOOP_VIDEO) {
147		for (i = 0; i < NUM_NO_OPS; i++)
148			*(rp++) = cpu_to_le32(RISC_NOOP);
149	}
150
151	/* scan lines */
152	for (line = 0; line < lines; line++) {
153		*(rp++) = cpu_to_le32(RISC_READ | RISC_SOL | RISC_EOL | bpl);
154		*(rp++) = cpu_to_le32(databuf_phys_addr + offset);
155		*(rp++) = cpu_to_le32(0);	/* bits 63-32 */
156
157		if ((lines <= NTSC_FIELD_HEIGHT)
158		    || (line < (NTSC_FIELD_HEIGHT - 1)) || !(dev->_isNTSC))
159			/* to skip the other field line */
160			offset += dist_betwn_starts;
161
162		/* check if we need to enable the FIFO after the first 4 lines
163		 * For the upstream video channel, the risc engine will enable
164		 * the FIFO. */
165		if (fifo_enable && line == 3) {
166			*(rp++) = RISC_WRITECR;
167			*(rp++) = sram_ch->dma_ctl;
168			*(rp++) = FLD_VID_FIFO_EN;
169			*(rp++) = 0x00000001;
170		}
171	}
172
173	return rp;
174}
175
176int cx25821_risc_buffer_upstream(struct cx25821_dev *dev,
177				 struct pci_dev *pci,
178				 unsigned int top_offset,
179				 unsigned int bpl, unsigned int lines)
180{
181	__le32 *rp;
182	int fifo_enable = 0;
183	/* get line count for single field */
184	int singlefield_lines = lines >> 1;
185	int odd_num_lines = singlefield_lines;
186	int frame = 0;
187	int frame_size = 0;
188	int databuf_offset = 0;
189	int risc_program_size = 0;
190	int risc_flag = RISC_CNT_RESET;
191	unsigned int bottom_offset = bpl;
192	dma_addr_t risc_phys_jump_addr;
193
194	if (dev->_isNTSC) {
195		odd_num_lines = singlefield_lines + 1;
196		risc_program_size = FRAME1_VID_PROG_SIZE;
197		frame_size = (bpl == Y411_LINE_SZ) ?
198			FRAME_SIZE_NTSC_Y411 : FRAME_SIZE_NTSC_Y422;
199	} else {
200		risc_program_size = PAL_VID_PROG_SIZE;
201		frame_size = (bpl == Y411_LINE_SZ) ?
202			FRAME_SIZE_PAL_Y411 : FRAME_SIZE_PAL_Y422;
203	}
204
205	/* Virtual address of Risc buffer program */
206	rp = dev->_dma_virt_addr;
207
208	for (frame = 0; frame < NUM_FRAMES; frame++) {
209		databuf_offset = frame_size * frame;
210
211		if (UNSET != top_offset) {
212			fifo_enable = (frame == 0) ? FIFO_ENABLE : FIFO_DISABLE;
213			rp = cx25821_risc_field_upstream(dev, rp,
214					dev->_data_buf_phys_addr +
215					databuf_offset, top_offset, 0, bpl,
216					odd_num_lines, fifo_enable, ODD_FIELD);
217		}
218
219		fifo_enable = FIFO_DISABLE;
220
221		/* Even Field */
222		rp = cx25821_risc_field_upstream(dev, rp,
223						 dev->_data_buf_phys_addr +
224						 databuf_offset, bottom_offset,
225						 0x200, bpl, singlefield_lines,
226						 fifo_enable, EVEN_FIELD);
227
228		if (frame == 0) {
229			risc_flag = RISC_CNT_RESET;
230			risc_phys_jump_addr = dev->_dma_phys_start_addr +
231				risc_program_size;
232		} else {
233			risc_phys_jump_addr = dev->_dma_phys_start_addr;
234			risc_flag = RISC_CNT_INC;
235		}
236
237		/* Loop to 2ndFrameRISC or to Start of Risc
238		 * program & generate IRQ
239		 */
240		*(rp++) = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | risc_flag);
241		*(rp++) = cpu_to_le32(risc_phys_jump_addr);
242		*(rp++) = cpu_to_le32(0);
243	}
244
245	return 0;
246}
247
248void cx25821_stop_upstream_video_ch1(struct cx25821_dev *dev)
249{
250	struct sram_channel *sram_ch =
251		dev->channels[VID_UPSTREAM_SRAM_CHANNEL_I].sram_channels;
252	u32 tmp = 0;
253
254	if (!dev->_is_running) {
255		pr_info("No video file is currently running so return!\n");
256		return;
257	}
258	/* Disable RISC interrupts */
259	tmp = cx_read(sram_ch->int_msk);
260	cx_write(sram_ch->int_msk, tmp & ~_intr_msk);
261
262	/* Turn OFF risc and fifo enable */
263	tmp = cx_read(sram_ch->dma_ctl);
264	cx_write(sram_ch->dma_ctl, tmp & ~(FLD_VID_FIFO_EN | FLD_VID_RISC_EN));
265
266	/* Clear data buffer memory */
267	if (dev->_data_buf_virt_addr)
268		memset(dev->_data_buf_virt_addr, 0, dev->_data_buf_size);
269
270	dev->_is_running = 0;
271	dev->_is_first_frame = 0;
272	dev->_frame_count = 0;
273	dev->_file_status = END_OF_FILE;
274
275	kfree(dev->_irq_queues);
276	dev->_irq_queues = NULL;
277
278	kfree(dev->_filename);
279
280	tmp = cx_read(VID_CH_MODE_SEL);
281	cx_write(VID_CH_MODE_SEL, tmp & 0xFFFFFE00);
282}
283
284void cx25821_free_mem_upstream_ch1(struct cx25821_dev *dev)
285{
286	if (dev->_is_running)
287		cx25821_stop_upstream_video_ch1(dev);
288
289	if (dev->_dma_virt_addr) {
290		pci_free_consistent(dev->pci, dev->_risc_size,
291				    dev->_dma_virt_addr, dev->_dma_phys_addr);
292		dev->_dma_virt_addr = NULL;
293	}
294
295	if (dev->_data_buf_virt_addr) {
296		pci_free_consistent(dev->pci, dev->_data_buf_size,
297				    dev->_data_buf_virt_addr,
298				    dev->_data_buf_phys_addr);
299		dev->_data_buf_virt_addr = NULL;
300	}
301}
302
303int cx25821_get_frame(struct cx25821_dev *dev, struct sram_channel *sram_ch)
304{
305	struct file *myfile;
306	int frame_index_temp = dev->_frame_index;
307	int i = 0;
308	int line_size = (dev->_pixel_format == PIXEL_FRMT_411) ?
309		Y411_LINE_SZ : Y422_LINE_SZ;
310	int frame_size = 0;
311	int frame_offset = 0;
312	ssize_t vfs_read_retval = 0;
313	char mybuf[line_size];
314	loff_t file_offset;
315	loff_t pos;
316	mm_segment_t old_fs;
317
318	if (dev->_file_status == END_OF_FILE)
319		return 0;
320
321	if (dev->_isNTSC)
322		frame_size = (line_size == Y411_LINE_SZ) ?
323			FRAME_SIZE_NTSC_Y411 : FRAME_SIZE_NTSC_Y422;
324	else
325		frame_size = (line_size == Y411_LINE_SZ) ?
326			FRAME_SIZE_PAL_Y411 : FRAME_SIZE_PAL_Y422;
327
328	frame_offset = (frame_index_temp > 0) ? frame_size : 0;
329	file_offset = dev->_frame_count * frame_size;
330
331	myfile = filp_open(dev->_filename, O_RDONLY | O_LARGEFILE, 0);
332
333	if (IS_ERR(myfile)) {
334		const int open_errno = -PTR_ERR(myfile);
335		pr_err("%s(): ERROR opening file(%s) with errno = %d!\n",
336		       __func__, dev->_filename, open_errno);
337		return PTR_ERR(myfile);
338	} else {
339		if (!(myfile->f_op)) {
340			pr_err("%s(): File has no file operations registered!\n",
341			       __func__);
342			filp_close(myfile, NULL);
343			return -EIO;
344		}
345
346		if (!myfile->f_op->read) {
347			pr_err("%s(): File has no READ operations registered!\n",
348			       __func__);
349			filp_close(myfile, NULL);
350			return -EIO;
351		}
352
353		pos = myfile->f_pos;
354		old_fs = get_fs();
355		set_fs(KERNEL_DS);
356
357		for (i = 0; i < dev->_lines_count; i++) {
358			pos = file_offset;
359
360			vfs_read_retval = vfs_read(myfile, mybuf, line_size,
361					&pos);
362
363			if (vfs_read_retval > 0 && vfs_read_retval == line_size
364			    && dev->_data_buf_virt_addr != NULL) {
365				memcpy((void *)(dev->_data_buf_virt_addr +
366						frame_offset / 4), mybuf,
367				       vfs_read_retval);
368			}
369
370			file_offset += vfs_read_retval;
371			frame_offset += vfs_read_retval;
372
373			if (vfs_read_retval < line_size) {
374				pr_info("Done: exit %s() since no more bytes to read from Video file\n",
375					__func__);
376				break;
377			}
378		}
379
380		if (i > 0)
381			dev->_frame_count++;
382
383		dev->_file_status = (vfs_read_retval == line_size) ?
384			IN_PROGRESS : END_OF_FILE;
385
386		set_fs(old_fs);
387		filp_close(myfile, NULL);
388	}
389
390	return 0;
391}
392
393static void cx25821_vidups_handler(struct work_struct *work)
394{
395	struct cx25821_dev *dev = container_of(work, struct cx25821_dev,
396			_irq_work_entry);
397
398	if (!dev) {
399		pr_err("ERROR %s(): since container_of(work_struct) FAILED!\n",
400		       __func__);
401		return;
402	}
403
404	cx25821_get_frame(dev, dev->channels[dev->_channel_upstream_select].
405			sram_channels);
406}
407
408int cx25821_openfile(struct cx25821_dev *dev, struct sram_channel *sram_ch)
409{
410	struct file *myfile;
411	int i = 0, j = 0;
412	int line_size = (dev->_pixel_format == PIXEL_FRMT_411) ?
413		Y411_LINE_SZ : Y422_LINE_SZ;
414	ssize_t vfs_read_retval = 0;
415	char mybuf[line_size];
416	loff_t pos;
417	loff_t offset = (unsigned long)0;
418	mm_segment_t old_fs;
419
420	myfile = filp_open(dev->_filename, O_RDONLY | O_LARGEFILE, 0);
421
422	if (IS_ERR(myfile)) {
423		const int open_errno = -PTR_ERR(myfile);
424		pr_err("%s(): ERROR opening file(%s) with errno = %d!\n",
425		       __func__, dev->_filename, open_errno);
426		return PTR_ERR(myfile);
427	} else {
428		if (!(myfile->f_op)) {
429			pr_err("%s(): File has no file operations registered!\n",
430			       __func__);
431			filp_close(myfile, NULL);
432			return -EIO;
433		}
434
435		if (!myfile->f_op->read) {
436			pr_err("%s(): File has no READ operations registered!  Returning\n",
437			       __func__);
438			filp_close(myfile, NULL);
439			return -EIO;
440		}
441
442		pos = myfile->f_pos;
443		old_fs = get_fs();
444		set_fs(KERNEL_DS);
445
446		for (j = 0; j < NUM_FRAMES; j++) {
447			for (i = 0; i < dev->_lines_count; i++) {
448				pos = offset;
449
450				vfs_read_retval = vfs_read(myfile, mybuf,
451						line_size, &pos);
452
453				if (vfs_read_retval > 0
454				    && vfs_read_retval == line_size
455				    && dev->_data_buf_virt_addr != NULL) {
456					memcpy((void *)(dev->
457							_data_buf_virt_addr +
458							offset / 4), mybuf,
459					       vfs_read_retval);
460				}
461
462				offset += vfs_read_retval;
463
464				if (vfs_read_retval < line_size) {
465					pr_info("Done: exit %s() since no more bytes to read from Video file\n",
466						__func__);
467					break;
468				}
469			}
470
471			if (i > 0)
472				dev->_frame_count++;
473
474			if (vfs_read_retval < line_size)
475				break;
476		}
477
478		dev->_file_status = (vfs_read_retval == line_size) ?
479			IN_PROGRESS : END_OF_FILE;
480
481		set_fs(old_fs);
482		myfile->f_pos = 0;
483		filp_close(myfile, NULL);
484	}
485
486	return 0;
487}
488
489int cx25821_upstream_buffer_prepare(struct cx25821_dev *dev,
490				    struct sram_channel *sram_ch, int bpl)
491{
492	int ret = 0;
493	dma_addr_t dma_addr;
494	dma_addr_t data_dma_addr;
495
496	if (dev->_dma_virt_addr != NULL)
497		pci_free_consistent(dev->pci, dev->upstream_riscbuf_size,
498				dev->_dma_virt_addr, dev->_dma_phys_addr);
499
500	dev->_dma_virt_addr = pci_alloc_consistent(dev->pci,
501			dev->upstream_riscbuf_size, &dma_addr);
502	dev->_dma_virt_start_addr = dev->_dma_virt_addr;
503	dev->_dma_phys_start_addr = dma_addr;
504	dev->_dma_phys_addr = dma_addr;
505	dev->_risc_size = dev->upstream_riscbuf_size;
506
507	if (!dev->_dma_virt_addr) {
508		pr_err("FAILED to allocate memory for Risc buffer! Returning\n");
509		return -ENOMEM;
510	}
511
512	/* Clear memory at address */
513	memset(dev->_dma_virt_addr, 0, dev->_risc_size);
514
515	if (dev->_data_buf_virt_addr != NULL)
516		pci_free_consistent(dev->pci, dev->upstream_databuf_size,
517				dev->_data_buf_virt_addr,
518				dev->_data_buf_phys_addr);
519	/* For Video Data buffer allocation */
520	dev->_data_buf_virt_addr = pci_alloc_consistent(dev->pci,
521			dev->upstream_databuf_size, &data_dma_addr);
522	dev->_data_buf_phys_addr = data_dma_addr;
523	dev->_data_buf_size = dev->upstream_databuf_size;
524
525	if (!dev->_data_buf_virt_addr) {
526		pr_err("FAILED to allocate memory for data buffer! Returning\n");
527		return -ENOMEM;
528	}
529
530	/* Clear memory at address */
531	memset(dev->_data_buf_virt_addr, 0, dev->_data_buf_size);
532
533	ret = cx25821_openfile(dev, sram_ch);
534	if (ret < 0)
535		return ret;
536
537	/* Create RISC programs */
538	ret = cx25821_risc_buffer_upstream(dev, dev->pci, 0, bpl,
539			dev->_lines_count);
540	if (ret < 0) {
541		pr_info("Failed creating Video Upstream Risc programs!\n");
542		goto error;
543	}
544
545	return 0;
546
547error:
548	return ret;
549}
550
551int cx25821_video_upstream_irq(struct cx25821_dev *dev, int chan_num,
552			       u32 status)
553{
554	u32 int_msk_tmp;
555	struct sram_channel *channel = dev->channels[chan_num].sram_channels;
556	int singlefield_lines = NTSC_FIELD_HEIGHT;
557	int line_size_in_bytes = Y422_LINE_SZ;
558	int odd_risc_prog_size = 0;
559	dma_addr_t risc_phys_jump_addr;
560	__le32 *rp;
561
562	if (status & FLD_VID_SRC_RISC1) {
563		/* We should only process one program per call */
564		u32 prog_cnt = cx_read(channel->gpcnt);
565
566		/* Since we've identified our IRQ, clear our bits from the
567		 * interrupt mask and interrupt status registers */
568		int_msk_tmp = cx_read(channel->int_msk);
569		cx_write(channel->int_msk, int_msk_tmp & ~_intr_msk);
570		cx_write(channel->int_stat, _intr_msk);
571
572		spin_lock(&dev->slock);
573
574		dev->_frame_index = prog_cnt;
575
576		queue_work(dev->_irq_queues, &dev->_irq_work_entry);
577
578		if (dev->_is_first_frame) {
579			dev->_is_first_frame = 0;
580
581			if (dev->_isNTSC) {
582				singlefield_lines += 1;
583				odd_risc_prog_size = ODD_FLD_NTSC_PROG_SIZE;
584			} else {
585				singlefield_lines = PAL_FIELD_HEIGHT;
586				odd_risc_prog_size = ODD_FLD_PAL_PROG_SIZE;
587			}
588
589			if (dev->_dma_virt_start_addr != NULL) {
590				line_size_in_bytes =
591				    (dev->_pixel_format ==
592				     PIXEL_FRMT_411) ? Y411_LINE_SZ :
593				    Y422_LINE_SZ;
594				risc_phys_jump_addr =
595				    dev->_dma_phys_start_addr +
596				    odd_risc_prog_size;
597
598				rp = cx25821_update_riscprogram(dev,
599					dev->_dma_virt_start_addr, TOP_OFFSET,
600					line_size_in_bytes, 0x0,
601					singlefield_lines, FIFO_DISABLE,
602					ODD_FIELD);
603
604				/* Jump to Even Risc program of 1st Frame */
605				*(rp++) = cpu_to_le32(RISC_JUMP);
606				*(rp++) = cpu_to_le32(risc_phys_jump_addr);
607				*(rp++) = cpu_to_le32(0);
608			}
609		}
610
611		spin_unlock(&dev->slock);
612	} else {
613		if (status & FLD_VID_SRC_UF)
614			pr_err("%s(): Video Received Underflow Error Interrupt!\n",
615			       __func__);
616
617		if (status & FLD_VID_SRC_SYNC)
618			pr_err("%s(): Video Received Sync Error Interrupt!\n",
619			       __func__);
620
621		if (status & FLD_VID_SRC_OPC_ERR)
622			pr_err("%s(): Video Received OpCode Error Interrupt!\n",
623			       __func__);
624	}
625
626	if (dev->_file_status == END_OF_FILE) {
627		pr_err("EOF Channel 1 Framecount = %d\n", dev->_frame_count);
628		return -1;
629	}
630	/* ElSE, set the interrupt mask register, re-enable irq. */
631	int_msk_tmp = cx_read(channel->int_msk);
632	cx_write(channel->int_msk, int_msk_tmp |= _intr_msk);
633
634	return 0;
635}
636
637static irqreturn_t cx25821_upstream_irq(int irq, void *dev_id)
638{
639	struct cx25821_dev *dev = dev_id;
640	u32 vid_status;
641	int handled = 0;
642	int channel_num = 0;
643	struct sram_channel *sram_ch;
644
645	if (!dev)
646		return -1;
647
648	channel_num = VID_UPSTREAM_SRAM_CHANNEL_I;
649
650	sram_ch = dev->channels[channel_num].sram_channels;
651
652	vid_status = cx_read(sram_ch->int_stat);
653
654	/* Only deal with our interrupt */
655	if (vid_status)
656		handled = cx25821_video_upstream_irq(dev, channel_num,
657				vid_status);
658
659	if (handled < 0)
660		cx25821_stop_upstream_video_ch1(dev);
661	else
662		handled += handled;
663
664	return IRQ_RETVAL(handled);
665}
666
667void cx25821_set_pixelengine(struct cx25821_dev *dev, struct sram_channel *ch,
668			     int pix_format)
669{
670	int width = WIDTH_D1;
671	int height = dev->_lines_count;
672	int num_lines, odd_num_lines;
673	u32 value;
674	int vip_mode = OUTPUT_FRMT_656;
675
676	value = ((pix_format & 0x3) << 12) | (vip_mode & 0x7);
677	value &= 0xFFFFFFEF;
678	value |= dev->_isNTSC ? 0 : 0x10;
679	cx_write(ch->vid_fmt_ctl, value);
680
681	/* set number of active pixels in each line.
682	 * Default is 720 pixels in both NTSC and PAL format */
683	cx_write(ch->vid_active_ctl1, width);
684
685	num_lines = (height / 2) & 0x3FF;
686	odd_num_lines = num_lines;
687
688	if (dev->_isNTSC)
689		odd_num_lines += 1;
690
691	value = (num_lines << 16) | odd_num_lines;
692
693	/* set number of active lines in field 0 (top) and field 1 (bottom) */
694	cx_write(ch->vid_active_ctl2, value);
695
696	cx_write(ch->vid_cdt_size, VID_CDT_SIZE >> 3);
697}
698
699int cx25821_start_video_dma_upstream(struct cx25821_dev *dev,
700				     struct sram_channel *sram_ch)
701{
702	u32 tmp = 0;
703	int err = 0;
704
705	/* 656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface for
706	 * channel A-C
707	 */
708	tmp = cx_read(VID_CH_MODE_SEL);
709	cx_write(VID_CH_MODE_SEL, tmp | 0x1B0001FF);
710
711	/* Set the physical start address of the RISC program in the initial
712	 * program counter(IPC) member of the cmds.
713	 */
714	cx_write(sram_ch->cmds_start + 0, dev->_dma_phys_addr);
715	/* Risc IPC High 64 bits 63-32 */
716	cx_write(sram_ch->cmds_start + 4, 0);
717
718	/* reset counter */
719	cx_write(sram_ch->gpcnt_ctl, 3);
720
721	/* Clear our bits from the interrupt status register. */
722	cx_write(sram_ch->int_stat, _intr_msk);
723
724	/* Set the interrupt mask register, enable irq. */
725	cx_set(PCI_INT_MSK, cx_read(PCI_INT_MSK) | (1 << sram_ch->irq_bit));
726	tmp = cx_read(sram_ch->int_msk);
727	cx_write(sram_ch->int_msk, tmp |= _intr_msk);
728
729	err = request_irq(dev->pci->irq, cx25821_upstream_irq,
730			IRQF_SHARED, dev->name, dev);
731	if (err < 0) {
732		pr_err("%s: can't get upstream IRQ %d\n",
733		       dev->name, dev->pci->irq);
734		goto fail_irq;
735	}
736
737	/* Start the DMA  engine */
738	tmp = cx_read(sram_ch->dma_ctl);
739	cx_set(sram_ch->dma_ctl, tmp | FLD_VID_RISC_EN);
740
741	dev->_is_running = 1;
742	dev->_is_first_frame = 1;
743
744	return 0;
745
746fail_irq:
747	cx25821_dev_unregister(dev);
748	return err;
749}
750
751int cx25821_vidupstream_init_ch1(struct cx25821_dev *dev, int channel_select,
752				 int pixel_format)
753{
754	struct sram_channel *sram_ch;
755	u32 tmp;
756	int retval = 0;
757	int err = 0;
758	int data_frame_size = 0;
759	int risc_buffer_size = 0;
760	int str_length = 0;
761
762	if (dev->_is_running) {
763		pr_info("Video Channel is still running so return!\n");
764		return 0;
765	}
766
767	dev->_channel_upstream_select = channel_select;
768	sram_ch = dev->channels[channel_select].sram_channels;
769
770	INIT_WORK(&dev->_irq_work_entry, cx25821_vidups_handler);
771	dev->_irq_queues = create_singlethread_workqueue("cx25821_workqueue");
772
773	if (!dev->_irq_queues) {
774		pr_err("create_singlethread_workqueue() for Video FAILED!\n");
775		return -ENOMEM;
776	}
777	/* 656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface for
778	 * channel A-C
779	 */
780	tmp = cx_read(VID_CH_MODE_SEL);
781	cx_write(VID_CH_MODE_SEL, tmp | 0x1B0001FF);
782
783	dev->_is_running = 0;
784	dev->_frame_count = 0;
785	dev->_file_status = RESET_STATUS;
786	dev->_lines_count = dev->_isNTSC ? 480 : 576;
787	dev->_pixel_format = pixel_format;
788	dev->_line_size = (dev->_pixel_format == PIXEL_FRMT_422) ?
789		(WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2;
790	data_frame_size = dev->_isNTSC ? NTSC_DATA_BUF_SZ : PAL_DATA_BUF_SZ;
791	risc_buffer_size = dev->_isNTSC ?
792		NTSC_RISC_BUF_SIZE : PAL_RISC_BUF_SIZE;
793
794	if (dev->input_filename) {
795		str_length = strlen(dev->input_filename);
796		dev->_filename = kmemdup(dev->input_filename, str_length + 1,
797					 GFP_KERNEL);
798
799		if (!dev->_filename)
800			goto error;
801	} else {
802		str_length = strlen(dev->_defaultname);
803		dev->_filename = kmemdup(dev->_defaultname, str_length + 1,
804					 GFP_KERNEL);
805
806		if (!dev->_filename)
807			goto error;
808	}
809
810	/* Default if filename is empty string */
811	if (strcmp(dev->input_filename, "") == 0) {
812		if (dev->_isNTSC) {
813			dev->_filename =
814				(dev->_pixel_format == PIXEL_FRMT_411) ?
815				"/root/vid411.yuv" : "/root/vidtest.yuv";
816		} else {
817			dev->_filename =
818				(dev->_pixel_format == PIXEL_FRMT_411) ?
819				"/root/pal411.yuv" : "/root/pal422.yuv";
820		}
821	}
822
823	dev->_is_running = 0;
824	dev->_frame_count = 0;
825	dev->_file_status = RESET_STATUS;
826	dev->_lines_count = dev->_isNTSC ? 480 : 576;
827	dev->_pixel_format = pixel_format;
828	dev->_line_size = (dev->_pixel_format == PIXEL_FRMT_422) ?
829		(WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2;
830
831	retval = cx25821_sram_channel_setup_upstream(dev, sram_ch,
832			dev->_line_size, 0);
833
834	/* setup fifo + format */
835	cx25821_set_pixelengine(dev, sram_ch, dev->_pixel_format);
836
837	dev->upstream_riscbuf_size = risc_buffer_size * 2;
838	dev->upstream_databuf_size = data_frame_size * 2;
839
840	/* Allocating buffers and prepare RISC program */
841	retval = cx25821_upstream_buffer_prepare(dev, sram_ch, dev->_line_size);
842	if (retval < 0) {
843		pr_err("%s: Failed to set up Video upstream buffers!\n",
844		       dev->name);
845		goto error;
846	}
847
848	cx25821_start_video_dma_upstream(dev, sram_ch);
849
850	return 0;
851
852error:
853	cx25821_dev_unregister(dev);
854
855	return err;
856}