hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/sound/firewire/fireface/ff.c
....@@ -1,9 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * ff.c - a part of driver for RME Fireface series
34 *
45 * Copyright (c) 2015-2017 Takashi Sakamoto
5
- *
6
- * Licensed under the terms of the GNU General Public License, version 2.
76 */
87
98 #include "ff.h"
....@@ -17,30 +16,32 @@
1716 static void name_card(struct snd_ff *ff)
1817 {
1918 struct fw_device *fw_dev = fw_parent_device(ff->unit);
19
+ const char *const names[] = {
20
+ [SND_FF_UNIT_VERSION_FF800] = "Fireface800",
21
+ [SND_FF_UNIT_VERSION_FF400] = "Fireface400",
22
+ [SND_FF_UNIT_VERSION_UFX] = "FirefaceUFX",
23
+ [SND_FF_UNIT_VERSION_UCX] = "FirefaceUCX",
24
+ [SND_FF_UNIT_VERSION_802] = "Fireface802",
25
+ };
26
+ const char *name;
27
+
28
+ name = names[ff->unit_version];
2029
2130 strcpy(ff->card->driver, "Fireface");
22
- strcpy(ff->card->shortname, ff->spec->name);
23
- strcpy(ff->card->mixername, ff->spec->name);
31
+ strcpy(ff->card->shortname, name);
32
+ strcpy(ff->card->mixername, name);
2433 snprintf(ff->card->longname, sizeof(ff->card->longname),
25
- "RME %s, GUID %08x%08x at %s, S%d", ff->spec->name,
34
+ "RME %s, GUID %08x%08x at %s, S%d", name,
2635 fw_dev->config_rom[3], fw_dev->config_rom[4],
2736 dev_name(&ff->unit->device), 100 << fw_dev->max_speed);
2837 }
2938
30
-static void ff_free(struct snd_ff *ff)
31
-{
32
- snd_ff_stream_destroy_duplex(ff);
33
- snd_ff_transaction_unregister(ff);
34
-
35
- fw_unit_put(ff->unit);
36
-
37
- mutex_destroy(&ff->mutex);
38
- kfree(ff);
39
-}
40
-
4139 static void ff_card_free(struct snd_card *card)
4240 {
43
- ff_free(card->private_data);
41
+ struct snd_ff *ff = card->private_data;
42
+
43
+ snd_ff_stream_destroy_duplex(ff);
44
+ snd_ff_transaction_unregister(ff);
4445 }
4546
4647 static void do_registration(struct work_struct *work)
....@@ -55,6 +56,8 @@
5556 &ff->card);
5657 if (err < 0)
5758 return;
59
+ ff->card->private_free = ff_card_free;
60
+ ff->card->private_data = ff;
5861
5962 err = snd_ff_transaction_register(ff);
6063 if (err < 0)
....@@ -84,14 +87,10 @@
8487 if (err < 0)
8588 goto error;
8689
87
- ff->card->private_free = ff_card_free;
88
- ff->card->private_data = ff;
8990 ff->registered = true;
9091
9192 return;
9293 error:
93
- snd_ff_transaction_unregister(ff);
94
- snd_ff_stream_destroy_duplex(ff);
9594 snd_card_free(ff->card);
9695 dev_info(&ff->unit->device,
9796 "Sound card registration failed: %d\n", err);
....@@ -102,11 +101,9 @@
102101 {
103102 struct snd_ff *ff;
104103
105
- ff = kzalloc(sizeof(struct snd_ff), GFP_KERNEL);
106
- if (ff == NULL)
104
+ ff = devm_kzalloc(&unit->device, sizeof(struct snd_ff), GFP_KERNEL);
105
+ if (!ff)
107106 return -ENOMEM;
108
-
109
- /* initialize myself */
110107 ff->unit = fw_unit_get(unit);
111108 dev_set_drvdata(&unit->device, ff);
112109
....@@ -114,6 +111,7 @@
114111 spin_lock_init(&ff->lock);
115112 init_waitqueue_head(&ff->hwdep_wait);
116113
114
+ ff->unit_version = entry->version;
117115 ff->spec = (const struct snd_ff_spec *)entry->driver_data;
118116
119117 /* Register this sound card later. */
....@@ -149,24 +147,71 @@
149147 cancel_work_sync(&ff->dwork.work);
150148
151149 if (ff->registered) {
152
- /* No need to wait for releasing card object in this context. */
153
- snd_card_free_when_closed(ff->card);
154
- } else {
155
- /* Don't forget this case. */
156
- ff_free(ff);
150
+ // Block till all of ALSA character devices are released.
151
+ snd_card_free(ff->card);
157152 }
153
+
154
+ mutex_destroy(&ff->mutex);
155
+ fw_unit_put(ff->unit);
158156 }
159157
158
+static const struct snd_ff_spec spec_ff800 = {
159
+ .pcm_capture_channels = {28, 20, 12},
160
+ .pcm_playback_channels = {28, 20, 12},
161
+ .midi_in_ports = 1,
162
+ .midi_out_ports = 1,
163
+ .protocol = &snd_ff_protocol_ff800,
164
+ .midi_high_addr = 0x000200000320ull,
165
+ .midi_addr_range = 12,
166
+ .midi_rx_addrs = {0x000080180000ull, 0},
167
+};
168
+
160169 static const struct snd_ff_spec spec_ff400 = {
161
- .name = "Fireface400",
162170 .pcm_capture_channels = {18, 14, 10},
163171 .pcm_playback_channels = {18, 14, 10},
164172 .midi_in_ports = 2,
165173 .midi_out_ports = 2,
166174 .protocol = &snd_ff_protocol_ff400,
175
+ .midi_high_addr = 0x0000801003f4ull,
176
+ .midi_addr_range = SND_FF_MAXIMIM_MIDI_QUADS * 4,
177
+ .midi_rx_addrs = {0x000080180000ull, 0x000080190000ull},
178
+};
179
+
180
+static const struct snd_ff_spec spec_ucx = {
181
+ .pcm_capture_channels = {18, 14, 12},
182
+ .pcm_playback_channels = {18, 14, 12},
183
+ .midi_in_ports = 2,
184
+ .midi_out_ports = 2,
185
+ .protocol = &snd_ff_protocol_latter,
186
+ .midi_high_addr = 0xffff00000034ull,
187
+ .midi_addr_range = 0x80,
188
+ .midi_rx_addrs = {0xffff00000030ull, 0xffff00000030ull},
189
+};
190
+
191
+static const struct snd_ff_spec spec_ufx_802 = {
192
+ .pcm_capture_channels = {30, 22, 14},
193
+ .pcm_playback_channels = {30, 22, 14},
194
+ .midi_in_ports = 1,
195
+ .midi_out_ports = 1,
196
+ .protocol = &snd_ff_protocol_latter,
197
+ .midi_high_addr = 0xffff00000034ull,
198
+ .midi_addr_range = 0x80,
199
+ .midi_rx_addrs = {0xffff00000030ull, 0xffff00000030ull},
167200 };
168201
169202 static const struct ieee1394_device_id snd_ff_id_table[] = {
203
+ /* Fireface 800 */
204
+ {
205
+ .match_flags = IEEE1394_MATCH_VENDOR_ID |
206
+ IEEE1394_MATCH_SPECIFIER_ID |
207
+ IEEE1394_MATCH_VERSION |
208
+ IEEE1394_MATCH_MODEL_ID,
209
+ .vendor_id = OUI_RME,
210
+ .specifier_id = OUI_RME,
211
+ .version = SND_FF_UNIT_VERSION_FF800,
212
+ .model_id = 0x101800,
213
+ .driver_data = (kernel_ulong_t)&spec_ff800,
214
+ },
170215 /* Fireface 400 */
171216 {
172217 .match_flags = IEEE1394_MATCH_VENDOR_ID |
....@@ -174,10 +219,46 @@
174219 IEEE1394_MATCH_VERSION |
175220 IEEE1394_MATCH_MODEL_ID,
176221 .vendor_id = OUI_RME,
177
- .specifier_id = 0x000a35,
178
- .version = 0x000002,
222
+ .specifier_id = OUI_RME,
223
+ .version = SND_FF_UNIT_VERSION_FF400,
179224 .model_id = 0x101800,
180225 .driver_data = (kernel_ulong_t)&spec_ff400,
226
+ },
227
+ // Fireface UFX.
228
+ {
229
+ .match_flags = IEEE1394_MATCH_VENDOR_ID |
230
+ IEEE1394_MATCH_SPECIFIER_ID |
231
+ IEEE1394_MATCH_VERSION |
232
+ IEEE1394_MATCH_MODEL_ID,
233
+ .vendor_id = OUI_RME,
234
+ .specifier_id = OUI_RME,
235
+ .version = SND_FF_UNIT_VERSION_UFX,
236
+ .model_id = 0x101800,
237
+ .driver_data = (kernel_ulong_t)&spec_ufx_802,
238
+ },
239
+ // Fireface UCX.
240
+ {
241
+ .match_flags = IEEE1394_MATCH_VENDOR_ID |
242
+ IEEE1394_MATCH_SPECIFIER_ID |
243
+ IEEE1394_MATCH_VERSION |
244
+ IEEE1394_MATCH_MODEL_ID,
245
+ .vendor_id = OUI_RME,
246
+ .specifier_id = OUI_RME,
247
+ .version = SND_FF_UNIT_VERSION_UCX,
248
+ .model_id = 0x101800,
249
+ .driver_data = (kernel_ulong_t)&spec_ucx,
250
+ },
251
+ // Fireface 802.
252
+ {
253
+ .match_flags = IEEE1394_MATCH_VENDOR_ID |
254
+ IEEE1394_MATCH_SPECIFIER_ID |
255
+ IEEE1394_MATCH_VERSION |
256
+ IEEE1394_MATCH_MODEL_ID,
257
+ .vendor_id = OUI_RME,
258
+ .specifier_id = OUI_RME,
259
+ .version = SND_FF_UNIT_VERSION_802,
260
+ .model_id = 0x101800,
261
+ .driver_data = (kernel_ulong_t)&spec_ufx_802,
181262 },
182263 {}
183264 };
....@@ -186,7 +267,7 @@
186267 static struct fw_driver ff_driver = {
187268 .driver = {
188269 .owner = THIS_MODULE,
189
- .name = "snd-fireface",
270
+ .name = KBUILD_MODNAME,
190271 .bus = &fw_bus_type,
191272 },
192273 .probe = snd_ff_probe,