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

📄 jadei2s.c

📁 Audio codec--TLV320AIC31 驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
/********************************************/
/* Jadei2s.c    : IIS module driver sources     */
/* Author   : 	jade	 yolanda		*/
/* Time     : 2007-8-6		    		*/
/********************************************/


#include "linux/types.h"
#include <linux/major.h>
#include <linux/vmalloc.h>
#include <linux/init.h>
#include <linux/poll.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/blkdev.h>
#include <linux/bitops.h>
#include <asm/io.h>
#include <linux/delay.h>
#include <asm/uaccess.h>
#include <asm-generic/errno-base.h>
#include <asm/sizes.h>
#include <linux/interrupt.h>

#include <asm/dma.h>
#include <asm/mach/dma.h>
#include <linux/completion.h>
#include <asm/arch/platform.h>

#include "apb_i2c_module.h"


#define IIS_BASE_HW        0x2003a000

#define IIS_CR0      	((volatile int *)(IIS_BASE + 0x000))
#define IIS_CR1      	((volatile int *)(IIS_BASE + 0x004))
#define IIS_SDR        	((volatile int *)(IIS_BASE + 0x008))
#define IIS_SSR       	((volatile int *)(IIS_BASE + 0x00C))
#define IIS_CPSR        ((volatile int *)(IIS_BASE + 0x010))
#define IIS_IMSC     	((volatile int *)(IIS_BASE + 0x014))
#define IIS_RIS      	((volatile int *)(IIS_BASE + 0x018))
#define IIS_MIS        	((volatile int *)(IIS_BASE + 0x01C))
#define IIS_ICR       	((volatile int *)(IIS_BASE + 0x020))
#define IIS_DMACR       ((volatile int *)(IIS_BASE + 0x024))

u32 IIS_BASE;

static unsigned char script_wm8976[][3] = {//LOUT2,ROUT2 , out DAC IN I2S SLAVE MODE.MIC in
{0x34,0x00,0x00},//R0  0X000				
{0x34,0x02,0x1d},//R1  0X00D
{0x34,0x04,0x15},//R2  0X011
{0x34,0x06,0x6F},//R3  0X00F
{0x34,0x08,0x10},//R4  0X010
{0x34,0x0a,0x00},//R5  0X000
{0x34,0x0c,0x00},//R6  0X000
{0x34,0x0e,0x00},//R7  0X000
{0x34,0x17,0xff},//R11 0X1FF
{0x34,0x19,0xff},//R12 0X1FF 
{0x34,0x31,0x32},//R24,0x132
{0x34,0x56,0x10}, //R43,0X010
{0x34,0x58,0x03},//R44 0X000
{0X34,0x62,0xd6},//R49 0X042
{0x34,0x64,0x01},//R50 0X001
{0x34,0x66,0x01},//R51 0X001
{0x34,0x6d,0x3f},//R54 0x13f
{0x34, 0x6f,0x3f },//R55 0x13f
};

static unsigned char script_wm8976_p[][3] = {//LOUT2,ROUT2 , out DAC IN I2S SLAVE MODE
{0x34,0x00,0x00},//R0  0X000				USED FOR PALYBACK()
{0x34,0x02,0x0d},//R1  0X00D	
{0x34,0x04,0x00},//R2  0X00
{0x34,0x06,0x6F},//R3  0X00F
{0x34,0x08,0x10},//R4  0X010
{0x34,0x0a,0x00},//R5  0X000
{0x34,0x0c,0x00},//R6  0X000
{0x34,0x17,0xff},//R11 0X1FF
{0x34,0x19,0xff},//R12 0X1FF 
{0x34,0x56,0x10}, //R43,0X010
{0X34,0x62,0x6},//R49 0X042
{0x34,0x64,0x01},//R50 0X001
{0x34,0x66,0x01},//R51 0X001
{0x34,0x6d,0x3f},//R54 0x13f
{0x34, 0x6f,0x3f },//R55 0x13f
};

