diff options
Diffstat (limited to 'sound/pci/rme9652')
-rw-r--r-- | sound/pci/rme9652/hdsp.c | 99 | ||||
-rw-r--r-- | sound/pci/rme9652/hdspm.c | 185 | ||||
-rw-r--r-- | sound/pci/rme9652/rme9652.c | 8 |
3 files changed, 206 insertions, 86 deletions
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c index 89b3c7ff5037..3b3ef657f73e 100644 --- a/sound/pci/rme9652/hdsp.c +++ b/sound/pci/rme9652/hdsp.c | |||
@@ -60,6 +60,12 @@ MODULE_LICENSE("GPL"); | |||
60 | MODULE_SUPPORTED_DEVICE("{{RME Hammerfall-DSP}," | 60 | MODULE_SUPPORTED_DEVICE("{{RME Hammerfall-DSP}," |
61 | "{RME HDSP-9652}," | 61 | "{RME HDSP-9652}," |
62 | "{RME HDSP-9632}}"); | 62 | "{RME HDSP-9632}}"); |
63 | #ifdef HDSP_FW_LOADER | ||
64 | MODULE_FIRMWARE("multiface_firmware.bin"); | ||
65 | MODULE_FIRMWARE("multiface_firmware_rev11.bin"); | ||
66 | MODULE_FIRMWARE("digiface_firmware.bin"); | ||
67 | MODULE_FIRMWARE("digiface_firmware_rev11.bin"); | ||
68 | #endif | ||
63 | 69 | ||
64 | #define HDSP_MAX_CHANNELS 26 | 70 | #define HDSP_MAX_CHANNELS 26 |
65 | #define HDSP_MAX_DS_CHANNELS 14 | 71 | #define HDSP_MAX_DS_CHANNELS 14 |
@@ -275,6 +281,11 @@ MODULE_SUPPORTED_DEVICE("{{RME Hammerfall-DSP}," | |||
275 | #define HDSP_Frequency128KHz (HDSP_QuadSpeed|HDSP_DoubleSpeed|HDSP_Frequency0) | 281 | #define HDSP_Frequency128KHz (HDSP_QuadSpeed|HDSP_DoubleSpeed|HDSP_Frequency0) |
276 | #define HDSP_Frequency176_4KHz (HDSP_QuadSpeed|HDSP_DoubleSpeed|HDSP_Frequency1) | 282 | #define HDSP_Frequency176_4KHz (HDSP_QuadSpeed|HDSP_DoubleSpeed|HDSP_Frequency1) |
277 | #define HDSP_Frequency192KHz (HDSP_QuadSpeed|HDSP_DoubleSpeed|HDSP_Frequency1|HDSP_Frequency0) | 283 | #define HDSP_Frequency192KHz (HDSP_QuadSpeed|HDSP_DoubleSpeed|HDSP_Frequency1|HDSP_Frequency0) |
284 | /* RME says n = 104857600000000, but in the windows MADI driver, I see: | ||
285 | return 104857600000000 / rate; // 100 MHz | ||
286 | return 110100480000000 / rate; // 105 MHz | ||
287 | */ | ||
288 | #define DDS_NUMERATOR 104857600000000ULL; /* = 2^20 * 10^8 */ | ||
278 | 289 | ||
279 | #define hdsp_encode_latency(x) (((x)<<1) & HDSP_LatencyMask) | 290 | #define hdsp_encode_latency(x) (((x)<<1) & HDSP_LatencyMask) |
280 | #define hdsp_decode_latency(x) (((x) & HDSP_LatencyMask)>>1) | 291 | #define hdsp_decode_latency(x) (((x) & HDSP_LatencyMask)>>1) |
@@ -1001,11 +1012,7 @@ static void hdsp_set_dds_value(struct hdsp *hdsp, int rate) | |||
1001 | else if (rate >= 56000) | 1012 | else if (rate >= 56000) |
1002 | rate /= 2; | 1013 | rate /= 2; |
1003 | 1014 | ||
1004 | /* RME says n = 104857600000000, but in the windows MADI driver, I see: | 1015 | n = DDS_NUMERATOR; |
1005 | // return 104857600000000 / rate; // 100 MHz | ||
1006 | return 110100480000000 / rate; // 105 MHz | ||
1007 | */ | ||
1008 | n = 104857600000000ULL; /* = 2^20 * 10^8 */ | ||
1009 | div64_32(&n, rate, &r); | 1016 | div64_32(&n, rate, &r); |
1010 | /* n should be less than 2^32 for being written to FREQ register */ | 1017 | /* n should be less than 2^32 for being written to FREQ register */ |
1011 | snd_assert((n >> 32) == 0); | 1018 | snd_assert((n >> 32) == 0); |
@@ -3085,11 +3092,83 @@ static int snd_hdsp_get_adat_sync_check(struct snd_kcontrol *kcontrol, struct sn | |||
3085 | return 0; | 3092 | return 0; |
3086 | } | 3093 | } |
3087 | 3094 | ||
3095 | #define HDSP_DDS_OFFSET(xname, xindex) \ | ||
3096 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | ||
3097 | .name = xname, \ | ||
3098 | .index = xindex, \ | ||
3099 | .info = snd_hdsp_info_dds_offset, \ | ||
3100 | .get = snd_hdsp_get_dds_offset, \ | ||
3101 | .put = snd_hdsp_put_dds_offset \ | ||
3102 | } | ||
3103 | |||
3104 | static int hdsp_dds_offset(struct hdsp *hdsp) | ||
3105 | { | ||
3106 | u64 n; | ||
3107 | u32 r; | ||
3108 | unsigned int dds_value = hdsp->dds_value; | ||
3109 | int system_sample_rate = hdsp->system_sample_rate; | ||
3110 | |||
3111 | n = DDS_NUMERATOR; | ||
3112 | /* | ||
3113 | * dds_value = n / rate | ||
3114 | * rate = n / dds_value | ||
3115 | */ | ||
3116 | div64_32(&n, dds_value, &r); | ||
3117 | if (system_sample_rate >= 112000) | ||
3118 | n *= 4; | ||
3119 | else if (system_sample_rate >= 56000) | ||
3120 | n *= 2; | ||
3121 | return ((int)n) - system_sample_rate; | ||
3122 | } | ||
3123 | |||
3124 | static int hdsp_set_dds_offset(struct hdsp *hdsp, int offset_hz) | ||
3125 | { | ||
3126 | int rate = hdsp->system_sample_rate + offset_hz; | ||
3127 | hdsp_set_dds_value(hdsp, rate); | ||
3128 | return 0; | ||
3129 | } | ||
3130 | |||
3131 | static int snd_hdsp_info_dds_offset(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | ||
3132 | { | ||
3133 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
3134 | uinfo->count = 1; | ||
3135 | uinfo->value.integer.min = -5000; | ||
3136 | uinfo->value.integer.max = 5000; | ||
3137 | return 0; | ||
3138 | } | ||
3139 | |||
3140 | static int snd_hdsp_get_dds_offset(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | ||
3141 | { | ||
3142 | struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); | ||
3143 | |||
3144 | ucontrol->value.enumerated.item[0] = hdsp_dds_offset(hdsp); | ||
3145 | return 0; | ||
3146 | } | ||
3147 | |||
3148 | static int snd_hdsp_put_dds_offset(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | ||
3149 | { | ||
3150 | struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); | ||
3151 | int change; | ||
3152 | int val; | ||
3153 | |||
3154 | if (!snd_hdsp_use_is_exclusive(hdsp)) | ||
3155 | return -EBUSY; | ||
3156 | val = ucontrol->value.enumerated.item[0]; | ||
3157 | spin_lock_irq(&hdsp->lock); | ||
3158 | if (val != hdsp_dds_offset(hdsp)) | ||
3159 | change = (hdsp_set_dds_offset(hdsp, val) == 0) ? 1 : 0; | ||
3160 | else | ||
3161 | change = 0; | ||
3162 | spin_unlock_irq(&hdsp->lock); | ||
3163 | return change; | ||
3164 | } | ||
3165 | |||
3088 | static struct snd_kcontrol_new snd_hdsp_9632_controls[] = { | 3166 | static struct snd_kcontrol_new snd_hdsp_9632_controls[] = { |
3089 | HDSP_DA_GAIN("DA Gain", 0), | 3167 | HDSP_DA_GAIN("DA Gain", 0), |
3090 | HDSP_AD_GAIN("AD Gain", 0), | 3168 | HDSP_AD_GAIN("AD Gain", 0), |
3091 | HDSP_PHONE_GAIN("Phones Gain", 0), | 3169 | HDSP_PHONE_GAIN("Phones Gain", 0), |
3092 | HDSP_XLR_BREAKOUT_CABLE("XLR Breakout Cable", 0) | 3170 | HDSP_XLR_BREAKOUT_CABLE("XLR Breakout Cable", 0), |
3171 | HDSP_DDS_OFFSET("DDS Sample Rate Offset", 0) | ||
3093 | }; | 3172 | }; |
3094 | 3173 | ||
3095 | static struct snd_kcontrol_new snd_hdsp_controls[] = { | 3174 | static struct snd_kcontrol_new snd_hdsp_controls[] = { |
@@ -3780,11 +3859,9 @@ static int snd_hdsp_reset(struct snd_pcm_substream *substream) | |||
3780 | else | 3859 | else |
3781 | runtime->status->hw_ptr = 0; | 3860 | runtime->status->hw_ptr = 0; |
3782 | if (other) { | 3861 | if (other) { |
3783 | struct list_head *pos; | ||
3784 | struct snd_pcm_substream *s; | 3862 | struct snd_pcm_substream *s; |
3785 | struct snd_pcm_runtime *oruntime = other->runtime; | 3863 | struct snd_pcm_runtime *oruntime = other->runtime; |
3786 | snd_pcm_group_for_each(pos, substream) { | 3864 | snd_pcm_group_for_each_entry(s, substream) { |
3787 | s = snd_pcm_group_substream_entry(pos); | ||
3788 | if (s == other) { | 3865 | if (s == other) { |
3789 | oruntime->status->hw_ptr = runtime->status->hw_ptr; | 3866 | oruntime->status->hw_ptr = runtime->status->hw_ptr; |
3790 | break; | 3867 | break; |
@@ -3933,10 +4010,8 @@ static int snd_hdsp_trigger(struct snd_pcm_substream *substream, int cmd) | |||
3933 | other = hdsp->playback_substream; | 4010 | other = hdsp->playback_substream; |
3934 | 4011 | ||
3935 | if (other) { | 4012 | if (other) { |
3936 | struct list_head *pos; | ||
3937 | struct snd_pcm_substream *s; | 4013 | struct snd_pcm_substream *s; |
3938 | snd_pcm_group_for_each(pos, substream) { | 4014 | snd_pcm_group_for_each_entry(s, substream) { |
3939 | s = snd_pcm_group_substream_entry(pos); | ||
3940 | if (s == other) { | 4015 | if (s == other) { |
3941 | snd_pcm_trigger_done(s, substream); | 4016 | snd_pcm_trigger_done(s, substream); |
3942 | if (cmd == SNDRV_PCM_TRIGGER_START) | 4017 | if (cmd == SNDRV_PCM_TRIGGER_START) |
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c index 6e95857e4e67..143185e7e4dc 100644 --- a/sound/pci/rme9652/hdspm.c +++ b/sound/pci/rme9652/hdspm.c | |||
@@ -91,8 +91,10 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}"); | |||
91 | #define HDSPM_controlRegister 64 | 91 | #define HDSPM_controlRegister 64 |
92 | #define HDSPM_interruptConfirmation 96 | 92 | #define HDSPM_interruptConfirmation 96 |
93 | #define HDSPM_control2Reg 256 /* not in specs ???????? */ | 93 | #define HDSPM_control2Reg 256 /* not in specs ???????? */ |
94 | #define HDSPM_freqReg 256 /* for AES32 */ | ||
94 | #define HDSPM_midiDataOut0 352 /* just believe in old code */ | 95 | #define HDSPM_midiDataOut0 352 /* just believe in old code */ |
95 | #define HDSPM_midiDataOut1 356 | 96 | #define HDSPM_midiDataOut1 356 |
97 | #define HDSPM_eeprom_wr 384 /* for AES32 */ | ||
96 | 98 | ||
97 | /* DMA enable for 64 channels, only Bit 0 is relevant */ | 99 | /* DMA enable for 64 channels, only Bit 0 is relevant */ |
98 | #define HDSPM_outputEnableBase 512 /* 512-767 input DMA */ | 100 | #define HDSPM_outputEnableBase 512 /* 512-767 input DMA */ |
@@ -389,9 +391,8 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}"); | |||
389 | size is the same regardless of the number of channels, and | 391 | size is the same regardless of the number of channels, and |
390 | also the latency to use. | 392 | also the latency to use. |
391 | for one direction !!! | 393 | for one direction !!! |
392 | => need to mupltiply by 2!! | ||
393 | */ | 394 | */ |
394 | #define HDSPM_DMA_AREA_BYTES (2 * HDSPM_MAX_CHANNELS * HDSPM_CHANNEL_BUFFER_BYTES) | 395 | #define HDSPM_DMA_AREA_BYTES (HDSPM_MAX_CHANNELS * HDSPM_CHANNEL_BUFFER_BYTES) |
395 | #define HDSPM_DMA_AREA_KILOBYTES (HDSPM_DMA_AREA_BYTES/1024) | 396 | #define HDSPM_DMA_AREA_KILOBYTES (HDSPM_DMA_AREA_BYTES/1024) |
396 | 397 | ||
397 | /* revisions >= 230 indicate AES32 card */ | 398 | /* revisions >= 230 indicate AES32 card */ |
@@ -484,28 +485,6 @@ static char channel_map_madi_ss[HDSPM_MAX_CHANNELS] = { | |||
484 | 56, 57, 58, 59, 60, 61, 62, 63 | 485 | 56, 57, 58, 59, 60, 61, 62, 63 |
485 | }; | 486 | }; |
486 | 487 | ||
487 | static char channel_map_madi_ds[HDSPM_MAX_CHANNELS] = { | ||
488 | 0, 2, 4, 6, 8, 10, 12, 14, | ||
489 | 16, 18, 20, 22, 24, 26, 28, 30, | ||
490 | 32, 34, 36, 38, 40, 42, 44, 46, | ||
491 | 48, 50, 52, 54, 56, 58, 60, 62, | ||
492 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
493 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
494 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
495 | -1, -1, -1, -1, -1, -1, -1, -1 | ||
496 | }; | ||
497 | |||
498 | static char channel_map_madi_qs[HDSPM_MAX_CHANNELS] = { | ||
499 | 0, 4, 8, 12, 16, 20, 24, 28, | ||
500 | 32, 36, 40, 44, 48, 52, 56, 60 | ||
501 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
502 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
503 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
504 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
505 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
506 | -1, -1, -1, -1, -1, -1, -1, -1 | ||
507 | }; | ||
508 | |||
509 | 488 | ||
510 | static struct pci_device_id snd_hdspm_ids[] __devinitdata = { | 489 | static struct pci_device_id snd_hdspm_ids[] __devinitdata = { |
511 | { | 490 | { |
@@ -818,6 +797,27 @@ static int hdspm_set_interrupt_interval(struct hdspm * s, unsigned int frames) | |||
818 | return 0; | 797 | return 0; |
819 | } | 798 | } |
820 | 799 | ||
800 | static void hdspm_set_dds_value(struct hdspm *hdspm, int rate) | ||
801 | { | ||
802 | u64 n; | ||
803 | u32 r; | ||
804 | |||
805 | if (rate >= 112000) | ||
806 | rate /= 4; | ||
807 | else if (rate >= 56000) | ||
808 | rate /= 2; | ||
809 | |||
810 | /* RME says n = 104857600000000, but in the windows MADI driver, I see: | ||
811 | // return 104857600000000 / rate; // 100 MHz | ||
812 | return 110100480000000 / rate; // 105 MHz | ||
813 | */ | ||
814 | //n = 104857600000000ULL; /* = 2^20 * 10^8 */ | ||
815 | n = 110100480000000ULL; /* Value checked for AES32 and MADI */ | ||
816 | div64_32(&n, rate, &r); | ||
817 | /* n should be less than 2^32 for being written to FREQ register */ | ||
818 | snd_assert((n >> 32) == 0); | ||
819 | hdspm_write(hdspm, HDSPM_freqReg, (u32)n); | ||
820 | } | ||
821 | 821 | ||
822 | /* dummy set rate lets see what happens */ | 822 | /* dummy set rate lets see what happens */ |
823 | static int hdspm_set_rate(struct hdspm * hdspm, int rate, int called_internally) | 823 | static int hdspm_set_rate(struct hdspm * hdspm, int rate, int called_internally) |
@@ -943,12 +943,16 @@ static int hdspm_set_rate(struct hdspm * hdspm, int rate, int called_internally) | |||
943 | hdspm->control_register |= rate_bits; | 943 | hdspm->control_register |= rate_bits; |
944 | hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register); | 944 | hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register); |
945 | 945 | ||
946 | if (rate > 96000 /* 64000*/) | 946 | /* For AES32, need to set DDS value in FREQ register |
947 | hdspm->channel_map = channel_map_madi_qs; | 947 | For MADI, also apparently */ |
948 | else if (rate > 48000) | 948 | hdspm_set_dds_value(hdspm, rate); |
949 | hdspm->channel_map = channel_map_madi_ds; | 949 | |
950 | else | 950 | if (hdspm->is_aes32 && rate != current_rate) |
951 | hdspm->channel_map = channel_map_madi_ss; | 951 | hdspm_write(hdspm, HDSPM_eeprom_wr, 0); |
952 | |||
953 | /* For AES32 and for MADI (at least rev 204), channel_map needs to | ||
954 | * always be channel_map_madi_ss, whatever the sample rate */ | ||
955 | hdspm->channel_map = channel_map_madi_ss; | ||
952 | 956 | ||
953 | hdspm->system_sample_rate = rate; | 957 | hdspm->system_sample_rate = rate; |
954 | 958 | ||
@@ -3184,8 +3188,8 @@ snd_hdspm_proc_read_aes32(struct snd_info_entry * entry, | |||
3184 | hdspm_read(hdspm, HDSPM_midiStatusIn0) & 0xFF, | 3188 | hdspm_read(hdspm, HDSPM_midiStatusIn0) & 0xFF, |
3185 | hdspm_read(hdspm, HDSPM_midiStatusIn1) & 0xFF); | 3189 | hdspm_read(hdspm, HDSPM_midiStatusIn1) & 0xFF); |
3186 | snd_iprintf(buffer, | 3190 | snd_iprintf(buffer, |
3187 | "Register: ctrl1=0x%x, ctrl2=0x%x, status1=0x%x, status2=0x%x, timecode=0x%x\n", | 3191 | "Register: ctrl1=0x%x, status1=0x%x, status2=0x%x, timecode=0x%x\n", |
3188 | hdspm->control_register, hdspm->control2_register, | 3192 | hdspm->control_register, |
3189 | status, status2, timecode); | 3193 | status, status2, timecode); |
3190 | 3194 | ||
3191 | snd_iprintf(buffer, "--- Settings ---\n"); | 3195 | snd_iprintf(buffer, "--- Settings ---\n"); |
@@ -3377,13 +3381,16 @@ static int snd_hdspm_set_defaults(struct hdspm * hdspm) | |||
3377 | 3381 | ||
3378 | hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register); | 3382 | hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register); |
3379 | 3383 | ||
3384 | if (!hdspm->is_aes32) { | ||
3385 | /* No control2 register for AES32 */ | ||
3380 | #ifdef SNDRV_BIG_ENDIAN | 3386 | #ifdef SNDRV_BIG_ENDIAN |
3381 | hdspm->control2_register = HDSPM_BIGENDIAN_MODE; | 3387 | hdspm->control2_register = HDSPM_BIGENDIAN_MODE; |
3382 | #else | 3388 | #else |
3383 | hdspm->control2_register = 0; | 3389 | hdspm->control2_register = 0; |
3384 | #endif | 3390 | #endif |
3385 | 3391 | ||
3386 | hdspm_write(hdspm, HDSPM_control2Reg, hdspm->control2_register); | 3392 | hdspm_write(hdspm, HDSPM_control2Reg, hdspm->control2_register); |
3393 | } | ||
3387 | hdspm_compute_period_size(hdspm); | 3394 | hdspm_compute_period_size(hdspm); |
3388 | 3395 | ||
3389 | /* silence everything */ | 3396 | /* silence everything */ |
@@ -3575,11 +3582,9 @@ static int snd_hdspm_reset(struct snd_pcm_substream *substream) | |||
3575 | else | 3582 | else |
3576 | runtime->status->hw_ptr = 0; | 3583 | runtime->status->hw_ptr = 0; |
3577 | if (other) { | 3584 | if (other) { |
3578 | struct list_head *pos; | ||
3579 | struct snd_pcm_substream *s; | 3585 | struct snd_pcm_substream *s; |
3580 | struct snd_pcm_runtime *oruntime = other->runtime; | 3586 | struct snd_pcm_runtime *oruntime = other->runtime; |
3581 | snd_pcm_group_for_each(pos, substream) { | 3587 | snd_pcm_group_for_each_entry(s, substream) { |
3582 | s = snd_pcm_group_substream_entry(pos); | ||
3583 | if (s == other) { | 3588 | if (s == other) { |
3584 | oruntime->status->hw_ptr = | 3589 | oruntime->status->hw_ptr = |
3585 | runtime->status->hw_ptr; | 3590 | runtime->status->hw_ptr; |
@@ -3658,11 +3663,10 @@ static int snd_hdspm_hw_params(struct snd_pcm_substream *substream, | |||
3658 | 3663 | ||
3659 | /* Memory allocation, takashi's method, dont know if we should spinlock */ | 3664 | /* Memory allocation, takashi's method, dont know if we should spinlock */ |
3660 | /* malloc all buffer even if not enabled to get sure */ | 3665 | /* malloc all buffer even if not enabled to get sure */ |
3661 | /* malloc only needed bytes */ | 3666 | /* Update for MADI rev 204: we need to allocate for all channels, |
3667 | * otherwise it doesn't work at 96kHz */ | ||
3662 | err = | 3668 | err = |
3663 | snd_pcm_lib_malloc_pages(substream, | 3669 | snd_pcm_lib_malloc_pages(substream, HDSPM_DMA_AREA_BYTES); |
3664 | HDSPM_CHANNEL_BUFFER_BYTES * | ||
3665 | params_channels(params)); | ||
3666 | if (err < 0) | 3670 | if (err < 0) |
3667 | return err; | 3671 | return err; |
3668 | 3672 | ||
@@ -3698,6 +3702,13 @@ static int snd_hdspm_hw_params(struct snd_pcm_substream *substream, | |||
3698 | "playback" : "capture", | 3702 | "playback" : "capture", |
3699 | snd_pcm_sgbuf_get_addr(sgbuf, 0)); | 3703 | snd_pcm_sgbuf_get_addr(sgbuf, 0)); |
3700 | */ | 3704 | */ |
3705 | /* | ||
3706 | snd_printdd("set_hwparams: %s %d Hz, %d channels, bs = %d\n", | ||
3707 | substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? | ||
3708 | "playback" : "capture", | ||
3709 | params_rate(params), params_channels(params), | ||
3710 | params_buffer_size(params)); | ||
3711 | */ | ||
3701 | return 0; | 3712 | return 0; |
3702 | } | 3713 | } |
3703 | 3714 | ||
@@ -3791,10 +3802,8 @@ static int snd_hdspm_trigger(struct snd_pcm_substream *substream, int cmd) | |||
3791 | other = hdspm->playback_substream; | 3802 | other = hdspm->playback_substream; |
3792 | 3803 | ||
3793 | if (other) { | 3804 | if (other) { |
3794 | struct list_head *pos; | ||
3795 | struct snd_pcm_substream *s; | 3805 | struct snd_pcm_substream *s; |
3796 | snd_pcm_group_for_each(pos, substream) { | 3806 | snd_pcm_group_for_each_entry(s, substream) { |
3797 | s = snd_pcm_group_substream_entry(pos); | ||
3798 | if (s == other) { | 3807 | if (s == other) { |
3799 | snd_pcm_trigger_done(s, substream); | 3808 | snd_pcm_trigger_done(s, substream); |
3800 | if (cmd == SNDRV_PCM_TRIGGER_START) | 3809 | if (cmd == SNDRV_PCM_TRIGGER_START) |
@@ -3904,16 +3913,16 @@ static int snd_hdspm_hw_rule_channels_rate(struct snd_pcm_hw_params *params, | |||
3904 | struct snd_interval *r = | 3913 | struct snd_interval *r = |
3905 | hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); | 3914 | hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); |
3906 | 3915 | ||
3907 | if (r->min > 48000) { | 3916 | if (r->min > 48000 && r->max <= 96000) { |
3908 | struct snd_interval t = { | 3917 | struct snd_interval t = { |
3909 | .min = 1, | 3918 | .min = hdspm->ds_channels, |
3910 | .max = hdspm->ds_channels, | 3919 | .max = hdspm->ds_channels, |
3911 | .integer = 1, | 3920 | .integer = 1, |
3912 | }; | 3921 | }; |
3913 | return snd_interval_refine(c, &t); | 3922 | return snd_interval_refine(c, &t); |
3914 | } else if (r->max < 64000) { | 3923 | } else if (r->max < 64000) { |
3915 | struct snd_interval t = { | 3924 | struct snd_interval t = { |
3916 | .min = 1, | 3925 | .min = hdspm->ss_channels, |
3917 | .max = hdspm->ss_channels, | 3926 | .max = hdspm->ss_channels, |
3918 | .integer = 1, | 3927 | .integer = 1, |
3919 | }; | 3928 | }; |
@@ -3931,14 +3940,14 @@ static int snd_hdspm_hw_rule_rate_channels(struct snd_pcm_hw_params *params, | |||
3931 | struct snd_interval *r = | 3940 | struct snd_interval *r = |
3932 | hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); | 3941 | hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); |
3933 | 3942 | ||
3934 | if (c->min <= hdspm->ss_channels) { | 3943 | if (c->min >= hdspm->ss_channels) { |
3935 | struct snd_interval t = { | 3944 | struct snd_interval t = { |
3936 | .min = 32000, | 3945 | .min = 32000, |
3937 | .max = 48000, | 3946 | .max = 48000, |
3938 | .integer = 1, | 3947 | .integer = 1, |
3939 | }; | 3948 | }; |
3940 | return snd_interval_refine(r, &t); | 3949 | return snd_interval_refine(r, &t); |
3941 | } else if (c->max > hdspm->ss_channels) { | 3950 | } else if (c->max <= hdspm->ds_channels) { |
3942 | struct snd_interval t = { | 3951 | struct snd_interval t = { |
3943 | .min = 64000, | 3952 | .min = 64000, |
3944 | .max = 96000, | 3953 | .max = 96000, |
@@ -3950,13 +3959,39 @@ static int snd_hdspm_hw_rule_rate_channels(struct snd_pcm_hw_params *params, | |||
3950 | return 0; | 3959 | return 0; |
3951 | } | 3960 | } |
3952 | 3961 | ||
3962 | static int snd_hdspm_hw_rule_channels(struct snd_pcm_hw_params *params, | ||
3963 | struct snd_pcm_hw_rule *rule) | ||
3964 | { | ||
3965 | unsigned int list[3]; | ||
3966 | struct hdspm *hdspm = rule->private; | ||
3967 | struct snd_interval *c = hw_param_interval(params, | ||
3968 | SNDRV_PCM_HW_PARAM_CHANNELS); | ||
3969 | if (hdspm->is_aes32) { | ||
3970 | list[0] = hdspm->qs_channels; | ||
3971 | list[1] = hdspm->ds_channels; | ||
3972 | list[2] = hdspm->ss_channels; | ||
3973 | return snd_interval_list(c, 3, list, 0); | ||
3974 | } else { | ||
3975 | list[0] = hdspm->ds_channels; | ||
3976 | list[1] = hdspm->ss_channels; | ||
3977 | return snd_interval_list(c, 2, list, 0); | ||
3978 | } | ||
3979 | } | ||
3980 | |||
3981 | |||
3982 | static unsigned int hdspm_aes32_sample_rates[] = { 32000, 44100, 48000, 64000, 88200, 96000, 128000, 176400, 192000 }; | ||
3983 | |||
3984 | static struct snd_pcm_hw_constraint_list hdspm_hw_constraints_aes32_sample_rates = { | ||
3985 | .count = ARRAY_SIZE(hdspm_aes32_sample_rates), | ||
3986 | .list = hdspm_aes32_sample_rates, | ||
3987 | .mask = 0 | ||
3988 | }; | ||
3989 | |||
3953 | static int snd_hdspm_playback_open(struct snd_pcm_substream *substream) | 3990 | static int snd_hdspm_playback_open(struct snd_pcm_substream *substream) |
3954 | { | 3991 | { |
3955 | struct hdspm *hdspm = snd_pcm_substream_chip(substream); | 3992 | struct hdspm *hdspm = snd_pcm_substream_chip(substream); |
3956 | struct snd_pcm_runtime *runtime = substream->runtime; | 3993 | struct snd_pcm_runtime *runtime = substream->runtime; |
3957 | 3994 | ||
3958 | snd_printdd("Open device substream %d\n", substream->stream); | ||
3959 | |||
3960 | spin_lock_irq(&hdspm->lock); | 3995 | spin_lock_irq(&hdspm->lock); |
3961 | 3996 | ||
3962 | snd_pcm_set_sync(substream); | 3997 | snd_pcm_set_sync(substream); |
@@ -3977,14 +4012,21 @@ static int snd_hdspm_playback_open(struct snd_pcm_substream *substream) | |||
3977 | SNDRV_PCM_HW_PARAM_PERIOD_SIZE, | 4012 | SNDRV_PCM_HW_PARAM_PERIOD_SIZE, |
3978 | &hw_constraints_period_sizes); | 4013 | &hw_constraints_period_sizes); |
3979 | 4014 | ||
3980 | snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, | 4015 | if (hdspm->is_aes32) { |
3981 | snd_hdspm_hw_rule_channels_rate, hdspm, | 4016 | snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, |
3982 | SNDRV_PCM_HW_PARAM_RATE, -1); | 4017 | &hdspm_hw_constraints_aes32_sample_rates); |
3983 | 4018 | } else { | |
3984 | snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, | 4019 | snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, |
3985 | snd_hdspm_hw_rule_rate_channels, hdspm, | 4020 | snd_hdspm_hw_rule_channels, hdspm, |
3986 | SNDRV_PCM_HW_PARAM_CHANNELS, -1); | 4021 | SNDRV_PCM_HW_PARAM_CHANNELS, -1); |
3987 | 4022 | snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, | |
4023 | snd_hdspm_hw_rule_channels_rate, hdspm, | ||
4024 | SNDRV_PCM_HW_PARAM_RATE, -1); | ||
4025 | |||
4026 | snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, | ||
4027 | snd_hdspm_hw_rule_rate_channels, hdspm, | ||
4028 | SNDRV_PCM_HW_PARAM_CHANNELS, -1); | ||
4029 | } | ||
3988 | return 0; | 4030 | return 0; |
3989 | } | 4031 | } |
3990 | 4032 | ||
@@ -4024,14 +4066,21 @@ static int snd_hdspm_capture_open(struct snd_pcm_substream *substream) | |||
4024 | snd_pcm_hw_constraint_list(runtime, 0, | 4066 | snd_pcm_hw_constraint_list(runtime, 0, |
4025 | SNDRV_PCM_HW_PARAM_PERIOD_SIZE, | 4067 | SNDRV_PCM_HW_PARAM_PERIOD_SIZE, |
4026 | &hw_constraints_period_sizes); | 4068 | &hw_constraints_period_sizes); |
4027 | 4069 | if (hdspm->is_aes32) { | |
4028 | snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, | 4070 | snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, |
4029 | snd_hdspm_hw_rule_channels_rate, hdspm, | 4071 | &hdspm_hw_constraints_aes32_sample_rates); |
4030 | SNDRV_PCM_HW_PARAM_RATE, -1); | 4072 | } else { |
4031 | 4073 | snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, | |
4032 | snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, | 4074 | snd_hdspm_hw_rule_channels, hdspm, |
4033 | snd_hdspm_hw_rule_rate_channels, hdspm, | 4075 | SNDRV_PCM_HW_PARAM_CHANNELS, -1); |
4034 | SNDRV_PCM_HW_PARAM_CHANNELS, -1); | 4076 | snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, |
4077 | snd_hdspm_hw_rule_channels_rate, hdspm, | ||
4078 | SNDRV_PCM_HW_PARAM_RATE, -1); | ||
4079 | |||
4080 | snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, | ||
4081 | snd_hdspm_hw_rule_rate_channels, hdspm, | ||
4082 | SNDRV_PCM_HW_PARAM_CHANNELS, -1); | ||
4083 | } | ||
4035 | return 0; | 4084 | return 0; |
4036 | } | 4085 | } |
4037 | 4086 | ||
diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c index cc3bdececce7..bd7dbd267ed1 100644 --- a/sound/pci/rme9652/rme9652.c +++ b/sound/pci/rme9652/rme9652.c | |||
@@ -1992,11 +1992,9 @@ static int snd_rme9652_reset(struct snd_pcm_substream *substream) | |||
1992 | else | 1992 | else |
1993 | runtime->status->hw_ptr = 0; | 1993 | runtime->status->hw_ptr = 0; |
1994 | if (other) { | 1994 | if (other) { |
1995 | struct list_head *pos; | ||
1996 | struct snd_pcm_substream *s; | 1995 | struct snd_pcm_substream *s; |
1997 | struct snd_pcm_runtime *oruntime = other->runtime; | 1996 | struct snd_pcm_runtime *oruntime = other->runtime; |
1998 | snd_pcm_group_for_each(pos, substream) { | 1997 | snd_pcm_group_for_each_entry(s, substream) { |
1999 | s = snd_pcm_group_substream_entry(pos); | ||
2000 | if (s == other) { | 1998 | if (s == other) { |
2001 | oruntime->status->hw_ptr = runtime->status->hw_ptr; | 1999 | oruntime->status->hw_ptr = runtime->status->hw_ptr; |
2002 | break; | 2000 | break; |
@@ -2140,10 +2138,8 @@ static int snd_rme9652_trigger(struct snd_pcm_substream *substream, | |||
2140 | other = rme9652->playback_substream; | 2138 | other = rme9652->playback_substream; |
2141 | 2139 | ||
2142 | if (other) { | 2140 | if (other) { |
2143 | struct list_head *pos; | ||
2144 | struct snd_pcm_substream *s; | 2141 | struct snd_pcm_substream *s; |
2145 | snd_pcm_group_for_each(pos, substream) { | 2142 | snd_pcm_group_for_each_entry(s, substream) { |
2146 | s = snd_pcm_group_substream_entry(pos); | ||
2147 | if (s == other) { | 2143 | if (s == other) { |
2148 | snd_pcm_trigger_done(s, substream); | 2144 | snd_pcm_trigger_done(s, substream); |
2149 | if (cmd == SNDRV_PCM_TRIGGER_START) | 2145 | if (cmd == SNDRV_PCM_TRIGGER_START) |