?? wtaudioout.c
字號:
/****************************************************************************//* * WTAudioOut.c -- audio driver for M5249 ColdFire internal audio. * * (C) Copyright 2004, AKGU *//****************************************************************************/#ifdef MODULE#include <linux/module.h>#include <linux/version.h>#else#define MOD_INC_USE_COUNT#define MOD_DEC_USE_COUNT#endif#ifndef __KERNEL__#define __KERNEL__#endif#include <linux/config.h>#include <linux/types.h>#include <linux/kernel.h>#include <linux/init.h>#include <linux/fs.h>#include <linux/slab.h>#include <linux/wait.h>#include <linux/major.h>#include <linux/delay.h>#include <linux/soundcard.h>#include <linux/ioctl.h>#include <linux/mm.h>#include <asm/uaccess.h>#include <asm/param.h>#include <asm/dma.h>#include <asm/irq.h>#include <asm/page.h>#include <asm/io.h>#include <asm/semaphore.h>/****************************************************************************///#define DEBUG 1//#define MYDEBUG 1#ifdef DEBUG#define KDEBUG(fmt, args...) printk(fmt, ##args)#else#define KDEBUG(fmt, args...) #endif//#define NOMAP//#define MYDEBUG 1/****************************************************************************///DATA TYPE DEFINE#define DWORD volatile unsigned long#define BYTE volatile unsigned char#define WORD volatile unsigned short/****************************************************************************//* Whether include receive functions *///#define RX/* You can choose to use either interrupt or DMA here. * DMA will give you much better CPU utilitization... *///#define CONFIG_TXIRQ 1#define CONFIG_TXDMA 1//Only PDIR2 and PDOR3 registers support DMA//Both DMA1req and DMA0req can be routed to DMA channel 0 or DMA channel 1.//DMA Config Register Address(MBAR2+0x9f)//DMACon[1:0] = [DMA1REQ:DMA0REQ] -- 0(PDIR2)... 1(PDOR3)#define INTBASE 128//#define WTAUDIO_TXIRQ (INTBASE+4) /* Audio TX FIFO IRQ (IIS1) */ /* WRITE TO FIFO IIS1 */ #define WTAUDIO_TXDMAIRQ 120 /* Audio TX DMA IRQ */#define WTAUDIO_TXDMA 0 /* Audio TX DMA channel *//****************************************************************************//* * Driver configurable settings.*///#define BUFSIZE (256*1024) /* Audio buffer data size */#define ADSAMP_PER_PACK ((508-4)*2+1) //1包adpcm 的數據轉換成upcm給音頻芯片所需要聲請的緩沖區大小#define BUFSIZE (128*4*ADSAMP_PER_PACK) /* Audio buffer data size (緩沖區分成4塊進行DMA傳輸)*/#define DMASIZE (32*4*ADSAMP_PER_PACK) /* DMA buffer maximum size (1/4 buffer)*/ #define PACKCOUNT (BUFSIZE/ADSAMP_PER_PACK) //緩沖區包個數#define DMACOUNT (DMASIZE/ADSAMP_PER_PACK) //DMA緩沖區最大包個數#define AUDIOOUTMAJOR 253#define FIELDNUM 6int WTAudio_txbusy,WTAudio_txdmaing,WTAudio_isopen;//struct semaphore sem;//BYTE DelayBuf[ADSAMP_PER_PACK];/****************************************************************************/#define IOC_MAGIC ('k')#define IOCASTOP _IO(IOC_MAGIC,0)#define IOCASTART _IO(IOC_MAGIC,1)#define IOCASPACKSIZE _IOW(IOC_MAGIC,2,int)#define IOCAGDEVBUFSTATUS _IOR(IOC_MAGIC,3,sizeof(WTDevBufStatus))#define IOCAGDEVSTATUS _IOR(IOC_MAGIC,4,sizeof(WTAudio_dev)) /****************************************************************************///*** base register define#define MCF_MBAR 0x10000000#define MCF_MBAR2 0x80000000/* * Quick and easy access to the audio registers. (This optimizes * nicely, since it will almost always be a constant pointer). */ //*** pointer for mem space#define mcf32p(r) ((DWORD *) (r))#define mcf16p(r) ((WORD *) (r))#define mcf8p(r) ((BYTE *) (r))//*** pointer for mbar register#define mcfReg32p(r) (mcf32p(MCF_MBAR + (r)))#define mcfReg16p(r) (mcf16p(MCF_MBAR + (r)))#define mcfReg8p(r) (mcf8p(MCF_MBAR + (r)))//*** pointer for 5249 mbar2 register#define mcf2Reg32p(r) (mcf32p(MCF_MBAR2 + (r)))#define mcf2Reg16p(r) (mcf16p(MCF_MBAR2 + (r)))#define mcf2Reg8p(r) (mcf8p(MCF_MBAR2 + (r)))/* register define */#define MCFSIM_IMR 0x44 /* Interrupt Mask reg (r/w) */#define MCFSIM_ICRDMA0 0x52 /* DMA 0 ICR [ICR6]*/#define MCFSIM_IMR_DMA0 0x4000 /* DMA 0 intr */#define MCFSIM_ICRDMA1 0x53 /* DMA 1 ICR [ICR7]*/#define MCFSIM_IMR_DMA1 0x8000 /* DMA 0 intr *//* * Flags for the DMA configuration register. */#define MCFA_DMA_0REQ 0x01 /* PDOR3 DMA on chan 0 */#define MCFA_DMA_1REQ 0x02 /* PDOR3 DMA on chan 1 *//* DMA register base mbr*/#define MCFDMA_INTVR0 0x314 /* DMA0 interrupt vec (r/w) */#define MCFDAM_INTVR1 0x354 /* DMA1 interrupt vec (r/w) */#define MCFA_IISCONFIG 0x10 /* IIS config regs (r/w) */#define MCFA_IIS1CONFIG 0x10 /* IIS1 config reg (r/w) */#define MCFA_IIS2CONFIG 0x14 /* IIS2 config reg (r/w) */#define MCFA_IIS3CONFIG 0x18 /* IIS3 config reg (r/w) */#define MCFA_IIS4CONFIG 0x1c /* IIS4 config reg (r/w) */#define MCFA_DATAINCTRL 0x30 /* Data in Control reg (r/w) *//* * Bit definitions for the ICR family of registers. */#define MCFSIM_ICR_AUTOVEC 0x80 /* Auto-vectored intr */#define MCFSIM_ICR_LEVEL0 0x00 /* Level 0 intr */#define MCFSIM_ICR_LEVEL1 0x04 /* Level 1 intr */#define MCFSIM_ICR_LEVEL2 0x08 /* Level 2 intr */#define MCFSIM_ICR_LEVEL3 0x0c /* Level 3 intr */#define MCFSIM_ICR_LEVEL4 0x10 /* Level 4 intr */#define MCFSIM_ICR_LEVEL5 0x14 /* Level 5 intr */#define MCFSIM_ICR_LEVEL6 0x18 /* Level 6 intr */#define MCFSIM_ICR_LEVEL7 0x1c /* Level 7 intr */#define MCFSIM_ICR_PRI0 0x00 /* Priority 0 intr */#define MCFSIM_ICR_PRI1 0x01 /* Priority 1 intr */#define MCFSIM_ICR_PRI2 0x02 /* Priority 2 intr */#define MCFSIM_ICR_PRI3 0x03 /* Priority 3 intr */#define MCFA_DMACONF 0x9f /* Audio DMA config (r/w) */#define MCFSIM2_DMAROUTE 0x188 /* DMA routing */#define MCFA_PDIR1L 0x34 /* Data in left #1 (r) */#define MCFA_PDIR3L 0x44 /* Data in left #3 (r) */#define MCFA_PDIR1R 0x54 /* Data in right #1 (r) */#define MCFA_PDIR3R 0x64 /* Data in right #3 (r) */#define MCFA_PDOR1L 0x34 /* Data out left #1 (w) */#define MCFA_PDOR1R 0x44 /* Data out right #1 (w) */#define MCFA_PDOR2L 0x54 /* Data out left #2 (w) */#define MCFA_PDOR2R 0x64 /* Data out right #2 (w) */#define MCFA_PDOR3 0x74 /* Data out l+r #3 (w) */#define MCFA_PDIR2 0x74 /* Data in l+r #2 (w) */#define MCFA_INTENABLE 0x94 /* Interrupt enable (r/w) */#define MCFA_INTCLEAR 0x98 /* Interrupt clear (w) */#define MCFA_INTSTAT 0x98 /* Interupt status (r) *//* * Flag defines for the IIS configuration registers. */#define MCFA_IIS_EFCFLG 0x00040000 /* EF/CFLG insert */#define MCFA_IIS_CFLGPOS 0x00020000 /* CFLG sample position */#define MCFA_IIS_CLKINPUT 0x00000000 /* CLK is SCLK/LRCLK input */#define MCFA_IIS_CLK24 0x00001000 /* CLK is AudioClk/24 */#define MCFA_IIS_CLK16 0x00002000 /* CLK is AudioClk/16 */#define MCFA_IIS_CLK12 0x00003000 /* CLK is AudioClk/12 */#define MCFA_IIS_CLK8 0x00004000 /* CLK is AudioClk/8 */#define MCFA_IIS_CLK6 0x00005000 /* CLK is AudioClk/6 */#define MCFA_IIS_CLK4 0x00006000 /* CLK is AudioClk/4 */#define MCFA_IIS_CLK3 0x00007000 /* CLK is AudioClk/3 */#define MCFA_IIS_CLK2 0x0000c000 /* CLK is AudioClk/2 */#define MCFA_IIS_CLKIIS1 0x00008000 /* CLK is IIS1 clock */#define MCFA_IIS_CLKIIS2 0x00009000 /* CLK is IIS2 clock */#define MCFA_IIS_CLKIIS3 0x0000a000 /* CLK is IIS3 clock */#define MCFA_IIS_CLKIIS4 0x0000b000 /* CLK is IIS4 clock */#define MCFA_IIS_FIFO 0x00000000 /* Normal FIFO operation */#define MCFA_IIS_FIFO1 0x00000800 /* 1 sample FIFO mode */#define MCFA_IIS_TXSRC_0 0x00000000 /* TX source is digital 0 */#define MCFA_IIS_TXSRC_PDOR1 0x00000100 /* TX source is PDOR1 */#define MCFA_IIS_TXSRC_PDOR2 0x00000200 /* TX source is PDOR2 */#define MCFA_IIS_TXSRC_PDOR3 0x00000300 /* TX source is PDOR3 */#define MCFA_IIS_TXSRC_IIS1 0x00000400 /* TX source is IIS1 in data */#define MCFA_IIS_TXSRC_IIS3 0x00000500 /* TX source is IIS3 in data */#define MCFA_IIS_TXSRC_IIS4 0x00000600 /* TX source is IIS4 in data */#define MCFA_IIS_TXSRC_EBU 0x00000700 /* TX source is EBU in data */#define MCFA_IIS_TXSRC_EBU2 0x00010000 /* TX source is EBU2 in data */#define MCFA_IIS_16BIT 0x00000000 /* 16 bit samples */#define MCFA_IIS_18BIT 0x00000040 /* 18 bit samples */#define MCFA_IIS_20BIT 0x00000080 /* 20 bit samples */#define MCFA_IIS_0BIT 0x000000c0 /* 0 sample */#define MCFA_IIS_MODE_IIS 0x00000000 /* Philips IIS mode */#define MCFA_IIS_MODE_EIAJ 0x00000000 /* Sony EIAJ mode */#define MCFA_IIS_LRCK64BIT 0x00000010 /* LRCK frequency 64 bit clk */#define MCFA_IIS_LRCK48BIT 0x00000008 /* LRCK frequency 48 bit clk */#define MCFA_IIS_LRCK32BIT 0x00000000 /* LRCK frequency 32 bit clk */#define MCFA_IIS_LRCKINV 0x00000002 /* Invert LRCK */#define MCFA_IIS_SCLKINV 0x00000001 /* Invert SCLK *//* * Data in Control register flags. */#define MCFA_DIC_PDIR3_0 0x00800000 /* PDIR3 zero control */#define MCFA_DIC_PDIR3_RESET 0x00400000 /* PDIR3 reset */#define MCFA_DIC_PDIR3_1SAMP 0x00000000 /* PDIR3 full on 1 sample */#define MCFA_DIC_PDIR3_2SAMP 0x00100000 /* PDIR3 full on 2 sample */#define MCFA_DIC_PDIR3_3SAMP 0x00200000 /* PDIR3 full on 3 sample */#define MCFA_DIC_PDIR3_6SAMP 0x00300000 /* PDIR3 full on 6 sample */#define MCFA_DIC_PDIR3_OFF 0x00000000 /* PDIR3 Disabled */#define MCFA_DIC_PDIR3_PDOR1 0x00010000 /* PDIR3 PDOR1 data */#define MCFA_DIC_PDIR3_PDOR2 0x00020000 /* PDIR3 PDOR2 data */#define MCFA_DIC_PDIR3_IIS1 0x00040000 /* PDIR3 IIS1 receiver data */#define MCFA_DIC_PDIR3_IIS3 0x00050000 /* PDIR3 IIS3 receiver data */#define MCFA_DIC_PDIR3_IIS4 0x00060000 /* PDIR3 IIS4 receiver data */#define MCFA_DIC_PDIR3_EBU1 0x00070000 /* PDIR3 EBU1 receiver data */#define MCFA_DIC_PDIR3_EBU2 0x00080000 /* PDIR3 EBU2 receiver data */#define MCFA_DIC_PDIR2_1SAMP 0x00000000 /* PDIR2 full on 1 sample */#define MCFA_DIC_PDIR2_2SAMP 0x00004000 /* PDIR2 full on 2 sample */#define MCFA_DIC_PDIR2_3SAMP 0x00008000 /* PDIR2 full on 3 sample */#define MCFA_DIC_PDIR2_6SAMP 0x0000c000 /* PDIR2 full on 6 sample */#define MCFA_DIC_PDIR2_0 0x00000800 /* PDIR2 zero control */#define MCFA_DIC_PDIR1_0 0x00000400 /* PDIR1 zero control */#define MCFA_DIC_PDIR2_RESET 0x00000200 /* PDIR2 reset */#define MCFA_DIC_PDIR1_RESET 0x00000100 /* PDIR1 reset */#define MCFA_DIC_PDIR1_1SAMP 0x00000000 /* PDIR1 full on 1 sample */#define MCFA_DIC_PDIR1_2SAMP 0x00000040 /* PDIR1 full on 2 sample */#define MCFA_DIC_PDIR1_3SAMP 0x00000080 /* PDIR1 full on 3 sample */#define MCFA_DIC_PDIR1_6SAMP 0x000000c0 /* PDIR1 full on 6 sample */#define MCFA_DIC_PDIR2_OFF 0x00000000 /* PDIR2 disable */#define MCFA_DIC_PDIR2_PDOR1 0x00000008 /* PDIR2 PDOR1 data */#define MCFA_DIC_PDIR2_PDOR2 0x00000010 /* PDIR2 PDOR2 data */#define MCFA_DIC_PDIR2_IIS1 0x00000020 /* PDIR2 IIS1 data */#define MCFA_DIC_PDIR2_IIS3 0x00000028 /* PDIR2 IIS3 data */#define MCFA_DIC_PDIR2_IIS4 0x00000030 /* PDIR2 IIS4 data */#define MCFA_DIC_PDIR2_EBU1 0x00000038 /* PDIR2 EBU1 data */#define MCFA_DIC_PDIR2_EBU2 0x00002000 /* PDIR2 EBU1 data */#define MCFA_DIC_PDIR1_OFF 0x00000000 /* PDIR1 disable */#define MCFA_DIC_PDIR1_PDOR1 0x00000001 /* PDIR1 PDOR1 data */#define MCFA_DIC_PDIR1_PDOR2 0x00000002 /* PDIR1 PDOR2 data */#define MCFA_DIC_PDIR1_IIS1 0x00000004 /* PDIR1 IIS1 data */#define MCFA_DIC_PDIR1_IIS3 0x00000005 /* PDIR1 IIS3 data */#define MCFA_DIC_PDIR1_IIS4 0x00000006 /* PDIR1 IIS4 data */#define MCFA_DIC_PDIR1_EBU1 0x00000007 /* PDIR1 EBU1 data */#define MCFA_DIC_PDIR1_EBU2 0x00001000 /* PDIR1 EBU2 data *///DMA REGISTER#define MCFDMA_DCR0 0x308 /* DMA status reg (r/w) */#define MCFDMA_DCR1 0x348 /* DMA status reg (r/w) */#define MCFDMA_DSR0 0x310 /* DMA status reg (r/w) */#define MCFDMA_DSR1 0x350 /* DMA status reg (r/w) */#define MCFDMA_SAR0 0x300 /* DMA status reg (r/w) */#define MCFDMA_SAR1 0x340 /* DMA status reg (r/w) */#define MCFDMA_DAR0 0x304 /* DMA status reg (r/w) */#define MCFDMA_DAR1 0x344 /* DMA status reg (r/w) */#define MCFDMA_BCR0 0x30C /* DMA status reg (r/w) */#define MCFDMA_BCR1 0x34C /* DMA status reg (r/w) *///#define DMA0_STATUE(x) (((*mcfReg8p(MCFDMA_DSR0))<<x)&0x01)//#define DMA1_STATUE(x) (((*mcfReg8p(MCFDMA_DSR1))<<x)&0x01)#define DMA0_STATUE (*mcfReg8p(MCFDMA_DSR0))#define DMA1_STATUE (*mcfReg8p(MCFDMA_DSR1))#define DMA0_CTL (*mcfReg32p(MCFDMA_DCR0))#define DMA1_CTL (*mcfReg32p(MCFDMA_DCR1))#define DMA0_SA (*mcfReg32p(MCFDMA_SAR0))#define DMA1_SA (*mcfReg32p(MCFDMA_SAR1))#define DMA0_DA (*mcfReg32p(MCFDMA_DAR0))#define DMA1_DA (*mcfReg32p(MCFDMA_DAR1))#define DMA0_BC (*mcfReg16p(MCFDMA_BCR0))#define DMA1_BC (*mcfReg16p(MCFDMA_BCR1))/* * General purpose IO registers (in MBAR2). */#define MCFSIM2_GPIOREAD 0x0 /* GPIO read values */#define MCFSIM2_GPIOWRITE 0x4 /* GPIO write values */#define MCFSIM2_GPIOENABLE 0x8 /* GPIO enabled */#define MCFSIM2_GPIOFUNC 0xc /* GPIO function */#define MCFSIM2_GPIO1READ 0xb0 /* GPIO1 read values */#define MCFSIM2_GPIO1WRITE 0xb4 /* GPIO1 write values */#define MCFSIM2_GPIO1ENABLE 0xb8 /* GPIO1 enabled */#define MCFSIM2_GPIO1FUNC 0xbc /* GPIO1 function */#define MCF_SDATAI3 0x00000200#define MCF_SDATAI4 0x00000400/****************************************************************************/// audio devicetypedef struct WTAudio_dev{ int major; //int tx_irq; //中斷方式的中斷號 int tx_nBufT; //當前讀寫緩沖區位置指示(以包為單位) //int tx_nBufB; //當前讀寫緩沖區位置頭指示(以包為單位) int tx_nDmaStart; //DMA讀寫緩沖區位置頭指示(以包為單位) int tx_nDmaCount; //DMA需要傳送的包個數 //unsigned long SysDelay; unsigned long mmstart; //buffer base addr unsigned long mmsize; //mmsize = packsize*packcount unsigned long dmasize; //dma buffer size dmasize = packsize*dmacount unsigned long packsize; //adpcm:1009 upcm: 508 unsigned long mmcount; // mmsize/packsize unsigned long dmacount; // dmasize/packsize}WTAudio_dev;unsigned char * WTAudio_buf;WTAudio_dev AudioDev={AUDIOOUTMAJOR,//WTAUDIO_TXIRQ, 0,0,0,0,BUFSIZE,DMASIZE,ADSAMP_PER_PACK,PACKCOUNT,DMACOUNT};#define BUFFERINC(x,y,z) ((x+y)%z) //z: num of package y: inc x: indicatetypedef struct WTDevBufStatus{ int tx_nBufT; //int tx_nBufB; int tx_nDmaStart;}WTDevBufStatus;/****************************************************************************/void WTAudio_chipinit(void){#if DEBUG printk("WTAudio_chipinit()\n");#endif //*mcf2Reg32p(MCFA_IIS2CONFIG) = MCFA_IIS_CLK8 | MCFA_IIS_TXSRC_IIS1 | // MCFA_IIS_16BIT | MCFA_IIS_MODE_IIS | MCFA_IIS_LRCK32BIT; //*mcf2Reg32p(MCFA_IIS1CONFIG) = MCFA_IIS_CLK8 | MCFA_IIS_TXSRC_PDOR3 | //MCFA_IIS_16BIT | MCFA_IIS_MODE_IIS | MCFA_IIS_LRCK32BIT;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -