2 * tascam-midi.c - a part of driver for TASCAM FireWire series
4 * Copyright (c) 2015 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
)
17 static int midi_playback_open(struct snd_rawmidi_substream
*substream
)
19 struct snd_tscm
*tscm
= substream
->rmidi
->private_data
;
21 snd_fw_async_midi_port_init(&tscm
->out_ports
[substream
->number
]);
26 static int midi_capture_close(struct snd_rawmidi_substream
*substream
)
32 static int midi_playback_close(struct snd_rawmidi_substream
*substream
)
37 static void midi_playback_drain(struct snd_rawmidi_substream
*substream
)
39 struct snd_tscm
*tscm
= substream
->rmidi
->private_data
;
41 snd_fw_async_midi_port_finish(&tscm
->out_ports
[substream
->number
]);
44 static void midi_capture_trigger(struct snd_rawmidi_substream
*substrm
, int up
)
46 struct snd_tscm
*tscm
= substrm
->rmidi
->private_data
;
49 spin_lock_irqsave(&tscm
->lock
, flags
);
52 tscm
->tx_midi_substreams
[substrm
->number
] = substrm
;
54 tscm
->tx_midi_substreams
[substrm
->number
] = NULL
;
56 spin_unlock_irqrestore(&tscm
->lock
, flags
);
59 static void midi_playback_trigger(struct snd_rawmidi_substream
*substrm
, int up
)
61 struct snd_tscm
*tscm
= substrm
->rmidi
->private_data
;
64 spin_lock_irqsave(&tscm
->lock
, flags
);
67 snd_fw_async_midi_port_run(&tscm
->out_ports
[substrm
->number
],
70 spin_unlock_irqrestore(&tscm
->lock
, flags
);
73 int snd_tscm_create_midi_devices(struct snd_tscm
*tscm
)
75 static const struct snd_rawmidi_ops capture_ops
= {
76 .open
= midi_capture_open
,
77 .close
= midi_capture_close
,
78 .trigger
= midi_capture_trigger
,
80 static const struct snd_rawmidi_ops playback_ops
= {
81 .open
= midi_playback_open
,
82 .close
= midi_playback_close
,
83 .drain
= midi_playback_drain
,
84 .trigger
= midi_playback_trigger
,
86 struct snd_rawmidi
*rmidi
;
87 struct snd_rawmidi_str
*stream
;
88 struct snd_rawmidi_substream
*subs
;
91 err
= snd_rawmidi_new(tscm
->card
, tscm
->card
->driver
, 0,
92 tscm
->spec
->midi_playback_ports
,
93 tscm
->spec
->midi_capture_ports
,
98 snprintf(rmidi
->name
, sizeof(rmidi
->name
),
99 "%s MIDI", tscm
->card
->shortname
);
100 rmidi
->private_data
= tscm
;
102 rmidi
->info_flags
|= SNDRV_RAWMIDI_INFO_INPUT
;
103 snd_rawmidi_set_ops(rmidi
, SNDRV_RAWMIDI_STREAM_INPUT
,
105 stream
= &rmidi
->streams
[SNDRV_RAWMIDI_STREAM_INPUT
];
107 /* Set port names for MIDI input. */
108 list_for_each_entry(subs
, &stream
->substreams
, list
) {
109 /* TODO: support virtual MIDI ports. */
110 if (subs
->number
< tscm
->spec
->midi_capture_ports
) {
111 /* Hardware MIDI ports. */
112 snprintf(subs
->name
, sizeof(subs
->name
),
114 tscm
->card
->shortname
, subs
->number
+ 1);
118 rmidi
->info_flags
|= SNDRV_RAWMIDI_INFO_OUTPUT
;
119 snd_rawmidi_set_ops(rmidi
, SNDRV_RAWMIDI_STREAM_OUTPUT
,
121 stream
= &rmidi
->streams
[SNDRV_RAWMIDI_STREAM_OUTPUT
];
123 /* Set port names for MIDI ourput. */
124 list_for_each_entry(subs
, &stream
->substreams
, list
) {
125 if (subs
->number
< tscm
->spec
->midi_playback_ports
) {
126 /* Hardware MIDI ports only. */
127 snprintf(subs
->name
, sizeof(subs
->name
),
129 tscm
->card
->shortname
, subs
->number
+ 1);
133 rmidi
->info_flags
|= SNDRV_RAWMIDI_INFO_DUPLEX
;