audio: enable 5.1.2 channel mask configuration
- Support query of DP max channels.
- Enable 5.1.2 channel mask configuration.
Change-Id: I0fa6f50fc21189b539ec963f35bd627d4bd261da
diff --git a/hal/edid.c b/hal/edid.c
index f7259c7..175842f 100644
--- a/hal/edid.c
+++ b/hal/edid.c
@@ -388,7 +388,9 @@
{
if (!info)
return;
- if (info->channel_allocation < 0 || info->channel_allocation > 0x1f) {
+ if (((info->channel_allocation < 0) ||
+ (info->channel_allocation > 0x1f)) &&
+ (info->channel_allocation != 0x2f)) {
ALOGE("Channel allocation out of supported range");
return;
}
@@ -631,6 +633,16 @@
info->channel_map[6] = PCM_CHANNEL_FLC;
info->channel_map[7] = PCM_CHANNEL_FRC;
break;
+ case 0x2f:
+ info->channel_map[0] = PCM_CHANNEL_FL;
+ info->channel_map[1] = PCM_CHANNEL_FR;
+ info->channel_map[2] = PCM_CHANNEL_LFE;
+ info->channel_map[3] = PCM_CHANNEL_FC;
+ info->channel_map[4] = PCM_CHANNEL_LS;
+ info->channel_map[5] = PCM_CHANNEL_RS;
+ info->channel_map[6] = 0; // PCM_CHANNEL_TFL; but not defined by LPASS
+ info->channel_map[7] = 0; // PCM_CHANNEL_TFR; but not defined by LPASS
+ break;
default:
break;
}
@@ -640,6 +652,180 @@
, info->channel_map[6], info->channel_map[7]);
}
+
+static void update_channel_mask(edid_audio_info* info)
+{
+ if (!info)
+ return;
+ if (((info->channel_allocation < 0) ||
+ (info->channel_allocation > 0x1f)) &&
+ (info->channel_allocation != 0x2f)) {
+ ALOGE("Channel allocation out of supported range");
+ return;
+ }
+ ALOGV("channel_allocation 0x%x", info->channel_allocation);
+ // Don't distinguish channel mask below?
+ // AUDIO_CHANNEL_OUT_5POINT1 and AUDIO_CHANNEL_OUT_5POINT1_SIDE
+ // AUDIO_CHANNEL_OUT_QUAD and AUDIO_CHANNEL_OUT_QUAD_SIDE
+ switch(info->channel_allocation) {
+ case 0x0:
+ info->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
+ break;
+ case 0x1:
+ info->channel_mask = AUDIO_CHANNEL_OUT_2POINT1;
+ break;
+ case 0x2:
+ info->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
+ info->channel_mask |= AUDIO_CHANNEL_OUT_FRONT_CENTER;
+ break;
+ case 0x3:
+ info->channel_mask = AUDIO_CHANNEL_OUT_2POINT1;
+ info->channel_mask |= AUDIO_CHANNEL_OUT_FRONT_CENTER;
+ break;
+ case 0x4:
+ info->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
+ info->channel_mask |= AUDIO_CHANNEL_OUT_BACK_CENTER;
+ break;
+ case 0x5:
+ info->channel_mask = AUDIO_CHANNEL_OUT_2POINT1;
+ info->channel_mask |= AUDIO_CHANNEL_OUT_LOW_FREQUENCY;
+ info->channel_mask |= AUDIO_CHANNEL_OUT_BACK_CENTER;
+ break;
+ case 0x6:
+ info->channel_mask = AUDIO_CHANNEL_OUT_SURROUND;
+ break;
+ case 0x7:
+ info->channel_mask = AUDIO_CHANNEL_OUT_SURROUND;
+ info->channel_mask |= AUDIO_CHANNEL_OUT_LOW_FREQUENCY;
+ break;
+ case 0x8:
+ info->channel_mask = AUDIO_CHANNEL_OUT_QUAD;
+ break;
+ case 0x9:
+ info->channel_mask = AUDIO_CHANNEL_OUT_QUAD;
+ info->channel_mask |= AUDIO_CHANNEL_OUT_LOW_FREQUENCY;
+ break;
+ case 0xa:
+ info->channel_mask = AUDIO_CHANNEL_OUT_PENTA;
+ break;
+ case 0xb:
+ info->channel_mask = AUDIO_CHANNEL_OUT_5POINT1;
+ break;
+ case 0xc:
+ info->channel_mask = AUDIO_CHANNEL_OUT_QUAD;
+ info->channel_mask |= AUDIO_CHANNEL_OUT_BACK_CENTER;
+ break;
+ case 0xd:
+ info->channel_mask = AUDIO_CHANNEL_OUT_QUAD;
+ info->channel_mask |= AUDIO_CHANNEL_OUT_LOW_FREQUENCY;
+ info->channel_mask |= AUDIO_CHANNEL_OUT_BACK_CENTER;
+ break;
+ case 0xe:
+ info->channel_mask = AUDIO_CHANNEL_OUT_PENTA;
+ info->channel_mask |= AUDIO_CHANNEL_OUT_BACK_CENTER;
+ break;
+ case 0xf:
+ info->channel_mask = AUDIO_CHANNEL_OUT_5POINT1;
+ info->channel_mask |= AUDIO_CHANNEL_OUT_BACK_CENTER;
+ break;
+ case 0x10:
+ info->channel_mask = AUDIO_CHANNEL_OUT_QUAD;
+ info->channel_mask |= AUDIO_CHANNEL_OUT_SIDE_LEFT;
+ info->channel_mask |= AUDIO_CHANNEL_OUT_SIDE_RIGHT;
+ break;
+ case 0x11:
+ info->channel_mask = AUDIO_CHANNEL_OUT_QUAD;
+ info->channel_mask |= AUDIO_CHANNEL_OUT_LOW_FREQUENCY;
+ info->channel_mask |= AUDIO_CHANNEL_OUT_SIDE_LEFT;
+ info->channel_mask |= AUDIO_CHANNEL_OUT_SIDE_RIGHT;
+ break;
+ case 0x12:
+ info->channel_mask = AUDIO_CHANNEL_OUT_QUAD;
+ info->channel_mask |= AUDIO_CHANNEL_OUT_FRONT_CENTER;
+ info->channel_mask |= AUDIO_CHANNEL_OUT_SIDE_LEFT;
+ info->channel_mask |= AUDIO_CHANNEL_OUT_SIDE_RIGHT;
+ break;
+ case 0x13:
+ info->channel_mask = AUDIO_CHANNEL_OUT_7POINT1;
+ break;
+ case 0x14:
+ info->channel_mask = AUDIO_CHANNEL_OUT_FRONT_LEFT;
+ info->channel_mask |= AUDIO_CHANNEL_OUT_FRONT_RIGHT;
+ info->channel_mask |= AUDIO_CHANNEL_OUT_FRONT_LEFT_OF_CENTER;
+ info->channel_mask |= AUDIO_CHANNEL_OUT_FRONT_RIGHT_OF_CENTER;
+ break;
+ case 0x15:
+ info->channel_mask = AUDIO_CHANNEL_OUT_2POINT1;
+ info->channel_mask |= AUDIO_CHANNEL_OUT_FRONT_LEFT_OF_CENTER;
+ info->channel_mask |= AUDIO_CHANNEL_OUT_FRONT_RIGHT_OF_CENTER;
+ break;
+ case 0x16:
+ info->channel_mask = AUDIO_CHANNEL_OUT_FRONT_LEFT;
+ info->channel_mask |= AUDIO_CHANNEL_OUT_FRONT_RIGHT;
+ info->channel_mask |= AUDIO_CHANNEL_OUT_FRONT_CENTER;
+ info->channel_mask |= AUDIO_CHANNEL_OUT_FRONT_LEFT_OF_CENTER;
+ info->channel_mask |= AUDIO_CHANNEL_OUT_FRONT_RIGHT_OF_CENTER;
+ break;
+ case 0x17:
+ info->channel_mask = AUDIO_CHANNEL_OUT_2POINT1;
+ info->channel_mask |= AUDIO_CHANNEL_OUT_FRONT_CENTER;
+ info->channel_mask |= AUDIO_CHANNEL_OUT_FRONT_LEFT_OF_CENTER;
+ info->channel_mask |= AUDIO_CHANNEL_OUT_FRONT_RIGHT_OF_CENTER;
+ break;
+ case 0x18:
+ info->channel_mask = AUDIO_CHANNEL_OUT_FRONT_LEFT;
+ info->channel_mask |= AUDIO_CHANNEL_OUT_FRONT_RIGHT;
+ info->channel_mask |= AUDIO_CHANNEL_OUT_BACK_CENTER;
+ info->channel_mask |= AUDIO_CHANNEL_OUT_FRONT_LEFT_OF_CENTER;
+ info->channel_mask |= AUDIO_CHANNEL_OUT_FRONT_RIGHT_OF_CENTER;
+ break;
+ case 0x19:
+ info->channel_mask = AUDIO_CHANNEL_OUT_2POINT1;
+ info->channel_mask |= AUDIO_CHANNEL_OUT_BACK_CENTER;
+ info->channel_mask |= AUDIO_CHANNEL_OUT_FRONT_LEFT_OF_CENTER;
+ info->channel_mask |= AUDIO_CHANNEL_OUT_FRONT_RIGHT_OF_CENTER;
+ break;
+ case 0x1a:
+ info->channel_mask = AUDIO_CHANNEL_OUT_SURROUND;
+ info->channel_mask |= AUDIO_CHANNEL_OUT_FRONT_LEFT_OF_CENTER;
+ info->channel_mask |= AUDIO_CHANNEL_OUT_FRONT_RIGHT_OF_CENTER;
+ break;
+ case 0x1b:
+ info->channel_mask = AUDIO_CHANNEL_OUT_SURROUND;
+ info->channel_mask |= AUDIO_CHANNEL_OUT_LOW_FREQUENCY;
+ info->channel_mask |= AUDIO_CHANNEL_OUT_FRONT_LEFT_OF_CENTER;
+ info->channel_mask |= AUDIO_CHANNEL_OUT_FRONT_RIGHT_OF_CENTER;
+ break;
+ case 0x1c:
+ info->channel_mask = AUDIO_CHANNEL_OUT_QUAD;
+ info->channel_mask |= AUDIO_CHANNEL_OUT_FRONT_LEFT_OF_CENTER;
+ info->channel_mask |= AUDIO_CHANNEL_OUT_FRONT_RIGHT_OF_CENTER;
+ break;
+ case 0x1d:
+ info->channel_mask = AUDIO_CHANNEL_OUT_QUAD;
+ info->channel_mask |= AUDIO_CHANNEL_OUT_LOW_FREQUENCY;
+ info->channel_mask |= AUDIO_CHANNEL_OUT_FRONT_LEFT_OF_CENTER;
+ info->channel_mask |= AUDIO_CHANNEL_OUT_FRONT_RIGHT_OF_CENTER;
+ break;
+ case 0x1e:
+ info->channel_mask = AUDIO_CHANNEL_OUT_PENTA;
+ info->channel_mask |= AUDIO_CHANNEL_OUT_FRONT_LEFT_OF_CENTER;
+ info->channel_mask |= AUDIO_CHANNEL_OUT_FRONT_RIGHT_OF_CENTER;
+ break;
+ case 0x1f:
+ info->channel_mask = AUDIO_CHANNEL_OUT_5POINT1;
+ info->channel_mask |= AUDIO_CHANNEL_OUT_FRONT_LEFT_OF_CENTER;
+ info->channel_mask |= AUDIO_CHANNEL_OUT_FRONT_RIGHT_OF_CENTER;
+ break;
+ case 0x2f:
+ info->channel_mask = AUDIO_CHANNEL_OUT_5POINT1POINT2;
+ break;
+ default:
+ break;
+ }
+ ALOGD("%s channel mask updated to %d", __func__, info->channel_mask);
+}
+
static void dump_edid_data(edid_audio_info *info)
{
@@ -715,6 +901,7 @@
update_channel_map(info);
update_channel_allocation(info);
update_channel_map_lpass(info);
+ update_channel_mask(info);
for (i=0; i<info->audio_blocks; i++) {
ALOGV("AUDIO DESC BLOCK # %d\n",i);
diff --git a/hal/edid.h b/hal/edid.h
index da5c592..f97d0e3 100644
--- a/hal/edid.h
+++ b/hal/edid.h
@@ -57,6 +57,24 @@
#define PCM_CHANNEL_FRC 14 /* Front right of center. */
#define PCM_CHANNEL_RLC 15 /* Rear left of center. */
#define PCM_CHANNEL_RRC 16 /* Rear right of center. */
+#define PCM_CHANNEL_LFE2 17 /* Rear right of center. */
+#define PCM_CHANNEL_SL 18 /* Side left channel. */
+#define PCM_CHANNEL_SR 19 /* Side right channel */
+#define PCM_CHANNEL_TFL 20 /* Top front left channel. */
+#define PCM_CHANNEL_TFR 21 /* Top front right channel. */
+#define PCM_CHANNEL_TC 22 /* Top center channel. */
+#define PCM_CHANNEL_TBL 23 /* Top back left channel. */
+#define PCM_CHANNEL_TBR 24 /* Top back right channel. */
+#define PCM_CHANNEL_TSL 25 /* Top side left channel */
+#define PCM_CHANNEL_TSR 26 /* Top side right channel. */
+#define PCM_CHANNEL_TBC 27 /* Top back center channel. */
+#define PCM_CHANNEL_BFC 28 /* Bottom front center channel. */
+#define PCM_CHANNEL_BFL 29 /* Bottom front left channel. */
+#define PCM_CHANNEL_BFR 30 /* Bottom front right channel. */
+#define PCM_CHANNEL_LW 31 /* Left wide channel. */
+#define PCM_CHANNEL_RW 32 /* Right wide channel. */
+#define PCM_CHANNEL_LSD 33 /* Left side direct channel. */
+#define PCM_CHANNEL_RSD 34 /* Right side direct channel. */
#define MAX_HDMI_CHANNEL_CNT 8
@@ -90,6 +108,7 @@
edid_audio_block_info audio_blocks_array[MAX_EDID_BLOCKS];
char channel_map[MAX_CHANNELS_SUPPORTED];
int channel_allocation;
+ unsigned int channel_mask;
} edid_audio_info;
#ifdef HDMI_EDID
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index e5e8c19..1d80893 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -5759,7 +5759,7 @@
my_data->current_backend_cfg[backend_idx].channels = channels;
if (backend_idx == HDMI_RX_BACKEND)
- platform_set_edid_channels_configuration(adev->platform, channels);
+ platform_set_edid_channels_configuration(adev->platform, channels, HDMI_RX_BACKEND);
ALOGD("%s:becf: afe: %s set to %s", __func__,
my_data->current_backend_cfg[backend_idx].channels_mixer_ctl, channel_cnt_str);
@@ -7091,7 +7091,7 @@
return false;
}
-int platform_set_edid_channels_configuration(void *platform, int channels) {
+int platform_set_edid_channels_configuration(void *platform, int channels, int backend_idx __unused) {
struct platform_data *my_data = (struct platform_data *)platform;
struct audio_device *adev = my_data->adev;
diff --git a/hal/msm8960/platform.c b/hal/msm8960/platform.c
index 7f33967..71090ca 100644
--- a/hal/msm8960/platform.c
+++ b/hal/msm8960/platform.c
@@ -1155,7 +1155,8 @@
}
int platform_set_edid_channels_configuration(void *platform __unused,
- int channels __unused)
+ int channels __unused,
+ int backend_idx __unused)
{
return 0;
}
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 02bac29..269c648 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -141,6 +141,7 @@
* device for voice usecase
*/
#define AUDIO_PARAMETER_KEY_DP_FOR_VOICE_USECASE "dp_for_voice"
+#define AUDIO_PARAMETER_KEY_DP_CHANNEL_MASK "dp_channel_mask"
#define EVENT_EXTERNAL_SPK_1 "qc_ext_spk_1"
#define EVENT_EXTERNAL_SPK_2 "qc_ext_spk_2"
@@ -5247,6 +5248,16 @@
str_parms_add_str(reply, AUDIO_PARAMETER_KEY_DP_FOR_VOICE_USECASE, value);
}
+ ret = str_parms_get_str(query, AUDIO_PARAMETER_KEY_DP_CHANNEL_MASK,
+ value, sizeof(value));
+ if (ret >= 0) {
+ ret = platform_get_edid_info(platform);
+ edid_audio_info *info = (edid_audio_info *)my_data->edid_info;
+ if (ret == 0 && info != NULL) {
+ str_parms_add_int(reply, AUDIO_PARAMETER_KEY_DP_CHANNEL_MASK, info->channel_mask);
+ }
+ }
+
/* Handle audio calibration keys */
get_audiocal(platform, query, reply);
native_audio_get_params(query, reply, value, sizeof(value));
@@ -5716,8 +5727,9 @@
mixer_ctl_set_enum_by_string(ctl, channel_cnt_str);
my_data->current_backend_cfg[backend_idx].channels = channels;
- if (backend_idx == HDMI_RX_BACKEND)
- platform_set_edid_channels_configuration(adev->platform, channels);
+ if ((backend_idx == HDMI_RX_BACKEND) ||
+ (backend_idx == DISP_PORT_RX_BACKEND))
+ platform_set_edid_channels_configuration(adev->platform, channels, backend_idx);
ALOGD("%s:becf: afe: %s set to %s ", __func__,
my_data->current_backend_cfg[backend_idx].channels_mixer_ctl,
@@ -6710,8 +6722,13 @@
channel_map[3] = PCM_CHANNEL_LFE;
channel_map[4] = PCM_CHANNEL_LB;
channel_map[5] = PCM_CHANNEL_RB;
- channel_map[6] = PCM_CHANNEL_LS;
- channel_map[7] = PCM_CHANNEL_RS;
+ if (channel_mask == AUDIO_CHANNEL_OUT_5POINT1POINT2) {
+ channel_map[6] = PCM_CHANNEL_TFL;
+ channel_map[7] = PCM_CHANNEL_TFR;
+ } else {
+ channel_map[6] = PCM_CHANNEL_LS;
+ channel_map[7] = PCM_CHANNEL_RS;
+ }
break;
default:
ALOGE("unsupported channels %d for setting channel map", channels);
@@ -7038,7 +7055,7 @@
return 0;
}
-int platform_set_edid_channels_configuration(void *platform, int channels) {
+int platform_set_edid_channels_configuration(void *platform, int channels, int backend_idx) {
struct platform_data *my_data = (struct platform_data *)platform;
struct audio_device *adev = my_data->adev;
@@ -7048,13 +7065,18 @@
char default_channelMap[MAX_CHANNELS_SUPPORTED] = {0};
struct audio_device_config_param *adev_device_cfg_ptr = adev->device_cfg_params;
+ if ((backend_idx != HDMI_RX_BACKEND) &&
+ (backend_idx != DISP_PORT_RX_BACKEND)) {
+ ALOGE("%s: Invalid backend idx %d", __func__, backend_idx);
+ return -EINVAL;
+ }
+
ret = platform_get_edid_info(platform);
info = (edid_audio_info *)my_data->edid_info;
- adev_device_cfg_ptr += HDMI_RX_BACKEND;
+ adev_device_cfg_ptr += backend_idx;
if(ret == 0 && info != NULL) {
if (channels > 2) {
-
- ALOGV("%s:able to get HDMI sink capabilities multi channel playback",
+ ALOGV("%s:able to get HDMI/DP sink capabilities multi channel playback",
__func__);
for (i = 0; i < info->audio_blocks && i < MAX_EDID_BLOCKS; i++) {
if (info->audio_blocks_array[i].format_id == LPCM &&
diff --git a/hal/platform_api.h b/hal/platform_api.h
index d487525..53a4888 100644
--- a/hal/platform_api.h
+++ b/hal/platform_api.h
@@ -213,7 +213,7 @@
int snd_id,
snd_device_t snd_device,
struct mix_matrix_params mm_params);
-int platform_set_edid_channels_configuration(void *platform, int channels);
+int platform_set_edid_channels_configuration(void *platform, int channels, int backend_idx);
unsigned char platform_map_to_edid_format(int format);
bool platform_is_edid_supported_format(void *platform, int format);
bool platform_is_edid_supported_sample_rate(void *platform, int sample_rate);