diff options
Diffstat (limited to 'sound/soc/omap/sdp4430.c')
-rw-r--r-- | sound/soc/omap/sdp4430.c | 96 |
1 files changed, 79 insertions, 17 deletions
diff --git a/sound/soc/omap/sdp4430.c b/sound/soc/omap/sdp4430.c index 69427c8..3d6a554 100644 --- a/sound/soc/omap/sdp4430.c +++ b/sound/soc/omap/sdp4430.c @@ -33,6 +33,7 @@ #include <asm/mach-types.h> #include <plat/hardware.h> #include <plat/mux.h> +#include <plat/mcbsp.h> #include "omap-mcpdm.h" #include "omap-abe.h" @@ -43,13 +44,65 @@ static int twl6040_power_mode; static int mcbsp_cfg; +static int sdp4430_modem_mcbsp_configure(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, int flag) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_pcm_substream *modem_substream[2]; + struct snd_soc_pcm_runtime *modem_rtd; + int channels; + + if (flag) { + modem_substream[substream->stream] = + snd_soc_get_dai_substream(rtd->card, + OMAP_ABE_BE_MM_EXT1, + substream->stream); + if (unlikely(modem_substream[substream->stream] == NULL)) + return -ENODEV; + + modem_rtd = + modem_substream[substream->stream]->private_data; + + if (!mcbsp_cfg) { + /* Set cpu DAI configuration */ + ret = snd_soc_dai_set_fmt(modem_rtd->cpu_dai, + SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBM_CFM); + + if (unlikely(ret < 0)) { + printk(KERN_ERR "can't set Modem cpu DAI configuration\n"); + goto exit; + } else { + mcbsp_cfg = 1; + } + } + + if (params != NULL) { + /* Configure McBSP internal buffer usage */ + /* this need to be done for playback and/or record */ + channels = params_channels(params); + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + omap_mcbsp_set_rx_threshold( + modem_rtd->cpu_dai->id, channels); + else + omap_mcbsp_set_tx_threshold( + modem_rtd->cpu_dai->id, channels); + } + } else { + mcbsp_cfg = 0; + } + +exit: + return ret; +} + static int sdp4430_mcpdm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *codec_dai = rtd->codec_dai; - struct snd_soc_pcm_runtime *modem_rtd; - struct snd_pcm_substream *modem_substream[2]; struct snd_soc_dsp_params *dsp_params; int clk_id, freq, ret, stream = substream->stream; @@ -73,23 +126,31 @@ static int sdp4430_mcpdm_hw_params(struct snd_pcm_substream *substream, if (dsp_params->fe->cpu_dai->id != ABE_FRONTEND_DAI_MODEM) continue; - if (!mcbsp_cfg) { - modem_substream[stream] = - snd_soc_get_dai_substream(rtd->card, - OMAP_ABE_BE_MM_EXT1, - substream->stream); - if (modem_substream[stream] == NULL) - return -ENODEV; + /* freed Modem McBSP configuration */ + ret = sdp4430_modem_mcbsp_configure(substream, params, 1); + if (ret < 0) { + printk(KERN_ERR "can't set Modem cpu DAI configuration\n"); + return ret; + } + } + return ret; +} - modem_rtd = modem_substream[stream]->private_data; +static int sdp4430_mcpdm_hw_free(struct snd_pcm_substream *substream) +{ + int ret = 0; - /* Set cpu DAI configuration */ - ret = snd_soc_dai_set_fmt(modem_rtd->cpu_dai, - SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBM_CFM); - mcbsp_cfg = 1; - } + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dsp_params *dsp_params; + int stream = substream->stream; + + list_for_each_entry(dsp_params, &rtd->dsp[stream].fe_clients, list_fe) { + + if (dsp_params->fe->cpu_dai->id != ABE_FRONTEND_DAI_MODEM) + continue; + + /* freed Modem McBSP configuration */ + ret = sdp4430_modem_mcbsp_configure(substream, NULL, 0); if (ret < 0) { printk(KERN_ERR "can't set Modem cpu DAI configuration\n"); return ret; @@ -100,6 +161,7 @@ static int sdp4430_mcpdm_hw_params(struct snd_pcm_substream *substream, static struct snd_soc_ops sdp4430_mcpdm_ops = { .hw_params = sdp4430_mcpdm_hw_params, + .hw_free = sdp4430_mcpdm_hw_free, }; static int sdp4430_mcbsp_hw_params(struct snd_pcm_substream *substream, |