2 * bebob_midi.c - a part of driver for BeBoB based devices
4 * Copyright (c) 2013-2014 Takashi Sakamoto
6 * Licensed under the terms of the GNU General Public License, version 2.
11 static int midi_capture_open(struct snd_rawmidi_substream
*substream
)
13 struct snd_bebob
*bebob
= substream
->rmidi
->private_data
;
16 err
= snd_bebob_stream_lock_try(bebob
);
20 atomic_inc(&bebob
->capture_substreams
);
21 err
= snd_bebob_stream_start_duplex(bebob
, 0);
23 snd_bebob_stream_lock_release(bebob
);
28 static int midi_playback_open(struct snd_rawmidi_substream
*substream
)
30 struct snd_bebob
*bebob
= substream
->rmidi
->private_data
;
33 err
= snd_bebob_stream_lock_try(bebob
);
37 atomic_inc(&bebob
->playback_substreams
);
38 err
= snd_bebob_stream_start_duplex(bebob
, 0);
40 snd_bebob_stream_lock_release(bebob
);
45 static int midi_capture_close(struct snd_rawmidi_substream
*substream
)
47 struct snd_bebob
*bebob
= substream
->rmidi
->private_data
;
49 atomic_dec(&bebob
->capture_substreams
);
50 snd_bebob_stream_stop_duplex(bebob
);
52 snd_bebob_stream_lock_release(bebob
);
56 static int midi_playback_close(struct snd_rawmidi_substream
*substream
)
58 struct snd_bebob
*bebob
= substream
->rmidi
->private_data
;
60 atomic_dec(&bebob
->playback_substreams
);
61 snd_bebob_stream_stop_duplex(bebob
);
63 snd_bebob_stream_lock_release(bebob
);
67 static void midi_capture_trigger(struct snd_rawmidi_substream
*substrm
, int up
)
69 struct snd_bebob
*bebob
= substrm
->rmidi
->private_data
;
72 spin_lock_irqsave(&bebob
->lock
, flags
);
75 amdtp_stream_midi_trigger(&bebob
->tx_stream
,
76 substrm
->number
, substrm
);
78 amdtp_stream_midi_trigger(&bebob
->tx_stream
,
79 substrm
->number
, NULL
);
81 spin_unlock_irqrestore(&bebob
->lock
, flags
);
84 static void midi_playback_trigger(struct snd_rawmidi_substream
*substrm
, int up
)
86 struct snd_bebob
*bebob
= substrm
->rmidi
->private_data
;
89 spin_lock_irqsave(&bebob
->lock
, flags
);
92 amdtp_stream_midi_trigger(&bebob
->rx_stream
,
93 substrm
->number
, substrm
);
95 amdtp_stream_midi_trigger(&bebob
->rx_stream
,
96 substrm
->number
, NULL
);
98 spin_unlock_irqrestore(&bebob
->lock
, flags
);
101 static struct snd_rawmidi_ops midi_capture_ops
= {
102 .open
= midi_capture_open
,
103 .close
= midi_capture_close
,
104 .trigger
= midi_capture_trigger
,
107 static struct snd_rawmidi_ops midi_playback_ops
= {
108 .open
= midi_playback_open
,
109 .close
= midi_playback_close
,
110 .trigger
= midi_playback_trigger
,
113 static void set_midi_substream_names(struct snd_bebob
*bebob
,
114 struct snd_rawmidi_str
*str
)
116 struct snd_rawmidi_substream
*subs
;
118 list_for_each_entry(subs
, &str
->substreams
, list
) {
119 snprintf(subs
->name
, sizeof(subs
->name
),
121 bebob
->card
->shortname
, subs
->number
+ 1);
125 int snd_bebob_create_midi_devices(struct snd_bebob
*bebob
)
127 struct snd_rawmidi
*rmidi
;
128 struct snd_rawmidi_str
*str
;
131 /* create midi ports */
132 err
= snd_rawmidi_new(bebob
->card
, bebob
->card
->driver
, 0,
133 bebob
->midi_output_ports
, bebob
->midi_input_ports
,
138 snprintf(rmidi
->name
, sizeof(rmidi
->name
),
139 "%s MIDI", bebob
->card
->shortname
);
140 rmidi
->private_data
= bebob
;
142 if (bebob
->midi_input_ports
> 0) {
143 rmidi
->info_flags
|= SNDRV_RAWMIDI_INFO_INPUT
;
145 snd_rawmidi_set_ops(rmidi
, SNDRV_RAWMIDI_STREAM_INPUT
,
148 str
= &rmidi
->streams
[SNDRV_RAWMIDI_STREAM_INPUT
];
150 set_midi_substream_names(bebob
, str
);
153 if (bebob
->midi_output_ports
> 0) {
154 rmidi
->info_flags
|= SNDRV_RAWMIDI_INFO_OUTPUT
;
156 snd_rawmidi_set_ops(rmidi
, SNDRV_RAWMIDI_STREAM_OUTPUT
,
159 str
= &rmidi
->streams
[SNDRV_RAWMIDI_STREAM_OUTPUT
];
161 set_midi_substream_names(bebob
, str
);
164 if ((bebob
->midi_output_ports
> 0) && (bebob
->midi_input_ports
> 0))
165 rmidi
->info_flags
|= SNDRV_RAWMIDI_INFO_DUPLEX
;