Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

ALSA: oxfw: configure packet format in pcm.hw_params callback



This commit is a part of preparation to perform allocation/release
of isochronous resources in pcm.hw_params/hw_free callbacks.

At present, several operations are done in pcm.prepare callback. To
reduce load of the callback, This commit splits out an operation to
set packet format in pcm.hw_params callback.

Signed-off-by: default avatarTakashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 4a0a0472
Loading
Loading
Loading
Loading
+10 −4
Original line number Diff line number Diff line
@@ -19,8 +19,11 @@ static int midi_capture_open(struct snd_rawmidi_substream *substream)

	mutex_lock(&oxfw->mutex);

	err = snd_oxfw_stream_reserve_duplex(oxfw, &oxfw->tx_stream, 0, 0);
	if (err >= 0) {
		++oxfw->substreams_count;
	err = snd_oxfw_stream_start_duplex(oxfw, &oxfw->tx_stream, 0, 0);
		err = snd_oxfw_stream_start_duplex(oxfw);
	}

	mutex_unlock(&oxfw->mutex);

@@ -41,8 +44,11 @@ static int midi_playback_open(struct snd_rawmidi_substream *substream)

	mutex_lock(&oxfw->mutex);

	err = snd_oxfw_stream_reserve_duplex(oxfw, &oxfw->rx_stream, 0, 0);
	if (err >= 0) {
		++oxfw->substreams_count;
	err = snd_oxfw_stream_start_duplex(oxfw, &oxfw->rx_stream, 0, 0);
		err = snd_oxfw_stream_start_duplex(oxfw);
	}

	mutex_unlock(&oxfw->mutex);

+17 −9
Original line number Diff line number Diff line
@@ -219,12 +219,18 @@ static int pcm_capture_hw_params(struct snd_pcm_substream *substream,
		return err;

	if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) {
		unsigned int rate = params_rate(hw_params);
		unsigned int channels = params_channels(hw_params);

		mutex_lock(&oxfw->mutex);
		err = snd_oxfw_stream_reserve_duplex(oxfw, &oxfw->tx_stream,
						     rate, channels);
		if (err >= 0)
			++oxfw->substreams_count;
		mutex_unlock(&oxfw->mutex);
	}

	return 0;
	return err;
}
static int pcm_playback_hw_params(struct snd_pcm_substream *substream,
				  struct snd_pcm_hw_params *hw_params)
@@ -238,7 +244,13 @@ static int pcm_playback_hw_params(struct snd_pcm_substream *substream,
		return err;

	if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) {
		unsigned int rate = params_rate(hw_params);
		unsigned int channels = params_channels(hw_params);

		mutex_lock(&oxfw->mutex);
		err = snd_oxfw_stream_reserve_duplex(oxfw, &oxfw->tx_stream,
						     rate, channels);
		if (err >= 0)
			++oxfw->substreams_count;
		mutex_unlock(&oxfw->mutex);
	}
