S3C2440 UDA1341声卡驱动分析(oos)

发布者:EtherealMelody最新更新时间:2024-06-13 来源: elecfans关键字:S3C2440  UDA1341  声卡驱动 手机看文章 扫描二维码
随时随地手机看文章

1,驱动架构:
驱动分两个层次,上层是平台设备驱动,底层是audio驱动与mixer驱动。

(1)标准的平台设备驱动结构,probe与remove两个函数。
probe:
获得平台资源->申请内存区域-io内存重映射->获得并使能时钟->设置gpio口->初始化iis总线-> 初始化uda1341->audio dma初始化->注册dsp和mixer->释放内存区域。
代码及注释:

static int s3c2410iis_probe(struct platform_device *pdev) {

struct resource *res;
unsigned long flags;
int ret;

DPRINTK('s3c2410iis_proben');

//获得平台设备资源

res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (res == NULL) {
printk(KERN_INFO PFX 'failed to get memory region resoucen');
return -ENOENT;
}

//申请可用内存

res = request_mem_region(res->start, RESSIZE(res), pdev->name);
if(res == 0){
printk(KERN_INFO PFX 'failed to request io memory region.n');
return -ENOENT;
}

//io内存重映射

iis_base = ioremap(res->start, RESSIZE(res));
if(iis_base == 0){
printk(KERN_INFO PFX 'failed to ioremap() io memory region.n'); ret = -EINVAL;
goto free_mem_region;
}

//获得时钟资源

iis_clock = clk_get(&pdev->dev, 'iis');
if (iis_clock == NULL) {
printk(KERN_INFO PFX 'failed to find clock sourcen');
return -ENOENT;
}
/**************************modify by lfc*****************************/
clk_enable(iis_clock);//使能时钟

/*****************************end add********************************/
//禁用本地中断,gpio口设置,恢复中断

local_irq_save(flags);

/* GPB 4: L3CLOCK, OUTPUT */
s3c2410_gpio_cfgpin(S3C2410_GPB4, S3C2410_GPB4_OUTP);
s3c2410_gpio_pullup(S3C2410_GPB4,1);
/* GPB 3: L3DATA, OUTPUT */
s3c2410_gpio_cfgpin(S3C2410_GPB3,S3C2410_GPB3_OUTP);
/* GPB 2: L3MODE, OUTPUT */
s3c2410_gpio_cfgpin(S3C2410_GPB2,S3C2410_GPB2_OUTP);
s3c2410_gpio_pullup(S3C2410_GPB2,1);
/* GPE 3: I2SSDI */
s3c2410_gpio_cfgpin(S3C2410_GPE3,S3C2410_GPE3_I2SSDI);
s3c2410_gpio_pullup(S3C2410_GPE3,1);
/* GPE 0: I2SLRCK */
s3c2410_gpio_cfgpin(S3C2410_GPE0,S3C2410_GPE0_I2SLRCK);
s3c2410_gpio_pullup(S3C2410_GPE0,1);
/* GPE 1: I2SSCLK */
s3c2410_gpio_cfgpin(S3C2410_GPE1,S3C2410_GPE1_I2SSCLK);
s3c2410_gpio_pullup(S3C2410_GPE1,1);
/* GPE 2: CDCLK */
s3c2410_gpio_cfgpin(S3C2410_GPE2,S3C2410_GPE2_CDCLK);
s3c2410_gpio_pullup(S3C2410_GPE2,1);
/* GPE 4: I2SSDO */
s3c2410_gpio_cfgpin(S3C2410_GPE4,S3C2410_GPE4_I2SSDO);
s3c2410_gpio_pullup(S3C2410_GPE4,1);

local_irq_restore(flags);

init_s3c2410_iis_bus();//初始化iis


init_uda1341();//初始化uda1341


//初始化dma ch1 ch2

output_stream.dma_ch = DMA_CH2;

if (!audio_init_dma(&output_stream, 'UDA1341 out') & DMACH_LOW_LEVEL) {
audio_clear_dma(&output_stream,&s3c2410iis_dma_out);
printk( KERN_WARNING AUDIO_NAME_VERBOSE
': unable to get DMA channelsn' );
return -EBUSY;
}

input_stream.dma_ch = DMA_CH1;

if (!audio_init_dma(&input_stream, 'UDA1341 in') & DMACH_LOW_LEVEL) {
audio_clear_dma(&input_stream,&s3c2410iis_dma_in);
printk( KERN_WARNING AUDIO_NAME_VERBOSE
': unable to get DMA channelsn' );
return -EBUSY;
}

//注册dsp及mixer

audio_dev_dsp = register_sound_dsp(&smdk2410_audio_fops, -1);
audio_dev_mixer = register_sound_mixer(&smdk2410_mixer_fops, -1);

printk(AUDIO_NAME_VERBOSE ' initializedn');

//释放内存区域

free_mem_region:
release_mem_region(res->start, RESSIZE(res));

return 0;
}

