diff options
-rw-r--r-- | sound/firewire/digi00x/digi00x-midi.c | 104 |
1 files changed, 50 insertions, 54 deletions
diff --git a/sound/firewire/digi00x/digi00x-midi.c b/sound/firewire/digi00x/digi00x-midi.c index 527f4b31f5c6..1a72a382b384 100644 --- a/sound/firewire/digi00x/digi00x-midi.c +++ b/sound/firewire/digi00x/digi00x-midi.c | |||
@@ -13,10 +13,6 @@ static int midi_phys_open(struct snd_rawmidi_substream *substream) | |||
13 | struct snd_dg00x *dg00x = substream->rmidi->private_data; | 13 | struct snd_dg00x *dg00x = substream->rmidi->private_data; |
14 | int err; | 14 | int err; |
15 | 15 | ||
16 | /* This port is for asynchronous transaction. */ | ||
17 | if (substream->number == 0) | ||
18 | return 0; | ||
19 | |||
20 | err = snd_dg00x_stream_lock_try(dg00x); | 16 | err = snd_dg00x_stream_lock_try(dg00x); |
21 | if (err < 0) | 17 | if (err < 0) |
22 | return err; | 18 | return err; |
@@ -35,10 +31,6 @@ static int midi_phys_close(struct snd_rawmidi_substream *substream) | |||
35 | { | 31 | { |
36 | struct snd_dg00x *dg00x = substream->rmidi->private_data; | 32 | struct snd_dg00x *dg00x = substream->rmidi->private_data; |
37 | 33 | ||
38 | /* This port is for asynchronous transaction. */ | ||
39 | if (substream->number == 0) | ||
40 | return 0; | ||
41 | |||
42 | mutex_lock(&dg00x->mutex); | 34 | mutex_lock(&dg00x->mutex); |
43 | dg00x->substreams_counter--; | 35 | dg00x->substreams_counter--; |
44 | snd_dg00x_stream_stop_duplex(dg00x); | 36 | snd_dg00x_stream_stop_duplex(dg00x); |
@@ -56,21 +48,12 @@ static void midi_phys_capture_trigger(struct snd_rawmidi_substream *substream, | |||
56 | 48 | ||
57 | spin_lock_irqsave(&dg00x->lock, flags); | 49 | spin_lock_irqsave(&dg00x->lock, flags); |
58 | 50 | ||
59 | /* This port is for asynchronous transaction. */ | 51 | if (up) |
60 | if (substream->number == 0) { | 52 | amdtp_dot_midi_trigger(&dg00x->tx_stream, substream->number, |
61 | if (up) | 53 | substream); |
62 | dg00x->in_control = substream; | 54 | else |
63 | else | 55 | amdtp_dot_midi_trigger(&dg00x->tx_stream, substream->number, |
64 | dg00x->in_control = NULL; | 56 | NULL); |
65 | } else { | ||
66 | if (up) | ||
67 | amdtp_dot_midi_trigger(&dg00x->tx_stream, | ||
68 | substream->number - 1, | ||
69 | substream); | ||
70 | else | ||
71 | amdtp_dot_midi_trigger(&dg00x->tx_stream, | ||
72 | substream->number - 1, NULL); | ||
73 | } | ||
74 | 57 | ||
75 | spin_unlock_irqrestore(&dg00x->lock, flags); | 58 | spin_unlock_irqrestore(&dg00x->lock, flags); |
76 | } | 59 | } |
@@ -83,20 +66,12 @@ static void midi_phys_playback_trigger(struct snd_rawmidi_substream *substream, | |||
83 | 66 | ||
84 | spin_lock_irqsave(&dg00x->lock, flags); | 67 | spin_lock_irqsave(&dg00x->lock, flags); |
85 | 68 | ||
86 | /* This port is for asynchronous transaction. */ | 69 | if (up) |
87 | if (substream->number == 0) { | 70 | amdtp_dot_midi_trigger(&dg00x->rx_stream, substream->number, |
88 | if (up) | 71 | substream); |
89 | snd_fw_async_midi_port_run(&dg00x->out_control, | 72 | else |
90 | substream); | 73 | amdtp_dot_midi_trigger(&dg00x->rx_stream, substream->number, |
91 | } else { | 74 | NULL); |
92 | if (up) | ||
93 | amdtp_dot_midi_trigger(&dg00x->rx_stream, | ||
94 | substream->number - 1, | ||
95 | substream); | ||
96 | else | ||
97 | amdtp_dot_midi_trigger(&dg00x->rx_stream, | ||
98 | substream->number - 1, NULL); | ||
99 | } | ||
100 | 75 | ||
101 | spin_unlock_irqrestore(&dg00x->lock, flags); | 76 | spin_unlock_irqrestore(&dg00x->lock, flags); |
102 | } | 77 | } |
@@ -177,15 +152,16 @@ static struct snd_rawmidi_ops midi_ctl_playback_ops = { | |||
177 | }; | 152 | }; |
178 | 153 | ||
179 | static void set_midi_substream_names(struct snd_dg00x *dg00x, | 154 | static void set_midi_substream_names(struct snd_dg00x *dg00x, |
180 | struct snd_rawmidi_str *str) | 155 | struct snd_rawmidi_str *str, |
156 | bool is_ctl) | ||
181 | { | 157 | { |
182 | struct snd_rawmidi_substream *subs; | 158 | struct snd_rawmidi_substream *subs; |
183 | 159 | ||
184 | list_for_each_entry(subs, &str->substreams, list) { | 160 | list_for_each_entry(subs, &str->substreams, list) { |
185 | if (subs->number > 0) | 161 | if (!is_ctl) |
186 | snprintf(subs->name, sizeof(subs->name), | 162 | snprintf(subs->name, sizeof(subs->name), |
187 | "%s MIDI %d", | 163 | "%s MIDI %d", |
188 | dg00x->card->shortname, subs->number); | 164 | dg00x->card->shortname, subs->number + 1); |
189 | else | 165 | else |
190 | /* This port is for asynchronous transaction. */ | 166 | /* This port is for asynchronous transaction. */ |
191 | snprintf(subs->name, sizeof(subs->name), | 167 | snprintf(subs->name, sizeof(subs->name), |
@@ -196,32 +172,52 @@ static void set_midi_substream_names(struct snd_dg00x *dg00x, | |||
196 | 172 | ||
197 | int snd_dg00x_create_midi_devices(struct snd_dg00x *dg00x) | 173 | int snd_dg00x_create_midi_devices(struct snd_dg00x *dg00x) |
198 | { | 174 | { |
199 | struct snd_rawmidi *rmidi; | 175 | struct snd_rawmidi *rmidi[2]; |
200 | struct snd_rawmidi_str *str; | 176 | struct snd_rawmidi_str *str; |
177 | unsigned int i; | ||
201 | int err; | 178 | int err; |
202 | 179 | ||
180 | /* Add physical midi ports. */ | ||
203 | err = snd_rawmidi_new(dg00x->card, dg00x->card->driver, 0, | 181 | err = snd_rawmidi_new(dg00x->card, dg00x->card->driver, 0, |
204 | DOT_MIDI_OUT_PORTS + 1, DOT_MIDI_IN_PORTS + 1, &rmidi); | 182 | DOT_MIDI_OUT_PORTS, DOT_MIDI_IN_PORTS, &rmidi[0]); |
205 | if (err < 0) | 183 | if (err < 0) |
206 | return err; | 184 | return err; |
207 | 185 | ||
208 | snprintf(rmidi->name, sizeof(rmidi->name), | 186 | snprintf(rmidi[0]->name, sizeof(rmidi[0]->name), |
209 | "%s MIDI", dg00x->card->shortname); | 187 | "%s MIDI", dg00x->card->shortname); |
210 | rmidi->private_data = dg00x; | ||
211 | 188 | ||
212 | rmidi->info_flags |= SNDRV_RAWMIDI_INFO_INPUT; | 189 | snd_rawmidi_set_ops(rmidi[0], SNDRV_RAWMIDI_STREAM_INPUT, |
213 | snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, | ||
214 | &midi_phys_capture_ops); | 190 | &midi_phys_capture_ops); |
215 | str = &rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT]; | 191 | snd_rawmidi_set_ops(rmidi[0], SNDRV_RAWMIDI_STREAM_OUTPUT, |
216 | set_midi_substream_names(dg00x, str); | ||
217 | |||
218 | rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT; | ||
219 | snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, | ||
220 | &midi_phys_playback_ops); | 192 | &midi_phys_playback_ops); |
221 | str = &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT]; | ||
222 | set_midi_substream_names(dg00x, str); | ||
223 | 193 | ||
224 | rmidi->info_flags |= SNDRV_RAWMIDI_INFO_DUPLEX; | 194 | /* Add a pair of control midi ports. */ |
195 | err = snd_rawmidi_new(dg00x->card, dg00x->card->driver, 1, | ||
196 | 1, 1, &rmidi[1]); | ||
197 | if (err < 0) | ||
198 | return err; | ||
199 | |||
200 | snprintf(rmidi[1]->name, sizeof(rmidi[1]->name), | ||
201 | "%s control", dg00x->card->shortname); | ||
202 | |||
203 | snd_rawmidi_set_ops(rmidi[1], SNDRV_RAWMIDI_STREAM_INPUT, | ||
204 | &midi_ctl_capture_ops); | ||
205 | snd_rawmidi_set_ops(rmidi[1], SNDRV_RAWMIDI_STREAM_OUTPUT, | ||
206 | &midi_ctl_playback_ops); | ||
207 | |||
208 | for (i = 0; i < ARRAY_SIZE(rmidi); i++) { | ||
209 | rmidi[i]->private_data = dg00x; | ||
210 | |||
211 | rmidi[i]->info_flags |= SNDRV_RAWMIDI_INFO_INPUT; | ||
212 | str = &rmidi[i]->streams[SNDRV_RAWMIDI_STREAM_INPUT]; | ||
213 | set_midi_substream_names(dg00x, str, i); | ||
214 | |||
215 | rmidi[i]->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT; | ||
216 | str = &rmidi[i]->streams[SNDRV_RAWMIDI_STREAM_OUTPUT]; | ||
217 | set_midi_substream_names(dg00x, str, i); | ||
218 | |||
219 | rmidi[i]->info_flags |= SNDRV_RAWMIDI_INFO_DUPLEX; | ||
220 | } | ||
225 | 221 | ||
226 | return 0; | 222 | return 0; |
227 | } | 223 | } |