hal: Enable support for multichannel tunnel USB.

-Update platform_check_codec api to enable support for multichannel
tunnel USB
-Update condition to check if voice call is active on a specific backend
then only force configure it
-Update the check to ensure that offload callback is triggered only for
non blocking writes.

Change-Id: I0dbd61c28b24cdba22f63b0e014eb7c362e2df34
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index 1d5b12e..d2cb9d3 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -165,7 +165,7 @@
 void audio_extn_usb_remove_device(audio_devices_t device, int card);
 bool audio_extn_usb_is_config_supported(unsigned int *bit_width,
                                         unsigned int *sample_rate,
-                                        unsigned int ch);
+                                        unsigned int *ch);
 int audio_extn_usb_enable_sidetone(int device, bool enable);
 int audio_extn_usb_set_sidetone_gain(struct str_parms *parms,
                                      char *value, int len);
diff --git a/hal/audio_extn/usb.c b/hal/audio_extn/usb.c
index 9e19eba..f95d6a7 100644
--- a/hal/audio_extn/usb.c
+++ b/hal/audio_extn/usb.c
@@ -739,7 +739,7 @@
                  "%s: USB ch(%d)bw(%d), stm ch(%d)bw(%d)sr(%d), candidate(%d)",
                  __func__, dev_info->channels, dev_info->bit_width,
                  ch, bit_width, stream_sample_rate, candidate);
-        if ((dev_info->bit_width != bit_width) && dev_info->channels != ch)
+        if ((dev_info->bit_width != bit_width) || dev_info->channels != ch)
             continue;
 
         candidate = 0;
@@ -786,34 +786,32 @@
 static bool usb_audio_backend_apply_policy(struct listnode *dev_list,
                                            unsigned int *bit_width,
                                            unsigned int *sample_rate,
-                                           unsigned int ch)
+                                           unsigned int *ch)
 {
-    unsigned int channel;
     bool is_usb_supported = true;
 
     ALOGV("%s: from stream: bit-width(%d) sample_rate(%d) channels (%d)",
-           __func__, *bit_width, *sample_rate, ch);
+           __func__, *bit_width, *sample_rate, *ch);
     if (list_empty(dev_list)) {
         *sample_rate = 48000;
         *bit_width = 16;
-        channel = 2;
+        *ch = 2;
         ALOGI("%s: list is empty,fall back to default setting", __func__);
         goto exit;
     }
     usb_get_best_match_for_bit_width(dev_list, *bit_width, bit_width);
     usb_get_best_match_for_channels(dev_list,
                                     *bit_width,
-                                    ch,
-                                    &channel);
+                                    *ch,
+                                    ch);
     usb_get_best_match_for_sample_rate(dev_list,
                                        *bit_width,
-                                       channel,
+                                       *ch,
                                        *sample_rate,
                                        sample_rate);
 exit:
     ALOGV("%s: Updated sample rate per profile: bit-width(%d) rate(%d) chs(%d)",
-           __func__, *bit_width, *sample_rate, channel);
-    usb_set_channel_mixer_ctl(channel, "USB_AUDIO_RX Channels");
+           __func__, *bit_width, *sample_rate, *ch);
     return is_usb_supported;
 }
 
@@ -885,14 +883,14 @@
 
 bool audio_extn_usb_is_config_supported(unsigned int *bit_width,
                                         unsigned int *sample_rate,
-                                        unsigned int ch)
+                                        unsigned int *ch)
 {
     struct listnode *node_i;
     struct usb_card_config *card_info;
     bool is_usb_supported = false;
 
     ALOGV("%s: from stream: bit-width(%d) sample_rate(%d) ch(%d)",
-           __func__, *bit_width, *sample_rate, ch);
+           __func__, *bit_width, *sample_rate, *ch);
     list_for_each(node_i, &usbmod->usb_card_conf_list) {
         card_info = node_to_item(node_i, struct usb_card_config, list);
         ALOGI_IF(usb_audio_debug_enable,
@@ -908,8 +906,8 @@
             break;
         }
     }
