diff options
Diffstat (limited to 'sound/pci/rme9652/hdspm.c')
-rw-r--r-- | sound/pci/rme9652/hdspm.c | 109 |
1 files changed, 107 insertions, 2 deletions
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c index af130ee0c45d..6edc67ced905 100644 --- a/sound/pci/rme9652/hdspm.c +++ b/sound/pci/rme9652/hdspm.c | |||
@@ -521,6 +521,7 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}"); | |||
521 | #define HDSPM_DMA_AREA_KILOBYTES (HDSPM_DMA_AREA_BYTES/1024) | 521 | #define HDSPM_DMA_AREA_KILOBYTES (HDSPM_DMA_AREA_BYTES/1024) |
522 | 522 | ||
523 | /* revisions >= 230 indicate AES32 card */ | 523 | /* revisions >= 230 indicate AES32 card */ |
524 | #define HDSPM_MADI_ANCIENT_REV 204 | ||
524 | #define HDSPM_MADI_OLD_REV 207 | 525 | #define HDSPM_MADI_OLD_REV 207 |
525 | #define HDSPM_MADI_REV 210 | 526 | #define HDSPM_MADI_REV 210 |
526 | #define HDSPM_RAYDAT_REV 211 | 527 | #define HDSPM_RAYDAT_REV 211 |
@@ -1217,6 +1218,22 @@ static int hdspm_external_sample_rate(struct hdspm *hdspm) | |||
1217 | rate = 0; | 1218 | rate = 0; |
1218 | break; | 1219 | break; |
1219 | } | 1220 | } |
1221 | |||
1222 | /* QS and DS rates normally can not be detected | ||
1223 | * automatically by the card. Only exception is MADI | ||
1224 | * in 96k frame mode. | ||
1225 | * | ||
1226 | * So if we read SS values (32 .. 48k), check for | ||
1227 | * user-provided DS/QS bits in the control register | ||
1228 | * and multiply the base frequency accordingly. | ||
1229 | */ | ||
1230 | if (rate <= 48000) { | ||
1231 | if (hdspm->control_register & HDSPM_QuadSpeed) | ||
1232 | rate *= 4; | ||
1233 | else if (hdspm->control_register & | ||
1234 | HDSPM_DoubleSpeed) | ||
1235 | rate *= 2; | ||
1236 | } | ||
1220 | } | 1237 | } |
1221 | break; | 1238 | break; |
1222 | } | 1239 | } |
@@ -3415,6 +3432,91 @@ static int snd_hdspm_put_qs_wire(struct snd_kcontrol *kcontrol, | |||
3415 | return change; | 3432 | return change; |
3416 | } | 3433 | } |
3417 | 3434 | ||
3435 | #define HDSPM_MADI_SPEEDMODE(xname, xindex) \ | ||
3436 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | ||
3437 | .name = xname, \ | ||
3438 | .index = xindex, \ | ||
3439 | .info = snd_hdspm_info_madi_speedmode, \ | ||
3440 | .get = snd_hdspm_get_madi_speedmode, \ | ||
3441 | .put = snd_hdspm_put_madi_speedmode \ | ||
3442 | } | ||
3443 | |||
3444 | static int hdspm_madi_speedmode(struct hdspm *hdspm) | ||
3445 | { | ||
3446 | if (hdspm->control_register & HDSPM_QuadSpeed) | ||
3447 | return 2; | ||
3448 | if (hdspm->control_register & HDSPM_DoubleSpeed) | ||
3449 | return 1; | ||
3450 | return 0; | ||
3451 | } | ||
3452 | |||
3453 | static int hdspm_set_madi_speedmode(struct hdspm *hdspm, int mode) | ||
3454 | { | ||
3455 | hdspm->control_register &= ~(HDSPM_DoubleSpeed | HDSPM_QuadSpeed); | ||
3456 | switch (mode) { | ||
3457 | case 0: | ||
3458 | break; | ||
3459 | case 1: | ||
3460 | hdspm->control_register |= HDSPM_DoubleSpeed; | ||
3461 | break; | ||
3462 | case 2: | ||
3463 | hdspm->control_register |= HDSPM_QuadSpeed; | ||
3464 | break; | ||
3465 | } | ||
3466 | hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register); | ||
3467 | |||
3468 | return 0; | ||
3469 | } | ||
3470 | |||
3471 | static int snd_hdspm_info_madi_speedmode(struct snd_kcontrol *kcontrol, | ||
3472 | struct snd_ctl_elem_info *uinfo) | ||
3473 | { | ||
3474 | static char *texts[] = { "Single", "Double", "Quad" }; | ||
3475 | |||
3476 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
3477 | uinfo->count = 1; | ||
3478 | uinfo->value.enumerated.items = 3; | ||
3479 | |||
3480 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | ||
3481 | uinfo->value.enumerated.item = | ||
3482 | uinfo->value.enumerated.items - 1; | ||
3483 | strcpy(uinfo->value.enumerated.name, | ||
3484 | texts[uinfo->value.enumerated.item]); | ||
3485 | |||
3486 | return 0; | ||
3487 | } | ||
3488 | |||
3489 | static int snd_hdspm_get_madi_speedmode(struct snd_kcontrol *kcontrol, | ||
3490 | struct snd_ctl_elem_value *ucontrol) | ||
3491 | { | ||
3492 | struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); | ||
3493 | |||
3494 | spin_lock_irq(&hdspm->lock); | ||
3495 | ucontrol->value.enumerated.item[0] = hdspm_madi_speedmode(hdspm); | ||
3496 | spin_unlock_irq(&hdspm->lock); | ||
3497 | return 0; | ||
3498 | } | ||
3499 | |||
3500 | static int snd_hdspm_put_madi_speedmode(struct snd_kcontrol *kcontrol, | ||
3501 | struct snd_ctl_elem_value *ucontrol) | ||
3502 | { | ||
3503 | struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); | ||
3504 | int change; | ||
3505 | int val; | ||
3506 | |||
3507 | if (!snd_hdspm_use_is_exclusive(hdspm)) | ||
3508 | return -EBUSY; | ||
3509 | val = ucontrol->value.integer.value[0]; | ||
3510 | if (val < 0) | ||
3511 | val = 0; | ||
3512 | if (val > 2) | ||
3513 | val = 2; | ||
3514 | spin_lock_irq(&hdspm->lock); | ||
3515 | change = val != hdspm_madi_speedmode(hdspm); | ||
3516 | hdspm_set_madi_speedmode(hdspm, val); | ||
3517 | spin_unlock_irq(&hdspm->lock); | ||
3518 | return change; | ||
3519 | } | ||
3418 | 3520 | ||
3419 | #define HDSPM_MIXER(xname, xindex) \ | 3521 | #define HDSPM_MIXER(xname, xindex) \ |
3420 | { .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ | 3522 | { .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ |
@@ -4289,7 +4391,8 @@ static struct snd_kcontrol_new snd_hdspm_controls_madi[] = { | |||
4289 | HDSPM_TX_64("TX 64 channels mode", 0), | 4391 | HDSPM_TX_64("TX 64 channels mode", 0), |
4290 | HDSPM_C_TMS("Clear Track Marker", 0), | 4392 | HDSPM_C_TMS("Clear Track Marker", 0), |
4291 | HDSPM_SAFE_MODE("Safe Mode", 0), | 4393 | HDSPM_SAFE_MODE("Safe Mode", 0), |
4292 | HDSPM_INPUT_SELECT("Input Select", 0) | 4394 | HDSPM_INPUT_SELECT("Input Select", 0), |
4395 | HDSPM_MADI_SPEEDMODE("MADI Speed Mode", 0) | ||
4293 | }; | 4396 | }; |
4294 | 4397 | ||
4295 | 4398 | ||
@@ -4302,7 +4405,8 @@ static struct snd_kcontrol_new snd_hdspm_controls_madiface[] = { | |||
4302 | HDSPM_SYNC_CHECK("MADI SyncCheck", 0), | 4405 | HDSPM_SYNC_CHECK("MADI SyncCheck", 0), |
4303 | HDSPM_TX_64("TX 64 channels mode", 0), | 4406 | HDSPM_TX_64("TX 64 channels mode", 0), |
4304 | HDSPM_C_TMS("Clear Track Marker", 0), | 4407 | HDSPM_C_TMS("Clear Track Marker", 0), |
4305 | HDSPM_SAFE_MODE("Safe Mode", 0) | 4408 | HDSPM_SAFE_MODE("Safe Mode", 0), |
4409 | HDSPM_MADI_SPEEDMODE("MADI Speed Mode", 0) | ||
4306 | }; | 4410 | }; |
4307 | 4411 | ||
4308 | static struct snd_kcontrol_new snd_hdspm_controls_aio[] = { | 4412 | static struct snd_kcontrol_new snd_hdspm_controls_aio[] = { |
@@ -6381,6 +6485,7 @@ static int __devinit snd_hdspm_create(struct snd_card *card, | |||
6381 | switch (hdspm->firmware_rev) { | 6485 | switch (hdspm->firmware_rev) { |
6382 | case HDSPM_MADI_REV: | 6486 | case HDSPM_MADI_REV: |
6383 | case HDSPM_MADI_OLD_REV: | 6487 | case HDSPM_MADI_OLD_REV: |
6488 | case HDSPM_MADI_ANCIENT_REV: | ||
6384 | hdspm->io_type = MADI; | 6489 | hdspm->io_type = MADI; |
6385 | hdspm->card_name = "RME MADI"; | 6490 | hdspm->card_name = "RME MADI"; |
6386 | hdspm->midiPorts = 3; | 6491 | hdspm->midiPorts = 3; |