diff options
| -rw-r--r-- | sound/firewire/amdtp.c | 11 | ||||
| -rw-r--r-- | sound/firewire/amdtp.h | 1 | ||||
| -rw-r--r-- | sound/firewire/dice.c | 15 |
3 files changed, 22 insertions, 5 deletions
diff --git a/sound/firewire/amdtp.c b/sound/firewire/amdtp.c index f96bf4c7c232..95fc2eaf11dc 100644 --- a/sound/firewire/amdtp.c +++ b/sound/firewire/amdtp.c | |||
| @@ -507,7 +507,16 @@ static void amdtp_pull_midi(struct amdtp_stream *s, | |||
| 507 | static void update_pcm_pointers(struct amdtp_stream *s, | 507 | static void update_pcm_pointers(struct amdtp_stream *s, |
| 508 | struct snd_pcm_substream *pcm, | 508 | struct snd_pcm_substream *pcm, |
| 509 | unsigned int frames) | 509 | unsigned int frames) |
| 510 | { unsigned int ptr; | 510 | { |
| 511 | unsigned int ptr; | ||
| 512 | |||
| 513 | /* | ||
| 514 | * In IEC 61883-6, one data block represents one event. In ALSA, one | ||
| 515 | * event equals to one PCM frame. But Dice has a quirk to transfer | ||
| 516 | * two PCM frames in one data block. | ||
| 517 | */ | ||
| 518 | if (s->double_pcm_frames) | ||
| 519 | frames *= 2; | ||
| 511 | 520 | ||
| 512 | ptr = s->pcm_buffer_pointer + frames; | 521 | ptr = s->pcm_buffer_pointer + frames; |
| 513 | if (ptr >= pcm->runtime->buffer_size) | 522 | if (ptr >= pcm->runtime->buffer_size) |
diff --git a/sound/firewire/amdtp.h b/sound/firewire/amdtp.h index d8ee7b0e9386..4823c08196ac 100644 --- a/sound/firewire/amdtp.h +++ b/sound/firewire/amdtp.h | |||
| @@ -125,6 +125,7 @@ struct amdtp_stream { | |||
| 125 | unsigned int pcm_buffer_pointer; | 125 | unsigned int pcm_buffer_pointer; |
| 126 | unsigned int pcm_period_pointer; | 126 | unsigned int pcm_period_pointer; |
| 127 | bool pointer_flush; | 127 | bool pointer_flush; |
| 128 | bool double_pcm_frames; | ||
| 128 | 129 | ||
| 129 | struct snd_rawmidi_substream *midi[AMDTP_MAX_CHANNELS_FOR_MIDI * 8]; | 130 | struct snd_rawmidi_substream *midi[AMDTP_MAX_CHANNELS_FOR_MIDI * 8]; |
| 130 | 131 | ||
diff --git a/sound/firewire/dice.c b/sound/firewire/dice.c index 4cf8eb704045..e3a04d69c853 100644 --- a/sound/firewire/dice.c +++ b/sound/firewire/dice.c | |||
| @@ -567,10 +567,14 @@ static int dice_hw_params(struct snd_pcm_substream *substream, | |||
| 567 | return err; | 567 | return err; |
| 568 | 568 | ||
| 569 | /* | 569 | /* |
| 570 | * At rates above 96 kHz, pretend that the stream runs at half the | 570 | * At 176.4/192.0 kHz, Dice has a quirk to transfer two PCM frames in |
| 571 | * actual sample rate with twice the number of channels; two samples | 571 | * one data block of AMDTP packet. Thus sampling transfer frequency is |
| 572 | * of a channel are stored consecutively in the packet. Requires | 572 | * a half of PCM sampling frequency, i.e. PCM frames at 192.0 kHz are |
| 573 | * blocking mode and PCM buffer size should be aligned to SYT_INTERVAL. | 573 | * transferred on AMDTP packets at 96 kHz. Two successive samples of a |
| 574 | * channel are stored consecutively in the packet. This quirk is called | ||
| 575 | * as 'Dual Wire'. | ||
| 576 | * For this quirk, blocking mode is required and PCM buffer size should | ||
| 577 | * be aligned to SYT_INTERVAL. | ||
| 574 | */ | 578 | */ |
| 575 | channels = params_channels(hw_params); | 579 | channels = params_channels(hw_params); |
| 576 | if (rate_index > 4) { | 580 | if (rate_index > 4) { |
| @@ -581,6 +585,9 @@ static int dice_hw_params(struct snd_pcm_substream *substream, | |||
| 581 | 585 | ||
| 582 | rate /= 2; | 586 | rate /= 2; |
| 583 | channels *= 2; | 587 | channels *= 2; |
| 588 | dice->stream.double_pcm_frames = true; | ||
| 589 | } else { | ||
| 590 | dice->stream.double_pcm_frames = false; | ||
| 584 | } | 591 | } |
| 585 | 592 | ||
| 586 | mode = rate_index_to_mode(rate_index); | 593 | mode = rate_index_to_mode(rate_index); |
