hal: add support of HDMI external display for rb3gen2

- add support for HDMI external display
- add stereo channel support for hdmi
- add mechanism to get controller and stream index for hdmi display

Change-Id: I12d60fd6cb3bfcd1d8264fbcdc4bdac808403eca
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index 175715f..d75dd5a 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -629,7 +629,7 @@
 };
 
 // START: MST ==================================================
-#define MAX_CONTROLLERS 1
+#define MAX_CONTROLLERS 2
 #define MAX_STREAMS_PER_CONTROLLER 2
 // END: MST ==================================================
 
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index cb2791c..4b3372b 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -2363,7 +2363,7 @@
 /* must be called with hw device mutex locked */
 static int read_hdmi_sink_caps(struct stream_out *out)
 {
-    int ret = 0, i = 0, j = 0;
+    int ret = 0, i = 0, j = 0, rc = 0;
     int channels = platform_edid_get_max_channels_v2(out->dev->platform,
                                                      out->extconn.cs.controller,
                                                      out->extconn.cs.stream);
@@ -2371,11 +2371,11 @@
     reset_hdmi_sink_caps(out);
 
     /* Cache ext disp type */
-    ret = platform_get_ext_disp_type_v2(adev->platform,
+    rc = platform_get_ext_disp_type_v2(adev->platform,
                                       out->extconn.cs.controller,
                                       out->extconn.cs.stream);
-    if(ret < 0) {
-        ALOGE("%s: Failed to query disp type, ret:%d", __func__, ret);
+    if(rc < 0) {
+        ALOGE("%s: Failed to query disp type, rc:%d", __func__, rc);
         return -EINVAL;
     }
 
@@ -2391,6 +2391,10 @@
         out->supported_channel_masks[i++] = AUDIO_CHANNEL_OUT_QUAD;
         out->supported_channel_masks[i++] = AUDIO_CHANNEL_OUT_SURROUND;
         out->supported_channel_masks[i++] = AUDIO_CHANNEL_OUT_2POINT1;
+    case 2:
+        ALOGV("%s: HDMI supports 2 channels", __func__);
+        out->supported_channel_masks[i++] = AUDIO_CHANNEL_OUT_STEREO;
+        out->supported_channel_masks[i++] = AUDIO_CHANNEL_OUT_MONO;
         break;
     default:
         ALOGE("invalid/nonstandard channal count[%d]",channels);
@@ -4926,7 +4930,7 @@
     pthread_mutex_unlock(&out->position_query_lock);
 
     ALOGVV("%s signed frames %lld written frames %lld kernel frames %lld dsp frames %lld",
-            __func__, signed_frames, written_frames, kernel_frames, dsp_frames);
+            __func__, (long long)signed_frames, (long long)written_frames, (long long)kernel_frames, (long long)dsp_frames);
 
     return actual_frames_rendered;
 }
@@ -5505,6 +5509,8 @@
     if (err == 0) {
         out->extconn.cs.controller = ext_controller;
         out->extconn.cs.stream = ext_stream;
+        adev->ext_controller = out->extconn.cs.controller;
+        adev->ext_stream = out->extconn.cs.stream;
         ALOGD("%s: usecase(%s) new controller/stream (%d/%d)", __func__,
               use_case_table[out->usecase], out->extconn.cs.controller,
               out->extconn.cs.stream);
@@ -8307,6 +8313,8 @@
     out->prev_card_status_offline = false;
     out->pspd_coeff_sent = false;
     out->mmap_shared_memory_fd = -1; // not open
+    out->extconn.cs.controller = adev->ext_controller;
+    out->extconn.cs.stream = adev->ext_stream;
 
     if ((flags & AUDIO_OUTPUT_FLAG_BD) &&
         (property_get_bool("vendor.audio.matrix.limiter.enable", false)))
@@ -8314,8 +8322,7 @@
 
     if (direct_dev &&
         (audio_is_linear_pcm(out->format) ||
-         config->format == AUDIO_FORMAT_DEFAULT) &&
-        out->flags == AUDIO_OUTPUT_FLAG_NONE) {
+         config->format == AUDIO_FORMAT_DEFAULT)) {
         audio_format_t req_format = config->format;
         audio_channel_mask_t req_channel_mask = config->channel_mask;
         uint32_t req_sample_rate = config->sample_rate;
@@ -9420,6 +9427,16 @@
             if (ret < 0) {
                 ALOGE("%s: Failed to query disp type, ret:%d", __func__, ret);
             } else {
+                // Update ctl and stream values for all the existing streams during HDMI connection,
+                // as adev_open_output_stream() doesn't get called for existing streams and values
+                // remain unupdated for those streams.
+                list_for_each(node, &adev->active_outputs_list) {
+                    streams_output_ctxt_t *out_ctxt = node_to_item(node,
+                            streams_output_ctxt_t,
+                            list);
+                    out_ctxt->output->extconn.cs.controller = controller;
+                    out_ctxt->output->extconn.cs.stream = stream;
+                }
                 platform_cache_edid_v2(adev->platform, controller, stream);
             }
         } else if (audio_is_usb_out_device(device) || audio_is_usb_in_device(device)) {
diff --git a/hal/audio_hw.h b/hal/audio_hw.h
index 1edae41..1d8bb15 100644
--- a/hal/audio_hw.h
+++ b/hal/audio_hw.h
@@ -848,6 +848,8 @@
     Hashmap *io_streams_map;
     bool a2dp_started;
     bool ha_proxy_enable;
+    int ext_controller;
+    int ext_stream;
 };
 
 struct audio_patch_record {
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 5e8a8aa..22c617b 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -6582,7 +6582,7 @@
  */
 int platform_get_display_port_ctl_index(int controller, int stream) {
 
-    if (controller < 0 || controller >= MAX_CONTROLLERS ||
+    if (controller < 0 || controller > MAX_CONTROLLERS ||
             stream < 0 || stream >= MAX_STREAMS_PER_CONTROLLER) {
         ALOGE("%s: Invalid controller/stream - %d/%d",
               __func__, controller, stream);
@@ -6600,9 +6600,10 @@
     struct mixer_ctl *ctl = NULL;
     int ctl_index = 0;
     const char *ctl_name_prefix = "External Display";
+    const char *ctl_name_prefix2 = "External HDMI";
     const char *ctl_name_suffix = "Audio Device";
     char mixer_ctl_name[MIXER_PATH_MAX_LENGTH] = {0};
-    int device_values[2] = {-1, -1};
+    long int device_values[2] = {-1, -1};
 
     if (!audio_extn_is_display_port_enabled()) {
         ALOGE("%s: display port is not supported", __func__);
@@ -6616,9 +6617,12 @@
         return -EINVAL;
     }
 
-    if (0 == ctl_index)
+    if (ctl_index < 2)
         snprintf(mixer_ctl_name, sizeof(mixer_ctl_name),
                  "%s %s", ctl_name_prefix, ctl_name_suffix);
+    else if (ctl_index < 4)
+        snprintf(mixer_ctl_name, sizeof(mixer_ctl_name),
+                 "%s %s", ctl_name_prefix2, ctl_name_suffix);
     else
         snprintf(mixer_ctl_name, sizeof(mixer_ctl_name),
                  "%s%d %s", ctl_name_prefix, ctl_index, ctl_name_suffix);
@@ -6635,7 +6639,7 @@
         return -EINVAL;
     }
 
-    ALOGV("%s: controller/stream: %d/%d", __func__, device_values[0],
+    ALOGV("%s: controller/stream: %ld/%ld", __func__, device_values[0],
           device_values[1]);
 
     return mixer_ctl_set_array(ctl, device_values, ARRAY_SIZE(device_values));
@@ -6670,12 +6674,16 @@
         struct audio_device *adev = my_data->adev;
         struct mixer_ctl *ctl = NULL;
         const char *ctl_name_prefix = "External Display";
+        const char *ctl_name_prefix2 = "External HDMI";
         const char *ctl_name_suffix = "Type";
         char mixer_ctl_name[MIXER_PATH_MAX_LENGTH] = {0};
 
-        if (0 == ctl_index)
+        if (ctl_index < 2)
             snprintf(mixer_ctl_name, sizeof(mixer_ctl_name),
                      "%s %s", ctl_name_prefix, ctl_name_suffix);
+        else if (ctl_index < 4)
+            snprintf(mixer_ctl_name, sizeof(mixer_ctl_name),
+                     "%s %s", ctl_name_prefix2, ctl_name_suffix);
         else
             snprintf(mixer_ctl_name, sizeof(mixer_ctl_name),
                      "%s%d %s", ctl_name_prefix, ctl_index, ctl_name_suffix);
@@ -6738,7 +6746,7 @@
         controller = out->extconn.cs.controller;
         stream = out->extconn.cs.stream;
 
-        if (controller < 0 || controller >= MAX_CONTROLLERS ||
+        if (controller < 0 || controller > MAX_CONTROLLERS ||
                 stream < 0 || stream >= MAX_STREAMS_PER_CONTROLLER) {
             ALOGE("%s: Invalid controller/stream - %d/%d",
                   __func__, controller, stream);
@@ -10216,7 +10224,7 @@
     controller = usecase->stream.out->extconn.cs.controller;
     stream = usecase->stream.out->extconn.cs.stream;
 
-    if (controller < 0 || controller >= MAX_CONTROLLERS ||
+    if (controller < 0 || controller > MAX_CONTROLLERS ||
             stream < 0 || stream >= MAX_STREAMS_PER_CONTROLLER) {
         controller = 0;
         stream = 0;
@@ -11925,7 +11933,7 @@
         return -EINVAL;
     }
 
-    if (controller < 0 || controller >= MAX_CONTROLLERS ||
+    if (controller < 0 || controller > MAX_CONTROLLERS ||
             stream < 0 || stream >= MAX_STREAMS_PER_CONTROLLER) {
         ALOGE("%s: Invalid controller/stream - %d/%d",
               __func__, controller, stream);
@@ -12042,7 +12050,7 @@
     int backend_idx;
     snd_device_t snd_device;
 
-    if (controller < 0 || controller >= MAX_CONTROLLERS ||
+    if (controller < 0 || controller > MAX_CONTROLLERS ||
             stream < 0 || stream >= MAX_STREAMS_PER_CONTROLLER) {
         ALOGE("%s: Invalid controller/stream - %d/%d",
               __func__, controller, stream);
@@ -13000,7 +13008,7 @@
                                                int *controller, int *stream) {
     str_parms_get_int(parms, "controller", controller);
     str_parms_get_int(parms, "stream", stream);
-    if (*controller < 0 || *controller >= MAX_CONTROLLERS ||
+    if (*controller < 0 || *controller > MAX_CONTROLLERS ||
             *stream < 0 || *stream >= MAX_STREAMS_PER_CONTROLLER) {
         *controller = 0;
         *stream = 0;