aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/davinci
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--sound/soc/davinci/Kconfig25
-rw-r--r--sound/soc/davinci/Makefile2
-rw-r--r--sound/soc/davinci/davinci-mcasp.c93
-rw-r--r--sound/soc/davinci/edma-pcm.c2
-rw-r--r--sound/soc/davinci/edma-pcm.h7
5 files changed, 114 insertions, 15 deletions
diff --git a/sound/soc/davinci/Kconfig b/sound/soc/davinci/Kconfig
index 50a098749b9e..d69510c53239 100644
--- a/sound/soc/davinci/Kconfig
+++ b/sound/soc/davinci/Kconfig
@@ -1,12 +1,29 @@
config SND_DAVINCI_SOC
- tristate "SoC Audio for TI DAVINCI or AM33XX/AM43XX chips"
- depends on ARCH_DAVINCI || SOC_AM33XX || SOC_AM43XX
+ tristate "SoC Audio for TI DAVINCI"
+ depends on ARCH_DAVINCI
+
+config SND_EDMA_SOC
+ tristate "SoC Audio for Texas Instruments chips using eDMA (AM33XX/43XX)"
+ depends on SOC_AM33XX || SOC_AM43XX
+ select SND_SOC_GENERIC_DMAENGINE_PCM
+ help
+ Say Y or M here if you want audio support for TI SoC which uses eDMA.
+ The following line of SoCs are supported by this platform driver:
+ - AM335x
+ - AM437x/AM438x
config SND_DAVINCI_SOC_I2S
tristate
config SND_DAVINCI_SOC_MCASP
- tristate
+ tristate "Multichannel Audio Serial Port (McASP) support"
+ depends on SND_DAVINCI_SOC || SND_OMAP_SOC || SND_EDMA_SOC
+ help
+ Say Y or M here if you want to have support for McASP IP found in
+ various Texas Instruments SoCs like:
+ - daVinci devices
+ - Sitara line of SoCs (AM335x, AM438x, etc)
+ - DRA7x devices
config SND_DAVINCI_SOC_VCIF
tristate
@@ -18,7 +35,7 @@ config SND_DAVINCI_SOC_GENERIC_EVM
config SND_AM33XX_SOC_EVM
tristate "SoC Audio for the AM33XX chip based boards"
- depends on SND_DAVINCI_SOC && SOC_AM33XX && I2C
+ depends on SND_EDMA_SOC && SOC_AM33XX && I2C
select SND_DAVINCI_SOC_GENERIC_EVM
help
Say Y or M if you want to add support for SoC audio on AM33XX
diff --git a/sound/soc/davinci/Makefile b/sound/soc/davinci/Makefile
index 744d4d9a0184..09bf2ba92d38 100644
--- a/sound/soc/davinci/Makefile
+++ b/sound/soc/davinci/Makefile
@@ -1,10 +1,12 @@
# DAVINCI Platform Support
snd-soc-davinci-objs := davinci-pcm.o
+snd-soc-edma-objs := edma-pcm.o
snd-soc-davinci-i2s-objs := davinci-i2s.o
snd-soc-davinci-mcasp-objs:= davinci-mcasp.o
snd-soc-davinci-vcif-objs:= davinci-vcif.o
obj-$(CONFIG_SND_DAVINCI_SOC) += snd-soc-davinci.o
+obj-$(CONFIG_SND_EDMA_SOC) += snd-soc-edma.o
obj-$(CONFIG_SND_DAVINCI_SOC_I2S) += snd-soc-davinci-i2s.o
obj-$(CONFIG_SND_DAVINCI_SOC_MCASP) += snd-soc-davinci-mcasp.o
obj-$(CONFIG_SND_DAVINCI_SOC_VCIF) += snd-soc-davinci-vcif.o
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index 9afb14629a17..c28508da34cf 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -27,6 +27,7 @@
#include <linux/of_platform.h>
#include <linux/of_device.h>
+#include <sound/asoundef.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
@@ -36,6 +37,7 @@
#include <sound/omap-pcm.h>
#include "davinci-pcm.h"
+#include "edma-pcm.h"
#include "davinci-mcasp.h"
#define MCASP_MAX_AFIFO_DEPTH 64
@@ -63,6 +65,7 @@ struct davinci_mcasp {
u8 num_serializer;
u8 *serial_dir;
u8 version;
+ u8 bclk_div;
u16 bclk_lrclk_ratio;
int streams;
@@ -417,6 +420,7 @@ static int davinci_mcasp_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div
ACLKXDIV(div - 1), ACLKXDIV_MASK);
mcasp_mod_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG,
ACLKRDIV(div - 1), ACLKRDIV_MASK);
+ mcasp->bclk_div = div;
break;
case 2: /* BCLK/LRCLK ratio */
@@ -637,8 +641,12 @@ static int mcasp_i2s_hw_param(struct davinci_mcasp *mcasp, int stream)
}
/* S/PDIF */
-static int mcasp_dit_hw_param(struct davinci_mcasp *mcasp)
+static int mcasp_dit_hw_param(struct davinci_mcasp *mcasp,
+ unsigned int rate)
{
+ u32 cs_value = 0;
+ u8 *cs_bytes = (u8*) &cs_value;
+
/* Set the TX format : 24 bit right rotation, 32 bit slot, Pad 0
and LSB first */
mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, TXROT(6) | TXSSZ(15));
@@ -660,6 +668,46 @@ static int mcasp_dit_hw_param(struct davinci_mcasp *mcasp)
/* Enable the DIT */
mcasp_set_bits(mcasp, DAVINCI_MCASP_TXDITCTL_REG, DITEN);
+ /* Set S/PDIF channel status bits */
+ cs_bytes[0] = IEC958_AES0_CON_NOT_COPYRIGHT;
+ cs_bytes[1] = IEC958_AES1_CON_PCM_CODER;
+
+ switch (rate) {
+ case 22050:
+ cs_bytes[3] |= IEC958_AES3_CON_FS_22050;
+ break;
+ case 24000:
+ cs_bytes[3] |= IEC958_AES3_CON_FS_24000;
+ break;
+ case 32000:
+ cs_bytes[3] |= IEC958_AES3_CON_FS_32000;
+ break;
+ case 44100:
+ cs_bytes[3] |= IEC958_AES3_CON_FS_44100;
+ break;
+ case 48000:
+ cs_bytes[3] |= IEC958_AES3_CON_FS_48000;
+ break;
+ case 88200:
+ cs_bytes[3] |= IEC958_AES3_CON_FS_88200;
+ break;
+ case 96000:
+ cs_bytes[3] |= IEC958_AES3_CON_FS_96000;
+ break;
+ case 176400:
+ cs_bytes[3] |= IEC958_AES3_CON_FS_176400;
+ break;
+ case 192000:
+ cs_bytes[3] |= IEC958_AES3_CON_FS_192000;
+ break;
+ default:
+ printk(KERN_WARNING "unsupported sampling rate: %d\n", rate);
+ return -EINVAL;
+ }
+
+ mcasp_set_reg(mcasp, DAVINCI_MCASP_DITCSRA_REG, cs_value);
+ mcasp_set_reg(mcasp, DAVINCI_MCASP_DITCSRB_REG, cs_value);
+
return 0;
}
@@ -675,15 +723,22 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
int period_size = params_period_size(params);
int ret;
- /* If mcasp is BCLK master we need to set BCLK divider */
- if (mcasp->bclk_master) {
+ /*
+ * If mcasp is BCLK master, and a BCLK divider was not provided by
+ * the machine driver, we need to calculate the ratio.
+ */
+ if (mcasp->bclk_master && mcasp->bclk_div == 0 && mcasp->sysclk_freq) {
unsigned int bclk_freq = snd_soc_params_to_bclk(params);
+ unsigned int div = mcasp->sysclk_freq / bclk_freq;
if (mcasp->sysclk_freq % bclk_freq != 0) {
- dev_err(mcasp->dev, "Can't produce required BCLK\n");
- return -EINVAL;
+ if (((mcasp->sysclk_freq / div) - bclk_freq) >
+ (bclk_freq - (mcasp->sysclk_freq / (div+1))))
+ div++;
+ dev_warn(mcasp->dev,
+ "Inaccurate BCLK: %u Hz / %u != %u Hz\n",
+ mcasp->sysclk_freq, div, bclk_freq);
}
- davinci_mcasp_set_clkdiv(
- cpu_dai, 1, mcasp->sysclk_freq / bclk_freq);
+ davinci_mcasp_set_clkdiv(cpu_dai, 1, div);
}
ret = mcasp_common_hw_param(mcasp, substream->stream,
@@ -692,7 +747,7 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
return ret;
if (mcasp->op_mode == DAVINCI_MCASP_DIT_MODE)
- ret = mcasp_dit_hw_param(mcasp);
+ ret = mcasp_dit_hw_param(mcasp, params_rate(params));
else
ret = mcasp_i2s_hw_param(mcasp, substream->stream);
@@ -720,6 +775,10 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
case SNDRV_PCM_FORMAT_U24_LE:
case SNDRV_PCM_FORMAT_S24_LE:
+ dma_params->data_type = 4;
+ word_length = 24;
+ break;
+
case SNDRV_PCM_FORMAT_U32_LE:
case SNDRV_PCM_FORMAT_S32_LE:
dma_params->data_type = 4;
@@ -778,7 +837,7 @@ static int davinci_mcasp_dai_probe(struct snd_soc_dai *dai)
{
struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai);
- if (mcasp->version == MCASP_VERSION_4) {
+ if (mcasp->version >= MCASP_VERSION_3) {
/* Using dmaengine PCM */
dai->playback_dma_data =
&mcasp->dma_data[SNDRV_PCM_STREAM_PLAYBACK];
@@ -1223,14 +1282,28 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
goto err;
switch (mcasp->version) {
+#if IS_BUILTIN(CONFIG_SND_DAVINCI_SOC) || \
+ (IS_MODULE(CONFIG_SND_DAVINCI_SOC_MCASP) && \
+ IS_MODULE(CONFIG_SND_DAVINCI_SOC))
case MCASP_VERSION_1:
case MCASP_VERSION_2:
- case MCASP_VERSION_3:
ret = davinci_soc_platform_register(&pdev->dev);
break;
+#endif
+#if IS_BUILTIN(CONFIG_SND_EDMA_SOC) || \
+ (IS_MODULE(CONFIG_SND_DAVINCI_SOC_MCASP) && \
+ IS_MODULE(CONFIG_SND_EDMA_SOC))
+ case MCASP_VERSION_3:
+ ret = edma_pcm_platform_register(&pdev->dev);
+ break;
+#endif
+#if IS_BUILTIN(CONFIG_SND_OMAP_SOC) || \
+ (IS_MODULE(CONFIG_SND_DAVINCI_SOC_MCASP) && \
+ IS_MODULE(CONFIG_SND_OMAP_SOC))
case MCASP_VERSION_4:
ret = omap_pcm_platform_register(&pdev->dev);
break;
+#endif
default:
dev_err(&pdev->dev, "Invalid McASP version: %d\n",
mcasp->version);
diff --git a/sound/soc/davinci/edma-pcm.c b/sound/soc/davinci/edma-pcm.c
index d38afb1c61ae..605e643133db 100644
--- a/sound/soc/davinci/edma-pcm.c
+++ b/sound/soc/davinci/edma-pcm.c
@@ -28,8 +28,8 @@
static const struct snd_pcm_hardware edma_pcm_hardware = {
.info = SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_BATCH |
SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME |
+ SNDRV_PCM_INFO_NO_PERIOD_WAKEUP |
SNDRV_PCM_INFO_INTERLEAVED,
.buffer_bytes_max = 128 * 1024,
.period_bytes_min = 32,
diff --git a/sound/soc/davinci/edma-pcm.h b/sound/soc/davinci/edma-pcm.h
index 894c378c0f74..b0957744851c 100644
--- a/sound/soc/davinci/edma-pcm.h
+++ b/sound/soc/davinci/edma-pcm.h
@@ -20,6 +20,13 @@
#ifndef __EDMA_PCM_H__
#define __EDMA_PCM_H__
+#if IS_ENABLED(CONFIG_SND_EDMA_SOC)
int edma_pcm_platform_register(struct device *dev);
+#else
+static inline int edma_pcm_platform_register(struct device *dev)
+{
+ return 0;
+}
+#endif /* CONFIG_SND_EDMA_SOC */
#endif /* __EDMA_PCM_H__ */