Merge "hal: Increase ffv process thread priority"
diff --git a/hal/audio_extn/utils.c b/hal/audio_extn/utils.c
index 433743e..3b70c2b 100644
--- a/hal/audio_extn/utils.c
+++ b/hal/audio_extn/utils.c
@@ -2136,8 +2136,9 @@
     void *hw_info = NULL;
     struct mixer *mixer = NULL;
     int retry_num = 0;
-    int snd_card_num = 0, min_snd_card_num = 0;
+    int snd_card_num = 0;
     char* snd_card_name = NULL;
+    int snd_card_detection_info[MAX_SND_CARD] = {0};
 
     if (!mixer_handle) {
         ALOGE("invalid mixer handle");
@@ -2145,26 +2146,29 @@
     }
     *mixer_handle = NULL;
     /*
-    * Try with all the sound cards ( 0 to 8 ) and if none of them were detected
+    * Try with all the sound cards ( 0 to 7 ) and if none of them were detected
     * sleep for 1 sec and try detections with sound card 0 again.
     * If sound card gets detected, check if it is relevant, if not check with the
     * other sound cards. To ensure that the irrelevant sound card is not check again,
     * we maintain it in min_snd_card_num.
     */
     while (retry_num < RETRY_NUMBER) {
-
-        while (snd_card_num <= MAX_SND_CARD) {
-           mixer = mixer_open(snd_card_num);
-           if (!mixer)
-              snd_card_num++;
-           else
-              break;
+        snd_card_num = 0;
+        while (snd_card_num < MAX_SND_CARD) {
+            if (snd_card_detection_info[snd_card_num] == 0) {
+                mixer = mixer_open(snd_card_num);
+                if (!mixer)
+                    snd_card_num++;
+                else
+                    break;
+            } else
+                snd_card_num++;
         }
 
         if (!mixer) {
            usleep(RETRY_US);
-           snd_card_num = min_snd_card_num;
            retry_num++;
+           ALOGD("%s: retry, retry_num %d", __func__, retry_num);
            continue;
         }
 
@@ -2175,18 +2179,13 @@
             return -1;
         }
         ALOGD("%s: snd_card_name: %s", __func__, snd_card_name);
-
+        snd_card_detection_info[snd_card_num] = 1;
         hw_info = hw_info_init(snd_card_name);
         if (hw_info) {
             ALOGD("%s: Opened sound card:%d", __func__, snd_card_num);
             break;
         }
-        ALOGE("%s: Failed to init hardware info", __func__);
-        min_snd_card_num++;
-        snd_card_num = min_snd_card_num;
-
-        if (snd_card_num >= MAX_SND_CARD)
-            break;
+        ALOGE("%s: Failed to init hardware info, snd_card_num:%d", __func__, snd_card_num);
 
         free(snd_card_name);
         snd_card_name = NULL;
@@ -2200,7 +2199,7 @@
     if (hw_info)
         hw_info_deinit(hw_info);
 
-    if ((snd_card_num >= MAX_SND_CARD) || (retry_num >= RETRY_NUMBER)) {
+    if (retry_num >= RETRY_NUMBER) {
         ALOGE("%s: Unable to find correct sound card, aborting.", __func__);
         return -1;
     }
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 967afdc..8f27e86 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -7085,6 +7085,7 @@
     struct listnode *node;
     struct audio_usecase *usecase = NULL;
     int ret = 0;
+
     pthread_mutex_lock(&adev->lock);
     if (adev->mode != mode) {
         ALOGD("%s: mode %d\n", __func__, mode);
@@ -7111,6 +7112,11 @@
             voice_stop_call(adev);
             platform_set_gsm_mode(adev->platform, false);
             adev->current_call_output = NULL;
+            // restore device for other active usecases after stop call
+            list_for_each(node, &adev->usecase_list) {
+                usecase = node_to_item(node, struct audio_usecase, list);
+                select_devices(adev, usecase->id);
+            }
         }
     }
     pthread_mutex_unlock(&adev->lock);
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index 3bf7628..63191a0 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -6029,7 +6029,7 @@
         my_data->current_backend_cfg[backend_idx].channels = channels;
 
         if (backend_idx == HDMI_RX_BACKEND)
-            platform_set_edid_channels_configuration(adev->platform, channels, HDMI_RX_BACKEND);
+            platform_set_edid_channels_configuration(adev->platform, channels, HDMI_RX_BACKEND, snd_device);
 
         ALOGD("%s:becf: afe: %s set to %s", __func__,
                my_data->current_backend_cfg[backend_idx].channels_mixer_ctl, channel_cnt_str);
@@ -6403,6 +6403,8 @@
 
         if (channels != my_data->current_backend_cfg[backend_idx].channels)
             channels_updated = true;
+
+        platform_set_edid_channels_configuration(adev->platform, channels, backend_idx, snd_device);
     }
 
     //check if mulitchannel clip needs to be down sampled to 48k
@@ -7064,7 +7066,7 @@
                 return -1;
         }
     }
-    ret = platform_set_channel_map(platform, channels, channel_map, snd_id);
+    ret = platform_set_channel_map(platform, channels, channel_map, snd_id, -1);
     return ret;
 }
 