static unsigned char script_wm8976_m[][3] = {//MIC
		{0x34,0x00,0x00},//R0  0X000
		{0x34,0x02,0x1d},//R1  0X00D
		{0x34,0x04,0x15},//R2  0X011
		{0x34,0x06,0x00},//R3  0X000
		{0x34,0x08,0x10},//R4  0X010
		{0x34,0x0a,0x00},//R5  0X000
		{0x34,0x0c,0x00},//R6  0X000
		{0x34,0x0e,0x00},//R7  0X000
		{0x34,0x1F,0xff},//R15 0X1FF 
		{0x34,0x58,0x03},//R44 0X000
		{0x34,0x5B,0x3F},//R45 0X110 
		{0x34,0x5E,0x00} //R47 0X005
};
static unsigned char script_wm8976_l[][3] = {//line in
{0x34,0x00,0x00},//R0  0X000
{0x34,0x02,0x0d},//R1  0X00D
{0x34,0x04,0x11},//R2  0X015
{0x34,0x06,0x00},//R3  0X000
{0x34,0x08,0x10},//R4  0X010
{0x34,0x0a,0x00},//R5  0X000
{0x34,0x0c,0x00},//R6  0X000
{0x34,0x1D,0x00},//R14 0X100
{0x34,0x1F,0xff},//R15 0X1FF
{0x34,0x41,0x38},//R32 0X138
{0x34,0x58,0x00},//R44 0X000
{0x34,0x5f,0x55},//R47 0X155
{0X34,0x62,0x02},//R49 0X002
{0x34,0x65,0x60},//R50 0X160
{0x34,0x67,0x60}, //R51 0X160
};

static unsigned char script_aic23_q[][3] = {//LOUT I2S SLAVE MODE
   		                                 // USED FOR PALYBACK(),MIC IN
{0x34,0x01,0x17},	
{0x34,0x03,0x17},
{0x34,0x05,0x79},
{0x34,0x06,0x0},
{0x34,0x08,0x14},
{0x34,0x0a,0x05},	
{0x34,0x0c,0x00},
{0x34,0x0e,0x02},	//usb mode 
{0x34,0x10,0x00},
{0x34,0x12,0x01}
};

   static unsigned char script_aic23_l[][3] = {//Lin1 I2S SLAVE MODE
   		                                 // USED FOR record
		{0x34,0x01,0x17},
		{0x34,0x03,0x17},
		{0x34,0x08,0x12},
		{0x34,0x0a,0x05},
		{0x34,0x0c,0x00},
		{0x34,0x0e,0x03},
		{0x34,0x10,0x01},
		{0x34,0x12,0x01}
};
static unsigned char script_aic23_r[][3] = {//MICIN I2S SLAVE MODE
				                                 // USED FOR record
{0x34,0x01,0x17},	
{0x34,0x03,0x17},
{0x34,0x05,0x10},
{0x34,0x07,0x11},
{0x34,0x08,0x14},
{0x34,0x0a,0x05},	
{0x34,0x0c,0x01},
{0x34,0x0e,0x02},	
{0x34,0x10,0x00},
{0x34,0x12,0x01}
};

	unsigned char aic23_for_close[3]={0x34,0x0c,0x08};	
	 unsigned char aic23_for_open[3]={0x34,0x0c,0x00};

/* playback data*/
const int sinewave[] = { 0x00000, 0x10B51, 0x2120F, 0x30FBB, 0x3FFFF, 0x4DEBD, 0x5A826, 0x658C8, 0x6ED9D, 0x7641A,
                         0x7BA36, 0x7EE79, 0x7FFFE, 0x7EE79, 0x7BA36, 0x7641A, 0x6ED9D, 0x658C8, 0x5A826, 0x4DEBD,
                         0x3FFFF, 0x30FBB, 0x2120F, 0x10B51, 0x00000, 0xEF4AF, 0xDEDF1, 0xCF045, 0xC0001, 0xB2143,
                         0xA57DA, 0x9A738, 0x91263, 0x89BE6, 0x845CA, 0x81187, 0x80002, 0x81187, 0x845CA, 0x89BE6,
                         0x91263, 0x9A738, 0xA57DA, 0xB2143, 0xC0001, 0xCF045, 0xDEDF1, 0xEF4AF };

 
