2 * motu-midi.h - a part of driver for MOTU FireWire series
4 * Copyright (c) 2015-2017 Takashi Sakamoto <o-takashi@sakamocchi.jp>
6 * Licensed under the terms of the GNU General Public License, version 2.
10 static int midi_capture_open(struct snd_rawmidi_substream *substream)
12 struct snd_motu *motu = substream->rmidi->private_data;
15 err = snd_motu_stream_lock_try(motu);
19 mutex_lock(&motu->mutex);
21 motu->capture_substreams++;
22 err = snd_motu_stream_start_duplex(motu, 0);
24 mutex_unlock(&motu->mutex);
27 snd_motu_stream_lock_release(motu);
32 static int midi_playback_open(struct snd_rawmidi_substream *substream)
34 struct snd_motu *motu = substream->rmidi->private_data;
37 err = snd_motu_stream_lock_try(motu);
41 mutex_lock(&motu->mutex);
43 motu->playback_substreams++;
44 err = snd_motu_stream_start_duplex(motu, 0);
46 mutex_unlock(&motu->mutex);
49 snd_motu_stream_lock_release(motu);
54 static int midi_capture_close(struct snd_rawmidi_substream *substream)
56 struct snd_motu *motu = substream->rmidi->private_data;
58 mutex_lock(&motu->mutex);
60 motu->capture_substreams--;
61 snd_motu_stream_stop_duplex(motu);
63 mutex_unlock(&motu->mutex);
65 snd_motu_stream_lock_release(motu);
69 static int midi_playback_close(struct snd_rawmidi_substream *substream)
71 struct snd_motu *motu = substream->rmidi->private_data;
73 mutex_lock(&motu->mutex);
75 motu->playback_substreams--;
76 snd_motu_stream_stop_duplex(motu);
78 mutex_unlock(&motu->mutex);
80 snd_motu_stream_lock_release(motu);
84 static void midi_capture_trigger(struct snd_rawmidi_substream *substrm, int up)
86 struct snd_motu *motu = substrm->rmidi->private_data;
89 spin_lock_irqsave(&motu->lock, flags);
92 amdtp_motu_midi_trigger(&motu->tx_stream, substrm->number,
95 amdtp_motu_midi_trigger(&motu->tx_stream, substrm->number,
98 spin_unlock_irqrestore(&motu->lock, flags);
101 static void midi_playback_trigger(struct snd_rawmidi_substream *substrm, int up)
103 struct snd_motu *motu = substrm->rmidi->private_data;
106 spin_lock_irqsave(&motu->lock, flags);
109 amdtp_motu_midi_trigger(&motu->rx_stream, substrm->number,
112 amdtp_motu_midi_trigger(&motu->rx_stream, substrm->number,
115 spin_unlock_irqrestore(&motu->lock, flags);
118 static void set_midi_substream_names(struct snd_motu *motu,
119 struct snd_rawmidi_str *str)
121 struct snd_rawmidi_substream *subs;
123 list_for_each_entry(subs, &str->substreams, list) {
124 snprintf(subs->name, sizeof(subs->name),
125 "%s MIDI %d", motu->card->shortname, subs->number + 1);
129 int snd_motu_create_midi_devices(struct snd_motu *motu)
131 static const struct snd_rawmidi_ops capture_ops = {
132 .open = midi_capture_open,
133 .close = midi_capture_close,
134 .trigger = midi_capture_trigger,
136 static const struct snd_rawmidi_ops playback_ops = {
137 .open = midi_playback_open,
138 .close = midi_playback_close,
139 .trigger = midi_playback_trigger,
141 struct snd_rawmidi *rmidi;
142 struct snd_rawmidi_str *str;
145 /* create midi ports */
146 err = snd_rawmidi_new(motu->card, motu->card->driver, 0, 1, 1, &rmidi);
150 snprintf(rmidi->name, sizeof(rmidi->name),
151 "%s MIDI", motu->card->shortname);
152 rmidi->private_data = motu;
154 rmidi->info_flags |= SNDRV_RAWMIDI_INFO_INPUT |
155 SNDRV_RAWMIDI_INFO_OUTPUT |
156 SNDRV_RAWMIDI_INFO_DUPLEX;
158 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT,
160 str = &rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT];
161 set_midi_substream_names(motu, str);
163 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,
165 str = &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT];
166 set_midi_substream_names(motu, str);