Linux音頻子系統(4) - ASoC Machine

  • 瞭解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/在這裏插入圖片描述
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章