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

📄 at2041_inf.c

📁 这个是Linux下的关于2042的程序
💻 C
📖 第 1 页 / 共 3 页
字号:
			demux_wr_cnt = 0;		}	} 	else if (demux_ring_cnt && (demux_wr_cnt < demux_rd_cnt)) {		demux_wr_cnt ++;	}	//printk ("down:%d %d %d\n", demux_ring_cnt, demux_wr_cnt, demux_rd_cnt);	return 0;}static int at2041_open(struct inode* inode, struct file* filp){	printk("the AT2041 Open!!!\n");	MOD_INC_USE_COUNT;	return 0;}static int at2041_release(struct inode* inode, struct file* filp){	printk("the AT2041 Release!!!\n"); 	MOD_DEC_USE_COUNT;	return 0;}/* the AT2041 file operations */static struct file_operations at2041_fops = {	read:   	muxfifo_read,	write:  	demuxfifo_write,	ioctl:		at2041_ioctl,	open:		at2041_open,	release: 	at2041_release,};static void at2041_interrupt_handle(int irq, void *dev_id, struct pt_regs * regs){	_SET_REG_STR_ set_reg_st={0,0,{0,0,0,0,0,0}};	unsigned int tx_data=0;	unsigned int stat_data=0;	unsigned int data_size = 0;	#if 0		int tmp=0;	unsigned short temp;	unsigned char picture_type[]={'I', 'P', 'B'};#endif		int break_value=0;	int count = 0;	unsigned int mux_data;	unsigned short mux_tmp[2];	unsigned short mux_swap[2];		unsigned short fifo_dat[4];	unsigned short id_conf = RxID(GID_ENC_VIDEO, 0x00, 0x01, R_FLAG);		do {		stat_data = *((unsigned short *)((unsigned int)fifo_reg + AT2041_STATUS_REG));		count ++;		udelay(10);	} while ((stat_data & 0x100) && (count < 1000));		//printk("stat_data_%d : 0x%04x\n",  count, stat_data); udelay(10);	if (count < 1000) 	{				/* data read from Tx_FIFO of the AT2041 */		//tx_data = *((unsigned short *)((unsigned int)fifo_reg + AT2041_TX_FIFO));		tx_data = *((unsigned int *)((unsigned int)fifo_reg + AT2041_TX_FIFO));udelay(10);		fifo_dat[0]=(tx_data&0xFFFF);		fifo_dat[1]=((tx_data>>AT2041_DAT_SHIFT)&0xFFFF);		//printk("fifo_dat : 0x%04x, 0x%04x\n", fifo_dat[0], fifo_dat[1]); 	}	#if 1	if (fifo_dat[0] ==id_conf)		/*RESOLUTION*/		{ 		tx_data = *((unsigned int *)((unsigned int)fifo_reg + AT2041_TX_FIFO));udelay(10);		fifo_dat[0]=(tx_data&0xFFFF);fifo_dat[1]=((tx_data>>AT2041_DAT_SHIFT)&0xFFFF);		tx_data = *((unsigned int *)((unsigned int)fifo_reg + AT2041_TX_FIFO));udelay(10);		if (fifo_dat[0]==480) {			PAL_NTSC=NTSC;			printk ("## NTSC INPUT VIDEO DETECTEDT ##\n");		}		else {			PAL_NTSC=PAL;			printk ("## PAL INPUT VIDEO DETECTEDT ##\n");		}		/* TxACK command */		set_reg_st.cmd_num=0;set_reg_st.addr=AT2041_RX_FIFO_ADDR;		set_reg_st.value[0]=0x8003;			do_mw32 ( (_SET_REG_STR_ ) set_reg_st);			/* acknowledge for data ready message */		set_reg_st.cmd_num=0;set_reg_st.addr=AT2041_RX_FIFO_ADDR;		set_reg_st.value[0]=id_conf;			do_mw32 ( (_SET_REG_STR_ ) set_reg_st);			}#endif	/* check whether first tx message is 'data ready message' 	 * or 'data request message'	 */	if ((fifo_dat[0] & 0x0001) == 0x0000)	/*Message*/		{ 		// read data from tx_fifo		/* check tx fifo empty */		do {			stat_data = *((unsigned short *)((unsigned int)fifo_reg + AT2041_STATUS_REG));			count ++;			udelay(10);		} while ((stat_data & 0x100) && (count < 1000));			//printk("Message : %d,  0x%04x\n",  count, stat_data); udelay(10);		if (count < 1000) {					/* data read from Tx_FIFO of the AT2041 */			tx_data = *((unsigned int *)((unsigned int)fifo_reg + AT2041_TX_FIFO));udelay(10);			fifo_dat[2]=(tx_data&0xFFFF);			fifo_dat[3]=((tx_data>>AT2041_DAT_SHIFT)&0xFFFF);			//printk("Message : 0x%04x, 0x%04x\n", fifo_dat[2], fifo_dat[3]); 		}		/* TxACK command */		set_reg_st.cmd_num=0;set_reg_st.addr=AT2041_RX_FIFO_ADDR;		set_reg_st.value[0]=0x8003;			do_mw32 ( (_SET_REG_STR_ ) set_reg_st);		}			else if (fifo_dat[0] == 0x8803) 	/*Encoding*/		{ 		// 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.		 */		/* read the second parameter of Tx_FIFO */		mux_buf[mux_wr_cnt][0] = fifo_dat[1];		//printk( "[ch:%d]", (mux_buf[mux_wr_cnt][0] >> 4) & 0xf);		//printk( "[%c]", picture_type[((mux_buf[mux_wr_cnt][0] >> 12) & 0x3)-1]);		//printk( "[type:%d]",  mux_buf[mux_wr_cnt][0] & 0xf);		do {			stat_data = *((unsigned short *)((unsigned int)fifo_reg + AT2041_STATUS_REG));			count ++;			udelay(10);		} while ((stat_data & 0x100) && (count < 1000));			if (count < 1000) {					/* data read from Tx_FIFO of the AT2041 */			tx_data = *((unsigned int *)((unsigned int)fifo_reg + AT2041_TX_FIFO));udelay(10);			fifo_dat[2]=(tx_data&0xFFFF);			fifo_dat[3]=((tx_data>>AT2041_DAT_SHIFT)&0xFFFF);		}		/* read the third parameter of Tx_FIFO */		/* the contents of the third tx_message are 'output data size' */				mux_buf[mux_wr_cnt][1] = fifo_dat[2];		//printk( "[size:%08d]\n", (((mux_buf[mux_wr_cnt][1] &0xffff) << 4) + enc_txmsg_size)*2);		  				/* read the fourth parameter of Tx_FIFO */		/* the contents of the fourth tx_message are 'reserved' */				mux_buf[mux_wr_cnt][2] = fifo_dat[3]; 		/* 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+=2) 	/*data size is short type*/		{			mux_data= *((unsigned int *)((unsigned int)fifo_reg + AT2041_MUX_FIFO));			mux_tmp[0]=(mux_data&0xFFFF);			mux_tmp[1]=((mux_data>>AT2041_DAT_SHIFT)&0xFFFF);			mux_swap[0]= (((mux_tmp[0]<<8)&0xFF00) | ((mux_tmp[0]>>8)&0x00FF));			mux_swap[1]= (((mux_tmp[1]<<8)&0xFF00) | ((mux_tmp[1]>>8)&0x00FF));			mux_buf[mux_wr_cnt][ii]=mux_swap[0];						mux_buf[mux_wr_cnt][ii+1]=mux_swap[1];		}		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);		}		if (mux_ring_cnt && mux_wr_cnt == mux_rd_cnt) {			mux_full = 1;			//printk("!!!!!!!! MUX FULL !!!!!!!!!\n");		} 				/* TxACK command */		set_reg_st.cmd_num=0;set_reg_st.addr=AT2041_RX_FIFO_ADDR;		set_reg_st.value[0]=0x8003;			do_mw32 ( (_SET_REG_STR_ ) set_reg_st);			/* acknowledge for data ready message */		set_reg_st.cmd_num=0;set_reg_st.addr=AT2041_RX_FIFO_ADDR;		set_reg_st.value[0]=0x8803;			do_mw32 ( (_SET_REG_STR_ ) set_reg_st);			}	/*Encoding*/			else if (fifo_dat[0] == 0x9003) 	/*Decoding*/		{ 			/* data write to de-multiplex FIFO of the AT2041 */		// read message from txfifo : data request(Decoding) 		if (!demux_ring_cnt && (demux_wr_cnt == demux_rd_cnt)) {	#if 0				/* check tx fifo empty */			do {				stat_data = *((unsigned short *)((unsigned int)fifo_reg + AT2041_STATUS_REG));				count ++;				udelay(10);			} while ((stat_data & 0x100) && (count < 1000));				if (count < 1000) {						/* data read from Tx_FIFO of the AT2041 */				tx_data = *((unsigned int *)((unsigned int)fifo_reg + AT2041_TX_FIFO));udelay(10);				fifo_dat[2]=(tx_data&0xFFFF);				fifo_dat[3]=((tx_data>>AT2041_DAT_SHIFT)&0xFFFF);			}		#endif						demux_empty=1;			/* TxACK command */			set_reg_st.cmd_num=0;set_reg_st.addr=AT2041_RX_FIFO_ADDR;			set_reg_st.value[0]=0x8003;				do_mw32 ( (_SET_REG_STR_ ) set_reg_st);				/* acknowledge for data ready message */			set_reg_st.cmd_num=0;set_reg_st.addr=AT2041_RX_FIFO_ADDR;			set_reg_st.value[0]=0x9003;				do_mw32 ( (_SET_REG_STR_ ) set_reg_st);							//printk ("[RETURN : %d %d %d]\n", demux_ring_cnt, demux_wr_cnt, demux_rd_cnt);			return ;		}		/* check tx fifo empty */	#if 0		do {			stat_data = *((unsigned short *)((unsigned int)fifo_reg + AT2041_STATUS_REG));			count ++;			udelay(10);		} while ((stat_data & 0x100) && (count < 1000));			if (count < 1000) {					/* data read from Tx_FIFO of the AT2041 */			tx_data = *((unsigned int *)((unsigned int)fifo_reg + AT2041_TX_FIFO));udelay(10);			fifo_dat[2]=(tx_data&0xFFFF);			fifo_dat[3]=((tx_data>>AT2041_DAT_SHIFT)&0xFFFF);		}		#endif			/* 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 +=2) { /*data size is short type*/			mux_tmp[0]=demux_buf[demux_rd_cnt][ii];			mux_tmp[1]=demux_buf[demux_rd_cnt][ii+1];			mux_swap[0]= (((mux_tmp[0]<<8)&0xFF00) | ((mux_tmp[0]>>8)&0x00FF));			mux_swap[1]= (((mux_tmp[1]<<8)&0xFF00) | ((mux_tmp[1]>>8)&0x00FF));#if 0			if (ii < 2) { 				//printk("%04x_%04x ", mux_swap[0], mux_swap[1]);				if (mux_swap[1]==0x01e0) break_value=1;				else break_value=0;			}			else if (ii < 4) {				//printk("%04x_%04x\n", mux_swap[0], mux_swap[1]);				if (break_value) break;			}#endif			set_reg_st.cmd_num=1;set_reg_st.addr=AT2041_DEMUX_FIFO_ADDR;			set_reg_st.value[0]=mux_swap[0];set_reg_st.value[1]=mux_swap[1];						do_mw32 ( (_SET_REG_STR_ ) set_reg_st);		} 		up(&demuxfifo_write_sem);		/* de-multiplex ring buffer control */		//if (!demux_ring_cnt && demux_rd_cnt <= demux_wr_cnt) 		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;			}						}				/* TxACK command */		set_reg_st.cmd_num=0;set_reg_st.addr=AT2041_RX_FIFO_ADDR;		set_reg_st.value[0]=0x8003;			do_mw32 ( (_SET_REG_STR_ ) set_reg_st);			/* acknowledge for data ready message */		set_reg_st.cmd_num=0;set_reg_st.addr=AT2041_RX_FIFO_ADDR;		set_reg_st.value[0]=0x9003;			do_mw32 ( (_SET_REG_STR_ ) set_reg_st);			//printk ("up:%d %d %d\n", demux_ring_cnt, demux_wr_cnt, demux_rd_cnt);	}	/*Decoding*/	else {				printk ("\n[ISR_ELSE : 0x%04x, 0x%04x, 0x%04x]\n", stat_data, fifo_dat[0], fifo_dat[1]);		/* TxACK command */		set_reg_st.cmd_num=0;set_reg_st.addr=AT2041_RX_FIFO_ADDR;		set_reg_st.value[0]=0x8003;			do_mw32 ( (_SET_REG_STR_ ) set_reg_st);					}	return ;}int at2041_init_module(void){	int ret, kk;	printk ("## BWSCON : 0x%08x ##\n" , rBWSCON);	/*BWSCON : 0x48000000*/		(unsigned int *)fifo_reg = (unsigned int *)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");/*HJT*/	//rBWSCON |= (0x5<<8);	printk ("__nWAIT_DISABLE__\n");printk ("__nWAIT_DISABLE__\n");/*HJT*/	rBWSCON &= ~(0x4<<8);	printk ("__Tacc_control__\n");printk ("__Tacc_control__\n");/*HJT*/		rBANKCON2 |= (0x7<<8);		/*14CLK*/#endif		/* Enable interrupts for EINT0/GPF0 */	/*HJT*/	printk ("__INTERRUPT_AVAILABLE__\n");	/*HJT*/	//rEXTINT0 = 0x22222244;    // EINT[7:0]	/*AT2042 Falling Edge Triggered*/	/*HJT*/	rEXTINT0 = 0x22222444;    // EINT[7:0]	/*AT2042 Rising Edge Triggered*/	/*HJT*/	//rINTMSK &= ~0x00000001;	//Intservice MASK ==> AVAILABLE		/*HJT*/		rSRCPND |= 0x00000004;	//Intservice requested /*HJT*/		//rINTMSK |=0x00000004;	//Intservice MASK ==> MASKED		/*HJT*/		rINTMSK &= ~0x00000004;	//Intservice MASK ==> AVAILABLE		/*HJT*/		/* 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);	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 + -