diff options
author | Takashi Sakamoto <o-takashi@sakamocchi.jp> | 2017-04-02 10:48:26 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2017-04-05 15:34:11 -0400 |
commit | 0c3f15f39cfd7697e0c4979a85fef1a3c3d17248 (patch) | |
tree | ebc7cda4859778487122e1ceaf24bc15a4883fc6 /sound/firewire | |
parent | 8820a4cf0cb4cd5c6540a9a18b2cedbdfd5a6891 (diff) |
ALSA: firewire-digi00x: allow user space applications to read/write MIDI messages for all ports
At a commit c5fcee0373b3 ("ALSA: firewire-digi00x: add MIDI operations for
MIDI control port"), I described that MIDI messages for control surface is
transferred by a different way from the messages for physical ports.
However, this is wrong. MIDI messages to/from all of MIDI ports are
transferred by isochronous packets.
This commit removes codes to transfer MIDI messages via asynchronous
transaction, from MIDI handling layer.
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/firewire')
-rw-r--r-- | sound/firewire/digi00x/digi00x-midi.c | 208 |
1 files changed, 79 insertions, 129 deletions
diff --git a/sound/firewire/digi00x/digi00x-midi.c b/sound/firewire/digi00x/digi00x-midi.c index 915d2a21223e..7ab3d0810f6b 100644 --- a/sound/firewire/digi00x/digi00x-midi.c +++ b/sound/firewire/digi00x/digi00x-midi.c | |||
@@ -8,7 +8,7 @@ | |||
8 | 8 | ||
9 | #include "digi00x.h" | 9 | #include "digi00x.h" |
10 | 10 | ||
11 | static int midi_phys_open(struct snd_rawmidi_substream *substream) | 11 | static int midi_open(struct snd_rawmidi_substream *substream) |
12 | { | 12 | { |
13 | struct snd_dg00x *dg00x = substream->rmidi->private_data; | 13 | struct snd_dg00x *dg00x = substream->rmidi->private_data; |
14 | int err; | 14 | int err; |
@@ -27,7 +27,7 @@ static int midi_phys_open(struct snd_rawmidi_substream *substream) | |||
27 | return err; | 27 | return err; |
28 | } | 28 | } |
29 | 29 | ||
30 | static int midi_phys_close(struct snd_rawmidi_substream *substream) | 30 | static int midi_close(struct snd_rawmidi_substream *substream) |
31 | { | 31 | { |
32 | struct snd_dg00x *dg00x = substream->rmidi->private_data; | 32 | struct snd_dg00x *dg00x = substream->rmidi->private_data; |
33 | 33 | ||
@@ -40,180 +40,130 @@ static int midi_phys_close(struct snd_rawmidi_substream *substream) | |||
40 | return 0; | 40 | return 0; |
41 | } | 41 | } |
42 | 42 | ||
43 | static void midi_phys_capture_trigger(struct snd_rawmidi_substream *substream, | 43 | static void midi_capture_trigger(struct snd_rawmidi_substream *substream, |
44 | int up) | 44 | int up) |
45 | { | 45 | { |
46 | struct snd_dg00x *dg00x = substream->rmidi->private_data; | 46 | struct snd_dg00x *dg00x = substream->rmidi->private_data; |
47 | unsigned int port; | ||
47 | unsigned long flags; | 48 | unsigned long flags; |
48 | 49 | ||
49 | spin_lock_irqsave(&dg00x->lock, flags); | 50 | if (substream->rmidi->device == 0) |
50 | 51 | port = substream->number; | |
51 | if (up) | ||
52 | amdtp_dot_midi_trigger(&dg00x->tx_stream, substream->number, | ||
53 | substream); | ||
54 | else | 52 | else |
55 | amdtp_dot_midi_trigger(&dg00x->tx_stream, substream->number, | 53 | port = 2; |
56 | NULL); | ||
57 | |||
58 | spin_unlock_irqrestore(&dg00x->lock, flags); | ||
59 | } | ||
60 | |||
61 | static void midi_phys_playback_trigger(struct snd_rawmidi_substream *substream, | ||
62 | int up) | ||
63 | { | ||
64 | struct snd_dg00x *dg00x = substream->rmidi->private_data; | ||
65 | unsigned long flags; | ||
66 | 54 | ||
67 | spin_lock_irqsave(&dg00x->lock, flags); | 55 | spin_lock_irqsave(&dg00x->lock, flags); |
68 | 56 | ||
69 | if (up) | 57 | if (up) |
70 | amdtp_dot_midi_trigger(&dg00x->rx_stream, substream->number, | 58 | amdtp_dot_midi_trigger(&dg00x->tx_stream, port, substream); |
71 | substream); | ||
72 | else | 59 | else |
73 | amdtp_dot_midi_trigger(&dg00x->rx_stream, substream->number, | 60 | amdtp_dot_midi_trigger(&dg00x->tx_stream, port, NULL); |
74 | NULL); | ||
75 | 61 | ||
76 | spin_unlock_irqrestore(&dg00x->lock, flags); | 62 | spin_unlock_irqrestore(&dg00x->lock, flags); |
77 | } | 63 | } |
78 | 64 | ||
79 | static int midi_ctl_open(struct snd_rawmidi_substream *substream) | 65 | static void midi_playback_trigger(struct snd_rawmidi_substream *substream, |
80 | { | 66 | int up) |
81 | /* Do nothing. */ | ||
82 | return 0; | ||
83 | } | ||
84 | |||
85 | static int midi_ctl_capture_close(struct snd_rawmidi_substream *substream) | ||
86 | { | ||
87 | /* Do nothing. */ | ||
88 | return 0; | ||
89 | } | ||
90 | |||
91 | static int midi_ctl_playback_close(struct snd_rawmidi_substream *substream) | ||
92 | { | ||
93 | struct snd_dg00x *dg00x = substream->rmidi->private_data; | ||
94 | |||
95 | snd_fw_async_midi_port_finish(&dg00x->out_control); | ||
96 | |||
97 | return 0; | ||
98 | } | ||
99 | |||
100 | static void midi_ctl_capture_trigger(struct snd_rawmidi_substream *substream, | ||
101 | int up) | ||
102 | { | 67 | { |
103 | struct snd_dg00x *dg00x = substream->rmidi->private_data; | 68 | struct snd_dg00x *dg00x = substream->rmidi->private_data; |
69 | unsigned int port; | ||
104 | unsigned long flags; | 70 | unsigned long flags; |
105 | 71 | ||
106 | spin_lock_irqsave(&dg00x->lock, flags); | 72 | if (substream->rmidi->device == 0) |
107 | 73 | port = substream->number; | |
108 | if (up) | ||
109 | dg00x->in_control = substream; | ||
110 | else | 74 | else |
111 | dg00x->in_control = NULL; | 75 | port = 2; |
112 | |||
113 | spin_unlock_irqrestore(&dg00x->lock, flags); | ||
114 | } | ||
115 | |||
116 | static void midi_ctl_playback_trigger(struct snd_rawmidi_substream *substream, | ||
117 | int up) | ||
118 | { | ||
119 | struct snd_dg00x *dg00x = substream->rmidi->private_data; | ||
120 | unsigned long flags; | ||
121 | 76 | ||
122 | spin_lock_irqsave(&dg00x->lock, flags); | 77 | spin_lock_irqsave(&dg00x->lock, flags); |
123 | 78 | ||
124 | if (up) | 79 | if (up) |
125 | snd_fw_async_midi_port_run(&dg00x->out_control, substream); | 80 | amdtp_dot_midi_trigger(&dg00x->rx_stream, port, substream); |
81 | else | ||
82 | amdtp_dot_midi_trigger(&dg00x->rx_stream, port, NULL); | ||
126 | 83 | ||
127 | spin_unlock_irqrestore(&dg00x->lock, flags); | 84 | spin_unlock_irqrestore(&dg00x->lock, flags); |
128 | } | 85 | } |
129 | 86 | ||
130 | static void set_midi_substream_names(struct snd_dg00x *dg00x, | 87 | static void set_substream_names(struct snd_dg00x *dg00x, |
131 | struct snd_rawmidi_str *str, | 88 | struct snd_rawmidi *rmidi, bool is_console) |
132 | bool is_ctl) | ||
133 | { | 89 | { |
134 | struct snd_rawmidi_substream *subs; | 90 | struct snd_rawmidi_substream *subs; |
135 | 91 | struct snd_rawmidi_str *str; | |
136 | list_for_each_entry(subs, &str->substreams, list) { | 92 | int i; |
137 | if (!is_ctl) | 93 | |
138 | snprintf(subs->name, sizeof(subs->name), | 94 | for (i = 0; i < 2; ++i) { |
139 | "%s MIDI %d", | 95 | str = &rmidi->streams[i]; |
140 | dg00x->card->shortname, subs->number + 1); | 96 | |
141 | else | 97 | list_for_each_entry(subs, &str->substreams, list) { |
142 | /* This port is for asynchronous transaction. */ | 98 | if (!is_console) { |
143 | snprintf(subs->name, sizeof(subs->name), | 99 | snprintf(subs->name, sizeof(subs->name), |
144 | "%s control", | 100 | "%s MIDI %d", |
145 | dg00x->card->shortname); | 101 | dg00x->card->shortname, |
102 | subs->number + 1); | ||
103 | } else { | ||
104 | snprintf(subs->name, sizeof(subs->name), | ||
105 | "%s control", | ||
106 | dg00x->card->shortname); | ||
107 | } | ||
108 | } | ||
146 | } | 109 | } |
147 | } | 110 | } |
148 | 111 | ||
149 | int snd_dg00x_create_midi_devices(struct snd_dg00x *dg00x) | 112 | static int add_substream_pair(struct snd_dg00x *dg00x, unsigned int out_ports, |
113 | unsigned int in_ports, bool is_console) | ||
150 | { | 114 | { |
151 | static const struct snd_rawmidi_ops phys_capture_ops = { | 115 | static const struct snd_rawmidi_ops capture_ops = { |
152 | .open = midi_phys_open, | 116 | .open = midi_open, |
153 | .close = midi_phys_close, | 117 | .close = midi_close, |
154 | .trigger = midi_phys_capture_trigger, | 118 | .trigger = midi_capture_trigger, |
155 | }; | ||
156 | static const struct snd_rawmidi_ops phys_playback_ops = { | ||
157 | .open = midi_phys_open, | ||
158 | .close = midi_phys_close, | ||
159 | .trigger = midi_phys_playback_trigger, | ||
160 | }; | 119 | }; |
161 | static const struct snd_rawmidi_ops ctl_capture_ops = { | 120 | static const struct snd_rawmidi_ops playback_ops = { |
162 | .open = midi_ctl_open, | 121 | .open = midi_open, |
163 | .close = midi_ctl_capture_close, | 122 | .close = midi_close, |
164 | .trigger = midi_ctl_capture_trigger, | 123 | .trigger = midi_playback_trigger, |
165 | }; | 124 | }; |
166 | static const struct snd_rawmidi_ops ctl_playback_ops = { | 125 | const char *label; |
167 | .open = midi_ctl_open, | 126 | struct snd_rawmidi *rmidi; |
168 | .close = midi_ctl_playback_close, | ||
169 | .trigger = midi_ctl_playback_trigger, | ||
170 | }; | ||
171 | struct snd_rawmidi *rmidi[2]; | ||
172 | struct snd_rawmidi_str *str; | ||
173 | unsigned int i; | ||
174 | int err; | 127 | int err; |
175 | 128 | ||
176 | /* Add physical midi ports. */ | 129 | /* Add physical midi ports. */ |
177 | err = snd_rawmidi_new(dg00x->card, dg00x->card->driver, 0, | 130 | err = snd_rawmidi_new(dg00x->card, dg00x->card->driver, is_console, |
178 | DOT_MIDI_OUT_PORTS, DOT_MIDI_IN_PORTS, &rmidi[0]); | 131 | out_ports, in_ports, &rmidi); |
179 | if (err < 0) | 132 | if (err < 0) |
180 | return err; | 133 | return err; |
134 | rmidi->private_data = dg00x; | ||
181 | 135 | ||
182 | snprintf(rmidi[0]->name, sizeof(rmidi[0]->name), | 136 | if (!is_console) |
183 | "%s MIDI", dg00x->card->shortname); | 137 | label = "%s control"; |
184 | 138 | else | |
185 | snd_rawmidi_set_ops(rmidi[0], SNDRV_RAWMIDI_STREAM_INPUT, | 139 | label = "%s MIDI"; |
186 | &phys_capture_ops); | 140 | snprintf(rmidi->name, sizeof(rmidi->name), label, |
187 | snd_rawmidi_set_ops(rmidi[0], SNDRV_RAWMIDI_STREAM_OUTPUT, | 141 | dg00x->card->shortname); |
188 | &phys_playback_ops); | ||
189 | 142 | ||
190 | /* Add a pair of control midi ports. */ | 143 | snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &playback_ops); |
191 | err = snd_rawmidi_new(dg00x->card, dg00x->card->driver, 1, | 144 | snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &capture_ops); |
192 | 1, 1, &rmidi[1]); | ||
193 | if (err < 0) | ||
194 | return err; | ||
195 | 145 | ||
196 | snprintf(rmidi[1]->name, sizeof(rmidi[1]->name), | 146 | rmidi->info_flags |= SNDRV_RAWMIDI_INFO_INPUT | |
197 | "%s control", dg00x->card->shortname); | 147 | SNDRV_RAWMIDI_INFO_OUTPUT | |
148 | SNDRV_RAWMIDI_INFO_DUPLEX; | ||
198 | 149 | ||
199 | snd_rawmidi_set_ops(rmidi[1], SNDRV_RAWMIDI_STREAM_INPUT, | 150 | set_substream_names(dg00x, rmidi, is_console); |
200 | &ctl_capture_ops); | ||
201 | snd_rawmidi_set_ops(rmidi[1], SNDRV_RAWMIDI_STREAM_OUTPUT, | ||
202 | &ctl_playback_ops); | ||
203 | 151 | ||
204 | for (i = 0; i < ARRAY_SIZE(rmidi); i++) { | 152 | return 0; |
205 | rmidi[i]->private_data = dg00x; | 153 | } |
206 | 154 | ||
207 | rmidi[i]->info_flags |= SNDRV_RAWMIDI_INFO_INPUT; | 155 | int snd_dg00x_create_midi_devices(struct snd_dg00x *dg00x) |
208 | str = &rmidi[i]->streams[SNDRV_RAWMIDI_STREAM_INPUT]; | 156 | { |
209 | set_midi_substream_names(dg00x, str, i); | 157 | int err; |
210 | 158 | ||
211 | rmidi[i]->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT; | 159 | /* Add physical midi ports. */ |
212 | str = &rmidi[i]->streams[SNDRV_RAWMIDI_STREAM_OUTPUT]; | 160 | err = add_substream_pair(dg00x, DOT_MIDI_OUT_PORTS, DOT_MIDI_IN_PORTS, |
213 | set_midi_substream_names(dg00x, str, i); | 161 | false); |
162 | if (err < 0) | ||
163 | return err; | ||
214 | 164 | ||
215 | rmidi[i]->info_flags |= SNDRV_RAWMIDI_INFO_DUPLEX; | 165 | if (dg00x->is_console) |
216 | } | 166 | err = add_substream_pair(dg00x, 1, 1, true); |
217 | 167 | ||
218 | return 0; | 168 | return err; |
219 | } | 169 | } |