Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ASoC: samsung: pass filter function as pointer

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>

authored by

Arnd Bergmann and committed by
Mark Brown
9bdca822 359fdfa6

+50 -26
+6
arch/arm/mach-s3c64xx/dev-audio.c
··· 58 58 59 59 static struct s3c_audio_pdata i2s0_pdata = { 60 60 .cfg_gpio = s3c64xx_i2s_cfg_gpio, 61 + .dma_filter = pl08x_filter_id, 61 62 .dma_playback = DMACH_I2S0_OUT, 62 63 .dma_capture = DMACH_I2S0_IN, 63 64 }; ··· 80 79 81 80 static struct s3c_audio_pdata i2s1_pdata = { 82 81 .cfg_gpio = s3c64xx_i2s_cfg_gpio, 82 + .dma_filter = pl08x_filter_id, 83 83 .dma_playback = DMACH_I2S1_OUT, 84 84 .dma_capture = DMACH_I2S1_IN, 85 85 }; ··· 102 100 103 101 static struct s3c_audio_pdata i2sv4_pdata = { 104 102 .cfg_gpio = s3c64xx_i2s_cfg_gpio, 103 + .dma_filter = pl08x_filter_id, 105 104 .dma_playback = DMACH_HSI_I2SV40_TX, 106 105 .dma_capture = DMACH_HSI_I2SV40_RX, 107 106 .type = { ··· 153 150 154 151 static struct s3c_audio_pdata s3c_pcm0_pdata = { 155 152 .cfg_gpio = s3c64xx_pcm_cfg_gpio, 153 + .dma_filter = pl08x_filter_id, 156 154 .dma_capture = DMACH_PCM0_RX, 157 155 .dma_playback = DMACH_PCM0_TX, 158 156 }; ··· 175 171 176 172 static struct s3c_audio_pdata s3c_pcm1_pdata = { 177 173 .cfg_gpio = s3c64xx_pcm_cfg_gpio, 174 + .dma_filter = pl08x_filter_id, 178 175 .dma_playback = DMACH_PCM1_TX, 179 176 .dma_capture = DMACH_PCM1_RX, 180 177 }; ··· 210 205 211 206 static struct s3c_audio_pdata s3c_ac97_pdata = { 212 207 .dma_playback = DMACH_AC97_PCMOUT, 208 + .dma_filter = pl08x_filter_id, 213 209 .dma_capture = DMACH_AC97_PCMIN, 214 210 .dma_capture_mic = DMACH_AC97_MICIN, 215 211 };
+6
arch/arm/plat-samsung/devs.c
··· 78 78 }; 79 79 80 80 static struct s3c_audio_pdata s3c_ac97_pdata = { 81 + #ifdef CONFIG_S3C24XX_DMAC 82 + .dma_filter = s3c24xx_dma_filter, 83 + #endif 81 84 .dma_playback = (void *)DMACH_PCM_OUT, 82 85 .dma_capture = (void *)DMACH_PCM_IN, 83 86 .dma_capture_mic = (void *)DMACH_MIC_IN, ··· 575 572 }; 576 573 577 574 static struct s3c_audio_pdata s3c_iis_platdata = { 575 + #ifdef CONFIG_S3C24XX_DMAC 576 + .dma_filter = s3c24xx_dma_filter, 577 + #endif 578 578 .dma_playback = (void *)DMACH_I2S_OUT, 579 579 .dma_capture = (void *)DMACH_I2S_IN, 580 580 };
+1 -1
drivers/dma/Kconfig
··· 432 432 Support for ST-Ericsson DMA40 controller 433 433 434 434 config S3C24XX_DMAC 435 - tristate "Samsung S3C24XX DMA support" 435 + bool "Samsung S3C24XX DMA support" 436 436 depends on ARCH_S3C24XX 437 437 select DMA_ENGINE 438 438 select DMA_VIRTUAL_CHANNELS
+4
include/linux/platform_data/asoc-s3c.h
··· 13 13 */ 14 14 #define S3C64XX_AC97_GPD 0 15 15 #define S3C64XX_AC97_GPE 1 16 + 17 + #include <linux/dmaengine.h> 18 + 16 19 extern void s3c64xx_ac97_setup_gpio(int); 17 20 18 21 struct samsung_i2s { ··· 42 39 */ 43 40 struct s3c_audio_pdata { 44 41 int (*cfg_gpio)(struct platform_device *); 42 + dma_filter_fn dma_filter; 45 43 void *dma_playback; 46 44 void *dma_capture; 47 45 void *dma_play_sec;
-2
sound/soc/samsung/Kconfig
··· 1 1 config SND_SOC_SAMSUNG 2 2 tristate "ASoC support for Samsung" 3 3 depends on (PLAT_SAMSUNG || ARCH_EXYNOS) 4 - depends on S3C64XX_PL080 || !ARCH_S3C64XX 5 - depends on S3C24XX_DMAC || !ARCH_S3C24XX 6 4 select SND_SOC_GENERIC_DMAENGINE_PCM 7 5 help 8 6 Say Y or M if you want to add support for codecs attached to
+2 -1
sound/soc/samsung/ac97.c
··· 388 388 if (ret) 389 389 goto err5; 390 390 391 - ret = samsung_asoc_dma_platform_register(&pdev->dev); 391 + ret = samsung_asoc_dma_platform_register(&pdev->dev, 392 + ac97_pdata->dma_filter); 392 393 if (ret) { 393 394 dev_err(&pdev->dev, "failed to get register DMA: %d\n", ret); 394 395 goto err5;
+3 -1
sound/soc/samsung/dma.h
··· 13 13 #define _S3C_AUDIO_H 14 14 15 15 #include <sound/dmaengine_pcm.h> 16 + #include <linux/dmaengine.h> 16 17 17 18 struct s3c_dma_params { 18 19 void *slave; /* Channel ID */ ··· 26 25 void samsung_asoc_init_dma_data(struct snd_soc_dai *dai, 27 26 struct s3c_dma_params *playback, 28 27 struct s3c_dma_params *capture); 29 - int samsung_asoc_dma_platform_register(struct device *dev); 28 + int samsung_asoc_dma_platform_register(struct device *dev, 29 + dma_filter_fn fn); 30 30 31 31 #endif
+5 -11
sound/soc/samsung/dmaengine.c
··· 28 28 29 29 #include "dma.h" 30 30 31 - #ifdef CONFIG_ARCH_S3C64XX 32 - #define filter_fn pl08x_filter_id 33 - #elif defined(CONFIG_ARCH_S3C24XX) 34 - #define filter_fn s3c24xx_dma_filter 35 - #else 36 - #define filter_fn NULL 37 - #endif 38 - 39 - static const struct snd_dmaengine_pcm_config samsung_dmaengine_pcm_config = { 31 + static struct snd_dmaengine_pcm_config samsung_dmaengine_pcm_config = { 40 32 .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config, 41 - .compat_filter_fn = filter_fn, 42 33 }; 43 34 44 35 void samsung_asoc_init_dma_data(struct snd_soc_dai *dai, ··· 58 67 } 59 68 EXPORT_SYMBOL_GPL(samsung_asoc_init_dma_data); 60 69 61 - int samsung_asoc_dma_platform_register(struct device *dev) 70 + int samsung_asoc_dma_platform_register(struct device *dev, 71 + dma_filter_fn filter) 62 72 { 73 + samsung_dmaengine_pcm_config.compat_filter_fn = filter; 74 + 63 75 return devm_snd_dmaengine_pcm_register(dev, 64 76 &samsung_dmaengine_pcm_config, 65 77 SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME |
+8 -3
sound/soc/samsung/i2s.c
··· 89 89 struct s3c_dma_params dma_playback; 90 90 struct s3c_dma_params dma_capture; 91 91 struct s3c_dma_params idma_playback; 92 + dma_filter_fn filter; 92 93 u32 quirks; 93 94 u32 suspend_i2smod; 94 95 u32 suspend_i2scon; ··· 1245 1244 if (ret != 0) 1246 1245 return ret; 1247 1246 1248 - return samsung_asoc_dma_platform_register(&pdev->dev); 1247 + return samsung_asoc_dma_platform_register(&pdev->dev, 1248 + sec_dai->filter); 1249 1249 } 1250 1250 1251 1251 pri_dai = i2s_alloc_dai(pdev, false); ··· 1266 1264 1267 1265 pri_dai->dma_playback.slave = i2s_pdata->dma_playback; 1268 1266 pri_dai->dma_capture.slave = i2s_pdata->dma_capture; 1267 + pri_dai->filter = i2s_pdata->dma_filter; 1269 1268 1270 1269 if (&i2s_pdata->type) 1271 1270 i2s_cfg = &i2s_pdata->type.i2s; ··· 1328 1325 sec_dai->dma_playback.dma_addr = regs_base + I2STXDS; 1329 1326 sec_dai->dma_playback.ch_name = "tx-sec"; 1330 1327 1331 - if (!np) 1328 + if (!np) { 1332 1329 sec_dai->dma_playback.slave = i2s_pdata->dma_play_sec; 1330 + sec_dai->filter = i2s_pdata->dma_filter; 1331 + } 1333 1332 1334 1333 sec_dai->dma_playback.dma_size = 4; 1335 1334 sec_dai->addr = pri_dai->addr; ··· 1353 1348 1354 1349 pm_runtime_enable(&pdev->dev); 1355 1350 1356 - ret = samsung_asoc_dma_platform_register(&pdev->dev); 1351 + ret = samsung_asoc_dma_platform_register(&pdev->dev, pri_dai->filter); 1357 1352 if (ret != 0) 1358 1353 return ret; 1359 1354
+4 -1
sound/soc/samsung/pcm.c
··· 488 488 struct s3c_pcm_info *pcm; 489 489 struct resource *mem_res; 490 490 struct s3c_audio_pdata *pcm_pdata; 491 + dma_filter_fn filter; 491 492 int ret; 492 493 493 494 /* Check for valid device index */ ··· 557 556 s3c_pcm_stereo_out[pdev->id].dma_addr = mem_res->start 558 557 + S3C_PCM_TXFIFO; 559 558 559 + filter = NULL; 560 560 if (pcm_pdata) { 561 561 s3c_pcm_stereo_in[pdev->id].slave = pcm_pdata->dma_capture; 562 562 s3c_pcm_stereo_out[pdev->id].slave = pcm_pdata->dma_playback; 563 + filter = pcm_pdata->dma_filter; 563 564 } 564 565 565 566 pcm->dma_capture = &s3c_pcm_stereo_in[pdev->id]; ··· 576 573 goto err5; 577 574 } 578 575 579 - ret = samsung_asoc_dma_platform_register(&pdev->dev); 576 + ret = samsung_asoc_dma_platform_register(&pdev->dev, filter); 580 577 if (ret) { 581 578 dev_err(&pdev->dev, "failed to get register DMA: %d\n", ret); 582 579 goto err5;
+2 -2
sound/soc/samsung/s3c2412-i2s.c
··· 25 25 #include <sound/soc.h> 26 26 #include <sound/pcm_params.h> 27 27 28 - #include <mach/dma.h> 29 28 #include <mach/gpio-samsung.h> 30 29 #include <plat/gpio-cfg.h> 31 30 ··· 176 177 return ret; 177 178 } 178 179 179 - ret = samsung_asoc_dma_platform_register(&pdev->dev); 180 + ret = samsung_asoc_dma_platform_register(&pdev->dev, 181 + pdata->dma_filter); 180 182 if (ret) 181 183 pr_err("failed to register the DMA: %d\n", ret); 182 184
+2 -2
sound/soc/samsung/s3c24xx-i2s.c
··· 23 23 #include <sound/soc.h> 24 24 #include <sound/pcm_params.h> 25 25 26 - #include <mach/dma.h> 27 26 #include <mach/gpio-samsung.h> 28 27 #include <plat/gpio-cfg.h> 29 28 #include "regs-iis.h" ··· 481 482 return ret; 482 483 } 483 484 484 - ret = samsung_asoc_dma_platform_register(&pdev->dev); 485 + ret = samsung_asoc_dma_platform_register(&pdev->dev, 486 + pdata->dma_filter); 485 487 if (ret) 486 488 pr_err("failed to register the dma: %d\n", ret); 487 489
+7 -2
sound/soc/samsung/spdif.c
··· 361 361 struct s3c_audio_pdata *spdif_pdata; 362 362 struct resource *mem_res; 363 363 struct samsung_spdif_info *spdif; 364 + dma_filter_fn filter; 364 365 int ret; 365 366 366 367 spdif_pdata = pdev->dev.platform_data; ··· 427 426 428 427 spdif_stereo_out.dma_size = 2; 429 428 spdif_stereo_out.dma_addr = mem_res->start + DATA_OUTBUF; 430 - spdif_stereo_out.slave = spdif_pdata ? spdif_pdata->dma_playback : NULL; 429 + filter = NULL; 430 + if (spdif_pdata) { 431 + spdif_stereo_out.slave = spdif_pdata->dma_playback; 432 + filter = spdif_pdata->dma_filter; 433 + } 431 434 432 435 spdif->dma_playback = &spdif_stereo_out; 433 436 434 - ret = samsung_asoc_dma_platform_register(&pdev->dev); 437 + ret = samsung_asoc_dma_platform_register(&pdev->dev, filter); 435 438 if (ret) { 436 439 dev_err(&pdev->dev, "failed to register DMA: %d\n", ret); 437 440 goto err4;