1 // SPDX-License-Identifier: GPL-2.0-only
3 * tascam-midi.c - a part of driver for TASCAM FireWire series
5 * Copyright (c) 2015 Takashi Sakamoto
10 static int midi_capture_open(struct snd_rawmidi_substream
*substream
)
16 static int midi_playback_open(struct snd_rawmidi_substream
*substream
)
18 struct snd_tscm
*tscm
= substream
->rmidi
->private_data
;
20 snd_fw_async_midi_port_init(&tscm
->out_ports
[substream
->number
]);
25 static int midi_capture_close(struct snd_rawmidi_substream
*substream
)
31 static int midi_playback_close(struct snd_rawmidi_substream
*substream
)
36 static void midi_playback_drain(struct snd_rawmidi_substream
*substream
)
38 struct snd_tscm
*tscm
= substream
->rmidi
->private_data
;
40 snd_fw_async_midi_port_finish(&tscm
->out_ports
[substream
->number
]);
43 static void midi_capture_trigger(struct snd_rawmidi_substream
*substrm
, int up
)
45 struct snd_tscm
*tscm
= substrm
->rmidi
->private_data
;
48 spin_lock_irqsave(&tscm
->lock
, flags
);
51 tscm
->tx_midi_substreams
[substrm
->number
] = substrm
;
53 tscm
->tx_midi_substreams
[substrm
->number
] = NULL
;
55 spin_unlock_irqrestore(&tscm
->lock
, flags
);
58 static void midi_playback_trigger(struct snd_rawmidi_substream
*substrm
, int up
)
60 struct snd_tscm
*tscm
= substrm
->rmidi
->private_data
;
63 spin_lock_irqsave(&tscm
->lock
, flags
);
66 snd_fw_async_midi_port_run(&tscm
->out_ports
[substrm
->number
],
69 spin_unlock_irqrestore(&tscm
->lock
, flags
);
72 int snd_tscm_create_midi_devices(struct snd_tscm
*tscm
)
74 static const struct snd_rawmidi_ops capture_ops
= {
75 .open
= midi_capture_open
,
76 .close
= midi_capture_close
,
77 .trigger
= midi_capture_trigger
,
79 static const struct snd_rawmidi_ops playback_ops
= {
80 .open
= midi_playback_open
,
81 .close
= midi_playback_close
,
82 .drain
= midi_playback_drain
,
83 .trigger
= midi_playback_trigger
,
85 struct snd_rawmidi
*rmidi
;
86 struct snd_rawmidi_str
*stream
;
87 struct snd_rawmidi_substream
*subs
;
90 err
= snd_rawmidi_new(tscm
->card
, tscm
->card
->driver
, 0,
91 tscm
->spec
->midi_playback_ports
,
92 tscm
->spec
->midi_capture_ports
,
97 snprintf(rmidi
->name
, sizeof(rmidi
->name
),
98 "%s MIDI", tscm
->card
->shortname
);
99 rmidi
->private_data
= tscm
;
101 rmidi
->info_flags
|= SNDRV_RAWMIDI_INFO_INPUT
;
102 snd_rawmidi_set_ops(rmidi
, SNDRV_RAWMIDI_STREAM_INPUT
,
104 stream
= &rmidi
->streams
[SNDRV_RAWMIDI_STREAM_INPUT
];
106 /* Set port names for MIDI input. */
107 list_for_each_entry(subs
, &stream
->substreams
, list
) {
108 /* TODO: support virtual MIDI ports. */
109 if (subs
->number
< tscm
->spec
->midi_capture_ports
) {
110 /* Hardware MIDI ports. */
111 snprintf(subs
->name
, sizeof(subs
->name
),
113 tscm
->card
->shortname
, subs
->number
+ 1);
117 rmidi
->info_flags
|= SNDRV_RAWMIDI_INFO_OUTPUT
;
118 snd_rawmidi_set_ops(rmidi
, SNDRV_RAWMIDI_STREAM_OUTPUT
,
120 stream
= &rmidi
->streams
[SNDRV_RAWMIDI_STREAM_OUTPUT
];
122 /* Set port names for MIDI ourput. */
123 list_for_each_entry(subs
, &stream
->substreams
, list
) {
124 if (subs
->number
< tscm
->spec
->midi_playback_ports
) {
125 /* Hardware MIDI ports only. */
126 snprintf(subs
->name
, sizeof(subs
->name
),
128 tscm
->card
->shortname
, subs
->number
+ 1);
132 rmidi
->info_flags
|= SNDRV_RAWMIDI_INFO_DUPLEX
;