@@ -7204,7 +7206,7 @@
     return ret;
 }
 
-int platform_set_channel_map(void *platform, int ch_count, char *ch_map, int snd_id)
+int platform_set_channel_map(void *platform, int ch_count, char *ch_map, int snd_id, int be_idx __unused)
 {
     struct mixer_ctl *ctl;
     char mixer_ctl_name[44] = {0}; // max length of name is 44 as defined
@@ -7366,7 +7368,7 @@
     return false;
 }
 
-int platform_set_edid_channels_configuration(void *platform, int channels, int backend_idx __unused) {
+int platform_set_edid_channels_configuration(void *platform, int channels, int backend_idx __unused, snd_device_t snd_device __unused) {
 
     struct platform_data *my_data = (struct platform_data *)platform;
     struct audio_device *adev = my_data->adev;
@@ -7399,9 +7401,9 @@
              */
             if (adev_device_cfg_ptr->use_client_dev_cfg) {
                 platform_set_channel_map(platform, adev_device_cfg_ptr->dev_cfg_params.channels,
-                                   (char *)adev_device_cfg_ptr->dev_cfg_params.channel_map, -1);
+                                   (char *)adev_device_cfg_ptr->dev_cfg_params.channel_map, -1, -1);
             } else {
-                platform_set_channel_map(platform, channel_count, info->channel_map, -1);
+                platform_set_channel_map(platform, channel_count, info->channel_map, -1, -1);
             }
 
             if (adev_device_cfg_ptr->use_client_dev_cfg) {
@@ -7420,7 +7422,7 @@
                 default_channelMap[0] = PCM_CHANNEL_FL;
                 default_channelMap[1] = PCM_CHANNEL_FR;
             }
-            platform_set_channel_map(platform,2,default_channelMap,-1);
+            platform_set_channel_map(platform, 2, default_channelMap, -1, -1);
             platform_set_channel_allocation(platform,0);
         }
     }
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 41ff789..72a1b41 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -4679,9 +4679,11 @@
         } else if (out_device &
                     (AUDIO_DEVICE_OUT_USB_DEVICE |
                      AUDIO_DEVICE_OUT_USB_HEADSET)) {
-          if (audio_extn_usb_is_capture_supported()) {
-              snd_device = SND_DEVICE_IN_VOICE_USB_HEADSET_MIC;
-          }
+            if (audio_extn_usb_is_capture_supported()) {
+                snd_device = SND_DEVICE_IN_VOICE_USB_HEADSET_MIC;
+            } else {
+                snd_device = SND_DEVICE_IN_HANDSET_MIC;
+            }
         }
     } else if (my_data->use_generic_handset == true &&  //     system prop is enabled
                (my_data->source_mic_type & SOURCE_QUAD_MIC) &&  // AND 4mic is available
@@ -6197,7 +6199,7 @@
 
         if ((backend_idx == HDMI_RX_BACKEND) ||
                 (backend_idx == DISP_PORT_RX_BACKEND))
-            platform_set_edid_channels_configuration(adev->platform, channels, backend_idx);
+            platform_set_edid_channels_configuration(adev->platform, channels, backend_idx, snd_device);
 
         ALOGD("%s:becf: afe: %s set to %s ", __func__,
                my_data->current_backend_cfg[backend_idx].channels_mixer_ctl,
@@ -6596,6 +6598,8 @@
 
         if (channels != my_data->current_backend_cfg[backend_idx].channels)
             channels_updated = true;
+
+        platform_set_edid_channels_configuration(adev->platform, channels, backend_idx, snd_device);
     }
 
     ALOGI("%s:becf: afe: Codec selected backend: %d updated bit width: %d and sample rate: %d",
@@ -7241,7 +7245,7 @@
                 return -1;
         }
     }
-    ret = platform_set_channel_map(platform, channels, channel_map, snd_id);
+    ret = platform_set_channel_map(platform, channels, channel_map, snd_id, -1);
     return ret;
 }
 
@@ -7355,13 +7359,15 @@
     return ret;
 }
 
