Merge "hal: Detect sound card dynamically"
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index c6d06df..6bd03ee 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -96,14 +96,11 @@
 #endif
 
 #ifndef AUDIO_LISTEN_ENABLED
-
 #define audio_extn_listen_init(adev, snd_card)                  (0)
 #define audio_extn_listen_deinit(adev)                          (0)
 #define audio_extn_listen_update_status(uc_info, event)         (0)
 #define audio_extn_listen_set_parameters(adev, parms)           (0)
-
 #else
-
 enum listen_event_type {
     LISTEN_EVENT_SND_DEVICE_FREE,
     LISTEN_EVENT_SND_DEVICE_BUSY
@@ -116,11 +113,10 @@
                                      listen_event_type_t event);
 void audio_extn_listen_set_parameters(struct audio_device *adev,
                                       struct str_parms *parms);
-
 #endif /* AUDIO_LISTEN_ENABLED */
 
 #ifndef AUXPCM_BT_ENABLED
-#define audio_extn_read_xml(adev, MIXER_CARD, MIXER_XML_PATH, \
+#define audio_extn_read_xml(adev, mixer_card, MIXER_XML_PATH, \
                             MIXER_XML_PATH_AUXPCM)               (-ENOSYS)
 #else
 int32_t audio_extn_read_xml(struct audio_device *adev, uint32_t mixer_card,
diff --git a/hal/audio_extn/fm.c b/hal/audio_extn/fm.c
index eeba404..a4157f8 100644
--- a/hal/audio_extn/fm.c
+++ b/hal/audio_extn/fm.c
@@ -170,10 +170,10 @@
               __func__, pcm_dev_rx_id, pcm_dev_tx_id, uc_info->id);
 
     ALOGV("%s: Opening PCM playback device card_id(%d) device_id(%d)",
-          __func__, SOUND_CARD, pcm_dev_rx_id);
-    fmmod.fm_pcm_rx = pcm_open(SOUND_CARD,
-                                  pcm_dev_rx_id,
-                                  PCM_OUT, &pcm_config_fm);
+          __func__, adev->snd_card, pcm_dev_rx_id);
+    fmmod.fm_pcm_rx = pcm_open(adev->snd_card,
+                               pcm_dev_rx_id,
+                               PCM_OUT, &pcm_config_fm);
     if (fmmod.fm_pcm_rx && !pcm_is_ready(fmmod.fm_pcm_rx)) {
         ALOGE("%s: %s", __func__, pcm_get_error(fmmod.fm_pcm_rx));
         ret = -EIO;
@@ -181,10 +181,10 @@
     }
 
     ALOGV("%s: Opening PCM capture device card_id(%d) device_id(%d)",
-          __func__, SOUND_CARD, pcm_dev_tx_id);
-    fmmod.fm_pcm_tx = pcm_open(SOUND_CARD,
-                                   pcm_dev_tx_id,
-                                   PCM_IN, &pcm_config_fm);
+          __func__, adev->snd_card, pcm_dev_tx_id);
+    fmmod.fm_pcm_tx = pcm_open(adev->snd_card,
+                               pcm_dev_tx_id,
+                               PCM_IN, &pcm_config_fm);
     if (fmmod.fm_pcm_tx && !pcm_is_ready(fmmod.fm_pcm_tx)) {
         ALOGE("%s: %s", __func__, pcm_get_error(fmmod.fm_pcm_tx));
         ret = -EIO;
diff --git a/hal/audio_extn/hfp.c b/hal/audio_extn/hfp.c
index e0bdc52..6b0546a 100644
--- a/hal/audio_extn/hfp.c
+++ b/hal/audio_extn/hfp.c
@@ -113,8 +113,8 @@
               __func__, pcm_dev_rx_id, pcm_dev_tx_id, uc_info->id);
 
     ALOGV("%s: Opening PCM playback device card_id(%d) device_id(%d)",
-          __func__, SOUND_CARD, pcm_dev_rx_id);
-    hfpmod.hfp_sco_rx = pcm_open(SOUND_CARD,
+          __func__, adev->snd_card, pcm_dev_rx_id);
+    hfpmod.hfp_sco_rx = pcm_open(adev->snd_card,
                                   pcm_dev_asm_rx_id,
                                   PCM_OUT, &pcm_config_hfp);
     if (hfpmod.hfp_sco_rx && !pcm_is_ready(hfpmod.hfp_sco_rx)) {
@@ -123,8 +123,8 @@
         goto exit;
     }
     ALOGD("%s: Opening PCM capture device card_id(%d) device_id(%d)",
-          __func__, SOUND_CARD, pcm_dev_tx_id);
-    hfpmod.hfp_pcm_rx = pcm_open(SOUND_CARD,
+          __func__, adev->snd_card, pcm_dev_tx_id);
+    hfpmod.hfp_pcm_rx = pcm_open(adev->snd_card,
                                    pcm_dev_rx_id,
                                    PCM_OUT, &pcm_config_hfp);
     if (hfpmod.hfp_pcm_rx && !pcm_is_ready(hfpmod.hfp_pcm_rx)) {
@@ -132,7 +132,7 @@
         ret = -EIO;
         goto exit;
     }
