Commit d4a0b6cb authored by Takashi Sakamoto's avatar Takashi Sakamoto Committed by Takashi Iwai
Browse files

ALSA: fireface: share helper function to switch fetching mode



Both of Fireface 400/800 have the same register to switch frame fetching
mode regardless of difference of available number of PCM frames in
rx isochronous packet.

This commit moves a helper function from model-dependent implementation.

Signed-off-by: default avatarTakashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 3d16200a
Loading
Loading
Loading
Loading
+0 −30
Original line number Diff line number Diff line
@@ -76,35 +76,6 @@ static void ff400_finish_session(struct snd_ff *ff)
			   FF400_ISOC_COMM_STOP, &reg, sizeof(reg), 0);
}

static int ff400_switch_fetching_mode(struct snd_ff *ff, bool enable)
{
	__le32 *reg;
	int i;
	int err;

	reg = kcalloc(18, sizeof(__le32), GFP_KERNEL);
	if (reg == NULL)
		return -ENOMEM;

	if (!enable) {
		/*
		 * Each quadlet is corresponding to data channels in a data
		 * blocks in reverse order. Precisely, quadlets for available
		 * data channels should be enabled. Here, I take second best
		 * to fetch PCM frames from all of data channels regardless of
		 * stf.
		 */
		for (i = 0; i < 18; ++i)
			reg[i] = cpu_to_le32(0x00000001);
	}

	err = snd_fw_transaction(ff->unit, TCODE_WRITE_BLOCK_REQUEST,
				 SND_FF_REG_FETCH_PCM_FRAMES, reg,
				 sizeof(__le32) * 18, 0);
	kfree(reg);
	return err;
}

static void ff400_handle_midi_msg(struct snd_ff *ff, __le32 *buf, size_t length)
{
	int i;
@@ -146,5 +117,4 @@ const struct snd_ff_protocol snd_ff_protocol_ff400 = {
	.handle_midi_msg	= ff400_handle_midi_msg,
	.begin_session		= ff400_begin_session,
	.finish_session		= ff400_finish_session,
	.switch_fetching_mode	= ff400_switch_fetching_mode,
};
+36 −2
Original line number Diff line number Diff line
@@ -73,10 +73,44 @@ static void release_resources(struct snd_ff *ff)
	fw_iso_resources_free(&ff->rx_resources);
}

static int switch_fetching_mode(struct snd_ff *ff, bool enable)
{
	unsigned int count;
	__le32 *reg;
	int i;
	int err;

	count = 0;
	for (i = 0; i < SND_FF_STREAM_MODES; ++i)
		count = max(count, ff->spec->pcm_playback_channels[i]);

	reg = kcalloc(count, sizeof(__le32), GFP_KERNEL);
	if (!reg)
		return -ENOMEM;

	if (!enable) {
		/*
		 * Each quadlet is corresponding to data channels in a data
		 * blocks in reverse order. Precisely, quadlets for available
		 * data channels should be enabled. Here, I take second best
		 * to fetch PCM frames from all of data channels regardless of
		 * stf.
		 */
		for (i = 0; i < count; ++i)
			reg[i] = cpu_to_le32(0x00000001);
	}

	err = snd_fw_transaction(ff->unit, TCODE_WRITE_BLOCK_REQUEST,
				 SND_FF_REG_FETCH_PCM_FRAMES, reg,
				 sizeof(__le32) * count, 0);
	kfree(reg);
	return err;
}

static inline void finish_session(struct snd_ff *ff)
{
	ff->spec->protocol->finish_session(ff);
	ff->spec->protocol->switch_fetching_mode(ff, false);
	switch_fetching_mode(ff, false);
}

static int init_stream(struct snd_ff *ff, enum amdtp_stream_direction dir)
@@ -188,7 +222,7 @@ int snd_ff_stream_start_duplex(struct snd_ff *ff, unsigned int rate)
			goto error;
		}

		err = ff->spec->protocol->switch_fetching_mode(ff, true);
		err = switch_fetching_mode(ff, true);
		if (err < 0)
			goto error;
	}
+0 −1
Original line number Diff line number Diff line
@@ -111,7 +111,6 @@ struct snd_ff_protocol {
	void (*handle_midi_msg)(struct snd_ff *ff, __le32 *buf, size_t length);
	int (*begin_session)(struct snd_ff *ff, unsigned int rate);
	void (*finish_session)(struct snd_ff *ff);
	int (*switch_fetching_mode)(struct snd_ff *ff, bool enable);
};

extern const struct snd_ff_protocol snd_ff_protocol_ff800;