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

📄 cs4334.c

📁 IIS 音频驱动实验 基于TEB-44B0实验平台 包括音频驱动程序与测试程序
💻 C
字号:
/* * Cypress CS4334 Audio Device Driver for S3C44B0X uClinux * * Copyright (C) 2005 QHKJ * * Author : Vencent  (zlg@qhkj.com)        * */#include <linux/module.h>#include <linux/init.h>#include <linux/types.h>#include <linux/fs.h>#include <linux/mm.h>#include <linux/slab.h>#include <linux/delay.h>#include <linux/sched.h>#include <linux/poll.h>#include <linux/interrupt.h>#include <linux/errno.h>#include <linux/sound.h>#include <linux/soundcard.h>#include <linux/pm.h>#include <asm/uaccess.h>#include <asm/io.h>#include <asm/hardware.h>#include <asm/semaphore.h>#include <asm/dma.h>#include <asm/arch/irqs.h>#include <asm/arch/s3c44b0x.h>//#include "wav.h"#undef DEBUG//#define DEBUG#ifdef DEBUG#define DPRINTK( x... )  printk( ##x )#else#define DPRINTK( x... )#endif#define DEVICE_NAME	"audio"//#define IRQ_AUDIO	S3C44B0X_INTERRUPT_BDMA0static int audio_rd_refcount;static int audio_wr_refcount;#define audio_active		(audio_rd_refcount | audio_wr_refcount)static int audio_dev_dsp;#define BUF_LEN		300*1024    // 300K Bytestatic unsigned short buf[BUF_LEN/2];static unsigned short *data;int audio_major = 80;              /* Select 0 for Dynamic adressing */#define AUDIO_NAME	"CS4334"//#define MAX_WAVSIZE	0xfffff#define IIS_FIFOREADY	!(((inl(S3C44B0X_IISCON))>>7)&1)static unsigned long pllvalue;           //add vencent static unsigned int ubdiv;static ssize_t s3c44b0_audio_read(struct file *file, char *buffer, size_t count, loff_t *offp)//static ssize_t s3c44b0_audio_read(struct file *file, char *buffer, size_t count, char offp){	int i;	//char *dev = file->private_data + offp;	char *dev = file->private_data;	#if 0		for(i = 0; i < count; i++)	{	 	printk("file_private_data: ");	 	printk(" 0x%x", dev[i]);	 	if(!(i % 10))	 	{	  		printk("\n");	 	}	}#endif		copy_to_user(buffer, &dev, count);	return count;}static ssize_t s3c44b0_audio_write(struct file *file, const char *buffer, size_t count, loff_t *offp){	unsigned short xx;	unsigned int i;		init_s3c44b0_iis_bus();	copy_from_user(buf, buffer, count);		outl(inl(S3C44B0X_IISCON)|(0x01), S3C44B0X_IISCON);       //  IIS enable	  		data = &buf[0]; 	while(1)	{	 	if(IIS_FIFOREADY)	 	{	  		for(i = 0; i < 8; i++)	  		{	  			 xx = (unsigned short)(*data++);//				 printk("  xx = 0x%x\n", xx);	   			 outl(xx, S3C44B0X_IISFIF);	  		}	  	  	 	if((data - buf) > count)	  		{	  		 	data = &buf[0];				printk("##### Finish #####\n");	   			goto out; 	  	 	}	 	 }	}	 out:	outl(inl(S3C44B0X_IISCON)&(0xfe), S3C44B0X_IISCON);	   //  IIS disable	return 0;}static int audio_set_dsp_speed(long val){	printk("  Val = %ld\n", val);	switch(val) {		case 44100:			outl(0x69081, S3C44B0X_PLLCON);     //MCLK=45.1584M <--11.2896M*4        		outl(24, S3C44B0X_UBRDIV0);			outl(24, S3C44B0X_UBRDIV1);			outl(0x11, S3C44B0X_IISPSR);        // Prescaler_A/B enable, value=4			break;		case 22050:			outl(0x69081, S3C44B0X_PLLCON);	// MCLK=45.1584M <--5.6448M*8        		outl(24, S3C44B0X_UBRDIV0);			outl(24, S3C44B0X_UBRDIV1);			outl(0x33, S3C44B0X_IISPSR);      // Prescaler_A/B enable, value=8			break;		case 11025:			outl(0x69081, S3C44B0X_PLLCON);	// MCLK=45.1584M <--5.6448M*16        		outl(24, S3C44B0X_UBRDIV0);			outl(24, S3C44B0X_UBRDIV1);			outl(0x77, S3C44B0X_IISPSR);      // Prescaler_A/B enable, value=16			break;		case 8000:			outl(0x21061, S3C44B0X_PLLCON);	// MCLK=20.48M<--2.048M*10        		outl(10, S3C44B0X_UBRDIV0);			outl(10, S3C44B0X_UBRDIV1);			outl(0x44, S3C44B0X_IISPSR);      // Prescaler_A/B enable, value=10			break;		default:			return -1;	}	return 0;}static int audio_set_dsp_channels(long val){ 	return 0;}static int audio_set_dsp_samplesize(long val){ 	return 0;}static int s3c44b0_audio_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg){		long val;        int ret;	switch(cmd) {		case SNDCTL_DSP_CHANNELS:		case SNDCTL_DSP_STEREO:			get_user(val, (long *) arg);			ret = audio_set_dsp_channels(val);			if (ret < 0) 				return -EINVAL;			break;		case SNDCTL_DSP_SPEED:			get_user(val, (long *) arg);		  	ret = audio_set_dsp_speed(val);			if (ret < 0) 				return -EINVAL;		  	break;		case SNDCTL_DSP_SAMPLESIZE:			get_user(val, (long *) arg);		  	ret = audio_set_dsp_samplesize(val);			if (ret < 0) 				return -EINVAL;			break;		default:			return -EINVAL;		}	return 1;}/*static void s3c44b0_isr_audio(int irq, void *dev_id, struct pt_regs *reg){	outl((0x01)<<17, S3C44B0X_I_ISPC);}*/static int s3c44b0_audio_open(struct inode *inode, struct file *file){        	//printk("Audio open!\n");	MOD_INC_USE_COUNT;	return 0;}static int s3c44b0_audio_release(struct inode *inode, struct file *file){	//printk("Audio release!\n");	outl(pllvalue, S3C44B0X_PLLCON);        outl(ubdiv, S3C44B0X_UBRDIV0);	outl(ubdiv, S3C44B0X_UBRDIV1);	MOD_DEC_USE_COUNT;	return 0;}static struct file_operations s3c44b0_audio_fops = {	read:		s3c44b0_audio_read,	write:		s3c44b0_audio_write,//	poll:		s3c44b0_audio_poll,	ioctl:		s3c44b0_audio_ioctl,	open:		s3c44b0_audio_open,	release:		s3c44b0_audio_release,};static void init_s3c44b0_iis_io(void){   	outl(inl(S3C44B0X_PCONC)|(0xcf), S3C44B0X_PCONC);        // IISCLK IISDO IISLRCK initialize 	outl(inl(S3C44B0X_PCONE)|(0x20000), S3C44B0X_PCONE);      // CODECLK/PE8 initialize}static void cs4334_init(void){// NULL}static void init_s3c44b0_iis_bus(void){        outl(inl(S3C44B0X_IISCON)&(~(0x1ff)), S3C44B0X_IISCON); 	outl(inl(S3C44B0X_IISCON)|(0x02), S3C44B0X_IISCON);       //  Tx DMA disable, Rx idle, Prescaler enable 	outl(inl(S3C44B0X_IISMOD)&(~(0x1ff)), S3C44B0X_IISMOD);	outl(inl(S3C44B0X_IISMOD)|(0x89), S3C44B0X_IISMOD);      // Master, Tx, L-ch=0, iis, 16bit, 256fs, 32fs//	outl(inl(S3C44B0X_IISPSR)&(~(0xff)), S3C44B0X_IISPSR); //	outl(inl(S3C44B0X_IISPSR)|(0x22), S3C44B0X_IISPSR);        //  Prescaler_A/B enable, value=6	outl(inl(S3C44B0X_IISFIFCON)&(~(0xfff)), S3C44B0X_IISFIFCON); 	outl(inl(S3C44B0X_IISFIFCON)|(0x200), S3C44B0X_IISFIFCON);    // Tx normal, Tx FIFO 	//	outl(inl(S3C44B0X_IISCON)|(0x01), S3C44B0X_IISCON);       //  IIS enable	  }/*static void init_s3c44b0_bdma(void){	outl(inl(S3C44B0X_BDISRC0)&(~(0xffffffff)), S3C44B0X_BDISRC0); 	outl(inl(S3C44B0X_BDISRC0)|((1<<30)+(1<<28)+(buf)), S3C44B0X_BDISRC0);       	 	outl(inl(S3C44B0X_BDIDES0)&(~(0xffffffff)), S3C44B0X_BDIDES0); 	outl(inl(S3C44B0X_BDIDES0)|((1<<30)+(3<<28)+(S3C44B0X_IISFIF)), S3C44B0X_BDIDES0);	outl(inl(S3C44B0X_BDICNT0)&(~(0xffffffff)), S3C44B0X_BDICNT0); 	outl(inl(S3C44B0X_BDICNT0)|((1<<30)+(1<<26)+(3<<22)+(0<<21)+(1<<20)+(sizeof(buf)&(~(0x3)))), S3C44B0X_BDICNT0);     	outl(inl(S3C44B0X_BDICNT0)|(1<<20), S3C44B0X_BDICNT0);     // enable DMA		outl(inl(S3C44B0X_BDCON0)&(~(0xff)), S3C44B0X_BDCON0);       //  BDMA0 enable	  	}static void cleanup_s3c44b0_bdma(void){	outl(inl(S3C44B0X_BDCON0)|(1<<2), S3C44B0X_BDCON0);       //  BDMA0 disable	}*/int s3c44b0_audio_init(void){ 	unsigned long flags;//	int ret;        int cold = !audio_active;		local_irq_save(flags);        init_s3c44b0_iis_io();	local_irq_restore(flags);		pllvalue = inl(S3C44B0X_PLLCON);        printk("PLL VALUE : 0x%lx\n", pllvalue);	ubdiv = inl(S3C44B0X_UBRDIV0);	printk("UBDIV : %d\n", ubdiv);	cs4334_init();	//	init_s3c44b0_iis_bus();	//	init_s3c44b0_bdma();		audio_dev_dsp = register_chrdev(audio_major, DEVICE_NAME, &s3c44b0_audio_fops);	if(audio_dev_dsp < 0)	{	 printk("Audio play initialized failed!\n");	 return -ENODEV;  	}	printk("Audio play initialized OK!\n");	/*		ret = request_irq(IRQ_AUDIO, s3c44b0_isr_audio, 0, DEVICE_NAME, NULL);	if(ret < 0)  	{   	 printk("Audio Driver: Error while installing IRQ_AUDIO handler.\n");   	//return -ENODEV;  	}  	else  	{   	 printk("The Audio is registered successfully!\n");   	 //printk("ret = %d \n", ret);  	}*/		if(cold) 	{ 	}		return 0;}static void s3c44b0_audio_exit(void){	unregister_chrdev(audio_major,DEVICE_NAME);//	cleanup_s3c44b0_bdma();//	free_irq(IRQ_AUDIO, NULL);	 //	outl(pllvalue, S3C44B0X_PLLCON);//       outl(ubdiv, S3C44B0X_UBRDIV0);//	outl(ubdiv, S3C44B0X_UBRDIV1);	printk("Audio play unloaded!\n");}

⌨️ 快捷键说明

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