diff options
Diffstat (limited to 'sound')
-rw-r--r-- | sound/firewire/dice/Makefile | 4 | ||||
-rw-r--r-- | sound/firewire/dice/dice-midi.c | 157 | ||||
-rw-r--r-- | sound/firewire/dice/dice-stream.c | 2 | ||||
-rw-r--r-- | sound/firewire/dice/dice.c | 4 | ||||
-rw-r--r-- | sound/firewire/dice/dice.h | 3 |
5 files changed, 168 insertions, 2 deletions
diff --git a/sound/firewire/dice/Makefile b/sound/firewire/dice/Makefile index 9a48289eb9cb..9ef228ef7baf 100644 --- a/sound/firewire/dice/Makefile +++ b/sound/firewire/dice/Makefile | |||
@@ -1,3 +1,3 @@ | |||
1 | snd-dice-objs := dice-transaction.o dice-stream.o dice-proc.o dice-pcm.o \ | 1 | snd-dice-objs := dice-transaction.o dice-stream.o dice-proc.o dice-midi.o \ |
2 | dice-hwdep.o dice.o | 2 | dice-pcm.o dice-hwdep.o dice.o |
3 | obj-m += snd-dice.o | 3 | obj-m += snd-dice.o |
diff --git a/sound/firewire/dice/dice-midi.c b/sound/firewire/dice/dice-midi.c new file mode 100644 index 000000000000..fe43ce791f84 --- /dev/null +++ b/sound/firewire/dice/dice-midi.c | |||
@@ -0,0 +1,157 @@ | |||
1 | /* | ||
2 | * dice_midi.c - a part of driver for Dice based devices | ||
3 | * | ||
4 | * Copyright (c) 2014 Takashi Sakamoto | ||
5 | * | ||
6 | * Licensed under the terms of the GNU General Public License, version 2. | ||
7 | */ | ||
8 | #include "dice.h" | ||
9 | |||
10 | static int midi_open(struct snd_rawmidi_substream *substream) | ||
11 | { | ||
12 | struct snd_dice *dice = substream->rmidi->private_data; | ||
13 | int err; | ||
14 | |||
15 | err = snd_dice_stream_lock_try(dice); | ||
16 | if (err < 0) | ||
17 | return err; | ||
18 | |||
19 | mutex_lock(&dice->mutex); | ||
20 | |||
21 | dice->substreams_counter++; | ||
22 | err = snd_dice_stream_start_duplex(dice, 0); | ||
23 | |||
24 | mutex_unlock(&dice->mutex); | ||
25 | |||
26 | if (err < 0) | ||
27 | snd_dice_stream_lock_release(dice); | ||
28 | |||
29 | return err; | ||
30 | } | ||
31 | |||
32 | static int midi_close(struct snd_rawmidi_substream *substream) | ||
33 | { | ||
34 | struct snd_dice *dice = substream->rmidi->private_data; | ||
35 | |||
36 | mutex_lock(&dice->mutex); | ||
37 | |||
38 | dice->substreams_counter--; | ||
39 | snd_dice_stream_stop_duplex(dice); | ||
40 | |||
41 | mutex_unlock(&dice->mutex); | ||
42 | |||
43 | snd_dice_stream_lock_release(dice); | ||
44 | return 0; | ||
45 | } | ||
46 | |||
47 | static void midi_capture_trigger(struct snd_rawmidi_substream *substrm, int up) | ||
48 | { | ||
49 | struct snd_dice *dice = substrm->rmidi->private_data; | ||
50 | unsigned long flags; | ||
51 | |||
52 | spin_lock_irqsave(&dice->lock, flags); | ||
53 | |||
54 | if (up) | ||
55 | amdtp_stream_midi_trigger(&dice->tx_stream, | ||
56 | substrm->number, substrm); | ||
57 | else | ||
58 | amdtp_stream_midi_trigger(&dice->tx_stream, | ||
59 | substrm->number, NULL); | ||
60 | |||
61 | spin_unlock_irqrestore(&dice->lock, flags); | ||
62 | } | ||
63 | |||
64 | static void midi_playback_trigger(struct snd_rawmidi_substream *substrm, int up) | ||
65 | { | ||
66 | struct snd_dice *dice = substrm->rmidi->private_data; | ||
67 | unsigned long flags; | ||
68 | |||
69 | spin_lock_irqsave(&dice->lock, flags); | ||
70 | |||
71 | if (up) | ||
72 | amdtp_stream_midi_trigger(&dice->rx_stream, | ||
73 | substrm->number, substrm); | ||
74 | else | ||
75 | amdtp_stream_midi_trigger(&dice->rx_stream, | ||
76 | substrm->number, NULL); | ||
77 | |||
78 | spin_unlock_irqrestore(&dice->lock, flags); | ||
79 | } | ||
80 | |||
81 | static struct snd_rawmidi_ops capture_ops = { | ||
82 | .open = midi_open, | ||
83 | .close = midi_close, | ||
84 | .trigger = midi_capture_trigger, | ||
85 | }; | ||
86 | |||
87 | static struct snd_rawmidi_ops playback_ops = { | ||
88 | .open = midi_open, | ||
89 | .close = midi_close, | ||
90 | .trigger = midi_playback_trigger, | ||
91 | }; | ||
92 | |||
93 | static void set_midi_substream_names(struct snd_dice *dice, | ||
94 | struct snd_rawmidi_str *str) | ||
95 | { | ||
96 | struct snd_rawmidi_substream *subs; | ||
97 | |||
98 | list_for_each_entry(subs, &str->substreams, list) { | ||
99 | snprintf(subs->name, sizeof(subs->name), | ||
100 | "%s MIDI %d", dice->card->shortname, subs->number + 1); | ||
101 | } | ||
102 | } | ||
103 | |||
104 | int snd_dice_create_midi(struct snd_dice *dice) | ||
105 | { | ||
106 | struct snd_rawmidi *rmidi; | ||
107 | struct snd_rawmidi_str *str; | ||
108 | unsigned int i, midi_in_ports, midi_out_ports; | ||
109 | int err; | ||
110 | |||
111 | midi_in_ports = midi_out_ports = 0; | ||
112 | for (i = 0; i < 3; i++) { | ||
113 | midi_in_ports = max(dice->tx_midi_ports[i], midi_in_ports); | ||
114 | midi_out_ports = max(dice->rx_midi_ports[i], midi_out_ports); | ||
115 | } | ||
116 | |||
117 | if (midi_in_ports + midi_out_ports == 0) | ||
118 | return 0; | ||
119 | |||
120 | /* create midi ports */ | ||
121 | err = snd_rawmidi_new(dice->card, dice->card->driver, 0, | ||
122 | midi_out_ports, midi_in_ports, | ||
123 | &rmidi); | ||
124 | if (err < 0) | ||
125 | return err; | ||
126 | |||
127 | snprintf(rmidi->name, sizeof(rmidi->name), | ||
128 | "%s MIDI", dice->card->shortname); | ||
129 | rmidi->private_data = dice; | ||
130 | |||
131 | if (midi_in_ports > 0) { | ||
132 | rmidi->info_flags |= SNDRV_RAWMIDI_INFO_INPUT; | ||
133 | |||
134 | snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, | ||
135 | &capture_ops); | ||
136 | |||
137 | str = &rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT]; | ||
138 | |||
139 | set_midi_substream_names(dice, str); | ||
140 | } | ||
141 | |||
142 | if (midi_out_ports > 0) { | ||
143 | rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT; | ||
144 | |||
145 | snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, | ||
146 | &playback_ops); | ||
147 | |||
148 | str = &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT]; | ||
149 | |||
150 | set_midi_substream_names(dice, str); | ||
151 | } | ||
152 | |||
153 | if ((midi_out_ports > 0) && (midi_in_ports > 0)) | ||
154 | rmidi->info_flags |= SNDRV_RAWMIDI_INFO_DUPLEX; | ||
155 | |||
156 | return 0; | ||
157 | } | ||
diff --git a/sound/firewire/dice/dice-stream.c b/sound/firewire/dice/dice-stream.c index 20765a05d294..fa9cf761b610 100644 --- a/sound/firewire/dice/dice-stream.c +++ b/sound/firewire/dice/dice-stream.c | |||
@@ -218,6 +218,8 @@ int snd_dice_stream_start_duplex(struct snd_dice *dice, unsigned int rate) | |||
218 | "fail to get sampling rate\n"); | 218 | "fail to get sampling rate\n"); |
219 | goto end; | 219 | goto end; |
220 | } | 220 | } |
221 | if (rate == 0) | ||
222 | rate = curr_rate; | ||
221 | if (rate != curr_rate) | 223 | if (rate != curr_rate) |
222 | stop_stream(dice, master); | 224 | stop_stream(dice, master); |
223 | 225 | ||
diff --git a/sound/firewire/dice/dice.c b/sound/firewire/dice/dice.c index 85bcfaf3ea8a..90d8f40ff727 100644 --- a/sound/firewire/dice/dice.c +++ b/sound/firewire/dice/dice.c | |||
@@ -279,6 +279,10 @@ static int dice_probe(struct fw_unit *unit, const struct ieee1394_device_id *id) | |||
279 | 279 | ||
280 | snd_dice_create_proc(dice); | 280 | snd_dice_create_proc(dice); |
281 | 281 | ||
282 | err = snd_dice_create_midi(dice); | ||
283 | if (err < 0) | ||
284 | goto error; | ||
285 | |||
282 | err = snd_dice_stream_init_duplex(dice); | 286 | err = snd_dice_stream_init_duplex(dice); |
283 | if (err < 0) | 287 | if (err < 0) |
284 | goto error; | 288 | goto error; |
diff --git a/sound/firewire/dice/dice.h b/sound/firewire/dice/dice.h index f30326e22288..ecf5dc862235 100644 --- a/sound/firewire/dice/dice.h +++ b/sound/firewire/dice/dice.h | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <sound/initval.h> | 32 | #include <sound/initval.h> |
33 | #include <sound/pcm.h> | 33 | #include <sound/pcm.h> |
34 | #include <sound/pcm_params.h> | 34 | #include <sound/pcm_params.h> |
35 | #include <sound/rawmidi.h> | ||
35 | 36 | ||
36 | #include "../amdtp.h" | 37 | #include "../amdtp.h" |
37 | #include "../iso-resources.h" | 38 | #include "../iso-resources.h" |
@@ -183,4 +184,6 @@ int snd_dice_create_hwdep(struct snd_dice *dice); | |||
183 | 184 | ||
184 | void snd_dice_create_proc(struct snd_dice *dice); | 185 | void snd_dice_create_proc(struct snd_dice *dice); |
185 | 186 | ||
187 | int snd_dice_create_midi(struct snd_dice *dice); | ||
188 | |||
186 | #endif | 189 | #endif |