diff options
Diffstat (limited to 'sound/usb')
-rw-r--r-- | sound/usb/card.h | 1 | ||||
-rw-r--r-- | sound/usb/pcm.c | 19 |
2 files changed, 19 insertions, 1 deletions
diff --git a/sound/usb/card.h b/sound/usb/card.h index ac55477ce6dd..bf2889a2cae5 100644 --- a/sound/usb/card.h +++ b/sound/usb/card.h | |||
@@ -29,6 +29,7 @@ struct audioformat { | |||
29 | unsigned char clock; /* associated clock */ | 29 | unsigned char clock; /* associated clock */ |
30 | struct snd_pcm_chmap_elem *chmap; /* (optional) channel map */ | 30 | struct snd_pcm_chmap_elem *chmap; /* (optional) channel map */ |
31 | bool dsd_dop; /* add DOP headers in case of DSD samples */ | 31 | bool dsd_dop; /* add DOP headers in case of DSD samples */ |
32 | bool dsd_bitrev; /* reverse the bits of each DSD sample */ | ||
32 | }; | 33 | }; |
33 | 34 | ||
34 | struct snd_usb_substream; | 35 | struct snd_usb_substream; |
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c index 4cd917cf058e..9723f3ceb155 100644 --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c | |||
@@ -16,6 +16,7 @@ | |||
16 | 16 | ||
17 | #include <linux/init.h> | 17 | #include <linux/init.h> |
18 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
19 | #include <linux/bitrev.h> | ||
19 | #include <linux/ratelimit.h> | 20 | #include <linux/ratelimit.h> |
20 | #include <linux/usb.h> | 21 | #include <linux/usb.h> |
21 | #include <linux/usb/audio.h> | 22 | #include <linux/usb/audio.h> |
@@ -1264,7 +1265,12 @@ static inline void fill_playback_urb_dsd_dop(struct snd_usb_substream *subs, | |||
1264 | } else { | 1265 | } else { |
1265 | /* stuff the DSD payload */ | 1266 | /* stuff the DSD payload */ |
1266 | int idx = (src_idx + subs->dsd_dop.byte_idx - 1) % wrap; | 1267 | int idx = (src_idx + subs->dsd_dop.byte_idx - 1) % wrap; |
1267 | dst[dst_idx++] = src[idx]; | 1268 | |
1269 | if (subs->cur_audiofmt->dsd_bitrev) | ||
1270 | dst[dst_idx++] = bitrev8(src[idx]); | ||
1271 | else | ||
1272 | dst[dst_idx++] = src[idx]; | ||
1273 | |||
1268 | subs->hwptr_done++; | 1274 | subs->hwptr_done++; |
1269 | } | 1275 | } |
1270 | } | 1276 | } |
@@ -1330,6 +1336,17 @@ static void prepare_playback_urb(struct snd_usb_substream *subs, | |||
1330 | if (unlikely(subs->pcm_format == SNDRV_PCM_FORMAT_DSD_U16_LE && | 1336 | if (unlikely(subs->pcm_format == SNDRV_PCM_FORMAT_DSD_U16_LE && |
1331 | subs->cur_audiofmt->dsd_dop)) { | 1337 | subs->cur_audiofmt->dsd_dop)) { |
1332 | fill_playback_urb_dsd_dop(subs, urb, bytes); | 1338 | fill_playback_urb_dsd_dop(subs, urb, bytes); |
1339 | } else if (unlikely(subs->pcm_format == SNDRV_PCM_FORMAT_DSD_U8 && | ||
1340 | subs->cur_audiofmt->dsd_bitrev)) { | ||
1341 | /* bit-reverse the bytes */ | ||
1342 | u8 *buf = urb->transfer_buffer; | ||
1343 | for (i = 0; i < bytes; i++) { | ||
1344 | int idx = (subs->hwptr_done + i) | ||
1345 | % (runtime->buffer_size * stride); | ||
1346 | buf[i] = bitrev8(runtime->dma_area[idx]); | ||
1347 | } | ||
1348 | |||
1349 | subs->hwptr_done += bytes; | ||
1333 | } else { | 1350 | } else { |
1334 | /* usual PCM */ | 1351 | /* usual PCM */ |
1335 | if (subs->hwptr_done + bytes > runtime->buffer_size * stride) { | 1352 | if (subs->hwptr_done + bytes > runtime->buffer_size * stride) { |