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 5825784ec2STakashi Sakamoto 5925784ec2STakashi Sakamoto #define MODEL_FOCUSRITE_SAFFIRE_BOTH 0x00000000 60fd6f4b0dSTakashi Sakamoto 61fd6f4b0dSTakashi Sakamoto static int 62fd6f4b0dSTakashi Sakamoto name_device(struct snd_bebob *bebob, unsigned int vendor_id) 63fd6f4b0dSTakashi Sakamoto { 64fd6f4b0dSTakashi Sakamoto struct fw_device *fw_dev = fw_parent_device(bebob->unit); 65fd6f4b0dSTakashi Sakamoto char vendor[24] = {0}; 66fd6f4b0dSTakashi Sakamoto char model[32] = {0}; 67fd6f4b0dSTakashi Sakamoto u32 id; 68fd6f4b0dSTakashi Sakamoto u32 data[2] = {0}; 69fd6f4b0dSTakashi Sakamoto u32 revision; 70fd6f4b0dSTakashi Sakamoto int err; 71fd6f4b0dSTakashi Sakamoto 72fd6f4b0dSTakashi Sakamoto /* get vendor name from root directory */ 73fd6f4b0dSTakashi Sakamoto err = fw_csr_string(fw_dev->config_rom + 5, CSR_VENDOR, 74fd6f4b0dSTakashi Sakamoto vendor, sizeof(vendor)); 75fd6f4b0dSTakashi Sakamoto if (err < 0) 76fd6f4b0dSTakashi Sakamoto goto end; 77fd6f4b0dSTakashi Sakamoto 78fd6f4b0dSTakashi Sakamoto /* get model name from unit directory */ 79fd6f4b0dSTakashi Sakamoto err = fw_csr_string(bebob->unit->directory, CSR_MODEL, 80fd6f4b0dSTakashi Sakamoto model, sizeof(model)); 81fd6f4b0dSTakashi Sakamoto if (err < 0) 82fd6f4b0dSTakashi Sakamoto goto end; 83fd6f4b0dSTakashi Sakamoto 84fd6f4b0dSTakashi Sakamoto /* get hardware id */ 85fd6f4b0dSTakashi Sakamoto err = snd_bebob_read_quad(bebob->unit, INFO_OFFSET_HW_MODEL_ID, 86fd6f4b0dSTakashi Sakamoto &id); 87fd6f4b0dSTakashi Sakamoto if (err < 0) 88fd6f4b0dSTakashi Sakamoto goto end; 89fd6f4b0dSTakashi Sakamoto 90fd6f4b0dSTakashi Sakamoto /* get hardware revision */ 91fd6f4b0dSTakashi Sakamoto err = snd_bebob_read_quad(bebob->unit, INFO_OFFSET_HW_MODEL_REVISION, 92fd6f4b0dSTakashi Sakamoto &revision); 93fd6f4b0dSTakashi Sakamoto if (err < 0) 94fd6f4b0dSTakashi Sakamoto goto end; 95fd6f4b0dSTakashi Sakamoto 96fd6f4b0dSTakashi Sakamoto /* get GUID */ 97fd6f4b0dSTakashi Sakamoto err = snd_bebob_read_block(bebob->unit, INFO_OFFSET_GUID, 98fd6f4b0dSTakashi Sakamoto data, sizeof(data)); 99fd6f4b0dSTakashi Sakamoto if (err < 0) 100fd6f4b0dSTakashi Sakamoto goto end; 101fd6f4b0dSTakashi Sakamoto 102fd6f4b0dSTakashi Sakamoto strcpy(bebob->card->driver, "BeBoB"); 103fd6f4b0dSTakashi Sakamoto strcpy(bebob->card->shortname, model); 104fd6f4b0dSTakashi Sakamoto strcpy(bebob->card->mixername, model); 105fd6f4b0dSTakashi Sakamoto snprintf(bebob->card->longname, sizeof(bebob->card->longname), 106fd6f4b0dSTakashi Sakamoto "%s %s (id:%d, rev:%d), GUID %08x%08x at %s, S%d", 107fd6f4b0dSTakashi Sakamoto vendor, model, id, revision, 108fd6f4b0dSTakashi Sakamoto data[0], data[1], dev_name(&bebob->unit->device), 109fd6f4b0dSTakashi Sakamoto 100 << fw_dev->max_speed); 110fd6f4b0dSTakashi Sakamoto end: 111fd6f4b0dSTakashi Sakamoto return err; 112fd6f4b0dSTakashi Sakamoto } 113fd6f4b0dSTakashi Sakamoto 114fd6f4b0dSTakashi Sakamoto static void 115fd6f4b0dSTakashi Sakamoto bebob_card_free(struct snd_card *card) 116fd6f4b0dSTakashi Sakamoto { 117fd6f4b0dSTakashi Sakamoto struct snd_bebob *bebob = card->private_data; 118fd6f4b0dSTakashi Sakamoto 119fd6f4b0dSTakashi Sakamoto if (bebob->card_index >= 0) { 120fd6f4b0dSTakashi Sakamoto mutex_lock(&devices_mutex); 121fd6f4b0dSTakashi Sakamoto clear_bit(bebob->card_index, devices_used); 122fd6f4b0dSTakashi Sakamoto mutex_unlock(&devices_mutex); 123fd6f4b0dSTakashi Sakamoto } 124fd6f4b0dSTakashi Sakamoto 125fd6f4b0dSTakashi Sakamoto mutex_destroy(&bebob->mutex); 126fd6f4b0dSTakashi Sakamoto } 127fd6f4b0dSTakashi Sakamoto 12825784ec2STakashi Sakamoto static const struct snd_bebob_spec * 12925784ec2STakashi Sakamoto get_saffire_spec(struct fw_unit *unit) 13025784ec2STakashi Sakamoto { 13125784ec2STakashi Sakamoto char name[24] = {0}; 13225784ec2STakashi Sakamoto 13325784ec2STakashi Sakamoto if (fw_csr_string(unit->directory, CSR_MODEL, name, sizeof(name)) < 0) 13425784ec2STakashi Sakamoto return NULL; 13525784ec2STakashi Sakamoto 13625784ec2STakashi Sakamoto if (strcmp(name, "SaffireLE") == 0) 13725784ec2STakashi Sakamoto return &saffire_le_spec; 13825784ec2STakashi Sakamoto else 13925784ec2STakashi Sakamoto return &saffire_spec; 14025784ec2STakashi Sakamoto } 14125784ec2STakashi Sakamoto 142fd6f4b0dSTakashi Sakamoto static int 143fd6f4b0dSTakashi Sakamoto bebob_probe(struct fw_unit *unit, 144fd6f4b0dSTakashi Sakamoto const struct ieee1394_device_id *entry) 145fd6f4b0dSTakashi Sakamoto { 146fd6f4b0dSTakashi Sakamoto struct snd_card *card; 147fd6f4b0dSTakashi Sakamoto struct snd_bebob *bebob; 1481fc9522aSTakashi Sakamoto const struct snd_bebob_spec *spec; 149fd6f4b0dSTakashi Sakamoto unsigned int card_index; 150fd6f4b0dSTakashi Sakamoto int err; 151fd6f4b0dSTakashi Sakamoto 152fd6f4b0dSTakashi Sakamoto mutex_lock(&devices_mutex); 153fd6f4b0dSTakashi Sakamoto 154fd6f4b0dSTakashi Sakamoto for (card_index = 0; card_index < SNDRV_CARDS; card_index++) { 155fd6f4b0dSTakashi Sakamoto if (!test_bit(card_index, devices_used) && enable[card_index]) 156fd6f4b0dSTakashi Sakamoto break; 157fd6f4b0dSTakashi Sakamoto } 158fd6f4b0dSTakashi Sakamoto if (card_index >= SNDRV_CARDS) { 159fd6f4b0dSTakashi Sakamoto err = -ENOENT; 160fd6f4b0dSTakashi Sakamoto goto end; 161fd6f4b0dSTakashi Sakamoto } 162fd6f4b0dSTakashi Sakamoto 16325784ec2STakashi Sakamoto if ((entry->vendor_id == VEN_FOCUSRITE) && 16425784ec2STakashi Sakamoto (entry->model_id == MODEL_FOCUSRITE_SAFFIRE_BOTH)) 16525784ec2STakashi Sakamoto spec = get_saffire_spec(unit); 16625784ec2STakashi Sakamoto else 1671fc9522aSTakashi Sakamoto spec = (const struct snd_bebob_spec *)entry->driver_data; 1681fc9522aSTakashi Sakamoto if (spec == NULL) { 1691fc9522aSTakashi Sakamoto err = -ENOSYS; 1701fc9522aSTakashi Sakamoto goto end; 1711fc9522aSTakashi Sakamoto } 1721fc9522aSTakashi Sakamoto 173fd6f4b0dSTakashi Sakamoto err = snd_card_new(&unit->device, index[card_index], id[card_index], 174fd6f4b0dSTakashi Sakamoto THIS_MODULE, sizeof(struct snd_bebob), &card); 175fd6f4b0dSTakashi Sakamoto if (err < 0) 176fd6f4b0dSTakashi Sakamoto goto end; 177fd6f4b0dSTakashi Sakamoto bebob = card->private_data; 178fd6f4b0dSTakashi Sakamoto bebob->card_index = card_index; 179fd6f4b0dSTakashi Sakamoto set_bit(card_index, devices_used); 180fd6f4b0dSTakashi Sakamoto card->private_free = bebob_card_free; 181fd6f4b0dSTakashi Sakamoto 182fd6f4b0dSTakashi Sakamoto bebob->card = card; 183fd6f4b0dSTakashi Sakamoto bebob->unit = unit; 1841fc9522aSTakashi Sakamoto bebob->spec = spec; 185fd6f4b0dSTakashi Sakamoto mutex_init(&bebob->mutex); 186fd6f4b0dSTakashi Sakamoto spin_lock_init(&bebob->lock); 187618eabeaSTakashi Sakamoto init_waitqueue_head(&bebob->hwdep_wait); 188fd6f4b0dSTakashi Sakamoto 189fd6f4b0dSTakashi Sakamoto err = name_device(bebob, entry->vendor_id); 190fd6f4b0dSTakashi Sakamoto if (err < 0) 191fd6f4b0dSTakashi Sakamoto goto error; 192fd6f4b0dSTakashi Sakamoto 193eb7b3a05STakashi Sakamoto err = snd_bebob_stream_discover(bebob); 194fd6f4b0dSTakashi Sakamoto if (err < 0) 195fd6f4b0dSTakashi Sakamoto goto error; 196eb7b3a05STakashi Sakamoto 197ad9697baSTakashi Sakamoto snd_bebob_proc_init(bebob); 198ad9697baSTakashi Sakamoto 199248b7802STakashi Sakamoto if ((bebob->midi_input_ports > 0) || 200248b7802STakashi Sakamoto (bebob->midi_output_ports > 0)) { 201248b7802STakashi Sakamoto err = snd_bebob_create_midi_devices(bebob); 202248b7802STakashi Sakamoto if (err < 0) 203248b7802STakashi Sakamoto goto error; 204248b7802STakashi Sakamoto } 205248b7802STakashi Sakamoto 206fbbebd2cSTakashi Sakamoto err = snd_bebob_create_pcm_devices(bebob); 207fbbebd2cSTakashi Sakamoto if (err < 0) 208fbbebd2cSTakashi Sakamoto goto error; 209fbbebd2cSTakashi Sakamoto 210618eabeaSTakashi Sakamoto err = snd_bebob_create_hwdep_device(bebob); 211618eabeaSTakashi Sakamoto if (err < 0) 212618eabeaSTakashi Sakamoto goto error; 213618eabeaSTakashi Sakamoto 214eb7b3a05STakashi Sakamoto err = snd_bebob_stream_init_duplex(bebob); 215eb7b3a05STakashi Sakamoto if (err < 0) 216eb7b3a05STakashi Sakamoto goto error; 217eb7b3a05STakashi Sakamoto 218eb7b3a05STakashi Sakamoto err = snd_card_register(card); 219eb7b3a05STakashi Sakamoto if (err < 0) { 220eb7b3a05STakashi Sakamoto snd_bebob_stream_destroy_duplex(bebob); 221eb7b3a05STakashi Sakamoto goto error; 222eb7b3a05STakashi Sakamoto } 223eb7b3a05STakashi Sakamoto 224fd6f4b0dSTakashi Sakamoto dev_set_drvdata(&unit->device, bebob); 225fd6f4b0dSTakashi Sakamoto end: 226fd6f4b0dSTakashi Sakamoto mutex_unlock(&devices_mutex); 227fd6f4b0dSTakashi Sakamoto return err; 228fd6f4b0dSTakashi Sakamoto error: 229fd6f4b0dSTakashi Sakamoto mutex_unlock(&devices_mutex); 230fd6f4b0dSTakashi Sakamoto snd_card_free(card); 231fd6f4b0dSTakashi Sakamoto return err; 232fd6f4b0dSTakashi Sakamoto } 233fd6f4b0dSTakashi Sakamoto 234fd6f4b0dSTakashi Sakamoto static void 235fd6f4b0dSTakashi Sakamoto bebob_update(struct fw_unit *unit) 236fd6f4b0dSTakashi Sakamoto { 237fd6f4b0dSTakashi Sakamoto struct snd_bebob *bebob = dev_get_drvdata(&unit->device); 238fd6f4b0dSTakashi Sakamoto fcp_bus_reset(bebob->unit); 239eb7b3a05STakashi Sakamoto snd_bebob_stream_update_duplex(bebob); 240fd6f4b0dSTakashi Sakamoto } 241fd6f4b0dSTakashi Sakamoto 242fd6f4b0dSTakashi Sakamoto static void bebob_remove(struct fw_unit *unit) 243fd6f4b0dSTakashi Sakamoto { 244fd6f4b0dSTakashi Sakamoto struct snd_bebob *bebob = dev_get_drvdata(&unit->device); 245eb7b3a05STakashi Sakamoto snd_bebob_stream_destroy_duplex(bebob); 246fd6f4b0dSTakashi Sakamoto snd_card_disconnect(bebob->card); 247fd6f4b0dSTakashi Sakamoto snd_card_free_when_closed(bebob->card); 248fd6f4b0dSTakashi Sakamoto } 249fd6f4b0dSTakashi Sakamoto 2501fc9522aSTakashi Sakamoto struct snd_bebob_rate_spec normal_rate_spec = { 2511fc9522aSTakashi Sakamoto .get = &snd_bebob_stream_get_rate, 2521fc9522aSTakashi Sakamoto .set = &snd_bebob_stream_set_rate 2531fc9522aSTakashi Sakamoto }; 2541fc9522aSTakashi Sakamoto static const struct snd_bebob_spec spec_normal = { 2551fc9522aSTakashi Sakamoto .clock = NULL, 2561fc9522aSTakashi Sakamoto .rate = &normal_rate_spec, 2571fc9522aSTakashi Sakamoto .meter = NULL 2581fc9522aSTakashi Sakamoto }; 2591fc9522aSTakashi Sakamoto 260fd6f4b0dSTakashi Sakamoto static const struct ieee1394_device_id bebob_id_table[] = { 261fd6f4b0dSTakashi Sakamoto /* Edirol, FA-66 */ 2621fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_EDIROL, 0x00010049, &spec_normal), 263fd6f4b0dSTakashi Sakamoto /* Edirol, FA-101 */ 2641fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_EDIROL, 0x00010048, &spec_normal), 265fd6f4b0dSTakashi Sakamoto /* Presonus, FIREBOX */ 2661fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_PRESONUS, 0x00010000, &spec_normal), 267fd6f4b0dSTakashi Sakamoto /* PreSonus, FIREPOD/FP10 */ 2681fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_PRESONUS, 0x00010066, &spec_normal), 269fd6f4b0dSTakashi Sakamoto /* PreSonus, Inspire1394 */ 2701fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_PRESONUS, 0x00010001, &spec_normal), 271fd6f4b0dSTakashi Sakamoto /* BridgeCo, RDAudio1 */ 2721fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_BRIDGECO, 0x00010048, &spec_normal), 273fd6f4b0dSTakashi Sakamoto /* BridgeCo, Audio5 */ 2741fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_BRIDGECO, 0x00010049, &spec_normal), 275fd6f4b0dSTakashi Sakamoto /* Mackie, Onyx 1220/1620/1640 (Firewire I/O Card) */ 2761fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_MACKIE, 0x00010065, &spec_normal), 277fd6f4b0dSTakashi Sakamoto /* Mackie, d.2 (Firewire Option) */ 2781fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_MACKIE, 0x00010067, &spec_normal), 279fd6f4b0dSTakashi Sakamoto /* Stanton, ScratchAmp */ 2801fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_STANTON, 0x00000001, &spec_normal), 281fd6f4b0dSTakashi Sakamoto /* Tascam, IF-FW DM */ 2821fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_TASCAM, 0x00010067, &spec_normal), 283fd6f4b0dSTakashi Sakamoto /* Behringer, XENIX UFX 1204 */ 2841fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_BEHRINGER, 0x00001204, &spec_normal), 285fd6f4b0dSTakashi Sakamoto /* Behringer, XENIX UFX 1604 */ 2861fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_BEHRINGER, 0x00001604, &spec_normal), 287fd6f4b0dSTakashi Sakamoto /* Behringer, Digital Mixer X32 series (X-UF Card) */ 2881fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_BEHRINGER, 0x00000006, &spec_normal), 289fd6f4b0dSTakashi Sakamoto /* Apogee Electronics, Rosetta 200/400 (X-FireWire card) */ 290fd6f4b0dSTakashi Sakamoto /* Apogee Electronics, DA/AD/DD-16X (X-FireWire card) */ 2911fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_APOGEE, 0x00010048, &spec_normal), 292fd6f4b0dSTakashi Sakamoto /* Apogee Electronics, Ensemble */ 2931fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_APOGEE, 0x00001eee, &spec_normal), 294fd6f4b0dSTakashi Sakamoto /* ESI, Quatafire610 */ 2951fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_ESI, 0x00010064, &spec_normal), 296fd6f4b0dSTakashi Sakamoto /* AcousticReality, eARMasterOne */ 2971fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_ACOUSTIC, 0x00000002, &spec_normal), 298fd6f4b0dSTakashi Sakamoto /* CME, MatrixKFW */ 2991fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_CME, 0x00030000, &spec_normal), 300fd6f4b0dSTakashi Sakamoto /* Phonic, Helix Board 12 MkII */ 3011fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_PHONIC, 0x00050000, &spec_normal), 302fd6f4b0dSTakashi Sakamoto /* Phonic, Helix Board 18 MkII */ 3031fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_PHONIC, 0x00060000, &spec_normal), 304fd6f4b0dSTakashi Sakamoto /* Phonic, Helix Board 24 MkII */ 3051fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_PHONIC, 0x00070000, &spec_normal), 306fd6f4b0dSTakashi Sakamoto /* Phonic, Helix Board 12 Universal/18 Universal/24 Universal */ 3071fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_PHONIC, 0x00000000, &spec_normal), 308fd6f4b0dSTakashi Sakamoto /* Lynx, Aurora 8/16 (LT-FW) */ 3091fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_LYNX, 0x00000001, &spec_normal), 310fd6f4b0dSTakashi Sakamoto /* ICON, FireXon */ 3111fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_ICON, 0x00000001, &spec_normal), 312fd6f4b0dSTakashi Sakamoto /* PrismSound, Orpheus */ 3131fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_PRISMSOUND, 0x00010048, &spec_normal), 314fd6f4b0dSTakashi Sakamoto /* PrismSound, ADA-8XR */ 3151fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_PRISMSOUND, 0x0000ada8, &spec_normal), 316326b9cacSTakashi Sakamoto /* TerraTec Electronic GmbH, PHASE 88 Rack FW */ 317326b9cacSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_TERRATEC, 0x00000003, &phase88_rack_spec), 318326b9cacSTakashi Sakamoto /* TerraTec Electronic GmbH, PHASE 24 FW */ 319326b9cacSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_TERRATEC, 0x00000004, &phase24_series_spec), 320326b9cacSTakashi Sakamoto /* TerraTec Electronic GmbH, Phase X24 FW */ 321326b9cacSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_TERRATEC, 0x00000007, &phase24_series_spec), 322326b9cacSTakashi Sakamoto /* TerraTec Electronic GmbH, EWS MIC2/MIC8 */ 323326b9cacSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_TERRATEC, 0x00000005, &spec_normal), 324326b9cacSTakashi Sakamoto /* Terratec Electronic GmbH, Aureon 7.1 Firewire */ 325326b9cacSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_TERRATEC, 0x00000002, &spec_normal), 3268ac98a35STakashi Sakamoto /* Yamaha, GO44 */ 3278ac98a35STakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_YAMAHA, 0x0010000b, &yamaha_go_spec), 3288ac98a35STakashi Sakamoto /* YAMAHA, GO46 */ 3298ac98a35STakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_YAMAHA, 0x0010000c, &yamaha_go_spec), 33025784ec2STakashi Sakamoto /* Focusrite, SaffirePro 26 I/O */ 33125784ec2STakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_FOCUSRITE, 0x00000003, &saffirepro_26_spec), 33225784ec2STakashi Sakamoto /* Focusrite, SaffirePro 10 I/O */ 33325784ec2STakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_FOCUSRITE, 0x00000006, &saffirepro_10_spec), 33425784ec2STakashi Sakamoto /* Focusrite, Saffire(no label and LE) */ 33525784ec2STakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_FOCUSRITE, MODEL_FOCUSRITE_SAFFIRE_BOTH, 33625784ec2STakashi Sakamoto &saffire_spec), 337fd6f4b0dSTakashi Sakamoto /* IDs are unknown but able to be supported */ 338fd6f4b0dSTakashi Sakamoto /* Apogee, Mini-ME Firewire */ 339fd6f4b0dSTakashi Sakamoto /* Apogee, Mini-DAC Firewire */ 340fd6f4b0dSTakashi Sakamoto /* Behringer, F-Control Audio 1616 */ 341fd6f4b0dSTakashi Sakamoto /* Behringer, F-Control Audio 610 */ 342fd6f4b0dSTakashi Sakamoto /* Cakawalk, Sonar Power Studio 66 */ 343fd6f4b0dSTakashi Sakamoto /* CME, UF400e */ 344fd6f4b0dSTakashi Sakamoto /* ESI, Quotafire XL */ 345fd6f4b0dSTakashi Sakamoto /* Infrasonic, DewX */ 346fd6f4b0dSTakashi Sakamoto /* Infrasonic, Windy6 */ 347fd6f4b0dSTakashi Sakamoto /* Mackie, Digital X Bus x.200 */ 348fd6f4b0dSTakashi Sakamoto /* Mackie, Digital X Bus x.400 */ 349fd6f4b0dSTakashi Sakamoto /* Phonic, HB 12 */ 350fd6f4b0dSTakashi Sakamoto /* Phonic, HB 24 */ 351fd6f4b0dSTakashi Sakamoto /* Phonic, HB 18 */ 352fd6f4b0dSTakashi Sakamoto /* Phonic, FireFly 202 */ 353fd6f4b0dSTakashi Sakamoto /* Phonic, FireFly 302 */ 354fd6f4b0dSTakashi Sakamoto /* Rolf Spuler, Firewire Guitar */ 355fd6f4b0dSTakashi Sakamoto {} 356fd6f4b0dSTakashi Sakamoto }; 357fd6f4b0dSTakashi Sakamoto MODULE_DEVICE_TABLE(ieee1394, bebob_id_table); 358fd6f4b0dSTakashi Sakamoto 359fd6f4b0dSTakashi Sakamoto static struct fw_driver bebob_driver = { 360fd6f4b0dSTakashi Sakamoto .driver = { 361fd6f4b0dSTakashi Sakamoto .owner = THIS_MODULE, 362fd6f4b0dSTakashi Sakamoto .name = "snd-bebob", 363fd6f4b0dSTakashi Sakamoto .bus = &fw_bus_type, 364fd6f4b0dSTakashi Sakamoto }, 365fd6f4b0dSTakashi Sakamoto .probe = bebob_probe, 366fd6f4b0dSTakashi Sakamoto .update = bebob_update, 367fd6f4b0dSTakashi Sakamoto .remove = bebob_remove, 368fd6f4b0dSTakashi Sakamoto .id_table = bebob_id_table, 369fd6f4b0dSTakashi Sakamoto }; 370fd6f4b0dSTakashi Sakamoto 371fd6f4b0dSTakashi Sakamoto static int __init 372fd6f4b0dSTakashi Sakamoto snd_bebob_init(void) 373fd6f4b0dSTakashi Sakamoto { 374fd6f4b0dSTakashi Sakamoto return driver_register(&bebob_driver.driver); 375fd6f4b0dSTakashi Sakamoto } 376fd6f4b0dSTakashi Sakamoto 377fd6f4b0dSTakashi Sakamoto static void __exit 378fd6f4b0dSTakashi Sakamoto snd_bebob_exit(void) 379fd6f4b0dSTakashi Sakamoto { 380fd6f4b0dSTakashi Sakamoto driver_unregister(&bebob_driver.driver); 381fd6f4b0dSTakashi Sakamoto mutex_destroy(&devices_mutex); 382fd6f4b0dSTakashi Sakamoto } 383fd6f4b0dSTakashi Sakamoto 384fd6f4b0dSTakashi Sakamoto module_init(snd_bebob_init); 385fd6f4b0dSTakashi Sakamoto module_exit(snd_bebob_exit); 386