From 2b730cc38d3ca592b4f9f71989e7f0c79b37b3b3 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 5 Jan 2015 10:18:21 +0100 Subject: [PATCH 01/10] ASoC: alc5632: Constify struct regmap_config and snd_soc_codec_driver The regmap_config struct may be const because it is not modified by the driver and regmap_init() accepts pointer to const. Make struct snd_soc_codec_driver const as well (snd_soc_register_codec() accepts pointer to const). Signed-off-by: Krzysztof Kozlowski Signed-off-by: Mark Brown --- sound/soc/codecs/alc5632.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/alc5632.c b/sound/soc/codecs/alc5632.c index d1fdbc266631..07630260e1ba 100644 --- a/sound/soc/codecs/alc5632.c +++ b/sound/soc/codecs/alc5632.c @@ -1066,7 +1066,7 @@ static int alc5632_probe(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver soc_codec_device_alc5632 = { +static const struct snd_soc_codec_driver soc_codec_device_alc5632 = { .probe = alc5632_probe, .resume = alc5632_resume, .set_bias_level = alc5632_set_bias_level, @@ -1080,7 +1080,7 @@ static struct snd_soc_codec_driver soc_codec_device_alc5632 = { .num_dapm_routes = ARRAY_SIZE(alc5632_dapm_routes), }; -static struct regmap_config alc5632_regmap = { +static const struct regmap_config alc5632_regmap = { .reg_bits = 8, .val_bits = 16, From 12e29a075d4c0c9767261068cdcbfa4b346a451b Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 2 Jan 2015 13:56:08 +0100 Subject: [PATCH 02/10] ASoC: au1x: Remove unnecessary snd_pcm_lib_preallocate_free_for_all() The ALSA core takes care that all preallocated memory is freed when the PCM itself is freed. There is no need to do this manually in the driver. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/au1x/dbdma2.c | 6 ------ sound/soc/au1x/dma.c | 6 ------ 2 files changed, 12 deletions(-) diff --git a/sound/soc/au1x/dbdma2.c b/sound/soc/au1x/dbdma2.c index b06b8d8128c6..dd94fea72d5d 100644 --- a/sound/soc/au1x/dbdma2.c +++ b/sound/soc/au1x/dbdma2.c @@ -315,11 +315,6 @@ static struct snd_pcm_ops au1xpsc_pcm_ops = { .pointer = au1xpsc_pcm_pointer, }; -static void au1xpsc_pcm_free_dma_buffers(struct snd_pcm *pcm) -{ - snd_pcm_lib_preallocate_free_for_all(pcm); -} - static int au1xpsc_pcm_new(struct snd_soc_pcm_runtime *rtd) { struct snd_card *card = rtd->card->snd_card; @@ -335,7 +330,6 @@ static int au1xpsc_pcm_new(struct snd_soc_pcm_runtime *rtd) static struct snd_soc_platform_driver au1xpsc_soc_platform = { .ops = &au1xpsc_pcm_ops, .pcm_new = au1xpsc_pcm_new, - .pcm_free = au1xpsc_pcm_free_dma_buffers, }; static int au1xpsc_pcm_drvprobe(struct platform_device *pdev) diff --git a/sound/soc/au1x/dma.c b/sound/soc/au1x/dma.c index 6ffaaff469c7..24cc7f40d87a 100644 --- a/sound/soc/au1x/dma.c +++ b/sound/soc/au1x/dma.c @@ -287,11 +287,6 @@ static struct snd_pcm_ops alchemy_pcm_ops = { .pointer = alchemy_pcm_pointer, }; -static void alchemy_pcm_free_dma_buffers(struct snd_pcm *pcm) -{ - snd_pcm_lib_preallocate_free_for_all(pcm); -} - static int alchemy_pcm_new(struct snd_soc_pcm_runtime *rtd) { struct snd_pcm *pcm = rtd->pcm; @@ -305,7 +300,6 @@ static int alchemy_pcm_new(struct snd_soc_pcm_runtime *rtd) static struct snd_soc_platform_driver alchemy_pcm_soc_platform = { .ops = &alchemy_pcm_ops, .pcm_new = alchemy_pcm_new, - .pcm_free = alchemy_pcm_free_dma_buffers, }; static int alchemy_pcm_drvprobe(struct platform_device *pdev) From 7491831f4f034e2d76326518145da9525dd90932 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Tue, 6 Jan 2015 10:21:20 +0100 Subject: [PATCH 03/10] ASoC: atmel: sam9g20_wm8731: remove useless include A mach/ header is included but never used. Simply remove it. Signed-off-by: Alexandre Belloni Acked-by: Bo Shen Signed-off-by: Mark Brown --- sound/soc/atmel/sam9g20_wm8731.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/atmel/sam9g20_wm8731.c b/sound/soc/atmel/sam9g20_wm8731.c index 66b66d0e7514..531728975bbb 100644 --- a/sound/soc/atmel/sam9g20_wm8731.c +++ b/sound/soc/atmel/sam9g20_wm8731.c @@ -47,7 +47,6 @@ #include #include -#include #include "../codecs/wm8731.h" #include "atmel-pcm.h" From bdb2c74d44be691e6d3b6d441e81ea13dab34145 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 12 Jan 2015 13:54:13 +0100 Subject: [PATCH 04/10] ASoC: ad193x: Don't power down DAC in CODEC probe The DAC powerdown bit is managed by DAPM. Manually powering down the DAC in the CODEC probe function may cause unnecessary power state transitions which can lead to click and pop noises. So leave the DAC powerdown bit in its default poweron-reset state and let DAPM do all the management. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/ad193x.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c index 387530b0b0fd..17c953595660 100644 --- a/sound/soc/codecs/ad193x.c +++ b/sound/soc/codecs/ad193x.c @@ -333,8 +333,8 @@ static int ad193x_codec_probe(struct snd_soc_codec *codec) regmap_write(ad193x->regmap, AD193X_DAC_CHNL_MUTE, 0x0); /* de-emphasis: 48kHz, powedown dac */ regmap_write(ad193x->regmap, AD193X_DAC_CTRL2, 0x1A); - /* powerdown dac, dac in tdm mode */ - regmap_write(ad193x->regmap, AD193X_DAC_CTRL0, 0x41); + /* dac in tdm mode */ + regmap_write(ad193x->regmap, AD193X_DAC_CTRL0, 0x40); /* high-pass filter enable */ regmap_write(ad193x->regmap, AD193X_ADC_CTRL0, 0x3); /* sata delay=1, adc aux mode */ From d869769663a19d79ddad24ff906576fc2cf0fbb4 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Tue, 13 Jan 2015 13:27:26 +0100 Subject: [PATCH 05/10] Asoc: sam9x5_wm8731: depend on ARCH_AT91 instead of SOC_AT91SAM9X5 The SOC_AT91SAM9X5 option is going to be removed, only depend on ARCH_AT91 like for the other drivers. Signed-off-by: Alexandre Belloni Acked-by: Nicolas Ferre Acked-by: Bo Shen Signed-off-by: Mark Brown --- sound/soc/atmel/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/atmel/Kconfig b/sound/soc/atmel/Kconfig index fb3878312bf8..1579e994acf8 100644 --- a/sound/soc/atmel/Kconfig +++ b/sound/soc/atmel/Kconfig @@ -45,7 +45,7 @@ config SND_ATMEL_SOC_WM8904 config SND_AT91_SOC_SAM9X5_WM8731 tristate "SoC Audio support for WM8731-based at91sam9x5 board" - depends on ATMEL_SSC && SND_ATMEL_SOC && SOC_AT91SAM9X5 + depends on ARCH_AT91 && ATMEL_SSC && SND_ATMEL_SOC select SND_ATMEL_SOC_SSC select SND_ATMEL_SOC_DMA select SND_SOC_WM8731 From 67d1aed0a5de49dfbc81315610a4fd49c864ec45 Mon Sep 17 00:00:00 2001 From: Bo Shen Date: Tue, 20 Jan 2015 15:43:17 +0800 Subject: [PATCH 06/10] ASoC: atmel_ssc_dai: remove clock pin comments As the clock can be get from TK/RK pin, so remove the comments. Signed-off-by: Bo Shen Signed-off-by: Mark Brown --- sound/soc/atmel/atmel_ssc_dai.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c index e691aab60761..3cd70597d109 100644 --- a/sound/soc/atmel/atmel_ssc_dai.c +++ b/sound/soc/atmel/atmel_ssc_dai.c @@ -450,13 +450,7 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream, break; case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM: - /* - * I2S format, CODEC supplies BCLK and LRC clocks. - * - * The SSC transmit clock is obtained from the BCLK signal on - * on the TK line, and the SSC receive clock is - * generated from the transmit clock. - */ + /* I2S format, CODEC supplies BCLK and LRC clocks. */ rcmr = SSC_BF(RCMR_PERIOD, 0) | SSC_BF(RCMR_STTDLY, START_DELAY) | SSC_BF(RCMR_START, SSC_START_FALLING_RF) @@ -535,10 +529,6 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream, /* * DSP/PCM Mode A format, CODEC supplies BCLK and LRC clocks. * - * The SSC transmit clock is obtained from the BCLK signal on - * on the TK line, and the SSC receive clock is - * generated from the transmit clock. - * * Data is transferred on first BCLK after LRC pulse rising * edge.If stereo, the right channel data is contiguous with * the left channel data. From eb5271497f212f9e2323adc0a2fd8a9358e751e4 Mon Sep 17 00:00:00 2001 From: Peter Rosin Date: Thu, 29 Jan 2015 11:16:29 +0100 Subject: [PATCH 07/10] ASoC: atmel_ssc_dai: Support SND_SOC_DAIFMT_CBM_CFS on I2S Signed-off-by: Peter Rosin Acked-by: Bo Shen Signed-off-by: Mark Brown --- sound/soc/atmel/atmel_ssc_dai.c | 48 +++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c index 3cd70597d109..f55f3aab8bdd 100644 --- a/sound/soc/atmel/atmel_ssc_dai.c +++ b/sound/soc/atmel/atmel_ssc_dai.c @@ -485,6 +485,54 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream, | SSC_BF(TFMR_DATLEN, (bits - 1)); break; + case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFS: + /* I2S format, CODEC supplies BCLK, SSC supplies LRCLK. */ + if (bits > 16 && !ssc->pdata->has_fslen_ext) { + dev_err(dai->dev, + "sample size %d is too large for SSC device\n", + bits); + return -EINVAL; + } + + fslen_ext = (bits - 1) / 16; + fslen = (bits - 1) % 16; + + rcmr = SSC_BF(RCMR_PERIOD, ssc_p->rcmr_period) + | SSC_BF(RCMR_STTDLY, START_DELAY) + | SSC_BF(RCMR_START, SSC_START_FALLING_RF) + | SSC_BF(RCMR_CKI, SSC_CKI_RISING) + | SSC_BF(RCMR_CKO, SSC_CKO_NONE) + | SSC_BF(RCMR_CKS, ssc->clk_from_rk_pin ? + SSC_CKS_PIN : SSC_CKS_CLOCK); + + rfmr = SSC_BF(RFMR_FSLEN_EXT, fslen_ext) + | SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE) + | SSC_BF(RFMR_FSOS, SSC_FSOS_NEGATIVE) + | SSC_BF(RFMR_FSLEN, fslen) + | SSC_BF(RFMR_DATNB, (channels - 1)) + | SSC_BIT(RFMR_MSBF) + | SSC_BF(RFMR_LOOP, 0) + | SSC_BF(RFMR_DATLEN, (bits - 1)); + + tcmr = SSC_BF(TCMR_PERIOD, ssc_p->tcmr_period) + | SSC_BF(TCMR_STTDLY, START_DELAY) + | SSC_BF(TCMR_START, SSC_START_FALLING_RF) + | SSC_BF(TCMR_CKI, SSC_CKI_FALLING) + | SSC_BF(TCMR_CKO, SSC_CKO_NONE) + | SSC_BF(TCMR_CKS, ssc->clk_from_rk_pin ? + SSC_CKS_CLOCK : SSC_CKS_PIN); + + tfmr = SSC_BF(TFMR_FSLEN_EXT, fslen_ext) + | SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_NEGATIVE) + | SSC_BF(TFMR_FSDEN, 0) + | SSC_BF(TFMR_FSOS, SSC_FSOS_NEGATIVE) + | SSC_BF(TFMR_FSLEN, fslen) + | SSC_BF(TFMR_DATNB, (channels - 1)) + | SSC_BIT(TFMR_MSBF) + | SSC_BF(TFMR_DATDEF, 0) + | SSC_BF(TFMR_DATLEN, (bits - 1)); + break; + case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBS_CFS: /* * DSP/PCM Mode A format, SSC provides BCLK and LRC clocks. From cbaadf0f90d6d406a36bb389fbdea524d6d89d8d Mon Sep 17 00:00:00 2001 From: Bo Shen Date: Fri, 30 Jan 2015 17:38:43 +0800 Subject: [PATCH 08/10] ASoC: atmel_ssc_dai: refactor the startup and shutdown In startup function, enable ssc clock and in shutdown function, disable clock. And also remove disable ssc in shutdown function, as ssc is disabled in prepare function. Signed-off-by: Bo Shen Signed-off-by: Mark Brown --- sound/soc/atmel/atmel_ssc_dai.c | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c index f55f3aab8bdd..76a9754370e8 100644 --- a/sound/soc/atmel/atmel_ssc_dai.c +++ b/sound/soc/atmel/atmel_ssc_dai.c @@ -204,6 +204,13 @@ static int atmel_ssc_startup(struct snd_pcm_substream *substream, pr_debug("atmel_ssc_startup: SSC_SR=0x%u\n", ssc_readl(ssc_p->ssc->regs, SR)); + /* Enable PMC peripheral clock for this SSC */ + pr_debug("atmel_ssc_dai: Starting clock\n"); + clk_enable(ssc_p->ssc->clk); + + /* Reset the SSC to keep it at a clean status */ + ssc_writel(ssc_p->ssc->regs, CR, SSC_BIT(CR_SWRST)); + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { dir = 0; dir_mask = SSC_DIR_MASK_PLAYBACK; @@ -250,11 +257,6 @@ static void atmel_ssc_shutdown(struct snd_pcm_substream *substream, dma_params = ssc_p->dma_params[dir]; if (dma_params != NULL) { - ssc_writel(ssc_p->ssc->regs, CR, dma_params->mask->ssc_disable); - pr_debug("atmel_ssc_shutdown: %s disabled SSC_SR=0x%08x\n", - (dir ? "receive" : "transmit"), - ssc_readl(ssc_p->ssc->regs, SR)); - dma_params->ssc = NULL; dma_params->substream = NULL; ssc_p->dma_params[dir] = NULL; @@ -266,10 +268,6 @@ static void atmel_ssc_shutdown(struct snd_pcm_substream *substream, ssc_p->dir_mask &= ~dir_mask; if (!ssc_p->dir_mask) { if (ssc_p->initialized) { - /* Shutdown the SSC clock. */ - pr_debug("atmel_ssc_dai: Stopping clock\n"); - clk_disable(ssc_p->ssc->clk); - free_irq(ssc_p->ssc->irq, ssc_p); ssc_p->initialized = 0; } @@ -280,6 +278,10 @@ static void atmel_ssc_shutdown(struct snd_pcm_substream *substream, ssc_p->cmr_div = ssc_p->tcmr_period = ssc_p->rcmr_period = 0; } spin_unlock_irq(&ssc_p->lock); + + /* Shutdown the SSC clock. */ + pr_debug("atmel_ssc_dai: Stopping clock\n"); + clk_disable(ssc_p->ssc->clk); } @@ -625,14 +627,6 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream, rcmr, rfmr, tcmr, tfmr); if (!ssc_p->initialized) { - - /* Enable PMC peripheral clock for this SSC */ - pr_debug("atmel_ssc_dai: Starting clock\n"); - clk_enable(ssc_p->ssc->clk); - - /* Reset the SSC and its PDC registers */ - ssc_writel(ssc_p->ssc->regs, CR, SSC_BIT(CR_SWRST)); - ssc_writel(ssc_p->ssc->regs, PDC_RPR, 0); ssc_writel(ssc_p->ssc->regs, PDC_RCR, 0); ssc_writel(ssc_p->ssc->regs, PDC_RNPR, 0); From 3fd5b30c577bdd51168f38cf4f2d322619015a53 Mon Sep 17 00:00:00 2001 From: Bo Shen Date: Fri, 30 Jan 2015 17:38:44 +0800 Subject: [PATCH 09/10] ASoC: atmel_ssc_dai: only clean PDC when using PDC Only using PDC, it needs to clean PDC registers. Signed-off-by: Bo Shen Signed-off-by: Mark Brown --- sound/soc/atmel/atmel_ssc_dai.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c index 76a9754370e8..379ac2a6ab16 100644 --- a/sound/soc/atmel/atmel_ssc_dai.c +++ b/sound/soc/atmel/atmel_ssc_dai.c @@ -627,15 +627,17 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream, rcmr, rfmr, tcmr, tfmr); if (!ssc_p->initialized) { - ssc_writel(ssc_p->ssc->regs, PDC_RPR, 0); - ssc_writel(ssc_p->ssc->regs, PDC_RCR, 0); - ssc_writel(ssc_p->ssc->regs, PDC_RNPR, 0); - ssc_writel(ssc_p->ssc->regs, PDC_RNCR, 0); + if (!ssc_p->ssc->pdata->use_dma) { + ssc_writel(ssc_p->ssc->regs, PDC_RPR, 0); + ssc_writel(ssc_p->ssc->regs, PDC_RCR, 0); + ssc_writel(ssc_p->ssc->regs, PDC_RNPR, 0); + ssc_writel(ssc_p->ssc->regs, PDC_RNCR, 0); - ssc_writel(ssc_p->ssc->regs, PDC_TPR, 0); - ssc_writel(ssc_p->ssc->regs, PDC_TCR, 0); - ssc_writel(ssc_p->ssc->regs, PDC_TNPR, 0); - ssc_writel(ssc_p->ssc->regs, PDC_TNCR, 0); + ssc_writel(ssc_p->ssc->regs, PDC_TPR, 0); + ssc_writel(ssc_p->ssc->regs, PDC_TCR, 0); + ssc_writel(ssc_p->ssc->regs, PDC_TNPR, 0); + ssc_writel(ssc_p->ssc->regs, PDC_TNCR, 0); + } ret = request_irq(ssc_p->ssc->irq, atmel_ssc_interrupt, 0, ssc_p->name, ssc_p); From 56bbd86c2e47d4f7707cb329fc008487c940ca27 Mon Sep 17 00:00:00 2001 From: Bo Shen Date: Mon, 2 Feb 2015 14:44:46 +0800 Subject: [PATCH 10/10] ASoC: atmel-pcm-dma: won't check direction when configure dma As DMA framework request DMA using direction only in prep_slave function, (The At91 xdma driver has adapted to this request). So won't check direction when do DMA configuration. Signed-off-by: Bo Shen Signed-off-by: Mark Brown --- sound/soc/atmel/atmel-pcm-dma.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/sound/soc/atmel/atmel-pcm-dma.c b/sound/soc/atmel/atmel-pcm-dma.c index 33fb3bb133df..b8e7bad05eb1 100644 --- a/sound/soc/atmel/atmel-pcm-dma.c +++ b/sound/soc/atmel/atmel-pcm-dma.c @@ -105,13 +105,11 @@ static int atmel_pcm_configure_dma(struct snd_pcm_substream *substream, return ret; } - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - slave_config->dst_addr = ssc->phybase + SSC_THR; - slave_config->dst_maxburst = 1; - } else { - slave_config->src_addr = ssc->phybase + SSC_RHR; - slave_config->src_maxburst = 1; - } + slave_config->dst_addr = ssc->phybase + SSC_THR; + slave_config->dst_maxburst = 1; + + slave_config->src_addr = ssc->phybase + SSC_RHR; + slave_config->src_maxburst = 1; prtd->dma_intr_handler = atmel_pcm_dma_irq;