@@ -989,10 +989,6 @@ static int afunc_validate_opts(struct g_audio *agdev, struct device *dev)
989989
990990 if (!opts -> p_chmask && !opts -> c_chmask )
991991 msg = "no playback and capture channels" ;
992- else if (opts -> p_chmask & ~UAC2_CHANNEL_MASK )
993- msg = "unsupported playback channels mask" ;
994- else if (opts -> c_chmask & ~UAC2_CHANNEL_MASK )
995- msg = "unsupported capture channels mask" ;
996992 else if ((opts -> p_ssize < 1 ) || (opts -> p_ssize > 4 ))
997993 msg = "incorrect playback sample size" ;
998994 else if ((opts -> c_ssize < 1 ) || (opts -> c_ssize > 4 ))
@@ -1090,14 +1086,25 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
10901086
10911087
10921088 /* Initialize the configurable parameters */
1089+ /*
1090+ * UAC2 spec §4.1: bmChannelConfig bits 27-30 are reserved and must be
1091+ * zero. For channel masks that exceed the 27 defined spatial positions
1092+ * (bits 0-26), use bmChannelConfig=0 (non-predefined spatial locations)
1093+ * with bNrChannels set from the popcount of the full mask. This is the
1094+ * standard-compliant way to declare more than 27 channels.
1095+ */
1096+ u32 c_chanconfig = (uac2_opts -> c_chmask & ~UAC2_CHANNEL_MASK ) ?
1097+ 0 : uac2_opts -> c_chmask ;
1098+ u32 p_chanconfig = (uac2_opts -> p_chmask & ~UAC2_CHANNEL_MASK ) ?
1099+ 0 : uac2_opts -> p_chmask ;
10931100 usb_out_it_desc .bNrChannels = num_channels (uac2_opts -> c_chmask );
1094- usb_out_it_desc .bmChannelConfig = cpu_to_le32 (uac2_opts -> c_chmask );
1101+ usb_out_it_desc .bmChannelConfig = cpu_to_le32 (c_chanconfig );
10951102 io_in_it_desc .bNrChannels = num_channels (uac2_opts -> p_chmask );
1096- io_in_it_desc .bmChannelConfig = cpu_to_le32 (uac2_opts -> p_chmask );
1103+ io_in_it_desc .bmChannelConfig = cpu_to_le32 (p_chanconfig );
10971104 as_out_hdr_desc .bNrChannels = num_channels (uac2_opts -> c_chmask );
1098- as_out_hdr_desc .bmChannelConfig = cpu_to_le32 (uac2_opts -> c_chmask );
1105+ as_out_hdr_desc .bmChannelConfig = cpu_to_le32 (c_chanconfig );
10991106 as_in_hdr_desc .bNrChannels = num_channels (uac2_opts -> p_chmask );
1100- as_in_hdr_desc .bmChannelConfig = cpu_to_le32 (uac2_opts -> p_chmask );
1107+ as_in_hdr_desc .bmChannelConfig = cpu_to_le32 (p_chanconfig );
11011108 as_out_fmt1_desc .bSubslotSize = uac2_opts -> c_ssize ;
11021109 as_out_fmt1_desc .bBitResolution = uac2_opts -> c_ssize * 8 ;
11031110 as_in_fmt1_desc .bSubslotSize = uac2_opts -> p_ssize ;
0 commit comments