remove:
禁用时钟->取消dsp mixer注册->清除dma

static int s3c2410iis_remove(struct platform_device *dev) {
DPRINTK('s3c2410iis_removen');

if (iis_clock != NULL){
clk_disable(iis_clock);
clk_put(iis_clock);
iis_clock = NULL;
}

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 ' unloadedn');

return 0;
}

uda1341的初始化:
设置gpio口->uda1341复位->uda1341设置

static void init_uda1341(void)
{

/* GPB 4: L3CLOCK */
/* GPB 3: L3DATA */
/* GPB 2: L3MODE */

unsigned long flags;

DPRINTK('init_uda1341n');

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);//L3MODE=1

s3c2410_gpio_setpin(S3C2410_GPB4,1);//L3CLOCK=1

local_irq_restore(flags);

uda1341_l3_address(UDA1341_REG_STATUS);
uda1341_l3_data(0x40 | STAT0_SC_384FS | 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(DATA0 | DATA0_VOLUME(uda1341_volume));//lfc

uda1341_l3_data(DATA1 |DATA1_BASS(uda1341_boost)| DATA1_TREBLE(0));
uda1341_l3_data((DATA2 |DATA2_DEEMP_NONE) &~(DATA2_MUTE));
uda1341_l3_data(EXTADDR(EXT2));
uda1341_l3_data(EXTDATA(EXT2_MIC_GAIN(0x6)) | EXT2_MIXMODE_CH1);//input channel 1 select(input channel 2 off)


}


关键字:S3C2440  UDA1341  声卡驱动 引用地址:S3C2440 UDA1341声卡驱动分析(oos)

上一篇:Linux S3C2440 LCD 设备驱动
下一篇:S3C2440 触摸屏驱动(针对Android版)

推荐阅读最新更新时间:2024-11-08 12:18

