Linux soc声卡构架分析.docx

上传人:b****3 文档编号:4260101 上传时间:2023-05-06 格式:DOCX 页数:60 大小:40.57KB
下载 相关 举报
Linux soc声卡构架分析.docx_第1页
第1页 / 共60页
Linux soc声卡构架分析.docx_第2页
第2页 / 共60页
Linux soc声卡构架分析.docx_第3页
第3页 / 共60页
Linux soc声卡构架分析.docx_第4页
第4页 / 共60页
Linux soc声卡构架分析.docx_第5页
第5页 / 共60页
Linux soc声卡构架分析.docx_第6页
第6页 / 共60页
Linux soc声卡构架分析.docx_第7页
第7页 / 共60页
Linux soc声卡构架分析.docx_第8页
第8页 / 共60页
Linux soc声卡构架分析.docx_第9页
第9页 / 共60页
Linux soc声卡构架分析.docx_第10页
第10页 / 共60页
Linux soc声卡构架分析.docx_第11页
第11页 / 共60页
Linux soc声卡构架分析.docx_第12页
第12页 / 共60页
Linux soc声卡构架分析.docx_第13页
第13页 / 共60页
Linux soc声卡构架分析.docx_第14页
第14页 / 共60页
Linux soc声卡构架分析.docx_第15页
第15页 / 共60页
Linux soc声卡构架分析.docx_第16页
第16页 / 共60页
Linux soc声卡构架分析.docx_第17页
第17页 / 共60页
Linux soc声卡构架分析.docx_第18页
第18页 / 共60页
Linux soc声卡构架分析.docx_第19页
第19页 / 共60页
Linux soc声卡构架分析.docx_第20页
第20页 / 共60页
亲,该文档总共60页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

Linux soc声卡构架分析.docx

《Linux soc声卡构架分析.docx》由会员分享,可在线阅读,更多相关《Linux soc声卡构架分析.docx(60页珍藏版)》请在冰点文库上搜索。

Linux soc声卡构架分析.docx

Linuxsoc声卡构架分析

Linuxsoc声卡构架分析(DMA)

以S3C2440为例进行分析,对应的文件linux-2.6.32.2/sound/soc/s3c24xx/s3c24xx_uda134x.c

其中module_init入口内容为:

357staticint__inits3c24xx_uda134x_init(void)

358{

359returnplatform_driver_register(&s3c24xx_uda134x_driver);

360}

359行是一个平台驱动的注册函数,注册的驱动是s3c24xx_uda134x_driver。

内容如下:

348staticstructplatform_drivers3c24xx_uda134x_driver={

349.probe=s3c24xx_uda134x_probe,

350.remove=s3c24xx_uda134x_remove,

351.driver={

352.name="s3c24xx_uda134x",

353.owner=THIS_MODULE,

354},

355};

由上面的name="s3c24xx_uda134x"可知,这个驱动对应的平台设备早在系统启动时在dev_init中注册进来了,所以接下来的事情就是直接调用probe方法。

290staticints3c24xx_uda134x_probe(structplatform_device*pdev)

