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

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

Merge "ASoC: msm: qdsp6v2: support for AFE encoder"

parents 1befb076 cb539e6d
Loading
Loading
Loading
Loading
+331 −0
Original line number Diff line number Diff line
@@ -2738,6 +2738,333 @@ struct afe_param_id_set_topology_cfg {
	u32		topology_id;
} __packed;


/*
 * Generic encoder module ID.
 * This module supports the following parameter IDs:
 * #AVS_ENCODER_PARAM_ID_ENC_FMT_ID (cannot be set run time)
 * #AVS_ENCODER_PARAM_ID_ENC_CFG_BLK (may be set run time)
 * #AVS_ENCODER_PARAM_ID_ENC_BITRATE (may be set run time)
 * #AVS_ENCODER_PARAM_ID_PACKETIZER_ID (cannot be set run time)
 * Opcode - AVS_MODULE_ID_ENCODER
 * AFE Command AFE_PORT_CMD_SET_PARAM_V2 supports this module ID.
 */
#define AFE_MODULE_ID_ENCODER        0x00013229

/* Macro for defining the packetizer ID: COP. */
#define AFE_MODULE_ID_PACKETIZER_COP 0x0001322A

/*
 * Packetizer type parameter for the #AVS_MODULE_ID_ENCODER module.
 * This parameter cannot be set runtime.
 */
#define AFE_ENCODER_PARAM_ID_PACKETIZER_ID 0x0001322E

/*
 * Encoder config block  parameter for the #AVS_MODULE_ID_ENCODER module.
 * This parameter may be set runtime.
 */
#define AFE_ENCODER_PARAM_ID_ENC_CFG_BLK 0x0001322C

/*
 * Encoder format ID parameter for the #AVS_MODULE_ID_ENCODER module.
 * This parameter cannot be set runtime.
 */
#define AFE_ENCODER_PARAM_ID_ENC_FMT_ID         0x0001322B

/*
 * Data format to send compressed data
 * is transmitted/received over Slimbus lines.
 */
#define AFE_SB_DATA_FORMAT_GENERIC_COMPRESSED    0x3

/*
 * ID for AFE port module. This will be used to define port properties.
 * This module supports following parameter IDs:
 * #AFE_PARAM_ID_PORT_MEDIA_TYPE
 * To configure the port property, the client must use the
 * #AFE_PORT_CMD_SET_PARAM_V2 command,
 * and fill the module ID with the respective parameter IDs as listed above.
 * @apr_hdr_fields
 * Opcode -- AFE_MODULE_PORT
 */
#define AFE_MODULE_PORT                          0x000102a6

/*
 * ID of the parameter used by #AFE_MODULE_PORT to set the port media type.
 * parameter ID is currently supported using#AFE_PORT_CMD_SET_PARAM_V2 command.
 */
#define AFE_PARAM_ID_PORT_MEDIA_TYPE              0x000102a7

/*
 * Macros for defining the "data_format" field in the
 * #AFE_PARAM_ID_PORT_MEDIA_TYPE
 */
#define AFE_PORT_DATA_FORMAT_PCM                  0x0
#define AFE_PORT_DATA_FORMAT_GENERIC_COMPRESSED   0x1

/*
 * Macro for defining the "minor_version" field in the
 * #AFE_PARAM_ID_PORT_MEDIA_TYPE
 */
#define AFE_API_VERSION_PORT_MEDIA_TYPE           0x1

#define ASM_MEDIA_FMT_NONE                        0x0

/*
 * Media format ID for SBC encode configuration.
 * @par SBC encode configuration (asm_sbc_enc_cfg_t)
 * @table{weak__asm__sbc__enc__cfg__t}
 */
#define ASM_MEDIA_FMT_SBC                         0x00010BF2

/* SBC channel Mono mode.*/
#define ASM_MEDIA_FMT_SBC_CHANNEL_MODE_MONO                     1

/* SBC channel Stereo mode. */
#define ASM_MEDIA_FMT_SBC_CHANNEL_MODE_STEREO                   2

/* SBC channel Dual Mono mode. */
#define ASM_MEDIA_FMT_SBC_CHANNEL_MODE_DUAL_MONO                8

/* SBC channel Joint Stereo mode. */
#define ASM_MEDIA_FMT_SBC_CHANNEL_MODE_JOINT_STEREO             9

/* SBC bit allocation method = loudness. */
#define ASM_MEDIA_FMT_SBC_ALLOCATION_METHOD_LOUDNESS            0

/* SBC bit allocation method = SNR. */
#define ASM_MEDIA_FMT_SBC_ALLOCATION_METHOD_SNR                 1


/*
 * Payload of the SBC encoder configuration parameters in the
 * #ASM_MEDIA_FMT_SBC media format.
 */
struct asm_sbc_enc_cfg_t {
	/*
	 * Number of subbands.
	 * @values 4, 8
	 */
	uint32_t    num_subbands;

	/*
	 * Size of the encoded block in samples.
	 * @values 4, 8, 12, 16
	 */
	uint32_t    blk_len;

	/*
	 * Mode used to allocate bits between channels.
	 * @values
	 * 0 (Native mode)
	 * #ASM_MEDIA_FMT_SBC_CHANNEL_MODE_MONO
	 * #ASM_MEDIA_FMT_SBC_CHANNEL_MODE_STEREO
	 * #ASM_MEDIA_FMT_SBC_CHANNEL_MODE_DUAL_MONO
	 * #ASM_MEDIA_FMT_SBC_CHANNEL_MODE_JOINT_STEREO
	 * Native mode indicates that encoding must be performed with the number
	 * of channels at the input.
	 * If postprocessing outputs one-channel data, Mono mode is used. If
	 * postprocessing outputs two-channel data, Stereo mode is used.
	 * The number of channels must not change during encoding.
	 */
	uint32_t    channel_mode;

	/*
	 * Encoder bit allocation method.
	 * @values
	 * #ASM_MEDIA_FMT_SBC_ALLOCATION_METHOD_LOUDNESS
	 * #ASM_MEDIA_FMT_SBC_ALLOCATION_METHOD_SNR @tablebulletend
	 */
	uint32_t    alloc_method;

	/*
	 * Number of encoded bits per second.
	 * @values
	 * Mono channel -- Maximum of 320 kbps
	 * Stereo channel -- Maximum of 512 kbps @tablebulletend
	 */
	uint32_t    bit_rate;

	/*
	 * Number of samples per second.
	 * @values 0 (Native mode), 16000, 32000, 44100, 48000 Hz
	 * Native mode indicates that encoding must be performed with the
	 * sampling rate at the input.
	 * The sampling rate must not change during encoding.
	 */
	uint32_t    sample_rate;
};

#define ASM_MEDIA_FMT_AAC_AOT_LC            2
#define ASM_MEDIA_FMT_AAC_AOT_SBR           5
#define ASM_MEDIA_FMT_AAC_AOT_PS            29
#define ASM_MEDIA_FMT_AAC_FORMAT_FLAG_ADTS  0
#define ASM_MEDIA_FMT_AAC_FORMAT_FLAG_RAW   3

struct asm_aac_enc_cfg_v2_t {

	/* Encoding rate in bits per second.*/
	uint32_t     bit_rate;

	/*
	 * Encoding mode.
	 * Supported values:
	 * #ASM_MEDIA_FMT_AAC_AOT_LC
	 * #ASM_MEDIA_FMT_AAC_AOT_SBR
	 * #ASM_MEDIA_FMT_AAC_AOT_PS
	 */
	uint32_t     enc_mode;

	/*
	 * AAC format flag.
	 * Supported values:
	 * #ASM_MEDIA_FMT_AAC_FORMAT_FLAG_ADTS
	 * #ASM_MEDIA_FMT_AAC_FORMAT_FLAG_RAW
	 */
	uint16_t     aac_fmt_flag;

	/*
	 * Number of channels to encode.
	 * Supported values:
	 * 0 - Native mode
	 * 1 - Mono
	 * 2 - Stereo
	 * Other values are not supported.
	 * @note1hang The eAAC+ encoder mode supports only stereo.
	 * Native mode indicates that encoding must be performed with the
	 * number of channels at the input.
	 * The number of channels must not change during encoding.
	 */
	uint32_t     channel_cfg;

	/*
	 * Number of samples per second.
	 * Supported values: - 0 -- Native mode - For other values,
	 * Native mode indicates that encoding must be performed with the
	 * sampling rate at the input.
	 * The sampling rate must not change during encoding.
	 */
	uint32_t     sample_rate;
} __packed;

/* FMT ID for apt-X Classic */
#define ASM_MEDIA_FMT_APTX 0x000131ff

/* FMT ID for apt-X HD */
#define ASM_MEDIA_FMT_APTX_HD 0x00013200

#define PCM_CHANNEL_L         1
#define PCM_CHANNEL_R         2
#define PCM_CHANNEL_C         3

struct asm_custom_enc_cfg_aptx_t {
	uint32_t    sample_rate;
	/* Mono or stereo */
	uint16_t    num_channels;
	uint16_t    reserved;
	/* num_ch == 1, then PCM_CHANNEL_C,
	 * num_ch == 2, then {PCM_CHANNEL_L, PCM_CHANNEL_R}
	 */
	uint8_t     channel_mapping[8];
	uint32_t    custom_size;
} __packed;

struct afe_enc_fmt_id_param_t {
	/*
	 * Supported values:
	 *  #ASM_MEDIA_FMT_SBC
	 *  #ASM_MEDIA_FMT_AAC_V2
	 * Any OpenDSP supported values
	 */
	uint32_t    fmt_id;
} __packed;

struct afe_port_media_type_t {
	/*
	 * Minor version
	 * @values #AFE_API_VERSION_PORT_MEDIA_TYPE.
	 */
	uint32_t    minor_version;

	/*
	 * Sampling rate of the port.
	 * @values
	 * #AFE_PORT_SAMPLE_RATE_8K
	 * #AFE_PORT_SAMPLE_RATE_11_025K
	 * #AFE_PORT_SAMPLE_RATE_12K
	 * #AFE_PORT_SAMPLE_RATE_16K
	 * #AFE_PORT_SAMPLE_RATE_22_05K
	 * #AFE_PORT_SAMPLE_RATE_24K
	 * #AFE_PORT_SAMPLE_RATE_32K
	 * #AFE_PORT_SAMPLE_RATE_44_1K
	 * #AFE_PORT_SAMPLE_RATE_48K
	 * #AFE_PORT_SAMPLE_RATE_88_2K
	 * #AFE_PORT_SAMPLE_RATE_96K
	 * #AFE_PORT_SAMPLE_RATE_176_4K
	 * #AFE_PORT_SAMPLE_RATE_192K
	 * #AFE_PORT_SAMPLE_RATE_352_8K
	 * #AFE_PORT_SAMPLE_RATE_384K
	 */
	uint32_t    sample_rate;

	/*
	 * Bit width of the sample.
	 * @values 16, 24
	 */
	uint16_t    bit_width;

	/*
	 * Number of channels.
	 * @values 1 to #AFE_PORT_MAX_AUDIO_CHAN_CNT
	 */
	uint16_t    num_channels;

	/*
	 * Data format supported by this port.
	 * If the port media type and device media type are different,
	 * it signifies a encoding/decoding use case
	 * @values
	 * #AFE_PORT_DATA_FORMAT_PCM
	 * #AFE_PORT_DATA_FORMAT_GENERIC_COMPRESSED
	 */
	uint16_t   data_format;

	/*This field must be set to zero.*/
	uint16_t   reserved;
} __packed;

union afe_enc_config_data {
	struct asm_sbc_enc_cfg_t sbc_config;
	struct asm_aac_enc_cfg_v2_t aac_config;
	struct asm_custom_enc_cfg_aptx_t  aptx_config;
};

struct afe_enc_config {
	u32 format;
	union afe_enc_config_data data;
};

struct afe_enc_cfg_blk_param_t {
	uint32_t enc_cfg_blk_size;
	/*
	 *Size of the encoder configuration block that follows this member
	 */
	union afe_enc_config_data enc_blk_config;
};

