⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 at2042_inf-old.c

📁 这个是Linux下的关于2042的程序
💻 C
📖 第 1 页 / 共 4 页
字号:
			PAL_NTSC=NTSC;
			printk ("## NTSC INPUT VIDEO DETECTEDT : %d ##\n", tx_data);
		}
		/* 3RD data read from Tx_FIFO of the AT2041 */
		tx_data = *((unsigned short *)((unsigned int)fifo_reg + AT2041_TX_FIFO));
		/* 4TH data read from Tx_FIFO of the AT2041 */
		tx_data = *((unsigned short *)((unsigned int)fifo_reg + AT2041_TX_FIFO));
		
		/* TxACK command */
		*((unsigned short *)((unsigned int)fifo_reg + AT2041_RX_FIFO)) = 0x8003;
	}
	/* check whether first tx message is 'data ready message' 
	 * or 'data request message'
	 */
	else if ((tx_data & 0x0001) == 0x0000) { 
		// read data from tx_fifo
		/* check tx fifo empty */
		if ( !(*((unsigned short *)((unsigned int)fifo_reg + AT2041_STATUS_REG)) & 0x100) ) {
			// read DATA
			/* data read from Tx_FIFO of the AT2041 */
			tx_data = *((unsigned short *)((unsigned int)fifo_reg + AT2041_TX_FIFO));
		}
		/* TxACK command */
		*((unsigned short *)((unsigned int)fifo_reg + AT2041_RX_FIFO)) = 0x8003;	
	}
	else if (tx_data == 0x8803) { 
		// read message from tx_fifo : data ready message(Encoder)
		/* if first tx message is 'data ready message', 
		 * read three tx message sequentially.
		 * the contents of second tx_message are 'data type', 'channel ID',
		 * 'skip', 'loss' and 'output buffer full', etc.
		 */

		/* check tx fifo empty */
		if ( !(*((unsigned short *)((unsigned int)fifo_reg + AT2041_STATUS_REG)) & 0x100) ) {
			/* read the second parameter of Tx_FIFO */
			mux_buf[mux_wr_cnt][0] = *((unsigned short *)((unsigned int)fifo_reg + AT2041_TX_FIFO));
		} 
		else {
			printk("[at2042 : 0x8803] It can't read tx0 register\n");
			/* TxACK command */
			//*((unsigned short *)((unsigned int)fifo_reg + AT2041_RX_FIFO)) = 0x8003;	
		}			
		
		if ( !(*((unsigned short *)((unsigned int)fifo_reg + AT2041_STATUS_REG)) & 0x100) ) {
			/* read the third parameter of Tx_FIFO */
			/* the contents of the third tx_message are 'output data size' */		
			mux_buf[mux_wr_cnt][1] = *((unsigned short *)((unsigned int)fifo_reg + AT2041_TX_FIFO));
		} 
		else {
			printk("[at2042 : 0x8803] It can't read tx1 register\n");
			/* TxACK command */
			//*((unsigned short *)((unsigned int)fifo_reg + AT2041_RX_FIFO)) = 0x8003;
		}		
				
		if ( !(*((unsigned short *)((unsigned int)fifo_reg + AT2041_STATUS_REG)) & 0x100) ) {
			/* read the fourth parameter of Tx_FIFO */
			/* the contents of the fourth tx_message are 'reserved' */		
			mux_buf[mux_wr_cnt][2] = *((unsigned short *)((unsigned int)fifo_reg + AT2041_TX_FIFO));
		} 
		else {
			printk("[at2042 : 0x8803] It can't read tx2 register\n");
			/* TxACK command */
			//*((unsigned short *)((unsigned int)fifo_reg + AT2041_RX_FIFO)) = 0x8003;
		}		

		/* calculate data size to transfer */
		*size_buf[mux_wr_cnt] = mux_buf[mux_wr_cnt][1];
		data_size = ((*size_buf[mux_wr_cnt] & 0xffff) << 4) + enc_txmsg_size;	
		
		/* data read from multiplex FIFO of the AT2041 */
		/* write multiplex data from the AT2041 to d/d's buffer */
		for (ii = enc_txmsg_size; ii < data_size; ii ++) {
			mux_data=*((unsigned short *)((unsigned int)fifo_reg + AT2041_MUX_FIFO));
			mux_swap= (((mux_data<<8)&0xFF00) | ((mux_data>>8)&0x00FF));
			mux_buf[mux_wr_cnt][ii]=mux_swap;			
		}

		up(&muxfifo_read_sem);	
				
		/* multiplex ring buffer control */
		if (!mux_ring_cnt) {
			mux_wr_cnt ++;				
			if (mux_wr_cnt == MAX_BUF_NUM) {
				mux_ring_cnt ++;				
				mux_wr_cnt = 0;
			}
		} 
		else if (mux_ring_cnt && mux_wr_cnt < mux_rd_cnt) {
			mux_wr_cnt ++;				
		}
		else {
			//printk("!!![MUX][%02d][%02d][%02d]\n", mux_wr_cnt, mux_rd_cnt, mux_ring_cnt);
		}

		/* TxACK command */
		*((unsigned short *)((unsigned int)fifo_reg + AT2041_RX_FIFO)) = 0x8003;	

		if (mux_ring_cnt && mux_wr_cnt == mux_rd_cnt) {
			mux_full = 1;
			//printk("!!!!!!!! MUX FULL !!!!!!!!!\n");
		} 
		else {
			/* acknowledge for data ready message */
			*((unsigned short *)((unsigned int)fifo_reg + AT2041_RX_FIFO)) = 0x8803;						
		}

		/* TxACK command */
		//*((unsigned short *)((unsigned int)fifo_reg + AT2041_RX_FIFO)) = 0x8003;	
		/* acknowledge for data ready message */
		//*((unsigned short *)((unsigned int)fifo_reg + AT2041_RX_FIFO)) = 0x8803;		

	}
	/* data write to de-multiplex FIFO of the AT2041 */
	else if (tx_data == 0x9003) {
		// read message from txfifo : data request(Decoding) 
		if (!demux_ring_cnt && (demux_wr_cnt == demux_rd_cnt)) {
			/* check tx fifo empty */
			if (!(*((unsigned short *)((unsigned int)fifo_reg + AT2041_STATUS_REG)) & 0x100)) {
				/* txfifo ring buffer control */
				temp = *((unsigned short *)((unsigned int)fifo_reg + AT2041_TX_FIFO));
			} 
			else {
				printk("[at2042 : 0x9003] It can't read tx0 register\n");			
				/* TxACK command */
				//*((unsigned short *)((unsigned int)fifo_reg + AT2041_RX_FIFO)) = 0x8003;
			}				
			/* TxACK command */
			*((unsigned short *)((unsigned int)fifo_reg + AT2041_RX_FIFO)) = 0x8003;			
			/* acknowledge for data request message */
			*((unsigned short *)((unsigned int)fifo_reg + AT2041_RX_FIFO)) = 0x9003;			
			return;
		}

		/* check tx fifo empty */
		if (!(*((unsigned short *)((unsigned int)fifo_reg + AT2041_STATUS_REG)) & 0x100)) {
			/* txfifo ring buffer control */
			temp = *((unsigned short *)((unsigned int)fifo_reg + AT2041_TX_FIFO));
		} 
		else {
			printk("[at2042 : 0x9003] It can't read tx1 register\n");		
			/* TxACK command */
			//*((unsigned short *)((unsigned int)fifo_reg + AT2041_RX_FIFO)) = 0x8003;
		}			

		/* write de-multiplex data from d/d's buffer to the AT2041 */
		for (ii = 0; ii < (demux_size_buf[demux_rd_cnt] + 256) / 2; ii ++)
		{
			demux_data=demux_buf[demux_rd_cnt][ii];
			demux_swap= (((demux_data<<8)&0xFF00) | ((demux_data>>8)&0x00FF));
			*((unsigned short *)((unsigned int)fifo_reg + AT2041_DEMUX_FIFO)) = demux_swap;
		}

		/* de-multiplex ring buffer control */
		if (!demux_ring_cnt && demux_rd_cnt <= demux_wr_cnt) {
			demux_rd_cnt ++;
			if (demux_rd_cnt == MAX_BUF_NUM) {
				demux_ring_cnt --;
				demux_rd_cnt = 0;
			}
		} else if (demux_ring_cnt) {
			demux_rd_cnt ++;
			if (demux_rd_cnt == MAX_BUF_NUM) {
				demux_ring_cnt --;
				demux_rd_cnt = 0;
			}				
		}
		
		up(&demuxfifo_write_sem);

		/* TxACK command */
		*((unsigned short *)((unsigned int)fifo_reg + AT2041_RX_FIFO)) = 0x8003;		
		/* acknowledge for data request message */
		*((unsigned short *)((unsigned int)fifo_reg + AT2041_RX_FIFO)) = 0x9003;				
	}
	else {
		/* TxACK command */
		*((unsigned short *)((unsigned int)fifo_reg + AT2041_RX_FIFO)) = 0x8003;	
	}

	return ;
}

