summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastien Guiriec <s-guiriec@ti.com>2010-08-03 18:39:25 +0200
committerXavier Boudet <x-boudet@ti.com>2010-08-05 01:09:41 +0200
commit17c5c8b2639366394406ff1937a349e7813ca955 (patch)
tree02034e1d9d3906cd21da4b72eeb82f10a5310e17
parent88d151695e5634fe1a66b4542771902660000d13 (diff)
ASoC: ABE: Switch to PDM_UL synchronization in case no DL is running
ABE event source synchronization selection must be switched to PDM_UL in case only uplink is running. In current Kernel synchronization source is always McPDM DL event if DL is not running.
-rw-r--r--sound/soc/codecs/abe-twl6040.c86
1 files changed, 54 insertions, 32 deletions
diff --git a/sound/soc/codecs/abe-twl6040.c b/sound/soc/codecs/abe-twl6040.c
index 8251cffad8e2..f37769a7ca58 100644
--- a/sound/soc/codecs/abe-twl6040.c
+++ b/sound/soc/codecs/abe-twl6040.c
@@ -1163,6 +1163,48 @@ static int twl6040_set_dai_sysclk(struct snd_soc_dai *codec_dai,
return 0;
}
+static inline void abe_mcpdm_dl_hw_params(struct twl6040_data *priv)
+{
+ if (!priv->mcpdm_dl_enable++)
+ abe_enable_data_transfer(PDM_DL_PORT);
+}
+
+static inline void abe_mcpdm_ul_hw_params(struct twl6040_data *priv)
+{
+ if (!priv->mcpdm_ul_enable++) {
+ /* Check if Downlinnk is not running to move
+ * to McPDM Uplink port for drift management */
+ if (!priv->mcpdm_dl_enable)
+ abe_select_main_port(PDM_UL_PORT);
+ abe_enable_data_transfer(PDM_UL_PORT);
+ }
+}
+
+static inline void abe_mcpdm_dl_shutdown(struct twl6040_data *priv)
+{
+ if (!--priv->mcpdm_dl_enable) {
+ abe_disable_data_transfer(PDM_DL_PORT);
+ /* Check if uplinnk is running to move
+ * to McPDM Uplink port for drift management */
+ if (priv->mcpdm_ul_enable)
+ abe_select_main_port(PDM_UL_PORT);
+ else
+ abe_disable_data_transfer(PDM_UL_PORT);
+ }
+}
+
+static inline void abe_mcpdm_ul_shutdown(struct twl6040_data *priv)
+{
+ if (!--priv->mcpdm_ul_enable) {
+ /* Dissable ATC only if no DL in parallel (HW issue) */
+ if (!priv->mcpdm_dl_enable)
+ abe_disable_data_transfer(PDM_UL_PORT);
+
+ /* Always move back to McPDM downlink after playback */
+ abe_select_main_port(PDM_DL_PORT);
+ }
+}
+
static int abe_mm_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
@@ -1273,14 +1315,11 @@ static int abe_mm_hw_params(struct snd_pcm_substream *substream,
if (!substream->stream) {
abe_connect_cbpr_dmareq_port(MM_DL_PORT, &format, ABE_CBPR0_IDX, &dma_sink);
abe_enable_data_transfer(MM_DL_PORT);
- if (!priv->mcpdm_dl_enable++) {
- abe_enable_data_transfer(PDM_DL_PORT);
- }
+ abe_mcpdm_dl_hw_params(priv);
} else {
abe_connect_cbpr_dmareq_port(MM_UL2_PORT, &format, ABE_CBPR4_IDX, &dma_sink);
abe_enable_data_transfer(MM_UL2_PORT);
- if (!priv->mcpdm_ul_enable++)
- abe_enable_data_transfer(PDM_UL_PORT);
+ abe_mcpdm_ul_hw_params(priv);
}
return 0;
@@ -1348,13 +1387,10 @@ static void abe_mm_shutdown(struct snd_pcm_substream *substream,
if (!substream->stream) {
abe_disable_data_transfer(MM_DL_PORT);
- if (!--priv->mcpdm_dl_enable) {
- abe_disable_data_transfer(PDM_DL_PORT);
- }
+ abe_mcpdm_dl_shutdown(priv);
} else {
abe_disable_data_transfer(MM_UL2_PORT);
- if (!--priv->mcpdm_ul_enable)
- abe_disable_data_transfer(PDM_UL_PORT);
+ abe_mcpdm_ul_shutdown(priv);
}
if (!--priv->configure) {
@@ -1456,8 +1492,7 @@ static int abe_tones_hw_params(struct snd_pcm_substream *substream,
abe_connect_cbpr_dmareq_port(TONES_DL_PORT, &format,
ABE_CBPR5_IDX, &dma_sink);
abe_enable_data_transfer(TONES_DL_PORT);
- if (!priv->mcpdm_dl_enable++)
- abe_enable_data_transfer(PDM_DL_PORT);
+ abe_mcpdm_dl_hw_params(priv);
}
return 0;
@@ -1525,8 +1560,7 @@ static void abe_tones_shutdown(struct snd_pcm_substream *substream,
if (!substream->stream) {
abe_disable_data_transfer(TONES_DL_PORT);
- if (!--priv->mcpdm_dl_enable)
- abe_disable_data_transfer(PDM_DL_PORT);
+ abe_mcpdm_dl_shutdown(priv);
}
if (!--priv->configure) {
@@ -1656,8 +1690,7 @@ static int abe_voice_hw_params(struct snd_pcm_substream *substream,
abe_connect_serial_port(VX_DL_PORT, &format, MCBSP2_RX);
/* Enable downlink port */
abe_enable_data_transfer(VX_DL_PORT);
- if (!priv->mcpdm_dl_enable++)
- abe_enable_data_transfer(PDM_DL_PORT);
+ abe_mcpdm_dl_hw_params(priv);
} else {
/* Vx_UL connection to McBSP 2 ports */
format.f = 8000;
@@ -1665,20 +1698,17 @@ static int abe_voice_hw_params(struct snd_pcm_substream *substream,
abe_connect_serial_port(VX_UL_PORT, &format, MCBSP2_TX);
/* Enable uplink port */
abe_enable_data_transfer(VX_UL_PORT);
- if (!priv->mcpdm_ul_enable++)
- abe_enable_data_transfer(PDM_UL_PORT);
+ abe_mcpdm_ul_hw_params(priv);
}
#else
if (!substream->stream) {
abe_connect_cbpr_dmareq_port(VX_DL_PORT, &format, ABE_CBPR1_IDX, &dma_sink);
abe_enable_data_transfer(VX_DL_PORT);
- if (!priv->mcpdm_dl_enable++)
- abe_enable_data_transfer(PDM_DL_PORT);
+ abe_mcpdm_dl_hw_params(priv);
} else {
abe_connect_cbpr_dmareq_port(VX_UL_PORT, &format, ABE_CBPR2_IDX, &dma_sink);
abe_enable_data_transfer(VX_UL_PORT);
- if (!priv->mcpdm_ul_enable++)
- abe_enable_data_transfer(PDM_UL_PORT);
+ abe_mcpdm_ul_hw_params(priv);
}
#endif
@@ -1747,18 +1777,10 @@ static void abe_voice_shutdown(struct snd_pcm_substream *substream,
if (!substream->stream) {
abe_disable_data_transfer(VX_DL_PORT);
- if (!--priv->mcpdm_dl_enable) {
- abe_disable_data_transfer(PDM_DL_PORT);
- if (priv->mcpdm_ul_enable == 0)
- abe_disable_data_transfer(PDM_UL_PORT);
- }
+ abe_mcpdm_dl_shutdown(priv);
} else {
abe_disable_data_transfer(VX_UL_PORT);
- if (!--priv->mcpdm_ul_enable) {
- if (priv->mcpdm_dl_enable == 0) {
- abe_disable_data_transfer(PDM_UL_PORT);
- }
- }
+ abe_mcpdm_ul_shutdown(priv);
}
if(!--priv->configure) {