diff --git a/sound/firewire/amdtp.c b/sound/firewire/amdtp.c index 094982f7c0fd2d02f5428bec0c776cd1ba928059..0bb5e14b66278ec6fdba3e761731cde83a745fa0 100644 --- a/sound/firewire/amdtp.c +++ b/sound/firewire/amdtp.c @@ -225,6 +225,16 @@ int amdtp_stream_set_parameters(struct amdtp_stream *s, s->data_block_quadlets = s->pcm_channels + midi_channels; s->midi_ports = midi_ports; + /* + * In IEC 61883-6, one data block represents one event. In ALSA, one + * event equals to one PCM frame. But Dice has a quirk at higher + * sampling rate to transfer two PCM frames in one data block. + */ + if (double_pcm_frames) + s->frame_multiplier = 2; + else + s->frame_multiplier = 1; + s->syt_interval = amdtp_syt_intervals[sfc]; /* default buffering in the device */ @@ -584,14 +594,6 @@ static void update_pcm_pointers(struct amdtp_stream *s, { 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; if (ptr >= pcm->runtime->buffer_size) ptr -= pcm->runtime->buffer_size; @@ -685,7 +687,7 @@ static int handle_out_packet(struct amdtp_stream *s, unsigned int data_blocks, return -EIO; if (pcm) - update_pcm_pointers(s, pcm, data_blocks); + update_pcm_pointers(s, pcm, data_blocks * s->frame_multiplier); /* No need to return the number of handled data blocks. */ return 0; @@ -788,7 +790,7 @@ static int handle_in_packet(struct amdtp_stream *s, return -EIO; if (pcm) - update_pcm_pointers(s, pcm, *data_blocks); + update_pcm_pointers(s, pcm, *data_blocks * s->frame_multiplier); return 0; } diff --git a/sound/firewire/amdtp.h b/sound/firewire/amdtp.h index 2c91306957803829d50fe86d27d3664fb13f1811..65229258bd241074a3dd8a4cfdac7b1e8f35e3a1 100644 --- a/sound/firewire/amdtp.h +++ b/sound/firewire/amdtp.h @@ -162,11 +162,12 @@ struct amdtp_stream { u8 pcm_positions[AMDTP_MAX_CHANNELS_FOR_PCM]; u8 midi_position; - bool double_pcm_frames; void (*transfer_samples)(struct amdtp_stream *s, struct snd_pcm_substream *pcm, __be32 *buffer, unsigned int frames); + + unsigned int frame_multiplier; }; int amdtp_stream_init(struct amdtp_stream *s, struct fw_unit *unit,