summaryrefslogtreecommitdiffstats
path: root/sound/firewire
diff options
context:
space:
mode:
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>2017-04-02 10:48:26 -0400
committerTakashi Iwai <tiwai@suse.de>2017-04-05 15:34:11 -0400
commit0c3f15f39cfd7697e0c4979a85fef1a3c3d17248 (patch)
treeebc7cda4859778487122e1ceaf24bc15a4883fc6 /sound/firewire
parent8820a4cf0cb4cd5c6540a9a18b2cedbdfd5a6891 (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.c208
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
11static int midi_phys_open(struct snd_rawmidi_substream *substream) 11static 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
30static int midi_phys_close(struct snd_rawmidi_substream *substream) 30static 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
43static void midi_phys_capture_trigger(struct snd_rawmidi_substream *substream, 43static 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
61static 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
79static int midi_ctl_open(struct snd_rawmidi_substream *substream) 65static void midi_playback_trigger(struct snd_rawmidi_substream *substream,
80{ 66 int up)
81 /* Do nothing. */
82 return 0;
83}
84
85static int midi_ctl_capture_close(struct snd_rawmidi_substream *substream)
86{
87 /* Do nothing. */
88 return 0;
89}
90
91static 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
100static 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
116static 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
130static void set_midi_substream_names(struct snd_dg00x *dg00x, 87static 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
149int snd_dg00x_create_midi_devices(struct snd_dg00x *dg00x) 112static 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; 155int 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}