linux/sound/firewire/oxfw/oxfw.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * oxfw.c - a part of driver for OXFW970/971 based devices
   4 *
   5 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
   6 */
   7
   8#include "oxfw.h"
   9
  10#define OXFORD_FIRMWARE_ID_ADDRESS      (CSR_REGISTER_BASE + 0x50000)
  11/* 0x970?vvvv or 0x971?vvvv, where vvvv = firmware version */
  12
  13#define OXFORD_HARDWARE_ID_ADDRESS      (CSR_REGISTER_BASE + 0x90020)
  14#define OXFORD_HARDWARE_ID_OXFW970      0x39443841
  15#define OXFORD_HARDWARE_ID_OXFW971      0x39373100
  16
  17#define VENDOR_LOUD             0x000ff2
  18#define VENDOR_GRIFFIN          0x001292
  19#define VENDOR_BEHRINGER        0x001564
  20#define VENDOR_LACIE            0x00d04b
  21#define VENDOR_TASCAM           0x00022e
  22#define OUI_STANTON             0x001260
  23#define OUI_APOGEE              0x0003db
  24
  25#define MODEL_SATELLITE         0x00200f
  26#define MODEL_SCS1M             0x001000
  27#define MODEL_DUET_FW           0x01dddd
  28
  29#define SPECIFIER_1394TA        0x00a02d
  30#define VERSION_AVC             0x010001
  31
  32MODULE_DESCRIPTION("Oxford Semiconductor FW970/971 driver");
  33MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
  34MODULE_LICENSE("GPL v2");
  35MODULE_ALIAS("snd-firewire-speakers");
  36MODULE_ALIAS("snd-scs1x");
  37
  38struct compat_info {
  39        const char *driver_name;
  40        const char *vendor_name;
  41        const char *model_name;
  42};
  43
  44static bool detect_loud_models(struct fw_unit *unit)
  45{
  46        const char *const models[] = {
  47                "Onyxi",
  48                "Onyx-i",
  49                "Onyx 1640i",
  50                "d.Pro",
  51                "U.420"};
  52        char model[32];
  53        int err;
  54
  55        err = fw_csr_string(unit->directory, CSR_MODEL,
  56                            model, sizeof(model));
  57        if (err < 0)
  58                return false;
  59
  60        return match_string(models, ARRAY_SIZE(models), model) >= 0;
  61}
  62
  63static int name_card(struct snd_oxfw *oxfw, const struct ieee1394_device_id *entry)
  64{
  65        struct fw_device *fw_dev = fw_parent_device(oxfw->unit);
  66        const struct compat_info *info;
  67        char vendor[24];
  68        char model[32];
  69        const char *d, *v, *m;
  70        u32 firmware;
  71        int err;
  72
  73        /* get vendor name from root directory */
  74        err = fw_csr_string(fw_dev->config_rom + 5, CSR_VENDOR,
  75                            vendor, sizeof(vendor));
  76        if (err < 0)
  77                goto end;
  78
  79        /* get model name from unit directory */
  80        err = fw_csr_string(oxfw->unit->directory, CSR_MODEL,
  81                            model, sizeof(model));
  82        if (err < 0)
  83                goto end;
  84
  85        err = snd_fw_transaction(oxfw->unit, TCODE_READ_QUADLET_REQUEST,
  86                                 OXFORD_FIRMWARE_ID_ADDRESS, &firmware, 4, 0);
  87        if (err < 0)
  88                goto end;
  89        be32_to_cpus(&firmware);
  90
  91        if (firmware >> 20 == 0x970)
  92                oxfw->quirks |= SND_OXFW_QUIRK_JUMBO_PAYLOAD;
  93
  94        /* to apply card definitions */
  95        if (entry->vendor_id == VENDOR_GRIFFIN || entry->vendor_id == VENDOR_LACIE) {
  96                info = (const struct compat_info *)entry->driver_data;
  97                d = info->driver_name;
  98                v = info->vendor_name;
  99                m = info->model_name;
 100        } else {
 101                d = "OXFW";
 102                v = vendor;
 103                m = model;
 104        }
 105
 106        strcpy(oxfw->card->driver, d);
 107        strcpy(oxfw->card->mixername, m);
 108        strcpy(oxfw->card->shortname, m);
 109
 110        snprintf(oxfw->card->longname, sizeof(oxfw->card->longname),
 111                 "%s %s (OXFW%x %04x), GUID %08x%08x at %s, S%d",
 112                 v, m, firmware >> 20, firmware & 0xffff,
 113                 fw_dev->config_rom[3], fw_dev->config_rom[4],
 114                 dev_name(&oxfw->unit->device), 100 << fw_dev->max_speed);
 115end:
 116        return err;
 117}
 118
 119static void oxfw_card_free(struct snd_card *card)
 120{
 121        struct snd_oxfw *oxfw = card->private_data;
 122
 123        if (oxfw->has_output || oxfw->has_input)
 124                snd_oxfw_stream_destroy_duplex(oxfw);
 125
 126        mutex_destroy(&oxfw->mutex);
 127        fw_unit_put(oxfw->unit);
 128}
 129
 130static int detect_quirks(struct snd_oxfw *oxfw, const struct ieee1394_device_id *entry)
 131{
 132        struct fw_device *fw_dev = fw_parent_device(oxfw->unit);
 133        struct fw_csr_iterator it;
 134        int key, val;
 135        int vendor, model;
 136
 137        /*
 138         * Add ALSA control elements for two models to keep compatibility to
 139         * old firewire-speaker module.
 140         */
 141        if (entry->vendor_id == VENDOR_GRIFFIN)
 142                return snd_oxfw_add_spkr(oxfw, false);
 143        if (entry->vendor_id == VENDOR_LACIE)
 144                return snd_oxfw_add_spkr(oxfw, true);
 145
 146        /*
 147         * Stanton models supports asynchronous transactions for unique MIDI
 148         * messages.
 149         */
 150        if (entry->vendor_id == OUI_STANTON) {
 151                oxfw->quirks |= SND_OXFW_QUIRK_SCS_TRANSACTION;
 152                if (entry->model_id == MODEL_SCS1M)
 153                        oxfw->quirks |= SND_OXFW_QUIRK_BLOCKING_TRANSMISSION;
 154
 155                // No physical MIDI ports.
 156                oxfw->midi_input_ports = 0;
 157                oxfw->midi_output_ports = 0;
 158
 159                return snd_oxfw_scs1x_add(oxfw);
 160        }
 161
 162        if (entry->vendor_id == OUI_APOGEE && entry->model_id == MODEL_DUET_FW) {
 163                oxfw->quirks |= SND_OXFW_QUIRK_BLOCKING_TRANSMISSION |
 164                                SND_OXFW_QUIRK_IGNORE_NO_INFO_PACKET;
 165        }
 166
 167        /*
 168         * TASCAM FireOne has physical control and requires a pair of additional
 169         * MIDI ports.
 170         */
 171        if (entry->vendor_id == VENDOR_TASCAM) {
 172                oxfw->midi_input_ports++;
 173                oxfw->midi_output_ports++;
 174                return 0;
 175        }
 176
 177        /* Seek from Root Directory of Config ROM. */
 178        vendor = model = 0;
 179        fw_csr_iterator_init(&it, fw_dev->config_rom + 5);
 180        while (fw_csr_iterator_next(&it, &key, &val)) {
 181                if (key == CSR_VENDOR)
 182                        vendor = val;
 183                else if (key == CSR_MODEL)
 184                        model = val;
 185        }
 186
 187        /*
 188         * Mackie Onyx Satellite with base station has a quirk to report a wrong
 189         * value in 'dbs' field of CIP header against its format information.
 190         */
 191        if (vendor == VENDOR_LOUD && model == MODEL_SATELLITE)
 192                oxfw->quirks |= SND_OXFW_QUIRK_WRONG_DBS;
 193
 194        return 0;
 195}
 196
 197static int oxfw_probe(struct fw_unit *unit, const struct ieee1394_device_id *entry)
 198{
 199        struct snd_card *card;
 200        struct snd_oxfw *oxfw;
 201        int err;
 202
 203        if (entry->vendor_id == VENDOR_LOUD && entry->model_id == 0 && !detect_loud_models(unit))
 204                return -ENODEV;
 205
 206        err = snd_card_new(&unit->device, -1, NULL, THIS_MODULE, sizeof(*oxfw), &card);
 207        if (err < 0)
 208                return err;
 209        card->private_free = oxfw_card_free;
 210
 211        oxfw = card->private_data;
 212        oxfw->unit = fw_unit_get(unit);
 213        dev_set_drvdata(&unit->device, oxfw);
 214        oxfw->card = card;
 215
 216        mutex_init(&oxfw->mutex);
 217        spin_lock_init(&oxfw->lock);
 218        init_waitqueue_head(&oxfw->hwdep_wait);
 219
 220        err = name_card(oxfw, entry);
 221        if (err < 0)
 222                goto error;
 223
 224        err = snd_oxfw_stream_discover(oxfw);
 225        if (err < 0)
 226                goto error;
 227
 228        err = detect_quirks(oxfw, entry);
 229        if (err < 0)
 230                goto error;
 231
 232        if (oxfw->has_output || oxfw->has_input) {
 233                err = snd_oxfw_stream_init_duplex(oxfw);
 234                if (err < 0)
 235                        goto error;
 236
 237                err = snd_oxfw_create_pcm(oxfw);
 238                if (err < 0)
 239                        goto error;
 240
 241                snd_oxfw_proc_init(oxfw);
 242
 243                err = snd_oxfw_create_midi(oxfw);
 244                if (err < 0)
 245                        goto error;
 246
 247                err = snd_oxfw_create_hwdep(oxfw);
 248                if (err < 0)
 249                        goto error;
 250        }
 251
 252        err = snd_card_register(card);
 253        if (err < 0)
 254                goto error;
 255
 256        return 0;
 257error:
 258        snd_card_free(card);
 259        return err;
 260}
 261
 262static void oxfw_bus_reset(struct fw_unit *unit)
 263{
 264        struct snd_oxfw *oxfw = dev_get_drvdata(&unit->device);
 265
 266        fcp_bus_reset(oxfw->unit);
 267
 268        if (oxfw->has_output || oxfw->has_input) {
 269                mutex_lock(&oxfw->mutex);
 270                snd_oxfw_stream_update_duplex(oxfw);
 271                mutex_unlock(&oxfw->mutex);
 272        }
 273
 274        if (oxfw->quirks & SND_OXFW_QUIRK_SCS_TRANSACTION)
 275                snd_oxfw_scs1x_update(oxfw);
 276}
 277
 278static void oxfw_remove(struct fw_unit *unit)
 279{
 280        struct snd_oxfw *oxfw = dev_get_drvdata(&unit->device);
 281
 282        // Block till all of ALSA character devices are released.
 283        snd_card_free(oxfw->card);
 284}
 285
 286static const struct compat_info griffin_firewave = {
 287        .driver_name = "FireWave",
 288        .vendor_name = "Griffin",
 289        .model_name = "FireWave",
 290};
 291
 292static const struct compat_info lacie_speakers = {
 293        .driver_name = "FWSpeakers",
 294        .vendor_name = "LaCie",
 295        .model_name = "FireWire Speakers",
 296};
 297
 298#define OXFW_DEV_ENTRY(vendor, model, data) \
 299{ \
 300        .match_flags  = IEEE1394_MATCH_VENDOR_ID | \
 301                        IEEE1394_MATCH_MODEL_ID | \
 302                        IEEE1394_MATCH_SPECIFIER_ID | \
 303                        IEEE1394_MATCH_VERSION, \
 304        .vendor_id    = vendor, \
 305        .model_id     = model, \
 306        .specifier_id = SPECIFIER_1394TA, \
 307        .version      = VERSION_AVC, \
 308        .driver_data  = (kernel_ulong_t)data, \
 309}
 310
 311static const struct ieee1394_device_id oxfw_id_table[] = {
 312        //
 313        // OXFW970 devices:
 314        // Initial firmware has a quirk to postpone isoc packet transmission during finishing async
 315        // transaction. As a result, several isochronous cycles are skipped to transfer the packets
 316        // and the audio data frames which should have been transferred during the cycles are put
 317        // into packet at the first isoc cycle after the postpone. Furthermore, the value of SYT
 318        // field in CIP header is not reliable as synchronization timing,
 319        //
 320        OXFW_DEV_ENTRY(VENDOR_GRIFFIN, 0x00f970, &griffin_firewave),
 321        OXFW_DEV_ENTRY(VENDOR_LACIE, 0x00f970, &lacie_speakers),
 322        // Behringer,F-Control Audio 202. The value of SYT field is not reliable at all.
 323        OXFW_DEV_ENTRY(VENDOR_BEHRINGER, 0x00fc22, NULL),
 324        // Loud Technologies, Tapco Link.FireWire 4x6. The value of SYT field is always 0xffff.
 325        OXFW_DEV_ENTRY(VENDOR_LOUD, 0x000460, NULL),
 326        // Loud Technologies, Mackie Onyx Satellite. Although revised version of firmware is
 327        // installed to avoid the postpone, the value of SYT field is always 0xffff.
 328        OXFW_DEV_ENTRY(VENDOR_LOUD, MODEL_SATELLITE, NULL),
 329        // Miglia HarmonyAudio. Not yet identified.
 330
 331        //
 332        // OXFW971 devices:
 333        // The value of SYT field in CIP header is enough reliable. Both of blocking and non-blocking
 334        // transmission methods are available.
 335        //
 336        // Any Mackie(Loud) models (name string/model id):
 337        //  Onyx-i series (former models):      0x081216
 338        //  Onyx 1640i:                         0x001640
 339        //  d.2 pro/d.4 pro (built-in card):    Unknown
 340        //  U.420:                              Unknown
 341        //  U.420d:                             Unknown
 342        {
 343                .match_flags    = IEEE1394_MATCH_VENDOR_ID |
 344                                  IEEE1394_MATCH_SPECIFIER_ID |
 345                                  IEEE1394_MATCH_VERSION,
 346                .vendor_id      = VENDOR_LOUD,
 347                .model_id       = 0,
 348                .specifier_id   = SPECIFIER_1394TA,
 349                .version        = VERSION_AVC,
 350        },
 351        // TASCAM, FireOne.
 352        OXFW_DEV_ENTRY(VENDOR_TASCAM, 0x800007, NULL),
 353        // Stanton, Stanton Controllers & Systems 1 Mixer (SCS.1m).
 354        OXFW_DEV_ENTRY(OUI_STANTON, MODEL_SCS1M, NULL),
 355        // Stanton, Stanton Controllers & Systems 1 Deck (SCS.1d).
 356        OXFW_DEV_ENTRY(OUI_STANTON, 0x002000, NULL),
 357        // APOGEE, duet FireWire.
 358        OXFW_DEV_ENTRY(OUI_APOGEE, MODEL_DUET_FW, NULL),
 359        { }
 360};
 361MODULE_DEVICE_TABLE(ieee1394, oxfw_id_table);
 362
 363static struct fw_driver oxfw_driver = {
 364        .driver   = {
 365                .owner  = THIS_MODULE,
 366                .name   = KBUILD_MODNAME,
 367                .bus    = &fw_bus_type,
 368        },
 369        .probe    = oxfw_probe,
 370        .update   = oxfw_bus_reset,
 371        .remove   = oxfw_remove,
 372        .id_table = oxfw_id_table,
 373};
 374
 375static int __init snd_oxfw_init(void)
 376{
 377        return driver_register(&oxfw_driver.driver);
 378}
 379
 380static void __exit snd_oxfw_exit(void)
 381{
 382        driver_unregister(&oxfw_driver.driver);
 383}
 384
 385module_init(snd_oxfw_init);
 386module_exit(snd_oxfw_exit);
 387