From patchwork Thu Oct 8 16:12:35 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alex Deucher X-Patchwork-Id: 7354031 Return-Path: X-Original-To: patchwork-alsa-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id E883D9F1B9 for ; Thu, 8 Oct 2015 16:14:11 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 11BB0207E4 for ; Thu, 8 Oct 2015 16:14:10 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) by mail.kernel.org (Postfix) with ESMTP id A1ABC207D4 for ; Thu, 8 Oct 2015 16:14:08 +0000 (UTC) Received: by alsa0.perex.cz (Postfix, from userid 1000) id B29D2266861; Thu, 8 Oct 2015 18:14:07 +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=-2.5 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, NO_DNS_FOR_FROM, RCVD_IN_DNSWL_LOW, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 Received: from alsa0.perex.cz (localhost [IPv6:::1]) by alsa0.perex.cz (Postfix) with ESMTP id A13802667BD; Thu, 8 Oct 2015 18:13:03 +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 1ED2E2667C1; Thu, 8 Oct 2015 18:13:02 +0200 (CEST) Received: from mail-qg0-f66.google.com (mail-qg0-f66.google.com [209.85.192.66]) by alsa0.perex.cz (Postfix) with ESMTP id 5D4D4264F30 for ; Thu, 8 Oct 2015 18:12:53 +0200 (CEST) Received: by qgt47 with SMTP id 47so5214276qgt.1 for ; Thu, 08 Oct 2015 09:12:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=O1lTUDLm02DQSJbgwcWbphy+Gp8NQHEPe16ZSddTyp0=; b=TSe/St0sKsyIYaDqx79pF/sALXng5y/yPJpuWITcbFcgy5nrrANakkBXuy5LJrb15W pIS7lFscF9aQenwEPj4SCNY5rN6sWfEZMXvHSDWUm/w2osqPyLvgldG7UXLto6pME2A0 lOi6IhbMzN2KtntI5q9p7ylhpzj+NHHdDTGxylahfsqRzTmRWya0v37s8mDoraLENe3u qs2SEdFdmvABnG1OHjsjNBUPj/QhBQ0ao1HXhoy2wC4DuMrh4EWEr0AQ3HYmH7TjYDNb eef5Zd8nqnW09D23RlKrD/RM1zVkHkA4c7nmnrDp+KnnwB7lM+sXb99A91ZH5LPMJn42 Chlg== X-Received: by 10.140.104.51 with SMTP id z48mr9137811qge.21.1444320772830; Thu, 08 Oct 2015 09:12:52 -0700 (PDT) Received: from localhost.localdomain (static-74-96-105-49.washdc.fios.verizon.net. [74.96.105.49]) by smtp.gmail.com with ESMTPSA id s52sm18960467qge.19.2015.10.08.09.12.51 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 08 Oct 2015 09:12:52 -0700 (PDT) From: Alex Deucher X-Google-Original-From: Alex Deucher To: broonie@kernel.org, airlied@gmail.com, dri-devel@lists.freedesktop.org, alsa-devel@alsa-project.org, maruthi.bayyavarapu@amd.com, rajeevkumar.linux@gmail.com Date: Thu, 8 Oct 2015 12:12:35 -0400 Message-Id: <1444320760-21936-3-git-send-email-alexander.deucher@amd.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1444320760-21936-1-git-send-email-alexander.deucher@amd.com> References: <1444320760-21936-1-git-send-email-alexander.deucher@amd.com> Cc: tiwai@suse.de, Maruthi Srinivas Bayyavarapu , lgirdwood@gmail.com Subject: [alsa-devel] [PATCH 2/8] ASoC : dwc : add different playback/capture base 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: Maruthi Srinivas Bayyavarapu Some platforms (Ex: AMD CZ) can have separate dwc controllers with different base address for playback and capture. This patch adds necessary changes to support it. Platforms which make use of it can supply a quirk in platform data to make use of this. By default, playback and capture base addesses are assumed to be same. Signed-off-by: Maruthi Bayyavarapu --- sound/soc/dwc/designware_i2s.c | 93 ++++++++++++++++++++++-------------------- 1 file changed, 48 insertions(+), 45 deletions(-) diff --git a/sound/soc/dwc/designware_i2s.c b/sound/soc/dwc/designware_i2s.c index f427325..374a83e 100644 --- a/sound/soc/dwc/designware_i2s.c +++ b/sound/soc/dwc/designware_i2s.c @@ -89,7 +89,8 @@ union dw_i2s_snd_dma_data { }; struct dw_i2s_dev { - void __iomem *i2s_base; + void __iomem *i2s_pbase; + void __iomem *i2s_cbase; struct clk *clk; int active; unsigned int capability; @@ -118,10 +119,10 @@ static inline void i2s_disable_channels(struct dw_i2s_dev *dev, u32 stream) if (stream == SNDRV_PCM_STREAM_PLAYBACK) { for (i = 0; i < 4; i++) - i2s_write_reg(dev->i2s_base, TER(i), 0); + i2s_write_reg(dev->i2s_pbase, TER(i), 0); } else { for (i = 0; i < 4; i++) - i2s_write_reg(dev->i2s_base, RER(i), 0); + i2s_write_reg(dev->i2s_cbase, RER(i), 0); } } @@ -131,25 +132,25 @@ static inline void i2s_clear_irqs(struct dw_i2s_dev *dev, u32 stream) if (stream == SNDRV_PCM_STREAM_PLAYBACK) { for (i = 0; i < 4; i++) - i2s_write_reg(dev->i2s_base, TOR(i), 0); + i2s_write_reg(dev->i2s_pbase, TOR(i), 0); } else { for (i = 0; i < 4; i++) - i2s_write_reg(dev->i2s_base, ROR(i), 0); + i2s_write_reg(dev->i2s_cbase, ROR(i), 0); } } static void i2s_start(struct dw_i2s_dev *dev, struct snd_pcm_substream *substream) { - - i2s_write_reg(dev->i2s_base, IER, 1); - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - i2s_write_reg(dev->i2s_base, ITER, 1); - else - i2s_write_reg(dev->i2s_base, IRER, 1); - - i2s_write_reg(dev->i2s_base, CER, 1); + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + i2s_write_reg(dev->i2s_pbase, IER, 1); + i2s_write_reg(dev->i2s_pbase, ITER, 1); + i2s_write_reg(dev->i2s_pbase, CER, 1); + } else { + i2s_write_reg(dev->i2s_cbase, IER, 1); + i2s_write_reg(dev->i2s_cbase, IRER, 1); + i2s_write_reg(dev->i2s_cbase, CER, 1); + } } static void i2s_stop(struct dw_i2s_dev *dev, @@ -159,24 +160,25 @@ static void i2s_stop(struct dw_i2s_dev *dev, i2s_clear_irqs(dev, substream->stream); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - i2s_write_reg(dev->i2s_base, ITER, 0); - + i2s_write_reg(dev->i2s_pbase, ITER, 0); for (i = 0; i < 4; i++) { - irq = i2s_read_reg(dev->i2s_base, IMR(i)); - i2s_write_reg(dev->i2s_base, IMR(i), irq | 0x30); + irq = i2s_read_reg(dev->i2s_pbase, IMR(i)); + i2s_write_reg(dev->i2s_pbase, IMR(i), + irq | 0x30); } } else { - i2s_write_reg(dev->i2s_base, IRER, 0); + i2s_write_reg(dev->i2s_cbase, IRER, 0); for (i = 0; i < 4; i++) { - irq = i2s_read_reg(dev->i2s_base, IMR(i)); - i2s_write_reg(dev->i2s_base, IMR(i), irq | 0x03); + irq = i2s_read_reg(dev->i2s_cbase, IMR(i)); + i2s_write_reg(dev->i2s_cbase, IMR(i), + irq | 0x03); } } if (!dev->active) { - i2s_write_reg(dev->i2s_base, CER, 0); - i2s_write_reg(dev->i2s_base, IER, 0); + i2s_write_reg(dev->i2s_pbase, CER, 0); + i2s_write_reg(dev->i2s_pbase, IER, 0); } } @@ -253,23 +255,23 @@ static int dw_i2s_hw_params(struct snd_pcm_substream *substream, for (ch_reg = 0; ch_reg < (config->chan_nr / 2); ch_reg++) { if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - i2s_write_reg(dev->i2s_base, TCR(ch_reg), + i2s_write_reg(dev->i2s_pbase, TCR(ch_reg), xfer_resolution); - i2s_write_reg(dev->i2s_base, TFCR(ch_reg), 0x02); - irq = i2s_read_reg(dev->i2s_base, IMR(ch_reg)); - i2s_write_reg(dev->i2s_base, IMR(ch_reg), irq & ~0x30); - i2s_write_reg(dev->i2s_base, TER(ch_reg), 1); + i2s_write_reg(dev->i2s_pbase, TFCR(ch_reg), 0x02); + irq = i2s_read_reg(dev->i2s_pbase, IMR(ch_reg)); + i2s_write_reg(dev->i2s_pbase, IMR(ch_reg), irq & ~0x30); + i2s_write_reg(dev->i2s_pbase, TER(ch_reg), 1); } else { - i2s_write_reg(dev->i2s_base, RCR(ch_reg), + i2s_write_reg(dev->i2s_cbase, RCR(ch_reg), xfer_resolution); - i2s_write_reg(dev->i2s_base, RFCR(ch_reg), 0x07); - irq = i2s_read_reg(dev->i2s_base, IMR(ch_reg)); - i2s_write_reg(dev->i2s_base, IMR(ch_reg), irq & ~0x03); - i2s_write_reg(dev->i2s_base, RER(ch_reg), 1); + i2s_write_reg(dev->i2s_cbase, RFCR(ch_reg), 0x07); + irq = i2s_read_reg(dev->i2s_cbase, IMR(ch_reg)); + i2s_write_reg(dev->i2s_cbase, IMR(ch_reg), irq & ~0x03); + i2s_write_reg(dev->i2s_cbase, RER(ch_reg), 1); } } - i2s_write_reg(dev->i2s_base, CCR, ccr); + i2s_write_reg(dev->i2s_pbase, CCR, ccr); config->sample_rate = params_rate(params); @@ -307,9 +309,9 @@ static int dw_i2s_prepare(struct snd_pcm_substream *substream, struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - i2s_write_reg(dev->i2s_base, TXFFR, 1); + i2s_write_reg(dev->i2s_pbase, TXFFR, 1); else - i2s_write_reg(dev->i2s_base, RXFFR, 1); + i2s_write_reg(dev->i2s_cbase, RXFFR, 1); return 0; } @@ -450,8 +452,8 @@ static int dw_configure_dai(struct dw_i2s_dev *dev, * Read component parameter registers to extract * the I2S block's configuration. */ - u32 comp1 = i2s_read_reg(dev->i2s_base, I2S_COMP_PARAM_1); - u32 comp2 = i2s_read_reg(dev->i2s_base, I2S_COMP_PARAM_2); + u32 comp1 = i2s_read_reg(dev->i2s_pbase, I2S_COMP_PARAM_1); + u32 comp2 = i2s_read_reg(dev->i2s_pbase, I2S_COMP_PARAM_2); u32 idx; if (COMP1_TX_ENABLED(comp1)) { @@ -494,7 +496,7 @@ static int dw_configure_dai_by_pd(struct dw_i2s_dev *dev, struct resource *res, const struct i2s_platform_data *pdata) { - u32 comp1 = i2s_read_reg(dev->i2s_base, I2S_COMP_PARAM_1); + u32 comp1 = i2s_read_reg(dev->i2s_pbase, I2S_COMP_PARAM_1); u32 idx = COMP1_APB_DATA_WIDTH(comp1); int ret; @@ -524,8 +526,8 @@ static int dw_configure_dai_by_dt(struct dw_i2s_dev *dev, struct snd_soc_dai_driver *dw_i2s_dai, struct resource *res) { - u32 comp1 = i2s_read_reg(dev->i2s_base, I2S_COMP_PARAM_1); - u32 comp2 = i2s_read_reg(dev->i2s_base, I2S_COMP_PARAM_2); + u32 comp1 = i2s_read_reg(dev->i2s_pbase, I2S_COMP_PARAM_1); + u32 comp2 = i2s_read_reg(dev->i2s_pbase, I2S_COMP_PARAM_2); u32 fifo_depth = 1 << (1 + COMP1_FIFO_DEPTH_GLOBAL(comp1)); u32 idx = COMP1_APB_DATA_WIDTH(comp1); u32 idx2; @@ -589,11 +591,11 @@ static int dw_i2s_probe(struct platform_device *pdev) dw_i2s_dai->resume = dw_i2s_resume; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - dev->i2s_base = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(dev->i2s_base)) - return PTR_ERR(dev->i2s_base); + dev->i2s_pbase = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(dev->i2s_pbase)) + return PTR_ERR(dev->i2s_pbase); - dev->dev = &pdev->dev; + dev->i2s_cbase = dev->i2s_pbase; if (pdata) { dev->capability = pdata->cap; @@ -624,6 +626,7 @@ static int dw_i2s_probe(struct platform_device *pdev) return ret; } + dev->dev = &pdev->dev; dev_set_drvdata(&pdev->dev, dev); ret = devm_snd_soc_register_component(&pdev->dev, &dw_i2s_component, dw_i2s_dai, 1);