From patchwork Tue Jun 22 01:14:13 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kuninori Morimoto X-Patchwork-Id: 465206 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B79C6C4743C for ; Tue, 22 Jun 2021 01:15:39 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 0D7896124B for ; Tue, 22 Jun 2021 01:15:39 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 0D7896124B Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=renesas.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org 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 A14751690; Tue, 22 Jun 2021 03:14:47 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz A14751690 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1624324537; bh=InqjXSZJtpDc9Wlwd3mEbY1Ow1SAP/WJDfFGtniMb50=; h=Date:From:Subject:To:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=qDm0iVBGwif4hNGAV2wa99DtklFyoc/1uRIut3wy78hS5gGdISzjQJCtqk19Lkwgg Qs4qQwuVBF5OjStc+xx2t7ukKYgfsa1hWUJtZnsNT/Vv5S6wkijtoadZTYNdXpvg3M qoCeIWfkaeOWSPXZtRgUSz/ccP/sUNPIEwvFL79s= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 97D9BF80245; Tue, 22 Jun 2021 03:14:23 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 0925AF80245; Tue, 22 Jun 2021 03:14:22 +0200 (CEST) Received: from relmlie5.idc.renesas.com (relmlor1.renesas.com [210.160.252.171]) by alsa1.perex.cz (Postfix) with ESMTP id 4138FF80111 for ; Tue, 22 Jun 2021 03:14:15 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 4138FF80111 Date: 22 Jun 2021 10:14:13 +0900 X-IronPort-AV: E=Sophos;i="5.83,290,1616425200"; d="scan'208";a="85109211" Received: from unknown (HELO relmlir6.idc.renesas.com) ([10.200.68.152]) by relmlie5.idc.renesas.com with ESMTP; 22 Jun 2021 10:14:13 +0900 Received: from mercury.renesas.com (unknown [10.166.252.133]) by relmlir6.idc.renesas.com (Postfix) with ESMTP id D6B264148A7D; Tue, 22 Jun 2021 10:14:13 +0900 (JST) Message-ID: <87zgvi3dlm.wl-kuninori.morimoto.gx@renesas.com> From: Kuninori Morimoto Subject: [PATCH RFC 01/15] of: property: add port base loop User-Agent: Wanderlust/2.15.9 Emacs/26.3 Mule/6.0 To: Mark Brown , Rob Herring In-Reply-To: <871r8u4s6q.wl-kuninori.morimoto.gx@renesas.com> References: <871r8u4s6q.wl-kuninori.morimoto.gx@renesas.com> MIME-Version: 1.0 (generated by SEMI-EPG 1.14.7 - "Harue") Cc: Linux-ALSA 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" From: Kuninori Morimoto We have endpoint base functions - of_graph_get_next_endpoint() - of_graph_get_endpoint_count() - for_each_endpoint_of_node() for_each_endpoint_of_node() loop finds endpoint. ports { port@0 { (1) endpoint {...}; }; port@1 { (2) endpoint {...}; }; ... }; In above case, for_each_endpoint_of_node() loop finds endpoint as (1) -> (2) -> ... If we want to get port@0 -> port@1 -> ... instead of endpoint, we need do like below for_each_endpoint_of_node(node, endpoint) { port = of_get_parent(endpoint); ... } But port might have multi endpoints. ports { port@0 { (1) endpoint@0 {...}; (2) endpoint@1 {...}; }; port@1 { (3) endpoint {...}; }; ... }; In such case, people want to have "port base" loop instead of "endpoints base" loop. This patch adds such functions/macros. Link: https://lore.kernel.org/r/87pn29pc5w.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Kuninori Morimoto --- drivers/of/property.c | 69 ++++++++++++++++++++++++++++++++++------ include/linux/of_graph.h | 14 ++++++++ 2 files changed, 73 insertions(+), 10 deletions(-) diff --git a/drivers/of/property.c b/drivers/of/property.c index 6c028632f425..bf3bdeeba2f9 100644 --- a/drivers/of/property.c +++ b/drivers/of/property.c @@ -650,15 +650,7 @@ struct device_node *of_graph_get_next_endpoint(const struct device_node *parent, * parent port node. */ if (!prev) { - struct device_node *node; - - node = of_get_child_by_name(parent, "ports"); - if (node) - parent = node; - - port = of_get_child_by_name(parent, "port"); - of_node_put(node); - + port = of_graph_get_next_port(parent, NULL); if (!port) { pr_err("graph: no port node found in %pOF\n", parent); return NULL; @@ -685,14 +677,59 @@ struct device_node *of_graph_get_next_endpoint(const struct device_node *parent, /* No more endpoints under this port, try the next one. */ prev = NULL; + port = of_graph_get_next_port(parent, port); + if (!port) + return NULL; + } +} +EXPORT_SYMBOL(of_graph_get_next_endpoint); + +/** + * of_graph_get_next_port() - get next port node + * @parent: pointer to the parent device node + * @prev: previous port node, or NULL to get first + * + * Return: An 'port' node pointer with refcount incremented. Refcount + * of the passed @prev node is decremented. + */ +struct device_node *of_graph_get_next_port(const struct device_node *parent, + struct device_node *prev) +{ + struct device_node *port = prev; + + if (!parent) + return NULL; + + /* + * Start by locating the port node. If no previous endpoint is specified + * search for the first port node, otherwise get the previous endpoint + * parent port node. + */ + if (!port) { + struct device_node *node; + + node = of_get_child_by_name(parent, "ports"); + if (node) + parent = node; + + port = of_get_child_by_name(parent, "port"); + of_node_put(node); + + if (!port) { + pr_err("graph: no port node found in %pOF\n", parent); + return NULL; + } + } else { do { port = of_get_next_child(parent, port); if (!port) return NULL; } while (!of_node_name_eq(port, "port")); } + + return port; } -EXPORT_SYMBOL(of_graph_get_next_endpoint); +EXPORT_SYMBOL(of_graph_get_next_port); /** * of_graph_get_endpoint_by_regs() - get endpoint node of specific identifiers @@ -819,6 +856,18 @@ int of_graph_get_endpoint_count(const struct device_node *np) } EXPORT_SYMBOL(of_graph_get_endpoint_count); +int of_graph_get_port_count(const struct device_node *np) +{ + struct device_node *port; + int num = 0; + + for_each_port_of_node(np, port) + num++; + + return num; +} +EXPORT_SYMBOL(of_graph_get_port_count); + /** * of_graph_get_remote_node() - get remote parent device_node for given port/endpoint * @node: pointer to parent device_node containing graph port/endpoint diff --git a/include/linux/of_graph.h b/include/linux/of_graph.h index 4d7756087b6b..8cd3bd674ebd 100644 --- a/include/linux/of_graph.h +++ b/include/linux/of_graph.h @@ -26,6 +26,17 @@ struct of_endpoint { const struct device_node *local_node; }; +/** + * for_each_port_of_node - iterate over every port in a device node + * @parent: parent device node containing ports and port + * @child: loop variable pointing to the current port node + * + * When breaking out of the loop, of_node_put(child) has to be called manually. + */ +#define for_each_port_of_node(parent, child) \ + for (child = of_graph_get_next_port(parent, NULL); child != NULL; \ + child = of_graph_get_next_port(parent, child)) + /** * for_each_endpoint_of_node - iterate over every endpoint in a device node * @parent: parent device node containing ports and endpoints @@ -41,8 +52,11 @@ struct of_endpoint { bool of_graph_is_present(const struct device_node *node); int of_graph_parse_endpoint(const struct device_node *node, struct of_endpoint *endpoint); +int of_graph_get_port_count(const struct device_node *np); int of_graph_get_endpoint_count(const struct device_node *np); struct device_node *of_graph_get_port_by_id(struct device_node *node, u32 id); +struct device_node *of_graph_get_next_port(const struct device_node *parent, + struct device_node *previous); struct device_node *of_graph_get_next_endpoint(const struct device_node *parent, struct device_node *previous); struct device_node *of_graph_get_endpoint_by_regs( From patchwork Tue Jun 22 01:14:21 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kuninori Morimoto X-Patchwork-Id: 465939 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1C5BFC4743C for ; Tue, 22 Jun 2021 01:15:55 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 29F0460FD8 for ; Tue, 22 Jun 2021 01:15:54 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 29F0460FD8 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=renesas.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org 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 BD468169C; Tue, 22 Jun 2021 03:15:02 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz BD468169C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1624324552; bh=KZrrjKjpWMTh5+lF+xQhrxACK7Gbd/ckYdN8S79Ofwg=; h=Date:From:Subject:To:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=WhbLORT4H4iOtqja7/XRVTv+w/xyDXFW3hlug5cOe/XSWJpJXEk4Jct4avFnpqhbs 1/qendWZAAJRaQEVlXlQzPR+A+2jWRWLCGjBsmnifsZYKL39yzirZcSX9OV2aNxU6d b2zn79dujHJUkhGv1Bls08Y99JOjR4huKoUwH04s= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id B39C1F8016D; Tue, 22 Jun 2021 03:14:28 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 0E690F804E0; Tue, 22 Jun 2021 03:14:28 +0200 (CEST) Received: from relmlie5.idc.renesas.com (relmlor1.renesas.com [210.160.252.171]) by alsa1.perex.cz (Postfix) with ESMTP id 7CD4BF8016D for ; Tue, 22 Jun 2021 03:14:21 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 7CD4BF8016D Date: 22 Jun 2021 10:14:21 +0900 X-IronPort-AV: E=Sophos;i="5.83,290,1616425200"; d="scan'208";a="85109217" Received: from unknown (HELO relmlir6.idc.renesas.com) ([10.200.68.152]) by relmlie5.idc.renesas.com with ESMTP; 22 Jun 2021 10:14:21 +0900 Received: from mercury.renesas.com (unknown [10.166.252.133]) by relmlir6.idc.renesas.com (Postfix) with ESMTP id 1D4824148A7D; Tue, 22 Jun 2021 10:14:21 +0900 (JST) Message-ID: <87y2b23dle.wl-kuninori.morimoto.gx@renesas.com> From: Kuninori Morimoto Subject: [PATCH RFC 02/15] ASoC: dt-bindings: test-component: add Test Component YAML bindings User-Agent: Wanderlust/2.15.9 Emacs/26.3 Mule/6.0 To: Mark Brown , Rob Herring In-Reply-To: <871r8u4s6q.wl-kuninori.morimoto.gx@renesas.com> References: <871r8u4s6q.wl-kuninori.morimoto.gx@renesas.com> MIME-Version: 1.0 (generated by SEMI-EPG 1.14.7 - "Harue") Cc: Linux-ALSA 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" From: Kuninori Morimoto This patch adds test-component sound device YAML bindings. It can be used for Sound Test/Debug. Signed-off-by: Kuninori Morimoto --- .../bindings/sound/test-component.yaml | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/test-component.yaml diff --git a/Documentation/devicetree/bindings/sound/test-component.yaml b/Documentation/devicetree/bindings/sound/test-component.yaml new file mode 100644 index 000000000000..62a6ecad0e88 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/test-component.yaml @@ -0,0 +1,33 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/test-component.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Test Component Device Tree Bindings + +maintainers: + - Kuninori Morimoto + +properties: + compatible: + enum: + - test-cpu + - test-cpu-vv + - test-cpu-vn + - test-cpu-nv + - test-codec + - test-codec-vv + - test-codec-vn + - test-codec-nv + +required: + - compatible + +additionalProperties: true + +examples: + - | + test_cpu { + compatible = "test-cpu"; + }; From patchwork Tue Jun 22 01:14:26 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kuninori Morimoto X-Patchwork-Id: 465205 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-10.9 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNWANTED_LANGUAGE_BODY, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C540BC4743C for ; Tue, 22 Jun 2021 01:16:21 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 1C540610C7 for ; Tue, 22 Jun 2021 01:16:21 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 1C540610C7 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=renesas.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org 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 78318826; Tue, 22 Jun 2021 03:15:29 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 78318826 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1624324579; bh=Cd6QHzUtecrURlK5ny/xUV1WqoZJq7sXCxs2ZXgQheI=; h=Date:From:Subject:To:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=Y9/+lfQT8//HfvwP0yI6jdffmy1stbygj8qB8fi8HpyGXpooWUYnFFrlCP2TItcV5 DEvuz5mIPvefDa3KjVA0lufNr2E7FbvRnHLGfJA0AmvmiLlKmdeEI7oLNLrPIYnuky 1SoLCZpxn1PvGWm3T31RZwDb4OI2NwREYkS7gH7M= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 4EB34F804E3; Tue, 22 Jun 2021 03:14:37 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 01936F804E4; Tue, 22 Jun 2021 03:14:36 +0200 (CEST) Received: from relmlie6.idc.renesas.com (relmlor2.renesas.com [210.160.252.172]) by alsa1.perex.cz (Postfix) with ESMTP id BB55BF804E2 for ; Tue, 22 Jun 2021 03:14:28 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz BB55BF804E2 Date: 22 Jun 2021 10:14:26 +0900 X-IronPort-AV: E=Sophos;i="5.83,290,1616425200"; d="scan'208";a="84989898" Received: from unknown (HELO relmlir5.idc.renesas.com) ([10.200.68.151]) by relmlie6.idc.renesas.com with ESMTP; 22 Jun 2021 10:14:26 +0900 Received: from mercury.renesas.com (unknown [10.166.252.133]) by relmlir5.idc.renesas.com (Postfix) with ESMTP id 87F4A400D0D1; Tue, 22 Jun 2021 10:14:26 +0900 (JST) Message-ID: <87wnqm3dl9.wl-kuninori.morimoto.gx@renesas.com> From: Kuninori Morimoto Subject: [PATCH RFC 03/15] ASoC: test-component: add Test Component for Sound debug/test User-Agent: Wanderlust/2.15.9 Emacs/26.3 Mule/6.0 To: Mark Brown , Rob Herring In-Reply-To: <871r8u4s6q.wl-kuninori.morimoto.gx@renesas.com> References: <871r8u4s6q.wl-kuninori.morimoto.gx@renesas.com> MIME-Version: 1.0 (generated by SEMI-EPG 1.14.7 - "Harue") Cc: Linux-ALSA 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" From: Kuninori Morimoto We already have dummy-codec, dummy-platform. But its issues are 1) we don't have dummy-cpu, 2) we can't select it via DeviceTree 3) It do nothing Sometimes we want to have Dummy Sound Component for debugging, for testing, for learning Framework behavior, etc, etc... This patch adds Test-Component driver for it. User can select CPU Component by using "test-cpu" compatible, and can select Codec Component by using "test-codec" compatible. It doesn't support Platform so far, but is easy to add. We can verbose print to know its progress if user selected xxx-vn or xxx-nv or xxx-vv compatible driver. for example, test-cpu : silent Component, silent DAI test-cpu-vn : verbose Component, silent DAI test-cpu-nv : silent Component, verbose DAI test-cpu-vv : verbose Component, verbose DAI Signed-off-by: Kuninori Morimoto --- sound/soc/generic/Kconfig | 6 + sound/soc/generic/Makefile | 2 + sound/soc/generic/test-component.c | 659 +++++++++++++++++++++++++++++ 3 files changed, 667 insertions(+) create mode 100644 sound/soc/generic/test-component.c diff --git a/sound/soc/generic/Kconfig b/sound/soc/generic/Kconfig index 4cafcf0e2bbf..bb734780669e 100644 --- a/sound/soc/generic/Kconfig +++ b/sound/soc/generic/Kconfig @@ -17,3 +17,9 @@ config SND_AUDIO_GRAPH_CARD This option enables generic simple sound card support with OF-graph DT bindings. It also support DPCM of multi CPU single Codec ststem. + +config SND_TEST_COMPONENT + tristate "ASoC Test component sound support" + depends on OF + help + This option enables test component sound driver support. diff --git a/sound/soc/generic/Makefile b/sound/soc/generic/Makefile index 21c29e5e0671..988bfd45d2e2 100644 --- a/sound/soc/generic/Makefile +++ b/sound/soc/generic/Makefile @@ -2,7 +2,9 @@ snd-soc-simple-card-utils-objs := simple-card-utils.o snd-soc-simple-card-objs := simple-card.o snd-soc-audio-graph-card-objs := audio-graph-card.o +snd-soc-test-component-objs := test-component.o obj-$(CONFIG_SND_SIMPLE_CARD_UTILS) += snd-soc-simple-card-utils.o obj-$(CONFIG_SND_SIMPLE_CARD) += snd-soc-simple-card.o obj-$(CONFIG_SND_AUDIO_GRAPH_CARD) += snd-soc-audio-graph-card.o +obj-$(CONFIG_SND_TEST_COMPONENT) += snd-soc-test-component.o diff --git a/sound/soc/generic/test-component.c b/sound/soc/generic/test-component.c new file mode 100644 index 000000000000..8a5247bf28c5 --- /dev/null +++ b/sound/soc/generic/test-component.c @@ -0,0 +1,659 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// test-component.c -- Test Audio Component driver +// +// Copyright (C) 2020 Renesas Electronics Corporation +// Kuninori Morimoto + +#include +#include +#include +#include +#include +#include +#include + +#define TEST_NAME_LEN 32 +struct test_dai_name { + char name[TEST_NAME_LEN]; + char name_playback[TEST_NAME_LEN]; + char name_capture[TEST_NAME_LEN]; +}; + +struct test_priv { + struct device *dev; + struct snd_pcm_substream *substream; + struct delayed_work dwork; + struct snd_soc_component_driver *component_driver; + struct snd_soc_dai_driver *dai_driver; + struct test_dai_name *name; +}; + +struct test_adata { + u32 is_cpu:1; + u32 cmp_v:1; + u32 dai_v:1; +}; + +#define mile_stone(d) dev_info((d)->dev, "%s() : %s", __func__, (d)->driver->name) +#define mile_stone_x(dev) dev_info(dev, "%s()", __func__) + +static int test_dai_set_sysclk(struct snd_soc_dai *dai, + int clk_id, unsigned int freq, int dir) +{ + mile_stone(dai); + + return 0; +} + +static int test_dai_set_pll(struct snd_soc_dai *dai, int pll_id, int source, + unsigned int freq_in, unsigned int freq_out) +{ + mile_stone(dai); + + return 0; +} + +static int test_dai_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div) +{ + mile_stone(dai); + + return 0; +} + +static int test_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) +{ + unsigned int format = fmt & SND_SOC_DAIFMT_FORMAT_MASK; + unsigned int clock = fmt & SND_SOC_DAIFMT_CLOCK_MASK; + unsigned int inv = fmt & SND_SOC_DAIFMT_INV_MASK; + unsigned int master = fmt & SND_SOC_DAIFMT_MASTER_MASK; + char *str; + + dev_info(dai->dev, "name : %s", dai->name); + + str = "unknown"; + switch (format) { + case SND_SOC_DAIFMT_I2S: + str = "i2s"; + break; + case SND_SOC_DAIFMT_RIGHT_J: + str = "right_j"; + break; + case SND_SOC_DAIFMT_LEFT_J: + str = "left_j"; + break; + case SND_SOC_DAIFMT_DSP_A: + str = "dsp_a"; + break; + case SND_SOC_DAIFMT_DSP_B: + str = "dsp_b"; + break; + case SND_SOC_DAIFMT_AC97: + str = "ac97"; + break; + case SND_SOC_DAIFMT_PDM: + str = "pdm"; + break; + } + dev_info(dai->dev, "format : %s", str); + + if (clock == SND_SOC_DAIFMT_CONT) + str = "continuous"; + else + str = "gated"; + dev_info(dai->dev, "clock : %s", str); + + str = "unknown"; + switch (master) { + case SND_SOC_DAIFMT_CBP_CFP: + str = "clk provider, frame provider"; + break; + case SND_SOC_DAIFMT_CBC_CFP: + str = "clk consumer, frame provider"; + break; + case SND_SOC_DAIFMT_CBP_CFC: + str = "clk provider, frame consumer"; + break; + case SND_SOC_DAIFMT_CBC_CFC: + str = "clk consumer, frame consumer"; + break; + } + dev_info(dai->dev, "clock : codec is %s", str); + + str = "unknown"; + switch (inv) { + case SND_SOC_DAIFMT_NB_NF: + str = "normal bit, normal frame"; + break; + case SND_SOC_DAIFMT_NB_IF: + str = "normal bit, invert frame"; + break; + case SND_SOC_DAIFMT_IB_NF: + str = "invert bit, normal frame"; + break; + case SND_SOC_DAIFMT_IB_IF: + str = "invert bit, invert frame"; + break; + } + dev_info(dai->dev, "signal : %s", str); + + return 0; +} + +static int test_dai_mute_stream(struct snd_soc_dai *dai, int mute, int stream) +{ + mile_stone(dai); + + return 0; +} + +static int test_dai_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) +{ + mile_stone(dai); + + return 0; +} + +static void test_dai_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) +{ + mile_stone(dai); +} + +static int test_dai_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) +{ + mile_stone(dai); + + return 0; +} + +static int test_dai_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) +{ + mile_stone(dai); + + return 0; +} + +static int test_dai_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai) +{ + mile_stone(dai); + + return 0; +} + +static int test_dai_bespoke_trigger(struct snd_pcm_substream *substream, + int cmd, struct snd_soc_dai *dai) +{ + mile_stone(dai); + + return 0; +} + +static u64 test_dai_formats = + /* + * Select below from Sound Card, not auto + * SND_SOC_POSSIBLE_DAIFMT_CBP_CFP + * SND_SOC_POSSIBLE_DAIFMT_CBC_CFP + * SND_SOC_POSSIBLE_DAIFMT_CBP_CFC + * SND_SOC_POSSIBLE_DAIFMT_CBC_CFC + */ + SND_SOC_POSSIBLE_DAIFMT_I2S | + SND_SOC_POSSIBLE_DAIFMT_RIGHT_J | + SND_SOC_POSSIBLE_DAIFMT_LEFT_J | + SND_SOC_POSSIBLE_DAIFMT_DSP_A | + SND_SOC_POSSIBLE_DAIFMT_DSP_B | + SND_SOC_POSSIBLE_DAIFMT_AC97 | + SND_SOC_POSSIBLE_DAIFMT_PDM | + SND_SOC_POSSIBLE_DAIFMT_NB_NF | + SND_SOC_POSSIBLE_DAIFMT_NB_IF | + SND_SOC_POSSIBLE_DAIFMT_IB_NF | + SND_SOC_POSSIBLE_DAIFMT_IB_IF; + +static const struct snd_soc_dai_ops test_ops = { + .set_fmt = test_dai_set_fmt, + .startup = test_dai_startup, + .shutdown = test_dai_shutdown, + .auto_selectable_formats = &test_dai_formats, + .num_auto_selectable_formats = 1, +}; + +static const struct snd_soc_dai_ops test_verbose_ops = { + .set_sysclk = test_dai_set_sysclk, + .set_pll = test_dai_set_pll, + .set_clkdiv = test_dai_set_clkdiv, + .set_fmt = test_dai_set_fmt, + .mute_stream = test_dai_mute_stream, + .startup = test_dai_startup, + .shutdown = test_dai_shutdown, + .hw_params = test_dai_hw_params, + .hw_free = test_dai_hw_free, + .trigger = test_dai_trigger, + .bespoke_trigger = test_dai_bespoke_trigger, + .auto_selectable_formats = &test_dai_formats, + .num_auto_selectable_formats = 1, +}; + +#define STUB_RATES SNDRV_PCM_RATE_8000_384000 +#define STUB_FORMATS (SNDRV_PCM_FMTBIT_S8 | \ + SNDRV_PCM_FMTBIT_U8 | \ + SNDRV_PCM_FMTBIT_S16_LE | \ + SNDRV_PCM_FMTBIT_U16_LE | \ + SNDRV_PCM_FMTBIT_S24_LE | \ + SNDRV_PCM_FMTBIT_S24_3LE | \ + SNDRV_PCM_FMTBIT_U24_LE | \ + SNDRV_PCM_FMTBIT_S32_LE | \ + SNDRV_PCM_FMTBIT_U32_LE) + +static int test_component_probe(struct snd_soc_component *component) +{ + mile_stone(component); + + return 0; +} + +static void test_component_remove(struct snd_soc_component *component) +{ + mile_stone(component); +} + +static int test_component_suspend(struct snd_soc_component *component) +{ + mile_stone(component); + + return 0; +} + +static int test_component_resume(struct snd_soc_component *component) +{ + mile_stone(component); + + return 0; +} + +#define PREALLOC_BUFFER (32 * 1024) +static int test_component_pcm_construct(struct snd_soc_component *component, + struct snd_soc_pcm_runtime *rtd) +{ + mile_stone(component); + + snd_pcm_set_managed_buffer_all( + rtd->pcm, + SNDRV_DMA_TYPE_DEV, + rtd->card->snd_card->dev, + PREALLOC_BUFFER, PREALLOC_BUFFER); + + return 0; +} + +static void test_component_pcm_destruct(struct snd_soc_component *component, + struct snd_pcm *pcm) +{ + mile_stone(component); +} + +static int test_component_set_sysclk(struct snd_soc_component *component, + int clk_id, int source, unsigned int freq, int dir) +{ + mile_stone(component); + + return 0; +} + +static int test_component_set_pll(struct snd_soc_component *component, int pll_id, + int source, unsigned int freq_in, unsigned int freq_out) +{ + mile_stone(component); + + return 0; +} + +static int test_component_set_jack(struct snd_soc_component *component, + struct snd_soc_jack *jack, void *data) +{ + mile_stone(component); + + return 0; +} + +static void test_component_seq_notifier(struct snd_soc_component *component, + enum snd_soc_dapm_type type, int subseq) +{ + mile_stone(component); +} + +static int test_component_stream_event(struct snd_soc_component *component, int event) +{ + mile_stone(component); + + return 0; +} + +static int test_component_set_bias_level(struct snd_soc_component *component, + enum snd_soc_bias_level level) +{ + mile_stone(component); + + return 0; +} + +static const struct snd_pcm_hardware test_component_hardware = { + /* Random values to keep userspace happy when checking constraints */ + .info = SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_MMAP_VALID, + .buffer_bytes_max = 32 * 1024, + .period_bytes_min = 32, + .period_bytes_max = 8192, + .periods_min = 1, + .periods_max = 128, + .fifo_size = 256, +}; + +static int test_component_open(struct snd_soc_component *component, + struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + + mile_stone(component); + + /* BE's dont need dummy params */ + if (!rtd->dai_link->no_pcm) + snd_soc_set_runtime_hwparams(substream, &test_component_hardware); + + return 0; +} + +static int test_component_close(struct snd_soc_component *component, + struct snd_pcm_substream *substream) +{ + mile_stone(component); + + return 0; +} + +static int test_component_ioctl(struct snd_soc_component *component, + struct snd_pcm_substream *substream, + unsigned int cmd, void *arg) +{ + mile_stone(component); + + return 0; +} + +static int test_component_hw_params(struct snd_soc_component *component, + struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + mile_stone(component); + + return 0; +} + +static int test_component_hw_free(struct snd_soc_component *component, + struct snd_pcm_substream *substream) +{ + mile_stone(component); + + return 0; +} + +static int test_component_prepare(struct snd_soc_component *component, + struct snd_pcm_substream *substream) +{ + mile_stone(component); + + return 0; +} + +static void test_component_timer_stop(struct test_priv *priv) +{ + cancel_delayed_work(&priv->dwork); +} + +static void test_component_timer_start(struct test_priv *priv) +{ + schedule_delayed_work(&priv->dwork, msecs_to_jiffies(10)); +} + +static void test_component_dwork(struct work_struct *work) +{ + struct test_priv *priv = container_of(work, struct test_priv, dwork.work); + + if (priv->substream) + snd_pcm_period_elapsed(priv->substream); + + test_component_timer_start(priv); +} + +static int test_component_trigger(struct snd_soc_component *component, + struct snd_pcm_substream *substream, int cmd) +{ + struct test_priv *priv = dev_get_drvdata(component->dev); + + mile_stone(component); + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + test_component_timer_start(priv); + priv->substream = substream; /* set substream later */ + break; + case SNDRV_PCM_TRIGGER_STOP: + priv->substream = NULL; + test_component_timer_stop(priv); + } + + return 0; +} + +static int test_component_sync_stop(struct snd_soc_component *component, + struct snd_pcm_substream *substream) +{ + mile_stone(component); + + return 0; +} + +static snd_pcm_uframes_t test_component_pointer(struct snd_soc_component *component, + struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + static int pointer; + + if (!runtime) + return 0; + + pointer += 10; + if (pointer > PREALLOC_BUFFER) + pointer = 0; + + /* mile_stone(component); */ + + return bytes_to_frames(runtime, pointer); +} + +static int test_component_get_time_info(struct snd_soc_component *component, + struct snd_pcm_substream *substream, + struct timespec64 *system_ts, + struct timespec64 *audio_ts, + struct snd_pcm_audio_tstamp_config *audio_tstamp_config, + struct snd_pcm_audio_tstamp_report *audio_tstamp_report) +{ + mile_stone(component); + + return 0; +} + +static int test_component_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + mile_stone_x(rtd->dev); + + return 0; +} + +/* CPU */ +static const struct test_adata test_cpu = { .is_cpu = 1, .cmp_v = 0, .dai_v = 0, }; +static const struct test_adata test_cpu_vv = { .is_cpu = 1, .cmp_v = 1, .dai_v = 1, }; +static const struct test_adata test_cpu_nv = { .is_cpu = 1, .cmp_v = 0, .dai_v = 1, }; +static const struct test_adata test_cpu_vn = { .is_cpu = 1, .cmp_v = 1, .dai_v = 0, }; +/* Codec */ +static const struct test_adata test_codec = { .is_cpu = 0, .cmp_v = 0, .dai_v = 0, }; +static const struct test_adata test_codec_vv = { .is_cpu = 0, .cmp_v = 1, .dai_v = 1, }; +static const struct test_adata test_codec_nv = { .is_cpu = 0, .cmp_v = 0, .dai_v = 1, }; +static const struct test_adata test_codec_vn = { .is_cpu = 0, .cmp_v = 1, .dai_v = 0, }; + +static const struct of_device_id test_of_match[] = { + { .compatible = "test-cpu", .data = (void *)&test_cpu, }, + { .compatible = "test-cpu-vv", .data = (void *)&test_cpu_vv, }, + { .compatible = "test-cpu-vn", .data = (void *)&test_cpu_vn, }, + { .compatible = "test-cpu-nv", .data = (void *)&test_cpu_nv, }, + { .compatible = "test-codec", .data = (void *)&test_codec, }, + { .compatible = "test-codec-vv", .data = (void *)&test_codec_vv, }, + { .compatible = "test-codec-vn", .data = (void *)&test_codec_vn, }, + { .compatible = "test-codec-nv", .data = (void *)&test_codec_nv, }, + {}, +}; +MODULE_DEVICE_TABLE(of, test_of_match); + +static const struct snd_soc_dapm_widget widgets[] = { + /* + * FIXME + * + * Just IN/OUT is OK for now, + * but need to be updated ? + */ + SND_SOC_DAPM_INPUT("IN"), + SND_SOC_DAPM_OUTPUT("OUT"), +}; + +static int test_driver_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *node = dev->of_node; + struct device_node *port; + const struct of_device_id *of_id = of_match_device(test_of_match, &pdev->dev); + const struct test_adata *adata = of_id->data; + struct snd_soc_component_driver *cdriv; + struct snd_soc_dai_driver *ddriv; + struct test_dai_name *dname; + struct test_priv *priv; + int num, ret, i; + + num = of_graph_get_port_count(node); + if (!num) { + dev_err(dev, "no port exits\n"); + return -EINVAL; + } + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + cdriv = devm_kzalloc(dev, sizeof(*cdriv), GFP_KERNEL); + ddriv = devm_kzalloc(dev, sizeof(*ddriv) * num, GFP_KERNEL); + dname = devm_kzalloc(dev, sizeof(*dname) * num, GFP_KERNEL); + if (!priv || !cdriv || !ddriv || !dname) + return -EINVAL; + + priv->dev = dev; + priv->component_driver = cdriv; + priv->dai_driver = ddriv; + priv->name = dname; + + INIT_DELAYED_WORK(&priv->dwork, test_component_dwork); + dev_set_drvdata(dev, priv); + + if (adata->is_cpu) { + cdriv->name = "test_cpu"; + cdriv->pcm_construct = test_component_pcm_construct; + cdriv->pointer = test_component_pointer; + cdriv->trigger = test_component_trigger; + } else { + cdriv->name = "test_codec"; + cdriv->idle_bias_on = 1; + cdriv->endianness = 1; + cdriv->non_legacy_dai_naming = 1; + } + + cdriv->open = test_component_open; + cdriv->dapm_widgets = widgets; + cdriv->num_dapm_widgets = ARRAY_SIZE(widgets); + + if (adata->cmp_v) { + cdriv->probe = test_component_probe; + cdriv->remove = test_component_remove; + cdriv->suspend = test_component_suspend; + cdriv->resume = test_component_resume; + cdriv->set_sysclk = test_component_set_sysclk; + cdriv->set_pll = test_component_set_pll; + cdriv->set_jack = test_component_set_jack; + cdriv->seq_notifier = test_component_seq_notifier; + cdriv->stream_event = test_component_stream_event; + cdriv->set_bias_level = test_component_set_bias_level; + cdriv->close = test_component_close; + cdriv->ioctl = test_component_ioctl; + cdriv->hw_params = test_component_hw_params; + cdriv->hw_free = test_component_hw_free; + cdriv->prepare = test_component_prepare; + cdriv->sync_stop = test_component_sync_stop; + cdriv->get_time_info = test_component_get_time_info; + cdriv->be_hw_params_fixup = test_component_be_hw_params_fixup; + + if (adata->is_cpu) + cdriv->pcm_destruct = test_component_pcm_destruct; + } + + i = 0; + for_each_port_of_node(node, port) { + snprintf(dname[i].name, TEST_NAME_LEN, "%s.%d", node->name, i); + ddriv[i].name = dname[i].name; + + snprintf(dname[i].name_playback, TEST_NAME_LEN, "DAI%d Playback", i); + ddriv[i].playback.stream_name = dname[i].name_playback; + ddriv[i].playback.channels_min = 1; + ddriv[i].playback.channels_max = 384; + ddriv[i].playback.rates = STUB_RATES; + ddriv[i].playback.formats = STUB_FORMATS; + + snprintf(dname[i].name_capture, TEST_NAME_LEN, "DAI%d Capture", i); + ddriv[i].capture.stream_name = dname[i].name_capture; + ddriv[i].capture.channels_min = 1; + ddriv[i].capture.channels_max = 384; + ddriv[i].capture.rates = STUB_RATES; + ddriv[i].capture.formats = STUB_FORMATS; + + if (adata->dai_v) + ddriv[i].ops = &test_verbose_ops; + else + ddriv[i].ops = &test_ops; + + i++; + } + + ret = devm_snd_soc_register_component(dev, cdriv, ddriv, num); + if (ret < 0) + return ret; + + mile_stone_x(dev); + + return 0; +} + +static int test_driver_remove(struct platform_device *pdev) +{ + mile_stone_x(&pdev->dev); + + return 0; +} + +static struct platform_driver test_driver = { + .driver = { + .name = "test-component", + .of_match_table = test_of_match, + }, + .probe = test_driver_probe, + .remove = test_driver_remove, +}; +module_platform_driver(test_driver); + +MODULE_ALIAS("platform:asoc-test-component"); +MODULE_AUTHOR("Kuninori Morimoto "); +MODULE_DESCRIPTION("ASoC Test Component"); +MODULE_LICENSE("GPL v2"); From patchwork Tue Jun 22 01:14:35 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kuninori Morimoto X-Patchwork-Id: 465938 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A12B4C4743C for ; Tue, 22 Jun 2021 01:16:35 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id C9B6060FD8 for ; Tue, 22 Jun 2021 01:16:34 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org C9B6060FD8 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=renesas.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org 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 75AC616AE; Tue, 22 Jun 2021 03:15:43 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 75AC616AE DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1624324593; bh=JyFjV984f2d2MOfITi8dgfEiInUYw6Rvz0f5awjrZZA=; h=Date:From:Subject:To:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=ixvz7VOsHYWqX2M4DethtQntwOYbJWaPVlUYpFXoa4B+/64w9/L2b1ikBeYjImHdy yO1b9LTKItZljCRdEJtoVJ8AO8HLpv3uuNIvh0WoS/1WojRWjixJa6O8lZiW8gfYQ+ LIn73NYIbHH1QtpU9yLzetbHkiGE2avDdR4XmEXE= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 28CBAF804E7; Tue, 22 Jun 2021 03:14:41 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id E2FEDF804EB; Tue, 22 Jun 2021 03:14:39 +0200 (CEST) Received: from relmlie5.idc.renesas.com (relmlor1.renesas.com [210.160.252.171]) by alsa1.perex.cz (Postfix) with ESMTP id 43A4FF804E6 for ; Tue, 22 Jun 2021 03:14:37 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 43A4FF804E6 Date: 22 Jun 2021 10:14:35 +0900 X-IronPort-AV: E=Sophos;i="5.83,290,1616425200"; d="scan'208";a="85109224" Received: from unknown (HELO relmlir5.idc.renesas.com) ([10.200.68.151]) by relmlie5.idc.renesas.com with ESMTP; 22 Jun 2021 10:14:35 +0900 Received: from mercury.renesas.com (unknown [10.166.252.133]) by relmlir5.idc.renesas.com (Postfix) with ESMTP id 8B6FD400D0CE; Tue, 22 Jun 2021 10:14:35 +0900 (JST) Message-ID: <87v9663dl0.wl-kuninori.morimoto.gx@renesas.com> From: Kuninori Morimoto Subject: [PATCH RFC 04/15] ASoC: simple-card-utils: add asoc_graph_is_ports0() User-Agent: Wanderlust/2.15.9 Emacs/26.3 Mule/6.0 To: Mark Brown , Rob Herring In-Reply-To: <871r8u4s6q.wl-kuninori.morimoto.gx@renesas.com> References: <871r8u4s6q.wl-kuninori.morimoto.gx@renesas.com> MIME-Version: 1.0 (generated by SEMI-EPG 1.14.7 - "Harue") Cc: Linux-ALSA 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" From: Kuninori Morimoto audio-graph-card2 will support DPCM/Multi/Codec2Codec, and these will use almost same DT settings which uses ports0 and ports1. This patch adds asoc_graph_is_ports0() which checks port is under port0 or not. Signed-off-by: Kuninori Morimoto --- include/sound/simple_card_utils.h | 1 + sound/soc/generic/simple-card-utils.c | 28 +++++++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/include/sound/simple_card_utils.h b/include/sound/simple_card_utils.h index 51b3b485a92e..520559b0a336 100644 --- a/include/sound/simple_card_utils.h +++ b/include/sound/simple_card_utils.h @@ -180,6 +180,7 @@ int asoc_simple_init_priv(struct asoc_simple_priv *priv, int asoc_simple_remove(struct platform_device *pdev); int asoc_graph_card_probe(struct snd_soc_card *card); +int asoc_graph_is_ports0(struct device_node *port); #ifdef DEBUG static inline void asoc_simple_debug_dai(struct asoc_simple_priv *priv, diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c index 677f7da93b4b..31802b15afd4 100644 --- a/sound/soc/generic/simple-card-utils.c +++ b/sound/soc/generic/simple-card-utils.c @@ -759,6 +759,34 @@ int asoc_graph_card_probe(struct snd_soc_card *card) } EXPORT_SYMBOL_GPL(asoc_graph_card_probe); +int asoc_graph_is_ports0(struct device_node *np) +{ + struct device_node *port, *ports, *ports0, *top; + int ret; + + /* np is "endpoint" or "port" */ + if (of_node_name_eq(np, "endpoint")) { + port = of_get_parent(np); + } else { + port = np; + of_node_get(port); + } + + ports = of_get_parent(port); + top = of_get_parent(ports); + ports0 = of_get_child_by_name(top, "ports"); + + ret = ports0 == ports; + + of_node_put(port); + of_node_put(ports); + of_node_put(ports0); + of_node_put(top); + + return ret; +} +EXPORT_SYMBOL_GPL(asoc_graph_is_ports0); + /* Module information */ MODULE_AUTHOR("Kuninori Morimoto "); MODULE_DESCRIPTION("ALSA SoC Simple Card Utils"); From patchwork Tue Jun 22 01:14:42 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kuninori Morimoto X-Patchwork-Id: 465204 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-10.9 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNWANTED_LANGUAGE_BODY, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B6649C4743C for ; Tue, 22 Jun 2021 01:17:12 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 3B61560FD8 for ; Tue, 22 Jun 2021 01:17:12 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 3B61560FD8 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=renesas.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org 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 C91D91692; Tue, 22 Jun 2021 03:16:20 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz C91D91692 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1624324630; bh=8JQ+cih0tQrJDhHK1hnYfW2zv5YiefI2MuB8SzUJOeQ=; h=Date:From:Subject:To:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=mF0UoAilz7Hz9WPAML7Zp/nPq/Y/w8ZVgnyzh0nYjt7BDXimr+dRV6vdUGzQ2Hioh 4K9v8RkmmLMG3ANyIVokfPZfpIApDtalkXO9jYGQuZFtFf62BZPMaz0quY4E0WRvky PQC/d+oWU00SuWtC4Fphcg24U8Y5m+fgPAyUVfhs= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 714B2F804FC; Tue, 22 Jun 2021 03:14:48 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 4BAF1F804F3; Tue, 22 Jun 2021 03:14:46 +0200 (CEST) Received: from relmlie6.idc.renesas.com (relmlor2.renesas.com [210.160.252.172]) by alsa1.perex.cz (Postfix) with ESMTP id 853D0F804F3 for ; Tue, 22 Jun 2021 03:14:43 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 853D0F804F3 Date: 22 Jun 2021 10:14:42 +0900 X-IronPort-AV: E=Sophos;i="5.83,290,1616425200"; d="scan'208";a="84989912" Received: from unknown (HELO relmlir5.idc.renesas.com) ([10.200.68.151]) by relmlie6.idc.renesas.com with ESMTP; 22 Jun 2021 10:14:42 +0900 Received: from mercury.renesas.com (unknown [10.166.252.133]) by relmlir5.idc.renesas.com (Postfix) with ESMTP id 2A0B3400D0CE; Tue, 22 Jun 2021 10:14:42 +0900 (JST) Message-ID: <87tulq3dkt.wl-kuninori.morimoto.gx@renesas.com> From: Kuninori Morimoto Subject: [PATCH RFC 05/15] ASoC: simple-card-utils: add codec2codec support User-Agent: Wanderlust/2.15.9 Emacs/26.3 Mule/6.0 To: Mark Brown , Rob Herring In-Reply-To: <871r8u4s6q.wl-kuninori.morimoto.gx@renesas.com> References: <871r8u4s6q.wl-kuninori.morimoto.gx@renesas.com> MIME-Version: 1.0 (generated by SEMI-EPG 1.14.7 - "Harue") Cc: Linux-ALSA 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" From: Kuninori Morimoto codec2codec needs snd_soc_pcm_stream settings. This patch adds it. Signed-off-by: Kuninori Morimoto --- include/sound/simple_card_utils.h | 3 +++ sound/soc/generic/simple-card-utils.c | 18 +++++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/include/sound/simple_card_utils.h b/include/sound/simple_card_utils.h index 520559b0a336..51f287220348 100644 --- a/include/sound/simple_card_utils.h +++ b/include/sound/simple_card_utils.h @@ -42,6 +42,7 @@ struct prop_nums { int cpus; int codecs; int platforms; + int c2c; }; struct asoc_simple_priv { @@ -54,6 +55,7 @@ struct asoc_simple_priv { struct snd_soc_dai_link_component *platforms; struct asoc_simple_data adata; struct snd_soc_codec_conf *codec_conf; + struct snd_soc_pcm_stream *c2c_conf; struct prop_nums num; unsigned int mclk_fs; } *dai_props; @@ -64,6 +66,7 @@ struct asoc_simple_priv { struct snd_soc_dai_link_component *dlcs; struct snd_soc_dai_link_component dummy; struct snd_soc_codec_conf *codec_conf; + struct snd_soc_pcm_stream *c2c_conf; struct gpio_desc *pa_gpio; const struct snd_soc_ops *ops; unsigned int dpcm_selectable:1; diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c index 31802b15afd4..16a545201f88 100644 --- a/sound/soc/generic/simple-card-utils.c +++ b/sound/soc/generic/simple-card-utils.c @@ -619,7 +619,8 @@ int asoc_simple_init_priv(struct asoc_simple_priv *priv, struct asoc_simple_dai *dais; struct snd_soc_dai_link_component *dlcs; struct snd_soc_codec_conf *cconf = NULL; - int i, dai_num = 0, dlc_num = 0, cnf_num = 0; + struct snd_soc_pcm_stream *c2c_conf = NULL; + int i, dai_num = 0, dlc_num = 0, cnf_num = 0, c2c_num = 0; dai_props = devm_kcalloc(dev, li->link, sizeof(*dai_props), GFP_KERNEL); dai_link = devm_kcalloc(dev, li->link, sizeof(*dai_link), GFP_KERNEL); @@ -638,6 +639,8 @@ int asoc_simple_init_priv(struct asoc_simple_priv *priv, if (!li->num[i].cpus) cnf_num += li->num[i].codecs; + + c2c_num += li->num[i].c2c; } dais = devm_kcalloc(dev, dai_num, sizeof(*dais), GFP_KERNEL); @@ -651,6 +654,12 @@ int asoc_simple_init_priv(struct asoc_simple_priv *priv, return -ENOMEM; } + if (c2c_num) { + c2c_conf = devm_kcalloc(dev, c2c_num, sizeof(*c2c_conf), GFP_KERNEL); + if (!c2c_conf) + return -ENOMEM; + } + dev_dbg(dev, "link %d, dais %d, ccnf %d\n", li->link, dai_num, cnf_num); @@ -664,6 +673,7 @@ int asoc_simple_init_priv(struct asoc_simple_priv *priv, priv->dais = dais; priv->dlcs = dlcs; priv->codec_conf = cconf; + priv->c2c_conf = c2c_conf; card->dai_link = priv->dai_link; card->num_links = li->link; @@ -681,6 +691,12 @@ int asoc_simple_init_priv(struct asoc_simple_priv *priv, dlcs += li->num[i].cpus; dais += li->num[i].cpus; + + if (li->num[i].c2c) { + /* Codec2Codec */ + dai_props[i].c2c_conf = c2c_conf; + c2c_conf += li->num[i].c2c; + } } else { /* DPCM Be's CPU = dummy */ dai_props[i].cpus = From patchwork Tue Jun 22 01:14:55 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kuninori Morimoto X-Patchwork-Id: 465937 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B7854C4743C for ; Tue, 22 Jun 2021 01:17:25 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 3BA2F60FD8 for ; Tue, 22 Jun 2021 01:17:25 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 3BA2F60FD8 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=renesas.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org 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 D9C1A168E; Tue, 22 Jun 2021 03:16:33 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz D9C1A168E DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1624324643; bh=GDwhixedS0tZCWS0b097D5NP94+OK/Sp6Y5Sg0/EmmY=; h=Date:From:Subject:To:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=EJro9Mj/PFQCuAmD0hH78QlRaDRtYIHIdNAZn5PcPNJTylRPwVvBtvsymi4u7eNrM bbe1pR0mz6Jk1uje8XqClzwIybk3sebw5tmn3BjuODUNuvbtWkV3nWVSPQJXBytAtA VyH5bxAGvXbDA3SDz3Bb7ACwY22tSMpn3Xn6hnng= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 35477F80111; Tue, 22 Jun 2021 03:15:06 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 756DFF804D8; Tue, 22 Jun 2021 03:15:04 +0200 (CEST) Received: from relmlie5.idc.renesas.com (relmlor1.renesas.com [210.160.252.171]) by alsa1.perex.cz (Postfix) with ESMTP id 6C4F6F80111 for ; Tue, 22 Jun 2021 03:14:56 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 6C4F6F80111 Date: 22 Jun 2021 10:14:55 +0900 X-IronPort-AV: E=Sophos;i="5.83,290,1616425200"; d="scan'208";a="85109250" Received: from unknown (HELO relmlir6.idc.renesas.com) ([10.200.68.152]) by relmlie5.idc.renesas.com with ESMTP; 22 Jun 2021 10:14:55 +0900 Received: from mercury.renesas.com (unknown [10.166.252.133]) by relmlir6.idc.renesas.com (Postfix) with ESMTP id DD3AD4148A7D; Tue, 22 Jun 2021 10:14:55 +0900 (JST) Message-ID: <87sg1a3dkg.wl-kuninori.morimoto.gx@renesas.com> From: Kuninori Morimoto Subject: [PATCH RFC 06/15] ASoC: audio-graph-card2: add Audio Graph Card2 driver User-Agent: Wanderlust/2.15.9 Emacs/26.3 Mule/6.0 MIME-Version: 1.0 (generated by SEMI-EPG 1.14.7 - "Harue") To: Mark Brown , Rob Herring In-Reply-To: <871r8u4s6q.wl-kuninori.morimoto.gx@renesas.com> References: <871r8u4s6q.wl-kuninori.morimoto.gx@renesas.com> Cc: Linux-ALSA 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" From: Kuninori Morimoto We already have audio-graph-card which is Of-graph base of general sound card driver. It is also supporting DPCM connection, but was forcibly expanded. Thus, it is very difficult to add new features on it, for example Multi CPU/Codec support, Codec2Codec support, etc. This patch adds more flexible new Audio Graph Card2 driver for it. audio-graph-card and audio-graph-card2 are similar, but don't have full compatibility. Difference between audio-graph-card and audio-graph-card2 are - audio-graph-card used "dais" to indicate DAI-links, audio-graph-card2 uses "links" to it. - audio-graph-card used "phandle" to indicate bitclock/frame-master, audio-graph-card2 uses flag to it. - audio-graph-card used "format" to indicate DAI format, audio-graph-card2 assumes CPU/Codec drivers have .get_fmt support. Audio Graph Card2 supports very generic connection, but some users want to have its own settings, for example PLL settings, etc. For such case, it has customizing support. In users own driver, it can use Audio Graph Card2 parsing by using asoc_graph_parse_of2(), and doing its own customizing. Because Audio Graph Card2 is still under experimental stage, it will indicate such warning when probing, and the DT syntax might be changed. Link: https://lore.kernel.org/r/87k0xszlep.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Kuninori Morimoto --- include/sound/graph_card.h | 15 + sound/soc/generic/Kconfig | 8 + sound/soc/generic/Makefile | 2 + sound/soc/generic/audio-graph-card2.c | 659 ++++++++++++++++++++++++++ 4 files changed, 684 insertions(+) create mode 100644 sound/soc/generic/audio-graph-card2.c diff --git a/include/sound/graph_card.h b/include/sound/graph_card.h index 6f10bfb0d5ee..b3185783caa7 100644 --- a/include/sound/graph_card.h +++ b/include/sound/graph_card.h @@ -9,6 +9,21 @@ #include +typedef int (*GRAPH_CUSTOM)(struct asoc_simple_priv *priv, + struct device_node *lnk, + struct link_info *li); + +struct graph_custom_hooks { + int (*hook_pre)(struct asoc_simple_priv *priv); + int (*hook_post)(struct asoc_simple_priv *priv); + GRAPH_CUSTOM custom_normal; +}; + int audio_graph_parse_of(struct asoc_simple_priv *priv, struct device *dev); +int audio_graph2_parse_of(struct asoc_simple_priv *priv, struct device *dev, + struct graph_custom_hooks *hooks); + +int audio_graph2_link_normal(struct asoc_simple_priv *priv, + struct device_node *lnk, struct link_info *li); #endif /* __GRAPH_CARD_H */ diff --git a/sound/soc/generic/Kconfig b/sound/soc/generic/Kconfig index bb734780669e..3385c488cd85 100644 --- a/sound/soc/generic/Kconfig +++ b/sound/soc/generic/Kconfig @@ -18,6 +18,14 @@ config SND_AUDIO_GRAPH_CARD with OF-graph DT bindings. It also support DPCM of multi CPU single Codec ststem. +config SND_AUDIO_GRAPH_CARD2 + tristate "ASoC Audio Graph Sound Card2 support" + depends on OF + select SND_SIMPLE_CARD_UTILS + help + This option enables generic simple sound card support + with OF-graph DT bindings. + config SND_TEST_COMPONENT tristate "ASoC Test component sound support" depends on OF diff --git a/sound/soc/generic/Makefile b/sound/soc/generic/Makefile index 988bfd45d2e2..b480f47a330d 100644 --- a/sound/soc/generic/Makefile +++ b/sound/soc/generic/Makefile @@ -2,9 +2,11 @@ snd-soc-simple-card-utils-objs := simple-card-utils.o snd-soc-simple-card-objs := simple-card.o snd-soc-audio-graph-card-objs := audio-graph-card.o +snd-soc-audio-graph-card2-objs := audio-graph-card2.o snd-soc-test-component-objs := test-component.o obj-$(CONFIG_SND_SIMPLE_CARD_UTILS) += snd-soc-simple-card-utils.o obj-$(CONFIG_SND_SIMPLE_CARD) += snd-soc-simple-card.o obj-$(CONFIG_SND_AUDIO_GRAPH_CARD) += snd-soc-audio-graph-card.o +obj-$(CONFIG_SND_AUDIO_GRAPH_CARD2) += snd-soc-audio-graph-card2.o obj-$(CONFIG_SND_TEST_COMPONENT) += snd-soc-test-component.o diff --git a/sound/soc/generic/audio-graph-card2.c b/sound/soc/generic/audio-graph-card2.c new file mode 100644 index 000000000000..f5edf1368e12 --- /dev/null +++ b/sound/soc/generic/audio-graph-card2.c @@ -0,0 +1,659 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// ASoC Audio Graph Sound Card2 support +// +// Copyright (C) 2020 Renesas Solutions Corp. +// Kuninori Morimoto +// +// based on ${LINUX}/sound/soc/generic/audio-graph-card.c +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/************************************ + daifmt + ************************************ + ports { + format = "left_j"; + port@0 { + bitclock-master; + sample0: endpoint@0 { + frame-master; + }; + sample1: endpoint@1 { + format = "i2s"; + }; + }; + ... + }; + + You can set daifmt at ports/port/endpoint. + It uses *latest* format, and *share* master settings. + In above case, + sample0: left_j, bitclock-master, frame-master + sample1: i2s, bitclock-master + + NOTE is that card2 is assuming to use .get_fmt. + + If there was no settings, *Codec* will be + bitclock/frame master as default. + see + graph_parse_daifmt(). + + ************************************ + Normal Audio-Graph + ************************************ + + CPU <---> Codec + + sound { + compatible = "audio-graph-card2"; + links = <&cpu>; + }; + + CPU { + cpu: port { + bitclock-master; + frame-master; + cpu_ep: endpoint { remote-endpoint = <&codec_ep>; }; }; + }; + + Codec { + port { codec_ep: endpoint { remote-endpoint = <&cpu_ep>; }; }; + }; + +*/ + +enum graph_type { + GRAPH_NORMAL, +}; + +#define port_to_endpoint(port) of_get_child_by_name(port, "endpoint") + +static enum graph_type graph_get_type(struct asoc_simple_priv *priv, + struct device_node *link) +{ + struct device_node *top; + const char *string; + enum graph_type type = GRAPH_NORMAL; + int ret; + + /* link is port or ports */ + top = of_get_parent(link); + if (of_node_name_eq(top, "ports")) { + of_node_put(top); + top = of_get_parent(top); + } + + ret = of_property_read_string(top, "compatible", &string); + if (ret < 0) + goto end; + +end: +#ifdef DEBUG + { + const char *str = "Normal"; + + dev_dbg(dev, "%pOF (%s)", link, str); + } +#endif + of_node_put(top); + + return type; +} + +static const struct snd_soc_ops graph_ops = { + .startup = asoc_simple_startup, + .shutdown = asoc_simple_shutdown, + .hw_params = asoc_simple_hw_params, +}; + +static int graph_get_dai_id(struct device_node *ep) +{ + struct device_node *node; + struct device_node *endpoint; + struct of_endpoint info; + int i, id; + const u32 *reg; + int ret; + + /* use driver specified DAI ID if exist */ + ret = snd_soc_get_dai_id(ep); + if (ret != -ENOTSUPP) + return ret; + + /* use endpoint/port reg if exist */ + ret = of_graph_parse_endpoint(ep, &info); + if (ret == 0) { + /* + * Because it will count port/endpoint if it doesn't have "reg". + * But, we can't judge whether it has "no reg", or "reg = <0>" + * only of_graph_parse_endpoint(). + * We need to check "reg" property + */ + if (of_get_property(ep, "reg", NULL)) + return info.id; + + node = of_get_parent(ep); + reg = of_get_property(node, "reg", NULL); + of_node_put(node); + if (reg) + return info.port; + } + node = of_graph_get_port_parent(ep); + + /* + * Non HDMI sound case, counting port/endpoint on its DT + * is enough. Let's count it. + */ + i = 0; + id = -1; + for_each_endpoint_of_node(node, endpoint) { + if (endpoint == ep) + id = i; + i++; + } + + of_node_put(node); + + if (id < 0) + return -ENODEV; + + return id; +} + +static int asoc_simple_parse_dai(struct device_node *ep, + struct snd_soc_dai_link_component *dlc, + int *is_single_link) +{ + struct device_node *node; + struct of_phandle_args args; + int ret; + + if (!ep) + return 0; + + node = of_graph_get_port_parent(ep); + + /* Get dai->name */ + args.np = node; + args.args[0] = graph_get_dai_id(ep); + args.args_count = (of_graph_get_endpoint_count(node) > 1); + + /* + * FIXME + * + * Here, dlc->dai_name is pointer to CPU/Codec DAI name. + * If user unbinded CPU or Codec driver, but not for Sound Card, + * dlc->dai_name is keeping unbinded CPU or Codec + * driver's pointer. + * + * If user re-bind CPU or Codec driver again, ALSA SoC will try + * to rebind Card via snd_soc_try_rebind_card(), but because of + * above reason, it might can't bind Sound Card. + * Because Sound Card is pointing to released dai_name pointer. + * + * To avoid this rebind Card issue, + * 1) It needs to alloc memory to keep dai_name eventhough + * CPU or Codec driver was unbinded, or + * 2) user need to rebind Sound Card everytime + * if he unbinded CPU or Codec. + */ + ret = snd_soc_get_dai_name(&args, &dlc->dai_name); + if (ret < 0) + return ret; + + dlc->of_node = node; + + if (is_single_link) + *is_single_link = of_graph_get_endpoint_count(node) == 1; + + return 0; +} + +static void graph_parse_mclk_fs(struct device_node *ep, + struct simple_dai_props *props) +{ + struct device_node *port = of_get_parent(ep); + struct device_node *ports = of_get_parent(port); + + if (of_node_name_eq(ports, "ports")) + of_property_read_u32(ports, "mclk-fs", &props->mclk_fs); + of_property_read_u32(port, "mclk-fs", &props->mclk_fs); + of_property_read_u32(ep, "mclk-fs", &props->mclk_fs); + + of_node_put(port); + of_node_put(ports); +} + +static int graph_dai_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_dai *dai; + struct device *dev = rtd->dev; + int i; + + /* + * Indicate assumption for a while. + * It will be removed. + */ + for_each_rtd_dais(rtd, i, dai) + if (!dai->driver->ops || + !dai->driver->ops->auto_selectable_formats) { + dev_warn_once(dev, "audio-graph-card2 is assuming " + "DAI driver (%s) has .auto_selectable_formats\n", dai->name); + break; + } + + return asoc_simple_dai_init(rtd); +} + +static int graph_parse_node(struct asoc_simple_priv *priv, + struct device_node *ep, + struct link_info *li, + int idx, int *cpu) +{ + struct device *dev = simple_priv_to_dev(priv); + struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link); + struct simple_dai_props *dai_props = simple_priv_to_props(priv, li->link); + struct snd_soc_dai_link_component *dlc; + struct asoc_simple_dai *dai; + int ret; + + if (cpu) { + dlc = asoc_link_to_cpu(dai_link, idx); + dai = simple_props_to_dai_cpu(dai_props, idx); + } else { + dlc = asoc_link_to_codec(dai_link, idx); + dai = simple_props_to_dai_codec(dai_props, idx); + } + + graph_parse_mclk_fs(ep, dai_props); + + ret = asoc_simple_parse_dai(ep, dlc, cpu); + if (ret < 0) + return ret; + + ret = asoc_simple_parse_tdm(ep, dai); + if (ret < 0) + return ret; + + ret = asoc_simple_parse_clk(dev, ep, dai, dlc); + if (ret < 0) + return ret; + + return 0; +} + +static void graph_parse_daifmt(struct device_node *node, + unsigned int *daifmt, unsigned int *bit_frame) +{ + unsigned int fmt; + + /* + * see also above "daifmt" explanation + * and samples. + */ + + /* + * ports { + * (A) + * port { + * (B) + * endpoint { + * (C) + * }; + * }; + * }; + * }; + */ + + /* + * clock_provider: + * + * It can be judged it is provider + * if (A) or (B) or (C) has bitclock-master / frame-master flag. + * + * use "or" + */ + *bit_frame |= snd_soc_daifmt_parse_clock_provider_as_bitmap(node, NULL); + +#define update_daifmt(name) \ + if (!(*daifmt & SND_SOC_DAIFMT_##name##_MASK) && \ + (fmt & SND_SOC_DAIFMT_##name##_MASK)) \ + *daifmt |= fmt & SND_SOC_DAIFMT_##name##_MASK; + + /* + * format + * + * This function is called by (C) -> (B) -> (A) order. + * Set if applicable part was not yet set. + */ + fmt = snd_soc_daifmt_parse_format(node, NULL); + update_daifmt(FORMAT); + update_daifmt(CLOCK); + update_daifmt(INV); +} + +static int graph_link_init(struct asoc_simple_priv *priv, + struct device_node *ep, + struct link_info *li, + int is_cpu_node, + char *name) +{ + struct device *dev = simple_priv_to_dev(priv); + struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link); + struct device_node *port = of_get_parent(ep); + struct device_node *ports = of_get_parent(port); + unsigned int daifmt = 0, daiclk = 0; + unsigned int bit_frame = 0; + + /* + * ports { + * (A) + * port { + * (B) + * endpoint { + * (C) + * }; + * }; + * }; + * }; + */ + graph_parse_daifmt(ep, &daifmt, &bit_frame); /* (C) */ + graph_parse_daifmt(port, &daifmt, &bit_frame); /* (B) */ + if (of_node_name_eq(ports, "ports")) + graph_parse_daifmt(ports, &daifmt, &bit_frame); /* (A) */ + + /* + * convert bit_frame + * We need to flip clock_provider if it was CPU node, + * because it is Codec base. + */ + daiclk = snd_soc_daifmt_clock_provider_from_bitmap(bit_frame); + if (is_cpu_node) + daiclk = snd_soc_daifmt_clock_provider_fliped(daiclk); + + if (daifmt) + dev_warn(dev, "don't use format. implemente .set_fmt instead (%pOFf)\n", port); + + dai_link->dai_fmt = daifmt | daiclk; + dai_link->init = graph_dai_init; + dai_link->ops = &graph_ops; + if (priv->ops) + dai_link->ops = priv->ops; + + return asoc_simple_set_dailink_name(dev, dai_link, name); +} + +int audio_graph2_link_normal(struct asoc_simple_priv *priv, + struct device_node *lnk, + struct link_info *li) +{ + struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link); + struct device_node *cpu_port = lnk; + struct device_node *cpu_ep = port_to_endpoint(cpu_port); + struct device_node *codec_ep = of_graph_get_remote_endpoint(cpu_ep); + struct snd_soc_dai_link_component *cpus = asoc_link_to_cpu(dai_link, 0); + struct snd_soc_dai_link_component *codecs = asoc_link_to_codec(dai_link, 0); + char dai_name[64]; + int ret, is_single_links = 0; + + ret = graph_parse_node(priv, cpu_ep, li, 0, &is_single_links); + if (ret < 0) + goto err; + + ret = graph_parse_node(priv, codec_ep, li, 0, NULL); + if (ret < 0) + goto err; + + snprintf(dai_name, sizeof(dai_name), + "%s-%s", cpus->dai_name, codecs->dai_name); + + asoc_simple_canonicalize_cpu(cpus, is_single_links); + + ret = graph_link_init(priv, cpu_ep, li, 1, dai_name); + if (ret < 0) + goto err; + +err: + of_node_put(cpu_ep); + of_node_put(codec_ep); + + return ret; +} +EXPORT_SYMBOL_GPL(audio_graph2_link_normal); + +static int graph_link(struct asoc_simple_priv *priv, + struct graph_custom_hooks *hooks, + enum graph_type gtype, + struct device_node *lnk, + struct link_info *li) +{ + struct device *dev = simple_priv_to_dev(priv); + GRAPH_CUSTOM func = NULL; + int ret = -EINVAL; + + switch (gtype) { + case GRAPH_NORMAL: + if (hooks && hooks->custom_normal) + func = hooks->custom_normal; + else + func = audio_graph2_link_normal; + break; + } + + if (!func) { + dev_err(dev, "non supported gtype (%d)\n", gtype); + goto err; + } + + ret = func(priv, lnk, li); + if (ret < 0) + goto err; + + li->link++; +err: + return ret; +} + +static int graph_count_normal(struct asoc_simple_priv *priv, + struct device_node *lnk, + struct link_info *li) +{ + /* + * CPU { + * => lnk: port { endpoint { .. }; }; + * }; + */ + li->num[li->link].cpus = 1; + li->num[li->link].codecs = 1; + + return 0; +} + +static int graph_count(struct asoc_simple_priv *priv, + struct graph_custom_hooks *hooks, + enum graph_type gtype, + struct device_node *lnk, + struct link_info *li) +{ + struct device *dev = simple_priv_to_dev(priv); + GRAPH_CUSTOM func = NULL; + int ret = -EINVAL; + + if (li->link >= SNDRV_MAX_LINKS) { + dev_err(dev, "too many links\n"); + return ret; + } + + switch (gtype) { + case GRAPH_NORMAL: + func = graph_count_normal; + break; + } + + if (!func) { + dev_err(dev, "non supported gtype (%d)\n", gtype); + goto err; + } + + ret = func(priv, lnk, li); + if (ret < 0) + goto err; + + li->link++; +err: + return ret; +} + +static int graph_for_each_link(struct asoc_simple_priv *priv, + struct graph_custom_hooks *hooks, + struct link_info *li, + int (*func)(struct asoc_simple_priv *priv, + struct graph_custom_hooks *hooks, + enum graph_type gtype, + struct device_node *lnk, + struct link_info *li)) +{ + struct of_phandle_iterator it; + struct device *dev = simple_priv_to_dev(priv); + struct device_node *node = dev->of_node; + struct device_node *lnk; + enum graph_type gtype; + int rc, ret; + + /* loop for all listed CPU port */ + of_for_each_phandle(&it, rc, node, "links", NULL, 0) { + lnk = it.node; + + gtype = graph_get_type(priv, lnk); + + ret = func(priv, hooks, gtype, lnk, li); + if (ret < 0) + return ret; + } + + return 0; +} + +int audio_graph2_parse_of(struct asoc_simple_priv *priv, struct device *dev, + struct graph_custom_hooks *hooks) +{ + struct snd_soc_card *card = simple_priv_to_card(priv); + struct link_info *li; + int ret; + + dev_warn(dev, "Audio Graph Card2 is still under Experimental stage\n"); + + li = devm_kzalloc(dev, sizeof(*li), GFP_KERNEL); + if (!li) + return -ENOMEM; + + card->probe = asoc_graph_card_probe; + card->owner = THIS_MODULE; + card->dev = dev; + + if ((hooks) && (hooks)->hook_pre) { + ret = (hooks)->hook_pre(priv); + if (ret < 0) + goto err; + } + + ret = graph_for_each_link(priv, hooks, li, graph_count); + if (!li->link) + ret = -EINVAL; + if (ret < 0) + goto err; + + ret = asoc_simple_init_priv(priv, li); + if (ret < 0) + goto err; + + priv->pa_gpio = devm_gpiod_get_optional(dev, "pa", GPIOD_OUT_LOW); + if (IS_ERR(priv->pa_gpio)) { + ret = PTR_ERR(priv->pa_gpio); + dev_err(dev, "failed to get amplifier gpio: %d\n", ret); + goto err; + } + + ret = asoc_simple_parse_widgets(card, NULL); + if (ret < 0) + goto err; + + ret = asoc_simple_parse_routing(card, NULL); + if (ret < 0) + goto err; + + memset(li, 0, sizeof(*li)); + ret = graph_for_each_link(priv, hooks, li, graph_link); + if (ret < 0) + goto err; + + ret = asoc_simple_parse_card_name(card, NULL); + if (ret < 0) + goto err; + + snd_soc_card_set_drvdata(card, priv); + + if ((hooks) && (hooks)->hook_post) { + ret = (hooks)->hook_post(priv); + if (ret < 0) + goto err; + } + + asoc_simple_debug_info(priv); + + ret = devm_snd_soc_register_card(dev, card); +err: + devm_kfree(dev, li); + + if ((ret < 0) && (ret != -EPROBE_DEFER)) + dev_err(dev, "parse error %d\n", ret); + + return ret; +} +EXPORT_SYMBOL_GPL(audio_graph2_parse_of); + +static int graph_probe(struct platform_device *pdev) +{ + struct asoc_simple_priv *priv; + struct device *dev = &pdev->dev; + + /* Allocate the private data and the DAI link array */ + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + return audio_graph2_parse_of(priv, dev, NULL); +} + +static const struct of_device_id graph_of_match[] = { + { .compatible = "audio-graph-card2", }, + {}, +}; +MODULE_DEVICE_TABLE(of, graph_of_match); + +static struct platform_driver graph_card = { + .driver = { + .name = "asoc-audio-graph-card2", + .pm = &snd_soc_pm_ops, + .of_match_table = graph_of_match, + }, + .probe = graph_probe, + .remove = asoc_simple_remove, +}; +module_platform_driver(graph_card); + +MODULE_ALIAS("platform:asoc-audio-graph-card2"); +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("ASoC Audio Graph Sound Card2"); +MODULE_AUTHOR("Kuninori Morimoto "); From patchwork Tue Jun 22 01:15:06 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kuninori Morimoto X-Patchwork-Id: 465203 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4EAEBC4743C for ; Tue, 22 Jun 2021 01:17:55 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id C272B6124B for ; Tue, 22 Jun 2021 01:17:54 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org C272B6124B Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=renesas.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org 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 318D3826; Tue, 22 Jun 2021 03:17:03 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 318D3826 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1624324673; bh=OvQoMrFel7/HTM0Fzubjz8c8orULZ8ZIj3s9GEqN9iM=; h=Date:From:Subject:To:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=B05v55F0antt6CQyXPunwUby5ilGd1nZO6tckDoDOgVeZA9jhXVNinbRe0SjACoYI pp6JP6cSmT5FYmUs5QaiT80Hqt9M16McUsKFRUjlxQeH3/fpeHc27WeuSBKyOCt+dc S51FH8ZruSyefmcy2h//07EqUiE0dAdUDqeeSa54= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 397E4F804D2; Tue, 22 Jun 2021 03:15:15 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 57F63F804DA; Tue, 22 Jun 2021 03:15:14 +0200 (CEST) Received: from relmlie5.idc.renesas.com (relmlor1.renesas.com [210.160.252.171]) by alsa1.perex.cz (Postfix) with ESMTP id 8BB76F804D2 for ; Tue, 22 Jun 2021 03:15:07 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 8BB76F804D2 Date: 22 Jun 2021 10:15:06 +0900 X-IronPort-AV: E=Sophos;i="5.83,290,1616425200"; d="scan'208";a="85109276" Received: from unknown (HELO relmlir6.idc.renesas.com) ([10.200.68.152]) by relmlie5.idc.renesas.com with ESMTP; 22 Jun 2021 10:15:06 +0900 Received: from mercury.renesas.com (unknown [10.166.252.133]) by relmlir6.idc.renesas.com (Postfix) with ESMTP id 66E5E4149817; Tue, 22 Jun 2021 10:15:06 +0900 (JST) Message-ID: <87r1gu3dk5.wl-kuninori.morimoto.gx@renesas.com> From: Kuninori Morimoto Subject: [PATCH RFC 07/15] ASoC: audio-graph-card2: add DPCM support User-Agent: Wanderlust/2.15.9 Emacs/26.3 Mule/6.0 To: Mark Brown , Rob Herring In-Reply-To: <871r8u4s6q.wl-kuninori.morimoto.gx@renesas.com> References: <871r8u4s6q.wl-kuninori.morimoto.gx@renesas.com> MIME-Version: 1.0 (generated by SEMI-EPG 1.14.7 - "Harue") Cc: Linux-ALSA 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" From: Kuninori Morimoto This patch adds DPCM support to audio-graph-card2. The big difference between audio-graph-card2 DPCM and audio-graph-card DPCM is that audio-graph-card2 uses extra node (X) for it. ******* PCM0 <--> * * <--> DAI0: Codec Headset PCM1 <--> * * <--> DAI1: Codec Speakers PCM2 <--> * DSP * <--> DAI2: MODEM PCM3 <--> * * <--> DAI3: BT * * <--> DAI4: DMIC * * <--> DAI5: FM ******* sound { compatible = "audio-graph-card2"; // indicate routing (A) routing = "xxx Playback", "xxx Playback", "xxx Playback", "xxx Playback", "xxx Playback", "xxx Playback"; // indicate all Front-End, Back-End in DPCM case (B) links = <&dsp_fe0, &dsp_fe1, &dsp_fe2, &dsp_fe3, &dsp_be0, &dsp_be1, &dsp_be2, &dsp_be3, &dsp_be4, &dsp_be5>; }; (X) DSP { compatible = "audio-graph-card2-dsp"; // Front-End ports@0 { (B) dsp_fe0: port@0 { dsp_fe0_ep: endpoint { remote-endpoint = <&pcm0_ep>; }; }; dsp_fe1: port@1 { dsp_fe1_ep: endpoint { remote-endpoint = <&pcm1_ep>; }; }; ... }; // Back-End ports@1 { (B) dsp_be0: port@0 { dsp_be0_ep: endpoint { remote-endpoint = <&dai0_ep>; }; }; dsp_be1: port@1 { dsp_be1_ep: endpoint { remote-endpoint = <&dai1_ep>; }; }; ... }; CPU { ports { bitclock-master; frame-master; port@0 { pcm0_ep: endpoint { remote-endpoint = <&dsp_fe0_ep>; }; }; port@1 { pcm1_ep: endpoint { remote-endpoint = <&dsp_fe1_ep>; }; }; ... }; }; Codec { ports { port@0 { dai0_ep: endpoint { remote-endpoint = <&dsp_be0_ep>; }; }; port@1 { dai1_ep: endpoint { remote-endpoint = <&dsp_be1_ep>; }; }; ... }; }; It needs to add routing (A) when DPCM case. "links" needs to indicate both Front-End and Back-End (B), instead of CPU/Codec node. Signed-off-by: Kuninori Morimoto --- include/sound/graph_card.h | 3 + sound/soc/generic/audio-graph-card2.c | 259 +++++++++++++++++++++++++- 2 files changed, 261 insertions(+), 1 deletion(-) diff --git a/include/sound/graph_card.h b/include/sound/graph_card.h index b3185783caa7..03df4c5a7151 100644 --- a/include/sound/graph_card.h +++ b/include/sound/graph_card.h @@ -17,6 +17,7 @@ struct graph_custom_hooks { int (*hook_pre)(struct asoc_simple_priv *priv); int (*hook_post)(struct asoc_simple_priv *priv); GRAPH_CUSTOM custom_normal; + GRAPH_CUSTOM custom_dpcm; }; int audio_graph_parse_of(struct asoc_simple_priv *priv, struct device *dev); @@ -25,5 +26,7 @@ int audio_graph2_parse_of(struct asoc_simple_priv *priv, struct device *dev, int audio_graph2_link_normal(struct asoc_simple_priv *priv, struct device_node *lnk, struct link_info *li); +int audio_graph2_link_dpcm(struct asoc_simple_priv *priv, + struct device_node *lnk, struct link_info *li); #endif /* __GRAPH_CARD_H */ diff --git a/sound/soc/generic/audio-graph-card2.c b/sound/soc/generic/audio-graph-card2.c index f5edf1368e12..b288975ffde2 100644 --- a/sound/soc/generic/audio-graph-card2.c +++ b/sound/soc/generic/audio-graph-card2.c @@ -71,12 +71,78 @@ port { codec_ep: endpoint { remote-endpoint = <&cpu_ep>; }; }; }; + + ************************************ + DSP Audio-Graph + ************************************ + + ******* + PCM0 <--> * * <--> DAI0: Codec Headset + PCM1 <--> * * <--> DAI1: Codec Speakers + PCM2 <--> * DSP * <--> DAI2: MODEM + PCM3 <--> * * <--> DAI3: BT + * * <--> DAI4: DMIC + * * <--> DAI5: FM + ******* + + sound { + compatible = "audio-graph-card2"; + + // indicate routing + routing = "xxx Playback", "xxx Playback", + "xxx Playback", "xxx Playback", + "xxx Playback", "xxx Playback"; + + // indicate all Front-End, Back-End in DPCM case + links = <&dsp_fe0, &dsp_fe1, &dsp_fe2, &dsp_fe3, + &dsp_be0, &dsp_be1, &dsp_be2, &dsp_be3, &dsp_be4, &dsp_be5>; + }; + + DSP { + compatible = "audio-graph-card2-dsp"; + + // Front-End + ports@0 { + dsp_fe0: port@0 { dsp_fe0_ep: endpoint { remote-endpoint = <&pcm0_ep>; }; }; + dsp_fe1: port@1 { dsp_fe1_ep: endpoint { remote-endpoint = <&pcm1_ep>; }; }; + ... + }; + + // Back-End + ports@1 { + dsp_be0: port@0 { dsp_be0_ep: endpoint { remote-endpoint = <&dai0_ep>; }; }; + dsp_be1: port@1 { dsp_be1_ep: endpoint { remote-endpoint = <&dai1_ep>; }; }; + ... + }; + ... + }; + + CPU { + ports { + bitclock-master; + frame-master; + port@0 { pcm0_ep: endpoint { remote-endpoint = <&dsp_fe0_ep>; }; }; + port@1 { pcm1_ep: endpoint { remote-endpoint = <&dsp_fe1_ep>; }; }; + ... + }; + }; + + Codec { + ports { + port@0 { dai0_ep: endpoint { remote-endpoint = <&dsp_be0_ep>; }; }; + port@1 { dai1_ep: endpoint { remote-endpoint = <&dsp_be1_ep>; }; }; + ... + }; + }; */ enum graph_type { GRAPH_NORMAL, + GRAPH_DPCM, }; +#define GRAPH_COMPATIBLE_DPCM "audio-graph-card2-dsp" + #define port_to_endpoint(port) of_get_child_by_name(port, "endpoint") static enum graph_type graph_get_type(struct asoc_simple_priv *priv, @@ -98,11 +164,24 @@ static enum graph_type graph_get_type(struct asoc_simple_priv *priv, if (ret < 0) goto end; + if (strcmp(string, GRAPH_COMPATIBLE_DPCM) == 0) + type = GRAPH_DPCM; end: #ifdef DEBUG { const char *str = "Normal"; - + struct device *dev = simple_priv_to_dev(priv); + + switch (type) { + case GRAPH_DPCM: + if (asoc_graph_is_ports0(link)) + str = "DPCM Front-End"; + else + str = "DPCM Back-End"; + break; + default: + break; + } dev_dbg(dev, "%pOF (%s)", link, str); } #endif @@ -220,6 +299,22 @@ static int asoc_simple_parse_dai(struct device_node *ep, return 0; } +static void graph_parse_convert(struct device_node *ep, + struct simple_dai_props *props) +{ + struct device_node *port = of_get_parent(ep); + struct device_node *ports = of_get_parent(port); + struct asoc_simple_data *adata = &props->adata; + + if (of_node_name_eq(ports, "ports")) + asoc_simple_parse_convert(ports, NULL, adata); + asoc_simple_parse_convert(port, NULL, adata); + asoc_simple_parse_convert(ep, NULL, adata); + + of_node_put(port); + of_node_put(ports); +} + static void graph_parse_mclk_fs(struct device_node *ep, struct simple_dai_props *props) { @@ -432,6 +527,128 @@ int audio_graph2_link_normal(struct asoc_simple_priv *priv, } EXPORT_SYMBOL_GPL(audio_graph2_link_normal); +int audio_graph2_link_dpcm(struct asoc_simple_priv *priv, + struct device_node *lnk, + struct link_info *li) +{ + struct device_node *ep = port_to_endpoint(lnk); + struct device_node *rep = of_graph_get_remote_endpoint(ep); + struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link); + struct simple_dai_props *dai_props = simple_priv_to_props(priv, li->link); + char dai_name[64]; + int is_cpu = asoc_graph_is_ports0(lnk); + int ret; + + if (is_cpu) { + struct snd_soc_dai_link_component *cpus = asoc_link_to_cpu(dai_link, 0); + int is_single_links = 0; + + /* + * DSP { + * compatible = "audio-graph-card2-dsp"; + * + * // Front-End + * ports@0 { + * => lnk: port@0 { ep: endpoint { remote-endpoint = <&rep>; }; }; + * ... + * }; + * // Back-End + * ports@0 { + * ... + * }; + * }; + * + * CPU { + * rports: ports { + * rport: port@0 { rep: endpoint { ... }; }; + * } + * } + */ + /* + * setup CPU here, Codec is already set as dummy. + * see + * asoc_simple_init_priv() + */ + dai_link->dynamic = 1; + dai_link->dpcm_merged_format = 1; + + ret = graph_parse_node(priv, rep, li, 0, &is_single_links); + if (ret) + goto err; + + snprintf(dai_name, sizeof(dai_name), + "fe.%pOFP.%s", cpus->of_node, cpus->dai_name); + + asoc_simple_canonicalize_cpu(cpus, is_single_links); + } else { + struct snd_soc_dai_link_component *codecs = asoc_link_to_codec(dai_link, 0); + struct snd_soc_codec_conf *cconf = simple_props_to_codec_conf(dai_props, 0); + struct device_node *rport; + struct device_node *rports; + + /* + * DSP { + * compatible = "audio-graph-card2-dsp"; + * + * // Front-End + * ports@0 { + * ... + * }; + * // Back-End + * ports@0 { + * => lnk: port@0 { ep: endpoint { remote-endpoint = <&rep>; }; }; + * ... + * }; + * }; + * + * Codec { + * rports: ports { + * rport: port@0 { rep: endpoint { ... }; }; + * } + * } + */ + /* + * setup Codec here, CPU is already set as dummy. + * see + * asoc_simple_init_priv() + */ + + /* BE settings */ + dai_link->no_pcm = 1; + dai_link->be_hw_params_fixup = asoc_simple_be_hw_params_fixup; + + ret = graph_parse_node(priv, rep, li, 0, NULL); + if (ret < 0) + goto err; + + snprintf(dai_name, sizeof(dai_name), + "be.%pOFP.%s", codecs->of_node, codecs->dai_name); + + /* check "prefix" from top node */ + rport = of_get_parent(rep); + rports = of_get_parent(rport); + + if (of_node_name_eq(rports, "ports")) + snd_soc_of_parse_node_prefix(rports, cconf, codecs->of_node, "prefix"); + snd_soc_of_parse_node_prefix(rport, cconf, codecs->of_node, "prefix"); + + of_node_put(rport); + of_node_put(rports); + } + + graph_parse_convert(rep, dai_props); + + snd_soc_dai_link_set_capabilities(dai_link); + + ret = graph_link_init(priv, rep, li, is_cpu, dai_name); +err: + of_node_put(ep); + of_node_put(rep); + + return ret; +} +EXPORT_SYMBOL_GPL(audio_graph2_link_dpcm); + static int graph_link(struct asoc_simple_priv *priv, struct graph_custom_hooks *hooks, enum graph_type gtype, @@ -449,6 +666,12 @@ static int graph_link(struct asoc_simple_priv *priv, else func = audio_graph2_link_normal; break; + case GRAPH_DPCM: + if (hooks && hooks->custom_dpcm) + func = hooks->custom_dpcm; + else + func = audio_graph2_link_dpcm; + break; } if (!func) { @@ -480,6 +703,37 @@ static int graph_count_normal(struct asoc_simple_priv *priv, return 0; } +static int graph_count_dsp(struct asoc_simple_priv *priv, + struct device_node *lnk, + struct link_info *li) +{ + /* + * DSP { + * compatible = "audio-graph-card2-dsp"; + * + * // Front-End + * ports@0 { + * => lnk: port@0 { endpoint { ... }; }; + * ... + * }; + * // Back-End + * ports@1 { + * => lnk: port@0 { endpoint { ... }; }; + * ... + * }; + * }; + */ + if (asoc_graph_is_ports0(lnk)) { + /* Front-End */ + li->num[li->link].cpus = 1; + } else { + /* Back-End */ + li->num[li->link].codecs = 1; + } + + return 0; +} + static int graph_count(struct asoc_simple_priv *priv, struct graph_custom_hooks *hooks, enum graph_type gtype, @@ -499,6 +753,9 @@ static int graph_count(struct asoc_simple_priv *priv, case GRAPH_NORMAL: func = graph_count_normal; break; + case GRAPH_DPCM: + func = graph_count_dsp; + break; } if (!func) { From patchwork Tue Jun 22 01:15:11 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kuninori Morimoto X-Patchwork-Id: 465936 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-10.9 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNWANTED_LANGUAGE_BODY, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6DF4EC4743C for ; Tue, 22 Jun 2021 01:18:21 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id E881C610C7 for ; Tue, 22 Jun 2021 01:18:20 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org E881C610C7 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=renesas.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org 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 87EBB168C; Tue, 22 Jun 2021 03:17:29 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 87EBB168C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1624324699; bh=T7p8KbodmMDouUik5+F8S3uG3i6ELViK+YzUm7BGMdQ=; h=Date:From:Subject:To:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=L7ZjV3JMe0cn2GmafyaSwyFs2fdVxmCJ5MjjzBs6QufBiuSEI1i5p6qTJQ8rm9AQg TJixMv4B540TJVt0rtdqG7UXPzCHM4y9GHvEbAhAaqAfDe6JzwSqae6gc7krzEQEdf XDfAvPw4jsPBU0MNjOPPtu1/I8Urs8rpCb0rUyXc= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id C2B3EF804D9; Tue, 22 Jun 2021 03:15:20 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 7DAD8F80517; Tue, 22 Jun 2021 03:15:19 +0200 (CEST) Received: from relmlie5.idc.renesas.com (relmlor1.renesas.com [210.160.252.171]) by alsa1.perex.cz (Postfix) with ESMTP id 52FB7F804D9 for ; Tue, 22 Jun 2021 03:15:12 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 52FB7F804D9 Date: 22 Jun 2021 10:15:11 +0900 X-IronPort-AV: E=Sophos;i="5.83,290,1616425200"; d="scan'208";a="85109292" Received: from unknown (HELO relmlir5.idc.renesas.com) ([10.200.68.151]) by relmlie5.idc.renesas.com with ESMTP; 22 Jun 2021 10:15:11 +0900 Received: from mercury.renesas.com (unknown [10.166.252.133]) by relmlir5.idc.renesas.com (Postfix) with ESMTP id E60B6400D0C5; Tue, 22 Jun 2021 10:15:11 +0900 (JST) Message-ID: <87pmwe3dk0.wl-kuninori.morimoto.gx@renesas.com> From: Kuninori Morimoto Subject: [PATCH RFC 08/15] ASoC: audio-graph-card2: add Multi CPU/Codec support User-Agent: Wanderlust/2.15.9 Emacs/26.3 Mule/6.0 To: Mark Brown , Rob Herring In-Reply-To: <871r8u4s6q.wl-kuninori.morimoto.gx@renesas.com> References: <871r8u4s6q.wl-kuninori.morimoto.gx@renesas.com> MIME-Version: 1.0 (generated by SEMI-EPG 1.14.7 - "Harue") Cc: Linux-ALSA 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" From: Kuninori Morimoto This patch adds Multi CPU/Codec support to audio-graph-card2. One note today is that ASoC doesn't support N CPUs to M CODECs (It supports "1 CPU to N Codecs" or "N CPUs to N Codecs"). Multi CPU/Codec support needs to have extra node (X) to indicate it. <- multi_CPU -> <-- multi_Codec --> ****** CPU1 <--> * * <--> Codec1 CPU2 <--> * * <--> Codec2 ****** sound { compatible = "audio-graph-card2"; (A) links = <&multi>; }; (X) multi_CPU_CODEC { compatible = "audio-graph-card2-multi"; /* for CPU */ (B) multi: ports@0 { port@0 { mcpu1_ep: endpoint { remote-endpoint = <&cpu1_ep>; }; }; port@1 { mcpu2_ep: endpoint { remote-endpoint = <&cpu2_ep>; }; }; /* for Codec */ ports@1 { port@0 { mcodec1_ep: endpoint { remote-endpoint = <&codec1_ep>; }; }; port@1 { mcodec2_ep: endpoint { remote-endpoint = <&codec2_ep>; }; }; }; }; CPU { ports { bitclock-master; frame-master; port@0 { cpu1_ep: endpoint { remote-endpoint = <&mcpu1_ep>; }; }; port@1 { cpu2_ep: endpoint { remote-endpoint = <&mcpu2_ep>; }; }; }; }; Codec { ports { port@0 { codec1_ep: endpoint { remote-endpoint = <&mcodec1_ep>; }; }; port@1 { codec2_ep: endpoint { remote-endpoint = <&mcodec2_ep>; }; }; }; }; "links" need to indicate Multi connection's CPU node (A)(B). Signed-off-by: Kuninori Morimoto --- include/sound/graph_card.h | 3 + sound/soc/generic/audio-graph-card2.c | 173 ++++++++++++++++++++++++++ 2 files changed, 176 insertions(+) diff --git a/include/sound/graph_card.h b/include/sound/graph_card.h index 03df4c5a7151..d0ccb7afda78 100644 --- a/include/sound/graph_card.h +++ b/include/sound/graph_card.h @@ -18,6 +18,7 @@ struct graph_custom_hooks { int (*hook_post)(struct asoc_simple_priv *priv); GRAPH_CUSTOM custom_normal; GRAPH_CUSTOM custom_dpcm; + GRAPH_CUSTOM custom_multi; }; int audio_graph_parse_of(struct asoc_simple_priv *priv, struct device *dev); @@ -28,5 +29,7 @@ int audio_graph2_link_normal(struct asoc_simple_priv *priv, struct device_node *lnk, struct link_info *li); int audio_graph2_link_dpcm(struct asoc_simple_priv *priv, struct device_node *lnk, struct link_info *li); +int audio_graph2_link_multi(struct asoc_simple_priv *priv, + struct device_node *lnk, struct link_info *li); #endif /* __GRAPH_CARD_H */ diff --git a/sound/soc/generic/audio-graph-card2.c b/sound/soc/generic/audio-graph-card2.c index b288975ffde2..ece0f7d28437 100644 --- a/sound/soc/generic/audio-graph-card2.c +++ b/sound/soc/generic/audio-graph-card2.c @@ -134,14 +134,66 @@ ... }; }; + + + ************************************ + Multi-CPU/Codec + ************************************ + +<- multi_CPU -> + <-- multi_Codec --> + ****** +CPU1 <--> * * <--> Codec1 +CPU2 <--> * * <--> Codec2 + ****** + *NOTE* + N cpus to M codecs is not yet supported + at ASoC framework for now. + + sound { + compatible = "audio-graph-card2"; + + links = <&multi>; + }; + + multi_CPU_CODEC { + compatible = "audio-graph-card2-multi"; + + multi: ports@0 { + port@0 { mcpu1_ep: endpoint { remote-endpoint = <&cpu1_ep>; }; }; + port@1 { mcpu2_ep: endpoint { remote-endpoint = <&cpu2_ep>; }; }; + }; + ports@1 { + port@0 { mcodec1_ep: endpoint { remote-endpoint = <&codec1_ep>; }; }; + port@1 { mcodec2_ep: endpoint { remote-endpoint = <&codec2_ep>; }; }; + }; +}; + + CPU { + ports { + bitclock-master; + frame-master; + port@0 { cpu1_ep: endpoint { remote-endpoint = <&mcpu1_ep>; }; }; + port@1 { cpu2_ep: endpoint { remote-endpoint = <&mcpu2_ep>; }; }; + }; + }; + + Codec { + ports { + port@0 { codec1_ep: endpoint { remote-endpoint = <&mcodec1_ep>; }; }; + port@1 { codec2_ep: endpoint { remote-endpoint = <&mcodec2_ep>; }; }; + }; + }; */ enum graph_type { GRAPH_NORMAL, GRAPH_DPCM, + GRAPH_MULTI, }; #define GRAPH_COMPATIBLE_DPCM "audio-graph-card2-dsp" +#define GRAPH_COMPATIBLE_MULTI "audio-graph-card2-multi" #define port_to_endpoint(port) of_get_child_by_name(port, "endpoint") @@ -166,6 +218,8 @@ static enum graph_type graph_get_type(struct asoc_simple_priv *priv, if (strcmp(string, GRAPH_COMPATIBLE_DPCM) == 0) type = GRAPH_DPCM; + else if (strcmp(string, GRAPH_COMPATIBLE_MULTI) == 0) + type = GRAPH_MULTI; end: #ifdef DEBUG { @@ -179,6 +233,9 @@ static enum graph_type graph_get_type(struct asoc_simple_priv *priv, else str = "DPCM Back-End"; break; + case GRAPH_MULTI: + str = "MULTI"; + break; default: break; } @@ -649,6 +706,78 @@ int audio_graph2_link_dpcm(struct asoc_simple_priv *priv, } EXPORT_SYMBOL_GPL(audio_graph2_link_dpcm); +int audio_graph2_link_multi(struct asoc_simple_priv *priv, + struct device_node *lnk, + struct link_info *li) +{ + struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link); + struct device_node *top = of_get_parent(lnk); + struct device_node *first_rep = NULL; + struct device_node *ports = lnk; + struct device_node *port; + char dai_name[64]; + int is_cpu = 1; + int i; + + /* + * top: MULTI { + * compatible = "audio-graph-card2-multi"; + * + * // CPU + * loop-0 ports@0 { + * port@0 { ep: endpoint { remote-endpoint = <&r_ep>; }; }; + * ... + * }; + * // Codec + * loop-1 ports@1 { + * ... + * }; + * }; + */ +ports_loop: + i = 0; + for_each_port_of_node(ports, port) { + struct device_node *ep = port_to_endpoint(port); + struct device_node *rep = of_graph_get_remote_endpoint(ep); + int ret, is_single_links = 0; + + if (!first_rep) + first_rep = rep; + + ret = graph_parse_node(priv, rep, li, i, + is_cpu ? &is_single_links : NULL); + + of_node_put(ep); + of_node_put(rep); + + if (ret < 0) + return ret; + + if (is_cpu) { + struct snd_soc_dai_link_component *cpus = asoc_link_to_cpu(dai_link, i); + + asoc_simple_canonicalize_cpu(cpus, is_single_links); + } + + i++; + } + + /* + * 1st turn was for CPU ports (is_cpu = 1) + * 2nd turn is for Codec ports (is_cpu = 0) + */ + is_cpu--; + if (is_cpu == 0) { + ports = of_get_next_child(top, ports); + goto ports_loop; + } + + snprintf(dai_name, sizeof(dai_name), "multi-%pOFP", top); + + return graph_link_init(priv, first_rep, li, 1, dai_name); +} +EXPORT_SYMBOL_GPL(audio_graph2_link_multi); + static int graph_link(struct asoc_simple_priv *priv, struct graph_custom_hooks *hooks, enum graph_type gtype, @@ -672,6 +801,12 @@ static int graph_link(struct asoc_simple_priv *priv, else func = audio_graph2_link_dpcm; break; + case GRAPH_MULTI: + if (hooks && hooks->custom_multi) + func = hooks->custom_multi; + else + func = audio_graph2_link_multi; + break; } if (!func) { @@ -734,6 +869,41 @@ static int graph_count_dsp(struct asoc_simple_priv *priv, return 0; } +static int graph_count_multi(struct asoc_simple_priv *priv, + struct device_node *lnk, + struct link_info *li) +{ + struct device_node *top = of_get_parent(lnk); + struct device_node *cpu_ports = lnk; + struct device_node *codec_ports = of_get_next_child(top, cpu_ports); + + of_node_get(cpu_ports); /* for vs of_get_next_child() */ + + /* + * MULTI { + * compatible = "audio-graph-card2-multi"; + * + * // CPU + * => lnk: ports@0 { + * port@0 { endpoint { ... }; }; + * ... + * }; + * // Codec + * ports@1 { + * port@0 { endpoint { ... }; }; + * ... + * }; + * }; + */ + li->num[li->link].cpus = of_graph_get_port_count(cpu_ports); + li->num[li->link].codecs = of_graph_get_port_count(codec_ports); + + of_node_put(top); + of_node_put(codec_ports); + + return 0; +} + static int graph_count(struct asoc_simple_priv *priv, struct graph_custom_hooks *hooks, enum graph_type gtype, @@ -756,6 +926,9 @@ static int graph_count(struct asoc_simple_priv *priv, case GRAPH_DPCM: func = graph_count_dsp; break; + case GRAPH_MULTI: + func = graph_count_multi; + break; } if (!func) { From patchwork Tue Jun 22 01:15:16 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kuninori Morimoto X-Patchwork-Id: 465202 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id CC673C4743C for ; Tue, 22 Jun 2021 01:18:40 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 4F74361289 for ; Tue, 22 Jun 2021 01:18:40 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 4F74361289 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=renesas.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org 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 E27ED16A0; Tue, 22 Jun 2021 03:17:48 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz E27ED16A0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1624324719; bh=uwkhH26eWwYsjTwgHeJxq4XCBTaCrHyjDJJV3Q07sCY=; h=Date:From:Subject:To:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=F4JaWvOOXS3ld9CGnvqMFbx9l7uZxsJl+IYooW+8UuZ2Bwe2RQJqyEvL+pupWKNUf Nj9/W7+i3fidKOtmkgtJek8shnoc4KJYqMj4fHNwxXSVkr+Gsi59QFnVs+EbemNVod tPRCT+HE54qdB97EigE8yLtaAu2SBWrjHtmLyaLA= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 9D9B6F8051A; Tue, 22 Jun 2021 03:15:22 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id B195BF80517; Tue, 22 Jun 2021 03:15:20 +0200 (CEST) Received: from relmlie5.idc.renesas.com (relmlor1.renesas.com [210.160.252.171]) by alsa1.perex.cz (Postfix) with ESMTP id 2AA23F8050F for ; Tue, 22 Jun 2021 03:15:16 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 2AA23F8050F Date: 22 Jun 2021 10:15:16 +0900 X-IronPort-AV: E=Sophos;i="5.83,290,1616425200"; d="scan'208";a="85109301" Received: from unknown (HELO relmlir5.idc.renesas.com) ([10.200.68.151]) by relmlie5.idc.renesas.com with ESMTP; 22 Jun 2021 10:15:16 +0900 Received: from mercury.renesas.com (unknown [10.166.252.133]) by relmlir5.idc.renesas.com (Postfix) with ESMTP id BCF4E400D0CE; Tue, 22 Jun 2021 10:15:16 +0900 (JST) Message-ID: <87o8by3djv.wl-kuninori.morimoto.gx@renesas.com> From: Kuninori Morimoto Subject: [PATCH RFC 09/15] ASoC: audio-graph-card2: add Codec2Codec support User-Agent: Wanderlust/2.15.9 Emacs/26.3 Mule/6.0 To: Mark Brown , Rob Herring In-Reply-To: <871r8u4s6q.wl-kuninori.morimoto.gx@renesas.com> References: <871r8u4s6q.wl-kuninori.morimoto.gx@renesas.com> MIME-Version: 1.0 (generated by SEMI-EPG 1.14.7 - "Harue") Cc: Linux-ALSA 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" From: Kuninori Morimoto This patch adds Codec2Codec support to audio-graph-card2. It can use Codec2Codec but very limited/simple case only for now. It doesn't have "SWITCH" control yet, thus it start automatically when probed, but can't stop, so far. Thus it needs to be updated around widgets/routing handling, and you need to understand that it is under experimental. It is assuming 2channel, S32_LE format for now. It needs to be updated, too. Codec2Codec support needs to have extra node (= X) to indicate it. Codec2Codec needs "routing" (= A) and "rate" (= C). "links" (= B) needs to indicate Codec2Codec's CPU part node (= D). +--+ | |<-- Codec0 | |--> Codec1 +--+ sound { compatible = "audio-graph-card2"; (A) routing = "OUT" ,"DAI1 Playback", "DAI0 Capture", "IN"; (B) links = <&codec2codec>; }; (X) CODEC2CODEC { compatible = "audio-graph-card2-codec2codec"; (C) rate = <48000>; ports { (D) codec2codec: port@0 { fe_ep: endpoint { remote-endpoint = <&codec0_ep>; }; }; port@1 { be_ep: endpoint { remote-endpoint = <&codec1_ep>; }; }; }; }; Codec { ports { port@0 { bitclock-master; frame-master; codec0_ep: endpoint { remote-endpoint = <&fe_ep>; }; }; port@1 { codec1_ep: endpoint { remote-endpoint = <&be_ep>; }; }; }; }; Signed-off-by: Kuninori Morimoto --- include/sound/graph_card.h | 3 + sound/soc/generic/audio-graph-card2.c | 164 ++++++++++++++++++++++++++ 2 files changed, 167 insertions(+) diff --git a/include/sound/graph_card.h b/include/sound/graph_card.h index d0ccb7afda78..e870ae133a15 100644 --- a/include/sound/graph_card.h +++ b/include/sound/graph_card.h @@ -19,6 +19,7 @@ struct graph_custom_hooks { GRAPH_CUSTOM custom_normal; GRAPH_CUSTOM custom_dpcm; GRAPH_CUSTOM custom_multi; + GRAPH_CUSTOM custom_c2c; }; int audio_graph_parse_of(struct asoc_simple_priv *priv, struct device *dev); @@ -31,5 +32,7 @@ int audio_graph2_link_dpcm(struct asoc_simple_priv *priv, struct device_node *lnk, struct link_info *li); int audio_graph2_link_multi(struct asoc_simple_priv *priv, struct device_node *lnk, struct link_info *li); +int audio_graph2_link_c2c(struct asoc_simple_priv *priv, + struct device_node *lnk, struct link_info *li); #endif /* __GRAPH_CARD_H */ diff --git a/sound/soc/generic/audio-graph-card2.c b/sound/soc/generic/audio-graph-card2.c index ece0f7d28437..2688b8d65e32 100644 --- a/sound/soc/generic/audio-graph-card2.c +++ b/sound/soc/generic/audio-graph-card2.c @@ -184,16 +184,58 @@ CPU2 <--> * * <--> Codec2 port@1 { codec2_ep: endpoint { remote-endpoint = <&mcodec2_ep>; }; }; }; }; + + + ************************************ + Codec to Codec + ************************************ + + +--+ + | |<-- Codec0 + | |--> Codec1 + +--+ + + sound { + compatible = "audio-graph-card2"; + + routing = "OUT" ,"DAI1 Playback", + "DAI0 Capture", "IN"; + + links = <&codec2codec>; + }; + + CODEC2CODEC { + compatible = "audio-graph-card2-codec2codec"; + + rate = <48000>; + ports { + codec2codec: port@0 { fe_ep: endpoint { remote-endpoint = <&codec0_ep>; }; }; + port@1 { be_ep: endpoint { remote-endpoint = <&codec1_ep>; }; }; + }; + }; + + Codec { + ports { + port@0 { + bitclock-master; + frame-master; + codec0_ep: endpoint { remote-endpoint = <&fe_ep>; }; }; + port@1 { codec1_ep: endpoint { remote-endpoint = <&be_ep>; }; }; + }; + }; + */ enum graph_type { GRAPH_NORMAL, GRAPH_DPCM, GRAPH_MULTI, + GRAPH_C2C, }; #define GRAPH_COMPATIBLE_DPCM "audio-graph-card2-dsp" #define GRAPH_COMPATIBLE_MULTI "audio-graph-card2-multi" +#define GRAPH_COMPATIBLE_C2C "audio-graph-card2-codec2codec" #define port_to_endpoint(port) of_get_child_by_name(port, "endpoint") @@ -220,6 +262,8 @@ static enum graph_type graph_get_type(struct asoc_simple_priv *priv, type = GRAPH_DPCM; else if (strcmp(string, GRAPH_COMPATIBLE_MULTI) == 0) type = GRAPH_MULTI; + else if (strcmp(string, GRAPH_COMPATIBLE_C2C) == 0) + type = GRAPH_C2C; end: #ifdef DEBUG { @@ -236,6 +280,9 @@ static enum graph_type graph_get_type(struct asoc_simple_priv *priv, case GRAPH_MULTI: str = "MULTI"; break; + case GRAPH_C2C: + str = "Codec2Codec"; + break; default: break; } @@ -778,6 +825,93 @@ int audio_graph2_link_multi(struct asoc_simple_priv *priv, } EXPORT_SYMBOL_GPL(audio_graph2_link_multi); +int audio_graph2_link_c2c(struct asoc_simple_priv *priv, + struct device_node *lnk, + struct link_info *li) +{ + struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link); + struct simple_dai_props *dai_props = simple_priv_to_props(priv, li->link); + struct snd_soc_pcm_stream *c2c_conf = dai_props->c2c_conf; + struct device_node *port = lnk; + struct device_node *ports = of_get_parent(port); + struct device_node *top = of_get_parent(ports); + struct device_node *ep; + struct device_node *rep; + struct device_node *first_rep = NULL; + char dai_name[64]; + u32 val; + int is_cpu; + int ret = -EINVAL; + + /* + * top: CODEC2CODEC { + * compatible = "audio-graph-card2-codec2codec"; + * + * rate = <48000>; + * ports { + * => lnk: port@0 { ep: endpoint { remote-endpoint = <&rep>; }; }; + * port@1 { ... }; + * }; + * }; + */ + if (!of_get_property(top, "rate", &val)) { + struct device *dev = simple_priv_to_dev(priv); + + dev_err(dev, "unknown codec2codec rate\n"); + goto err; + } + + c2c_conf->formats = SNDRV_PCM_FMTBIT_S32_LE; /* update ME */ + c2c_conf->rate_min = + c2c_conf->rate_max = val; + c2c_conf->channels_min = + c2c_conf->channels_max = 2; /* update ME */ + dai_link->params = c2c_conf; + + of_node_get(lnk); + for (is_cpu = 1; is_cpu >= 0; is_cpu--) { + int is_single_links = 0; + + ep = port_to_endpoint(port); + rep = of_graph_get_remote_endpoint(ep); + + if (!first_rep) + first_rep = rep; + + ret = graph_parse_node(priv, rep, li, 0, + is_cpu ? &is_single_links : NULL); + if (ret < 0) + goto err; + + of_node_put(ep); + of_node_put(rep); + + /* + * 1st turn was for CPU part of Codec (is_cpu = 1) + * 2nd turn is for Codec part of Codec (is_cpu = 0) + */ + if (is_cpu) { + struct snd_soc_dai_link_component *cpus = asoc_link_to_cpu(dai_link, 0); + + asoc_simple_canonicalize_cpu(cpus, is_single_links); + + /* next port = Codec part port */ + port = of_get_next_child(ports, port); + } + } + + snprintf(dai_name, sizeof(dai_name), "codec2codec-%pOFP", top); + + ret = graph_link_init(priv, first_rep, li, 0, dai_name); /* Codec base */ +err: + of_node_put(ports); + of_node_put(port); + of_node_put(top); + + return ret; +} +EXPORT_SYMBOL_GPL(audio_graph2_link_c2c); + static int graph_link(struct asoc_simple_priv *priv, struct graph_custom_hooks *hooks, enum graph_type gtype, @@ -807,6 +941,12 @@ static int graph_link(struct asoc_simple_priv *priv, else func = audio_graph2_link_multi; break; + case GRAPH_C2C: + if (hooks && hooks->custom_c2c) + func = hooks->custom_c2c; + else + func = audio_graph2_link_c2c; + break; } if (!func) { @@ -904,6 +1044,27 @@ static int graph_count_multi(struct asoc_simple_priv *priv, return 0; } +static int graph_count_c2c(struct asoc_simple_priv *priv, + struct device_node *lnk, + struct link_info *li) +{ + /* + * CODEC2CODEC { + * compatible = "audio-graph-card2-codec2codec"; + * + * ports { + * => lnk: port@0 { endpoint { ... }; }; + * port@1 { endpoint { ... }; }; + * }; + * }; + */ + li->num[li->link].cpus = 1; + li->num[li->link].codecs = 1; + li->num[li->link].c2c = 1; + + return 0; +} + static int graph_count(struct asoc_simple_priv *priv, struct graph_custom_hooks *hooks, enum graph_type gtype, @@ -929,6 +1090,9 @@ static int graph_count(struct asoc_simple_priv *priv, case GRAPH_MULTI: func = graph_count_multi; break; + case GRAPH_C2C: + func = graph_count_c2c; + break; } if (!func) { From patchwork Tue Jun 22 01:15:21 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kuninori Morimoto X-Patchwork-Id: 465935 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4DB34C4743C for ; Tue, 22 Jun 2021 01:19:03 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id C421B610C7 for ; Tue, 22 Jun 2021 01:19:02 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org C421B610C7 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=renesas.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org 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 6526316AB; Tue, 22 Jun 2021 03:18:11 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 6526316AB DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1624324741; bh=hvO1M56M6EtTG7vVgCl714E11oI/JaW85rzS/nOe0wQ=; h=Date:From:Subject:To:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=Ptgv1RjY6L++PR93xWRLBkOIPFNU6ManpNeI2KfROogDNTiJsNsLAn79R1ICRUHJU CoI+m6Kmkr2wkuMNb8hHIMbGaiXiupjt/YBSwah94+wAW2922UfXTEpv/dsYfZeS+p kBoK8GR4xpfPwy2ahGVWZXl/nLxgIJSt1d0fxPkk= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 33158F80515; Tue, 22 Jun 2021 03:15:30 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 48D2FF8051E; Tue, 22 Jun 2021 03:15:29 +0200 (CEST) Received: from relmlie6.idc.renesas.com (relmlor2.renesas.com [210.160.252.172]) by alsa1.perex.cz (Postfix) with ESMTP id E6F80F80518 for ; Tue, 22 Jun 2021 03:15:22 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz E6F80F80518 Date: 22 Jun 2021 10:15:21 +0900 X-IronPort-AV: E=Sophos;i="5.83,290,1616425200"; d="scan'208";a="84989975" Received: from unknown (HELO relmlir5.idc.renesas.com) ([10.200.68.151]) by relmlie6.idc.renesas.com with ESMTP; 22 Jun 2021 10:15:21 +0900 Received: from mercury.renesas.com (unknown [10.166.252.133]) by relmlir5.idc.renesas.com (Postfix) with ESMTP id 68A98400D0C5; Tue, 22 Jun 2021 10:15:21 +0900 (JST) Message-ID: <87mtri3djq.wl-kuninori.morimoto.gx@renesas.com> From: Kuninori Morimoto Subject: [PATCH RFC 10/15] ASoC: audio-graph-card2: add Yaml Document User-Agent: Wanderlust/2.15.9 Emacs/26.3 Mule/6.0 To: Mark Brown , Rob Herring In-Reply-To: <871r8u4s6q.wl-kuninori.morimoto.gx@renesas.com> References: <871r8u4s6q.wl-kuninori.morimoto.gx@renesas.com> MIME-Version: 1.0 (generated by SEMI-EPG 1.14.7 - "Harue") Cc: Linux-ALSA 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" From: Kuninori Morimoto This patch adds Audio Graph Card2 Yaml bindings. It is similar to Audio Graph Card, but different. - audio-graph-card used "dais" to indicate DAI-links, audio-graph-card2 uses "links" to it. - audio-graph-card used "phandle" to indicate bitclock/frame-master, audio-graph-card2 uses flag to it. - audio-graph-card used "format" to indicate DAI format, audio-graph-card2 assumes CPU/Codec drivers have .get_fmt support. Signed-off-by: Kuninori Morimoto --- .../sound/audio-graph-card2-items.yaml | 36 +++++++++ .../bindings/sound/audio-graph-card2.yaml | 45 +++++++++++ .../bindings/sound/audio-graph-port2.yaml | 74 +++++++++++++++++++ 3 files changed, 155 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/audio-graph-card2-items.yaml create mode 100644 Documentation/devicetree/bindings/sound/audio-graph-card2.yaml create mode 100644 Documentation/devicetree/bindings/sound/audio-graph-port2.yaml diff --git a/Documentation/devicetree/bindings/sound/audio-graph-card2-items.yaml b/Documentation/devicetree/bindings/sound/audio-graph-card2-items.yaml new file mode 100644 index 000000000000..40439f78df60 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/audio-graph-card2-items.yaml @@ -0,0 +1,36 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/audio-graph-card2-items.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Audio Graph Card2 Items Bindings + +maintainers: + - Kuninori Morimoto + +properties: + compatible: + enum: + - audio-graph-card2-dsp + - audio-graph-card2-multi + - audio-graph-card2-codec2codec + +required: + - compatible + +additionalProperties: true + +examples: + - | + mix { + compatible = "audio-graph-card2-dsp"; + }; + + multi { + compatible = "audio-graph-card2-multi"; + }; + + codec2codec { + compatible = "audio-graph-card2-codec2codec"; + }; diff --git a/Documentation/devicetree/bindings/sound/audio-graph-card2.yaml b/Documentation/devicetree/bindings/sound/audio-graph-card2.yaml new file mode 100644 index 000000000000..b5908ef144c1 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/audio-graph-card2.yaml @@ -0,0 +1,45 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/audio-graph-card2.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Audio Graph Card2 Device Tree Bindings + +maintainers: + - Kuninori Morimoto + +properties: + compatible: + enum: + - audio-graph-card2 + links: + $ref: /schemas/types.yaml#/definitions/phandle-array + routing: + description: | + A list of the connections between audio components. + Each entry is a pair of strings, the first being the + connection's sink, the second being the connection's source. + $ref: /schemas/types.yaml#/definitions/non-unique-string-array + +required: + - compatible + - links + +unevaluatedProperties: false + +examples: + - | + sound { + compatible = "audio-graph-card2"; + + links = <&cpu_port>; + }; + + cpu { + cpu_port: port { cpu_ep: endpoint { remote-endpoint = <&codec_ep>; }; }; + }; + + codec { + port { codec_ep: endpoint { remote-endpoint = <&cpu_ep>; }; }; + }; diff --git a/Documentation/devicetree/bindings/sound/audio-graph-port2.yaml b/Documentation/devicetree/bindings/sound/audio-graph-port2.yaml new file mode 100644 index 000000000000..0a7753a140bf --- /dev/null +++ b/Documentation/devicetree/bindings/sound/audio-graph-port2.yaml @@ -0,0 +1,74 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/audio-graph-port.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Audio Graph Card2 'port' Node Bindings + +maintainers: + - Kuninori Morimoto + +select: false + +properties: + port: + description: single OF-Graph subnode + type: object + properties: + reg: + maxItems: 1 + prefix: + description: "device name prefix" + $ref: /schemas/types.yaml#/definitions/string + convert-rate: + description: CPU to Codec rate convert. + $ref: /schemas/types.yaml#/definitions/uint32 + convert-channels: + description: CPU to Codec rate channels. + $ref: /schemas/types.yaml#/definitions/uint32 + mclk-fs: + description: | + Multiplication factor between stream rate and codec mclk. + When defined, mclk-fs property defined in dai-link sub nodes are + ignored. + $ref: /schemas/types.yaml#/definitions/uint32 + patternProperties: + "^endpoint(@[0-9a-f]+)?": + type: object + properties: + remote-endpoint: + maxItems: 1 + mclk-fs: + description: | + Multiplication factor between stream rate and codec mclk. + When defined, mclk-fs property defined in dai-link sub nodes are + ignored. + $ref: /schemas/types.yaml#/definitions/uint32 + frame-inversion: + description: dai-link uses frame clock inversion + $ref: /schemas/types.yaml#/definitions/flag + bitclock-inversion: + description: dai-link uses bit clock inversion + $ref: /schemas/types.yaml#/definitions/flag + frame-master: + description: Indicates dai-link frame master. + $ref: /schemas/types.yaml#/definitions/flag + bitclock-master: + description: Indicates dai-link bit clock master + $ref: /schemas/types.yaml#/definitions/flag + convert-rate: + description: CPU to Codec rate convert. + $ref: /schemas/types.yaml#/definitions/uint32 + convert-channels: + description: CPU to Codec rate channels. + $ref: /schemas/types.yaml#/definitions/uint32 + + ports: + description: multi OF-Graph subnode + type: object + patternProperties: + "^port(@[0-9a-f]+)?": + $ref: "#/properties/port" + +additionalProperties: true From patchwork Tue Jun 22 01:15:25 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kuninori Morimoto X-Patchwork-Id: 465201 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-10.9 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNWANTED_LANGUAGE_BODY, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 157A5C4743C for ; Tue, 22 Jun 2021 01:19:22 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 8F3A2610C7 for ; Tue, 22 Jun 2021 01:19:21 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 8F3A2610C7 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=renesas.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org 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 2C7A716AE; Tue, 22 Jun 2021 03:18:30 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 2C7A716AE DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1624324760; bh=pdah/ldGsBecmTkWhtML23PC1NjKwElQ7Trnhsa7/pc=; h=Date:From:Subject:To:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=HxwNf29lm3Lu3kRfW4LICle+pHGOz3TQDwykdw5hQeV4hXOL9+1EHfoGj0yJxNSKe 7SW7r3Urgdrnx/S2hM1iVvwqYXWvZN7rm9Qco6sRKDOAqbnu8b4Lw+47ZzpkSfiods CCf8xWYIMcxEIGDkcqKc7xgiTcIZCJUd8tzZW75E= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id A7174F8051D; Tue, 22 Jun 2021 03:15:30 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 6FC55F8051D; Tue, 22 Jun 2021 03:15:29 +0200 (CEST) Received: from relmlie6.idc.renesas.com (relmlor2.renesas.com [210.160.252.172]) by alsa1.perex.cz (Postfix) with ESMTP id F2B2CF8016A for ; Tue, 22 Jun 2021 03:15:25 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz F2B2CF8016A Date: 22 Jun 2021 10:15:25 +0900 X-IronPort-AV: E=Sophos;i="5.83,290,1616425200"; d="scan'208";a="84989987" Received: from unknown (HELO relmlir5.idc.renesas.com) ([10.200.68.151]) by relmlie6.idc.renesas.com with ESMTP; 22 Jun 2021 10:15:25 +0900 Received: from mercury.renesas.com (unknown [10.166.252.133]) by relmlir5.idc.renesas.com (Postfix) with ESMTP id 91B04400D0CE; Tue, 22 Jun 2021 10:15:25 +0900 (JST) Message-ID: <87lf723djm.wl-kuninori.morimoto.gx@renesas.com> From: Kuninori Morimoto Subject: [PATCH RFC 11/15] ASoC: sample-custom-card: add Audio Graph Card2 custome sample User-Agent: Wanderlust/2.15.9 Emacs/26.3 Mule/6.0 To: Mark Brown , Rob Herring In-Reply-To: <871r8u4s6q.wl-kuninori.morimoto.gx@renesas.com> References: <871r8u4s6q.wl-kuninori.morimoto.gx@renesas.com> MIME-Version: 1.0 (generated by SEMI-EPG 1.14.7 - "Harue") Cc: Linux-ALSA 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" From: Kuninori Morimoto One of audio-graph-card issue was that it can't handle *user own* card settings. We can expand audio-graph-card if it was *generic* feature. Latest audio-graph-card has customizing support. Audio Graph Card2 also have customize support. This means user can use its own special settings by using audio-graph-card2 driver parsing. This patch adds Audio Graph Cars2 customize sample driver. It can get basic audio-graph-card2 setups by calling asoc_graph_parse_of2(...), and user can update/expand each own setting on it. Signed-off-by: Kuninori Morimoto --- sound/soc/generic/Kconfig | 6 + sound/soc/generic/Makefile | 2 + sound/soc/generic/sample-custom-card.c | 160 +++++++++++++++++++++++++ 3 files changed, 168 insertions(+) create mode 100644 sound/soc/generic/sample-custom-card.c diff --git a/sound/soc/generic/Kconfig b/sound/soc/generic/Kconfig index 3385c488cd85..c7cd0488e4fc 100644 --- a/sound/soc/generic/Kconfig +++ b/sound/soc/generic/Kconfig @@ -26,6 +26,12 @@ config SND_AUDIO_GRAPH_CARD2 This option enables generic simple sound card support with OF-graph DT bindings. +config SND_SAMPLE_CUSTOM_CARD + tristate "ASoC Audio Graph Sound Card2 base custom card sample support" + depends on OF && SND_AUDIO_GRAPH_CARD2 + help + This option enables Audio Graph Sound Card2 base custom card support + config SND_TEST_COMPONENT tristate "ASoC Test component sound support" depends on OF diff --git a/sound/soc/generic/Makefile b/sound/soc/generic/Makefile index b480f47a330d..1b438202609c 100644 --- a/sound/soc/generic/Makefile +++ b/sound/soc/generic/Makefile @@ -3,10 +3,12 @@ snd-soc-simple-card-utils-objs := simple-card-utils.o snd-soc-simple-card-objs := simple-card.o snd-soc-audio-graph-card-objs := audio-graph-card.o snd-soc-audio-graph-card2-objs := audio-graph-card2.o +snd-soc-sample-custom-card-objs := sample-custom-card.o snd-soc-test-component-objs := test-component.o obj-$(CONFIG_SND_SIMPLE_CARD_UTILS) += snd-soc-simple-card-utils.o obj-$(CONFIG_SND_SIMPLE_CARD) += snd-soc-simple-card.o obj-$(CONFIG_SND_AUDIO_GRAPH_CARD) += snd-soc-audio-graph-card.o obj-$(CONFIG_SND_AUDIO_GRAPH_CARD2) += snd-soc-audio-graph-card2.o +obj-$(CONFIG_SND_SAMPLE_CUSTOM_CARD) += snd-soc-sample-custom-card.o obj-$(CONFIG_SND_TEST_COMPONENT) += snd-soc-test-component.o diff --git a/sound/soc/generic/sample-custom-card.c b/sound/soc/generic/sample-custom-card.c new file mode 100644 index 000000000000..e7b321fb5db9 --- /dev/null +++ b/sound/soc/generic/sample-custom-card.c @@ -0,0 +1,160 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// sample-custom-card.c +// +// Copyright (c) 2020 Kuninori Morimoto +// +#include +#include +#include +#include + +/* + * Custom driver can have own priv + * which includes asoc_simple_priv. + */ +struct custom_priv { + struct asoc_simple_priv simple_priv; + + /* custom driver's own params */ + int custom_params; +}; + +/* You can get custom_priv from simple_priv */ +#define simple_to_custom(simple) container_of((simple), struct custom_priv, simple_priv) + +static int custom_card_probe(struct snd_soc_card *card) +{ + struct asoc_simple_priv *simple_priv = snd_soc_card_get_drvdata(card); + struct custom_priv *custom_priv = simple_to_custom(simple_priv); + struct device *dev = simple_priv_to_dev(simple_priv); + + dev_info(dev, "custom probe\n"); + + custom_priv->custom_params = 1; + + /* you can use generic probe function */ + return asoc_graph_card_probe(card); +} + +static int custom_hook_pre(struct asoc_simple_priv *priv) +{ + struct device *dev = simple_priv_to_dev(priv); + + /* You can custom before parsing */ + dev_info(dev, "hook : %s\n", __func__); + + return 0; +} + +static int custom_hook_post(struct asoc_simple_priv *priv) +{ + struct device *dev = simple_priv_to_dev(priv); + struct snd_soc_card *card; + + /* You can custom after parsing */ + dev_info(dev, "hook : %s\n", __func__); + + card = simple_priv_to_card(priv); + card->probe = custom_card_probe; /* overwrite .probe */ + + return 0; +} + +static int custom_dpcm(struct asoc_simple_priv *priv, + struct device_node *lnk, + struct link_info *li) +{ + struct device *dev = simple_priv_to_dev(priv); + + /* You can custom for DPCM parsing */ + dev_info(dev, "hook : %s\n", __func__); + + return audio_graph2_link_dpcm(priv, lnk, li); +} + +static int custom_c2c(struct asoc_simple_priv *priv, + struct device_node *lnk, + struct link_info *li) +{ + struct device *dev = simple_priv_to_dev(priv); + + /* You can custom for Codec2Codec parsing */ + dev_info(dev, "hook : %s\n", __func__); + + return audio_graph2_link_c2c(priv, lnk, li); +} + +/* + * audio-graph-card2 has many hooks for your customizing. + */ +static struct graph_custom_hooks custom_hooks = { + .hook_pre = custom_hook_pre, + .hook_post = custom_hook_post, + .custom_dpcm = custom_dpcm, + .custom_c2c = custom_c2c, + /* and more ... */ +}; + +static int custom_startup(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct asoc_simple_priv *priv = snd_soc_card_get_drvdata(rtd->card); + struct device *dev = simple_priv_to_dev(priv); + + dev_info(dev, "custom startup\n"); + + return asoc_simple_startup(substream); +} + +/* You can use custom ops */ +static const struct snd_soc_ops custom_ops = { + .startup = custom_startup, + .shutdown = asoc_simple_shutdown, + .hw_params = asoc_simple_hw_params, +}; + +static int custom_probe(struct platform_device *pdev) +{ + struct custom_priv *custom_priv; + struct asoc_simple_priv *simple_priv; + struct device *dev = &pdev->dev; + int ret; + + custom_priv = devm_kzalloc(dev, sizeof(*custom_priv), GFP_KERNEL); + if (!custom_priv) + return -ENOMEM; + + simple_priv = &custom_priv->simple_priv; + simple_priv->ops = &custom_ops; /* customize dai_link ops */ + + /* use audio-graph-card2 parsing with own custom hooks */ + ret = audio_graph2_parse_of(simple_priv, dev, &custom_hooks); + if (ret < 0) + return ret; + + /* customize more if needed */ + + return 0; +} + +static const struct of_device_id custom_of_match[] = { + { .compatible = "sample-custom-card", }, + {}, +}; +MODULE_DEVICE_TABLE(of, custom_of_match); + +static struct platform_driver custom_card = { + .driver = { + .name = "sample-custom-card", + .of_match_table = custom_of_match, + }, + .probe = custom_probe, + .remove = asoc_simple_remove, +}; +module_platform_driver(custom_card); + +MODULE_ALIAS("platform:asoc-sample-custom-card"); +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("ASoC Audio Graph Sound Card2 Custom"); +MODULE_AUTHOR("Kuninori Morimoto "); From patchwork Tue Jun 22 01:15:29 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kuninori Morimoto X-Patchwork-Id: 465934 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 89844C4743C for ; Tue, 22 Jun 2021 01:19:56 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id B56A2610C7 for ; Tue, 22 Jun 2021 01:19:55 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org B56A2610C7 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=renesas.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org 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 510BB16AA; Tue, 22 Jun 2021 03:19:04 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 510BB16AA DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1624324794; bh=KR/8ZrfmrPFXYl7mjVmSK7VrUotsVWa2YfW2a1q65u0=; h=Date:From:Subject:To:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=uHm70iP7PiccF3yxluOIyUM+WYFtyHfUsttqTFEvmNbkshh+LSQS+72ul/NREeJV4 NLpM34pyym7uyrE7758CfvmgCe5S3Q4TWvM3FncuUnLDyKSrmPmapPrxHHRvbNSMIn XhcgrcEt+Z+n92hi/SNKGlDFdVPpa6ER6aQWB7pc= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id A1F93F80534; Tue, 22 Jun 2021 03:15:35 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id F4195F80534; Tue, 22 Jun 2021 03:15:33 +0200 (CEST) Received: from relmlie5.idc.renesas.com (relmlor1.renesas.com [210.160.252.171]) by alsa1.perex.cz (Postfix) with ESMTP id 1C518F8052D for ; Tue, 22 Jun 2021 03:15:30 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 1C518F8052D Date: 22 Jun 2021 10:15:29 +0900 X-IronPort-AV: E=Sophos;i="5.83,290,1616425200"; d="scan'208";a="85109328" Received: from unknown (HELO relmlir6.idc.renesas.com) ([10.200.68.152]) by relmlie5.idc.renesas.com with ESMTP; 22 Jun 2021 10:15:29 +0900 Received: from mercury.renesas.com (unknown [10.166.252.133]) by relmlir6.idc.renesas.com (Postfix) with ESMTP id E79434149C63; Tue, 22 Jun 2021 10:15:29 +0900 (JST) Message-ID: <87k0mm3dji.wl-kuninori.morimoto.gx@renesas.com> From: Kuninori Morimoto Subject: [PATCH RFC 12/15] ASoC: audio-graph-card2-sample.dtsi: add Sample DT for Audio Graph Card2 User-Agent: Wanderlust/2.15.9 Emacs/26.3 Mule/6.0 To: Mark Brown , Rob Herring In-Reply-To: <871r8u4s6q.wl-kuninori.morimoto.gx@renesas.com> References: <871r8u4s6q.wl-kuninori.morimoto.gx@renesas.com> MIME-Version: 1.0 (generated by SEMI-EPG 1.14.7 - "Harue") Cc: Linux-ALSA 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" From: Kuninori Morimoto Audio Graph Card2 settings is a little bit difficult for beginner, and Customizing it also difficult/confusable too. So, this patch adds sample for it. You can easily use it by adding below line on your DT file, and select CONFIGs to your .config. #include "../../../../../sound/soc/generic/audio-graph-card2-sample.dtsi" CONFIG_SND_AUDIO_GRAPH_CARD2 CONFIG_SND_SAMPLE_CUSTOM_CARD CONFIG_SND_TEST_COMPONENT This patch uses audio-graph-card2 base sample custom driver. You can directly use audio-graph-card2 instead of custom driver by modifing compatible. - compatible = "sample-custom-card"; + compatible = "audio-graph-card2"; Sample custom driver will indicate customized print. Previous "audio-graph-card" and new "audio-graph-card2" doesn't have full compatibility. The differenct from audio-graph-card are - audio-graph-card2 uses "links" instead of "dais". - audio-graph-card2 uses flags for bitclock/frame-master instead of phandle. - audio-graph-card2 uses .get_fmt instead of having "format" It is using Test-Component driver for CPU/Codec. It can indicate more detail print of each behavior if user want to. In such case, you need to update compatible to "xxx-nv" or "xxx-vv". - compatible = "test-cpu"; + compatible = "test-cpu-nv"; Signed-off-by: Kuninori Morimoto --- .../soc/generic/audio-graph-card2-sample.dtsi | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 sound/soc/generic/audio-graph-card2-sample.dtsi diff --git a/sound/soc/generic/audio-graph-card2-sample.dtsi b/sound/soc/generic/audio-graph-card2-sample.dtsi new file mode 100644 index 000000000000..5e83bfed1781 --- /dev/null +++ b/sound/soc/generic/audio-graph-card2-sample.dtsi @@ -0,0 +1,68 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * audio-graph-card2-sample dtsi + * + * + * This sample indicates how to use audio-graph-card2 and its + * custom driver. "sample-custom-card" is the custome driver + * which is using audio-graph-card2. + * + * You can easily use this sample by adding below line on your DT file, + * and add new CONFIG to your .config. + * + * #include "../../../../../sound/soc/generic/audio-graph-card2-sample.dtsi" + * + * CONFIG_SND_AUDIO_GRAPH_CARD2 + * CONFIG_SND_SAMPLE_CUSTOM_CARD + * CONFIG_SND_TEST_COMPONENT + */ +/ { + /* + * cpu0 <--> codec0 // Normal + * cpu1 <--> codec1 // Normal + */ + card2 { + /* + * You can use audio-graph-card2 directly + * by using + * + * compatible = "audio-graph-card2"; + */ + compatible = "sample-custom-card"; + + links = <&cpu0 &cpu1 /* normal: cpu side only */ + >; + }; + + test_cpu { + /* + * update compatible to indicate more detail behaviour + * if you want. see test-compatible for more detail. + * + * - compatible = "test-cpu"; + * + compatible = "test-cpu-nv"; + */ + compatible = "test-cpu"; + ports { + bitclock-master; + frame-master; + cpu0: port@0 { cpu0_ep: endpoint { remote-endpoint = <&codec0_ep>; }; }; + cpu1: port@1 { cpu1_ep: endpoint { remote-endpoint = <&codec1_ep>; }; }; + }; + }; + + test_codec { + /* + * update compatible to indicate more detail behaviour + * if you want. see test-compatible for more detail. + * + * - compatible = "test-codec"; + * + compatible = "test-codec-nv"; + */ + compatible = "test-codec"; + ports { + port@0 { codec0_ep: endpoint { remote-endpoint = <&cpu0_ep>; }; }; + port@1 { codec1_ep: endpoint { remote-endpoint = <&cpu1_ep>; }; }; + }; + }; +}; From patchwork Tue Jun 22 01:15:34 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kuninori Morimoto X-Patchwork-Id: 465200 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 96D07C4743C for ; Tue, 22 Jun 2021 01:20:12 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 10C76601FC for ; Tue, 22 Jun 2021 01:20:12 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 10C76601FC Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=renesas.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org 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 9F5CC169A; Tue, 22 Jun 2021 03:19:20 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 9F5CC169A DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1624324810; bh=AAo2/dBTmNbrV1NNJVogYmrrC/4kVmuTOR+q7p4zWiY=; h=Date:From:Subject:To:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=cMLzh1hU87Dq1z951wmrOPz0UMtotc9UdHtJo+Rf4Pcf/wO54TiDlXD4biDZIa9tX a8Q8rjcqpuOTmv9yM00GSQQAv7t6he8RCy/W4HmKlFoR/C5wPgeRjiAzEEwhabmurP nO31PWwdiTxhT9GuVqBcb0aWF13Nx8j8QLTIO/G8= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 5C8F2F8052D; Tue, 22 Jun 2021 03:15:38 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 3B2F2F80538; Tue, 22 Jun 2021 03:15:37 +0200 (CEST) Received: from relmlie5.idc.renesas.com (relmlor1.renesas.com [210.160.252.171]) by alsa1.perex.cz (Postfix) with ESMTP id 7AB4DF8052D for ; Tue, 22 Jun 2021 03:15:34 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 7AB4DF8052D Date: 22 Jun 2021 10:15:34 +0900 X-IronPort-AV: E=Sophos;i="5.83,290,1616425200"; d="scan'208";a="85109342" Received: from unknown (HELO relmlir5.idc.renesas.com) ([10.200.68.151]) by relmlie5.idc.renesas.com with ESMTP; 22 Jun 2021 10:15:34 +0900 Received: from mercury.renesas.com (unknown [10.166.252.133]) by relmlir5.idc.renesas.com (Postfix) with ESMTP id 16574400D0D1; Tue, 22 Jun 2021 10:15:34 +0900 (JST) Message-ID: <87im263djd.wl-kuninori.morimoto.gx@renesas.com> From: Kuninori Morimoto Subject: [PATCH RFC 13/15] ASoC: audio-graph-card2-sample.dtsi: add DPCM sample User-Agent: Wanderlust/2.15.9 Emacs/26.3 Mule/6.0 To: Mark Brown , Rob Herring In-Reply-To: <871r8u4s6q.wl-kuninori.morimoto.gx@renesas.com> References: <871r8u4s6q.wl-kuninori.morimoto.gx@renesas.com> MIME-Version: 1.0 (generated by SEMI-EPG 1.14.7 - "Harue") Cc: Linux-ALSA 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" From: Kuninori Morimoto This patch adds DPCM sample to audio-graph-card2-sample.dtsi. This sample is assuming MIXer connection. CPU2 --\ +-- Codec2 CPU3 --/ Signed-off-by: Kuninori Morimoto --- .../soc/generic/audio-graph-card2-sample.dtsi | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/sound/soc/generic/audio-graph-card2-sample.dtsi b/sound/soc/generic/audio-graph-card2-sample.dtsi index 5e83bfed1781..9aab6be176e5 100644 --- a/sound/soc/generic/audio-graph-card2-sample.dtsi +++ b/sound/soc/generic/audio-graph-card2-sample.dtsi @@ -20,6 +20,8 @@ / { /* * cpu0 <--> codec0 // Normal * cpu1 <--> codec1 // Normal + * cpu2 <--> codec2 // DPCM + * cpu3 <-/ // DPCM */ card2 { /* @@ -30,10 +32,27 @@ card2 { */ compatible = "sample-custom-card"; + routing = "TC DAI2 Playback", "DAI2 Playback", + "TC DAI2 Playback", "DAI3 Playback", + "DAI2 Capture", "TC DAI2 Capture", + "DAI3 Capture", "TC DAI2 Capture"; + links = <&cpu0 &cpu1 /* normal: cpu side only */ + &mix_fe0 &mix_fe1 &mix_be0 /* dsp : both fe/be */ >; }; + mix { + compatible = "audio-graph-card2-dsp"; + DSP_FE: ports@0 { + mix_fe0: port@0 { mix_fe0_ep: endpoint { remote-endpoint = <&cpu2_ep>; }; }; + mix_fe1: port@1 { mix_fe1_ep: endpoint { remote-endpoint = <&cpu3_ep>; }; }; + }; + DSP_BE: ports@1 { + mix_be0: port { mix_be0_ep: endpoint { remote-endpoint = <&codec2_ep>; }; }; + }; + }; + test_cpu { /* * update compatible to indicate more detail behaviour @@ -48,6 +67,8 @@ ports { frame-master; cpu0: port@0 { cpu0_ep: endpoint { remote-endpoint = <&codec0_ep>; }; }; cpu1: port@1 { cpu1_ep: endpoint { remote-endpoint = <&codec1_ep>; }; }; + port@2 { cpu2_ep: endpoint { remote-endpoint = <&mix_fe0_ep>; }; }; + port@3 { cpu3_ep: endpoint { remote-endpoint = <&mix_fe1_ep>; }; }; }; }; @@ -61,8 +82,15 @@ test_codec { */ compatible = "test-codec"; ports { + /* + * prefix can be added to *component*, + * see card2::routing + */ + prefix = "TC"; + port@0 { codec0_ep: endpoint { remote-endpoint = <&cpu0_ep>; }; }; port@1 { codec1_ep: endpoint { remote-endpoint = <&cpu1_ep>; }; }; + port@2 { codec2_ep: endpoint { remote-endpoint = <&mix_be0_ep>; }; }; }; }; }; From patchwork Tue Jun 22 01:15:38 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kuninori Morimoto X-Patchwork-Id: 465933 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 96EB5C4743C for ; Tue, 22 Jun 2021 01:20:35 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 12869610C7 for ; Tue, 22 Jun 2021 01:20:35 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 12869610C7 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=renesas.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org 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 988D116AB; Tue, 22 Jun 2021 03:19:43 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 988D116AB DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1624324833; bh=do6zhIu3+EdeRRvf6bEwWoYdsNMQrhvB7YDK7iJjABc=; h=Date:From:Subject:To:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=GCaT9F7L8iS0n229bHid4zL6QrqPTZ1C59PFFXYX6bjZeOvd+TzofgV+Sqru0r6pm SZQjyFHz8CVoX9cVQTkgJrdHxVt2zf+7u5If3AlYFXy2WBhybGA7RF8Sy0jJmQrvux gG0C8NoDhGZdZISg9t9AbBmZcMDOkee/1cT3CGyo= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 075E5F80539; Tue, 22 Jun 2021 03:15:43 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 394F8F80539; Tue, 22 Jun 2021 03:15:41 +0200 (CEST) Received: from relmlie5.idc.renesas.com (relmlor1.renesas.com [210.160.252.171]) by alsa1.perex.cz (Postfix) with ESMTP id 819DEF80536 for ; Tue, 22 Jun 2021 03:15:38 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 819DEF80536 Date: 22 Jun 2021 10:15:38 +0900 X-IronPort-AV: E=Sophos;i="5.83,290,1616425200"; d="scan'208";a="85109360" Received: from unknown (HELO relmlir6.idc.renesas.com) ([10.200.68.152]) by relmlie5.idc.renesas.com with ESMTP; 22 Jun 2021 10:15:38 +0900 Received: from mercury.renesas.com (unknown [10.166.252.133]) by relmlir6.idc.renesas.com (Postfix) with ESMTP id 215E64149817; Tue, 22 Jun 2021 10:15:38 +0900 (JST) Message-ID: <87h7hq3dj9.wl-kuninori.morimoto.gx@renesas.com> From: Kuninori Morimoto Subject: [PATCH RFC 14/15] ASoC: audio-graph-card2-sample.dtsi: add Multi CPU/Codec sample User-Agent: Wanderlust/2.15.9 Emacs/26.3 Mule/6.0 To: Mark Brown , Rob Herring In-Reply-To: <871r8u4s6q.wl-kuninori.morimoto.gx@renesas.com> References: <871r8u4s6q.wl-kuninori.morimoto.gx@renesas.com> MIME-Version: 1.0 (generated by SEMI-EPG 1.14.7 - "Harue") Cc: Linux-ALSA 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" From: Kuninori Morimoto This patch adds Multi CPU/Codec sample to audio-graph-card2-sample.dtsi. Because ASoC doesn't support "N CPUs to M Codecs", this sample uses "2 CPUs to 2 Codecs". +---+ CPU4 --| |-- Codec3 CPU5 --| |-- Codec4 +---+ Signed-off-by: Kuninori Morimoto --- .../soc/generic/audio-graph-card2-sample.dtsi | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/sound/soc/generic/audio-graph-card2-sample.dtsi b/sound/soc/generic/audio-graph-card2-sample.dtsi index 9aab6be176e5..1d18aba22011 100644 --- a/sound/soc/generic/audio-graph-card2-sample.dtsi +++ b/sound/soc/generic/audio-graph-card2-sample.dtsi @@ -22,6 +22,8 @@ / { * cpu1 <--> codec1 // Normal * cpu2 <--> codec2 // DPCM * cpu3 <-/ // DPCM + * cpu4 <==> codec3 // Multi (*1) + * cpu5 <==> codec4 // Multi (*1) */ card2 { /* @@ -39,6 +41,7 @@ card2 { links = <&cpu0 &cpu1 /* normal: cpu side only */ &mix_fe0 &mix_fe1 &mix_be0 /* dsp : both fe/be */ + &multi_cpu /* multi : cpu side only */ >; }; @@ -53,6 +56,26 @@ DSP_BE: ports@1 { }; }; + multi { + compatible = "audio-graph-card2-multi"; + + /* + * (*1) + * + * This uses 2 CPUs x 2 Codecs as Multi connection, + * Because ASoC doesn't support N cpus to M codecs + */ + + multi_cpu: ports@0 { + port@0 { multi_00_ep: endpoint { remote-endpoint = <&cpu4_ep>; }; }; + port@1 { multi_01_ep: endpoint { remote-endpoint = <&cpu5_ep>; }; }; + }; + multi_codec: ports@1 { + port@0 { multi_10_ep: endpoint { remote-endpoint = <&codec3_ep>; }; }; + port@1 { multi_11_ep: endpoint { remote-endpoint = <&codec4_ep>; }; }; + }; + }; + test_cpu { /* * update compatible to indicate more detail behaviour @@ -69,6 +92,8 @@ ports { cpu1: port@1 { cpu1_ep: endpoint { remote-endpoint = <&codec1_ep>; }; }; port@2 { cpu2_ep: endpoint { remote-endpoint = <&mix_fe0_ep>; }; }; port@3 { cpu3_ep: endpoint { remote-endpoint = <&mix_fe1_ep>; }; }; + port@4 { cpu4_ep: endpoint { remote-endpoint = <&multi_00_ep>; }; }; + port@5 { cpu5_ep: endpoint { remote-endpoint = <&multi_01_ep>; }; }; }; }; @@ -91,6 +116,8 @@ ports { port@0 { codec0_ep: endpoint { remote-endpoint = <&cpu0_ep>; }; }; port@1 { codec1_ep: endpoint { remote-endpoint = <&cpu1_ep>; }; }; port@2 { codec2_ep: endpoint { remote-endpoint = <&mix_be0_ep>; }; }; + port@3 { codec3_ep: endpoint { remote-endpoint = <&multi_10_ep>; }; }; + port@4 { codec4_ep: endpoint { remote-endpoint = <&multi_11_ep>; }; }; }; }; }; From patchwork Tue Jun 22 01:15:42 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kuninori Morimoto X-Patchwork-Id: 465199 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E6988C4743C for ; Tue, 22 Jun 2021 01:20:52 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 64930601FC for ; Tue, 22 Jun 2021 01:20:52 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 64930601FC Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=renesas.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org 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 0299B16CA; Tue, 22 Jun 2021 03:20:01 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 0299B16CA DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1624324851; bh=/zLaHncKpjo++ifBUc+VHyu/73Xm+PlVQjV5J3j1Pj4=; h=Date:From:Subject:To:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=jI9iLiu31JGjpo6uHwsE9nYdcNlbHt3OOtaGFjFRknuF1AnhBWtshVKsegi1rNlES GYkElD/04Fur2wfSpv6cQAnMI/8d4rAMaGBUvwb/C5xTZZNbprFELVJ1nudyif0U5v K1CR+td7iok2/c8RJvNwNk2Rgh3R/lHzea2ndhWA= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 5D98AF8053A; Tue, 22 Jun 2021 03:15:50 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 6586AF804E5; Tue, 22 Jun 2021 03:15:49 +0200 (CEST) Received: from relmlie5.idc.renesas.com (relmlor1.renesas.com [210.160.252.171]) by alsa1.perex.cz (Postfix) with ESMTP id A32DDF8053A for ; Tue, 22 Jun 2021 03:15:42 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz A32DDF8053A Date: 22 Jun 2021 10:15:42 +0900 X-IronPort-AV: E=Sophos;i="5.83,290,1616425200"; d="scan'208";a="85109369" Received: from unknown (HELO relmlir5.idc.renesas.com) ([10.200.68.151]) by relmlie5.idc.renesas.com with ESMTP; 22 Jun 2021 10:15:42 +0900 Received: from mercury.renesas.com (unknown [10.166.252.133]) by relmlir5.idc.renesas.com (Postfix) with ESMTP id 3F869400D0C5; Tue, 22 Jun 2021 10:15:42 +0900 (JST) Message-ID: <87fsxa3dj5.wl-kuninori.morimoto.gx@renesas.com> From: Kuninori Morimoto Subject: [PATCH RFC 15/15] ASoC: audio-graph-card2-sample.dtsi: add Codec2Codec sample. User-Agent: Wanderlust/2.15.9 Emacs/26.3 Mule/6.0 To: Mark Brown , Rob Herring In-Reply-To: <871r8u4s6q.wl-kuninori.morimoto.gx@renesas.com> References: <871r8u4s6q.wl-kuninori.morimoto.gx@renesas.com> MIME-Version: 1.0 (generated by SEMI-EPG 1.14.7 - "Harue") Cc: Linux-ALSA 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" From: Kuninori Morimoto This patch adds Codec2Codec sample to audio-graph-card2-sample.dtsi. Because it can use very basic connection only for now, it can use only - 2channels - S32_LE format Test-Component driver has "IN" and "OUT" widget. Thus the route is +--+ | | <-- Codec5 | | --> Codec6 +--+ (*) "IN" -> "DAI5 Capture" -> "DAI6 Playback" -> "OUT" (*) routing is using "TC" prefix on this sample. One note here is that it will start works when it boot. In other words we can't stop it so far. We need to update driver for it in the future. Signed-off-by: Kuninori Morimoto --- .../soc/generic/audio-graph-card2-sample.dtsi | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/sound/soc/generic/audio-graph-card2-sample.dtsi b/sound/soc/generic/audio-graph-card2-sample.dtsi index 1d18aba22011..f7cae9c480be 100644 --- a/sound/soc/generic/audio-graph-card2-sample.dtsi +++ b/sound/soc/generic/audio-graph-card2-sample.dtsi @@ -24,6 +24,8 @@ / { * cpu3 <-/ // DPCM * cpu4 <==> codec3 // Multi (*1) * cpu5 <==> codec4 // Multi (*1) + * /=> codec5 // Codec2Codec + * \=> codec6 // Codec2Codec */ card2 { /* @@ -37,11 +39,14 @@ card2 { routing = "TC DAI2 Playback", "DAI2 Playback", "TC DAI2 Playback", "DAI3 Playback", "DAI2 Capture", "TC DAI2 Capture", - "DAI3 Capture", "TC DAI2 Capture"; + "DAI3 Capture", "TC DAI2 Capture", + "TC OUT" ,"TC DAI6 Playback", + "TC DAI5 Capture", "TC IN"; links = <&cpu0 &cpu1 /* normal: cpu side only */ &mix_fe0 &mix_fe1 &mix_be0 /* dsp : both fe/be */ &multi_cpu /* multi : cpu side only */ + &c2c /* c2c : first one only */ >; }; @@ -76,6 +81,16 @@ multi_codec: ports@1 { }; }; + codec2codec { + compatible = "audio-graph-card2-codec2codec"; + + rate = <48000>; + ports@1 { + c2c: port@0 { c2c_0_ep: endpoint { remote-endpoint = <&codec5_ep>; }; }; + port@1 { c2c_1_ep: endpoint { remote-endpoint = <&codec6_ep>; }; }; + }; + }; + test_cpu { /* * update compatible to indicate more detail behaviour @@ -118,6 +133,8 @@ ports { port@2 { codec2_ep: endpoint { remote-endpoint = <&mix_be0_ep>; }; }; port@3 { codec3_ep: endpoint { remote-endpoint = <&multi_10_ep>; }; }; port@4 { codec4_ep: endpoint { remote-endpoint = <&multi_11_ep>; }; }; + port@5 { codec5_ep: endpoint { remote-endpoint = <&c2c_0_ep>; }; }; + port@6 { codec6_ep: endpoint { remote-endpoint = <&c2c_1_ep>; }; }; }; }; };