/*
 * Payload of the AVS_ENCODER_PARAM_ID_PACKETIZER_ID parameter.
 */
struct avs_enc_packetizer_id_param_t {
	/*
	 * Supported values:
	 * #AVS_MODULE_ID_PACKETIZER_COP
	 * Any OpenDSP supported values
	 */
	uint32_t enc_packetizer_id;
};

union afe_port_config {
	struct afe_param_id_pcm_cfg               pcm;
	struct afe_param_id_i2s_cfg               i2s;
@@ -2751,6 +3078,10 @@ union afe_port_config {
	struct afe_param_id_set_topology_cfg      topology;
	struct afe_param_id_tdm_cfg               tdm;
	struct afe_param_id_usb_audio_cfg         usb_audio;
	struct afe_enc_fmt_id_param_t             enc_fmt;
	struct afe_port_media_type_t              media_type;
	struct afe_enc_cfg_blk_param_t            enc_blk_param;
	struct avs_enc_packetizer_id_param_t      enc_pkt_id_param;
} __packed;

struct afe_audioif_config_command_no_payload {
+3 −0
Original line number Diff line number Diff line
@@ -274,6 +274,9 @@ int afe_rt_proxy_port_read(phys_addr_t buf_addr_p,
void afe_set_cal_mode(u16 port_id, enum afe_cal_mode afe_cal_mode);
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,
		      struct afe_enc_config *enc_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);
+180 −3
Original line number Diff line number Diff line
@@ -37,6 +37,14 @@
#define CHANNEL_STATUS_MASK 0x4
#define AFE_API_VERSION_CLOCK_SET 1

enum {
	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,
	ENC_FMT_APTX_HD = ASM_MEDIA_FMT_APTX_HD,
};

static const struct afe_clk_set lpass_clk_set_default = {
	AFE_API_VERSION_CLOCK_SET,
	Q6AFE_LPASS_CLK_ID_PRI_PCM_IBIT,
@@ -157,6 +165,8 @@ struct msm_dai_q6_dai_data {
	u32 channels;
	u32 bitwidth;
	u32 cal_mode;
	u32 afe_in_channels;
	struct afe_enc_config enc_config;
	union afe_port_config port_config;
};

@@ -1330,9 +1340,20 @@ static int msm_dai_q6_prepare(struct snd_pcm_substream *substream,
	int rc = 0;

	if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
		if (dai_data->enc_config.format != ENC_FMT_NONE) {
			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,
					       &dai_data->enc_config);
			if (rc < 0)
				pr_err("%s: afe_port_start_v2 failed error: %d\n",
					__func__, rc);
		} else {
			rc = afe_port_start(dai->id, &dai_data->port_config,
						dai_data->rate);

		}
		if (IS_ERR_VALUE(rc))
			dev_err(dai->dev, "fail to open AFE port 0x%x\n",
				dai->id);
@@ -1941,6 +1962,151 @@ static int msm_dai_q6_usb_audio_cfg_get(struct snd_kcontrol *kcontrol,
	return 0;
}

static int  msm_dai_q6_afe_enc_cfg_info(struct snd_kcontrol *kcontrol,
					struct snd_ctl_elem_info *uinfo)
{
	uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
	uinfo->count = sizeof(struct afe_enc_config);

	return 0;
}

static int msm_dai_q6_afe_enc_cfg_get(struct snd_kcontrol *kcontrol,
				      struct snd_ctl_elem_value *ucontrol)
{
	int ret = 0;
	struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data;

	if (dai_data) {
		int format_size = sizeof(dai_data->enc_config.format);

		pr_debug("%s:encoder config for %d format\n",
			 __func__, dai_data->enc_config.format);
		memcpy(ucontrol->value.bytes.data,
			&dai_data->enc_config.format,
			format_size);
		switch (dai_data->enc_config.format) {
		case ENC_FMT_SBC:
			memcpy(ucontrol->value.bytes.data + format_size,
				&dai_data->enc_config.data,
				sizeof(struct asm_sbc_enc_cfg_t));
			break;
		case ENC_FMT_AAC_V2:
			memcpy(ucontrol->value.bytes.data + format_size,
				&dai_data->enc_config.data,
				sizeof(struct asm_aac_enc_cfg_v2_t));
			break;
		case ENC_FMT_APTX:
		case ENC_FMT_APTX_HD:
			memcpy(ucontrol->value.bytes.data + format_size,
				&dai_data->enc_config.data,
				sizeof(struct asm_aac_enc_cfg_v2_t));
			break;
		default:
			pr_debug("%s: unknown format = %d\n",
				 __func__, dai_data->enc_config.format);
			ret = -EINVAL;
			break;
		}
	}

	return ret;
}

static int msm_dai_q6_afe_enc_cfg_put(struct snd_kcontrol *kcontrol,
				      struct snd_ctl_elem_value *ucontrol)
{
	int ret = 0;
	struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data;

	if (dai_data) {
		int format_size = sizeof(dai_data->enc_config.format);

		memset(&dai_data->enc_config, 0x0,
			sizeof(struct afe_enc_config));
		memcpy(&dai_data->enc_config.format,
			ucontrol->value.bytes.data,
			format_size);
		pr_debug("%s: Received encoder config for %d format\n",
			 __func__, dai_data->enc_config.format);
		switch (dai_data->enc_config.format) {
		case ENC_FMT_SBC:
			memcpy(&dai_data->enc_config.data,
				ucontrol->value.bytes.data + format_size,
				sizeof(struct asm_sbc_enc_cfg_t));
			break;
		case ENC_FMT_AAC_V2:
			memcpy(&dai_data->enc_config.data,
				ucontrol->value.bytes.data + format_size,
				sizeof(struct asm_aac_enc_cfg_v2_t));
			break;
		case ENC_FMT_APTX:
		case ENC_FMT_APTX_HD:
			memcpy(&dai_data->enc_config.data,
				ucontrol->value.bytes.data + format_size,
				sizeof(struct asm_custom_enc_cfg_aptx_t));
			break;
		default:
			pr_debug("%s: Ignore enc config for unknown format = %d\n",
				 __func__, dai_data->enc_config.format);
			ret = -EINVAL;
			break;
		}
	} else
		ret = -EINVAL;

	return ret;
}

static const char *const afe_input_chs_text[] = {"Zero", "One", "Two"};

static const struct soc_enum afe_input_chs_enum[] = {
	SOC_ENUM_SINGLE_EXT(3, afe_input_chs_text),
};

static int msm_dai_q6_afe_input_channel_get(struct snd_kcontrol *kcontrol,
			struct snd_ctl_elem_value *ucontrol)
{
	struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data;

	if (dai_data) {
		ucontrol->value.integer.value[0] = dai_data->afe_in_channels;
		pr_debug("%s:afe input channel = %d\n",
			  __func__, dai_data->afe_in_channels);
	}

	return 0;
}

static int msm_dai_q6_afe_input_channel_put(struct snd_kcontrol *kcontrol,
			struct snd_ctl_elem_value *ucontrol)
{
	struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data;

	if (dai_data) {
		dai_data->afe_in_channels = ucontrol->value.integer.value[0];
		pr_debug("%s: updating afe input channel : %d\n",
			__func__, dai_data->afe_in_channels);
	}

	return 0;
}

static const struct snd_kcontrol_new afe_enc_config_controls[] = {
	{
		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
			   SNDRV_CTL_ELEM_ACCESS_INACTIVE),
		.iface = SNDRV_CTL_ELEM_IFACE_PCM,
		.name = "SLIM_7_RX Encoder Config",
		.info = msm_dai_q6_afe_enc_cfg_info,
		.get = msm_dai_q6_afe_enc_cfg_get,
		.put = msm_dai_q6_afe_enc_cfg_put,
	},
	SOC_ENUM_EXT("AFE Input Channels", afe_input_chs_enum[0],
		     msm_dai_q6_afe_input_channel_get,
		     msm_dai_q6_afe_input_channel_put),
};

static const char * const afe_cal_mode_text[] = {
	"CAL_MODE_DEFAULT", "CAL_MODE_NONE"
};
@@ -2020,6 +2186,17 @@ static int msm_dai_q6_dai_probe(struct snd_soc_dai *dai)
				 snd_ctl_new1(&sb_config_controls[1],
				 dai_data));
		break;
	case SLIMBUS_7_RX:
		rc = snd_ctl_add(dai->component->card->snd_card,
				 snd_ctl_new1(&afe_enc_config_controls[0],
				 dai_data));
		rc = snd_ctl_add(dai->component->card->snd_card,
				 snd_ctl_new1(&afe_enc_config_controls[1],
				 dai_data));
		rc = snd_ctl_add(dai->component->card->snd_card,
				 snd_ctl_new1(&afe_enc_config_controls[2],
				 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],
+166 −3
Original line number Diff line number Diff line
@@ -2632,8 +2632,113 @@ exit:
	return ret;
}

int afe_port_start(u16 port_id, union afe_port_config *afe_config,
	u32 rate) /* This function is no blocking */
static int q6afe_send_enc_config(u16 port_id,
			union afe_enc_config_data *cfg, u32 format,
			union afe_port_config afe_config, u16 afe_in_channels)
{
	struct afe_audioif_config_command config;
	int index;
	int ret;
	int payload_size = sizeof(config) - sizeof(struct apr_hdr) -
				sizeof(config.param) - sizeof(config.port);