291{

292intret;

293

294printk(KERN_INFO"S3C24XX_UDA134XSoCAudiodriver\n");

295

296s3c24xx_uda134x_l3_pins=pdev->dev.platform_data;

297if(s3c24xx_uda134x_l3_pins==NULL){

298printk(KERN_ERR"S3C24XX_UDA134XSoCAudio:

"

299"unabletofindplatformdata\n");

300return-ENODEV;

301}

302s3c24xx_uda134x.power=s3c24xx_uda134x_l3_pins->power;

303s3c24xx_uda134x.model=s3c24xx_uda134x_l3_pins->model;

304

305if(s3c24xx_uda134x_setup_pin(s3c24xx_uda134x_l3_pins->l3_data,

306"data")<0)

307return-EBUSY;

308if(s3c24xx_uda134x_setup_pin(s3c24xx_uda134x_l3_pins->l3_clk,

309"clk")<0){

310gpio_free(s3c24xx_uda134x_l3_pins->l3_data);

311return-EBUSY;

312}

313if(s3c24xx_uda134x_setup_pin(s3c24xx_uda134x_l3_pins->l3_mode,

314"mode")<0){

315gpio_free(s3c24xx_uda134x_l3_pins->l3_data);

316gpio_free(s3c24xx_uda134x_l3_pins->l3_clk);

317return-EBUSY;

318}

319

320s3c24xx_uda134x_snd_device=platform_device_alloc("soc-audio",-1);

321if(!

s3c24xx_uda134x_snd_device){

322printk(KERN_ERR"S3C24XX_UDA134XSoCAudio:

"

323"Unabletoregister\n");

324return-ENOMEM;

325}

326

327platform_set_drvdata(s3c24xx_uda134x_snd_device,

328&s3c24xx_uda134x_snd_devdata);

329s3c24xx_uda134x_snd_devdata.dev=&s3c24xx_uda134x_snd_device->dev;

330ret=platform_device_add(s3c24xx_uda134x_snd_device);

331if(ret){

332printk(KERN_ERR"S3C24XX_UDA134XSoCAudio:

Unabletoadd\n");

333platform_device_put(s3c24xx_uda134x_snd_device);

334}

335

336returnret;

337}

305-318行就是设置udal34x要用的gpio引脚的功能。

320-334行是融入soc-core的关键,320行申请的platform_dev是soc-core的device结构。

对应驱动的名称也应该是"soc-audio"。

330行是问题的关键,s3c24xx_uda134x_snd_device注册并与soc-core驱动进行匹配。

相关的内容在linux/sound/soc/soc-core.c文件中。

Soc-core的入口是module_init(snd_soc_init)。

2546staticint__initsnd_soc_init(void)

2547{

2548#ifdefCONFIG_DEBUG_FS

2549debugfs_root=debugfs_create_dir("asoc",NULL);

2550if(IS_ERR(debugfs_root)||!

debugfs_root){

2551printk(KERN_WARNING

2552"ASoC:

Failedtocreatedebugfsdirectory\n");

2553debugfs_root=NULL;

2554}

2555#endif

2556

2557returnplatform_driver_register(&soc_driver);

2558}

2557行是soc-core驱动注册的核心,soc_driver的内容如下:

1057/*ASoCplatformdriver*/

1058staticstructplatform_driversoc_driver={

1059.driver={

1060.name="soc-audio",

1061.owner=THIS_MODULE,

1062.pm=&soc_pm_ops,

1063},

1064.probe=soc_probe,

1065.remove=soc_remove,

1066};

Soc_driver和s3c24xx_uda134x_snd_device的名称匹配,满足mach的基本条件。

后面会调用soc_driver的probe方法进行驱动的进一步枚举。

978/*probesanewsocdev*/

979staticintsoc_probe(structplatform_device*pdev)

980{

981intret=0;

982structsnd_soc_device*socdev=platform_get_drvdata(pdev);

983structsnd_soc_card*card=socdev->card;

984

985/*Bodgewhilewepushthingsoutofsocdev*/

986card->socdev=socdev;

987

988/*Bodgewhileweunpickinstantiation*/

989card->dev=&pdev->dev;

990ret=snd_soc_register_card(card);

991if(ret!

=0){

992dev_err(&pdev->dev,"Failedtoregistercard\n");

993returnret;

994}

995

996return0;

997}

928行是获取平台驱动数据,这里就是前面设置的:

platform_set_drvdata(s3c24xx_uda134x_snd_device,&s3c24xx_uda134x_snd_devdata);

s3c24xx_uda134x_snd_devdata的数据类型为structsnd_soc_device

staticstructsnd_soc_devices3c24xx_uda134x_snd_devdata={

.card=&snd_soc_s3c24xx_uda134x,

.codec_dev=&soc_codec_dev_uda134x,

.codec_data=&s3c24xx_uda134x,

};

Structsnd_soc_device描述了一个soc子系统中的soc设备其成员如下:

structsnd_soc_device{

structdevice*dev;

structsnd_soc_card*card;

structsnd_soc_codec_device*codec_dev;

void*codec_data;

};

首先主要关注structsnd_soc_card*card;这个数据结构,后面的内容就是这张声卡实例化。

475structsnd_soc_card{

476char*name;

477structdevice*dev;

478

479structlist_headlist;

480

481intinstantiated;

482

483int(*probe)(structplatform_device*pdev);

484int(*remove)(structplatform_device*pdev);

485

486/*thepreandpostPMfunctionsareusedtodoanyPMworkbeforeand

487*afterthecodecandDAI'sdoanyPMwork.*/

488int(*suspend_pre)(structplatform_device*pdev,pm_message_tstate);

489int(*suspend_post)(structplatform_device*pdev,pm_message_tstate);

490int(*resume_pre)(structplatform_device*pdev);

491int(*resume_post)(structplatform_device*pdev);

492

493/*callbacks*/

494int(*set_bias_level)(structsnd_soc_card*,

495

496

497/*CPU<-->CodecDAIlinks*/

498structsnd_soc_dai_link*dai_link;

499intnum_links;

500

501structsnd_soc_device*socdev;

502

503structsnd_soc_codec*codec;

504

505structsnd_soc_platform*platform;

506structdelayed_workdelayed_work;

507structwork_structdeferred_resume_work;

508};

接下来进入到snd_soc_register_card(card);函数,这事soc_probe的核心。

2302staticintsnd_soc_register_card(structsnd_soc_card*card)

2303{

2304if(!

card->name||!

card->dev)

2305return-EINVAL;

2306

2307INIT_LIST_HEAD(&card->list);

2308card->instantiated=0;

2309

2310mutex_lock(&client_mutex);

2311list_add(&card->list,&card_list);

2312snd_soc_instantiate_cards();

2313mutex_unlock(&client_mutex);

2314

2315dev_dbg(card->dev,"Registeredcard'%s'\n",card->name);

2316

2317return0;

2318}

函数首先初始化一个list头,并将当前card加入到card_list全局的一张soc声卡链表中。

然后就调用snd_soc_instantiate_cards();来具体实例化一张声卡。

971staticvoidsnd_soc_instantiate_cards(void)

972{

973structsnd_soc_card*card;

974list_for_each_entry(card,&card_list,list)

975snd_soc_instantiate_card(card);

976}

974行遍历card_list然后调用snd_soc_instantiate_card实例化。

840staticvoidsnd_soc_instantiate_card(structsnd_soc_card*card)

841{

842structplatform_device*pdev=container_of(card->dev,

843structplatform_device,

844dev);

845structsnd_soc_codec_device*codec_dev=card->socdev->codec_dev;

846structsnd_soc_platform*platform;

847structsnd_soc_dai*dai;

848inti,found,ret,ac97;

849

850if(card->instantiated)

851return;

852

853found=0;

854list_for_each_entry(platform,&platform_list,list)

855if(card->platform==platform){

856found=1;

857break;

858}

859if(!

found){

860dev_dbg(card->dev,"Platform%snotregistered\n",

861card->platform->name);

862return;

863}

864

865ac97=0;

866for(i=0;inum_links;i++){

867found=0;

868list_for_each_entry(dai,&dai_list,list)

869if(card->dai_link[i].cpu_dai==dai){

870found=1;

871break;

872}

873if(!

found){

874dev_dbg(card->dev,"DAI%snotregistered\n",

875card->dai_link[i].cpu_dai->name);

876return;

877}

878

879if(card->dai_link[i].cpu_dai->ac97_control)

880ac97=1;

881}

882

883for(i=0;inum_links;i++){

884if(!

card->dai_link[i].codec_dai->ops)

885card->dai_link[i].codec_dai->ops=&null_dai_ops;

886}

887

888/*IfwehaveAC97inthesystemthendon'twaitforthe

889*codec.Thiswillneedrevisitingifwehavetohandle

890*systemswithmixedAC97andnon-AC97parts.Onlycheckfor

891*DAIscurrently;wecan'tdothisperlinksincesomeAC97

892*codecshavenon-AC97DAIs.

893*/

894if(!

ac97)

895for(i=0;inum_links;i++){

896found=0;

897list_for_each_entry(dai,&dai_list,list)

898if(card->dai_link[i].codec_dai==dai){

899found=1;

900break;

901}

902if(!

found){

903dev_dbg(card->dev,"DAI%snotregistered\n",

904card->dai_link[i].codec_dai->name);

905return;

906}

907}

908

909/*Notethatwedonotcurrentcheckforcodeccomponents*/

910

911dev_dbg(card->dev,"Allcomponentspresent,instantiating\n");

912

913/*Foundeverything,bringitup*/

914if(card->probe){

915ret=card->probe(pdev);

916if(ret<0)

917return;

918}

919

920for(i=0;inum_links;i++){

921structsnd_soc_dai*cpu_dai=card->dai_link[i].cpu_dai;

922if(cpu_dai->probe){

923ret=cpu_dai->probe(pdev,cpu_dai);

924if(ret<0)

925gotocpu_dai_err;

926}

927}

928

929if(codec_dev->probe){

930ret=codec_dev->probe(pdev);

931if(ret<0)

932gotocpu_dai_err;

933}

934

935if(platform->probe){

936ret=platform->probe(pdev);

937if(ret<0)

938gotoplatform_err;

939}

940

941/*DAPMstreamwork*/

942INIT_DELAYED_WORK(

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 法律文书 > 调解书

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2