static int mode=0;

static int ch_r,ch_p;
static struct ver_dma_param pa_r,pa_p;
/****************for GPIO init**************/
static volatile void *gpio5_base;
        
#define GPIO5_DATA (gpio5_base + 0x3fc)
#define GPIO5_DIR  (gpio5_base + 0x400)
#define GPIO5_IS   (gpio5_base + 0x404)
#define GPIO5_IBE  (gpio5_base + 0x408)
#define GPIO5_IEV  (gpio5_base + 0x40c)
#define GPIO5_IE   (gpio5_base + 0x410)
#define GPIO5_RIS  (gpio5_base + 0x414)
#define GPIO5_MIS  (gpio5_base + 0x418)
#define GPIO5_IC   (gpio5_base + 0x41c)
#define GPIO5_AFSEL (gpio5_base + 0x420)

/********end for GPIO init variable******/

#define READBUFSIZE 1024
#define PIN_MASKBASE	0x20020000
#define PLAYBUFSIZE 4096
#define RECBUFSIZE 2048

#define I2S_IOC_MAGIC  'm'

#define I2S_IOCRESET    _IO(I2S_IOC_MAGIC, 0)
#define I2S_IOCLAST      _IOR(I2S_IOC_MAGIC, 1, unsigned long )
#define I2S_IOCHWADDR    _IOR(I2S_IOC_MAGIC, 2, unsigned long )
#define I2S_IOCVIRADDR	 _IOR(I2S_IOC_MAGIC, 3, unsigned long )
#define I2S_IOC_SETFMT   _IOW(I2S_IOC_MAGIC ,4,unsigned long )

#define I2S_IOC_SETCh   _IOW(I2S_IOC_MAGIC ,5,unsigned long )
#define I2S_IOC_SETSPEED _IOW(I2S_IOC_MAGIC ,6,unsigned int)

#ifdef CONFIG_USE_aic23
	#define I2S_IOC_SetReVol _IOW(I2S_IOC_MAGIC,7,unsigned int)

	#define I2S_IOC_SetPlVol _IOW(I2S_IOC_MAGIC,8,unsigned int)

	#define I2S_IOC_GInt _IOR(I2S_IOC_MAGIC,9,unsigned long)

	#define I2S_IOC_GetVol _IOR(I2S_IOC_MAGIC,10,unsigned long )
	
	#define I2S_IOC_SetReg0 _IOW(I2S_IOC_MAGIC,11,unsigned int)

	#define I2S_IOC_SetReg2 _IOW(I2S_IOC_MAGIC,12,unsigned int)
	#define I2S_IOC_SetReg4 _IOW(I2S_IOC_MAGIC,13,unsigned int)
	#define I2S_IOC_SetReg5 _IOW(I2S_IOC_MAGIC,14,unsigned int)
	#define I2S_IOC_SetReg6 _IOW(I2S_IOC_MAGIC,15,unsigned int)
	#define I2S_IOC_SetReg7 _IOW(I2S_IOC_MAGIC,16,unsigned int)
	#define I2S_IOC_SetReg8 _IOW(I2S_IOC_MAGIC,17,unsigned int)
	#define I2S_IOC_SetReg9 _IOW(I2S_IOC_MAGIC,18,unsigned int)
	#define I2S_IOC_SetReg15 _IOW(I2S_IOC_MAGIC,19,unsigned int)

	
	#define I2S_IOCHARDRESET _IO(I2S_IOC_MAGIC, 20) /* debugging tool */


	#define I2S_IOC_MAXNR 21
#else
	#define I2S_IOC_MAXNR 7
#endif

//#define DEBUG_I2S

#ifdef DEBUG_I2S
	
	#define debug(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
#else
	#define debug(fmt, args...)
