From patchwork Thu May 22 07:01:26 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benoit Cousson X-Patchwork-Id: 4220751 Return-Path: X-Original-To: patchwork-alsa-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 0C54DBEEAB for ; Thu, 22 May 2014 07:02:01 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id D17C42018B for ; Thu, 22 May 2014 07:01:58 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) by mail.kernel.org (Postfix) with ESMTP id 37A7C2012E for ; Thu, 22 May 2014 07:01:57 +0000 (UTC) Received: by alsa0.perex.cz (Postfix, from userid 1000) id 44DC026558D; Thu, 22 May 2014 09:01:56 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,NO_DNS_FOR_FROM, UNPARSEABLE_RELAY autolearn=no version=3.3.1 Received: from alsa0.perex.cz (localhost [IPv6:::1]) by alsa0.perex.cz (Postfix) with ESMTP id 945DD26558E; Thu, 22 May 2014 09:01:43 +0200 (CEST) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa0.perex.cz (Postfix, from userid 1000) id BF18B265584; Thu, 22 May 2014 09:01:41 +0200 (CEST) Received: from mail-we0-f171.google.com (mail-we0-f171.google.com [74.125.82.171]) by alsa0.perex.cz (Postfix) with ESMTP id 4D88026558D for ; Thu, 22 May 2014 09:01:29 +0200 (CEST) Received: by mail-we0-f171.google.com with SMTP id w62so3032926wes.16 for ; Thu, 22 May 2014 00:01:29 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:message-id:date:from:organization:user-agent :mime-version:to:cc:subject:references:in-reply-to:content-type :content-transfer-encoding; bh=Xi1JDIynNR4cHBpfxwgGMT+/d9BY6boqORLAqhmem7k=; b=f9oUFQLlLLBuWWOwPmeYOXj2CjHe1wjXjHrB/2x7aLWtU267OBejcsEdjFoQ3SDIkG LZ2CgOLftFQDQS+wiAGG+Cp3fIrr6RDGbEEBuerEowvavUwP06W0+5cxPlQwgOz5mXzW LzB8mB6Wdw02Znl+Unw++fK2GyYZNJMiKWi5tKlya83Es/11zbQYZNjDUbbv90MT0g4K nIppU7kuRCpC6dK5F4UGNMvZa5zD8w2u0N8qcR9gHu1x2lgPxrqNz4XvQMvJvpUHMLlB r0y2XrzcFwOpy3gOKVC9+cAixGOjvrDJMxtjH2YvM4XZdDHNvPoFJbiTp0jzchvJeXGG nc6A== X-Gm-Message-State: ALoCoQnqQ3O7BCVu6Pt9WlK9QD+aYyRNvJ+i5HeMf+v8gaeotU0AZHSTFwyqCvW/V15GvnU5/NII X-Received: by 10.180.36.138 with SMTP id q10mr968735wij.4.1400742088940; Thu, 22 May 2014 00:01:28 -0700 (PDT) Received: from [192.168.1.8] (lau06-1-82-228-246-9.fbx.proxad.net. [82.228.246.9]) by mx.google.com with ESMTPSA id l4sm25553024wjf.14.2014.05.22.00.01.27 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 22 May 2014 00:01:28 -0700 (PDT) Message-ID: <537DA0C6.7080502@baylibre.com> Date: Thu, 22 May 2014 09:01:26 +0200 From: Benoit Cousson Organization: BayLibre User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.5.0 MIME-Version: 1.0 To: Lars-Peter Clausen References: <1398340906-5017-1-git-send-email-bcousson@baylibre.com> <1398340906-5017-4-git-send-email-bcousson@baylibre.com> <535BABCF.6080001@metafoo.de> <5374D6BF.4060500@baylibre.com> <5375EC1C.9020909@metafoo.de> In-Reply-To: <5375EC1C.9020909@metafoo.de> Cc: Fabien Parent , misael.lopez@ti.com, broonie@kernel.org, lgirdwood@gmail.com, alsa-devel@alsa-project.org Subject: Re: [alsa-devel] [RFT v3 3/3] ASoC: core: Add support for DAI multicodec X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.14 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-bounces@alsa-project.org X-Virus-Scanned: ClamAV using ClamSMTP Hi Lars, On 16/05/2014 12:44, Lars-Peter Clausen wrote: > On 05/15/2014 05:01 PM, Benoit Cousson wrote: [...] >>>> @@ -1586,16 +1626,21 @@ static int soc_probe_link_dais(struct >>>> snd_soc_card *card, int num, int order) >>>> codec2codec_close_delayed_work); >>>> >>>> /* link the DAI widgets */ >>>> - ret = soc_link_dai_widgets(card, dai_link, >>>> - cpu_dai, codec_dai); >>>> - if (ret) >>>> - return ret; >>>> + for (i = 0; i < rtd->num_codecs; i++) { >>>> + ret = soc_link_dai_widgets(card, dai_link, >>>> + cpu_dai, rtd->codec_dais[i]); >>> >>> This will create a DAI link widget for each CODEC DAI. The DAI link >>> widget will configure the CPU and the CODEC DAI that are connected to >>> it. If there is one DAI link widget per CODEC DAI this means that the >>> CPU DAI will be connected to multiple DAI link widgets, which means it >>> will be configured once for each CODEC DAI (with possible conflicting >>> configurations). >> >> I've got that point, but now I'm wondering what struct should be per >> codec_dai. Should we consider one source and several sinks to >> represent the multiple codecs? > > The soc_link_dai_widgets function should take the rtd as a parameter > instead of the CODEC and CPU DAIs. Same goes for snd_soc_dapm_new_pcm() > then you create one dai_link widget per stream (i.e. one for capture of > there is capture support, one for playback if there is playback > support). And then create the paths between the dai_link widgets and the > DAI widgets accordingly. I'm still not 100% sure how it should work so here is a tentative patch to try to handle that part. Please note that in my setup none of that code is ever called :-( I'm not sure why! Please ignore the extra DEBUG code I added and there is probably some way to factorize some code, but I'd like to be sure that this is the proper way to handle the routes in the multicodec case before re-sending that series. Thanks, Benoit --- From 565bfa3f31abbe2b677238ed423eb9fa99609086 Mon Sep 17 00:00:00 2001 From: Benoit Cousson Date: Thu, 22 May 2014 08:54:54 +0200 Subject: [PATCH] ASoC: Temp: Tentative multicodec adaptation for dapm routes Not-Signed-off-by: Benoit Cousson --- include/sound/soc-dapm.h | 3 +- sound/soc/soc-core.c | 31 +---------- sound/soc/soc-dapm.c | 132 +++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 113 insertions(+), 53 deletions(-) diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h index b041fc6..41336be 100644 --- a/include/sound/soc-dapm.h +++ b/include/sound/soc-dapm.h @@ -381,8 +381,7 @@ int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card); void snd_soc_dapm_connect_dai_link_widgets(struct snd_soc_card *card); int snd_soc_dapm_new_pcm(struct snd_soc_card *card, const struct snd_soc_pcm_stream *params, - struct snd_soc_dapm_widget *source, - struct snd_soc_dapm_widget *sink); + struct snd_soc_pcm_runtime *rtd); /* dapm path setup */ int snd_soc_dapm_new_widgets(struct snd_soc_card *card); diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 077f51a..208df5d 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1483,37 +1483,8 @@ static int soc_link_dai_widgets(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link, struct snd_soc_pcm_runtime *rtd) { - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - struct snd_soc_dai *codec_dai = rtd->codec_dai; - struct snd_soc_dapm_widget *play_w, *capture_w; - int ret; - /* link the DAI widgets */ - play_w = codec_dai->playback_widget; - capture_w = cpu_dai->capture_widget; - if (play_w && capture_w) { - ret = snd_soc_dapm_new_pcm(card, dai_link->params, - capture_w, play_w); - if (ret != 0) { - dev_err(card->dev, "ASoC: Can't link %s to %s: %d\n", - play_w->name, capture_w->name, ret); - return ret; - } - } - - play_w = cpu_dai->playback_widget; - capture_w = codec_dai->capture_widget; - if (play_w && capture_w) { - ret = snd_soc_dapm_new_pcm(card, dai_link->params, - capture_w, play_w); - if (ret != 0) { - dev_err(card->dev, "ASoC: Can't link %s to %s: %d\n", - play_w->name, capture_w->name, ret); - return ret; - } - } - - return 0; + return snd_soc_dapm_new_pcm(card, dai_link->params,rtd); } static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order) diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index f457225..4f21429 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -22,7 +22,7 @@ * device reopen. * */ - +#define DEBUG #include #include #include @@ -3248,22 +3248,12 @@ out: return ret; } -int snd_soc_dapm_new_pcm(struct snd_soc_card *card, +int snd_soc_dapm_new_link(struct snd_soc_card *card, const struct snd_soc_pcm_stream *params, - struct snd_soc_dapm_widget *source, - struct snd_soc_dapm_widget *sink) + char *link_name) { - struct snd_soc_dapm_route routes[2]; struct snd_soc_dapm_widget template; struct snd_soc_dapm_widget *w; - size_t len; - char *link_name; - - len = strlen(source->name) + strlen(sink->name) + 2; - link_name = devm_kzalloc(card->dev, len, GFP_KERNEL); - if (!link_name) - return -ENOMEM; - snprintf(link_name, len, "%s-%s", source->name, sink->name); memset(&template, 0, sizeof(template)); template.reg = SND_SOC_NOPM; @@ -3271,7 +3261,7 @@ int snd_soc_dapm_new_pcm(struct snd_soc_card *card, template.name = link_name; template.event = snd_soc_dai_link_event; template.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | - SND_SOC_DAPM_PRE_PMD; + SND_SOC_DAPM_PRE_PMD; dev_dbg(card->dev, "ASoC: adding %s widget\n", link_name); @@ -3284,15 +3274,115 @@ int snd_soc_dapm_new_pcm(struct snd_soc_card *card, w->params = params; - memset(&routes, 0, sizeof(routes)); + return 0; +} + +int snd_soc_dapm_new_pcm(struct snd_soc_card *card, + const struct snd_soc_pcm_stream *params, + struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_dapm_route route; + struct snd_soc_dapm_widget *source, *sink; + size_t len; + char *link_name; + const char *codecs_link_name = "multiple"; + unsigned int num_widgets = 0; + int i; + + /* cpu_dai->capture_widget -> codec_dai->playback_widget */ + for (i = 0; i < rtd->num_codecs; i++) + if (rtd->codec_dais[i]->playback_widget) + num_widgets++; + + if (!rtd->cpu_dai->capture_widget || !num_widgets) + return 0; + + + source = rtd->cpu_dai->capture_widget; + + if (num_widgets > 1) { + len = strlen(source->name) + strlen(codecs_link_name) + 2; + } else { + sink = rtd->codec_dais[0]->playback_widget; + len = strlen(source->name) + strlen(sink->name) + 2; + } + + link_name = devm_kzalloc(card->dev, len, GFP_KERNEL); + if (!link_name) + return -ENOMEM; + + if (num_widgets > 1) + snprintf(link_name, len, "%s-%s", source->name, codecs_link_name); + else + snprintf(link_name, len, "%s-%s", source->name, sink->name); + + pr_info("%s(), link_name #1 %s", __func__,link_name); + snd_soc_dapm_new_link(card, params, link_name); - routes[0].source = source->name; - routes[0].sink = link_name; - routes[1].source = link_name; - routes[1].sink = sink->name; - return snd_soc_dapm_add_routes(&card->dapm, routes, - ARRAY_SIZE(routes)); + memset(&route, 0, sizeof(route)); + route.source = source->name; + route.sink = link_name; + snd_soc_dapm_add_route(&card->dapm, &route, false); + + route.source = link_name; + for (i = 0; i < rtd->num_codecs; i++) { + if (!rtd->codec_dais[i]->playback_widget) + continue; + + route.sink = rtd->codec_dais[i]->playback_widget->name; + snd_soc_dapm_add_route(&card->dapm, &route, false); + } + + + num_widgets = 0; + + /* codec_dai->capture_widget -> cpu_dai->playback_widget */ + for (i = 0; i < rtd->num_codecs; i++) + if (rtd->codec_dais[i]->capture_widget) + num_widgets++; + + if (!rtd->cpu_dai->playback_widget || !num_widgets) + return 0; + + + sink = rtd->cpu_dai->playback_widget; + + if (num_widgets > 1) { + len = strlen(sink->name) + strlen(codecs_link_name) + 2; + } else { + source = rtd->codec_dais[0]->playback_widget; + len = strlen(source->name) + strlen(sink->name) + 2; + } + + link_name = devm_kzalloc(card->dev, len, GFP_KERNEL); + if (!link_name) + return -ENOMEM; + + if (num_widgets > 1) + snprintf(link_name, len, "%s-%s", codecs_link_name, sink->name); + else + snprintf(link_name, len, "%s-%s", source->name, sink->name); + + pr_info("%s(), link_name #2 %s", __func__,link_name); + snd_soc_dapm_new_link(card, params, link_name); + + + memset(&route, 0, sizeof(route)); + route.sink = link_name; + for (i = 0; i < rtd->num_codecs; i++) { + if (!rtd->codec_dais[i]->capture_widget) + continue; + + route.source = rtd->codec_dais[i]->capture_widget->name; + snd_soc_dapm_add_route(&card->dapm, &route, false); + } + + route.source = link_name; + route.sink = sink->name; + snd_soc_dapm_add_route(&card->dapm, &route, false); + + return 0; } int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm,