Loading asoc/msm-dai-q6-v2.c +113 −8 Original line number Diff line number Diff line Loading @@ -46,6 +46,7 @@ enum { ENC_FMT_NONE, DEC_FMT_NONE = ENC_FMT_NONE, ENC_FMT_SBC = ASM_MEDIA_FMT_SBC, ENC_FMT_AAC_V2 = ASM_MEDIA_FMT_AAC_V2, ENC_FMT_APTX = ASM_MEDIA_FMT_APTX, Loading Loading @@ -200,6 +201,7 @@ struct msm_dai_q6_dai_data { u32 afe_in_channels; u16 afe_in_bitformat; struct afe_enc_config enc_config; struct afe_dec_config dec_config; union afe_port_config port_config; u16 vi_feed_mono; }; Loading Loading @@ -1538,22 +1540,46 @@ static int msm_dai_q6_prepare(struct snd_pcm_substream *substream, if (dai_data->enc_config.format != ENC_FMT_NONE) { int bitwidth = 0; if (dai_data->afe_in_bitformat == SNDRV_PCM_FORMAT_S24_LE) switch (dai_data->afe_in_bitformat) { case SNDRV_PCM_FORMAT_S32_LE: bitwidth = 32; break; case SNDRV_PCM_FORMAT_S24_LE: bitwidth = 24; else if (dai_data->afe_in_bitformat == SNDRV_PCM_FORMAT_S16_LE) break; case SNDRV_PCM_FORMAT_S16_LE: default: bitwidth = 16; break; } pr_debug("%s: calling AFE_PORT_START_V2 with enc_format: %d\n", __func__, dai_data->enc_config.format); rc = afe_port_start_v2(dai->id, &dai_data->port_config, dai_data->rate, dai_data->afe_in_channels, bitwidth, &dai_data->enc_config); &dai_data->enc_config, NULL); if (rc < 0) pr_err("%s: afe_port_start_v2 failed error: %d\n", __func__, rc); } else if (dai_data->dec_config.format != DEC_FMT_NONE) { /* * A dummy Tx session is established in LPASS to * get the link statistics from BTSoC. * Depacketizer extracts the bit rate levels and * transmits them to the encoder on the Rx path. * Since this is a dummy decoder - channels, bit * width are sent as 0 and encoder config is NULL. * This could be updated in the future if there is * a complete Tx path set up that uses this decoder. */ rc = afe_port_start_v2(dai->id, &dai_data->port_config, dai_data->rate, 0, 0, NULL, &dai_data->dec_config); if (rc < 0) { pr_err("%s: fail to open AFE port 0x%x\n", __func__, dai->id); } } else { rc = afe_port_start(dai->id, &dai_data->port_config, dai_data->rate); Loading Loading @@ -2345,10 +2371,11 @@ static const struct soc_enum afe_input_chs_enum[] = { SOC_ENUM_SINGLE_EXT(3, afe_input_chs_text), }; static const char *const afe_input_bit_format_text[] = {"S16_LE", "S24_LE"}; static const char *const afe_input_bit_format_text[] = {"S16_LE", "S24_LE", "S32_LE"}; static const struct soc_enum afe_input_bit_format_enum[] = { SOC_ENUM_SINGLE_EXT(2, afe_input_bit_format_text), SOC_ENUM_SINGLE_EXT(3, afe_input_bit_format_text), }; static int msm_dai_q6_afe_input_channel_get(struct snd_kcontrol *kcontrol, Loading Loading @@ -2391,6 +2418,9 @@ static int msm_dai_q6_afe_input_bit_format_get( } switch (dai_data->afe_in_bitformat) { case SNDRV_PCM_FORMAT_S32_LE: ucontrol->value.integer.value[0] = 2; break; case SNDRV_PCM_FORMAT_S24_LE: ucontrol->value.integer.value[0] = 1; break; Loading @@ -2416,6 +2446,9 @@ static int msm_dai_q6_afe_input_bit_format_put( return -EINVAL; } switch (ucontrol->value.integer.value[0]) { case 2: dai_data->afe_in_bitformat = SNDRV_PCM_FORMAT_S32_LE; break; case 1: dai_data->afe_in_bitformat = SNDRV_PCM_FORMAT_S24_LE; break; Loading Loading @@ -2483,6 +2516,73 @@ static const struct snd_kcontrol_new afe_enc_config_controls[] = { msm_dai_q6_afe_scrambler_mode_put), }; static int msm_dai_q6_afe_dec_cfg_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; uinfo->count = sizeof(struct afe_dec_config); 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; int 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); memcpy(ucontrol->value.bytes.data + format_size, &dai_data->dec_config.abr_dec_cfg, sizeof(struct afe_abr_dec_cfg_t)); return 0; } static int msm_dai_q6_afe_dec_cfg_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; int 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); memcpy(&dai_data->dec_config.abr_dec_cfg, ucontrol->value.bytes.data + format_size, sizeof(struct afe_abr_dec_cfg_t)); return 0; } static const struct snd_kcontrol_new afe_dec_config_controls[] = { { .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE), .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, }, }; static int msm_dai_q6_slim_rx_drift_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { Loading Loading @@ -2650,6 +2750,11 @@ static int msm_dai_q6_dai_probe(struct snd_soc_dai *dai) snd_ctl_new1(&avd_drift_config_controls[2], dai)); break; case SLIMBUS_7_TX: rc = snd_ctl_add(dai->component->card->snd_card, snd_ctl_new1(&afe_dec_config_controls[0], dai_data)); break; case RT_PROXY_DAI_001_RX: rc = snd_ctl_add(dai->component->card->snd_card, snd_ctl_new1(&rt_proxy_config_controls[0], Loading asoc/msm-pcm-routing-v2.c +38 −0 Original line number Diff line number Diff line Loading @@ -62,6 +62,7 @@ static struct cal_type_data *cal_data[MAX_ROUTING_CAL_TYPES]; static int fm_switch_enable; static int hfp_switch_enable; static int a2dp_switch_enable; static int int0_mi2s_switch_enable; static int int4_mi2s_switch_enable; static int pri_mi2s_switch_enable; Loading Loading @@ -2160,6 +2161,34 @@ static int msm_routing_put_hfp_switch_mixer(struct snd_kcontrol *kcontrol, return 1; } static int msm_routing_a2dp_switch_mixer_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { ucontrol->value.integer.value[0] = a2dp_switch_enable; pr_debug("%s: A2DP Switch enable %ld\n", __func__, ucontrol->value.integer.value[0]); return 0; } static int msm_routing_a2dp_switch_mixer_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kcontrol); struct snd_soc_dapm_update *update = NULL; pr_debug("%s: A2DP Switch enable %ld\n", __func__, ucontrol->value.integer.value[0]); a2dp_switch_enable = ucontrol->value.integer.value[0]; if (a2dp_switch_enable) snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, 1, update); else snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, 0, update); return 1; } static int msm_routing_get_int0_mi2s_switch_mixer(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { Loading Loading @@ -13659,6 +13688,11 @@ static const struct snd_kcontrol_new usb_switch_mixer_controls = 0, 1, 0, msm_routing_get_usb_switch_mixer, msm_routing_put_usb_switch_mixer); static const struct snd_kcontrol_new a2dp_slim7_switch_mixer_controls = SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, 0, 1, 0, msm_routing_a2dp_switch_mixer_get, msm_routing_a2dp_switch_mixer_put); static const struct soc_enum lsm_port_enum = SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(lsm_port_text), lsm_port_text); Loading Loading @@ -15469,6 +15503,8 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { &hfp_slim7_switch_mixer_controls), SND_SOC_DAPM_SWITCH("USB_DL_HL", SND_SOC_NOPM, 0, 0, &usb_switch_mixer_controls), SND_SOC_DAPM_SWITCH("A2DP_SLIM7_UL_HL", SND_SOC_NOPM, 0, 0, &a2dp_slim7_switch_mixer_controls), /* Mixer definitions */ SND_SOC_DAPM_MIXER("PRI_RX Audio Mixer", SND_SOC_NOPM, 0, 0, Loading Loading @@ -17826,6 +17862,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"HFP_SLIM7_UL_HL", "Switch", "SLIMBUS_7_TX"}, {"AUX_PCM_RX", NULL, "AUXPCM_DL_HL"}, {"AUX_PCM_RX", NULL, "INTHFP_DL_HL"}, {"SLIM7_UL_HL", NULL, "A2DP_SLIM7_UL_HL"}, {"A2DP_SLIM7_UL_HL", "Switch", "SLIMBUS_7_TX"}, {"SEC_AUX_PCM_RX", NULL, "SEC_AUXPCM_DL_HL"}, {"AUXPCM_UL_HL", NULL, "AUX_PCM_TX"}, {"SEC_AUXPCM_UL_HL", NULL, "SEC_AUX_PCM_TX"}, dsp/q6afe.c +181 −25 Original line number Diff line number Diff line Loading @@ -2905,6 +2905,79 @@ int afe_port_send_usb_dev_param(u16 port_id, union afe_port_config *afe_config) return ret; } static int q6afe_send_dec_config(u16 port_id, union afe_port_config afe_config, struct afe_dec_config *cfg) { struct avs_dec_depacketizer_id_param_t dec_depkt_id_param; struct afe_enc_dec_imc_info_param_t imc_info_param; struct afe_port_media_type_t media_type; struct param_hdr_v3 param_hdr; int ret; memset(&dec_depkt_id_param, 0, sizeof(dec_depkt_id_param)); memset(&imc_info_param, 0, sizeof(imc_info_param)); memset(&media_type, 0, sizeof(media_type)); memset(¶m_hdr, 0, sizeof(param_hdr)); param_hdr.module_id = AFE_MODULE_ID_DECODER; param_hdr.instance_id = INSTANCE_ID_0; pr_debug("%s: sending AFE_DECODER_PARAM_ID_DEPACKETIZER to DSP payload\n", __func__); param_hdr.param_id = AFE_DECODER_PARAM_ID_DEPACKETIZER_ID; param_hdr.param_size = sizeof(struct avs_dec_depacketizer_id_param_t); dec_depkt_id_param.dec_depacketizer_id = AFE_MODULE_ID_DEPACKETIZER_COP; ret = q6afe_pack_and_set_param_in_band(port_id, q6audio_get_port_index(port_id), param_hdr, (u8 *) &dec_depkt_id_param); if (ret) { pr_err("%s: AFE_DECODER_PARAM_ID_DEPACKETIZER for port 0x%x failed %d\n", __func__, port_id, ret); goto exit; } pr_debug("%s:sending AFE_ENCDEC_PARAM_ID_DEC_TO_ENC_COMMUNICATION to DSP payload\n", __func__); param_hdr.param_id = AFE_ENCDEC_PARAM_ID_DEC_TO_ENC_COMMUNICATION; param_hdr.param_size = sizeof(struct afe_enc_dec_imc_info_param_t); imc_info_param.imc_info = cfg->abr_dec_cfg.imc_info; ret = q6afe_pack_and_set_param_in_band(port_id, q6audio_get_port_index(port_id), param_hdr, (u8 *) &imc_info_param); if (ret) { pr_err("%s: AFE_ENCDEC_PARAM_ID_DEC_TO_ENC_COMMUNICATION for port 0x%x failed %d\n", __func__, port_id, ret); goto exit; } pr_debug("%s:Sending AFE_API_VERSION_PORT_MEDIA_TYPE to DSP", __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); media_type.minor_version = AFE_API_VERSION_PORT_MEDIA_TYPE; media_type.sample_rate = afe_config.slim_sch.sample_rate; media_type.bit_width = afe_config.slim_sch.bit_width; media_type.num_channels = afe_config.slim_sch.num_channels; media_type.data_format = AFE_PORT_DATA_FORMAT_PCM; media_type.reserved = 0; ret = q6afe_pack_and_set_param_in_band(port_id, q6audio_get_port_index(port_id), param_hdr, (u8 *) &media_type); if (ret) { pr_err("%s: AFE_API_VERSION_PORT_MEDIA_TYPE for port 0x%x failed %d\n", __func__, port_id, ret); goto exit; } exit: return ret; } static int q6afe_send_enc_config(u16 port_id, union afe_enc_config_data *cfg, u32 format, union afe_port_config afe_config, Loading @@ -2916,6 +2989,8 @@ static int q6afe_send_enc_config(u16 port_id, struct afe_param_id_aptx_sync_mode sync_mode_param; struct avs_enc_packetizer_id_param_t enc_pkt_id_param; struct avs_enc_set_scrambler_param_t enc_set_scrambler_param; struct afe_enc_level_to_bitrate_map_param_t map_param; struct afe_enc_dec_imc_info_param_t imc_info_param; struct afe_port_media_type_t media_type; struct param_hdr_v3 param_hdr; int ret; Loading @@ -2926,6 +3001,8 @@ static int q6afe_send_enc_config(u16 port_id, memset(&sync_mode_param, 0, sizeof(sync_mode_param)); memset(&enc_pkt_id_param, 0, sizeof(enc_pkt_id_param)); memset(&enc_set_scrambler_param, 0, sizeof(enc_set_scrambler_param)); memset(&map_param, 0, sizeof(map_param)); memset(&imc_info_param, 0, sizeof(imc_info_param)); memset(&media_type, 0, sizeof(media_type)); memset(¶m_hdr, 0, sizeof(param_hdr)); Loading Loading @@ -2953,11 +3030,20 @@ static int q6afe_send_enc_config(u16 port_id, goto exit; } if (format == ASM_MEDIA_FMT_LDAC) { param_hdr.param_size = sizeof(struct afe_enc_cfg_blk_param_t) - sizeof(struct afe_abr_enc_cfg_t); enc_blk_param.enc_cfg_blk_size = sizeof(union afe_enc_config_data) - sizeof(struct afe_abr_enc_cfg_t); } else { param_hdr.param_size = sizeof(struct afe_enc_cfg_blk_param_t); enc_blk_param.enc_cfg_blk_size = sizeof(union afe_enc_config_data); } pr_debug("%s:send AFE_ENCODER_PARAM_ID_ENC_CFG_BLK to DSP payloadn", __func__); param_hdr.param_id = AFE_ENCODER_PARAM_ID_ENC_CFG_BLK; param_hdr.param_size = sizeof(struct afe_enc_cfg_blk_param_t); enc_blk_param.enc_cfg_blk_size = sizeof(union afe_enc_config_data); enc_blk_param.enc_blk_config = *cfg; ret = q6afe_pack_and_set_param_in_band(port_id, q6audio_get_port_index(port_id), Loading Loading @@ -3019,12 +3105,55 @@ static int q6afe_send_enc_config(u16 port_id, goto exit; } if (format == ASM_MEDIA_FMT_LDAC) { pr_debug("%s:sending AFE_ENCODER_PARAM_ID_BIT_RATE_LEVEL_MAP to DSP payload", __func__); param_hdr.param_id = AFE_ENCODER_PARAM_ID_BIT_RATE_LEVEL_MAP; param_hdr.param_size = sizeof(struct afe_enc_level_to_bitrate_map_param_t); map_param.mapping_table = cfg->ldac_config.abr_config.mapping_info; ret = q6afe_pack_and_set_param_in_band(port_id, q6audio_get_port_index(port_id), param_hdr, (u8 *) &map_param); if (ret) { pr_err("%s: AFE_ENCODER_PARAM_ID_BIT_RATE_LEVEL_MAP for port 0x%x failed %d\n", __func__, port_id, ret); goto exit; } pr_debug("%s: sending AFE_ENCDEC_PARAM_ID_DEC_TO_ENC_COMMUNICATION to DSP payload", __func__); param_hdr.param_id = AFE_ENCDEC_PARAM_ID_DEC_TO_ENC_COMMUNICATION; param_hdr.param_size = sizeof(struct afe_enc_dec_imc_info_param_t); imc_info_param.imc_info = cfg->ldac_config.abr_config.imc_info; ret = q6afe_pack_and_set_param_in_band(port_id, q6audio_get_port_index(port_id), param_hdr, (u8 *) &imc_info_param); if (ret) { pr_err("%s: AFE_ENCDEC_PARAM_ID_DEC_TO_ENC_COMMUNICATION for port 0x%x failed %d\n", __func__, port_id, ret); goto exit; } } pr_debug("%s:Sending AFE_API_VERSION_PORT_MEDIA_TYPE to DSP", __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); media_type.minor_version = AFE_API_VERSION_PORT_MEDIA_TYPE; media_type.sample_rate = afe_config.slim_sch.sample_rate; if (format == ASM_MEDIA_FMT_LDAC) media_type.sample_rate = cfg->ldac_config.custom_config.sample_rate; else media_type.sample_rate = afe_config.slim_sch.sample_rate; if (afe_in_bit_width) media_type.bit_width = afe_in_bit_width; else Loading Loading @@ -3052,8 +3181,9 @@ static int q6afe_send_enc_config(u16 port_id, static int __afe_port_start(u16 port_id, union afe_port_config *afe_config, u32 rate, u16 afe_in_channels, u16 afe_in_bit_width, union afe_enc_config_data *cfg, u32 enc_format, u32 scrambler_mode) union afe_enc_config_data *enc_cfg, u32 codec_format, u32 scrambler_mode, struct afe_dec_config *dec_cfg) { union afe_port_config port_cfg; struct param_hdr_v3 param_hdr; Loading Loading @@ -3290,7 +3420,8 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config, param_hdr.param_size = sizeof(union afe_port_config); port_cfg = *afe_config; if ((enc_format != ASM_MEDIA_FMT_NONE) && if (((enc_cfg != NULL) || (dec_cfg != NULL)) && (codec_format != ASM_MEDIA_FMT_NONE) && (cfg_type == AFE_PARAM_ID_SLIMBUS_CONFIG)) { port_cfg.slim_sch.data_format = AFE_SB_DATA_FORMAT_GENERIC_COMPRESSED; Loading @@ -3304,12 +3435,14 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config, goto fail_cmd; } if ((enc_format != ASM_MEDIA_FMT_NONE) && if ((codec_format != ASM_MEDIA_FMT_NONE) && (cfg_type == AFE_PARAM_ID_SLIMBUS_CONFIG)) { pr_debug("%s: Found AFE encoder support for SLIMBUS enc_format = %d\n", __func__, enc_format); ret = q6afe_send_enc_config(port_id, cfg, enc_format, *afe_config, afe_in_channels, if (enc_cfg != NULL) { pr_debug("%s: Found AFE encoder support for SLIMBUS format = %d\n", __func__, codec_format); ret = q6afe_send_enc_config(port_id, enc_cfg, codec_format, *afe_config, afe_in_channels, afe_in_bit_width, scrambler_mode); if (ret) { Loading @@ -3318,6 +3451,18 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config, goto fail_cmd; } } if (dec_cfg != NULL) { pr_debug("%s: Found AFE decoder support for SLIMBUS format = %d\n", __func__, codec_format); ret = q6afe_send_dec_config(port_id, *afe_config, dec_cfg); if (ret) { pr_err("%s: AFE decoder config for port 0x%x failed %d\n", __func__, port_id, ret); goto fail_cmd; } } } port_index = afe_get_port_index(port_id); if ((port_index >= 0) && (port_index < AFE_MAX_PORTS)) { Loading Loading @@ -3364,31 +3509,42 @@ int afe_port_start(u16 port_id, union afe_port_config *afe_config, u32 rate) { return __afe_port_start(port_id, afe_config, rate, 0, 0, NULL, ASM_MEDIA_FMT_NONE, 0); 0, 0, NULL, ASM_MEDIA_FMT_NONE, 0, NULL); } EXPORT_SYMBOL(afe_port_start); /** * afe_port_start_v2 - to configure AFE session with * specified port configuration and encoder params * specified port configuration and encoder /decoder params * * @port_id: AFE port id number * @afe_config: port configutation * @rate: sampling rate of port * @cfg: AFE encoder configuration information to setup encoder * @enc_cfg: AFE enc configuration information to setup encoder * @afe_in_channels: AFE input channel configuration, this needs * update only if input channel is differ from AFE output * @dec_cfg: AFE dec configuration information to set up decoder * * Returns 0 on success or error value on port start failure. */ int afe_port_start_v2(u16 port_id, union afe_port_config *afe_config, u32 rate, u16 afe_in_channels, u16 afe_in_bit_width, struct afe_enc_config *enc_cfg) struct afe_enc_config *enc_cfg, struct afe_dec_config *dec_cfg) { return __afe_port_start(port_id, afe_config, rate, int ret = 0; if (enc_cfg != NULL) ret = __afe_port_start(port_id, afe_config, rate, afe_in_channels, afe_in_bit_width, &enc_cfg->data, enc_cfg->format, enc_cfg->scrambler_mode); enc_cfg->scrambler_mode, dec_cfg); else if (dec_cfg != NULL) ret = __afe_port_start(port_id, afe_config, rate, afe_in_channels, afe_in_bit_width, NULL, dec_cfg->format, 0, dec_cfg); return ret; } EXPORT_SYMBOL(afe_port_start_v2); Loading include/dsp/apr_audio-v2.h +141 −0 Original line number Diff line number Diff line Loading @@ -3180,6 +3180,72 @@ struct afe_param_id_set_topology_cfg { u32 topology_id; } __packed; #define MAX_ABR_LEVELS 5 struct afe_bit_rate_level_map_t { /* * Key value pair for link quality level to bitrate * mapping in AFE */ uint32_t link_quality_level; uint32_t bitrate; } __packed; struct afe_quality_level_to_bitrate_info { /* * Number of quality levels being mapped. * This will be equal to the size of mapping table. */ uint32_t num_levels; /* * Quality level to bitrate mapping table */ struct afe_bit_rate_level_map_t bit_rate_level_map[MAX_ABR_LEVELS]; } __packed; struct afe_imc_dec_enc_info { /* * Decoder to encoder communication direction. * Transmit = 0 / Receive = 1 */ uint32_t direction; /* * Enable / disable IMC between decoder and encoder */ uint32_t enable; /* * Purpose of IMC being set up between decoder and encoder. * Param ID defined for link quality feedback in LPASS will * be the default value sent as purpose. * Supported values: * AFE_ENCDEC_PURPOSE_ID_BT_INFO */ uint32_t purpose; /* * Unique communication instance ID. * Data type a2dp_abr_instance used to set instance ID. * purpose and comm_instance together form the actual key * used in IMC registration, which must be the same for * encoder and decoder for which IMC is being set up. */ uint32_t comm_instance; } __packed; struct afe_abr_dec_cfg_t { struct afe_imc_dec_enc_info imc_info; } __packed; struct afe_abr_enc_cfg_t { /* * Link quality level to bitrate mapping info sent to DSP. */ struct afe_quality_level_to_bitrate_info mapping_info; /* * Information to set up IMC between decoder and encoder. */ struct afe_imc_dec_enc_info imc_info; } __packed; #define AFE_PARAM_ID_APTX_SYNC_MODE 0x00013205 struct afe_param_id_aptx_sync_mode { Loading Loading @@ -3230,6 +3296,39 @@ struct afe_param_id_aptx_sync_mode { */ #define AFE_ENCODER_PARAM_ID_ENABLE_SCRAMBLING 0x0001323C /* * Link quality level to bitrate mapping info sent to AFE Encoder. * This parameter may be set runtime. */ #define AFE_ENCODER_PARAM_ID_BIT_RATE_LEVEL_MAP 0x000132E1 /* * Parameter to set up Inter Module Communication (IMC) between * AFE Decoder and Encoder. * This parameter may be set runtime. */ #define AFE_ENCDEC_PARAM_ID_DEC_TO_ENC_COMMUNICATION 0x0001323D /* * Purpose of IMC set up between encoder and decoder. * Communication instance and purpose together form the * actual key used for IMC registration. */ #define AFE_ENCDEC_PURPOSE_ID_BT_INFO 0x000132E2 #define AFE_MODULE_ID_DECODER 0x00013231 /* * Macro for defining the depacketizer ID: COP. */ #define AFE_MODULE_ID_DEPACKETIZER_COP 0x00013233 /* * Depacketizer type parameter for the #AVS_MODULE_ID_DECODER module. * This parameter cannot be set runtime. */ #define AFE_DECODER_PARAM_ID_DEPACKETIZER_ID 0x00013235 /* * Data format to send compressed data * is transmitted/received over Slimbus lines. Loading Loading @@ -3531,6 +3630,7 @@ struct asm_ldac_specific_enc_cfg_t { struct asm_ldac_enc_cfg_t { struct asm_custom_enc_cfg_t custom_config; struct asm_ldac_specific_enc_cfg_t ldac_specific_config; struct afe_abr_enc_cfg_t abr_config; } __packed; struct afe_enc_fmt_id_param_t { Loading Loading @@ -3612,6 +3712,11 @@ struct afe_enc_config { union afe_enc_config_data data; }; struct afe_dec_config { u32 format; struct afe_abr_dec_cfg_t abr_dec_cfg; }; struct afe_enc_cfg_blk_param_t { uint32_t enc_cfg_blk_size; /* Loading Loading @@ -3644,6 +3749,39 @@ struct avs_enc_set_scrambler_param_t { uint32_t enable_scrambler; }; /* * Payload of the AVS_ENCODER_PARAM_ID_BIT_RATE_LEVEL_MAP parameter. */ struct afe_enc_level_to_bitrate_map_param_t { /* * Parameter for mapping link quality level to bitrate. */ struct afe_quality_level_to_bitrate_info mapping_table; }; /* * Payload of the AVS_ENCDEC_PARAM_ID_DEC_TO_ENC_COMMUNICATION parameter. */ struct afe_enc_dec_imc_info_param_t { /* * Parameter to set up Inter Module Communication (IMC) between * AFE Decoder and Encoder. */ struct afe_imc_dec_enc_info imc_info; }; /* * Payload of the AVS_DECODER_PARAM_ID_DEPACKETIZER_ID parameter. */ struct avs_dec_depacketizer_id_param_t { /* * Supported values: * #AVS_MODULE_ID_DEPACKETIZER_COP * Any OpenDSP supported values */ uint32_t dec_depacketizer_id; }; union afe_port_config { struct afe_param_id_pcm_cfg pcm; struct afe_param_id_i2s_cfg i2s; Loading @@ -3663,6 +3801,9 @@ union afe_port_config { struct afe_enc_cfg_blk_param_t enc_blk_param; struct avs_enc_packetizer_id_param_t enc_pkt_id_param; struct avs_enc_set_scrambler_param_t enc_set_scrambler_param; struct avs_dec_depacketizer_id_param_t dec_depkt_id_param; struct afe_enc_level_to_bitrate_map_param_t map_param; struct afe_enc_dec_imc_info_param_t imc_info_param; } __packed; #define AFE_PORT_CMD_DEVICE_START 0x000100E5 Loading include/dsp/q6afe-v2.h +2 −1 Original line number Diff line number Diff line Loading @@ -318,7 +318,8 @@ int afe_port_start(u16 port_id, union afe_port_config *afe_config, u32 rate); int afe_port_start_v2(u16 port_id, union afe_port_config *afe_config, u32 rate, u16 afe_in_channels, u16 afe_in_bit_width, struct afe_enc_config *enc_config); struct afe_enc_config *enc_config, struct afe_dec_config *dec_config); int afe_spk_prot_feed_back_cfg(int src_port, int dst_port, int l_ch, int r_ch, u32 enable); int afe_spk_prot_get_calib_data(struct afe_spkr_prot_get_vi_calib *calib); Loading Loading
asoc/msm-dai-q6-v2.c +113 −8 Original line number Diff line number Diff line Loading @@ -46,6 +46,7 @@ enum { ENC_FMT_NONE, DEC_FMT_NONE = ENC_FMT_NONE, ENC_FMT_SBC = ASM_MEDIA_FMT_SBC, ENC_FMT_AAC_V2 = ASM_MEDIA_FMT_AAC_V2, ENC_FMT_APTX = ASM_MEDIA_FMT_APTX, Loading Loading @@ -200,6 +201,7 @@ struct msm_dai_q6_dai_data { u32 afe_in_channels; u16 afe_in_bitformat; struct afe_enc_config enc_config; struct afe_dec_config dec_config; union afe_port_config port_config; u16 vi_feed_mono; }; Loading Loading @@ -1538,22 +1540,46 @@ static int msm_dai_q6_prepare(struct snd_pcm_substream *substream, if (dai_data->enc_config.format != ENC_FMT_NONE) { int bitwidth = 0; if (dai_data->afe_in_bitformat == SNDRV_PCM_FORMAT_S24_LE) switch (dai_data->afe_in_bitformat) { case SNDRV_PCM_FORMAT_S32_LE: bitwidth = 32; break; case SNDRV_PCM_FORMAT_S24_LE: bitwidth = 24; else if (dai_data->afe_in_bitformat == SNDRV_PCM_FORMAT_S16_LE) break; case SNDRV_PCM_FORMAT_S16_LE: default: bitwidth = 16; break; } pr_debug("%s: calling AFE_PORT_START_V2 with enc_format: %d\n", __func__, dai_data->enc_config.format); rc = afe_port_start_v2(dai->id, &dai_data->port_config, dai_data->rate, dai_data->afe_in_channels, bitwidth, &dai_data->enc_config); &dai_data->enc_config, NULL); if (rc < 0) pr_err("%s: afe_port_start_v2 failed error: %d\n", __func__, rc); } else if (dai_data->dec_config.format != DEC_FMT_NONE) { /* * A dummy Tx session is established in LPASS to * get the link statistics from BTSoC. * Depacketizer extracts the bit rate levels and * transmits them to the encoder on the Rx path. * Since this is a dummy decoder - channels, bit * width are sent as 0 and encoder config is NULL. * This could be updated in the future if there is * a complete Tx path set up that uses this decoder. */ rc = afe_port_start_v2(dai->id, &dai_data->port_config, dai_data->rate, 0, 0, NULL, &dai_data->dec_config); if (rc < 0) { pr_err("%s: fail to open AFE port 0x%x\n", __func__, dai->id); } } else { rc = afe_port_start(dai->id, &dai_data->port_config, dai_data->rate); Loading Loading @@ -2345,10 +2371,11 @@ static const struct soc_enum afe_input_chs_enum[] = { SOC_ENUM_SINGLE_EXT(3, afe_input_chs_text), }; static const char *const afe_input_bit_format_text[] = {"S16_LE", "S24_LE"}; static const char *const afe_input_bit_format_text[] = {"S16_LE", "S24_LE", "S32_LE"}; static const struct soc_enum afe_input_bit_format_enum[] = { SOC_ENUM_SINGLE_EXT(2, afe_input_bit_format_text), SOC_ENUM_SINGLE_EXT(3, afe_input_bit_format_text), }; static int msm_dai_q6_afe_input_channel_get(struct snd_kcontrol *kcontrol, Loading Loading @@ -2391,6 +2418,9 @@ static int msm_dai_q6_afe_input_bit_format_get( } switch (dai_data->afe_in_bitformat) { case SNDRV_PCM_FORMAT_S32_LE: ucontrol->value.integer.value[0] = 2; break; case SNDRV_PCM_FORMAT_S24_LE: ucontrol->value.integer.value[0] = 1; break; Loading @@ -2416,6 +2446,9 @@ static int msm_dai_q6_afe_input_bit_format_put( return -EINVAL; } switch (ucontrol->value.integer.value[0]) { case 2: dai_data->afe_in_bitformat = SNDRV_PCM_FORMAT_S32_LE; break; case 1: dai_data->afe_in_bitformat = SNDRV_PCM_FORMAT_S24_LE; break; Loading Loading @@ -2483,6 +2516,73 @@ static const struct snd_kcontrol_new afe_enc_config_controls[] = { msm_dai_q6_afe_scrambler_mode_put), }; static int msm_dai_q6_afe_dec_cfg_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; uinfo->count = sizeof(struct afe_dec_config); 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; int 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); memcpy(ucontrol->value.bytes.data + format_size, &dai_data->dec_config.abr_dec_cfg, sizeof(struct afe_abr_dec_cfg_t)); return 0; } static int msm_dai_q6_afe_dec_cfg_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; int 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); memcpy(&dai_data->dec_config.abr_dec_cfg, ucontrol->value.bytes.data + format_size, sizeof(struct afe_abr_dec_cfg_t)); return 0; } static const struct snd_kcontrol_new afe_dec_config_controls[] = { { .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE), .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, }, }; static int msm_dai_q6_slim_rx_drift_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { Loading Loading @@ -2650,6 +2750,11 @@ static int msm_dai_q6_dai_probe(struct snd_soc_dai *dai) snd_ctl_new1(&avd_drift_config_controls[2], dai)); break; case SLIMBUS_7_TX: rc = snd_ctl_add(dai->component->card->snd_card, snd_ctl_new1(&afe_dec_config_controls[0], dai_data)); break; case RT_PROXY_DAI_001_RX: rc = snd_ctl_add(dai->component->card->snd_card, snd_ctl_new1(&rt_proxy_config_controls[0], Loading
asoc/msm-pcm-routing-v2.c +38 −0 Original line number Diff line number Diff line Loading @@ -62,6 +62,7 @@ static struct cal_type_data *cal_data[MAX_ROUTING_CAL_TYPES]; static int fm_switch_enable; static int hfp_switch_enable; static int a2dp_switch_enable; static int int0_mi2s_switch_enable; static int int4_mi2s_switch_enable; static int pri_mi2s_switch_enable; Loading Loading @@ -2160,6 +2161,34 @@ static int msm_routing_put_hfp_switch_mixer(struct snd_kcontrol *kcontrol, return 1; } static int msm_routing_a2dp_switch_mixer_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { ucontrol->value.integer.value[0] = a2dp_switch_enable; pr_debug("%s: A2DP Switch enable %ld\n", __func__, ucontrol->value.integer.value[0]); return 0; } static int msm_routing_a2dp_switch_mixer_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kcontrol); struct snd_soc_dapm_update *update = NULL; pr_debug("%s: A2DP Switch enable %ld\n", __func__, ucontrol->value.integer.value[0]); a2dp_switch_enable = ucontrol->value.integer.value[0]; if (a2dp_switch_enable) snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, 1, update); else snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, 0, update); return 1; } static int msm_routing_get_int0_mi2s_switch_mixer(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { Loading Loading @@ -13659,6 +13688,11 @@ static const struct snd_kcontrol_new usb_switch_mixer_controls = 0, 1, 0, msm_routing_get_usb_switch_mixer, msm_routing_put_usb_switch_mixer); static const struct snd_kcontrol_new a2dp_slim7_switch_mixer_controls = SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, 0, 1, 0, msm_routing_a2dp_switch_mixer_get, msm_routing_a2dp_switch_mixer_put); static const struct soc_enum lsm_port_enum = SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(lsm_port_text), lsm_port_text); Loading Loading @@ -15469,6 +15503,8 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { &hfp_slim7_switch_mixer_controls), SND_SOC_DAPM_SWITCH("USB_DL_HL", SND_SOC_NOPM, 0, 0, &usb_switch_mixer_controls), SND_SOC_DAPM_SWITCH("A2DP_SLIM7_UL_HL", SND_SOC_NOPM, 0, 0, &a2dp_slim7_switch_mixer_controls), /* Mixer definitions */ SND_SOC_DAPM_MIXER("PRI_RX Audio Mixer", SND_SOC_NOPM, 0, 0, Loading Loading @@ -17826,6 +17862,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"HFP_SLIM7_UL_HL", "Switch", "SLIMBUS_7_TX"}, {"AUX_PCM_RX", NULL, "AUXPCM_DL_HL"}, {"AUX_PCM_RX", NULL, "INTHFP_DL_HL"}, {"SLIM7_UL_HL", NULL, "A2DP_SLIM7_UL_HL"}, {"A2DP_SLIM7_UL_HL", "Switch", "SLIMBUS_7_TX"}, {"SEC_AUX_PCM_RX", NULL, "SEC_AUXPCM_DL_HL"}, {"AUXPCM_UL_HL", NULL, "AUX_PCM_TX"}, {"SEC_AUXPCM_UL_HL", NULL, "SEC_AUX_PCM_TX"},
dsp/q6afe.c +181 −25 Original line number Diff line number Diff line Loading @@ -2905,6 +2905,79 @@ int afe_port_send_usb_dev_param(u16 port_id, union afe_port_config *afe_config) return ret; } static int q6afe_send_dec_config(u16 port_id, union afe_port_config afe_config, struct afe_dec_config *cfg) { struct avs_dec_depacketizer_id_param_t dec_depkt_id_param; struct afe_enc_dec_imc_info_param_t imc_info_param; struct afe_port_media_type_t media_type; struct param_hdr_v3 param_hdr; int ret; memset(&dec_depkt_id_param, 0, sizeof(dec_depkt_id_param)); memset(&imc_info_param, 0, sizeof(imc_info_param)); memset(&media_type, 0, sizeof(media_type)); memset(¶m_hdr, 0, sizeof(param_hdr)); param_hdr.module_id = AFE_MODULE_ID_DECODER; param_hdr.instance_id = INSTANCE_ID_0; pr_debug("%s: sending AFE_DECODER_PARAM_ID_DEPACKETIZER to DSP payload\n", __func__); param_hdr.param_id = AFE_DECODER_PARAM_ID_DEPACKETIZER_ID; param_hdr.param_size = sizeof(struct avs_dec_depacketizer_id_param_t); dec_depkt_id_param.dec_depacketizer_id = AFE_MODULE_ID_DEPACKETIZER_COP; ret = q6afe_pack_and_set_param_in_band(port_id, q6audio_get_port_index(port_id), param_hdr, (u8 *) &dec_depkt_id_param); if (ret) { pr_err("%s: AFE_DECODER_PARAM_ID_DEPACKETIZER for port 0x%x failed %d\n", __func__, port_id, ret); goto exit; } pr_debug("%s:sending AFE_ENCDEC_PARAM_ID_DEC_TO_ENC_COMMUNICATION to DSP payload\n", __func__); param_hdr.param_id = AFE_ENCDEC_PARAM_ID_DEC_TO_ENC_COMMUNICATION; param_hdr.param_size = sizeof(struct afe_enc_dec_imc_info_param_t); imc_info_param.imc_info = cfg->abr_dec_cfg.imc_info; ret = q6afe_pack_and_set_param_in_band(port_id, q6audio_get_port_index(port_id), param_hdr, (u8 *) &imc_info_param); if (ret) { pr_err("%s: AFE_ENCDEC_PARAM_ID_DEC_TO_ENC_COMMUNICATION for port 0x%x failed %d\n", __func__, port_id, ret); goto exit; } pr_debug("%s:Sending AFE_API_VERSION_PORT_MEDIA_TYPE to DSP", __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); media_type.minor_version = AFE_API_VERSION_PORT_MEDIA_TYPE; media_type.sample_rate = afe_config.slim_sch.sample_rate; media_type.bit_width = afe_config.slim_sch.bit_width; media_type.num_channels = afe_config.slim_sch.num_channels; media_type.data_format = AFE_PORT_DATA_FORMAT_PCM; media_type.reserved = 0; ret = q6afe_pack_and_set_param_in_band(port_id, q6audio_get_port_index(port_id), param_hdr, (u8 *) &media_type); if (ret) { pr_err("%s: AFE_API_VERSION_PORT_MEDIA_TYPE for port 0x%x failed %d\n", __func__, port_id, ret); goto exit; } exit: return ret; } static int q6afe_send_enc_config(u16 port_id, union afe_enc_config_data *cfg, u32 format, union afe_port_config afe_config, Loading @@ -2916,6 +2989,8 @@ static int q6afe_send_enc_config(u16 port_id, struct afe_param_id_aptx_sync_mode sync_mode_param; struct avs_enc_packetizer_id_param_t enc_pkt_id_param; struct avs_enc_set_scrambler_param_t enc_set_scrambler_param; struct afe_enc_level_to_bitrate_map_param_t map_param; struct afe_enc_dec_imc_info_param_t imc_info_param; struct afe_port_media_type_t media_type; struct param_hdr_v3 param_hdr; int ret; Loading @@ -2926,6 +3001,8 @@ static int q6afe_send_enc_config(u16 port_id, memset(&sync_mode_param, 0, sizeof(sync_mode_param)); memset(&enc_pkt_id_param, 0, sizeof(enc_pkt_id_param)); memset(&enc_set_scrambler_param, 0, sizeof(enc_set_scrambler_param)); memset(&map_param, 0, sizeof(map_param)); memset(&imc_info_param, 0, sizeof(imc_info_param)); memset(&media_type, 0, sizeof(media_type)); memset(¶m_hdr, 0, sizeof(param_hdr)); Loading Loading @@ -2953,11 +3030,20 @@ static int q6afe_send_enc_config(u16 port_id, goto exit; } if (format == ASM_MEDIA_FMT_LDAC) { param_hdr.param_size = sizeof(struct afe_enc_cfg_blk_param_t) - sizeof(struct afe_abr_enc_cfg_t); enc_blk_param.enc_cfg_blk_size = sizeof(union afe_enc_config_data) - sizeof(struct afe_abr_enc_cfg_t); } else { param_hdr.param_size = sizeof(struct afe_enc_cfg_blk_param_t); enc_blk_param.enc_cfg_blk_size = sizeof(union afe_enc_config_data); } pr_debug("%s:send AFE_ENCODER_PARAM_ID_ENC_CFG_BLK to DSP payloadn", __func__); param_hdr.param_id = AFE_ENCODER_PARAM_ID_ENC_CFG_BLK; param_hdr.param_size = sizeof(struct afe_enc_cfg_blk_param_t); enc_blk_param.enc_cfg_blk_size = sizeof(union afe_enc_config_data); enc_blk_param.enc_blk_config = *cfg; ret = q6afe_pack_and_set_param_in_band(port_id, q6audio_get_port_index(port_id), Loading Loading @@ -3019,12 +3105,55 @@ static int q6afe_send_enc_config(u16 port_id, goto exit; } if (format == ASM_MEDIA_FMT_LDAC) { pr_debug("%s:sending AFE_ENCODER_PARAM_ID_BIT_RATE_LEVEL_MAP to DSP payload", __func__); param_hdr.param_id = AFE_ENCODER_PARAM_ID_BIT_RATE_LEVEL_MAP; param_hdr.param_size = sizeof(struct afe_enc_level_to_bitrate_map_param_t); map_param.mapping_table = cfg->ldac_config.abr_config.mapping_info; ret = q6afe_pack_and_set_param_in_band(port_id, q6audio_get_port_index(port_id), param_hdr, (u8 *) &map_param); if (ret) { pr_err("%s: AFE_ENCODER_PARAM_ID_BIT_RATE_LEVEL_MAP for port 0x%x failed %d\n", __func__, port_id, ret); goto exit; } pr_debug("%s: sending AFE_ENCDEC_PARAM_ID_DEC_TO_ENC_COMMUNICATION to DSP payload", __func__); param_hdr.param_id = AFE_ENCDEC_PARAM_ID_DEC_TO_ENC_COMMUNICATION; param_hdr.param_size = sizeof(struct afe_enc_dec_imc_info_param_t); imc_info_param.imc_info = cfg->ldac_config.abr_config.imc_info; ret = q6afe_pack_and_set_param_in_band(port_id, q6audio_get_port_index(port_id), param_hdr, (u8 *) &imc_info_param); if (ret) { pr_err("%s: AFE_ENCDEC_PARAM_ID_DEC_TO_ENC_COMMUNICATION for port 0x%x failed %d\n", __func__, port_id, ret); goto exit; } } pr_debug("%s:Sending AFE_API_VERSION_PORT_MEDIA_TYPE to DSP", __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); media_type.minor_version = AFE_API_VERSION_PORT_MEDIA_TYPE; media_type.sample_rate = afe_config.slim_sch.sample_rate; if (format == ASM_MEDIA_FMT_LDAC) media_type.sample_rate = cfg->ldac_config.custom_config.sample_rate; else media_type.sample_rate = afe_config.slim_sch.sample_rate; if (afe_in_bit_width) media_type.bit_width = afe_in_bit_width; else Loading Loading @@ -3052,8 +3181,9 @@ static int q6afe_send_enc_config(u16 port_id, static int __afe_port_start(u16 port_id, union afe_port_config *afe_config, u32 rate, u16 afe_in_channels, u16 afe_in_bit_width, union afe_enc_config_data *cfg, u32 enc_format, u32 scrambler_mode) union afe_enc_config_data *enc_cfg, u32 codec_format, u32 scrambler_mode, struct afe_dec_config *dec_cfg) { union afe_port_config port_cfg; struct param_hdr_v3 param_hdr; Loading Loading @@ -3290,7 +3420,8 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config, param_hdr.param_size = sizeof(union afe_port_config); port_cfg = *afe_config; if ((enc_format != ASM_MEDIA_FMT_NONE) && if (((enc_cfg != NULL) || (dec_cfg != NULL)) && (codec_format != ASM_MEDIA_FMT_NONE) && (cfg_type == AFE_PARAM_ID_SLIMBUS_CONFIG)) { port_cfg.slim_sch.data_format = AFE_SB_DATA_FORMAT_GENERIC_COMPRESSED; Loading @@ -3304,12 +3435,14 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config, goto fail_cmd; } if ((enc_format != ASM_MEDIA_FMT_NONE) && if ((codec_format != ASM_MEDIA_FMT_NONE) && (cfg_type == AFE_PARAM_ID_SLIMBUS_CONFIG)) { pr_debug("%s: Found AFE encoder support for SLIMBUS enc_format = %d\n", __func__, enc_format); ret = q6afe_send_enc_config(port_id, cfg, enc_format, *afe_config, afe_in_channels, if (enc_cfg != NULL) { pr_debug("%s: Found AFE encoder support for SLIMBUS format = %d\n", __func__, codec_format); ret = q6afe_send_enc_config(port_id, enc_cfg, codec_format, *afe_config, afe_in_channels, afe_in_bit_width, scrambler_mode); if (ret) { Loading @@ -3318,6 +3451,18 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config, goto fail_cmd; } } if (dec_cfg != NULL) { pr_debug("%s: Found AFE decoder support for SLIMBUS format = %d\n", __func__, codec_format); ret = q6afe_send_dec_config(port_id, *afe_config, dec_cfg); if (ret) { pr_err("%s: AFE decoder config for port 0x%x failed %d\n", __func__, port_id, ret); goto fail_cmd; } } } port_index = afe_get_port_index(port_id); if ((port_index >= 0) && (port_index < AFE_MAX_PORTS)) { Loading Loading @@ -3364,31 +3509,42 @@ int afe_port_start(u16 port_id, union afe_port_config *afe_config, u32 rate) { return __afe_port_start(port_id, afe_config, rate, 0, 0, NULL, ASM_MEDIA_FMT_NONE, 0); 0, 0, NULL, ASM_MEDIA_FMT_NONE, 0, NULL); } EXPORT_SYMBOL(afe_port_start); /** * afe_port_start_v2 - to configure AFE session with * specified port configuration and encoder params * specified port configuration and encoder /decoder params * * @port_id: AFE port id number * @afe_config: port configutation * @rate: sampling rate of port * @cfg: AFE encoder configuration information to setup encoder * @enc_cfg: AFE enc configuration information to setup encoder * @afe_in_channels: AFE input channel configuration, this needs * update only if input channel is differ from AFE output * @dec_cfg: AFE dec configuration information to set up decoder * * Returns 0 on success or error value on port start failure. */ int afe_port_start_v2(u16 port_id, union afe_port_config *afe_config, u32 rate, u16 afe_in_channels, u16 afe_in_bit_width, struct afe_enc_config *enc_cfg) struct afe_enc_config *enc_cfg, struct afe_dec_config *dec_cfg) { return __afe_port_start(port_id, afe_config, rate, int ret = 0; if (enc_cfg != NULL) ret = __afe_port_start(port_id, afe_config, rate, afe_in_channels, afe_in_bit_width, &enc_cfg->data, enc_cfg->format, enc_cfg->scrambler_mode); enc_cfg->scrambler_mode, dec_cfg); else if (dec_cfg != NULL) ret = __afe_port_start(port_id, afe_config, rate, afe_in_channels, afe_in_bit_width, NULL, dec_cfg->format, 0, dec_cfg); return ret; } EXPORT_SYMBOL(afe_port_start_v2); Loading
include/dsp/apr_audio-v2.h +141 −0 Original line number Diff line number Diff line Loading @@ -3180,6 +3180,72 @@ struct afe_param_id_set_topology_cfg { u32 topology_id; } __packed; #define MAX_ABR_LEVELS 5 struct afe_bit_rate_level_map_t { /* * Key value pair for link quality level to bitrate * mapping in AFE */ uint32_t link_quality_level; uint32_t bitrate; } __packed; struct afe_quality_level_to_bitrate_info { /* * Number of quality levels being mapped. * This will be equal to the size of mapping table. */ uint32_t num_levels; /* * Quality level to bitrate mapping table */ struct afe_bit_rate_level_map_t bit_rate_level_map[MAX_ABR_LEVELS]; } __packed; struct afe_imc_dec_enc_info { /* * Decoder to encoder communication direction. * Transmit = 0 / Receive = 1 */ uint32_t direction; /* * Enable / disable IMC between decoder and encoder */ uint32_t enable; /* * Purpose of IMC being set up between decoder and encoder. * Param ID defined for link quality feedback in LPASS will * be the default value sent as purpose. * Supported values: * AFE_ENCDEC_PURPOSE_ID_BT_INFO */ uint32_t purpose; /* * Unique communication instance ID. * Data type a2dp_abr_instance used to set instance ID. * purpose and comm_instance together form the actual key * used in IMC registration, which must be the same for * encoder and decoder for which IMC is being set up. */ uint32_t comm_instance; } __packed; struct afe_abr_dec_cfg_t { struct afe_imc_dec_enc_info imc_info; } __packed; struct afe_abr_enc_cfg_t { /* * Link quality level to bitrate mapping info sent to DSP. */ struct afe_quality_level_to_bitrate_info mapping_info; /* * Information to set up IMC between decoder and encoder. */ struct afe_imc_dec_enc_info imc_info; } __packed; #define AFE_PARAM_ID_APTX_SYNC_MODE 0x00013205 struct afe_param_id_aptx_sync_mode { Loading Loading @@ -3230,6 +3296,39 @@ struct afe_param_id_aptx_sync_mode { */ #define AFE_ENCODER_PARAM_ID_ENABLE_SCRAMBLING 0x0001323C /* * Link quality level to bitrate mapping info sent to AFE Encoder. * This parameter may be set runtime. */ #define AFE_ENCODER_PARAM_ID_BIT_RATE_LEVEL_MAP 0x000132E1 /* * Parameter to set up Inter Module Communication (IMC) between * AFE Decoder and Encoder. * This parameter may be set runtime. */ #define AFE_ENCDEC_PARAM_ID_DEC_TO_ENC_COMMUNICATION 0x0001323D /* * Purpose of IMC set up between encoder and decoder. * Communication instance and purpose together form the * actual key used for IMC registration. */ #define AFE_ENCDEC_PURPOSE_ID_BT_INFO 0x000132E2 #define AFE_MODULE_ID_DECODER 0x00013231 /* * Macro for defining the depacketizer ID: COP. */ #define AFE_MODULE_ID_DEPACKETIZER_COP 0x00013233 /* * Depacketizer type parameter for the #AVS_MODULE_ID_DECODER module. * This parameter cannot be set runtime. */ #define AFE_DECODER_PARAM_ID_DEPACKETIZER_ID 0x00013235 /* * Data format to send compressed data * is transmitted/received over Slimbus lines. Loading Loading @@ -3531,6 +3630,7 @@ struct asm_ldac_specific_enc_cfg_t { struct asm_ldac_enc_cfg_t { struct asm_custom_enc_cfg_t custom_config; struct asm_ldac_specific_enc_cfg_t ldac_specific_config; struct afe_abr_enc_cfg_t abr_config; } __packed; struct afe_enc_fmt_id_param_t { Loading Loading @@ -3612,6 +3712,11 @@ struct afe_enc_config { union afe_enc_config_data data; }; struct afe_dec_config { u32 format; struct afe_abr_dec_cfg_t abr_dec_cfg; }; struct afe_enc_cfg_blk_param_t { uint32_t enc_cfg_blk_size; /* Loading Loading @@ -3644,6 +3749,39 @@ struct avs_enc_set_scrambler_param_t { uint32_t enable_scrambler; }; /* * Payload of the AVS_ENCODER_PARAM_ID_BIT_RATE_LEVEL_MAP parameter. */ struct afe_enc_level_to_bitrate_map_param_t { /* * Parameter for mapping link quality level to bitrate. */ struct afe_quality_level_to_bitrate_info mapping_table; }; /* * Payload of the AVS_ENCDEC_PARAM_ID_DEC_TO_ENC_COMMUNICATION parameter. */ struct afe_enc_dec_imc_info_param_t { /* * Parameter to set up Inter Module Communication (IMC) between * AFE Decoder and Encoder. */ struct afe_imc_dec_enc_info imc_info; }; /* * Payload of the AVS_DECODER_PARAM_ID_DEPACKETIZER_ID parameter. */ struct avs_dec_depacketizer_id_param_t { /* * Supported values: * #AVS_MODULE_ID_DEPACKETIZER_COP * Any OpenDSP supported values */ uint32_t dec_depacketizer_id; }; union afe_port_config { struct afe_param_id_pcm_cfg pcm; struct afe_param_id_i2s_cfg i2s; Loading @@ -3663,6 +3801,9 @@ union afe_port_config { struct afe_enc_cfg_blk_param_t enc_blk_param; struct avs_enc_packetizer_id_param_t enc_pkt_id_param; struct avs_enc_set_scrambler_param_t enc_set_scrambler_param; struct avs_dec_depacketizer_id_param_t dec_depkt_id_param; struct afe_enc_level_to_bitrate_map_param_t map_param; struct afe_enc_dec_imc_info_param_t imc_info_param; } __packed; #define AFE_PORT_CMD_DEVICE_START 0x000100E5 Loading
include/dsp/q6afe-v2.h +2 −1 Original line number Diff line number Diff line Loading @@ -318,7 +318,8 @@ int afe_port_start(u16 port_id, union afe_port_config *afe_config, u32 rate); int afe_port_start_v2(u16 port_id, union afe_port_config *afe_config, u32 rate, u16 afe_in_channels, u16 afe_in_bit_width, struct afe_enc_config *enc_config); struct afe_enc_config *enc_config, struct afe_dec_config *dec_config); int afe_spk_prot_feed_back_cfg(int src_port, int dst_port, int l_ch, int r_ch, u32 enable); int afe_spk_prot_get_calib_data(struct afe_spkr_prot_get_vi_calib *calib); Loading