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