diff options
Diffstat (limited to 'sound/usb')
-rw-r--r-- | sound/usb/6fire/pcm.c | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/sound/usb/6fire/pcm.c b/sound/usb/6fire/pcm.c index 2110cbf35474..7ea698793d43 100644 --- a/sound/usb/6fire/pcm.c +++ b/sound/usb/6fire/pcm.c | |||
@@ -64,7 +64,7 @@ static const struct snd_pcm_hardware pcm_hw = { | |||
64 | SNDRV_PCM_INFO_MMAP_VALID | | 64 | SNDRV_PCM_INFO_MMAP_VALID | |
65 | SNDRV_PCM_INFO_BATCH, | 65 | SNDRV_PCM_INFO_BATCH, |
66 | 66 | ||
67 | .formats = SNDRV_PCM_FMTBIT_S24_LE, | 67 | .formats = SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, |
68 | 68 | ||
69 | .rates = SNDRV_PCM_RATE_44100 | | 69 | .rates = SNDRV_PCM_RATE_44100 | |
70 | SNDRV_PCM_RATE_48000 | | 70 | SNDRV_PCM_RATE_48000 | |
@@ -228,7 +228,7 @@ static void usb6fire_pcm_capture(struct pcm_substream *sub, struct pcm_urb *urb) | |||
228 | unsigned int total_length = 0; | 228 | unsigned int total_length = 0; |
229 | struct pcm_runtime *rt = snd_pcm_substream_chip(sub->instance); | 229 | struct pcm_runtime *rt = snd_pcm_substream_chip(sub->instance); |
230 | struct snd_pcm_runtime *alsa_rt = sub->instance->runtime; | 230 | struct snd_pcm_runtime *alsa_rt = sub->instance->runtime; |
231 | u32 *src = (u32 *) urb->buffer; | 231 | u32 *src = NULL; |
232 | u32 *dest = (u32 *) (alsa_rt->dma_area + sub->dma_off | 232 | u32 *dest = (u32 *) (alsa_rt->dma_area + sub->dma_off |
233 | * (alsa_rt->frame_bits >> 3)); | 233 | * (alsa_rt->frame_bits >> 3)); |
234 | u32 *dest_end = (u32 *) (alsa_rt->dma_area + alsa_rt->buffer_size | 234 | u32 *dest_end = (u32 *) (alsa_rt->dma_area + alsa_rt->buffer_size |
@@ -244,7 +244,12 @@ static void usb6fire_pcm_capture(struct pcm_substream *sub, struct pcm_urb *urb) | |||
244 | else | 244 | else |
245 | frame_count = 0; | 245 | frame_count = 0; |
246 | 246 | ||
247 | src = (u32 *) (urb->buffer + total_length); | 247 | if (alsa_rt->format == SNDRV_PCM_FORMAT_S24_LE) |
248 | src = (u32 *) (urb->buffer + total_length); | ||
249 | else if (alsa_rt->format == SNDRV_PCM_FORMAT_S32_LE) | ||
250 | src = (u32 *) (urb->buffer - 1 + total_length); | ||
251 | else | ||
252 | return; | ||
248 | src++; /* skip leading 4 bytes of every packet */ | 253 | src++; /* skip leading 4 bytes of every packet */ |
249 | total_length += urb->packets[i].length; | 254 | total_length += urb->packets[i].length; |
250 | for (frame = 0; frame < frame_count; frame++) { | 255 | for (frame = 0; frame < frame_count; frame++) { |
@@ -274,9 +279,18 @@ static void usb6fire_pcm_playback(struct pcm_substream *sub, | |||
274 | * (alsa_rt->frame_bits >> 3)); | 279 | * (alsa_rt->frame_bits >> 3)); |
275 | u32 *src_end = (u32 *) (alsa_rt->dma_area + alsa_rt->buffer_size | 280 | u32 *src_end = (u32 *) (alsa_rt->dma_area + alsa_rt->buffer_size |
276 | * (alsa_rt->frame_bits >> 3)); | 281 | * (alsa_rt->frame_bits >> 3)); |
277 | u32 *dest = (u32 *) urb->buffer; | 282 | u32 *dest; |
278 | int bytes_per_frame = alsa_rt->channels << 2; | 283 | int bytes_per_frame = alsa_rt->channels << 2; |
279 | 284 | ||
285 | if (alsa_rt->format == SNDRV_PCM_FORMAT_S32_LE) | ||
286 | dest = (u32 *) (urb->buffer - 1); | ||
287 | else if (alsa_rt->format == SNDRV_PCM_FORMAT_S24_LE) | ||
288 | dest = (u32 *) (urb->buffer); | ||
289 | else { | ||
290 | snd_printk(KERN_ERR PREFIX "Unknown sample format."); | ||
291 | return; | ||
292 | } | ||
293 | |||
280 | for (i = 0; i < PCM_N_PACKETS_PER_URB; i++) { | 294 | for (i = 0; i < PCM_N_PACKETS_PER_URB; i++) { |
281 | /* at least 4 header bytes for valid packet. | 295 | /* at least 4 header bytes for valid packet. |
282 | * after that: 32 bits per sample for analog channels */ | 296 | * after that: 32 bits per sample for analog channels */ |