aboutsummaryrefslogtreecommitdiff
path: root/sound/firewire/oxfw
diff options
context:
space:
mode:
authorTakashi Sakamoto2019-06-12 17:44:22 +0900
committerTakashi Iwai2019-06-12 15:27:01 +0200
commit0356ce3adda0a7b5ef49d580790e94b9c80e8862 (patch)
tree978f5d6ebeb54ffe5bd7b55d0a776ce5f45910d8 /sound/firewire/oxfw
parent4f380d0070528da8b93c4ac3994c20097393f6dd (diff)
ALSA: oxfw: configure stream parameter 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. This commit splits out an operation to configure stream parameters into pcm.hw_params callback. In pcm.prepare callback, establishing connections and start isochronous contexts. Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/firewire/oxfw')
-rw-r--r--sound/firewire/oxfw/oxfw-stream.c97
1 files changed, 57 insertions, 40 deletions
diff --git a/sound/firewire/oxfw/oxfw-stream.c b/sound/firewire/oxfw/oxfw-stream.c
index 373154d8ee0e..837733f10736 100644
--- a/sound/firewire/oxfw/oxfw-stream.c
+++ b/sound/firewire/oxfw/oxfw-stream.c
@@ -103,51 +103,13 @@ static int set_stream_format(struct snd_oxfw *oxfw, struct amdtp_stream *s,
static int start_stream(struct snd_oxfw *oxfw, struct amdtp_stream *stream)
{
- u8 **formats;
- enum avc_general_plug_dir dir;
struct cmp_connection *conn;
- struct snd_oxfw_stream_formation formation;
- int i;
int err;
- if (stream == &oxfw->rx_stream) {
- dir = AVC_GENERAL_PLUG_DIR_IN;
- formats = oxfw->rx_stream_formats;
+ if (stream == &oxfw->rx_stream)
conn = &oxfw->in_conn;
- } else {
- dir = AVC_GENERAL_PLUG_DIR_OUT;
- formats = oxfw->tx_stream_formats;
+ else
conn = &oxfw->out_conn;
- }
-
- err = snd_oxfw_stream_get_current_formation(oxfw, dir, &formation);
- if (err < 0)
- return err;
-
- for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++) {
- struct snd_oxfw_stream_formation fmt;
-
- if (formats[i] == NULL)
- break;
-
- err = snd_oxfw_stream_parse_format(formats[i], &fmt);
- if (err < 0)
- return err;
- if (fmt.rate == formation.rate && fmt.pcm == formation.pcm &&
- fmt.midi == formation.midi)
- break;
- }
- if (i == SND_OXFW_STREAM_FORMAT_ENTRIES)
- return -EINVAL;
-
- // The stream should have one pcm channels at least.
- if (formation.pcm == 0)
- return -EINVAL;
-
- err = amdtp_am824_set_parameters(stream, formation.rate, formation.pcm,
- formation.midi * 8, false);
- if (err < 0)
- return err;
err = cmp_connection_establish(conn,
amdtp_stream_get_max_payload(stream));
@@ -236,6 +198,51 @@ static int init_stream(struct snd_oxfw *oxfw, struct amdtp_stream *stream)
return 0;
}
+static int keep_resources(struct snd_oxfw *oxfw, struct amdtp_stream *stream)
+{
+ enum avc_general_plug_dir dir;
+ u8 **formats;
+ struct snd_oxfw_stream_formation formation;
+ int i;
+ int err;
+
+ if (stream == &oxfw->rx_stream) {
+ dir = AVC_GENERAL_PLUG_DIR_IN;
+ formats = oxfw->rx_stream_formats;
+ } else {
+ dir = AVC_GENERAL_PLUG_DIR_OUT;
+ formats = oxfw->tx_stream_formats;
+ }
+
+ err = snd_oxfw_stream_get_current_formation(oxfw, dir, &formation);
+ if (err < 0)
+ return err;
+
+ for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++) {
+ struct snd_oxfw_stream_formation fmt;
+
+ if (formats[i] == NULL)
+ break;
+
+ err = snd_oxfw_stream_parse_format(formats[i], &fmt);
+ if (err < 0)
+ return err;
+
+ if (fmt.rate == formation.rate && fmt.pcm == formation.pcm &&
+ fmt.midi == formation.midi)
+ break;
+ }
+ if (i == SND_OXFW_STREAM_FORMAT_ENTRIES)
+ return -EINVAL;
+
+ // The stream should have one pcm channels at least.
+ if (formation.pcm == 0)
+ return -EINVAL;
+
+ return amdtp_am824_set_parameters(stream, formation.rate, formation.pcm,
+ formation.midi * 8, false);
+}
+
int snd_oxfw_stream_reserve_duplex(struct snd_oxfw *oxfw,
struct amdtp_stream *stream,
unsigned int rate, unsigned int pcm_channels)
@@ -285,6 +292,16 @@ int snd_oxfw_stream_reserve_duplex(struct snd_oxfw *oxfw,
"fail to set stream format: %d\n", err);
return err;
}
+
+ err = keep_resources(oxfw, &oxfw->rx_stream);
+ if (err < 0)
+ return err;
+
+ if (oxfw->has_output) {
+ err = keep_resources(oxfw, &oxfw->tx_stream);
+ if (err < 0)
+ return err;
+ }
}
return 0;