hal: Avoid multiple mixer open calls during init

audio_extn_utils_get_snd_card_num opens the mixer for
primary sound card. clients of this API are opening the
mixer again for the same card. Multiple mixer open calls
during HAL initialization are adding to boot up latency.

Return mixer handle as well along with the sound card
number from audio_extn_utils_open_snd_mixer. Added
close API as well to be consistent with the open API.
Retained old APIs for backward compatability with
ST HAL.

CRs-Fixed: 2205214
Change-Id: I323ee7a3c3fe446cd268b46a6e2c498467273ddb
diff --git a/hal/acdb.c b/hal/acdb.c
index ad67d61..4ae03e9 100644
--- a/hal/acdb.c
+++ b/hal/acdb.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
  * Not a Contribution.
  *
  * Copyright (C) 2013 The Android Open Source Project
@@ -32,11 +32,7 @@
 {
 
     int result = -1;
-    char *cvd_version = NULL;
-
-    const char *snd_card_name = NULL;
     struct mixer *mixer = NULL;
-    struct acdb_platform_data *my_data = NULL;
 
     if(snd_card_num < 0) {
         ALOGE("invalid sound card number");
@@ -47,7 +43,25 @@
     if (!mixer) {
         ALOGE("%s: Unable to open the mixer card: %d", __func__,
                snd_card_num);
-        goto cleanup;
+        return result;
+    }
+    result = acdb_init_v2(mixer);
+    mixer_close(mixer);
+    return result;
+}
+
+int acdb_init_v2(struct mixer *mixer)
+{
+
+    int result = -1;
+    char *cvd_version = NULL;
+
+    const char *snd_card_name = NULL;
+    struct acdb_platform_data *my_data = NULL;
+
+    if (!mixer) {
+       ALOGE("Invalid mixer handle");
+       return result;
     }
 
     my_data = calloc(1, sizeof(struct acdb_platform_data));
@@ -155,9 +169,6 @@
         free(my_data);
     }
 
-    if (mixer)
-        mixer_close(mixer);
-
     if (cvd_version)
         free(cvd_version);
 
diff --git a/hal/acdb.h b/hal/acdb.h
index d1f863b..140370a 100644
--- a/hal/acdb.h
+++ b/hal/acdb.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
  * Not a Contribution.
  *
  * Copyright (C) 2013 The Android Open Source Project
@@ -33,6 +33,7 @@
 #define PLATFORM_INFO_XML_PATH "/vendor/etc/audio_platform_info.xml"
 #endif
 
+struct mixer;
 /* Audio calibration related functions */
 typedef void (*acdb_deallocate_t)();
 typedef int  (*acdb_init_t)();
@@ -68,6 +69,7 @@
 };
 
 int acdb_init(int);
+int acdb_init_v2(struct mixer *);
 
 int acdb_set_metainfo_key(void *platform, char *name, int key);
 #endif //ACDB_H
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index 2b55648..0092e87 100755
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -638,6 +638,8 @@
                                   struct audio_device *adev,
                                   struct audio_usecase *usecase);
 int audio_extn_utils_get_snd_card_num();
+int audio_extn_utils_open_snd_mixer(struct mixer **mixer_handle);
+void audio_extn_utils_close_snd_mixer(struct mixer *mixer);
 bool audio_extn_is_dsp_bit_width_enforce_mode_supported(audio_output_flags_t flags);
 bool audio_extn_utils_is_dolby_format(audio_format_t format);
 int audio_extn_utils_get_bit_width_from_string(const char *);
