diff options
-rw-r--r-- | Documentation/devicetree/bindings/sound/fsl,ssi.txt (renamed from Documentation/devicetree/bindings/powerpc/fsl/ssi.txt) | 8 | ||||
-rw-r--r-- | Documentation/devicetree/bindings/sound/imx-audmux.txt | 9 | ||||
-rw-r--r-- | sound/soc/fsl/Kconfig | 8 | ||||
-rw-r--r-- | sound/soc/fsl/fsl_ssi.c | 161 | ||||
-rw-r--r-- | sound/soc/fsl/imx-audmux.c | 78 | ||||
-rw-r--r-- | sound/soc/fsl/imx-mc13783.c | 1 | ||||
-rw-r--r-- | sound/soc/fsl/imx-pcm-dma.c | 1 | ||||
-rw-r--r-- | sound/soc/fsl/imx-pcm-fiq.c | 18 | ||||
-rw-r--r-- | sound/soc/fsl/imx-pcm.h | 26 | ||||
-rw-r--r-- | sound/soc/fsl/imx-sgtl5000.c | 4 | ||||
-rw-r--r-- | sound/soc/fsl/imx-ssi.c | 11 | ||||
-rw-r--r-- | sound/soc/fsl/imx-ssi.h | 1 | ||||
-rw-r--r-- | sound/soc/fsl/imx-wm8962.c | 3 |
13 files changed, 238 insertions, 91 deletions
diff --git a/Documentation/devicetree/bindings/powerpc/fsl/ssi.txt b/Documentation/devicetree/bindings/sound/fsl,ssi.txt index 5ff76c9c57d2..088a2c038f01 100644 --- a/Documentation/devicetree/bindings/powerpc/fsl/ssi.txt +++ b/Documentation/devicetree/bindings/sound/fsl,ssi.txt @@ -47,6 +47,14 @@ Optional properties: - codec-handle: Phandle to a 'codec' node that defines an audio codec connected to this SSI. This node is typically a child of an I2C or other control node. +- fsl,fiq-stream-filter: Bool property. Disabled DMA and use FIQ instead to + filter the codec stream. This is necessary for some boards + where an incompatible codec is connected to this SSI, e.g. + on pca100 and pcm043. +- dmas: Generic dma devicetree binding as described in + Documentation/devicetree/bindings/dma/dma.txt. +- dma-names: Two dmas have to be defined, "tx" and "rx", if fsl,imx-fiq + is not defined. Child 'codec' node required properties: - compatible: Compatible list, contains the name of the codec diff --git a/Documentation/devicetree/bindings/sound/imx-audmux.txt b/Documentation/devicetree/bindings/sound/imx-audmux.txt index 215aa9817213..f88a00e54c63 100644 --- a/Documentation/devicetree/bindings/sound/imx-audmux.txt +++ b/Documentation/devicetree/bindings/sound/imx-audmux.txt @@ -5,6 +5,15 @@ Required properties: or "fsl,imx31-audmux" for the version firstly used on i.MX31. - reg : Should contain AUDMUX registers location and length +An initial configuration can be setup using child nodes. + +Required properties of optional child nodes: +- fsl,audmux-port : Integer of the audmux port that is configured by this + child node. +- fsl,port-config : List of configuration options for the specific port. For + imx31-audmux and above, it is a list of tuples <ptcr pdcr>. For + imx21-audmux it is a list of pcr values. + Example: audmux@021d8000 { diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig index aa438546c912..e15f77197d0b 100644 --- a/sound/soc/fsl/Kconfig +++ b/sound/soc/fsl/Kconfig @@ -98,7 +98,7 @@ endif # SND_POWERPC_SOC menuconfig SND_IMX_SOC tristate "SoC Audio for Freescale i.MX CPUs" - depends on ARCH_MXC + depends on ARCH_MXC || COMPILE_TEST help Say Y or M if you want to add support for codecs attached to the i.MX CPUs. @@ -109,11 +109,11 @@ config SND_SOC_IMX_SSI tristate config SND_SOC_IMX_PCM_FIQ - bool + tristate select FIQ config SND_SOC_IMX_PCM_DMA - bool + tristate select SND_SOC_GENERIC_DMAENGINE_PCM config SND_SOC_IMX_AUDMUX @@ -194,7 +194,7 @@ config SND_SOC_IMX_SGTL5000 config SND_SOC_IMX_MC13783 tristate "SoC Audio support for I.MX boards with mc13783" - depends on MFD_MC13783 + depends on MFD_MC13783 && ARM select SND_SOC_IMX_SSI select SND_SOC_IMX_AUDMUX select SND_SOC_MC13783 diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 2f2d837df07f..0c072ff10875 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -8,6 +8,26 @@ * This file is licensed under the terms of the GNU General Public License * version 2. This program is licensed "as is" without any warranty of any * kind, whether express or implied. + * + * + * Some notes why imx-pcm-fiq is used instead of DMA on some boards: + * + * The i.MX SSI core has some nasty limitations in AC97 mode. While most + * sane processor vendors have a FIFO per AC97 slot, the i.MX has only + * one FIFO which combines all valid receive slots. We cannot even select + * which slots we want to receive. The WM9712 with which this driver + * was developed with always sends GPIO status data in slot 12 which + * we receive in our (PCM-) data stream. The only chance we have is to + * manually skip this data in the FIQ handler. With sampling rates different + * from 48000Hz not every frame has valid receive data, so the ratio + * between pcm data and GPIO status data changes. Our FIQ handler is not + * able to handle this, hence this driver only works with 48000Hz sampling + * rate. + * Reading and writing AC97 registers is another challenge. The core + * provides us status bits when the read register is updated with *another* + * value. When we read the same register two times (and the register still + * contains the same value) these status bits are not set. We work + * around this by not polling these bits but only wait a fixed delay. */ #include <linux/init.h> @@ -36,7 +56,7 @@ #define read_ssi(addr) in_be32(addr) #define write_ssi(val, addr) out_be32(addr, val) #define write_ssi_mask(addr, clear, set) clrsetbits_be32(addr, clear, set) -#elif defined ARM +#else #define read_ssi(addr) readl(addr) #define write_ssi(val, addr) writel(val, addr) /* @@ -121,11 +141,13 @@ struct fsl_ssi_private { bool new_binding; bool ssi_on_imx; + bool use_dma; struct clk *clk; struct snd_dmaengine_dai_dma_data dma_params_tx; struct snd_dmaengine_dai_dma_data dma_params_rx; struct imx_dma_data filter_data_tx; struct imx_dma_data filter_data_rx; + struct imx_pcm_fiq_params fiq_params; struct { unsigned int rfrc; @@ -355,7 +377,12 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream, */ /* Enable the interrupts and DMA requests */ - write_ssi(SIER_FLAGS, &ssi->sier); + if (ssi_private->use_dma) + write_ssi(SIER_FLAGS, &ssi->sier); + else + write_ssi(CCSR_SSI_SIER_TIE | CCSR_SSI_SIER_TFE0_EN | + CCSR_SSI_SIER_RIE | + CCSR_SSI_SIER_RFF0_EN, &ssi->sier); /* * Set the watermark for transmit FIFI 0 and receive FIFO 0. We @@ -510,6 +537,9 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd, write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_TE, 0); else write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_RE, 0); + + if ((read_ssi(&ssi->scr) & (CCSR_SSI_SCR_TE | CCSR_SSI_SCR_RE)) == 0) + write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_SSIEN, 0); break; default: @@ -534,22 +564,13 @@ static void fsl_ssi_shutdown(struct snd_pcm_substream *substream, ssi_private->first_stream = ssi_private->second_stream; ssi_private->second_stream = NULL; - - /* - * If this is the last active substream, disable the SSI. - */ - if (!ssi_private->first_stream) { - struct ccsr_ssi __iomem *ssi = ssi_private->ssi; - - write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_SSIEN, 0); - } } static int fsl_ssi_dai_probe(struct snd_soc_dai *dai) { struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(dai); - if (ssi_private->ssi_on_imx) { + if (ssi_private->ssi_on_imx && ssi_private->use_dma) { dai->playback_dma_data = &ssi_private->dma_params_tx; dai->capture_dma_data = &ssi_private->dma_params_rx; } @@ -680,7 +701,7 @@ static int fsl_ssi_probe(struct platform_device *pdev) /* The DAI name is the last part of the full name of the node. */ p = strrchr(np->full_name, '/') + 1; - ssi_private = kzalloc(sizeof(struct fsl_ssi_private) + strlen(p), + ssi_private = devm_kzalloc(&pdev->dev, sizeof(*ssi_private) + strlen(p), GFP_KERNEL); if (!ssi_private) { dev_err(&pdev->dev, "could not allocate DAI object\n"); @@ -689,6 +710,9 @@ static int fsl_ssi_probe(struct platform_device *pdev) strcpy(ssi_private->name, p); + ssi_private->use_dma = !of_property_read_bool(np, + "fsl,fiq-stream-filter"); + /* Initialize this copy of the CPU DAI driver structure */ memcpy(&ssi_private->cpu_dai_drv, &fsl_ssi_dai_template, sizeof(fsl_ssi_dai_template)); @@ -698,29 +722,31 @@ static int fsl_ssi_probe(struct platform_device *pdev) ret = of_address_to_resource(np, 0, &res); if (ret) { dev_err(&pdev->dev, "could not determine device resources\n"); - goto error_kmalloc; + return ret; } ssi_private->ssi = of_iomap(np, 0); if (!ssi_private->ssi) { dev_err(&pdev->dev, "could not map device resources\n"); - ret = -ENOMEM; - goto error_kmalloc; + return -ENOMEM; } ssi_private->ssi_phys = res.start; ssi_private->irq = irq_of_parse_and_map(np, 0); if (ssi_private->irq == NO_IRQ) { dev_err(&pdev->dev, "no irq for node %s\n", np->full_name); - ret = -ENXIO; - goto error_iomap; - } - - /* The 'name' should not have any slashes in it. */ - ret = request_irq(ssi_private->irq, fsl_ssi_isr, 0, ssi_private->name, - ssi_private); - if (ret < 0) { - dev_err(&pdev->dev, "could not claim irq %u\n", ssi_private->irq); - goto error_irqmap; + return -ENXIO; + } + + if (ssi_private->use_dma) { + /* The 'name' should not have any slashes in it. */ + ret = devm_request_irq(&pdev->dev, ssi_private->irq, + fsl_ssi_isr, 0, ssi_private->name, + ssi_private); + if (ret < 0) { + dev_err(&pdev->dev, "could not claim irq %u\n", + ssi_private->irq); + goto error_irqmap; + } } /* Are the RX and the TX clocks locked? */ @@ -739,13 +765,18 @@ static int fsl_ssi_probe(struct platform_device *pdev) u32 dma_events[2]; ssi_private->ssi_on_imx = true; - ssi_private->clk = clk_get(&pdev->dev, NULL); + ssi_private->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(ssi_private->clk)) { ret = PTR_ERR(ssi_private->clk); dev_err(&pdev->dev, "could not get clock: %d\n", ret); - goto error_irq; + goto error_irqmap; + } + ret = clk_prepare_enable(ssi_private->clk); + if (ret) { + dev_err(&pdev->dev, "clk_prepare_enable failed: %d\n", + ret); + goto error_irqmap; } - clk_prepare_enable(ssi_private->clk); /* * We have burstsize be "fifo_depth - 2" to match the SSI @@ -763,24 +794,28 @@ static int fsl_ssi_probe(struct platform_device *pdev) &ssi_private->filter_data_tx; ssi_private->dma_params_rx.filter_data = &ssi_private->filter_data_rx; - /* - * TODO: This is a temporary solution and should be changed - * to use generic DMA binding later when the helplers get in. - */ - ret = of_property_read_u32_array(pdev->dev.of_node, + if (!of_property_read_bool(pdev->dev.of_node, "dmas") && + ssi_private->use_dma) { + /* + * FIXME: This is a temporary solution until all + * necessary dma drivers support the generic dma + * bindings. + */ + ret = of_property_read_u32_array(pdev->dev.of_node, "fsl,ssi-dma-events", dma_events, 2); - if (ret) { - dev_err(&pdev->dev, "could not get dma events\n"); - goto error_clk; + if (ret && ssi_private->use_dma) { + dev_err(&pdev->dev, "could not get dma events but fsl-ssi is configured to use DMA\n"); + goto error_clk; + } } shared = of_device_is_compatible(of_get_parent(np), "fsl,spba-bus"); imx_pcm_dma_params_init_data(&ssi_private->filter_data_tx, - dma_events[0], shared); + dma_events[0], shared ? IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI); imx_pcm_dma_params_init_data(&ssi_private->filter_data_rx, - dma_events[1], shared); + dma_events[1], shared ? IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI); } /* Initialize the the device_attribute structure */ @@ -794,7 +829,7 @@ static int fsl_ssi_probe(struct platform_device *pdev) if (ret) { dev_err(&pdev->dev, "could not create sysfs %s file\n", ssi_private->dev_attr.attr.name); - goto error_irq; + goto error_clk; } /* Register with ASoC */ @@ -808,9 +843,30 @@ static int fsl_ssi_probe(struct platform_device *pdev) } if (ssi_private->ssi_on_imx) { - ret = imx_pcm_dma_init(pdev); - if (ret) - goto error_dev; + if (!ssi_private->use_dma) { + + /* + * Some boards use an incompatible codec. To get it + * working, we are using imx-fiq-pcm-audio, that + * can handle those codecs. DMA is not possible in this + * situation. + */ + + ssi_private->fiq_params.irq = ssi_private->irq; + ssi_private->fiq_params.base = ssi_private->ssi; + ssi_private->fiq_params.dma_params_rx = + &ssi_private->dma_params_rx; + ssi_private->fiq_params.dma_params_tx = + &ssi_private->dma_params_tx; + + ret = imx_pcm_fiq_init(pdev, &ssi_private->fiq_params); + if (ret) + goto error_dev; + } else { + ret = imx_pcm_dma_init(pdev); + if (ret) + goto error_dev; + } } /* @@ -857,23 +913,12 @@ error_dev: device_remove_file(&pdev->dev, dev_attr); error_clk: - if (ssi_private->ssi_on_imx) { + if (ssi_private->ssi_on_imx) clk_disable_unprepare(ssi_private->clk); - clk_put(ssi_private->clk); - } - -error_irq: - free_irq(ssi_private->irq, ssi_private); error_irqmap: irq_dispose_mapping(ssi_private->irq); -error_iomap: - iounmap(ssi_private->ssi); - -error_kmalloc: - kfree(ssi_private); - return ret; } @@ -886,15 +931,10 @@ static int fsl_ssi_remove(struct platform_device *pdev) if (ssi_private->ssi_on_imx) { imx_pcm_dma_exit(pdev); clk_disable_unprepare(ssi_private->clk); - clk_put(ssi_private->clk); } snd_soc_unregister_component(&pdev->dev); device_remove_file(&pdev->dev, &ssi_private->dev_attr); - - free_irq(ssi_private->irq, ssi_private); irq_dispose_mapping(ssi_private->irq); - - kfree(ssi_private); dev_set_drvdata(&pdev->dev, NULL); return 0; @@ -919,6 +959,7 @@ static struct platform_driver fsl_ssi_driver = { module_platform_driver(fsl_ssi_driver); +MODULE_ALIAS("platform:fsl-ssi-dai"); MODULE_AUTHOR("Timur Tabi <timur@freescale.com>"); MODULE_DESCRIPTION("Freescale Synchronous Serial Interface (SSI) ASoC Driver"); MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/fsl/imx-audmux.c b/sound/soc/fsl/imx-audmux.c index e260f1f899db..103d1b020496 100644 --- a/sound/soc/fsl/imx-audmux.c +++ b/sound/soc/fsl/imx-audmux.c @@ -73,8 +73,11 @@ static ssize_t audmux_read_file(struct file *file, char __user *user_buf, if (!buf) return -ENOMEM; - if (audmux_clk) - clk_prepare_enable(audmux_clk); + if (audmux_clk) { + ret = clk_prepare_enable(audmux_clk); + if (ret) + return ret; + } ptcr = readl(audmux_base + IMX_AUDMUX_V2_PTCR(port)); pdcr = readl(audmux_base + IMX_AUDMUX_V2_PDCR(port)); @@ -224,14 +227,19 @@ EXPORT_SYMBOL_GPL(imx_audmux_v1_configure_port); int imx_audmux_v2_configure_port(unsigned int port, unsigned int ptcr, unsigned int pdcr) { + int ret; + if (audmux_type != IMX31_AUDMUX) return -EINVAL; if (!audmux_base) return -ENOSYS; - if (audmux_clk) - clk_prepare_enable(audmux_clk); + if (audmux_clk) { + ret = clk_prepare_enable(audmux_clk); + if (ret) + return ret; + } writel(ptcr, audmux_base + IMX_AUDMUX_V2_PTCR(port)); writel(pdcr, audmux_base + IMX_AUDMUX_V2_PDCR(port)); @@ -243,6 +251,66 @@ int imx_audmux_v2_configure_port(unsigned int port, unsigned int ptcr, } EXPORT_SYMBOL_GPL(imx_audmux_v2_configure_port); +static int imx_audmux_parse_dt_defaults(struct platform_device *pdev, + struct device_node *of_node) +{ + struct device_node *child; + + for_each_available_child_of_node(of_node, child) { + unsigned int port; + unsigned int ptcr = 0; + unsigned int pdcr = 0; + unsigned int pcr = 0; + unsigned int val; + int ret; + int i = 0; + + ret = of_property_read_u32(child, "fsl,audmux-port", &port); + if (ret) { + dev_warn(&pdev->dev, "Failed to get fsl,audmux-port of child node \"%s\"\n", + child->full_name); + continue; + } + if (!of_property_read_bool(child, "fsl,port-config")) { + dev_warn(&pdev->dev, "child node \"%s\" does not have property fsl,port-config\n", + child->full_name); + continue; + } + + for (i = 0; (ret = of_property_read_u32_index(child, + "fsl,port-config\n", i, &val)) == 0; + ++i) { + if (audmux_type == IMX31_AUDMUX) { + if (i % 2) + pdcr |= val; + else + ptcr |= val; + } else { + pcr |= val; + } + } + + if (ret != -ENODATA) { + dev_err(&pdev->dev, "Failed to read u32 at index %d of child %s\n", + i, child->full_name); + continue; + } + + if (audmux_type == IMX31_AUDMUX) { + if (i % 2) { + dev_err(&pdev->dev, "One pdcr value is missing in child node %s\n", + child->full_name); + continue; + } + imx_audmux_v2_configure_port(port, ptcr, pdcr); + } else { + imx_audmux_v1_configure_port(port, pcr); + } + } + + return 0; +} + static int imx_audmux_probe(struct platform_device *pdev) { struct resource *res; @@ -267,6 +335,8 @@ static int imx_audmux_probe(struct platform_device *pdev) if (audmux_type == IMX31_AUDMUX) audmux_debugfs_init(); + imx_audmux_parse_dt_defaults(pdev, pdev->dev.of_node); + return 0; } diff --git a/sound/soc/fsl/imx-mc13783.c b/sound/soc/fsl/imx-mc13783.c index 9df173c091a6..a3d60d4bea4c 100644 --- a/sound/soc/fsl/imx-mc13783.c +++ b/sound/soc/fsl/imx-mc13783.c @@ -90,6 +90,7 @@ static const struct snd_soc_dapm_route imx_mc13783_routes[] = { static struct snd_soc_card imx_mc13783 = { .name = "imx_mc13783", + .owner = THIS_MODULE, .dai_link = imx_mc13783_dai_mc13783, .num_links = ARRAY_SIZE(imx_mc13783_dai_mc13783), .dapm_widgets = imx_mc13783_widget, diff --git a/sound/soc/fsl/imx-pcm-dma.c b/sound/soc/fsl/imx-pcm-dma.c index fde4d2ea68c8..f323ce09f881 100644 --- a/sound/soc/fsl/imx-pcm-dma.c +++ b/sound/soc/fsl/imx-pcm-dma.c @@ -64,7 +64,6 @@ int imx_pcm_dma_init(struct platform_device *pdev) { return snd_dmaengine_pcm_register(&pdev->dev, &imx_dmaengine_pcm_config, SND_DMAENGINE_PCM_FLAG_NO_RESIDUE | - SND_DMAENGINE_PCM_FLAG_NO_DT | SND_DMAENGINE_PCM_FLAG_COMPAT); } EXPORT_SYMBOL_GPL(imx_pcm_dma_init); diff --git a/sound/soc/fsl/imx-pcm-fiq.c b/sound/soc/fsl/imx-pcm-fiq.c index 310d90290320..3b2ba994beee 100644 --- a/sound/soc/fsl/imx-pcm-fiq.c +++ b/sound/soc/fsl/imx-pcm-fiq.c @@ -22,6 +22,7 @@ #include <linux/slab.h> #include <sound/core.h> +#include <sound/dmaengine_pcm.h> #include <sound/initval.h> #include <sound/pcm.h> #include <sound/pcm_params.h> @@ -32,6 +33,7 @@ #include <linux/platform_data/asoc-imx-ssi.h> #include "imx-ssi.h" +#include "imx-pcm.h" struct imx_pcm_runtime_data { unsigned int period; @@ -366,9 +368,9 @@ static struct snd_soc_platform_driver imx_soc_platform_fiq = { .pcm_free = imx_pcm_fiq_free, }; -int imx_pcm_fiq_init(struct platform_device *pdev) +int imx_pcm_fiq_init(struct platform_device *pdev, + struct imx_pcm_fiq_params *params) { - struct imx_ssi *ssi = platform_get_drvdata(pdev); int ret; ret = claim_fiq(&fh); @@ -377,15 +379,15 @@ int imx_pcm_fiq_init(struct platform_device *pdev) return ret; } - mxc_set_irq_fiq(ssi->irq, 1); - ssi_irq = ssi->irq; + mxc_set_irq_fiq(params->irq, 1); + ssi_irq = params->irq; - imx_pcm_fiq = ssi->irq; + imx_pcm_fiq = params->irq; - imx_ssi_fiq_base = (unsigned long)ssi->base; + imx_ssi_fiq_base = (unsigned long)params->base; - ssi->dma_params_tx.maxburst = 4; - ssi->dma_params_rx.maxburst = 6; + params->dma_params_tx->maxburst = 4; + params->dma_params_rx->maxburst = 6; ret = snd_soc_register_platform(&pdev->dev, &imx_soc_platform_fiq); if (ret) diff --git a/sound/soc/fsl/imx-pcm.h b/sound/soc/fsl/imx-pcm.h index 67f656c7c320..5d5b73303e11 100644 --- a/sound/soc/fsl/imx-pcm.h +++ b/sound/soc/fsl/imx-pcm.h @@ -22,17 +22,23 @@ static inline void imx_pcm_dma_params_init_data(struct imx_dma_data *dma_data, - int dma, bool shared) + int dma, enum sdma_peripheral_type peripheral_type) { dma_data->dma_request = dma; dma_data->priority = DMA_PRIO_HIGH; - if (shared) - dma_data->peripheral_type = IMX_DMATYPE_SSI_SP; - else - dma_data->peripheral_type = IMX_DMATYPE_SSI; + dma_data->peripheral_type = peripheral_type; } -#ifdef CONFIG_SND_SOC_IMX_PCM_DMA +struct imx_pcm_fiq_params { + int irq; + void __iomem *base; + + /* Pointer to original ssi driver to setup tx rx sizes */ + struct snd_dmaengine_dai_dma_data *dma_params_rx; + struct snd_dmaengine_dai_dma_data *dma_params_tx; +}; + +#if IS_ENABLED(CONFIG_SND_SOC_IMX_PCM_DMA) int imx_pcm_dma_init(struct platform_device *pdev); void imx_pcm_dma_exit(struct platform_device *pdev); #else @@ -46,11 +52,13 @@ static inline void imx_pcm_dma_exit(struct platform_device *pdev) } #endif -#ifdef CONFIG_SND_SOC_IMX_PCM_FIQ -int imx_pcm_fiq_init(struct platform_device *pdev); +#if IS_ENABLED(CONFIG_SND_SOC_IMX_PCM_FIQ) +int imx_pcm_fiq_init(struct platform_device *pdev, + struct imx_pcm_fiq_params *params); void imx_pcm_fiq_exit(struct platform_device *pdev); #else -static inline int imx_pcm_fiq_init(struct platform_device *pdev) +static inline int imx_pcm_fiq_init(struct platform_device *pdev, + struct imx_pcm_fiq_params *params) { return -ENODEV; } diff --git a/sound/soc/fsl/imx-sgtl5000.c b/sound/soc/fsl/imx-sgtl5000.c index 3f726e4f88db..389cbfa6dca7 100644 --- a/sound/soc/fsl/imx-sgtl5000.c +++ b/sound/soc/fsl/imx-sgtl5000.c @@ -129,8 +129,10 @@ static int imx_sgtl5000_probe(struct platform_device *pdev) } data->codec_clk = devm_clk_get(&codec_dev->dev, NULL); - if (IS_ERR(data->codec_clk)) + if (IS_ERR(data->codec_clk)) { + ret = PTR_ERR(data->codec_clk); goto fail; + } data->clk_frequency = clk_get_rate(data->codec_clk); diff --git a/sound/soc/fsl/imx-ssi.c b/sound/soc/fsl/imx-ssi.c index 51be3772cba9..f58bcd85c07f 100644 --- a/sound/soc/fsl/imx-ssi.c +++ b/sound/soc/fsl/imx-ssi.c @@ -571,13 +571,13 @@ static int imx_ssi_probe(struct platform_device *pdev) res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx0"); if (res) { imx_pcm_dma_params_init_data(&ssi->filter_data_tx, res->start, - false); + IMX_DMATYPE_SSI); } res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx0"); if (res) { imx_pcm_dma_params_init_data(&ssi->filter_data_rx, res->start, - false); + IMX_DMATYPE_SSI); } platform_set_drvdata(pdev, ssi); @@ -595,7 +595,12 @@ static int imx_ssi_probe(struct platform_device *pdev) goto failed_register; } - ret = imx_pcm_fiq_init(pdev); + ssi->fiq_params.irq = ssi->irq; + ssi->fiq_params.base = ssi->base; + ssi->fiq_params.dma_params_rx = &ssi->dma_params_rx; + ssi->fiq_params.dma_params_tx = &ssi->dma_params_tx; + + ret = imx_pcm_fiq_init(pdev, &ssi->fiq_params); if (ret) goto failed_pcm_fiq; diff --git a/sound/soc/fsl/imx-ssi.h b/sound/soc/fsl/imx-ssi.h index d5003cefca8d..fb1616ba8c59 100644 --- a/sound/soc/fsl/imx-ssi.h +++ b/sound/soc/fsl/imx-ssi.h @@ -209,6 +209,7 @@ struct imx_ssi { struct snd_dmaengine_dai_dma_data dma_params_tx; struct imx_dma_data filter_data_tx; struct imx_dma_data filter_data_rx; + struct imx_pcm_fiq_params fiq_params; int enabled; }; diff --git a/sound/soc/fsl/imx-wm8962.c b/sound/soc/fsl/imx-wm8962.c index 52a36a90f4f4..1d70e278e915 100644 --- a/sound/soc/fsl/imx-wm8962.c +++ b/sound/soc/fsl/imx-wm8962.c @@ -217,7 +217,8 @@ static int imx_wm8962_probe(struct platform_device *pdev) codec_dev = of_find_i2c_device_by_node(codec_np); if (!codec_dev || !codec_dev->driver) { dev_err(&pdev->dev, "failed to find codec platform device\n"); - return -EINVAL; + ret = -EINVAL; + goto fail; } data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); |