日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux 音频驱动的流程,Intel平台下Linux音频驱动流程分析

發布時間:2023/12/10 linux 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux 音频驱动的流程,Intel平台下Linux音频驱动流程分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

【軟件框架】

在對要做的事情一無所知的時候,從全局看看系統的拓撲圖對我們認識新事物有很大的幫助。Audio 部分的驅動程序框架如下圖所示:

這幅圖明顯地分為 3 級。

上方藍色系的 ALSA Kernel 整體屬于Linux Kernel,是原生Linux 操作系統的一部分,其中又分出 ASoC Core 和 PCM Core 兩級,和她們相關的代碼都可以直接在 Linux 源碼中找到。

中間淡紅色的部分看名字就知道和驅動相關,分為左右 2 條支線。需要注意的是左側支線由 ASoC 派生而來,而 ASoC 雖本質上屬于 ALSA,但在代碼上將各部分驅動進行分離設計,也就是這里看到的 Platform Driver、Machine Driver、Codec Driver,分別對應 CPU 驅動、板驅動、編解碼芯片驅動。這種架構增強了 CPU 芯片驅動和編解碼芯片驅動的可移植性,讓我們在開發音頻驅動時只需要重新編寫電路板相關的板驅動即可。進一步分析,緊接 Platform Driver 后面是 SST Driver,這個 SST 即 Smart Sound Technology,是 Intel 自研的技術,所以這部分結構不一定適用于其它 CPU 芯片,但一旁的 DMA Driver 卻是所有 CPU 驅動都必須包含的,因為音頻的實質是數據;Codec Driver 之后是 I2C 驅動,對于編解碼芯片寄存器的讀寫都是通過 I2C 總線實現。右側支線從 PCM Core 引出,這部分我目前還不熟悉,從框圖和字面意思上看是和高清音頻接口相關的,直接通過 ALSA 的 PCM 機制進行操作并且在硬件上使用專門的 HDMI 控制器而非編解碼芯片。

下方灰色一級是最底層的硬件部分,依次為 CPU 內嵌的 DSP 模塊、獨立的編解碼芯片、獨立的 HDMI 控制器。在 DSP 與 Codec 之間存在音頻數據傳輸,雖然在圖中沒有注明,但我們知道這是通過 I2S 總線實現的。在我的實際項目中,DSP 模塊集成在編解碼芯片中。

無疑,編解碼芯片驅動,也即 Codec Driver 部分是我們編寫音頻驅動的核心。負責對內驅動芯片實現設備/驅動正常注冊,對外溝通 DSP 進行音頻數據交換。所以下文以此為中心進行代碼分析。

【源碼文件架構】

按照 ASoC 框架的設計理念,源碼文件應該分為 3 個部分,分別是 Platform Driver、Machine Driver、Codec Driver,這 3 者為并行關系,各對應一份源碼。其中,Platform Driver 相關的源碼主要實現 DMA 功能和 DAI,即 DSP 模塊的 I2S 數據傳輸功能,并導出相應變量或操作函數接口;Codec Driver 相關的源碼主要實現 I/O 控制、DAPM 和 PCM 配置,并導出相應變量或操作函數接口;Machine Driver 相關的源碼則將前 2 個文件中導出的接口綁定在一起。內核啟動后,以模塊的形式加載 3 個驅動。

在我的實際項目中,文件 rt5677.c 中是?Codec Driver 部分的源碼,文件 cht_rt5677.c 中則為 Machine Driver 部分的源碼。前者實現編解碼芯片的寄存器配置、設備/驅動創建與注冊,后者實現將 Machine 與 Platform 綁定。

【Machine Driver 代碼分析】

既然驅動是以模塊的形式載入的,那么我們就從模塊初始化函數開始閱讀代碼。

模塊初始化函數部分的代碼為 late_initcall(snd_cht_driver_init);

查看 snd_cht_driver_init() 函數:

static int __init snd_cht_driver_init(void)

{

return platform_driver_register(&snd_cht_mc_driver);

}

原來是注冊 platform 驅動,接下來的流程應該就比較熟悉了。

結構體snd_cht_mc_driver 的定義如下:

static struct platform_driver snd_cht_mc_driver = {

.driver = {

.owner = THIS_MODULE,

.name = "cht_rt5677",

.pm = &snd_cht_mc_pm_ops,

},

.probe = snd_cht_mc_probe, // 綁定 probe() 函數

.remove = snd_cht_mc_remove,

.shutdown = snd_cht_mc_shutdown,

};

這里的 probe 函數 snd_cht_mc_probe() 會在平臺驅動注冊過程中被調用。查看該函數代碼:

static int snd_cht_mc_probe(struct platform_device *pdev)

{

/* register the soc card */

snd_soc_card_cht.dev = &pdev->dev;

ret_val = snd_soc_register_card(&snd_soc_card_cht); // 注冊聲卡

platform_set_drvdata(pdev,&snd_soc_card_cht); // 設定聲卡信息

codec = cht_get_codec(&snd_soc_card_cht);

// use gpio GPIO_SPK_EN to enable/disable ext boost pa

gpio_request(GPIO_SPK_EN, "speaker boost pa ctl");

gpio_direction_output(GPIO_SPK_EN, 0);

return ret_val;

}

其中 snd_soc_register_card() 是ASoC Core 中的函數,由Linux 內核實現,功能是創建和注冊一個聲卡設備。而函數 platform_set_drvdata() 的功能是將預設的聲卡結構體值配置到 machine driver。追蹤 snd_soc_card_cht 這個結構體,其定義如下:

/* SoCcard */

static struct snd_soc_card snd_soc_card_cht = {

.name = "cherrytrailaud",

.dai_link = cht_dailink, // 綁定 dai_link

.num_links = ARRAY_SIZE(cht_dailink),

.set_bias_level = cht_set_bias_level,

.dapm_widgets = cht_dapm_widgets, // 綁定 dapm_widgets

.num_dapm_widgets = ARRAY_SIZE(cht_dapm_widgets),

.dapm_routes = cht_audio_map,

.num_dapm_routes = ARRAY_SIZE(cht_audio_map),

.controls = cht_mc_controls, // 綁定 controls

.num_controls = ARRAY_SIZE(cht_mc_controls),

};

在這里我們看到了 cht_dailink 數組、cht_dapm_widgets() 數組、cht_mc_controls 數組。后 2 者主要實現 DAPM 相關操作,我們重點查看 cht_dailink,該數組核心部分代碼如下:

static struct snd_soc_dai_link cht_dailink[] = {

[CHT_DPCM_AUDIO] = {

.name = "Cherrytrail Audio Port",

.stream_name = "Cherrytrail Audio",

.cpu_dai_name = "Headset-cpu-dai",

.codec_name = "snd-soc-dummy",

.codec_dai_name = "snd-soc-dummy-dai",

.platform_name = "sst-platform",

.init = cht_audio_init, // 綁定 init() 函數

.ignore_suspend = 1,

.dynamic = 1,

.ops = &cht_aif1_ops,

.dpcm_playback = 1,

},

};

初始化函數 cht_audio_init() 在第 1 個 cht_dailink 元素中被綁定。至此,Machine Driver 相關代碼的分析就完成了。

總結

以上是生活随笔為你收集整理的linux 音频驱动的流程,Intel平台下Linux音频驱动流程分析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。