Received: by 2002:a05:6a10:206:0:0:0:0 with SMTP id 6csp2232333pxj; Sat, 5 Jun 2021 18:08:12 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxx7JxeYZ7mvmLuc3pNlfnfYDVhlrBsGHQsOWfaU7Lu2dyvjFthe55cLkhGgqHNOONefxgo X-Received: by 2002:a17:906:dfd1:: with SMTP id jt17mr11316578ejc.486.1622941692357; Sat, 05 Jun 2021 18:08:12 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1622941692; cv=none; d=google.com; s=arc-20160816; b=g4phbIot9QEPWb5DXlFGm3CaatcSKhqUnbzBcPoELhTinLfBQch2LB3hImaLAsuqDN 5G59HN0SAxWmXkg08Bpz3bmszEAjcoDNTpYkvPQCexOrwpB5HyvxXAQVG2QSJQymv0F/ QmhbUi1EhYCAsZC6Kz5PJw/+7ILjgzHDqtUeHJms67GDmvEN5FwJZRZTdDcgdM2xEAtQ eyWa9vb05yMJzVyxC7WStldgBI++a+Rmg+5geOjM/taPDb72+LaRS/vovYzFRr+pG9qc 83gh5UCJe0Uq5BW7HDP/fQgKIMp3maP7G+HVeqRhFLfNgd7WbwCDq9Es48wlB3uGInSa S9bA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:references:in-reply-to:message-id:date:subject :cc:to:from:ironport-sdr:ironport-sdr; bh=85fi7NVa7K8jqQGFtZmsvYPStq/i/jYSFBDvzWnmnao=; b=TGXaeqpqUX2rLyDbdV7ELeQMxKZCW1uj1DpSa3Abd1vBPwwbo0qJl2g2ncRo4kTMKJ hvnJLpaBXkG5P9YeZWATK2bp4T6YZf98YG1dNSlVjRxBIoV+KtFiKnTOB0JlDEii3FeN L5WuPR4db2Rx2eBRQg3KYGl7HldmiQqKieLVxOuEUk3QwC6QNPvr1dnrXFielYF8dNoY 7PXcSZPf7yoa7d7FQEzdMY6TL07hUetaQB7k6t9jd55BBhn9XbSJGTU5zUWn2fzilJxi Busp8904VKWOay0jdo3GeVqk4ukwEsTChmLL0XFcFMmcsdvAcHVtitiVn5pXhq2Xma+Y 5RnA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id bx16si6603108edb.256.2021.06.05.18.07.50; Sat, 05 Jun 2021 18:08:12 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230200AbhFFBDM (ORCPT + 99 others); Sat, 5 Jun 2021 21:03:12 -0400 Received: from mga02.intel.com ([134.134.136.20]:36539 "EHLO mga02.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230025AbhFFBDM (ORCPT ); Sat, 5 Jun 2021 21:03:12 -0400 IronPort-SDR: HEsSU8SNLFH9+urtPHfx1C6zePspASw8zx8Q0S3seVqMZLu2kiNtEDAwowxXnY1xOj0/xHbWPg hVAJV/AxNIDQ== X-IronPort-AV: E=McAfee;i="6200,9189,10006"; a="191581120" X-IronPort-AV: E=Sophos;i="5.83,252,1616482800"; d="scan'208";a="191581120" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jun 2021 18:01:22 -0700 IronPort-SDR: y77Ereashd6AfDhFFHiBET8KVca0mwnmrR2S2sH1ZOwR6dBkXudP2gY5NNu+LGadVyqwv+Bu31 FHygSxpN6sOA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.83,252,1616482800"; d="scan'208";a="412724639" Received: from brentlu-desk0.itwn.intel.com ([10.5.253.32]) by fmsmga007.fm.intel.com with ESMTP; 05 Jun 2021 18:01:18 -0700 From: Brent Lu To: alsa-devel@alsa-project.org Cc: Cezary Rojewski , Pierre-Louis Bossart , Liam Girdwood , Jie Yang , Mark Brown , Jaroslav Kysela , Takashi Iwai , Brent Lu , Rander Wang , Guennadi Liakhovetski , linux-kernel@vger.kernel.org, Ranjani Sridharan , Kai Vehmanen , Dharageswari R , Sathyanarayana Nujella , Bard Liao , Kuninori Morimoto , Naveen Manohar , Yong Zhi , Vamshi Krishna Gopal , Fred Oh , Tzung-Bi Shih Subject: [PATCH 1/4] ASoC: Intel: sof_cs42l42: support JSL DAI link sequence Date: Sun, 6 Jun 2021 08:40:59 +0800 Message-Id: <20210606004102.26190-2-brent.lu@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210606004102.26190-1-brent.lu@intel.com> References: <20210606004102.26190-1-brent.lu@intel.com> Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The backend DAI link sequence of GLK platform is different from the sequence of other platforms. We refactor the sof_card_dai_links_create() function to support both style. GLK: SPK - HP - DMIC - HDMI Other: HP - DMIC - HDMI - SPK Signed-off-by: Brent Lu --- sound/soc/intel/boards/sof_cs42l42.c | 318 ++++++++++++++++++--------- 1 file changed, 208 insertions(+), 110 deletions(-) diff --git a/sound/soc/intel/boards/sof_cs42l42.c b/sound/soc/intel/boards/sof_cs42l42.c index 8919d3ba3c89..e3171242f612 100644 --- a/sound/soc/intel/boards/sof_cs42l42.c +++ b/sound/soc/intel/boards/sof_cs42l42.c @@ -259,133 +259,166 @@ static struct snd_soc_dai_link_component dmic_component[] = { } }; -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) +static int create_spk_amp_dai_links(struct device *dev, + struct snd_soc_dai_link *links, + struct snd_soc_dai_link_component *cpus, + int *id, int ssp_amp) { - struct snd_soc_dai_link_component *idisp_components; - struct snd_soc_dai_link_component *cpus; - struct snd_soc_dai_link *links; - int i, id = 0; - - links = devm_kzalloc(dev, sizeof(struct snd_soc_dai_link) * - sof_audio_card_cs42l42.num_links, GFP_KERNEL); - cpus = devm_kzalloc(dev, sizeof(struct snd_soc_dai_link_component) * - sof_audio_card_cs42l42.num_links, GFP_KERNEL); - if (!links || !cpus) - goto devm_err; + int ret = 0; /* speaker amp */ - if (sof_cs42l42_quirk & SOF_SPEAKER_AMP_PRESENT) { - links[id].name = devm_kasprintf(dev, GFP_KERNEL, - "SSP%d-Codec", ssp_amp); - if (!links[id].name) - goto devm_err; + if (!(sof_cs42l42_quirk & SOF_SPEAKER_AMP_PRESENT)) + return 0; - links[id].id = id; + links[*id].name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-Codec", + ssp_amp); + if (!links[*id].name) { + ret = -ENOMEM; + goto devm_err; + } - if (sof_cs42l42_quirk & SOF_MAX98357A_SPEAKER_AMP_PRESENT) { - max_98357a_dai_link(&links[id]); - } else { - dev_err(dev, "no amp defined\n"); - goto devm_err; - } + links[*id].id = *id; - links[id].platforms = platform_component; - links[id].num_platforms = ARRAY_SIZE(platform_component); - links[id].dpcm_playback = 1; - links[id].no_pcm = 1; - links[id].cpus = &cpus[id]; - links[id].num_cpus = 1; - - links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, - "SSP%d Pin", - ssp_amp); - if (!links[id].cpus->dai_name) - goto devm_err; + if (sof_cs42l42_quirk & SOF_MAX98357A_SPEAKER_AMP_PRESENT) { + max_98357a_dai_link(&links[*id]); + } else { + dev_err(dev, "no amp defined\n"); + ret = -EINVAL; + goto devm_err; + } - id++; + links[*id].platforms = platform_component; + links[*id].num_platforms = ARRAY_SIZE(platform_component); + links[*id].dpcm_playback = 1; + links[*id].no_pcm = 1; + links[*id].cpus = &cpus[*id]; + links[*id].num_cpus = 1; + + links[*id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, + "SSP%d Pin", ssp_amp); + if (!links[*id].cpus->dai_name) { + ret = -ENOMEM; + goto devm_err; } + (*id)++; + +devm_err: + return ret; +} + +static int create_hp_codec_dai_links(struct device *dev, + struct snd_soc_dai_link *links, + struct snd_soc_dai_link_component *cpus, + int *id, int ssp_codec) +{ /* codec SSP */ - links[id].name = devm_kasprintf(dev, GFP_KERNEL, - "SSP%d-Codec", ssp_codec); - if (!links[id].name) + links[*id].name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-Codec", + ssp_codec); + if (!links[*id].name) goto devm_err; - links[id].id = id; - links[id].codecs = cs42l42_component; - links[id].num_codecs = ARRAY_SIZE(cs42l42_component); - links[id].platforms = platform_component; - links[id].num_platforms = ARRAY_SIZE(platform_component); - links[id].init = sof_cs42l42_init; - links[id].exit = sof_cs42l42_exit; - links[id].ops = &sof_cs42l42_ops; - links[id].dpcm_playback = 1; - links[id].dpcm_capture = 1; - links[id].no_pcm = 1; - links[id].cpus = &cpus[id]; - links[id].num_cpus = 1; - - links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, - "SSP%d Pin", - ssp_codec); - if (!links[id].cpus->dai_name) + links[*id].id = *id; + links[*id].codecs = cs42l42_component; + links[*id].num_codecs = ARRAY_SIZE(cs42l42_component); + links[*id].platforms = platform_component; + links[*id].num_platforms = ARRAY_SIZE(platform_component); + links[*id].init = sof_cs42l42_init; + links[*id].exit = sof_cs42l42_exit; + links[*id].ops = &sof_cs42l42_ops; + links[*id].dpcm_playback = 1; + links[*id].dpcm_capture = 1; + links[*id].no_pcm = 1; + links[*id].cpus = &cpus[*id]; + links[*id].num_cpus = 1; + + links[*id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, + "SSP%d Pin", + ssp_codec); + if (!links[*id].cpus->dai_name) goto devm_err; - id++; + (*id)++; + + return 0; + +devm_err: + return -ENOMEM; +} + +static int create_dmic_dai_links(struct device *dev, + struct snd_soc_dai_link *links, + struct snd_soc_dai_link_component *cpus, + int *id, int dmic_be_num) +{ + int i; /* dmic */ - if (dmic_be_num > 0) { - /* at least we have dmic01 */ - links[id].name = "dmic01"; - links[id].cpus = &cpus[id]; - links[id].cpus->dai_name = "DMIC01 Pin"; - links[id].init = dmic_init; - if (dmic_be_num > 1) { - /* set up 2 BE links at most */ - links[id + 1].name = "dmic16k"; - links[id + 1].cpus = &cpus[id + 1]; - links[id + 1].cpus->dai_name = "DMIC16k Pin"; - dmic_be_num = 2; - } + if (dmic_be_num <= 0) + return 0; + + /* at least we have dmic01 */ + links[*id].name = "dmic01"; + links[*id].cpus = &cpus[*id]; + links[*id].cpus->dai_name = "DMIC01 Pin"; + links[*id].init = dmic_init; + if (dmic_be_num > 1) { + /* set up 2 BE links at most */ + links[*id + 1].name = "dmic16k"; + links[*id + 1].cpus = &cpus[*id + 1]; + links[*id + 1].cpus->dai_name = "DMIC16k Pin"; + dmic_be_num = 2; } for (i = 0; i < dmic_be_num; i++) { - links[id].id = id; - links[id].num_cpus = 1; - links[id].codecs = dmic_component; - links[id].num_codecs = ARRAY_SIZE(dmic_component); - links[id].platforms = platform_component; - links[id].num_platforms = ARRAY_SIZE(platform_component); - links[id].ignore_suspend = 1; - links[id].dpcm_capture = 1; - links[id].no_pcm = 1; - id++; + links[*id].id = *id; + links[*id].num_cpus = 1; + links[*id].codecs = dmic_component; + links[*id].num_codecs = ARRAY_SIZE(dmic_component); + links[*id].platforms = platform_component; + links[*id].num_platforms = ARRAY_SIZE(platform_component); + links[*id].ignore_suspend = 1; + links[*id].dpcm_capture = 1; + links[*id].no_pcm = 1; + + (*id)++; } + return 0; +} + +static int create_hdmi_dai_links(struct device *dev, + struct snd_soc_dai_link *links, + struct snd_soc_dai_link_component *cpus, + int *id, int hdmi_num) +{ + struct snd_soc_dai_link_component *idisp_components; + int i; + /* HDMI */ - if (hdmi_num > 0) { - idisp_components = devm_kzalloc(dev, - sizeof(struct snd_soc_dai_link_component) * - hdmi_num, GFP_KERNEL); - if (!idisp_components) - goto devm_err; - } + if (hdmi_num <= 0) + return 0; + + idisp_components = devm_kzalloc(dev, + sizeof(struct snd_soc_dai_link_component) * + hdmi_num, GFP_KERNEL); + if (!idisp_components) + goto devm_err; + for (i = 1; i <= hdmi_num; i++) { - links[id].name = devm_kasprintf(dev, GFP_KERNEL, - "iDisp%d", i); - if (!links[id].name) + links[*id].name = devm_kasprintf(dev, GFP_KERNEL, + "iDisp%d", i); + if (!links[*id].name) goto devm_err; - links[id].id = id; - links[id].cpus = &cpus[id]; - links[id].num_cpus = 1; - links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, - "iDisp%d Pin", i); - if (!links[id].cpus->dai_name) + links[*id].id = *id; + links[*id].cpus = &cpus[*id]; + links[*id].num_cpus = 1; + links[*id].cpus->dai_name = devm_kasprintf(dev, + GFP_KERNEL, + "iDisp%d Pin", + i); + if (!links[*id].cpus->dai_name) goto devm_err; idisp_components[i - 1].name = "ehdaudio0D2"; @@ -396,14 +429,79 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, if (!idisp_components[i - 1].dai_name) goto devm_err; - links[id].codecs = &idisp_components[i - 1]; - links[id].num_codecs = 1; - links[id].platforms = platform_component; - links[id].num_platforms = ARRAY_SIZE(platform_component); - links[id].init = sof_hdmi_init; - links[id].dpcm_playback = 1; - links[id].no_pcm = 1; - id++; + links[*id].codecs = &idisp_components[i - 1]; + links[*id].num_codecs = 1; + links[*id].platforms = platform_component; + links[*id].num_platforms = ARRAY_SIZE(platform_component); + links[*id].init = sof_hdmi_init; + links[*id].dpcm_playback = 1; + links[*id].no_pcm = 1; + + (*id)++; + } + + return 0; + +devm_err: + return -ENOMEM; +} + +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 *cpus; + struct snd_soc_dai_link *links; + int ret, id = 0; + + links = devm_kzalloc(dev, sizeof(struct snd_soc_dai_link) * + sof_audio_card_cs42l42.num_links, GFP_KERNEL); + cpus = devm_kzalloc(dev, sizeof(struct snd_soc_dai_link_component) * + sof_audio_card_cs42l42.num_links, GFP_KERNEL); + if (!links || !cpus) + goto devm_err; + + if (soc_intel_is_glk()) { + /* gemini lake starts from spk link */ + ret = create_spk_amp_dai_links(dev, links, cpus, &id, ssp_amp); + if (ret < 0) { + dev_err(dev, "fail to create spk amp dai links, ret %d\n", + ret); + goto devm_err; + } + } + + ret = create_hp_codec_dai_links(dev, links, cpus, &id, ssp_codec); + if (ret < 0) { + dev_err(dev, "fail to create hp codec dai links, ret %d\n", + ret); + goto devm_err; + } + + ret = create_dmic_dai_links(dev, links, cpus, &id, dmic_be_num); + if (ret < 0) { + dev_err(dev, "fail to create dmic dai links, ret %d\n", + ret); + goto devm_err; + } + + ret = create_hdmi_dai_links(dev, links, cpus, &id, hdmi_num); + if (ret < 0) { + dev_err(dev, "fail to create hdmi dai links, ret %d\n", + ret); + goto devm_err; + } + + if (!soc_intel_is_glk()) { + /* other platforms end with spk link */ + ret = create_spk_amp_dai_links(dev, links, cpus, &id, ssp_amp); + if (ret < 0) { + dev_err(dev, "fail to create spk amp dai links, ret %d\n", + ret); + goto devm_err; + } } return links; -- 2.17.1