From fcbf2fad440c26296d00b4513939fdf078f145a4 Mon Sep 17 00:00:00 2001 From: Siena Richard Date: Wed, 11 Jan 2017 16:20:55 -0800 Subject: [PATCH] ASoC: msm: add support for multi-copps for multiple BEs Add support for multi-copps for multiple BEs with independent calibration data. This allows for more accurate calibration of device copps. CRs-fixed: 1110411 Change-Id: I72ce501408a474eb620a088172e3c4d789ab5ef0 Signed-off-by: Siena Richard --- include/sound/q6adm-v2.h | 6 +- include/sound/q6afe-v2.h | 3 + sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c | 92 +++-- sound/soc/msm/qdsp6v2/msm-lsm-client.c | 44 ++- sound/soc/msm/qdsp6v2/msm-pcm-loopback-v2.c | 92 +++-- sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c | 92 +++-- sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c | 366 +++++++++++++++----- sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h | 14 +- sound/soc/msm/qdsp6v2/q6adm.c | 10 +- sound/soc/msm/qdsp6v2/q6afe.c | 91 ++++- 10 files changed, 531 insertions(+), 279 deletions(-) diff --git a/include/sound/q6adm-v2.h b/include/sound/q6adm-v2.h index 25376315dd20..42d048f24e12 100644 --- a/include/sound/q6adm-v2.h +++ b/include/sound/q6adm-v2.h @@ -58,9 +58,9 @@ enum { struct route_payload { unsigned int copp_idx[MAX_COPPS_PER_PORT]; unsigned int port_id[MAX_COPPS_PER_PORT]; - int app_type; - int acdb_dev_id; - int sample_rate; + int app_type[MAX_COPPS_PER_PORT]; + int acdb_dev_id[MAX_COPPS_PER_PORT]; + int sample_rate[MAX_COPPS_PER_PORT]; unsigned short num_copps; unsigned int session_id; }; diff --git a/include/sound/q6afe-v2.h b/include/sound/q6afe-v2.h index a47d2805b9c5..e4033e712804 100644 --- a/include/sound/q6afe-v2.h +++ b/include/sound/q6afe-v2.h @@ -42,6 +42,8 @@ #define AFE_CLK_VERSION_V1 1 #define AFE_CLK_VERSION_V2 2 +typedef int (*routing_cb)(int port); + enum { /* IDX 0->4 */ IDX_PRIMARY_I2S_RX, @@ -363,4 +365,5 @@ int afe_send_custom_tdm_header_cfg( u16 port_id); int afe_tdm_port_start(u16 port_id, struct afe_tdm_port_config *tdm_port, u32 rate); +void afe_set_routing_callback(routing_cb); #endif /* __Q6AFE_V2_H__ */ diff --git a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c index 2ba41ac1877f..9e20c0beb770 100644 --- a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c +++ b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c @@ -3220,48 +3220,45 @@ static int msm_compr_playback_app_type_cfg_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { u64 fe_id = kcontrol->private_value; + int session_type = SESSION_TYPE_RX; + int be_id = ucontrol->value.integer.value[3]; + int ret = 0; int app_type; int acdb_dev_id; int sample_rate = 48000; - pr_debug("%s: fe_id- %llu\n", __func__, fe_id); - if (fe_id >= MSM_FRONTEND_DAI_MAX) { - 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]; - if (0 != ucontrol->value.integer.value[2]) + if (ucontrol->value.integer.value[2] != 0) 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_RX); - msm_pcm_routing_reg_stream_app_type_cfg(fe_id, app_type, - acdb_dev_id, sample_rate, SESSION_TYPE_RX); + pr_debug("%s: fe_id- %llu session_type- %d be_id- %d app_type- %d acdb_dev_id- %d sample_rate- %d\n", + __func__, fe_id, session_type, be_id, + app_type, acdb_dev_id, sample_rate); + ret = msm_pcm_routing_reg_stream_app_type_cfg(fe_id, session_type, + be_id, app_type, + acdb_dev_id, sample_rate); + if (ret < 0) + pr_err("%s: msm_pcm_routing_reg_stream_app_type_cfg failed returned %d\n", + __func__, ret); - return 0; + return ret; } static int msm_compr_playback_app_type_cfg_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { u64 fe_id = kcontrol->private_value; + int session_type = SESSION_TYPE_RX; + int be_id = ucontrol->value.integer.value[3]; 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_MAX) { - pr_err("%s Received out of bounds fe_id %llu\n", - __func__, fe_id); - ret = -EINVAL; - goto done; - } - - ret = msm_pcm_routing_get_stream_app_type_cfg(fe_id, SESSION_TYPE_RX, - &app_type, &acdb_dev_id, &sample_rate); + ret = msm_pcm_routing_get_stream_app_type_cfg(fe_id, session_type, + be_id, &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); @@ -3271,8 +3268,8 @@ static int msm_compr_playback_app_type_cfg_get(struct snd_kcontrol *kcontrol, 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_RX, + pr_debug("%s: fedai_id %llu, session_type %d, be_id %d, app_type %d, acdb_dev_id %d, sample_rate %d\n", + __func__, fe_id, session_type, be_id, app_type, acdb_dev_id, sample_rate); done: return ret; @@ -3282,48 +3279,45 @@ static int msm_compr_capture_app_type_cfg_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { u64 fe_id = kcontrol->private_value; + int session_type = SESSION_TYPE_TX; + int be_id = ucontrol->value.integer.value[3]; + int ret = 0; int app_type; int acdb_dev_id; int sample_rate = 48000; - pr_debug("%s: fe_id- %llu\n", __func__, fe_id); - if (fe_id >= MSM_FRONTEND_DAI_MAX) { - 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]; if (ucontrol->value.integer.value[2] != 0) 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); + pr_debug("%s: fe_id- %llu session_type- %d be_id- %d app_type- %d acdb_dev_id- %d sample_rate- %d\n", + __func__, fe_id, session_type, be_id, + app_type, acdb_dev_id, sample_rate); + ret = msm_pcm_routing_reg_stream_app_type_cfg(fe_id, session_type, + be_id, app_type, + acdb_dev_id, sample_rate); + if (ret < 0) + pr_err("%s: msm_pcm_routing_reg_stream_app_type_cfg failed returned %d\n", + __func__, ret); - return 0; + return ret; } static int msm_compr_capture_app_type_cfg_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { u64 fe_id = kcontrol->private_value; + int session_type = SESSION_TYPE_TX; + int be_id = ucontrol->value.integer.value[3]; 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_MAX) { - pr_err("%s Received out of bounds fe_id %llu\n", - __func__, fe_id); - ret = -EINVAL; - goto done; - } - - ret = msm_pcm_routing_get_stream_app_type_cfg(fe_id, SESSION_TYPE_TX, - &app_type, &acdb_dev_id, &sample_rate); + ret = msm_pcm_routing_get_stream_app_type_cfg(fe_id, session_type, + be_id, &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); @@ -3333,8 +3327,8 @@ static int msm_compr_capture_app_type_cfg_get(struct snd_kcontrol *kcontrol, 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, + pr_debug("%s: fedai_id %llu, session_type %d, be_id %d, app_type %d, acdb_dev_id %d, sample_rate %d\n", + __func__, fe_id, session_type, be_id, app_type, acdb_dev_id, sample_rate); done: return ret; diff --git a/sound/soc/msm/qdsp6v2/msm-lsm-client.c b/sound/soc/msm/qdsp6v2/msm-lsm-client.c index 55ca659567f5..3fa14d0113ef 100644 --- a/sound/soc/msm/qdsp6v2/msm-lsm-client.c +++ b/sound/soc/msm/qdsp6v2/msm-lsm-client.c @@ -2204,26 +2204,26 @@ 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 session_type = SESSION_TYPE_TX; + int be_id = ucontrol->value.integer.value[3]; + 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; - } - 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); + pr_debug("%s: fe_id- %llu session_type- %d be_id- %d app_type- %d acdb_dev_id- %d sample_rate- %d\n", + __func__, fe_id, session_type, be_id, + app_type, acdb_dev_id, sample_rate); + ret = msm_pcm_routing_reg_stream_app_type_cfg(fe_id, session_type, + be_id, app_type, + acdb_dev_id, sample_rate); + if (ret < 0) + pr_err("%s: msm_pcm_routing_reg_stream_app_type_cfg failed returned %d\n", + __func__, ret); return 0; } @@ -2232,21 +2232,17 @@ 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 session_type = SESSION_TYPE_TX; + int be_id = ucontrol->value.integer.value[3]; 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); + ret = msm_pcm_routing_get_stream_app_type_cfg(fe_id, session_type, + be_id, &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); @@ -2256,8 +2252,8 @@ static int msm_lsm_app_type_cfg_ctl_get(struct snd_kcontrol *kcontrol, 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, + pr_debug("%s: fedai_id %llu, session_type %d, be_id %d, app_type %d, acdb_dev_id %d, sample_rate %d\n", + __func__, fe_id, session_type, be_id, app_type, acdb_dev_id, sample_rate); done: return ret; diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-loopback-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-loopback-v2.c index bd1468beedf6..b8610b59ca63 100644 --- a/sound/soc/msm/qdsp6v2/msm-pcm-loopback-v2.c +++ b/sound/soc/msm/qdsp6v2/msm-pcm-loopback-v2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-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 @@ -556,48 +556,45 @@ static int msm_pcm_playback_app_type_cfg_ctl_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { u64 fe_id = kcontrol->private_value; + int session_type = SESSION_TYPE_RX; + int be_id = ucontrol->value.integer.value[3]; + int ret = 0; int app_type; int acdb_dev_id; int sample_rate = 48000; - pr_debug("%s: fe_id- %llu\n", __func__, fe_id); - if (fe_id >= MSM_FRONTEND_DAI_MAX) { - 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]; if (ucontrol->value.integer.value[2] != 0) 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_RX); - msm_pcm_routing_reg_stream_app_type_cfg(fe_id, app_type, - acdb_dev_id, sample_rate, SESSION_TYPE_RX); + pr_debug("%s: fe_id- %llu session_type- %d be_id- %d app_type- %d acdb_dev_id- %d sample_rate- %d\n", + __func__, fe_id, session_type, be_id, + app_type, acdb_dev_id, sample_rate); + ret = msm_pcm_routing_reg_stream_app_type_cfg(fe_id, session_type, + be_id, app_type, + acdb_dev_id, sample_rate); + if (ret < 0) + pr_err("%s: msm_pcm_routing_reg_stream_app_type_cfg failed returned %d\n", + __func__, ret); - return 0; + return ret; } static int msm_pcm_playback_app_type_cfg_ctl_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { u64 fe_id = kcontrol->private_value; + int session_type = SESSION_TYPE_RX; + int be_id = ucontrol->value.integer.value[3]; 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_MAX) { - pr_err("%s: Received out of bounds fe_id %llu\n", - __func__, fe_id); - ret = -EINVAL; - goto done; - } - - ret = msm_pcm_routing_get_stream_app_type_cfg(fe_id, SESSION_TYPE_RX, - &app_type, &acdb_dev_id, &sample_rate); + ret = msm_pcm_routing_get_stream_app_type_cfg(fe_id, session_type, + be_id, &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); @@ -607,8 +604,8 @@ static int msm_pcm_playback_app_type_cfg_ctl_get(struct snd_kcontrol *kcontrol, 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_RX, + pr_debug("%s: fedai_id %llu, session_type %d, be_id %d, app_type %d, acdb_dev_id %d, sample_rate %d\n", + __func__, fe_id, session_type, be_id, app_type, acdb_dev_id, sample_rate); done: return ret; @@ -618,48 +615,45 @@ static int msm_pcm_capture_app_type_cfg_ctl_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { u64 fe_id = kcontrol->private_value; + int session_type = SESSION_TYPE_TX; + int be_id = ucontrol->value.integer.value[3]; + int ret = 0; int app_type; int acdb_dev_id; int sample_rate = 48000; - pr_debug("%s: fe_id- %llu\n", __func__, fe_id); - if (fe_id >= MSM_FRONTEND_DAI_MAX) { - 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]; if (ucontrol->value.integer.value[2] != 0) 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); + pr_debug("%s: fe_id- %llu session_type- %d be_id- %d app_type- %d acdb_dev_id- %d sample_rate- %d\n", + __func__, fe_id, session_type, be_id, + app_type, acdb_dev_id, sample_rate); + ret = msm_pcm_routing_reg_stream_app_type_cfg(fe_id, session_type, + be_id, app_type, + acdb_dev_id, sample_rate); + if (ret < 0) + pr_err("%s: msm_pcm_routing_reg_stream_app_type_cfg failed returned %d\n", + __func__, ret); - return 0; + return ret; } static int msm_pcm_capture_app_type_cfg_ctl_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { u64 fe_id = kcontrol->private_value; + int session_type = SESSION_TYPE_TX; + int be_id = ucontrol->value.integer.value[3]; 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_MAX) { - pr_err("%s: Received out of bounds fe_id %llu\n", - __func__, fe_id); - ret = -EINVAL; - goto done; - } - - ret = msm_pcm_routing_get_stream_app_type_cfg(fe_id, SESSION_TYPE_TX, - &app_type, &acdb_dev_id, &sample_rate); + ret = msm_pcm_routing_get_stream_app_type_cfg(fe_id, session_type, + be_id, &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); @@ -669,8 +663,8 @@ static int msm_pcm_capture_app_type_cfg_ctl_get(struct snd_kcontrol *kcontrol, 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, + pr_debug("%s: fedai_id %llu, session_type %d, be_id %d, app_type %d, acdb_dev_id %d, sample_rate %d\n", + __func__, fe_id, session_type, be_id, app_type, acdb_dev_id, sample_rate); done: return ret; diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c index 9b672d803d31..e2f662f26cff 100644 --- a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c +++ b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c @@ -1182,48 +1182,45 @@ static int msm_pcm_playback_app_type_cfg_ctl_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { u64 fe_id = kcontrol->private_value; + int session_type = SESSION_TYPE_RX; + int be_id = ucontrol->value.integer.value[3]; + int ret = 0; int app_type; int acdb_dev_id; int sample_rate = 48000; - pr_debug("%s: fe_id- %llu\n", __func__, fe_id); - if (fe_id >= MSM_FRONTEND_DAI_MAX) { - 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]; - if (0 != ucontrol->value.integer.value[2]) + if (ucontrol->value.integer.value[2] != 0) 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_RX); - msm_pcm_routing_reg_stream_app_type_cfg(fe_id, app_type, - acdb_dev_id, sample_rate, SESSION_TYPE_RX); + pr_debug("%s: fe_id- %llu session_type- %d be_id- %d app_type- %d acdb_dev_id- %d sample_rate- %d\n", + __func__, fe_id, session_type, be_id, + app_type, acdb_dev_id, sample_rate); + ret = msm_pcm_routing_reg_stream_app_type_cfg(fe_id, session_type, + be_id, app_type, + acdb_dev_id, sample_rate); + if (ret < 0) + pr_err("%s: msm_pcm_routing_reg_stream_app_type_cfg failed returned %d\n", + __func__, ret); - return 0; + return ret; } static int msm_pcm_playback_app_type_cfg_ctl_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { u64 fe_id = kcontrol->private_value; + int session_type = SESSION_TYPE_RX; + int be_id = ucontrol->value.integer.value[3]; 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_MAX) { - pr_err("%s Received out of bounds fe_id %llu\n", - __func__, fe_id); - ret = -EINVAL; - goto done; - } - - ret = msm_pcm_routing_get_stream_app_type_cfg(fe_id, SESSION_TYPE_RX, - &app_type, &acdb_dev_id, &sample_rate); + ret = msm_pcm_routing_get_stream_app_type_cfg(fe_id, session_type, + be_id, &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); @@ -1233,8 +1230,8 @@ static int msm_pcm_playback_app_type_cfg_ctl_get(struct snd_kcontrol *kcontrol, 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_RX, + pr_debug("%s: fedai_id %llu, session_type %d, be_id %d, app_type %d, acdb_dev_id %d, sample_rate %d\n", + __func__, fe_id, session_type, be_id, app_type, acdb_dev_id, sample_rate); done: return ret; @@ -1244,48 +1241,45 @@ static int msm_pcm_capture_app_type_cfg_ctl_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { u64 fe_id = kcontrol->private_value; + int session_type = SESSION_TYPE_TX; + int be_id = ucontrol->value.integer.value[3]; + int ret = 0; int app_type; int acdb_dev_id; int sample_rate = 48000; - pr_debug("%s: fe_id- %llu\n", __func__, fe_id); - if (fe_id >= MSM_FRONTEND_DAI_MAX) { - 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]; if (ucontrol->value.integer.value[2] != 0) 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); + pr_debug("%s: fe_id- %llu session_type- %d be_id- %d app_type- %d acdb_dev_id- %d sample_rate- %d\n", + __func__, fe_id, session_type, be_id, + app_type, acdb_dev_id, sample_rate); + ret = msm_pcm_routing_reg_stream_app_type_cfg(fe_id, session_type, + be_id, app_type, + acdb_dev_id, sample_rate); + if (ret < 0) + pr_err("%s: msm_pcm_routing_reg_stream_app_type_cfg failed returned %d\n", + __func__, ret); - return 0; + return ret; } static int msm_pcm_capture_app_type_cfg_ctl_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { u64 fe_id = kcontrol->private_value; + int session_type = SESSION_TYPE_TX; + int be_id = ucontrol->value.integer.value[3]; 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_MAX) { - pr_err("%s: Received out of bounds fe_id %llu\n", - __func__, fe_id); - ret = -EINVAL; - goto done; - } - - ret = msm_pcm_routing_get_stream_app_type_cfg(fe_id, SESSION_TYPE_TX, - &app_type, &acdb_dev_id, &sample_rate); + ret = msm_pcm_routing_get_stream_app_type_cfg(fe_id, session_type, + be_id, &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); @@ -1295,8 +1289,8 @@ static int msm_pcm_capture_app_type_cfg_ctl_get(struct snd_kcontrol *kcontrol, 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, + pr_debug("%s: fedai_id %llu, session_type %d, be_id %d, app_type %d, acdb_dev_id %d, sample_rate %d\n", + __func__, fe_id, session_type, be_id, app_type, acdb_dev_id, sample_rate); done: return ret; diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c index 39fdd6b49357..658ace327283 100644 --- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c +++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c @@ -56,8 +56,6 @@ #define DS2_ADM_COPP_TOPOLOGY_ID 0xFFFFFFFF #endif -static int get_cal_path(int path_type); - static struct mutex routing_lock; static struct cal_type_data *cal_data; @@ -124,6 +122,18 @@ static struct msm_pcm_route_bdai_pp_params {DISPLAY_PORT_RX, 0, 0, 0}, }; +/* + * The be_dai_name_table is passed to HAL so that it can specify the + * BE ID for the BE it wants to enable based on the name. Thus there + * is a matching table and structure in HAL that need to be updated + * if any changes to these are made. + */ +struct msm_pcm_route_bdai_name { + unsigned int be_id; + char be_name[LPASS_BE_NAME_MAX_LENGTH]; +}; +static struct msm_pcm_route_bdai_name be_dai_name_table[MSM_BACKEND_DAI_MAX]; + static int msm_routing_send_device_pp_params(int port_id, int copp_idx); static int msm_routing_get_bit_width(unsigned int format) @@ -663,7 +673,7 @@ static unsigned long session_copp_map[MSM_FRONTEND_DAI_MAX][2] 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_MAX][2]; + fe_dai_app_type_cfg[MSM_FRONTEND_DAI_MAX][2][MSM_BACKEND_DAI_MAX]; /* The caller of this should aqcuire routing lock */ void msm_pcm_routing_get_bedai_info(int be_idx, @@ -731,45 +741,64 @@ static bool is_mm_lsm_fe_id(int fe_id) 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) +int msm_pcm_routing_reg_stream_app_type_cfg(int fedai_id, int session_type, + int be_id, int app_type, + int acdb_dev_id, int sample_rate) { - 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); + int ret = 0; + + pr_debug("%s: fedai_id %d, session_type %d, be_id %d, app_type %d, acdb_dev_id %d, sample_rate %d\n", + __func__, fedai_id, session_type, be_id, + app_type, acdb_dev_id, sample_rate); + if (!is_mm_lsm_fe_id(fedai_id)) { pr_err("%s: Invalid machine driver ID %d\n", __func__, fedai_id); - return; + ret = -EINVAL; + goto done; } if (session_type != SESSION_TYPE_RX && session_type != SESSION_TYPE_TX) { pr_err("%s: Invalid session type %d\n", __func__, session_type); - return; + ret = -EINVAL; + goto done; } - fe_dai_app_type_cfg[fedai_id][session_type].app_type = app_type; - fe_dai_app_type_cfg[fedai_id][session_type].acdb_dev_id = acdb_dev_id; - fe_dai_app_type_cfg[fedai_id][session_type].sample_rate = sample_rate; + if (be_id < 0 || be_id >= MSM_BACKEND_DAI_MAX) { + pr_err("%s: Received out of bounds be_id %d\n", + __func__, be_id); + ret = -EINVAL; + goto done; + } + + fe_dai_app_type_cfg[fedai_id][session_type][be_id].app_type = app_type; + fe_dai_app_type_cfg[fedai_id][session_type][be_id].acdb_dev_id = + acdb_dev_id; + fe_dai_app_type_cfg[fedai_id][session_type][be_id].sample_rate = + sample_rate; + +done: + return ret; } /** * msm_pcm_routing_get_stream_app_type_cfg * - * Receives fedai_id, session_type and populates app_type, acdb_dev_id, & - * sample rate. Returns 0 on success. On failure returns + * Receives fedai_id, session_type, be_id, and populates app_type, + * acdb_dev_id, & sample rate. Returns 0 on success. On failure returns * -EINVAL and does not alter passed values. * * fedai_id - Passed value, front end ID for which app type config is wanted * session_type - Passed value, session type for which app type config * is wanted + * be_id - Passed value, back end device id for which app type config is wanted * app_type - Returned value, app type used by app type config * acdb_dev_id - Returned value, ACDB device ID used by app type config * sample_rate - Returned value, sample rate used by app type config */ int msm_pcm_routing_get_stream_app_type_cfg(int fedai_id, int session_type, - int *app_type, int *acdb_dev_id, int *sample_rate) + int be_id, int *app_type, + int *acdb_dev_id, int *sample_rate) { int ret = 0; @@ -791,18 +820,25 @@ int msm_pcm_routing_get_stream_app_type_cfg(int fedai_id, int session_type, ret = -EINVAL; goto done; } else if (session_type != SESSION_TYPE_RX && - session_type != SESSION_TYPE_TX) { + session_type != SESSION_TYPE_TX) { pr_err("%s: Invalid session type %d\n", __func__, session_type); ret = -EINVAL; goto done; + } else if (be_id < 0 || be_id >= MSM_BACKEND_DAI_MAX) { + pr_err("%s: Received out of bounds be_id %d\n", + __func__, be_id); + return -EINVAL; } - *app_type = fe_dai_app_type_cfg[fedai_id][session_type].app_type; - *acdb_dev_id = fe_dai_app_type_cfg[fedai_id][session_type].acdb_dev_id; - *sample_rate = fe_dai_app_type_cfg[fedai_id][session_type].sample_rate; - 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 = fe_dai_app_type_cfg[fedai_id][session_type][be_id].app_type; + *acdb_dev_id = + fe_dai_app_type_cfg[fedai_id][session_type][be_id].acdb_dev_id; + *sample_rate = + fe_dai_app_type_cfg[fedai_id][session_type][be_id].sample_rate; + + pr_debug("%s: fedai_id %d, session_type %d, be_id %d, app_type %d, acdb_dev_id %d, sample_rate %d\n", + __func__, fedai_id, session_type, be_id, *app_type, *acdb_dev_id, *sample_rate); done: return ret; @@ -858,24 +894,27 @@ static struct cal_block_data *msm_routing_find_topology(int path, return msm_routing_find_topology_by_path(path); } -static int msm_routing_get_adm_topology(int path, int fedai_id, - int session_type) +static int msm_routing_get_adm_topology(int fedai_id, int session_type, + int be_id) { - int topology = NULL_COPP_TOPOLOGY; - struct cal_block_data *cal_block = NULL; + int topology = NULL_COPP_TOPOLOGY; + struct cal_block_data *cal_block = NULL; int app_type = 0, acdb_dev_id = 0; - pr_debug("%s\n", __func__); - path = get_cal_path(path); + pr_debug("%s: fedai_id %d, session_type %d, be_id %d\n", + __func__, fedai_id, session_type, be_id); + if (cal_data == NULL) goto done; mutex_lock(&cal_data->lock); - app_type = fe_dai_app_type_cfg[fedai_id][session_type].app_type; - acdb_dev_id = fe_dai_app_type_cfg[fedai_id][session_type].acdb_dev_id; + app_type = fe_dai_app_type_cfg[fedai_id][session_type][be_id].app_type; + acdb_dev_id = + fe_dai_app_type_cfg[fedai_id][session_type][be_id].acdb_dev_id; - cal_block = msm_routing_find_topology(path, app_type, acdb_dev_id); + cal_block = msm_routing_find_topology(session_type, app_type, + acdb_dev_id); if (cal_block == NULL) goto unlock; @@ -905,8 +944,8 @@ static void msm_pcm_routing_build_matrix(int fedai_id, int sess_type, int i, port_type, j, num_copps = 0; struct route_payload payload; - port_type = ((path_type == ADM_PATH_PLAYBACK || - path_type == ADM_PATH_COMPRESSED_RX) ? + port_type = ((path_type == ADM_PATH_PLAYBACK || + path_type == ADM_PATH_COMPRESSED_RX) ? MSM_AFE_PORT_TYPE_RX : MSM_AFE_PORT_TYPE_TX); for (i = 0; i < MSM_BACKEND_DAI_MAX; i++) { @@ -921,6 +960,18 @@ static void msm_pcm_routing_build_matrix(int fedai_id, int sess_type, payload.port_id[num_copps] = msm_bedais[i].port_id; payload.copp_idx[num_copps] = j; + payload.app_type[num_copps] = + fe_dai_app_type_cfg + [fedai_id][sess_type][i] + .app_type; + payload.acdb_dev_id[num_copps] = + fe_dai_app_type_cfg + [fedai_id][sess_type][i] + .acdb_dev_id; + payload.sample_rate[num_copps] = + fe_dai_app_type_cfg + [fedai_id][sess_type][i] + .sample_rate; num_copps++; } } @@ -930,12 +981,6 @@ static void msm_pcm_routing_build_matrix(int fedai_id, int sess_type, if (num_copps) { payload.num_copps = num_copps; payload.session_id = fe_dai_map[fedai_id][sess_type].strm_id; - payload.app_type = - fe_dai_app_type_cfg[fedai_id][sess_type].app_type; - payload.acdb_dev_id = - 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, passthr_mode); msm_pcm_routng_cfg_matrix_map_pp(payload, path_type, perf_mode); } @@ -1001,7 +1046,8 @@ int msm_pcm_routing_reg_phy_compr_stream(int fe_id, int perf_mode, int dspst_id, int stream_type, uint32_t passthr_mode) { - int i, j, session_type, path_type, port_type, topology, num_copps = 0; + int i, j, session_type, path_type, port_type, topology; + int num_copps = 0; struct route_payload payload; u32 channels, sample_rate; u16 bit_width = 16; @@ -1069,13 +1115,13 @@ int msm_pcm_routing_reg_phy_compr_stream(int fe_id, int perf_mode, bit_width = msm_routing_get_bit_width( msm_bedais[i].format); app_type = - fe_dai_app_type_cfg[fe_id][session_type].app_type; + fe_dai_app_type_cfg[fe_id][session_type][i].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; + fe_dai_app_type_cfg[fe_id][session_type][i] + .sample_rate; bit_width = lsm_app_type_cfg[app_type_idx].bit_width; } else if (app_type) { @@ -1083,17 +1129,17 @@ int msm_pcm_routing_reg_phy_compr_stream(int fe_id, int perf_mode, msm_pcm_routing_get_app_type_idx( app_type); sample_rate = - fe_dai_app_type_cfg[fe_id][session_type].sample_rate; + fe_dai_app_type_cfg[fe_id][session_type][i].sample_rate; bit_width = app_type_cfg[app_type_idx].bit_width; } else { sample_rate = msm_bedais[i].sample_rate; } acdb_dev_id = - fe_dai_app_type_cfg[fe_id][session_type].acdb_dev_id; - topology = msm_routing_get_adm_topology(path_type, - fe_id, session_type); - + fe_dai_app_type_cfg[fe_id][session_type][i].acdb_dev_id; + topology = msm_routing_get_adm_topology(fe_id, + session_type, + i); if (passthr_mode == COMPRESSED_PASSTHROUGH_DSD) topology = COMPRESS_PASSTHROUGH_NONE_TOPOLOGY; pr_debug("%s: Before adm open topology %d\n", __func__, @@ -1130,6 +1176,18 @@ int msm_pcm_routing_reg_phy_compr_stream(int fe_id, int perf_mode, payload.port_id[num_copps] = msm_bedais[i].port_id; payload.copp_idx[num_copps] = j; + payload.app_type[num_copps] = + fe_dai_app_type_cfg + [fe_id][session_type][i] + .app_type; + payload.acdb_dev_id[num_copps] = + fe_dai_app_type_cfg + [fe_id][session_type][i] + .acdb_dev_id; + payload.sample_rate[num_copps] = + fe_dai_app_type_cfg + [fe_id][session_type][i] + .sample_rate; num_copps++; } } @@ -1143,12 +1201,6 @@ int msm_pcm_routing_reg_phy_compr_stream(int fe_id, int perf_mode, if (num_copps) { payload.num_copps = num_copps; payload.session_id = fe_dai_map[fe_id][session_type].strm_id; - payload.app_type = - 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; - 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); } @@ -1247,22 +1299,24 @@ int msm_pcm_routing_reg_phy_stream(int fedai_id, int perf_mode, msm_bedais[i].format); app_type = - fe_dai_app_type_cfg[fedai_id][session_type].app_type; + fe_dai_app_type_cfg[fedai_id][session_type][i].app_type; if (app_type) { app_type_idx = msm_pcm_routing_get_app_type_idx(app_type); sample_rate = - fe_dai_app_type_cfg[fedai_id][session_type]. - sample_rate; + fe_dai_app_type_cfg[fedai_id][session_type][i] + .sample_rate; bits_per_sample = app_type_cfg[app_type_idx].bit_width; } else sample_rate = msm_bedais[i].sample_rate; acdb_dev_id = - fe_dai_app_type_cfg[fedai_id][session_type].acdb_dev_id; - topology = msm_routing_get_adm_topology(path_type, - fedai_id, session_type); + fe_dai_app_type_cfg[fedai_id][session_type][i] + .acdb_dev_id; + topology = msm_routing_get_adm_topology(fedai_id, + session_type, + i); copp_idx = adm_open(msm_bedais[i].port_id, path_type, sample_rate, channels, topology, perf_mode, bits_per_sample, @@ -1293,6 +1347,18 @@ int msm_pcm_routing_reg_phy_stream(int fedai_id, int perf_mode, payload.port_id[num_copps] = msm_bedais[i].port_id; payload.copp_idx[num_copps] = j; + payload.app_type[num_copps] = + fe_dai_app_type_cfg + [fedai_id][session_type] + [i].app_type; + payload.acdb_dev_id[num_copps] = + fe_dai_app_type_cfg + [fedai_id][session_type] + [i].acdb_dev_id; + payload.sample_rate[num_copps] = + fe_dai_app_type_cfg + [fedai_id][session_type] + [i].sample_rate; num_copps++; } } @@ -1307,12 +1373,6 @@ int msm_pcm_routing_reg_phy_stream(int fedai_id, int perf_mode, if (num_copps) { payload.num_copps = num_copps; payload.session_id = fe_dai_map[fedai_id][session_type].strm_id; - payload.app_type = - fe_dai_app_type_cfg[fedai_id][session_type].app_type; - payload.acdb_dev_id = - 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, passthr_mode); msm_pcm_routng_cfg_matrix_map_pp(payload, path_type, perf_mode); } @@ -1491,30 +1551,31 @@ static void msm_pcm_routing_process_audio(u16 reg, u16 val, int set) msm_bedais[reg].format); app_type = - fe_dai_app_type_cfg[val][session_type].app_type; + fe_dai_app_type_cfg[val][session_type][reg].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; + fe_dai_app_type_cfg[val][session_type][reg] + .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 = - fe_dai_app_type_cfg[val][session_type]. - sample_rate; + fe_dai_app_type_cfg[val][session_type][reg] + .sample_rate; bits_per_sample = app_type_cfg[app_type_idx].bit_width; } else sample_rate = msm_bedais[reg].sample_rate; - topology = msm_routing_get_adm_topology(path_type, val, - session_type); + topology = msm_routing_get_adm_topology(val, + session_type, + reg); acdb_dev_id = - fe_dai_app_type_cfg[val][session_type].acdb_dev_id; + fe_dai_app_type_cfg[val][session_type][reg].acdb_dev_id; copp_idx = adm_open(msm_bedais[reg].port_id, path_type, sample_rate, channels, topology, fdai->perf_mode, bits_per_sample, @@ -1847,6 +1908,68 @@ static int msm_routing_put_voice_stub_mixer(struct snd_kcontrol *kcontrol, return 1; } +/* + * Return the mapping between port ID and backend ID to enable the AFE callback + * to determine the acdb_dev_id from the port id + */ +int msm_pcm_get_be_id_from_port_id(int port_id) +{ + int i; + int be_id = -EINVAL; + + for (i = 0; i < MSM_BACKEND_DAI_MAX; i++) { + if (msm_bedais[i].port_id == port_id) { + be_id = i; + break; + } + } + + return be_id; +} + +/* + * Return the registered dev_acdb_id given a port ID to enable identifying the + * correct AFE calibration information by comparing the header information. + */ +static int msm_pcm_get_dev_acdb_id_by_port_id(int port_id) +{ + int acdb_id = -EINVAL; + int i = 0; + int session; + int port_type = afe_get_port_type(port_id); + int be_id = msm_pcm_get_be_id_from_port_id(port_id); + + pr_debug("%s:port_id %d be_id %d, port_type 0x%x\n", + __func__, port_id, be_id, port_type); + + if (port_type == MSM_AFE_PORT_TYPE_TX) { + session = SESSION_TYPE_TX; + } else if (port_type == MSM_AFE_PORT_TYPE_RX) { + session = SESSION_TYPE_RX; + } else { + pr_err("%s: Invalid port type %d\n", __func__, port_type); + acdb_id = -EINVAL; + goto exit; + } + + if (be_id < 0) { + pr_err("%s: Error getting backend id %d\n", __func__, be_id); + goto exit; + } + + mutex_lock(&routing_lock); + i = find_first_bit(&msm_bedais[be_id].fe_sessions[0], + MSM_FRONTEND_DAI_MAX); + if (i < MSM_FRONTEND_DAI_MAX) + acdb_id = fe_dai_app_type_cfg[i][session][be_id].acdb_dev_id; + + pr_debug("%s: FE[%d] session[%d] BE[%d] acdb_id(%d)\n", + __func__, i, session, be_id, acdb_id); + mutex_unlock(&routing_lock); +exit: + return acdb_id; +} + static int msm_routing_get_switch_mixer(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -13884,21 +14007,21 @@ static int msm_pcm_routing_prepare(struct snd_pcm_substream *substream) bedai->format); app_type = - fe_dai_app_type_cfg[i][session_type].app_type; + fe_dai_app_type_cfg[i][session_type][be_id].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; + fe_dai_app_type_cfg[i][session_type][be_id] + .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 = - fe_dai_app_type_cfg[i][session_type]. - sample_rate; + fe_dai_app_type_cfg[i][session_type] + [be_id].sample_rate; bits_per_sample = app_type_cfg[app_type_idx].bit_width; } else @@ -13912,9 +14035,9 @@ static int msm_pcm_routing_prepare(struct snd_pcm_substream *substream) else channels = bedai->adm_override_ch; acdb_dev_id = - fe_dai_app_type_cfg[i][session_type].acdb_dev_id; - topology = msm_routing_get_adm_topology(path_type, i, - session_type); + fe_dai_app_type_cfg[i][session_type][be_id].acdb_dev_id; + topology = msm_routing_get_adm_topology(i, session_type, + be_id); copp_idx = adm_open(bedai->port_id, path_type, sample_rate, channels, topology, fdai->perf_mode, bits_per_sample, @@ -14201,6 +14324,64 @@ static const struct snd_kcontrol_new aptx_dec_license_controls[] = { msm_aptx_dec_license_control_put), }; +static int msm_routing_be_dai_name_table_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; + uinfo->count = sizeof(be_dai_name_table); + return 0; +} + +static int msm_routing_be_dai_name_table_tlv_get(unsigned int __user *bytes, + unsigned int size) +{ + int i; + int ret; + + if (size < sizeof(be_dai_name_table)) { + pr_err("%s: invalid size %d requested, returning\n", + __func__, size); + ret = -EINVAL; + goto done; + } + + /* + * Fill be_dai_name_table from msm_bedais table to reduce code changes + * needed when adding new backends + */ + for (i = 0; i < MSM_BACKEND_DAI_MAX; i++) { + be_dai_name_table[i].be_id = i; + strlcpy(be_dai_name_table[i].be_name, + msm_bedais[i].name, + LPASS_BE_NAME_MAX_LENGTH); + } + + ret = copy_to_user(bytes, &be_dai_name_table, + sizeof(be_dai_name_table)); + if (ret) { + pr_err("%s: failed to copy be_dai_name_table\n", __func__); + ret = -EFAULT; + } + +done: + return ret; +} + +static const struct snd_kcontrol_new + msm_routing_be_dai_name_table_mixer_controls[] = { + { + .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | + SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK, + .info = msm_routing_be_dai_name_table_info, + .name = "Backend DAI Name Table", + .tlv.c = snd_soc_bytes_tlv_callback, + .private_value = (unsigned long) &(struct soc_bytes_ext) { + .max = sizeof(be_dai_name_table), + .get = msm_routing_be_dai_name_table_tlv_get, + } + }, +}; + static struct snd_pcm_ops msm_routing_pcm_ops = { .hw_params = msm_pcm_routing_hw_params, .close = msm_pcm_routing_close, @@ -14253,6 +14434,10 @@ static int msm_routing_probe(struct snd_soc_platform *platform) device_pp_params_mixer_controls, ARRAY_SIZE(device_pp_params_mixer_controls)); + snd_soc_add_platform_controls(platform, + msm_routing_be_dai_name_table_mixer_controls, + ARRAY_SIZE(msm_routing_be_dai_name_table_mixer_controls)); + msm_dts_eagle_add_controls(platform); snd_soc_add_platform_controls(platform, msm_source_tracking_controls, @@ -14327,15 +14512,6 @@ int msm_routing_check_backend_enabled(int fedai_id) return 0; } -static int get_cal_path(int path_type) -{ - if (path_type == ADM_PATH_PLAYBACK || - path_type == ADM_PATH_COMPRESSED_RX) - return RX_DEVICE; - else - return TX_DEVICE; -} - static int msm_routing_set_cal(int32_t cal_type, size_t data_size, void *data) { @@ -14394,6 +14570,11 @@ static int __init msm_soc_routing_platform_init(void) if (msm_routing_init_cal_data()) pr_err("%s: could not init cal data!\n", __func__); + afe_set_routing_callback( + (routing_cb)msm_pcm_get_dev_acdb_id_by_port_id); + + memset(&be_dai_name_table, 0, sizeof(be_dai_name_table)); + return platform_driver_register(&msm_routing_pcm_driver); } module_init(msm_soc_routing_platform_init); @@ -14401,6 +14582,7 @@ module_init(msm_soc_routing_platform_init); static void __exit msm_soc_routing_platform_exit(void) { msm_routing_delete_cal_data(); + memset(&be_dai_name_table, 0, sizeof(be_dai_name_table)); platform_driver_unregister(&msm_routing_pcm_driver); } module_exit(msm_soc_routing_platform_exit); diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h index a066e9afc9e5..94c79f00afec 100644 --- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h +++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h @@ -13,6 +13,12 @@ #define _MSM_PCM_ROUTING_H #include +/* + * These names are used by HAL to specify the BE. If any changes are + * made to the string names or the max name length corresponding + * changes need to be made in the HAL to ensure they still match. + */ +#define LPASS_BE_NAME_MAX_LENGTH 24 #define LPASS_BE_PRI_I2S_RX "PRIMARY_I2S_RX" #define LPASS_BE_PRI_I2S_TX "PRIMARY_I2S_TX" #define LPASS_BE_SLIMBUS_0_RX "SLIMBUS_0_RX" @@ -470,8 +476,10 @@ void msm_pcm_routing_get_fedai_info(int fe_idx, int sess_type, void msm_pcm_routing_acquire_lock(void); void msm_pcm_routing_release_lock(void); -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); +int msm_pcm_routing_reg_stream_app_type_cfg(int fedai_id, int session_type, + int be_id, int app_type, + int acdb_dev_id, int sample_rate); int msm_pcm_routing_get_stream_app_type_cfg(int fedai_id, int session_type, - int *app_type, int *acdb_dev_id, int *sample_rate); + int be_id, int *app_type, + int *acdb_dev_id, int *sample_rate); #endif /*_MSM_PCM_H*/ diff --git a/sound/soc/msm/qdsp6v2/q6adm.c b/sound/soc/msm/qdsp6v2/q6adm.c index 16ae05034662..4a4f02c7b9b6 100644 --- a/sound/soc/msm/qdsp6v2/q6adm.c +++ b/sound/soc/msm/qdsp6v2/q6adm.c @@ -2815,8 +2815,8 @@ int adm_matrix_map(int path, struct route_payload payload_map, int perf_mode, [port_idx][copp_idx]), get_cal_path(path), payload_map.session_id, - payload_map.app_type, - payload_map.acdb_dev_id); + payload_map.app_type[i], + payload_map.acdb_dev_id[i]); if (!test_bit(ADM_STATUS_CALIBRATION_REQUIRED, (void *)&this_adm.copp.adm_status[port_idx] @@ -2827,9 +2827,9 @@ int adm_matrix_map(int path, struct route_payload payload_map, int perf_mode, } send_adm_cal(payload_map.port_id[i], copp_idx, get_cal_path(path), perf_mode, - payload_map.app_type, - payload_map.acdb_dev_id, - payload_map.sample_rate); + payload_map.app_type[i], + payload_map.acdb_dev_id[i], + payload_map.sample_rate[i]); /* ADM COPP calibration is already sent */ clear_bit(ADM_STATUS_CALIBRATION_REQUIRED, (void *)&this_adm.copp. diff --git a/sound/soc/msm/qdsp6v2/q6afe.c b/sound/soc/msm/qdsp6v2/q6afe.c index f1607b8e5d66..32d5fa94de64 100644 --- a/sound/soc/msm/qdsp6v2/q6afe.c +++ b/sound/soc/msm/qdsp6v2/q6afe.c @@ -119,6 +119,8 @@ struct afe_ctl { struct aanc_data aanc_info; struct mutex afe_cmd_lock; int set_custom_topology; + int dev_acdb_id[AFE_MAX_PORTS]; + routing_cb rt_cb; }; static atomic_t afe_ports_mad_type[SLIMBUS_PORT_LAST - SLIMBUS_0_RX]; @@ -1245,6 +1247,10 @@ static struct cal_block_data *afe_find_cal_topo_id_by_port( struct cal_block_data *cal_block = NULL; int32_t path; struct audio_cal_info_afe_top *afe_top; + int afe_port_index = q6audio_get_port_index(port_id); + + if (afe_port_index < 0) + goto err_exit; list_for_each_safe(ptr, next, &cal_type->cal_blocks) { @@ -1255,13 +1261,17 @@ static struct cal_block_data *afe_find_cal_topo_id_by_port( MSM_AFE_PORT_TYPE_TX)?(TX_DEVICE):(RX_DEVICE)); afe_top = (struct audio_cal_info_afe_top *)cal_block->cal_info; - if (afe_top->path == path) { + if ((afe_top->path == path) && + (afe_top->acdb_id == + this_afe.dev_acdb_id[afe_port_index])) { pr_debug("%s: top_id:%x acdb_id:%d afe_port:%d\n", - __func__, afe_top->topology, afe_top->acdb_id, - q6audio_get_port_id(port_id)); + __func__, afe_top->topology, afe_top->acdb_id, + q6audio_get_port_id(port_id)); return cal_block; } } + +err_exit: return NULL; } @@ -1405,6 +1415,41 @@ done: return ret; } +static struct cal_block_data *afe_find_cal(int cal_index, int port_id) +{ + struct list_head *ptr, *next; + struct cal_block_data *cal_block = NULL; + struct audio_cal_info_afe *afe_cal_info = NULL; + int afe_port_index = q6audio_get_port_index(port_id); + + pr_debug("%s: cal_index %d port_id %d port_index %d\n", __func__, + cal_index, port_id, afe_port_index); + if (afe_port_index < 0) { + pr_err("%s: Error getting AFE port index %d\n", + __func__, afe_port_index); + goto exit; + } + + list_for_each_safe(ptr, next, + &this_afe.cal_data[cal_index]->cal_blocks) { + cal_block = list_entry(ptr, struct cal_block_data, list); + afe_cal_info = cal_block->cal_info; + if ((afe_cal_info->acdb_id == + this_afe.dev_acdb_id[afe_port_index]) && + (afe_cal_info->sample_rate == + this_afe.afe_sample_rates[afe_port_index])) { + pr_debug("%s: cal block is a match, size is %zd\n", + __func__, cal_block->cal_data.size); + goto exit; + } + } + pr_err("%s: no matching cal_block found\n", __func__); + cal_block = NULL; + +exit: + return cal_block; +} + static void send_afe_cal_type(int cal_index, int port_id) { struct cal_block_data *cal_block = NULL; @@ -1418,7 +1463,14 @@ static void send_afe_cal_type(int cal_index, int port_id) } mutex_lock(&this_afe.cal_data[cal_index]->lock); - cal_block = cal_utils_get_only_cal_block(this_afe.cal_data[cal_index]); + + if ((cal_index == AFE_COMMON_RX_CAL) || + (cal_index == AFE_COMMON_TX_CAL)) + cal_block = afe_find_cal(cal_index, port_id); + else + cal_block = cal_utils_get_only_cal_block( + this_afe.cal_data[cal_index]); + if (cal_block == NULL) { pr_err("%s cal_block not found!!\n", __func__); goto unlock; @@ -2518,6 +2570,13 @@ int afe_tdm_port_start(u16 port_id, struct afe_tdm_port_config *tdm_port, return ret; } + if ((index >= 0) && (index < AFE_MAX_PORTS)) { + this_afe.afe_sample_rates[index] = rate; + + if (this_afe.rt_cb) + this_afe.dev_acdb_id[index] = this_afe.rt_cb(port_id); + } + /* Also send the topology id here: */ port_index = afe_get_port_index(port_id); if (!(this_afe.afe_cal_mode[port_index] == AFE_CAL_MODE_NONE)) { @@ -2612,6 +2671,11 @@ void afe_set_cal_mode(u16 port_id, enum afe_cal_mode afe_cal_mode) this_afe.afe_cal_mode[port_index] = afe_cal_mode; } +void afe_set_routing_callback(routing_cb cb) +{ + this_afe.rt_cb = cb; +} + int afe_port_send_usb_dev_param(u16 port_id, union afe_port_config *afe_config) { struct afe_usb_audio_dev_param_command config; @@ -2841,6 +2905,13 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config, return ret; } + if ((index >= 0) && (index < AFE_MAX_PORTS)) { + this_afe.afe_sample_rates[index] = rate; + + if (this_afe.rt_cb) + this_afe.dev_acdb_id[index] = this_afe.rt_cb(port_id); + } + mutex_lock(&this_afe.afe_cmd_lock); /* Also send the topology id here: */ port_index = afe_get_port_index(port_id); @@ -3045,7 +3116,6 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config, port_index = afe_get_port_index(port_id); if ((port_index >= 0) && (port_index < AFE_MAX_PORTS)) { - this_afe.afe_sample_rates[port_index] = rate; /* * If afe_port_start() for tx port called before * rx port, then aanc rx sample rate is zero. So, @@ -3408,6 +3478,14 @@ int afe_open(u16 port_id, pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret); return -EINVAL; } + + if ((index >= 0) && (index < AFE_MAX_PORTS)) { + this_afe.afe_sample_rates[index] = rate; + + if (this_afe.rt_cb) + this_afe.dev_acdb_id[index] = this_afe.rt_cb(port_id); + } + /* Also send the topology id here: */ afe_send_custom_topology(); /* One time call: only for first time */ afe_send_port_topology_id(port_id); @@ -5398,6 +5476,7 @@ int afe_close(int port_id) if ((port_index >= 0) && (port_index < AFE_MAX_PORTS)) { this_afe.afe_sample_rates[port_index] = 0; this_afe.topology[port_index] = 0; + this_afe.dev_acdb_id[port_index] = 0; } else { pr_err("%s: port %d\n", __func__, port_index); ret = -EINVAL; @@ -6873,6 +6952,8 @@ static int __init afe_init(void) mutex_init(&this_afe.afe_cmd_lock); for (i = 0; i < AFE_MAX_PORTS; i++) { this_afe.afe_cal_mode[i] = AFE_CAL_MODE_DEFAULT; + this_afe.afe_sample_rates[i] = 0; + this_afe.dev_acdb_id[i] = 0; init_waitqueue_head(&this_afe.wait[i]); } wakeup_source_init(&wl.ws, "spkr-prot");