-    ALOGV("%s: updated: bit-width(%d) sample_rate(%d)",
-           __func__, *bit_width, *sample_rate);
+    ALOGV("%s: updated: bit-width(%d) sample_rate(%d) channels (%d)",
+           __func__, *bit_width, *sample_rate, *ch);
 
     return is_usb_supported;
 }
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index ee7647e..3077f89 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -934,6 +934,7 @@
             (usecase->out_snd_device != snd_device || force_routing) &&
             ((usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND) ||
              (usecase->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) ||
+             (usecase->devices & AUDIO_DEVICE_OUT_USB_DEVICE) ||
              (force_restart_session)) &&
             (platform_check_backends_match(snd_device, usecase->out_snd_device)||
              (platform_check_codec_asrc_support(adev->platform) && !adev->asrc_mode_enabled &&
@@ -2786,7 +2787,8 @@
         if (ret < 0)
             ret = -errno;
         ALOGVV("%s: writing buffer (%zu bytes) to compress device returned %zd", __func__, bytes, ret);
-        if (ret >= 0 && ret < (ssize_t)bytes) {
+        /*msg to cb thread only if non blocking write is enabled*/
+        if (ret >= 0 && ret < (ssize_t)bytes && out->non_blocking) {
             ALOGD("No space available in compress driver, post msg to cb thread");
             send_offload_cmd_l(out, OFFLOAD_CMD_WAIT_FOR_BUFFER);
         } else if (-ENETRESET == ret) {
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index 7fe114b..07def67 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -1231,6 +1231,8 @@
     hw_interface_table[SND_DEVICE_OUT_SPEAKER_AND_HDMI] = strdup("SLIMBUS_0_RX-and-HDMI_RX");
     hw_interface_table[SND_DEVICE_OUT_DISPLAY_PORT] = strdup("DISPLAY_PORT_RX");
     hw_interface_table[SND_DEVICE_OUT_SPEAKER_AND_DISPLAY_PORT] = strdup("SLIMBUS_0_RX-and-DISPLAY_PORT_RX");
+    hw_interface_table[SND_DEVICE_OUT_USB_HEADSET] = strdup("USB_AUDIO_RX");
+    hw_interface_table[SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET] = strdup("SLIMBUS_0_RX-and-USB_AUDIO_RX");
     hw_interface_table[SND_DEVICE_OUT_VOICE_TX] = strdup("AFE_PCM_RX");
 
     my_data->max_mic_count = PLATFORM_DEFAULT_MIC_COUNT;
@@ -1894,6 +1896,10 @@
         if (idx == HEADPHONE_44_1_BACKEND)
             my_data->current_backend_cfg[idx].sample_rate = OUTPUT_SAMPLING_RATE_44100;
         my_data->current_backend_cfg[idx].bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
+        my_data->current_backend_cfg[idx].channels = CODEC_BACKEND_DEFAULT_CHANNELS;
+        my_data->current_backend_cfg[idx].bitwidth_mixer_ctl = NULL;
+        my_data->current_backend_cfg[idx].samplerate_mixer_ctl = NULL;
+        my_data->current_backend_cfg[idx].channels_mixer_ctl = NULL;
     }
 
     my_data->current_tx_backend_cfg[DEFAULT_CODEC_BACKEND].sample_rate =
@@ -1937,6 +1943,8 @@
         strdup("USB_AUDIO_RX Format");
     my_data->current_backend_cfg[USB_AUDIO_RX_BACKEND].samplerate_mixer_ctl =
         strdup("USB_AUDIO_RX SampleRate");
+    my_data->current_backend_cfg[USB_AUDIO_RX_BACKEND].channels_mixer_ctl =
+        strdup("USB_AUDIO_RX Channels");
 
     my_data->current_backend_cfg[HDMI_RX_BACKEND].bitwidth_mixer_ctl =
         strdup("HDMI_RX Bit Format");
@@ -2456,14 +2464,14 @@
     return ret;
 }
 
-int check_44100_support_device(audio_devices_t out_device)
+int codec_device_supports_native_playback(audio_devices_t out_device)
 {
-    int ret = true;
+    int ret = false;
 
     if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
         out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET ||
         out_device & AUDIO_DEVICE_OUT_LINE)
-        ret = false;
+        ret = true;
 
     return ret;
 }
@@ -4154,6 +4162,29 @@
     return fragment_size;
 }
 
