Merge "asoc: lahaina: add support to send power mode for voice usecase"

This commit is contained in:
qctecmdr 2020-06-05 01:54:02 -07:00 committed by Gerrit - the friendly Code Review server
commit 344b47efbe
5 changed files with 382 additions and 0 deletions

View File

@ -2723,6 +2723,63 @@ static int msm_get_port_id(int be_id)
case MSM_BACKEND_DAI_VA_CDC_DMA_TX_2:
afe_port_id = AFE_PORT_ID_VA_CODEC_DMA_TX_2;
break;
case MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0:
afe_port_id = AFE_PORT_ID_WSA_CODEC_DMA_RX_0;
break;
case MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0:
afe_port_id = AFE_PORT_ID_WSA_CODEC_DMA_TX_0;
break;
case MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1:
afe_port_id = AFE_PORT_ID_WSA_CODEC_DMA_RX_1;
break;
case MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1:
afe_port_id = AFE_PORT_ID_WSA_CODEC_DMA_TX_1;
break;
case MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2:
afe_port_id = AFE_PORT_ID_WSA_CODEC_DMA_TX_2;
break;
case MSM_BACKEND_DAI_RX_CDC_DMA_RX_0:
afe_port_id = AFE_PORT_ID_RX_CODEC_DMA_RX_0;
break;
case MSM_BACKEND_DAI_TX_CDC_DMA_TX_0:
afe_port_id = AFE_PORT_ID_TX_CODEC_DMA_TX_0;
break;
case MSM_BACKEND_DAI_RX_CDC_DMA_RX_1:
afe_port_id = AFE_PORT_ID_RX_CODEC_DMA_RX_1;
break;
case MSM_BACKEND_DAI_TX_CDC_DMA_TX_1:
afe_port_id = AFE_PORT_ID_TX_CODEC_DMA_TX_1;
break;
case MSM_BACKEND_DAI_RX_CDC_DMA_RX_2:
afe_port_id = AFE_PORT_ID_RX_CODEC_DMA_RX_2;
break;
case MSM_BACKEND_DAI_TX_CDC_DMA_TX_2:
afe_port_id = AFE_PORT_ID_TX_CODEC_DMA_TX_2;
break;
case MSM_BACKEND_DAI_RX_CDC_DMA_RX_3:
afe_port_id = AFE_PORT_ID_RX_CODEC_DMA_RX_3;
break;
case MSM_BACKEND_DAI_TX_CDC_DMA_TX_3:
afe_port_id = AFE_PORT_ID_TX_CODEC_DMA_TX_3;
break;
case MSM_BACKEND_DAI_RX_CDC_DMA_RX_4:
afe_port_id = AFE_PORT_ID_RX_CODEC_DMA_RX_4;
break;
case MSM_BACKEND_DAI_TX_CDC_DMA_TX_4:
afe_port_id = AFE_PORT_ID_TX_CODEC_DMA_TX_4;
break;
case MSM_BACKEND_DAI_RX_CDC_DMA_RX_5:
afe_port_id = AFE_PORT_ID_RX_CODEC_DMA_RX_5;
break;
case MSM_BACKEND_DAI_TX_CDC_DMA_TX_5:
afe_port_id = AFE_PORT_ID_TX_CODEC_DMA_TX_5;
break;
case MSM_BACKEND_DAI_RX_CDC_DMA_RX_6:
afe_port_id = AFE_PORT_ID_RX_CODEC_DMA_RX_6;
break;
case MSM_BACKEND_DAI_RX_CDC_DMA_RX_7:
afe_port_id = AFE_PORT_ID_RX_CODEC_DMA_RX_7;
break;
default:
pr_err("%s: Invalid BE id: %d\n", __func__, be_id);
afe_port_id = -EINVAL;
@ -4124,6 +4181,38 @@ static int lahaina_send_island_va_config(int32_t be_id)
return rc;
}
static int lahaina_send_power_mode(int32_t be_id)
{
int rc = 0;
int port_id = 0xFFFF;
port_id = msm_get_port_id(be_id);
if (port_id < 0) {
pr_err("%s: Invalid power interface, be_id: %d\n",
__func__, be_id);
rc = -EINVAL;
} else {
/*
* send island mode config
* This should be the first configuration
*
*/
rc = afe_send_port_island_mode(port_id);
if (rc)
pr_err("%s: afe send island mode failed %d\n",
__func__, rc);
/*
* send power mode config
* This should be set after island configuration
*/
rc = afe_send_port_power_mode(port_id);
if (rc)
pr_err("%s: afe send power mode failed %d\n",
__func__, rc);
}
return rc;
}
static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
struct snd_pcm_hw_params *params)
{
@ -4887,6 +4976,12 @@ static int msm_snd_cdc_dma_startup(struct snd_pcm_substream *substream)
pr_err("%s: send island va cfg failed, err: %d\n",
__func__, ret);
break;
default:
ret = lahaina_send_power_mode(dai_link->id);
if (ret)
pr_err("%s: send power mode failed, err: %d\n",
__func__, ret);
break;
}
return ret;

