]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - drivers/usb/gadget/function/f_uac2.c
Merge tag 'usb-for-v4.3' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb...
[karo-tx-linux.git] / drivers / usb / gadget / function / f_uac2.c
index 53186154725330d4c1f710e4829d4a8b25b614cd..f8de7ea2a0c1e9585782e2fe60af23a41c072e37 100644 (file)
@@ -975,6 +975,29 @@ free_ep(struct uac2_rtd_params *prm, struct usb_ep *ep)
                        "%s:%d Error!\n", __func__, __LINE__);
 }
 
+static void set_ep_max_packet_size(const struct f_uac2_opts *uac2_opts,
+       struct usb_endpoint_descriptor *ep_desc,
+       unsigned int factor, bool is_playback)
+{
+       int chmask, srate, ssize;
+       u16 max_packet_size;
+
+       if (is_playback) {
+               chmask = uac2_opts->p_chmask;
+               srate = uac2_opts->p_srate;
+               ssize = uac2_opts->p_ssize;
+       } else {
+               chmask = uac2_opts->c_chmask;
+               srate = uac2_opts->c_srate;
+               ssize = uac2_opts->c_ssize;
+       }
+
+       max_packet_size = num_channels(chmask) * ssize *
+               DIV_ROUND_UP(srate, factor / (1 << (ep_desc->bInterval - 1)));
+       ep_desc->wMaxPacketSize = cpu_to_le16(min_t(u16, max_packet_size,
+                               le16_to_cpu(ep_desc->wMaxPacketSize)));
+}
+
 static int
 afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
 {
@@ -1070,10 +1093,14 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
        uac2->p_prm.uac2 = uac2;
        uac2->c_prm.uac2 = uac2;
 
+       /* Calculate wMaxPacketSize according to audio bandwidth */
+       set_ep_max_packet_size(uac2_opts, &fs_epin_desc, 1000, true);
+       set_ep_max_packet_size(uac2_opts, &fs_epout_desc, 1000, false);
+       set_ep_max_packet_size(uac2_opts, &hs_epin_desc, 8000, true);
+       set_ep_max_packet_size(uac2_opts, &hs_epout_desc, 8000, false);
+
        hs_epout_desc.bEndpointAddress = fs_epout_desc.bEndpointAddress;
-       hs_epout_desc.wMaxPacketSize = fs_epout_desc.wMaxPacketSize;
        hs_epin_desc.bEndpointAddress = fs_epin_desc.bEndpointAddress;
-       hs_epin_desc.wMaxPacketSize = fs_epin_desc.wMaxPacketSize;
 
        ret = usb_assign_descriptors(fn, fs_audio_desc, hs_audio_desc, NULL);
        if (ret)