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