Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ALSA: hdsp - Add support for RPM io box

Add support for the RME HDSP RPM IO box. Changes have been made in the identification of the IO box and the neccessary controls have been added.

Signed-off-by: Florian Faber <faberman@linuxproaudio.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>

authored by

Florian Faber and committed by
Takashi Iwai
28b26e15 03cfe6f5

+482 -57
+1
include/sound/hdsp.h
··· 28 28 Multiface, 29 29 H9652, 30 30 H9632, 31 + RPM, 31 32 Undefined, 32 33 }; 33 34
+481 -57
sound/pci/rme9652/hdsp.c
··· 60 60 "{RME HDSP-9652}," 61 61 "{RME HDSP-9632}}"); 62 62 #ifdef HDSP_FW_LOADER 63 + MODULE_FIRMWARE("rpm_firmware.bin"); 63 64 MODULE_FIRMWARE("multiface_firmware.bin"); 64 65 MODULE_FIRMWARE("multiface_firmware_rev11.bin"); 65 66 MODULE_FIRMWARE("digiface_firmware.bin"); ··· 82 81 #define H9632_SS_CHANNELS 12 83 82 #define H9632_DS_CHANNELS 8 84 83 #define H9632_QS_CHANNELS 4 84 + #define RPM_CHANNELS 6 85 85 86 86 /* Write registers. These are defined as byte-offsets from the iobase value. 87 87 */ ··· 192 190 #define HDSP_PhoneGain0 (1<<29) 193 191 #define HDSP_PhoneGain1 (1<<30) 194 192 #define HDSP_QuadSpeed (1<<31) 193 + 194 + /* RPM uses some of the registers for special purposes */ 195 + #define HDSP_RPM_Inp12 0x04A00 196 + #define HDSP_RPM_Inp12_Phon_6dB 0x00800 /* Dolby */ 197 + #define HDSP_RPM_Inp12_Phon_0dB 0x00000 /* .. */ 198 + #define HDSP_RPM_Inp12_Phon_n6dB 0x04000 /* inp_0 */ 199 + #define HDSP_RPM_Inp12_Line_0dB 0x04200 /* Dolby+PRO */ 200 + #define HDSP_RPM_Inp12_Line_n6dB 0x00200 /* PRO */ 201 + 202 + #define HDSP_RPM_Inp34 0x32000 203 + #define HDSP_RPM_Inp34_Phon_6dB 0x20000 /* SyncRef1 */ 204 + #define HDSP_RPM_Inp34_Phon_0dB 0x00000 /* .. */ 205 + #define HDSP_RPM_Inp34_Phon_n6dB 0x02000 /* SyncRef2 */ 206 + #define HDSP_RPM_Inp34_Line_0dB 0x30000 /* SyncRef1+SyncRef0 */ 207 + #define HDSP_RPM_Inp34_Line_n6dB 0x10000 /* SyncRef0 */ 208 + 209 + #define HDSP_RPM_Bypass 0x01000 210 + 211 + #define HDSP_RPM_Disconnect 0x00001 195 212 196 213 #define HDSP_ADGainMask (HDSP_ADGain0|HDSP_ADGain1) 197 214 #define HDSP_ADGainMinus10dBV HDSP_ADGainMask ··· 471 450 u32 creg_spdif; 472 451 u32 creg_spdif_stream; 473 452 int clock_source_locked; 474 - char *card_name; /* digiface/multiface */ 453 + char *card_name; /* digiface/multiface/rpm */ 475 454 enum HDSP_IO_Type io_type; /* ditto, but for code use */ 476 455 unsigned short firmware_rev; 477 456 unsigned short state; /* stores state bits */ ··· 633 612 switch (hdsp->io_type) { 634 613 case Multiface: 635 614 case Digiface: 615 + case RPM: 636 616 default: 637 617 if (hdsp->firmware_rev == 0xa) 638 618 return (64 * out) + (32 + (in)); ··· 651 629 switch (hdsp->io_type) { 652 630 case Multiface: 653 631 case Digiface: 632 + case RPM: 654 633 default: 655 634 if (hdsp->firmware_rev == 0xa) 656 635 return (64 * out) + in; ··· 678 655 { 679 656 if (hdsp->io_type == H9652 || hdsp->io_type == H9632) return 0; 680 657 if (hdsp_read (hdsp, HDSP_statusRegister) & HDSP_ConfigError) { 681 - snd_printk ("Hammerfall-DSP: no Digiface or Multiface connected!\n"); 658 + snd_printk("Hammerfall-DSP: no IO box connected!\n"); 682 659 hdsp->state &= ~HDSP_FirmwareLoaded; 683 660 return -EIO; 684 661 } ··· 703 680 } 704 681 } 705 682 706 - snd_printk("Hammerfall-DSP: no Digiface or Multiface connected!\n"); 683 + snd_printk("Hammerfall-DSP: no IO box connected!\n"); 707 684 hdsp->state &= ~HDSP_FirmwareLoaded; 708 685 return -EIO; 709 686 } ··· 775 752 hdsp_write (hdsp, HDSP_control2Reg, HDSP_S_LOAD); 776 753 hdsp_write (hdsp, HDSP_fifoData, 0); 777 754 778 - if (hdsp_fifo_wait (hdsp, 0, HDSP_SHORT_WAIT)) { 779 - hdsp->io_type = Multiface; 780 - hdsp_write (hdsp, HDSP_control2Reg, HDSP_VERSION_BIT); 781 - hdsp_write (hdsp, HDSP_control2Reg, HDSP_S_LOAD); 782 - hdsp_fifo_wait (hdsp, 0, HDSP_SHORT_WAIT); 755 + if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT)) { 756 + hdsp_write(hdsp, HDSP_control2Reg, HDSP_VERSION_BIT); 757 + hdsp_write(hdsp, HDSP_control2Reg, HDSP_S_LOAD); 758 + if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT)) 759 + hdsp->io_type = RPM; 760 + else 761 + hdsp->io_type = Multiface; 783 762 } else { 784 763 hdsp->io_type = Digiface; 785 764 } 786 765 } else { 787 766 /* firmware was already loaded, get iobox type */ 788 - if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version1) 767 + if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version2) 768 + hdsp->io_type = RPM; 769 + else if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version1) 789 770 hdsp->io_type = Multiface; 790 771 else 791 772 hdsp->io_type = Digiface; ··· 1211 1184 hdsp->channel_map = channel_map_ds; 1212 1185 } else { 1213 1186 switch (hdsp->io_type) { 1187 + case RPM: 1214 1188 case Multiface: 1215 1189 hdsp->channel_map = channel_map_mf_ss; 1216 1190 break; ··· 3259 3231 HDSP_USE_MIDI_TASKLET("Use Midi Tasklet", 0), 3260 3232 }; 3261 3233 3234 + 3235 + static int hdsp_rpm_input12(struct hdsp *hdsp) 3236 + { 3237 + switch (hdsp->control_register & HDSP_RPM_Inp12) { 3238 + case HDSP_RPM_Inp12_Phon_6dB: 3239 + return 0; 3240 + case HDSP_RPM_Inp12_Phon_n6dB: 3241 + return 2; 3242 + case HDSP_RPM_Inp12_Line_0dB: 3243 + return 3; 3244 + case HDSP_RPM_Inp12_Line_n6dB: 3245 + return 4; 3246 + } 3247 + return 1; 3248 + } 3249 + 3250 + 3251 + static int snd_hdsp_get_rpm_input12(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 3252 + { 3253 + struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); 3254 + 3255 + ucontrol->value.enumerated.item[0] = hdsp_rpm_input12(hdsp); 3256 + return 0; 3257 + } 3258 + 3259 + 3260 + static int hdsp_set_rpm_input12(struct hdsp *hdsp, int mode) 3261 + { 3262 + hdsp->control_register &= ~HDSP_RPM_Inp12; 3263 + switch (mode) { 3264 + case 0: 3265 + hdsp->control_register |= HDSP_RPM_Inp12_Phon_6dB; 3266 + break; 3267 + case 1: 3268 + break; 3269 + case 2: 3270 + hdsp->control_register |= HDSP_RPM_Inp12_Phon_n6dB; 3271 + break; 3272 + case 3: 3273 + hdsp->control_register |= HDSP_RPM_Inp12_Line_0dB; 3274 + break; 3275 + case 4: 3276 + hdsp->control_register |= HDSP_RPM_Inp12_Line_n6dB; 3277 + break; 3278 + default: 3279 + return -1; 3280 + } 3281 + 3282 + hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register); 3283 + return 0; 3284 + } 3285 + 3286 + 3287 + static int snd_hdsp_put_rpm_input12(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 3288 + { 3289 + struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); 3290 + int change; 3291 + int val; 3292 + 3293 + if (!snd_hdsp_use_is_exclusive(hdsp)) 3294 + return -EBUSY; 3295 + val = ucontrol->value.enumerated.item[0]; 3296 + if (val < 0) 3297 + val = 0; 3298 + if (val > 4) 3299 + val = 4; 3300 + spin_lock_irq(&hdsp->lock); 3301 + if (val != hdsp_rpm_input12(hdsp)) 3302 + change = (hdsp_set_rpm_input12(hdsp, val) == 0) ? 1 : 0; 3303 + else 3304 + change = 0; 3305 + spin_unlock_irq(&hdsp->lock); 3306 + return change; 3307 + } 3308 + 3309 + 3310 + static int snd_hdsp_info_rpm_input(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 3311 + { 3312 + static char *texts[] = {"Phono +6dB", "Phono 0dB", "Phono -6dB", "Line 0dB", "Line -6dB"}; 3313 + 3314 + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 3315 + uinfo->count = 1; 3316 + uinfo->value.enumerated.items = 5; 3317 + if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) 3318 + uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; 3319 + strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); 3320 + return 0; 3321 + } 3322 + 3323 + 3324 + static int hdsp_rpm_input34(struct hdsp *hdsp) 3325 + { 3326 + switch (hdsp->control_register & HDSP_RPM_Inp34) { 3327 + case HDSP_RPM_Inp34_Phon_6dB: 3328 + return 0; 3329 + case HDSP_RPM_Inp34_Phon_n6dB: 3330 + return 2; 3331 + case HDSP_RPM_Inp34_Line_0dB: 3332 + return 3; 3333 + case HDSP_RPM_Inp34_Line_n6dB: 3334 + return 4; 3335 + } 3336 + return 1; 3337 + } 3338 + 3339 + 3340 + static int snd_hdsp_get_rpm_input34(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 3341 + { 3342 + struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); 3343 + 3344 + ucontrol->value.enumerated.item[0] = hdsp_rpm_input34(hdsp); 3345 + return 0; 3346 + } 3347 + 3348 + 3349 + static int hdsp_set_rpm_input34(struct hdsp *hdsp, int mode) 3350 + { 3351 + hdsp->control_register &= ~HDSP_RPM_Inp34; 3352 + switch (mode) { 3353 + case 0: 3354 + hdsp->control_register |= HDSP_RPM_Inp34_Phon_6dB; 3355 + break; 3356 + case 1: 3357 + break; 3358 + case 2: 3359 + hdsp->control_register |= HDSP_RPM_Inp34_Phon_n6dB; 3360 + break; 3361 + case 3: 3362 + hdsp->control_register |= HDSP_RPM_Inp34_Line_0dB; 3363 + break; 3364 + case 4: 3365 + hdsp->control_register |= HDSP_RPM_Inp34_Line_n6dB; 3366 + break; 3367 + default: 3368 + return -1; 3369 + } 3370 + 3371 + hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register); 3372 + return 0; 3373 + } 3374 + 3375 + 3376 + static int snd_hdsp_put_rpm_input34(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 3377 + { 3378 + struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); 3379 + int change; 3380 + int val; 3381 + 3382 + if (!snd_hdsp_use_is_exclusive(hdsp)) 3383 + return -EBUSY; 3384 + val = ucontrol->value.enumerated.item[0]; 3385 + if (val < 0) 3386 + val = 0; 3387 + if (val > 4) 3388 + val = 4; 3389 + spin_lock_irq(&hdsp->lock); 3390 + if (val != hdsp_rpm_input34(hdsp)) 3391 + change = (hdsp_set_rpm_input34(hdsp, val) == 0) ? 1 : 0; 3392 + else 3393 + change = 0; 3394 + spin_unlock_irq(&hdsp->lock); 3395 + return change; 3396 + } 3397 + 3398 + 3399 + /* RPM Bypass switch */ 3400 + static int hdsp_rpm_bypass(struct hdsp *hdsp) 3401 + { 3402 + return (hdsp->control_register & HDSP_RPM_Bypass) ? 1 : 0; 3403 + } 3404 + 3405 + 3406 + static int snd_hdsp_get_rpm_bypass(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 3407 + { 3408 + struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); 3409 + 3410 + ucontrol->value.integer.value[0] = hdsp_rpm_bypass(hdsp); 3411 + return 0; 3412 + } 3413 + 3414 + 3415 + static int hdsp_set_rpm_bypass(struct hdsp *hdsp, int on) 3416 + { 3417 + if (on) 3418 + hdsp->control_register |= HDSP_RPM_Bypass; 3419 + else 3420 + hdsp->control_register &= ~HDSP_RPM_Bypass; 3421 + hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register); 3422 + return 0; 3423 + } 3424 + 3425 + 3426 + static int snd_hdsp_put_rpm_bypass(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 3427 + { 3428 + struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); 3429 + int change; 3430 + unsigned int val; 3431 + 3432 + if (!snd_hdsp_use_is_exclusive(hdsp)) 3433 + return -EBUSY; 3434 + val = ucontrol->value.integer.value[0] & 1; 3435 + spin_lock_irq(&hdsp->lock); 3436 + change = (int)val != hdsp_rpm_bypass(hdsp); 3437 + hdsp_set_rpm_bypass(hdsp, val); 3438 + spin_unlock_irq(&hdsp->lock); 3439 + return change; 3440 + } 3441 + 3442 + 3443 + static int snd_hdsp_info_rpm_bypass(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 3444 + { 3445 + static char *texts[] = {"On", "Off"}; 3446 + 3447 + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 3448 + uinfo->count = 1; 3449 + uinfo->value.enumerated.items = 2; 3450 + if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) 3451 + uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; 3452 + strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); 3453 + return 0; 3454 + } 3455 + 3456 + 3457 + /* RPM Disconnect switch */ 3458 + static int hdsp_rpm_disconnect(struct hdsp *hdsp) 3459 + { 3460 + return (hdsp->control_register & HDSP_RPM_Disconnect) ? 1 : 0; 3461 + } 3462 + 3463 + 3464 + static int snd_hdsp_get_rpm_disconnect(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 3465 + { 3466 + struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); 3467 + 3468 + ucontrol->value.integer.value[0] = hdsp_rpm_disconnect(hdsp); 3469 + return 0; 3470 + } 3471 + 3472 + 3473 + static int hdsp_set_rpm_disconnect(struct hdsp *hdsp, int on) 3474 + { 3475 + if (on) 3476 + hdsp->control_register |= HDSP_RPM_Disconnect; 3477 + else 3478 + hdsp->control_register &= ~HDSP_RPM_Disconnect; 3479 + hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register); 3480 + return 0; 3481 + } 3482 + 3483 + 3484 + static int snd_hdsp_put_rpm_disconnect(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 3485 + { 3486 + struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); 3487 + int change; 3488 + unsigned int val; 3489 + 3490 + if (!snd_hdsp_use_is_exclusive(hdsp)) 3491 + return -EBUSY; 3492 + val = ucontrol->value.integer.value[0] & 1; 3493 + spin_lock_irq(&hdsp->lock); 3494 + change = (int)val != hdsp_rpm_disconnect(hdsp); 3495 + hdsp_set_rpm_disconnect(hdsp, val); 3496 + spin_unlock_irq(&hdsp->lock); 3497 + return change; 3498 + } 3499 + 3500 + static int snd_hdsp_info_rpm_disconnect(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 3501 + { 3502 + static char *texts[] = {"On", "Off"}; 3503 + 3504 + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 3505 + uinfo->count = 1; 3506 + uinfo->value.enumerated.items = 2; 3507 + if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) 3508 + uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; 3509 + strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); 3510 + return 0; 3511 + } 3512 + 3513 + static struct snd_kcontrol_new snd_hdsp_rpm_controls[] = { 3514 + { 3515 + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3516 + .name = "RPM Bypass", 3517 + .get = snd_hdsp_get_rpm_bypass, 3518 + .put = snd_hdsp_put_rpm_bypass, 3519 + .info = snd_hdsp_info_rpm_bypass 3520 + }, 3521 + { 3522 + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3523 + .name = "RPM Disconnect", 3524 + .get = snd_hdsp_get_rpm_disconnect, 3525 + .put = snd_hdsp_put_rpm_disconnect, 3526 + .info = snd_hdsp_info_rpm_disconnect 3527 + }, 3528 + { 3529 + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3530 + .name = "Input 1/2", 3531 + .get = snd_hdsp_get_rpm_input12, 3532 + .put = snd_hdsp_put_rpm_input12, 3533 + .info = snd_hdsp_info_rpm_input 3534 + }, 3535 + { 3536 + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3537 + .name = "Input 3/4", 3538 + .get = snd_hdsp_get_rpm_input34, 3539 + .put = snd_hdsp_put_rpm_input34, 3540 + .info = snd_hdsp_info_rpm_input 3541 + }, 3542 + HDSP_SYSTEM_SAMPLE_RATE("System Sample Rate", 0), 3543 + HDSP_MIXER("Mixer", 0) 3544 + }; 3545 + 3262 3546 static struct snd_kcontrol_new snd_hdsp_96xx_aeb = HDSP_AEB("Analog Extension Board", 0); 3263 3547 static struct snd_kcontrol_new snd_hdsp_adat_sync_check = HDSP_ADAT_SYNC_CHECK; 3264 3548 ··· 3579 3239 unsigned int idx; 3580 3240 int err; 3581 3241 struct snd_kcontrol *kctl; 3242 + 3243 + if (hdsp->io_type == RPM) { 3244 + /* RPM Bypass, Disconnect and Input switches */ 3245 + for (idx = 0; idx < ARRAY_SIZE(snd_hdsp_rpm_controls); idx++) { 3246 + err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_hdsp_rpm_controls[idx], hdsp)); 3247 + if (err < 0) 3248 + return err; 3249 + } 3250 + return 0; 3251 + } 3582 3252 3583 3253 for (idx = 0; idx < ARRAY_SIZE(snd_hdsp_controls); idx++) { 3584 3254 if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_hdsp_controls[idx], hdsp))) < 0) ··· 3809 3459 3810 3460 snd_iprintf(buffer, "\n"); 3811 3461 3812 - switch (hdsp_spdif_in(hdsp)) { 3813 - case HDSP_SPDIFIN_OPTICAL: 3814 - snd_iprintf(buffer, "IEC958 input: Optical\n"); 3815 - break; 3816 - case HDSP_SPDIFIN_COAXIAL: 3817 - snd_iprintf(buffer, "IEC958 input: Coaxial\n"); 3818 - break; 3819 - case HDSP_SPDIFIN_INTERNAL: 3820 - snd_iprintf(buffer, "IEC958 input: Internal\n"); 3821 - break; 3822 - case HDSP_SPDIFIN_AES: 3823 - snd_iprintf(buffer, "IEC958 input: AES\n"); 3824 - break; 3825 - default: 3826 - snd_iprintf(buffer, "IEC958 input: ???\n"); 3827 - break; 3462 + if (hdsp->io_type != RPM) { 3463 + switch (hdsp_spdif_in(hdsp)) { 3464 + case HDSP_SPDIFIN_OPTICAL: 3465 + snd_iprintf(buffer, "IEC958 input: Optical\n"); 3466 + break; 3467 + case HDSP_SPDIFIN_COAXIAL: 3468 + snd_iprintf(buffer, "IEC958 input: Coaxial\n"); 3469 + break; 3470 + case HDSP_SPDIFIN_INTERNAL: 3471 + snd_iprintf(buffer, "IEC958 input: Internal\n"); 3472 + break; 3473 + case HDSP_SPDIFIN_AES: 3474 + snd_iprintf(buffer, "IEC958 input: AES\n"); 3475 + break; 3476 + default: 3477 + snd_iprintf(buffer, "IEC958 input: ???\n"); 3478 + break; 3479 + } 3828 3480 } 3829 3481 3830 - if (hdsp->control_register & HDSP_SPDIFOpticalOut) 3831 - snd_iprintf(buffer, "IEC958 output: Coaxial & ADAT1\n"); 3832 - else 3833 - snd_iprintf(buffer, "IEC958 output: Coaxial only\n"); 3482 + if (RPM == hdsp->io_type) { 3483 + if (hdsp->control_register & HDSP_RPM_Bypass) 3484 + snd_iprintf(buffer, "RPM Bypass: disabled\n"); 3485 + else 3486 + snd_iprintf(buffer, "RPM Bypass: enabled\n"); 3487 + if (hdsp->control_register & HDSP_RPM_Disconnect) 3488 + snd_iprintf(buffer, "RPM disconnected\n"); 3489 + else 3490 + snd_iprintf(buffer, "RPM connected\n"); 3834 3491 3835 - if (hdsp->control_register & HDSP_SPDIFProfessional) 3836 - snd_iprintf(buffer, "IEC958 quality: Professional\n"); 3837 - else 3838 - snd_iprintf(buffer, "IEC958 quality: Consumer\n"); 3492 + switch (hdsp->control_register & HDSP_RPM_Inp12) { 3493 + case HDSP_RPM_Inp12_Phon_6dB: 3494 + snd_iprintf(buffer, "Input 1/2: Phono, 6dB\n"); 3495 + break; 3496 + case HDSP_RPM_Inp12_Phon_0dB: 3497 + snd_iprintf(buffer, "Input 1/2: Phono, 0dB\n"); 3498 + break; 3499 + case HDSP_RPM_Inp12_Phon_n6dB: 3500 + snd_iprintf(buffer, "Input 1/2: Phono, -6dB\n"); 3501 + break; 3502 + case HDSP_RPM_Inp12_Line_0dB: 3503 + snd_iprintf(buffer, "Input 1/2: Line, 0dB\n"); 3504 + break; 3505 + case HDSP_RPM_Inp12_Line_n6dB: 3506 + snd_iprintf(buffer, "Input 1/2: Line, -6dB\n"); 3507 + break; 3508 + default: 3509 + snd_iprintf(buffer, "Input 1/2: ???\n"); 3510 + } 3839 3511 3840 - if (hdsp->control_register & HDSP_SPDIFEmphasis) 3841 - snd_iprintf(buffer, "IEC958 emphasis: on\n"); 3842 - else 3843 - snd_iprintf(buffer, "IEC958 emphasis: off\n"); 3512 + switch (hdsp->control_register & HDSP_RPM_Inp34) { 3513 + case HDSP_RPM_Inp34_Phon_6dB: 3514 + snd_iprintf(buffer, "Input 3/4: Phono, 6dB\n"); 3515 + break; 3516 + case HDSP_RPM_Inp34_Phon_0dB: 3517 + snd_iprintf(buffer, "Input 3/4: Phono, 0dB\n"); 3518 + break; 3519 + case HDSP_RPM_Inp34_Phon_n6dB: 3520 + snd_iprintf(buffer, "Input 3/4: Phono, -6dB\n"); 3521 + break; 3522 + case HDSP_RPM_Inp34_Line_0dB: 3523 + snd_iprintf(buffer, "Input 3/4: Line, 0dB\n"); 3524 + break; 3525 + case HDSP_RPM_Inp34_Line_n6dB: 3526 + snd_iprintf(buffer, "Input 3/4: Line, -6dB\n"); 3527 + break; 3528 + default: 3529 + snd_iprintf(buffer, "Input 3/4: ???\n"); 3530 + } 3844 3531 3845 - if (hdsp->control_register & HDSP_SPDIFNonAudio) 3846 - snd_iprintf(buffer, "IEC958 NonAudio: on\n"); 3847 - else 3848 - snd_iprintf(buffer, "IEC958 NonAudio: off\n"); 3849 - if ((x = hdsp_spdif_sample_rate (hdsp)) != 0) 3850 - snd_iprintf (buffer, "IEC958 sample rate: %d\n", x); 3851 - else 3852 - snd_iprintf (buffer, "IEC958 sample rate: Error flag set\n"); 3532 + } else { 3533 + if (hdsp->control_register & HDSP_SPDIFOpticalOut) 3534 + snd_iprintf(buffer, "IEC958 output: Coaxial & ADAT1\n"); 3535 + else 3536 + snd_iprintf(buffer, "IEC958 output: Coaxial only\n"); 3853 3537 3538 + if (hdsp->control_register & HDSP_SPDIFProfessional) 3539 + snd_iprintf(buffer, "IEC958 quality: Professional\n"); 3540 + else 3541 + snd_iprintf(buffer, "IEC958 quality: Consumer\n"); 3542 + 3543 + if (hdsp->control_register & HDSP_SPDIFEmphasis) 3544 + snd_iprintf(buffer, "IEC958 emphasis: on\n"); 3545 + else 3546 + snd_iprintf(buffer, "IEC958 emphasis: off\n"); 3547 + 3548 + if (hdsp->control_register & HDSP_SPDIFNonAudio) 3549 + snd_iprintf(buffer, "IEC958 NonAudio: on\n"); 3550 + else 3551 + snd_iprintf(buffer, "IEC958 NonAudio: off\n"); 3552 + x = hdsp_spdif_sample_rate(hdsp); 3553 + if (x != 0) 3554 + snd_iprintf(buffer, "IEC958 sample rate: %d\n", x); 3555 + else 3556 + snd_iprintf(buffer, "IEC958 sample rate: Error flag set\n"); 3557 + } 3854 3558 snd_iprintf(buffer, "\n"); 3855 3559 3856 3560 /* Sync Check */ ··· 4169 3765 snd_hdsp_midi_input_read (&hdsp->midi[0]); 4170 3766 } 4171 3767 } 4172 - if (hdsp->io_type != Multiface && hdsp->io_type != H9632 && midi1 && midi1status) { 3768 + if (hdsp->io_type != Multiface && hdsp->io_type != RPM && hdsp->io_type != H9632 && midi1 && midi1status) { 4173 3769 if (hdsp->use_midi_tasklet) { 4174 3770 /* we disable interrupts for this input until processing is done */ 4175 3771 hdsp->control_register &= ~HDSP_Midi1InterruptEnable; ··· 4497 4093 SNDRV_PCM_RATE_96000), 4498 4094 .rate_min = 32000, 4499 4095 .rate_max = 96000, 4500 - .channels_min = 14, 4096 + .channels_min = 6, 4501 4097 .channels_max = HDSP_MAX_CHANNELS, 4502 4098 .buffer_bytes_max = HDSP_CHANNEL_BUFFER_BYTES * HDSP_MAX_CHANNELS, 4503 4099 .period_bytes_min = (64 * 4) * 10, ··· 4526 4122 SNDRV_PCM_RATE_96000), 4527 4123 .rate_min = 32000, 4528 4124 .rate_max = 96000, 4529 - .channels_min = 14, 4125 + .channels_min = 5, 4530 4126 .channels_max = HDSP_MAX_CHANNELS, 4531 4127 .buffer_bytes_max = HDSP_CHANNEL_BUFFER_BYTES * HDSP_MAX_CHANNELS, 4532 4128 .period_bytes_min = (64 * 4) * 10, ··· 4761 4357 snd_hdsp_hw_rule_rate_out_channels, hdsp, 4762 4358 SNDRV_PCM_HW_PARAM_CHANNELS, -1); 4763 4359 4764 - hdsp->creg_spdif_stream = hdsp->creg_spdif; 4765 - hdsp->spdif_ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE; 4766 - snd_ctl_notify(hdsp->card, SNDRV_CTL_EVENT_MASK_VALUE | 4767 - SNDRV_CTL_EVENT_MASK_INFO, &hdsp->spdif_ctl->id); 4360 + if (RPM != hdsp->io_type) { 4361 + hdsp->creg_spdif_stream = hdsp->creg_spdif; 4362 + hdsp->spdif_ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE; 4363 + snd_ctl_notify(hdsp->card, SNDRV_CTL_EVENT_MASK_VALUE | 4364 + SNDRV_CTL_EVENT_MASK_INFO, &hdsp->spdif_ctl->id); 4365 + } 4768 4366 return 0; 4769 4367 } 4770 4368 ··· 4781 4375 4782 4376 spin_unlock_irq(&hdsp->lock); 4783 4377 4784 - hdsp->spdif_ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE; 4785 - snd_ctl_notify(hdsp->card, SNDRV_CTL_EVENT_MASK_VALUE | 4786 - SNDRV_CTL_EVENT_MASK_INFO, &hdsp->spdif_ctl->id); 4378 + if (RPM != hdsp->io_type) { 4379 + hdsp->spdif_ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE; 4380 + snd_ctl_notify(hdsp->card, SNDRV_CTL_EVENT_MASK_VALUE | 4381 + SNDRV_CTL_EVENT_MASK_INFO, &hdsp->spdif_ctl->id); 4382 + } 4787 4383 return 0; 4788 4384 } 4789 4385 ··· 5024 4616 if (hdsp->io_type != H9632) 5025 4617 info.adatsync_sync_check = (unsigned char)hdsp_adatsync_sync_check(hdsp); 5026 4618 info.spdif_sync_check = (unsigned char)hdsp_spdif_sync_check(hdsp); 5027 - for (i = 0; i < ((hdsp->io_type != Multiface && hdsp->io_type != H9632) ? 3 : 1); ++i) 4619 + for (i = 0; i < ((hdsp->io_type != Multiface && hdsp->io_type != RPM && hdsp->io_type != H9632) ? 3 : 1); ++i) 5028 4620 info.adat_sync_check[i] = (unsigned char)hdsp_adat_sync_check(hdsp, i); 5029 4621 info.spdif_in = (unsigned char)hdsp_spdif_in(hdsp); 5030 4622 info.spdif_out = (unsigned char)hdsp_spdif_out(hdsp); ··· 5044 4636 info.phone_gain = (unsigned char)hdsp_phone_gain(hdsp); 5045 4637 info.xlr_breakout_cable = (unsigned char)hdsp_xlr_breakout_cable(hdsp); 5046 4638 4639 + } else if (hdsp->io_type == RPM) { 4640 + info.da_gain = (unsigned char) hdsp_rpm_input12(hdsp); 4641 + info.ad_gain = (unsigned char) hdsp_rpm_input34(hdsp); 5047 4642 } 5048 4643 if (hdsp->io_type == H9632 || hdsp->io_type == H9652) 5049 4644 info.analog_extension_board = (unsigned char)hdsp_aeb(hdsp); ··· 5255 4844 hdsp->ds_in_channels = hdsp->ds_out_channels = MULTIFACE_DS_CHANNELS; 5256 4845 break; 5257 4846 4847 + case RPM: 4848 + hdsp->card_name = "RME Hammerfall DSP + RPM"; 4849 + hdsp->ss_in_channels = RPM_CHANNELS-1; 4850 + hdsp->ss_out_channels = RPM_CHANNELS; 4851 + hdsp->ds_in_channels = RPM_CHANNELS-1; 4852 + hdsp->ds_out_channels = RPM_CHANNELS; 4853 + break; 4854 + 5258 4855 default: 5259 4856 /* should never get here */ 5260 4857 break; ··· 5349 4930 5350 4931 /* caution: max length of firmware filename is 30! */ 5351 4932 switch (hdsp->io_type) { 4933 + case RPM: 4934 + fwfile = "rpm_firmware.bin"; 4935 + break; 5352 4936 case Multiface: 5353 4937 if (hdsp->firmware_rev == 0xa) 5354 4938 fwfile = "multiface_firmware.bin"; ··· 5522 5100 return 0; 5523 5101 } else { 5524 5102 snd_printk(KERN_INFO "Hammerfall-DSP: Firmware already present, initializing card.\n"); 5525 - if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version1) 5103 + if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version2) 5104 + hdsp->io_type = RPM; 5105 + else if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version1) 5526 5106 hdsp->io_type = Multiface; 5527 5107 else 5528 5108 hdsp->io_type = Digiface;