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