View File

@ -1280,6 +1280,83 @@ static int msm_dai_q6_dai_auxpcm_remove(struct snd_soc_dai *dai)
return 0;
}
static int msm_dai_q6_power_mode_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
int value = ucontrol->value.integer.value[0];
u16 port_id = (u16)kcontrol->private_value;
pr_debug("%s: power mode = %d\n", __func__, value);
trace_printk("%s: power mode = %d\n", __func__, value);
afe_set_power_mode_cfg(port_id, value);
return 0;
}
static int msm_dai_q6_power_mode_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
int value;
u16 port_id = (u16)kcontrol->private_value;
afe_get_power_mode_cfg(port_id, &value);
ucontrol->value.integer.value[0] = value;
return 0;
}
static void power_mode_mx_ctl_private_free(struct snd_kcontrol *kcontrol)
{
struct snd_kcontrol_new *knew = snd_kcontrol_chip(kcontrol);
kfree(knew);
}
static int msm_dai_q6_add_power_mode_mx_ctls(struct snd_card *card,
const char *dai_name,
int dai_id, void *dai_data)
{
const char *mx_ctl_name = "Power Mode";
char *mixer_str = NULL;
int dai_str_len = 0, ctl_len = 0;
int rc = 0;
struct snd_kcontrol_new *knew = NULL;
struct snd_kcontrol *kctl = NULL;
dai_str_len = strlen(dai_name) + 1;
ctl_len = dai_str_len + strlen(mx_ctl_name) + 1;
mixer_str = kzalloc(ctl_len, GFP_KERNEL);
if (!mixer_str)
return -ENOMEM;
snprintf(mixer_str, ctl_len, "%s %s", dai_name, mx_ctl_name);
knew = kzalloc(sizeof(struct snd_kcontrol_new), GFP_KERNEL);
if (!knew) {
kfree(mixer_str);
return -ENOMEM;
}
knew->iface = SNDRV_CTL_ELEM_IFACE_MIXER;
knew->info = snd_ctl_boolean_mono_info;
knew->get = msm_dai_q6_power_mode_get;
knew->put = msm_dai_q6_power_mode_put;
knew->name = mixer_str;
knew->private_value = dai_id;
kctl = snd_ctl_new1(knew, knew);
if (!kctl) {
kfree(knew);
kfree(mixer_str);
return -ENOMEM;
}
kctl->private_free = power_mode_mx_ctl_private_free;
rc = snd_ctl_add(card, kctl);
if (rc < 0)
pr_err("%s: err add config ctl, DAI = %s\n",
__func__, dai_name);
kfree(mixer_str);
return rc;
}
static int msm_dai_q6_island_mode_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
@ -1359,6 +1436,54 @@ static int msm_dai_q6_add_island_mx_ctls(struct snd_card *card,
return rc;
}
static int msm_dai_q6_add_isconfig_config_mx_ctls(struct snd_card *card,
const char *dai_name,
int dai_id, void *dai_data)
{
const char *mx_ctl_name = "Island Config";
char *mixer_str = NULL;
int dai_str_len = 0, ctl_len = 0;
int rc = 0;
struct snd_kcontrol_new *knew = NULL;
struct snd_kcontrol *kctl = NULL;
dai_str_len = strlen(dai_name) + 1;
ctl_len = dai_str_len + strlen(mx_ctl_name) + 1;
mixer_str = kzalloc(ctl_len, GFP_KERNEL);
if (!mixer_str)
return -ENOMEM;
snprintf(mixer_str, ctl_len, "%s %s", dai_name, mx_ctl_name);
knew = kzalloc(sizeof(struct snd_kcontrol_new), GFP_KERNEL);
if (!knew) {
kfree(mixer_str);
return -ENOMEM;
}
knew->iface = SNDRV_CTL_ELEM_IFACE_MIXER;
knew->info = snd_ctl_boolean_mono_info;
knew->get = msm_dai_q6_island_mode_get;
knew->put = msm_dai_q6_island_mode_put;
knew->name = mixer_str;
knew->private_value = dai_id;
kctl = snd_ctl_new1(knew, knew);
if (!kctl) {
kfree(knew);
kfree(mixer_str);
return -ENOMEM;
}
kctl->private_free = island_mx_ctl_private_free;
rc = snd_ctl_add(card, kctl);
if (rc < 0)
pr_err("%s: err add config ctl, DAI = %s\n",
__func__, dai_name);
kfree(mixer_str);
return rc;
}
/*
* For single CPU DAI registration, the dai id needs to be
* set explicitly in the dai probe as ASoC does not read
@ -12322,6 +12447,14 @@ static int msm_dai_q6_dai_cdc_dma_probe(struct snd_soc_dai *dai)
dai->component->card->snd_card,
dai->name, dai->id,
(void *)dai_data);
rc = msm_dai_q6_add_power_mode_mx_ctls(
dai->component->card->snd_card,
dai->name, dai->id,
(void *)dai_data);
rc= msm_dai_q6_add_isconfig_config_mx_ctls(
dai->component->card->snd_card,
dai->name, dai->id,
(void *)dai_data);
rc = msm_dai_q6_dai_add_route(dai);
return rc;
@ -12765,6 +12898,7 @@ static struct snd_soc_dai_driver msm_dai_q6_cdc_dma_dai[] = {
.rate_min = 8000,
.rate_max = 384000,
},
.name = "RX_CDC_DMA_RX_0",
.ops = &msm_dai_q6_cdc_dma_ops,
.id = AFE_PORT_ID_RX_CODEC_DMA_RX_0,
.probe = msm_dai_q6_dai_cdc_dma_probe,
@ -12815,6 +12949,7 @@ static struct snd_soc_dai_driver msm_dai_q6_cdc_dma_dai[] = {
.rate_min = 8000,
.rate_max = 384000,
},
.name = "RX_CDC_DMA_RX_1",
.ops = &msm_dai_q6_cdc_dma_ops,
.id = AFE_PORT_ID_RX_CODEC_DMA_RX_1,
.probe = msm_dai_q6_dai_cdc_dma_probe,
@ -12939,6 +13074,7 @@ static struct snd_soc_dai_driver msm_dai_q6_cdc_dma_dai[] = {
.rate_min = 8000,
.rate_max = 384000,
},
.name = "TX_CDC_DMA_TX_3",
.ops = &msm_dai_q6_cdc_dma_ops,
.id = AFE_PORT_ID_TX_CODEC_DMA_TX_3,
.probe = msm_dai_q6_dai_cdc_dma_probe,
@ -12989,6 +13125,7 @@ static struct snd_soc_dai_driver msm_dai_q6_cdc_dma_dai[] = {
.rate_min = 8000,
.rate_max = 384000,
},
.name = "TX_CDC_DMA_TX_4",
.ops = &msm_dai_q6_cdc_dma_ops,
.id = AFE_PORT_ID_TX_CODEC_DMA_TX_4,
.probe = msm_dai_q6_dai_cdc_dma_probe,

View File

@ -176,6 +176,7 @@ struct afe_ctl {
/* cal info for AFE */
struct afe_fw_info *fw_data;
u32 island_mode[AFE_MAX_PORTS];
u32 power_mode[AFE_MAX_PORTS];
struct vad_config vad_cfg[AFE_MAX_PORTS];
struct work_struct afe_dc_work;
struct notifier_block event_notifier;
@ -2872,6 +2873,81 @@ done:
}
static int afe_get_power_mode(u16 port_id, u32 *power_mode)
{
int ret = 0;
int index = 0;
*power_mode = 0;
index = q6audio_get_port_index(port_id);
if (index < 0 || index >= AFE_MAX_PORTS) {
pr_err("%s: AFE port index[%d] invalid!\n",
__func__, index);
return -EINVAL;
}
*power_mode = this_afe.power_mode[index];
return ret;
}
/**
* afe_send_port_power_mode -
* for sending power mode to AFE
*
* @port_id: AFE port id number
* Returns 0 on success or error on failure.
*/
int afe_send_port_power_mode(u16 port_id)
{
struct afe_param_id_power_mode_cfg_t power_mode_cfg;
struct param_hdr_v3 param_info;
u32 power_mode = 0;
int ret = 0;
if (!(q6core_get_avcs_api_version_per_service(
APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V4)) {
pr_debug("%s: AFE port[%d] API version is invalid!\n",
__func__, port_id);
return 0;
}
memset(&power_mode_cfg, 0, sizeof(power_mode_cfg));
memset(&param_info, 0, sizeof(param_info));
ret = afe_get_power_mode(port_id, &power_mode);
if (ret) {
pr_err("%s: AFE port[%d] get power mode is invalid!\n",
__func__, port_id);
return ret;
}
if (power_mode == 0) {
pr_debug("%s: AFE port[%d] power mode is not enabled\n",
__func__, port_id);
return ret;
}
param_info.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
param_info.instance_id = INSTANCE_ID_0;
param_info.param_id = AFE_PARAM_ID_POWER_MODE_CONFIG;
param_info.param_size = sizeof(power_mode_cfg);
power_mode_cfg.power_mode_cfg_minor_version =
AFE_API_VERSION_POWER_MODE_CONFIG;
power_mode_cfg.power_mode_enable = power_mode;
ret = q6afe_pack_and_set_param_in_band(port_id,
q6audio_get_port_index(port_id),
param_info, (u8 *) &power_mode_cfg);
if (ret) {
pr_err("%s: AFE set power mode enable for port 0x%x failed %d\n",
__func__, port_id, ret);
return ret;
}
pr_debug("%s: AFE set power mode 0x%x enable for port 0x%x ret %d\n",
__func__, power_mode, port_id, ret);
trace_printk("%s: AFE set power mode 0x%x enable for port 0x%x ret %d\n",
__func__, power_mode, port_id, ret);
return ret;
}
EXPORT_SYMBOL(afe_send_port_power_mode);
static int afe_get_island_mode(u16 port_id, u32 *island_mode)
{
@ -2921,6 +2997,11 @@ int afe_send_port_island_mode(u16 port_id)
__func__, port_id);
return ret;
}
if (island_mode == 0) {
pr_debug("%s: AFE port[%d] island mode is not enabled\n",
__func__, port_id);
return ret;
}
param_info.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
param_info.instance_id = INSTANCE_ID_0;
param_info.param_id = AFE_PARAM_ID_ISLAND_CONFIG;
@ -4268,6 +4349,55 @@ void afe_set_island_mode_cfg(u16 port_id, u32 enable_flag)
}
EXPORT_SYMBOL(afe_set_island_mode_cfg);
/**
* afe_get_power_mode_cfg -
* get power mode configuration
* @port_id: AFE port id number
* @enable_flag: Enable or Disable
*/
int afe_get_power_mode_cfg(u16 port_id, u32 *enable_flag)
{
uint16_t port_index;
int ret = 0;
if (enable_flag) {
port_index = afe_get_port_index(port_id);
if (port_index < 0 || port_index >= AFE_MAX_PORTS) {
pr_err("%s: AFE port index[%d] invalid!\n",
__func__, port_index);
return -EINVAL;
}
*enable_flag = this_afe.power_mode[port_index];
}
return ret;
}
EXPORT_SYMBOL(afe_get_power_mode_cfg);
/**
* afe_set_power_mode_cfg -
* set power mode configuration
* @port_id: AFE port id number
* @enable_flag: Enable or Disable
*/
int afe_set_power_mode_cfg(u16 port_id, u32 enable_flag)
{
uint16_t port_index;
int ret= 0;
port_index = afe_get_port_index(port_id);
if (port_index < 0 || port_index >= AFE_MAX_PORTS) {
pr_err("%s: AFE port index[%d] invalid!\n",
__func__, port_index);
return -EINVAL;
}
this_afe.power_mode[port_index] = enable_flag;
trace_printk("%s: set power mode cfg 0x%x for port 0x%x\n",
__func__, this_afe.power_mode[port_index], port_id);
return ret;
}
EXPORT_SYMBOL(afe_set_power_mode_cfg);
/**
* afe_set_routing_callback -
* Update callback function for routing
@ -10479,6 +10609,7 @@ int __init afe_init(void)
this_afe.afe_sample_rates[i] = 0;
this_afe.dev_acdb_id[i] = 0;
this_afe.island_mode[i] = 0;
this_afe.power_mode[i] = 0;
this_afe.vad_cfg[i].is_enable = 0;
this_afe.vad_cfg[i].pre_roll = 0;
init_waitqueue_head(&this_afe.wait[i]);

View File

@ -4929,6 +4929,9 @@ struct avs_dec_congestion_buffer_param_t {
/* Payload of the AFE_PARAM_ID_ISLAND_CONFIG parameter used by
* AFE_MODULE_AUDIO_DEV_INTERFACE.
*/
#define AFE_PARAM_ID_POWER_MODE_CONFIG 0x0002002c
#define AFE_API_VERSION_POWER_MODE_CONFIG 0x1
struct afe_param_id_island_cfg_t {
uint32_t island_cfg_minor_version;
/* Tracks the configuration of this parameter.
@ -4942,6 +4945,19 @@ struct afe_param_id_island_cfg_t {
*/
} __packed;
struct afe_param_id_power_mode_cfg_t {
uint32_t power_mode_cfg_minor_version;
/* Tracks the configuration of this parameter
* Supported values: #AFE_API_VERSION_POWER_MODE_CONFIG
*/
uint32_t power_mode_enable;
/* Specifies whether island mode should be enabled or disabled for the
* use-case being setup.
* Supported values: 0 - Disable, 1 - Enable
*/
} __packed;
/* ID of the parameter used by #AFE_MODULE_AUDIO_DEV_INTERFACE to configure
* the Codec DMA interface.
*/

View File

@ -398,6 +398,8 @@ void afe_set_vad_cfg(u32 vad_enable, u32 preroll_config,
void afe_set_island_mode_cfg(u16 port_id, u32 enable_flag);
void afe_get_island_mode_cfg(u16 port_id, u32 *enable_flag);
int afe_send_cdc_dma_data_align(u16 port_id, u32 cdc_dma_data_align);
int afe_set_power_mode_cfg(u16 port_id, u32 enable_flag);
int afe_get_power_mode_cfg(u16 port_id, u32 *enable_flag);
int afe_port_start(u16 port_id, union afe_port_config *afe_config,
u32 rate);
int afe_set_tws_channel_mode(u32 foramt, u16 port_id, u32 channel_mode);
@ -489,6 +491,7 @@ int afe_get_sp_rx_tmax_xmax_logging_data(
u16 port_id);
int afe_cal_init_hwdep(void *card);
int afe_send_port_island_mode(u16 port_id);
int afe_send_port_power_mode(u16 port_id);
int afe_send_port_vad_cfg_params(u16 port_id);
int afe_send_cmd_wakeup_register(void *handle, bool enable);
void afe_register_wakeup_irq_callback(