hal: add sample rate as a part of argument in gef callback

Add sample rate as a part of argument in gef callback, as client needs
this information to determine what's the exact sample rate COPP is
running and get calibration value accordingly.

If there's gef APIs call in callback, device lock will be probed twice.
Temproraily unlock device lock around GEF device change notification
to solve deadlock.

CRs-Fixed: 1094022
Change-Id: I47fdb1f88397e4340ba930113c64c140596bc62a
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index 2bde664..afc9a2e 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -665,7 +665,7 @@
 
 #define audio_extn_gef_init(adev) (0)
 #define audio_extn_gef_deinit() (0)
-#define audio_extn_gef_notify_device_config(devices, cmask, acdb_id) (0)
+#define audio_extn_gef_notify_device_config(devices, cmask, sample_rate, acdb_id) (0)
 #define audio_extn_gef_send_audio_cal(dev, acdb_dev_id, acdb_device_type,\
     app_type, topology_id, sample_rate, module_id, param_id, data, length, persist) (0)
 #define audio_extn_gef_get_audio_cal(adev, acdb_dev_id, acdb_device_type,\
@@ -681,7 +681,7 @@
 void audio_extn_gef_deinit();
 
 void audio_extn_gef_notify_device_config(audio_devices_t audio_device,
-    audio_channel_mask_t channel_mask, int acdb_id);
+    audio_channel_mask_t channel_mask, int sample_rate, int acdb_id);
 int audio_extn_gef_send_audio_cal(void* adev, int acdb_dev_id, int acdb_device_type,
     int app_type, int topology_id, int sample_rate, uint32_t module_id, uint32_t param_id,
     void* data, int length, bool persist);
diff --git a/hal/audio_extn/gef.c b/hal/audio_extn/gef.c
index d0ccd8c..dc5fbca 100644
--- a/hal/audio_extn/gef.c
+++ b/hal/audio_extn/gef.c
@@ -53,7 +53,7 @@
 
 typedef void* (*gef_init_t)(void*);
 typedef void (*gef_device_config_cb_t)(void*, audio_devices_t,
-    audio_channel_mask_t, int);
+    audio_channel_mask_t, int, int);
 
 typedef struct {
     void* handle;
@@ -259,14 +259,14 @@
 
 //this will be called from HAL to notify GEF of new device configuration
 void audio_extn_gef_notify_device_config(audio_devices_t audio_device,
-    audio_channel_mask_t channel_mask, int acdb_id)
+    audio_channel_mask_t channel_mask, int sample_rate, int acdb_id)
 {
     ALOGV("%s: Enter", __func__);
 
     //call into GEF to share channel mask and device info
     if (gef_hal_handle.handle && gef_hal_handle.device_config_cb) {
         gef_hal_handle.device_config_cb(gef_hal_handle.gef_ptr, audio_device, channel_mask,
-            acdb_id);
+            sample_rate, acdb_id);
     }
 
     ALOGV("%s: Exit", __func__);
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index d84515b..134ddb1 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -1599,11 +1599,35 @@
     audio_extn_utils_update_stream_app_type_cfg_for_usecase(adev,
                                                             usecase);
     if (usecase->type == PCM_PLAYBACK) {
+        if ((24 == usecase->stream.out->bit_width) &&
+                (usecase->stream.out->devices & AUDIO_DEVICE_OUT_SPEAKER)) {
+            usecase->stream.out->app_type_cfg.sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
+        } else if ((out_snd_device == SND_DEVICE_OUT_HDMI ||
+                    out_snd_device == SND_DEVICE_OUT_USB_HEADSET ||
+                    out_snd_device == SND_DEVICE_OUT_DISPLAY_PORT) &&
+                   (usecase->stream.out->sample_rate >= OUTPUT_SAMPLING_RATE_44100)) {
+            /*
+             * To best utlize DSP, check if the stream sample rate is supported/multiple of
+             * configured device sample rate, if not update the COPP rate to be equal to the
+             * device sample rate, else open COPP at stream sample rate
+             */
+            platform_check_and_update_copp_sample_rate(adev->platform, out_snd_device,
+                    usecase->stream.out->sample_rate,
+                    &usecase->stream.out->app_type_cfg.sample_rate);
+        } else if ((out_snd_device != SND_DEVICE_OUT_HEADPHONES_44_1 &&
+                    usecase->stream.out->sample_rate == OUTPUT_SAMPLING_RATE_44100) ||
+                    (usecase->stream.out->sample_rate < OUTPUT_SAMPLING_RATE_44100)) {
+            usecase->stream.out->app_type_cfg.sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
+        }
+
         /* Notify device change info to effect clients registered */
+        pthread_mutex_unlock(&adev->lock);
         audio_extn_gef_notify_device_config(
                 usecase->stream.out->devices,
                 usecase->stream.out->channel_mask,
+                usecase->stream.out->app_type_cfg.sample_rate,
                 platform_get_snd_device_acdb_id(usecase->out_snd_device));
+        pthread_mutex_lock(&adev->lock);
     }
     enable_audio_route(adev, usecase);
 
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 462a18a..55644d9 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -832,6 +832,32 @@
        {AUDIO_DEVICE_NONE                               ,      -1},
        {AUDIO_DEVICE_OUT_DEFAULT                        ,      -1},
 };
+#elif PLATFORM_MSM8998
+static int msm_device_to_be_id [][NO_COLS] = {
+       {AUDIO_DEVICE_OUT_EARPIECE                       ,       2},
+       {AUDIO_DEVICE_OUT_SPEAKER                        ,       2},
+       {AUDIO_DEVICE_OUT_WIRED_HEADSET                  ,       41},
+       {AUDIO_DEVICE_OUT_WIRED_HEADPHONE                ,       41},
+       {AUDIO_DEVICE_OUT_BLUETOOTH_SCO                  ,       11},
+       {AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET          ,       11},
+       {AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT           ,       11},
+       {AUDIO_DEVICE_OUT_BLUETOOTH_A2DP                 ,       -1},
+       {AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES      ,       -1},
+       {AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER         ,       -1},
+       {AUDIO_DEVICE_OUT_AUX_DIGITAL                    ,       4},
+       {AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET              ,       9},
+       {AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET              ,       9},
+       {AUDIO_DEVICE_OUT_USB_ACCESSORY                  ,       -1},
+       {AUDIO_DEVICE_OUT_USB_DEVICE                     ,       -1},
+       {AUDIO_DEVICE_OUT_REMOTE_SUBMIX                  ,       9},
+       {AUDIO_DEVICE_OUT_PROXY                          ,       9},
+/* Add the correct be ids */
+       {AUDIO_DEVICE_OUT_FM                             ,       7},
+       {AUDIO_DEVICE_OUT_FM_TX                          ,       8},
+       {AUDIO_DEVICE_OUT_ALL                            ,      -1},
+       {AUDIO_DEVICE_NONE                               ,      -1},
+       {AUDIO_DEVICE_OUT_DEFAULT                        ,      -1},
+};
 #else
 static int msm_device_to_be_id [][NO_COLS] = {
     {AUDIO_DEVICE_NONE, -1},