1fd6f4b0dSTakashi Sakamoto /* 2fd6f4b0dSTakashi Sakamoto * bebob.c - a part of driver for BeBoB based devices 3fd6f4b0dSTakashi Sakamoto * 4fd6f4b0dSTakashi Sakamoto * Copyright (c) 2013-2014 Takashi Sakamoto 5fd6f4b0dSTakashi Sakamoto * 6fd6f4b0dSTakashi Sakamoto * Licensed under the terms of the GNU General Public License, version 2. 7fd6f4b0dSTakashi Sakamoto */ 8fd6f4b0dSTakashi Sakamoto 9fd6f4b0dSTakashi Sakamoto /* 10fd6f4b0dSTakashi Sakamoto * BeBoB is 'BridgeCo enhanced Breakout Box'. This is installed to firewire 11fd6f4b0dSTakashi Sakamoto * devices with DM1000/DM1100/DM1500 chipset. It gives common way for host 12fd6f4b0dSTakashi Sakamoto * system to handle BeBoB based devices. 13fd6f4b0dSTakashi Sakamoto */ 14fd6f4b0dSTakashi Sakamoto 15fd6f4b0dSTakashi Sakamoto #include "bebob.h" 16fd6f4b0dSTakashi Sakamoto 17fd6f4b0dSTakashi Sakamoto MODULE_DESCRIPTION("BridgeCo BeBoB driver"); 18fd6f4b0dSTakashi Sakamoto MODULE_AUTHOR("Takashi Sakamoto <o-takashi@sakamocchi.jp>"); 19fd6f4b0dSTakashi Sakamoto MODULE_LICENSE("GPL v2"); 20fd6f4b0dSTakashi Sakamoto 21fd6f4b0dSTakashi Sakamoto static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; 22fd6f4b0dSTakashi Sakamoto static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; 23fd6f4b0dSTakashi Sakamoto static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; 24fd6f4b0dSTakashi Sakamoto 25fd6f4b0dSTakashi Sakamoto module_param_array(index, int, NULL, 0444); 26fd6f4b0dSTakashi Sakamoto MODULE_PARM_DESC(index, "card index"); 27fd6f4b0dSTakashi Sakamoto module_param_array(id, charp, NULL, 0444); 28fd6f4b0dSTakashi Sakamoto MODULE_PARM_DESC(id, "ID string"); 29fd6f4b0dSTakashi Sakamoto module_param_array(enable, bool, NULL, 0444); 30fd6f4b0dSTakashi Sakamoto MODULE_PARM_DESC(enable, "enable BeBoB sound card"); 31fd6f4b0dSTakashi Sakamoto 32fd6f4b0dSTakashi Sakamoto static DEFINE_MUTEX(devices_mutex); 33fd6f4b0dSTakashi Sakamoto static DECLARE_BITMAP(devices_used, SNDRV_CARDS); 34fd6f4b0dSTakashi Sakamoto 35fd6f4b0dSTakashi Sakamoto /* Offsets from information register. */ 36fd6f4b0dSTakashi Sakamoto #define INFO_OFFSET_GUID 0x10 37fd6f4b0dSTakashi Sakamoto #define INFO_OFFSET_HW_MODEL_ID 0x18 38fd6f4b0dSTakashi Sakamoto #define INFO_OFFSET_HW_MODEL_REVISION 0x1c 39fd6f4b0dSTakashi Sakamoto 40fd6f4b0dSTakashi Sakamoto #define VEN_EDIROL 0x000040ab 41fd6f4b0dSTakashi Sakamoto #define VEN_PRESONUS 0x00000a92 42fd6f4b0dSTakashi Sakamoto #define VEN_BRIDGECO 0x000007f5 43fd6f4b0dSTakashi Sakamoto #define VEN_MACKIE 0x0000000f 44fd6f4b0dSTakashi Sakamoto #define VEN_STANTON 0x00001260 45fd6f4b0dSTakashi Sakamoto #define VEN_TASCAM 0x0000022e 46fd6f4b0dSTakashi Sakamoto #define VEN_BEHRINGER 0x00001564 47fd6f4b0dSTakashi Sakamoto #define VEN_APOGEE 0x000003db 48fd6f4b0dSTakashi Sakamoto #define VEN_ESI 0x00000f1b 49fd6f4b0dSTakashi Sakamoto #define VEN_ACOUSTIC 0x00000002 50fd6f4b0dSTakashi Sakamoto #define VEN_CME 0x0000000a 51fd6f4b0dSTakashi Sakamoto #define VEN_PHONIC 0x00001496 52fd6f4b0dSTakashi Sakamoto #define VEN_LYNX 0x000019e5 53fd6f4b0dSTakashi Sakamoto #define VEN_ICON 0x00001a9e 54fd6f4b0dSTakashi Sakamoto #define VEN_PRISMSOUND 0x00001198 55326b9cacSTakashi Sakamoto #define VEN_TERRATEC 0x00000aac 568ac98a35STakashi Sakamoto #define VEN_YAMAHA 0x0000a0de 5725784ec2STakashi Sakamoto #define VEN_FOCUSRITE 0x0000130e 589076c22dSTakashi Sakamoto #define VEN_MAUDIO1 0x00000d6c 599076c22dSTakashi Sakamoto #define VEN_MAUDIO2 0x000007f5 6025784ec2STakashi Sakamoto 6125784ec2STakashi Sakamoto #define MODEL_FOCUSRITE_SAFFIRE_BOTH 0x00000000 629076c22dSTakashi Sakamoto #define MODEL_MAUDIO_AUDIOPHILE_BOTH 0x00010060 63fd6f4b0dSTakashi Sakamoto 64fd6f4b0dSTakashi Sakamoto static int 65fd6f4b0dSTakashi Sakamoto name_device(struct snd_bebob *bebob, unsigned int vendor_id) 66fd6f4b0dSTakashi Sakamoto { 67fd6f4b0dSTakashi Sakamoto struct fw_device *fw_dev = fw_parent_device(bebob->unit); 68fd6f4b0dSTakashi Sakamoto char vendor[24] = {0}; 69fd6f4b0dSTakashi Sakamoto char model[32] = {0}; 70fd6f4b0dSTakashi Sakamoto u32 id; 71fd6f4b0dSTakashi Sakamoto u32 data[2] = {0}; 72fd6f4b0dSTakashi Sakamoto u32 revision; 73fd6f4b0dSTakashi Sakamoto int err; 74fd6f4b0dSTakashi Sakamoto 75fd6f4b0dSTakashi Sakamoto /* get vendor name from root directory */ 76fd6f4b0dSTakashi Sakamoto err = fw_csr_string(fw_dev->config_rom + 5, CSR_VENDOR, 77fd6f4b0dSTakashi Sakamoto vendor, sizeof(vendor)); 78fd6f4b0dSTakashi Sakamoto if (err < 0) 79fd6f4b0dSTakashi Sakamoto goto end; 80fd6f4b0dSTakashi Sakamoto 81fd6f4b0dSTakashi Sakamoto /* get model name from unit directory */ 82fd6f4b0dSTakashi Sakamoto err = fw_csr_string(bebob->unit->directory, CSR_MODEL, 83fd6f4b0dSTakashi Sakamoto model, sizeof(model)); 84fd6f4b0dSTakashi Sakamoto if (err < 0) 85fd6f4b0dSTakashi Sakamoto goto end; 86fd6f4b0dSTakashi Sakamoto 87fd6f4b0dSTakashi Sakamoto /* get hardware id */ 88fd6f4b0dSTakashi Sakamoto err = snd_bebob_read_quad(bebob->unit, INFO_OFFSET_HW_MODEL_ID, 89fd6f4b0dSTakashi Sakamoto &id); 90fd6f4b0dSTakashi Sakamoto if (err < 0) 91fd6f4b0dSTakashi Sakamoto goto end; 92fd6f4b0dSTakashi Sakamoto 93fd6f4b0dSTakashi Sakamoto /* get hardware revision */ 94fd6f4b0dSTakashi Sakamoto err = snd_bebob_read_quad(bebob->unit, INFO_OFFSET_HW_MODEL_REVISION, 95fd6f4b0dSTakashi Sakamoto &revision); 96fd6f4b0dSTakashi Sakamoto if (err < 0) 97fd6f4b0dSTakashi Sakamoto goto end; 98fd6f4b0dSTakashi Sakamoto 99fd6f4b0dSTakashi Sakamoto /* get GUID */ 100fd6f4b0dSTakashi Sakamoto err = snd_bebob_read_block(bebob->unit, INFO_OFFSET_GUID, 101fd6f4b0dSTakashi Sakamoto data, sizeof(data)); 102fd6f4b0dSTakashi Sakamoto if (err < 0) 103fd6f4b0dSTakashi Sakamoto goto end; 104fd6f4b0dSTakashi Sakamoto 105fd6f4b0dSTakashi Sakamoto strcpy(bebob->card->driver, "BeBoB"); 106fd6f4b0dSTakashi Sakamoto strcpy(bebob->card->shortname, model); 107fd6f4b0dSTakashi Sakamoto strcpy(bebob->card->mixername, model); 108fd6f4b0dSTakashi Sakamoto snprintf(bebob->card->longname, sizeof(bebob->card->longname), 109fd6f4b0dSTakashi Sakamoto "%s %s (id:%d, rev:%d), GUID %08x%08x at %s, S%d", 110fd6f4b0dSTakashi Sakamoto vendor, model, id, revision, 111fd6f4b0dSTakashi Sakamoto data[0], data[1], dev_name(&bebob->unit->device), 112fd6f4b0dSTakashi Sakamoto 100 << fw_dev->max_speed); 113fd6f4b0dSTakashi Sakamoto end: 114fd6f4b0dSTakashi Sakamoto return err; 115fd6f4b0dSTakashi Sakamoto } 116fd6f4b0dSTakashi Sakamoto 117fd6f4b0dSTakashi Sakamoto static void 118fd6f4b0dSTakashi Sakamoto bebob_card_free(struct snd_card *card) 119fd6f4b0dSTakashi Sakamoto { 120fd6f4b0dSTakashi Sakamoto struct snd_bebob *bebob = card->private_data; 121fd6f4b0dSTakashi Sakamoto 122fd6f4b0dSTakashi Sakamoto if (bebob->card_index >= 0) { 123fd6f4b0dSTakashi Sakamoto mutex_lock(&devices_mutex); 124fd6f4b0dSTakashi Sakamoto clear_bit(bebob->card_index, devices_used); 125fd6f4b0dSTakashi Sakamoto mutex_unlock(&devices_mutex); 126fd6f4b0dSTakashi Sakamoto } 127fd6f4b0dSTakashi Sakamoto 128fd6f4b0dSTakashi Sakamoto mutex_destroy(&bebob->mutex); 129fd6f4b0dSTakashi Sakamoto } 130fd6f4b0dSTakashi Sakamoto 13125784ec2STakashi Sakamoto static const struct snd_bebob_spec * 13225784ec2STakashi Sakamoto get_saffire_spec(struct fw_unit *unit) 13325784ec2STakashi Sakamoto { 13425784ec2STakashi Sakamoto char name[24] = {0}; 13525784ec2STakashi Sakamoto 13625784ec2STakashi Sakamoto if (fw_csr_string(unit->directory, CSR_MODEL, name, sizeof(name)) < 0) 13725784ec2STakashi Sakamoto return NULL; 13825784ec2STakashi Sakamoto 13925784ec2STakashi Sakamoto if (strcmp(name, "SaffireLE") == 0) 14025784ec2STakashi Sakamoto return &saffire_le_spec; 14125784ec2STakashi Sakamoto else 14225784ec2STakashi Sakamoto return &saffire_spec; 14325784ec2STakashi Sakamoto } 14425784ec2STakashi Sakamoto 1459076c22dSTakashi Sakamoto static bool 1469076c22dSTakashi Sakamoto check_audiophile_booted(struct fw_unit *unit) 1479076c22dSTakashi Sakamoto { 1489076c22dSTakashi Sakamoto char name[24] = {0}; 1499076c22dSTakashi Sakamoto 1509076c22dSTakashi Sakamoto if (fw_csr_string(unit->directory, CSR_MODEL, name, sizeof(name)) < 0) 1519076c22dSTakashi Sakamoto return false; 1529076c22dSTakashi Sakamoto 1539076c22dSTakashi Sakamoto return strncmp(name, "FW Audiophile Bootloader", 15) != 0; 1549076c22dSTakashi Sakamoto } 1559076c22dSTakashi Sakamoto 156fd6f4b0dSTakashi Sakamoto static int 157fd6f4b0dSTakashi Sakamoto bebob_probe(struct fw_unit *unit, 158fd6f4b0dSTakashi Sakamoto const struct ieee1394_device_id *entry) 159fd6f4b0dSTakashi Sakamoto { 160fd6f4b0dSTakashi Sakamoto struct snd_card *card; 161fd6f4b0dSTakashi Sakamoto struct snd_bebob *bebob; 1621fc9522aSTakashi Sakamoto const struct snd_bebob_spec *spec; 163fd6f4b0dSTakashi Sakamoto unsigned int card_index; 164fd6f4b0dSTakashi Sakamoto int err; 165fd6f4b0dSTakashi Sakamoto 166fd6f4b0dSTakashi Sakamoto mutex_lock(&devices_mutex); 167fd6f4b0dSTakashi Sakamoto 168fd6f4b0dSTakashi Sakamoto for (card_index = 0; card_index < SNDRV_CARDS; card_index++) { 169fd6f4b0dSTakashi Sakamoto if (!test_bit(card_index, devices_used) && enable[card_index]) 170fd6f4b0dSTakashi Sakamoto break; 171fd6f4b0dSTakashi Sakamoto } 172fd6f4b0dSTakashi Sakamoto if (card_index >= SNDRV_CARDS) { 173fd6f4b0dSTakashi Sakamoto err = -ENOENT; 174fd6f4b0dSTakashi Sakamoto goto end; 175fd6f4b0dSTakashi Sakamoto } 176fd6f4b0dSTakashi Sakamoto 17725784ec2STakashi Sakamoto if ((entry->vendor_id == VEN_FOCUSRITE) && 1789076c22dSTakashi Sakamoto (entry->model_id == MODEL_FOCUSRITE_SAFFIRE_BOTH)) { 17925784ec2STakashi Sakamoto spec = get_saffire_spec(unit); 1809076c22dSTakashi Sakamoto } else if ((entry->vendor_id == VEN_MAUDIO1) && 1819076c22dSTakashi Sakamoto (entry->model_id == MODEL_MAUDIO_AUDIOPHILE_BOTH) && 1829076c22dSTakashi Sakamoto !check_audiophile_booted(unit)) { 1839076c22dSTakashi Sakamoto err = 0; 1849076c22dSTakashi Sakamoto goto end; 1859076c22dSTakashi Sakamoto } else { 1861fc9522aSTakashi Sakamoto spec = (const struct snd_bebob_spec *)entry->driver_data; 1879076c22dSTakashi Sakamoto } 1881fc9522aSTakashi Sakamoto if (spec == NULL) { 1891fc9522aSTakashi Sakamoto err = -ENOSYS; 1901fc9522aSTakashi Sakamoto goto end; 1911fc9522aSTakashi Sakamoto } 1921fc9522aSTakashi Sakamoto 193fd6f4b0dSTakashi Sakamoto err = snd_card_new(&unit->device, index[card_index], id[card_index], 194fd6f4b0dSTakashi Sakamoto THIS_MODULE, sizeof(struct snd_bebob), &card); 195fd6f4b0dSTakashi Sakamoto if (err < 0) 196fd6f4b0dSTakashi Sakamoto goto end; 197fd6f4b0dSTakashi Sakamoto bebob = card->private_data; 198fd6f4b0dSTakashi Sakamoto bebob->card_index = card_index; 199fd6f4b0dSTakashi Sakamoto set_bit(card_index, devices_used); 200fd6f4b0dSTakashi Sakamoto card->private_free = bebob_card_free; 201fd6f4b0dSTakashi Sakamoto 202fd6f4b0dSTakashi Sakamoto bebob->card = card; 203fd6f4b0dSTakashi Sakamoto bebob->unit = unit; 2041fc9522aSTakashi Sakamoto bebob->spec = spec; 205fd6f4b0dSTakashi Sakamoto mutex_init(&bebob->mutex); 206fd6f4b0dSTakashi Sakamoto spin_lock_init(&bebob->lock); 207618eabeaSTakashi Sakamoto init_waitqueue_head(&bebob->hwdep_wait); 208fd6f4b0dSTakashi Sakamoto 209fd6f4b0dSTakashi Sakamoto err = name_device(bebob, entry->vendor_id); 210fd6f4b0dSTakashi Sakamoto if (err < 0) 211fd6f4b0dSTakashi Sakamoto goto error; 212fd6f4b0dSTakashi Sakamoto 213eb7b3a05STakashi Sakamoto err = snd_bebob_stream_discover(bebob); 214fd6f4b0dSTakashi Sakamoto if (err < 0) 215fd6f4b0dSTakashi Sakamoto goto error; 216eb7b3a05STakashi Sakamoto 217ad9697baSTakashi Sakamoto snd_bebob_proc_init(bebob); 218ad9697baSTakashi Sakamoto 219248b7802STakashi Sakamoto if ((bebob->midi_input_ports > 0) || 220248b7802STakashi Sakamoto (bebob->midi_output_ports > 0)) { 221248b7802STakashi Sakamoto err = snd_bebob_create_midi_devices(bebob); 222248b7802STakashi Sakamoto if (err < 0) 223248b7802STakashi Sakamoto goto error; 224248b7802STakashi Sakamoto } 225248b7802STakashi Sakamoto 226fbbebd2cSTakashi Sakamoto err = snd_bebob_create_pcm_devices(bebob); 227fbbebd2cSTakashi Sakamoto if (err < 0) 228fbbebd2cSTakashi Sakamoto goto error; 229fbbebd2cSTakashi Sakamoto 230618eabeaSTakashi Sakamoto err = snd_bebob_create_hwdep_device(bebob); 231618eabeaSTakashi Sakamoto if (err < 0) 232618eabeaSTakashi Sakamoto goto error; 233618eabeaSTakashi Sakamoto 234eb7b3a05STakashi Sakamoto err = snd_bebob_stream_init_duplex(bebob); 235eb7b3a05STakashi Sakamoto if (err < 0) 236eb7b3a05STakashi Sakamoto goto error; 237eb7b3a05STakashi Sakamoto 238eb7b3a05STakashi Sakamoto err = snd_card_register(card); 239eb7b3a05STakashi Sakamoto if (err < 0) { 240eb7b3a05STakashi Sakamoto snd_bebob_stream_destroy_duplex(bebob); 241eb7b3a05STakashi Sakamoto goto error; 242eb7b3a05STakashi Sakamoto } 243eb7b3a05STakashi Sakamoto 244fd6f4b0dSTakashi Sakamoto dev_set_drvdata(&unit->device, bebob); 245fd6f4b0dSTakashi Sakamoto end: 246fd6f4b0dSTakashi Sakamoto mutex_unlock(&devices_mutex); 247fd6f4b0dSTakashi Sakamoto return err; 248fd6f4b0dSTakashi Sakamoto error: 249fd6f4b0dSTakashi Sakamoto mutex_unlock(&devices_mutex); 250fd6f4b0dSTakashi Sakamoto snd_card_free(card); 251fd6f4b0dSTakashi Sakamoto return err; 252fd6f4b0dSTakashi Sakamoto } 253fd6f4b0dSTakashi Sakamoto 254fd6f4b0dSTakashi Sakamoto static void 255fd6f4b0dSTakashi Sakamoto bebob_update(struct fw_unit *unit) 256fd6f4b0dSTakashi Sakamoto { 257fd6f4b0dSTakashi Sakamoto struct snd_bebob *bebob = dev_get_drvdata(&unit->device); 2589076c22dSTakashi Sakamoto 2599076c22dSTakashi Sakamoto if (bebob == NULL) 2609076c22dSTakashi Sakamoto return; 2619076c22dSTakashi Sakamoto 262fd6f4b0dSTakashi Sakamoto fcp_bus_reset(bebob->unit); 263eb7b3a05STakashi Sakamoto snd_bebob_stream_update_duplex(bebob); 264fd6f4b0dSTakashi Sakamoto } 265fd6f4b0dSTakashi Sakamoto 266fd6f4b0dSTakashi Sakamoto static void bebob_remove(struct fw_unit *unit) 267fd6f4b0dSTakashi Sakamoto { 268fd6f4b0dSTakashi Sakamoto struct snd_bebob *bebob = dev_get_drvdata(&unit->device); 2699076c22dSTakashi Sakamoto 2709076c22dSTakashi Sakamoto if (bebob == NULL) 2719076c22dSTakashi Sakamoto return; 2729076c22dSTakashi Sakamoto 273eb7b3a05STakashi Sakamoto snd_bebob_stream_destroy_duplex(bebob); 274fd6f4b0dSTakashi Sakamoto snd_card_disconnect(bebob->card); 275fd6f4b0dSTakashi Sakamoto snd_card_free_when_closed(bebob->card); 276fd6f4b0dSTakashi Sakamoto } 277fd6f4b0dSTakashi Sakamoto 2781fc9522aSTakashi Sakamoto struct snd_bebob_rate_spec normal_rate_spec = { 2791fc9522aSTakashi Sakamoto .get = &snd_bebob_stream_get_rate, 2801fc9522aSTakashi Sakamoto .set = &snd_bebob_stream_set_rate 2811fc9522aSTakashi Sakamoto }; 2821fc9522aSTakashi Sakamoto static const struct snd_bebob_spec spec_normal = { 2831fc9522aSTakashi Sakamoto .clock = NULL, 2841fc9522aSTakashi Sakamoto .rate = &normal_rate_spec, 2851fc9522aSTakashi Sakamoto .meter = NULL 2861fc9522aSTakashi Sakamoto }; 2871fc9522aSTakashi Sakamoto 288fd6f4b0dSTakashi Sakamoto static const struct ieee1394_device_id bebob_id_table[] = { 289fd6f4b0dSTakashi Sakamoto /* Edirol, FA-66 */ 2901fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_EDIROL, 0x00010049, &spec_normal), 291fd6f4b0dSTakashi Sakamoto /* Edirol, FA-101 */ 2921fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_EDIROL, 0x00010048, &spec_normal), 293fd6f4b0dSTakashi Sakamoto /* Presonus, FIREBOX */ 2941fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_PRESONUS, 0x00010000, &spec_normal), 295fd6f4b0dSTakashi Sakamoto /* PreSonus, FIREPOD/FP10 */ 2961fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_PRESONUS, 0x00010066, &spec_normal), 297fd6f4b0dSTakashi Sakamoto /* PreSonus, Inspire1394 */ 2981fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_PRESONUS, 0x00010001, &spec_normal), 299fd6f4b0dSTakashi Sakamoto /* BridgeCo, RDAudio1 */ 3001fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_BRIDGECO, 0x00010048, &spec_normal), 301fd6f4b0dSTakashi Sakamoto /* BridgeCo, Audio5 */ 3021fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_BRIDGECO, 0x00010049, &spec_normal), 303fd6f4b0dSTakashi Sakamoto /* Mackie, Onyx 1220/1620/1640 (Firewire I/O Card) */ 3041fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_MACKIE, 0x00010065, &spec_normal), 305fd6f4b0dSTakashi Sakamoto /* Mackie, d.2 (Firewire Option) */ 3061fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_MACKIE, 0x00010067, &spec_normal), 307fd6f4b0dSTakashi Sakamoto /* Stanton, ScratchAmp */ 3081fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_STANTON, 0x00000001, &spec_normal), 309fd6f4b0dSTakashi Sakamoto /* Tascam, IF-FW DM */ 3101fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_TASCAM, 0x00010067, &spec_normal), 311fd6f4b0dSTakashi Sakamoto /* Behringer, XENIX UFX 1204 */ 3121fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_BEHRINGER, 0x00001204, &spec_normal), 313fd6f4b0dSTakashi Sakamoto /* Behringer, XENIX UFX 1604 */ 3141fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_BEHRINGER, 0x00001604, &spec_normal), 315fd6f4b0dSTakashi Sakamoto /* Behringer, Digital Mixer X32 series (X-UF Card) */ 3161fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_BEHRINGER, 0x00000006, &spec_normal), 317fd6f4b0dSTakashi Sakamoto /* Apogee Electronics, Rosetta 200/400 (X-FireWire card) */ 318fd6f4b0dSTakashi Sakamoto /* Apogee Electronics, DA/AD/DD-16X (X-FireWire card) */ 3191fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_APOGEE, 0x00010048, &spec_normal), 320fd6f4b0dSTakashi Sakamoto /* Apogee Electronics, Ensemble */ 3211fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_APOGEE, 0x00001eee, &spec_normal), 322fd6f4b0dSTakashi Sakamoto /* ESI, Quatafire610 */ 3231fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_ESI, 0x00010064, &spec_normal), 324fd6f4b0dSTakashi Sakamoto /* AcousticReality, eARMasterOne */ 3251fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_ACOUSTIC, 0x00000002, &spec_normal), 326fd6f4b0dSTakashi Sakamoto /* CME, MatrixKFW */ 3271fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_CME, 0x00030000, &spec_normal), 328fd6f4b0dSTakashi Sakamoto /* Phonic, Helix Board 12 MkII */ 3291fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_PHONIC, 0x00050000, &spec_normal), 330fd6f4b0dSTakashi Sakamoto /* Phonic, Helix Board 18 MkII */ 3311fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_PHONIC, 0x00060000, &spec_normal), 332fd6f4b0dSTakashi Sakamoto /* Phonic, Helix Board 24 MkII */ 3331fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_PHONIC, 0x00070000, &spec_normal), 334fd6f4b0dSTakashi Sakamoto /* Phonic, Helix Board 12 Universal/18 Universal/24 Universal */ 3351fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_PHONIC, 0x00000000, &spec_normal), 336fd6f4b0dSTakashi Sakamoto /* Lynx, Aurora 8/16 (LT-FW) */ 3371fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_LYNX, 0x00000001, &spec_normal), 338fd6f4b0dSTakashi Sakamoto /* ICON, FireXon */ 3391fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_ICON, 0x00000001, &spec_normal), 340fd6f4b0dSTakashi Sakamoto /* PrismSound, Orpheus */ 3411fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_PRISMSOUND, 0x00010048, &spec_normal), 342fd6f4b0dSTakashi Sakamoto /* PrismSound, ADA-8XR */ 3431fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_PRISMSOUND, 0x0000ada8, &spec_normal), 344326b9cacSTakashi Sakamoto /* TerraTec Electronic GmbH, PHASE 88 Rack FW */ 345326b9cacSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_TERRATEC, 0x00000003, &phase88_rack_spec), 346326b9cacSTakashi Sakamoto /* TerraTec Electronic GmbH, PHASE 24 FW */ 347326b9cacSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_TERRATEC, 0x00000004, &phase24_series_spec), 348326b9cacSTakashi Sakamoto /* TerraTec Electronic GmbH, Phase X24 FW */ 349326b9cacSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_TERRATEC, 0x00000007, &phase24_series_spec), 350326b9cacSTakashi Sakamoto /* TerraTec Electronic GmbH, EWS MIC2/MIC8 */ 351326b9cacSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_TERRATEC, 0x00000005, &spec_normal), 352326b9cacSTakashi Sakamoto /* Terratec Electronic GmbH, Aureon 7.1 Firewire */ 353326b9cacSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_TERRATEC, 0x00000002, &spec_normal), 3548ac98a35STakashi Sakamoto /* Yamaha, GO44 */ 3558ac98a35STakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_YAMAHA, 0x0010000b, &yamaha_go_spec), 3568ac98a35STakashi Sakamoto /* YAMAHA, GO46 */ 3578ac98a35STakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_YAMAHA, 0x0010000c, &yamaha_go_spec), 35825784ec2STakashi Sakamoto /* Focusrite, SaffirePro 26 I/O */ 35925784ec2STakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_FOCUSRITE, 0x00000003, &saffirepro_26_spec), 36025784ec2STakashi Sakamoto /* Focusrite, SaffirePro 10 I/O */ 36125784ec2STakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_FOCUSRITE, 0x00000006, &saffirepro_10_spec), 36225784ec2STakashi Sakamoto /* Focusrite, Saffire(no label and LE) */ 36325784ec2STakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_FOCUSRITE, MODEL_FOCUSRITE_SAFFIRE_BOTH, 36425784ec2STakashi Sakamoto &saffire_spec), 3659076c22dSTakashi Sakamoto /* M-Audio, Firewire 410 */ 3669076c22dSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_MAUDIO2, 0x00010046, &maudio_fw410_spec), 3679076c22dSTakashi Sakamoto /* M-Audio, Firewire Audiophile */ 3689076c22dSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_MAUDIO1, MODEL_MAUDIO_AUDIOPHILE_BOTH, 3699076c22dSTakashi Sakamoto &maudio_audiophile_spec), 3709076c22dSTakashi Sakamoto /* M-Audio, Firewire Solo */ 3719076c22dSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_MAUDIO1, 0x00010062, &maudio_solo_spec), 3729076c22dSTakashi Sakamoto /* M-Audio, Ozonic */ 3739076c22dSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_MAUDIO1, 0x0000000a, &maudio_ozonic_spec), 3749076c22dSTakashi Sakamoto /* M-Audio NRV10 */ 3759076c22dSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_MAUDIO1, 0x00010081, &maudio_nrv10_spec), 3769076c22dSTakashi Sakamoto /* M-Audio, ProFireLightbridge */ 3779076c22dSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_MAUDIO1, 0x000100a1, &spec_normal), 378fd6f4b0dSTakashi Sakamoto /* IDs are unknown but able to be supported */ 379fd6f4b0dSTakashi Sakamoto /* Apogee, Mini-ME Firewire */ 380fd6f4b0dSTakashi Sakamoto /* Apogee, Mini-DAC Firewire */ 381fd6f4b0dSTakashi Sakamoto /* Behringer, F-Control Audio 1616 */ 382fd6f4b0dSTakashi Sakamoto /* Behringer, F-Control Audio 610 */ 383fd6f4b0dSTakashi Sakamoto /* Cakawalk, Sonar Power Studio 66 */ 384fd6f4b0dSTakashi Sakamoto /* CME, UF400e */ 385fd6f4b0dSTakashi Sakamoto /* ESI, Quotafire XL */ 386fd6f4b0dSTakashi Sakamoto /* Infrasonic, DewX */ 387fd6f4b0dSTakashi Sakamoto /* Infrasonic, Windy6 */ 388fd6f4b0dSTakashi Sakamoto /* Mackie, Digital X Bus x.200 */ 389fd6f4b0dSTakashi Sakamoto /* Mackie, Digital X Bus x.400 */ 390fd6f4b0dSTakashi Sakamoto /* Phonic, HB 12 */ 391fd6f4b0dSTakashi Sakamoto /* Phonic, HB 24 */ 392fd6f4b0dSTakashi Sakamoto /* Phonic, HB 18 */ 393fd6f4b0dSTakashi Sakamoto /* Phonic, FireFly 202 */ 394fd6f4b0dSTakashi Sakamoto /* Phonic, FireFly 302 */ 395fd6f4b0dSTakashi Sakamoto /* Rolf Spuler, Firewire Guitar */ 396fd6f4b0dSTakashi Sakamoto {} 397fd6f4b0dSTakashi Sakamoto }; 398fd6f4b0dSTakashi Sakamoto MODULE_DEVICE_TABLE(ieee1394, bebob_id_table); 399fd6f4b0dSTakashi Sakamoto 400fd6f4b0dSTakashi Sakamoto static struct fw_driver bebob_driver = { 401fd6f4b0dSTakashi Sakamoto .driver = { 402fd6f4b0dSTakashi Sakamoto .owner = THIS_MODULE, 403fd6f4b0dSTakashi Sakamoto .name = "snd-bebob", 404fd6f4b0dSTakashi Sakamoto .bus = &fw_bus_type, 405fd6f4b0dSTakashi Sakamoto }, 406fd6f4b0dSTakashi Sakamoto .probe = bebob_probe, 407fd6f4b0dSTakashi Sakamoto .update = bebob_update, 408fd6f4b0dSTakashi Sakamoto .remove = bebob_remove, 409fd6f4b0dSTakashi Sakamoto .id_table = bebob_id_table, 410fd6f4b0dSTakashi Sakamoto }; 411fd6f4b0dSTakashi Sakamoto 412fd6f4b0dSTakashi Sakamoto static int __init 413fd6f4b0dSTakashi Sakamoto snd_bebob_init(void) 414fd6f4b0dSTakashi Sakamoto { 415fd6f4b0dSTakashi Sakamoto return driver_register(&bebob_driver.driver); 416fd6f4b0dSTakashi Sakamoto } 417fd6f4b0dSTakashi Sakamoto 418fd6f4b0dSTakashi Sakamoto static void __exit 419fd6f4b0dSTakashi Sakamoto snd_bebob_exit(void) 420fd6f4b0dSTakashi Sakamoto { 421fd6f4b0dSTakashi Sakamoto driver_unregister(&bebob_driver.driver); 422fd6f4b0dSTakashi Sakamoto mutex_destroy(&devices_mutex); 423fd6f4b0dSTakashi Sakamoto } 424fd6f4b0dSTakashi Sakamoto 425fd6f4b0dSTakashi Sakamoto module_init(snd_bebob_init); 426fd6f4b0dSTakashi Sakamoto module_exit(snd_bebob_exit); 427