qcom/audio/hal: Fix ringtone playback issue on Speaker

- Start music playback on HDMI, go to settings-->sound-->ringtone
  and select a ringtone for playback. The ringtone audio playback
  starts only after 15sec.
- When ringtone is selected, the low latency path is switched from
  HDMI to Speaker device. The low latency path uses only 2 buffers
  of 10.3msec each. If the device switch takes more time, the data
  filled kernel buffers meet the stop threshold and the ALSA
  framework triggers auto stop on the stream. This results PCM
  stream to be blocked for more than 10sec and hence no audio
  heard until the write is unblocked.
- Fix the issue by setting the stop threshold to INT_MAX to avoid
  auto stop.
- This change also ensures that open_output_stream fails if the
  HDMI sink does not support 5.1 or 7.1 playback.

Bug: 8401042
Change-Id: I4c1e04be2c47d67087b1cdda87e2dce77bde58f1
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 15b1be0..3782c32 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -308,7 +308,7 @@
             acdb_dev_type = ACDB_DEV_TYPE_IN;
         adev->acdb_send_audio_cal(acdb_dev_id, acdb_dev_type);
     } else {
-        ALOGW("%s: Could find the symbol acdb_send_audio_cal from %s",
+        ALOGW("%s: Could not find the symbol acdb_send_audio_cal from %s",
               __func__, LIB_ACDB_LOADER);
     }
 
@@ -448,10 +448,10 @@
 }
 
 /* must be called with hw device mutex locked */
-static void read_hdmi_channel_masks(struct stream_out *out)
+static int read_hdmi_channel_masks(struct stream_out *out)
 {
+    int ret = 0;
     int channels = edid_get_max_channels();
-    ALOGV("%s: enter", __func__);
 
     switch (channels) {
         /*
@@ -468,11 +468,11 @@
         out->supported_channel_masks[1] = AUDIO_CHANNEL_OUT_7POINT1;
         break;
     default:
-        ALOGE("Unsupported number of channels (%d)", channels);
+        ALOGE("HDMI does not support multi channel playback");
+        ret = -ENOSYS;
         break;
     }
-
-    ALOGV("%s: exit", __func__);
+    return ret;
 }
 
 static snd_device_t get_output_snd_device(struct audio_device *adev,
@@ -1410,6 +1410,8 @@
     pthread_mutex_unlock(&out->lock);
 
     if (ret != 0) {
+        if (out->pcm)
+            ALOGE("%s: error %d - %s", __func__, ret, pcm_get_error(out->pcm));
         out_standby(&out->stream.common);
         usleep(bytes * 1000000 / audio_stream_frame_size(&out->stream.common) /
                out_get_sample_rate(&out->stream.common));
@@ -1640,16 +1642,24 @@
     /* Init use case and pcm_config */
     if (out->flags & AUDIO_OUTPUT_FLAG_DIRECT &&
         out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
+        pthread_mutex_lock(&adev->lock);
+        ret = read_hdmi_channel_masks(out);
+        pthread_mutex_unlock(&adev->lock);
+        if (ret != 0) {
+            /* If HDMI does not support multi channel playback, set the default */
+            out->config.channels = popcount(out->channel_mask);
+            set_hdmi_channels(adev->mixer, out->config.channels);
+            goto error_open;
+        }
+
+        if (config->sample_rate == 0)
+            config->sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
+        if (config->channel_mask == 0)
+            config->channel_mask = AUDIO_CHANNEL_OUT_5POINT1;
+
+        out->channel_mask = config->channel_mask;
         out->usecase = USECASE_AUDIO_PLAYBACK_MULTI_CH;
         out->config = pcm_config_hdmi_multi;
-
-        pthread_mutex_lock(&adev->lock);
-        read_hdmi_channel_masks(out);
-        pthread_mutex_unlock(&adev->lock);
-
-        if (config->sample_rate == 0) config->sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
-        if (config->channel_mask == 0) config->channel_mask = AUDIO_CHANNEL_OUT_5POINT1;
-        out->channel_mask = config->channel_mask;
         out->config.rate = config->sample_rate;
         out->config.channels = popcount(out->channel_mask);
         out->config.period_size = HDMI_MULTI_PERIOD_BYTES / (out->config.channels * 2);
@@ -1667,7 +1677,8 @@
             adev->primary_output = out;
         else {
             ALOGE("%s: Primary output is already opened", __func__);
-            return -EEXIST;
+            ret = -EEXIST;
+            goto error_open;
         }
     }
 
@@ -1675,10 +1686,9 @@
     pthread_mutex_lock(&adev->lock);
     if (get_usecase_from_list(adev, out->usecase) != NULL) {
         ALOGE("%s: Usecase (%d) is already present", __func__, out->usecase);
-        free(out);
-        *stream_out = NULL;
         pthread_mutex_unlock(&adev->lock);
-        return -EEXIST;
+        ret = -EEXIST;
+        goto error_open;
     }
     pthread_mutex_unlock(&adev->lock);
 
@@ -1710,6 +1720,12 @@
     *stream_out = &out->stream;
     ALOGD("%s: exit", __func__);
     return 0;
+
+error_open:
+    free(out);
+    *stream_out = NULL;
+    ALOGD("%s: exit: ret %d", __func__, ret);
+    return ret;
 }
 
 static void adev_close_output_stream(struct audio_hw_device *dev,