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

📄 audio.c

📁 9200下的音频驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
#include "khead.h"
#include "/HHARM9200/linux-2.4.19-rmk7/drivers/sound/sound_config.h"   /*include many macro definiation */
#include "/HHARM9200/linux-2.4.19-rmk7/drivers/sound/dev_table.h"      /*sound_install_audiodrv()... */
#include <linux/soundcard.h>
#include "sound.h"
#include <asm-arm/arch-at91rm9200/pio.h>
#include <asm-arm/arch-at91rm9200/AT91RM9200_PDC.h>
#include <asm-arm/arch-at91rm9200/AT91RM9200_SSC.h>
#include <asm-arm/arch-at91rm9200/AT91RM9200_SYS.h>
#include <asm-arm/arch-at91rm9200/AT91RM9200_AIC.h>
#include "lib_SSC.h"
                                                                                

//#define DPRINTK(fmt, args...) printk(KERN_ALERT fmt, ## args)
#define DPRINTK(fmt, args...)
AT91PS_SSC  ssc_regs;
AT91PS_PDC  pdc_regs;
AT91PS_AIC   aic_regs;
                                                                                
/* WELL add, uda1380 i2c commands */
extern unsigned int I2C_test(void);
extern unsigned int I2C_read(unsigned int reg, unsigned int *_data, int);
extern unsigned int I2C_write(unsigned int reg, unsigned int data, int);

#define I2S_ASY_MASTER_TX_SETTING(nb_bit_by_slot, nb_slot_by_frame)( +\AT91C_SSC_CKS_DIV   +\AT91C_SSC_CKO_CONTINOUS      +\AT91C_SSC_START_FALL_RF +\((1<<16) & AT91C_SSC_STTDLY) +\((((nb_bit_by_slot*nb_slot_by_frame)/2)-1) <<24))#define I2S_ASY_TX_FRAME_SETTING(nb_bit_by_slot, nb_slot_by_frame)( +\(nb_bit_by_slot-1)  +\AT91C_SSC_MSBF   +\(((nb_slot_by_frame-1)<<8) & AT91C_SSC_DATNB)  +\(((nb_bit_by_slot-1)<<16) & AT91C_SSC_FSLEN) +\AT91C_SSC_FSOS_NEGATIVE)                                                                                #define EVMODE          0x00#define I2SIO           0x01#define POWCON          0x02#define ANAMIX          0x03#define HPAM            0x04#define MASVOLCON       0x10#define MIXVOLCON       0x11#define MODSEL          0x12#define MASMUT          0x13#define MIXSD           0x14#define DECVOLCON       0x20#define PGAMUT          0x21#define ADCCON          0x22#define AGCCON          0x23#define RESL3           0x7F#define DECSTA          0x28#define INTFILSTA       0x18                                                                                /*Sample rate define */#define     k8                  8000#define     k11025              11025#define     k16                 16000#define     k2205               22050#define     k32                 32000#define     k441                44100#define     k48                 48000                                                                                #define     SR_REG              0x01#define     AVOL                0x02#define     GCFG                0x03                                                                                /*********************************************************************************** *This to store the control word for codec uda1380 * ********************************************************************************/static UINT8 mesgbuf[4];static UINT8 judge[2];/*********************************************************************************** *  Gloab var * ********************************************************************************/static UINT32 ssi_dma;static UINT32 ssi_bits;static UINT32 ssi_channel;static UINT32 ssi_speed;static UINT32 ssi_busy;static UINT32 open_mode;                                                                                 
static int audio_dev_dsp;int ssi_audiodev;struct pm_dev *pmdev;U32 myenable = ~0;


struct a9200_fomat {
        unsigned int format;
        unsigned int bits;
} a9200_formattable[] = {
        {AFMT_MU_LAW,8},{AFMT_A_LAW,8},{AFMT_IMA_ADPCM,8},{AFMT_U8,8},{AFMT_S16_LE,16},{AFMT_S16_BE,16},{AFMT_S8,8},{AFMT_U16_LE,16},{AFMT_U16_BE,16},};
                                                                                
#define FORMATSIZE (sizeof(a9200_formattable) / sizeof(struct a9200_format))

void set_pm(int number)
{
        unsigned long tmp;
        unsigned long num;
        num = (unsigned long) number;
        //tmp = REG(SSI_STCCR);
        tmp &= 0xff00;
        tmp |= num;
        //WREG(SSI_STCCR, tmp);
}

