From patchwork Mon Jun 15 06:24:15 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kuninori Morimoto X-Patchwork-Id: 6606351 Return-Path: X-Original-To: patchwork-alsa-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 6FBF5C0020 for ; Mon, 15 Jun 2015 06:29:33 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 0583820532 for ; Mon, 15 Jun 2015 06:29:32 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) by mail.kernel.org (Postfix) with ESMTP id 331F02052C for ; Mon, 15 Jun 2015 06:29:30 +0000 (UTC) Received: by alsa0.perex.cz (Postfix, from userid 1000) id 505ED261B20; Mon, 15 Jun 2015 08:29:29 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 Received: from alsa0.perex.cz (localhost [IPv6:::1]) by alsa0.perex.cz (Postfix) with ESMTP id E52B92608CD; Mon, 15 Jun 2015 08:26:21 +0200 (CEST) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa0.perex.cz (Postfix, from userid 1000) id D60EF2608CD; Mon, 15 Jun 2015 08:26:20 +0200 (CEST) Received: from relmlie3.idc.renesas.com (relmlor4.renesas.com [210.160.252.174]) by alsa0.perex.cz (Postfix) with ESMTP id BAF50260A5D for ; Mon, 15 Jun 2015 08:24:18 +0200 (CEST) Received: from unknown (HELO relmlir4.idc.renesas.com) ([10.200.68.154]) by relmlie3.idc.renesas.com with ESMTP; 15 Jun 2015 15:24:17 +0900 Received: from relmlac4.idc.renesas.com (relmlac4.idc.renesas.com [10.200.69.24]) by relmlir4.idc.renesas.com (Postfix) with ESMTP id 7807E46513; Mon, 15 Jun 2015 15:24:17 +0900 (JST) Received: by relmlac4.idc.renesas.com (Postfix, from userid 0) id 6D2C4480A4; Mon, 15 Jun 2015 15:24:17 +0900 (JST) Received: from relmlac4.idc.renesas.com (localhost [127.0.0.1]) by relmlac4.idc.renesas.com (Postfix) with ESMTP id 627AE480A3; Mon, 15 Jun 2015 15:24:17 +0900 (JST) Received: from relmlii1.idc.renesas.com [10.200.68.65] by relmlac4.idc.renesas.com with ESMTP id RAE07310; Mon, 15 Jun 2015 15:24:17 +0900 X-IronPort-AV: E=Sophos;i="5.13,617,1427727600"; d="scan'";a="188302213" Received: from mail-hk1lp0125.outbound.protection.outlook.com (HELO APAC01-HK1-obe.outbound.protection.outlook.com) ([207.46.51.125]) by relmlii1.idc.renesas.com with ESMTP/TLS/AES256-SHA; 15 Jun 2015 15:24:16 +0900 Authentication-Results: kernel.org; dkim=none (message not signed) header.d=none; Received: from morimoto-PC.renesas.com (211.11.155.132) by HKNPR06MB305.apcprd06.prod.outlook.com (10.141.37.16) with Microsoft SMTP Server (TLS) id 15.1.190.14; Mon, 15 Jun 2015 06:24:15 +0000 Message-ID: <87fv5tv6d8.wl%kuninori.morimoto.gx@renesas.com> From: Kuninori Morimoto User-Agent: Wanderlust/2.15.9 Emacs/24.3 Mule/6.0 To: Mark Brown In-Reply-To: <87twu9v6kn.wl%kuninori.morimoto.gx@renesas.com> References: <87twu9v6kn.wl%kuninori.morimoto.gx@renesas.com> MIME-Version: 1.0 (generated by SEMI-EPG 1.14.7 - "Harue") Date: Mon, 15 Jun 2015 06:24:15 +0000 X-Originating-IP: [211.11.155.132] X-ClientProxiedBy: TY1PR01CA0029.jpnprd01.prod.outlook.com (25.164.162.139) To HKNPR06MB305.apcprd06.prod.outlook.com (10.141.37.16) X-Microsoft-Exchange-Diagnostics: 1; HKNPR06MB305; 2:u7tPZ/tt7HeTN62D6dS5XrIvd/Pb7ItMedu6rMB2D+plX3nTwst4hIqcZcR6M5Da; 2:3fr05uWEB4tmmr5XIHobCThxJN+Hk3An8NJJhFQ89vC1w2dmriZECIAOoVsm2De68VLYJh3VBgDSJ+CpcskLVpxXx5LXF5arZNqNTMKIVIw6JwZxTNk/34XBw0BbKA2URVp8h3MxVk0jo0AgUXSZJQ==; 6:c/5duzZYxbhANhsrqGwVW8ELXOe3VE0M9gZPmqn1iGfHvIUAlu0f3fy9whmM4qSdky+f8GXsUZyepcpLcun8SBN6UHcksNFSzvzlDMCsgKI9gR2eQf8E6NIMvURQXFB/dmvCSqA2XMhYHVgziML6lkqz5I2ILf9yezq+KT4KaI8lKmvsQhvCwdhXxEJzDl4KOZ8xAyYWrvsxxM85Zwl7ZZr0Y3qRPBSgTEMmq9tPsiflskFECOIybtHcjR4eDvWX+e6r45A0DO6nevv5j4jrxbdWFWWHKjP2KPJb1o+FRWxfbbIZhnhElt6atodSz5jgf9s64SYWSY6dInVO+FHrKBmQHsROxc7hKdbIMzVygZ/9jueFQhDR0f6AC+xKib5fngsPX6cApBMVdMsV4MLNzonlC4UKb9pTAOHwGQgxpgjbwGbJrvhWbU7dFYbknLN3kiHopGLq1UKG3ZDTiv+Qo8VSdIoFeb6gQ6OKuK5a46wbpQo4W+k583RtrncrBCaZ X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:HKNPR06MB305; X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(601004)(520003)(5005006)(3002001); SRVR:HKNPR06MB305; BCL:0; PCL:0; RULEID:; SRVR:HKNPR06MB305; X-Microsoft-Exchange-Diagnostics: 1; HKNPR06MB305; 3:0w6ZTqzc4mHttdsztYQsmYuK/8z86+uVqnFe2aJCFg5LaQRtx5p1Ki3C3aH9B8LazgNqy49LXzoQHCL/qt7BsGQxiQQlezni0BIVxXeuHSZlJgB7I2n7G64/vZjsp5ybruFwVhh4DWSsNhXlGSoF/Tex9YuZg0EY7M84T2Xb8Gs4I1VNHwrjV5aA0fvESAZYc5PZ9d/yODksXep3L1Ps7hSxIB9v685WibU5Cds7XuJKiDQ7M6fFLaxASehDjolYGu8mfFsO1iKo/g1y1b0fuueOOLLl2AZSlN76To/K+gnAg0qNKK5gKc7K0ZiHzK9Y X-Forefront-PRVS: 0608DEDB67 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10019020)(6009001)(66066001)(47776003)(4001350100001)(53416004)(122386002)(42186005)(5001960100002)(50466002)(110136002)(77156002)(62966003)(77096005)(19580405001)(2950100001)(19580395003)(83506001)(87976001)(189998001)(86362001)(40100003)(46102003)(33646002)(92566002)(229853001)(50986999)(23726002)(36756003)(54356999)(76176999)(21314002); DIR:OUT; SFP:1102; SCL:1; SRVR:HKNPR06MB305; H:morimoto-PC.renesas.com; FPR:; SPF:None; MLV:sfv; LANG:en; X-Microsoft-Exchange-Diagnostics: 1; HKNPR06MB305; 9:67wSfZUYe/FtXDG0vSz1vyK5htQ8zGwMxYSg09Qrq34liCUfZxRxAGWVvXCGajgKfwvWzITmvsJtyq1OtFEyI74iiLn/naIlOoCrAH8dJpmT+91xZ5PfHHDgielXLF3SOWO2TW07vNuY1Kss1Rezls7qBA1ly0fkWHGreqYrtVfVUiZ0IkYIlMyCAW44XqYh5z8XhJt6XQFII3ktKUvgRAVzcOjNfZJcLlotbpSxynqxxa5QDNV2HVZoQkc/hppqE1BGPQ7bWFMgFzXClDNwESf/hikVWzyrz/NeUesOViLZ2pABwQtFzmFuWJwZRhQc315lhZcLgEz054ClPV3MY/pOoRdW7kqR4Onl7FVJCjODiy0+d4Kr7HdIx2kXKya3FddwggSCsTZrCOWSuPagSR3aOjFI/nztLu8+0EiYjSIGF6CjG06fqWnbGpOXPshsAl5Tl8o9jrHd96knKrhLwHfkWMZeUk08Bk6LkqpmSXtNOEQ+QYcicZHVvz4+Yr28CBsLPOBGS2lKqcremaRT5f9eFi2glM8w6k25kdhhUVZFg905A0/eCcOKTYjMXa2A0BvxkYb7Z0zLtFzZzoifE5KqFXX7xnJprRQYIhO5b2hM3/yQXW4dLL9CVaISTTDHwTjblzWfv6rcX+1HRtpS0WInlCID9aU8uWddjMWUmuepLFCBfUglRH9tg7l4Bkt7NqRZRWnmxMUo3KIUmfKh6VIjpgQJFJlN6xpofS2WCwE+yRpNbm266rED5ztXur0B00xrikhgEV/xY0cb97aGcvgvFv/6QPx5sQV1m8pmxeP4CB94QeCgrW1xl+1Ev3SQpI66hUBv3RF1h6Nxr29sHVQnF/Cu3LWSX0DmqGxXfjU= X-Microsoft-Exchange-Diagnostics: 1; HKNPR06MB305; 3:VsNm+Ub3+CIMU5PolBEmEoplRqzlpQ1+aL9v5NwS3Z9RKqTqwlBb15CduOYJBxnsgs/kzkT7WPf6HI2I5KoAi/+IjGues5k5pTvQ3Ge/S9JpGqus5Dtmhz5Prx5zGe5+fUJrIirBED4SRwhJc7EgUQ==; 10:6AOitEg8j0/evTd/b07UpJP1BmT4VeLy2wXWGSv1WvGHSQwjPl1PQnTjgK8I4IVEV8/aGDxVjXWUwOyajSonuIsCb8EHMPE/Z8V9ILAudyU=; 6:2f185bkTIkO0tBZGcyfw2Hy4Mctn+eYsV+G/C7jbrLcNqITlvbDxE7/1XJOPyZWRTfuKB6d/prKh/opu65omqdXrxqSVoKtLdmuHZXWZQxfbu36d0/LOdhaRPrbpGeg71MxGD3mvUCMcAuvxaxZeUw== X-OriginatorOrg: renesas.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 15 Jun 2015 06:24:15.0653 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: HKNPR06MB305 Cc: Linux-ALSA , Simon , Liam Girdwood Subject: [alsa-devel] [PATCH 10/21] ASoC: rsrc-card: cleanup for DPCM X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: alsa-devel-bounces@alsa-project.org X-Virus-Scanned: ClamAV using ClamSMTP From: Kuninori Morimoto rsrc-card driver is based on simple-card driver which is caring about CPU / Codec connection. OTOH, rsrc-card is used for DPCM system. FE portion is constituted by CPU and dummy Codec, and BE is constituted by dummy CPU and Codec in DPCM system. Because of this, current rsrc-card is doing pointless method. It works well if FE/BE was 1:1, but not good for multi FE/BE. This patch cleanups rsrc-card driver for DPCM. and this is prepare for MIX support for Renesas sound driver. Signed-off-by: Kuninori Morimoto Tested-by: Keita Kobayashi --- sound/soc/sh/rcar/rsrc-card.c | 324 ++++++++++++++++++------------------------ 1 file changed, 135 insertions(+), 189 deletions(-) diff --git a/sound/soc/sh/rcar/rsrc-card.c b/sound/soc/sh/rcar/rsrc-card.c index 52123d6..8caca2e 100644 --- a/sound/soc/sh/rcar/rsrc-card.c +++ b/sound/soc/sh/rcar/rsrc-card.c @@ -45,23 +45,20 @@ static const struct of_device_id rsrc_card_of_match[] = { }; MODULE_DEVICE_TABLE(of, rsrc_card_of_match); +#define DAI_NAME_NUM 32 struct rsrc_card_dai { unsigned int fmt; unsigned int sysclk; struct clk *clk; + char dai_name[DAI_NAME_NUM]; }; #define IDX_CPU 0 #define IDX_CODEC 1 -#define DAI_NAME_NUM 32 struct rsrc_card_priv { struct snd_soc_card snd_card; - struct rsrc_card_dai_props { - struct rsrc_card_dai cpu_dai; - struct rsrc_card_dai codec_dai; - char dai_name[DAI_NAME_NUM]; - } *dai_props; struct snd_soc_codec_conf codec_conf; + struct rsrc_card_dai *dai_props; struct snd_soc_dai_link *dai_link; int dai_num; u32 convert_rate; @@ -76,31 +73,22 @@ static int rsrc_card_startup(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card); - struct rsrc_card_dai_props *dai_props = + struct rsrc_card_dai *dai_props = rsrc_priv_to_props(priv, rtd - rtd->card->rtd); int ret; - ret = clk_prepare_enable(dai_props->cpu_dai.clk); - if (ret) - return ret; - - ret = clk_prepare_enable(dai_props->codec_dai.clk); - if (ret) - clk_disable_unprepare(dai_props->cpu_dai.clk); - return ret; + return clk_prepare_enable(dai_props->clk); } static void rsrc_card_shutdown(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card); - struct rsrc_card_dai_props *dai_props = + struct rsrc_card_dai *dai_props = rsrc_priv_to_props(priv, rtd - rtd->card->rtd); - clk_disable_unprepare(dai_props->cpu_dai.clk); - - clk_disable_unprepare(dai_props->codec_dai.clk); + clk_disable_unprepare(dai_props->clk); } static struct snd_soc_ops rsrc_card_ops = { @@ -108,21 +96,31 @@ static struct snd_soc_ops rsrc_card_ops = { .shutdown = rsrc_card_shutdown, }; -static int __rsrc_card_dai_init(struct snd_soc_dai *dai, - struct rsrc_card_dai *set) +static int rsrc_card_dai_init(struct snd_soc_pcm_runtime *rtd) { + struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card); + struct snd_soc_dai *dai; + struct snd_soc_dai_link *dai_link; + struct rsrc_card_dai *dai_props; + int num = rtd - rtd->card->rtd; int ret; - if (set->fmt) { - ret = snd_soc_dai_set_fmt(dai, set->fmt); + dai_link = rsrc_priv_to_link(priv, num); + dai_props = rsrc_priv_to_props(priv, num); + dai = dai_link->dynamic ? + rtd->cpu_dai : + rtd->codec_dai; + + if (dai_props->fmt) { + ret = snd_soc_dai_set_fmt(dai, dai_props->fmt); if (ret && ret != -ENOTSUPP) { dev_err(dai->dev, "set_fmt error\n"); goto err; } } - if (set->sysclk) { - ret = snd_soc_dai_set_sysclk(dai, 0, set->sysclk, 0); + if (dai_props->sysclk) { + ret = snd_soc_dai_set_sysclk(dai, 0, dai_props->sysclk, 0); if (ret && ret != -ENOTSUPP) { dev_err(dai->dev, "set_sysclk error\n"); goto err; @@ -135,27 +133,6 @@ err: return ret; } -static int rsrc_card_dai_init(struct snd_soc_pcm_runtime *rtd) -{ - struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *codec = rtd->codec_dai; - struct snd_soc_dai *cpu = rtd->cpu_dai; - struct rsrc_card_dai_props *dai_props; - int num, ret; - - num = rtd - rtd->card->rtd; - dai_props = &priv->dai_props[num]; - ret = __rsrc_card_dai_init(codec, &dai_props->codec_dai); - if (ret < 0) - return ret; - - ret = __rsrc_card_dai_init(cpu, &dai_props->cpu_dai); - if (ret < 0) - return ret; - - return 0; -} - static int rsrc_card_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params) { @@ -172,15 +149,14 @@ static int rsrc_card_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, } static int rsrc_card_parse_daifmt(struct device_node *node, + struct device_node *np, struct rsrc_card_priv *priv, - struct device_node *codec, - int idx) + int idx, bool is_fe) { + struct rsrc_card_dai *dai_props = rsrc_priv_to_props(priv, idx); struct device_node *bitclkmaster = NULL; struct device_node *framemaster = NULL; - struct rsrc_card_dai_props *dai_props = rsrc_priv_to_props(priv, idx); - struct rsrc_card_dai *cpu_dai = &dai_props->cpu_dai; - struct rsrc_card_dai *codec_dai = &dai_props->codec_dai; + struct device_node *codec = is_fe ? NULL : np; unsigned int daifmt; daifmt = snd_soc_of_parse_daifmt(node, NULL, @@ -197,8 +173,7 @@ static int rsrc_card_parse_daifmt(struct device_node *node, daifmt |= (codec == framemaster) ? SND_SOC_DAIFMT_CBS_CFM : SND_SOC_DAIFMT_CBS_CFS; - cpu_dai->fmt = daifmt; - codec_dai->fmt = daifmt; + dai_props->fmt = daifmt; of_node_put(bitclkmaster); of_node_put(framemaster); @@ -206,41 +181,15 @@ static int rsrc_card_parse_daifmt(struct device_node *node, return 0; } -static int -rsrc_card_sub_parse_of(struct rsrc_card_priv *priv, - struct device_node *np, - struct rsrc_card_dai *dai, - struct snd_soc_dai_link *dai_link, - int *args_count) +static int rsrc_card_parse_links(struct device_node *np, + struct rsrc_card_priv *priv, + int idx, bool is_fe) { - struct device *dev = rsrc_priv_to_dev(priv); - const struct rsrc_card_of_data *of_data = rsrc_dev_to_of_data(dev); + struct snd_soc_dai_link *dai_link = rsrc_priv_to_link(priv, idx); + struct rsrc_card_dai *dai_props = rsrc_priv_to_props(priv, idx); struct of_phandle_args args; - struct device_node **p_node; - struct clk *clk; - const char **dai_name; - const char **name; - u32 val; int ret; - if (args_count) { - p_node = &dai_link->cpu_of_node; - dai_name = &dai_link->cpu_dai_name; - name = &dai_link->cpu_name; - } else { - p_node = &dai_link->codec_of_node; - dai_name = &dai_link->codec_dai_name; - name = &dai_link->codec_name; - } - - if (!np) { - /* use snd-soc-dummy */ - *p_node = NULL; - *dai_name = "snd-soc-dummy-dai"; - *name = "snd-soc-dummy"; - return 0; - } - /* * Get node via "sound-dai = <&phandle port>" * it will be used as xxx_of_node on soc_bind_dai_link() @@ -250,31 +199,82 @@ rsrc_card_sub_parse_of(struct rsrc_card_priv *priv, if (ret) return ret; - *p_node = args.np; + if (is_fe) { + /* BE is dummy */ + dai_link->codec_of_node = NULL; + dai_link->codec_dai_name = "snd-soc-dummy-dai"; + dai_link->codec_name = "snd-soc-dummy"; + + /* FE settings */ + dai_link->dynamic = 1; + dai_link->dpcm_merged_format = 1; + dai_link->cpu_of_node = args.np; + snd_soc_of_get_dai_name(np, &dai_link->cpu_dai_name); + + /* set dai_name */ + snprintf(dai_props->dai_name, DAI_NAME_NUM, "fe.%s", + dai_link->cpu_dai_name); + + /* + * In soc_bind_dai_link() will check cpu name after + * of_node matching if dai_link has cpu_dai_name. + * but, it will never match if name was created by + * fmt_single_name() remove cpu_dai_name if cpu_args + * was 0. See: + * fmt_single_name() + * fmt_multiple_name() + */ + if (!args.args_count) + dai_link->cpu_dai_name = NULL; + } else { + struct device *dev = rsrc_priv_to_dev(priv); + const struct rsrc_card_of_data *of_data; - /* Get dai->name */ - ret = snd_soc_of_get_dai_name(np, dai_name); - if (ret < 0) - return ret; + of_data = rsrc_dev_to_of_data(dev); - /* - * FIXME - * - * rsrc assumes DPCM playback/capture - */ - dai_link->dpcm_playback = 1; - dai_link->dpcm_capture = 1; + /* FE is dummy */ + dai_link->cpu_of_node = NULL; + dai_link->cpu_dai_name = "snd-soc-dummy-dai"; + dai_link->cpu_name = "snd-soc-dummy"; - if (args_count) { - *args_count = args.args_count; - dai_link->dynamic = 1; - dai_link->dpcm_merged_format = 1; - } else { - dai_link->no_pcm = 1; - priv->codec_conf.of_node = (*p_node); - priv->codec_conf.name_prefix = of_data->prefix; + /* BE settings */ + dai_link->no_pcm = 1; + dai_link->be_hw_params_fixup = rsrc_card_be_hw_params_fixup; + dai_link->codec_of_node = args.np; + snd_soc_of_get_dai_name(np, &dai_link->codec_dai_name); + + /* additional name prefix */ + priv->codec_conf.of_node = dai_link->codec_of_node; + priv->codec_conf.name_prefix = of_data->prefix; + + /* set dai_name */ + snprintf(dai_props->dai_name, DAI_NAME_NUM, "be.%s", + dai_link->codec_dai_name); } + /* Simple Card assumes platform == cpu */ + dai_link->platform_of_node = dai_link->cpu_of_node; + dai_link->dpcm_playback = 1; + dai_link->dpcm_capture = 1; + dai_link->name = dai_props->dai_name; + dai_link->stream_name = dai_props->dai_name; + dai_link->ops = &rsrc_card_ops; + dai_link->init = rsrc_card_dai_init; + + return 0; +} + +static int rsrc_card_parse_clk(struct device_node *np, + struct rsrc_card_priv *priv, + int idx, bool is_fe) +{ + struct snd_soc_dai_link *dai_link = rsrc_priv_to_link(priv, idx); + struct rsrc_card_dai *dai_props = rsrc_priv_to_props(priv, idx); + struct clk *clk; + struct device_node *of_np = is_fe ? dai_link->cpu_of_node : + dai_link->codec_of_node; + u32 val; + /* * Parse dai->sysclk come from "clocks = <&xxx>" * (if system has common clock) @@ -286,103 +286,48 @@ rsrc_card_sub_parse_of(struct rsrc_card_priv *priv, if (IS_ERR(clk)) return PTR_ERR(clk); - dai->sysclk = clk_get_rate(clk); - dai->clk = clk; + dai_props->sysclk = clk_get_rate(clk); + dai_props->clk = clk; } else if (!of_property_read_u32(np, "system-clock-frequency", &val)) { - dai->sysclk = val; + dai_props->sysclk = val; } else { - clk = of_clk_get(args.np, 0); + clk = of_clk_get(of_np, 0); if (!IS_ERR(clk)) - dai->sysclk = clk_get_rate(clk); + dai_props->sysclk = clk_get_rate(clk); } return 0; } static int rsrc_card_dai_link_of(struct device_node *node, + struct device_node *np, struct rsrc_card_priv *priv, int idx) { struct device *dev = rsrc_priv_to_dev(priv); - struct snd_soc_dai_link *dai_link = rsrc_priv_to_link(priv, idx); - struct rsrc_card_dai_props *dai_props = rsrc_priv_to_props(priv, idx); - struct device_node *cpu = NULL; - struct device_node *codec = NULL; - char *name = dai_props->dai_name; - char prop[128]; - int ret, cpu_args; - - cpu = of_get_child_by_name(node, "cpu"); - codec = of_get_child_by_name(node, "codec"); - - if (!cpu || !codec) { - ret = -EINVAL; - dev_err(dev, "%s: Can't find %s DT node\n", __func__, prop); - goto dai_link_of_err; - } + struct rsrc_card_dai *dai_props = rsrc_priv_to_props(priv, idx); + bool is_fe = false; + int ret; - ret = rsrc_card_parse_daifmt(node, priv, codec, idx); - if (ret < 0) - goto dai_link_of_err; + if (0 == strcmp(np->name, "cpu")) + is_fe = true; - ret = rsrc_card_sub_parse_of(priv, (idx == IDX_CPU) ? cpu : NULL, - &dai_props->cpu_dai, - dai_link, - &cpu_args); + ret = rsrc_card_parse_daifmt(node, np, priv, idx, is_fe); if (ret < 0) - goto dai_link_of_err; + return ret; - ret = rsrc_card_sub_parse_of(priv, (idx == IDX_CODEC) ? codec : NULL, - &dai_props->codec_dai, - dai_link, - NULL); + ret = rsrc_card_parse_links(np, priv, idx, is_fe); if (ret < 0) - goto dai_link_of_err; - - if (!dai_link->cpu_dai_name || !dai_link->codec_dai_name) { - ret = -EINVAL; - goto dai_link_of_err; - } - - /* Simple Card assumes platform == cpu */ - dai_link->platform_of_node = dai_link->cpu_of_node; - - snprintf(name, DAI_NAME_NUM, "%s.%s", - dai_link->dynamic ? "fe" : "be", - dai_link->dynamic ? dai_link->cpu_dai_name : - dai_link->codec_dai_name); - dai_link->name = dai_link->stream_name = name; - dai_link->ops = &rsrc_card_ops; - dai_link->init = rsrc_card_dai_init; - - if (idx == IDX_CODEC) - dai_link->be_hw_params_fixup = rsrc_card_be_hw_params_fixup; - - dev_dbg(dev, "\tname : %s\n", dai_link->stream_name); - dev_dbg(dev, "\tcpu : %s / %04x / %d\n", - dai_link->cpu_dai_name, - dai_props->cpu_dai.fmt, - dai_props->cpu_dai.sysclk); - dev_dbg(dev, "\tcodec : %s / %04x / %d\n", - dai_link->codec_dai_name, - dai_props->codec_dai.fmt, - dai_props->codec_dai.sysclk); + return ret; - /* - * In soc_bind_dai_link() will check cpu name after - * of_node matching if dai_link has cpu_dai_name. - * but, it will never match if name was created by - * fmt_single_name() remove cpu_dai_name if cpu_args - * was 0. See: - * fmt_single_name() - * fmt_multiple_name() - */ - if (!cpu_args) - dai_link->cpu_dai_name = NULL; + ret = rsrc_card_parse_clk(np, priv, idx, is_fe); + if (ret < 0) + return ret; -dai_link_of_err: - of_node_put(cpu); - of_node_put(codec); + dev_dbg(dev, "\t%s / %04x / %d\n", + dai_props->dai_name, + dai_props->fmt, + dai_props->sysclk); return ret; } @@ -392,9 +337,9 @@ static int rsrc_card_parse_of(struct device_node *node, struct device *dev) { const struct rsrc_card_of_data *of_data = rsrc_dev_to_of_data(dev); - struct rsrc_card_dai_props *props; + struct rsrc_card_dai *props; struct snd_soc_dai_link *links; - + struct device_node *np; int ret; int i, num; @@ -411,9 +356,6 @@ static int rsrc_card_parse_of(struct device_node *node, priv->dai_link = links; priv->dai_num = num; - /* Parse the card name from DT */ - snd_soc_of_parse_card_name(&priv->snd_card, "card-name"); - /* Init snd_soc_card */ priv->snd_card.owner = THIS_MODULE; priv->snd_card.dev = dev; @@ -424,6 +366,9 @@ static int rsrc_card_parse_of(struct device_node *node, priv->snd_card.of_dapm_routes = of_data->routes; priv->snd_card.num_of_dapm_routes = of_data->num_routes; + /* Parse the card name from DT */ + snd_soc_of_parse_card_name(&priv->snd_card, "card-name"); + /* sampling rate convert */ of_property_read_u32(node, "convert-rate", &priv->convert_rate); @@ -431,11 +376,12 @@ static int rsrc_card_parse_of(struct device_node *node, priv->snd_card.name ? priv->snd_card.name : "", priv->convert_rate); - /* FE/BE */ - for (i = 0; i < num; i++) { - ret = rsrc_card_dai_link_of(node, priv, i); + i = 0; + for_each_child_of_node(node, np) { + ret = rsrc_card_dai_link_of(node, np, priv, i); if (ret < 0) return ret; + i++; } if (!priv->snd_card.name)