Merge "hal: Fix closure of hardware dependent node" into av-userspace.lnx.1.0-dev.1.0
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index a513048..f630270 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
  * Not a Contribution.
  *
  * Copyright (C) 2013 The Android Open Source Project
@@ -247,6 +247,7 @@
     codec_backend_cfg_t current_backend_cfg[MAX_CODEC_BACKENDS];
     char ec_ref_mixer_path[64];
     char codec_version[CODEC_VERSION_MAX_LENGTH];
+    int hw_dep_fd;
 };
 
 static bool is_external_codec = false;
@@ -1386,14 +1387,15 @@
     return ret;
 }
 
-static int send_codec_cal(acdb_loader_get_calibration_t acdb_loader_get_calibration,
+static void send_codec_cal(acdb_loader_get_calibration_t acdb_loader_get_calibration,
                           struct platform_data *plat_data, int fd)
 {
-    int ret = 0, type;
+    int type;
 
     for (type = WCD9XXX_ANC_CAL; type < WCD9XXX_MAX_CAL; type++) {
         struct wcdcal_ioctl_buffer codec_buffer;
         struct param_data calib;
+        int ret;
 
         /* MAD calibration is handled by sound trigger HAL, skip here */
         if (type == WCD9XXX_MAD_CAL)
@@ -1410,14 +1412,14 @@
                                                                  &calib);
         if (ret < 0) {
             ALOGE("%s get_calibration failed\n", __func__);
-            return ret;
+            continue;
         }
         calib.get_size = 0;
         calib.buff = malloc(calib.buff_size);
         if(calib.buff == NULL) {
             ALOGE("%s mem allocation for %d bytes for %s failed\n"
                 , __func__, calib.buff_size, cal_name_info[type]);
-            return -1;
+            continue;
         }
         ret = acdb_loader_get_calibration(cal_name_info[type],
                               sizeof(struct param_data), &calib);
@@ -1425,7 +1427,7 @@
             ALOGE("%s get_calibration failed type=%s calib.size=%d\n"
                 , __func__, cal_name_info[type], codec_buffer.size);
             free(calib.buff);
-            return ret;
+            continue;
         }
         codec_buffer.buffer = calib.buff;
         codec_buffer.size = calib.data_size;
@@ -1437,14 +1439,14 @@
             , __func__, cal_name_info[type], codec_buffer.size);
         free(calib.buff);
     }
-    return ret;
 }
 
 static void audio_hwdep_send_cal(struct platform_data *plat_data)
 {
-    int fd;
+    int fd = plat_data->hw_dep_fd;
 
-    fd = hw_util_open(plat_data->adev->snd_card);
+    if (fd < 0)
+        fd = hw_util_open(plat_data->adev->snd_card);
     if (fd == -1) {
         ALOGE("%s error open\n", __func__);
         return;
@@ -1456,11 +1458,15 @@
     if (acdb_loader_get_calibration == NULL) {
         ALOGE("%s: ERROR. dlsym Error:%s acdb_loader_get_calibration", __func__,
            dlerror());
+        if (fd >= 0) {
+            close(fd);
+            plat_data->hw_dep_fd = -1;
+        }
         return;
     }
-    if (send_codec_cal(acdb_loader_get_calibration, plat_data, fd) < 0)
-        ALOGE("%s: Could not send anc cal", __FUNCTION__);
-    close(fd);
+
+    send_codec_cal(acdb_loader_get_calibration, plat_data, fd);
+    plat_data->hw_dep_fd = fd;
 }
 
 const char * get_snd_card_name_for_acdb_loader(const char *snd_card_name) {
@@ -1683,6 +1689,7 @@
     my_data->hd_voice = false;
     my_data->edid_info = NULL;
     my_data->is_wsa_speaker = false;
+    my_data->hw_dep_fd = -1;
 
     property_get("ro.qc.sdk.audio.fluencetype", my_data->fluence_cap, "");
     if (!strncmp("fluencepro", my_data->fluence_cap, sizeof("fluencepro"))) {
@@ -1907,6 +1914,11 @@
         my_data->edid_info = NULL;
     }
 
+    if (my_data->hw_dep_fd >= 0) {
+        close(my_data->hw_dep_fd);
+        my_data->hw_dep_fd = -1;
+    }
+
     hw_info_deinit(my_data->hw_info);
     close_csd_client(my_data->csd);
 
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index f243790..179593d 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
  * Not a Contribution.
  *
  * Copyright (C) 2013 The Android Open Source Project
@@ -243,6 +243,7 @@
     char ec_ref_mixer_path[64];
     codec_backend_cfg_t current_backend_cfg[MAX_CODEC_BACKENDS];
     char codec_version[CODEC_VERSION_MAX_LENGTH];
+    int hw_dep_fd;
 };
 
 static int pcm_device_table[AUDIO_USECASE_MAX][2] = {
@@ -1212,9 +1213,10 @@
 
 static void audio_hwdep_send_cal(struct platform_data *plat_data)
 {
-    int fd;
+    int fd = plat_data->hw_dep_fd;
 
-    fd = hw_util_open(plat_data->adev->snd_card);
+    if (fd < 0)
+        fd = hw_util_open(plat_data->adev->snd_card);
     if (fd == -1) {
         ALOGE("%s error open\n", __func__);
         return;
@@ -1226,11 +1228,15 @@
     if (acdb_loader_get_calibration == NULL) {
         ALOGE("%s: ERROR. dlsym Error:%s acdb_loader_get_calibration", __func__,
            dlerror());
+        if (fd >= 0) {
+            close(fd);
+            plat_data->hw_dep_fd = -1;
+        }
         return;
     }
 
     send_codec_cal(acdb_loader_get_calibration, plat_data, fd);
-    close(fd);
+    plat_data->hw_dep_fd = fd;
 }
 
 static int platform_acdb_init(void *platform)
@@ -1405,6 +1411,7 @@
     my_data->slowtalk = false;
     my_data->hd_voice = false;
     my_data->edid_info = NULL;
+    my_data->hw_dep_fd = -1;
 
     property_get("ro.qc.sdk.audio.fluencetype", my_data->fluence_cap, "");
     if (!strncmp("fluencepro", my_data->fluence_cap, sizeof("fluencepro"))) {
@@ -1621,6 +1628,11 @@
         my_data->edid_info = NULL;
     }
 
+    if (my_data->hw_dep_fd >= 0) {
+        close(my_data->hw_dep_fd);
+        my_data->hw_dep_fd = -1;
+    }
+
     hw_info_deinit(my_data->hw_info);
     close_csd_client(my_data->csd);