diff options
Diffstat (limited to 'sound/soc/samsung')
-rw-r--r-- | sound/soc/samsung/Kconfig | 13 | ||||
-rw-r--r-- | sound/soc/samsung/Makefile | 6 | ||||
-rw-r--r-- | sound/soc/samsung/ac97.c | 51 | ||||
-rw-r--r-- | sound/soc/samsung/dma.c | 14 | ||||
-rw-r--r-- | sound/soc/samsung/dma.h | 6 | ||||
-rw-r--r-- | sound/soc/samsung/dmaengine.c | 83 | ||||
-rw-r--r-- | sound/soc/samsung/i2s.c | 9 | ||||
-rw-r--r-- | sound/soc/samsung/idma.c | 8 | ||||
-rw-r--r-- | sound/soc/samsung/pcm.c | 18 | ||||
-rw-r--r-- | sound/soc/samsung/regs-ac97.h | 9 | ||||
-rw-r--r-- | sound/soc/samsung/regs-iis.h | 9 |
11 files changed, 153 insertions, 73 deletions
diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig index 37459dfd168d..27930fc432dc 100644 --- a/sound/soc/samsung/Kconfig +++ b/sound/soc/samsung/Kconfig @@ -1,13 +1,22 @@ config SND_SOC_SAMSUNG tristate "ASoC support for Samsung" depends on PLAT_SAMSUNG - select S3C64XX_DMA if ARCH_S3C64XX - select S3C24XX_DMA if ARCH_S3C24XX + select S3C2410_DMA if ARCH_S3C24XX + select S3C64XX_PL080 if ARCH_S3C64XX + select SND_S3C_DMA if !ARCH_S3C24XX + select SND_S3C_DMA_LEGACY if ARCH_S3C24XX + select SND_SOC_GENERIC_DMAENGINE_PCM if !ARCH_S3C24XX help Say Y or M if you want to add support for codecs attached to the Samsung SoCs' Audio interfaces. You will also need to select the audio interfaces to support below. +config SND_S3C_DMA + tristate + +config SND_S3C_DMA_LEGACY + tristate + config SND_S3C24XX_I2S tristate select S3C2410_DMA diff --git a/sound/soc/samsung/Makefile b/sound/soc/samsung/Makefile index 709f6059ad67..86715d8efee6 100644 --- a/sound/soc/samsung/Makefile +++ b/sound/soc/samsung/Makefile @@ -1,5 +1,6 @@ # S3c24XX Platform Support -snd-soc-s3c24xx-objs := dma.o +snd-soc-s3c-dma-objs := dmaengine.o +snd-soc-s3c-dma-legacy-objs := dma.o snd-soc-idma-objs := idma.o snd-soc-s3c24xx-i2s-objs := s3c24xx-i2s.o snd-soc-s3c2412-i2s-objs := s3c2412-i2s.o @@ -9,7 +10,8 @@ snd-soc-samsung-spdif-objs := spdif.o snd-soc-pcm-objs := pcm.o snd-soc-i2s-objs := i2s.o -obj-$(CONFIG_SND_SOC_SAMSUNG) += snd-soc-s3c24xx.o +obj-$(CONFIG_SND_S3C_DMA) += snd-soc-s3c-dma.o +obj-$(CONFIG_SND_S3C_DMA_LEGACY) += snd-soc-s3c-dma-legacy.o obj-$(CONFIG_SND_S3C24XX_I2S) += snd-soc-s3c24xx-i2s.o obj-$(CONFIG_SND_SAMSUNG_AC97) += snd-soc-ac97.o obj-$(CONFIG_SND_S3C2412_SOC_I2S) += snd-soc-s3c2412-i2s.o diff --git a/sound/soc/samsung/ac97.c b/sound/soc/samsung/ac97.c index 350ba23a9893..4a88e36c82ec 100644 --- a/sound/soc/samsung/ac97.c +++ b/sound/soc/samsung/ac97.c @@ -221,24 +221,6 @@ static struct snd_ac97_bus_ops s3c_ac97_ops = { .reset = s3c_ac97_cold_reset, }; -static int s3c_ac97_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *dai) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - struct s3c_dma_params *dma_data; - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - dma_data = &s3c_ac97_pcm_out; - else - dma_data = &s3c_ac97_pcm_in; - - snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data); - - return 0; -} - static int s3c_ac97_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai) { @@ -279,21 +261,6 @@ static int s3c_ac97_trigger(struct snd_pcm_substream *substream, int cmd, return 0; } -static int s3c_ac97_hw_mic_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *dai) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - return -ENODEV; - else - snd_soc_dai_set_dma_data(cpu_dai, substream, &s3c_ac97_mic_in); - - return 0; -} - static int s3c_ac97_mic_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai) { @@ -329,15 +296,27 @@ static int s3c_ac97_mic_trigger(struct snd_pcm_substream *substream, } static const struct snd_soc_dai_ops s3c_ac97_dai_ops = { - .hw_params = s3c_ac97_hw_params, .trigger = s3c_ac97_trigger, }; static const struct snd_soc_dai_ops s3c_ac97_mic_dai_ops = { - .hw_params = s3c_ac97_hw_mic_params, .trigger = s3c_ac97_mic_trigger, }; +static int s3c_ac97_dai_probe(struct snd_soc_dai *dai) +{ + samsung_asoc_init_dma_data(dai, &s3c_ac97_pcm_out, &s3c_ac97_pcm_in); + + return 0; +} + +static int s3c_ac97_mic_dai_probe(struct snd_soc_dai *dai) +{ + samsung_asoc_init_dma_data(dai, NULL, &s3c_ac97_mic_in); + + return 0; +} + static struct snd_soc_dai_driver s3c_ac97_dai[] = { [S3C_AC97_DAI_PCM] = { .name = "samsung-ac97", @@ -354,6 +333,7 @@ static struct snd_soc_dai_driver s3c_ac97_dai[] = { .channels_max = 2, .rates = SNDRV_PCM_RATE_8000_48000, .formats = SNDRV_PCM_FMTBIT_S16_LE,}, + .probe = s3c_ac97_dai_probe, .ops = &s3c_ac97_dai_ops, }, [S3C_AC97_DAI_MIC] = { @@ -365,6 +345,7 @@ static struct snd_soc_dai_driver s3c_ac97_dai[] = { .channels_max = 1, .rates = SNDRV_PCM_RATE_8000_48000, .formats = SNDRV_PCM_FMTBIT_S16_LE,}, + .probe = s3c_ac97_mic_dai_probe, .ops = &s3c_ac97_mic_dai_ops, }, }; diff --git a/sound/soc/samsung/dma.c b/sound/soc/samsung/dma.c index fe2748b494d4..dc09b71b7d9f 100644 --- a/sound/soc/samsung/dma.c +++ b/sound/soc/samsung/dma.c @@ -35,12 +35,6 @@ static const struct snd_pcm_hardware dma_hardware = { SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID, - .formats = SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_U16_LE | - SNDRV_PCM_FMTBIT_U8 | - SNDRV_PCM_FMTBIT_S8, - .channels_min = 2, - .channels_max = 2, .buffer_bytes_max = 128*1024, .period_bytes_min = PAGE_SIZE, .period_bytes_max = PAGE_SIZE*2, @@ -441,6 +435,14 @@ static struct snd_soc_platform_driver samsung_asoc_platform = { .pcm_free = dma_free_dma_buffers, }; +void samsung_asoc_init_dma_data(struct snd_soc_dai *dai, + struct s3c_dma_params *playback, + struct s3c_dma_params *capture) +{ + snd_soc_dai_init_dma_data(dai, playback, capture); +} +EXPORT_SYMBOL_GPL(samsung_asoc_init_dma_data); + int samsung_asoc_dma_platform_register(struct device *dev) { return snd_soc_register_platform(dev, &samsung_asoc_platform); diff --git a/sound/soc/samsung/dma.h b/sound/soc/samsung/dma.h index 0e86315a3eaf..225e5378014e 100644 --- a/sound/soc/samsung/dma.h +++ b/sound/soc/samsung/dma.h @@ -12,6 +12,8 @@ #ifndef _S3C_AUDIO_H #define _S3C_AUDIO_H +#include <sound/dmaengine_pcm.h> + struct s3c_dma_params { struct s3c2410_dma_client *client; /* stream identifier */ int channel; /* Channel ID */ @@ -20,8 +22,12 @@ struct s3c_dma_params { unsigned ch; struct samsung_dma_ops *ops; char *ch_name; + struct snd_dmaengine_dai_dma_data dma_data; }; +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); void samsung_asoc_dma_platform_unregister(struct device *dev); diff --git a/sound/soc/samsung/dmaengine.c b/sound/soc/samsung/dmaengine.c new file mode 100644 index 000000000000..750ce5808d9f --- /dev/null +++ b/sound/soc/samsung/dmaengine.c @@ -0,0 +1,83 @@ +/* + * dmaengine.c - Samsung dmaengine wrapper + * + * Author: Mark Brown <broonie@linaro.org> + * Copyright 2013 Linaro + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + */ + +#include <linux/module.h> +#include <linux/amba/pl08x.h> + +#include <sound/core.h> +#include <sound/pcm.h> +#include <sound/pcm_params.h> +#include <sound/dmaengine_pcm.h> +#include <sound/soc.h> +#include <sound/soc-dai.h> + +#include "dma.h" + +#ifdef CONFIG_ARCH_S3C64XX +#define filter_fn pl08x_filter_id +#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, + .compat_filter_fn = filter_fn, +}; + +void samsung_asoc_init_dma_data(struct snd_soc_dai *dai, + struct s3c_dma_params *playback, + struct s3c_dma_params *capture) +{ + struct snd_dmaengine_dai_dma_data *playback_data = NULL; + struct snd_dmaengine_dai_dma_data *capture_data = NULL; + + if (playback) { + playback_data = &playback->dma_data; + playback_data->filter_data = (void *)playback->channel; + playback_data->chan_name = playback->ch_name; + playback_data->addr = playback->dma_addr; + playback_data->addr_width = playback->dma_size; + } + if (capture) { + capture_data = &capture->dma_data; + capture_data->filter_data = (void *)capture->channel; + capture_data->chan_name = capture->ch_name; + capture_data->addr = capture->dma_addr; + capture_data->addr_width = capture->dma_size; + } + + snd_soc_dai_init_dma_data(dai, playback_data, capture_data); +} +EXPORT_SYMBOL_GPL(samsung_asoc_init_dma_data); + +int samsung_asoc_dma_platform_register(struct device *dev) +{ + return snd_dmaengine_pcm_register(dev, &samsung_dmaengine_pcm_config, + SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME | + SND_DMAENGINE_PCM_FLAG_COMPAT); +} +EXPORT_SYMBOL_GPL(samsung_asoc_dma_platform_register); + +void samsung_asoc_dma_platform_unregister(struct device *dev) +{ + return snd_dmaengine_pcm_unregister(dev); +} +EXPORT_SYMBOL_GPL(samsung_asoc_dma_platform_unregister); + +MODULE_AUTHOR("Mark Brown <broonie@linaro.org>"); +MODULE_DESCRIPTION("Samsung dmaengine ASoC driver"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c index a5cbdb4f1655..92f64363427d 100644 --- a/sound/soc/samsung/i2s.c +++ b/sound/soc/samsung/i2s.c @@ -702,6 +702,8 @@ static int i2s_hw_params(struct snd_pcm_substream *substream, } writel(mod, i2s->addr + I2SMOD); + samsung_asoc_init_dma_data(dai, &i2s->dma_playback, &i2s->dma_capture); + i2s->frmclk = params_rate(params); return 0; @@ -946,8 +948,11 @@ static int samsung_i2s_dai_probe(struct snd_soc_dai *dai) struct i2s_dai *i2s = to_info(dai); struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; - if (other && other->clk) /* If this is probe on secondary */ + if (other && other->clk) { /* If this is probe on secondary */ + samsung_asoc_init_dma_data(dai, &other->sec_dai->dma_playback, + NULL); goto probe_exit; + } i2s->addr = ioremap(i2s->base, 0x100); if (i2s->addr == NULL) { @@ -963,7 +968,7 @@ static int samsung_i2s_dai_probe(struct snd_soc_dai *dai) } clk_prepare_enable(i2s->clk); - snd_soc_dai_init_dma_data(dai, &i2s->dma_playback, &i2s->dma_capture); + samsung_asoc_init_dma_data(dai, &i2s->dma_playback, &i2s->dma_capture); if (other) { other->addr = i2s->addr; diff --git a/sound/soc/samsung/idma.c b/sound/soc/samsung/idma.c index e4f318fc2f82..3d5cf1530b6f 100644 --- a/sound/soc/samsung/idma.c +++ b/sound/soc/samsung/idma.c @@ -35,14 +35,6 @@ static const struct snd_pcm_hardware idma_hardware = { SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME, - .formats = SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_U16_LE | - SNDRV_PCM_FMTBIT_S24_LE | - SNDRV_PCM_FMTBIT_U24_LE | - SNDRV_PCM_FMTBIT_U8 | - SNDRV_PCM_FMTBIT_S8, - .channels_min = 2, - .channels_max = 2, .buffer_bytes_max = MAX_IDMA_BUFFER, .period_bytes_min = 128, .period_bytes_max = MAX_IDMA_PERIOD, diff --git a/sound/soc/samsung/pcm.c b/sound/soc/samsung/pcm.c index e54256fc4b2c..6a5e4bf6ac96 100644 --- a/sound/soc/samsung/pcm.c +++ b/sound/soc/samsung/pcm.c @@ -275,7 +275,6 @@ static int s3c_pcm_hw_params(struct snd_pcm_substream *substream, { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct s3c_pcm_info *pcm = snd_soc_dai_get_drvdata(rtd->cpu_dai); - struct s3c_dma_params *dma_data; void __iomem *regs = pcm->regs; struct clk *clk; int sclk_div, sync_div; @@ -284,13 +283,6 @@ static int s3c_pcm_hw_params(struct snd_pcm_substream *substream, dev_dbg(pcm->dev, "Entered %s\n", __func__); - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - dma_data = pcm->dma_playback; - else - dma_data = pcm->dma_capture; - - snd_soc_dai_set_dma_data(rtd->cpu_dai, substream, dma_data); - /* Strictly check for sample size */ switch (params_format(params)) { case SNDRV_PCM_FORMAT_S16_LE: @@ -461,10 +453,20 @@ static const struct snd_soc_dai_ops s3c_pcm_dai_ops = { .set_fmt = s3c_pcm_set_fmt, }; +static int s3c_pcm_dai_probe(struct snd_soc_dai *dai) +{ + struct s3c_pcm_info *pcm = snd_soc_dai_get_drvdata(dai); + + snd_soc_dai_init_dma_data(dai, pcm->dma_playback, pcm->dma_capture); + + return 0; +} + #define S3C_PCM_RATES SNDRV_PCM_RATE_8000_96000 #define S3C_PCM_DAI_DECLARE \ .symmetric_rates = 1, \ + .probe = s3c_pcm_dai_probe, \ .ops = &s3c_pcm_dai_ops, \ .playback = { \ .channels_min = 2, \ diff --git a/sound/soc/samsung/regs-ac97.h b/sound/soc/samsung/regs-ac97.h index c3878f7acb83..a71be45bbffc 100644 --- a/sound/soc/samsung/regs-ac97.h +++ b/sound/soc/samsung/regs-ac97.h @@ -1,5 +1,4 @@ -/* arch/arm/mach-s3c2410/include/mach/regs-ac97.h - * +/* * Copyright (c) 2006 Simtec Electronics <linux@simtec.co.uk> * http://www.simtec.co.uk/products/SWLINUX/ * @@ -10,8 +9,8 @@ * S3C2440 AC97 Controller */ -#ifndef __ASM_ARCH_REGS_AC97_H -#define __ASM_ARCH_REGS_AC97_H __FILE__ +#ifndef __SAMSUNG_REGS_AC97_H__ +#define __SAMSUNG_REGS_AC97_H__ #define S3C_AC97_GLBCTRL (0x00) @@ -64,4 +63,4 @@ #define S3C_AC97_PCM_DATA (0x18) #define S3C_AC97_MIC_DATA (0x1C) -#endif /* __ASM_ARCH_REGS_AC97_H */ +#endif /* __SAMSUNG_REGS_AC97_H__ */ diff --git a/sound/soc/samsung/regs-iis.h b/sound/soc/samsung/regs-iis.h index a18d35e7a735..dc6cbbe9c4f0 100644 --- a/sound/soc/samsung/regs-iis.h +++ b/sound/soc/samsung/regs-iis.h @@ -1,5 +1,4 @@ -/* arch/arm/plat-samsung/include/plat/regs-iis.h - * +/* * Copyright (c) 2003 Simtec Electronics <linux@simtec.co.uk> * http://www.simtec.co.uk/products/SWLINUX/ * @@ -10,8 +9,8 @@ * S3C2410 IIS register definition */ -#ifndef __ASM_ARCH_REGS_IIS_H -#define __ASM_ARCH_REGS_IIS_H +#ifndef __SAMSUNG_REGS_IIS_H__ +#define __SAMSUNG_REGS_IIS_H__ #define S3C2410_IISCON (0x00) @@ -67,4 +66,4 @@ #define S3C2410_IISFIFO (0x10) -#endif /* __ASM_ARCH_REGS_IIS_H */ +#endif /* __SAMSUNG_REGS_IIS_H__ */ |