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

📄 qq2440-audio.c

📁 uda1341 linux driver for s3c2440.
💻 C
📖 第 1 页 / 共 3 页
字号:
	    if (cold)    {        audio_rate = AUDIO_RATE_DEFAULT;        audio_channels = AUDIO_CHANNELS_DEFAULT;        /*         * the UDA1341 is stereo only ==> 2 channels         */	/* gxf add */	IISCON = 0;	IISMOD = 0;	IISFIFOC = 0;        if ((file->f_mode & FMODE_WRITE))        {            output_stream.fragsize = AUDIO_FRAGSIZE_DEFAULT;            output_stream.nbfrags = AUDIO_NBFRAGS_DEFAULT;            output_stream.channels = audio_channels;            start_sbc2440_iis_bus_tx();            audio_clear_buf(&output_stream);	    if (!output_stream .buffers && audio_setup_buf(&output_stream)) 		return -ENOMEM;            init_waitqueue_head(&output_stream.frag_wq);        }        if ((file->f_mode & FMODE_READ))        {            input_stream.fragsize = AUDIO_FRAGSIZE_DEFAULT;            input_stream.nbfrags = AUDIO_NBFRAGS_DEFAULT;            input_stream.channels = audio_channels;            start_sbc2440_iis_bus_rx();            audio_clear_buf(&input_stream);            init_waitqueue_head(&input_stream.frag_wq);        }	    }    return 0;}static intsbc2440_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 voidstart_uda1341(void){#if 0    struct uda1341_cfg cfg;    cfg.format = FMT_MSB;    cfg.fs = S_CLOCK_FREQ;    l3_command(&uda1341, L3_UDA1341_CONFIGURE, &cfg);#endif}static voidstart_sbc2440_iis_bus_rx(void){         /* gxf delete    IISCON = 0;    IISMOD = 0;    IISFIFOC = 0;    */    /*     * 44 KHz , 384fs      */    IISPSR = (IISPSR_A(iispsr_value(AUDIO_RATE_DEFAULT)) | IISPSR_B(iispsr_value(AUDIO_RATE_DEFAULT)));    dprintk("iis_bus_rx\n");#if 0    IISCON |= (IISCON_RX_DMA     /* Transmit DMA service request */              | IISCON_TX_IDLE  /* Receive Channel idle */              | IISCON_PRESCALE);   /* IIS Prescaler Enable */#endif    IISCON |= (IISCON_RX_DMA     /* Transmit DMA service request */              | IISCON_PRESCALE);   /* IIS Prescaler Enable */    IISMOD |= (IISMOD_SEL_MA     /* Master mode */              | IISMOD_SEL_RX | IISMOD_CH_RIGHT /* Low for left channel */              | IISMOD_FMT_MSB  /* MSB-justified format */              | IISMOD_BIT_16   /* Serial data bit/channel is 16 bit */#if (S_CLOCK_FREQ == 384)              | IISMOD_FREQ_384 /* Master clock freq = 384 fs */#else              | IISMOD_FREQ_256 /* Master clock freq = 256 fs */#endif              | IISMOD_SFREQ_32);   /* 32 fs */    IISFIFOC |= (IISFCON_RX_DMA  /* Transmit FIFO access mode: DMA */                | IISFCON_RX_EN);   /* Transmit FIFO enable */    IISCON |= IISCON_EN;        /* IIS enable(start) */}voidstart_sbc2440_iis_bus_tx(void){    /* gxf delete    IISCON = 0;    IISMOD = 0;    IISFIFOC = 0;    */    IISPSR = (IISPSR_A(iispsr_value(AUDIO_RATE_DEFAULT)) | IISPSR_B(iispsr_value(AUDIO_RATE_DEFAULT)));    dprintk("iis_bus_tx\n");#if 0    IISCON |= (IISCON_TX_DMA     /* Transmit DMA service request */              | IISCON_RX_IDLE  /* Receive Channel idle */              | IISCON_PRESCALE);   /* IIS Prescaler Enable */#endif    IISCON |= (IISCON_TX_DMA     /* Transmit DMA service request */                            | 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 */#if (S_CLOCK_FREQ == 384)              | IISMOD_FREQ_384 /* Master clock freq = 384 fs */#else              | IISMOD_FREQ_256 /* Master clock freq = 256 fs */#endif              | 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) */}#ifdef USE_SYSFS // sysfs»ç¿ëÇÒ °æ¿ì.static int audio_init_dma(audio_stream_t * s, char *desc)#elsestatic int __init audio_init_dma(audio_stream_t * s, char *desc)#endif{	int ret;	    if (s->dma_ch == S3C2410_DMA_CH2)    {        ret = s3c2410_dma_request(s->dma_ch, &(s->dmaclient), NULL);        if( ret )        {        	dprintk("%s: dma request err\n", __FUNCTION__ );        	return ret;        }        /* ao_dcon = S3C2410_DCON_HANDSHAKE|S3C2410_DCON_SYNC_PCLK|S3C2410_DCON_TSZUNIT|S3C2410_DCON_SSERVE|S3C2410_DCON_CH2_I2SSDO|S3C2410_DCON_NORELOAD| */	ao_dcon = 0xa0900000;        s3c2410_dma_config(s->dma_ch, 2, ao_dcon); // a out, halfword        s3c2410_dma_setflags(s->dma_ch, S3C2410_DMAF_AUTOSTART); // a out        s3c2410_dma_set_buffdone_fn(s->dma_ch, audio_dmaout_done_callback);        s3c2410_dma_devconfig(s->dma_ch, S3C2410_DMASRC_MEM, BUF_ON_APB, 0x55000010);        dprintk("%s: dma request done audio out channel\n", __FUNCTION__ );                                return 0;    }    else if (s->dma_ch == S3C2410_DMA_CH1)    {        ret = s3c2410_dma_request(s->dma_ch, &(s->dmaclient), NULL);        if( ret )        {        	dprintk("%s: dma request err\n", __FUNCTION__ );        	return ret;        }/*         ai_dcon = S3C2410_DCON_HANDSHAKE|S3C2410_DCON_SYNC_PCLK|S3C2410_DCON_TSZUNIT|S3C2410_DCON_SSERVE|S3C2410_DCON_CH1_I2SSDI|S3C2410_DCON_NORELOAD| */        ai_dcon = 0xa2900000;        s3c2410_dma_config(s->dma_ch, 2, ai_dcon); // a in, halfword        s3c2410_dma_setflags(s->dma_ch, S3C2410_DMAF_AUTOSTART); // a in                s3c2410_dma_set_buffdone_fn(s->dma_ch, audio_dmain_done_callback);        s3c2410_dma_devconfig(s->dma_ch, S3C2410_DMASRC_HW, BUF_ON_APB, 0x55000010);                          dprintk("%s: dma request done audio in channel\n", __FUNCTION__ );        return 0;    }    else        return 1;}static intaudio_clear_dma(audio_stream_t * s){	//extern int s3c2410_dma_free(dmach_t channel, s3c2410_dma_client_t *);	s3c2410_dma_free(s->dma_ch, &(s->dmaclient) );    //sbc2440_free_dma(s->dma_ch);    return 0;}// ghcstop: audio driver common routine ==> device driver register routine ===================static struct file_operations sbc2440_audio_fops = {  llseek:  sbc2440_audio_llseek,  write:   sbc2440_audio_write,  read:    sbc2440_audio_read,  poll:    sbc2440_audio_poll,  ioctl:   sbc2440_audio_ioctl,  open:    sbc2440_audio_open,  release: sbc2440_audio_release,  owner:	THIS_MODULE};static struct file_operations sbc2440_mixer_fops = {  ioctl: sbc2440_mixer_ioctl,  owner: THIS_MODULE};#if 0 // if use sa1100-audio driver style, todo thisstatic int h3600_audio_open(struct inode *inode, struct file *file){	return sa1100_audio_attach(inode, file, &audio_state);}/* * Missing fields of this structure will be patched with the call * to sa1100_audio_attach(). */static struct file_operations h3600_audio_fops = {	open:		h3600_audio_open,	owner:		THIS_MODULE};#endifstatic inline voidsbc2440_uda1341_enable(void){    start_uda1341();    start_sbc2440_iis_bus_tx();}#ifdef CONFIG_PMstatic intsbc2440_audio_suspend(struct device *dev, u32 state, u32 level){    switch (level)    {    case SUSPEND_POWER_DOWN:        break;    }    return 0;}static intsbc2440_audio_resume(struct device *dev, u32 level){    switch (level)    {    case RESUME_POWER_ON:        printk("%s\n", __FUNCTION__);        sbc2440_uda1341_enable();        break;    }    return 0;}#else#define sbc2440_audio_suspend	NULL#define sbc2440_audio_resume	NULL#endifstatic int      audio_dev_dsp, audio_dev_mixer;static int sbc2440_audio_probe(struct device *_dev){    int             ret = 0;    printk("SBC2440 SOUND driver probe!\n");    ret = l3_attach_client(&uda1341, "l3-bit-24x0-gpio", "uda1341");    if (ret)    {        printk("l3_attach_client() failed.\n");        return ret;    }    l3_open(&uda1341);    start_uda1341();    output_stream.dma_ch = S3C2410_DMA_CH2;    output_stream.dmaclient.name = "audio_out";    if (audio_init_dma(&output_stream, "UDA1341 out"))    {        audio_clear_dma(&output_stream);        printk(KERN_WARNING AUDIO_NAME_VERBOSE ": unable to get DMA channels\n");        return -EBUSY;    }    input_stream.dma_ch = S3C2410_DMA_CH1;    input_stream.dmaclient.name = "audio_in";    if (audio_init_dma(&input_stream, "UDA1341 in"))    {        audio_clear_dma(&input_stream);        printk(KERN_WARNING AUDIO_NAME_VERBOSE ": unable to get DMA channels\n");        return -EBUSY;    }    audio_dev_dsp = register_sound_dsp(&sbc2440_audio_fops, -1);    audio_dev_mixer = register_sound_mixer(&sbc2440_mixer_fops, -1);    printk(AUDIO_NAME_VERBOSE " initialized\n");    return 0;}static int sbc2440_audio_remove(struct device *_dev){    unregister_sound_dsp(audio_dev_dsp);    unregister_sound_mixer(audio_dev_mixer);    audio_clear_dma(&output_stream);    audio_clear_dma(&input_stream);    l3_close(&uda1341);    l3_detach_client(&uda1341);    printk(AUDIO_NAME_VERBOSE " unloaded\n");        return 0;}static struct device_driver sbc2440_audio_driver = {	.name		= "s3c2440-sound",	.bus		= &platform_bus_type,	.probe		= sbc2440_audio_probe,	.remove		= sbc2440_audio_remove,	.suspend	= sbc2440_audio_suspend,	.resume		= sbc2440_audio_resume,};#ifdef USE_SYSFSstatic int __init sbc2440_uda1341_init(void){	int ret = -ENODEV;printk("SBC2440 SOUND driver register\n");	//if (!machine_is_h3600() || machine_is_h3100() || machine_is_h3800())	ret = driver_register(&sbc2440_audio_driver);	if( ret )	{		printk("S3C2440 SOUND driver un registered, %d\n", ret);	}	return ret;}static void __exit sbc2440_uda1341_exit(void){	driver_unregister(&sbc2440_audio_driver);}#elseint __init sbc2440_uda1341_init(void){    int             ret = 0;//printk("ghcstop.........probe\n");    ret = l3_attach_client(&uda1341, "l3-bit-24x0-gpio", "uda1341");    if (ret)    {        printk("l3_attach_client() failed.\n");        return ret;    }    l3_open(&uda1341);    start_uda1341();    output_stream.dma_ch = S3C2410_DMA_CH2;    output_stream.dmaclient.name = "audio_out";    if (audio_init_dma(&output_stream, "UDA1341 out"))    {        audio_clear_dma(&output_stream);        printk(KERN_WARNING AUDIO_NAME_VERBOSE ": unable to get DMA channels\n");        return -EBUSY;    }    input_stream.dma_ch = S3C2410_DMA_CH1;    input_stream.dmaclient.name = "audio_in";    if (audio_init_dma(&input_stream, "UDA1341 in"))    {        audio_clear_dma(&input_stream);        printk(KERN_WARNING AUDIO_NAME_VERBOSE ": unable to get DMA channels\n");        return -EBUSY;    }    audio_dev_dsp = register_sound_dsp(&sbc2440_audio_fops, -1);    audio_dev_mixer = register_sound_mixer(&sbc2440_mixer_fops, -1);    printk(AUDIO_NAME_VERBOSE " initialized\n");    return 0;}void __exit sbc2440_uda1341_exit(void){    unregister_sound_dsp(audio_dev_dsp);    unregister_sound_mixer(audio_dev_mixer);    audio_clear_dma(&output_stream);    audio_clear_dma(&input_stream);    l3_close(&uda1341);    l3_detach_client(&uda1341);    printk(AUDIO_NAME_VERBOSE " unloaded\n");        //return 0;}#endifmodule_init(sbc2440_uda1341_init);module_exit(sbc2440_uda1341_exit);MODULE_AUTHOR("Kwanghyun La <nala.la@samsung.com>");MODULE_LICENSE("GPL");MODULE_DESCRIPTION("IIS sound driver for S3C2440");

⌨️ 快捷键说明

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