From patchwork Mon Nov 10 04:00:58 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kuninori Morimoto X-Patchwork-Id: 5263831 Return-Path: X-Original-To: patchwork-alsa-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 6CDC9C11AC for ; Mon, 10 Nov 2014 04:02:12 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 6EFAC20160 for ; Mon, 10 Nov 2014 04:02:11 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) by mail.kernel.org (Postfix) with ESMTP id 0972B20109 for ; Mon, 10 Nov 2014 04:02:10 +0000 (UTC) Received: by alsa0.perex.cz (Postfix, from userid 1000) id 1DFC62605F6; Mon, 10 Nov 2014 05:02:09 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Spam-Level: X-Spam-Status: No, score=-1.8 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=no version=3.3.1 Received: from alsa0.perex.cz (localhost [IPv6:::1]) by alsa0.perex.cz (Postfix) with ESMTP id A639326064A; Mon, 10 Nov 2014 05:01:32 +0100 (CET) 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 5FC38260642; Mon, 10 Nov 2014 05:01:31 +0100 (CET) Received: from mail-pd0-f172.google.com (mail-pd0-f172.google.com [209.85.192.172]) by alsa0.perex.cz (Postfix) with ESMTP id EFDE02605CC for ; Mon, 10 Nov 2014 05:00:59 +0100 (CET) Received: by mail-pd0-f172.google.com with SMTP id r10so6978467pdi.17 for ; Sun, 09 Nov 2014 20:00:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=date:message-id:from:to:cc:subject:user-agent:mime-version :content-type; bh=XjA/8o+k0VkQYVXruzkYbFFvStYuqw1YN29QKMKiiSo=; b=Bw/mWfGmGttyAwSlj88Ta9TgWe3oA1WSdT1TqExxuVqRhVqlHcJHlseZOFdB0BksdR acwm3bIH4R0GczpOm6uA3aW2JAvjzKf4obVmnBq+janj+h6oyvcc4JJs66NfCqIsvNz6 1K720QIanRXQ8FmN8cIJGhiNHFm9vy7/Kd1p5UXwI/P9Odn/0bO5HH+CIwjRBdAhSMPv meAP3Is2xnJgZDrBz77RAo0CrxPb+STpoheloMVqLAtr6X+MiYgT9Ufb3iI28xQ7UMv5 TJ4YxPTv7IOK/2PWAARsfVq34SFeVzFPXoSLsfRhu1kufsFsFv5jOuJh4z942TwWIXty OnJQ== X-Received: by 10.68.213.8 with SMTP id no8mr29526031pbc.92.1415592059089; Sun, 09 Nov 2014 20:00:59 -0800 (PST) Received: from remon.gmail.com (49.14.32.202.bf.2iij.net. [202.32.14.49]) by mx.google.com with ESMTPSA id qr8sm13740742pbc.96.2014.11.09.20.00.56 for (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Sun, 09 Nov 2014 20:00:58 -0800 (PST) Date: Sun, 09 Nov 2014 20:00:58 -0800 (PST) Message-ID: <87389rogaw.wl%kuninori.morimoto.gx@gmail.com> From: Kuninori Morimoto To: Mark Brown User-Agent: Wanderlust/2.14.0 Emacs/23.3 Mule/6.0 MIME-Version: 1.0 (generated by SEMI 1.14.6 - "Maruoka") Cc: Linux-ALSA , Simon , Magnus , Liam Girdwood , Kuninori Morimoto Subject: [alsa-devel] [PATCH] ASoC: rsnd: fallback to PIO mode if DMA mode was failed 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 Current Renesas R-Car sound driver probe will be failed if it try to use DMA mode and it couldn't use for some reasons. But PIO mode works even though in such case. This patch try to fallback to PIO mode if DMA mode probing was failed. Signed-off-by: Kuninori Morimoto --- sound/soc/sh/rcar/core.c | 74 +++++++++++++++++++++++++++++++++++++++++++--- sound/soc/sh/rcar/ssi.c | 15 ++++++++++ 2 files changed, 85 insertions(+), 4 deletions(-) diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 5205618..110b99d 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -349,7 +349,7 @@ int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, dma_name); if (!dma->chan) { dev_err(dev, "can't get dma channel\n"); - return -EIO; + goto rsnd_dma_channel_err; } ret = dmaengine_slave_config(dma->chan, &cfg); @@ -363,8 +363,15 @@ int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, rsnd_dma_init_err: rsnd_dma_quit(priv, dma); +rsnd_dma_channel_err: - return ret; + /* + * DMA failed. try to PIO mode + * see + * rsnd_ssi_dma_remove() + * rsnd_rdai_continuance_probe() + */ + return -EAGAIN; } void rsnd_dma_quit(struct rsnd_priv *priv, @@ -456,6 +463,13 @@ static int rsnd_dai_connect(struct rsnd_mod *mod, return 0; } +static void rsnd_dai_disconnect(struct rsnd_mod *mod, + struct rsnd_dai_stream *io) +{ + mod->io = NULL; + io->mod[mod->type] = NULL; +} + int rsnd_dai_id(struct rsnd_priv *priv, struct rsnd_dai *rdai) { int id = rdai - priv->rdai; @@ -686,6 +700,20 @@ static const struct snd_soc_dai_ops rsnd_soc_dai_ops = { ret; \ }) +#define rsnd_path_break(priv, io, type) \ +{ \ + struct rsnd_mod *mod; \ + int id = -1; \ + \ + if (rsnd_is_enable_path(io, type)) { \ + id = rsnd_info_id(priv, io, type); \ + if (id >= 0) { \ + mod = rsnd_##type##_mod_get(priv, id); \ + rsnd_dai_disconnect(mod, io); \ + } \ + } \ +} + static int rsnd_path_init(struct rsnd_priv *priv, struct rsnd_dai *rdai, struct rsnd_dai_stream *io) @@ -977,6 +1005,44 @@ static const struct snd_soc_component_driver rsnd_soc_component = { .name = "rsnd", }; +static int rsnd_rdai_continuance_probe(struct rsnd_priv *priv, + struct rsnd_dai *rdai, + int is_play) +{ + struct rsnd_dai_stream *io = is_play ? &rdai->playback : &rdai->capture; + int ret; + + ret = rsnd_dai_call(probe, io, rdai); + if (ret == -EAGAIN) { + /* + * Fallback to PIO mode + */ + + /* + * call "remove" for SSI/SRC/DVC + * SSI will be switch to PIO mode if it was DMA mode + * see + * rsnd_dma_init() + * rsnd_ssi_dma_remove() + */ + rsnd_dai_call(remove, io, rdai); + + /* + * remove SRC/DVC from DAI, + */ + rsnd_path_break(priv, io, src); + rsnd_path_break(priv, io, dvc); + + /* + * retry to "probe". + * DAI has SSI which is PIO mode only now. + */ + ret = rsnd_dai_call(probe, io, rdai); + } + + return ret; +} + /* * rsnd probe */ @@ -1038,11 +1104,11 @@ static int rsnd_probe(struct platform_device *pdev) } for_each_rsnd_dai(rdai, priv, i) { - ret = rsnd_dai_call(probe, &rdai->playback, rdai); + ret = rsnd_rdai_continuance_probe(priv, rdai, 1); if (ret) goto exit_snd_probe; - ret = rsnd_dai_call(probe, &rdai->capture, rdai); + ret = rsnd_rdai_continuance_probe(priv, rdai, 0); if (ret) goto exit_snd_probe; } diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index cae08b7..346d3dc 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -465,8 +465,23 @@ static int rsnd_ssi_dma_probe(struct rsnd_mod *mod, static int rsnd_ssi_dma_remove(struct rsnd_mod *mod, struct rsnd_dai *rdai) { + struct rsnd_priv *priv = rsnd_mod_to_priv(mod); + struct device *dev = rsnd_priv_to_dev(priv); + rsnd_dma_quit(rsnd_mod_to_priv(mod), rsnd_mod_to_dma(mod)); + /* + * fallback to PIO + * + * SSI .probe might be called again. + * see + * rsnd_rdai_continuance_probe() + */ + mod->ops = &rsnd_ssi_pio_ops; + + dev_info(dev, "%s[%d] fallback to PIO mode\n", + rsnd_mod_name(mod), rsnd_mod_id(mod)); + return 0; }