0001
0002
0003
0004
0005
0006
0007 #include "motu.h"
0008
0009 static int midi_open(struct snd_rawmidi_substream *substream)
0010 {
0011 struct snd_motu *motu = substream->rmidi->private_data;
0012 int err;
0013
0014 err = snd_motu_stream_lock_try(motu);
0015 if (err < 0)
0016 return err;
0017
0018 mutex_lock(&motu->mutex);
0019
0020 err = snd_motu_stream_reserve_duplex(motu, 0, 0, 0);
0021 if (err >= 0) {
0022 ++motu->substreams_counter;
0023 err = snd_motu_stream_start_duplex(motu);
0024 if (err < 0)
0025 --motu->substreams_counter;
0026 }
0027
0028 mutex_unlock(&motu->mutex);
0029
0030 if (err < 0)
0031 snd_motu_stream_lock_release(motu);
0032
0033 return err;
0034 }
0035
0036 static int midi_close(struct snd_rawmidi_substream *substream)
0037 {
0038 struct snd_motu *motu = substream->rmidi->private_data;
0039
0040 mutex_lock(&motu->mutex);
0041
0042 --motu->substreams_counter;
0043 snd_motu_stream_stop_duplex(motu);
0044
0045 mutex_unlock(&motu->mutex);
0046
0047 snd_motu_stream_lock_release(motu);
0048 return 0;
0049 }
0050
0051 static void midi_capture_trigger(struct snd_rawmidi_substream *substrm, int up)
0052 {
0053 struct snd_motu *motu = substrm->rmidi->private_data;
0054 unsigned long flags;
0055
0056 spin_lock_irqsave(&motu->lock, flags);
0057
0058 if (up)
0059 amdtp_motu_midi_trigger(&motu->tx_stream, substrm->number,
0060 substrm);
0061 else
0062 amdtp_motu_midi_trigger(&motu->tx_stream, substrm->number,
0063 NULL);
0064
0065 spin_unlock_irqrestore(&motu->lock, flags);
0066 }
0067
0068 static void midi_playback_trigger(struct snd_rawmidi_substream *substrm, int up)
0069 {
0070 struct snd_motu *motu = substrm->rmidi->private_data;
0071 unsigned long flags;
0072
0073 spin_lock_irqsave(&motu->lock, flags);
0074
0075 if (up)
0076 amdtp_motu_midi_trigger(&motu->rx_stream, substrm->number,
0077 substrm);
0078 else
0079 amdtp_motu_midi_trigger(&motu->rx_stream, substrm->number,
0080 NULL);
0081
0082 spin_unlock_irqrestore(&motu->lock, flags);
0083 }
0084
0085 static void set_midi_substream_names(struct snd_motu *motu,
0086 struct snd_rawmidi_str *str)
0087 {
0088 struct snd_rawmidi_substream *subs;
0089
0090 list_for_each_entry(subs, &str->substreams, list) {
0091 snprintf(subs->name, sizeof(subs->name),
0092 "%s MIDI %d", motu->card->shortname, subs->number + 1);
0093 }
0094 }
0095
0096 int snd_motu_create_midi_devices(struct snd_motu *motu)
0097 {
0098 static const struct snd_rawmidi_ops capture_ops = {
0099 .open = midi_open,
0100 .close = midi_close,
0101 .trigger = midi_capture_trigger,
0102 };
0103 static const struct snd_rawmidi_ops playback_ops = {
0104 .open = midi_open,
0105 .close = midi_close,
0106 .trigger = midi_playback_trigger,
0107 };
0108 struct snd_rawmidi *rmidi;
0109 struct snd_rawmidi_str *str;
0110 int err;
0111
0112
0113 err = snd_rawmidi_new(motu->card, motu->card->driver, 0, 1, 1, &rmidi);
0114 if (err < 0)
0115 return err;
0116
0117 snprintf(rmidi->name, sizeof(rmidi->name),
0118 "%s MIDI", motu->card->shortname);
0119 rmidi->private_data = motu;
0120
0121 rmidi->info_flags |= SNDRV_RAWMIDI_INFO_INPUT |
0122 SNDRV_RAWMIDI_INFO_OUTPUT |
0123 SNDRV_RAWMIDI_INFO_DUPLEX;
0124
0125 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT,
0126 &capture_ops);
0127 str = &rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT];
0128 set_midi_substream_names(motu, str);
0129
0130 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,
0131 &playback_ops);
0132 str = &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT];
0133 set_midi_substream_names(motu, str);
0134
0135 return 0;
0136 }