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

📄 uda1380.c

📁 这个源码相信对很多用arm开发板开发的人会有用的
💻 C
📖 第 1 页 / 共 3 页
字号:
	    audio_buf_info *inf = (audio_buf_info *) arg;	    int err = access_ok(VERIFY_WRITE, inf, sizeof(*inf)) ? 0 : -EFAULT;	    int i;	    int frags = 0, bytes = 0;	    if (err)		return err;	    for (i = 0; i < s->nbfrags; i++) 	    {		if (atomic_read(&s->buffers[i].sem.count) > 0) 		{		    if (s->buffers[i].size == 0) frags++;		    bytes += s->fragsize - s->buffers[i].size;		}	    }	    put_user(frags, &inf->fragments);	    put_user(s->nbfrags, &inf->fragstotal);	    put_user(s->fragsize, &inf->fragsize);	    put_user(bytes, &inf->bytes);	    break;	}	case SNDCTL_DSP_GETISPACE:	{	    audio_stream_t *s = &input_stream;	    audio_buf_info *inf = (audio_buf_info *) arg;	    int err = access_ok(VERIFY_WRITE, inf, sizeof(*inf)) ? 0 : -EFAULT;	    int i;	    int frags = 0;	    int bytes = 0;	    if (!(file->f_mode & FMODE_READ))                return -EINVAL;	    if (err)		return err;	    for(i = 0; i < s->nbfrags; i++)	    {		if (atomic_read(&s->buffers[i].sem.count) > 0)                {                    if (s->buffers[i].size == s->fragsize)                        frags++;                    bytes += s->buffers[i].size;                }            }	    put_user(frags, &inf->fragments);            put_user(s->nbfrags, &inf->fragstotal);            put_user(s->fragsize, &inf->fragsize);            put_user(bytes, &inf->bytes);            break;	}	case SNDCTL_DSP_RESET:	    if (file->f_mode & FMODE_READ) 	    {                audio_clear_buf(&input_stream);            }            if (file->f_mode & FMODE_WRITE) 	    {                audio_clear_buf(&output_stream);            }            return 0;	case SNDCTL_DSP_NONBLOCK:	case SNDCTL_DSP_POST:	case SNDCTL_DSP_SUBDIVIDE:	case SNDCTL_DSP_GETCAPS:	case SNDCTL_DSP_GETTRIGGER:	case SNDCTL_DSP_SETTRIGGER:	case SNDCTL_DSP_GETIPTR:	case SNDCTL_DSP_GETOPTR:	case SNDCTL_DSP_MAPINBUF:	case SNDCTL_DSP_MAPOUTBUF:	case SNDCTL_DSP_SETSYNCRO:	case SNDCTL_DSP_SETDUPLEX:	    return -ENOSYS;	default:	    return smdk2410_mixer_ioctl(inode, file, cmd, arg);    }    return 0;}static int smdk2410_audio_open(struct inode *inode, struct file *file){		    int cold = !audio_active;    DPRINTK("audio_open\n");    if ((file->f_flags & O_ACCMODE) == O_RDONLY)     {	if (audio_rd_refcount || audio_wr_refcount)	    return -EBUSY;	audio_rd_refcount++;    }     else if ((file->f_flags & O_ACCMODE) == O_WRONLY)     {	if (audio_wr_refcount)	    return -EBUSY;	audio_wr_refcount++;    }     else if ((file->f_flags & O_ACCMODE) == O_RDWR)     {	if (audio_rd_refcount || audio_wr_refcount)	    return -EBUSY;	audio_rd_refcount++;	audio_wr_refcount++;    }     else	return -EINVAL;    if (cold)     {	audio_rate = AUDIO_RATE_DEFAULT;	audio_channels = AUDIO_CHANNELS_DEFAULT;	audio_fragsize = AUDIO_FRAGSIZE_DEFAULT;	audio_nbfrags = AUDIO_NBFRAGS_DEFAULT;	init_s3c2410_iis_bus_txrx(); //for the full duplex 	if ((file->f_mode & FMODE_WRITE))	{		//	    init_s3c2410_iis_bus_tx();	    audio_clear_buf(&output_stream);	}	if ((file->f_mode & FMODE_READ))	{		//	    init_s3c2410_iis_bus_rx();	    audio_clear_buf(&input_stream);	}    }    return 0;}static int smdk2410_mixer_open(struct inode *inode, struct file *file){    return 0;}static int smdk2410_audio_release(struct inode *inode, struct file *file){    DPRINTK("audio_release\n");    if (file->f_mode & FMODE_READ)     {	if (audio_rd_refcount == 1)	    audio_clear_buf(&input_stream);	audio_rd_refcount = 0;    }    if(file->f_mode & FMODE_WRITE)     {	if (audio_wr_refcount == 1) 	{	    audio_sync(file);	    audio_clear_buf(&output_stream);	    audio_wr_refcount = 0;	}    }    return 0;}static int smdk2410_mixer_release(struct inode *inode, struct file *file){    return 0;}static struct file_operations smdk2410_audio_fops = {    .llseek = smdk2410_audio_llseek,    .write  = smdk2410_audio_write,    .read   = smdk2410_audio_read,    .poll   = smdk2410_audio_poll,    .ioctl  = smdk2410_audio_ioctl,    .open   = smdk2410_audio_open,    .release = smdk2410_audio_release};static struct file_operations smdk2410_mixer_fops = {	.ioctl	= smdk2410_mixer_ioctl,	.open	= smdk2410_mixer_open,	.release = smdk2410_mixer_release};/* * To enble Full-Duplex */static void init_s3c2410_iis_bus_txrx(void){    unsigned long tmp_read;    __raw_writel(0,S3C2410_SBC_IISCON);    __raw_writel(0,S3C2410_SBC_IISMOD);    __raw_writel(0,S3C2410_SBC_IISFCON);		/* 8 kHZ, 384fs */    __raw_writel((IISPSR_A(iispsr_value(S_CLOCK_FREQ, 8000)) 	        | IISPSR_B(iispsr_value(S_CLOCK_FREQ, 8000)))		,S3C2410_SBC_IISPSR);	    __raw_writel(S3C2410_IISCON_RXDMAEN 		 /* (1 << 4):Receive DMA service request */		| S3C2410_IISCON_TXDMAEN	         /* (1 << 5):Transmit DMA service request */			| S3C2410_IISCON_PSCEN		/* (1 << 1):IIS Prescaler Enable */		,S3C2410_SBC_IISCON);	    __raw_writel(S3C2410_IISMOD_MASTER 		    	/* (0 << 8):Master mode */		| S3C2410_IISMOD_RXMODE		/* (1 << 6):Receive mode */		| S3C2410_IISMOD_TXMODE		/* (2 << 6):Transmit mode */		| S3C2410_IISMOD_LR_LLOW		/* (0 << 5):Low for left channel */		| S3C2410_IISMOD_IIS			/* (1 << 4):MSB-justified format */		| S3C2410_IISMOD_16BIT		/* (1 << 3):Serial data bit/channel is 16 bit */		| S3C2410_IISMOD_384FS		/* (1 << 2):Master clock freq = 384 fs */		| S3C2410_IISMOD_32FS		/* (1 << 0):32 fs */		,S3C2410_SBC_IISMOD);	    __raw_writel(S3C2410_IISFCON_TXDMA		/* (1 << 15):Transmit FIFO access mode:DMA */		| S3C2410_IISFCON_RXDMA		/* (1 << 14):Receive FIFO access mode:DMA */		| S3C2410_IISFCON_TXENABLE		/* (1 << 13):Transmit FIFO enable */		| S3C2410_IISFCON_RXENABLE		/* (1 << 12):Receive FIFO access enable */		,S3C2410_SBC_IISFCON);	    tmp_read = __raw_readl(S3C2410_SBC_IISCON);    tmp_read = tmp_read | S3C2410_IISCON_IISEN;	/* IIS enable(start) */    __raw_writel(tmp_read,S3C2410_SBC_IISCON);}static void init_s3c2410_iis_bus_rx(void){    unsigned long tmp_read;    __raw_writel(0,S3C2410_SBC_IISCON);    __raw_writel(0,S3C2410_SBC_IISMOD);    __raw_writel(0,S3C2410_SBC_IISFCON);        /* 44 KHz , 384fs */    __raw_writel((IISPSR_A(iispsr_value(S_CLOCK_FREQ, 44100)) 		| IISPSR_B(iispsr_value(S_CLOCK_FREQ, 44100)))		,S3C2410_SBC_IISPSR);	    __raw_writel(S3C2410_IISCON_RXDMAEN    	    /* Transmit DMA service request */		| S3C2410_IISCON_TXIDLE 		/* Receive Channel idle */		| S3C2410_IISCON_PSCEN		    /* IIS Prescaler Enable */		,S3C2410_SBC_IISCON);	    __raw_writel(S3C2410_IISMOD_MASTER 				/* Master mode */		| S3C2410_IISMOD_RXMODE 		/* Transmit */		| S3C2410_IISMOD_LR_LLOW 		/* Low for left channel */		| S3C2410_IISMOD_IIS 		/* MSB-justified format */		| S3C2410_IISMOD_16BIT 		/* Serial data bit/channel is 16 bit */		| S3C2410_IISMOD_384FS 		/* Master clock freq = 384 fs */		| S3C2410_IISMOD_32FS 		/* 32 fs */		, S3C2410_SBC_IISMOD);	    __raw_writel(S3C2410_IISFCON_RXDMA 		/* Transmit FIFO access mode:DMA */		| S3C2410_IISFCON_RXENABLE		/* Transmit FIFO enable */		, S3C2410_SBC_IISFCON);		    tmp_read=__raw_readl(S3C2410_SBC_IISCON);    tmp_read=tmp_read | S3C2410_IISCON_IISEN;	/* IIS enable(start) */    __raw_writel(tmp_read,S3C2410_SBC_IISCON);}static void init_s3c2410_iis_bus_tx(void){	unsigned long tmp_read;   	__raw_writel(0,S3C2410_SBC_IISCON);	__raw_writel(0,S3C2410_SBC_IISMOD);	__raw_writel(0,S3C2410_SBC_IISFCON);    	/* 44 KHz , 384fs */	 __raw_writel( (IISPSR_A(iispsr_value(S_CLOCK_FREQ, 44100)) \				 | IISPSR_B(iispsr_value(S_CLOCK_FREQ, 44100))),S3C2410_SBC_IISPSR);	 	__raw_writel(S3C2410_IISCON_TXDMAEN 		/* Transmit DMA service request */	           | S3C2410_IISCON_RXIDLE 		/* Receive Channel idle */		   | S3C2410_IISCON_PSCEN		/* IIS Prescaler Enable */		   ,S3C2410_SBC_IISCON);	 	__raw_writel(S3C2410_IISMOD_MASTER 	    		/* Master mode */		   |S3C2410_IISMOD_TXMODE 		/* Transmit */		   | S3C2410_IISMOD_LR_LLOW 		/* Low for left channel */		   | S3C2410_IISMOD_IIS 		/* MSB-justified format */		   | S3C2410_IISMOD_16BIT  		/* Serial data bit/channel is 16 bit */		   | S3C2410_IISMOD_384FS  		/* Master clock freq = 384 fs */		   | S3C2410_IISMOD_32FS 		/* 32 fs */		   ,S3C2410_SBC_IISMOD);	 	__raw_writel(S3C2410_IISFCON_TXDMA		/* Transmit FIFO access mode : DMA */		   | S3C2410_IISFCON_TXENABLE 		/*Transmit FIFO enable */		   ,S3C2410_SBC_IISFCON);		tmp_read=__raw_readl(S3C2410_SBC_IISCON);	tmp_read=tmp_read | S3C2410_IISCON_IISEN;	/* IIS enable (start) */	__raw_writel(tmp_read,S3C2410_SBC_IISCON);}static int __init audio_init_dma(audio_stream_t * s){	s3c2410_dmasrc_t source; 	if(s->dma_ch == 2) 	{		/* UDA1380,........MEM */		source = S3C2410_DMASRC_MEM;		s3c2410_dma_devconfig(s->dma_ch,source, 3, 0x55000010); 		s3c2410_dma_config(s->dma_ch, 2, 0xa0900000);		s3c2410_dma_set_buffdone_fn(s->dma_ch, audio_dmaout_done_callback);		s3c2410_dma_setflags(s->dma_ch, S3C2410_DMAF_AUTOSTART);		return s3c2410_dma_request(s->dma_ch, &s3c2410_dma_client_out,NULL);	}	else if(s->dma_ch == 1) 	{		source = S3C2410_DMASRC_HW;		s3c2410_dma_devconfig(s->dma_ch, source, 3, 0x55000010);		s3c2410_dma_config(s->dma_ch, 2, 0xa2900000);		s3c2410_dma_set_buffdone_fn(s->dma_ch, audio_dmain_done_callback);		s3c2410_dma_setflags(s->dma_ch, S3C2410_DMAF_AUTOSTART);		return s3c2410_dma_request(s->dma_ch, &s3c2410_dma_client_in,NULL);	}	else		return 1;}static int audio_clear_dma(audio_stream_t * s,s3c2410_dma_client_t *client){	s3c2410_dma_free(s->dma_ch,client);	return 0;}int __init s3c2410_uda1380_init(void){	unsigned long flags;	local_irq_save(flags);	/* GPE 3: I2SSDI ,Pull up enable	 * To set Bit 6 & Bit 7 of GPECON to be 02	 * To set Bit 3 of GPEUP to be 0	 */	s3c2410_gpio_cfgpin(S3C2410_GPE3,S3C2410_GPE3_I2SSDI);	s3c2410_gpio_pullup(S3C2410_GPE3,0);		/* GPE 0: I2SLRCK,Pull up enable 	 * To Set Bit 0 & Bit 1 of GPECON to be 02	 * To set Bit 0 of GPEUP to be 0	 */	s3c2410_gpio_cfgpin(S3C2410_GPE0,S3C2410_GPE0_I2SLRCK);	s3c2410_gpio_pullup(S3C2410_GPE0,0);		/* GPE 1: I2SSCLK,Pull up enable 	 * To set Bit 2 & Bit 3 of GPECON to be 02	 * To set Bit 1 of GPEUP  to be 0	 */	s3c2410_gpio_cfgpin(S3C2410_GPE1,S3C2410_GPE1_I2SSCLK);	s3c2410_gpio_pullup(S3C2410_GPE1,0);		/* GPE 2: CDCLK,Pull up enable 	 * To set Bit 4 & Bit 5 of GPECON to be 02	 * To set Bit 2 of GPEUP to be 0	 */	s3c2410_gpio_cfgpin(S3C2410_GPE2,S3C2410_GPE2_CDCLK);	s3c2410_gpio_pullup(S3C2410_GPE2,0);		/* GPE 4: I2SSDO,Pull up enable 	 * To set Bit 8 &bit 9 of GPECON to be 02	 * To set Bit 4 of GPEUP to be 0	 */	s3c2410_gpio_cfgpin(S3C2410_GPE4,S3C2410_GPE4_I2SSDO);	s3c2410_gpio_pullup(S3C2410_GPE4,0);		local_irq_restore(flags);	wrcodec(EVAMODE_CLK, 0x0f02);//0x0f06	wrcodec(IISBUS, 0x0000);	wrcodec(POWERCTL, 0xa5df);//0xafff	wrcodec(ALG_MIXER, 0x0000);	wrcodec(HP_AMP, 0x0202);	wrcodec(MASTER_VOL_CTL, 0x0000);	wrcodec(MIXER_VOLUME_CTL, 0x0000);	wrcodec(MODE_BASS_TREBLE, 0x0000);	wrcodec(MASTER_MUTE_DEEMP_MUTE, 0x0000);//0x0202	wrcodec(MIXER_SILENCE_DETECTOR, 0x0000);	wrcodec(DECIMATOR_VOLUME_CONTROL, 0x0030);	wrcodec(PGA_MUTE, 0x0000);	wrcodec(ADC, 0x000C);   //  mic//	wrcodec(ADC, 0x0000);	//  line-in	wrcodec(AGC, 0x0000);	output_stream.dma_ch = DMA_CH2;  	if (audio_init_dma(&output_stream)) {		audio_clear_dma(&output_stream,&s3c2410_dma_client_out);		printk( KERN_WARNING AUDIO_NAME_VERBOSE 			": unable to get DMA channels for output\n" );		return -EBUSY;	}	input_stream.dma_ch = DMA_CH1;  	if (audio_init_dma(&input_stream)) {                audio_clear_dma(&input_stream,&s3c2410_dma_client_in);                printk( KERN_WARNING AUDIO_NAME_VERBOSE                        ": unable to get DMA channels for input\n" );                return -EBUSY;        }		audio_dev_dsp = register_sound_dsp(&smdk2410_audio_fops, -1);	audio_dev_mixer = register_sound_mixer(&smdk2410_mixer_fops, -1);	printk(AUDIO_NAME_VERBOSE " initialized\n");	return 0;}void __exit s3c2410_uda1380_exit(void){	unregister_sound_dsp(audio_dev_dsp);	unregister_sound_mixer(audio_dev_mixer);	audio_clear_dma(&output_stream,&s3c2410_dma_client_out);	audio_clear_dma(&input_stream,&s3c2410_dma_client_in); /* input */	printk(AUDIO_NAME_VERBOSE " unloaded\n");}module_init(s3c2410_uda1380_init);module_exit(s3c2410_uda1380_exit);

⌨️ 快捷键说明

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