云题海 - 专业文章范例文档资料分享平台

当前位置:首页 > s3c2440 uda1341驱动分析

s3c2440 uda1341驱动分析

  • 62 次阅读
  • 3 次下载
  • 2025/5/24 13:48:56

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(\//获得平台设备资源

res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res == NULL) {

printk(KERN_INFO PFX \emory region resouce\\n\return -ENOENT; }

//申请可用内存

res = request_mem_region(res->start, RESSIZE(res), pdev->name); if(res == 0){

printk(KERN_INFO PFX \emory region.\\n\return -ENOENT; }

//io内存重映射

iis_base = ioremap(res->start, RESSIZE(res)); if(iis_base == 0){

printk(KERN_INFO PFX \ap() io memory region.\\n\ -EINVAL; goto free_mem_region; }

//获得时钟资源

iis_clock = clk_get(&pdev->dev, \if (iis_clock == NULL) {

printk(KERN_INFO PFX \ source\\n\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, \audio_clear_dma(&output_stream,&s3c2410iis_dma_out); printk( KERN_WARNING AUDIO_NAME_VERBOSE \return -EBUSY; }

input_stream.dma_ch = DMA_CH1;

if (!audio_init_dma(&input_stream, \audio_clear_dma(&input_stream,&s3c2410iis_dma_in); printk( KERN_WARNING AUDIO_NAME_VERBOSE \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 \//释放内存区域 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(\ove\\n\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 \return 0; }

uda1341的初始化:

设置gpio口->uda1341复位->uda1341设置 static void init_uda1341(void) {

/* GPB 4: L3CLOCK */ /* GPB 3: L3DATA */ /* GPB 2: L3MODE */ unsigned long flags;

DPRINTK(\

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) }

(2)底层的audio和mixer其实就是字符设备,完成file_operations结构体后在上面说的probe函数中注册 audio驱动: fops结构体

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 }; write:

判断打开标志是否可写->判断BUFFER内存空间是否可用->判断阻塞方式还是非阻塞方式->循环写入内存块,并将写好的内存块加入dma队列->返回传输字节数

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(\%d\\n\switch (file->f_flags & O_ACCMODE) { case O_WRONLY: case O_RDWR: break; default:

DPRINTK(\return -EPERM; }

if (!s->buffers && audio_setup_buf(s)){ DPRINTK(\return -ENOMEM; }

count &= ~0x03;

搜索更多关于: s3c2440 uda1341驱动分析 的文档
  • 收藏
  • 违规举报
  • 版权认领
下载文档10.00 元 加入VIP免费下载
推荐下载
本文作者:...

共分享92篇相关文档

文档简介:

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(\//获得平台设备资源 res = platform_get_resourc

× 游客快捷下载通道(下载后可以自由复制和排版)
单篇付费下载
限时特价:10 元/份 原价:20元
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信:fanwen365 QQ:370150219
Copyright © 云题海 All Rights Reserved. 苏ICP备16052595号-3 网站地图 客服QQ:370150219 邮箱:370150219@qq.com