|
@@ -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(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)
|