s3c2440启动过程分析
2440启动过程算是一个难点,不太容易理解,而对于2440启动过程的理解,影响了后面裸机代码执行流程的分析,从而看出2440启动过程的重要性。 2440启动方式和启动方式选择 在S3C2440的datasheet《S3C2440A_UserManual_Rev13.pdf》中搜索map,可以在第5章中搜索到下图。 从此图中,可以得知 OM = 01,10,Not using NAND flash for boot ROM OM = 00, Using NAND flash for boot ROM 而OM 又是什么呢? 从S3C2440的datasheet《S3C2440A_UserManual_Rev13.pdf》中搜
[单片机]
ADS1.2使用jlink调试程序(调试芯片s3c2440 arm9)
一、软件安装 ADS1.2下载: http://down.drv5.cn/www.drv5.cn/arm ads1.2.rar jlink驱动下载: http://fastsoft.onlinedown.net/down/JLink_Windows_V630d.exe S3C2440led裸机程序(GT2440开发板的): https://download.csdn.net/download/u012577474/11249524 下载,安装上面的3个软件。 二、CodeWarrior编辑arm程序 ADS安装后,会安装以下这些工具。 这里先打开CodeWarrior,导入我们的led裸机程序。 程序目录: 导入程
[单片机]
ADS1.2使用jlink调试程序(调试芯片<font color='red'>s3c2440</font> arm9)
S3C2440存储控制器和MMU浅析
一、S3C2440存储控制器 如果大家写过S3C2440的ARM裸机程序都应该知道通常SDRAM的起始地址是0X30000000,但是大家有没有想过为什么呢?下面我将给大家做一个简要的介绍。 查S3C2440的手册可知S3C2440可寻址1G的地址范围,但是S3C2440的地址线只有27根,理论上只能寻址2的27次方等于128M的地址范围。于是S3C2440通过一个叫BANK的东东解决了这个问题。S3C2440引出了8根BANK线(对应nGCS0~ nGCS7),通过这个8根线来选通和关闭不同的存储器,这样S3C2440最多就可以连接8个128M的存储器,只要在某一时刻只选通一个BANK就可以实现1G的寻址空间每个
[单片机]
<font color='red'>S3C2440</font>存储控制器和MMU浅析
GNU ARM汇编--(六)s3c2440的时钟控制
前面几篇利用GNU ARM汇编控制LED以及ARM的中断处理的设计,对ARM汇编以及体系结构有了一定的认识.后面的汇编学习会结合具体的芯片进行,一个为了更灵活熟练的使用汇编,二也是为了通过学习一款具体芯片来提炼出一些有价值的经验.此次选择的芯片是三星的s3c2440,arm920t的核,整个板子是TQ2440的板子,这个板子放了两年多了,零散的玩过一些,但是为了建立更有体系的知识结构,还是值得把它玩过个遍.可能这个芯片很过时了,应该很多人在玩6410,在工作中接触的也是arm11Cortex-A9或者ppc,但是很多东西并不会过时的.虽然工作中接触的东西比较新,但是作为做应用的公司,很多底层的东西IC设计厂商都帮你做好了,你
[单片机]
GNU ARM汇编--(六)<font color='red'>s3c2440</font>的时钟控制
GPIO-点亮一个LED(JZ2440-S3C2440)
1、看电气原理图 GPF4--------(GPFCON =01; GPFDAT =1) GPF4引脚输出1(高电平):LED1灯灭。 GPF4引脚输出0(低电平):LED1电亮。 2、如何让引脚输出高/低电平 (1)配置引脚功能(2)输出引脚:写值到某个寄存器;输入引脚:读寄存器的值。 3、看芯片手册 GPIO包括A----J组。 这里要用到GPF组的寄存器: GPFCON寄存器:用来配置引脚的功能; GPFDAT:引脚的值。 GPFCON寄存器的可以设置引脚的功能为:输入、输出、中断和保留功能。 GPFDAT寄存器: 4、编写程序:GPFCON的地址为0x56000050。G
[单片机]
GPIO-点亮一个LED(JZ2440-S3C2440)
基于S3C2440处理器Linux平台的物流配送系统设计
  引言   现代的物流系统已经进入了信息化的阶段。信息化配送系统对信息化物流有着重要的影响。物流配送信息化,就是运用现代信息系统与电子化手段加强对企业物流链管理,形成企业物流的支撑体系,进而实现物流配送的高效率与高效益。本文通过嵌入式系统模块与GPS定位技术的融合,加上计算机控制中心,形成一个比较完善的物流配送系统。在物流配送过程中,通过这个系统对整个物流配送过程进行监控与管理。   1 相关核心技术概述   1.1 移动定位技术   目前的移动定位技术已经非常成熟,最主要的有3类:   ① 利用卫星进行后方交汇的定位技术, 即GPS(Global Positioning System,全球定位系统),是由美国建立的一
[单片机]
基于<font color='red'>S3C2440</font>处理器Linux平台的物流配送系统设计
GNU ARM汇编--(七)s3c2440的串口控制
在配置完s3c2440的系统时钟后,我们来控制串口.之所以将串口放在这么靠前,是因为串口会给我们带来更多的信息.在没有串口的时候,uboot启动阶段只能靠led来显示一些信息.那么有了串口,debug就方便很多了.在工作中,一般情况下,很少有机会用jtag口加上昂贵的codeviser工具进行debug,也很少用gdb进行远程debug的,用的最多的还是打开debug的define来分析确定问题. 还是从s3c2440的datasheet开始: s3c2440A的UART提供3个独立的异步串行IO口,每一个都支持中断和DMA.换句话来说,UART可以产生中断请求或DMA请求来在CPU和UART之间传输数据.
[单片机]
GNU ARM汇编--(七)<font color='red'>s3c2440</font>的串口控制
S3C2440驱动篇之ADC驱动分析
一.硬件简介 Linux-2.6.32.2内核没有提供S3C2440的ADC驱动程序,ADC驱动属于字符设备驱动,下面就讲解驱动实现的过程。 在2440中,AD和触摸屏使用共同的A/D转换器,如下图所示,具体见2440芯片手册16章。 二.驱动实现: 驱动源码如下: #include linux/errno.h #include linux/kernel.h #include linux/module.h #include linux/slab.h #include linux/input.h #include linux/init.h #include
[单片机]
<font color='red'>S3C2440</font><font color='red'>驱动</font>篇之ADC<font color='red'>驱动</font>分析
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
").each(function(i){ $(this).attr("indexb",i); }); $(".ahover").mouseDelay().hover(function(){ var tindex = $(this).attr("indexb"); $(".ahover").each(function(i){ if(parseInt(tindex)!=parseInt(i)){ $(this).find('.show-message').animate({height:"0px"}, 1000); } }); $(this).find('.show-message').animate({height:"80px"},1000); },function(){ $(this).find('.show-message').animate({height:"0px"}, 1000); }); });