Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 40bf8e89 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "asoc: dsp: Add support for adaptive bitrate"

parents eb01e25c c0c31476
Loading
Loading
Loading
Loading
+113 −8
Original line number Diff line number Diff line
@@ -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,
@@ -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;
};
@@ -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);
@@ -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,
@@ -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;
@@ -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;
@@ -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)
{
@@ -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],
+38 −0
Original line number Diff line number Diff line
@@ -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;
@@ -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)
{
@@ -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);
@@ -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,
@@ -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"},
+181 −25
Original line number Diff line number Diff line
@@ -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(&param_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,
@@ -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;
@@ -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(&param_hdr, 0, sizeof(param_hdr));

@@ -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),
@@ -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
@@ -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;
@@ -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;
@@ -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) {
@@ -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)) {
@@ -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);

+141 −0
Original line number Diff line number Diff line
@@ -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 {
@@ -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.
@@ -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 {
@@ -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;
	/*
@@ -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;
@@ -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
+2 −1
Original line number Diff line number Diff line
@@ -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);