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