1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * ff.c - a part of driver for RME Fireface series 4 * 5 * Copyright (c) 2015-2017 Takashi Sakamoto 6 */ 7 8 #include "ff.h" 9 10 #define OUI_RME 0x000a35 11 12 MODULE_DESCRIPTION("RME Fireface series Driver"); 13 MODULE_AUTHOR("Takashi Sakamoto <o-takashi@sakamocchi.jp>"); 14 MODULE_LICENSE("GPL v2"); 15 16 static void name_card(struct snd_ff *ff) 17 { 18 struct fw_device *fw_dev = fw_parent_device(ff->unit); 19 20 strcpy(ff->card->driver, "Fireface"); 21 strcpy(ff->card->shortname, ff->spec->name); 22 strcpy(ff->card->mixername, ff->spec->name); 23 snprintf(ff->card->longname, sizeof(ff->card->longname), 24 "RME %s, GUID %08x%08x at %s, S%d", ff->spec->name, 25 fw_dev->config_rom[3], fw_dev->config_rom[4], 26 dev_name(&ff->unit->device), 100 << fw_dev->max_speed); 27 } 28 29 static void ff_card_free(struct snd_card *card) 30 { 31 struct snd_ff *ff = card->private_data; 32 33 snd_ff_stream_destroy_duplex(ff); 34 snd_ff_transaction_unregister(ff); 35 } 36 37 static void do_registration(struct work_struct *work) 38 { 39 struct snd_ff *ff = container_of(work, struct snd_ff, dwork.work); 40 int err; 41 42 if (ff->registered) 43 return; 44 45 err = snd_card_new(&ff->unit->device, -1, NULL, THIS_MODULE, 0, 46 &ff->card); 47 if (err < 0) 48 return; 49 ff->card->private_free = ff_card_free; 50 ff->card->private_data = ff; 51 52 err = snd_ff_transaction_register(ff); 53 if (err < 0) 54 goto error; 55 56 name_card(ff); 57 58 err = snd_ff_stream_init_duplex(ff); 59 if (err < 0) 60 goto error; 61 62 snd_ff_proc_init(ff); 63 64 err = snd_ff_create_midi_devices(ff); 65 if (err < 0) 66 goto error; 67 68 err = snd_ff_create_pcm_devices(ff); 69 if (err < 0) 70 goto error; 71 72 err = snd_ff_create_hwdep_devices(ff); 73 if (err < 0) 74 goto error; 75 76 err = snd_card_register(ff->card); 77 if (err < 0) 78 goto error; 79 80 ff->registered = true; 81 82 return; 83 error: 84 snd_card_free(ff->card); 85 dev_info(&ff->unit->device, 86 "Sound card registration failed: %d\n", err); 87 } 88 89 static int snd_ff_probe(struct fw_unit *unit, 90 const struct ieee1394_device_id *entry) 91 { 92 struct snd_ff *ff; 93 94 ff = devm_kzalloc(&unit->device, sizeof(struct snd_ff), GFP_KERNEL); 95 if (!ff) 96 return -ENOMEM; 97 ff->unit = fw_unit_get(unit); 98 dev_set_drvdata(&unit->device, ff); 99 100 mutex_init(&ff->mutex); 101 spin_lock_init(&ff->lock); 102 init_waitqueue_head(&ff->hwdep_wait); 103 104 ff->spec = (const struct snd_ff_spec *)entry->driver_data; 105 106 /* Register this sound card later. */ 107 INIT_DEFERRABLE_WORK(&ff->dwork, do_registration); 108 snd_fw_schedule_registration(unit, &ff->dwork); 109 110 return 0; 111 } 112 113 static void snd_ff_update(struct fw_unit *unit) 114 { 115 struct snd_ff *ff = dev_get_drvdata(&unit->device); 116 117 /* Postpone a workqueue for deferred registration. */ 118 if (!ff->registered) 119 snd_fw_schedule_registration(unit, &ff->dwork); 120 121 snd_ff_transaction_reregister(ff); 122 123 if (ff->registered) 124 snd_ff_stream_update_duplex(ff); 125 } 126 127 static void snd_ff_remove(struct fw_unit *unit) 128 { 129 struct snd_ff *ff = dev_get_drvdata(&unit->device); 130 131 /* 132 * Confirm to stop the work for registration before the sound card is 133 * going to be released. The work is not scheduled again because bus 134 * reset handler is not called anymore. 135 */ 136 cancel_work_sync(&ff->dwork.work); 137 138 if (ff->registered) { 139 // Block till all of ALSA character devices are released. 140 snd_card_free(ff->card); 141 } 142 143 mutex_destroy(&ff->mutex); 144 fw_unit_put(ff->unit); 145 } 146 147 static const struct snd_ff_spec spec_ff800 = { 148 .name = "Fireface800", 149 .pcm_capture_channels = {28, 20, 12}, 150 .pcm_playback_channels = {28, 20, 12}, 151 .midi_in_ports = 1, 152 .midi_out_ports = 1, 153 .protocol = &snd_ff_protocol_ff800, 154 .midi_high_addr = 0x000200000320ull, 155 .midi_addr_range = 12, 156 .midi_rx_addrs = {0x000080180000ull, 0}, 157 }; 158 159 static const struct snd_ff_spec spec_ff400 = { 160 .name = "Fireface400", 161 .pcm_capture_channels = {18, 14, 10}, 162 .pcm_playback_channels = {18, 14, 10}, 163 .midi_in_ports = 2, 164 .midi_out_ports = 2, 165 .protocol = &snd_ff_protocol_ff400, 166 .midi_high_addr = 0x0000801003f4ull, 167 .midi_addr_range = SND_FF_MAXIMIM_MIDI_QUADS * 4, 168 .midi_rx_addrs = {0x000080180000ull, 0x000080190000ull}, 169 }; 170 171 static const struct snd_ff_spec spec_ucx = { 172 .name = "FirefaceUCX", 173 .pcm_capture_channels = {18, 14, 12}, 174 .pcm_playback_channels = {18, 14, 12}, 175 .midi_in_ports = 2, 176 .midi_out_ports = 2, 177 .protocol = &snd_ff_protocol_latter, 178 .midi_high_addr = 0xffff00000034ull, 179 .midi_addr_range = 0x80, 180 .midi_rx_addrs = {0xffff00000030ull, 0xffff00000030ull}, 181 }; 182 183 static const struct ieee1394_device_id snd_ff_id_table[] = { 184 /* Fireface 800 */ 185 { 186 .match_flags = IEEE1394_MATCH_VENDOR_ID | 187 IEEE1394_MATCH_SPECIFIER_ID | 188 IEEE1394_MATCH_VERSION | 189 IEEE1394_MATCH_MODEL_ID, 190 .vendor_id = OUI_RME, 191 .specifier_id = OUI_RME, 192 .version = 0x000001, 193 .model_id = 0x101800, 194 .driver_data = (kernel_ulong_t)&spec_ff800, 195 }, 196 /* Fireface 400 */ 197 { 198 .match_flags = IEEE1394_MATCH_VENDOR_ID | 199 IEEE1394_MATCH_SPECIFIER_ID | 200 IEEE1394_MATCH_VERSION | 201 IEEE1394_MATCH_MODEL_ID, 202 .vendor_id = OUI_RME, 203 .specifier_id = OUI_RME, 204 .version = 0x000002, 205 .model_id = 0x101800, 206 .driver_data = (kernel_ulong_t)&spec_ff400, 207 }, 208 // Fireface UCX. 209 { 210 .match_flags = IEEE1394_MATCH_VENDOR_ID | 211 IEEE1394_MATCH_SPECIFIER_ID | 212 IEEE1394_MATCH_VERSION | 213 IEEE1394_MATCH_MODEL_ID, 214 .vendor_id = OUI_RME, 215 .specifier_id = OUI_RME, 216 .version = 0x000004, 217 .model_id = 0x101800, 218 .driver_data = (kernel_ulong_t)&spec_ucx, 219 }, 220 {} 221 }; 222 MODULE_DEVICE_TABLE(ieee1394, snd_ff_id_table); 223 224 static struct fw_driver ff_driver = { 225 .driver = { 226 .owner = THIS_MODULE, 227 .name = "snd-fireface", 228 .bus = &fw_bus_type, 229 }, 230 .probe = snd_ff_probe, 231 .update = snd_ff_update, 232 .remove = snd_ff_remove, 233 .id_table = snd_ff_id_table, 234 }; 235 236 static int __init snd_ff_init(void) 237 { 238 return driver_register(&ff_driver.driver); 239 } 240 241 static void __exit snd_ff_exit(void) 242 { 243 driver_unregister(&ff_driver.driver); 244 } 245 246 module_init(snd_ff_init); 247 module_exit(snd_ff_exit); 248