+/*
+ * return backend_idx on which voice call is active
+ */
+static int platform_get_voice_call_backend(struct audio_device* adev)
+{
+   struct audio_usecase *uc = NULL;
+   struct listnode *node;
+   snd_device_t out_snd_device = SND_DEVICE_NONE;
+
+   int backend_idx = -1;
+
+   if (voice_is_in_call(adev) || adev->mode == AUDIO_MODE_IN_COMMUNICATION) {
+       list_for_each(node, &adev->usecase_list) {
+           uc =  node_to_item(node, struct audio_usecase, list);
+           if (uc && (uc->type == VOICE_CALL || uc->type == VOIP_CALL) && uc->stream.out) {
+               out_snd_device = platform_get_output_snd_device(adev->platform, uc->stream.out);
+               backend_idx = platform_get_backend_index(out_snd_device);
+               break;
+           }
+       }
+   }
+   return backend_idx;
+}
 
 /*
  * configures afe with bit width and Sample Rate
@@ -4265,7 +4296,7 @@
             mixer_ctl_set_enum_by_string(ctl, rate_str);
             my_data->current_backend_cfg[backend_idx].sample_rate = sample_rate;
     }
-    if ((backend_idx == HDMI_RX_BACKEND || backend_idx == DISP_PORT_RX_BACKEND) &&
+    if ((my_data->current_backend_cfg[backend_idx].channels_mixer_ctl) &&
         (channels != my_data->current_backend_cfg[backend_idx].channels)) {
         struct  mixer_ctl *ctl;
         char *channel_cnt_str = NULL;
@@ -4297,7 +4328,10 @@
         }
         mixer_ctl_set_enum_by_string(ctl, channel_cnt_str);
         my_data->current_backend_cfg[backend_idx].channels = channels;
-        platform_set_edid_channels_configuration(adev->platform, channels);
+
+        if (backend_idx == HDMI_RX_BACKEND)
+            platform_set_edid_channels_configuration(adev->platform, channels);
+
         ALOGD("%s:becf: afe: %s set to %s", __func__,
                my_data->current_backend_cfg[backend_idx].channels_mixer_ctl, channel_cnt_str);
     }
@@ -4427,7 +4461,6 @@
     bool passthrough_enabled = false;
     int backend_idx = DEFAULT_CODEC_BACKEND;
     struct platform_data *my_data = (struct platform_data *)adev->platform;
-    int na_mode = platform_get_native_support();
     bool channels_updated = false;
 
     backend_idx = platform_get_backend_index(snd_device);
@@ -4442,8 +4475,7 @@
     // For voice calls use default configuration i.e. 16b/48K, only applicable to
     // default backend
     // force routing is not required here, caller will do it anyway
-    if ((voice_is_in_call(adev) || adev->mode == AUDIO_MODE_IN_COMMUNICATION) &&
-        usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND) {
+    if (backend_idx == platform_get_voice_call_backend(adev)) {
         ALOGW("%s:becf: afe:Use default bw and sr for voice/voip calls ",
               __func__);
         bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
@@ -4486,52 +4518,45 @@
         }
     }
 
-    if (audio_is_true_native_stream_active(adev)) {
-        if (check_hdset_combo_device(snd_device)) {
-        /*
-         * In true native mode Tasha has a limitation that one port at 44.1 khz
-         * cannot drive both spkr and hdset, to simiplify the solution lets
-         * move the AFE to 48khzwhen a ring tone selects combo device.
-         */
-            sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
-            bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
-            ALOGD("%s:becf: afe: port has to run at 48k for a combo device",
-                  __func__);
-        } else {
-        /*
-         * in single BE mode, if native audio playback
-         * is active then it will take priority
-         */
-            sample_rate = OUTPUT_SAMPLING_RATE_44100;
-            ALOGD("%s:becf: afe: napb active set rate to 44.1 khz",
-                  __func__);
+    /* Native playback is preferred for Headphone/HS device over 192Khz */
+    if (codec_device_supports_native_playback(usecase->devices)) {
+        if (audio_is_true_native_stream_active(adev)) {
+            if (check_hdset_combo_device(snd_device)) {
+                /*
+                 * In true native mode Tasha has a limitation that one port at 44.1 khz
+                 * cannot drive both spkr and hdset, to simiplify the solution lets
+                 * move the AFE to 48khzwhen a ring tone selects combo device.
+                 * or if NATIVE playback is not enabled.
+                 */
+                    sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
+                    bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
+                    ALOGD("%s:becf: afe: port has to run at 48k for a combo device",
+                          __func__);
+            } else {
+             /*
+              * in single BE mode, if native audio playback
+              * is active then it will take priority
+              */
+                 sample_rate = OUTPUT_SAMPLING_RATE_44100;
+                 ALOGD("%s:becf: afe: true napb active set rate to 44.1 khz",
+                       __func__);
+            }
+        } else if (OUTPUT_SAMPLING_RATE_44100 == sample_rate) {
+                 sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
+                 ALOGD("%s:becf: afe: napb not active - set (48k) default rate",
+                       __func__);
         }
-    }
-
-    /*
-     * hifi playback not supported on non-44.1-support devices, limit the Sample Rate
-     * to 48 khz.
-     */
-    if (check_44100_support_device(usecase->devices)) {
+    } else if ((usecase->devices & AUDIO_DEVICE_OUT_SPEAKER) ||
+               (usecase->devices & AUDIO_DEVICE_OUT_EARPIECE) ) {
         sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
-        ALOGD("%s:becf: afe: playback on non-44.1-support device Configure afe to "
+        ALOGD("%s:becf: afe: playback on codec device not supporting native playback set "
             "default Sample Rate(48k)", __func__);
     }
 
     /*
-     * native playback is not enabled.Configure afe to default Sample Rate(48k)
-     */
-    if (NATIVE_AUDIO_MODE_INVALID == na_mode &&
-            OUTPUT_SAMPLING_RATE_44100 == sample_rate) {
-        sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
-        ALOGD("%s:becf: afe: napb not active - set (48k) default rate",
-              __func__);
-    }
-
-    /*
      * reset the sample rate to default value(48K), if hifi audio is not supported
      */
-    if (!my_data->hifi_audio) {
+    if (!my_data->hifi_audio && (usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND)) {
                ALOGD("%s:becf: afe: only 48KHZ sample rate is supported "
                       "Configure afe to default Sample Rate(48k)", __func__);
                sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
@@ -4571,10 +4596,11 @@
     }
 
     if (backend_idx == USB_AUDIO_RX_BACKEND) {
-        unsigned int channels = audio_channel_count_from_out_mask(usecase->stream.out->channel_mask);
-        audio_extn_usb_is_config_supported(&bit_width, &sample_rate, channels);
+        audio_extn_usb_is_config_supported(&bit_width, &sample_rate, &channels);
         ALOGV("%s: USB BE configured as bit_width(%d)sample_rate(%d)channels(%d)",
                    __func__, bit_width, sample_rate, channels);
+        if (channels != my_data->current_backend_cfg[backend_idx].channels)
+            channels_updated = true;
     }
 
     ALOGI("%s:becf: afe: Codec selected backend: %d updated bit width: %d and sample rate: %d",
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index ff062b6..8327130 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -1129,6 +1129,8 @@
     hw_interface_table[SND_DEVICE_OUT_SPEAKER_AND_HDMI] = strdup("SLIMBUS_0_RX-and-HDMI_RX");
     hw_interface_table[SND_DEVICE_OUT_DISPLAY_PORT] = strdup("DISPLAY_PORT_RX");
     hw_interface_table[SND_DEVICE_OUT_SPEAKER_AND_DISPLAY_PORT] = strdup("SLIMBUS_0_RX-and-DISPLAY_PORT_RX");
+    hw_interface_table[SND_DEVICE_OUT_USB_HEADSET] = strdup("USB_AUDIO_RX");
+    hw_interface_table[SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET] = strdup("SLIMBUS_0_RX-and-USB_AUDIO_RX");
     hw_interface_table[SND_DEVICE_OUT_VOICE_TX] = strdup("AFE_PCM_RX");
 
     my_data->max_mic_count = PLATFORM_DEFAULT_MIC_COUNT;
@@ -1728,6 +1730,10 @@
         if (idx == HEADPHONE_44_1_BACKEND)
             my_data->current_backend_cfg[idx].sample_rate = OUTPUT_SAMPLING_RATE_44100;
         my_data->current_backend_cfg[idx].bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
+        my_data->current_backend_cfg[idx].channels = CODEC_BACKEND_DEFAULT_CHANNELS;
+        my_data->current_backend_cfg[idx].bitwidth_mixer_ctl = NULL;
+        my_data->current_backend_cfg[idx].samplerate_mixer_ctl = NULL;
+        my_data->current_backend_cfg[idx].channels_mixer_ctl = NULL;
     }
 
     my_data->current_backend_cfg[DEFAULT_CODEC_BACKEND].bitwidth_mixer_ctl =
@@ -1798,6 +1804,8 @@
         strdup("USB_AUDIO_RX Format");
     my_data->current_backend_cfg[USB_AUDIO_RX_BACKEND].samplerate_mixer_ctl =
         strdup("USB_AUDIO_RX SampleRate");
+    my_data->current_backend_cfg[USB_AUDIO_RX_BACKEND].channels_mixer_ctl =
+        strdup("USB_AUDIO_RX Channels");
 
     my_data->edid_info = NULL;
     free(snd_card_name);
@@ -2305,14 +2313,14 @@
     return ret;
 }
 
-int check_44100_support_device(audio_devices_t out_device)
+int codec_device_supports_native_playback(audio_devices_t out_device)
 {
-    int ret = true;
+    int ret = false;
 
     if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
         out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET ||
         out_device & AUDIO_DEVICE_OUT_LINE)
-        ret = false;
+        ret = true;
 
     return ret;
 }
@@ -4194,6 +4202,30 @@
 }
 
 /*
+ * return backend_idx on which voice call is active
+ */
+static int platform_get_voice_call_backend(struct audio_device* adev)
+{
+   struct audio_usecase *uc = NULL;
+   struct listnode *node;
+   snd_device_t out_snd_device = SND_DEVICE_NONE;
+
+   int backend_idx = -1;
+
+   if (voice_is_in_call(adev) || adev->mode == AUDIO_MODE_IN_COMMUNICATION) {
+       list_for_each(node, &adev->usecase_list) {
+           uc =  node_to_item(node, struct audio_usecase, list);
+           if (uc && (uc->type == VOICE_CALL || uc->type == VOIP_CALL) && uc->stream.out) {
+               out_snd_device = platform_get_output_snd_device(adev->platform, uc->stream.out);
+               backend_idx = platform_get_backend_index(out_snd_device);
+               break;
+           }
+       }
+   }
+   return backend_idx;
+}
+
+/*
  * configures afe with bit width and Sample Rate
  */
 static int platform_set_codec_backend_cfg(struct audio_device* adev,
@@ -4296,7 +4328,7 @@
             mixer_ctl_set_enum_by_string(ctl, rate_str);
             my_data->current_backend_cfg[backend_idx].sample_rate = sample_rate;
     }
