ASoC: msm: Change voice routing controls.
Change voice routing controls to contain back-end DAI and front-end
DAI information.
CRs-fixed: 304889
Signed-off-by: Neema Shetty <nshetty@codeaurora.org>
diff --git a/sound/soc/msm/msm-pcm-routing.c b/sound/soc/msm/msm-pcm-routing.c
index d262024..5fbe3ce 100644
--- a/sound/soc/msm/msm-pcm-routing.c
+++ b/sound/soc/msm/msm-pcm-routing.c
@@ -17,6 +17,7 @@
#include <linux/moduleparam.h>
#include <linux/platform_device.h>
#include <linux/bitops.h>
+#include <linux/mutex.h>
#include <sound/core.h>
#include <sound/soc.h>
#include <sound/soc-dapm.h>
@@ -35,8 +36,18 @@
u32 mixer_type; /* playback or capture */
};
+struct msm_pcm_routing_bdai_data {
+ u16 port_id; /* AFE port ID */
+ u8 active; /* track if this backend is enabled */
+ struct snd_pcm_hw_params *hw_params; /* to get freq and channel mode */
+ unsigned long fe_sessions; /* Front-end sessions */
+ unsigned long port_sessions; /* track Tx BE ports -> Rx BE */
+};
+
#define INVALID_SESSION -1
+static struct mutex routing_lock;
+
enum {
AUDIO_MIXER_PRI_I2S_RX = 0,
AUDIO_MIXER_SLIMBUS_0_RX,
@@ -84,6 +95,22 @@
INT_FM_TX,
};
+/* This array is indexed by back-end DAI ID defined in msm-pcm-routing.h
+ * If new back-end is defined, add new back-end DAI ID at the end of enum
+ */
+static struct msm_pcm_routing_bdai_data msm_bedais[MSM_BACKEND_DAI_MAX] = {
+ { PRIMARY_I2S_RX, 0, NULL, 0, 0},
+ { PRIMARY_I2S_TX, 0, NULL, 0, 0},
+ { SLIMBUS_0_RX, 0, NULL, 0, 0},
+ { SLIMBUS_0_TX, 0, NULL, 0, 0},
+ { HDMI_RX, 0, NULL, 0, 0},
+ { INT_BT_SCO_RX, 0, NULL, 0, 0},
+ { INT_BT_SCO_TX, 0, NULL, 0, 0},
+ { INT_FM_RX, 0, NULL, 0, 0},
+ { INT_FM_TX, 0, NULL, 0, 0},
+};
+
+
/* Track ASM playback & capture sessions of DAI */
static int fe_dai_map[MSM_FRONTEND_DAI_MAX][2] = {
/* MULTIMEDIA1 */
@@ -108,20 +135,6 @@
/* AUDIO_MIXER_INT_FM_RX */
{INT_FM_RX, 0, SNDRV_PCM_STREAM_PLAYBACK},
};
-static struct voice_mixer_data voice_mixers[VOICE_MIXER_MAX] = {
- /* VOICE_MIXER_PRI_I2S_RX */
- {VOICE_PRI_I2S_RX, 0, SNDRV_PCM_STREAM_PLAYBACK},
- /* VOICE_MIXER_SLIMBUS_0_RX */
- {VOICE_SLIMBUS_0_RX, 0, SNDRV_PCM_STREAM_PLAYBACK},
- /* VOICE_MIXER_PRI_I2S_TX */
- {VOICE_PRI_I2S_TX, 0, SNDRV_PCM_STREAM_CAPTURE},
- /* VOICE_MIXER_SLIMBUS_0_TX */
- {VOICE_SLIMBUS_0_TX, 0, SNDRV_PCM_STREAM_CAPTURE},
- /* VOICE_MIXER_INT_BT_SCO_RX */
- {VOICE_INT_BT_SCO_RX, 0, SNDRV_PCM_STREAM_PLAYBACK},
- /* VOICE_MIXER_INT_BT_SCO_TX */
- {VOICE_INT_BT_SCO_TX, 0, SNDRV_PCM_STREAM_CAPTURE}
-};
/* Reuse audio_mixer_data struct but ignore mixer type field
* unless there is use case for RX -> TX
@@ -255,36 +268,35 @@
return 1;
}
-static void msm_pcm_routing_process_voice(u16 reg, u16 val, u16 invert, int set)
+static void msm_pcm_routing_process_voice(u16 reg, u16 val, int set)
{
-
- u32 port_map_id;
u16 session_id = 0;
- pr_debug("%s: reg %x val %x invert %x set %x\n",
- __func__, reg, val, invert, set);
+ pr_debug("%s: reg %x val %x set %x\n", __func__, reg, val, set);
- if (invert == MSM_FRONTEND_DAI_CS_VOICE)
+ if (val == MSM_FRONTEND_DAI_CS_VOICE)
session_id = voc_get_session_id(VOICE_SESSION_NAME);
else
session_id = voc_get_session_id(VOIP_SESSION_NAME);
pr_debug("%s: FE DAI 0x%x session_id 0x%x\n",
- __func__, invert, session_id);
+ __func__, val, session_id);
- port_map_id = voice_mixers[reg].port_id;
+ mutex_lock(&routing_lock);
if (set)
- set_bit(val, &voice_mixers[reg].dai_sessions);
+ set_bit(val, &msm_bedais[reg].fe_sessions);
else
- clear_bit(val, &voice_mixers[reg].dai_sessions);
+ clear_bit(val, &msm_bedais[reg].fe_sessions);
- if (voice_mixers[reg].mixer_type == SNDRV_PCM_STREAM_PLAYBACK) {
+ mutex_unlock(&routing_lock);
+
+ if (afe_get_port_type(msm_bedais[reg].port_id) ==
+ MSM_AFE_PORT_TYPE_RX) {
voc_set_route_flag(session_id, RX_PATH, set);
if (set) {
voc_set_rxtx_port(session_id,
- bedai_port_map[port_map_id],
- DEV_RX);
+ msm_bedais[reg].port_id, DEV_RX);
if (voc_get_route_flag(session_id, RX_PATH) &&
voc_get_route_flag(session_id, TX_PATH))
@@ -296,8 +308,7 @@
voc_set_route_flag(session_id, TX_PATH, set);
if (set) {
voc_set_rxtx_port(session_id,
- bedai_port_map[port_map_id],
- DEV_TX);
+ msm_bedais[reg].port_id, DEV_TX);
if (voc_get_route_flag(session_id, RX_PATH) &&
voc_get_route_flag(session_id, TX_PATH))
@@ -314,11 +325,15 @@
struct soc_mixer_control *mc =
(struct soc_mixer_control *)kcontrol->private_value;
- if (test_bit(mc->shift, &voice_mixers[mc->reg].dai_sessions))
+ mutex_lock(&routing_lock);
+
+ if (test_bit(mc->shift, &msm_bedais[mc->reg].fe_sessions))
ucontrol->value.integer.value[0] = 1;
else
ucontrol->value.integer.value[0] = 0;
+ mutex_unlock(&routing_lock);
+
pr_debug("%s: reg %x shift %x val %ld\n", __func__, mc->reg, mc->shift,
ucontrol->value.integer.value[0]);
@@ -334,12 +349,10 @@
(struct soc_mixer_control *)kcontrol->private_value;
if (ucontrol->value.integer.value[0]) {
- msm_pcm_routing_process_voice(mc->reg, mc->shift,
- mc->invert, 1);
+ msm_pcm_routing_process_voice(mc->reg, mc->shift, 1);
snd_soc_dapm_mixer_update_power(widget, kcontrol, 1);
} else {
- msm_pcm_routing_process_voice(mc->reg, mc->shift,
- mc->invert, 0);
+ msm_pcm_routing_process_voice(mc->reg, mc->shift, 0);
snd_soc_dapm_mixer_update_power(widget, kcontrol, 0);
}
@@ -512,54 +525,54 @@
};
static const struct snd_kcontrol_new pri_rx_voice_mixer_controls[] = {
- SOC_SINGLE_EXT("CSVoice", VOICE_MIXER_PRI_I2S_RX,
- MSM_FRONTEND_DAI_CS_VOICE, 1, MSM_FRONTEND_DAI_CS_VOICE,
- msm_routing_get_voice_mixer, msm_routing_put_voice_mixer),
- SOC_SINGLE_EXT("Voip", VOICE_MIXER_PRI_I2S_RX ,
- MSM_FRONTEND_DAI_VOIP, 1, MSM_FRONTEND_DAI_VOIP,
- msm_routing_get_voice_mixer, msm_routing_put_voice_mixer),
+ SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_PRI_I2S_RX,
+ MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
+ msm_routing_put_voice_mixer),
+ SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_PRI_I2S_RX,
+ MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
+ msm_routing_put_voice_mixer),
};
static const struct snd_kcontrol_new slimbus_rx_voice_mixer_controls[] = {
- SOC_SINGLE_EXT("CSVoice", VOICE_MIXER_SLIMBUS_0_RX,
- MSM_FRONTEND_DAI_CS_VOICE, 1, MSM_FRONTEND_DAI_CS_VOICE,
- msm_routing_get_voice_mixer, msm_routing_put_voice_mixer),
- SOC_SINGLE_EXT("Voip", VOICE_MIXER_SLIMBUS_0_RX ,
- MSM_FRONTEND_DAI_VOIP, 1, MSM_FRONTEND_DAI_VOIP,
- msm_routing_get_voice_mixer, msm_routing_put_voice_mixer),
+ SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_SLIMBUS_0_RX,
+ MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
+ msm_routing_put_voice_mixer),
+ SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_SLIMBUS_0_RX ,
+ MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
+ msm_routing_put_voice_mixer),
};
static const struct snd_kcontrol_new bt_sco_rx_voice_mixer_controls[] = {
- SOC_SINGLE_EXT("CSVoice", VOICE_MIXER_INT_BT_SCO_RX,
- MSM_FRONTEND_DAI_CS_VOICE, 1, MSM_FRONTEND_DAI_CS_VOICE,
- msm_routing_get_voice_mixer, msm_routing_put_voice_mixer),
- SOC_SINGLE_EXT("Voip", VOICE_MIXER_INT_BT_SCO_RX ,
- MSM_FRONTEND_DAI_VOIP, 1, MSM_FRONTEND_DAI_VOIP,
- msm_routing_get_voice_mixer, msm_routing_put_voice_mixer),
+ SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_INT_BT_SCO_RX,
+ MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
+ msm_routing_put_voice_mixer),
+ SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_INT_BT_SCO_RX ,
+ MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
+ msm_routing_put_voice_mixer),
};
static const struct snd_kcontrol_new tx_voice_mixer_controls[] = {
- SOC_SINGLE_EXT("PRI_TX_Voice", VOICE_MIXER_PRI_I2S_TX,
- MSM_BACKEND_DAI_PRI_I2S_TX, 1, MSM_FRONTEND_DAI_CS_VOICE,
- msm_routing_get_voice_mixer, msm_routing_put_voice_mixer),
- SOC_SINGLE_EXT("SLIM_0_TX_Voice", VOICE_MIXER_SLIMBUS_0_TX,
- MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, MSM_FRONTEND_DAI_CS_VOICE,
- msm_routing_get_voice_mixer, msm_routing_put_voice_mixer),
- SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX_Voice", VOICE_MIXER_INT_BT_SCO_TX,
- MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, MSM_FRONTEND_DAI_CS_VOICE,
+ SOC_SINGLE_EXT("PRI_TX_Voice", MSM_BACKEND_DAI_PRI_I2S_TX,
+ MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
+ msm_routing_put_voice_mixer),
+ SOC_SINGLE_EXT("SLIM_0_TX_Voice", MSM_BACKEND_DAI_SLIMBUS_0_TX,
+ MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
+ msm_routing_put_voice_mixer),
+ SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX_Voice",
+ MSM_BACKEND_DAI_INT_BT_SCO_TX, MSM_FRONTEND_DAI_CS_VOICE, 1, 0,
msm_routing_get_voice_mixer, msm_routing_put_voice_mixer),
};
static const struct snd_kcontrol_new tx_voip_mixer_controls[] = {
- SOC_SINGLE_EXT("PRI_TX_Voip", VOICE_MIXER_PRI_I2S_TX,
- MSM_BACKEND_DAI_PRI_I2S_TX, 1, MSM_FRONTEND_DAI_VOIP,
- msm_routing_get_voice_mixer, msm_routing_put_voice_mixer),
- SOC_SINGLE_EXT("SLIM_0_TX_Voip", VOICE_MIXER_SLIMBUS_0_TX,
- MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, MSM_FRONTEND_DAI_VOIP,
- msm_routing_get_voice_mixer, msm_routing_put_voice_mixer),
- SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX_Voip", VOICE_MIXER_INT_BT_SCO_TX,
- MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, MSM_FRONTEND_DAI_VOIP,
- msm_routing_get_voice_mixer, msm_routing_put_voice_mixer),
+ SOC_SINGLE_EXT("PRI_TX_Voip", MSM_BACKEND_DAI_PRI_I2S_TX,
+ MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
+ msm_routing_put_voice_mixer),
+ SOC_SINGLE_EXT("SLIM_0_TX_Voip", MSM_BACKEND_DAI_SLIMBUS_0_TX,
+ MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
+ msm_routing_put_voice_mixer),
+ SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX_Voip", MSM_BACKEND_DAI_INT_BT_SCO_TX,
+ MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
+ msm_routing_put_voice_mixer),
};
static const struct snd_kcontrol_new sbus_0_rx_port_mixer_controls[] = {
@@ -791,6 +804,7 @@
static int __init msm_soc_routing_platform_init(void)
{
+ mutex_init(&routing_lock);
return platform_driver_register(&msm_routing_pcm_driver);
}
module_init(msm_soc_routing_platform_init);