ALSA: cs4281: remove redundant assignment to variable val and remove a goto
[linux-2.6-block.git] / sound / firewire / bebob / bebob_midi.c
CommitLineData
248b7802
TS
1/*
2 * bebob_midi.c - a part of driver for BeBoB based devices
3 *
4 * Copyright (c) 2013-2014 Takashi Sakamoto
5 *
6 * Licensed under the terms of the GNU General Public License, version 2.
7 */
8
9#include "bebob.h"
10
73f7864e 11static int midi_open(struct snd_rawmidi_substream *substream)
248b7802
TS
12{
13 struct snd_bebob *bebob = substream->rmidi->private_data;
618eabea
TS
14 int err;
15
16 err = snd_bebob_stream_lock_try(bebob);
17 if (err < 0)
ac2888b9 18 return err;
248b7802 19
2a71e701 20 mutex_lock(&bebob->mutex);
ac2888b9
TS
21 err = snd_bebob_stream_reserve_duplex(bebob, 0);
22 if (err >= 0) {
23 ++bebob->substreams_counter;
24 err = snd_bebob_stream_start_duplex(bebob);
25 }
2a71e701 26 mutex_unlock(&bebob->mutex);
618eabea
TS
27 if (err < 0)
28 snd_bebob_stream_lock_release(bebob);
ac2888b9 29
618eabea 30 return err;
248b7802
TS
31}
32
73f7864e 33static int midi_close(struct snd_rawmidi_substream *substream)
248b7802
TS
34{
35 struct snd_bebob *bebob = substream->rmidi->private_data;
36
2a71e701 37 mutex_lock(&bebob->mutex);
4fd6c6c7 38 bebob->substreams_counter--;
248b7802 39 snd_bebob_stream_stop_duplex(bebob);
2a71e701 40 mutex_unlock(&bebob->mutex);
248b7802 41
618eabea 42 snd_bebob_stream_lock_release(bebob);
248b7802
TS
43 return 0;
44}
45
46static void midi_capture_trigger(struct snd_rawmidi_substream *substrm, int up)
47{
48 struct snd_bebob *bebob = substrm->rmidi->private_data;
49 unsigned long flags;
50
51 spin_lock_irqsave(&bebob->lock, flags);
52
53 if (up)
03e2a67e
TS
54 amdtp_am824_midi_trigger(&bebob->tx_stream,
55 substrm->number, substrm);
248b7802 56 else
03e2a67e
TS
57 amdtp_am824_midi_trigger(&bebob->tx_stream,
58 substrm->number, NULL);
248b7802
TS
59
60 spin_unlock_irqrestore(&bebob->lock, flags);
61}
62
63static void midi_playback_trigger(struct snd_rawmidi_substream *substrm, int up)
64{
65 struct snd_bebob *bebob = substrm->rmidi->private_data;
66 unsigned long flags;
67
68 spin_lock_irqsave(&bebob->lock, flags);
69
70 if (up)
03e2a67e
TS
71 amdtp_am824_midi_trigger(&bebob->rx_stream,
72 substrm->number, substrm);
248b7802 73 else
03e2a67e
TS
74 amdtp_am824_midi_trigger(&bebob->rx_stream,
75 substrm->number, NULL);
248b7802
TS
76
77 spin_unlock_irqrestore(&bebob->lock, flags);
78}
79
248b7802
TS
80static void set_midi_substream_names(struct snd_bebob *bebob,
81 struct snd_rawmidi_str *str)
82{
83 struct snd_rawmidi_substream *subs;
84
85 list_for_each_entry(subs, &str->substreams, list) {
86 snprintf(subs->name, sizeof(subs->name),
87 "%s MIDI %d",
88 bebob->card->shortname, subs->number + 1);
89 }
90}
91
92int snd_bebob_create_midi_devices(struct snd_bebob *bebob)
93{
57eb6799 94 static const struct snd_rawmidi_ops capture_ops = {
73f7864e
TS
95 .open = midi_open,
96 .close = midi_close,
4780f774
TS
97 .trigger = midi_capture_trigger,
98 };
57eb6799 99 static const struct snd_rawmidi_ops playback_ops = {
73f7864e
TS
100 .open = midi_open,
101 .close = midi_close,
4780f774
TS
102 .trigger = midi_playback_trigger,
103 };
248b7802
TS
104 struct snd_rawmidi *rmidi;
105 struct snd_rawmidi_str *str;
106 int err;
107
108 /* create midi ports */
109 err = snd_rawmidi_new(bebob->card, bebob->card->driver, 0,
110 bebob->midi_output_ports, bebob->midi_input_ports,
111 &rmidi);
112 if (err < 0)
113 return err;
114
115 snprintf(rmidi->name, sizeof(rmidi->name),
116 "%s MIDI", bebob->card->shortname);
117 rmidi->private_data = bebob;
118
119 if (bebob->midi_input_ports > 0) {
120 rmidi->info_flags |= SNDRV_RAWMIDI_INFO_INPUT;
121
122 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT,
4780f774 123 &capture_ops);
248b7802
TS
124
125 str = &rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT];
126
127 set_midi_substream_names(bebob, str);
128 }
129
130 if (bebob->midi_output_ports > 0) {
131 rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT;
132
133 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,
4780f774 134 &playback_ops);
248b7802
TS
135
136 str = &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT];
137
138 set_midi_substream_names(bebob, str);
139 }
140
141 if ((bebob->midi_output_ports > 0) && (bebob->midi_input_ports > 0))
142 rmidi->info_flags |= SNDRV_RAWMIDI_INFO_DUPLEX;
143
144 return 0;
145}