#define hwc_debug(fmt, args...) do { } while(0)
 #endif
 
+#define MAX_BUFFER_BYTES       (1024 * 1024)
+#define MAX_PERIOD_BYTES       (512 * 1024)
+
 static const struct snd_pcm_hardware snd_usb_hardware =
 {
        .info =                 SNDRV_PCM_INFO_MMAP |
                                SNDRV_PCM_INFO_PAUSE,
        .channels_min =         1,
        .channels_max =         256,
-       .buffer_bytes_max =     1024 * 1024,
+       .buffer_bytes_max =     MAX_BUFFER_BYTES,
        .period_bytes_min =     64,
-       .period_bytes_max =     512 * 1024,
+       .period_bytes_max =     MAX_PERIOD_BYTES,
        .periods_min =          2,
        .periods_max =          1024,
 };
                                      ep->cur_buffer_periods);
 }
 
+/* get the adjusted max buffer (or period) bytes that can fit with the
+ * paired format for implicit fb
+ */
+static unsigned int
+get_adjusted_max_bytes(struct snd_usb_substream *subs,
+                      struct snd_usb_substream *pair,
+                      struct snd_pcm_hw_params *params,
+                      unsigned int max_bytes,
+                      bool reverse_map)
+{
+       const struct audioformat *fp, *pp;
+       unsigned int rmax = 0, r;
+
+       list_for_each_entry(fp, &subs->fmt_list, list) {
+               if (!fp->implicit_fb)
+                       continue;
+               if (!reverse_map &&
+                   !hw_check_valid_format(subs, params, fp))
+                       continue;
+               list_for_each_entry(pp, &pair->fmt_list, list) {
+                       if (pp->iface != fp->sync_iface ||
+                           pp->altsetting != fp->sync_altsetting ||
+                           pp->ep_idx != fp->sync_ep_idx)
+                               continue;
+                       if (reverse_map &&
+                           !hw_check_valid_format(pair, params, pp))
+                               break;
+                       if (!reverse_map && pp->channels > fp->channels)
+                               r = max_bytes * fp->channels / pp->channels;
+                       else if (reverse_map && pp->channels < fp->channels)
+                               r = max_bytes * pp->channels / fp->channels;
+                       else
+                               r = max_bytes;
+                       rmax = max(rmax, r);
+                       break;
+               }
+       }
+       return rmax;
+}
+
+/* Reduce the period or buffer bytes depending on the paired substream;
+ * when a paired configuration for implicit fb has a higher number of channels,
+ * we need to reduce the max size accordingly, otherwise it may become unusable
+ */
+static int hw_rule_bytes_implicit_fb(struct snd_pcm_hw_params *params,
+                                    struct snd_pcm_hw_rule *rule)
+{
+       struct snd_usb_substream *subs = rule->private;
+       struct snd_usb_substream *pair;
+       struct snd_interval *it;
+       unsigned int max_bytes;
+       unsigned int rmax;
+
+       pair = &subs->stream->substream[!subs->direction];
+       if (!pair->ep_num)
+               return 0;
+
+       if (rule->var == SNDRV_PCM_HW_PARAM_PERIOD_BYTES)
+               max_bytes = MAX_PERIOD_BYTES;
+       else
+               max_bytes = MAX_BUFFER_BYTES;
+
+       rmax = get_adjusted_max_bytes(subs, pair, params, max_bytes, false);
+       if (!rmax)
+               rmax = get_adjusted_max_bytes(pair, subs, params, max_bytes, true);
+       if (!rmax)
+               return 0;
+
+       it = hw_param_interval(params, rule->var);
+       return apply_hw_params_minmax(it, 0, rmax);
+}
+
 /*
  * set up the runtime hardware information.
  */
                                  SNDRV_PCM_HW_PARAM_PERIODS, -1);
        if (err < 0)
                return err;
+       err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
+                                 hw_rule_bytes_implicit_fb, subs,
+                                 SNDRV_PCM_HW_PARAM_BUFFER_BYTES, -1);
+       if (err < 0)
+               return err;
+       err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
+                                 hw_rule_bytes_implicit_fb, subs,
+                                 SNDRV_PCM_HW_PARAM_PERIOD_BYTES, -1);
+       if (err < 0)
+               return err;
 
        list_for_each_entry(fp, &subs->fmt_list, list) {
                if (fp->implicit_fb) {