aboutsummaryrefslogtreecommitdiffstats
path: root/sound/usb
diff options
context:
space:
mode:
authorDavid Henningsson <david.henningsson@canonical.com>2013-11-04 22:41:06 -0500
committerTakashi Iwai <tiwai@suse.de>2013-11-05 01:46:15 -0500
commit0dca01c37a68017fe7112b46bc4b48c927db18c6 (patch)
tree8da8f7085ec2369893331c8b859b1d37a58836ac /sound/usb
parent24eff328f65c8ef352c90b6adb7c2f39eb94205d (diff)
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>
Diffstat (limited to 'sound/usb')
-rw-r--r--sound/usb/stream.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/sound/usb/stream.c b/sound/usb/stream.c
index c4339f97226b..b43b6eec3227 100644
--- a/sound/usb/stream.c
+++ b/sound/usb/stream.c
@@ -281,8 +281,6 @@ static struct snd_pcm_chmap_elem *convert_chmap(int channels, unsigned int bits,
281 const unsigned int *maps; 281 const unsigned int *maps;
282 int c; 282 int c;
283 283
284 if (!bits)
285 return NULL;
286 if (channels > ARRAY_SIZE(chmap->map)) 284 if (channels > ARRAY_SIZE(chmap->map))
287 return NULL; 285 return NULL;
288 286
@@ -293,9 +291,19 @@ static struct snd_pcm_chmap_elem *convert_chmap(int channels, unsigned int bits,
293 maps = protocol == UAC_VERSION_2 ? uac2_maps : uac1_maps; 291 maps = protocol == UAC_VERSION_2 ? uac2_maps : uac1_maps;
294 chmap->channels = channels; 292 chmap->channels = channels;
295 c = 0; 293 c = 0;
296 for (; bits && *maps; maps++, bits >>= 1) { 294
297 if (bits & 1) 295 if (bits) {
298 chmap->map[c++] = *maps; 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 for (; c < channels; c++) 309 for (; c < channels; c++)