Merge "asoc: Add support for Aptx Adaptive decoder"
This commit is contained in:

committed by
Gerrit - the friendly Code Review server

commit
16470427d0
@@ -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 |
|
||||
|
54
dsp/q6afe.c
54
dsp/q6afe.c
@@ -75,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;
|
||||
};
|
||||
@@ -3564,6 +3569,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__);
|
||||
@@ -3584,7 +3612,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);
|
||||
@@ -3598,6 +3626,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;
|
||||
@@ -3623,11 +3660,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;
|
||||
@@ -3646,9 +3691,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;
|
||||
@@ -3657,7 +3703,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;
|
||||
}
|
||||
|
@@ -2480,6 +2480,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
|
||||
@@ -3798,6 +3799,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 {
|
||||
@@ -4440,6 +4442,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;
|
||||
@@ -4461,6 +4476,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 {
|
||||
|
Reference in New Issue
Block a user