#endif

static char *Play_Buffer;
static int use;

static int Record_PhyAddr;
 static int Record_MemAddr;

void *comp_record = NULL;
void *comp_play = NULL;
char Record_Buffer[1024];
static int use_i2s=0;


volatile unsigned int volR_add=8,volR_del=23;
volatile unsigned int volP_add=6,volP_del=73;
volatile unsigned char org_vol_p= 0x79;
volatile unsigned char org_vol_r = 0x17;

int PinMask( int device , int enable )
{
	u32 mask;
	int error = 0;
	switch( device )
	{
	case 0:		// disable 656 out ( 68k clock ).
		mask = (1<<14);
		break;
	case 1:		// i2c out
		mask = 0x00000480;
		break;
	case 2:
		mask = (1<<21);	// disable 656 out ( sensor clock enable)
		break;
	case 3:		// 68k enable( sci disable )
		mask = (1<<15);
		break;
	default:
		error = 1;
	}
	if( mask )
	{
		volatile int* pinmark = (volatile int*)ioremap( PIN_MASKBASE , 0x1000);
		if( pinmark )
		{
			if( enable )
				pinmark[0x10c/4] |= mask;
			else
				pinmark[0x10c/4] &= ~mask;
			iounmap( (void*)pinmark );
		}
		else
		{
			error = 2;
		}
	}
	return error;
}


 static int i2sbufviraddr(){

	Record_PhyAddr = i2sbufbaseaddr();
	if(!Record_PhyAddr){
		debug("SOUND: get Record_PhyAddr fail\n");
		return -1;
	}
	debug("Record_PhyAddr = %x \n",Record_PhyAddr);
	
	Record_MemAddr = (int)ioremap(Record_PhyAddr, RECBUFSIZE*4);
	if(!Record_MemAddr){
		debug("SOUND: get Record_MemAddr fail\n");
		return -1;
	}
	debug("Record_MemAddr = %x \n",Record_MemAddr);
	return Record_MemAddr;


 };
static int i2s_open(struct inode *inode, struct file *filp){

	int error;
	if ((filp->f_flags & O_ACCMODE) == O_RDONLY) {
		use = 0;
	} else if ((filp->f_flags & O_ACCMODE) == O_WRONLY) {
		use = 1;
	} else if ((filp->f_flags & O_ACCMODE) == O_RDWR) {
		use = 2;
	} else
		return -EINVAL;

	#ifdef CONFIG_USE_aic23
	
	init_i2c();
	transmitData( 2 , &aic23_for_open[1], 0x34/2 );

	mdelay(1);
	
	dele_i2c();

	Play_Buffer = kmalloc(PLAYBUFSIZE, GFP_KERNEL);
        if(Play_Buffer==NULL){
                debug("SOUND: error malloc Play_Buffer\n");
                return -ENODEV;
        }

 	error = init_playback_dma();
        if (error != 0)
        {
                debug("SOUND: init_playback_dma  fail !\n");
                return -ENODEV;
        }
	error = init_record_dma();
        if (error != 0)
        {
                debug("SOUND: init_dma_record  fail !\n");
                return -ENODEV;
        }

        error = start_record_dma();
        if (error != 0)
        {
                debug("SOUND: start_dma_record fail !\n");
                return -ENODEV;
        }
	
	#endif
	return 0;

}

static int i2s_release(struct inode *inode, struct file *filp){

	test_close();
 	ver_free_dma(ch_p);
        ver_end_dma(ch_p);
	 ver_free_dma(ch_r);
        ver_end_dma(ch_r);
	return 0;
}

