📄 ac97_sport.c
字号:
rxTail = 0; return 0;}void ac97_sport_close(void){ dev.codec_initialized = 0; sport_enable(-1,-1); // bzero(&dev, sizeof(dev)); return;}void ac97_sport_start(void) { if( !dev.codec_initialized ) { init_ac97(); sport_enable(1,1); //printk("ac97_sport_start\n"); } txHead = 0; txTail = 0; rxHead = 0; rxTail = 0;}void ac97_sport_stop(void) { dev.codec_initialized = 0; sport_enable(-1,-1); bfin_write_DMA4_CONFIG(0) ; bfin_write_DMA3_CONFIG(0) ; }void getrx(){ short i,count; struct ac97_frame *pSrc; unsigned short tmpDest,tmptail; pSrc = (struct ac97_frame *)&dev.rxbuf[ac97_rx_lastfrag*FRAG_SIZE]; tmptail = rxTail + 1; if (tmptail >= AC97_BUFFER_SIZE) { tmptail = 0; } for(i=0; i<FRAG_SIZE; i++) { if (tmptail != rxHead) { if (pSrc->ac97_tag & TAG_PCM_RIGHT) { tmpDest = (unsigned short)((pSrc->ac97_pcmleft12_pcmright4 & 0x000f) << 12); tmpDest |= (unsigned short)(((unsigned short)(pSrc->ac97_pcmright16) >> 4) & 0x0fff); rxbuf[rxTail++] = (short)tmpDest; if (rxTail >= AC97_BUFFER_SIZE) { rxTail = 0; } tmptail = rxTail; } if ((tmptail != rxHead) && (bStereo)) { if (pSrc->ac97_tag & TAG_PCM_LEFT) { tmpDest = (pSrc->ac97_cmddataL8_pcmleftH8 & 0x00ff) << 8; tmpDest |= (pSrc->ac97_pcmleft12_pcmright4 >> 8) & 0x00ff; rxbuf[rxTail++] = (short)tmpDest; if (rxTail >= AC97_BUFFER_SIZE) { rxTail = 0; } tmptail = rxTail; } } } if (pSrc->ac97_tag & TAG_CMD) { tmpDest = (pSrc->ac97_addr4_data12 & 0x0fff) << 4; tmpDest |= (pSrc->ac97_cmddataL8_pcmleftH8 & 0xf000) >> 12; dev.register_cache[(pSrc->ac97_addr >> 8) & 0x7f] = tmpDest; // printk("reg=%x val=%x\n",(pSrc->ac97_addr >> 8)& 0x7f,tmpDest); } pSrc ++; } }ssize_t ac97_audio_read(uint16_t* pcmdata, size_t len){ int i; short tmphead; short realCount; if ((!dev.codec_ready) || (!dev.codec_initialized)) { return 0; } realCount = 0; for(i=0; i<len; i++) { if (rxHead == rxTail) { break; } pcmdata[i] = rxbuf[rxHead++]; if (rxHead >= AC97_BUFFER_SIZE) { rxHead = 0; } realCount++; } return realCount; }/* * on rx: check if we got any commands * return 0: success * -EINPROGRESS: dma not asserted */int ac97_sport_handle_rx(void){ int tmpFrag,i; int status=0; short tmptail;// unsigned int next_dma_ptr; status = bfin_read_DMA3_IRQ_STATUS(); if( !(status & DMA_DONE) ) { bfin_write_DMA3_IRQ_STATUS(status); return -EINPROGRESS; } bfin_write_DMA3_IRQ_STATUS(DMA_DONE); dev.codec_ready = dev.rxbuf[ac97_rx_lastfrag*FRAG_SIZE].ac97_tag & TAG_VALID; if(dev.codec_ready) { getrx(); if (bReadWaiting) { bReadWaiting = 0; wake_up(&dev.audio_in_wait); /* wake up any proces waiting for at least 1 fragment */ } } ac97_rx_lastfrag++; if (ac97_rx_lastfrag>=FRAG_NUM) { ac97_rx_lastfrag = 0; } return 0;}ssize_t ac97_audio_write(const uint16_t* pcmdata, size_t len){ int i; short tmptail; short realCount; if ((!dev.codec_ready) || (!dev.codec_initialized)) { return 0; } tmptail = txTail+1; if(tmptail >= AC97_BUFFER_SIZE) { tmptail = 0; } if (tmptail == txHead) { return 0; } realCount = 0; tmptail = txTail; for(i=0; i<len; i++) { tmptail++; if (tmptail >= AC97_BUFFER_SIZE) { tmptail = 0; } if (tmptail == txHead) { break; } txbuf[txTail] = pcmdata[i]; txTail = tmptail; realCount++; } return realCount; }extern unsigned char lightstatus;#define MUTE_SHUT 0x01#define LCD_LIGHT_ADDR 0x203f6000 ///#define pLCD_LIGHT_ADDR ((volatile unsigned char *)LCD_LIGHT_ADDR)unsigned char tx(){ int i; unsigned long tmpData1,tmpData2,tmpData3; unsigned short *pSrc; struct ac97_frame* dest; unsigned long tmpSrc; unsigned int Bitmappos; dest = (struct ac97_frame*)&dev.txbuf[ac97_tx_lastfrag*FRAG_SIZE]; for (i=0;i<FRAG_SIZE;i++) { Bitmappos = 0x0001 << curBitmapCol; if (pBitmap[curBitmapRow] & Bitmappos) { if(txHead != txTail) { tmpSrc = txbuf[txHead++]; if(txHead >= AC97_BUFFER_SIZE) { txHead = 0; } tmpData2 = (tmpSrc & 0xf000) >> 12; tmpData3 = (tmpSrc & 0x0fff) << 4; dest->ac97_pcmleft12_pcmright4 = tmpData2 ; dest->ac97_pcmright16 = tmpData3; if (bStereo) { tmpSrc = txbuf[txHead++]; if(txHead >= AC97_BUFFER_SIZE) { txHead = 0; } } tmpData2 = (tmpSrc & 0xff00) >> 8; tmpData3 = (tmpSrc & 0x00ff) << 8; dest->ac97_cmddataL8_pcmleftH8 = tmpData2 ; dest->ac97_pcmleft12_pcmright4 |= tmpData3; dest->ac97_tag = TAG_VALID | TAG_PCM; } else { dest->ac97_cmddataL8_pcmleftH8 = 0 ; dest->ac97_pcmleft12_pcmright4 = 0; dest->ac97_pcmright16 = 0; dest->ac97_tag = TAG_VALID | TAG_PCM; } } else { dest->ac97_cmddataL8_pcmleftH8 = 0 ; dest->ac97_pcmleft12_pcmright4 = 0; dest->ac97_pcmright16 = 0; dest->ac97_tag = TAG_VALID; } dest ++; curBitmapCol ++; if(curBitmapCol >= 32) { curBitmapCol = 0; curBitmapRow ++; if (curBitmapRow >= BitmapLen) { curBitmapRow = 0; } } } return 1;}int ac97_sport_handle_tx(void){ short i; int tmpFrag; int status=0; _ac97_cmd_t *pac97_cmd; status = bfin_read_DMA4_IRQ_STATUS(); if( !(status & DMA_DONE) ) { bfin_write_DMA4_IRQ_STATUS(status); return -EINPROGRESS; } bfin_write_DMA4_IRQ_STATUS(DMA_DONE); if(dev.codec_ready) { struct ac97_frame* dest; if (!dev.codec_initialized) { init_ac97();// return; } memset ((char *)&dev.txbuf[ac97_tx_lastfrag*FRAG_SIZE],0,FRAG_SIZE*sizeof(struct ac97_frame)); tx(); dest = (struct ac97_frame*)&dev.txbuf[ac97_tx_lastfrag*FRAG_SIZE]; dest += 6; while (pac97_cmd = outqueue_cmd()) { dest->ac97_tag |= TAG_VALID | TAG_CMD; dest->ac97_addr = pac97_cmd->reg; dest->ac97_addr4_data12 = (pac97_cmd->value >> 4) & 0x0fff; dest->ac97_cmddataL8_pcmleftH8 |= (pac97_cmd->value << 12) & 0xf000; dest += 6; //printk("cmd:reg = %x val=%x\n",pac97_cmd->reg,pac97_cmd->value); } if (bWriteWaiting) { bWriteWaiting = 0; wake_up(&dev.audio_out_wait); } } // codec ready ac97_tx_lastfrag++; if (ac97_tx_lastfrag >= FRAG_NUM) { ac97_tx_lastfrag = 0; } return 0;} // handle txint ac97_audio_read_min_bytes(){ int read_max; if ((!dev.codec_ready) || (!dev.codec_initialized)) { //printk("not ready\n"); return 0; } if(rxTail < rxHead ) { read_max = AC97_BUFFER_SIZE - rxHead + rxTail; } else { read_max = rxTail - rxHead; } return read_max; }int ac97_wait_for_audio_read_with_timeout(unsigned long timeout){ bReadWaiting = 1; return interruptible_sleep_on_timeout(&dev.audio_in_wait, timeout);}int ac97_wait_for_audio_write_with_timeout(unsigned long timeout){ bWriteWaiting = 1; return interruptible_sleep_on_timeout(&dev.audio_out_wait, timeout);}//only for 48Kint ac97_audio_write_max_bytes(void){ int write_max; if ((!dev.codec_ready) || (!dev.codec_initialized)) { return 0; } if(txTail >= txHead ) { write_max = AC97_BUFFER_SIZE - txTail + txHead; } else { write_max = txHead - txTail; } return write_max; }void ac97_set_sample_rate(unsigned int rate){ ac97_sport_set_register(AC97_PCM_FRONT_RATE,rate); ac97_sport_set_register(AC97_PCM_LR_RATE,rate); ac97_sport_get_register(AC97_PCM_FRONT_RATE); ac97_sport_get_register(AC97_PCM_LR_RATE);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -