Fugu audio HAL: support ENCODING_IEC61937

Report support for AUDIO_FORMAT_IEC61937.
Allow IEC61937 streams to be opened.

Bug: 24541671
Bug: 20891646
Bug: 26373761
Change-Id: I87570981259190edfca97c2a4adbdb26fb755c5d
Signed-off-by: Phil Burk <philburk@google.com>
diff --git a/libaudio/AudioOutput.cpp b/libaudio/AudioOutput.cpp
index e86a5ea..72c39b5 100644
--- a/libaudio/AudioOutput.cpp
+++ b/libaudio/AudioOutput.cpp
@@ -432,6 +432,7 @@
 
     int err = BAD_VALUE;
     switch(format) {
+    case AUDIO_FORMAT_IEC61937:
     case AUDIO_FORMAT_PCM_16_BIT: {
         const size_t outputSize = len * 2;
         if (outputSize > mStagingSize) {
diff --git a/libaudio/AudioStreamOut.cpp b/libaudio/AudioStreamOut.cpp
index 0ae8e3b..53a13ef 100644
--- a/libaudio/AudioStreamOut.cpp
+++ b/libaudio/AudioStreamOut.cpp
@@ -97,7 +97,7 @@
     if (pChannels) *pChannels = lChannels;
     if (pRate)     *pRate     = lRate;
 
-    if (!audio_is_linear_pcm(lFormat)) {
+    if (!audio_has_proportional_frames(lFormat)) {
         ALOGW("set: format 0x%08X needs to be wrapped in SPDIF data burst", lFormat);
         return BAD_VALUE;
     }
diff --git a/libaudio/alsa_utils.cpp b/libaudio/alsa_utils.cpp
index 81e7355..2062cf6 100644
--- a/libaudio/alsa_utils.cpp
+++ b/libaudio/alsa_utils.cpp
@@ -256,11 +256,11 @@
         return;
     }
 
+    // These names must match formats in android.media.AudioFormat
     fmts.append("AUDIO_FORMAT_PCM_16_BIT|AUDIO_FORMAT_PCM_8_24_BIT");
     // TODO: when we can start to expect 20 and 24 bit audio modes coming from
     // AF, we need to implement support to enumerate those modes.
 
-    // These names must match formats in android.media.AudioFormat
     for (size_t i = 0; i < mModes.size(); ++i) {
         switch (mModes[i].fmt) {
             case kFmtAC3:
@@ -279,6 +279,8 @@
                 break;
         }
     }
+    // HDMI supports IEC61937 S/PDIF audio wrapper.
+    fmts.append("|AUDIO_FORMAT_IEC61937");
 
 #if ALSA_UTILS_PRINT_FORMATS
     ALOGI("ALSAFORMATS: formats = %s", fmts.string());
@@ -367,13 +369,19 @@
         return false;
 
     AudFormat alsaFormat;
-    switch (format & AUDIO_FORMAT_MAIN_MASK) {
+    switch (audio_get_main_format(format)) {
         case AUDIO_FORMAT_PCM: alsaFormat = kFmtLPCM; break;
         case AUDIO_FORMAT_AC3: alsaFormat = kFmtAC3; break;
         case AUDIO_FORMAT_E_AC3: alsaFormat = kFmtAC3; break; // FIXME should this be kFmtEAC3?
         case AUDIO_FORMAT_DTS: alsaFormat = kFmtDTS; break;
         case AUDIO_FORMAT_DTS_HD: alsaFormat = kFmtDTSHD; break;
-        default: return false;
+        case AUDIO_FORMAT_IEC61937:
+            alsaFormat = kFmtLPCM;
+            isIec958NonAudio = true;
+            break;
+        default:
+            ALOGE("supportsFormat() says format %#x not supported", format);
+            return false;
     }
 
     // EAC3 uses a PCM sample rate of 4X the base rate.
@@ -403,14 +411,17 @@
 
     // if PCM then determine actual bits per sample.
     if (alsaFormat == kFmtLPCM) {
-        uint32_t subFormat = format & AUDIO_FORMAT_SUB_MASK;
         BPSMask bpsMask;
-        switch (subFormat) {
+        switch (format) {
         // FIXME: (legacy code). We match on 16 bits, but on Fugu we hard code to use
         // PCM_FORMAT_S24_LE.
-            case AUDIO_FORMAT_PCM_SUB_16_BIT: // fall through
-            case AUDIO_FORMAT_PCM_SUB_8_24_BIT: bpsMask = kBPS_16bit; break;
-            default: return false;
+            case AUDIO_FORMAT_PCM_16_BIT: // fall through
+            case AUDIO_FORMAT_PCM_8_24_BIT:
+            case AUDIO_FORMAT_IEC61937:
+                bpsMask = kBPS_16bit;
+                break;
+            default:
+                return false;
         }
 
         // Is the caller requesting basic audio?  If so, we should be good to go.