📄 audio.c
字号:
#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 + -