From 4a466532e4c3152f8a99159cc79df3678575c7f9 Mon Sep 17 00:00:00 2001 From: Chaithanya Krishna Bacharaju Date: Mon, 21 Jan 2019 10:59:51 +0530 Subject: [PATCH 1/2] dsp: Add support for Aptx Adaptive decoder Add support for Aptx Adaptive decoder. Introduce flag to indicate ABR feedback decoder configuration to differentiate from regular decoder configuration. Change-Id: I272e0a9572a56e878f7ad1385514b3be7010145a Signed-off-by: Chaithanya Krishna Bacharaju --- dsp/q6afe.c | 57 ++++++++++++++++++++++++++++++++++---- include/dsp/apr_audio-v2.h | 16 +++++++++++ 2 files changed, 67 insertions(+), 6 deletions(-) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 1b5c94d59a..8743b56c52 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -1,6 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. */ #include #include @@ -76,6 +75,11 @@ enum { Q6AFE_MSM_SPKR_FTM_MODE }; +enum { + APTX_AD_48 = 0, + APTX_AD_44_1 = 1 +}; + struct wlock { struct wakeup_source ws; }; @@ -3541,6 +3545,29 @@ static int q6afe_send_dec_config(u16 port_id, goto exit; } break; + case ASM_MEDIA_FMT_APTX_ADAPTIVE: + if (!cfg->abr_dec_cfg.is_abr_enabled) { + pr_debug("%s: sending aptx adaptive congestion buffer size to dsp\n", + __func__); + param_hdr.param_id = + AFE_DECODER_PARAM_ID_CONGESTION_BUFFER_SIZE; + param_hdr.param_size = + sizeof(struct avs_dec_congestion_buffer_param_t); + dec_buffer_id_param.version = 0; + dec_buffer_id_param.max_nr_buffers = 226; + dec_buffer_id_param.pre_buffer_size = 226; + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, + (u8 *) &dec_buffer_id_param); + if (ret) { + pr_err("%s: aptx adaptive congestion buffer size for port 0x%x failed %d\n", + __func__, port_id, ret); + goto exit; + } + break; + } + /* fall through for abr enabled case */ default: pr_debug("%s:sending AFE_ENCDEC_PARAM_ID_DEC_TO_ENC_COMMUNICATION to DSP payload\n", __func__); @@ -3561,7 +3588,7 @@ static int q6afe_send_dec_config(u16 port_id, break; } - pr_debug("%s:Sending AFE_API_VERSION_PORT_MEDIA_TYPE to DSP", __func__); + pr_debug("%s: Send AFE_API_VERSION_PORT_MEDIA_TYPE to DSP\n", __func__); param_hdr.module_id = AFE_MODULE_PORT; param_hdr.param_id = AFE_PARAM_ID_PORT_MEDIA_TYPE; param_hdr.param_size = sizeof(struct afe_port_media_type_t); @@ -3575,6 +3602,15 @@ static int q6afe_send_dec_config(u16 port_id, media_type.sample_rate = cfg->data.sbc_config.sample_rate; break; + case ASM_MEDIA_FMT_APTX_ADAPTIVE: + if (!cfg->abr_dec_cfg.is_abr_enabled) { + media_type.sample_rate = + (cfg->data.aptx_ad_config.sample_rate == APTX_AD_44_1) ? + AFE_PORT_SAMPLE_RATE_44_1K : + AFE_PORT_SAMPLE_RATE_48K; + break; + } + /* fall through for abr enabled case */ default: media_type.sample_rate = afe_config.slim_sch.sample_rate; @@ -3600,11 +3636,19 @@ static int q6afe_send_dec_config(u16 port_id, goto exit; } - if (format != ASM_MEDIA_FMT_SBC && format != ASM_MEDIA_FMT_AAC_V2) { + if (format != ASM_MEDIA_FMT_SBC && format != ASM_MEDIA_FMT_AAC_V2 && + format != ASM_MEDIA_FMT_APTX_ADAPTIVE) { pr_debug("%s:Unsuppported dec format. Ignore AFE config %u\n", __func__, format); goto exit; } + + if (format == ASM_MEDIA_FMT_APTX_ADAPTIVE && + cfg->abr_dec_cfg.is_abr_enabled) { + pr_debug("%s: Ignore AFE config for abr case\n", __func__); + goto exit; + } + pr_debug("%s: sending AFE_DECODER_PARAM_ID_DEC_MEDIA_FMT to DSP payload\n", __func__); param_hdr.module_id = AFE_MODULE_ID_DECODER; @@ -3623,9 +3667,10 @@ static int q6afe_send_dec_config(u16 port_id, switch (cfg->format) { case ASM_MEDIA_FMT_AAC_V2: + case ASM_MEDIA_FMT_APTX_ADAPTIVE: param_hdr.param_size = sizeof(struct afe_dec_media_fmt_t); - pr_debug("%s:send AFE_DECODER_PARAM_ID DEC_MEDIA_FMT to DSP payload\n", + pr_debug("%s:send AVS_DECODER_PARAM_ID DEC_MEDIA_FMT to DSP payload\n", __func__); param_hdr.param_id = AVS_DECODER_PARAM_ID_DEC_MEDIA_FMT; dec_media_fmt.dec_media_config = cfg->data; @@ -3634,7 +3679,7 @@ static int q6afe_send_dec_config(u16 port_id, param_hdr, (u8 *) &dec_media_fmt); if (ret) { - pr_err("%s: AFE_DECODER_PARAM_ID DEC_MEDIA_FMT for port 0x%x failed %d\n", + pr_err("%s: AVS_DECODER_PARAM_ID DEC_MEDIA_FMT for port 0x%x failed %d\n", __func__, port_id, ret); goto exit; } diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index 9daebe5a41..5327427941 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -2477,6 +2477,7 @@ struct afe_port_data_cmd_rt_proxy_port_read_v2 { #define AFE_MODULE_AUDIO_DEV_INTERFACE 0x0001020C #define AFE_PORT_SAMPLE_RATE_8K 8000 #define AFE_PORT_SAMPLE_RATE_16K 16000 +#define AFE_PORT_SAMPLE_RATE_44_1K 44100 #define AFE_PORT_SAMPLE_RATE_48K 48000 #define AFE_PORT_SAMPLE_RATE_96K 96000 #define AFE_PORT_SAMPLE_RATE_176P4K 176400 @@ -3795,6 +3796,7 @@ struct afe_imc_dec_enc_info { struct afe_abr_dec_cfg_t { struct afe_imc_dec_enc_info imc_info; + bool is_abr_enabled; } __packed; struct afe_abr_enc_cfg_t { @@ -4437,6 +4439,19 @@ struct asm_aac_dec_cfg_v2_t { */ } __packed; +/* + * Payload of the APTX AD decoder configuration parameters in the + * #ASM_MEDIA_FMT_APTX_ADAPTIVE media format. + */ +struct asm_aptx_ad_dec_cfg_t { + uint32_t sample_rate; + /* + * Number of samples per second. + * + * @values 0x0(48000Hz), 0x1(44100Hz) + */ +} __packed; + union afe_enc_config_data { struct asm_sbc_enc_cfg_t sbc_config; struct asm_aac_enc_cfg_t aac_config; @@ -4458,6 +4473,7 @@ union afe_dec_config_data { struct asm_sbc_dec_cfg_t sbc_config; struct asm_aac_dec_cfg_v2_t aac_config; struct asm_mp3_dec_cfg_t mp3_config; + struct asm_aptx_ad_dec_cfg_t aptx_ad_config; }; struct afe_dec_config { From cdde1800606f6a67b01dadad53e8fad06cc1fed1 Mon Sep 17 00:00:00 2001 From: Chaithanya Krishna Bacharaju Date: Thu, 24 Jan 2019 13:38:42 +0530 Subject: [PATCH 2/2] asoc: Add support for Aptx Adaptive decoder Add support for Aptx Adaptive decoder. Introduce new get and put for ABR feedback decoder controls since same decoder config format is required to be passed by client in regular and feedback decoder configuration. Change-Id: I96d9daef2a0967788640c2efb5478119eeae48ab Signed-off-by: Chaithanya Krishna Bacharaju --- asoc/msm-dai-q6-v2.c | 89 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 75 insertions(+), 14 deletions(-) diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index 10acd501a8..c2be85b032 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -3226,11 +3226,64 @@ static int msm_dai_q6_afe_dec_cfg_info(struct snd_kcontrol *kcontrol, return 0; } +static int msm_dai_q6_afe_feedback_dec_cfg_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; + u32 format_size = 0; + + if (!dai_data) { + pr_err("%s: Invalid dai data\n", __func__); + return -EINVAL; + } + + format_size = sizeof(dai_data->dec_config.format); + memcpy(ucontrol->value.bytes.data, + &dai_data->dec_config.format, + format_size); + + pr_debug("%s: abr_dec_cfg for %d format\n", + __func__, dai_data->dec_config.format); + memcpy(ucontrol->value.bytes.data + format_size, + &dai_data->dec_config.abr_dec_cfg, + sizeof(struct afe_imc_dec_enc_info)); + + return 0; +} + +static int msm_dai_q6_afe_feedback_dec_cfg_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; + u32 format_size = 0; + + if (!dai_data) { + pr_err("%s: Invalid dai data\n", __func__); + return -EINVAL; + } + + memset(&dai_data->dec_config, 0x0, + sizeof(struct afe_dec_config)); + format_size = sizeof(dai_data->dec_config.format); + memcpy(&dai_data->dec_config.format, + ucontrol->value.bytes.data, + format_size); + + pr_debug("%s: abr_dec_cfg for %d format\n", + __func__, dai_data->dec_config.format); + memcpy(&dai_data->dec_config.abr_dec_cfg, + ucontrol->value.bytes.data + format_size, + sizeof(struct afe_imc_dec_enc_info)); + dai_data->dec_config.abr_dec_cfg.is_abr_enabled = true; + return 0; +} + static int msm_dai_q6_afe_dec_cfg_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; u32 format_size = 0; + int ret = 0; if (!dai_data) { pr_err("%s: Invalid dai data\n", __func__); @@ -3247,20 +3300,23 @@ static int msm_dai_q6_afe_dec_cfg_get(struct snd_kcontrol *kcontrol, &dai_data->dec_config.data, sizeof(struct asm_aac_dec_cfg_v2_t)); break; + case DEC_FMT_APTX_ADAPTIVE: + memcpy(ucontrol->value.bytes.data + format_size, + &dai_data->dec_config.data, + sizeof(struct asm_aptx_ad_dec_cfg_t)); + break; case DEC_FMT_SBC: case DEC_FMT_MP3: /* No decoder specific data available */ break; default: - pr_debug("%s: Default decoder config for %d format: Expect abr_dec_cfg\n", + pr_err("%s: Invalid format %d\n", __func__, dai_data->dec_config.format); - memcpy(ucontrol->value.bytes.data + format_size, - &dai_data->dec_config.abr_dec_cfg, - sizeof(struct afe_abr_dec_cfg_t)); - + ret = -EINVAL; break; } - return 0; + + return ret; } static int msm_dai_q6_afe_dec_cfg_put(struct snd_kcontrol *kcontrol, @@ -3268,6 +3324,7 @@ static int msm_dai_q6_afe_dec_cfg_put(struct snd_kcontrol *kcontrol, { struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; u32 format_size = 0; + int ret = 0; if (!dai_data) { pr_err("%s: Invalid dai data\n", __func__); @@ -3293,15 +3350,19 @@ static int msm_dai_q6_afe_dec_cfg_put(struct snd_kcontrol *kcontrol, ucontrol->value.bytes.data + format_size, sizeof(struct asm_sbc_dec_cfg_t)); break; - default: - pr_debug("%s: Default decoder config for %d format: Expect abr_dec_cfg\n", - __func__, dai_data->dec_config.format); - memcpy(&dai_data->dec_config.abr_dec_cfg, + case DEC_FMT_APTX_ADAPTIVE: + memcpy(&dai_data->dec_config.data, ucontrol->value.bytes.data + format_size, - sizeof(struct afe_abr_dec_cfg_t)); + sizeof(struct asm_aptx_ad_dec_cfg_t)); + break; + default: + pr_err("%s: Invalid format %d\n", + __func__, dai_data->dec_config.format); + ret = -EINVAL; break; } - return 0; + + return ret; } static const struct snd_kcontrol_new afe_dec_config_controls[] = { @@ -3311,8 +3372,8 @@ static const struct snd_kcontrol_new afe_dec_config_controls[] = { .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = "SLIM_7_TX Decoder Config", .info = msm_dai_q6_afe_dec_cfg_info, - .get = msm_dai_q6_afe_dec_cfg_get, - .put = msm_dai_q6_afe_dec_cfg_put, + .get = msm_dai_q6_afe_feedback_dec_cfg_get, + .put = msm_dai_q6_afe_feedback_dec_cfg_put, }, { .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |