Merge "msmnile: update speaker mic for qrd device" into audio-hal.lnx.5.0
diff --git a/configs/msmnile/msmnile.mk b/configs/msmnile/msmnile.mk
index b837e05..e515548 100644
--- a/configs/msmnile/msmnile.mk
+++ b/configs/msmnile/msmnile.mk
@@ -65,6 +65,7 @@
 AUDIO_FEATURE_ENABLED_RAS := true
 AUDIO_FEATURE_ENABLED_SND_MONITOR := true
 AUDIO_FEATURE_ENABLED_DLKM := true
+AUDIO_FEATURE_ENABLED_USB_BURST_MODE := true
 ##AUDIO_FEATURE_FLAGS
 
 #Audio Specific device overlays
diff --git a/hal/Android.mk b/hal/Android.mk
index 4d107e5..fec5236 100644
--- a/hal/Android.mk
+++ b/hal/Android.mk
@@ -401,6 +401,10 @@
     LOCAL_CFLAGS += -DINSTANCE_ID_ENABLED
 endif
 
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_USB_BURST_MODE)), true)
+    LOCAL_CFLAGS += -DUSB_BURST_MODE_ENABLED
+endif
+
 LOCAL_CFLAGS += -Wall -Werror
 
 LOCAL_COPY_HEADERS_TO   := mm-audio
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
old mode 100755
new mode 100644
index 66e2166..090cd15
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -222,6 +222,7 @@
 #define audio_extn_usb_get_sup_sample_rates(t, s, l)                   (0)
 #define audio_extn_usb_is_tunnel_supported()                           (0)
 #define audio_extn_usb_alive(adev)                                     (false)
+#undef USB_BURST_MODE_ENABLED
 #else
 void audio_extn_usb_init(void *adev);
 void audio_extn_usb_deinit();
@@ -242,6 +243,32 @@
 bool audio_extn_usb_alive(int card);
 #endif
 
+#ifndef USB_BURST_MODE_ENABLED
+#define audio_extn_usb_find_service_interval(m, p)                     (0)
+#define audio_extn_usb_altset_for_service_interval(p, si, bw, sr, ch)  (-1)
+#define audio_extn_usb_set_service_interval(p, si, recfg)              (-1)
+#define audio_extn_usb_get_service_interval(p, si)                     (-1)
+#define audio_extn_usb_check_and_set_svc_int(uc,ss)                    (0)
+#define audio_extn_usb_is_reconfig_req()                               (0)
+#define audio_extn_usb_set_reconfig(isreq)                             (0)
+#else
+unsigned long audio_extn_usb_find_service_interval(bool min, bool playback);
+int audio_extn_usb_altset_for_service_interval(bool is_playback,
+                                               unsigned long service_interval,
+                                               uint32_t *bit_width,
+                                               uint32_t *sample_rate,
+                                               uint32_t *channel_count);
+int audio_extn_usb_set_service_interval(bool playback,
+                                        unsigned long service_interval,
+                                        bool *reconfig);
+int audio_extn_usb_get_service_interval(bool playback,
+                                        unsigned long *service_interval);
+int audio_extn_usb_check_and_set_svc_int(struct audio_usecase *uc_info,
+                                         bool starting_output_stream);
+bool audio_extn_usb_is_reconfig_req();
+void audio_extn_usb_set_reconfig(bool is_required);
+#endif
+
 #ifndef SPLIT_A2DP_ENABLED
 #define audio_extn_a2dp_init(adev)                       (0)
 #define audio_extn_a2dp_start_playback()                 (0)
diff --git a/hal/audio_extn/usb.c b/hal/audio_extn/usb.c
index e8b72b0..d96da2b 100644
--- a/hal/audio_extn/usb.c
+++ b/hal/audio_extn/usb.c
@@ -48,6 +48,7 @@
 #define CHANNEL_NUMBER_STR      "Channels: "
 #define PLAYBACK_PROFILE_STR    "Playback:"
 #define CAPTURE_PROFILE_STR     "Capture:"
