summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c98
-rw-r--r--sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h18
-rw-r--r--sound/soc/msm/qdsp6v2/q6adm.c108
3 files changed, 172 insertions, 52 deletions
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
index b64bd7ed8fc7..9d1e20f71829 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
@@ -120,17 +120,13 @@ static const char * const lsm_port_text[] = {
};
struct msm_pcm_route_bdai_pp_params {
- u16 port_id; /* AFE port ID */
unsigned long pp_params_config;
bool mute_on;
int latency;
};
static struct msm_pcm_route_bdai_pp_params
- msm_bedais_pp_params[MSM_BACKEND_DAI_PP_PARAMS_REQ_MAX] = {
- {HDMI_RX, 0, 0, 0},
- {DISPLAY_PORT_RX, 0, 0, 0},
-};
+ msm_bedais_pp_params[MSM_BACKEND_DAI_MAX];
/*
* The be_dai_name_table is passed to HAL so that it can specify the
@@ -144,6 +140,7 @@ struct msm_pcm_route_bdai_name {
};
static struct msm_pcm_route_bdai_name be_dai_name_table[MSM_BACKEND_DAI_MAX];
+static bool msm_pcm_routing_test_pp_param(int be_idx, long param_bit);
static int msm_routing_send_device_pp_params(int port_id, int copp_idx,
int fe_id);
@@ -955,7 +952,7 @@ static void msm_pcm_routing_build_matrix(int fedai_id, int sess_type,
uint32_t passthr_mode)
{
int i, port_type, j, num_copps = 0;
- struct route_payload payload;
+ struct route_payload payload = { {0} };
port_type = ((path_type == ADM_PATH_PLAYBACK ||
path_type == ADM_PATH_COMPRESSED_RX) ?
@@ -985,6 +982,11 @@ static void msm_pcm_routing_build_matrix(int fedai_id, int sess_type,
fe_dai_app_type_cfg
[fedai_id][sess_type][i]
.sample_rate;
+ if (msm_pcm_routing_test_pp_param(i,
+ ADM_PP_PARAM_LIMITER_BIT))
+ set_bit(ADM_STATUS_LIMITER,
+ &payload.route_status
+ [num_copps]);
num_copps++;
}
}
@@ -1206,6 +1208,11 @@ int msm_pcm_routing_reg_phy_compr_stream(int fe_id, int perf_mode,
fe_dai_app_type_cfg
[fe_id][session_type][i]
.sample_rate;
+ if (msm_pcm_routing_test_pp_param(i,
+ ADM_PP_PARAM_LIMITER_BIT))
+ set_bit(ADM_STATUS_LIMITER,
+ &payload.route_status
+ [num_copps]);
num_copps++;
}
}
@@ -1436,6 +1443,11 @@ int msm_pcm_routing_reg_phy_stream(int fedai_id, int perf_mode,
fe_dai_app_type_cfg
[fedai_id][session_type]
[i].sample_rate;
+ if (msm_pcm_routing_test_pp_param(i,
+ ADM_PP_PARAM_LIMITER_BIT))
+ set_bit(ADM_STATUS_LIMITER,
+ &payload.route_status
+ [num_copps]);
num_copps++;
}
}
@@ -15335,7 +15347,7 @@ done:
static int msm_routing_send_device_pp_params(int port_id, int copp_idx,
int fe_id)
{
- int index, topo_id, be_idx;
+ int topo_id, be_idx;
unsigned long pp_config = 0;
bool mute_on;
int latency;
@@ -15359,16 +15371,6 @@ static int msm_routing_send_device_pp_params(int port_id, int copp_idx,
return -EINVAL;
}
- for (index = 0; index < MSM_BACKEND_DAI_PP_PARAMS_REQ_MAX; index++) {
- if (msm_bedais_pp_params[index].port_id == port_id)
- break;
- }
- if (index >= MSM_BACKEND_DAI_PP_PARAMS_REQ_MAX) {
- pr_err("%s: Invalid backend pp params index %d\n",
- __func__, index);
- return -EINVAL;
- }
-
topo_id = adm_get_topology_for_port_copp_idx(port_id, copp_idx);
if (topo_id != COMPRESSED_PASSTHROUGH_DEFAULT_TOPOLOGY) {
pr_err("%s: Invalid passthrough topology 0x%x\n",
@@ -15380,11 +15382,11 @@ static int msm_routing_send_device_pp_params(int port_id, int copp_idx,
(msm_bedais[be_idx].passthr_mode[fe_id] == LISTEN))
compr_passthr_mode = false;
- pp_config = msm_bedais_pp_params[index].pp_params_config;
+ pp_config = msm_bedais_pp_params[be_idx].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;
+ mute_on = msm_bedais_pp_params[be_idx].mute_on;
if ((msm_bedais[be_idx].active) && compr_passthr_mode)
adm_send_compressed_device_mute(port_id,
copp_idx,
@@ -15394,7 +15396,7 @@ static int msm_routing_send_device_pp_params(int port_id, int copp_idx,
pr_debug("%s: ADM_PP_PARAM_LATENCY\n", __func__);
clear_bit(ADM_PP_PARAM_LATENCY_BIT,
&pp_config);
- latency = msm_bedais_pp_params[index].latency;
+ latency = msm_bedais_pp_params[be_idx].latency;
if ((msm_bedais[be_idx].active) && compr_passthr_mode)
adm_send_compressed_device_latency(port_id,
copp_idx,
@@ -15403,18 +15405,47 @@ static int msm_routing_send_device_pp_params(int port_id, int copp_idx,
return 0;
}
+static bool msm_pcm_routing_test_pp_param(int be_idx, long param_bit)
+{
+ return test_bit(param_bit,
+ &msm_bedais_pp_params[be_idx].pp_params_config);
+}
+
+static void msm_routing_set_pp_param(long param_bit, int value)
+{
+ int be_idx;
+
+ if (value) {
+ for (be_idx = 0; be_idx < MSM_BACKEND_DAI_MAX; be_idx++)
+ set_bit(param_bit,
+ &msm_bedais_pp_params[be_idx].
+ pp_params_config);
+ } else {
+ for (be_idx = 0; be_idx < MSM_BACKEND_DAI_MAX; be_idx++)
+ clear_bit(param_bit,
+ &msm_bedais_pp_params[be_idx].
+ pp_params_config);
+ }
+}
+
static int msm_routing_put_device_pp_params_mixer(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
int pp_id = ucontrol->value.integer.value[0];
+ int value = ucontrol->value.integer.value[1];
int port_id = 0;
- int index, be_idx, i, topo_id, idx;
+ int 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);
+ if (pp_id == ADM_PP_PARAM_LIMITER_ID) {
+ msm_routing_set_pp_param(ADM_PP_PARAM_LIMITER_BIT, value);
+ goto done;
+ }
+
for (be_idx = 0; be_idx < MSM_BACKEND_DAI_MAX; be_idx++) {
port_id = msm_bedais[be_idx].port_id;
if (port_id == HDMI_RX || port_id == DISPLAY_PORT_RX)
@@ -15426,16 +15457,6 @@ static int msm_routing_put_device_pp_params_mixer(struct snd_kcontrol *kcontrol,
return -EINVAL;
}
- for (index = 0; index < MSM_BACKEND_DAI_PP_PARAMS_REQ_MAX; index++) {
- if (msm_bedais_pp_params[index].port_id == port_id)
- break;
- }
- if (index >= MSM_BACKEND_DAI_PP_PARAMS_REQ_MAX) {
- pr_err("%s: Invalid pp params backend index %d\n",
- __func__, index);
- return -EINVAL;
- }
-
for_each_set_bit(i, &msm_bedais[be_idx].fe_sessions[0],
MSM_FRONTEND_DAI_MM_SIZE) {
if ((msm_bedais[be_idx].passthr_mode[i] == LEGACY_PCM) ||
@@ -15458,22 +15479,20 @@ static int msm_routing_put_device_pp_params_mixer(struct snd_kcontrol *kcontrol,
switch (pp_id) {
case ADM_PP_PARAM_MUTE_ID:
pr_debug("%s: ADM_PP_PARAM_MUTE\n", __func__);
- mute = ucontrol->value.integer.value[1] ? true : false;
- msm_bedais_pp_params[index].mute_on = mute;
+ mute = value ? true : false;
+ msm_bedais_pp_params[be_idx].mute_on = mute;
set_bit(ADM_PP_PARAM_MUTE_BIT,
- &msm_bedais_pp_params[index].pp_params_config);
+ &msm_bedais_pp_params[be_idx].pp_params_config);
if ((msm_bedais[be_idx].active) && compr_passthr_mode)
adm_send_compressed_device_mute(port_id,
idx, mute);
break;
case ADM_PP_PARAM_LATENCY_ID:
pr_debug("%s: ADM_PP_PARAM_LATENCY\n", __func__);
- msm_bedais_pp_params[index].latency =
- ucontrol->value.integer.value[1];
+ msm_bedais_pp_params[be_idx].latency = value;
set_bit(ADM_PP_PARAM_LATENCY_BIT,
- &msm_bedais_pp_params[index].pp_params_config);
- latency = msm_bedais_pp_params[index].latency =
- ucontrol->value.integer.value[1];
+ &msm_bedais_pp_params[be_idx].pp_params_config);
+ latency = msm_bedais_pp_params[be_idx].latency = value;
if ((msm_bedais[be_idx].active) && compr_passthr_mode)
adm_send_compressed_device_latency(port_id,
idx, latency);
@@ -15485,6 +15504,7 @@ static int msm_routing_put_device_pp_params_mixer(struct snd_kcontrol *kcontrol,
}
}
}
+done:
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 fa948abd1b4c..a8daff09db58 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h
@@ -397,12 +397,20 @@ enum {
#define RELEASE_LOCK 0
#define ACQUIRE_LOCK 1
-#define MSM_BACKEND_DAI_PP_PARAMS_REQ_MAX 2
#define HDMI_RX_ID 0x8001
-#define ADM_PP_PARAM_MUTE_ID 0
-#define ADM_PP_PARAM_MUTE_BIT 1
-#define ADM_PP_PARAM_LATENCY_ID 1
-#define ADM_PP_PARAM_LATENCY_BIT 2
+
+enum {
+ ADM_PP_PARAM_MUTE_ID,
+ ADM_PP_PARAM_LATENCY_ID,
+ ADM_PP_PARAM_LIMITER_ID
+};
+
+enum {
+ ADM_PP_PARAM_MUTE_BIT = 0x1,
+ ADM_PP_PARAM_LATENCY_BIT = 0x2,
+ ADM_PP_PARAM_LIMITER_BIT = 0x4
+};
+
#define BE_DAI_PORT_SESSIONS_IDX_MAX 4
#define BE_DAI_FE_SESSIONS_IDX_MAX 2
diff --git a/sound/soc/msm/qdsp6v2/q6adm.c b/sound/soc/msm/qdsp6v2/q6adm.c
index 4aad16db3e0f..e1bfc950d0e3 100644
--- a/sound/soc/msm/qdsp6v2/q6adm.c
+++ b/sound/soc/msm/qdsp6v2/q6adm.c
@@ -48,12 +48,6 @@
#define DS2_ADM_COPP_TOPOLOGY_ID 0xFFFFFFFF
#endif
-/* ENUM for adm_status */
-enum adm_cal_status {
- ADM_STATUS_CALIBRATION_REQUIRED = 0,
- ADM_STATUS_MAX,
-};
-
struct adm_copp {
atomic_t id[AFE_MAX_PORTS][MAX_COPPS_PER_PORT];
@@ -1413,6 +1407,7 @@ static int32_t adm_callback(struct apr_client_data *data, void *priv)
case ADM_CMD_DEVICE_OPEN_V5:
case ADM_CMD_DEVICE_CLOSE_V5:
case ADM_CMD_DEVICE_OPEN_V6:
+ case ADM_CMD_SET_MTMX_STRTR_DEV_PARAMS_V1:
pr_debug("%s: Basic callback received, wake up.\n",
__func__);
atomic_set(&this_adm.copp.stat[port_idx]
@@ -2695,6 +2690,97 @@ fail_cmd:
return;
}
+
+static int adm_set_mtmx_params_v1(int port_idx, int copp_idx,
+ int params_length, void *params)
+{
+ struct adm_cmd_set_mtmx_params_v1 *adm_params = NULL;
+ int rc = 0;
+ int sz;
+
+ sz = sizeof(*adm_params) + params_length;
+ adm_params = kzalloc(sz, GFP_KERNEL);
+ if (!adm_params)
+ return -ENOMEM;
+
+ memcpy(((u8 *)adm_params + sizeof(*adm_params)),
+ params, params_length);
+ adm_params->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
+ APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
+ adm_params->hdr.pkt_size = sz;
+ adm_params->hdr.src_svc = APR_SVC_ADM;
+ adm_params->hdr.src_domain = APR_DOMAIN_APPS;
+ adm_params->hdr.src_port = 0;
+ adm_params->hdr.dest_svc = APR_SVC_ADM;
+ adm_params->hdr.dest_domain = APR_DOMAIN_ADSP;
+ adm_params->hdr.dest_port =
+ atomic_read(&this_adm.copp.id[port_idx][copp_idx]);
+ adm_params->hdr.token = port_idx << 16 | copp_idx;
+ adm_params->hdr.opcode = ADM_CMD_SET_MTMX_STRTR_DEV_PARAMS_V1;
+ adm_params->payload_addr_lsw = 0;
+ adm_params->payload_addr_msw = 0;
+ adm_params->mem_map_handle = 0;
+ adm_params->payload_size = params_length;
+ adm_params->copp_id = atomic_read(&this_adm.copp.
+ id[port_idx][copp_idx]);
+
+ atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1);
+ rc = apr_send_pkt(this_adm.apr, (uint32_t *)adm_params);
+ if (rc < 0) {
+ pr_err("%s: Set params failed port_idx = 0x%x rc %d\n",
+ __func__, port_idx, rc);
+ rc = -EINVAL;
+ goto send_param_return;
+ }
+ /* Wait for the callback */
+ rc = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx],
+ atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) >= 0,
+ msecs_to_jiffies(TIMEOUT_MS));
+ if (!rc) {
+ pr_err("%s: Set params timed out port_idx = 0x%x\n",
+ __func__, port_idx);
+ rc = -EINVAL;
+ goto send_param_return;
+ } else if (atomic_read(&this_adm.copp.stat
+ [port_idx][copp_idx]) > 0) {
+ pr_err("%s: DSP returned error[%s]\n",
+ __func__, adsp_err_get_err_str(
+ atomic_read(&this_adm.copp.stat
+ [port_idx][copp_idx])));
+ rc = adsp_err_get_lnx_err_code(
+ atomic_read(&this_adm.copp.stat
+ [port_idx][copp_idx]));
+ goto send_param_return;
+ }
+ rc = 0;
+send_param_return:
+ kfree(adm_params);
+ return rc;
+}
+
+static void adm_enable_mtmx_limiter(int port_idx, int copp_idx)
+{
+ int rc;
+ struct enable_param_v6 adm_param = { {0} };
+
+ adm_param.param.module_id = ADM_MTMX_MODULE_STREAM_LIMITER;
+ adm_param.param.param_id = AUDPROC_PARAM_ID_ENABLE;
+ adm_param.param.param_size = sizeof(adm_param.enable);
+ adm_param.enable = 1;
+
+ rc = adm_set_mtmx_params_v1(port_idx, copp_idx,
+ sizeof(adm_param), &adm_param);
+ if (rc < 0) {
+ pr_err("%s: adm_set_mtmx_params_v1 failed port_idx = 0x%x rc %d\n",
+ __func__, port_idx, rc);
+ goto done;
+ }
+ set_bit(ADM_STATUS_LIMITER,
+ (void *)&this_adm.copp.adm_status[port_idx][copp_idx]);
+done:
+ return;
+}
+
static void route_set_opcode_matrix_id(
struct adm_cmd_matrix_map_routings_v5 **route_addr,
int path, uint32_t passthr_mode)
@@ -2791,6 +2877,11 @@ int adm_matrix_map(int path, struct route_payload payload_map, int perf_mode,
copp_idx = payload_map.copp_idx[i];
copps_list[i] = atomic_read(&this_adm.copp.id[port_idx]
[copp_idx]);
+ if (test_bit(ADM_STATUS_LIMITER,
+ (void *)&payload_map.route_status) &&
+ ((path == ADM_PATH_PLAYBACK) ||
+ (path == ADM_PATH_COMPRESSED_RX)))
+ adm_enable_mtmx_limiter(port_idx, copp_idx);
}
atomic_set(&this_adm.matrix_map_stat, -1);
@@ -2991,6 +3082,8 @@ int adm_close(int port_id, int perf_mode, int copp_idx)
clear_bit(ADM_STATUS_CALIBRATION_REQUIRED,
(void *)&this_adm.copp.adm_status[port_idx][copp_idx]);
+ clear_bit(ADM_STATUS_LIMITER,
+ (void *)&this_adm.copp.adm_status[port_idx][copp_idx]);
ret = apr_send_pkt(this_adm.apr, (uint32_t *)&close);
if (ret < 0) {
@@ -4807,8 +4900,7 @@ static int __init adm_init(void)
&this_adm.copp.adm_delay_wait[i][j]);
atomic_set(&this_adm.copp.topology[i][j], 0);
this_adm.copp.adm_delay[i][j] = 0;
- this_adm.copp.adm_status[i][j] =
- ADM_STATUS_CALIBRATION_REQUIRED;
+ this_adm.copp.adm_status[i][j] = 0;
}
}