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

📄 s3c2410-uda1341.c

📁 s3c2410 uda1341 linux 2.6.14 driver
💻 C
📖 第 1 页 / 共 3 页
字号:
                }                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));                        int i;                        int frags = 0, 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:                        file->f_flags |= O_NONBLOCK;                        return 0;                 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;                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};static void init_uda1341(void){        unsigned long flags;          uda1341_volume = 62 - ((DEF_VOLUME * 61) / 100);        uda1341_boost = 0;          uda_sampling = DATA2_DEEMP_NONE;        uda_sampling &= ~(DATA2_MUTE);               local_irq_save(flags);        s3c2410_gpio_setpin(S3C2410_GPB2,1);        s3c2410_gpio_setpin(S3C2410_GPB4,1);        local_irq_restore(flags);               uda1341_l3_address(UDA1341_REG_STATUS);        uda1341_l3_data(0x40 | STAT0_SC_256FS | STAT0_IF_MSB|STAT0_DC_FILTER); // reset uda1341                uda1341_l3_data(STAT1 | STAT1_ADC_ON | STAT1_DAC_ON);                uda1341_l3_address(UDA1341_REG_DATA0);        uda1341_l3_data(DATA0 |DATA0_VOLUME(0x0));  // maximum volume        uda1341_l3_data(DATA1 |DATA1_BASS(uda1341_boost)| DATA1_TREBLE(0));                uda1341_l3_data(uda_sampling); /* --;;*/        uda1341_l3_data(EXTADDR(EXT2));        uda1341_l3_data(EXTDATA(EXT2_MIC_GAIN(0x6)) | EXT2_MIXMODE_CH1);       }static void init_s3c2410_iis_bus(void){        writel(0, iis_base + S3C2410_IISPSR);        writel(0, iis_base + S3C2410_IISCON);        writel(0, iis_base + S3C2410_IISMOD);        writel(0, iis_base + S3C2410_IISFCON);        clk_disable(iis_clock);}static void init_s3c2410_iis_bus_rx(void){        unsigned int iiscon, iismod, iisfcon;        char *dstr;        //Kill everything...        writel(0, iis_base + S3C2410_IISPSR);        writel(0, iis_base + S3C2410_IISCON);        writel(0, iis_base + S3C2410_IISMOD);        writel(0, iis_base + S3C2410_IISFCON);        clk_enable(iis_clock);        iiscon = iismod = iisfcon = 0;        //Setup basic stuff        iiscon |= S3C2410_IISCON_PSCEN;                                // Enable prescaler        iiscon |= S3C2410_IISCON_IISEN;                                // Enable interface        iismod |= IISMOD_SEL_MA;                        // Set interface to Master Mode        iismod |= S3C2410_IISMOD_LR_LLOW;                        // Low for left channel        iismod |= S3C2410_IISMOD_MSB;                                // IIS format        iismod |= S3C2410_IISMOD_16BIT;                                // Serial data bit/channel is 16 bit        iismod |= S3C2410_IISMOD_384FS;                                // Master clock freq = 384 fs        iismod |= S3C2410_IISMOD_32FS;                                // 32 fs        iisfcon|= S3C2410_IISFCON_RXDMA;                        //Set RX FIFO acces mode to DMA        iisfcon|= S3C2410_IISFCON_TXDMA;                        //Set RX FIFO acces mode to DMA        iiscon |= S3C2410_IISCON_RXDMAEN;        //Enable RX DMA service request        iiscon |= S3C2410_IISCON_TXIDLE;        //Set TX channel idle        iismod |= S3C2410_IISMOD_RXMODE;        //Set RX Mode        iisfcon|= S3C2410_IISFCON_RXENABLE;        //Enable RX Fifo        dstr="RX";        //setup the prescaler        audio_set_dsp_speed(audio_rate);        //iiscon has to be set last - it enables the interface        writel(iismod, iis_base + S3C2410_IISMOD);        writel(iisfcon, iis_base + S3C2410_IISFCON);        writel(iiscon, iis_base + S3C2410_IISCON);}static void init_s3c2410_iis_bus_tx(void){        unsigned int iiscon, iismod, iisfcon;        char *dstr;        //Kill everything...        writel(0, iis_base + S3C2410_IISPSR);        writel(0, iis_base + S3C2410_IISCON);        writel(0, iis_base + S3C2410_IISMOD);        writel(0, iis_base + S3C2410_IISFCON);        clk_enable(iis_clock);        iiscon = iismod = iisfcon = 0;        //Setup basic stuff        iiscon |= S3C2410_IISCON_PSCEN;                                // Enable prescaler        iiscon |= S3C2410_IISCON_IISEN;                                // Enable interface        iismod |= IISMOD_SEL_MA;                        // Set interface to Master Mode        iismod |= S3C2410_IISMOD_LR_LLOW;                        // Low for left channel        iismod |= S3C2410_IISMOD_MSB;                                // MSB format        iismod |= S3C2410_IISMOD_16BIT;                                // Serial data bit/channel is 16 bit        iismod |= S3C2410_IISMOD_256FS;                                // Master clock freq = 384 fs        iismod |= S3C2410_IISMOD_32FS;                                // 32 fs        iisfcon|= S3C2410_IISFCON_RXDMA;                        //Set RX FIFO acces mode to DMA        iisfcon|= S3C2410_IISFCON_TXDMA;                        //Set TX FIFO acces mode to DMA        iiscon |= S3C2410_IISCON_TXDMAEN;        //Enable TX DMA service request        iiscon |= S3C2410_IISCON_RXIDLE;        //Set RX channel idle        iismod |= S3C2410_IISMOD_TXMODE;        //Set TX Mode        iisfcon|= S3C2410_IISFCON_TXENABLE;        //Enable TX Fifo        dstr="TX";        //setup the prescaler        audio_set_dsp_speed(audio_rate);        //iiscon has to be set last - it enables the interface        writel(iismod, iis_base + S3C2410_IISMOD);        writel(iisfcon, iis_base + S3C2410_IISFCON);        writel(iiscon, iis_base + S3C2410_IISCON);}static int __init audio_init_dma(audio_stream_t * s, char *desc){        int ret ;        s3c2410_dmasrc_t         source;        int                         hwcfg;        unsigned long                 devaddr;        dmach_t                        channel;        int                         dcon;        unsigned int                flags = 0;        if(s->dma_ch == DMA_CH2){                channel = 2;                source  = S3C2410_DMASRC_MEM;                hwcfg        = 3;                devaddr        = 0x55000010;                dcon        = 1<<31;                flags        = S3C2410_DMAF_AUTOSTART;                ret = s3c2410_dma_request(s->dma_ch, &s3c2410iis_dma_out, NULL);                s3c2410_dma_devconfig(channel, source, hwcfg, devaddr);                s3c2410_dma_config(channel, 2, dcon);                s3c2410_dma_set_buffdone_fn(channel, audio_dmaout_done_callback);                s3c2410_dma_setflags(channel, flags);                s->dma_ok = 1;                return ret;        }        else if(s->dma_ch == DMA_CH1){                ret = s3c2410_dma_request(s->dma_ch, &s3c2410iis_dma_in, NULL);                            s3c2410_dma_set_buffdone_fn(s->dma_ch, audio_dmain_done_callback);                return ret ;                               }        else                return 1;}static int audio_clear_dma(audio_stream_t * s,s3c2410_dma_client_t *client){        s3c2410_dma_set_buffdone_fn(s->dma_ch, NULL);        s3c2410_dma_free(s->dma_ch, client);        return 0;}static int s3c2410iis_probe(struct device *dev) {        struct platform_device *pdev = to_platform_device(dev);        struct resource *res;        unsigned long flags;        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);        if (res == NULL) {                printk(KERN_INFO PFX "failed to get memory region resouce\n");                return -ENOENT;        }        iis_base = (void *)S3C24XX_VA_IIS ;        if (iis_base == 0) {                printk(KERN_INFO PFX "failed to ioremap() region\n");                return -EINVAL;        }        iis_clock = clk_get(dev, "iis");        if (iis_clock == NULL) {                printk(KERN_INFO PFX "failed to find clock source\n");                return -ENOENT;        }        clk_enable(iis_clock);        local_irq_save(flags);        /* GPB 4: L3CLOCK, OUTPUT */        s3c2410_gpio_cfgpin(S3C2410_GPB4, S3C2410_GPB4_OUTP);        /* GPB 3: L3DATA, OUTPUT */        s3c2410_gpio_cfgpin(S3C2410_GPB3,S3C2410_GPB3_OUTP);        /* GPB 2: L3MODE, OUTPUT */        s3c2410_gpio_cfgpin(S3C2410_GPB2,S3C2410_GPB2_OUTP);        /* GPE 3: I2SSDI */        s3c2410_gpio_cfgpin(S3C2410_GPE3,S3C2410_GPE3_I2SSDI);               /* GPE 0: I2SLRCK */        s3c2410_gpio_cfgpin(S3C2410_GPE0,S3C2410_GPE0_I2SLRCK);        /* GPE 1: I2SSCLK */        s3c2410_gpio_cfgpin(S3C2410_GPE1,S3C2410_GPE1_I2SSCLK);               /* GPE 2: CDCLK */        s3c2410_gpio_cfgpin(S3C2410_GPE2,S3C2410_GPE2_CDCLK);                       /* GPE 4: I2SSDO */        s3c2410_gpio_cfgpin(S3C2410_GPE4,S3C2410_GPE4_I2SSDO);        local_irq_restore(flags);        init_s3c2410_iis_bus();               init_uda1341();        output_stream.dma_ch = DMA_CH2;        if (audio_init_dma(&output_stream, "UDA1341 out")) {                audio_clear_dma(&output_stream,&s3c2410iis_dma_out);                printk( KERN_WARNING AUDIO_NAME_VERBOSE                        ": unable to get DMA channels\n" );                return -EBUSY;        }        input_stream.dma_ch = DMA_CH1;           if (audio_init_dma(&input_stream, "UDA1341 in")) {                        audio_clear_dma(&input_stream,&s3c2410iis_dma_in);                        printk( KERN_WARNING AUDIO_NAME_VERBOSE                        ": unable to get DMA channels\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;}static int s3c2410iis_remove(struct device *dev) {        unregister_sound_dsp(audio_dev_dsp);        unregister_sound_mixer(audio_dev_mixer);        audio_clear_dma(&output_stream,&s3c2410iis_dma_out);        audio_clear_dma(&input_stream,&s3c2410iis_dma_in); /* input */        printk(AUDIO_NAME_VERBOSE " unloaded\n");        return 0;}static struct device_driver s3c2410iis_driver = {        .name           = "s3c2410-iis",        .bus            = &platform_bus_type,        .probe          = s3c2410iis_probe,        .remove         = s3c2410iis_remove,};static int __init s3c2410_uda1341_init(void) {        memzero(&input_stream, sizeof(audio_stream_t));        memzero(&output_stream, sizeof(audio_stream_t));        return driver_register(&s3c2410iis_driver);}static void __exit s3c2410_uda1341_exit(void) {        driver_unregister(&s3c2410iis_driver);}module_init(s3c2410_uda1341_init);module_exit(s3c2410_uda1341_exit);MODULE_LICENSE("GPL");MODULE_AUTHOR("superlp<xinshengtaier@eyou.com>");MODULE_DESCRIPTION("S3C2410 uda1341 sound driver");

⌨️ 快捷键说明

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