//#define __KERNEL_THREAD__	/*2005-01-12*/
#ifdef __KERNEL_THREAD__
pid_t thr_pid;
struct completion thr_exited;
static int at2042_thread (void *data)
{
	unsigned short id_conf;
	
	while (1) 
	{
		printk ("[at2042_thread]\n");
		for (id_conf=0;id_conf<20;id_conf++) AT2042_DELAY (100000);
	}
	complete_and_exit (&thr_exited, 0);
}
#endif

int at2041_init_module(void)
{
	volatile int ret, kk;

	printk ("## BWSCON : 0x%08x ##\n" , rBWSCON);	/*BWSCON : 0x48000000*/
	
	(unsigned short *)fifo_reg = (unsigned short *)ioremap(AT2042_BASE, AT2042_REMAP_SIZE);
	
	printk("init_at2042  0x%x ==> 0x%x\n", (unsigned int)fifo_reg,  (unsigned int)fifo_reg+AT2042_REMAP_SIZE);
	
	ret = register_chrdev(AT2041_MAJOR, "at2042", &at2041_fops);

	init_MUTEX_LOCKED(&muxfifo_read_sem);
	sema_init(&demuxfifo_write_sem, MAX_BUF_NUM);	
	
	if (ret < 0) {
		printk("at2042: at2042 register failed\n");
		return ret;
	}
		
	/* mux_buf & demux_buf allocation */
	for (kk = 0; kk < MAX_BUF_NUM; kk ++){
		if (!(mux_buf[kk] = (unsigned short *) kmalloc(MAX_BUF_SIZE + (enc_txmsg_size << 1), GFP_KERNEL))) {
			printk("AT2041 : mux_buf kmalloc failed...\n");
			return -ENOMEM;
		}
		if (!(demux_buf[kk] = (unsigned short *) kmalloc(MAX_BUF_SIZE, GFP_KERNEL))) {
			printk("AT2041 : demux_buf kmalloc failed...\n");
			return -ENOMEM;
		}
		if (!(size_buf[kk] = (unsigned short *) vmalloc(sizeof(unsigned short)))) {
			printk("AT2041 : size_buf kmalloc failed...\n");
			return -ENOMEM;
		}
	}

	printk("the AT2041 driver initialized...\n");
	
#if 0
	//printk ("__nWAIT_REENABLE__\n");printk ("__nWAIT_REENABLE__\n");/*netbsd*/
	//rBWSCON |= (0x5<<8);
	printk ("__nWAIT_DISABLE__\n");printk ("__nWAIT_DISABLE__\n");/*netbsd*/
	rBWSCON &= ~(0x4<<8);
	printk ("__Tacc_control__\n");printk ("__Tacc_control__\n");/*netbsd*/	
	rBANKCON2 |= (0x7<<8);		/*14CLK*/
#endif
	
	/* Enable interrupts for EINT0/GPF0 */	/*netbsd*/
	printk ("__INTERRUPT_AVAILABLE__\n");	/*netbsd*/
	//rEXTINT0 = 0x22222244;    // EINT[7:0]	/*AT2042 Falling Edge Triggered*/	/*netbsd*/
	rEXTINT0 = 0x22222444;    // EINT[7:0]	/*AT2042 Rising Edge Triggered*/	/*netbsd*/
	//rINTMSK &= ~0x00000001;	//Intservice MASK ==> AVAILABLE		/*netbsd*/	
	rSRCPND |= 0x00000004;	//Intservice requested /*netbsd*/	
	//rINTMSK |=0x00000004;	//Intservice MASK ==> MASKED		/*netbsd*/	
	rINTMSK &= ~0x00000004;	//Intservice MASK ==> AVAILABLE		/*netbsd*/	

	/* AT2041_IRQ = 25, Fast interrupt, No interrupt sharing */
	//printk ("0x%x : 0x%x\n", SA_INTERRUPT, SA_SHIRQ);
	//if(request_irq(IRQ_EINT2, at2041_interrupt_handle, SA_INTERRUPT, "at2042", NULL)) 
	//if(request_irq(IRQ_EINT2, at2041_interrupt_handle, SA_SHIRQ, "at2042", NULL)) 		
	if(request_irq(IRQ_EINT2, at2041_interrupt_handle, 0, "at2042", NULL)) 				
	{
		printk("at2042 : cannot register IRQ %d\n", IRQ_EINT2);
		return -EIO;
	}
	printk("at2042 : register IRQ %d\n", IRQ_EINT2);

#ifdef __KERNEL_THREAD__
	thr_pid = kernel_thread (at2042_thread, NULL, CLONE_FS | CLONE_FILES);
	if (thr_pid <0)
	{
		printk ("%s: unable to start kernel thread\n", "at2042");
	}
	else {
		printk ("%s: start kernel thread\n", "at2042");
	}
#endif

#if 1		/*2005-01-18*/
{
		/*Rescale*/
		unsigned short id_conf;
		udelay(1000);
		id_conf = RxID(GID_DEC_VIDEO_CH, 0x00, 0x10, W_FLAG);
		*((unsigned short  *)((unsigned int)fifo_reg + AT2041_RX_FIFO)) = id_conf;
		*((unsigned short  *)((unsigned int)fifo_reg + AT2041_RX_FIFO)) = 0;// 1/1 Hor scale
		*((unsigned short  *)((unsigned int)fifo_reg + AT2041_RX_FIFO)) = 0;// 1/1 Ver scale
		//printf ("[Display Rescale]\n"); 
		/*Deocding video offset*/		
		id_conf = RxID(GID_DEC_VIDEO_CH, 0x00, 0x11, W_FLAG);
		*((unsigned short  *)((unsigned int)fifo_reg + AT2041_RX_FIFO)) = id_conf;
		*((unsigned short  *)((unsigned int)fifo_reg + AT2041_RX_FIFO)) = (0x00);// Hor offset
		*((unsigned short  *)((unsigned int)fifo_reg + AT2041_RX_FIFO)) = (0x00);// Ver offset	
		printk ("[Display Rescale]\n"); 
}
#endif		

	return 0;
}


void at2041_cleanup_module(void)
{
	volatile int ret;
	
	free_irq(IRQ_EINT2, NULL);

	ret = unregister_chrdev(AT2041_MAJOR, "at2042");
	
	if (ret < 0) {
		printk("at2042: at2042 unregister failed\n");
		return;
	}

	for (ii = 0; ii < MAX_BUF_NUM; ii ++) {
		kfree(mux_buf[ii]);
		kfree(demux_buf[ii]);
		vfree(size_buf[ii]);
	}

	printk("at2042: at2042 unloaded\n");

	iounmap((void *)fifo_reg);

	return;
}

module_init(at2041_init_module);
module_exit(at2041_cleanup_module);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -