设为首页 加入收藏

TOP

Linux 内核 ASoC DMA 引擎驱动程序(一)
2023-09-09 10:25:41 】 浏览:183
Tags:Linux 内核 ASoC DMA 程序

Linux 内核 ASoC 框架,在概念上将嵌入式音频系统拆分为多个可复用的组件驱动程序,包括 Codec 类驱动程序、平台类驱动程序和机器类驱动程序。在实现上,机器类驱动程序用 struct snd_soc_cardstruct snd_soc_dai_link 结构描述,属于平台类驱动程序的 DMA 引擎驱动程序由 struct snd_soc_component_driver 结构描述,codec 类驱动程序和 I2S 等驱动程序,由 struct snd_soc_component_driverstruct snd_soc_dai_driverstruct snd_soc_dai_ops 等结构描述。除平台类驱动程序外的各种驱动程序都通过 component 抽象组织在一起,即这些驱动程序都作为 struct snd_soc_component_driver 注册给 Linux 内核 ASoC 框架,Linux 内核 ASoC 框架为它们各自创建 struct snd_soc_component 结构对象,并保存在 sound/soc/soc-core.c 文件中定义的全局链表 component_list 中。

一个 DMA 驱动程序的示例为 soc/pxa/pxa2xx-pcm.c

static const struct snd_soc_component_driver pxa2xx_soc_platform = {
	.pcm_construct	= pxa2xx_soc_pcm_new,
	.pcm_destruct	= pxa2xx_soc_pcm_free,
	.open		= pxa2xx_soc_pcm_open,
	.close		= pxa2xx_soc_pcm_close,
	.hw_params	= pxa2xx_soc_pcm_hw_params,
	.hw_free	= pxa2xx_soc_pcm_hw_free,
	.prepare	= pxa2xx_soc_pcm_prepare,
	.trigger	= pxa2xx_soc_pcm_trigger,
	.pointer	= pxa2xx_soc_pcm_pointer,
	.mmap		= pxa2xx_soc_pcm_mmap,
};

static int pxa2xx_soc_platform_probe(struct platform_device *pdev)
{
	return devm_snd_soc_register_component(&pdev->dev, &pxa2xx_soc_platform,
					       NULL, 0);
}

static struct platform_driver pxa_pcm_driver = {
	.driver = {
		.name = "pxa-pcm-audio",
	},

	.probe = pxa2xx_soc_platform_probe,
};

module_platform_driver(pxa_pcm_driver);

DMA 引擎驱动程序和 I2S 或 Codec 驱动程序一样,通过 devm_snd_soc_register_component() 函数以 struct snd_soc_component_driver 的形式注册给 Linux 内核 ASoC 框架,但比较特别的地方在于,它的 dai driver 参数为空。

机器类驱动程序定义的 struct snd_soc_dai_link 结构对象通过 struct snd_soc_dai_link_component 描述它引用的其它类型的驱动程序,如机器类驱动程序 sound/soc/pxa/e800_wm9712.c 有如下的代码片段:

SND_SOC_DAILINK_DEFS(ac97,
	DAILINK_COMP_ARRAY(COMP_CPU("pxa2xx-ac97")),
	DAILINK_COMP_ARRAY(COMP_CODEC("wm9712-codec", "wm9712-hifi")),
	DAILINK_COMP_ARRAY(COMP_PLATFORM("pxa-pcm-audio")));

SND_SOC_DAILINK_DEFS(ac97_aux,
	DAILINK_COMP_ARRAY(COMP_CPU("pxa2xx-ac97-aux")),
	DAILINK_COMP_ARRAY(COMP_CODEC("wm9712-codec", "wm9712-aux")),
	DAILINK_COMP_ARRAY(COMP_PLATFORM("pxa-pcm-audio")));

static struct snd_soc_dai_link e800_dai[] = {
	{
		.name = "AC97",
		.stream_name = "AC97 HiFi",
		SND_SOC_DAILINK_REG(ac97),
	},
	{
		.name = "AC97 Aux",
		.stream_name = "AC97 Aux",
		SND_SOC_DAILINK_REG(ac97_aux),
	},
};

static struct snd_soc_card e800 = {
	.name = "Toshiba e800",
	.owner = THIS_MODULE,
	.dai_link = e800_dai,
	.num_links = ARRAY_SIZE(e800_dai),

	.dapm_widgets = e800_dapm_widgets,
	.num_dapm_widgets = ARRAY_SIZE(e800_dapm_widgets),
	.dapm_routes = audio_map,
	.num_dapm_routes = ARRAY_SIZE(audio_map),
};

SND_SOC_DAILINK_DEFS() 宏用于为 struct snd_soc_dai_link 方便地定义引用的 cpuscodecsplatformsstruct snd_soc_dai_link_component 数组,其中用于定义 platformsDAILINK_COMP_ARRAY(COMP_PLATFORM("pxa-pcm-audio")) 引用了上面我们看到的 DMA 引擎驱动。

Linux 内核 ASoC 框架提供了一个通用的 DMA 引擎驱动程序,位于文件 sound/soc/soc-generic-dmaengine-pcm 中。这个驱动程序本身不会主动向 Linux 内核 ASoC 框架注册自己,需要使用 DMA 引擎在设备和内存之间传数据的驱动程序要在 probe 时注册它,如 sound/soc/rockchip/rockchip_pcm.c

static const struct snd_pcm_hardware snd_rockchip_hardware = {
	.inf
首页 上一页 1 2 3 4 5 6 7 下一页 尾页 1/8/8
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇[20230826]dc命令复杂学习2.txt 下一篇shell简明教程2退出状态和返回代码

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目