diff --git a/asoc/msm-pcm-loopback-v2.c b/asoc/msm-pcm-loopback-v2.c index d3dca8db6002..6094a8fca863 100644 --- a/asoc/msm-pcm-loopback-v2.c +++ b/asoc/msm-pcm-loopback-v2.c @@ -2,6 +2,9 @@ /* Copyright (c) 2013-2021, The Linux Foundation. All rights reserved. * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ +/* + * Add support for 24 and 32bit format for ASM loopback and playback session. + */ #include #include @@ -302,6 +305,7 @@ static int msm_pcm_open(struct snd_pcm_substream *substream) struct asm_session_mtmx_strtr_param_window_v2_t asm_mtmx_strtr_window; uint32_t param_id; struct msm_pcm_pdata *pdata; + uint16_t format = 0; if (!component) { pr_err("%s: component is NULL\n", __func__); @@ -349,6 +353,23 @@ static int msm_pcm_open(struct snd_pcm_substream *substream) pcm->audio_client->fedai_id = rtd->dai_link->id; pcm->audio_client->perf_mode = pdata->perf_mode; pcm->audio_client->stream_type = substream->stream; + + format = msm_pcm_asm_cfg_get(rtd->dai_link->id, MSM_ASM_LOOPBACK_MODE); + switch (format) { + case SNDRV_PCM_FORMAT_S32_LE: + bits_per_sample = 32; + break; + case SNDRV_PCM_FORMAT_S24_LE: + case SNDRV_PCM_FORMAT_S24_3LE: + bits_per_sample = 24; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + bits_per_sample = 16; + } + pr_debug("%s: fe_id:%d, bits_per_sample:%d\n",__func__, + rtd->dai_link->id,bits_per_sample); + ret = q6asm_open_loopback_with_retry(pcm->audio_client, bits_per_sample); pcm->session_id = pcm->audio_client->session; diff --git a/asoc/msm-pcm-q6-v2.c b/asoc/msm-pcm-q6-v2.c index 037885635cce..1169388d6bfc 100644 --- a/asoc/msm-pcm-q6-v2.c +++ b/asoc/msm-pcm-q6-v2.c @@ -2,6 +2,9 @@ /* Copyright (c) 2012-2021, The Linux Foundation. All rights reserved. * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ +/* +* Add support for 24 and 32bit format for ASM loopback and playback session. +*/ #include @@ -557,6 +560,11 @@ static int msm_pcm_playback_prepare(struct snd_pcm_substream *substream) uint32_t fmt_type = FORMAT_LINEAR_PCM; uint16_t bits_per_sample; uint16_t sample_word_size; + uint16_t format_blk_bits_per_sample = 0; + uint16_t format_blk_sample_word_size = 0; + uint16_t format = 0; + uint16_t req_format = 0; + uint16_t input_file_format = 0; if (!component) { pr_err("%s: component is NULL\n", __func__); @@ -598,7 +606,21 @@ static int msm_pcm_playback_prepare(struct snd_pcm_substream *substream) prtd->audio_client->stream_type = SNDRV_PCM_STREAM_PLAYBACK; prtd->audio_client->fedai_id = soc_prtd->dai_link->id; - switch (params_format(params)) { + req_format = msm_pcm_asm_cfg_get(soc_prtd->dai_link->id, MSM_ASM_PLAYBACK_MODE); + input_file_format = params_format(params); + + pr_debug("%s: fe_id:%d, req_format:%d, input_file_format:%d\n",__func__, + soc_prtd->dai_link->id, req_format, input_file_format); + + if(req_format > input_file_format) { + format = req_format; + pr_debug("%s: enforce ASM bitwidth to %d from %d\n",__func__, + format,input_file_format); + }else { + format = input_file_format; + } + + switch (format) { case SNDRV_PCM_FORMAT_S32_LE: bits_per_sample = 32; sample_word_size = 32; @@ -617,6 +639,10 @@ static int msm_pcm_playback_prepare(struct snd_pcm_substream *substream) sample_word_size = 16; break; } + + pr_debug("%s: fe_id:%d, bits_per_sample:%d, sample_word_size:%d\n",__func__, + soc_prtd->dai_link->id, bits_per_sample, sample_word_size); + if (prtd->compress_enable) { fmt_type = FORMAT_GEN_COMPR; pr_debug("%s: Compressed enabled!\n", __func__); @@ -664,11 +690,32 @@ static int msm_pcm_playback_prepare(struct snd_pcm_substream *substream) pr_err("%s: stream reg failed ret:%d\n", __func__, ret); return ret; } + + /*Format block is configure with input file bits_per_sample*/ + switch (input_file_format) { + case SNDRV_PCM_FORMAT_S32_LE: + format_blk_bits_per_sample = 32; + format_blk_sample_word_size = 32; + break; + case SNDRV_PCM_FORMAT_S24_LE: + format_blk_bits_per_sample = 24; + format_blk_sample_word_size = 32; + break; + case SNDRV_PCM_FORMAT_S24_3LE: + format_blk_bits_per_sample = 24; + format_blk_sample_word_size = 24; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + format_blk_bits_per_sample = 16; + format_blk_sample_word_size = 16; + break; + } if (prtd->compress_enable) { ret = q6asm_media_format_block_gen_compr( prtd->audio_client, runtime->rate, runtime->channels, !prtd->set_channel_map, - prtd->channel_map, bits_per_sample); + prtd->channel_map, format_blk_bits_per_sample); } else { if ((q6core_get_avcs_api_version_per_service( @@ -678,15 +725,15 @@ static int msm_pcm_playback_prepare(struct snd_pcm_substream *substream) ret = q6asm_media_format_block_multi_ch_pcm_v5( prtd->audio_client, runtime->rate, runtime->channels, !chmap->set_channel_map, - chmap->channel_map, bits_per_sample, - sample_word_size, ASM_LITTLE_ENDIAN, + chmap->channel_map, format_blk_bits_per_sample, + format_blk_sample_word_size, ASM_LITTLE_ENDIAN, DEFAULT_QF); } else { ret = q6asm_media_format_block_multi_ch_pcm_v4( prtd->audio_client, runtime->rate, runtime->channels, !prtd->set_channel_map, - prtd->channel_map, bits_per_sample, - sample_word_size, ASM_LITTLE_ENDIAN, + prtd->channel_map, format_blk_bits_per_sample, + format_blk_sample_word_size, ASM_LITTLE_ENDIAN, DEFAULT_QF); } } diff --git a/asoc/msm-pcm-routing-auto.c b/asoc/msm-pcm-routing-auto.c index 08fb1fbb47ca..ff1f6274a863 100644 --- a/asoc/msm-pcm-routing-auto.c +++ b/asoc/msm-pcm-routing-auto.c @@ -2,6 +2,9 @@ /* Copyright (c) 2012-2021, The Linux Foundation. All rights reserved. * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ +/* +* Add support for 24 and 32bit format for ASM loopback and playback session. +*/ #include #include @@ -4382,6 +4385,290 @@ static int msm_routing_afe_lb_tx_port_put(struct snd_kcontrol *kcontrol, return 0; } +#define ASM_CFG_PARAM_MAX 4 +static int asm_cfg_params[ASM_CFG_PARAM_MAX]; + +struct msm_asm_config loopback_cfg[] = { + [MSM_FRONTEND_DAI_MULTIMEDIA1] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA2] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA3] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA4] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA5] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA6] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA7] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA8] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA9] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA10] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA11] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA12] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA13] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA14] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA15] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA16] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA17] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA18] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA19] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA20] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA21] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA22] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA23] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA24] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA25] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA26] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA27] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA28] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA29] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA30] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA31] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA32] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA33] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA34] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_VOIP] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_AFE_RX] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_AFE_TX] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_VOICE_STUB] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_DTMF_RX] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_QCHAT] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_VOLTE_STUB] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_LSM1] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_LSM2] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_LSM3] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_LSM4] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_LSM5] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_LSM6] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_LSM7] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_LSM8] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_VOICE2_STUB] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_VOICEMMODE1] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_VOICEMMODE2] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, +}; + +struct msm_asm_config playback_cfg[] = { + [MSM_FRONTEND_DAI_MULTIMEDIA1] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA2] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA3] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA4] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA5] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA6] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA7] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA8] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA9] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA10] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA11] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA12] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA13] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA14] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA15] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA16] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA17] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA18] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA19] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA20] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA21] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA22] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA23] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA24] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA25] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA26] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA27] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA28] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA29] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA30] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA31] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA32] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA33] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA34] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_VOIP] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_AFE_RX] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_AFE_TX] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_VOICE_STUB] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_DTMF_RX] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_QCHAT] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_VOLTE_STUB] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_LSM1] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_LSM2] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_LSM3] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_LSM4] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_LSM5] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_LSM6] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_LSM7] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_LSM8] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_VOICE2_STUB] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_VOICEMMODE1] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_VOICEMMODE2] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, +}; + +struct msm_asm_config capture_cfg[] = { + [MSM_FRONTEND_DAI_MULTIMEDIA1] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA2] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA3] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA4] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA5] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA6] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA7] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA8] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA9] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA10] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA11] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA12] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA13] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA14] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA15] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA16] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA17] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA18] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA19] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA20] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA21] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA22] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA23] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA24] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA25] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA26] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA27] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA28] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA29] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA30] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA31] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA32] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA33] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA34] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_VOIP] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_AFE_RX] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_AFE_TX] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_VOICE_STUB] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_DTMF_RX] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_QCHAT] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_VOLTE_STUB] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_LSM1] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_LSM2] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_LSM3] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_LSM4] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_LSM5] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_LSM6] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_LSM7] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_LSM8] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_VOICE2_STUB] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_VOICEMMODE1] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_VOICEMMODE2] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, +}; + +int msm_pcm_asm_cfg_get(int fe_id, int mode) +{ + int format = 0; + if (mode == MSM_ASM_PLAYBACK_MODE) { + format = playback_cfg[fe_id].bit_format; + } + else if(mode == MSM_ASM_CAPTURE_MODE) { + format = capture_cfg[fe_id].bit_format; + } + else if (mode == MSM_ASM_LOOPBACK_MODE) { + format = loopback_cfg[fe_id].bit_format; + } + return format; +} +EXPORT_SYMBOL(msm_pcm_asm_cfg_get); + +static int msm_pcm_get_format(int value) +{ + int format = 0; + switch (value) { + case 16: + format = SNDRV_PCM_FORMAT_S16_LE; + break; + case 24: + format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 32: + format = SNDRV_PCM_FORMAT_S32_LE; + break; + default: + break; + } + return format; +} + +static int msm_pcm_asm_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret = 0; + int fe_id = 0, mode = 0, format = 0, set = 0; + + mutex_lock(&routing_lock); + asm_cfg_params[0] = ucontrol->value.integer.value[0]; + asm_cfg_params[1] = ucontrol->value.integer.value[1]; + asm_cfg_params[2] = ucontrol->value.integer.value[2]; + set = ucontrol->value.integer.value[3]; + mutex_unlock(&routing_lock); + + if(set) { + fe_id = asm_cfg_params[0]; + mode = asm_cfg_params[1]; + format = msm_pcm_get_format(asm_cfg_params[2]); + + pr_debug("%s: fe_id:%d, mode:%d, format:%d, set:%d\n", + __func__,fe_id,mode,format,set); + + if((fe_id < MSM_FRONTEND_DAI_MULTIMEDIA1) || + (fe_id >= MSM_FRONTEND_DAI_MAX)) { + pr_err("%s: Received invalid fe_id %lu\n", __func__, fe_id); + return -EINVAL; + } + if((mode < MSM_ASM_PLAYBACK_MODE) || + (mode >= MSM_ASM_MAX_MODE)) { + pr_err("%s: Received invalid mode %lu\n", __func__, mode); + return -EINVAL; + } + if((format == SNDRV_PCM_FORMAT_S16_LE) || + (format == SNDRV_PCM_FORMAT_S24_LE) || + (format == SNDRV_PCM_FORMAT_S32_LE)) { + if(mode == MSM_ASM_PLAYBACK_MODE) { + playback_cfg[fe_id].fe_id = fe_id; + playback_cfg[fe_id].mode = mode; + playback_cfg[fe_id].bit_format = format; + } else if(mode == MSM_ASM_CAPTURE_MODE) { + capture_cfg[fe_id].fe_id = fe_id; + capture_cfg[fe_id].mode = mode; + capture_cfg[fe_id].bit_format = format; + } else if(mode == MSM_ASM_LOOPBACK_MODE) { + loopback_cfg[fe_id].fe_id = fe_id; + loopback_cfg[fe_id].mode = mode; + loopback_cfg[fe_id].bit_format = format; + } + }else { + pr_err("%s: Received invalid foramt %lu\n", __func__, + asm_cfg_params[2]); + return -EINVAL; + } + } + return ret; +} + +static int msm_pcm_asm_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + mutex_lock(&routing_lock); + ucontrol->value.integer.value[0] = asm_cfg_params[0]; + ucontrol->value.integer.value[1] = asm_cfg_params[1]; + ucontrol->value.integer.value[2] = asm_cfg_params[2]; + ucontrol->value.integer.value[3] = 0; + mutex_unlock(&routing_lock); + + pr_debug("%s: fe_id:%d, mode:%d, format:%d, set:%d\n",__func__, + ucontrol->value.integer.value[0], + ucontrol->value.integer.value[1], + ucontrol->value.integer.value[2], + ucontrol->value.integer.value[3]); + return 0; +} + +static const struct snd_kcontrol_new msm_asm_format_controls[] = { + SOC_SINGLE_MULTI_EXT("ASM Format", SND_SOC_NOPM, + 0, 0xFFFF, 0, 4, + msm_pcm_asm_format_get, + msm_pcm_asm_format_put), +}; + static const char *const ec_ref_rate_text[] = {"0", "8000", "16000", "24000", "32000", "44100", "48000", "96000", "192000", "384000"}; @@ -33333,6 +33620,9 @@ static int msm_routing_probe(struct snd_soc_component *component) snd_soc_add_component_controls(component, adm_channel_config_controls, ARRAY_SIZE(adm_channel_config_controls)); + snd_soc_add_component_controls(component, msm_asm_format_controls, + ARRAY_SIZE(msm_asm_format_controls)); + snd_soc_add_component_controls(component, aptx_dec_license_controls, ARRAY_SIZE(aptx_dec_license_controls)); snd_soc_add_component_controls( diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 58f53efe6ec9..bb064eac9dbb 100755 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -2,6 +2,9 @@ /* Copyright (c) 2012-2021, The Linux Foundation. All rights reserved. * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ +/* +* Add support for 24 and 32bit format for ASM loopback and playback session. +*/ #include #include @@ -6347,6 +6350,294 @@ static int msm_routing_afe_lb_tx_port_put(struct snd_kcontrol *kcontrol, return 0; } +#define ASM_CFG_PARAM_MAX 4 +static int asm_cfg_params[ASM_CFG_PARAM_MAX]; + +struct msm_asm_config loopback_cfg[] = { + [MSM_FRONTEND_DAI_MULTIMEDIA1] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA2] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA3] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA4] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA5] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA6] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA7] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA8] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA9] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA10] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA11] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA12] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA13] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA14] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA15] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA16] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA17] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA18] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA19] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA20] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA21] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA22] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA23] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA24] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA25] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA26] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA27] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA28] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA29] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA30] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA31] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA32] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA33] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA34] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_VOIP] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_AFE_RX] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_AFE_TX] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_VOICE_STUB] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_DTMF_RX] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_QCHAT] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_VOLTE_STUB] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_LSM1] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_LSM2] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_LSM3] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_LSM4] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_LSM5] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_LSM6] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_LSM7] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_LSM8] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_VOICE2_STUB] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_VOICEMMODE1] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_VOICEMMODE2] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, +}; + +struct msm_asm_config playback_cfg[] = { + [MSM_FRONTEND_DAI_MULTIMEDIA1] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA2] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA3] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA4] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA5] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA6] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA7] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA8] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA9] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA10] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA11] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA12] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA13] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA14] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA15] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA16] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA17] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA18] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA19] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA20] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA21] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA22] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA23] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA24] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA25] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA26] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA27] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA28] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA29] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA30] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA31] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA32] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA33] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA34] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_VOIP] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_AFE_RX] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_AFE_TX] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_VOICE_STUB] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_DTMF_RX] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_QCHAT] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_VOLTE_STUB] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_LSM1] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_LSM2] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_LSM3] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_LSM4] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_LSM5] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_LSM6] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_LSM7] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_LSM8] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_VOICE2_STUB] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_VOICEMMODE1] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_VOICEMMODE2] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, +}; + +struct msm_asm_config capture_cfg[] = { + [MSM_FRONTEND_DAI_MULTIMEDIA1] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA2] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA3] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA4] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA5] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA6] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA7] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA8] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA9] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA10] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA11] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA12] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA13] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA14] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA15] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA16] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA17] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA18] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA19] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA20] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA21] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA22] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA23] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA24] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA25] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA26] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA27] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA28] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA29] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA30] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA31] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA32] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA33] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_MULTIMEDIA34] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_VOIP] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_AFE_RX] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_AFE_TX] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_VOICE_STUB] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_DTMF_RX] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_QCHAT] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_VOLTE_STUB] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_LSM1] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_LSM2] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_LSM3] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_LSM4] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_LSM5] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_LSM6] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_LSM7] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_LSM8] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_VOICE2_STUB] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_VOICEMMODE1] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, + [MSM_FRONTEND_DAI_VOICEMMODE2] = {0, 0, SNDRV_PCM_FORMAT_S16_LE}, +}; + +int msm_pcm_asm_cfg_get(int fe_id, int mode) +{ + int format = 0; + if (mode == MSM_ASM_PLAYBACK_MODE) { + format = playback_cfg[fe_id].bit_format; + } + else if(mode == MSM_ASM_CAPTURE_MODE) { + format = capture_cfg[fe_id].bit_format; + } + else if (mode == MSM_ASM_LOOPBACK_MODE) { + format = loopback_cfg[fe_id].bit_format; + } + return format; +} +EXPORT_SYMBOL(msm_pcm_asm_cfg_get); + +static int msm_pcm_get_format(int value) +{ + int format = 0; + switch (value) { + case 16: + format = SNDRV_PCM_FORMAT_S16_LE; + break; + case 24: + format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 32: + format = SNDRV_PCM_FORMAT_S32_LE; + break; + default: + break; + } + return format; +} + +static int msm_pcm_asm_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret = 0; + int fe_id = 0, mode = 0, format = 0, set = 0; + + mutex_lock(&routing_lock); + asm_cfg_params[0] = ucontrol->value.integer.value[0]; + asm_cfg_params[1] = ucontrol->value.integer.value[1]; + asm_cfg_params[2] = ucontrol->value.integer.value[2]; + set = ucontrol->value.integer.value[3]; + mutex_unlock(&routing_lock); + + if(set) { + fe_id = asm_cfg_params[0]; + mode = asm_cfg_params[1]; + format = msm_pcm_get_format(asm_cfg_params[2]); + + pr_debug("%s: fe_id:%d, mode:%d, format:%d, set:%d\n", + __func__,fe_id,mode,format,set); + + if((fe_id < MSM_FRONTEND_DAI_MULTIMEDIA1) || + (fe_id >= MSM_FRONTEND_DAI_MAX)) { + pr_err("%s: Received invalid fe_id %lu\n", __func__, fe_id); + ret = -EINVAL; + goto done; + } + if((mode < MSM_ASM_PLAYBACK_MODE) || + (mode >= MSM_ASM_MAX_MODE)) { + pr_err("%s: Received invalid mode %lu\n", __func__, mode); + ret = -EINVAL; + goto done; + } + if((format == SNDRV_PCM_FORMAT_S16_LE) || + (format == SNDRV_PCM_FORMAT_S24_LE) || + (format == SNDRV_PCM_FORMAT_S32_LE)) { + if(mode == MSM_ASM_PLAYBACK_MODE) { + playback_cfg[fe_id].fe_id = fe_id; + playback_cfg[fe_id].mode = mode; + playback_cfg[fe_id].bit_format = format; + } else if(mode == MSM_ASM_CAPTURE_MODE) { + capture_cfg[fe_id].fe_id = fe_id; + capture_cfg[fe_id].mode = mode; + capture_cfg[fe_id].bit_format = format; + } else if(mode == MSM_ASM_LOOPBACK_MODE) { + loopback_cfg[fe_id].fe_id = fe_id; + loopback_cfg[fe_id].mode = mode; + loopback_cfg[fe_id].bit_format = format; + } + }else { + pr_err("%s: Received invalid foramt %lu\n", __func__, + asm_cfg_params[2]); + ret = -EINVAL; + goto done; + } + } + done: + return ret; +} + +static int msm_pcm_asm_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + mutex_lock(&routing_lock); + ucontrol->value.integer.value[0] = asm_cfg_params[0]; + ucontrol->value.integer.value[1] = asm_cfg_params[1]; + ucontrol->value.integer.value[2] = asm_cfg_params[2]; + ucontrol->value.integer.value[3] = 0; + mutex_unlock(&routing_lock); + + pr_debug("%s: fe_id:%d, mode:%d, format:%d, set:%d\n",__func__, + ucontrol->value.integer.value[0], + ucontrol->value.integer.value[1], + ucontrol->value.integer.value[2], + ucontrol->value.integer.value[3]); + return 0; +} + +static const struct snd_kcontrol_new msm_asm_format_controls[] = { + SOC_SINGLE_MULTI_EXT("ASM Format", SND_SOC_NOPM, + 0, 0xFFFF, 0, 4, + msm_pcm_asm_format_get, + msm_pcm_asm_format_put), +}; + static const char *const ec_ref_rate_text[] = {"0", "8000", "16000", "24000", "32000", "44100", "48000", "96000", "192000", "384000"}; @@ -43329,6 +43620,9 @@ static int msm_routing_probe(struct snd_soc_component *component) snd_soc_add_component_controls(component, adm_channel_config_controls, ARRAY_SIZE(adm_channel_config_controls)); + snd_soc_add_component_controls(component, msm_asm_format_controls, + ARRAY_SIZE(msm_asm_format_controls)); + snd_soc_add_component_controls(component, aptx_dec_license_controls, ARRAY_SIZE(aptx_dec_license_controls)); snd_soc_add_component_controls(component, diff --git a/asoc/msm-pcm-routing-v2.h b/asoc/msm-pcm-routing-v2.h old mode 100755 new mode 100644 index 0ce5e1d73cdb..752fe58c1ec5 --- a/asoc/msm-pcm-routing-v2.h +++ b/asoc/msm-pcm-routing-v2.h @@ -2,6 +2,10 @@ /* Copyright (c) 2012-2021, The Linux Foundation. All rights reserved. * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ +/* + * Add support for 24 and 32bit format for ASM loopback and playback session. + */ + #ifndef _MSM_PCM_ROUTING_H #define _MSM_PCM_ROUTING_H #include @@ -757,6 +761,20 @@ struct msm_pcm_channel_mixer_v2 { int be_id; bool is_used; }; + +struct msm_asm_config { + u8 fe_id; + u8 mode; /* playback=0, capture=1,loopback=2 */ + u8 bit_format; +}; + +enum { + MSM_ASM_PLAYBACK_MODE = 0, + MSM_ASM_CAPTURE_MODE, + MSM_ASM_LOOPBACK_MODE, + MSM_ASM_MAX_MODE +}; + /* dai_id: front-end ID, * dspst_id: DSP audio stream ID * stream_type: playback or capture @@ -807,6 +825,7 @@ int msm_pcm_routing_set_channel_mixer_runtime( int msm_pcm_routing_set_stream_ec_ref_chmix_cfg( int fedai_id, struct msm_pcm_channel_mixer *cfg_data); +int msm_pcm_asm_cfg_get(int fe_id, int mode); /* array element of usr elem */