	pr_debug("%s:update DSP for enc format = %d\n", __func__, format);
	if (format != ASM_MEDIA_FMT_SBC && format != ASM_MEDIA_FMT_AAC_V2 &&
	    format != ASM_MEDIA_FMT_APTX && format != ASM_MEDIA_FMT_APTX_HD) {
		pr_err("%s:Unsuppported format Ignore AFE config\n", __func__);
		return 0;
	}
	memset(&config, 0, sizeof(config));
	index = q6audio_get_port_index(port_id);
	config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
				APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
	config.hdr.pkt_size = sizeof(config);
	config.hdr.src_port = 0;
	config.hdr.dest_port = 0;
	config.hdr.token = index;

	config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
	config.param.port_id = q6audio_get_port_id(port_id);
	config.param.payload_size = payload_size + sizeof(config.port.enc_fmt);
	config.param.payload_address_lsw = 0x00;
	config.param.payload_address_msw = 0x00;
	config.param.mem_map_handle = 0x00;
	config.pdata.module_id = AFE_MODULE_ID_ENCODER;
	config.pdata.param_id = AFE_ENCODER_PARAM_ID_ENC_FMT_ID;
	config.pdata.param_size = sizeof(config.port.enc_fmt);
	config.port.enc_fmt.fmt_id = format;
	pr_debug("%s:sending AFE_ENCODER_PARAM_ID_ENC_FMT_ID payload: %d\n",
			__func__, config.param.payload_size);
	ret = afe_apr_send_pkt(&config, &this_afe.wait[index]);
	if (ret) {
		pr_err("%s:unable to send AFE_ENCODER_PARAM_ID_ENC_FMT_ID",
				__func__);
		goto exit;
	}

