From patchwork Wed Sep 23 17:03:00 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alex Deucher X-Patchwork-Id: 7251351 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 2E7FE9F30C for ; Wed, 23 Sep 2015 17:04:05 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 3236920A3B for ; Wed, 23 Sep 2015 17:04:04 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) by mail.kernel.org (Postfix) with ESMTP id 74BD820A2A for ; Wed, 23 Sep 2015 17:04:02 +0000 (UTC) Received: by alsa0.perex.cz (Postfix, from userid 1000) id AB19B2657BC; Wed, 23 Sep 2015 19:04:01 +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, 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 2C592260468; Wed, 23 Sep 2015 19:03:26 +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 0E57E262626; Wed, 23 Sep 2015 19:03:24 +0200 (CEST) Received: from mail-qk0-f177.google.com (mail-qk0-f177.google.com [209.85.220.177]) by alsa0.perex.cz (Postfix) with ESMTP id 7972D260468 for ; Wed, 23 Sep 2015 19:03:15 +0200 (CEST) Received: by qkdw123 with SMTP id w123so19751447qkd.0 for ; Wed, 23 Sep 2015 10:03:15 -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=RPOPsTsk+VPM3oadjs+GHJcGXBDisfFZqT0+H5jUGRA=; b=jUVwcy7RHvJ++TRuaY09Rdmp5Y1iERd+jY6IgqsOwlfxnwmKKoaegpq+TXnJNIcn3t POcBSFk3zdNcCjIve561y/7zFCU+0ojgC/HmVzlOSJizqfW7WZckpsxfTMI7f+ZoFQNP VMfpSl1PVORt+xsOIzIf8FeNBUvn0tJUBmpSBfKFLfkQxhlgHsPuuPNnmGLIy3Js7uDj qJHc2wyBnh4K9Lu3Ewz9GkaXf0O562L6znCalx7TXHolXhuESDuKfjrsVcVUtaaH/zvw qH+F//8lPe22amIfUWd8Pu8uoHjMqEHK0EKLfbOF9PMFoVo5W1a0mI5GT0mpj/yt/ejg K0OQ== X-Received: by 10.55.49.75 with SMTP id x72mr39219234qkx.45.1443027794850; Wed, 23 Sep 2015 10:03:14 -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 68sm1813151qgy.16.2015.09.23.10.03.14 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 23 Sep 2015 10:03:14 -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: Wed, 23 Sep 2015 13:03:00 -0400 Message-Id: <1443027783-2591-3-git-send-email-alexander.deucher@amd.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1443027783-2591-1-git-send-email-alexander.deucher@amd.com> References: <1443027783-2591-1-git-send-email-alexander.deucher@amd.com> Cc: tiwai@suse.de, Maruthi Srinivas Bayyavarapu , lgirdwood@gmail.com Subject: [alsa-devel] [PATCH 1/5] ASoC : dwc : support dw i2s in slave mode 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 dw i2s controller can work in slave mode, codec being master. Added a device caps (DW_I2S_SLAVE) to support slave mode operation. This can be added to platform data to support slave mode. Signed-off-by: Maruthi Bayyavarapu --- include/sound/designware_i2s.h | 1 + sound/soc/dwc/designware_i2s.c | 86 ++++++++++++++++++++++++------------------ 2 files changed, 51 insertions(+), 36 deletions(-) diff --git a/include/sound/designware_i2s.h b/include/sound/designware_i2s.h index 3a8fca9..08e3418 100644 --- a/include/sound/designware_i2s.h +++ b/include/sound/designware_i2s.h @@ -38,6 +38,7 @@ struct i2s_clk_config_data { struct i2s_platform_data { #define DWC_I2S_PLAY (1 << 0) #define DWC_I2S_RECORD (1 << 1) + #define DW_I2S_SLAVE (1 << 2) unsigned int cap; int channel; u32 snd_fmts; diff --git a/sound/soc/dwc/designware_i2s.c b/sound/soc/dwc/designware_i2s.c index a3e97b4..e3dcaca 100644 --- a/sound/soc/dwc/designware_i2s.c +++ b/sound/soc/dwc/designware_i2s.c @@ -209,6 +209,7 @@ static int dw_i2s_hw_params(struct snd_pcm_substream *substream, { struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); struct i2s_clk_config_data *config = &dev->config; + const struct i2s_platform_data *pdata = dev_get_platdata(dai->dev); u32 ccr, xfer_resolution, ch_reg, irq; int ret; @@ -273,23 +274,25 @@ static int dw_i2s_hw_params(struct snd_pcm_substream *substream, config->sample_rate = params_rate(params); - if (dev->i2s_clk_cfg) { - ret = dev->i2s_clk_cfg(config); - if (ret < 0) { - dev_err(dev->dev, "runtime audio clk config fail\n"); - return ret; + if (!(pdata->cap & DW_I2S_SLAVE)) { + if (dev->i2s_clk_cfg) { + ret = dev->i2s_clk_cfg(config); + if (ret < 0) { + dev_err(dev->dev, "runtime audio clk config fail\n"); + return ret; } - } else { - u32 bitclk = config->sample_rate * config->data_width * 2; - - ret = clk_set_rate(dev->clk, bitclk); - if (ret) { - dev_err(dev->dev, "Can't set I2S clock rate: %d\n", - ret); - return ret; + } else { + u32 bitclk = config->sample_rate * + config->data_width * 2; + + ret = clk_set_rate(dev->clk, bitclk); + if (ret) { + dev_err(dev->dev, "Can't set I2S clock rate: %d\n", + ret); + return ret; + } } } - return 0; } @@ -356,16 +359,20 @@ static const struct snd_soc_component_driver dw_i2s_component = { static int dw_i2s_suspend(struct snd_soc_dai *dai) { struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); + const struct i2s_platform_data *pdata = dev_get_platdata(dai->dev); - clk_disable(dev->clk); + if (!(pdata->cap & DW_I2S_SLAVE)) + clk_disable(dev->clk); return 0; } static int dw_i2s_resume(struct snd_soc_dai *dai) { struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); + const struct i2s_platform_data *pdata = dev_get_platdata(dai->dev); - clk_enable(dev->clk); + if (!(pdata->cap & DW_I2S_SLAVE)) + clk_enable(dev->clk); return 0; } @@ -529,6 +536,7 @@ static int dw_i2s_probe(struct platform_device *pdev) struct resource *res; int ret; struct snd_soc_dai_driver *dw_i2s_dai; + const char *clk_id; dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); if (!dev) { @@ -550,33 +558,36 @@ static int dw_i2s_probe(struct platform_device *pdev) return PTR_ERR(dev->i2s_base); dev->dev = &pdev->dev; + if (pdata) { + clk_id = NULL; ret = dw_configure_dai_by_pd(dev, dw_i2s_dai, res, pdata); - if (ret < 0) - return ret; - dev->capability = pdata->cap; - dev->i2s_clk_cfg = pdata->i2s_clk_cfg; - if (!dev->i2s_clk_cfg) { - dev_err(&pdev->dev, "no clock configure method\n"); - return -ENODEV; - } - - dev->clk = devm_clk_get(&pdev->dev, NULL); } else { + clk_id = "i2sclk"; ret = dw_configure_dai_by_dt(dev, dw_i2s_dai, res); - if (ret < 0) - return ret; - - dev->clk = devm_clk_get(&pdev->dev, "i2sclk"); } - if (IS_ERR(dev->clk)) - return PTR_ERR(dev->clk); - - ret = clk_prepare_enable(dev->clk); if (ret < 0) return ret; + if (!(pdata->cap & DW_I2S_SLAVE)) { + if (pdata) { + dev->i2s_clk_cfg = pdata->i2s_clk_cfg; + if (!dev->i2s_clk_cfg) { + dev_err(&pdev->dev, "no clock configure method\n"); + return -ENODEV; + } + } + dev->clk = devm_clk_get(&pdev->dev, clk_id); + + if (IS_ERR(dev->clk)) + return PTR_ERR(dev->clk); + + ret = clk_prepare_enable(dev->clk); + if (ret < 0) + return ret; + } + dev_set_drvdata(&pdev->dev, dev); ret = devm_snd_soc_register_component(&pdev->dev, &dw_i2s_component, dw_i2s_dai, 1); @@ -597,15 +608,18 @@ static int dw_i2s_probe(struct platform_device *pdev) return 0; err_clk_disable: - clk_disable_unprepare(dev->clk); + if (!(pdata->cap & DW_I2S_SLAVE)) + clk_disable_unprepare(dev->clk); return ret; } static int dw_i2s_remove(struct platform_device *pdev) { + const struct i2s_platform_data *pdata = pdev->dev.platform_data; struct dw_i2s_dev *dev = dev_get_drvdata(&pdev->dev); - clk_disable_unprepare(dev->clk); + if (!(pdata->cap & DW_I2S_SLAVE)) + clk_disable_unprepare(dev->clk); return 0; }