diff options
Diffstat (limited to 'sound/pci/rme9652')
-rw-r--r-- | sound/pci/rme9652/hdspm.c | 4466 |
1 files changed, 3352 insertions, 1114 deletions
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c index f5eadfc0672a..a323eafb9e03 100644 --- a/sound/pci/rme9652/hdspm.c +++ b/sound/pci/rme9652/hdspm.c | |||
@@ -8,6 +8,21 @@ | |||
8 | * Modified 2006-06-01 for AES32 support by Remy Bruno | 8 | * Modified 2006-06-01 for AES32 support by Remy Bruno |
9 | * <remy.bruno@trinnov.com> | 9 | * <remy.bruno@trinnov.com> |
10 | * | 10 | * |
11 | * Modified 2009-04-13 for proper metering by Florian Faber | ||
12 | * <faber@faberman.de> | ||
13 | * | ||
14 | * Modified 2009-04-14 for native float support by Florian Faber | ||
15 | * <faber@faberman.de> | ||
16 | * | ||
17 | * Modified 2009-04-26 fixed bug in rms metering by Florian Faber | ||
18 | * <faber@faberman.de> | ||
19 | * | ||
20 | * Modified 2009-04-30 added hw serial number support by Florian Faber | ||
21 | * | ||
22 | * Modified 2011-01-14 added S/PDIF input on RayDATs by Adrian Knoth | ||
23 | * | ||
24 | * Modified 2011-01-25 variable period sizes on RayDAT/AIO by Adrian Knoth | ||
25 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | 26 | * This program is free software; you can redistribute it and/or modify |
12 | * it under the terms of the GNU General Public License as published by | 27 | * it under the terms of the GNU General Public License as published by |
13 | * the Free Software Foundation; either version 2 of the License, or | 28 | * the Free Software Foundation; either version 2 of the License, or |
@@ -35,6 +50,7 @@ | |||
35 | #include <sound/core.h> | 50 | #include <sound/core.h> |
36 | #include <sound/control.h> | 51 | #include <sound/control.h> |
37 | #include <sound/pcm.h> | 52 | #include <sound/pcm.h> |
53 | #include <sound/pcm_params.h> | ||
38 | #include <sound/info.h> | 54 | #include <sound/info.h> |
39 | #include <sound/asoundef.h> | 55 | #include <sound/asoundef.h> |
40 | #include <sound/rawmidi.h> | 56 | #include <sound/rawmidi.h> |
@@ -47,15 +63,6 @@ static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ | |||
47 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ | 63 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ |
48 | static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;/* Enable this card */ | 64 | static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;/* Enable this card */ |
49 | 65 | ||
50 | /* Disable precise pointer at start */ | ||
51 | static int precise_ptr[SNDRV_CARDS]; | ||
52 | |||
53 | /* Send all playback to line outs */ | ||
54 | static int line_outs_monitor[SNDRV_CARDS]; | ||
55 | |||
56 | /* Enable Analog Outs on Channel 63/64 by default */ | ||
57 | static int enable_monitor[SNDRV_CARDS]; | ||
58 | |||
59 | module_param_array(index, int, NULL, 0444); | 66 | module_param_array(index, int, NULL, 0444); |
60 | MODULE_PARM_DESC(index, "Index value for RME HDSPM interface."); | 67 | MODULE_PARM_DESC(index, "Index value for RME HDSPM interface."); |
61 | 68 | ||
@@ -65,42 +72,39 @@ MODULE_PARM_DESC(id, "ID string for RME HDSPM interface."); | |||
65 | module_param_array(enable, bool, NULL, 0444); | 72 | module_param_array(enable, bool, NULL, 0444); |
66 | MODULE_PARM_DESC(enable, "Enable/disable specific HDSPM soundcards."); | 73 | MODULE_PARM_DESC(enable, "Enable/disable specific HDSPM soundcards."); |
67 | 74 | ||
68 | module_param_array(precise_ptr, bool, NULL, 0444); | ||
69 | MODULE_PARM_DESC(precise_ptr, "Enable or disable precise pointer."); | ||
70 | |||
71 | module_param_array(line_outs_monitor, bool, NULL, 0444); | ||
72 | MODULE_PARM_DESC(line_outs_monitor, | ||
73 | "Send playback streams to analog outs by default."); | ||
74 | |||
75 | module_param_array(enable_monitor, bool, NULL, 0444); | ||
76 | MODULE_PARM_DESC(enable_monitor, | ||
77 | "Enable Analog Out on Channel 63/64 by default."); | ||
78 | 75 | ||
79 | MODULE_AUTHOR | 76 | MODULE_AUTHOR |
80 | ("Winfried Ritsch <ritsch_AT_iem.at>, " | 77 | ( |
81 | "Paul Davis <paul@linuxaudiosystems.com>, " | 78 | "Winfried Ritsch <ritsch_AT_iem.at>, " |
82 | "Marcus Andersson, Thomas Charbonnel <thomas@undata.org>, " | 79 | "Paul Davis <paul@linuxaudiosystems.com>, " |
83 | "Remy Bruno <remy.bruno@trinnov.com>"); | 80 | "Marcus Andersson, Thomas Charbonnel <thomas@undata.org>, " |
81 | "Remy Bruno <remy.bruno@trinnov.com>, " | ||
82 | "Florian Faber <faberman@linuxproaudio.org>, " | ||
83 | "Adrian Knoth <adi@drcomp.erfurt.thur.de>" | ||
84 | ); | ||
84 | MODULE_DESCRIPTION("RME HDSPM"); | 85 | MODULE_DESCRIPTION("RME HDSPM"); |
85 | MODULE_LICENSE("GPL"); | 86 | MODULE_LICENSE("GPL"); |
86 | MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}"); | 87 | MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}"); |
87 | 88 | ||
88 | /* --- Write registers. --- | 89 | /* --- Write registers. --- |
89 | These are defined as byte-offsets from the iobase value. */ | 90 | These are defined as byte-offsets from the iobase value. */ |
90 | 91 | ||
92 | #define HDSPM_WR_SETTINGS 0 | ||
93 | #define HDSPM_outputBufferAddress 32 | ||
94 | #define HDSPM_inputBufferAddress 36 | ||
91 | #define HDSPM_controlRegister 64 | 95 | #define HDSPM_controlRegister 64 |
92 | #define HDSPM_interruptConfirmation 96 | 96 | #define HDSPM_interruptConfirmation 96 |
93 | #define HDSPM_control2Reg 256 /* not in specs ???????? */ | 97 | #define HDSPM_control2Reg 256 /* not in specs ???????? */ |
94 | #define HDSPM_freqReg 256 /* for AES32 */ | 98 | #define HDSPM_freqReg 256 /* for AES32 */ |
95 | #define HDSPM_midiDataOut0 352 /* just believe in old code */ | 99 | #define HDSPM_midiDataOut0 352 /* just believe in old code */ |
96 | #define HDSPM_midiDataOut1 356 | 100 | #define HDSPM_midiDataOut1 356 |
97 | #define HDSPM_eeprom_wr 384 /* for AES32 */ | 101 | #define HDSPM_eeprom_wr 384 /* for AES32 */ |
98 | 102 | ||
99 | /* DMA enable for 64 channels, only Bit 0 is relevant */ | 103 | /* DMA enable for 64 channels, only Bit 0 is relevant */ |
100 | #define HDSPM_outputEnableBase 512 /* 512-767 input DMA */ | 104 | #define HDSPM_outputEnableBase 512 /* 512-767 input DMA */ |
101 | #define HDSPM_inputEnableBase 768 /* 768-1023 output DMA */ | 105 | #define HDSPM_inputEnableBase 768 /* 768-1023 output DMA */ |
102 | 106 | ||
103 | /* 16 page addresses for each of the 64 channels DMA buffer in and out | 107 | /* 16 page addresses for each of the 64 channels DMA buffer in and out |
104 | (each 64k=16*4k) Buffer must be 4k aligned (which is default i386 ????) */ | 108 | (each 64k=16*4k) Buffer must be 4k aligned (which is default i386 ????) */ |
105 | #define HDSPM_pageAddressBufferOut 8192 | 109 | #define HDSPM_pageAddressBufferOut 8192 |
106 | #define HDSPM_pageAddressBufferIn (HDSPM_pageAddressBufferOut+64*16*4) | 110 | #define HDSPM_pageAddressBufferIn (HDSPM_pageAddressBufferOut+64*16*4) |
@@ -119,22 +123,84 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}"); | |||
119 | #define HDSPM_statusRegister2 192 | 123 | #define HDSPM_statusRegister2 192 |
120 | #define HDSPM_timecodeRegister 128 | 124 | #define HDSPM_timecodeRegister 128 |
121 | 125 | ||
126 | /* AIO, RayDAT */ | ||
127 | #define HDSPM_RD_STATUS_0 0 | ||
128 | #define HDSPM_RD_STATUS_1 64 | ||
129 | #define HDSPM_RD_STATUS_2 128 | ||
130 | #define HDSPM_RD_STATUS_3 192 | ||
131 | |||
132 | #define HDSPM_RD_TCO 256 | ||
133 | #define HDSPM_RD_PLL_FREQ 512 | ||
134 | #define HDSPM_WR_TCO 128 | ||
135 | |||
136 | #define HDSPM_TCO1_TCO_lock 0x00000001 | ||
137 | #define HDSPM_TCO1_WCK_Input_Range_LSB 0x00000002 | ||
138 | #define HDSPM_TCO1_WCK_Input_Range_MSB 0x00000004 | ||
139 | #define HDSPM_TCO1_LTC_Input_valid 0x00000008 | ||
140 | #define HDSPM_TCO1_WCK_Input_valid 0x00000010 | ||
141 | #define HDSPM_TCO1_Video_Input_Format_NTSC 0x00000020 | ||
142 | #define HDSPM_TCO1_Video_Input_Format_PAL 0x00000040 | ||
143 | |||
144 | #define HDSPM_TCO1_set_TC 0x00000100 | ||
145 | #define HDSPM_TCO1_set_drop_frame_flag 0x00000200 | ||
146 | #define HDSPM_TCO1_LTC_Format_LSB 0x00000400 | ||
147 | #define HDSPM_TCO1_LTC_Format_MSB 0x00000800 | ||
148 | |||
149 | #define HDSPM_TCO2_TC_run 0x00010000 | ||
150 | #define HDSPM_TCO2_WCK_IO_ratio_LSB 0x00020000 | ||
151 | #define HDSPM_TCO2_WCK_IO_ratio_MSB 0x00040000 | ||
152 | #define HDSPM_TCO2_set_num_drop_frames_LSB 0x00080000 | ||
153 | #define HDSPM_TCO2_set_num_drop_frames_MSB 0x00100000 | ||
154 | #define HDSPM_TCO2_set_jam_sync 0x00200000 | ||
155 | #define HDSPM_TCO2_set_flywheel 0x00400000 | ||
156 | |||
157 | #define HDSPM_TCO2_set_01_4 0x01000000 | ||
158 | #define HDSPM_TCO2_set_pull_down 0x02000000 | ||
159 | #define HDSPM_TCO2_set_pull_up 0x04000000 | ||
160 | #define HDSPM_TCO2_set_freq 0x08000000 | ||
161 | #define HDSPM_TCO2_set_term_75R 0x10000000 | ||
162 | #define HDSPM_TCO2_set_input_LSB 0x20000000 | ||
163 | #define HDSPM_TCO2_set_input_MSB 0x40000000 | ||
164 | #define HDSPM_TCO2_set_freq_from_app 0x80000000 | ||
165 | |||
166 | |||
167 | #define HDSPM_midiDataOut0 352 | ||
168 | #define HDSPM_midiDataOut1 356 | ||
169 | #define HDSPM_midiDataOut2 368 | ||
170 | |||
122 | #define HDSPM_midiDataIn0 360 | 171 | #define HDSPM_midiDataIn0 360 |
123 | #define HDSPM_midiDataIn1 364 | 172 | #define HDSPM_midiDataIn1 364 |
173 | #define HDSPM_midiDataIn2 372 | ||
174 | #define HDSPM_midiDataIn3 376 | ||
124 | 175 | ||
125 | /* status is data bytes in MIDI-FIFO (0-128) */ | 176 | /* status is data bytes in MIDI-FIFO (0-128) */ |
126 | #define HDSPM_midiStatusOut0 384 | 177 | #define HDSPM_midiStatusOut0 384 |
127 | #define HDSPM_midiStatusOut1 388 | 178 | #define HDSPM_midiStatusOut1 388 |
128 | #define HDSPM_midiStatusIn0 392 | 179 | #define HDSPM_midiStatusOut2 400 |
129 | #define HDSPM_midiStatusIn1 396 | 180 | |
181 | #define HDSPM_midiStatusIn0 392 | ||
182 | #define HDSPM_midiStatusIn1 396 | ||
183 | #define HDSPM_midiStatusIn2 404 | ||
184 | #define HDSPM_midiStatusIn3 408 | ||
130 | 185 | ||
131 | 186 | ||
132 | /* the meters are regular i/o-mapped registers, but offset | 187 | /* the meters are regular i/o-mapped registers, but offset |
133 | considerably from the rest. the peak registers are reset | 188 | considerably from the rest. the peak registers are reset |
134 | when read; the least-significant 4 bits are full-scale counters; | 189 | when read; the least-significant 4 bits are full-scale counters; |
135 | the actual peak value is in the most-significant 24 bits. | 190 | the actual peak value is in the most-significant 24 bits. |
136 | */ | 191 | */ |
137 | #define HDSPM_MADI_peakrmsbase 4096 /* 4096-8191 2x64x32Bit Meters */ | 192 | |
193 | #define HDSPM_MADI_INPUT_PEAK 4096 | ||
194 | #define HDSPM_MADI_PLAYBACK_PEAK 4352 | ||
195 | #define HDSPM_MADI_OUTPUT_PEAK 4608 | ||
196 | |||
197 | #define HDSPM_MADI_INPUT_RMS_L 6144 | ||
198 | #define HDSPM_MADI_PLAYBACK_RMS_L 6400 | ||
199 | #define HDSPM_MADI_OUTPUT_RMS_L 6656 | ||
200 | |||
201 | #define HDSPM_MADI_INPUT_RMS_H 7168 | ||
202 | #define HDSPM_MADI_PLAYBACK_RMS_H 7424 | ||
203 | #define HDSPM_MADI_OUTPUT_RMS_H 7680 | ||
138 | 204 | ||
139 | /* --- Control Register bits --------- */ | 205 | /* --- Control Register bits --------- */ |
140 | #define HDSPM_Start (1<<0) /* start engine */ | 206 | #define HDSPM_Start (1<<0) /* start engine */ |
@@ -143,7 +209,9 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}"); | |||
143 | #define HDSPM_Latency1 (1<<2) /* where n is defined */ | 209 | #define HDSPM_Latency1 (1<<2) /* where n is defined */ |
144 | #define HDSPM_Latency2 (1<<3) /* by Latency{2,1,0} */ | 210 | #define HDSPM_Latency2 (1<<3) /* by Latency{2,1,0} */ |
145 | 211 | ||
146 | #define HDSPM_ClockModeMaster (1<<4) /* 1=Master, 0=Slave/Autosync */ | 212 | #define HDSPM_ClockModeMaster (1<<4) /* 1=Master, 0=Autosync */ |
213 | #define HDSPM_c0Master 0x1 /* Master clock bit in settings | ||
214 | register [RayDAT, AIO] */ | ||
147 | 215 | ||
148 | #define HDSPM_AudioInterruptEnable (1<<5) /* what do you think ? */ | 216 | #define HDSPM_AudioInterruptEnable (1<<5) /* what do you think ? */ |
149 | 217 | ||
@@ -157,7 +225,7 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}"); | |||
157 | 56channelMODE=0 */ /* MADI ONLY*/ | 225 | 56channelMODE=0 */ /* MADI ONLY*/ |
158 | #define HDSPM_Emphasis (1<<10) /* Emphasis */ /* AES32 ONLY */ | 226 | #define HDSPM_Emphasis (1<<10) /* Emphasis */ /* AES32 ONLY */ |
159 | 227 | ||
160 | #define HDSPM_AutoInp (1<<11) /* Auto Input (takeover) == Safe Mode, | 228 | #define HDSPM_AutoInp (1<<11) /* Auto Input (takeover) == Safe Mode, |
161 | 0=off, 1=on */ /* MADI ONLY */ | 229 | 0=off, 1=on */ /* MADI ONLY */ |
162 | #define HDSPM_Dolby (1<<11) /* Dolby = "NonAudio" ?? */ /* AES32 ONLY */ | 230 | #define HDSPM_Dolby (1<<11) /* Dolby = "NonAudio" ?? */ /* AES32 ONLY */ |
163 | 231 | ||
@@ -166,22 +234,23 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}"); | |||
166 | */ | 234 | */ |
167 | #define HDSPM_InputSelect1 (1<<15) /* should be 0 */ | 235 | #define HDSPM_InputSelect1 (1<<15) /* should be 0 */ |
168 | 236 | ||
169 | #define HDSPM_SyncRef0 (1<<16) /* 0=WOrd, 1=MADI */ | ||
170 | #define HDSPM_SyncRef1 (1<<17) /* for AES32: SyncRefN codes the AES # */ | ||
171 | #define HDSPM_SyncRef2 (1<<13) | 237 | #define HDSPM_SyncRef2 (1<<13) |
172 | #define HDSPM_SyncRef3 (1<<25) | 238 | #define HDSPM_SyncRef3 (1<<25) |
173 | 239 | ||
174 | #define HDSPM_SMUX (1<<18) /* Frame ??? */ /* MADI ONY */ | 240 | #define HDSPM_SMUX (1<<18) /* Frame ??? */ /* MADI ONY */ |
175 | #define HDSPM_clr_tms (1<<19) /* clear track marker, do not use | 241 | #define HDSPM_clr_tms (1<<19) /* clear track marker, do not use |
176 | AES additional bits in | 242 | AES additional bits in |
177 | lower 5 Audiodatabits ??? */ | 243 | lower 5 Audiodatabits ??? */ |
178 | #define HDSPM_taxi_reset (1<<20) /* ??? */ /* MADI ONLY ? */ | 244 | #define HDSPM_taxi_reset (1<<20) /* ??? */ /* MADI ONLY ? */ |
179 | #define HDSPM_WCK48 (1<<20) /* Frame ??? = HDSPM_SMUX */ /* AES32 ONLY */ | 245 | #define HDSPM_WCK48 (1<<20) /* Frame ??? = HDSPM_SMUX */ /* AES32 ONLY */ |
180 | 246 | ||
181 | #define HDSPM_Midi0InterruptEnable (1<<22) | 247 | #define HDSPM_Midi0InterruptEnable 0x0400000 |
182 | #define HDSPM_Midi1InterruptEnable (1<<23) | 248 | #define HDSPM_Midi1InterruptEnable 0x0800000 |
249 | #define HDSPM_Midi2InterruptEnable 0x0200000 | ||
250 | #define HDSPM_Midi3InterruptEnable 0x4000000 | ||
183 | 251 | ||
184 | #define HDSPM_LineOut (1<<24) /* Analog Out on channel 63/64 on=1, mute=0 */ | 252 | #define HDSPM_LineOut (1<<24) /* Analog Out on channel 63/64 on=1, mute=0 */ |
253 | #define HDSPe_FLOAT_FORMAT 0x2000000 | ||
185 | 254 | ||
186 | #define HDSPM_DS_DoubleWire (1<<26) /* AES32 ONLY */ | 255 | #define HDSPM_DS_DoubleWire (1<<26) /* AES32 ONLY */ |
187 | #define HDSPM_QS_DoubleWire (1<<27) /* AES32 ONLY */ | 256 | #define HDSPM_QS_DoubleWire (1<<27) /* AES32 ONLY */ |
@@ -198,11 +267,18 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}"); | |||
198 | #define HDSPM_InputCoaxial (HDSPM_InputSelect0) | 267 | #define HDSPM_InputCoaxial (HDSPM_InputSelect0) |
199 | #define HDSPM_SyncRefMask (HDSPM_SyncRef0|HDSPM_SyncRef1|\ | 268 | #define HDSPM_SyncRefMask (HDSPM_SyncRef0|HDSPM_SyncRef1|\ |
200 | HDSPM_SyncRef2|HDSPM_SyncRef3) | 269 | HDSPM_SyncRef2|HDSPM_SyncRef3) |
201 | #define HDSPM_SyncRef_Word 0 | ||
202 | #define HDSPM_SyncRef_MADI (HDSPM_SyncRef0) | ||
203 | 270 | ||
204 | #define HDSPM_SYNC_FROM_WORD 0 /* Preferred sync reference */ | 271 | #define HDSPM_c0_SyncRef0 0x2 |
205 | #define HDSPM_SYNC_FROM_MADI 1 /* choices - used by "pref_sync_ref" */ | 272 | #define HDSPM_c0_SyncRef1 0x4 |
273 | #define HDSPM_c0_SyncRef2 0x8 | ||
274 | #define HDSPM_c0_SyncRef3 0x10 | ||
275 | #define HDSPM_c0_SyncRefMask (HDSPM_c0_SyncRef0 | HDSPM_c0_SyncRef1 |\ | ||
276 | HDSPM_c0_SyncRef2 | HDSPM_c0_SyncRef3) | ||
277 | |||
278 | #define HDSPM_SYNC_FROM_WORD 0 /* Preferred sync reference */ | ||
279 | #define HDSPM_SYNC_FROM_MADI 1 /* choices - used by "pref_sync_ref" */ | ||
280 | #define HDSPM_SYNC_FROM_TCO 2 | ||
281 | #define HDSPM_SYNC_FROM_SYNC_IN 3 | ||
206 | 282 | ||
207 | #define HDSPM_Frequency32KHz HDSPM_Frequency0 | 283 | #define HDSPM_Frequency32KHz HDSPM_Frequency0 |
208 | #define HDSPM_Frequency44_1KHz HDSPM_Frequency1 | 284 | #define HDSPM_Frequency44_1KHz HDSPM_Frequency1 |
@@ -216,17 +292,6 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}"); | |||
216 | #define HDSPM_Frequency192KHz (HDSPM_QuadSpeed|HDSPM_Frequency1|\ | 292 | #define HDSPM_Frequency192KHz (HDSPM_QuadSpeed|HDSPM_Frequency1|\ |
217 | HDSPM_Frequency0) | 293 | HDSPM_Frequency0) |
218 | 294 | ||
219 | /* --- for internal discrimination */ | ||
220 | #define HDSPM_CLOCK_SOURCE_AUTOSYNC 0 /* Sample Clock Sources */ | ||
221 | #define HDSPM_CLOCK_SOURCE_INTERNAL_32KHZ 1 | ||
222 | #define HDSPM_CLOCK_SOURCE_INTERNAL_44_1KHZ 2 | ||
223 | #define HDSPM_CLOCK_SOURCE_INTERNAL_48KHZ 3 | ||
224 | #define HDSPM_CLOCK_SOURCE_INTERNAL_64KHZ 4 | ||
225 | #define HDSPM_CLOCK_SOURCE_INTERNAL_88_2KHZ 5 | ||
226 | #define HDSPM_CLOCK_SOURCE_INTERNAL_96KHZ 6 | ||
227 | #define HDSPM_CLOCK_SOURCE_INTERNAL_128KHZ 7 | ||
228 | #define HDSPM_CLOCK_SOURCE_INTERNAL_176_4KHZ 8 | ||
229 | #define HDSPM_CLOCK_SOURCE_INTERNAL_192KHZ 9 | ||
230 | 295 | ||
231 | /* Synccheck Status */ | 296 | /* Synccheck Status */ |
232 | #define HDSPM_SYNC_CHECK_NO_LOCK 0 | 297 | #define HDSPM_SYNC_CHECK_NO_LOCK 0 |
@@ -236,14 +301,16 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}"); | |||
236 | /* AutoSync References - used by "autosync_ref" control switch */ | 301 | /* AutoSync References - used by "autosync_ref" control switch */ |
237 | #define HDSPM_AUTOSYNC_FROM_WORD 0 | 302 | #define HDSPM_AUTOSYNC_FROM_WORD 0 |
238 | #define HDSPM_AUTOSYNC_FROM_MADI 1 | 303 | #define HDSPM_AUTOSYNC_FROM_MADI 1 |
239 | #define HDSPM_AUTOSYNC_FROM_NONE 2 | 304 | #define HDSPM_AUTOSYNC_FROM_TCO 2 |
305 | #define HDSPM_AUTOSYNC_FROM_SYNC_IN 3 | ||
306 | #define HDSPM_AUTOSYNC_FROM_NONE 4 | ||
240 | 307 | ||
241 | /* Possible sources of MADI input */ | 308 | /* Possible sources of MADI input */ |
242 | #define HDSPM_OPTICAL 0 /* optical */ | 309 | #define HDSPM_OPTICAL 0 /* optical */ |
243 | #define HDSPM_COAXIAL 1 /* BNC */ | 310 | #define HDSPM_COAXIAL 1 /* BNC */ |
244 | 311 | ||
245 | #define hdspm_encode_latency(x) (((x)<<1) & HDSPM_LatencyMask) | 312 | #define hdspm_encode_latency(x) (((x)<<1) & HDSPM_LatencyMask) |
246 | #define hdspm_decode_latency(x) (((x) & HDSPM_LatencyMask)>>1) | 313 | #define hdspm_decode_latency(x) ((((x) & HDSPM_LatencyMask)>>1)) |
247 | 314 | ||
248 | #define hdspm_encode_in(x) (((x)&0x3)<<14) | 315 | #define hdspm_encode_in(x) (((x)&0x3)<<14) |
249 | #define hdspm_decode_in(x) (((x)>>14)&0x3) | 316 | #define hdspm_decode_in(x) (((x)>>14)&0x3) |
@@ -270,13 +337,21 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}"); | |||
270 | #define HDSPM_AB_int (1<<2) /* InputChannel Opt=0, Coax=1 | 337 | #define HDSPM_AB_int (1<<2) /* InputChannel Opt=0, Coax=1 |
271 | * (like inp0) | 338 | * (like inp0) |
272 | */ | 339 | */ |
340 | |||
273 | #define HDSPM_madiLock (1<<3) /* MADI Locked =1, no=0 */ | 341 | #define HDSPM_madiLock (1<<3) /* MADI Locked =1, no=0 */ |
342 | #define HDSPM_madiSync (1<<18) /* MADI is in sync */ | ||
343 | |||
344 | #define HDSPM_tcoLock 0x00000020 /* Optional TCO locked status FOR HDSPe MADI! */ | ||
345 | #define HDSPM_tcoSync 0x10000000 /* Optional TCO sync status */ | ||
346 | |||
347 | #define HDSPM_syncInLock 0x00010000 /* Sync In lock status FOR HDSPe MADI! */ | ||
348 | #define HDSPM_syncInSync 0x00020000 /* Sync In sync status FOR HDSPe MADI! */ | ||
274 | 349 | ||
275 | #define HDSPM_BufferPositionMask 0x000FFC0 /* Bit 6..15 : h/w buffer pointer */ | 350 | #define HDSPM_BufferPositionMask 0x000FFC0 /* Bit 6..15 : h/w buffer pointer */ |
276 | /* since 64byte accurate last 6 bits | 351 | /* since 64byte accurate, last 6 bits are not used */ |
277 | are not used */ | 352 | |
353 | |||
278 | 354 | ||
279 | #define HDSPM_madiSync (1<<18) /* MADI is in sync */ | ||
280 | #define HDSPM_DoubleSpeedStatus (1<<19) /* (input) card in double speed */ | 355 | #define HDSPM_DoubleSpeedStatus (1<<19) /* (input) card in double speed */ |
281 | 356 | ||
282 | #define HDSPM_madiFreq0 (1<<22) /* system freq 0=error */ | 357 | #define HDSPM_madiFreq0 (1<<22) /* system freq 0=error */ |
@@ -287,8 +362,19 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}"); | |||
287 | #define HDSPM_BufferID (1<<26) /* (Double)Buffer ID toggles with | 362 | #define HDSPM_BufferID (1<<26) /* (Double)Buffer ID toggles with |
288 | * Interrupt | 363 | * Interrupt |
289 | */ | 364 | */ |
290 | #define HDSPM_midi0IRQPending (1<<30) /* MIDI IRQ is pending */ | 365 | #define HDSPM_tco_detect 0x08000000 |
291 | #define HDSPM_midi1IRQPending (1<<31) /* and aktiv */ | 366 | #define HDSPM_tco_lock 0x20000000 |
367 | |||
368 | #define HDSPM_s2_tco_detect 0x00000040 | ||
369 | #define HDSPM_s2_AEBO_D 0x00000080 | ||
370 | #define HDSPM_s2_AEBI_D 0x00000100 | ||
371 | |||
372 | |||
373 | #define HDSPM_midi0IRQPending 0x40000000 | ||
374 | #define HDSPM_midi1IRQPending 0x80000000 | ||
375 | #define HDSPM_midi2IRQPending 0x20000000 | ||
376 | #define HDSPM_midi2IRQPendingAES 0x00000020 | ||
377 | #define HDSPM_midi3IRQPending 0x00200000 | ||
292 | 378 | ||
293 | /* --- status bit helpers */ | 379 | /* --- status bit helpers */ |
294 | #define HDSPM_madiFreqMask (HDSPM_madiFreq0|HDSPM_madiFreq1|\ | 380 | #define HDSPM_madiFreqMask (HDSPM_madiFreq0|HDSPM_madiFreq1|\ |
@@ -317,7 +403,10 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}"); | |||
317 | #define HDSPM_wc_freq2 (1<<7) /* 100=64, 101=88.2, 110=96, */ | 403 | #define HDSPM_wc_freq2 (1<<7) /* 100=64, 101=88.2, 110=96, */ |
318 | /* missing Bit for 111=128, 1000=176.4, 1001=192 */ | 404 | /* missing Bit for 111=128, 1000=176.4, 1001=192 */ |
319 | 405 | ||
320 | #define HDSPM_SelSyncRef0 (1<<8) /* Sync Source in slave mode */ | 406 | #define HDSPM_SyncRef0 0x10000 /* Sync Reference */ |
407 | #define HDSPM_SyncRef1 0x20000 | ||
408 | |||
409 | #define HDSPM_SelSyncRef0 (1<<8) /* AutoSync Source */ | ||
321 | #define HDSPM_SelSyncRef1 (1<<9) /* 000=word, 001=MADI, */ | 410 | #define HDSPM_SelSyncRef1 (1<<9) /* 000=word, 001=MADI, */ |
322 | #define HDSPM_SelSyncRef2 (1<<10) /* 111=no valid signal */ | 411 | #define HDSPM_SelSyncRef2 (1<<10) /* 111=no valid signal */ |
323 | 412 | ||
@@ -331,11 +420,19 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}"); | |||
331 | #define HDSPM_wcFreq88_2 (HDSPM_wc_freq0|HDSPM_wc_freq2) | 420 | #define HDSPM_wcFreq88_2 (HDSPM_wc_freq0|HDSPM_wc_freq2) |
332 | #define HDSPM_wcFreq96 (HDSPM_wc_freq1|HDSPM_wc_freq2) | 421 | #define HDSPM_wcFreq96 (HDSPM_wc_freq1|HDSPM_wc_freq2) |
333 | 422 | ||
423 | #define HDSPM_status1_F_0 0x0400000 | ||
424 | #define HDSPM_status1_F_1 0x0800000 | ||
425 | #define HDSPM_status1_F_2 0x1000000 | ||
426 | #define HDSPM_status1_F_3 0x2000000 | ||
427 | #define HDSPM_status1_freqMask (HDSPM_status1_F_0|HDSPM_status1_F_1|HDSPM_status1_F_2|HDSPM_status1_F_3) | ||
428 | |||
334 | 429 | ||
335 | #define HDSPM_SelSyncRefMask (HDSPM_SelSyncRef0|HDSPM_SelSyncRef1|\ | 430 | #define HDSPM_SelSyncRefMask (HDSPM_SelSyncRef0|HDSPM_SelSyncRef1|\ |
336 | HDSPM_SelSyncRef2) | 431 | HDSPM_SelSyncRef2) |
337 | #define HDSPM_SelSyncRef_WORD 0 | 432 | #define HDSPM_SelSyncRef_WORD 0 |
338 | #define HDSPM_SelSyncRef_MADI (HDSPM_SelSyncRef0) | 433 | #define HDSPM_SelSyncRef_MADI (HDSPM_SelSyncRef0) |
434 | #define HDSPM_SelSyncRef_TCO (HDSPM_SelSyncRef1) | ||
435 | #define HDSPM_SelSyncRef_SyncIn (HDSPM_SelSyncRef0|HDSPM_SelSyncRef1) | ||
339 | #define HDSPM_SelSyncRef_NVALID (HDSPM_SelSyncRef0|HDSPM_SelSyncRef1|\ | 436 | #define HDSPM_SelSyncRef_NVALID (HDSPM_SelSyncRef0|HDSPM_SelSyncRef1|\ |
340 | HDSPM_SelSyncRef2) | 437 | HDSPM_SelSyncRef2) |
341 | 438 | ||
@@ -345,7 +442,7 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}"); | |||
345 | /* status */ | 442 | /* status */ |
346 | #define HDSPM_AES32_wcLock 0x0200000 | 443 | #define HDSPM_AES32_wcLock 0x0200000 |
347 | #define HDSPM_AES32_wcFreq_bit 22 | 444 | #define HDSPM_AES32_wcFreq_bit 22 |
348 | /* (status >> HDSPM_AES32_wcFreq_bit) & 0xF gives WC frequency (cf function | 445 | /* (status >> HDSPM_AES32_wcFreq_bit) & 0xF gives WC frequency (cf function |
349 | HDSPM_bit2freq */ | 446 | HDSPM_bit2freq */ |
350 | #define HDSPM_AES32_syncref_bit 16 | 447 | #define HDSPM_AES32_syncref_bit 16 |
351 | /* (status >> HDSPM_AES32_syncref_bit) & 0xF gives sync source */ | 448 | /* (status >> HDSPM_AES32_syncref_bit) & 0xF gives sync source */ |
@@ -398,28 +495,348 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}"); | |||
398 | #define MADI_DS_CHANNELS 32 | 495 | #define MADI_DS_CHANNELS 32 |
399 | #define MADI_QS_CHANNELS 16 | 496 | #define MADI_QS_CHANNELS 16 |
400 | 497 | ||
498 | #define RAYDAT_SS_CHANNELS 36 | ||
499 | #define RAYDAT_DS_CHANNELS 20 | ||
500 | #define RAYDAT_QS_CHANNELS 12 | ||
501 | |||
502 | #define AIO_IN_SS_CHANNELS 14 | ||
503 | #define AIO_IN_DS_CHANNELS 10 | ||
504 | #define AIO_IN_QS_CHANNELS 8 | ||
505 | #define AIO_OUT_SS_CHANNELS 16 | ||
506 | #define AIO_OUT_DS_CHANNELS 12 | ||
507 | #define AIO_OUT_QS_CHANNELS 10 | ||
508 | |||
509 | #define AES32_CHANNELS 16 | ||
510 | |||
401 | /* the size of a substream (1 mono data stream) */ | 511 | /* the size of a substream (1 mono data stream) */ |
402 | #define HDSPM_CHANNEL_BUFFER_SAMPLES (16*1024) | 512 | #define HDSPM_CHANNEL_BUFFER_SAMPLES (16*1024) |
403 | #define HDSPM_CHANNEL_BUFFER_BYTES (4*HDSPM_CHANNEL_BUFFER_SAMPLES) | 513 | #define HDSPM_CHANNEL_BUFFER_BYTES (4*HDSPM_CHANNEL_BUFFER_SAMPLES) |
404 | 514 | ||
405 | /* the size of the area we need to allocate for DMA transfers. the | 515 | /* the size of the area we need to allocate for DMA transfers. the |
406 | size is the same regardless of the number of channels, and | 516 | size is the same regardless of the number of channels, and |
407 | also the latency to use. | 517 | also the latency to use. |
408 | for one direction !!! | 518 | for one direction !!! |
409 | */ | 519 | */ |
410 | #define HDSPM_DMA_AREA_BYTES (HDSPM_MAX_CHANNELS * HDSPM_CHANNEL_BUFFER_BYTES) | 520 | #define HDSPM_DMA_AREA_BYTES (HDSPM_MAX_CHANNELS * HDSPM_CHANNEL_BUFFER_BYTES) |
411 | #define HDSPM_DMA_AREA_KILOBYTES (HDSPM_DMA_AREA_BYTES/1024) | 521 | #define HDSPM_DMA_AREA_KILOBYTES (HDSPM_DMA_AREA_BYTES/1024) |
412 | 522 | ||
413 | /* revisions >= 230 indicate AES32 card */ | 523 | /* revisions >= 230 indicate AES32 card */ |
414 | #define HDSPM_AESREVISION 230 | 524 | #define HDSPM_MADI_REV 210 |
525 | #define HDSPM_RAYDAT_REV 211 | ||
526 | #define HDSPM_AIO_REV 212 | ||
527 | #define HDSPM_MADIFACE_REV 213 | ||
528 | #define HDSPM_AES_REV 240 | ||
529 | #define HDSPM_AES32_REV 234 | ||
530 | #define HDSPM_AES32_OLD_REV 233 | ||
415 | 531 | ||
416 | /* speed factor modes */ | 532 | /* speed factor modes */ |
417 | #define HDSPM_SPEED_SINGLE 0 | 533 | #define HDSPM_SPEED_SINGLE 0 |
418 | #define HDSPM_SPEED_DOUBLE 1 | 534 | #define HDSPM_SPEED_DOUBLE 1 |
419 | #define HDSPM_SPEED_QUAD 2 | 535 | #define HDSPM_SPEED_QUAD 2 |
536 | |||
420 | /* names for speed modes */ | 537 | /* names for speed modes */ |
421 | static char *hdspm_speed_names[] = { "single", "double", "quad" }; | 538 | static char *hdspm_speed_names[] = { "single", "double", "quad" }; |
422 | 539 | ||
540 | static char *texts_autosync_aes_tco[] = { "Word Clock", | ||
541 | "AES1", "AES2", "AES3", "AES4", | ||
542 | "AES5", "AES6", "AES7", "AES8", | ||
543 | "TCO" }; | ||
544 | static char *texts_autosync_aes[] = { "Word Clock", | ||
545 | "AES1", "AES2", "AES3", "AES4", | ||
546 | "AES5", "AES6", "AES7", "AES8" }; | ||
547 | static char *texts_autosync_madi_tco[] = { "Word Clock", | ||
548 | "MADI", "TCO", "Sync In" }; | ||
549 | static char *texts_autosync_madi[] = { "Word Clock", | ||
550 | "MADI", "Sync In" }; | ||
551 | |||
552 | static char *texts_autosync_raydat_tco[] = { | ||
553 | "Word Clock", | ||
554 | "ADAT 1", "ADAT 2", "ADAT 3", "ADAT 4", | ||
555 | "AES", "SPDIF", "TCO", "Sync In" | ||
556 | }; | ||
557 | static char *texts_autosync_raydat[] = { | ||
558 | "Word Clock", | ||
559 | "ADAT 1", "ADAT 2", "ADAT 3", "ADAT 4", | ||
560 | "AES", "SPDIF", "Sync In" | ||
561 | }; | ||
562 | static char *texts_autosync_aio_tco[] = { | ||
563 | "Word Clock", | ||
564 | "ADAT", "AES", "SPDIF", "TCO", "Sync In" | ||
565 | }; | ||
566 | static char *texts_autosync_aio[] = { "Word Clock", | ||
567 | "ADAT", "AES", "SPDIF", "Sync In" }; | ||
568 | |||
569 | static char *texts_freq[] = { | ||
570 | "No Lock", | ||
571 | "32 kHz", | ||
572 | "44.1 kHz", | ||
573 | "48 kHz", | ||
574 | "64 kHz", | ||
575 | "88.2 kHz", | ||
576 | "96 kHz", | ||
577 | "128 kHz", | ||
578 | "176.4 kHz", | ||
579 | "192 kHz" | ||
580 | }; | ||
581 | |||
582 | static char *texts_ports_madi[] = { | ||
583 | "MADI.1", "MADI.2", "MADI.3", "MADI.4", "MADI.5", "MADI.6", | ||
584 | "MADI.7", "MADI.8", "MADI.9", "MADI.10", "MADI.11", "MADI.12", | ||
585 | "MADI.13", "MADI.14", "MADI.15", "MADI.16", "MADI.17", "MADI.18", | ||
586 | "MADI.19", "MADI.20", "MADI.21", "MADI.22", "MADI.23", "MADI.24", | ||
587 | "MADI.25", "MADI.26", "MADI.27", "MADI.28", "MADI.29", "MADI.30", | ||
588 | "MADI.31", "MADI.32", "MADI.33", "MADI.34", "MADI.35", "MADI.36", | ||
589 | "MADI.37", "MADI.38", "MADI.39", "MADI.40", "MADI.41", "MADI.42", | ||
590 | "MADI.43", "MADI.44", "MADI.45", "MADI.46", "MADI.47", "MADI.48", | ||
591 | "MADI.49", "MADI.50", "MADI.51", "MADI.52", "MADI.53", "MADI.54", | ||
592 | "MADI.55", "MADI.56", "MADI.57", "MADI.58", "MADI.59", "MADI.60", | ||
593 | "MADI.61", "MADI.62", "MADI.63", "MADI.64", | ||
594 | }; | ||
595 | |||
596 | |||
597 | static char *texts_ports_raydat_ss[] = { | ||
598 | "ADAT1.1", "ADAT1.2", "ADAT1.3", "ADAT1.4", "ADAT1.5", "ADAT1.6", | ||
599 | "ADAT1.7", "ADAT1.8", "ADAT2.1", "ADAT2.2", "ADAT2.3", "ADAT2.4", | ||
600 | "ADAT2.5", "ADAT2.6", "ADAT2.7", "ADAT2.8", "ADAT3.1", "ADAT3.2", | ||
601 | "ADAT3.3", "ADAT3.4", "ADAT3.5", "ADAT3.6", "ADAT3.7", "ADAT3.8", | ||
602 | "ADAT4.1", "ADAT4.2", "ADAT4.3", "ADAT4.4", "ADAT4.5", "ADAT4.6", | ||
603 | "ADAT4.7", "ADAT4.8", | ||
604 | "AES.L", "AES.R", | ||
605 | "SPDIF.L", "SPDIF.R" | ||
606 | }; | ||
607 | |||
608 | static char *texts_ports_raydat_ds[] = { | ||
609 | "ADAT1.1", "ADAT1.2", "ADAT1.3", "ADAT1.4", | ||
610 | "ADAT2.1", "ADAT2.2", "ADAT2.3", "ADAT2.4", | ||
611 | "ADAT3.1", "ADAT3.2", "ADAT3.3", "ADAT3.4", | ||
612 | "ADAT4.1", "ADAT4.2", "ADAT4.3", "ADAT4.4", | ||
613 | "AES.L", "AES.R", | ||
614 | "SPDIF.L", "SPDIF.R" | ||
615 | }; | ||
616 | |||
617 | static char *texts_ports_raydat_qs[] = { | ||
618 | "ADAT1.1", "ADAT1.2", | ||
619 | "ADAT2.1", "ADAT2.2", | ||
620 | "ADAT3.1", "ADAT3.2", | ||
621 | "ADAT4.1", "ADAT4.2", | ||
622 | "AES.L", "AES.R", | ||
623 | "SPDIF.L", "SPDIF.R" | ||
624 | }; | ||
625 | |||
626 | |||
627 | static char *texts_ports_aio_in_ss[] = { | ||
628 | "Analogue.L", "Analogue.R", | ||
629 | "AES.L", "AES.R", | ||
630 | "SPDIF.L", "SPDIF.R", | ||
631 | "ADAT.1", "ADAT.2", "ADAT.3", "ADAT.4", "ADAT.5", "ADAT.6", | ||
632 | "ADAT.7", "ADAT.8" | ||
633 | }; | ||
634 | |||
635 | static char *texts_ports_aio_out_ss[] = { | ||
636 | "Analogue.L", "Analogue.R", | ||
637 | "AES.L", "AES.R", | ||
638 | "SPDIF.L", "SPDIF.R", | ||
639 | "ADAT.1", "ADAT.2", "ADAT.3", "ADAT.4", "ADAT.5", "ADAT.6", | ||
640 | "ADAT.7", "ADAT.8", | ||
641 | "Phone.L", "Phone.R" | ||
642 | }; | ||
643 | |||
644 | static char *texts_ports_aio_in_ds[] = { | ||
645 | "Analogue.L", "Analogue.R", | ||
646 | "AES.L", "AES.R", | ||
647 | "SPDIF.L", "SPDIF.R", | ||
648 | "ADAT.1", "ADAT.2", "ADAT.3", "ADAT.4" | ||
649 | }; | ||
650 | |||
651 | static char *texts_ports_aio_out_ds[] = { | ||
652 | "Analogue.L", "Analogue.R", | ||
653 | "AES.L", "AES.R", | ||
654 | "SPDIF.L", "SPDIF.R", | ||
655 | "ADAT.1", "ADAT.2", "ADAT.3", "ADAT.4", | ||
656 | "Phone.L", "Phone.R" | ||
657 | }; | ||
658 | |||
659 | static char *texts_ports_aio_in_qs[] = { | ||
660 | "Analogue.L", "Analogue.R", | ||
661 | "AES.L", "AES.R", | ||
662 | "SPDIF.L", "SPDIF.R", | ||
663 | "ADAT.1", "ADAT.2", "ADAT.3", "ADAT.4" | ||
664 | }; | ||
665 | |||
666 | static char *texts_ports_aio_out_qs[] = { | ||
667 | "Analogue.L", "Analogue.R", | ||
668 | "AES.L", "AES.R", | ||
669 | "SPDIF.L", "SPDIF.R", | ||
670 | "ADAT.1", "ADAT.2", "ADAT.3", "ADAT.4", | ||
671 | "Phone.L", "Phone.R" | ||
672 | }; | ||
673 | |||
674 | static char *texts_ports_aes32[] = { | ||
675 | "AES.1", "AES.2", "AES.3", "AES.4", "AES.5", "AES.6", "AES.7", | ||
676 | "AES.8", "AES.9.", "AES.10", "AES.11", "AES.12", "AES.13", "AES.14", | ||
677 | "AES.15", "AES.16" | ||
678 | }; | ||
679 | |||
680 | /* These tables map the ALSA channels 1..N to the channels that we | ||
681 | need to use in order to find the relevant channel buffer. RME | ||
682 | refers to this kind of mapping as between "the ADAT channel and | ||
683 | the DMA channel." We index it using the logical audio channel, | ||
684 | and the value is the DMA channel (i.e. channel buffer number) | ||
685 | where the data for that channel can be read/written from/to. | ||
686 | */ | ||
687 | |||
688 | static char channel_map_unity_ss[HDSPM_MAX_CHANNELS] = { | ||
689 | 0, 1, 2, 3, 4, 5, 6, 7, | ||
690 | 8, 9, 10, 11, 12, 13, 14, 15, | ||
691 | 16, 17, 18, 19, 20, 21, 22, 23, | ||
692 | 24, 25, 26, 27, 28, 29, 30, 31, | ||
693 | 32, 33, 34, 35, 36, 37, 38, 39, | ||
694 | 40, 41, 42, 43, 44, 45, 46, 47, | ||
695 | 48, 49, 50, 51, 52, 53, 54, 55, | ||
696 | 56, 57, 58, 59, 60, 61, 62, 63 | ||
697 | }; | ||
698 | |||
699 | static char channel_map_raydat_ss[HDSPM_MAX_CHANNELS] = { | ||
700 | 4, 5, 6, 7, 8, 9, 10, 11, /* ADAT 1 */ | ||
701 | 12, 13, 14, 15, 16, 17, 18, 19, /* ADAT 2 */ | ||
702 | 20, 21, 22, 23, 24, 25, 26, 27, /* ADAT 3 */ | ||
703 | 28, 29, 30, 31, 32, 33, 34, 35, /* ADAT 4 */ | ||
704 | 0, 1, /* AES */ | ||
705 | 2, 3, /* SPDIF */ | ||
706 | -1, -1, -1, -1, | ||
707 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
708 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
709 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
710 | }; | ||
711 | |||
712 | static char channel_map_raydat_ds[HDSPM_MAX_CHANNELS] = { | ||
713 | 4, 5, 6, 7, /* ADAT 1 */ | ||
714 | 8, 9, 10, 11, /* ADAT 2 */ | ||
715 | 12, 13, 14, 15, /* ADAT 3 */ | ||
716 | 16, 17, 18, 19, /* ADAT 4 */ | ||
717 | 0, 1, /* AES */ | ||
718 | 2, 3, /* SPDIF */ | ||
719 | -1, -1, -1, -1, | ||
720 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
721 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
722 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
723 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
724 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
725 | }; | ||
726 | |||
727 | static char channel_map_raydat_qs[HDSPM_MAX_CHANNELS] = { | ||
728 | 4, 5, /* ADAT 1 */ | ||
729 | 6, 7, /* ADAT 2 */ | ||
730 | 8, 9, /* ADAT 3 */ | ||
731 | 10, 11, /* ADAT 4 */ | ||
732 | 0, 1, /* AES */ | ||
733 | 2, 3, /* SPDIF */ | ||
734 | -1, -1, -1, -1, | ||
735 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
736 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
737 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
738 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
739 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
740 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
741 | }; | ||
742 | |||
743 | static char channel_map_aio_in_ss[HDSPM_MAX_CHANNELS] = { | ||
744 | 0, 1, /* line in */ | ||
745 | 8, 9, /* aes in, */ | ||
746 | 10, 11, /* spdif in */ | ||
747 | 12, 13, 14, 15, 16, 17, 18, 19, /* ADAT in */ | ||
748 | -1, -1, | ||
749 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
750 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
751 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
752 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
753 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
754 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
755 | }; | ||
756 | |||
757 | static char channel_map_aio_out_ss[HDSPM_MAX_CHANNELS] = { | ||
758 | 0, 1, /* line out */ | ||
759 | 8, 9, /* aes out */ | ||
760 | 10, 11, /* spdif out */ | ||
761 | 12, 13, 14, 15, 16, 17, 18, 19, /* ADAT out */ | ||
762 | 6, 7, /* phone out */ | ||
763 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
764 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
765 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
766 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
767 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
768 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
769 | }; | ||
770 | |||
771 | static char channel_map_aio_in_ds[HDSPM_MAX_CHANNELS] = { | ||
772 | 0, 1, /* line in */ | ||
773 | 8, 9, /* aes in */ | ||
774 | 10, 11, /* spdif in */ | ||
775 | 12, 14, 16, 18, /* adat in */ | ||
776 | -1, -1, -1, -1, -1, -1, | ||
777 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
778 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
779 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
780 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
781 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
782 | -1, -1, -1, -1, -1, -1, -1, -1 | ||
783 | }; | ||
784 | |||
785 | static char channel_map_aio_out_ds[HDSPM_MAX_CHANNELS] = { | ||
786 | 0, 1, /* line out */ | ||
787 | 8, 9, /* aes out */ | ||
788 | 10, 11, /* spdif out */ | ||
789 | 12, 14, 16, 18, /* adat out */ | ||
790 | 6, 7, /* phone out */ | ||
791 | -1, -1, -1, -1, | ||
792 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
793 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
794 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
795 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
796 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
797 | -1, -1, -1, -1, -1, -1, -1, -1 | ||
798 | }; | ||
799 | |||
800 | static char channel_map_aio_in_qs[HDSPM_MAX_CHANNELS] = { | ||
801 | 0, 1, /* line in */ | ||
802 | 8, 9, /* aes in */ | ||
803 | 10, 11, /* spdif in */ | ||
804 | 12, 16, /* adat in */ | ||
805 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
806 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
807 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
808 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
809 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
810 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
811 | -1, -1, -1, -1, -1, -1, -1, -1 | ||
812 | }; | ||
813 | |||
814 | static char channel_map_aio_out_qs[HDSPM_MAX_CHANNELS] = { | ||
815 | 0, 1, /* line out */ | ||
816 | 8, 9, /* aes out */ | ||
817 | 10, 11, /* spdif out */ | ||
818 | 12, 16, /* adat out */ | ||
819 | 6, 7, /* phone out */ | ||
820 | -1, -1, -1, -1, -1, -1, | ||
821 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
822 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
823 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
824 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
825 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
826 | -1, -1, -1, -1, -1, -1, -1, -1 | ||
827 | }; | ||
828 | |||
829 | static char channel_map_aes32[HDSPM_MAX_CHANNELS] = { | ||
830 | 0, 1, 2, 3, 4, 5, 6, 7, | ||
831 | 8, 9, 10, 11, 12, 13, 14, 15, | ||
832 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
833 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
834 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
835 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
836 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
837 | -1, -1, -1, -1, -1, -1, -1, -1 | ||
838 | }; | ||
839 | |||
423 | struct hdspm_midi { | 840 | struct hdspm_midi { |
424 | struct hdspm *hdspm; | 841 | struct hdspm *hdspm; |
425 | int id; | 842 | int id; |
@@ -430,6 +847,21 @@ struct hdspm_midi { | |||
430 | struct timer_list timer; | 847 | struct timer_list timer; |
431 | spinlock_t lock; | 848 | spinlock_t lock; |
432 | int pending; | 849 | int pending; |
850 | int dataIn; | ||
851 | int statusIn; | ||
852 | int dataOut; | ||
853 | int statusOut; | ||
854 | int ie; | ||
855 | int irq; | ||
856 | }; | ||
857 | |||
858 | struct hdspm_tco { | ||
859 | int input; | ||
860 | int framerate; | ||
861 | int wordclock; | ||
862 | int samplerate; | ||
863 | int pull; | ||
864 | int term; /* 0 = off, 1 = on */ | ||
433 | }; | 865 | }; |
434 | 866 | ||
435 | struct hdspm { | 867 | struct hdspm { |
@@ -441,21 +873,39 @@ struct hdspm { | |||
441 | char *card_name; /* for procinfo */ | 873 | char *card_name; /* for procinfo */ |
442 | unsigned short firmware_rev; /* dont know if relevant (yes if AES32)*/ | 874 | unsigned short firmware_rev; /* dont know if relevant (yes if AES32)*/ |
443 | 875 | ||
444 | unsigned char is_aes32; /* indicates if card is AES32 */ | 876 | uint8_t io_type; |
445 | 877 | ||
446 | int precise_ptr; /* use precise pointers, to be tested */ | ||
447 | int monitor_outs; /* set up monitoring outs init flag */ | 878 | int monitor_outs; /* set up monitoring outs init flag */ |
448 | 879 | ||
449 | u32 control_register; /* cached value */ | 880 | u32 control_register; /* cached value */ |
450 | u32 control2_register; /* cached value */ | 881 | u32 control2_register; /* cached value */ |
882 | u32 settings_register; | ||
451 | 883 | ||
452 | struct hdspm_midi midi[2]; | 884 | struct hdspm_midi midi[4]; |
453 | struct tasklet_struct midi_tasklet; | 885 | struct tasklet_struct midi_tasklet; |
454 | 886 | ||
455 | size_t period_bytes; | 887 | size_t period_bytes; |
456 | unsigned char ss_channels; /* channels of card in single speed */ | 888 | unsigned char ss_in_channels; |
457 | unsigned char ds_channels; /* Double Speed */ | 889 | unsigned char ds_in_channels; |
458 | unsigned char qs_channels; /* Quad Speed */ | 890 | unsigned char qs_in_channels; |
891 | unsigned char ss_out_channels; | ||
892 | unsigned char ds_out_channels; | ||
893 | unsigned char qs_out_channels; | ||
894 | |||
895 | unsigned char max_channels_in; | ||
896 | unsigned char max_channels_out; | ||
897 | |||
898 | char *channel_map_in; | ||
899 | char *channel_map_out; | ||
900 | |||
901 | char *channel_map_in_ss, *channel_map_in_ds, *channel_map_in_qs; | ||
902 | char *channel_map_out_ss, *channel_map_out_ds, *channel_map_out_qs; | ||
903 | |||
904 | char **port_names_in; | ||
905 | char **port_names_out; | ||
906 | |||
907 | char **port_names_in_ss, **port_names_in_ds, **port_names_in_qs; | ||
908 | char **port_names_out_ss, **port_names_out_ds, **port_names_out_qs; | ||
459 | 909 | ||
460 | unsigned char *playback_buffer; /* suitably aligned address */ | 910 | unsigned char *playback_buffer; /* suitably aligned address */ |
461 | unsigned char *capture_buffer; /* suitably aligned address */ | 911 | unsigned char *capture_buffer; /* suitably aligned address */ |
@@ -468,14 +918,13 @@ struct hdspm { | |||
468 | int last_internal_sample_rate; | 918 | int last_internal_sample_rate; |
469 | int system_sample_rate; | 919 | int system_sample_rate; |
470 | 920 | ||
471 | char *channel_map; /* channel map for DS and Quadspeed */ | ||
472 | |||
473 | int dev; /* Hardware vars... */ | 921 | int dev; /* Hardware vars... */ |
474 | int irq; | 922 | int irq; |
475 | unsigned long port; | 923 | unsigned long port; |
476 | void __iomem *iobase; | 924 | void __iomem *iobase; |
477 | 925 | ||
478 | int irq_count; /* for debug */ | 926 | int irq_count; /* for debug */ |
927 | int midiPorts; | ||
479 | 928 | ||
480 | struct snd_card *card; /* one card */ | 929 | struct snd_card *card; /* one card */ |
481 | struct snd_pcm *pcm; /* has one pcm */ | 930 | struct snd_pcm *pcm; /* has one pcm */ |
@@ -487,28 +936,17 @@ struct hdspm { | |||
487 | struct snd_kcontrol *playback_mixer_ctls[HDSPM_MAX_CHANNELS]; | 936 | struct snd_kcontrol *playback_mixer_ctls[HDSPM_MAX_CHANNELS]; |
488 | /* but input to much, so not used */ | 937 | /* but input to much, so not used */ |
489 | struct snd_kcontrol *input_mixer_ctls[HDSPM_MAX_CHANNELS]; | 938 | struct snd_kcontrol *input_mixer_ctls[HDSPM_MAX_CHANNELS]; |
490 | /* full mixer accessible over mixer ioctl or hwdep-device */ | 939 | /* full mixer accessable over mixer ioctl or hwdep-device */ |
491 | struct hdspm_mixer *mixer; | 940 | struct hdspm_mixer *mixer; |
492 | 941 | ||
493 | }; | 942 | struct hdspm_tco *tco; /* NULL if no TCO detected */ |
494 | 943 | ||
495 | /* These tables map the ALSA channels 1..N to the channels that we | 944 | char **texts_autosync; |
496 | need to use in order to find the relevant channel buffer. RME | 945 | int texts_autosync_items; |
497 | refer to this kind of mapping as between "the ADAT channel and | 946 | |
498 | the DMA channel." We index it using the logical audio channel, | 947 | cycles_t last_interrupt; |
499 | and the value is the DMA channel (i.e. channel buffer number) | ||
500 | where the data for that channel can be read/written from/to. | ||
501 | */ | ||
502 | 948 | ||
503 | static char channel_map_madi_ss[HDSPM_MAX_CHANNELS] = { | 949 | struct hdspm_peak_rms peak_rms; |
504 | 0, 1, 2, 3, 4, 5, 6, 7, | ||
505 | 8, 9, 10, 11, 12, 13, 14, 15, | ||
506 | 16, 17, 18, 19, 20, 21, 22, 23, | ||
507 | 24, 25, 26, 27, 28, 29, 30, 31, | ||
508 | 32, 33, 34, 35, 36, 37, 38, 39, | ||
509 | 40, 41, 42, 43, 44, 45, 46, 47, | ||
510 | 48, 49, 50, 51, 52, 53, 54, 55, | ||
511 | 56, 57, 58, 59, 60, 61, 62, 63 | ||
512 | }; | 950 | }; |
513 | 951 | ||
514 | 952 | ||
@@ -532,11 +970,11 @@ static int __devinit snd_hdspm_create_alsa_devices(struct snd_card *card, | |||
532 | static int __devinit snd_hdspm_create_pcm(struct snd_card *card, | 970 | static int __devinit snd_hdspm_create_pcm(struct snd_card *card, |
533 | struct hdspm * hdspm); | 971 | struct hdspm * hdspm); |
534 | 972 | ||
535 | static inline void snd_hdspm_initialize_midi_flush(struct hdspm * hdspm); | 973 | static inline void snd_hdspm_initialize_midi_flush(struct hdspm *hdspm); |
536 | static int hdspm_update_simple_mixer_controls(struct hdspm * hdspm); | 974 | static int hdspm_update_simple_mixer_controls(struct hdspm *hdspm); |
537 | static int hdspm_autosync_ref(struct hdspm * hdspm); | 975 | static int hdspm_autosync_ref(struct hdspm *hdspm); |
538 | static int snd_hdspm_set_defaults(struct hdspm * hdspm); | 976 | static int snd_hdspm_set_defaults(struct hdspm *hdspm); |
539 | static void hdspm_set_sgbuf(struct hdspm * hdspm, | 977 | static void hdspm_set_sgbuf(struct hdspm *hdspm, |
540 | struct snd_pcm_substream *substream, | 978 | struct snd_pcm_substream *substream, |
541 | unsigned int reg, int channels); | 979 | unsigned int reg, int channels); |
542 | 980 | ||
@@ -550,7 +988,7 @@ static inline int HDSPM_bit2freq(int n) | |||
550 | return bit2freq_tab[n]; | 988 | return bit2freq_tab[n]; |
551 | } | 989 | } |
552 | 990 | ||
553 | /* Write/read to/from HDSPM with Addresses in Bytes | 991 | /* Write/read to/from HDSPM with Adresses in Bytes |
554 | not words but only 32Bit writes are allowed */ | 992 | not words but only 32Bit writes are allowed */ |
555 | 993 | ||
556 | static inline void hdspm_write(struct hdspm * hdspm, unsigned int reg, | 994 | static inline void hdspm_write(struct hdspm * hdspm, unsigned int reg, |
@@ -564,8 +1002,8 @@ static inline unsigned int hdspm_read(struct hdspm * hdspm, unsigned int reg) | |||
564 | return readl(hdspm->iobase + reg); | 1002 | return readl(hdspm->iobase + reg); |
565 | } | 1003 | } |
566 | 1004 | ||
567 | /* for each output channel (chan) I have an Input (in) and Playback (pb) Fader | 1005 | /* for each output channel (chan) I have an Input (in) and Playback (pb) Fader |
568 | mixer is write only on hardware so we have to cache him for read | 1006 | mixer is write only on hardware so we have to cache him for read |
569 | each fader is a u32, but uses only the first 16 bit */ | 1007 | each fader is a u32, but uses only the first 16 bit */ |
570 | 1008 | ||
571 | static inline int hdspm_read_in_gain(struct hdspm * hdspm, unsigned int chan, | 1009 | static inline int hdspm_read_in_gain(struct hdspm * hdspm, unsigned int chan, |
@@ -641,30 +1079,67 @@ static int snd_hdspm_use_is_exclusive(struct hdspm *hdspm) | |||
641 | /* check for external sample rate */ | 1079 | /* check for external sample rate */ |
642 | static int hdspm_external_sample_rate(struct hdspm *hdspm) | 1080 | static int hdspm_external_sample_rate(struct hdspm *hdspm) |
643 | { | 1081 | { |
644 | if (hdspm->is_aes32) { | 1082 | unsigned int status, status2, timecode; |
645 | unsigned int status2 = hdspm_read(hdspm, HDSPM_statusRegister2); | 1083 | int syncref, rate = 0, rate_bits; |
646 | unsigned int status = hdspm_read(hdspm, HDSPM_statusRegister); | ||
647 | unsigned int timecode = | ||
648 | hdspm_read(hdspm, HDSPM_timecodeRegister); | ||
649 | 1084 | ||
650 | int syncref = hdspm_autosync_ref(hdspm); | 1085 | switch (hdspm->io_type) { |
1086 | case AES32: | ||
1087 | status2 = hdspm_read(hdspm, HDSPM_statusRegister2); | ||
1088 | status = hdspm_read(hdspm, HDSPM_statusRegister); | ||
1089 | timecode = hdspm_read(hdspm, HDSPM_timecodeRegister); | ||
1090 | |||
1091 | syncref = hdspm_autosync_ref(hdspm); | ||
651 | 1092 | ||
652 | if (syncref == HDSPM_AES32_AUTOSYNC_FROM_WORD && | 1093 | if (syncref == HDSPM_AES32_AUTOSYNC_FROM_WORD && |
653 | status & HDSPM_AES32_wcLock) | 1094 | status & HDSPM_AES32_wcLock) |
654 | return HDSPM_bit2freq((status >> HDSPM_AES32_wcFreq_bit) | 1095 | return HDSPM_bit2freq((status >> HDSPM_AES32_wcFreq_bit) & 0xF); |
655 | & 0xF); | 1096 | |
656 | if (syncref >= HDSPM_AES32_AUTOSYNC_FROM_AES1 && | 1097 | if (syncref >= HDSPM_AES32_AUTOSYNC_FROM_AES1 && |
657 | syncref <= HDSPM_AES32_AUTOSYNC_FROM_AES8 && | 1098 | syncref <= HDSPM_AES32_AUTOSYNC_FROM_AES8 && |
658 | status2 & (HDSPM_LockAES >> | 1099 | status2 & (HDSPM_LockAES >> |
659 | (syncref - HDSPM_AES32_AUTOSYNC_FROM_AES1))) | 1100 | (syncref - HDSPM_AES32_AUTOSYNC_FROM_AES1))) |
660 | return HDSPM_bit2freq((timecode >> | 1101 | return HDSPM_bit2freq((timecode >> (4*(syncref-HDSPM_AES32_AUTOSYNC_FROM_AES1))) & 0xF); |
661 | (4*(syncref-HDSPM_AES32_AUTOSYNC_FROM_AES1))) & 0xF); | ||
662 | return 0; | 1102 | return 0; |
663 | } else { | 1103 | break; |
664 | unsigned int status2 = hdspm_read(hdspm, HDSPM_statusRegister2); | 1104 | |
665 | unsigned int status = hdspm_read(hdspm, HDSPM_statusRegister); | 1105 | case MADIface: |
666 | unsigned int rate_bits; | 1106 | status = hdspm_read(hdspm, HDSPM_statusRegister); |
667 | int rate = 0; | 1107 | |
1108 | if (!(status & HDSPM_madiLock)) { | ||
1109 | rate = 0; /* no lock */ | ||
1110 | } else { | ||
1111 | switch (status & (HDSPM_status1_freqMask)) { | ||
1112 | case HDSPM_status1_F_0*1: | ||
1113 | rate = 32000; break; | ||
1114 | case HDSPM_status1_F_0*2: | ||
1115 | rate = 44100; break; | ||
1116 | case HDSPM_status1_F_0*3: | ||
1117 | rate = 48000; break; | ||
1118 | case HDSPM_status1_F_0*4: | ||
1119 | rate = 64000; break; | ||
1120 | case HDSPM_status1_F_0*5: | ||
1121 | rate = 88200; break; | ||
1122 | case HDSPM_status1_F_0*6: | ||
1123 | rate = 96000; break; | ||
1124 | case HDSPM_status1_F_0*7: | ||
1125 | rate = 128000; break; | ||
1126 | case HDSPM_status1_F_0*8: | ||
1127 | rate = 176400; break; | ||
1128 | case HDSPM_status1_F_0*9: | ||
1129 | rate = 192000; break; | ||
1130 | default: | ||
1131 | rate = 0; break; | ||
1132 | } | ||
1133 | } | ||
1134 | |||
1135 | break; | ||
1136 | |||
1137 | case MADI: | ||
1138 | case AIO: | ||
1139 | case RayDAT: | ||
1140 | status2 = hdspm_read(hdspm, HDSPM_statusRegister2); | ||
1141 | status = hdspm_read(hdspm, HDSPM_statusRegister); | ||
1142 | rate = 0; | ||
668 | 1143 | ||
669 | /* if wordclock has synced freq and wordclock is valid */ | 1144 | /* if wordclock has synced freq and wordclock is valid */ |
670 | if ((status2 & HDSPM_wcLock) != 0 && | 1145 | if ((status2 & HDSPM_wcLock) != 0 && |
@@ -672,6 +1147,7 @@ static int hdspm_external_sample_rate(struct hdspm *hdspm) | |||
672 | 1147 | ||
673 | rate_bits = status2 & HDSPM_wcFreqMask; | 1148 | rate_bits = status2 & HDSPM_wcFreqMask; |
674 | 1149 | ||
1150 | |||
675 | switch (rate_bits) { | 1151 | switch (rate_bits) { |
676 | case HDSPM_wcFreq32: | 1152 | case HDSPM_wcFreq32: |
677 | rate = 32000; | 1153 | rate = 32000; |
@@ -691,7 +1167,6 @@ static int hdspm_external_sample_rate(struct hdspm *hdspm) | |||
691 | case HDSPM_wcFreq96: | 1167 | case HDSPM_wcFreq96: |
692 | rate = 96000; | 1168 | rate = 96000; |
693 | break; | 1169 | break; |
694 | /* Quadspeed Bit missing ???? */ | ||
695 | default: | 1170 | default: |
696 | rate = 0; | 1171 | rate = 0; |
697 | break; | 1172 | break; |
@@ -702,10 +1177,10 @@ static int hdspm_external_sample_rate(struct hdspm *hdspm) | |||
702 | * word has priority to MADI | 1177 | * word has priority to MADI |
703 | */ | 1178 | */ |
704 | if (rate != 0 && | 1179 | if (rate != 0 && |
705 | (status2 & HDSPM_SelSyncRefMask) == HDSPM_SelSyncRef_WORD) | 1180 | (status2 & HDSPM_SelSyncRefMask) == HDSPM_SelSyncRef_WORD) |
706 | return rate; | 1181 | return rate; |
707 | 1182 | ||
708 | /* maby a madi input (which is taken if sel sync is madi) */ | 1183 | /* maybe a madi input (which is taken if sel sync is madi) */ |
709 | if (status & HDSPM_madiLock) { | 1184 | if (status & HDSPM_madiLock) { |
710 | rate_bits = status & HDSPM_madiFreqMask; | 1185 | rate_bits = status & HDSPM_madiFreqMask; |
711 | 1186 | ||
@@ -742,36 +1217,35 @@ static int hdspm_external_sample_rate(struct hdspm *hdspm) | |||
742 | break; | 1217 | break; |
743 | } | 1218 | } |
744 | } | 1219 | } |
745 | return rate; | 1220 | break; |
746 | } | 1221 | } |
1222 | |||
1223 | return rate; | ||
747 | } | 1224 | } |
748 | 1225 | ||
749 | /* Latency function */ | 1226 | /* Latency function */ |
750 | static inline void hdspm_compute_period_size(struct hdspm * hdspm) | 1227 | static inline void hdspm_compute_period_size(struct hdspm *hdspm) |
751 | { | 1228 | { |
752 | hdspm->period_bytes = | 1229 | hdspm->period_bytes = 1 << ((hdspm_decode_latency(hdspm->control_register) + 8)); |
753 | 1 << ((hdspm_decode_latency(hdspm->control_register) + 8)); | ||
754 | } | 1230 | } |
755 | 1231 | ||
756 | static snd_pcm_uframes_t hdspm_hw_pointer(struct hdspm * hdspm) | 1232 | |
1233 | static snd_pcm_uframes_t hdspm_hw_pointer(struct hdspm *hdspm) | ||
757 | { | 1234 | { |
758 | int position; | 1235 | int position; |
759 | 1236 | ||
760 | position = hdspm_read(hdspm, HDSPM_statusRegister); | 1237 | position = hdspm_read(hdspm, HDSPM_statusRegister); |
761 | 1238 | ||
762 | if (!hdspm->precise_ptr) | 1239 | switch (hdspm->io_type) { |
763 | return (position & HDSPM_BufferID) ? | 1240 | case RayDAT: |
1241 | case AIO: | ||
1242 | position &= HDSPM_BufferPositionMask; | ||
1243 | position /= 4; /* Bytes per sample */ | ||
1244 | break; | ||
1245 | default: | ||
1246 | position = (position & HDSPM_BufferID) ? | ||
764 | (hdspm->period_bytes / 4) : 0; | 1247 | (hdspm->period_bytes / 4) : 0; |
765 | 1248 | } | |
766 | /* hwpointer comes in bytes and is 64Bytes accurate (by docu since | ||
767 | PCI Burst) | ||
768 | i have experimented that it is at most 64 Byte to much for playing | ||
769 | so substraction of 64 byte should be ok for ALSA, but use it only | ||
770 | for application where you know what you do since if you come to | ||
771 | near with record pointer it can be a disaster */ | ||
772 | |||
773 | position &= HDSPM_BufferPositionMask; | ||
774 | position = ((position - 64) % (2 * hdspm->period_bytes)) / 4; | ||
775 | 1249 | ||
776 | return position; | 1250 | return position; |
777 | } | 1251 | } |
@@ -805,7 +1279,7 @@ static void hdspm_silence_playback(struct hdspm *hdspm) | |||
805 | } | 1279 | } |
806 | } | 1280 | } |
807 | 1281 | ||
808 | static int hdspm_set_interrupt_interval(struct hdspm * s, unsigned int frames) | 1282 | static int hdspm_set_interrupt_interval(struct hdspm *s, unsigned int frames) |
809 | { | 1283 | { |
810 | int n; | 1284 | int n; |
811 | 1285 | ||
@@ -829,21 +1303,53 @@ static int hdspm_set_interrupt_interval(struct hdspm * s, unsigned int frames) | |||
829 | return 0; | 1303 | return 0; |
830 | } | 1304 | } |
831 | 1305 | ||
1306 | static u64 hdspm_calc_dds_value(struct hdspm *hdspm, u64 period) | ||
1307 | { | ||
1308 | u64 freq_const; | ||
1309 | |||
1310 | if (period == 0) | ||
1311 | return 0; | ||
1312 | |||
1313 | switch (hdspm->io_type) { | ||
1314 | case MADI: | ||
1315 | case AES32: | ||
1316 | freq_const = 110069313433624ULL; | ||
1317 | break; | ||
1318 | case RayDAT: | ||
1319 | case AIO: | ||
1320 | freq_const = 104857600000000ULL; | ||
1321 | break; | ||
1322 | case MADIface: | ||
1323 | freq_const = 131072000000000ULL; | ||
1324 | } | ||
1325 | |||
1326 | return div_u64(freq_const, period); | ||
1327 | } | ||
1328 | |||
1329 | |||
832 | static void hdspm_set_dds_value(struct hdspm *hdspm, int rate) | 1330 | static void hdspm_set_dds_value(struct hdspm *hdspm, int rate) |
833 | { | 1331 | { |
834 | u64 n; | 1332 | u64 n; |
835 | 1333 | ||
836 | if (rate >= 112000) | 1334 | if (rate >= 112000) |
837 | rate /= 4; | 1335 | rate /= 4; |
838 | else if (rate >= 56000) | 1336 | else if (rate >= 56000) |
839 | rate /= 2; | 1337 | rate /= 2; |
840 | 1338 | ||
841 | /* RME says n = 104857600000000, but in the windows MADI driver, I see: | 1339 | switch (hdspm->io_type) { |
842 | // return 104857600000000 / rate; // 100 MHz | 1340 | case MADIface: |
843 | return 110100480000000 / rate; // 105 MHz | 1341 | n = 131072000000000ULL; /* 125 MHz */ |
844 | */ | 1342 | break; |
845 | /* n = 104857600000000ULL; */ /* = 2^20 * 10^8 */ | 1343 | case MADI: |
846 | n = 110100480000000ULL; /* Value checked for AES32 and MADI */ | 1344 | case AES32: |
1345 | n = 110069313433624ULL; /* 105 MHz */ | ||
1346 | break; | ||
1347 | case RayDAT: | ||
1348 | case AIO: | ||
1349 | n = 104857600000000ULL; /* 100 MHz */ | ||
1350 | break; | ||
1351 | } | ||
1352 | |||
847 | n = div_u64(n, rate); | 1353 | n = div_u64(n, rate); |
848 | /* n should be less than 2^32 for being written to FREQ register */ | 1354 | /* n should be less than 2^32 for being written to FREQ register */ |
849 | snd_BUG_ON(n >> 32); | 1355 | snd_BUG_ON(n >> 32); |
@@ -864,13 +1370,13 @@ static int hdspm_set_rate(struct hdspm * hdspm, int rate, int called_internally) | |||
864 | 1370 | ||
865 | if (!(hdspm->control_register & HDSPM_ClockModeMaster)) { | 1371 | if (!(hdspm->control_register & HDSPM_ClockModeMaster)) { |
866 | 1372 | ||
867 | /* SLAVE --- */ | 1373 | /* SLAVE --- */ |
868 | if (called_internally) { | 1374 | if (called_internally) { |
869 | 1375 | ||
870 | /* request from ctl or card initialization | 1376 | /* request from ctl or card initialization |
871 | just make a warning an remember setting | 1377 | just make a warning an remember setting |
872 | for future master mode switching */ | 1378 | for future master mode switching */ |
873 | 1379 | ||
874 | snd_printk(KERN_WARNING "HDSPM: " | 1380 | snd_printk(KERN_WARNING "HDSPM: " |
875 | "Warning: device is not running " | 1381 | "Warning: device is not running " |
876 | "as a clock master.\n"); | 1382 | "as a clock master.\n"); |
@@ -907,7 +1413,7 @@ static int hdspm_set_rate(struct hdspm * hdspm, int rate, int called_internally) | |||
907 | 1413 | ||
908 | Note that a similar but essentially insoluble problem exists for | 1414 | Note that a similar but essentially insoluble problem exists for |
909 | externally-driven rate changes. All we can do is to flag rate | 1415 | externally-driven rate changes. All we can do is to flag rate |
910 | changes in the read/write routines. | 1416 | changes in the read/write routines. |
911 | */ | 1417 | */ |
912 | 1418 | ||
913 | if (current_rate <= 48000) | 1419 | if (current_rate <= 48000) |
@@ -975,16 +1481,35 @@ static int hdspm_set_rate(struct hdspm * hdspm, int rate, int called_internally) | |||
975 | /* For AES32, need to set DDS value in FREQ register | 1481 | /* For AES32, need to set DDS value in FREQ register |
976 | For MADI, also apparently */ | 1482 | For MADI, also apparently */ |
977 | hdspm_set_dds_value(hdspm, rate); | 1483 | hdspm_set_dds_value(hdspm, rate); |
978 | 1484 | ||
979 | if (hdspm->is_aes32 && rate != current_rate) | 1485 | if (AES32 == hdspm->io_type && rate != current_rate) |
980 | hdspm_write(hdspm, HDSPM_eeprom_wr, 0); | 1486 | hdspm_write(hdspm, HDSPM_eeprom_wr, 0); |
981 | |||
982 | /* For AES32 and for MADI (at least rev 204), channel_map needs to | ||
983 | * always be channel_map_madi_ss, whatever the sample rate */ | ||
984 | hdspm->channel_map = channel_map_madi_ss; | ||
985 | 1487 | ||
986 | hdspm->system_sample_rate = rate; | 1488 | hdspm->system_sample_rate = rate; |
987 | 1489 | ||
1490 | if (rate <= 48000) { | ||
1491 | hdspm->channel_map_in = hdspm->channel_map_in_ss; | ||
1492 | hdspm->channel_map_out = hdspm->channel_map_out_ss; | ||
1493 | hdspm->max_channels_in = hdspm->ss_in_channels; | ||
1494 | hdspm->max_channels_out = hdspm->ss_out_channels; | ||
1495 | hdspm->port_names_in = hdspm->port_names_in_ss; | ||
1496 | hdspm->port_names_out = hdspm->port_names_out_ss; | ||
1497 | } else if (rate <= 96000) { | ||
1498 | hdspm->channel_map_in = hdspm->channel_map_in_ds; | ||
1499 | hdspm->channel_map_out = hdspm->channel_map_out_ds; | ||
1500 | hdspm->max_channels_in = hdspm->ds_in_channels; | ||
1501 | hdspm->max_channels_out = hdspm->ds_out_channels; | ||
1502 | hdspm->port_names_in = hdspm->port_names_in_ds; | ||
1503 | hdspm->port_names_out = hdspm->port_names_out_ds; | ||
1504 | } else { | ||
1505 | hdspm->channel_map_in = hdspm->channel_map_in_qs; | ||
1506 | hdspm->channel_map_out = hdspm->channel_map_out_qs; | ||
1507 | hdspm->max_channels_in = hdspm->qs_in_channels; | ||
1508 | hdspm->max_channels_out = hdspm->qs_out_channels; | ||
1509 | hdspm->port_names_in = hdspm->port_names_in_qs; | ||
1510 | hdspm->port_names_out = hdspm->port_names_out_qs; | ||
1511 | } | ||
1512 | |||
988 | if (not_set != 0) | 1513 | if (not_set != 0) |
989 | return -1; | 1514 | return -1; |
990 | 1515 | ||
@@ -1019,39 +1544,26 @@ static inline unsigned char snd_hdspm_midi_read_byte (struct hdspm *hdspm, | |||
1019 | int id) | 1544 | int id) |
1020 | { | 1545 | { |
1021 | /* the hardware already does the relevant bit-mask with 0xff */ | 1546 | /* the hardware already does the relevant bit-mask with 0xff */ |
1022 | if (id) | 1547 | return hdspm_read(hdspm, hdspm->midi[id].dataIn); |
1023 | return hdspm_read(hdspm, HDSPM_midiDataIn1); | ||
1024 | else | ||
1025 | return hdspm_read(hdspm, HDSPM_midiDataIn0); | ||
1026 | } | 1548 | } |
1027 | 1549 | ||
1028 | static inline void snd_hdspm_midi_write_byte (struct hdspm *hdspm, int id, | 1550 | static inline void snd_hdspm_midi_write_byte (struct hdspm *hdspm, int id, |
1029 | int val) | 1551 | int val) |
1030 | { | 1552 | { |
1031 | /* the hardware already does the relevant bit-mask with 0xff */ | 1553 | /* the hardware already does the relevant bit-mask with 0xff */ |
1032 | if (id) | 1554 | return hdspm_write(hdspm, hdspm->midi[id].dataOut, val); |
1033 | hdspm_write(hdspm, HDSPM_midiDataOut1, val); | ||
1034 | else | ||
1035 | hdspm_write(hdspm, HDSPM_midiDataOut0, val); | ||
1036 | } | 1555 | } |
1037 | 1556 | ||
1038 | static inline int snd_hdspm_midi_input_available (struct hdspm *hdspm, int id) | 1557 | static inline int snd_hdspm_midi_input_available (struct hdspm *hdspm, int id) |
1039 | { | 1558 | { |
1040 | if (id) | 1559 | return hdspm_read(hdspm, hdspm->midi[id].statusIn) & 0xFF; |
1041 | return (hdspm_read(hdspm, HDSPM_midiStatusIn1) & 0xff); | ||
1042 | else | ||
1043 | return (hdspm_read(hdspm, HDSPM_midiStatusIn0) & 0xff); | ||
1044 | } | 1560 | } |
1045 | 1561 | ||
1046 | static inline int snd_hdspm_midi_output_possible (struct hdspm *hdspm, int id) | 1562 | static inline int snd_hdspm_midi_output_possible (struct hdspm *hdspm, int id) |
1047 | { | 1563 | { |
1048 | int fifo_bytes_used; | 1564 | int fifo_bytes_used; |
1049 | 1565 | ||
1050 | if (id) | 1566 | fifo_bytes_used = hdspm_read(hdspm, hdspm->midi[id].statusOut) & 0xFF; |
1051 | fifo_bytes_used = hdspm_read(hdspm, HDSPM_midiStatusOut1); | ||
1052 | else | ||
1053 | fifo_bytes_used = hdspm_read(hdspm, HDSPM_midiStatusOut0); | ||
1054 | fifo_bytes_used &= 0xff; | ||
1055 | 1567 | ||
1056 | if (fifo_bytes_used < 128) | 1568 | if (fifo_bytes_used < 128) |
1057 | return 128 - fifo_bytes_used; | 1569 | return 128 - fifo_bytes_used; |
@@ -1074,7 +1586,7 @@ static int snd_hdspm_midi_output_write (struct hdspm_midi *hmidi) | |||
1074 | unsigned char buf[128]; | 1586 | unsigned char buf[128]; |
1075 | 1587 | ||
1076 | /* Output is not interrupt driven */ | 1588 | /* Output is not interrupt driven */ |
1077 | 1589 | ||
1078 | spin_lock_irqsave (&hmidi->lock, flags); | 1590 | spin_lock_irqsave (&hmidi->lock, flags); |
1079 | if (hmidi->output && | 1591 | if (hmidi->output && |
1080 | !snd_rawmidi_transmit_empty (hmidi->output)) { | 1592 | !snd_rawmidi_transmit_empty (hmidi->output)) { |
@@ -1083,11 +1595,11 @@ static int snd_hdspm_midi_output_write (struct hdspm_midi *hmidi) | |||
1083 | if (n_pending > 0) { | 1595 | if (n_pending > 0) { |
1084 | if (n_pending > (int)sizeof (buf)) | 1596 | if (n_pending > (int)sizeof (buf)) |
1085 | n_pending = sizeof (buf); | 1597 | n_pending = sizeof (buf); |
1086 | 1598 | ||
1087 | to_write = snd_rawmidi_transmit (hmidi->output, buf, | 1599 | to_write = snd_rawmidi_transmit (hmidi->output, buf, |
1088 | n_pending); | 1600 | n_pending); |
1089 | if (to_write > 0) { | 1601 | if (to_write > 0) { |
1090 | for (i = 0; i < to_write; ++i) | 1602 | for (i = 0; i < to_write; ++i) |
1091 | snd_hdspm_midi_write_byte (hmidi->hdspm, | 1603 | snd_hdspm_midi_write_byte (hmidi->hdspm, |
1092 | hmidi->id, | 1604 | hmidi->id, |
1093 | buf[i]); | 1605 | buf[i]); |
@@ -1127,12 +1639,11 @@ static int snd_hdspm_midi_input_read (struct hdspm_midi *hmidi) | |||
1127 | } | 1639 | } |
1128 | } | 1640 | } |
1129 | hmidi->pending = 0; | 1641 | hmidi->pending = 0; |
1130 | if (hmidi->id) | 1642 | |
1131 | hmidi->hdspm->control_register |= HDSPM_Midi1InterruptEnable; | 1643 | hmidi->hdspm->control_register |= hmidi->ie; |
1132 | else | ||
1133 | hmidi->hdspm->control_register |= HDSPM_Midi0InterruptEnable; | ||
1134 | hdspm_write(hmidi->hdspm, HDSPM_controlRegister, | 1644 | hdspm_write(hmidi->hdspm, HDSPM_controlRegister, |
1135 | hmidi->hdspm->control_register); | 1645 | hmidi->hdspm->control_register); |
1646 | |||
1136 | spin_unlock_irqrestore (&hmidi->lock, flags); | 1647 | spin_unlock_irqrestore (&hmidi->lock, flags); |
1137 | return snd_hdspm_midi_output_write (hmidi); | 1648 | return snd_hdspm_midi_output_write (hmidi); |
1138 | } | 1649 | } |
@@ -1143,20 +1654,18 @@ snd_hdspm_midi_input_trigger(struct snd_rawmidi_substream *substream, int up) | |||
1143 | struct hdspm *hdspm; | 1654 | struct hdspm *hdspm; |
1144 | struct hdspm_midi *hmidi; | 1655 | struct hdspm_midi *hmidi; |
1145 | unsigned long flags; | 1656 | unsigned long flags; |
1146 | u32 ie; | ||
1147 | 1657 | ||
1148 | hmidi = substream->rmidi->private_data; | 1658 | hmidi = substream->rmidi->private_data; |
1149 | hdspm = hmidi->hdspm; | 1659 | hdspm = hmidi->hdspm; |
1150 | ie = hmidi->id ? | 1660 | |
1151 | HDSPM_Midi1InterruptEnable : HDSPM_Midi0InterruptEnable; | ||
1152 | spin_lock_irqsave (&hdspm->lock, flags); | 1661 | spin_lock_irqsave (&hdspm->lock, flags); |
1153 | if (up) { | 1662 | if (up) { |
1154 | if (!(hdspm->control_register & ie)) { | 1663 | if (!(hdspm->control_register & hmidi->ie)) { |
1155 | snd_hdspm_flush_midi_input (hdspm, hmidi->id); | 1664 | snd_hdspm_flush_midi_input (hdspm, hmidi->id); |
1156 | hdspm->control_register |= ie; | 1665 | hdspm->control_register |= hmidi->ie; |
1157 | } | 1666 | } |
1158 | } else { | 1667 | } else { |
1159 | hdspm->control_register &= ~ie; | 1668 | hdspm->control_register &= ~hmidi->ie; |
1160 | } | 1669 | } |
1161 | 1670 | ||
1162 | hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register); | 1671 | hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register); |
@@ -1167,14 +1676,14 @@ static void snd_hdspm_midi_output_timer(unsigned long data) | |||
1167 | { | 1676 | { |
1168 | struct hdspm_midi *hmidi = (struct hdspm_midi *) data; | 1677 | struct hdspm_midi *hmidi = (struct hdspm_midi *) data; |
1169 | unsigned long flags; | 1678 | unsigned long flags; |
1170 | 1679 | ||
1171 | snd_hdspm_midi_output_write(hmidi); | 1680 | snd_hdspm_midi_output_write(hmidi); |
1172 | spin_lock_irqsave (&hmidi->lock, flags); | 1681 | spin_lock_irqsave (&hmidi->lock, flags); |
1173 | 1682 | ||
1174 | /* this does not bump hmidi->istimer, because the | 1683 | /* this does not bump hmidi->istimer, because the |
1175 | kernel automatically removed the timer when it | 1684 | kernel automatically removed the timer when it |
1176 | expired, and we are now adding it back, thus | 1685 | expired, and we are now adding it back, thus |
1177 | leaving istimer wherever it was set before. | 1686 | leaving istimer wherever it was set before. |
1178 | */ | 1687 | */ |
1179 | 1688 | ||
1180 | if (hmidi->istimer) { | 1689 | if (hmidi->istimer) { |
@@ -1288,22 +1797,103 @@ static int __devinit snd_hdspm_create_midi (struct snd_card *card, | |||
1288 | hdspm->midi[id].hdspm = hdspm; | 1797 | hdspm->midi[id].hdspm = hdspm; |
1289 | spin_lock_init (&hdspm->midi[id].lock); | 1798 | spin_lock_init (&hdspm->midi[id].lock); |
1290 | 1799 | ||
1291 | sprintf (buf, "%s MIDI %d", card->shortname, id+1); | 1800 | if (0 == id) { |
1292 | err = snd_rawmidi_new (card, buf, id, 1, 1, &hdspm->midi[id].rmidi); | 1801 | if (MADIface == hdspm->io_type) { |
1293 | if (err < 0) | 1802 | /* MIDI-over-MADI on HDSPe MADIface */ |
1294 | return err; | 1803 | hdspm->midi[0].dataIn = HDSPM_midiDataIn2; |
1804 | hdspm->midi[0].statusIn = HDSPM_midiStatusIn2; | ||
1805 | hdspm->midi[0].dataOut = HDSPM_midiDataOut2; | ||
1806 | hdspm->midi[0].statusOut = HDSPM_midiStatusOut2; | ||
1807 | hdspm->midi[0].ie = HDSPM_Midi2InterruptEnable; | ||
1808 | hdspm->midi[0].irq = HDSPM_midi2IRQPending; | ||
1809 | } else { | ||
1810 | hdspm->midi[0].dataIn = HDSPM_midiDataIn0; | ||
1811 | hdspm->midi[0].statusIn = HDSPM_midiStatusIn0; | ||
1812 | hdspm->midi[0].dataOut = HDSPM_midiDataOut0; | ||
1813 | hdspm->midi[0].statusOut = HDSPM_midiStatusOut0; | ||
1814 | hdspm->midi[0].ie = HDSPM_Midi0InterruptEnable; | ||
1815 | hdspm->midi[0].irq = HDSPM_midi0IRQPending; | ||
1816 | } | ||
1817 | } else if (1 == id) { | ||
1818 | hdspm->midi[1].dataIn = HDSPM_midiDataIn1; | ||
1819 | hdspm->midi[1].statusIn = HDSPM_midiStatusIn1; | ||
1820 | hdspm->midi[1].dataOut = HDSPM_midiDataOut1; | ||
1821 | hdspm->midi[1].statusOut = HDSPM_midiStatusOut1; | ||
1822 | hdspm->midi[1].ie = HDSPM_Midi1InterruptEnable; | ||
1823 | hdspm->midi[1].irq = HDSPM_midi1IRQPending; | ||
1824 | } else if ((2 == id) && (MADI == hdspm->io_type)) { | ||
1825 | /* MIDI-over-MADI on HDSPe MADI */ | ||
1826 | hdspm->midi[2].dataIn = HDSPM_midiDataIn2; | ||
1827 | hdspm->midi[2].statusIn = HDSPM_midiStatusIn2; | ||
1828 | hdspm->midi[2].dataOut = HDSPM_midiDataOut2; | ||
1829 | hdspm->midi[2].statusOut = HDSPM_midiStatusOut2; | ||
1830 | hdspm->midi[2].ie = HDSPM_Midi2InterruptEnable; | ||
1831 | hdspm->midi[2].irq = HDSPM_midi2IRQPending; | ||
1832 | } else if (2 == id) { | ||
1833 | /* TCO MTC, read only */ | ||
1834 | hdspm->midi[2].dataIn = HDSPM_midiDataIn2; | ||
1835 | hdspm->midi[2].statusIn = HDSPM_midiStatusIn2; | ||
1836 | hdspm->midi[2].dataOut = -1; | ||
1837 | hdspm->midi[2].statusOut = -1; | ||
1838 | hdspm->midi[2].ie = HDSPM_Midi2InterruptEnable; | ||
1839 | hdspm->midi[2].irq = HDSPM_midi2IRQPendingAES; | ||
1840 | } else if (3 == id) { | ||
1841 | /* TCO MTC on HDSPe MADI */ | ||
1842 | hdspm->midi[3].dataIn = HDSPM_midiDataIn3; | ||
1843 | hdspm->midi[3].statusIn = HDSPM_midiStatusIn3; | ||
1844 | hdspm->midi[3].dataOut = -1; | ||
1845 | hdspm->midi[3].statusOut = -1; | ||
1846 | hdspm->midi[3].ie = HDSPM_Midi3InterruptEnable; | ||
1847 | hdspm->midi[3].irq = HDSPM_midi3IRQPending; | ||
1848 | } | ||
1295 | 1849 | ||
1296 | sprintf(hdspm->midi[id].rmidi->name, "HDSPM MIDI %d", id+1); | 1850 | if ((id < 2) || ((2 == id) && ((MADI == hdspm->io_type) || |
1297 | hdspm->midi[id].rmidi->private_data = &hdspm->midi[id]; | 1851 | (MADIface == hdspm->io_type)))) { |
1852 | if ((id == 0) && (MADIface == hdspm->io_type)) { | ||
1853 | sprintf(buf, "%s MIDIoverMADI", card->shortname); | ||
1854 | } else if ((id == 2) && (MADI == hdspm->io_type)) { | ||
1855 | sprintf(buf, "%s MIDIoverMADI", card->shortname); | ||
1856 | } else { | ||
1857 | sprintf(buf, "%s MIDI %d", card->shortname, id+1); | ||
1858 | } | ||
1859 | err = snd_rawmidi_new(card, buf, id, 1, 1, | ||
1860 | &hdspm->midi[id].rmidi); | ||
1861 | if (err < 0) | ||
1862 | return err; | ||
1298 | 1863 | ||
1299 | snd_rawmidi_set_ops(hdspm->midi[id].rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, | 1864 | sprintf(hdspm->midi[id].rmidi->name, "%s MIDI %d", |
1300 | &snd_hdspm_midi_output); | 1865 | card->id, id+1); |
1301 | snd_rawmidi_set_ops(hdspm->midi[id].rmidi, SNDRV_RAWMIDI_STREAM_INPUT, | 1866 | hdspm->midi[id].rmidi->private_data = &hdspm->midi[id]; |
1302 | &snd_hdspm_midi_input); | 1867 | |
1868 | snd_rawmidi_set_ops(hdspm->midi[id].rmidi, | ||
1869 | SNDRV_RAWMIDI_STREAM_OUTPUT, | ||
1870 | &snd_hdspm_midi_output); | ||
1871 | snd_rawmidi_set_ops(hdspm->midi[id].rmidi, | ||
1872 | SNDRV_RAWMIDI_STREAM_INPUT, | ||
1873 | &snd_hdspm_midi_input); | ||
1874 | |||
1875 | hdspm->midi[id].rmidi->info_flags |= | ||
1876 | SNDRV_RAWMIDI_INFO_OUTPUT | | ||
1877 | SNDRV_RAWMIDI_INFO_INPUT | | ||
1878 | SNDRV_RAWMIDI_INFO_DUPLEX; | ||
1879 | } else { | ||
1880 | /* TCO MTC, read only */ | ||
1881 | sprintf(buf, "%s MTC %d", card->shortname, id+1); | ||
1882 | err = snd_rawmidi_new(card, buf, id, 1, 1, | ||
1883 | &hdspm->midi[id].rmidi); | ||
1884 | if (err < 0) | ||
1885 | return err; | ||
1303 | 1886 | ||
1304 | hdspm->midi[id].rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | | 1887 | sprintf(hdspm->midi[id].rmidi->name, |
1305 | SNDRV_RAWMIDI_INFO_INPUT | | 1888 | "%s MTC %d", card->id, id+1); |
1306 | SNDRV_RAWMIDI_INFO_DUPLEX; | 1889 | hdspm->midi[id].rmidi->private_data = &hdspm->midi[id]; |
1890 | |||
1891 | snd_rawmidi_set_ops(hdspm->midi[id].rmidi, | ||
1892 | SNDRV_RAWMIDI_STREAM_INPUT, | ||
1893 | &snd_hdspm_midi_input); | ||
1894 | |||
1895 | hdspm->midi[id].rmidi->info_flags |= SNDRV_RAWMIDI_INFO_INPUT; | ||
1896 | } | ||
1307 | 1897 | ||
1308 | return 0; | 1898 | return 0; |
1309 | } | 1899 | } |
@@ -1312,12 +1902,15 @@ static int __devinit snd_hdspm_create_midi (struct snd_card *card, | |||
1312 | static void hdspm_midi_tasklet(unsigned long arg) | 1902 | static void hdspm_midi_tasklet(unsigned long arg) |
1313 | { | 1903 | { |
1314 | struct hdspm *hdspm = (struct hdspm *)arg; | 1904 | struct hdspm *hdspm = (struct hdspm *)arg; |
1315 | 1905 | int i = 0; | |
1316 | if (hdspm->midi[0].pending) | 1906 | |
1317 | snd_hdspm_midi_input_read (&hdspm->midi[0]); | 1907 | while (i < hdspm->midiPorts) { |
1318 | if (hdspm->midi[1].pending) | 1908 | if (hdspm->midi[i].pending) |
1319 | snd_hdspm_midi_input_read (&hdspm->midi[1]); | 1909 | snd_hdspm_midi_input_read(&hdspm->midi[i]); |
1320 | } | 1910 | |
1911 | i++; | ||
1912 | } | ||
1913 | } | ||
1321 | 1914 | ||
1322 | 1915 | ||
1323 | /*----------------------------------------------------------------------------- | 1916 | /*----------------------------------------------------------------------------- |
@@ -1326,6 +1919,22 @@ static void hdspm_midi_tasklet(unsigned long arg) | |||
1326 | 1919 | ||
1327 | /* get the system sample rate which is set */ | 1920 | /* get the system sample rate which is set */ |
1328 | 1921 | ||
1922 | |||
1923 | /** | ||
1924 | * Calculate the real sample rate from the | ||
1925 | * current DDS value. | ||
1926 | **/ | ||
1927 | static int hdspm_get_system_sample_rate(struct hdspm *hdspm) | ||
1928 | { | ||
1929 | unsigned int period, rate; | ||
1930 | |||
1931 | period = hdspm_read(hdspm, HDSPM_RD_PLL_FREQ); | ||
1932 | rate = hdspm_calc_dds_value(hdspm, period); | ||
1933 | |||
1934 | return rate; | ||
1935 | } | ||
1936 | |||
1937 | |||
1329 | #define HDSPM_SYSTEM_SAMPLE_RATE(xname, xindex) \ | 1938 | #define HDSPM_SYSTEM_SAMPLE_RATE(xname, xindex) \ |
1330 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | 1939 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
1331 | .name = xname, \ | 1940 | .name = xname, \ |
@@ -1340,112 +1949,274 @@ static int snd_hdspm_info_system_sample_rate(struct snd_kcontrol *kcontrol, | |||
1340 | { | 1949 | { |
1341 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | 1950 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; |
1342 | uinfo->count = 1; | 1951 | uinfo->count = 1; |
1952 | uinfo->value.integer.min = 27000; | ||
1953 | uinfo->value.integer.max = 207000; | ||
1954 | uinfo->value.integer.step = 1; | ||
1343 | return 0; | 1955 | return 0; |
1344 | } | 1956 | } |
1345 | 1957 | ||
1958 | |||
1346 | static int snd_hdspm_get_system_sample_rate(struct snd_kcontrol *kcontrol, | 1959 | static int snd_hdspm_get_system_sample_rate(struct snd_kcontrol *kcontrol, |
1347 | struct snd_ctl_elem_value * | 1960 | struct snd_ctl_elem_value * |
1348 | ucontrol) | 1961 | ucontrol) |
1349 | { | 1962 | { |
1350 | struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); | 1963 | struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); |
1351 | 1964 | ||
1352 | ucontrol->value.enumerated.item[0] = hdspm->system_sample_rate; | 1965 | ucontrol->value.integer.value[0] = hdspm_get_system_sample_rate(hdspm); |
1966 | return 0; | ||
1967 | } | ||
1968 | |||
1969 | |||
1970 | /** | ||
1971 | * Returns the WordClock sample rate class for the given card. | ||
1972 | **/ | ||
1973 | static int hdspm_get_wc_sample_rate(struct hdspm *hdspm) | ||
1974 | { | ||
1975 | int status; | ||
1976 | |||
1977 | switch (hdspm->io_type) { | ||
1978 | case RayDAT: | ||
1979 | case AIO: | ||
1980 | status = hdspm_read(hdspm, HDSPM_RD_STATUS_1); | ||
1981 | return (status >> 16) & 0xF; | ||
1982 | break; | ||
1983 | default: | ||
1984 | break; | ||
1985 | } | ||
1986 | |||
1987 | |||
1988 | return 0; | ||
1989 | } | ||
1990 | |||
1991 | |||
1992 | /** | ||
1993 | * Returns the TCO sample rate class for the given card. | ||
1994 | **/ | ||
1995 | static int hdspm_get_tco_sample_rate(struct hdspm *hdspm) | ||
1996 | { | ||
1997 | int status; | ||
1998 | |||
1999 | if (hdspm->tco) { | ||
2000 | switch (hdspm->io_type) { | ||
2001 | case RayDAT: | ||
2002 | case AIO: | ||
2003 | status = hdspm_read(hdspm, HDSPM_RD_STATUS_1); | ||
2004 | return (status >> 20) & 0xF; | ||
2005 | break; | ||
2006 | default: | ||
2007 | break; | ||
2008 | } | ||
2009 | } | ||
2010 | |||
2011 | return 0; | ||
2012 | } | ||
2013 | |||
2014 | |||
2015 | /** | ||
2016 | * Returns the SYNC_IN sample rate class for the given card. | ||
2017 | **/ | ||
2018 | static int hdspm_get_sync_in_sample_rate(struct hdspm *hdspm) | ||
2019 | { | ||
2020 | int status; | ||
2021 | |||
2022 | if (hdspm->tco) { | ||
2023 | switch (hdspm->io_type) { | ||
2024 | case RayDAT: | ||
2025 | case AIO: | ||
2026 | status = hdspm_read(hdspm, HDSPM_RD_STATUS_2); | ||
2027 | return (status >> 12) & 0xF; | ||
2028 | break; | ||
2029 | default: | ||
2030 | break; | ||
2031 | } | ||
2032 | } | ||
2033 | |||
1353 | return 0; | 2034 | return 0; |
1354 | } | 2035 | } |
1355 | 2036 | ||
2037 | |||
2038 | /** | ||
2039 | * Returns the sample rate class for input source <idx> for | ||
2040 | * 'new style' cards like the AIO and RayDAT. | ||
2041 | **/ | ||
2042 | static int hdspm_get_s1_sample_rate(struct hdspm *hdspm, unsigned int idx) | ||
2043 | { | ||
2044 | int status = hdspm_read(hdspm, HDSPM_RD_STATUS_2); | ||
2045 | |||
2046 | return (status >> (idx*4)) & 0xF; | ||
2047 | } | ||
2048 | |||
2049 | |||
2050 | |||
1356 | #define HDSPM_AUTOSYNC_SAMPLE_RATE(xname, xindex) \ | 2051 | #define HDSPM_AUTOSYNC_SAMPLE_RATE(xname, xindex) \ |
1357 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | 2052 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
1358 | .name = xname, \ | 2053 | .name = xname, \ |
1359 | .index = xindex, \ | 2054 | .private_value = xindex, \ |
1360 | .access = SNDRV_CTL_ELEM_ACCESS_READ, \ | 2055 | .access = SNDRV_CTL_ELEM_ACCESS_READ, \ |
1361 | .info = snd_hdspm_info_autosync_sample_rate, \ | 2056 | .info = snd_hdspm_info_autosync_sample_rate, \ |
1362 | .get = snd_hdspm_get_autosync_sample_rate \ | 2057 | .get = snd_hdspm_get_autosync_sample_rate \ |
1363 | } | 2058 | } |
1364 | 2059 | ||
2060 | |||
1365 | static int snd_hdspm_info_autosync_sample_rate(struct snd_kcontrol *kcontrol, | 2061 | static int snd_hdspm_info_autosync_sample_rate(struct snd_kcontrol *kcontrol, |
1366 | struct snd_ctl_elem_info *uinfo) | 2062 | struct snd_ctl_elem_info *uinfo) |
1367 | { | 2063 | { |
1368 | static char *texts[] = { "32000", "44100", "48000", | ||
1369 | "64000", "88200", "96000", | ||
1370 | "128000", "176400", "192000", | ||
1371 | "None" | ||
1372 | }; | ||
1373 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 2064 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; |
1374 | uinfo->count = 1; | 2065 | uinfo->count = 1; |
1375 | uinfo->value.enumerated.items = 10; | 2066 | uinfo->value.enumerated.items = 10; |
2067 | |||
1376 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | 2068 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) |
1377 | uinfo->value.enumerated.item = | 2069 | uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; |
1378 | uinfo->value.enumerated.items - 1; | ||
1379 | strcpy(uinfo->value.enumerated.name, | 2070 | strcpy(uinfo->value.enumerated.name, |
1380 | texts[uinfo->value.enumerated.item]); | 2071 | texts_freq[uinfo->value.enumerated.item]); |
1381 | return 0; | 2072 | return 0; |
1382 | } | 2073 | } |
1383 | 2074 | ||
2075 | |||
1384 | static int snd_hdspm_get_autosync_sample_rate(struct snd_kcontrol *kcontrol, | 2076 | static int snd_hdspm_get_autosync_sample_rate(struct snd_kcontrol *kcontrol, |
1385 | struct snd_ctl_elem_value * | 2077 | struct snd_ctl_elem_value * |
1386 | ucontrol) | 2078 | ucontrol) |
1387 | { | 2079 | { |
1388 | struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); | 2080 | struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); |
1389 | 2081 | ||
1390 | switch (hdspm_external_sample_rate(hdspm)) { | 2082 | switch (hdspm->io_type) { |
1391 | case 32000: | 2083 | case RayDAT: |
1392 | ucontrol->value.enumerated.item[0] = 0; | 2084 | switch (kcontrol->private_value) { |
1393 | break; | 2085 | case 0: |
1394 | case 44100: | 2086 | ucontrol->value.enumerated.item[0] = |
1395 | ucontrol->value.enumerated.item[0] = 1; | 2087 | hdspm_get_wc_sample_rate(hdspm); |
1396 | break; | 2088 | break; |
1397 | case 48000: | 2089 | case 7: |
1398 | ucontrol->value.enumerated.item[0] = 2; | 2090 | ucontrol->value.enumerated.item[0] = |
1399 | break; | 2091 | hdspm_get_tco_sample_rate(hdspm); |
1400 | case 64000: | 2092 | break; |
1401 | ucontrol->value.enumerated.item[0] = 3; | 2093 | case 8: |
1402 | break; | 2094 | ucontrol->value.enumerated.item[0] = |
1403 | case 88200: | 2095 | hdspm_get_sync_in_sample_rate(hdspm); |
1404 | ucontrol->value.enumerated.item[0] = 4; | 2096 | break; |
1405 | break; | 2097 | default: |
1406 | case 96000: | 2098 | ucontrol->value.enumerated.item[0] = |
1407 | ucontrol->value.enumerated.item[0] = 5; | 2099 | hdspm_get_s1_sample_rate(hdspm, |
1408 | break; | 2100 | kcontrol->private_value-1); |
1409 | case 128000: | 2101 | } |
1410 | ucontrol->value.enumerated.item[0] = 6; | 2102 | |
1411 | break; | 2103 | case AIO: |
1412 | case 176400: | 2104 | switch (kcontrol->private_value) { |
1413 | ucontrol->value.enumerated.item[0] = 7; | 2105 | case 0: /* WC */ |
1414 | break; | 2106 | ucontrol->value.enumerated.item[0] = |
1415 | case 192000: | 2107 | hdspm_get_wc_sample_rate(hdspm); |
1416 | ucontrol->value.enumerated.item[0] = 8; | 2108 | break; |
1417 | break; | 2109 | case 4: /* TCO */ |
2110 | ucontrol->value.enumerated.item[0] = | ||
2111 | hdspm_get_tco_sample_rate(hdspm); | ||
2112 | break; | ||
2113 | case 5: /* SYNC_IN */ | ||
2114 | ucontrol->value.enumerated.item[0] = | ||
2115 | hdspm_get_sync_in_sample_rate(hdspm); | ||
2116 | break; | ||
2117 | default: | ||
2118 | ucontrol->value.enumerated.item[0] = | ||
2119 | hdspm_get_s1_sample_rate(hdspm, | ||
2120 | ucontrol->id.index-1); | ||
2121 | } | ||
2122 | |||
2123 | case AES32: | ||
1418 | 2124 | ||
2125 | switch (kcontrol->private_value) { | ||
2126 | case 0: /* WC */ | ||
2127 | ucontrol->value.enumerated.item[0] = | ||
2128 | hdspm_get_wc_sample_rate(hdspm); | ||
2129 | break; | ||
2130 | case 9: /* TCO */ | ||
2131 | ucontrol->value.enumerated.item[0] = | ||
2132 | hdspm_get_tco_sample_rate(hdspm); | ||
2133 | break; | ||
2134 | case 10: /* SYNC_IN */ | ||
2135 | ucontrol->value.enumerated.item[0] = | ||
2136 | hdspm_get_sync_in_sample_rate(hdspm); | ||
2137 | break; | ||
2138 | default: /* AES1 to AES8 */ | ||
2139 | ucontrol->value.enumerated.item[0] = | ||
2140 | hdspm_get_s1_sample_rate(hdspm, | ||
2141 | kcontrol->private_value-1); | ||
2142 | break; | ||
2143 | |||
2144 | } | ||
1419 | default: | 2145 | default: |
1420 | ucontrol->value.enumerated.item[0] = 9; | 2146 | break; |
1421 | } | 2147 | } |
2148 | |||
1422 | return 0; | 2149 | return 0; |
1423 | } | 2150 | } |
1424 | 2151 | ||
2152 | |||
1425 | #define HDSPM_SYSTEM_CLOCK_MODE(xname, xindex) \ | 2153 | #define HDSPM_SYSTEM_CLOCK_MODE(xname, xindex) \ |
1426 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | 2154 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
1427 | .name = xname, \ | 2155 | .name = xname, \ |
1428 | .index = xindex, \ | 2156 | .index = xindex, \ |
1429 | .access = SNDRV_CTL_ELEM_ACCESS_READ, \ | 2157 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\ |
1430 | .info = snd_hdspm_info_system_clock_mode, \ | 2158 | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ |
1431 | .get = snd_hdspm_get_system_clock_mode, \ | 2159 | .info = snd_hdspm_info_system_clock_mode, \ |
1432 | } | 2160 | .get = snd_hdspm_get_system_clock_mode, \ |
2161 | .put = snd_hdspm_put_system_clock_mode, \ | ||
2162 | } | ||
2163 | |||
2164 | |||
2165 | /** | ||
2166 | * Returns the system clock mode for the given card. | ||
2167 | * @returns 0 - master, 1 - slave | ||
2168 | **/ | ||
2169 | static int hdspm_system_clock_mode(struct hdspm *hdspm) | ||
2170 | { | ||
2171 | switch (hdspm->io_type) { | ||
2172 | case AIO: | ||
2173 | case RayDAT: | ||
2174 | if (hdspm->settings_register & HDSPM_c0Master) | ||
2175 | return 0; | ||
2176 | break; | ||
2177 | |||
2178 | default: | ||
2179 | if (hdspm->control_register & HDSPM_ClockModeMaster) | ||
2180 | return 0; | ||
2181 | } | ||
1433 | 2182 | ||
2183 | return 1; | ||
2184 | } | ||
1434 | 2185 | ||
1435 | 2186 | ||
1436 | static int hdspm_system_clock_mode(struct hdspm * hdspm) | 2187 | /** |
2188 | * Sets the system clock mode. | ||
2189 | * @param mode 0 - master, 1 - slave | ||
2190 | **/ | ||
2191 | static void hdspm_set_system_clock_mode(struct hdspm *hdspm, int mode) | ||
1437 | { | 2192 | { |
1438 | /* Always reflect the hardware info, rme is never wrong !!!! */ | 2193 | switch (hdspm->io_type) { |
2194 | case AIO: | ||
2195 | case RayDAT: | ||
2196 | if (0 == mode) | ||
2197 | hdspm->settings_register |= HDSPM_c0Master; | ||
2198 | else | ||
2199 | hdspm->settings_register &= ~HDSPM_c0Master; | ||
1439 | 2200 | ||
1440 | if (hdspm->control_register & HDSPM_ClockModeMaster) | 2201 | hdspm_write(hdspm, HDSPM_WR_SETTINGS, hdspm->settings_register); |
1441 | return 0; | 2202 | break; |
1442 | return 1; | 2203 | |
2204 | default: | ||
2205 | if (0 == mode) | ||
2206 | hdspm->control_register |= HDSPM_ClockModeMaster; | ||
2207 | else | ||
2208 | hdspm->control_register &= ~HDSPM_ClockModeMaster; | ||
2209 | |||
2210 | hdspm_write(hdspm, HDSPM_controlRegister, | ||
2211 | hdspm->control_register); | ||
2212 | } | ||
1443 | } | 2213 | } |
1444 | 2214 | ||
2215 | |||
1445 | static int snd_hdspm_info_system_clock_mode(struct snd_kcontrol *kcontrol, | 2216 | static int snd_hdspm_info_system_clock_mode(struct snd_kcontrol *kcontrol, |
1446 | struct snd_ctl_elem_info *uinfo) | 2217 | struct snd_ctl_elem_info *uinfo) |
1447 | { | 2218 | { |
1448 | static char *texts[] = { "Master", "Slave" }; | 2219 | static char *texts[] = { "Master", "AutoSync" }; |
1449 | 2220 | ||
1450 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 2221 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; |
1451 | uinfo->count = 1; | 2222 | uinfo->count = 1; |
@@ -1463,96 +2234,83 @@ static int snd_hdspm_get_system_clock_mode(struct snd_kcontrol *kcontrol, | |||
1463 | { | 2234 | { |
1464 | struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); | 2235 | struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); |
1465 | 2236 | ||
1466 | ucontrol->value.enumerated.item[0] = | 2237 | ucontrol->value.enumerated.item[0] = hdspm_system_clock_mode(hdspm); |
1467 | hdspm_system_clock_mode(hdspm); | ||
1468 | return 0; | 2238 | return 0; |
1469 | } | 2239 | } |
1470 | 2240 | ||
1471 | #define HDSPM_CLOCK_SOURCE(xname, xindex) \ | 2241 | static int snd_hdspm_put_system_clock_mode(struct snd_kcontrol *kcontrol, |
1472 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | 2242 | struct snd_ctl_elem_value *ucontrol) |
1473 | .name = xname, \ | 2243 | { |
1474 | .index = xindex, \ | 2244 | struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); |
1475 | .info = snd_hdspm_info_clock_source, \ | 2245 | int val; |
1476 | .get = snd_hdspm_get_clock_source, \ | 2246 | |
1477 | .put = snd_hdspm_put_clock_source \ | 2247 | if (!snd_hdspm_use_is_exclusive(hdspm)) |
2248 | return -EBUSY; | ||
2249 | |||
2250 | val = ucontrol->value.enumerated.item[0]; | ||
2251 | if (val < 0) | ||
2252 | val = 0; | ||
2253 | else if (val > 1) | ||
2254 | val = 1; | ||
2255 | |||
2256 | hdspm_set_system_clock_mode(hdspm, val); | ||
2257 | |||
2258 | return 0; | ||
1478 | } | 2259 | } |
1479 | 2260 | ||
2261 | |||
2262 | #define HDSPM_INTERNAL_CLOCK(xname, xindex) \ | ||
2263 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | ||
2264 | .name = xname, \ | ||
2265 | .index = xindex, \ | ||
2266 | .info = snd_hdspm_info_clock_source, \ | ||
2267 | .get = snd_hdspm_get_clock_source, \ | ||
2268 | .put = snd_hdspm_put_clock_source \ | ||
2269 | } | ||
2270 | |||
2271 | |||
1480 | static int hdspm_clock_source(struct hdspm * hdspm) | 2272 | static int hdspm_clock_source(struct hdspm * hdspm) |
1481 | { | 2273 | { |
1482 | if (hdspm->control_register & HDSPM_ClockModeMaster) { | 2274 | switch (hdspm->system_sample_rate) { |
1483 | switch (hdspm->system_sample_rate) { | 2275 | case 32000: return 0; |
1484 | case 32000: | 2276 | case 44100: return 1; |
1485 | return 1; | 2277 | case 48000: return 2; |
1486 | case 44100: | 2278 | case 64000: return 3; |
1487 | return 2; | 2279 | case 88200: return 4; |
1488 | case 48000: | 2280 | case 96000: return 5; |
1489 | return 3; | 2281 | case 128000: return 6; |
1490 | case 64000: | 2282 | case 176400: return 7; |
1491 | return 4; | 2283 | case 192000: return 8; |
1492 | case 88200: | ||
1493 | return 5; | ||
1494 | case 96000: | ||
1495 | return 6; | ||
1496 | case 128000: | ||
1497 | return 7; | ||
1498 | case 176400: | ||
1499 | return 8; | ||
1500 | case 192000: | ||
1501 | return 9; | ||
1502 | default: | ||
1503 | return 3; | ||
1504 | } | ||
1505 | } else { | ||
1506 | return 0; | ||
1507 | } | 2284 | } |
2285 | |||
2286 | return -1; | ||
1508 | } | 2287 | } |
1509 | 2288 | ||
1510 | static int hdspm_set_clock_source(struct hdspm * hdspm, int mode) | 2289 | static int hdspm_set_clock_source(struct hdspm * hdspm, int mode) |
1511 | { | 2290 | { |
1512 | int rate; | 2291 | int rate; |
1513 | switch (mode) { | 2292 | switch (mode) { |
1514 | 2293 | case 0: | |
1515 | case HDSPM_CLOCK_SOURCE_AUTOSYNC: | 2294 | rate = 32000; break; |
1516 | if (hdspm_external_sample_rate(hdspm) != 0) { | 2295 | case 1: |
1517 | hdspm->control_register &= ~HDSPM_ClockModeMaster; | 2296 | rate = 44100; break; |
1518 | hdspm_write(hdspm, HDSPM_controlRegister, | 2297 | case 2: |
1519 | hdspm->control_register); | 2298 | rate = 48000; break; |
1520 | return 0; | 2299 | case 3: |
1521 | } | 2300 | rate = 64000; break; |
1522 | return -1; | 2301 | case 4: |
1523 | case HDSPM_CLOCK_SOURCE_INTERNAL_32KHZ: | 2302 | rate = 88200; break; |
1524 | rate = 32000; | 2303 | case 5: |
1525 | break; | 2304 | rate = 96000; break; |
1526 | case HDSPM_CLOCK_SOURCE_INTERNAL_44_1KHZ: | 2305 | case 6: |
1527 | rate = 44100; | 2306 | rate = 128000; break; |
1528 | break; | 2307 | case 7: |
1529 | case HDSPM_CLOCK_SOURCE_INTERNAL_48KHZ: | 2308 | rate = 176400; break; |
1530 | rate = 48000; | 2309 | case 8: |
1531 | break; | 2310 | rate = 192000; break; |
1532 | case HDSPM_CLOCK_SOURCE_INTERNAL_64KHZ: | ||
1533 | rate = 64000; | ||
1534 | break; | ||
1535 | case HDSPM_CLOCK_SOURCE_INTERNAL_88_2KHZ: | ||
1536 | rate = 88200; | ||
1537 | break; | ||
1538 | case HDSPM_CLOCK_SOURCE_INTERNAL_96KHZ: | ||
1539 | rate = 96000; | ||
1540 | break; | ||
1541 | case HDSPM_CLOCK_SOURCE_INTERNAL_128KHZ: | ||
1542 | rate = 128000; | ||
1543 | break; | ||
1544 | case HDSPM_CLOCK_SOURCE_INTERNAL_176_4KHZ: | ||
1545 | rate = 176400; | ||
1546 | break; | ||
1547 | case HDSPM_CLOCK_SOURCE_INTERNAL_192KHZ: | ||
1548 | rate = 192000; | ||
1549 | break; | ||
1550 | |||
1551 | default: | 2311 | default: |
1552 | rate = 44100; | 2312 | rate = 48000; |
1553 | } | 2313 | } |
1554 | hdspm->control_register |= HDSPM_ClockModeMaster; | ||
1555 | hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register); | ||
1556 | hdspm_set_rate(hdspm, rate, 1); | 2314 | hdspm_set_rate(hdspm, rate, 1); |
1557 | return 0; | 2315 | return 0; |
1558 | } | 2316 | } |
@@ -1560,25 +2318,16 @@ static int hdspm_set_clock_source(struct hdspm * hdspm, int mode) | |||
1560 | static int snd_hdspm_info_clock_source(struct snd_kcontrol *kcontrol, | 2318 | static int snd_hdspm_info_clock_source(struct snd_kcontrol *kcontrol, |
1561 | struct snd_ctl_elem_info *uinfo) | 2319 | struct snd_ctl_elem_info *uinfo) |
1562 | { | 2320 | { |
1563 | static char *texts[] = { "AutoSync", | ||
1564 | "Internal 32.0 kHz", "Internal 44.1 kHz", | ||
1565 | "Internal 48.0 kHz", | ||
1566 | "Internal 64.0 kHz", "Internal 88.2 kHz", | ||
1567 | "Internal 96.0 kHz", | ||
1568 | "Internal 128.0 kHz", "Internal 176.4 kHz", | ||
1569 | "Internal 192.0 kHz" | ||
1570 | }; | ||
1571 | |||
1572 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 2321 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; |
1573 | uinfo->count = 1; | 2322 | uinfo->count = 1; |
1574 | uinfo->value.enumerated.items = 10; | 2323 | uinfo->value.enumerated.items = 9; |
1575 | 2324 | ||
1576 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | 2325 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) |
1577 | uinfo->value.enumerated.item = | 2326 | uinfo->value.enumerated.item = |
1578 | uinfo->value.enumerated.items - 1; | 2327 | uinfo->value.enumerated.items - 1; |
1579 | 2328 | ||
1580 | strcpy(uinfo->value.enumerated.name, | 2329 | strcpy(uinfo->value.enumerated.name, |
1581 | texts[uinfo->value.enumerated.item]); | 2330 | texts_freq[uinfo->value.enumerated.item+1]); |
1582 | 2331 | ||
1583 | return 0; | 2332 | return 0; |
1584 | } | 2333 | } |
@@ -1615,134 +2364,301 @@ static int snd_hdspm_put_clock_source(struct snd_kcontrol *kcontrol, | |||
1615 | return change; | 2364 | return change; |
1616 | } | 2365 | } |
1617 | 2366 | ||
1618 | #define HDSPM_PREF_SYNC_REF(xname, xindex) \ | ||
1619 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | ||
1620 | .name = xname, \ | ||
1621 | .index = xindex, \ | ||
1622 | .info = snd_hdspm_info_pref_sync_ref, \ | ||
1623 | .get = snd_hdspm_get_pref_sync_ref, \ | ||
1624 | .put = snd_hdspm_put_pref_sync_ref \ | ||
1625 | } | ||
1626 | 2367 | ||
2368 | #define HDSPM_PREF_SYNC_REF(xname, xindex) \ | ||
2369 | {.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | ||
2370 | .name = xname, \ | ||
2371 | .index = xindex, \ | ||
2372 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\ | ||
2373 | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ | ||
2374 | .info = snd_hdspm_info_pref_sync_ref, \ | ||
2375 | .get = snd_hdspm_get_pref_sync_ref, \ | ||
2376 | .put = snd_hdspm_put_pref_sync_ref \ | ||
2377 | } | ||
2378 | |||
2379 | |||
2380 | /** | ||
2381 | * Returns the current preferred sync reference setting. | ||
2382 | * The semantics of the return value are depending on the | ||
2383 | * card, please see the comments for clarification. | ||
2384 | **/ | ||
1627 | static int hdspm_pref_sync_ref(struct hdspm * hdspm) | 2385 | static int hdspm_pref_sync_ref(struct hdspm * hdspm) |
1628 | { | 2386 | { |
1629 | /* Notice that this looks at the requested sync source, | 2387 | switch (hdspm->io_type) { |
1630 | not the one actually in use. | 2388 | case AES32: |
1631 | */ | ||
1632 | if (hdspm->is_aes32) { | ||
1633 | switch (hdspm->control_register & HDSPM_SyncRefMask) { | 2389 | switch (hdspm->control_register & HDSPM_SyncRefMask) { |
1634 | /* number gives AES index, except for 0 which | 2390 | case 0: return 0; /* WC */ |
1635 | corresponds to WordClock */ | 2391 | case HDSPM_SyncRef0: return 1; /* AES 1 */ |
1636 | case 0: return 0; | 2392 | case HDSPM_SyncRef1: return 2; /* AES 2 */ |
1637 | case HDSPM_SyncRef0: return 1; | 2393 | case HDSPM_SyncRef1+HDSPM_SyncRef0: return 3; /* AES 3 */ |
1638 | case HDSPM_SyncRef1: return 2; | 2394 | case HDSPM_SyncRef2: return 4; /* AES 4 */ |
1639 | case HDSPM_SyncRef1+HDSPM_SyncRef0: return 3; | 2395 | case HDSPM_SyncRef2+HDSPM_SyncRef0: return 5; /* AES 5 */ |
1640 | case HDSPM_SyncRef2: return 4; | 2396 | case HDSPM_SyncRef2+HDSPM_SyncRef1: return 6; /* AES 6 */ |
1641 | case HDSPM_SyncRef2+HDSPM_SyncRef0: return 5; | 2397 | case HDSPM_SyncRef2+HDSPM_SyncRef1+HDSPM_SyncRef0: |
1642 | case HDSPM_SyncRef2+HDSPM_SyncRef1: return 6; | 2398 | return 7; /* AES 7 */ |
1643 | case HDSPM_SyncRef2+HDSPM_SyncRef1+HDSPM_SyncRef0: return 7; | 2399 | case HDSPM_SyncRef3: return 8; /* AES 8 */ |
1644 | case HDSPM_SyncRef3: return 8; | 2400 | case HDSPM_SyncRef3+HDSPM_SyncRef0: return 9; /* TCO */ |
1645 | } | 2401 | } |
1646 | } else { | 2402 | break; |
1647 | switch (hdspm->control_register & HDSPM_SyncRefMask) { | 2403 | |
1648 | case HDSPM_SyncRef_Word: | 2404 | case MADI: |
1649 | return HDSPM_SYNC_FROM_WORD; | 2405 | case MADIface: |
1650 | case HDSPM_SyncRef_MADI: | 2406 | if (hdspm->tco) { |
1651 | return HDSPM_SYNC_FROM_MADI; | 2407 | switch (hdspm->control_register & HDSPM_SyncRefMask) { |
2408 | case 0: return 0; /* WC */ | ||
2409 | case HDSPM_SyncRef0: return 1; /* MADI */ | ||
2410 | case HDSPM_SyncRef1: return 2; /* TCO */ | ||
2411 | case HDSPM_SyncRef1+HDSPM_SyncRef0: | ||
2412 | return 3; /* SYNC_IN */ | ||
2413 | } | ||
2414 | } else { | ||
2415 | switch (hdspm->control_register & HDSPM_SyncRefMask) { | ||
2416 | case 0: return 0; /* WC */ | ||
2417 | case HDSPM_SyncRef0: return 1; /* MADI */ | ||
2418 | case HDSPM_SyncRef1+HDSPM_SyncRef0: | ||
2419 | return 2; /* SYNC_IN */ | ||
2420 | } | ||
2421 | } | ||
2422 | break; | ||
2423 | |||
2424 | case RayDAT: | ||
2425 | if (hdspm->tco) { | ||
2426 | switch ((hdspm->settings_register & | ||
2427 | HDSPM_c0_SyncRefMask) / HDSPM_c0_SyncRef0) { | ||
2428 | case 0: return 0; /* WC */ | ||
2429 | case 3: return 1; /* ADAT 1 */ | ||
2430 | case 4: return 2; /* ADAT 2 */ | ||
2431 | case 5: return 3; /* ADAT 3 */ | ||
2432 | case 6: return 4; /* ADAT 4 */ | ||
2433 | case 1: return 5; /* AES */ | ||
2434 | case 2: return 6; /* SPDIF */ | ||
2435 | case 9: return 7; /* TCO */ | ||
2436 | case 10: return 8; /* SYNC_IN */ | ||
2437 | } | ||
2438 | } else { | ||
2439 | switch ((hdspm->settings_register & | ||
2440 | HDSPM_c0_SyncRefMask) / HDSPM_c0_SyncRef0) { | ||
2441 | case 0: return 0; /* WC */ | ||
2442 | case 3: return 1; /* ADAT 1 */ | ||
2443 | case 4: return 2; /* ADAT 2 */ | ||
2444 | case 5: return 3; /* ADAT 3 */ | ||
2445 | case 6: return 4; /* ADAT 4 */ | ||
2446 | case 1: return 5; /* AES */ | ||
2447 | case 2: return 6; /* SPDIF */ | ||
2448 | case 10: return 7; /* SYNC_IN */ | ||
2449 | } | ||
1652 | } | 2450 | } |
2451 | |||
2452 | break; | ||
2453 | |||
2454 | case AIO: | ||
2455 | if (hdspm->tco) { | ||
2456 | switch ((hdspm->settings_register & | ||
2457 | HDSPM_c0_SyncRefMask) / HDSPM_c0_SyncRef0) { | ||
2458 | case 0: return 0; /* WC */ | ||
2459 | case 3: return 1; /* ADAT */ | ||
2460 | case 1: return 2; /* AES */ | ||
2461 | case 2: return 3; /* SPDIF */ | ||
2462 | case 9: return 4; /* TCO */ | ||
2463 | case 10: return 5; /* SYNC_IN */ | ||
2464 | } | ||
2465 | } else { | ||
2466 | switch ((hdspm->settings_register & | ||
2467 | HDSPM_c0_SyncRefMask) / HDSPM_c0_SyncRef0) { | ||
2468 | case 0: return 0; /* WC */ | ||
2469 | case 3: return 1; /* ADAT */ | ||
2470 | case 1: return 2; /* AES */ | ||
2471 | case 2: return 3; /* SPDIF */ | ||
2472 | case 10: return 4; /* SYNC_IN */ | ||
2473 | } | ||
2474 | } | ||
2475 | |||
2476 | break; | ||
1653 | } | 2477 | } |
1654 | 2478 | ||
1655 | return HDSPM_SYNC_FROM_WORD; | 2479 | return -1; |
1656 | } | 2480 | } |
1657 | 2481 | ||
2482 | |||
2483 | /** | ||
2484 | * Set the preferred sync reference to <pref>. The semantics | ||
2485 | * of <pref> are depending on the card type, see the comments | ||
2486 | * for clarification. | ||
2487 | **/ | ||
1658 | static int hdspm_set_pref_sync_ref(struct hdspm * hdspm, int pref) | 2488 | static int hdspm_set_pref_sync_ref(struct hdspm * hdspm, int pref) |
1659 | { | 2489 | { |
1660 | hdspm->control_register &= ~HDSPM_SyncRefMask; | 2490 | int p = 0; |
1661 | 2491 | ||
1662 | if (hdspm->is_aes32) { | 2492 | switch (hdspm->io_type) { |
1663 | switch (pref) { | 2493 | case AES32: |
1664 | case 0: | 2494 | hdspm->control_register &= ~HDSPM_SyncRefMask; |
1665 | hdspm->control_register |= 0; | ||
1666 | break; | ||
1667 | case 1: | ||
1668 | hdspm->control_register |= HDSPM_SyncRef0; | ||
1669 | break; | ||
1670 | case 2: | ||
1671 | hdspm->control_register |= HDSPM_SyncRef1; | ||
1672 | break; | ||
1673 | case 3: | ||
1674 | hdspm->control_register |= HDSPM_SyncRef1+HDSPM_SyncRef0; | ||
1675 | break; | ||
1676 | case 4: | ||
1677 | hdspm->control_register |= HDSPM_SyncRef2; | ||
1678 | break; | ||
1679 | case 5: | ||
1680 | hdspm->control_register |= HDSPM_SyncRef2+HDSPM_SyncRef0; | ||
1681 | break; | ||
1682 | case 6: | ||
1683 | hdspm->control_register |= HDSPM_SyncRef2+HDSPM_SyncRef1; | ||
1684 | break; | ||
1685 | case 7: | ||
1686 | hdspm->control_register |= | ||
1687 | HDSPM_SyncRef2+HDSPM_SyncRef1+HDSPM_SyncRef0; | ||
1688 | break; | ||
1689 | case 8: | ||
1690 | hdspm->control_register |= HDSPM_SyncRef3; | ||
1691 | break; | ||
1692 | default: | ||
1693 | return -1; | ||
1694 | } | ||
1695 | } else { | ||
1696 | switch (pref) { | 2495 | switch (pref) { |
1697 | case HDSPM_SYNC_FROM_MADI: | 2496 | case 0: /* WC */ |
1698 | hdspm->control_register |= HDSPM_SyncRef_MADI; | 2497 | break; |
2498 | case 1: /* AES 1 */ | ||
2499 | hdspm->control_register |= HDSPM_SyncRef0; | ||
2500 | break; | ||
2501 | case 2: /* AES 2 */ | ||
2502 | hdspm->control_register |= HDSPM_SyncRef1; | ||
2503 | break; | ||
2504 | case 3: /* AES 3 */ | ||
2505 | hdspm->control_register |= | ||
2506 | HDSPM_SyncRef1+HDSPM_SyncRef0; | ||
2507 | break; | ||
2508 | case 4: /* AES 4 */ | ||
2509 | hdspm->control_register |= HDSPM_SyncRef2; | ||
2510 | break; | ||
2511 | case 5: /* AES 5 */ | ||
2512 | hdspm->control_register |= | ||
2513 | HDSPM_SyncRef2+HDSPM_SyncRef0; | ||
1699 | break; | 2514 | break; |
1700 | case HDSPM_SYNC_FROM_WORD: | 2515 | case 6: /* AES 6 */ |
1701 | hdspm->control_register |= HDSPM_SyncRef_Word; | 2516 | hdspm->control_register |= |
2517 | HDSPM_SyncRef2+HDSPM_SyncRef1; | ||
2518 | break; | ||
2519 | case 7: /* AES 7 */ | ||
2520 | hdspm->control_register |= | ||
2521 | HDSPM_SyncRef2+HDSPM_SyncRef1+HDSPM_SyncRef0; | ||
2522 | break; | ||
2523 | case 8: /* AES 8 */ | ||
2524 | hdspm->control_register |= HDSPM_SyncRef3; | ||
2525 | break; | ||
2526 | case 9: /* TCO */ | ||
2527 | hdspm->control_register |= | ||
2528 | HDSPM_SyncRef3+HDSPM_SyncRef0; | ||
1702 | break; | 2529 | break; |
1703 | default: | 2530 | default: |
1704 | return -1; | 2531 | return -1; |
1705 | } | 2532 | } |
2533 | |||
2534 | break; | ||
2535 | |||
2536 | case MADI: | ||
2537 | case MADIface: | ||
2538 | hdspm->control_register &= ~HDSPM_SyncRefMask; | ||
2539 | if (hdspm->tco) { | ||
2540 | switch (pref) { | ||
2541 | case 0: /* WC */ | ||
2542 | break; | ||
2543 | case 1: /* MADI */ | ||
2544 | hdspm->control_register |= HDSPM_SyncRef0; | ||
2545 | break; | ||
2546 | case 2: /* TCO */ | ||
2547 | hdspm->control_register |= HDSPM_SyncRef1; | ||
2548 | break; | ||
2549 | case 3: /* SYNC_IN */ | ||
2550 | hdspm->control_register |= | ||
2551 | HDSPM_SyncRef0+HDSPM_SyncRef1; | ||
2552 | break; | ||
2553 | default: | ||
2554 | return -1; | ||
2555 | } | ||
2556 | } else { | ||
2557 | switch (pref) { | ||
2558 | case 0: /* WC */ | ||
2559 | break; | ||
2560 | case 1: /* MADI */ | ||
2561 | hdspm->control_register |= HDSPM_SyncRef0; | ||
2562 | break; | ||
2563 | case 2: /* SYNC_IN */ | ||
2564 | hdspm->control_register |= | ||
2565 | HDSPM_SyncRef0+HDSPM_SyncRef1; | ||
2566 | break; | ||
2567 | default: | ||
2568 | return -1; | ||
2569 | } | ||
2570 | } | ||
2571 | |||
2572 | break; | ||
2573 | |||
2574 | case RayDAT: | ||
2575 | if (hdspm->tco) { | ||
2576 | switch (pref) { | ||
2577 | case 0: p = 0; break; /* WC */ | ||
2578 | case 1: p = 3; break; /* ADAT 1 */ | ||
2579 | case 2: p = 4; break; /* ADAT 2 */ | ||
2580 | case 3: p = 5; break; /* ADAT 3 */ | ||
2581 | case 4: p = 6; break; /* ADAT 4 */ | ||
2582 | case 5: p = 1; break; /* AES */ | ||
2583 | case 6: p = 2; break; /* SPDIF */ | ||
2584 | case 7: p = 9; break; /* TCO */ | ||
2585 | case 8: p = 10; break; /* SYNC_IN */ | ||
2586 | default: return -1; | ||
2587 | } | ||
2588 | } else { | ||
2589 | switch (pref) { | ||
2590 | case 0: p = 0; break; /* WC */ | ||
2591 | case 1: p = 3; break; /* ADAT 1 */ | ||
2592 | case 2: p = 4; break; /* ADAT 2 */ | ||
2593 | case 3: p = 5; break; /* ADAT 3 */ | ||
2594 | case 4: p = 6; break; /* ADAT 4 */ | ||
2595 | case 5: p = 1; break; /* AES */ | ||
2596 | case 6: p = 2; break; /* SPDIF */ | ||
2597 | case 7: p = 10; break; /* SYNC_IN */ | ||
2598 | default: return -1; | ||
2599 | } | ||
2600 | } | ||
2601 | break; | ||
2602 | |||
2603 | case AIO: | ||
2604 | if (hdspm->tco) { | ||
2605 | switch (pref) { | ||
2606 | case 0: p = 0; break; /* WC */ | ||
2607 | case 1: p = 3; break; /* ADAT */ | ||
2608 | case 2: p = 1; break; /* AES */ | ||
2609 | case 3: p = 2; break; /* SPDIF */ | ||
2610 | case 4: p = 9; break; /* TCO */ | ||
2611 | case 5: p = 10; break; /* SYNC_IN */ | ||
2612 | default: return -1; | ||
2613 | } | ||
2614 | } else { | ||
2615 | switch (pref) { | ||
2616 | case 0: p = 0; break; /* WC */ | ||
2617 | case 1: p = 3; break; /* ADAT */ | ||
2618 | case 2: p = 1; break; /* AES */ | ||
2619 | case 3: p = 2; break; /* SPDIF */ | ||
2620 | case 4: p = 10; break; /* SYNC_IN */ | ||
2621 | default: return -1; | ||
2622 | } | ||
2623 | } | ||
2624 | break; | ||
1706 | } | 2625 | } |
1707 | hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register); | 2626 | |
2627 | switch (hdspm->io_type) { | ||
2628 | case RayDAT: | ||
2629 | case AIO: | ||
2630 | hdspm->settings_register &= ~HDSPM_c0_SyncRefMask; | ||
2631 | hdspm->settings_register |= HDSPM_c0_SyncRef0 * p; | ||
2632 | hdspm_write(hdspm, HDSPM_WR_SETTINGS, hdspm->settings_register); | ||
2633 | break; | ||
2634 | |||
2635 | case MADI: | ||
2636 | case MADIface: | ||
2637 | case AES32: | ||
2638 | hdspm_write(hdspm, HDSPM_controlRegister, | ||
2639 | hdspm->control_register); | ||
2640 | } | ||
2641 | |||
1708 | return 0; | 2642 | return 0; |
1709 | } | 2643 | } |
1710 | 2644 | ||
2645 | |||
1711 | static int snd_hdspm_info_pref_sync_ref(struct snd_kcontrol *kcontrol, | 2646 | static int snd_hdspm_info_pref_sync_ref(struct snd_kcontrol *kcontrol, |
1712 | struct snd_ctl_elem_info *uinfo) | 2647 | struct snd_ctl_elem_info *uinfo) |
1713 | { | 2648 | { |
1714 | struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); | 2649 | struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); |
1715 | 2650 | ||
1716 | if (hdspm->is_aes32) { | 2651 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; |
1717 | static char *texts[] = { "Word", "AES1", "AES2", "AES3", | 2652 | uinfo->count = 1; |
1718 | "AES4", "AES5", "AES6", "AES7", "AES8" }; | 2653 | uinfo->value.enumerated.items = hdspm->texts_autosync_items; |
1719 | |||
1720 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
1721 | uinfo->count = 1; | ||
1722 | |||
1723 | uinfo->value.enumerated.items = 9; | ||
1724 | |||
1725 | if (uinfo->value.enumerated.item >= | ||
1726 | uinfo->value.enumerated.items) | ||
1727 | uinfo->value.enumerated.item = | ||
1728 | uinfo->value.enumerated.items - 1; | ||
1729 | strcpy(uinfo->value.enumerated.name, | ||
1730 | texts[uinfo->value.enumerated.item]); | ||
1731 | } else { | ||
1732 | static char *texts[] = { "Word", "MADI" }; | ||
1733 | 2654 | ||
1734 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 2655 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) |
1735 | uinfo->count = 1; | 2656 | uinfo->value.enumerated.item = |
2657 | uinfo->value.enumerated.items - 1; | ||
1736 | 2658 | ||
1737 | uinfo->value.enumerated.items = 2; | 2659 | strcpy(uinfo->value.enumerated.name, |
2660 | hdspm->texts_autosync[uinfo->value.enumerated.item]); | ||
1738 | 2661 | ||
1739 | if (uinfo->value.enumerated.item >= | ||
1740 | uinfo->value.enumerated.items) | ||
1741 | uinfo->value.enumerated.item = | ||
1742 | uinfo->value.enumerated.items - 1; | ||
1743 | strcpy(uinfo->value.enumerated.name, | ||
1744 | texts[uinfo->value.enumerated.item]); | ||
1745 | } | ||
1746 | return 0; | 2662 | return 0; |
1747 | } | 2663 | } |
1748 | 2664 | ||
@@ -1750,32 +2666,41 @@ static int snd_hdspm_get_pref_sync_ref(struct snd_kcontrol *kcontrol, | |||
1750 | struct snd_ctl_elem_value *ucontrol) | 2666 | struct snd_ctl_elem_value *ucontrol) |
1751 | { | 2667 | { |
1752 | struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); | 2668 | struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); |
2669 | int psf = hdspm_pref_sync_ref(hdspm); | ||
1753 | 2670 | ||
1754 | ucontrol->value.enumerated.item[0] = hdspm_pref_sync_ref(hdspm); | 2671 | if (psf >= 0) { |
1755 | return 0; | 2672 | ucontrol->value.enumerated.item[0] = psf; |
2673 | return 0; | ||
2674 | } | ||
2675 | |||
2676 | return -1; | ||
1756 | } | 2677 | } |
1757 | 2678 | ||
1758 | static int snd_hdspm_put_pref_sync_ref(struct snd_kcontrol *kcontrol, | 2679 | static int snd_hdspm_put_pref_sync_ref(struct snd_kcontrol *kcontrol, |
1759 | struct snd_ctl_elem_value *ucontrol) | 2680 | struct snd_ctl_elem_value *ucontrol) |
1760 | { | 2681 | { |
1761 | struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); | 2682 | struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); |
1762 | int change, max; | 2683 | int val, change = 0; |
1763 | unsigned int val; | ||
1764 | |||
1765 | max = hdspm->is_aes32 ? 9 : 2; | ||
1766 | 2684 | ||
1767 | if (!snd_hdspm_use_is_exclusive(hdspm)) | 2685 | if (!snd_hdspm_use_is_exclusive(hdspm)) |
1768 | return -EBUSY; | 2686 | return -EBUSY; |
1769 | 2687 | ||
1770 | val = ucontrol->value.enumerated.item[0] % max; | 2688 | val = ucontrol->value.enumerated.item[0]; |
2689 | |||
2690 | if (val < 0) | ||
2691 | val = 0; | ||
2692 | else if (val >= hdspm->texts_autosync_items) | ||
2693 | val = hdspm->texts_autosync_items-1; | ||
1771 | 2694 | ||
1772 | spin_lock_irq(&hdspm->lock); | 2695 | spin_lock_irq(&hdspm->lock); |
1773 | change = (int) val != hdspm_pref_sync_ref(hdspm); | 2696 | if (val != hdspm_pref_sync_ref(hdspm)) |
1774 | hdspm_set_pref_sync_ref(hdspm, val); | 2697 | change = (0 == hdspm_set_pref_sync_ref(hdspm, val)) ? 1 : 0; |
2698 | |||
1775 | spin_unlock_irq(&hdspm->lock); | 2699 | spin_unlock_irq(&hdspm->lock); |
1776 | return change; | 2700 | return change; |
1777 | } | 2701 | } |
1778 | 2702 | ||
2703 | |||
1779 | #define HDSPM_AUTOSYNC_REF(xname, xindex) \ | 2704 | #define HDSPM_AUTOSYNC_REF(xname, xindex) \ |
1780 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | 2705 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
1781 | .name = xname, \ | 2706 | .name = xname, \ |
@@ -1785,18 +2710,18 @@ static int snd_hdspm_put_pref_sync_ref(struct snd_kcontrol *kcontrol, | |||
1785 | .get = snd_hdspm_get_autosync_ref, \ | 2710 | .get = snd_hdspm_get_autosync_ref, \ |
1786 | } | 2711 | } |
1787 | 2712 | ||
1788 | static int hdspm_autosync_ref(struct hdspm * hdspm) | 2713 | static int hdspm_autosync_ref(struct hdspm *hdspm) |
1789 | { | 2714 | { |
1790 | if (hdspm->is_aes32) { | 2715 | if (AES32 == hdspm->io_type) { |
1791 | unsigned int status = hdspm_read(hdspm, HDSPM_statusRegister); | 2716 | unsigned int status = hdspm_read(hdspm, HDSPM_statusRegister); |
1792 | unsigned int syncref = (status >> HDSPM_AES32_syncref_bit) & | 2717 | unsigned int syncref = |
1793 | 0xF; | 2718 | (status >> HDSPM_AES32_syncref_bit) & 0xF; |
1794 | if (syncref == 0) | 2719 | if (syncref == 0) |
1795 | return HDSPM_AES32_AUTOSYNC_FROM_WORD; | 2720 | return HDSPM_AES32_AUTOSYNC_FROM_WORD; |
1796 | if (syncref <= 8) | 2721 | if (syncref <= 8) |
1797 | return syncref; | 2722 | return syncref; |
1798 | return HDSPM_AES32_AUTOSYNC_FROM_NONE; | 2723 | return HDSPM_AES32_AUTOSYNC_FROM_NONE; |
1799 | } else { | 2724 | } else if (MADI == hdspm->io_type) { |
1800 | /* This looks at the autosync selected sync reference */ | 2725 | /* This looks at the autosync selected sync reference */ |
1801 | unsigned int status2 = hdspm_read(hdspm, HDSPM_statusRegister2); | 2726 | unsigned int status2 = hdspm_read(hdspm, HDSPM_statusRegister2); |
1802 | 2727 | ||
@@ -1805,22 +2730,27 @@ static int hdspm_autosync_ref(struct hdspm * hdspm) | |||
1805 | return HDSPM_AUTOSYNC_FROM_WORD; | 2730 | return HDSPM_AUTOSYNC_FROM_WORD; |
1806 | case HDSPM_SelSyncRef_MADI: | 2731 | case HDSPM_SelSyncRef_MADI: |
1807 | return HDSPM_AUTOSYNC_FROM_MADI; | 2732 | return HDSPM_AUTOSYNC_FROM_MADI; |
2733 | case HDSPM_SelSyncRef_TCO: | ||
2734 | return HDSPM_AUTOSYNC_FROM_TCO; | ||
2735 | case HDSPM_SelSyncRef_SyncIn: | ||
2736 | return HDSPM_AUTOSYNC_FROM_SYNC_IN; | ||
1808 | case HDSPM_SelSyncRef_NVALID: | 2737 | case HDSPM_SelSyncRef_NVALID: |
1809 | return HDSPM_AUTOSYNC_FROM_NONE; | 2738 | return HDSPM_AUTOSYNC_FROM_NONE; |
1810 | default: | 2739 | default: |
1811 | return 0; | 2740 | return 0; |
1812 | } | 2741 | } |
1813 | 2742 | ||
1814 | return 0; | ||
1815 | } | 2743 | } |
2744 | return 0; | ||
1816 | } | 2745 | } |
1817 | 2746 | ||
2747 | |||
1818 | static int snd_hdspm_info_autosync_ref(struct snd_kcontrol *kcontrol, | 2748 | static int snd_hdspm_info_autosync_ref(struct snd_kcontrol *kcontrol, |
1819 | struct snd_ctl_elem_info *uinfo) | 2749 | struct snd_ctl_elem_info *uinfo) |
1820 | { | 2750 | { |
1821 | struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); | 2751 | struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); |
1822 | 2752 | ||
1823 | if (hdspm->is_aes32) { | 2753 | if (AES32 == hdspm->io_type) { |
1824 | static char *texts[] = { "WordClock", "AES1", "AES2", "AES3", | 2754 | static char *texts[] = { "WordClock", "AES1", "AES2", "AES3", |
1825 | "AES4", "AES5", "AES6", "AES7", "AES8", "None"}; | 2755 | "AES4", "AES5", "AES6", "AES7", "AES8", "None"}; |
1826 | 2756 | ||
@@ -1833,14 +2763,15 @@ static int snd_hdspm_info_autosync_ref(struct snd_kcontrol *kcontrol, | |||
1833 | uinfo->value.enumerated.items - 1; | 2763 | uinfo->value.enumerated.items - 1; |
1834 | strcpy(uinfo->value.enumerated.name, | 2764 | strcpy(uinfo->value.enumerated.name, |
1835 | texts[uinfo->value.enumerated.item]); | 2765 | texts[uinfo->value.enumerated.item]); |
1836 | } else { | 2766 | } else if (MADI == hdspm->io_type) { |
1837 | static char *texts[] = { "WordClock", "MADI", "None" }; | 2767 | static char *texts[] = {"Word Clock", "MADI", "TCO", |
2768 | "Sync In", "None" }; | ||
1838 | 2769 | ||
1839 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 2770 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; |
1840 | uinfo->count = 1; | 2771 | uinfo->count = 1; |
1841 | uinfo->value.enumerated.items = 3; | 2772 | uinfo->value.enumerated.items = 5; |
1842 | if (uinfo->value.enumerated.item >= | 2773 | if (uinfo->value.enumerated.item >= |
1843 | uinfo->value.enumerated.items) | 2774 | uinfo->value.enumerated.items) |
1844 | uinfo->value.enumerated.item = | 2775 | uinfo->value.enumerated.item = |
1845 | uinfo->value.enumerated.items - 1; | 2776 | uinfo->value.enumerated.items - 1; |
1846 | strcpy(uinfo->value.enumerated.name, | 2777 | strcpy(uinfo->value.enumerated.name, |
@@ -1858,6 +2789,7 @@ static int snd_hdspm_get_autosync_ref(struct snd_kcontrol *kcontrol, | |||
1858 | return 0; | 2789 | return 0; |
1859 | } | 2790 | } |
1860 | 2791 | ||
2792 | |||
1861 | #define HDSPM_LINE_OUT(xname, xindex) \ | 2793 | #define HDSPM_LINE_OUT(xname, xindex) \ |
1862 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | 2794 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
1863 | .name = xname, \ | 2795 | .name = xname, \ |
@@ -1914,6 +2846,7 @@ static int snd_hdspm_put_line_out(struct snd_kcontrol *kcontrol, | |||
1914 | return change; | 2846 | return change; |
1915 | } | 2847 | } |
1916 | 2848 | ||
2849 | |||
1917 | #define HDSPM_TX_64(xname, xindex) \ | 2850 | #define HDSPM_TX_64(xname, xindex) \ |
1918 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | 2851 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
1919 | .name = xname, \ | 2852 | .name = xname, \ |
@@ -1969,6 +2902,7 @@ static int snd_hdspm_put_tx_64(struct snd_kcontrol *kcontrol, | |||
1969 | return change; | 2902 | return change; |
1970 | } | 2903 | } |
1971 | 2904 | ||
2905 | |||
1972 | #define HDSPM_C_TMS(xname, xindex) \ | 2906 | #define HDSPM_C_TMS(xname, xindex) \ |
1973 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | 2907 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
1974 | .name = xname, \ | 2908 | .name = xname, \ |
@@ -2024,6 +2958,7 @@ static int snd_hdspm_put_c_tms(struct snd_kcontrol *kcontrol, | |||
2024 | return change; | 2958 | return change; |
2025 | } | 2959 | } |
2026 | 2960 | ||
2961 | |||
2027 | #define HDSPM_SAFE_MODE(xname, xindex) \ | 2962 | #define HDSPM_SAFE_MODE(xname, xindex) \ |
2028 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | 2963 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
2029 | .name = xname, \ | 2964 | .name = xname, \ |
@@ -2079,6 +3014,7 @@ static int snd_hdspm_put_safe_mode(struct snd_kcontrol *kcontrol, | |||
2079 | return change; | 3014 | return change; |
2080 | } | 3015 | } |
2081 | 3016 | ||
3017 | |||
2082 | #define HDSPM_EMPHASIS(xname, xindex) \ | 3018 | #define HDSPM_EMPHASIS(xname, xindex) \ |
2083 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | 3019 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
2084 | .name = xname, \ | 3020 | .name = xname, \ |
@@ -2134,6 +3070,7 @@ static int snd_hdspm_put_emphasis(struct snd_kcontrol *kcontrol, | |||
2134 | return change; | 3070 | return change; |
2135 | } | 3071 | } |
2136 | 3072 | ||
3073 | |||
2137 | #define HDSPM_DOLBY(xname, xindex) \ | 3074 | #define HDSPM_DOLBY(xname, xindex) \ |
2138 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | 3075 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
2139 | .name = xname, \ | 3076 | .name = xname, \ |
@@ -2189,6 +3126,7 @@ static int snd_hdspm_put_dolby(struct snd_kcontrol *kcontrol, | |||
2189 | return change; | 3126 | return change; |
2190 | } | 3127 | } |
2191 | 3128 | ||
3129 | |||
2192 | #define HDSPM_PROFESSIONAL(xname, xindex) \ | 3130 | #define HDSPM_PROFESSIONAL(xname, xindex) \ |
2193 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | 3131 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
2194 | .name = xname, \ | 3132 | .name = xname, \ |
@@ -2315,6 +3253,7 @@ static int snd_hdspm_put_input_select(struct snd_kcontrol *kcontrol, | |||
2315 | return change; | 3253 | return change; |
2316 | } | 3254 | } |
2317 | 3255 | ||
3256 | |||
2318 | #define HDSPM_DS_WIRE(xname, xindex) \ | 3257 | #define HDSPM_DS_WIRE(xname, xindex) \ |
2319 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | 3258 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
2320 | .name = xname, \ | 3259 | .name = xname, \ |
@@ -2386,6 +3325,7 @@ static int snd_hdspm_put_ds_wire(struct snd_kcontrol *kcontrol, | |||
2386 | return change; | 3325 | return change; |
2387 | } | 3326 | } |
2388 | 3327 | ||
3328 | |||
2389 | #define HDSPM_QS_WIRE(xname, xindex) \ | 3329 | #define HDSPM_QS_WIRE(xname, xindex) \ |
2390 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | 3330 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
2391 | .name = xname, \ | 3331 | .name = xname, \ |
@@ -2472,15 +3412,6 @@ static int snd_hdspm_put_qs_wire(struct snd_kcontrol *kcontrol, | |||
2472 | return change; | 3412 | return change; |
2473 | } | 3413 | } |
2474 | 3414 | ||
2475 | /* Simple Mixer | ||
2476 | deprecated since to much faders ??? | ||
2477 | MIXER interface says output (source, destination, value) | ||
2478 | where source > MAX_channels are playback channels | ||
2479 | on MADICARD | ||
2480 | - playback mixer matrix: [channelout+64] [output] [value] | ||
2481 | - input(thru) mixer matrix: [channelin] [output] [value] | ||
2482 | (better do 2 kontrols for separation ?) | ||
2483 | */ | ||
2484 | 3415 | ||
2485 | #define HDSPM_MIXER(xname, xindex) \ | 3416 | #define HDSPM_MIXER(xname, xindex) \ |
2486 | { .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ | 3417 | { .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ |
@@ -2586,7 +3517,7 @@ static int snd_hdspm_put_mixer(struct snd_kcontrol *kcontrol, | |||
2586 | 3517 | ||
2587 | /* The simple mixer control(s) provide gain control for the | 3518 | /* The simple mixer control(s) provide gain control for the |
2588 | basic 1:1 mappings of playback streams to output | 3519 | basic 1:1 mappings of playback streams to output |
2589 | streams. | 3520 | streams. |
2590 | */ | 3521 | */ |
2591 | 3522 | ||
2592 | #define HDSPM_PLAYBACK_MIXER \ | 3523 | #define HDSPM_PLAYBACK_MIXER \ |
@@ -2604,7 +3535,7 @@ static int snd_hdspm_info_playback_mixer(struct snd_kcontrol *kcontrol, | |||
2604 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | 3535 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; |
2605 | uinfo->count = 1; | 3536 | uinfo->count = 1; |
2606 | uinfo->value.integer.min = 0; | 3537 | uinfo->value.integer.min = 0; |
2607 | uinfo->value.integer.max = 65536; | 3538 | uinfo->value.integer.max = 64; |
2608 | uinfo->value.integer.step = 1; | 3539 | uinfo->value.integer.step = 1; |
2609 | return 0; | 3540 | return 0; |
2610 | } | 3541 | } |
@@ -2614,28 +3545,17 @@ static int snd_hdspm_get_playback_mixer(struct snd_kcontrol *kcontrol, | |||
2614 | { | 3545 | { |
2615 | struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); | 3546 | struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); |
2616 | int channel; | 3547 | int channel; |
2617 | int mapped_channel; | ||
2618 | 3548 | ||
2619 | channel = ucontrol->id.index - 1; | 3549 | channel = ucontrol->id.index - 1; |
2620 | 3550 | ||
2621 | if (snd_BUG_ON(channel < 0 || channel >= HDSPM_MAX_CHANNELS)) | 3551 | if (snd_BUG_ON(channel < 0 || channel >= HDSPM_MAX_CHANNELS)) |
2622 | return -EINVAL; | 3552 | return -EINVAL; |
2623 | 3553 | ||
2624 | mapped_channel = hdspm->channel_map[channel]; | ||
2625 | if (mapped_channel < 0) | ||
2626 | return -EINVAL; | ||
2627 | |||
2628 | spin_lock_irq(&hdspm->lock); | 3554 | spin_lock_irq(&hdspm->lock); |
2629 | ucontrol->value.integer.value[0] = | 3555 | ucontrol->value.integer.value[0] = |
2630 | hdspm_read_pb_gain(hdspm, mapped_channel, mapped_channel); | 3556 | (hdspm_read_pb_gain(hdspm, channel, channel)*64)/UNITY_GAIN; |
2631 | spin_unlock_irq(&hdspm->lock); | 3557 | spin_unlock_irq(&hdspm->lock); |
2632 | 3558 | ||
2633 | /* | ||
2634 | snd_printdd("get pb mixer index %d, channel %d, mapped_channel %d, " | ||
2635 | "value %d\n", | ||
2636 | ucontrol->id.index, channel, mapped_channel, | ||
2637 | ucontrol->value.integer.value[0]); | ||
2638 | */ | ||
2639 | return 0; | 3559 | return 0; |
2640 | } | 3560 | } |
2641 | 3561 | ||
@@ -2645,7 +3565,6 @@ static int snd_hdspm_put_playback_mixer(struct snd_kcontrol *kcontrol, | |||
2645 | struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); | 3565 | struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); |
2646 | int change; | 3566 | int change; |
2647 | int channel; | 3567 | int channel; |
2648 | int mapped_channel; | ||
2649 | int gain; | 3568 | int gain; |
2650 | 3569 | ||
2651 | if (!snd_hdspm_use_is_exclusive(hdspm)) | 3570 | if (!snd_hdspm_use_is_exclusive(hdspm)) |
@@ -2656,59 +3575,60 @@ static int snd_hdspm_put_playback_mixer(struct snd_kcontrol *kcontrol, | |||
2656 | if (snd_BUG_ON(channel < 0 || channel >= HDSPM_MAX_CHANNELS)) | 3575 | if (snd_BUG_ON(channel < 0 || channel >= HDSPM_MAX_CHANNELS)) |
2657 | return -EINVAL; | 3576 | return -EINVAL; |
2658 | 3577 | ||
2659 | mapped_channel = hdspm->channel_map[channel]; | 3578 | gain = ucontrol->value.integer.value[0]*UNITY_GAIN/64; |
2660 | if (mapped_channel < 0) | ||
2661 | return -EINVAL; | ||
2662 | |||
2663 | gain = ucontrol->value.integer.value[0]; | ||
2664 | 3579 | ||
2665 | spin_lock_irq(&hdspm->lock); | 3580 | spin_lock_irq(&hdspm->lock); |
2666 | change = | 3581 | change = |
2667 | gain != hdspm_read_pb_gain(hdspm, mapped_channel, | 3582 | gain != hdspm_read_pb_gain(hdspm, channel, |
2668 | mapped_channel); | 3583 | channel); |
2669 | if (change) | 3584 | if (change) |
2670 | hdspm_write_pb_gain(hdspm, mapped_channel, mapped_channel, | 3585 | hdspm_write_pb_gain(hdspm, channel, channel, |
2671 | gain); | 3586 | gain); |
2672 | spin_unlock_irq(&hdspm->lock); | 3587 | spin_unlock_irq(&hdspm->lock); |
2673 | return change; | 3588 | return change; |
2674 | } | 3589 | } |
2675 | 3590 | ||
2676 | #define HDSPM_WC_SYNC_CHECK(xname, xindex) \ | 3591 | #define HDSPM_SYNC_CHECK(xname, xindex) \ |
2677 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | 3592 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
2678 | .name = xname, \ | 3593 | .name = xname, \ |
2679 | .index = xindex, \ | 3594 | .private_value = xindex, \ |
2680 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ | 3595 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ |
2681 | .info = snd_hdspm_info_sync_check, \ | 3596 | .info = snd_hdspm_info_sync_check, \ |
2682 | .get = snd_hdspm_get_wc_sync_check \ | 3597 | .get = snd_hdspm_get_sync_check \ |
2683 | } | 3598 | } |
2684 | 3599 | ||
3600 | |||
2685 | static int snd_hdspm_info_sync_check(struct snd_kcontrol *kcontrol, | 3601 | static int snd_hdspm_info_sync_check(struct snd_kcontrol *kcontrol, |
2686 | struct snd_ctl_elem_info *uinfo) | 3602 | struct snd_ctl_elem_info *uinfo) |
2687 | { | 3603 | { |
2688 | static char *texts[] = { "No Lock", "Lock", "Sync" }; | 3604 | static char *texts[] = { "No Lock", "Lock", "Sync", "N/A" }; |
2689 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 3605 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; |
2690 | uinfo->count = 1; | 3606 | uinfo->count = 1; |
2691 | uinfo->value.enumerated.items = 3; | 3607 | uinfo->value.enumerated.items = 4; |
2692 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | 3608 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) |
2693 | uinfo->value.enumerated.item = | 3609 | uinfo->value.enumerated.item = |
2694 | uinfo->value.enumerated.items - 1; | 3610 | uinfo->value.enumerated.items - 1; |
2695 | strcpy(uinfo->value.enumerated.name, | 3611 | strcpy(uinfo->value.enumerated.name, |
2696 | texts[uinfo->value.enumerated.item]); | 3612 | texts[uinfo->value.enumerated.item]); |
2697 | return 0; | 3613 | return 0; |
2698 | } | 3614 | } |
2699 | 3615 | ||
2700 | static int hdspm_wc_sync_check(struct hdspm * hdspm) | 3616 | static int hdspm_wc_sync_check(struct hdspm *hdspm) |
2701 | { | 3617 | { |
2702 | if (hdspm->is_aes32) { | 3618 | int status, status2; |
2703 | int status = hdspm_read(hdspm, HDSPM_statusRegister); | 3619 | |
2704 | if (status & HDSPM_AES32_wcLock) { | 3620 | switch (hdspm->io_type) { |
2705 | /* I don't know how to differenciate sync from lock. | 3621 | case AES32: |
2706 | Doing as if sync for now */ | 3622 | status = hdspm_read(hdspm, HDSPM_statusRegister); |
3623 | if (status & HDSPM_wcSync) | ||
2707 | return 2; | 3624 | return 2; |
2708 | } | 3625 | else if (status & HDSPM_wcLock) |
3626 | return 1; | ||
2709 | return 0; | 3627 | return 0; |
2710 | } else { | 3628 | break; |
2711 | int status2 = hdspm_read(hdspm, HDSPM_statusRegister2); | 3629 | |
3630 | case MADI: | ||
3631 | status2 = hdspm_read(hdspm, HDSPM_statusRegister2); | ||
2712 | if (status2 & HDSPM_wcLock) { | 3632 | if (status2 & HDSPM_wcLock) { |
2713 | if (status2 & HDSPM_wcSync) | 3633 | if (status2 & HDSPM_wcSync) |
2714 | return 2; | 3634 | return 2; |
@@ -2716,29 +3636,30 @@ static int hdspm_wc_sync_check(struct hdspm * hdspm) | |||
2716 | return 1; | 3636 | return 1; |
2717 | } | 3637 | } |
2718 | return 0; | 3638 | return 0; |
2719 | } | 3639 | break; |
2720 | } | ||
2721 | 3640 | ||
2722 | static int snd_hdspm_get_wc_sync_check(struct snd_kcontrol *kcontrol, | 3641 | case RayDAT: |
2723 | struct snd_ctl_elem_value *ucontrol) | 3642 | case AIO: |
2724 | { | 3643 | status = hdspm_read(hdspm, HDSPM_statusRegister); |
2725 | struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); | ||
2726 | 3644 | ||
2727 | ucontrol->value.enumerated.item[0] = hdspm_wc_sync_check(hdspm); | 3645 | if (status & 0x2000000) |
2728 | return 0; | 3646 | return 2; |
2729 | } | 3647 | else if (status & 0x1000000) |
3648 | return 1; | ||
3649 | return 0; | ||
2730 | 3650 | ||
3651 | break; | ||
2731 | 3652 | ||
2732 | #define HDSPM_MADI_SYNC_CHECK(xname, xindex) \ | 3653 | case MADIface: |
2733 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | 3654 | break; |
2734 | .name = xname, \ | 3655 | } |
2735 | .index = xindex, \ | 3656 | |
2736 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ | 3657 | |
2737 | .info = snd_hdspm_info_sync_check, \ | 3658 | return 3; |
2738 | .get = snd_hdspm_get_madisync_sync_check \ | ||
2739 | } | 3659 | } |
2740 | 3660 | ||
2741 | static int hdspm_madisync_sync_check(struct hdspm * hdspm) | 3661 | |
3662 | static int hdspm_madi_sync_check(struct hdspm *hdspm) | ||
2742 | { | 3663 | { |
2743 | int status = hdspm_read(hdspm, HDSPM_statusRegister); | 3664 | int status = hdspm_read(hdspm, HDSPM_statusRegister); |
2744 | if (status & HDSPM_madiLock) { | 3665 | if (status & HDSPM_madiLock) { |
@@ -2750,89 +3671,726 @@ static int hdspm_madisync_sync_check(struct hdspm * hdspm) | |||
2750 | return 0; | 3671 | return 0; |
2751 | } | 3672 | } |
2752 | 3673 | ||
2753 | static int snd_hdspm_get_madisync_sync_check(struct snd_kcontrol *kcontrol, | 3674 | |
2754 | struct snd_ctl_elem_value * | 3675 | static int hdspm_s1_sync_check(struct hdspm *hdspm, int idx) |
2755 | ucontrol) | ||
2756 | { | 3676 | { |
2757 | struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); | 3677 | int status, lock, sync; |
3678 | |||
3679 | status = hdspm_read(hdspm, HDSPM_RD_STATUS_1); | ||
3680 | |||
3681 | lock = (status & (0x1<<idx)) ? 1 : 0; | ||
3682 | sync = (status & (0x100<<idx)) ? 1 : 0; | ||
2758 | 3683 | ||
2759 | ucontrol->value.enumerated.item[0] = | 3684 | if (lock && sync) |
2760 | hdspm_madisync_sync_check(hdspm); | 3685 | return 2; |
3686 | else if (lock) | ||
3687 | return 1; | ||
2761 | return 0; | 3688 | return 0; |
2762 | } | 3689 | } |
2763 | 3690 | ||
2764 | 3691 | ||
2765 | #define HDSPM_AES_SYNC_CHECK(xname, xindex) \ | 3692 | static int hdspm_sync_in_sync_check(struct hdspm *hdspm) |
2766 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | 3693 | { |
2767 | .name = xname, \ | 3694 | int status, lock = 0, sync = 0; |
2768 | .index = xindex, \ | 3695 | |
2769 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ | 3696 | switch (hdspm->io_type) { |
2770 | .info = snd_hdspm_info_sync_check, \ | 3697 | case RayDAT: |
2771 | .get = snd_hdspm_get_aes_sync_check \ | 3698 | case AIO: |
3699 | status = hdspm_read(hdspm, HDSPM_RD_STATUS_3); | ||
3700 | lock = (status & 0x400) ? 1 : 0; | ||
3701 | sync = (status & 0x800) ? 1 : 0; | ||
3702 | break; | ||
3703 | |||
3704 | case MADI: | ||
3705 | case AES32: | ||
3706 | status = hdspm_read(hdspm, HDSPM_statusRegister2); | ||
3707 | lock = (status & HDSPM_syncInLock) ? 1 : 0; | ||
3708 | sync = (status & HDSPM_syncInSync) ? 1 : 0; | ||
3709 | break; | ||
3710 | |||
3711 | case MADIface: | ||
3712 | break; | ||
3713 | } | ||
3714 | |||
3715 | if (lock && sync) | ||
3716 | return 2; | ||
3717 | else if (lock) | ||
3718 | return 1; | ||
3719 | |||
3720 | return 0; | ||
2772 | } | 3721 | } |
2773 | 3722 | ||
2774 | static int hdspm_aes_sync_check(struct hdspm * hdspm, int idx) | 3723 | static int hdspm_aes_sync_check(struct hdspm *hdspm, int idx) |
2775 | { | 3724 | { |
2776 | int status2 = hdspm_read(hdspm, HDSPM_statusRegister2); | 3725 | int status2, lock, sync; |
2777 | if (status2 & (HDSPM_LockAES >> idx)) { | 3726 | status2 = hdspm_read(hdspm, HDSPM_statusRegister2); |
2778 | /* I don't know how to differenciate sync from lock. | 3727 | |
2779 | Doing as if sync for now */ | 3728 | lock = (status2 & (0x0080 >> idx)) ? 1 : 0; |
3729 | sync = (status2 & (0x8000 >> idx)) ? 1 : 0; | ||
3730 | |||
3731 | if (sync) | ||
2780 | return 2; | 3732 | return 2; |
3733 | else if (lock) | ||
3734 | return 1; | ||
3735 | return 0; | ||
3736 | } | ||
3737 | |||
3738 | |||
3739 | static int hdspm_tco_sync_check(struct hdspm *hdspm) | ||
3740 | { | ||
3741 | int status; | ||
3742 | |||
3743 | if (hdspm->tco) { | ||
3744 | switch (hdspm->io_type) { | ||
3745 | case MADI: | ||
3746 | case AES32: | ||
3747 | status = hdspm_read(hdspm, HDSPM_statusRegister); | ||
3748 | if (status & HDSPM_tcoLock) { | ||
3749 | if (status & HDSPM_tcoSync) | ||
3750 | return 2; | ||
3751 | else | ||
3752 | return 1; | ||
3753 | } | ||
3754 | return 0; | ||
3755 | |||
3756 | break; | ||
3757 | |||
3758 | case RayDAT: | ||
3759 | case AIO: | ||
3760 | status = hdspm_read(hdspm, HDSPM_RD_STATUS_1); | ||
3761 | |||
3762 | if (status & 0x8000000) | ||
3763 | return 2; /* Sync */ | ||
3764 | if (status & 0x4000000) | ||
3765 | return 1; /* Lock */ | ||
3766 | return 0; /* No signal */ | ||
3767 | break; | ||
3768 | |||
3769 | default: | ||
3770 | break; | ||
3771 | } | ||
3772 | } | ||
3773 | |||
3774 | return 3; /* N/A */ | ||
3775 | } | ||
3776 | |||
3777 | |||
3778 | static int snd_hdspm_get_sync_check(struct snd_kcontrol *kcontrol, | ||
3779 | struct snd_ctl_elem_value *ucontrol) | ||
3780 | { | ||
3781 | struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); | ||
3782 | int val = -1; | ||
3783 | |||
3784 | switch (hdspm->io_type) { | ||
3785 | case RayDAT: | ||
3786 | switch (kcontrol->private_value) { | ||
3787 | case 0: /* WC */ | ||
3788 | val = hdspm_wc_sync_check(hdspm); break; | ||
3789 | case 7: /* TCO */ | ||
3790 | val = hdspm_tco_sync_check(hdspm); break; | ||
3791 | case 8: /* SYNC IN */ | ||
3792 | val = hdspm_sync_in_sync_check(hdspm); break; | ||
3793 | default: | ||
3794 | val = hdspm_s1_sync_check(hdspm, ucontrol->id.index-1); | ||
3795 | } | ||
3796 | |||
3797 | case AIO: | ||
3798 | switch (kcontrol->private_value) { | ||
3799 | case 0: /* WC */ | ||
3800 | val = hdspm_wc_sync_check(hdspm); break; | ||
3801 | case 4: /* TCO */ | ||
3802 | val = hdspm_tco_sync_check(hdspm); break; | ||
3803 | case 5: /* SYNC IN */ | ||
3804 | val = hdspm_sync_in_sync_check(hdspm); break; | ||
3805 | default: | ||
3806 | val = hdspm_s1_sync_check(hdspm, ucontrol->id.index-1); | ||
3807 | } | ||
3808 | |||
3809 | case MADI: | ||
3810 | switch (kcontrol->private_value) { | ||
3811 | case 0: /* WC */ | ||
3812 | val = hdspm_wc_sync_check(hdspm); break; | ||
3813 | case 1: /* MADI */ | ||
3814 | val = hdspm_madi_sync_check(hdspm); break; | ||
3815 | case 2: /* TCO */ | ||
3816 | val = hdspm_tco_sync_check(hdspm); break; | ||
3817 | case 3: /* SYNC_IN */ | ||
3818 | val = hdspm_sync_in_sync_check(hdspm); break; | ||
3819 | } | ||
3820 | |||
3821 | case MADIface: | ||
3822 | val = hdspm_madi_sync_check(hdspm); /* MADI */ | ||
3823 | break; | ||
3824 | |||
3825 | case AES32: | ||
3826 | switch (kcontrol->private_value) { | ||
3827 | case 0: /* WC */ | ||
3828 | val = hdspm_wc_sync_check(hdspm); break; | ||
3829 | case 9: /* TCO */ | ||
3830 | val = hdspm_tco_sync_check(hdspm); break; | ||
3831 | case 10 /* SYNC IN */: | ||
3832 | val = hdspm_sync_in_sync_check(hdspm); break; | ||
3833 | default: /* AES1 to AES8 */ | ||
3834 | val = hdspm_aes_sync_check(hdspm, | ||
3835 | kcontrol->private_value-1); | ||
3836 | } | ||
3837 | |||
2781 | } | 3838 | } |
3839 | |||
3840 | if (-1 == val) | ||
3841 | val = 3; | ||
3842 | |||
3843 | ucontrol->value.enumerated.item[0] = val; | ||
2782 | return 0; | 3844 | return 0; |
2783 | } | 3845 | } |
2784 | 3846 | ||
2785 | static int snd_hdspm_get_aes_sync_check(struct snd_kcontrol *kcontrol, | 3847 | |
3848 | |||
3849 | /** | ||
3850 | * TCO controls | ||
3851 | **/ | ||
3852 | static void hdspm_tco_write(struct hdspm *hdspm) | ||
3853 | { | ||
3854 | unsigned int tc[4] = { 0, 0, 0, 0}; | ||
3855 | |||
3856 | switch (hdspm->tco->input) { | ||
3857 | case 0: | ||
3858 | tc[2] |= HDSPM_TCO2_set_input_MSB; | ||
3859 | break; | ||
3860 | case 1: | ||
3861 | tc[2] |= HDSPM_TCO2_set_input_LSB; | ||
3862 | break; | ||
3863 | default: | ||
3864 | break; | ||
3865 | } | ||
3866 | |||
3867 | switch (hdspm->tco->framerate) { | ||
3868 | case 1: | ||
3869 | tc[1] |= HDSPM_TCO1_LTC_Format_LSB; | ||
3870 | break; | ||
3871 | case 2: | ||
3872 | tc[1] |= HDSPM_TCO1_LTC_Format_MSB; | ||
3873 | break; | ||
3874 | case 3: | ||
3875 | tc[1] |= HDSPM_TCO1_LTC_Format_MSB + | ||
3876 | HDSPM_TCO1_set_drop_frame_flag; | ||
3877 | break; | ||
3878 | case 4: | ||
3879 | tc[1] |= HDSPM_TCO1_LTC_Format_LSB + | ||
3880 | HDSPM_TCO1_LTC_Format_MSB; | ||
3881 | break; | ||
3882 | case 5: | ||
3883 | tc[1] |= HDSPM_TCO1_LTC_Format_LSB + | ||
3884 | HDSPM_TCO1_LTC_Format_MSB + | ||
3885 | HDSPM_TCO1_set_drop_frame_flag; | ||
3886 | break; | ||
3887 | default: | ||
3888 | break; | ||
3889 | } | ||
3890 | |||
3891 | switch (hdspm->tco->wordclock) { | ||
3892 | case 1: | ||
3893 | tc[2] |= HDSPM_TCO2_WCK_IO_ratio_LSB; | ||
3894 | break; | ||
3895 | case 2: | ||
3896 | tc[2] |= HDSPM_TCO2_WCK_IO_ratio_MSB; | ||
3897 | break; | ||
3898 | default: | ||
3899 | break; | ||
3900 | } | ||
3901 | |||
3902 | switch (hdspm->tco->samplerate) { | ||
3903 | case 1: | ||
3904 | tc[2] |= HDSPM_TCO2_set_freq; | ||
3905 | break; | ||
3906 | case 2: | ||
3907 | tc[2] |= HDSPM_TCO2_set_freq_from_app; | ||
3908 | break; | ||
3909 | default: | ||
3910 | break; | ||
3911 | } | ||
3912 | |||
3913 | switch (hdspm->tco->pull) { | ||
3914 | case 1: | ||
3915 | tc[2] |= HDSPM_TCO2_set_pull_up; | ||
3916 | break; | ||
3917 | case 2: | ||
3918 | tc[2] |= HDSPM_TCO2_set_pull_down; | ||
3919 | break; | ||
3920 | case 3: | ||
3921 | tc[2] |= HDSPM_TCO2_set_pull_up + HDSPM_TCO2_set_01_4; | ||
3922 | break; | ||
3923 | case 4: | ||
3924 | tc[2] |= HDSPM_TCO2_set_pull_down + HDSPM_TCO2_set_01_4; | ||
3925 | break; | ||
3926 | default: | ||
3927 | break; | ||
3928 | } | ||
3929 | |||
3930 | if (1 == hdspm->tco->term) { | ||
3931 | tc[2] |= HDSPM_TCO2_set_term_75R; | ||
3932 | } | ||
3933 | |||
3934 | hdspm_write(hdspm, HDSPM_WR_TCO, tc[0]); | ||
3935 | hdspm_write(hdspm, HDSPM_WR_TCO+4, tc[1]); | ||
3936 | hdspm_write(hdspm, HDSPM_WR_TCO+8, tc[2]); | ||
3937 | hdspm_write(hdspm, HDSPM_WR_TCO+12, tc[3]); | ||
3938 | } | ||
3939 | |||
3940 | |||
3941 | #define HDSPM_TCO_SAMPLE_RATE(xname, xindex) \ | ||
3942 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | ||
3943 | .name = xname, \ | ||
3944 | .index = xindex, \ | ||
3945 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\ | ||
3946 | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ | ||
3947 | .info = snd_hdspm_info_tco_sample_rate, \ | ||
3948 | .get = snd_hdspm_get_tco_sample_rate, \ | ||
3949 | .put = snd_hdspm_put_tco_sample_rate \ | ||
3950 | } | ||
3951 | |||
3952 | static int snd_hdspm_info_tco_sample_rate(struct snd_kcontrol *kcontrol, | ||
3953 | struct snd_ctl_elem_info *uinfo) | ||
3954 | { | ||
3955 | static char *texts[] = { "44.1 kHz", "48 kHz" }; | ||
3956 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
3957 | uinfo->count = 1; | ||
3958 | uinfo->value.enumerated.items = 2; | ||
3959 | |||
3960 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | ||
3961 | uinfo->value.enumerated.item = | ||
3962 | uinfo->value.enumerated.items - 1; | ||
3963 | |||
3964 | strcpy(uinfo->value.enumerated.name, | ||
3965 | texts[uinfo->value.enumerated.item]); | ||
3966 | |||
3967 | return 0; | ||
3968 | } | ||
3969 | |||
3970 | static int snd_hdspm_get_tco_sample_rate(struct snd_kcontrol *kcontrol, | ||
3971 | struct snd_ctl_elem_value *ucontrol) | ||
3972 | { | ||
3973 | struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); | ||
3974 | |||
3975 | ucontrol->value.enumerated.item[0] = hdspm->tco->samplerate; | ||
3976 | |||
3977 | return 0; | ||
3978 | } | ||
3979 | |||
3980 | static int snd_hdspm_put_tco_sample_rate(struct snd_kcontrol *kcontrol, | ||
3981 | struct snd_ctl_elem_value *ucontrol) | ||
3982 | { | ||
3983 | struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); | ||
3984 | |||
3985 | if (hdspm->tco->samplerate != ucontrol->value.enumerated.item[0]) { | ||
3986 | hdspm->tco->samplerate = ucontrol->value.enumerated.item[0]; | ||
3987 | |||
3988 | hdspm_tco_write(hdspm); | ||
3989 | |||
3990 | return 1; | ||
3991 | } | ||
3992 | |||
3993 | return 0; | ||
3994 | } | ||
3995 | |||
3996 | |||
3997 | #define HDSPM_TCO_PULL(xname, xindex) \ | ||
3998 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | ||
3999 | .name = xname, \ | ||
4000 | .index = xindex, \ | ||
4001 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\ | ||
4002 | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ | ||
4003 | .info = snd_hdspm_info_tco_pull, \ | ||
4004 | .get = snd_hdspm_get_tco_pull, \ | ||
4005 | .put = snd_hdspm_put_tco_pull \ | ||
4006 | } | ||
4007 | |||
4008 | static int snd_hdspm_info_tco_pull(struct snd_kcontrol *kcontrol, | ||
4009 | struct snd_ctl_elem_info *uinfo) | ||
4010 | { | ||
4011 | static char *texts[] = { "0", "+ 0.1 %", "- 0.1 %", "+ 4 %", "- 4 %" }; | ||
4012 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
4013 | uinfo->count = 1; | ||
4014 | uinfo->value.enumerated.items = 5; | ||
4015 | |||
4016 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | ||
4017 | uinfo->value.enumerated.item = | ||
4018 | uinfo->value.enumerated.items - 1; | ||
4019 | |||
4020 | strcpy(uinfo->value.enumerated.name, | ||
4021 | texts[uinfo->value.enumerated.item]); | ||
4022 | |||
4023 | return 0; | ||
4024 | } | ||
4025 | |||
4026 | static int snd_hdspm_get_tco_pull(struct snd_kcontrol *kcontrol, | ||
4027 | struct snd_ctl_elem_value *ucontrol) | ||
4028 | { | ||
4029 | struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); | ||
4030 | |||
4031 | ucontrol->value.enumerated.item[0] = hdspm->tco->pull; | ||
4032 | |||
4033 | return 0; | ||
4034 | } | ||
4035 | |||
4036 | static int snd_hdspm_put_tco_pull(struct snd_kcontrol *kcontrol, | ||
4037 | struct snd_ctl_elem_value *ucontrol) | ||
4038 | { | ||
4039 | struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); | ||
4040 | |||
4041 | if (hdspm->tco->pull != ucontrol->value.enumerated.item[0]) { | ||
4042 | hdspm->tco->pull = ucontrol->value.enumerated.item[0]; | ||
4043 | |||
4044 | hdspm_tco_write(hdspm); | ||
4045 | |||
4046 | return 1; | ||
4047 | } | ||
4048 | |||
4049 | return 0; | ||
4050 | } | ||
4051 | |||
4052 | #define HDSPM_TCO_WCK_CONVERSION(xname, xindex) \ | ||
4053 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | ||
4054 | .name = xname, \ | ||
4055 | .index = xindex, \ | ||
4056 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\ | ||
4057 | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ | ||
4058 | .info = snd_hdspm_info_tco_wck_conversion, \ | ||
4059 | .get = snd_hdspm_get_tco_wck_conversion, \ | ||
4060 | .put = snd_hdspm_put_tco_wck_conversion \ | ||
4061 | } | ||
4062 | |||
4063 | static int snd_hdspm_info_tco_wck_conversion(struct snd_kcontrol *kcontrol, | ||
4064 | struct snd_ctl_elem_info *uinfo) | ||
4065 | { | ||
4066 | static char *texts[] = { "1:1", "44.1 -> 48", "48 -> 44.1" }; | ||
4067 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
4068 | uinfo->count = 1; | ||
4069 | uinfo->value.enumerated.items = 3; | ||
4070 | |||
4071 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | ||
4072 | uinfo->value.enumerated.item = | ||
4073 | uinfo->value.enumerated.items - 1; | ||
4074 | |||
4075 | strcpy(uinfo->value.enumerated.name, | ||
4076 | texts[uinfo->value.enumerated.item]); | ||
4077 | |||
4078 | return 0; | ||
4079 | } | ||
4080 | |||
4081 | static int snd_hdspm_get_tco_wck_conversion(struct snd_kcontrol *kcontrol, | ||
4082 | struct snd_ctl_elem_value *ucontrol) | ||
4083 | { | ||
4084 | struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); | ||
4085 | |||
4086 | ucontrol->value.enumerated.item[0] = hdspm->tco->wordclock; | ||
4087 | |||
4088 | return 0; | ||
4089 | } | ||
4090 | |||
4091 | static int snd_hdspm_put_tco_wck_conversion(struct snd_kcontrol *kcontrol, | ||
4092 | struct snd_ctl_elem_value *ucontrol) | ||
4093 | { | ||
4094 | struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); | ||
4095 | |||
4096 | if (hdspm->tco->wordclock != ucontrol->value.enumerated.item[0]) { | ||
4097 | hdspm->tco->wordclock = ucontrol->value.enumerated.item[0]; | ||
4098 | |||
4099 | hdspm_tco_write(hdspm); | ||
4100 | |||
4101 | return 1; | ||
4102 | } | ||
4103 | |||
4104 | return 0; | ||
4105 | } | ||
4106 | |||
4107 | |||
4108 | #define HDSPM_TCO_FRAME_RATE(xname, xindex) \ | ||
4109 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | ||
4110 | .name = xname, \ | ||
4111 | .index = xindex, \ | ||
4112 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\ | ||
4113 | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ | ||
4114 | .info = snd_hdspm_info_tco_frame_rate, \ | ||
4115 | .get = snd_hdspm_get_tco_frame_rate, \ | ||
4116 | .put = snd_hdspm_put_tco_frame_rate \ | ||
4117 | } | ||
4118 | |||
4119 | static int snd_hdspm_info_tco_frame_rate(struct snd_kcontrol *kcontrol, | ||
4120 | struct snd_ctl_elem_info *uinfo) | ||
4121 | { | ||
4122 | static char *texts[] = { "24 fps", "25 fps", "29.97fps", | ||
4123 | "29.97 dfps", "30 fps", "30 dfps" }; | ||
4124 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
4125 | uinfo->count = 1; | ||
4126 | uinfo->value.enumerated.items = 6; | ||
4127 | |||
4128 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | ||
4129 | uinfo->value.enumerated.item = | ||
4130 | uinfo->value.enumerated.items - 1; | ||
4131 | |||
4132 | strcpy(uinfo->value.enumerated.name, | ||
4133 | texts[uinfo->value.enumerated.item]); | ||
4134 | |||
4135 | return 0; | ||
4136 | } | ||
4137 | |||
4138 | static int snd_hdspm_get_tco_frame_rate(struct snd_kcontrol *kcontrol, | ||
2786 | struct snd_ctl_elem_value *ucontrol) | 4139 | struct snd_ctl_elem_value *ucontrol) |
2787 | { | 4140 | { |
2788 | int offset; | ||
2789 | struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); | 4141 | struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); |
2790 | 4142 | ||
2791 | offset = ucontrol->id.index - 1; | 4143 | ucontrol->value.enumerated.item[0] = hdspm->tco->framerate; |
2792 | if (offset < 0 || offset >= 8) | ||
2793 | return -EINVAL; | ||
2794 | 4144 | ||
2795 | ucontrol->value.enumerated.item[0] = | ||
2796 | hdspm_aes_sync_check(hdspm, offset); | ||
2797 | return 0; | 4145 | return 0; |
2798 | } | 4146 | } |
2799 | 4147 | ||
4148 | static int snd_hdspm_put_tco_frame_rate(struct snd_kcontrol *kcontrol, | ||
4149 | struct snd_ctl_elem_value *ucontrol) | ||
4150 | { | ||
4151 | struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); | ||
4152 | |||
4153 | if (hdspm->tco->framerate != ucontrol->value.enumerated.item[0]) { | ||
4154 | hdspm->tco->framerate = ucontrol->value.enumerated.item[0]; | ||
2800 | 4155 | ||
2801 | static struct snd_kcontrol_new snd_hdspm_controls_madi[] = { | 4156 | hdspm_tco_write(hdspm); |
4157 | |||
4158 | return 1; | ||
4159 | } | ||
4160 | |||
4161 | return 0; | ||
4162 | } | ||
2802 | 4163 | ||
2803 | HDSPM_MIXER("Mixer", 0), | ||
2804 | /* 'Sample Clock Source' complies with the alsa control naming scheme */ | ||
2805 | HDSPM_CLOCK_SOURCE("Sample Clock Source", 0), | ||
2806 | 4164 | ||
4165 | #define HDSPM_TCO_SYNC_SOURCE(xname, xindex) \ | ||
4166 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | ||
4167 | .name = xname, \ | ||
4168 | .index = xindex, \ | ||
4169 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\ | ||
4170 | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ | ||
4171 | .info = snd_hdspm_info_tco_sync_source, \ | ||
4172 | .get = snd_hdspm_get_tco_sync_source, \ | ||
4173 | .put = snd_hdspm_put_tco_sync_source \ | ||
4174 | } | ||
4175 | |||
4176 | static int snd_hdspm_info_tco_sync_source(struct snd_kcontrol *kcontrol, | ||
4177 | struct snd_ctl_elem_info *uinfo) | ||
4178 | { | ||
4179 | static char *texts[] = { "LTC", "Video", "WCK" }; | ||
4180 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
4181 | uinfo->count = 1; | ||
4182 | uinfo->value.enumerated.items = 3; | ||
4183 | |||
4184 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | ||
4185 | uinfo->value.enumerated.item = | ||
4186 | uinfo->value.enumerated.items - 1; | ||
4187 | |||
4188 | strcpy(uinfo->value.enumerated.name, | ||
4189 | texts[uinfo->value.enumerated.item]); | ||
4190 | |||
4191 | return 0; | ||
4192 | } | ||
4193 | |||
4194 | static int snd_hdspm_get_tco_sync_source(struct snd_kcontrol *kcontrol, | ||
4195 | struct snd_ctl_elem_value *ucontrol) | ||
4196 | { | ||
4197 | struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); | ||
4198 | |||
4199 | ucontrol->value.enumerated.item[0] = hdspm->tco->input; | ||
4200 | |||
4201 | return 0; | ||
4202 | } | ||
4203 | |||
4204 | static int snd_hdspm_put_tco_sync_source(struct snd_kcontrol *kcontrol, | ||
4205 | struct snd_ctl_elem_value *ucontrol) | ||
4206 | { | ||
4207 | struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); | ||
4208 | |||
4209 | if (hdspm->tco->input != ucontrol->value.enumerated.item[0]) { | ||
4210 | hdspm->tco->input = ucontrol->value.enumerated.item[0]; | ||
4211 | |||
4212 | hdspm_tco_write(hdspm); | ||
4213 | |||
4214 | return 1; | ||
4215 | } | ||
4216 | |||
4217 | return 0; | ||
4218 | } | ||
4219 | |||
4220 | |||
4221 | #define HDSPM_TCO_WORD_TERM(xname, xindex) \ | ||
4222 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | ||
4223 | .name = xname, \ | ||
4224 | .index = xindex, \ | ||
4225 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\ | ||
4226 | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ | ||
4227 | .info = snd_hdspm_info_tco_word_term, \ | ||
4228 | .get = snd_hdspm_get_tco_word_term, \ | ||
4229 | .put = snd_hdspm_put_tco_word_term \ | ||
4230 | } | ||
4231 | |||
4232 | static int snd_hdspm_info_tco_word_term(struct snd_kcontrol *kcontrol, | ||
4233 | struct snd_ctl_elem_info *uinfo) | ||
4234 | { | ||
4235 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; | ||
4236 | uinfo->count = 1; | ||
4237 | uinfo->value.integer.min = 0; | ||
4238 | uinfo->value.integer.max = 1; | ||
4239 | |||
4240 | return 0; | ||
4241 | } | ||
4242 | |||
4243 | |||
4244 | static int snd_hdspm_get_tco_word_term(struct snd_kcontrol *kcontrol, | ||
4245 | struct snd_ctl_elem_value *ucontrol) | ||
4246 | { | ||
4247 | struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); | ||
4248 | |||
4249 | ucontrol->value.enumerated.item[0] = hdspm->tco->term; | ||
4250 | |||
4251 | return 0; | ||
4252 | } | ||
4253 | |||
4254 | |||
4255 | static int snd_hdspm_put_tco_word_term(struct snd_kcontrol *kcontrol, | ||
4256 | struct snd_ctl_elem_value *ucontrol) | ||
4257 | { | ||
4258 | struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); | ||
4259 | |||
4260 | if (hdspm->tco->term != ucontrol->value.enumerated.item[0]) { | ||
4261 | hdspm->tco->term = ucontrol->value.enumerated.item[0]; | ||
4262 | |||
4263 | hdspm_tco_write(hdspm); | ||
4264 | |||
4265 | return 1; | ||
4266 | } | ||
4267 | |||
4268 | return 0; | ||
4269 | } | ||
4270 | |||
4271 | |||
4272 | |||
4273 | |||
4274 | static struct snd_kcontrol_new snd_hdspm_controls_madi[] = { | ||
4275 | HDSPM_MIXER("Mixer", 0), | ||
4276 | HDSPM_INTERNAL_CLOCK("Internal Clock", 0), | ||
2807 | HDSPM_SYSTEM_CLOCK_MODE("System Clock Mode", 0), | 4277 | HDSPM_SYSTEM_CLOCK_MODE("System Clock Mode", 0), |
2808 | HDSPM_PREF_SYNC_REF("Preferred Sync Reference", 0), | 4278 | HDSPM_PREF_SYNC_REF("Preferred Sync Reference", 0), |
2809 | HDSPM_AUTOSYNC_REF("AutoSync Reference", 0), | 4279 | HDSPM_AUTOSYNC_REF("AutoSync Reference", 0), |
2810 | HDSPM_SYSTEM_SAMPLE_RATE("System Sample Rate", 0), | 4280 | HDSPM_SYSTEM_SAMPLE_RATE("System Sample Rate", 0), |
2811 | /* 'External Rate' complies with the alsa control naming scheme */ | 4281 | HDSPM_SYNC_CHECK("WC SyncCheck", 0), |
2812 | HDSPM_AUTOSYNC_SAMPLE_RATE("External Rate", 0), | 4282 | HDSPM_SYNC_CHECK("MADI SyncCheck", 1), |
2813 | HDSPM_WC_SYNC_CHECK("Word Clock Lock Status", 0), | 4283 | HDSPM_SYNC_CHECK("TCO SyncCHeck", 2), |
2814 | HDSPM_MADI_SYNC_CHECK("MADI Sync Lock Status", 0), | 4284 | HDSPM_SYNC_CHECK("SYNC IN SyncCheck", 3), |
2815 | HDSPM_LINE_OUT("Line Out", 0), | 4285 | HDSPM_LINE_OUT("Line Out", 0), |
2816 | HDSPM_TX_64("TX 64 channels mode", 0), | 4286 | HDSPM_TX_64("TX 64 channels mode", 0), |
2817 | HDSPM_C_TMS("Clear Track Marker", 0), | 4287 | HDSPM_C_TMS("Clear Track Marker", 0), |
2818 | HDSPM_SAFE_MODE("Safe Mode", 0), | 4288 | HDSPM_SAFE_MODE("Safe Mode", 0), |
2819 | HDSPM_INPUT_SELECT("Input Select", 0), | 4289 | HDSPM_INPUT_SELECT("Input Select", 0) |
2820 | }; | 4290 | }; |
2821 | 4291 | ||
2822 | static struct snd_kcontrol_new snd_hdspm_controls_aes32[] = { | ||
2823 | 4292 | ||
4293 | static struct snd_kcontrol_new snd_hdspm_controls_madiface[] = { | ||
2824 | HDSPM_MIXER("Mixer", 0), | 4294 | HDSPM_MIXER("Mixer", 0), |
2825 | /* 'Sample Clock Source' complies with the alsa control naming scheme */ | 4295 | HDSPM_INTERNAL_CLOCK("Internal Clock", 0), |
2826 | HDSPM_CLOCK_SOURCE("Sample Clock Source", 0), | 4296 | HDSPM_SYSTEM_CLOCK_MODE("System Clock Mode", 0), |
4297 | HDSPM_SYSTEM_SAMPLE_RATE("System Sample Rate", 0), | ||
4298 | HDSPM_AUTOSYNC_SAMPLE_RATE("External Rate", 0), | ||
4299 | HDSPM_SYNC_CHECK("MADI SyncCheck", 0), | ||
4300 | HDSPM_TX_64("TX 64 channels mode", 0), | ||
4301 | HDSPM_C_TMS("Clear Track Marker", 0), | ||
4302 | HDSPM_SAFE_MODE("Safe Mode", 0) | ||
4303 | }; | ||
2827 | 4304 | ||
4305 | static struct snd_kcontrol_new snd_hdspm_controls_aio[] = { | ||
4306 | HDSPM_MIXER("Mixer", 0), | ||
4307 | HDSPM_INTERNAL_CLOCK("Internal Clock", 0), | ||
2828 | HDSPM_SYSTEM_CLOCK_MODE("System Clock Mode", 0), | 4308 | HDSPM_SYSTEM_CLOCK_MODE("System Clock Mode", 0), |
2829 | HDSPM_PREF_SYNC_REF("Preferred Sync Reference", 0), | 4309 | HDSPM_PREF_SYNC_REF("Preferred Sync Reference", 0), |
2830 | HDSPM_AUTOSYNC_REF("AutoSync Reference", 0), | 4310 | HDSPM_AUTOSYNC_REF("AutoSync Reference", 0), |
2831 | HDSPM_SYSTEM_SAMPLE_RATE("System Sample Rate", 0), | 4311 | HDSPM_SYSTEM_SAMPLE_RATE("System Sample Rate", 0), |
2832 | /* 'External Rate' complies with the alsa control naming scheme */ | ||
2833 | HDSPM_AUTOSYNC_SAMPLE_RATE("External Rate", 0), | 4312 | HDSPM_AUTOSYNC_SAMPLE_RATE("External Rate", 0), |
2834 | HDSPM_WC_SYNC_CHECK("Word Clock Lock Status", 0), | 4313 | HDSPM_SYNC_CHECK("WC SyncCheck", 0), |
2835 | /* HDSPM_AES_SYNC_CHECK("AES Lock Status", 0),*/ /* created in snd_hdspm_create_controls() */ | 4314 | HDSPM_SYNC_CHECK("AES SyncCheck", 1), |
4315 | HDSPM_SYNC_CHECK("SPDIF SyncCheck", 2), | ||
4316 | HDSPM_SYNC_CHECK("ADAT SyncCheck", 3), | ||
4317 | HDSPM_SYNC_CHECK("TCO SyncCheck", 4), | ||
4318 | HDSPM_SYNC_CHECK("SYNC IN SyncCheck", 5), | ||
4319 | HDSPM_AUTOSYNC_SAMPLE_RATE("WC Frequency", 0), | ||
4320 | HDSPM_AUTOSYNC_SAMPLE_RATE("AES Frequency", 1), | ||
4321 | HDSPM_AUTOSYNC_SAMPLE_RATE("SPDIF Frequency", 2), | ||
4322 | HDSPM_AUTOSYNC_SAMPLE_RATE("ADAT Frequency", 3), | ||
4323 | HDSPM_AUTOSYNC_SAMPLE_RATE("TCO Frequency", 4), | ||
4324 | HDSPM_AUTOSYNC_SAMPLE_RATE("SYNC IN Frequency", 5) | ||
4325 | |||
4326 | /* | ||
4327 | HDSPM_INPUT_SELECT("Input Select", 0), | ||
4328 | HDSPM_SPDIF_OPTICAL("SPDIF Out Optical", 0), | ||
4329 | HDSPM_PROFESSIONAL("SPDIF Out Professional", 0); | ||
4330 | HDSPM_SPDIF_IN("SPDIF In", 0); | ||
4331 | HDSPM_BREAKOUT_CABLE("Breakout Cable", 0); | ||
4332 | HDSPM_INPUT_LEVEL("Input Level", 0); | ||
4333 | HDSPM_OUTPUT_LEVEL("Output Level", 0); | ||
4334 | HDSPM_PHONES("Phones", 0); | ||
4335 | */ | ||
4336 | }; | ||
4337 | |||
4338 | static struct snd_kcontrol_new snd_hdspm_controls_raydat[] = { | ||
4339 | HDSPM_MIXER("Mixer", 0), | ||
4340 | HDSPM_INTERNAL_CLOCK("Internal Clock", 0), | ||
4341 | HDSPM_SYSTEM_CLOCK_MODE("Clock Mode", 0), | ||
4342 | HDSPM_PREF_SYNC_REF("Pref Sync Ref", 0), | ||
4343 | HDSPM_SYSTEM_SAMPLE_RATE("System Sample Rate", 0), | ||
4344 | HDSPM_SYNC_CHECK("WC SyncCheck", 0), | ||
4345 | HDSPM_SYNC_CHECK("AES SyncCheck", 1), | ||
4346 | HDSPM_SYNC_CHECK("SPDIF SyncCheck", 2), | ||
4347 | HDSPM_SYNC_CHECK("ADAT1 SyncCheck", 3), | ||
4348 | HDSPM_SYNC_CHECK("ADAT2 SyncCheck", 4), | ||
4349 | HDSPM_SYNC_CHECK("ADAT3 SyncCheck", 5), | ||
4350 | HDSPM_SYNC_CHECK("ADAT4 SyncCheck", 6), | ||
4351 | HDSPM_SYNC_CHECK("TCO SyncCheck", 7), | ||
4352 | HDSPM_SYNC_CHECK("SYNC IN SyncCheck", 8), | ||
4353 | HDSPM_AUTOSYNC_SAMPLE_RATE("WC Frequency", 0), | ||
4354 | HDSPM_AUTOSYNC_SAMPLE_RATE("AES Frequency", 1), | ||
4355 | HDSPM_AUTOSYNC_SAMPLE_RATE("SPDIF Frequency", 2), | ||
4356 | HDSPM_AUTOSYNC_SAMPLE_RATE("ADAT1 Frequency", 3), | ||
4357 | HDSPM_AUTOSYNC_SAMPLE_RATE("ADAT2 Frequency", 4), | ||
4358 | HDSPM_AUTOSYNC_SAMPLE_RATE("ADAT3 Frequency", 5), | ||
4359 | HDSPM_AUTOSYNC_SAMPLE_RATE("ADAT4 Frequency", 6), | ||
4360 | HDSPM_AUTOSYNC_SAMPLE_RATE("TCO Frequency", 7), | ||
4361 | HDSPM_AUTOSYNC_SAMPLE_RATE("SYNC IN Frequency", 8) | ||
4362 | }; | ||
4363 | |||
4364 | static struct snd_kcontrol_new snd_hdspm_controls_aes32[] = { | ||
4365 | HDSPM_MIXER("Mixer", 0), | ||
4366 | HDSPM_INTERNAL_CLOCK("Internal Clock", 0), | ||
4367 | HDSPM_SYSTEM_CLOCK_MODE("System Clock Mode", 0), | ||
4368 | HDSPM_PREF_SYNC_REF("Preferred Sync Reference", 0), | ||
4369 | HDSPM_AUTOSYNC_REF("AutoSync Reference", 0), | ||
4370 | HDSPM_SYSTEM_SAMPLE_RATE("System Sample Rate", 0), | ||
4371 | HDSPM_AUTOSYNC_SAMPLE_RATE("External Rate", 0), | ||
4372 | HDSPM_SYNC_CHECK("WC Sync Check", 0), | ||
4373 | HDSPM_SYNC_CHECK("AES1 Sync Check", 1), | ||
4374 | HDSPM_SYNC_CHECK("AES2 Sync Check", 2), | ||
4375 | HDSPM_SYNC_CHECK("AES3 Sync Check", 3), | ||
4376 | HDSPM_SYNC_CHECK("AES4 Sync Check", 4), | ||
4377 | HDSPM_SYNC_CHECK("AES5 Sync Check", 5), | ||
4378 | HDSPM_SYNC_CHECK("AES6 Sync Check", 6), | ||
4379 | HDSPM_SYNC_CHECK("AES7 Sync Check", 7), | ||
4380 | HDSPM_SYNC_CHECK("AES8 Sync Check", 8), | ||
4381 | HDSPM_SYNC_CHECK("TCO Sync Check", 9), | ||
4382 | HDSPM_SYNC_CHECK("SYNC IN Sync Check", 10), | ||
4383 | HDSPM_AUTOSYNC_SAMPLE_RATE("WC Frequency", 0), | ||
4384 | HDSPM_AUTOSYNC_SAMPLE_RATE("AES1 Frequency", 1), | ||
4385 | HDSPM_AUTOSYNC_SAMPLE_RATE("AES2 Frequency", 2), | ||
4386 | HDSPM_AUTOSYNC_SAMPLE_RATE("AES3 Frequency", 3), | ||
4387 | HDSPM_AUTOSYNC_SAMPLE_RATE("AES4 Frequency", 4), | ||
4388 | HDSPM_AUTOSYNC_SAMPLE_RATE("AES5 Frequency", 5), | ||
4389 | HDSPM_AUTOSYNC_SAMPLE_RATE("AES6 Frequency", 6), | ||
4390 | HDSPM_AUTOSYNC_SAMPLE_RATE("AES7 Frequency", 7), | ||
4391 | HDSPM_AUTOSYNC_SAMPLE_RATE("AES8 Frequency", 8), | ||
4392 | HDSPM_AUTOSYNC_SAMPLE_RATE("TCO Frequency", 9), | ||
4393 | HDSPM_AUTOSYNC_SAMPLE_RATE("SYNC IN Frequency", 10), | ||
2836 | HDSPM_LINE_OUT("Line Out", 0), | 4394 | HDSPM_LINE_OUT("Line Out", 0), |
2837 | HDSPM_EMPHASIS("Emphasis", 0), | 4395 | HDSPM_EMPHASIS("Emphasis", 0), |
2838 | HDSPM_DOLBY("Non Audio", 0), | 4396 | HDSPM_DOLBY("Non Audio", 0), |
@@ -2842,6 +4400,19 @@ static struct snd_kcontrol_new snd_hdspm_controls_aes32[] = { | |||
2842 | HDSPM_QS_WIRE("Quad Speed Wire Mode", 0), | 4400 | HDSPM_QS_WIRE("Quad Speed Wire Mode", 0), |
2843 | }; | 4401 | }; |
2844 | 4402 | ||
4403 | |||
4404 | |||
4405 | /* Control elements for the optional TCO module */ | ||
4406 | static struct snd_kcontrol_new snd_hdspm_controls_tco[] = { | ||
4407 | HDSPM_TCO_SAMPLE_RATE("TCO Sample Rate", 0), | ||
4408 | HDSPM_TCO_PULL("TCO Pull", 0), | ||
4409 | HDSPM_TCO_WCK_CONVERSION("TCO WCK Conversion", 0), | ||
4410 | HDSPM_TCO_FRAME_RATE("TCO Frame Rate", 0), | ||
4411 | HDSPM_TCO_SYNC_SOURCE("TCO Sync Source", 0), | ||
4412 | HDSPM_TCO_WORD_TERM("TCO Word Term", 0) | ||
4413 | }; | ||
4414 | |||
4415 | |||
2845 | static struct snd_kcontrol_new snd_hdspm_playback_mixer = HDSPM_PLAYBACK_MIXER; | 4416 | static struct snd_kcontrol_new snd_hdspm_playback_mixer = HDSPM_PLAYBACK_MIXER; |
2846 | 4417 | ||
2847 | 4418 | ||
@@ -2849,78 +4420,76 @@ static int hdspm_update_simple_mixer_controls(struct hdspm * hdspm) | |||
2849 | { | 4420 | { |
2850 | int i; | 4421 | int i; |
2851 | 4422 | ||
2852 | for (i = hdspm->ds_channels; i < hdspm->ss_channels; ++i) { | 4423 | for (i = hdspm->ds_out_channels; i < hdspm->ss_out_channels; ++i) { |
2853 | if (hdspm->system_sample_rate > 48000) { | 4424 | if (hdspm->system_sample_rate > 48000) { |
2854 | hdspm->playback_mixer_ctls[i]->vd[0].access = | 4425 | hdspm->playback_mixer_ctls[i]->vd[0].access = |
2855 | SNDRV_CTL_ELEM_ACCESS_INACTIVE | | 4426 | SNDRV_CTL_ELEM_ACCESS_INACTIVE | |
2856 | SNDRV_CTL_ELEM_ACCESS_READ | | 4427 | SNDRV_CTL_ELEM_ACCESS_READ | |
2857 | SNDRV_CTL_ELEM_ACCESS_VOLATILE; | 4428 | SNDRV_CTL_ELEM_ACCESS_VOLATILE; |
2858 | } else { | 4429 | } else { |
2859 | hdspm->playback_mixer_ctls[i]->vd[0].access = | 4430 | hdspm->playback_mixer_ctls[i]->vd[0].access = |
2860 | SNDRV_CTL_ELEM_ACCESS_READWRITE | | 4431 | SNDRV_CTL_ELEM_ACCESS_READWRITE | |
2861 | SNDRV_CTL_ELEM_ACCESS_VOLATILE; | 4432 | SNDRV_CTL_ELEM_ACCESS_VOLATILE; |
2862 | } | 4433 | } |
2863 | snd_ctl_notify(hdspm->card, SNDRV_CTL_EVENT_MASK_VALUE | | 4434 | snd_ctl_notify(hdspm->card, SNDRV_CTL_EVENT_MASK_VALUE | |
2864 | SNDRV_CTL_EVENT_MASK_INFO, | 4435 | SNDRV_CTL_EVENT_MASK_INFO, |
2865 | &hdspm->playback_mixer_ctls[i]->id); | 4436 | &hdspm->playback_mixer_ctls[i]->id); |
2866 | } | 4437 | } |
2867 | 4438 | ||
2868 | return 0; | 4439 | return 0; |
2869 | } | 4440 | } |
2870 | 4441 | ||
2871 | 4442 | ||
2872 | static int snd_hdspm_create_controls(struct snd_card *card, struct hdspm * hdspm) | 4443 | static int snd_hdspm_create_controls(struct snd_card *card, |
4444 | struct hdspm *hdspm) | ||
2873 | { | 4445 | { |
2874 | unsigned int idx, limit; | 4446 | unsigned int idx, limit; |
2875 | int err; | 4447 | int err; |
2876 | struct snd_kcontrol *kctl; | 4448 | struct snd_kcontrol *kctl; |
4449 | struct snd_kcontrol_new *list = NULL; | ||
2877 | 4450 | ||
2878 | /* add control list first */ | 4451 | switch (hdspm->io_type) { |
2879 | if (hdspm->is_aes32) { | 4452 | case MADI: |
2880 | struct snd_kcontrol_new aes_sync_ctl = | 4453 | list = snd_hdspm_controls_madi; |
2881 | HDSPM_AES_SYNC_CHECK("AES Lock Status", 0); | 4454 | limit = ARRAY_SIZE(snd_hdspm_controls_madi); |
4455 | break; | ||
4456 | case MADIface: | ||
4457 | list = snd_hdspm_controls_madiface; | ||
4458 | limit = ARRAY_SIZE(snd_hdspm_controls_madiface); | ||
4459 | break; | ||
4460 | case AIO: | ||
4461 | list = snd_hdspm_controls_aio; | ||
4462 | limit = ARRAY_SIZE(snd_hdspm_controls_aio); | ||
4463 | break; | ||
4464 | case RayDAT: | ||
4465 | list = snd_hdspm_controls_raydat; | ||
4466 | limit = ARRAY_SIZE(snd_hdspm_controls_raydat); | ||
4467 | break; | ||
4468 | case AES32: | ||
4469 | list = snd_hdspm_controls_aes32; | ||
4470 | limit = ARRAY_SIZE(snd_hdspm_controls_aes32); | ||
4471 | break; | ||
4472 | } | ||
2882 | 4473 | ||
2883 | for (idx = 0; idx < ARRAY_SIZE(snd_hdspm_controls_aes32); | 4474 | if (NULL != list) { |
2884 | idx++) { | 4475 | for (idx = 0; idx < limit; idx++) { |
2885 | err = snd_ctl_add(card, | ||
2886 | snd_ctl_new1(&snd_hdspm_controls_aes32[idx], | ||
2887 | hdspm)); | ||
2888 | if (err < 0) | ||
2889 | return err; | ||
2890 | } | ||
2891 | for (idx = 1; idx <= 8; idx++) { | ||
2892 | aes_sync_ctl.index = idx; | ||
2893 | err = snd_ctl_add(card, | ||
2894 | snd_ctl_new1(&aes_sync_ctl, hdspm)); | ||
2895 | if (err < 0) | ||
2896 | return err; | ||
2897 | } | ||
2898 | } else { | ||
2899 | for (idx = 0; idx < ARRAY_SIZE(snd_hdspm_controls_madi); | ||
2900 | idx++) { | ||
2901 | err = snd_ctl_add(card, | 4476 | err = snd_ctl_add(card, |
2902 | snd_ctl_new1(&snd_hdspm_controls_madi[idx], | 4477 | snd_ctl_new1(&list[idx], hdspm)); |
2903 | hdspm)); | ||
2904 | if (err < 0) | 4478 | if (err < 0) |
2905 | return err; | 4479 | return err; |
2906 | } | 4480 | } |
2907 | } | 4481 | } |
2908 | 4482 | ||
2909 | /* Channel playback mixer as default control | ||
2910 | Note: the whole matrix would be 128*HDSPM_MIXER_CHANNELS Faders, | ||
2911 | thats too * big for any alsamixer they are accessible via special | ||
2912 | IOCTL on hwdep and the mixer 2dimensional mixer control | ||
2913 | */ | ||
2914 | 4483 | ||
4484 | /* create simple 1:1 playback mixer controls */ | ||
2915 | snd_hdspm_playback_mixer.name = "Chn"; | 4485 | snd_hdspm_playback_mixer.name = "Chn"; |
2916 | limit = HDSPM_MAX_CHANNELS; | 4486 | if (hdspm->system_sample_rate >= 128000) { |
2917 | 4487 | limit = hdspm->qs_out_channels; | |
2918 | /* The index values are one greater than the channel ID so that | 4488 | } else if (hdspm->system_sample_rate >= 64000) { |
2919 | * alsamixer will display them correctly. We want to use the index | 4489 | limit = hdspm->ds_out_channels; |
2920 | * for fast lookup of the relevant channel, but if we use it at all, | 4490 | } else { |
2921 | * most ALSA software does the wrong thing with it ... | 4491 | limit = hdspm->ss_out_channels; |
2922 | */ | 4492 | } |
2923 | |||
2924 | for (idx = 0; idx < limit; ++idx) { | 4493 | for (idx = 0; idx < limit; ++idx) { |
2925 | snd_hdspm_playback_mixer.index = idx + 1; | 4494 | snd_hdspm_playback_mixer.index = idx + 1; |
2926 | kctl = snd_ctl_new1(&snd_hdspm_playback_mixer, hdspm); | 4495 | kctl = snd_ctl_new1(&snd_hdspm_playback_mixer, hdspm); |
@@ -2930,11 +4499,24 @@ static int snd_hdspm_create_controls(struct snd_card *card, struct hdspm * hdspm | |||
2930 | hdspm->playback_mixer_ctls[idx] = kctl; | 4499 | hdspm->playback_mixer_ctls[idx] = kctl; |
2931 | } | 4500 | } |
2932 | 4501 | ||
4502 | |||
4503 | if (hdspm->tco) { | ||
4504 | /* add tco control elements */ | ||
4505 | list = snd_hdspm_controls_tco; | ||
4506 | limit = ARRAY_SIZE(snd_hdspm_controls_tco); | ||
4507 | for (idx = 0; idx < limit; idx++) { | ||
4508 | err = snd_ctl_add(card, | ||
4509 | snd_ctl_new1(&list[idx], hdspm)); | ||
4510 | if (err < 0) | ||
4511 | return err; | ||
4512 | } | ||
4513 | } | ||
4514 | |||
2933 | return 0; | 4515 | return 0; |
2934 | } | 4516 | } |
2935 | 4517 | ||
2936 | /*------------------------------------------------------------ | 4518 | /*------------------------------------------------------------ |
2937 | /proc interface | 4519 | /proc interface |
2938 | ------------------------------------------------------------*/ | 4520 | ------------------------------------------------------------*/ |
2939 | 4521 | ||
2940 | static void | 4522 | static void |
@@ -2942,72 +4524,178 @@ snd_hdspm_proc_read_madi(struct snd_info_entry * entry, | |||
2942 | struct snd_info_buffer *buffer) | 4524 | struct snd_info_buffer *buffer) |
2943 | { | 4525 | { |
2944 | struct hdspm *hdspm = entry->private_data; | 4526 | struct hdspm *hdspm = entry->private_data; |
2945 | unsigned int status; | 4527 | unsigned int status, status2, control, freq; |
2946 | unsigned int status2; | 4528 | |
2947 | char *pref_sync_ref; | 4529 | char *pref_sync_ref; |
2948 | char *autosync_ref; | 4530 | char *autosync_ref; |
2949 | char *system_clock_mode; | 4531 | char *system_clock_mode; |
2950 | char *clock_source; | ||
2951 | char *insel; | 4532 | char *insel; |
2952 | char *syncref; | ||
2953 | int x, x2; | 4533 | int x, x2; |
2954 | 4534 | ||
4535 | /* TCO stuff */ | ||
4536 | int a, ltc, frames, seconds, minutes, hours; | ||
4537 | unsigned int period; | ||
4538 | u64 freq_const = 0; | ||
4539 | u32 rate; | ||
4540 | |||
2955 | status = hdspm_read(hdspm, HDSPM_statusRegister); | 4541 | status = hdspm_read(hdspm, HDSPM_statusRegister); |
2956 | status2 = hdspm_read(hdspm, HDSPM_statusRegister2); | 4542 | status2 = hdspm_read(hdspm, HDSPM_statusRegister2); |
4543 | control = hdspm->control_register; | ||
4544 | freq = hdspm_read(hdspm, HDSPM_timecodeRegister); | ||
2957 | 4545 | ||
2958 | snd_iprintf(buffer, "%s (Card #%d) Rev.%x Status2first3bits: %x\n", | 4546 | snd_iprintf(buffer, "%s (Card #%d) Rev.%x Status2first3bits: %x\n", |
2959 | hdspm->card_name, hdspm->card->number + 1, | 4547 | hdspm->card_name, hdspm->card->number + 1, |
2960 | hdspm->firmware_rev, | 4548 | hdspm->firmware_rev, |
2961 | (status2 & HDSPM_version0) | | 4549 | (status2 & HDSPM_version0) | |
2962 | (status2 & HDSPM_version1) | (status2 & | 4550 | (status2 & HDSPM_version1) | (status2 & |
2963 | HDSPM_version2)); | 4551 | HDSPM_version2)); |
4552 | |||
4553 | snd_iprintf(buffer, "HW Serial: 0x%06x%06x\n", | ||
4554 | (hdspm_read(hdspm, HDSPM_midiStatusIn1)>>8) & 0xFFFFFF, | ||
4555 | (hdspm_read(hdspm, HDSPM_midiStatusIn0)>>8) & 0xFFFFFF); | ||
2964 | 4556 | ||
2965 | snd_iprintf(buffer, "IRQ: %d Registers bus: 0x%lx VM: 0x%lx\n", | 4557 | snd_iprintf(buffer, "IRQ: %d Registers bus: 0x%lx VM: 0x%lx\n", |
2966 | hdspm->irq, hdspm->port, (unsigned long)hdspm->iobase); | 4558 | hdspm->irq, hdspm->port, (unsigned long)hdspm->iobase); |
2967 | 4559 | ||
2968 | snd_iprintf(buffer, "--- System ---\n"); | 4560 | snd_iprintf(buffer, "--- System ---\n"); |
2969 | 4561 | ||
2970 | snd_iprintf(buffer, | 4562 | snd_iprintf(buffer, |
2971 | "IRQ Pending: Audio=%d, MIDI0=%d, MIDI1=%d, IRQcount=%d\n", | 4563 | "IRQ Pending: Audio=%d, MIDI0=%d, MIDI1=%d, IRQcount=%d\n", |
2972 | status & HDSPM_audioIRQPending, | 4564 | status & HDSPM_audioIRQPending, |
2973 | (status & HDSPM_midi0IRQPending) ? 1 : 0, | 4565 | (status & HDSPM_midi0IRQPending) ? 1 : 0, |
2974 | (status & HDSPM_midi1IRQPending) ? 1 : 0, | 4566 | (status & HDSPM_midi1IRQPending) ? 1 : 0, |
2975 | hdspm->irq_count); | 4567 | hdspm->irq_count); |
2976 | snd_iprintf(buffer, | 4568 | snd_iprintf(buffer, |
2977 | "HW pointer: id = %d, rawptr = %d (%d->%d) " | 4569 | "HW pointer: id = %d, rawptr = %d (%d->%d) " |
2978 | "estimated= %ld (bytes)\n", | 4570 | "estimated= %ld (bytes)\n", |
2979 | ((status & HDSPM_BufferID) ? 1 : 0), | 4571 | ((status & HDSPM_BufferID) ? 1 : 0), |
2980 | (status & HDSPM_BufferPositionMask), | 4572 | (status & HDSPM_BufferPositionMask), |
2981 | (status & HDSPM_BufferPositionMask) % | 4573 | (status & HDSPM_BufferPositionMask) % |
2982 | (2 * (int)hdspm->period_bytes), | 4574 | (2 * (int)hdspm->period_bytes), |
2983 | ((status & HDSPM_BufferPositionMask) - 64) % | 4575 | ((status & HDSPM_BufferPositionMask) - 64) % |
2984 | (2 * (int)hdspm->period_bytes), | 4576 | (2 * (int)hdspm->period_bytes), |
2985 | (long) hdspm_hw_pointer(hdspm) * 4); | 4577 | (long) hdspm_hw_pointer(hdspm) * 4); |
2986 | 4578 | ||
2987 | snd_iprintf(buffer, | 4579 | snd_iprintf(buffer, |
2988 | "MIDI FIFO: Out1=0x%x, Out2=0x%x, In1=0x%x, In2=0x%x \n", | 4580 | "MIDI FIFO: Out1=0x%x, Out2=0x%x, In1=0x%x, In2=0x%x \n", |
2989 | hdspm_read(hdspm, HDSPM_midiStatusOut0) & 0xFF, | 4581 | hdspm_read(hdspm, HDSPM_midiStatusOut0) & 0xFF, |
2990 | hdspm_read(hdspm, HDSPM_midiStatusOut1) & 0xFF, | 4582 | hdspm_read(hdspm, HDSPM_midiStatusOut1) & 0xFF, |
2991 | hdspm_read(hdspm, HDSPM_midiStatusIn0) & 0xFF, | 4583 | hdspm_read(hdspm, HDSPM_midiStatusIn0) & 0xFF, |
2992 | hdspm_read(hdspm, HDSPM_midiStatusIn1) & 0xFF); | 4584 | hdspm_read(hdspm, HDSPM_midiStatusIn1) & 0xFF); |
2993 | snd_iprintf(buffer, | 4585 | snd_iprintf(buffer, |
2994 | "Register: ctrl1=0x%x, ctrl2=0x%x, status1=0x%x, " | 4586 | "MIDIoverMADI FIFO: In=0x%x, Out=0x%x \n", |
2995 | "status2=0x%x\n", | 4587 | hdspm_read(hdspm, HDSPM_midiStatusIn2) & 0xFF, |
2996 | hdspm->control_register, hdspm->control2_register, | 4588 | hdspm_read(hdspm, HDSPM_midiStatusOut2) & 0xFF); |
2997 | status, status2); | 4589 | snd_iprintf(buffer, |
4590 | "Register: ctrl1=0x%x, ctrl2=0x%x, status1=0x%x, " | ||
4591 | "status2=0x%x\n", | ||
4592 | hdspm->control_register, hdspm->control2_register, | ||
4593 | status, status2); | ||
4594 | if (status & HDSPM_tco_detect) { | ||
4595 | snd_iprintf(buffer, "TCO module detected.\n"); | ||
4596 | a = hdspm_read(hdspm, HDSPM_RD_TCO+4); | ||
4597 | if (a & HDSPM_TCO1_LTC_Input_valid) { | ||
4598 | snd_iprintf(buffer, " LTC valid, "); | ||
4599 | switch (a & (HDSPM_TCO1_LTC_Format_LSB | | ||
4600 | HDSPM_TCO1_LTC_Format_MSB)) { | ||
4601 | case 0: | ||
4602 | snd_iprintf(buffer, "24 fps, "); | ||
4603 | break; | ||
4604 | case HDSPM_TCO1_LTC_Format_LSB: | ||
4605 | snd_iprintf(buffer, "25 fps, "); | ||
4606 | break; | ||
4607 | case HDSPM_TCO1_LTC_Format_MSB: | ||
4608 | snd_iprintf(buffer, "29.97 fps, "); | ||
4609 | break; | ||
4610 | default: | ||
4611 | snd_iprintf(buffer, "30 fps, "); | ||
4612 | break; | ||
4613 | } | ||
4614 | if (a & HDSPM_TCO1_set_drop_frame_flag) { | ||
4615 | snd_iprintf(buffer, "drop frame\n"); | ||
4616 | } else { | ||
4617 | snd_iprintf(buffer, "full frame\n"); | ||
4618 | } | ||
4619 | } else { | ||
4620 | snd_iprintf(buffer, " no LTC\n"); | ||
4621 | } | ||
4622 | if (a & HDSPM_TCO1_Video_Input_Format_NTSC) { | ||
4623 | snd_iprintf(buffer, " Video: NTSC\n"); | ||
4624 | } else if (a & HDSPM_TCO1_Video_Input_Format_PAL) { | ||
4625 | snd_iprintf(buffer, " Video: PAL\n"); | ||
4626 | } else { | ||
4627 | snd_iprintf(buffer, " No video\n"); | ||
4628 | } | ||
4629 | if (a & HDSPM_TCO1_TCO_lock) { | ||
4630 | snd_iprintf(buffer, " Sync: lock\n"); | ||
4631 | } else { | ||
4632 | snd_iprintf(buffer, " Sync: no lock\n"); | ||
4633 | } | ||
4634 | |||
4635 | switch (hdspm->io_type) { | ||
4636 | case MADI: | ||
4637 | case AES32: | ||
4638 | freq_const = 110069313433624ULL; | ||
4639 | break; | ||
4640 | case RayDAT: | ||
4641 | case AIO: | ||
4642 | freq_const = 104857600000000ULL; | ||
4643 | break; | ||
4644 | case MADIface: | ||
4645 | break; /* no TCO possible */ | ||
4646 | } | ||
4647 | |||
4648 | period = hdspm_read(hdspm, HDSPM_RD_PLL_FREQ); | ||
4649 | snd_iprintf(buffer, " period: %u\n", period); | ||
4650 | |||
4651 | |||
4652 | /* rate = freq_const/period; */ | ||
4653 | rate = div_u64(freq_const, period); | ||
4654 | |||
4655 | if (control & HDSPM_QuadSpeed) { | ||
4656 | rate *= 4; | ||
4657 | } else if (control & HDSPM_DoubleSpeed) { | ||
4658 | rate *= 2; | ||
4659 | } | ||
4660 | |||
4661 | snd_iprintf(buffer, " Frequency: %u Hz\n", | ||
4662 | (unsigned int) rate); | ||
4663 | |||
4664 | ltc = hdspm_read(hdspm, HDSPM_RD_TCO); | ||
4665 | frames = ltc & 0xF; | ||
4666 | ltc >>= 4; | ||
4667 | frames += (ltc & 0x3) * 10; | ||
4668 | ltc >>= 4; | ||
4669 | seconds = ltc & 0xF; | ||
4670 | ltc >>= 4; | ||
4671 | seconds += (ltc & 0x7) * 10; | ||
4672 | ltc >>= 4; | ||
4673 | minutes = ltc & 0xF; | ||
4674 | ltc >>= 4; | ||
4675 | minutes += (ltc & 0x7) * 10; | ||
4676 | ltc >>= 4; | ||
4677 | hours = ltc & 0xF; | ||
4678 | ltc >>= 4; | ||
4679 | hours += (ltc & 0x3) * 10; | ||
4680 | snd_iprintf(buffer, | ||
4681 | " LTC In: %02d:%02d:%02d:%02d\n", | ||
4682 | hours, minutes, seconds, frames); | ||
4683 | |||
4684 | } else { | ||
4685 | snd_iprintf(buffer, "No TCO module detected.\n"); | ||
4686 | } | ||
2998 | 4687 | ||
2999 | snd_iprintf(buffer, "--- Settings ---\n"); | 4688 | snd_iprintf(buffer, "--- Settings ---\n"); |
3000 | 4689 | ||
3001 | x = 1 << (6 + hdspm_decode_latency(hdspm->control_register & | 4690 | x = 1 << (6 + hdspm_decode_latency(hdspm->control_register & |
3002 | HDSPM_LatencyMask)); | 4691 | HDSPM_LatencyMask)); |
3003 | 4692 | ||
3004 | snd_iprintf(buffer, | 4693 | snd_iprintf(buffer, |
3005 | "Size (Latency): %d samples (2 periods of %lu bytes)\n", | 4694 | "Size (Latency): %d samples (2 periods of %lu bytes)\n", |
3006 | x, (unsigned long) hdspm->period_bytes); | 4695 | x, (unsigned long) hdspm->period_bytes); |
3007 | 4696 | ||
3008 | snd_iprintf(buffer, "Line out: %s, Precise Pointer: %s\n", | 4697 | snd_iprintf(buffer, "Line out: %s\n", |
3009 | (hdspm->control_register & HDSPM_LineOut) ? "on " : "off", | 4698 | (hdspm->control_register & HDSPM_LineOut) ? "on " : "off"); |
3010 | (hdspm->precise_ptr) ? "on" : "off"); | ||
3011 | 4699 | ||
3012 | switch (hdspm->control_register & HDSPM_InputMask) { | 4700 | switch (hdspm->control_register & HDSPM_InputMask) { |
3013 | case HDSPM_InputOptical: | 4701 | case HDSPM_InputOptical: |
@@ -3017,63 +4705,22 @@ snd_hdspm_proc_read_madi(struct snd_info_entry * entry, | |||
3017 | insel = "Coaxial"; | 4705 | insel = "Coaxial"; |
3018 | break; | 4706 | break; |
3019 | default: | 4707 | default: |
3020 | insel = "Unknown"; | 4708 | insel = "Unkown"; |
3021 | } | ||
3022 | |||
3023 | switch (hdspm->control_register & HDSPM_SyncRefMask) { | ||
3024 | case HDSPM_SyncRef_Word: | ||
3025 | syncref = "WordClock"; | ||
3026 | break; | ||
3027 | case HDSPM_SyncRef_MADI: | ||
3028 | syncref = "MADI"; | ||
3029 | break; | ||
3030 | default: | ||
3031 | syncref = "Unknown"; | ||
3032 | } | 4709 | } |
3033 | snd_iprintf(buffer, "Inputsel = %s, SyncRef = %s\n", insel, | ||
3034 | syncref); | ||
3035 | 4710 | ||
3036 | snd_iprintf(buffer, | 4711 | snd_iprintf(buffer, |
3037 | "ClearTrackMarker = %s, Transmit in %s Channel Mode, " | 4712 | "ClearTrackMarker = %s, Transmit in %s Channel Mode, " |
3038 | "Auto Input %s\n", | 4713 | "Auto Input %s\n", |
3039 | (hdspm-> | 4714 | (hdspm->control_register & HDSPM_clr_tms) ? "on" : "off", |
3040 | control_register & HDSPM_clr_tms) ? "on" : "off", | 4715 | (hdspm->control_register & HDSPM_TX_64ch) ? "64" : "56", |
3041 | (hdspm-> | 4716 | (hdspm->control_register & HDSPM_AutoInp) ? "on" : "off"); |
3042 | control_register & HDSPM_TX_64ch) ? "64" : "56", | 4717 | |
3043 | (hdspm-> | ||
3044 | control_register & HDSPM_AutoInp) ? "on" : "off"); | ||
3045 | 4718 | ||
3046 | switch (hdspm_clock_source(hdspm)) { | ||
3047 | case HDSPM_CLOCK_SOURCE_AUTOSYNC: | ||
3048 | clock_source = "AutoSync"; | ||
3049 | break; | ||
3050 | case HDSPM_CLOCK_SOURCE_INTERNAL_32KHZ: | ||
3051 | clock_source = "Internal 32 kHz"; | ||
3052 | break; | ||
3053 | case HDSPM_CLOCK_SOURCE_INTERNAL_44_1KHZ: | ||
3054 | clock_source = "Internal 44.1 kHz"; | ||
3055 | break; | ||
3056 | case HDSPM_CLOCK_SOURCE_INTERNAL_48KHZ: | ||
3057 | clock_source = "Internal 48 kHz"; | ||
3058 | break; | ||
3059 | case HDSPM_CLOCK_SOURCE_INTERNAL_64KHZ: | ||
3060 | clock_source = "Internal 64 kHz"; | ||
3061 | break; | ||
3062 | case HDSPM_CLOCK_SOURCE_INTERNAL_88_2KHZ: | ||
3063 | clock_source = "Internal 88.2 kHz"; | ||
3064 | break; | ||
3065 | case HDSPM_CLOCK_SOURCE_INTERNAL_96KHZ: | ||
3066 | clock_source = "Internal 96 kHz"; | ||
3067 | break; | ||
3068 | default: | ||
3069 | clock_source = "Error"; | ||
3070 | } | ||
3071 | snd_iprintf(buffer, "Sample Clock Source: %s\n", clock_source); | ||
3072 | if (!(hdspm->control_register & HDSPM_ClockModeMaster)) | 4719 | if (!(hdspm->control_register & HDSPM_ClockModeMaster)) |
3073 | system_clock_mode = "Slave"; | 4720 | system_clock_mode = "AutoSync"; |
3074 | else | 4721 | else |
3075 | system_clock_mode = "Master"; | 4722 | system_clock_mode = "Master"; |
3076 | snd_iprintf(buffer, "System Clock Mode: %s\n", system_clock_mode); | 4723 | snd_iprintf(buffer, "AutoSync Reference: %s\n", system_clock_mode); |
3077 | 4724 | ||
3078 | switch (hdspm_pref_sync_ref(hdspm)) { | 4725 | switch (hdspm_pref_sync_ref(hdspm)) { |
3079 | case HDSPM_SYNC_FROM_WORD: | 4726 | case HDSPM_SYNC_FROM_WORD: |
@@ -3082,15 +4729,21 @@ snd_hdspm_proc_read_madi(struct snd_info_entry * entry, | |||
3082 | case HDSPM_SYNC_FROM_MADI: | 4729 | case HDSPM_SYNC_FROM_MADI: |
3083 | pref_sync_ref = "MADI Sync"; | 4730 | pref_sync_ref = "MADI Sync"; |
3084 | break; | 4731 | break; |
4732 | case HDSPM_SYNC_FROM_TCO: | ||
4733 | pref_sync_ref = "TCO"; | ||
4734 | break; | ||
4735 | case HDSPM_SYNC_FROM_SYNC_IN: | ||
4736 | pref_sync_ref = "Sync In"; | ||
4737 | break; | ||
3085 | default: | 4738 | default: |
3086 | pref_sync_ref = "XXXX Clock"; | 4739 | pref_sync_ref = "XXXX Clock"; |
3087 | break; | 4740 | break; |
3088 | } | 4741 | } |
3089 | snd_iprintf(buffer, "Preferred Sync Reference: %s\n", | 4742 | snd_iprintf(buffer, "Preferred Sync Reference: %s\n", |
3090 | pref_sync_ref); | 4743 | pref_sync_ref); |
3091 | 4744 | ||
3092 | snd_iprintf(buffer, "System Clock Frequency: %d\n", | 4745 | snd_iprintf(buffer, "System Clock Frequency: %d\n", |
3093 | hdspm->system_sample_rate); | 4746 | hdspm->system_sample_rate); |
3094 | 4747 | ||
3095 | 4748 | ||
3096 | snd_iprintf(buffer, "--- Status:\n"); | 4749 | snd_iprintf(buffer, "--- Status:\n"); |
@@ -3099,12 +4752,18 @@ snd_hdspm_proc_read_madi(struct snd_info_entry * entry, | |||
3099 | x2 = status2 & HDSPM_wcSync; | 4752 | x2 = status2 & HDSPM_wcSync; |
3100 | 4753 | ||
3101 | snd_iprintf(buffer, "Inputs MADI=%s, WordClock=%s\n", | 4754 | snd_iprintf(buffer, "Inputs MADI=%s, WordClock=%s\n", |
3102 | (status & HDSPM_madiLock) ? (x ? "Sync" : "Lock") : | 4755 | (status & HDSPM_madiLock) ? (x ? "Sync" : "Lock") : |
3103 | "NoLock", | 4756 | "NoLock", |
3104 | (status2 & HDSPM_wcLock) ? (x2 ? "Sync" : "Lock") : | 4757 | (status2 & HDSPM_wcLock) ? (x2 ? "Sync" : "Lock") : |
3105 | "NoLock"); | 4758 | "NoLock"); |
3106 | 4759 | ||
3107 | switch (hdspm_autosync_ref(hdspm)) { | 4760 | switch (hdspm_autosync_ref(hdspm)) { |
4761 | case HDSPM_AUTOSYNC_FROM_SYNC_IN: | ||
4762 | autosync_ref = "Sync In"; | ||
4763 | break; | ||
4764 | case HDSPM_AUTOSYNC_FROM_TCO: | ||
4765 | autosync_ref = "TCO"; | ||
4766 | break; | ||
3108 | case HDSPM_AUTOSYNC_FROM_WORD: | 4767 | case HDSPM_AUTOSYNC_FROM_WORD: |
3109 | autosync_ref = "Word Clock"; | 4768 | autosync_ref = "Word Clock"; |
3110 | break; | 4769 | break; |
@@ -3119,15 +4778,15 @@ snd_hdspm_proc_read_madi(struct snd_info_entry * entry, | |||
3119 | break; | 4778 | break; |
3120 | } | 4779 | } |
3121 | snd_iprintf(buffer, | 4780 | snd_iprintf(buffer, |
3122 | "AutoSync: Reference= %s, Freq=%d (MADI = %d, Word = %d)\n", | 4781 | "AutoSync: Reference= %s, Freq=%d (MADI = %d, Word = %d)\n", |
3123 | autosync_ref, hdspm_external_sample_rate(hdspm), | 4782 | autosync_ref, hdspm_external_sample_rate(hdspm), |
3124 | (status & HDSPM_madiFreqMask) >> 22, | 4783 | (status & HDSPM_madiFreqMask) >> 22, |
3125 | (status2 & HDSPM_wcFreqMask) >> 5); | 4784 | (status2 & HDSPM_wcFreqMask) >> 5); |
3126 | 4785 | ||
3127 | snd_iprintf(buffer, "Input: %s, Mode=%s\n", | 4786 | snd_iprintf(buffer, "Input: %s, Mode=%s\n", |
3128 | (status & HDSPM_AB_int) ? "Coax" : "Optical", | 4787 | (status & HDSPM_AB_int) ? "Coax" : "Optical", |
3129 | (status & HDSPM_RX_64ch) ? "64 channels" : | 4788 | (status & HDSPM_RX_64ch) ? "64 channels" : |
3130 | "56 channels"); | 4789 | "56 channels"); |
3131 | 4790 | ||
3132 | snd_iprintf(buffer, "\n"); | 4791 | snd_iprintf(buffer, "\n"); |
3133 | } | 4792 | } |
@@ -3142,8 +4801,6 @@ snd_hdspm_proc_read_aes32(struct snd_info_entry * entry, | |||
3142 | unsigned int timecode; | 4801 | unsigned int timecode; |
3143 | int pref_syncref; | 4802 | int pref_syncref; |
3144 | char *autosync_ref; | 4803 | char *autosync_ref; |
3145 | char *system_clock_mode; | ||
3146 | char *clock_source; | ||
3147 | int x; | 4804 | int x; |
3148 | 4805 | ||
3149 | status = hdspm_read(hdspm, HDSPM_statusRegister); | 4806 | status = hdspm_read(hdspm, HDSPM_statusRegister); |
@@ -3183,24 +4840,27 @@ snd_hdspm_proc_read_aes32(struct snd_info_entry * entry, | |||
3183 | hdspm_read(hdspm, HDSPM_midiStatusIn0) & 0xFF, | 4840 | hdspm_read(hdspm, HDSPM_midiStatusIn0) & 0xFF, |
3184 | hdspm_read(hdspm, HDSPM_midiStatusIn1) & 0xFF); | 4841 | hdspm_read(hdspm, HDSPM_midiStatusIn1) & 0xFF); |
3185 | snd_iprintf(buffer, | 4842 | snd_iprintf(buffer, |
3186 | "Register: ctrl1=0x%x, status1=0x%x, status2=0x%x, " | 4843 | "MIDIoverMADI FIFO: In=0x%x, Out=0x%x \n", |
3187 | "timecode=0x%x\n", | 4844 | hdspm_read(hdspm, HDSPM_midiStatusIn2) & 0xFF, |
3188 | hdspm->control_register, | 4845 | hdspm_read(hdspm, HDSPM_midiStatusOut2) & 0xFF); |
3189 | status, status2, timecode); | 4846 | snd_iprintf(buffer, |
4847 | "Register: ctrl1=0x%x, ctrl2=0x%x, status1=0x%x, " | ||
4848 | "status2=0x%x\n", | ||
4849 | hdspm->control_register, hdspm->control2_register, | ||
4850 | status, status2); | ||
3190 | 4851 | ||
3191 | snd_iprintf(buffer, "--- Settings ---\n"); | 4852 | snd_iprintf(buffer, "--- Settings ---\n"); |
3192 | 4853 | ||
3193 | x = 1 << (6 + hdspm_decode_latency(hdspm->control_register & | 4854 | x = 1 << (6 + hdspm_decode_latency(hdspm->control_register & |
3194 | HDSPM_LatencyMask)); | 4855 | HDSPM_LatencyMask)); |
3195 | 4856 | ||
3196 | snd_iprintf(buffer, | 4857 | snd_iprintf(buffer, |
3197 | "Size (Latency): %d samples (2 periods of %lu bytes)\n", | 4858 | "Size (Latency): %d samples (2 periods of %lu bytes)\n", |
3198 | x, (unsigned long) hdspm->period_bytes); | 4859 | x, (unsigned long) hdspm->period_bytes); |
3199 | 4860 | ||
3200 | snd_iprintf(buffer, "Line out: %s, Precise Pointer: %s\n", | 4861 | snd_iprintf(buffer, "Line out: %s\n", |
3201 | (hdspm-> | 4862 | (hdspm-> |
3202 | control_register & HDSPM_LineOut) ? "on " : "off", | 4863 | control_register & HDSPM_LineOut) ? "on " : "off"); |
3203 | (hdspm->precise_ptr) ? "on" : "off"); | ||
3204 | 4864 | ||
3205 | snd_iprintf(buffer, | 4865 | snd_iprintf(buffer, |
3206 | "ClearTrackMarker %s, Emphasis %s, Dolby %s\n", | 4866 | "ClearTrackMarker %s, Emphasis %s, Dolby %s\n", |
@@ -3211,46 +4871,6 @@ snd_hdspm_proc_read_aes32(struct snd_info_entry * entry, | |||
3211 | (hdspm-> | 4871 | (hdspm-> |
3212 | control_register & HDSPM_Dolby) ? "on" : "off"); | 4872 | control_register & HDSPM_Dolby) ? "on" : "off"); |
3213 | 4873 | ||
3214 | switch (hdspm_clock_source(hdspm)) { | ||
3215 | case HDSPM_CLOCK_SOURCE_AUTOSYNC: | ||
3216 | clock_source = "AutoSync"; | ||
3217 | break; | ||
3218 | case HDSPM_CLOCK_SOURCE_INTERNAL_32KHZ: | ||
3219 | clock_source = "Internal 32 kHz"; | ||
3220 | break; | ||
3221 | case HDSPM_CLOCK_SOURCE_INTERNAL_44_1KHZ: | ||
3222 | clock_source = "Internal 44.1 kHz"; | ||
3223 | break; | ||
3224 | case HDSPM_CLOCK_SOURCE_INTERNAL_48KHZ: | ||
3225 | clock_source = "Internal 48 kHz"; | ||
3226 | break; | ||
3227 | case HDSPM_CLOCK_SOURCE_INTERNAL_64KHZ: | ||
3228 | clock_source = "Internal 64 kHz"; | ||
3229 | break; | ||
3230 | case HDSPM_CLOCK_SOURCE_INTERNAL_88_2KHZ: | ||
3231 | clock_source = "Internal 88.2 kHz"; | ||
3232 | break; | ||
3233 | case HDSPM_CLOCK_SOURCE_INTERNAL_96KHZ: | ||
3234 | clock_source = "Internal 96 kHz"; | ||
3235 | break; | ||
3236 | case HDSPM_CLOCK_SOURCE_INTERNAL_128KHZ: | ||
3237 | clock_source = "Internal 128 kHz"; | ||
3238 | break; | ||
3239 | case HDSPM_CLOCK_SOURCE_INTERNAL_176_4KHZ: | ||
3240 | clock_source = "Internal 176.4 kHz"; | ||
3241 | break; | ||
3242 | case HDSPM_CLOCK_SOURCE_INTERNAL_192KHZ: | ||
3243 | clock_source = "Internal 192 kHz"; | ||
3244 | break; | ||
3245 | default: | ||
3246 | clock_source = "Error"; | ||
3247 | } | ||
3248 | snd_iprintf(buffer, "Sample Clock Source: %s\n", clock_source); | ||
3249 | if (!(hdspm->control_register & HDSPM_ClockModeMaster)) | ||
3250 | system_clock_mode = "Slave"; | ||
3251 | else | ||
3252 | system_clock_mode = "Master"; | ||
3253 | snd_iprintf(buffer, "System Clock Mode: %s\n", system_clock_mode); | ||
3254 | 4874 | ||
3255 | pref_syncref = hdspm_pref_sync_ref(hdspm); | 4875 | pref_syncref = hdspm_pref_sync_ref(hdspm); |
3256 | if (pref_syncref == 0) | 4876 | if (pref_syncref == 0) |
@@ -3274,38 +4894,108 @@ snd_hdspm_proc_read_aes32(struct snd_info_entry * entry, | |||
3274 | snd_iprintf(buffer, "--- Status:\n"); | 4894 | snd_iprintf(buffer, "--- Status:\n"); |
3275 | 4895 | ||
3276 | snd_iprintf(buffer, "Word: %s Frequency: %d\n", | 4896 | snd_iprintf(buffer, "Word: %s Frequency: %d\n", |
3277 | (status & HDSPM_AES32_wcLock)? "Sync " : "No Lock", | 4897 | (status & HDSPM_AES32_wcLock) ? "Sync " : "No Lock", |
3278 | HDSPM_bit2freq((status >> HDSPM_AES32_wcFreq_bit) & 0xF)); | 4898 | HDSPM_bit2freq((status >> HDSPM_AES32_wcFreq_bit) & 0xF)); |
3279 | 4899 | ||
3280 | for (x = 0; x < 8; x++) { | 4900 | for (x = 0; x < 8; x++) { |
3281 | snd_iprintf(buffer, "AES%d: %s Frequency: %d\n", | 4901 | snd_iprintf(buffer, "AES%d: %s Frequency: %d\n", |
3282 | x+1, | 4902 | x+1, |
3283 | (status2 & (HDSPM_LockAES >> x)) ? | 4903 | (status2 & (HDSPM_LockAES >> x)) ? |
3284 | "Sync ": "No Lock", | 4904 | "Sync " : "No Lock", |
3285 | HDSPM_bit2freq((timecode >> (4*x)) & 0xF)); | 4905 | HDSPM_bit2freq((timecode >> (4*x)) & 0xF)); |
3286 | } | 4906 | } |
3287 | 4907 | ||
3288 | switch (hdspm_autosync_ref(hdspm)) { | 4908 | switch (hdspm_autosync_ref(hdspm)) { |
3289 | case HDSPM_AES32_AUTOSYNC_FROM_NONE: autosync_ref="None"; break; | 4909 | case HDSPM_AES32_AUTOSYNC_FROM_NONE: |
3290 | case HDSPM_AES32_AUTOSYNC_FROM_WORD: autosync_ref="Word Clock"; break; | 4910 | autosync_ref = "None"; break; |
3291 | case HDSPM_AES32_AUTOSYNC_FROM_AES1: autosync_ref="AES1"; break; | 4911 | case HDSPM_AES32_AUTOSYNC_FROM_WORD: |
3292 | case HDSPM_AES32_AUTOSYNC_FROM_AES2: autosync_ref="AES2"; break; | 4912 | autosync_ref = "Word Clock"; break; |
3293 | case HDSPM_AES32_AUTOSYNC_FROM_AES3: autosync_ref="AES3"; break; | 4913 | case HDSPM_AES32_AUTOSYNC_FROM_AES1: |
3294 | case HDSPM_AES32_AUTOSYNC_FROM_AES4: autosync_ref="AES4"; break; | 4914 | autosync_ref = "AES1"; break; |
3295 | case HDSPM_AES32_AUTOSYNC_FROM_AES5: autosync_ref="AES5"; break; | 4915 | case HDSPM_AES32_AUTOSYNC_FROM_AES2: |
3296 | case HDSPM_AES32_AUTOSYNC_FROM_AES6: autosync_ref="AES6"; break; | 4916 | autosync_ref = "AES2"; break; |
3297 | case HDSPM_AES32_AUTOSYNC_FROM_AES7: autosync_ref="AES7"; break; | 4917 | case HDSPM_AES32_AUTOSYNC_FROM_AES3: |
3298 | case HDSPM_AES32_AUTOSYNC_FROM_AES8: autosync_ref="AES8"; break; | 4918 | autosync_ref = "AES3"; break; |
3299 | default: autosync_ref = "---"; break; | 4919 | case HDSPM_AES32_AUTOSYNC_FROM_AES4: |
4920 | autosync_ref = "AES4"; break; | ||
4921 | case HDSPM_AES32_AUTOSYNC_FROM_AES5: | ||
4922 | autosync_ref = "AES5"; break; | ||
4923 | case HDSPM_AES32_AUTOSYNC_FROM_AES6: | ||
4924 | autosync_ref = "AES6"; break; | ||
4925 | case HDSPM_AES32_AUTOSYNC_FROM_AES7: | ||
4926 | autosync_ref = "AES7"; break; | ||
4927 | case HDSPM_AES32_AUTOSYNC_FROM_AES8: | ||
4928 | autosync_ref = "AES8"; break; | ||
4929 | default: | ||
4930 | autosync_ref = "---"; break; | ||
3300 | } | 4931 | } |
3301 | snd_iprintf(buffer, "AutoSync ref = %s\n", autosync_ref); | 4932 | snd_iprintf(buffer, "AutoSync ref = %s\n", autosync_ref); |
3302 | 4933 | ||
3303 | snd_iprintf(buffer, "\n"); | 4934 | snd_iprintf(buffer, "\n"); |
3304 | } | 4935 | } |
3305 | 4936 | ||
4937 | static void | ||
4938 | snd_hdspm_proc_read_raydat(struct snd_info_entry *entry, | ||
4939 | struct snd_info_buffer *buffer) | ||
4940 | { | ||
4941 | struct hdspm *hdspm = entry->private_data; | ||
4942 | unsigned int status1, status2, status3, control, i; | ||
4943 | unsigned int lock, sync; | ||
4944 | |||
4945 | status1 = hdspm_read(hdspm, HDSPM_RD_STATUS_1); /* s1 */ | ||
4946 | status2 = hdspm_read(hdspm, HDSPM_RD_STATUS_2); /* freq */ | ||
4947 | status3 = hdspm_read(hdspm, HDSPM_RD_STATUS_3); /* s2 */ | ||
4948 | |||
4949 | control = hdspm->control_register; | ||
4950 | |||
4951 | snd_iprintf(buffer, "STATUS1: 0x%08x\n", status1); | ||
4952 | snd_iprintf(buffer, "STATUS2: 0x%08x\n", status2); | ||
4953 | snd_iprintf(buffer, "STATUS3: 0x%08x\n", status3); | ||
4954 | |||
4955 | |||
4956 | snd_iprintf(buffer, "\n*** CLOCK MODE\n\n"); | ||
4957 | |||
4958 | snd_iprintf(buffer, "Clock mode : %s\n", | ||
4959 | (hdspm_system_clock_mode(hdspm) == 0) ? "master" : "slave"); | ||
4960 | snd_iprintf(buffer, "System frequency: %d Hz\n", | ||
4961 | hdspm_get_system_sample_rate(hdspm)); | ||
4962 | |||
4963 | snd_iprintf(buffer, "\n*** INPUT STATUS\n\n"); | ||
4964 | |||
4965 | lock = 0x1; | ||
4966 | sync = 0x100; | ||
4967 | |||
4968 | for (i = 0; i < 8; i++) { | ||
4969 | snd_iprintf(buffer, "s1_input %d: Lock %d, Sync %d, Freq %s\n", | ||
4970 | i, | ||
4971 | (status1 & lock) ? 1 : 0, | ||
4972 | (status1 & sync) ? 1 : 0, | ||
4973 | texts_freq[(status2 >> (i * 4)) & 0xF]); | ||
4974 | |||
4975 | lock = lock<<1; | ||
4976 | sync = sync<<1; | ||
4977 | } | ||
4978 | |||
4979 | snd_iprintf(buffer, "WC input: Lock %d, Sync %d, Freq %s\n", | ||
4980 | (status1 & 0x1000000) ? 1 : 0, | ||
4981 | (status1 & 0x2000000) ? 1 : 0, | ||
4982 | texts_freq[(status1 >> 16) & 0xF]); | ||
4983 | |||
4984 | snd_iprintf(buffer, "TCO input: Lock %d, Sync %d, Freq %s\n", | ||
4985 | (status1 & 0x4000000) ? 1 : 0, | ||
4986 | (status1 & 0x8000000) ? 1 : 0, | ||
4987 | texts_freq[(status1 >> 20) & 0xF]); | ||
4988 | |||
4989 | snd_iprintf(buffer, "SYNC IN: Lock %d, Sync %d, Freq %s\n", | ||
4990 | (status3 & 0x400) ? 1 : 0, | ||
4991 | (status3 & 0x800) ? 1 : 0, | ||
4992 | texts_freq[(status2 >> 12) & 0xF]); | ||
4993 | |||
4994 | } | ||
4995 | |||
3306 | #ifdef CONFIG_SND_DEBUG | 4996 | #ifdef CONFIG_SND_DEBUG |
3307 | static void | 4997 | static void |
3308 | snd_hdspm_proc_read_debug(struct snd_info_entry * entry, | 4998 | snd_hdspm_proc_read_debug(struct snd_info_entry *entry, |
3309 | struct snd_info_buffer *buffer) | 4999 | struct snd_info_buffer *buffer) |
3310 | { | 5000 | { |
3311 | struct hdspm *hdspm = entry->private_data; | 5001 | struct hdspm *hdspm = entry->private_data; |
@@ -3322,16 +5012,68 @@ snd_hdspm_proc_read_debug(struct snd_info_entry * entry, | |||
3322 | #endif | 5012 | #endif |
3323 | 5013 | ||
3324 | 5014 | ||
5015 | static void snd_hdspm_proc_ports_in(struct snd_info_entry *entry, | ||
5016 | struct snd_info_buffer *buffer) | ||
5017 | { | ||
5018 | struct hdspm *hdspm = entry->private_data; | ||
5019 | int i; | ||
5020 | |||
5021 | snd_iprintf(buffer, "# generated by hdspm\n"); | ||
5022 | |||
5023 | for (i = 0; i < hdspm->max_channels_in; i++) { | ||
5024 | snd_iprintf(buffer, "%d=%s\n", i+1, hdspm->port_names_in[i]); | ||
5025 | } | ||
5026 | } | ||
3325 | 5027 | ||
3326 | static void __devinit snd_hdspm_proc_init(struct hdspm * hdspm) | 5028 | static void snd_hdspm_proc_ports_out(struct snd_info_entry *entry, |
5029 | struct snd_info_buffer *buffer) | ||
5030 | { | ||
5031 | struct hdspm *hdspm = entry->private_data; | ||
5032 | int i; | ||
5033 | |||
5034 | snd_iprintf(buffer, "# generated by hdspm\n"); | ||
5035 | |||
5036 | for (i = 0; i < hdspm->max_channels_out; i++) { | ||
5037 | snd_iprintf(buffer, "%d=%s\n", i+1, hdspm->port_names_out[i]); | ||
5038 | } | ||
5039 | } | ||
5040 | |||
5041 | |||
5042 | static void __devinit snd_hdspm_proc_init(struct hdspm *hdspm) | ||
3327 | { | 5043 | { |
3328 | struct snd_info_entry *entry; | 5044 | struct snd_info_entry *entry; |
3329 | 5045 | ||
3330 | if (!snd_card_proc_new(hdspm->card, "hdspm", &entry)) | 5046 | if (!snd_card_proc_new(hdspm->card, "hdspm", &entry)) { |
3331 | snd_info_set_text_ops(entry, hdspm, | 5047 | switch (hdspm->io_type) { |
3332 | hdspm->is_aes32 ? | 5048 | case AES32: |
3333 | snd_hdspm_proc_read_aes32 : | 5049 | snd_info_set_text_ops(entry, hdspm, |
3334 | snd_hdspm_proc_read_madi); | 5050 | snd_hdspm_proc_read_aes32); |
5051 | break; | ||
5052 | case MADI: | ||
5053 | snd_info_set_text_ops(entry, hdspm, | ||
5054 | snd_hdspm_proc_read_madi); | ||
5055 | break; | ||
5056 | case MADIface: | ||
5057 | /* snd_info_set_text_ops(entry, hdspm, | ||
5058 | snd_hdspm_proc_read_madiface); */ | ||
5059 | break; | ||
5060 | case RayDAT: | ||
5061 | snd_info_set_text_ops(entry, hdspm, | ||
5062 | snd_hdspm_proc_read_raydat); | ||
5063 | break; | ||
5064 | case AIO: | ||
5065 | break; | ||
5066 | } | ||
5067 | } | ||
5068 | |||
5069 | if (!snd_card_proc_new(hdspm->card, "ports.in", &entry)) { | ||
5070 | snd_info_set_text_ops(entry, hdspm, snd_hdspm_proc_ports_in); | ||
5071 | } | ||
5072 | |||
5073 | if (!snd_card_proc_new(hdspm->card, "ports.out", &entry)) { | ||
5074 | snd_info_set_text_ops(entry, hdspm, snd_hdspm_proc_ports_out); | ||
5075 | } | ||
5076 | |||
3335 | #ifdef CONFIG_SND_DEBUG | 5077 | #ifdef CONFIG_SND_DEBUG |
3336 | /* debug file to read all hdspm registers */ | 5078 | /* debug file to read all hdspm registers */ |
3337 | if (!snd_card_proc_new(hdspm->card, "debug", &entry)) | 5079 | if (!snd_card_proc_new(hdspm->card, "debug", &entry)) |
@@ -3341,47 +5083,48 @@ static void __devinit snd_hdspm_proc_init(struct hdspm * hdspm) | |||
3341 | } | 5083 | } |
3342 | 5084 | ||
3343 | /*------------------------------------------------------------ | 5085 | /*------------------------------------------------------------ |
3344 | hdspm intitialize | 5086 | hdspm intitialize |
3345 | ------------------------------------------------------------*/ | 5087 | ------------------------------------------------------------*/ |
3346 | 5088 | ||
3347 | static int snd_hdspm_set_defaults(struct hdspm * hdspm) | 5089 | static int snd_hdspm_set_defaults(struct hdspm * hdspm) |
3348 | { | 5090 | { |
3349 | unsigned int i; | ||
3350 | |||
3351 | /* ASSUMPTION: hdspm->lock is either held, or there is no need to | 5091 | /* ASSUMPTION: hdspm->lock is either held, or there is no need to |
3352 | hold it (e.g. during module initialization). | 5092 | hold it (e.g. during module initialization). |
3353 | */ | 5093 | */ |
3354 | 5094 | ||
3355 | /* set defaults: */ | 5095 | /* set defaults: */ |
3356 | 5096 | ||
3357 | if (hdspm->is_aes32) | 5097 | hdspm->settings_register = 0; |
5098 | |||
5099 | switch (hdspm->io_type) { | ||
5100 | case MADI: | ||
5101 | case MADIface: | ||
5102 | hdspm->control_register = | ||
5103 | 0x2 + 0x8 + 0x10 + 0x80 + 0x400 + 0x4000 + 0x1000000; | ||
5104 | break; | ||
5105 | |||
5106 | case RayDAT: | ||
5107 | case AIO: | ||
5108 | hdspm->settings_register = 0x1 + 0x1000; | ||
5109 | /* Magic values are: LAT_0, LAT_2, Master, freq1, tx64ch, inp_0, | ||
5110 | * line_out */ | ||
5111 | hdspm->control_register = | ||
5112 | 0x2 + 0x8 + 0x10 + 0x80 + 0x400 + 0x4000 + 0x1000000; | ||
5113 | break; | ||
5114 | |||
5115 | case AES32: | ||
3358 | hdspm->control_register = | 5116 | hdspm->control_register = |
3359 | HDSPM_ClockModeMaster | /* Master Cloack Mode on */ | 5117 | HDSPM_ClockModeMaster | /* Master Cloack Mode on */ |
3360 | hdspm_encode_latency(7) | /* latency maximum = | 5118 | hdspm_encode_latency(7) | /* latency max=8192samples */ |
3361 | * 8192 samples | ||
3362 | */ | ||
3363 | HDSPM_SyncRef0 | /* AES1 is syncclock */ | 5119 | HDSPM_SyncRef0 | /* AES1 is syncclock */ |
3364 | HDSPM_LineOut | /* Analog output in */ | 5120 | HDSPM_LineOut | /* Analog output in */ |
3365 | HDSPM_Professional; /* Professional mode */ | 5121 | HDSPM_Professional; /* Professional mode */ |
3366 | else | 5122 | break; |
3367 | hdspm->control_register = | 5123 | } |
3368 | HDSPM_ClockModeMaster | /* Master Cloack Mode on */ | ||
3369 | hdspm_encode_latency(7) | /* latency maximum = | ||
3370 | * 8192 samples | ||
3371 | */ | ||
3372 | HDSPM_InputCoaxial | /* Input Coax not Optical */ | ||
3373 | HDSPM_SyncRef_MADI | /* Madi is syncclock */ | ||
3374 | HDSPM_LineOut | /* Analog output in */ | ||
3375 | HDSPM_TX_64ch | /* transmit in 64ch mode */ | ||
3376 | HDSPM_AutoInp; /* AutoInput chossing (takeover) */ | ||
3377 | |||
3378 | /* ! HDSPM_Frequency0|HDSPM_Frequency1 = 44.1khz */ | ||
3379 | /* ! HDSPM_DoubleSpeed HDSPM_QuadSpeed = normal speed */ | ||
3380 | /* ! HDSPM_clr_tms = do not clear bits in track marks */ | ||
3381 | 5124 | ||
3382 | hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register); | 5125 | hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register); |
3383 | 5126 | ||
3384 | if (!hdspm->is_aes32) { | 5127 | if (AES32 == hdspm->io_type) { |
3385 | /* No control2 register for AES32 */ | 5128 | /* No control2 register for AES32 */ |
3386 | #ifdef SNDRV_BIG_ENDIAN | 5129 | #ifdef SNDRV_BIG_ENDIAN |
3387 | hdspm->control2_register = HDSPM_BIGENDIAN_MODE; | 5130 | hdspm->control2_register = HDSPM_BIGENDIAN_MODE; |
@@ -3397,57 +5140,59 @@ static int snd_hdspm_set_defaults(struct hdspm * hdspm) | |||
3397 | 5140 | ||
3398 | all_in_all_mixer(hdspm, 0 * UNITY_GAIN); | 5141 | all_in_all_mixer(hdspm, 0 * UNITY_GAIN); |
3399 | 5142 | ||
3400 | if (line_outs_monitor[hdspm->dev]) { | 5143 | if (hdspm->io_type == AIO || hdspm->io_type == RayDAT) { |
3401 | 5144 | hdspm_write(hdspm, HDSPM_WR_SETTINGS, hdspm->settings_register); | |
3402 | snd_printk(KERN_INFO "HDSPM: " | ||
3403 | "sending all playback streams to line outs.\n"); | ||
3404 | |||
3405 | for (i = 0; i < HDSPM_MIXER_CHANNELS; i++) { | ||
3406 | if (hdspm_write_pb_gain(hdspm, i, i, UNITY_GAIN)) | ||
3407 | return -EIO; | ||
3408 | } | ||
3409 | } | 5145 | } |
3410 | 5146 | ||
3411 | /* set a default rate so that the channel map is set up. */ | 5147 | /* set a default rate so that the channel map is set up. */ |
3412 | hdspm->channel_map = channel_map_madi_ss; | 5148 | hdspm_set_rate(hdspm, 48000, 1); |
3413 | hdspm_set_rate(hdspm, 44100, 1); | ||
3414 | 5149 | ||
3415 | return 0; | 5150 | return 0; |
3416 | } | 5151 | } |
3417 | 5152 | ||
3418 | 5153 | ||
3419 | /*------------------------------------------------------------ | 5154 | /*------------------------------------------------------------ |
3420 | interrupt | 5155 | interrupt |
3421 | ------------------------------------------------------------*/ | 5156 | ------------------------------------------------------------*/ |
3422 | 5157 | ||
3423 | static irqreturn_t snd_hdspm_interrupt(int irq, void *dev_id) | 5158 | static irqreturn_t snd_hdspm_interrupt(int irq, void *dev_id) |
3424 | { | 5159 | { |
3425 | struct hdspm *hdspm = (struct hdspm *) dev_id; | 5160 | struct hdspm *hdspm = (struct hdspm *) dev_id; |
3426 | unsigned int status; | 5161 | unsigned int status; |
3427 | int audio; | 5162 | int i, audio, midi, schedule = 0; |
3428 | int midi0; | 5163 | /* cycles_t now; */ |
3429 | int midi1; | ||
3430 | unsigned int midi0status; | ||
3431 | unsigned int midi1status; | ||
3432 | int schedule = 0; | ||
3433 | 5164 | ||
3434 | status = hdspm_read(hdspm, HDSPM_statusRegister); | 5165 | status = hdspm_read(hdspm, HDSPM_statusRegister); |
3435 | 5166 | ||
3436 | audio = status & HDSPM_audioIRQPending; | 5167 | audio = status & HDSPM_audioIRQPending; |
3437 | midi0 = status & HDSPM_midi0IRQPending; | 5168 | midi = status & (HDSPM_midi0IRQPending | HDSPM_midi1IRQPending | |
3438 | midi1 = status & HDSPM_midi1IRQPending; | 5169 | HDSPM_midi2IRQPending | HDSPM_midi3IRQPending); |
5170 | |||
5171 | /* now = get_cycles(); */ | ||
5172 | /** | ||
5173 | * LAT_2..LAT_0 period counter (win) counter (mac) | ||
5174 | * 6 4096 ~256053425 ~514672358 | ||
5175 | * 5 2048 ~128024983 ~257373821 | ||
5176 | * 4 1024 ~64023706 ~128718089 | ||
5177 | * 3 512 ~32005945 ~64385999 | ||
5178 | * 2 256 ~16003039 ~32260176 | ||
5179 | * 1 128 ~7998738 ~16194507 | ||
5180 | * 0 64 ~3998231 ~8191558 | ||
5181 | **/ | ||
5182 | /* | ||
5183 | snd_printk(KERN_INFO "snd_hdspm_interrupt %llu @ %llx\n", | ||
5184 | now-hdspm->last_interrupt, status & 0xFFC0); | ||
5185 | hdspm->last_interrupt = now; | ||
5186 | */ | ||
3439 | 5187 | ||
3440 | if (!audio && !midi0 && !midi1) | 5188 | if (!audio && !midi) |
3441 | return IRQ_NONE; | 5189 | return IRQ_NONE; |
3442 | 5190 | ||
3443 | hdspm_write(hdspm, HDSPM_interruptConfirmation, 0); | 5191 | hdspm_write(hdspm, HDSPM_interruptConfirmation, 0); |
3444 | hdspm->irq_count++; | 5192 | hdspm->irq_count++; |
3445 | 5193 | ||
3446 | midi0status = hdspm_read(hdspm, HDSPM_midiStatusIn0) & 0xff; | ||
3447 | midi1status = hdspm_read(hdspm, HDSPM_midiStatusIn1) & 0xff; | ||
3448 | 5194 | ||
3449 | if (audio) { | 5195 | if (audio) { |
3450 | |||
3451 | if (hdspm->capture_substream) | 5196 | if (hdspm->capture_substream) |
3452 | snd_pcm_period_elapsed(hdspm->capture_substream); | 5197 | snd_pcm_period_elapsed(hdspm->capture_substream); |
3453 | 5198 | ||
@@ -3455,118 +5200,44 @@ static irqreturn_t snd_hdspm_interrupt(int irq, void *dev_id) | |||
3455 | snd_pcm_period_elapsed(hdspm->playback_substream); | 5200 | snd_pcm_period_elapsed(hdspm->playback_substream); |
3456 | } | 5201 | } |
3457 | 5202 | ||
3458 | if (midi0 && midi0status) { | 5203 | if (midi) { |
3459 | /* we disable interrupts for this input until processing | 5204 | i = 0; |
3460 | * is done | 5205 | while (i < hdspm->midiPorts) { |
3461 | */ | 5206 | if ((hdspm_read(hdspm, |
3462 | hdspm->control_register &= ~HDSPM_Midi0InterruptEnable; | 5207 | hdspm->midi[i].statusIn) & 0xff) && |
3463 | hdspm_write(hdspm, HDSPM_controlRegister, | 5208 | (status & hdspm->midi[i].irq)) { |
3464 | hdspm->control_register); | 5209 | /* we disable interrupts for this input until |
3465 | hdspm->midi[0].pending = 1; | 5210 | * processing is done |
3466 | schedule = 1; | 5211 | */ |
3467 | } | 5212 | hdspm->control_register &= ~hdspm->midi[i].ie; |
3468 | if (midi1 && midi1status) { | 5213 | hdspm_write(hdspm, HDSPM_controlRegister, |
3469 | /* we disable interrupts for this input until processing | 5214 | hdspm->control_register); |
3470 | * is done | 5215 | hdspm->midi[i].pending = 1; |
3471 | */ | 5216 | schedule = 1; |
3472 | hdspm->control_register &= ~HDSPM_Midi1InterruptEnable; | 5217 | } |
3473 | hdspm_write(hdspm, HDSPM_controlRegister, | 5218 | |
3474 | hdspm->control_register); | 5219 | i++; |
3475 | hdspm->midi[1].pending = 1; | 5220 | } |
3476 | schedule = 1; | 5221 | |
5222 | if (schedule) | ||
5223 | tasklet_hi_schedule(&hdspm->midi_tasklet); | ||
3477 | } | 5224 | } |
3478 | if (schedule) | 5225 | |
3479 | tasklet_schedule(&hdspm->midi_tasklet); | ||
3480 | return IRQ_HANDLED; | 5226 | return IRQ_HANDLED; |
3481 | } | 5227 | } |
3482 | 5228 | ||
3483 | /*------------------------------------------------------------ | 5229 | /*------------------------------------------------------------ |
3484 | pcm interface | 5230 | pcm interface |
3485 | ------------------------------------------------------------*/ | 5231 | ------------------------------------------------------------*/ |
3486 | 5232 | ||
3487 | 5233 | ||
3488 | static snd_pcm_uframes_t snd_hdspm_hw_pointer(struct snd_pcm_substream * | 5234 | static snd_pcm_uframes_t snd_hdspm_hw_pointer(struct snd_pcm_substream |
3489 | substream) | 5235 | *substream) |
3490 | { | 5236 | { |
3491 | struct hdspm *hdspm = snd_pcm_substream_chip(substream); | 5237 | struct hdspm *hdspm = snd_pcm_substream_chip(substream); |
3492 | return hdspm_hw_pointer(hdspm); | 5238 | return hdspm_hw_pointer(hdspm); |
3493 | } | 5239 | } |
3494 | 5240 | ||
3495 | static char *hdspm_channel_buffer_location(struct hdspm * hdspm, | ||
3496 | int stream, int channel) | ||
3497 | { | ||
3498 | int mapped_channel; | ||
3499 | |||
3500 | if (snd_BUG_ON(channel < 0 || channel >= HDSPM_MAX_CHANNELS)) | ||
3501 | return NULL; | ||
3502 | |||
3503 | mapped_channel = hdspm->channel_map[channel]; | ||
3504 | if (mapped_channel < 0) | ||
3505 | return NULL; | ||
3506 | |||
3507 | if (stream == SNDRV_PCM_STREAM_CAPTURE) | ||
3508 | return hdspm->capture_buffer + | ||
3509 | mapped_channel * HDSPM_CHANNEL_BUFFER_BYTES; | ||
3510 | else | ||
3511 | return hdspm->playback_buffer + | ||
3512 | mapped_channel * HDSPM_CHANNEL_BUFFER_BYTES; | ||
3513 | } | ||
3514 | |||
3515 | |||
3516 | /* dont know why need it ??? */ | ||
3517 | static int snd_hdspm_playback_copy(struct snd_pcm_substream *substream, | ||
3518 | int channel, snd_pcm_uframes_t pos, | ||
3519 | void __user *src, snd_pcm_uframes_t count) | ||
3520 | { | ||
3521 | struct hdspm *hdspm = snd_pcm_substream_chip(substream); | ||
3522 | char *channel_buf; | ||
3523 | |||
3524 | if (snd_BUG_ON(pos + count > HDSPM_CHANNEL_BUFFER_BYTES / 4)) | ||
3525 | return -EINVAL; | ||
3526 | |||
3527 | channel_buf = | ||
3528 | hdspm_channel_buffer_location(hdspm, substream->pstr->stream, | ||
3529 | channel); | ||
3530 | |||
3531 | if (snd_BUG_ON(!channel_buf)) | ||
3532 | return -EIO; | ||
3533 | |||
3534 | return copy_from_user(channel_buf + pos * 4, src, count * 4); | ||
3535 | } | ||
3536 | |||
3537 | static int snd_hdspm_capture_copy(struct snd_pcm_substream *substream, | ||
3538 | int channel, snd_pcm_uframes_t pos, | ||
3539 | void __user *dst, snd_pcm_uframes_t count) | ||
3540 | { | ||
3541 | struct hdspm *hdspm = snd_pcm_substream_chip(substream); | ||
3542 | char *channel_buf; | ||
3543 | |||
3544 | if (snd_BUG_ON(pos + count > HDSPM_CHANNEL_BUFFER_BYTES / 4)) | ||
3545 | return -EINVAL; | ||
3546 | |||
3547 | channel_buf = | ||
3548 | hdspm_channel_buffer_location(hdspm, substream->pstr->stream, | ||
3549 | channel); | ||
3550 | if (snd_BUG_ON(!channel_buf)) | ||
3551 | return -EIO; | ||
3552 | return copy_to_user(dst, channel_buf + pos * 4, count * 4); | ||
3553 | } | ||
3554 | |||
3555 | static int snd_hdspm_hw_silence(struct snd_pcm_substream *substream, | ||
3556 | int channel, snd_pcm_uframes_t pos, | ||
3557 | snd_pcm_uframes_t count) | ||
3558 | { | ||
3559 | struct hdspm *hdspm = snd_pcm_substream_chip(substream); | ||
3560 | char *channel_buf; | ||
3561 | |||
3562 | channel_buf = | ||
3563 | hdspm_channel_buffer_location(hdspm, substream->pstr->stream, | ||
3564 | channel); | ||
3565 | if (snd_BUG_ON(!channel_buf)) | ||
3566 | return -EIO; | ||
3567 | memset(channel_buf + pos * 4, 0, count * 4); | ||
3568 | return 0; | ||
3569 | } | ||
3570 | 5241 | ||
3571 | static int snd_hdspm_reset(struct snd_pcm_substream *substream) | 5242 | static int snd_hdspm_reset(struct snd_pcm_substream *substream) |
3572 | { | 5243 | { |
@@ -3589,7 +5260,7 @@ static int snd_hdspm_reset(struct snd_pcm_substream *substream) | |||
3589 | snd_pcm_group_for_each_entry(s, substream) { | 5260 | snd_pcm_group_for_each_entry(s, substream) { |
3590 | if (s == other) { | 5261 | if (s == other) { |
3591 | oruntime->status->hw_ptr = | 5262 | oruntime->status->hw_ptr = |
3592 | runtime->status->hw_ptr; | 5263 | runtime->status->hw_ptr; |
3593 | break; | 5264 | break; |
3594 | } | 5265 | } |
3595 | } | 5266 | } |
@@ -3621,19 +5292,19 @@ static int snd_hdspm_hw_params(struct snd_pcm_substream *substream, | |||
3621 | /* The other stream is open, and not by the same | 5292 | /* The other stream is open, and not by the same |
3622 | task as this one. Make sure that the parameters | 5293 | task as this one. Make sure that the parameters |
3623 | that matter are the same. | 5294 | that matter are the same. |
3624 | */ | 5295 | */ |
3625 | 5296 | ||
3626 | if (params_rate(params) != hdspm->system_sample_rate) { | 5297 | if (params_rate(params) != hdspm->system_sample_rate) { |
3627 | spin_unlock_irq(&hdspm->lock); | 5298 | spin_unlock_irq(&hdspm->lock); |
3628 | _snd_pcm_hw_param_setempty(params, | 5299 | _snd_pcm_hw_param_setempty(params, |
3629 | SNDRV_PCM_HW_PARAM_RATE); | 5300 | SNDRV_PCM_HW_PARAM_RATE); |
3630 | return -EBUSY; | 5301 | return -EBUSY; |
3631 | } | 5302 | } |
3632 | 5303 | ||
3633 | if (params_period_size(params) != hdspm->period_bytes / 4) { | 5304 | if (params_period_size(params) != hdspm->period_bytes / 4) { |
3634 | spin_unlock_irq(&hdspm->lock); | 5305 | spin_unlock_irq(&hdspm->lock); |
3635 | _snd_pcm_hw_param_setempty(params, | 5306 | _snd_pcm_hw_param_setempty(params, |
3636 | SNDRV_PCM_HW_PARAM_PERIOD_SIZE); | 5307 | SNDRV_PCM_HW_PARAM_PERIOD_SIZE); |
3637 | return -EBUSY; | 5308 | return -EBUSY; |
3638 | } | 5309 | } |
3639 | 5310 | ||
@@ -3646,18 +5317,20 @@ static int snd_hdspm_hw_params(struct snd_pcm_substream *substream, | |||
3646 | spin_lock_irq(&hdspm->lock); | 5317 | spin_lock_irq(&hdspm->lock); |
3647 | err = hdspm_set_rate(hdspm, params_rate(params), 0); | 5318 | err = hdspm_set_rate(hdspm, params_rate(params), 0); |
3648 | if (err < 0) { | 5319 | if (err < 0) { |
5320 | snd_printk(KERN_INFO "err on hdspm_set_rate: %d\n", err); | ||
3649 | spin_unlock_irq(&hdspm->lock); | 5321 | spin_unlock_irq(&hdspm->lock); |
3650 | _snd_pcm_hw_param_setempty(params, | 5322 | _snd_pcm_hw_param_setempty(params, |
3651 | SNDRV_PCM_HW_PARAM_RATE); | 5323 | SNDRV_PCM_HW_PARAM_RATE); |
3652 | return err; | 5324 | return err; |
3653 | } | 5325 | } |
3654 | spin_unlock_irq(&hdspm->lock); | 5326 | spin_unlock_irq(&hdspm->lock); |
3655 | 5327 | ||
3656 | err = hdspm_set_interrupt_interval(hdspm, | 5328 | err = hdspm_set_interrupt_interval(hdspm, |
3657 | params_period_size(params)); | 5329 | params_period_size(params)); |
3658 | if (err < 0) { | 5330 | if (err < 0) { |
5331 | snd_printk(KERN_INFO "err on hdspm_set_interrupt_interval: %d\n", err); | ||
3659 | _snd_pcm_hw_param_setempty(params, | 5332 | _snd_pcm_hw_param_setempty(params, |
3660 | SNDRV_PCM_HW_PARAM_PERIOD_SIZE); | 5333 | SNDRV_PCM_HW_PARAM_PERIOD_SIZE); |
3661 | return err; | 5334 | return err; |
3662 | } | 5335 | } |
3663 | 5336 | ||
@@ -3667,10 +5340,13 @@ static int snd_hdspm_hw_params(struct snd_pcm_substream *substream, | |||
3667 | /* malloc all buffer even if not enabled to get sure */ | 5340 | /* malloc all buffer even if not enabled to get sure */ |
3668 | /* Update for MADI rev 204: we need to allocate for all channels, | 5341 | /* Update for MADI rev 204: we need to allocate for all channels, |
3669 | * otherwise it doesn't work at 96kHz */ | 5342 | * otherwise it doesn't work at 96kHz */ |
5343 | |||
3670 | err = | 5344 | err = |
3671 | snd_pcm_lib_malloc_pages(substream, HDSPM_DMA_AREA_BYTES); | 5345 | snd_pcm_lib_malloc_pages(substream, HDSPM_DMA_AREA_BYTES); |
3672 | if (err < 0) | 5346 | if (err < 0) { |
5347 | snd_printk(KERN_INFO "err on snd_pcm_lib_malloc_pages: %d\n", err); | ||
3673 | return err; | 5348 | return err; |
5349 | } | ||
3674 | 5350 | ||
3675 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | 5351 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
3676 | 5352 | ||
@@ -3681,7 +5357,7 @@ static int snd_hdspm_hw_params(struct snd_pcm_substream *substream, | |||
3681 | snd_hdspm_enable_out(hdspm, i, 1); | 5357 | snd_hdspm_enable_out(hdspm, i, 1); |
3682 | 5358 | ||
3683 | hdspm->playback_buffer = | 5359 | hdspm->playback_buffer = |
3684 | (unsigned char *) substream->runtime->dma_area; | 5360 | (unsigned char *) substream->runtime->dma_area; |
3685 | snd_printdd("Allocated sample buffer for playback at %p\n", | 5361 | snd_printdd("Allocated sample buffer for playback at %p\n", |
3686 | hdspm->playback_buffer); | 5362 | hdspm->playback_buffer); |
3687 | } else { | 5363 | } else { |
@@ -3692,23 +5368,40 @@ static int snd_hdspm_hw_params(struct snd_pcm_substream *substream, | |||
3692 | snd_hdspm_enable_in(hdspm, i, 1); | 5368 | snd_hdspm_enable_in(hdspm, i, 1); |
3693 | 5369 | ||
3694 | hdspm->capture_buffer = | 5370 | hdspm->capture_buffer = |
3695 | (unsigned char *) substream->runtime->dma_area; | 5371 | (unsigned char *) substream->runtime->dma_area; |
3696 | snd_printdd("Allocated sample buffer for capture at %p\n", | 5372 | snd_printdd("Allocated sample buffer for capture at %p\n", |
3697 | hdspm->capture_buffer); | 5373 | hdspm->capture_buffer); |
3698 | } | 5374 | } |
5375 | |||
3699 | /* | 5376 | /* |
3700 | snd_printdd("Allocated sample buffer for %s at 0x%08X\n", | 5377 | snd_printdd("Allocated sample buffer for %s at 0x%08X\n", |
3701 | substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? | 5378 | substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? |
3702 | "playback" : "capture", | 5379 | "playback" : "capture", |
3703 | snd_pcm_sgbuf_get_addr(substream, 0)); | 5380 | snd_pcm_sgbuf_get_addr(substream, 0)); |
3704 | */ | 5381 | */ |
3705 | /* | 5382 | /* |
3706 | snd_printdd("set_hwparams: %s %d Hz, %d channels, bs = %d\n", | 5383 | snd_printdd("set_hwparams: %s %d Hz, %d channels, bs = %d\n", |
3707 | substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? | 5384 | substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? |
3708 | "playback" : "capture", | 5385 | "playback" : "capture", |
3709 | params_rate(params), params_channels(params), | 5386 | params_rate(params), params_channels(params), |
3710 | params_buffer_size(params)); | 5387 | params_buffer_size(params)); |
3711 | */ | 5388 | */ |
5389 | |||
5390 | |||
5391 | /* Switch to native float format if requested */ | ||
5392 | if (SNDRV_PCM_FORMAT_FLOAT_LE == params_format(params)) { | ||
5393 | if (!(hdspm->control_register & HDSPe_FLOAT_FORMAT)) | ||
5394 | snd_printk(KERN_INFO "hdspm: Switching to native 32bit LE float format.\n"); | ||
5395 | |||
5396 | hdspm->control_register |= HDSPe_FLOAT_FORMAT; | ||
5397 | } else if (SNDRV_PCM_FORMAT_S32_LE == params_format(params)) { | ||
5398 | if (hdspm->control_register & HDSPe_FLOAT_FORMAT) | ||
5399 | snd_printk(KERN_INFO "hdspm: Switching to native 32bit LE integer format.\n"); | ||
5400 | |||
5401 | hdspm->control_register &= ~HDSPe_FLOAT_FORMAT; | ||
5402 | } | ||
5403 | hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register); | ||
5404 | |||
3712 | return 0; | 5405 | return 0; |
3713 | } | 5406 | } |
3714 | 5407 | ||
@@ -3719,14 +5412,14 @@ static int snd_hdspm_hw_free(struct snd_pcm_substream *substream) | |||
3719 | 5412 | ||
3720 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | 5413 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
3721 | 5414 | ||
3722 | /* params_channels(params) should be enough, | 5415 | /* params_channels(params) should be enough, |
3723 | but to get sure in case of error */ | 5416 | but to get sure in case of error */ |
3724 | for (i = 0; i < HDSPM_MAX_CHANNELS; ++i) | 5417 | for (i = 0; i < hdspm->max_channels_out; ++i) |
3725 | snd_hdspm_enable_out(hdspm, i, 0); | 5418 | snd_hdspm_enable_out(hdspm, i, 0); |
3726 | 5419 | ||
3727 | hdspm->playback_buffer = NULL; | 5420 | hdspm->playback_buffer = NULL; |
3728 | } else { | 5421 | } else { |
3729 | for (i = 0; i < HDSPM_MAX_CHANNELS; ++i) | 5422 | for (i = 0; i < hdspm->max_channels_in; ++i) |
3730 | snd_hdspm_enable_in(hdspm, i, 0); | 5423 | snd_hdspm_enable_in(hdspm, i, 0); |
3731 | 5424 | ||
3732 | hdspm->capture_buffer = NULL; | 5425 | hdspm->capture_buffer = NULL; |
@@ -3738,37 +5431,58 @@ static int snd_hdspm_hw_free(struct snd_pcm_substream *substream) | |||
3738 | return 0; | 5431 | return 0; |
3739 | } | 5432 | } |
3740 | 5433 | ||
5434 | |||
3741 | static int snd_hdspm_channel_info(struct snd_pcm_substream *substream, | 5435 | static int snd_hdspm_channel_info(struct snd_pcm_substream *substream, |
3742 | struct snd_pcm_channel_info * info) | 5436 | struct snd_pcm_channel_info *info) |
3743 | { | 5437 | { |
3744 | struct hdspm *hdspm = snd_pcm_substream_chip(substream); | 5438 | struct hdspm *hdspm = snd_pcm_substream_chip(substream); |
3745 | int mapped_channel; | ||
3746 | 5439 | ||
3747 | if (snd_BUG_ON(info->channel >= HDSPM_MAX_CHANNELS)) | 5440 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
3748 | return -EINVAL; | 5441 | if (snd_BUG_ON(info->channel >= hdspm->max_channels_out)) { |
5442 | snd_printk(KERN_INFO "snd_hdspm_channel_info: output channel out of range (%d)\n", info->channel); | ||
5443 | return -EINVAL; | ||
5444 | } | ||
3749 | 5445 | ||
3750 | mapped_channel = hdspm->channel_map[info->channel]; | 5446 | if (hdspm->channel_map_out[info->channel] < 0) { |
3751 | if (mapped_channel < 0) | 5447 | snd_printk(KERN_INFO "snd_hdspm_channel_info: output channel %d mapped out\n", info->channel); |
3752 | return -EINVAL; | 5448 | return -EINVAL; |
5449 | } | ||
5450 | |||
5451 | info->offset = hdspm->channel_map_out[info->channel] * | ||
5452 | HDSPM_CHANNEL_BUFFER_BYTES; | ||
5453 | } else { | ||
5454 | if (snd_BUG_ON(info->channel >= hdspm->max_channels_in)) { | ||
5455 | snd_printk(KERN_INFO "snd_hdspm_channel_info: input channel out of range (%d)\n", info->channel); | ||
5456 | return -EINVAL; | ||
5457 | } | ||
5458 | |||
5459 | if (hdspm->channel_map_in[info->channel] < 0) { | ||
5460 | snd_printk(KERN_INFO "snd_hdspm_channel_info: input channel %d mapped out\n", info->channel); | ||
5461 | return -EINVAL; | ||
5462 | } | ||
5463 | |||
5464 | info->offset = hdspm->channel_map_in[info->channel] * | ||
5465 | HDSPM_CHANNEL_BUFFER_BYTES; | ||
5466 | } | ||
3753 | 5467 | ||
3754 | info->offset = mapped_channel * HDSPM_CHANNEL_BUFFER_BYTES; | ||
3755 | info->first = 0; | 5468 | info->first = 0; |
3756 | info->step = 32; | 5469 | info->step = 32; |
3757 | return 0; | 5470 | return 0; |
3758 | } | 5471 | } |
3759 | 5472 | ||
5473 | |||
3760 | static int snd_hdspm_ioctl(struct snd_pcm_substream *substream, | 5474 | static int snd_hdspm_ioctl(struct snd_pcm_substream *substream, |
3761 | unsigned int cmd, void *arg) | 5475 | unsigned int cmd, void *arg) |
3762 | { | 5476 | { |
3763 | switch (cmd) { | 5477 | switch (cmd) { |
3764 | case SNDRV_PCM_IOCTL1_RESET: | 5478 | case SNDRV_PCM_IOCTL1_RESET: |
3765 | return snd_hdspm_reset(substream); | 5479 | return snd_hdspm_reset(substream); |
3766 | 5480 | ||
3767 | case SNDRV_PCM_IOCTL1_CHANNEL_INFO: | 5481 | case SNDRV_PCM_IOCTL1_CHANNEL_INFO: |
3768 | { | 5482 | { |
3769 | struct snd_pcm_channel_info *info = arg; | 5483 | struct snd_pcm_channel_info *info = arg; |
3770 | return snd_hdspm_channel_info(substream, info); | 5484 | return snd_hdspm_channel_info(substream, info); |
3771 | } | 5485 | } |
3772 | default: | 5486 | default: |
3773 | break; | 5487 | break; |
3774 | } | 5488 | } |
@@ -3815,19 +5529,19 @@ static int snd_hdspm_trigger(struct snd_pcm_substream *substream, int cmd) | |||
3815 | } | 5529 | } |
3816 | if (cmd == SNDRV_PCM_TRIGGER_START) { | 5530 | if (cmd == SNDRV_PCM_TRIGGER_START) { |
3817 | if (!(running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) | 5531 | if (!(running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) |
3818 | && substream->stream == | 5532 | && substream->stream == |
3819 | SNDRV_PCM_STREAM_CAPTURE) | 5533 | SNDRV_PCM_STREAM_CAPTURE) |
3820 | hdspm_silence_playback(hdspm); | 5534 | hdspm_silence_playback(hdspm); |
3821 | } else { | 5535 | } else { |
3822 | if (running && | 5536 | if (running && |
3823 | substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 5537 | substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
3824 | hdspm_silence_playback(hdspm); | 5538 | hdspm_silence_playback(hdspm); |
3825 | } | 5539 | } |
3826 | } else { | 5540 | } else { |
3827 | if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) | 5541 | if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) |
3828 | hdspm_silence_playback(hdspm); | 5542 | hdspm_silence_playback(hdspm); |
3829 | } | 5543 | } |
3830 | _ok: | 5544 | _ok: |
3831 | snd_pcm_trigger_done(substream, substream); | 5545 | snd_pcm_trigger_done(substream, substream); |
3832 | if (!hdspm->running && running) | 5546 | if (!hdspm->running && running) |
3833 | hdspm_start_audio(hdspm); | 5547 | hdspm_start_audio(hdspm); |
@@ -3844,8 +5558,18 @@ static int snd_hdspm_prepare(struct snd_pcm_substream *substream) | |||
3844 | return 0; | 5558 | return 0; |
3845 | } | 5559 | } |
3846 | 5560 | ||
3847 | static unsigned int period_sizes[] = | 5561 | static unsigned int period_sizes_old[] = { |
3848 | { 64, 128, 256, 512, 1024, 2048, 4096, 8192 }; | 5562 | 64, 128, 256, 512, 1024, 2048, 4096 |
5563 | }; | ||
5564 | |||
5565 | static unsigned int period_sizes_new[] = { | ||
5566 | 32, 64, 128, 256, 512, 1024, 2048, 4096 | ||
5567 | }; | ||
5568 | |||
5569 | /* RayDAT and AIO always have a buffer of 16384 samples per channel */ | ||
5570 | static unsigned int raydat_aio_buffer_sizes[] = { | ||
5571 | 16384 | ||
5572 | }; | ||
3849 | 5573 | ||
3850 | static struct snd_pcm_hardware snd_hdspm_playback_subinfo = { | 5574 | static struct snd_pcm_hardware snd_hdspm_playback_subinfo = { |
3851 | .info = (SNDRV_PCM_INFO_MMAP | | 5575 | .info = (SNDRV_PCM_INFO_MMAP | |
@@ -3866,9 +5590,9 @@ static struct snd_pcm_hardware snd_hdspm_playback_subinfo = { | |||
3866 | .buffer_bytes_max = | 5590 | .buffer_bytes_max = |
3867 | HDSPM_CHANNEL_BUFFER_BYTES * HDSPM_MAX_CHANNELS, | 5591 | HDSPM_CHANNEL_BUFFER_BYTES * HDSPM_MAX_CHANNELS, |
3868 | .period_bytes_min = (64 * 4), | 5592 | .period_bytes_min = (64 * 4), |
3869 | .period_bytes_max = (8192 * 4) * HDSPM_MAX_CHANNELS, | 5593 | .period_bytes_max = (4096 * 4) * HDSPM_MAX_CHANNELS, |
3870 | .periods_min = 2, | 5594 | .periods_min = 2, |
3871 | .periods_max = 2, | 5595 | .periods_max = 512, |
3872 | .fifo_size = 0 | 5596 | .fifo_size = 0 |
3873 | }; | 5597 | }; |
3874 | 5598 | ||
@@ -3891,20 +5615,66 @@ static struct snd_pcm_hardware snd_hdspm_capture_subinfo = { | |||
3891 | .buffer_bytes_max = | 5615 | .buffer_bytes_max = |
3892 | HDSPM_CHANNEL_BUFFER_BYTES * HDSPM_MAX_CHANNELS, | 5616 | HDSPM_CHANNEL_BUFFER_BYTES * HDSPM_MAX_CHANNELS, |
3893 | .period_bytes_min = (64 * 4), | 5617 | .period_bytes_min = (64 * 4), |
3894 | .period_bytes_max = (8192 * 4) * HDSPM_MAX_CHANNELS, | 5618 | .period_bytes_max = (4096 * 4) * HDSPM_MAX_CHANNELS, |
3895 | .periods_min = 2, | 5619 | .periods_min = 2, |
3896 | .periods_max = 2, | 5620 | .periods_max = 512, |
3897 | .fifo_size = 0 | 5621 | .fifo_size = 0 |
3898 | }; | 5622 | }; |
3899 | 5623 | ||
3900 | static struct snd_pcm_hw_constraint_list hw_constraints_period_sizes = { | 5624 | static struct snd_pcm_hw_constraint_list hw_constraints_period_sizes_old = { |
3901 | .count = ARRAY_SIZE(period_sizes), | 5625 | .count = ARRAY_SIZE(period_sizes_old), |
3902 | .list = period_sizes, | 5626 | .list = period_sizes_old, |
3903 | .mask = 0 | 5627 | .mask = 0 |
3904 | }; | 5628 | }; |
3905 | 5629 | ||
5630 | static struct snd_pcm_hw_constraint_list hw_constraints_period_sizes_new = { | ||
5631 | .count = ARRAY_SIZE(period_sizes_new), | ||
5632 | .list = period_sizes_new, | ||
5633 | .mask = 0 | ||
5634 | }; | ||
3906 | 5635 | ||
3907 | static int snd_hdspm_hw_rule_channels_rate(struct snd_pcm_hw_params *params, | 5636 | static struct snd_pcm_hw_constraint_list hw_constraints_raydat_io_buffer = { |
5637 | .count = ARRAY_SIZE(raydat_aio_buffer_sizes), | ||
5638 | .list = raydat_aio_buffer_sizes, | ||
5639 | .mask = 0 | ||
5640 | }; | ||
5641 | |||
5642 | static int snd_hdspm_hw_rule_in_channels_rate(struct snd_pcm_hw_params *params, | ||
5643 | struct snd_pcm_hw_rule *rule) | ||
5644 | { | ||
5645 | struct hdspm *hdspm = rule->private; | ||
5646 | struct snd_interval *c = | ||
5647 | hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); | ||
5648 | struct snd_interval *r = | ||
5649 | hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); | ||
5650 | |||
5651 | if (r->min > 96000 && r->max <= 192000) { | ||
5652 | struct snd_interval t = { | ||
5653 | .min = hdspm->qs_in_channels, | ||
5654 | .max = hdspm->qs_in_channels, | ||
5655 | .integer = 1, | ||
5656 | }; | ||
5657 | return snd_interval_refine(c, &t); | ||
5658 | } else if (r->min > 48000 && r->max <= 96000) { | ||
5659 | struct snd_interval t = { | ||
5660 | .min = hdspm->ds_in_channels, | ||
5661 | .max = hdspm->ds_in_channels, | ||
5662 | .integer = 1, | ||
5663 | }; | ||
5664 | return snd_interval_refine(c, &t); | ||
5665 | } else if (r->max < 64000) { | ||
5666 | struct snd_interval t = { | ||
5667 | .min = hdspm->ss_in_channels, | ||
5668 | .max = hdspm->ss_in_channels, | ||
5669 | .integer = 1, | ||
5670 | }; | ||
5671 | return snd_interval_refine(c, &t); | ||
5672 | } | ||
5673 | |||
5674 | return 0; | ||
5675 | } | ||
5676 | |||
5677 | static int snd_hdspm_hw_rule_out_channels_rate(struct snd_pcm_hw_params *params, | ||
3908 | struct snd_pcm_hw_rule * rule) | 5678 | struct snd_pcm_hw_rule * rule) |
3909 | { | 5679 | { |
3910 | struct hdspm *hdspm = rule->private; | 5680 | struct hdspm *hdspm = rule->private; |
@@ -3913,25 +5683,33 @@ static int snd_hdspm_hw_rule_channels_rate(struct snd_pcm_hw_params *params, | |||
3913 | struct snd_interval *r = | 5683 | struct snd_interval *r = |
3914 | hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); | 5684 | hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); |
3915 | 5685 | ||
3916 | if (r->min > 48000 && r->max <= 96000) { | 5686 | if (r->min > 96000 && r->max <= 192000) { |
3917 | struct snd_interval t = { | 5687 | struct snd_interval t = { |
3918 | .min = hdspm->ds_channels, | 5688 | .min = hdspm->qs_out_channels, |
3919 | .max = hdspm->ds_channels, | 5689 | .max = hdspm->qs_out_channels, |
5690 | .integer = 1, | ||
5691 | }; | ||
5692 | return snd_interval_refine(c, &t); | ||
5693 | } else if (r->min > 48000 && r->max <= 96000) { | ||
5694 | struct snd_interval t = { | ||
5695 | .min = hdspm->ds_out_channels, | ||
5696 | .max = hdspm->ds_out_channels, | ||
3920 | .integer = 1, | 5697 | .integer = 1, |
3921 | }; | 5698 | }; |
3922 | return snd_interval_refine(c, &t); | 5699 | return snd_interval_refine(c, &t); |
3923 | } else if (r->max < 64000) { | 5700 | } else if (r->max < 64000) { |
3924 | struct snd_interval t = { | 5701 | struct snd_interval t = { |
3925 | .min = hdspm->ss_channels, | 5702 | .min = hdspm->ss_out_channels, |
3926 | .max = hdspm->ss_channels, | 5703 | .max = hdspm->ss_out_channels, |
3927 | .integer = 1, | 5704 | .integer = 1, |
3928 | }; | 5705 | }; |
3929 | return snd_interval_refine(c, &t); | 5706 | return snd_interval_refine(c, &t); |
5707 | } else { | ||
3930 | } | 5708 | } |
3931 | return 0; | 5709 | return 0; |
3932 | } | 5710 | } |
3933 | 5711 | ||
3934 | static int snd_hdspm_hw_rule_rate_channels(struct snd_pcm_hw_params *params, | 5712 | static int snd_hdspm_hw_rule_rate_in_channels(struct snd_pcm_hw_params *params, |
3935 | struct snd_pcm_hw_rule * rule) | 5713 | struct snd_pcm_hw_rule * rule) |
3936 | { | 5714 | { |
3937 | struct hdspm *hdspm = rule->private; | 5715 | struct hdspm *hdspm = rule->private; |
@@ -3940,42 +5718,92 @@ static int snd_hdspm_hw_rule_rate_channels(struct snd_pcm_hw_params *params, | |||
3940 | struct snd_interval *r = | 5718 | struct snd_interval *r = |
3941 | hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); | 5719 | hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); |
3942 | 5720 | ||
3943 | if (c->min >= hdspm->ss_channels) { | 5721 | if (c->min >= hdspm->ss_in_channels) { |
3944 | struct snd_interval t = { | 5722 | struct snd_interval t = { |
3945 | .min = 32000, | 5723 | .min = 32000, |
3946 | .max = 48000, | 5724 | .max = 48000, |
3947 | .integer = 1, | 5725 | .integer = 1, |
3948 | }; | 5726 | }; |
3949 | return snd_interval_refine(r, &t); | 5727 | return snd_interval_refine(r, &t); |
3950 | } else if (c->max <= hdspm->ds_channels) { | 5728 | } else if (c->max <= hdspm->qs_in_channels) { |
5729 | struct snd_interval t = { | ||
5730 | .min = 128000, | ||
5731 | .max = 192000, | ||
5732 | .integer = 1, | ||
5733 | }; | ||
5734 | return snd_interval_refine(r, &t); | ||
5735 | } else if (c->max <= hdspm->ds_in_channels) { | ||
3951 | struct snd_interval t = { | 5736 | struct snd_interval t = { |
3952 | .min = 64000, | 5737 | .min = 64000, |
3953 | .max = 96000, | 5738 | .max = 96000, |
3954 | .integer = 1, | 5739 | .integer = 1, |
3955 | }; | 5740 | }; |
5741 | return snd_interval_refine(r, &t); | ||
5742 | } | ||
3956 | 5743 | ||
5744 | return 0; | ||
5745 | } | ||
5746 | static int snd_hdspm_hw_rule_rate_out_channels(struct snd_pcm_hw_params *params, | ||
5747 | struct snd_pcm_hw_rule *rule) | ||
5748 | { | ||
5749 | struct hdspm *hdspm = rule->private; | ||
5750 | struct snd_interval *c = | ||
5751 | hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); | ||
5752 | struct snd_interval *r = | ||
5753 | hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); | ||
5754 | |||
5755 | if (c->min >= hdspm->ss_out_channels) { | ||
5756 | struct snd_interval t = { | ||
5757 | .min = 32000, | ||
5758 | .max = 48000, | ||
5759 | .integer = 1, | ||
5760 | }; | ||
5761 | return snd_interval_refine(r, &t); | ||
5762 | } else if (c->max <= hdspm->qs_out_channels) { | ||
5763 | struct snd_interval t = { | ||
5764 | .min = 128000, | ||
5765 | .max = 192000, | ||
5766 | .integer = 1, | ||
5767 | }; | ||
5768 | return snd_interval_refine(r, &t); | ||
5769 | } else if (c->max <= hdspm->ds_out_channels) { | ||
5770 | struct snd_interval t = { | ||
5771 | .min = 64000, | ||
5772 | .max = 96000, | ||
5773 | .integer = 1, | ||
5774 | }; | ||
3957 | return snd_interval_refine(r, &t); | 5775 | return snd_interval_refine(r, &t); |
3958 | } | 5776 | } |
5777 | |||
3959 | return 0; | 5778 | return 0; |
3960 | } | 5779 | } |
3961 | 5780 | ||
3962 | static int snd_hdspm_hw_rule_channels(struct snd_pcm_hw_params *params, | 5781 | static int snd_hdspm_hw_rule_in_channels(struct snd_pcm_hw_params *params, |
3963 | struct snd_pcm_hw_rule *rule) | 5782 | struct snd_pcm_hw_rule *rule) |
3964 | { | 5783 | { |
3965 | unsigned int list[3]; | 5784 | unsigned int list[3]; |
3966 | struct hdspm *hdspm = rule->private; | 5785 | struct hdspm *hdspm = rule->private; |
3967 | struct snd_interval *c = hw_param_interval(params, | 5786 | struct snd_interval *c = hw_param_interval(params, |
3968 | SNDRV_PCM_HW_PARAM_CHANNELS); | 5787 | SNDRV_PCM_HW_PARAM_CHANNELS); |
3969 | if (hdspm->is_aes32) { | 5788 | |
3970 | list[0] = hdspm->qs_channels; | 5789 | list[0] = hdspm->qs_in_channels; |
3971 | list[1] = hdspm->ds_channels; | 5790 | list[1] = hdspm->ds_in_channels; |
3972 | list[2] = hdspm->ss_channels; | 5791 | list[2] = hdspm->ss_in_channels; |
3973 | return snd_interval_list(c, 3, list, 0); | 5792 | return snd_interval_list(c, 3, list, 0); |
3974 | } else { | 5793 | } |
3975 | list[0] = hdspm->ds_channels; | 5794 | |
3976 | list[1] = hdspm->ss_channels; | 5795 | static int snd_hdspm_hw_rule_out_channels(struct snd_pcm_hw_params *params, |
3977 | return snd_interval_list(c, 2, list, 0); | 5796 | struct snd_pcm_hw_rule *rule) |
3978 | } | 5797 | { |
5798 | unsigned int list[3]; | ||
5799 | struct hdspm *hdspm = rule->private; | ||
5800 | struct snd_interval *c = hw_param_interval(params, | ||
5801 | SNDRV_PCM_HW_PARAM_CHANNELS); | ||
5802 | |||
5803 | list[0] = hdspm->qs_out_channels; | ||
5804 | list[1] = hdspm->ds_out_channels; | ||
5805 | list[2] = hdspm->ss_out_channels; | ||
5806 | return snd_interval_list(c, 3, list, 0); | ||
3979 | } | 5807 | } |
3980 | 5808 | ||
3981 | 5809 | ||
@@ -3999,6 +5827,7 @@ static int snd_hdspm_playback_open(struct snd_pcm_substream *substream) | |||
3999 | 5827 | ||
4000 | snd_pcm_set_sync(substream); | 5828 | snd_pcm_set_sync(substream); |
4001 | 5829 | ||
5830 | |||
4002 | runtime->hw = snd_hdspm_playback_subinfo; | 5831 | runtime->hw = snd_hdspm_playback_subinfo; |
4003 | 5832 | ||
4004 | if (hdspm->capture_substream == NULL) | 5833 | if (hdspm->capture_substream == NULL) |
@@ -4011,25 +5840,41 @@ static int snd_hdspm_playback_open(struct snd_pcm_substream *substream) | |||
4011 | 5840 | ||
4012 | snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24); | 5841 | snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24); |
4013 | 5842 | ||
4014 | snd_pcm_hw_constraint_list(runtime, 0, | 5843 | switch (hdspm->io_type) { |
4015 | SNDRV_PCM_HW_PARAM_PERIOD_SIZE, | 5844 | case AIO: |
4016 | &hw_constraints_period_sizes); | 5845 | case RayDAT: |
5846 | snd_pcm_hw_constraint_list(runtime, 0, | ||
5847 | SNDRV_PCM_HW_PARAM_PERIOD_SIZE, | ||
5848 | &hw_constraints_period_sizes_new); | ||
5849 | snd_pcm_hw_constraint_list(runtime, 0, | ||
5850 | SNDRV_PCM_HW_PARAM_BUFFER_SIZE, | ||
5851 | &hw_constraints_raydat_io_buffer); | ||
4017 | 5852 | ||
4018 | if (hdspm->is_aes32) { | 5853 | break; |
5854 | |||
5855 | default: | ||
5856 | snd_pcm_hw_constraint_list(runtime, 0, | ||
5857 | SNDRV_PCM_HW_PARAM_PERIOD_SIZE, | ||
5858 | &hw_constraints_period_sizes_old); | ||
5859 | } | ||
5860 | |||
5861 | if (AES32 == hdspm->io_type) { | ||
4019 | snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, | 5862 | snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, |
4020 | &hdspm_hw_constraints_aes32_sample_rates); | 5863 | &hdspm_hw_constraints_aes32_sample_rates); |
4021 | } else { | 5864 | } else { |
4022 | snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, | ||
4023 | snd_hdspm_hw_rule_channels, hdspm, | ||
4024 | SNDRV_PCM_HW_PARAM_CHANNELS, -1); | ||
4025 | snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, | ||
4026 | snd_hdspm_hw_rule_channels_rate, hdspm, | ||
4027 | SNDRV_PCM_HW_PARAM_RATE, -1); | ||
4028 | |||
4029 | snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, | 5865 | snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, |
4030 | snd_hdspm_hw_rule_rate_channels, hdspm, | 5866 | snd_hdspm_hw_rule_rate_out_channels, hdspm, |
4031 | SNDRV_PCM_HW_PARAM_CHANNELS, -1); | 5867 | SNDRV_PCM_HW_PARAM_CHANNELS, -1); |
4032 | } | 5868 | } |
5869 | |||
5870 | snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, | ||
5871 | snd_hdspm_hw_rule_out_channels, hdspm, | ||
5872 | SNDRV_PCM_HW_PARAM_CHANNELS, -1); | ||
5873 | |||
5874 | snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, | ||
5875 | snd_hdspm_hw_rule_out_channels_rate, hdspm, | ||
5876 | SNDRV_PCM_HW_PARAM_RATE, -1); | ||
5877 | |||
4033 | return 0; | 5878 | return 0; |
4034 | } | 5879 | } |
4035 | 5880 | ||
@@ -4066,24 +5911,40 @@ static int snd_hdspm_capture_open(struct snd_pcm_substream *substream) | |||
4066 | spin_unlock_irq(&hdspm->lock); | 5911 | spin_unlock_irq(&hdspm->lock); |
4067 | 5912 | ||
4068 | snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24); | 5913 | snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24); |
4069 | snd_pcm_hw_constraint_list(runtime, 0, | 5914 | switch (hdspm->io_type) { |
4070 | SNDRV_PCM_HW_PARAM_PERIOD_SIZE, | 5915 | case AIO: |
4071 | &hw_constraints_period_sizes); | 5916 | case RayDAT: |
4072 | if (hdspm->is_aes32) { | 5917 | snd_pcm_hw_constraint_list(runtime, 0, |
5918 | SNDRV_PCM_HW_PARAM_PERIOD_SIZE, | ||
5919 | &hw_constraints_period_sizes_new); | ||
5920 | snd_pcm_hw_constraint_list(runtime, 0, | ||
5921 | SNDRV_PCM_HW_PARAM_BUFFER_SIZE, | ||
5922 | &hw_constraints_raydat_io_buffer); | ||
5923 | break; | ||
5924 | |||
5925 | default: | ||
5926 | snd_pcm_hw_constraint_list(runtime, 0, | ||
5927 | SNDRV_PCM_HW_PARAM_PERIOD_SIZE, | ||
5928 | &hw_constraints_period_sizes_old); | ||
5929 | } | ||
5930 | |||
5931 | if (AES32 == hdspm->io_type) { | ||
4073 | snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, | 5932 | snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, |
4074 | &hdspm_hw_constraints_aes32_sample_rates); | 5933 | &hdspm_hw_constraints_aes32_sample_rates); |
4075 | } else { | 5934 | } else { |
4076 | snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, | ||
4077 | snd_hdspm_hw_rule_channels, hdspm, | ||
4078 | SNDRV_PCM_HW_PARAM_CHANNELS, -1); | ||
4079 | snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, | ||
4080 | snd_hdspm_hw_rule_channels_rate, hdspm, | ||
4081 | SNDRV_PCM_HW_PARAM_RATE, -1); | ||
4082 | |||
4083 | snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, | 5935 | snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, |
4084 | snd_hdspm_hw_rule_rate_channels, hdspm, | 5936 | snd_hdspm_hw_rule_rate_in_channels, hdspm, |
4085 | SNDRV_PCM_HW_PARAM_CHANNELS, -1); | 5937 | SNDRV_PCM_HW_PARAM_CHANNELS, -1); |
4086 | } | 5938 | } |
5939 | |||
5940 | snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, | ||
5941 | snd_hdspm_hw_rule_in_channels, hdspm, | ||
5942 | SNDRV_PCM_HW_PARAM_CHANNELS, -1); | ||
5943 | |||
5944 | snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, | ||
5945 | snd_hdspm_hw_rule_in_channels_rate, hdspm, | ||
5946 | SNDRV_PCM_HW_PARAM_RATE, -1); | ||
5947 | |||
4087 | return 0; | 5948 | return 0; |
4088 | } | 5949 | } |
4089 | 5950 | ||
@@ -4100,32 +5961,129 @@ static int snd_hdspm_capture_release(struct snd_pcm_substream *substream) | |||
4100 | return 0; | 5961 | return 0; |
4101 | } | 5962 | } |
4102 | 5963 | ||
4103 | static int snd_hdspm_hwdep_ioctl(struct snd_hwdep * hw, struct file *file, | 5964 | static int snd_hdspm_hwdep_dummy_op(struct snd_hwdep *hw, struct file *file) |
4104 | unsigned int cmd, unsigned long arg) | ||
4105 | { | 5965 | { |
5966 | /* we have nothing to initialize but the call is required */ | ||
5967 | return 0; | ||
5968 | } | ||
5969 | |||
5970 | static inline int copy_u32_le(void __user *dest, void __iomem *src) | ||
5971 | { | ||
5972 | u32 val = readl(src); | ||
5973 | return copy_to_user(dest, &val, 4); | ||
5974 | } | ||
5975 | |||
5976 | static int snd_hdspm_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, | ||
5977 | unsigned int cmd, unsigned long __user arg) | ||
5978 | { | ||
5979 | void __user *argp = (void __user *)arg; | ||
4106 | struct hdspm *hdspm = hw->private_data; | 5980 | struct hdspm *hdspm = hw->private_data; |
4107 | struct hdspm_mixer_ioctl mixer; | 5981 | struct hdspm_mixer_ioctl mixer; |
4108 | struct hdspm_config_info info; | 5982 | struct hdspm_config info; |
5983 | struct hdspm_status status; | ||
4109 | struct hdspm_version hdspm_version; | 5984 | struct hdspm_version hdspm_version; |
4110 | struct hdspm_peak_rms_ioctl rms; | 5985 | struct hdspm_peak_rms *levels; |
5986 | struct hdspm_ltc ltc; | ||
5987 | unsigned int statusregister; | ||
5988 | long unsigned int s; | ||
5989 | int i = 0; | ||
4111 | 5990 | ||
4112 | switch (cmd) { | 5991 | switch (cmd) { |
4113 | 5992 | ||
4114 | case SNDRV_HDSPM_IOCTL_GET_PEAK_RMS: | 5993 | case SNDRV_HDSPM_IOCTL_GET_PEAK_RMS: |
4115 | if (copy_from_user(&rms, (void __user *)arg, sizeof(rms))) | 5994 | levels = &hdspm->peak_rms; |
5995 | for (i = 0; i < HDSPM_MAX_CHANNELS; i++) { | ||
5996 | levels->input_peaks[i] = | ||
5997 | readl(hdspm->iobase + | ||
5998 | HDSPM_MADI_INPUT_PEAK + i*4); | ||
5999 | levels->playback_peaks[i] = | ||
6000 | readl(hdspm->iobase + | ||
6001 | HDSPM_MADI_PLAYBACK_PEAK + i*4); | ||
6002 | levels->output_peaks[i] = | ||
6003 | readl(hdspm->iobase + | ||
6004 | HDSPM_MADI_OUTPUT_PEAK + i*4); | ||
6005 | |||
6006 | levels->input_rms[i] = | ||
6007 | ((uint64_t) readl(hdspm->iobase + | ||
6008 | HDSPM_MADI_INPUT_RMS_H + i*4) << 32) | | ||
6009 | (uint64_t) readl(hdspm->iobase + | ||
6010 | HDSPM_MADI_INPUT_RMS_L + i*4); | ||
6011 | levels->playback_rms[i] = | ||
6012 | ((uint64_t)readl(hdspm->iobase + | ||
6013 | HDSPM_MADI_PLAYBACK_RMS_H+i*4) << 32) | | ||
6014 | (uint64_t)readl(hdspm->iobase + | ||
6015 | HDSPM_MADI_PLAYBACK_RMS_L + i*4); | ||
6016 | levels->output_rms[i] = | ||
6017 | ((uint64_t)readl(hdspm->iobase + | ||
6018 | HDSPM_MADI_OUTPUT_RMS_H + i*4) << 32) | | ||
6019 | (uint64_t)readl(hdspm->iobase + | ||
6020 | HDSPM_MADI_OUTPUT_RMS_L + i*4); | ||
6021 | } | ||
6022 | |||
6023 | if (hdspm->system_sample_rate > 96000) { | ||
6024 | levels->speed = qs; | ||
6025 | } else if (hdspm->system_sample_rate > 48000) { | ||
6026 | levels->speed = ds; | ||
6027 | } else { | ||
6028 | levels->speed = ss; | ||
6029 | } | ||
6030 | levels->status2 = hdspm_read(hdspm, HDSPM_statusRegister2); | ||
6031 | |||
6032 | s = copy_to_user(argp, levels, sizeof(struct hdspm_peak_rms)); | ||
6033 | if (0 != s) { | ||
6034 | /* snd_printk(KERN_ERR "copy_to_user(.., .., %lu): %lu | ||
6035 | [Levels]\n", sizeof(struct hdspm_peak_rms), s); | ||
6036 | */ | ||
4116 | return -EFAULT; | 6037 | return -EFAULT; |
4117 | /* maybe there is a chance to memorymap in future | 6038 | } |
4118 | * so dont touch just copy | 6039 | break; |
4119 | */ | 6040 | |
4120 | if(copy_to_user_fromio((void __user *)rms.peak, | 6041 | case SNDRV_HDSPM_IOCTL_GET_LTC: |
4121 | hdspm->iobase+HDSPM_MADI_peakrmsbase, | 6042 | ltc.ltc = hdspm_read(hdspm, HDSPM_RD_TCO); |
4122 | sizeof(struct hdspm_peak_rms)) != 0 ) | 6043 | i = hdspm_read(hdspm, HDSPM_RD_TCO + 4); |
6044 | if (i & HDSPM_TCO1_LTC_Input_valid) { | ||
6045 | switch (i & (HDSPM_TCO1_LTC_Format_LSB | | ||
6046 | HDSPM_TCO1_LTC_Format_MSB)) { | ||
6047 | case 0: | ||
6048 | ltc.format = fps_24; | ||
6049 | break; | ||
6050 | case HDSPM_TCO1_LTC_Format_LSB: | ||
6051 | ltc.format = fps_25; | ||
6052 | break; | ||
6053 | case HDSPM_TCO1_LTC_Format_MSB: | ||
6054 | ltc.format = fps_2997; | ||
6055 | break; | ||
6056 | default: | ||
6057 | ltc.format = 30; | ||
6058 | break; | ||
6059 | } | ||
6060 | if (i & HDSPM_TCO1_set_drop_frame_flag) { | ||
6061 | ltc.frame = drop_frame; | ||
6062 | } else { | ||
6063 | ltc.frame = full_frame; | ||
6064 | } | ||
6065 | } else { | ||
6066 | ltc.format = format_invalid; | ||
6067 | ltc.frame = frame_invalid; | ||
6068 | } | ||
6069 | if (i & HDSPM_TCO1_Video_Input_Format_NTSC) { | ||
6070 | ltc.input_format = ntsc; | ||
6071 | } else if (i & HDSPM_TCO1_Video_Input_Format_PAL) { | ||
6072 | ltc.input_format = pal; | ||
6073 | } else { | ||
6074 | ltc.input_format = no_video; | ||
6075 | } | ||
6076 | |||
6077 | s = copy_to_user(argp, <c, sizeof(struct hdspm_ltc)); | ||
6078 | if (0 != s) { | ||
6079 | /* | ||
6080 | snd_printk(KERN_ERR "copy_to_user(.., .., %lu): %lu [LTC]\n", sizeof(struct hdspm_ltc), s); */ | ||
4123 | return -EFAULT; | 6081 | return -EFAULT; |
6082 | } | ||
4124 | 6083 | ||
4125 | break; | 6084 | break; |
4126 | |||
4127 | 6085 | ||
4128 | case SNDRV_HDSPM_IOCTL_GET_CONFIG_INFO: | 6086 | case SNDRV_HDSPM_IOCTL_GET_CONFIG: |
4129 | 6087 | ||
4130 | memset(&info, 0, sizeof(info)); | 6088 | memset(&info, 0, sizeof(info)); |
4131 | spin_lock_irq(&hdspm->lock); | 6089 | spin_lock_irq(&hdspm->lock); |
@@ -4134,7 +6092,7 @@ static int snd_hdspm_hwdep_ioctl(struct snd_hwdep * hw, struct file *file, | |||
4134 | 6092 | ||
4135 | info.system_sample_rate = hdspm->system_sample_rate; | 6093 | info.system_sample_rate = hdspm->system_sample_rate; |
4136 | info.autosync_sample_rate = | 6094 | info.autosync_sample_rate = |
4137 | hdspm_external_sample_rate(hdspm); | 6095 | hdspm_external_sample_rate(hdspm); |
4138 | info.system_clock_mode = hdspm_system_clock_mode(hdspm); | 6096 | info.system_clock_mode = hdspm_system_clock_mode(hdspm); |
4139 | info.clock_source = hdspm_clock_source(hdspm); | 6097 | info.clock_source = hdspm_clock_source(hdspm); |
4140 | info.autosync_ref = hdspm_autosync_ref(hdspm); | 6098 | info.autosync_ref = hdspm_autosync_ref(hdspm); |
@@ -4145,10 +6103,58 @@ static int snd_hdspm_hwdep_ioctl(struct snd_hwdep * hw, struct file *file, | |||
4145 | return -EFAULT; | 6103 | return -EFAULT; |
4146 | break; | 6104 | break; |
4147 | 6105 | ||
6106 | case SNDRV_HDSPM_IOCTL_GET_STATUS: | ||
6107 | status.card_type = hdspm->io_type; | ||
6108 | |||
6109 | status.autosync_source = hdspm_autosync_ref(hdspm); | ||
6110 | |||
6111 | status.card_clock = 110069313433624ULL; | ||
6112 | status.master_period = hdspm_read(hdspm, HDSPM_RD_PLL_FREQ); | ||
6113 | |||
6114 | switch (hdspm->io_type) { | ||
6115 | case MADI: | ||
6116 | case MADIface: | ||
6117 | status.card_specific.madi.sync_wc = | ||
6118 | hdspm_wc_sync_check(hdspm); | ||
6119 | status.card_specific.madi.sync_madi = | ||
6120 | hdspm_madi_sync_check(hdspm); | ||
6121 | status.card_specific.madi.sync_tco = | ||
6122 | hdspm_tco_sync_check(hdspm); | ||
6123 | status.card_specific.madi.sync_in = | ||
6124 | hdspm_sync_in_sync_check(hdspm); | ||
6125 | |||
6126 | statusregister = | ||
6127 | hdspm_read(hdspm, HDSPM_statusRegister); | ||
6128 | status.card_specific.madi.madi_input = | ||
6129 | (statusregister & HDSPM_AB_int) ? 1 : 0; | ||
6130 | status.card_specific.madi.channel_format = | ||
6131 | (statusregister & HDSPM_TX_64ch) ? 1 : 0; | ||
6132 | /* TODO: Mac driver sets it when f_s>48kHz */ | ||
6133 | status.card_specific.madi.frame_format = 0; | ||
6134 | |||
6135 | default: | ||
6136 | break; | ||
6137 | } | ||
6138 | |||
6139 | if (copy_to_user((void __user *) arg, &status, sizeof(status))) | ||
6140 | return -EFAULT; | ||
6141 | |||
6142 | |||
6143 | break; | ||
6144 | |||
4148 | case SNDRV_HDSPM_IOCTL_GET_VERSION: | 6145 | case SNDRV_HDSPM_IOCTL_GET_VERSION: |
6146 | hdspm_version.card_type = hdspm->io_type; | ||
6147 | strncpy(hdspm_version.cardname, hdspm->card_name, | ||
6148 | sizeof(hdspm_version.cardname)); | ||
6149 | hdspm_version.serial = (hdspm_read(hdspm, | ||
6150 | HDSPM_midiStatusIn0)>>8) & 0xFFFFFF; | ||
4149 | hdspm_version.firmware_rev = hdspm->firmware_rev; | 6151 | hdspm_version.firmware_rev = hdspm->firmware_rev; |
6152 | hdspm_version.addons = 0; | ||
6153 | if (hdspm->tco) | ||
6154 | hdspm_version.addons |= HDSPM_ADDON_TCO; | ||
6155 | |||
4150 | if (copy_to_user((void __user *) arg, &hdspm_version, | 6156 | if (copy_to_user((void __user *) arg, &hdspm_version, |
4151 | sizeof(hdspm_version))) | 6157 | sizeof(hdspm_version))) |
4152 | return -EFAULT; | 6158 | return -EFAULT; |
4153 | break; | 6159 | break; |
4154 | 6160 | ||
@@ -4156,7 +6162,7 @@ static int snd_hdspm_hwdep_ioctl(struct snd_hwdep * hw, struct file *file, | |||
4156 | if (copy_from_user(&mixer, (void __user *)arg, sizeof(mixer))) | 6162 | if (copy_from_user(&mixer, (void __user *)arg, sizeof(mixer))) |
4157 | return -EFAULT; | 6163 | return -EFAULT; |
4158 | if (copy_to_user((void __user *)mixer.mixer, hdspm->mixer, | 6164 | if (copy_to_user((void __user *)mixer.mixer, hdspm->mixer, |
4159 | sizeof(struct hdspm_mixer))) | 6165 | sizeof(struct hdspm_mixer))) |
4160 | return -EFAULT; | 6166 | return -EFAULT; |
4161 | break; | 6167 | break; |
4162 | 6168 | ||
@@ -4175,8 +6181,6 @@ static struct snd_pcm_ops snd_hdspm_playback_ops = { | |||
4175 | .prepare = snd_hdspm_prepare, | 6181 | .prepare = snd_hdspm_prepare, |
4176 | .trigger = snd_hdspm_trigger, | 6182 | .trigger = snd_hdspm_trigger, |
4177 | .pointer = snd_hdspm_hw_pointer, | 6183 | .pointer = snd_hdspm_hw_pointer, |
4178 | .copy = snd_hdspm_playback_copy, | ||
4179 | .silence = snd_hdspm_hw_silence, | ||
4180 | .page = snd_pcm_sgbuf_ops_page, | 6184 | .page = snd_pcm_sgbuf_ops_page, |
4181 | }; | 6185 | }; |
4182 | 6186 | ||
@@ -4189,7 +6193,6 @@ static struct snd_pcm_ops snd_hdspm_capture_ops = { | |||
4189 | .prepare = snd_hdspm_prepare, | 6193 | .prepare = snd_hdspm_prepare, |
4190 | .trigger = snd_hdspm_trigger, | 6194 | .trigger = snd_hdspm_trigger, |
4191 | .pointer = snd_hdspm_hw_pointer, | 6195 | .pointer = snd_hdspm_hw_pointer, |
4192 | .copy = snd_hdspm_capture_copy, | ||
4193 | .page = snd_pcm_sgbuf_ops_page, | 6196 | .page = snd_pcm_sgbuf_ops_page, |
4194 | }; | 6197 | }; |
4195 | 6198 | ||
@@ -4207,16 +6210,18 @@ static int __devinit snd_hdspm_create_hwdep(struct snd_card *card, | |||
4207 | hw->private_data = hdspm; | 6210 | hw->private_data = hdspm; |
4208 | strcpy(hw->name, "HDSPM hwdep interface"); | 6211 | strcpy(hw->name, "HDSPM hwdep interface"); |
4209 | 6212 | ||
6213 | hw->ops.open = snd_hdspm_hwdep_dummy_op; | ||
4210 | hw->ops.ioctl = snd_hdspm_hwdep_ioctl; | 6214 | hw->ops.ioctl = snd_hdspm_hwdep_ioctl; |
6215 | hw->ops.release = snd_hdspm_hwdep_dummy_op; | ||
4211 | 6216 | ||
4212 | return 0; | 6217 | return 0; |
4213 | } | 6218 | } |
4214 | 6219 | ||
4215 | 6220 | ||
4216 | /*------------------------------------------------------------ | 6221 | /*------------------------------------------------------------ |
4217 | memory interface | 6222 | memory interface |
4218 | ------------------------------------------------------------*/ | 6223 | ------------------------------------------------------------*/ |
4219 | static int __devinit snd_hdspm_preallocate_memory(struct hdspm * hdspm) | 6224 | static int __devinit snd_hdspm_preallocate_memory(struct hdspm *hdspm) |
4220 | { | 6225 | { |
4221 | int err; | 6226 | int err; |
4222 | struct snd_pcm *pcm; | 6227 | struct snd_pcm *pcm; |
@@ -4228,7 +6233,7 @@ static int __devinit snd_hdspm_preallocate_memory(struct hdspm * hdspm) | |||
4228 | 6233 | ||
4229 | err = | 6234 | err = |
4230 | snd_pcm_lib_preallocate_pages_for_all(pcm, | 6235 | snd_pcm_lib_preallocate_pages_for_all(pcm, |
4231 | SNDRV_DMA_TYPE_DEV_SG, | 6236 | SNDRV_DMA_TYPE_DEV_SG, |
4232 | snd_dma_pci_data(hdspm->pci), | 6237 | snd_dma_pci_data(hdspm->pci), |
4233 | wanted, | 6238 | wanted, |
4234 | wanted); | 6239 | wanted); |
@@ -4242,19 +6247,23 @@ static int __devinit snd_hdspm_preallocate_memory(struct hdspm * hdspm) | |||
4242 | return 0; | 6247 | return 0; |
4243 | } | 6248 | } |
4244 | 6249 | ||
4245 | static void hdspm_set_sgbuf(struct hdspm * hdspm, | 6250 | |
6251 | static void hdspm_set_sgbuf(struct hdspm *hdspm, | ||
4246 | struct snd_pcm_substream *substream, | 6252 | struct snd_pcm_substream *substream, |
4247 | unsigned int reg, int channels) | 6253 | unsigned int reg, int channels) |
4248 | { | 6254 | { |
4249 | int i; | 6255 | int i; |
6256 | |||
6257 | /* continuous memory segment */ | ||
4250 | for (i = 0; i < (channels * 16); i++) | 6258 | for (i = 0; i < (channels * 16); i++) |
4251 | hdspm_write(hdspm, reg + 4 * i, | 6259 | hdspm_write(hdspm, reg + 4 * i, |
4252 | snd_pcm_sgbuf_get_addr(substream, 4096 * i)); | 6260 | snd_pcm_sgbuf_get_addr(substream, 4096 * i)); |
4253 | } | 6261 | } |
4254 | 6262 | ||
6263 | |||
4255 | /* ------------- ALSA Devices ---------------------------- */ | 6264 | /* ------------- ALSA Devices ---------------------------- */ |
4256 | static int __devinit snd_hdspm_create_pcm(struct snd_card *card, | 6265 | static int __devinit snd_hdspm_create_pcm(struct snd_card *card, |
4257 | struct hdspm * hdspm) | 6266 | struct hdspm *hdspm) |
4258 | { | 6267 | { |
4259 | struct snd_pcm *pcm; | 6268 | struct snd_pcm *pcm; |
4260 | int err; | 6269 | int err; |
@@ -4283,27 +6292,30 @@ static int __devinit snd_hdspm_create_pcm(struct snd_card *card, | |||
4283 | 6292 | ||
4284 | static inline void snd_hdspm_initialize_midi_flush(struct hdspm * hdspm) | 6293 | static inline void snd_hdspm_initialize_midi_flush(struct hdspm * hdspm) |
4285 | { | 6294 | { |
4286 | snd_hdspm_flush_midi_input(hdspm, 0); | 6295 | int i; |
4287 | snd_hdspm_flush_midi_input(hdspm, 1); | 6296 | |
6297 | for (i = 0; i < hdspm->midiPorts; i++) | ||
6298 | snd_hdspm_flush_midi_input(hdspm, i); | ||
4288 | } | 6299 | } |
4289 | 6300 | ||
4290 | static int __devinit snd_hdspm_create_alsa_devices(struct snd_card *card, | 6301 | static int __devinit snd_hdspm_create_alsa_devices(struct snd_card *card, |
4291 | struct hdspm * hdspm) | 6302 | struct hdspm * hdspm) |
4292 | { | 6303 | { |
4293 | int err; | 6304 | int err, i; |
4294 | 6305 | ||
4295 | snd_printdd("Create card...\n"); | 6306 | snd_printdd("Create card...\n"); |
4296 | err = snd_hdspm_create_pcm(card, hdspm); | 6307 | err = snd_hdspm_create_pcm(card, hdspm); |
4297 | if (err < 0) | 6308 | if (err < 0) |
4298 | return err; | 6309 | return err; |
4299 | 6310 | ||
4300 | err = snd_hdspm_create_midi(card, hdspm, 0); | 6311 | i = 0; |
4301 | if (err < 0) | 6312 | while (i < hdspm->midiPorts) { |
4302 | return err; | 6313 | err = snd_hdspm_create_midi(card, hdspm, i); |
4303 | 6314 | if (err < 0) { | |
4304 | err = snd_hdspm_create_midi(card, hdspm, 1); | 6315 | return err; |
4305 | if (err < 0) | 6316 | } |
4306 | return err; | 6317 | i++; |
6318 | } | ||
4307 | 6319 | ||
4308 | err = snd_hdspm_create_controls(card, hdspm); | 6320 | err = snd_hdspm_create_controls(card, hdspm); |
4309 | if (err < 0) | 6321 | if (err < 0) |
@@ -4346,37 +6358,55 @@ static int __devinit snd_hdspm_create_alsa_devices(struct snd_card *card, | |||
4346 | } | 6358 | } |
4347 | 6359 | ||
4348 | static int __devinit snd_hdspm_create(struct snd_card *card, | 6360 | static int __devinit snd_hdspm_create(struct snd_card *card, |
4349 | struct hdspm *hdspm, | 6361 | struct hdspm *hdspm) { |
4350 | int precise_ptr, int enable_monitor) | 6362 | |
4351 | { | ||
4352 | struct pci_dev *pci = hdspm->pci; | 6363 | struct pci_dev *pci = hdspm->pci; |
4353 | int err; | 6364 | int err; |
4354 | unsigned long io_extent; | 6365 | unsigned long io_extent; |
4355 | 6366 | ||
4356 | hdspm->irq = -1; | 6367 | hdspm->irq = -1; |
4357 | |||
4358 | spin_lock_init(&hdspm->midi[0].lock); | ||
4359 | spin_lock_init(&hdspm->midi[1].lock); | ||
4360 | |||
4361 | hdspm->card = card; | 6368 | hdspm->card = card; |
4362 | 6369 | ||
4363 | spin_lock_init(&hdspm->lock); | 6370 | spin_lock_init(&hdspm->lock); |
4364 | 6371 | ||
4365 | tasklet_init(&hdspm->midi_tasklet, | ||
4366 | hdspm_midi_tasklet, (unsigned long) hdspm); | ||
4367 | |||
4368 | pci_read_config_word(hdspm->pci, | 6372 | pci_read_config_word(hdspm->pci, |
4369 | PCI_CLASS_REVISION, &hdspm->firmware_rev); | 6373 | PCI_CLASS_REVISION, &hdspm->firmware_rev); |
4370 | |||
4371 | hdspm->is_aes32 = (hdspm->firmware_rev >= HDSPM_AESREVISION); | ||
4372 | 6374 | ||
4373 | strcpy(card->mixername, "Xilinx FPGA"); | 6375 | strcpy(card->mixername, "Xilinx FPGA"); |
4374 | if (hdspm->is_aes32) { | 6376 | strcpy(card->driver, "HDSPM"); |
4375 | strcpy(card->driver, "HDSPAES32"); | 6377 | |
4376 | hdspm->card_name = "RME HDSPM AES32"; | 6378 | switch (hdspm->firmware_rev) { |
4377 | } else { | 6379 | case HDSPM_MADI_REV: |
4378 | strcpy(card->driver, "HDSPM"); | 6380 | hdspm->io_type = MADI; |
4379 | hdspm->card_name = "RME HDSPM MADI"; | 6381 | hdspm->card_name = "RME MADI"; |
6382 | hdspm->midiPorts = 3; | ||
6383 | break; | ||
6384 | case HDSPM_RAYDAT_REV: | ||
6385 | hdspm->io_type = RayDAT; | ||
6386 | hdspm->card_name = "RME RayDAT"; | ||
6387 | hdspm->midiPorts = 2; | ||
6388 | break; | ||
6389 | case HDSPM_AIO_REV: | ||
6390 | hdspm->io_type = AIO; | ||
6391 | hdspm->card_name = "RME AIO"; | ||
6392 | hdspm->midiPorts = 1; | ||
6393 | break; | ||
6394 | case HDSPM_MADIFACE_REV: | ||
6395 | hdspm->io_type = MADIface; | ||
6396 | hdspm->card_name = "RME MADIface"; | ||
6397 | hdspm->midiPorts = 1; | ||
6398 | break; | ||
6399 | case HDSPM_AES_REV: | ||
6400 | case HDSPM_AES32_REV: | ||
6401 | case HDSPM_AES32_OLD_REV: | ||
6402 | hdspm->io_type = AES32; | ||
6403 | hdspm->card_name = "RME AES32"; | ||
6404 | hdspm->midiPorts = 2; | ||
6405 | break; | ||
6406 | default: | ||
6407 | snd_printk(KERN_ERR "HDSPM: unknown firmware revision %x\n", | ||
6408 | hdspm->firmware_rev); | ||
6409 | return -ENODEV; | ||
4380 | } | 6410 | } |
4381 | 6411 | ||
4382 | err = pci_enable_device(pci); | 6412 | err = pci_enable_device(pci); |
@@ -4393,22 +6423,21 @@ static int __devinit snd_hdspm_create(struct snd_card *card, | |||
4393 | io_extent = pci_resource_len(pci, 0); | 6423 | io_extent = pci_resource_len(pci, 0); |
4394 | 6424 | ||
4395 | snd_printdd("grabbed memory region 0x%lx-0x%lx\n", | 6425 | snd_printdd("grabbed memory region 0x%lx-0x%lx\n", |
4396 | hdspm->port, hdspm->port + io_extent - 1); | 6426 | hdspm->port, hdspm->port + io_extent - 1); |
4397 | |||
4398 | 6427 | ||
4399 | hdspm->iobase = ioremap_nocache(hdspm->port, io_extent); | 6428 | hdspm->iobase = ioremap_nocache(hdspm->port, io_extent); |
4400 | if (!hdspm->iobase) { | 6429 | if (!hdspm->iobase) { |
4401 | snd_printk(KERN_ERR "HDSPM: " | 6430 | snd_printk(KERN_ERR "HDSPM: " |
4402 | "unable to remap region 0x%lx-0x%lx\n", | 6431 | "unable to remap region 0x%lx-0x%lx\n", |
4403 | hdspm->port, hdspm->port + io_extent - 1); | 6432 | hdspm->port, hdspm->port + io_extent - 1); |
4404 | return -EBUSY; | 6433 | return -EBUSY; |
4405 | } | 6434 | } |
4406 | snd_printdd("remapped region (0x%lx) 0x%lx-0x%lx\n", | 6435 | snd_printdd("remapped region (0x%lx) 0x%lx-0x%lx\n", |
4407 | (unsigned long)hdspm->iobase, hdspm->port, | 6436 | (unsigned long)hdspm->iobase, hdspm->port, |
4408 | hdspm->port + io_extent - 1); | 6437 | hdspm->port + io_extent - 1); |
4409 | 6438 | ||
4410 | if (request_irq(pci->irq, snd_hdspm_interrupt, | 6439 | if (request_irq(pci->irq, snd_hdspm_interrupt, |
4411 | IRQF_SHARED, "hdspm", hdspm)) { | 6440 | IRQF_SHARED, "hdspm", hdspm)) { |
4412 | snd_printk(KERN_ERR "HDSPM: unable to use IRQ %d\n", pci->irq); | 6441 | snd_printk(KERN_ERR "HDSPM: unable to use IRQ %d\n", pci->irq); |
4413 | return -EBUSY; | 6442 | return -EBUSY; |
4414 | } | 6443 | } |
@@ -4416,23 +6445,219 @@ static int __devinit snd_hdspm_create(struct snd_card *card, | |||
4416 | snd_printdd("use IRQ %d\n", pci->irq); | 6445 | snd_printdd("use IRQ %d\n", pci->irq); |
4417 | 6446 | ||
4418 | hdspm->irq = pci->irq; | 6447 | hdspm->irq = pci->irq; |
4419 | hdspm->precise_ptr = precise_ptr; | ||
4420 | |||
4421 | hdspm->monitor_outs = enable_monitor; | ||
4422 | 6448 | ||
4423 | snd_printdd("kmalloc Mixer memory of %zd Bytes\n", | 6449 | snd_printdd("kmalloc Mixer memory of %zd Bytes\n", |
4424 | sizeof(struct hdspm_mixer)); | 6450 | sizeof(struct hdspm_mixer)); |
4425 | hdspm->mixer = kzalloc(sizeof(struct hdspm_mixer), GFP_KERNEL); | 6451 | hdspm->mixer = kzalloc(sizeof(struct hdspm_mixer), GFP_KERNEL); |
4426 | if (!hdspm->mixer) { | 6452 | if (!hdspm->mixer) { |
4427 | snd_printk(KERN_ERR "HDSPM: " | 6453 | snd_printk(KERN_ERR "HDSPM: " |
4428 | "unable to kmalloc Mixer memory of %d Bytes\n", | 6454 | "unable to kmalloc Mixer memory of %d Bytes\n", |
4429 | (int)sizeof(struct hdspm_mixer)); | 6455 | (int)sizeof(struct hdspm_mixer)); |
4430 | return err; | 6456 | return err; |
4431 | } | 6457 | } |
4432 | 6458 | ||
4433 | hdspm->ss_channels = MADI_SS_CHANNELS; | 6459 | hdspm->port_names_in = NULL; |
4434 | hdspm->ds_channels = MADI_DS_CHANNELS; | 6460 | hdspm->port_names_out = NULL; |
4435 | hdspm->qs_channels = MADI_QS_CHANNELS; | 6461 | |
6462 | switch (hdspm->io_type) { | ||
6463 | case AES32: | ||
6464 | hdspm->ss_in_channels = hdspm->ss_out_channels = AES32_CHANNELS; | ||
6465 | hdspm->ds_in_channels = hdspm->ds_out_channels = AES32_CHANNELS; | ||
6466 | hdspm->qs_in_channels = hdspm->qs_out_channels = AES32_CHANNELS; | ||
6467 | |||
6468 | hdspm->channel_map_in_ss = hdspm->channel_map_out_ss = | ||
6469 | channel_map_aes32; | ||
6470 | hdspm->channel_map_in_ds = hdspm->channel_map_out_ds = | ||
6471 | channel_map_aes32; | ||
6472 | hdspm->channel_map_in_qs = hdspm->channel_map_out_qs = | ||
6473 | channel_map_aes32; | ||
6474 | hdspm->port_names_in_ss = hdspm->port_names_out_ss = | ||
6475 | texts_ports_aes32; | ||
6476 | hdspm->port_names_in_ds = hdspm->port_names_out_ds = | ||
6477 | texts_ports_aes32; | ||
6478 | hdspm->port_names_in_qs = hdspm->port_names_out_qs = | ||
6479 | texts_ports_aes32; | ||
6480 | |||
6481 | hdspm->max_channels_out = hdspm->max_channels_in = | ||
6482 | AES32_CHANNELS; | ||
6483 | hdspm->port_names_in = hdspm->port_names_out = | ||
6484 | texts_ports_aes32; | ||
6485 | hdspm->channel_map_in = hdspm->channel_map_out = | ||
6486 | channel_map_aes32; | ||
6487 | |||
6488 | break; | ||
6489 | |||
6490 | case MADI: | ||
6491 | case MADIface: | ||
6492 | hdspm->ss_in_channels = hdspm->ss_out_channels = | ||
6493 | MADI_SS_CHANNELS; | ||
6494 | hdspm->ds_in_channels = hdspm->ds_out_channels = | ||
6495 | MADI_DS_CHANNELS; | ||
6496 | hdspm->qs_in_channels = hdspm->qs_out_channels = | ||
6497 | MADI_QS_CHANNELS; | ||
6498 | |||
6499 | hdspm->channel_map_in_ss = hdspm->channel_map_out_ss = | ||
6500 | channel_map_unity_ss; | ||
6501 | hdspm->channel_map_in_ds = hdspm->channel_map_out_ds = | ||
6502 | channel_map_unity_ss; | ||
6503 | hdspm->channel_map_in_qs = hdspm->channel_map_out_qs = | ||
6504 | channel_map_unity_ss; | ||
6505 | |||
6506 | hdspm->port_names_in_ss = hdspm->port_names_out_ss = | ||
6507 | texts_ports_madi; | ||
6508 | hdspm->port_names_in_ds = hdspm->port_names_out_ds = | ||
6509 | texts_ports_madi; | ||
6510 | hdspm->port_names_in_qs = hdspm->port_names_out_qs = | ||
6511 | texts_ports_madi; | ||
6512 | break; | ||
6513 | |||
6514 | case AIO: | ||
6515 | if (0 == (hdspm_read(hdspm, HDSPM_statusRegister2) & HDSPM_s2_AEBI_D)) { | ||
6516 | snd_printk(KERN_INFO "HDSPM: AEB input board found, but not supported\n"); | ||
6517 | } | ||
6518 | |||
6519 | hdspm->ss_in_channels = AIO_IN_SS_CHANNELS; | ||
6520 | hdspm->ds_in_channels = AIO_IN_DS_CHANNELS; | ||
6521 | hdspm->qs_in_channels = AIO_IN_QS_CHANNELS; | ||
6522 | hdspm->ss_out_channels = AIO_OUT_SS_CHANNELS; | ||
6523 | hdspm->ds_out_channels = AIO_OUT_DS_CHANNELS; | ||
6524 | hdspm->qs_out_channels = AIO_OUT_QS_CHANNELS; | ||
6525 | |||
6526 | hdspm->channel_map_out_ss = channel_map_aio_out_ss; | ||
6527 | hdspm->channel_map_out_ds = channel_map_aio_out_ds; | ||
6528 | hdspm->channel_map_out_qs = channel_map_aio_out_qs; | ||
6529 | |||
6530 | hdspm->channel_map_in_ss = channel_map_aio_in_ss; | ||
6531 | hdspm->channel_map_in_ds = channel_map_aio_in_ds; | ||
6532 | hdspm->channel_map_in_qs = channel_map_aio_in_qs; | ||
6533 | |||
6534 | hdspm->port_names_in_ss = texts_ports_aio_in_ss; | ||
6535 | hdspm->port_names_out_ss = texts_ports_aio_out_ss; | ||
6536 | hdspm->port_names_in_ds = texts_ports_aio_in_ds; | ||
6537 | hdspm->port_names_out_ds = texts_ports_aio_out_ds; | ||
6538 | hdspm->port_names_in_qs = texts_ports_aio_in_qs; | ||
6539 | hdspm->port_names_out_qs = texts_ports_aio_out_qs; | ||
6540 | |||
6541 | break; | ||
6542 | |||
6543 | case RayDAT: | ||
6544 | hdspm->ss_in_channels = hdspm->ss_out_channels = | ||
6545 | RAYDAT_SS_CHANNELS; | ||
6546 | hdspm->ds_in_channels = hdspm->ds_out_channels = | ||
6547 | RAYDAT_DS_CHANNELS; | ||
6548 | hdspm->qs_in_channels = hdspm->qs_out_channels = | ||
6549 | RAYDAT_QS_CHANNELS; | ||
6550 | |||
6551 | hdspm->max_channels_in = RAYDAT_SS_CHANNELS; | ||
6552 | hdspm->max_channels_out = RAYDAT_SS_CHANNELS; | ||
6553 | |||
6554 | hdspm->channel_map_in_ss = hdspm->channel_map_out_ss = | ||
6555 | channel_map_raydat_ss; | ||
6556 | hdspm->channel_map_in_ds = hdspm->channel_map_out_ds = | ||
6557 | channel_map_raydat_ds; | ||
6558 | hdspm->channel_map_in_qs = hdspm->channel_map_out_qs = | ||
6559 | channel_map_raydat_qs; | ||
6560 | hdspm->channel_map_in = hdspm->channel_map_out = | ||
6561 | channel_map_raydat_ss; | ||
6562 | |||
6563 | hdspm->port_names_in_ss = hdspm->port_names_out_ss = | ||
6564 | texts_ports_raydat_ss; | ||
6565 | hdspm->port_names_in_ds = hdspm->port_names_out_ds = | ||
6566 | texts_ports_raydat_ds; | ||
6567 | hdspm->port_names_in_qs = hdspm->port_names_out_qs = | ||
6568 | texts_ports_raydat_qs; | ||
6569 | |||
6570 | |||
6571 | break; | ||
6572 | |||
6573 | } | ||
6574 | |||
6575 | /* TCO detection */ | ||
6576 | switch (hdspm->io_type) { | ||
6577 | case AIO: | ||
6578 | case RayDAT: | ||
6579 | if (hdspm_read(hdspm, HDSPM_statusRegister2) & | ||
6580 | HDSPM_s2_tco_detect) { | ||
6581 | hdspm->midiPorts++; | ||
6582 | hdspm->tco = kzalloc(sizeof(struct hdspm_tco), | ||
6583 | GFP_KERNEL); | ||
6584 | if (NULL != hdspm->tco) { | ||
6585 | hdspm_tco_write(hdspm); | ||
6586 | } | ||
6587 | snd_printk(KERN_INFO "HDSPM: AIO/RayDAT TCO module found\n"); | ||
6588 | } else { | ||
6589 | hdspm->tco = NULL; | ||
6590 | } | ||
6591 | break; | ||
6592 | |||
6593 | case MADI: | ||
6594 | if (hdspm_read(hdspm, HDSPM_statusRegister) & HDSPM_tco_detect) { | ||
6595 | hdspm->midiPorts++; | ||
6596 | hdspm->tco = kzalloc(sizeof(struct hdspm_tco), | ||
6597 | GFP_KERNEL); | ||
6598 | if (NULL != hdspm->tco) { | ||
6599 | hdspm_tco_write(hdspm); | ||
6600 | } | ||
6601 | snd_printk(KERN_INFO "HDSPM: MADI TCO module found\n"); | ||
6602 | } else { | ||
6603 | hdspm->tco = NULL; | ||
6604 | } | ||
6605 | break; | ||
6606 | |||
6607 | default: | ||
6608 | hdspm->tco = NULL; | ||
6609 | } | ||
6610 | |||
6611 | /* texts */ | ||
6612 | switch (hdspm->io_type) { | ||
6613 | case AES32: | ||
6614 | if (hdspm->tco) { | ||
6615 | hdspm->texts_autosync = texts_autosync_aes_tco; | ||
6616 | hdspm->texts_autosync_items = 10; | ||
6617 | } else { | ||
6618 | hdspm->texts_autosync = texts_autosync_aes; | ||
6619 | hdspm->texts_autosync_items = 9; | ||
6620 | } | ||
6621 | break; | ||
6622 | |||
6623 | case MADI: | ||
6624 | if (hdspm->tco) { | ||
6625 | hdspm->texts_autosync = texts_autosync_madi_tco; | ||
6626 | hdspm->texts_autosync_items = 4; | ||
6627 | } else { | ||
6628 | hdspm->texts_autosync = texts_autosync_madi; | ||
6629 | hdspm->texts_autosync_items = 3; | ||
6630 | } | ||
6631 | break; | ||
6632 | |||
6633 | case MADIface: | ||
6634 | |||
6635 | break; | ||
6636 | |||
6637 | case RayDAT: | ||
6638 | if (hdspm->tco) { | ||
6639 | hdspm->texts_autosync = texts_autosync_raydat_tco; | ||
6640 | hdspm->texts_autosync_items = 9; | ||
6641 | } else { | ||
6642 | hdspm->texts_autosync = texts_autosync_raydat; | ||
6643 | hdspm->texts_autosync_items = 8; | ||
6644 | } | ||
6645 | break; | ||
6646 | |||
6647 | case AIO: | ||
6648 | if (hdspm->tco) { | ||
6649 | hdspm->texts_autosync = texts_autosync_aio_tco; | ||
6650 | hdspm->texts_autosync_items = 6; | ||
6651 | } else { | ||
6652 | hdspm->texts_autosync = texts_autosync_aio; | ||
6653 | hdspm->texts_autosync_items = 5; | ||
6654 | } | ||
6655 | break; | ||
6656 | |||
6657 | } | ||
6658 | |||
6659 | tasklet_init(&hdspm->midi_tasklet, | ||
6660 | hdspm_midi_tasklet, (unsigned long) hdspm); | ||
4436 | 6661 | ||
4437 | snd_printdd("create alsa devices.\n"); | 6662 | snd_printdd("create alsa devices.\n"); |
4438 | err = snd_hdspm_create_alsa_devices(card, hdspm); | 6663 | err = snd_hdspm_create_alsa_devices(card, hdspm); |
@@ -4444,6 +6669,7 @@ static int __devinit snd_hdspm_create(struct snd_card *card, | |||
4444 | return 0; | 6669 | return 0; |
4445 | } | 6670 | } |
4446 | 6671 | ||
6672 | |||
4447 | static int snd_hdspm_free(struct hdspm * hdspm) | 6673 | static int snd_hdspm_free(struct hdspm * hdspm) |
4448 | { | 6674 | { |
4449 | 6675 | ||
@@ -4452,7 +6678,8 @@ static int snd_hdspm_free(struct hdspm * hdspm) | |||
4452 | /* stop th audio, and cancel all interrupts */ | 6678 | /* stop th audio, and cancel all interrupts */ |
4453 | hdspm->control_register &= | 6679 | hdspm->control_register &= |
4454 | ~(HDSPM_Start | HDSPM_AudioInterruptEnable | | 6680 | ~(HDSPM_Start | HDSPM_AudioInterruptEnable | |
4455 | HDSPM_Midi0InterruptEnable | HDSPM_Midi1InterruptEnable); | 6681 | HDSPM_Midi0InterruptEnable | HDSPM_Midi1InterruptEnable | |
6682 | HDSPM_Midi2InterruptEnable | HDSPM_Midi3InterruptEnable); | ||
4456 | hdspm_write(hdspm, HDSPM_controlRegister, | 6683 | hdspm_write(hdspm, HDSPM_controlRegister, |
4457 | hdspm->control_register); | 6684 | hdspm->control_register); |
4458 | } | 6685 | } |
@@ -4472,6 +6699,7 @@ static int snd_hdspm_free(struct hdspm * hdspm) | |||
4472 | return 0; | 6699 | return 0; |
4473 | } | 6700 | } |
4474 | 6701 | ||
6702 | |||
4475 | static void snd_hdspm_card_free(struct snd_card *card) | 6703 | static void snd_hdspm_card_free(struct snd_card *card) |
4476 | { | 6704 | { |
4477 | struct hdspm *hdspm = card->private_data; | 6705 | struct hdspm *hdspm = card->private_data; |
@@ -4480,6 +6708,7 @@ static void snd_hdspm_card_free(struct snd_card *card) | |||
4480 | snd_hdspm_free(hdspm); | 6708 | snd_hdspm_free(hdspm); |
4481 | } | 6709 | } |
4482 | 6710 | ||
6711 | |||
4483 | static int __devinit snd_hdspm_probe(struct pci_dev *pci, | 6712 | static int __devinit snd_hdspm_probe(struct pci_dev *pci, |
4484 | const struct pci_device_id *pci_id) | 6713 | const struct pci_device_id *pci_id) |
4485 | { | 6714 | { |
@@ -4496,7 +6725,7 @@ static int __devinit snd_hdspm_probe(struct pci_dev *pci, | |||
4496 | } | 6725 | } |
4497 | 6726 | ||
4498 | err = snd_card_create(index[dev], id[dev], | 6727 | err = snd_card_create(index[dev], id[dev], |
4499 | THIS_MODULE, sizeof(struct hdspm), &card); | 6728 | THIS_MODULE, sizeof(struct hdspm), &card); |
4500 | if (err < 0) | 6729 | if (err < 0) |
4501 | return err; | 6730 | return err; |
4502 | 6731 | ||
@@ -4507,16 +6736,25 @@ static int __devinit snd_hdspm_probe(struct pci_dev *pci, | |||
4507 | 6736 | ||
4508 | snd_card_set_dev(card, &pci->dev); | 6737 | snd_card_set_dev(card, &pci->dev); |
4509 | 6738 | ||
4510 | err = snd_hdspm_create(card, hdspm, precise_ptr[dev], | 6739 | err = snd_hdspm_create(card, hdspm); |
4511 | enable_monitor[dev]); | ||
4512 | if (err < 0) { | 6740 | if (err < 0) { |
4513 | snd_card_free(card); | 6741 | snd_card_free(card); |
4514 | return err; | 6742 | return err; |
4515 | } | 6743 | } |
4516 | 6744 | ||
4517 | strcpy(card->shortname, "HDSPM MADI"); | 6745 | if (hdspm->io_type != MADIface) { |
4518 | sprintf(card->longname, "%s at 0x%lx, irq %d", hdspm->card_name, | 6746 | sprintf(card->shortname, "%s_%x", |
4519 | hdspm->port, hdspm->irq); | 6747 | hdspm->card_name, |
6748 | (hdspm_read(hdspm, HDSPM_midiStatusIn0)>>8) & 0xFFFFFF); | ||
6749 | sprintf(card->longname, "%s S/N 0x%x at 0x%lx, irq %d", | ||
6750 | hdspm->card_name, | ||
6751 | (hdspm_read(hdspm, HDSPM_midiStatusIn0)>>8) & 0xFFFFFF, | ||
6752 | hdspm->port, hdspm->irq); | ||
6753 | } else { | ||
6754 | sprintf(card->shortname, "%s", hdspm->card_name); | ||
6755 | sprintf(card->longname, "%s at 0x%lx, irq %d", | ||
6756 | hdspm->card_name, hdspm->port, hdspm->irq); | ||
6757 | } | ||
4520 | 6758 | ||
4521 | err = snd_card_register(card); | 6759 | err = snd_card_register(card); |
4522 | if (err < 0) { | 6760 | if (err < 0) { |