From patchwork Tue Dec 19 17:00:18 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicolin Chen X-Patchwork-Id: 10123815 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 BB03F603B5 for ; Tue, 19 Dec 2017 17:04:38 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9E47B2903E for ; Tue, 19 Dec 2017 17:04:38 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 92947290EB; Tue, 19 Dec 2017 17:04:38 +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 98FD52903E for ; Tue, 19 Dec 2017 17:04:37 +0000 (UTC) Received: from alsa0.perex.cz (localhost [127.0.0.1]) by alsa0.perex.cz (Postfix) with ESMTP id 11502267749; Tue, 19 Dec 2017 18:01:34 +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 9FABF26773D; Tue, 19 Dec 2017 18:01:31 +0100 (CET) Received: from mail-pg0-f68.google.com (mail-pg0-f68.google.com [74.125.83.68]) by alsa0.perex.cz (Postfix) with ESMTP id 60E76267700 for ; Tue, 19 Dec 2017 18:01:23 +0100 (CET) Received: by mail-pg0-f68.google.com with SMTP id b18so10765491pgv.10 for ; Tue, 19 Dec 2017 09:01:23 -0800 (PST) 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=N8QOukjrUownP3WbZrfaSYhlUM1RkmGCEvOhOfjBGgk=; b=E2L8uxX3xFkZAD83OwKuiFYMXK3aJ6bXYi7ifmNvpmzQHJLGJSfly3wPbiomInVDY7 /Z81K6SjMz2YN0T4ThyxH4bgSrypEyh09Cq28DsM2Uj9fErJBsYHBb2Wkb0b4o6hPdGT WDj2Hc5tpBEIduz0tgONgUIGE11tGp/Ol37I7KfTaAlCw6Pbsptf3bc0Wm6NWR/yoDEb r/Gn/OgQsncbxQufGvFiojJWpUySzBixOkZJ026pRoPT8XNaqP7Zljo6XzZB9ud+ks/x bwSBSowaTSpvGCiKY2HwngFRJvkRLwfQYUQZqDpkBCcLqp1Ziif7RtjfaJY5EWToLBcZ vY+g== 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=N8QOukjrUownP3WbZrfaSYhlUM1RkmGCEvOhOfjBGgk=; b=Q1zEwy67svi1davFWzL4ukOn70VBKZP5lionOetDUNvC1KdBAmvnD7oACJWoypep5q 3TyZNgHyPLzMNnbqlUUC6vBK3axd6CYz5I91MZ4mVdpwYDA6AFO7e/4RUfp0jePxJLYE BLvUISomZXn4aUv5owWq6nddoDOhvL/Fib1tCEifAT+lPZd5kRvYqs6mPK23P7xzJc36 rdJNkehuDJft1fmgyFaMe5MOI90TnalJflvg3DANlGIGPC/6pNjPvAehR547pLbEs+bR Ms6ESgIFECYnVIm1HUPTz+ltQTrSFsbu1MTLUIUTuxUQRU5MkV1OqoGT/FCKi4GfuBAs dYRQ== X-Gm-Message-State: AKGB3mKlQlVAsee3oJT0XFkN4IG6vys3dzameklzkbTC9VMLAcovA89q anek0vubEXzICTusrIKh61o= X-Google-Smtp-Source: ACJfBosqhM6vZW7tNOzK/M0xLK1tVCZ2Lrit8pbbynvCknfVqCAlEjWWrz3ln1ZcukCFb94QPQ4Ajg== X-Received: by 10.98.193.1 with SMTP id i1mr3921924pfg.29.1513702882637; Tue, 19 Dec 2017 09:01:22 -0800 (PST) Received: from Asurada-CZ80.localdomain (c-73-231-2-134.hsd1.ca.comcast.net. [73.231.2.134]) by smtp.gmail.com with ESMTPSA id q9sm34490181pfl.116.2017.12.19.09.01.21 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 19 Dec 2017 09:01:22 -0800 (PST) From: Nicolin Chen To: timur@tabi.org, broonie@kernel.org Date: Tue, 19 Dec 2017 09:00:18 -0800 Message-Id: <1513702819-42310-15-git-send-email-nicoleotsuka@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1513702819-42310-1-git-send-email-nicoleotsuka@gmail.com> References: <1513702819-42310-1-git-send-email-nicoleotsuka@gmail.com> Cc: mail@maciej.szmigiero.name, kernel@pengutronix.de, lgirdwood@gmail.com, alsa-devel@alsa-project.org, caleb@crome.org, linux-kernel@vger.kernel.org, arnaud.mouiche@invoxia.com, lukma@denx.de, fabio.estevam@nxp.com, linuxppc-dev@lists.ozlabs.org Subject: [alsa-devel] [PATCH v1 14/15] ASoC: fsl_ssi: Move DT related code to a separate probe() 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 This patch cleans up probe() function by moving all Device Tree related code into a separate function. It allows the probe() to be Device Tree independent. This will be very useful for future integration of imx-ssi driver which has similar functionalities while exists only because it supports non-DT cases. This patch also moves symmetric_channels of AC97 from the probe to the structure snd_soc_dai_driver for simplification. Additionally, since PowerPC and AC97 use the same pdev pointer to register a platform device, this patch also unifies related code. Signed-off-by: Nicolin Chen --- sound/soc/fsl/fsl_ssi.c | 204 +++++++++++++++++++++++++----------------------- 1 file changed, 108 insertions(+), 96 deletions(-) diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 7d6149d..a7aaead 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -234,8 +234,12 @@ struct fsl_ssi_soc_data { * * @fiq_params: FIQ stream filtering parameters * - * @pdev: Pointer to pdev when using fsl-ssi as sound card (ppc only) - * TODO: Should be replaced with simple-sound-card + * @card_pdev: Platform_device pointer when using fsl-ssi as sound card + * (PowerPC or AC97 only) + * @card_name: Platform_device name when using fsl-ssi as sound card + * (PowerPC or AC97 only) + * @card_idx: The index of SSI when registering a sound card + * (PowerPC or AC97 only) * * @dbg_stats: Debugging statistics * @@ -279,7 +283,9 @@ struct fsl_ssi { struct imx_pcm_fiq_params fiq_params; - struct platform_device *pdev; + struct platform_device *card_pdev; + char card_name[32]; + u32 card_idx; struct fsl_ssi_dbg dbg_stats; @@ -1155,6 +1161,7 @@ static const struct snd_soc_component_driver fsl_ssi_component = { static struct snd_soc_dai_driver fsl_ssi_ac97_dai = { .bus_control = true, + .symmetric_channels = 1, .probe = fsl_ssi_dai_probe, .remove = fsl_ssi_dai_ac97_remove, .playback = { @@ -1266,9 +1273,7 @@ static void make_lowercase(char *s) static int fsl_ssi_imx_probe(struct platform_device *pdev, struct fsl_ssi *ssi, void __iomem *iomem) { - struct device_node *np = pdev->dev.of_node; struct device *dev = &pdev->dev; - u32 dmas[4]; int ret; /* Backward compatible for a DT without ipg clock name assigned */ @@ -1302,14 +1307,8 @@ static int fsl_ssi_imx_probe(struct platform_device *pdev, ssi->dma_params_tx.addr = ssi->ssi_phys + REG_SSI_STX0; ssi->dma_params_rx.addr = ssi->ssi_phys + REG_SSI_SRX0; - /* Set to dual FIFO mode according to the SDMA sciprt */ - ret = of_property_read_u32_array(np, "dmas", dmas, 4); - if (ssi->use_dma && !ret && dmas[2] == IMX_DMATYPE_SSI_DUAL) { - ssi->use_dual_fifo = true; - /* - * Use even numbers to avoid channel swap due to SDMA - * script design - */ + /* Use even numbers to avoid channel swap due to SDMA script design */ + if (ssi->use_dual_fifo) { ssi->dma_params_tx.maxburst &= ~0x1; ssi->dma_params_rx.maxburst &= ~0x1; } @@ -1350,42 +1349,103 @@ static void fsl_ssi_imx_clean(struct platform_device *pdev, struct fsl_ssi *ssi) clk_disable_unprepare(ssi->clk); } -static int fsl_ssi_probe(struct platform_device *pdev) +static int fsl_ssi_probe_from_dt(struct fsl_ssi *ssi) { - struct snd_soc_dai_driver *cpu_dai_drv; - struct fsl_ssi *ssi; - int ret = 0; - struct device_node *np = pdev->dev.of_node; - struct device *dev = &pdev->dev; + struct device *dev = ssi->dev; + struct device_node *np = dev->of_node; const struct of_device_id *of_id; const char *p, *sprop; const uint32_t *iprop; - struct resource *res; - void __iomem *iomem; - char name[64]; - struct regmap_config regconfig = fsl_ssi_regconfig; + u32 dmas[4]; + int ret; of_id = of_match_device(fsl_ssi_ids, dev); if (!of_id || !of_id->data) return -EINVAL; - ssi = devm_kzalloc(dev, sizeof(*ssi), GFP_KERNEL); - if (!ssi) - return -ENOMEM; - ssi->soc = of_id->data; - ssi->dev = dev; + + ret = of_property_match_string(np, "clock-names", "ipg"); + /* Get error code if not found */ + ssi->has_ipg_clk_name = ret >= 0; /* Check if being used in AC97 mode */ sprop = of_get_property(np, "fsl,mode", NULL); - if (sprop) { - if (!strcmp(sprop, "ac97-slave")) - ssi->dai_fmt = FSLSSI_AC97_DAIFMT; + if (sprop && !strcmp(sprop, "ac97-slave")) { + ssi->dai_fmt = FSLSSI_AC97_DAIFMT; + + ret = of_property_read_u32(np, "cell-index", &ssi->card_idx); + if (ret) { + dev_err(dev, "failed to get SSI index property\n"); + return -EINVAL; + } + strcpy(ssi->card_name, "ac97-codec"); } /* Select DMA or FIQ */ ssi->use_dma = !of_property_read_bool(np, "fsl,fiq-stream-filter"); + /* In synchronous mode, STCK and STFS ports are used by RX as well */ + if (!of_find_property(np, "fsl,ssi-asynchronous", NULL)) + ssi->synchronous = true; + + /* Fetch FIFO depth; Set to 8 for older DT without this property */ + iprop = of_get_property(np, "fsl,fifo-depth", NULL); + if (iprop) + ssi->fifo_depth = be32_to_cpup(iprop); + else + ssi->fifo_depth = 8; + + /* Use dual FIFO mode depending on the support from SDMA script */ + ret = of_property_read_u32_array(np, "dmas", dmas, 4); + if (ssi->use_dma && !ret && dmas[2] == IMX_DMATYPE_SSI_DUAL) + ssi->use_dual_fifo = true; + + /* + * Backward compatible for older bindings by manually triggering the + * machine driver's probe(). Use /compatible property, including the + * address of CPU DAI driver structure, as the name of machine driver + * + * If card_name is set by AC97 earlier, bypass here since it uses a + * different name to register the device. + */ + if (!ssi->card_name[0] && of_get_property(np, "codec-handle", NULL)) { + sprop = of_get_property(of_find_node_by_path("/"), + "compatible", NULL); + /* Strip "fsl," in the compatible name if applicable */ + p = strrchr(sprop, ','); + if (p) + sprop = p + 1; + snprintf(ssi->card_name, sizeof(ssi->card_name), + "snd-soc-%s", sprop); + make_lowercase(ssi->card_name); + ssi->card_idx = 0; + } + + return 0; +} + +static int fsl_ssi_probe(struct platform_device *pdev) +{ + struct regmap_config regconfig = fsl_ssi_regconfig; + struct snd_soc_dai_driver *cpu_dai_drv; + struct device *dev = &pdev->dev; + struct fsl_ssi *ssi; + struct resource *res; + void __iomem *iomem; + int ret = 0; + + ssi = devm_kzalloc(dev, sizeof(*ssi), GFP_KERNEL); + if (!ssi) + return -ENOMEM; + + ssi->dev = dev; + + /* Probe from DT */ + ret = fsl_ssi_probe_from_dt(ssi); + if (ret) + return ret; + if (fsl_ssi_is_ac97(ssi)) { cpu_dai_drv = &fsl_ssi_ac97_dai; fsl_ac97_data = ssi; @@ -1407,15 +1467,11 @@ static int fsl_ssi_probe(struct platform_device *pdev) REG_SSI_SRMSK / sizeof(uint32_t) + 1; } - ret = of_property_match_string(np, "clock-names", "ipg"); - if (ret < 0) { - ssi->has_ipg_clk_name = false; - ssi->regs = devm_regmap_init_mmio(dev, iomem, ®config); - } else { - ssi->has_ipg_clk_name = true; + if (ssi->has_ipg_clk_name) ssi->regs = devm_regmap_init_mmio_clk(dev, "ipg", iomem, ®config); - } + else + ssi->regs = devm_regmap_init_mmio(dev, iomem, ®config); if (IS_ERR(ssi->regs)) { dev_err(dev, "failed to init register map\n"); return PTR_ERR(ssi->regs); @@ -1427,24 +1483,13 @@ static int fsl_ssi_probe(struct platform_device *pdev) return ssi->irq; } - /* Set software limitations for synchronous mode */ - if (!of_find_property(np, "fsl,ssi-asynchronous", NULL)) { - if (!fsl_ssi_is_ac97(ssi)) { - cpu_dai_drv->symmetric_rates = 1; - cpu_dai_drv->symmetric_samplebits = 1; - ssi->synchronous = true; - } - + /* Set software limitations for synchronous mode except AC97 */ + if (ssi->synchronous && !fsl_ssi_is_ac97(ssi)) { + cpu_dai_drv->symmetric_rates = 1; cpu_dai_drv->symmetric_channels = 1; + cpu_dai_drv->symmetric_samplebits = 1; } - /* Fetch FIFO depth; Set to 8 for older DT without this property */ - iprop = of_get_property(np, "fsl,fifo-depth", NULL); - if (iprop) - ssi->fifo_depth = be32_to_cpup(iprop); - else - ssi->fifo_depth = 8; - /* * Configure TX and RX DMA watermarks -- when to send a DMA request * @@ -1509,47 +1554,14 @@ static int fsl_ssi_probe(struct platform_device *pdev) if (ret) goto error_asoc_register; - /* Bypass it if using newer DT bindings of ASoC machine drivers */ - if (!of_get_property(np, "codec-handle", NULL)) - goto done; - - /* - * Backward compatible for older bindings by manually triggering the - * machine driver's probe(). Use /compatible property, including the - * address of CPU DAI driver structure, as the name of machine driver. - */ - sprop = of_get_property(of_find_node_by_path("/"), "compatible", NULL); - /* Sometimes the compatible name has a "fsl," prefix, so we strip it. */ - p = strrchr(sprop, ','); - if (p) - sprop = p + 1; - snprintf(name, sizeof(name), "snd-soc-%s", sprop); - make_lowercase(name); - - ssi->pdev = platform_device_register_data(dev, name, 0, NULL, 0); - if (IS_ERR(ssi->pdev)) { - ret = PTR_ERR(ssi->pdev); - dev_err(dev, "failed to register platform: %d\n", ret); - goto error_sound_card; - } - -done: - if (fsl_ssi_is_ac97(ssi)) { - u32 ssi_idx; - - ret = of_property_read_u32(np, "cell-index", &ssi_idx); - if (ret) { - dev_err(dev, "failed to get SSI index property\n"); - goto error_sound_card; - } - - ssi->pdev = platform_device_register_data(NULL, "ac97-codec", - ssi_idx, NULL, 0); - if (IS_ERR(ssi->pdev)) { - ret = PTR_ERR(ssi->pdev); - dev_err(dev, - "failed to register AC97 codec platform: %d\n", - ret); + /* Register a platform device for older bindings or AC97 */ + if (ssi->card_name[0]) { + ssi->card_pdev = platform_device_register_data(dev, + ssi->card_name, ssi->card_idx, NULL, 0); + if (IS_ERR(ssi->card_pdev)) { + ret = PTR_ERR(ssi->card_pdev); + dev_err(dev, "failed to register %s: %d\n", + ssi->card_name, ret); goto error_sound_card; } } @@ -1577,8 +1589,8 @@ static int fsl_ssi_remove(struct platform_device *pdev) fsl_ssi_debugfs_remove(&ssi->dbg_stats); - if (ssi->pdev) - platform_device_unregister(ssi->pdev); + if (ssi->card_pdev) + platform_device_unregister(ssi->card_pdev); if (ssi->soc->imx) fsl_ssi_imx_clean(pdev, ssi);