Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * TC Applied Technologies Digital Interface Communications Engine driver
0004  *
0005  * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
0006  */
0007 
0008 #include "dice.h"
0009 
0010 MODULE_DESCRIPTION("DICE driver");
0011 MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
0012 MODULE_LICENSE("GPL v2");
0013 
0014 #define OUI_WEISS       0x001c6a
0015 #define OUI_LOUD        0x000ff2
0016 #define OUI_FOCUSRITE       0x00130e
0017 #define OUI_TCELECTRONIC    0x000166
0018 #define OUI_ALESIS      0x000595
0019 #define OUI_MAUDIO      0x000d6c
0020 #define OUI_MYTEK       0x001ee8
0021 #define OUI_SSL         0x0050c2    // Actually ID reserved by IEEE.
0022 #define OUI_PRESONUS        0x000a92
0023 #define OUI_HARMAN      0x000fd7
0024 #define OUI_AVID        0x00a07e
0025 
0026 #define DICE_CATEGORY_ID    0x04
0027 #define WEISS_CATEGORY_ID   0x00
0028 #define LOUD_CATEGORY_ID    0x10
0029 #define HARMAN_CATEGORY_ID  0x20
0030 
0031 #define MODEL_ALESIS_IO_BOTH    0x000001
0032 
0033 static int check_dice_category(struct fw_unit *unit)
0034 {
0035     struct fw_device *device = fw_parent_device(unit);
0036     struct fw_csr_iterator it;
0037     int key, val, vendor = -1, model = -1;
0038     unsigned int category;
0039 
0040     /*
0041      * Check that GUID and unit directory are constructed according to DICE
0042      * rules, i.e., that the specifier ID is the GUID's OUI, and that the
0043      * GUID chip ID consists of the 8-bit category ID, the 10-bit product
0044      * ID, and a 22-bit serial number.
0045      */
0046     fw_csr_iterator_init(&it, unit->directory);
0047     while (fw_csr_iterator_next(&it, &key, &val)) {
0048         switch (key) {
0049         case CSR_SPECIFIER_ID:
0050             vendor = val;
0051             break;
0052         case CSR_MODEL:
0053             model = val;
0054             break;
0055         }
0056     }
0057 
0058     if (vendor == OUI_WEISS)
0059         category = WEISS_CATEGORY_ID;
0060     else if (vendor == OUI_LOUD)
0061         category = LOUD_CATEGORY_ID;
0062     else if (vendor == OUI_HARMAN)
0063         category = HARMAN_CATEGORY_ID;
0064     else
0065         category = DICE_CATEGORY_ID;
0066     if (device->config_rom[3] != ((vendor << 8) | category) ||
0067         device->config_rom[4] >> 22 != model)
0068         return -ENODEV;
0069 
0070     return 0;
0071 }
0072 
0073 static int check_clock_caps(struct snd_dice *dice)
0074 {
0075     __be32 value;
0076     int err;
0077 
0078     /* some very old firmwares don't tell about their clock support */
0079     if (dice->clock_caps > 0) {
0080         err = snd_dice_transaction_read_global(dice,
0081                         GLOBAL_CLOCK_CAPABILITIES,
0082                         &value, 4);
0083         if (err < 0)
0084             return err;
0085         dice->clock_caps = be32_to_cpu(value);
0086     } else {
0087         /* this should be supported by any device */
0088         dice->clock_caps = CLOCK_CAP_RATE_44100 |
0089                    CLOCK_CAP_RATE_48000 |
0090                    CLOCK_CAP_SOURCE_ARX1 |
0091                    CLOCK_CAP_SOURCE_INTERNAL;
0092     }
0093 
0094     return 0;
0095 }
0096 
0097 static void dice_card_strings(struct snd_dice *dice)
0098 {
0099     struct snd_card *card = dice->card;
0100     struct fw_device *dev = fw_parent_device(dice->unit);
0101     char vendor[32], model[32];
0102     unsigned int i;
0103     int err;
0104 
0105     strcpy(card->driver, "DICE");
0106 
0107     strcpy(card->shortname, "DICE");
0108     BUILD_BUG_ON(NICK_NAME_SIZE < sizeof(card->shortname));
0109     err = snd_dice_transaction_read_global(dice, GLOBAL_NICK_NAME,
0110                            card->shortname,
0111                            sizeof(card->shortname));
0112     if (err >= 0) {
0113         /* DICE strings are returned in "always-wrong" endianness */
0114         BUILD_BUG_ON(sizeof(card->shortname) % 4 != 0);
0115         for (i = 0; i < sizeof(card->shortname); i += 4)
0116             swab32s((u32 *)&card->shortname[i]);
0117         card->shortname[sizeof(card->shortname) - 1] = '\0';
0118     }
0119 
0120     strcpy(vendor, "?");
0121     fw_csr_string(dev->config_rom + 5, CSR_VENDOR, vendor, sizeof(vendor));
0122     strcpy(model, "?");
0123     fw_csr_string(dice->unit->directory, CSR_MODEL, model, sizeof(model));
0124     snprintf(card->longname, sizeof(card->longname),
0125          "%s %s (serial %u) at %s, S%d",
0126          vendor, model, dev->config_rom[4] & 0x3fffff,
0127          dev_name(&dice->unit->device), 100 << dev->max_speed);
0128 
0129     strcpy(card->mixername, "DICE");
0130 }
0131 
0132 static void dice_card_free(struct snd_card *card)
0133 {
0134     struct snd_dice *dice = card->private_data;
0135 
0136     snd_dice_stream_destroy_duplex(dice);
0137     snd_dice_transaction_destroy(dice);
0138 
0139     mutex_destroy(&dice->mutex);
0140     fw_unit_put(dice->unit);
0141 }
0142 
0143 static int dice_probe(struct fw_unit *unit, const struct ieee1394_device_id *entry)
0144 {
0145     struct snd_card *card;
0146     struct snd_dice *dice;
0147     snd_dice_detect_formats_t detect_formats;
0148     int err;
0149 
0150     if (!entry->driver_data && entry->vendor_id != OUI_SSL) {
0151         err = check_dice_category(unit);
0152         if (err < 0)
0153             return -ENODEV;
0154     }
0155 
0156     err = snd_card_new(&unit->device, -1, NULL, THIS_MODULE, sizeof(*dice), &card);
0157     if (err < 0)
0158         return err;
0159     card->private_free = dice_card_free;
0160 
0161     dice = card->private_data;
0162     dice->unit = fw_unit_get(unit);
0163     dev_set_drvdata(&unit->device, dice);
0164     dice->card = card;
0165 
0166     if (!entry->driver_data)
0167         detect_formats = snd_dice_stream_detect_current_formats;
0168     else
0169         detect_formats = (snd_dice_detect_formats_t)entry->driver_data;
0170 
0171     // Below models are compliant to IEC 61883-1/6 and have no quirk at high sampling transfer
0172     // frequency.
0173     // * Avid M-Box 3 Pro
0174     // * M-Audio Profire 610
0175     // * M-Audio Profire 2626
0176     if (entry->vendor_id == OUI_MAUDIO || entry->vendor_id == OUI_AVID)
0177         dice->disable_double_pcm_frames = true;
0178 
0179     spin_lock_init(&dice->lock);
0180     mutex_init(&dice->mutex);
0181     init_completion(&dice->clock_accepted);
0182     init_waitqueue_head(&dice->hwdep_wait);
0183 
0184     err = snd_dice_transaction_init(dice);
0185     if (err < 0)
0186         goto error;
0187 
0188     err = check_clock_caps(dice);
0189     if (err < 0)
0190         goto error;
0191 
0192     dice_card_strings(dice);
0193 
0194     err = detect_formats(dice);
0195     if (err < 0)
0196         goto error;
0197 
0198     err = snd_dice_stream_init_duplex(dice);
0199     if (err < 0)
0200         goto error;
0201 
0202     snd_dice_create_proc(dice);
0203 
0204     err = snd_dice_create_pcm(dice);
0205     if (err < 0)
0206         goto error;
0207 
0208     err = snd_dice_create_midi(dice);
0209     if (err < 0)
0210         goto error;
0211 
0212     err = snd_dice_create_hwdep(dice);
0213     if (err < 0)
0214         goto error;
0215 
0216     err = snd_card_register(card);
0217     if (err < 0)
0218         goto error;
0219 
0220     return 0;
0221 error:
0222     snd_card_free(card);
0223     return err;
0224 }
0225 
0226 static void dice_remove(struct fw_unit *unit)
0227 {
0228     struct snd_dice *dice = dev_get_drvdata(&unit->device);
0229 
0230     // Block till all of ALSA character devices are released.
0231     snd_card_free(dice->card);
0232 }
0233 
0234 static void dice_bus_reset(struct fw_unit *unit)
0235 {
0236     struct snd_dice *dice = dev_get_drvdata(&unit->device);
0237 
0238     /* The handler address register becomes initialized. */
0239     snd_dice_transaction_reinit(dice);
0240 
0241     mutex_lock(&dice->mutex);
0242     snd_dice_stream_update_duplex(dice);
0243     mutex_unlock(&dice->mutex);
0244 }
0245 
0246 #define DICE_INTERFACE  0x000001
0247 
0248 #define DICE_DEV_ENTRY_TYPICAL(vendor, model, data) \
0249     { \
0250         .match_flags    = IEEE1394_MATCH_VENDOR_ID | \
0251                   IEEE1394_MATCH_MODEL_ID | \
0252                   IEEE1394_MATCH_SPECIFIER_ID | \
0253                   IEEE1394_MATCH_VERSION, \
0254         .vendor_id  = (vendor), \
0255         .model_id   = (model), \
0256         .specifier_id   = (vendor), \
0257         .version    = DICE_INTERFACE, \
0258         .driver_data = (kernel_ulong_t)(data), \
0259     }
0260 
0261 static const struct ieee1394_device_id dice_id_table[] = {
0262     // Avid M-Box 3 Pro. To match in probe function.
0263     DICE_DEV_ENTRY_TYPICAL(OUI_AVID, 0x000004, snd_dice_detect_extension_formats),
0264     /* M-Audio Profire 2626 has a different value in version field. */
0265     {
0266         .match_flags    = IEEE1394_MATCH_VENDOR_ID |
0267                   IEEE1394_MATCH_MODEL_ID,
0268         .vendor_id  = OUI_MAUDIO,
0269         .model_id   = 0x000010,
0270         .driver_data = (kernel_ulong_t)snd_dice_detect_extension_formats,
0271     },
0272     /* M-Audio Profire 610 has a different value in version field. */
0273     {
0274         .match_flags    = IEEE1394_MATCH_VENDOR_ID |
0275                   IEEE1394_MATCH_MODEL_ID,
0276         .vendor_id  = OUI_MAUDIO,
0277         .model_id   = 0x000011,
0278         .driver_data = (kernel_ulong_t)snd_dice_detect_extension_formats,
0279     },
0280     /* TC Electronic Konnekt 24D. */
0281     {
0282         .match_flags    = IEEE1394_MATCH_VENDOR_ID |
0283                   IEEE1394_MATCH_MODEL_ID,
0284         .vendor_id  = OUI_TCELECTRONIC,
0285         .model_id   = 0x000020,
0286         .driver_data = (kernel_ulong_t)snd_dice_detect_tcelectronic_formats,
0287     },
0288     /* TC Electronic Konnekt 8. */
0289     {
0290         .match_flags    = IEEE1394_MATCH_VENDOR_ID |
0291                   IEEE1394_MATCH_MODEL_ID,
0292         .vendor_id  = OUI_TCELECTRONIC,
0293         .model_id   = 0x000021,
0294         .driver_data = (kernel_ulong_t)snd_dice_detect_tcelectronic_formats,
0295     },
0296     /* TC Electronic Studio Konnekt 48. */
0297     {
0298         .match_flags    = IEEE1394_MATCH_VENDOR_ID |
0299                   IEEE1394_MATCH_MODEL_ID,
0300         .vendor_id  = OUI_TCELECTRONIC,
0301         .model_id   = 0x000022,
0302         .driver_data = (kernel_ulong_t)snd_dice_detect_tcelectronic_formats,
0303     },
0304     /* TC Electronic Konnekt Live. */
0305     {
0306         .match_flags    = IEEE1394_MATCH_VENDOR_ID |
0307                   IEEE1394_MATCH_MODEL_ID,
0308         .vendor_id  = OUI_TCELECTRONIC,
0309         .model_id   = 0x000023,
0310         .driver_data = (kernel_ulong_t)snd_dice_detect_tcelectronic_formats,
0311     },
0312     /* TC Electronic Desktop Konnekt 6. */
0313     {
0314         .match_flags    = IEEE1394_MATCH_VENDOR_ID |
0315                   IEEE1394_MATCH_MODEL_ID,
0316         .vendor_id  = OUI_TCELECTRONIC,
0317         .model_id   = 0x000024,
0318         .driver_data = (kernel_ulong_t)snd_dice_detect_tcelectronic_formats,
0319     },
0320     /* TC Electronic Impact Twin. */
0321     {
0322         .match_flags    = IEEE1394_MATCH_VENDOR_ID |
0323                   IEEE1394_MATCH_MODEL_ID,
0324         .vendor_id  = OUI_TCELECTRONIC,
0325         .model_id   = 0x000027,
0326         .driver_data = (kernel_ulong_t)snd_dice_detect_tcelectronic_formats,
0327     },
0328     /* TC Electronic Digital Konnekt x32. */
0329     {
0330         .match_flags    = IEEE1394_MATCH_VENDOR_ID |
0331                   IEEE1394_MATCH_MODEL_ID,
0332         .vendor_id  = OUI_TCELECTRONIC,
0333         .model_id   = 0x000030,
0334         .driver_data = (kernel_ulong_t)snd_dice_detect_tcelectronic_formats,
0335     },
0336     /* Alesis iO14/iO26. */
0337     {
0338         .match_flags    = IEEE1394_MATCH_VENDOR_ID |
0339                   IEEE1394_MATCH_MODEL_ID,
0340         .vendor_id  = OUI_ALESIS,
0341         .model_id   = MODEL_ALESIS_IO_BOTH,
0342         .driver_data = (kernel_ulong_t)snd_dice_detect_alesis_formats,
0343     },
0344     // Alesis MasterControl.
0345     {
0346         .match_flags    = IEEE1394_MATCH_VENDOR_ID |
0347                   IEEE1394_MATCH_MODEL_ID,
0348         .vendor_id  = OUI_ALESIS,
0349         .model_id   = 0x000002,
0350         .driver_data = (kernel_ulong_t)snd_dice_detect_alesis_mastercontrol_formats,
0351     },
0352     /* Mytek Stereo 192 DSD-DAC. */
0353     {
0354         .match_flags    = IEEE1394_MATCH_VENDOR_ID |
0355                   IEEE1394_MATCH_MODEL_ID,
0356         .vendor_id  = OUI_MYTEK,
0357         .model_id   = 0x000002,
0358         .driver_data = (kernel_ulong_t)snd_dice_detect_mytek_formats,
0359     },
0360     // Solid State Logic, Duende Classic and Mini.
0361     // NOTE: each field of GUID in config ROM is not compliant to standard
0362     // DICE scheme.
0363     {
0364         .match_flags    = IEEE1394_MATCH_VENDOR_ID |
0365                   IEEE1394_MATCH_MODEL_ID,
0366         .vendor_id  = OUI_SSL,
0367         .model_id   = 0x000070,
0368     },
0369     // Presonus FireStudio.
0370     {
0371         .match_flags    = IEEE1394_MATCH_VENDOR_ID |
0372                   IEEE1394_MATCH_MODEL_ID,
0373         .vendor_id  = OUI_PRESONUS,
0374         .model_id   = 0x000008,
0375         .driver_data    = (kernel_ulong_t)snd_dice_detect_presonus_formats,
0376     },
0377     // Lexicon I-ONYX FW810S.
0378     {
0379         .match_flags    = IEEE1394_MATCH_VENDOR_ID |
0380                   IEEE1394_MATCH_MODEL_ID,
0381         .vendor_id  = OUI_HARMAN,
0382         .model_id   = 0x000001,
0383         .driver_data    = (kernel_ulong_t)snd_dice_detect_harman_formats,
0384     },
0385     {
0386         .match_flags = IEEE1394_MATCH_VERSION,
0387         .version     = DICE_INTERFACE,
0388     },
0389     { }
0390 };
0391 MODULE_DEVICE_TABLE(ieee1394, dice_id_table);
0392 
0393 static struct fw_driver dice_driver = {
0394     .driver   = {
0395         .owner  = THIS_MODULE,
0396         .name   = KBUILD_MODNAME,
0397         .bus    = &fw_bus_type,
0398     },
0399     .probe    = dice_probe,
0400     .update   = dice_bus_reset,
0401     .remove   = dice_remove,
0402     .id_table = dice_id_table,
0403 };
0404 
0405 static int __init alsa_dice_init(void)
0406 {
0407     return driver_register(&dice_driver.driver);
0408 }
0409 
0410 static void __exit alsa_dice_exit(void)
0411 {
0412     driver_unregister(&dice_driver.driver);
0413 }
0414 
0415 module_init(alsa_dice_init);
0416 module_exit(alsa_dice_exit);