diff --git a/hal/audio_extn/utils.c b/hal/audio_extn/utils.c
index c968c56..8a585df 100755
--- a/hal/audio_extn/utils.c
+++ b/hal/audio_extn/utils.c
@@ -2111,6 +2111,17 @@
 
 int audio_extn_utils_get_snd_card_num()
 {
+    int snd_card_num = 0;
+    struct mixer *mixer = NULL;
+
+    snd_card_num = audio_extn_utils_open_snd_mixer(&mixer);
+    if (mixer)
+        mixer_close(mixer);
+    return snd_card_num;
+}
+
+int audio_extn_utils_open_snd_mixer(struct mixer **mixer_handle)
+{
 
     void *hw_info = NULL;
     struct mixer *mixer = NULL;
@@ -2118,6 +2129,11 @@
     int snd_card_num = 0, min_snd_card_num = 0;
     char* snd_card_name = NULL;
 
+    if (!mixer_handle) {
+        ALOGE("invalid mixer handle");
+        return -1;
+    }
+    *mixer_handle = NULL;
     /*
     * Try with all the sound cards ( 0 to 8 ) and if none of them were detected
     * sleep for 1 sec and try detections with sound card 0 again.
@@ -2171,9 +2187,6 @@
     if (snd_card_name)
         free(snd_card_name);
 
-    if (mixer)
-        mixer_close(mixer);
-
     if (hw_info)
         hw_info_deinit(hw_info);
 
@@ -2182,9 +2195,18 @@
         return -1;
     }
 
+    if (mixer)
+        *mixer_handle = mixer;
+
     return snd_card_num;
 }
 
+void audio_extn_utils_close_snd_mixer(struct mixer *mixer)
+{
+    if (mixer)
+        mixer_close(mixer);
+}
+
 #ifdef SNDRV_COMPRESS_ENABLE_ADJUST_SESSION_CLOCK
 int audio_extn_utils_compress_enable_drift_correction(
         struct stream_out *out,
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index 7a48978..98d4fd5 100755
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -2215,7 +2215,7 @@
     const char *id_string = NULL;
     int cfg_value = -1;
 
-    snd_card_num = audio_extn_utils_get_snd_card_num();
+    snd_card_num = audio_extn_utils_open_snd_mixer(&adev->mixer);
     if(snd_card_num < 0) {
         ALOGE("%s: Unable to find correct sound card", __func__);
         return NULL;
@@ -2224,13 +2224,6 @@
     adev->snd_card = snd_card_num;
     ALOGD("%s: Opened sound card:%d", __func__, snd_card_num);
 
-    adev->mixer = mixer_open(snd_card_num);
-    if (!adev->mixer) {
-        ALOGE("%s: Unable to open the mixer card: %d", __func__,
-               snd_card_num);
-        return NULL;
-    }
-
     snd_card_name = mixer_get_name(adev->mixer);
     ALOGD("%s: snd_card_name: %s", __func__, snd_card_name);
 
@@ -2260,7 +2253,7 @@
         ALOGE("%s: Failed to init audio route controls, aborting.",
                __func__);
         free(my_data);
-        mixer_close(adev->mixer);
+        audio_extn_utils_close_snd_mixer(adev->mixer);
         return NULL;
     }
     update_codec_type(snd_card_name);
@@ -2482,7 +2475,7 @@
             goto acdb_init_fail;
         }
 
-        int result = acdb_init(adev->snd_card);
+        int result = acdb_init_v2(adev->mixer);
         if (!result) {
             my_data->is_acdb_initialized = true;
             ALOGD("ACDB initialized");
@@ -2777,7 +2770,7 @@
     }
 
     if (my_data->adev->mixer) {
-        mixer_close(my_data->adev->mixer);
+        audio_extn_utils_close_snd_mixer(my_data->adev->mixer);
         my_data->adev->mixer = NULL;
     }
 
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 3ac3b93..34558a0 100755
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -1947,24 +1947,17 @@
     const char *id_string = NULL;
     int cfg_value = -1;
 
-    adev->snd_card = audio_extn_utils_get_snd_card_num();
+    adev->snd_card = audio_extn_utils_open_snd_mixer(&adev->mixer);
     if (adev->snd_card < 0) {
         ALOGE("%s: Unable to find correct sound card", __func__);
         return NULL;
     }
     ALOGD("%s: Opened sound card:%d", __func__, adev->snd_card);
 
-    adev->mixer = mixer_open(adev->snd_card);
-    if (!adev->mixer) {
-        ALOGE("%s: Unable to open the mixer card: %d", __func__,
-               adev->snd_card);
-        return NULL;
-    }
-
     snd_card_name = strdup(mixer_get_name(adev->mixer));
     if (!snd_card_name) {
         ALOGE("failed to allocate memory for snd_card_name\n");
-        mixer_close(adev->mixer);
+        audio_extn_utils_close_snd_mixer(adev->mixer);
         return NULL;
     }
 
@@ -1973,7 +1966,7 @@
         ALOGE("failed to allocate platform data");
         if (snd_card_name)
             free(snd_card_name);
-        mixer_close(adev->mixer);
+        audio_extn_utils_close_snd_mixer(adev->mixer);
         return NULL;
     }
 
@@ -1983,7 +1976,7 @@
     my_data->hw_info = hw_info_init(snd_card_name);
     if (!my_data->hw_info) {
         ALOGE("failed to init hw_info");
-        mixer_close(adev->mixer);
+        audio_extn_utils_close_snd_mixer(adev->mixer);
         if (my_data)
             free(my_data);
 
@@ -2055,7 +2048,7 @@
             free(snd_card_name);
         if (snd_card_name_t)
             free(snd_card_name_t);
-        mixer_close(adev->mixer);
+        audio_extn_utils_close_snd_mixer(adev->mixer);
         return NULL;
     }
 
@@ -2267,7 +2260,7 @@
             goto acdb_init_fail;
         }
 
-        int result = acdb_init(adev->snd_card);
+        int result = acdb_init_v2(adev->mixer);
         if (!result) {
             my_data->is_acdb_initialized = true;
             ALOGD("ACDB initialized");
@@ -2574,7 +2567,7 @@
     }
 
     if (my_data->adev->mixer) {
-        mixer_close(my_data->adev->mixer);
+        audio_extn_utils_close_snd_mixer(my_data->adev->mixer);
         my_data->adev->mixer = NULL;
     }