#include "u_audio.h"
 #include "u_uac2.h"
 
+/* UAC2 spec: 4.1 Audio Channel Cluster Descriptor */
+#define UAC2_CHANNEL_MASK 0x07FFFFFF
+
 /*
  * The driver implements a simple UAC_2 topology.
  * USB-OUT -> IT_1 -> OT_3 -> ALSA_Capture
        setup_headers(opts, ss_audio_desc, USB_SPEED_SUPER);
 }
 
+static int afunc_validate_opts(struct g_audio *agdev, struct device *dev)
+{
+       struct f_uac2_opts *opts = g_audio_to_uac2_opts(agdev);
+
+       if (!opts->p_chmask && !opts->c_chmask) {
+               dev_err(dev, "Error: no playback and capture channels\n");
+               return -EINVAL;
+       } else if (opts->p_chmask & ~UAC2_CHANNEL_MASK) {
+               dev_err(dev, "Error: unsupported playback channels mask\n");
+               return -EINVAL;
+       } else if (opts->c_chmask & ~UAC2_CHANNEL_MASK) {
+               dev_err(dev, "Error: unsupported capture channels mask\n");
+               return -EINVAL;
+       } else if ((opts->p_ssize < 1) || (opts->p_ssize > 4)) {
+               dev_err(dev, "Error: incorrect playback sample size\n");
+               return -EINVAL;
+       } else if ((opts->c_ssize < 1) || (opts->c_ssize > 4)) {
+               dev_err(dev, "Error: incorrect capture sample size\n");
+               return -EINVAL;
+       } else if (!opts->p_srate) {
+               dev_err(dev, "Error: incorrect playback sampling rate\n");
+               return -EINVAL;
+       } else if (!opts->c_srate) {
+               dev_err(dev, "Error: incorrect capture sampling rate\n");
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
 static int
 afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
 {
        struct usb_composite_dev *cdev = cfg->cdev;
        struct usb_gadget *gadget = cdev->gadget;
        struct device *dev = &gadget->dev;
-       struct f_uac2_opts *uac2_opts;
+       struct f_uac2_opts *uac2_opts = g_audio_to_uac2_opts(agdev);
        struct usb_string *us;
        int ret;
 
-       uac2_opts = container_of(fn->fi, struct f_uac2_opts, func_inst);
+       ret = afunc_validate_opts(agdev, dev);
+       if (ret)
+               return ret;
 
        us = usb_gstrings_attach(cdev, fn_strings, ARRAY_SIZE(strings_fn));
        if (IS_ERR(us))