From patchwork Mon Jan 15 04:21:26 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicolin Chen X-Patchwork-Id: 10163033 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 86379601C0 for ; Mon, 15 Jan 2018 04:25:47 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 85AC328329 for ; Mon, 15 Jan 2018 04:25:47 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 79BEA2889F; Mon, 15 Jan 2018 04:25:47 +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 6EBBC28329 for ; Mon, 15 Jan 2018 04:25:46 +0000 (UTC) Received: from alsa0.perex.cz (localhost [127.0.0.1]) by alsa0.perex.cz (Postfix) with ESMTP id 8F00526743E; Mon, 15 Jan 2018 05:22:44 +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 29B4526742C; Mon, 15 Jan 2018 05:22:41 +0100 (CET) Received: from mail-pl0-f68.google.com (mail-pl0-f68.google.com [209.85.160.68]) by alsa0.perex.cz (Postfix) with ESMTP id ADC162673A0 for ; Mon, 15 Jan 2018 05:22:33 +0100 (CET) Received: by mail-pl0-f68.google.com with SMTP id p5so2804344plo.12 for ; Sun, 14 Jan 2018 20:22:33 -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=5vYfB6ADav2UG00GMetbw4ow6cjwaxyIuMDwLSgRWhg=; b=lB3DOyO1zuZZEaKKTmSYlLzK9QByiVLN5D+aFso+mkmq1y76a0FDlnb5tPskiLmwei ShcWWSLxCqcCkNm1KaDCf+FGN2MXr+8QKO1QlFbKBjNeL7dvGtaB5LWrGz51cACcMGPW 5hE0Pp/lUbngALcxU1HfXdx9vfZhhYUT8VaOLTDhwpLDICdllPdGaJxKBR2dAHeRpm69 Z/Y6rD7YNz8TdgiP9TMm4yvh1/oz4My34KepH2IVh9eAV2NRshd0gZnvWVBB1eTpT8tq lkzlF2w5EwhTeGGIKV4Bl0+Gwg1Os7snefH34Cx871Mcjx1P237Otkzh+8w3vTSUkWrR qFLQ== 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=5vYfB6ADav2UG00GMetbw4ow6cjwaxyIuMDwLSgRWhg=; b=MdGhQyh85amekPwfzsEIQRta0JkLttec5w6wjQ6OJTsoed/SqoAYHgc9bGYKdd0RK3 EbdbU63sQDaemIKrM7Jx/MvfG8ob2TFb2xt+jvlOYDdqoP3oqm5F4J9ry1cgfv9KSfY4 V6yxuafJhl76H6iioat+fg2upgWsCX7ydistEiWCV3HPa/uvDux7eG15w+wz5NATA8QZ +/Z1tcqdGFvlA3jiHDZHA6WvgyVtuIyDH3or49eveb7V39ZiAk3zC5qvgrBKOB+J3U8o pCsrmdLb4tYROMk06+kgNZ27Xn6A4iqtRKo4HF/0vkNN9fpf+mTGJCojHFvROfYjDKh+ CIDA== X-Gm-Message-State: AKwxytc4ohq+f/wFhCftXBW14kxxs5JtbVG+2qV5pzjTxv33QOWMBUZe VtUhMY/3f7Ikl8uSTBkOD0g= X-Google-Smtp-Source: ACJfBouVC1tN5C1Y2YXQBUivH3Zm3Z185w9i0WXmNmVnMqB1uzxkRdisLsEBY0z/0wCxxXrmVif9CQ== X-Received: by 10.159.211.10 with SMTP id bc10mr5095381plb.19.1515990152531; Sun, 14 Jan 2018 20:22:32 -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 v7sm17011018pgs.83.2018.01.14.20.22.31 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sun, 14 Jan 2018 20:22:32 -0800 (PST) From: Nicolin Chen To: timur@tabi.org, broonie@kernel.org, mail@maciej.szmigiero.name Date: Sun, 14 Jan 2018 20:21:26 -0800 Message-Id: <1515990087-11598-17-git-send-email-nicoleotsuka@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1515990087-11598-1-git-send-email-nicoleotsuka@gmail.com> References: <1515990087-11598-1-git-send-email-nicoleotsuka@gmail.com> Cc: alsa-devel@alsa-project.org, kernel@pengutronix.de, linux-kernel@vger.kernel.org, caleb@crome.org, lgirdwood@gmail.com, arnaud.mouiche@invoxia.com, lukma@denx.de, fabio.estevam@nxp.com, linuxppc-dev@lists.ozlabs.org Subject: [alsa-devel] [PATCH v3 16/17] 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 Tested-by: Caleb Crome --- sound/soc/fsl/fsl_ssi.c | 202 +++++++++++++++++++++++++----------------------- 1 file changed, 107 insertions(+), 95 deletions(-) diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 20889d8..d2072de 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -239,8 +239,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 * @@ -285,7 +289,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; @@ -1131,6 +1137,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, .playback = { .stream_name = "AC97 Playback", @@ -1282,9 +1289,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 */ @@ -1318,14 +1323,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; } @@ -1366,41 +1365,102 @@ 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 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 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)) { memcpy(&ssi->cpu_dai_drv, &fsl_ssi_ac97_dai, sizeof(fsl_ssi_ac97_dai)); @@ -1424,15 +1484,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); @@ -1444,24 +1500,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)) { - ssi->cpu_dai_drv.symmetric_rates = 1; - ssi->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)) { + ssi->cpu_dai_drv.symmetric_rates = 1; ssi->cpu_dai_drv.symmetric_channels = 1; + ssi->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 * @@ -1526,50 +1571,17 @@ 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: /* Initially configures SSI registers */ fsl_ssi_hw_init(ssi); - 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; } } @@ -1599,8 +1611,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);