📄 uda1380.c
字号:
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 + -