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

Commit 70668fcb authored by Dieter Luecking's avatar Dieter Luecking Committed by Gerrit - the friendly Code Review server
Browse files

asoc: msm: Add support for 32 ch



PCM streams do now support up to 32 channels.
Extend Playback Channel Map mixer control to 32
channels. Use new DSP 32 channel API if DSP version
supports it. If not fall back to 8 channels API.

Change-Id: I74c4f91b0c9fab2a963690ba8143ebea36ad23dd
Signed-off-by: default avatarDieter Luecking <dieterl@codeaurora.org>
Signed-off-by: default avatarMangesh Kunchamwar <mangeshk@codeaurora.org>
parent 39b3e3cc
Loading
Loading
Loading
Loading
+60 −16
Original line number Original line Diff line number Diff line
@@ -35,6 +35,8 @@
#include <sound/pcm_params.h>
#include <sound/pcm_params.h>
#include <dsp/msm_audio_ion.h>
#include <dsp/msm_audio_ion.h>
#include <dsp/q6audio-v2.h>
#include <dsp/q6audio-v2.h>
#include <dsp/q6core.h>
#include <dsp/q6asm-v2.h>


#include "msm-pcm-q6-v2.h"
#include "msm-pcm-q6-v2.h"
#include "msm-pcm-routing-v2.h"
#include "msm-pcm-routing-v2.h"
@@ -384,11 +386,17 @@ static int msm_pcm_playback_prepare(struct snd_pcm_substream *substream)
			return -ENOMEM;
			return -ENOMEM;
		}
		}
	} else {
	} else {
		if (q6core_get_avcs_api_version_per_service(
				APRV2_IDS_SERVICE_ID_ADSP_ASM_V) >=
				ADSP_ASM_API_VERSION_V2)
			ret = q6asm_open_write_v5(prtd->audio_client,
				fmt_type, bits_per_sample);
		else
			ret = q6asm_open_write_v4(prtd->audio_client,
			ret = q6asm_open_write_v4(prtd->audio_client,
				fmt_type, bits_per_sample);
				fmt_type, bits_per_sample);


		if (ret < 0) {
		if (ret < 0) {
			pr_err("%s: q6asm_open_write_v4 failed (%d)\n",
			pr_err("%s: q6asm_open_write failed (%d)\n",
			__func__, ret);
			__func__, ret);
			q6asm_audio_client_free(prtd->audio_client);
			q6asm_audio_client_free(prtd->audio_client);
			prtd->audio_client = NULL;
			prtd->audio_client = NULL;
@@ -425,6 +433,18 @@ static int msm_pcm_playback_prepare(struct snd_pcm_substream *substream)
			runtime->channels, !prtd->set_channel_map,
			runtime->channels, !prtd->set_channel_map,
			prtd->channel_map, bits_per_sample);
			prtd->channel_map, bits_per_sample);
	} else {
	} else {

		if (q6core_get_avcs_api_version_per_service(
				APRV2_IDS_SERVICE_ID_ADSP_ASM_V) >=
				ADSP_ASM_API_VERSION_V2) {

			ret = q6asm_media_format_block_multi_ch_pcm_v5(
				prtd->audio_client, runtime->rate,
				runtime->channels, !prtd->set_channel_map,
				prtd->channel_map, bits_per_sample,
				sample_word_size, ASM_LITTLE_ENDIAN,
				DEFAULT_QF);
		} else {
			ret = q6asm_media_format_block_multi_ch_pcm_v4(
			ret = q6asm_media_format_block_multi_ch_pcm_v4(
				prtd->audio_client, runtime->rate,
				prtd->audio_client, runtime->rate,
				runtime->channels, !prtd->set_channel_map,
				runtime->channels, !prtd->set_channel_map,
@@ -432,6 +452,7 @@ static int msm_pcm_playback_prepare(struct snd_pcm_substream *substream)
				sample_word_size, ASM_LITTLE_ENDIAN,
				sample_word_size, ASM_LITTLE_ENDIAN,
				DEFAULT_QF);
				DEFAULT_QF);
		}
		}
	}
	if (ret < 0)
	if (ret < 0)
		pr_info("%s: CMD Format block failed\n", __func__);
		pr_info("%s: CMD Format block failed\n", __func__);


