ASoC: msm: add dai link for SLIM_2_Rx and tabla_rx3.
Dai link connecting Slimbus2 RX CPU DAI to tabla_rx3 dai is used for
sending Ultrasound stream to ear piece or external top Speaker.
Change-Id: If25fb5a959a191a056227ab01c4ba9603014fd32
Signed-off-by: Kiran Kandi <kkandi@codeaurora.org>
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index 806bbd8..72430e6 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -2187,6 +2187,7 @@
&apq_cpudai_stub,
&apq_cpudai_slimbus_1_rx,
&apq_cpudai_slimbus_1_tx,
+ &apq_cpudai_slimbus_2_rx,
&apq_cpudai_slimbus_2_tx,
&apq_cpudai_slimbus_3_rx,
&apq8064_rpm_device,
diff --git a/arch/arm/mach-msm/board-8960.c b/arch/arm/mach-msm/board-8960.c
index e0831fb..90ba66b 100644
--- a/arch/arm/mach-msm/board-8960.c
+++ b/arch/arm/mach-msm/board-8960.c
@@ -2521,6 +2521,7 @@
&msm_pcm_routing,
&msm_cpudai0,
&msm_cpudai1,
+ &msm8960_cpudai_slimbus_2_rx,
&msm8960_cpudai_slimbus_2_tx,
&msm_cpudai_hdmi_rx,
&msm_cpudai_bt_rx,
@@ -2577,6 +2578,7 @@
&msm_pcm_routing,
&msm_cpudai0,
&msm_cpudai1,
+ &msm8960_cpudai_slimbus_2_rx,
&msm8960_cpudai_slimbus_2_tx,
&msm_cpudai_hdmi_rx,
&msm_cpudai_bt_rx,
diff --git a/arch/arm/mach-msm/devices-8064.c b/arch/arm/mach-msm/devices-8064.c
index 1382632..6401722 100644
--- a/arch/arm/mach-msm/devices-8064.c
+++ b/arch/arm/mach-msm/devices-8064.c
@@ -608,6 +608,11 @@
.id = 0x4003,
};
+struct platform_device apq_cpudai_slimbus_2_rx = {
+ .name = "msm-dai-q6",
+ .id = 0x4004,
+};
+
struct platform_device apq_cpudai_slimbus_2_tx = {
.name = "msm-dai-q6",
.id = 0x4005,
diff --git a/arch/arm/mach-msm/devices-8960.c b/arch/arm/mach-msm/devices-8960.c
index be364e7..14ddd96 100644
--- a/arch/arm/mach-msm/devices-8960.c
+++ b/arch/arm/mach-msm/devices-8960.c
@@ -1841,6 +1841,11 @@
.id = 0x4001,
};
+struct platform_device msm8960_cpudai_slimbus_2_rx = {
+ .name = "msm-dai-q6",
+ .id = 0x4004,
+};
+
struct platform_device msm8960_cpudai_slimbus_2_tx = {
.name = "msm-dai-q6",
.id = 0x4005,
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h
index f180aa5..0b59c00 100644
--- a/arch/arm/mach-msm/devices.h
+++ b/arch/arm/mach-msm/devices.h
@@ -202,6 +202,7 @@
extern struct platform_device msm_cpudai0;
extern struct platform_device msm_cpudai1;
extern struct platform_device mpq_cpudai_sec_i2s_rx;
+extern struct platform_device msm8960_cpudai_slimbus_2_rx;
extern struct platform_device msm8960_cpudai_slimbus_2_tx;
extern struct platform_device msm_cpudai_hdmi_rx;
extern struct platform_device msm_cpudai_bt_rx;
@@ -267,6 +268,7 @@
extern struct platform_device apq_cpudai_stub;
extern struct platform_device apq_cpudai_slimbus_1_rx;
extern struct platform_device apq_cpudai_slimbus_1_tx;
+extern struct platform_device apq_cpudai_slimbus_2_rx;
extern struct platform_device apq_cpudai_slimbus_2_tx;
extern struct platform_device apq_cpudai_slimbus_3_rx;
extern struct platform_device apq_cpudai_slim_4_rx;
diff --git a/sound/soc/msm/apq8064.c b/sound/soc/msm/apq8064.c
index 353ffd6..f48bab9 100644
--- a/sound/soc/msm/apq8064.c
+++ b/sound/soc/msm/apq8064.c
@@ -46,6 +46,8 @@
#define BOTTOM_SPK_AMP_NEG 0x2
#define TOP_SPK_AMP_POS 0x4
#define TOP_SPK_AMP_NEG 0x8
+#define TOP_SPK_AMP 0x10
+
#define GPIO_AUX_PCM_DOUT 43
#define GPIO_AUX_PCM_DIN 44
@@ -201,10 +203,14 @@
usleep_range(4000, 4000);
}
- } else if (spk & (TOP_SPK_AMP_POS | TOP_SPK_AMP_NEG)) {
+ } else if (spk & (TOP_SPK_AMP_POS | TOP_SPK_AMP_NEG | TOP_SPK_AMP)) {
- if ((msm_ext_top_spk_pamp & TOP_SPK_AMP_POS) &&
- (msm_ext_top_spk_pamp & TOP_SPK_AMP_NEG)) {
+ pr_debug("%s():top_spk_amp_state = 0x%x spk_event = 0x%x\n",
+ __func__, msm_ext_top_spk_pamp, spk);
+
+ if (((msm_ext_top_spk_pamp & TOP_SPK_AMP_POS) &&
+ (msm_ext_top_spk_pamp & TOP_SPK_AMP_NEG)) ||
+ (msm_ext_top_spk_pamp & TOP_SPK_AMP)) {
pr_debug("%s() External Top Speaker Ampl already"
"turned on. spk = 0x%08x\n", __func__, spk);
@@ -213,8 +219,9 @@
msm_ext_top_spk_pamp |= spk;
- if ((msm_ext_top_spk_pamp & TOP_SPK_AMP_POS) &&
- (msm_ext_top_spk_pamp & TOP_SPK_AMP_NEG)) {
+ if (((msm_ext_top_spk_pamp & TOP_SPK_AMP_POS) &&
+ (msm_ext_top_spk_pamp & TOP_SPK_AMP_NEG)) ||
+ (msm_ext_top_spk_pamp & TOP_SPK_AMP)) {
msm_enable_ext_spk_amp_gpio(top_spk_pamp_gpio);
pr_debug("%s: sleeping 4 ms after turning on "
@@ -245,17 +252,31 @@
usleep_range(4000, 4000);
- } else if (spk & (TOP_SPK_AMP_POS | TOP_SPK_AMP_NEG)) {
+ } else if (spk & (TOP_SPK_AMP_POS | TOP_SPK_AMP_NEG | TOP_SPK_AMP)) {
+
+ pr_debug("%s: top_spk_amp_state = 0x%x spk_event = 0x%x\n",
+ __func__, msm_ext_top_spk_pamp, spk);
if (!msm_ext_top_spk_pamp)
return;
+ if ((spk & TOP_SPK_AMP_POS) || (spk & TOP_SPK_AMP_NEG)) {
+
+ msm_ext_top_spk_pamp &= (~(TOP_SPK_AMP_POS |
+ TOP_SPK_AMP_NEG));
+ } else if (spk & TOP_SPK_AMP) {
+ msm_ext_top_spk_pamp &= ~TOP_SPK_AMP;
+ }
+
+ if (msm_ext_top_spk_pamp)
+ return;
+
gpio_direction_output(top_spk_pamp_gpio, 0);
gpio_free(top_spk_pamp_gpio);
msm_ext_top_spk_pamp = 0;
- pr_debug("%s: sleeping 4 ms after turning off external Top"
- " Spkaker Ampl\n", __func__);
+ pr_debug("%s: sleeping 4 ms after ext Top Spek Ampl is off\n",
+ __func__);
usleep_range(4000, 4000);
} else {
@@ -320,6 +341,8 @@
msm_ext_spk_power_amp_on(TOP_SPK_AMP_POS);
else if (!strncmp(w->name, "Ext Spk Top Neg", 15))
msm_ext_spk_power_amp_on(TOP_SPK_AMP_NEG);
+ else if (!strncmp(w->name, "Ext Spk Top", 12))
+ msm_ext_spk_power_amp_on(TOP_SPK_AMP);
else {
pr_err("%s() Invalid Speaker Widget = %s\n",
__func__, w->name);
@@ -335,6 +358,8 @@
msm_ext_spk_power_amp_off(TOP_SPK_AMP_POS);
else if (!strncmp(w->name, "Ext Spk Top Neg", 15))
msm_ext_spk_power_amp_off(TOP_SPK_AMP_NEG);
+ else if (!strncmp(w->name, "Ext Spk Top", 12))
+ msm_ext_spk_power_amp_off(TOP_SPK_AMP);
else {
pr_err("%s() Invalid Speaker Widget = %s\n",
__func__, w->name);
@@ -434,6 +459,7 @@
SND_SOC_DAPM_SPK("Ext Spk Top Pos", msm_spkramp_event),
SND_SOC_DAPM_SPK("Ext Spk Top Neg", msm_spkramp_event),
+ SND_SOC_DAPM_SPK("Ext Spk Top", msm_spkramp_event),
/************ Analog MICs ************/
/**
@@ -468,6 +494,7 @@
{"Ext Spk Top Pos", NULL, "LINEOUT2"},
{"Ext Spk Top Neg", NULL, "LINEOUT4"},
+ {"Ext Spk Top", NULL, "LINEOUT5"},
/************ Analog MIC Paths ************/
@@ -814,7 +841,7 @@
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;
- unsigned int user_set_tx_ch = 0;
+ unsigned int num_tx_ch = 0;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
@@ -844,19 +871,17 @@
} else {
if (codec_dai->id == 2)
- user_set_tx_ch = msm_slim_0_tx_ch;
- else if (codec_dai->id == 4)
- user_set_tx_ch = params_channels(params);
+ num_tx_ch = msm_slim_0_tx_ch;
else if (codec_dai->id == 5) {
/* DAI 5 is used for external EC reference from codec.
* Since Rx is fed as reference for EC, the config of
* this DAI is based on that of the Rx path.
*/
- user_set_tx_ch = msm_slim_0_rx_ch;
+ num_tx_ch = msm_slim_0_rx_ch;
}
pr_debug("%s: %s_tx_dai_id_%d_ch=%d\n", __func__,
- codec_dai->name, codec_dai->id, user_set_tx_ch);
+ codec_dai->name, codec_dai->id, num_tx_ch);
ret = snd_soc_dai_get_channel_map(codec_dai,
&tx_ch_cnt, tx_ch, &rx_ch_cnt , rx_ch);
@@ -866,13 +891,13 @@
}
ret = snd_soc_dai_set_channel_map(cpu_dai,
- user_set_tx_ch, tx_ch, 0 , 0);
+ num_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,
- user_set_tx_ch, tx_ch, 0, 0);
+ num_tx_ch, tx_ch, 0, 0);
if (ret < 0) {
pr_err("%s: failed to set codec channel map\n",
__func__);
@@ -892,6 +917,77 @@
return 0;
}
+static int msm_slimbus_2_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;
+ unsigned int num_tx_ch = 0;
+ unsigned int num_rx_ch = 0;
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+
+ num_rx_ch = params_channels(params);
+
+ pr_debug("%s: %s rx_dai_id = %d num_ch = %d\n", __func__,
+ codec_dai->name, codec_dai->id, num_rx_ch);
+
+ 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,
+ num_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,
+ num_rx_ch, rx_ch);
+ if (ret < 0) {
+ pr_err("%s: failed to set codec channel map\n",
+ __func__);
+ goto end;
+ }
+ } else {
+
+ num_tx_ch = params_channels(params);
+
+ pr_debug("%s: %s tx_dai_id = %d num_ch = %d\n", __func__,
+ codec_dai->name, codec_dai->id, num_tx_ch);
+
+ 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,
+ num_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,
+ num_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 msm_slimbus_1_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
@@ -1263,8 +1359,12 @@
}
static int msm_startup(struct snd_pcm_substream *substream)
{
- pr_debug("%s(): substream = %s stream = %d\n", __func__,
- substream->name, substream->stream);
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+
+ pr_debug("%s(): dai_link_str_name = %s cpu_dai = %s codec_dai = %s\n",
+ __func__, rtd->dai_link->stream_name,
+ rtd->dai_link->cpu_dai_name,
+ rtd->dai_link->codec_dai_name);
return 0;
}
@@ -1290,8 +1390,11 @@
static void msm_shutdown(struct snd_pcm_substream *substream)
{
- pr_debug("%s(): substream = %s stream = %d\n", __func__,
- substream->name, substream->stream);
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+
+ pr_debug("%s(): dai_link_str_name = %s cpu_dai = %s codec_dai = %s\n",
+ __func__, rtd->dai_link->stream_name,
+ rtd->dai_link->cpu_dai_name, rtd->dai_link->codec_dai_name);
}
static struct snd_soc_ops msm_be_ops = {
@@ -1323,6 +1426,13 @@
.shutdown = msm_shutdown,
};
+static struct snd_soc_ops msm_slimbus_2_be_ops = {
+ .startup = msm_startup,
+ .hw_params = msm_slimbus_2_hw_params,
+ .shutdown = msm_shutdown,
+};
+
+
/* Digital audio interface glue - connects codec <---> CPU */
static struct snd_soc_dai_link msm_dai[] = {
/* FrontEnd DAI Links */
@@ -1679,18 +1789,30 @@
.be_hw_params_fixup = msm_btsco_be_hw_params_fixup,
.ops = &msm_slimbus_1_be_ops,
},
+ /* Ultrasound TX Back End DAI Link */
{
- .name = "SLIMBUS_2 Hostless",
- .stream_name = "SLIMBUS_2 Hostless",
+ .name = "SLIMBUS_2 Hostless Capture",
+ .stream_name = "SLIMBUS_2 Hostless Capture",
.cpu_dai_name = "msm-dai-q6.16389",
.platform_name = "msm-pcm-hostless",
.codec_name = "tabla_codec",
.codec_dai_name = "tabla_tx2",
.ignore_suspend = 1,
.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
- .ops = &msm_be_ops,
+ .ops = &msm_slimbus_2_be_ops,
},
-
+ /* Ultrasound RX Back End DAI Link */
+ {
+ .name = "SLIMBUS_2 Hostless Playback",
+ .stream_name = "SLIMBUS_2 Hostless Playback",
+ .cpu_dai_name = "msm-dai-q6.16388",
+ .platform_name = "msm-pcm-hostless",
+ .codec_name = "tabla_codec",
+ .codec_dai_name = "tabla_rx3",
+ .ignore_suspend = 1,
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ops = &msm_slimbus_2_be_ops,
+ },
/* Incall Music Back End DAI Link */
{
.name = LPASS_BE_SLIMBUS_4_RX,
diff --git a/sound/soc/msm/msm8960.c b/sound/soc/msm/msm8960.c
index bb5d817..98cfa6d 100644
--- a/sound/soc/msm/msm8960.c
+++ b/sound/soc/msm/msm8960.c
@@ -47,6 +47,7 @@
#define BOTTOM_SPK_AMP_NEG 0x2
#define TOP_SPK_AMP_POS 0x4
#define TOP_SPK_AMP_NEG 0x8
+#define TOP_SPK_AMP 0x10
#define GPIO_AUX_PCM_DOUT 63
#define GPIO_AUX_PCM_DIN 64
@@ -191,10 +192,14 @@
usleep_range(4000, 4000);
}
- } else if (spk & (TOP_SPK_AMP_POS | TOP_SPK_AMP_NEG)) {
+ } else if (spk & (TOP_SPK_AMP_POS | TOP_SPK_AMP_NEG | TOP_SPK_AMP)) {
- if ((msm8960_ext_top_spk_pamp & TOP_SPK_AMP_POS) &&
- (msm8960_ext_top_spk_pamp & TOP_SPK_AMP_NEG)) {
+ pr_debug("%s: top_spk_amp_state = 0x%x spk_event = 0x%x\n",
+ __func__, msm8960_ext_top_spk_pamp, spk);
+
+ if (((msm8960_ext_top_spk_pamp & TOP_SPK_AMP_POS) &&
+ (msm8960_ext_top_spk_pamp & TOP_SPK_AMP_NEG)) ||
+ (msm8960_ext_top_spk_pamp & TOP_SPK_AMP)) {
pr_debug("%s() External Top Speaker Ampl already"
"turned on. spk = 0x%08x\n", __func__, spk);
@@ -203,8 +208,9 @@
msm8960_ext_top_spk_pamp |= spk;
- if ((msm8960_ext_top_spk_pamp & TOP_SPK_AMP_POS) &&
- (msm8960_ext_top_spk_pamp & TOP_SPK_AMP_NEG)) {
+ if (((msm8960_ext_top_spk_pamp & TOP_SPK_AMP_POS) &&
+ (msm8960_ext_top_spk_pamp & TOP_SPK_AMP_NEG)) ||
+ (msm8960_ext_top_spk_pamp & TOP_SPK_AMP)) {
msm8960_enable_ext_spk_amp_gpio(top_spk_pamp_gpio);
pr_debug("%s: sleeping 4 ms after turning on "
@@ -235,17 +241,31 @@
usleep_range(4000, 4000);
- } else if (spk & (TOP_SPK_AMP_POS | TOP_SPK_AMP_NEG)) {
+ } else if (spk & (TOP_SPK_AMP_POS | TOP_SPK_AMP_NEG | TOP_SPK_AMP)) {
+
+ pr_debug("%s: top_spk_amp_state = 0x%x spk_event = 0x%x\n",
+ __func__, msm8960_ext_top_spk_pamp, spk);
if (!msm8960_ext_top_spk_pamp)
return;
+ if ((spk & TOP_SPK_AMP_POS) || (spk & TOP_SPK_AMP_NEG)) {
+
+ msm8960_ext_top_spk_pamp &= (~(TOP_SPK_AMP_POS |
+ TOP_SPK_AMP_NEG));
+ } else if (spk & TOP_SPK_AMP) {
+ msm8960_ext_top_spk_pamp &= ~TOP_SPK_AMP;
+ }
+
+ if (msm8960_ext_top_spk_pamp)
+ return;
+
gpio_direction_output(top_spk_pamp_gpio, 0);
gpio_free(top_spk_pamp_gpio);
msm8960_ext_top_spk_pamp = 0;
- pr_debug("%s: sleeping 4 ms after turning off external Top"
- " Spkaker Ampl\n", __func__);
+ pr_debug("%s: sleeping 4 ms after ext Top Spek Ampl is off\n",
+ __func__);
usleep_range(4000, 4000);
} else {
@@ -313,6 +333,8 @@
msm8960_ext_spk_power_amp_on(TOP_SPK_AMP_POS);
else if (!strncmp(w->name, "Ext Spk Top Neg", 15))
msm8960_ext_spk_power_amp_on(TOP_SPK_AMP_NEG);
+ else if (!strncmp(w->name, "Ext Spk Top", 12))
+ msm8960_ext_spk_power_amp_on(TOP_SPK_AMP);
else {
pr_err("%s() Invalid Speaker Widget = %s\n",
__func__, w->name);
@@ -328,6 +350,8 @@
msm8960_ext_spk_power_amp_off(TOP_SPK_AMP_POS);
else if (!strncmp(w->name, "Ext Spk Top Neg", 15))
msm8960_ext_spk_power_amp_off(TOP_SPK_AMP_NEG);
+ else if (!strncmp(w->name, "Ext Spk Top", 12))
+ msm8960_ext_spk_power_amp_off(TOP_SPK_AMP);
else {
pr_err("%s() Invalid Speaker Widget = %s\n",
__func__, w->name);
@@ -411,6 +435,7 @@
SND_SOC_DAPM_SPK("Ext Spk Top Pos", msm8960_spkramp_event),
SND_SOC_DAPM_SPK("Ext Spk Top Neg", msm8960_spkramp_event),
+ SND_SOC_DAPM_SPK("Ext Spk Top", msm8960_spkramp_event),
SND_SOC_DAPM_MIC("Handset Mic", NULL),
SND_SOC_DAPM_MIC("Headset Mic", NULL),
@@ -438,6 +463,7 @@
{"Ext Spk Top Pos", NULL, "LINEOUT2"},
{"Ext Spk Top Neg", NULL, "LINEOUT4"},
+ {"Ext Spk Top", NULL, "LINEOUT5"},
/* Microphone path */
{"AMIC1", NULL, "MIC BIAS1 Internal1"},
@@ -725,8 +751,6 @@
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;
- unsigned int user_set_tx_ch = 0;
-
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
@@ -754,13 +778,8 @@
}
} else {
- if (codec_dai->id == 2)
- user_set_tx_ch = msm8960_slim_0_tx_ch;
- else if (codec_dai->id == 4)
- user_set_tx_ch = params_channels(params);
-
- pr_debug("%s: %s_tx_dai_id_%d_ch=%d\n", __func__,
- codec_dai->name, codec_dai->id, user_set_tx_ch);
+ pr_debug("%s: %s tx_dai_id = %d num_ch = %d\n", __func__,
+ codec_dai->name, codec_dai->id, msm8960_slim_0_tx_ch);
ret = snd_soc_dai_get_channel_map(codec_dai,
&tx_ch_cnt, tx_ch, &rx_ch_cnt , rx_ch);
@@ -769,20 +788,88 @@
goto end;
}
ret = snd_soc_dai_set_channel_map(cpu_dai,
- user_set_tx_ch, tx_ch, 0 , 0);
+ 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,
- user_set_tx_ch, tx_ch, 0, 0);
+ 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_slimbus_2_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;
+ unsigned int num_tx_ch = 0;
+ unsigned int num_rx_ch = 0;
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+
+ num_rx_ch = params_channels(params);
+
+ pr_debug("%s: %s rx_dai_id = %d num_ch = %d\n", __func__,
+ codec_dai->name, codec_dai->id, num_rx_ch);
+
+ 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,
+ num_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,
+ num_rx_ch, rx_ch);
+ if (ret < 0) {
+ pr_err("%s: failed to set codec channel map\n",
+ __func__);
+ goto end;
+ }
+ } else {
+ num_tx_ch = params_channels(params);
+
+ pr_debug("%s: %s tx_dai_id = %d num_ch = %d\n", __func__,
+ codec_dai->name, codec_dai->id, num_tx_ch);
+
+ 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,
+ num_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,
+ num_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;
@@ -1011,8 +1098,11 @@
}
static int msm8960_startup(struct snd_pcm_substream *substream)
{
- pr_debug("%s(): substream = %s stream = %d\n", __func__,
- substream->name, substream->stream);
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+
+ pr_debug("%s(): dai_link_str_name = %s cpu_dai = %s codec_dai = %s\n",
+ __func__, rtd->dai_link->stream_name,
+ rtd->dai_link->cpu_dai_name, rtd->dai_link->codec_dai_name);
return 0;
}
@@ -1038,8 +1128,11 @@
static void msm8960_shutdown(struct snd_pcm_substream *substream)
{
- pr_debug("%s(): substream = %s stream = %d\n", __func__,
- substream->name, substream->stream);
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+
+ pr_debug("%s(): dai_link str_name = %s cpu_dai = %s codec_dai = %s\n",
+ __func__, rtd->dai_link->stream_name,
+ rtd->dai_link->cpu_dai_name, rtd->dai_link->codec_dai_name);
}
static struct snd_soc_ops msm8960_be_ops = {
@@ -1053,6 +1146,12 @@
.shutdown = msm8960_auxpcm_shutdown,
};
+static struct snd_soc_ops msm8960_slimbus_2_be_ops = {
+ .startup = msm8960_startup,
+ .hw_params = msm8960_slimbus_2_hw_params,
+ .shutdown = msm8960_shutdown,
+};
+
/* Digital audio interface glue - connects codec <---> CPU */
static struct snd_soc_dai_link msm8960_dai_common[] = {
/* FrontEnd DAI Links */
@@ -1396,16 +1495,29 @@
.be_hw_params_fixup = msm8960_slim_0_tx_be_hw_params_fixup,
.ops = &msm8960_be_ops,
},
+ /* Ultrasound TX Back End DAI Link */
{
- .name = "SLIMBUS_2 Hostless",
- .stream_name = "SLIMBUS_2 Hostless",
+ .name = "SLIMBUS_2 Hostless Capture",
+ .stream_name = "SLIMBUS_2 Hostless Capture",
.cpu_dai_name = "msm-dai-q6.16389",
.platform_name = "msm-pcm-hostless",
.codec_name = "tabla1x_codec",
.codec_dai_name = "tabla_tx2",
.ignore_suspend = 1,
.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
- .ops = &msm8960_be_ops,
+ .ops = &msm8960_slimbus_2_be_ops,
+ },
+ /* Ultrasound RX Back End DAI Link */
+ {
+ .name = "SLIMBUS_2 Hostless Playback",
+ .stream_name = "SLIMBUS_2 Hostless Playback",
+ .cpu_dai_name = "msm-dai-q6.16388",
+ .platform_name = "msm-pcm-hostless",
+ .codec_name = "tabla1x_codec",
+ .codec_dai_name = "tabla_rx3",
+ .ignore_suspend = 1,
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ops = &msm8960_slimbus_2_be_ops,
},
};
@@ -1438,16 +1550,29 @@
.be_hw_params_fixup = msm8960_slim_0_tx_be_hw_params_fixup,
.ops = &msm8960_be_ops,
},
+ /* Ultrasound TX Back End DAI Link */
{
- .name = "SLIMBUS_2 Hostless",
- .stream_name = "SLIMBUS_2 Hostless",
+ .name = "SLIMBUS_2 Hostless Capture",
+ .stream_name = "SLIMBUS_2 Hostless Capture",
.cpu_dai_name = "msm-dai-q6.16389",
.platform_name = "msm-pcm-hostless",
.codec_name = "tabla_codec",
.codec_dai_name = "tabla_tx2",
.ignore_suspend = 1,
.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
- .ops = &msm8960_be_ops,
+ .ops = &msm8960_slimbus_2_be_ops,
+ },
+ /* Ultrasound RX Back End DAI Link */
+ {
+ .name = "SLIMBUS_2 Hostless Playback",
+ .stream_name = "SLIMBUS_2 Hostless Playback",
+ .cpu_dai_name = "msm-dai-q6.16388",
+ .platform_name = "msm-pcm-hostless",
+ .codec_name = "tabla_codec",
+ .codec_dai_name = "tabla_rx3",
+ .ignore_suspend = 1,
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ops = &msm8960_slimbus_2_be_ops,
},
};