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

📄 uda1380.c

📁 uda1380的驱动程序
💻 C
📖 第 1 页 / 共 3 页
字号:
			IISPSR = (IISPSR_A(iispsr_value(S_CLOCK_FREQ, 44100)) 				| IISPSR_B(iispsr_value(S_CLOCK_FREQ, 44100)));			break;											//		case 22050:											//			IISPSR = (IISPSR_A(iispsr_value(S_CLOCK_FREQ, 22050)) 				| IISPSR_B(iispsr_value(S_CLOCK_FREQ, 22050)));			break;											//		case 11025:											//			IISPSR = (IISPSR_A(iispsr_value(S_CLOCK_FREQ, 11025)) 				| IISPSR_B(iispsr_value(S_CLOCK_FREQ, 11025)));			break;											//		case 8000:			IISPSR = (IISPSR_A(iispsr_value(S_CLOCK_FREQ, 8000)) 				| IISPSR_B(iispsr_value(S_CLOCK_FREQ, 8000)));			break;											//		default:											//			return -1;										//	}	audio_rate = val;										//		return audio_rate;										//}static int smdk2410_audio_ioctl(struct inode *inode, struct file *file,                                 uint cmd, ulong arg){	long val;												//	switch (cmd) {											//	  	case SNDCTL_DSP_SETFMT:								//			get_user(val, (long *) arg);					//		  	if (val & AUDIO_FMT_MASK) {						//			    	audio_fmt = val;						//			    	break;									//		  	} else											//				return -EINVAL;								//	  	case SNDCTL_DSP_CHANNELS:							//	  	case SNDCTL_DSP_STEREO:								//		  	get_user(val, (long *) arg);					//		  	if (cmd == SNDCTL_DSP_STEREO)					//			  	val = val ? 2 : 1;							//		  	if (val != 1 && val != 2)						//			  	return -EINVAL;								//		  	audio_channels = val;							//		  	break;											//	  	case SOUND_PCM_READ_CHANNELS:						//		  	put_user(audio_channels, (long *) arg);			//		 	break;											//	  	case SNDCTL_DSP_SPEED:								//		  	get_user(val, (long *) arg);					//		  	val = audio_set_dsp_speed(val);					//                        if (val < 0) 						//				return -EINVAL;								//		  	put_user(val, (long *) arg);					//		  	break;											//	  	case SOUND_PCM_READ_RATE:							//		  	put_user(audio_rate, (long *) arg);				//		  	break;											//	  	case SNDCTL_DSP_GETFMTS:							//		  	put_user(AUDIO_FMT_MASK, (long *) arg);			//		  	break;											//	  	case SNDCTL_DSP_GETBLKSIZE:							//		  	put_user(audio_fragsize, (long *) arg);			//		  	break;											//	  	case SNDCTL_DSP_SETFRAGMENT:						//		  	if (output_stream.buffers)						//			  	return -EBUSY;								//		  	get_user(val, (long *) arg);					//		  	audio_fragsize = 1 << (val & 0xFFFF);			//		  	if (audio_fragsize < 16)						//			  	audio_fragsize = 16;						//		  	if (audio_fragsize > 16384)						//			  	audio_fragsize = 16384;						//		  	audio_nbfrags = (val >> 16) & 0x7FFF;			//			if (audio_nbfrags < 2)							//				audio_nbfrags = 2;							//		  	if (audio_nbfrags * audio_fragsize > 128 * 1024)			  	audio_nbfrags = 128 * 1024 / audio_fragsize;		  	if (audio_setup_buf(&output_stream))			//			  	return -ENOMEM;								//		  	break;											//	  	case SNDCTL_DSP_SYNC:								//		  	return audio_sync(file);						//	  	case SNDCTL_DSP_GETOSPACE:							//		{			audio_stream_t *s = &output_stream;				//			audio_buf_info *inf = (audio_buf_info *) arg;			int err = verify_area(VERIFY_WRITE, inf, sizeof(*inf));			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_RESET:								//		  	switch (file->f_flags & O_ACCMODE) {			//		    		case O_RDONLY:							//		    		case O_RDWR:							//		    	}		  	switch (file->f_flags & O_ACCMODE) {			//		    		case O_WRONLY:							//		    		case O_RDWR:							//			    		audio_clear_buf(&output_stream);	//		    	}		  	return 0;										//	 	case SNDCTL_DSP_POST:								//	      	case SNDCTL_DSP_SUBDIVIDE:						//	      	case SNDCTL_DSP_NONBLOCK:						//	      	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;				//		audio_clear_buf(&output_stream);					//	}	MOD_INC_USE_COUNT;										//	return 0;												//}static int smdk2410_mixer_open(struct inode *inode, struct file *file){	MOD_INC_USE_COUNT;										//	return 0;												//}static int smdk2410_audio_release(struct inode *inode, struct file *file){	DPRINTK("audio_release\n");								//	switch (file->f_flags & O_ACCMODE) {					// Read buffer operation.	  	case O_RDONLY:										//	  	case O_RDWR:										//		  	if (audio_rd_refcount == 1)						//			  	audio_rd_refcount = 0;						//	}	switch (file->f_flags & O_ACCMODE) {					// Write buffer operation.	  	case O_WRONLY:										//	  	case O_RDWR:										//		  	if (audio_wr_refcount == 1) {					//			    	audio_sync(file);						//			    	audio_clear_buf(&output_stream);		//			    	audio_wr_refcount = 0;					//		    	}											//	  	}													//	MOD_DEC_USE_COUNT;										//	return 0;												//}static int smdk2410_mixer_release(struct inode *inode, struct file *file){	MOD_DEC_USE_COUNT;										//	return 0;												//}/* * Philips UDA1380 driver interface description, and initialize operation, * exit operation for module server. ****************************************************************************//** * Philips UDA1380 audio device interface description.  */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};/** * Philips UDA1380 audio device initialize. */static void init_uda1380( void ){    int flags;												// define value.    int i,a;												//    uda1380_volume = 0;										// Master volume.    local_irq_save(flags);									// keep.    write_gpio_bit(GPIO_L3CLOCK, 1);						// I/O Port set.    write_gpio_bit(GPIO_L3DATA, 1);							//    local_irq_restore(flags);								// restore./***** S.Yin insert program begin 2005-03-20 **********/    _Wr2410Iic( UDA1380_ADDR, 0x7f, 0xFFFF );				// reset operation.    Delay(50);												// Delay 10ms.    a = 0;    for ( i = 0; i < ARRAY_SIZE( uda1380_reg_info ); i++ ) {//        a += _Wr2410Iic( UDA1380_ADDR,             uda1380_reg_info[i].num,             uda1380_reg_info[i].default_value );			//    Delay(50);												// Delay 10ms.    }    if ( a > 0 )											//        printk( "Philips UDA1380 initialization fail ....\n" );/** S.Yin insert program end 2005-03-20 ****//***** S.Yin close program begin 2005-03-20 *	uda1341_l3_address(UDA1380_ADDR + UDA1341_REG_STATUS);	//	uda1341_l3_data(SC_384fs | IF_MSB);						// set 384 system clock, MSB	uda1341_l3_data(0xC1);									//	uda1341_l3_address(UDA1380_ADDR + UDA1341_REG_DATA);	//	uda1341_l3_data(uda1380_volume);						// maximum volume	uda1341_l3_data(uda_sampling);							//NO_DE_EMPHASIS and no muting***** S.Yin insert program end 2005-03-20 ****/}/** * Samsung S3C2410 I2C Bus device initialize. */static void init_iic_bus(void){    unsigned int save_E, save_PE;							// define value.    rtc_address_map();										// Set I2C Bus control register.    save_E   = rGPECON;										// Keep.    save_PE  = rGPEUP;										//    rGPEUP  |= 0xc000;										// Pull-up disable    rGPECON |= 0xa00000;									// GPE15:IICSDA , GPE14:IICSCL        rIICCON		= 0;										// Clear    rIICSTAT	= 0;										//    rIICADD		= 0x10;										// S3C2410 slave address=[7:1]    rIICCON		= 0xe0;										// Enable ACK, Prescaler IICCLK=PCLK/512,    														// Enable interrupt, Transmit clock value    														// Tx clock=IICCLK/512    rIICSTAT	= 0xd0;										// to get to a sane state (also generates a STOP condition)    rGPEUP  = save_PE;										// restore    rGPECON = save_E;										//}/** * Samsung S3C2410 I2S Bus device initialize. */static void init_s3c2410_iis_bus(void){    IISCON		= 0;										// Clear register.    IISMOD		= 0;										//    IISFIFOC	= 0;										//    IISPSR = (IISPSR_A( iispsr_value( S_CLOCK_FREQ,44100 ))         | IISPSR_B(iispsr_value(S_CLOCK_FREQ, 44100)));		// 44 KHz , 384fs    IISCON = (IISCON_TX_DMA									// Transmit DMA service request        |IISCON_RX_IDLE										// Receive Channel idle        |IISCON_PRESCALE);									// IIS Prescaler Enable    IISMOD = (IISMOD_SEL_MA									// Master mode        | IISMOD_SEL_TX										// Transmit        | IISMOD_CH_RIGHT									// Low for left channel        | IISMOD_FMT_MSB									// MSB-justified format        | IISMOD_BIT_16										// Serial data bit/channel is 16 bit        | IISMOD_FREQ_384									// Master clock freq = 384 fs        | IISMOD_SFREQ_32);									// 32 fs    IISFIFOC = (IISFCON_TX_DMA								// Transmit FIFO access mode: DMA        | IISFCON_TX_EN);									// Transmit FIFO enable    IISCON |= IISCON_EN;									// IIS enable(start)}/** * Samsung S3C2410 DMA device initialize for audio server. */static int __init audio_init_dma(audio_stream_t * s, char *desc){    return s3c2410_request_dma("I2SSDO", s->dma_ch, audio_dmaout_done_callback, NULL);}/** * Philips UDA1380 audio device close. */static int s3c2410_uda1380_close(void){    _Wr2410Iic( UDA1380_ADDR, 0x0, 0x0 );					// reset operation.    Delay(50);												// Delay 10ms.    _Wr2410Iic( UDA1380_ADDR, 0x02, 0x0 );					// reset operation.    Delay(50);												// Delay 10ms.    return 0;												// return.}/** * Clear Samsung S3C2410 DMA device. */static int audio_clear_dma(audio_stream_t * s){    s3c2410_free_dma(s->dma_ch);							// Free DMA device.    return 0;												// return.}/** * Philips UDA1380 Audio driver initialize. */int __init s3c2410_uda1380_init(void){    unsigned long flags;									// Define valuse.       local_irq_save(flags);									// keep.    /***** Initialize Samsung S3C2410 I/O port. *****/    set_gpio_ctrl(GPIO_L3CLOCK);							// GPB 4: L3CLOCK, OUTPUT    set_gpio_ctrl(GPIO_L3DATA);								// GPB 3: L3DATA, OUTPUT    set_gpio_ctrl(GPIO_L3MODE);								// GPB 2: L3MODE, OUTPUT    set_gpio_ctrl(GPIO_E3 | GPIO_PULLUP_EN | GPIO_MODE_I2SSDI);		// GPE 3: I2SSDI    set_gpio_ctrl(GPIO_E0 | GPIO_PULLUP_EN | GPIO_MODE_I2SSDI);		// GPE 0: I2SLRCK    set_gpio_ctrl(GPIO_E1 | GPIO_PULLUP_EN | GPIO_MODE_I2SSCLK);	// GPE 1: I2SSCLK    set_gpio_ctrl(GPIO_E2 | GPIO_PULLUP_EN | GPIO_MODE_CDCLK);		// GPE 2: CDCLK    set_gpio_ctrl(GPIO_E4 | GPIO_PULLUP_EN | GPIO_MODE_I2SSDO);		// GPE 4: I2SSDO    local_irq_restore(flags);								// restore.    /****  Samsung S3C2410 I2C bus and I2S bus, DMA device, UDA1380 Initialize. *****/    int init_iic_bus();										// I2C bus initialization.    init_uda1380();											// uda1380 initialization.    init_s3c2410_iis_bus();									// I2S bus initialization.    output_stream.dma_ch = DMA_CH2;							// DMA device initialization.    if (audio_init_dma(&output_stream, "UDA1380 out")) {	//        audio_clear_dma(&output_stream);					//        printk( KERN_WARNING AUDIO_NAME_VERBOSE            ": unable to get DMA channels\n" );				//        return -EBUSY;										// return busy.    }    /***** Register Philips UDA1380 Audio device *****/    audio_dev_dsp = register_sound_dsp(&smdk2410_audio_fops, -1);    audio_dev_mixer = register_sound_mixer(&smdk2410_mixer_fops, -1);    printk(AUDIO_NAME_VERBOSE " device initialized.\n");	// Complete note...    return 0;												// normal return.}/** * Drive device EXIT oparation. */void __exit s3c2410_uda1380_exit(void){    s3c2410_uda1380_close();								// Clear UDA1380 control register.    unregister_sound_dsp(audio_dev_dsp);					// Release audio drive interfase.    unregister_sound_mixer(audio_dev_mixer);				// Release Mixer device interfase.    audio_clear_dma(&output_stream);						// Release DMA server.    printk(AUDIO_NAME_VERBOSE " device unloaded\n");		// Release note...}module_init(s3c2410_uda1380_init);module_exit(s3c2410_uda1380_exit);MODULE_AUTHOR( "Yinshenk" );MODULE_DESCRIPTION( "Philips UDA1380 CODEC driver" );MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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