ALSA框架学习笔记1:component注册

devm_snd_soc_register_component 是音频驱动框架中比较关键的一个函数,单独分析下。
一、函数原型
/**
 * devm_snd_soc_register_component - resource managed component registration
 * @dev: Device used to manage component
 * @cmpnt_drv: Component driver
 * @dai_drv: DAI driver
 * @num_dai: Number of DAIs to register
 *
 * Register a component with automatic unregistration when the device is
 * unregistered.
 */
int devm_snd_soc_register_component(struct device *dev,
			 const struct snd_soc_component_driver *cmpnt_drv,
			 struct snd_soc_dai_driver *dai_drv, int num_dai)
{
	struct device **ptr;
	int ret;

	ptr = devres_alloc(devm_component_release, sizeof(*ptr), GFP_KERNEL);
	if (!ptr)
		return -ENOMEM;

	ret = snd_soc_register_component(dev, cmpnt_drv, dai_drv, num_dai);
	if (ret == 0) {
		*ptr = dev;
		devres_add(dev, ptr);
	} else {
		devres_free(ptr);
	}

	return ret;
}

作用:构造一个component,并add到全局的component_list中,并将dai_driver与component建立联系。

二、函数实现(省略部分细节)
snd_soc_register_component(dev, cmpnt_drv, dai_drv, num_dai)
{
	struct snd_soc_component *component;			// 创建一个component
	... ...
	snd_soc_add_component(dev, component, component_driver, dai_drv, num_dai)
	{
		snd_soc_component_initialize(component, component_driver, dev)
		{
			component->name = fmt_single_name(dev, &component->id);
			component->dev = dev;          			// component->dev指向dev,即platform_device->dev
			component->driver = driver;   			// component->driver指向component_driver
		}
		
		snd_soc_register_dais(component, dai_drv, num_dai)
		{
			// 一个component可以有多个dai_driver
			for (i = 0; i < count; i++) 
			{
				soc_add_dai(component, dai_drv + i, count == 1 && !component->driver->non_legacy_dai_naming)
				{
					struct snd_soc_dai *dai;	 						// 创建一个soc_dai
					dai->component = component;  						// dai->component指向component
					dai->dev = dev;              						// dai->dev指向component->dev
					dai->driver = dai_drv;       						// dai->driver指向dai_drv
					list_add_tail(&dai->list, &component->dai_list);	// 把dai->list加到component->dai_list中
				}
			}
		}
		
		snd_soc_component_add(component)
		{
			list_add(&component->list, &component_list);		// 把component->list加入到全局的component_list中
		}
		
		// 暂时先跳过
		snd_soc_try_rebind_card()
		{
			... ...
		}
	}
}
三、结构体关系图

ALSA框架学习笔记1:component注册_第1张图片

你可能感兴趣的:(linux,android,学习)