2 * digi00x-midi.h - a part of driver for Digidesign Digi 002/003 family
4 * Copyright (c) 2014-2015 Takashi Sakamoto
6 * Licensed under the terms of the GNU General Public License, version 2.
11 static int midi_open(struct snd_rawmidi_substream
*substream
)
13 struct snd_dg00x
*dg00x
= substream
->rmidi
->private_data
;
16 err
= snd_dg00x_stream_lock_try(dg00x
);
20 mutex_lock(&dg00x
->mutex
);
21 dg00x
->substreams_counter
++;
22 err
= snd_dg00x_stream_start_duplex(dg00x
, 0);
23 mutex_unlock(&dg00x
->mutex
);
25 snd_dg00x_stream_lock_release(dg00x
);
30 static int midi_close(struct snd_rawmidi_substream
*substream
)
32 struct snd_dg00x
*dg00x
= substream
->rmidi
->private_data
;
34 mutex_lock(&dg00x
->mutex
);
35 dg00x
->substreams_counter
--;
36 snd_dg00x_stream_stop_duplex(dg00x
);
37 mutex_unlock(&dg00x
->mutex
);
39 snd_dg00x_stream_lock_release(dg00x
);
43 static void midi_capture_trigger(struct snd_rawmidi_substream
*substream
,
46 struct snd_dg00x
*dg00x
= substream
->rmidi
->private_data
;
50 if (substream
->rmidi
->device
== 0)
51 port
= substream
->number
;
55 spin_lock_irqsave(&dg00x
->lock
, flags
);
58 amdtp_dot_midi_trigger(&dg00x
->tx_stream
, port
, substream
);
60 amdtp_dot_midi_trigger(&dg00x
->tx_stream
, port
, NULL
);
62 spin_unlock_irqrestore(&dg00x
->lock
, flags
);
65 static void midi_playback_trigger(struct snd_rawmidi_substream
*substream
,
68 struct snd_dg00x
*dg00x
= substream
->rmidi
->private_data
;
72 if (substream
->rmidi
->device
== 0)
73 port
= substream
->number
;
77 spin_lock_irqsave(&dg00x
->lock
, flags
);
80 amdtp_dot_midi_trigger(&dg00x
->rx_stream
, port
, substream
);
82 amdtp_dot_midi_trigger(&dg00x
->rx_stream
, port
, NULL
);
84 spin_unlock_irqrestore(&dg00x
->lock
, flags
);
87 static void set_substream_names(struct snd_dg00x
*dg00x
,
88 struct snd_rawmidi
*rmidi
, bool is_console
)
90 struct snd_rawmidi_substream
*subs
;
91 struct snd_rawmidi_str
*str
;
94 for (i
= 0; i
< 2; ++i
) {
95 str
= &rmidi
->streams
[i
];
97 list_for_each_entry(subs
, &str
->substreams
, list
) {
99 snprintf(subs
->name
, sizeof(subs
->name
),
101 dg00x
->card
->shortname
,
104 snprintf(subs
->name
, sizeof(subs
->name
),
106 dg00x
->card
->shortname
);
112 static int add_substream_pair(struct snd_dg00x
*dg00x
, unsigned int out_ports
,
113 unsigned int in_ports
, bool is_console
)
115 static const struct snd_rawmidi_ops capture_ops
= {
118 .trigger
= midi_capture_trigger
,
120 static const struct snd_rawmidi_ops playback_ops
= {
123 .trigger
= midi_playback_trigger
,
126 struct snd_rawmidi
*rmidi
;
129 /* Add physical midi ports. */
130 err
= snd_rawmidi_new(dg00x
->card
, dg00x
->card
->driver
, is_console
,
131 out_ports
, in_ports
, &rmidi
);
134 rmidi
->private_data
= dg00x
;
137 label
= "%s control";
140 snprintf(rmidi
->name
, sizeof(rmidi
->name
), label
,
141 dg00x
->card
->shortname
);
143 snd_rawmidi_set_ops(rmidi
, SNDRV_RAWMIDI_STREAM_OUTPUT
, &playback_ops
);
144 snd_rawmidi_set_ops(rmidi
, SNDRV_RAWMIDI_STREAM_INPUT
, &capture_ops
);
146 rmidi
->info_flags
|= SNDRV_RAWMIDI_INFO_INPUT
|
147 SNDRV_RAWMIDI_INFO_OUTPUT
|
148 SNDRV_RAWMIDI_INFO_DUPLEX
;
150 set_substream_names(dg00x
, rmidi
, is_console
);
155 int snd_dg00x_create_midi_devices(struct snd_dg00x
*dg00x
)
159 /* Add physical midi ports. */
160 err
= add_substream_pair(dg00x
, DOT_MIDI_OUT_PORTS
, DOT_MIDI_IN_PORTS
,
165 if (dg00x
->is_console
)
166 err
= add_substream_pair(dg00x
, 1, 1, true);