ALSA驱动asoc框架之Platform

本文详细介绍了ALSA驱动的ASOC框架中,CPU_DAI(数字音频接口)的注册过程,包括如何在snd_soc_dai_link中配置,并在zx29_i2s.c中定义对应的snd_soc_dai_driver结构体。同时,也阐述了Platform的注册,特别是在zx29_pcm.c中通过snd_soc_register_platform函数进行注册。这些操作用于建立平台与Codec之间的连接,支持不同的音频流和格式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、注册cpu_dai

前面说了machine是连接platform和Codec的桥梁,在machine章节中 zx297520v3_nau8810_dai_link中有cpu_dai_nameplatform_name,如下:

static struct snd_soc_dai_link zx297520v3_nau8810_dai_link[] =
{
	{
		.name = "NAU8810_Media",
		.stream_name = "MultiMedia",
		.codec_name = "nau8810.1-001a", //nau8810.1-001a
		.codec_dai_name = "nau8810-hifi",
		.cpu_dai_name = "MultiMedia",
		.ops = &zx297520v3_nau8810_ops,
		.init = zx297520v3_nau8810_init_paiftx,
		.platform_name	= "zx29-pcm-audio",
	},
	{
		.name = "voice_call",
		.stream_name = "voice",
		.codec_name = "nau8810.1-001a",
		.codec_dai_name = "nau8810-hifi",
		.cpu_dai_name = "voice", //"snd-soc-dummy-dai",
		.platform_name	= "snd-soc-dummy",
		.init = zx297520v3_nau8810_init_paiftx,
		.ops = &zx297520v3_nau8810_ops1,
	}
};

代码工程中搜索cpu_dai_name “MultiMedia”,在zx29_i2s.c中找到snd_soc_dai_driver结构体:

static struct snd_soc_dai_driver zx_i2s_dais[] = {
	{
		.name = "MultiMedia",
		.probe	= zx29_i2s_dai_probe,
		.suspend = zx29_i2s_suspend,
		.resume = zx29_i2s_resume,
		.playback   = {
			.stream_name = "MultiMedia Playback",
			.channels_min	= 1,
			.channels_max	= 8,
			.rates		= ZX29_I2S_RATES,
			.formats	= ZX29_I2S_FMTBIT,
		},
		.capture = {
			.stream_name = "MultiMedia Capture",
			.channels_min	= 1,
			.channels_max	= 2,
			.rates		= ZX29_I2S_RATES,
			.formats	= ZX29_I2S_FMTBIT,
		},
		.ops	= &zx29_i2s_dai_ops,
	},
	{
		.name = "voice",
		.probe = zx29_i2s_dai_probe1,
		.playback = {
			.stream_name = "voice Playback",
			.rates = ZX29_I2S_RATES,
			.formats = ZX29_I2S_FMTBIT,
			.channels_min = 1,
			.channels_max = 2,
		},
		.capture = {
			.stream_name = "voice Capture",
			.rates = ZX29_I2S_RATES,
			.formats = ZX29_I2S_FMTBIT,
			.channels_min = 1,
			.channels_max = 2,
		},
	}
};

snd_soc_dai_driver结构体ops 指向snd_soc_dai_ops结构,用于配置和控制该dai;playback snd_soc_pcm_stream结构,用于指出该dai支持的声道数,码率,数据格式等能力;capture snd_soc_pcm_stream结构,用于指出该dai支持的声道数,码率,数据格式等能力;

snd_soc_dai_ops实例如下,

static const struct snd_soc_dai_ops zx29_i2s_dai_ops = {
	.trigger	= zx29_i2s_trigger,
	.hw_params	= zx29_i2s_hw_params,
	.set_fmt	= zx29_i2s_set_fmt,
	.set_sysclk = zx29_i2s_set_sysclk,
	.startup	= zx29_i2s_startup,
	.shutdown	= zx29_i2s_shutdown,
};

trigger:数据传送的开始,暂停,恢复和停止时,该函数会被调用。
hw_params:驱动的hw_params阶段,该函数会被调用。
set_fmt:设置dai的格式
set_sysclk: 设置dai的主时钟

在整体看下注册cpu_dai的过程如下,通过snd_soc_register_dais就将上面说的snd_soc_dai_driver zx_i2s_dais关联起来了
zx29_i2s_dev_probe
—>snd_soc_register_dais

static __devinit int zx29_i2s_dev_probe(struct platform_device *pdev)
{
... ...
	return snd_soc_register_dais(&pdev->dev, zx_i2s_dais, ARRAY_SIZE(zx_i2s_dais));
}

static struct platform_driver zx29_i2s_driver = {
	.probe  = zx29_i2s_dev_probe,
	.remove = __devexit_p(zx29_i2s_dev_remove),
	.driver = {
		.name = "zx29_i2s",
		.owner = THIS_MODULE,
	},
};

二、注册platform

代码工程中搜索platform_name"zx29-pcm-audio",在zx29_pcm.c文件中找到platform_driver asoc_dma_driver如下:


static int __devinit zx29_asoc_platform_probe(struct platform_device *pdev)
{
	return snd_soc_register_platform(&pdev->dev, &zx_asoc_platform);
}

static int __devexit zx29_asoc_platform_remove(struct platform_device *pdev)
{
	snd_soc_unregister_platform(&pdev->dev);
	return 0;
}

static struct platform_driver asoc_dma_driver = {
	.driver = {
		.name = "zx29-pcm-audio",
		.owner = THIS_MODULE,
	},
	.probe = zx29_asoc_platform_probe,
	.remove = __devexit_p(zx29_asoc_platform_remove),
};

这里除了snd_soc_register_platform函数注册platform外,还要关注snd_soc_platform_driver zx_asoc_platform如下:

static struct snd_soc_platform_driver zx_asoc_platform = {
	.ops		= &dma_ops,
	.pcm_new	= zx29_dma_new,
	.pcm_free	= zx29_dma_free_dma_buffers,
};

static struct snd_pcm_ops dma_ops = {
	.open		= zx29_dma_open,
	.close		= zx29_dma_close,
	.ioctl		= snd_pcm_lib_ioctl,
	.hw_params	= zx29_dma_hw_params,
	.hw_free	= zx29_dma_hw_free,
	.prepare	= zx29_dma_prepare,
	.trigger	= zx29_dma_trigger,
	.pointer	= zx29_dma_pointer,
	.mmap		= zx29_dma_mmap,
};

对于DMA的申请释、放使用pcm_new、pcm_free,而对于配置和开始传输使用dma_ops的操作函数集来完成。
至此ALSA驱动asoc框架之machineALSA驱动asoc框架之Codec、以及本章ALSA驱动asoc框架之Platform就简单说完了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值