ASoC: samsung: pass filter function as pointer
authorArnd Bergmann <arnd@arndb.de>
Wed, 18 Nov 2015 21:31:11 +0000 (22:31 +0100)
committerMark Brown <broonie@kernel.org>
Sat, 21 Nov 2015 13:27:22 +0000 (13:27 +0000)
As we are now passing the filter data as pointers to the drivers,
we can take the final step and also pass the filter function the
same way. I'm keeping this change separate, as there it's less
obvious that this is a net win.

Upsides of this are:

- The ASoC drivers are completely independent from the DMA engine
  implementation, which simplifies the Kconfig logic and in theory
  allows the same sound drivers to be built in a kernel that supports
  different kinds of dmaengine drivers.

- Consistency with other subsystems and drivers

On the other hand, we have a few downsides:

- The s3c24xx-dma driver now needs to be built-in for the ac97 platform
  device to be instantiated on s3c2440.

- samsung_dmaengine_pcm_config cannot be marked 'const' any more
  because the filter function pointer needs to be set at runtime.
  This is safe as long we don't have multiple different DMA engines
  in thet same system at runtime, but is nonetheless ugly.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Reviewed-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
13 files changed:
arch/arm/mach-s3c64xx/dev-audio.c
arch/arm/plat-samsung/devs.c
drivers/dma/Kconfig
include/linux/platform_data/asoc-s3c.h
sound/soc/samsung/Kconfig
sound/soc/samsung/ac97.c
sound/soc/samsung/dma.h
sound/soc/samsung/dmaengine.c
sound/soc/samsung/i2s.c
sound/soc/samsung/pcm.c
sound/soc/samsung/s3c2412-i2s.c
sound/soc/samsung/s3c24xx-i2s.c
sound/soc/samsung/spdif.c

