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