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

📄 ac97.c

📁 VXWORKS操作系统下的S3C2440声卡驱动源程序
💻 C
字号:
/*ac97 sound driver program
	Users can use this driver to play his/her sound file,
	but can not record,because of 2440's bug(maybe).
	Created by Feng Rongwei
	2006.3.27
*/
#include "vxWorks.h"
#include "errno.h"
#include "fcntl.h"
#include "intLib.h"
#include "ioLib.h"
#include "iosLib.h"
#include "iv.h"
#include "logLib.h"
#include "lstLib.h"
#include "msgQLib.h"
#include "semLib.h"
#include "stdlib.h"
#include "string.h"
#include "taskLib.h"
#include "sb16drv.h"


LOCAL int DrvNum;	/*驱动程索引*/
int fintcount=0;	/*中断次数计数*/
int temdevId, int *tembuffer, int temmaxbytes;



AC97_GPIO_Init()
{
	frGPECON|=0x3ff;
	frGPEUP|= 0x1f;
}

void Delay(USHORT count)
{
	volatile int i, j;
	
	for(;count > 0;count--)
		for(i=0;i < floop; i++) { j++; }
}


ac97_controller_init()		/*ac97 控制器初始化*/
{
	frCLKCON |= AC97_INTERNAL_CLOCK_ENABLE;		/*Enable the CPU clock to the AC97 controller*/
	
	AC97_GPIO_Init();
	
	rAC_GLBCTRL=0;
	Delay(10);

	/*Cold Reset*/ 
	rAC_GLBCTRL = 0x1; 
	Delay(10);
	rAC_GLBCTRL = 0x0;
	Delay(10); 

	/*AC-link On*/
	rAC_GLBCTRL = (1<<2);
	Delay(10); 

	/*Transfer data enable using AC-link*/
	rAC_GLBCTRL|= (1<<3);
	Delay(10); 

	/*Disable the Codec ready Interrupt*/
	rAC_GLBCTRL|= (1<<22);
	Delay(10); 
	
	rAC_GLBCTRL&= ~(0x400000);	/* codec ready interrupt disable*/

	Delay(10); 
}




WriteCodecRegister(UCHAR Reg, USHORT Val)
{
	rAC_CODEC_CMD = (Reg << AC97_CMD_ADDR_SHIFT) | (Val << AC97_CMD_DATA_SHIFT);
	Delay(100);
	rAC_CODEC_CMD |= (AC97_READ_COMMAND);	/*To receive SLOTREQ bits when VRA is '1'.*/
}


/*UINT32 ReadCodecRegister(UCHAR Reg)
{
	UINT32 retval=0;
	
	rAC_CODEC_CMD = AC97_READ_COMMAND | (Reg <<16);
	
	Delay(100);
	
	retval = rAC_CODEC_STAT&0xffff;
	
	return retval;
}*/


ac97_codec_init()
{
	/* write the Codec software reset (00h)*/
	WriteCodecRegister(AC97_RESET, 0x01); 
	
	/* enable the VRA	(2Ah)*/
	WriteCodecRegister(AC97_EXT_AUDIO_CONTROL, 1);
	WriteCodecRegister(AC97_PCM_DAC_RATE, 0xbb80);

	/* Turn Power on for sections	(26h)*/
	WriteCodecRegister( AC97_POWER_CONTROL, AC97_PWR_D0 );

	/*volume control*/
	WriteCodecRegister( AC97_MASTER_VOL_STEREO, 0x0101);
	WriteCodecRegister( AC97_HEADPHONE_VOL, 0x0101 );
	WriteCodecRegister( AC97_PCMOUT_VOL, 0x0101 );
}



initsoundHardware1()	/*设备硬件初始化*/
{
	ac97_controller_init();
	ac97_codec_init();
}


 initsoundHardware2()
 {
	rAC_GLBCTRL|=(1<<12);
	rAC_GLBCTRL|=(1<<21);	/*enable pcm out interrupt*/
 }



STATUS  ac97Drv(void)		/*设备驱动程序装载函数*/
{
  if (DrvNum > 0) return OK;		/*判断驱动程序是否已安装*/
  /*将驱动程序添加到驱动程序描述表中*/
  DrvNum = iosDrvInstall (soundOpen, NULL, soundOpen, soundCloe,NULL, soundWrite, soundIoctl);
  return (DrvNum == ERROR) ? ERROR : OK;
}


STATUS ac97DevCreate (char *devName)    	/*创建设备*/
{
  SOUND_DEV *fpDev;		/*设备描述符*/

  if (DrvNum < 1)	/*检查驱动是否安装*/
  {
 /*   errno = S_ioLib_NO_DRIVER;*/
    return ERROR;
  }

  fpDev = (SOUND_DEV *)malloc (sizeof(SOUND_DEV));	/*分配内存并初始化*/
  if (!fpDev) return ERROR;
  bzero ((char *)fpDev, sizeof(SOUND_DEV));

  fpDev->soundopen=0;	/*初始化设备描述结构pDev */


  initsoundHardware1();	/*设备硬件初始化*/


  if (iosDevAdd (&fpDev->devHdr, devName, DrvNum) == ERROR)	/*将设备添加到设备列表*/
  {
    free ((char *)fpDev);
    return ERROR;
  }
    return OK;
}

int soundOpen(DEV_HDR *fpDevHdr, char *fileName, int flags, int mode)
{
	SOUND_DEV *fpDev=(SOUND_DEV *)fpDevHdr;
	 if (fpDev==NULL)
  		{
    			/*errno = S_ioLib_DEVICE_ERROR;*/
    			return ERROR;
  		}
	 if(fpDev->soundopen)
	 	{
			/*errno = S_ioLib_DEVICE_OPENED;*/
			return ERROR;
	 	}
	 fpDev->soundopen=1;
	 
	 initsoundHardware2();
	 
	 return((int)fpDevHdr);
}

int soundWrite(int devId, int *buffer, int maxbytes)
{
	int 	fcount;
	temdevId=devId;
	tembuffer=buffer;
	temmaxbytes=maxbytes;
	for(fcount=0;fcount<16;fcount++,buffer++,fintcount++)
		{
			rAC_PCMDATA=*buffer;
		}
	if(fintcount>=maxbytes)
		intDisable (9);
}

int soundCloe(int devId)
{
	SOUND_DEV *fpDev=(SOUND_DEV *) devId;
	free(fpDev);
}


int soundIoctl(int devId, int function, int arg)
{

}


audio_send_int()		/*中断处理函数*/
{
    UINT32 intId;
    UINT32 intId_temp;
    intId = (*(volatile UINT32 *)0x4a000018);
    intId_temp = (*(volatile UINT32 *)0x4a000014);
    
    if (((intId & 0x4000) == 0x4000) && (intId_temp == 9))    
    	{
       	intDisable (9);
		soundWrite(int temdevId, char *tembuffer, int temmaxbytes);
		intEnable (9);
    	}

	(*(volatile unsigned *)0x4a000000) = (*(volatile unsigned *)0x4a000000);
	(*(volatile unsigned *)0x4a000018) = (*(volatile unsigned *)0x4a000018);
	(*(volatile unsigned *)0x4a000010) = (*(volatile unsigned *)0x4a000010);
}



⌨️ 快捷键说明

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