ASoc: msm: Add support for slimbus shared channel.
Previously, DSP used to setup the data path towards the
codec via slimbus. Now, the data path setup is broken into
two parts - one half of the path setup between apps to slimbus
and the other half from DSP. This configuration mode is
required to reduce overflow or underflow errors. Also this is
required to handle a configuration where mdm can talk
directly to codec.
Change-Id: Ic9f20b8a2f8a8eb355c07565ec80ec947a7a7337
Signed-off-by: Bharath Ramachandramurthy <bramacha@codeaurora.org>
diff --git a/sound/soc/msm/msm8960.c b/sound/soc/msm/msm8960.c
index 1ed73e2..bedfd68 100644
--- a/sound/soc/msm/msm8960.c
+++ b/sound/soc/msm/msm8960.c
@@ -643,6 +643,66 @@
return tabla_cal;
}
+static int msm8960_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_dai *cpu_dai = rtd->cpu_dai;
+ int ret = 0;
+ unsigned int rx_ch[SLIM_MAX_RX_PORTS], tx_ch[SLIM_MAX_TX_PORTS];
+ unsigned int rx_ch_cnt = 0, tx_ch_cnt = 0;
+
+ pr_debug("%s: ch=%d\n", __func__,
+ msm8960_slim_0_rx_ch);
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ ret = snd_soc_dai_get_channel_map(codec_dai,
+ &tx_ch_cnt, tx_ch, &rx_ch_cnt , rx_ch);
+ if (ret < 0) {
+ pr_err("%s: failed to get codec chan map\n", __func__);
+ goto end;
+ }
+
+ ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0,
+ msm8960_slim_0_rx_ch, rx_ch);
+ if (ret < 0) {
+ pr_err("%s: failed to set cpu chan map\n", __func__);
+ goto end;
+ }
+ ret = snd_soc_dai_set_channel_map(codec_dai, 0, 0,
+ msm8960_slim_0_rx_ch, rx_ch);
+ if (ret < 0) {
+ pr_err("%s: failed to set codec channel map\n",
+ __func__);
+ goto end;
+ }
+ } else {
+ ret = snd_soc_dai_get_channel_map(codec_dai,
+ &tx_ch_cnt, tx_ch, &rx_ch_cnt , rx_ch);
+ if (ret < 0) {
+ pr_err("%s: failed to get codec chan map\n", __func__);
+ goto end;
+ }
+ ret = snd_soc_dai_set_channel_map(cpu_dai,
+ msm8960_slim_0_tx_ch, tx_ch, 0 , 0);
+ if (ret < 0) {
+ pr_err("%s: failed to set cpu chan map\n", __func__);
+ goto end;
+ }
+ ret = snd_soc_dai_set_channel_map(codec_dai,
+ msm8960_slim_0_tx_ch, tx_ch, 0, 0);
+ if (ret < 0) {
+ pr_err("%s: failed to set codec channel map\n",
+ __func__);
+ goto end;
+ }
+
+
+ }
+end:
+ return ret;
+}
+
static int msm8960_audrx_init(struct snd_soc_pcm_runtime *rtd)
{
int err;
@@ -914,6 +974,7 @@
static struct snd_soc_ops msm8960_be_ops = {
.startup = msm8960_startup,
+ .hw_params = msm8960_hw_params,
.shutdown = msm8960_shutdown,
};