[ALSA] sound - fix .iface field of mixer control elements
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / sound / pci / rme9652 / hdspm.c
CommitLineData
763f356c
TI
1/* -*- linux-c -*-
2 *
3 * ALSA driver for RME Hammerfall DSP MADI audio interface(s)
4 *
5 * Copyright (c) 2003 Winfried Ritsch (IEM)
6 * code based on hdsp.c Paul Davis
7 * Marcus Andersson
8 * Thomas Charbonnel
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 *
24 */
25#include <sound/driver.h>
26#include <linux/init.h>
27#include <linux/delay.h>
28#include <linux/interrupt.h>
29#include <linux/moduleparam.h>
30#include <linux/slab.h>
31#include <linux/pci.h>
32#include <asm/io.h>
33
34#include <sound/core.h>
35#include <sound/control.h>
36#include <sound/pcm.h>
37#include <sound/info.h>
38#include <sound/asoundef.h>
39#include <sound/rawmidi.h>
40#include <sound/hwdep.h>
41#include <sound/initval.h>
42
43#include <sound/hdspm.h>
44
45static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
46static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
47static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;/* Enable this card */
48
49/* Disable precise pointer at start */
50static int precise_ptr[SNDRV_CARDS];
51
52/* Send all playback to line outs */
53static int line_outs_monitor[SNDRV_CARDS];
54
55/* Enable Analog Outs on Channel 63/64 by default */
56static int enable_monitor[SNDRV_CARDS];
57
58module_param_array(index, int, NULL, 0444);
59MODULE_PARM_DESC(index, "Index value for RME HDSPM interface.");
60
61module_param_array(id, charp, NULL, 0444);
62MODULE_PARM_DESC(id, "ID string for RME HDSPM interface.");
63
64module_param_array(enable, bool, NULL, 0444);
65MODULE_PARM_DESC(enable, "Enable/disable specific HDSPM soundcards.");
66
67module_param_array(precise_ptr, bool, NULL, 0444);
68MODULE_PARM_DESC(precise_ptr, "Enable precise pointer, or disable.");
69
70module_param_array(line_outs_monitor, bool, NULL, 0444);
71MODULE_PARM_DESC(line_outs_monitor,
72 "Send playback streams to analog outs by default.");
73
74module_param_array(enable_monitor, bool, NULL, 0444);
75MODULE_PARM_DESC(enable_monitor,
76 "Enable Analog Out on Channel 63/64 by default.");
77
78MODULE_AUTHOR
79 ("Winfried Ritsch <ritsch_AT_iem.at>, Paul Davis <paul@linuxaudiosystems.com>, "
80 "Marcus Andersson, Thomas Charbonnel <thomas@undata.org>");
81MODULE_DESCRIPTION("RME HDSPM");
82MODULE_LICENSE("GPL");
83MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
84
85/* --- Write registers. ---
86 These are defined as byte-offsets from the iobase value. */
87
88#define HDSPM_controlRegister 64
89#define HDSPM_interruptConfirmation 96
90#define HDSPM_control2Reg 256 /* not in specs ???????? */
91#define HDSPM_midiDataOut0 352 /* just believe in old code */
92#define HDSPM_midiDataOut1 356
93
94/* DMA enable for 64 channels, only Bit 0 is relevant */
95#define HDSPM_outputEnableBase 512 /* 512-767 input DMA */
96#define HDSPM_inputEnableBase 768 /* 768-1023 output DMA */
97
98/* 16 page addresses for each of the 64 channels DMA buffer in and out
99 (each 64k=16*4k) Buffer must be 4k aligned (which is default i386 ????) */
100#define HDSPM_pageAddressBufferOut 8192
101#define HDSPM_pageAddressBufferIn (HDSPM_pageAddressBufferOut+64*16*4)
102
103#define HDSPM_MADI_mixerBase 32768 /* 32768-65535 for 2x64x64 Fader */
104
105#define HDSPM_MATRIX_MIXER_SIZE 8192 /* = 2*64*64 * 4 Byte => 32kB */
106
107/* --- Read registers. ---
108 These are defined as byte-offsets from the iobase value */
109#define HDSPM_statusRegister 0
110#define HDSPM_statusRegister2 96
111
112#define HDSPM_midiDataIn0 360
113#define HDSPM_midiDataIn1 364
114
115/* status is data bytes in MIDI-FIFO (0-128) */
116#define HDSPM_midiStatusOut0 384
117#define HDSPM_midiStatusOut1 388
118#define HDSPM_midiStatusIn0 392
119#define HDSPM_midiStatusIn1 396
120
121
122/* the meters are regular i/o-mapped registers, but offset
123 considerably from the rest. the peak registers are reset
124 when read; the least-significant 4 bits are full-scale counters;
125 the actual peak value is in the most-significant 24 bits.
126*/
127#define HDSPM_MADI_peakrmsbase 4096 /* 4096-8191 2x64x32Bit Meters */
128
129/* --- Control Register bits --------- */
130#define HDSPM_Start (1<<0) /* start engine */
131
132#define HDSPM_Latency0 (1<<1) /* buffer size = 2^n */
133#define HDSPM_Latency1 (1<<2) /* where n is defined */
134#define HDSPM_Latency2 (1<<3) /* by Latency{2,1,0} */
135
136#define HDSPM_ClockModeMaster (1<<4) /* 1=Master, 0=Slave/Autosync */
137
138#define HDSPM_AudioInterruptEnable (1<<5) /* what do you think ? */
139
140#define HDSPM_Frequency0 (1<<6) /* 0=44.1kHz/88.2kHz 1=48kHz/96kHz */
141#define HDSPM_Frequency1 (1<<7) /* 0=32kHz/64kHz */
142#define HDSPM_DoubleSpeed (1<<8) /* 0=normal speed, 1=double speed */
143#define HDSPM_QuadSpeed (1<<31) /* quad speed bit, not implemented now */
144
145#define HDSPM_TX_64ch (1<<10) /* Output 64channel MODE=1,
146 56channelMODE=0 */
147
148#define HDSPM_AutoInp (1<<11) /* Auto Input (takeover) == Safe Mode,
149 0=off, 1=on */
150
151#define HDSPM_InputSelect0 (1<<14) /* Input select 0= optical, 1=coax */
152#define HDSPM_InputSelect1 (1<<15) /* should be 0 */
153
154#define HDSPM_SyncRef0 (1<<16) /* 0=WOrd, 1=MADI */
155#define HDSPM_SyncRef1 (1<<17) /* should be 0 */
156
157#define HDSPM_clr_tms (1<<19) /* clear track marker, do not use
158 AES additional bits in
159 lower 5 Audiodatabits ??? */
160
161#define HDSPM_Midi0InterruptEnable (1<<22)
162#define HDSPM_Midi1InterruptEnable (1<<23)
163
164#define HDSPM_LineOut (1<<24) /* Analog Out on channel 63/64 on=1, mute=0 */
165
166
167/* --- bit helper defines */
168#define HDSPM_LatencyMask (HDSPM_Latency0|HDSPM_Latency1|HDSPM_Latency2)
169#define HDSPM_FrequencyMask (HDSPM_Frequency0|HDSPM_Frequency1)
170#define HDSPM_InputMask (HDSPM_InputSelect0|HDSPM_InputSelect1)
171#define HDSPM_InputOptical 0
172#define HDSPM_InputCoaxial (HDSPM_InputSelect0)
173#define HDSPM_SyncRefMask (HDSPM_SyncRef0|HDSPM_SyncRef1)
174#define HDSPM_SyncRef_Word 0
175#define HDSPM_SyncRef_MADI (HDSPM_SyncRef0)
176
177#define HDSPM_SYNC_FROM_WORD 0 /* Preferred sync reference */
178#define HDSPM_SYNC_FROM_MADI 1 /* choices - used by "pref_sync_ref" */
179
180#define HDSPM_Frequency32KHz HDSPM_Frequency0
181#define HDSPM_Frequency44_1KHz HDSPM_Frequency1
182#define HDSPM_Frequency48KHz (HDSPM_Frequency1|HDSPM_Frequency0)
183#define HDSPM_Frequency64KHz (HDSPM_DoubleSpeed|HDSPM_Frequency0)
184#define HDSPM_Frequency88_2KHz (HDSPM_DoubleSpeed|HDSPM_Frequency1)
185#define HDSPM_Frequency96KHz (HDSPM_DoubleSpeed|HDSPM_Frequency1|HDSPM_Frequency0)
186
187/* --- for internal discrimination */
188#define HDSPM_CLOCK_SOURCE_AUTOSYNC 0 /* Sample Clock Sources */
189#define HDSPM_CLOCK_SOURCE_INTERNAL_32KHZ 1
190#define HDSPM_CLOCK_SOURCE_INTERNAL_44_1KHZ 2
191#define HDSPM_CLOCK_SOURCE_INTERNAL_48KHZ 3
192#define HDSPM_CLOCK_SOURCE_INTERNAL_64KHZ 4
193#define HDSPM_CLOCK_SOURCE_INTERNAL_88_2KHZ 5
194#define HDSPM_CLOCK_SOURCE_INTERNAL_96KHZ 6
195#define HDSPM_CLOCK_SOURCE_INTERNAL_128KHZ 7
196#define HDSPM_CLOCK_SOURCE_INTERNAL_176_4KHZ 8
197#define HDSPM_CLOCK_SOURCE_INTERNAL_192KHZ 9
198
199/* Synccheck Status */
200#define HDSPM_SYNC_CHECK_NO_LOCK 0
201#define HDSPM_SYNC_CHECK_LOCK 1
202#define HDSPM_SYNC_CHECK_SYNC 2
203
204/* AutoSync References - used by "autosync_ref" control switch */
205#define HDSPM_AUTOSYNC_FROM_WORD 0
206#define HDSPM_AUTOSYNC_FROM_MADI 1
207#define HDSPM_AUTOSYNC_FROM_NONE 2
208
209/* Possible sources of MADI input */
210#define HDSPM_OPTICAL 0 /* optical */
211#define HDSPM_COAXIAL 1 /* BNC */
212
213#define hdspm_encode_latency(x) (((x)<<1) & HDSPM_LatencyMask)
214#define hdspm_decode_latency(x) (((x) & HDSPM_LatencyMask)>>1)
215
216#define hdspm_encode_in(x) (((x)&0x3)<<14)
217#define hdspm_decode_in(x) (((x)>>14)&0x3)
218
219/* --- control2 register bits --- */
220#define HDSPM_TMS (1<<0)
221#define HDSPM_TCK (1<<1)
222#define HDSPM_TDI (1<<2)
223#define HDSPM_JTAG (1<<3)
224#define HDSPM_PWDN (1<<4)
225#define HDSPM_PROGRAM (1<<5)
226#define HDSPM_CONFIG_MODE_0 (1<<6)
227#define HDSPM_CONFIG_MODE_1 (1<<7)
228/*#define HDSPM_VERSION_BIT (1<<8) not defined any more*/
229#define HDSPM_BIGENDIAN_MODE (1<<9)
230#define HDSPM_RD_MULTIPLE (1<<10)
231
232/* --- Status Register bits --- */
233#define HDSPM_audioIRQPending (1<<0) /* IRQ is high and pending */
234#define HDSPM_RX_64ch (1<<1) /* Input 64chan. MODE=1, 56chn. MODE=0 */
235#define HDSPM_AB_int (1<<2) /* InputChannel Opt=0, Coax=1 (like inp0) */
236#define HDSPM_madiLock (1<<3) /* MADI Locked =1, no=0 */
237
238#define HDSPM_BufferPositionMask 0x000FFC0 /* Bit 6..15 : h/w buffer pointer */
239 /* since 64byte accurate last 6 bits
240 are not used */
241
242#define HDSPM_madiSync (1<<18) /* MADI is in sync */
243#define HDSPM_DoubleSpeedStatus (1<<19) /* (input) card in double speed */
244
245#define HDSPM_madiFreq0 (1<<22) /* system freq 0=error */
246#define HDSPM_madiFreq1 (1<<23) /* 1=32, 2=44.1 3=48 */
247#define HDSPM_madiFreq2 (1<<24) /* 4=64, 5=88.2 6=96 */
248#define HDSPM_madiFreq3 (1<<25) /* 7=128, 8=176.4 9=192 */
249
250#define HDSPM_BufferID (1<<26) /* (Double)Buffer ID toggles with Interrupt */
251#define HDSPM_midi0IRQPending (1<<30) /* MIDI IRQ is pending */
252#define HDSPM_midi1IRQPending (1<<31) /* and aktiv */
253
254/* --- status bit helpers */
255#define HDSPM_madiFreqMask (HDSPM_madiFreq0|HDSPM_madiFreq1|HDSPM_madiFreq2|HDSPM_madiFreq3)
256#define HDSPM_madiFreq32 (HDSPM_madiFreq0)
257#define HDSPM_madiFreq44_1 (HDSPM_madiFreq1)
258#define HDSPM_madiFreq48 (HDSPM_madiFreq0|HDSPM_madiFreq1)
259#define HDSPM_madiFreq64 (HDSPM_madiFreq2)
260#define HDSPM_madiFreq88_2 (HDSPM_madiFreq0|HDSPM_madiFreq2)
261#define HDSPM_madiFreq96 (HDSPM_madiFreq1|HDSPM_madiFreq2)
262#define HDSPM_madiFreq128 (HDSPM_madiFreq0|HDSPM_madiFreq1|HDSPM_madiFreq2)
263#define HDSPM_madiFreq176_4 (HDSPM_madiFreq3)
264#define HDSPM_madiFreq192 (HDSPM_madiFreq3|HDSPM_madiFreq0)
265
266/* Status2 Register bits */
267
268#define HDSPM_version0 (1<<0) /* not realy defined but I guess */
269#define HDSPM_version1 (1<<1) /* in former cards it was ??? */
270#define HDSPM_version2 (1<<2)
271
272#define HDSPM_wcLock (1<<3) /* Wordclock is detected and locked */
273#define HDSPM_wcSync (1<<4) /* Wordclock is in sync with systemclock */
274
275#define HDSPM_wc_freq0 (1<<5) /* input freq detected via autosync */
276#define HDSPM_wc_freq1 (1<<6) /* 001=32, 010==44.1, 011=48, */
277#define HDSPM_wc_freq2 (1<<7) /* 100=64, 101=88.2, 110=96, */
278/* missing Bit for 111=128, 1000=176.4, 1001=192 */
279
280#define HDSPM_SelSyncRef0 (1<<8) /* Sync Source in slave mode */
281#define HDSPM_SelSyncRef1 (1<<9) /* 000=word, 001=MADI, */
282#define HDSPM_SelSyncRef2 (1<<10) /* 111=no valid signal */
283
284#define HDSPM_wc_valid (HDSPM_wcLock|HDSPM_wcSync)
285
286#define HDSPM_wcFreqMask (HDSPM_wc_freq0|HDSPM_wc_freq1|HDSPM_wc_freq2)
287#define HDSPM_wcFreq32 (HDSPM_wc_freq0)
288#define HDSPM_wcFreq44_1 (HDSPM_wc_freq1)
289#define HDSPM_wcFreq48 (HDSPM_wc_freq0|HDSPM_wc_freq1)
290#define HDSPM_wcFreq64 (HDSPM_wc_freq2)
291#define HDSPM_wcFreq88_2 (HDSPM_wc_freq0|HDSPM_wc_freq2)
292#define HDSPM_wcFreq96 (HDSPM_wc_freq1|HDSPM_wc_freq2)
293
294
295#define HDSPM_SelSyncRefMask (HDSPM_SelSyncRef0|HDSPM_SelSyncRef1|HDSPM_SelSyncRef2)
296#define HDSPM_SelSyncRef_WORD 0
297#define HDSPM_SelSyncRef_MADI (HDSPM_SelSyncRef0)
298#define HDSPM_SelSyncRef_NVALID (HDSPM_SelSyncRef0|HDSPM_SelSyncRef1|HDSPM_SelSyncRef2)
299
300/* Mixer Values */
301#define UNITY_GAIN 32768 /* = 65536/2 */
302#define MINUS_INFINITY_GAIN 0
303
304/* PCI info */
305#ifndef PCI_VENDOR_ID_XILINX
306#define PCI_VENDOR_ID_XILINX 0x10ee
307#endif
308#ifndef PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP
309#define PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP 0x3fc5
310#endif
311#ifndef PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP_MADI
312#define PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP_MADI 0x3fc6
313#endif
314
315
316/* Number of channels for different Speed Modes */
317#define MADI_SS_CHANNELS 64
318#define MADI_DS_CHANNELS 32
319#define MADI_QS_CHANNELS 16
320
321/* the size of a substream (1 mono data stream) */
322#define HDSPM_CHANNEL_BUFFER_SAMPLES (16*1024)
323#define HDSPM_CHANNEL_BUFFER_BYTES (4*HDSPM_CHANNEL_BUFFER_SAMPLES)
324
325/* the size of the area we need to allocate for DMA transfers. the
326 size is the same regardless of the number of channels, and
327 also the latency to use.
328 for one direction !!!
329*/
330#define HDSPM_DMA_AREA_BYTES (HDSPM_MAX_CHANNELS * HDSPM_CHANNEL_BUFFER_BYTES)
331#define HDSPM_DMA_AREA_KILOBYTES (HDSPM_DMA_AREA_BYTES/1024)
332
333typedef struct _hdspm hdspm_t;
334typedef struct _hdspm_midi hdspm_midi_t;
335
336struct _hdspm_midi {
337 hdspm_t *hdspm;
338 int id;
339 snd_rawmidi_t *rmidi;
340 snd_rawmidi_substream_t *input;
341 snd_rawmidi_substream_t *output;
342 char istimer; /* timer in use */
343 struct timer_list timer;
344 spinlock_t lock;
345 int pending;
346};
347
348struct _hdspm {
349 spinlock_t lock;
350 snd_pcm_substream_t *capture_substream; /* only one playback */
351 snd_pcm_substream_t *playback_substream; /* and/or capture stream */
352
353 char *card_name; /* for procinfo */
354 unsigned short firmware_rev; /* dont know if relevant */
355
356 int precise_ptr; /* use precise pointers, to be tested */
357 int monitor_outs; /* set up monitoring outs init flag */
358
359 u32 control_register; /* cached value */
360 u32 control2_register; /* cached value */
361
362 hdspm_midi_t midi[2];
363 struct tasklet_struct midi_tasklet;
364
365 size_t period_bytes;
366 unsigned char ss_channels; /* channels of card in single speed */
367 unsigned char ds_channels; /* Double Speed */
368 unsigned char qs_channels; /* Quad Speed */
369
370 unsigned char *playback_buffer; /* suitably aligned address */
371 unsigned char *capture_buffer; /* suitably aligned address */
372
373 pid_t capture_pid; /* process id which uses capture */
374 pid_t playback_pid; /* process id which uses capture */
375 int running; /* running status */
376
377 int last_external_sample_rate; /* samplerate mystic ... */
378 int last_internal_sample_rate;
379 int system_sample_rate;
380
381 char *channel_map; /* channel map for DS and Quadspeed */
382
383 int dev; /* Hardware vars... */
384 int irq;
385 unsigned long port;
386 void __iomem *iobase;
387
388 int irq_count; /* for debug */
389
390 snd_card_t *card; /* one card */
391 snd_pcm_t *pcm; /* has one pcm */
392 snd_hwdep_t *hwdep; /* and a hwdep for additional ioctl */
393 struct pci_dev *pci; /* and an pci info */
394
395 /* Mixer vars */
396 snd_kcontrol_t *playback_mixer_ctls[HDSPM_MAX_CHANNELS]; /* fast alsa mixer */
397 snd_kcontrol_t *input_mixer_ctls[HDSPM_MAX_CHANNELS]; /* but input to much, so not used */
398 hdspm_mixer_t *mixer; /* full mixer accessable over mixer ioctl or hwdep-device */
399
400};
401
402/* These tables map the ALSA channels 1..N to the channels that we
403 need to use in order to find the relevant channel buffer. RME
404 refer to this kind of mapping as between "the ADAT channel and
405 the DMA channel." We index it using the logical audio channel,
406 and the value is the DMA channel (i.e. channel buffer number)
407 where the data for that channel can be read/written from/to.
408*/
409
410static char channel_map_madi_ss[HDSPM_MAX_CHANNELS] = {
411 0, 1, 2, 3, 4, 5, 6, 7,
412 8, 9, 10, 11, 12, 13, 14, 15,
413 16, 17, 18, 19, 20, 21, 22, 23,
414 24, 25, 26, 27, 28, 29, 30, 31,
415 32, 33, 34, 35, 36, 37, 38, 39,
416 40, 41, 42, 43, 44, 45, 46, 47,
417 48, 49, 50, 51, 52, 53, 54, 55,
418 56, 57, 58, 59, 60, 61, 62, 63
419};
420
421static char channel_map_madi_ds[HDSPM_MAX_CHANNELS] = {
422 0, 2, 4, 6, 8, 10, 12, 14,
423 16, 18, 20, 22, 24, 26, 28, 30,
424 32, 34, 36, 38, 40, 42, 44, 46,
425 48, 50, 52, 54, 56, 58, 60, 62,
426 -1, -1, -1, -1, -1, -1, -1, -1,
427 -1, -1, -1, -1, -1, -1, -1, -1,
428 -1, -1, -1, -1, -1, -1, -1, -1,
429 -1, -1, -1, -1, -1, -1, -1, -1
430};
431
432static char channel_map_madi_qs[HDSPM_MAX_CHANNELS] = {
433 0, 4, 8, 12, 16, 20, 24, 28,
434 32, 36, 40, 44, 48, 52, 56, 60
435 -1, -1, -1, -1, -1, -1, -1, -1,
436 -1, -1, -1, -1, -1, -1, -1, -1,
437 -1, -1, -1, -1, -1, -1, -1, -1,
438 -1, -1, -1, -1, -1, -1, -1, -1,
439 -1, -1, -1, -1, -1, -1, -1, -1,
440 -1, -1, -1, -1, -1, -1, -1, -1
441};
442
443
444static struct pci_device_id snd_hdspm_ids[] = {
445 {
446 .vendor = PCI_VENDOR_ID_XILINX,
447 .device = PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP_MADI,
448 .subvendor = PCI_ANY_ID,
449 .subdevice = PCI_ANY_ID,
450 .class = 0,
451 .class_mask = 0,
452 .driver_data = 0},
453 {0,}
454};
455
456MODULE_DEVICE_TABLE(pci, snd_hdspm_ids);
457
458/* prototypes */
459static int __devinit snd_hdspm_create_alsa_devices(snd_card_t * card,
460 hdspm_t * hdspm);
461static int __devinit snd_hdspm_create_pcm(snd_card_t * card,
462 hdspm_t * hdspm);
463
464static inline void snd_hdspm_initialize_midi_flush(hdspm_t * hdspm);
465static int hdspm_update_simple_mixer_controls(hdspm_t * hdspm);
466static int hdspm_autosync_ref(hdspm_t * hdspm);
467static int snd_hdspm_set_defaults(hdspm_t * hdspm);
468static void hdspm_set_sgbuf(hdspm_t * hdspm, struct snd_sg_buf *sgbuf,
469 unsigned int reg, int channels);
470
471/* Write/read to/from HDSPM with Adresses in Bytes
472 not words but only 32Bit writes are allowed */
473
474static inline void hdspm_write(hdspm_t * hdspm, unsigned int reg,
475 unsigned int val)
476{
477 writel(val, hdspm->iobase + reg);
478}
479
480static inline unsigned int hdspm_read(hdspm_t * hdspm, unsigned int reg)
481{
482 return readl(hdspm->iobase + reg);
483}
484
485/* for each output channel (chan) I have an Input (in) and Playback (pb) Fader
486 mixer is write only on hardware so we have to cache him for read
487 each fader is a u32, but uses only the first 16 bit */
488
489static inline int hdspm_read_in_gain(hdspm_t * hdspm, unsigned int chan,
490 unsigned int in)
491{
492 if (chan > HDSPM_MIXER_CHANNELS || in > HDSPM_MIXER_CHANNELS)
493 return 0;
494
495 return hdspm->mixer->ch[chan].in[in];
496}
497
498static inline int hdspm_read_pb_gain(hdspm_t * hdspm, unsigned int chan,
499 unsigned int pb)
500{
501 if (chan > HDSPM_MIXER_CHANNELS || pb > HDSPM_MIXER_CHANNELS)
502 return 0;
503 return hdspm->mixer->ch[chan].pb[pb];
504}
505
506static inline int hdspm_write_in_gain(hdspm_t * hdspm, unsigned int chan,
507 unsigned int in, unsigned short data)
508{
509 if (chan >= HDSPM_MIXER_CHANNELS || in >= HDSPM_MIXER_CHANNELS)
510 return -1;
511
512 hdspm_write(hdspm,
513 HDSPM_MADI_mixerBase +
514 ((in + 128 * chan) * sizeof(u32)),
515 (hdspm->mixer->ch[chan].in[in] = data & 0xFFFF));
516 return 0;
517}
518
519static inline int hdspm_write_pb_gain(hdspm_t * hdspm, unsigned int chan,
520 unsigned int pb, unsigned short data)
521{
522 if (chan >= HDSPM_MIXER_CHANNELS || pb >= HDSPM_MIXER_CHANNELS)
523 return -1;
524
525 hdspm_write(hdspm,
526 HDSPM_MADI_mixerBase +
527 ((64 + pb + 128 * chan) * sizeof(u32)),
528 (hdspm->mixer->ch[chan].pb[pb] = data & 0xFFFF));
529 return 0;
530}
531
532
533/* enable DMA for specific channels, now available for DSP-MADI */
534static inline void snd_hdspm_enable_in(hdspm_t * hdspm, int i, int v)
535{
536 hdspm_write(hdspm, HDSPM_inputEnableBase + (4 * i), v);
537}
538
539static inline void snd_hdspm_enable_out(hdspm_t * hdspm, int i, int v)
540{
541 hdspm_write(hdspm, HDSPM_outputEnableBase + (4 * i), v);
542}
543
544/* check if same process is writing and reading */
545static inline int snd_hdspm_use_is_exclusive(hdspm_t * hdspm)
546{
547 unsigned long flags;
548 int ret = 1;
549
550 spin_lock_irqsave(&hdspm->lock, flags);
551 if ((hdspm->playback_pid != hdspm->capture_pid) &&
552 (hdspm->playback_pid >= 0) && (hdspm->capture_pid >= 0)) {
553 ret = 0;
554 }
555 spin_unlock_irqrestore(&hdspm->lock, flags);
556 return ret;
557}
558
559/* check for external sample rate */
560static inline int hdspm_external_sample_rate(hdspm_t * hdspm)
561{
562 unsigned int status2 = hdspm_read(hdspm, HDSPM_statusRegister2);
563 unsigned int status = hdspm_read(hdspm, HDSPM_statusRegister);
564 unsigned int rate_bits;
565 int rate = 0;
566
567 /* if wordclock has synced freq and wordclock is valid */
568 if ((status2 & HDSPM_wcLock) != 0 &&
569 (status & HDSPM_SelSyncRef0) == 0) {
570
571 rate_bits = status2 & HDSPM_wcFreqMask;
572
573 switch (rate_bits) {
574 case HDSPM_wcFreq32:
575 rate = 32000;
576 break;
577 case HDSPM_wcFreq44_1:
578 rate = 44100;
579 break;
580 case HDSPM_wcFreq48:
581 rate = 48000;
582 break;
583 case HDSPM_wcFreq64:
584 rate = 64000;
585 break;
586 case HDSPM_wcFreq88_2:
587 rate = 88200;
588 break;
589 case HDSPM_wcFreq96:
590 rate = 96000;
591 break;
592 /* Quadspeed Bit missing ???? */
593 default:
594 rate = 0;
595 break;
596 }
597 }
598
599 /* if rate detected and Syncref is Word than have it, word has priority to MADI */
600 if (rate != 0
601 && (status2 & HDSPM_SelSyncRefMask) == HDSPM_SelSyncRef_WORD)
602 return rate;
603
604 /* maby a madi input (which is taken if sel sync is madi) */
605 if (status & HDSPM_madiLock) {
606 rate_bits = status & HDSPM_madiFreqMask;
607
608 switch (rate_bits) {
609 case HDSPM_madiFreq32:
610 rate = 32000;
611 break;
612 case HDSPM_madiFreq44_1:
613 rate = 44100;
614 break;
615 case HDSPM_madiFreq48:
616 rate = 48000;
617 break;
618 case HDSPM_madiFreq64:
619 rate = 64000;
620 break;
621 case HDSPM_madiFreq88_2:
622 rate = 88200;
623 break;
624 case HDSPM_madiFreq96:
625 rate = 96000;
626 break;
627 case HDSPM_madiFreq128:
628 rate = 128000;
629 break;
630 case HDSPM_madiFreq176_4:
631 rate = 176400;
632 break;
633 case HDSPM_madiFreq192:
634 rate = 192000;
635 break;
636 default:
637 rate = 0;
638 break;
639 }
640 }
641 return rate;
642}
643
644/* Latency function */
645static inline void hdspm_compute_period_size(hdspm_t * hdspm)
646{
647 hdspm->period_bytes =
648 1 << ((hdspm_decode_latency(hdspm->control_register) + 8));
649}
650
651static snd_pcm_uframes_t hdspm_hw_pointer(hdspm_t * hdspm)
652{
653 int position;
654
655 position = hdspm_read(hdspm, HDSPM_statusRegister);
656
657 if (!hdspm->precise_ptr) {
658 return (position & HDSPM_BufferID) ? (hdspm->period_bytes /
659 4) : 0;
660 }
661
662 /* hwpointer comes in bytes and is 64Bytes accurate (by docu since PCI Burst)
663 i have experimented that it is at most 64 Byte to much for playing
664 so substraction of 64 byte should be ok for ALSA, but use it only
665 for application where you know what you do since if you come to
666 near with record pointer it can be a disaster */
667
668 position &= HDSPM_BufferPositionMask;
669 position = ((position - 64) % (2 * hdspm->period_bytes)) / 4;
670
671 return position;
672}
673
674
675static inline void hdspm_start_audio(hdspm_t * s)
676{
677 s->control_register |= (HDSPM_AudioInterruptEnable | HDSPM_Start);
678 hdspm_write(s, HDSPM_controlRegister, s->control_register);
679}
680
681static inline void hdspm_stop_audio(hdspm_t * s)
682{
683 s->control_register &= ~(HDSPM_Start | HDSPM_AudioInterruptEnable);
684 hdspm_write(s, HDSPM_controlRegister, s->control_register);
685}
686
687/* should I silence all or only opened ones ? doit all for first even is 4MB*/
688static inline void hdspm_silence_playback(hdspm_t * hdspm)
689{
690 int i;
691 int n = hdspm->period_bytes;
692 void *buf = hdspm->playback_buffer;
693
694 snd_assert(buf != NULL, return);
695
696 for (i = 0; i < HDSPM_MAX_CHANNELS; i++) {
697 memset(buf, 0, n);
698 buf += HDSPM_CHANNEL_BUFFER_BYTES;
699 }
700}
701
702static int hdspm_set_interrupt_interval(hdspm_t * s, unsigned int frames)
703{
704 int n;
705
706 spin_lock_irq(&s->lock);
707
708 frames >>= 7;
709 n = 0;
710 while (frames) {
711 n++;
712 frames >>= 1;
713 }
714 s->control_register &= ~HDSPM_LatencyMask;
715 s->control_register |= hdspm_encode_latency(n);
716
717 hdspm_write(s, HDSPM_controlRegister, s->control_register);
718
719 hdspm_compute_period_size(s);
720
721 spin_unlock_irq(&s->lock);
722
723 return 0;
724}
725
726
727/* dummy set rate lets see what happens */
728static int hdspm_set_rate(hdspm_t * hdspm, int rate, int called_internally)
729{
730 int reject_if_open = 0;
731 int current_rate;
732 int rate_bits;
733 int not_set = 0;
734
735 /* ASSUMPTION: hdspm->lock is either set, or there is no need for
736 it (e.g. during module initialization).
737 */
738
739 if (!(hdspm->control_register & HDSPM_ClockModeMaster)) {
740
741 /* SLAVE --- */
742 if (called_internally) {
743
744 /* request from ctl or card initialization
745 just make a warning an remember setting
746 for future master mode switching */
747
748 snd_printk
749 (KERN_WARNING "HDSPM: Warning: device is not running as a clock master.\n");
750 not_set = 1;
751 } else {
752
753 /* hw_param request while in AutoSync mode */
754 int external_freq =
755 hdspm_external_sample_rate(hdspm);
756
757 if ((hdspm_autosync_ref(hdspm) ==
758 HDSPM_AUTOSYNC_FROM_NONE)) {
759
760 snd_printk(KERN_WARNING "HDSPM: Detected no Externel Sync \n");
761 not_set = 1;
762
763 } else if (rate != external_freq) {
764
765 snd_printk
766 (KERN_WARNING "HDSPM: Warning: No AutoSync source for requested rate\n");
767 not_set = 1;
768 }
769 }
770 }
771
772 current_rate = hdspm->system_sample_rate;
773
774 /* Changing between Singe, Double and Quad speed is not
775 allowed if any substreams are open. This is because such a change
776 causes a shift in the location of the DMA buffers and a reduction
777 in the number of available buffers.
778
779 Note that a similar but essentially insoluble problem exists for
780 externally-driven rate changes. All we can do is to flag rate
781 changes in the read/write routines.
782 */
783
784 switch (rate) {
785 case 32000:
786 if (current_rate > 48000) {
787 reject_if_open = 1;
788 }
789 rate_bits = HDSPM_Frequency32KHz;
790 break;
791 case 44100:
792 if (current_rate > 48000) {
793 reject_if_open = 1;
794 }
795 rate_bits = HDSPM_Frequency44_1KHz;
796 break;
797 case 48000:
798 if (current_rate > 48000) {
799 reject_if_open = 1;
800 }
801 rate_bits = HDSPM_Frequency48KHz;
802 break;
803 case 64000:
804 if (current_rate <= 48000) {
805 reject_if_open = 1;
806 }
807 rate_bits = HDSPM_Frequency64KHz;
808 break;
809 case 88200:
810 if (current_rate <= 48000) {
811 reject_if_open = 1;
812 }
813 rate_bits = HDSPM_Frequency88_2KHz;
814 break;
815 case 96000:
816 if (current_rate <= 48000) {
817 reject_if_open = 1;
818 }
819 rate_bits = HDSPM_Frequency96KHz;
820 break;
821 default:
822 return -EINVAL;
823 }
824
825 if (reject_if_open
826 && (hdspm->capture_pid >= 0 || hdspm->playback_pid >= 0)) {
827 snd_printk
828 (KERN_ERR "HDSPM: cannot change between single- and double-speed mode (capture PID = %d, playback PID = %d)\n",
829 hdspm->capture_pid, hdspm->playback_pid);
830 return -EBUSY;
831 }
832
833 hdspm->control_register &= ~HDSPM_FrequencyMask;
834 hdspm->control_register |= rate_bits;
835 hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
836
837 if (rate > 64000)
838 hdspm->channel_map = channel_map_madi_qs;
839 else if (rate > 48000)
840 hdspm->channel_map = channel_map_madi_ds;
841 else
842 hdspm->channel_map = channel_map_madi_ss;
843
844 hdspm->system_sample_rate = rate;
845
846 if (not_set != 0)
847 return -1;
848
849 return 0;
850}
851
852/* mainly for init to 0 on load */
853static void all_in_all_mixer(hdspm_t * hdspm, int sgain)
854{
855 int i, j;
856 unsigned int gain =
857 (sgain > UNITY_GAIN) ? UNITY_GAIN : (sgain < 0) ? 0 : sgain;
858
859 for (i = 0; i < HDSPM_MIXER_CHANNELS; i++)
860 for (j = 0; j < HDSPM_MIXER_CHANNELS; j++) {
861 hdspm_write_in_gain(hdspm, i, j, gain);
862 hdspm_write_pb_gain(hdspm, i, j, gain);
863 }
864}
865
866/*----------------------------------------------------------------------------
867 MIDI
868 ----------------------------------------------------------------------------*/
869
870static inline unsigned char snd_hdspm_midi_read_byte (hdspm_t *hdspm, int id)
871{
872 /* the hardware already does the relevant bit-mask with 0xff */
873 if (id)
874 return hdspm_read(hdspm, HDSPM_midiDataIn1);
875 else
876 return hdspm_read(hdspm, HDSPM_midiDataIn0);
877}
878
879static inline void snd_hdspm_midi_write_byte (hdspm_t *hdspm, int id, int val)
880{
881 /* the hardware already does the relevant bit-mask with 0xff */
882 if (id)
883 return hdspm_write(hdspm, HDSPM_midiDataOut1, val);
884 else
885 return hdspm_write(hdspm, HDSPM_midiDataOut0, val);
886}
887
888static inline int snd_hdspm_midi_input_available (hdspm_t *hdspm, int id)
889{
890 if (id)
891 return (hdspm_read(hdspm, HDSPM_midiStatusIn1) & 0xff);
892 else
893 return (hdspm_read(hdspm, HDSPM_midiStatusIn0) & 0xff);
894}
895
896static inline int snd_hdspm_midi_output_possible (hdspm_t *hdspm, int id)
897{
898 int fifo_bytes_used;
899
900 if (id)
901 fifo_bytes_used = hdspm_read(hdspm, HDSPM_midiStatusOut1) & 0xff;
902 else
903 fifo_bytes_used = hdspm_read(hdspm, HDSPM_midiStatusOut0) & 0xff;
904
905 if (fifo_bytes_used < 128)
906 return 128 - fifo_bytes_used;
907 else
908 return 0;
909}
910
911static inline void snd_hdspm_flush_midi_input (hdspm_t *hdspm, int id)
912{
913 while (snd_hdspm_midi_input_available (hdspm, id))
914 snd_hdspm_midi_read_byte (hdspm, id);
915}
916
917static int snd_hdspm_midi_output_write (hdspm_midi_t *hmidi)
918{
919 unsigned long flags;
920 int n_pending;
921 int to_write;
922 int i;
923 unsigned char buf[128];
924
925 /* Output is not interrupt driven */
926
927 spin_lock_irqsave (&hmidi->lock, flags);
928 if (hmidi->output) {
929 if (!snd_rawmidi_transmit_empty (hmidi->output)) {
930 if ((n_pending = snd_hdspm_midi_output_possible (hmidi->hdspm, hmidi->id)) > 0) {
931 if (n_pending > (int)sizeof (buf))
932 n_pending = sizeof (buf);
933
934 if ((to_write = snd_rawmidi_transmit (hmidi->output, buf, n_pending)) > 0) {
935 for (i = 0; i < to_write; ++i)
936 snd_hdspm_midi_write_byte (hmidi->hdspm, hmidi->id, buf[i]);
937 }
938 }
939 }
940 }
941 spin_unlock_irqrestore (&hmidi->lock, flags);
942 return 0;
943}
944
945static int snd_hdspm_midi_input_read (hdspm_midi_t *hmidi)
946{
947 unsigned char buf[128]; /* this buffer is designed to match the MIDI input FIFO size */
948 unsigned long flags;
949 int n_pending;
950 int i;
951
952 spin_lock_irqsave (&hmidi->lock, flags);
953 if ((n_pending = snd_hdspm_midi_input_available (hmidi->hdspm, hmidi->id)) > 0) {
954 if (hmidi->input) {
955 if (n_pending > (int)sizeof (buf)) {
956 n_pending = sizeof (buf);
957 }
958 for (i = 0; i < n_pending; ++i) {
959 buf[i] = snd_hdspm_midi_read_byte (hmidi->hdspm, hmidi->id);
960 }
961 if (n_pending) {
962 snd_rawmidi_receive (hmidi->input, buf, n_pending);
963 }
964 } else {
965 /* flush the MIDI input FIFO */
966 while (n_pending--) {
967 snd_hdspm_midi_read_byte (hmidi->hdspm, hmidi->id);
968 }
969 }
970 }
971 hmidi->pending = 0;
972 if (hmidi->id) {
973 hmidi->hdspm->control_register |= HDSPM_Midi1InterruptEnable;
974 } else {
975 hmidi->hdspm->control_register |= HDSPM_Midi0InterruptEnable;
976 }
977 hdspm_write(hmidi->hdspm, HDSPM_controlRegister, hmidi->hdspm->control_register);
978 spin_unlock_irqrestore (&hmidi->lock, flags);
979 return snd_hdspm_midi_output_write (hmidi);
980}
981
982static void snd_hdspm_midi_input_trigger(snd_rawmidi_substream_t * substream, int up)
983{
984 hdspm_t *hdspm;
985 hdspm_midi_t *hmidi;
986 unsigned long flags;
987 u32 ie;
988
989 hmidi = (hdspm_midi_t *) substream->rmidi->private_data;
990 hdspm = hmidi->hdspm;
991 ie = hmidi->id ? HDSPM_Midi1InterruptEnable : HDSPM_Midi0InterruptEnable;
992 spin_lock_irqsave (&hdspm->lock, flags);
993 if (up) {
994 if (!(hdspm->control_register & ie)) {
995 snd_hdspm_flush_midi_input (hdspm, hmidi->id);
996 hdspm->control_register |= ie;
997 }
998 } else {
999 hdspm->control_register &= ~ie;
1000 }
1001
1002 hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
1003 spin_unlock_irqrestore (&hdspm->lock, flags);
1004}
1005
1006static void snd_hdspm_midi_output_timer(unsigned long data)
1007{
1008 hdspm_midi_t *hmidi = (hdspm_midi_t *) data;
1009 unsigned long flags;
1010
1011 snd_hdspm_midi_output_write(hmidi);
1012 spin_lock_irqsave (&hmidi->lock, flags);
1013
1014 /* this does not bump hmidi->istimer, because the
1015 kernel automatically removed the timer when it
1016 expired, and we are now adding it back, thus
1017 leaving istimer wherever it was set before.
1018 */
1019
1020 if (hmidi->istimer) {
1021 hmidi->timer.expires = 1 + jiffies;
1022 add_timer(&hmidi->timer);
1023 }
1024
1025 spin_unlock_irqrestore (&hmidi->lock, flags);
1026}
1027
1028static void snd_hdspm_midi_output_trigger(snd_rawmidi_substream_t * substream, int up)
1029{
1030 hdspm_midi_t *hmidi;
1031 unsigned long flags;
1032
1033 hmidi = (hdspm_midi_t *) substream->rmidi->private_data;
1034 spin_lock_irqsave (&hmidi->lock, flags);
1035 if (up) {
1036 if (!hmidi->istimer) {
1037 init_timer(&hmidi->timer);
1038 hmidi->timer.function = snd_hdspm_midi_output_timer;
1039 hmidi->timer.data = (unsigned long) hmidi;
1040 hmidi->timer.expires = 1 + jiffies;
1041 add_timer(&hmidi->timer);
1042 hmidi->istimer++;
1043 }
1044 } else {
1045 if (hmidi->istimer && --hmidi->istimer <= 0) {
1046 del_timer (&hmidi->timer);
1047 }
1048 }
1049 spin_unlock_irqrestore (&hmidi->lock, flags);
1050 if (up)
1051 snd_hdspm_midi_output_write(hmidi);
1052}
1053
1054static int snd_hdspm_midi_input_open(snd_rawmidi_substream_t * substream)
1055{
1056 hdspm_midi_t *hmidi;
1057
1058 hmidi = (hdspm_midi_t *) substream->rmidi->private_data;
1059 spin_lock_irq (&hmidi->lock);
1060 snd_hdspm_flush_midi_input (hmidi->hdspm, hmidi->id);
1061 hmidi->input = substream;
1062 spin_unlock_irq (&hmidi->lock);
1063
1064 return 0;
1065}
1066
1067static int snd_hdspm_midi_output_open(snd_rawmidi_substream_t * substream)
1068{
1069 hdspm_midi_t *hmidi;
1070
1071 hmidi = (hdspm_midi_t *) substream->rmidi->private_data;
1072 spin_lock_irq (&hmidi->lock);
1073 hmidi->output = substream;
1074 spin_unlock_irq (&hmidi->lock);
1075
1076 return 0;
1077}
1078
1079static int snd_hdspm_midi_input_close(snd_rawmidi_substream_t * substream)
1080{
1081 hdspm_midi_t *hmidi;
1082
1083 snd_hdspm_midi_input_trigger (substream, 0);
1084
1085 hmidi = (hdspm_midi_t *) substream->rmidi->private_data;
1086 spin_lock_irq (&hmidi->lock);
1087 hmidi->input = NULL;
1088 spin_unlock_irq (&hmidi->lock);
1089
1090 return 0;
1091}
1092
1093static int snd_hdspm_midi_output_close(snd_rawmidi_substream_t * substream)
1094{
1095 hdspm_midi_t *hmidi;
1096
1097 snd_hdspm_midi_output_trigger (substream, 0);
1098
1099 hmidi = (hdspm_midi_t *) substream->rmidi->private_data;
1100 spin_lock_irq (&hmidi->lock);
1101 hmidi->output = NULL;
1102 spin_unlock_irq (&hmidi->lock);
1103
1104 return 0;
1105}
1106
1107snd_rawmidi_ops_t snd_hdspm_midi_output =
1108{
1109 .open = snd_hdspm_midi_output_open,
1110 .close = snd_hdspm_midi_output_close,
1111 .trigger = snd_hdspm_midi_output_trigger,
1112};
1113
1114snd_rawmidi_ops_t snd_hdspm_midi_input =
1115{
1116 .open = snd_hdspm_midi_input_open,
1117 .close = snd_hdspm_midi_input_close,
1118 .trigger = snd_hdspm_midi_input_trigger,
1119};
1120
1121static int __devinit snd_hdspm_create_midi (snd_card_t *card, hdspm_t *hdspm, int id)
1122{
1123 int err;
1124 char buf[32];
1125
1126 hdspm->midi[id].id = id;
1127 hdspm->midi[id].rmidi = NULL;
1128 hdspm->midi[id].input = NULL;
1129 hdspm->midi[id].output = NULL;
1130 hdspm->midi[id].hdspm = hdspm;
1131 hdspm->midi[id].istimer = 0;
1132 hdspm->midi[id].pending = 0;
1133 spin_lock_init (&hdspm->midi[id].lock);
1134
1135 sprintf (buf, "%s MIDI %d", card->shortname, id+1);
1136 if ((err = snd_rawmidi_new (card, buf, id, 1, 1, &hdspm->midi[id].rmidi)) < 0)
1137 return err;
1138
1139 sprintf (hdspm->midi[id].rmidi->name, "%s MIDI %d", card->id, id+1);
1140 hdspm->midi[id].rmidi->private_data = &hdspm->midi[id];
1141
1142 snd_rawmidi_set_ops (hdspm->midi[id].rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_hdspm_midi_output);
1143 snd_rawmidi_set_ops (hdspm->midi[id].rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_hdspm_midi_input);
1144
1145 hdspm->midi[id].rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT |
1146 SNDRV_RAWMIDI_INFO_INPUT |
1147 SNDRV_RAWMIDI_INFO_DUPLEX;
1148
1149 return 0;
1150}
1151
1152
1153static void hdspm_midi_tasklet(unsigned long arg)
1154{
1155 hdspm_t *hdspm = (hdspm_t *)arg;
1156
1157 if (hdspm->midi[0].pending)
1158 snd_hdspm_midi_input_read (&hdspm->midi[0]);
1159 if (hdspm->midi[1].pending)
1160 snd_hdspm_midi_input_read (&hdspm->midi[1]);
1161}
1162
1163
1164/*-----------------------------------------------------------------------------
1165 Status Interface
1166 ----------------------------------------------------------------------------*/
1167
1168/* get the system sample rate which is set */
1169
1170#define HDSPM_SYSTEM_SAMPLE_RATE(xname, xindex) \
67ed4161 1171{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
763f356c
TI
1172 .name = xname, \
1173 .index = xindex, \
1174 .access = SNDRV_CTL_ELEM_ACCESS_READ, \
1175 .info = snd_hdspm_info_system_sample_rate, \
1176 .get = snd_hdspm_get_system_sample_rate \
1177}
1178
1179static int snd_hdspm_info_system_sample_rate(snd_kcontrol_t * kcontrol,
1180 snd_ctl_elem_info_t * uinfo)
1181{
1182 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1183 uinfo->count = 1;
1184 return 0;
1185}
1186
1187static int snd_hdspm_get_system_sample_rate(snd_kcontrol_t * kcontrol,
1188 snd_ctl_elem_value_t *
1189 ucontrol)
1190{
1191 hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
1192
1193 ucontrol->value.enumerated.item[0] = hdspm->system_sample_rate;
1194 return 0;
1195}
1196
1197#define HDSPM_AUTOSYNC_SAMPLE_RATE(xname, xindex) \
67ed4161 1198{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
763f356c
TI
1199 .name = xname, \
1200 .index = xindex, \
1201 .access = SNDRV_CTL_ELEM_ACCESS_READ, \
1202 .info = snd_hdspm_info_autosync_sample_rate, \
1203 .get = snd_hdspm_get_autosync_sample_rate \
1204}
1205
1206static int snd_hdspm_info_autosync_sample_rate(snd_kcontrol_t * kcontrol,
1207 snd_ctl_elem_info_t * uinfo)
1208{
1209 static char *texts[] = { "32000", "44100", "48000",
1210 "64000", "88200", "96000",
1211 "128000", "176400", "192000",
1212 "None"
1213 };
1214 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1215 uinfo->count = 1;
1216 uinfo->value.enumerated.items = 10;
1217 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1218 uinfo->value.enumerated.item =
1219 uinfo->value.enumerated.items - 1;
1220 strcpy(uinfo->value.enumerated.name,
1221 texts[uinfo->value.enumerated.item]);
1222 return 0;
1223}
1224
1225static int snd_hdspm_get_autosync_sample_rate(snd_kcontrol_t * kcontrol,
1226 snd_ctl_elem_value_t *
1227 ucontrol)
1228{
1229 hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
1230
1231 switch (hdspm_external_sample_rate(hdspm)) {
1232 case 32000:
1233 ucontrol->value.enumerated.item[0] = 0;
1234 break;
1235 case 44100:
1236 ucontrol->value.enumerated.item[0] = 1;
1237 break;
1238 case 48000:
1239 ucontrol->value.enumerated.item[0] = 2;
1240 break;
1241 case 64000:
1242 ucontrol->value.enumerated.item[0] = 3;
1243 break;
1244 case 88200:
1245 ucontrol->value.enumerated.item[0] = 4;
1246 break;
1247 case 96000:
1248 ucontrol->value.enumerated.item[0] = 5;
1249 break;
1250 case 128000:
1251 ucontrol->value.enumerated.item[0] = 6;
1252 break;
1253 case 176400:
1254 ucontrol->value.enumerated.item[0] = 7;
1255 break;
1256 case 192000:
1257 ucontrol->value.enumerated.item[0] = 8;
1258 break;
1259
1260 default:
1261 ucontrol->value.enumerated.item[0] = 9;
1262 }
1263 return 0;
1264}
1265
1266#define HDSPM_SYSTEM_CLOCK_MODE(xname, xindex) \
67ed4161 1267{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
763f356c
TI
1268 .name = xname, \
1269 .index = xindex, \
1270 .access = SNDRV_CTL_ELEM_ACCESS_READ, \
1271 .info = snd_hdspm_info_system_clock_mode, \
1272 .get = snd_hdspm_get_system_clock_mode, \
1273}
1274
1275
1276
1277static int hdspm_system_clock_mode(hdspm_t * hdspm)
1278{
1279 /* Always reflect the hardware info, rme is never wrong !!!! */
1280
1281 if (hdspm->control_register & HDSPM_ClockModeMaster)
1282 return 0;
1283 return 1;
1284}
1285
1286static int snd_hdspm_info_system_clock_mode(snd_kcontrol_t * kcontrol,
1287 snd_ctl_elem_info_t * uinfo)
1288{
1289 static char *texts[] = { "Master", "Slave" };
1290
1291 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1292 uinfo->count = 1;
1293 uinfo->value.enumerated.items = 2;
1294 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1295 uinfo->value.enumerated.item =
1296 uinfo->value.enumerated.items - 1;
1297 strcpy(uinfo->value.enumerated.name,
1298 texts[uinfo->value.enumerated.item]);
1299 return 0;
1300}
1301
1302static int snd_hdspm_get_system_clock_mode(snd_kcontrol_t * kcontrol,
1303 snd_ctl_elem_value_t * ucontrol)
1304{
1305 hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
1306
1307 ucontrol->value.enumerated.item[0] =
1308 hdspm_system_clock_mode(hdspm);
1309 return 0;
1310}
1311
1312#define HDSPM_CLOCK_SOURCE(xname, xindex) \
67ed4161 1313{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
763f356c
TI
1314 .name = xname, \
1315 .index = xindex, \
1316 .info = snd_hdspm_info_clock_source, \
1317 .get = snd_hdspm_get_clock_source, \
1318 .put = snd_hdspm_put_clock_source \
1319}
1320
1321static int hdspm_clock_source(hdspm_t * hdspm)
1322{
1323 if (hdspm->control_register & HDSPM_ClockModeMaster) {
1324 switch (hdspm->system_sample_rate) {
1325 case 32000:
1326 return 1;
1327 case 44100:
1328 return 2;
1329 case 48000:
1330 return 3;
1331 case 64000:
1332 return 4;
1333 case 88200:
1334 return 5;
1335 case 96000:
1336 return 6;
1337 case 128000:
1338 return 7;
1339 case 176400:
1340 return 8;
1341 case 192000:
1342 return 9;
1343 default:
1344 return 3;
1345 }
1346 } else {
1347 return 0;
1348 }
1349}
1350
1351static int hdspm_set_clock_source(hdspm_t * hdspm, int mode)
1352{
1353 int rate;
1354 switch (mode) {
1355
1356 case HDSPM_CLOCK_SOURCE_AUTOSYNC:
1357 if (hdspm_external_sample_rate(hdspm) != 0) {
1358 hdspm->control_register &= ~HDSPM_ClockModeMaster;
1359 hdspm_write(hdspm, HDSPM_controlRegister,
1360 hdspm->control_register);
1361 return 0;
1362 }
1363 return -1;
1364 case HDSPM_CLOCK_SOURCE_INTERNAL_32KHZ:
1365 rate = 32000;
1366 break;
1367 case HDSPM_CLOCK_SOURCE_INTERNAL_44_1KHZ:
1368 rate = 44100;
1369 break;
1370 case HDSPM_CLOCK_SOURCE_INTERNAL_48KHZ:
1371 rate = 48000;
1372 break;
1373 case HDSPM_CLOCK_SOURCE_INTERNAL_64KHZ:
1374 rate = 64000;
1375 break;
1376 case HDSPM_CLOCK_SOURCE_INTERNAL_88_2KHZ:
1377 rate = 88200;
1378 break;
1379 case HDSPM_CLOCK_SOURCE_INTERNAL_96KHZ:
1380 rate = 96000;
1381 break;
1382 case HDSPM_CLOCK_SOURCE_INTERNAL_128KHZ:
1383 rate = 128000;
1384 break;
1385 case HDSPM_CLOCK_SOURCE_INTERNAL_176_4KHZ:
1386 rate = 176400;
1387 break;
1388 case HDSPM_CLOCK_SOURCE_INTERNAL_192KHZ:
1389 rate = 192000;
1390 break;
1391
1392 default:
1393 rate = 44100;
1394 }
1395 hdspm->control_register |= HDSPM_ClockModeMaster;
1396 hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
1397 hdspm_set_rate(hdspm, rate, 1);
1398 return 0;
1399}
1400
1401static int snd_hdspm_info_clock_source(snd_kcontrol_t * kcontrol,
1402 snd_ctl_elem_info_t * uinfo)
1403{
1404 static char *texts[] = { "AutoSync",
1405 "Internal 32.0 kHz", "Internal 44.1 kHz",
1406 "Internal 48.0 kHz",
1407 "Internal 64.0 kHz", "Internal 88.2 kHz",
1408 "Internal 96.0 kHz",
1409 "Internal 128.0 kHz", "Internal 176.4 kHz",
1410 "Internal 192.0 kHz"
1411 };
1412
1413 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1414 uinfo->count = 1;
1415 uinfo->value.enumerated.items = 10;
1416
1417 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1418 uinfo->value.enumerated.item =
1419 uinfo->value.enumerated.items - 1;
1420
1421 strcpy(uinfo->value.enumerated.name,
1422 texts[uinfo->value.enumerated.item]);
1423
1424 return 0;
1425}
1426
1427static int snd_hdspm_get_clock_source(snd_kcontrol_t * kcontrol,
1428 snd_ctl_elem_value_t * ucontrol)
1429{
1430 hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
1431
1432 ucontrol->value.enumerated.item[0] = hdspm_clock_source(hdspm);
1433 return 0;
1434}
1435
1436static int snd_hdspm_put_clock_source(snd_kcontrol_t * kcontrol,
1437 snd_ctl_elem_value_t * ucontrol)
1438{
1439 hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
1440 int change;
1441 int val;
1442
1443 if (!snd_hdspm_use_is_exclusive(hdspm))
1444 return -EBUSY;
1445 val = ucontrol->value.enumerated.item[0];
1446 if (val < 0)
1447 val = 0;
1448 if (val > 6)
1449 val = 6;
1450 spin_lock_irq(&hdspm->lock);
1451 if (val != hdspm_clock_source(hdspm))
1452 change = (hdspm_set_clock_source(hdspm, val) == 0) ? 1 : 0;
1453 else
1454 change = 0;
1455 spin_unlock_irq(&hdspm->lock);
1456 return change;
1457}
1458
1459#define HDSPM_PREF_SYNC_REF(xname, xindex) \
67ed4161 1460{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
763f356c
TI
1461 .name = xname, \
1462 .index = xindex, \
1463 .info = snd_hdspm_info_pref_sync_ref, \
1464 .get = snd_hdspm_get_pref_sync_ref, \
1465 .put = snd_hdspm_put_pref_sync_ref \
1466}
1467
1468static int hdspm_pref_sync_ref(hdspm_t * hdspm)
1469{
1470 /* Notice that this looks at the requested sync source,
1471 not the one actually in use.
1472 */
1473 switch (hdspm->control_register & HDSPM_SyncRefMask) {
1474 case HDSPM_SyncRef_Word:
1475 return HDSPM_SYNC_FROM_WORD;
1476 case HDSPM_SyncRef_MADI:
1477 return HDSPM_SYNC_FROM_MADI;
1478 }
1479
1480 return HDSPM_SYNC_FROM_WORD;
1481}
1482
1483static int hdspm_set_pref_sync_ref(hdspm_t * hdspm, int pref)
1484{
1485 hdspm->control_register &= ~HDSPM_SyncRefMask;
1486
1487 switch (pref) {
1488 case HDSPM_SYNC_FROM_MADI:
1489 hdspm->control_register |= HDSPM_SyncRef_MADI;
1490 break;
1491 case HDSPM_SYNC_FROM_WORD:
1492 hdspm->control_register |= HDSPM_SyncRef_Word;
1493 break;
1494 default:
1495 return -1;
1496 }
1497 hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
1498 return 0;
1499}
1500
1501static int snd_hdspm_info_pref_sync_ref(snd_kcontrol_t * kcontrol,
1502 snd_ctl_elem_info_t * uinfo)
1503{
1504 static char *texts[] = { "Word", "MADI" };
1505
1506 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1507 uinfo->count = 1;
1508
1509 uinfo->value.enumerated.items = 2;
1510
1511 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1512 uinfo->value.enumerated.item =
1513 uinfo->value.enumerated.items - 1;
1514 strcpy(uinfo->value.enumerated.name,
1515 texts[uinfo->value.enumerated.item]);
1516 return 0;
1517}
1518
1519static int snd_hdspm_get_pref_sync_ref(snd_kcontrol_t * kcontrol,
1520 snd_ctl_elem_value_t * ucontrol)
1521{
1522 hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
1523
1524 ucontrol->value.enumerated.item[0] = hdspm_pref_sync_ref(hdspm);
1525 return 0;
1526}
1527
1528static int snd_hdspm_put_pref_sync_ref(snd_kcontrol_t * kcontrol,
1529 snd_ctl_elem_value_t * ucontrol)
1530{
1531 hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
1532 int change, max;
1533 unsigned int val;
1534
1535 max = 2;
1536
1537 if (!snd_hdspm_use_is_exclusive(hdspm))
1538 return -EBUSY;
1539
1540 val = ucontrol->value.enumerated.item[0] % max;
1541
1542 spin_lock_irq(&hdspm->lock);
1543 change = (int) val != hdspm_pref_sync_ref(hdspm);
1544 hdspm_set_pref_sync_ref(hdspm, val);
1545 spin_unlock_irq(&hdspm->lock);
1546 return change;
1547}
1548
1549#define HDSPM_AUTOSYNC_REF(xname, xindex) \
67ed4161 1550{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
763f356c
TI
1551 .name = xname, \
1552 .index = xindex, \
1553 .access = SNDRV_CTL_ELEM_ACCESS_READ, \
1554 .info = snd_hdspm_info_autosync_ref, \
1555 .get = snd_hdspm_get_autosync_ref, \
1556}
1557
1558static int hdspm_autosync_ref(hdspm_t * hdspm)
1559{
1560 /* This looks at the autosync selected sync reference */
1561 unsigned int status2 = hdspm_read(hdspm, HDSPM_statusRegister2);
1562
1563 switch (status2 & HDSPM_SelSyncRefMask) {
1564
1565 case HDSPM_SelSyncRef_WORD:
1566 return HDSPM_AUTOSYNC_FROM_WORD;
1567
1568 case HDSPM_SelSyncRef_MADI:
1569 return HDSPM_AUTOSYNC_FROM_MADI;
1570
1571 case HDSPM_SelSyncRef_NVALID:
1572 return HDSPM_AUTOSYNC_FROM_NONE;
1573
1574 default:
1575 return 0;
1576 }
1577
1578 return 0;
1579}
1580
1581static int snd_hdspm_info_autosync_ref(snd_kcontrol_t * kcontrol,
1582 snd_ctl_elem_info_t * uinfo)
1583{
1584 static char *texts[] = { "WordClock", "MADI", "None" };
1585
1586 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1587 uinfo->count = 1;
1588 uinfo->value.enumerated.items = 3;
1589 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1590 uinfo->value.enumerated.item =
1591 uinfo->value.enumerated.items - 1;
1592 strcpy(uinfo->value.enumerated.name,
1593 texts[uinfo->value.enumerated.item]);
1594 return 0;
1595}
1596
1597static int snd_hdspm_get_autosync_ref(snd_kcontrol_t * kcontrol,
1598 snd_ctl_elem_value_t * ucontrol)
1599{
1600 hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
1601
1602 ucontrol->value.enumerated.item[0] = hdspm_pref_sync_ref(hdspm);
1603 return 0;
1604}
1605
1606#define HDSPM_LINE_OUT(xname, xindex) \
67ed4161 1607{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
763f356c
TI
1608 .name = xname, \
1609 .index = xindex, \
1610 .info = snd_hdspm_info_line_out, \
1611 .get = snd_hdspm_get_line_out, \
1612 .put = snd_hdspm_put_line_out \
1613}
1614
1615static int hdspm_line_out(hdspm_t * hdspm)
1616{
1617 return (hdspm->control_register & HDSPM_LineOut) ? 1 : 0;
1618}
1619
1620
1621static int hdspm_set_line_output(hdspm_t * hdspm, int out)
1622{
1623 if (out)
1624 hdspm->control_register |= HDSPM_LineOut;
1625 else
1626 hdspm->control_register &= ~HDSPM_LineOut;
1627 hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
1628
1629 return 0;
1630}
1631
1632static int snd_hdspm_info_line_out(snd_kcontrol_t * kcontrol,
1633 snd_ctl_elem_info_t * uinfo)
1634{
1635 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1636 uinfo->count = 1;
1637 uinfo->value.integer.min = 0;
1638 uinfo->value.integer.max = 1;
1639 return 0;
1640}
1641
1642static int snd_hdspm_get_line_out(snd_kcontrol_t * kcontrol,
1643 snd_ctl_elem_value_t * ucontrol)
1644{
1645 hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
1646
1647 spin_lock_irq(&hdspm->lock);
1648 ucontrol->value.integer.value[0] = hdspm_line_out(hdspm);
1649 spin_unlock_irq(&hdspm->lock);
1650 return 0;
1651}
1652
1653static int snd_hdspm_put_line_out(snd_kcontrol_t * kcontrol,
1654 snd_ctl_elem_value_t * ucontrol)
1655{
1656 hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
1657 int change;
1658 unsigned int val;
1659
1660 if (!snd_hdspm_use_is_exclusive(hdspm))
1661 return -EBUSY;
1662 val = ucontrol->value.integer.value[0] & 1;
1663 spin_lock_irq(&hdspm->lock);
1664 change = (int) val != hdspm_line_out(hdspm);
1665 hdspm_set_line_output(hdspm, val);
1666 spin_unlock_irq(&hdspm->lock);
1667 return change;
1668}
1669
1670#define HDSPM_TX_64(xname, xindex) \
67ed4161 1671{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
763f356c
TI
1672 .name = xname, \
1673 .index = xindex, \
1674 .info = snd_hdspm_info_tx_64, \
1675 .get = snd_hdspm_get_tx_64, \
1676 .put = snd_hdspm_put_tx_64 \
1677}
1678
1679static int hdspm_tx_64(hdspm_t * hdspm)
1680{
1681 return (hdspm->control_register & HDSPM_TX_64ch) ? 1 : 0;
1682}
1683
1684static int hdspm_set_tx_64(hdspm_t * hdspm, int out)
1685{
1686 if (out)
1687 hdspm->control_register |= HDSPM_TX_64ch;
1688 else
1689 hdspm->control_register &= ~HDSPM_TX_64ch;
1690 hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
1691
1692 return 0;
1693}
1694
1695static int snd_hdspm_info_tx_64(snd_kcontrol_t * kcontrol,
1696 snd_ctl_elem_info_t * uinfo)
1697{
1698 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1699 uinfo->count = 1;
1700 uinfo->value.integer.min = 0;
1701 uinfo->value.integer.max = 1;
1702 return 0;
1703}
1704
1705static int snd_hdspm_get_tx_64(snd_kcontrol_t * kcontrol,
1706 snd_ctl_elem_value_t * ucontrol)
1707{
1708 hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
1709
1710 spin_lock_irq(&hdspm->lock);
1711 ucontrol->value.integer.value[0] = hdspm_tx_64(hdspm);
1712 spin_unlock_irq(&hdspm->lock);
1713 return 0;
1714}
1715
1716static int snd_hdspm_put_tx_64(snd_kcontrol_t * kcontrol,
1717 snd_ctl_elem_value_t * ucontrol)
1718{
1719 hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
1720 int change;
1721 unsigned int val;
1722
1723 if (!snd_hdspm_use_is_exclusive(hdspm))
1724 return -EBUSY;
1725 val = ucontrol->value.integer.value[0] & 1;
1726 spin_lock_irq(&hdspm->lock);
1727 change = (int) val != hdspm_tx_64(hdspm);
1728 hdspm_set_tx_64(hdspm, val);
1729 spin_unlock_irq(&hdspm->lock);
1730 return change;
1731}
1732
1733#define HDSPM_C_TMS(xname, xindex) \
67ed4161 1734{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
763f356c
TI
1735 .name = xname, \
1736 .index = xindex, \
1737 .info = snd_hdspm_info_c_tms, \
1738 .get = snd_hdspm_get_c_tms, \
1739 .put = snd_hdspm_put_c_tms \
1740}
1741
1742static int hdspm_c_tms(hdspm_t * hdspm)
1743{
1744 return (hdspm->control_register & HDSPM_clr_tms) ? 1 : 0;
1745}
1746
1747static int hdspm_set_c_tms(hdspm_t * hdspm, int out)
1748{
1749 if (out)
1750 hdspm->control_register |= HDSPM_clr_tms;
1751 else
1752 hdspm->control_register &= ~HDSPM_clr_tms;
1753 hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
1754
1755 return 0;
1756}
1757
1758static int snd_hdspm_info_c_tms(snd_kcontrol_t * kcontrol,
1759 snd_ctl_elem_info_t * uinfo)
1760{
1761 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1762 uinfo->count = 1;
1763 uinfo->value.integer.min = 0;
1764 uinfo->value.integer.max = 1;
1765 return 0;
1766}
1767
1768static int snd_hdspm_get_c_tms(snd_kcontrol_t * kcontrol,
1769 snd_ctl_elem_value_t * ucontrol)
1770{
1771 hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
1772
1773 spin_lock_irq(&hdspm->lock);
1774 ucontrol->value.integer.value[0] = hdspm_c_tms(hdspm);
1775 spin_unlock_irq(&hdspm->lock);
1776 return 0;
1777}
1778
1779static int snd_hdspm_put_c_tms(snd_kcontrol_t * kcontrol,
1780 snd_ctl_elem_value_t * ucontrol)
1781{
1782 hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
1783 int change;
1784 unsigned int val;
1785
1786 if (!snd_hdspm_use_is_exclusive(hdspm))
1787 return -EBUSY;
1788 val = ucontrol->value.integer.value[0] & 1;
1789 spin_lock_irq(&hdspm->lock);
1790 change = (int) val != hdspm_c_tms(hdspm);
1791 hdspm_set_c_tms(hdspm, val);
1792 spin_unlock_irq(&hdspm->lock);
1793 return change;
1794}
1795
1796#define HDSPM_SAFE_MODE(xname, xindex) \
67ed4161 1797{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
763f356c
TI
1798 .name = xname, \
1799 .index = xindex, \
1800 .info = snd_hdspm_info_safe_mode, \
1801 .get = snd_hdspm_get_safe_mode, \
1802 .put = snd_hdspm_put_safe_mode \
1803}
1804
1805static int hdspm_safe_mode(hdspm_t * hdspm)
1806{
1807 return (hdspm->control_register & HDSPM_AutoInp) ? 1 : 0;
1808}
1809
1810static int hdspm_set_safe_mode(hdspm_t * hdspm, int out)
1811{
1812 if (out)
1813 hdspm->control_register |= HDSPM_AutoInp;
1814 else
1815 hdspm->control_register &= ~HDSPM_AutoInp;
1816 hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
1817
1818 return 0;
1819}
1820
1821static int snd_hdspm_info_safe_mode(snd_kcontrol_t * kcontrol,
1822 snd_ctl_elem_info_t * uinfo)
1823{
1824 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1825 uinfo->count = 1;
1826 uinfo->value.integer.min = 0;
1827 uinfo->value.integer.max = 1;
1828 return 0;
1829}
1830
1831static int snd_hdspm_get_safe_mode(snd_kcontrol_t * kcontrol,
1832 snd_ctl_elem_value_t * ucontrol)
1833{
1834 hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
1835
1836 spin_lock_irq(&hdspm->lock);
1837 ucontrol->value.integer.value[0] = hdspm_safe_mode(hdspm);
1838 spin_unlock_irq(&hdspm->lock);
1839 return 0;
1840}
1841
1842static int snd_hdspm_put_safe_mode(snd_kcontrol_t * kcontrol,
1843 snd_ctl_elem_value_t * ucontrol)
1844{
1845 hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
1846 int change;
1847 unsigned int val;
1848
1849 if (!snd_hdspm_use_is_exclusive(hdspm))
1850 return -EBUSY;
1851 val = ucontrol->value.integer.value[0] & 1;
1852 spin_lock_irq(&hdspm->lock);
1853 change = (int) val != hdspm_safe_mode(hdspm);
1854 hdspm_set_safe_mode(hdspm, val);
1855 spin_unlock_irq(&hdspm->lock);
1856 return change;
1857}
1858
1859#define HDSPM_INPUT_SELECT(xname, xindex) \
67ed4161 1860{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
763f356c
TI
1861 .name = xname, \
1862 .index = xindex, \
1863 .info = snd_hdspm_info_input_select, \
1864 .get = snd_hdspm_get_input_select, \
1865 .put = snd_hdspm_put_input_select \
1866}
1867
1868static int hdspm_input_select(hdspm_t * hdspm)
1869{
1870 return (hdspm->control_register & HDSPM_InputSelect0) ? 1 : 0;
1871}
1872
1873static int hdspm_set_input_select(hdspm_t * hdspm, int out)
1874{
1875 if (out)
1876 hdspm->control_register |= HDSPM_InputSelect0;
1877 else
1878 hdspm->control_register &= ~HDSPM_InputSelect0;
1879 hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
1880
1881 return 0;
1882}
1883
1884static int snd_hdspm_info_input_select(snd_kcontrol_t * kcontrol,
1885 snd_ctl_elem_info_t * uinfo)
1886{
1887 static char *texts[] = { "optical", "coaxial" };
1888
1889 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1890 uinfo->count = 1;
1891 uinfo->value.enumerated.items = 2;
1892
1893 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1894 uinfo->value.enumerated.item =
1895 uinfo->value.enumerated.items - 1;
1896 strcpy(uinfo->value.enumerated.name,
1897 texts[uinfo->value.enumerated.item]);
1898
1899 return 0;
1900}
1901
1902static int snd_hdspm_get_input_select(snd_kcontrol_t * kcontrol,
1903 snd_ctl_elem_value_t * ucontrol)
1904{
1905 hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
1906
1907 spin_lock_irq(&hdspm->lock);
1908 ucontrol->value.enumerated.item[0] = hdspm_input_select(hdspm);
1909 spin_unlock_irq(&hdspm->lock);
1910 return 0;
1911}
1912
1913static int snd_hdspm_put_input_select(snd_kcontrol_t * kcontrol,
1914 snd_ctl_elem_value_t * ucontrol)
1915{
1916 hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
1917 int change;
1918 unsigned int val;
1919
1920 if (!snd_hdspm_use_is_exclusive(hdspm))
1921 return -EBUSY;
1922 val = ucontrol->value.integer.value[0] & 1;
1923 spin_lock_irq(&hdspm->lock);
1924 change = (int) val != hdspm_input_select(hdspm);
1925 hdspm_set_input_select(hdspm, val);
1926 spin_unlock_irq(&hdspm->lock);
1927 return change;
1928}
1929
1930/* Simple Mixer
1931 deprecated since to much faders ???
1932 MIXER interface says output (source, destination, value)
1933 where source > MAX_channels are playback channels
1934 on MADICARD
1935 - playback mixer matrix: [channelout+64] [output] [value]
1936 - input(thru) mixer matrix: [channelin] [output] [value]
1937 (better do 2 kontrols for seperation ?)
1938*/
1939
1940#define HDSPM_MIXER(xname, xindex) \
1941{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \
1942 .name = xname, \
1943 .index = xindex, \
67ed4161 1944 .device = 0, \
763f356c
TI
1945 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
1946 SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
1947 .info = snd_hdspm_info_mixer, \
1948 .get = snd_hdspm_get_mixer, \
1949 .put = snd_hdspm_put_mixer \
1950}
1951
1952static int snd_hdspm_info_mixer(snd_kcontrol_t * kcontrol,
1953 snd_ctl_elem_info_t * uinfo)
1954{
1955 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1956 uinfo->count = 3;
1957 uinfo->value.integer.min = 0;
1958 uinfo->value.integer.max = 65535;
1959 uinfo->value.integer.step = 1;
1960 return 0;
1961}
1962
1963static int snd_hdspm_get_mixer(snd_kcontrol_t * kcontrol,
1964 snd_ctl_elem_value_t * ucontrol)
1965{
1966 hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
1967 int source;
1968 int destination;
1969
1970 source = ucontrol->value.integer.value[0];
1971 if (source < 0)
1972 source = 0;
1973 else if (source >= 2 * HDSPM_MAX_CHANNELS)
1974 source = 2 * HDSPM_MAX_CHANNELS - 1;
1975
1976 destination = ucontrol->value.integer.value[1];
1977 if (destination < 0)
1978 destination = 0;
1979 else if (destination >= HDSPM_MAX_CHANNELS)
1980 destination = HDSPM_MAX_CHANNELS - 1;
1981
1982 spin_lock_irq(&hdspm->lock);
1983 if (source >= HDSPM_MAX_CHANNELS)
1984 ucontrol->value.integer.value[2] =
1985 hdspm_read_pb_gain(hdspm, destination,
1986 source - HDSPM_MAX_CHANNELS);
1987 else
1988 ucontrol->value.integer.value[2] =
1989 hdspm_read_in_gain(hdspm, destination, source);
1990
1991 spin_unlock_irq(&hdspm->lock);
1992
1993 return 0;
1994}
1995
1996static int snd_hdspm_put_mixer(snd_kcontrol_t * kcontrol,
1997 snd_ctl_elem_value_t * ucontrol)
1998{
1999 hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
2000 int change;
2001 int source;
2002 int destination;
2003 int gain;
2004
2005 if (!snd_hdspm_use_is_exclusive(hdspm))
2006 return -EBUSY;
2007
2008 source = ucontrol->value.integer.value[0];
2009 destination = ucontrol->value.integer.value[1];
2010
2011 if (source < 0 || source >= 2 * HDSPM_MAX_CHANNELS)
2012 return -1;
2013 if (destination < 0 || destination >= HDSPM_MAX_CHANNELS)
2014 return -1;
2015
2016 gain = ucontrol->value.integer.value[2];
2017
2018 spin_lock_irq(&hdspm->lock);
2019
2020 if (source >= HDSPM_MAX_CHANNELS)
2021 change = gain != hdspm_read_pb_gain(hdspm, destination,
2022 source -
2023 HDSPM_MAX_CHANNELS);
2024 else
2025 change =
2026 gain != hdspm_read_in_gain(hdspm, destination, source);
2027
2028 if (change) {
2029 if (source >= HDSPM_MAX_CHANNELS)
2030 hdspm_write_pb_gain(hdspm, destination,
2031 source - HDSPM_MAX_CHANNELS,
2032 gain);
2033 else
2034 hdspm_write_in_gain(hdspm, destination, source,
2035 gain);
2036 }
2037 spin_unlock_irq(&hdspm->lock);
2038
2039 return change;
2040}
2041
2042/* The simple mixer control(s) provide gain control for the
2043 basic 1:1 mappings of playback streams to output
2044 streams.
2045*/
2046
2047#define HDSPM_PLAYBACK_MIXER \
2048{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2049 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_WRITE | \
2050 SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
2051 .info = snd_hdspm_info_playback_mixer, \
2052 .get = snd_hdspm_get_playback_mixer, \
2053 .put = snd_hdspm_put_playback_mixer \
2054}
2055
2056static int snd_hdspm_info_playback_mixer(snd_kcontrol_t * kcontrol,
2057 snd_ctl_elem_info_t * uinfo)
2058{
2059 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2060 uinfo->count = 1;
2061 uinfo->value.integer.min = 0;
2062 uinfo->value.integer.max = 65536;
2063 uinfo->value.integer.step = 1;
2064 return 0;
2065}
2066
2067static int snd_hdspm_get_playback_mixer(snd_kcontrol_t * kcontrol,
2068 snd_ctl_elem_value_t * ucontrol)
2069{
2070 hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
2071 int channel;
2072 int mapped_channel;
2073
2074 channel = ucontrol->id.index - 1;
2075
2076 snd_assert(channel >= 0
2077 || channel < HDSPM_MAX_CHANNELS, return -EINVAL);
2078
2079 if ((mapped_channel = hdspm->channel_map[channel]) < 0)
2080 return -EINVAL;
2081
2082 spin_lock_irq(&hdspm->lock);
2083 ucontrol->value.integer.value[0] =
2084 hdspm_read_pb_gain(hdspm, mapped_channel, mapped_channel);
2085 spin_unlock_irq(&hdspm->lock);
2086
2087 /* snd_printdd("get pb mixer index %d, channel %d, mapped_channel %d, value %d\n",
2088 ucontrol->id.index, channel, mapped_channel, ucontrol->value.integer.value[0]);
2089 */
2090
2091 return 0;
2092}
2093
2094static int snd_hdspm_put_playback_mixer(snd_kcontrol_t * kcontrol,
2095 snd_ctl_elem_value_t * ucontrol)
2096{
2097 hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
2098 int change;
2099 int channel;
2100 int mapped_channel;
2101 int gain;
2102
2103 if (!snd_hdspm_use_is_exclusive(hdspm))
2104 return -EBUSY;
2105
2106 channel = ucontrol->id.index - 1;
2107
2108 snd_assert(channel >= 0
2109 || channel < HDSPM_MAX_CHANNELS, return -EINVAL);
2110
2111 if ((mapped_channel = hdspm->channel_map[channel]) < 0)
2112 return -EINVAL;
2113
2114 gain = ucontrol->value.integer.value[0];
2115
2116 spin_lock_irq(&hdspm->lock);
2117 change =
2118 gain != hdspm_read_pb_gain(hdspm, mapped_channel,
2119 mapped_channel);
2120 if (change)
2121 hdspm_write_pb_gain(hdspm, mapped_channel, mapped_channel,
2122 gain);
2123 spin_unlock_irq(&hdspm->lock);
2124 return change;
2125}
2126
2127#define HDSPM_WC_SYNC_CHECK(xname, xindex) \
67ed4161 2128{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
763f356c
TI
2129 .name = xname, \
2130 .index = xindex, \
2131 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
2132 .info = snd_hdspm_info_sync_check, \
2133 .get = snd_hdspm_get_wc_sync_check \
2134}
2135
2136static int snd_hdspm_info_sync_check(snd_kcontrol_t * kcontrol,
2137 snd_ctl_elem_info_t * uinfo)
2138{
2139 static char *texts[] = { "No Lock", "Lock", "Sync" };
2140 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2141 uinfo->count = 1;
2142 uinfo->value.enumerated.items = 3;
2143 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
2144 uinfo->value.enumerated.item =
2145 uinfo->value.enumerated.items - 1;
2146 strcpy(uinfo->value.enumerated.name,
2147 texts[uinfo->value.enumerated.item]);
2148 return 0;
2149}
2150
2151static int hdspm_wc_sync_check(hdspm_t * hdspm)
2152{
2153 int status2 = hdspm_read(hdspm, HDSPM_statusRegister2);
2154 if (status2 & HDSPM_wcLock) {
2155 if (status2 & HDSPM_wcSync)
2156 return 2;
2157 else
2158 return 1;
2159 }
2160 return 0;
2161}
2162
2163static int snd_hdspm_get_wc_sync_check(snd_kcontrol_t * kcontrol,
2164 snd_ctl_elem_value_t * ucontrol)
2165{
2166 hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
2167
2168 ucontrol->value.enumerated.item[0] = hdspm_wc_sync_check(hdspm);
2169 return 0;
2170}
2171
2172
2173#define HDSPM_MADI_SYNC_CHECK(xname, xindex) \
67ed4161 2174{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
763f356c
TI
2175 .name = xname, \
2176 .index = xindex, \
2177 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
2178 .info = snd_hdspm_info_sync_check, \
2179 .get = snd_hdspm_get_madisync_sync_check \
2180}
2181
2182static int hdspm_madisync_sync_check(hdspm_t * hdspm)
2183{
2184 int status = hdspm_read(hdspm, HDSPM_statusRegister);
2185 if (status & HDSPM_madiLock) {
2186 if (status & HDSPM_madiSync)
2187 return 2;
2188 else
2189 return 1;
2190 }
2191 return 0;
2192}
2193
2194static int snd_hdspm_get_madisync_sync_check(snd_kcontrol_t * kcontrol,
2195 snd_ctl_elem_value_t *
2196 ucontrol)
2197{
2198 hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
2199
2200 ucontrol->value.enumerated.item[0] =
2201 hdspm_madisync_sync_check(hdspm);
2202 return 0;
2203}
2204
2205
2206
2207
2208static snd_kcontrol_new_t snd_hdspm_controls[] = {
2209
2210 HDSPM_MIXER("Mixer", 0),
2211/* 'Sample Clock Source' complies with the alsa control naming scheme */
2212 HDSPM_CLOCK_SOURCE("Sample Clock Source", 0),
2213
2214 HDSPM_SYSTEM_CLOCK_MODE("System Clock Mode", 0),
2215 HDSPM_PREF_SYNC_REF("Preferred Sync Reference", 0),
2216 HDSPM_AUTOSYNC_REF("AutoSync Reference", 0),
2217 HDSPM_SYSTEM_SAMPLE_RATE("System Sample Rate", 0),
2218/* 'External Rate' complies with the alsa control naming scheme */
2219 HDSPM_AUTOSYNC_SAMPLE_RATE("External Rate", 0),
2220 HDSPM_WC_SYNC_CHECK("Word Clock Lock Status", 0),
2221 HDSPM_MADI_SYNC_CHECK("MADI Sync Lock Status", 0),
2222 HDSPM_LINE_OUT("Line Out", 0),
2223 HDSPM_TX_64("TX 64 channels mode", 0),
2224 HDSPM_C_TMS("Clear Track Marker", 0),
2225 HDSPM_SAFE_MODE("Safe Mode", 0),
2226 HDSPM_INPUT_SELECT("Input Select", 0),
2227};
2228
2229static snd_kcontrol_new_t snd_hdspm_playback_mixer = HDSPM_PLAYBACK_MIXER;
2230
2231
2232static int hdspm_update_simple_mixer_controls(hdspm_t * hdspm)
2233{
2234 int i;
2235
2236 for (i = hdspm->ds_channels; i < hdspm->ss_channels; ++i) {
2237 if (hdspm->system_sample_rate > 48000) {
2238 hdspm->playback_mixer_ctls[i]->vd[0].access =
2239 SNDRV_CTL_ELEM_ACCESS_INACTIVE |
2240 SNDRV_CTL_ELEM_ACCESS_READ |
2241 SNDRV_CTL_ELEM_ACCESS_VOLATILE;
2242 } else {
2243 hdspm->playback_mixer_ctls[i]->vd[0].access =
2244 SNDRV_CTL_ELEM_ACCESS_READWRITE |
2245 SNDRV_CTL_ELEM_ACCESS_VOLATILE;
2246 }
2247 snd_ctl_notify(hdspm->card, SNDRV_CTL_EVENT_MASK_VALUE |
2248 SNDRV_CTL_EVENT_MASK_INFO,
2249 &hdspm->playback_mixer_ctls[i]->id);
2250 }
2251
2252 return 0;
2253}
2254
2255
2256static int snd_hdspm_create_controls(snd_card_t * card, hdspm_t * hdspm)
2257{
2258 unsigned int idx, limit;
2259 int err;
2260 snd_kcontrol_t *kctl;
2261
2262 /* add control list first */
2263
2264 for (idx = 0; idx < ARRAY_SIZE(snd_hdspm_controls); idx++) {
2265 if ((err =
2266 snd_ctl_add(card, kctl =
2267 snd_ctl_new1(&snd_hdspm_controls[idx],
2268 hdspm))) < 0) {
2269 return err;
2270 }
2271 }
2272
2273 /* Channel playback mixer as default control
2274 Note: the whole matrix would be 128*HDSPM_MIXER_CHANNELS Faders, thats to big for any alsamixer
2275 they are accesible via special IOCTL on hwdep
2276 and the mixer 2dimensional mixer control */
2277
2278 snd_hdspm_playback_mixer.name = "Chn";
2279 limit = HDSPM_MAX_CHANNELS;
2280
2281 /* The index values are one greater than the channel ID so that alsamixer
2282 will display them correctly. We want to use the index for fast lookup
2283 of the relevant channel, but if we use it at all, most ALSA software
2284 does the wrong thing with it ...
2285 */
2286
2287 for (idx = 0; idx < limit; ++idx) {
2288 snd_hdspm_playback_mixer.index = idx + 1;
2289 if ((err = snd_ctl_add(card,
2290 kctl =
2291 snd_ctl_new1
2292 (&snd_hdspm_playback_mixer,
2293 hdspm)))) {
2294 return err;
2295 }
2296 hdspm->playback_mixer_ctls[idx] = kctl;
2297 }
2298
2299 return 0;
2300}
2301
2302/*------------------------------------------------------------
2303 /proc interface
2304 ------------------------------------------------------------*/
2305
2306static void
2307snd_hdspm_proc_read(snd_info_entry_t * entry, snd_info_buffer_t * buffer)
2308{
2309 hdspm_t *hdspm = (hdspm_t *) entry->private_data;
2310 unsigned int status;
2311 unsigned int status2;
2312 char *pref_sync_ref;
2313 char *autosync_ref;
2314 char *system_clock_mode;
2315 char *clock_source;
2316 char *insel;
2317 char *syncref;
2318 int x, x2;
2319
2320 status = hdspm_read(hdspm, HDSPM_statusRegister);
2321 status2 = hdspm_read(hdspm, HDSPM_statusRegister2);
2322
2323 snd_iprintf(buffer, "%s (Card #%d) Rev.%x Status2first3bits: %x\n",
2324 hdspm->card_name, hdspm->card->number + 1,
2325 hdspm->firmware_rev,
2326 (status2 & HDSPM_version0) |
2327 (status2 & HDSPM_version1) | (status2 &
2328 HDSPM_version2));
2329
2330 snd_iprintf(buffer, "IRQ: %d Registers bus: 0x%lx VM: 0x%lx\n",
2331 hdspm->irq, hdspm->port, (unsigned long)hdspm->iobase);
2332
2333 snd_iprintf(buffer, "--- System ---\n");
2334
2335 snd_iprintf(buffer,
2336 "IRQ Pending: Audio=%d, MIDI0=%d, MIDI1=%d, IRQcount=%d\n",
2337 status & HDSPM_audioIRQPending,
2338 (status & HDSPM_midi0IRQPending) ? 1 : 0,
2339 (status & HDSPM_midi1IRQPending) ? 1 : 0,
2340 hdspm->irq_count);
2341 snd_iprintf(buffer,
2342 "HW pointer: id = %d, rawptr = %d (%d->%d) estimated= %ld (bytes)\n",
2343 ((status & HDSPM_BufferID) ? 1 : 0),
2344 (status & HDSPM_BufferPositionMask),
2345 (status & HDSPM_BufferPositionMask) % (2 *
2346 (int)hdspm->
2347 period_bytes),
2348 ((status & HDSPM_BufferPositionMask) -
2349 64) % (2 * (int)hdspm->period_bytes),
2350 (long) hdspm_hw_pointer(hdspm) * 4);
2351
2352 snd_iprintf(buffer,
2353 "MIDI FIFO: Out1=0x%x, Out2=0x%x, In1=0x%x, In2=0x%x \n",
2354 hdspm_read(hdspm, HDSPM_midiStatusOut0) & 0xFF,
2355 hdspm_read(hdspm, HDSPM_midiStatusOut1) & 0xFF,
2356 hdspm_read(hdspm, HDSPM_midiStatusIn0) & 0xFF,
2357 hdspm_read(hdspm, HDSPM_midiStatusIn1) & 0xFF);
2358 snd_iprintf(buffer,
2359 "Register: ctrl1=0x%x, ctrl2=0x%x, status1=0x%x, status2=0x%x\n",
2360 hdspm->control_register, hdspm->control2_register,
2361 status, status2);
2362
2363 snd_iprintf(buffer, "--- Settings ---\n");
2364
2365 x = 1 << (6 +
2366 hdspm_decode_latency(hdspm->
2367 control_register &
2368 HDSPM_LatencyMask));
2369
2370 snd_iprintf(buffer,
2371 "Size (Latency): %d samples (2 periods of %lu bytes)\n",
2372 x, (unsigned long) hdspm->period_bytes);
2373
2374 snd_iprintf(buffer, "Line out: %s, Precise Pointer: %s\n",
2375 (hdspm->
2376 control_register & HDSPM_LineOut) ? "on " : "off",
2377 (hdspm->precise_ptr) ? "on" : "off");
2378
2379 switch (hdspm->control_register & HDSPM_InputMask) {
2380 case HDSPM_InputOptical:
2381 insel = "Optical";
2382 break;
2383 case HDSPM_InputCoaxial:
2384 insel = "Coaxial";
2385 break;
2386 default:
2387 insel = "Unkown";
2388 }
2389
2390 switch (hdspm->control_register & HDSPM_SyncRefMask) {
2391 case HDSPM_SyncRef_Word:
2392 syncref = "WordClock";
2393 break;
2394 case HDSPM_SyncRef_MADI:
2395 syncref = "MADI";
2396 break;
2397 default:
2398 syncref = "Unkown";
2399 }
2400 snd_iprintf(buffer, "Inputsel = %s, SyncRef = %s\n", insel,
2401 syncref);
2402
2403 snd_iprintf(buffer,
2404 "ClearTrackMarker = %s, Transmit in %s Channel Mode, Auto Input %s\n",
2405 (hdspm->
2406 control_register & HDSPM_clr_tms) ? "on" : "off",
2407 (hdspm->
2408 control_register & HDSPM_TX_64ch) ? "64" : "56",
2409 (hdspm->
2410 control_register & HDSPM_AutoInp) ? "on" : "off");
2411
2412 switch (hdspm_clock_source(hdspm)) {
2413 case HDSPM_CLOCK_SOURCE_AUTOSYNC:
2414 clock_source = "AutoSync";
2415 break;
2416 case HDSPM_CLOCK_SOURCE_INTERNAL_32KHZ:
2417 clock_source = "Internal 32 kHz";
2418 break;
2419 case HDSPM_CLOCK_SOURCE_INTERNAL_44_1KHZ:
2420 clock_source = "Internal 44.1 kHz";
2421 break;
2422 case HDSPM_CLOCK_SOURCE_INTERNAL_48KHZ:
2423 clock_source = "Internal 48 kHz";
2424 break;
2425 case HDSPM_CLOCK_SOURCE_INTERNAL_64KHZ:
2426 clock_source = "Internal 64 kHz";
2427 break;
2428 case HDSPM_CLOCK_SOURCE_INTERNAL_88_2KHZ:
2429 clock_source = "Internal 88.2 kHz";
2430 break;
2431 case HDSPM_CLOCK_SOURCE_INTERNAL_96KHZ:
2432 clock_source = "Internal 96 kHz";
2433 break;
2434 default:
2435 clock_source = "Error";
2436 }
2437 snd_iprintf(buffer, "Sample Clock Source: %s\n", clock_source);
2438 if (!(hdspm->control_register & HDSPM_ClockModeMaster)) {
2439 system_clock_mode = "Slave";
2440 } else {
2441 system_clock_mode = "Master";
2442 }
2443 snd_iprintf(buffer, "System Clock Mode: %s\n", system_clock_mode);
2444
2445 switch (hdspm_pref_sync_ref(hdspm)) {
2446 case HDSPM_SYNC_FROM_WORD:
2447 pref_sync_ref = "Word Clock";
2448 break;
2449 case HDSPM_SYNC_FROM_MADI:
2450 pref_sync_ref = "MADI Sync";
2451 break;
2452 default:
2453 pref_sync_ref = "XXXX Clock";
2454 break;
2455 }
2456 snd_iprintf(buffer, "Preferred Sync Reference: %s\n",
2457 pref_sync_ref);
2458
2459 snd_iprintf(buffer, "System Clock Frequency: %d\n",
2460 hdspm->system_sample_rate);
2461
2462
2463 snd_iprintf(buffer, "--- Status:\n");
2464
2465 x = status & HDSPM_madiSync;
2466 x2 = status2 & HDSPM_wcSync;
2467
2468 snd_iprintf(buffer, "Inputs MADI=%s, WordClock=%s\n",
2469 (status & HDSPM_madiLock) ? (x ? "Sync" : "Lock") :
2470 "NoLock",
2471 (status2 & HDSPM_wcLock) ? (x2 ? "Sync" : "Lock") :
2472 "NoLock");
2473
2474 switch (hdspm_autosync_ref(hdspm)) {
2475 case HDSPM_AUTOSYNC_FROM_WORD:
2476 autosync_ref = "Word Clock";
2477 break;
2478 case HDSPM_AUTOSYNC_FROM_MADI:
2479 autosync_ref = "MADI Sync";
2480 break;
2481 case HDSPM_AUTOSYNC_FROM_NONE:
2482 autosync_ref = "Input not valid";
2483 break;
2484 default:
2485 autosync_ref = "---";
2486 break;
2487 }
2488 snd_iprintf(buffer,
2489 "AutoSync: Reference= %s, Freq=%d (MADI = %d, Word = %d)\n",
2490 autosync_ref, hdspm_external_sample_rate(hdspm),
2491 (status & HDSPM_madiFreqMask) >> 22,
2492 (status2 & HDSPM_wcFreqMask) >> 5);
2493
2494 snd_iprintf(buffer, "Input: %s, Mode=%s\n",
2495 (status & HDSPM_AB_int) ? "Coax" : "Optical",
2496 (status & HDSPM_RX_64ch) ? "64 channels" :
2497 "56 channels");
2498
2499 snd_iprintf(buffer, "\n");
2500}
2501
2502static void __devinit snd_hdspm_proc_init(hdspm_t * hdspm)
2503{
2504 snd_info_entry_t *entry;
2505
2506 if (!snd_card_proc_new(hdspm->card, "hdspm", &entry))
2507 snd_info_set_text_ops(entry, hdspm, 1024,
2508 snd_hdspm_proc_read);
2509}
2510
2511/*------------------------------------------------------------
2512 hdspm intitialize
2513 ------------------------------------------------------------*/
2514
2515static int snd_hdspm_set_defaults(hdspm_t * hdspm)
2516{
2517 unsigned int i;
2518
2519 /* ASSUMPTION: hdspm->lock is either held, or there is no need to
2520 hold it (e.g. during module initalization).
2521 */
2522
2523 /* set defaults: */
2524
2525 hdspm->control_register = HDSPM_ClockModeMaster | /* Master Cloack Mode on */
2526 hdspm_encode_latency(7) | /* latency maximum = 8192 samples */
2527 HDSPM_InputCoaxial | /* Input Coax not Optical */
2528 HDSPM_SyncRef_MADI | /* Madi is syncclock */
2529 HDSPM_LineOut | /* Analog output in */
2530 HDSPM_TX_64ch | /* transmit in 64ch mode */
2531 HDSPM_AutoInp; /* AutoInput chossing (takeover) */
2532
2533 /* ! HDSPM_Frequency0|HDSPM_Frequency1 = 44.1khz */
2534 /* ! HDSPM_DoubleSpeed HDSPM_QuadSpeed = normal speed */
2535 /* ! HDSPM_clr_tms = do not clear bits in track marks */
2536
2537 hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
2538
2539#ifdef SNDRV_BIG_ENDIAN
2540 hdspm->control2_register = HDSPM_BIGENDIAN_MODE;
2541#else
2542 hdspm->control2_register = 0;
2543#endif
2544
2545 hdspm_write(hdspm, HDSPM_control2Reg, hdspm->control2_register);
2546 hdspm_compute_period_size(hdspm);
2547
2548 /* silence everything */
2549
2550 all_in_all_mixer(hdspm, 0 * UNITY_GAIN);
2551
2552 if (line_outs_monitor[hdspm->dev]) {
2553
2554 snd_printk(KERN_INFO "HDSPM: sending all playback streams to line outs.\n");
2555
2556 for (i = 0; i < HDSPM_MIXER_CHANNELS; i++) {
2557 if (hdspm_write_pb_gain(hdspm, i, i, UNITY_GAIN))
2558 return -EIO;
2559 }
2560 }
2561
2562 /* set a default rate so that the channel map is set up. */
2563 hdspm->channel_map = channel_map_madi_ss;
2564 hdspm_set_rate(hdspm, 44100, 1);
2565
2566 return 0;
2567}
2568
2569
2570/*------------------------------------------------------------
2571 interupt
2572 ------------------------------------------------------------*/
2573
2574static irqreturn_t snd_hdspm_interrupt(int irq, void *dev_id,
2575 struct pt_regs *regs)
2576{
2577 hdspm_t *hdspm = (hdspm_t *) dev_id;
2578 unsigned int status;
2579 int audio;
2580 int midi0;
2581 int midi1;
2582 unsigned int midi0status;
2583 unsigned int midi1status;
2584 int schedule = 0;
2585
2586 status = hdspm_read(hdspm, HDSPM_statusRegister);
2587
2588 audio = status & HDSPM_audioIRQPending;
2589 midi0 = status & HDSPM_midi0IRQPending;
2590 midi1 = status & HDSPM_midi1IRQPending;
2591
2592 if (!audio && !midi0 && !midi1)
2593 return IRQ_NONE;
2594
2595 hdspm_write(hdspm, HDSPM_interruptConfirmation, 0);
2596 hdspm->irq_count++;
2597
2598 midi0status = hdspm_read(hdspm, HDSPM_midiStatusIn0) & 0xff;
2599 midi1status = hdspm_read(hdspm, HDSPM_midiStatusIn1) & 0xff;
2600
2601 if (audio) {
2602
2603 if (hdspm->capture_substream)
2604 snd_pcm_period_elapsed(hdspm->pcm->
2605 streams
2606 [SNDRV_PCM_STREAM_CAPTURE].
2607 substream);
2608
2609 if (hdspm->playback_substream)
2610 snd_pcm_period_elapsed(hdspm->pcm->
2611 streams
2612 [SNDRV_PCM_STREAM_PLAYBACK].
2613 substream);
2614 }
2615
2616 if (midi0 && midi0status) {
2617 /* we disable interrupts for this input until processing is done */
2618 hdspm->control_register &= ~HDSPM_Midi0InterruptEnable;
2619 hdspm_write(hdspm, HDSPM_controlRegister,
2620 hdspm->control_register);
2621 hdspm->midi[0].pending = 1;
2622 schedule = 1;
2623 }
2624 if (midi1 && midi1status) {
2625 /* we disable interrupts for this input until processing is done */
2626 hdspm->control_register &= ~HDSPM_Midi1InterruptEnable;
2627 hdspm_write(hdspm, HDSPM_controlRegister,
2628 hdspm->control_register);
2629 hdspm->midi[1].pending = 1;
2630 schedule = 1;
2631 }
2632 if (schedule)
2633 tasklet_hi_schedule(&hdspm->midi_tasklet);
2634 return IRQ_HANDLED;
2635}
2636
2637/*------------------------------------------------------------
2638 pcm interface
2639 ------------------------------------------------------------*/
2640
2641
2642static snd_pcm_uframes_t snd_hdspm_hw_pointer(snd_pcm_substream_t *
2643 substream)
2644{
2645 hdspm_t *hdspm = snd_pcm_substream_chip(substream);
2646 return hdspm_hw_pointer(hdspm);
2647}
2648
2649static char *hdspm_channel_buffer_location(hdspm_t * hdspm,
2650 int stream, int channel)
2651{
2652 int mapped_channel;
2653
2654 snd_assert(channel >= 0
2655 || channel < HDSPM_MAX_CHANNELS, return NULL);
2656
2657 if ((mapped_channel = hdspm->channel_map[channel]) < 0)
2658 return NULL;
2659
2660 if (stream == SNDRV_PCM_STREAM_CAPTURE) {
2661 return hdspm->capture_buffer +
2662 mapped_channel * HDSPM_CHANNEL_BUFFER_BYTES;
2663 } else {
2664 return hdspm->playback_buffer +
2665 mapped_channel * HDSPM_CHANNEL_BUFFER_BYTES;
2666 }
2667}
2668
2669
2670/* dont know why need it ??? */
2671static int snd_hdspm_playback_copy(snd_pcm_substream_t * substream,
2672 int channel, snd_pcm_uframes_t pos,
2673 void __user *src, snd_pcm_uframes_t count)
2674{
2675 hdspm_t *hdspm = snd_pcm_substream_chip(substream);
2676 char *channel_buf;
2677
2678 snd_assert(pos + count <= HDSPM_CHANNEL_BUFFER_BYTES / 4,
2679 return -EINVAL);
2680
2681 channel_buf = hdspm_channel_buffer_location(hdspm,
2682 substream->pstr->
2683 stream, channel);
2684
2685 snd_assert(channel_buf != NULL, return -EIO);
2686
2687 return copy_from_user(channel_buf + pos * 4, src, count * 4);
2688}
2689
2690static int snd_hdspm_capture_copy(snd_pcm_substream_t * substream,
2691 int channel, snd_pcm_uframes_t pos,
2692 void __user *dst, snd_pcm_uframes_t count)
2693{
2694 hdspm_t *hdspm = snd_pcm_substream_chip(substream);
2695 char *channel_buf;
2696
2697 snd_assert(pos + count <= HDSPM_CHANNEL_BUFFER_BYTES / 4,
2698 return -EINVAL);
2699
2700 channel_buf = hdspm_channel_buffer_location(hdspm,
2701 substream->pstr->
2702 stream, channel);
2703 snd_assert(channel_buf != NULL, return -EIO);
2704 return copy_to_user(dst, channel_buf + pos * 4, count * 4);
2705}
2706
2707static int snd_hdspm_hw_silence(snd_pcm_substream_t * substream,
2708 int channel, snd_pcm_uframes_t pos,
2709 snd_pcm_uframes_t count)
2710{
2711 hdspm_t *hdspm = snd_pcm_substream_chip(substream);
2712 char *channel_buf;
2713
2714 channel_buf =
2715 hdspm_channel_buffer_location(hdspm, substream->pstr->stream,
2716 channel);
2717 snd_assert(channel_buf != NULL, return -EIO);
2718 memset(channel_buf + pos * 4, 0, count * 4);
2719 return 0;
2720}
2721
2722static int snd_hdspm_reset(snd_pcm_substream_t * substream)
2723{
2724 snd_pcm_runtime_t *runtime = substream->runtime;
2725 hdspm_t *hdspm = snd_pcm_substream_chip(substream);
2726 snd_pcm_substream_t *other;
2727
2728 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
2729 other = hdspm->capture_substream;
2730 else
2731 other = hdspm->playback_substream;
2732
2733 if (hdspm->running)
2734 runtime->status->hw_ptr = hdspm_hw_pointer(hdspm);
2735 else
2736 runtime->status->hw_ptr = 0;
2737 if (other) {
2738 struct list_head *pos;
2739 snd_pcm_substream_t *s;
2740 snd_pcm_runtime_t *oruntime = other->runtime;
2741 snd_pcm_group_for_each(pos, substream) {
2742 s = snd_pcm_group_substream_entry(pos);
2743 if (s == other) {
2744 oruntime->status->hw_ptr =
2745 runtime->status->hw_ptr;
2746 break;
2747 }
2748 }
2749 }
2750 return 0;
2751}
2752
2753static int snd_hdspm_hw_params(snd_pcm_substream_t * substream,
2754 snd_pcm_hw_params_t * params)
2755{
2756 hdspm_t *hdspm = snd_pcm_substream_chip(substream);
2757 int err;
2758 int i;
2759 pid_t this_pid;
2760 pid_t other_pid;
2761 struct snd_sg_buf *sgbuf;
2762
2763
2764 spin_lock_irq(&hdspm->lock);
2765
2766 if (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK) {
2767 this_pid = hdspm->playback_pid;
2768 other_pid = hdspm->capture_pid;
2769 } else {
2770 this_pid = hdspm->capture_pid;
2771 other_pid = hdspm->playback_pid;
2772 }
2773
2774 if ((other_pid > 0) && (this_pid != other_pid)) {
2775
2776 /* The other stream is open, and not by the same
2777 task as this one. Make sure that the parameters
2778 that matter are the same.
2779 */
2780
2781 if (params_rate(params) != hdspm->system_sample_rate) {
2782 spin_unlock_irq(&hdspm->lock);
2783 _snd_pcm_hw_param_setempty(params,
2784 SNDRV_PCM_HW_PARAM_RATE);
2785 return -EBUSY;
2786 }
2787
2788 if (params_period_size(params) != hdspm->period_bytes / 4) {
2789 spin_unlock_irq(&hdspm->lock);
2790 _snd_pcm_hw_param_setempty(params,
2791 SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
2792 return -EBUSY;
2793 }
2794
2795 }
2796 /* We're fine. */
2797 spin_unlock_irq(&hdspm->lock);
2798
2799 /* how to make sure that the rate matches an externally-set one ? */
2800
2801 spin_lock_irq(&hdspm->lock);
2802 if ((err = hdspm_set_rate(hdspm, params_rate(params), 0)) < 0) {
2803 spin_unlock_irq(&hdspm->lock);
2804 _snd_pcm_hw_param_setempty(params,
2805 SNDRV_PCM_HW_PARAM_RATE);
2806 return err;
2807 }
2808 spin_unlock_irq(&hdspm->lock);
2809
2810 if ((err =
2811 hdspm_set_interrupt_interval(hdspm,
2812 params_period_size(params))) <
2813 0) {
2814 _snd_pcm_hw_param_setempty(params,
2815 SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
2816 return err;
2817 }
2818
2819 /* Memory allocation, takashi's method, dont know if we should spinlock */
2820 /* malloc all buffer even if not enabled to get sure */
2821 /* malloc only needed bytes */
2822 err =
2823 snd_pcm_lib_malloc_pages(substream,
2824 HDSPM_CHANNEL_BUFFER_BYTES *
2825 params_channels(params));
2826 if (err < 0)
2827 return err;
2828
2829 sgbuf = snd_pcm_substream_sgbuf(substream);
2830
2831 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
2832
2833 hdspm_set_sgbuf(hdspm, sgbuf, HDSPM_pageAddressBufferOut,
2834 params_channels(params));
2835
2836 for (i = 0; i < params_channels(params); ++i)
2837 snd_hdspm_enable_out(hdspm, i, 1);
2838
2839 hdspm->playback_buffer =
2840 (unsigned char *) substream->runtime->dma_area;
2841 } else {
2842 hdspm_set_sgbuf(hdspm, sgbuf, HDSPM_pageAddressBufferIn,
2843 params_channels(params));
2844
2845 for (i = 0; i < params_channels(params); ++i)
2846 snd_hdspm_enable_in(hdspm, i, 1);
2847
2848 hdspm->capture_buffer =
2849 (unsigned char *) substream->runtime->dma_area;
2850 }
2851 return 0;
2852}
2853
2854static int snd_hdspm_hw_free(snd_pcm_substream_t * substream)
2855{
2856 int i;
2857 hdspm_t *hdspm = snd_pcm_substream_chip(substream);
2858
2859 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
2860
2861 /* params_channels(params) should be enough,
2862 but to get sure in case of error */
2863 for (i = 0; i < HDSPM_MAX_CHANNELS; ++i)
2864 snd_hdspm_enable_out(hdspm, i, 0);
2865
2866 hdspm->playback_buffer = NULL;
2867 } else {
2868 for (i = 0; i < HDSPM_MAX_CHANNELS; ++i)
2869 snd_hdspm_enable_in(hdspm, i, 0);
2870
2871 hdspm->capture_buffer = NULL;
2872
2873 }
2874
2875 snd_pcm_lib_free_pages(substream);
2876
2877 return 0;
2878}
2879
2880static int snd_hdspm_channel_info(snd_pcm_substream_t * substream,
2881 snd_pcm_channel_info_t * info)
2882{
2883 hdspm_t *hdspm = snd_pcm_substream_chip(substream);
2884 int mapped_channel;
2885
2886 snd_assert(info->channel < HDSPM_MAX_CHANNELS, return -EINVAL);
2887
2888 if ((mapped_channel = hdspm->channel_map[info->channel]) < 0)
2889 return -EINVAL;
2890
2891 info->offset = mapped_channel * HDSPM_CHANNEL_BUFFER_BYTES;
2892 info->first = 0;
2893 info->step = 32;
2894 return 0;
2895}
2896
2897static int snd_hdspm_ioctl(snd_pcm_substream_t * substream,
2898 unsigned int cmd, void *arg)
2899{
2900 switch (cmd) {
2901 case SNDRV_PCM_IOCTL1_RESET:
2902 {
2903 return snd_hdspm_reset(substream);
2904 }
2905
2906 case SNDRV_PCM_IOCTL1_CHANNEL_INFO:
2907 {
2908 snd_pcm_channel_info_t *info = arg;
2909 return snd_hdspm_channel_info(substream, info);
2910 }
2911 default:
2912 break;
2913 }
2914
2915 return snd_pcm_lib_ioctl(substream, cmd, arg);
2916}
2917
2918static int snd_hdspm_trigger(snd_pcm_substream_t * substream, int cmd)
2919{
2920 hdspm_t *hdspm = snd_pcm_substream_chip(substream);
2921 snd_pcm_substream_t *other;
2922 int running;
2923
2924 spin_lock(&hdspm->lock);
2925 running = hdspm->running;
2926 switch (cmd) {
2927 case SNDRV_PCM_TRIGGER_START:
2928 running |= 1 << substream->stream;
2929 break;
2930 case SNDRV_PCM_TRIGGER_STOP:
2931 running &= ~(1 << substream->stream);
2932 break;
2933 default:
2934 snd_BUG();
2935 spin_unlock(&hdspm->lock);
2936 return -EINVAL;
2937 }
2938 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
2939 other = hdspm->capture_substream;
2940 else
2941 other = hdspm->playback_substream;
2942
2943 if (other) {
2944 struct list_head *pos;
2945 snd_pcm_substream_t *s;
2946 snd_pcm_group_for_each(pos, substream) {
2947 s = snd_pcm_group_substream_entry(pos);
2948 if (s == other) {
2949 snd_pcm_trigger_done(s, substream);
2950 if (cmd == SNDRV_PCM_TRIGGER_START)
2951 running |= 1 << s->stream;
2952 else
2953 running &= ~(1 << s->stream);
2954 goto _ok;
2955 }
2956 }
2957 if (cmd == SNDRV_PCM_TRIGGER_START) {
2958 if (!(running & (1 << SNDRV_PCM_STREAM_PLAYBACK))
2959 && substream->stream ==
2960 SNDRV_PCM_STREAM_CAPTURE)
2961 hdspm_silence_playback(hdspm);
2962 } else {
2963 if (running &&
2964 substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
2965 hdspm_silence_playback(hdspm);
2966 }
2967 } else {
2968 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
2969 hdspm_silence_playback(hdspm);
2970 }
2971 _ok:
2972 snd_pcm_trigger_done(substream, substream);
2973 if (!hdspm->running && running)
2974 hdspm_start_audio(hdspm);
2975 else if (hdspm->running && !running)
2976 hdspm_stop_audio(hdspm);
2977 hdspm->running = running;
2978 spin_unlock(&hdspm->lock);
2979
2980 return 0;
2981}
2982
2983static int snd_hdspm_prepare(snd_pcm_substream_t * substream)
2984{
2985 return 0;
2986}
2987
2988static unsigned int period_sizes[] =
2989 { 64, 128, 256, 512, 1024, 2048, 4096, 8192 };
2990
2991static snd_pcm_hardware_t snd_hdspm_playback_subinfo = {
2992 .info = (SNDRV_PCM_INFO_MMAP |
2993 SNDRV_PCM_INFO_MMAP_VALID |
2994 SNDRV_PCM_INFO_NONINTERLEAVED |
2995 SNDRV_PCM_INFO_SYNC_START | SNDRV_PCM_INFO_DOUBLE),
2996 .formats = SNDRV_PCM_FMTBIT_S32_LE,
2997 .rates = (SNDRV_PCM_RATE_32000 |
2998 SNDRV_PCM_RATE_44100 |
2999 SNDRV_PCM_RATE_48000 |
3000 SNDRV_PCM_RATE_64000 |
3001 SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000),
3002 .rate_min = 32000,
3003 .rate_max = 96000,
3004 .channels_min = 1,
3005 .channels_max = HDSPM_MAX_CHANNELS,
3006 .buffer_bytes_max =
3007 HDSPM_CHANNEL_BUFFER_BYTES * HDSPM_MAX_CHANNELS,
3008 .period_bytes_min = (64 * 4),
3009 .period_bytes_max = (8192 * 4) * HDSPM_MAX_CHANNELS,
3010 .periods_min = 2,
3011 .periods_max = 2,
3012 .fifo_size = 0
3013};
3014
3015static snd_pcm_hardware_t snd_hdspm_capture_subinfo = {
3016 .info = (SNDRV_PCM_INFO_MMAP |
3017 SNDRV_PCM_INFO_MMAP_VALID |
3018 SNDRV_PCM_INFO_NONINTERLEAVED |
3019 SNDRV_PCM_INFO_SYNC_START),
3020 .formats = SNDRV_PCM_FMTBIT_S32_LE,
3021 .rates = (SNDRV_PCM_RATE_32000 |
3022 SNDRV_PCM_RATE_44100 |
3023 SNDRV_PCM_RATE_48000 |
3024 SNDRV_PCM_RATE_64000 |
3025 SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000),
3026 .rate_min = 32000,
3027 .rate_max = 96000,
3028 .channels_min = 1,
3029 .channels_max = HDSPM_MAX_CHANNELS,
3030 .buffer_bytes_max =
3031 HDSPM_CHANNEL_BUFFER_BYTES * HDSPM_MAX_CHANNELS,
3032 .period_bytes_min = (64 * 4),
3033 .period_bytes_max = (8192 * 4) * HDSPM_MAX_CHANNELS,
3034 .periods_min = 2,
3035 .periods_max = 2,
3036 .fifo_size = 0
3037};
3038
3039static snd_pcm_hw_constraint_list_t hw_constraints_period_sizes = {
3040 .count = ARRAY_SIZE(period_sizes),
3041 .list = period_sizes,
3042 .mask = 0
3043};
3044
3045
3046static int snd_hdspm_hw_rule_channels_rate(snd_pcm_hw_params_t * params,
3047 snd_pcm_hw_rule_t * rule)
3048{
3049 hdspm_t *hdspm = rule->private;
3050 snd_interval_t *c =
3051 hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
3052 snd_interval_t *r =
3053 hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
3054
3055 if (r->min > 48000) {
3056 snd_interval_t t = {
3057 .min = 1,
3058 .max = hdspm->ds_channels,
3059 .integer = 1,
3060 };
3061 return snd_interval_refine(c, &t);
3062 } else if (r->max < 64000) {
3063 snd_interval_t t = {
3064 .min = 1,
3065 .max = hdspm->ss_channels,
3066 .integer = 1,
3067 };
3068 return snd_interval_refine(c, &t);
3069 }
3070 return 0;
3071}
3072
3073static int snd_hdspm_hw_rule_rate_channels(snd_pcm_hw_params_t * params,
3074 snd_pcm_hw_rule_t * rule)
3075{
3076 hdspm_t *hdspm = rule->private;
3077 snd_interval_t *c =
3078 hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
3079 snd_interval_t *r =
3080 hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
3081
3082 if (c->min <= hdspm->ss_channels) {
3083 snd_interval_t t = {
3084 .min = 32000,
3085 .max = 48000,
3086 .integer = 1,
3087 };
3088 return snd_interval_refine(r, &t);
3089 } else if (c->max > hdspm->ss_channels) {
3090 snd_interval_t t = {
3091 .min = 64000,
3092 .max = 96000,
3093 .integer = 1,
3094 };
3095
3096 return snd_interval_refine(r, &t);
3097 }
3098 return 0;
3099}
3100
3101static int snd_hdspm_playback_open(snd_pcm_substream_t * substream)
3102{
3103 hdspm_t *hdspm = snd_pcm_substream_chip(substream);
3104 snd_pcm_runtime_t *runtime = substream->runtime;
3105
3106 snd_printdd("Open device substream %d\n", substream->stream);
3107
3108 spin_lock_irq(&hdspm->lock);
3109
3110 snd_pcm_set_sync(substream);
3111
3112 runtime->hw = snd_hdspm_playback_subinfo;
3113
3114 if (hdspm->capture_substream == NULL)
3115 hdspm_stop_audio(hdspm);
3116
3117 hdspm->playback_pid = current->pid;
3118 hdspm->playback_substream = substream;
3119
3120 spin_unlock_irq(&hdspm->lock);
3121
3122 snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
3123
3124 snd_pcm_hw_constraint_list(runtime, 0,
3125 SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
3126 &hw_constraints_period_sizes);
3127
3128 snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
3129 snd_hdspm_hw_rule_channels_rate, hdspm,
3130 SNDRV_PCM_HW_PARAM_RATE, -1);
3131
3132 snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
3133 snd_hdspm_hw_rule_rate_channels, hdspm,
3134 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
3135
3136 return 0;
3137}
3138
3139static int snd_hdspm_playback_release(snd_pcm_substream_t * substream)
3140{
3141 hdspm_t *hdspm = snd_pcm_substream_chip(substream);
3142
3143 spin_lock_irq(&hdspm->lock);
3144
3145 hdspm->playback_pid = -1;
3146 hdspm->playback_substream = NULL;
3147
3148 spin_unlock_irq(&hdspm->lock);
3149
3150 return 0;
3151}
3152
3153
3154static int snd_hdspm_capture_open(snd_pcm_substream_t * substream)
3155{
3156 hdspm_t *hdspm = snd_pcm_substream_chip(substream);
3157 snd_pcm_runtime_t *runtime = substream->runtime;
3158
3159 spin_lock_irq(&hdspm->lock);
3160 snd_pcm_set_sync(substream);
3161 runtime->hw = snd_hdspm_capture_subinfo;
3162
3163 if (hdspm->playback_substream == NULL)
3164 hdspm_stop_audio(hdspm);
3165
3166 hdspm->capture_pid = current->pid;
3167 hdspm->capture_substream = substream;
3168
3169 spin_unlock_irq(&hdspm->lock);
3170
3171 snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
3172 snd_pcm_hw_constraint_list(runtime, 0,
3173 SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
3174 &hw_constraints_period_sizes);
3175
3176 snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
3177 snd_hdspm_hw_rule_channels_rate, hdspm,
3178 SNDRV_PCM_HW_PARAM_RATE, -1);
3179
3180 snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
3181 snd_hdspm_hw_rule_rate_channels, hdspm,
3182 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
3183 return 0;
3184}
3185
3186static int snd_hdspm_capture_release(snd_pcm_substream_t * substream)
3187{
3188 hdspm_t *hdspm = snd_pcm_substream_chip(substream);
3189
3190 spin_lock_irq(&hdspm->lock);
3191
3192 hdspm->capture_pid = -1;
3193 hdspm->capture_substream = NULL;
3194
3195 spin_unlock_irq(&hdspm->lock);
3196 return 0;
3197}
3198
3199static int snd_hdspm_hwdep_dummy_op(snd_hwdep_t * hw, struct file *file)
3200{
3201 /* we have nothing to initialize but the call is required */
3202 return 0;
3203}
3204
3205
3206static int snd_hdspm_hwdep_ioctl(snd_hwdep_t * hw, struct file *file,
3207 unsigned int cmd, unsigned long arg)
3208{
3209 hdspm_t *hdspm = (hdspm_t *) hw->private_data;
3210 struct sndrv_hdspm_mixer_ioctl mixer;
3211 hdspm_config_info_t info;
3212 hdspm_version_t hdspm_version;
3213 struct sndrv_hdspm_peak_rms_ioctl rms;
3214
3215 switch (cmd) {
3216
3217
3218 case SNDRV_HDSPM_IOCTL_GET_PEAK_RMS:
3219 if (copy_from_user(&rms, (void __user *)arg, sizeof(rms)))
3220 return -EFAULT;
3221 /* maybe there is a chance to memorymap in future so dont touch just copy */
3222 if(copy_to_user_fromio((void __user *)rms.peak,
3223 hdspm->iobase+HDSPM_MADI_peakrmsbase,
3224 sizeof(hdspm_peak_rms_t)) != 0 )
3225 return -EFAULT;
3226
3227 break;
3228
3229
3230 case SNDRV_HDSPM_IOCTL_GET_CONFIG_INFO:
3231
3232 spin_lock_irq(&hdspm->lock);
3233 info.pref_sync_ref =
3234 (unsigned char) hdspm_pref_sync_ref(hdspm);
3235 info.wordclock_sync_check =
3236 (unsigned char) hdspm_wc_sync_check(hdspm);
3237
3238 info.system_sample_rate = hdspm->system_sample_rate;
3239 info.autosync_sample_rate =
3240 hdspm_external_sample_rate(hdspm);
3241 info.system_clock_mode =
3242 (unsigned char) hdspm_system_clock_mode(hdspm);
3243 info.clock_source =
3244 (unsigned char) hdspm_clock_source(hdspm);
3245 info.autosync_ref =
3246 (unsigned char) hdspm_autosync_ref(hdspm);
3247 info.line_out = (unsigned char) hdspm_line_out(hdspm);
3248 info.passthru = 0;
3249 spin_unlock_irq(&hdspm->lock);
3250 if (copy_to_user((void __user *) arg, &info, sizeof(info)))
3251 return -EFAULT;
3252 break;
3253
3254 case SNDRV_HDSPM_IOCTL_GET_VERSION:
3255 hdspm_version.firmware_rev = hdspm->firmware_rev;
3256 if (copy_to_user((void __user *) arg, &hdspm_version,
3257 sizeof(hdspm_version)))
3258 return -EFAULT;
3259 break;
3260
3261 case SNDRV_HDSPM_IOCTL_GET_MIXER:
3262 if (copy_from_user(&mixer, (void __user *)arg, sizeof(mixer)))
3263 return -EFAULT;
3264 if (copy_to_user
3265 ((void __user *)mixer.mixer, hdspm->mixer, sizeof(hdspm_mixer_t)))
3266 return -EFAULT;
3267 break;
3268
3269 default:
3270 return -EINVAL;
3271 }
3272 return 0;
3273}
3274
3275static snd_pcm_ops_t snd_hdspm_playback_ops = {
3276 .open = snd_hdspm_playback_open,
3277 .close = snd_hdspm_playback_release,
3278 .ioctl = snd_hdspm_ioctl,
3279 .hw_params = snd_hdspm_hw_params,
3280 .hw_free = snd_hdspm_hw_free,
3281 .prepare = snd_hdspm_prepare,
3282 .trigger = snd_hdspm_trigger,
3283 .pointer = snd_hdspm_hw_pointer,
3284 .copy = snd_hdspm_playback_copy,
3285 .silence = snd_hdspm_hw_silence,
3286 .page = snd_pcm_sgbuf_ops_page,
3287};
3288
3289static snd_pcm_ops_t snd_hdspm_capture_ops = {
3290 .open = snd_hdspm_capture_open,
3291 .close = snd_hdspm_capture_release,
3292 .ioctl = snd_hdspm_ioctl,
3293 .hw_params = snd_hdspm_hw_params,
3294 .hw_free = snd_hdspm_hw_free,
3295 .prepare = snd_hdspm_prepare,
3296 .trigger = snd_hdspm_trigger,
3297 .pointer = snd_hdspm_hw_pointer,
3298 .copy = snd_hdspm_capture_copy,
3299 .page = snd_pcm_sgbuf_ops_page,
3300};
3301
3302static int __devinit snd_hdspm_create_hwdep(snd_card_t * card,
3303 hdspm_t * hdspm)
3304{
3305 snd_hwdep_t *hw;
3306 int err;
3307
3308 if ((err = snd_hwdep_new(card, "HDSPM hwdep", 0, &hw)) < 0)
3309 return err;
3310
3311 hdspm->hwdep = hw;
3312 hw->private_data = hdspm;
3313 strcpy(hw->name, "HDSPM hwdep interface");
3314
3315 hw->ops.open = snd_hdspm_hwdep_dummy_op;
3316 hw->ops.ioctl = snd_hdspm_hwdep_ioctl;
3317 hw->ops.release = snd_hdspm_hwdep_dummy_op;
3318
3319 return 0;
3320}
3321
3322
3323/*------------------------------------------------------------
3324 memory interface
3325 ------------------------------------------------------------*/
3326static int __devinit snd_hdspm_preallocate_memory(hdspm_t * hdspm)
3327{
3328 int err;
3329 snd_pcm_t *pcm;
3330 size_t wanted;
3331
3332 pcm = hdspm->pcm;
3333
3334 wanted = HDSPM_DMA_AREA_BYTES + 4096; /* dont know why, but it works */
3335
3336 if ((err =
3337 snd_pcm_lib_preallocate_pages_for_all(pcm,
3338 SNDRV_DMA_TYPE_DEV_SG,
3339 snd_dma_pci_data(hdspm->pci),
3340 wanted,
3341 wanted)) < 0) {
3342 snd_printdd("Could not preallocate %d Bytes\n", wanted);
3343
3344 return err;
3345 } else
3346 snd_printdd(" Preallocated %d Bytes\n", wanted);
3347
3348 return 0;
3349}
3350
3351static int snd_hdspm_memory_free(hdspm_t * hdspm)
3352{
3353 snd_printdd("memory_free_for_all %p\n", hdspm->pcm);
3354
3355 snd_pcm_lib_preallocate_free_for_all(hdspm->pcm);
3356 return 0;
3357}
3358
3359
3360static void hdspm_set_sgbuf(hdspm_t * hdspm, struct snd_sg_buf *sgbuf,
3361 unsigned int reg, int channels)
3362{
3363 int i;
3364 for (i = 0; i < (channels * 16); i++)
3365 hdspm_write(hdspm, reg + 4 * i,
3366 snd_pcm_sgbuf_get_addr(sgbuf,
3367 (size_t) 4096 * i));
3368}
3369
3370/* ------------- ALSA Devices ---------------------------- */
3371static int __devinit snd_hdspm_create_pcm(snd_card_t * card,
3372 hdspm_t * hdspm)
3373{
3374 snd_pcm_t *pcm;
3375 int err;
3376
3377 if ((err = snd_pcm_new(card, hdspm->card_name, 0, 1, 1, &pcm)) < 0)
3378 return err;
3379
3380 hdspm->pcm = pcm;
3381 pcm->private_data = hdspm;
3382 strcpy(pcm->name, hdspm->card_name);
3383
3384 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
3385 &snd_hdspm_playback_ops);
3386 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
3387 &snd_hdspm_capture_ops);
3388
3389 pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX;
3390
3391 if ((err = snd_hdspm_preallocate_memory(hdspm)) < 0)
3392 return err;
3393
3394 return 0;
3395}
3396
3397static inline void snd_hdspm_initialize_midi_flush(hdspm_t * hdspm)
3398{
3399 snd_hdspm_flush_midi_input(hdspm, 0);
3400 snd_hdspm_flush_midi_input(hdspm, 1);
3401}
3402
3403static int __devinit snd_hdspm_create_alsa_devices(snd_card_t * card,
3404 hdspm_t * hdspm)
3405{
3406 int err;
3407
3408 snd_printdd("Create card...\n");
3409 if ((err = snd_hdspm_create_pcm(card, hdspm)) < 0)
3410 return err;
3411
3412 if ((err = snd_hdspm_create_midi(card, hdspm, 0)) < 0)
3413 return err;
3414
3415 if ((err = snd_hdspm_create_midi(card, hdspm, 1)) < 0)
3416 return err;
3417
3418 if ((err = snd_hdspm_create_controls(card, hdspm)) < 0)
3419 return err;
3420
3421 if ((err = snd_hdspm_create_hwdep(card, hdspm)) < 0)
3422 return err;
3423
3424 snd_printdd("proc init...\n");
3425 snd_hdspm_proc_init(hdspm);
3426
3427 hdspm->system_sample_rate = -1;
3428 hdspm->last_external_sample_rate = -1;
3429 hdspm->last_internal_sample_rate = -1;
3430 hdspm->playback_pid = -1;
3431 hdspm->capture_pid = -1;
3432 hdspm->capture_substream = NULL;
3433 hdspm->playback_substream = NULL;
3434
3435 snd_printdd("Set defaults...\n");
3436 if ((err = snd_hdspm_set_defaults(hdspm)) < 0)
3437 return err;
3438
3439 snd_printdd("Update mixer controls...\n");
3440 hdspm_update_simple_mixer_controls(hdspm);
3441
3442 snd_printdd("Initializeing complete ???\n");
3443
3444 if ((err = snd_card_register(card)) < 0) {
3445 snd_printk(KERN_ERR "HDSPM: error registering card\n");
3446 return err;
3447 }
3448
3449 snd_printdd("... yes now\n");
3450
3451 return 0;
3452}
3453
3454static int __devinit snd_hdspm_create(snd_card_t * card, hdspm_t * hdspm,
3455 int precise_ptr, int enable_monitor)
3456{
3457 struct pci_dev *pci = hdspm->pci;
3458 int err;
3459 int i;
3460
3461 unsigned long io_extent;
3462
3463 hdspm->irq = -1;
3464 hdspm->irq_count = 0;
3465
3466 hdspm->midi[0].rmidi = NULL;
3467 hdspm->midi[1].rmidi = NULL;
3468 hdspm->midi[0].input = NULL;
3469 hdspm->midi[1].input = NULL;
3470 hdspm->midi[0].output = NULL;
3471 hdspm->midi[1].output = NULL;
3472 spin_lock_init(&hdspm->midi[0].lock);
3473 spin_lock_init(&hdspm->midi[1].lock);
3474 hdspm->iobase = NULL;
3475 hdspm->control_register = 0;
3476 hdspm->control2_register = 0;
3477
3478 hdspm->playback_buffer = NULL;
3479 hdspm->capture_buffer = NULL;
3480
3481 for (i = 0; i < HDSPM_MAX_CHANNELS; ++i)
3482 hdspm->playback_mixer_ctls[i] = NULL;
3483 hdspm->mixer = NULL;
3484
3485 hdspm->card = card;
3486
3487 spin_lock_init(&hdspm->lock);
3488
3489 tasklet_init(&hdspm->midi_tasklet,
3490 hdspm_midi_tasklet, (unsigned long) hdspm);
3491
3492 pci_read_config_word(hdspm->pci,
3493 PCI_CLASS_REVISION, &hdspm->firmware_rev);
3494
3495 strcpy(card->driver, "HDSPM");
3496 strcpy(card->mixername, "Xilinx FPGA");
3497 hdspm->card_name = "RME HDSPM MADI";
3498
3499 if ((err = pci_enable_device(pci)) < 0)
3500 return err;
3501
3502 pci_set_master(hdspm->pci);
3503
3504 if ((err = pci_request_regions(pci, "hdspm")) < 0)
3505 return err;
3506
3507 hdspm->port = pci_resource_start(pci, 0);
3508 io_extent = pci_resource_len(pci, 0);
3509
3510 snd_printdd("grabbed memory region 0x%lx-0x%lx\n",
3511 hdspm->port, hdspm->port + io_extent - 1);
3512
3513
3514 if ((hdspm->iobase = ioremap_nocache(hdspm->port, io_extent)) == NULL) {
3515 snd_printk(KERN_ERR "HDSPM: unable to remap region 0x%lx-0x%lx\n",
3516 hdspm->port, hdspm->port + io_extent - 1);
3517 return -EBUSY;
3518 }
3519 snd_printdd("remapped region (0x%lx) 0x%lx-0x%lx\n",
3520 (unsigned long)hdspm->iobase, hdspm->port,
3521 hdspm->port + io_extent - 1);
3522
3523 if (request_irq(pci->irq, snd_hdspm_interrupt,
3524 SA_INTERRUPT | SA_SHIRQ, "hdspm",
3525 (void *) hdspm)) {
3526 snd_printk(KERN_ERR "HDSPM: unable to use IRQ %d\n", pci->irq);
3527 return -EBUSY;
3528 }
3529
3530 snd_printdd("use IRQ %d\n", pci->irq);
3531
3532 hdspm->irq = pci->irq;
3533 hdspm->precise_ptr = precise_ptr;
3534
3535 hdspm->monitor_outs = enable_monitor;
3536
3537 snd_printdd("kmalloc Mixer memory of %d Bytes\n",
3538 sizeof(hdspm_mixer_t));
3539 if ((hdspm->mixer =
3540 (hdspm_mixer_t *) kmalloc(sizeof(hdspm_mixer_t), GFP_KERNEL))
3541 == NULL) {
3542 snd_printk(KERN_ERR "HDSPM: unable to kmalloc Mixer memory of %d Bytes\n",
3543 (int)sizeof(hdspm_mixer_t));
3544 return err;
3545 }
3546
3547 hdspm->ss_channels = MADI_SS_CHANNELS;
3548 hdspm->ds_channels = MADI_DS_CHANNELS;
3549 hdspm->qs_channels = MADI_QS_CHANNELS;
3550
3551 snd_printdd("create alsa devices.\n");
3552 if ((err = snd_hdspm_create_alsa_devices(card, hdspm)) < 0)
3553 return err;
3554
3555 snd_hdspm_initialize_midi_flush(hdspm);
3556
3557 return 0;
3558}
3559
3560static int snd_hdspm_free(hdspm_t * hdspm)
3561{
3562
3563 if (hdspm->port) {
3564
3565 /* stop th audio, and cancel all interrupts */
3566 hdspm->control_register &=
3567 ~(HDSPM_Start | HDSPM_AudioInterruptEnable
3568 | HDSPM_Midi0InterruptEnable |
3569 HDSPM_Midi1InterruptEnable);
3570 hdspm_write(hdspm, HDSPM_controlRegister,
3571 hdspm->control_register);
3572 }
3573
3574 if (hdspm->irq >= 0)
3575 free_irq(hdspm->irq, (void *) hdspm);
3576
3577
3578 if (hdspm->mixer)
3579 kfree(hdspm->mixer);
3580
3581 if (hdspm->iobase)
3582 iounmap(hdspm->iobase);
3583
3584 snd_hdspm_memory_free(hdspm);
3585
3586 if (hdspm->port)
3587 pci_release_regions(hdspm->pci);
3588
3589 pci_disable_device(hdspm->pci);
3590 return 0;
3591}
3592
3593static void snd_hdspm_card_free(snd_card_t * card)
3594{
3595 hdspm_t *hdspm = (hdspm_t *) card->private_data;
3596
3597 if (hdspm)
3598 snd_hdspm_free(hdspm);
3599}
3600
3601static int __devinit snd_hdspm_probe(struct pci_dev *pci,
3602 const struct pci_device_id *pci_id)
3603{
3604 static int dev;
3605 hdspm_t *hdspm;
3606 snd_card_t *card;
3607 int err;
3608
3609 if (dev >= SNDRV_CARDS)
3610 return -ENODEV;
3611 if (!enable[dev]) {
3612 dev++;
3613 return -ENOENT;
3614 }
3615
3616 if (!(card = snd_card_new(index[dev], id[dev],
3617 THIS_MODULE, sizeof(hdspm_t))))
3618 return -ENOMEM;
3619
3620 hdspm = (hdspm_t *) card->private_data;
3621 card->private_free = snd_hdspm_card_free;
3622 hdspm->dev = dev;
3623 hdspm->pci = pci;
3624
3625 if ((err =
3626 snd_hdspm_create(card, hdspm, precise_ptr[dev],
3627 enable_monitor[dev])) < 0) {
3628 snd_card_free(card);
3629 return err;
3630 }
3631
3632 strcpy(card->shortname, "HDSPM MADI");
3633 sprintf(card->longname, "%s at 0x%lx, irq %d", hdspm->card_name,
3634 hdspm->port, hdspm->irq);
3635
3636 if ((err = snd_card_register(card)) < 0) {
3637 snd_card_free(card);
3638 return err;
3639 }
3640
3641 pci_set_drvdata(pci, card);
3642
3643 dev++;
3644 return 0;
3645}
3646
3647static void __devexit snd_hdspm_remove(struct pci_dev *pci)
3648{
3649 snd_card_free(pci_get_drvdata(pci));
3650 pci_set_drvdata(pci, NULL);
3651}
3652
3653static struct pci_driver driver = {
3654 .name = "RME Hammerfall DSP MADI",
3655 .id_table = snd_hdspm_ids,
3656 .probe = snd_hdspm_probe,
3657 .remove = __devexit_p(snd_hdspm_remove),
3658};
3659
3660
3661static int __init alsa_card_hdspm_init(void)
3662{
3663 return pci_register_driver(&driver);
3664}
3665
3666static void __exit alsa_card_hdspm_exit(void)
3667{
3668 pci_unregister_driver(&driver);
3669}
3670
3671module_init(alsa_card_hdspm_init)
3672module_exit(alsa_card_hdspm_exit)