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

📄 uda1380.c

📁 uda1380的驱动程序
💻 C
📖 第 1 页 / 共 3 页
字号:
	write_gpio_bit(GPIO_L3MODE, 0);	write_gpio_bit(GPIO_L3DATA, 0);	write_gpio_bit(GPIO_L3CLOCK, 1);	udelay(1);		for (i = 0; i < 8; i++) {		if (data & 0x1) {			write_gpio_bit(GPIO_L3CLOCK, 0);			udelay(1);			write_gpio_bit(GPIO_L3DATA, 1);			udelay(1);			write_gpio_bit(GPIO_L3CLOCK, 1);		udelay(1);		} else {			write_gpio_bit(GPIO_L3CLOCK, 0);			udelay(1);			write_gpio_bit(GPIO_L3DATA, 0);			udelay(1);			write_gpio_bit(GPIO_L3CLOCK, 1);			udelay(1);		}		data >>= 1;	}	write_gpio_bit(GPIO_L3MODE, 1);	udelay(1);	local_irq_restore(flags);}static void uda1341_l3_data(u8 data){	int i;	int flags;	local_irq_save(flags);	write_gpio_bit(GPIO_L3MODE, 1);	udelay(1);	write_gpio_bit(GPIO_L3MODE, 0);	udelay(1);	write_gpio_bit(GPIO_L3MODE, 1);	for (i = 0; i < 8; i++) {		if (data & 0x1) {			write_gpio_bit(GPIO_L3CLOCK, 0);			udelay(1);			write_gpio_bit(GPIO_L3DATA, 1);			udelay(1);			write_gpio_bit(GPIO_L3CLOCK, 1);			udelay(1);		} else {			write_gpio_bit(GPIO_L3CLOCK, 0);			udelay(1);			write_gpio_bit(GPIO_L3DATA, 0);			udelay(1);			write_gpio_bit(GPIO_L3CLOCK, 1);			udelay(1);		}		data >>= 1;	}	write_gpio_bit(GPIO_L3MODE, 1);	write_gpio_bit(GPIO_L3MODE, 0);	udelay(1);	write_gpio_bit(GPIO_L3MODE, 1);	local_irq_restore(flags);}***** S.Yin close this part program end 2005-03-20 *****//** * Clear Audio data stream buffer. */static void audio_clear_buf(audio_stream_t * s){    int frag;												// define value.    DPRINTK( "audio_clear_buf\n" );							// pinter.    s3c2410_dma_flush_all( s->dma_ch );						// DMA     if ( s->buffers ) {										// If buffer have data...         for ( frag = 0; frag < s->nbfrags; frag++ ) {		//            if ( !s->buffers[frag].master )					//                continue;									// If Buffer have data, then            consistent_free(s->buffers[frag].start,                s->buffers[frag].master,                s->buffers[frag].dma_addr);					// Free DMA buffer.        }        kfree(s->buffers);									// Free Buffer.        s->buffers = NULL;									// Buffer clear.    }    s->buf_idx = 0;											// Buffer pointer.    s->buf = NULL;											// Buffer clear.}/** * Set audio data stream buffer.  */static int audio_setup_buf(audio_stream_t * s){    int frag;												// define value.    int dmasize = 0;										//    char *dmabuf = 0;										//    dma_addr_t dmaphys = 0;									//    /* Set buffer point and size.*/    if (s->buffers)											// If buffer have data, then.    return -EBUSY;											// return busy status.    s->nbfrags = audio_nbfrags;								//     s->fragsize = audio_fragsize;							//    s->buffers = (audio_buf_t *)        kmalloc( sizeof( audio_buf_t ) * s->nbfrags, GFP_KERNEL );    if ( !s->buffers )										//        goto err;											//    memset( s->buffers, 0, sizeof( audio_buf_t ) * s->nbfrags );    /* Move data to buffer. */    for ( frag = 0; frag < s->nbfrags; frag++ ) {			//        audio_buf_t *b = &s->buffers[frag];					//        if ( !dmasize ) {									//            dmasize = ( s->nbfrags - frag ) * s->fragsize;	//            do {											//                dmabuf = consistent_alloc(GFP_KERNEL|GFP_DMA,                    dmasize, &dmaphys);						//                if ( !dmabuf ) 								//				    dmasize -= s->fragsize;					//            } while ( !dmabuf && dmasize );					//            if ( !dmabuf )									//                goto err;									//            b->master = dmasize;							//        }        b->start = dmabuf;									//        b->dma_addr = dmaphys;								//        sema_init(&b->sem, 1);								//        DPRINTK("buf %d: start %p dma %p\n", frag, b->start,            b->dma_addr);									//        dmabuf += s->fragsize;								// counter.        dmaphys += s->fragsize;								//         dmasize -= s->fragsize;								//    }    s->buf_idx = 0;											//    s->buf = &s->buffers[0];								//    return 0;												// normal return.    /* Error process */err:    printk(AUDIO_NAME ": unable to allocate audio memory\n ");    audio_clear_buf(s);										//    return -ENOMEM;											//}/** * DMA request server. */static void audio_dmaout_done_callback(void *buf_id, int size){    audio_buf_t *b = (audio_buf_t *) buf_id;				//    up(&b->sem);											//    wake_up(&b->sem.wait);									//}static int audio_sync(struct file *file){	audio_stream_t *s = &output_stream;						//	audio_buf_t *b = s->buf;								//	DPRINTK("audio_sync\n");								//	if (!s->buffers)										//		return 0;											//	if (b->size != 0) {										//		down(&b->sem);										//        s3c2410_dma_queue_buffer(s->dma_ch, (void *) b,          b->dma_addr, b->size, DMA_BUF_WR);				//		b->size = 0;										//		NEXT_BUF(s, buf);									//	}	b = s->buffers + ((s->nbfrags + s->buf_idx - 1) % s->nbfrags);	if (down_interruptible(&b->sem))						//		return -EINTR;										//	up(&b->sem);											//	return 0;												//}static inline int copy_from_user_mono_stereo(char *to, const char *from, int count){	u_int *dst = (u_int *)to;								//	const char *end = from + count;							//	if (verify_area(VERIFY_READ, from, count))				//		return -EFAULT;										//	if ((int)from & 0x2) {									//		u_int v;											//		__get_user(v, (const u_short *)from); from += 2;	//		*dst++ = v | (v << 16);								//	}	while (from < end-2) {									//		u_int v, x, y;										//		__get_user(v, (const u_int *)from); from += 4;		//		x = v << 16;										//		x |= x >> 16;										//		y = v >> 16;										//		y |= y << 16;										//		*dst++ = x;											//		*dst++ = y;											//	}	if (from < end) {										//		u_int v;											//		__get_user(v, (const u_short *)from);				//		*dst = v | (v << 16);								//	}	return 0;												//}static ssize_t smdk2410_audio_write(struct file *file, const char *buffer, 				    size_t count, loff_t * ppos){	const char *buffer0 = buffer;							//	audio_stream_t *s = &output_stream;						//	int chunksize, ret = 0;									//	DPRINTK("audio_write : start count=%d\n", count);		//	switch (file->f_flags & O_ACCMODE) {					//	  	case O_WRONLY:										//	  	case O_RDWR:										//			break;											//	  	default:											//		  	return -EPERM;									//	}	if (!s->buffers && audio_setup_buf(s))					//		return -ENOMEM;										//	count &= ~0x03;											//	while (count > 0) {										//		audio_buf_t *b = s->buf;							//		if (file->f_flags & O_NONBLOCK) {					//			ret = -EAGAIN;									//			if (down_trylock(&b->sem))						//				break;										//		} else {											//			ret = -ERESTARTSYS;								//			if (down_interruptible(&b->sem))				//				break;										//		}		if (audio_channels == 2) {							//			chunksize = s->fragsize - b->size;				//			if (chunksize > count)							//				chunksize = count;							//			DPRINTK("write %d to %d\n", chunksize, s->buf_idx);			if (copy_from_user(b->start + b->size, buffer, chunksize)) {				up(&b->sem);								//				return -EFAULT;								//			}			b->size += chunksize;							//		} else {											//			chunksize = (s->fragsize - b->size) >> 1;		//			if (chunksize > count)							//				chunksize = count;							//			DPRINTK("write %d to %d\n", chunksize*2, s->buf_idx);			if (copy_from_user_mono_stereo(b->start + b->size, 				    		       buffer, chunksize)) {	//				up(&b->sem);								//				return -EFAULT;								//			}			b->size += chunksize*2;							//		}		buffer += chunksize;								//		count -= chunksize;									//		if (b->size < s->fragsize) {						//			up(&b->sem);									//			break;											//		}		s3c2410_dma_queue_buffer(s->dma_ch, (void *) b,					   b->dma_addr, b->size, DMA_BUF_WR);	//		b->size = 0;										//		NEXT_BUF(s, buf);									//	}	if ((buffer - buffer0))									//		ret = buffer - buffer0;								//	DPRINTK("audio_write : end count=%d\n\n", ret);			//	return ret;												//}static ssize_t smdk2410_audio_read(struct file *file, char *buffer,                                         size_t count, loff_t * ppos){	return 0;												//}static unsigned int smdk2410_audio_poll(struct file *file, 					struct poll_table_struct *wait){	unsigned int mask = 0;									//	int i;													//	DPRINTK("audio_poll(): mode=%s\n",						//		(file->f_mode & FMODE_WRITE) ? "w" : "");			//	if (file->f_mode & FMODE_WRITE) {						//		if (!output_stream.buffers && audio_setup_buf(&output_stream))			return -ENOMEM;									//		poll_wait(file, &output_stream.buf->sem.wait, wait);//		for (i = 0; i < output_stream.nbfrags; i++) {		//			if (atomic_read(&output_stream.buffers[i].sem.count) > 0)				mask |= POLLOUT | POLLWRNORM;				//		}	}	DPRINTK("audio_poll() returned mask of %s\n",		(mask & POLLOUT) ? "w" : "");						//	return mask;											//}static loff_t smdk2410_audio_llseek(struct file *file, loff_t offset, 				    int origin){            return -ESPIPE;									//}static int smdk2410_mixer_ioctl(struct inode *inode, struct file *file,                                 unsigned int cmd, unsigned long arg){        int ret;											//        long val = 0;										//	switch (cmd) {											//		case SOUND_MIXER_INFO:								//		{			mixer_info info;								//			strncpy(info.id, "UDA1380", sizeof(info.id));	//			strncpy(info.name,"Philips UDA1380", sizeof(info.name));			info.modify_counter = audio_mix_modcnt;			//			return copy_to_user((void *)arg, &info, sizeof(info));		}			case SOUND_OLD_MIXER_INFO:							//		{			_old_mixer_info info;							//			strncpy(info.id, "UDA1380", sizeof(info.id));			strncpy(info.name,"Philips UDA1380", sizeof(info.name));			return copy_to_user((void *)arg, &info, sizeof(info));		}		case SOUND_MIXER_READ_STEREODEVS:					//			return put_user(0, (long *) arg);				//		case SOUND_MIXER_READ_CAPS:							//			val = SOUND_CAP_EXCL_INPUT;						//			return put_user(val, (long *) arg);				//		case SOUND_MIXER_WRITE_VOLUME:						//			ret = get_user(val, (long *) arg);				//			if (ret)										//				return ret;									///***** S.Yin insert program begin 2005-03-20 *****/			uda1380_volume = 63 - (((val & 0xff) + 1) * 63) / 100;            _Wr2410Iic( 0x30, MASTER_VOL_REG, uda1380_volume );/***** S.Yin insert program end 2005-03-20 *****//***** S.Yin close this part program begin 2005-03-20			uda1341_l3_address(UDA1380_ADDR + UDA1341_REG_DATA);			uda1341_l3_data(uda1380_volume);***** S.Yin close this part program end 2005-03-20 *****/			break;											//				case SOUND_MIXER_READ_VOLUME:						//			val = ((63 - uda1380_volume) * 100) / 63;		//			val |= val << 8;								//			return put_user(val, (long *) arg);				//		default:											//			DPRINTK("mixer ioctl %u unknown\n", cmd);		//			return -ENOSYS;									//	}				audio_mix_modcnt++;										//	return 0;												//}static int iispsr_value(int s_bit_clock, int sample_rate){        int i, prescaler = 0;								//        unsigned long tmpval;								//        unsigned long tmpval384;							//        unsigned long tmpval384min = 0xffff;				// 	tmpval384 = s3c2410_get_bus_clk(GET_PCLK) / s_bit_clock;        for (i = 0; i < 32; i++) {							//                tmpval = tmpval384/(i+1);					//                if (PCM_ABS((sample_rate - tmpval)) < tmpval384min) {                        tmpval384min = PCM_ABS((sample_rate - tmpval));                        prescaler = i;						//                }        }        DPRINTK("prescaler addr= %d\n", prescaler);			//        return prescaler;									//}static long audio_set_dsp_speed(long val){	switch (val) {											//		case 48000:											//		case 44100:											//

⌨️ 快捷键说明

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