summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Mower <mowerm@gmail.com>2016-07-14 01:56:31 -0500
committerMatt Mower <mowerm@gmail.com>2016-07-26 02:06:45 -0500
commitf7451db8678b40e8a84899f67b4579acb29e2679 (patch)
treefc2b7ece1940a6a2f61b8853b6910ff1c2c802e1
parenta1225ab3224802d12b8cf5460d5b6153e4adcd2c (diff)
downloadhardware_qcom_audio-f7451db8678b40e8a84899f67b4579acb29e2679.tar.gz
hardware_qcom_audio-f7451db8678b40e8a84899f67b4579acb29e2679.tar.bz2
hardware_qcom_audio-f7451db8678b40e8a84899f67b4579acb29e2679.zip
hal: Add legacy EDID channel retrieval
Change-Id: I138a829f687c0de0ed8f4e1b1230aa67f96699fd
-rw-r--r--hal/msm8960/platform.c79
1 files changed, 79 insertions, 0 deletions
diff --git a/hal/msm8960/platform.c b/hal/msm8960/platform.c
index 5e2b6660..c5361368 100644
--- a/hal/msm8960/platform.c
+++ b/hal/msm8960/platform.c
@@ -1762,6 +1762,78 @@ int platform_set_hdmi_channels(void *platform, int channel_count)
return 0;
}
+/* Legacy EDID channel retrieval */
+#define MAX_EDID_BLOCKS 10
+#define MAX_SHORT_AUDIO_DESC_CNT 30
+#define MIN_AUDIO_DESC_LENGTH 3
+#define MAX_CHANNELS_SUPPORTED 8
+
+int legacy_edid_get_max_channels() {
+ unsigned char channels[16];
+ unsigned char* data = NULL;
+ int i = 0;
+ int count = 0;
+ int channel_count = 0;
+ int length = 0;
+ int nCountDesc = 0;
+ unsigned int sad[MAX_SHORT_AUDIO_DESC_CNT];
+
+ const char* file = "/sys/class/graphics/fb1/audio_data_block";
+ FILE* fpaudiocaps = fopen(file, "rb");
+ if (fpaudiocaps) {
+ ALOGV("%s: Opened audio_data_block successfully\n", __func__);
+ fseek(fpaudiocaps, 0, SEEK_END);
+ long size = ftell(fpaudiocaps);
+ ALOGV("%s: audio_data_block size is %ld\n", __func__, size);
+ data = (unsigned char*)malloc(size);
+ if (data) {
+ fseek(fpaudiocaps, 0, SEEK_SET);
+ fread(data, 1, size, fpaudiocaps);
+ }
+ fclose(fpaudiocaps);
+ } else {
+ ALOGE("%s: Failed to open audio_data_block", __func__);
+ return channel_count;
+ }
+
+ if (data) {
+ memcpy(&count, data, sizeof(int));
+ data += sizeof(int);
+ ALOGV("%s: Audio Block Count is %d\n", __func__, count);
+ memcpy(&length, data, sizeof(int));
+ data += sizeof(int);
+ ALOGV("%s: Total length is %d\n", __func__, length);
+
+ for (i = 0; length >= MIN_AUDIO_DESC_LENGTH
+ && count < MAX_SHORT_AUDIO_DESC_CNT; i++) {
+ sad[i] = (unsigned int)data[0]
+ + ((unsigned int)data[1] << 8)
+ + ((unsigned int)data[2] << 16);
+ nCountDesc++;
+ length -= MIN_AUDIO_DESC_LENGTH;
+ data += MIN_AUDIO_DESC_LENGTH;
+ }
+ ALOGV("%s: Total # of audio descriptors is %d\n",
+ __func__, nCountDesc);
+
+ for (i = 0; i < nCountDesc; i++)
+ channels[i] = (sad[i] & 0x7) + 1;
+
+ free(data);
+ }
+
+ for (i = 0; i < nCountDesc && i < MAX_EDID_BLOCKS; i++) {
+ if ((int)channels[i] > channel_count
+ && (int)channels[i] <= MAX_CHANNELS_SUPPORTED)
+ channel_count = (int)channels[i];
+ }
+
+ ALOGD("%s: Max channels reported by audio_data_block is: %d\n",
+ __func__, channel_count);
+
+ return channel_count;
+}
+
int platform_edid_get_max_channels(void *platform)
{
struct platform_data *my_data = (struct platform_data *)platform;
@@ -1777,6 +1849,13 @@ int platform_edid_get_max_channels(void *platform)
ctl = mixer_get_ctl_by_name(adev->mixer, AUDIO_DATA_BLOCK_MIXER_CTL);
if (!ctl) {
+ /* A-Family devices likely do not have HDMI EDID ctl,
+ * attempt fall-back to legacy sysfs EDID retrieval.
+ */
+ max_channels = legacy_edid_get_max_channels();
+ if (max_channels > 0)
+ return max_channels;
+
ALOGE("%s: Could not get ctl for mixer cmd - %s",
__func__, AUDIO_DATA_BLOCK_MIXER_CTL);
return 0;