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", 4603abd33aSTakashi Sakamoto "Onyx 1640i", 47ec4dba50STakashi Sakamoto "d.Pro", 48ec4dba50STakashi Sakamoto "Mackie Onyx Satellite", 49ec4dba50STakashi Sakamoto "Tapco LINK.firewire 4x6", 50ec4dba50STakashi Sakamoto "U.420"}; 51ec4dba50STakashi Sakamoto char model[32]; 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 592cc47d31SYisheng Xie return match_string(models, ARRAY_SIZE(models), model) >= 0; 60ec4dba50STakashi Sakamoto } 61ec4dba50STakashi Sakamoto 62fec7b753STakashi Sakamoto static int name_card(struct snd_oxfw *oxfw) 631a4e39c2STakashi Sakamoto { 64fec7b753STakashi Sakamoto struct fw_device *fw_dev = fw_parent_device(oxfw->unit); 65d6ce6bbdSTakashi Sakamoto const struct compat_info *info; 66ec4dba50STakashi Sakamoto char vendor[24]; 67ec4dba50STakashi Sakamoto char model[32]; 68fec7b753STakashi Sakamoto const char *d, *v, *m; 69fec7b753STakashi Sakamoto u32 firmware; 701a4e39c2STakashi Sakamoto int err; 711a4e39c2STakashi Sakamoto 72ec4dba50STakashi Sakamoto /* get vendor name from root directory */ 73ec4dba50STakashi Sakamoto err = fw_csr_string(fw_dev->config_rom + 5, CSR_VENDOR, 74ec4dba50STakashi Sakamoto vendor, sizeof(vendor)); 75ec4dba50STakashi Sakamoto if (err < 0) 76ec4dba50STakashi Sakamoto goto end; 77ec4dba50STakashi Sakamoto 78ec4dba50STakashi Sakamoto /* get model name from unit directory */ 79ec4dba50STakashi Sakamoto err = fw_csr_string(oxfw->unit->directory, CSR_MODEL, 80ec4dba50STakashi Sakamoto model, sizeof(model)); 81ec4dba50STakashi Sakamoto if (err < 0) 82ec4dba50STakashi Sakamoto goto end; 83ec4dba50STakashi Sakamoto 84fec7b753STakashi Sakamoto err = snd_fw_transaction(oxfw->unit, TCODE_READ_QUADLET_REQUEST, 85fec7b753STakashi Sakamoto OXFORD_FIRMWARE_ID_ADDRESS, &firmware, 4, 0); 86fec7b753STakashi Sakamoto if (err < 0) 87fec7b753STakashi Sakamoto goto end; 88fec7b753STakashi Sakamoto be32_to_cpus(&firmware); 89fec7b753STakashi Sakamoto 90ec4dba50STakashi Sakamoto /* to apply card definitions */ 9127e66635STakashi Sakamoto if (oxfw->entry->vendor_id == VENDOR_GRIFFIN || 9227e66635STakashi Sakamoto oxfw->entry->vendor_id == VENDOR_LACIE) { 93d6ce6bbdSTakashi Sakamoto info = (const struct compat_info *)oxfw->entry->driver_data; 9427e66635STakashi Sakamoto d = info->driver_name; 9527e66635STakashi Sakamoto v = info->vendor_name; 9627e66635STakashi Sakamoto m = info->model_name; 97ec4dba50STakashi Sakamoto } else { 98ec4dba50STakashi Sakamoto d = "OXFW"; 99ec4dba50STakashi Sakamoto v = vendor; 100ec4dba50STakashi Sakamoto m = model; 101ec4dba50STakashi Sakamoto } 102fec7b753STakashi Sakamoto 103fec7b753STakashi Sakamoto strcpy(oxfw->card->driver, d); 104fec7b753STakashi Sakamoto strcpy(oxfw->card->mixername, m); 105fec7b753STakashi Sakamoto strcpy(oxfw->card->shortname, m); 106fec7b753STakashi Sakamoto 107fec7b753STakashi Sakamoto snprintf(oxfw->card->longname, sizeof(oxfw->card->longname), 108fec7b753STakashi Sakamoto "%s %s (OXFW%x %04x), GUID %08x%08x at %s, S%d", 109fec7b753STakashi Sakamoto v, m, firmware >> 20, firmware & 0xffff, 110fec7b753STakashi Sakamoto fw_dev->config_rom[3], fw_dev->config_rom[4], 111fec7b753STakashi Sakamoto dev_name(&oxfw->unit->device), 100 << fw_dev->max_speed); 112fec7b753STakashi Sakamoto end: 113fec7b753STakashi Sakamoto return err; 1141a4e39c2STakashi Sakamoto } 1151a4e39c2STakashi Sakamoto 1166c29230eSTakashi Sakamoto static void oxfw_free(struct snd_oxfw *oxfw) 1171a4e39c2STakashi Sakamoto { 1185cd1d3f4STakashi Sakamoto unsigned int i; 1195cd1d3f4STakashi Sakamoto 120dec84316STakashi Sakamoto snd_oxfw_stream_destroy_simplex(oxfw, &oxfw->rx_stream); 121dec84316STakashi Sakamoto if (oxfw->has_output) 122dec84316STakashi Sakamoto snd_oxfw_stream_destroy_simplex(oxfw, &oxfw->tx_stream); 123dec84316STakashi Sakamoto 12412ed7192STakashi Sakamoto fw_unit_put(oxfw->unit); 12512ed7192STakashi Sakamoto 126b0ac0009STakashi Sakamoto for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++) { 127b0ac0009STakashi Sakamoto kfree(oxfw->tx_stream_formats[i]); 1285cd1d3f4STakashi Sakamoto kfree(oxfw->rx_stream_formats[i]); 129b0ac0009STakashi Sakamoto } 1301a4e39c2STakashi Sakamoto 131c582cc66STakashi Sakamoto kfree(oxfw->spec); 1321a4e39c2STakashi Sakamoto mutex_destroy(&oxfw->mutex); 1331a4e39c2STakashi Sakamoto } 1341a4e39c2STakashi Sakamoto 1356c29230eSTakashi Sakamoto /* 1366c29230eSTakashi Sakamoto * This module releases the FireWire unit data after all ALSA character devices 1376c29230eSTakashi Sakamoto * are released by applications. This is for releasing stream data or finishing 1386c29230eSTakashi Sakamoto * transactions safely. Thus at returning from .remove(), this module still keep 1396c29230eSTakashi Sakamoto * references for the unit. 1406c29230eSTakashi Sakamoto */ 1416c29230eSTakashi Sakamoto static void oxfw_card_free(struct snd_card *card) 1426c29230eSTakashi Sakamoto { 1436c29230eSTakashi Sakamoto oxfw_free(card->private_data); 1446c29230eSTakashi Sakamoto } 1456c29230eSTakashi Sakamoto 1465ce8cc48STakashi Sakamoto static int detect_quirks(struct snd_oxfw *oxfw) 14713f3a46dSTakashi Sakamoto { 14813f3a46dSTakashi Sakamoto struct fw_device *fw_dev = fw_parent_device(oxfw->unit); 14913f3a46dSTakashi Sakamoto struct fw_csr_iterator it; 15013f3a46dSTakashi Sakamoto int key, val; 15113f3a46dSTakashi Sakamoto int vendor, model; 15213f3a46dSTakashi Sakamoto 15327e66635STakashi Sakamoto /* 1545ce8cc48STakashi Sakamoto * Add ALSA control elements for two models to keep compatibility to 1555ce8cc48STakashi Sakamoto * old firewire-speaker module. 1565ce8cc48STakashi Sakamoto */ 1573e2f4570STakashi Sakamoto if (oxfw->entry->vendor_id == VENDOR_GRIFFIN) 1583e2f4570STakashi Sakamoto return snd_oxfw_add_spkr(oxfw, false); 1593e2f4570STakashi Sakamoto if (oxfw->entry->vendor_id == VENDOR_LACIE) 1603e2f4570STakashi Sakamoto return snd_oxfw_add_spkr(oxfw, true); 1615ce8cc48STakashi Sakamoto 1625ce8cc48STakashi Sakamoto /* 1639e2004f9STakashi Sakamoto * Stanton models supports asynchronous transactions for unique MIDI 1649e2004f9STakashi Sakamoto * messages. 1659e2004f9STakashi Sakamoto */ 166de5126ccSTakashi Sakamoto if (oxfw->entry->vendor_id == OUI_STANTON) { 167de5126ccSTakashi Sakamoto /* No physical MIDI ports. */ 168de5126ccSTakashi Sakamoto oxfw->midi_input_ports = 0; 169de5126ccSTakashi Sakamoto oxfw->midi_output_ports = 0; 170de5126ccSTakashi Sakamoto 171de5126ccSTakashi Sakamoto /* Output stream exists but no data channels are useful. */ 172de5126ccSTakashi Sakamoto oxfw->has_output = false; 173de5126ccSTakashi Sakamoto 1749e2004f9STakashi Sakamoto return snd_oxfw_scs1x_add(oxfw); 175de5126ccSTakashi Sakamoto } 1769e2004f9STakashi Sakamoto 1779e2004f9STakashi Sakamoto /* 17827e66635STakashi Sakamoto * TASCAM FireOne has physical control and requires a pair of additional 17927e66635STakashi Sakamoto * MIDI ports. 18027e66635STakashi Sakamoto */ 18127e66635STakashi Sakamoto if (oxfw->entry->vendor_id == VENDOR_TASCAM) { 18227e66635STakashi Sakamoto oxfw->midi_input_ports++; 18327e66635STakashi Sakamoto oxfw->midi_output_ports++; 1845ce8cc48STakashi Sakamoto return 0; 18527e66635STakashi Sakamoto } 18627e66635STakashi Sakamoto 18713f3a46dSTakashi Sakamoto /* Seek from Root Directory of Config ROM. */ 18813f3a46dSTakashi Sakamoto vendor = model = 0; 18913f3a46dSTakashi Sakamoto fw_csr_iterator_init(&it, fw_dev->config_rom + 5); 19013f3a46dSTakashi Sakamoto while (fw_csr_iterator_next(&it, &key, &val)) { 19113f3a46dSTakashi Sakamoto if (key == CSR_VENDOR) 19213f3a46dSTakashi Sakamoto vendor = val; 19313f3a46dSTakashi Sakamoto else if (key == CSR_MODEL) 19413f3a46dSTakashi Sakamoto model = val; 19513f3a46dSTakashi Sakamoto } 19613f3a46dSTakashi Sakamoto 19713f3a46dSTakashi Sakamoto /* 19813f3a46dSTakashi Sakamoto * Mackie Onyx Satellite with base station has a quirk to report a wrong 19913f3a46dSTakashi Sakamoto * value in 'dbs' field of CIP header against its format information. 20013f3a46dSTakashi Sakamoto */ 20113f3a46dSTakashi Sakamoto if (vendor == VENDOR_LOUD && model == MODEL_SATELLITE) 20213f3a46dSTakashi Sakamoto oxfw->wrong_dbs = true; 2035ce8cc48STakashi Sakamoto 2045ce8cc48STakashi Sakamoto return 0; 20513f3a46dSTakashi Sakamoto } 20613f3a46dSTakashi Sakamoto 2076c29230eSTakashi Sakamoto static void do_registration(struct work_struct *work) 2081a4e39c2STakashi Sakamoto { 2096c29230eSTakashi Sakamoto struct snd_oxfw *oxfw = container_of(work, struct snd_oxfw, dwork.work); 2101a4e39c2STakashi Sakamoto int err; 2111a4e39c2STakashi Sakamoto 2126c29230eSTakashi Sakamoto if (oxfw->registered) 2136c29230eSTakashi Sakamoto return; 214ec4dba50STakashi Sakamoto 2156c29230eSTakashi Sakamoto err = snd_card_new(&oxfw->unit->device, -1, NULL, THIS_MODULE, 0, 2166c29230eSTakashi Sakamoto &oxfw->card); 2171a4e39c2STakashi Sakamoto if (err < 0) 2186c29230eSTakashi Sakamoto return; 2195cd1d3f4STakashi Sakamoto 2203f47152aSTakashi Sakamoto err = name_card(oxfw); 2215ce8cc48STakashi Sakamoto if (err < 0) 2225ce8cc48STakashi Sakamoto goto error; 22313f3a46dSTakashi Sakamoto 2243d016d57STakashi Sakamoto err = snd_oxfw_stream_discover(oxfw); 225fec7b753STakashi Sakamoto if (err < 0) 226fec7b753STakashi Sakamoto goto error; 2271a4e39c2STakashi Sakamoto 2283d016d57STakashi Sakamoto err = detect_quirks(oxfw); 2296c29230eSTakashi Sakamoto if (err < 0) 2306c29230eSTakashi Sakamoto goto error; 2316c29230eSTakashi Sakamoto 2326c29230eSTakashi Sakamoto err = snd_oxfw_stream_init_simplex(oxfw, &oxfw->rx_stream); 2336c29230eSTakashi Sakamoto if (err < 0) 2346c29230eSTakashi Sakamoto goto error; 2356c29230eSTakashi Sakamoto if (oxfw->has_output) { 2366c29230eSTakashi Sakamoto err = snd_oxfw_stream_init_simplex(oxfw, &oxfw->tx_stream); 2376c29230eSTakashi Sakamoto if (err < 0) 2386c29230eSTakashi Sakamoto goto error; 2396c29230eSTakashi Sakamoto } 2406c29230eSTakashi Sakamoto 2413713d93aSTakashi Sakamoto err = snd_oxfw_create_pcm(oxfw); 2421a4e39c2STakashi Sakamoto if (err < 0) 2431a4e39c2STakashi Sakamoto goto error; 2441a4e39c2STakashi Sakamoto 2453c96101fSTakashi Sakamoto snd_oxfw_proc_init(oxfw); 2463c96101fSTakashi Sakamoto 24705588d34STakashi Sakamoto err = snd_oxfw_create_midi(oxfw); 24805588d34STakashi Sakamoto if (err < 0) 24905588d34STakashi Sakamoto goto error; 25005588d34STakashi Sakamoto 2518985f4acSTakashi Sakamoto err = snd_oxfw_create_hwdep(oxfw); 2528985f4acSTakashi Sakamoto if (err < 0) 2538985f4acSTakashi Sakamoto goto error; 2548985f4acSTakashi Sakamoto 2556c29230eSTakashi Sakamoto err = snd_card_register(oxfw->card); 2561a4e39c2STakashi Sakamoto if (err < 0) 2571a4e39c2STakashi Sakamoto goto error; 2581a4e39c2STakashi Sakamoto 2596c29230eSTakashi Sakamoto /* 2606c29230eSTakashi Sakamoto * After registered, oxfw instance can be released corresponding to 2616c29230eSTakashi Sakamoto * releasing the sound card instance. 2626c29230eSTakashi Sakamoto */ 2636c29230eSTakashi Sakamoto oxfw->card->private_free = oxfw_card_free; 2646c29230eSTakashi Sakamoto oxfw->card->private_data = oxfw; 2656c29230eSTakashi Sakamoto oxfw->registered = true; 2666c29230eSTakashi Sakamoto 2676c29230eSTakashi Sakamoto return; 2686c29230eSTakashi Sakamoto error: 269b0ac0009STakashi Sakamoto snd_oxfw_stream_destroy_simplex(oxfw, &oxfw->rx_stream); 270b0ac0009STakashi Sakamoto if (oxfw->has_output) 271b0ac0009STakashi Sakamoto snd_oxfw_stream_destroy_simplex(oxfw, &oxfw->tx_stream); 2726c29230eSTakashi Sakamoto snd_card_free(oxfw->card); 2736c29230eSTakashi Sakamoto dev_info(&oxfw->unit->device, 2746c29230eSTakashi Sakamoto "Sound card registration failed: %d\n", err); 275e2786ca6STakashi Sakamoto } 2766c29230eSTakashi Sakamoto 2776c29230eSTakashi Sakamoto static int oxfw_probe(struct fw_unit *unit, 2786c29230eSTakashi Sakamoto const struct ieee1394_device_id *entry) 2796c29230eSTakashi Sakamoto { 2806c29230eSTakashi Sakamoto struct snd_oxfw *oxfw; 2816c29230eSTakashi Sakamoto 2826c29230eSTakashi Sakamoto if (entry->vendor_id == VENDOR_LOUD && !detect_loud_models(unit)) 2836c29230eSTakashi Sakamoto return -ENODEV; 2846c29230eSTakashi Sakamoto 2856c29230eSTakashi Sakamoto /* Allocate this independent of sound card instance. */ 2866c29230eSTakashi Sakamoto oxfw = kzalloc(sizeof(struct snd_oxfw), GFP_KERNEL); 2876c29230eSTakashi Sakamoto if (oxfw == NULL) 2886c29230eSTakashi Sakamoto return -ENOMEM; 2896c29230eSTakashi Sakamoto 2906c29230eSTakashi Sakamoto oxfw->entry = entry; 2916c29230eSTakashi Sakamoto oxfw->unit = fw_unit_get(unit); 2921a4e39c2STakashi Sakamoto dev_set_drvdata(&unit->device, oxfw); 2931a4e39c2STakashi Sakamoto 2946c29230eSTakashi Sakamoto mutex_init(&oxfw->mutex); 2956c29230eSTakashi Sakamoto spin_lock_init(&oxfw->lock); 2966c29230eSTakashi Sakamoto init_waitqueue_head(&oxfw->hwdep_wait); 2976c29230eSTakashi Sakamoto 2986c29230eSTakashi Sakamoto /* Allocate and register this sound card later. */ 2996c29230eSTakashi Sakamoto INIT_DEFERRABLE_WORK(&oxfw->dwork, do_registration); 3006c29230eSTakashi Sakamoto snd_fw_schedule_registration(unit, &oxfw->dwork); 3016c29230eSTakashi Sakamoto 3021a4e39c2STakashi Sakamoto return 0; 3031a4e39c2STakashi Sakamoto } 3041a4e39c2STakashi Sakamoto 3051a4e39c2STakashi Sakamoto static void oxfw_bus_reset(struct fw_unit *unit) 3061a4e39c2STakashi Sakamoto { 3071a4e39c2STakashi Sakamoto struct snd_oxfw *oxfw = dev_get_drvdata(&unit->device); 3081a4e39c2STakashi Sakamoto 3096c29230eSTakashi Sakamoto if (!oxfw->registered) 3106c29230eSTakashi Sakamoto snd_fw_schedule_registration(unit, &oxfw->dwork); 3116c29230eSTakashi Sakamoto 3121a4e39c2STakashi Sakamoto fcp_bus_reset(oxfw->unit); 3131a4e39c2STakashi Sakamoto 3146c29230eSTakashi Sakamoto if (oxfw->registered) { 3151a4e39c2STakashi Sakamoto mutex_lock(&oxfw->mutex); 316b0ac0009STakashi Sakamoto 317b0ac0009STakashi Sakamoto snd_oxfw_stream_update_simplex(oxfw, &oxfw->rx_stream); 318b0ac0009STakashi Sakamoto if (oxfw->has_output) 319b0ac0009STakashi Sakamoto snd_oxfw_stream_update_simplex(oxfw, &oxfw->tx_stream); 320b0ac0009STakashi Sakamoto 3211a4e39c2STakashi Sakamoto mutex_unlock(&oxfw->mutex); 3229e2004f9STakashi Sakamoto 3239e2004f9STakashi Sakamoto if (oxfw->entry->vendor_id == OUI_STANTON) 3249e2004f9STakashi Sakamoto snd_oxfw_scs1x_update(oxfw); 3251a4e39c2STakashi Sakamoto } 3266c29230eSTakashi Sakamoto } 3271a4e39c2STakashi Sakamoto 3281a4e39c2STakashi Sakamoto static void oxfw_remove(struct fw_unit *unit) 3291a4e39c2STakashi Sakamoto { 3301a4e39c2STakashi Sakamoto struct snd_oxfw *oxfw = dev_get_drvdata(&unit->device); 3311a4e39c2STakashi Sakamoto 3326c29230eSTakashi Sakamoto /* 3336c29230eSTakashi Sakamoto * Confirm to stop the work for registration before the sound card is 3346c29230eSTakashi Sakamoto * going to be released. The work is not scheduled again because bus 3356c29230eSTakashi Sakamoto * reset handler is not called anymore. 3366c29230eSTakashi Sakamoto */ 3376c29230eSTakashi Sakamoto cancel_delayed_work_sync(&oxfw->dwork); 3386c29230eSTakashi Sakamoto 3396c29230eSTakashi Sakamoto if (oxfw->registered) { 34012ed7192STakashi Sakamoto /* No need to wait for releasing card object in this context. */ 3411a4e39c2STakashi Sakamoto snd_card_free_when_closed(oxfw->card); 3426c29230eSTakashi Sakamoto } else { 3436c29230eSTakashi Sakamoto /* Don't forget this case. */ 3446c29230eSTakashi Sakamoto oxfw_free(oxfw); 3456c29230eSTakashi Sakamoto } 3461a4e39c2STakashi Sakamoto } 3471a4e39c2STakashi Sakamoto 348d6ce6bbdSTakashi Sakamoto static const struct compat_info griffin_firewave = { 3491a4e39c2STakashi Sakamoto .driver_name = "FireWave", 350fec7b753STakashi Sakamoto .vendor_name = "Griffin", 351fec7b753STakashi Sakamoto .model_name = "FireWave", 3521a4e39c2STakashi Sakamoto }; 3531a4e39c2STakashi Sakamoto 354d6ce6bbdSTakashi Sakamoto static const struct compat_info lacie_speakers = { 3551a4e39c2STakashi Sakamoto .driver_name = "FWSpeakers", 356fec7b753STakashi Sakamoto .vendor_name = "LaCie", 357fec7b753STakashi Sakamoto .model_name = "FireWire Speakers", 3581a4e39c2STakashi Sakamoto }; 3591a4e39c2STakashi Sakamoto 3601a4e39c2STakashi Sakamoto static const struct ieee1394_device_id oxfw_id_table[] = { 3611a4e39c2STakashi Sakamoto { 3621a4e39c2STakashi Sakamoto .match_flags = IEEE1394_MATCH_VENDOR_ID | 3631a4e39c2STakashi Sakamoto IEEE1394_MATCH_MODEL_ID | 3641a4e39c2STakashi Sakamoto IEEE1394_MATCH_SPECIFIER_ID | 3651a4e39c2STakashi Sakamoto IEEE1394_MATCH_VERSION, 3661a4e39c2STakashi Sakamoto .vendor_id = VENDOR_GRIFFIN, 3671a4e39c2STakashi Sakamoto .model_id = 0x00f970, 3681a4e39c2STakashi Sakamoto .specifier_id = SPECIFIER_1394TA, 3691a4e39c2STakashi Sakamoto .version = VERSION_AVC, 3701a4e39c2STakashi Sakamoto .driver_data = (kernel_ulong_t)&griffin_firewave, 3711a4e39c2STakashi Sakamoto }, 3721a4e39c2STakashi Sakamoto { 3731a4e39c2STakashi Sakamoto .match_flags = IEEE1394_MATCH_VENDOR_ID | 3741a4e39c2STakashi Sakamoto IEEE1394_MATCH_MODEL_ID | 3751a4e39c2STakashi Sakamoto IEEE1394_MATCH_SPECIFIER_ID | 3761a4e39c2STakashi Sakamoto IEEE1394_MATCH_VERSION, 3771a4e39c2STakashi Sakamoto .vendor_id = VENDOR_LACIE, 3781a4e39c2STakashi Sakamoto .model_id = 0x00f970, 3791a4e39c2STakashi Sakamoto .specifier_id = SPECIFIER_1394TA, 3801a4e39c2STakashi Sakamoto .version = VERSION_AVC, 3811a4e39c2STakashi Sakamoto .driver_data = (kernel_ulong_t)&lacie_speakers, 3821a4e39c2STakashi Sakamoto }, 383ec4dba50STakashi Sakamoto /* Behringer,F-Control Audio 202 */ 384ec4dba50STakashi Sakamoto { 385ec4dba50STakashi Sakamoto .match_flags = IEEE1394_MATCH_VENDOR_ID | 386ec4dba50STakashi Sakamoto IEEE1394_MATCH_MODEL_ID, 387ec4dba50STakashi Sakamoto .vendor_id = VENDOR_BEHRINGER, 388ec4dba50STakashi Sakamoto .model_id = 0x00fc22, 389ec4dba50STakashi Sakamoto }, 390ec4dba50STakashi Sakamoto /* 391ec4dba50STakashi Sakamoto * Any Mackie(Loud) models (name string/model id): 392ec4dba50STakashi Sakamoto * Onyx-i series (former models): 0x081216 393ec4dba50STakashi Sakamoto * Mackie Onyx Satellite: 0x00200f 394ec4dba50STakashi Sakamoto * Tapco LINK.firewire 4x6: 0x000460 395ec4dba50STakashi Sakamoto * d.2 pro: Unknown 396ec4dba50STakashi Sakamoto * d.4 pro: Unknown 397ec4dba50STakashi Sakamoto * U.420: Unknown 398ec4dba50STakashi Sakamoto * U.420d: Unknown 399ec4dba50STakashi Sakamoto */ 400ec4dba50STakashi Sakamoto { 401ec4dba50STakashi Sakamoto .match_flags = IEEE1394_MATCH_VENDOR_ID | 402ec4dba50STakashi Sakamoto IEEE1394_MATCH_SPECIFIER_ID | 403ec4dba50STakashi Sakamoto IEEE1394_MATCH_VERSION, 404ec4dba50STakashi Sakamoto .vendor_id = VENDOR_LOUD, 405ec4dba50STakashi Sakamoto .specifier_id = SPECIFIER_1394TA, 406ec4dba50STakashi Sakamoto .version = VERSION_AVC, 407ec4dba50STakashi Sakamoto }, 408759a2f40STakashi Sakamoto /* TASCAM, FireOne */ 409759a2f40STakashi Sakamoto { 410759a2f40STakashi Sakamoto .match_flags = IEEE1394_MATCH_VENDOR_ID | 411759a2f40STakashi Sakamoto IEEE1394_MATCH_MODEL_ID, 412759a2f40STakashi Sakamoto .vendor_id = VENDOR_TASCAM, 413759a2f40STakashi Sakamoto .model_id = 0x800007, 414759a2f40STakashi Sakamoto }, 4159e2004f9STakashi Sakamoto /* Stanton, Stanton Controllers & Systems 1 Mixer (SCS.1m) */ 4169e2004f9STakashi Sakamoto { 4179e2004f9STakashi Sakamoto .match_flags = IEEE1394_MATCH_VENDOR_ID | 4189e2004f9STakashi Sakamoto IEEE1394_MATCH_MODEL_ID, 4199e2004f9STakashi Sakamoto .vendor_id = OUI_STANTON, 4209e2004f9STakashi Sakamoto .model_id = 0x001000, 4219e2004f9STakashi Sakamoto }, 4229e2004f9STakashi Sakamoto /* Stanton, Stanton Controllers & Systems 1 Deck (SCS.1d) */ 4239e2004f9STakashi Sakamoto { 4249e2004f9STakashi Sakamoto .match_flags = IEEE1394_MATCH_VENDOR_ID | 4259e2004f9STakashi Sakamoto IEEE1394_MATCH_MODEL_ID, 4269e2004f9STakashi Sakamoto .vendor_id = OUI_STANTON, 4279e2004f9STakashi Sakamoto .model_id = 0x002000, 4289e2004f9STakashi Sakamoto }, 4291a4e39c2STakashi Sakamoto { } 4301a4e39c2STakashi Sakamoto }; 4311a4e39c2STakashi Sakamoto MODULE_DEVICE_TABLE(ieee1394, oxfw_id_table); 4321a4e39c2STakashi Sakamoto 4331a4e39c2STakashi Sakamoto static struct fw_driver oxfw_driver = { 4341a4e39c2STakashi Sakamoto .driver = { 4351a4e39c2STakashi Sakamoto .owner = THIS_MODULE, 4361a4e39c2STakashi Sakamoto .name = KBUILD_MODNAME, 4371a4e39c2STakashi Sakamoto .bus = &fw_bus_type, 4381a4e39c2STakashi Sakamoto }, 4391a4e39c2STakashi Sakamoto .probe = oxfw_probe, 4401a4e39c2STakashi Sakamoto .update = oxfw_bus_reset, 4411a4e39c2STakashi Sakamoto .remove = oxfw_remove, 4421a4e39c2STakashi Sakamoto .id_table = oxfw_id_table, 4431a4e39c2STakashi Sakamoto }; 4441a4e39c2STakashi Sakamoto 4451a4e39c2STakashi Sakamoto static int __init snd_oxfw_init(void) 4461a4e39c2STakashi Sakamoto { 4471a4e39c2STakashi Sakamoto return driver_register(&oxfw_driver.driver); 4481a4e39c2STakashi Sakamoto } 4491a4e39c2STakashi Sakamoto 4501a4e39c2STakashi Sakamoto static void __exit snd_oxfw_exit(void) 4511a4e39c2STakashi Sakamoto { 4521a4e39c2STakashi Sakamoto driver_unregister(&oxfw_driver.driver); 4531a4e39c2STakashi Sakamoto } 4541a4e39c2STakashi Sakamoto 4551a4e39c2STakashi Sakamoto module_init(snd_oxfw_init); 4561a4e39c2STakashi Sakamoto module_exit(snd_oxfw_exit); 457