	config.param.payload_size = payload_size
					+ sizeof(config.port.enc_blk_param);
	pr_debug("%s:send AFE_ENCODER_PARAM_ID_ENC_CFG_BLK to DSP payload:%d\n",
				__func__, config.param.payload_size);
	config.pdata.param_id = AFE_ENCODER_PARAM_ID_ENC_CFG_BLK;
	config.pdata.param_size = sizeof(config.port.enc_blk_param);
	config.port.enc_blk_param.enc_cfg_blk_size =
			sizeof(config.port.enc_blk_param.enc_blk_config);
	config.port.enc_blk_param.enc_blk_config = *cfg;
	ret = afe_apr_send_pkt(&config, &this_afe.wait[index]);
	if (ret) {
		pr_err("%s: AFE_ENCODER_PARAM_ID_ENC_CFG_BLK for port 0x%x failed %d\n",
			__func__, port_id, ret);
		goto exit;
	}

	config.param.payload_size =
			payload_size + sizeof(config.port.enc_pkt_id_param);
	pr_debug("%s:sending AFE_ENCODER_PARAM_ID_PACKETIZER to DSP payload = %d",
					__func__, config.param.payload_size);
	config.pdata.param_id = AFE_ENCODER_PARAM_ID_PACKETIZER_ID;
	config.pdata.param_size = sizeof(config.port.enc_pkt_id_param);
	config.port.enc_pkt_id_param.enc_packetizer_id =
					AFE_MODULE_ID_PACKETIZER_COP;
	ret = afe_apr_send_pkt(&config, &this_afe.wait[index]);
	if (ret) {
		pr_err("%s: AFE_ENCODER_PARAM_ID_PACKETIZER for port 0x%x failed %d\n",
			__func__, port_id, ret);
		goto exit;
	}

