Commit 0dca01c37a68017fe7112b46bc4b48c927db18c6

Authored by David Henningsson
Committed by Takashi Iwai
1 parent 24eff328f6

ALSA: usb: supply channel maps even when wChannelConfig is unspecified

If wChannelconfig is given for some formats but not others, userspace
might not be able to set the channel map.

This is RFC because I'm not sure what the best behaviour is - to guess
the channel map from the given number of channels (it's quite likely
that one channel is MONO and two channels is FL FR), or just to supply
UNKNOWN for all channels.

But the complete lack of channel map for a format leads userspace to
believe that the format is not available at all. Or am I
misunderstanding how this should be used?

Signed-off-by: David Henningsson <david.henningsson@canonical.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>

Showing 1 changed file with 13 additions and 5 deletions Side-by-side Diff

... ... @@ -281,8 +281,6 @@
281 281 const unsigned int *maps;
282 282 int c;
283 283  
284   - if (!bits)
285   - return NULL;
286 284 if (channels > ARRAY_SIZE(chmap->map))
287 285 return NULL;
288 286  
... ... @@ -293,9 +291,19 @@
293 291 maps = protocol == UAC_VERSION_2 ? uac2_maps : uac1_maps;
294 292 chmap->channels = channels;
295 293 c = 0;
296   - for (; bits && *maps; maps++, bits >>= 1) {
297   - if (bits & 1)
298   - chmap->map[c++] = *maps;
  294 +
  295 + if (bits) {
  296 + for (; bits && *maps; maps++, bits >>= 1)
  297 + if (bits & 1)
  298 + chmap->map[c++] = *maps;
  299 + } else {
  300 + /* If we're missing wChannelConfig, then guess something
  301 + to make sure the channel map is not skipped entirely */
  302 + if (channels == 1)
  303 + chmap->map[c++] = SNDRV_CHMAP_MONO;
  304 + else
  305 + for (; c < channels && *maps; maps++)
  306 + chmap->map[c++] = *maps;
299 307 }
300 308  
301 309 for (; c < channels; c++)