diff --git a/asoc/msm-compress-q6-v2.c b/asoc/msm-compress-q6-v2.c
index c4fecdefa2b3..c0d8614559f1 100644
--- a/asoc/msm-compress-q6-v2.c
+++ b/asoc/msm-compress-q6-v2.c
@@ -1432,6 +1432,7 @@ static int msm_compr_configure_dsp_for_capture(struct snd_compr_stream *cstream)
 	int dir = OUT, ret = 0;
 	struct audio_client *ac = prtd->audio_client;
 	uint32_t stream_index;
+	uint32_t enc_cfg_id = ENC_CFG_ID_NONE;
 
 	switch (prtd->codec_param.codec.format) {
 	case SNDRV_PCM_FORMAT_S24_LE:
@@ -1450,6 +1451,9 @@ static int msm_compr_configure_dsp_for_capture(struct snd_compr_stream *cstream)
 	default:
 		bits_per_sample = 16;
 		sample_word_size = 16;
+		if (prtd->codec == FORMAT_BESPOKE)
+			enc_cfg_id =
+			prtd->codec_param.codec.options.generic.reserved[0];
 		break;
 	}
 
@@ -1457,11 +1461,11 @@ static int msm_compr_configure_dsp_for_capture(struct snd_compr_stream *cstream)
 			__func__, ac->stream_id, bits_per_sample);
 
 	if (prtd->codec_param.codec.flags & COMPRESSED_TIMESTAMP_FLAG) {
-		ret = q6asm_open_read_v4(prtd->audio_client, FORMAT_LINEAR_PCM,
-			bits_per_sample, true);
+		ret = q6asm_open_read_v4(prtd->audio_client, prtd->codec,
+			bits_per_sample, true, enc_cfg_id);
 	} else {
-		ret = q6asm_open_read_v4(prtd->audio_client, FORMAT_LINEAR_PCM,
-			bits_per_sample, false);
+		ret = q6asm_open_read_v4(prtd->audio_client, prtd->codec,
+			bits_per_sample, false, enc_cfg_id);
 	}
 	if (ret < 0) {
 		pr_err("%s: q6asm_open_read failed:%d\n", __func__, ret);
@@ -1521,10 +1525,20 @@ static int msm_compr_configure_dsp_for_capture(struct snd_compr_stream *cstream)
 	pr_debug("%s: sample_rate = %d channels = %d bps = %d sample_word_size = %d\n",
 			__func__, prtd->sample_rate, prtd->num_channels,
 					 bits_per_sample, sample_word_size);
-	ret = q6asm_enc_cfg_blk_pcm_format_support_v4(prtd->audio_client,
+	if (prtd->codec == FORMAT_BESPOKE) {
+		/*
+		 * For BESPOKE codec, encoder specific config params are
+		 * included as part of generic.
+		 */
+		ret = q6asm_enc_cfg_blk_custom(prtd->audio_client, prtd->sample_rate,
+			prtd->num_channels, prtd->codec,
+			(void *)&prtd->codec_param.codec.options.generic);
+	} else {
+		ret = q6asm_enc_cfg_blk_pcm_format_support_v4(prtd->audio_client,
 					prtd->sample_rate, prtd->num_channels,
 					bits_per_sample, sample_word_size,
 					ASM_LITTLE_ENDIAN, DEFAULT_QF);
+	}
 
 	return ret;
 }
@@ -2043,6 +2057,12 @@ static int msm_compr_set_params(struct snd_compr_stream *cstream,
 		break;
 	}
 
+	case SND_AUDIOCODEC_BESPOKE: {
+		pr_debug("%s: SND_AUDIOCODEC_BESPOKE\n", __func__);
+		prtd->codec = FORMAT_BESPOKE;
+		break;
+	}
+
 	default:
 		pr_err("codec not supported, id =%d\n", params->codec.id);
 		return -EINVAL;
diff --git a/asoc/msm-pcm-q6-v2.c b/asoc/msm-pcm-q6-v2.c
index b82128e7fabe..8ae85b743686 100644
--- a/asoc/msm-pcm-q6-v2.c
+++ b/asoc/msm-pcm-q6-v2.c
@@ -490,7 +490,7 @@ static int msm_pcm_capture_prepare(struct snd_pcm_substream *substream)
 				prtd->audio_client->perf_mode);
 
 		ret = q6asm_open_read_v4(prtd->audio_client, FORMAT_LINEAR_PCM,
-				bits_per_sample, false);
+				bits_per_sample, false, ENC_CFG_ID_NONE);
 		if (ret < 0) {
 			pr_err("%s: q6asm_open_read failed\n", __func__);
 			q6asm_audio_client_free(prtd->audio_client);
diff --git a/dsp/q6asm.c b/dsp/q6asm.c
index a12347966f5a..38ddc88b0f24 100644
--- a/dsp/q6asm.c
+++ b/dsp/q6asm.c
@@ -46,6 +46,8 @@
 #define FALSE       0x00
 #define SESSION_MAX 8
 
+#define ENC_FRAMES_PER_BUFFER 0x01
+
 enum {
 	ASM_TOPOLOGY_CAL = 0,
 	ASM_CUSTOM_TOP_CAL,
@@ -2812,7 +2814,7 @@ EXPORT_SYMBOL(q6asm_set_soft_volume_module_instance_ids);
 static int __q6asm_open_read(struct audio_client *ac,
 			     uint32_t format, uint16_t bits_per_sample,
 			     uint32_t pcm_format_block_ver,
-			     bool ts_mode)
+			     bool ts_mode, uint32_t enc_cfg_id)
 {
 	int rc = 0x00;
 	struct asm_stream_cmd_open_read_v3 open;
@@ -2888,6 +2890,12 @@ static int __q6asm_open_read(struct audio_client *ac,
 		open.mode_flags |= BUFFER_META_ENABLE;
 		open.enc_cfg_id = ASM_MEDIA_FMT_AMRWB_FS;
 		break;
+	case FORMAT_BESPOKE:
+		open.mode_flags |= BUFFER_META_ENABLE;
+		open.enc_cfg_id = enc_cfg_id;
+		if (ts_mode)
+			open.mode_flags |= ABSOLUTE_TIMESTAMP_ENABLE;
+		break;
 	default:
 		pr_err("%s: Invalid format 0x%x\n",
 			__func__, format);
@@ -2939,7 +2947,7 @@ int q6asm_open_read(struct audio_client *ac,
 {
 	return __q6asm_open_read(ac, format, 16,
 				PCM_MEDIA_FORMAT_V2 /*media fmt block ver*/,
-				false/*ts_mode*/);
+				false/*ts_mode*/, ENC_CFG_ID_NONE);
 }
 EXPORT_SYMBOL(q6asm_open_read);
 
@@ -2948,7 +2956,7 @@ int q6asm_open_read_v2(struct audio_client *ac, uint32_t format,
 {
 	return __q6asm_open_read(ac, format, bits_per_sample,
 				 PCM_MEDIA_FORMAT_V2 /*media fmt block ver*/,
-				 false/*ts_mode*/);
+				 false/*ts_mode*/, ENC_CFG_ID_NONE);
 }
 
 /*
@@ -2963,7 +2971,7 @@ int q6asm_open_read_v3(struct audio_client *ac, uint32_t format,
 {
 	return __q6asm_open_read(ac, format, bits_per_sample,
 				 PCM_MEDIA_FORMAT_V3/*media fmt block ver*/,
-				 false/*ts_mode*/);
+				 false/*ts_mode*/, ENC_CFG_ID_NONE);
 }
 EXPORT_SYMBOL(q6asm_open_read_v3);
 