-int platform_set_channel_map(void *platform, int ch_count, char *ch_map, int snd_id)
+int platform_set_channel_map(void *platform, int ch_count, char *ch_map, int snd_id, int be_idx)
 {
-    struct mixer_ctl *ctl;
+    struct mixer_ctl *ctl, *be_ctl = NULL;
     char mixer_ctl_name[44] = {0}; // max length of name is 44 as defined
+    char be_mixer_ctl_name[] = "Backend Device Channel Map";
     int ret;
     unsigned int i;
     long set_values[FCC_8] = {0};
+    long be_set_values[FCC_8 + 1] = {0};
     struct platform_data *my_data = (struct platform_data *)platform;
     struct audio_device *adev = my_data->adev;
     ALOGV("%s channel_count:%d",__func__, ch_count);
@@ -7377,7 +7383,19 @@
     if (snd_id >= 0) {
         snprintf(mixer_ctl_name, sizeof(mixer_ctl_name), "Playback Channel Map%d", snd_id);
     } else {
-        strlcpy(mixer_ctl_name, "Playback Device Channel Map", sizeof(mixer_ctl_name));
+        if (be_idx >=0) {
+            be_ctl = mixer_get_ctl_by_name(adev->mixer, be_mixer_ctl_name);
+            if (!be_ctl) {
+                ALOGD("%s: Could not get ctl for mixer cmd - %s, using default control",
+                       __func__, be_mixer_ctl_name);
+                strlcpy(mixer_ctl_name, "Playback Device Channel Map", sizeof(mixer_ctl_name));
+                be_idx = -1;
+            } else {
+                strlcpy(mixer_ctl_name, "Backend Device Channel Map", sizeof(mixer_ctl_name));
+            }
+        } else {
+            strlcpy(mixer_ctl_name, "Playback Device Channel Map", sizeof(mixer_ctl_name));
+        }
     }
 
     ALOGD("%s mixer_ctl_name:%s", __func__, mixer_ctl_name);
@@ -7396,7 +7414,13 @@
         set_values[0], set_values[1], set_values[2], set_values[3], set_values[4],
         set_values[5], set_values[6], set_values[7], ch_count);
 
-    ret = mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
+    if (be_idx >= 0) {
+        be_set_values[0] = be_idx;
+        memcpy(&be_set_values[1], set_values, sizeof(long) * ch_count);
+        ret = mixer_ctl_set_array(ctl, be_set_values, ARRAY_SIZE(be_set_values));
+    } else {
+        ret = mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
+    }
     if (ret < 0) {
         ALOGE("%s: Could not set ctl, error:%d ch_count:%d",
               __func__, ret, ch_count);
@@ -7561,7 +7585,7 @@
     return 0;
 }
 
-int platform_set_edid_channels_configuration(void *platform, int channels, int backend_idx) {
+int platform_set_edid_channels_configuration(void *platform, int channels, int backend_idx, snd_device_t snd_device) {
 
     struct platform_data *my_data = (struct platform_data *)platform;
     struct audio_device *adev = my_data->adev;
@@ -7570,6 +7594,7 @@
     int i, ret;
     char default_channelMap[MAX_CHANNELS_SUPPORTED] = {0};
     struct audio_device_config_param *adev_device_cfg_ptr = adev->device_cfg_params;
+    int be_idx = -1;
 
     if ((backend_idx != HDMI_RX_BACKEND) &&
             (backend_idx != DISP_PORT_RX_BACKEND)) {
@@ -7577,6 +7602,7 @@
         return -EINVAL;
     }
 
+    be_idx = platform_get_snd_device_backend_index(snd_device);
     ret = platform_get_edid_info(platform);
     info = (edid_audio_info *)my_data->edid_info;
     adev_device_cfg_ptr += backend_idx;
@@ -7599,9 +7625,9 @@
              */
             if (adev_device_cfg_ptr->use_client_dev_cfg) {
                 platform_set_channel_map(platform, adev_device_cfg_ptr->dev_cfg_params.channels,
-                                   (char *)adev_device_cfg_ptr->dev_cfg_params.channel_map, -1);
+                                   (char *)adev_device_cfg_ptr->dev_cfg_params.channel_map, -1, be_idx);
             } else {
-                platform_set_channel_map(platform, channel_count, info->channel_map, -1);
+                platform_set_channel_map(platform, channel_count, info->channel_map, -1, be_idx);
             }
 
             if (adev_device_cfg_ptr->use_client_dev_cfg) {
@@ -7620,7 +7646,7 @@
                 default_channelMap[0] = PCM_CHANNEL_FL;
                 default_channelMap[1] = PCM_CHANNEL_FR;
             }
-            platform_set_channel_map(platform,2,default_channelMap,-1);
+            platform_set_channel_map(platform, 2, default_channelMap, -1, be_idx);
             platform_set_channel_allocation(platform,0);
         }
     }
diff --git a/hal/platform_api.h b/hal/platform_api.h
index 80138c8..17afefc 100644
--- a/hal/platform_api.h
+++ b/hal/platform_api.h
@@ -225,7 +225,7 @@
 int platform_get_edid_info(void *platform);
 int platform_get_supported_copp_sampling_rate(uint32_t stream_sr);
 int platform_set_channel_map(void *platform, int ch_count, char *ch_map,
-                             int snd_id);
+                             int snd_id, int be_idx);
 int platform_set_stream_channel_map(void *platform, audio_channel_mask_t channel_mask,
                                    int snd_id, uint8_t *input_channel_map);
 int platform_set_stream_pan_scale_params(void *platform,
@@ -235,7 +235,8 @@
                                        int snd_id,
                                        snd_device_t snd_device,
                                        struct mix_matrix_params mm_params);
-int platform_set_edid_channels_configuration(void *platform, int channels, int backend_idx);
+int platform_set_edid_channels_configuration(void *platform, int channels,
+                                             int backend_idx, snd_device_t snd_device);
 unsigned char platform_map_to_edid_format(int format);
 bool platform_is_edid_supported_format(void *platform, int format);
 bool platform_is_edid_supported_sample_rate(void *platform, int sample_rate);