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: Dieter Luecking <dieterl@codeaurora.org>
Signed-off-by: Mangesh Kunchamwar <mangeshk@codeaurora.org>
This commit is contained in:
Dieter Luecking 2018-09-28 15:03:01 +02:00 committed by Gerrit - the friendly Code Review server
parent 39b3e3cc9e
commit 70668fcb8d
5 changed files with 79 additions and 23 deletions

View File

@ -35,6 +35,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"
@ -384,11 +386,17 @@ static int msm_pcm_playback_prepare(struct snd_pcm_substream *substream)
return -ENOMEM;
}
} else {
ret = q6asm_open_write_v4(prtd->audio_client,
fmt_type, bits_per_sample);
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;
@ -425,12 +433,25 @@ static int msm_pcm_playback_prepare(struct snd_pcm_substream *substream)
runtime->channels, !prtd->set_channel_map,
prtd->channel_map, bits_per_sample);
} else {
ret = q6asm_media_format_block_multi_ch_pcm_v4(
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,
prtd->channel_map, bits_per_sample,
sample_word_size, ASM_LITTLE_ENDIAN,
DEFAULT_QF);
}
}
if (ret < 0)
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),
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);
if (ret < 0) {
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",
__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,
prtd->samp_rate,
prtd->channel_mode,
bits_per_sample,
sample_word_size,
ASM_LITTLE_ENDIAN,
DEFAULT_QF);
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__);
@ -1508,7 +1552,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]);
}
@ -1536,11 +1580,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;
}
@ -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__);
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__);

View File

@ -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;

View File

@ -591,6 +591,12 @@ struct msm_pcm_routing_bdai_data msm_bedais[MSM_BACKEND_DAI_MAX] = {
LPASS_BE_INT6_MI2S_RX},
{ AFE_PORT_ID_INT6_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0,
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,
LPASS_BE_WSA_CDC_DMA_RX_0},
{ AFE_PORT_ID_WSA_CODEC_DMA_TX_0, 0, {0}, {0}, 0, 0, 0, 0,

View File

@ -43,6 +43,8 @@
#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_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_VOICE2_PLAYBACK_TX "VOICE2_PLAYBACK_TX"
#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_TX "QUIN_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_TX_0 "PRI_TDM_TX_0"
@ -431,6 +434,9 @@ enum {
MSM_BACKEND_DAI_INT5_MI2S_TX,
MSM_BACKEND_DAI_INT6_MI2S_RX,
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_TX_0,
MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1,

View File

@ -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,
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;
@ -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,
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);
@ -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[] = {
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),
};