diff options
Diffstat (limited to 'sound/firewire/dice/dice.c')
-rw-r--r-- | sound/firewire/dice/dice.c | 156 |
1 files changed, 109 insertions, 47 deletions
diff --git a/sound/firewire/dice/dice.c b/sound/firewire/dice/dice.c index 96bb01b6b751..774eb2205668 100644 --- a/sound/firewire/dice/dice.c +++ b/sound/firewire/dice/dice.c | |||
@@ -15,40 +15,15 @@ MODULE_LICENSE("GPL v2"); | |||
15 | #define OUI_LOUD 0x000ff2 | 15 | #define OUI_LOUD 0x000ff2 |
16 | #define OUI_FOCUSRITE 0x00130e | 16 | #define OUI_FOCUSRITE 0x00130e |
17 | #define OUI_TCELECTRONIC 0x000166 | 17 | #define OUI_TCELECTRONIC 0x000166 |
18 | #define OUI_ALESIS 0x000595 | ||
19 | #define OUI_MAUDIO 0x000d6c | ||
20 | #define OUI_MYTEK 0x001ee8 | ||
18 | 21 | ||
19 | #define DICE_CATEGORY_ID 0x04 | 22 | #define DICE_CATEGORY_ID 0x04 |
20 | #define WEISS_CATEGORY_ID 0x00 | 23 | #define WEISS_CATEGORY_ID 0x00 |
21 | #define LOUD_CATEGORY_ID 0x10 | 24 | #define LOUD_CATEGORY_ID 0x10 |
22 | 25 | ||
23 | /* | 26 | #define MODEL_ALESIS_IO_BOTH 0x000001 |
24 | * Some models support several isochronous channels, while these streams are not | ||
25 | * always available. In this case, add the model name to this list. | ||
26 | */ | ||
27 | static bool force_two_pcm_support(struct fw_unit *unit) | ||
28 | { | ||
29 | static const char *const models[] = { | ||
30 | /* TC Electronic models. */ | ||
31 | "StudioKonnekt48", | ||
32 | /* Focusrite models. */ | ||
33 | "SAFFIRE_PRO_40", | ||
34 | "LIQUID_SAFFIRE_56", | ||
35 | "SAFFIRE_PRO_40_1", | ||
36 | }; | ||
37 | char model[32]; | ||
38 | unsigned int i; | ||
39 | int err; | ||
40 | |||
41 | err = fw_csr_string(unit->directory, CSR_MODEL, model, sizeof(model)); | ||
42 | if (err < 0) | ||
43 | return false; | ||
44 | |||
45 | for (i = 0; i < ARRAY_SIZE(models); i++) { | ||
46 | if (strcmp(models[i], model) == 0) | ||
47 | break; | ||
48 | } | ||
49 | |||
50 | return i < ARRAY_SIZE(models); | ||
51 | } | ||
52 | 27 | ||
53 | static int check_dice_category(struct fw_unit *unit) | 28 | static int check_dice_category(struct fw_unit *unit) |
54 | { | 29 | { |
@@ -75,11 +50,6 @@ static int check_dice_category(struct fw_unit *unit) | |||
75 | } | 50 | } |
76 | } | 51 | } |
77 | 52 | ||
78 | if (vendor == OUI_FOCUSRITE || vendor == OUI_TCELECTRONIC) { | ||
79 | if (force_two_pcm_support(unit)) | ||
80 | return 0; | ||
81 | } | ||
82 | |||
83 | if (vendor == OUI_WEISS) | 53 | if (vendor == OUI_WEISS) |
84 | category = WEISS_CATEGORY_ID; | 54 | category = WEISS_CATEGORY_ID; |
85 | else if (vendor == OUI_LOUD) | 55 | else if (vendor == OUI_LOUD) |
@@ -186,9 +156,6 @@ static void do_registration(struct work_struct *work) | |||
186 | if (err < 0) | 156 | if (err < 0) |
187 | return; | 157 | return; |
188 | 158 | ||
189 | if (force_two_pcm_support(dice->unit)) | ||
190 | dice->force_two_pcms = true; | ||
191 | |||
192 | err = snd_dice_transaction_init(dice); | 159 | err = snd_dice_transaction_init(dice); |
193 | if (err < 0) | 160 | if (err < 0) |
194 | goto error; | 161 | goto error; |
@@ -199,6 +166,10 @@ static void do_registration(struct work_struct *work) | |||
199 | 166 | ||
200 | dice_card_strings(dice); | 167 | dice_card_strings(dice); |
201 | 168 | ||
169 | err = dice->detect_formats(dice); | ||
170 | if (err < 0) | ||
171 | goto error; | ||
172 | |||
202 | err = snd_dice_stream_init_duplex(dice); | 173 | err = snd_dice_stream_init_duplex(dice); |
203 | if (err < 0) | 174 | if (err < 0) |
204 | goto error; | 175 | goto error; |
@@ -239,14 +210,17 @@ error: | |||
239 | "Sound card registration failed: %d\n", err); | 210 | "Sound card registration failed: %d\n", err); |
240 | } | 211 | } |
241 | 212 | ||
242 | static int dice_probe(struct fw_unit *unit, const struct ieee1394_device_id *id) | 213 | static int dice_probe(struct fw_unit *unit, |
214 | const struct ieee1394_device_id *entry) | ||
243 | { | 215 | { |
244 | struct snd_dice *dice; | 216 | struct snd_dice *dice; |
245 | int err; | 217 | int err; |
246 | 218 | ||
247 | err = check_dice_category(unit); | 219 | if (!entry->driver_data) { |
248 | if (err < 0) | 220 | err = check_dice_category(unit); |
249 | return -ENODEV; | 221 | if (err < 0) |
222 | return -ENODEV; | ||
223 | } | ||
250 | 224 | ||
251 | /* Allocate this independent of sound card instance. */ | 225 | /* Allocate this independent of sound card instance. */ |
252 | dice = kzalloc(sizeof(struct snd_dice), GFP_KERNEL); | 226 | dice = kzalloc(sizeof(struct snd_dice), GFP_KERNEL); |
@@ -256,6 +230,13 @@ static int dice_probe(struct fw_unit *unit, const struct ieee1394_device_id *id) | |||
256 | dice->unit = fw_unit_get(unit); | 230 | dice->unit = fw_unit_get(unit); |
257 | dev_set_drvdata(&unit->device, dice); | 231 | dev_set_drvdata(&unit->device, dice); |
258 | 232 | ||
233 | if (!entry->driver_data) { | ||
234 | dice->detect_formats = snd_dice_stream_detect_current_formats; | ||
235 | } else { | ||
236 | dice->detect_formats = | ||
237 | (snd_dice_detect_formats_t)entry->driver_data; | ||
238 | } | ||
239 | |||
259 | spin_lock_init(&dice->lock); | 240 | spin_lock_init(&dice->lock); |
260 | mutex_init(&dice->mutex); | 241 | mutex_init(&dice->mutex); |
261 | init_completion(&dice->clock_accepted); | 242 | init_completion(&dice->clock_accepted); |
@@ -313,16 +294,97 @@ static void dice_bus_reset(struct fw_unit *unit) | |||
313 | #define DICE_INTERFACE 0x000001 | 294 | #define DICE_INTERFACE 0x000001 |
314 | 295 | ||
315 | static const struct ieee1394_device_id dice_id_table[] = { | 296 | static const struct ieee1394_device_id dice_id_table[] = { |
297 | /* M-Audio Profire 2626 has a different value in version field. */ | ||
316 | { | 298 | { |
317 | .match_flags = IEEE1394_MATCH_VERSION, | 299 | .match_flags = IEEE1394_MATCH_VENDOR_ID | |
318 | .version = DICE_INTERFACE, | 300 | IEEE1394_MATCH_MODEL_ID, |
301 | .vendor_id = OUI_MAUDIO, | ||
302 | .model_id = 0x000010, | ||
303 | .driver_data = (kernel_ulong_t)snd_dice_detect_extension_formats, | ||
319 | }, | 304 | }, |
320 | /* M-Audio Profire 610/2626 has a different value in version field. */ | 305 | /* M-Audio Profire 610 has a different value in version field. */ |
321 | { | 306 | { |
322 | .match_flags = IEEE1394_MATCH_VENDOR_ID | | 307 | .match_flags = IEEE1394_MATCH_VENDOR_ID | |
323 | IEEE1394_MATCH_SPECIFIER_ID, | 308 | IEEE1394_MATCH_MODEL_ID, |
324 | .vendor_id = 0x000d6c, | 309 | .vendor_id = OUI_MAUDIO, |
325 | .specifier_id = 0x000d6c, | 310 | .model_id = 0x000011, |
311 | .driver_data = (kernel_ulong_t)snd_dice_detect_extension_formats, | ||
312 | }, | ||
313 | /* TC Electronic Konnekt 24D. */ | ||
314 | { | ||
315 | .match_flags = IEEE1394_MATCH_VENDOR_ID | | ||
316 | IEEE1394_MATCH_MODEL_ID, | ||
317 | .vendor_id = OUI_TCELECTRONIC, | ||
318 | .model_id = 0x000020, | ||
319 | .driver_data = (kernel_ulong_t)snd_dice_detect_tcelectronic_formats, | ||
320 | }, | ||
321 | /* TC Electronic Konnekt 8. */ | ||
322 | { | ||
323 | .match_flags = IEEE1394_MATCH_VENDOR_ID | | ||
324 | IEEE1394_MATCH_MODEL_ID, | ||
325 | .vendor_id = OUI_TCELECTRONIC, | ||
326 | .model_id = 0x000021, | ||
327 | .driver_data = (kernel_ulong_t)snd_dice_detect_tcelectronic_formats, | ||
328 | }, | ||
329 | /* TC Electronic Studio Konnekt 48. */ | ||
330 | { | ||
331 | .match_flags = IEEE1394_MATCH_VENDOR_ID | | ||
332 | IEEE1394_MATCH_MODEL_ID, | ||
333 | .vendor_id = OUI_TCELECTRONIC, | ||
334 | .model_id = 0x000022, | ||
335 | .driver_data = (kernel_ulong_t)snd_dice_detect_tcelectronic_formats, | ||
336 | }, | ||
337 | /* TC Electronic Konnekt Live. */ | ||
338 | { | ||
339 | .match_flags = IEEE1394_MATCH_VENDOR_ID | | ||
340 | IEEE1394_MATCH_MODEL_ID, | ||
341 | .vendor_id = OUI_TCELECTRONIC, | ||
342 | .model_id = 0x000023, | ||
343 | .driver_data = (kernel_ulong_t)snd_dice_detect_tcelectronic_formats, | ||
344 | }, | ||
345 | /* TC Electronic Desktop Konnekt 6. */ | ||
346 | { | ||
347 | .match_flags = IEEE1394_MATCH_VENDOR_ID | | ||
348 | IEEE1394_MATCH_MODEL_ID, | ||
349 | .vendor_id = OUI_TCELECTRONIC, | ||
350 | .model_id = 0x000024, | ||
351 | .driver_data = (kernel_ulong_t)snd_dice_detect_tcelectronic_formats, | ||
352 | }, | ||
353 | /* TC Electronic Impact Twin. */ | ||
354 | { | ||
355 | .match_flags = IEEE1394_MATCH_VENDOR_ID | | ||
356 | IEEE1394_MATCH_MODEL_ID, | ||
357 | .vendor_id = OUI_TCELECTRONIC, | ||
358 | .model_id = 0x000027, | ||
359 | .driver_data = (kernel_ulong_t)snd_dice_detect_tcelectronic_formats, | ||
360 | }, | ||
361 | /* TC Electronic Digital Konnekt x32. */ | ||
362 | { | ||
363 | .match_flags = IEEE1394_MATCH_VENDOR_ID | | ||
364 | IEEE1394_MATCH_MODEL_ID, | ||
365 | .vendor_id = OUI_TCELECTRONIC, | ||
366 | .model_id = 0x000030, | ||
367 | .driver_data = (kernel_ulong_t)snd_dice_detect_tcelectronic_formats, | ||
368 | }, | ||
369 | /* Alesis iO14/iO26. */ | ||
370 | { | ||
371 | .match_flags = IEEE1394_MATCH_VENDOR_ID | | ||
372 | IEEE1394_MATCH_MODEL_ID, | ||
373 | .vendor_id = OUI_ALESIS, | ||
374 | .model_id = MODEL_ALESIS_IO_BOTH, | ||
375 | .driver_data = (kernel_ulong_t)snd_dice_detect_alesis_formats, | ||
376 | }, | ||
377 | /* Mytek Stereo 192 DSD-DAC. */ | ||
378 | { | ||
379 | .match_flags = IEEE1394_MATCH_VENDOR_ID | | ||
380 | IEEE1394_MATCH_MODEL_ID, | ||
381 | .vendor_id = OUI_MYTEK, | ||
382 | .model_id = 0x000002, | ||
383 | .driver_data = (kernel_ulong_t)snd_dice_detect_mytek_formats, | ||
384 | }, | ||
385 | { | ||
386 | .match_flags = IEEE1394_MATCH_VERSION, | ||
387 | .version = DICE_INTERFACE, | ||
326 | }, | 388 | }, |
327 | { } | 389 | { } |
328 | }; | 390 | }; |