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