dice.c (4b96583869c4d990b779eca72976063970d41b8d) dice.c (7c1543f6b57fa9c0e202c4b5a3cb5ffbb63dc9d0)
1/*
2 * TC Applied Technologies Digital Interface Communications Engine driver
3 *
4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
5 * Licensed under the terms of the GNU General Public License, version 2.
6 */
7
8#include "dice.h"
9
10MODULE_DESCRIPTION("DICE driver");
11MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
12MODULE_LICENSE("GPL v2");
13
14#define OUI_WEISS 0x001c6a
15#define OUI_LOUD 0x000ff2
16#define OUI_FOCUSRITE 0x00130e
17#define OUI_TCELECTRONIC 0x000166
1/*
2 * TC Applied Technologies Digital Interface Communications Engine driver
3 *
4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
5 * Licensed under the terms of the GNU General Public License, version 2.
6 */
7
8#include "dice.h"
9
10MODULE_DESCRIPTION("DICE driver");
11MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
12MODULE_LICENSE("GPL v2");
13
14#define OUI_WEISS 0x001c6a
15#define OUI_LOUD 0x000ff2
16#define OUI_FOCUSRITE 0x00130e
17#define OUI_TCELECTRONIC 0x000166
18#define OUI_ALESIS 0x000595
19#define OUI_MAUDIO 0x000d6c
20#define OUI_MYTEK 0x001ee8
18
19#define DICE_CATEGORY_ID 0x04
20#define WEISS_CATEGORY_ID 0x00
21#define LOUD_CATEGORY_ID 0x10
22
21
22#define DICE_CATEGORY_ID 0x04
23#define WEISS_CATEGORY_ID 0x00
24#define LOUD_CATEGORY_ID 0x10
25
23/*
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 */
27static 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;
26#define MODEL_ALESIS_IO_BOTH 0x000001
40
27
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
53static int check_dice_category(struct fw_unit *unit)
54{
55 struct fw_device *device = fw_parent_device(unit);
56 struct fw_csr_iterator it;
57 int key, val, vendor = -1, model = -1;
58 unsigned int category;
59
60 /*

--- 9 unchanged lines hidden (view full) ---

70 vendor = val;
71 break;
72 case CSR_MODEL:
73 model = val;
74 break;
75 }
76 }
77
28static int check_dice_category(struct fw_unit *unit)
29{
30 struct fw_device *device = fw_parent_device(unit);
31 struct fw_csr_iterator it;
32 int key, val, vendor = -1, model = -1;
33 unsigned int category;
34
35 /*

--- 9 unchanged lines hidden (view full) ---

45 vendor = val;
46 break;
47 case CSR_MODEL:
48 model = val;
49 break;
50 }
51 }
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)
84 category = WEISS_CATEGORY_ID;
85 else if (vendor == OUI_LOUD)
86 category = LOUD_CATEGORY_ID;
87 else
88 category = DICE_CATEGORY_ID;
89 if (device->config_rom[3] != ((vendor << 8) | category) ||
90 device->config_rom[4] >> 22 != model)

--- 90 unchanged lines hidden (view full) ---

181 if (dice->registered)
182 return;
183
184 err = snd_card_new(&dice->unit->device, -1, NULL, THIS_MODULE, 0,
185 &dice->card);
186 if (err < 0)
187 return;
188
53 if (vendor == OUI_WEISS)
54 category = WEISS_CATEGORY_ID;
55 else if (vendor == OUI_LOUD)
56 category = LOUD_CATEGORY_ID;
57 else
58 category = DICE_CATEGORY_ID;
59 if (device->config_rom[3] != ((vendor << 8) | category) ||
60 device->config_rom[4] >> 22 != model)

--- 90 unchanged lines hidden (view full) ---

151 if (dice->registered)
152 return;
153
154 err = snd_card_new(&dice->unit->device, -1, NULL, THIS_MODULE, 0,
155 &dice->card);
156 if (err < 0)
157 return;
158
189 if (force_two_pcm_support(dice->unit))
190 dice->force_two_pcms = true;
191
192 err = snd_dice_transaction_init(dice);
193 if (err < 0)
194 goto error;
195
196 err = check_clock_caps(dice);
197 if (err < 0)
198 goto error;
199
200 dice_card_strings(dice);
201
159 err = snd_dice_transaction_init(dice);
160 if (err < 0)
161 goto error;
162
163 err = check_clock_caps(dice);
164 if (err < 0)
165 goto error;
166
167 dice_card_strings(dice);
168
169 err = dice->detect_formats(dice);
170 if (err < 0)
171 goto error;
172
202 err = snd_dice_stream_init_duplex(dice);
203 if (err < 0)
204 goto error;
205
206 snd_dice_create_proc(dice);
207
208 err = snd_dice_create_pcm(dice);
209 if (err < 0)

--- 24 unchanged lines hidden (view full) ---

234 snd_dice_stream_destroy_duplex(dice);
235 snd_dice_transaction_destroy(dice);
236 snd_dice_stream_destroy_duplex(dice);
237 snd_card_free(dice->card);
238 dev_info(&dice->unit->device,
239 "Sound card registration failed: %d\n", err);
240}
241
173 err = snd_dice_stream_init_duplex(dice);
174 if (err < 0)
175 goto error;
176
177 snd_dice_create_proc(dice);
178
179 err = snd_dice_create_pcm(dice);
180 if (err < 0)

--- 24 unchanged lines hidden (view full) ---

205 snd_dice_stream_destroy_duplex(dice);
206 snd_dice_transaction_destroy(dice);
207 snd_dice_stream_destroy_duplex(dice);
208 snd_card_free(dice->card);
209 dev_info(&dice->unit->device,
210 "Sound card registration failed: %d\n", err);
211}
212
242static int dice_probe(struct fw_unit *unit, const struct ieee1394_device_id *id)
213static int dice_probe(struct fw_unit *unit,
214 const struct ieee1394_device_id *entry)
243{
244 struct snd_dice *dice;
245 int err;
246
215{
216 struct snd_dice *dice;
217 int err;
218
247 err = check_dice_category(unit);
248 if (err < 0)
249 return -ENODEV;
219 if (!entry->driver_data) {
220 err = check_dice_category(unit);
221 if (err < 0)
222 return -ENODEV;
223 }
250
251 /* Allocate this independent of sound card instance. */
252 dice = kzalloc(sizeof(struct snd_dice), GFP_KERNEL);
253 if (dice == NULL)
254 return -ENOMEM;
255
256 dice->unit = fw_unit_get(unit);
257 dev_set_drvdata(&unit->device, dice);
258
224
225 /* Allocate this independent of sound card instance. */
226 dice = kzalloc(sizeof(struct snd_dice), GFP_KERNEL);
227 if (dice == NULL)
228 return -ENOMEM;
229
230 dice->unit = fw_unit_get(unit);
231 dev_set_drvdata(&unit->device, dice);
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);
260 mutex_init(&dice->mutex);
261 init_completion(&dice->clock_accepted);
262 init_waitqueue_head(&dice->hwdep_wait);
263
264 /* Allocate and register this sound card later. */
265 INIT_DEFERRABLE_WORK(&dice->dwork, do_registration);
266 snd_fw_schedule_registration(unit, &dice->dwork);

