1 From 65845f29bec6bc17f80eff25c3bc39bcf3be9bf9 Mon Sep 17 00:00:00 2001
2 From: Takashi Sakamoto <o-takashi@sakamocchi.jp>
3 Date: Fri, 29 Aug 2014 13:40:45 +0900
4 Subject: ALSA: firewire-lib/dice: add arrangements of PCM pointer and interrupts for Dice quirk
6 From: Takashi Sakamoto <o-takashi@sakamocchi.jp>
8 commit 65845f29bec6bc17f80eff25c3bc39bcf3be9bf9 upstream.
10 In IEC 61883-6, one data block transfers one event. In ALSA, the event equals one PCM frame,
11 hence one data block transfers one PCM frame. But Dice has a quirk at higher sampling rate
12 (176.4/192.0 kHz) that one data block transfers two PCM frames.
14 Commit 10550bea44a8 ("ALSA: dice/firewire-lib: Keep dualwire mode but obsolete
15 CIP_HI_DUALWIRE") moved some codes related to this quirk into Dice driver. But the commit
16 forgot to add arrangements for PCM period interrupts and DMA pointer updates. As a result, Dice
17 driver cannot work correctly at higher sampling rate.
19 This commit adds 'double_pcm_frames' parameter to amdtp structure for this quirk. When this
20 parameter is set, PCM period interrupts and DMA pointer updates occur at double speed than in
23 Reported-by: Daniel Robbins <drobbins@funtoo.org>
24 Fixes: 10550bea44a8 ("ALSA: dice/firewire-lib: Keep dualwire mode but obsolete CIP_HI_DUALWIRE")
25 Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
26 Signed-off-by: Takashi Iwai <tiwai@suse.de>
27 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
30 sound/firewire/amdtp.c | 11 ++++++++++-
31 sound/firewire/amdtp.h | 1 +
32 sound/firewire/dice.c | 15 +++++++++++----
33 3 files changed, 22 insertions(+), 5 deletions(-)
35 --- a/sound/firewire/amdtp.c
36 +++ b/sound/firewire/amdtp.c
37 @@ -507,7 +507,16 @@ static void amdtp_pull_midi(struct amdtp
38 static void update_pcm_pointers(struct amdtp_stream *s,
39 struct snd_pcm_substream *pcm,
46 + * In IEC 61883-6, one data block represents one event. In ALSA, one
47 + * event equals to one PCM frame. But Dice has a quirk to transfer
48 + * two PCM frames in one data block.
50 + if (s->double_pcm_frames)
53 ptr = s->pcm_buffer_pointer + frames;
54 if (ptr >= pcm->runtime->buffer_size)
55 --- a/sound/firewire/amdtp.h
56 +++ b/sound/firewire/amdtp.h
57 @@ -125,6 +125,7 @@ struct amdtp_stream {
58 unsigned int pcm_buffer_pointer;
59 unsigned int pcm_period_pointer;
61 + bool double_pcm_frames;
63 struct snd_rawmidi_substream *midi[AMDTP_MAX_CHANNELS_FOR_MIDI * 8];
65 --- a/sound/firewire/dice.c
66 +++ b/sound/firewire/dice.c
67 @@ -567,10 +567,14 @@ static int dice_hw_params(struct snd_pcm
71 - * At rates above 96 kHz, pretend that the stream runs at half the
72 - * actual sample rate with twice the number of channels; two samples
73 - * of a channel are stored consecutively in the packet. Requires
74 - * blocking mode and PCM buffer size should be aligned to SYT_INTERVAL.
75 + * At 176.4/192.0 kHz, Dice has a quirk to transfer two PCM frames in
76 + * one data block of AMDTP packet. Thus sampling transfer frequency is
77 + * a half of PCM sampling frequency, i.e. PCM frames at 192.0 kHz are
78 + * transferred on AMDTP packets at 96 kHz. Two successive samples of a
79 + * channel are stored consecutively in the packet. This quirk is called
81 + * For this quirk, blocking mode is required and PCM buffer size should
82 + * be aligned to SYT_INTERVAL.
84 channels = params_channels(hw_params);
86 @@ -581,6 +585,9 @@ static int dice_hw_params(struct snd_pcm
90 + dice->stream.double_pcm_frames = true;
92 + dice->stream.double_pcm_frames = false;
95 mode = rate_index_to_mode(rate_index);