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>
This commit is contained in:
Arnd Bergmann 2015-11-18 22:31:11 +01:00 committed by Mark Brown
parent 359fdfa6fd
commit 9bdca822cb
13 changed files with 50 additions and 26 deletions

View File

@ -58,6 +58,7 @@ static struct resource s3c64xx_iis0_resource[] = {
static struct s3c_audio_pdata i2s0_pdata = { static struct s3c_audio_pdata i2s0_pdata = {
.cfg_gpio = s3c64xx_i2s_cfg_gpio, .cfg_gpio = s3c64xx_i2s_cfg_gpio,
.dma_filter = pl08x_filter_id,
.dma_playback = DMACH_I2S0_OUT, .dma_playback = DMACH_I2S0_OUT,
.dma_capture = DMACH_I2S0_IN, .dma_capture = DMACH_I2S0_IN,
}; };
@ -79,6 +80,7 @@ static struct resource s3c64xx_iis1_resource[] = {
static struct s3c_audio_pdata i2s1_pdata = { static struct s3c_audio_pdata i2s1_pdata = {
.cfg_gpio = s3c64xx_i2s_cfg_gpio, .cfg_gpio = s3c64xx_i2s_cfg_gpio,
.dma_filter = pl08x_filter_id,
.dma_playback = DMACH_I2S1_OUT, .dma_playback = DMACH_I2S1_OUT,
.dma_capture = DMACH_I2S1_IN, .dma_capture = DMACH_I2S1_IN,
}; };
@ -100,6 +102,7 @@ static struct resource s3c64xx_iisv4_resource[] = {
static struct s3c_audio_pdata i2sv4_pdata = { static struct s3c_audio_pdata i2sv4_pdata = {
.cfg_gpio = s3c64xx_i2s_cfg_gpio, .cfg_gpio = s3c64xx_i2s_cfg_gpio,
.dma_filter = pl08x_filter_id,
.dma_playback = DMACH_HSI_I2SV40_TX, .dma_playback = DMACH_HSI_I2SV40_TX,
.dma_capture = DMACH_HSI_I2SV40_RX, .dma_capture = DMACH_HSI_I2SV40_RX,
.type = { .type = {
@ -150,6 +153,7 @@ static struct resource s3c64xx_pcm0_resource[] = {
static struct s3c_audio_pdata s3c_pcm0_pdata = { static struct s3c_audio_pdata s3c_pcm0_pdata = {
.cfg_gpio = s3c64xx_pcm_cfg_gpio, .cfg_gpio = s3c64xx_pcm_cfg_gpio,
.dma_filter = pl08x_filter_id,
.dma_capture = DMACH_PCM0_RX, .dma_capture = DMACH_PCM0_RX,
.dma_playback = DMACH_PCM0_TX, .dma_playback = DMACH_PCM0_TX,
}; };
@ -171,6 +175,7 @@ static struct resource s3c64xx_pcm1_resource[] = {
static struct s3c_audio_pdata s3c_pcm1_pdata = { static struct s3c_audio_pdata s3c_pcm1_pdata = {
.cfg_gpio = s3c64xx_pcm_cfg_gpio, .cfg_gpio = s3c64xx_pcm_cfg_gpio,
.dma_filter = pl08x_filter_id,
.dma_playback = DMACH_PCM1_TX, .dma_playback = DMACH_PCM1_TX,
.dma_capture = DMACH_PCM1_RX, .dma_capture = DMACH_PCM1_RX,
}; };
@ -205,6 +210,7 @@ static struct resource s3c64xx_ac97_resource[] = {
static struct s3c_audio_pdata s3c_ac97_pdata = { static struct s3c_audio_pdata s3c_ac97_pdata = {
.dma_playback = DMACH_AC97_PCMOUT, .dma_playback = DMACH_AC97_PCMOUT,
.dma_filter = pl08x_filter_id,
.dma_capture = DMACH_AC97_PCMIN, .dma_capture = DMACH_AC97_PCMIN,
.dma_capture_mic = DMACH_AC97_MICIN, .dma_capture_mic = DMACH_AC97_MICIN,
}; };

View File

@ -78,6 +78,9 @@ static struct resource s3c_ac97_resource[] = {
}; };
static struct s3c_audio_pdata s3c_ac97_pdata = { 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_playback = (void *)DMACH_PCM_OUT,
.dma_capture = (void *)DMACH_PCM_IN, .dma_capture = (void *)DMACH_PCM_IN,
.dma_capture_mic = (void *)DMACH_MIC_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 = { 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_playback = (void *)DMACH_I2S_OUT,
.dma_capture = (void *)DMACH_I2S_IN, .dma_capture = (void *)DMACH_I2S_IN,
}; };

View File

@ -432,7 +432,7 @@ config STE_DMA40
Support for ST-Ericsson DMA40 controller Support for ST-Ericsson DMA40 controller
config S3C24XX_DMAC config S3C24XX_DMAC
tristate "Samsung S3C24XX DMA support" bool "Samsung S3C24XX DMA support"
depends on ARCH_S3C24XX depends on ARCH_S3C24XX
select DMA_ENGINE select DMA_ENGINE
select DMA_VIRTUAL_CHANNELS select DMA_VIRTUAL_CHANNELS

View File

@ -13,6 +13,9 @@
*/ */
#define S3C64XX_AC97_GPD 0 #define S3C64XX_AC97_GPD 0
#define S3C64XX_AC97_GPE 1 #define S3C64XX_AC97_GPE 1
#include <linux/dmaengine.h>
extern void s3c64xx_ac97_setup_gpio(int); extern void s3c64xx_ac97_setup_gpio(int);
struct samsung_i2s { struct samsung_i2s {
@ -39,6 +42,7 @@ struct samsung_i2s {
*/ */
struct s3c_audio_pdata { struct s3c_audio_pdata {
int (*cfg_gpio)(struct platform_device *); int (*cfg_gpio)(struct platform_device *);
dma_filter_fn dma_filter;
void *dma_playback; void *dma_playback;
void *dma_capture; void *dma_capture;
void *dma_play_sec; void *dma_play_sec;

View File

@ -1,8 +1,6 @@
config SND_SOC_SAMSUNG config SND_SOC_SAMSUNG
tristate "ASoC support for Samsung" tristate "ASoC support for Samsung"
depends on (PLAT_SAMSUNG || ARCH_EXYNOS) depends on (PLAT_SAMSUNG || ARCH_EXYNOS)
depends on S3C64XX_PL080 || !ARCH_S3C64XX
depends on S3C24XX_DMAC || !ARCH_S3C24XX
select SND_SOC_GENERIC_DMAENGINE_PCM select SND_SOC_GENERIC_DMAENGINE_PCM
help help
Say Y or M if you want to add support for codecs attached to Say Y or M if you want to add support for codecs attached to

View File

@ -388,7 +388,8 @@ static int s3c_ac97_probe(struct platform_device *pdev)
if (ret) if (ret)
goto err5; goto err5;
ret = samsung_asoc_dma_platform_register(&pdev->dev); ret = samsung_asoc_dma_platform_register(&pdev->dev,
ac97_pdata->dma_filter);
if (ret) { if (ret) {
dev_err(&pdev->dev, "failed to get register DMA: %d\n", ret); dev_err(&pdev->dev, "failed to get register DMA: %d\n", ret);
goto err5; goto err5;

View File

@ -13,6 +13,7 @@
#define _S3C_AUDIO_H #define _S3C_AUDIO_H
#include <sound/dmaengine_pcm.h> #include <sound/dmaengine_pcm.h>
#include <linux/dmaengine.h>
struct s3c_dma_params { struct s3c_dma_params {
void *slave; /* Channel ID */ void *slave; /* Channel ID */
@ -25,6 +26,7 @@ struct s3c_dma_params {
void samsung_asoc_init_dma_data(struct snd_soc_dai *dai, void samsung_asoc_init_dma_data(struct snd_soc_dai *dai,
struct s3c_dma_params *playback, struct s3c_dma_params *playback,
struct s3c_dma_params *capture); 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 #endif

View File

@ -28,17 +28,8 @@
#include "dma.h" #include "dma.h"
#ifdef CONFIG_ARCH_S3C64XX static struct snd_dmaengine_pcm_config samsung_dmaengine_pcm_config = {
#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 = {
.prepare_slave_config = snd_dmaengine_pcm_prepare_slave_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, 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); 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, return devm_snd_dmaengine_pcm_register(dev,
&samsung_dmaengine_pcm_config, &samsung_dmaengine_pcm_config,
SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME | SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME |

View File

@ -89,6 +89,7 @@ struct i2s_dai {
struct s3c_dma_params dma_playback; struct s3c_dma_params dma_playback;
struct s3c_dma_params dma_capture; struct s3c_dma_params dma_capture;
struct s3c_dma_params idma_playback; struct s3c_dma_params idma_playback;
dma_filter_fn filter;
u32 quirks; u32 quirks;
u32 suspend_i2smod; u32 suspend_i2smod;
u32 suspend_i2scon; u32 suspend_i2scon;
@ -1244,7 +1245,8 @@ static int samsung_i2s_probe(struct platform_device *pdev)
if (ret != 0) if (ret != 0)
return ret; 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); 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_playback.slave = i2s_pdata->dma_playback;
pri_dai->dma_capture.slave = i2s_pdata->dma_capture; pri_dai->dma_capture.slave = i2s_pdata->dma_capture;
pri_dai->filter = i2s_pdata->dma_filter;
if (&i2s_pdata->type) if (&i2s_pdata->type)
i2s_cfg = &i2s_pdata->type.i2s; 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.dma_addr = regs_base + I2STXDS;
sec_dai->dma_playback.ch_name = "tx-sec"; sec_dai->dma_playback.ch_name = "tx-sec";
if (!np) if (!np) {
sec_dai->dma_playback.slave = i2s_pdata->dma_play_sec; 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->dma_playback.dma_size = 4;
sec_dai->addr = pri_dai->addr; sec_dai->addr = pri_dai->addr;
@ -1348,7 +1353,7 @@ static int samsung_i2s_probe(struct platform_device *pdev)
pm_runtime_enable(&pdev->dev); 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) if (ret != 0)
return ret; return ret;

View File

@ -488,6 +488,7 @@ static int s3c_pcm_dev_probe(struct platform_device *pdev)
struct s3c_pcm_info *pcm; struct s3c_pcm_info *pcm;
struct resource *mem_res; struct resource *mem_res;
struct s3c_audio_pdata *pcm_pdata; struct s3c_audio_pdata *pcm_pdata;
dma_filter_fn filter;
int ret; int ret;
/* Check for valid device index */ /* 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_stereo_out[pdev->id].dma_addr = mem_res->start
+ S3C_PCM_TXFIFO; + S3C_PCM_TXFIFO;
filter = NULL;
if (pcm_pdata) { if (pcm_pdata) {
s3c_pcm_stereo_in[pdev->id].slave = pcm_pdata->dma_capture; s3c_pcm_stereo_in[pdev->id].slave = pcm_pdata->dma_capture;
s3c_pcm_stereo_out[pdev->id].slave = pcm_pdata->dma_playback; 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]; 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; goto err5;
} }
ret = samsung_asoc_dma_platform_register(&pdev->dev); ret = samsung_asoc_dma_platform_register(&pdev->dev, filter);
if (ret) { if (ret) {
dev_err(&pdev->dev, "failed to get register DMA: %d\n", ret); dev_err(&pdev->dev, "failed to get register DMA: %d\n", ret);
goto err5; goto err5;

View File

@ -25,7 +25,6 @@
#include <sound/soc.h> #include <sound/soc.h>
#include <sound/pcm_params.h> #include <sound/pcm_params.h>
#include <mach/dma.h>
#include <mach/gpio-samsung.h> #include <mach/gpio-samsung.h>
#include <plat/gpio-cfg.h> #include <plat/gpio-cfg.h>
@ -177,7 +176,8 @@ static int s3c2412_iis_dev_probe(struct platform_device *pdev)
return ret; return ret;
} }
ret = samsung_asoc_dma_platform_register(&pdev->dev); ret = samsung_asoc_dma_platform_register(&pdev->dev,
pdata->dma_filter);
if (ret) if (ret)
pr_err("failed to register the DMA: %d\n", ret); pr_err("failed to register the DMA: %d\n", ret);

View File

@ -23,7 +23,6 @@
#include <sound/soc.h> #include <sound/soc.h>
#include <sound/pcm_params.h> #include <sound/pcm_params.h>
#include <mach/dma.h>
#include <mach/gpio-samsung.h> #include <mach/gpio-samsung.h>
#include <plat/gpio-cfg.h> #include <plat/gpio-cfg.h>
#include "regs-iis.h" #include "regs-iis.h"
@ -482,7 +481,8 @@ static int s3c24xx_iis_dev_probe(struct platform_device *pdev)
return ret; return ret;
} }
ret = samsung_asoc_dma_platform_register(&pdev->dev); ret = samsung_asoc_dma_platform_register(&pdev->dev,
pdata->dma_filter);
if (ret) if (ret)
pr_err("failed to register the dma: %d\n", ret); pr_err("failed to register the dma: %d\n", ret);

View File

@ -361,6 +361,7 @@ static int spdif_probe(struct platform_device *pdev)
struct s3c_audio_pdata *spdif_pdata; struct s3c_audio_pdata *spdif_pdata;
struct resource *mem_res; struct resource *mem_res;
struct samsung_spdif_info *spdif; struct samsung_spdif_info *spdif;
dma_filter_fn filter;
int ret; int ret;
spdif_pdata = pdev->dev.platform_data; 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_size = 2;
spdif_stereo_out.dma_addr = mem_res->start + DATA_OUTBUF; 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; 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) { if (ret) {
dev_err(&pdev->dev, "failed to register DMA: %d\n", ret); dev_err(&pdev->dev, "failed to register DMA: %d\n", ret);
goto err4; goto err4;