11a4e39c2STakashi Sakamoto /* 21a4e39c2STakashi Sakamoto * oxfw.c - a part of driver for OXFW970/971 based devices 31a4e39c2STakashi Sakamoto * 41a4e39c2STakashi Sakamoto * Copyright (c) Clemens Ladisch <clemens@ladisch.de> 51a4e39c2STakashi Sakamoto * Licensed under the terms of the GNU General Public License, version 2. 61a4e39c2STakashi Sakamoto */ 71a4e39c2STakashi Sakamoto 8e2786ca6STakashi Sakamoto #include "oxfw.h" 91a4e39c2STakashi Sakamoto 101a4e39c2STakashi Sakamoto #define OXFORD_FIRMWARE_ID_ADDRESS (CSR_REGISTER_BASE + 0x50000) 111a4e39c2STakashi Sakamoto /* 0x970?vvvv or 0x971?vvvv, where vvvv = firmware version */ 121a4e39c2STakashi Sakamoto 131a4e39c2STakashi Sakamoto #define OXFORD_HARDWARE_ID_ADDRESS (CSR_REGISTER_BASE + 0x90020) 141a4e39c2STakashi Sakamoto #define OXFORD_HARDWARE_ID_OXFW970 0x39443841 151a4e39c2STakashi Sakamoto #define OXFORD_HARDWARE_ID_OXFW971 0x39373100 161a4e39c2STakashi Sakamoto 17ec4dba50STakashi Sakamoto #define VENDOR_LOUD 0x000ff2 181a4e39c2STakashi Sakamoto #define VENDOR_GRIFFIN 0x001292 19ec4dba50STakashi Sakamoto #define VENDOR_BEHRINGER 0x001564 201a4e39c2STakashi Sakamoto #define VENDOR_LACIE 0x00d04b 21759a2f40STakashi Sakamoto #define VENDOR_TASCAM 0x00022e 229e2004f9STakashi Sakamoto #define OUI_STANTON 0x001260 231a4e39c2STakashi Sakamoto 2413f3a46dSTakashi Sakamoto #define MODEL_SATELLITE 0x00200f 2513f3a46dSTakashi Sakamoto 261a4e39c2STakashi Sakamoto #define SPECIFIER_1394TA 0x00a02d 271a4e39c2STakashi Sakamoto #define VERSION_AVC 0x010001 281a4e39c2STakashi Sakamoto 291a4e39c2STakashi Sakamoto MODULE_DESCRIPTION("Oxford Semiconductor FW970/971 driver"); 301a4e39c2STakashi Sakamoto MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>"); 311a4e39c2STakashi Sakamoto MODULE_LICENSE("GPL v2"); 321a4e39c2STakashi Sakamoto MODULE_ALIAS("snd-firewire-speakers"); 339e2004f9STakashi Sakamoto MODULE_ALIAS("snd-scs1x"); 341a4e39c2STakashi Sakamoto 35d6ce6bbdSTakashi Sakamoto struct compat_info { 36d6ce6bbdSTakashi Sakamoto const char *driver_name; 37d6ce6bbdSTakashi Sakamoto const char *vendor_name; 38d6ce6bbdSTakashi Sakamoto const char *model_name; 39d6ce6bbdSTakashi Sakamoto }; 40d6ce6bbdSTakashi Sakamoto 41ec4dba50STakashi Sakamoto static bool detect_loud_models(struct fw_unit *unit) 42ec4dba50STakashi Sakamoto { 43ec4dba50STakashi Sakamoto const char *const models[] = { 44ec4dba50STakashi Sakamoto "Onyxi", 45ec4dba50STakashi Sakamoto "Onyx-i", 46ec4dba50STakashi Sakamoto "d.Pro", 47ec4dba50STakashi Sakamoto "Mackie Onyx Satellite", 48ec4dba50STakashi Sakamoto "Tapco LINK.firewire 4x6", 49ec4dba50STakashi Sakamoto "U.420"}; 50ec4dba50STakashi Sakamoto char model[32]; 51ec4dba50STakashi Sakamoto unsigned int i; 52ec4dba50STakashi Sakamoto int err; 53ec4dba50STakashi Sakamoto 54ec4dba50STakashi Sakamoto err = fw_csr_string(unit->directory, CSR_MODEL, 55ec4dba50STakashi Sakamoto model, sizeof(model)); 56ec4dba50STakashi Sakamoto if (err < 0) 570d3aba30SDan Carpenter return false; 58ec4dba50STakashi Sakamoto 59ec4dba50STakashi Sakamoto for (i = 0; i < ARRAY_SIZE(models); i++) { 60ec4dba50STakashi Sakamoto if (strcmp(models[i], model) == 0) 61ec4dba50STakashi Sakamoto break; 62ec4dba50STakashi Sakamoto } 63ec4dba50STakashi Sakamoto 64ec4dba50STakashi Sakamoto return (i < ARRAY_SIZE(models)); 65ec4dba50STakashi Sakamoto } 66ec4dba50STakashi Sakamoto 67fec7b753STakashi Sakamoto static int name_card(struct snd_oxfw *oxfw) 681a4e39c2STakashi Sakamoto { 69fec7b753STakashi Sakamoto struct fw_device *fw_dev = fw_parent_device(oxfw->unit); 70d6ce6bbdSTakashi Sakamoto const struct compat_info *info; 71ec4dba50STakashi Sakamoto char vendor[24]; 72ec4dba50STakashi Sakamoto char model[32]; 73fec7b753STakashi Sakamoto const char *d, *v, *m; 74fec7b753STakashi Sakamoto u32 firmware; 751a4e39c2STakashi Sakamoto int err; 761a4e39c2STakashi Sakamoto 77ec4dba50STakashi Sakamoto /* get vendor name from root directory */ 78ec4dba50STakashi Sakamoto err = fw_csr_string(fw_dev->config_rom + 5, CSR_VENDOR, 79ec4dba50STakashi Sakamoto vendor, sizeof(vendor)); 80ec4dba50STakashi Sakamoto if (err < 0) 81ec4dba50STakashi Sakamoto goto end; 82ec4dba50STakashi Sakamoto 83ec4dba50STakashi Sakamoto /* get model name from unit directory */ 84ec4dba50STakashi Sakamoto err = fw_csr_string(oxfw->unit->directory, CSR_MODEL, 85ec4dba50STakashi Sakamoto model, sizeof(model)); 86ec4dba50STakashi Sakamoto if (err < 0) 87ec4dba50STakashi Sakamoto goto end; 88ec4dba50STakashi Sakamoto 89fec7b753STakashi Sakamoto err = snd_fw_transaction(oxfw->unit, TCODE_READ_QUADLET_REQUEST, 90fec7b753STakashi Sakamoto OXFORD_FIRMWARE_ID_ADDRESS, &firmware, 4, 0); 91fec7b753STakashi Sakamoto if (err < 0) 92fec7b753STakashi Sakamoto goto end; 93fec7b753STakashi Sakamoto be32_to_cpus(&firmware); 94fec7b753STakashi Sakamoto 95ec4dba50STakashi Sakamoto /* to apply card definitions */ 9627e66635STakashi Sakamoto if (oxfw->entry->vendor_id == VENDOR_GRIFFIN || 9727e66635STakashi Sakamoto oxfw->entry->vendor_id == VENDOR_LACIE) { 98d6ce6bbdSTakashi Sakamoto info = (const struct compat_info *)oxfw->entry->driver_data; 9927e66635STakashi Sakamoto d = info->driver_name; 10027e66635STakashi Sakamoto v = info->vendor_name; 10127e66635STakashi Sakamoto m = info->model_name; 102ec4dba50STakashi Sakamoto } else { 103ec4dba50STakashi Sakamoto d = "OXFW"; 104ec4dba50STakashi Sakamoto v = vendor; 105ec4dba50STakashi Sakamoto m = model; 106ec4dba50STakashi Sakamoto } 107fec7b753STakashi Sakamoto 108fec7b753STakashi Sakamoto strcpy(oxfw->card->driver, d); 109fec7b753STakashi Sakamoto strcpy(oxfw->card->mixername, m); 110fec7b753STakashi Sakamoto strcpy(oxfw->card->shortname, m); 111fec7b753STakashi Sakamoto 112fec7b753STakashi Sakamoto snprintf(oxfw->card->longname, sizeof(oxfw->card->longname), 113fec7b753STakashi Sakamoto "%s %s (OXFW%x %04x), GUID %08x%08x at %s, S%d", 114fec7b753STakashi Sakamoto v, m, firmware >> 20, firmware & 0xffff, 115fec7b753STakashi Sakamoto fw_dev->config_rom[3], fw_dev->config_rom[4], 116fec7b753STakashi Sakamoto dev_name(&oxfw->unit->device), 100 << fw_dev->max_speed); 117fec7b753STakashi Sakamoto end: 118fec7b753STakashi Sakamoto return err; 1191a4e39c2STakashi Sakamoto } 1201a4e39c2STakashi Sakamoto 1216c29230eSTakashi Sakamoto static void oxfw_free(struct snd_oxfw *oxfw) 1221a4e39c2STakashi Sakamoto { 1235cd1d3f4STakashi Sakamoto unsigned int i; 1245cd1d3f4STakashi Sakamoto 125dec84316STakashi Sakamoto snd_oxfw_stream_destroy_simplex(oxfw, &oxfw->rx_stream); 126dec84316STakashi Sakamoto if (oxfw->has_output) 127dec84316STakashi Sakamoto snd_oxfw_stream_destroy_simplex(oxfw, &oxfw->tx_stream); 128dec84316STakashi Sakamoto 12912ed7192STakashi Sakamoto fw_unit_put(oxfw->unit); 13012ed7192STakashi Sakamoto 131b0ac0009STakashi Sakamoto for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++) { 132b0ac0009STakashi Sakamoto kfree(oxfw->tx_stream_formats[i]); 1335cd1d3f4STakashi Sakamoto kfree(oxfw->rx_stream_formats[i]); 134b0ac0009STakashi Sakamoto } 1351a4e39c2STakashi Sakamoto 136c582cc66STakashi Sakamoto kfree(oxfw->spec); 1371a4e39c2STakashi Sakamoto mutex_destroy(&oxfw->mutex); 1381a4e39c2STakashi Sakamoto } 1391a4e39c2STakashi Sakamoto 1406c29230eSTakashi Sakamoto /* 1416c29230eSTakashi Sakamoto * This module releases the FireWire unit data after all ALSA character devices 1426c29230eSTakashi Sakamoto * are released by applications. This is for releasing stream data or finishing 1436c29230eSTakashi Sakamoto * transactions safely. Thus at returning from .remove(), this module still keep 1446c29230eSTakashi Sakamoto * references for the unit. 1456c29230eSTakashi Sakamoto */ 1466c29230eSTakashi Sakamoto static void oxfw_card_free(struct snd_card *card) 1476c29230eSTakashi Sakamoto { 1486c29230eSTakashi Sakamoto oxfw_free(card->private_data); 1496c29230eSTakashi Sakamoto } 1506c29230eSTakashi Sakamoto 1515ce8cc48STakashi Sakamoto static int detect_quirks(struct snd_oxfw *oxfw) 15213f3a46dSTakashi Sakamoto { 15313f3a46dSTakashi Sakamoto struct fw_device *fw_dev = fw_parent_device(oxfw->unit); 15413f3a46dSTakashi Sakamoto struct fw_csr_iterator it; 15513f3a46dSTakashi Sakamoto int key, val; 15613f3a46dSTakashi Sakamoto int vendor, model; 15713f3a46dSTakashi Sakamoto 15827e66635STakashi Sakamoto /* 1595ce8cc48STakashi Sakamoto * Add ALSA control elements for two models to keep compatibility to 1605ce8cc48STakashi Sakamoto * old firewire-speaker module. 1615ce8cc48STakashi Sakamoto */ 1623e2f4570STakashi Sakamoto if (oxfw->entry->vendor_id == VENDOR_GRIFFIN) 1633e2f4570STakashi Sakamoto return snd_oxfw_add_spkr(oxfw, false); 1643e2f4570STakashi Sakamoto if (oxfw->entry->vendor_id == VENDOR_LACIE) 1653e2f4570STakashi Sakamoto return snd_oxfw_add_spkr(oxfw, true); 1665ce8cc48STakashi Sakamoto 1675ce8cc48STakashi Sakamoto /* 1689e2004f9STakashi Sakamoto * Stanton models supports asynchronous transactions for unique MIDI 1699e2004f9STakashi Sakamoto * messages. 1709e2004f9STakashi Sakamoto */ 171de5126ccSTakashi Sakamoto if (oxfw->entry->vendor_id == OUI_STANTON) { 172de5126ccSTakashi Sakamoto /* No physical MIDI ports. */ 173de5126ccSTakashi Sakamoto oxfw->midi_input_ports = 0; 174de5126ccSTakashi Sakamoto oxfw->midi_output_ports = 0; 175de5126ccSTakashi Sakamoto 176de5126ccSTakashi Sakamoto /* Output stream exists but no data channels are useful. */ 177de5126ccSTakashi Sakamoto oxfw->has_output = false; 178de5126ccSTakashi Sakamoto 1799e2004f9STakashi Sakamoto return snd_oxfw_scs1x_add(oxfw); 180de5126ccSTakashi Sakamoto } 1819e2004f9STakashi Sakamoto 1829e2004f9STakashi Sakamoto /* 18327e66635STakashi Sakamoto * TASCAM FireOne has physical control and requires a pair of additional 18427e66635STakashi Sakamoto * MIDI ports. 18527e66635STakashi Sakamoto */ 18627e66635STakashi Sakamoto if (oxfw->entry->vendor_id == VENDOR_TASCAM) { 18727e66635STakashi Sakamoto oxfw->midi_input_ports++; 18827e66635STakashi Sakamoto oxfw->midi_output_ports++; 1895ce8cc48STakashi Sakamoto return 0; 19027e66635STakashi Sakamoto } 19127e66635STakashi Sakamoto 19213f3a46dSTakashi Sakamoto /* Seek from Root Directory of Config ROM. */ 19313f3a46dSTakashi Sakamoto vendor = model = 0; 19413f3a46dSTakashi Sakamoto fw_csr_iterator_init(&it, fw_dev->config_rom + 5); 19513f3a46dSTakashi Sakamoto while (fw_csr_iterator_next(&it, &key, &val)) { 19613f3a46dSTakashi Sakamoto if (key == CSR_VENDOR) 19713f3a46dSTakashi Sakamoto vendor = val; 19813f3a46dSTakashi Sakamoto else if (key == CSR_MODEL) 19913f3a46dSTakashi Sakamoto model = val; 20013f3a46dSTakashi Sakamoto } 20113f3a46dSTakashi Sakamoto 20213f3a46dSTakashi Sakamoto /* 20313f3a46dSTakashi Sakamoto * Mackie Onyx Satellite with base station has a quirk to report a wrong 20413f3a46dSTakashi Sakamoto * value in 'dbs' field of CIP header against its format information. 20513f3a46dSTakashi Sakamoto */ 20613f3a46dSTakashi Sakamoto if (vendor == VENDOR_LOUD && model == MODEL_SATELLITE) 20713f3a46dSTakashi Sakamoto oxfw->wrong_dbs = true; 2085ce8cc48STakashi Sakamoto 2095ce8cc48STakashi Sakamoto return 0; 21013f3a46dSTakashi Sakamoto } 21113f3a46dSTakashi Sakamoto 2126c29230eSTakashi Sakamoto static void do_registration(struct work_struct *work) 2131a4e39c2STakashi Sakamoto { 2146c29230eSTakashi Sakamoto struct snd_oxfw *oxfw = container_of(work, struct snd_oxfw, dwork.work); 2151a4e39c2STakashi Sakamoto int err; 2161a4e39c2STakashi Sakamoto 2176c29230eSTakashi Sakamoto if (oxfw->registered) 2186c29230eSTakashi Sakamoto return; 219ec4dba50STakashi Sakamoto 2206c29230eSTakashi Sakamoto err = snd_card_new(&oxfw->unit->device, -1, NULL, THIS_MODULE, 0, 2216c29230eSTakashi Sakamoto &oxfw->card); 2221a4e39c2STakashi Sakamoto if (err < 0) 2236c29230eSTakashi Sakamoto return; 2245cd1d3f4STakashi Sakamoto 2253f47152aSTakashi Sakamoto err = name_card(oxfw); 2265ce8cc48STakashi Sakamoto if (err < 0) 2275ce8cc48STakashi Sakamoto goto error; 22813f3a46dSTakashi Sakamoto 2293f47152aSTakashi Sakamoto err = detect_quirks(oxfw); 230fec7b753STakashi Sakamoto if (err < 0) 231fec7b753STakashi Sakamoto goto error; 2321a4e39c2STakashi Sakamoto 2336c29230eSTakashi Sakamoto err = snd_oxfw_stream_discover(oxfw); 2346c29230eSTakashi Sakamoto if (err < 0) 2356c29230eSTakashi Sakamoto goto error; 2366c29230eSTakashi Sakamoto 2376c29230eSTakashi Sakamoto err = snd_oxfw_stream_init_simplex(oxfw, &oxfw->rx_stream); 2386c29230eSTakashi Sakamoto if (err < 0) 2396c29230eSTakashi Sakamoto goto error; 2406c29230eSTakashi Sakamoto if (oxfw->has_output) { 2416c29230eSTakashi Sakamoto err = snd_oxfw_stream_init_simplex(oxfw, &oxfw->tx_stream); 2426c29230eSTakashi Sakamoto if (err < 0) 2436c29230eSTakashi Sakamoto goto error; 2446c29230eSTakashi Sakamoto } 2456c29230eSTakashi Sakamoto 2463713d93aSTakashi Sakamoto err = snd_oxfw_create_pcm(oxfw); 2471a4e39c2STakashi Sakamoto if (err < 0) 2481a4e39c2STakashi Sakamoto goto error; 2491a4e39c2STakashi Sakamoto 2503c96101fSTakashi Sakamoto snd_oxfw_proc_init(oxfw); 2513c96101fSTakashi Sakamoto 25205588d34STakashi Sakamoto err = snd_oxfw_create_midi(oxfw); 25305588d34STakashi Sakamoto if (err < 0) 25405588d34STakashi Sakamoto goto error; 25505588d34STakashi Sakamoto 2568985f4acSTakashi Sakamoto err = snd_oxfw_create_hwdep(oxfw); 2578985f4acSTakashi Sakamoto if (err < 0) 2588985f4acSTakashi Sakamoto goto error; 2598985f4acSTakashi Sakamoto 2606c29230eSTakashi Sakamoto err = snd_card_register(oxfw->card); 2611a4e39c2STakashi Sakamoto if (err < 0) 2621a4e39c2STakashi Sakamoto goto error; 2631a4e39c2STakashi Sakamoto 2646c29230eSTakashi Sakamoto /* 2656c29230eSTakashi Sakamoto * After registered, oxfw instance can be released corresponding to 2666c29230eSTakashi Sakamoto * releasing the sound card instance. 2676c29230eSTakashi Sakamoto */ 2686c29230eSTakashi Sakamoto oxfw->card->private_free = oxfw_card_free; 2696c29230eSTakashi Sakamoto oxfw->card->private_data = oxfw; 2706c29230eSTakashi Sakamoto oxfw->registered = true; 2716c29230eSTakashi Sakamoto 2726c29230eSTakashi Sakamoto return; 2736c29230eSTakashi Sakamoto error: 274b0ac0009STakashi Sakamoto snd_oxfw_stream_destroy_simplex(oxfw, &oxfw->rx_stream); 275b0ac0009STakashi Sakamoto if (oxfw->has_output) 276b0ac0009STakashi Sakamoto snd_oxfw_stream_destroy_simplex(oxfw, &oxfw->tx_stream); 2776c29230eSTakashi Sakamoto snd_card_free(oxfw->card); 2786c29230eSTakashi Sakamoto dev_info(&oxfw->unit->device, 2796c29230eSTakashi Sakamoto "Sound card registration failed: %d\n", err); 280e2786ca6STakashi Sakamoto } 2816c29230eSTakashi Sakamoto 2826c29230eSTakashi Sakamoto static int oxfw_probe(struct fw_unit *unit, 2836c29230eSTakashi Sakamoto const struct ieee1394_device_id *entry) 2846c29230eSTakashi Sakamoto { 2856c29230eSTakashi Sakamoto struct snd_oxfw *oxfw; 2866c29230eSTakashi Sakamoto 2876c29230eSTakashi Sakamoto if (entry->vendor_id == VENDOR_LOUD && !detect_loud_models(unit)) 2886c29230eSTakashi Sakamoto return -ENODEV; 2896c29230eSTakashi Sakamoto 2906c29230eSTakashi Sakamoto /* Allocate this independent of sound card instance. */ 2916c29230eSTakashi Sakamoto oxfw = kzalloc(sizeof(struct snd_oxfw), GFP_KERNEL); 2926c29230eSTakashi Sakamoto if (oxfw == NULL) 2936c29230eSTakashi Sakamoto return -ENOMEM; 2946c29230eSTakashi Sakamoto 2956c29230eSTakashi Sakamoto oxfw->entry = entry; 2966c29230eSTakashi Sakamoto oxfw->unit = fw_unit_get(unit); 2971a4e39c2STakashi Sakamoto dev_set_drvdata(&unit->device, oxfw); 2981a4e39c2STakashi Sakamoto 2996c29230eSTakashi Sakamoto mutex_init(&oxfw->mutex); 3006c29230eSTakashi Sakamoto spin_lock_init(&oxfw->lock); 3016c29230eSTakashi Sakamoto init_waitqueue_head(&oxfw->hwdep_wait); 3026c29230eSTakashi Sakamoto 3036c29230eSTakashi Sakamoto /* Allocate and register this sound card later. */ 3046c29230eSTakashi Sakamoto INIT_DEFERRABLE_WORK(&oxfw->dwork, do_registration); 3056c29230eSTakashi Sakamoto snd_fw_schedule_registration(unit, &oxfw->dwork); 3066c29230eSTakashi Sakamoto 3071a4e39c2STakashi Sakamoto return 0; 3081a4e39c2STakashi Sakamoto } 3091a4e39c2STakashi Sakamoto 3101a4e39c2STakashi Sakamoto static void oxfw_bus_reset(struct fw_unit *unit) 3111a4e39c2STakashi Sakamoto { 3121a4e39c2STakashi Sakamoto struct snd_oxfw *oxfw = dev_get_drvdata(&unit->device); 3131a4e39c2STakashi Sakamoto 3146c29230eSTakashi Sakamoto if (!oxfw->registered) 3156c29230eSTakashi Sakamoto snd_fw_schedule_registration(unit, &oxfw->dwork); 3166c29230eSTakashi Sakamoto 3171a4e39c2STakashi Sakamoto fcp_bus_reset(oxfw->unit); 3181a4e39c2STakashi Sakamoto 3196c29230eSTakashi Sakamoto if (oxfw->registered) { 3201a4e39c2STakashi Sakamoto mutex_lock(&oxfw->mutex); 321b0ac0009STakashi Sakamoto 322b0ac0009STakashi Sakamoto snd_oxfw_stream_update_simplex(oxfw, &oxfw->rx_stream); 323b0ac0009STakashi Sakamoto if (oxfw->has_output) 324b0ac0009STakashi Sakamoto snd_oxfw_stream_update_simplex(oxfw, &oxfw->tx_stream); 325b0ac0009STakashi Sakamoto 3261a4e39c2STakashi Sakamoto mutex_unlock(&oxfw->mutex); 3279e2004f9STakashi Sakamoto 3289e2004f9STakashi Sakamoto if (oxfw->entry->vendor_id == OUI_STANTON) 3299e2004f9STakashi Sakamoto snd_oxfw_scs1x_update(oxfw); 3301a4e39c2STakashi Sakamoto } 3316c29230eSTakashi Sakamoto } 3321a4e39c2STakashi Sakamoto 3331a4e39c2STakashi Sakamoto static void oxfw_remove(struct fw_unit *unit) 3341a4e39c2STakashi Sakamoto { 3351a4e39c2STakashi Sakamoto struct snd_oxfw *oxfw = dev_get_drvdata(&unit->device); 3361a4e39c2STakashi Sakamoto 3376c29230eSTakashi Sakamoto /* 3386c29230eSTakashi Sakamoto * Confirm to stop the work for registration before the sound card is 3396c29230eSTakashi Sakamoto * going to be released. The work is not scheduled again because bus 3406c29230eSTakashi Sakamoto * reset handler is not called anymore. 3416c29230eSTakashi Sakamoto */ 3426c29230eSTakashi Sakamoto cancel_delayed_work_sync(&oxfw->dwork); 3436c29230eSTakashi Sakamoto 3446c29230eSTakashi Sakamoto if (oxfw->registered) { 34512ed7192STakashi Sakamoto /* No need to wait for releasing card object in this context. */ 3461a4e39c2STakashi Sakamoto snd_card_free_when_closed(oxfw->card); 3476c29230eSTakashi Sakamoto } else { 3486c29230eSTakashi Sakamoto /* Don't forget this case. */ 3496c29230eSTakashi Sakamoto oxfw_free(oxfw); 3506c29230eSTakashi Sakamoto } 3511a4e39c2STakashi Sakamoto } 3521a4e39c2STakashi Sakamoto 353d6ce6bbdSTakashi Sakamoto static const struct compat_info griffin_firewave = { 3541a4e39c2STakashi Sakamoto .driver_name = "FireWave", 355fec7b753STakashi Sakamoto .vendor_name = "Griffin", 356fec7b753STakashi Sakamoto .model_name = "FireWave", 3571a4e39c2STakashi Sakamoto }; 3581a4e39c2STakashi Sakamoto 359d6ce6bbdSTakashi Sakamoto static const struct compat_info lacie_speakers = { 3601a4e39c2STakashi Sakamoto .driver_name = "FWSpeakers", 361fec7b753STakashi Sakamoto .vendor_name = "LaCie", 362fec7b753STakashi Sakamoto .model_name = "FireWire Speakers", 3631a4e39c2STakashi Sakamoto }; 3641a4e39c2STakashi Sakamoto 3651a4e39c2STakashi Sakamoto static const struct ieee1394_device_id oxfw_id_table[] = { 3661a4e39c2STakashi Sakamoto { 3671a4e39c2STakashi Sakamoto .match_flags = IEEE1394_MATCH_VENDOR_ID | 3681a4e39c2STakashi Sakamoto IEEE1394_MATCH_MODEL_ID | 3691a4e39c2STakashi Sakamoto IEEE1394_MATCH_SPECIFIER_ID | 3701a4e39c2STakashi Sakamoto IEEE1394_MATCH_VERSION, 3711a4e39c2STakashi Sakamoto .vendor_id = VENDOR_GRIFFIN, 3721a4e39c2STakashi Sakamoto .model_id = 0x00f970, 3731a4e39c2STakashi Sakamoto .specifier_id = SPECIFIER_1394TA, 3741a4e39c2STakashi Sakamoto .version = VERSION_AVC, 3751a4e39c2STakashi Sakamoto .driver_data = (kernel_ulong_t)&griffin_firewave, 3761a4e39c2STakashi Sakamoto }, 3771a4e39c2STakashi Sakamoto { 3781a4e39c2STakashi Sakamoto .match_flags = IEEE1394_MATCH_VENDOR_ID | 3791a4e39c2STakashi Sakamoto IEEE1394_MATCH_MODEL_ID | 3801a4e39c2STakashi Sakamoto IEEE1394_MATCH_SPECIFIER_ID | 3811a4e39c2STakashi Sakamoto IEEE1394_MATCH_VERSION, 3821a4e39c2STakashi Sakamoto .vendor_id = VENDOR_LACIE, 3831a4e39c2STakashi Sakamoto .model_id = 0x00f970, 3841a4e39c2STakashi Sakamoto .specifier_id = SPECIFIER_1394TA, 3851a4e39c2STakashi Sakamoto .version = VERSION_AVC, 3861a4e39c2STakashi Sakamoto .driver_data = (kernel_ulong_t)&lacie_speakers, 3871a4e39c2STakashi Sakamoto }, 388ec4dba50STakashi Sakamoto /* Behringer,F-Control Audio 202 */ 389ec4dba50STakashi Sakamoto { 390ec4dba50STakashi Sakamoto .match_flags = IEEE1394_MATCH_VENDOR_ID | 391ec4dba50STakashi Sakamoto IEEE1394_MATCH_MODEL_ID, 392ec4dba50STakashi Sakamoto .vendor_id = VENDOR_BEHRINGER, 393ec4dba50STakashi Sakamoto .model_id = 0x00fc22, 394ec4dba50STakashi Sakamoto }, 395ec4dba50STakashi Sakamoto /* 396ec4dba50STakashi Sakamoto * Any Mackie(Loud) models (name string/model id): 397ec4dba50STakashi Sakamoto * Onyx-i series (former models): 0x081216 398ec4dba50STakashi Sakamoto * Mackie Onyx Satellite: 0x00200f 399ec4dba50STakashi Sakamoto * Tapco LINK.firewire 4x6: 0x000460 400ec4dba50STakashi Sakamoto * d.2 pro: Unknown 401ec4dba50STakashi Sakamoto * d.4 pro: Unknown 402ec4dba50STakashi Sakamoto * U.420: Unknown 403ec4dba50STakashi Sakamoto * U.420d: Unknown 404ec4dba50STakashi Sakamoto */ 405ec4dba50STakashi Sakamoto { 406ec4dba50STakashi Sakamoto .match_flags = IEEE1394_MATCH_VENDOR_ID | 407ec4dba50STakashi Sakamoto IEEE1394_MATCH_SPECIFIER_ID | 408ec4dba50STakashi Sakamoto IEEE1394_MATCH_VERSION, 409ec4dba50STakashi Sakamoto .vendor_id = VENDOR_LOUD, 410ec4dba50STakashi Sakamoto .specifier_id = SPECIFIER_1394TA, 411ec4dba50STakashi Sakamoto .version = VERSION_AVC, 412ec4dba50STakashi Sakamoto }, 413759a2f40STakashi Sakamoto /* TASCAM, FireOne */ 414759a2f40STakashi Sakamoto { 415759a2f40STakashi Sakamoto .match_flags = IEEE1394_MATCH_VENDOR_ID | 416759a2f40STakashi Sakamoto IEEE1394_MATCH_MODEL_ID, 417759a2f40STakashi Sakamoto .vendor_id = VENDOR_TASCAM, 418759a2f40STakashi Sakamoto .model_id = 0x800007, 419759a2f40STakashi Sakamoto }, 4209e2004f9STakashi Sakamoto /* Stanton, Stanton Controllers & Systems 1 Mixer (SCS.1m) */ 4219e2004f9STakashi Sakamoto { 4229e2004f9STakashi Sakamoto .match_flags = IEEE1394_MATCH_VENDOR_ID | 4239e2004f9STakashi Sakamoto IEEE1394_MATCH_MODEL_ID, 4249e2004f9STakashi Sakamoto .vendor_id = OUI_STANTON, 4259e2004f9STakashi Sakamoto .model_id = 0x001000, 4269e2004f9STakashi Sakamoto }, 4279e2004f9STakashi Sakamoto /* Stanton, Stanton Controllers & Systems 1 Deck (SCS.1d) */ 4289e2004f9STakashi Sakamoto { 4299e2004f9STakashi Sakamoto .match_flags = IEEE1394_MATCH_VENDOR_ID | 4309e2004f9STakashi Sakamoto IEEE1394_MATCH_MODEL_ID, 4319e2004f9STakashi Sakamoto .vendor_id = OUI_STANTON, 4329e2004f9STakashi Sakamoto .model_id = 0x002000, 4339e2004f9STakashi Sakamoto }, 4341a4e39c2STakashi Sakamoto { } 4351a4e39c2STakashi Sakamoto }; 4361a4e39c2STakashi Sakamoto MODULE_DEVICE_TABLE(ieee1394, oxfw_id_table); 4371a4e39c2STakashi Sakamoto 4381a4e39c2STakashi Sakamoto static struct fw_driver oxfw_driver = { 4391a4e39c2STakashi Sakamoto .driver = { 4401a4e39c2STakashi Sakamoto .owner = THIS_MODULE, 4411a4e39c2STakashi Sakamoto .name = KBUILD_MODNAME, 4421a4e39c2STakashi Sakamoto .bus = &fw_bus_type, 4431a4e39c2STakashi Sakamoto }, 4441a4e39c2STakashi Sakamoto .probe = oxfw_probe, 4451a4e39c2STakashi Sakamoto .update = oxfw_bus_reset, 4461a4e39c2STakashi Sakamoto .remove = oxfw_remove, 4471a4e39c2STakashi Sakamoto .id_table = oxfw_id_table, 4481a4e39c2STakashi Sakamoto }; 4491a4e39c2STakashi Sakamoto 4501a4e39c2STakashi Sakamoto static int __init snd_oxfw_init(void) 4511a4e39c2STakashi Sakamoto { 4521a4e39c2STakashi Sakamoto return driver_register(&oxfw_driver.driver); 4531a4e39c2STakashi Sakamoto } 4541a4e39c2STakashi Sakamoto 4551a4e39c2STakashi Sakamoto static void __exit snd_oxfw_exit(void) 4561a4e39c2STakashi Sakamoto { 4571a4e39c2STakashi Sakamoto driver_unregister(&oxfw_driver.driver); 4581a4e39c2STakashi Sakamoto } 4591a4e39c2STakashi Sakamoto 4601a4e39c2STakashi Sakamoto module_init(snd_oxfw_init); 4611a4e39c2STakashi Sakamoto module_exit(snd_oxfw_exit); 462