-    if ((backend_idx == HDMI_RX_BACKEND || backend_idx == DISP_PORT_RX_BACKEND) &&
+    if ((my_data->current_backend_cfg[backend_idx].channels_mixer_ctl) &&
         (channels != my_data->current_backend_cfg[backend_idx].channels)) {
         struct  mixer_ctl *ctl;
         char *channel_cnt_str = NULL;
@@ -4328,7 +4360,10 @@
         }
         mixer_ctl_set_enum_by_string(ctl, channel_cnt_str);
         my_data->current_backend_cfg[backend_idx].channels = channels;
-        platform_set_edid_channels_configuration(adev->platform, channels);
+
+        if (backend_idx == HDMI_RX_BACKEND)
+            platform_set_edid_channels_configuration(adev->platform, channels);
+
         ALOGD("%s:becf: afe: %s set to %s", __func__,
                my_data->current_backend_cfg[backend_idx].channels_mixer_ctl, channel_cnt_str);
     }
@@ -4484,12 +4519,12 @@
     // For voice calls use default configuration i.e. 16b/48K, only applicable to
     // default backend
     // force routing is not required here, caller will do it anyway
-    if ((voice_is_in_call(adev) || adev->mode == AUDIO_MODE_IN_COMMUNICATION) &&
-        usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND) {
+    if (backend_idx == platform_get_voice_call_backend(adev)) {
         ALOGW("%s:becf: afe:Use default bw and sr for voice/voip calls ",
               __func__);
         bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
         sample_rate =  CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
+        channels = CODEC_BACKEND_DEFAULT_CHANNELS;
     } else {
         /*
          * The backend should be configured at highest bit width and/or
@@ -4528,53 +4563,47 @@
         }
     }
 
-    if (audio_is_true_native_stream_active(adev)) {
-        if (check_hdset_combo_device(snd_device)) {
-        /*
-         * In true native mode Tasha has a limitation that one port at 44.1 khz
-         * cannot drive both spkr and hdset, to simiplify the solution lets
-         * move the AFE to 48khzwhen a ring tone selects combo device.
-         */
-            sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
-            bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
-            ALOGD("%s:becf: afe: port has to run at 48k for a combo device",
-                  __func__);
-        } else {
-        /*
-         * in single BE mode, if native audio playback
-         * is active then it will take priority
-         */
-            sample_rate = OUTPUT_SAMPLING_RATE_44100;
-            ALOGD("%s:becf: afe: true napb active set rate to 44.1 khz",
-                  __func__);
+    /* Native playback is preferred for Headphone/HS device over 192Khz */
+    if (codec_device_supports_native_playback(usecase->devices)) {
+        if (audio_is_true_native_stream_active(adev)) {
+            if (check_hdset_combo_device(snd_device)) {
+                /*
+                 * In true native mode Tasha has a limitation that one port at 44.1 khz
+                 * cannot drive both spkr and hdset, to simiplify the solution lets
+                 * move the AFE to 48khzwhen a ring tone selects combo device.
+                 * or if NATIVE playback is not enabled.
+                 */
+                    sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
+                    bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
+                    ALOGD("%s:becf: afe: port has to run at 48k for a combo device",
+                          __func__);
+            } else {
+             /*
+              * in single BE mode, if native audio playback
+              * is active then it will take priority
+              */
+                 sample_rate = OUTPUT_SAMPLING_RATE_44100;
+                 ALOGD("%s:becf: afe: true napb active set rate to 44.1 khz",
+                       __func__);
+            }
+        } else if (OUTPUT_SAMPLING_RATE_44100 == sample_rate) {
+                 sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
+                 ALOGD("%s:becf: afe: napb not active - set (48k) default rate",
+                       __func__);
         }
-    }
-
-    /*
-     * hifi playback not supported on non-44.1-support devices, limit the Sample Rate
-     * to 48 khz.
-     */
-    if (check_44100_support_device(usecase->devices)) {
+    } else if ((usecase->devices & AUDIO_DEVICE_OUT_SPEAKER) ||
+               (usecase->devices & AUDIO_DEVICE_OUT_EARPIECE) ) {
         sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
-        ALOGD("%s:becf: afe: playback on non-44.1-support device Configure afe to "
+        ALOGD("%s:becf: afe: playback on codec device not supporting native playback set "
             "default Sample Rate(48k)", __func__);
     }
 
-    /*
-     * native playback is not enabled.Configure afe to default Sample Rate(48k)
-     */
-    if (NATIVE_AUDIO_MODE_INVALID == na_mode &&
-            OUTPUT_SAMPLING_RATE_44100 == sample_rate) {
-        sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
-        ALOGD("%s:becf: afe: napb not active - set (48k) default rate",
-              __func__);
-    }
-
     if (backend_idx == USB_AUDIO_RX_BACKEND) {
-        unsigned int channels = audio_channel_count_from_out_mask(usecase->stream.out->channel_mask);
-        audio_extn_usb_is_config_supported(&bit_width, &sample_rate, channels);
+        audio_extn_usb_is_config_supported(&bit_width, &sample_rate, &channels);
         ALOGV("%s: USB BE configured as bit_width(%d)sample_rate(%d)channels(%d)",
                    __func__, bit_width, sample_rate, channels);
+        if (channels != my_data->current_backend_cfg[backend_idx].channels)
+            channels_updated = true;
     }
 
     if (backend_idx == HDMI_RX_BACKEND || backend_idx == DISP_PORT_RX_BACKEND) {
diff --git a/hal/platform_api.h b/hal/platform_api.h
index 25ff64c..6ca95db 100644
--- a/hal/platform_api.h
+++ b/hal/platform_api.h
@@ -23,6 +23,7 @@
 
 #define CODEC_BACKEND_DEFAULT_BIT_WIDTH 16
 #define CODEC_BACKEND_DEFAULT_SAMPLE_RATE 48000
+#define CODEC_BACKEND_DEFAULT_CHANNELS 2
 
 enum {
     NATIVE_AUDIO_MODE_SRC = 1,