index 9a42736ef4ac9e3e3039b1a5ae31b1d66d020245..b57783371d525976946f3f47a2b37933308756f9 100644 (file)
@@ -58,6 +58,7 @@ static struct resource s3c64xx_iis0_resource[] = {
 
 static struct s3c_audio_pdata i2s0_pdata = {
        .cfg_gpio = s3c64xx_i2s_cfg_gpio,
+       .dma_filter = pl08x_filter_id,
        .dma_playback = DMACH_I2S0_OUT,
        .dma_capture = DMACH_I2S0_IN,
 };
@@ -79,6 +80,7 @@ static struct resource s3c64xx_iis1_resource[] = {
 
 static struct s3c_audio_pdata i2s1_pdata = {
        .cfg_gpio = s3c64xx_i2s_cfg_gpio,
+       .dma_filter = pl08x_filter_id,
        .dma_playback = DMACH_I2S1_OUT,
        .dma_capture = DMACH_I2S1_IN,
 };
@@ -100,6 +102,7 @@ static struct resource s3c64xx_iisv4_resource[] = {
 
 static struct s3c_audio_pdata i2sv4_pdata = {
        .cfg_gpio = s3c64xx_i2s_cfg_gpio,
+       .dma_filter = pl08x_filter_id,
        .dma_playback = DMACH_HSI_I2SV40_TX,
        .dma_capture = DMACH_HSI_I2SV40_RX,
        .type = {
@@ -150,6 +153,7 @@ static struct resource s3c64xx_pcm0_resource[] = {
 
 static struct s3c_audio_pdata s3c_pcm0_pdata = {
        .cfg_gpio = s3c64xx_pcm_cfg_gpio,
+       .dma_filter = pl08x_filter_id,
        .dma_capture = DMACH_PCM0_RX,
        .dma_playback = DMACH_PCM0_TX,
 };
@@ -171,6 +175,7 @@ static struct resource s3c64xx_pcm1_resource[] = {
 
 static struct s3c_audio_pdata s3c_pcm1_pdata = {
        .cfg_gpio = s3c64xx_pcm_cfg_gpio,
+       .dma_filter = pl08x_filter_id,
        .dma_playback = DMACH_PCM1_TX,
        .dma_capture = DMACH_PCM1_RX,
 };
@@ -205,6 +210,7 @@ static struct resource s3c64xx_ac97_resource[] = {
 
 static struct s3c_audio_pdata s3c_ac97_pdata = {
        .dma_playback = DMACH_AC97_PCMOUT,
+       .dma_filter = pl08x_filter_id,
        .dma_capture = DMACH_AC97_PCMIN,
        .dma_capture_mic = DMACH_AC97_MICIN,
 };
index 823de7b4e53b27691dd29ef1621243f693af8bc4..7263e95a6f354287533f2f13a702fcddae6fc260 100644 (file)
@@ -78,6 +78,9 @@ static struct resource s3c_ac97_resource[] = {
 };
 
 static struct s3c_audio_pdata s3c_ac97_pdata = {
+#ifdef CONFIG_S3C24XX_DMAC
+       .dma_filter = s3c24xx_dma_filter,
+#endif
        .dma_playback = (void *)DMACH_PCM_OUT,
        .dma_capture = (void *)DMACH_PCM_IN,
        .dma_capture_mic = (void *)DMACH_MIC_IN,
@@ -572,6 +575,9 @@ static struct resource s3c_iis_resource[] = {
 };
 
 static struct s3c_audio_pdata s3c_iis_platdata = {
+#ifdef CONFIG_S3C24XX_DMAC
+       .dma_filter = s3c24xx_dma_filter,
+#endif
        .dma_playback = (void *)DMACH_I2S_OUT,
        .dma_capture = (void *)DMACH_I2S_IN,
 };
index e6cd1a32025a916cec7d219d4693c7c71e4c09a9..17655d9ba518b855a0203c7ba87d547b50003ab9 100644 (file)
@@ -432,7 +432,7 @@ config STE_DMA40
          Support for ST-Ericsson DMA40 controller
 
 config S3C24XX_DMAC
-       tristate "Samsung S3C24XX DMA support"
+       bool "Samsung S3C24XX DMA support"
        depends on ARCH_S3C24XX
        select DMA_ENGINE
        select DMA_VIRTUAL_CHANNELS
index 33f88b4479e49fa0a024df8830361ce900f386b1..15bf56ee8af7d21d307c924df06d0f443d835975 100644 (file)
@@ -13,6 +13,9 @@
  */
 #define S3C64XX_AC97_GPD  0
 #define S3C64XX_AC97_GPE  1
+
+#include <linux/dmaengine.h>
+
 extern void s3c64xx_ac97_setup_gpio(int);
 
 struct samsung_i2s {
@@ -39,6 +42,7 @@ struct samsung_i2s {
  */
 struct s3c_audio_pdata {
        int (*cfg_gpio)(struct platform_device *);
+       dma_filter_fn dma_filter;
        void *dma_playback;
        void *dma_capture;
        void *dma_play_sec;
index 3744c9ed537041f6c14c005bd71977d51d4cc375..78baa26e938b5e783d4c5babdfeb3ec7914b5770 100644 (file)
@@ -1,8 +1,6 @@
 config SND_SOC_SAMSUNG
        tristate "ASoC support for Samsung"
        depends on (PLAT_SAMSUNG || ARCH_EXYNOS)
-       depends on S3C64XX_PL080 || !ARCH_S3C64XX
-       depends on S3C24XX_DMAC || !ARCH_S3C24XX
        select SND_SOC_GENERIC_DMAENGINE_PCM
        help
          Say Y or M if you want to add support for codecs attached to
index 9c52193924603d00493708c66d05d36279d529c6..4a7a503fe13c121ea55c046772a5c43d4f1349f3 100644 (file)
@@ -388,7 +388,8 @@ static int s3c_ac97_probe(struct platform_device *pdev)
        if (ret)
                goto err5;
 
-       ret = samsung_asoc_dma_platform_register(&pdev->dev);
+       ret = samsung_asoc_dma_platform_register(&pdev->dev,
+                                                ac97_pdata->dma_filter);
        if (ret) {
                dev_err(&pdev->dev, "failed to get register DMA: %d\n", ret);
                goto err5;
index 085ef30f5ca28464b3c3e1b7293b50f50fd8b61d..a7616cc9b39ee5a59221ddaaf5ed61859d253234 100644 (file)
@@ -13,6 +13,7 @@
 #define _S3C_AUDIO_H
 
 #include <sound/dmaengine_pcm.h>
+#include <linux/dmaengine.h>
 
 struct s3c_dma_params {
        void *slave;                            /* Channel ID */
@@ -25,6 +26,7 @@ struct s3c_dma_params {
 void samsung_asoc_init_dma_data(struct snd_soc_dai *dai,
                                struct s3c_dma_params *playback,
                                struct s3c_dma_params *capture);
-int samsung_asoc_dma_platform_register(struct device *dev);
+int samsung_asoc_dma_platform_register(struct device *dev,
+                                      dma_filter_fn fn);
 
 #endif
index 727008d57d1439e276c73b880685adbcef030d74..063125937311e9600f063a3cc8ddac308e876c7f 100644 (file)
 
 #include "dma.h"
 
-#ifdef CONFIG_ARCH_S3C64XX
-#define filter_fn pl08x_filter_id
-#elif defined(CONFIG_ARCH_S3C24XX)
-#define filter_fn s3c24xx_dma_filter
-#else
-#define filter_fn NULL
-#endif
-
-static const struct snd_dmaengine_pcm_config samsung_dmaengine_pcm_config = {
+static struct snd_dmaengine_pcm_config samsung_dmaengine_pcm_config = {
        .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
-       .compat_filter_fn = filter_fn,
 };
 
 void samsung_asoc_init_dma_data(struct snd_soc_dai *dai,
@@ -67,8 +58,11 @@ void samsung_asoc_init_dma_data(struct snd_soc_dai *dai,
 }
 EXPORT_SYMBOL_GPL(samsung_asoc_init_dma_data);
 
-int samsung_asoc_dma_platform_register(struct device *dev)
+int samsung_asoc_dma_platform_register(struct device *dev,
+                                      dma_filter_fn filter)
 {
+       samsung_dmaengine_pcm_config.compat_filter_fn = filter;
+
        return devm_snd_dmaengine_pcm_register(dev,
                        &samsung_dmaengine_pcm_config,
                        SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME |
index 0945b5de39e7f9aaf745891b73f66fd1ed617f6d..84d9e77c0fbe1e8d5e737d26beb492c3ce85883b 100644 (file)
@@ -89,6 +89,7 @@ struct i2s_dai {
        struct s3c_dma_params dma_playback;
        struct s3c_dma_params dma_capture;
        struct s3c_dma_params idma_playback;
+       dma_filter_fn filter;
        u32     quirks;
        u32     suspend_i2smod;
        u32     suspend_i2scon;
@@ -1244,7 +1245,8 @@ static int samsung_i2s_probe(struct platform_device *pdev)
                if (ret != 0)
                        return ret;
 
-               return samsung_asoc_dma_platform_register(&pdev->dev);
+               return samsung_asoc_dma_platform_register(&pdev->dev,
+                                                         sec_dai->filter);
        }
 
        pri_dai = i2s_alloc_dai(pdev, false);
@@ -1264,6 +1266,7 @@ static int samsung_i2s_probe(struct platform_device *pdev)
 
                pri_dai->dma_playback.slave = i2s_pdata->dma_playback;
                pri_dai->dma_capture.slave = i2s_pdata->dma_capture;
+               pri_dai->filter = i2s_pdata->dma_filter;
 
                if (&i2s_pdata->type)
                        i2s_cfg = &i2s_pdata->type.i2s;
@@ -1325,8 +1328,10 @@ static int samsung_i2s_probe(struct platform_device *pdev)
                sec_dai->dma_playback.dma_addr = regs_base + I2STXDS;
                sec_dai->dma_playback.ch_name = "tx-sec";
 
-               if (!np)
+               if (!np) {
                        sec_dai->dma_playback.slave = i2s_pdata->dma_play_sec;
+                       sec_dai->filter = i2s_pdata->dma_filter;
+               }
 
                sec_dai->dma_playback.dma_size = 4;
                sec_dai->addr = pri_dai->addr;
@@ -1348,7 +1353,7 @@ static int samsung_i2s_probe(struct platform_device *pdev)
 
        pm_runtime_enable(&pdev->dev);
 
-       ret = samsung_asoc_dma_platform_register(&pdev->dev);
+       ret = samsung_asoc_dma_platform_register(&pdev->dev, pri_dai->filter);
        if (ret != 0)
                return ret;
 
index c77f324e0bb85727b04589d4477d4150adb62976..498f563a4c9cb2e7fb483c05f367ef348370bb5d 100644 (file)
@@ -488,6 +488,7 @@ static int s3c_pcm_dev_probe(struct platform_device *pdev)
        struct s3c_pcm_info *pcm;
        struct resource *mem_res;
        struct s3c_audio_pdata *pcm_pdata;
+       dma_filter_fn filter;
        int ret;
 
        /* Check for valid device index */
@@ -556,9 +557,11 @@ static int s3c_pcm_dev_probe(struct platform_device *pdev)
        s3c_pcm_stereo_out[pdev->id].dma_addr = mem_res->start
                                                        + S3C_PCM_TXFIFO;
 
+       filter = NULL;
        if (pcm_pdata) {
                s3c_pcm_stereo_in[pdev->id].slave = pcm_pdata->dma_capture;
                s3c_pcm_stereo_out[pdev->id].slave = pcm_pdata->dma_playback;
+               filter = pcm_pdata->dma_filter;
        }
 
        pcm->dma_capture = &s3c_pcm_stereo_in[pdev->id];
@@ -573,7 +576,7 @@ static int s3c_pcm_dev_probe(struct platform_device *pdev)
                goto err5;
        }
 
-       ret = samsung_asoc_dma_platform_register(&pdev->dev);
+       ret = samsung_asoc_dma_platform_register(&pdev->dev, filter);
        if (ret) {
                dev_err(&pdev->dev, "failed to get register DMA: %d\n", ret);
                goto err5;
index 105317f523f26e148424f5758da7a28f396f5d34..204029d12f5b2f639f487ffe6ef591636fdf4746 100644 (file)
@@ -25,7 +25,6 @@
 #include <sound/soc.h>
 #include <sound/pcm_params.h>
 
-#include <mach/dma.h>
 #include <mach/gpio-samsung.h>
 #include <plat/gpio-cfg.h>
 
@@ -177,7 +176,8 @@ static int s3c2412_iis_dev_probe(struct platform_device *pdev)
                return ret;
        }
 
-       ret = samsung_asoc_dma_platform_register(&pdev->dev);
+       ret = samsung_asoc_dma_platform_register(&pdev->dev,
+                                                pdata->dma_filter);
        if (ret)
                pr_err("failed to register the DMA: %d\n", ret);
 
index 9e6a5bc012e3483ee1c7a4780d35c235df2c6338..b3a475d73ba790c6d67bc21ebd271950e3c36f2c 100644 (file)
@@ -23,7 +23,6 @@
 #include <sound/soc.h>
 #include <sound/pcm_params.h>
 
-#include <mach/dma.h>
 #include <mach/gpio-samsung.h>
 #include <plat/gpio-cfg.h>
 #include "regs-iis.h"
@@ -482,7 +481,8 @@ static int s3c24xx_iis_dev_probe(struct platform_device *pdev)
                return ret;
        }
 
-       ret = samsung_asoc_dma_platform_register(&pdev->dev);
+       ret = samsung_asoc_dma_platform_register(&pdev->dev,
+                                                pdata->dma_filter);
        if (ret)
                pr_err("failed to register the dma: %d\n", ret);
 
index 9dd7ee6d03ff16828ea52f211a3a5741444b98ca..4687f521197c5c46a7255873e94f9b0d67215d9a 100644 (file)
@@ -361,6 +361,7 @@ static int spdif_probe(struct platform_device *pdev)
        struct s3c_audio_pdata *spdif_pdata;
        struct resource *mem_res;
        struct samsung_spdif_info *spdif;
+       dma_filter_fn filter;
        int ret;
 
        spdif_pdata = pdev->dev.platform_data;
@@ -426,11 +427,15 @@ static int spdif_probe(struct platform_device *pdev)
 
        spdif_stereo_out.dma_size = 2;
        spdif_stereo_out.dma_addr = mem_res->start + DATA_OUTBUF;
-       spdif_stereo_out.slave = spdif_pdata ? spdif_pdata->dma_playback : NULL;
+       filter = NULL;
+       if (spdif_pdata) {
+               spdif_stereo_out.slave = spdif_pdata->dma_playback;
+               filter = spdif_pdata->dma_filter;
+       }
 
        spdif->dma_playback = &spdif_stereo_out;
 
-       ret = samsung_asoc_dma_platform_register(&pdev->dev);
+       ret = samsung_asoc_dma_platform_register(&pdev->dev, filter);
        if (ret) {
                dev_err(&pdev->dev, "failed to register DMA: %d\n", ret);
                goto err4;