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

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

asoc: msm: Add support for 32 channels



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>
Signed-off-by: default avatarDhanalakshmi Siddani <dsiddani@codeaurora.org>
parent ff8d0d94
Loading
Loading
Loading
Loading
+60 −16
Original line number Diff line number Diff line
@@ -36,6 +36,8 @@
#include <sound/pcm_params.h>
#include <dsp/msm_audio_ion.h>
#include <dsp/q6audio-v2.h>
#include <dsp/q6core.h>
#include <dsp/q6asm-v2.h>

#include "msm-pcm-q6-v2.h"
#include "msm-pcm-routing-v2.h"
@@ -385,11 +387,17 @@ static int msm_pcm_playback_prepare(struct snd_pcm_substream *substream)
			return -ENOMEM;
		}
	} 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,
				fmt_type, bits_per_sample);

		if (ret < 0) {
			pr_err("%s: q6asm_open_write_v4 failed (%d)\n",
			pr_err("%s: q6asm_open_write failed (%d)\n",
			__func__, ret);
			q6asm_audio_client_free(prtd->audio_client);
			prtd->audio_client = NULL;
@@ -426,6 +434,18 @@ static int msm_pcm_playback_prepare(struct snd_pcm_substream *substream)
			runtime->channels, !prtd->set_channel_map,
			prtd->channel_map, bits_per_sample);
	} 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(
				prtd->audio_client, runtime->rate,
				runtime->channels, !prtd->set_channel_map,
@@ -433,6 +453,7 @@ static int msm_pcm_playback_prepare(struct snd_pcm_substream *substream)
				sample_word_size, ASM_LITTLE_ENDIAN,
				DEFAULT_QF);
		}
	}
	if (ret < 0)
		pr_info("%s: CMD Format block failed\n", __func__);

@@ -490,7 +511,15 @@ static int msm_pcm_capture_prepare(struct snd_pcm_substream *substream)
				__func__, params_channels(params),
				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);
		if (ret < 0) {
			pr_err("%s: q6asm_open_read failed\n", __func__);
@@ -558,13 +587,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",
			__func__, prtd->samp_rate, prtd->channel_mode,
			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->channel_mode,
						bits_per_sample,
						sample_word_size,
						ASM_LITTLE_ENDIAN,
						DEFAULT_QF);

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

@@ -1598,7 +1642,7 @@ static int msm_pcm_chmap_ctl_put(struct snd_kcontrol *kcontrol,
	prtd = substream->runtime->private_data;
	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++)
				prtd->channel_map[i] =
				(char)(ucontrol->value.integer.value[i]);
	}
@@ -1641,11 +1685,11 @@ static int msm_pcm_chmap_ctl_get(struct snd_kcontrol *kcontrol,
	prtd = substream->runtime->private_data;

	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] =
					(int)prtd->channel_map[i];
	} 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;
	}

@@ -1664,7 +1708,7 @@ static int msm_pcm_add_chmap_controls(struct snd_soc_pcm_runtime *rtd)
	pr_debug("%s, Channel map cntrl add\n", __func__);
	ret = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
				     snd_pcm_std_chmaps,
				     PCM_FORMAT_MAX_NUM_CHANNEL, 0,
				     PCM_FORMAT_MAX_NUM_CHANNEL_V8, 0,
				     &chmap_info);
	if (ret < 0) {
		pr_err("%s, channel map cntrl add failed\n", __func__);
+1 −1
Original line number Diff line number Diff line
@@ -105,7 +105,7 @@ struct msm_audio {
	int mmap_flag;
	atomic_t pending_buffer;
	bool set_channel_map;
	char channel_map[8];
	char channel_map[PCM_FORMAT_MAX_NUM_CHANNEL_V8];
	int cmd_interrupt;
	bool meta_data_mode;
	uint32_t volume;
+3 −3
Original line number Diff line number Diff line
@@ -19678,7 +19678,7 @@ static const struct snd_kcontrol_new aptx_dec_license_controls[] = {
static int msm_routing_put_port_chmap_mixer(struct snd_kcontrol *kcontrol,
					    struct snd_ctl_elem_value *ucontrol)
{
	uint8_t channel_map[PCM_FORMAT_MAX_NUM_CHANNEL];
	uint8_t channel_map[PCM_FORMAT_MAX_NUM_CHANNEL_V8];
	uint32_t be_idx = ucontrol->value.integer.value[0];
	int i;
@@ -19688,7 +19688,7 @@ static int msm_routing_put_port_chmap_mixer(struct snd_kcontrol *kcontrol,
		return -EINVAL;
	}
	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 + 1]);
		if (channel_map[i] > PCM_MAX_CHMAP_ID) {
			pr_err("%s: Invalid channel map %d\n",
@@ -19704,7 +19704,7 @@ static int msm_routing_put_port_chmap_mixer(struct snd_kcontrol *kcontrol,
static const struct snd_kcontrol_new port_multi_channel_map_mixer_controls[] = {
	SOC_SINGLE_MULTI_EXT("Backend Device Channel Map", SND_SOC_NOPM, 0,
			MSM_BACKEND_DAI_MAX, 0,
			PCM_FORMAT_MAX_NUM_CHANNEL + 1, NULL,
			PCM_FORMAT_MAX_NUM_CHANNEL_V8 + 1, NULL,
			msm_routing_put_port_chmap_mixer),
};
+6 −6
Original line number Diff line number Diff line
@@ -646,11 +646,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,
					    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;

	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] =
			(unsigned int) channel_map[i];
	return 0;
@@ -659,10 +659,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,
					    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;

	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]);
	adm_set_multi_ch_map(channel_map, ADM_PATH_PLAYBACK);

@@ -1239,8 +1239,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[] = {
	SOC_SINGLE_MULTI_EXT("Playback Device Channel Map", SND_SOC_NOPM, 0, 16,
	0, 8, msm_qti_pp_get_channel_map_mixer,
	SOC_SINGLE_MULTI_EXT("Playback Device Channel Map", SND_SOC_NOPM, 0, 34,
	0, PCM_FORMAT_MAX_NUM_CHANNEL_V8, msm_qti_pp_get_channel_map_mixer,
	msm_qti_pp_put_channel_map_mixer),
};