@@ -280,12 +292,10 @@ static int pcm_playback_hw_free(struct snd_pcm_substream *substream)
static int pcm_capture_prepare(struct snd_pcm_substream *substream)
{
	struct snd_oxfw *oxfw = substream->private_data;
	struct snd_pcm_runtime *runtime = substream->runtime;
	int err;

	mutex_lock(&oxfw->mutex);
	err = snd_oxfw_stream_start_duplex(oxfw, &oxfw->tx_stream,
					   runtime->rate, runtime->channels);
	err = snd_oxfw_stream_start_duplex(oxfw);
	mutex_unlock(&oxfw->mutex);
	if (err < 0)
		goto end;
@@ -297,12 +307,10 @@ static int pcm_capture_prepare(struct snd_pcm_substream *substream)
static int pcm_playback_prepare(struct snd_pcm_substream *substream)
{
	struct snd_oxfw *oxfw = substream->private_data;
	struct snd_pcm_runtime *runtime = substream->runtime;
	int err;

	mutex_lock(&oxfw->mutex);
	err = snd_oxfw_stream_start_duplex(oxfw, &oxfw->rx_stream,
					   runtime->rate, runtime->channels);
	err = snd_oxfw_stream_start_duplex(oxfw);
	mutex_unlock(&oxfw->mutex);
	if (err < 0)
		goto end;
+31 −13
Original line number Diff line number Diff line
@@ -236,16 +236,13 @@ static int init_stream(struct snd_oxfw *oxfw, struct amdtp_stream *stream)
	return 0;
}

int snd_oxfw_stream_start_duplex(struct snd_oxfw *oxfw,
int snd_oxfw_stream_reserve_duplex(struct snd_oxfw *oxfw,
				   struct amdtp_stream *stream,
				   unsigned int rate, unsigned int pcm_channels)
{
	struct snd_oxfw_stream_formation formation;
	enum avc_general_plug_dir dir;
	int err = 0;

	if (oxfw->substreams_count == 0)
		return -EIO;
	int err;

	// Considering JACK/FFADO streaming:
	// TODO: This can be removed hwdep functionality becomes popular.
@@ -266,14 +263,11 @@ int snd_oxfw_stream_start_duplex(struct snd_oxfw *oxfw,
	err = snd_oxfw_stream_get_current_formation(oxfw, dir, &formation);
	if (err < 0)
		return err;
	if (rate == 0)
	if (rate == 0) {
		rate = formation.rate;
	if (pcm_channels == 0)
		pcm_channels = formation.pcm;

	if (formation.rate != rate || formation.pcm != pcm_channels ||
	    amdtp_streaming_error(&oxfw->rx_stream) ||
	    amdtp_streaming_error(&oxfw->tx_stream)) {
	}
	if (formation.rate != rate || formation.pcm != pcm_channels) {
		amdtp_stream_stop(&oxfw->rx_stream);
		cmp_connection_break(&oxfw->in_conn);

@@ -281,7 +275,10 @@ int snd_oxfw_stream_start_duplex(struct snd_oxfw *oxfw,
			amdtp_stream_stop(&oxfw->tx_stream);
			cmp_connection_break(&oxfw->out_conn);
		}
	}

	if (oxfw->substreams_count == 0 ||
	    formation.rate != rate || formation.pcm != pcm_channels) {
		err = set_stream_format(oxfw, stream, rate, pcm_channels);
		if (err < 0) {
			dev_err(&oxfw->unit->device,
@@ -290,6 +287,27 @@ int snd_oxfw_stream_start_duplex(struct snd_oxfw *oxfw,
		}
	}

	return 0;
}

int snd_oxfw_stream_start_duplex(struct snd_oxfw *oxfw)
{
	int err;

	if (oxfw->substreams_count == 0)
		return -EIO;

	if (amdtp_streaming_error(&oxfw->rx_stream) ||
	    amdtp_streaming_error(&oxfw->tx_stream)) {
		amdtp_stream_stop(&oxfw->rx_stream);
		cmp_connection_break(&oxfw->in_conn);

		if (oxfw->has_output) {
			amdtp_stream_stop(&oxfw->tx_stream);
			cmp_connection_break(&oxfw->out_conn);
		}
	}

	if (!amdtp_stream_running(&oxfw->rx_stream)) {
		err = start_stream(oxfw, &oxfw->rx_stream);
		if (err < 0) {
+4 −3
Original line number Diff line number Diff line
@@ -99,9 +99,10 @@ int avc_general_inquiry_sig_fmt(struct fw_unit *unit, unsigned int rate,
				unsigned short pid);

int snd_oxfw_stream_init_duplex(struct snd_oxfw *oxfw);
int snd_oxfw_stream_start_duplex(struct snd_oxfw *oxfw,
int snd_oxfw_stream_reserve_duplex(struct snd_oxfw *oxfw,
				   struct amdtp_stream *stream,
				   unsigned int rate, unsigned int pcm_channels);
int snd_oxfw_stream_start_duplex(struct snd_oxfw *oxfw);
void snd_oxfw_stream_stop_duplex(struct snd_oxfw *oxfw);
void snd_oxfw_stream_destroy_duplex(struct snd_oxfw *oxfw);
void snd_oxfw_stream_update_duplex(struct snd_oxfw *oxfw);