Merge "hal: send calibration parameters in stream route"
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index 771d913..ac8896e 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -265,4 +265,7 @@
                                   audio_format_t format,
                                   struct stream_app_type_cfg *app_type_cfg);
 int audio_extn_utils_send_app_type_cfg(struct audio_usecase *usecase);
+void audio_extn_utils_send_audio_calibration(struct audio_device *adev,
+                                             struct audio_usecase *usecase);
+
 #endif /* AUDIO_EXTN_H */
diff --git a/hal/audio_extn/spkr_protection.c b/hal/audio_extn/spkr_protection.c
index 91f69f3..cd2a94e 100644
--- a/hal/audio_extn/spkr_protection.c
+++ b/hal/audio_extn/spkr_protection.c
@@ -686,11 +686,6 @@
     }
     spkr_prot_calib_cancel(adev);
     spkr_prot_set_spkrstatus(true);
-    if (platform_send_audio_calibration(adev->platform,
-        SND_DEVICE_OUT_SPEAKER_PROTECTED) < 0) {
-        adev->snd_dev_ref_cnt[snd_device]--;
-        return -EINVAL;
-    }
     ALOGV("%s: snd_device(%d: %s)", __func__, snd_device,
          platform_get_snd_device_name(SND_DEVICE_OUT_SPEAKER_PROTECTED));
     audio_route_apply_and_update_path(adev->audio_route,
@@ -732,7 +727,8 @@
 exit:
    /* Clear VI feedback cal and replace with handset MIC  */
    platform_send_audio_calibration(adev->platform,
-        SND_DEVICE_IN_HANDSET_MIC);
+        SND_DEVICE_IN_HANDSET_MIC,
+        platform_get_default_app_type(adev->platform), 8000);
     if (ret) {
         if (handle.pcm_tx)
             pcm_close(handle.pcm_tx);
diff --git a/hal/audio_extn/utils.c b/hal/audio_extn/utils.c
index bb34bf0..6bb1b1b 100644
--- a/hal/audio_extn/utils.c
+++ b/hal/audio_extn/utils.c
@@ -174,7 +174,7 @@
 
 static int parse_app_type_names(void *platform, char *name)
 {
-    int app_type = 0; /* TODO: default app type from acdb when exposed using "platform" */
+    int app_type = platform_get_default_app_type(platform);
     char *str = strtok(name, "|");
 
     if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG))
@@ -248,7 +248,7 @@
     }
     if (streams_output_cfg_list == NULL) {
         app_type_cfg[length++] = 1;
-        app_type_cfg[length++] = 0; /* TODO: default app type from acdb when exposed from "platform" */
+        app_type_cfg[length++] = platform_get_default_app_type(platform);
         app_type_cfg[length++] = 48000;
         app_type_cfg[length++] = 16;
         mixer_ctl_set_array(ctl, app_type_cfg, length);
@@ -383,7 +383,7 @@
         }
     }
     ALOGW("%s: App type could not be selected. Falling back to default", __func__);
-    app_type_cfg->app_type = 0; /* TODO: default app type from acdb when exposed from "platform" */
+    app_type_cfg->app_type = platform_get_default_app_type(platform);
     app_type_cfg->sample_rate = 48000;
     app_type_cfg->bit_width = 16;
 }
@@ -444,3 +444,26 @@
 exit_send_app_type_cfg:
     return rc;
 }
+
+void audio_extn_utils_send_audio_calibration(struct audio_device *adev,
+                                             struct audio_usecase *usecase)
+{
+    int type = usecase->type;
+
+    if (type == PCM_PLAYBACK) {
+        struct stream_out *out = usecase->stream.out;
+        int snd_device = usecase->out_snd_device;
+        snd_device = (snd_device == SND_DEVICE_OUT_SPEAKER) ?
+                     audio_extn_get_spkr_prot_snd_device(snd_device) : snd_device;
+        platform_send_audio_calibration(adev->platform, usecase->out_snd_device,
+                                        out->app_type_cfg.app_type,
+                                        out->app_type_cfg.sample_rate);
+    }
+    if ((type == PCM_HFP_CALL) || (type == PCM_CAPTURE)) {
+        /* when app type is default. the sample rate is not used to send cal */
+        platform_send_audio_calibration(adev->platform, usecase->in_snd_device,
+                                        platform_get_default_app_type(adev->platform),
+                                        48000);
+    }
+}
+
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 0468b42..806a4be 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -257,6 +257,7 @@
     audio_extn_dolby_set_dmid(adev);
     audio_extn_dolby_set_endpoint(adev);
 #endif
+    audio_extn_utils_send_audio_calibration(adev, usecase);
     audio_extn_utils_send_app_type_cfg(usecase);
     strcpy(mixer_path, use_case_table[usecase->id]);
     platform_add_backend_name(mixer_path, snd_device);
@@ -323,6 +324,10 @@
     if ((snd_device == SND_DEVICE_OUT_SPEAKER ||
         snd_device == SND_DEVICE_OUT_VOICE_SPEAKER) &&
         audio_extn_spkr_prot_is_enabled()) {
+       if (audio_extn_spkr_prot_get_acdb_id(snd_device) < 0) {
+           adev->snd_dev_ref_cnt[snd_device]--;
+           return -EINVAL;
+       }
         if (audio_extn_spkr_prot_start_processing(snd_device)) {
             ALOGE("%s: spkr_start_processing failed", __func__);
             return -EINVAL;
@@ -334,7 +339,7 @@
             and audio, notify listen hal before audio calibration is sent */
         audio_extn_listen_update_status(snd_device,
                        LISTEN_EVENT_SND_DEVICE_BUSY);
-        if (platform_send_audio_calibration(adev->platform, snd_device) < 0) {
+        if (platform_get_snd_device_acdb_id(snd_device) < 0) {
             adev->snd_dev_ref_cnt[snd_device]--;
             audio_extn_listen_update_status(snd_device,
                            LISTEN_EVENT_SND_DEVICE_FREE);
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index 8f11acd..d92f707 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -70,6 +70,9 @@
 /* EDID format ID for LPCM audio */
 #define EDID_FORMAT_LPCM    1
 
+/* fallback app type if the default app type from acdb loader fails */
+#define DEFAULT_APP_TYPE  0x11130
+
 /* Retry for delay in FW loading*/
 #define RETRY_NUMBER 20
 #define RETRY_US 500000
@@ -97,9 +100,10 @@
 /* Audio calibration related functions */
 typedef void (*acdb_deallocate_t)();
 typedef int  (*acdb_init_t)(char *);
-typedef void (*acdb_send_audio_cal_t)(int, int);
+typedef void (*acdb_send_audio_cal_t)(int, int, int, int);
 typedef void (*acdb_send_voice_cal_t)(int, int);
 typedef int (*acdb_reload_vocvoltable_t)(int);
+typedef int  (*acdb_get_default_app_type_t)(void);
 
 struct platform_data {
     struct audio_device *adev;
@@ -119,6 +123,7 @@
     acdb_send_audio_cal_t      acdb_send_audio_cal;
     acdb_send_voice_cal_t      acdb_send_voice_cal;
     acdb_reload_vocvoltable_t  acdb_reload_vocvoltable;
+    acdb_get_default_app_type_t acdb_get_default_app_type;
 
     void *hw_info;
     struct csd_data *csd;
@@ -684,7 +689,7 @@
                   __func__, LIB_ACDB_LOADER);
 
         my_data->acdb_send_audio_cal = (acdb_send_audio_cal_t)dlsym(my_data->acdb_handle,
-                                                    "acdb_loader_send_audio_cal");
+                                                    "acdb_loader_send_audio_cal_v2");
         if (!my_data->acdb_send_audio_cal)
             ALOGE("%s: Could not find the symbol acdb_send_audio_cal from %s",
                   __func__, LIB_ACDB_LOADER);
@@ -701,6 +706,13 @@
             ALOGE("%s: Could not find the symbol acdb_loader_reload_vocvoltable from %s",
                   __func__, LIB_ACDB_LOADER);
 
+        my_data->acdb_get_default_app_type = (acdb_get_default_app_type_t)dlsym(
+                                                    my_data->acdb_handle,
+                                                    "acdb_loader_get_default_app_type");
+        if (!my_data->acdb_get_default_app_type)
+            ALOGE("%s: Could not find the symbol acdb_get_default_app_type from %s",
+                  __func__, LIB_ACDB_LOADER);
+
         my_data->acdb_init = (acdb_init_t)dlsym(my_data->acdb_handle,
                                                     "acdb_loader_init_v2");
         if (my_data->acdb_init == NULL)
@@ -898,6 +910,16 @@
     return ret;
 }
 
+int platform_get_default_app_type(void *platform)
+{
+    struct platform_data *my_data = (struct platform_data *)platform;
+
+    if (my_data->acdb_get_default_app_type)
+        return my_data->acdb_get_default_app_type();
+    else
+        return DEFAULT_APP_TYPE;
+}
+
 int platform_get_snd_device_acdb_id(snd_device_t snd_device)
 {
     if ((snd_device < SND_DEVICE_MIN) || (snd_device >= SND_DEVICE_MAX)) {
@@ -907,7 +929,8 @@
     return acdb_device_table[snd_device];
 }
 
-int platform_send_audio_calibration(void *platform, snd_device_t snd_device)
+int platform_send_audio_calibration(void *platform, snd_device_t snd_device,
+                                    int app_type, int sample_rate)
 {
     struct platform_data *my_data = (struct platform_data *)platform;
     int acdb_dev_id, acdb_dev_type;
@@ -919,14 +942,15 @@
         return -EINVAL;
     }
     if (my_data->acdb_send_audio_cal) {
-        ("%s: sending audio calibration for snd_device(%d) acdb_id(%d)",
+        ALOGV("%s: sending audio calibration for snd_device(%d) acdb_id(%d)",
               __func__, snd_device, acdb_dev_id);
         if (snd_device >= SND_DEVICE_OUT_BEGIN &&
                 snd_device < SND_DEVICE_OUT_END)
             acdb_dev_type = ACDB_DEV_TYPE_OUT;
         else
             acdb_dev_type = ACDB_DEV_TYPE_IN;
-        my_data->acdb_send_audio_cal(acdb_dev_id, acdb_dev_type);
+        my_data->acdb_send_audio_cal(acdb_dev_id, acdb_dev_type, app_type,
+                                     sample_rate);
     }
     return 0;
 }
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index dae686e..82bafe5 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -74,6 +74,9 @@
 /* EDID format ID for LPCM audio */
 #define EDID_FORMAT_LPCM    1
 
+/* fallback app type if the default app type from acdb loader fails */
+#define DEFAULT_APP_TYPE  0x11130
+
 /* Retry for delay in FW loading*/
 #define RETRY_NUMBER 10
 #define RETRY_US 500000
@@ -101,9 +104,10 @@
 /* Audio calibration related functions */
 typedef void (*acdb_deallocate_t)();
 typedef int  (*acdb_init_t)(char *);
-typedef void (*acdb_send_audio_cal_t)(int, int);
+typedef void (*acdb_send_audio_cal_t)(int, int, int , int);
 typedef void (*acdb_send_voice_cal_t)(int, int);
 typedef int (*acdb_reload_vocvoltable_t)(int);
+typedef int  (*acdb_get_default_app_type_t)(void);
 
 struct platform_data {
     struct audio_device *adev;
@@ -125,6 +129,7 @@
     acdb_send_audio_cal_t      acdb_send_audio_cal;
     acdb_send_voice_cal_t      acdb_send_voice_cal;
     acdb_reload_vocvoltable_t  acdb_reload_vocvoltable;
+    acdb_get_default_app_type_t acdb_get_default_app_type;
 
     void *hw_info;
     struct csd_data *csd;
@@ -743,7 +748,7 @@
                   __func__, LIB_ACDB_LOADER);
 
         my_data->acdb_send_audio_cal = (acdb_send_audio_cal_t)dlsym(my_data->acdb_handle,
-                                                    "acdb_loader_send_audio_cal");
+                                                    "acdb_loader_send_audio_cal_v2");
         if (!my_data->acdb_send_audio_cal)
             ALOGE("%s: Could not find the symbol acdb_send_audio_cal from %s",
                   __func__, LIB_ACDB_LOADER);
@@ -760,6 +765,13 @@
             ALOGE("%s: Could not find the symbol acdb_loader_reload_vocvoltable from %s",
                   __func__, LIB_ACDB_LOADER);
 
+        my_data->acdb_get_default_app_type = (acdb_get_default_app_type_t)dlsym(
+                                                    my_data->acdb_handle,
+                                                    "acdb_loader_get_default_app_type");
+        if (!my_data->acdb_get_default_app_type)
+            ALOGE("%s: Could not find the symbol acdb_get_default_app_type from %s",
+                  __func__, LIB_ACDB_LOADER);
+
         my_data->acdb_init = (acdb_init_t)dlsym(my_data->acdb_handle,
                                                     "acdb_loader_init_v2");
         if (my_data->acdb_init == NULL)
@@ -970,6 +982,16 @@
     return ret;
 }
 
+int platform_get_default_app_type(void *platform)
+{
+    struct platform_data *my_data = (struct platform_data *)platform;
+
+    if (my_data->acdb_get_default_app_type)
+        return my_data->acdb_get_default_app_type();
+    else
+        return DEFAULT_APP_TYPE;
+}
+
 int platform_get_snd_device_acdb_id(snd_device_t snd_device)
 {
     if ((snd_device < SND_DEVICE_MIN) || (snd_device >= SND_DEVICE_MAX)) {
@@ -979,7 +1001,8 @@
     return acdb_device_table[snd_device];
 }
 
-int platform_send_audio_calibration(void *platform, snd_device_t snd_device)
+int platform_send_audio_calibration(void *platform, snd_device_t snd_device,
+                                    int app_type, int sample_rate)
 {
     struct platform_data *my_data = (struct platform_data *)platform;
     int acdb_dev_id, acdb_dev_type;
@@ -991,14 +1014,15 @@
         return -EINVAL;
     }
     if (my_data->acdb_send_audio_cal) {
-        ("%s: sending audio calibration for snd_device(%d) acdb_id(%d)",
+        ALOGV("%s: sending audio calibration for snd_device(%d) acdb_id(%d)",
               __func__, snd_device, acdb_dev_id);
         if (snd_device >= SND_DEVICE_OUT_BEGIN &&
                 snd_device < SND_DEVICE_OUT_END)
             acdb_dev_type = ACDB_DEV_TYPE_OUT;
         else
             acdb_dev_type = ACDB_DEV_TYPE_IN;
-        my_data->acdb_send_audio_cal(acdb_dev_id, acdb_dev_type);
+        my_data->acdb_send_audio_cal(acdb_dev_id, acdb_dev_type, app_type,
+                                     sample_rate);
     }
     return 0;
 }
diff --git a/hal/platform_api.h b/hal/platform_api.h
index 15deea5..1e97adf 100644
--- a/hal/platform_api.h
+++ b/hal/platform_api.h
@@ -32,7 +32,9 @@
 int platform_get_fluence_type(void *platform, char *value, uint32_t len);
 int platform_set_snd_device_acdb_id(snd_device_t snd_device, unsigned int acdb_id);
 int platform_get_snd_device_acdb_id(snd_device_t snd_device);
-int platform_send_audio_calibration(void *platform, snd_device_t snd_device);
+int platform_send_audio_calibration(void *platform, snd_device_t snd_device,
+                                    int app_type, int sample_rate);
+int platform_get_default_app_type(void *platform);
 int platform_switch_voice_call_device_pre(void *platform);
 int platform_switch_voice_call_enable_device_config(void *platform,
                                                     snd_device_t out_snd_device,