--- 41 unchanged lines hidden (view full) ---

308 snd_dice_stream_update_duplex(dice);
309 mutex_unlock(&dice->mutex);
310 }
311}
312
313#define DICE_INTERFACE 0x000001
314
315static const struct ieee1394_device_id dice_id_table[] = {
240 spin_lock_init(&dice->lock);
241 mutex_init(&dice->mutex);
242 init_completion(&dice->clock_accepted);
243 init_waitqueue_head(&dice->hwdep_wait);
244
245 /* Allocate and register this sound card later. */
246 INIT_DEFERRABLE_WORK(&dice->dwork, do_registration);
247 snd_fw_schedule_registration(unit, &dice->dwork);

--- 41 unchanged lines hidden (view full) ---

289 snd_dice_stream_update_duplex(dice);
290 mutex_unlock(&dice->mutex);
291 }
292}
293
294#define DICE_INTERFACE 0x000001
295
296static 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,
318 .version = DICE_INTERFACE,
299 .match_flags = IEEE1394_MATCH_VENDOR_ID |
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 {
322 .match_flags = IEEE1394_MATCH_VENDOR_ID |
306 {
307 .match_flags = IEEE1394_MATCH_VENDOR_ID |
323 IEEE1394_MATCH_SPECIFIER_ID,
324 .vendor_id = 0x000d6c,
325 .specifier_id = 0x000d6c,
308 IEEE1394_MATCH_MODEL_ID,
309 .vendor_id = OUI_MAUDIO,
310 .model_id = 0x000011,
311 .driver_data = (kernel_ulong_t)snd_dice_detect_extension_formats,
326 },
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 /* Alesis iO14/iO26. */
362 {
363 .match_flags = IEEE1394_MATCH_VENDOR_ID |
364 IEEE1394_MATCH_MODEL_ID,
365 .vendor_id = OUI_ALESIS,
366 .model_id = MODEL_ALESIS_IO_BOTH,
367 .driver_data = (kernel_ulong_t)snd_dice_detect_alesis_formats,
368 },
369 /* Mytek Stereo 192 DSD-DAC. */
370 {
371 .match_flags = IEEE1394_MATCH_VENDOR_ID |
372 IEEE1394_MATCH_MODEL_ID,
373 .vendor_id = OUI_MYTEK,
374 .model_id = 0x000002,
375 .driver_data = (kernel_ulong_t)snd_dice_detect_mytek_formats,
376 },
377 {
378 .match_flags = IEEE1394_MATCH_VERSION,
379 .version = DICE_INTERFACE,
380 },
327 { }
328};
329MODULE_DEVICE_TABLE(ieee1394, dice_id_table);
330
331static struct fw_driver dice_driver = {
332 .driver = {
333 .owner = THIS_MODULE,
334 .name = KBUILD_MODNAME,

--- 20 unchanged lines hidden ---
381 { }
382};
383MODULE_DEVICE_TABLE(ieee1394, dice_id_table);
384
385static struct fw_driver dice_driver = {
386 .driver = {
387 .owner = THIS_MODULE,
388 .name = KBUILD_MODNAME,

--- 20 unchanged lines hidden ---