-    hfpmod.hfp_sco_tx = pcm_open(SOUND_CARD,
+    hfpmod.hfp_sco_tx = pcm_open(adev->snd_card,
                                   pcm_dev_asm_tx_id,
                                   PCM_IN, &pcm_config_hfp);
     if (hfpmod.hfp_sco_tx && !pcm_is_ready(hfpmod.hfp_sco_tx)) {
@@ -141,8 +141,8 @@
         goto exit;
     }
     ALOGV("%s: Opening PCM capture device card_id(%d) device_id(%d)",
-          __func__, SOUND_CARD, pcm_dev_tx_id);
-    hfpmod.hfp_pcm_tx = pcm_open(SOUND_CARD,
+          __func__, adev->snd_card, pcm_dev_tx_id);
+    hfpmod.hfp_pcm_tx = pcm_open(adev->snd_card,
                                    pcm_dev_tx_id,
                                    PCM_IN, &pcm_config_hfp);
     if (hfpmod.hfp_pcm_tx && !pcm_is_ready(hfpmod.hfp_pcm_tx)) {
diff --git a/hal/audio_extn/spkr_protection.c b/hal/audio_extn/spkr_protection.c
index 0fc790a..5ec7eba 100644
--- a/hal/audio_extn/spkr_protection.c
+++ b/hal/audio_extn/spkr_protection.c
@@ -240,8 +240,9 @@
         goto exit;
     }
     handle.pcm_rx = handle.pcm_tx = NULL;
-    handle.pcm_rx = pcm_open(SOUND_CARD, pcm_dev_rx_id,
-                    PCM_OUT, &pcm_config_skr_prot);
+    handle.pcm_rx = pcm_open(adev->snd_card,
+                             pcm_dev_rx_id,
+                             PCM_OUT, &pcm_config_skr_prot);
     if (handle.pcm_rx && !pcm_is_ready(handle.pcm_rx)) {
         ALOGE("%s: %s", __func__, pcm_get_error(handle.pcm_rx));
         status.status = -EIO;
@@ -267,8 +268,9 @@
         status.status = -ENODEV;
         goto exit;
     }
-    handle.pcm_tx = pcm_open(SOUND_CARD, pcm_dev_tx_id,
-                    PCM_IN, &pcm_config_skr_prot);
+    handle.pcm_tx = pcm_open(adev->snd_card,
+                             pcm_dev_tx_id,
+                             PCM_IN, &pcm_config_skr_prot);
     if (handle.pcm_tx && !pcm_is_ready(handle.pcm_tx)) {
         ALOGE("%s: %s", __func__, pcm_get_error(handle.pcm_tx));
         status.status = -EIO;
@@ -618,8 +620,9 @@
             ret = -ENODEV;
             goto exit;
         }
-        handle.pcm_tx = pcm_open(SOUND_CARD, pcm_dev_tx_id,
-                        PCM_IN, &pcm_config_skr_prot);
+        handle.pcm_tx = pcm_open(adev->snd_card,
+                                 pcm_dev_tx_id,
+                                 PCM_IN, &pcm_config_skr_prot);
         if (handle.pcm_tx && !pcm_is_ready(handle.pcm_tx)) {
             ALOGE("%s: %s", __func__, pcm_get_error(handle.pcm_tx));
             ret = -EIO;
diff --git a/hal/audio_extn/usb.c b/hal/audio_extn/usb.c
index 88af9be..88e3cad 100644
--- a/hal/audio_extn/usb.c
+++ b/hal/audio_extn/usb.c
@@ -348,7 +348,10 @@
         usbmod->proxy_pcm_playback_handle = pcm_open(usbmod->proxy_card,
                                             usbmod->proxy_device_id, PCM_IN |
                                      PCM_MMAP | PCM_NOIRQ, &pcm_config_usbmod);
-        if(!usbmod->proxy_pcm_playback_handle){
+        if(usbmod->proxy_pcm_playback_handle
+            && !pcm_is_ready(usbmod->proxy_pcm_playback_handle)){
+                     pcm_close(usbmod->proxy_pcm_playback_handle);
+                     usbmod->proxy_pcm_playback_handle = NULL;
                      proxy_open_retry_count--;
                      usleep(USB_PROXY_OPEN_WAIT_TIME * 1000);
                      ALOGE("%s: pcm_open for proxy failed retrying = %d",
@@ -463,7 +466,10 @@
         usbmod->proxy_pcm_record_handle = pcm_open(usbmod->proxy_card,
                                             usbmod->proxy_device_id, PCM_OUT |
                                      PCM_MMAP | PCM_NOIRQ, &pcm_config_usbmod);
-        if(!usbmod->proxy_pcm_record_handle){
+        if(usbmod->proxy_pcm_record_handle
+            && !pcm_is_ready(usbmod->proxy_pcm_record_handle)){
+                     pcm_close(usbmod->proxy_pcm_record_handle);
+                     usbmod->proxy_pcm_record_handle = NULL;
                      proxy_open_retry_count--;
                      usleep(USB_PROXY_OPEN_WAIT_TIME * 1000);
                      ALOGE("%s: pcm_open for proxy(recording) failed retrying = %d",
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index b8195b4..fc78610 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -796,9 +796,10 @@
     select_devices(adev, in->usecase);
 
     ALOGV("%s: Opening PCM device card_id(%d) device_id(%d), channels %d",
-          __func__, SOUND_CARD, in->pcm_device_id, in->config.channels);
-    in->pcm = pcm_open(SOUND_CARD, in->pcm_device_id,
-                           PCM_IN, &in->config);
+          __func__, adev->snd_card,
+          in->pcm_device_id, in->config.channels);
+    in->pcm = pcm_open(adev->snd_card,
+                       in->pcm_device_id, PCM_IN, &in->config);
     if (in->pcm && !pcm_is_ready(in->pcm)) {
         ALOGE("%s: %s", __func__, pcm_get_error(in->pcm));
         pcm_close(in->pcm);
@@ -1113,8 +1114,9 @@
     ALOGV("%s: Opening PCM device card_id(%d) device_id(%d)",
           __func__, 0, out->pcm_device_id);
     if (out->usecase != USECASE_AUDIO_PLAYBACK_OFFLOAD) {
-        out->pcm = pcm_open(SOUND_CARD, out->pcm_device_id,
-                               PCM_OUT | PCM_MONOTONIC, &out->config);
+        out->pcm = pcm_open(adev->snd_card,
+                            out->pcm_device_id,
+                            PCM_OUT | PCM_MONOTONIC, &out->config);
         if (out->pcm && !pcm_is_ready(out->pcm)) {
             ALOGE("%s: %s", __func__, pcm_get_error(out->pcm));
             pcm_close(out->pcm);
@@ -1124,7 +1126,8 @@
         }
     } else {
         out->pcm = NULL;
-        out->compr = compress_open(SOUND_CARD, out->pcm_device_id,
+        out->compr = compress_open(adev->snd_card,
+                                   out->pcm_device_id,
                                    COMPRESS_IN, &out->compr_config);
         if (out->compr && !is_compress_ready(out->compr)) {
             ALOGE("%s: %s", __func__, compress_get_error(out->compr));
@@ -2607,7 +2610,7 @@
                                                         "visualizer_hal_stop_output");
         }
     }
-    audio_extn_listen_init(adev, SOUND_CARD);
+    audio_extn_listen_init(adev, adev->snd_card);
 
     if (access(OFFLOAD_EFFECTS_BUNDLE_LIBRARY_PATH, R_OK) == 0) {
         adev->offload_effects_lib = dlopen(OFFLOAD_EFFECTS_BUNDLE_LIBRARY_PATH, RTLD_NOW);
diff --git a/hal/audio_hw.h b/hal/audio_hw.h
index ccb0298..3055470 100644
--- a/hal/audio_hw.h
+++ b/hal/audio_hw.h
@@ -223,6 +223,7 @@
     struct voice voice;
     unsigned int cur_hdmi_channels;
 
+    int snd_card;
     void *platform;
 
     void *visualizer_lib;
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index d88fb10..272dea8 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -53,6 +53,7 @@
 /* Retry for delay in FW loading*/
 #define RETRY_NUMBER 10
 #define RETRY_US 500000
+#define MAX_SND_CARD 8
 
 #define SAMPLE_RATE_8KHZ  8000
 #define SAMPLE_RATE_16KHZ 16000
@@ -428,38 +429,58 @@
     char platform[PROPERTY_VALUE_MAX];
     char baseband[PROPERTY_VALUE_MAX];
     char value[PROPERTY_VALUE_MAX];
-    struct platform_data *my_data;
-    int retry_num = 0;
+    struct platform_data *my_data = NULL;
+    int retry_num = 0, snd_card_num = 0;
     const char *snd_card_name;
 
-    adev->mixer = mixer_open(MIXER_CARD);
-
-    while (!adev->mixer && retry_num < RETRY_NUMBER) {
-        usleep(RETRY_US);
-        adev->mixer = mixer_open(MIXER_CARD);
-        retry_num++;
-    }
-
-    if (!adev->mixer) {
-        ALOGE("Unable to open the mixer, aborting.");
-        return NULL;
-    }
-
-    if (audio_extn_read_xml(adev, MIXER_CARD, MIXER_XML_PATH,
-                            MIXER_XML_PATH_AUXPCM) == -ENOSYS)
-        adev->audio_route = audio_route_init(MIXER_CARD, MIXER_XML_PATH);
-
-    if (!adev->audio_route) {
-        ALOGE("%s: Failed to init audio route controls, aborting.", __func__);
-        return NULL;
-    }
-
     my_data = calloc(1, sizeof(struct platform_data));
 
-    snd_card_name = mixer_get_name(adev->mixer);
-    my_data->hw_info = hw_info_init(snd_card_name);
-    if (!my_data->hw_info) {
-        ALOGE("%s: Failed to init hardware info", __func__);
+    while (snd_card_num < MAX_SND_CARD) {
+        adev->mixer = mixer_open(snd_card_num);
+
+        while (!adev->mixer && retry_num < RETRY_NUMBER) {
+            usleep(RETRY_US);
+            adev->mixer = mixer_open(snd_card_num);
+            retry_num++;
+        }
+
+        if (!adev->mixer) {
+            ALOGE("%s: Unable to open the mixer card: %d", __func__,
+                   snd_card_num);
+            retry_num = 0;
+            snd_card_num++;
+            continue;
+        }
+
+        snd_card_name = mixer_get_name(adev->mixer);
+        ALOGV("%s: snd_card_name: %s", __func__, snd_card_name);
+
+        my_data->hw_info = hw_info_init(snd_card_name);
+        if (!my_data->hw_info) {
+            ALOGE("%s: Failed to init hardware info", __func__);
+        } else {
+            if (audio_extn_read_xml(adev, snd_card_num, MIXER_XML_PATH,
+                                    MIXER_XML_PATH_AUXPCM) == -ENOSYS)
+                adev->audio_route = audio_route_init(snd_card_num,
+                                                 MIXER_XML_PATH);
+            if (!adev->audio_route) {
+                ALOGE("%s: Failed to init audio route controls, aborting.",
+                       __func__);
+                free(my_data);
+                return NULL;
+            }
+            adev->snd_card = snd_card_num;
+            ALOGD("%s: Opened sound card:%d", __func__, snd_card_num);
+            break;
+        }
+        retry_num = 0;
+        snd_card_num++;
+    }
+
+    if (snd_card_num >= MAX_SND_CARD) {
+        ALOGE("%s: Unable to find correct sound card, aborting.", __func__);
+        free(my_data);
+        return NULL;
     }
 
     my_data->adev = adev;
@@ -536,6 +557,8 @@
 
     /* init usb */
     audio_extn_usb_init(adev);
+    /* update sound cards appropriately */
+    audio_extn_usb_set_proxy_sound_card(adev->snd_card);
 
     /* Read one time ssr property */
     audio_extn_ssr_update_enabled(adev);
diff --git a/hal/msm8974/platform.h b/hal/msm8974/platform.h
index e05cba2..a791445 100644
--- a/hal/msm8974/platform.h
+++ b/hal/msm8974/platform.h
@@ -126,9 +126,6 @@
 
 };
 
-#define MIXER_CARD 0
-#define SOUND_CARD 0
-
 #define DEFAULT_OUTPUT_SAMPLING_RATE 48000
 
 #define ALL_SESSION_VSID                0xFFFFFFFF
diff --git a/hal/voice.c b/hal/voice.c
index afbd0af..cbf8956 100644
--- a/hal/voice.c
+++ b/hal/voice.c
@@ -135,8 +135,8 @@
     }
 
     ALOGV("%s: Opening PCM playback device card_id(%d) device_id(%d)",
-          __func__, SOUND_CARD, pcm_dev_rx_id);
-    session->pcm_rx = pcm_open(SOUND_CARD,
+          __func__, adev->snd_card, pcm_dev_rx_id);
+    session->pcm_rx = pcm_open(adev->snd_card,
                                pcm_dev_rx_id,
                                PCM_OUT, &voice_config);
     if (session->pcm_rx && !pcm_is_ready(session->pcm_rx)) {
@@ -146,8 +146,8 @@
     }
 
     ALOGV("%s: Opening PCM capture device card_id(%d) device_id(%d)",
-          __func__, SOUND_CARD, pcm_dev_tx_id);
-    session->pcm_tx = pcm_open(SOUND_CARD,
+          __func__, adev->snd_card, pcm_dev_tx_id);
+    session->pcm_tx = pcm_open(adev->snd_card,
                                pcm_dev_tx_id,
                                PCM_IN, &voice_config);
     if (session->pcm_tx && !pcm_is_ready(session->pcm_tx)) {
diff --git a/hal/voice_extn/compress_voip.c b/hal/voice_extn/compress_voip.c
index d5b0f0e..ee9fd30 100644
--- a/hal/voice_extn/compress_voip.c
+++ b/hal/voice_extn/compress_voip.c
@@ -348,8 +348,8 @@
         }
 
         ALOGD("%s: Opening PCM playback device card_id(%d) device_id(%d)",
-              __func__, SOUND_CARD, pcm_dev_rx_id);
-        voip_data.pcm_rx = pcm_open(SOUND_CARD,
+              __func__, adev->snd_card, pcm_dev_rx_id);
+        voip_data.pcm_rx = pcm_open(adev->snd_card,
                                     pcm_dev_rx_id,
                                     PCM_OUT, voip_config);
         if (voip_data.pcm_rx && !pcm_is_ready(voip_data.pcm_rx)) {
@@ -361,8 +361,8 @@
         }
 
         ALOGD("%s: Opening PCM capture device card_id(%d) device_id(%d)",
-              __func__, SOUND_CARD, pcm_dev_tx_id);
-        voip_data.pcm_tx = pcm_open(SOUND_CARD,
+              __func__, adev->snd_card, pcm_dev_tx_id);
+        voip_data.pcm_tx = pcm_open(adev->snd_card,
                                     pcm_dev_tx_id,
                                     PCM_IN, voip_config);
         if (voip_data.pcm_tx && !pcm_is_ready(voip_data.pcm_tx)) {