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. Commit10550bea44
("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:10550bea44
("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>
This commit is contained in:
parent
1033eb5b5a
commit
65845f29be
|
@ -507,7 +507,16 @@ static void amdtp_pull_midi(struct amdtp_stream *s,
|
||||||
static void update_pcm_pointers(struct amdtp_stream *s,
|
static void update_pcm_pointers(struct amdtp_stream *s,
|
||||||
struct snd_pcm_substream *pcm,
|
struct snd_pcm_substream *pcm,
|
||||||
unsigned int frames)
|
unsigned int frames)
|
||||||
{ unsigned int ptr;
|
{
|
||||||
|
unsigned int ptr;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* In IEC 61883-6, one data block represents one event. In ALSA, one
|
||||||
|
* event equals to one PCM frame. But Dice has a quirk to transfer
|
||||||
|
* two PCM frames in one data block.
|
||||||
|
*/
|
||||||
|
if (s->double_pcm_frames)
|
||||||
|
frames *= 2;
|
||||||
|
|
||||||
ptr = s->pcm_buffer_pointer + frames;
|
ptr = s->pcm_buffer_pointer + frames;
|
||||||
if (ptr >= pcm->runtime->buffer_size)
|
if (ptr >= pcm->runtime->buffer_size)
|
||||||
|
|
|
@ -125,6 +125,7 @@ struct amdtp_stream {
|
||||||
unsigned int pcm_buffer_pointer;
|
unsigned int pcm_buffer_pointer;
|
||||||
unsigned int pcm_period_pointer;
|
unsigned int pcm_period_pointer;
|
||||||
bool pointer_flush;
|
bool pointer_flush;
|
||||||
|
bool double_pcm_frames;
|
||||||
|
|
||||||
struct snd_rawmidi_substream *midi[AMDTP_MAX_CHANNELS_FOR_MIDI * 8];
|
struct snd_rawmidi_substream *midi[AMDTP_MAX_CHANNELS_FOR_MIDI * 8];
|
||||||
|
|
||||||
|
|
|
@ -567,10 +567,14 @@ static int dice_hw_params(struct snd_pcm_substream *substream,
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* At rates above 96 kHz, pretend that the stream runs at half the
|
* At 176.4/192.0 kHz, Dice has a quirk to transfer two PCM frames in
|
||||||
* actual sample rate with twice the number of channels; two samples
|
* one data block of AMDTP packet. Thus sampling transfer frequency is
|
||||||
* of a channel are stored consecutively in the packet. Requires
|
* a half of PCM sampling frequency, i.e. PCM frames at 192.0 kHz are
|
||||||
* blocking mode and PCM buffer size should be aligned to SYT_INTERVAL.
|
* transferred on AMDTP packets at 96 kHz. Two successive samples of a
|
||||||
|
* channel are stored consecutively in the packet. This quirk is called
|
||||||
|
* as 'Dual Wire'.
|
||||||
|
* For this quirk, blocking mode is required and PCM buffer size should
|
||||||
|
* be aligned to SYT_INTERVAL.
|
||||||
*/
|
*/
|
||||||
channels = params_channels(hw_params);
|
channels = params_channels(hw_params);
|
||||||
if (rate_index > 4) {
|
if (rate_index > 4) {
|
||||||
|
@ -581,6 +585,9 @@ static int dice_hw_params(struct snd_pcm_substream *substream,
|
||||||
|
|
||||||
rate /= 2;
|
rate /= 2;
|
||||||
channels *= 2;
|
channels *= 2;
|
||||||
|
dice->stream.double_pcm_frames = true;
|
||||||
|
} else {
|
||||||
|
dice->stream.double_pcm_frames = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
mode = rate_index_to_mode(rate_index);
|
mode = rate_index_to_mode(rate_index);
|
||||||
|
|
Loading…
Reference in New Issue