	config.param.payload_size =
			payload_size + sizeof(config.port.media_type);
	config.pdata.param_size = sizeof(config.port.media_type);

	pr_debug("%s:Sending AFE_API_VERSION_PORT_MEDIA_TYPE to DSP", __func__);
	config.pdata.module_id = AFE_MODULE_PORT;
	config.pdata.param_id = AFE_PARAM_ID_PORT_MEDIA_TYPE;
	config.port.media_type.minor_version = AFE_API_VERSION_PORT_MEDIA_TYPE;
	config.port.media_type.sample_rate = afe_config.slim_sch.sample_rate;
	config.port.media_type.bit_width = afe_config.slim_sch.bit_width;
	if (afe_in_channels != 0)
		config.port.media_type.num_channels = afe_in_channels;
	else
		config.port.media_type.num_channels =
					afe_config.slim_sch.num_channels;
	config.port.media_type.data_format = AFE_PORT_DATA_FORMAT_PCM;
	config.port.media_type.reserved = 0;

	ret = afe_apr_send_pkt(&config, &this_afe.wait[index]);
	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 __afe_port_start(u16 port_id, union afe_port_config *afe_config,
			   u32 rate,  u16 afe_in_channels,
			   union afe_enc_config_data *cfg, u32 enc_format)
{
	struct afe_audioif_config_command config;
	int ret = 0;
@@ -2850,7 +2955,11 @@ int afe_port_start(u16 port_id, union afe_port_config *afe_config,
	config.pdata.param_size = sizeof(config.port);

	config.port = *afe_config;

	if ((enc_format != ASM_MEDIA_FMT_NONE) &&
	    (cfg_type == AFE_PARAM_ID_SLIMBUS_CONFIG)) {
		config.port.slim_sch.data_format =
				AFE_SB_DATA_FORMAT_GENERIC_COMPRESSED;
	}
	ret = afe_apr_send_pkt(&config, &this_afe.wait[index]);
	if (ret) {
		pr_err("%s: AFE enable for port 0x%x failed %d\n",
@@ -2858,6 +2967,19 @@ int afe_port_start(u16 port_id, union afe_port_config *afe_config,
		goto fail_cmd;
	}

	if ((enc_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 (ret) {
			pr_err("%s: AFE encoder 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)) {
		this_afe.afe_sample_rates[port_index] = rate;
@@ -2890,6 +3012,47 @@ fail_cmd:
	return ret;
}

/**
 * afe_port_start - to configure AFE session with
 * specified port configuration
 *
 * @port_id: AFE port id number
 * @afe_config: port configutation
 * @rate: sampling rate of port
 *
 * Returns 0 on success or error value on port start failure.
 */
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, NULL, ASM_MEDIA_FMT_NONE);
}
EXPORT_SYMBOL(afe_port_start);

/**
 * afe_port_start_v2 - to configure AFE session with
 * specified port configuration and encoder params
 *
 * @port_id: AFE port id number
 * @afe_config: port configutation
 * @rate: sampling rate of port
 * @cfg: AFE encoder configuration information to setup encoder
 * @afe_in_channels: AFE input channel configuration, this needs
 *  update only if input channel is differ from AFE output
 *
 * 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,
		      struct afe_enc_config *enc_cfg)
{
	return __afe_port_start(port_id, afe_config, rate,
				afe_in_channels, &enc_cfg->data,
				enc_cfg->format);
}
EXPORT_SYMBOL(afe_port_start_v2);

int afe_get_port_index(u16 port_id)
{
	switch (port_id) {