- 瞭解ASoC架構Machine
1.概述
ASoC被分爲Machine、Platform和Codec三大部分,其中Machine驅動負責Platform和Codec之間的耦合以及部分和設備或板子特定的代碼,本章的主要內容是:
- Machine驅動如何負責處理機器特有的一些控件和音頻事件;
- Machine驅動如何把Platform和Codec結合在一起完成整個設備的音頻處理工作。
1.1.硬件設計
數據流向:
- 當需要發出聲音信號的時候,數據從內存通過系統總線進入soc的I2S模塊,I2S模塊再把數據發送到UDA1341,然後通過揚聲器輸出;
- 當需要接收聲音信號的時候,數據從外界通過聲音採集設備,進入UDA1341,然後I2S模塊,最後通過系統總線傳輸到內存。
1.2. 代碼分析
- platform_device:
arch/arm/mach-s3c24xx/mach-mini2440.c:
static struct platform_device mini2440_audio = {
.name = "s3c24xx_uda134x",
.id = 0,
.dev = {
.platform_data = &mini2440_audio_pins,
},
};
- platform_driver:
sound/soc/samsung/s3c24xx_uda134x.c:
static struct platform_driver s3c24xx_uda134x_driver = {
.probe = s3c24xx_uda134x_probe,
.driver = {
.name = "s3c24xx_uda134x",
},
};
module_platform_driver(s3c24xx_uda134x_driver);
- 匹配成功後,調用probe函數:
sound/soc/samsung/s3c24xx_uda134x.c:
static int s3c24xx_uda134x_probe(struct platform_device *pdev)
{
struct snd_soc_card *card = &snd_soc_s3c24xx_uda134x;
struct s3c24xx_uda134x *priv;
int ret;
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
mutex_init(&priv->clk_lock);
card->dev = &pdev->dev;
snd_soc_card_set_drvdata(card, priv);
ret = devm_snd_soc_register_card(&pdev->dev, card);
return ret;
}
函數實現:
- 初始化struct snd_soc_card *card = &snd_soc_s3c24xx_uda134x;
- 註冊devm_snd_soc_register_card(&pdev->dev, card);
2.snd_soc_card 結構體初始化:
/* 創建並配置一個 snd_soc_card 結構體 */
static struct snd_soc_card snd_soc_s3c24xx_uda134x = {
.name = "S3C24XX_UDA134X",
.owner = THIS_MODULE,
.dai_link = &s3c24xx_uda134x_dai_link,
.num_links = 1,
};
static struct snd_soc_dai_link s3c24xx_uda134x_dai_link = {
.name = "UDA134X",
.stream_name = "UDA134X",
.codec_name = "uda134x-codec", //根據codec_name知道用哪一個編解碼芯片
.codec_dai_name = "uda134x-hifi", //codec_dai_name表示codec芯片裏的哪一個接口,有些編解碼芯片有多個接口
.cpu_dai_name = "s3c24xx-iis", //cpu_dai_name表示2440那一側的dai接口(IIs接口),
.ops = &s3c24xx_uda134x_ops,
.platform_name = "samsung-audio", //platform_name表示DMA
};
static struct snd_soc_ops s3c24xx_uda134x_ops = {
.startup = s3c24xx_uda134x_startup,
.shutdown = s3c24xx_uda134x_shutdown,
.hw_params = s3c24xx_uda134x_hw_params,
};
通過snd_soc_card結構,又引出了Machine驅動的另外兩個數據結構:
- snd_soc_dai_link:dai_link結構就是用作連接platform和codec的,指明到底用那個codec,那個platfrom。(實例:s3c24xx_uda134x_dai_link)【指定了Platform、Codec、codec_dai、cpu_dai的名字】
- snd_soc_ops(實例:s3c24xx_uda134x_ops)【硬件的操作】
其中snd_soc_dai_link,指定了Platform、Codec、codec_dai、cpu_dai的名字,Machine驅動將會利用這些名字去匹配已經在系統中註冊的platform,codec,dai,這些註冊的部件都是在另外相應的Platform驅動和Codec驅動的代碼文件中定義的,這樣看來,Machine驅動的設備初始化代碼無非就是選擇合適Platform和Codec以及dai,用它們填充以上幾個數據結構,然後註冊Platform設備即可。當然還要實現連接Platform和Codec的dai_link對應的ops實現,本例就是s3c24xx_uda134x_ops。
3.snd_soc_register_card
代碼流程如下:
refer to
- http://www.alivepea.me/kernel/alsa-asoc/