+#define DATA_PACKET_INTERVAL_STR "Data packet interval:"
 #define USB_SIDETONE_GAIN_STR   "usb_sidetone_gain"
 #define ABS_SUB(A, B) (((A) > (B)) ? ((A) - (B)):((B) - (A)))
 #define SAMPLE_RATE_8000          8000
@@ -60,13 +61,15 @@
 
 #define  MAX_SAMPLE_RATE_SIZE  sizeof(supported_sample_rates)/sizeof(supported_sample_rates[0])
 
+#define DEFAULT_SERVICE_INTERVAL_US    0
+
 #define _MAX(x, y) (((x) >= (y)) ? (x) : (y))
 #define _MIN(x, y) (((x) <= (y)) ? (x) : (y))
 
-enum usb_usecase_type{
+typedef enum usb_usecase_type{
     USB_PLAYBACK = 0,
     USB_CAPTURE,
-};
+} usb_usecase_type_t;
 
 enum {
     USB_SIDETONE_ENABLE_INDEX = 0,
@@ -80,6 +83,8 @@
     unsigned int channels;
     unsigned int rate_size;
     unsigned int rates[MAX_SAMPLE_RATE_SIZE];
+    unsigned long service_interval_us;
+    usb_usecase_type_t type;
 };
 
 struct usb_card_config {
@@ -99,6 +104,7 @@
     struct audio_device *adev;
     int sidetone_gain;
     bool is_capture_supported;
+    bool usb_reconfig;
 };
 
 static struct usb_module *usbmod = NULL;
@@ -318,6 +324,43 @@
     return 0;
 }
 
+static int usb_get_service_interval(const char *interval_str_start,
+                                    struct usb_device_config *usb_device_info)
+{
+    unsigned long interval = 0;
+    char time_unit[8] = {0};
+    int multiplier = 0;
+
+    char *eol = strchr(interval_str_start, '\n');
+    if (!eol) {
+        ALOGE("%s: No EOL found", __func__);
+        return -1;
+    }
+    char *tmp = (char *)calloc(1, eol-interval_str_start+1);
+    if (!tmp) {
+        ALOGE("%s: failed to allocate tmp", __func__);
+        return -1;
+    }
+    memcpy(tmp, interval_str_start, eol-interval_str_start);
+    sscanf(tmp, "%lu %2s", &interval, &time_unit[0]);
+    if (!strcmp(time_unit, "us")) {
+        multiplier = 1;
+    } else if (!strcmp(time_unit, "ms")) {
+        multiplier = 1000;
+    } else if (!strcmp(time_unit, "s")) {
+        multiplier = 1000000;
+    } else {
+        ALOGE("%s: unknown time_unit %s, assume default", __func__, time_unit);
+        interval = DEFAULT_SERVICE_INTERVAL_US;
+        multiplier = 1;
+    }
+    interval *= multiplier;
+    ALOGD("%s: set service_interval_us %lu", __func__, interval);
+    usb_device_info->service_interval_us = interval;
+    free(tmp);
+    return 0;
+}
+
 static int usb_get_capability(int type,
                               struct usb_card_config *usb_card_info,
                               int card)
@@ -333,6 +376,7 @@
     char *target = NULL;
     char *read_buf = NULL;
     char *rates_str = NULL;
+    char *interval_str_start = NULL;
     char path[128];
     int ret = 0;
     char *bit_width_str = NULL;
@@ -402,6 +446,7 @@
             ret = -ENOMEM;
             break;
         }
+        usb_device_info->type = type;
         /* Bit bit_width parsing */
         bit_width_start = strstr(str_start, "Format: ");
         if (bit_width_start == NULL) {
@@ -482,6 +527,19 @@
             free(usb_device_info);
             continue;
         }
+        // Data packet interval is an optional field.
+        // Assume 0ms interval if this cannot be read
+        // LPASS USB and HLOS USB will figure out the default to use
+        usb_device_info->service_interval_us = DEFAULT_SERVICE_INTERVAL_US;
+        interval_str_start = strstr(str_start, DATA_PACKET_INTERVAL_STR);
+        if (interval_str_start != NULL) {
+            interval_str_start += strlen(DATA_PACKET_INTERVAL_STR);
+            ret = usb_get_service_interval(interval_str_start, usb_device_info);
+            if (ret < 0) {
+                ALOGE("%s: error unable to get service interval, assume default",
+                      __func__);
+            }
+        }
         /* Add to list if every field is valid */
         list_add_tail(&usb_card_info->usb_device_conf_list,
                       &usb_device_info->list);
