Loading asoc/msm-dai-q6-v2.c +74 −13 Original line number Diff line number Diff line Loading @@ -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__); Loading @@ -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, Loading @@ -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__); Loading @@ -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; case DEC_FMT_APTX_ADAPTIVE: memcpy(&dai_data->dec_config.data, ucontrol->value.bytes.data + format_size, sizeof(struct asm_aptx_ad_dec_cfg_t)); 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(&dai_data->dec_config.abr_dec_cfg, ucontrol->value.bytes.data + format_size, sizeof(struct afe_abr_dec_cfg_t)); ret = -EINVAL; break; } return 0; return ret; } static const struct snd_kcontrol_new afe_dec_config_controls[] = { Loading @@ -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 | Loading dsp/q6afe.c +50 −4 Original line number Diff line number Diff line Loading @@ -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; }; Loading Loading @@ -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__); Loading @@ -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); Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -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; } Loading include/dsp/apr_audio-v2.h +16 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 { Loading Loading @@ -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; Loading @@ -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 { Loading Loading
asoc/msm-dai-q6-v2.c +74 −13 Original line number Diff line number Diff line Loading @@ -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__); Loading @@ -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, Loading @@ -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__); Loading @@ -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; case DEC_FMT_APTX_ADAPTIVE: memcpy(&dai_data->dec_config.data, ucontrol->value.bytes.data + format_size, sizeof(struct asm_aptx_ad_dec_cfg_t)); 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(&dai_data->dec_config.abr_dec_cfg, ucontrol->value.bytes.data + format_size, sizeof(struct afe_abr_dec_cfg_t)); ret = -EINVAL; break; } return 0; return ret; } static const struct snd_kcontrol_new afe_dec_config_controls[] = { Loading @@ -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 | Loading
dsp/q6afe.c +50 −4 Original line number Diff line number Diff line Loading @@ -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; }; Loading Loading @@ -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__); Loading @@ -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); Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -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; } Loading
include/dsp/apr_audio-v2.h +16 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 { Loading Loading @@ -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; Loading @@ -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 { Loading