blob: 845158b01b0295ac089b16b56110bc1f30bf47c3 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * ALSA driver for RME Hammerfall DSP audio interface(s)
3 *
4 * Copyright (c) 2002 Paul Davis
5 * Marcus Andersson
6 * Thomas Charbonnel
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 */
23
24#include <sound/driver.h>
25#include <linux/init.h>
26#include <linux/delay.h>
27#include <linux/interrupt.h>
28#include <linux/slab.h>
29#include <linux/pci.h>
30#include <linux/firmware.h>
31#include <linux/moduleparam.h>
32
33#include <sound/core.h>
34#include <sound/control.h>
35#include <sound/pcm.h>
36#include <sound/info.h>
37#include <sound/asoundef.h>
38#include <sound/rawmidi.h>
39#include <sound/hwdep.h>
40#include <sound/initval.h>
41#include <sound/hdsp.h>
42
43#include <asm/byteorder.h>
44#include <asm/current.h>
45#include <asm/io.h>
46
47static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
48static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
49static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
50
51module_param_array(index, int, NULL, 0444);
52MODULE_PARM_DESC(index, "Index value for RME Hammerfall DSP interface.");
53module_param_array(id, charp, NULL, 0444);
54MODULE_PARM_DESC(id, "ID string for RME Hammerfall DSP interface.");
55module_param_array(enable, bool, NULL, 0444);
56MODULE_PARM_DESC(enable, "Enable/disable specific Hammerfall DSP soundcards.");
57MODULE_AUTHOR("Paul Davis <paul@linuxaudiosystems.com>, Marcus Andersson, Thomas Charbonnel <thomas@undata.org>");
58MODULE_DESCRIPTION("RME Hammerfall DSP");
59MODULE_LICENSE("GPL");
60MODULE_SUPPORTED_DEVICE("{{RME Hammerfall-DSP},"
61 "{RME HDSP-9652},"
62 "{RME HDSP-9632}}");
63
64#define HDSP_MAX_CHANNELS 26
65#define HDSP_MAX_DS_CHANNELS 14
66#define HDSP_MAX_QS_CHANNELS 8
67#define DIGIFACE_SS_CHANNELS 26
68#define DIGIFACE_DS_CHANNELS 14
69#define MULTIFACE_SS_CHANNELS 18
70#define MULTIFACE_DS_CHANNELS 14
71#define H9652_SS_CHANNELS 26
72#define H9652_DS_CHANNELS 14
73/* This does not include possible Analog Extension Boards
74 AEBs are detected at card initialization
75*/
76#define H9632_SS_CHANNELS 12
77#define H9632_DS_CHANNELS 8
78#define H9632_QS_CHANNELS 4
79
80/* Write registers. These are defined as byte-offsets from the iobase value.
81 */
82#define HDSP_resetPointer 0
83#define HDSP_outputBufferAddress 32
84#define HDSP_inputBufferAddress 36
85#define HDSP_controlRegister 64
86#define HDSP_interruptConfirmation 96
87#define HDSP_outputEnable 128
88#define HDSP_control2Reg 256
89#define HDSP_midiDataOut0 352
90#define HDSP_midiDataOut1 356
91#define HDSP_fifoData 368
92#define HDSP_inputEnable 384
93
94/* Read registers. These are defined as byte-offsets from the iobase value
95 */
96
97#define HDSP_statusRegister 0
98#define HDSP_timecode 128
99#define HDSP_status2Register 192
100#define HDSP_midiDataOut0 352
101#define HDSP_midiDataOut1 356
102#define HDSP_midiDataIn0 360
103#define HDSP_midiDataIn1 364
104#define HDSP_midiStatusOut0 384
105#define HDSP_midiStatusOut1 388
106#define HDSP_midiStatusIn0 392
107#define HDSP_midiStatusIn1 396
108#define HDSP_fifoStatus 400
109
110/* the meters are regular i/o-mapped registers, but offset
111 considerably from the rest. the peak registers are reset
112 when read; the least-significant 4 bits are full-scale counters;
113 the actual peak value is in the most-significant 24 bits.
114*/
115
116#define HDSP_playbackPeakLevel 4096 /* 26 * 32 bit values */
117#define HDSP_inputPeakLevel 4224 /* 26 * 32 bit values */
118#define HDSP_outputPeakLevel 4352 /* (26+2) * 32 bit values */
119#define HDSP_playbackRmsLevel 4612 /* 26 * 64 bit values */
120#define HDSP_inputRmsLevel 4868 /* 26 * 64 bit values */
121
122
123/* This is for H9652 cards
124 Peak values are read downward from the base
125 Rms values are read upward
126 There are rms values for the outputs too
127 26*3 values are read in ss mode
128 14*3 in ds mode, with no gap between values
129*/
130#define HDSP_9652_peakBase 7164
131#define HDSP_9652_rmsBase 4096
132
133/* c.f. the hdsp_9632_meters_t struct */
134#define HDSP_9632_metersBase 4096
135
136#define HDSP_IO_EXTENT 7168
137
138/* control2 register bits */
139
140#define HDSP_TMS 0x01
141#define HDSP_TCK 0x02
142#define HDSP_TDI 0x04
143#define HDSP_JTAG 0x08
144#define HDSP_PWDN 0x10
145#define HDSP_PROGRAM 0x020
146#define HDSP_CONFIG_MODE_0 0x040
147#define HDSP_CONFIG_MODE_1 0x080
148#define HDSP_VERSION_BIT 0x100
149#define HDSP_BIGENDIAN_MODE 0x200
150#define HDSP_RD_MULTIPLE 0x400
151#define HDSP_9652_ENABLE_MIXER 0x800
152#define HDSP_TDO 0x10000000
153
154#define HDSP_S_PROGRAM (HDSP_PROGRAM|HDSP_CONFIG_MODE_0)
155#define HDSP_S_LOAD (HDSP_PROGRAM|HDSP_CONFIG_MODE_1)
156
157/* Control Register bits */
158
159#define HDSP_Start (1<<0) /* start engine */
160#define HDSP_Latency0 (1<<1) /* buffer size = 2^n where n is defined by Latency{2,1,0} */
161#define HDSP_Latency1 (1<<2) /* [ see above ] */
162#define HDSP_Latency2 (1<<3) /* [ see above ] */
163#define HDSP_ClockModeMaster (1<<4) /* 1=Master, 0=Slave/Autosync */
164#define HDSP_AudioInterruptEnable (1<<5) /* what do you think ? */
165#define HDSP_Frequency0 (1<<6) /* 0=44.1kHz/88.2kHz/176.4kHz 1=48kHz/96kHz/192kHz */
166#define HDSP_Frequency1 (1<<7) /* 0=32kHz/64kHz/128kHz */
167#define HDSP_DoubleSpeed (1<<8) /* 0=normal speed, 1=double speed */
168#define HDSP_SPDIFProfessional (1<<9) /* 0=consumer, 1=professional */
169#define HDSP_SPDIFEmphasis (1<<10) /* 0=none, 1=on */
170#define HDSP_SPDIFNonAudio (1<<11) /* 0=off, 1=on */
171#define HDSP_SPDIFOpticalOut (1<<12) /* 1=use 1st ADAT connector for SPDIF, 0=do not */
172#define HDSP_SyncRef2 (1<<13)
173#define HDSP_SPDIFInputSelect0 (1<<14)
174#define HDSP_SPDIFInputSelect1 (1<<15)
175#define HDSP_SyncRef0 (1<<16)
176#define HDSP_SyncRef1 (1<<17)
177#define HDSP_AnalogExtensionBoard (1<<18) /* For H9632 cards */
178#define HDSP_XLRBreakoutCable (1<<20) /* For H9632 cards */
179#define HDSP_Midi0InterruptEnable (1<<22)
180#define HDSP_Midi1InterruptEnable (1<<23)
181#define HDSP_LineOut (1<<24)
182#define HDSP_ADGain0 (1<<25) /* From here : H9632 specific */
183#define HDSP_ADGain1 (1<<26)
184#define HDSP_DAGain0 (1<<27)
185#define HDSP_DAGain1 (1<<28)
186#define HDSP_PhoneGain0 (1<<29)
187#define HDSP_PhoneGain1 (1<<30)
188#define HDSP_QuadSpeed (1<<31)
189
190#define HDSP_ADGainMask (HDSP_ADGain0|HDSP_ADGain1)
191#define HDSP_ADGainMinus10dBV HDSP_ADGainMask
192#define HDSP_ADGainPlus4dBu (HDSP_ADGain0)
193#define HDSP_ADGainLowGain 0
194
195#define HDSP_DAGainMask (HDSP_DAGain0|HDSP_DAGain1)
196#define HDSP_DAGainHighGain HDSP_DAGainMask
197#define HDSP_DAGainPlus4dBu (HDSP_DAGain0)
198#define HDSP_DAGainMinus10dBV 0
199
200#define HDSP_PhoneGainMask (HDSP_PhoneGain0|HDSP_PhoneGain1)
201#define HDSP_PhoneGain0dB HDSP_PhoneGainMask
202#define HDSP_PhoneGainMinus6dB (HDSP_PhoneGain0)
203#define HDSP_PhoneGainMinus12dB 0
204
205#define HDSP_LatencyMask (HDSP_Latency0|HDSP_Latency1|HDSP_Latency2)
206#define HDSP_FrequencyMask (HDSP_Frequency0|HDSP_Frequency1|HDSP_DoubleSpeed|HDSP_QuadSpeed)
207
208#define HDSP_SPDIFInputMask (HDSP_SPDIFInputSelect0|HDSP_SPDIFInputSelect1)
209#define HDSP_SPDIFInputADAT1 0
210#define HDSP_SPDIFInputCoaxial (HDSP_SPDIFInputSelect0)
211#define HDSP_SPDIFInputCdrom (HDSP_SPDIFInputSelect1)
212#define HDSP_SPDIFInputAES (HDSP_SPDIFInputSelect0|HDSP_SPDIFInputSelect1)
213
214#define HDSP_SyncRefMask (HDSP_SyncRef0|HDSP_SyncRef1|HDSP_SyncRef2)
215#define HDSP_SyncRef_ADAT1 0
216#define HDSP_SyncRef_ADAT2 (HDSP_SyncRef0)
217#define HDSP_SyncRef_ADAT3 (HDSP_SyncRef1)
218#define HDSP_SyncRef_SPDIF (HDSP_SyncRef0|HDSP_SyncRef1)
219#define HDSP_SyncRef_WORD (HDSP_SyncRef2)
220#define HDSP_SyncRef_ADAT_SYNC (HDSP_SyncRef0|HDSP_SyncRef2)
221
222/* Sample Clock Sources */
223
224#define HDSP_CLOCK_SOURCE_AUTOSYNC 0
225#define HDSP_CLOCK_SOURCE_INTERNAL_32KHZ 1
226#define HDSP_CLOCK_SOURCE_INTERNAL_44_1KHZ 2
227#define HDSP_CLOCK_SOURCE_INTERNAL_48KHZ 3
228#define HDSP_CLOCK_SOURCE_INTERNAL_64KHZ 4
229#define HDSP_CLOCK_SOURCE_INTERNAL_88_2KHZ 5
230#define HDSP_CLOCK_SOURCE_INTERNAL_96KHZ 6
231#define HDSP_CLOCK_SOURCE_INTERNAL_128KHZ 7
232#define HDSP_CLOCK_SOURCE_INTERNAL_176_4KHZ 8
233#define HDSP_CLOCK_SOURCE_INTERNAL_192KHZ 9
234
235/* Preferred sync reference choices - used by "pref_sync_ref" control switch */
236
237#define HDSP_SYNC_FROM_WORD 0
238#define HDSP_SYNC_FROM_SPDIF 1
239#define HDSP_SYNC_FROM_ADAT1 2
240#define HDSP_SYNC_FROM_ADAT_SYNC 3
241#define HDSP_SYNC_FROM_ADAT2 4
242#define HDSP_SYNC_FROM_ADAT3 5
243
244/* SyncCheck status */
245
246#define HDSP_SYNC_CHECK_NO_LOCK 0
247#define HDSP_SYNC_CHECK_LOCK 1
248#define HDSP_SYNC_CHECK_SYNC 2
249
250/* AutoSync references - used by "autosync_ref" control switch */
251
252#define HDSP_AUTOSYNC_FROM_WORD 0
253#define HDSP_AUTOSYNC_FROM_ADAT_SYNC 1
254#define HDSP_AUTOSYNC_FROM_SPDIF 2
255#define HDSP_AUTOSYNC_FROM_NONE 3
256#define HDSP_AUTOSYNC_FROM_ADAT1 4
257#define HDSP_AUTOSYNC_FROM_ADAT2 5
258#define HDSP_AUTOSYNC_FROM_ADAT3 6
259
260/* Possible sources of S/PDIF input */
261
262#define HDSP_SPDIFIN_OPTICAL 0 /* optical (ADAT1) */
263#define HDSP_SPDIFIN_COAXIAL 1 /* coaxial (RCA) */
264#define HDSP_SPDIFIN_INTERNAL 2 /* internal (CDROM) */
265#define HDSP_SPDIFIN_AES 3 /* xlr for H9632 (AES)*/
266
267#define HDSP_Frequency32KHz HDSP_Frequency0
268#define HDSP_Frequency44_1KHz HDSP_Frequency1
269#define HDSP_Frequency48KHz (HDSP_Frequency1|HDSP_Frequency0)
270#define HDSP_Frequency64KHz (HDSP_DoubleSpeed|HDSP_Frequency0)
271#define HDSP_Frequency88_2KHz (HDSP_DoubleSpeed|HDSP_Frequency1)
272#define HDSP_Frequency96KHz (HDSP_DoubleSpeed|HDSP_Frequency1|HDSP_Frequency0)
273/* For H9632 cards */
274#define HDSP_Frequency128KHz (HDSP_QuadSpeed|HDSP_DoubleSpeed|HDSP_Frequency0)
275#define HDSP_Frequency176_4KHz (HDSP_QuadSpeed|HDSP_DoubleSpeed|HDSP_Frequency1)
276#define HDSP_Frequency192KHz (HDSP_QuadSpeed|HDSP_DoubleSpeed|HDSP_Frequency1|HDSP_Frequency0)
277
278#define hdsp_encode_latency(x) (((x)<<1) & HDSP_LatencyMask)
279#define hdsp_decode_latency(x) (((x) & HDSP_LatencyMask)>>1)
280
281#define hdsp_encode_spdif_in(x) (((x)&0x3)<<14)
282#define hdsp_decode_spdif_in(x) (((x)>>14)&0x3)
283
284/* Status Register bits */
285
286#define HDSP_audioIRQPending (1<<0)
287#define HDSP_Lock2 (1<<1) /* this is for Digiface and H9652 */
288#define HDSP_spdifFrequency3 HDSP_Lock2 /* this is for H9632 only */
289#define HDSP_Lock1 (1<<2)
290#define HDSP_Lock0 (1<<3)
291#define HDSP_SPDIFSync (1<<4)
292#define HDSP_TimecodeLock (1<<5)
293#define HDSP_BufferPositionMask 0x000FFC0 /* Bit 6..15 : h/w buffer pointer */
294#define HDSP_Sync2 (1<<16)
295#define HDSP_Sync1 (1<<17)
296#define HDSP_Sync0 (1<<18)
297#define HDSP_DoubleSpeedStatus (1<<19)
298#define HDSP_ConfigError (1<<20)
299#define HDSP_DllError (1<<21)
300#define HDSP_spdifFrequency0 (1<<22)
301#define HDSP_spdifFrequency1 (1<<23)
302#define HDSP_spdifFrequency2 (1<<24)
303#define HDSP_SPDIFErrorFlag (1<<25)
304#define HDSP_BufferID (1<<26)
305#define HDSP_TimecodeSync (1<<27)
306#define HDSP_AEBO (1<<28) /* H9632 specific Analog Extension Boards */
307#define HDSP_AEBI (1<<29) /* 0 = present, 1 = absent */
308#define HDSP_midi0IRQPending (1<<30)
309#define HDSP_midi1IRQPending (1<<31)
310
311#define HDSP_spdifFrequencyMask (HDSP_spdifFrequency0|HDSP_spdifFrequency1|HDSP_spdifFrequency2)
312
313#define HDSP_spdifFrequency32KHz (HDSP_spdifFrequency0)
314#define HDSP_spdifFrequency44_1KHz (HDSP_spdifFrequency1)
315#define HDSP_spdifFrequency48KHz (HDSP_spdifFrequency0|HDSP_spdifFrequency1)
316
317#define HDSP_spdifFrequency64KHz (HDSP_spdifFrequency2)
318#define HDSP_spdifFrequency88_2KHz (HDSP_spdifFrequency0|HDSP_spdifFrequency2)
319#define HDSP_spdifFrequency96KHz (HDSP_spdifFrequency2|HDSP_spdifFrequency1)
320
321/* This is for H9632 cards */
322#define HDSP_spdifFrequency128KHz HDSP_spdifFrequencyMask
323#define HDSP_spdifFrequency176_4KHz HDSP_spdifFrequency3
324#define HDSP_spdifFrequency192KHz (HDSP_spdifFrequency3|HDSP_spdifFrequency0)
325
326/* Status2 Register bits */
327
328#define HDSP_version0 (1<<0)
329#define HDSP_version1 (1<<1)
330#define HDSP_version2 (1<<2)
331#define HDSP_wc_lock (1<<3)
332#define HDSP_wc_sync (1<<4)
333#define HDSP_inp_freq0 (1<<5)
334#define HDSP_inp_freq1 (1<<6)
335#define HDSP_inp_freq2 (1<<7)
336#define HDSP_SelSyncRef0 (1<<8)
337#define HDSP_SelSyncRef1 (1<<9)
338#define HDSP_SelSyncRef2 (1<<10)
339
340#define HDSP_wc_valid (HDSP_wc_lock|HDSP_wc_sync)
341
342#define HDSP_systemFrequencyMask (HDSP_inp_freq0|HDSP_inp_freq1|HDSP_inp_freq2)
343#define HDSP_systemFrequency32 (HDSP_inp_freq0)
344#define HDSP_systemFrequency44_1 (HDSP_inp_freq1)
345#define HDSP_systemFrequency48 (HDSP_inp_freq0|HDSP_inp_freq1)
346#define HDSP_systemFrequency64 (HDSP_inp_freq2)
347#define HDSP_systemFrequency88_2 (HDSP_inp_freq0|HDSP_inp_freq2)
348#define HDSP_systemFrequency96 (HDSP_inp_freq1|HDSP_inp_freq2)
349/* FIXME : more values for 9632 cards ? */
350
351#define HDSP_SelSyncRefMask (HDSP_SelSyncRef0|HDSP_SelSyncRef1|HDSP_SelSyncRef2)
352#define HDSP_SelSyncRef_ADAT1 0
353#define HDSP_SelSyncRef_ADAT2 (HDSP_SelSyncRef0)
354#define HDSP_SelSyncRef_ADAT3 (HDSP_SelSyncRef1)
355#define HDSP_SelSyncRef_SPDIF (HDSP_SelSyncRef0|HDSP_SelSyncRef1)
356#define HDSP_SelSyncRef_WORD (HDSP_SelSyncRef2)
357#define HDSP_SelSyncRef_ADAT_SYNC (HDSP_SelSyncRef0|HDSP_SelSyncRef2)
358
359/* Card state flags */
360
361#define HDSP_InitializationComplete (1<<0)
362#define HDSP_FirmwareLoaded (1<<1)
363#define HDSP_FirmwareCached (1<<2)
364
365/* FIFO wait times, defined in terms of 1/10ths of msecs */
366
367#define HDSP_LONG_WAIT 5000
368#define HDSP_SHORT_WAIT 30
369
370#define UNITY_GAIN 32768
371#define MINUS_INFINITY_GAIN 0
372
Linus Torvalds1da177e2005-04-16 15:20:36 -0700373/* the size of a substream (1 mono data stream) */
374
375#define HDSP_CHANNEL_BUFFER_SAMPLES (16*1024)
376#define HDSP_CHANNEL_BUFFER_BYTES (4*HDSP_CHANNEL_BUFFER_SAMPLES)
377
378/* the size of the area we need to allocate for DMA transfers. the
379 size is the same regardless of the number of channels - the
380 Multiface still uses the same memory area.
381
382 Note that we allocate 1 more channel than is apparently needed
383 because the h/w seems to write 1 byte beyond the end of the last
384 page. Sigh.
385*/
386
387#define HDSP_DMA_AREA_BYTES ((HDSP_MAX_CHANNELS+1) * HDSP_CHANNEL_BUFFER_BYTES)
388#define HDSP_DMA_AREA_KILOBYTES (HDSP_DMA_AREA_BYTES/1024)
389
390/* use hotplug firmeare loader? */
391#if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE)
392#ifndef HDSP_USE_HWDEP_LOADER
393#define HDSP_FW_LOADER
394#endif
395#endif
396
397typedef struct _hdsp hdsp_t;
398typedef struct _hdsp_midi hdsp_midi_t;
399typedef struct _hdsp_9632_meters hdsp_9632_meters_t;
400
401struct _hdsp_9632_meters {
402 u32 input_peak[16];
403 u32 playback_peak[16];
404 u32 output_peak[16];
405 u32 xxx_peak[16];
406 u32 padding[64];
407 u32 input_rms_low[16];
408 u32 playback_rms_low[16];
409 u32 output_rms_low[16];
410 u32 xxx_rms_low[16];
411 u32 input_rms_high[16];
412 u32 playback_rms_high[16];
413 u32 output_rms_high[16];
414 u32 xxx_rms_high[16];
415};
416
417struct _hdsp_midi {
418 hdsp_t *hdsp;
419 int id;
420 snd_rawmidi_t *rmidi;
421 snd_rawmidi_substream_t *input;
422 snd_rawmidi_substream_t *output;
423 char istimer; /* timer in use */
424 struct timer_list timer;
425 spinlock_t lock;
426 int pending;
427};
428
429struct _hdsp {
430 spinlock_t lock;
431 snd_pcm_substream_t *capture_substream;
432 snd_pcm_substream_t *playback_substream;
433 hdsp_midi_t midi[2];
434 struct tasklet_struct midi_tasklet;
435 int use_midi_tasklet;
436 int precise_ptr;
437 u32 control_register; /* cached value */
438 u32 control2_register; /* cached value */
439 u32 creg_spdif;
440 u32 creg_spdif_stream;
Takashi Iwaie3ea4d82005-07-04 18:12:39 +0200441 int clock_source_locked;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700442 char *card_name; /* digiface/multiface */
443 HDSP_IO_Type io_type; /* ditto, but for code use */
444 unsigned short firmware_rev;
445 unsigned short state; /* stores state bits */
446 u32 firmware_cache[24413]; /* this helps recover from accidental iobox power failure */
447 size_t period_bytes; /* guess what this is */
448 unsigned char max_channels;
449 unsigned char qs_in_channels; /* quad speed mode for H9632 */
450 unsigned char ds_in_channels;
451 unsigned char ss_in_channels; /* different for multiface/digiface */
452 unsigned char qs_out_channels;
453 unsigned char ds_out_channels;
454 unsigned char ss_out_channels;
455
456 struct snd_dma_buffer capture_dma_buf;
457 struct snd_dma_buffer playback_dma_buf;
458 unsigned char *capture_buffer; /* suitably aligned address */
459 unsigned char *playback_buffer; /* suitably aligned address */
460
461 pid_t capture_pid;
462 pid_t playback_pid;
463 int running;
464 int system_sample_rate;
465 char *channel_map;
466 int dev;
467 int irq;
468 unsigned long port;
469 void __iomem *iobase;
470 snd_card_t *card;
471 snd_pcm_t *pcm;
472 snd_hwdep_t *hwdep;
473 struct pci_dev *pci;
474 snd_kcontrol_t *spdif_ctl;
475 unsigned short mixer_matrix[HDSP_MATRIX_MIXER_SIZE];
476};
477
478/* These tables map the ALSA channels 1..N to the channels that we
479 need to use in order to find the relevant channel buffer. RME
480 refer to this kind of mapping as between "the ADAT channel and
481 the DMA channel." We index it using the logical audio channel,
482 and the value is the DMA channel (i.e. channel buffer number)
483 where the data for that channel can be read/written from/to.
484*/
485
486static char channel_map_df_ss[HDSP_MAX_CHANNELS] = {
487 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
488 18, 19, 20, 21, 22, 23, 24, 25
489};
490
491static char channel_map_mf_ss[HDSP_MAX_CHANNELS] = { /* Multiface */
492 /* Analog */
493 0, 1, 2, 3, 4, 5, 6, 7,
494 /* ADAT 2 */
495 16, 17, 18, 19, 20, 21, 22, 23,
496 /* SPDIF */
497 24, 25,
498 -1, -1, -1, -1, -1, -1, -1, -1
499};
500
501static char channel_map_ds[HDSP_MAX_CHANNELS] = {
502 /* ADAT channels are remapped */
503 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23,
504 /* channels 12 and 13 are S/PDIF */
505 24, 25,
506 /* others don't exist */
507 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
508};
509
510static char channel_map_H9632_ss[HDSP_MAX_CHANNELS] = {
511 /* ADAT channels */
512 0, 1, 2, 3, 4, 5, 6, 7,
513 /* SPDIF */
514 8, 9,
515 /* Analog */
516 10, 11,
517 /* AO4S-192 and AI4S-192 extension boards */
518 12, 13, 14, 15,
519 /* others don't exist */
520 -1, -1, -1, -1, -1, -1, -1, -1,
521 -1, -1
522};
523
524static char channel_map_H9632_ds[HDSP_MAX_CHANNELS] = {
525 /* ADAT */
526 1, 3, 5, 7,
527 /* SPDIF */
528 8, 9,
529 /* Analog */
530 10, 11,
531 /* AO4S-192 and AI4S-192 extension boards */
532 12, 13, 14, 15,
533 /* others don't exist */
534 -1, -1, -1, -1, -1, -1, -1, -1,
535 -1, -1, -1, -1, -1, -1
536};
537
538static char channel_map_H9632_qs[HDSP_MAX_CHANNELS] = {
539 /* ADAT is disabled in this mode */
540 /* SPDIF */
541 8, 9,
542 /* Analog */
543 10, 11,
544 /* AO4S-192 and AI4S-192 extension boards */
545 12, 13, 14, 15,
546 /* others don't exist */
547 -1, -1, -1, -1, -1, -1, -1, -1,
548 -1, -1, -1, -1, -1, -1, -1, -1,
549 -1, -1
550};
551
552static int snd_hammerfall_get_buffer(struct pci_dev *pci, struct snd_dma_buffer *dmab, size_t size)
553{
554 dmab->dev.type = SNDRV_DMA_TYPE_DEV;
555 dmab->dev.dev = snd_dma_pci_data(pci);
Takashi Iwaib6a96912005-05-30 18:27:03 +0200556 if (snd_dma_get_reserved_buf(dmab, snd_dma_pci_buf_id(pci))) {
557 if (dmab->bytes >= size)
558 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700559 }
Takashi Iwaib6a96912005-05-30 18:27:03 +0200560 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
561 size, dmab) < 0)
562 return -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700563 return 0;
564}
565
566static void snd_hammerfall_free_buffer(struct snd_dma_buffer *dmab, struct pci_dev *pci)
567{
Takashi Iwaib6a96912005-05-30 18:27:03 +0200568 if (dmab->area) {
569 dmab->dev.dev = NULL; /* make it anonymous */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700570 snd_dma_reserve_buf(dmab, snd_dma_pci_buf_id(pci));
Takashi Iwaib6a96912005-05-30 18:27:03 +0200571 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700572}
573
574
575static struct pci_device_id snd_hdsp_ids[] = {
576 {
577 .vendor = PCI_VENDOR_ID_XILINX,
578 .device = PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP,
579 .subvendor = PCI_ANY_ID,
580 .subdevice = PCI_ANY_ID,
581 }, /* RME Hammerfall-DSP */
582 { 0, },
583};
584
585MODULE_DEVICE_TABLE(pci, snd_hdsp_ids);
586
587/* prototypes */
588static int snd_hdsp_create_alsa_devices(snd_card_t *card, hdsp_t *hdsp);
589static int snd_hdsp_create_pcm(snd_card_t *card, hdsp_t *hdsp);
590static int snd_hdsp_enable_io (hdsp_t *hdsp);
591static void snd_hdsp_initialize_midi_flush (hdsp_t *hdsp);
592static void snd_hdsp_initialize_channels (hdsp_t *hdsp);
593static int hdsp_fifo_wait(hdsp_t *hdsp, int count, int timeout);
594static int hdsp_autosync_ref(hdsp_t *hdsp);
595static int snd_hdsp_set_defaults(hdsp_t *hdsp);
596static void snd_hdsp_9652_enable_mixer (hdsp_t *hdsp);
597
598static int hdsp_playback_to_output_key (hdsp_t *hdsp, int in, int out)
599{
600 switch (hdsp->firmware_rev) {
601 case 0xa:
602 return (64 * out) + (32 + (in));
603 case 0x96:
604 case 0x97:
605 return (32 * out) + (16 + (in));
606 default:
607 return (52 * out) + (26 + (in));
608 }
609}
610
611static int hdsp_input_to_output_key (hdsp_t *hdsp, int in, int out)
612{
613 switch (hdsp->firmware_rev) {
614 case 0xa:
615 return (64 * out) + in;
616 case 0x96:
617 case 0x97:
618 return (32 * out) + in;
619 default:
620 return (52 * out) + in;
621 }
622}
623
624static void hdsp_write(hdsp_t *hdsp, int reg, int val)
625{
626 writel(val, hdsp->iobase + reg);
627}
628
629static unsigned int hdsp_read(hdsp_t *hdsp, int reg)
630{
631 return readl (hdsp->iobase + reg);
632}
633
634static int hdsp_check_for_iobox (hdsp_t *hdsp)
635{
636
637 if (hdsp->io_type == H9652 || hdsp->io_type == H9632) return 0;
638 if (hdsp_read (hdsp, HDSP_statusRegister) & HDSP_ConfigError) {
639 snd_printk ("Hammerfall-DSP: no Digiface or Multiface connected!\n");
640 hdsp->state &= ~HDSP_FirmwareLoaded;
641 return -EIO;
642 }
643 return 0;
644
645}
646
647static int snd_hdsp_load_firmware_from_cache(hdsp_t *hdsp) {
648
649 int i;
650 unsigned long flags;
651
652 if ((hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DllError) != 0) {
653
654 snd_printk ("Hammerfall-DSP: loading firmware\n");
655
656 hdsp_write (hdsp, HDSP_control2Reg, HDSP_S_PROGRAM);
657 hdsp_write (hdsp, HDSP_fifoData, 0);
658
659 if (hdsp_fifo_wait (hdsp, 0, HDSP_LONG_WAIT)) {
660 snd_printk ("Hammerfall-DSP: timeout waiting for download preparation\n");
661 return -EIO;
662 }
663
664 hdsp_write (hdsp, HDSP_control2Reg, HDSP_S_LOAD);
665
666 for (i = 0; i < 24413; ++i) {
667 hdsp_write(hdsp, HDSP_fifoData, hdsp->firmware_cache[i]);
668 if (hdsp_fifo_wait (hdsp, 127, HDSP_LONG_WAIT)) {
669 snd_printk ("Hammerfall-DSP: timeout during firmware loading\n");
670 return -EIO;
671 }
672 }
673
Takashi Iwaib0b98112005-10-20 18:29:58 +0200674 ssleep(3);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700675
676 if (hdsp_fifo_wait (hdsp, 0, HDSP_LONG_WAIT)) {
677 snd_printk ("Hammerfall-DSP: timeout at end of firmware loading\n");
678 return -EIO;
679 }
680
681#ifdef SNDRV_BIG_ENDIAN
682 hdsp->control2_register = HDSP_BIGENDIAN_MODE;
683#else
684 hdsp->control2_register = 0;
685#endif
686 hdsp_write (hdsp, HDSP_control2Reg, hdsp->control2_register);
687 snd_printk ("Hammerfall-DSP: finished firmware loading\n");
688
689 }
690 if (hdsp->state & HDSP_InitializationComplete) {
Takashi Iwaib0b98112005-10-20 18:29:58 +0200691 snd_printk(KERN_INFO "Hammerfall-DSP: firmware loaded from cache, restoring defaults\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700692 spin_lock_irqsave(&hdsp->lock, flags);
693 snd_hdsp_set_defaults(hdsp);
694 spin_unlock_irqrestore(&hdsp->lock, flags);
695 }
696
697 hdsp->state |= HDSP_FirmwareLoaded;
698
699 return 0;
700}
701
702static int hdsp_get_iobox_version (hdsp_t *hdsp)
703{
704 if ((hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DllError) != 0) {
705
706 hdsp_write (hdsp, HDSP_control2Reg, HDSP_PROGRAM);
707 hdsp_write (hdsp, HDSP_fifoData, 0);
Takashi Iwaib0b98112005-10-20 18:29:58 +0200708 if (hdsp_fifo_wait (hdsp, 0, HDSP_SHORT_WAIT) < 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700709 return -EIO;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700710
711 hdsp_write (hdsp, HDSP_control2Reg, HDSP_S_LOAD);
712 hdsp_write (hdsp, HDSP_fifoData, 0);
713
714 if (hdsp_fifo_wait (hdsp, 0, HDSP_SHORT_WAIT)) {
715 hdsp->io_type = Multiface;
716 hdsp_write (hdsp, HDSP_control2Reg, HDSP_VERSION_BIT);
717 hdsp_write (hdsp, HDSP_control2Reg, HDSP_S_LOAD);
718 hdsp_fifo_wait (hdsp, 0, HDSP_SHORT_WAIT);
719 } else {
720 hdsp->io_type = Digiface;
721 }
722 } else {
723 /* firmware was already loaded, get iobox type */
Takashi Iwaib0b98112005-10-20 18:29:58 +0200724 if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version1)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700725 hdsp->io_type = Multiface;
Takashi Iwaib0b98112005-10-20 18:29:58 +0200726 else
Linus Torvalds1da177e2005-04-16 15:20:36 -0700727 hdsp->io_type = Digiface;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700728 }
729 return 0;
730}
731
732
Takashi Iwaib0b98112005-10-20 18:29:58 +0200733static int hdsp_check_for_firmware (hdsp_t *hdsp, int show_err)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700734{
735 if (hdsp->io_type == H9652 || hdsp->io_type == H9632) return 0;
736 if ((hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DllError) != 0) {
Takashi Iwaib0b98112005-10-20 18:29:58 +0200737 snd_printk(KERN_ERR "Hammerfall-DSP: firmware not present.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700738 hdsp->state &= ~HDSP_FirmwareLoaded;
Takashi Iwaib0b98112005-10-20 18:29:58 +0200739 if (! show_err)
740 return -EIO;
741 /* try to load firmware */
742 if (hdsp->state & HDSP_FirmwareCached) {
743 if (snd_hdsp_load_firmware_from_cache(hdsp) != 0)
744 snd_printk(KERN_ERR "Hammerfall-DSP: Firmware loading from cache failed, please upload manually.\n");
745 } else {
746 snd_printk(KERN_ERR "Hammerfall-DSP: No firmware loaded nor cached, please upload firmware.\n");
747 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700748 return -EIO;
749 }
750 return 0;
751}
752
753
754static int hdsp_fifo_wait(hdsp_t *hdsp, int count, int timeout)
755{
756 int i;
757
758 /* the fifoStatus registers reports on how many words
759 are available in the command FIFO.
760 */
761
762 for (i = 0; i < timeout; i++) {
763
764 if ((int)(hdsp_read (hdsp, HDSP_fifoStatus) & 0xff) <= count)
765 return 0;
766
767 /* not very friendly, but we only do this during a firmware
768 load and changing the mixer, so we just put up with it.
769 */
770
771 udelay (100);
772 }
773
774 snd_printk ("Hammerfall-DSP: wait for FIFO status <= %d failed after %d iterations\n",
775 count, timeout);
776 return -1;
777}
778
779static int hdsp_read_gain (hdsp_t *hdsp, unsigned int addr)
780{
Takashi Iwaib0b98112005-10-20 18:29:58 +0200781 if (addr >= HDSP_MATRIX_MIXER_SIZE)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700782 return 0;
Takashi Iwaib0b98112005-10-20 18:29:58 +0200783
Linus Torvalds1da177e2005-04-16 15:20:36 -0700784 return hdsp->mixer_matrix[addr];
785}
786
787static int hdsp_write_gain(hdsp_t *hdsp, unsigned int addr, unsigned short data)
788{
789 unsigned int ad;
790
791 if (addr >= HDSP_MATRIX_MIXER_SIZE)
792 return -1;
793
794 if (hdsp->io_type == H9652 || hdsp->io_type == H9632) {
795
796 /* from martin bjornsen:
797
798 "You can only write dwords to the
799 mixer memory which contain two
800 mixer values in the low and high
801 word. So if you want to change
802 value 0 you have to read value 1
803 from the cache and write both to
804 the first dword in the mixer
805 memory."
806 */
807
Takashi Iwaib0b98112005-10-20 18:29:58 +0200808 if (hdsp->io_type == H9632 && addr >= 512)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700809 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700810
Takashi Iwaib0b98112005-10-20 18:29:58 +0200811 if (hdsp->io_type == H9652 && addr >= 1352)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700812 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700813
814 hdsp->mixer_matrix[addr] = data;
815
816
817 /* `addr' addresses a 16-bit wide address, but
818 the address space accessed via hdsp_write
819 uses byte offsets. put another way, addr
820 varies from 0 to 1351, but to access the
821 corresponding memory location, we need
822 to access 0 to 2703 ...
823 */
824 ad = addr/2;
825
826 hdsp_write (hdsp, 4096 + (ad*4),
827 (hdsp->mixer_matrix[(addr&0x7fe)+1] << 16) +
828 hdsp->mixer_matrix[addr&0x7fe]);
829
830 return 0;
831
832 } else {
833
834 ad = (addr << 16) + data;
835
Takashi Iwaib0b98112005-10-20 18:29:58 +0200836 if (hdsp_fifo_wait(hdsp, 127, HDSP_LONG_WAIT))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700837 return -1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700838
839 hdsp_write (hdsp, HDSP_fifoData, ad);
840 hdsp->mixer_matrix[addr] = data;
841
842 }
843
844 return 0;
845}
846
847static int snd_hdsp_use_is_exclusive(hdsp_t *hdsp)
848{
849 unsigned long flags;
850 int ret = 1;
851
852 spin_lock_irqsave(&hdsp->lock, flags);
853 if ((hdsp->playback_pid != hdsp->capture_pid) &&
Takashi Iwaib0b98112005-10-20 18:29:58 +0200854 (hdsp->playback_pid >= 0) && (hdsp->capture_pid >= 0))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700855 ret = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700856 spin_unlock_irqrestore(&hdsp->lock, flags);
857 return ret;
858}
859
860static int hdsp_external_sample_rate (hdsp_t *hdsp)
861{
862 unsigned int status2 = hdsp_read(hdsp, HDSP_status2Register);
863 unsigned int rate_bits = status2 & HDSP_systemFrequencyMask;
864
865 switch (rate_bits) {
866 case HDSP_systemFrequency32: return 32000;
867 case HDSP_systemFrequency44_1: return 44100;
868 case HDSP_systemFrequency48: return 48000;
869 case HDSP_systemFrequency64: return 64000;
870 case HDSP_systemFrequency88_2: return 88200;
871 case HDSP_systemFrequency96: return 96000;
872 default:
873 return 0;
874 }
875}
876
877static int hdsp_spdif_sample_rate(hdsp_t *hdsp)
878{
879 unsigned int status = hdsp_read(hdsp, HDSP_statusRegister);
880 unsigned int rate_bits = (status & HDSP_spdifFrequencyMask);
881
Takashi Iwaib0b98112005-10-20 18:29:58 +0200882 if (status & HDSP_SPDIFErrorFlag)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700883 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700884
885 switch (rate_bits) {
886 case HDSP_spdifFrequency32KHz: return 32000;
887 case HDSP_spdifFrequency44_1KHz: return 44100;
888 case HDSP_spdifFrequency48KHz: return 48000;
889 case HDSP_spdifFrequency64KHz: return 64000;
890 case HDSP_spdifFrequency88_2KHz: return 88200;
891 case HDSP_spdifFrequency96KHz: return 96000;
892 case HDSP_spdifFrequency128KHz:
893 if (hdsp->io_type == H9632) return 128000;
894 break;
895 case HDSP_spdifFrequency176_4KHz:
896 if (hdsp->io_type == H9632) return 176400;
897 break;
898 case HDSP_spdifFrequency192KHz:
899 if (hdsp->io_type == H9632) return 192000;
900 break;
901 default:
902 break;
903 }
904 snd_printk ("Hammerfall-DSP: unknown spdif frequency status; bits = 0x%x, status = 0x%x\n", rate_bits, status);
905 return 0;
906}
907
908static void hdsp_compute_period_size(hdsp_t *hdsp)
909{
910 hdsp->period_bytes = 1 << ((hdsp_decode_latency(hdsp->control_register) + 8));
911}
912
913static snd_pcm_uframes_t hdsp_hw_pointer(hdsp_t *hdsp)
914{
915 int position;
916
917 position = hdsp_read(hdsp, HDSP_statusRegister);
918
Takashi Iwaib0b98112005-10-20 18:29:58 +0200919 if (!hdsp->precise_ptr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700920 return (position & HDSP_BufferID) ? (hdsp->period_bytes / 4) : 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700921
922 position &= HDSP_BufferPositionMask;
923 position /= 4;
924 position &= (hdsp->period_bytes/2) - 1;
925 return position;
926}
927
928static void hdsp_reset_hw_pointer(hdsp_t *hdsp)
929{
930 hdsp_write (hdsp, HDSP_resetPointer, 0);
931}
932
933static void hdsp_start_audio(hdsp_t *s)
934{
935 s->control_register |= (HDSP_AudioInterruptEnable | HDSP_Start);
936 hdsp_write(s, HDSP_controlRegister, s->control_register);
937}
938
939static void hdsp_stop_audio(hdsp_t *s)
940{
941 s->control_register &= ~(HDSP_Start | HDSP_AudioInterruptEnable);
942 hdsp_write(s, HDSP_controlRegister, s->control_register);
943}
944
945static void hdsp_silence_playback(hdsp_t *hdsp)
946{
947 memset(hdsp->playback_buffer, 0, HDSP_DMA_AREA_BYTES);
948}
949
950static int hdsp_set_interrupt_interval(hdsp_t *s, unsigned int frames)
951{
952 int n;
953
954 spin_lock_irq(&s->lock);
955
956 frames >>= 7;
957 n = 0;
958 while (frames) {
959 n++;
960 frames >>= 1;
961 }
962
963 s->control_register &= ~HDSP_LatencyMask;
964 s->control_register |= hdsp_encode_latency(n);
965
966 hdsp_write(s, HDSP_controlRegister, s->control_register);
967
968 hdsp_compute_period_size(s);
969
970 spin_unlock_irq(&s->lock);
971
972 return 0;
973}
974
975static int hdsp_set_rate(hdsp_t *hdsp, int rate, int called_internally)
976{
977 int reject_if_open = 0;
978 int current_rate;
979 int rate_bits;
980
981 /* ASSUMPTION: hdsp->lock is either held, or
982 there is no need for it (e.g. during module
983 initialization).
984 */
985
986 if (!(hdsp->control_register & HDSP_ClockModeMaster)) {
987 if (called_internally) {
988 /* request from ctl or card initialization */
Takashi Iwaib0b98112005-10-20 18:29:58 +0200989 snd_printk(KERN_ERR "Hammerfall-DSP: device is not running as a clock master: cannot set sample rate.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700990 return -1;
991 } else {
992 /* hw_param request while in AutoSync mode */
993 int external_freq = hdsp_external_sample_rate(hdsp);
994 int spdif_freq = hdsp_spdif_sample_rate(hdsp);
995
Takashi Iwaib0b98112005-10-20 18:29:58 +0200996 if ((spdif_freq == external_freq*2) && (hdsp_autosync_ref(hdsp) >= HDSP_AUTOSYNC_FROM_ADAT1))
997 snd_printk(KERN_INFO "Hammerfall-DSP: Detected ADAT in double speed mode\n");
998 else if (hdsp->io_type == H9632 && (spdif_freq == external_freq*4) && (hdsp_autosync_ref(hdsp) >= HDSP_AUTOSYNC_FROM_ADAT1))
999 snd_printk(KERN_INFO "Hammerfall-DSP: Detected ADAT in quad speed mode\n");
1000 else if (rate != external_freq) {
1001 snd_printk(KERN_INFO "Hammerfall-DSP: No AutoSync source for requested rate\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001002 return -1;
1003 }
1004 }
1005 }
1006
1007 current_rate = hdsp->system_sample_rate;
1008
1009 /* Changing from a "single speed" to a "double speed" rate is
1010 not allowed if any substreams are open. This is because
1011 such a change causes a shift in the location of
1012 the DMA buffers and a reduction in the number of available
1013 buffers.
1014
1015 Note that a similar but essentially insoluble problem
1016 exists for externally-driven rate changes. All we can do
1017 is to flag rate changes in the read/write routines. */
1018
Takashi Iwaib0b98112005-10-20 18:29:58 +02001019 if (rate > 96000 && hdsp->io_type != H9632)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001020 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001021
1022 switch (rate) {
1023 case 32000:
Takashi Iwaib0b98112005-10-20 18:29:58 +02001024 if (current_rate > 48000)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001025 reject_if_open = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001026 rate_bits = HDSP_Frequency32KHz;
1027 break;
1028 case 44100:
Takashi Iwaib0b98112005-10-20 18:29:58 +02001029 if (current_rate > 48000)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001030 reject_if_open = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001031 rate_bits = HDSP_Frequency44_1KHz;
1032 break;
1033 case 48000:
Takashi Iwaib0b98112005-10-20 18:29:58 +02001034 if (current_rate > 48000)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001035 reject_if_open = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001036 rate_bits = HDSP_Frequency48KHz;
1037 break;
1038 case 64000:
Takashi Iwaib0b98112005-10-20 18:29:58 +02001039 if (current_rate <= 48000 || current_rate > 96000)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001040 reject_if_open = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001041 rate_bits = HDSP_Frequency64KHz;
1042 break;
1043 case 88200:
Takashi Iwaib0b98112005-10-20 18:29:58 +02001044 if (current_rate <= 48000 || current_rate > 96000)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001045 reject_if_open = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001046 rate_bits = HDSP_Frequency88_2KHz;
1047 break;
1048 case 96000:
Takashi Iwaib0b98112005-10-20 18:29:58 +02001049 if (current_rate <= 48000 || current_rate > 96000)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001050 reject_if_open = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001051 rate_bits = HDSP_Frequency96KHz;
1052 break;
1053 case 128000:
Takashi Iwaib0b98112005-10-20 18:29:58 +02001054 if (current_rate < 128000)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001055 reject_if_open = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001056 rate_bits = HDSP_Frequency128KHz;
1057 break;
1058 case 176400:
Takashi Iwaib0b98112005-10-20 18:29:58 +02001059 if (current_rate < 128000)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001060 reject_if_open = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001061 rate_bits = HDSP_Frequency176_4KHz;
1062 break;
1063 case 192000:
Takashi Iwaib0b98112005-10-20 18:29:58 +02001064 if (current_rate < 128000)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001065 reject_if_open = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001066 rate_bits = HDSP_Frequency192KHz;
1067 break;
1068 default:
1069 return -EINVAL;
1070 }
1071
1072 if (reject_if_open && (hdsp->capture_pid >= 0 || hdsp->playback_pid >= 0)) {
1073 snd_printk ("Hammerfall-DSP: cannot change speed mode (capture PID = %d, playback PID = %d)\n",
1074 hdsp->capture_pid,
1075 hdsp->playback_pid);
1076 return -EBUSY;
1077 }
1078
1079 hdsp->control_register &= ~HDSP_FrequencyMask;
1080 hdsp->control_register |= rate_bits;
1081 hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
1082
1083 if (rate >= 128000) {
1084 hdsp->channel_map = channel_map_H9632_qs;
1085 } else if (rate > 48000) {
Takashi Iwaib0b98112005-10-20 18:29:58 +02001086 if (hdsp->io_type == H9632)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001087 hdsp->channel_map = channel_map_H9632_ds;
Takashi Iwaib0b98112005-10-20 18:29:58 +02001088 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07001089 hdsp->channel_map = channel_map_ds;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001090 } else {
1091 switch (hdsp->io_type) {
1092 case Multiface:
1093 hdsp->channel_map = channel_map_mf_ss;
1094 break;
1095 case Digiface:
1096 case H9652:
1097 hdsp->channel_map = channel_map_df_ss;
1098 break;
1099 case H9632:
1100 hdsp->channel_map = channel_map_H9632_ss;
1101 break;
1102 default:
1103 /* should never happen */
1104 break;
1105 }
1106 }
1107
1108 hdsp->system_sample_rate = rate;
1109
1110 return 0;
1111}
1112
1113/*----------------------------------------------------------------------------
1114 MIDI
1115 ----------------------------------------------------------------------------*/
1116
1117static unsigned char snd_hdsp_midi_read_byte (hdsp_t *hdsp, int id)
1118{
1119 /* the hardware already does the relevant bit-mask with 0xff */
Takashi Iwaib0b98112005-10-20 18:29:58 +02001120 if (id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001121 return hdsp_read(hdsp, HDSP_midiDataIn1);
Takashi Iwaib0b98112005-10-20 18:29:58 +02001122 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07001123 return hdsp_read(hdsp, HDSP_midiDataIn0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001124}
1125
1126static void snd_hdsp_midi_write_byte (hdsp_t *hdsp, int id, int val)
1127{
1128 /* the hardware already does the relevant bit-mask with 0xff */
Takashi Iwaib0b98112005-10-20 18:29:58 +02001129 if (id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001130 hdsp_write(hdsp, HDSP_midiDataOut1, val);
Takashi Iwaib0b98112005-10-20 18:29:58 +02001131 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07001132 hdsp_write(hdsp, HDSP_midiDataOut0, val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001133}
1134
1135static int snd_hdsp_midi_input_available (hdsp_t *hdsp, int id)
1136{
Takashi Iwaib0b98112005-10-20 18:29:58 +02001137 if (id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001138 return (hdsp_read(hdsp, HDSP_midiStatusIn1) & 0xff);
Takashi Iwaib0b98112005-10-20 18:29:58 +02001139 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07001140 return (hdsp_read(hdsp, HDSP_midiStatusIn0) & 0xff);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001141}
1142
1143static int snd_hdsp_midi_output_possible (hdsp_t *hdsp, int id)
1144{
1145 int fifo_bytes_used;
1146
Takashi Iwaib0b98112005-10-20 18:29:58 +02001147 if (id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001148 fifo_bytes_used = hdsp_read(hdsp, HDSP_midiStatusOut1) & 0xff;
Takashi Iwaib0b98112005-10-20 18:29:58 +02001149 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07001150 fifo_bytes_used = hdsp_read(hdsp, HDSP_midiStatusOut0) & 0xff;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001151
Takashi Iwaib0b98112005-10-20 18:29:58 +02001152 if (fifo_bytes_used < 128)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001153 return 128 - fifo_bytes_used;
Takashi Iwaib0b98112005-10-20 18:29:58 +02001154 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07001155 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001156}
1157
1158static void snd_hdsp_flush_midi_input (hdsp_t *hdsp, int id)
1159{
Takashi Iwaib0b98112005-10-20 18:29:58 +02001160 while (snd_hdsp_midi_input_available (hdsp, id))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001161 snd_hdsp_midi_read_byte (hdsp, id);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001162}
1163
1164static int snd_hdsp_midi_output_write (hdsp_midi_t *hmidi)
1165{
1166 unsigned long flags;
1167 int n_pending;
1168 int to_write;
1169 int i;
1170 unsigned char buf[128];
1171
1172 /* Output is not interrupt driven */
1173
1174 spin_lock_irqsave (&hmidi->lock, flags);
1175 if (hmidi->output) {
1176 if (!snd_rawmidi_transmit_empty (hmidi->output)) {
1177 if ((n_pending = snd_hdsp_midi_output_possible (hmidi->hdsp, hmidi->id)) > 0) {
1178 if (n_pending > (int)sizeof (buf))
1179 n_pending = sizeof (buf);
1180
1181 if ((to_write = snd_rawmidi_transmit (hmidi->output, buf, n_pending)) > 0) {
1182 for (i = 0; i < to_write; ++i)
1183 snd_hdsp_midi_write_byte (hmidi->hdsp, hmidi->id, buf[i]);
1184 }
1185 }
1186 }
1187 }
1188 spin_unlock_irqrestore (&hmidi->lock, flags);
1189 return 0;
1190}
1191
1192static int snd_hdsp_midi_input_read (hdsp_midi_t *hmidi)
1193{
1194 unsigned char buf[128]; /* this buffer is designed to match the MIDI input FIFO size */
1195 unsigned long flags;
1196 int n_pending;
1197 int i;
1198
1199 spin_lock_irqsave (&hmidi->lock, flags);
1200 if ((n_pending = snd_hdsp_midi_input_available (hmidi->hdsp, hmidi->id)) > 0) {
1201 if (hmidi->input) {
Takashi Iwaib0b98112005-10-20 18:29:58 +02001202 if (n_pending > (int)sizeof (buf))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001203 n_pending = sizeof (buf);
Takashi Iwaib0b98112005-10-20 18:29:58 +02001204 for (i = 0; i < n_pending; ++i)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001205 buf[i] = snd_hdsp_midi_read_byte (hmidi->hdsp, hmidi->id);
Takashi Iwaib0b98112005-10-20 18:29:58 +02001206 if (n_pending)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001207 snd_rawmidi_receive (hmidi->input, buf, n_pending);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001208 } else {
1209 /* flush the MIDI input FIFO */
Takashi Iwaib0b98112005-10-20 18:29:58 +02001210 while (--n_pending)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001211 snd_hdsp_midi_read_byte (hmidi->hdsp, hmidi->id);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001212 }
1213 }
1214 hmidi->pending = 0;
Takashi Iwaib0b98112005-10-20 18:29:58 +02001215 if (hmidi->id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001216 hmidi->hdsp->control_register |= HDSP_Midi1InterruptEnable;
Takashi Iwaib0b98112005-10-20 18:29:58 +02001217 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07001218 hmidi->hdsp->control_register |= HDSP_Midi0InterruptEnable;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001219 hdsp_write(hmidi->hdsp, HDSP_controlRegister, hmidi->hdsp->control_register);
1220 spin_unlock_irqrestore (&hmidi->lock, flags);
1221 return snd_hdsp_midi_output_write (hmidi);
1222}
1223
1224static void snd_hdsp_midi_input_trigger(snd_rawmidi_substream_t * substream, int up)
1225{
1226 hdsp_t *hdsp;
1227 hdsp_midi_t *hmidi;
1228 unsigned long flags;
1229 u32 ie;
1230
1231 hmidi = (hdsp_midi_t *) substream->rmidi->private_data;
1232 hdsp = hmidi->hdsp;
1233 ie = hmidi->id ? HDSP_Midi1InterruptEnable : HDSP_Midi0InterruptEnable;
1234 spin_lock_irqsave (&hdsp->lock, flags);
1235 if (up) {
1236 if (!(hdsp->control_register & ie)) {
1237 snd_hdsp_flush_midi_input (hdsp, hmidi->id);
1238 hdsp->control_register |= ie;
1239 }
1240 } else {
1241 hdsp->control_register &= ~ie;
1242 tasklet_kill(&hdsp->midi_tasklet);
1243 }
1244
1245 hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
1246 spin_unlock_irqrestore (&hdsp->lock, flags);
1247}
1248
1249static void snd_hdsp_midi_output_timer(unsigned long data)
1250{
1251 hdsp_midi_t *hmidi = (hdsp_midi_t *) data;
1252 unsigned long flags;
1253
1254 snd_hdsp_midi_output_write(hmidi);
1255 spin_lock_irqsave (&hmidi->lock, flags);
1256
1257 /* this does not bump hmidi->istimer, because the
1258 kernel automatically removed the timer when it
1259 expired, and we are now adding it back, thus
1260 leaving istimer wherever it was set before.
1261 */
1262
1263 if (hmidi->istimer) {
1264 hmidi->timer.expires = 1 + jiffies;
1265 add_timer(&hmidi->timer);
1266 }
1267
1268 spin_unlock_irqrestore (&hmidi->lock, flags);
1269}
1270
1271static void snd_hdsp_midi_output_trigger(snd_rawmidi_substream_t * substream, int up)
1272{
1273 hdsp_midi_t *hmidi;
1274 unsigned long flags;
1275
1276 hmidi = (hdsp_midi_t *) substream->rmidi->private_data;
1277 spin_lock_irqsave (&hmidi->lock, flags);
1278 if (up) {
1279 if (!hmidi->istimer) {
1280 init_timer(&hmidi->timer);
1281 hmidi->timer.function = snd_hdsp_midi_output_timer;
1282 hmidi->timer.data = (unsigned long) hmidi;
1283 hmidi->timer.expires = 1 + jiffies;
1284 add_timer(&hmidi->timer);
1285 hmidi->istimer++;
1286 }
1287 } else {
Takashi Iwaib0b98112005-10-20 18:29:58 +02001288 if (hmidi->istimer && --hmidi->istimer <= 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001289 del_timer (&hmidi->timer);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001290 }
1291 spin_unlock_irqrestore (&hmidi->lock, flags);
1292 if (up)
1293 snd_hdsp_midi_output_write(hmidi);
1294}
1295
1296static int snd_hdsp_midi_input_open(snd_rawmidi_substream_t * substream)
1297{
1298 hdsp_midi_t *hmidi;
1299
1300 hmidi = (hdsp_midi_t *) substream->rmidi->private_data;
1301 spin_lock_irq (&hmidi->lock);
1302 snd_hdsp_flush_midi_input (hmidi->hdsp, hmidi->id);
1303 hmidi->input = substream;
1304 spin_unlock_irq (&hmidi->lock);
1305
1306 return 0;
1307}
1308
1309static int snd_hdsp_midi_output_open(snd_rawmidi_substream_t * substream)
1310{
1311 hdsp_midi_t *hmidi;
1312
1313 hmidi = (hdsp_midi_t *) substream->rmidi->private_data;
1314 spin_lock_irq (&hmidi->lock);
1315 hmidi->output = substream;
1316 spin_unlock_irq (&hmidi->lock);
1317
1318 return 0;
1319}
1320
1321static int snd_hdsp_midi_input_close(snd_rawmidi_substream_t * substream)
1322{
1323 hdsp_midi_t *hmidi;
1324
1325 snd_hdsp_midi_input_trigger (substream, 0);
1326
1327 hmidi = (hdsp_midi_t *) substream->rmidi->private_data;
1328 spin_lock_irq (&hmidi->lock);
1329 hmidi->input = NULL;
1330 spin_unlock_irq (&hmidi->lock);
1331
1332 return 0;
1333}
1334
1335static int snd_hdsp_midi_output_close(snd_rawmidi_substream_t * substream)
1336{
1337 hdsp_midi_t *hmidi;
1338
1339 snd_hdsp_midi_output_trigger (substream, 0);
1340
1341 hmidi = (hdsp_midi_t *) substream->rmidi->private_data;
1342 spin_lock_irq (&hmidi->lock);
1343 hmidi->output = NULL;
1344 spin_unlock_irq (&hmidi->lock);
1345
1346 return 0;
1347}
1348
1349static snd_rawmidi_ops_t snd_hdsp_midi_output =
1350{
1351 .open = snd_hdsp_midi_output_open,
1352 .close = snd_hdsp_midi_output_close,
1353 .trigger = snd_hdsp_midi_output_trigger,
1354};
1355
1356static snd_rawmidi_ops_t snd_hdsp_midi_input =
1357{
1358 .open = snd_hdsp_midi_input_open,
1359 .close = snd_hdsp_midi_input_close,
1360 .trigger = snd_hdsp_midi_input_trigger,
1361};
1362
1363static int __devinit snd_hdsp_create_midi (snd_card_t *card, hdsp_t *hdsp, int id)
1364{
1365 char buf[32];
1366
1367 hdsp->midi[id].id = id;
1368 hdsp->midi[id].rmidi = NULL;
1369 hdsp->midi[id].input = NULL;
1370 hdsp->midi[id].output = NULL;
1371 hdsp->midi[id].hdsp = hdsp;
1372 hdsp->midi[id].istimer = 0;
1373 hdsp->midi[id].pending = 0;
1374 spin_lock_init (&hdsp->midi[id].lock);
1375
1376 sprintf (buf, "%s MIDI %d", card->shortname, id+1);
Takashi Iwaib0b98112005-10-20 18:29:58 +02001377 if (snd_rawmidi_new (card, buf, id, 1, 1, &hdsp->midi[id].rmidi) < 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001378 return -1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001379
1380 sprintf (hdsp->midi[id].rmidi->name, "%s MIDI %d", card->id, id+1);
1381 hdsp->midi[id].rmidi->private_data = &hdsp->midi[id];
1382
1383 snd_rawmidi_set_ops (hdsp->midi[id].rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_hdsp_midi_output);
1384 snd_rawmidi_set_ops (hdsp->midi[id].rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_hdsp_midi_input);
1385
1386 hdsp->midi[id].rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT |
1387 SNDRV_RAWMIDI_INFO_INPUT |
1388 SNDRV_RAWMIDI_INFO_DUPLEX;
1389
1390 return 0;
1391}
1392
1393/*-----------------------------------------------------------------------------
1394 Control Interface
1395 ----------------------------------------------------------------------------*/
1396
1397static u32 snd_hdsp_convert_from_aes(snd_aes_iec958_t *aes)
1398{
1399 u32 val = 0;
1400 val |= (aes->status[0] & IEC958_AES0_PROFESSIONAL) ? HDSP_SPDIFProfessional : 0;
1401 val |= (aes->status[0] & IEC958_AES0_NONAUDIO) ? HDSP_SPDIFNonAudio : 0;
1402 if (val & HDSP_SPDIFProfessional)
1403 val |= (aes->status[0] & IEC958_AES0_PRO_EMPHASIS_5015) ? HDSP_SPDIFEmphasis : 0;
1404 else
1405 val |= (aes->status[0] & IEC958_AES0_CON_EMPHASIS_5015) ? HDSP_SPDIFEmphasis : 0;
1406 return val;
1407}
1408
1409static void snd_hdsp_convert_to_aes(snd_aes_iec958_t *aes, u32 val)
1410{
1411 aes->status[0] = ((val & HDSP_SPDIFProfessional) ? IEC958_AES0_PROFESSIONAL : 0) |
1412 ((val & HDSP_SPDIFNonAudio) ? IEC958_AES0_NONAUDIO : 0);
1413 if (val & HDSP_SPDIFProfessional)
1414 aes->status[0] |= (val & HDSP_SPDIFEmphasis) ? IEC958_AES0_PRO_EMPHASIS_5015 : 0;
1415 else
1416 aes->status[0] |= (val & HDSP_SPDIFEmphasis) ? IEC958_AES0_CON_EMPHASIS_5015 : 0;
1417}
1418
1419static int snd_hdsp_control_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1420{
1421 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
1422 uinfo->count = 1;
1423 return 0;
1424}
1425
1426static int snd_hdsp_control_spdif_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1427{
1428 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
1429
1430 snd_hdsp_convert_to_aes(&ucontrol->value.iec958, hdsp->creg_spdif);
1431 return 0;
1432}
1433
1434static int snd_hdsp_control_spdif_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1435{
1436 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
1437 int change;
1438 u32 val;
1439
1440 val = snd_hdsp_convert_from_aes(&ucontrol->value.iec958);
1441 spin_lock_irq(&hdsp->lock);
1442 change = val != hdsp->creg_spdif;
1443 hdsp->creg_spdif = val;
1444 spin_unlock_irq(&hdsp->lock);
1445 return change;
1446}
1447
1448static int snd_hdsp_control_spdif_stream_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1449{
1450 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
1451 uinfo->count = 1;
1452 return 0;
1453}
1454
1455static int snd_hdsp_control_spdif_stream_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1456{
1457 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
1458
1459 snd_hdsp_convert_to_aes(&ucontrol->value.iec958, hdsp->creg_spdif_stream);
1460 return 0;
1461}
1462
1463static int snd_hdsp_control_spdif_stream_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1464{
1465 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
1466 int change;
1467 u32 val;
1468
1469 val = snd_hdsp_convert_from_aes(&ucontrol->value.iec958);
1470 spin_lock_irq(&hdsp->lock);
1471 change = val != hdsp->creg_spdif_stream;
1472 hdsp->creg_spdif_stream = val;
1473 hdsp->control_register &= ~(HDSP_SPDIFProfessional | HDSP_SPDIFNonAudio | HDSP_SPDIFEmphasis);
1474 hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register |= val);
1475 spin_unlock_irq(&hdsp->lock);
1476 return change;
1477}
1478
1479static int snd_hdsp_control_spdif_mask_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1480{
1481 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
1482 uinfo->count = 1;
1483 return 0;
1484}
1485
1486static int snd_hdsp_control_spdif_mask_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1487{
1488 ucontrol->value.iec958.status[0] = kcontrol->private_value;
1489 return 0;
1490}
1491
1492#define HDSP_SPDIF_IN(xname, xindex) \
Clemens Ladisch67ed4162005-07-29 15:32:58 +02001493{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
Linus Torvalds1da177e2005-04-16 15:20:36 -07001494 .name = xname, \
1495 .index = xindex, \
1496 .info = snd_hdsp_info_spdif_in, \
1497 .get = snd_hdsp_get_spdif_in, \
1498 .put = snd_hdsp_put_spdif_in }
1499
1500static unsigned int hdsp_spdif_in(hdsp_t *hdsp)
1501{
1502 return hdsp_decode_spdif_in(hdsp->control_register & HDSP_SPDIFInputMask);
1503}
1504
1505static int hdsp_set_spdif_input(hdsp_t *hdsp, int in)
1506{
1507 hdsp->control_register &= ~HDSP_SPDIFInputMask;
1508 hdsp->control_register |= hdsp_encode_spdif_in(in);
1509 hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
1510 return 0;
1511}
1512
1513static int snd_hdsp_info_spdif_in(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1514{
1515 static char *texts[4] = {"Optical", "Coaxial", "Internal", "AES"};
1516 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
1517
1518 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1519 uinfo->count = 1;
1520 uinfo->value.enumerated.items = ((hdsp->io_type == H9632) ? 4 : 3);
1521 if (uinfo->value.enumerated.item > ((hdsp->io_type == H9632) ? 3 : 2))
1522 uinfo->value.enumerated.item = ((hdsp->io_type == H9632) ? 3 : 2);
1523 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1524 return 0;
1525}
1526
1527static int snd_hdsp_get_spdif_in(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1528{
1529 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
1530
1531 ucontrol->value.enumerated.item[0] = hdsp_spdif_in(hdsp);
1532 return 0;
1533}
1534
1535static int snd_hdsp_put_spdif_in(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1536{
1537 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
1538 int change;
1539 unsigned int val;
1540
1541 if (!snd_hdsp_use_is_exclusive(hdsp))
1542 return -EBUSY;
1543 val = ucontrol->value.enumerated.item[0] % ((hdsp->io_type == H9632) ? 4 : 3);
1544 spin_lock_irq(&hdsp->lock);
1545 change = val != hdsp_spdif_in(hdsp);
1546 if (change)
1547 hdsp_set_spdif_input(hdsp, val);
1548 spin_unlock_irq(&hdsp->lock);
1549 return change;
1550}
1551
1552#define HDSP_SPDIF_OUT(xname, xindex) \
Clemens Ladisch67ed4162005-07-29 15:32:58 +02001553{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
Linus Torvalds1da177e2005-04-16 15:20:36 -07001554 .info = snd_hdsp_info_spdif_bits, \
1555 .get = snd_hdsp_get_spdif_out, .put = snd_hdsp_put_spdif_out }
1556
1557static int hdsp_spdif_out(hdsp_t *hdsp)
1558{
1559 return (hdsp->control_register & HDSP_SPDIFOpticalOut) ? 1 : 0;
1560}
1561
1562static int hdsp_set_spdif_output(hdsp_t *hdsp, int out)
1563{
Takashi Iwaib0b98112005-10-20 18:29:58 +02001564 if (out)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001565 hdsp->control_register |= HDSP_SPDIFOpticalOut;
Takashi Iwaib0b98112005-10-20 18:29:58 +02001566 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07001567 hdsp->control_register &= ~HDSP_SPDIFOpticalOut;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001568 hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
1569 return 0;
1570}
1571
1572static int snd_hdsp_info_spdif_bits(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1573{
1574 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1575 uinfo->count = 1;
1576 uinfo->value.integer.min = 0;
1577 uinfo->value.integer.max = 1;
1578 return 0;
1579}
1580
1581static int snd_hdsp_get_spdif_out(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1582{
1583 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
1584
1585 ucontrol->value.integer.value[0] = hdsp_spdif_out(hdsp);
1586 return 0;
1587}
1588
1589static int snd_hdsp_put_spdif_out(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1590{
1591 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
1592 int change;
1593 unsigned int val;
1594
1595 if (!snd_hdsp_use_is_exclusive(hdsp))
1596 return -EBUSY;
1597 val = ucontrol->value.integer.value[0] & 1;
1598 spin_lock_irq(&hdsp->lock);
1599 change = (int)val != hdsp_spdif_out(hdsp);
1600 hdsp_set_spdif_output(hdsp, val);
1601 spin_unlock_irq(&hdsp->lock);
1602 return change;
1603}
1604
1605#define HDSP_SPDIF_PROFESSIONAL(xname, xindex) \
Clemens Ladisch67ed4162005-07-29 15:32:58 +02001606{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
Linus Torvalds1da177e2005-04-16 15:20:36 -07001607 .info = snd_hdsp_info_spdif_bits, \
1608 .get = snd_hdsp_get_spdif_professional, .put = snd_hdsp_put_spdif_professional }
1609
1610static int hdsp_spdif_professional(hdsp_t *hdsp)
1611{
1612 return (hdsp->control_register & HDSP_SPDIFProfessional) ? 1 : 0;
1613}
1614
1615static int hdsp_set_spdif_professional(hdsp_t *hdsp, int val)
1616{
Takashi Iwaib0b98112005-10-20 18:29:58 +02001617 if (val)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001618 hdsp->control_register |= HDSP_SPDIFProfessional;
Takashi Iwaib0b98112005-10-20 18:29:58 +02001619 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07001620 hdsp->control_register &= ~HDSP_SPDIFProfessional;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001621 hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
1622 return 0;
1623}
1624
1625static int snd_hdsp_get_spdif_professional(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1626{
1627 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
1628
1629 ucontrol->value.integer.value[0] = hdsp_spdif_professional(hdsp);
1630 return 0;
1631}
1632
1633static int snd_hdsp_put_spdif_professional(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1634{
1635 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
1636 int change;
1637 unsigned int val;
1638
1639 if (!snd_hdsp_use_is_exclusive(hdsp))
1640 return -EBUSY;
1641 val = ucontrol->value.integer.value[0] & 1;
1642 spin_lock_irq(&hdsp->lock);
1643 change = (int)val != hdsp_spdif_professional(hdsp);
1644 hdsp_set_spdif_professional(hdsp, val);
1645 spin_unlock_irq(&hdsp->lock);
1646 return change;
1647}
1648
1649#define HDSP_SPDIF_EMPHASIS(xname, xindex) \
Clemens Ladisch67ed4162005-07-29 15:32:58 +02001650{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
Linus Torvalds1da177e2005-04-16 15:20:36 -07001651 .info = snd_hdsp_info_spdif_bits, \
1652 .get = snd_hdsp_get_spdif_emphasis, .put = snd_hdsp_put_spdif_emphasis }
1653
1654static int hdsp_spdif_emphasis(hdsp_t *hdsp)
1655{
1656 return (hdsp->control_register & HDSP_SPDIFEmphasis) ? 1 : 0;
1657}
1658
1659static int hdsp_set_spdif_emphasis(hdsp_t *hdsp, int val)
1660{
Takashi Iwaib0b98112005-10-20 18:29:58 +02001661 if (val)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001662 hdsp->control_register |= HDSP_SPDIFEmphasis;
Takashi Iwaib0b98112005-10-20 18:29:58 +02001663 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07001664 hdsp->control_register &= ~HDSP_SPDIFEmphasis;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001665 hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
1666 return 0;
1667}
1668
1669static int snd_hdsp_get_spdif_emphasis(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1670{
1671 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
1672
1673 ucontrol->value.integer.value[0] = hdsp_spdif_emphasis(hdsp);
1674 return 0;
1675}
1676
1677static int snd_hdsp_put_spdif_emphasis(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1678{
1679 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
1680 int change;
1681 unsigned int val;
1682
1683 if (!snd_hdsp_use_is_exclusive(hdsp))
1684 return -EBUSY;
1685 val = ucontrol->value.integer.value[0] & 1;
1686 spin_lock_irq(&hdsp->lock);
1687 change = (int)val != hdsp_spdif_emphasis(hdsp);
1688 hdsp_set_spdif_emphasis(hdsp, val);
1689 spin_unlock_irq(&hdsp->lock);
1690 return change;
1691}
1692
1693#define HDSP_SPDIF_NON_AUDIO(xname, xindex) \
Clemens Ladisch67ed4162005-07-29 15:32:58 +02001694{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
Linus Torvalds1da177e2005-04-16 15:20:36 -07001695 .info = snd_hdsp_info_spdif_bits, \
1696 .get = snd_hdsp_get_spdif_nonaudio, .put = snd_hdsp_put_spdif_nonaudio }
1697
1698static int hdsp_spdif_nonaudio(hdsp_t *hdsp)
1699{
1700 return (hdsp->control_register & HDSP_SPDIFNonAudio) ? 1 : 0;
1701}
1702
1703static int hdsp_set_spdif_nonaudio(hdsp_t *hdsp, int val)
1704{
Takashi Iwaib0b98112005-10-20 18:29:58 +02001705 if (val)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001706 hdsp->control_register |= HDSP_SPDIFNonAudio;
Takashi Iwaib0b98112005-10-20 18:29:58 +02001707 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07001708 hdsp->control_register &= ~HDSP_SPDIFNonAudio;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001709 hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
1710 return 0;
1711}
1712
1713static int snd_hdsp_get_spdif_nonaudio(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1714{
1715 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
1716
1717 ucontrol->value.integer.value[0] = hdsp_spdif_nonaudio(hdsp);
1718 return 0;
1719}
1720
1721static int snd_hdsp_put_spdif_nonaudio(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1722{
1723 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
1724 int change;
1725 unsigned int val;
1726
1727 if (!snd_hdsp_use_is_exclusive(hdsp))
1728 return -EBUSY;
1729 val = ucontrol->value.integer.value[0] & 1;
1730 spin_lock_irq(&hdsp->lock);
1731 change = (int)val != hdsp_spdif_nonaudio(hdsp);
1732 hdsp_set_spdif_nonaudio(hdsp, val);
1733 spin_unlock_irq(&hdsp->lock);
1734 return change;
1735}
1736
1737#define HDSP_SPDIF_SAMPLE_RATE(xname, xindex) \
Clemens Ladisch67ed4162005-07-29 15:32:58 +02001738{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
Linus Torvalds1da177e2005-04-16 15:20:36 -07001739 .name = xname, \
1740 .index = xindex, \
1741 .access = SNDRV_CTL_ELEM_ACCESS_READ, \
1742 .info = snd_hdsp_info_spdif_sample_rate, \
1743 .get = snd_hdsp_get_spdif_sample_rate \
1744}
1745
1746static int snd_hdsp_info_spdif_sample_rate(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1747{
1748 static char *texts[] = {"32000", "44100", "48000", "64000", "88200", "96000", "None", "128000", "176400", "192000"};
1749 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
1750
1751 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1752 uinfo->count = 1;
1753 uinfo->value.enumerated.items = (hdsp->io_type == H9632) ? 10 : 7;
1754 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1755 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1756 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1757 return 0;
1758}
1759
1760static int snd_hdsp_get_spdif_sample_rate(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1761{
1762 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
1763
1764 switch (hdsp_spdif_sample_rate(hdsp)) {
1765 case 32000:
1766 ucontrol->value.enumerated.item[0] = 0;
1767 break;
1768 case 44100:
1769 ucontrol->value.enumerated.item[0] = 1;
1770 break;
1771 case 48000:
1772 ucontrol->value.enumerated.item[0] = 2;
1773 break;
1774 case 64000:
1775 ucontrol->value.enumerated.item[0] = 3;
1776 break;
1777 case 88200:
1778 ucontrol->value.enumerated.item[0] = 4;
1779 break;
1780 case 96000:
1781 ucontrol->value.enumerated.item[0] = 5;
1782 break;
1783 case 128000:
1784 ucontrol->value.enumerated.item[0] = 7;
1785 break;
1786 case 176400:
1787 ucontrol->value.enumerated.item[0] = 8;
1788 break;
1789 case 192000:
1790 ucontrol->value.enumerated.item[0] = 9;
1791 break;
1792 default:
1793 ucontrol->value.enumerated.item[0] = 6;
1794 }
1795 return 0;
1796}
1797
1798#define HDSP_SYSTEM_SAMPLE_RATE(xname, xindex) \
Clemens Ladisch67ed4162005-07-29 15:32:58 +02001799{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
Linus Torvalds1da177e2005-04-16 15:20:36 -07001800 .name = xname, \
1801 .index = xindex, \
1802 .access = SNDRV_CTL_ELEM_ACCESS_READ, \
1803 .info = snd_hdsp_info_system_sample_rate, \
1804 .get = snd_hdsp_get_system_sample_rate \
1805}
1806
1807static int snd_hdsp_info_system_sample_rate(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1808{
1809 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1810 uinfo->count = 1;
1811 return 0;
1812}
1813
1814static int snd_hdsp_get_system_sample_rate(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1815{
1816 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
1817
1818 ucontrol->value.enumerated.item[0] = hdsp->system_sample_rate;
1819 return 0;
1820}
1821
1822#define HDSP_AUTOSYNC_SAMPLE_RATE(xname, xindex) \
Clemens Ladisch67ed4162005-07-29 15:32:58 +02001823{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
Linus Torvalds1da177e2005-04-16 15:20:36 -07001824 .name = xname, \
1825 .index = xindex, \
1826 .access = SNDRV_CTL_ELEM_ACCESS_READ, \
1827 .info = snd_hdsp_info_autosync_sample_rate, \
1828 .get = snd_hdsp_get_autosync_sample_rate \
1829}
1830
1831static int snd_hdsp_info_autosync_sample_rate(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1832{
1833 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
1834 static char *texts[] = {"32000", "44100", "48000", "64000", "88200", "96000", "None", "128000", "176400", "192000"};
1835 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1836 uinfo->count = 1;
1837 uinfo->value.enumerated.items = (hdsp->io_type == H9632) ? 10 : 7 ;
1838 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1839 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1840 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1841 return 0;
1842}
1843
1844static int snd_hdsp_get_autosync_sample_rate(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1845{
1846 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
1847
1848 switch (hdsp_external_sample_rate(hdsp)) {
1849 case 32000:
1850 ucontrol->value.enumerated.item[0] = 0;
1851 break;
1852 case 44100:
1853 ucontrol->value.enumerated.item[0] = 1;
1854 break;
1855 case 48000:
1856 ucontrol->value.enumerated.item[0] = 2;
1857 break;
1858 case 64000:
1859 ucontrol->value.enumerated.item[0] = 3;
1860 break;
1861 case 88200:
1862 ucontrol->value.enumerated.item[0] = 4;
1863 break;
1864 case 96000:
1865 ucontrol->value.enumerated.item[0] = 5;
1866 break;
1867 case 128000:
1868 ucontrol->value.enumerated.item[0] = 7;
1869 break;
1870 case 176400:
1871 ucontrol->value.enumerated.item[0] = 8;
1872 break;
1873 case 192000:
1874 ucontrol->value.enumerated.item[0] = 9;
1875 break;
1876 default:
1877 ucontrol->value.enumerated.item[0] = 6;
1878 }
1879 return 0;
1880}
1881
1882#define HDSP_SYSTEM_CLOCK_MODE(xname, xindex) \
Clemens Ladisch67ed4162005-07-29 15:32:58 +02001883{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
Linus Torvalds1da177e2005-04-16 15:20:36 -07001884 .name = xname, \
1885 .index = xindex, \
1886 .access = SNDRV_CTL_ELEM_ACCESS_READ, \
1887 .info = snd_hdsp_info_system_clock_mode, \
1888 .get = snd_hdsp_get_system_clock_mode \
1889}
1890
1891static int hdsp_system_clock_mode(hdsp_t *hdsp)
1892{
Takashi Iwaib0b98112005-10-20 18:29:58 +02001893 if (hdsp->control_register & HDSP_ClockModeMaster)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001894 return 0;
Takashi Iwaib0b98112005-10-20 18:29:58 +02001895 else if (hdsp_external_sample_rate(hdsp) != hdsp->system_sample_rate)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001896 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001897 return 1;
1898}
1899
1900static int snd_hdsp_info_system_clock_mode(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1901{
1902 static char *texts[] = {"Master", "Slave" };
1903
1904 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1905 uinfo->count = 1;
1906 uinfo->value.enumerated.items = 2;
1907 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1908 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1909 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1910 return 0;
1911}
1912
1913static int snd_hdsp_get_system_clock_mode(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1914{
1915 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
1916
1917 ucontrol->value.enumerated.item[0] = hdsp_system_clock_mode(hdsp);
1918 return 0;
1919}
1920
1921#define HDSP_CLOCK_SOURCE(xname, xindex) \
Clemens Ladisch67ed4162005-07-29 15:32:58 +02001922{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
Linus Torvalds1da177e2005-04-16 15:20:36 -07001923 .name = xname, \
1924 .index = xindex, \
1925 .info = snd_hdsp_info_clock_source, \
1926 .get = snd_hdsp_get_clock_source, \
1927 .put = snd_hdsp_put_clock_source \
1928}
1929
1930static int hdsp_clock_source(hdsp_t *hdsp)
1931{
1932 if (hdsp->control_register & HDSP_ClockModeMaster) {
1933 switch (hdsp->system_sample_rate) {
1934 case 32000:
1935 return 1;
1936 case 44100:
1937 return 2;
1938 case 48000:
1939 return 3;
1940 case 64000:
1941 return 4;
1942 case 88200:
1943 return 5;
1944 case 96000:
1945 return 6;
1946 case 128000:
1947 return 7;
1948 case 176400:
1949 return 8;
1950 case 192000:
1951 return 9;
1952 default:
1953 return 3;
1954 }
1955 } else {
1956 return 0;
1957 }
1958}
1959
1960static int hdsp_set_clock_source(hdsp_t *hdsp, int mode)
1961{
1962 int rate;
1963 switch (mode) {
1964 case HDSP_CLOCK_SOURCE_AUTOSYNC:
1965 if (hdsp_external_sample_rate(hdsp) != 0) {
1966 if (!hdsp_set_rate(hdsp, hdsp_external_sample_rate(hdsp), 1)) {
1967 hdsp->control_register &= ~HDSP_ClockModeMaster;
1968 hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
1969 return 0;
1970 }
1971 }
1972 return -1;
1973 case HDSP_CLOCK_SOURCE_INTERNAL_32KHZ:
1974 rate = 32000;
1975 break;
1976 case HDSP_CLOCK_SOURCE_INTERNAL_44_1KHZ:
1977 rate = 44100;
1978 break;
1979 case HDSP_CLOCK_SOURCE_INTERNAL_48KHZ:
1980 rate = 48000;
1981 break;
1982 case HDSP_CLOCK_SOURCE_INTERNAL_64KHZ:
1983 rate = 64000;
1984 break;
1985 case HDSP_CLOCK_SOURCE_INTERNAL_88_2KHZ:
1986 rate = 88200;
1987 break;
1988 case HDSP_CLOCK_SOURCE_INTERNAL_96KHZ:
1989 rate = 96000;
1990 break;
1991 case HDSP_CLOCK_SOURCE_INTERNAL_128KHZ:
1992 rate = 128000;
1993 break;
1994 case HDSP_CLOCK_SOURCE_INTERNAL_176_4KHZ:
1995 rate = 176400;
1996 break;
1997 case HDSP_CLOCK_SOURCE_INTERNAL_192KHZ:
1998 rate = 192000;
1999 break;
2000 default:
2001 rate = 48000;
2002 }
2003 hdsp->control_register |= HDSP_ClockModeMaster;
2004 hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
2005 hdsp_set_rate(hdsp, rate, 1);
2006 return 0;
2007}
2008
2009static int snd_hdsp_info_clock_source(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
2010{
2011 static char *texts[] = {"AutoSync", "Internal 32.0 kHz", "Internal 44.1 kHz", "Internal 48.0 kHz", "Internal 64.0 kHz", "Internal 88.2 kHz", "Internal 96.0 kHz", "Internal 128 kHz", "Internal 176.4 kHz", "Internal 192.0 KHz" };
2012 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
2013
2014 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2015 uinfo->count = 1;
2016 if (hdsp->io_type == H9632)
2017 uinfo->value.enumerated.items = 10;
2018 else
2019 uinfo->value.enumerated.items = 7;
2020 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
2021 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
2022 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2023 return 0;
2024}
2025
2026static int snd_hdsp_get_clock_source(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2027{
2028 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
2029
2030 ucontrol->value.enumerated.item[0] = hdsp_clock_source(hdsp);
2031 return 0;
2032}
2033
2034static int snd_hdsp_put_clock_source(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2035{
2036 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
2037 int change;
2038 int val;
2039
2040 if (!snd_hdsp_use_is_exclusive(hdsp))
2041 return -EBUSY;
2042 val = ucontrol->value.enumerated.item[0];
2043 if (val < 0) val = 0;
2044 if (hdsp->io_type == H9632) {
Takashi Iwaib0b98112005-10-20 18:29:58 +02002045 if (val > 9)
2046 val = 9;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002047 } else {
Takashi Iwaib0b98112005-10-20 18:29:58 +02002048 if (val > 6)
2049 val = 6;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002050 }
2051 spin_lock_irq(&hdsp->lock);
Takashi Iwaib0b98112005-10-20 18:29:58 +02002052 if (val != hdsp_clock_source(hdsp))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002053 change = (hdsp_set_clock_source(hdsp, val) == 0) ? 1 : 0;
Takashi Iwaib0b98112005-10-20 18:29:58 +02002054 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07002055 change = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002056 spin_unlock_irq(&hdsp->lock);
2057 return change;
2058}
2059
Takashi Iwaie3ea4d82005-07-04 18:12:39 +02002060static int snd_hdsp_info_clock_source_lock(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
2061{
2062 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
2063 uinfo->count = 1;
2064 uinfo->value.integer.min = 0;
2065 uinfo->value.integer.max = 1;
2066 return 0;
2067}
2068
2069static int snd_hdsp_get_clock_source_lock(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2070{
2071 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
2072
2073 ucontrol->value.integer.value[0] = hdsp->clock_source_locked;
2074 return 0;
2075}
2076
2077static int snd_hdsp_put_clock_source_lock(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2078{
2079 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
2080 int change;
2081
2082 change = (int)ucontrol->value.integer.value[0] != hdsp->clock_source_locked;
2083 if (change)
2084 hdsp->clock_source_locked = ucontrol->value.integer.value[0];
2085 return change;
2086}
2087
Linus Torvalds1da177e2005-04-16 15:20:36 -07002088#define HDSP_DA_GAIN(xname, xindex) \
Clemens Ladisch67ed4162005-07-29 15:32:58 +02002089{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
Linus Torvalds1da177e2005-04-16 15:20:36 -07002090 .name = xname, \
2091 .index = xindex, \
2092 .info = snd_hdsp_info_da_gain, \
2093 .get = snd_hdsp_get_da_gain, \
2094 .put = snd_hdsp_put_da_gain \
2095}
2096
2097static int hdsp_da_gain(hdsp_t *hdsp)
2098{
2099 switch (hdsp->control_register & HDSP_DAGainMask) {
2100 case HDSP_DAGainHighGain:
2101 return 0;
2102 case HDSP_DAGainPlus4dBu:
2103 return 1;
2104 case HDSP_DAGainMinus10dBV:
2105 return 2;
2106 default:
2107 return 1;
2108 }
2109}
2110
2111static int hdsp_set_da_gain(hdsp_t *hdsp, int mode)
2112{
2113 hdsp->control_register &= ~HDSP_DAGainMask;
2114 switch (mode) {
2115 case 0:
2116 hdsp->control_register |= HDSP_DAGainHighGain;
2117 break;
2118 case 1:
2119 hdsp->control_register |= HDSP_DAGainPlus4dBu;
2120 break;
2121 case 2:
2122 hdsp->control_register |= HDSP_DAGainMinus10dBV;
2123 break;
2124 default:
2125 return -1;
2126
2127 }
2128 hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
2129 return 0;
2130}
2131
2132static int snd_hdsp_info_da_gain(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
2133{
2134 static char *texts[] = {"Hi Gain", "+4 dBu", "-10 dbV"};
2135
2136 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2137 uinfo->count = 1;
2138 uinfo->value.enumerated.items = 3;
2139 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
2140 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
2141 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2142 return 0;
2143}
2144
2145static int snd_hdsp_get_da_gain(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2146{
2147 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
2148
2149 ucontrol->value.enumerated.item[0] = hdsp_da_gain(hdsp);
2150 return 0;
2151}
2152
2153static int snd_hdsp_put_da_gain(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2154{
2155 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
2156 int change;
2157 int val;
2158
2159 if (!snd_hdsp_use_is_exclusive(hdsp))
2160 return -EBUSY;
2161 val = ucontrol->value.enumerated.item[0];
2162 if (val < 0) val = 0;
2163 if (val > 2) val = 2;
2164 spin_lock_irq(&hdsp->lock);
Takashi Iwaib0b98112005-10-20 18:29:58 +02002165 if (val != hdsp_da_gain(hdsp))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002166 change = (hdsp_set_da_gain(hdsp, val) == 0) ? 1 : 0;
Takashi Iwaib0b98112005-10-20 18:29:58 +02002167 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07002168 change = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002169 spin_unlock_irq(&hdsp->lock);
2170 return change;
2171}
2172
2173#define HDSP_AD_GAIN(xname, xindex) \
Clemens Ladisch67ed4162005-07-29 15:32:58 +02002174{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
Linus Torvalds1da177e2005-04-16 15:20:36 -07002175 .name = xname, \
2176 .index = xindex, \
2177 .info = snd_hdsp_info_ad_gain, \
2178 .get = snd_hdsp_get_ad_gain, \
2179 .put = snd_hdsp_put_ad_gain \
2180}
2181
2182static int hdsp_ad_gain(hdsp_t *hdsp)
2183{
2184 switch (hdsp->control_register & HDSP_ADGainMask) {
2185 case HDSP_ADGainMinus10dBV:
2186 return 0;
2187 case HDSP_ADGainPlus4dBu:
2188 return 1;
2189 case HDSP_ADGainLowGain:
2190 return 2;
2191 default:
2192 return 1;
2193 }
2194}
2195
2196static int hdsp_set_ad_gain(hdsp_t *hdsp, int mode)
2197{
2198 hdsp->control_register &= ~HDSP_ADGainMask;
2199 switch (mode) {
2200 case 0:
2201 hdsp->control_register |= HDSP_ADGainMinus10dBV;
2202 break;
2203 case 1:
2204 hdsp->control_register |= HDSP_ADGainPlus4dBu;
2205 break;
2206 case 2:
2207 hdsp->control_register |= HDSP_ADGainLowGain;
2208 break;
2209 default:
2210 return -1;
2211
2212 }
2213 hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
2214 return 0;
2215}
2216
2217static int snd_hdsp_info_ad_gain(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
2218{
2219 static char *texts[] = {"-10 dBV", "+4 dBu", "Lo Gain"};
2220
2221 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2222 uinfo->count = 1;
2223 uinfo->value.enumerated.items = 3;
2224 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
2225 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
2226 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2227 return 0;
2228}
2229
2230static int snd_hdsp_get_ad_gain(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2231{
2232 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
2233
2234 ucontrol->value.enumerated.item[0] = hdsp_ad_gain(hdsp);
2235 return 0;
2236}
2237
2238static int snd_hdsp_put_ad_gain(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2239{
2240 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
2241 int change;
2242 int val;
2243
2244 if (!snd_hdsp_use_is_exclusive(hdsp))
2245 return -EBUSY;
2246 val = ucontrol->value.enumerated.item[0];
2247 if (val < 0) val = 0;
2248 if (val > 2) val = 2;
2249 spin_lock_irq(&hdsp->lock);
Takashi Iwaib0b98112005-10-20 18:29:58 +02002250 if (val != hdsp_ad_gain(hdsp))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002251 change = (hdsp_set_ad_gain(hdsp, val) == 0) ? 1 : 0;
Takashi Iwaib0b98112005-10-20 18:29:58 +02002252 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07002253 change = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002254 spin_unlock_irq(&hdsp->lock);
2255 return change;
2256}
2257
2258#define HDSP_PHONE_GAIN(xname, xindex) \
Clemens Ladisch67ed4162005-07-29 15:32:58 +02002259{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
Linus Torvalds1da177e2005-04-16 15:20:36 -07002260 .name = xname, \
2261 .index = xindex, \
2262 .info = snd_hdsp_info_phone_gain, \
2263 .get = snd_hdsp_get_phone_gain, \
2264 .put = snd_hdsp_put_phone_gain \
2265}
2266
2267static int hdsp_phone_gain(hdsp_t *hdsp)
2268{
2269 switch (hdsp->control_register & HDSP_PhoneGainMask) {
2270 case HDSP_PhoneGain0dB:
2271 return 0;
2272 case HDSP_PhoneGainMinus6dB:
2273 return 1;
2274 case HDSP_PhoneGainMinus12dB:
2275 return 2;
2276 default:
2277 return 0;
2278 }
2279}
2280
2281static int hdsp_set_phone_gain(hdsp_t *hdsp, int mode)
2282{
2283 hdsp->control_register &= ~HDSP_PhoneGainMask;
2284 switch (mode) {
2285 case 0:
2286 hdsp->control_register |= HDSP_PhoneGain0dB;
2287 break;
2288 case 1:
2289 hdsp->control_register |= HDSP_PhoneGainMinus6dB;
2290 break;
2291 case 2:
2292 hdsp->control_register |= HDSP_PhoneGainMinus12dB;
2293 break;
2294 default:
2295 return -1;
2296
2297 }
2298 hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
2299 return 0;
2300}
2301
2302static int snd_hdsp_info_phone_gain(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
2303{
2304 static char *texts[] = {"0 dB", "-6 dB", "-12 dB"};
2305
2306 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2307 uinfo->count = 1;
2308 uinfo->value.enumerated.items = 3;
2309 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
2310 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
2311 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2312 return 0;
2313}
2314
2315static int snd_hdsp_get_phone_gain(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2316{
2317 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
2318
2319 ucontrol->value.enumerated.item[0] = hdsp_phone_gain(hdsp);
2320 return 0;
2321}
2322
2323static int snd_hdsp_put_phone_gain(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2324{
2325 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
2326 int change;
2327 int val;
2328
2329 if (!snd_hdsp_use_is_exclusive(hdsp))
2330 return -EBUSY;
2331 val = ucontrol->value.enumerated.item[0];
2332 if (val < 0) val = 0;
2333 if (val > 2) val = 2;
2334 spin_lock_irq(&hdsp->lock);
Takashi Iwaib0b98112005-10-20 18:29:58 +02002335 if (val != hdsp_phone_gain(hdsp))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002336 change = (hdsp_set_phone_gain(hdsp, val) == 0) ? 1 : 0;
Takashi Iwaib0b98112005-10-20 18:29:58 +02002337 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07002338 change = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002339 spin_unlock_irq(&hdsp->lock);
2340 return change;
2341}
2342
2343#define HDSP_XLR_BREAKOUT_CABLE(xname, xindex) \
Clemens Ladisch67ed4162005-07-29 15:32:58 +02002344{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
Linus Torvalds1da177e2005-04-16 15:20:36 -07002345 .name = xname, \
2346 .index = xindex, \
2347 .info = snd_hdsp_info_xlr_breakout_cable, \
2348 .get = snd_hdsp_get_xlr_breakout_cable, \
2349 .put = snd_hdsp_put_xlr_breakout_cable \
2350}
2351
2352static int hdsp_xlr_breakout_cable(hdsp_t *hdsp)
2353{
Takashi Iwaib0b98112005-10-20 18:29:58 +02002354 if (hdsp->control_register & HDSP_XLRBreakoutCable)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002355 return 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002356 return 0;
2357}
2358
2359static int hdsp_set_xlr_breakout_cable(hdsp_t *hdsp, int mode)
2360{
Takashi Iwaib0b98112005-10-20 18:29:58 +02002361 if (mode)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002362 hdsp->control_register |= HDSP_XLRBreakoutCable;
Takashi Iwaib0b98112005-10-20 18:29:58 +02002363 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07002364 hdsp->control_register &= ~HDSP_XLRBreakoutCable;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002365 hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
2366 return 0;
2367}
2368
2369static int snd_hdsp_info_xlr_breakout_cable(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
2370{
2371 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
2372 uinfo->count = 1;
2373 uinfo->value.integer.min = 0;
2374 uinfo->value.integer.max = 1;
2375 return 0;
2376}
2377
2378static int snd_hdsp_get_xlr_breakout_cable(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2379{
2380 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
2381
2382 ucontrol->value.enumerated.item[0] = hdsp_xlr_breakout_cable(hdsp);
2383 return 0;
2384}
2385
2386static int snd_hdsp_put_xlr_breakout_cable(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2387{
2388 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
2389 int change;
2390 int val;
2391
2392 if (!snd_hdsp_use_is_exclusive(hdsp))
2393 return -EBUSY;
2394 val = ucontrol->value.integer.value[0] & 1;
2395 spin_lock_irq(&hdsp->lock);
2396 change = (int)val != hdsp_xlr_breakout_cable(hdsp);
2397 hdsp_set_xlr_breakout_cable(hdsp, val);
2398 spin_unlock_irq(&hdsp->lock);
2399 return change;
2400}
2401
2402/* (De)activates old RME Analog Extension Board
2403 These are connected to the internal ADAT connector
2404 Switching this on desactivates external ADAT
2405*/
2406#define HDSP_AEB(xname, xindex) \
Clemens Ladisch67ed4162005-07-29 15:32:58 +02002407{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
Linus Torvalds1da177e2005-04-16 15:20:36 -07002408 .name = xname, \
2409 .index = xindex, \
2410 .info = snd_hdsp_info_aeb, \
2411 .get = snd_hdsp_get_aeb, \
2412 .put = snd_hdsp_put_aeb \
2413}
2414
2415static int hdsp_aeb(hdsp_t *hdsp)
2416{
Takashi Iwaib0b98112005-10-20 18:29:58 +02002417 if (hdsp->control_register & HDSP_AnalogExtensionBoard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002418 return 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002419 return 0;
2420}
2421
2422static int hdsp_set_aeb(hdsp_t *hdsp, int mode)
2423{
Takashi Iwaib0b98112005-10-20 18:29:58 +02002424 if (mode)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002425 hdsp->control_register |= HDSP_AnalogExtensionBoard;
Takashi Iwaib0b98112005-10-20 18:29:58 +02002426 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07002427 hdsp->control_register &= ~HDSP_AnalogExtensionBoard;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002428 hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
2429 return 0;
2430}
2431
2432static int snd_hdsp_info_aeb(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
2433{
2434 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
2435 uinfo->count = 1;
2436 uinfo->value.integer.min = 0;
2437 uinfo->value.integer.max = 1;
2438 return 0;
2439}
2440
2441static int snd_hdsp_get_aeb(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2442{
2443 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
2444
2445 ucontrol->value.enumerated.item[0] = hdsp_aeb(hdsp);
2446 return 0;
2447}
2448
2449static int snd_hdsp_put_aeb(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2450{
2451 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
2452 int change;
2453 int val;
2454
2455 if (!snd_hdsp_use_is_exclusive(hdsp))
2456 return -EBUSY;
2457 val = ucontrol->value.integer.value[0] & 1;
2458 spin_lock_irq(&hdsp->lock);
2459 change = (int)val != hdsp_aeb(hdsp);
2460 hdsp_set_aeb(hdsp, val);
2461 spin_unlock_irq(&hdsp->lock);
2462 return change;
2463}
2464
2465#define HDSP_PREF_SYNC_REF(xname, xindex) \
Clemens Ladisch67ed4162005-07-29 15:32:58 +02002466{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
Linus Torvalds1da177e2005-04-16 15:20:36 -07002467 .name = xname, \
2468 .index = xindex, \
2469 .info = snd_hdsp_info_pref_sync_ref, \
2470 .get = snd_hdsp_get_pref_sync_ref, \
2471 .put = snd_hdsp_put_pref_sync_ref \
2472}
2473
2474static int hdsp_pref_sync_ref(hdsp_t *hdsp)
2475{
2476 /* Notice that this looks at the requested sync source,
2477 not the one actually in use.
2478 */
2479
2480 switch (hdsp->control_register & HDSP_SyncRefMask) {
2481 case HDSP_SyncRef_ADAT1:
2482 return HDSP_SYNC_FROM_ADAT1;
2483 case HDSP_SyncRef_ADAT2:
2484 return HDSP_SYNC_FROM_ADAT2;
2485 case HDSP_SyncRef_ADAT3:
2486 return HDSP_SYNC_FROM_ADAT3;
2487 case HDSP_SyncRef_SPDIF:
2488 return HDSP_SYNC_FROM_SPDIF;
2489 case HDSP_SyncRef_WORD:
2490 return HDSP_SYNC_FROM_WORD;
2491 case HDSP_SyncRef_ADAT_SYNC:
2492 return HDSP_SYNC_FROM_ADAT_SYNC;
2493 default:
2494 return HDSP_SYNC_FROM_WORD;
2495 }
2496 return 0;
2497}
2498
2499static int hdsp_set_pref_sync_ref(hdsp_t *hdsp, int pref)
2500{
2501 hdsp->control_register &= ~HDSP_SyncRefMask;
2502 switch (pref) {
2503 case HDSP_SYNC_FROM_ADAT1:
2504 hdsp->control_register &= ~HDSP_SyncRefMask; /* clear SyncRef bits */
2505 break;
2506 case HDSP_SYNC_FROM_ADAT2:
2507 hdsp->control_register |= HDSP_SyncRef_ADAT2;
2508 break;
2509 case HDSP_SYNC_FROM_ADAT3:
2510 hdsp->control_register |= HDSP_SyncRef_ADAT3;
2511 break;
2512 case HDSP_SYNC_FROM_SPDIF:
2513 hdsp->control_register |= HDSP_SyncRef_SPDIF;
2514 break;
2515 case HDSP_SYNC_FROM_WORD:
2516 hdsp->control_register |= HDSP_SyncRef_WORD;
2517 break;
2518 case HDSP_SYNC_FROM_ADAT_SYNC:
2519 hdsp->control_register |= HDSP_SyncRef_ADAT_SYNC;
2520 break;
2521 default:
2522 return -1;
2523 }
2524 hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
2525 return 0;
2526}
2527
2528static int snd_hdsp_info_pref_sync_ref(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
2529{
2530 static char *texts[] = {"Word", "IEC958", "ADAT1", "ADAT Sync", "ADAT2", "ADAT3" };
2531 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
2532
2533 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2534 uinfo->count = 1;
2535
2536 switch (hdsp->io_type) {
2537 case Digiface:
2538 case H9652:
2539 uinfo->value.enumerated.items = 6;
2540 break;
2541 case Multiface:
2542 uinfo->value.enumerated.items = 4;
2543 break;
2544 case H9632:
2545 uinfo->value.enumerated.items = 3;
2546 break;
2547 default:
2548 uinfo->value.enumerated.items = 0;
2549 break;
2550 }
2551
2552 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
2553 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
2554 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2555 return 0;
2556}
2557
2558static int snd_hdsp_get_pref_sync_ref(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2559{
2560 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
2561
2562 ucontrol->value.enumerated.item[0] = hdsp_pref_sync_ref(hdsp);
2563 return 0;
2564}
2565
2566static int snd_hdsp_put_pref_sync_ref(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2567{
2568 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
2569 int change, max;
2570 unsigned int val;
2571
2572 if (!snd_hdsp_use_is_exclusive(hdsp))
2573 return -EBUSY;
2574
2575 switch (hdsp->io_type) {
2576 case Digiface:
2577 case H9652:
2578 max = 6;
2579 break;
2580 case Multiface:
2581 max = 4;
2582 break;
2583 case H9632:
2584 max = 3;
2585 break;
2586 default:
2587 return -EIO;
2588 }
2589
2590 val = ucontrol->value.enumerated.item[0] % max;
2591 spin_lock_irq(&hdsp->lock);
2592 change = (int)val != hdsp_pref_sync_ref(hdsp);
2593 hdsp_set_pref_sync_ref(hdsp, val);
2594 spin_unlock_irq(&hdsp->lock);
2595 return change;
2596}
2597
2598#define HDSP_AUTOSYNC_REF(xname, xindex) \
Clemens Ladisch67ed4162005-07-29 15:32:58 +02002599{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
Linus Torvalds1da177e2005-04-16 15:20:36 -07002600 .name = xname, \
2601 .index = xindex, \
2602 .access = SNDRV_CTL_ELEM_ACCESS_READ, \
2603 .info = snd_hdsp_info_autosync_ref, \
2604 .get = snd_hdsp_get_autosync_ref, \
2605}
2606
2607static int hdsp_autosync_ref(hdsp_t *hdsp)
2608{
2609 /* This looks at the autosync selected sync reference */
2610 unsigned int status2 = hdsp_read(hdsp, HDSP_status2Register);
2611
2612 switch (status2 & HDSP_SelSyncRefMask) {
2613 case HDSP_SelSyncRef_WORD:
2614 return HDSP_AUTOSYNC_FROM_WORD;
2615 case HDSP_SelSyncRef_ADAT_SYNC:
2616 return HDSP_AUTOSYNC_FROM_ADAT_SYNC;
2617 case HDSP_SelSyncRef_SPDIF:
2618 return HDSP_AUTOSYNC_FROM_SPDIF;
2619 case HDSP_SelSyncRefMask:
2620 return HDSP_AUTOSYNC_FROM_NONE;
2621 case HDSP_SelSyncRef_ADAT1:
2622 return HDSP_AUTOSYNC_FROM_ADAT1;
2623 case HDSP_SelSyncRef_ADAT2:
2624 return HDSP_AUTOSYNC_FROM_ADAT2;
2625 case HDSP_SelSyncRef_ADAT3:
2626 return HDSP_AUTOSYNC_FROM_ADAT3;
2627 default:
2628 return HDSP_AUTOSYNC_FROM_WORD;
2629 }
2630 return 0;
2631}
2632
2633static int snd_hdsp_info_autosync_ref(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
2634{
2635 static char *texts[] = {"Word", "ADAT Sync", "IEC958", "None", "ADAT1", "ADAT2", "ADAT3" };
2636
2637 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2638 uinfo->count = 1;
2639 uinfo->value.enumerated.items = 7;
2640 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
2641 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
2642 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2643 return 0;
2644}
2645
2646static int snd_hdsp_get_autosync_ref(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2647{
2648 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
2649
2650 ucontrol->value.enumerated.item[0] = hdsp_autosync_ref(hdsp);
2651 return 0;
2652}
2653
2654#define HDSP_LINE_OUT(xname, xindex) \
Clemens Ladisch67ed4162005-07-29 15:32:58 +02002655{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
Linus Torvalds1da177e2005-04-16 15:20:36 -07002656 .name = xname, \
2657 .index = xindex, \
2658 .info = snd_hdsp_info_line_out, \
2659 .get = snd_hdsp_get_line_out, \
2660 .put = snd_hdsp_put_line_out \
2661}
2662
2663static int hdsp_line_out(hdsp_t *hdsp)
2664{
2665 return (hdsp->control_register & HDSP_LineOut) ? 1 : 0;
2666}
2667
2668static int hdsp_set_line_output(hdsp_t *hdsp, int out)
2669{
Takashi Iwaib0b98112005-10-20 18:29:58 +02002670 if (out)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002671 hdsp->control_register |= HDSP_LineOut;
Takashi Iwaib0b98112005-10-20 18:29:58 +02002672 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07002673 hdsp->control_register &= ~HDSP_LineOut;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002674 hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
2675 return 0;
2676}
2677
2678static int snd_hdsp_info_line_out(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
2679{
2680 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
2681 uinfo->count = 1;
2682 uinfo->value.integer.min = 0;
2683 uinfo->value.integer.max = 1;
2684 return 0;
2685}
2686
2687static int snd_hdsp_get_line_out(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2688{
2689 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
2690
2691 spin_lock_irq(&hdsp->lock);
2692 ucontrol->value.integer.value[0] = hdsp_line_out(hdsp);
2693 spin_unlock_irq(&hdsp->lock);
2694 return 0;
2695}
2696
2697static int snd_hdsp_put_line_out(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2698{
2699 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
2700 int change;
2701 unsigned int val;
2702
2703 if (!snd_hdsp_use_is_exclusive(hdsp))
2704 return -EBUSY;
2705 val = ucontrol->value.integer.value[0] & 1;
2706 spin_lock_irq(&hdsp->lock);
2707 change = (int)val != hdsp_line_out(hdsp);
2708 hdsp_set_line_output(hdsp, val);
2709 spin_unlock_irq(&hdsp->lock);
2710 return change;
2711}
2712
2713#define HDSP_PRECISE_POINTER(xname, xindex) \
Clemens Ladisch67ed4162005-07-29 15:32:58 +02002714{ .iface = SNDRV_CTL_ELEM_IFACE_CARD, \
Linus Torvalds1da177e2005-04-16 15:20:36 -07002715 .name = xname, \
2716 .index = xindex, \
2717 .info = snd_hdsp_info_precise_pointer, \
2718 .get = snd_hdsp_get_precise_pointer, \
2719 .put = snd_hdsp_put_precise_pointer \
2720}
2721
2722static int hdsp_set_precise_pointer(hdsp_t *hdsp, int precise)
2723{
Takashi Iwaib0b98112005-10-20 18:29:58 +02002724 if (precise)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002725 hdsp->precise_ptr = 1;
Takashi Iwaib0b98112005-10-20 18:29:58 +02002726 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07002727 hdsp->precise_ptr = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002728 return 0;
2729}
2730
2731static int snd_hdsp_info_precise_pointer(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
2732{
2733 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
2734 uinfo->count = 1;
2735 uinfo->value.integer.min = 0;
2736 uinfo->value.integer.max = 1;
2737 return 0;
2738}
2739
2740static int snd_hdsp_get_precise_pointer(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2741{
2742 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
2743
2744 spin_lock_irq(&hdsp->lock);
2745 ucontrol->value.integer.value[0] = hdsp->precise_ptr;
2746 spin_unlock_irq(&hdsp->lock);
2747 return 0;
2748}
2749
2750static int snd_hdsp_put_precise_pointer(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2751{
2752 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
2753 int change;
2754 unsigned int val;
2755
2756 if (!snd_hdsp_use_is_exclusive(hdsp))
2757 return -EBUSY;
2758 val = ucontrol->value.integer.value[0] & 1;
2759 spin_lock_irq(&hdsp->lock);
2760 change = (int)val != hdsp->precise_ptr;
2761 hdsp_set_precise_pointer(hdsp, val);
2762 spin_unlock_irq(&hdsp->lock);
2763 return change;
2764}
2765
2766#define HDSP_USE_MIDI_TASKLET(xname, xindex) \
Clemens Ladisch67ed4162005-07-29 15:32:58 +02002767{ .iface = SNDRV_CTL_ELEM_IFACE_CARD, \
Linus Torvalds1da177e2005-04-16 15:20:36 -07002768 .name = xname, \
2769 .index = xindex, \
2770 .info = snd_hdsp_info_use_midi_tasklet, \
2771 .get = snd_hdsp_get_use_midi_tasklet, \
2772 .put = snd_hdsp_put_use_midi_tasklet \
2773}
2774
2775static int hdsp_set_use_midi_tasklet(hdsp_t *hdsp, int use_tasklet)
2776{
Takashi Iwaib0b98112005-10-20 18:29:58 +02002777 if (use_tasklet)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002778 hdsp->use_midi_tasklet = 1;
Takashi Iwaib0b98112005-10-20 18:29:58 +02002779 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07002780 hdsp->use_midi_tasklet = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002781 return 0;
2782}
2783
2784static int snd_hdsp_info_use_midi_tasklet(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
2785{
2786 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
2787 uinfo->count = 1;
2788 uinfo->value.integer.min = 0;
2789 uinfo->value.integer.max = 1;
2790 return 0;
2791}
2792
2793static int snd_hdsp_get_use_midi_tasklet(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2794{
2795 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
2796
2797 spin_lock_irq(&hdsp->lock);
2798 ucontrol->value.integer.value[0] = hdsp->use_midi_tasklet;
2799 spin_unlock_irq(&hdsp->lock);
2800 return 0;
2801}
2802
2803static int snd_hdsp_put_use_midi_tasklet(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2804{
2805 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
2806 int change;
2807 unsigned int val;
2808
2809 if (!snd_hdsp_use_is_exclusive(hdsp))
2810 return -EBUSY;
2811 val = ucontrol->value.integer.value[0] & 1;
2812 spin_lock_irq(&hdsp->lock);
2813 change = (int)val != hdsp->use_midi_tasklet;
2814 hdsp_set_use_midi_tasklet(hdsp, val);
2815 spin_unlock_irq(&hdsp->lock);
2816 return change;
2817}
2818
2819#define HDSP_MIXER(xname, xindex) \
2820{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \
2821 .name = xname, \
2822 .index = xindex, \
Clemens Ladisch67ed4162005-07-29 15:32:58 +02002823 .device = 0, \
Linus Torvalds1da177e2005-04-16 15:20:36 -07002824 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
2825 SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
2826 .info = snd_hdsp_info_mixer, \
2827 .get = snd_hdsp_get_mixer, \
2828 .put = snd_hdsp_put_mixer \
2829}
2830
2831static int snd_hdsp_info_mixer(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
2832{
2833 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2834 uinfo->count = 3;
2835 uinfo->value.integer.min = 0;
2836 uinfo->value.integer.max = 65536;
2837 uinfo->value.integer.step = 1;
2838 return 0;
2839}
2840
2841static int snd_hdsp_get_mixer(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2842{
2843 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
2844 int source;
2845 int destination;
2846 int addr;
2847
2848 source = ucontrol->value.integer.value[0];
2849 destination = ucontrol->value.integer.value[1];
2850
Takashi Iwaib0b98112005-10-20 18:29:58 +02002851 if (source >= hdsp->max_channels)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002852 addr = hdsp_playback_to_output_key(hdsp,source-hdsp->max_channels,destination);
Takashi Iwaib0b98112005-10-20 18:29:58 +02002853 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07002854 addr = hdsp_input_to_output_key(hdsp,source, destination);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002855
2856 spin_lock_irq(&hdsp->lock);
2857 ucontrol->value.integer.value[2] = hdsp_read_gain (hdsp, addr);
2858 spin_unlock_irq(&hdsp->lock);
2859 return 0;
2860}
2861
2862static int snd_hdsp_put_mixer(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2863{
2864 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
2865 int change;
2866 int source;
2867 int destination;
2868 int gain;
2869 int addr;
2870
2871 if (!snd_hdsp_use_is_exclusive(hdsp))
2872 return -EBUSY;
2873
2874 source = ucontrol->value.integer.value[0];
2875 destination = ucontrol->value.integer.value[1];
2876
Takashi Iwaib0b98112005-10-20 18:29:58 +02002877 if (source >= hdsp->max_channels)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002878 addr = hdsp_playback_to_output_key(hdsp,source-hdsp->max_channels, destination);
Takashi Iwaib0b98112005-10-20 18:29:58 +02002879 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07002880 addr = hdsp_input_to_output_key(hdsp,source, destination);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002881
2882 gain = ucontrol->value.integer.value[2];
2883
2884 spin_lock_irq(&hdsp->lock);
2885 change = gain != hdsp_read_gain(hdsp, addr);
2886 if (change)
2887 hdsp_write_gain(hdsp, addr, gain);
2888 spin_unlock_irq(&hdsp->lock);
2889 return change;
2890}
2891
2892#define HDSP_WC_SYNC_CHECK(xname, xindex) \
Clemens Ladisch67ed4162005-07-29 15:32:58 +02002893{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
Linus Torvalds1da177e2005-04-16 15:20:36 -07002894 .name = xname, \
2895 .index = xindex, \
2896 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
2897 .info = snd_hdsp_info_sync_check, \
2898 .get = snd_hdsp_get_wc_sync_check \
2899}
2900
2901static int snd_hdsp_info_sync_check(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
2902{
2903 static char *texts[] = {"No Lock", "Lock", "Sync" };
2904 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2905 uinfo->count = 1;
2906 uinfo->value.enumerated.items = 3;
2907 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
2908 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
2909 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2910 return 0;
2911}
2912
2913static int hdsp_wc_sync_check(hdsp_t *hdsp)
2914{
2915 int status2 = hdsp_read(hdsp, HDSP_status2Register);
2916 if (status2 & HDSP_wc_lock) {
Takashi Iwaib0b98112005-10-20 18:29:58 +02002917 if (status2 & HDSP_wc_sync)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002918 return 2;
Takashi Iwaib0b98112005-10-20 18:29:58 +02002919 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07002920 return 1;
Takashi Iwaib0b98112005-10-20 18:29:58 +02002921 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -07002922 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002923 return 0;
2924}
2925
2926static int snd_hdsp_get_wc_sync_check(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2927{
2928 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
2929
2930 ucontrol->value.enumerated.item[0] = hdsp_wc_sync_check(hdsp);
2931 return 0;
2932}
2933
2934#define HDSP_SPDIF_SYNC_CHECK(xname, xindex) \
Clemens Ladisch67ed4162005-07-29 15:32:58 +02002935{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
Linus Torvalds1da177e2005-04-16 15:20:36 -07002936 .name = xname, \
2937 .index = xindex, \
2938 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
2939 .info = snd_hdsp_info_sync_check, \
2940 .get = snd_hdsp_get_spdif_sync_check \
2941}
2942
2943static int hdsp_spdif_sync_check(hdsp_t *hdsp)
2944{
2945 int status = hdsp_read(hdsp, HDSP_statusRegister);
Takashi Iwaib0b98112005-10-20 18:29:58 +02002946 if (status & HDSP_SPDIFErrorFlag)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002947 return 0;
Takashi Iwaib0b98112005-10-20 18:29:58 +02002948 else {
2949 if (status & HDSP_SPDIFSync)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002950 return 2;
Takashi Iwaib0b98112005-10-20 18:29:58 +02002951 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07002952 return 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002953 }
2954 return 0;
2955}
2956
2957static int snd_hdsp_get_spdif_sync_check(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2958{
2959 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
2960
2961 ucontrol->value.enumerated.item[0] = hdsp_spdif_sync_check(hdsp);
2962 return 0;
2963}
2964
2965#define HDSP_ADATSYNC_SYNC_CHECK(xname, xindex) \
Clemens Ladisch67ed4162005-07-29 15:32:58 +02002966{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
Linus Torvalds1da177e2005-04-16 15:20:36 -07002967 .name = xname, \
2968 .index = xindex, \
2969 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
2970 .info = snd_hdsp_info_sync_check, \
2971 .get = snd_hdsp_get_adatsync_sync_check \
2972}
2973
2974static int hdsp_adatsync_sync_check(hdsp_t *hdsp)
2975{
2976 int status = hdsp_read(hdsp, HDSP_statusRegister);
2977 if (status & HDSP_TimecodeLock) {
Takashi Iwaib0b98112005-10-20 18:29:58 +02002978 if (status & HDSP_TimecodeSync)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002979 return 2;
Takashi Iwaib0b98112005-10-20 18:29:58 +02002980 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07002981 return 1;
Takashi Iwaib0b98112005-10-20 18:29:58 +02002982 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -07002983 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002984}
2985
2986static int snd_hdsp_get_adatsync_sync_check(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2987{
2988 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
2989
2990 ucontrol->value.enumerated.item[0] = hdsp_adatsync_sync_check(hdsp);
2991 return 0;
2992}
2993
2994#define HDSP_ADAT_SYNC_CHECK \
Clemens Ladisch67ed4162005-07-29 15:32:58 +02002995{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
Linus Torvalds1da177e2005-04-16 15:20:36 -07002996 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
2997 .info = snd_hdsp_info_sync_check, \
2998 .get = snd_hdsp_get_adat_sync_check \
2999}
3000
3001static int hdsp_adat_sync_check(hdsp_t *hdsp, int idx)
3002{
3003 int status = hdsp_read(hdsp, HDSP_statusRegister);
3004
3005 if (status & (HDSP_Lock0>>idx)) {
Takashi Iwaib0b98112005-10-20 18:29:58 +02003006 if (status & (HDSP_Sync0>>idx))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003007 return 2;
Takashi Iwaib0b98112005-10-20 18:29:58 +02003008 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07003009 return 1;
Takashi Iwaib0b98112005-10-20 18:29:58 +02003010 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -07003011 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003012}
3013
3014static int snd_hdsp_get_adat_sync_check(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
3015{
3016 int offset;
3017 hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
3018
3019 offset = ucontrol->id.index - 1;
3020 snd_assert(offset >= 0);
3021
3022 switch (hdsp->io_type) {
3023 case Digiface:
3024 case H9652:
3025 if (offset >= 3)
3026 return -EINVAL;
3027 break;
3028 case Multiface:
3029 case H9632:
3030 if (offset >= 1)
3031 return -EINVAL;
3032 break;
3033 default:
3034 return -EIO;
3035 }
3036
3037 ucontrol->value.enumerated.item[0] = hdsp_adat_sync_check(hdsp, offset);
3038 return 0;
3039}
3040
3041static snd_kcontrol_new_t snd_hdsp_9632_controls[] = {
3042HDSP_DA_GAIN("DA Gain", 0),
3043HDSP_AD_GAIN("AD Gain", 0),
3044HDSP_PHONE_GAIN("Phones Gain", 0),
3045HDSP_XLR_BREAKOUT_CABLE("XLR Breakout Cable", 0)
3046};
3047
3048static snd_kcontrol_new_t snd_hdsp_controls[] = {
3049{
Clemens Ladisch5549d542005-08-03 13:50:30 +02003050 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003051 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
3052 .info = snd_hdsp_control_spdif_info,
3053 .get = snd_hdsp_control_spdif_get,
3054 .put = snd_hdsp_control_spdif_put,
3055},
3056{
3057 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
Clemens Ladisch5549d542005-08-03 13:50:30 +02003058 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003059 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM),
3060 .info = snd_hdsp_control_spdif_stream_info,
3061 .get = snd_hdsp_control_spdif_stream_get,
3062 .put = snd_hdsp_control_spdif_stream_put,
3063},
3064{
3065 .access = SNDRV_CTL_ELEM_ACCESS_READ,
Clemens Ladisch5549d542005-08-03 13:50:30 +02003066 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003067 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK),
3068 .info = snd_hdsp_control_spdif_mask_info,
3069 .get = snd_hdsp_control_spdif_mask_get,
3070 .private_value = IEC958_AES0_NONAUDIO |
3071 IEC958_AES0_PROFESSIONAL |
3072 IEC958_AES0_CON_EMPHASIS,
3073},
3074{
3075 .access = SNDRV_CTL_ELEM_ACCESS_READ,
Clemens Ladisch5549d542005-08-03 13:50:30 +02003076 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003077 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PRO_MASK),
3078 .info = snd_hdsp_control_spdif_mask_info,
3079 .get = snd_hdsp_control_spdif_mask_get,
3080 .private_value = IEC958_AES0_NONAUDIO |
3081 IEC958_AES0_PROFESSIONAL |
3082 IEC958_AES0_PRO_EMPHASIS,
3083},
3084HDSP_MIXER("Mixer", 0),
3085HDSP_SPDIF_IN("IEC958 Input Connector", 0),
3086HDSP_SPDIF_OUT("IEC958 Output also on ADAT1", 0),
3087HDSP_SPDIF_PROFESSIONAL("IEC958 Professional Bit", 0),
3088HDSP_SPDIF_EMPHASIS("IEC958 Emphasis Bit", 0),
3089HDSP_SPDIF_NON_AUDIO("IEC958 Non-audio Bit", 0),
3090/* 'Sample Clock Source' complies with the alsa control naming scheme */
3091HDSP_CLOCK_SOURCE("Sample Clock Source", 0),
Takashi Iwaie3ea4d82005-07-04 18:12:39 +02003092{
Takashi Iwaie3ea4d82005-07-04 18:12:39 +02003093 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3094 .name = "Sample Clock Source Locking",
3095 .info = snd_hdsp_info_clock_source_lock,
3096 .get = snd_hdsp_get_clock_source_lock,
3097 .put = snd_hdsp_put_clock_source_lock,
3098},
Linus Torvalds1da177e2005-04-16 15:20:36 -07003099HDSP_SYSTEM_CLOCK_MODE("System Clock Mode", 0),
3100HDSP_PREF_SYNC_REF("Preferred Sync Reference", 0),
3101HDSP_AUTOSYNC_REF("AutoSync Reference", 0),
3102HDSP_SPDIF_SAMPLE_RATE("SPDIF Sample Rate", 0),
3103HDSP_SYSTEM_SAMPLE_RATE("System Sample Rate", 0),
3104/* 'External Rate' complies with the alsa control naming scheme */
3105HDSP_AUTOSYNC_SAMPLE_RATE("External Rate", 0),
3106HDSP_WC_SYNC_CHECK("Word Clock Lock Status", 0),
3107HDSP_SPDIF_SYNC_CHECK("SPDIF Lock Status", 0),
3108HDSP_ADATSYNC_SYNC_CHECK("ADAT Sync Lock Status", 0),
3109HDSP_LINE_OUT("Line Out", 0),
3110HDSP_PRECISE_POINTER("Precise Pointer", 0),
3111HDSP_USE_MIDI_TASKLET("Use Midi Tasklet", 0),
3112};
3113
3114static snd_kcontrol_new_t snd_hdsp_96xx_aeb = HDSP_AEB("Analog Extension Board", 0);
3115static snd_kcontrol_new_t snd_hdsp_adat_sync_check = HDSP_ADAT_SYNC_CHECK;
3116
3117static int snd_hdsp_create_controls(snd_card_t *card, hdsp_t *hdsp)
3118{
3119 unsigned int idx;
3120 int err;
3121 snd_kcontrol_t *kctl;
3122
3123 for (idx = 0; idx < ARRAY_SIZE(snd_hdsp_controls); idx++) {
Takashi Iwaib0b98112005-10-20 18:29:58 +02003124 if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_hdsp_controls[idx], hdsp))) < 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003125 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003126 if (idx == 1) /* IEC958 (S/PDIF) Stream */
3127 hdsp->spdif_ctl = kctl;
3128 }
3129
3130 /* ADAT SyncCheck status */
3131 snd_hdsp_adat_sync_check.name = "ADAT Lock Status";
3132 snd_hdsp_adat_sync_check.index = 1;
Takashi Iwaib0b98112005-10-20 18:29:58 +02003133 if ((err = snd_ctl_add (card, kctl = snd_ctl_new1(&snd_hdsp_adat_sync_check, hdsp))))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003134 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003135 if (hdsp->io_type == Digiface || hdsp->io_type == H9652) {
3136 for (idx = 1; idx < 3; ++idx) {
3137 snd_hdsp_adat_sync_check.index = idx+1;
Takashi Iwaib0b98112005-10-20 18:29:58 +02003138 if ((err = snd_ctl_add (card, kctl = snd_ctl_new1(&snd_hdsp_adat_sync_check, hdsp))))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003139 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003140 }
3141 }
3142
3143 /* DA, AD and Phone gain and XLR breakout cable controls for H9632 cards */
3144 if (hdsp->io_type == H9632) {
3145 for (idx = 0; idx < ARRAY_SIZE(snd_hdsp_9632_controls); idx++) {
Takashi Iwaib0b98112005-10-20 18:29:58 +02003146 if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_hdsp_9632_controls[idx], hdsp))) < 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003147 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003148 }
3149 }
3150
3151 /* AEB control for H96xx card */
3152 if (hdsp->io_type == H9632 || hdsp->io_type == H9652) {
Takashi Iwaib0b98112005-10-20 18:29:58 +02003153 if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_hdsp_96xx_aeb, hdsp))) < 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003154 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003155 }
3156
3157 return 0;
3158}
3159
3160/*------------------------------------------------------------
3161 /proc interface
3162 ------------------------------------------------------------*/
3163
3164static void
3165snd_hdsp_proc_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
3166{
3167 hdsp_t *hdsp = (hdsp_t *) entry->private_data;
3168 unsigned int status;
3169 unsigned int status2;
3170 char *pref_sync_ref;
3171 char *autosync_ref;
3172 char *system_clock_mode;
3173 char *clock_source;
3174 int x;
3175
Takashi Iwaib0b98112005-10-20 18:29:58 +02003176 if (hdsp_check_for_iobox (hdsp))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003177 snd_iprintf(buffer, "No I/O box connected.\nPlease connect one and upload firmware.\n");
3178 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003179
Takashi Iwaib0b98112005-10-20 18:29:58 +02003180 if (hdsp_check_for_firmware(hdsp, 0)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003181 if (hdsp->state & HDSP_FirmwareCached) {
3182 if (snd_hdsp_load_firmware_from_cache(hdsp) != 0) {
3183 snd_iprintf(buffer, "Firmware loading from cache failed, please upload manually.\n");
3184 return;
3185 }
3186 } else {
3187 snd_iprintf(buffer, "No firmware loaded nor cached, please upload firmware.\n");
3188 return;
3189 }
3190 }
3191
3192 status = hdsp_read(hdsp, HDSP_statusRegister);
3193 status2 = hdsp_read(hdsp, HDSP_status2Register);
3194
3195 snd_iprintf(buffer, "%s (Card #%d)\n", hdsp->card_name, hdsp->card->number + 1);
3196 snd_iprintf(buffer, "Buffers: capture %p playback %p\n",
3197 hdsp->capture_buffer, hdsp->playback_buffer);
3198 snd_iprintf(buffer, "IRQ: %d Registers bus: 0x%lx VM: 0x%lx\n",
3199 hdsp->irq, hdsp->port, (unsigned long)hdsp->iobase);
3200 snd_iprintf(buffer, "Control register: 0x%x\n", hdsp->control_register);
3201 snd_iprintf(buffer, "Control2 register: 0x%x\n", hdsp->control2_register);
3202 snd_iprintf(buffer, "Status register: 0x%x\n", status);
3203 snd_iprintf(buffer, "Status2 register: 0x%x\n", status2);
3204 snd_iprintf(buffer, "FIFO status: %d\n", hdsp_read(hdsp, HDSP_fifoStatus) & 0xff);
3205 snd_iprintf(buffer, "MIDI1 Output status: 0x%x\n", hdsp_read(hdsp, HDSP_midiStatusOut0));
3206 snd_iprintf(buffer, "MIDI1 Input status: 0x%x\n", hdsp_read(hdsp, HDSP_midiStatusIn0));
3207 snd_iprintf(buffer, "MIDI2 Output status: 0x%x\n", hdsp_read(hdsp, HDSP_midiStatusOut1));
3208 snd_iprintf(buffer, "MIDI2 Input status: 0x%x\n", hdsp_read(hdsp, HDSP_midiStatusIn1));
3209 snd_iprintf(buffer, "Use Midi Tasklet: %s\n", hdsp->use_midi_tasklet ? "on" : "off");
3210
3211 snd_iprintf(buffer, "\n");
3212
3213 x = 1 << (6 + hdsp_decode_latency(hdsp->control_register & HDSP_LatencyMask));
3214
3215 snd_iprintf(buffer, "Buffer Size (Latency): %d samples (2 periods of %lu bytes)\n", x, (unsigned long) hdsp->period_bytes);
3216 snd_iprintf(buffer, "Hardware pointer (frames): %ld\n", hdsp_hw_pointer(hdsp));
3217 snd_iprintf(buffer, "Precise pointer: %s\n", hdsp->precise_ptr ? "on" : "off");
3218 snd_iprintf(buffer, "Line out: %s\n", (hdsp->control_register & HDSP_LineOut) ? "on" : "off");
3219
3220 snd_iprintf(buffer, "Firmware version: %d\n", (status2&HDSP_version0)|(status2&HDSP_version1)<<1|(status2&HDSP_version2)<<2);
3221
3222 snd_iprintf(buffer, "\n");
3223
3224
3225 switch (hdsp_clock_source(hdsp)) {
3226 case HDSP_CLOCK_SOURCE_AUTOSYNC:
3227 clock_source = "AutoSync";
3228 break;
3229 case HDSP_CLOCK_SOURCE_INTERNAL_32KHZ:
3230 clock_source = "Internal 32 kHz";
3231 break;
3232 case HDSP_CLOCK_SOURCE_INTERNAL_44_1KHZ:
3233 clock_source = "Internal 44.1 kHz";
3234 break;
3235 case HDSP_CLOCK_SOURCE_INTERNAL_48KHZ:
3236 clock_source = "Internal 48 kHz";
3237 break;
3238 case HDSP_CLOCK_SOURCE_INTERNAL_64KHZ:
3239 clock_source = "Internal 64 kHz";
3240 break;
3241 case HDSP_CLOCK_SOURCE_INTERNAL_88_2KHZ:
3242 clock_source = "Internal 88.2 kHz";
3243 break;
3244 case HDSP_CLOCK_SOURCE_INTERNAL_96KHZ:
3245 clock_source = "Internal 96 kHz";
3246 break;
3247 case HDSP_CLOCK_SOURCE_INTERNAL_128KHZ:
3248 clock_source = "Internal 128 kHz";
3249 break;
3250 case HDSP_CLOCK_SOURCE_INTERNAL_176_4KHZ:
3251 clock_source = "Internal 176.4 kHz";
3252 break;
3253 case HDSP_CLOCK_SOURCE_INTERNAL_192KHZ:
3254 clock_source = "Internal 192 kHz";
3255 break;
3256 default:
3257 clock_source = "Error";
3258 }
3259 snd_iprintf (buffer, "Sample Clock Source: %s\n", clock_source);
3260
Takashi Iwaib0b98112005-10-20 18:29:58 +02003261 if (hdsp_system_clock_mode(hdsp))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003262 system_clock_mode = "Slave";
Takashi Iwaib0b98112005-10-20 18:29:58 +02003263 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07003264 system_clock_mode = "Master";
Linus Torvalds1da177e2005-04-16 15:20:36 -07003265
3266 switch (hdsp_pref_sync_ref (hdsp)) {
3267 case HDSP_SYNC_FROM_WORD:
3268 pref_sync_ref = "Word Clock";
3269 break;
3270 case HDSP_SYNC_FROM_ADAT_SYNC:
3271 pref_sync_ref = "ADAT Sync";
3272 break;
3273 case HDSP_SYNC_FROM_SPDIF:
3274 pref_sync_ref = "SPDIF";
3275 break;
3276 case HDSP_SYNC_FROM_ADAT1:
3277 pref_sync_ref = "ADAT1";
3278 break;
3279 case HDSP_SYNC_FROM_ADAT2:
3280 pref_sync_ref = "ADAT2";
3281 break;
3282 case HDSP_SYNC_FROM_ADAT3:
3283 pref_sync_ref = "ADAT3";
3284 break;
3285 default:
3286 pref_sync_ref = "Word Clock";
3287 break;
3288 }
3289 snd_iprintf (buffer, "Preferred Sync Reference: %s\n", pref_sync_ref);
3290
3291 switch (hdsp_autosync_ref (hdsp)) {
3292 case HDSP_AUTOSYNC_FROM_WORD:
3293 autosync_ref = "Word Clock";
3294 break;
3295 case HDSP_AUTOSYNC_FROM_ADAT_SYNC:
3296 autosync_ref = "ADAT Sync";
3297 break;
3298 case HDSP_AUTOSYNC_FROM_SPDIF:
3299 autosync_ref = "SPDIF";
3300 break;
3301 case HDSP_AUTOSYNC_FROM_NONE:
3302 autosync_ref = "None";
3303 break;
3304 case HDSP_AUTOSYNC_FROM_ADAT1:
3305 autosync_ref = "ADAT1";
3306 break;
3307 case HDSP_AUTOSYNC_FROM_ADAT2:
3308 autosync_ref = "ADAT2";
3309 break;
3310 case HDSP_AUTOSYNC_FROM_ADAT3:
3311 autosync_ref = "ADAT3";
3312 break;
3313 default:
3314 autosync_ref = "---";
3315 break;
3316 }
3317 snd_iprintf (buffer, "AutoSync Reference: %s\n", autosync_ref);
3318
3319 snd_iprintf (buffer, "AutoSync Frequency: %d\n", hdsp_external_sample_rate(hdsp));
3320
3321 snd_iprintf (buffer, "System Clock Mode: %s\n", system_clock_mode);
3322
3323 snd_iprintf (buffer, "System Clock Frequency: %d\n", hdsp->system_sample_rate);
Takashi Iwaie3ea4d82005-07-04 18:12:39 +02003324 snd_iprintf (buffer, "System Clock Locked: %s\n", hdsp->clock_source_locked ? "Yes" : "No");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003325
3326 snd_iprintf(buffer, "\n");
3327
3328 switch (hdsp_spdif_in(hdsp)) {
3329 case HDSP_SPDIFIN_OPTICAL:
3330 snd_iprintf(buffer, "IEC958 input: Optical\n");
3331 break;
3332 case HDSP_SPDIFIN_COAXIAL:
3333 snd_iprintf(buffer, "IEC958 input: Coaxial\n");
3334 break;
3335 case HDSP_SPDIFIN_INTERNAL:
3336 snd_iprintf(buffer, "IEC958 input: Internal\n");
3337 break;
3338 case HDSP_SPDIFIN_AES:
3339 snd_iprintf(buffer, "IEC958 input: AES\n");
3340 break;
3341 default:
3342 snd_iprintf(buffer, "IEC958 input: ???\n");
3343 break;
3344 }
3345
Takashi Iwaib0b98112005-10-20 18:29:58 +02003346 if (hdsp->control_register & HDSP_SPDIFOpticalOut)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003347 snd_iprintf(buffer, "IEC958 output: Coaxial & ADAT1\n");
Takashi Iwaib0b98112005-10-20 18:29:58 +02003348 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07003349 snd_iprintf(buffer, "IEC958 output: Coaxial only\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003350
Takashi Iwaib0b98112005-10-20 18:29:58 +02003351 if (hdsp->control_register & HDSP_SPDIFProfessional)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003352 snd_iprintf(buffer, "IEC958 quality: Professional\n");
Takashi Iwaib0b98112005-10-20 18:29:58 +02003353 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07003354 snd_iprintf(buffer, "IEC958 quality: Consumer\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003355
Takashi Iwaib0b98112005-10-20 18:29:58 +02003356 if (hdsp->control_register & HDSP_SPDIFEmphasis)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003357 snd_iprintf(buffer, "IEC958 emphasis: on\n");
Takashi Iwaib0b98112005-10-20 18:29:58 +02003358 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07003359 snd_iprintf(buffer, "IEC958 emphasis: off\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003360
Takashi Iwaib0b98112005-10-20 18:29:58 +02003361 if (hdsp->control_register & HDSP_SPDIFNonAudio)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003362 snd_iprintf(buffer, "IEC958 NonAudio: on\n");
Takashi Iwaib0b98112005-10-20 18:29:58 +02003363 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07003364 snd_iprintf(buffer, "IEC958 NonAudio: off\n");
Takashi Iwaib0b98112005-10-20 18:29:58 +02003365 if ((x = hdsp_spdif_sample_rate (hdsp)) != 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003366 snd_iprintf (buffer, "IEC958 sample rate: %d\n", x);
Takashi Iwaib0b98112005-10-20 18:29:58 +02003367 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07003368 snd_iprintf (buffer, "IEC958 sample rate: Error flag set\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003369
3370 snd_iprintf(buffer, "\n");
3371
3372 /* Sync Check */
3373 x = status & HDSP_Sync0;
Takashi Iwaib0b98112005-10-20 18:29:58 +02003374 if (status & HDSP_Lock0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003375 snd_iprintf(buffer, "ADAT1: %s\n", x ? "Sync" : "Lock");
Takashi Iwaib0b98112005-10-20 18:29:58 +02003376 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07003377 snd_iprintf(buffer, "ADAT1: No Lock\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003378
3379 switch (hdsp->io_type) {
3380 case Digiface:
3381 case H9652:
3382 x = status & HDSP_Sync1;
Takashi Iwaib0b98112005-10-20 18:29:58 +02003383 if (status & HDSP_Lock1)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003384 snd_iprintf(buffer, "ADAT2: %s\n", x ? "Sync" : "Lock");
Takashi Iwaib0b98112005-10-20 18:29:58 +02003385 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07003386 snd_iprintf(buffer, "ADAT2: No Lock\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003387 x = status & HDSP_Sync2;
Takashi Iwaib0b98112005-10-20 18:29:58 +02003388 if (status & HDSP_Lock2)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003389 snd_iprintf(buffer, "ADAT3: %s\n", x ? "Sync" : "Lock");
Takashi Iwaib0b98112005-10-20 18:29:58 +02003390 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07003391 snd_iprintf(buffer, "ADAT3: No Lock\n");
Takashi Iwaib0b98112005-10-20 18:29:58 +02003392 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003393 default:
3394 /* relax */
3395 break;
3396 }
3397
3398 x = status & HDSP_SPDIFSync;
Takashi Iwaib0b98112005-10-20 18:29:58 +02003399 if (status & HDSP_SPDIFErrorFlag)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003400 snd_iprintf (buffer, "SPDIF: No Lock\n");
Takashi Iwaib0b98112005-10-20 18:29:58 +02003401 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07003402 snd_iprintf (buffer, "SPDIF: %s\n", x ? "Sync" : "Lock");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003403
3404 x = status2 & HDSP_wc_sync;
Takashi Iwaib0b98112005-10-20 18:29:58 +02003405 if (status2 & HDSP_wc_lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003406 snd_iprintf (buffer, "Word Clock: %s\n", x ? "Sync" : "Lock");
Takashi Iwaib0b98112005-10-20 18:29:58 +02003407 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07003408 snd_iprintf (buffer, "Word Clock: No Lock\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003409
3410 x = status & HDSP_TimecodeSync;
Takashi Iwaib0b98112005-10-20 18:29:58 +02003411 if (status & HDSP_TimecodeLock)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003412 snd_iprintf(buffer, "ADAT Sync: %s\n", x ? "Sync" : "Lock");
Takashi Iwaib0b98112005-10-20 18:29:58 +02003413 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07003414 snd_iprintf(buffer, "ADAT Sync: No Lock\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003415
3416 snd_iprintf(buffer, "\n");
3417
3418 /* Informations about H9632 specific controls */
3419 if (hdsp->io_type == H9632) {
3420 char *tmp;
3421
3422 switch (hdsp_ad_gain(hdsp)) {
3423 case 0:
3424 tmp = "-10 dBV";
3425 break;
3426 case 1:
3427 tmp = "+4 dBu";
3428 break;
3429 default:
3430 tmp = "Lo Gain";
3431 break;
3432 }
3433 snd_iprintf(buffer, "AD Gain : %s\n", tmp);
3434
3435 switch (hdsp_da_gain(hdsp)) {
3436 case 0:
3437 tmp = "Hi Gain";
3438 break;
3439 case 1:
3440 tmp = "+4 dBu";
3441 break;
3442 default:
3443 tmp = "-10 dBV";
3444 break;
3445 }
3446 snd_iprintf(buffer, "DA Gain : %s\n", tmp);
3447
3448 switch (hdsp_phone_gain(hdsp)) {
3449 case 0:
3450 tmp = "0 dB";
3451 break;
3452 case 1:
3453 tmp = "-6 dB";
3454 break;
3455 default:
3456 tmp = "-12 dB";
3457 break;
3458 }
3459 snd_iprintf(buffer, "Phones Gain : %s\n", tmp);
3460
3461 snd_iprintf(buffer, "XLR Breakout Cable : %s\n", hdsp_xlr_breakout_cable(hdsp) ? "yes" : "no");
3462
Takashi Iwaib0b98112005-10-20 18:29:58 +02003463 if (hdsp->control_register & HDSP_AnalogExtensionBoard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003464 snd_iprintf(buffer, "AEB : on (ADAT1 internal)\n");
Takashi Iwaib0b98112005-10-20 18:29:58 +02003465 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07003466 snd_iprintf(buffer, "AEB : off (ADAT1 external)\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003467 snd_iprintf(buffer, "\n");
3468 }
3469
3470}
3471
3472static void __devinit snd_hdsp_proc_init(hdsp_t *hdsp)
3473{
3474 snd_info_entry_t *entry;
3475
3476 if (! snd_card_proc_new(hdsp->card, "hdsp", &entry))
3477 snd_info_set_text_ops(entry, hdsp, 1024, snd_hdsp_proc_read);
3478}
3479
3480static void snd_hdsp_free_buffers(hdsp_t *hdsp)
3481{
3482 snd_hammerfall_free_buffer(&hdsp->capture_dma_buf, hdsp->pci);
3483 snd_hammerfall_free_buffer(&hdsp->playback_dma_buf, hdsp->pci);
3484}
3485
3486static int __devinit snd_hdsp_initialize_memory(hdsp_t *hdsp)
3487{
3488 unsigned long pb_bus, cb_bus;
3489
3490 if (snd_hammerfall_get_buffer(hdsp->pci, &hdsp->capture_dma_buf, HDSP_DMA_AREA_BYTES) < 0 ||
3491 snd_hammerfall_get_buffer(hdsp->pci, &hdsp->playback_dma_buf, HDSP_DMA_AREA_BYTES) < 0) {
3492 if (hdsp->capture_dma_buf.area)
3493 snd_dma_free_pages(&hdsp->capture_dma_buf);
3494 printk(KERN_ERR "%s: no buffers available\n", hdsp->card_name);
3495 return -ENOMEM;
3496 }
3497
3498 /* Align to bus-space 64K boundary */
3499
3500 cb_bus = (hdsp->capture_dma_buf.addr + 0xFFFF) & ~0xFFFFl;
3501 pb_bus = (hdsp->playback_dma_buf.addr + 0xFFFF) & ~0xFFFFl;
3502
3503 /* Tell the card where it is */
3504
3505 hdsp_write(hdsp, HDSP_inputBufferAddress, cb_bus);
3506 hdsp_write(hdsp, HDSP_outputBufferAddress, pb_bus);
3507
3508 hdsp->capture_buffer = hdsp->capture_dma_buf.area + (cb_bus - hdsp->capture_dma_buf.addr);
3509 hdsp->playback_buffer = hdsp->playback_dma_buf.area + (pb_bus - hdsp->playback_dma_buf.addr);
3510
3511 return 0;
3512}
3513
3514static int snd_hdsp_set_defaults(hdsp_t *hdsp)
3515{
3516 unsigned int i;
3517
3518 /* ASSUMPTION: hdsp->lock is either held, or
3519 there is no need to hold it (e.g. during module
3520 initalization).
3521 */
3522
3523 /* set defaults:
3524
3525 SPDIF Input via Coax
3526 Master clock mode
3527 maximum latency (7 => 2^7 = 8192 samples, 64Kbyte buffer,
3528 which implies 2 4096 sample, 32Kbyte periods).
3529 Enable line out.
3530 */
3531
3532 hdsp->control_register = HDSP_ClockModeMaster |
3533 HDSP_SPDIFInputCoaxial |
3534 hdsp_encode_latency(7) |
3535 HDSP_LineOut;
3536
3537
3538 hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
3539
3540#ifdef SNDRV_BIG_ENDIAN
3541 hdsp->control2_register = HDSP_BIGENDIAN_MODE;
3542#else
3543 hdsp->control2_register = 0;
3544#endif
Takashi Iwaib0b98112005-10-20 18:29:58 +02003545 if (hdsp->io_type == H9652)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003546 snd_hdsp_9652_enable_mixer (hdsp);
Takashi Iwaib0b98112005-10-20 18:29:58 +02003547 else
3548 hdsp_write (hdsp, HDSP_control2Reg, hdsp->control2_register);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003549
3550 hdsp_reset_hw_pointer(hdsp);
3551 hdsp_compute_period_size(hdsp);
3552
3553 /* silence everything */
3554
Takashi Iwaib0b98112005-10-20 18:29:58 +02003555 for (i = 0; i < HDSP_MATRIX_MIXER_SIZE; ++i)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003556 hdsp->mixer_matrix[i] = MINUS_INFINITY_GAIN;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003557
3558 for (i = 0; i < ((hdsp->io_type == H9652 || hdsp->io_type == H9632) ? 1352 : HDSP_MATRIX_MIXER_SIZE); ++i) {
Takashi Iwaib0b98112005-10-20 18:29:58 +02003559 if (hdsp_write_gain (hdsp, i, MINUS_INFINITY_GAIN))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003560 return -EIO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003561 }
3562
3563 /* H9632 specific defaults */
3564 if (hdsp->io_type == H9632) {
3565 hdsp->control_register |= (HDSP_DAGainPlus4dBu | HDSP_ADGainPlus4dBu | HDSP_PhoneGain0dB);
3566 hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
3567 }
3568
3569 /* set a default rate so that the channel map is set up.
3570 */
3571
3572 hdsp_set_rate(hdsp, 48000, 1);
3573
3574 return 0;
3575}
3576
3577static void hdsp_midi_tasklet(unsigned long arg)
3578{
3579 hdsp_t *hdsp = (hdsp_t *)arg;
3580
Takashi Iwaib0b98112005-10-20 18:29:58 +02003581 if (hdsp->midi[0].pending)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003582 snd_hdsp_midi_input_read (&hdsp->midi[0]);
Takashi Iwaib0b98112005-10-20 18:29:58 +02003583 if (hdsp->midi[1].pending)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003584 snd_hdsp_midi_input_read (&hdsp->midi[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003585}
3586
3587static irqreturn_t snd_hdsp_interrupt(int irq, void *dev_id, struct pt_regs *regs)
3588{
3589 hdsp_t *hdsp = (hdsp_t *) dev_id;
3590 unsigned int status;
3591 int audio;
3592 int midi0;
3593 int midi1;
3594 unsigned int midi0status;
3595 unsigned int midi1status;
3596 int schedule = 0;
3597
3598 status = hdsp_read(hdsp, HDSP_statusRegister);
3599
3600 audio = status & HDSP_audioIRQPending;
3601 midi0 = status & HDSP_midi0IRQPending;
3602 midi1 = status & HDSP_midi1IRQPending;
3603
Takashi Iwaib0b98112005-10-20 18:29:58 +02003604 if (!audio && !midi0 && !midi1)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003605 return IRQ_NONE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003606
3607 hdsp_write(hdsp, HDSP_interruptConfirmation, 0);
3608
3609 midi0status = hdsp_read (hdsp, HDSP_midiStatusIn0) & 0xff;
3610 midi1status = hdsp_read (hdsp, HDSP_midiStatusIn1) & 0xff;
3611
3612 if (audio) {
Takashi Iwaib0b98112005-10-20 18:29:58 +02003613 if (hdsp->capture_substream)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003614 snd_pcm_period_elapsed(hdsp->pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003615
Takashi Iwaib0b98112005-10-20 18:29:58 +02003616 if (hdsp->playback_substream)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003617 snd_pcm_period_elapsed(hdsp->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003618 }
3619
3620 if (midi0 && midi0status) {
3621 if (hdsp->use_midi_tasklet) {
3622 /* we disable interrupts for this input until processing is done */
3623 hdsp->control_register &= ~HDSP_Midi0InterruptEnable;
3624 hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
3625 hdsp->midi[0].pending = 1;
3626 schedule = 1;
3627 } else {
3628 snd_hdsp_midi_input_read (&hdsp->midi[0]);
3629 }
3630 }
3631 if (hdsp->io_type != Multiface && hdsp->io_type != H9632 && midi1 && midi1status) {
3632 if (hdsp->use_midi_tasklet) {
3633 /* we disable interrupts for this input until processing is done */
3634 hdsp->control_register &= ~HDSP_Midi1InterruptEnable;
3635 hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
3636 hdsp->midi[1].pending = 1;
3637 schedule = 1;
3638 } else {
3639 snd_hdsp_midi_input_read (&hdsp->midi[1]);
3640 }
3641 }
3642 if (hdsp->use_midi_tasklet && schedule)
3643 tasklet_hi_schedule(&hdsp->midi_tasklet);
3644 return IRQ_HANDLED;
3645}
3646
3647static snd_pcm_uframes_t snd_hdsp_hw_pointer(snd_pcm_substream_t *substream)
3648{
3649 hdsp_t *hdsp = snd_pcm_substream_chip(substream);
3650 return hdsp_hw_pointer(hdsp);
3651}
3652
3653static char *hdsp_channel_buffer_location(hdsp_t *hdsp,
3654 int stream,
3655 int channel)
3656
3657{
3658 int mapped_channel;
3659
3660 snd_assert(channel >= 0 && channel < hdsp->max_channels, return NULL);
3661
Takashi Iwaib0b98112005-10-20 18:29:58 +02003662 if ((mapped_channel = hdsp->channel_map[channel]) < 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003663 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003664
Takashi Iwaib0b98112005-10-20 18:29:58 +02003665 if (stream == SNDRV_PCM_STREAM_CAPTURE)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003666 return hdsp->capture_buffer + (mapped_channel * HDSP_CHANNEL_BUFFER_BYTES);
Takashi Iwaib0b98112005-10-20 18:29:58 +02003667 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07003668 return hdsp->playback_buffer + (mapped_channel * HDSP_CHANNEL_BUFFER_BYTES);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003669}
3670
3671static int snd_hdsp_playback_copy(snd_pcm_substream_t *substream, int channel,
3672 snd_pcm_uframes_t pos, void __user *src, snd_pcm_uframes_t count)
3673{
3674 hdsp_t *hdsp = snd_pcm_substream_chip(substream);
3675 char *channel_buf;
3676
3677 snd_assert(pos + count <= HDSP_CHANNEL_BUFFER_BYTES / 4, return -EINVAL);
3678
3679 channel_buf = hdsp_channel_buffer_location (hdsp, substream->pstr->stream, channel);
3680 snd_assert(channel_buf != NULL, return -EIO);
3681 if (copy_from_user(channel_buf + pos * 4, src, count * 4))
3682 return -EFAULT;
3683 return count;
3684}
3685
3686static int snd_hdsp_capture_copy(snd_pcm_substream_t *substream, int channel,
3687 snd_pcm_uframes_t pos, void __user *dst, snd_pcm_uframes_t count)
3688{
3689 hdsp_t *hdsp = snd_pcm_substream_chip(substream);
3690 char *channel_buf;
3691
3692 snd_assert(pos + count <= HDSP_CHANNEL_BUFFER_BYTES / 4, return -EINVAL);
3693
3694 channel_buf = hdsp_channel_buffer_location (hdsp, substream->pstr->stream, channel);
3695 snd_assert(channel_buf != NULL, return -EIO);
3696 if (copy_to_user(dst, channel_buf + pos * 4, count * 4))
3697 return -EFAULT;
3698 return count;
3699}
3700
3701static int snd_hdsp_hw_silence(snd_pcm_substream_t *substream, int channel,
3702 snd_pcm_uframes_t pos, snd_pcm_uframes_t count)
3703{
3704 hdsp_t *hdsp = snd_pcm_substream_chip(substream);
3705 char *channel_buf;
3706
3707 channel_buf = hdsp_channel_buffer_location (hdsp, substream->pstr->stream, channel);
3708 snd_assert(channel_buf != NULL, return -EIO);
3709 memset(channel_buf + pos * 4, 0, count * 4);
3710 return count;
3711}
3712
3713static int snd_hdsp_reset(snd_pcm_substream_t *substream)
3714{
3715 snd_pcm_runtime_t *runtime = substream->runtime;
3716 hdsp_t *hdsp = snd_pcm_substream_chip(substream);
3717 snd_pcm_substream_t *other;
3718 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
3719 other = hdsp->capture_substream;
3720 else
3721 other = hdsp->playback_substream;
3722 if (hdsp->running)
3723 runtime->status->hw_ptr = hdsp_hw_pointer(hdsp);
3724 else
3725 runtime->status->hw_ptr = 0;
3726 if (other) {
3727 struct list_head *pos;
3728 snd_pcm_substream_t *s;
3729 snd_pcm_runtime_t *oruntime = other->runtime;
3730 snd_pcm_group_for_each(pos, substream) {
3731 s = snd_pcm_group_substream_entry(pos);
3732 if (s == other) {
3733 oruntime->status->hw_ptr = runtime->status->hw_ptr;
3734 break;
3735 }
3736 }
3737 }
3738 return 0;
3739}
3740
3741static int snd_hdsp_hw_params(snd_pcm_substream_t *substream,
3742 snd_pcm_hw_params_t *params)
3743{
3744 hdsp_t *hdsp = snd_pcm_substream_chip(substream);
3745 int err;
3746 pid_t this_pid;
3747 pid_t other_pid;
3748
Takashi Iwaib0b98112005-10-20 18:29:58 +02003749 if (hdsp_check_for_iobox (hdsp))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003750 return -EIO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003751
Takashi Iwaib0b98112005-10-20 18:29:58 +02003752 if (hdsp_check_for_firmware(hdsp, 1))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003753 return -EIO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003754
3755 spin_lock_irq(&hdsp->lock);
3756
3757 if (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK) {
3758 hdsp->control_register &= ~(HDSP_SPDIFProfessional | HDSP_SPDIFNonAudio | HDSP_SPDIFEmphasis);
3759 hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register |= hdsp->creg_spdif_stream);
3760 this_pid = hdsp->playback_pid;
3761 other_pid = hdsp->capture_pid;
3762 } else {
3763 this_pid = hdsp->capture_pid;
3764 other_pid = hdsp->playback_pid;
3765 }
3766
3767 if ((other_pid > 0) && (this_pid != other_pid)) {
3768
3769 /* The other stream is open, and not by the same
3770 task as this one. Make sure that the parameters
3771 that matter are the same.
3772 */
3773
3774 if (params_rate(params) != hdsp->system_sample_rate) {
3775 spin_unlock_irq(&hdsp->lock);
3776 _snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_RATE);
3777 return -EBUSY;
3778 }
3779
3780 if (params_period_size(params) != hdsp->period_bytes / 4) {
3781 spin_unlock_irq(&hdsp->lock);
3782 _snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
3783 return -EBUSY;
3784 }
3785
3786 /* We're fine. */
3787
3788 spin_unlock_irq(&hdsp->lock);
3789 return 0;
3790
3791 } else {
3792 spin_unlock_irq(&hdsp->lock);
3793 }
3794
3795 /* how to make sure that the rate matches an externally-set one ?
3796 */
3797
3798 spin_lock_irq(&hdsp->lock);
Takashi Iwaie3ea4d82005-07-04 18:12:39 +02003799 if (! hdsp->clock_source_locked) {
3800 if ((err = hdsp_set_rate(hdsp, params_rate(params), 0)) < 0) {
3801 spin_unlock_irq(&hdsp->lock);
3802 _snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_RATE);
3803 return err;
3804 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003805 }
Takashi Iwaie3ea4d82005-07-04 18:12:39 +02003806 spin_unlock_irq(&hdsp->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003807
3808 if ((err = hdsp_set_interrupt_interval(hdsp, params_period_size(params))) < 0) {
3809 _snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
3810 return err;
3811 }
3812
3813 return 0;
3814}
3815
3816static int snd_hdsp_channel_info(snd_pcm_substream_t *substream,
3817 snd_pcm_channel_info_t *info)
3818{
3819 hdsp_t *hdsp = snd_pcm_substream_chip(substream);
3820 int mapped_channel;
3821
3822 snd_assert(info->channel < hdsp->max_channels, return -EINVAL);
3823
Takashi Iwaib0b98112005-10-20 18:29:58 +02003824 if ((mapped_channel = hdsp->channel_map[info->channel]) < 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003825 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003826
3827 info->offset = mapped_channel * HDSP_CHANNEL_BUFFER_BYTES;
3828 info->first = 0;
3829 info->step = 32;
3830 return 0;
3831}
3832
3833static int snd_hdsp_ioctl(snd_pcm_substream_t *substream,
3834 unsigned int cmd, void *arg)
3835{
3836 switch (cmd) {
3837 case SNDRV_PCM_IOCTL1_RESET:
Linus Torvalds1da177e2005-04-16 15:20:36 -07003838 return snd_hdsp_reset(substream);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003839 case SNDRV_PCM_IOCTL1_CHANNEL_INFO:
Takashi Iwaib0b98112005-10-20 18:29:58 +02003840 return snd_hdsp_channel_info(substream, arg);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003841 default:
3842 break;
3843 }
3844
3845 return snd_pcm_lib_ioctl(substream, cmd, arg);
3846}
3847
3848static int snd_hdsp_trigger(snd_pcm_substream_t *substream, int cmd)
3849{
3850 hdsp_t *hdsp = snd_pcm_substream_chip(substream);
3851 snd_pcm_substream_t *other;
3852 int running;
3853
Takashi Iwaib0b98112005-10-20 18:29:58 +02003854 if (hdsp_check_for_iobox (hdsp))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003855 return -EIO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003856
Takashi Iwaib0b98112005-10-20 18:29:58 +02003857 if (hdsp_check_for_firmware(hdsp, 1))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003858 return -EIO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003859
3860 spin_lock(&hdsp->lock);
3861 running = hdsp->running;
3862 switch (cmd) {
3863 case SNDRV_PCM_TRIGGER_START:
3864 running |= 1 << substream->stream;
3865 break;
3866 case SNDRV_PCM_TRIGGER_STOP:
3867 running &= ~(1 << substream->stream);
3868 break;
3869 default:
3870 snd_BUG();
3871 spin_unlock(&hdsp->lock);
3872 return -EINVAL;
3873 }
3874 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
3875 other = hdsp->capture_substream;
3876 else
3877 other = hdsp->playback_substream;
3878
3879 if (other) {
3880 struct list_head *pos;
3881 snd_pcm_substream_t *s;
3882 snd_pcm_group_for_each(pos, substream) {
3883 s = snd_pcm_group_substream_entry(pos);
3884 if (s == other) {
3885 snd_pcm_trigger_done(s, substream);
3886 if (cmd == SNDRV_PCM_TRIGGER_START)
3887 running |= 1 << s->stream;
3888 else
3889 running &= ~(1 << s->stream);
3890 goto _ok;
3891 }
3892 }
3893 if (cmd == SNDRV_PCM_TRIGGER_START) {
3894 if (!(running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) &&
3895 substream->stream == SNDRV_PCM_STREAM_CAPTURE)
3896 hdsp_silence_playback(hdsp);
3897 } else {
3898 if (running &&
3899 substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
3900 hdsp_silence_playback(hdsp);
3901 }
3902 } else {
3903 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
3904 hdsp_silence_playback(hdsp);
3905 }
3906 _ok:
3907 snd_pcm_trigger_done(substream, substream);
3908 if (!hdsp->running && running)
3909 hdsp_start_audio(hdsp);
3910 else if (hdsp->running && !running)
3911 hdsp_stop_audio(hdsp);
3912 hdsp->running = running;
3913 spin_unlock(&hdsp->lock);
3914
3915 return 0;
3916}
3917
3918static int snd_hdsp_prepare(snd_pcm_substream_t *substream)
3919{
3920 hdsp_t *hdsp = snd_pcm_substream_chip(substream);
3921 int result = 0;
3922
Takashi Iwaib0b98112005-10-20 18:29:58 +02003923 if (hdsp_check_for_iobox (hdsp))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003924 return -EIO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003925
Takashi Iwaib0b98112005-10-20 18:29:58 +02003926 if (hdsp_check_for_firmware(hdsp, 1))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003927 return -EIO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003928
3929 spin_lock_irq(&hdsp->lock);
3930 if (!hdsp->running)
3931 hdsp_reset_hw_pointer(hdsp);
3932 spin_unlock_irq(&hdsp->lock);
3933 return result;
3934}
3935
3936static snd_pcm_hardware_t snd_hdsp_playback_subinfo =
3937{
3938 .info = (SNDRV_PCM_INFO_MMAP |
3939 SNDRV_PCM_INFO_MMAP_VALID |
3940 SNDRV_PCM_INFO_NONINTERLEAVED |
3941 SNDRV_PCM_INFO_SYNC_START |
3942 SNDRV_PCM_INFO_DOUBLE),
3943#ifdef SNDRV_BIG_ENDIAN
3944 .formats = SNDRV_PCM_FMTBIT_S32_BE,
3945#else
3946 .formats = SNDRV_PCM_FMTBIT_S32_LE,
3947#endif
3948 .rates = (SNDRV_PCM_RATE_32000 |
3949 SNDRV_PCM_RATE_44100 |
3950 SNDRV_PCM_RATE_48000 |
3951 SNDRV_PCM_RATE_64000 |
3952 SNDRV_PCM_RATE_88200 |
3953 SNDRV_PCM_RATE_96000),
3954 .rate_min = 32000,
3955 .rate_max = 96000,
3956 .channels_min = 14,
3957 .channels_max = HDSP_MAX_CHANNELS,
3958 .buffer_bytes_max = HDSP_CHANNEL_BUFFER_BYTES * HDSP_MAX_CHANNELS,
3959 .period_bytes_min = (64 * 4) * 10,
3960 .period_bytes_max = (8192 * 4) * HDSP_MAX_CHANNELS,
3961 .periods_min = 2,
3962 .periods_max = 2,
3963 .fifo_size = 0
3964};
3965
3966static snd_pcm_hardware_t snd_hdsp_capture_subinfo =
3967{
3968 .info = (SNDRV_PCM_INFO_MMAP |
3969 SNDRV_PCM_INFO_MMAP_VALID |
3970 SNDRV_PCM_INFO_NONINTERLEAVED |
3971 SNDRV_PCM_INFO_SYNC_START),
3972#ifdef SNDRV_BIG_ENDIAN
3973 .formats = SNDRV_PCM_FMTBIT_S32_BE,
3974#else
3975 .formats = SNDRV_PCM_FMTBIT_S32_LE,
3976#endif
3977 .rates = (SNDRV_PCM_RATE_32000 |
3978 SNDRV_PCM_RATE_44100 |
3979 SNDRV_PCM_RATE_48000 |
3980 SNDRV_PCM_RATE_64000 |
3981 SNDRV_PCM_RATE_88200 |
3982 SNDRV_PCM_RATE_96000),
3983 .rate_min = 32000,
3984 .rate_max = 96000,
3985 .channels_min = 14,
3986 .channels_max = HDSP_MAX_CHANNELS,
3987 .buffer_bytes_max = HDSP_CHANNEL_BUFFER_BYTES * HDSP_MAX_CHANNELS,
3988 .period_bytes_min = (64 * 4) * 10,
3989 .period_bytes_max = (8192 * 4) * HDSP_MAX_CHANNELS,
3990 .periods_min = 2,
3991 .periods_max = 2,
3992 .fifo_size = 0
3993};
3994
3995static unsigned int hdsp_period_sizes[] = { 64, 128, 256, 512, 1024, 2048, 4096, 8192 };
3996
3997static snd_pcm_hw_constraint_list_t hdsp_hw_constraints_period_sizes = {
3998 .count = ARRAY_SIZE(hdsp_period_sizes),
3999 .list = hdsp_period_sizes,
4000 .mask = 0
4001};
4002
4003static unsigned int hdsp_9632_sample_rates[] = { 32000, 44100, 48000, 64000, 88200, 96000, 128000, 176400, 192000 };
4004
4005static snd_pcm_hw_constraint_list_t hdsp_hw_constraints_9632_sample_rates = {
4006 .count = ARRAY_SIZE(hdsp_9632_sample_rates),
4007 .list = hdsp_9632_sample_rates,
4008 .mask = 0
4009};
4010
4011static int snd_hdsp_hw_rule_in_channels(snd_pcm_hw_params_t *params,
4012 snd_pcm_hw_rule_t *rule)
4013{
4014 hdsp_t *hdsp = rule->private;
4015 snd_interval_t *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
4016 if (hdsp->io_type == H9632) {
4017 unsigned int list[3];
4018 list[0] = hdsp->qs_in_channels;
4019 list[1] = hdsp->ds_in_channels;
4020 list[2] = hdsp->ss_in_channels;
4021 return snd_interval_list(c, 3, list, 0);
4022 } else {
4023 unsigned int list[2];
4024 list[0] = hdsp->ds_in_channels;
4025 list[1] = hdsp->ss_in_channels;
4026 return snd_interval_list(c, 2, list, 0);
4027 }
4028}
4029
4030static int snd_hdsp_hw_rule_out_channels(snd_pcm_hw_params_t *params,
4031 snd_pcm_hw_rule_t *rule)
4032{
4033 unsigned int list[3];
4034 hdsp_t *hdsp = rule->private;
4035 snd_interval_t *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
4036 if (hdsp->io_type == H9632) {
4037 list[0] = hdsp->qs_out_channels;
4038 list[1] = hdsp->ds_out_channels;
4039 list[2] = hdsp->ss_out_channels;
4040 return snd_interval_list(c, 3, list, 0);
4041 } else {
4042 list[0] = hdsp->ds_out_channels;
4043 list[1] = hdsp->ss_out_channels;
4044 }
4045 return snd_interval_list(c, 2, list, 0);
4046}
4047
4048static int snd_hdsp_hw_rule_in_channels_rate(snd_pcm_hw_params_t *params,
4049 snd_pcm_hw_rule_t *rule)
4050{
4051 hdsp_t *hdsp = rule->private;
4052 snd_interval_t *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
4053 snd_interval_t *r = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
4054 if (r->min > 96000 && hdsp->io_type == H9632) {
4055 snd_interval_t t = {
4056 .min = hdsp->qs_in_channels,
4057 .max = hdsp->qs_in_channels,
4058 .integer = 1,
4059 };
4060 return snd_interval_refine(c, &t);
4061 } else if (r->min > 48000 && r->max <= 96000) {
4062 snd_interval_t t = {
4063 .min = hdsp->ds_in_channels,
4064 .max = hdsp->ds_in_channels,
4065 .integer = 1,
4066 };
4067 return snd_interval_refine(c, &t);
4068 } else if (r->max < 64000) {
4069 snd_interval_t t = {
4070 .min = hdsp->ss_in_channels,
4071 .max = hdsp->ss_in_channels,
4072 .integer = 1,
4073 };
4074 return snd_interval_refine(c, &t);
4075 }
4076 return 0;
4077}
4078
4079static int snd_hdsp_hw_rule_out_channels_rate(snd_pcm_hw_params_t *params,
4080 snd_pcm_hw_rule_t *rule)
4081{
4082 hdsp_t *hdsp = rule->private;
4083 snd_interval_t *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
4084 snd_interval_t *r = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
4085 if (r->min > 96000 && hdsp->io_type == H9632) {
4086 snd_interval_t t = {
4087 .min = hdsp->qs_out_channels,
4088 .max = hdsp->qs_out_channels,
4089 .integer = 1,
4090 };
4091 return snd_interval_refine(c, &t);
4092 } else if (r->min > 48000 && r->max <= 96000) {
4093 snd_interval_t t = {
4094 .min = hdsp->ds_out_channels,
4095 .max = hdsp->ds_out_channels,
4096 .integer = 1,
4097 };
4098 return snd_interval_refine(c, &t);
4099 } else if (r->max < 64000) {
4100 snd_interval_t t = {
4101 .min = hdsp->ss_out_channels,
4102 .max = hdsp->ss_out_channels,
4103 .integer = 1,
4104 };
4105 return snd_interval_refine(c, &t);
4106 }
4107 return 0;
4108}
4109
4110static int snd_hdsp_hw_rule_rate_out_channels(snd_pcm_hw_params_t *params,
4111 snd_pcm_hw_rule_t *rule)
4112{
4113 hdsp_t *hdsp = rule->private;
4114 snd_interval_t *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
4115 snd_interval_t *r = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
4116 if (c->min >= hdsp->ss_out_channels) {
4117 snd_interval_t t = {
4118 .min = 32000,
4119 .max = 48000,
4120 .integer = 1,
4121 };
4122 return snd_interval_refine(r, &t);
4123 } else if (c->max <= hdsp->qs_out_channels && hdsp->io_type == H9632) {
4124 snd_interval_t t = {
4125 .min = 128000,
4126 .max = 192000,
4127 .integer = 1,
4128 };
4129 return snd_interval_refine(r, &t);
4130 } else if (c->max <= hdsp->ds_out_channels) {
4131 snd_interval_t t = {
4132 .min = 64000,
4133 .max = 96000,
4134 .integer = 1,
4135 };
4136 return snd_interval_refine(r, &t);
4137 }
4138 return 0;
4139}
4140
4141static int snd_hdsp_hw_rule_rate_in_channels(snd_pcm_hw_params_t *params,
4142 snd_pcm_hw_rule_t *rule)
4143{
4144 hdsp_t *hdsp = rule->private;
4145 snd_interval_t *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
4146 snd_interval_t *r = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
4147 if (c->min >= hdsp->ss_in_channels) {
4148 snd_interval_t t = {
4149 .min = 32000,
4150 .max = 48000,
4151 .integer = 1,
4152 };
4153 return snd_interval_refine(r, &t);
4154 } else if (c->max <= hdsp->qs_in_channels && hdsp->io_type == H9632) {
4155 snd_interval_t t = {
4156 .min = 128000,
4157 .max = 192000,
4158 .integer = 1,
4159 };
4160 return snd_interval_refine(r, &t);
4161 } else if (c->max <= hdsp->ds_in_channels) {
4162 snd_interval_t t = {
4163 .min = 64000,
4164 .max = 96000,
4165 .integer = 1,
4166 };
4167 return snd_interval_refine(r, &t);
4168 }
4169 return 0;
4170}
4171
4172static int snd_hdsp_playback_open(snd_pcm_substream_t *substream)
4173{
4174 hdsp_t *hdsp = snd_pcm_substream_chip(substream);
4175 snd_pcm_runtime_t *runtime = substream->runtime;
4176
Takashi Iwaib0b98112005-10-20 18:29:58 +02004177 if (hdsp_check_for_iobox (hdsp))
Linus Torvalds1da177e2005-04-16 15:20:36 -07004178 return -EIO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004179
Takashi Iwaib0b98112005-10-20 18:29:58 +02004180 if (hdsp_check_for_firmware(hdsp, 1))
Linus Torvalds1da177e2005-04-16 15:20:36 -07004181 return -EIO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004182
4183 spin_lock_irq(&hdsp->lock);
4184
4185 snd_pcm_set_sync(substream);
4186
4187 runtime->hw = snd_hdsp_playback_subinfo;
4188 runtime->dma_area = hdsp->playback_buffer;
4189 runtime->dma_bytes = HDSP_DMA_AREA_BYTES;
4190
4191 hdsp->playback_pid = current->pid;
4192 hdsp->playback_substream = substream;
4193
4194 spin_unlock_irq(&hdsp->lock);
4195
4196 snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
4197 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, &hdsp_hw_constraints_period_sizes);
Takashi Iwaie3ea4d82005-07-04 18:12:39 +02004198 if (hdsp->clock_source_locked) {
4199 runtime->hw.rate_min = runtime->hw.rate_max = hdsp->system_sample_rate;
4200 } else if (hdsp->io_type == H9632) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004201 runtime->hw.rate_max = 192000;
4202 runtime->hw.rates = SNDRV_PCM_RATE_KNOT;
4203 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hdsp_hw_constraints_9632_sample_rates);
4204 }
Takashi Iwaie3ea4d82005-07-04 18:12:39 +02004205 if (hdsp->io_type == H9632) {
4206 runtime->hw.channels_min = hdsp->qs_out_channels;
4207 runtime->hw.channels_max = hdsp->ss_out_channels;
4208 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004209
4210 snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
4211 snd_hdsp_hw_rule_out_channels, hdsp,
4212 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
4213 snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
4214 snd_hdsp_hw_rule_out_channels_rate, hdsp,
4215 SNDRV_PCM_HW_PARAM_RATE, -1);
4216 snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
4217 snd_hdsp_hw_rule_rate_out_channels, hdsp,
4218 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
4219
4220 hdsp->creg_spdif_stream = hdsp->creg_spdif;
4221 hdsp->spdif_ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
4222 snd_ctl_notify(hdsp->card, SNDRV_CTL_EVENT_MASK_VALUE |
4223 SNDRV_CTL_EVENT_MASK_INFO, &hdsp->spdif_ctl->id);
4224 return 0;
4225}
4226
4227static int snd_hdsp_playback_release(snd_pcm_substream_t *substream)
4228{
4229 hdsp_t *hdsp = snd_pcm_substream_chip(substream);
4230
4231 spin_lock_irq(&hdsp->lock);
4232
4233 hdsp->playback_pid = -1;
4234 hdsp->playback_substream = NULL;
4235
4236 spin_unlock_irq(&hdsp->lock);
4237
4238 hdsp->spdif_ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
4239 snd_ctl_notify(hdsp->card, SNDRV_CTL_EVENT_MASK_VALUE |
4240 SNDRV_CTL_EVENT_MASK_INFO, &hdsp->spdif_ctl->id);
4241 return 0;
4242}
4243
4244
4245static int snd_hdsp_capture_open(snd_pcm_substream_t *substream)
4246{
4247 hdsp_t *hdsp = snd_pcm_substream_chip(substream);
4248 snd_pcm_runtime_t *runtime = substream->runtime;
4249
Takashi Iwaib0b98112005-10-20 18:29:58 +02004250 if (hdsp_check_for_iobox (hdsp))
Linus Torvalds1da177e2005-04-16 15:20:36 -07004251 return -EIO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004252
Takashi Iwaib0b98112005-10-20 18:29:58 +02004253 if (hdsp_check_for_firmware(hdsp, 1))
Linus Torvalds1da177e2005-04-16 15:20:36 -07004254 return -EIO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004255
4256 spin_lock_irq(&hdsp->lock);
4257
4258 snd_pcm_set_sync(substream);
4259
4260 runtime->hw = snd_hdsp_capture_subinfo;
4261 runtime->dma_area = hdsp->capture_buffer;
4262 runtime->dma_bytes = HDSP_DMA_AREA_BYTES;
4263
4264 hdsp->capture_pid = current->pid;
4265 hdsp->capture_substream = substream;
4266
4267 spin_unlock_irq(&hdsp->lock);
4268
4269 snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
4270 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, &hdsp_hw_constraints_period_sizes);
4271 if (hdsp->io_type == H9632) {
4272 runtime->hw.channels_min = hdsp->qs_in_channels;
4273 runtime->hw.channels_max = hdsp->ss_in_channels;
4274 runtime->hw.rate_max = 192000;
4275 runtime->hw.rates = SNDRV_PCM_RATE_KNOT;
4276 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hdsp_hw_constraints_9632_sample_rates);
4277 }
4278 snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
4279 snd_hdsp_hw_rule_in_channels, hdsp,
4280 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
4281 snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
4282 snd_hdsp_hw_rule_in_channels_rate, hdsp,
4283 SNDRV_PCM_HW_PARAM_RATE, -1);
4284 snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
4285 snd_hdsp_hw_rule_rate_in_channels, hdsp,
4286 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
4287 return 0;
4288}
4289
4290static int snd_hdsp_capture_release(snd_pcm_substream_t *substream)
4291{
4292 hdsp_t *hdsp = snd_pcm_substream_chip(substream);
4293
4294 spin_lock_irq(&hdsp->lock);
4295
4296 hdsp->capture_pid = -1;
4297 hdsp->capture_substream = NULL;
4298
4299 spin_unlock_irq(&hdsp->lock);
4300 return 0;
4301}
4302
4303static int snd_hdsp_hwdep_dummy_op(snd_hwdep_t *hw, struct file *file)
4304{
4305 /* we have nothing to initialize but the call is required */
4306 return 0;
4307}
4308
4309
4310/* helper functions for copying meter values */
4311static inline int copy_u32_le(void __user *dest, void __iomem *src)
4312{
4313 u32 val = readl(src);
4314 return copy_to_user(dest, &val, 4);
4315}
4316
4317static inline int copy_u64_le(void __user *dest, void __iomem *src_low, void __iomem *src_high)
4318{
4319 u32 rms_low, rms_high;
4320 u64 rms;
4321 rms_low = readl(src_low);
4322 rms_high = readl(src_high);
4323 rms = ((u64)rms_high << 32) | rms_low;
4324 return copy_to_user(dest, &rms, 8);
4325}
4326
4327static inline int copy_u48_le(void __user *dest, void __iomem *src_low, void __iomem *src_high)
4328{
4329 u32 rms_low, rms_high;
4330 u64 rms;
4331 rms_low = readl(src_low) & 0xffffff00;
4332 rms_high = readl(src_high) & 0xffffff00;
4333 rms = ((u64)rms_high << 32) | rms_low;
4334 return copy_to_user(dest, &rms, 8);
4335}
4336
4337static int hdsp_9652_get_peak(hdsp_t *hdsp, hdsp_peak_rms_t __user *peak_rms)
4338{
4339 int doublespeed = 0;
4340 int i, j, channels, ofs;
4341
4342 if (hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DoubleSpeedStatus)
4343 doublespeed = 1;
4344 channels = doublespeed ? 14 : 26;
4345 for (i = 0, j = 0; i < 26; ++i) {
4346 if (doublespeed && (i & 4))
4347 continue;
4348 ofs = HDSP_9652_peakBase - j * 4;
4349 if (copy_u32_le(&peak_rms->input_peaks[i], hdsp->iobase + ofs))
4350 return -EFAULT;
4351 ofs -= channels * 4;
4352 if (copy_u32_le(&peak_rms->playback_peaks[i], hdsp->iobase + ofs))
4353 return -EFAULT;
4354 ofs -= channels * 4;
4355 if (copy_u32_le(&peak_rms->output_peaks[i], hdsp->iobase + ofs))
4356 return -EFAULT;
4357 ofs = HDSP_9652_rmsBase + j * 8;
4358 if (copy_u48_le(&peak_rms->input_rms[i], hdsp->iobase + ofs,
4359 hdsp->iobase + ofs + 4))
4360 return -EFAULT;
4361 ofs += channels * 8;
4362 if (copy_u48_le(&peak_rms->playback_rms[i], hdsp->iobase + ofs,
4363 hdsp->iobase + ofs + 4))
4364 return -EFAULT;
4365 ofs += channels * 8;
4366 if (copy_u48_le(&peak_rms->output_rms[i], hdsp->iobase + ofs,
4367 hdsp->iobase + ofs + 4))
4368 return -EFAULT;
4369 j++;
4370 }
4371 return 0;
4372}
4373
4374static int hdsp_9632_get_peak(hdsp_t *hdsp, hdsp_peak_rms_t __user *peak_rms)
4375{
4376 int i, j;
4377 hdsp_9632_meters_t __iomem *m;
4378 int doublespeed = 0;
4379
4380 if (hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DoubleSpeedStatus)
4381 doublespeed = 1;
4382 m = (hdsp_9632_meters_t __iomem *)(hdsp->iobase+HDSP_9632_metersBase);
4383 for (i = 0, j = 0; i < 16; ++i, ++j) {
4384 if (copy_u32_le(&peak_rms->input_peaks[i], &m->input_peak[j]))
4385 return -EFAULT;
4386 if (copy_u32_le(&peak_rms->playback_peaks[i], &m->playback_peak[j]))
4387 return -EFAULT;
4388 if (copy_u32_le(&peak_rms->output_peaks[i], &m->output_peak[j]))
4389 return -EFAULT;
4390 if (copy_u64_le(&peak_rms->input_rms[i], &m->input_rms_low[j],
4391 &m->input_rms_high[j]))
4392 return -EFAULT;
4393 if (copy_u64_le(&peak_rms->playback_rms[i], &m->playback_rms_low[j],
4394 &m->playback_rms_high[j]))
4395 return -EFAULT;
4396 if (copy_u64_le(&peak_rms->output_rms[i], &m->output_rms_low[j],
4397 &m->output_rms_high[j]))
4398 return -EFAULT;
4399 if (doublespeed && i == 3) i += 4;
4400 }
4401 return 0;
4402}
4403
4404static int hdsp_get_peak(hdsp_t *hdsp, hdsp_peak_rms_t __user *peak_rms)
4405{
4406 int i;
4407
4408 for (i = 0; i < 26; i++) {
4409 if (copy_u32_le(&peak_rms->playback_peaks[i],
4410 hdsp->iobase + HDSP_playbackPeakLevel + i * 4))
4411 return -EFAULT;
4412 if (copy_u32_le(&peak_rms->input_peaks[i],
4413 hdsp->iobase + HDSP_inputPeakLevel + i * 4))
4414 return -EFAULT;
4415 }
4416 for (i = 0; i < 28; i++) {
4417 if (copy_u32_le(&peak_rms->output_peaks[i],
4418 hdsp->iobase + HDSP_outputPeakLevel + i * 4))
4419 return -EFAULT;
4420 }
4421 for (i = 0; i < 26; ++i) {
4422 if (copy_u64_le(&peak_rms->playback_rms[i],
4423 hdsp->iobase + HDSP_playbackRmsLevel + i * 8 + 4,
4424 hdsp->iobase + HDSP_playbackRmsLevel + i * 8))
4425 return -EFAULT;
4426 if (copy_u64_le(&peak_rms->input_rms[i],
4427 hdsp->iobase + HDSP_inputRmsLevel + i * 8 + 4,
4428 hdsp->iobase + HDSP_inputRmsLevel + i * 8))
4429 return -EFAULT;
4430 }
4431 return 0;
4432}
4433
4434static int snd_hdsp_hwdep_ioctl(snd_hwdep_t *hw, struct file *file, unsigned int cmd, unsigned long arg)
4435{
4436 hdsp_t *hdsp = (hdsp_t *)hw->private_data;
4437 void __user *argp = (void __user *)arg;
4438
4439 switch (cmd) {
4440 case SNDRV_HDSP_IOCTL_GET_PEAK_RMS: {
4441 hdsp_peak_rms_t __user *peak_rms = (hdsp_peak_rms_t __user *)arg;
4442
4443 if (!(hdsp->state & HDSP_FirmwareLoaded)) {
4444 snd_printk(KERN_ERR "Hammerfall-DSP: firmware needs to be uploaded to the card.\n");
4445 return -EINVAL;
4446 }
4447
4448 switch (hdsp->io_type) {
4449 case H9652:
4450 return hdsp_9652_get_peak(hdsp, peak_rms);
4451 case H9632:
4452 return hdsp_9632_get_peak(hdsp, peak_rms);
4453 default:
4454 return hdsp_get_peak(hdsp, peak_rms);
4455 }
4456 }
4457 case SNDRV_HDSP_IOCTL_GET_CONFIG_INFO: {
4458 hdsp_config_info_t info;
4459 unsigned long flags;
4460 int i;
4461
4462 if (!(hdsp->state & HDSP_FirmwareLoaded)) {
Takashi Iwaib0b98112005-10-20 18:29:58 +02004463 snd_printk(KERN_ERR "Hammerfall-DSP: Firmware needs to be uploaded to the card.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004464 return -EINVAL;
4465 }
4466 spin_lock_irqsave(&hdsp->lock, flags);
4467 info.pref_sync_ref = (unsigned char)hdsp_pref_sync_ref(hdsp);
4468 info.wordclock_sync_check = (unsigned char)hdsp_wc_sync_check(hdsp);
Takashi Iwaib0b98112005-10-20 18:29:58 +02004469 if (hdsp->io_type != H9632)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004470 info.adatsync_sync_check = (unsigned char)hdsp_adatsync_sync_check(hdsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004471 info.spdif_sync_check = (unsigned char)hdsp_spdif_sync_check(hdsp);
Takashi Iwaib0b98112005-10-20 18:29:58 +02004472 for (i = 0; i < ((hdsp->io_type != Multiface && hdsp->io_type != H9632) ? 3 : 1); ++i)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004473 info.adat_sync_check[i] = (unsigned char)hdsp_adat_sync_check(hdsp, i);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004474 info.spdif_in = (unsigned char)hdsp_spdif_in(hdsp);
4475 info.spdif_out = (unsigned char)hdsp_spdif_out(hdsp);
4476 info.spdif_professional = (unsigned char)hdsp_spdif_professional(hdsp);
4477 info.spdif_emphasis = (unsigned char)hdsp_spdif_emphasis(hdsp);
4478 info.spdif_nonaudio = (unsigned char)hdsp_spdif_nonaudio(hdsp);
4479 info.spdif_sample_rate = hdsp_spdif_sample_rate(hdsp);
4480 info.system_sample_rate = hdsp->system_sample_rate;
4481 info.autosync_sample_rate = hdsp_external_sample_rate(hdsp);
4482 info.system_clock_mode = (unsigned char)hdsp_system_clock_mode(hdsp);
4483 info.clock_source = (unsigned char)hdsp_clock_source(hdsp);
4484 info.autosync_ref = (unsigned char)hdsp_autosync_ref(hdsp);
4485 info.line_out = (unsigned char)hdsp_line_out(hdsp);
4486 if (hdsp->io_type == H9632) {
4487 info.da_gain = (unsigned char)hdsp_da_gain(hdsp);
4488 info.ad_gain = (unsigned char)hdsp_ad_gain(hdsp);
4489 info.phone_gain = (unsigned char)hdsp_phone_gain(hdsp);
4490 info.xlr_breakout_cable = (unsigned char)hdsp_xlr_breakout_cable(hdsp);
4491
4492 }
Takashi Iwaib0b98112005-10-20 18:29:58 +02004493 if (hdsp->io_type == H9632 || hdsp->io_type == H9652)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004494 info.analog_extension_board = (unsigned char)hdsp_aeb(hdsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004495 spin_unlock_irqrestore(&hdsp->lock, flags);
4496 if (copy_to_user(argp, &info, sizeof(info)))
4497 return -EFAULT;
4498 break;
4499 }
4500 case SNDRV_HDSP_IOCTL_GET_9632_AEB: {
4501 hdsp_9632_aeb_t h9632_aeb;
4502
4503 if (hdsp->io_type != H9632) return -EINVAL;
4504 h9632_aeb.aebi = hdsp->ss_in_channels - H9632_SS_CHANNELS;
4505 h9632_aeb.aebo = hdsp->ss_out_channels - H9632_SS_CHANNELS;
4506 if (copy_to_user(argp, &h9632_aeb, sizeof(h9632_aeb)))
4507 return -EFAULT;
4508 break;
4509 }
4510 case SNDRV_HDSP_IOCTL_GET_VERSION: {
4511 hdsp_version_t hdsp_version;
4512 int err;
4513
4514 if (hdsp->io_type == H9652 || hdsp->io_type == H9632) return -EINVAL;
4515 if (hdsp->io_type == Undefined) {
Takashi Iwaib0b98112005-10-20 18:29:58 +02004516 if ((err = hdsp_get_iobox_version(hdsp)) < 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004517 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004518 }
4519 hdsp_version.io_type = hdsp->io_type;
4520 hdsp_version.firmware_rev = hdsp->firmware_rev;
Takashi Iwaib0b98112005-10-20 18:29:58 +02004521 if ((err = copy_to_user(argp, &hdsp_version, sizeof(hdsp_version))))
Linus Torvalds1da177e2005-04-16 15:20:36 -07004522 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004523 break;
4524 }
4525 case SNDRV_HDSP_IOCTL_UPLOAD_FIRMWARE: {
4526 hdsp_firmware_t __user *firmware;
4527 u32 __user *firmware_data;
4528 int err;
4529
4530 if (hdsp->io_type == H9652 || hdsp->io_type == H9632) return -EINVAL;
4531 /* SNDRV_HDSP_IOCTL_GET_VERSION must have been called */
4532 if (hdsp->io_type == Undefined) return -EINVAL;
4533
4534 if (hdsp->state & (HDSP_FirmwareCached | HDSP_FirmwareLoaded))
4535 return -EBUSY;
4536
Takashi Iwaib0b98112005-10-20 18:29:58 +02004537 snd_printk(KERN_INFO "Hammerfall-DSP: initializing firmware upload\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004538 firmware = (hdsp_firmware_t __user *)argp;
4539
Takashi Iwaib0b98112005-10-20 18:29:58 +02004540 if (get_user(firmware_data, &firmware->firmware_data))
Linus Torvalds1da177e2005-04-16 15:20:36 -07004541 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004542
Takashi Iwaib0b98112005-10-20 18:29:58 +02004543 if (hdsp_check_for_iobox (hdsp))
Linus Torvalds1da177e2005-04-16 15:20:36 -07004544 return -EIO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004545
Takashi Iwaib0b98112005-10-20 18:29:58 +02004546 if (copy_from_user(hdsp->firmware_cache, firmware_data, sizeof(hdsp->firmware_cache)) != 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004547 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004548
4549 hdsp->state |= HDSP_FirmwareCached;
4550
Takashi Iwaib0b98112005-10-20 18:29:58 +02004551 if ((err = snd_hdsp_load_firmware_from_cache(hdsp)) < 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004552 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004553
4554 if (!(hdsp->state & HDSP_InitializationComplete)) {
Takashi Iwaib0b98112005-10-20 18:29:58 +02004555 if ((err = snd_hdsp_enable_io(hdsp)) < 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004556 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004557
4558 snd_hdsp_initialize_channels(hdsp);
4559 snd_hdsp_initialize_midi_flush(hdsp);
4560
4561 if ((err = snd_hdsp_create_alsa_devices(hdsp->card, hdsp)) < 0) {
Takashi Iwaib0b98112005-10-20 18:29:58 +02004562 snd_printk(KERN_ERR "Hammerfall-DSP: error creating alsa devices\n");
4563 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004564 }
4565 }
4566 break;
4567 }
4568 case SNDRV_HDSP_IOCTL_GET_MIXER: {
4569 hdsp_mixer_t __user *mixer = (hdsp_mixer_t __user *)argp;
4570 if (copy_to_user(mixer->matrix, hdsp->mixer_matrix, sizeof(unsigned short)*HDSP_MATRIX_MIXER_SIZE))
4571 return -EFAULT;
4572 break;
4573 }
4574 default:
4575 return -EINVAL;
4576 }
4577 return 0;
4578}
4579
4580static snd_pcm_ops_t snd_hdsp_playback_ops = {
4581 .open = snd_hdsp_playback_open,
4582 .close = snd_hdsp_playback_release,
4583 .ioctl = snd_hdsp_ioctl,
4584 .hw_params = snd_hdsp_hw_params,
4585 .prepare = snd_hdsp_prepare,
4586 .trigger = snd_hdsp_trigger,
4587 .pointer = snd_hdsp_hw_pointer,
4588 .copy = snd_hdsp_playback_copy,
4589 .silence = snd_hdsp_hw_silence,
4590};
4591
4592static snd_pcm_ops_t snd_hdsp_capture_ops = {
4593 .open = snd_hdsp_capture_open,
4594 .close = snd_hdsp_capture_release,
4595 .ioctl = snd_hdsp_ioctl,
4596 .hw_params = snd_hdsp_hw_params,
4597 .prepare = snd_hdsp_prepare,
4598 .trigger = snd_hdsp_trigger,
4599 .pointer = snd_hdsp_hw_pointer,
4600 .copy = snd_hdsp_capture_copy,
4601};
4602
4603static int __devinit snd_hdsp_create_hwdep(snd_card_t *card,
4604 hdsp_t *hdsp)
4605{
4606 snd_hwdep_t *hw;
4607 int err;
4608
4609 if ((err = snd_hwdep_new(card, "HDSP hwdep", 0, &hw)) < 0)
4610 return err;
4611
4612 hdsp->hwdep = hw;
4613 hw->private_data = hdsp;
4614 strcpy(hw->name, "HDSP hwdep interface");
4615
4616 hw->ops.open = snd_hdsp_hwdep_dummy_op;
4617 hw->ops.ioctl = snd_hdsp_hwdep_ioctl;
4618 hw->ops.release = snd_hdsp_hwdep_dummy_op;
4619
4620 return 0;
4621}
4622
4623static int snd_hdsp_create_pcm(snd_card_t *card, hdsp_t *hdsp)
4624{
4625 snd_pcm_t *pcm;
4626 int err;
4627
4628 if ((err = snd_pcm_new(card, hdsp->card_name, 0, 1, 1, &pcm)) < 0)
4629 return err;
4630
4631 hdsp->pcm = pcm;
4632 pcm->private_data = hdsp;
4633 strcpy(pcm->name, hdsp->card_name);
4634
4635 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_hdsp_playback_ops);
4636 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_hdsp_capture_ops);
4637
4638 pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX;
4639
4640 return 0;
4641}
4642
4643static void snd_hdsp_9652_enable_mixer (hdsp_t *hdsp)
4644{
4645 hdsp->control2_register |= HDSP_9652_ENABLE_MIXER;
4646 hdsp_write (hdsp, HDSP_control2Reg, hdsp->control2_register);
4647}
4648
4649static int snd_hdsp_enable_io (hdsp_t *hdsp)
4650{
4651 int i;
4652
4653 if (hdsp_fifo_wait (hdsp, 0, 100)) {
Takashi Iwaib0b98112005-10-20 18:29:58 +02004654 snd_printk(KERN_ERR "Hammerfall-DSP: enable_io fifo_wait failed\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004655 return -EIO;
4656 }
4657
4658 for (i = 0; i < hdsp->max_channels; ++i) {
4659 hdsp_write (hdsp, HDSP_inputEnable + (4 * i), 1);
4660 hdsp_write (hdsp, HDSP_outputEnable + (4 * i), 1);
4661 }
4662
4663 return 0;
4664}
4665
4666static void snd_hdsp_initialize_channels(hdsp_t *hdsp)
4667{
4668 int status, aebi_channels, aebo_channels;
4669
4670 switch (hdsp->io_type) {
4671 case Digiface:
4672 hdsp->card_name = "RME Hammerfall DSP + Digiface";
4673 hdsp->ss_in_channels = hdsp->ss_out_channels = DIGIFACE_SS_CHANNELS;
4674 hdsp->ds_in_channels = hdsp->ds_out_channels = DIGIFACE_DS_CHANNELS;
4675 break;
4676
4677 case H9652:
4678 hdsp->card_name = "RME Hammerfall HDSP 9652";
4679 hdsp->ss_in_channels = hdsp->ss_out_channels = H9652_SS_CHANNELS;
4680 hdsp->ds_in_channels = hdsp->ds_out_channels = H9652_DS_CHANNELS;
4681 break;
4682
4683 case H9632:
4684 status = hdsp_read(hdsp, HDSP_statusRegister);
4685 /* HDSP_AEBx bits are low when AEB are connected */
4686 aebi_channels = (status & HDSP_AEBI) ? 0 : 4;
4687 aebo_channels = (status & HDSP_AEBO) ? 0 : 4;
4688 hdsp->card_name = "RME Hammerfall HDSP 9632";
4689 hdsp->ss_in_channels = H9632_SS_CHANNELS+aebi_channels;
4690 hdsp->ds_in_channels = H9632_DS_CHANNELS+aebi_channels;
4691 hdsp->qs_in_channels = H9632_QS_CHANNELS+aebi_channels;
4692 hdsp->ss_out_channels = H9632_SS_CHANNELS+aebo_channels;
4693 hdsp->ds_out_channels = H9632_DS_CHANNELS+aebo_channels;
4694 hdsp->qs_out_channels = H9632_QS_CHANNELS+aebo_channels;
4695 break;
4696
4697 case Multiface:
4698 hdsp->card_name = "RME Hammerfall DSP + Multiface";
4699 hdsp->ss_in_channels = hdsp->ss_out_channels = MULTIFACE_SS_CHANNELS;
4700 hdsp->ds_in_channels = hdsp->ds_out_channels = MULTIFACE_DS_CHANNELS;
4701 break;
4702
4703 default:
4704 /* should never get here */
4705 break;
4706 }
4707}
4708
4709static void snd_hdsp_initialize_midi_flush (hdsp_t *hdsp)
4710{
4711 snd_hdsp_flush_midi_input (hdsp, 0);
4712 snd_hdsp_flush_midi_input (hdsp, 1);
4713}
4714
4715static int snd_hdsp_create_alsa_devices(snd_card_t *card, hdsp_t *hdsp)
4716{
4717 int err;
4718
4719 if ((err = snd_hdsp_create_pcm(card, hdsp)) < 0) {
Takashi Iwaib0b98112005-10-20 18:29:58 +02004720 snd_printk(KERN_ERR "Hammerfall-DSP: Error creating pcm interface\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004721 return err;
4722 }
4723
4724
4725 if ((err = snd_hdsp_create_midi(card, hdsp, 0)) < 0) {
Takashi Iwaib0b98112005-10-20 18:29:58 +02004726 snd_printk(KERN_ERR "Hammerfall-DSP: Error creating first midi interface\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004727 return err;
4728 }
4729
4730 if (hdsp->io_type == Digiface || hdsp->io_type == H9652) {
4731 if ((err = snd_hdsp_create_midi(card, hdsp, 1)) < 0) {
Takashi Iwaib0b98112005-10-20 18:29:58 +02004732 snd_printk(KERN_ERR "Hammerfall-DSP: Error creating second midi interface\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004733 return err;
4734 }
4735 }
4736
4737 if ((err = snd_hdsp_create_controls(card, hdsp)) < 0) {
Takashi Iwaib0b98112005-10-20 18:29:58 +02004738 snd_printk(KERN_ERR "Hammerfall-DSP: Error creating ctl interface\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004739 return err;
4740 }
4741
4742 snd_hdsp_proc_init(hdsp);
4743
4744 hdsp->system_sample_rate = -1;
4745 hdsp->playback_pid = -1;
4746 hdsp->capture_pid = -1;
4747 hdsp->capture_substream = NULL;
4748 hdsp->playback_substream = NULL;
4749
4750 if ((err = snd_hdsp_set_defaults(hdsp)) < 0) {
Takashi Iwaib0b98112005-10-20 18:29:58 +02004751 snd_printk(KERN_ERR "Hammerfall-DSP: Error setting default values\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004752 return err;
4753 }
4754
4755 if (!(hdsp->state & HDSP_InitializationComplete)) {
Clemens Ladischb73c1c12005-09-02 08:49:21 +02004756 strcpy(card->shortname, "Hammerfall DSP");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004757 sprintf(card->longname, "%s at 0x%lx, irq %d", hdsp->card_name,
4758 hdsp->port, hdsp->irq);
4759
4760 if ((err = snd_card_register(card)) < 0) {
Takashi Iwaib0b98112005-10-20 18:29:58 +02004761 snd_printk(KERN_ERR "Hammerfall-DSP: error registering card\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004762 return err;
4763 }
4764 hdsp->state |= HDSP_InitializationComplete;
4765 }
4766
4767 return 0;
4768}
4769
4770#ifdef HDSP_FW_LOADER
4771/* load firmware via hotplug fw loader */
4772static int __devinit hdsp_request_fw_loader(hdsp_t *hdsp)
4773{
4774 const char *fwfile;
4775 const struct firmware *fw;
4776 int err;
4777
4778 if (hdsp->io_type == H9652 || hdsp->io_type == H9632)
4779 return 0;
4780 if (hdsp->io_type == Undefined) {
4781 if ((err = hdsp_get_iobox_version(hdsp)) < 0)
4782 return err;
4783 if (hdsp->io_type == H9652 || hdsp->io_type == H9632)
4784 return 0;
4785 }
4786
4787 /* caution: max length of firmware filename is 30! */
4788 switch (hdsp->io_type) {
4789 case Multiface:
4790 if (hdsp->firmware_rev == 0xa)
4791 fwfile = "multiface_firmware.bin";
4792 else
4793 fwfile = "multiface_firmware_rev11.bin";
4794 break;
4795 case Digiface:
4796 if (hdsp->firmware_rev == 0xa)
4797 fwfile = "digiface_firmware.bin";
4798 else
4799 fwfile = "digiface_firmware_rev11.bin";
4800 break;
4801 default:
4802 snd_printk(KERN_ERR "Hammerfall-DSP: invalid io_type %d\n", hdsp->io_type);
4803 return -EINVAL;
4804 }
4805
4806 if (request_firmware(&fw, fwfile, &hdsp->pci->dev)) {
4807 snd_printk(KERN_ERR "Hammerfall-DSP: cannot load firmware %s\n", fwfile);
4808 return -ENOENT;
4809 }
4810 if (fw->size < sizeof(hdsp->firmware_cache)) {
4811 snd_printk(KERN_ERR "Hammerfall-DSP: too short firmware size %d (expected %d)\n",
4812 (int)fw->size, (int)sizeof(hdsp->firmware_cache));
4813 release_firmware(fw);
4814 return -EINVAL;
4815 }
Thomas Charbonnel7679a032005-04-25 11:35:29 +02004816
Linus Torvalds1da177e2005-04-16 15:20:36 -07004817 memcpy(hdsp->firmware_cache, fw->data, sizeof(hdsp->firmware_cache));
Thomas Charbonnel7679a032005-04-25 11:35:29 +02004818
Linus Torvalds1da177e2005-04-16 15:20:36 -07004819 release_firmware(fw);
4820
4821 hdsp->state |= HDSP_FirmwareCached;
4822
4823 if ((err = snd_hdsp_load_firmware_from_cache(hdsp)) < 0)
4824 return err;
4825
4826 if (!(hdsp->state & HDSP_InitializationComplete)) {
Takashi Iwaib0b98112005-10-20 18:29:58 +02004827 if ((err = snd_hdsp_enable_io(hdsp)) < 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004828 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004829
4830 if ((err = snd_hdsp_create_hwdep(hdsp->card, hdsp)) < 0) {
Takashi Iwaib0b98112005-10-20 18:29:58 +02004831 snd_printk(KERN_ERR "Hammerfall-DSP: error creating hwdep device\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004832 return err;
4833 }
4834 snd_hdsp_initialize_channels(hdsp);
4835 snd_hdsp_initialize_midi_flush(hdsp);
4836 if ((err = snd_hdsp_create_alsa_devices(hdsp->card, hdsp)) < 0) {
Takashi Iwaib0b98112005-10-20 18:29:58 +02004837 snd_printk(KERN_ERR "Hammerfall-DSP: error creating alsa devices\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004838 return err;
4839 }
4840 }
4841 return 0;
4842}
4843#endif
4844
4845static int __devinit snd_hdsp_create(snd_card_t *card,
4846 hdsp_t *hdsp)
4847{
4848 struct pci_dev *pci = hdsp->pci;
4849 int err;
4850 int is_9652 = 0;
4851 int is_9632 = 0;
4852
4853 hdsp->irq = -1;
4854 hdsp->state = 0;
4855 hdsp->midi[0].rmidi = NULL;
4856 hdsp->midi[1].rmidi = NULL;
4857 hdsp->midi[0].input = NULL;
4858 hdsp->midi[1].input = NULL;
4859 hdsp->midi[0].output = NULL;
4860 hdsp->midi[1].output = NULL;
4861 hdsp->midi[0].pending = 0;
4862 hdsp->midi[1].pending = 0;
4863 spin_lock_init(&hdsp->midi[0].lock);
4864 spin_lock_init(&hdsp->midi[1].lock);
4865 hdsp->iobase = NULL;
4866 hdsp->control_register = 0;
4867 hdsp->control2_register = 0;
4868 hdsp->io_type = Undefined;
4869 hdsp->max_channels = 26;
4870
4871 hdsp->card = card;
4872
4873 spin_lock_init(&hdsp->lock);
4874
4875 tasklet_init(&hdsp->midi_tasklet, hdsp_midi_tasklet, (unsigned long)hdsp);
4876
4877 pci_read_config_word(hdsp->pci, PCI_CLASS_REVISION, &hdsp->firmware_rev);
4878 hdsp->firmware_rev &= 0xff;
4879
4880 /* From Martin Bjoernsen :
4881 "It is important that the card's latency timer register in
4882 the PCI configuration space is set to a value much larger
4883 than 0 by the computer's BIOS or the driver.
4884 The windows driver always sets this 8 bit register [...]
4885 to its maximum 255 to avoid problems with some computers."
4886 */
4887 pci_write_config_byte(hdsp->pci, PCI_LATENCY_TIMER, 0xFF);
4888
4889 strcpy(card->driver, "H-DSP");
4890 strcpy(card->mixername, "Xilinx FPGA");
4891
Takashi Iwaib0b98112005-10-20 18:29:58 +02004892 if (hdsp->firmware_rev < 0xa)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004893 return -ENODEV;
Takashi Iwaib0b98112005-10-20 18:29:58 +02004894 else if (hdsp->firmware_rev < 0x64)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004895 hdsp->card_name = "RME Hammerfall DSP";
Takashi Iwaib0b98112005-10-20 18:29:58 +02004896 else if (hdsp->firmware_rev < 0x96) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004897 hdsp->card_name = "RME HDSP 9652";
4898 is_9652 = 1;
4899 } else {
4900 hdsp->card_name = "RME HDSP 9632";
4901 hdsp->max_channels = 16;
4902 is_9632 = 1;
4903 }
4904
Takashi Iwaib0b98112005-10-20 18:29:58 +02004905 if ((err = pci_enable_device(pci)) < 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004906 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004907
4908 pci_set_master(hdsp->pci);
4909
4910 if ((err = pci_request_regions(pci, "hdsp")) < 0)
4911 return err;
4912 hdsp->port = pci_resource_start(pci, 0);
4913 if ((hdsp->iobase = ioremap_nocache(hdsp->port, HDSP_IO_EXTENT)) == NULL) {
Takashi Iwaib0b98112005-10-20 18:29:58 +02004914 snd_printk(KERN_ERR "Hammerfall-DSP: unable to remap region 0x%lx-0x%lx\n", hdsp->port, hdsp->port + HDSP_IO_EXTENT - 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004915 return -EBUSY;
4916 }
4917
4918 if (request_irq(pci->irq, snd_hdsp_interrupt, SA_INTERRUPT|SA_SHIRQ, "hdsp", (void *)hdsp)) {
Takashi Iwaib0b98112005-10-20 18:29:58 +02004919 snd_printk(KERN_ERR "Hammerfall-DSP: unable to use IRQ %d\n", pci->irq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004920 return -EBUSY;
4921 }
4922
4923 hdsp->irq = pci->irq;
4924 hdsp->precise_ptr = 1;
4925 hdsp->use_midi_tasklet = 1;
4926
Takashi Iwaib0b98112005-10-20 18:29:58 +02004927 if ((err = snd_hdsp_initialize_memory(hdsp)) < 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004928 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004929
4930 if (!is_9652 && !is_9632) {
4931 /* we wait 2 seconds to let freshly inserted cardbus cards do their hardware init */
Takashi Iwaib0b98112005-10-20 18:29:58 +02004932 ssleep(2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004933
4934 if ((hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DllError) != 0) {
4935#ifdef HDSP_FW_LOADER
Takashi Iwaib0b98112005-10-20 18:29:58 +02004936 if ((err = hdsp_request_fw_loader(hdsp)) < 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004937 /* we don't fail as this can happen
4938 if userspace is not ready for
4939 firmware upload
4940 */
Takashi Iwaib0b98112005-10-20 18:29:58 +02004941 snd_printk(KERN_ERR "Hammerfall-DSP: couldn't get firmware from userspace. try using hdsploader\n");
4942 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07004943 /* init is complete, we return */
4944 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004945#endif
4946 /* no iobox connected, we defer initialization */
Takashi Iwaib0b98112005-10-20 18:29:58 +02004947 snd_printk(KERN_INFO "Hammerfall-DSP: card initialization pending : waiting for firmware\n");
4948 if ((err = snd_hdsp_create_hwdep(card, hdsp)) < 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004949 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004950 return 0;
4951 } else {
Takashi Iwaib0b98112005-10-20 18:29:58 +02004952 snd_printk(KERN_INFO "Hammerfall-DSP: Firmware already present, initializing card.\n");
4953 if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version1)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004954 hdsp->io_type = Multiface;
Takashi Iwaib0b98112005-10-20 18:29:58 +02004955 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07004956 hdsp->io_type = Digiface;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004957 }
4958 }
4959
Takashi Iwaib0b98112005-10-20 18:29:58 +02004960 if ((err = snd_hdsp_enable_io(hdsp)) != 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004961 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004962
Takashi Iwaib0b98112005-10-20 18:29:58 +02004963 if (is_9652)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004964 hdsp->io_type = H9652;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004965
Takashi Iwaib0b98112005-10-20 18:29:58 +02004966 if (is_9632)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004967 hdsp->io_type = H9632;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004968
Takashi Iwaib0b98112005-10-20 18:29:58 +02004969 if ((err = snd_hdsp_create_hwdep(card, hdsp)) < 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004970 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004971
4972 snd_hdsp_initialize_channels(hdsp);
4973 snd_hdsp_initialize_midi_flush(hdsp);
4974
4975 hdsp->state |= HDSP_FirmwareLoaded;
4976
Takashi Iwaib0b98112005-10-20 18:29:58 +02004977 if ((err = snd_hdsp_create_alsa_devices(card, hdsp)) < 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004978 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004979
4980 return 0;
4981}
4982
4983static int snd_hdsp_free(hdsp_t *hdsp)
4984{
4985 if (hdsp->port) {
4986 /* stop the audio, and cancel all interrupts */
4987 tasklet_kill(&hdsp->midi_tasklet);
4988 hdsp->control_register &= ~(HDSP_Start|HDSP_AudioInterruptEnable|HDSP_Midi0InterruptEnable|HDSP_Midi1InterruptEnable);
4989 hdsp_write (hdsp, HDSP_controlRegister, hdsp->control_register);
4990 }
4991
4992 if (hdsp->irq >= 0)
4993 free_irq(hdsp->irq, (void *)hdsp);
4994
4995 snd_hdsp_free_buffers(hdsp);
4996
4997 if (hdsp->iobase)
4998 iounmap(hdsp->iobase);
4999
5000 if (hdsp->port)
5001 pci_release_regions(hdsp->pci);
5002
5003 pci_disable_device(hdsp->pci);
5004 return 0;
5005}
5006
5007static void snd_hdsp_card_free(snd_card_t *card)
5008{
5009 hdsp_t *hdsp = (hdsp_t *) card->private_data;
5010
5011 if (hdsp)
5012 snd_hdsp_free(hdsp);
5013}
5014
5015static int __devinit snd_hdsp_probe(struct pci_dev *pci,
5016 const struct pci_device_id *pci_id)
5017{
5018 static int dev;
5019 hdsp_t *hdsp;
5020 snd_card_t *card;
5021 int err;
5022
5023 if (dev >= SNDRV_CARDS)
5024 return -ENODEV;
5025 if (!enable[dev]) {
5026 dev++;
5027 return -ENOENT;
5028 }
5029
5030 if (!(card = snd_card_new(index[dev], id[dev], THIS_MODULE, sizeof(hdsp_t))))
5031 return -ENOMEM;
5032
5033 hdsp = (hdsp_t *) card->private_data;
5034 card->private_free = snd_hdsp_card_free;
5035 hdsp->dev = dev;
5036 hdsp->pci = pci;
5037 snd_card_set_dev(card, &pci->dev);
5038
5039 if ((err = snd_hdsp_create(card, hdsp)) < 0) {
5040 snd_card_free(card);
5041 return err;
5042 }
5043
5044 strcpy(card->shortname, "Hammerfall DSP");
5045 sprintf(card->longname, "%s at 0x%lx, irq %d", hdsp->card_name,
5046 hdsp->port, hdsp->irq);
5047
5048 if ((err = snd_card_register(card)) < 0) {
5049 snd_card_free(card);
5050 return err;
5051 }
5052 pci_set_drvdata(pci, card);
5053 dev++;
5054 return 0;
5055}
5056
5057static void __devexit snd_hdsp_remove(struct pci_dev *pci)
5058{
5059 snd_card_free(pci_get_drvdata(pci));
5060 pci_set_drvdata(pci, NULL);
5061}
5062
5063static struct pci_driver driver = {
5064 .name = "RME Hammerfall DSP",
Clemens Ladisch3bcd4642005-09-12 08:20:54 +02005065 .owner = THIS_MODULE,
Linus Torvalds1da177e2005-04-16 15:20:36 -07005066 .id_table = snd_hdsp_ids,
5067 .probe = snd_hdsp_probe,
5068 .remove = __devexit_p(snd_hdsp_remove),
5069};
5070
5071static int __init alsa_card_hdsp_init(void)
5072{
Takashi Iwai01d25d42005-04-11 16:58:24 +02005073 return pci_register_driver(&driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005074}
5075
5076static void __exit alsa_card_hdsp_exit(void)
5077{
5078 pci_unregister_driver(&driver);
5079}
5080
5081module_init(alsa_card_hdsp_init)
5082module_exit(alsa_card_hdsp_exit)