📄 record.c
字号:
else if((ssc_regs->SSC_SR & (0x1 << 2)) && (ssc_regs->SSC_IMR & (0x1 << 2)) ) {// if(txflag==0)// { printk("tx interrupt ... \n");// txflag=1;// } ssc_regs->SSC_IDR = 0x1 << 2; // disbale endtx interrupt //pdc_regs->PDC_PTCR = AT91C_PDC_TXTDIS; a9200_dmaing = 0; // update data pointers and counts a9200_dmastart += a9200_dmacount; if(a9200_dmastart >= BUFSIZE) a9200_dmastart = 0; spin_lock(&tx_count_lock); a9200_dmacount = 0; spin_unlock(&tx_count_lock);//printk("interrupt : dmastart = %d count = %d \n",a9200_dmastart,a9200_dmacount); // start new dma buffer if we can a9200_tx_dmabuf(); }}/******************************************************************************************************* Input:* dev: The major number of the device.* Value Returned: None. * Description: This routine will reset device.** Modification History:* 8 JAN,2002, Initial version. Li Qin*******************************************************************************************************///int at91_audio_openflag=0;static int at91_audio_open(struct inode * inode, struct file * filp){// if(at91_audio_openflag ==0)// {// printk("now open ... \n");// at91_audio_openflag=1;// } return 0;}//int a9200_txdrainflag=0; void a9200_txdrain(void){// if(a9200_txdrainflag==0)// {// printk("a9200_txdrain() \n");// a9200_txdrainflag =1;// } a9200_txbusy = 0; current->state = TASK_INTERRUPTIBLE; schedule_timeout(1); return; while(!signal_pending(current)) { if(a9200_txbusy == 0) break; }}//int at91_audio_closeflag=0; static int at91_audio_close(struct inode *inode, struct file *filp){// if(at91_audio_closeflag==0)// {// printk("now cloes ... \n");// at91_audio_closeflag=1;// } a9200_txdrain();// a9200_mute(); // soft reset AT91F_PDC_Close(pdc_regs); //printk("ssc_sr = %p ssc_imr = %p \n", ssc_regs->SSC_SR,ssc_regs->SSC_IMR); a9200_dmaing = 0; a9200_txbusy =0; a9200_dmastart = 0; a9200_dmacount = 0; a9200_append = 0; a9200_isopen = 0; a9200_rxstart = 0; a9200_rxend = 0; return (0);}//int at91_audio_writeflag=0;static ssize_t at91_audio_write(struct file * file, const char * buf, size_t count,loff_t *ppos){ unsigned long *dp,*buflp,tmp; unsigned short *bufwp; unsigned char *bufbp; unsigned int slen,bufcnt,i,s,e; if(count <= 0) return (0); // if(at91_audio_writeflag==0)// {// printk("now at91_audio_write() \n");// at91_audio_writeflag=1;// } buflp = (unsigned long *) buf; bufwp = (unsigned short *) buf; bufbp = (unsigned char *) buf; bufcnt = count & ~0x3; if(a9200_stereo == 0) bufcnt <<= 1; if(a9200_bits == 8) bufcnt <<= 1; tmp = ssc_regs->SSC_THR ; while(bufcnt>0) { s = a9200_dmastart; e = a9200_append; dp = (unsigned long *) & a9200_tx_buf[e]; slen = ((s > e) ? (s - e) : (BUFSIZE - (e - s))) - 4; if(slen > bufcnt) slen = bufcnt; if((BUFSIZE - e) < slen) slen = BUFSIZE - e; if(slen == 0) { if(signal_pending(current)) return (-ERESTARTSYS); set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(1); continue; } if(a9200_stereo) { if(a9200_bits == 16) { for(i = 0;i < slen;i += 4) *dp++ = *buflp++; } else { for(i = 0;i < slen;i += 4) { *dp++ = (((unsigned long) *bufbp++) << 24) | (((unsigned long) *bufbp++) << 8); } } } else { if(a9200_bits == 16) { for(i = 0;i < slen;i += 4) { *dp++ = (((unsigned long) *bufwp) << 16) | *bufwp; bufwp++; } } else { for(i = 0;i < slen;i += 4) { *dp++ = (((unsigned long) *bufbp) << 24) | (((unsigned long) *bufbp) << 8); bufbp++; } } } e += slen; if(e >= BUFSIZE) e = 0; a9200_append = e; // tx with dma a9200_tx_dmabuf(); bufcnt -= slen; } return (count);}//int at91_audio_readflag=0;static ssize_t at91_audio_read(struct file *file,char *buf,size_t count,loff_t * ppos){ unsigned short *buflp; unsigned long *appbuflp,tmp; unsigned long bufcnt,slen; unsigned int i; const unsigned long LBUFSIZE = BUFSIZE /4; if(count <= 0) return 0;// if(at91_audio_readflag==0)// { // printk("now at91_audio_read() \n");// at91_audio_readflag=1;// } bufcnt = count; appbuflp = (unsigned long *) buf; buflp = (unsigned short *) a9200_rx_buf; if(a9200_stereo == 1) bufcnt >>= 1; if(a9200_bits == 16) bufcnt >>= 1; while(bufcnt) { a9200_rxstart = 0; a9200_rxend =0 ; slen = LBUFSIZE ; if(LBUFSIZE >= bufcnt) slen = bufcnt; else slen = (bufcnt - LBUFSIZE) > LBUFSIZE ? LBUFSIZE : (bufcnt - LBUFSIZE); a9200_rxend +=slen ; // rx with irq if(a9200_rxbusy == 0) { a9200_rxbusy = 1; tmp = ssc_regs->SSC_RHR; a9200_rx_dmabuf(); } PDEBUG("waiting the recording to finish ... \n"); /* while(a9200_rxbusy == 1) { set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(1); }*/ if (wait_event_interruptible(rx_buffer_end, (a9200_rxbusy == 0))) return -ERESTARTSYS; /* signal: tell the fs layer to handle it */ PDEBUG("Copy from buflp : %p to appbuflp : %p ,length : %p \n",appbuflp,buflp,4 * slen); for(i = 0;i < slen;i++) { *appbuflp++ = (((unsigned long) *buflp) << 16) | *buflp; buflp++; //*appbuflp++ = buflp[i]; }//#else // rx with dma// a9200_rx_dmabuf();//#endif bufcnt -= slen;} return (count);} struct file_operations at91_audio_fops = { open:at91_audio_open, /* open */ read:at91_audio_read, /*read */ release:at91_audio_close,/* release */ write:at91_audio_write, /* write */ ioctl:at91_audio_ioctl, /* ioctl */}; static int __init init_ssi(void){ SINT32 ok = 0; printk("AT91RM9200 audio driver version 0.1, build time:" __TIME__ "\n"); audio_dev_dsp = register_sound_dsp(&at91_audio_fops, -1); a9200_rx_buf = (unsigned char *) __get_dma_pages(GFP_KERNEL,7); a9200_tx_buf = (unsigned char *) __get_dma_pages(GFP_KERNEL,7); if( request_irq(AT91C_ID_SSC1, a9200_dma_isr, SA_INTERRUPT, "SSC", NULL) < 0 ) printk("SSC interrupt handler request failed!\n"); AT91_PIO_SSC_Set(); SSC_init(); I2C_test(); codec_init(uda1380_rx_init); return ok;}static void __exit cleanup_ssi(void){ printk("Rmmod audio driver.\n"); if (a9200_rx_buf) free_pages((unsigned long) a9200_rx_buf, 7); // 512K if (a9200_tx_buf) free_pages((unsigned long) a9200_tx_buf, 7); // 512K free_irq(AT91C_ID_SSC1,NULL); unregister_sound_dsp(audio_dev_dsp);} MODULE_AUTHOR("GSG-China");MODULE_DESCRIPTION("SSI-Low Level Audio Device Driver"); module_init(init_ssi);module_exit(cleanup_ssi);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -