sof_sdw.c 这个文件实现了Intel 新Soundwire 平台的Machine Driver
sof_sdw - ASOC Machine driver for Intel SoundWire platforms
sof_sdw_rt5682.c
static struct sof_sdw_codec_info codec_info_list[] = {
{
.id = 0x700,
.direction = {
true, true},
.dai_name = "rt700-aif1",
.init = sof_sdw_rt700_init,
},
{
.id = 0x711,
.direction = {
true, true},
.dai_name = "rt711-aif1",
.init = sof_sdw_rt711_init,
},
{
.id = 0x1308,
.acpi_id = "10EC1308",
.direction = {
true, false},
.dai_name = "rt1308-aif",
.ops = &sof_sdw_rt1308_i2s_ops,
.init = sof_sdw_rt1308_init,
},
{
.id = 0x715,
.direction = {
false, true},
.dai_name = "rt715-aif2",
.init = sof_sdw_rt715_init,
},
{
.id = 0x5682,
.direction = {
true, true},
.dai_name = "rt5682-sdw",
.init = sof_sdw_rt5682_init,
},
};
/* SoC card */
struct snd_soc_card {
...
/* CPU <--> Codec DAI links */
struct snd_soc_dai_link *dai_link; /* predefined links only */
int num_links; /* predefined links only */
...
}
Machine Driver 结构体define,
snd_soc_card 代表一个新的声卡实例
/* sof audio machine driver for rt5682 codec */
static struct snd_soc_card sof_audio_card_rt5682 = {
.name = "rt5682", /* the sof- prefix is added by the core */
.owner = THIS_MODULE,
.controls = sof_controls,
.num_controls = ARRAY_SIZE(sof_controls),
.dapm_widgets = sof_widgets,
.num_dapm_widgets = ARRAY_SIZE(sof_widgets),
.dapm_routes = sof_map,
.num_dapm_routes = ARRAY_SIZE(sof_map),
.fully_routed = true,
.late_probe = sof_card_late_probe,
};
创建Platform 的Dai link 就是CPU_DAI ,然后通过上面的
struct snd_soc_dai_link *dai_link;
实现了Machine Driver 对Platform 和Codec 的连接功能
dai_links = sof_card_dai_links_create(&pdev->dev, ssp_codec, ssp_amp,
dmic_be_num, hdmi_num);
if (!dai_links)
return -ENOMEM;
sof_audio_card_rt5682.dai_link = dai_links;
这里贴一下上面的sof_card_dai_links_create的实现,可以看到这个函数中创建了很多的SSP,DMIC,HDMI 的link
就是这个link :
struct snd_soc_dai_link *links;
这里的links[id] 数组包括了所有platform 的Dai Link ,这个函数是实现的关键.
这个links是这样生成的:
links = devm_kzalloc(dev, sizeof(struct snd_soc_dai_link) *
sof_audio_card_rt5682.num_links, GFP_KERNEL);
的数值是这样赋值的:基本都在probe 函数中做了 初始化.
if (soc_intel_is_byt() || soc_intel_is_cht()) {
is_legacy_cpu = 1;
dmic_be_num = 0;
hdmi_num = 0;
/* default quirk for legacy cpu */
sof_rt5682_quirk = SOF_RT5682_MCLK_EN |
SOF_RT5682_MCLK_BYTCHT_EN |
SOF_RT5682_SSP_CODEC(2);
} else {
dmic_be_num = 2;
hdmi_num = (sof_rt5682_quirk & SOF_RT5682_NUM_HDMIDEV_MASK) >>
SOF_RT5682_NUM_HDMIDEV_SHIFT;
/* default number of HDMI DAI's */
if (!hdmi_num)
hdmi_num = 3;
}
sof_audio_probe(){
…
/* compute number of dai links /
sof_audio_card_rt5682.num_links = 1 + dmic_be_num + hdmi_num;
…
}
/ codec SSP */
links[id].name = devm_kasprintf(dev, GFP_KERNEL,
“SSP%d-Codec”, ssp_codec);
sof_card_dai_links_create
static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev,
int ssp_codec,
int ssp_amp,
int dmic_be_num,
int hdmi_num)
{
struct snd_soc_dai_link_component *idisp_components;
struct snd_soc_dai_link_component *cpus;
s