audio-driver: Update drivers to support 32 channels
Update asm/adm/afe drivers to support 32 channels
Change-Id: Ia231eb6a0fb545569f0f8e1f2442432d761866e9
Signed-off-by: Cong Tang <congt@codeaurora.org>
diff --git a/asoc/msm-dai-fe.c b/asoc/msm-dai-fe.c
index 3de797f..cdad909 100644
--- a/asoc/msm-dai-fe.c
+++ b/asoc/msm-dai-fe.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -99,7 +99,7 @@
SNDRV_PCM_FMTBIT_S24_3LE |
SNDRV_PCM_FMTBIT_S32_LE),
.channels_min = 1,
- .channels_max = 8,
+ .channels_max = 32,
.rate_min = 8000,
.rate_max = 384000,
},
@@ -113,7 +113,7 @@
SNDRV_PCM_FMTBIT_S24_3LE |
SNDRV_PCM_FMTBIT_S32_LE),
.channels_min = 1,
- .channels_max = 8,
+ .channels_max = 32,
.rate_min = 8000,
.rate_max = 48000,
},
@@ -132,7 +132,7 @@
SNDRV_PCM_FMTBIT_S24_3LE |
SNDRV_PCM_FMTBIT_S32_LE),
.channels_min = 1,
- .channels_max = 8,
+ .channels_max = 32,
.rate_min = 8000,
.rate_max = 384000,
},
@@ -146,7 +146,7 @@
SNDRV_PCM_FMTBIT_S24_3LE |
SNDRV_PCM_FMTBIT_S32_LE),
.channels_min = 1,
- .channels_max = 8,
+ .channels_max = 32,
.rate_min = 8000,
.rate_max = 48000,
},
@@ -192,7 +192,7 @@
SNDRV_PCM_FMTBIT_S24_3LE |
SNDRV_PCM_FMTBIT_S32_LE),
.channels_min = 1,
- .channels_max = 6,
+ .channels_max = 32,
.rate_min = 8000,
.rate_max = 384000,
},
@@ -206,7 +206,7 @@
SNDRV_PCM_FMTBIT_S24_3LE |
SNDRV_PCM_FMTBIT_S32_LE),
.channels_min = 1,
- .channels_max = 8,
+ .channels_max = 32,
.rate_min = 8000,
.rate_max = 48000,
},
@@ -225,7 +225,7 @@
SNDRV_PCM_FMTBIT_S24_3LE |
SNDRV_PCM_FMTBIT_S32_LE),
.channels_min = 1,
- .channels_max = 8,
+ .channels_max = 32,
.rate_min = 8000,
.rate_max = 384000,
},
@@ -245,7 +245,7 @@
SNDRV_PCM_FMTBIT_S24_3LE |
SNDRV_PCM_FMTBIT_S32_LE),
.channels_min = 1,
- .channels_max = 8,
+ .channels_max = 32,
.rate_min = 8000,
.rate_max = 384000,
},
@@ -259,7 +259,7 @@
SNDRV_PCM_FMTBIT_S24_3LE |
SNDRV_PCM_FMTBIT_S32_LE),
.channels_min = 1,
- .channels_max = 8,
+ .channels_max = 32,
.rate_min = 8000,
.rate_max = 48000,
},
@@ -278,7 +278,7 @@
SNDRV_PCM_FMTBIT_S24_3LE |
SNDRV_PCM_FMTBIT_S32_LE),
.channels_min = 1,
- .channels_max = 8,
+ .channels_max = 32,
.rate_min = 8000,
.rate_max = 384000,
},
@@ -292,7 +292,7 @@
SNDRV_PCM_FMTBIT_S24_3LE |
SNDRV_PCM_FMTBIT_S32_LE),
.channels_min = 1,
- .channels_max = 8,
+ .channels_max = 32,
.rate_min = 8000,
.rate_max = 48000,
},
@@ -311,7 +311,7 @@
SNDRV_PCM_FMTBIT_S24_3LE |
SNDRV_PCM_FMTBIT_S32_LE),
.channels_min = 1,
- .channels_max = 8,
+ .channels_max = 32,
.rate_min = 8000,
.rate_max = 384000,
},
@@ -331,7 +331,7 @@
SNDRV_PCM_FMTBIT_S24_3LE |
SNDRV_PCM_FMTBIT_S32_LE),
.channels_min = 1,
- .channels_max = 8,
+ .channels_max = 32,
.rate_min = 8000,
.rate_max = 384000,
},
@@ -345,7 +345,7 @@
SNDRV_PCM_FMTBIT_S24_3LE |
SNDRV_PCM_FMTBIT_S32_LE),
.channels_min = 1,
- .channels_max = 8,
+ .channels_max = 32,
.rate_min = 8000,
.rate_max = 48000,
},
@@ -2083,7 +2083,7 @@
SNDRV_PCM_FMTBIT_S24_LE |
SNDRV_PCM_FMTBIT_S24_3LE),
.channels_min = 1,
- .channels_max = 8,
+ .channels_max = 32,
.rate_min = 8000,
.rate_max = 384000,
},
@@ -2094,7 +2094,7 @@
SNDRV_PCM_RATE_KNOT),
.formats = SNDRV_PCM_FMTBIT_S16_LE,
.channels_min = 1,
- .channels_max = 8,
+ .channels_max = 32,
.rate_min = 8000,
.rate_max = 48000,
},
@@ -2275,7 +2275,7 @@
SNDRV_PCM_FMTBIT_S24_3LE |
SNDRV_PCM_FMTBIT_S32_LE),
.channels_min = 1,
- .channels_max = 8,
+ .channels_max = 32,
.rate_min = 8000,
.rate_max = 384000,
},
@@ -2288,7 +2288,7 @@
SNDRV_PCM_FMTBIT_S24_LE |
SNDRV_PCM_FMTBIT_S24_3LE),
.channels_min = 1,
- .channels_max = 8,
+ .channels_max = 32,
.rate_min = 8000,
.rate_max = 48000,
},
@@ -2307,7 +2307,7 @@
SNDRV_PCM_FMTBIT_S24_3LE |
SNDRV_PCM_FMTBIT_S32_LE),
.channels_min = 1,
- .channels_max = 8,
+ .channels_max = 32,
.rate_min = 8000,
.rate_max = 384000,
},
@@ -2327,7 +2327,7 @@
SNDRV_PCM_FMTBIT_S24_3LE |
SNDRV_PCM_FMTBIT_S32_LE),
.channels_min = 1,
- .channels_max = 8,
+ .channels_max = 32,
.rate_min = 8000,
.rate_max = 384000,
},
@@ -2347,7 +2347,7 @@
SNDRV_PCM_FMTBIT_S24_3LE |
SNDRV_PCM_FMTBIT_S32_LE),
.channels_min = 1,
- .channels_max = 8,
+ .channels_max = 32,
.rate_min = 8000,
.rate_max = 384000,
},
@@ -2367,7 +2367,7 @@
SNDRV_PCM_FMTBIT_S24_3LE |
SNDRV_PCM_FMTBIT_S32_LE),
.channels_min = 1,
- .channels_max = 8,
+ .channels_max = 32,
.rate_min = 8000,
.rate_max = 384000,
},
@@ -2387,7 +2387,7 @@
SNDRV_PCM_FMTBIT_S24_3LE |
SNDRV_PCM_FMTBIT_S32_LE),
.channels_min = 1,
- .channels_max = 8,
+ .channels_max = 32,
.rate_min = 8000,
.rate_max = 384000,
},
@@ -2407,7 +2407,7 @@
SNDRV_PCM_FMTBIT_S24_3LE |
SNDRV_PCM_FMTBIT_S32_LE),
.channels_min = 1,
- .channels_max = 8,
+ .channels_max = 32,
.rate_min = 8000,
.rate_max = 384000,
},
@@ -2421,7 +2421,7 @@
SNDRV_PCM_FMTBIT_S24_3LE |
SNDRV_PCM_FMTBIT_S32_LE),
.channels_min = 1,
- .channels_max = 8,
+ .channels_max = 32,
.rate_min = 8000,
.rate_max = 48000,
},
@@ -2489,7 +2489,7 @@
SNDRV_PCM_FMTBIT_S24_LE |
SNDRV_PCM_FMTBIT_S24_3LE),
.channels_min = 1,
- .channels_max = 8,
+ .channels_max = 32,
.rate_min = 8000,
.rate_max = 192000,
},
@@ -2508,7 +2508,7 @@
SNDRV_PCM_FMTBIT_S24_LE |
SNDRV_PCM_FMTBIT_S24_3LE),
.channels_min = 1,
- .channels_max = 8,
+ .channels_max = 32,
.rate_min = 8000,
.rate_max = 192000,
},
@@ -2527,7 +2527,7 @@
SNDRV_PCM_FMTBIT_S24_LE |
SNDRV_PCM_FMTBIT_S24_3LE),
.channels_min = 1,
- .channels_max = 8,
+ .channels_max = 32,
.rate_min = 8000,
.rate_max = 192000,
},
@@ -2547,7 +2547,7 @@
SNDRV_PCM_FMTBIT_S24_3LE |
SNDRV_PCM_FMTBIT_S32_LE),
.channels_min = 1,
- .channels_max = 8,
+ .channels_max = 32,
.rate_min = 8000,
.rate_max = 384000,
},
@@ -2561,7 +2561,7 @@
SNDRV_PCM_FMTBIT_S24_3LE |
SNDRV_PCM_FMTBIT_S32_LE),
.channels_min = 1,
- .channels_max = 8,
+ .channels_max = 32,
.rate_min = 8000,
.rate_max = 48000,
},
@@ -2579,7 +2579,7 @@
SNDRV_PCM_FMTBIT_S24_LE |
SNDRV_PCM_FMTBIT_S24_3LE),
.channels_min = 1,
- .channels_max = 8,
+ .channels_max = 32,
.rate_min = 8000,
.rate_max = 192000,
},
@@ -2598,7 +2598,7 @@
SNDRV_PCM_FMTBIT_S24_LE |
SNDRV_PCM_FMTBIT_S24_3LE),
.channels_min = 1,
- .channels_max = 8,
+ .channels_max = 32,
.rate_min = 8000,
.rate_max = 192000,
},
diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c
index 04d2de8..9be62cf 100644
--- a/asoc/msm-dai-q6-v2.c
+++ b/asoc/msm-dai-q6-v2.c
@@ -24,6 +24,7 @@
#include <sound/pcm_params.h>
#include <dsp/apr_audio-v2.h>
#include <dsp/q6afe-v2.h>
+#include <dsp/q6core.h>
#include "msm-dai-q6-v2.h"
#include "codecs/core.h"
@@ -6751,6 +6752,9 @@
case 16:
cap_mask = 0xFFFF;
break;
+ case 32:
+ cap_mask = 0xFFFFFFFF;
+ break;
default:
dev_err(dai->dev, "%s: invalid slots %d\n",
__func__, slots);
@@ -6893,6 +6897,8 @@
dev_get_drvdata(dai->dev);
struct afe_param_id_slot_mapping_cfg *slot_mapping =
&dai_data->port_cfg.slot_mapping;
+ struct afe_param_id_slot_mapping_cfg_v2 *slot_mapping_v2 =
+ &dai_data->port_cfg.slot_mapping_v2;
int i = 0;
dev_dbg(dai->dev, "%s: dai id = 0x%x\n", __func__, dai->id);
@@ -6938,23 +6944,49 @@
case AFE_PORT_ID_QUINARY_TDM_RX_5:
case AFE_PORT_ID_QUINARY_TDM_RX_6:
case AFE_PORT_ID_QUINARY_TDM_RX_7:
- if (!rx_slot) {
- dev_err(dai->dev, "%s: rx slot not found\n", __func__);
- return -EINVAL;
- }
- if (rx_num > AFE_PORT_MAX_AUDIO_CHAN_CNT) {
- dev_err(dai->dev, "%s: invalid rx num %d\n", __func__,
- rx_num);
- return -EINVAL;
- }
+ if (q6core_get_avcs_api_version_per_service(
+ APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V3) {
+ if (!rx_slot) {
+ dev_err(dai->dev, "%s: rx slot not found\n",
+ __func__);
+ return -EINVAL;
+ }
+ if (rx_num > AFE_PORT_MAX_AUDIO_CHAN_CNT_V2) {
+ dev_err(dai->dev, "%s: invalid rx num %d\n",
+ __func__,
+ rx_num);
+ return -EINVAL;
+ }
- for (i = 0; i < rx_num; i++)
- slot_mapping->offset[i] = rx_slot[i];
- for (i = rx_num; i < AFE_PORT_MAX_AUDIO_CHAN_CNT; i++)
- slot_mapping->offset[i] =
- AFE_SLOT_MAPPING_OFFSET_INVALID;
+ for (i = 0; i < rx_num; i++)
+ slot_mapping_v2->offset[i] = rx_slot[i];
+ for (i = rx_num; i < AFE_PORT_MAX_AUDIO_CHAN_CNT_V2;
+ i++)
+ slot_mapping_v2->offset[i] =
+ AFE_SLOT_MAPPING_OFFSET_INVALID;
- slot_mapping->num_channel = rx_num;
+ slot_mapping_v2->num_channel = rx_num;
+ } else {
+ if (!rx_slot) {
+ dev_err(dai->dev, "%s: rx slot not found\n",
+ __func__);
+ return -EINVAL;
+ }
+ if (rx_num > AFE_PORT_MAX_AUDIO_CHAN_CNT) {
+ dev_err(dai->dev, "%s: invalid rx num %d\n",
+ __func__,
+ rx_num);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < rx_num; i++)
+ slot_mapping->offset[i] = rx_slot[i];
+ for (i = rx_num; i < AFE_PORT_MAX_AUDIO_CHAN_CNT; i++)
+ slot_mapping->offset[i] =
+ AFE_SLOT_MAPPING_OFFSET_INVALID;
+
+ slot_mapping->num_channel = rx_num;
+ }
break;
case AFE_PORT_ID_PRIMARY_TDM_TX:
case AFE_PORT_ID_PRIMARY_TDM_TX_1:
@@ -6996,23 +7028,49 @@
case AFE_PORT_ID_QUINARY_TDM_TX_5:
case AFE_PORT_ID_QUINARY_TDM_TX_6:
case AFE_PORT_ID_QUINARY_TDM_TX_7:
- if (!tx_slot) {
- dev_err(dai->dev, "%s: tx slot not found\n", __func__);
- return -EINVAL;
- }
- if (tx_num > AFE_PORT_MAX_AUDIO_CHAN_CNT) {
- dev_err(dai->dev, "%s: invalid tx num %d\n", __func__,
- tx_num);
- return -EINVAL;
- }
+ if (q6core_get_avcs_api_version_per_service(
+ APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V3) {
+ if (!tx_slot) {
+ dev_err(dai->dev, "%s: tx slot not found\n",
+ __func__);
+ return -EINVAL;
+ }
+ if (tx_num > AFE_PORT_MAX_AUDIO_CHAN_CNT_V2) {
+ dev_err(dai->dev, "%s: invalid tx num %d\n",
+ __func__,
+ tx_num);
+ return -EINVAL;
+ }
- for (i = 0; i < tx_num; i++)
- slot_mapping->offset[i] = tx_slot[i];
- for (i = tx_num; i < AFE_PORT_MAX_AUDIO_CHAN_CNT; i++)
- slot_mapping->offset[i] =
- AFE_SLOT_MAPPING_OFFSET_INVALID;
+ for (i = 0; i < tx_num; i++)
+ slot_mapping_v2->offset[i] = tx_slot[i];
+ for (i = tx_num; i < AFE_PORT_MAX_AUDIO_CHAN_CNT_V2;
+ i++)
+ slot_mapping_v2->offset[i] =
+ AFE_SLOT_MAPPING_OFFSET_INVALID;
- slot_mapping->num_channel = tx_num;
+ slot_mapping_v2->num_channel = tx_num;
+ } else {
+ if (!tx_slot) {
+ dev_err(dai->dev, "%s: tx slot not found\n",
+ __func__);
+ return -EINVAL;
+ }
+ if (tx_num > AFE_PORT_MAX_AUDIO_CHAN_CNT) {
+ dev_err(dai->dev, "%s: invalid tx num %d\n",
+ __func__,
+ tx_num);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < tx_num; i++)
+ slot_mapping->offset[i] = tx_slot[i];
+ for (i = tx_num; i < AFE_PORT_MAX_AUDIO_CHAN_CNT; i++)
+ slot_mapping->offset[i] =
+ AFE_SLOT_MAPPING_OFFSET_INVALID;
+
+ slot_mapping->num_channel = tx_num;
+ }
break;
default:
dev_err(dai->dev, "%s: invalid dai id 0x%x\n",
@@ -7036,6 +7094,8 @@
&dai_data->port_cfg.tdm;
struct afe_param_id_slot_mapping_cfg *slot_mapping =
&dai_data->port_cfg.slot_mapping;
+ struct afe_param_id_slot_mapping_cfg_v2 *slot_mapping_v2 =
+ &dai_data->port_cfg.slot_mapping_v2;
struct afe_param_id_custom_tdm_header_cfg *custom_tdm_header =
&dai_data->port_cfg.custom_tdm_header;
@@ -7043,7 +7103,7 @@
__func__, dev_name(dai->dev));
if ((params_channels(params) == 0) ||
- (params_channels(params) > 8)) {
+ (params_channels(params) > 32)) {
dev_err(dai->dev, "%s: invalid param channels %d\n",
__func__, params_channels(params));
return -EINVAL;
@@ -7131,32 +7191,88 @@
tdm->ctrl_data_out_enable,
tdm->ctrl_invert_sync_pulse,
tdm->ctrl_sync_data_delay);
+ if (q6core_get_avcs_api_version_per_service(
+ APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V3) {
+ /*
+ * update slot mapping v2 config param
+ * NOTE: channels/rate/bitwidth are per stream property
+ */
+ slot_mapping_v2->bitwidth = dai_data->bitwidth;
- /*
- * update slot mapping config param
- * NOTE: channels/rate/bitwidth are per stream property
- */
- slot_mapping->bitwidth = dai_data->bitwidth;
-
- pr_debug("%s: SLOT MAPPING:\n"
+ pr_debug("%s: SLOT MAPPING_V2:\n"
"num_channel=%d bitwidth=%d data_align=0x%x\n",
__func__,
- slot_mapping->num_channel,
- slot_mapping->bitwidth,
- slot_mapping->data_align_type);
- pr_debug("%s: SLOT MAPPING:\n"
+ slot_mapping_v2->num_channel,
+ slot_mapping_v2->bitwidth,
+ slot_mapping_v2->data_align_type);
+ pr_debug("%s: SLOT MAPPING V2:\n"
"offset[0]=0x%x offset[1]=0x%x offset[2]=0x%x offset[3]=0x%x\n"
- "offset[4]=0x%x offset[5]=0x%x offset[6]=0x%x offset[7]=0x%x\n",
+ "offset[4]=0x%x offset[5]=0x%x offset[6]=0x%x offset[7]=0x%x\n"
+ "offset[8]=0x%x offset[9]=0x%x offset[10]=0x%x offset[11]=0x%x\n"
+ "offset[12]=0x%x offset[13]=0x%x offset[14]=0x%x offset[15]=0x%x\n"
+ "offset[16]=0x%x offset[17]=0x%x offset[18]=0x%x offset[19]=0x%x\n"
+ "offset[20]=0x%x offset[21]=0x%x offset[22]=0x%x offset[23]=0x%x\n"
+ "offset[24]=0x%x offset[25]=0x%x offset[26]=0x%x offset[27]=0x%x\n"
+ "offset[28]=0x%x offset[29]=0x%x offset[30]=0x%x offset[31]=0x%x\n",
__func__,
- slot_mapping->offset[0],
- slot_mapping->offset[1],
- slot_mapping->offset[2],
- slot_mapping->offset[3],
- slot_mapping->offset[4],
- slot_mapping->offset[5],
- slot_mapping->offset[6],
- slot_mapping->offset[7]);
+ slot_mapping_v2->offset[0],
+ slot_mapping_v2->offset[1],
+ slot_mapping_v2->offset[2],
+ slot_mapping_v2->offset[3],
+ slot_mapping_v2->offset[4],
+ slot_mapping_v2->offset[5],
+ slot_mapping_v2->offset[6],
+ slot_mapping_v2->offset[7],
+ slot_mapping_v2->offset[8],
+ slot_mapping_v2->offset[9],
+ slot_mapping_v2->offset[10],
+ slot_mapping_v2->offset[11],
+ slot_mapping_v2->offset[12],
+ slot_mapping_v2->offset[13],
+ slot_mapping_v2->offset[14],
+ slot_mapping_v2->offset[15],
+ slot_mapping_v2->offset[16],
+ slot_mapping_v2->offset[17],
+ slot_mapping_v2->offset[18],
+ slot_mapping_v2->offset[19],
+ slot_mapping_v2->offset[20],
+ slot_mapping_v2->offset[21],
+ slot_mapping_v2->offset[22],
+ slot_mapping_v2->offset[23],
+ slot_mapping_v2->offset[24],
+ slot_mapping_v2->offset[25],
+ slot_mapping_v2->offset[26],
+ slot_mapping_v2->offset[27],
+ slot_mapping_v2->offset[28],
+ slot_mapping_v2->offset[29],
+ slot_mapping_v2->offset[30],
+ slot_mapping_v2->offset[31]);
+ } else {
+ /*
+ * update slot mapping config param
+ * NOTE: channels/rate/bitwidth are per stream property
+ */
+ slot_mapping->bitwidth = dai_data->bitwidth;
+ pr_debug("%s: SLOT MAPPING:\n"
+ "num_channel=%d bitwidth=%d data_align=0x%x\n",
+ __func__,
+ slot_mapping->num_channel,
+ slot_mapping->bitwidth,
+ slot_mapping->data_align_type);
+ pr_debug("%s: SLOT MAPPING:\n"
+ "offset[0]=0x%x offset[1]=0x%x offset[2]=0x%x offset[3]=0x%x\n"
+ "offset[4]=0x%x offset[5]=0x%x offset[6]=0x%x offset[7]=0x%x\n",
+ __func__,
+ slot_mapping->offset[0],
+ slot_mapping->offset[1],
+ slot_mapping->offset[2],
+ slot_mapping->offset[3],
+ slot_mapping->offset[4],
+ slot_mapping->offset[5],
+ slot_mapping->offset[6],
+ slot_mapping->offset[7]);
+ }
/*
* update custom header config param
* NOTE: channels/rate/bitwidth are per playback stream property.
@@ -9290,6 +9406,8 @@
/* TDM SLOT MAPPING CFG -- set default */
dai_data->port_cfg.slot_mapping.minor_version =
AFE_API_VERSION_SLOT_MAPPING_CONFIG;
+ dai_data->port_cfg.slot_mapping_v2.minor_version =
+ AFE_API_VERSION_SLOT_MAPPING_CONFIG_V2;
/* CUSTOM TDM HEADER CFG */
custom_tdm_header = &dai_data->port_cfg.custom_tdm_header;
diff --git a/dsp/q6adm.c b/dsp/q6adm.c
index 85e1b85..c3580a7 100644
--- a/dsp/q6adm.c
+++ b/dsp/q6adm.c
@@ -2767,6 +2767,39 @@
ep_payload->dev_channel_mapping[13] = PCM_CHANNEL_FRC;
ep_payload->dev_channel_mapping[14] = PCM_CHANNEL_RLC;
ep_payload->dev_channel_mapping[15] = PCM_CHANNEL_RRC;
+ } else if (channel_mode == 32) {
+ ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL;
+ ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR;
+ ep_payload->dev_channel_mapping[2] = PCM_CHANNEL_LFE;
+ ep_payload->dev_channel_mapping[3] = PCM_CHANNEL_FC;
+ ep_payload->dev_channel_mapping[4] = PCM_CHANNEL_LS;
+ ep_payload->dev_channel_mapping[5] = PCM_CHANNEL_RS;
+ ep_payload->dev_channel_mapping[6] = PCM_CHANNEL_LB;
+ ep_payload->dev_channel_mapping[7] = PCM_CHANNEL_RB;
+ ep_payload->dev_channel_mapping[8] = PCM_CHANNEL_CS;
+ ep_payload->dev_channel_mapping[9] = PCM_CHANNELS;
+ ep_payload->dev_channel_mapping[10] = PCM_CHANNEL_CVH;
+ ep_payload->dev_channel_mapping[11] = PCM_CHANNEL_MS;
+ ep_payload->dev_channel_mapping[12] = PCM_CHANNEL_FLC;
+ ep_payload->dev_channel_mapping[13] = PCM_CHANNEL_FRC;
+ ep_payload->dev_channel_mapping[14] = PCM_CHANNEL_RLC;
+ ep_payload->dev_channel_mapping[15] = PCM_CHANNEL_RRC;
+ ep_payload->dev_channel_mapping[16] = PCM_CHANNEL_LFE2;
+ ep_payload->dev_channel_mapping[17] = PCM_CHANNEL_SL;
+ ep_payload->dev_channel_mapping[18] = PCM_CHANNEL_SR;
+ ep_payload->dev_channel_mapping[19] = PCM_CHANNEL_TFL;
+ ep_payload->dev_channel_mapping[20] = PCM_CHANNEL_TFR;
+ ep_payload->dev_channel_mapping[21] = PCM_CHANNEL_TC;
+ ep_payload->dev_channel_mapping[22] = PCM_CHANNEL_TBL;
+ ep_payload->dev_channel_mapping[23] = PCM_CHANNEL_TBR;
+ ep_payload->dev_channel_mapping[24] = PCM_CHANNEL_TSL;
+ ep_payload->dev_channel_mapping[25] = PCM_CHANNEL_TSR;
+ ep_payload->dev_channel_mapping[26] = PCM_CHANNEL_TBC;
+ ep_payload->dev_channel_mapping[27] = PCM_CHANNEL_BFC;
+ ep_payload->dev_channel_mapping[28] = PCM_CHANNEL_BFL;
+ ep_payload->dev_channel_mapping[29] = PCM_CHANNEL_BFR;
+ ep_payload->dev_channel_mapping[30] = PCM_CHANNEL_LW;
+ ep_payload->dev_channel_mapping[31] = PCM_CHANNEL_RW;
} else {
pr_err("%s: invalid num_chan %d\n", __func__,
channel_mode);
@@ -2866,6 +2899,39 @@
ep_payload->dev_channel_mapping[13] = PCM_CHANNEL_FRC;
ep_payload->dev_channel_mapping[14] = PCM_CHANNEL_RLC;
ep_payload->dev_channel_mapping[15] = PCM_CHANNEL_RRC;
+ } else if (channel_mode == 32) {
+ ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL;
+ ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR;
+ ep_payload->dev_channel_mapping[2] = PCM_CHANNEL_LFE;
+ ep_payload->dev_channel_mapping[3] = PCM_CHANNEL_FC;
+ ep_payload->dev_channel_mapping[4] = PCM_CHANNEL_LS;
+ ep_payload->dev_channel_mapping[5] = PCM_CHANNEL_RS;
+ ep_payload->dev_channel_mapping[6] = PCM_CHANNEL_LB;
+ ep_payload->dev_channel_mapping[7] = PCM_CHANNEL_RB;
+ ep_payload->dev_channel_mapping[8] = PCM_CHANNEL_CS;
+ ep_payload->dev_channel_mapping[9] = PCM_CHANNELS;
+ ep_payload->dev_channel_mapping[10] = PCM_CHANNEL_CVH;
+ ep_payload->dev_channel_mapping[11] = PCM_CHANNEL_MS;
+ ep_payload->dev_channel_mapping[12] = PCM_CHANNEL_FLC;
+ ep_payload->dev_channel_mapping[13] = PCM_CHANNEL_FRC;
+ ep_payload->dev_channel_mapping[14] = PCM_CHANNEL_RLC;
+ ep_payload->dev_channel_mapping[15] = PCM_CHANNEL_RRC;
+ ep_payload->dev_channel_mapping[16] = PCM_CHANNEL_LFE2;
+ ep_payload->dev_channel_mapping[17] = PCM_CHANNEL_SL;
+ ep_payload->dev_channel_mapping[18] = PCM_CHANNEL_SR;
+ ep_payload->dev_channel_mapping[19] = PCM_CHANNEL_TFL;
+ ep_payload->dev_channel_mapping[20] = PCM_CHANNEL_TFR;
+ ep_payload->dev_channel_mapping[21] = PCM_CHANNEL_TC;
+ ep_payload->dev_channel_mapping[22] = PCM_CHANNEL_TBL;
+ ep_payload->dev_channel_mapping[23] = PCM_CHANNEL_TBR;
+ ep_payload->dev_channel_mapping[24] = PCM_CHANNEL_TSL;
+ ep_payload->dev_channel_mapping[25] = PCM_CHANNEL_TSR;
+ ep_payload->dev_channel_mapping[26] = PCM_CHANNEL_TBC;
+ ep_payload->dev_channel_mapping[27] = PCM_CHANNEL_BFC;
+ ep_payload->dev_channel_mapping[28] = PCM_CHANNEL_BFL;
+ ep_payload->dev_channel_mapping[29] = PCM_CHANNEL_BFR;
+ ep_payload->dev_channel_mapping[30] = PCM_CHANNEL_LW;
+ ep_payload->dev_channel_mapping[31] = PCM_CHANNEL_RW;
} else {
pr_err("%s: invalid num_chan %d\n", __func__,
channel_mode);
diff --git a/dsp/q6afe.c b/dsp/q6afe.c
index 87b2c58..959eb61 100644
--- a/dsp/q6afe.c
+++ b/dsp/q6afe.c
@@ -2788,6 +2788,85 @@
return ret;
}
+int afe_send_slot_mapping_cfg_v2(
+ struct afe_param_id_slot_mapping_cfg_v2 *slot_mapping_cfg,
+ u16 port_id)
+{
+ struct afe_slot_mapping_config_command_v2 config;
+ int ret = 0;
+ int index = 0;
+
+ if (!slot_mapping_cfg) {
+ pr_err("%s: Error, no configuration data\n", __func__);
+ return -EINVAL;
+ }
+
+ pr_debug("%s: port id: 0x%x\n", __func__, port_id);
+
+ index = q6audio_get_port_index(port_id);
+ if (index < 0 || index >= AFE_MAX_PORTS) {
+ pr_err("%s: AFE port index[%d] invalid!\n",
+ __func__, index);
+ return -EINVAL;
+ }
+ ret = q6audio_validate_port(port_id);
+ if (ret < 0) {
+ pr_err("%s: port id: 0x%x ret %d\n", __func__, port_id, ret);
+ return -EINVAL;
+ }
+
+ memset(&config, 0, sizeof(config));
+ config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
+ APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
+ config.hdr.pkt_size = sizeof(config);
+ config.hdr.src_port = 0;
+ config.hdr.dest_port = 0;
+ config.hdr.token = index;
+
+ config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
+ config.param.port_id = q6audio_get_port_id(port_id);
+ config.param.payload_size = sizeof(config)
+ - sizeof(struct apr_hdr) - sizeof(config.param);
+ config.param.payload_address_lsw = 0x00;
+ config.param.payload_address_msw = 0x00;
+ config.param.mem_map_handle = 0x00;
+ config.pdata.module_id = AFE_MODULE_TDM;
+ config.pdata.param_id = AFE_PARAM_ID_PORT_SLOT_MAPPING_CONFIG;
+ config.pdata.param_size = sizeof(config.slot_mapping);
+ config.slot_mapping = *slot_mapping_cfg;
+
+ atomic_set(&this_afe.state, 1);
+ atomic_set(&this_afe.status, 0);
+ ret = apr_send_pkt(this_afe.apr, (uint32_t *) &config);
+ if (ret < 0) {
+ pr_err("%s: AFE send slot mapping for port 0x%x failed ret = %d\n",
+ __func__, port_id, ret);
+ ret = -EINVAL;
+ goto fail_cmd;
+ }
+
+ ret = wait_event_timeout(this_afe.wait[index],
+ (atomic_read(&this_afe.state) == 0),
+ msecs_to_jiffies(TIMEOUT_MS));
+ if (!ret) {
+ pr_err("%s: wait_event timeout\n",
+ __func__);
+ ret = -EINVAL;
+ goto fail_cmd;
+ }
+ if (atomic_read(&this_afe.status) > 0) {
+ pr_err("%s: config cmd failed [%s]\n",
+ __func__, adsp_err_get_err_str(
+ atomic_read(&this_afe.status)));
+ ret = adsp_err_get_lnx_err_code(
+ atomic_read(&this_afe.status));
+ goto fail_cmd;
+ }
+
+fail_cmd:
+ return ret;
+}
+
/**
* afe_tdm_port_start - to configure AFE session with
* specified port configuration
@@ -2905,8 +2984,15 @@
goto fail_cmd;
}
- ret = afe_send_slot_mapping_cfg(&tdm_port->slot_mapping,
- port_id);
+ if (q6core_get_avcs_api_version_per_service(
+ APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V3)
+ ret = afe_send_slot_mapping_cfg_v2(
+ &tdm_port->slot_mapping_v2, port_id);
+ else
+ ret = afe_send_slot_mapping_cfg(
+ &tdm_port->slot_mapping,
+ port_id);
+
if (ret < 0) {
pr_err("%s: afe send failed %d\n", __func__, ret);
goto fail_cmd;
diff --git a/dsp/q6asm.c b/dsp/q6asm.c
index f55f584..80aa2a6 100644
--- a/dsp/q6asm.c
+++ b/dsp/q6asm.c
@@ -5292,6 +5292,39 @@
lchannel_mapping[13] = PCM_CHANNEL_FRC;
lchannel_mapping[14] = PCM_CHANNEL_RLC;
lchannel_mapping[15] = PCM_CHANNEL_RRC;
+ } else if (channels == 32) {
+ lchannel_mapping[0] = PCM_CHANNEL_FL;
+ lchannel_mapping[1] = PCM_CHANNEL_FR;
+ lchannel_mapping[2] = PCM_CHANNEL_LFE;
+ lchannel_mapping[3] = PCM_CHANNEL_FC;
+ lchannel_mapping[4] = PCM_CHANNEL_LS;
+ lchannel_mapping[5] = PCM_CHANNEL_RS;
+ lchannel_mapping[6] = PCM_CHANNEL_LB;
+ lchannel_mapping[7] = PCM_CHANNEL_RB;
+ lchannel_mapping[8] = PCM_CHANNEL_CS;
+ lchannel_mapping[9] = PCM_CHANNELS;
+ lchannel_mapping[10] = PCM_CHANNEL_CVH;
+ lchannel_mapping[11] = PCM_CHANNEL_MS;
+ lchannel_mapping[12] = PCM_CHANNEL_FLC;
+ lchannel_mapping[13] = PCM_CHANNEL_FRC;
+ lchannel_mapping[14] = PCM_CHANNEL_RLC;
+ lchannel_mapping[15] = PCM_CHANNEL_RRC;
+ lchannel_mapping[16] = PCM_CHANNEL_LFE2;
+ lchannel_mapping[17] = PCM_CHANNEL_SL;
+ lchannel_mapping[18] = PCM_CHANNEL_SR;
+ lchannel_mapping[19] = PCM_CHANNEL_TFL;
+ lchannel_mapping[20] = PCM_CHANNEL_TFR;
+ lchannel_mapping[21] = PCM_CHANNEL_TC;
+ lchannel_mapping[22] = PCM_CHANNEL_TBL;
+ lchannel_mapping[23] = PCM_CHANNEL_TBR;
+ lchannel_mapping[24] = PCM_CHANNEL_TSL;
+ lchannel_mapping[25] = PCM_CHANNEL_TSR;
+ lchannel_mapping[26] = PCM_CHANNEL_TBC;
+ lchannel_mapping[27] = PCM_CHANNEL_BFC;
+ lchannel_mapping[28] = PCM_CHANNEL_BFL;
+ lchannel_mapping[29] = PCM_CHANNEL_BFR;
+ lchannel_mapping[30] = PCM_CHANNEL_LW;
+ lchannel_mapping[31] = PCM_CHANNEL_RW;
} else {
pr_err("%s: ERROR.unsupported num_ch = %u\n",
__func__, channels);
diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h
index ef24f63..308a5c8 100644
--- a/include/dsp/apr_audio-v2.h
+++ b/include/dsp/apr_audio-v2.h
@@ -2587,6 +2587,8 @@
#define AFE_PORT_MAX_AUDIO_CHAN_CNT 0x8
+#define AFE_PORT_MAX_AUDIO_CHAN_CNT_V2 0x20
+
/* Payload of the #AFE_PORT_CMD_SLIMBUS_CONFIG command's SLIMbus
* port configuration parameter.
*/
@@ -3059,6 +3061,10 @@
*/
#define AFE_API_VERSION_SLOT_MAPPING_CONFIG 0x1
+/** Version information used to handle future additions to slot mapping
+* configuration support 32 channels.
+*/
+#define AFE_API_VERSION_SLOT_MAPPING_CONFIG_V2 0x2
/* Data align type */
#define AFE_SLOT_MAPPING_DATA_ALIGN_MSB 0
#define AFE_SLOT_MAPPING_DATA_ALIGN_LSB 1
@@ -3108,9 +3114,52 @@
*/
} __packed;
-/* ID of the parameter used by #AFE_MODULE_TDM to configure
- * the customer TDM header. #AFE_PORT_CMD_SET_PARAM can use this parameter ID.
- */
+/* Payload of the AFE_PARAM_ID_PORT_SLOT_MAPPING_CONFIG_V2
+* command's TDM configuration parameter.
+*/
+struct afe_param_id_slot_mapping_cfg_v2 {
+ u32 minor_version;
+ /**< Minor version used for tracking TDM slot configuration.
+ * @values #AFE_API_VERSION_TDM_SLOT_CONFIG
+ */
+
+ u16 num_channel;
+ /**< number of channel of the audio sample.
+ * @values 1, 2, 4, 6, 8, 16, 32 @tablebulletend
+ */
+
+ u16 bitwidth;
+ /**< Slot bit width for each channel
+ * @values 16, 24, 32
+ */
+
+ u32 data_align_type;
+ /**< indicate how data packed from slot_offset for 32 slot bit width
+ * in case of sample bit width is 24.
+ * @values
+ * #AFE_SLOT_MAPPING_DATA_ALIGN_MSB
+ * #AFE_SLOT_MAPPING_DATA_ALIGN_LSB
+ */
+
+ u16 offset[AFE_PORT_MAX_AUDIO_CHAN_CNT_V2];
+ /**< Array of the slot mapping start offset in bytes for this frame.
+ * The bytes is counted from 0. The 0 is mapped to the 1st byte
+ * in or out of the digital serial data line this sub-frame belong to.
+ * slot_offset[] setting is per-channel based.
+ * The max num of channel supported is 8.
+ * The valid offset value must always be continuly placed in
+ * from index 0.
+ * Set offset as AFE_SLOT_MAPPING_OFFSET_INVALID for not used arrays.
+ * If "slot_bitwidth_per_channel" is 32 and "sample_bitwidth" is 24,
+ * "data_align_type" is used to indicate how 24 bit sample data in
+ * aligning with 32 bit slot width per-channel.
+ * @values, in byte
+ */
+} __packed;
+
+/** ID of the parameter used by #AFE_MODULE_TDM to configure
+ the customer TDM header. #AFE_PORT_CMD_SET_PARAM can use this parameter ID.
+*/
#define AFE_PARAM_ID_CUSTOM_TDM_HEADER_CONFIG 0x00010298
/* Version information used to handle future additions to custom TDM header
@@ -3182,6 +3231,13 @@
struct afe_param_id_slot_mapping_cfg slot_mapping;
} __packed;
+struct afe_slot_mapping_config_command_v2 {
+ struct apr_hdr hdr;
+ struct afe_port_cmd_set_param_v2 param;
+ struct afe_port_param_data_v2 pdata;
+ struct afe_param_id_slot_mapping_cfg_v2 slot_mapping;
+} __packed;
+
struct afe_custom_tdm_header_config_command {
struct apr_hdr hdr;
struct afe_port_cmd_set_param_v2 param;
@@ -3192,6 +3248,7 @@
struct afe_tdm_port_config {
struct afe_param_id_tdm_cfg tdm;
struct afe_param_id_slot_mapping_cfg slot_mapping;
+ struct afe_param_id_slot_mapping_cfg_v2 slot_mapping_v2;
struct afe_param_id_custom_tdm_header_cfg custom_tdm_header;
} __packed;
@@ -9904,6 +9961,7 @@
#define AVCS_SERVICE_ID_ALL (0xFFFFFFFF)
#define AVCS_SERVICE_ID_AFE (0x4)
#define APRV2_IDS_SERVICE_ID_ADSP_CVP_V (0xB)
+#define APRV2_IDS_SERVICE_ID_ADSP_AFE_V (0x4)
struct avcs_get_fwk_version {
/*
diff --git a/include/dsp/q6afe-v2.h b/include/dsp/q6afe-v2.h
index 45bcfd4..4360a61 100644
--- a/include/dsp/q6afe-v2.h
+++ b/include/dsp/q6afe-v2.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -42,6 +42,7 @@
#define AFE_CLK_VERSION_V1 1
#define AFE_CLK_VERSION_V2 2
#define AFE_API_VERSION_SUPPORT_SPV3 2
+#define AFE_API_VERSION_V3 3
typedef int (*routing_cb)(int port);
enum {