summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2017-02-03 06:26:34 -0800
committerGerrit - the friendly Code Review server <code-review@localhost>2017-02-03 06:26:33 -0800
commit25c4cbcf138296314103ccdea1225ae151ea3192 (patch)
treeb6fbd4f9c177515deeabe70032802d7571eb216c
parent892e41e7c7758e2d9904b2e13f755e5225c10f0c (diff)
parenta2e395cfb2f71f0f2b45d1ef7b8e70a6e8c86d63 (diff)
Merge "ASoC: msm: qdsp6v2: Add App type cfg support for Listen"
-rw-r--r--include/sound/apr_audio-v2.h10
-rw-r--r--include/sound/cpe_core.h4
-rw-r--r--include/sound/q6adm-v2.h4
-rw-r--r--include/sound/q6lsm.h71
-rw-r--r--include/uapi/sound/lsm_params.h51
-rw-r--r--sound/soc/codecs/wcd_cpe_core.c6
-rw-r--r--sound/soc/msm/msm-cpe-lsm.c4
-rw-r--r--sound/soc/msm/msm-dai-fe.c82
-rw-r--r--sound/soc/msm/qdsp6v2/msm-lsm-client.c523
-rw-r--r--sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c1345
-rw-r--r--sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h9
-rw-r--r--sound/soc/msm/qdsp6v2/q6adm.c63
-rw-r--r--sound/soc/msm/qdsp6v2/q6asm.c18
-rw-r--r--sound/soc/msm/qdsp6v2/q6lsm.c293
14 files changed, 1946 insertions, 537 deletions
diff --git a/include/sound/apr_audio-v2.h b/include/sound/apr_audio-v2.h
index a047a33334d2..1f8bba7e9ab7 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
@@ -9044,6 +9046,7 @@ struct asm_aptx_dec_fmt_blk_v2 {
#define LSM_SESSION_EVENT_DETECTION_STATUS_V2 (0x00012B01)
#define LSM_DATA_EVENT_READ_DONE (0x00012B02)
#define LSM_DATA_EVENT_STATUS (0x00012B03)
+#define LSM_SESSION_EVENT_DETECTION_STATUS_V3 (0x00012B04)
#define LSM_MODULE_ID_VOICE_WAKEUP (0x00012C00)
#define LSM_PARAM_ID_ENDPOINT_DETECT_THRESHOLD (0x00012C01)
@@ -9056,6 +9059,12 @@ 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)
+#define LSM_PARAM_ID_MEDIA_FMT (0x00012C1E)
+#define LSM_PARAM_ID_FWK_MODE_CONFIG (0x00012C27)
/* HW MAD specific */
#define AFE_MODULE_HW_MAD (0x00010230)
@@ -10172,6 +10181,7 @@ enum {
COMPRESSED_PASSTHROUGH,
COMPRESSED_PASSTHROUGH_CONVERT,
COMPRESSED_PASSTHROUGH_DSD,
+ LISTEN,
};
#define AUDPROC_MODULE_ID_COMPRESSED_MUTE 0x00010770
diff --git a/include/sound/cpe_core.h b/include/sound/cpe_core.h
index 323a63fd6238..846cf819b9e5 100644
--- a/include/sound/cpe_core.h
+++ b/include/sound/cpe_core.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2016, Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2017, 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
@@ -162,7 +162,7 @@ struct wcd_cpe_lsm_ops {
int (*lsm_set_one_param)(void *core_handle,
struct cpe_lsm_session *session,
struct lsm_params_info *p_info,
- void *data, enum LSM_PARAM_TYPE param_type);
+ void *data, uint32_t param_type);
void (*lsm_get_snd_model_offset)
(void *core_handle, struct cpe_lsm_session *,
size_t *offset);
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 fb848bc70873..4805246766d6 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-2017, 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,10 @@
#define MAX_NUM_CONFIDENCE 20
+#define ADM_LSM_PORT_ID 0xADCB
+
+#define LSM_MAX_NUM_CHANNELS 8
+
typedef void (*lsm_app_cb)(uint32_t opcode, uint32_t token,
uint32_t *payload, void *priv);
@@ -49,11 +53,12 @@ struct lsm_lab_buffer {
uint32_t mem_map_handle;
};
-struct lsm_lab_hw_params {
+struct lsm_hw_params {
u16 sample_rate;
u16 sample_size;
u32 buf_sz;
u32 period_count;
+ u16 num_chs;
};
struct lsm_client {
@@ -79,8 +84,12 @@ struct lsm_client {
bool lab_enable;
bool lab_started;
struct lsm_lab_buffer *lab_buffer;
- struct lsm_lab_hw_params hw_params;
+ struct lsm_hw_params hw_params;
bool use_topology;
+ int session_state;
+ bool poll_enable;
+ int perf_mode;
+ uint32_t event_mode;
};
struct lsm_stream_cmd_open_tx {
@@ -134,6 +143,27 @@ 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;
+
+struct lsm_param_fwk_mode_cfg {
+ struct lsm_param_payload_common common;
+ uint32_t minor_version;
+ uint32_t mode;
+} __packed;
+
+struct lsm_param_media_fmt {
+ struct lsm_param_payload_common common;
+ uint32_t minor_version;
+ uint32_t sample_rate;
+ uint16_t num_channels;
+ uint16_t bit_width;
+ uint8_t channel_mapping[LSM_MAX_NUM_CHANNELS];
+} __packed;
/*
* This param cannot be sent in this format.
@@ -163,11 +193,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_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_connect_to_port connect_to_port;
- struct lsm_param_op_mode op_mode;
+ struct lsm_param_poll_enable poll_enable;
} __packed;
struct lsm_param_epd_thres {
@@ -250,6 +291,19 @@ struct lsm_cmd_read_done {
uint32_t flags;
} __packed;
+struct lsm_cmd_set_fwk_mode_cfg {
+ struct apr_hdr msg_hdr;
+ struct lsm_set_params_hdr params_hdr;
+ struct lsm_param_fwk_mode_cfg fwk_mode_cfg;
+} __packed;
+
+struct lsm_cmd_set_media_fmt {
+ struct apr_hdr msg_hdr;
+ struct lsm_set_params_hdr params_hdr;
+ struct lsm_param_media_fmt media_fmt;
+} __packed;
+
+
struct lsm_client *q6lsm_client_alloc(lsm_app_cb cb, void *priv);
void q6lsm_client_free(struct lsm_client *client);
int q6lsm_open(struct lsm_client *client, uint16_t app_id);
@@ -274,8 +328,11 @@ int q6lsm_read(struct lsm_client *client, struct lsm_cmd_read *read);
int q6lsm_lab_buffer_alloc(struct lsm_client *client, bool alloc);
int q6lsm_set_one_param(struct lsm_client *client,
struct lsm_params_info *p_info, void *data,
- enum LSM_PARAM_TYPE param_type);
+ uint32_t param_type);
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);
+int q6lsm_set_fwk_mode_cfg(struct lsm_client *client, uint32_t event_mode);
+int q6lsm_set_media_fmt_params(struct lsm_client *client);
#endif /* __Q6LSM_H__ */
diff --git a/include/uapi/sound/lsm_params.h b/include/uapi/sound/lsm_params.h
index eafdc117413a..9ca5930475ba 100644
--- a/include/uapi/sound/lsm_params.h
+++ b/include/uapi/sound/lsm_params.h
@@ -1,6 +1,9 @@
#ifndef _UAPI_LSM_PARAMS_H__
#define _UAPI_LSM_PARAMS_H__
+#define LSM_POLLING_ENABLE_SUPPORT
+#define LSM_EVENT_TIMESTAMP_MODE_SUPPORT
+
#include <linux/types.h>
#include <sound/asound.h>
@@ -18,6 +21,19 @@
#define LSM_OUT_TRANSFER_MODE_RT (0)
#define LSM_OUT_TRANSFER_MODE_FTRT (1)
+#define LSM_ENDPOINT_DETECT_THRESHOLD (0)
+#define LSM_OPERATION_MODE (1)
+#define LSM_GAIN (2)
+#define LSM_MIN_CONFIDENCE_LEVELS (3)
+#define LSM_REG_SND_MODEL (4)
+#define LSM_DEREG_SND_MODEL (5)
+#define LSM_CUSTOM_PARAMS (6)
+#define LSM_POLLING_ENABLE (7)
+#define LSM_PARAMS_MAX (LSM_POLLING_ENABLE + 1)
+
+#define LSM_EVENT_NON_TIME_STAMP_MODE (0)
+#define LSM_EVENT_TIME_STAMP_MODE (1)
+
enum lsm_app_id {
LSM_VOICE_WAKEUP_APP_ID = 1,
LSM_VOICE_WAKEUP_APP_ID_V2 = 2,
@@ -35,18 +51,6 @@ enum lsm_vw_status {
LSM_VOICE_WAKEUP_STATUS_REJECTED
};
-enum LSM_PARAM_TYPE {
- LSM_ENDPOINT_DETECT_THRESHOLD = 0,
- LSM_OPERATION_MODE,
- LSM_GAIN,
- LSM_MIN_CONFIDENCE_LEVELS,
- LSM_REG_SND_MODEL,
- LSM_DEREG_SND_MODEL,
- LSM_CUSTOM_PARAMS,
- /* driver ioctl will parse only so many params */
- LSM_PARAMS_MAX,
-};
-
/*
* Data for LSM_ENDPOINT_DETECT_THRESHOLD param_type
* @epd_begin: Begin threshold
@@ -75,6 +79,14 @@ struct snd_lsm_gain {
__u16 gain;
};
+/*
+ * Data for LSM_POLLING_ENABLE param_type
+ * @poll_en: Polling enable or disable
+ */
+struct snd_lsm_poll_enable {
+ bool poll_en;
+};
+
struct snd_lsm_sound_model_v2 {
__u8 __user *data;
@@ -95,11 +107,20 @@ struct snd_lsm_event_status {
__u8 payload[0];
};
+struct snd_lsm_event_status_v3 {
+ __u32 timestamp_lsw;
+ __u32 timestamp_msw;
+ __u16 status;
+ __u16 payload_size;
+ __u8 payload[0];
+};
+
struct snd_lsm_detection_params {
__u8 *conf_level;
enum lsm_detection_mode detect_mode;
__u8 num_confidence_levels;
bool detect_failure;
+ bool poll_enable;
};
/*
@@ -122,7 +143,7 @@ struct lsm_params_info {
__u32 param_id;
__u32 param_size;
__u8 __user *param_data;
- enum LSM_PARAM_TYPE param_type;
+ uint32_t param_type;
};
/*
@@ -171,5 +192,9 @@ struct snd_lsm_output_format_cfg {
struct snd_lsm_module_params)
#define SNDRV_LSM_OUT_FORMAT_CFG _IOW('U', 0x0C, \
struct snd_lsm_output_format_cfg)
+#define SNDRV_LSM_SET_PORT _IO('U', 0x0D)
+#define SNDRV_LSM_SET_FWK_MODE_CONFIG _IOW('U', 0x0E, uint32_t)
+#define SNDRV_LSM_EVENT_STATUS_V3 _IOW('U', 0x0F, \
+ struct snd_lsm_event_status_v3)
#endif
diff --git a/sound/soc/codecs/wcd_cpe_core.c b/sound/soc/codecs/wcd_cpe_core.c
index 2088698392de..3fc021b68122 100644
--- a/sound/soc/codecs/wcd_cpe_core.c
+++ b/sound/soc/codecs/wcd_cpe_core.c
@@ -3029,7 +3029,7 @@ err_ret:
static int wcd_cpe_set_one_param(void *core_handle,
struct cpe_lsm_session *session, struct lsm_params_info *p_info,
- void *data, enum LSM_PARAM_TYPE param_type)
+ void *data, uint32_t param_type)
{
struct wcd_cpe_core *core = core_handle;
int rc = 0;
@@ -3081,13 +3081,13 @@ static int wcd_cpe_set_one_param(void *core_handle,
break;
default:
pr_err("%s: wrong param_type 0x%x\n",
- __func__, p_info->param_type);
+ __func__, param_type);
}
if (rc)
dev_err(core->dev,
"%s: send_param(%d) failed, err %d\n",
- __func__, p_info->param_type, rc);
+ __func__, param_type, rc);
return rc;
}
diff --git a/sound/soc/msm/msm-cpe-lsm.c b/sound/soc/msm/msm-cpe-lsm.c
index ffc6119e543d..5ea54c34d7f4 100644
--- a/sound/soc/msm/msm-cpe-lsm.c
+++ b/sound/soc/msm/msm-cpe-lsm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2016, Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2017, 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
@@ -2297,7 +2297,7 @@ struct lsm_params_info_32 {
u32 param_id;
u32 param_size;
compat_uptr_t param_data;
- enum LSM_PARAM_TYPE param_type;
+ uint32_t param_type;
};
struct snd_lsm_module_params_32 {
diff --git a/sound/soc/msm/msm-dai-fe.c b/sound/soc/msm/msm-dai-fe.c
index 6c1897340e74..44a6a245c7a2 100644
--- a/sound/soc/msm/msm-dai-fe.c
+++ b/sound/soc/msm/msm-dai-fe.c
@@ -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
@@ -2203,12 +2203,14 @@ static struct snd_soc_dai_driver msm_fe_dais[] = {
.capture = {
.stream_name = "Listen 1 Audio Service Capture",
.aif_name = "LSM1_UL_HL",
- .rates = SNDRV_PCM_RATE_16000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .rates = (SNDRV_PCM_RATE_16000 |
+ SNDRV_PCM_RATE_48000),
+ .formats = (SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE),
.channels_min = 1,
- .channels_max = 1,
+ .channels_max = 4,
.rate_min = 16000,
- .rate_max = 16000,
+ .rate_max = 48000,
},
.ops = &msm_fe_dai_ops,
.name = "LSM1",
@@ -2218,12 +2220,14 @@ static struct snd_soc_dai_driver msm_fe_dais[] = {
.capture = {
.stream_name = "Listen 2 Audio Service Capture",
.aif_name = "LSM2_UL_HL",
- .rates = SNDRV_PCM_RATE_16000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .rates = (SNDRV_PCM_RATE_16000 |
+ SNDRV_PCM_RATE_48000),
+ .formats = (SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE),
.channels_min = 1,
- .channels_max = 1,
+ .channels_max = 4,
.rate_min = 16000,
- .rate_max = 16000,
+ .rate_max = 48000,
},
.ops = &msm_fe_dai_ops,
.name = "LSM2",
@@ -2233,12 +2237,14 @@ static struct snd_soc_dai_driver msm_fe_dais[] = {
.capture = {
.stream_name = "Listen 3 Audio Service Capture",
.aif_name = "LSM3_UL_HL",
- .rates = SNDRV_PCM_RATE_16000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .rates = (SNDRV_PCM_RATE_16000 |
+ SNDRV_PCM_RATE_48000),
+ .formats = (SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE),
.channels_min = 1,
- .channels_max = 1,
+ .channels_max = 4,
.rate_min = 16000,
- .rate_max = 16000,
+ .rate_max = 48000,
},
.ops = &msm_fe_dai_ops,
.name = "LSM3",
@@ -2248,12 +2254,14 @@ static struct snd_soc_dai_driver msm_fe_dais[] = {
.capture = {
.stream_name = "Listen 4 Audio Service Capture",
.aif_name = "LSM4_UL_HL",
- .rates = SNDRV_PCM_RATE_16000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .rates = (SNDRV_PCM_RATE_16000 |
+ SNDRV_PCM_RATE_48000),
+ .formats = (SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE),
.channels_min = 1,
- .channels_max = 1,
+ .channels_max = 4,
.rate_min = 16000,
- .rate_max = 16000,
+ .rate_max = 48000,
},
.ops = &msm_fe_dai_ops,
.name = "LSM4",
@@ -2263,12 +2271,14 @@ static struct snd_soc_dai_driver msm_fe_dais[] = {
.capture = {
.stream_name = "Listen 5 Audio Service Capture",
.aif_name = "LSM5_UL_HL",
- .rates = SNDRV_PCM_RATE_16000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .rates = (SNDRV_PCM_RATE_16000 |
+ SNDRV_PCM_RATE_48000),
+ .formats = (SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE),
.channels_min = 1,
- .channels_max = 1,
+ .channels_max = 4,
.rate_min = 16000,
- .rate_max = 16000,
+ .rate_max = 48000,
},
.ops = &msm_fe_dai_ops,
.name = "LSM5",
@@ -2278,12 +2288,14 @@ static struct snd_soc_dai_driver msm_fe_dais[] = {
.capture = {
.stream_name = "Listen 6 Audio Service Capture",
.aif_name = "LSM6_UL_HL",
- .rates = SNDRV_PCM_RATE_16000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .rates = (SNDRV_PCM_RATE_16000 |
+ SNDRV_PCM_RATE_48000),
+ .formats = (SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE),
.channels_min = 1,
- .channels_max = 1,
+ .channels_max = 4,
.rate_min = 16000,
- .rate_max = 16000,
+ .rate_max = 48000,
},
.ops = &msm_fe_dai_ops,
.name = "LSM6",
@@ -2293,12 +2305,14 @@ static struct snd_soc_dai_driver msm_fe_dais[] = {
.capture = {
.stream_name = "Listen 7 Audio Service Capture",
.aif_name = "LSM7_UL_HL",
- .rates = SNDRV_PCM_RATE_16000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .rates = (SNDRV_PCM_RATE_16000 |
+ SNDRV_PCM_RATE_48000),
+ .formats = (SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE),
.channels_min = 1,
- .channels_max = 1,
+ .channels_max = 4,
.rate_min = 16000,
- .rate_max = 16000,
+ .rate_max = 48000,
},
.ops = &msm_fe_dai_ops,
.name = "LSM7",
@@ -2308,12 +2322,14 @@ static struct snd_soc_dai_driver msm_fe_dais[] = {
.capture = {
.stream_name = "Listen 8 Audio Service Capture",
.aif_name = "LSM8_UL_HL",
- .rates = SNDRV_PCM_RATE_16000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .rates = (SNDRV_PCM_RATE_16000 |
+ SNDRV_PCM_RATE_48000),
+ .formats = (SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE),
.channels_min = 1,
- .channels_max = 1,
+ .channels_max = 4,
.rate_min = 16000,
- .rate_max = 16000,
+ .rate_max = 48000,
},
.ops = &msm_fe_dai_ops,
.name = "LSM8",
diff --git a/sound/soc/msm/qdsp6v2/msm-lsm-client.c b/sound/soc/msm/qdsp6v2/msm-lsm-client.c
index efb6644e551f..55ca659567f5 100644
--- a/sound/soc/msm/qdsp6v2/msm-lsm-client.c
+++ b/sound/soc/msm/qdsp6v2/msm-lsm-client.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2015, Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2017, 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
@@ -35,7 +35,7 @@
#define CAPTURE_MIN_NUM_PERIODS 2
#define CAPTURE_MAX_NUM_PERIODS 8
-#define CAPTURE_MAX_PERIOD_SIZE 4096
+#define CAPTURE_MAX_PERIOD_SIZE 61440
#define CAPTURE_MIN_PERIOD_SIZE 320
#define LISTEN_MAX_STATUS_PAYLOAD_SIZE 256
@@ -47,12 +47,14 @@ static struct snd_pcm_hardware msm_pcm_hardware_capture = {
SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME),
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_16000,
+ .formats = (SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE),
+ .rates = (SNDRV_PCM_RATE_16000 |
+ SNDRV_PCM_RATE_48000),
.rate_min = 16000,
- .rate_max = 16000,
+ .rate_max = 48000,
.channels_min = 1,
- .channels_max = 1,
+ .channels_max = 4,
.buffer_bytes_max = CAPTURE_MAX_NUM_PERIODS *
CAPTURE_MAX_PERIOD_SIZE,
.period_bytes_min = CAPTURE_MIN_PERIOD_SIZE,
@@ -64,7 +66,7 @@ static struct snd_pcm_hardware msm_pcm_hardware_capture = {
/* Conventional and unconventional sample rate supported */
static unsigned int supported_sample_rates[] = {
- 16000,
+ 16000, 48000,
};
static struct snd_pcm_hw_constraint_list constraints_sample_rates = {
@@ -76,7 +78,7 @@ static struct snd_pcm_hw_constraint_list constraints_sample_rates = {
struct lsm_priv {
struct snd_pcm_substream *substream;
struct lsm_client *lsm_client;
- struct snd_lsm_event_status *event_status;
+ struct snd_lsm_event_status_v3 *event_status;
spinlock_t event_lock;
wait_queue_head_t event_wait;
unsigned long event_avail;
@@ -88,6 +90,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;
@@ -196,6 +203,8 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token,
uint16_t status = 0;
uint16_t payload_size = 0;
uint16_t index = 0;
+ uint32_t event_ts_lsw = 0;
+ uint32_t event_ts_msw = 0;
if (!substream || !substream->private_data) {
pr_err("%s: Invalid %s\n", __func__,
@@ -269,24 +278,44 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token,
"%s: event detect status = %d payload size = %d\n",
__func__, status , payload_size);
break;
+
+ case LSM_SESSION_EVENT_DETECTION_STATUS_V3:
+ event_ts_lsw = ((uint32_t *)payload)[0];
+ event_ts_msw = ((uint32_t *)payload)[1];
+ status = (uint16_t)((uint8_t *)payload)[8];
+ payload_size = (uint16_t)((uint8_t *)payload)[9];
+ index = 10;
+ dev_dbg(rtd->dev,
+ "%s: ts_msw = %u, ts_lsw = %u, event detect status = %d payload size = %d\n",
+ __func__, event_ts_msw, event_ts_lsw, status,
+ payload_size);
+ break;
+
default:
break;
}
if (opcode == LSM_SESSION_EVENT_DETECTION_STATUS ||
- opcode == LSM_SESSION_EVENT_DETECTION_STATUS_V2) {
+ opcode == LSM_SESSION_EVENT_DETECTION_STATUS_V2 ||
+ opcode == LSM_SESSION_EVENT_DETECTION_STATUS_V3) {
spin_lock_irqsave(&prtd->event_lock, flags);
prtd->event_status = krealloc(prtd->event_status,
- sizeof(struct snd_lsm_event_status) +
+ sizeof(struct snd_lsm_event_status_v3) +
payload_size, GFP_ATOMIC);
if (!prtd->event_status) {
dev_err(rtd->dev, "%s: no memory for event status\n",
__func__);
return;
}
-
+ /*
+ * event status timestamp will be non-zero and valid if
+ * opcode is LSM_SESSION_EVENT_DETECTION_STATUS_V3
+ */
+ prtd->event_status->timestamp_lsw = event_ts_lsw;
+ prtd->event_status->timestamp_msw = event_ts_msw;
prtd->event_status->status = status;
prtd->event_status->payload_size = payload_size;
+
if (likely(prtd->event_status)) {
memcpy(prtd->event_status->payload,
&((uint8_t *)payload)[index],
@@ -641,6 +670,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 +758,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",
@@ -710,10 +790,8 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream,
struct snd_lsm_session_data session_data;
int rc = 0;
int xchg = 0;
- u32 size = 0;
struct snd_pcm_runtime *runtime;
struct lsm_priv *prtd;
- struct snd_lsm_event_status *user = arg;
struct snd_lsm_detection_params det_params;
uint8_t *confidence_level = NULL;
@@ -870,6 +948,10 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream,
break;
case SNDRV_LSM_EVENT_STATUS:
+ case SNDRV_LSM_EVENT_STATUS_V3: {
+ uint32_t ts_lsw, ts_msw;
+ uint16_t status = 0, payload_size = 0;
+
dev_dbg(rtd->dev, "%s: Get event status\n", __func__);
atomic_set(&prtd->event_wait_stop, 0);
rc = wait_event_freezable(prtd->event_wait,
@@ -882,9 +964,12 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream,
dev_dbg(rtd->dev, "%s: New event available %ld\n",
__func__, prtd->event_avail);
spin_lock_irqsave(&prtd->event_lock, flags);
+
if (prtd->event_status) {
- size = sizeof(*(prtd->event_status)) +
- prtd->event_status->payload_size;
+ payload_size = prtd->event_status->payload_size;
+ ts_lsw = prtd->event_status->timestamp_lsw;
+ ts_msw = prtd->event_status->timestamp_msw;
+ status = prtd->event_status->status;
spin_unlock_irqrestore(&prtd->event_lock,
flags);
} else {
@@ -896,15 +981,43 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream,
__func__);
break;
}
- if (user->payload_size <
- prtd->event_status->payload_size) {
- dev_dbg(rtd->dev,
- "%s: provided %d bytes isn't enough, needs %d bytes\n",
- __func__, user->payload_size,
- prtd->event_status->payload_size);
- rc = -ENOMEM;
+
+ if (cmd == SNDRV_LSM_EVENT_STATUS) {
+ struct snd_lsm_event_status *user = arg;
+
+ if (user->payload_size < payload_size) {
+ dev_dbg(rtd->dev,
+ "%s: provided %d bytes isn't enough, needs %d bytes\n",
+ __func__, user->payload_size,
+ payload_size);
+ rc = -ENOMEM;
+ } else {
+ user->status = status;
+ user->payload_size = payload_size;
+ memcpy(user->payload,
+ prtd->event_status->payload,
+ payload_size);
+ }
} else {
- memcpy(user, prtd->event_status, size);
+ struct snd_lsm_event_status_v3 *user_v3 = arg;
+
+ if (user_v3->payload_size < payload_size) {
+ dev_dbg(rtd->dev,
+ "%s: provided %d bytes isn't enough, needs %d bytes\n",
+ __func__, user_v3->payload_size,
+ payload_size);
+ rc = -ENOMEM;
+ } else {
+ user_v3->timestamp_lsw = ts_lsw;
+ user_v3->timestamp_msw = ts_msw;
+ user_v3->status = status;
+ user_v3->payload_size = payload_size;
+ memcpy(user_v3->payload,
+ prtd->event_status->payload,
+ payload_size);
+ }
+ }
+ if (!rc) {
if (prtd->lsm_client->lab_enable
&& !prtd->lsm_client->lab_started
&& prtd->event_status->status ==
@@ -929,6 +1042,7 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream,
rc = 0;
}
break;
+ }
case SNDRV_LSM_ABORT_EVENT:
dev_dbg(rtd->dev, "%s: Aborting event status wait\n",
@@ -1035,6 +1149,43 @@ 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;
+
+ case SNDRV_LSM_SET_FWK_MODE_CONFIG: {
+ u32 *mode = NULL;
+
+ if (!arg) {
+ dev_err(rtd->dev,
+ "%s: Invalid param arg for ioctl %s session %d\n",
+ __func__, "SNDRV_LSM_SET_FWK_MODE_CONFIG",
+ prtd->lsm_client->session);
+ rc = -EINVAL;
+ break;
+ }
+ mode = (u32 *)arg;
+ if (prtd->lsm_client->event_mode == *mode) {
+ dev_dbg(rtd->dev,
+ "%s: mode for %d already set to %d\n",
+ __func__, prtd->lsm_client->session, *mode);
+ rc = 0;
+ } else {
+ dev_dbg(rtd->dev, "%s: Event mode = %d\n",
+ __func__, *mode);
+ rc = q6lsm_set_fwk_mode_cfg(prtd->lsm_client, *mode);
+ if (!rc)
+ prtd->lsm_client->event_mode = *mode;
+ else
+ dev_err(rtd->dev,
+ "%s: set event mode failed %d\n",
+ __func__, rc);
+ }
+ break;
+ }
+
default:
dev_dbg(rtd->dev,
"%s: Falling into default snd_lib_ioctl cmd 0x%x\n",
@@ -1053,6 +1204,21 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream,
return rc;
}
#ifdef CONFIG_COMPAT
+
+struct snd_lsm_event_status32 {
+ u16 status;
+ u16 payload_size;
+ u8 payload[0];
+};
+
+struct snd_lsm_event_status_v3_32 {
+ u32 timestamp_lsw;
+ u32 timestamp_msw;
+ u16 status;
+ u16 payload_size;
+ u8 payload[0];
+};
+
struct snd_lsm_sound_model_v2_32 {
compat_uptr_t data;
compat_uptr_t confidence_level;
@@ -1074,7 +1240,7 @@ struct lsm_params_info_32 {
u32 param_id;
u32 param_size;
compat_uptr_t param_data;
- enum LSM_PARAM_TYPE param_type;
+ uint32_t param_type;
};
struct snd_lsm_module_params_32 {
@@ -1090,6 +1256,8 @@ enum {
_IOW('U', 0x0A, struct snd_lsm_detection_params_32),
SNDRV_LSM_SET_MODULE_PARAMS_32 =
_IOW('U', 0x0B, struct snd_lsm_module_params_32),
+ SNDRV_LSM_EVENT_STATUS_V3_32 =
+ _IOW('U', 0x0F, struct snd_lsm_event_status_v3_32),
};
static int msm_lsm_ioctl_compat(struct snd_pcm_substream *substream,
@@ -1178,6 +1346,73 @@ static int msm_lsm_ioctl_compat(struct snd_pcm_substream *substream,
break;
}
+ case SNDRV_LSM_EVENT_STATUS_V3_32: {
+ struct snd_lsm_event_status_v3_32 userarg32, *user32 = NULL;
+ struct snd_lsm_event_status_v3 *user = NULL;
+
+ if (copy_from_user(&userarg32, arg, sizeof(userarg32))) {
+ dev_err(rtd->dev, "%s: err copyuser ioctl %s\n",
+ __func__, "SNDRV_LSM_EVENT_STATUS_V3_32");
+ return -EFAULT;
+ }
+
+ if (userarg32.payload_size >
+ LISTEN_MAX_STATUS_PAYLOAD_SIZE) {
+ pr_err("%s: payload_size %d is invalid, max allowed = %d\n",
+ __func__, userarg32.payload_size,
+ LISTEN_MAX_STATUS_PAYLOAD_SIZE);
+ return -EINVAL;
+ }
+
+ size = sizeof(*user) + userarg32.payload_size;
+ user = kmalloc(size, GFP_KERNEL);
+ if (!user) {
+ dev_err(rtd->dev,
+ "%s: Allocation failed event status size %d\n",
+ __func__, size);
+ return -EFAULT;
+ }
+ cmd = SNDRV_LSM_EVENT_STATUS_V3;
+ user->payload_size = userarg32.payload_size;
+ err = msm_lsm_ioctl_shared(substream, cmd, user);
+
+ /* Update size with actual payload size */
+ size = sizeof(userarg32) + user->payload_size;
+ if (!err && !access_ok(VERIFY_WRITE, arg, size)) {
+ dev_err(rtd->dev,
+ "%s: write verify failed size %d\n",
+ __func__, size);
+ err = -EFAULT;
+ }
+ if (!err) {
+ user32 = kmalloc(size, GFP_KERNEL);
+ if (!user32) {
+ dev_err(rtd->dev,
+ "%s: Allocation event user status size %d\n",
+ __func__, size);
+ err = -EFAULT;
+ } else {
+ user32->timestamp_lsw = user->timestamp_lsw;
+ user32->timestamp_msw = user->timestamp_msw;
+ user32->status = user->status;
+ user32->payload_size = user->payload_size;
+ memcpy(user32->payload,
+ user->payload, user32->payload_size);
+ }
+ }
+ if (!err && (copy_to_user(arg, user32, size))) {
+ dev_err(rtd->dev, "%s: failed to copy payload %d",
+ __func__, size);
+ err = -EFAULT;
+ }
+ kfree(user);
+ kfree(user32);
+ if (err)
+ dev_err(rtd->dev, "%s: lsmevent failed %d",
+ __func__, err);
+ break;
+ }
+
case SNDRV_LSM_REG_SND_MODEL_V2_32: {
struct snd_lsm_sound_model_v2_32 snd_modelv232;
struct snd_lsm_sound_model_v2 snd_modelv2;
@@ -1573,6 +1808,67 @@ static int msm_lsm_ioctl(struct snd_pcm_substream *substream,
"%s: lsmevent failed %d", __func__, err);
return err;
}
+
+ case SNDRV_LSM_EVENT_STATUS_V3: {
+ struct snd_lsm_event_status_v3 *user = NULL;
+ struct snd_lsm_event_status_v3 userarg;
+
+ dev_dbg(rtd->dev,
+ "%s: SNDRV_LSM_EVENT_STATUS_V3\n", __func__);
+ if (!arg) {
+ dev_err(rtd->dev,
+ "%s: Invalid params event_status_v3\n",
+ __func__);
+ return -EINVAL;
+ }
+ if (copy_from_user(&userarg, arg, sizeof(userarg))) {
+ dev_err(rtd->dev,
+ "%s: err copyuser event_status_v3\n",
+ __func__);
+ return -EFAULT;
+ }
+
+ if (userarg.payload_size >
+ LISTEN_MAX_STATUS_PAYLOAD_SIZE) {
+ pr_err("%s: payload_size %d is invalid, max allowed = %d\n",
+ __func__, userarg.payload_size,
+ LISTEN_MAX_STATUS_PAYLOAD_SIZE);
+ return -EINVAL;
+ }
+
+ size = sizeof(struct snd_lsm_event_status_v3) +
+ userarg.payload_size;
+ user = kmalloc(size, GFP_KERNEL);
+ if (!user) {
+ dev_err(rtd->dev,
+ "%s: Allocation failed event status size %d\n",
+ __func__, size);
+ return -EFAULT;
+ }
+ user->payload_size = userarg.payload_size;
+ err = msm_lsm_ioctl_shared(substream, cmd, user);
+
+ /* Update size with actual payload size */
+ size = sizeof(*user) + user->payload_size;
+ if (!err && !access_ok(VERIFY_WRITE, arg, size)) {
+ dev_err(rtd->dev,
+ "%s: write verify failed size %d\n",
+ __func__, size);
+ err = -EFAULT;
+ }
+ if (!err && (copy_to_user(arg, user, size))) {
+ dev_err(rtd->dev,
+ "%s: failed to copy payload %d",
+ __func__, size);
+ err = -EFAULT;
+ }
+ kfree(user);
+ if (err)
+ dev_err(rtd->dev,
+ "%s: lsm_event_v3 failed %d", __func__, err);
+ break;
+ }
+
default:
err = msm_lsm_ioctl_shared(substream, cmd, arg);
break;
@@ -1640,6 +1936,11 @@ 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;
+ prtd->lsm_client->event_mode = LSM_EVENT_NON_TIME_STAMP_MODE;
+
return 0;
}
@@ -1648,6 +1949,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 +1963,30 @@ static int msm_lsm_prepare(struct snd_pcm_substream *substream)
"%s: LSM client data ptr is NULL\n", __func__);
return -EINVAL;
}
+
+ if (q6lsm_set_media_fmt_params(prtd->lsm_client))
+ dev_dbg(rtd->dev,
+ "%s: failed to set lsm media fmt params\n", __func__);
+
+ 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 +2035,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;
@@ -1733,7 +2059,7 @@ static int msm_lsm_hw_params(struct snd_pcm_substream *substream,
{
struct snd_pcm_runtime *runtime = substream->runtime;
struct lsm_priv *prtd = runtime->private_data;
- struct lsm_lab_hw_params *hw_params = NULL;
+ struct lsm_hw_params *hw_params = NULL;
struct snd_soc_pcm_runtime *rtd;
if (!substream->private_data) {
@@ -1749,25 +2075,36 @@ static int msm_lsm_hw_params(struct snd_pcm_substream *substream,
return -EINVAL;
}
hw_params = &prtd->lsm_client->hw_params;
- hw_params->sample_rate = params_rate(params);
- hw_params->sample_size =
- (params_format(params) == SNDRV_PCM_FORMAT_S16_LE) ? 16 : 0;
+ hw_params->num_chs = params_channels(params);
hw_params->period_count = params_periods(params);
- if (hw_params->sample_rate != 16000 || hw_params->sample_size != 16 ||
- hw_params->period_count == 0) {
+ hw_params->sample_rate = params_rate(params);
+ if (((hw_params->sample_rate != 16000) &&
+ (hw_params->sample_rate != 48000)) ||
+ (hw_params->period_count == 0)) {
dev_err(rtd->dev,
- "%s: Invalid params sample rate %d sample size %d period count %d",
+ "%s: Invalid Params sample rate %d period count %d\n",
__func__, hw_params->sample_rate,
- hw_params->sample_size,
- hw_params->period_count);
+ hw_params->period_count);
return -EINVAL;
}
+
+ if (params_format(params) == SNDRV_PCM_FORMAT_S16_LE) {
+ hw_params->sample_size = 16;
+ } else if (params_format(params) == SNDRV_PCM_FORMAT_S24_LE) {
+ hw_params->sample_size = 24;
+ } else {
+ dev_err(rtd->dev, "%s: Invalid Format 0x%x\n",
+ __func__, params_format(params));
+ return -EINVAL;
+ }
+
hw_params->buf_sz = params_buffer_bytes(params) /
- hw_params->period_count;
+ hw_params->period_count;
dev_dbg(rtd->dev,
- "%s: sample rate %d sample size %d buffer size %d period count %d\n",
- __func__, hw_params->sample_rate, hw_params->sample_size,
- hw_params->buf_sz, hw_params->period_count);
+ "%s: channels %d sample rate %d sample size %d buffer size %d period count %d\n",
+ __func__, hw_params->num_chs, hw_params->sample_rate,
+ hw_params->sample_size, hw_params->buf_sz,
+ hw_params->period_count);
return 0;
}
@@ -1863,6 +2200,109 @@ static int msm_lsm_pcm_copy(struct snd_pcm_substream *substream, int ch,
return 0;
}
+static int msm_lsm_app_type_cfg_ctl_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ u64 fe_id = kcontrol->private_value;
+ int app_type;
+ int acdb_dev_id;
+ int sample_rate;
+
+ pr_debug("%s: fe_id- %llu\n", __func__, fe_id);
+ if ((fe_id < MSM_FRONTEND_DAI_LSM1) ||
+ (fe_id > MSM_FRONTEND_DAI_LSM8)) {
+ pr_err("%s: Received out of bounds fe_id %llu\n",
+ __func__, fe_id);
+ return -EINVAL;
+ }
+
+ app_type = ucontrol->value.integer.value[0];
+ acdb_dev_id = ucontrol->value.integer.value[1];
+ sample_rate = ucontrol->value.integer.value[2];
+
+ pr_debug("%s: app_type- %d acdb_dev_id- %d sample_rate- %d session_type- %d\n",
+ __func__, app_type, acdb_dev_id, sample_rate, SESSION_TYPE_TX);
+ msm_pcm_routing_reg_stream_app_type_cfg(fe_id, app_type,
+ acdb_dev_id, sample_rate, SESSION_TYPE_TX);
+
+ return 0;
+}
+
+static int msm_lsm_app_type_cfg_ctl_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ u64 fe_id = kcontrol->private_value;
+ int ret = 0;
+ int app_type;
+ int acdb_dev_id;
+ int sample_rate;
+
+ pr_debug("%s: fe_id- %llu\n", __func__, fe_id);
+ if ((fe_id < MSM_FRONTEND_DAI_LSM1) ||
+ (fe_id > MSM_FRONTEND_DAI_LSM8)) {
+ pr_err("%s: Received out of bounds fe_id %llu\n",
+ __func__, fe_id);
+ return -EINVAL;
+ }
+
+ ret = msm_pcm_routing_get_stream_app_type_cfg(fe_id, SESSION_TYPE_TX,
+ &app_type, &acdb_dev_id, &sample_rate);
+ if (ret < 0) {
+ pr_err("%s: msm_pcm_routing_get_stream_app_type_cfg failed returned %d\n",
+ __func__, ret);
+ goto done;
+ }
+
+ ucontrol->value.integer.value[0] = app_type;
+ ucontrol->value.integer.value[1] = acdb_dev_id;
+ ucontrol->value.integer.value[2] = sample_rate;
+ pr_debug("%s: fedai_id %llu, session_type %d, app_type %d, acdb_dev_id %d, sample_rate %d\n",
+ __func__, fe_id, SESSION_TYPE_TX,
+ app_type, acdb_dev_id, sample_rate);
+done:
+ return ret;
+}
+
+static int msm_lsm_add_app_type_controls(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_pcm *pcm = rtd->pcm;
+ struct snd_pcm_usr *app_type_info;
+ struct snd_kcontrol *kctl;
+ const char *mixer_ctl_name = "Listen Stream";
+ const char *deviceNo = "NN";
+ const char *suffix = "App Type Cfg";
+ int ctl_len, ret = 0;
+
+ ctl_len = strlen(mixer_ctl_name) + 1 +
+ strlen(deviceNo) + 1 + strlen(suffix) + 1;
+ pr_debug("%s: Listen app type cntrl add\n", __func__);
+ ret = snd_pcm_add_usr_ctls(pcm, SNDRV_PCM_STREAM_CAPTURE,
+ NULL, 1, ctl_len, rtd->dai_link->be_id,
+ &app_type_info);
+ if (ret < 0) {
+ pr_err("%s: Listen app type cntrl add failed: %d\n",
+ __func__, ret);
+ return ret;
+ }
+ kctl = app_type_info->kctl;
+ snprintf(kctl->id.name, ctl_len, "%s %d %s",
+ mixer_ctl_name, rtd->pcm->device, suffix);
+ kctl->put = msm_lsm_app_type_cfg_ctl_put;
+ kctl->get = msm_lsm_app_type_cfg_ctl_get;
+ return 0;
+}
+
+static int msm_lsm_add_controls(struct snd_soc_pcm_runtime *rtd)
+{
+ int ret = 0;
+
+ ret = msm_lsm_add_app_type_controls(rtd);
+ if (ret)
+ pr_err("%s, add app type controls failed:%d\n", __func__, ret);
+
+ return ret;
+}
+
static struct snd_pcm_ops msm_lsm_ops = {
.open = msm_lsm_open,
.close = msm_lsm_close,
@@ -1877,11 +2317,16 @@ static struct snd_pcm_ops msm_lsm_ops = {
static int msm_asoc_lsm_new(struct snd_soc_pcm_runtime *rtd)
{
struct snd_card *card = rtd->card->snd_card;
+ int ret = 0;
if (!card->dev->coherent_dma_mask)
card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
- return 0;
+ ret = msm_lsm_add_controls(rtd);
+ if (ret)
+ pr_err("%s, kctl add failed:%d\n", __func__, ret);
+
+ return ret;
}
static int msm_asoc_lsm_probe(struct snd_soc_platform *platform)
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
index 2d410170f48d..30522ac023cd 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
@@ -72,9 +72,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;
@@ -88,6 +91,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"
@@ -96,12 +101,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 {
@@ -270,254 +277,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} } },
@@ -575,13 +590,80 @@ 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_routing_app_type_data lsm_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,
@@ -624,13 +706,39 @@ static int msm_pcm_routing_get_app_type_idx(int app_type)
return 0;
}
+static int msm_pcm_routing_get_lsm_app_type_idx(int app_type)
+{
+ int idx;
+
+ pr_debug("%s: app_type: %d\n", __func__, app_type);
+ for (idx = 0; idx < MAX_APP_TYPES; idx++) {
+ if (lsm_app_type_cfg[idx].app_type == app_type)
+ return idx;
+ }
+ pr_debug("%s: App type not available, fallback to default\n", __func__);
+ return 0;
+}
+
+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;
+}
+
+
void msm_pcm_routing_reg_stream_app_type_cfg(int fedai_id, int app_type,
int acdb_dev_id, int sample_rate, int session_type)
{
pr_debug("%s: fedai_id %d, session_type %d, app_type %d, acdb_dev_id %d, sample_rate %d\n",
__func__, fedai_id, session_type, app_type,
acdb_dev_id, sample_rate);
- if (fedai_id > MSM_FRONTEND_DAI_MM_MAX_ID) {
+ if (!is_mm_lsm_fe_id(fedai_id)) {
pr_err("%s: Invalid machine driver ID %d\n",
__func__, fedai_id);
return;
@@ -677,7 +785,7 @@ int msm_pcm_routing_get_stream_app_type_cfg(int fedai_id, int session_type,
pr_err("%s: NULL pointer sent for sample rate\n", __func__);
ret = -EINVAL;
goto done;
- } else if (fedai_id > MSM_FRONTEND_DAI_MM_MAX_ID) {
+ } else if (!is_mm_lsm_fe_id(fedai_id)) {
pr_err("%s: Invalid FE ID %d\n",
__func__, fedai_id);
ret = -EINVAL;
@@ -791,7 +899,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;
@@ -804,7 +913,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];
@@ -827,7 +936,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);
}
}
@@ -861,7 +970,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);
@@ -871,28 +980,51 @@ 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;
+}
+
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;
u32 channels, sample_rate;
u16 bit_width = 16;
+ bool is_lsm;
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;
@@ -906,6 +1038,8 @@ int msm_pcm_routing_reg_phy_compr_stream(int fe_id, int perf_mode,
return -EINVAL;
}
+ is_lsm = (fe_id >= MSM_FRONTEND_DAI_LSM1) &&
+ (fe_id <= MSM_FRONTEND_DAI_LSM8);
mutex_lock(&routing_lock);
payload.num_copps = 0; /* only RX needs to use payload */
@@ -913,14 +1047,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;
/*
@@ -936,7 +1070,15 @@ int msm_pcm_routing_reg_phy_compr_stream(int fe_id, int perf_mode,
msm_bedais[i].format);
app_type =
fe_dai_app_type_cfg[fe_id][session_type].app_type;
- if (app_type) {
+ if (app_type && is_lsm) {
+ app_type_idx =
+ msm_pcm_routing_get_lsm_app_type_idx(app_type);
+ sample_rate =
+ fe_dai_app_type_cfg[fe_id][session_type].
+ sample_rate;
+ bit_width =
+ lsm_app_type_cfg[app_type_idx].bit_width;
+ } else if (app_type) {
app_type_idx =
msm_pcm_routing_get_app_type_idx(
app_type);
@@ -951,9 +1093,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 =
@@ -990,7 +1133,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);
@@ -1004,7 +1147,9 @@ 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);
+ payload.sample_rate =
+ fe_dai_app_type_cfg[fe_id][session_type].sample_rate;
+ 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);
@@ -1055,6 +1200,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 */
@@ -1084,7 +1230,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
@@ -1094,7 +1240,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(
@@ -1151,7 +1297,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,
@@ -1167,7 +1313,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);
@@ -1196,7 +1342,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;
@@ -1217,7 +1363,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];
@@ -1242,7 +1388,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);
@@ -1259,13 +1405,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;
@@ -1277,19 +1423,27 @@ 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;
+ bool is_lsm;
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;
@@ -1297,15 +1451,17 @@ static void msm_pcm_routing_process_audio(u16 reg, u16 val, int set)
session_type = SESSION_TYPE_TX;
path_type = ADM_PATH_LIVE_REC;
}
+ is_lsm = (val >= MSM_FRONTEND_DAI_LSM1) &&
+ (val <= MSM_FRONTEND_DAI_LSM8);
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) {
@@ -1336,7 +1492,15 @@ static void msm_pcm_routing_process_audio(u16 reg, u16 val, int set)
app_type =
fe_dai_app_type_cfg[val][session_type].app_type;
- if (app_type) {
+ if (app_type && is_lsm) {
+ app_type_idx =
+ msm_pcm_routing_get_lsm_app_type_idx(app_type);
+ sample_rate =
+ fe_dai_app_type_cfg[val][session_type].
+ sample_rate;
+ bits_per_sample =
+ lsm_app_type_cfg[app_type_idx].bit_width;
+ } else if (app_type) {
app_type_idx =
msm_pcm_routing_get_app_type_idx(app_type);
sample_rate =
@@ -1381,20 +1545,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) {
@@ -1419,14 +1583,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)
@@ -1442,7 +1606,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;
@@ -1476,6 +1640,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;
@@ -1492,9 +1701,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) ==
@@ -1553,7 +1762,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;
@@ -1595,7 +1804,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;
@@ -1620,13 +1829,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);
@@ -1928,23 +2137,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);
@@ -1975,19 +2180,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;
}
@@ -2000,23 +2204,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);
@@ -2051,12 +2259,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;
}
@@ -2084,11 +2292,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);
@@ -2253,6 +2466,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)
{
@@ -7721,6 +8072,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,
@@ -7806,53 +8349,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,
@@ -7867,6 +8374,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[] = {
@@ -7923,7 +8457,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)
@@ -8029,6 +8563,45 @@ static const struct snd_kcontrol_new app_type_cfg_controls[] = {
msm_routing_put_app_type_cfg_control),
};
+static int msm_routing_get_lsm_app_type_cfg_control(
+ struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ return 0;
+}
+
+static int msm_routing_put_lsm_app_type_cfg_control(
+ struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int i = 0, j;
+ int num_app_types = ucontrol->value.integer.value[i++];
+
+ memset(lsm_app_type_cfg, 0, MAX_APP_TYPES*
+ sizeof(struct msm_pcm_routing_app_type_data));
+ if (num_app_types > MAX_APP_TYPES) {
+ pr_err("%s: number of app types exceed the max supported\n",
+ __func__);
+ return -EINVAL;
+ }
+ for (j = 0; j < num_app_types; j++) {
+ lsm_app_type_cfg[j].app_type =
+ ucontrol->value.integer.value[i++];
+ lsm_app_type_cfg[j].sample_rate =
+ ucontrol->value.integer.value[i++];
+ lsm_app_type_cfg[j].bit_width =
+ ucontrol->value.integer.value[i++];
+ }
+
+ return 0;
+}
+
+static const struct snd_kcontrol_new lsm_app_type_cfg_controls[] = {
+ SOC_SINGLE_MULTI_EXT("Listen App Type Config", SND_SOC_NOPM, 0,
+ 0xFFFFFFFF, 0, 128, msm_routing_get_lsm_app_type_cfg_control,
+ msm_routing_put_lsm_app_type_cfg_control),
+};
+
static int msm_routing_get_use_ds1_or_ds2_control(
struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
@@ -8224,7 +8797,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]
@@ -9298,16 +9871,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)),
@@ -9665,6 +10228,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"),
@@ -11124,70 +11704,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"},
-
-
- {"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"},
-
-
- {"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"},
-
- {"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"},
-
- {"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"},
-
-
- {"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"},
+
+ {"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 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 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 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 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"},
+
+ {"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"},
@@ -11804,7 +12391,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;
@@ -11825,13 +12414,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;
@@ -11851,6 +12439,7 @@ static int msm_pcm_routing_prepare(struct snd_pcm_substream *substream)
struct msm_pcm_routing_fdai_data *fdai;
u32 session_id;
struct media_format_info voc_be_media_format;
+ bool is_lsm;
pr_debug("%s: substream->pcm->id:%s\n",
__func__, substream->pcm->id);
@@ -11863,7 +12452,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;
@@ -11884,7 +12473,13 @@ 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;
+
+ is_lsm = (i >= MSM_FRONTEND_DAI_LSM1) &&
+ (i <= MSM_FRONTEND_DAI_LSM8);
fdai = &fe_dai_map[i][session_type];
if (fdai->strm_id != INVALID_SESSION) {
int app_type, app_type_idx, copp_idx, acdb_dev_id;
@@ -11906,7 +12501,15 @@ static int msm_pcm_routing_prepare(struct snd_pcm_substream *substream)
app_type =
fe_dai_app_type_cfg[i][session_type].app_type;
- if (app_type) {
+ if (app_type && is_lsm) {
+ app_type_idx =
+ msm_pcm_routing_get_lsm_app_type_idx(app_type);
+ sample_rate =
+ fe_dai_app_type_cfg[i][session_type].
+ sample_rate;
+ bits_per_sample =
+ lsm_app_type_cfg[app_type_idx].bit_width;
+ } else if (app_type) {
app_type_idx =
msm_pcm_routing_get_app_type_idx(app_type);
sample_rate =
@@ -11951,16 +12554,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__,
@@ -12025,6 +12628,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);
@@ -12061,14 +12665,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);
@@ -12078,9 +12684,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);
@@ -12096,6 +12700,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);
@@ -12120,7 +12725,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 =
@@ -12134,7 +12743,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__);
@@ -12142,9 +12751,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;
@@ -12156,9 +12763,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;
@@ -12228,8 +12833,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));
@@ -12240,10 +12845,16 @@ static int msm_routing_probe(struct snd_soc_platform *platform)
snd_soc_add_platform_controls(platform, app_type_cfg_controls,
ARRAY_SIZE(app_type_cfg_controls));
+ snd_soc_add_platform_controls(platform, lsm_app_type_cfg_controls,
+ ARRAY_SIZE(lsm_app_type_cfg_controls));
+
snd_soc_add_platform_controls(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);
@@ -12326,7 +12937,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 2c501ce3d6ff..74fbe984e6e9 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 2bf0c490e834..525ec1c30f48 100644
--- a/sound/soc/msm/qdsp6v2/q6lsm.c
+++ b/sound/soc/msm/qdsp6v2/q6lsm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2016, Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2017, 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
@@ -38,6 +38,8 @@
#define LSM_ALIGN_BOUNDARY 512
#define LSM_SAMPLE_RATE 16000
#define QLSM_PARAM_ID_MINOR_VERSION 1
+#define QLSM_PARAM_ID_MINOR_VERSION_2 2
+
static int lsm_afe_port;
enum {
@@ -707,29 +709,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,10 +742,61 @@ static int q6lsm_send_params(struct lsm_client *client,
op_mode->reserved = 0;
pr_debug("%s: mode = 0x%x", __func__, op_mode->mode);
+ rc = q6lsm_apr_send_pkt(client, client->apr,
+ &opmode_params, true, NULL);
+ if (rc)
+ pr_err("%s: Failed set_params opcode 0x%x, rc %d\n",
+ __func__, msg_hdr->opcode, rc);
+
+ pr_debug("%s: leave %d\n", __func__, rc);
+ return rc;
+}
+
+void set_lsm_port(int lsm_port)
+{
+ lsm_afe_port = 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,
+ &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;
@@ -752,23 +804,191 @@ static int q6lsm_send_params(struct lsm_client *client,
pr_debug("%s: port= %d", __func__, connect_to_port->port_id);
rc = q6lsm_apr_send_pkt(client, client->apr,
- &opmode_connectport, true, NULL);
+ &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);
- pr_debug("%s: leave %d\n", __func__, rc);
return rc;
}
-void set_lsm_port(int lsm_port)
+int q6lsm_set_fwk_mode_cfg(struct lsm_client *client,
+ uint32_t event_mode)
{
- lsm_afe_port = lsm_port;
+ int rc = 0;
+ struct lsm_cmd_set_fwk_mode_cfg cmd;
+ struct lsm_module_param_ids fwk_mode_cfg_ids;
+ struct apr_hdr *msg_hdr;
+ struct lsm_param_fwk_mode_cfg *fwk_mode_cfg;
+ u32 data_payload_size, param_size, set_param_opcode;
+
+ if (client->use_topology) {
+ set_param_opcode = LSM_SESSION_CMD_SET_PARAMS_V2;
+ fwk_mode_cfg_ids.module_id = LSM_MODULE_ID_FRAMEWORK;
+ fwk_mode_cfg_ids.param_id = LSM_PARAM_ID_FWK_MODE_CONFIG;
+ } else {
+ pr_debug("%s: Ignore sending event mode\n", __func__);
+ return rc;
+ }
+
+ msg_hdr = &cmd.msg_hdr;
+ q6lsm_add_hdr(client, msg_hdr,
+ sizeof(struct lsm_cmd_set_fwk_mode_cfg), true);
+ msg_hdr->opcode = set_param_opcode;
+ data_payload_size = sizeof(struct lsm_cmd_set_fwk_mode_cfg) -
+ sizeof(struct apr_hdr) -
+ sizeof(struct lsm_set_params_hdr);
+ q6lsm_set_param_hdr_info(&cmd.params_hdr,
+ data_payload_size, 0, 0, 0);
+ fwk_mode_cfg = &cmd.fwk_mode_cfg;
+
+ param_size = (sizeof(struct lsm_param_fwk_mode_cfg) -
+ sizeof(fwk_mode_cfg->common));
+ q6lsm_set_param_common(&fwk_mode_cfg->common,
+ &fwk_mode_cfg_ids, param_size,
+ set_param_opcode);
+
+ fwk_mode_cfg->minor_version = QLSM_PARAM_ID_MINOR_VERSION;
+ fwk_mode_cfg->mode = event_mode;
+ pr_debug("%s: mode = %d\n", __func__, fwk_mode_cfg->mode);
+
+ 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 get_lsm_port()
+static int q6lsm_arrange_mch_map(struct lsm_param_media_fmt *media_fmt,
+ int channel_count)
{
- return lsm_afe_port;
+ int rc = 0;
+
+ memset(media_fmt->channel_mapping, 0, LSM_MAX_NUM_CHANNELS);
+
+ switch (channel_count) {
+ case 1:
+ media_fmt->channel_mapping[0] = PCM_CHANNEL_FC;
+ break;
+ case 2:
+ media_fmt->channel_mapping[0] = PCM_CHANNEL_FL;
+ media_fmt->channel_mapping[1] = PCM_CHANNEL_FR;
+ break;
+ case 3:
+ media_fmt->channel_mapping[0] = PCM_CHANNEL_FL;
+ media_fmt->channel_mapping[1] = PCM_CHANNEL_FR;
+ media_fmt->channel_mapping[2] = PCM_CHANNEL_FC;
+ break;
+ case 4:
+ media_fmt->channel_mapping[0] = PCM_CHANNEL_FL;
+ media_fmt->channel_mapping[1] = PCM_CHANNEL_FR;
+ media_fmt->channel_mapping[2] = PCM_CHANNEL_LS;
+ media_fmt->channel_mapping[3] = PCM_CHANNEL_RS;
+ break;
+ default:
+ pr_err("%s: invalid num_chan %d\n", __func__, channel_count);
+ rc = -EINVAL;
+ break;
+ }
+ return rc;
+}
+
+int q6lsm_set_media_fmt_params(struct lsm_client *client)
+{
+ int rc = 0;
+ struct lsm_cmd_set_media_fmt cmd;
+ struct lsm_module_param_ids media_fmt_ids;
+ struct apr_hdr *msg_hdr;
+ struct lsm_param_media_fmt *media_fmt;
+ u32 data_payload_size, param_size, set_param_opcode;
+ struct lsm_hw_params param = client->hw_params;
+
+ if (client->use_topology) {
+ set_param_opcode = LSM_SESSION_CMD_SET_PARAMS_V2;
+ media_fmt_ids.module_id = LSM_MODULE_ID_FRAMEWORK;
+ media_fmt_ids.param_id = LSM_PARAM_ID_MEDIA_FMT;
+ } else {
+ pr_debug("%s: Ignore sending media format\n", __func__);
+ goto err_ret;
+ }
+
+ msg_hdr = &cmd.msg_hdr;
+ q6lsm_add_hdr(client, msg_hdr,
+ sizeof(struct lsm_cmd_set_media_fmt), true);
+ msg_hdr->opcode = set_param_opcode;
+ data_payload_size = sizeof(struct lsm_cmd_set_media_fmt) -
+ sizeof(struct apr_hdr) -
+ sizeof(struct lsm_set_params_hdr);
+ q6lsm_set_param_hdr_info(&cmd.params_hdr,
+ data_payload_size, 0, 0, 0);
+ media_fmt = &cmd.media_fmt;
+
+ param_size = (sizeof(struct lsm_param_media_fmt) -
+ sizeof(media_fmt->common));
+ q6lsm_set_param_common(&media_fmt->common,
+ &media_fmt_ids, param_size,
+ set_param_opcode);
+
+ media_fmt->minor_version = QLSM_PARAM_ID_MINOR_VERSION_2;
+ media_fmt->sample_rate = param.sample_rate;
+ media_fmt->num_channels = param.num_chs;
+ media_fmt->bit_width = param.sample_size;
+
+ rc = q6lsm_arrange_mch_map(media_fmt, media_fmt->num_channels);
+ if (rc)
+ goto err_ret;
+
+ pr_debug("%s: sample rate= %d, channels %d bit width %d\n",
+ __func__, media_fmt->sample_rate, media_fmt->num_channels,
+ media_fmt->bit_width);
+
+ 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);
+err_ret:
+ return rc;
}
int q6lsm_set_data(struct lsm_client *client,
@@ -776,7 +996,7 @@ int q6lsm_set_data(struct lsm_client *client,
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 +1020,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);
@@ -1390,7 +1606,7 @@ static int q6lsm_send_param_gain(
int q6lsm_set_one_param(struct lsm_client *client,
struct lsm_params_info *p_info, void *data,
- enum LSM_PARAM_TYPE param_type)
+ uint32_t param_type)
{
int rc = 0, pkt_sz;
struct lsm_module_param_ids ids;
@@ -1409,7 +1625,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 +1637,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 +1669,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;