diff options
Diffstat (limited to 'sound/soc/cirrus')
| -rw-r--r-- | sound/soc/cirrus/Kconfig | 6 | ||||
| -rw-r--r-- | sound/soc/cirrus/edb93xx.c | 2 | ||||
| -rw-r--r-- | sound/soc/cirrus/ep93xx-ac97.c | 49 | ||||
| -rw-r--r-- | sound/soc/cirrus/ep93xx-i2s.c | 37 | ||||
| -rw-r--r-- | sound/soc/cirrus/ep93xx-pcm.c | 169 | ||||
| -rw-r--r-- | sound/soc/cirrus/ep93xx-pcm.h | 22 | ||||
| -rw-r--r-- | sound/soc/cirrus/simone.c | 2 | ||||
| -rw-r--r-- | sound/soc/cirrus/snappercl15.c | 20 |
8 files changed, 98 insertions, 209 deletions
diff --git a/sound/soc/cirrus/Kconfig b/sound/soc/cirrus/Kconfig index 88143db7e75..5477c547592 100644 --- a/sound/soc/cirrus/Kconfig +++ b/sound/soc/cirrus/Kconfig @@ -1,7 +1,7 @@ config SND_EP93XX_SOC tristate "SoC Audio support for the Cirrus Logic EP93xx series" - depends on ARCH_EP93XX && SND_SOC - select SND_SOC_DMAENGINE_PCM + depends on ARCH_EP93XX || COMPILE_TEST + select SND_SOC_GENERIC_DMAENGINE_PCM help Say Y or M if you want to add support for codecs attached to the EP93xx I2S or AC97 interfaces. @@ -18,7 +18,7 @@ config SND_EP93XX_SOC_SNAPPERCL15 tristate "SoC Audio support for Bluewater Systems Snapper CL15 module" depends on SND_EP93XX_SOC && MACH_SNAPPER_CL15 select SND_EP93XX_SOC_I2S - select SND_SOC_TLV320AIC23 + select SND_SOC_TLV320AIC23_I2C help Say Y or M here if you want to add support for I2S audio on the Bluewater Systems Snapper CL15 module. diff --git a/sound/soc/cirrus/edb93xx.c b/sound/soc/cirrus/edb93xx.c index c43fb214558..4f900efc437 100644 --- a/sound/soc/cirrus/edb93xx.c +++ b/sound/soc/cirrus/edb93xx.c @@ -63,7 +63,7 @@ static struct snd_soc_ops edb93xx_ops = { static struct snd_soc_dai_link edb93xx_dai = { .name = "CS4271", .stream_name = "CS4271 HiFi", - .platform_name = "ep93xx-pcm-audio", + .platform_name = "ep93xx-i2s", .cpu_dai_name = "ep93xx-i2s", .codec_name = "spi0.0", .codec_dai_name = "cs4271-hifi", diff --git a/sound/soc/cirrus/ep93xx-ac97.c b/sound/soc/cirrus/ep93xx-ac97.c index 7798fbd5e81..f30dadf85b9 100644 --- a/sound/soc/cirrus/ep93xx-ac97.c +++ b/sound/soc/cirrus/ep93xx-ac97.c @@ -19,11 +19,14 @@ #include <linux/slab.h> #include <sound/core.h> +#include <sound/dmaengine_pcm.h> #include <sound/ac97_codec.h> #include <sound/soc.h> #include <linux/platform_data/dma-ep93xx.h> +#include "ep93xx-pcm.h" + /* * Per channel (1-4) registers. */ @@ -95,6 +98,8 @@ struct ep93xx_ac97_info { struct device *dev; void __iomem *regs; struct completion done; + struct snd_dmaengine_dai_dma_data dma_params_rx; + struct snd_dmaengine_dai_dma_data dma_params_tx; }; /* currently ALSA only supports a single AC97 device */ @@ -102,13 +107,13 @@ static struct ep93xx_ac97_info *ep93xx_ac97_info; static struct ep93xx_dma_data ep93xx_ac97_pcm_out = { .name = "ac97-pcm-out", - .dma_port = EP93XX_DMA_AAC1, + .port = EP93XX_DMA_AAC1, .direction = DMA_MEM_TO_DEV, }; static struct ep93xx_dma_data ep93xx_ac97_pcm_in = { .name = "ac97-pcm-in", - .dma_port = EP93XX_DMA_AAC1, + .port = EP93XX_DMA_AAC1, .direction = DMA_DEV_TO_MEM, }; @@ -237,13 +242,12 @@ static irqreturn_t ep93xx_ac97_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } -struct snd_ac97_bus_ops soc_ac97_ops = { +static struct snd_ac97_bus_ops ep93xx_ac97_ops = { .read = ep93xx_ac97_read, .write = ep93xx_ac97_write, .reset = ep93xx_ac97_cold_reset, .warm_reset = ep93xx_ac97_warm_reset, }; -EXPORT_SYMBOL_GPL(soc_ac97_ops); static int ep93xx_ac97_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai) @@ -314,22 +318,20 @@ static int ep93xx_ac97_trigger(struct snd_pcm_substream *substream, return 0; } -static int ep93xx_ac97_startup(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) +static int ep93xx_ac97_dai_probe(struct snd_soc_dai *dai) { - struct ep93xx_dma_data *dma_data; + struct ep93xx_ac97_info *info = snd_soc_dai_get_drvdata(dai); + + info->dma_params_tx.filter_data = &ep93xx_ac97_pcm_out; + info->dma_params_rx.filter_data = &ep93xx_ac97_pcm_in; - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - dma_data = &ep93xx_ac97_pcm_out; - else - dma_data = &ep93xx_ac97_pcm_in; + dai->playback_dma_data = &info->dma_params_tx; + dai->capture_dma_data = &info->dma_params_rx; - snd_soc_dai_set_dma_data(dai, substream, dma_data); return 0; } static const struct snd_soc_dai_ops ep93xx_ac97_dai_ops = { - .startup = ep93xx_ac97_startup, .trigger = ep93xx_ac97_trigger, }; @@ -337,6 +339,7 @@ static struct snd_soc_dai_driver ep93xx_ac97_dai = { .name = "ep93xx-ac97", .id = 0, .ac97_control = 1, + .probe = ep93xx_ac97_dai_probe, .playback = { .stream_name = "AC97 Playback", .channels_min = 2, @@ -370,9 +373,6 @@ static int ep93xx_ac97_probe(struct platform_device *pdev) return -ENOMEM; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) - return -ENODEV; - info->regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(info->regs)) return PTR_ERR(info->regs); @@ -395,17 +395,26 @@ static int ep93xx_ac97_probe(struct platform_device *pdev) ep93xx_ac97_info = info; platform_set_drvdata(pdev, info); + ret = snd_soc_set_ac97_ops(&ep93xx_ac97_ops); + if (ret) + goto fail; + ret = snd_soc_register_component(&pdev->dev, &ep93xx_ac97_component, &ep93xx_ac97_dai, 1); if (ret) goto fail; + ret = devm_ep93xx_pcm_platform_register(&pdev->dev); + if (ret) + goto fail_unregister; + return 0; +fail_unregister: + snd_soc_unregister_component(&pdev->dev); fail: - platform_set_drvdata(pdev, NULL); ep93xx_ac97_info = NULL; - dev_set_drvdata(&pdev->dev, NULL); + snd_soc_set_ac97_ops(NULL); return ret; } @@ -418,9 +427,9 @@ static int ep93xx_ac97_remove(struct platform_device *pdev) /* disable the AC97 controller */ ep93xx_ac97_write_reg(info, AC97GCR, 0); - platform_set_drvdata(pdev, NULL); ep93xx_ac97_info = NULL; - dev_set_drvdata(&pdev->dev, NULL); + + snd_soc_set_ac97_ops(NULL); return 0; } diff --git a/sound/soc/cirrus/ep93xx-i2s.c b/sound/soc/cirrus/ep93xx-i2s.c index 5c1102e9e15..943145f9d1b 100644 --- a/sound/soc/cirrus/ep93xx-i2s.c +++ b/sound/soc/cirrus/ep93xx-i2s.c @@ -21,6 +21,7 @@ #include <linux/io.h> #include <sound/core.h> +#include <sound/dmaengine_pcm.h> #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/initval.h> @@ -30,6 +31,8 @@ #include <mach/ep93xx-regs.h> #include <linux/platform_data/dma-ep93xx.h> +#include "ep93xx-pcm.h" + #define EP93XX_I2S_TXCLKCFG 0x00 #define EP93XX_I2S_RXCLKCFG 0x04 #define EP93XX_I2S_GLCTRL 0x0C @@ -60,11 +63,12 @@ struct ep93xx_i2s_info { struct clk *mclk; struct clk *sclk; struct clk *lrclk; - struct ep93xx_dma_data *dma_data; void __iomem *regs; + struct snd_dmaengine_dai_dma_data dma_params_rx; + struct snd_dmaengine_dai_dma_data dma_params_tx; }; -struct ep93xx_dma_data ep93xx_i2s_dma_data[] = { +static struct ep93xx_dma_data ep93xx_i2s_dma_data[] = { [SNDRV_PCM_STREAM_PLAYBACK] = { .name = "i2s-pcm-out", .port = EP93XX_DMA_I2S1, @@ -139,15 +143,18 @@ static void ep93xx_i2s_disable(struct ep93xx_i2s_info *info, int stream) } } -static int ep93xx_i2s_startup(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) +static int ep93xx_i2s_dai_probe(struct snd_soc_dai *dai) { - struct snd_soc_pcm_runtime *rtd = substream->private_data; struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(dai); - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - snd_soc_dai_set_dma_data(cpu_dai, substream, - &info->dma_data[substream->stream]); + info->dma_params_tx.filter_data = + &ep93xx_i2s_dma_data[SNDRV_PCM_STREAM_PLAYBACK]; + info->dma_params_rx.filter_data = + &ep93xx_i2s_dma_data[SNDRV_PCM_STREAM_CAPTURE]; + + dai->playback_dma_data = &info->dma_params_tx; + dai->capture_dma_data = &info->dma_params_rx; + return 0; } @@ -338,7 +345,6 @@ static int ep93xx_i2s_resume(struct snd_soc_dai *dai) #endif static const struct snd_soc_dai_ops ep93xx_i2s_dai_ops = { - .startup = ep93xx_i2s_startup, .shutdown = ep93xx_i2s_shutdown, .hw_params = ep93xx_i2s_hw_params, .set_sysclk = ep93xx_i2s_set_sysclk, @@ -349,6 +355,7 @@ static const struct snd_soc_dai_ops ep93xx_i2s_dai_ops = { static struct snd_soc_dai_driver ep93xx_i2s_dai = { .symmetric_rates= 1, + .probe = ep93xx_i2s_dai_probe, .suspend = ep93xx_i2s_suspend, .resume = ep93xx_i2s_resume, .playback = { @@ -381,9 +388,6 @@ static int ep93xx_i2s_probe(struct platform_device *pdev) return -ENOMEM; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) - return -ENODEV; - info->regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(info->regs)) return PTR_ERR(info->regs); @@ -407,17 +411,21 @@ static int ep93xx_i2s_probe(struct platform_device *pdev) } dev_set_drvdata(&pdev->dev, info); - info->dma_data = ep93xx_i2s_dma_data; err = snd_soc_register_component(&pdev->dev, &ep93xx_i2s_component, &ep93xx_i2s_dai, 1); if (err) goto fail_put_lrclk; + err = devm_ep93xx_pcm_platform_register(&pdev->dev); + if (err) + goto fail_unregister; + return 0; +fail_unregister: + snd_soc_unregister_component(&pdev->dev); fail_put_lrclk: - dev_set_drvdata(&pdev->dev, NULL); clk_put(info->lrclk); fail_put_sclk: clk_put(info->sclk); @@ -432,7 +440,6 @@ static int ep93xx_i2s_remove(struct platform_device *pdev) struct ep93xx_i2s_info *info = dev_get_drvdata(&pdev->dev); snd_soc_unregister_component(&pdev->dev); - dev_set_drvdata(&pdev->dev, NULL); clk_put(info->lrclk); clk_put(info->sclk); clk_put(info->mclk); diff --git a/sound/soc/cirrus/ep93xx-pcm.c b/sound/soc/cirrus/ep93xx-pcm.c index 48803269037..5f664471d99 100644 --- a/sound/soc/cirrus/ep93xx-pcm.c +++ b/sound/soc/cirrus/ep93xx-pcm.c @@ -14,35 +14,22 @@ #include <linux/module.h> #include <linux/init.h> -#include <linux/device.h> -#include <linux/slab.h> +#include <linux/platform_device.h> #include <linux/dmaengine.h> -#include <linux/dma-mapping.h> -#include <sound/core.h> #include <sound/pcm.h> -#include <sound/pcm_params.h> #include <sound/soc.h> #include <sound/dmaengine_pcm.h> #include <linux/platform_data/dma-ep93xx.h> -#include <mach/hardware.h> -#include <mach/ep93xx-regs.h> + +#include "ep93xx-pcm.h" static const struct snd_pcm_hardware ep93xx_pcm_hardware = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER), - - .rates = SNDRV_PCM_RATE_8000_192000, - .rate_min = SNDRV_PCM_RATE_8000, - .rate_max = SNDRV_PCM_RATE_192000, - - .formats = (SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_S24_LE | - SNDRV_PCM_FMTBIT_S32_LE), - .buffer_bytes_max = 131072, .period_bytes_min = 32, .period_bytes_max = 32768, @@ -63,150 +50,22 @@ static bool ep93xx_pcm_dma_filter(struct dma_chan *chan, void *filter_param) return false; } -static int ep93xx_pcm_open(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - - snd_soc_set_runtime_hwparams(substream, &ep93xx_pcm_hardware); - - return snd_dmaengine_pcm_open_request_chan(substream, - ep93xx_pcm_dma_filter, - snd_soc_dai_get_dma_data(rtd->cpu_dai, substream)); -} - -static int ep93xx_pcm_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); - - return 0; -} - -static int ep93xx_pcm_hw_free(struct snd_pcm_substream *substream) -{ - snd_pcm_set_runtime_buffer(substream, NULL); - return 0; -} - -static int ep93xx_pcm_mmap(struct snd_pcm_substream *substream, - struct vm_area_struct *vma) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - - return dma_mmap_writecombine(substream->pcm->card->dev, vma, - runtime->dma_area, - runtime->dma_addr, - runtime->dma_bytes); -} - -static struct snd_pcm_ops ep93xx_pcm_ops = { - .open = ep93xx_pcm_open, - .close = snd_dmaengine_pcm_close_release_chan, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = ep93xx_pcm_hw_params, - .hw_free = ep93xx_pcm_hw_free, - .trigger = snd_dmaengine_pcm_trigger, - .pointer = snd_dmaengine_pcm_pointer_no_residue, - .mmap = ep93xx_pcm_mmap, +static const struct snd_dmaengine_pcm_config ep93xx_dmaengine_pcm_config = { + .pcm_hardware = &ep93xx_pcm_hardware, + .compat_filter_fn = ep93xx_pcm_dma_filter, + .prealloc_buffer_size = 131072, }; -static int ep93xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream) +int devm_ep93xx_pcm_platform_register(struct device *dev) { - struct snd_pcm_substream *substream = pcm->streams[stream].substream; - struct snd_dma_buffer *buf = &substream->dma_buffer; - size_t size = ep93xx_pcm_hardware.buffer_bytes_max; - - buf->dev.type = SNDRV_DMA_TYPE_DEV; - buf->dev.dev = pcm->card->dev; - buf->private_data = NULL; - buf->area = dma_alloc_writecombine(pcm->card->dev, size, - &buf->addr, GFP_KERNEL); - buf->bytes = size; - - return (buf->area == NULL) ? -ENOMEM : 0; + return devm_snd_dmaengine_pcm_register(dev, + &ep93xx_dmaengine_pcm_config, + SND_DMAENGINE_PCM_FLAG_NO_RESIDUE | + SND_DMAENGINE_PCM_FLAG_NO_DT | + SND_DMAENGINE_PCM_FLAG_COMPAT); } - -static void ep93xx_pcm_free_dma_buffers(struct snd_pcm *pcm) -{ - struct snd_pcm_substream *substream; - struct snd_dma_buffer *buf; - int stream; - - for (stream = 0; stream < 2; stream++) { - substream = pcm->streams[stream].substream; - if (!substream) - continue; - - buf = &substream->dma_buffer; - if (!buf->area) - continue; - - dma_free_writecombine(pcm->card->dev, buf->bytes, buf->area, - buf->addr); - buf->area = NULL; - } -} - -static u64 ep93xx_pcm_dmamask = DMA_BIT_MASK(32); - -static int ep93xx_pcm_new(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_card *card = rtd->card->snd_card; - struct snd_pcm *pcm = rtd->pcm; - int ret = 0; - - if (!card->dev->dma_mask) - card->dev->dma_mask = &ep93xx_pcm_dmamask; - if (!card->dev->coherent_dma_mask) - card->dev->coherent_dma_mask = DMA_BIT_MASK(32); - - if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { - ret = ep93xx_pcm_preallocate_dma_buffer(pcm, - SNDRV_PCM_STREAM_PLAYBACK); - if (ret) - return ret; - } - - if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { - ret = ep93xx_pcm_preallocate_dma_buffer(pcm, - SNDRV_PCM_STREAM_CAPTURE); - if (ret) - return ret; - } - - return 0; -} - -static struct snd_soc_platform_driver ep93xx_soc_platform = { - .ops = &ep93xx_pcm_ops, - .pcm_new = &ep93xx_pcm_new, - .pcm_free = &ep93xx_pcm_free_dma_buffers, -}; - -static int ep93xx_soc_platform_probe(struct platform_device *pdev) -{ - return snd_soc_register_platform(&pdev->dev, &ep93xx_soc_platform); -} - -static int ep93xx_soc_platform_remove(struct platform_device *pdev) -{ - snd_soc_unregister_platform(&pdev->dev); - return 0; -} - -static struct platform_driver ep93xx_pcm_driver = { - .driver = { - .name = "ep93xx-pcm-audio", - .owner = THIS_MODULE, - }, - - .probe = ep93xx_soc_platform_probe, - .remove = ep93xx_soc_platform_remove, -}; - -module_platform_driver(ep93xx_pcm_driver); +EXPORT_SYMBOL_GPL(devm_ep93xx_pcm_platform_register); MODULE_AUTHOR("Ryan Mallon"); MODULE_DESCRIPTION("EP93xx ALSA PCM interface"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:ep93xx-pcm-audio"); diff --git a/sound/soc/cirrus/ep93xx-pcm.h b/sound/soc/cirrus/ep93xx-pcm.h new file mode 100644 index 00000000000..b7a12a2fae9 --- /dev/null +++ b/sound/soc/cirrus/ep93xx-pcm.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef __EP93XX_PCM_H__ +#define __EP93XX_PCM_H__ + +int devm_ep93xx_pcm_platform_register(struct device *dev); + +#endif diff --git a/sound/soc/cirrus/simone.c b/sound/soc/cirrus/simone.c index 4d094d00c34..822a19a89e7 100644 --- a/sound/soc/cirrus/simone.c +++ b/sound/soc/cirrus/simone.c @@ -27,7 +27,7 @@ static struct snd_soc_dai_link simone_dai = { .cpu_dai_name = "ep93xx-ac97", .codec_dai_name = "ac97-hifi", .codec_name = "ac97-codec", - .platform_name = "ep93xx-pcm-audio", + .platform_name = "ep93xx-ac97", }; static struct snd_soc_card snd_soc_simone = { diff --git a/sound/soc/cirrus/snappercl15.c b/sound/soc/cirrus/snappercl15.c index 69041074f2c..5b68b106cfc 100644 --- a/sound/soc/cirrus/snappercl15.c +++ b/sound/soc/cirrus/snappercl15.c @@ -65,26 +65,13 @@ static const struct snd_soc_dapm_route audio_map[] = { {"MICIN", NULL, "Mic Jack"}, }; -static int snappercl15_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_codec *codec = rtd->codec; - struct snd_soc_dapm_context *dapm = &codec->dapm; - - snd_soc_dapm_new_controls(dapm, tlv320aic23_dapm_widgets, - ARRAY_SIZE(tlv320aic23_dapm_widgets)); - - snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); - return 0; -} - static struct snd_soc_dai_link snappercl15_dai = { .name = "tlv320aic23", .stream_name = "AIC23", .cpu_dai_name = "ep93xx-i2s", .codec_dai_name = "tlv320aic23-hifi", .codec_name = "tlv320aic23-codec.0-001a", - .platform_name = "ep93xx-pcm-audio", - .init = snappercl15_tlv320aic23_init, + .platform_name = "ep93xx-i2s", .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_IF | SND_SOC_DAIFMT_CBS_CFS, .ops = &snappercl15_ops, @@ -95,6 +82,11 @@ static struct snd_soc_card snd_soc_snappercl15 = { .owner = THIS_MODULE, .dai_link = &snappercl15_dai, .num_links = 1, + + .dapm_widgets = tlv320aic23_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(tlv320aic23_dapm_widgets), + .dapm_routes = audio_map, + .num_dapm_routes = ARRAY_SIZE(audio_map), }; static int snappercl15_probe(struct platform_device *pdev) |