@@ -2976,11 +2984,12 @@ EXPORT_SYMBOL(q6asm_open_read_v3);
  * @ts_mode: timestamp mode
  */
 int q6asm_open_read_v4(struct audio_client *ac, uint32_t format,
-			uint16_t bits_per_sample, bool ts_mode)
+			uint16_t bits_per_sample, bool ts_mode,
+			uint32_t enc_cfg_id)
 {
 	return __q6asm_open_read(ac, format, bits_per_sample,
 				 PCM_MEDIA_FORMAT_V4 /*media fmt block ver*/,
-				 ts_mode);
+				 ts_mode, enc_cfg_id);
 }
 EXPORT_SYMBOL(q6asm_open_read_v4);
 
@@ -4287,6 +4296,95 @@ int q6asm_stream_run_nowait(struct audio_client *ac, uint32_t flags,
 	return __q6asm_run_nowait(ac, flags, msw_ts, lsw_ts, stream_id);
 }
 
+/**
+ * q6asm_enc_cfg_blk_custom -
+ *       command to set encode cfg block for custom
+ *
+ * @ac: Audio client handle
+ * @sample_rate: Sample rate
+ * @channels: number of ASM channels
+ * @format: custom format flag
+ * @cfg: generic encoder config
+ *
+ * Returns 0 on success or error on failure
+ */
+int q6asm_enc_cfg_blk_custom(struct audio_client *ac,
+			uint32_t sample_rate, uint32_t channels,
+			uint32_t format, void *cfg)
+{
+	struct asm_custom_enc_cfg_t_v2 enc_cfg;
+	int rc = 0;
+	uint32_t custom_size;
+	struct snd_enc_generic *enc_generic = (struct snd_enc_generic *) cfg;
+
+	custom_size = enc_generic->reserved[1];
+
+	pr_debug("%s: session[%d] size[%d] res[2]=[%d] res[3]=[%d]\n",
+		 __func__, ac->session, custom_size, enc_generic->reserved[2],
+		 enc_generic->reserved[3]);
+
+	pr_debug("%s: res[4]=[%d] sr[%d] ch[%d] format[%d]\n",
+		 __func__, enc_generic->reserved[4], sample_rate,
+		 channels, format);
+
+	memset(&enc_cfg, 0, sizeof(struct asm_custom_enc_cfg_t_v2));
+	q6asm_add_hdr(ac, &enc_cfg.hdr, sizeof(enc_cfg), TRUE);
+	atomic_set(&ac->cmd_state, -1);
+
+	enc_cfg.hdr.opcode = ASM_STREAM_CMD_SET_ENCDEC_PARAM;
+	enc_cfg.encdec.param_id = ASM_PARAM_ID_ENCDEC_ENC_CFG_BLK_V2;
+	enc_cfg.encdec.param_size = sizeof(struct asm_custom_enc_cfg_t_v2) -
+				sizeof(struct asm_stream_cmd_set_encdec_param);
+	enc_cfg.encblk.frames_per_buf = ENC_FRAMES_PER_BUFFER;
+	enc_cfg.encblk.enc_cfg_blk_size  = enc_cfg.encdec.param_size -
+				sizeof(struct asm_enc_cfg_blk_param_v2);
+
+	enc_cfg.num_channels = channels;
+	enc_cfg.sample_rate = sample_rate;
+
+	if (q6asm_map_channels(enc_cfg.channel_mapping, channels, false)) {
+		pr_err("%s: map channels failed %d\n",
+		       __func__, channels);
+		rc = -EINVAL;
+		goto fail_cmd;
+	}
+
+	if (format == FORMAT_BESPOKE && custom_size &&
+		custom_size <= sizeof(enc_cfg.custom_data)) {
+		memcpy(enc_cfg.custom_data, &enc_generic->reserved[2],
+			   custom_size);
+		enc_cfg.custom_size = custom_size;
+	}
+
+	rc = apr_send_pkt(ac->apr, (uint32_t *) &enc_cfg);
+	if (rc < 0) {
+		pr_err("%s: Comamnd %d failed %d\n",
+		       __func__, ASM_STREAM_CMD_SET_ENCDEC_PARAM, rc);
+		rc = -EINVAL;
+		goto fail_cmd;
+	}
+	rc = wait_event_timeout(ac->cmd_wait,
+			(atomic_read(&ac->cmd_state) >= 0), 5*HZ);
+	if (!rc) {
+		pr_err("%s: timeout. waited for FORMAT_UPDATE\n",
+			__func__);
+		rc = -ETIMEDOUT;
+		goto fail_cmd;
+	}
+	if (atomic_read(&ac->cmd_state) > 0) {
+		pr_err("%s: DSP returned error[%s]\n",
+					__func__, adsp_err_get_err_str(
+					atomic_read(&ac->cmd_state)));
+		rc = adsp_err_get_lnx_err_code(
+				atomic_read(&ac->cmd_state));
+		goto fail_cmd;
+	}
+	return 0;
+fail_cmd:
+	return rc;
+}
+EXPORT_SYMBOL(q6asm_enc_cfg_blk_custom);
+
 /**
  * q6asm_enc_cfg_blk_aac -
  *       command to set encode cfg block for aac
diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h
index a282f78b33d6..5f62a2711d6e 100644
--- a/include/dsp/apr_audio-v2.h
+++ b/include/dsp/apr_audio-v2.h
@@ -4743,6 +4743,22 @@ struct asm_enc_cfg_blk_param_v2 {
 
 } __packed;
 
+struct asm_custom_enc_cfg_t_v2 {
+	struct apr_hdr hdr;
+	struct asm_stream_cmd_set_encdec_param encdec;
+	struct asm_enc_cfg_blk_param_v2 encblk;
+	uint32_t sample_rate;
+
+	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;
+	uint8_t  custom_data[15];
+} __packed;
+
 /* @brief Dolby Digital Plus end point configuration structure
  */
 struct asm_dec_ddp_endp_param_v2 {
diff --git a/include/dsp/q6asm-v2.h b/include/dsp/q6asm-v2.h
index ba35779a5788..e6f021db7e88 100644
--- a/include/dsp/q6asm-v2.h
+++ b/include/dsp/q6asm-v2.h
@@ -57,11 +57,14 @@
 #define FORMAT_GEN_COMPR    0x001f
 #define FORMAT_TRUEHD       0x0020
 #define FORMAT_IEC61937     0x0021
+#define FORMAT_BESPOKE      0x0022
 
 #define ENCDEC_SBCBITRATE   0x0001
 #define ENCDEC_IMMEDIATE_DECODE 0x0002
 #define ENCDEC_CFG_BLK          0x0003
 
+#define ENC_CFG_ID_NONE    0x0000
+
 #define CMD_PAUSE          0x0001
 #define CMD_FLUSH          0x0002
 #define CMD_EOS            0x0003
@@ -290,7 +293,8 @@ int q6asm_open_read_v3(struct audio_client *ac, uint32_t format,
 		       uint16_t bits_per_sample);
 
 int q6asm_open_read_v4(struct audio_client *ac, uint32_t format,
-		       uint16_t bits_per_sample, bool ts_mode);
+		       uint16_t bits_per_sample, bool ts_mode,
+			   uint32_t enc_cfg_id);
 
 int q6asm_open_write(struct audio_client *ac, uint32_t format
 		/*, uint16_t bits_per_sample*/);
@@ -454,6 +458,10 @@ int q6asm_enc_cfg_blk_pcm_format_support_v4(struct audio_client *ac,
 					    uint16_t endianness,
 					    uint16_t mode);
 
+int q6asm_enc_cfg_blk_custom(struct audio_client *ac,
+			uint32_t sample_rate, uint32_t channels,
+			uint32_t format, void *cfg);
+
 int q6asm_set_encdec_chan_map(struct audio_client *ac,
 		uint32_t num_channels);