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