aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>2016-03-07 08:35:45 -0500
committerTakashi Iwai <tiwai@suse.de>2016-03-09 10:20:58 -0500
commit7cafc65b3aa1b6970f92211c55712f115d876cfc (patch)
tree639f2a0953885e915a123745d950f190b170e156
parent4bdc495c87b323721eace38c581d7bd2652aa613 (diff)
ALSA: dice: force to add two pcm devices for listed models
Some models reduce the number of available isochronous streams for higher sampling transfer frequency. Such models bring an issue about how to add PCM substreams. When at lower sampling transfer frequency, the models reports whole available streams, thus this driver can add enough number of PCM substreams at probing time. On the other hand, at higher sampling transfer frequency, this driver can just add reduced number of PCM substreams. After probed, even if the sampling transfer frequency is changed to lower rate, fewer PCM substreams are actually available. This is inconvenience. For the reason, this commit adds a list so that this driver assume models on the list to have two pairs of PCM substreams. This list keeps the name of model in which the number of available streams differs depending on sampling transfer frequency. Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--sound/firewire/dice/dice-pcm.c24
-rw-r--r--sound/firewire/dice/dice.c41
-rw-r--r--sound/firewire/dice/dice.h2
3 files changed, 58 insertions, 9 deletions
diff --git a/sound/firewire/dice/dice-pcm.c b/sound/firewire/dice/dice-pcm.c
index 05e2e18b4c30..4aa0249826fd 100644
--- a/sound/firewire/dice/dice-pcm.c
+++ b/sound/firewire/dice/dice-pcm.c
@@ -332,16 +332,22 @@ int snd_dice_create_pcm(struct snd_dice *dice)
332 int err; 332 int err;
333 333
334 /* Check whether PCM substreams are required. */ 334 /* Check whether PCM substreams are required. */
335 max_capture = max_playback = 0; 335 if (dice->force_two_pcms) {
336 err = snd_dice_transaction_read_tx(dice, TX_NUMBER, &reg, sizeof(reg)); 336 max_capture = max_playback = 2;
337 if (err < 0) 337 } else {
338 return err; 338 max_capture = max_playback = 0;
339 max_capture = min_t(unsigned int, be32_to_cpu(reg), MAX_STREAMS); 339 err = snd_dice_transaction_read_tx(dice, TX_NUMBER, &reg,
340 sizeof(reg));
341 if (err < 0)
342 return err;
343 max_capture = min_t(unsigned int, be32_to_cpu(reg), MAX_STREAMS);
340 344
341 err = snd_dice_transaction_read_rx(dice, RX_NUMBER, &reg, sizeof(reg)); 345 err = snd_dice_transaction_read_rx(dice, RX_NUMBER, &reg,
342 if (err < 0) 346 sizeof(reg));
343 return err; 347 if (err < 0)
344 max_playback = min_t(unsigned int, be32_to_cpu(reg), MAX_STREAMS); 348 return err;
349 max_playback = min_t(unsigned int, be32_to_cpu(reg), MAX_STREAMS);
350 }
345 351
346 for (i = 0; i < MAX_STREAMS; i++) { 352 for (i = 0; i < MAX_STREAMS; i++) {
347 capture = playback = 0; 353 capture = playback = 0;
diff --git a/sound/firewire/dice/dice.c b/sound/firewire/dice/dice.c
index f7303a650ac2..8b64aef31a86 100644
--- a/sound/firewire/dice/dice.c
+++ b/sound/firewire/dice/dice.c
@@ -13,6 +13,8 @@ MODULE_LICENSE("GPL v2");
13 13
14#define OUI_WEISS 0x001c6a 14#define OUI_WEISS 0x001c6a
15#define OUI_LOUD 0x000ff2 15#define OUI_LOUD 0x000ff2
16#define OUI_FOCUSRITE 0x00130e
17#define OUI_TCELECTRONIC 0x001486
16 18
17#define DICE_CATEGORY_ID 0x04 19#define DICE_CATEGORY_ID 0x04
18#define WEISS_CATEGORY_ID 0x00 20#define WEISS_CATEGORY_ID 0x00
@@ -20,6 +22,36 @@ MODULE_LICENSE("GPL v2");
20 22
21#define PROBE_DELAY_MS (2 * MSEC_PER_SEC) 23#define PROBE_DELAY_MS (2 * MSEC_PER_SEC)
22 24
25/*
26 * Some models support several isochronous channels, while these streams are not
27 * always available. In this case, add the model name to this list.
28 */
29static bool force_two_pcm_support(struct fw_unit *unit)
30{
31 const char *const models[] = {
32 /* TC Electronic models. */
33 "StudioKonnekt48",
34 /* Focusrite models. */
35 "SAFFIRE_PRO_40",
36 "LIQUID_SAFFIRE_56",
37 "SAFFIRE_PRO_40_1",
38 };
39 char model[32];
40 unsigned int i;
41 int err;
42
43 err = fw_csr_string(unit->directory, CSR_MODEL, model, sizeof(model));
44 if (err < 0)
45 return false;
46
47 for (i = 0; i < ARRAY_SIZE(models); i++) {
48 if (strcmp(models[i], model) == 0)
49 break;
50 }
51
52 return i < ARRAY_SIZE(models);
53}
54
23static int check_dice_category(struct fw_unit *unit) 55static int check_dice_category(struct fw_unit *unit)
24{ 56{
25 struct fw_device *device = fw_parent_device(unit); 57 struct fw_device *device = fw_parent_device(unit);
@@ -44,6 +76,12 @@ static int check_dice_category(struct fw_unit *unit)
44 break; 76 break;
45 } 77 }
46 } 78 }
79
80 if (vendor == OUI_FOCUSRITE || vendor == OUI_TCELECTRONIC) {
81 if (force_two_pcm_support(unit))
82 return 0;
83 }
84
47 if (vendor == OUI_WEISS) 85 if (vendor == OUI_WEISS)
48 category = WEISS_CATEGORY_ID; 86 category = WEISS_CATEGORY_ID;
49 else if (vendor == OUI_LOUD) 87 else if (vendor == OUI_LOUD)
@@ -150,6 +188,9 @@ static void do_registration(struct work_struct *work)
150 if (err < 0) 188 if (err < 0)
151 return; 189 return;
152 190
191 if (force_two_pcm_support(dice->unit))
192 dice->force_two_pcms = true;
193
153 err = snd_dice_transaction_init(dice); 194 err = snd_dice_transaction_init(dice);
154 if (err < 0) 195 if (err < 0)
155 goto error; 196 goto error;
diff --git a/sound/firewire/dice/dice.h b/sound/firewire/dice/dice.h
index 8fba87d83810..e6c07857f475 100644
--- a/sound/firewire/dice/dice.h
+++ b/sound/firewire/dice/dice.h
@@ -97,6 +97,8 @@ struct snd_dice {
97 bool global_enabled; 97 bool global_enabled;
98 struct completion clock_accepted; 98 struct completion clock_accepted;
99 unsigned int substreams_counter; 99 unsigned int substreams_counter;
100
101 bool force_two_pcms;
100}; 102};
101 103
102enum snd_dice_addr_type { 104enum snd_dice_addr_type {