motu.c (5357B)
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * motu.c - a part of driver for MOTU FireWire series 4 * 5 * Copyright (c) 2015-2017 Takashi Sakamoto <o-takashi@sakamocchi.jp> 6 */ 7 8#include "motu.h" 9 10#define OUI_MOTU 0x0001f2 11 12MODULE_DESCRIPTION("MOTU FireWire driver"); 13MODULE_AUTHOR("Takashi Sakamoto <o-takashi@sakamocchi.jp>"); 14MODULE_LICENSE("GPL v2"); 15 16const unsigned int snd_motu_clock_rates[SND_MOTU_CLOCK_RATE_COUNT] = { 17 /* mode 0 */ 18 [0] = 44100, 19 [1] = 48000, 20 /* mode 1 */ 21 [2] = 88200, 22 [3] = 96000, 23 /* mode 2 */ 24 [4] = 176400, 25 [5] = 192000, 26}; 27 28static void name_card(struct snd_motu *motu) 29{ 30 struct fw_device *fw_dev = fw_parent_device(motu->unit); 31 struct fw_csr_iterator it; 32 int key, val; 33 u32 version = 0; 34 35 fw_csr_iterator_init(&it, motu->unit->directory); 36 while (fw_csr_iterator_next(&it, &key, &val)) { 37 switch (key) { 38 case CSR_MODEL: 39 version = val; 40 break; 41 } 42 } 43 44 strcpy(motu->card->driver, "FW-MOTU"); 45 strcpy(motu->card->shortname, motu->spec->name); 46 strcpy(motu->card->mixername, motu->spec->name); 47 snprintf(motu->card->longname, sizeof(motu->card->longname), 48 "MOTU %s (version:%06x), GUID %08x%08x at %s, S%d", 49 motu->spec->name, version, 50 fw_dev->config_rom[3], fw_dev->config_rom[4], 51 dev_name(&motu->unit->device), 100 << fw_dev->max_speed); 52} 53 54static void motu_card_free(struct snd_card *card) 55{ 56 struct snd_motu *motu = card->private_data; 57 58 snd_motu_transaction_unregister(motu); 59 snd_motu_stream_destroy_duplex(motu); 60 61 mutex_destroy(&motu->mutex); 62 fw_unit_put(motu->unit); 63} 64 65static int motu_probe(struct fw_unit *unit, const struct ieee1394_device_id *entry) 66{ 67 struct snd_card *card; 68 struct snd_motu *motu; 69 int err; 70 71 err = snd_card_new(&unit->device, -1, NULL, THIS_MODULE, sizeof(*motu), &card); 72 if (err < 0) 73 return err; 74 card->private_free = motu_card_free; 75 76 motu = card->private_data; 77 motu->unit = fw_unit_get(unit); 78 dev_set_drvdata(&unit->device, motu); 79 motu->card = card; 80 81 motu->spec = (const struct snd_motu_spec *)entry->driver_data; 82 mutex_init(&motu->mutex); 83 spin_lock_init(&motu->lock); 84 init_waitqueue_head(&motu->hwdep_wait); 85 86 name_card(motu); 87 88 err = snd_motu_transaction_register(motu); 89 if (err < 0) 90 goto error; 91 92 err = snd_motu_stream_init_duplex(motu); 93 if (err < 0) 94 goto error; 95 96 snd_motu_proc_init(motu); 97 98 err = snd_motu_create_pcm_devices(motu); 99 if (err < 0) 100 goto error; 101 102 if ((motu->spec->flags & SND_MOTU_SPEC_RX_MIDI_2ND_Q) || 103 (motu->spec->flags & SND_MOTU_SPEC_RX_MIDI_3RD_Q) || 104 (motu->spec->flags & SND_MOTU_SPEC_TX_MIDI_2ND_Q) || 105 (motu->spec->flags & SND_MOTU_SPEC_TX_MIDI_3RD_Q)) { 106 err = snd_motu_create_midi_devices(motu); 107 if (err < 0) 108 goto error; 109 } 110 111 err = snd_motu_create_hwdep_device(motu); 112 if (err < 0) 113 goto error; 114 115 if (motu->spec->flags & SND_MOTU_SPEC_REGISTER_DSP) { 116 err = snd_motu_register_dsp_message_parser_new(motu); 117 if (err < 0) 118 goto error; 119 } else if (motu->spec->flags & SND_MOTU_SPEC_COMMAND_DSP) { 120 err = snd_motu_command_dsp_message_parser_new(motu); 121 if (err < 0) 122 goto error; 123 } 124 125 err = snd_card_register(card); 126 if (err < 0) 127 goto error; 128 129 return 0; 130error: 131 snd_card_free(card); 132 return err; 133} 134 135static void motu_remove(struct fw_unit *unit) 136{ 137 struct snd_motu *motu = dev_get_drvdata(&unit->device); 138 139 // Block till all of ALSA character devices are released. 140 snd_card_free(motu->card); 141} 142 143static void motu_bus_update(struct fw_unit *unit) 144{ 145 struct snd_motu *motu = dev_get_drvdata(&unit->device); 146 147 /* The handler address register becomes initialized. */ 148 snd_motu_transaction_reregister(motu); 149} 150 151#define SND_MOTU_DEV_ENTRY(model, data) \ 152{ \ 153 .match_flags = IEEE1394_MATCH_VENDOR_ID | \ 154 IEEE1394_MATCH_SPECIFIER_ID | \ 155 IEEE1394_MATCH_VERSION, \ 156 .vendor_id = OUI_MOTU, \ 157 .specifier_id = OUI_MOTU, \ 158 .version = model, \ 159 .driver_data = (kernel_ulong_t)data, \ 160} 161 162static const struct ieee1394_device_id motu_id_table[] = { 163 SND_MOTU_DEV_ENTRY(0x000001, &snd_motu_spec_828), 164 SND_MOTU_DEV_ENTRY(0x000002, &snd_motu_spec_896), 165 SND_MOTU_DEV_ENTRY(0x000003, &snd_motu_spec_828mk2), 166 SND_MOTU_DEV_ENTRY(0x000005, &snd_motu_spec_896hd), 167 SND_MOTU_DEV_ENTRY(0x000009, &snd_motu_spec_traveler), 168 SND_MOTU_DEV_ENTRY(0x00000d, &snd_motu_spec_ultralite), 169 SND_MOTU_DEV_ENTRY(0x00000f, &snd_motu_spec_8pre), 170 SND_MOTU_DEV_ENTRY(0x000015, &snd_motu_spec_828mk3_fw), // FireWire only. 171 SND_MOTU_DEV_ENTRY(0x000019, &snd_motu_spec_ultralite_mk3), // FireWire only. 172 SND_MOTU_DEV_ENTRY(0x00001b, &snd_motu_spec_traveler_mk3), 173 SND_MOTU_DEV_ENTRY(0x000030, &snd_motu_spec_ultralite_mk3), // Hybrid. 174 SND_MOTU_DEV_ENTRY(0x000035, &snd_motu_spec_828mk3_hybrid), // Hybrid. 175 SND_MOTU_DEV_ENTRY(0x000033, &snd_motu_spec_audio_express), 176 SND_MOTU_DEV_ENTRY(0x000039, &snd_motu_spec_track16), 177 SND_MOTU_DEV_ENTRY(0x000045, &snd_motu_spec_4pre), 178 { } 179}; 180MODULE_DEVICE_TABLE(ieee1394, motu_id_table); 181 182static struct fw_driver motu_driver = { 183 .driver = { 184 .owner = THIS_MODULE, 185 .name = KBUILD_MODNAME, 186 .bus = &fw_bus_type, 187 }, 188 .probe = motu_probe, 189 .update = motu_bus_update, 190 .remove = motu_remove, 191 .id_table = motu_id_table, 192}; 193 194static int __init alsa_motu_init(void) 195{ 196 return driver_register(&motu_driver.driver); 197} 198 199static void __exit alsa_motu_exit(void) 200{ 201 driver_unregister(&motu_driver.driver); 202} 203 204module_init(alsa_motu_init); 205module_exit(alsa_motu_exit);