From 6df96093b32d24047e97a7e0e1d196fa2483dda1 Mon Sep 17 00:00:00 2001 From: Revathi Uddaraju Date: Wed, 19 Oct 2016 14:12:00 +0530 Subject: [PATCH] ASoC: msm: qdsp6v2: Add support to connect LSM to ADM LSM will connect to ADM to apply preprocessing and improve detection performance. LSM can also directly connect to AFE similar to the existing mechanism. MAD polling will be disabled in case of LSM connects to ADM. Add EC reference end channel, bit format and sample rate control to configure far end params for Echo Cancellation. Change-Id: I4684ae346884d656e95350b7a63929b91a843512 Signed-off-by: Chaithanya Krishna Bacharaju Signed-off-by: Revathi Uddaraju --- include/sound/apr_audio-v2.h | 7 + include/sound/q6adm-v2.h | 4 +- include/sound/q6lsm.h | 31 +- sound/soc/msm/qdsp6v2/msm-lsm-client.c | 89 +- sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c | 1224 ++++++++++++++------ sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h | 9 +- sound/soc/msm/qdsp6v2/q6adm.c | 63 +- sound/soc/msm/qdsp6v2/q6asm.c | 18 +- sound/soc/msm/qdsp6v2/q6lsm.c | 157 ++- 9 files changed, 1170 insertions(+), 432 deletions(-) diff --git a/include/sound/apr_audio-v2.h b/include/sound/apr_audio-v2.h index a047a33334d2..31846849f483 100644 --- a/include/sound/apr_audio-v2.h +++ b/include/sound/apr_audio-v2.h @@ -42,6 +42,8 @@ struct param_outband { #define ADM_MATRIX_ID_AUDIO_TX 1 #define ADM_MATRIX_ID_COMPRESSED_AUDIO_RX 2 + +#define ADM_MATRIX_ID_LISTEN_TX 4 /* Enumeration for an audio Tx matrix ID.*/ #define ADM_MATRIX_ID_AUDIOX 1 @@ -9056,6 +9058,10 @@ struct asm_aptx_dec_fmt_blk_v2 { #define LSM_PARAM_ID_LAB_ENABLE (0x00012C09) #define LSM_PARAM_ID_LAB_CONFIG (0x00012C0A) #define LSM_MODULE_ID_FRAMEWORK (0x00012C0E) +#define LSM_PARAM_ID_SWMAD_CFG (0x00012C18) +#define LSM_PARAM_ID_SWMAD_MODEL (0x00012C19) +#define LSM_PARAM_ID_SWMAD_ENABLE (0x00012C1A) +#define LSM_PARAM_ID_POLLING_ENABLE (0x00012C1B) /* HW MAD specific */ #define AFE_MODULE_HW_MAD (0x00010230) @@ -10172,6 +10178,7 @@ enum { COMPRESSED_PASSTHROUGH, COMPRESSED_PASSTHROUGH_CONVERT, COMPRESSED_PASSTHROUGH_DSD, + LISTEN, }; #define AUDPROC_MODULE_ID_COMPRESSED_MUTE 0x00010770 diff --git a/include/sound/q6adm-v2.h b/include/sound/q6adm-v2.h index 8c7da3b9838d..25376315dd20 100644 --- a/include/sound/q6adm-v2.h +++ b/include/sound/q6adm-v2.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -96,7 +96,7 @@ int adm_unmap_rtac_block(uint32_t *mem_map_handle); int adm_close(int port, int topology, int perf_mode); int adm_matrix_map(int path, struct route_payload payload_map, - int perf_mode); + int perf_mode, uint32_t passthr_mode); int adm_connect_afe_port(int mode, int session_id, int port_id); diff --git a/include/sound/q6lsm.h b/include/sound/q6lsm.h index 92aa0b78f07d..7ed3dcbc033f 100644 --- a/include/sound/q6lsm.h +++ b/include/sound/q6lsm.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2015, Linux Foundation. All rights reserved. + * Copyright (c) 2013-2016, Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -21,6 +21,8 @@ #define MAX_NUM_CONFIDENCE 20 +#define ADM_LSM_PORT_ID 0xADCB + typedef void (*lsm_app_cb)(uint32_t opcode, uint32_t token, uint32_t *payload, void *priv); @@ -81,6 +83,9 @@ struct lsm_client { struct lsm_lab_buffer *lab_buffer; struct lsm_lab_hw_params hw_params; bool use_topology; + int session_state; + bool poll_enable; + int perf_mode; }; struct lsm_stream_cmd_open_tx { @@ -134,6 +139,12 @@ struct lsm_param_connect_to_port { uint16_t reserved; } __packed; +struct lsm_param_poll_enable { + struct lsm_param_payload_common common; + uint32_t minor_version; + /* indicates to voice wakeup that HW MAD/SW polling is enabled or not */ + uint32_t polling_enable; +} __packed; /* * This param cannot be sent in this format. @@ -163,11 +174,22 @@ struct lsm_cmd_set_params_conf { struct lsm_param_min_confidence_levels conf_payload; } __packed; -struct lsm_cmd_set_opmode_connectport { +struct lsm_cmd_set_params_opmode { struct apr_hdr msg_hdr; struct lsm_set_params_hdr params_hdr; - struct lsm_param_connect_to_port connect_to_port; - struct lsm_param_op_mode op_mode; + struct lsm_param_op_mode op_mode; +} __packed; + +struct lsm_cmd_set_connectport { + struct apr_hdr msg_hdr; + struct lsm_set_params_hdr params_hdr; + struct lsm_param_connect_to_port connect_to_port; +} __packed; + +struct lsm_cmd_poll_enable { + struct apr_hdr msg_hdr; + struct lsm_set_params_hdr params_hdr; + struct lsm_param_poll_enable poll_enable; } __packed; struct lsm_param_epd_thres { @@ -278,4 +300,5 @@ int q6lsm_set_one_param(struct lsm_client *client, void q6lsm_sm_set_param_data(struct lsm_client *client, struct lsm_params_info *p_info, size_t *offset); +int q6lsm_set_port_connected(struct lsm_client *client); #endif /* __Q6LSM_H__ */ diff --git a/sound/soc/msm/qdsp6v2/msm-lsm-client.c b/sound/soc/msm/qdsp6v2/msm-lsm-client.c index 5c54257a0793..8e5e8a1e1fdb 100644 --- a/sound/soc/msm/qdsp6v2/msm-lsm-client.c +++ b/sound/soc/msm/qdsp6v2/msm-lsm-client.c @@ -88,6 +88,11 @@ struct lsm_priv { int dma_write; }; +enum { /* lsm session states */ + IDLE = 0, + RUNNING, +}; + static int msm_lsm_queue_lab_buffer(struct lsm_priv *prtd, int i) { int rc = 0; @@ -641,6 +646,54 @@ err_ret: return rc; } +static int msm_lsm_set_poll_enable(struct snd_pcm_substream *substream, + struct lsm_params_info *p_info) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct lsm_priv *prtd = runtime->private_data; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_lsm_poll_enable poll_enable; + int rc = 0; + + if (p_info->param_size != sizeof(poll_enable)) { + dev_err(rtd->dev, + "%s: Invalid param_size %d\n", + __func__, p_info->param_size); + rc = -EINVAL; + goto done; + } + + if (copy_from_user(&poll_enable, p_info->param_data, + sizeof(poll_enable))) { + dev_err(rtd->dev, + "%s: copy_from_user failed, size = %zd\n", + __func__, sizeof(poll_enable)); + rc = -EFAULT; + goto done; + } + + if (prtd->lsm_client->poll_enable == poll_enable.poll_en) { + dev_dbg(rtd->dev, + "%s: Polling for session %d already %s\n", + __func__, prtd->lsm_client->session, + (poll_enable.poll_en ? "enabled" : "disabled")); + rc = 0; + goto done; + } + + rc = q6lsm_set_one_param(prtd->lsm_client, p_info, + &poll_enable, LSM_POLLING_ENABLE); + if (!rc) { + prtd->lsm_client->poll_enable = poll_enable.poll_en; + } else { + dev_err(rtd->dev, + "%s: Failed to set poll enable, err = %d\n", + __func__, rc); + } +done: + return rc; +} + static int msm_lsm_process_params(struct snd_pcm_substream *substream, struct snd_lsm_module_params *p_data, void *params) @@ -681,6 +734,9 @@ static int msm_lsm_process_params(struct snd_pcm_substream *substream, case LSM_CUSTOM_PARAMS: rc = msm_lsm_set_custom(substream, p_info); break; + case LSM_POLLING_ENABLE: + rc = msm_lsm_set_poll_enable(substream, p_info); + break; default: dev_err(rtd->dev, "%s: Invalid param_type %d\n", @@ -1035,6 +1091,12 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream, prtd->lsm_client->lab_started = false; } break; + + case SNDRV_LSM_SET_PORT: + dev_dbg(rtd->dev, "%s: set LSM port\n", __func__); + rc = q6lsm_set_port_connected(prtd->lsm_client); + break; + default: dev_dbg(rtd->dev, "%s: Falling into default snd_lib_ioctl cmd 0x%x\n", @@ -1640,6 +1702,10 @@ static int msm_lsm_open(struct snd_pcm_substream *substream) return -ENOMEM; } prtd->lsm_client->opened = false; + prtd->lsm_client->session_state = IDLE; + prtd->lsm_client->poll_enable = true; + prtd->lsm_client->perf_mode = 0; + return 0; } @@ -1648,6 +1714,7 @@ static int msm_lsm_prepare(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime = substream->runtime; struct lsm_priv *prtd = runtime->private_data; struct snd_soc_pcm_runtime *rtd; + int ret = 0; if (!substream->private_data) { pr_err("%s: Invalid private_data", __func__); @@ -1661,9 +1728,26 @@ static int msm_lsm_prepare(struct snd_pcm_substream *substream) "%s: LSM client data ptr is NULL\n", __func__); return -EINVAL; } + + if (prtd->lsm_client->session_state == IDLE) { + ret = msm_pcm_routing_reg_phy_compr_stream( + rtd->dai_link->be_id, + prtd->lsm_client->perf_mode, + prtd->lsm_client->session, + SNDRV_PCM_STREAM_CAPTURE, + LISTEN); + if (ret) { + dev_err(rtd->dev, + "%s: register phy compr stream failed %d\n", + __func__, ret); + return ret; + } + } + + prtd->lsm_client->session_state = RUNNING; prtd->lsm_client->started = false; runtime->private_data = prtd; - return 0; + return ret; } static int msm_lsm_close(struct snd_pcm_substream *substream) @@ -1712,6 +1796,9 @@ static int msm_lsm_close(struct snd_pcm_substream *substream) __func__); } + msm_pcm_routing_dereg_phy_stream(rtd->dai_link->be_id, + SNDRV_PCM_STREAM_CAPTURE); + if (prtd->lsm_client->opened) { q6lsm_close(prtd->lsm_client); prtd->lsm_client->opened = false; diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c index a62420a23789..f7218f5ea786 100644 --- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c +++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c @@ -70,9 +70,12 @@ static int tert_mi2s_switch_enable; static int quat_mi2s_switch_enable; static int fm_pcmrx_switch_enable; static int usb_switch_enable; -static int lsm_mux_slim_port; +static int lsm_port_index; static int slim0_rx_aanc_fb_port; static int msm_route_ec_ref_rx; +static int msm_ec_ref_ch = 4; +static int msm_ec_ref_bit_format = SNDRV_PCM_FORMAT_S16_LE; +static int msm_ec_ref_sampling_rate = 48000; static uint32_t voc_session_id = ALL_SESSION_VSID; static int msm_route_ext_ec_ref; static bool is_custom_stereo_on; @@ -86,6 +89,8 @@ enum { MADSWAUDIO, }; +#define ADM_LSM_PORT_INDEX 9 + #define SLIMBUS_0_TX_TEXT "SLIMBUS_0_TX" #define SLIMBUS_1_TX_TEXT "SLIMBUS_1_TX" #define SLIMBUS_2_TX_TEXT "SLIMBUS_2_TX" @@ -94,12 +99,14 @@ enum { #define SLIMBUS_TX_VI_TEXT "SLIMBUS_TX_VI" #define SLIMBUS_5_TX_TEXT "SLIMBUS_5_TX" #define TERT_MI2S_TX_TEXT "TERT_MI2S_TX" +#define QUAT_MI2S_TX_TEXT "QUAT_MI2S_TX" +#define ADM_LSM_TX_TEXT "ADM_LSM_TX" #define LSM_FUNCTION_TEXT "LSM Function" -static const char * const mad_audio_mux_text[] = { +static const char * const lsm_port_text[] = { "None", SLIMBUS_0_TX_TEXT, SLIMBUS_1_TX_TEXT, SLIMBUS_2_TX_TEXT, - SLIMBUS_3_TX_TEXT, SLIMBUS_4_TX_TEXT, SLIMBUS_TX_VI_TEXT, - SLIMBUS_5_TX_TEXT, TERT_MI2S_TX_TEXT + SLIMBUS_3_TX_TEXT, SLIMBUS_4_TX_TEXT, SLIMBUS_5_TX_TEXT, + TERT_MI2S_TX_TEXT, QUAT_MI2S_TX_TEXT, ADM_LSM_TX_TEXT }; struct msm_pcm_route_bdai_pp_params { @@ -268,254 +275,262 @@ static void msm_pcm_routng_cfg_matrix_map_pp(struct route_payload payload, #define SLIMBUS_EXTPROC_RX AFE_PORT_INVALID struct msm_pcm_routing_bdai_data msm_bedais[MSM_BACKEND_DAI_MAX] = { - { PRIMARY_I2S_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_PRI_I2S_RX}, - { PRIMARY_I2S_TX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_PRI_I2S_TX}, - { SLIMBUS_0_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_0_RX}, - { SLIMBUS_0_TX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_0_TX}, - { HDMI_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_HDMI}, - { INT_BT_SCO_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_INT_BT_SCO_RX}, - { INT_BT_SCO_TX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_INT_BT_SCO_TX}, - { INT_FM_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_INT_FM_RX}, - { INT_FM_TX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_INT_FM_TX}, - { RT_PROXY_PORT_001_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_AFE_PCM_RX}, - { RT_PROXY_PORT_001_TX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_AFE_PCM_TX}, - { AFE_PORT_ID_PRIMARY_PCM_RX, 0, 0, {0}, 0, 0, 0, 0, 0, + { PRIMARY_I2S_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_PRI_I2S_RX}, + { PRIMARY_I2S_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_PRI_I2S_TX}, + { SLIMBUS_0_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_0_RX}, + { SLIMBUS_0_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_0_TX}, + { HDMI_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_HDMI}, + { INT_BT_SCO_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_INT_BT_SCO_RX}, + { INT_BT_SCO_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_INT_BT_SCO_TX}, + { INT_FM_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_INT_FM_RX}, + { INT_FM_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_INT_FM_TX}, + { RT_PROXY_PORT_001_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, + LPASS_BE_AFE_PCM_RX}, + { RT_PROXY_PORT_001_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, + LPASS_BE_AFE_PCM_TX}, + { AFE_PORT_ID_PRIMARY_PCM_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_AUXPCM_RX}, - { AFE_PORT_ID_PRIMARY_PCM_TX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_PRIMARY_PCM_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_AUXPCM_TX}, - { VOICE_PLAYBACK_TX, 0, 0, {0}, 0, 0, 0, 0, 0, + { VOICE_PLAYBACK_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_VOICE_PLAYBACK_TX}, - { VOICE2_PLAYBACK_TX, 0, 0, {0}, 0, 0, 0, 0, 0, + { VOICE2_PLAYBACK_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_VOICE2_PLAYBACK_TX}, - { VOICE_RECORD_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_INCALL_RECORD_RX}, - { VOICE_RECORD_TX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_INCALL_RECORD_TX}, - { MI2S_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_MI2S_RX}, - { MI2S_TX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_MI2S_TX}, - { SECONDARY_I2S_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SEC_I2S_RX}, - { SLIMBUS_1_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_1_RX}, - { SLIMBUS_1_TX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_1_TX}, - { SLIMBUS_2_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_2_RX}, - { SLIMBUS_2_TX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_2_TX}, - { SLIMBUS_3_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_3_RX}, - { SLIMBUS_3_TX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_3_TX}, - { SLIMBUS_4_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_4_RX}, - { SLIMBUS_4_TX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_4_TX}, - { SLIMBUS_5_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_5_RX}, - { SLIMBUS_5_TX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_5_TX}, - { SLIMBUS_6_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_6_RX}, - { SLIMBUS_6_TX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_6_TX}, - { SLIMBUS_7_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_7_RX}, - { SLIMBUS_7_TX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_7_TX}, - { SLIMBUS_8_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_8_RX}, - { SLIMBUS_8_TX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_8_TX}, - { SLIMBUS_EXTPROC_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_STUB_RX}, - { SLIMBUS_EXTPROC_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_STUB_TX}, - { SLIMBUS_EXTPROC_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_STUB_1_TX}, - { AFE_PORT_ID_QUATERNARY_MI2S_RX, 0, 0, {0}, 0, 0, 0, 0, 0, + { VOICE_RECORD_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, + LPASS_BE_INCALL_RECORD_RX}, + { VOICE_RECORD_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, + LPASS_BE_INCALL_RECORD_TX}, + { MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_MI2S_RX}, + { MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_MI2S_TX}, + { SECONDARY_I2S_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SEC_I2S_RX}, + { SLIMBUS_1_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_1_RX}, + { SLIMBUS_1_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_1_TX}, + { SLIMBUS_2_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_2_RX}, + { SLIMBUS_2_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_2_TX}, + { SLIMBUS_3_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_3_RX}, + { SLIMBUS_3_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_3_TX}, + { SLIMBUS_4_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_4_RX}, + { SLIMBUS_4_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_4_TX}, + { SLIMBUS_5_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_5_RX}, + { SLIMBUS_5_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_5_TX}, + { SLIMBUS_6_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_6_RX}, + { SLIMBUS_6_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_6_TX}, + { SLIMBUS_7_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_7_RX}, + { SLIMBUS_7_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_7_TX}, + { SLIMBUS_8_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_8_RX}, + { SLIMBUS_8_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_8_TX}, + { SLIMBUS_EXTPROC_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_STUB_RX}, + { SLIMBUS_EXTPROC_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_STUB_TX}, + { SLIMBUS_EXTPROC_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_STUB_1_TX}, + { AFE_PORT_ID_QUATERNARY_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_QUAT_MI2S_RX}, - { AFE_PORT_ID_QUATERNARY_MI2S_TX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_QUATERNARY_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_QUAT_MI2S_TX}, - { AFE_PORT_ID_SECONDARY_MI2S_RX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_SECONDARY_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SEC_MI2S_RX}, - { AFE_PORT_ID_SECONDARY_MI2S_TX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_SECONDARY_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SEC_MI2S_TX}, - { AFE_PORT_ID_PRIMARY_MI2S_RX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_PRIMARY_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_PRI_MI2S_RX}, - { AFE_PORT_ID_PRIMARY_MI2S_TX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_PRIMARY_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_PRI_MI2S_TX}, - { AFE_PORT_ID_TERTIARY_MI2S_RX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_TERTIARY_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_TERT_MI2S_RX}, - { AFE_PORT_ID_TERTIARY_MI2S_TX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_TERTIARY_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_TERT_MI2S_TX}, - { AUDIO_PORT_ID_I2S_RX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AUDIO_PORT_ID_I2S_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_AUDIO_I2S_RX}, - { AFE_PORT_ID_SECONDARY_PCM_RX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_SECONDARY_PCM_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SEC_AUXPCM_RX}, - { AFE_PORT_ID_SECONDARY_PCM_TX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_SECONDARY_PCM_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SEC_AUXPCM_TX}, - { AFE_PORT_ID_SPDIF_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SPDIF_RX}, - { AFE_PORT_ID_SECONDARY_MI2S_RX_SD1, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_SPDIF_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SPDIF_RX}, + { AFE_PORT_ID_SECONDARY_MI2S_RX_SD1, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SEC_MI2S_RX_SD1}, - { AFE_PORT_ID_QUINARY_MI2S_RX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_QUINARY_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_QUIN_MI2S_RX}, - { AFE_PORT_ID_QUINARY_MI2S_TX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_QUINARY_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_QUIN_MI2S_TX}, - { AFE_PORT_ID_SENARY_MI2S_TX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_SENARY_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SENARY_MI2S_TX}, - { AFE_PORT_ID_PRIMARY_TDM_RX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_PRIMARY_TDM_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_PRI_TDM_RX_0}, - { AFE_PORT_ID_PRIMARY_TDM_TX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_PRIMARY_TDM_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_PRI_TDM_TX_0}, - { AFE_PORT_ID_PRIMARY_TDM_RX_1, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_PRIMARY_TDM_RX_1, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_PRI_TDM_RX_1}, - { AFE_PORT_ID_PRIMARY_TDM_TX_1, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_PRIMARY_TDM_TX_1, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_PRI_TDM_TX_1}, - { AFE_PORT_ID_PRIMARY_TDM_RX_2, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_PRIMARY_TDM_RX_2, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_PRI_TDM_RX_2}, - { AFE_PORT_ID_PRIMARY_TDM_TX_2, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_PRIMARY_TDM_TX_2, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_PRI_TDM_TX_2}, - { AFE_PORT_ID_PRIMARY_TDM_RX_3, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_PRIMARY_TDM_RX_3, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_PRI_TDM_RX_3}, - { AFE_PORT_ID_PRIMARY_TDM_TX_3, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_PRIMARY_TDM_TX_3, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_PRI_TDM_TX_3}, - { AFE_PORT_ID_PRIMARY_TDM_RX_4, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_PRIMARY_TDM_RX_4, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_PRI_TDM_RX_4}, - { AFE_PORT_ID_PRIMARY_TDM_TX_4, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_PRIMARY_TDM_TX_4, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_PRI_TDM_TX_4}, - { AFE_PORT_ID_PRIMARY_TDM_RX_5, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_PRIMARY_TDM_RX_5, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_PRI_TDM_RX_5}, - { AFE_PORT_ID_PRIMARY_TDM_TX_5, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_PRIMARY_TDM_TX_5, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_PRI_TDM_TX_5}, - { AFE_PORT_ID_PRIMARY_TDM_RX_6, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_PRIMARY_TDM_RX_6, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_PRI_TDM_RX_6}, - { AFE_PORT_ID_PRIMARY_TDM_TX_6, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_PRIMARY_TDM_TX_6, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_PRI_TDM_TX_6}, - { AFE_PORT_ID_PRIMARY_TDM_RX_7, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_PRIMARY_TDM_RX_7, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_PRI_TDM_RX_7}, - { AFE_PORT_ID_PRIMARY_TDM_TX_7, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_PRIMARY_TDM_TX_7, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_PRI_TDM_TX_7}, - { AFE_PORT_ID_SECONDARY_TDM_RX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_SECONDARY_TDM_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SEC_TDM_RX_0}, - { AFE_PORT_ID_SECONDARY_TDM_TX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_SECONDARY_TDM_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SEC_TDM_TX_0}, - { AFE_PORT_ID_SECONDARY_TDM_RX_1, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_SECONDARY_TDM_RX_1, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SEC_TDM_RX_1}, - { AFE_PORT_ID_SECONDARY_TDM_TX_1, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_SECONDARY_TDM_TX_1, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SEC_TDM_TX_1}, - { AFE_PORT_ID_SECONDARY_TDM_RX_2, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_SECONDARY_TDM_RX_2, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SEC_TDM_RX_2}, - { AFE_PORT_ID_SECONDARY_TDM_TX_2, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_SECONDARY_TDM_TX_2, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SEC_TDM_TX_2}, - { AFE_PORT_ID_SECONDARY_TDM_RX_3, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_SECONDARY_TDM_RX_3, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SEC_TDM_RX_3}, - { AFE_PORT_ID_SECONDARY_TDM_TX_3, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_SECONDARY_TDM_TX_3, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SEC_TDM_TX_3}, - { AFE_PORT_ID_SECONDARY_TDM_RX_4, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_SECONDARY_TDM_RX_4, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SEC_TDM_RX_4}, - { AFE_PORT_ID_SECONDARY_TDM_TX_4, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_SECONDARY_TDM_TX_4, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SEC_TDM_TX_4}, - { AFE_PORT_ID_SECONDARY_TDM_RX_5, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_SECONDARY_TDM_RX_5, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SEC_TDM_RX_5}, - { AFE_PORT_ID_SECONDARY_TDM_TX_5, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_SECONDARY_TDM_TX_5, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SEC_TDM_TX_5}, - { AFE_PORT_ID_SECONDARY_TDM_RX_6, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_SECONDARY_TDM_RX_6, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SEC_TDM_RX_6}, - { AFE_PORT_ID_SECONDARY_TDM_TX_6, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_SECONDARY_TDM_TX_6, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SEC_TDM_TX_6}, - { AFE_PORT_ID_SECONDARY_TDM_RX_7, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_SECONDARY_TDM_RX_7, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SEC_TDM_RX_7}, - { AFE_PORT_ID_SECONDARY_TDM_TX_7, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_SECONDARY_TDM_TX_7, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SEC_TDM_TX_7}, - { AFE_PORT_ID_TERTIARY_TDM_RX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_TERTIARY_TDM_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_TERT_TDM_RX_0}, - { AFE_PORT_ID_TERTIARY_TDM_TX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_TERTIARY_TDM_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_TERT_TDM_TX_0}, - { AFE_PORT_ID_TERTIARY_TDM_RX_1, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_TERTIARY_TDM_RX_1, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_TERT_TDM_RX_1}, - { AFE_PORT_ID_TERTIARY_TDM_TX_1, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_TERTIARY_TDM_TX_1, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_TERT_TDM_TX_1}, - { AFE_PORT_ID_TERTIARY_TDM_RX_2, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_TERTIARY_TDM_RX_2, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_TERT_TDM_RX_2}, - { AFE_PORT_ID_TERTIARY_TDM_TX_2, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_TERTIARY_TDM_TX_2, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_TERT_TDM_TX_2}, - { AFE_PORT_ID_TERTIARY_TDM_RX_3, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_TERTIARY_TDM_RX_3, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_TERT_TDM_RX_3}, - { AFE_PORT_ID_TERTIARY_TDM_TX_3, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_TERTIARY_TDM_TX_3, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_TERT_TDM_TX_3}, - { AFE_PORT_ID_TERTIARY_TDM_RX_4, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_TERTIARY_TDM_RX_4, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_TERT_TDM_RX_4}, - { AFE_PORT_ID_TERTIARY_TDM_TX_4, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_TERTIARY_TDM_TX_4, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_TERT_TDM_TX_4}, - { AFE_PORT_ID_TERTIARY_TDM_RX_5, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_TERTIARY_TDM_RX_5, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_TERT_TDM_RX_5}, - { AFE_PORT_ID_TERTIARY_TDM_TX_5, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_TERTIARY_TDM_TX_5, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_TERT_TDM_TX_5}, - { AFE_PORT_ID_TERTIARY_TDM_RX_6, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_TERTIARY_TDM_RX_6, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_TERT_TDM_RX_6}, - { AFE_PORT_ID_TERTIARY_TDM_TX_6, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_TERTIARY_TDM_TX_6, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_TERT_TDM_TX_6}, - { AFE_PORT_ID_TERTIARY_TDM_RX_7, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_TERTIARY_TDM_RX_7, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_TERT_TDM_RX_7}, - { AFE_PORT_ID_TERTIARY_TDM_TX_7, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_TERTIARY_TDM_TX_7, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_TERT_TDM_TX_7}, - { AFE_PORT_ID_QUATERNARY_TDM_RX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_QUATERNARY_TDM_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_QUAT_TDM_RX_0}, - { AFE_PORT_ID_QUATERNARY_TDM_TX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_QUATERNARY_TDM_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_QUAT_TDM_TX_0}, - { AFE_PORT_ID_QUATERNARY_TDM_RX_1, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_QUATERNARY_TDM_RX_1, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_QUAT_TDM_RX_1}, - { AFE_PORT_ID_QUATERNARY_TDM_TX_1, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_QUATERNARY_TDM_TX_1, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_QUAT_TDM_TX_1}, - { AFE_PORT_ID_QUATERNARY_TDM_RX_2, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_QUATERNARY_TDM_RX_2, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_QUAT_TDM_RX_2}, - { AFE_PORT_ID_QUATERNARY_TDM_TX_2, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_QUATERNARY_TDM_TX_2, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_QUAT_TDM_TX_2}, - { AFE_PORT_ID_QUATERNARY_TDM_RX_3, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_QUATERNARY_TDM_RX_3, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_QUAT_TDM_RX_3}, - { AFE_PORT_ID_QUATERNARY_TDM_TX_3, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_QUATERNARY_TDM_TX_3, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_QUAT_TDM_TX_3}, - { AFE_PORT_ID_QUATERNARY_TDM_RX_4, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_QUATERNARY_TDM_RX_4, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_QUAT_TDM_RX_4}, - { AFE_PORT_ID_QUATERNARY_TDM_TX_4, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_QUATERNARY_TDM_TX_4, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_QUAT_TDM_TX_4}, - { AFE_PORT_ID_QUATERNARY_TDM_RX_5, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_QUATERNARY_TDM_RX_5, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_QUAT_TDM_RX_5}, - { AFE_PORT_ID_QUATERNARY_TDM_TX_5, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_QUATERNARY_TDM_TX_5, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_QUAT_TDM_TX_5}, - { AFE_PORT_ID_QUATERNARY_TDM_RX_6, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_QUATERNARY_TDM_RX_6, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_QUAT_TDM_RX_6}, - { AFE_PORT_ID_QUATERNARY_TDM_TX_6, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_QUATERNARY_TDM_TX_6, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_QUAT_TDM_TX_6}, - { AFE_PORT_ID_QUATERNARY_TDM_RX_7, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_QUATERNARY_TDM_RX_7, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_QUAT_TDM_RX_7}, - { AFE_PORT_ID_QUATERNARY_TDM_TX_7, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_QUATERNARY_TDM_TX_7, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_QUAT_TDM_TX_7}, - { INT_BT_A2DP_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_INT_BT_A2DP_RX}, - { AFE_PORT_ID_USB_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_USB_AUDIO_RX}, - { AFE_PORT_ID_USB_TX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_USB_AUDIO_TX}, - { DISPLAY_PORT_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_DISPLAY_PORT}, - { AFE_PORT_ID_TERTIARY_PCM_RX, 0, 0, {0}, 0, 0, 0, 0, 0, + { INT_BT_A2DP_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_INT_BT_A2DP_RX}, + { AFE_PORT_ID_USB_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, + LPASS_BE_USB_AUDIO_RX}, + { AFE_PORT_ID_USB_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, + LPASS_BE_USB_AUDIO_TX}, + { DISPLAY_PORT_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_DISPLAY_PORT}, + { AFE_PORT_ID_TERTIARY_PCM_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_TERT_AUXPCM_RX}, - { AFE_PORT_ID_TERTIARY_PCM_TX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_TERTIARY_PCM_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_TERT_AUXPCM_TX}, - { AFE_PORT_ID_QUATERNARY_PCM_RX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_QUATERNARY_PCM_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_QUAT_AUXPCM_RX}, - { AFE_PORT_ID_QUATERNARY_PCM_TX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_QUATERNARY_PCM_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_QUAT_AUXPCM_TX}, - { AFE_PORT_ID_INT0_MI2S_RX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_INT0_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_INT0_MI2S_RX}, - { AFE_PORT_ID_INT0_MI2S_TX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_INT0_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_INT0_MI2S_TX}, - { AFE_PORT_ID_INT1_MI2S_RX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_INT1_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_INT1_MI2S_RX}, - { AFE_PORT_ID_INT1_MI2S_TX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_INT1_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_INT1_MI2S_TX}, - { AFE_PORT_ID_INT2_MI2S_RX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_INT2_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_INT2_MI2S_RX}, - { AFE_PORT_ID_INT2_MI2S_TX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_INT2_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_INT2_MI2S_TX}, - { AFE_PORT_ID_INT3_MI2S_RX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_INT3_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_INT3_MI2S_RX}, - { AFE_PORT_ID_INT3_MI2S_TX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_INT3_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_INT3_MI2S_TX}, - { AFE_PORT_ID_INT4_MI2S_RX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_INT4_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_INT4_MI2S_RX}, - { AFE_PORT_ID_INT4_MI2S_TX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_INT4_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_INT4_MI2S_TX}, - { AFE_PORT_ID_INT5_MI2S_RX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_INT5_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_INT5_MI2S_RX}, - { AFE_PORT_ID_INT5_MI2S_TX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_INT5_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_INT5_MI2S_TX}, - { AFE_PORT_ID_INT6_MI2S_RX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_INT6_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_INT6_MI2S_RX}, - { AFE_PORT_ID_INT6_MI2S_TX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_INT6_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_INT6_MI2S_TX}, - { SLIMBUS_TX_VI, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_TX_VI}, + { SLIMBUS_TX_VI, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_TX_VI}, }; -/* Track ASM playback & capture sessions of DAI */ +/* Track ASM playback & capture sessions of DAI + * Track LSM listen sessions + */ static struct msm_pcm_routing_fdai_data - fe_dai_map[MSM_FRONTEND_DAI_MM_SIZE][2] = { + fe_dai_map[MSM_FRONTEND_DAI_MAX][2] = { /* MULTIMEDIA1 */ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, @@ -573,13 +588,79 @@ static struct msm_pcm_routing_fdai_data /* MULTIMEDIA19 */ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* CS_VOICE */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* VOIP */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* AFE_RX */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* AFE_TX */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* VOICE_STUB */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* VOLTE */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* DTMF_RX */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* VOICE2 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* QCHAT */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* VOLTE_STUB */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* LSM1 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* LSM2 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* LSM3 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* LSM4 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* LSM5 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* LSM6 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* LSM7 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* LSM8 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* VOICE2_STUB */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* VOWLAN */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* VOICEMMODE1 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* VOICEMMODE2 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, }; -static unsigned long session_copp_map[MSM_FRONTEND_DAI_MM_SIZE][2] +static unsigned long session_copp_map[MSM_FRONTEND_DAI_MAX][2] [MSM_BACKEND_DAI_MAX]; static struct msm_pcm_routing_app_type_data app_type_cfg[MAX_APP_TYPES]; static struct msm_pcm_stream_app_type_cfg - fe_dai_app_type_cfg[MSM_FRONTEND_DAI_MM_SIZE][2]; + fe_dai_app_type_cfg[MSM_FRONTEND_DAI_MAX][2]; /* The caller of this should aqcuire routing lock */ void msm_pcm_routing_get_bedai_info(int be_idx, @@ -789,7 +870,8 @@ static uint8_t is_be_dai_extproc(int be_dai) } static void msm_pcm_routing_build_matrix(int fedai_id, int sess_type, - int path_type, int perf_mode) + int path_type, int perf_mode, + uint32_t passthr_mode) { int i, port_type, j, num_copps = 0; struct route_payload payload; @@ -802,7 +884,7 @@ static void msm_pcm_routing_build_matrix(int fedai_id, int sess_type, if (!is_be_dai_extproc(i) && (afe_get_port_type(msm_bedais[i].port_id) == port_type) && (msm_bedais[i].active) && - (test_bit(fedai_id, &msm_bedais[i].fe_sessions))) { + (test_bit(fedai_id, &msm_bedais[i].fe_sessions[0]))) { for (j = 0; j < MAX_COPPS_PER_PORT; j++) { unsigned long copp = session_copp_map[fedai_id][sess_type][i]; @@ -825,7 +907,7 @@ static void msm_pcm_routing_build_matrix(int fedai_id, int sess_type, fe_dai_app_type_cfg[fedai_id][sess_type].acdb_dev_id; payload.sample_rate = fe_dai_app_type_cfg[fedai_id][sess_type].sample_rate; - adm_matrix_map(path_type, payload, perf_mode); + adm_matrix_map(path_type, payload, perf_mode, passthr_mode); msm_pcm_routng_cfg_matrix_map_pp(payload, path_type, perf_mode); } } @@ -859,7 +941,7 @@ void msm_pcm_routing_reg_psthr_stream(int fedai_id, int dspst_id, if (!is_be_dai_extproc(i) && (afe_get_port_type(msm_bedais[i].port_id) == port_type) && (msm_bedais[i].active) && - (test_bit(fedai_id, &msm_bedais[i].fe_sessions))) { + (test_bit(fedai_id, &msm_bedais[i].fe_sessions[0]))) { mode = afe_get_port_type(msm_bedais[i].port_id); adm_connect_afe_port(mode, dspst_id, msm_bedais[i].port_id); @@ -869,9 +951,38 @@ void msm_pcm_routing_reg_psthr_stream(int fedai_id, int dspst_id, mutex_unlock(&routing_lock); } +static bool route_check_fe_id_adm_support(int fe_id) +{ + bool rc = true; + + if ((fe_id >= MSM_FRONTEND_DAI_LSM1) && + (fe_id <= MSM_FRONTEND_DAI_LSM8)) { + /* fe id is listen while port is set to afe */ + if (lsm_port_index != ADM_LSM_PORT_INDEX) { + pr_debug("%s: fe_id %d, lsm mux slim port %d\n", + __func__, fe_id, lsm_port_index); + rc = false; + } + } + + return rc; +} + +static bool is_mm_lsm_fe_id(int fe_id) +{ + bool rc = true; + + if (fe_id > MSM_FRONTEND_DAI_MM_MAX_ID && + ((fe_id < MSM_FRONTEND_DAI_LSM1) || + (fe_id > MSM_FRONTEND_DAI_LSM8))) { + rc = false; + } + return rc; +} + int msm_pcm_routing_reg_phy_compr_stream(int fe_id, int perf_mode, int dspst_id, int stream_type, - uint32_t compr_passthr_mode) + uint32_t passthr_mode) { int i, j, session_type, path_type, port_type, topology, num_copps = 0; struct route_payload payload; @@ -880,17 +991,22 @@ int msm_pcm_routing_reg_phy_compr_stream(int fe_id, int perf_mode, pr_debug("%s:fe_id[%d] perf_mode[%d] id[%d] stream_type[%d] passt[%d]", __func__, fe_id, perf_mode, dspst_id, - stream_type, compr_passthr_mode); - - if (fe_id > MSM_FRONTEND_DAI_MM_MAX_ID) { + stream_type, passthr_mode); + if (!is_mm_lsm_fe_id(fe_id)) { /* bad ID assigned in machine driver */ pr_err("%s: bad MM ID %d\n", __func__, fe_id); return -EINVAL; } + if (!route_check_fe_id_adm_support(fe_id)) { + /* ignore adm open if not supported for fe_id */ + pr_debug("%s: No ADM support for fe id %d\n", __func__, fe_id); + return 0; + } + if (stream_type == SNDRV_PCM_STREAM_PLAYBACK) { session_type = SESSION_TYPE_RX; - if (compr_passthr_mode != LEGACY_PCM) + if (passthr_mode != LEGACY_PCM) path_type = ADM_PATH_COMPRESSED_RX; else path_type = ADM_PATH_PLAYBACK; @@ -911,14 +1027,14 @@ int msm_pcm_routing_reg_phy_compr_stream(int fe_id, int perf_mode, /* re-enable EQ if active */ msm_qti_pp_send_eq_values(fe_id); for (i = 0; i < MSM_BACKEND_DAI_MAX; i++) { - if (test_bit(fe_id, &msm_bedais[i].fe_sessions)) - msm_bedais[i].compr_passthr_mode = compr_passthr_mode; + if (test_bit(fe_id, &msm_bedais[i].fe_sessions[0])) + msm_bedais[i].passthr_mode = passthr_mode; if (!is_be_dai_extproc(i) && (afe_get_port_type(msm_bedais[i].port_id) == port_type) && (msm_bedais[i].active) && - (test_bit(fe_id, &msm_bedais[i].fe_sessions))) { + (test_bit(fe_id, &msm_bedais[i].fe_sessions[0]))) { int app_type, app_type_idx, copp_idx, acdb_dev_id; /* @@ -949,9 +1065,10 @@ int msm_pcm_routing_reg_phy_compr_stream(int fe_id, int perf_mode, fe_dai_app_type_cfg[fe_id][session_type].acdb_dev_id; topology = msm_routing_get_adm_topology(path_type, fe_id, session_type); - if (compr_passthr_mode == COMPRESSED_PASSTHROUGH_DSD) + + if (passthr_mode == COMPRESSED_PASSTHROUGH_DSD) topology = COMPRESS_PASSTHROUGH_NONE_TOPOLOGY; - pr_err("%s: Before adm open topology %d\n", __func__, + pr_debug("%s: Before adm open topology %d\n", __func__, topology); copp_idx = @@ -988,7 +1105,7 @@ int msm_pcm_routing_reg_phy_compr_stream(int fe_id, int perf_mode, num_copps++; } } - if (compr_passthr_mode != COMPRESSED_PASSTHROUGH_DSD) { + if (passthr_mode != COMPRESSED_PASSTHROUGH_DSD) { msm_routing_send_device_pp_params( msm_bedais[i].port_id, copp_idx); @@ -1002,7 +1119,7 @@ int msm_pcm_routing_reg_phy_compr_stream(int fe_id, int perf_mode, fe_dai_app_type_cfg[fe_id][session_type].app_type; payload.acdb_dev_id = fe_dai_app_type_cfg[fe_id][session_type].acdb_dev_id; - adm_matrix_map(path_type, payload, perf_mode); + adm_matrix_map(path_type, payload, perf_mode, passthr_mode); msm_pcm_routng_cfg_matrix_map_pp(payload, path_type, perf_mode); } mutex_unlock(&routing_lock); @@ -1053,6 +1170,7 @@ int msm_pcm_routing_reg_phy_stream(int fedai_id, int perf_mode, struct route_payload payload; u32 channels, sample_rate; uint16_t bits_per_sample = 16; + uint32_t passthr_mode = LEGACY_PCM; if (fedai_id > MSM_FRONTEND_DAI_MM_MAX_ID) { /* bad ID assigned in machine driver */ @@ -1082,7 +1200,7 @@ int msm_pcm_routing_reg_phy_stream(int fedai_id, int perf_mode, if (!is_be_dai_extproc(i) && (afe_get_port_type(msm_bedais[i].port_id) == port_type) && (msm_bedais[i].active) && - (test_bit(fedai_id, &msm_bedais[i].fe_sessions))) { + (test_bit(fedai_id, &msm_bedais[i].fe_sessions[0]))) { int app_type, app_type_idx, copp_idx, acdb_dev_id; /* * check if ADM needs to be configured with different @@ -1092,7 +1210,7 @@ int msm_pcm_routing_reg_phy_stream(int fedai_id, int perf_mode, channels = msm_bedais[i].channel; else channels = msm_bedais[i].adm_override_ch; - msm_bedais[i].compr_passthr_mode = + msm_bedais[i].passthr_mode = LEGACY_PCM; bits_per_sample = msm_routing_get_bit_width( @@ -1149,7 +1267,7 @@ int msm_pcm_routing_reg_phy_stream(int fedai_id, int perf_mode, } } if ((perf_mode == LEGACY_PCM_MODE) && - (msm_bedais[i].compr_passthr_mode == + (msm_bedais[i].passthr_mode == LEGACY_PCM)) msm_pcm_routing_cfg_pp(msm_bedais[i].port_id, copp_idx, topology, @@ -1165,7 +1283,7 @@ int msm_pcm_routing_reg_phy_stream(int fedai_id, int perf_mode, fe_dai_app_type_cfg[fedai_id][session_type].acdb_dev_id; payload.sample_rate = fe_dai_app_type_cfg[fedai_id][session_type].sample_rate; - adm_matrix_map(path_type, payload, perf_mode); + adm_matrix_map(path_type, payload, perf_mode, passthr_mode); msm_pcm_routng_cfg_matrix_map_pp(payload, path_type, perf_mode); } mutex_unlock(&routing_lock); @@ -1194,7 +1312,7 @@ void msm_pcm_routing_dereg_phy_stream(int fedai_id, int stream_type) int i, port_type, session_type, path_type, topology; struct msm_pcm_routing_fdai_data *fdai; - if (fedai_id > MSM_FRONTEND_DAI_MM_MAX_ID) { + if (!is_mm_lsm_fe_id(fedai_id)) { /* bad ID assigned in machine driver */ pr_err("%s: bad MM ID\n", __func__); return; @@ -1215,7 +1333,7 @@ void msm_pcm_routing_dereg_phy_stream(int fedai_id, int stream_type) if (!is_be_dai_extproc(i) && (afe_get_port_type(msm_bedais[i].port_id) == port_type) && (msm_bedais[i].active) && - (test_bit(fedai_id, &msm_bedais[i].fe_sessions))) { + (test_bit(fedai_id, &msm_bedais[i].fe_sessions[0]))) { int idx; unsigned long copp = session_copp_map[fedai_id][session_type][i]; @@ -1240,7 +1358,7 @@ void msm_pcm_routing_dereg_phy_stream(int fedai_id, int stream_type) if ((DOLBY_ADM_COPP_TOPOLOGY_ID == topology || DS2_ADM_COPP_TOPOLOGY_ID == topology) && (fdai->perf_mode == LEGACY_PCM_MODE) && - (msm_bedais[i].compr_passthr_mode == + (msm_bedais[i].passthr_mode == LEGACY_PCM)) msm_pcm_routing_deinit_pp(msm_bedais[i].port_id, topology); @@ -1257,13 +1375,13 @@ static bool msm_pcm_routing_route_is_set(u16 be_id, u16 fe_id) { bool rc = false; - if (fe_id > MSM_FRONTEND_DAI_MM_MAX_ID) { + if (!is_mm_lsm_fe_id(fe_id)) { /* recheck FE ID in the mixer control defined in this file */ pr_err("%s: bad MM ID\n", __func__); return rc; } - if (test_bit(fe_id, &msm_bedais[be_id].fe_sessions)) + if (test_bit(fe_id, &msm_bedais[be_id].fe_sessions[0])) rc = true; return rc; @@ -1275,19 +1393,26 @@ static void msm_pcm_routing_process_audio(u16 reg, u16 val, int set) u32 channels, sample_rate; uint16_t bits_per_sample = 16; struct msm_pcm_routing_fdai_data *fdai; + uint32_t passthr_mode = msm_bedais[reg].passthr_mode; pr_debug("%s: reg %x val %x set %x\n", __func__, reg, val, set); - if (val > MSM_FRONTEND_DAI_MM_MAX_ID) { + if (!is_mm_lsm_fe_id(val)) { /* recheck FE ID in the mixer control defined in this file */ pr_err("%s: bad MM ID\n", __func__); return; } + if (!route_check_fe_id_adm_support(val)) { + /* ignore adm open if not supported for fe_id */ + pr_debug("%s: No ADM support for fe id %d\n", __func__, val); + return; + } + if (afe_get_port_type(msm_bedais[reg].port_id) == MSM_AFE_PORT_TYPE_RX) { session_type = SESSION_TYPE_RX; - if (msm_bedais[reg].compr_passthr_mode != LEGACY_PCM) + if (passthr_mode != LEGACY_PCM) path_type = ADM_PATH_COMPRESSED_RX; else path_type = ADM_PATH_PLAYBACK; @@ -1298,12 +1423,12 @@ static void msm_pcm_routing_process_audio(u16 reg, u16 val, int set) mutex_lock(&routing_lock); if (set) { - if (!test_bit(val, &msm_bedais[reg].fe_sessions) && + if (!test_bit(val, &msm_bedais[reg].fe_sessions[0]) && ((msm_bedais[reg].port_id == VOICE_PLAYBACK_TX) || (msm_bedais[reg].port_id == VOICE2_PLAYBACK_TX))) voc_start_playback(set, msm_bedais[reg].port_id); - set_bit(val, &msm_bedais[reg].fe_sessions); + set_bit(val, &msm_bedais[reg].fe_sessions[0]); fdai = &fe_dai_map[val][session_type]; if (msm_bedais[reg].active && fdai->strm_id != INVALID_SESSION) { @@ -1379,20 +1504,20 @@ static void msm_pcm_routing_process_audio(u16 reg, u16 val, int set) msm_pcm_routing_build_matrix(val, session_type, path_type, - fdai->perf_mode); + fdai->perf_mode, + passthr_mode); if ((fdai->perf_mode == LEGACY_PCM_MODE) && - (msm_bedais[reg].compr_passthr_mode == - LEGACY_PCM)) + (passthr_mode == LEGACY_PCM)) msm_pcm_routing_cfg_pp(msm_bedais[reg].port_id, copp_idx, topology, channels); } } else { - if (test_bit(val, &msm_bedais[reg].fe_sessions) && + if (test_bit(val, &msm_bedais[reg].fe_sessions[0]) && ((msm_bedais[reg].port_id == VOICE_PLAYBACK_TX) || (msm_bedais[reg].port_id == VOICE2_PLAYBACK_TX))) voc_start_playback(set, msm_bedais[reg].port_id); - clear_bit(val, &msm_bedais[reg].fe_sessions); + clear_bit(val, &msm_bedais[reg].fe_sessions[0]); fdai = &fe_dai_map[val][session_type]; if (msm_bedais[reg].active && fdai->strm_id != INVALID_SESSION) { @@ -1417,14 +1542,14 @@ static void msm_pcm_routing_process_audio(u16 reg, u16 val, int set) if ((DOLBY_ADM_COPP_TOPOLOGY_ID == topology || DS2_ADM_COPP_TOPOLOGY_ID == topology) && (fdai->perf_mode == LEGACY_PCM_MODE) && - (msm_bedais[reg].compr_passthr_mode == - LEGACY_PCM)) + (passthr_mode == LEGACY_PCM)) msm_pcm_routing_deinit_pp( msm_bedais[reg].port_id, topology); msm_pcm_routing_build_matrix(val, session_type, path_type, - fdai->perf_mode); + fdai->perf_mode, + passthr_mode); } } if ((msm_bedais[reg].port_id == VOICE_RECORD_RX) @@ -1440,7 +1565,7 @@ static int msm_routing_get_audio_mixer(struct snd_kcontrol *kcontrol, struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; - if (test_bit(mc->shift, &msm_bedais[mc->reg].fe_sessions)) + if (test_bit(mc->shift, &msm_bedais[mc->reg].fe_sessions[0])) ucontrol->value.integer.value[0] = 1; else ucontrol->value.integer.value[0] = 0; @@ -1474,6 +1599,51 @@ static int msm_routing_put_audio_mixer(struct snd_kcontrol *kcontrol, return 1; } +static int msm_routing_get_listen_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + + if (test_bit(mc->shift, &msm_bedais[mc->reg].fe_sessions[0])) + ucontrol->value.integer.value[0] = 1; + else + ucontrol->value.integer.value[0] = 0; + + pr_debug("%s: reg %x shift %x val %ld\n", __func__, mc->reg, mc->shift, + ucontrol->value.integer.value[0]); + + return 0; +} + +static int msm_routing_put_listen_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget_list *wlist = + dapm_kcontrol_get_wlist(kcontrol); + struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + struct snd_soc_dapm_update *update = NULL; + + pr_debug("%s: reg %x shift %x val %ld\n", __func__, mc->reg, mc->shift, + ucontrol->value.integer.value[0]); + + if (ucontrol->value.integer.value[0]) { + if (msm_pcm_routing_route_is_set(mc->reg, mc->shift) == false) + msm_pcm_routing_process_audio(mc->reg, mc->shift, 1); + snd_soc_dapm_mixer_update_power(widget->dapm, + kcontrol, 1, update); + } else if (!ucontrol->value.integer.value[0]) { + if (msm_pcm_routing_route_is_set(mc->reg, mc->shift) == true) + msm_pcm_routing_process_audio(mc->reg, mc->shift, 0); + snd_soc_dapm_mixer_update_power(widget->dapm, + kcontrol, 0, update); + } + + return 1; +} + static void msm_pcm_routing_process_voice(u16 reg, u16 val, int set) { u32 session_id = 0; @@ -1490,9 +1660,9 @@ static void msm_pcm_routing_process_voice(u16 reg, u16 val, int set) mutex_lock(&routing_lock); if (set) - set_bit(val, &msm_bedais[reg].fe_sessions); + set_bit(val, &msm_bedais[reg].fe_sessions[0]); else - clear_bit(val, &msm_bedais[reg].fe_sessions); + clear_bit(val, &msm_bedais[reg].fe_sessions[0]); if (val == MSM_FRONTEND_DAI_DTMF_RX && afe_get_port_type(msm_bedais[reg].port_id) == @@ -1551,7 +1721,7 @@ static int msm_routing_get_voice_mixer(struct snd_kcontrol *kcontrol, mutex_lock(&routing_lock); - if (test_bit(mc->shift, &msm_bedais[mc->reg].fe_sessions)) + if (test_bit(mc->shift, &msm_bedais[mc->reg].fe_sessions[0])) ucontrol->value.integer.value[0] = 1; else ucontrol->value.integer.value[0] = 0; @@ -1593,7 +1763,7 @@ static int msm_routing_get_voice_stub_mixer(struct snd_kcontrol *kcontrol, mutex_lock(&routing_lock); - if (test_bit(mc->shift, &msm_bedais[mc->reg].fe_sessions)) + if (test_bit(mc->shift, &msm_bedais[mc->reg].fe_sessions[0])) ucontrol->value.integer.value[0] = 1; else ucontrol->value.integer.value[0] = 0; @@ -1618,13 +1788,13 @@ static int msm_routing_put_voice_stub_mixer(struct snd_kcontrol *kcontrol, if (ucontrol->value.integer.value[0]) { mutex_lock(&routing_lock); - set_bit(mc->shift, &msm_bedais[mc->reg].fe_sessions); + set_bit(mc->shift, &msm_bedais[mc->reg].fe_sessions[0]); mutex_unlock(&routing_lock); snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, 1, update); } else { mutex_lock(&routing_lock); - clear_bit(mc->shift, &msm_bedais[mc->reg].fe_sessions); + clear_bit(mc->shift, &msm_bedais[mc->reg].fe_sessions[0]); mutex_unlock(&routing_lock); snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, 0, update); @@ -1868,23 +2038,19 @@ static int msm_routing_put_fm_pcmrx_switch_mixer(struct snd_kcontrol *kcontrol, return 1; } -static int msm_routing_lsm_mux_get(struct snd_kcontrol *kcontrol, +static int msm_routing_lsm_port_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - ucontrol->value.integer.value[0] = lsm_mux_slim_port; + ucontrol->value.integer.value[0] = lsm_port_index; return 0; } -static int msm_routing_lsm_mux_put(struct snd_kcontrol *kcontrol, +static int msm_routing_lsm_port_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_widget_list *wlist = - dapm_kcontrol_get_wlist(kcontrol); - struct snd_soc_dapm_widget *widget = wlist->widgets[0]; struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; int mux = ucontrol->value.enumerated.item[0]; int lsm_port = AFE_PORT_ID_SLIMBUS_MULTI_CHAN_5_TX; - struct snd_soc_dapm_update *update = NULL; if (mux >= e->items) { pr_err("%s: Invalid mux value %d\n", __func__, mux); @@ -1915,19 +2081,18 @@ static int msm_routing_lsm_mux_put(struct snd_kcontrol *kcontrol, case 7: lsm_port = AFE_PORT_ID_TERTIARY_MI2S_TX; break; + case 8: + lsm_port = AFE_PORT_ID_QUATERNARY_MI2S_TX; + break; + case 9: + lsm_port = ADM_LSM_PORT_ID; + break; default: pr_err("Default lsm port"); break; } set_lsm_port(lsm_port); - - if (ucontrol->value.integer.value[0]) { - lsm_mux_slim_port = ucontrol->value.integer.value[0]; - snd_soc_dapm_mux_update_power(widget->dapm, kcontrol, mux, e, update); - } else { - snd_soc_dapm_mux_update_power(widget->dapm, kcontrol, mux, e, update); - lsm_mux_slim_port = ucontrol->value.integer.value[0]; - } + lsm_port_index = ucontrol->value.integer.value[0]; return 0; } @@ -1940,23 +2105,27 @@ static int msm_routing_lsm_func_get(struct snd_kcontrol *kcontrol, enum afe_mad_type mad_type; pr_debug("%s: enter\n", __func__); - for (i = 0; i < ARRAY_SIZE(mad_audio_mux_text); i++) - if (!strncmp(kcontrol->id.name, mad_audio_mux_text[i], - strlen(mad_audio_mux_text[i]))) + for (i = 0; i < ARRAY_SIZE(lsm_port_text); i++) + if (!strnstr(kcontrol->id.name, lsm_port_text[i], + strlen(lsm_port_text[i]))) break; - if (i-- == ARRAY_SIZE(mad_audio_mux_text)) { + if (i-- == ARRAY_SIZE(lsm_port_text)) { WARN(1, "Invalid id name %s\n", kcontrol->id.name); return -EINVAL; } /*Check for Tertiary TX port*/ - if (!strcmp(kcontrol->id.name, mad_audio_mux_text[7])) { + if (!strcmp(kcontrol->id.name, lsm_port_text[7])) { ucontrol->value.integer.value[0] = MADSWAUDIO; return 0; } port_id = i * 2 + 1 + SLIMBUS_0_RX; + + if (!strcmp(kcontrol->id.name, lsm_port_text[8])) + port_id = AFE_PORT_ID_QUATERNARY_MI2S_TX; + mad_type = afe_port_get_mad_type(port_id); pr_debug("%s: port_id 0x%x, mad_type %d\n", __func__, port_id, mad_type); @@ -1991,12 +2160,12 @@ static int msm_routing_lsm_func_put(struct snd_kcontrol *kcontrol, enum afe_mad_type mad_type; pr_debug("%s: enter\n", __func__); - for (i = 0; i < ARRAY_SIZE(mad_audio_mux_text); i++) - if (!strncmp(kcontrol->id.name, mad_audio_mux_text[i], - strlen(mad_audio_mux_text[i]))) + for (i = 0; i < ARRAY_SIZE(lsm_port_text); i++) + if (strnstr(kcontrol->id.name, lsm_port_text[i], + strlen(lsm_port_text[i]))) break; - if (i-- == ARRAY_SIZE(mad_audio_mux_text)) { + if (i-- == ARRAY_SIZE(lsm_port_text)) { WARN(1, "Invalid id name %s\n", kcontrol->id.name); return -EINVAL; } @@ -2024,11 +2193,16 @@ static int msm_routing_lsm_func_put(struct snd_kcontrol *kcontrol, } /*Check for Tertiary TX port*/ - if (!strcmp(kcontrol->id.name, mad_audio_mux_text[7])) { + if (strnstr(kcontrol->id.name, lsm_port_text[7], + strlen(lsm_port_text[7]))) { port_id = AFE_PORT_ID_TERTIARY_MI2S_TX; mad_type = MAD_SW_AUDIO; } + if (strnstr(kcontrol->id.name, lsm_port_text[8], + strlen(lsm_port_text[8]))) + port_id = AFE_PORT_ID_QUATERNARY_MI2S_TX; + pr_debug("%s: port_id 0x%x, mad_type %d\n", __func__, port_id, mad_type); return afe_port_set_mad_type(port_id, mad_type); @@ -2193,6 +2367,144 @@ static int msm_routing_put_port_mixer(struct snd_kcontrol *kcontrol, return 1; } +static int msm_ec_ref_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = msm_ec_ref_ch; + pr_debug("%s: msm_ec_ref_ch = %ld\n", __func__, + ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_ec_ref_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + msm_ec_ref_ch = ucontrol->value.integer.value[0]; + pr_debug("%s: msm_ec_ref_ch = %d\n", __func__, msm_ec_ref_ch); + adm_num_ec_ref_rx_chans(msm_ec_ref_ch); + return 0; +} + +static const char *const ec_ref_ch_text[] = {"Zero", "One", "Two", "Three", + "Four", "Five", "Six", "Seven", "Eight"}; + +static int msm_ec_ref_bit_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (msm_ec_ref_bit_format) { + case SNDRV_PCM_FORMAT_S24_LE: + ucontrol->value.integer.value[0] = 2; + break; + case SNDRV_PCM_FORMAT_S16_LE: + ucontrol->value.integer.value[0] = 1; + break; + default: + ucontrol->value.integer.value[0] = 0; + break; + } + pr_debug("%s: msm_ec_ref_bit_format = %ld\n", + __func__, ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_ec_ref_bit_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u16 bit_width = 0; + + switch (ucontrol->value.integer.value[0]) { + case 2: + msm_ec_ref_bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 1: + msm_ec_ref_bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + default: + msm_ec_ref_bit_format = 0; + break; + } + + if (msm_ec_ref_bit_format == SNDRV_PCM_FORMAT_S16_LE) + bit_width = 16; + else if (msm_ec_ref_bit_format == SNDRV_PCM_FORMAT_S24_LE) + bit_width = 24; + + pr_debug("%s: msm_ec_ref_bit_format = %d\n", + __func__, msm_ec_ref_bit_format); + adm_ec_ref_rx_bit_width(bit_width); + return 0; +} + +static char const *ec_ref_bit_format_text[] = {"0", "S16_LE", "S24_LE"}; + +static int msm_ec_ref_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = msm_ec_ref_sampling_rate; + pr_debug("%s: msm_ec_ref_sampling_rate = %ld\n", + __func__, ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_ec_ref_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 0: + msm_ec_ref_sampling_rate = 0; + break; + case 1: + msm_ec_ref_sampling_rate = 8000; + break; + case 2: + msm_ec_ref_sampling_rate = 16000; + break; + case 3: + msm_ec_ref_sampling_rate = 32000; + break; + case 4: + msm_ec_ref_sampling_rate = 44100; + break; + case 5: + msm_ec_ref_sampling_rate = 48000; + break; + case 6: + msm_ec_ref_sampling_rate = 96000; + break; + case 7: + msm_ec_ref_sampling_rate = 192000; + break; + case 8: + msm_ec_ref_sampling_rate = 384000; + break; + default: + msm_ec_ref_sampling_rate = 48000; + break; + } + pr_debug("%s: msm_ec_ref_sampling_rate = %d\n", + __func__, msm_ec_ref_sampling_rate); + adm_ec_ref_rx_sampling_rate(msm_ec_ref_sampling_rate); + return 0; +} + +static const char *const ec_ref_rate_text[] = {"0", "8000", "16000", + "32000", "44100", "48000", "96000", "192000", "384000"}; + +static const struct soc_enum msm_route_ec_ref_params_enum[] = { + SOC_ENUM_SINGLE_EXT(9, ec_ref_ch_text), + SOC_ENUM_SINGLE_EXT(3, ec_ref_bit_format_text), + SOC_ENUM_SINGLE_EXT(9, ec_ref_rate_text), +}; + +static const struct snd_kcontrol_new ec_ref_param_controls[] = { + SOC_ENUM_EXT("EC Reference Channels", msm_route_ec_ref_params_enum[0], + msm_ec_ref_ch_get, msm_ec_ref_ch_put), + SOC_ENUM_EXT("EC Reference Bit Format", msm_route_ec_ref_params_enum[1], + msm_ec_ref_bit_format_get, msm_ec_ref_bit_format_put), + SOC_ENUM_EXT("EC Reference SampleRate", msm_route_ec_ref_params_enum[2], + msm_ec_ref_rate_get, msm_ec_ref_rate_put), +}; + static int msm_routing_ec_ref_rx_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -7661,6 +7973,198 @@ static const struct snd_kcontrol_new sec_mi2s_rx_port_mixer_controls[] = { msm_routing_put_port_mixer), }; +static const struct snd_kcontrol_new lsm1_mixer_controls[] = { + SOC_SINGLE_EXT("SLIMBUS_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_1_TX", MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_3_TX", MSM_BACKEND_DAI_SLIMBUS_3_TX, + MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_4_TX", MSM_BACKEND_DAI_SLIMBUS_4_TX, + MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_5_TX", MSM_BACKEND_DAI_SLIMBUS_5_TX, + MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +}; + +static const struct snd_kcontrol_new lsm2_mixer_controls[] = { + SOC_SINGLE_EXT("SLIMBUS_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_1_TX", MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_3_TX", MSM_BACKEND_DAI_SLIMBUS_3_TX, + MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_4_TX", MSM_BACKEND_DAI_SLIMBUS_4_TX, + MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_5_TX", MSM_BACKEND_DAI_SLIMBUS_5_TX, + MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +}; + +static const struct snd_kcontrol_new lsm3_mixer_controls[] = { + SOC_SINGLE_EXT("SLIMBUS_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_1_TX", MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_3_TX", MSM_BACKEND_DAI_SLIMBUS_3_TX, + MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_4_TX", MSM_BACKEND_DAI_SLIMBUS_4_TX, + MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_5_TX", MSM_BACKEND_DAI_SLIMBUS_5_TX, + MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +}; + +static const struct snd_kcontrol_new lsm4_mixer_controls[] = { + SOC_SINGLE_EXT("SLIMBUS_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_1_TX", MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_3_TX", MSM_BACKEND_DAI_SLIMBUS_3_TX, + MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_4_TX", MSM_BACKEND_DAI_SLIMBUS_4_TX, + MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_5_TX", MSM_BACKEND_DAI_SLIMBUS_5_TX, + MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +}; + +static const struct snd_kcontrol_new lsm5_mixer_controls[] = { + SOC_SINGLE_EXT("SLIMBUS_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_1_TX", MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_3_TX", MSM_BACKEND_DAI_SLIMBUS_3_TX, + MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_4_TX", MSM_BACKEND_DAI_SLIMBUS_4_TX, + MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_5_TX", MSM_BACKEND_DAI_SLIMBUS_5_TX, + MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +}; + +static const struct snd_kcontrol_new lsm6_mixer_controls[] = { + SOC_SINGLE_EXT("SLIMBUS_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_1_TX", MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_3_TX", MSM_BACKEND_DAI_SLIMBUS_3_TX, + MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_4_TX", MSM_BACKEND_DAI_SLIMBUS_4_TX, + MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_5_TX", MSM_BACKEND_DAI_SLIMBUS_5_TX, + MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +}; + +static const struct snd_kcontrol_new lsm7_mixer_controls[] = { + SOC_SINGLE_EXT("SLIMBUS_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_1_TX", MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_3_TX", MSM_BACKEND_DAI_SLIMBUS_3_TX, + MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_4_TX", MSM_BACKEND_DAI_SLIMBUS_4_TX, + MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_5_TX", MSM_BACKEND_DAI_SLIMBUS_5_TX, + MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +}; + +static const struct snd_kcontrol_new lsm8_mixer_controls[] = { + SOC_SINGLE_EXT("SLIMBUS_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_1_TX", MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_3_TX", MSM_BACKEND_DAI_SLIMBUS_3_TX, + MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_4_TX", MSM_BACKEND_DAI_SLIMBUS_4_TX, + MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_5_TX", MSM_BACKEND_DAI_SLIMBUS_5_TX, + MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +}; + static const struct snd_kcontrol_new slim_fm_switch_mixer_controls = SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, 0, 1, 0, msm_routing_get_switch_mixer, @@ -7736,53 +8240,17 @@ static const struct snd_kcontrol_new usb_switch_mixer_controls = 0, 1, 0, msm_routing_get_usb_switch_mixer, msm_routing_put_usb_switch_mixer); -static const struct soc_enum lsm_mux_enum = - SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(mad_audio_mux_text), mad_audio_mux_text); - -static const struct snd_kcontrol_new lsm1_mux = - SOC_DAPM_ENUM_EXT("LSM1 MUX", lsm_mux_enum, - msm_routing_lsm_mux_get, - msm_routing_lsm_mux_put); - -static const struct snd_kcontrol_new lsm2_mux = - SOC_DAPM_ENUM_EXT("LSM2 MUX", lsm_mux_enum, - msm_routing_lsm_mux_get, - msm_routing_lsm_mux_put); -static const struct snd_kcontrol_new lsm3_mux = - SOC_DAPM_ENUM_EXT("LSM3 MUX", lsm_mux_enum, - msm_routing_lsm_mux_get, - msm_routing_lsm_mux_put); - -static const struct snd_kcontrol_new lsm4_mux = - SOC_DAPM_ENUM_EXT("LSM4 MUX", lsm_mux_enum, - msm_routing_lsm_mux_get, - msm_routing_lsm_mux_put); -static const struct snd_kcontrol_new lsm5_mux = - SOC_DAPM_ENUM_EXT("LSM5 MUX", lsm_mux_enum, - msm_routing_lsm_mux_get, - msm_routing_lsm_mux_put); - -static const struct snd_kcontrol_new lsm6_mux = - SOC_DAPM_ENUM_EXT("LSM6 MUX", lsm_mux_enum, - msm_routing_lsm_mux_get, - msm_routing_lsm_mux_put); -static const struct snd_kcontrol_new lsm7_mux = - SOC_DAPM_ENUM_EXT("LSM7 MUX", lsm_mux_enum, - msm_routing_lsm_mux_get, - msm_routing_lsm_mux_put); - -static const struct snd_kcontrol_new lsm8_mux = - SOC_DAPM_ENUM_EXT("LSM8 MUX", lsm_mux_enum, - msm_routing_lsm_mux_get, - msm_routing_lsm_mux_put); - +static const struct soc_enum lsm_port_enum = + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(lsm_port_text), lsm_port_text); static const char * const lsm_func_text[] = { "None", "AUDIO", "BEACON", "ULTRASOUND", "SWAUDIO", }; static const struct soc_enum lsm_func_enum = SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(lsm_func_text), lsm_func_text); -static const struct snd_kcontrol_new lsm_function[] = { + +static const struct snd_kcontrol_new lsm_controls[] = { + /* kcontrol of lsm_function */ SOC_ENUM_EXT(SLIMBUS_0_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, msm_routing_lsm_func_get, msm_routing_lsm_func_put), SOC_ENUM_EXT(SLIMBUS_1_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, @@ -7797,6 +8265,33 @@ static const struct snd_kcontrol_new lsm_function[] = { msm_routing_lsm_func_get, msm_routing_lsm_func_put), SOC_ENUM_EXT(TERT_MI2S_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, msm_routing_lsm_func_get, msm_routing_lsm_func_put), + SOC_ENUM_EXT(QUAT_MI2S_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, + msm_routing_lsm_func_get, msm_routing_lsm_func_put), + /* kcontrol of lsm_port */ + SOC_ENUM_EXT("LSM1 Port", lsm_port_enum, + msm_routing_lsm_port_get, + msm_routing_lsm_port_put), + SOC_ENUM_EXT("LSM2 Port", lsm_port_enum, + msm_routing_lsm_port_get, + msm_routing_lsm_port_put), + SOC_ENUM_EXT("LSM3 Port", lsm_port_enum, + msm_routing_lsm_port_get, + msm_routing_lsm_port_put), + SOC_ENUM_EXT("LSM4 Port", lsm_port_enum, + msm_routing_lsm_port_get, + msm_routing_lsm_port_put), + SOC_ENUM_EXT("LSM5 Port", lsm_port_enum, + msm_routing_lsm_port_get, + msm_routing_lsm_port_put), + SOC_ENUM_EXT("LSM6 Port", lsm_port_enum, + msm_routing_lsm_port_get, + msm_routing_lsm_port_put), + SOC_ENUM_EXT("LSM7 Port", lsm_port_enum, + msm_routing_lsm_port_get, + msm_routing_lsm_port_put), + SOC_ENUM_EXT("LSM8 Port", lsm_port_enum, + msm_routing_lsm_port_get, + msm_routing_lsm_port_put), }; static const char * const aanc_slim_0_rx_text[] = { @@ -7853,7 +8348,7 @@ static int msm_routing_put_stereo_to_custom_stereo_control( (port_id != AFE_PORT_ID_INT4_MI2S_RX)) continue; - for_each_set_bit(i, &msm_bedais[be_index].fe_sessions, + for_each_set_bit(i, &msm_bedais[be_index].fe_sessions[0], MSM_FRONTEND_DAI_MM_SIZE) { if (fe_dai_map[i][SESSION_TYPE_RX].perf_mode != LEGACY_PCM_MODE) @@ -8154,7 +8649,7 @@ static int msm_audio_get_copp_idx_from_port_id(int port_id, int session_type, goto done; } - for_each_set_bit(i, &msm_bedais[be_idx].fe_sessions, + for_each_set_bit(i, &msm_bedais[be_idx].fe_sessions[0], MSM_FRONTEND_DAI_MM_SIZE) { for (idx = 0; idx < MAX_COPPS_PER_PORT; idx++) { copp = session_copp_map[i] @@ -9224,16 +9719,6 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_SWITCH("USB_DL_HL", SND_SOC_NOPM, 0, 0, &usb_switch_mixer_controls), - /* Mux Definitions */ - SND_SOC_DAPM_MUX("LSM1 MUX", SND_SOC_NOPM, 0, 0, &lsm1_mux), - SND_SOC_DAPM_MUX("LSM2 MUX", SND_SOC_NOPM, 0, 0, &lsm2_mux), - SND_SOC_DAPM_MUX("LSM3 MUX", SND_SOC_NOPM, 0, 0, &lsm3_mux), - SND_SOC_DAPM_MUX("LSM4 MUX", SND_SOC_NOPM, 0, 0, &lsm4_mux), - SND_SOC_DAPM_MUX("LSM5 MUX", SND_SOC_NOPM, 0, 0, &lsm5_mux), - SND_SOC_DAPM_MUX("LSM6 MUX", SND_SOC_NOPM, 0, 0, &lsm6_mux), - SND_SOC_DAPM_MUX("LSM7 MUX", SND_SOC_NOPM, 0, 0, &lsm7_mux), - SND_SOC_DAPM_MUX("LSM8 MUX", SND_SOC_NOPM, 0, 0, &lsm8_mux), - /* Mixer definitions */ SND_SOC_DAPM_MIXER("PRI_RX Audio Mixer", SND_SOC_NOPM, 0, 0, pri_i2s_rx_mixer_controls, ARRAY_SIZE(pri_i2s_rx_mixer_controls)), @@ -9591,6 +10076,23 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_MIXER("USB_AUDIO_RX Port Mixer", SND_SOC_NOPM, 0, 0, usb_rx_port_mixer_controls, ARRAY_SIZE(usb_rx_port_mixer_controls)), + /* lsm mixer definitions */ + SND_SOC_DAPM_MIXER("LSM1 Mixer", SND_SOC_NOPM, 0, 0, + lsm1_mixer_controls, ARRAY_SIZE(lsm1_mixer_controls)), + SND_SOC_DAPM_MIXER("LSM2 Mixer", SND_SOC_NOPM, 0, 0, + lsm2_mixer_controls, ARRAY_SIZE(lsm2_mixer_controls)), + SND_SOC_DAPM_MIXER("LSM3 Mixer", SND_SOC_NOPM, 0, 0, + lsm3_mixer_controls, ARRAY_SIZE(lsm3_mixer_controls)), + SND_SOC_DAPM_MIXER("LSM4 Mixer", SND_SOC_NOPM, 0, 0, + lsm4_mixer_controls, ARRAY_SIZE(lsm4_mixer_controls)), + SND_SOC_DAPM_MIXER("LSM5 Mixer", SND_SOC_NOPM, 0, 0, + lsm5_mixer_controls, ARRAY_SIZE(lsm5_mixer_controls)), + SND_SOC_DAPM_MIXER("LSM6 Mixer", SND_SOC_NOPM, 0, 0, + lsm6_mixer_controls, ARRAY_SIZE(lsm6_mixer_controls)), + SND_SOC_DAPM_MIXER("LSM7 Mixer", SND_SOC_NOPM, 0, 0, + lsm7_mixer_controls, ARRAY_SIZE(lsm7_mixer_controls)), + SND_SOC_DAPM_MIXER("LSM8 Mixer", SND_SOC_NOPM, 0, 0, + lsm8_mixer_controls, ARRAY_SIZE(lsm8_mixer_controls)), /* Virtual Pins to force backends ON atm */ SND_SOC_DAPM_OUTPUT("BE_OUT"), SND_SOC_DAPM_INPUT("BE_IN"), @@ -11050,70 +11552,77 @@ static const struct snd_soc_dapm_route intercon[] = { {"SLIM4_UL_HL", NULL, "SLIMBUS_4_TX"}, {"SLIM8_UL_HL", NULL, "SLIMBUS_8_TX"}, - {"LSM1 MUX", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, - {"LSM1 MUX", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, - {"LSM1 MUX", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, - {"LSM1 MUX", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, - {"LSM1 MUX", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, - {"LSM1 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"LSM1_UL_HL", NULL, "LSM1 MUX"}, - {"LSM2 MUX", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, - {"LSM2 MUX", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, - {"LSM2 MUX", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, - {"LSM2 MUX", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, - {"LSM2 MUX", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, - {"LSM2 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"LSM2_UL_HL", NULL, "LSM2 MUX"}, + {"LSM1 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, + {"LSM1 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, + {"LSM1 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, + {"LSM1 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, + {"LSM1 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, + {"LSM1 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"LSM1 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"LSM1_UL_HL", NULL, "LSM1 Mixer"}, + + {"LSM2 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, + {"LSM2 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, + {"LSM2 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, + {"LSM2 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, + {"LSM2 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, + {"LSM2 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"LSM2 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"LSM2_UL_HL", NULL, "LSM2 Mixer"}, - {"LSM3 MUX", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, - {"LSM3 MUX", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, - {"LSM3 MUX", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, - {"LSM3 MUX", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, - {"LSM3 MUX", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, - {"LSM3 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"LSM3_UL_HL", NULL, "LSM3 MUX"}, + {"LSM3 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, + {"LSM3 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, + {"LSM3 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, + {"LSM3 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, + {"LSM3 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, + {"LSM3 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"LSM3 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"LSM3_UL_HL", NULL, "LSM3 Mixer"}, - {"LSM4 MUX", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, - {"LSM4 MUX", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, - {"LSM4 MUX", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, - {"LSM4 MUX", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, - {"LSM4 MUX", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, - {"LSM4 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"LSM4_UL_HL", NULL, "LSM4 MUX"}, + {"LSM4 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, + {"LSM4 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, + {"LSM4 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, + {"LSM4 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, + {"LSM4 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, + {"LSM4 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"LSM4 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"LSM4_UL_HL", NULL, "LSM4 Mixer"}, - {"LSM5 MUX", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, - {"LSM5 MUX", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, - {"LSM5 MUX", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, - {"LSM5 MUX", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, - {"LSM5 MUX", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, - {"LSM5 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"LSM5_UL_HL", NULL, "LSM5 MUX"}, + {"LSM5 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, + {"LSM5 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, + {"LSM5 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, + {"LSM5 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, + {"LSM5 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, + {"LSM5 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"LSM5 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"LSM5_UL_HL", NULL, "LSM5 Mixer"}, - {"LSM6 MUX", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, - {"LSM6 MUX", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, - {"LSM6 MUX", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, - {"LSM6 MUX", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, - {"LSM6 MUX", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, - {"LSM6_UL_HL", NULL, "LSM6 MUX"}, + {"LSM6 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, + {"LSM6 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, + {"LSM6 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, + {"LSM6 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, + {"LSM6 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, + {"LSM6 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"LSM6_UL_HL", NULL, "LSM6 Mixer"}, + {"LSM7 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, + {"LSM7 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, + {"LSM7 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, + {"LSM7 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, + {"LSM7 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, + {"LSM7 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"LSM7_UL_HL", NULL, "LSM7 Mixer"}, - {"LSM7 MUX", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, - {"LSM7 MUX", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, - {"LSM7 MUX", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, - {"LSM7 MUX", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, - {"LSM7 MUX", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, - {"LSM7_UL_HL", NULL, "LSM7 MUX"}, - - - {"LSM8 MUX", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, - {"LSM8 MUX", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, - {"LSM8 MUX", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, - {"LSM8 MUX", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, - {"LSM8 MUX", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, - {"LSM8_UL_HL", NULL, "LSM8 MUX"}, + {"LSM8 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, + {"LSM8 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, + {"LSM8 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, + {"LSM8 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, + {"LSM8 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, + {"LSM8 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"LSM8_UL_HL", NULL, "LSM8 Mixer"}, {"CPE_LSM_UL_HL", NULL, "BE_IN"}, @@ -11730,7 +12239,9 @@ static int msm_pcm_routing_close(struct snd_pcm_substream *substream) path_type = ADM_PATH_LIVE_REC; mutex_lock(&routing_lock); - for_each_set_bit(i, &bedai->fe_sessions, MSM_FRONTEND_DAI_MM_SIZE) { + for_each_set_bit(i, &bedai->fe_sessions[0], MSM_FRONTEND_DAI_MAX) { + if (!is_mm_lsm_fe_id(i)) + continue; fdai = &fe_dai_map[i][session_type]; if (fdai->strm_id != INVALID_SESSION) { int idx; @@ -11751,13 +12262,12 @@ static int msm_pcm_routing_close(struct snd_pcm_substream *substream) clear_bit(idx, &session_copp_map[i][session_type][be_id]); if ((fdai->perf_mode == LEGACY_PCM_MODE) && - (bedai->compr_passthr_mode == LEGACY_PCM)) + (bedai->passthr_mode == LEGACY_PCM)) msm_pcm_routing_deinit_pp(bedai->port_id, topology); } } - bedai->compr_passthr_mode = LEGACY_PCM; bedai->active = 0; bedai->sample_rate = 0; bedai->channel = 0; @@ -11789,7 +12299,7 @@ static int msm_pcm_routing_prepare(struct snd_pcm_substream *substream) bedai = &msm_bedais[be_id]; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - if (bedai->compr_passthr_mode != LEGACY_PCM) + if (bedai->passthr_mode != LEGACY_PCM) path_type = ADM_PATH_COMPRESSED_RX; else path_type = ADM_PATH_PLAYBACK; @@ -11810,7 +12320,10 @@ static int msm_pcm_routing_prepare(struct snd_pcm_substream *substream) */ bedai->active = 1; - for_each_set_bit(i, &bedai->fe_sessions, MSM_FRONTEND_DAI_MM_SIZE) { + for_each_set_bit(i, &bedai->fe_sessions[0], MSM_FRONTEND_DAI_MAX) { + if (!(is_mm_lsm_fe_id(i) && + route_check_fe_id_adm_support(i))) + continue; fdai = &fe_dai_map[i][session_type]; if (fdai->strm_id != INVALID_SESSION) { int app_type, app_type_idx, copp_idx, acdb_dev_id; @@ -11877,16 +12390,16 @@ static int msm_pcm_routing_prepare(struct snd_pcm_substream *substream) bedai->sample_rate); msm_pcm_routing_build_matrix(i, session_type, path_type, - fdai->perf_mode); + fdai->perf_mode, + bedai->passthr_mode); if ((fdai->perf_mode == LEGACY_PCM_MODE) && - (bedai->compr_passthr_mode == - LEGACY_PCM)) + (bedai->passthr_mode == LEGACY_PCM)) msm_pcm_routing_cfg_pp(bedai->port_id, copp_idx, topology, channels); } } - for_each_set_bit(i, &bedai->fe_sessions, MSM_FRONTEND_DAI_MAX) { + for_each_set_bit(i, &bedai->fe_sessions[0], MSM_FRONTEND_DAI_MAX) { session_id = msm_pcm_routing_get_voc_sessionid(i); if (session_id) { pr_debug("%s voice session_id: 0x%x\n", __func__, @@ -11951,6 +12464,7 @@ static int msm_routing_send_device_pp_params(int port_id, int copp_idx) unsigned long pp_config = 0; bool mute_on; int latency; + bool compr_passthr_mode = true; pr_debug("%s: port_id %d, copp_idx %d\n", __func__, port_id, copp_idx); @@ -11987,14 +12501,16 @@ static int msm_routing_send_device_pp_params(int port_id, int copp_idx) return -EINVAL; } + if ((msm_bedais[be_idx].passthr_mode == LEGACY_PCM) || + (msm_bedais[be_idx].passthr_mode == LISTEN)) + compr_passthr_mode = false; + pp_config = msm_bedais_pp_params[index].pp_params_config; if (test_bit(ADM_PP_PARAM_MUTE_BIT, &pp_config)) { pr_debug("%s: ADM_PP_PARAM_MUTE\n", __func__); clear_bit(ADM_PP_PARAM_MUTE_BIT, &pp_config); mute_on = msm_bedais_pp_params[index].mute_on; - if ((msm_bedais[be_idx].active) && - (msm_bedais[be_idx].compr_passthr_mode != - LEGACY_PCM)) + if ((msm_bedais[be_idx].active) && compr_passthr_mode) adm_send_compressed_device_mute(port_id, copp_idx, mute_on); @@ -12004,9 +12520,7 @@ static int msm_routing_send_device_pp_params(int port_id, int copp_idx) clear_bit(ADM_PP_PARAM_LATENCY_BIT, &pp_config); latency = msm_bedais_pp_params[index].latency; - if ((msm_bedais[be_idx].active) && - (msm_bedais[be_idx].compr_passthr_mode != - LEGACY_PCM)) + if ((msm_bedais[be_idx].active) && compr_passthr_mode) adm_send_compressed_device_latency(port_id, copp_idx, latency); @@ -12022,6 +12536,7 @@ static int msm_routing_put_device_pp_params_mixer(struct snd_kcontrol *kcontrol, int index, be_idx, i, topo_id, idx; bool mute; int latency; + bool compr_passthr_mode = true; pr_debug("%s: pp_id: 0x%x\n", __func__, pp_id); @@ -12046,7 +12561,11 @@ static int msm_routing_put_device_pp_params_mixer(struct snd_kcontrol *kcontrol, return -EINVAL; } - for_each_set_bit(i, &msm_bedais[be_idx].fe_sessions, + if ((msm_bedais[be_idx].passthr_mode == LEGACY_PCM) || + (msm_bedais[be_idx].passthr_mode == LISTEN)) + compr_passthr_mode = false; + + for_each_set_bit(i, &msm_bedais[be_idx].fe_sessions[0], MSM_FRONTEND_DAI_MM_SIZE) { for (idx = 0; idx < MAX_COPPS_PER_PORT; idx++) { unsigned long copp = @@ -12060,7 +12579,7 @@ static int msm_routing_put_device_pp_params_mixer(struct snd_kcontrol *kcontrol, continue; pr_debug("%s: port: 0x%x, copp %ld, be active: %d, passt: %d\n", __func__, port_id, copp, msm_bedais[be_idx].active, - msm_bedais[be_idx].compr_passthr_mode); + msm_bedais[be_idx].passthr_mode); switch (pp_id) { case ADM_PP_PARAM_MUTE_ID: pr_debug("%s: ADM_PP_PARAM_MUTE\n", __func__); @@ -12068,9 +12587,7 @@ static int msm_routing_put_device_pp_params_mixer(struct snd_kcontrol *kcontrol, msm_bedais_pp_params[index].mute_on = mute; set_bit(ADM_PP_PARAM_MUTE_BIT, &msm_bedais_pp_params[index].pp_params_config); - if ((msm_bedais[be_idx].active) && - (msm_bedais[be_idx].compr_passthr_mode != - LEGACY_PCM)) + if ((msm_bedais[be_idx].active) && compr_passthr_mode) adm_send_compressed_device_mute(port_id, idx, mute); break; @@ -12082,9 +12599,7 @@ static int msm_routing_put_device_pp_params_mixer(struct snd_kcontrol *kcontrol, &msm_bedais_pp_params[index].pp_params_config); latency = msm_bedais_pp_params[index].latency = ucontrol->value.integer.value[1]; - if ((msm_bedais[be_idx].active) && - (msm_bedais[be_idx].compr_passthr_mode != - LEGACY_PCM)) + if ((msm_bedais[be_idx].active) && compr_passthr_mode) adm_send_compressed_device_latency(port_id, idx, latency); break; @@ -12154,8 +12669,8 @@ static int msm_routing_probe(struct snd_soc_platform *platform) snd_soc_dapm_new_widgets(platform->component.dapm.card); - snd_soc_add_platform_controls(platform, lsm_function, - ARRAY_SIZE(lsm_function)); + snd_soc_add_platform_controls(platform, lsm_controls, + ARRAY_SIZE(lsm_controls)); snd_soc_add_platform_controls(platform, aanc_slim_0_rx_mux, ARRAY_SIZE(aanc_slim_0_rx_mux)); @@ -12170,6 +12685,9 @@ static int msm_routing_probe(struct snd_soc_platform *platform) stereo_to_custom_stereo_controls, ARRAY_SIZE(stereo_to_custom_stereo_controls)); + snd_soc_add_platform_controls(platform, ec_ref_param_controls, + ARRAY_SIZE(ec_ref_param_controls)); + msm_qti_pp_add_controls(platform); msm_dts_srs_tm_add_controls(platform); @@ -12252,7 +12770,7 @@ int msm_routing_check_backend_enabled(int fedai_id) return 0; } for (i = 0; i < MSM_BACKEND_DAI_MAX; i++) { - if (test_bit(fedai_id, &msm_bedais[i].fe_sessions)) + if (test_bit(fedai_id, &msm_bedais[i].fe_sessions[0])) return msm_bedais[i].active; } return 0; diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h index 0bb069154512..a066e9afc9e5 100644 --- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h +++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -392,6 +392,7 @@ enum { #define ADM_PP_PARAM_LATENCY_ID 1 #define ADM_PP_PARAM_LATENCY_BIT 2 #define BE_DAI_PORT_SESSIONS_IDX_MAX 4 +#define BE_DAI_FE_SESSIONS_IDX_MAX 2 struct msm_pcm_routing_evt { void (*event_func)(enum msm_pcm_routing_event, void *); @@ -401,7 +402,9 @@ struct msm_pcm_routing_evt { struct msm_pcm_routing_bdai_data { u16 port_id; /* AFE port ID */ u8 active; /* track if this backend is enabled */ - unsigned long fe_sessions; /* Front-end sessions */ + + /* Front-end sessions */ + unsigned long fe_sessions[BE_DAI_FE_SESSIONS_IDX_MAX]; /* * Track Tx BE ports -> Rx BE ports. * port_sessions[0] used to track BE 0 to BE 63. @@ -415,7 +418,7 @@ struct msm_pcm_routing_bdai_data { unsigned int channel; unsigned int format; unsigned int adm_override_ch; - u32 compr_passthr_mode; + u32 passthr_mode; char *name; }; diff --git a/sound/soc/msm/qdsp6v2/q6adm.c b/sound/soc/msm/qdsp6v2/q6adm.c index 32826d38f65a..16ae05034662 100644 --- a/sound/soc/msm/qdsp6v2/q6adm.c +++ b/sound/soc/msm/qdsp6v2/q6adm.c @@ -2574,7 +2574,6 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, return copp_idx; } - void adm_copp_mfc_cfg(int port_id, int copp_idx, int dst_sample_rate) { struct audproc_mfc_output_media_fmt mfc_cfg; @@ -2677,8 +2676,43 @@ fail_cmd: return; } +static void route_set_opcode_matrix_id( + struct adm_cmd_matrix_map_routings_v5 **route_addr, + int path, uint32_t passthr_mode) +{ + struct adm_cmd_matrix_map_routings_v5 *route = *route_addr; -int adm_matrix_map(int path, struct route_payload payload_map, int perf_mode) + switch (path) { + case ADM_PATH_PLAYBACK: + route->hdr.opcode = ADM_CMD_MATRIX_MAP_ROUTINGS_V5; + route->matrix_id = ADM_MATRIX_ID_AUDIO_RX; + break; + case ADM_PATH_LIVE_REC: + if (passthr_mode == LISTEN) { + route->hdr.opcode = + ADM_CMD_STREAM_DEVICE_MAP_ROUTINGS_V5; + route->matrix_id = ADM_MATRIX_ID_LISTEN_TX; + break; + } + /* fall through to set matrix id for non-listen case */ + case ADM_PATH_NONLIVE_REC: + route->hdr.opcode = ADM_CMD_MATRIX_MAP_ROUTINGS_V5; + route->matrix_id = ADM_MATRIX_ID_AUDIO_TX; + break; + case ADM_PATH_COMPRESSED_RX: + route->hdr.opcode = ADM_CMD_STREAM_DEVICE_MAP_ROUTINGS_V5; + route->matrix_id = ADM_MATRIX_ID_COMPRESSED_AUDIO_RX; + break; + default: + pr_err("%s: Wrong path set[%d]\n", __func__, path); + break; + } + pr_debug("%s: opcode 0x%x, matrix id %d\n", + __func__, route->hdr.opcode, route->matrix_id); +} + +int adm_matrix_map(int path, struct route_payload payload_map, int perf_mode, + uint32_t passthr_mode) { struct adm_cmd_matrix_map_routings_v5 *route; struct adm_session_map_node_v5 *node; @@ -2711,32 +2745,9 @@ int adm_matrix_map(int path, struct route_payload payload_map, int perf_mode) route->hdr.dest_domain = APR_DOMAIN_ADSP; route->hdr.dest_port = 0; /* Ignored */; route->hdr.token = 0; - if (path == ADM_PATH_COMPRESSED_RX) { - pr_debug("%s: ADM_CMD_STREAM_DEVICE_MAP_ROUTINGS_V5 0x%x\n", - __func__, ADM_CMD_STREAM_DEVICE_MAP_ROUTINGS_V5); - route->hdr.opcode = ADM_CMD_STREAM_DEVICE_MAP_ROUTINGS_V5; - } else { - pr_debug("%s: DM_CMD_MATRIX_MAP_ROUTINGS_V5 0x%x\n", - __func__, ADM_CMD_MATRIX_MAP_ROUTINGS_V5); - route->hdr.opcode = ADM_CMD_MATRIX_MAP_ROUTINGS_V5; - } route->num_sessions = 1; + route_set_opcode_matrix_id(&route, path, passthr_mode); - switch (path) { - case ADM_PATH_PLAYBACK: - route->matrix_id = ADM_MATRIX_ID_AUDIO_RX; - break; - case ADM_PATH_LIVE_REC: - case ADM_PATH_NONLIVE_REC: - route->matrix_id = ADM_MATRIX_ID_AUDIO_TX; - break; - case ADM_PATH_COMPRESSED_RX: - route->matrix_id = ADM_MATRIX_ID_COMPRESSED_AUDIO_RX; - break; - default: - pr_err("%s: Wrong path set[%d]\n", __func__, path); - break; - } payload = ((u8 *)matrix_map + sizeof(struct adm_cmd_matrix_map_routings_v5)); node = (struct adm_session_map_node_v5 *)payload; diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c index 9353b2132e15..4fc652f6bab3 100644 --- a/sound/soc/msm/qdsp6v2/q6asm.c +++ b/sound/soc/msm/qdsp6v2/q6asm.c @@ -8343,14 +8343,17 @@ int q6asm_get_apr_service_id(int session_id) int q6asm_get_asm_topology(int session_id) { - int topology; + int topology = -EINVAL; if (session_id <= 0 || session_id > ASM_ACTIVE_STREAMS_ALLOWED) { pr_err("%s: invalid session_id = %d\n", __func__, session_id); - topology = -EINVAL; goto done; } - + if (session[session_id] == NULL) { + pr_err("%s: session not created for session id = %d\n", + __func__, session_id); + goto done; + } topology = session[session_id]->topology; done: return topology; @@ -8358,14 +8361,17 @@ done: int q6asm_get_asm_app_type(int session_id) { - int app_type; + int app_type = -EINVAL; if (session_id <= 0 || session_id > ASM_ACTIVE_STREAMS_ALLOWED) { pr_err("%s: invalid session_id = %d\n", __func__, session_id); - app_type = -EINVAL; goto done; } - + if (session[session_id] == NULL) { + pr_err("%s: session not created for session id = %d\n", + __func__, session_id); + goto done; + } app_type = session[session_id]->app_type; done: return app_type; diff --git a/sound/soc/msm/qdsp6v2/q6lsm.c b/sound/soc/msm/qdsp6v2/q6lsm.c index 5303a312fc57..cba74b0c17ac 100644 --- a/sound/soc/msm/qdsp6v2/q6lsm.c +++ b/sound/soc/msm/qdsp6v2/q6lsm.c @@ -707,29 +707,28 @@ static int q6lsm_send_confidence_levels( return rc; } -static int q6lsm_send_params(struct lsm_client *client, +static int q6lsm_send_param_opmode(struct lsm_client *client, struct lsm_module_param_ids *opmode_ids, - struct lsm_module_param_ids *connectport_ids, u32 set_param_opcode) { int rc; - struct lsm_cmd_set_opmode_connectport opmode_connectport; + struct lsm_cmd_set_params_opmode opmode_params; struct apr_hdr *msg_hdr; - struct lsm_param_connect_to_port *connect_to_port; + struct lsm_param_op_mode *op_mode; u32 data_payload_size, param_size; - msg_hdr = &opmode_connectport.msg_hdr; + msg_hdr = &opmode_params.msg_hdr; q6lsm_add_hdr(client, msg_hdr, - sizeof(opmode_connectport), true); + sizeof(opmode_params), true); msg_hdr->opcode = set_param_opcode; - data_payload_size = sizeof(opmode_connectport) - + data_payload_size = sizeof(opmode_params) - sizeof(*msg_hdr) - - sizeof(opmode_connectport.params_hdr); - q6lsm_set_param_hdr_info(&opmode_connectport.params_hdr, + sizeof(opmode_params.params_hdr); + q6lsm_set_param_hdr_info(&opmode_params.params_hdr, data_payload_size, 0, 0, 0); - connect_to_port = &opmode_connectport.connect_to_port; - op_mode = &opmode_connectport.op_mode; + op_mode = &opmode_params.op_mode; + param_size = sizeof(struct lsm_param_op_mode) - sizeof(op_mode->common); @@ -741,18 +740,8 @@ static int q6lsm_send_params(struct lsm_client *client, op_mode->reserved = 0; pr_debug("%s: mode = 0x%x", __func__, op_mode->mode); - param_size = (sizeof(struct lsm_param_connect_to_port) - - sizeof(connect_to_port->common)); - q6lsm_set_param_common(&connect_to_port->common, - connectport_ids, param_size, - set_param_opcode); - connect_to_port->minor_version = QLSM_PARAM_ID_MINOR_VERSION; - connect_to_port->port_id = client->connect_to_port; - connect_to_port->reserved = 0; - pr_debug("%s: port= %d", __func__, connect_to_port->port_id); - rc = q6lsm_apr_send_pkt(client, client->apr, - &opmode_connectport, true, NULL); + &opmode_params, true, NULL); if (rc) pr_err("%s: Failed set_params opcode 0x%x, rc %d\n", __func__, msg_hdr->opcode, rc); @@ -766,17 +755,106 @@ void set_lsm_port(int lsm_port) lsm_afe_port = lsm_port; } -int get_lsm_port() +int get_lsm_port(void) { return lsm_afe_port; } +int q6lsm_set_port_connected(struct lsm_client *client) +{ + int rc; + struct lsm_cmd_set_connectport connectport; + struct lsm_module_param_ids connectport_ids; + struct apr_hdr *msg_hdr; + struct lsm_param_connect_to_port *connect_to_port; + u32 data_payload_size, param_size, set_param_opcode; + + if (client->use_topology) { + set_param_opcode = LSM_SESSION_CMD_SET_PARAMS_V2; + connectport_ids.module_id = LSM_MODULE_ID_FRAMEWORK; + connectport_ids.param_id = LSM_PARAM_ID_CONNECT_TO_PORT; + } else { + set_param_opcode = LSM_SESSION_CMD_SET_PARAMS; + connectport_ids.module_id = LSM_MODULE_ID_VOICE_WAKEUP; + connectport_ids.param_id = LSM_PARAM_ID_CONNECT_TO_PORT; + } + client->connect_to_port = get_lsm_port(); + + msg_hdr = &connectport.msg_hdr; + q6lsm_add_hdr(client, msg_hdr, + sizeof(connectport), true); + msg_hdr->opcode = set_param_opcode; + data_payload_size = sizeof(connectport) - + sizeof(*msg_hdr) - + sizeof(connectport.params_hdr); + q6lsm_set_param_hdr_info(&connectport.params_hdr, + data_payload_size, 0, 0, 0); + connect_to_port = &connectport.connect_to_port; + + param_size = (sizeof(struct lsm_param_connect_to_port) - + sizeof(connect_to_port->common)); + q6lsm_set_param_common(&connect_to_port->common, + &connectport_ids, param_size, + set_param_opcode); + connect_to_port->minor_version = QLSM_PARAM_ID_MINOR_VERSION; + connect_to_port->port_id = client->connect_to_port; + connect_to_port->reserved = 0; + pr_debug("%s: port= %d", __func__, connect_to_port->port_id); + + rc = q6lsm_apr_send_pkt(client, client->apr, + &connectport, true, NULL); + if (rc) + pr_err("%s: Failed set_params opcode 0x%x, rc %d\n", + __func__, msg_hdr->opcode, rc); + + return rc; +} +static int q6lsm_send_param_polling_enable(struct lsm_client *client, + bool poll_en, + struct lsm_module_param_ids *poll_enable_ids, + u32 set_param_opcode) +{ + int rc = 0; + struct lsm_cmd_poll_enable cmd; + struct apr_hdr *msg_hdr; + struct lsm_param_poll_enable *poll_enable; + u32 data_payload_size, param_size; + + msg_hdr = &cmd.msg_hdr; + q6lsm_add_hdr(client, msg_hdr, + sizeof(struct lsm_cmd_poll_enable), true); + msg_hdr->opcode = set_param_opcode; + data_payload_size = sizeof(struct lsm_cmd_poll_enable) - + sizeof(struct apr_hdr) - + sizeof(struct lsm_set_params_hdr); + q6lsm_set_param_hdr_info(&cmd.params_hdr, + data_payload_size, 0, 0, 0); + poll_enable = &cmd.poll_enable; + + param_size = (sizeof(struct lsm_param_poll_enable) - + sizeof(poll_enable->common)); + q6lsm_set_param_common(&poll_enable->common, + poll_enable_ids, param_size, + set_param_opcode); + poll_enable->minor_version = QLSM_PARAM_ID_MINOR_VERSION; + poll_enable->polling_enable = (poll_en) ? 1 : 0; + pr_debug("%s: poll enable= %d", __func__, poll_enable->polling_enable); + + rc = q6lsm_apr_send_pkt(client, client->apr, + &cmd, true, NULL); + if (rc) + pr_err("%s: Failed set_params opcode 0x%x, rc %d\n", + __func__, msg_hdr->opcode, rc); + + return rc; +} + int q6lsm_set_data(struct lsm_client *client, enum lsm_detection_mode mode, bool detectfailure) { int rc = 0; - struct lsm_module_param_ids opmode_ids, connectport_ids; + struct lsm_module_param_ids opmode_ids; struct lsm_module_param_ids conf_levels_ids; if (!client->confidence_levels) { @@ -800,16 +878,12 @@ int q6lsm_set_data(struct lsm_client *client, goto err_ret; } client->mode |= detectfailure << 2; - client->connect_to_port = get_lsm_port(); opmode_ids.module_id = LSM_MODULE_ID_VOICE_WAKEUP; opmode_ids.param_id = LSM_PARAM_ID_OPERATION_MODE; - connectport_ids.module_id = LSM_MODULE_ID_VOICE_WAKEUP; - connectport_ids.param_id = LSM_PARAM_ID_CONNECT_TO_PORT; - - rc = q6lsm_send_params(client, &opmode_ids, &connectport_ids, - LSM_SESSION_CMD_SET_PARAMS); + rc = q6lsm_send_param_opmode(client, &opmode_ids, + LSM_SESSION_CMD_SET_PARAMS); if (rc) { pr_err("%s: Failed to set lsm config params %d\n", __func__, rc); @@ -1409,7 +1483,6 @@ int q6lsm_set_one_param(struct lsm_client *client, case LSM_OPERATION_MODE: { struct snd_lsm_detect_mode *det_mode = data; struct lsm_module_param_ids opmode_ids; - struct lsm_module_param_ids connectport_ids; if (det_mode->mode == LSM_MODE_KEYWORD_ONLY_DETECTION) { client->mode = 0x01; @@ -1422,16 +1495,12 @@ int q6lsm_set_one_param(struct lsm_client *client, } client->mode |= det_mode->detect_failure << 2; - client->connect_to_port = get_lsm_port(); opmode_ids.module_id = p_info->module_id; opmode_ids.param_id = p_info->param_id; - connectport_ids.module_id = LSM_MODULE_ID_FRAMEWORK; - connectport_ids.param_id = LSM_PARAM_ID_CONNECT_TO_PORT; - - rc = q6lsm_send_params(client, &opmode_ids, &connectport_ids, - LSM_SESSION_CMD_SET_PARAMS_V2); + rc = q6lsm_send_param_opmode(client, &opmode_ids, + LSM_SESSION_CMD_SET_PARAMS_V2); if (rc) pr_err("%s: OPERATION_MODE failed, rc %d\n", __func__, rc); @@ -1458,6 +1527,20 @@ int q6lsm_set_one_param(struct lsm_client *client, pr_err("%s: CONFIDENCE_LEVELS cmd failed, rc %d\n", __func__, rc); break; + case LSM_POLLING_ENABLE: { + struct snd_lsm_poll_enable *lsm_poll_enable = + (struct snd_lsm_poll_enable *) data; + ids.module_id = p_info->module_id; + ids.param_id = p_info->param_id; + rc = q6lsm_send_param_polling_enable(client, + lsm_poll_enable->poll_en, &ids, + LSM_SESSION_CMD_SET_PARAMS_V2); + if (rc) + pr_err("%s: POLLING ENABLE cmd failed, rc %d\n", + __func__, rc); + break; + } + case LSM_REG_SND_MODEL: { struct lsm_cmd_set_params model_param; u32 payload_size;