📄 s3c2410_dma_3.c
字号:
int num_start= num_be?(S3C2410_DMA_NUMSBUF/2):0; int i ; for (i = num_start;i < num_end;i ++) s3c2410_dmabuffer_array_rd[i].dirty = 0; printk("zero_dmabuffarray--%d--",num_be);}static int DMA0_STOP(void){ while (!(dma_types[DMA_CH0]->DMASKTRIG & CHANNEL_ON)) {dma_types[DMA_CH0]->DCON |= CLR_ATRELOAD; dma_types[DMA_CH0]->DMASKTRIG = DMA_STOP; }//dma_types[DMA_CH0]->DMASKTRIG = DMA_STOP; printk("Channel is turnning down\n"); spin_unlock_wait(&protect_dma_lock); printk("protect_dma_lock is locked"); return 0;} static int exter_DMA0_read(struct file *file, char *buf, size_t cnt, loff_t * ppos){ int err = 0,dirty[2] = {1,1},k; for (k = 0; k< S3C2410_DMA_NUMSBUF;k++) dirty[k > (S3C2410_DMA_NUMSBUF/2 -1)] *= s3c2410_dmabuffer_array_rd[k].dirty; if (!(dirty[0]|dirty[1])) return 0; else {if (dirty[0]) { err = copy_to_user(buf, s3c2410_dmabuffer_array_rd[0].start, PAGESIZE); if (err< 0) printk(KERN_ERR "unable to -----copy_to_user failure----\n"); zero_dmabuffarray(0); } else { err = copy_to_user(buf, s3c2410_dmabuffer_array_rd[4].start, PAGESIZE); if (err< 0) printk(KERN_ERR "unable to -----copy_to_user failure----\n"); zero_dmabuffarray(1); } } return (PAGESIZE - err); }//返回读出字节数小于static int exter_DMA1_write(struct file *file, const char *buf, size_t cnt, loff_t * ppos){ int err = 0; if (usr_buff_write.active[0]||usr_buff_write.active[1]) return -1; if (copy_from_user(&usr_buff_write,buf,sizeof(user_buf_t))) { printk( KERN_ERR "unable to -----copy_from_user failure----\n"); return -1; } printk("---pp---\n"); usr_buff_write.active[usr_buff_write.num] = 1; usr_buff_write.curr_pos= usr_buff_write.start; usr_buff_write.valid_size = cnt; s3c2410_dmabuffer_array_wr.size_valid =((usr_buff_write.valid_size >( s3c2410_dmabuffer_array_wr.size)) ?(s3c2410_dmabuffer_array_wr.size):(usr_buff_write.valid_size)); err = copy_from_user( s3c2410_dmabuffer_array_wr.start, usr_buff_write.curr_pos,s3c2410_dmabuffer_array_wr.size_valid); if (err < 0) { printk( KERN_ERR "unable to -----copy_from_user failure----\n"); return -1; } s3c2410_dmabuffer_array_wr.size_valid -= err; usr_buff_write.curr_pos += s3c2410_dmabuffer_array_wr.size_valid; printk("user_num +%d,size_valid %d\n",usr_buff_write.num,s3c2410_dmabuffer_array_wr.size_valid); DMA1_write(); //wait_event_interruptible(wq, (usr_buff_write[user_num].write_success == cnt)); return ( usr_buff_write.curr_pos- usr_buff_write.start);}//成功返回字节数static int DMA0_check_fifo(){ unsigned int ret_tmp = (*(volatile unsigned int*)( Mod612Addr )); RunMode = ret_tmp & 0x1; switch( RunMode ) { case ENCODE: DMA0_read(); break; //case DECODE: // DMA1_write(); // break; } return RunMode;}/******************************************///读时自动装载;//写时自动装载;/******************************************/static void clear_usr_buff(user_buf_t * p){ printk("Clear usr buff\n"); p ->active[p->num] =0; p->curr_pos = p->start; //wake_up_interruptible(&wq);}static void s3c2410_dma_done_callback(int irq, void *dev_id, struct pt_regs *regs){ int left,err;//time_t timecul = xtime.tv_sec; dma_buf_t *dma_buff_curr = (dma_buf_t *)dev_id; SRCPND = INT_DMA0; INTPND = INT_DMA0; if (dma_buff_curr->write_or_rd == DMA_BUF_WR) { printk(KERN_INFO DEVICE_NAME "----DMA0 Write interrupt handle--.\n");//s3c2410_dma_buff_rd.start); if (!usr_buff_write.active[usr_buff_write.num]) goto end; else if(! (left = (usr_buff_write.valid_size +usr_buff_write.start- usr_buff_write.curr_pos))) { //end clear_usr_buff(&usr_buff_write); goto end; } else s3c2410_dmabuffer_array_wr.size_valid =((left >( s3c2410_dmabuffer_array_wr.size)) ?(s3c2410_dmabuffer_array_wr.size):left); err = copy_from_user( s3c2410_dmabuffer_array_wr.start, usr_buff_write.curr_pos,s3c2410_dmabuffer_array_wr.size_valid); if (err < 0) { printk( KERN_ERR "unable to -----copy_from_user failure----\n"); return ; } s3c2410_dmabuffer_array_wr.size_valid -= err; usr_buff_write .curr_pos += s3c2410_dmabuffer_array_wr.size_valid; printk("buff.%d,left +%d,curr_pos+%x,curr.size_valid +%d\n",usr_buff_write.num,left,usr_buff_write.curr_pos,s3c2410_dmabuffer_array_wr.size_valid); dma_types[DMA_CH0]->DCON = rXDREQ0_WR_CTL|TX_CNT(dma_buff_cur_int.size_valid/16); }//up(&(dma0_sem)); else { //dma_types[DMA_CH0]->DIDST = DMA_BASE_ADDR(s3c2410_dmabuffer_array_rd[(ch0_buff_rd++)%S3C2410_DMA_NUMSBUF].dma_addr); memcpy(s3c2410_dmabuffer_array_rd[ch0_buff_rd%S3C2410_DMA_NUMSBUF].start,s3c2410_dma_buff_rd.start,s3c2410_dma_buff_rd.size); printk(KERN_INFO DEVICE_NAME "--DMA0 read interrupt ---read %d Bytes num--%d--\n",s3c2410_dma_buff_rd.size,(ch0_buff_rd%S3C2410_DMA_NUMSBUF)); s3c2410_dmabuffer_array_rd[ch0_buff_rd++%S3C2410_DMA_NUMSBUF].dirty = 1; //dma_types[DMA_CH0]->DCON |= TX_CNT(DMA_TRANS_NUM); }end: up(&dma0_sem); init_MUTEX(&dma0_sem); //spin_unlock(&protect_dma_lock); printk("protect_dma_lock is unlocked\n"); // printk("time 4 +%d\n",(int)(timecul =(xtime.tv_sec - timecul)));/////////////// return ;}static int DMA_transfer_init(void){ int err; err = request_irq(IRQ_DMA0, s3c2410_dma_done_callback, 0, "nDMA0", (void *)&dma_buff_cur_int); if (err) { printk( KERN_ERR "%s: unable to request read IRQ %d for DMA channel\n", "DMA0", IRQ_DMA0); return err; } PRIORITY |= 0x00000000; INTMOD |= 0x00000000; INTMSK &= ~INT_DMA0; return 0;}/********************************************************************************************************** File Operations function**open,release********************************************************************************************************/static int s3c2410_dma_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg){ int ret = 0; if (arg > 4) return -EINVAL; switch(cmd) { case DMA_BUF_WR0: ret = usr_buff_write.active[0]; break; case DMA_BUF_WR1: ret = usr_buff_write.active[1]; break; case DMA_CHECK: ret = DMA0_check_fifo(); break; case DMA_DSTAT0: ret = DSTAT0; break; case DMA_SET_STOP: DMA0_STOP(); break; case DMA_SET_READ: DMA0_read(); default: return -EINVAL; } return ret;}static int s3c2410_dma_open(struct inode *inode, struct file *filp){ //************Only to Test*******// unsigned int ret_tmp; char *MapAddr = NULL; dma_buff_initizlize(); DMA_transfer_init(); //init_waitqueue_head(&wq); init_MUTEX(&dma0_sem); //spin_lock_init(&protect_write_lock); /*****************REQ0 Input**************/ GPBCON|= (2<<20)|(2<<18); /***************************************/ //0x28000000--0x28000408 MapAddr = ioremap(HARDWARE_FIFO_ADDR,0x100); Cmd612Addr = MapAddr; Dat612Addr = MapAddr+0x04; //base+0x04 //Fifo612Addr = MapAddr+0x08; //base+0x08 Int612Addr = MapAddr+0x18; //base+0x10 Cfg612Addr = MapAddr+0x1c; //base+0x10 Mod612Addr = MapAddr+0x24; //base+0x1c /*******************************/ ret_tmp = (*(volatile unsigned int*)( Cfg612Addr )); boardtype = (unsigned short)ret_tmp&0xff; boardversion = ((ret_tmp&0xf0000000)>>28)*100+((ret_tmp&0x0f000000)>>24); ret_tmp = (*(volatile unsigned int*)( Mod612Addr )); RunMode = ret_tmp & 0x1; printk ("MPSIO nGCS5 Driver Ver2.0.071022 build022 Loaded \n"); printk ("(c)Copyright 1992~2007 \n"); printk ("StartAddr:0x%x Range:0~%d\n", HARDWARE_FIFO_ADDR, 0x100); printk ("Boardtype=0x%x HWVersion=%d\n", boardtype, boardversion); printk ("BANK5=0x%x->\n", BANKCON5); // fifo_check_rd = MapAddr + 0x08; fifo_check_wr = MapAddr + 0x08; /////////////////////////////////////////////////// //BANKCON5 = 0x2a70; printk ("BANK5=0x%x\n", BANKCON5); DMA0_check_fifo(); if( RunMode==ENCODE ) { LVT612_EN_Init(); printk ("Mode%d: ENCODE\n", RunMode); } else { LVT612_DE_Init(); printk ("Mode%d: DECODE\n", RunMode); } /////////////////////////////////////////////////// MOD_INC_USE_COUNT; printk(KERN_INFO DEVICE_NAME ": opened.\n"); return 0;}static int s3c2410_dma_release(struct inode *inode, struct file *filp){ dma_clear_buf(&dma_buff_temp_2page,1);//dma mem free dma_clear_buf(&s3c2410_dmabuffer_array_wr,1);//dma mem free dma_clear_buf(&s3c2410_dma_buff_rd,1);//dma mem free free_irq(IRQ_DMA0,(void *)&dma_buff_cur_int); MOD_DEC_USE_COUNT; printk(KERN_INFO DEVICE_NAME ": released.\n"); return 0;}static struct file_operations s3c2410_dma_fops = { owner: THIS_MODULE, read: exter_DMA0_read, write: exter_DMA1_write, ioctl: s3c2410_dma_ioctl, open: s3c2410_dma_open, mmap: s3c2410_dma_mmap, release: s3c2410_dma_release,};static int __init s3c2410_dma_init(void){ dma_types[0] = (dma_regs_t *)io_p2v(0x4b000000); //Register Char Driver devfs_handle = devfs_register(NULL, DEVICE_NAME, DEVFS_FL_AUTO_DEVNUM, 0, 0, S_IFCHR | S_IRUSR | S_IWUSR, &s3c2410_dma_fops, NULL); printk(KERN_INFO DEVICE_NAME ": Initialize s3c2410_DMA_char OK.\n"); return 0;}static void __exit s3c2410_dma_exit(void){ devfs_unregister(devfs_handle);}module_init(s3c2410_dma_init);module_exit(s3c2410_dma_exit);/*********************************************************************************************************** End of File*********************************************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -