hal: Add support for TrueHD HDMI pass-through
Add TrueHD format for apq8098 compress pass-through.
Change-Id: Ica0e11aee535c6f7e21c26ab391e5e7bb71c6b02
diff --git a/hal/audio_extn/passthru.c b/hal/audio_extn/passthru.c
index eaa8c0a..dd4d4d4 100644
--- a/hal/audio_extn/passthru.c
+++ b/hal/audio_extn/passthru.c
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -46,7 +46,8 @@
AUDIO_FORMAT_E_AC3,
AUDIO_FORMAT_E_AC3_JOC,
AUDIO_FORMAT_DTS,
- AUDIO_FORMAT_DTS_HD
+ AUDIO_FORMAT_DTS_HD,
+ AUDIO_FORMAT_DOLBY_TRUEHD
};
/*
@@ -216,6 +217,8 @@
bool passt = false;
switch (out->format) {
case AUDIO_FORMAT_E_AC3:
+ case AUDIO_FORMAT_DTS_HD:
+ case AUDIO_FORMAT_DOLBY_TRUEHD:
if (platform_is_edid_supported_format(adev->platform, out->format)) {
ALOGV("%s:PASSTHROUGH supported for format %x",
__func__, out->format);
@@ -249,13 +252,6 @@
passt = true;
}
break;
- case AUDIO_FORMAT_DTS_HD:
- if (platform_is_edid_supported_format(adev->platform, out->format)) {
- ALOGV("%s:PASSTHROUGH supported for format %x",
- __func__, out->format);
- passt = true;
- }
- break;
default:
ALOGV("%s:Passthrough not supported", __func__);
}
diff --git a/hal/audio_extn/qaf.c b/hal/audio_extn/qaf.c
index ed66934..caf64ee 100644
--- a/hal/audio_extn/qaf.c
+++ b/hal/audio_extn/qaf.c
@@ -351,7 +351,8 @@
case AUDIO_FORMAT_AC3:
case AUDIO_FORMAT_E_AC3:
case AUDIO_FORMAT_DTS:
- case AUDIO_FORMAT_DTS_HD: {
+ case AUDIO_FORMAT_DTS_HD:
+ case AUDIO_FORMAT_DOLBY_TRUEHD: {
is_enabled = true;
break;
}
diff --git a/hal/audio_extn/utils.c b/hal/audio_extn/utils.c
index b8be7aa..27bbae8 100644
--- a/hal/audio_extn/utils.c
+++ b/hal/audio_extn/utils.c
@@ -70,6 +70,10 @@
#define BASE_TABLE_SIZE 64
#define MAX_BASEINDEX_LEN 256
+#ifndef SND_AUDIOCODEC_TRUEHD
+#define SND_AUDIOCODEC_TRUEHD 0x00000023
+#endif
+
#ifdef AUDIO_EXTERNAL_HDMI_ENABLED
#define PROFESSIONAL (1<<0) /* 0 = consumer, 1 = professional */
#define NON_LPCM (1<<1) /* 0 = audio, 1 = non-audio */
@@ -130,6 +134,7 @@
STRING_TO_ENUM(AUDIO_FORMAT_E_AC3),
STRING_TO_ENUM(AUDIO_FORMAT_DTS),
STRING_TO_ENUM(AUDIO_FORMAT_DTS_HD),
+ STRING_TO_ENUM(AUDIO_FORMAT_DOLBY_TRUEHD),
#ifdef AUDIO_EXTN_FORMATS_ENABLED
STRING_TO_ENUM(AUDIO_FORMAT_E_AC3_JOC),
STRING_TO_ENUM(AUDIO_FORMAT_WMA),
@@ -900,7 +905,8 @@
app_type_cfg[len++] = app_type;
app_type_cfg[len++] = acdb_dev_id;
if (((usecase->stream.out->format == AUDIO_FORMAT_E_AC3) ||
- (usecase->stream.out->format == AUDIO_FORMAT_E_AC3_JOC))
+ (usecase->stream.out->format == AUDIO_FORMAT_E_AC3_JOC) ||
+ (usecase->stream.out->format == AUDIO_FORMAT_DOLBY_TRUEHD))
&& audio_extn_passthru_is_passthrough_stream(usecase->stream.out)) {
app_type_cfg[len++] = sample_rate * 4;
} else {
@@ -1246,6 +1252,9 @@
case AUDIO_FORMAT_DTS_HD:
id = SND_AUDIOCODEC_DTS;
break;
+ case AUDIO_FORMAT_DOLBY_TRUEHD:
+ id = SND_AUDIOCODEC_TRUEHD;
+ break;
case AUDIO_FORMAT_DSD:
id = SND_AUDIOCODEC_DSD;
break;
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 68a552d..de8b388 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -293,6 +293,7 @@
STRING_TO_ENUM(AUDIO_FORMAT_AC3),
STRING_TO_ENUM(AUDIO_FORMAT_E_AC3),
STRING_TO_ENUM(AUDIO_FORMAT_E_AC3_JOC),
+ STRING_TO_ENUM(AUDIO_FORMAT_DOLBY_TRUEHD),
STRING_TO_ENUM(AUDIO_FORMAT_DTS),
STRING_TO_ENUM(AUDIO_FORMAT_DTS_HD),
};
@@ -511,6 +512,7 @@
format == AUDIO_FORMAT_PCM_16_BIT ||
format == AUDIO_FORMAT_AC3 ||
format == AUDIO_FORMAT_E_AC3 ||
+ format == AUDIO_FORMAT_DOLBY_TRUEHD ||
format == AUDIO_FORMAT_DTS ||
format == AUDIO_FORMAT_DTS_HD ||
format == AUDIO_FORMAT_FLAC ||
@@ -1313,6 +1315,11 @@
out->supported_formats[i++] = AUDIO_FORMAT_E_AC3_JOC;
}
+ if (platform_is_edid_supported_format(out->dev->platform, AUDIO_FORMAT_DOLBY_TRUEHD)) {
+ ALOGV(":%s HDMI supports TRUE HD format", __func__);
+ out->supported_formats[i++] = AUDIO_FORMAT_DOLBY_TRUEHD;
+ }
+
if (platform_is_edid_supported_format(out->dev->platform, AUDIO_FORMAT_DTS)) {
ALOGV(":%s HDMI supports DTS format", __func__);
out->supported_formats[i++] = AUDIO_FORMAT_DTS;
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index 935bae3..2ab9408 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -5457,12 +5457,20 @@
channels = max_supported_channels;
} else {
- /*During pass through set default bit width and channels*/
- channels = DEFAULT_HDMI_OUT_CHANNELS;
+ /*During pass through set default bit width */
+ if (usecase->stream.out->format == AUDIO_FORMAT_DOLBY_TRUEHD)
+ channels = 8;
+ else
+ channels = DEFAULT_HDMI_OUT_CHANNELS;
+
if ((usecase->stream.out->format == AUDIO_FORMAT_E_AC3) ||
- (usecase->stream.out->format == AUDIO_FORMAT_E_AC3_JOC))
+ (usecase->stream.out->format == AUDIO_FORMAT_E_AC3_JOC) ||
+ (usecase->stream.out->format == AUDIO_FORMAT_DOLBY_TRUEHD))
sample_rate = sample_rate * 4 ;
+ if (!edid_is_supported_sr(edid_info, sample_rate))
+ sample_rate = edid_get_highest_supported_sr(edid_info);
+
bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
/* We force route so that the BE format can be set to Compr */
}
@@ -6301,6 +6309,10 @@
ALOGV("%s:E_AC3", __func__);
format = DOLBY_DIGITAL_PLUS;
break;
+ case AUDIO_FORMAT_DOLBY_TRUEHD:
+ ALOGV("%s:MAT", __func__);
+ format = MAT;
+ break;
case AUDIO_FORMAT_DTS:
ALOGV("%s:DTS", __func__);
format = DTS;
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 1d32409..8f7e125 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -5175,12 +5175,20 @@
channels = max_supported_channels;
} else {
- /*During pass through set default bit width and channels*/
- channels = DEFAULT_HDMI_OUT_CHANNELS;
+ /*During pass through set default bit width */
+ if (usecase->stream.out->format == AUDIO_FORMAT_DOLBY_TRUEHD)
+ channels = 8;
+ else
+ channels = DEFAULT_HDMI_OUT_CHANNELS;
+
if ((usecase->stream.out->format == AUDIO_FORMAT_E_AC3) ||
- (usecase->stream.out->format == AUDIO_FORMAT_E_AC3_JOC))
+ (usecase->stream.out->format == AUDIO_FORMAT_E_AC3_JOC) ||
+ (usecase->stream.out->format == AUDIO_FORMAT_DOLBY_TRUEHD))
sample_rate = sample_rate * 4 ;
+ if (!edid_is_supported_sr(edid_info, sample_rate))
+ sample_rate = edid_get_highest_supported_sr(edid_info);
+
bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
/* We force route so that the BE format can be set to Compr */
}
@@ -5970,6 +5978,10 @@
ALOGV("%s:E_AC3", __func__);
format = DOLBY_DIGITAL_PLUS;
break;
+ case AUDIO_FORMAT_DOLBY_TRUEHD:
+ ALOGV("%s:MAT", __func__);
+ format = MAT;
+ break;
case AUDIO_FORMAT_DTS:
ALOGV("%s:DTS", __func__);
format = DTS;
diff --git a/qahw_api/test/qahw_playback_test.c b/qahw_api/test/qahw_playback_test.c
index 1f65368..9fe713d 100644
--- a/qahw_api/test/qahw_playback_test.c
+++ b/qahw_api/test/qahw_playback_test.c
@@ -77,7 +77,8 @@
FILE_EAC3_JOC,
FILE_DTS,
FILE_MP2,
- FILE_APTX
+ FILE_APTX,
+ FILE_TRUEHD
};
typedef enum {
@@ -962,6 +963,9 @@
case FILE_APTX:
stream_info->config.offload_info.format = AUDIO_FORMAT_APTX;
break;
+ case FILE_TRUEHD:
+ stream_info->config.offload_info.format = AUDIO_FORMAT_DOLBY_TRUEHD;
+ break;
default:
fprintf(log_file, "Does not support given filetype\n");
fprintf(stderr, "Does not support given filetype\n");