From patchwork Mon Mar 12 15:57:51 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Code Kipper X-Patchwork-Id: 10276661 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 155EF603B5 for ; Mon, 12 Mar 2018 15:58:46 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0387828AF3 for ; Mon, 12 Mar 2018 15:58:46 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id EC7DC28B14; Mon, 12 Mar 2018 15:58:45 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.8 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE, T_DKIM_INVALID autolearn=no version=3.3.1 Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 070EA28AF3 for ; Mon, 12 Mar 2018 15:58:45 +0000 (UTC) Received: from alsa0.perex.cz (localhost [127.0.0.1]) by alsa0.perex.cz (Postfix) with ESMTP id E5F6A2676CB; Mon, 12 Mar 2018 16:58:10 +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 C32992673DC; Mon, 12 Mar 2018 16:58:03 +0100 (CET) Received: from mail-lf0-f67.google.com (mail-lf0-f67.google.com [209.85.215.67]) by alsa0.perex.cz (Postfix) with ESMTP id 2B3262673D8 for ; Mon, 12 Mar 2018 16:58:02 +0100 (CET) Received: by mail-lf0-f67.google.com with SMTP id w16-v6so2934399lfc.13 for ; Mon, 12 Mar 2018 08:58:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=hhJuyJlqm6dZILjeLRL4PI+4oPYLb3i0Bc1HKwHenW0=; b=DRoN4qWSm+tejjqWKYdk7oiXypKFQQ8Q4A27yWXVA+qpSVp08vgsKsiFVWhH2AgnlA 2xlp6zKDWk65h0EMF10mU0LKbXN2WKGsBi06ksWKRXhsUSffReLtRAtEHl89v4J3p/H5 oC+ZeWmJVlmA6uV8ATYjD+LCtQqhktgTqT3zAjE6QpfTjdThLCP7iai/bGvYqZFUmoJW evczKFMdIdO0bFcNxtZzeT9Iwx7iszfMfpd/Ikr6pQQvrWtpPJCYd8D+WIs6CV9/zXs5 fLeMYjHNhRNYzKIEBGLXmiE4TYUnalIMyWB8P6PsOH2kXZLbvmVT7OOevPE7bheNbCi/ /GeA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=hhJuyJlqm6dZILjeLRL4PI+4oPYLb3i0Bc1HKwHenW0=; b=nAqSugdLxqJGnHRQ/WN3JQPgLR3ggAHHKhF+0Va5AxqLqpzWXpw5HwEA9Cki+TfN10 nKuycctMqJpFgsH5tVhcaDYp0vFQH7buGKZafF65nPnLd8QcpACL9b8VyYkFkfBoXAfD xi71tLP3KnebPPLdnEo7X/qQ8QoW5UJRDHvW0Y1zupXx2IcAlYMNasy1A/XqA+0lgm0Y UiEUTUeSFdX95jJSp6XdqqX/ZNFzDJ9wG+U6U8iaMLUtuBFAE5I5wABUI24I3Es5h7YO g+cQuKZ9wewAxWrcblv4NrFLUZhIBv7BPi4+HtdFGB1Y20NjB63k+DUSdrh5ol22olAt Wuiw== X-Gm-Message-State: AElRT7HZ25yqCRamle8t/NMe1etuUDrt1Pbt1mOyU22RSgC0JD0x8HRj c2CkrvsKQ5p6JzPNoev2k7M= X-Google-Smtp-Source: AG47ELtsBpDSpGR+6aRIJoDlj+/6rnCaX8eDIzzpILl4h/kcpIJweTMwaulsB9E0DtbqTn7CTSvBVg== X-Received: by 2002:a19:964e:: with SMTP id y75-v6mr5676062lfd.81.1520870281574; Mon, 12 Mar 2018 08:58:01 -0700 (PDT) Received: from localhost.localdomain (c83-253-254-90.bredband.comhem.se. [83.253.254.90]) by smtp.gmail.com with ESMTPSA id h11-v6sm1833448lfd.88.2018.03.12.08.58.00 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 12 Mar 2018 08:58:00 -0700 (PDT) From: codekipper@gmail.com To: maxime.ripard@free-electrons.com, wens@csie.org, linux-sunxi@googlegroups.com Date: Mon, 12 Mar 2018 16:57:51 +0100 Message-Id: <20180312155753.9478-5-codekipper@gmail.com> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180312155753.9478-1-codekipper@gmail.com> References: <20180312155753.9478-1-codekipper@gmail.com> Cc: alsa-devel@alsa-project.org, Marcus Cooper , lgirdwood@gmail.com, linux-kernel@vger.kernel.org, be17068@iperbole.bo.it, broonie@kernel.org, linux-arm-kernel@lists.infradead.org Subject: [alsa-devel] [PATCH v2 4/6] ASoC: sun4i-i2s: Add multi-lane functionality 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: , MIME-Version: 1.0 Errors-To: alsa-devel-bounces@alsa-project.org Sender: alsa-devel-bounces@alsa-project.org X-Virus-Scanned: ClamAV using ClamSMTP From: Marcus Cooper The i2s block supports multi-lane i2s output however this functionality is only possible in earlier SoCs where the pins are exposed and for the i2s block used for HDMI audio on the later SoCs. To enable this functionality, an optional property has been added to the bindings. Signed-off-by: Marcus Cooper --- .../devicetree/bindings/sound/sun4i-i2s.txt | 3 ++ sound/soc/sunxi/sun4i-i2s.c | 48 +++++++++++++++++----- 2 files changed, 41 insertions(+), 10 deletions(-) diff --git a/Documentation/devicetree/bindings/sound/sun4i-i2s.txt b/Documentation/devicetree/bindings/sound/sun4i-i2s.txt index 48addef65b8f..3f966ac61b9e 100644 --- a/Documentation/devicetree/bindings/sound/sun4i-i2s.txt +++ b/Documentation/devicetree/bindings/sound/sun4i-i2s.txt @@ -33,6 +33,9 @@ Optional properties: configured to extend the slot width to the value specified. Min 8, Max 32. +- allwinner,playback-channels: if this property is present then the number + of available channels is extended and the + outputs enabled. Example: i2s0: i2s@1c22400 { diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c index 2bd0befa02a8..436480df1844 100644 --- a/sound/soc/sunxi/sun4i-i2s.c +++ b/sound/soc/sunxi/sun4i-i2s.c @@ -27,7 +27,7 @@ #define SUN4I_I2S_CTRL_REG 0x00 #define SUN4I_I2S_CTRL_SDO_EN_MASK GENMASK(11, 8) -#define SUN4I_I2S_CTRL_SDO_EN(sdo) BIT(8 + (sdo)) +#define SUN4I_I2S_CTRL_SDO_EN(lines) (((1 << lines) - 1) << 8) #define SUN4I_I2S_CTRL_MODE_MASK BIT(5) #define SUN4I_I2S_CTRL_MODE_SLAVE (1 << 5) #define SUN4I_I2S_CTRL_MODE_MASTER (0 << 5) @@ -394,14 +394,23 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream, struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai); int sr, wss, channels; u32 width; + int lines; channels = params_channels(params); - if (channels != 2) { + if ((channels > dai->driver->playback.channels_max) || + (channels < dai->driver->playback.channels_min)) { dev_err(dai->dev, "Unsupported number of channels: %d\n", channels); return -EINVAL; } + lines = (channels + 1) / 2; + + /* Enable the required output lines */ + regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG, + SUN4I_I2S_CTRL_SDO_EN_MASK, + SUN4I_I2S_CTRL_SDO_EN(lines)); + if (i2s->variant->has_chcfg) { regmap_update_bits(i2s->regmap, SUN8I_I2S_CHAN_CFG_REG, SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM_MASK, @@ -412,8 +421,19 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream, } /* Map the channels for playback and capture */ - regmap_field_write(i2s->field_txchanmap, 0x76543210); regmap_field_write(i2s->field_rxchanmap, 0x00003210); + regmap_field_write(i2s->field_txchanmap, 0x10); + if (i2s->variant->has_chsel_tx_chen) { + if (channels > 2) + regmap_write(i2s->regmap, + SUN8I_I2S_TX_CHAN_MAP_REG+4, 0x32); + if (channels > 4) + regmap_write(i2s->regmap, + SUN8I_I2S_TX_CHAN_MAP_REG+8, 0x54); + if (channels > 6) + regmap_write(i2s->regmap, + SUN8I_I2S_TX_CHAN_MAP_REG+12, 0x76); + } /* Configure the channels */ regmap_field_write(i2s->field_txchansel, @@ -692,12 +712,6 @@ static int sun4i_i2s_startup(struct snd_pcm_substream *substream, regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG, SUN4I_I2S_CTRL_GL_EN, SUN4I_I2S_CTRL_GL_EN); - /* Enable the first output line */ - regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG, - SUN4I_I2S_CTRL_SDO_EN_MASK, - SUN4I_I2S_CTRL_SDO_EN(0)); - - return clk_prepare_enable(i2s->mod_clk); } @@ -1073,6 +1087,7 @@ static int sun4i_i2s_init_regmap_fields(struct device *dev, static int sun4i_i2s_probe(struct platform_device *pdev) { struct sun4i_i2s *i2s; + struct snd_soc_dai_driver *soc_dai; struct resource *res; void __iomem *regs; int irq, ret, val; @@ -1148,6 +1163,19 @@ static int sun4i_i2s_probe(struct platform_device *pdev) i2s->slot_width = val; } + soc_dai = devm_kmemdup(&pdev->dev, &sun4i_i2s_dai, + sizeof(*soc_dai), GFP_KERNEL); + if (!soc_dai) { + ret = -ENOMEM; + goto err_pm_disable; + } + + if (!of_property_read_u32(pdev->dev.of_node, + "allwinner,playback-channels", &val)) { + if (val >= 2 && val <= 8) + soc_dai->playback.channels_max = val; + } + pm_runtime_enable(&pdev->dev); if (!pm_runtime_enabled(&pdev->dev)) { ret = sun4i_i2s_runtime_resume(&pdev->dev); @@ -1157,7 +1185,7 @@ static int sun4i_i2s_probe(struct platform_device *pdev) ret = devm_snd_soc_register_component(&pdev->dev, &sun4i_i2s_component, - &sun4i_i2s_dai, 1); + soc_dai, 1); if (ret) { dev_err(&pdev->dev, "Could not register DAI\n"); goto err_suspend;