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 --- |