diff options
author | Takashi Sakamoto <o-takashi@sakamocchi.jp> | 2014-08-29 00:40:45 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2014-08-29 03:52:07 -0400 |
commit | 65845f29bec6bc17f80eff25c3bc39bcf3be9bf9 (patch) | |
tree | 5fd70c1a8a22e4c439887020f2a3ef7df1673361 /sound/firewire | |
parent | 1033eb5b5aeeb526c22068e0fb0cef9f3c14231e (diff) |
ALSA: firewire-lib/dice: add arrangements of PCM pointer and interrupts for Dice quirk
In IEC 61883-6, one data block transfers one event. In ALSA, the event equals one PCM frame,
hence one data block transfers one PCM frame. But Dice has a quirk at higher sampling rate
(176.4/192.0 kHz) that one data block transfers two PCM frames.
Commit 10550bea44a8 ("ALSA: dice/firewire-lib: Keep dualwire mode but obsolete
CIP_HI_DUALWIRE") moved some codes related to this quirk into Dice driver. But the commit
forgot to add arrangements for PCM period interrupts and DMA pointer updates. As a result, Dice
driver cannot work correctly at higher sampling rate.
This commit adds 'double_pcm_frames' parameter to amdtp structure for this quirk. When this
parameter is set, PCM period interrupts and DMA pointer updates occur at double speed than in
IEC 61883-6.
Reported-by: Daniel Robbins <drobbins@funtoo.org>
Fixes: 10550bea44a8 ("ALSA: dice/firewire-lib: Keep dualwire mode but obsolete CIP_HI_DUALWIRE")
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Cc: <stable@vger.kernel.org> # 3.16
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/firewire')
-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); |