unsigned char uda1380_init[] = {
       //0x00, 0x0F, 0x06, //Sysclock
        0x00, 0x0F, 0x32,     //WSPLL 44.1KHz
        0x01, 0x00, 0x00,
        0x02, 0x00, 0x00,       //
        0x03, 0x00, 0x00,
        0x04, 0x02, 0x02,   //default
        0x10, 0x20, 0x20,
        0x11, 0xb0, 0xb0,
        0x12, 0x00, 0x00,
        0x13, 0x00, 0x00,
        0x14, 0x00, 0x00,
        0x20, 0x00, 0x00,
        0x21, 0x80, 0x00,
        0x22, 0x00, 0x00,       //line-in
        //0x22, 0x00, 0x0C,             //mic
        0x23, 0x00, 0x00
};

unsigned char uda1380_tx_init[]={
        //0x00, 0x0F, 0x06, //Sysclock
        0x00, 0x0F, 0x32,     //WSPLL 44.1KHz
        0x01, 0x00, 0x00,
        0x02, 0xa5, 0xdf,       //
        0x03, 0x00, 0x00,
        0x04, 0x02, 0x02,   //default
        0x10, 0x00, 0x00,
        0x11, 0x00, 0x00,
        0x12, 0x00, 0x00,
        0x13, 0x00, 0x00,
        0x14, 0x00, 0x00,
        0x20, 0x00, 0x00,
        0x21, 0x00, 0x00,
        0x22, 0x00, 0x00,       //line-in
        //0x22, 0x00, 0x0C,             //mic
        0x23, 0x00, 0x00
};

unsigned char uda1380_rx_init[]={
    //0x00, 0x0F, 0x06, //Sysclock
        0x00, 0x0F, 0x32,     //WSPLL 44.1KHz
        0x01, 0x00, 0x00,    //IIS-bus INPUT AND OUTPUT SETTINGS
        0x02, 0xa5, 0xdf,    //power ctrl
        0x03, 0x00, 0x00,   //ANALOG MIXER SETTINGS
        0x04, 0x02, 0x02,   //default
        0x10, 0xb0, 0xb0,    //MASTER VOLUME CONTROL
        0x11, 0x00, 0x00,    //MIXER VOLUME CONTROL
        0x12, 0x00, 0x00,   //MODE,BASS BOOST AND TREBLE
        0x13, 0x00, 0x00,   //MASTER MUTE,CHANNEL DE-EMPHASIS AND MUTE
        0x14, 0x00, 0xc0,   //MIXER,SILENCE DETECTOR AND OVERSAMPLING SETTINGS
        0x20, 0x00, 0x00,   //DECIMATOR VOLUME CONTROL
        0x21, 0x00, 0x00,   //PGA SETTINGS AND MUTE
        0x22, 0x00, 0x00,       //line-in
        //0x22, 0x00, 0x0C,             //mic
        0x23, 0x00, 0x00    //AGC SETTINGS
};


unsigned char volume[]={
	0x00,0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x80,0x90
};	

/*
void change_volume(int ic)
{
        
        unsigned int msb, lsb, data, reg,tata;
                                                                                
//      PDEBUG("Testing I2C\n");
       switch (ic) 
	{       
     		case 100:
			I2C_write(0x10, volume[0], 2);
			break;
		case 100:
			I2C_write(0x10, volume[0], 2);
			break;
		case 100:
		       I2C_write(0x10, volume[0], 2);
			break;
			
		 default :
			ret = -EINVAL;
			break;
		
	        
	}
        for (ic = 0; ic < 42; ic += 3) {
                reg = command[ic];
                lsb = command[ic + 1];
                msb = command[ic + 2];
                data = msb << 8 | lsb;
                I2C_write(reg, data, 2);
 //              I2C_read(reg,&tata,2);
 //             printk("0x%p data set to = %p ( %p )\n",reg,tata,data);
        }
      printk("UDA1380 init ok...\n");
}
*/

void codec_init(unsigned char *command)
{
        int ic;
        unsigned int msb, lsb, data, reg,tata;
                                                                                
//      PDEBUG("Testing I2C\n");
       
        for (ic = 0; ic < 42; ic += 3) {
                reg = command[ic];
                lsb = command[ic + 1];
                msb = command[ic + 2];
                data = msb << 8 | lsb;
                I2C_write(reg, data, 2);
 //              I2C_read(reg,&tata,2);
 //             printk("0x%p data set to = %p ( %p )\n",reg,tata,data);
        }
      printk("UDA1380 init ok...\n");
}
                                                                                