@@ -489,7 +510,15 @@ static int msm_pcm_capture_prepare(struct snd_pcm_substream *substream)
				__func__, params_channels(params),
				__func__, params_channels(params),
				prtd->audio_client->perf_mode);
				prtd->audio_client->perf_mode);


		ret = q6asm_open_read_v4(prtd->audio_client, FORMAT_LINEAR_PCM,
		if (q6core_get_avcs_api_version_per_service(
				APRV2_IDS_SERVICE_ID_ADSP_ASM_V) >=
				ADSP_ASM_API_VERSION_V2)
			ret = q6asm_open_read_v5(prtd->audio_client,
				FORMAT_LINEAR_PCM,
				bits_per_sample, false, ENC_CFG_ID_NONE);
		else
			ret = q6asm_open_read_v4(prtd->audio_client,
				FORMAT_LINEAR_PCM,
				bits_per_sample, false, ENC_CFG_ID_NONE);
				bits_per_sample, false, ENC_CFG_ID_NONE);
		if (ret < 0) {
		if (ret < 0) {
			pr_err("%s: q6asm_open_read failed\n", __func__);
			pr_err("%s: q6asm_open_read failed\n", __func__);
@@ -557,13 +586,28 @@ static int msm_pcm_capture_prepare(struct snd_pcm_substream *substream)
	pr_debug("%s: Samp_rate = %d Channel = %d bit width = %d, word size = %d\n",
	pr_debug("%s: Samp_rate = %d Channel = %d bit width = %d, word size = %d\n",
			__func__, prtd->samp_rate, prtd->channel_mode,
			__func__, prtd->samp_rate, prtd->channel_mode,
			bits_per_sample, sample_word_size);
			bits_per_sample, sample_word_size);
	ret = q6asm_enc_cfg_blk_pcm_format_support_v4(prtd->audio_client,

	if (q6core_get_avcs_api_version_per_service(
			APRV2_IDS_SERVICE_ID_ADSP_ASM_V) >=
			ADSP_ASM_API_VERSION_V2)
		ret = q6asm_enc_cfg_blk_pcm_format_support_v5(
						prtd->audio_client,
						prtd->samp_rate,
						prtd->channel_mode,
						bits_per_sample,
						sample_word_size,
						ASM_LITTLE_ENDIAN,
						DEFAULT_QF);
	else
		ret = q6asm_enc_cfg_blk_pcm_format_support_v4(
						prtd->audio_client,
						prtd->samp_rate,
						prtd->samp_rate,
						prtd->channel_mode,
						prtd->channel_mode,
						bits_per_sample,
						bits_per_sample,
						sample_word_size,
						sample_word_size,
						ASM_LITTLE_ENDIAN,
						ASM_LITTLE_ENDIAN,
						DEFAULT_QF);
						DEFAULT_QF);

	if (ret < 0)
	if (ret < 0)
		pr_debug("%s: cmd cfg pcm was block failed", __func__);
		pr_debug("%s: cmd cfg pcm was block failed", __func__);


@@ -1508,7 +1552,7 @@ static int msm_pcm_chmap_ctl_put(struct snd_kcontrol *kcontrol,
	prtd = substream->runtime->private_data;
	prtd = substream->runtime->private_data;
	if (prtd) {
	if (prtd) {
		prtd->set_channel_map = true;
		prtd->set_channel_map = true;
			for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL; i++)
			for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++)
				prtd->channel_map[i] =
				prtd->channel_map[i] =
				(char)(ucontrol->value.integer.value[i]);
				(char)(ucontrol->value.integer.value[i]);
	}
	}
@@ -1536,11 +1580,11 @@ static int msm_pcm_chmap_ctl_get(struct snd_kcontrol *kcontrol,
	prtd = substream->runtime->private_data;
	prtd = substream->runtime->private_data;


	if (prtd && prtd->set_channel_map == true) {
	if (prtd && prtd->set_channel_map == true) {
		for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL; i++)
		for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++)
			ucontrol->value.integer.value[i] =
			ucontrol->value.integer.value[i] =
					(int)prtd->channel_map[i];
					(int)prtd->channel_map[i];
	} else {
	} else {
		for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL; i++)
		for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++)
			ucontrol->value.integer.value[i] = 0;
			ucontrol->value.integer.value[i] = 0;
	}
	}


