aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorRemy Bruno <remy.bruno@trinnov.com>2006-10-16 06:46:32 -0400
committerJaroslav Kysela <perex@suse.cz>2007-02-09 03:00:57 -0500
commit3cee5a60ce18034a63f70ba2bdd54f85018ce960 (patch)
tree9054f39eadc635debe335723bd5aab31d9938cd9 /sound
parentb3b9c1cbb35125f7e43a323ebe89e7a74e3c1ac2 (diff)
[ALSA] hdspm: Add support for AES32
Add support for AES32. Difference between MADI and AES32 is done through revision. Master support is not finished for now (RME so-called DDS feature is not supported yet) Signed-off-by: Remy Bruno <remy.bruno@trinnov.com> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Jaroslav Kysela <perex@suse.cz>
Diffstat (limited to 'sound')
-rw-r--r--sound/pci/rme9652/hdspm.c1242
1 files changed, 1059 insertions, 183 deletions
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c
index 0547f6f04bdc..3d3a4ce3a35e 100644
--- a/sound/pci/rme9652/hdspm.c
+++ b/sound/pci/rme9652/hdspm.c
@@ -6,6 +6,8 @@
6 * code based on hdsp.c Paul Davis 6 * code based on hdsp.c Paul Davis
7 * Marcus Andersson 7 * Marcus Andersson
8 * Thomas Charbonnel 8 * Thomas Charbonnel
9 * Modified 2006-06-01 for AES32 support by Remy Bruno
10 * <remy.bruno@trinnov.com>
9 * 11 *
10 * This program is free software; you can redistribute it and/or modify 12 * 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 13 * it under the terms of the GNU General Public License as published by
@@ -77,7 +79,8 @@ MODULE_PARM_DESC(enable_monitor,
77 79
78MODULE_AUTHOR 80MODULE_AUTHOR
79 ("Winfried Ritsch <ritsch_AT_iem.at>, Paul Davis <paul@linuxaudiosystems.com>, " 81 ("Winfried Ritsch <ritsch_AT_iem.at>, Paul Davis <paul@linuxaudiosystems.com>, "
80 "Marcus Andersson, Thomas Charbonnel <thomas@undata.org>"); 82 "Marcus Andersson, Thomas Charbonnel <thomas@undata.org>, "
83 "Remy Bruno <remy.bruno@trinnov.com>");
81MODULE_DESCRIPTION("RME HDSPM"); 84MODULE_DESCRIPTION("RME HDSPM");
82MODULE_LICENSE("GPL"); 85MODULE_LICENSE("GPL");
83MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}"); 86MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
@@ -107,7 +110,12 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
107/* --- Read registers. --- 110/* --- Read registers. ---
108 These are defined as byte-offsets from the iobase value */ 111 These are defined as byte-offsets from the iobase value */
109#define HDSPM_statusRegister 0 112#define HDSPM_statusRegister 0
110#define HDSPM_statusRegister2 96 113/*#define HDSPM_statusRegister2 96 */
114/* after RME Windows driver sources, status2 is 4-byte word # 48 = word at
115 * offset 192, for AES32 *and* MADI
116 * => need to check that offset 192 is working on MADI */
117#define HDSPM_statusRegister2 192
118#define HDSPM_timecodeRegister 128
111 119
112#define HDSPM_midiDataIn0 360 120#define HDSPM_midiDataIn0 360
113#define HDSPM_midiDataIn1 364 121#define HDSPM_midiDataIn1 364
@@ -140,37 +148,50 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
140#define HDSPM_Frequency0 (1<<6) /* 0=44.1kHz/88.2kHz 1=48kHz/96kHz */ 148#define HDSPM_Frequency0 (1<<6) /* 0=44.1kHz/88.2kHz 1=48kHz/96kHz */
141#define HDSPM_Frequency1 (1<<7) /* 0=32kHz/64kHz */ 149#define HDSPM_Frequency1 (1<<7) /* 0=32kHz/64kHz */
142#define HDSPM_DoubleSpeed (1<<8) /* 0=normal speed, 1=double speed */ 150#define HDSPM_DoubleSpeed (1<<8) /* 0=normal speed, 1=double speed */
143#define HDSPM_QuadSpeed (1<<31) /* quad speed bit, not implemented now */ 151#define HDSPM_QuadSpeed (1<<31) /* quad speed bit */
144 152
153#define HDSPM_Professional (1<<9) /* Professional */ /* AES32 ONLY */
145#define HDSPM_TX_64ch (1<<10) /* Output 64channel MODE=1, 154#define HDSPM_TX_64ch (1<<10) /* Output 64channel MODE=1,
146 56channelMODE=0 */ 155 56channelMODE=0 */ /* MADI ONLY*/
156#define HDSPM_Emphasis (1<<10) /* Emphasis */ /* AES32 ONLY */
147 157
148#define HDSPM_AutoInp (1<<11) /* Auto Input (takeover) == Safe Mode, 158#define HDSPM_AutoInp (1<<11) /* Auto Input (takeover) == Safe Mode,
149 0=off, 1=on */ 159 0=off, 1=on */ /* MADI ONLY */
160#define HDSPM_Dolby (1<<11) /* Dolby = "NonAudio" ?? */ /* AES32 ONLY */
150 161
151#define HDSPM_InputSelect0 (1<<14) /* Input select 0= optical, 1=coax */ 162#define HDSPM_InputSelect0 (1<<14) /* Input select 0= optical, 1=coax */ /* MADI ONLY*/
152#define HDSPM_InputSelect1 (1<<15) /* should be 0 */ 163#define HDSPM_InputSelect1 (1<<15) /* should be 0 */
153 164
154#define HDSPM_SyncRef0 (1<<16) /* 0=WOrd, 1=MADI */ 165#define HDSPM_SyncRef0 (1<<16) /* 0=WOrd, 1=MADI */
155#define HDSPM_SyncRef1 (1<<17) /* should be 0 */ 166#define HDSPM_SyncRef1 (1<<17) /* for AES32: SyncRefN codes the AES # */
167#define HDSPM_SyncRef2 (1<<13)
168#define HDSPM_SyncRef3 (1<<25)
156 169
170#define HDSPM_SMUX (1<<18) /* Frame ??? */ /* MADI ONY */
157#define HDSPM_clr_tms (1<<19) /* clear track marker, do not use 171#define HDSPM_clr_tms (1<<19) /* clear track marker, do not use
158 AES additional bits in 172 AES additional bits in
159 lower 5 Audiodatabits ??? */ 173 lower 5 Audiodatabits ??? */
174#define HDSPM_taxi_reset (1<<20) /* ??? */ /* MADI ONLY ? */
175#define HDSPM_WCK48 (1<<20) /* Frame ??? = HDSPM_SMUX */ /* AES32 ONLY */
160 176
161#define HDSPM_Midi0InterruptEnable (1<<22) 177#define HDSPM_Midi0InterruptEnable (1<<22)
162#define HDSPM_Midi1InterruptEnable (1<<23) 178#define HDSPM_Midi1InterruptEnable (1<<23)
163 179
164#define HDSPM_LineOut (1<<24) /* Analog Out on channel 63/64 on=1, mute=0 */ 180#define HDSPM_LineOut (1<<24) /* Analog Out on channel 63/64 on=1, mute=0 */
165 181
182#define HDSPM_DS_DoubleWire (1<<26) /* AES32 ONLY */
183#define HDSPM_QS_DoubleWire (1<<27) /* AES32 ONLY */
184#define HDSPM_QS_QuadWire (1<<28) /* AES32 ONLY */
185
186#define HDSPM_wclk_sel (1<<30)
166 187
167/* --- bit helper defines */ 188/* --- bit helper defines */
168#define HDSPM_LatencyMask (HDSPM_Latency0|HDSPM_Latency1|HDSPM_Latency2) 189#define HDSPM_LatencyMask (HDSPM_Latency0|HDSPM_Latency1|HDSPM_Latency2)
169#define HDSPM_FrequencyMask (HDSPM_Frequency0|HDSPM_Frequency1) 190#define HDSPM_FrequencyMask (HDSPM_Frequency0|HDSPM_Frequency1|HDSPM_DoubleSpeed|HDSPM_QuadSpeed)
170#define HDSPM_InputMask (HDSPM_InputSelect0|HDSPM_InputSelect1) 191#define HDSPM_InputMask (HDSPM_InputSelect0|HDSPM_InputSelect1)
171#define HDSPM_InputOptical 0 192#define HDSPM_InputOptical 0
172#define HDSPM_InputCoaxial (HDSPM_InputSelect0) 193#define HDSPM_InputCoaxial (HDSPM_InputSelect0)
173#define HDSPM_SyncRefMask (HDSPM_SyncRef0|HDSPM_SyncRef1) 194#define HDSPM_SyncRefMask (HDSPM_SyncRef0|HDSPM_SyncRef1|HDSPM_SyncRef2|HDSPM_SyncRef3)
174#define HDSPM_SyncRef_Word 0 195#define HDSPM_SyncRef_Word 0
175#define HDSPM_SyncRef_MADI (HDSPM_SyncRef0) 196#define HDSPM_SyncRef_MADI (HDSPM_SyncRef0)
176 197
@@ -183,6 +204,9 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
183#define HDSPM_Frequency64KHz (HDSPM_DoubleSpeed|HDSPM_Frequency0) 204#define HDSPM_Frequency64KHz (HDSPM_DoubleSpeed|HDSPM_Frequency0)
184#define HDSPM_Frequency88_2KHz (HDSPM_DoubleSpeed|HDSPM_Frequency1) 205#define HDSPM_Frequency88_2KHz (HDSPM_DoubleSpeed|HDSPM_Frequency1)
185#define HDSPM_Frequency96KHz (HDSPM_DoubleSpeed|HDSPM_Frequency1|HDSPM_Frequency0) 206#define HDSPM_Frequency96KHz (HDSPM_DoubleSpeed|HDSPM_Frequency1|HDSPM_Frequency0)
207#define HDSPM_Frequency128KHz (HDSPM_QuadSpeed|HDSPM_Frequency0)
208#define HDSPM_Frequency176_4KHz (HDSPM_QuadSpeed|HDSPM_Frequency1)
209#define HDSPM_Frequency192KHz (HDSPM_QuadSpeed|HDSPM_Frequency1|HDSPM_Frequency0)
186 210
187/* --- for internal discrimination */ 211/* --- for internal discrimination */
188#define HDSPM_CLOCK_SOURCE_AUTOSYNC 0 /* Sample Clock Sources */ 212#define HDSPM_CLOCK_SOURCE_AUTOSYNC 0 /* Sample Clock Sources */
@@ -229,7 +253,8 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
229#define HDSPM_BIGENDIAN_MODE (1<<9) 253#define HDSPM_BIGENDIAN_MODE (1<<9)
230#define HDSPM_RD_MULTIPLE (1<<10) 254#define HDSPM_RD_MULTIPLE (1<<10)
231 255
232/* --- Status Register bits --- */ 256/* --- Status Register bits --- */ /* MADI ONLY */ /* Bits defined here and
257 that do not conflict with specific bits for AES32 seem to be valid also for the AES32 */
233#define HDSPM_audioIRQPending (1<<0) /* IRQ is high and pending */ 258#define HDSPM_audioIRQPending (1<<0) /* IRQ is high and pending */
234#define HDSPM_RX_64ch (1<<1) /* Input 64chan. MODE=1, 56chn. MODE=0 */ 259#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) */ 260#define HDSPM_AB_int (1<<2) /* InputChannel Opt=0, Coax=1 (like inp0) */
@@ -263,7 +288,7 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
263#define HDSPM_madiFreq176_4 (HDSPM_madiFreq3) 288#define HDSPM_madiFreq176_4 (HDSPM_madiFreq3)
264#define HDSPM_madiFreq192 (HDSPM_madiFreq3|HDSPM_madiFreq0) 289#define HDSPM_madiFreq192 (HDSPM_madiFreq3|HDSPM_madiFreq0)
265 290
266/* Status2 Register bits */ 291/* Status2 Register bits */ /* MADI ONLY */
267 292
268#define HDSPM_version0 (1<<0) /* not realy defined but I guess */ 293#define HDSPM_version0 (1<<0) /* not realy defined but I guess */
269#define HDSPM_version1 (1<<1) /* in former cards it was ??? */ 294#define HDSPM_version1 (1<<1) /* in former cards it was ??? */
@@ -297,6 +322,56 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
297#define HDSPM_SelSyncRef_MADI (HDSPM_SelSyncRef0) 322#define HDSPM_SelSyncRef_MADI (HDSPM_SelSyncRef0)
298#define HDSPM_SelSyncRef_NVALID (HDSPM_SelSyncRef0|HDSPM_SelSyncRef1|HDSPM_SelSyncRef2) 323#define HDSPM_SelSyncRef_NVALID (HDSPM_SelSyncRef0|HDSPM_SelSyncRef1|HDSPM_SelSyncRef2)
299 324
325/*
326 For AES32, bits for status, status2 and timecode are different
327*/
328/* status */
329#define HDSPM_AES32_wcLock 0x0200000
330#define HDSPM_AES32_wcFreq_bit 22
331/* (status >> HDSPM_AES32_wcFreq_bit) & 0xF gives WC frequency (cf function
332 HDSPM_bit2freq */
333#define HDSPM_AES32_syncref_bit 16
334/* (status >> HDSPM_AES32_syncref_bit) & 0xF gives sync source */
335
336#define HDSPM_AES32_AUTOSYNC_FROM_WORD 0
337#define HDSPM_AES32_AUTOSYNC_FROM_AES1 1
338#define HDSPM_AES32_AUTOSYNC_FROM_AES2 2
339#define HDSPM_AES32_AUTOSYNC_FROM_AES3 3
340#define HDSPM_AES32_AUTOSYNC_FROM_AES4 4
341#define HDSPM_AES32_AUTOSYNC_FROM_AES5 5
342#define HDSPM_AES32_AUTOSYNC_FROM_AES6 6
343#define HDSPM_AES32_AUTOSYNC_FROM_AES7 7
344#define HDSPM_AES32_AUTOSYNC_FROM_AES8 8
345#define HDSPM_AES32_AUTOSYNC_FROM_NONE -1
346
347/* status2 */
348/* HDSPM_LockAES_bit is given by HDSPM_LockAES >> (AES# - 1) */
349#define HDSPM_LockAES 0x80
350#define HDSPM_LockAES1 0x80
351#define HDSPM_LockAES2 0x40
352#define HDSPM_LockAES3 0x20
353#define HDSPM_LockAES4 0x10
354#define HDSPM_LockAES5 0x8
355#define HDSPM_LockAES6 0x4
356#define HDSPM_LockAES7 0x2
357#define HDSPM_LockAES8 0x1
358/*
359 Timecode
360 After windows driver sources, bits 4*i to 4*i+3 give the input frequency on
361 AES i+1
362 bits 3210
363 0001 32kHz
364 0010 44.1kHz
365 0011 48kHz
366 0100 64kHz
367 0101 88.2kHz
368 0110 96kHz
369 0111 128kHz
370 1000 176.4kHz
371 1001 192kHz
372 NB: Timecode register doesn't seem to work on AES32 card revision 230
373*/
374
300/* Mixer Values */ 375/* Mixer Values */
301#define UNITY_GAIN 32768 /* = 65536/2 */ 376#define UNITY_GAIN 32768 /* = 65536/2 */
302#define MINUS_INFINITY_GAIN 0 377#define MINUS_INFINITY_GAIN 0
@@ -314,10 +389,14 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
314 size is the same regardless of the number of channels, and 389 size is the same regardless of the number of channels, and
315 also the latency to use. 390 also the latency to use.
316 for one direction !!! 391 for one direction !!!
392 => need to mupltiply by 2!!
317*/ 393*/
318#define HDSPM_DMA_AREA_BYTES (HDSPM_MAX_CHANNELS * HDSPM_CHANNEL_BUFFER_BYTES) 394#define HDSPM_DMA_AREA_BYTES (2 * HDSPM_MAX_CHANNELS * HDSPM_CHANNEL_BUFFER_BYTES)
319#define HDSPM_DMA_AREA_KILOBYTES (HDSPM_DMA_AREA_BYTES/1024) 395#define HDSPM_DMA_AREA_KILOBYTES (HDSPM_DMA_AREA_BYTES/1024)
320 396
397/* revisions >= 230 indicate AES32 card */
398#define HDSPM_AESREVISION 230
399
321struct hdspm_midi { 400struct hdspm_midi {
322 struct hdspm *hdspm; 401 struct hdspm *hdspm;
323 int id; 402 int id;
@@ -336,7 +415,9 @@ struct hdspm {
336 struct snd_pcm_substream *playback_substream; /* and/or capture stream */ 415 struct snd_pcm_substream *playback_substream; /* and/or capture stream */
337 416
338 char *card_name; /* for procinfo */ 417 char *card_name; /* for procinfo */
339 unsigned short firmware_rev; /* dont know if relevant */ 418 unsigned short firmware_rev; /* dont know if relevant (yes if AES32)*/
419
420 unsigned char is_aes32; /* indicates if card is AES32 */
340 421
341 int precise_ptr; /* use precise pointers, to be tested */ 422 int precise_ptr; /* use precise pointers, to be tested */
342 int monitor_outs; /* set up monitoring outs init flag */ 423 int monitor_outs; /* set up monitoring outs init flag */
@@ -453,6 +534,15 @@ static int snd_hdspm_set_defaults(struct hdspm * hdspm);
453static void hdspm_set_sgbuf(struct hdspm * hdspm, struct snd_sg_buf *sgbuf, 534static void hdspm_set_sgbuf(struct hdspm * hdspm, struct snd_sg_buf *sgbuf,
454 unsigned int reg, int channels); 535 unsigned int reg, int channels);
455 536
537static inline int HDSPM_bit2freq(int n)
538{
539 static int bit2freq_tab[] = { 0, 32000, 44100, 48000, 64000, 88200,
540 96000, 128000, 176400, 192000 };
541 if (n < 1 || n > 9)
542 return 0;
543 return bit2freq_tab[n];
544}
545
456/* Write/read to/from HDSPM with Adresses in Bytes 546/* Write/read to/from HDSPM with Adresses in Bytes
457 not words but only 32Bit writes are allowed */ 547 not words but only 32Bit writes are allowed */
458 548
@@ -544,86 +634,105 @@ static inline int snd_hdspm_use_is_exclusive(struct hdspm * hdspm)
544/* check for external sample rate */ 634/* check for external sample rate */
545static inline int hdspm_external_sample_rate(struct hdspm * hdspm) 635static inline int hdspm_external_sample_rate(struct hdspm * hdspm)
546{ 636{
547 unsigned int status2 = hdspm_read(hdspm, HDSPM_statusRegister2); 637 if (hdspm->is_aes32) {
548 unsigned int status = hdspm_read(hdspm, HDSPM_statusRegister); 638 unsigned int status2 = hdspm_read(hdspm, HDSPM_statusRegister2);
549 unsigned int rate_bits; 639 unsigned int status = hdspm_read(hdspm, HDSPM_statusRegister);
550 int rate = 0; 640 unsigned int timecode = hdspm_read(hdspm, HDSPM_timecodeRegister);
641
642 int syncref = hdspm_autosync_ref(hdspm);
643
644 if (syncref == HDSPM_AES32_AUTOSYNC_FROM_WORD &&
645 status & HDSPM_AES32_wcLock)
646 return HDSPM_bit2freq((status >> HDSPM_AES32_wcFreq_bit) & 0xF);
647 if (syncref >= HDSPM_AES32_AUTOSYNC_FROM_AES1 &&
648 syncref <= HDSPM_AES32_AUTOSYNC_FROM_AES8 &&
649 status2 & (HDSPM_LockAES >>
650 (syncref - HDSPM_AES32_AUTOSYNC_FROM_AES1)))
651 return HDSPM_bit2freq((timecode >>
652 (4*(syncref-HDSPM_AES32_AUTOSYNC_FROM_AES1))) & 0xF);
653 return 0;
654 } else {
655 unsigned int status2 = hdspm_read(hdspm, HDSPM_statusRegister2);
656 unsigned int status = hdspm_read(hdspm, HDSPM_statusRegister);
657 unsigned int rate_bits;
658 int rate = 0;
551 659
552 /* if wordclock has synced freq and wordclock is valid */ 660 /* if wordclock has synced freq and wordclock is valid */
553 if ((status2 & HDSPM_wcLock) != 0 && 661 if ((status2 & HDSPM_wcLock) != 0 &&
554 (status & HDSPM_SelSyncRef0) == 0) { 662 (status & HDSPM_SelSyncRef0) == 0) {
555 663
556 rate_bits = status2 & HDSPM_wcFreqMask; 664 rate_bits = status2 & HDSPM_wcFreqMask;
557 665
558 switch (rate_bits) { 666 switch (rate_bits) {
559 case HDSPM_wcFreq32: 667 case HDSPM_wcFreq32:
560 rate = 32000; 668 rate = 32000;
561 break; 669 break;
562 case HDSPM_wcFreq44_1: 670 case HDSPM_wcFreq44_1:
563 rate = 44100; 671 rate = 44100;
564 break; 672 break;
565 case HDSPM_wcFreq48: 673 case HDSPM_wcFreq48:
566 rate = 48000; 674 rate = 48000;
567 break; 675 break;
568 case HDSPM_wcFreq64: 676 case HDSPM_wcFreq64:
569 rate = 64000; 677 rate = 64000;
570 break; 678 break;
571 case HDSPM_wcFreq88_2: 679 case HDSPM_wcFreq88_2:
572 rate = 88200; 680 rate = 88200;
573 break; 681 break;
574 case HDSPM_wcFreq96: 682 case HDSPM_wcFreq96:
575 rate = 96000; 683 rate = 96000;
576 break; 684 break;
577 /* Quadspeed Bit missing ???? */ 685 /* Quadspeed Bit missing ???? */
578 default: 686 default:
579 rate = 0; 687 rate = 0;
580 break; 688 break;
689 }
581 } 690 }
582 }
583 691
584 /* if rate detected and Syncref is Word than have it, word has priority to MADI */ 692 /* if rate detected and Syncref is Word than have it, word has priority to MADI */
585 if (rate != 0 693 if (rate != 0 &&
586 && (status2 & HDSPM_SelSyncRefMask) == HDSPM_SelSyncRef_WORD) 694 (status2 & HDSPM_SelSyncRefMask) == HDSPM_SelSyncRef_WORD)
587 return rate; 695 return rate;
588 696
589 /* maby a madi input (which is taken if sel sync is madi) */ 697 /* maby a madi input (which is taken if sel sync is madi) */
590 if (status & HDSPM_madiLock) { 698 if (status & HDSPM_madiLock) {
591 rate_bits = status & HDSPM_madiFreqMask; 699 rate_bits = status & HDSPM_madiFreqMask;
592 700
593 switch (rate_bits) { 701 switch (rate_bits) {
594 case HDSPM_madiFreq32: 702 case HDSPM_madiFreq32:
595 rate = 32000; 703 rate = 32000;
596 break; 704 break;
597 case HDSPM_madiFreq44_1: 705 case HDSPM_madiFreq44_1:
598 rate = 44100; 706 rate = 44100;
599 break; 707 break;
600 case HDSPM_madiFreq48: 708 case HDSPM_madiFreq48:
601 rate = 48000; 709 rate = 48000;
602 break; 710 break;
603 case HDSPM_madiFreq64: 711 case HDSPM_madiFreq64:
604 rate = 64000; 712 rate = 64000;
605 break; 713 break;
606 case HDSPM_madiFreq88_2: 714 case HDSPM_madiFreq88_2:
607 rate = 88200; 715 rate = 88200;
608 break; 716 break;
609 case HDSPM_madiFreq96: 717 case HDSPM_madiFreq96:
610 rate = 96000; 718 rate = 96000;
611 break; 719 break;
612 case HDSPM_madiFreq128: 720 case HDSPM_madiFreq128:
613 rate = 128000; 721 rate = 128000;
614 break; 722 break;
615 case HDSPM_madiFreq176_4: 723 case HDSPM_madiFreq176_4:
616 rate = 176400; 724 rate = 176400;
617 break; 725 break;
618 case HDSPM_madiFreq192: 726 case HDSPM_madiFreq192:
619 rate = 192000; 727 rate = 192000;
620 break; 728 break;
621 default: 729 default:
622 rate = 0; 730 rate = 0;
623 break; 731 break;
732 }
624 } 733 }
734 return rate;
625 } 735 }
626 return rate;
627} 736}
628 737
629/* Latency function */ 738/* Latency function */
@@ -676,7 +785,8 @@ static inline void hdspm_silence_playback(struct hdspm * hdspm)
676 int n = hdspm->period_bytes; 785 int n = hdspm->period_bytes;
677 void *buf = hdspm->playback_buffer; 786 void *buf = hdspm->playback_buffer;
678 787
679 snd_assert(buf != NULL, return); 788 if (buf == NULL)
789 return;
680 790
681 for (i = 0; i < HDSPM_MAX_CHANNELS; i++) { 791 for (i = 0; i < HDSPM_MAX_CHANNELS; i++) {
682 memset(buf, 0, n); 792 memset(buf, 0, n);
@@ -716,6 +826,7 @@ static int hdspm_set_rate(struct hdspm * hdspm, int rate, int called_internally)
716 int current_rate; 826 int current_rate;
717 int rate_bits; 827 int rate_bits;
718 int not_set = 0; 828 int not_set = 0;
829 int is_single, is_double, is_quad;
719 830
720 /* ASSUMPTION: hdspm->lock is either set, or there is no need for 831 /* ASSUMPTION: hdspm->lock is either set, or there is no need for
721 it (e.g. during module initialization). 832 it (e.g. during module initialization).
@@ -766,43 +877,56 @@ static int hdspm_set_rate(struct hdspm * hdspm, int rate, int called_internally)
766 changes in the read/write routines. 877 changes in the read/write routines.
767 */ 878 */
768 879
880 is_single = (current_rate <= 48000);
881 is_double = (current_rate > 48000 && current_rate <= 96000);
882 is_quad = (current_rate > 96000);
883
769 switch (rate) { 884 switch (rate) {
770 case 32000: 885 case 32000:
771 if (current_rate > 48000) { 886 if (!is_single)
772 reject_if_open = 1; 887 reject_if_open = 1;
773 }
774 rate_bits = HDSPM_Frequency32KHz; 888 rate_bits = HDSPM_Frequency32KHz;
775 break; 889 break;
776 case 44100: 890 case 44100:
777 if (current_rate > 48000) { 891 if (!is_single)
778 reject_if_open = 1; 892 reject_if_open = 1;
779 }
780 rate_bits = HDSPM_Frequency44_1KHz; 893 rate_bits = HDSPM_Frequency44_1KHz;
781 break; 894 break;
782 case 48000: 895 case 48000:
783 if (current_rate > 48000) { 896 if (!is_single)
784 reject_if_open = 1; 897 reject_if_open = 1;
785 }
786 rate_bits = HDSPM_Frequency48KHz; 898 rate_bits = HDSPM_Frequency48KHz;
787 break; 899 break;
788 case 64000: 900 case 64000:
789 if (current_rate <= 48000) { 901 if (!is_double)
790 reject_if_open = 1; 902 reject_if_open = 1;
791 }
792 rate_bits = HDSPM_Frequency64KHz; 903 rate_bits = HDSPM_Frequency64KHz;
793 break; 904 break;
794 case 88200: 905 case 88200:
795 if (current_rate <= 48000) { 906 if (!is_double)
796 reject_if_open = 1; 907 reject_if_open = 1;
797 }
798 rate_bits = HDSPM_Frequency88_2KHz; 908 rate_bits = HDSPM_Frequency88_2KHz;
799 break; 909 break;
800 case 96000: 910 case 96000:
801 if (current_rate <= 48000) { 911 if (!is_double)
802 reject_if_open = 1; 912 reject_if_open = 1;
803 }
804 rate_bits = HDSPM_Frequency96KHz; 913 rate_bits = HDSPM_Frequency96KHz;
805 break; 914 break;
915 case 128000:
916 if (!is_quad)
917 reject_if_open = 1;
918 rate_bits = HDSPM_Frequency128KHz;
919 break;
920 case 176400:
921 if (!is_quad)
922 reject_if_open = 1;
923 rate_bits = HDSPM_Frequency176_4KHz;
924 break;
925 case 192000:
926 if (!is_quad)
927 reject_if_open = 1;
928 rate_bits = HDSPM_Frequency192KHz;
929 break;
806 default: 930 default:
807 return -EINVAL; 931 return -EINVAL;
808 } 932 }
@@ -819,7 +943,7 @@ static int hdspm_set_rate(struct hdspm * hdspm, int rate, int called_internally)
819 hdspm->control_register |= rate_bits; 943 hdspm->control_register |= rate_bits;
820 hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register); 944 hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
821 945
822 if (rate > 64000) 946 if (rate > 96000 /* 64000*/)
823 hdspm->channel_map = channel_map_madi_qs; 947 hdspm->channel_map = channel_map_madi_qs;
824 else if (rate > 48000) 948 else if (rate > 48000)
825 hdspm->channel_map = channel_map_madi_ds; 949 hdspm->channel_map = channel_map_madi_ds;
@@ -1455,11 +1579,27 @@ static int hdspm_pref_sync_ref(struct hdspm * hdspm)
1455 /* Notice that this looks at the requested sync source, 1579 /* Notice that this looks at the requested sync source,
1456 not the one actually in use. 1580 not the one actually in use.
1457 */ 1581 */
1458 switch (hdspm->control_register & HDSPM_SyncRefMask) { 1582 if (hdspm->is_aes32) {
1459 case HDSPM_SyncRef_Word: 1583 switch (hdspm->control_register & HDSPM_SyncRefMask) {
1460 return HDSPM_SYNC_FROM_WORD; 1584 /* number gives AES index, except for 0 which
1461 case HDSPM_SyncRef_MADI: 1585 corresponds to WordClock */
1462 return HDSPM_SYNC_FROM_MADI; 1586 case 0: return 0;
1587 case HDSPM_SyncRef0: return 1;
1588 case HDSPM_SyncRef1: return 2;
1589 case HDSPM_SyncRef1+HDSPM_SyncRef0: return 3;
1590 case HDSPM_SyncRef2: return 4;
1591 case HDSPM_SyncRef2+HDSPM_SyncRef0: return 5;
1592 case HDSPM_SyncRef2+HDSPM_SyncRef1: return 6;
1593 case HDSPM_SyncRef2+HDSPM_SyncRef1+HDSPM_SyncRef0: return 7;
1594 case HDSPM_SyncRef3: return 8;
1595 }
1596 } else {
1597 switch (hdspm->control_register & HDSPM_SyncRefMask) {
1598 case HDSPM_SyncRef_Word:
1599 return HDSPM_SYNC_FROM_WORD;
1600 case HDSPM_SyncRef_MADI:
1601 return HDSPM_SYNC_FROM_MADI;
1602 }
1463 } 1603 }
1464 1604
1465 return HDSPM_SYNC_FROM_WORD; 1605 return HDSPM_SYNC_FROM_WORD;
@@ -1469,15 +1609,49 @@ static int hdspm_set_pref_sync_ref(struct hdspm * hdspm, int pref)
1469{ 1609{
1470 hdspm->control_register &= ~HDSPM_SyncRefMask; 1610 hdspm->control_register &= ~HDSPM_SyncRefMask;
1471 1611
1472 switch (pref) { 1612 if (hdspm->is_aes32) {
1473 case HDSPM_SYNC_FROM_MADI: 1613 switch (pref) {
1474 hdspm->control_register |= HDSPM_SyncRef_MADI; 1614 case 0:
1475 break; 1615 hdspm->control_register |= 0;
1476 case HDSPM_SYNC_FROM_WORD: 1616 break;
1477 hdspm->control_register |= HDSPM_SyncRef_Word; 1617 case 1:
1478 break; 1618 hdspm->control_register |= HDSPM_SyncRef0;
1479 default: 1619 break;
1480 return -1; 1620 case 2:
1621 hdspm->control_register |= HDSPM_SyncRef1;
1622 break;
1623 case 3:
1624 hdspm->control_register |= HDSPM_SyncRef1+HDSPM_SyncRef0;
1625 break;
1626 case 4:
1627 hdspm->control_register |= HDSPM_SyncRef2;
1628 break;
1629 case 5:
1630 hdspm->control_register |= HDSPM_SyncRef2+HDSPM_SyncRef0;
1631 break;
1632 case 6:
1633 hdspm->control_register |= HDSPM_SyncRef2+HDSPM_SyncRef1;
1634 break;
1635 case 7:
1636 hdspm->control_register |= HDSPM_SyncRef2+HDSPM_SyncRef1+HDSPM_SyncRef0;
1637 break;
1638 case 8:
1639 hdspm->control_register |= HDSPM_SyncRef3;
1640 break;
1641 default:
1642 return -1;
1643 }
1644 } else {
1645 switch (pref) {
1646 case HDSPM_SYNC_FROM_MADI:
1647 hdspm->control_register |= HDSPM_SyncRef_MADI;
1648 break;
1649 case HDSPM_SYNC_FROM_WORD:
1650 hdspm->control_register |= HDSPM_SyncRef_Word;
1651 break;
1652 default:
1653 return -1;
1654 }
1481 } 1655 }
1482 hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register); 1656 hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
1483 return 0; 1657 return 0;
@@ -1486,18 +1660,36 @@ static int hdspm_set_pref_sync_ref(struct hdspm * hdspm, int pref)
1486static int snd_hdspm_info_pref_sync_ref(struct snd_kcontrol *kcontrol, 1660static int snd_hdspm_info_pref_sync_ref(struct snd_kcontrol *kcontrol,
1487 struct snd_ctl_elem_info *uinfo) 1661 struct snd_ctl_elem_info *uinfo)
1488{ 1662{
1489 static char *texts[] = { "Word", "MADI" }; 1663 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
1490 1664
1491 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 1665 if (hdspm->is_aes32) {
1492 uinfo->count = 1; 1666 static char *texts[] = { "Word", "AES1", "AES2", "AES3",
1667 "AES4", "AES5", "AES6", "AES7", "AES8" };
1493 1668
1494 uinfo->value.enumerated.items = 2; 1669 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1670 uinfo->count = 1;
1495 1671
1496 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) 1672 uinfo->value.enumerated.items = 9;
1497 uinfo->value.enumerated.item = 1673
1498 uinfo->value.enumerated.items - 1; 1674 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1499 strcpy(uinfo->value.enumerated.name, 1675 uinfo->value.enumerated.item =
1500 texts[uinfo->value.enumerated.item]); 1676 uinfo->value.enumerated.items - 1;
1677 strcpy(uinfo->value.enumerated.name,
1678 texts[uinfo->value.enumerated.item]);
1679 } else {
1680 static char *texts[] = { "Word", "MADI" };
1681
1682 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1683 uinfo->count = 1;
1684
1685 uinfo->value.enumerated.items = 2;
1686
1687 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1688 uinfo->value.enumerated.item =
1689 uinfo->value.enumerated.items - 1;
1690 strcpy(uinfo->value.enumerated.name,
1691 texts[uinfo->value.enumerated.item]);
1692 }
1501 return 0; 1693 return 0;
1502} 1694}
1503 1695
@@ -1517,7 +1709,7 @@ static int snd_hdspm_put_pref_sync_ref(struct snd_kcontrol *kcontrol,
1517 int change, max; 1709 int change, max;
1518 unsigned int val; 1710 unsigned int val;
1519 1711
1520 max = 2; 1712 max = hdspm->is_aes32 ? 9 : 2;
1521 1713
1522 if (!snd_hdspm_use_is_exclusive(hdspm)) 1714 if (!snd_hdspm_use_is_exclusive(hdspm))
1523 return -EBUSY; 1715 return -EBUSY;
@@ -1542,40 +1734,64 @@ static int snd_hdspm_put_pref_sync_ref(struct snd_kcontrol *kcontrol,
1542 1734
1543static int hdspm_autosync_ref(struct hdspm * hdspm) 1735static int hdspm_autosync_ref(struct hdspm * hdspm)
1544{ 1736{
1545 /* This looks at the autosync selected sync reference */ 1737 if (hdspm->is_aes32) {
1546 unsigned int status2 = hdspm_read(hdspm, HDSPM_statusRegister2); 1738 unsigned int status = hdspm_read(hdspm, HDSPM_statusRegister);
1547 1739 unsigned int syncref = (status >> HDSPM_AES32_syncref_bit) & 0xF;
1548 switch (status2 & HDSPM_SelSyncRefMask) { 1740 if (syncref == 0)
1549 1741 return HDSPM_AES32_AUTOSYNC_FROM_WORD;
1550 case HDSPM_SelSyncRef_WORD: 1742 if (syncref <= 8)
1551 return HDSPM_AUTOSYNC_FROM_WORD; 1743 return syncref;
1552 1744 return HDSPM_AES32_AUTOSYNC_FROM_NONE;
1553 case HDSPM_SelSyncRef_MADI: 1745 } else {
1554 return HDSPM_AUTOSYNC_FROM_MADI; 1746 /* This looks at the autosync selected sync reference */
1555 1747 unsigned int status2 = hdspm_read(hdspm, HDSPM_statusRegister2);
1556 case HDSPM_SelSyncRef_NVALID: 1748
1557 return HDSPM_AUTOSYNC_FROM_NONE; 1749 switch (status2 & HDSPM_SelSyncRefMask) {
1750 case HDSPM_SelSyncRef_WORD:
1751 return HDSPM_AUTOSYNC_FROM_WORD;
1752 case HDSPM_SelSyncRef_MADI:
1753 return HDSPM_AUTOSYNC_FROM_MADI;
1754 case HDSPM_SelSyncRef_NVALID:
1755 return HDSPM_AUTOSYNC_FROM_NONE;
1756 default:
1757 return 0;
1758 }
1558 1759
1559 default:
1560 return 0; 1760 return 0;
1561 } 1761 }
1562
1563 return 0;
1564} 1762}
1565 1763
1566static int snd_hdspm_info_autosync_ref(struct snd_kcontrol *kcontrol, 1764static int snd_hdspm_info_autosync_ref(struct snd_kcontrol *kcontrol,
1567 struct snd_ctl_elem_info *uinfo) 1765 struct snd_ctl_elem_info *uinfo)
1568{ 1766{
1569 static char *texts[] = { "WordClock", "MADI", "None" }; 1767 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
1570 1768
1571 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 1769 if (hdspm->is_aes32) {
1572 uinfo->count = 1; 1770 static char *texts[] = { "WordClock", "AES1", "AES2", "AES3",
1573 uinfo->value.enumerated.items = 3; 1771 "AES4", "AES5", "AES6", "AES7", "AES8", "None"};
1574 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) 1772
1575 uinfo->value.enumerated.item = 1773 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1576 uinfo->value.enumerated.items - 1; 1774 uinfo->count = 1;
1577 strcpy(uinfo->value.enumerated.name, 1775 uinfo->value.enumerated.items = 10;
1578 texts[uinfo->value.enumerated.item]); 1776 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1777 uinfo->value.enumerated.item =
1778 uinfo->value.enumerated.items - 1;
1779 strcpy(uinfo->value.enumerated.name,
1780 texts[uinfo->value.enumerated.item]);
1781 }
1782 else
1783 {
1784 static char *texts[] = { "WordClock", "MADI", "None" };
1785
1786 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1787 uinfo->count = 1;
1788 uinfo->value.enumerated.items = 3;
1789 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1790 uinfo->value.enumerated.item =
1791 uinfo->value.enumerated.items - 1;
1792 strcpy(uinfo->value.enumerated.name,
1793 texts[uinfo->value.enumerated.item]);
1794 }
1579 return 0; 1795 return 0;
1580} 1796}
1581 1797
@@ -1841,6 +2057,195 @@ static int snd_hdspm_put_safe_mode(struct snd_kcontrol *kcontrol,
1841 return change; 2057 return change;
1842} 2058}
1843 2059
2060#define HDSPM_EMPHASIS(xname, xindex) \
2061{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2062 .name = xname, \
2063 .index = xindex, \
2064 .info = snd_hdspm_info_emphasis, \
2065 .get = snd_hdspm_get_emphasis, \
2066 .put = snd_hdspm_put_emphasis \
2067}
2068
2069static int hdspm_emphasis(struct hdspm * hdspm)
2070{
2071 return (hdspm->control_register & HDSPM_Emphasis) ? 1 : 0;
2072}
2073
2074static int hdspm_set_emphasis(struct hdspm * hdspm, int emp)
2075{
2076 if (emp)
2077 hdspm->control_register |= HDSPM_Emphasis;
2078 else
2079 hdspm->control_register &= ~HDSPM_Emphasis;
2080 hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
2081
2082 return 0;
2083}
2084
2085static int snd_hdspm_info_emphasis(struct snd_kcontrol *kcontrol,
2086 struct snd_ctl_elem_info *uinfo)
2087{
2088 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
2089 uinfo->count = 1;
2090 uinfo->value.integer.min = 0;
2091 uinfo->value.integer.max = 1;
2092 return 0;
2093}
2094
2095static int snd_hdspm_get_emphasis(struct snd_kcontrol *kcontrol,
2096 struct snd_ctl_elem_value *ucontrol)
2097{
2098 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
2099
2100 spin_lock_irq(&hdspm->lock);
2101 ucontrol->value.enumerated.item[0] = hdspm_emphasis(hdspm);
2102 spin_unlock_irq(&hdspm->lock);
2103 return 0;
2104}
2105
2106static int snd_hdspm_put_emphasis(struct snd_kcontrol *kcontrol,
2107 struct snd_ctl_elem_value *ucontrol)
2108{
2109 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
2110 int change;
2111 unsigned int val;
2112
2113 if (!snd_hdspm_use_is_exclusive(hdspm))
2114 return -EBUSY;
2115 val = ucontrol->value.integer.value[0] & 1;
2116 spin_lock_irq(&hdspm->lock);
2117 change = (int) val != hdspm_emphasis(hdspm);
2118 hdspm_set_emphasis(hdspm, val);
2119 spin_unlock_irq(&hdspm->lock);
2120 return change;
2121}
2122
2123#define HDSPM_DOLBY(xname, xindex) \
2124{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2125 .name = xname, \
2126 .index = xindex, \
2127 .info = snd_hdspm_info_dolby, \
2128 .get = snd_hdspm_get_dolby, \
2129 .put = snd_hdspm_put_dolby \
2130}
2131
2132static int hdspm_dolby(struct hdspm * hdspm)
2133{
2134 return (hdspm->control_register & HDSPM_Dolby) ? 1 : 0;
2135}
2136
2137static int hdspm_set_dolby(struct hdspm * hdspm, int dol)
2138{
2139 if (dol)
2140 hdspm->control_register |= HDSPM_Dolby;
2141 else
2142 hdspm->control_register &= ~HDSPM_Dolby;
2143 hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
2144
2145 return 0;
2146}
2147
2148static int snd_hdspm_info_dolby(struct snd_kcontrol *kcontrol,
2149 struct snd_ctl_elem_info *uinfo)
2150{
2151 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
2152 uinfo->count = 1;
2153 uinfo->value.integer.min = 0;
2154 uinfo->value.integer.max = 1;
2155 return 0;
2156}
2157
2158static int snd_hdspm_get_dolby(struct snd_kcontrol *kcontrol,
2159 struct snd_ctl_elem_value *ucontrol)
2160{
2161 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
2162
2163 spin_lock_irq(&hdspm->lock);
2164 ucontrol->value.enumerated.item[0] = hdspm_dolby(hdspm);
2165 spin_unlock_irq(&hdspm->lock);
2166 return 0;
2167}
2168
2169static int snd_hdspm_put_dolby(struct snd_kcontrol *kcontrol,
2170 struct snd_ctl_elem_value *ucontrol)
2171{
2172 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
2173 int change;
2174 unsigned int val;
2175
2176 if (!snd_hdspm_use_is_exclusive(hdspm))
2177 return -EBUSY;
2178 val = ucontrol->value.integer.value[0] & 1;
2179 spin_lock_irq(&hdspm->lock);
2180 change = (int) val != hdspm_dolby(hdspm);
2181 hdspm_set_dolby(hdspm, val);
2182 spin_unlock_irq(&hdspm->lock);
2183 return change;
2184}
2185
2186#define HDSPM_PROFESSIONAL(xname, xindex) \
2187{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2188 .name = xname, \
2189 .index = xindex, \
2190 .info = snd_hdspm_info_professional, \
2191 .get = snd_hdspm_get_professional, \
2192 .put = snd_hdspm_put_professional \
2193}
2194
2195static int hdspm_professional(struct hdspm * hdspm)
2196{
2197 return (hdspm->control_register & HDSPM_Professional) ? 1 : 0;
2198}
2199
2200static int hdspm_set_professional(struct hdspm * hdspm, int dol)
2201{
2202 if (dol)
2203 hdspm->control_register |= HDSPM_Professional;
2204 else
2205 hdspm->control_register &= ~HDSPM_Professional;
2206 hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
2207
2208 return 0;
2209}
2210
2211static int snd_hdspm_info_professional(struct snd_kcontrol *kcontrol,
2212 struct snd_ctl_elem_info *uinfo)
2213{
2214 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
2215 uinfo->count = 1;
2216 uinfo->value.integer.min = 0;
2217 uinfo->value.integer.max = 1;
2218 return 0;
2219}
2220
2221static int snd_hdspm_get_professional(struct snd_kcontrol *kcontrol,
2222 struct snd_ctl_elem_value *ucontrol)
2223{
2224 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
2225
2226 spin_lock_irq(&hdspm->lock);
2227 ucontrol->value.enumerated.item[0] = hdspm_professional(hdspm);
2228 spin_unlock_irq(&hdspm->lock);
2229 return 0;
2230}
2231
2232static int snd_hdspm_put_professional(struct snd_kcontrol *kcontrol,
2233 struct snd_ctl_elem_value *ucontrol)
2234{
2235 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
2236 int change;
2237 unsigned int val;
2238
2239 if (!snd_hdspm_use_is_exclusive(hdspm))
2240 return -EBUSY;
2241 val = ucontrol->value.integer.value[0] & 1;
2242 spin_lock_irq(&hdspm->lock);
2243 change = (int) val != hdspm_professional(hdspm);
2244 hdspm_set_professional(hdspm, val);
2245 spin_unlock_irq(&hdspm->lock);
2246 return change;
2247}
2248
1844#define HDSPM_INPUT_SELECT(xname, xindex) \ 2249#define HDSPM_INPUT_SELECT(xname, xindex) \
1845{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 2250{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1846 .name = xname, \ 2251 .name = xname, \
@@ -1912,6 +2317,163 @@ static int snd_hdspm_put_input_select(struct snd_kcontrol *kcontrol,
1912 return change; 2317 return change;
1913} 2318}
1914 2319
2320#define HDSPM_DS_WIRE(xname, xindex) \
2321{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2322 .name = xname, \
2323 .index = xindex, \
2324 .info = snd_hdspm_info_ds_wire, \
2325 .get = snd_hdspm_get_ds_wire, \
2326 .put = snd_hdspm_put_ds_wire \
2327}
2328
2329static int hdspm_ds_wire(struct hdspm * hdspm)
2330{
2331 return (hdspm->control_register & HDSPM_DS_DoubleWire) ? 1 : 0;
2332}
2333
2334static int hdspm_set_ds_wire(struct hdspm * hdspm, int ds)
2335{
2336 if (ds)
2337 hdspm->control_register |= HDSPM_DS_DoubleWire;
2338 else
2339 hdspm->control_register &= ~HDSPM_DS_DoubleWire;
2340 hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
2341
2342 return 0;
2343}
2344
2345static int snd_hdspm_info_ds_wire(struct snd_kcontrol *kcontrol,
2346 struct snd_ctl_elem_info *uinfo)
2347{
2348 static char *texts[] = { "Single", "Double" };
2349
2350 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2351 uinfo->count = 1;
2352 uinfo->value.enumerated.items = 2;
2353
2354 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
2355 uinfo->value.enumerated.item =
2356 uinfo->value.enumerated.items - 1;
2357 strcpy(uinfo->value.enumerated.name,
2358 texts[uinfo->value.enumerated.item]);
2359
2360 return 0;
2361}
2362
2363static int snd_hdspm_get_ds_wire(struct snd_kcontrol *kcontrol,
2364 struct snd_ctl_elem_value *ucontrol)
2365{
2366 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
2367
2368 spin_lock_irq(&hdspm->lock);
2369 ucontrol->value.enumerated.item[0] = hdspm_ds_wire(hdspm);
2370 spin_unlock_irq(&hdspm->lock);
2371 return 0;
2372}
2373
2374static int snd_hdspm_put_ds_wire(struct snd_kcontrol *kcontrol,
2375 struct snd_ctl_elem_value *ucontrol)
2376{
2377 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
2378 int change;
2379 unsigned int val;
2380
2381 if (!snd_hdspm_use_is_exclusive(hdspm))
2382 return -EBUSY;
2383 val = ucontrol->value.integer.value[0] & 1;
2384 spin_lock_irq(&hdspm->lock);
2385 change = (int) val != hdspm_ds_wire(hdspm);
2386 hdspm_set_ds_wire(hdspm, val);
2387 spin_unlock_irq(&hdspm->lock);
2388 return change;
2389}
2390
2391#define HDSPM_QS_WIRE(xname, xindex) \
2392{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2393 .name = xname, \
2394 .index = xindex, \
2395 .info = snd_hdspm_info_qs_wire, \
2396 .get = snd_hdspm_get_qs_wire, \
2397 .put = snd_hdspm_put_qs_wire \
2398}
2399
2400static int hdspm_qs_wire(struct hdspm * hdspm)
2401{
2402 if (hdspm->control_register & HDSPM_QS_DoubleWire)
2403 return 1;
2404 if (hdspm->control_register & HDSPM_QS_QuadWire)
2405 return 2;
2406 return 0;
2407}
2408
2409static int hdspm_set_qs_wire(struct hdspm * hdspm, int mode)
2410{
2411 hdspm->control_register &= ~(HDSPM_QS_DoubleWire | HDSPM_QS_QuadWire);
2412 switch (mode) {
2413 case 0:
2414 break;
2415 case 1:
2416 hdspm->control_register |= HDSPM_QS_DoubleWire;
2417 break;
2418 case 2:
2419 hdspm->control_register |= HDSPM_QS_QuadWire;
2420 break;
2421 }
2422 hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
2423
2424 return 0;
2425}
2426
2427static int snd_hdspm_info_qs_wire(struct snd_kcontrol *kcontrol,
2428 struct snd_ctl_elem_info *uinfo)
2429{
2430 static char *texts[] = { "Single", "Double", "Quad" };
2431
2432 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2433 uinfo->count = 1;
2434 uinfo->value.enumerated.items = 3;
2435
2436 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
2437 uinfo->value.enumerated.item =
2438 uinfo->value.enumerated.items - 1;
2439 strcpy(uinfo->value.enumerated.name,
2440 texts[uinfo->value.enumerated.item]);
2441
2442 return 0;
2443}
2444
2445static int snd_hdspm_get_qs_wire(struct snd_kcontrol *kcontrol,
2446 struct snd_ctl_elem_value *ucontrol)
2447{
2448 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
2449
2450 spin_lock_irq(&hdspm->lock);
2451 ucontrol->value.enumerated.item[0] = hdspm_qs_wire(hdspm);
2452 spin_unlock_irq(&hdspm->lock);
2453 return 0;
2454}
2455
2456static int snd_hdspm_put_qs_wire(struct snd_kcontrol *kcontrol,
2457 struct snd_ctl_elem_value *ucontrol)
2458{
2459 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
2460 int change;
2461 int val;
2462
2463 if (!snd_hdspm_use_is_exclusive(hdspm))
2464 return -EBUSY;
2465 val = ucontrol->value.integer.value[0];
2466 if (val < 0)
2467 val = 0;
2468 if (val > 2)
2469 val = 2;
2470 spin_lock_irq(&hdspm->lock);
2471 change = (int) val != hdspm_qs_wire(hdspm);
2472 hdspm_set_qs_wire(hdspm, val);
2473 spin_unlock_irq(&hdspm->lock);
2474 return change;
2475}
2476
1915/* Simple Mixer 2477/* Simple Mixer
1916 deprecated since to much faders ??? 2478 deprecated since to much faders ???
1917 MIXER interface says output (source, destination, value) 2479 MIXER interface says output (source, destination, value)
@@ -2135,14 +2697,24 @@ static int snd_hdspm_info_sync_check(struct snd_kcontrol *kcontrol,
2135 2697
2136static int hdspm_wc_sync_check(struct hdspm * hdspm) 2698static int hdspm_wc_sync_check(struct hdspm * hdspm)
2137{ 2699{
2138 int status2 = hdspm_read(hdspm, HDSPM_statusRegister2); 2700 if (hdspm->is_aes32) {
2139 if (status2 & HDSPM_wcLock) { 2701 int status = hdspm_read(hdspm, HDSPM_statusRegister);
2140 if (status2 & HDSPM_wcSync) 2702 if (status & HDSPM_AES32_wcLock) {
2703 /* I don't know how to differenciate sync from lock.
2704 Doing as if sync for now */
2141 return 2; 2705 return 2;
2142 else 2706 }
2143 return 1; 2707 return 0;
2708 } else {
2709 int status2 = hdspm_read(hdspm, HDSPM_statusRegister2);
2710 if (status2 & HDSPM_wcLock) {
2711 if (status2 & HDSPM_wcSync)
2712 return 2;
2713 else
2714 return 1;
2715 }
2716 return 0;
2144 } 2717 }
2145 return 0;
2146} 2718}
2147 2719
2148static int snd_hdspm_get_wc_sync_check(struct snd_kcontrol *kcontrol, 2720static int snd_hdspm_get_wc_sync_check(struct snd_kcontrol *kcontrol,
@@ -2188,9 +2760,43 @@ static int snd_hdspm_get_madisync_sync_check(struct snd_kcontrol *kcontrol,
2188} 2760}
2189 2761
2190 2762
2763#define HDSPM_AES_SYNC_CHECK(xname, xindex) \
2764{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2765 .name = xname, \
2766 .index = xindex, \
2767 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
2768 .info = snd_hdspm_info_sync_check, \
2769 .get = snd_hdspm_get_aes_sync_check \
2770}
2771
2772static int hdspm_aes_sync_check(struct hdspm * hdspm, int idx)
2773{
2774 int status2 = hdspm_read(hdspm, HDSPM_statusRegister2);
2775 if (status2 & (HDSPM_LockAES >> idx)) {
2776 /* I don't know how to differenciate sync from lock.
2777 Doing as if sync for now */
2778 return 2;
2779 }
2780 return 0;
2781}
2782
2783static int snd_hdspm_get_aes_sync_check(struct snd_kcontrol *kcontrol,
2784 struct snd_ctl_elem_value *ucontrol)
2785{
2786 int offset;
2787 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
2788
2789 offset = ucontrol->id.index - 1;
2790 if (offset < 0 || offset >= 8)
2791 return -EINVAL;
2792
2793 ucontrol->value.enumerated.item[0] =
2794 hdspm_aes_sync_check(hdspm, offset);
2795 return 0;
2796}
2191 2797
2192 2798
2193static struct snd_kcontrol_new snd_hdspm_controls[] = { 2799static struct snd_kcontrol_new snd_hdspm_controls_madi[] = {
2194 2800
2195 HDSPM_MIXER("Mixer", 0), 2801 HDSPM_MIXER("Mixer", 0),
2196/* 'Sample Clock Source' complies with the alsa control naming scheme */ 2802/* 'Sample Clock Source' complies with the alsa control naming scheme */
@@ -2211,6 +2817,29 @@ static struct snd_kcontrol_new snd_hdspm_controls[] = {
2211 HDSPM_INPUT_SELECT("Input Select", 0), 2817 HDSPM_INPUT_SELECT("Input Select", 0),
2212}; 2818};
2213 2819
2820static struct snd_kcontrol_new snd_hdspm_controls_aes32[] = {
2821
2822 HDSPM_MIXER("Mixer", 0),
2823/* 'Sample Clock Source' complies with the alsa control naming scheme */
2824 HDSPM_CLOCK_SOURCE("Sample Clock Source", 0),
2825
2826 HDSPM_SYSTEM_CLOCK_MODE("System Clock Mode", 0),
2827 HDSPM_PREF_SYNC_REF("Preferred Sync Reference", 0),
2828 HDSPM_AUTOSYNC_REF("AutoSync Reference", 0),
2829 HDSPM_SYSTEM_SAMPLE_RATE("System Sample Rate", 0),
2830/* 'External Rate' complies with the alsa control naming scheme */
2831 HDSPM_AUTOSYNC_SAMPLE_RATE("External Rate", 0),
2832 HDSPM_WC_SYNC_CHECK("Word Clock Lock Status", 0),
2833/* HDSPM_AES_SYNC_CHECK("AES Lock Status", 0),*/ /* created in snd_hdspm_create_controls() */
2834 HDSPM_LINE_OUT("Line Out", 0),
2835 HDSPM_EMPHASIS("Emphasis", 0),
2836 HDSPM_DOLBY("Non Audio", 0),
2837 HDSPM_PROFESSIONAL("Professional", 0),
2838 HDSPM_C_TMS("Clear Track Marker", 0),
2839 HDSPM_DS_WIRE("Double Speed Wire Mode", 0),
2840 HDSPM_QS_WIRE("Quad Speed Wire Mode", 0),
2841};
2842
2214static struct snd_kcontrol_new snd_hdspm_playback_mixer = HDSPM_PLAYBACK_MIXER; 2843static struct snd_kcontrol_new snd_hdspm_playback_mixer = HDSPM_PLAYBACK_MIXER;
2215 2844
2216 2845
@@ -2245,20 +2874,40 @@ static int snd_hdspm_create_controls(struct snd_card *card, struct hdspm * hdspm
2245 struct snd_kcontrol *kctl; 2874 struct snd_kcontrol *kctl;
2246 2875
2247 /* add control list first */ 2876 /* add control list first */
2248 2877 if (hdspm->is_aes32) {
2249 for (idx = 0; idx < ARRAY_SIZE(snd_hdspm_controls); idx++) { 2878 struct snd_kcontrol_new aes_sync_ctl =
2250 if ((err = 2879 HDSPM_AES_SYNC_CHECK("AES Lock Status", 0);
2251 snd_ctl_add(card, kctl = 2880
2252 snd_ctl_new1(&snd_hdspm_controls[idx], 2881 for (idx = 0; idx < ARRAY_SIZE(snd_hdspm_controls_aes32);
2253 hdspm))) < 0) { 2882 idx++) {
2254 return err; 2883 err = snd_ctl_add(card,
2884 snd_ctl_new1(&snd_hdspm_controls_aes32[idx],
2885 hdspm));
2886 if (err < 0)
2887 return err;
2888 }
2889 for (idx = 1; idx <= 8; idx++) {
2890 aes_sync_ctl.index = idx;
2891 err = snd_ctl_add(card,
2892 snd_ctl_new1(&aes_sync_ctl, hdspm));
2893 if (err < 0)
2894 return err;
2895 }
2896 } else {
2897 for (idx = 0; idx < ARRAY_SIZE(snd_hdspm_controls_madi);
2898 idx++) {
2899 err = snd_ctl_add(card,
2900 snd_ctl_new1(&snd_hdspm_controls_madi[idx],
2901 hdspm));
2902 if (err < 0)
2903 return err;
2255 } 2904 }
2256 } 2905 }
2257 2906
2258 /* Channel playback mixer as default control 2907 /* Channel playback mixer as default control
2259 Note: the whole matrix would be 128*HDSPM_MIXER_CHANNELS Faders, thats too big for any alsamixer 2908Note: the whole matrix would be 128*HDSPM_MIXER_CHANNELS Faders, thats too big for any alsamixer
2260 they are accesible via special IOCTL on hwdep 2909they are accesible via special IOCTL on hwdep
2261 and the mixer 2dimensional mixer control */ 2910and the mixer 2dimensional mixer control */
2262 2911
2263 snd_hdspm_playback_mixer.name = "Chn"; 2912 snd_hdspm_playback_mixer.name = "Chn";
2264 limit = HDSPM_MAX_CHANNELS; 2913 limit = HDSPM_MAX_CHANNELS;
@@ -2289,7 +2938,8 @@ static int snd_hdspm_create_controls(struct snd_card *card, struct hdspm * hdspm
2289 ------------------------------------------------------------*/ 2938 ------------------------------------------------------------*/
2290 2939
2291static void 2940static void
2292snd_hdspm_proc_read(struct snd_info_entry * entry, struct snd_info_buffer *buffer) 2941snd_hdspm_proc_read_madi(struct snd_info_entry * entry,
2942 struct snd_info_buffer *buffer)
2293{ 2943{
2294 struct hdspm *hdspm = (struct hdspm *) entry->private_data; 2944 struct hdspm *hdspm = (struct hdspm *) entry->private_data;
2295 unsigned int status; 2945 unsigned int status;
@@ -2420,11 +3070,10 @@ snd_hdspm_proc_read(struct snd_info_entry * entry, struct snd_info_buffer *buffe
2420 clock_source = "Error"; 3070 clock_source = "Error";
2421 } 3071 }
2422 snd_iprintf(buffer, "Sample Clock Source: %s\n", clock_source); 3072 snd_iprintf(buffer, "Sample Clock Source: %s\n", clock_source);
2423 if (!(hdspm->control_register & HDSPM_ClockModeMaster)) { 3073 if (!(hdspm->control_register & HDSPM_ClockModeMaster))
2424 system_clock_mode = "Slave"; 3074 system_clock_mode = "Slave";
2425 } else { 3075 else
2426 system_clock_mode = "Master"; 3076 system_clock_mode = "Master";
2427 }
2428 snd_iprintf(buffer, "System Clock Mode: %s\n", system_clock_mode); 3077 snd_iprintf(buffer, "System Clock Mode: %s\n", system_clock_mode);
2429 3078
2430 switch (hdspm_pref_sync_ref(hdspm)) { 3079 switch (hdspm_pref_sync_ref(hdspm)) {
@@ -2484,13 +3133,213 @@ snd_hdspm_proc_read(struct snd_info_entry * entry, struct snd_info_buffer *buffe
2484 snd_iprintf(buffer, "\n"); 3133 snd_iprintf(buffer, "\n");
2485} 3134}
2486 3135
3136static void
3137snd_hdspm_proc_read_aes32(struct snd_info_entry * entry,
3138 struct snd_info_buffer *buffer)
3139{
3140 struct hdspm *hdspm = (struct hdspm *) entry->private_data;
3141 unsigned int status;
3142 unsigned int status2;
3143 unsigned int timecode;
3144 int pref_syncref;
3145 char *autosync_ref;
3146 char *system_clock_mode;
3147 char *clock_source;
3148 int x;
3149
3150 status = hdspm_read(hdspm, HDSPM_statusRegister);
3151 status2 = hdspm_read(hdspm, HDSPM_statusRegister2);
3152 timecode = hdspm_read(hdspm, HDSPM_timecodeRegister);
3153
3154 snd_iprintf(buffer, "%s (Card #%d) Rev.%x\n",
3155 hdspm->card_name, hdspm->card->number + 1,
3156 hdspm->firmware_rev);
3157
3158 snd_iprintf(buffer, "IRQ: %d Registers bus: 0x%lx VM: 0x%lx\n",
3159 hdspm->irq, hdspm->port, (unsigned long)hdspm->iobase);
3160
3161 snd_iprintf(buffer, "--- System ---\n");
3162
3163 snd_iprintf(buffer,
3164 "IRQ Pending: Audio=%d, MIDI0=%d, MIDI1=%d, IRQcount=%d\n",
3165 status & HDSPM_audioIRQPending,
3166 (status & HDSPM_midi0IRQPending) ? 1 : 0,
3167 (status & HDSPM_midi1IRQPending) ? 1 : 0,
3168 hdspm->irq_count);
3169 snd_iprintf(buffer,
3170 "HW pointer: id = %d, rawptr = %d (%d->%d) estimated= %ld (bytes)\n",
3171 ((status & HDSPM_BufferID) ? 1 : 0),
3172 (status & HDSPM_BufferPositionMask),
3173 (status & HDSPM_BufferPositionMask) % (2 *
3174 (int)hdspm->
3175 period_bytes),
3176 ((status & HDSPM_BufferPositionMask) -
3177 64) % (2 * (int)hdspm->period_bytes),
3178 (long) hdspm_hw_pointer(hdspm) * 4);
3179
3180 snd_iprintf(buffer,
3181 "MIDI FIFO: Out1=0x%x, Out2=0x%x, In1=0x%x, In2=0x%x \n",
3182 hdspm_read(hdspm, HDSPM_midiStatusOut0) & 0xFF,
3183 hdspm_read(hdspm, HDSPM_midiStatusOut1) & 0xFF,
3184 hdspm_read(hdspm, HDSPM_midiStatusIn0) & 0xFF,
3185 hdspm_read(hdspm, HDSPM_midiStatusIn1) & 0xFF);
3186 snd_iprintf(buffer,
3187 "Register: ctrl1=0x%x, ctrl2=0x%x, status1=0x%x, status2=0x%x, timecode=0x%x\n",
3188 hdspm->control_register, hdspm->control2_register,
3189 status, status2, timecode);
3190
3191 snd_iprintf(buffer, "--- Settings ---\n");
3192
3193 x = 1 << (6 +
3194 hdspm_decode_latency(hdspm->
3195 control_register &
3196 HDSPM_LatencyMask));
3197
3198 snd_iprintf(buffer,
3199 "Size (Latency): %d samples (2 periods of %lu bytes)\n",
3200 x, (unsigned long) hdspm->period_bytes);
3201
3202 snd_iprintf(buffer, "Line out: %s, Precise Pointer: %s\n",
3203 (hdspm->
3204 control_register & HDSPM_LineOut) ? "on " : "off",
3205 (hdspm->precise_ptr) ? "on" : "off");
3206
3207 snd_iprintf(buffer,
3208 "ClearTrackMarker %s, Emphasis %s, Dolby %s\n",
3209 (hdspm->
3210 control_register & HDSPM_clr_tms) ? "on" : "off",
3211 (hdspm->
3212 control_register & HDSPM_Emphasis) ? "on" : "off",
3213 (hdspm->
3214 control_register & HDSPM_Dolby) ? "on" : "off");
3215
3216 switch (hdspm_clock_source(hdspm)) {
3217 case HDSPM_CLOCK_SOURCE_AUTOSYNC:
3218 clock_source = "AutoSync";
3219 break;
3220 case HDSPM_CLOCK_SOURCE_INTERNAL_32KHZ:
3221 clock_source = "Internal 32 kHz";
3222 break;
3223 case HDSPM_CLOCK_SOURCE_INTERNAL_44_1KHZ:
3224 clock_source = "Internal 44.1 kHz";
3225 break;
3226 case HDSPM_CLOCK_SOURCE_INTERNAL_48KHZ:
3227 clock_source = "Internal 48 kHz";
3228 break;
3229 case HDSPM_CLOCK_SOURCE_INTERNAL_64KHZ:
3230 clock_source = "Internal 64 kHz";
3231 break;
3232 case HDSPM_CLOCK_SOURCE_INTERNAL_88_2KHZ:
3233 clock_source = "Internal 88.2 kHz";
3234 break;
3235 case HDSPM_CLOCK_SOURCE_INTERNAL_96KHZ:
3236 clock_source = "Internal 96 kHz";
3237 break;
3238 case HDSPM_CLOCK_SOURCE_INTERNAL_128KHZ:
3239 clock_source = "Internal 128 kHz";
3240 break;
3241 case HDSPM_CLOCK_SOURCE_INTERNAL_176_4KHZ:
3242 clock_source = "Internal 176.4 kHz";
3243 break;
3244 case HDSPM_CLOCK_SOURCE_INTERNAL_192KHZ:
3245 clock_source = "Internal 192 kHz";
3246 break;
3247 default:
3248 clock_source = "Error";
3249 }
3250 snd_iprintf(buffer, "Sample Clock Source: %s\n", clock_source);
3251 if (!(hdspm->control_register & HDSPM_ClockModeMaster))
3252 system_clock_mode = "Slave";
3253 else
3254 system_clock_mode = "Master";
3255 snd_iprintf(buffer, "System Clock Mode: %s\n", system_clock_mode);
3256
3257 pref_syncref = hdspm_pref_sync_ref(hdspm);
3258 if (pref_syncref == 0)
3259 snd_iprintf(buffer, "Preferred Sync Reference: Word Clock\n");
3260 else
3261 snd_iprintf(buffer, "Preferred Sync Reference: AES%d\n",
3262 pref_syncref);
3263
3264 snd_iprintf(buffer, "System Clock Frequency: %d\n",
3265 hdspm->system_sample_rate);
3266
3267 snd_iprintf(buffer, "Double speed: %s\n",
3268 hdspm->control_register & HDSPM_DS_DoubleWire?
3269 "Double wire" : "Single wire");
3270 snd_iprintf(buffer, "Quad speed: %s\n",
3271 hdspm->control_register & HDSPM_QS_DoubleWire?
3272 "Double wire" :
3273 hdspm->control_register & HDSPM_QS_QuadWire?
3274 "Quad wire" : "Single wire");
3275
3276 snd_iprintf(buffer, "--- Status:\n");
3277
3278 snd_iprintf(buffer, "Word: %s Frequency: %d\n",
3279 (status & HDSPM_AES32_wcLock)? "Sync " : "No Lock",
3280 HDSPM_bit2freq((status >> HDSPM_AES32_wcFreq_bit) & 0xF));
3281
3282 for (x = 0; x < 8; x++) {
3283 snd_iprintf(buffer, "AES%d: %s Frequency: %d\n",
3284 x+1,
3285 (status2 & (HDSPM_LockAES >> x))? "Sync ": "No Lock",
3286 HDSPM_bit2freq((timecode >> (4*x)) & 0xF));
3287 }
3288
3289 switch (hdspm_autosync_ref(hdspm)) {
3290 case HDSPM_AES32_AUTOSYNC_FROM_NONE: autosync_ref="None"; break;
3291 case HDSPM_AES32_AUTOSYNC_FROM_WORD: autosync_ref="Word Clock"; break;
3292 case HDSPM_AES32_AUTOSYNC_FROM_AES1: autosync_ref="AES1"; break;
3293 case HDSPM_AES32_AUTOSYNC_FROM_AES2: autosync_ref="AES2"; break;
3294 case HDSPM_AES32_AUTOSYNC_FROM_AES3: autosync_ref="AES3"; break;
3295 case HDSPM_AES32_AUTOSYNC_FROM_AES4: autosync_ref="AES4"; break;
3296 case HDSPM_AES32_AUTOSYNC_FROM_AES5: autosync_ref="AES5"; break;
3297 case HDSPM_AES32_AUTOSYNC_FROM_AES6: autosync_ref="AES6"; break;
3298 case HDSPM_AES32_AUTOSYNC_FROM_AES7: autosync_ref="AES7"; break;
3299 case HDSPM_AES32_AUTOSYNC_FROM_AES8: autosync_ref="AES8"; break;
3300 default: autosync_ref = "---"; break;
3301 }
3302 snd_iprintf(buffer, "AutoSync ref = %s\n", autosync_ref);
3303
3304 snd_iprintf(buffer, "\n");
3305}
3306
3307#ifdef CONFIG_SND_DEBUG
3308static void
3309snd_hdspm_proc_read_debug(struct snd_info_entry * entry,
3310 struct snd_info_buffer *buffer)
3311{
3312 struct hdspm *hdspm = (struct hdspm *)entry->private_data;
3313
3314 int j,i;
3315
3316 for (i = 0; i < 256 /* 1024*64 */; i += j)
3317 {
3318 snd_iprintf(buffer, "0x%08X: ", i);
3319 for (j = 0; j < 16; j += 4)
3320 snd_iprintf(buffer, "%08X ", hdspm_read(hdspm, i + j));
3321 snd_iprintf(buffer, "\n");
3322 }
3323}
3324#endif
3325
3326
3327
2487static void __devinit snd_hdspm_proc_init(struct hdspm * hdspm) 3328static void __devinit snd_hdspm_proc_init(struct hdspm * hdspm)
2488{ 3329{
2489 struct snd_info_entry *entry; 3330 struct snd_info_entry *entry;
2490 3331
2491 if (!snd_card_proc_new(hdspm->card, "hdspm", &entry)) 3332 if (!snd_card_proc_new(hdspm->card, "hdspm", &entry))
2492 snd_info_set_text_ops(entry, hdspm, 3333 snd_info_set_text_ops(entry, hdspm,
2493 snd_hdspm_proc_read); 3334 hdspm->is_aes32 ?
3335 snd_hdspm_proc_read_aes32 :
3336 snd_hdspm_proc_read_madi);
3337#ifdef CONFIG_SND_DEBUG
3338 /* debug file to read all hdspm registers */
3339 if (!snd_card_proc_new(hdspm->card, "debug", &entry))
3340 snd_info_set_text_ops(entry, hdspm,
3341 snd_hdspm_proc_read_debug);
3342#endif
2494} 3343}
2495 3344
2496/*------------------------------------------------------------ 3345/*------------------------------------------------------------
@@ -2507,13 +3356,20 @@ static int snd_hdspm_set_defaults(struct hdspm * hdspm)
2507 3356
2508 /* set defaults: */ 3357 /* set defaults: */
2509 3358
2510 hdspm->control_register = HDSPM_ClockModeMaster | /* Master Cloack Mode on */ 3359 if (hdspm->is_aes32)
2511 hdspm_encode_latency(7) | /* latency maximum = 8192 samples */ 3360 hdspm->control_register = HDSPM_ClockModeMaster | /* Master Cloack Mode on */
2512 HDSPM_InputCoaxial | /* Input Coax not Optical */ 3361 hdspm_encode_latency(7) | /* latency maximum = 8192 samples */
2513 HDSPM_SyncRef_MADI | /* Madi is syncclock */ 3362 HDSPM_SyncRef0 | /* AES1 is syncclock */
2514 HDSPM_LineOut | /* Analog output in */ 3363 HDSPM_LineOut | /* Analog output in */
2515 HDSPM_TX_64ch | /* transmit in 64ch mode */ 3364 HDSPM_Professional; /* Professional mode */
2516 HDSPM_AutoInp; /* AutoInput chossing (takeover) */ 3365 else
3366 hdspm->control_register = HDSPM_ClockModeMaster | /* Master Cloack Mode on */
3367 hdspm_encode_latency(7) | /* latency maximum = 8192 samples */
3368 HDSPM_InputCoaxial | /* Input Coax not Optical */
3369 HDSPM_SyncRef_MADI | /* Madi is syncclock */
3370 HDSPM_LineOut | /* Analog output in */
3371 HDSPM_TX_64ch | /* transmit in 64ch mode */
3372 HDSPM_AutoInp; /* AutoInput chossing (takeover) */
2517 3373
2518 /* ! HDSPM_Frequency0|HDSPM_Frequency1 = 44.1khz */ 3374 /* ! HDSPM_Frequency0|HDSPM_Frequency1 = 44.1khz */
2519 /* ! HDSPM_DoubleSpeed HDSPM_QuadSpeed = normal speed */ 3375 /* ! HDSPM_DoubleSpeed HDSPM_QuadSpeed = normal speed */
@@ -2822,6 +3678,8 @@ static int snd_hdspm_hw_params(struct snd_pcm_substream *substream,
2822 3678
2823 hdspm->playback_buffer = 3679 hdspm->playback_buffer =
2824 (unsigned char *) substream->runtime->dma_area; 3680 (unsigned char *) substream->runtime->dma_area;
3681 snd_printdd("Allocated sample buffer for playback at 0x%08X\n",
3682 hdspm->playback_buffer);
2825 } else { 3683 } else {
2826 hdspm_set_sgbuf(hdspm, sgbuf, HDSPM_pageAddressBufferIn, 3684 hdspm_set_sgbuf(hdspm, sgbuf, HDSPM_pageAddressBufferIn,
2827 params_channels(params)); 3685 params_channels(params));
@@ -2831,7 +3689,15 @@ static int snd_hdspm_hw_params(struct snd_pcm_substream *substream,
2831 3689
2832 hdspm->capture_buffer = 3690 hdspm->capture_buffer =
2833 (unsigned char *) substream->runtime->dma_area; 3691 (unsigned char *) substream->runtime->dma_area;
3692 snd_printdd("Allocated sample buffer for capture at 0x%08X\n",
3693 hdspm->capture_buffer);
2834 } 3694 }
3695 /*
3696 snd_printdd("Allocated sample buffer for %s at 0x%08X\n",
3697 substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
3698 "playback" : "capture",
3699 snd_pcm_sgbuf_get_addr(sgbuf, 0));
3700 */
2835 return 0; 3701 return 0;
2836} 3702}
2837 3703
@@ -2982,9 +3848,10 @@ static struct snd_pcm_hardware snd_hdspm_playback_subinfo = {
2982 SNDRV_PCM_RATE_44100 | 3848 SNDRV_PCM_RATE_44100 |
2983 SNDRV_PCM_RATE_48000 | 3849 SNDRV_PCM_RATE_48000 |
2984 SNDRV_PCM_RATE_64000 | 3850 SNDRV_PCM_RATE_64000 |
2985 SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000), 3851 SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
3852 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000 ),
2986 .rate_min = 32000, 3853 .rate_min = 32000,
2987 .rate_max = 96000, 3854 .rate_max = 192000,
2988 .channels_min = 1, 3855 .channels_min = 1,
2989 .channels_max = HDSPM_MAX_CHANNELS, 3856 .channels_max = HDSPM_MAX_CHANNELS,
2990 .buffer_bytes_max = 3857 .buffer_bytes_max =
@@ -3006,9 +3873,10 @@ static struct snd_pcm_hardware snd_hdspm_capture_subinfo = {
3006 SNDRV_PCM_RATE_44100 | 3873 SNDRV_PCM_RATE_44100 |
3007 SNDRV_PCM_RATE_48000 | 3874 SNDRV_PCM_RATE_48000 |
3008 SNDRV_PCM_RATE_64000 | 3875 SNDRV_PCM_RATE_64000 |
3009 SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000), 3876 SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
3877 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000),
3010 .rate_min = 32000, 3878 .rate_min = 32000,
3011 .rate_max = 96000, 3879 .rate_max = 192000,
3012 .channels_min = 1, 3880 .channels_min = 1,
3013 .channels_max = HDSPM_MAX_CHANNELS, 3881 .channels_max = HDSPM_MAX_CHANNELS,
3014 .buffer_bytes_max = 3882 .buffer_bytes_max =
@@ -3315,7 +4183,8 @@ static int __devinit snd_hdspm_preallocate_memory(struct hdspm * hdspm)
3315 4183
3316 pcm = hdspm->pcm; 4184 pcm = hdspm->pcm;
3317 4185
3318 wanted = HDSPM_DMA_AREA_BYTES + 4096; /* dont know why, but it works */ 4186/* wanted = HDSPM_DMA_AREA_BYTES + 4096;*/ /* dont know why, but it works */
4187 wanted = HDSPM_DMA_AREA_BYTES;
3319 4188
3320 if ((err = 4189 if ((err =
3321 snd_pcm_lib_preallocate_pages_for_all(pcm, 4190 snd_pcm_lib_preallocate_pages_for_all(pcm,
@@ -3467,9 +4336,16 @@ static int __devinit snd_hdspm_create(struct snd_card *card, struct hdspm * hdsp
3467 pci_read_config_word(hdspm->pci, 4336 pci_read_config_word(hdspm->pci,
3468 PCI_CLASS_REVISION, &hdspm->firmware_rev); 4337 PCI_CLASS_REVISION, &hdspm->firmware_rev);
3469 4338
3470 strcpy(card->driver, "HDSPM"); 4339 hdspm->is_aes32 = (hdspm->firmware_rev >= HDSPM_AESREVISION);
4340
3471 strcpy(card->mixername, "Xilinx FPGA"); 4341 strcpy(card->mixername, "Xilinx FPGA");
3472 hdspm->card_name = "RME HDSPM MADI"; 4342 if (hdspm->is_aes32) {
4343 strcpy(card->driver, "HDSPAES32");
4344 hdspm->card_name = "RME HDSPM AES32";
4345 } else {
4346 strcpy(card->driver, "HDSPM");
4347 hdspm->card_name = "RME HDSPM MADI";
4348 }
3473 4349
3474 if ((err = pci_enable_device(pci)) < 0) 4350 if ((err = pci_enable_device(pci)) < 0)
3475 return err; 4351 return err;