2 * fireworks_midi.c - a part of driver for Fireworks based devices
4 * Copyright (c) 2009-2010 Clemens Ladisch
5 * Copyright (c) 2013-2014 Takashi Sakamoto
7 * 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_efw
*efw
= substream
->rmidi
->private_data
;
16 err
= snd_efw_stream_lock_try(efw
);
20 atomic_inc(&efw
->capture_substreams
);
21 err
= snd_efw_stream_start_duplex(efw
, 0);
23 snd_efw_stream_lock_release(efw
);
29 static int midi_playback_open(struct snd_rawmidi_substream
*substream
)
31 struct snd_efw
*efw
= substream
->rmidi
->private_data
;
34 err
= snd_efw_stream_lock_try(efw
);
38 atomic_inc(&efw
->playback_substreams
);
39 err
= snd_efw_stream_start_duplex(efw
, 0);
41 snd_efw_stream_lock_release(efw
);
46 static int midi_capture_close(struct snd_rawmidi_substream
*substream
)
48 struct snd_efw
*efw
= substream
->rmidi
->private_data
;
50 atomic_dec(&efw
->capture_substreams
);
51 snd_efw_stream_stop_duplex(efw
);
53 snd_efw_stream_lock_release(efw
);
57 static int midi_playback_close(struct snd_rawmidi_substream
*substream
)
59 struct snd_efw
*efw
= substream
->rmidi
->private_data
;
61 atomic_dec(&efw
->playback_substreams
);
62 snd_efw_stream_stop_duplex(efw
);
64 snd_efw_stream_lock_release(efw
);
68 static void midi_capture_trigger(struct snd_rawmidi_substream
*substrm
, int up
)
70 struct snd_efw
*efw
= substrm
->rmidi
->private_data
;
73 spin_lock_irqsave(&efw
->lock
, flags
);
76 amdtp_stream_midi_trigger(&efw
->tx_stream
,
77 substrm
->number
, substrm
);
79 amdtp_stream_midi_trigger(&efw
->tx_stream
,
80 substrm
->number
, NULL
);
82 spin_unlock_irqrestore(&efw
->lock
, flags
);
85 static void midi_playback_trigger(struct snd_rawmidi_substream
*substrm
, int up
)
87 struct snd_efw
*efw
= substrm
->rmidi
->private_data
;
90 spin_lock_irqsave(&efw
->lock
, flags
);
93 amdtp_stream_midi_trigger(&efw
->rx_stream
,
94 substrm
->number
, substrm
);
96 amdtp_stream_midi_trigger(&efw
->rx_stream
,
97 substrm
->number
, NULL
);
99 spin_unlock_irqrestore(&efw
->lock
, flags
);
102 static struct snd_rawmidi_ops midi_capture_ops
= {
103 .open
= midi_capture_open
,
104 .close
= midi_capture_close
,
105 .trigger
= midi_capture_trigger
,
108 static struct snd_rawmidi_ops midi_playback_ops
= {
109 .open
= midi_playback_open
,
110 .close
= midi_playback_close
,
111 .trigger
= midi_playback_trigger
,
114 static void set_midi_substream_names(struct snd_efw
*efw
,
115 struct snd_rawmidi_str
*str
)
117 struct snd_rawmidi_substream
*subs
;
119 list_for_each_entry(subs
, &str
->substreams
, list
) {
120 snprintf(subs
->name
, sizeof(subs
->name
),
121 "%s MIDI %d", efw
->card
->shortname
, subs
->number
+ 1);
125 int snd_efw_create_midi_devices(struct snd_efw
*efw
)
127 struct snd_rawmidi
*rmidi
;
128 struct snd_rawmidi_str
*str
;
131 /* create midi ports */
132 err
= snd_rawmidi_new(efw
->card
, efw
->card
->driver
, 0,
133 efw
->midi_out_ports
, efw
->midi_in_ports
,
138 snprintf(rmidi
->name
, sizeof(rmidi
->name
),
139 "%s MIDI", efw
->card
->shortname
);
140 rmidi
->private_data
= efw
;
142 if (efw
->midi_in_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(efw
, str
);
153 if (efw
->midi_out_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(efw
, str
);
164 if ((efw
->midi_out_ports
> 0) && (efw
->midi_in_ports
> 0))
165 rmidi
->info_flags
|= SNDRV_RAWMIDI_INFO_DUPLEX
;