alsa音效卡框架的簡單分析

2021-06-09 17:26:19 字數 4810 閱讀 7109

拿老師那個音效卡驅動移植過來自然能用,現在為了了解alsa框架,特地花了一天的時間去分析這個框架,貼出自己的分析過程,由於alsa框架比較複雜

所以分析的時候,有點亂,下面貼出分析過程(可能貼出來,函式的呼叫關係不是那麼明顯,具體的縮排體現不了,我附上自己的分析筆記)

先來看看/dev/dsp是怎麼生成的

// /dev/dsp的註冊

pcm_oss.c (linux-2.6.31\sound\core\oss)

alsa_pcm_oss_init

snd_pcm_notify(&snd_pcm_oss_notify, 0))

list_for_each_entry(pcm, &snd_pcm_devices, list)

notify->n_unregister(pcm);//.n_register =snd_pcm_oss_register_minor,

register_oss_dsp(pcm, 0);

snd_register_oss_device

snd_card_get_device_link(card);

register_sound_special_device(f_ops, minor, carddev);

register_sound_special_device(f_ops, track2,carddev);

sound_insert_unit(&chains[chain], fops, -1, unit, max_unit, name, s_irusr | s_iwusr, dev);

device_create(sound_class, dev, mkdev(sound_major, s->unit_minor),null, s->name+6);

// /dev/dsp的開啟 sound_core.c (linux-2.6.31\sound)

init_soundcore 

init_oss_soundcore();

register_chrdev(sound_major, "sound", &soundcore_fops)==-1) 

//這裡註冊了以sound_major為主裝置號,名字為"sound"的裝置

//看看soundcore_fops結構體,裡面只有open函式

//接下來看看open函式

soundcore_open(struct inode *inode, struct file *file)

s = __look_for_unit(chain, unit);

new_fops = fops_get(s->unit_fops);

s=chains[chain];//搜尋一下chains就知道,chains是在本檔案定義的

//register_sound_special_device這個函式在本檔案定義,呼叫sound_insert_unit

register_sound_special_device(const struct file_operations *fops, int unit,struct device *dev)

return sound_insert_unit(&chains[chain], fops, -1, unit, max_unit,name, s_irusr | s_iwusr, dev);

//結合 /dev/dsp的註冊就可以清楚的知道,/dev/dsp是怎麼註冊怎麼開啟的

class_create(this_module, "sound");

snd_pcm_oss_register_minor是主動被註冊的,也就是當alsa_pcm_oss_init註冊的時候,順著上述的過程然後主動呼叫

下面說說被動呼叫過程

從uda134x.c (linux-2.6.31\sound\soc\codecs)開始看

uda134x_init

snd_soc_register_dai(&uda134x_dai);

snd_soc_instantiate_cards();//這個函式的意思是例項化乙個音效卡,通過判斷它的platform和dai是否存在,如果存在

//最後是呼叫codec_dev和cpu_dai的probe函式

list_for_each_entry(card, &card_list, list)

snd_soc_instantiate_card

list_for_each_entry(platform, &platform_list, list)

if (card->platform == platform)

//搜尋&platform_list,在本檔案的                                  

snd_soc_register_platform(struct snd_soc_platform *platform)    

list_add(&platform->list, &platform_list);

//搜尋snd_soc_register_platform

//在  s3c24xx-pcm.c (linux-2.6.31\sound\soc\s3c24xx)

static int __init s3c24xx_soc_platform_init(void)

// snd_soc_register_platform(&s3c24xx_soc_platform)

//最後也會和snd_soc_register_dai(&uda134x_dai);類似的去例項化乙個音效卡

//再看看&s3c24xx_soc_platform**被引用

//搜尋發現在s3c24xx_uda134x.c (linux-2.6.31\sound\soc\s3c24xx)

static struct snd_soc_card snd_soc_s3c24xx_uda134x =

//看看s3c24xx_uda134x.c的入口函式

static int __init s3c24xx_uda134x_init(void)

//這是乙個平台驅動,看probe函式

s3c24xx_uda134x_probe

...//進行一些硬體設定,主要是設定成l3介面

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

platform_set_drvdata(s3c24xx_uda134x_snd_device,&s3c24xx_uda134x_snd_devdata);

platform_device_add(s3c24xx_uda134x_snd_device);//這裡又註冊乙個平台裝置

//搜尋"soc-audio"在soc-core.c (linux-2.6.31\sound\soc)裡面的平台驅動有

static struct platform_driver soc_driver = ,

.probe

= soc_probe,

.remove

= soc_remove,

.suspend

= soc_suspend,

.resume

= soc_resume,

};//看看它的probe函式

soc_probe(struct platform_device *pdev)

snd_soc_register_card(card);//呼叫這個函式其實就是對音效卡的例項化了

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

snd_soc_instantiate_cards();

if (cpu_dai->probe) //主要是初始化iis

...s3c24xx_snd_txctrl(0);

s3c24xx_snd_rxctrl(0);

if (codec_dev->probe)

if (platform->probe)

//主要說說codec_dev->probe這個函式的呼叫

//也就是uda134x_soc_probe(struct platform_device *pdev)

uda134x_soc_probe(struct platform_device *pdev)

snd_soc_new_pcms(socdev, sndrv_default_idx1, sndrv_default_str1);

snd_card_create(idx, xid, codec->owner, 0, &codec->card);

soc_new_pcm(socdev, &card->dai_link[i], i);

snd_pcm_new

static struct snd_device_ops ops = ;

snd_ctl_create(card);

static struct snd_device_ops ops = ;

snd_soc_init_card(socdev);

snd_card_register(codec->card);

if ((err = snd_device_register_all(card)) < 0)

list_for_each_entry(dev, &card->devices, list) {

if (dev->state == sndrv_dev_build && dev->ops->dev_register) 

.dev_register =

snd_pcm_dev_register,

snd_pcm_dev_register

list_for_each_entry(notify, &snd_pcm_notify_list, list)

notify->n_register(pcm);//到此就去註冊/dev/dsp

linux音效卡驅動框架 ALSA簡介

alsa的 檔案在 sound core 該目錄包含了alsa驅動的中間層,它是整個alsa驅動的核心部分 core oss 包含模擬舊的oss架構的pcm和mixer模組 core seq 有關音序器相關的 include alsa驅動的公共頭檔案目錄,該目錄的標頭檔案需要匯出給使用者空間的應用程...

ALSA音效卡驅動的 DAPM

參考文章 alsa音效卡驅動的 dapm dapm是dynamic audio power management的縮寫,直譯過來就是動態音訊電源管理的意思,dapm是為了使基於linux的移動裝置上的音訊子系統,在任何時候都工作在最小功耗狀態下。dapm對使用者空間的應用程式來說是透明的,所有與電源...

ALSA音效卡驅動中的DAPM詳解

alsa音效卡驅動中的dapm詳解之一 kcontrol alsa音效卡驅動中的dapm詳解之二 widget 具備路徑和電源管理資訊的kcontrol alsa音效卡驅動中的dapm詳解之三 如何定義各種widget alsa音效卡驅動中的dapm詳解之四 在驅動程式中初始化並註冊widget和r...