@@ -750,7 +808,9 @@
                             unsigned int bit_width,
                             unsigned int ch,
                             unsigned int stream_sample_rate,
-                            unsigned int *sr)
+                            unsigned int *sr,
+                            unsigned int service_interval,
+                            bool do_service_interval_check)
 {
     struct listnode *node_i;
     struct usb_device_config *dev_info;
@@ -768,7 +828,11 @@
                  "%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) ||
+            (do_service_interval_check && (dev_info->service_interval_us !=
+                                           service_interval)))
             continue;
 
         candidate = 0;
@@ -837,7 +901,9 @@
                                        *bit_width,
                                        *ch,
                                        *sample_rate,
-                                       sample_rate);
+                                       sample_rate,
+                                       0 /*service int*/,
+                                       false /*do service int check*/);
 exit:
     ALOGV("%s: Updated sample rate per profile: bit-width(%d) rate(%d) chs(%d)",
            __func__, *bit_width, *sample_rate, *ch);
@@ -1152,6 +1218,218 @@
     return access(path, F_OK) == 0;
 }
 
+unsigned long audio_extn_usb_find_service_interval(bool min,
+                                                   bool playback) {
+    struct usb_card_config *card_info = NULL;
+    struct usb_device_config *dev_info = NULL;
+    struct listnode *node_i = NULL;
+    struct listnode *node_j = NULL;
+    unsigned long interval_us = min ? UINT_MAX : 0;
+    list_for_each(node_i, &usbmod->usb_card_conf_list) {
+        card_info = node_to_item(node_i, struct usb_card_config, list);
+        list_for_each(node_j, &card_info->usb_device_conf_list) {
+            dev_info = node_to_item(node_j, struct usb_device_config, list);
+            bool match = (playback && (dev_info->type == USB_PLAYBACK)) ||
+                    (!playback && (dev_info->type == USB_CAPTURE));
+            if (match) {
+                interval_us = min ?
+                        _MIN(interval_us, dev_info->service_interval_us) :
+                        _MAX(interval_us, dev_info->service_interval_us);
+            }
+        }
+        break;
+    }
+    return interval_us;
+}
+
+int audio_extn_usb_altset_for_service_interval(bool playback,
+                                               unsigned long service_interval,
+                                               uint32_t *bit_width,
+                                               uint32_t *sample_rate,
+                                               uint32_t *channels)
+{
+    struct usb_card_config *card_info = NULL;
+    struct usb_device_config *dev_info = NULL;;
+    struct listnode *node_i = NULL;;
+    struct listnode *node_j = NULL;;
+    uint32_t bw = 0;
+    uint32_t ch = 0;
+    uint32_t sr = 0;
+
+    if (service_interval == 0)
+        return 0;
+        /* not a valid service interval to search for */
+
+#define FIND_BEST_MATCH(local_var, field, cond)                                      \
+    list_for_each(node_i, &usbmod->usb_card_conf_list) {                             \
+            /* Currently only apply the first playback sound card configuration */   \
+            card_info = node_to_item(node_i, struct usb_card_config, list);          \
+            list_for_each(node_j, &card_info->usb_device_conf_list) {                \
+                    dev_info = node_to_item(node_j, struct usb_device_config, list); \
+                    bool match = (playback && (dev_info->type == USB_PLAYBACK)) ||   \
+                            (!playback && (dev_info->type == USB_CAPTURE));          \
+                    if (match && (cond)) {                                           \
+                        local_var = _MAX(local_var, dev_info->field);                \
+                    }                                                                \
+            }                                                                        \
+            break;                                                                   \
+    }
+
+    FIND_BEST_MATCH(bw, bit_width, dev_info->service_interval_us == service_interval);
+    FIND_BEST_MATCH(ch, channels, \
+                    dev_info->service_interval_us == service_interval && \
+                    dev_info->bit_width == bw);
+    list_for_each(node_i, &usbmod->usb_card_conf_list) {
+        /* Currently only apply the first playback sound card configuration */
+        card_info = node_to_item(node_i, struct usb_card_config, list);
+        if ((playback && usb_output_device(card_info->usb_device_type)) ||
+            (!playback && usb_input_device(card_info->usb_device_type))) {
+            usb_get_best_match_for_sample_rate(&card_info->usb_device_conf_list,
+                                               bw, ch, sr, &sr,
+                                               service_interval,
+                                               true);
+        }
+        break;
+    }
+
+#define SET_OR_RETURN_ON_ERROR(arg, local_var, cond) \
+    if (local_var != (cond)) arg = local_var; else return -1;
+
+    SET_OR_RETURN_ON_ERROR(*bit_width, bw, 0);
+    SET_OR_RETURN_ON_ERROR(*sample_rate, sr, 0);
+    SET_OR_RETURN_ON_ERROR(*channels, ch, 0);
+    return 0;
+#undef FIND_BEST_MATCH
+#undef SET_OR_RETURN_ON_ERROR
+}
+
+int audio_extn_usb_get_service_interval(bool playback,
+                                        unsigned long *service_interval)
+{
+    const char *ctl_name = "USB_AUDIO_RX service_interval";
+    struct mixer_ctl *ctl = mixer_get_ctl_by_name(usbmod->adev->mixer,
+                                                  ctl_name);
+
+    if (!playback) {
+        ALOGE("%s not valid for capture", __func__);
+        return -1;
+    }
+
+    if (!ctl) {
+        ALOGV("%s: could not get mixer %s", __func__, ctl_name);
+        return -1;
+    }
+
+    *service_interval = mixer_ctl_get_value(ctl, 0);
+    return 0;
+}
+
+int audio_extn_usb_set_service_interval(bool playback,
+                                        unsigned long service_interval,
+                                        bool *reconfig)
+{
+    *reconfig = false;
+    unsigned long current_service_interval = 0;
+    const char *ctl_name = "USB_AUDIO_RX service_interval";
+    struct mixer_ctl *ctl = mixer_get_ctl_by_name(usbmod->adev->mixer,
+                                                  ctl_name);
+
+    if (!playback) {
+        ALOGE("%s not valid for capture", __func__);
+        return -1;
+    }
+
+    if (!ctl) {
+        ALOGV("%s: could not get mixer %s", __func__, ctl_name);
+        return -1;
+    }
+
+    if (audio_extn_usb_get_service_interval(playback,
+                                            &current_service_interval) != 0) {
+        ALOGE("%s Unable to get current service interval", __func__);
+        return -1;
+    }
+
+    if (current_service_interval != service_interval) {
+        mixer_ctl_set_value(ctl, 0, service_interval);
+        *reconfig = usbmod->usb_reconfig = true;
+    }
+    else
+        *reconfig = usbmod->usb_reconfig = false;
+    return 0;
+}
+
+int audio_extn_usb_check_and_set_svc_int(struct audio_usecase *uc_info,
+                                         bool starting_output_stream)
+{
+    struct listnode *node = NULL;
+    struct audio_usecase *usecase = uc_info;
+    bool reconfig = false;
+    bool burst_mode = true;
+    unsigned long service_interval = 0;
+    struct audio_device *adev = usbmod->adev;
+
+    ALOGV("%s: enter:", __func__);
+
+    if ((starting_output_stream == true &&
+        ((uc_info->id == USECASE_AUDIO_PLAYBACK_MMAP) ||
+        (uc_info->id == USECASE_AUDIO_PLAYBACK_ULL))) ||
+        (voice_is_call_state_active(usbmod->adev))) {
+        burst_mode = false;
+    } else {
+    /* set if the valid usecase do not already exist */
+        list_for_each(node, &adev->usecase_list) {
+            usecase = node_to_item(node, struct audio_usecase, list);
+            if (usecase->type == PCM_PLAYBACK &&
+                audio_is_usb_out_device(usecase->devices & AUDIO_DEVICE_OUT_ALL_USB )) {
+                switch (usecase->id) {
+                    case USECASE_AUDIO_PLAYBACK_MMAP:
+                    case USECASE_AUDIO_PLAYBACK_ULL:
+                    {
+                        if (uc_info != usecase) {
+                            //another ULL stream exists
+                            ALOGV("%s: another ULL Stream in active use-case list burst mode = false.", __func__);
+                            burst_mode = false;
+                        } else {
+                            ALOGV("%s:current ULL uc is the same as incoming uc_info \
+                                   which means we are stopping the output stream, \
+                                   we don't want to set burst mode to false", __func__);
+                        }
+                        break;
+                    }
+                    default:
+                        break;
+                }
+            }
+        }
+    }
+
+    ALOGV("%s: burst mode(%d).", __func__,burst_mode);
+
+    service_interval =
+            audio_extn_usb_find_service_interval(!burst_mode, true /*playback*/);
+
+    if (service_interval != 0)
+        audio_extn_usb_set_service_interval(true /*playback*/,
+                                            service_interval,
+                                            &reconfig);
+
+    /* no change or not supported or no active usecases */
+    if (reconfig)
+        return -1;
+    return 0;
+}
+
+bool audio_extn_usb_is_reconfig_req()
+{
+    return usbmod->usb_reconfig;
+}
+
+void audio_extn_usb_set_reconfig(bool is_required)
+{
+    usbmod->usb_reconfig = is_required;
+}
+
 void audio_extn_usb_init(void *adev)
 {
     if (usbmod == NULL) {
@@ -1165,6 +1443,7 @@
     usbmod->adev = (struct audio_device*)adev;
     usbmod->sidetone_gain = usb_sidetone_gain;
     usbmod->is_capture_supported = false;
+    usbmod->usb_reconfig = false;
 exit:
     return;
 }
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index e414c86..d726a9f 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -2899,9 +2899,18 @@
                                                 adev->dsp_bit_width_enforce_mode,
                                                 false);
     }
