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