diff options
Diffstat (limited to 'sound/firewire/dice/dice.c')
-rw-r--r-- | sound/firewire/dice/dice.c | 108 |
1 files changed, 44 insertions, 64 deletions
diff --git a/sound/firewire/dice/dice.c b/sound/firewire/dice/dice.c index b91b3739c810..8b64aef31a86 100644 --- a/sound/firewire/dice/dice.c +++ b/sound/firewire/dice/dice.c @@ -13,6 +13,8 @@ MODULE_LICENSE("GPL v2"); #define OUI_WEISS 0x001c6a #define OUI_LOUD 0x000ff2 +#define OUI_FOCUSRITE 0x00130e +#define OUI_TCELECTRONIC 0x001486 #define DICE_CATEGORY_ID 0x04 #define WEISS_CATEGORY_ID 0x00 @@ -20,6 +22,36 @@ MODULE_LICENSE("GPL v2"); #define PROBE_DELAY_MS (2 * MSEC_PER_SEC) +/* + * Some models support several isochronous channels, while these streams are not + * always available. In this case, add the model name to this list. + */ +static bool force_two_pcm_support(struct fw_unit *unit) +{ + const char *const models[] = { + /* TC Electronic models. */ + "StudioKonnekt48", + /* Focusrite models. */ + "SAFFIRE_PRO_40", + "LIQUID_SAFFIRE_56", + "SAFFIRE_PRO_40_1", + }; + char model[32]; + unsigned int i; + int err; + + err = fw_csr_string(unit->directory, CSR_MODEL, model, sizeof(model)); + if (err < 0) + return false; + + for (i = 0; i < ARRAY_SIZE(models); i++) { + if (strcmp(models[i], model) == 0) + break; + } + + return i < ARRAY_SIZE(models); +} + static int check_dice_category(struct fw_unit *unit) { struct fw_device *device = fw_parent_device(unit); @@ -44,6 +76,12 @@ static int check_dice_category(struct fw_unit *unit) break; } } + + if (vendor == OUI_FOCUSRITE || vendor == OUI_TCELECTRONIC) { + if (force_two_pcm_support(unit)) + return 0; + } + if (vendor == OUI_WEISS) category = WEISS_CATEGORY_ID; else if (vendor == OUI_LOUD) @@ -57,65 +95,10 @@ static int check_dice_category(struct fw_unit *unit) return 0; } -static int highest_supported_mode_rate(struct snd_dice *dice, - unsigned int mode, unsigned int *rate) -{ - unsigned int i, m; - - for (i = ARRAY_SIZE(snd_dice_rates); i > 0; i--) { - *rate = snd_dice_rates[i - 1]; - if (snd_dice_stream_get_rate_mode(dice, *rate, &m) < 0) - continue; - if (mode == m) - break; - } - if (i == 0) - return -EINVAL; - - return 0; -} - -static int dice_read_mode_params(struct snd_dice *dice, unsigned int mode) -{ - __be32 values[2]; - unsigned int rate; - int err; - - if (highest_supported_mode_rate(dice, mode, &rate) < 0) { - dice->tx_channels[mode] = 0; - dice->tx_midi_ports[mode] = 0; - dice->rx_channels[mode] = 0; - dice->rx_midi_ports[mode] = 0; - return 0; - } - - err = snd_dice_transaction_set_rate(dice, rate); - if (err < 0) - return err; - - err = snd_dice_transaction_read_tx(dice, TX_NUMBER_AUDIO, - values, sizeof(values)); - if (err < 0) - return err; - - dice->tx_channels[mode] = be32_to_cpu(values[0]); - dice->tx_midi_ports[mode] = be32_to_cpu(values[1]); - - err = snd_dice_transaction_read_rx(dice, RX_NUMBER_AUDIO, - values, sizeof(values)); - if (err < 0) - return err; - - dice->rx_channels[mode] = be32_to_cpu(values[0]); - dice->rx_midi_ports[mode] = be32_to_cpu(values[1]); - - return 0; -} - -static int dice_read_params(struct snd_dice *dice) +static int check_clock_caps(struct snd_dice *dice) { __be32 value; - int mode, err; + int err; /* some very old firmwares don't tell about their clock support */ if (dice->clock_caps > 0) { @@ -133,12 +116,6 @@ static int dice_read_params(struct snd_dice *dice) CLOCK_CAP_SOURCE_INTERNAL; } - for (mode = 2; mode >= 0; --mode) { - err = dice_read_mode_params(dice, mode); - if (err < 0) - return err; - } - return 0; } @@ -211,11 +188,14 @@ static void do_registration(struct work_struct *work) if (err < 0) return; + if (force_two_pcm_support(dice->unit)) + dice->force_two_pcms = true; + err = snd_dice_transaction_init(dice); if (err < 0) goto error; - err = dice_read_params(dice); + err = check_clock_caps(dice); if (err < 0) goto error; |