+    if (audio_is_usb_out_device(out->devices & AUDIO_DEVICE_OUT_ALL_USB)) {
+        ret = audio_extn_usb_check_and_set_svc_int(uc_info,
+                                                   false);
+
+        if (ret != 0)
+            check_usecases_codec_backend(adev, uc_info, uc_info->out_snd_device);
+            /* default service interval was successfully updated,
+            reopen USB backend with new service interval */
+        ret = 0;
+    }
 
     list_remove(&uc_info->list);
-    free(uc_info);
     out->started = 0;
     if (is_offload_usecase(out->usecase) &&
         (audio_extn_passthru_is_passthrough_stream(out))) {
@@ -2922,6 +2931,7 @@
             ALOGE("%s: audio_extn_ip_hdlr_intf_close failed %d",__func__, ret);
     }
 
+    free(uc_info);
     ALOGV("%s: exit: status(%d)", __func__, ret);
     return ret;
 }
@@ -3001,6 +3011,14 @@
     uc_info->devices = out->devices;
     uc_info->in_snd_device = SND_DEVICE_NONE;
     uc_info->out_snd_device = SND_DEVICE_NONE;
+
+    /* This must be called before adding this usecase to the list */
+    if (audio_is_usb_out_device(out->devices & AUDIO_DEVICE_OUT_ALL_USB)) {
+       audio_extn_usb_check_and_set_svc_int(uc_info, true);
+       /* USB backend is not reopened immediately.
+       This is eventually done as part of select_devices */
+    }
+
     list_add_tail(&adev->usecase_list, &uc_info->list);
 
     audio_extn_perf_lock_acquire(&adev->perf_lock_handle, 0,
@@ -3625,6 +3643,8 @@
     char value[32];
     int ret = 0, val = 0, err;
     bool bypass_a2dp = false;
+    bool reconfig = false;
+    unsigned long service_interval = 0;
 
     ALOGD("%s: enter: usecase(%d: %s) kvpairs: %s",
           __func__, out->usecase, use_case_table[out->usecase], kvpairs);
@@ -3727,7 +3747,14 @@
                 if (!voice_is_call_state_active(adev)) {
                     if (adev->mode == AUDIO_MODE_IN_CALL) {
                         adev->current_call_output = out;
-                        ret = voice_start_call(adev);
+                        if (audio_is_usb_out_device(out->devices & AUDIO_DEVICE_OUT_ALL_USB)) {
+                            service_interval = audio_extn_usb_find_service_interval(true, true /*playback*/);
+                            audio_extn_usb_set_service_interval(true /*playback*/,
+                                                                service_interval,
+                                                                &reconfig);
+                            ALOGD("%s, svc_int(%ld),reconfig(%d)",__func__,service_interval, reconfig);
+                         }
+                         ret = voice_start_call(adev);
                     }
                 } else {
                     adev->current_call_output = out;
@@ -6560,12 +6587,32 @@
 static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
 {
     struct audio_device *adev = (struct audio_device *)dev;
-
+    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);
         adev->mode = mode;
         if ((mode == AUDIO_MODE_NORMAL) && voice_is_in_call(adev)) {
+            list_for_each(node, &adev->usecase_list) {
+                usecase = node_to_item(node, struct audio_usecase, list);
+                if (usecase->type == VOICE_CALL)
+                    break;
+            }
+            if (usecase &&
+                audio_is_usb_out_device(usecase->out_snd_device & AUDIO_DEVICE_OUT_ALL_USB)) {
+                ret = audio_extn_usb_check_and_set_svc_int(usecase,
+                                                           true);
+                if (ret != 0) {
+                    /* default service interval was successfully updated,
+                       reopen USB backend with new service interval */
+                    check_usecases_codec_backend(adev,
+                                                 usecase,
+                                                 usecase->out_snd_device);
+                }
+            }
+
             voice_stop_call(adev);
             platform_set_gsm_mode(adev->platform, false);
             adev->current_call_output = NULL;
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index ca36adf..8b4ba5e 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -2266,7 +2266,6 @@
             ALOGD("ACDB initialization failed");
         }
     }
-
     /* init keep-alive for compress passthru */
     audio_extn_keep_alive_init(adev);
 #ifdef DYNAMIC_LOG_ENABLED
@@ -5952,6 +5951,8 @@
     unsigned int bit_width;
     unsigned int sample_rate;
     unsigned int channels;
+    unsigned long service_interval = 0;
+    bool service_interval_update = false;
     bool passthrough_enabled = false;
     bool voice_call_active = false;
     int backend_idx = DEFAULT_CODEC_BACKEND;
@@ -6100,6 +6101,27 @@
         audio_extn_usb_is_config_supported(&bit_width, &sample_rate, &channels, true);
         ALOGV("%s: USB BE configured as bit_width(%d)sample_rate(%d)channels(%d)",
                    __func__, bit_width, sample_rate, channels);
+
+        if (audio_extn_usb_get_service_interval(true,
+                                                &service_interval) == 0) {
+            /* overwrite with best altset for this service interval */
+            int ret =
+                    audio_extn_usb_altset_for_service_interval(true /*playback*/,
+                                                               service_interval,
+                                                               &bit_width,
+                                                               &sample_rate,
+                                                               &channels);
+            ALOGD("%s: Override USB BE configured as bit_width(%d)sample_rate(%d)channels(%d)SI(%lu)",
+           __func__, bit_width, sample_rate, channels, service_interval);
+            if (ret < 0) {
+                ALOGW("Failed to find altset for service interval %lu, skip reconfig",
+                      service_interval);
+                return false;
+            }
+            service_interval_update = audio_extn_usb_is_reconfig_req();
+            audio_extn_usb_set_reconfig(false);
+        }
+
         if (channels != my_data->current_backend_cfg[backend_idx].channels)
             channels_updated = true;
     }
@@ -6138,7 +6160,7 @@
     // is not same as current backend comfiguration
     if ((bit_width != my_data->current_backend_cfg[backend_idx].bit_width) ||
         (sample_rate != my_data->current_backend_cfg[backend_idx].sample_rate) ||
-         passthrough_enabled || channels_updated) {
+         passthrough_enabled || channels_updated || service_interval_update ) {
         backend_cfg->bit_width = bit_width;
         backend_cfg->sample_rate = sample_rate;
         backend_cfg->channels = channels;