1 /* 2 * motu.c - a part of driver for MOTU FireWire series 3 * 4 * Copyright (c) 2015-2017 Takashi Sakamoto <o-takashi@sakamocchi.jp> 5 * 6 * Licensed under the terms of the GNU General Public License, version 2. 7 */ 8 9 #include "motu.h" 10 11 #define OUI_MOTU 0x0001f2 12 13 MODULE_DESCRIPTION("MOTU FireWire driver"); 14 MODULE_AUTHOR("Takashi Sakamoto <o-takashi@sakamocchi.jp>"); 15 MODULE_LICENSE("GPL v2"); 16 17 const unsigned int snd_motu_clock_rates[SND_MOTU_CLOCK_RATE_COUNT] = { 18 /* mode 0 */ 19 [0] = 44100, 20 [1] = 48000, 21 /* mode 1 */ 22 [2] = 88200, 23 [3] = 96000, 24 /* mode 2 */ 25 [4] = 176400, 26 [5] = 192000, 27 }; 28 29 static void name_card(struct snd_motu *motu) 30 { 31 struct fw_device *fw_dev = fw_parent_device(motu->unit); 32 struct fw_csr_iterator it; 33 int key, val; 34 u32 version = 0; 35 36 fw_csr_iterator_init(&it, motu->unit->directory); 37 while (fw_csr_iterator_next(&it, &key, &val)) { 38 switch (key) { 39 case CSR_MODEL: 40 version = val; 41 break; 42 } 43 } 44 45 strcpy(motu->card->driver, "FW-MOTU"); 46 strcpy(motu->card->shortname, motu->spec->name); 47 strcpy(motu->card->mixername, motu->spec->name); 48 snprintf(motu->card->longname, sizeof(motu->card->longname), 49 "MOTU %s (version:%06x), GUID %08x%08x at %s, S%d", 50 motu->spec->name, version, 51 fw_dev->config_rom[3], fw_dev->config_rom[4], 52 dev_name(&motu->unit->device), 100 << fw_dev->max_speed); 53 } 54 55 static void motu_card_free(struct snd_card *card) 56 { 57 struct snd_motu *motu = card->private_data; 58 59 snd_motu_transaction_unregister(motu); 60 snd_motu_stream_destroy_duplex(motu); 61 } 62 63 static void do_registration(struct work_struct *work) 64 { 65 struct snd_motu *motu = container_of(work, struct snd_motu, dwork.work); 66 int err; 67 68 if (motu->registered) 69 return; 70 71 err = snd_card_new(&motu->unit->device, -1, NULL, THIS_MODULE, 0, 72 &motu->card); 73 if (err < 0) 74 return; 75 motu->card->private_free = motu_card_free; 76 motu->card->private_data = motu; 77 78 name_card(motu); 79 80 err = snd_motu_transaction_register(motu); 81 if (err < 0) 82 goto error; 83 84 err = snd_motu_stream_init_duplex(motu); 85 if (err < 0) 86 goto error; 87 88 snd_motu_proc_init(motu); 89 90 err = snd_motu_create_pcm_devices(motu); 91 if (err < 0) 92 goto error; 93 94 if ((motu->spec->flags & SND_MOTU_SPEC_RX_MIDI_2ND_Q) || 95 (motu->spec->flags & SND_MOTU_SPEC_RX_MIDI_3RD_Q) || 96 (motu->spec->flags & SND_MOTU_SPEC_TX_MIDI_2ND_Q) || 97 (motu->spec->flags & SND_MOTU_SPEC_TX_MIDI_3RD_Q)) { 98 err = snd_motu_create_midi_devices(motu); 99 if (err < 0) 100 goto error; 101 } 102 103 err = snd_motu_create_hwdep_device(motu); 104 if (err < 0) 105 goto error; 106 107 err = snd_card_register(motu->card); 108 if (err < 0) 109 goto error; 110 111 motu->registered = true; 112 113 return; 114 error: 115 snd_card_free(motu->card); 116 dev_info(&motu->unit->device, 117 "Sound card registration failed: %d\n", err); 118 } 119 120 static int motu_probe(struct fw_unit *unit, 121 const struct ieee1394_device_id *entry) 122 { 123 struct snd_motu *motu; 124 125 /* Allocate this independently of sound card instance. */ 126 motu = devm_kzalloc(&unit->device, sizeof(struct snd_motu), GFP_KERNEL); 127 if (!motu) 128 return -ENOMEM; 129 motu->unit = fw_unit_get(unit); 130 dev_set_drvdata(&unit->device, motu); 131 132 motu->spec = (const struct snd_motu_spec *)entry->driver_data; 133 mutex_init(&motu->mutex); 134 spin_lock_init(&motu->lock); 135 init_waitqueue_head(&motu->hwdep_wait); 136 137 /* Allocate and register this sound card later. */ 138 INIT_DEFERRABLE_WORK(&motu->dwork, do_registration); 139 snd_fw_schedule_registration(unit, &motu->dwork); 140 141 return 0; 142 } 143 144 static void motu_remove(struct fw_unit *unit) 145 { 146 struct snd_motu *motu = dev_get_drvdata(&unit->device); 147 148 /* 149 * Confirm to stop the work for registration before the sound card is 150 * going to be released. The work is not scheduled again because bus 151 * reset handler is not called anymore. 152 */ 153 cancel_delayed_work_sync(&motu->dwork); 154 155 if (motu->registered) { 156 // Block till all of ALSA character devices are released. 157 snd_card_free(motu->card); 158 } 159 160 mutex_destroy(&motu->mutex); 161 fw_unit_put(motu->unit); 162 } 163 164 static void motu_bus_update(struct fw_unit *unit) 165 { 166 struct snd_motu *motu = dev_get_drvdata(&unit->device); 167 168 /* Postpone a workqueue for deferred registration. */ 169 if (!motu->registered) 170 snd_fw_schedule_registration(unit, &motu->dwork); 171 172 /* The handler address register becomes initialized. */ 173 snd_motu_transaction_reregister(motu); 174 } 175 176 static const struct snd_motu_spec motu_828mk2 = { 177 .name = "828mk2", 178 .protocol = &snd_motu_protocol_v2, 179 .flags = SND_MOTU_SPEC_SUPPORT_CLOCK_X2 | 180 SND_MOTU_SPEC_TX_MICINST_CHUNK | 181 SND_MOTU_SPEC_TX_RETURN_CHUNK | 182 SND_MOTU_SPEC_RX_SEPARETED_MAIN | 183 SND_MOTU_SPEC_HAS_OPT_IFACE_A | 184 SND_MOTU_SPEC_RX_MIDI_2ND_Q | 185 SND_MOTU_SPEC_TX_MIDI_2ND_Q, 186 187 .analog_in_ports = 8, 188 .analog_out_ports = 8, 189 }; 190 191 const struct snd_motu_spec snd_motu_spec_traveler = { 192 .name = "Traveler", 193 .protocol = &snd_motu_protocol_v2, 194 .flags = SND_MOTU_SPEC_SUPPORT_CLOCK_X2 | 195 SND_MOTU_SPEC_SUPPORT_CLOCK_X4 | 196 SND_MOTU_SPEC_TX_RETURN_CHUNK | 197 SND_MOTU_SPEC_HAS_AESEBU_IFACE | 198 SND_MOTU_SPEC_HAS_OPT_IFACE_A | 199 SND_MOTU_SPEC_RX_MIDI_2ND_Q | 200 SND_MOTU_SPEC_TX_MIDI_2ND_Q, 201 202 .analog_in_ports = 8, 203 .analog_out_ports = 8, 204 }; 205 206 const struct snd_motu_spec snd_motu_spec_8pre = { 207 .name = "8pre", 208 .protocol = &snd_motu_protocol_v2, 209 // In tx, use coax chunks for mix-return 1/2. In rx, use coax chunks for 210 // dummy 1/2. 211 .flags = SND_MOTU_SPEC_SUPPORT_CLOCK_X2 | 212 SND_MOTU_SPEC_HAS_OPT_IFACE_A | 213 SND_MOTU_SPEC_HAS_OPT_IFACE_B | 214 SND_MOTU_SPEC_RX_MIDI_2ND_Q | 215 SND_MOTU_SPEC_TX_MIDI_2ND_Q, 216 .analog_in_ports = 8, 217 .analog_out_ports = 2, 218 }; 219 220 static const struct snd_motu_spec motu_828mk3 = { 221 .name = "828mk3", 222 .protocol = &snd_motu_protocol_v3, 223 .flags = SND_MOTU_SPEC_SUPPORT_CLOCK_X2 | 224 SND_MOTU_SPEC_SUPPORT_CLOCK_X4 | 225 SND_MOTU_SPEC_TX_MICINST_CHUNK | 226 SND_MOTU_SPEC_TX_RETURN_CHUNK | 227 SND_MOTU_SPEC_TX_REVERB_CHUNK | 228 SND_MOTU_SPEC_RX_SEPARETED_MAIN | 229 SND_MOTU_SPEC_HAS_OPT_IFACE_A | 230 SND_MOTU_SPEC_HAS_OPT_IFACE_B | 231 SND_MOTU_SPEC_RX_MIDI_3RD_Q | 232 SND_MOTU_SPEC_TX_MIDI_3RD_Q, 233 234 .analog_in_ports = 8, 235 .analog_out_ports = 8, 236 }; 237 238 static const struct snd_motu_spec motu_audio_express = { 239 .name = "AudioExpress", 240 .protocol = &snd_motu_protocol_v3, 241 .flags = SND_MOTU_SPEC_SUPPORT_CLOCK_X2 | 242 SND_MOTU_SPEC_TX_MICINST_CHUNK | 243 SND_MOTU_SPEC_TX_RETURN_CHUNK | 244 SND_MOTU_SPEC_RX_SEPARETED_MAIN | 245 SND_MOTU_SPEC_RX_MIDI_2ND_Q | 246 SND_MOTU_SPEC_TX_MIDI_3RD_Q, 247 .analog_in_ports = 2, 248 .analog_out_ports = 4, 249 }; 250 251 #define SND_MOTU_DEV_ENTRY(model, data) \ 252 { \ 253 .match_flags = IEEE1394_MATCH_VENDOR_ID | \ 254 IEEE1394_MATCH_SPECIFIER_ID | \ 255 IEEE1394_MATCH_VERSION, \ 256 .vendor_id = OUI_MOTU, \ 257 .specifier_id = OUI_MOTU, \ 258 .version = model, \ 259 .driver_data = (kernel_ulong_t)data, \ 260 } 261 262 static const struct ieee1394_device_id motu_id_table[] = { 263 SND_MOTU_DEV_ENTRY(0x000003, &motu_828mk2), 264 SND_MOTU_DEV_ENTRY(0x000009, &snd_motu_spec_traveler), 265 SND_MOTU_DEV_ENTRY(0x00000f, &snd_motu_spec_8pre), 266 SND_MOTU_DEV_ENTRY(0x000015, &motu_828mk3), /* FireWire only. */ 267 SND_MOTU_DEV_ENTRY(0x000035, &motu_828mk3), /* Hybrid. */ 268 SND_MOTU_DEV_ENTRY(0x000033, &motu_audio_express), 269 { } 270 }; 271 MODULE_DEVICE_TABLE(ieee1394, motu_id_table); 272 273 static struct fw_driver motu_driver = { 274 .driver = { 275 .owner = THIS_MODULE, 276 .name = KBUILD_MODNAME, 277 .bus = &fw_bus_type, 278 }, 279 .probe = motu_probe, 280 .update = motu_bus_update, 281 .remove = motu_remove, 282 .id_table = motu_id_table, 283 }; 284 285 static int __init alsa_motu_init(void) 286 { 287 return driver_register(&motu_driver.driver); 288 } 289 290 static void __exit alsa_motu_exit(void) 291 { 292 driver_unregister(&motu_driver.driver); 293 } 294 295 module_init(alsa_motu_init); 296 module_exit(alsa_motu_exit); 297