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