From: Charles Keepax ckeepax@opensource.cirrus.com
The code contains a fair amount of state tracking and one part of that is keeping track of which entry in the large global cpus snd_soc_dai_link_component array is currently in use. Add a helper function to allocate a simple DAI link, this simplifies the code slightly and moves us in the direction of eliminating the need for the large global cpus array. This does slightly increase the number of allocations done, but this is probe time and the code already does a large number of allocations so this increase is small over all.
Signed-off-by: Charles Keepax ckeepax@opensource.cirrus.com Reviewed-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Signed-off-by: Bard Liao yung-chuan.liao@linux.intel.com --- sound/soc/intel/boards/sof_sdw.c | 161 ++++++++++++++----------------- 1 file changed, 72 insertions(+), 89 deletions(-)
diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index eaecdb75686c..f64bf8b2377c 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -488,13 +488,6 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { {} };
-static struct snd_soc_dai_link_component dmic_component[] = { - { - .name = "dmic-codec", - .dai_name = "dmic-hifi", - } -}; - static struct snd_soc_dai_link_component platform_component[] = { { /* name might be overridden during probe */ @@ -1121,6 +1114,31 @@ static void init_dai_link(struct device *dev, struct snd_soc_dai_link *dai_links dai_links->ops = ops; }
+static int init_simple_dai_link(struct device *dev, struct snd_soc_dai_link *dai_links, + int be_id, char *name, int playback, int capture, + const char *cpu_dai_name, + const char *codec_name, const char *codec_dai_name, + int (*init)(struct snd_soc_pcm_runtime *rtd), + const struct snd_soc_ops *ops) +{ + struct snd_soc_dai_link_component *dlc; + + /* Allocate two DLCs one for the CPU, one for the CODEC */ + dlc = devm_kcalloc(dev, 2, sizeof(*dlc), GFP_KERNEL); + if (!dlc || !name || !cpu_dai_name || !codec_name || !codec_dai_name) + return -ENOMEM; + + dlc[0].dai_name = cpu_dai_name; + + dlc[1].name = codec_name; + dlc[1].dai_name = codec_dai_name; + + init_dai_link(dev, dai_links, be_id, name, playback, capture, + &dlc[0], 1, &dlc[1], 1, init, ops); + + return 0; +} + static bool is_unique_device(const struct snd_soc_acpi_link_adr *adr_link, unsigned int sdw_version, unsigned int mfg_id, @@ -1512,8 +1530,6 @@ static int sof_card_dai_links_create(struct snd_soc_card *card) struct snd_soc_acpi_mach *mach = dev_get_platdata(card->dev); int sdw_be_num = 0, ssp_num = 0, dmic_num = 0, hdmi_num = 0, bt_num = 0; struct mc_private *ctx = snd_soc_card_get_drvdata(card); - struct snd_soc_dai_link_component *idisp_components; - struct snd_soc_dai_link_component *ssp_components; struct snd_soc_acpi_mach_params *mach_params = &mach->mach_params; const struct snd_soc_acpi_link_adr *adr_link = mach_params->links; bool aggregation = !(sof_sdw_quirk & SOF_SDW_NO_AGGREGATION); @@ -1527,7 +1543,8 @@ static int sof_card_dai_links_create(struct snd_soc_card *card) int ssp_codec_index, ssp_mask; struct snd_soc_dai_link *dai_links; int num_links, link_index = 0; - char *name, *cpu_name; + char *name, *cpu_dai_name; + char *codec_name, *codec_dai_name; int total_cpu_dai_num; int sdw_cpu_dai_num; int i, j, be_id = 0; @@ -1670,43 +1687,26 @@ static int sof_card_dai_links_create(struct snd_soc_card *card) for (i = 0, j = 0; ssp_mask; i++, ssp_mask >>= 1) { struct sof_sdw_codec_info *info; int playback, capture; - char *codec_name;
if (!(ssp_mask & 0x1)) continue;
- name = devm_kasprintf(dev, GFP_KERNEL, - "SSP%d-Codec", i); - if (!name) - return -ENOMEM; - - cpu_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", i); - if (!cpu_name) - return -ENOMEM; - - ssp_components = devm_kzalloc(dev, sizeof(*ssp_components), - GFP_KERNEL); - if (!ssp_components) - return -ENOMEM; - info = &codec_info_list[ssp_codec_index]; + + name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-Codec", i); + cpu_dai_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", i); codec_name = devm_kasprintf(dev, GFP_KERNEL, "i2c-%s:0%d", info->acpi_id, j++); - if (!codec_name) - return -ENOMEM; - - ssp_components->name = codec_name; - /* TODO: support multi codec dai on SSP when it is needed */ - ssp_components->dai_name = info->dais[0].dai_name; - cpus[cpu_id].dai_name = cpu_name;
playback = info->dais[0].direction[SNDRV_PCM_STREAM_PLAYBACK]; capture = info->dais[0].direction[SNDRV_PCM_STREAM_CAPTURE]; - init_dai_link(dev, dai_links + link_index, be_id, name, - playback, capture, - cpus + cpu_id, 1, - ssp_components, 1, - NULL, info->ops); + + ret = init_simple_dai_link(dev, dai_links + link_index, be_id, name, + playback, capture, cpu_dai_name, + codec_name, info->dais[0].dai_name, + NULL, info->ops); + if (ret) + return ret;
ret = info->dais[0].init(card, NULL, dai_links + link_index, info, 0); if (ret < 0) @@ -1722,63 +1722,49 @@ static int sof_card_dai_links_create(struct snd_soc_card *card) dev_warn(dev, "Ignoring PCH DMIC\n"); goto HDMI; } - cpus[cpu_id].dai_name = "DMIC01 Pin"; - init_dai_link(dev, dai_links + link_index, be_id, "dmic01", - 0, 1, // DMIC only supports capture - cpus + cpu_id, 1, - dmic_component, 1, - sof_sdw_dmic_init, NULL); + + ret = init_simple_dai_link(dev, dai_links + link_index, be_id, "dmic01", + 0, 1, // DMIC only supports capture + "DMIC01 Pin", "dmic-codec", "dmic-hifi", + sof_sdw_dmic_init, NULL); + if (ret) + return ret; + INC_ID(be_id, cpu_id, link_index);
- cpus[cpu_id].dai_name = "DMIC16k Pin"; - init_dai_link(dev, dai_links + link_index, be_id, "dmic16k", - 0, 1, // DMIC only supports capture - cpus + cpu_id, 1, - dmic_component, 1, - /* don't call sof_sdw_dmic_init() twice */ - NULL, NULL); + ret = init_simple_dai_link(dev, dai_links + link_index, be_id, "dmic16k", + 0, 1, // DMIC only supports capture + "DMIC16k Pin", "dmic-codec", "dmic-hifi", + /* don't call sof_sdw_dmic_init() twice */ + NULL, NULL); + if (ret) + return ret; + INC_ID(be_id, cpu_id, link_index); }
HDMI: /* HDMI */ - if (hdmi_num > 0) { - idisp_components = devm_kcalloc(dev, hdmi_num, - sizeof(*idisp_components), - GFP_KERNEL); - if (!idisp_components) - return -ENOMEM; - } - for (i = 0; i < hdmi_num; i++) { - name = devm_kasprintf(dev, GFP_KERNEL, - "iDisp%d", i + 1); - if (!name) - return -ENOMEM; + name = devm_kasprintf(dev, GFP_KERNEL, "iDisp%d", i + 1); + cpu_dai_name = devm_kasprintf(dev, GFP_KERNEL, "iDisp%d Pin", i + 1);
if (ctx->idisp_codec) { - idisp_components[i].name = "ehdaudio0D2"; - idisp_components[i].dai_name = devm_kasprintf(dev, - GFP_KERNEL, - "intel-hdmi-hifi%d", - i + 1); - if (!idisp_components[i].dai_name) - return -ENOMEM; + codec_name = "ehdaudio0D2"; + codec_dai_name = devm_kasprintf(dev, GFP_KERNEL, + "intel-hdmi-hifi%d", i + 1); } else { - idisp_components[i] = asoc_dummy_dlc; + codec_name = "snd-soc-dummy"; + codec_dai_name = "snd-soc-dummy-dai"; }
- cpu_name = devm_kasprintf(dev, GFP_KERNEL, - "iDisp%d Pin", i + 1); - if (!cpu_name) - return -ENOMEM; + ret = init_simple_dai_link(dev, dai_links + link_index, be_id, name, + 1, 0, // HDMI only supports playback + cpu_dai_name, codec_name, codec_dai_name, + sof_sdw_hdmi_init, NULL); + if (ret) + return ret;
- cpus[cpu_id].dai_name = cpu_name; - init_dai_link(dev, dai_links + link_index, be_id, name, - 1, 0, // HDMI only supports playback - cpus + cpu_id, 1, - idisp_components + i, 1, - sof_sdw_hdmi_init, NULL); INC_ID(be_id, cpu_id, link_index); }
@@ -1787,16 +1773,13 @@ static int sof_card_dai_links_create(struct snd_soc_card *card) SOF_BT_OFFLOAD_SSP_SHIFT;
name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-BT", port); - if (!name) - return -ENOMEM; + cpu_dai_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", port);
- cpu_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", port); - if (!cpu_name) - return -ENOMEM; - - cpus[cpu_id].dai_name = cpu_name; - init_dai_link(dev, dai_links + link_index, be_id, name, 1, 1, - cpus + cpu_id, 1, &asoc_dummy_dlc, 1, NULL, NULL); + ret = init_simple_dai_link(dev, dai_links + link_index, be_id, name, + 1, 1, cpu_dai_name, asoc_dummy_dlc.name, + asoc_dummy_dlc.dai_name, NULL, NULL); + if (ret) + return ret; }
card->dai_link = dai_links;