static ssize_t i2s_write (struct file *filp, const char __user * buf, size_t sz, loff_t * off){

	int cnt = 0,error,loop=0;
	const char *b = buf;
	int i;

	if(sz >PLAYBUFSIZE){
		while( (sz-cnt) > PLAYBUFSIZE )
			{
				for( i = 0; i<PLAYBUFSIZE; i++)	Play_Buffer[i]=*(b+cnt+i);
				start_play_dma(Play_Buffer, PLAYBUFSIZE);
				cnt +=PLAYBUFSIZE;
			}
		for( i = 0; i<PLAYBUFSIZE; i++)
			{
				if(i<sz-cnt)
					Play_Buffer[i]=*(b+cnt+i);
				else
					Play_Buffer[i]='\0';
			}

			start_play_dma( Play_Buffer, PLAYBUFSIZE);
			cnt = sz;
	}else{
		for( i = 0; i<PLAYBUFSIZE; i++){
			if(i<sz)
				Play_Buffer[i]=*(b+cnt+i);
			else
				Play_Buffer[i]='\0';
			}		

		error = start_play_dma(Play_Buffer, PLAYBUFSIZE);
		
		if (error != 0){
			debug("SOUND: start_play_dma fail !%\n");
			return -ENODEV;
		}
	}
		
	cnt = sz;
	return cnt;
}


int i2s_miclin_mode()
{
	return mode;
	}

int getrecord(char *buf, int sz)
{
	if( sz > RECBUFSIZE )
		return -1;
	DECLARE_COMPLETION(com);
	comp_record = &com;

	wait_for_completion(&com);
	comp_record  = NULL;
	
 	int  i, j;
	i = i2slastdone();
	char *p = (char*)Record_MemAddr + RECBUFSIZE*i;

	for(i = 0,j = 0; i < sz; i += 4, j += 4)
	{
		buf[j] = *(p+i) + *(p+i+2);
		buf[j+1] = *(p+i+1) + *(p+i+3);
		buf[j+2] = *(p+i) + *(p+i+2);
		buf[j+3] = *(p+i+1) + *(p+i+3);
	}
	
	return sz;
}



static ssize_t i2s_read (struct file *filp, char __user * buf, size_t sz, loff_t * off){

	int i,error;


	if( sz > RECBUFSIZE )
                return -1;

	DECLARE_COMPLETION(com);

	comp_record = &com;
	wait_for_completion(&com);
	comp_record = NULL;

	
	buf[0] = '0' + i2slastdone();
	buf[1] = '\0';

	return sz;

}


/*
static unsigned int i2s_poll(struct file *filp, poll_table * wait)
{
	poll_wait(filp, &wq, wait);

	if(!needpollout) return 0;

	needpollout = 0;

	return POLLIN | POLLRDNORM;
}
*/

/* to capture the data at IIS bus*/
int i2s_capture(unsigned short *buf, int size)
{
	int i;

	*IIS_CR0=0x031f;
	*IIS_CPSR=0x0004;
	*IIS_IMSC=0x0004;
	*IIS_CR1=0x0002;

	for(i=0; i<size; ){
   		while(!(*IIS_MIS & 0x4));
   		buf[i++] = *IIS_SDR;
   		buf[i++] = *IIS_SDR;
	}

	return 0;
}

irqreturn_t do_iis_irq(int irq, void *devid, struct pt_regs *regs){
	debug("<1>i2s irqd\n");
	return IRQ_HANDLED;
}

int init_wm8976()
{
        int i , count;

        printk("enter init_wm8976\n");

        if(use_i2s==1)
                count=sizeof(script_wm8976_l) / sizeof(script_wm8976_l[0]);
                else if (use_i2s==2) count=sizeof(script_wm8976_m) / sizeof(script_wm8976_m[0]);
                 else if (use_i2s==3) count=sizeof(script_wm8976) / sizeof(script_wm8976[0]);
                 else count=sizeof(script_wm8976_p) / sizeof(script_wm8976_p[0]);

        PinMask( 1 , 1 );       // enable i2c pin mask
        init_i2c();
        debug("after i2c_init\n");
        {
                if(use_i2s==1){
                        	for( i=0; i<count; i++ )
			transmitData( 2 , &script_wm8976_l[i][1] , script_wm8976_l[i][0]/2 );
                        debug("now --- init mode\n");
                }

⌨️ 快捷键说明

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