void SSC_init(void)
{
         ssc_regs = (AT91PS_SSC) AT91C_VA_BASE_SSC1;
        pdc_regs = (AT91PS_PDC) AT91C_VA_BASE_PDC_SSC1;
        aic_regs = (AT91PS_AIC) AT91C_VA_BASE_AIC;
                                                                                
        AT91_SYS->PMC_PCER = 1 << AT91C_ID_SSC1;/* Peripheral Clock Enable */

//      printk("SSC_SR should be 0xCC,read value is %x\n",ssc_regs->SSC_SR);

        /*soft reset */
        ssc_regs->SSC_CR = AT91C_SSC_SWRST;
        /* Clear Transmit and Receive Counters */
        AT91F_PDC_Close(pdc_regs);

        AT91F_SSC_SetBaudrate(ssc_regs, AT91C_MASTER_CLOCK,FILE_SAMPLING_FREQ *
(BITS_BY_SLOT * SLOT_BY_FRAME));
                                                                                
        ssc_regs->SSC_IDR = 0xCFF;      //disabled all
                                                                                
        aic_regs->AIC_IECR = 0x1 << AT91C_ID_SSC1; //Enable interrupt
                                                                                
        /* SSC Transmit Clock Mode Register */
        ssc_regs->SSC_TCMR = I2S_ASY_MASTER_TX_SETTING(BITS_BY_SLOT,SLOT_BY_FRAME);
        /* SSC Transmit Frame Mode Register */
       ssc_regs->SSC_TFMR = I2S_ASY_TX_FRAME_SETTING(BITS_BY_SLOT,SLOT_BY_FRAME);

        /* SSC_RFMR */
        ssc_regs->SSC_RFMR = I2S_ASY_TX_FRAME_SETTING(BITS_BY_SLOT,SLOT_BY_FRAME);
        /* SSC_RCMR */
       ssc_regs->SSC_RCMR = I2S_ASY_MASTER_TX_SETTING(BITS_BY_SLOT,SLOT_BY_FRAME);
}



 /*                                                                               
static unsigned int ssi_audio_setbits(int dev, unsigned int bits)
{
}
                                                                                
static signed short ssi_audio_setchannel(int dev, signed short channels)
{
}
                                                                                
static int ssi_audio_setspeed(int dev, int speed)
{
}
*/

void a9200_mute(void)
{
}                                                                               
/******************************************************************************************************
* Input:
*       dev:         The major number of the device.
*       cmd:         The command to control the codec.
* Value Returned:    1       success.
*                    -1      falure.
*
* Description: This routine will be used to control the codec.
*
* Modification History:
*       8 JAN,2002, Initial version.                    Li Qin
*******************************************************************************************************/
/*
static int at91_mixer_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,unsigned long arg)
{
        int val, ret = 0;
        U32 tmpdata;
        U8 lsb, msb;
/*
	switch(cmd)
		{
		case LINEIN :
			I2C_write(0x22,0x0000,2);
			break;
		case MIC :
			I2C_write(0x22,0x0c00,2);
			break;
		default :
			ret = -EINVAL;
			break;
	        }

        return ret;
}  */
/*
static int rec_sound(struct inode *inode, struct file *filp, unsigned int cmd,unsigned long arg)
{
        int val, ret = 0;
        U32 tmpdata;
        U8 lsb, msb;

	switch (cmd) 
	{       
                case REC:
			codec_init(uda1380_rx_init);
                       break;
		 case SOUND:
		 	codec_init(uda1380_tx_init);
                       break;
		 default :
			ret = -EINVAL;
			break;
		
	        
	}

	return ret;
}
*/

static int at91_audio_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,unsigned long arg)
{
        int val, ret = 0;
        U32 tmpdata;
        U8 lsb, msb;
#if 1
	switch (cmd) {
		case REC:
			codec_init(uda1380_rx_init);
                       break;
		 case SOUND:
		 	codec_init(uda1380_tx_init);
                       break;
		case MUTE:
			I2C_write(0x02, 0x00<<8|0x00,2);
			 break;
               case 100:
		 	I2C_write(0x10, volume[0]<<8|volume[0],2);
			break;
		 case 101:
		 	I2C_write(0x10, volume[1]<<8|volume[1], 2);
			break;
		 case 102:
		 	I2C_write(0x10, volume[2]<<8|volume[2], 2);
			break;
		 case 103:
		 	I2C_write(0x10, volume[3]<<8|volume[3], 2);
			break;
		 case 104:
		 	I2C_write(0x10, volume[4]<<8|volume[4], 2);
			break;
		 case 105:
		 	I2C_write(0x10, volume[5]<<8|volume[5], 2);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -