From patchwork Thu Mar 17 17:50:26 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Ranjani Sridharan X-Patchwork-Id: 552266 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id CFF89C433EF for ; Thu, 17 Mar 2022 17:53:28 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id F2D4818BB; Thu, 17 Mar 2022 18:52:36 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz F2D4818BB DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1647539607; bh=Px5WUh7+GYyzaDBhCLmS0KV1WQ96drJzbOBM7gBMx2w=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=CyNdqf4orpxEVMjt5Uhc51Mn3Cpk1IAyrEZJHd5fog/c4csY8OU3PJOwFMax6iC0y yr+8CIG+UbxS1Hu6kjZZ04N2RFC4U9yeQElFPZtwTVcfixritf14KRoZtQcBtyg0/J ogSe+u3/TuD+Cq0U1QTa/h4+scY3gqyByif6VJwk= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id BE5B0F8051A; Thu, 17 Mar 2022 18:51:52 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 1617DF80516; Thu, 17 Mar 2022 18:51:50 +0100 (CET) Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 25EABF80132 for ; Thu, 17 Mar 2022 18:51:42 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 25EABF80132 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="b2vHk6Dg" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1647539504; x=1679075504; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Px5WUh7+GYyzaDBhCLmS0KV1WQ96drJzbOBM7gBMx2w=; b=b2vHk6DgszM5nOVij/4tVVOEg1epxHmStxCl9rE01G5jDbIMiwoQ1nLb LhLBIvt8OykT7v19WosWvWzU8aH60fFTlkRxvgW93lFLQHIfUFR0SN5Ln n7r7fl1LAZ1lzI+hm6XLz+bdYeXPavKp/PLIfWqZXCdVCFgNF0gqmy2N2 ySbjlLxHhJPgiz38yRl6a4HQ+7zgWwXKPL7iMpz4J3Kx+9GyaaXTSLVHV NwjCR0F+0+qRqnGFzqKkmB7wjNeBksjxgN0edxqOCBu9qoOqqp+029B3d NUYx6zB9ffgMUJvvBmRcDNmCSxICNwE/mVUKD1O7ADC7vsOHz/XmWpx0X Q==; X-IronPort-AV: E=McAfee;i="6200,9189,10289"; a="254492896" X-IronPort-AV: E=Sophos;i="5.90,188,1643702400"; d="scan'208";a="254492896" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Mar 2022 10:51:21 -0700 X-IronPort-AV: E=Sophos;i="5.90,188,1643702400"; d="scan'208";a="550431106" Received: from jfbonin1-mobl6.amr.corp.intel.com (HELO rsridh2-mobl1.localdomain) ([10.255.92.163]) by fmsmga007-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Mar 2022 10:51:21 -0700 From: Ranjani Sridharan To: alsa-devel@alsa-project.org Subject: [PATCH 01/19] ASoC: SOF: set up scheduler widget before all other widgets in the pipeline Date: Thu, 17 Mar 2022 10:50:26 -0700 Message-Id: <20220317175044.1752400-2-ranjani.sridharan@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220317175044.1752400-1-ranjani.sridharan@linux.intel.com> References: <20220317175044.1752400-1-ranjani.sridharan@linux.intel.com> MIME-Version: 1.0 Cc: tiwai@suse.de, broonie@kernel.org, =?utf-8?q?P=C3=A9ter_Ujfalusi?= , Ranjani Sridharan , Pierre-Louis Bossart X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" For dynamic pipelines, We set up the DAI widget during BE DAI hw_params and this results in it getting set up before the scheduler widget for the pipeline it belongs to is set up. Move the scheduler widget set up into sof_widget_setup() to ensure that the scheduler widget is always the first widget in a pipeline to be set up and the last one to get freed after all the other widgets have been freed. Fixes: 5fcdbb2d45df ('ASoC: SOF: Add support for dynamic pipelines') Signed-off-by: Ranjani Sridharan Reviewed-by: Péter Ujfalusi Reviewed-by: Pierre-Louis Bossart --- sound/soc/sof/sof-audio.c | 82 +++++++++++++++++++++------------------ 1 file changed, 44 insertions(+), 38 deletions(-) diff --git a/sound/soc/sof/sof-audio.c b/sound/soc/sof/sof-audio.c index 683c290bb69a..cc0d647a2d0d 100644 --- a/sound/soc/sof/sof-audio.c +++ b/sound/soc/sof/sof-audio.c @@ -104,7 +104,7 @@ int sof_widget_free(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget) .id = swidget->comp_id, }; struct sof_ipc_reply reply; - int ret, ret1; + int ret, err; if (!swidget->private) return 0; @@ -136,31 +136,41 @@ int sof_widget_free(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget) } /* continue to disable core even if IPC fails */ - ret = sof_ipc_tx_message(sdev->ipc, ipc_free.hdr.cmd, &ipc_free, sizeof(ipc_free), + err = sof_ipc_tx_message(sdev->ipc, ipc_free.hdr.cmd, &ipc_free, sizeof(ipc_free), &reply, sizeof(reply)); - if (ret < 0) + if (err < 0) dev_err(sdev->dev, "error: failed to free widget %s\n", swidget->widget->name); /* * disable widget core. continue to route setup status and complete flag * even if this fails and return the appropriate error */ - ret1 = snd_sof_dsp_core_put(sdev, swidget->core); - if (ret1 < 0) { + ret = snd_sof_dsp_core_put(sdev, swidget->core); + if (ret < 0) { dev_err(sdev->dev, "error: failed to disable target core: %d for widget %s\n", swidget->core, swidget->widget->name); - if (!ret) - ret = ret1; + if (!err) + err = ret; } /* reset route setup status for all routes that contain this widget */ sof_reset_route_setup_status(sdev, swidget); swidget->complete = 0; - if (!ret) + /* + * free the scheduler widget (same as pipe_widget) associated with the current swidget. + * skip for static pipelines + */ + if (swidget->dynamic_pipeline_widget && swidget->id != snd_soc_dapm_scheduler) { + ret = sof_widget_free(sdev, swidget->pipe_widget); + if (ret < 0 && !err) + err = ret; + } + + if (!err) dev_dbg(sdev->dev, "widget %s freed\n", swidget->widget->name); - return ret; + return err; } EXPORT_SYMBOL(sof_widget_free); @@ -181,12 +191,32 @@ int sof_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget) if (++swidget->use_count > 1) return 0; + /* + * The scheduler widget for a pipeline is not part of the connected DAPM + * widget list and it needs to be set up before the widgets in the pipeline + * are set up. The use_count for the scheduler widget is incremented for every + * widget in a given pipeline to ensure that it is freed only after the last + * widget in the pipeline is freed. Skip setting up scheduler widget for static pipelines. + */ + if (swidget->dynamic_pipeline_widget && swidget->id != snd_soc_dapm_scheduler) { + if (!swidget->pipe_widget) { + dev_err(sdev->dev, "No scheduler widget set for %s\n", + swidget->widget->name); + ret = -EINVAL; + goto use_count_dec; + } + + ret = sof_widget_setup(sdev, swidget->pipe_widget); + if (ret < 0) + goto use_count_dec; + } + /* enable widget core */ ret = snd_sof_dsp_core_get(sdev, swidget->core); if (ret < 0) { dev_err(sdev->dev, "error: failed to enable target core for widget %s\n", swidget->widget->name); - goto use_count_dec; + goto pipe_widget_free; } switch (swidget->id) { @@ -257,6 +287,9 @@ int sof_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget) core_put: snd_sof_dsp_core_put(sdev, swidget->core); +pipe_widget_free: + if (swidget->id != snd_soc_dapm_scheduler) + sof_widget_free(sdev, swidget->pipe_widget); use_count_dec: swidget->use_count--; return ret; @@ -374,36 +407,14 @@ int sof_widget_list_setup(struct snd_sof_dev *sdev, struct snd_sof_pcm *spcm, in /* set up widgets in the list */ for_each_dapm_widgets(list, num_widgets, widget) { struct snd_sof_widget *swidget = widget->dobj.private; - struct snd_sof_widget *pipe_widget; if (!swidget) continue; - /* - * The scheduler widget for a pipeline is not part of the connected DAPM - * widget list and it needs to be set up before the widgets in the pipeline - * are set up. The use_count for the scheduler widget is incremented for every - * widget in a given pipeline to ensure that it is freed only after the last - * widget in the pipeline is freed. - */ - pipe_widget = swidget->pipe_widget; - if (!pipe_widget) { - dev_err(sdev->dev, "error: no pipeline widget found for %s\n", - swidget->widget->name); - ret = -EINVAL; - goto widget_free; - } - - ret = sof_widget_setup(sdev, pipe_widget); - if (ret < 0) - goto widget_free; - /* set up the widget */ ret = sof_widget_setup(sdev, swidget); - if (ret < 0) { - sof_widget_free(sdev, pipe_widget); + if (ret < 0) goto widget_free; - } } /* @@ -456,7 +467,6 @@ int sof_widget_list_setup(struct snd_sof_dev *sdev, struct snd_sof_pcm *spcm, in break; sof_widget_free(sdev, swidget); - sof_widget_free(sdev, swidget->pipe_widget); } return ret; @@ -490,10 +500,6 @@ int sof_widget_list_free(struct snd_sof_dev *sdev, struct snd_sof_pcm *spcm, int ret = sof_widget_free(sdev, swidget); if (ret < 0) ret1 = ret; - - ret = sof_widget_free(sdev, swidget->pipe_widget); - if (ret < 0) - ret1 = ret; } snd_soc_dapm_dai_free_widgets(&list); From patchwork Thu Mar 17 17:50:31 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Ranjani Sridharan X-Patchwork-Id: 552265 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 86864C433EF for ; Thu, 17 Mar 2022 17:54:02 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id CF9A018E2; Thu, 17 Mar 2022 18:53:10 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz CF9A018E2 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1647539640; bh=fHsyIITrqRUCS4qFa0kVAZRjYFat2lFNdC2Uyn3h9IE=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=tRqu2bMryvbjB/V6+4oHFmimJsQ2npxnfCmARsSnDPK551j3E4shuBx86JyxdrnVA yUhLX382ioRuuAMGQsco7qQIbt7lq+WT+3eHqn04gWHnPvO6XF51WGG1oBHSihek/0 A5SGDIaSEUL0JY/u01nmWfgvdr/sCPDwCxec1mLg= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 77869F80529; Thu, 17 Mar 2022 18:51:59 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 5431DF80526; Thu, 17 Mar 2022 18:51:55 +0100 (CET) Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 1E49FF802DF for ; Thu, 17 Mar 2022 18:51:47 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 1E49FF802DF Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="hFprFEBc" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1647539509; x=1679075509; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=fHsyIITrqRUCS4qFa0kVAZRjYFat2lFNdC2Uyn3h9IE=; b=hFprFEBc76umj9i4PItQ684bfULWpj/lTKf7MHiK8EEKGPwoZPXWF9sb mV6AAYC38q5XZAyjmlTRvmXKAoP3BouoA7fbqnf5Rl+/KlE76oQm1yTvN MOa1+GKjOMJopAINEfM/8rM1cGeFH3dyTHlDyV8HGU0F9fbZ9+f//lqrC 4HaVuE5DlKqC80h0lwM5tc3F4uOd4ZZQPvnrpl5Hw1ZTKmO31x6tnzAfI 0CYMbjnkULv5bZUIK0AyNSpOe41ZXhGBySrH8wfK3yLGmbrVh5BiH2OTr MrcBaC3DmgpFXveK8jYOddvpl0pJFjVIyz0ZnuUQVQfX7utXCtE2l/FEB A==; X-IronPort-AV: E=McAfee;i="6200,9189,10289"; a="254492908" X-IronPort-AV: E=Sophos;i="5.90,188,1643702400"; d="scan'208";a="254492908" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Mar 2022 10:51:22 -0700 X-IronPort-AV: E=Sophos;i="5.90,188,1643702400"; d="scan'208";a="550431125" Received: from jfbonin1-mobl6.amr.corp.intel.com (HELO rsridh2-mobl1.localdomain) ([10.255.92.163]) by fmsmga007-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Mar 2022 10:51:22 -0700 From: Ranjani Sridharan To: alsa-devel@alsa-project.org Subject: [PATCH 06/19] ASoC: SOF: Add volume_get/put IPC3 ops Date: Thu, 17 Mar 2022 10:50:31 -0700 Message-Id: <20220317175044.1752400-7-ranjani.sridharan@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220317175044.1752400-1-ranjani.sridharan@linux.intel.com> References: <20220317175044.1752400-1-ranjani.sridharan@linux.intel.com> MIME-Version: 1.0 Cc: tiwai@suse.de, broonie@kernel.org, =?utf-8?q?P=C3=A9ter_Ujfalusi?= , Ranjani Sridharan , Pierre-Louis Bossart X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" Define and set the volume_get/put control IPC ops for IPC3. Signed-off-by: Ranjani Sridharan Reviewed-by: Péter Ujfalusi Reviewed-by: Pierre-Louis Bossart --- sound/soc/sof/control.c | 64 +++++----------------- sound/soc/sof/ipc3-control.c | 100 +++++++++++++++++++++++++++++++++++ 2 files changed, 114 insertions(+), 50 deletions(-) diff --git a/sound/soc/sof/control.c b/sound/soc/sof/control.c index fb2311d880d3..9eb54b7024b3 100644 --- a/sound/soc/sof/control.c +++ b/sound/soc/sof/control.c @@ -45,26 +45,6 @@ static void update_mute_led(struct snd_sof_control *scontrol, #endif } -static inline u32 mixer_to_ipc(unsigned int value, u32 *volume_map, int size) -{ - if (value >= size) - return volume_map[size - 1]; - - return volume_map[value]; -} - -static inline u32 ipc_to_mixer(u32 value, u32 *volume_map, int size) -{ - int i; - - for (i = 0; i < size; i++) { - if (volume_map[i] >= value) - return i; - } - - return i - 1; -} - static void snd_sof_refresh_control(struct snd_sof_control *scontrol) { struct sof_ipc_ctrl_data *cdata = scontrol->ipc_control_data; @@ -85,7 +65,8 @@ static void snd_sof_refresh_control(struct snd_sof_control *scontrol) scontrol->comp_data_dirty = false; ret = snd_sof_ipc_set_get_comp_data(scontrol, false); if (ret < 0) { - dev_err(scomp->dev, "error: failed to get control data: %d\n", ret); + dev_err(scomp->dev, "Failed to get control data: %d\n", ret); + /* Set the flag to re-try next time to get the data */ scontrol->comp_data_dirty = true; } @@ -94,19 +75,14 @@ static void snd_sof_refresh_control(struct snd_sof_control *scontrol) int snd_sof_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct soc_mixer_control *sm = - (struct soc_mixer_control *)kcontrol->private_value; + struct soc_mixer_control *sm = (struct soc_mixer_control *)kcontrol->private_value; struct snd_sof_control *scontrol = sm->dobj.private; - struct sof_ipc_ctrl_data *cdata = scontrol->ipc_control_data; - unsigned int i, channels = scontrol->num_channels; + struct snd_soc_component *scomp = scontrol->scomp; + struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); + const struct sof_ipc_tplg_ops *tplg_ops = sdev->ipc->ops->tplg; - snd_sof_refresh_control(scontrol); - - /* read back each channel */ - for (i = 0; i < channels; i++) - ucontrol->value.integer.value[i] = - ipc_to_mixer(cdata->chanv[i].value, - scontrol->volume_table, sm->max + 1); + if (tplg_ops->control->volume_get) + return tplg_ops->control->volume_get(scontrol, ucontrol); return 0; } @@ -114,28 +90,16 @@ int snd_sof_volume_get(struct snd_kcontrol *kcontrol, int snd_sof_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct soc_mixer_control *sm = - (struct soc_mixer_control *)kcontrol->private_value; + struct soc_mixer_control *sm = (struct soc_mixer_control *)kcontrol->private_value; struct snd_sof_control *scontrol = sm->dobj.private; struct snd_soc_component *scomp = scontrol->scomp; - struct sof_ipc_ctrl_data *cdata = scontrol->ipc_control_data; - unsigned int i, channels = scontrol->num_channels; - bool change = false; - u32 value; + struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); + const struct sof_ipc_tplg_ops *tplg_ops = sdev->ipc->ops->tplg; - /* update each channel */ - for (i = 0; i < channels; i++) { - value = mixer_to_ipc(ucontrol->value.integer.value[i], - scontrol->volume_table, sm->max + 1); - change = change || (value != cdata->chanv[i].value); - cdata->chanv[i].channel = i; - cdata->chanv[i].value = value; - } + if (tplg_ops->control->volume_put) + return tplg_ops->control->volume_put(scontrol, ucontrol); - /* notify DSP of mixer updates */ - if (pm_runtime_active(scomp->dev)) - snd_sof_ipc_set_get_comp_data(scontrol, true); - return change; + return false; } int snd_sof_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) diff --git a/sound/soc/sof/ipc3-control.c b/sound/soc/sof/ipc3-control.c index d4086e805c18..12aeb3ae4e52 100644 --- a/sound/soc/sof/ipc3-control.c +++ b/sound/soc/sof/ipc3-control.c @@ -11,6 +11,104 @@ #include "sof-audio.h" #include "ipc3-ops.h" +static inline u32 mixer_to_ipc(unsigned int value, u32 *volume_map, int size) +{ + if (value >= size) + return volume_map[size - 1]; + + return volume_map[value]; +} + +static inline u32 ipc_to_mixer(u32 value, u32 *volume_map, int size) +{ + int i; + + for (i = 0; i < size; i++) { + if (volume_map[i] >= value) + return i; + } + + return i - 1; +} + +static void snd_sof_refresh_control(struct snd_sof_control *scontrol) +{ + struct sof_ipc_ctrl_data *cdata = scontrol->ipc_control_data; + struct snd_soc_component *scomp = scontrol->scomp; + int ret; + + if (!scontrol->comp_data_dirty) + return; + + if (!pm_runtime_active(scomp->dev)) + return; + + /* set the ABI header values */ + cdata->data->magic = SOF_ABI_MAGIC; + cdata->data->abi = SOF_ABI_VERSION; + + /* refresh the component data from DSP */ + scontrol->comp_data_dirty = false; + ret = snd_sof_ipc_set_get_comp_data(scontrol, false); + if (ret < 0) { + dev_err(scomp->dev, "Failed to get control data: %d\n", ret); + + /* Set the flag to re-try next time to get the data */ + scontrol->comp_data_dirty = true; + } +} + +static int sof_ipc3_volume_get(struct snd_sof_control *scontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct sof_ipc_ctrl_data *cdata = scontrol->ipc_control_data; + unsigned int channels = scontrol->num_channels; + unsigned int i; + + snd_sof_refresh_control(scontrol); + + /* read back each channel */ + for (i = 0; i < channels; i++) + ucontrol->value.integer.value[i] = ipc_to_mixer(cdata->chanv[i].value, + scontrol->volume_table, + scontrol->max + 1); + + return 0; +} + +static bool sof_ipc3_volume_put(struct snd_sof_control *scontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct sof_ipc_ctrl_data *cdata = scontrol->ipc_control_data; + struct snd_soc_component *scomp = scontrol->scomp; + unsigned int channels = scontrol->num_channels; + unsigned int i; + bool change = false; + + /* update each channel */ + for (i = 0; i < channels; i++) { + u32 value = mixer_to_ipc(ucontrol->value.integer.value[i], + scontrol->volume_table, scontrol->max + 1); + + change = change || (value != cdata->chanv[i].value); + cdata->chanv[i].channel = i; + cdata->chanv[i].value = value; + } + + /* notify DSP of mixer updates */ + if (pm_runtime_active(scomp->dev)) { + int ret = snd_sof_ipc_set_get_comp_data(scontrol, true); + + if (ret < 0) { + dev_err(scomp->dev, "Failed to set mixer updates for %s\n", + scontrol->name); + return false; + } + } + + return change; +} + static void snd_sof_update_control(struct snd_sof_control *scontrol, struct sof_ipc_ctrl_data *cdata) { @@ -152,5 +250,7 @@ static void sof_ipc3_control_update(struct snd_sof_dev *sdev, void *ipc_control_ } const struct sof_ipc_tplg_control_ops tplg_ipc3_control_ops = { + .volume_put = sof_ipc3_volume_put, + .volume_get = sof_ipc3_volume_get, .update = sof_ipc3_control_update, }; From patchwork Thu Mar 17 17:50:33 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Ranjani Sridharan X-Patchwork-Id: 552264 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id C85A1C433EF for ; Thu, 17 Mar 2022 17:54:36 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id E814B18BD; Thu, 17 Mar 2022 18:53:44 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz E814B18BD DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1647539675; bh=icr7OkwnHEwr801hagV2X9F7RXGHcVlRXX/SRsTK6Rc=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=bkUB0J/Y5NgeCT5wvfFuOgn/iZ8dpU1VMm9ZgOIoQxJX/SEFlYgeSlUsU9xpfHT3K cnORGRNqb9berauH/24zBHh9TmExI9gZQ5jIOciEkLLwDFQlWmyjd290GvaZE0Tw3I JffeUwXuh6jghaatG6tcyXfCgUdca+wTn3mm9CRg= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 582BFF80519; Thu, 17 Mar 2022 18:52:10 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 653C0F80526; Thu, 17 Mar 2022 18:51:57 +0100 (CET) Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 209A9F8020D for ; Thu, 17 Mar 2022 18:51:49 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 209A9F8020D Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="UxG59dZc" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1647539511; x=1679075511; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=icr7OkwnHEwr801hagV2X9F7RXGHcVlRXX/SRsTK6Rc=; b=UxG59dZcrpivfAxkrXKU4Rpzw3Pd08Bc0TKpkRZkZx6i8w0GxTcAofgP OBN3Ts6D9osYBa1TICW3ueVknmEGVXGU/2EcCOfz+JZqZW2rEcpbplI4C uh1k+GCAj/awzzH03p3NzRT07IczvLyUb6eCZIj6Ycvhf9LRzavxDKdT9 7zYZeAj9EMhkjtJzLwgBmcsXDfARzEP678iBjo5GJK6452Lf8igmN7sDD 6uuZ9WkmniZe1I4GEjz5sSaB7QpoQBy7xkFKKkGx3KLpP29fx1+pQXiW6 b2FfBvYehysndSXtzbJk9Vbz0rGvOkF2VJlP1oZVRYg5R6LasKSWqS9tJ Q==; X-IronPort-AV: E=McAfee;i="6200,9189,10289"; a="254492913" X-IronPort-AV: E=Sophos;i="5.90,188,1643702400"; d="scan'208";a="254492913" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Mar 2022 10:51:22 -0700 X-IronPort-AV: E=Sophos;i="5.90,188,1643702400"; d="scan'208";a="550431129" Received: from jfbonin1-mobl6.amr.corp.intel.com (HELO rsridh2-mobl1.localdomain) ([10.255.92.163]) by fmsmga007-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Mar 2022 10:51:22 -0700 From: Ranjani Sridharan To: alsa-devel@alsa-project.org Subject: [PATCH 08/19] ASoC: SOF: Add enum_get/put control ops for IPC3 Date: Thu, 17 Mar 2022 10:50:33 -0700 Message-Id: <20220317175044.1752400-9-ranjani.sridharan@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220317175044.1752400-1-ranjani.sridharan@linux.intel.com> References: <20220317175044.1752400-1-ranjani.sridharan@linux.intel.com> MIME-Version: 1.0 Cc: tiwai@suse.de, broonie@kernel.org, =?utf-8?q?P=C3=A9ter_Ujfalusi?= , Ranjani Sridharan , Pierre-Louis Bossart X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" Define and set the enum_get/put control IPC ops for IPC3. Signed-off-by: Ranjani Sridharan Reviewed-by: Péter Ujfalusi Reviewed-by: Pierre-Louis Bossart --- sound/soc/sof/control.c | 39 +++++++++------------------- sound/soc/sof/ipc3-control.c | 50 ++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 27 deletions(-) diff --git a/sound/soc/sof/control.c b/sound/soc/sof/control.c index f9f8bd37b480..499d426c5d38 100644 --- a/sound/soc/sof/control.c +++ b/sound/soc/sof/control.c @@ -160,17 +160,14 @@ int snd_sof_switch_put(struct snd_kcontrol *kcontrol, int snd_sof_enum_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct soc_enum *se = - (struct soc_enum *)kcontrol->private_value; + struct soc_enum *se = (struct soc_enum *)kcontrol->private_value; struct snd_sof_control *scontrol = se->dobj.private; - struct sof_ipc_ctrl_data *cdata = scontrol->ipc_control_data; - unsigned int i, channels = scontrol->num_channels; - - snd_sof_refresh_control(scontrol); + struct snd_soc_component *scomp = scontrol->scomp; + struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); + const struct sof_ipc_tplg_ops *tplg_ops = sdev->ipc->ops->tplg; - /* read back each channel */ - for (i = 0; i < channels; i++) - ucontrol->value.enumerated.item[i] = cdata->chanv[i].value; + if (tplg_ops->control->enum_get) + return tplg_ops->control->enum_get(scontrol, ucontrol); return 0; } @@ -178,28 +175,16 @@ int snd_sof_enum_get(struct snd_kcontrol *kcontrol, int snd_sof_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct soc_enum *se = - (struct soc_enum *)kcontrol->private_value; + struct soc_enum *se = (struct soc_enum *)kcontrol->private_value; struct snd_sof_control *scontrol = se->dobj.private; struct snd_soc_component *scomp = scontrol->scomp; - struct sof_ipc_ctrl_data *cdata = scontrol->ipc_control_data; - unsigned int i, channels = scontrol->num_channels; - bool change = false; - u32 value; - - /* update each channel */ - for (i = 0; i < channels; i++) { - value = ucontrol->value.enumerated.item[i]; - change = change || (value != cdata->chanv[i].value); - cdata->chanv[i].channel = i; - cdata->chanv[i].value = value; - } + struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); + const struct sof_ipc_tplg_ops *tplg_ops = sdev->ipc->ops->tplg; - /* notify DSP of enum updates */ - if (pm_runtime_active(scomp->dev)) - snd_sof_ipc_set_get_comp_data(scontrol, true); + if (tplg_ops->control->enum_put) + return tplg_ops->control->enum_put(scontrol, ucontrol); - return change; + return false; } int snd_sof_bytes_get(struct snd_kcontrol *kcontrol, diff --git a/sound/soc/sof/ipc3-control.c b/sound/soc/sof/ipc3-control.c index ba9cde011b5a..03948f8f7eb0 100644 --- a/sound/soc/sof/ipc3-control.c +++ b/sound/soc/sof/ipc3-control.c @@ -157,6 +157,54 @@ static bool sof_ipc3_switch_put(struct snd_sof_control *scontrol, return change; } +static int sof_ipc3_enum_get(struct snd_sof_control *scontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct sof_ipc_ctrl_data *cdata = scontrol->ipc_control_data; + unsigned int channels = scontrol->num_channels; + unsigned int i; + + snd_sof_refresh_control(scontrol); + + /* read back each channel */ + for (i = 0; i < channels; i++) + ucontrol->value.enumerated.item[i] = cdata->chanv[i].value; + + return 0; +} + +static bool sof_ipc3_enum_put(struct snd_sof_control *scontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct sof_ipc_ctrl_data *cdata = scontrol->ipc_control_data; + struct snd_soc_component *scomp = scontrol->scomp; + unsigned int channels = scontrol->num_channels; + unsigned int i; + bool change = false; + u32 value; + + /* update each channel */ + for (i = 0; i < channels; i++) { + value = ucontrol->value.enumerated.item[i]; + change = change || (value != cdata->chanv[i].value); + cdata->chanv[i].channel = i; + cdata->chanv[i].value = value; + } + + /* notify DSP of enum updates */ + if (pm_runtime_active(scomp->dev)) { + int ret = snd_sof_ipc_set_get_comp_data(scontrol, true); + + if (ret < 0) { + dev_err(scomp->dev, "Failed to set enum updates for %s\n", + scontrol->name); + return false; + } + } + + return change; +} + static void snd_sof_update_control(struct snd_sof_control *scontrol, struct sof_ipc_ctrl_data *cdata) { @@ -302,5 +350,7 @@ const struct sof_ipc_tplg_control_ops tplg_ipc3_control_ops = { .volume_get = sof_ipc3_volume_get, .switch_put = sof_ipc3_switch_put, .switch_get = sof_ipc3_switch_get, + .enum_put = sof_ipc3_enum_put, + .enum_get = sof_ipc3_enum_get, .update = sof_ipc3_control_update, }; From patchwork Thu Mar 17 17:50:34 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Ranjani Sridharan X-Patchwork-Id: 552263 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 83A81C433EF for ; Thu, 17 Mar 2022 17:55:10 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id B14A518E5; Thu, 17 Mar 2022 18:54:18 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz B14A518E5 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1647539708; bh=//31PYFIAylqF9BN8lgzTSi6M1KjhCNv4fekcap99XU=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=kwAo71GQLZdDuDGhBp9M7XGqTvgFFn8Abv2JK8APHrhLnnvnS1BQJpQWS2As1MWMG QAarvgxEb1PCYSsGif81YzuvMGnP8o6B8zsYsYdSm88R+TlbrI64ZDw5G9BhnsegO7 YJoeqLD2LnbUaOCfyEivpCnTGQhArutJqOYMTBzE= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 59A1DF8052E; Thu, 17 Mar 2022 18:52:12 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id C7284F80534; Thu, 17 Mar 2022 18:51:59 +0100 (CET) Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 70ED7F80516 for ; Thu, 17 Mar 2022 18:51:51 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 70ED7F80516 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="S08ff3/+" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1647539512; x=1679075512; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=//31PYFIAylqF9BN8lgzTSi6M1KjhCNv4fekcap99XU=; b=S08ff3/+JMxFJCYL3MvyTcm6AJpJHLlKwvdhkg5IwqJko59Mh+ShWzLS UpAI1NJyXWLZemNITtotC3hwGFTWFqYu9Znb3RRdPCiXy2ig+cYus9Xce 7vrGFnUuOVS9T2fMXaLVAg+9USyK3nI3uVdSZqeRWc/sliWgiE+An2w0f 490DeW0AhGzM1a2pQo+NxTWm8/vXUiOei7LrnEiSPUk8i4y/l7Iew9XwX E7Tja8m67Uy+cx6msPdTQGCEbNyF+QrmpQqHfoUOksBvSwTxt4RnLlQBv DfZoOHRi9MWcxohA5uGMIyIfVwiKm8jG5C1/pI60xRXtAKbwIoTSMnQ6m A==; X-IronPort-AV: E=McAfee;i="6200,9189,10289"; a="254492916" X-IronPort-AV: E=Sophos;i="5.90,188,1643702400"; d="scan'208";a="254492916" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Mar 2022 10:51:22 -0700 X-IronPort-AV: E=Sophos;i="5.90,188,1643702400"; d="scan'208";a="550431134" Received: from jfbonin1-mobl6.amr.corp.intel.com (HELO rsridh2-mobl1.localdomain) ([10.255.92.163]) by fmsmga007-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Mar 2022 10:51:22 -0700 From: Ranjani Sridharan To: alsa-devel@alsa-project.org Subject: [PATCH 09/19] ASoC: SOF: Add bytes_get/put control IPC ops for IPC3 Date: Thu, 17 Mar 2022 10:50:34 -0700 Message-Id: <20220317175044.1752400-10-ranjani.sridharan@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220317175044.1752400-1-ranjani.sridharan@linux.intel.com> References: <20220317175044.1752400-1-ranjani.sridharan@linux.intel.com> MIME-Version: 1.0 Cc: tiwai@suse.de, broonie@kernel.org, =?utf-8?q?P=C3=A9ter_Ujfalusi?= , Ranjani Sridharan , Pierre-Louis Bossart X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" Define and set the bytes_get/put IPC control ops for IPC3. Signed-off-by: Ranjani Sridharan Reviewed-by: Péter Ujfalusi Reviewed-by: Pierre-Louis Bossart --- sound/soc/sof/control.c | 64 ++++++---------------------------- sound/soc/sof/ipc3-control.c | 67 ++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+), 54 deletions(-) diff --git a/sound/soc/sof/control.c b/sound/soc/sof/control.c index 499d426c5d38..2a4997e1cd1e 100644 --- a/sound/soc/sof/control.c +++ b/sound/soc/sof/control.c @@ -190,35 +190,14 @@ int snd_sof_enum_put(struct snd_kcontrol *kcontrol, int snd_sof_bytes_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct soc_bytes_ext *be = - (struct soc_bytes_ext *)kcontrol->private_value; + struct soc_bytes_ext *be = (struct soc_bytes_ext *)kcontrol->private_value; struct snd_sof_control *scontrol = be->dobj.private; struct snd_soc_component *scomp = scontrol->scomp; - struct sof_ipc_ctrl_data *cdata = scontrol->ipc_control_data; - struct sof_abi_hdr *data = cdata->data; - size_t size; - - snd_sof_refresh_control(scontrol); - - if (be->max > sizeof(ucontrol->value.bytes.data)) { - dev_err_ratelimited(scomp->dev, - "error: data max %d exceeds ucontrol data array size\n", - be->max); - return -EINVAL; - } - - /* be->max has been verified to be >= sizeof(struct sof_abi_hdr) */ - if (data->size > be->max - sizeof(*data)) { - dev_err_ratelimited(scomp->dev, - "error: %u bytes of control data is invalid, max is %zu\n", - data->size, be->max - sizeof(*data)); - return -EINVAL; - } - - size = data->size + sizeof(*data); + struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); + const struct sof_ipc_tplg_ops *tplg_ops = sdev->ipc->ops->tplg; - /* copy back to kcontrol */ - memcpy(ucontrol->value.bytes.data, data, size); + if (tplg_ops->control->bytes_get) + return tplg_ops->control->bytes_get(scontrol, ucontrol); return 0; } @@ -226,37 +205,14 @@ int snd_sof_bytes_get(struct snd_kcontrol *kcontrol, int snd_sof_bytes_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct soc_bytes_ext *be = - (struct soc_bytes_ext *)kcontrol->private_value; + struct soc_bytes_ext *be = (struct soc_bytes_ext *)kcontrol->private_value; struct snd_sof_control *scontrol = be->dobj.private; struct snd_soc_component *scomp = scontrol->scomp; - struct sof_ipc_ctrl_data *cdata = scontrol->ipc_control_data; - struct sof_abi_hdr *data = cdata->data; - size_t size; - - if (be->max > sizeof(ucontrol->value.bytes.data)) { - dev_err_ratelimited(scomp->dev, - "error: data max %d exceeds ucontrol data array size\n", - be->max); - return -EINVAL; - } - - /* be->max has been verified to be >= sizeof(struct sof_abi_hdr) */ - if (data->size > be->max - sizeof(*data)) { - dev_err_ratelimited(scomp->dev, - "error: data size too big %u bytes max is %zu\n", - data->size, be->max - sizeof(*data)); - return -EINVAL; - } - - size = data->size + sizeof(*data); - - /* copy from kcontrol */ - memcpy(data, ucontrol->value.bytes.data, size); + struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); + const struct sof_ipc_tplg_ops *tplg_ops = sdev->ipc->ops->tplg; - /* notify DSP of byte control updates */ - if (pm_runtime_active(scomp->dev)) - snd_sof_ipc_set_get_comp_data(scontrol, true); + if (tplg_ops->control->bytes_put) + return tplg_ops->control->bytes_put(scontrol, ucontrol); return 0; } diff --git a/sound/soc/sof/ipc3-control.c b/sound/soc/sof/ipc3-control.c index 03948f8f7eb0..df8e4df9663d 100644 --- a/sound/soc/sof/ipc3-control.c +++ b/sound/soc/sof/ipc3-control.c @@ -205,6 +205,71 @@ static bool sof_ipc3_enum_put(struct snd_sof_control *scontrol, return change; } +static int sof_ipc3_bytes_get(struct snd_sof_control *scontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct sof_ipc_ctrl_data *cdata = scontrol->ipc_control_data; + struct snd_soc_component *scomp = scontrol->scomp; + struct sof_abi_hdr *data = cdata->data; + size_t size; + + snd_sof_refresh_control(scontrol); + + if (scontrol->max_size > sizeof(ucontrol->value.bytes.data)) { + dev_err_ratelimited(scomp->dev, "data max %zu exceeds ucontrol data array size\n", + scontrol->max_size); + return -EINVAL; + } + + /* be->max has been verified to be >= sizeof(struct sof_abi_hdr) */ + if (data->size > scontrol->max_size - sizeof(*data)) { + dev_err_ratelimited(scomp->dev, + "%u bytes of control data is invalid, max is %zu\n", + data->size, scontrol->max_size - sizeof(*data)); + return -EINVAL; + } + + size = data->size + sizeof(*data); + + /* copy back to kcontrol */ + memcpy(ucontrol->value.bytes.data, data, size); + + return 0; +} + +static int sof_ipc3_bytes_put(struct snd_sof_control *scontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct sof_ipc_ctrl_data *cdata = scontrol->ipc_control_data; + struct snd_soc_component *scomp = scontrol->scomp; + struct sof_abi_hdr *data = cdata->data; + size_t size; + + if (scontrol->max_size > sizeof(ucontrol->value.bytes.data)) { + dev_err_ratelimited(scomp->dev, "data max %zu exceeds ucontrol data array size\n", + scontrol->max_size); + return -EINVAL; + } + + /* scontrol->max_size has been verified to be >= sizeof(struct sof_abi_hdr) */ + if (data->size > scontrol->max_size - sizeof(*data)) { + dev_err_ratelimited(scomp->dev, "data size too big %u bytes max is %zu\n", + data->size, scontrol->max_size - sizeof(*data)); + return -EINVAL; + } + + size = data->size + sizeof(*data); + + /* copy from kcontrol */ + memcpy(data, ucontrol->value.bytes.data, size); + + /* notify DSP of byte control updates */ + if (pm_runtime_active(scomp->dev)) + return snd_sof_ipc_set_get_comp_data(scontrol, true); + + return 0; +} + static void snd_sof_update_control(struct snd_sof_control *scontrol, struct sof_ipc_ctrl_data *cdata) { @@ -352,5 +417,7 @@ const struct sof_ipc_tplg_control_ops tplg_ipc3_control_ops = { .switch_get = sof_ipc3_switch_get, .enum_put = sof_ipc3_enum_put, .enum_get = sof_ipc3_enum_get, + .bytes_put = sof_ipc3_bytes_put, + .bytes_get = sof_ipc3_bytes_get, .update = sof_ipc3_control_update, }; From patchwork Thu Mar 17 17:50:35 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Ranjani Sridharan X-Patchwork-Id: 552261 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id C062DC433EF for ; Thu, 17 Mar 2022 17:56:12 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 0C64617F1; Thu, 17 Mar 2022 18:55:21 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 0C64617F1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1647539771; bh=s54QIOYxLYpwYIrccYCban+d46ntW9dfhPYNkjuOt28=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=BygShfO/Fpq4qipndOHstSUIqVoI3fpuFCysmNtC/E6FPPiiuAnFm97yLZ/9Q3OSi FUKLuo7JQ5eifWttElLFBK4up2nd+C4C0D9XPSQTDOnkbyorgSJbdb3W2hl55M1hoR H2Le54R3uad2cX/LHFNCUOcCYFWLHlQK0skgaS8c= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id F3133F80551; Thu, 17 Mar 2022 18:52:14 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 2B752F8023A; Thu, 17 Mar 2022 18:52:06 +0100 (CET) Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id DEC97F8023A for ; Thu, 17 Mar 2022 18:51:53 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz DEC97F8023A Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="hSYyJpIU" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1647539515; x=1679075515; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=s54QIOYxLYpwYIrccYCban+d46ntW9dfhPYNkjuOt28=; b=hSYyJpIUJ/sK2rGxsZkQ9kA/Qopt2MyP41rO3cCJ4tlKz+Ca+yOAUHPq G6XxmSwdzk+cBWFLOMMIWlG8kv+rEOH3Nm720fwA8SCpxbQBzA0pbhuWS BpKdmggGbsTe/NGB036d/kjB/MeiRDTy8KgrNCyjlEOyO/mIjdY1dyFsS g84iToAbcys/OpuS0J2tHyINQSyBOECN2J833/1GuODkcizLVNiLngNJy kCshb3RwAwMbEFQgGpKfHk95k7NG7o8W1EV1SFINEm+nQzukqCtdFfOPN Rs/U1tf3qzB3sMCN2zXIgVK2mkT3MlCaGif+l9DFGj/gNBDkvlN8mqAYX Q==; X-IronPort-AV: E=McAfee;i="6200,9189,10289"; a="254492918" X-IronPort-AV: E=Sophos;i="5.90,188,1643702400"; d="scan'208";a="254492918" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Mar 2022 10:51:23 -0700 X-IronPort-AV: E=Sophos;i="5.90,188,1643702400"; d="scan'208";a="550431139" Received: from jfbonin1-mobl6.amr.corp.intel.com (HELO rsridh2-mobl1.localdomain) ([10.255.92.163]) by fmsmga007-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Mar 2022 10:51:22 -0700 From: Ranjani Sridharan To: alsa-devel@alsa-project.org Subject: [PATCH 10/19] ASoC: SOF: Add bytes_ext control IPC ops for IPC3 Date: Thu, 17 Mar 2022 10:50:35 -0700 Message-Id: <20220317175044.1752400-11-ranjani.sridharan@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220317175044.1752400-1-ranjani.sridharan@linux.intel.com> References: <20220317175044.1752400-1-ranjani.sridharan@linux.intel.com> MIME-Version: 1.0 Cc: tiwai@suse.de, broonie@kernel.org, =?utf-8?q?P=C3=A9ter_Ujfalusi?= , Ranjani Sridharan , Pierre-Louis Bossart X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" Define and set the get/put/volatile_get control IPC ops for byte controls for IPC3. Signed-off-by: Ranjani Sridharan Reviewed-by: Péter Ujfalusi Reviewed-by: Pierre-Louis Bossart --- sound/soc/sof/control.c | 197 +++-------------------------------- sound/soc/sof/ipc3-control.c | 171 ++++++++++++++++++++++++++++++ 2 files changed, 188 insertions(+), 180 deletions(-) diff --git a/sound/soc/sof/control.c b/sound/soc/sof/control.c index 2a4997e1cd1e..de1778c4002b 100644 --- a/sound/soc/sof/control.c +++ b/sound/soc/sof/control.c @@ -45,33 +45,6 @@ static void update_mute_led(struct snd_sof_control *scontrol, #endif } -static void snd_sof_refresh_control(struct snd_sof_control *scontrol) -{ - struct sof_ipc_ctrl_data *cdata = scontrol->ipc_control_data; - struct snd_soc_component *scomp = scontrol->scomp; - int ret; - - if (!scontrol->comp_data_dirty) - return; - - if (!pm_runtime_active(scomp->dev)) - return; - - /* set the ABI header values */ - cdata->data->magic = SOF_ABI_MAGIC; - cdata->data->abi = SOF_ABI_VERSION; - - /* refresh the component data from DSP */ - scontrol->comp_data_dirty = false; - ret = snd_sof_ipc_set_get_comp_data(scontrol, false); - if (ret < 0) { - dev_err(scomp->dev, "Failed to get control data: %d\n", ret); - - /* Set the flag to re-try next time to get the data */ - scontrol->comp_data_dirty = true; - } -} - int snd_sof_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -221,74 +194,18 @@ int snd_sof_bytes_ext_put(struct snd_kcontrol *kcontrol, const unsigned int __user *binary_data, unsigned int size) { - struct soc_bytes_ext *be = - (struct soc_bytes_ext *)kcontrol->private_value; + struct soc_bytes_ext *be = (struct soc_bytes_ext *)kcontrol->private_value; struct snd_sof_control *scontrol = be->dobj.private; struct snd_soc_component *scomp = scontrol->scomp; - struct sof_ipc_ctrl_data *cdata = scontrol->ipc_control_data; - struct snd_ctl_tlv header; - const struct snd_ctl_tlv __user *tlvd = - (const struct snd_ctl_tlv __user *)binary_data; + struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); + const struct sof_ipc_tplg_ops *tplg_ops = sdev->ipc->ops->tplg; /* make sure we have at least a header */ if (size < sizeof(struct snd_ctl_tlv)) return -EINVAL; - /* - * The beginning of bytes data contains a header from where - * the length (as bytes) is needed to know the correct copy - * length of data from tlvd->tlv. - */ - if (copy_from_user(&header, tlvd, sizeof(struct snd_ctl_tlv))) - return -EFAULT; - - /* make sure TLV info is consistent */ - if (header.length + sizeof(struct snd_ctl_tlv) > size) { - dev_err_ratelimited(scomp->dev, "error: inconsistent TLV, data %d + header %zu > %d\n", - header.length, sizeof(struct snd_ctl_tlv), size); - return -EINVAL; - } - - /* be->max is coming from topology */ - if (header.length > be->max) { - dev_err_ratelimited(scomp->dev, "error: Bytes data size %d exceeds max %d.\n", - header.length, be->max); - return -EINVAL; - } - - /* Check that header id matches the command */ - if (header.numid != cdata->cmd) { - dev_err_ratelimited(scomp->dev, - "error: incorrect numid %d\n", - header.numid); - return -EINVAL; - } - - if (copy_from_user(cdata->data, tlvd->tlv, header.length)) - return -EFAULT; - - if (cdata->data->magic != SOF_ABI_MAGIC) { - dev_err_ratelimited(scomp->dev, - "error: Wrong ABI magic 0x%08x.\n", - cdata->data->magic); - return -EINVAL; - } - - if (SOF_ABI_VERSION_INCOMPATIBLE(SOF_ABI_VERSION, cdata->data->abi)) { - dev_err_ratelimited(scomp->dev, "error: Incompatible ABI version 0x%08x.\n", - cdata->data->abi); - return -EINVAL; - } - - /* be->max has been verified to be >= sizeof(struct sof_abi_hdr) */ - if (cdata->data->size > be->max - sizeof(struct sof_abi_hdr)) { - dev_err_ratelimited(scomp->dev, "error: Mismatch in ABI data size (truncated?).\n"); - return -EINVAL; - } - - /* notify DSP of byte control updates */ - if (pm_runtime_active(scomp->dev)) - snd_sof_ipc_set_get_comp_data(scontrol, true); + if (tplg_ops->control->bytes_ext_put) + return tplg_ops->control->bytes_ext_put(scontrol, binary_data, size); return 0; } @@ -299,67 +216,24 @@ int snd_sof_bytes_ext_volatile_get(struct snd_kcontrol *kcontrol, unsigned int _ struct soc_bytes_ext *be = (struct soc_bytes_ext *)kcontrol->private_value; struct snd_sof_control *scontrol = be->dobj.private; struct snd_soc_component *scomp = scontrol->scomp; - struct sof_ipc_ctrl_data *cdata = scontrol->ipc_control_data; - struct snd_ctl_tlv header; - struct snd_ctl_tlv __user *tlvd = (struct snd_ctl_tlv __user *)binary_data; - size_t data_size; - int ret; - int err; - - /* - * Decrement the limit by ext bytes header size to - * ensure the user space buffer is not exceeded. - */ - if (size < sizeof(struct snd_ctl_tlv)) - return -ENOSPC; - size -= sizeof(struct snd_ctl_tlv); + struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); + const struct sof_ipc_tplg_ops *tplg_ops = sdev->ipc->ops->tplg; + int ret, err; ret = pm_runtime_get_sync(scomp->dev); if (ret < 0 && ret != -EACCES) { - dev_err_ratelimited(scomp->dev, "error: bytes_ext get failed to resume %d\n", ret); + dev_err_ratelimited(scomp->dev, "%s: failed to resume %d\n", __func__, ret); pm_runtime_put_noidle(scomp->dev); return ret; } - /* set the ABI header values */ - cdata->data->magic = SOF_ABI_MAGIC; - cdata->data->abi = SOF_ABI_VERSION; - /* get all the component data from DSP */ - ret = snd_sof_ipc_set_get_comp_data(scontrol, false); - if (ret < 0) - goto out; - - /* check data size doesn't exceed max coming from topology */ - if (cdata->data->size > be->max - sizeof(struct sof_abi_hdr)) { - dev_err_ratelimited(scomp->dev, "error: user data size %d exceeds max size %zu.\n", - cdata->data->size, - be->max - sizeof(struct sof_abi_hdr)); - ret = -EINVAL; - goto out; - } - - data_size = cdata->data->size + sizeof(struct sof_abi_hdr); + if (tplg_ops->control->bytes_ext_volatile_get) + ret = tplg_ops->control->bytes_ext_volatile_get(scontrol, binary_data, size); - /* make sure we don't exceed size provided by user space for data */ - if (data_size > size) { - ret = -ENOSPC; - goto out; - } - - header.numid = cdata->cmd; - header.length = data_size; - if (copy_to_user(tlvd, &header, sizeof(struct snd_ctl_tlv))) { - ret = -EFAULT; - goto out; - } - - if (copy_to_user(tlvd->tlv, cdata->data, data_size)) - ret = -EFAULT; -out: pm_runtime_mark_last_busy(scomp->dev); err = pm_runtime_put_autosuspend(scomp->dev); if (err < 0) - dev_err_ratelimited(scomp->dev, "error: bytes_ext get failed to idle %d\n", err); + dev_err_ratelimited(scomp->dev, "%s: failed to idle %d\n", __func__, err); return ret; } @@ -368,51 +242,14 @@ int snd_sof_bytes_ext_get(struct snd_kcontrol *kcontrol, unsigned int __user *binary_data, unsigned int size) { - struct soc_bytes_ext *be = - (struct soc_bytes_ext *)kcontrol->private_value; + struct soc_bytes_ext *be = (struct soc_bytes_ext *)kcontrol->private_value; struct snd_sof_control *scontrol = be->dobj.private; struct snd_soc_component *scomp = scontrol->scomp; - struct sof_ipc_ctrl_data *cdata = scontrol->ipc_control_data; - struct snd_ctl_tlv header; - struct snd_ctl_tlv __user *tlvd = - (struct snd_ctl_tlv __user *)binary_data; - size_t data_size; - - snd_sof_refresh_control(scontrol); - - /* - * Decrement the limit by ext bytes header size to - * ensure the user space buffer is not exceeded. - */ - if (size < sizeof(struct snd_ctl_tlv)) - return -ENOSPC; - size -= sizeof(struct snd_ctl_tlv); - - /* set the ABI header values */ - cdata->data->magic = SOF_ABI_MAGIC; - cdata->data->abi = SOF_ABI_VERSION; - - /* check data size doesn't exceed max coming from topology */ - if (cdata->data->size > be->max - sizeof(struct sof_abi_hdr)) { - dev_err_ratelimited(scomp->dev, "error: user data size %d exceeds max size %zu.\n", - cdata->data->size, - be->max - sizeof(struct sof_abi_hdr)); - return -EINVAL; - } - - data_size = cdata->data->size + sizeof(struct sof_abi_hdr); - - /* make sure we don't exceed size provided by user space for data */ - if (data_size > size) - return -ENOSPC; - - header.numid = cdata->cmd; - header.length = data_size; - if (copy_to_user(tlvd, &header, sizeof(struct snd_ctl_tlv))) - return -EFAULT; + struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); + const struct sof_ipc_tplg_ops *tplg_ops = sdev->ipc->ops->tplg; - if (copy_to_user(tlvd->tlv, cdata->data, data_size)) - return -EFAULT; + if (tplg_ops->control->bytes_ext_get) + return tplg_ops->control->bytes_ext_get(scontrol, binary_data, size); return 0; } diff --git a/sound/soc/sof/ipc3-control.c b/sound/soc/sof/ipc3-control.c index df8e4df9663d..cdd5ad860a94 100644 --- a/sound/soc/sof/ipc3-control.c +++ b/sound/soc/sof/ipc3-control.c @@ -270,6 +270,174 @@ static int sof_ipc3_bytes_put(struct snd_sof_control *scontrol, return 0; } +static int sof_ipc3_bytes_ext_get(struct snd_sof_control *scontrol, + const unsigned int __user *binary_data, unsigned int size) +{ + struct snd_ctl_tlv __user *tlvd = (struct snd_ctl_tlv __user *)binary_data; + struct sof_ipc_ctrl_data *cdata = scontrol->ipc_control_data; + struct snd_soc_component *scomp = scontrol->scomp; + struct snd_ctl_tlv header; + size_t data_size; + + snd_sof_refresh_control(scontrol); + + /* + * Decrement the limit by ext bytes header size to + * ensure the user space buffer is not exceeded. + */ + if (size < sizeof(struct snd_ctl_tlv)) + return -ENOSPC; + + size -= sizeof(struct snd_ctl_tlv); + + /* set the ABI header values */ + cdata->data->magic = SOF_ABI_MAGIC; + cdata->data->abi = SOF_ABI_VERSION; + + /* check data size doesn't exceed max coming from topology */ + if (cdata->data->size > scontrol->max_size - sizeof(struct sof_abi_hdr)) { + dev_err_ratelimited(scomp->dev, "User data size %d exceeds max size %zu\n", + cdata->data->size, + scontrol->max_size - sizeof(struct sof_abi_hdr)); + return -EINVAL; + } + + data_size = cdata->data->size + sizeof(struct sof_abi_hdr); + + /* make sure we don't exceed size provided by user space for data */ + if (data_size > size) + return -ENOSPC; + + header.numid = cdata->cmd; + header.length = data_size; + if (copy_to_user(tlvd, &header, sizeof(struct snd_ctl_tlv))) + return -EFAULT; + + if (copy_to_user(tlvd->tlv, cdata->data, data_size)) + return -EFAULT; + + return 0; +} + +static int sof_ipc3_bytes_ext_put(struct snd_sof_control *scontrol, + const unsigned int __user *binary_data, + unsigned int size) +{ + const struct snd_ctl_tlv __user *tlvd = (const struct snd_ctl_tlv __user *)binary_data; + struct sof_ipc_ctrl_data *cdata = scontrol->ipc_control_data; + struct snd_soc_component *scomp = scontrol->scomp; + struct snd_ctl_tlv header; + + /* + * The beginning of bytes data contains a header from where + * the length (as bytes) is needed to know the correct copy + * length of data from tlvd->tlv. + */ + if (copy_from_user(&header, tlvd, sizeof(struct snd_ctl_tlv))) + return -EFAULT; + + /* make sure TLV info is consistent */ + if (header.length + sizeof(struct snd_ctl_tlv) > size) { + dev_err_ratelimited(scomp->dev, "Inconsistent TLV, data %d + header %zu > %d\n", + header.length, sizeof(struct snd_ctl_tlv), size); + return -EINVAL; + } + + /* be->max is coming from topology */ + if (header.length > scontrol->max_size) { + dev_err_ratelimited(scomp->dev, "Bytes data size %d exceeds max %zu\n", + header.length, scontrol->max_size); + return -EINVAL; + } + + /* Check that header id matches the command */ + if (header.numid != cdata->cmd) { + dev_err_ratelimited(scomp->dev, "Incorrect command for bytes put %d\n", + header.numid); + return -EINVAL; + } + + if (copy_from_user(cdata->data, tlvd->tlv, header.length)) + return -EFAULT; + + if (cdata->data->magic != SOF_ABI_MAGIC) { + dev_err_ratelimited(scomp->dev, "Wrong ABI magic 0x%08x\n", cdata->data->magic); + return -EINVAL; + } + + if (SOF_ABI_VERSION_INCOMPATIBLE(SOF_ABI_VERSION, cdata->data->abi)) { + dev_err_ratelimited(scomp->dev, "Incompatible ABI version 0x%08x\n", + cdata->data->abi); + return -EINVAL; + } + + /* be->max has been verified to be >= sizeof(struct sof_abi_hdr) */ + if (cdata->data->size > scontrol->max_size - sizeof(struct sof_abi_hdr)) { + dev_err_ratelimited(scomp->dev, "Mismatch in ABI data size (truncated?)\n"); + return -EINVAL; + } + + /* notify DSP of byte control updates */ + if (pm_runtime_active(scomp->dev)) + return snd_sof_ipc_set_get_comp_data(scontrol, true); + + return 0; +} + +static int sof_ipc3_bytes_ext_volatile_get(struct snd_sof_control *scontrol, + const unsigned int __user *binary_data, + unsigned int size) +{ + struct snd_ctl_tlv __user *tlvd = (struct snd_ctl_tlv __user *)binary_data; + struct sof_ipc_ctrl_data *cdata = scontrol->ipc_control_data; + struct snd_soc_component *scomp = scontrol->scomp; + struct snd_ctl_tlv header; + size_t data_size; + int ret; + + /* + * Decrement the limit by ext bytes header size to + * ensure the user space buffer is not exceeded. + */ + if (size < sizeof(struct snd_ctl_tlv)) + return -ENOSPC; + + size -= sizeof(struct snd_ctl_tlv); + + /* set the ABI header values */ + cdata->data->magic = SOF_ABI_MAGIC; + cdata->data->abi = SOF_ABI_VERSION; + + /* get all the component data from DSP */ + ret = snd_sof_ipc_set_get_comp_data(scontrol, false); + if (ret < 0) + return ret; + + /* check data size doesn't exceed max coming from topology */ + if (cdata->data->size > scontrol->max_size - sizeof(struct sof_abi_hdr)) { + dev_err_ratelimited(scomp->dev, "User data size %d exceeds max size %zu\n", + cdata->data->size, + scontrol->max_size - sizeof(struct sof_abi_hdr)); + return -EINVAL; + } + + data_size = cdata->data->size + sizeof(struct sof_abi_hdr); + + /* make sure we don't exceed size provided by user space for data */ + if (data_size > size) + return -ENOSPC; + + header.numid = cdata->cmd; + header.length = data_size; + if (copy_to_user(tlvd, &header, sizeof(struct snd_ctl_tlv))) + return -EFAULT; + + if (copy_to_user(tlvd->tlv, cdata->data, data_size)) + return -EFAULT; + + return ret; +} + static void snd_sof_update_control(struct snd_sof_control *scontrol, struct sof_ipc_ctrl_data *cdata) { @@ -419,5 +587,8 @@ const struct sof_ipc_tplg_control_ops tplg_ipc3_control_ops = { .enum_get = sof_ipc3_enum_get, .bytes_put = sof_ipc3_bytes_put, .bytes_get = sof_ipc3_bytes_get, + .bytes_ext_put = sof_ipc3_bytes_ext_put, + .bytes_ext_get = sof_ipc3_bytes_ext_get, + .bytes_ext_volatile_get = sof_ipc3_bytes_ext_volatile_get, .update = sof_ipc3_control_update, }; From patchwork Thu Mar 17 17:50:36 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Ranjani Sridharan X-Patchwork-Id: 552262 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 48E62C433EF for ; Thu, 17 Mar 2022 17:55:43 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 9559018FE; Thu, 17 Mar 2022 18:54:51 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 9559018FE DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1647539741; bh=oh448Xd11lB3oMc5RnUnNqrLe+WesJgQE7IDz0X9HDk=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=HA7L8ulG7FtVNdAPDkYtkesJWng561MP4BxYvFBpat8lsPME9/7h4Vbs0Lrs79j7j Rv5KHcHZ6IP9uY4CsKaIEAVTG/LnrkpGLfpurDb0vlOXiU8xGKAo2OLLwbBh/D7vqS 2iGK/hkP56sKevscUuZJnBbYlGAgtc9UJfwC9OFc= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id B31C2F8053C; Thu, 17 Mar 2022 18:52:13 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 8E6FEF80537; Thu, 17 Mar 2022 18:52:01 +0100 (CET) Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 95E88F8051F for ; Thu, 17 Mar 2022 18:51:53 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 95E88F8051F Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="e2OKFquU" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1647539514; x=1679075514; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=oh448Xd11lB3oMc5RnUnNqrLe+WesJgQE7IDz0X9HDk=; b=e2OKFquUAaWTgy/OwGLiHgHfb4biYHEdxeJ4Icw2M4mg2JhyHopU2tv3 sAmjIbW5UOusGuLxx9gSTRILQuFtmVV/Slj3thKfGDMAn6SM7LqGBRM8a PlYscSKksdRp9iR0we2t9QZ7q3IwDd9pxfDcRvDOBKwKC66CvnpcXDa7N oerR5UxZsdW60T/qCfDBMOUtlRHJEsjepmMp6AONqBE6aCbJ5/xgEfXAB QW8BmDKaeeZOSq1a0WHDYQTY8avrTIW76fZq1ZYpPVg9MoyR5UzRADEvO KJFyXX5Vy7FbwLp1uaV+YZl7t5rx9UP0CfLNb7yBtxihYSnhmhrWBqUEM w==; X-IronPort-AV: E=McAfee;i="6200,9189,10289"; a="254492921" X-IronPort-AV: E=Sophos;i="5.90,188,1643702400"; d="scan'208";a="254492921" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Mar 2022 10:51:23 -0700 X-IronPort-AV: E=Sophos;i="5.90,188,1643702400"; d="scan'208";a="550431142" Received: from jfbonin1-mobl6.amr.corp.intel.com (HELO rsridh2-mobl1.localdomain) ([10.255.92.163]) by fmsmga007-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Mar 2022 10:51:23 -0700 From: Ranjani Sridharan To: alsa-devel@alsa-project.org Subject: [PATCH 11/19] ASoC: SOF: Introduce IPC-specific PCM ops Date: Thu, 17 Mar 2022 10:50:36 -0700 Message-Id: <20220317175044.1752400-12-ranjani.sridharan@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220317175044.1752400-1-ranjani.sridharan@linux.intel.com> References: <20220317175044.1752400-1-ranjani.sridharan@linux.intel.com> MIME-Version: 1.0 Cc: tiwai@suse.de, broonie@kernel.org, =?utf-8?q?P=C3=A9ter_Ujfalusi?= , Ranjani Sridharan , Pierre-Louis Bossart X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" Introduce the IPC-specific PCM ops that will be used to abstract the PCM related IPC's. Signed-off-by: Ranjani Sridharan Reviewed-by: Péter Ujfalusi Reviewed-by: Pierre-Louis Bossart --- sound/soc/sof/sof-audio.h | 17 +++++++++++++++++ sound/soc/sof/sof-priv.h | 3 +++ 2 files changed, 20 insertions(+) diff --git a/sound/soc/sof/sof-audio.h b/sound/soc/sof/sof-audio.h index bcd38c882078..4d25e781e5ae 100644 --- a/sound/soc/sof/sof-audio.h +++ b/sound/soc/sof/sof-audio.h @@ -45,6 +45,23 @@ struct snd_sof_dai_config_data { int dai_data; /* contains DAI-specific information */ }; +/** + * struct sof_ipc_pcm_ops - IPC-specific PCM ops + * @hw_params: Function pointer for hw_params + * @hw_free: Function pointer for hw_free + * @trigger: Function pointer for trigger + * @dai_link_fixup: Function pointer for DAI link fixup + */ +struct sof_ipc_pcm_ops { + int (*hw_params)(struct snd_soc_component *component, struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_sof_platform_stream_params *platform_params); + int (*hw_free)(struct snd_soc_component *component, struct snd_pcm_substream *substream); + int (*trigger)(struct snd_soc_component *component, struct snd_pcm_substream *substream, + int cmd); + int (*dai_link_fixup)(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params); +}; + /** * struct sof_ipc_tplg_control_ops - IPC-specific ops for topology kcontrol IO */ diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h index 3e883044dd0f..0d9b640ae24c 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -371,15 +371,18 @@ struct sof_ipc_pm_ops { }; struct sof_ipc_tplg_ops; +struct sof_ipc_pcm_ops; /** * struct sof_ipc_ops - IPC-specific ops * @tplg: Pointer to IPC-specific topology ops * @pm: Pointer to PM ops + * @pcm: Pointer to PCM ops */ struct sof_ipc_ops { const struct sof_ipc_tplg_ops *tplg; const struct sof_ipc_pm_ops *pm; + const struct sof_ipc_pcm_ops *pcm; }; /* SOF generic IPC data */ From patchwork Thu Mar 17 17:50:40 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Ranjani Sridharan X-Patchwork-Id: 552260 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id BB1AFC433EF for ; Thu, 17 Mar 2022 17:56:45 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id F306A190C; Thu, 17 Mar 2022 18:55:53 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz F306A190C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1647539804; bh=qWisgQRCiDNAtpHZOy5FO5/vMlRPNwTm17WeTY5QnTE=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=rk8rMEf1ZQ/B/EqG1b7pPWk/0Ubb70FjXnqoPqFB4l2Cwk2Kwke7y0u+SsTYaZiyW cqzi6YjO8asBNapgyKqe0K5e133T/9r/h8kTCvdc9jivESFVuCVcs4kpzDerlv3ldC 58mfPsMP2Kb3D/cGRx7+qIpSZ8WunRxbkXmg6ess= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 22C1DF8055A; Thu, 17 Mar 2022 18:52:16 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id D5B04F8051B; Thu, 17 Mar 2022 18:52:06 +0100 (CET) Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id D82F3F8051D for ; Thu, 17 Mar 2022 18:51:55 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz D82F3F8051D Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="M1bewocM" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1647539517; x=1679075517; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=qWisgQRCiDNAtpHZOy5FO5/vMlRPNwTm17WeTY5QnTE=; b=M1bewocMzZT/3sYES8ThvnXpkyTUjttrrWQvvupV3AUpBmhVPNDSXBXH S+yK4vybwUBh66075b1wDCXmjEe9R+UwU18r8i5X2fyI47HdtvnpofGO6 nJOMIQB3llrO/5e0TIFU0HNmt5lHc+9yHPJYWrBmmYpDtk6RRTXny5sqy PuVdgk4m+bxyP87gU5aH91CoTG+hxzYkhZO0GSfKmx5rOUyqv7T3Bk8Fh Up5F2r0NRybiI6k0iERVTeqS/kjLb5JI58HSSyK6PUfNhY5fFEIklCkAn 6n/1g5CVkZUI0J+MzGoPkuuN0pAeUc876QENLS43HQT24JQkLWG5cjyQU A==; X-IronPort-AV: E=McAfee;i="6200,9189,10289"; a="254492931" X-IronPort-AV: E=Sophos;i="5.90,188,1643702400"; d="scan'208";a="254492931" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Mar 2022 10:51:23 -0700 X-IronPort-AV: E=Sophos;i="5.90,188,1643702400"; d="scan'208";a="550431155" Received: from jfbonin1-mobl6.amr.corp.intel.com (HELO rsridh2-mobl1.localdomain) ([10.255.92.163]) by fmsmga007-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Mar 2022 10:51:23 -0700 From: Ranjani Sridharan To: alsa-devel@alsa-project.org Subject: [PATCH 15/19] ASoC: SOF: Add trigger PCM op for IPC3 Date: Thu, 17 Mar 2022 10:50:40 -0700 Message-Id: <20220317175044.1752400-16-ranjani.sridharan@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220317175044.1752400-1-ranjani.sridharan@linux.intel.com> References: <20220317175044.1752400-1-ranjani.sridharan@linux.intel.com> MIME-Version: 1.0 Cc: tiwai@suse.de, broonie@kernel.org, =?utf-8?q?P=C3=A9ter_Ujfalusi?= , Ranjani Sridharan , Pierre-Louis Bossart X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" Add the trigger PCM op for IPC3 and use it. Signed-off-by: Ranjani Sridharan Reviewed-by: Péter Ujfalusi Reviewed-by: Pierre-Louis Bossart --- sound/soc/sof/ipc3-pcm.c | 43 ++++++++++++++++++++++++++++++++++++++++ sound/soc/sof/pcm.c | 23 ++++++--------------- 2 files changed, 49 insertions(+), 17 deletions(-) diff --git a/sound/soc/sof/ipc3-pcm.c b/sound/soc/sof/ipc3-pcm.c index b715199a2aaa..d83d54540bbe 100644 --- a/sound/soc/sof/ipc3-pcm.c +++ b/sound/soc/sof/ipc3-pcm.c @@ -137,7 +137,50 @@ static int sof_ipc3_pcm_hw_params(struct snd_soc_component *component, return ret; } +static int sof_ipc3_pcm_trigger(struct snd_soc_component *component, + struct snd_pcm_substream *substream, int cmd) +{ + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component); + struct sof_ipc_stream stream; + struct sof_ipc_reply reply; + struct snd_sof_pcm *spcm; + + spcm = snd_sof_find_spcm_dai(component, rtd); + if (!spcm) + return -EINVAL; + + stream.hdr.size = sizeof(stream); + stream.hdr.cmd = SOF_IPC_GLB_STREAM_MSG; + stream.comp_id = spcm->stream[substream->stream].comp_id; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + stream.hdr.cmd |= SOF_IPC_STREAM_TRIG_PAUSE; + break; + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + stream.hdr.cmd |= SOF_IPC_STREAM_TRIG_RELEASE; + break; + case SNDRV_PCM_TRIGGER_START: + stream.hdr.cmd |= SOF_IPC_STREAM_TRIG_START; + break; + case SNDRV_PCM_TRIGGER_SUSPEND: + fallthrough; + case SNDRV_PCM_TRIGGER_STOP: + stream.hdr.cmd |= SOF_IPC_STREAM_TRIG_STOP; + break; + default: + dev_err(component->dev, "Unhandled trigger cmd %d\n", cmd); + return -EINVAL; + } + + /* send IPC to the DSP */ + return sof_ipc_tx_message(sdev->ipc, stream.hdr.cmd, &stream, + sizeof(stream), &reply, sizeof(reply)); +} + const struct sof_ipc_pcm_ops ipc3_pcm_ops = { .hw_params = sof_ipc3_pcm_hw_params, .hw_free = sof_ipc3_pcm_hw_free, + .trigger = sof_ipc3_pcm_trigger, }; diff --git a/sound/soc/sof/pcm.c b/sound/soc/sof/pcm.c index 8a194c130981..dc55a04a1588 100644 --- a/sound/soc/sof/pcm.c +++ b/sound/soc/sof/pcm.c @@ -274,13 +274,12 @@ static int sof_pcm_trigger(struct snd_soc_component *component, { struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component); + const struct sof_ipc_pcm_ops *pcm_ops = sdev->ipc->ops->pcm; struct snd_sof_pcm *spcm; - struct sof_ipc_stream stream; - struct sof_ipc_reply reply; bool reset_hw_params = false; bool free_widget_list = false; bool ipc_first = false; - int ret; + int ret = 0; /* nothing to do for BE */ if (rtd->dai_link->no_pcm) @@ -293,17 +292,11 @@ static int sof_pcm_trigger(struct snd_soc_component *component, dev_dbg(component->dev, "pcm: trigger stream %d dir %d cmd %d\n", spcm->pcm.pcm_id, substream->stream, cmd); - stream.hdr.size = sizeof(stream); - stream.hdr.cmd = SOF_IPC_GLB_STREAM_MSG; - stream.comp_id = spcm->stream[substream->stream].comp_id; - switch (cmd) { case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - stream.hdr.cmd |= SOF_IPC_STREAM_TRIG_PAUSE; ipc_first = true; break; case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - stream.hdr.cmd |= SOF_IPC_STREAM_TRIG_RELEASE; break; case SNDRV_PCM_TRIGGER_START: if (spcm->stream[substream->stream].suspend_ignored) { @@ -315,7 +308,6 @@ static int sof_pcm_trigger(struct snd_soc_component *component, spcm->stream[substream->stream].suspend_ignored = false; return 0; } - stream.hdr.cmd |= SOF_IPC_STREAM_TRIG_START; break; case SNDRV_PCM_TRIGGER_SUSPEND: if (sdev->system_suspend_target == SOF_SUSPEND_S0IX && @@ -332,13 +324,11 @@ static int sof_pcm_trigger(struct snd_soc_component *component, free_widget_list = true; fallthrough; case SNDRV_PCM_TRIGGER_STOP: - stream.hdr.cmd |= SOF_IPC_STREAM_TRIG_STOP; ipc_first = true; reset_hw_params = true; break; default: - dev_err(component->dev, "error: unhandled trigger cmd %d\n", - cmd); + dev_err(component->dev, "Unhandled trigger cmd %d\n", cmd); return -EINVAL; } @@ -349,11 +339,10 @@ static int sof_pcm_trigger(struct snd_soc_component *component, if (!ipc_first) snd_sof_pcm_platform_trigger(sdev, substream, cmd); - /* send IPC to the DSP */ - ret = sof_ipc_tx_message(sdev->ipc, stream.hdr.cmd, &stream, - sizeof(stream), &reply, sizeof(reply)); + if (pcm_ops->trigger) + ret = pcm_ops->trigger(component, substream, cmd); - /* need to STOP DMA even if STOP IPC failed */ + /* need to STOP DMA even if trigger IPC failed */ if (ipc_first) snd_sof_pcm_platform_trigger(sdev, substream, cmd); From patchwork Thu Mar 17 17:50:41 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Ranjani Sridharan X-Patchwork-Id: 552258 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id DC890C433EF for ; Thu, 17 Mar 2022 17:58:01 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 260E41AA5; Thu, 17 Mar 2022 18:57:10 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 260E41AA5 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1647539880; bh=3WhlAcg6vKx9GuYzLzKN0v8vT66/Uj5AKZpU2z/yvV4=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=vOlMrc45d0bifPAKknoXIgXh9ONUN5eWiKcGbwUWskunGntzUaqeIVIlfUKyqCX+a pv/P+o3VyFTeGyw95Y33UjLBYtpkISqkTs5PPwU8N1AuxvW7F2Ezj1/Yvpgr1OjlEp uTY0IpYL5dhQvj6knQy9+cea605IE6yUeZFxVFlw= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 16EF2F805B6; Thu, 17 Mar 2022 18:52:23 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id CA798F8053B; Thu, 17 Mar 2022 18:52:12 +0100 (CET) Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id B9FBDF80526 for ; Thu, 17 Mar 2022 18:51:57 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz B9FBDF80526 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="Xuh6CRmw" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1647539518; x=1679075518; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=3WhlAcg6vKx9GuYzLzKN0v8vT66/Uj5AKZpU2z/yvV4=; b=Xuh6CRmwDX0/+4V4M6W8r+Ppqn2Ve9bpsyHMOw68rNOOXuYMAq05zuO2 fxx+piFQfpXS1spK+FrGO2Uq7y7XvrSyTtDpMyoVRtHBnygQgQQlZBgxL c7NOH8X7duyCqiYt9cGgT3NlKqKfLOa9G+bnTHNYLgraUcDJdOgpQhYEc fdWSYCnAWzWpNYSdrPTQteyRM7HjB9fcChY92i/NSLDHobfzjCvly1Ky2 WEoPczwheDXLP36ukWL2keFQ1HD3k0DD37HdAflaexOHt0dWhkQ9jHz0I z7Wo+Q8vRSyBHsK9LIYfx+UDjugEtMxWRsh1pwspVFRCIslKQ0Bvh1Kte w==; X-IronPort-AV: E=McAfee;i="6200,9189,10289"; a="254492932" X-IronPort-AV: E=Sophos;i="5.90,188,1643702400"; d="scan'208";a="254492932" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Mar 2022 10:51:23 -0700 X-IronPort-AV: E=Sophos;i="5.90,188,1643702400"; d="scan'208";a="550431157" Received: from jfbonin1-mobl6.amr.corp.intel.com (HELO rsridh2-mobl1.localdomain) ([10.255.92.163]) by fmsmga007-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Mar 2022 10:51:23 -0700 From: Ranjani Sridharan To: alsa-devel@alsa-project.org Subject: [PATCH 16/19] ASoC: SOF: Add dai_link_fixup PCM op for IPC3 Date: Thu, 17 Mar 2022 10:50:41 -0700 Message-Id: <20220317175044.1752400-17-ranjani.sridharan@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220317175044.1752400-1-ranjani.sridharan@linux.intel.com> References: <20220317175044.1752400-1-ranjani.sridharan@linux.intel.com> MIME-Version: 1.0 Cc: tiwai@suse.de, =?utf-8?q?P=C3=A9ter_Ujfalusi?= , Ranjani Sridharan , Pierre-Louis Bossart , broonie@kernel.org, Bard Liao X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" Define the dai_link_fixup PCM op for IPC3 and use it Signed-off-by: Ranjani Sridharan Reviewed-by: Péter Ujfalusi Reviewed-by: Pierre-Louis Bossart Reviewed-by: Bard Liao --- sound/soc/sof/ipc3-pcm.c | 186 +++++++++++++++++++++++++++++++++++++++ sound/soc/sof/pcm.c | 174 +----------------------------------- 2 files changed, 189 insertions(+), 171 deletions(-) diff --git a/sound/soc/sof/ipc3-pcm.c b/sound/soc/sof/ipc3-pcm.c index d83d54540bbe..58b75943cf6d 100644 --- a/sound/soc/sof/ipc3-pcm.c +++ b/sound/soc/sof/ipc3-pcm.c @@ -179,8 +179,194 @@ static int sof_ipc3_pcm_trigger(struct snd_soc_component *component, sizeof(stream), &reply, sizeof(reply)); } +static void ssp_dai_config_pcm_params_match(struct snd_sof_dev *sdev, const char *link_name, + struct snd_pcm_hw_params *params) +{ + struct sof_ipc_dai_config *config; + struct snd_sof_dai *dai; + int i; + + /* + * Search for all matching DAIs as we can have both playback and capture DAI + * associated with the same link. + */ + list_for_each_entry(dai, &sdev->dai_list, list) { + if (!dai->name || strcmp(link_name, dai->name)) + continue; + for (i = 0; i < dai->number_configs; i++) { + struct sof_dai_private_data *private = dai->private; + + config = &private->dai_config[i]; + if (config->ssp.fsync_rate == params_rate(params)) { + dev_dbg(sdev->dev, "DAI config %d matches pcm hw params\n", i); + dai->current_config = i; + break; + } + } + } +} + +static int sof_ipc3_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, SOF_AUDIO_PCM_DRV_NAME); + struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); + struct snd_sof_dai *dai = snd_sof_find_dai(component, (char *)rtd->dai_link->name); + struct snd_interval *rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); + struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); + struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component); + struct sof_dai_private_data *private; + struct snd_soc_dpcm *dpcm; + + if (!dai) { + dev_err(component->dev, "%s: No DAI found with name %s\n", __func__, + rtd->dai_link->name); + return -EINVAL; + } + + private = dai->private; + if (!private) { + dev_err(component->dev, "%s: No private data found for DAI %s\n", __func__, + rtd->dai_link->name); + return -EINVAL; + } + + /* read format from topology */ + snd_mask_none(fmt); + + switch (private->comp_dai->config.frame_fmt) { + case SOF_IPC_FRAME_S16_LE: + snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S16_LE); + break; + case SOF_IPC_FRAME_S24_4LE: + snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S24_LE); + break; + case SOF_IPC_FRAME_S32_LE: + snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S32_LE); + break; + default: + dev_err(component->dev, "No available DAI format!\n"); + return -EINVAL; + } + + /* read rate and channels from topology */ + switch (private->dai_config->type) { + case SOF_DAI_INTEL_SSP: + /* search for config to pcm params match, if not found use default */ + ssp_dai_config_pcm_params_match(sdev, (char *)rtd->dai_link->name, params); + + rate->min = private->dai_config[dai->current_config].ssp.fsync_rate; + rate->max = private->dai_config[dai->current_config].ssp.fsync_rate; + channels->min = private->dai_config[dai->current_config].ssp.tdm_slots; + channels->max = private->dai_config[dai->current_config].ssp.tdm_slots; + + dev_dbg(component->dev, "rate_min: %d rate_max: %d\n", rate->min, rate->max); + dev_dbg(component->dev, "channels_min: %d channels_max: %d\n", + channels->min, channels->max); + + break; + case SOF_DAI_INTEL_DMIC: + /* DMIC only supports 16 or 32 bit formats */ + if (private->comp_dai->config.frame_fmt == SOF_IPC_FRAME_S24_4LE) { + dev_err(component->dev, "Invalid fmt %d for DAI type %d\n", + private->comp_dai->config.frame_fmt, + private->dai_config->type); + } + break; + case SOF_DAI_INTEL_HDA: + /* + * HDAudio does not follow the default trigger + * sequence due to firmware implementation + */ + for_each_dpcm_fe(rtd, SNDRV_PCM_STREAM_PLAYBACK, dpcm) { + struct snd_soc_pcm_runtime *fe = dpcm->fe; + + fe->dai_link->trigger[SNDRV_PCM_STREAM_PLAYBACK] = + SND_SOC_DPCM_TRIGGER_POST; + } + break; + case SOF_DAI_INTEL_ALH: + /* + * Dai could run with different channel count compared with + * front end, so get dai channel count from topology + */ + channels->min = private->dai_config->alh.channels; + channels->max = private->dai_config->alh.channels; + break; + case SOF_DAI_IMX_ESAI: + rate->min = private->dai_config->esai.fsync_rate; + rate->max = private->dai_config->esai.fsync_rate; + channels->min = private->dai_config->esai.tdm_slots; + channels->max = private->dai_config->esai.tdm_slots; + + dev_dbg(component->dev, "rate_min: %d rate_max: %d\n", rate->min, rate->max); + dev_dbg(component->dev, "channels_min: %d channels_max: %d\n", + channels->min, channels->max); + break; + case SOF_DAI_MEDIATEK_AFE: + rate->min = private->dai_config->afe.rate; + rate->max = private->dai_config->afe.rate; + channels->min = private->dai_config->afe.channels; + channels->max = private->dai_config->afe.channels; + + dev_dbg(component->dev, "rate_min: %d rate_max: %d\n", rate->min, rate->max); + dev_dbg(component->dev, "channels_min: %d channels_max: %d\n", + channels->min, channels->max); + break; + case SOF_DAI_IMX_SAI: + rate->min = private->dai_config->sai.fsync_rate; + rate->max = private->dai_config->sai.fsync_rate; + channels->min = private->dai_config->sai.tdm_slots; + channels->max = private->dai_config->sai.tdm_slots; + + dev_dbg(component->dev, "rate_min: %d rate_max: %d\n", rate->min, rate->max); + dev_dbg(component->dev, "channels_min: %d channels_max: %d\n", + channels->min, channels->max); + break; + case SOF_DAI_AMD_BT: + rate->min = private->dai_config->acpbt.fsync_rate; + rate->max = private->dai_config->acpbt.fsync_rate; + channels->min = private->dai_config->acpbt.tdm_slots; + channels->max = private->dai_config->acpbt.tdm_slots; + + dev_dbg(component->dev, + "AMD_BT rate_min: %d rate_max: %d\n", rate->min, rate->max); + dev_dbg(component->dev, "AMD_BT channels_min: %d channels_max: %d\n", + channels->min, channels->max); + break; + case SOF_DAI_AMD_SP: + rate->min = private->dai_config->acpsp.fsync_rate; + rate->max = private->dai_config->acpsp.fsync_rate; + channels->min = private->dai_config->acpsp.tdm_slots; + channels->max = private->dai_config->acpsp.tdm_slots; + + dev_dbg(component->dev, + "AMD_SP rate_min: %d rate_max: %d\n", rate->min, rate->max); + dev_dbg(component->dev, "AMD_SP channels_min: %d channels_max: %d\n", + channels->min, channels->max); + break; + case SOF_DAI_AMD_DMIC: + rate->min = private->dai_config->acpdmic.fsync_rate; + rate->max = private->dai_config->acpdmic.fsync_rate; + channels->min = private->dai_config->acpdmic.tdm_slots; + channels->max = private->dai_config->acpdmic.tdm_slots; + + dev_dbg(component->dev, + "AMD_DMIC rate_min: %d rate_max: %d\n", rate->min, rate->max); + dev_dbg(component->dev, "AMD_DMIC channels_min: %d channels_max: %d\n", + channels->min, channels->max); + break; + default: + dev_err(component->dev, "Invalid DAI type %d\n", private->dai_config->type); + break; + } + + return 0; +} + const struct sof_ipc_pcm_ops ipc3_pcm_ops = { .hw_params = sof_ipc3_pcm_hw_params, .hw_free = sof_ipc3_pcm_hw_free, .trigger = sof_ipc3_pcm_trigger, + .dai_link_fixup = sof_ipc3_pcm_dai_link_fixup, }; diff --git a/sound/soc/sof/pcm.c b/sound/soc/sof/pcm.c index dc55a04a1588..658cd8966c9a 100644 --- a/sound/soc/sof/pcm.c +++ b/sound/soc/sof/pcm.c @@ -556,33 +556,6 @@ static int sof_pcm_new(struct snd_soc_component *component, return 0; } -static void ssp_dai_config_pcm_params_match(struct snd_sof_dev *sdev, const char *link_name, - struct snd_pcm_hw_params *params) -{ - struct sof_ipc_dai_config *config; - struct snd_sof_dai *dai; - int i; - - /* - * Search for all matching DAIs as we can have both playback and capture DAI - * associated with the same link. - */ - list_for_each_entry(dai, &sdev->dai_list, list) { - if (!dai->name || strcmp(link_name, dai->name)) - continue; - for (i = 0; i < dai->number_configs; i++) { - struct sof_dai_private_data *private = dai->private; - - config = &private->dai_config[i]; - if (config->ssp.fsync_rate == params_rate(params)) { - dev_dbg(sdev->dev, "DAI config %d matches pcm hw params\n", i); - dai->current_config = i; - break; - } - } - } -} - /* fixup the BE DAI link to match any values from topology */ int sof_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params) { @@ -596,8 +569,7 @@ int sof_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_pa struct snd_sof_dai *dai = snd_sof_find_dai(component, (char *)rtd->dai_link->name); struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component); - struct sof_dai_private_data *private = dai->private; - struct snd_soc_dpcm *dpcm; + const struct sof_ipc_pcm_ops *pcm_ops = sdev->ipc->ops->pcm; /* no topology exists for this BE, try a common configuration */ if (!dai) { @@ -618,148 +590,8 @@ int sof_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_pa return 0; } - /* read format from topology */ - snd_mask_none(fmt); - - switch (private->comp_dai->config.frame_fmt) { - case SOF_IPC_FRAME_S16_LE: - snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S16_LE); - break; - case SOF_IPC_FRAME_S24_4LE: - snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S24_LE); - break; - case SOF_IPC_FRAME_S32_LE: - snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S32_LE); - break; - default: - dev_err(component->dev, "error: No available DAI format!\n"); - return -EINVAL; - } - - /* read rate and channels from topology */ - switch (private->dai_config->type) { - case SOF_DAI_INTEL_SSP: - /* search for config to pcm params match, if not found use default */ - ssp_dai_config_pcm_params_match(sdev, (char *)rtd->dai_link->name, params); - - rate->min = private->dai_config[dai->current_config].ssp.fsync_rate; - rate->max = private->dai_config[dai->current_config].ssp.fsync_rate; - channels->min = private->dai_config[dai->current_config].ssp.tdm_slots; - channels->max = private->dai_config[dai->current_config].ssp.tdm_slots; - - dev_dbg(component->dev, - "rate_min: %d rate_max: %d\n", rate->min, rate->max); - dev_dbg(component->dev, - "channels_min: %d channels_max: %d\n", - channels->min, channels->max); - - break; - case SOF_DAI_INTEL_DMIC: - /* DMIC only supports 16 or 32 bit formats */ - if (private->comp_dai->config.frame_fmt == SOF_IPC_FRAME_S24_4LE) { - dev_err(component->dev, - "error: invalid fmt %d for DAI type %d\n", - private->comp_dai->config.frame_fmt, - private->dai_config->type); - } - break; - case SOF_DAI_INTEL_HDA: - /* - * HDAudio does not follow the default trigger - * sequence due to firmware implementation - */ - for_each_dpcm_fe(rtd, SNDRV_PCM_STREAM_PLAYBACK, dpcm) { - struct snd_soc_pcm_runtime *fe = dpcm->fe; - - fe->dai_link->trigger[SNDRV_PCM_STREAM_PLAYBACK] = - SND_SOC_DPCM_TRIGGER_POST; - } - break; - case SOF_DAI_INTEL_ALH: - /* - * Dai could run with different channel count compared with - * front end, so get dai channel count from topology - */ - channels->min = private->dai_config->alh.channels; - channels->max = private->dai_config->alh.channels; - break; - case SOF_DAI_IMX_ESAI: - rate->min = private->dai_config->esai.fsync_rate; - rate->max = private->dai_config->esai.fsync_rate; - channels->min = private->dai_config->esai.tdm_slots; - channels->max = private->dai_config->esai.tdm_slots; - - dev_dbg(component->dev, - "rate_min: %d rate_max: %d\n", rate->min, rate->max); - dev_dbg(component->dev, - "channels_min: %d channels_max: %d\n", - channels->min, channels->max); - break; - case SOF_DAI_MEDIATEK_AFE: - rate->min = private->dai_config->afe.rate; - rate->max = private->dai_config->afe.rate; - channels->min = private->dai_config->afe.channels; - channels->max = private->dai_config->afe.channels; - - dev_dbg(component->dev, - "rate_min: %d rate_max: %d\n", rate->min, rate->max); - dev_dbg(component->dev, - "channels_min: %d channels_max: %d\n", - channels->min, channels->max); - break; - case SOF_DAI_IMX_SAI: - rate->min = private->dai_config->sai.fsync_rate; - rate->max = private->dai_config->sai.fsync_rate; - channels->min = private->dai_config->sai.tdm_slots; - channels->max = private->dai_config->sai.tdm_slots; - - dev_dbg(component->dev, - "rate_min: %d rate_max: %d\n", rate->min, rate->max); - dev_dbg(component->dev, - "channels_min: %d channels_max: %d\n", - channels->min, channels->max); - break; - case SOF_DAI_AMD_BT: - rate->min = private->dai_config->acpbt.fsync_rate; - rate->max = private->dai_config->acpbt.fsync_rate; - channels->min = private->dai_config->acpbt.tdm_slots; - channels->max = private->dai_config->acpbt.tdm_slots; - - dev_dbg(component->dev, - "AMD_BT rate_min: %d rate_max: %d\n", rate->min, rate->max); - dev_dbg(component->dev, - "AMD_BT channels_min: %d channels_max: %d\n", - channels->min, channels->max); - break; - case SOF_DAI_AMD_SP: - rate->min = private->dai_config->acpsp.fsync_rate; - rate->max = private->dai_config->acpsp.fsync_rate; - channels->min = private->dai_config->acpsp.tdm_slots; - channels->max = private->dai_config->acpsp.tdm_slots; - - dev_dbg(component->dev, - "AMD_SP rate_min: %d rate_max: %d\n", rate->min, rate->max); - dev_dbg(component->dev, - "AMD_SP channels_min: %d channels_max: %d\n", - channels->min, channels->max); - break; - case SOF_DAI_AMD_DMIC: - rate->min = private->dai_config->acpdmic.fsync_rate; - rate->max = private->dai_config->acpdmic.fsync_rate; - channels->min = private->dai_config->acpdmic.tdm_slots; - channels->max = private->dai_config->acpdmic.tdm_slots; - - dev_dbg(component->dev, - "AMD_DMIC rate_min: %d rate_max: %d\n", rate->min, rate->max); - dev_dbg(component->dev, - "AMD_DMIC channels_min: %d channels_max: %d\n", - channels->min, channels->max); - break; - default: - dev_err(component->dev, "error: invalid DAI type %d\n", - private->dai_config->type); - break; - } + if (pcm_ops->dai_link_fixup) + return pcm_ops->dai_link_fixup(rtd, params); return 0; } From patchwork Thu Mar 17 17:50:44 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ranjani Sridharan X-Patchwork-Id: 552259 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id A1AEEC433F5 for ; Thu, 17 Mar 2022 17:57:37 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id E0206170E; Thu, 17 Mar 2022 18:56:45 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz E0206170E DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1647539855; bh=UFO0mKXc1Pe4BdIkYJ4BmO0PrzhaI/opvkJbUhm0dfI=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=Mx/bufb27BZxRi6rLnV50d9/lF9o9aaG/UCOhcCZXeNNyyvSGgC7roF1OC3hMiM0Z 1BnDcUNSIENtiMv4DKSP2hQJTWflU8MwT1e0v1z4yuitjK/ewRJ429rZ1MOpDIS1Jy DnU3M/t1dIabFlpWa0kasacEchFd2pCuJGija9ME= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 18F59F805AB; Thu, 17 Mar 2022 18:52:22 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 65453F8051D; Thu, 17 Mar 2022 18:52:10 +0100 (CET) Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id EDB47F80527 for ; Thu, 17 Mar 2022 18:51:57 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz EDB47F80527 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="AZQdrqEt" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1647539519; x=1679075519; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=UFO0mKXc1Pe4BdIkYJ4BmO0PrzhaI/opvkJbUhm0dfI=; b=AZQdrqEtq6KZM8V0ggKoKukvjrOLG+t6cHm2vTEhUi6FmPdlipNH8vCW LPzwpNKJ8Rp7UjN1tiZDsXZYG+p/1Nn1J9o5KZ4hY7ukWrdY+/9VRLKWA CsM7zVvJXN2I472LSU9VKXh0fXVgzo55NFsFOPs8nANLQ9EAkqH8Q70ND IhjKzKI5IcWos75z5qE5NgqMApZRzcUwlAMa4ksK85wj7WqTA04Bq1d3z jiAS9xJ+EaUFfzcRRYU2Vn+k7Aoy2G10q7i6Gf8WKfUR9yEOj6ITrrNou o0JgXLjug6g+p7WenX9s7j+gmcz3LOFU2azHlzNfvT+acoTb0aupZXvyh g==; X-IronPort-AV: E=McAfee;i="6200,9189,10289"; a="254492937" X-IronPort-AV: E=Sophos;i="5.90,188,1643702400"; d="scan'208";a="254492937" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Mar 2022 10:51:24 -0700 X-IronPort-AV: E=Sophos;i="5.90,188,1643702400"; d="scan'208";a="550431163" Received: from jfbonin1-mobl6.amr.corp.intel.com (HELO rsridh2-mobl1.localdomain) ([10.255.92.163]) by fmsmga007-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Mar 2022 10:51:24 -0700 From: Ranjani Sridharan To: alsa-devel@alsa-project.org Subject: [PATCH 19/19] ASoC: SOF: Add a new dai_get_clk topology IPC op Date: Thu, 17 Mar 2022 10:50:44 -0700 Message-Id: <20220317175044.1752400-20-ranjani.sridharan@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220317175044.1752400-1-ranjani.sridharan@linux.intel.com> References: <20220317175044.1752400-1-ranjani.sridharan@linux.intel.com> MIME-Version: 1.0 Cc: tiwai@suse.de, Pierre-Louis Bossart , Ranjani Sridharan , broonie@kernel.org, Rander Wang , Bard Liao X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" This will help make the code for getting the mclk and bclk IPC specific. Add the implementation for IPC3 as well. Signed-off-by: Ranjani Sridharan Reviewed-by: Rander Wang Reviewed-by: Pierre-Louis Bossart Reviewed-by: Bard Liao --- sound/soc/sof/ipc3-topology.c | 29 +++++++++++++++++++++++++++++ sound/soc/sof/sof-audio.c | 31 +++++++------------------------ sound/soc/sof/sof-audio.h | 6 ++++++ 3 files changed, 42 insertions(+), 24 deletions(-) diff --git a/sound/soc/sof/ipc3-topology.c b/sound/soc/sof/ipc3-topology.c index 3ac65dacc7b9..2f8450a8c0a1 100644 --- a/sound/soc/sof/ipc3-topology.c +++ b/sound/soc/sof/ipc3-topology.c @@ -2252,6 +2252,34 @@ static int sof_ipc3_tear_down_all_pipelines(struct snd_sof_dev *sdev, bool verif return 0; } +static int sof_ipc3_dai_get_clk(struct snd_sof_dev *sdev, struct snd_sof_dai *dai, int clk_type) +{ + struct sof_dai_private_data *private = dai->private; + + if (!private || !private->dai_config) + return 0; + + switch (private->dai_config->type) { + case SOF_DAI_INTEL_SSP: + switch (clk_type) { + case SOF_DAI_CLK_INTEL_SSP_MCLK: + return private->dai_config->ssp.mclk_rate; + case SOF_DAI_CLK_INTEL_SSP_BCLK: + return private->dai_config->ssp.bclk_rate; + default: + break; + } + dev_err(sdev->dev, "fail to get SSP clk %d rate\n", clk_type); + break; + default: + /* not yet implemented for platforms other than the above */ + dev_err(sdev->dev, "DAI type %d not supported yet!\n", private->dai_config->type); + break; + } + + return -EINVAL; +} + /* token list for each topology object */ static enum sof_tokens host_token_list[] = { SOF_CORE_TOKENS, @@ -2359,6 +2387,7 @@ const struct sof_ipc_tplg_ops ipc3_tplg_ops = { .widget_free = sof_ipc3_widget_free, .widget_setup = sof_ipc3_widget_setup, .dai_config = sof_ipc3_dai_config, + .dai_get_clk = sof_ipc3_dai_get_clk, .set_up_all_pipelines = sof_ipc3_set_up_all_pipelines, .tear_down_all_pipelines = sof_ipc3_tear_down_all_pipelines, }; diff --git a/sound/soc/sof/sof-audio.c b/sound/soc/sof/sof-audio.c index b4ee65cf9841..b2f009a0c5b7 100644 --- a/sound/soc/sof/sof-audio.c +++ b/sound/soc/sof/sof-audio.c @@ -628,40 +628,23 @@ struct snd_sof_dai *snd_sof_find_dai(struct snd_soc_component *scomp, return NULL; } -#define SOF_DAI_CLK_INTEL_SSP_MCLK 0 -#define SOF_DAI_CLK_INTEL_SSP_BCLK 1 - static int sof_dai_get_clk(struct snd_soc_pcm_runtime *rtd, int clk_type) { struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, SOF_AUDIO_PCM_DRV_NAME); struct snd_sof_dai *dai = snd_sof_find_dai(component, (char *)rtd->dai_link->name); - struct sof_dai_private_data *private = dai->private; + struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component); + const struct sof_ipc_tplg_ops *tplg_ops = sdev->ipc->ops->tplg; /* use the tplg configured mclk if existed */ - if (!dai || !private || !private->dai_config) + if (!dai) return 0; - switch (private->dai_config->type) { - case SOF_DAI_INTEL_SSP: - switch (clk_type) { - case SOF_DAI_CLK_INTEL_SSP_MCLK: - return private->dai_config->ssp.mclk_rate; - case SOF_DAI_CLK_INTEL_SSP_BCLK: - return private->dai_config->ssp.bclk_rate; - default: - dev_err(rtd->dev, "fail to get SSP clk %d rate\n", - clk_type); - return -EINVAL; - } - break; - default: - /* not yet implemented for platforms other than the above */ - dev_err(rtd->dev, "DAI type %d not supported yet!\n", - private->dai_config->type); - return -EINVAL; - } + if (tplg_ops->dai_get_clk) + return tplg_ops->dai_get_clk(sdev, dai, clk_type); + + return 0; } /* diff --git a/sound/soc/sof/sof-audio.h b/sound/soc/sof/sof-audio.h index b9a9956b5baa..7f15b3bc8196 100644 --- a/sound/soc/sof/sof-audio.h +++ b/sound/soc/sof/sof-audio.h @@ -30,6 +30,9 @@ #define WIDGET_IS_DAI(id) ((id) == snd_soc_dapm_dai_in || (id) == snd_soc_dapm_dai_out) +#define SOF_DAI_CLK_INTEL_SSP_MCLK 0 +#define SOF_DAI_CLK_INTEL_SSP_BCLK 1 + /* * Volume fractional word length define to 16 sets * the volume linear gain value to use Qx.16 format @@ -39,6 +42,7 @@ struct snd_sof_widget; struct snd_sof_route; struct snd_sof_control; +struct snd_sof_dai; struct snd_sof_dai_config_data { int dai_index; @@ -117,6 +121,7 @@ struct sof_ipc_tplg_widget_ops { * @widget_setup: Function pointer for setting up setup in the DSP * @widget_free: Function pointer for freeing widget in the DSP * @dai_config: Function pointer for sending DAI config IPC to the DSP + * @dai_get_clk: Function pointer for getting the DAI clock setting * @set_up_all_pipelines: Function pointer for setting up all topology pipelines * @tear_down_all_pipelines: Function pointer for tearing down all topology pipelines */ @@ -132,6 +137,7 @@ struct sof_ipc_tplg_ops { int (*widget_free)(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget); int (*dai_config)(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget, unsigned int flags, struct snd_sof_dai_config_data *data); + int (*dai_get_clk)(struct snd_sof_dev *sdev, struct snd_sof_dai *dai, int clk_type); int (*set_up_all_pipelines)(struct snd_sof_dev *sdev, bool verify); int (*tear_down_all_pipelines)(struct snd_sof_dev *sdev, bool verify); };