Linux 4.18.10
[linux/fpc-iii.git] / sound / firewire / motu / motu-midi.c
blobe55cab6d79c7df91d72b6837def3a1bdb1b6bdca
1 /*
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.
7 */
8 #include "motu.h"
10 static int midi_capture_open(struct snd_rawmidi_substream *substream)
12 struct snd_motu *motu = substream->rmidi->private_data;
13 int err;
15 err = snd_motu_stream_lock_try(motu);
16 if (err < 0)
17 return err;
19 mutex_lock(&motu->mutex);
21 motu->capture_substreams++;
22 err = snd_motu_stream_start_duplex(motu, 0);
24 mutex_unlock(&motu->mutex);
26 if (err < 0)
27 snd_motu_stream_lock_release(motu);
29 return err;
32 static int midi_playback_open(struct snd_rawmidi_substream *substream)
34 struct snd_motu *motu = substream->rmidi->private_data;
35 int err;
37 err = snd_motu_stream_lock_try(motu);
38 if (err < 0)
39 return err;
41 mutex_lock(&motu->mutex);
43 motu->playback_substreams++;
44 err = snd_motu_stream_start_duplex(motu, 0);
46 mutex_unlock(&motu->mutex);
48 if (err < 0)
49 snd_motu_stream_lock_release(motu);
51 return err;
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);
66 return 0;
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);
81 return 0;
84 static void midi_capture_trigger(struct snd_rawmidi_substream *substrm, int up)
86 struct snd_motu *motu = substrm->rmidi->private_data;
87 unsigned long flags;
89 spin_lock_irqsave(&motu->lock, flags);
91 if (up)
92 amdtp_motu_midi_trigger(&motu->tx_stream, substrm->number,
93 substrm);
94 else
95 amdtp_motu_midi_trigger(&motu->tx_stream, substrm->number,
96 NULL);
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;
104 unsigned long flags;
106 spin_lock_irqsave(&motu->lock, flags);
108 if (up)
109 amdtp_motu_midi_trigger(&motu->rx_stream, substrm->number,
110 substrm);
111 else
112 amdtp_motu_midi_trigger(&motu->rx_stream, substrm->number,
113 NULL);
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;
143 int err;
145 /* create midi ports */
146 err = snd_rawmidi_new(motu->card, motu->card->driver, 0, 1, 1, &rmidi);
147 if (err < 0)
148 return err;
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,
159 &capture_ops);
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,
164 &playback_ops);
165 str = &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT];
166 set_midi_substream_names(motu, str);
168 return 0;