@@ -1558,7 +1602,7 @@ static int msm_pcm_add_chmap_controls(struct snd_soc_pcm_runtime *rtd)
	pr_debug("%s, Channel map cntrl add\n", __func__);
	pr_debug("%s, Channel map cntrl add\n", __func__);
	ret = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
	ret = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
				     snd_pcm_std_chmaps,
				     snd_pcm_std_chmaps,
				     PCM_FORMAT_MAX_NUM_CHANNEL, 0,
				     PCM_FORMAT_MAX_NUM_CHANNEL_V8, 0,
				     &chmap_info);
				     &chmap_info);
	if (ret < 0) {
	if (ret < 0) {
		pr_err("%s, channel map cntrl add failed\n", __func__);
		pr_err("%s, channel map cntrl add failed\n", __func__);
+1 −1
Original line number Original line Diff line number Diff line
@@ -105,7 +105,7 @@ struct msm_audio {
	int mmap_flag;
	int mmap_flag;
	atomic_t pending_buffer;
	atomic_t pending_buffer;
	bool set_channel_map;
	bool set_channel_map;
	char channel_map[8];
	char channel_map[PCM_FORMAT_MAX_NUM_CHANNEL_V8];
	int cmd_interrupt;
	int cmd_interrupt;
	bool meta_data_mode;
	bool meta_data_mode;
	uint32_t volume;
	uint32_t volume;
+6 −0
Original line number Original line Diff line number Diff line
@@ -591,6 +591,12 @@ struct msm_pcm_routing_bdai_data msm_bedais[MSM_BACKEND_DAI_MAX] = {
	  LPASS_BE_INT6_MI2S_RX},
	  LPASS_BE_INT6_MI2S_RX},
	{ AFE_PORT_ID_INT6_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0,
	{ AFE_PORT_ID_INT6_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0,
	  LPASS_BE_INT6_MI2S_TX},
	  LPASS_BE_INT6_MI2S_TX},
	{ AFE_PORT_ID_SENARY_PCM_RX, 0, {0}, {0}, 0, 0, 0, 0,
	  LPASS_BE_SEN_AUXPCM_RX},
	{ AFE_PORT_ID_SENARY_PCM_TX, 0, {0}, {0}, 0, 0, 0, 0,
	  LPASS_BE_SEN_AUXPCM_TX},
	{ AFE_PORT_ID_SENARY_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0,
	  LPASS_BE_SENARY_MI2S_RX},
	{ AFE_PORT_ID_WSA_CODEC_DMA_RX_0, 0, {0}, {0}, 0, 0, 0, 0,
	{ AFE_PORT_ID_WSA_CODEC_DMA_RX_0, 0, {0}, {0}, 0, 0, 0, 0,
	  LPASS_BE_WSA_CDC_DMA_RX_0},
	  LPASS_BE_WSA_CDC_DMA_RX_0},
	{ AFE_PORT_ID_WSA_CODEC_DMA_TX_0, 0, {0}, {0}, 0, 0, 0, 0,
	{ AFE_PORT_ID_WSA_CODEC_DMA_TX_0, 0, {0}, {0}, 0, 0, 0, 0,
+6 −0
Original line number Original line Diff line number Diff line
@@ -43,6 +43,8 @@
#define LPASS_BE_QUAT_AUXPCM_TX "QUAT_AUX_PCM_TX"
#define LPASS_BE_QUAT_AUXPCM_TX "QUAT_AUX_PCM_TX"
#define LPASS_BE_QUIN_AUXPCM_RX "QUIN_AUX_PCM_RX"
#define LPASS_BE_QUIN_AUXPCM_RX "QUIN_AUX_PCM_RX"
#define LPASS_BE_QUIN_AUXPCM_TX "QUIN_AUX_PCM_TX"
#define LPASS_BE_QUIN_AUXPCM_TX "QUIN_AUX_PCM_TX"
#define LPASS_BE_SEN_AUXPCM_RX "SEN_AUX_PCM_RX"
#define LPASS_BE_SEN_AUXPCM_TX "SEN_AUX_PCM_TX"
#define LPASS_BE_VOICE_PLAYBACK_TX "VOICE_PLAYBACK_TX"
#define LPASS_BE_VOICE_PLAYBACK_TX "VOICE_PLAYBACK_TX"
#define LPASS_BE_VOICE2_PLAYBACK_TX "VOICE2_PLAYBACK_TX"
#define LPASS_BE_VOICE2_PLAYBACK_TX "VOICE2_PLAYBACK_TX"
#define LPASS_BE_INCALL_RECORD_RX "INCALL_RECORD_RX"
#define LPASS_BE_INCALL_RECORD_RX "INCALL_RECORD_RX"
@@ -84,6 +86,7 @@
#define LPASS_BE_QUIN_MI2S_RX "QUIN_MI2S_RX"
#define LPASS_BE_QUIN_MI2S_RX "QUIN_MI2S_RX"
#define LPASS_BE_QUIN_MI2S_TX "QUIN_MI2S_TX"
#define LPASS_BE_QUIN_MI2S_TX "QUIN_MI2S_TX"
#define LPASS_BE_SENARY_MI2S_TX "SENARY_MI2S_TX"
#define LPASS_BE_SENARY_MI2S_TX "SENARY_MI2S_TX"
#define LPASS_BE_SENARY_MI2S_RX "SENARY_MI2S_RX"


#define LPASS_BE_PRI_TDM_RX_0 "PRI_TDM_RX_0"
#define LPASS_BE_PRI_TDM_RX_0 "PRI_TDM_RX_0"
#define LPASS_BE_PRI_TDM_TX_0 "PRI_TDM_TX_0"
#define LPASS_BE_PRI_TDM_TX_0 "PRI_TDM_TX_0"
@@ -431,6 +434,9 @@ enum {
	MSM_BACKEND_DAI_INT5_MI2S_TX,
	MSM_BACKEND_DAI_INT5_MI2S_TX,
	MSM_BACKEND_DAI_INT6_MI2S_RX,
	MSM_BACKEND_DAI_INT6_MI2S_RX,
	MSM_BACKEND_DAI_INT6_MI2S_TX,
	MSM_BACKEND_DAI_INT6_MI2S_TX,
	MSM_BACKEND_DAI_SEN_AUXPCM_RX,
	MSM_BACKEND_DAI_SEN_AUXPCM_TX,
	MSM_BACKEND_DAI_SENARY_MI2S_RX,
	MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0,
	MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0,
	MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0,
	MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0,
	MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1,
	MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1,
+6 −6
Original line number Original line Diff line number Diff line
@@ -809,11 +809,11 @@ static int msm_qti_pp_set_sec_auxpcm_lb_vol_mixer(
static int msm_qti_pp_get_channel_map_mixer(struct snd_kcontrol *kcontrol,
static int msm_qti_pp_get_channel_map_mixer(struct snd_kcontrol *kcontrol,
					    struct snd_ctl_elem_value *ucontrol)
					    struct snd_ctl_elem_value *ucontrol)
{
{
	char channel_map[PCM_FORMAT_MAX_NUM_CHANNEL] = {0};
	char channel_map[PCM_FORMAT_MAX_NUM_CHANNEL_V8] = {0};
	int i;
	int i;


	adm_get_multi_ch_map(channel_map, ADM_PATH_PLAYBACK);
	adm_get_multi_ch_map(channel_map, ADM_PATH_PLAYBACK);
	for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL; i++)
	for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++)
		ucontrol->value.integer.value[i] =
		ucontrol->value.integer.value[i] =
			(unsigned int) channel_map[i];
			(unsigned int) channel_map[i];
	return 0;
	return 0;
@@ -822,10 +822,10 @@ static int msm_qti_pp_get_channel_map_mixer(struct snd_kcontrol *kcontrol,
static int msm_qti_pp_put_channel_map_mixer(struct snd_kcontrol *kcontrol,
static int msm_qti_pp_put_channel_map_mixer(struct snd_kcontrol *kcontrol,
					    struct snd_ctl_elem_value *ucontrol)
					    struct snd_ctl_elem_value *ucontrol)
{
{
	char channel_map[PCM_FORMAT_MAX_NUM_CHANNEL];
	char channel_map[PCM_FORMAT_MAX_NUM_CHANNEL_V8];
	int i;
	int i;


	for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL; i++)
	for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++)
		channel_map[i] = (char)(ucontrol->value.integer.value[i]);
		channel_map[i] = (char)(ucontrol->value.integer.value[i]);
	adm_set_multi_ch_map(channel_map, ADM_PATH_PLAYBACK);
	adm_set_multi_ch_map(channel_map, ADM_PATH_PLAYBACK);


@@ -1414,8 +1414,8 @@ static const struct snd_kcontrol_new sec_auxpcm_lb_vol_mixer_controls[] = {
};
};


static const struct snd_kcontrol_new multi_ch_channel_map_mixer_controls[] = {
static const struct snd_kcontrol_new multi_ch_channel_map_mixer_controls[] = {
	SOC_SINGLE_MULTI_EXT("Playback Device Channel Map", SND_SOC_NOPM, 0, 16,
	SOC_SINGLE_MULTI_EXT("Playback Device Channel Map", SND_SOC_NOPM, 0, 34,
	0, 8, msm_qti_pp_get_channel_map_mixer,
	0, PCM_FORMAT_MAX_NUM_CHANNEL_V8, msm_qti_pp_get_channel_map_mixer,
	msm_qti_pp_put_channel_map_mixer),
	msm_qti_pp_put_channel_map_mixer),
};
};