44 #include <linux/module.h>
45 #include <linux/slab.h>
46 #include <linux/pci.h>
78 "Winfried Ritsch <ritsch_AT_iem.at>, "
92 #define HDSPM_WR_SETTINGS 0
93 #define HDSPM_outputBufferAddress 32
94 #define HDSPM_inputBufferAddress 36
95 #define HDSPM_controlRegister 64
96 #define HDSPM_interruptConfirmation 96
97 #define HDSPM_control2Reg 256
98 #define HDSPM_freqReg 256
99 #define HDSPM_midiDataOut0 352
100 #define HDSPM_midiDataOut1 356
101 #define HDSPM_eeprom_wr 384
104 #define HDSPM_outputEnableBase 512
105 #define HDSPM_inputEnableBase 768
109 #define HDSPM_pageAddressBufferOut 8192
110 #define HDSPM_pageAddressBufferIn (HDSPM_pageAddressBufferOut+64*16*4)
112 #define HDSPM_MADI_mixerBase 32768
114 #define HDSPM_MATRIX_MIXER_SIZE 8192
118 #define HDSPM_statusRegister 0
123 #define HDSPM_statusRegister2 192
124 #define HDSPM_timecodeRegister 128
127 #define HDSPM_RD_STATUS_0 0
128 #define HDSPM_RD_STATUS_1 64
129 #define HDSPM_RD_STATUS_2 128
130 #define HDSPM_RD_STATUS_3 192
132 #define HDSPM_RD_TCO 256
133 #define HDSPM_RD_PLL_FREQ 512
134 #define HDSPM_WR_TCO 128
136 #define HDSPM_TCO1_TCO_lock 0x00000001
137 #define HDSPM_TCO1_WCK_Input_Range_LSB 0x00000002
138 #define HDSPM_TCO1_WCK_Input_Range_MSB 0x00000004
139 #define HDSPM_TCO1_LTC_Input_valid 0x00000008
140 #define HDSPM_TCO1_WCK_Input_valid 0x00000010
141 #define HDSPM_TCO1_Video_Input_Format_NTSC 0x00000020
142 #define HDSPM_TCO1_Video_Input_Format_PAL 0x00000040
144 #define HDSPM_TCO1_set_TC 0x00000100
145 #define HDSPM_TCO1_set_drop_frame_flag 0x00000200
146 #define HDSPM_TCO1_LTC_Format_LSB 0x00000400
147 #define HDSPM_TCO1_LTC_Format_MSB 0x00000800
149 #define HDSPM_TCO2_TC_run 0x00010000
150 #define HDSPM_TCO2_WCK_IO_ratio_LSB 0x00020000
151 #define HDSPM_TCO2_WCK_IO_ratio_MSB 0x00040000
152 #define HDSPM_TCO2_set_num_drop_frames_LSB 0x00080000
153 #define HDSPM_TCO2_set_num_drop_frames_MSB 0x00100000
154 #define HDSPM_TCO2_set_jam_sync 0x00200000
155 #define HDSPM_TCO2_set_flywheel 0x00400000
157 #define HDSPM_TCO2_set_01_4 0x01000000
158 #define HDSPM_TCO2_set_pull_down 0x02000000
159 #define HDSPM_TCO2_set_pull_up 0x04000000
160 #define HDSPM_TCO2_set_freq 0x08000000
161 #define HDSPM_TCO2_set_term_75R 0x10000000
162 #define HDSPM_TCO2_set_input_LSB 0x20000000
163 #define HDSPM_TCO2_set_input_MSB 0x40000000
164 #define HDSPM_TCO2_set_freq_from_app 0x80000000
167 #define HDSPM_midiDataOut0 352
168 #define HDSPM_midiDataOut1 356
169 #define HDSPM_midiDataOut2 368
171 #define HDSPM_midiDataIn0 360
172 #define HDSPM_midiDataIn1 364
173 #define HDSPM_midiDataIn2 372
174 #define HDSPM_midiDataIn3 376
177 #define HDSPM_midiStatusOut0 384
178 #define HDSPM_midiStatusOut1 388
179 #define HDSPM_midiStatusOut2 400
181 #define HDSPM_midiStatusIn0 392
182 #define HDSPM_midiStatusIn1 396
183 #define HDSPM_midiStatusIn2 404
184 #define HDSPM_midiStatusIn3 408
193 #define HDSPM_MADI_INPUT_PEAK 4096
194 #define HDSPM_MADI_PLAYBACK_PEAK 4352
195 #define HDSPM_MADI_OUTPUT_PEAK 4608
197 #define HDSPM_MADI_INPUT_RMS_L 6144
198 #define HDSPM_MADI_PLAYBACK_RMS_L 6400
199 #define HDSPM_MADI_OUTPUT_RMS_L 6656
201 #define HDSPM_MADI_INPUT_RMS_H 7168
202 #define HDSPM_MADI_PLAYBACK_RMS_H 7424
203 #define HDSPM_MADI_OUTPUT_RMS_H 7680
206 #define HDSPM_Start (1<<0)
208 #define HDSPM_Latency0 (1<<1)
209 #define HDSPM_Latency1 (1<<2)
210 #define HDSPM_Latency2 (1<<3)
212 #define HDSPM_ClockModeMaster (1<<4)
213 #define HDSPM_c0Master 0x1
216 #define HDSPM_AudioInterruptEnable (1<<5)
218 #define HDSPM_Frequency0 (1<<6)
219 #define HDSPM_Frequency1 (1<<7)
220 #define HDSPM_DoubleSpeed (1<<8)
221 #define HDSPM_QuadSpeed (1<<31)
223 #define HDSPM_Professional (1<<9)
224 #define HDSPM_TX_64ch (1<<10)
226 #define HDSPM_Emphasis (1<<10)
228 #define HDSPM_AutoInp (1<<11)
230 #define HDSPM_Dolby (1<<11)
232 #define HDSPM_InputSelect0 (1<<14)
235 #define HDSPM_InputSelect1 (1<<15)
237 #define HDSPM_SyncRef2 (1<<13)
238 #define HDSPM_SyncRef3 (1<<25)
240 #define HDSPM_SMUX (1<<18)
241 #define HDSPM_clr_tms (1<<19)
244 #define HDSPM_taxi_reset (1<<20)
245 #define HDSPM_WCK48 (1<<20)
247 #define HDSPM_Midi0InterruptEnable 0x0400000
248 #define HDSPM_Midi1InterruptEnable 0x0800000
249 #define HDSPM_Midi2InterruptEnable 0x0200000
250 #define HDSPM_Midi3InterruptEnable 0x4000000
252 #define HDSPM_LineOut (1<<24)
253 #define HDSPe_FLOAT_FORMAT 0x2000000
255 #define HDSPM_DS_DoubleWire (1<<26)
256 #define HDSPM_QS_DoubleWire (1<<27)
257 #define HDSPM_QS_QuadWire (1<<28)
259 #define HDSPM_wclk_sel (1<<30)
262 #define HDSPM_LatencyMask (HDSPM_Latency0|HDSPM_Latency1|HDSPM_Latency2)
263 #define HDSPM_FrequencyMask (HDSPM_Frequency0|HDSPM_Frequency1|\
264 HDSPM_DoubleSpeed|HDSPM_QuadSpeed)
265 #define HDSPM_InputMask (HDSPM_InputSelect0|HDSPM_InputSelect1)
266 #define HDSPM_InputOptical 0
267 #define HDSPM_InputCoaxial (HDSPM_InputSelect0)
268 #define HDSPM_SyncRefMask (HDSPM_SyncRef0|HDSPM_SyncRef1|\
269 HDSPM_SyncRef2|HDSPM_SyncRef3)
271 #define HDSPM_c0_SyncRef0 0x2
272 #define HDSPM_c0_SyncRef1 0x4
273 #define HDSPM_c0_SyncRef2 0x8
274 #define HDSPM_c0_SyncRef3 0x10
275 #define HDSPM_c0_SyncRefMask (HDSPM_c0_SyncRef0 | HDSPM_c0_SyncRef1 |\
276 HDSPM_c0_SyncRef2 | HDSPM_c0_SyncRef3)
278 #define HDSPM_SYNC_FROM_WORD 0
279 #define HDSPM_SYNC_FROM_MADI 1
280 #define HDSPM_SYNC_FROM_TCO 2
281 #define HDSPM_SYNC_FROM_SYNC_IN 3
283 #define HDSPM_Frequency32KHz HDSPM_Frequency0
284 #define HDSPM_Frequency44_1KHz HDSPM_Frequency1
285 #define HDSPM_Frequency48KHz (HDSPM_Frequency1|HDSPM_Frequency0)
286 #define HDSPM_Frequency64KHz (HDSPM_DoubleSpeed|HDSPM_Frequency0)
287 #define HDSPM_Frequency88_2KHz (HDSPM_DoubleSpeed|HDSPM_Frequency1)
288 #define HDSPM_Frequency96KHz (HDSPM_DoubleSpeed|HDSPM_Frequency1|\
290 #define HDSPM_Frequency128KHz (HDSPM_QuadSpeed|HDSPM_Frequency0)
291 #define HDSPM_Frequency176_4KHz (HDSPM_QuadSpeed|HDSPM_Frequency1)
292 #define HDSPM_Frequency192KHz (HDSPM_QuadSpeed|HDSPM_Frequency1|\
297 #define HDSPM_SYNC_CHECK_NO_LOCK 0
298 #define HDSPM_SYNC_CHECK_LOCK 1
299 #define HDSPM_SYNC_CHECK_SYNC 2
302 #define HDSPM_AUTOSYNC_FROM_WORD 0
303 #define HDSPM_AUTOSYNC_FROM_MADI 1
304 #define HDSPM_AUTOSYNC_FROM_TCO 2
305 #define HDSPM_AUTOSYNC_FROM_SYNC_IN 3
306 #define HDSPM_AUTOSYNC_FROM_NONE 4
309 #define HDSPM_OPTICAL 0
310 #define HDSPM_COAXIAL 1
312 #define hdspm_encode_latency(x) (((x)<<1) & HDSPM_LatencyMask)
313 #define hdspm_decode_latency(x) ((((x) & HDSPM_LatencyMask)>>1))
315 #define hdspm_encode_in(x) (((x)&0x3)<<14)
316 #define hdspm_decode_in(x) (((x)>>14)&0x3)
319 #define HDSPM_TMS (1<<0)
320 #define HDSPM_TCK (1<<1)
321 #define HDSPM_TDI (1<<2)
322 #define HDSPM_JTAG (1<<3)
323 #define HDSPM_PWDN (1<<4)
324 #define HDSPM_PROGRAM (1<<5)
325 #define HDSPM_CONFIG_MODE_0 (1<<6)
326 #define HDSPM_CONFIG_MODE_1 (1<<7)
328 #define HDSPM_BIGENDIAN_MODE (1<<9)
329 #define HDSPM_RD_MULTIPLE (1<<10)
335 #define HDSPM_audioIRQPending (1<<0)
336 #define HDSPM_RX_64ch (1<<1)
337 #define HDSPM_AB_int (1<<2)
341 #define HDSPM_madiLock (1<<3)
342 #define HDSPM_madiSync (1<<18)
344 #define HDSPM_tcoLock 0x00000020
345 #define HDSPM_tcoSync 0x10000000
347 #define HDSPM_syncInLock 0x00010000
348 #define HDSPM_syncInSync 0x00020000
350 #define HDSPM_BufferPositionMask 0x000FFC0
355 #define HDSPM_DoubleSpeedStatus (1<<19)
357 #define HDSPM_madiFreq0 (1<<22)
358 #define HDSPM_madiFreq1 (1<<23)
359 #define HDSPM_madiFreq2 (1<<24)
360 #define HDSPM_madiFreq3 (1<<25)
362 #define HDSPM_BufferID (1<<26)
365 #define HDSPM_tco_detect 0x08000000
366 #define HDSPM_tco_lock 0x20000000
368 #define HDSPM_s2_tco_detect 0x00000040
369 #define HDSPM_s2_AEBO_D 0x00000080
370 #define HDSPM_s2_AEBI_D 0x00000100
373 #define HDSPM_midi0IRQPending 0x40000000
374 #define HDSPM_midi1IRQPending 0x80000000
375 #define HDSPM_midi2IRQPending 0x20000000
376 #define HDSPM_midi2IRQPendingAES 0x00000020
377 #define HDSPM_midi3IRQPending 0x00200000
380 #define HDSPM_madiFreqMask (HDSPM_madiFreq0|HDSPM_madiFreq1|\
381 HDSPM_madiFreq2|HDSPM_madiFreq3)
382 #define HDSPM_madiFreq32 (HDSPM_madiFreq0)
383 #define HDSPM_madiFreq44_1 (HDSPM_madiFreq1)
384 #define HDSPM_madiFreq48 (HDSPM_madiFreq0|HDSPM_madiFreq1)
385 #define HDSPM_madiFreq64 (HDSPM_madiFreq2)
386 #define HDSPM_madiFreq88_2 (HDSPM_madiFreq0|HDSPM_madiFreq2)
387 #define HDSPM_madiFreq96 (HDSPM_madiFreq1|HDSPM_madiFreq2)
388 #define HDSPM_madiFreq128 (HDSPM_madiFreq0|HDSPM_madiFreq1|HDSPM_madiFreq2)
389 #define HDSPM_madiFreq176_4 (HDSPM_madiFreq3)
390 #define HDSPM_madiFreq192 (HDSPM_madiFreq3|HDSPM_madiFreq0)
394 #define HDSPM_version0 (1<<0)
395 #define HDSPM_version1 (1<<1)
396 #define HDSPM_version2 (1<<2)
398 #define HDSPM_wcLock (1<<3)
399 #define HDSPM_wcSync (1<<4)
401 #define HDSPM_wc_freq0 (1<<5)
402 #define HDSPM_wc_freq1 (1<<6)
403 #define HDSPM_wc_freq2 (1<<7)
406 #define HDSPM_SyncRef0 0x10000
407 #define HDSPM_SyncRef1 0x20000
409 #define HDSPM_SelSyncRef0 (1<<8)
410 #define HDSPM_SelSyncRef1 (1<<9)
411 #define HDSPM_SelSyncRef2 (1<<10)
413 #define HDSPM_wc_valid (HDSPM_wcLock|HDSPM_wcSync)
415 #define HDSPM_wcFreqMask (HDSPM_wc_freq0|HDSPM_wc_freq1|HDSPM_wc_freq2)
416 #define HDSPM_wcFreq32 (HDSPM_wc_freq0)
417 #define HDSPM_wcFreq44_1 (HDSPM_wc_freq1)
418 #define HDSPM_wcFreq48 (HDSPM_wc_freq0|HDSPM_wc_freq1)
419 #define HDSPM_wcFreq64 (HDSPM_wc_freq2)
420 #define HDSPM_wcFreq88_2 (HDSPM_wc_freq0|HDSPM_wc_freq2)
421 #define HDSPM_wcFreq96 (HDSPM_wc_freq1|HDSPM_wc_freq2)
423 #define HDSPM_status1_F_0 0x0400000
424 #define HDSPM_status1_F_1 0x0800000
425 #define HDSPM_status1_F_2 0x1000000
426 #define HDSPM_status1_F_3 0x2000000
427 #define HDSPM_status1_freqMask (HDSPM_status1_F_0|HDSPM_status1_F_1|HDSPM_status1_F_2|HDSPM_status1_F_3)
430 #define HDSPM_SelSyncRefMask (HDSPM_SelSyncRef0|HDSPM_SelSyncRef1|\
432 #define HDSPM_SelSyncRef_WORD 0
433 #define HDSPM_SelSyncRef_MADI (HDSPM_SelSyncRef0)
434 #define HDSPM_SelSyncRef_TCO (HDSPM_SelSyncRef1)
435 #define HDSPM_SelSyncRef_SyncIn (HDSPM_SelSyncRef0|HDSPM_SelSyncRef1)
436 #define HDSPM_SelSyncRef_NVALID (HDSPM_SelSyncRef0|HDSPM_SelSyncRef1|\
443 #define HDSPM_AES32_wcLock 0x0200000
444 #define HDSPM_AES32_wcFreq_bit 22
447 #define HDSPM_AES32_syncref_bit 16
450 #define HDSPM_AES32_AUTOSYNC_FROM_WORD 0
451 #define HDSPM_AES32_AUTOSYNC_FROM_AES1 1
452 #define HDSPM_AES32_AUTOSYNC_FROM_AES2 2
453 #define HDSPM_AES32_AUTOSYNC_FROM_AES3 3
454 #define HDSPM_AES32_AUTOSYNC_FROM_AES4 4
455 #define HDSPM_AES32_AUTOSYNC_FROM_AES5 5
456 #define HDSPM_AES32_AUTOSYNC_FROM_AES6 6
457 #define HDSPM_AES32_AUTOSYNC_FROM_AES7 7
458 #define HDSPM_AES32_AUTOSYNC_FROM_AES8 8
459 #define HDSPM_AES32_AUTOSYNC_FROM_NONE 9
463 #define HDSPM_LockAES 0x80
464 #define HDSPM_LockAES1 0x80
465 #define HDSPM_LockAES2 0x40
466 #define HDSPM_LockAES3 0x20
467 #define HDSPM_LockAES4 0x10
468 #define HDSPM_LockAES5 0x8
469 #define HDSPM_LockAES6 0x4
470 #define HDSPM_LockAES7 0x2
471 #define HDSPM_LockAES8 0x1
490 #define UNITY_GAIN 32768
491 #define MINUS_INFINITY_GAIN 0
494 #define MADI_SS_CHANNELS 64
495 #define MADI_DS_CHANNELS 32
496 #define MADI_QS_CHANNELS 16
498 #define RAYDAT_SS_CHANNELS 36
499 #define RAYDAT_DS_CHANNELS 20
500 #define RAYDAT_QS_CHANNELS 12
502 #define AIO_IN_SS_CHANNELS 14
503 #define AIO_IN_DS_CHANNELS 10
504 #define AIO_IN_QS_CHANNELS 8
505 #define AIO_OUT_SS_CHANNELS 16
506 #define AIO_OUT_DS_CHANNELS 12
507 #define AIO_OUT_QS_CHANNELS 10
509 #define AES32_CHANNELS 16
512 #define HDSPM_CHANNEL_BUFFER_SAMPLES (16*1024)
513 #define HDSPM_CHANNEL_BUFFER_BYTES (4*HDSPM_CHANNEL_BUFFER_SAMPLES)
520 #define HDSPM_DMA_AREA_BYTES (HDSPM_MAX_CHANNELS * HDSPM_CHANNEL_BUFFER_BYTES)
521 #define HDSPM_DMA_AREA_KILOBYTES (HDSPM_DMA_AREA_BYTES/1024)
523 #define HDSPM_RAYDAT_REV 211
524 #define HDSPM_AIO_REV 212
525 #define HDSPM_MADIFACE_REV 213
528 #define HDSPM_SPEED_SINGLE 0
529 #define HDSPM_SPEED_DOUBLE 1
530 #define HDSPM_SPEED_QUAD 2
533 static char *hdspm_speed_names[] = {
"single",
"double",
"quad" };
535 static char *texts_autosync_aes_tco[] = {
"Word Clock",
536 "AES1",
"AES2",
"AES3",
"AES4",
537 "AES5",
"AES6",
"AES7",
"AES8",
539 static char *texts_autosync_aes[] = {
"Word Clock",
540 "AES1",
"AES2",
"AES3",
"AES4",
541 "AES5",
"AES6",
"AES7",
"AES8" };
542 static char *texts_autosync_madi_tco[] = {
"Word Clock",
543 "MADI",
"TCO",
"Sync In" };
544 static char *texts_autosync_madi[] = {
"Word Clock",
547 static char *texts_autosync_raydat_tco[] = {
549 "ADAT 1",
"ADAT 2",
"ADAT 3",
"ADAT 4",
550 "AES",
"SPDIF",
"TCO",
"Sync In"
552 static char *texts_autosync_raydat[] = {
554 "ADAT 1",
"ADAT 2",
"ADAT 3",
"ADAT 4",
555 "AES",
"SPDIF",
"Sync In"
557 static char *texts_autosync_aio_tco[] = {
559 "ADAT",
"AES",
"SPDIF",
"TCO",
"Sync In"
561 static char *texts_autosync_aio[] = {
"Word Clock",
562 "ADAT",
"AES",
"SPDIF",
"Sync In" };
564 static char *texts_freq[] = {
577 static char *texts_ports_madi[] = {
578 "MADI.1",
"MADI.2",
"MADI.3",
"MADI.4",
"MADI.5",
"MADI.6",
579 "MADI.7",
"MADI.8",
"MADI.9",
"MADI.10",
"MADI.11",
"MADI.12",
580 "MADI.13",
"MADI.14",
"MADI.15",
"MADI.16",
"MADI.17",
"MADI.18",
581 "MADI.19",
"MADI.20",
"MADI.21",
"MADI.22",
"MADI.23",
"MADI.24",
582 "MADI.25",
"MADI.26",
"MADI.27",
"MADI.28",
"MADI.29",
"MADI.30",
583 "MADI.31",
"MADI.32",
"MADI.33",
"MADI.34",
"MADI.35",
"MADI.36",
584 "MADI.37",
"MADI.38",
"MADI.39",
"MADI.40",
"MADI.41",
"MADI.42",
585 "MADI.43",
"MADI.44",
"MADI.45",
"MADI.46",
"MADI.47",
"MADI.48",
586 "MADI.49",
"MADI.50",
"MADI.51",
"MADI.52",
"MADI.53",
"MADI.54",
587 "MADI.55",
"MADI.56",
"MADI.57",
"MADI.58",
"MADI.59",
"MADI.60",
588 "MADI.61",
"MADI.62",
"MADI.63",
"MADI.64",
592 static char *texts_ports_raydat_ss[] = {
593 "ADAT1.1",
"ADAT1.2",
"ADAT1.3",
"ADAT1.4",
"ADAT1.5",
"ADAT1.6",
594 "ADAT1.7",
"ADAT1.8",
"ADAT2.1",
"ADAT2.2",
"ADAT2.3",
"ADAT2.4",
595 "ADAT2.5",
"ADAT2.6",
"ADAT2.7",
"ADAT2.8",
"ADAT3.1",
"ADAT3.2",
596 "ADAT3.3",
"ADAT3.4",
"ADAT3.5",
"ADAT3.6",
"ADAT3.7",
"ADAT3.8",
597 "ADAT4.1",
"ADAT4.2",
"ADAT4.3",
"ADAT4.4",
"ADAT4.5",
"ADAT4.6",
598 "ADAT4.7",
"ADAT4.8",
603 static char *texts_ports_raydat_ds[] = {
604 "ADAT1.1",
"ADAT1.2",
"ADAT1.3",
"ADAT1.4",
605 "ADAT2.1",
"ADAT2.2",
"ADAT2.3",
"ADAT2.4",
606 "ADAT3.1",
"ADAT3.2",
"ADAT3.3",
"ADAT3.4",
607 "ADAT4.1",
"ADAT4.2",
"ADAT4.3",
"ADAT4.4",
612 static char *texts_ports_raydat_qs[] = {
613 "ADAT1.1",
"ADAT1.2",
614 "ADAT2.1",
"ADAT2.2",
615 "ADAT3.1",
"ADAT3.2",
616 "ADAT4.1",
"ADAT4.2",
622 static char *texts_ports_aio_in_ss[] = {
623 "Analogue.L",
"Analogue.R",
625 "SPDIF.L",
"SPDIF.R",
626 "ADAT.1",
"ADAT.2",
"ADAT.3",
"ADAT.4",
"ADAT.5",
"ADAT.6",
630 static char *texts_ports_aio_out_ss[] = {
631 "Analogue.L",
"Analogue.R",
633 "SPDIF.L",
"SPDIF.R",
634 "ADAT.1",
"ADAT.2",
"ADAT.3",
"ADAT.4",
"ADAT.5",
"ADAT.6",
639 static char *texts_ports_aio_in_ds[] = {
640 "Analogue.L",
"Analogue.R",
642 "SPDIF.L",
"SPDIF.R",
643 "ADAT.1",
"ADAT.2",
"ADAT.3",
"ADAT.4"
646 static char *texts_ports_aio_out_ds[] = {
647 "Analogue.L",
"Analogue.R",
649 "SPDIF.L",
"SPDIF.R",
650 "ADAT.1",
"ADAT.2",
"ADAT.3",
"ADAT.4",
654 static char *texts_ports_aio_in_qs[] = {
655 "Analogue.L",
"Analogue.R",
657 "SPDIF.L",
"SPDIF.R",
658 "ADAT.1",
"ADAT.2",
"ADAT.3",
"ADAT.4"
661 static char *texts_ports_aio_out_qs[] = {
662 "Analogue.L",
"Analogue.R",
664 "SPDIF.L",
"SPDIF.R",
665 "ADAT.1",
"ADAT.2",
"ADAT.3",
"ADAT.4",
669 static char *texts_ports_aes32[] = {
670 "AES.1",
"AES.2",
"AES.3",
"AES.4",
"AES.5",
"AES.6",
"AES.7",
671 "AES.8",
"AES.9.",
"AES.10",
"AES.11",
"AES.12",
"AES.13",
"AES.14",
684 0, 1, 2, 3, 4, 5, 6, 7,
685 8, 9, 10, 11, 12, 13, 14, 15,
686 16, 17, 18, 19, 20, 21, 22, 23,
687 24, 25, 26, 27, 28, 29, 30, 31,
688 32, 33, 34, 35, 36, 37, 38, 39,
689 40, 41, 42, 43, 44, 45, 46, 47,
690 48, 49, 50, 51, 52, 53, 54, 55,
691 56, 57, 58, 59, 60, 61, 62, 63
695 4, 5, 6, 7, 8, 9, 10, 11,
696 12, 13, 14, 15, 16, 17, 18, 19,
697 20, 21, 22, 23, 24, 25, 26, 27,
698 28, 29, 30, 31, 32, 33, 34, 35,
702 -1, -1, -1, -1, -1, -1, -1, -1,
703 -1, -1, -1, -1, -1, -1, -1, -1,
704 -1, -1, -1, -1, -1, -1, -1, -1,
715 -1, -1, -1, -1, -1, -1, -1, -1,
716 -1, -1, -1, -1, -1, -1, -1, -1,
717 -1, -1, -1, -1, -1, -1, -1, -1,
718 -1, -1, -1, -1, -1, -1, -1, -1,
719 -1, -1, -1, -1, -1, -1, -1, -1,
730 -1, -1, -1, -1, -1, -1, -1, -1,
731 -1, -1, -1, -1, -1, -1, -1, -1,
732 -1, -1, -1, -1, -1, -1, -1, -1,
733 -1, -1, -1, -1, -1, -1, -1, -1,
734 -1, -1, -1, -1, -1, -1, -1, -1,
735 -1, -1, -1, -1, -1, -1, -1, -1,
742 12, 13, 14, 15, 16, 17, 18, 19,
744 -1, -1, -1, -1, -1, -1, -1, -1,
745 -1, -1, -1, -1, -1, -1, -1, -1,
746 -1, -1, -1, -1, -1, -1, -1, -1,
747 -1, -1, -1, -1, -1, -1, -1, -1,
748 -1, -1, -1, -1, -1, -1, -1, -1,
749 -1, -1, -1, -1, -1, -1, -1, -1,
756 12, 13, 14, 15, 16, 17, 18, 19,
758 -1, -1, -1, -1, -1, -1, -1, -1,
759 -1, -1, -1, -1, -1, -1, -1, -1,
760 -1, -1, -1, -1, -1, -1, -1, -1,
761 -1, -1, -1, -1, -1, -1, -1, -1,
762 -1, -1, -1, -1, -1, -1, -1, -1,
763 -1, -1, -1, -1, -1, -1, -1, -1,
771 -1, -1, -1, -1, -1, -1,
772 -1, -1, -1, -1, -1, -1, -1, -1,
773 -1, -1, -1, -1, -1, -1, -1, -1,
774 -1, -1, -1, -1, -1, -1, -1, -1,
775 -1, -1, -1, -1, -1, -1, -1, -1,
776 -1, -1, -1, -1, -1, -1, -1, -1,
777 -1, -1, -1, -1, -1, -1, -1, -1
787 -1, -1, -1, -1, -1, -1, -1, -1,
788 -1, -1, -1, -1, -1, -1, -1, -1,
789 -1, -1, -1, -1, -1, -1, -1, -1,
790 -1, -1, -1, -1, -1, -1, -1, -1,
791 -1, -1, -1, -1, -1, -1, -1, -1,
792 -1, -1, -1, -1, -1, -1, -1, -1
800 -1, -1, -1, -1, -1, -1, -1, -1,
801 -1, -1, -1, -1, -1, -1, -1, -1,
802 -1, -1, -1, -1, -1, -1, -1, -1,
803 -1, -1, -1, -1, -1, -1, -1, -1,
804 -1, -1, -1, -1, -1, -1, -1, -1,
805 -1, -1, -1, -1, -1, -1, -1, -1,
806 -1, -1, -1, -1, -1, -1, -1, -1
815 -1, -1, -1, -1, -1, -1,
816 -1, -1, -1, -1, -1, -1, -1, -1,
817 -1, -1, -1, -1, -1, -1, -1, -1,
818 -1, -1, -1, -1, -1, -1, -1, -1,
819 -1, -1, -1, -1, -1, -1, -1, -1,
820 -1, -1, -1, -1, -1, -1, -1, -1,
821 -1, -1, -1, -1, -1, -1, -1, -1
825 0, 1, 2, 3, 4, 5, 6, 7,
826 8, 9, 10, 11, 12, 13, 14, 15,
827 -1, -1, -1, -1, -1, -1, -1, -1,
828 -1, -1, -1, -1, -1, -1, -1, -1,
829 -1, -1, -1, -1, -1, -1, -1, -1,
830 -1, -1, -1, -1, -1, -1, -1, -1,
831 -1, -1, -1, -1, -1, -1, -1, -1,
832 -1, -1, -1, -1, -1, -1, -1, -1
970 static inline void snd_hdspm_initialize_midi_flush(
struct hdspm *
hdspm);
971 static int hdspm_update_simple_mixer_controls(
struct hdspm *
hdspm);
972 static int hdspm_autosync_ref(
struct hdspm *
hdspm);
973 static int snd_hdspm_set_defaults(
struct hdspm *
hdspm);
974 static int hdspm_system_clock_mode(
struct hdspm *
hdspm);
975 static void hdspm_set_sgbuf(
struct hdspm *
hdspm,
979 static inline int HDSPM_bit2freq(
int n)
981 static const int bit2freq_tab[] = {
982 0, 32000, 44100, 48000, 64000, 88200,
983 96000, 128000, 176400, 192000 };
986 return bit2freq_tab[
n];
992 static inline void hdspm_write(
struct hdspm *
hdspm,
unsigned int reg,
998 static inline unsigned int hdspm_read(
struct hdspm *
hdspm,
unsigned int reg)
1007 static inline int hdspm_read_in_gain(
struct hdspm *
hdspm,
unsigned int chan,
1013 return hdspm->
mixer->ch[chan].in[
in];
1016 static inline int hdspm_read_pb_gain(
struct hdspm * hdspm,
unsigned int chan,
1021 return hdspm->
mixer->ch[chan].pb[pb];
1024 static int hdspm_write_in_gain(
struct hdspm *hdspm,
unsigned int chan,
1025 unsigned int in,
unsigned short data)
1032 ((in + 128 * chan) *
sizeof(
u32)),
1033 (hdspm->
mixer->ch[chan].in[in] = data & 0xFFFF));
1037 static int hdspm_write_pb_gain(
struct hdspm *hdspm,
unsigned int chan,
1038 unsigned int pb,
unsigned short data)
1045 ((64 + pb + 128 * chan) *
sizeof(
u32)),
1046 (hdspm->
mixer->ch[chan].pb[pb] = data & 0xFFFF));
1052 static inline void snd_hdspm_enable_in(
struct hdspm * hdspm,
int i,
int v)
1057 static inline void snd_hdspm_enable_out(
struct hdspm * hdspm,
int i,
int v)
1063 static int snd_hdspm_use_is_exclusive(
struct hdspm *hdspm)
1065 unsigned long flags;
1073 spin_unlock_irqrestore(&hdspm->
lock, flags);
1078 static int hdspm_external_sample_rate(
struct hdspm *hdspm)
1081 int syncref,
rate = 0, rate_bits;
1089 syncref = hdspm_autosync_ref(hdspm);
1111 rate = 32000;
break;
1113 rate = 44100;
break;
1115 rate = 48000;
break;
1117 rate = 64000;
break;
1119 rate = 88200;
break;
1121 rate = 96000;
break;
1123 rate = 128000;
break;
1125 rate = 176400;
break;
1127 rate = 192000;
break;
1149 switch (rate_bits) {
1182 if (status & HDSPM_madiLock) {
1185 switch (rate_bits) {
1226 if (rate <= 48000) {
1241 static int hdspm_get_latency(
struct hdspm *hdspm)
1257 return 1 << (n + 6);
1261 static inline void hdspm_compute_period_size(
struct hdspm *hdspm)
1288 static inline void hdspm_start_audio(
struct hdspm *
s)
1294 static inline void hdspm_stop_audio(
struct hdspm *
s)
1301 static void hdspm_silence_playback(
struct hdspm *hdspm)
1316 static int hdspm_set_interrupt_interval(
struct hdspm *
s,
unsigned int frames)
1320 spin_lock_irq(&s->
lock);
1348 hdspm_compute_period_size(s);
1350 spin_unlock_irq(&s->
lock);
1355 static u64 hdspm_calc_dds_value(
struct hdspm *hdspm,
u64 period)
1365 freq_const = 110069313433624ULL;
1369 freq_const = 104857600000000ULL;
1372 freq_const = 131072000000000ULL;
1379 return div_u64(freq_const, period);
1383 static void hdspm_set_dds_value(
struct hdspm *hdspm,
int rate)
1389 else if (rate >= 56000)
1394 n = 131072000000000ULL;
1398 n = 110069313433624ULL;
1402 n = 104857600000000ULL;
1409 n = div_u64(n, rate);
1416 static int hdspm_set_rate(
struct hdspm * hdspm,
int rate,
int called_internally)
1421 int current_speed, target_speed;
1430 if (called_internally) {
1437 "Warning: device is not running "
1438 "as a clock master.\n");
1444 hdspm_external_sample_rate(hdspm);
1446 if (hdspm_autosync_ref(hdspm) ==
1450 "Detected no Externel Sync \n");
1453 }
else if (rate != external_freq) {
1456 "Warning: No AutoSync source for "
1457 "requested rate\n");
1475 if (current_rate <= 48000)
1477 else if (current_rate <= 96000)
1484 else if (rate <= 96000)
1521 if (current_speed != target_speed
1525 "cannot change from %s speed to %s speed mode "
1526 "(capture PID = %d, playback PID = %d)\n",
1527 hdspm_speed_names[current_speed],
1528 hdspm_speed_names[target_speed],
1539 hdspm_set_dds_value(hdspm, rate);
1546 if (rate <= 48000) {
1553 }
else if (rate <= 96000) {
1576 static void all_in_all_mixer(
struct hdspm * hdspm,
int sgain)
1590 hdspm_write_in_gain(hdspm, i, j, gain);
1591 hdspm_write_pb_gain(hdspm, i, j, gain);
1599 static inline unsigned char snd_hdspm_midi_read_byte (
struct hdspm *hdspm,
1603 return hdspm_read(hdspm, hdspm->
midi[
id].dataIn);
1606 static inline void snd_hdspm_midi_write_byte (
struct hdspm *hdspm,
int id,
1610 return hdspm_write(hdspm, hdspm->
midi[
id].dataOut, val);
1613 static inline int snd_hdspm_midi_input_available (
struct hdspm *hdspm,
int id)
1615 return hdspm_read(hdspm, hdspm->
midi[
id].statusIn) & 0xFF;
1618 static inline int snd_hdspm_midi_output_possible (
struct hdspm *hdspm,
int id)
1620 int fifo_bytes_used;
1622 fifo_bytes_used = hdspm_read(hdspm, hdspm->
midi[
id].statusOut) & 0xFF;
1624 if (fifo_bytes_used < 128)
1625 return 128 - fifo_bytes_used;
1630 static void snd_hdspm_flush_midi_input(
struct hdspm *hdspm,
int id)
1632 while (snd_hdspm_midi_input_available (hdspm,
id))
1633 snd_hdspm_midi_read_byte (hdspm,
id);
1636 static int snd_hdspm_midi_output_write (
struct hdspm_midi *hmidi)
1638 unsigned long flags;
1642 unsigned char buf[128];
1649 n_pending = snd_hdspm_midi_output_possible (hmidi->
hdspm,
1651 if (n_pending > 0) {
1652 if (n_pending > (
int)
sizeof (buf))
1653 n_pending =
sizeof (
buf);
1658 for (i = 0; i < to_write; ++
i)
1659 snd_hdspm_midi_write_byte (hmidi->
hdspm,
1665 spin_unlock_irqrestore (&hmidi->
lock, flags);
1669 static int snd_hdspm_midi_input_read (
struct hdspm_midi *hmidi)
1671 unsigned char buf[128];
1674 unsigned long flags;
1679 n_pending = snd_hdspm_midi_input_available (hmidi->
hdspm, hmidi->
id);
1680 if (n_pending > 0) {
1682 if (n_pending > (
int)
sizeof (buf))
1683 n_pending =
sizeof (
buf);
1684 for (i = 0; i < n_pending; ++
i)
1685 buf[i] = snd_hdspm_midi_read_byte (hmidi->
hdspm,
1693 snd_hdspm_midi_read_byte (hmidi->
hdspm,
1698 spin_unlock_irqrestore(&hmidi->
lock, flags);
1701 hmidi->
hdspm->control_register |= hmidi->
ie;
1703 hmidi->
hdspm->control_register);
1704 spin_unlock_irqrestore(&hmidi->
hdspm->lock, flags);
1706 return snd_hdspm_midi_output_write (hmidi);
1712 struct hdspm *hdspm;
1714 unsigned long flags;
1716 hmidi = substream->
rmidi->private_data;
1717 hdspm = hmidi->
hdspm;
1722 snd_hdspm_flush_midi_input (hdspm, hmidi->
id);
1730 spin_unlock_irqrestore (&hdspm->
lock, flags);
1733 static void snd_hdspm_midi_output_timer(
unsigned long data)
1736 unsigned long flags;
1738 snd_hdspm_midi_output_write(hmidi);
1752 spin_unlock_irqrestore (&hmidi->
lock, flags);
1759 unsigned long flags;
1761 hmidi = substream->
rmidi->private_data;
1766 hmidi->
timer.function = snd_hdspm_midi_output_timer;
1767 hmidi->
timer.data = (
unsigned long) hmidi;
1776 spin_unlock_irqrestore (&hmidi->
lock, flags);
1778 snd_hdspm_midi_output_write(hmidi);
1785 hmidi = substream->
rmidi->private_data;
1786 spin_lock_irq (&hmidi->
lock);
1787 snd_hdspm_flush_midi_input (hmidi->
hdspm, hmidi->
id);
1788 hmidi->
input = substream;
1789 spin_unlock_irq (&hmidi->
lock);
1798 hmidi = substream->
rmidi->private_data;
1799 spin_lock_irq (&hmidi->
lock);
1800 hmidi->
output = substream;
1801 spin_unlock_irq (&hmidi->
lock);
1810 snd_hdspm_midi_input_trigger (substream, 0);
1812 hmidi = substream->
rmidi->private_data;
1813 spin_lock_irq (&hmidi->
lock);
1815 spin_unlock_irq (&hmidi->
lock);
1824 snd_hdspm_midi_output_trigger (substream, 0);
1826 hmidi = substream->
rmidi->private_data;
1827 spin_lock_irq (&hmidi->
lock);
1829 spin_unlock_irq (&hmidi->
lock);
1836 .open = snd_hdspm_midi_output_open,
1837 .close = snd_hdspm_midi_output_close,
1838 .trigger = snd_hdspm_midi_output_trigger,
1843 .open = snd_hdspm_midi_input_open,
1844 .close = snd_hdspm_midi_input_close,
1845 .trigger = snd_hdspm_midi_input_trigger,
1849 struct hdspm *hdspm,
int id)
1855 hdspm->
midi[
id].hdspm = hdspm;
1875 }
else if (1 ==
id) {
1882 }
else if ((2 ==
id) && (
MADI == hdspm->
io_type)) {
1890 }
else if (2 ==
id) {
1894 hdspm->
midi[2].dataOut = -1;
1895 hdspm->
midi[2].statusOut = -1;
1898 }
else if (3 ==
id) {
1902 hdspm->
midi[3].dataOut = -1;
1903 hdspm->
midi[3].statusOut = -1;
1908 if ((
id < 2) || ((2 ==
id) && ((
MADI == hdspm->
io_type) ||
1912 }
else if ((
id == 2) && (
MADI == hdspm->
io_type)) {
1918 &hdspm->
midi[
id].rmidi);
1922 sprintf(hdspm->
midi[
id].rmidi->name,
"%s MIDI %d",
1924 hdspm->
midi[
id].rmidi->private_data = &hdspm->
midi[
id];
1928 &snd_hdspm_midi_output);
1931 &snd_hdspm_midi_input);
1933 hdspm->
midi[
id].rmidi->info_flags |=
1941 &hdspm->
midi[
id].rmidi);
1946 "%s MTC %d", card->
id,
id+1);
1947 hdspm->
midi[
id].rmidi->private_data = &hdspm->
midi[
id];
1951 &snd_hdspm_midi_input);
1960 static void hdspm_midi_tasklet(
unsigned long arg)
1962 struct hdspm *hdspm = (
struct hdspm *)arg;
1966 if (hdspm->
midi[i].pending)
1967 snd_hdspm_midi_input_read(&hdspm->
midi[i]);
1985 static int hdspm_get_system_sample_rate(
struct hdspm *hdspm)
1990 rate = hdspm_calc_dds_value(hdspm, period);
1992 if (rate > 207000) {
1994 if (0 == hdspm_system_clock_mode(hdspm)) {
1999 rate = hdspm_external_sample_rate(hdspm);
2007 #define HDSPM_SYSTEM_SAMPLE_RATE(xname, xindex) \
2008 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2011 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\
2012 SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
2013 .info = snd_hdspm_info_system_sample_rate, \
2014 .put = snd_hdspm_put_system_sample_rate, \
2015 .get = snd_hdspm_get_system_sample_rate \
2018 static int snd_hdspm_info_system_sample_rate(
struct snd_kcontrol *kcontrol,
2030 static int snd_hdspm_get_system_sample_rate(
struct snd_kcontrol *kcontrol,
2036 ucontrol->
value.integer.value[0] = hdspm_get_system_sample_rate(hdspm);
2040 static int snd_hdspm_put_system_sample_rate(
struct snd_kcontrol *kcontrol,
2046 hdspm_set_dds_value(hdspm, ucontrol->
value.enumerated.item[0]);
2054 static int hdspm_get_wc_sample_rate(
struct hdspm *hdspm)
2062 return (status >> 16) & 0xF;
2076 static int hdspm_get_tco_sample_rate(
struct hdspm *hdspm)
2085 return (status >> 20) & 0xF;
2099 static int hdspm_get_sync_in_sample_rate(
struct hdspm *hdspm)
2108 return (status >> 12) & 0xF;
2123 static int hdspm_get_s1_sample_rate(
struct hdspm *hdspm,
unsigned int idx)
2127 return (status >> (idx*4)) & 0xF;
2132 #define HDSPM_AUTOSYNC_SAMPLE_RATE(xname, xindex) \
2133 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2135 .private_value = xindex, \
2136 .access = SNDRV_CTL_ELEM_ACCESS_READ, \
2137 .info = snd_hdspm_info_autosync_sample_rate, \
2138 .get = snd_hdspm_get_autosync_sample_rate \
2142 static int snd_hdspm_info_autosync_sample_rate(
struct snd_kcontrol *kcontrol,
2157 static int snd_hdspm_get_autosync_sample_rate(
struct snd_kcontrol *kcontrol,
2167 ucontrol->
value.enumerated.item[0] =
2168 hdspm_get_wc_sample_rate(hdspm);
2171 ucontrol->
value.enumerated.item[0] =
2172 hdspm_get_tco_sample_rate(hdspm);
2175 ucontrol->
value.enumerated.item[0] =
2176 hdspm_get_sync_in_sample_rate(hdspm);
2179 ucontrol->
value.enumerated.item[0] =
2180 hdspm_get_s1_sample_rate(hdspm,
2188 ucontrol->
value.enumerated.item[0] =
2189 hdspm_get_wc_sample_rate(hdspm);
2192 ucontrol->
value.enumerated.item[0] =
2193 hdspm_get_tco_sample_rate(hdspm);
2196 ucontrol->
value.enumerated.item[0] =
2197 hdspm_get_sync_in_sample_rate(hdspm);
2200 ucontrol->
value.enumerated.item[0] =
2201 hdspm_get_s1_sample_rate(hdspm,
2202 ucontrol->
id.index-1);
2210 ucontrol->
value.enumerated.item[0] =
2211 hdspm_get_wc_sample_rate(hdspm);
2214 ucontrol->
value.enumerated.item[0] =
2215 hdspm_get_tco_sample_rate(hdspm);
2218 ucontrol->
value.enumerated.item[0] =
2219 hdspm_get_sync_in_sample_rate(hdspm);
2222 ucontrol->
value.enumerated.item[0] =
2223 hdspm_get_s1_sample_rate(hdspm,
2232 int rate = hdspm_external_sample_rate(hdspm);
2233 int i, selected_rate = 0;
2234 for (i = 1; i < 10; i++)
2235 if (HDSPM_bit2freq(i) == rate) {
2239 ucontrol->
value.enumerated.item[0] = selected_rate;
2251 #define HDSPM_SYSTEM_CLOCK_MODE(xname, xindex) \
2252 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2255 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\
2256 SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
2257 .info = snd_hdspm_info_system_clock_mode, \
2258 .get = snd_hdspm_get_system_clock_mode, \
2259 .put = snd_hdspm_put_system_clock_mode, \
2267 static int hdspm_system_clock_mode(
struct hdspm *hdspm)
2289 static void hdspm_set_system_clock_mode(
struct hdspm *hdspm,
int mode)
2314 static int snd_hdspm_info_system_clock_mode(
struct snd_kcontrol *kcontrol,
2317 static char *texts[] = {
"Master",
"AutoSync" };
2330 static int snd_hdspm_get_system_clock_mode(
struct snd_kcontrol *kcontrol,
2335 ucontrol->
value.enumerated.item[0] = hdspm_system_clock_mode(hdspm);
2339 static int snd_hdspm_put_system_clock_mode(
struct snd_kcontrol *kcontrol,
2345 if (!snd_hdspm_use_is_exclusive(hdspm))
2348 val = ucontrol->
value.enumerated.item[0];
2354 hdspm_set_system_clock_mode(hdspm, val);
2360 #define HDSPM_INTERNAL_CLOCK(xname, xindex) \
2361 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2364 .info = snd_hdspm_info_clock_source, \
2365 .get = snd_hdspm_get_clock_source, \
2366 .put = snd_hdspm_put_clock_source \
2370 static int hdspm_clock_source(
struct hdspm * hdspm)
2373 case 32000:
return 0;
2374 case 44100:
return 1;
2375 case 48000:
return 2;
2376 case 64000:
return 3;
2377 case 88200:
return 4;
2378 case 96000:
return 5;
2379 case 128000:
return 6;
2380 case 176400:
return 7;
2381 case 192000:
return 8;
2387 static int hdspm_set_clock_source(
struct hdspm * hdspm,
int mode)
2392 rate = 32000;
break;
2394 rate = 44100;
break;
2396 rate = 48000;
break;
2398 rate = 64000;
break;
2400 rate = 88200;
break;
2402 rate = 96000;
break;
2404 rate = 128000;
break;
2406 rate = 176400;
break;
2408 rate = 192000;
break;
2412 hdspm_set_rate(hdspm, rate, 1);
2416 static int snd_hdspm_info_clock_source(
struct snd_kcontrol *kcontrol,
2433 static int snd_hdspm_get_clock_source(
struct snd_kcontrol *kcontrol,
2438 ucontrol->
value.enumerated.item[0] = hdspm_clock_source(hdspm);
2442 static int snd_hdspm_put_clock_source(
struct snd_kcontrol *kcontrol,
2449 if (!snd_hdspm_use_is_exclusive(hdspm))
2451 val = ucontrol->
value.enumerated.item[0];
2456 spin_lock_irq(&hdspm->
lock);
2457 if (val != hdspm_clock_source(hdspm))
2458 change = (hdspm_set_clock_source(hdspm, val) == 0) ? 1 : 0;
2461 spin_unlock_irq(&hdspm->
lock);
2466 #define HDSPM_PREF_SYNC_REF(xname, xindex) \
2467 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2470 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\
2471 SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
2472 .info = snd_hdspm_info_pref_sync_ref, \
2473 .get = snd_hdspm_get_pref_sync_ref, \
2474 .put = snd_hdspm_put_pref_sync_ref \
2483 static int hdspm_pref_sync_ref(
struct hdspm * hdspm)
2586 static int hdspm_set_pref_sync_ref(
struct hdspm * hdspm,
int pref)
2675 case 0: p = 0;
break;
2676 case 1: p = 3;
break;
2677 case 2: p = 4;
break;
2678 case 3: p = 5;
break;
2679 case 4: p = 6;
break;
2680 case 5: p = 1;
break;
2681 case 6: p = 2;
break;
2682 case 7: p = 9;
break;
2683 case 8: p = 10;
break;
2688 case 0: p = 0;
break;
2689 case 1: p = 3;
break;
2690 case 2: p = 4;
break;
2691 case 3: p = 5;
break;
2692 case 4: p = 6;
break;
2693 case 5: p = 1;
break;
2694 case 6: p = 2;
break;
2695 case 7: p = 10;
break;
2704 case 0: p = 0;
break;
2705 case 1: p = 3;
break;
2706 case 2: p = 1;
break;
2707 case 3: p = 2;
break;
2708 case 4: p = 9;
break;
2709 case 5: p = 10;
break;
2714 case 0: p = 0;
break;
2715 case 1: p = 3;
break;
2716 case 2: p = 1;
break;
2717 case 3: p = 2;
break;
2718 case 4: p = 10;
break;
2744 static int snd_hdspm_info_pref_sync_ref(
struct snd_kcontrol *kcontrol,
2763 static int snd_hdspm_get_pref_sync_ref(
struct snd_kcontrol *kcontrol,
2767 int psf = hdspm_pref_sync_ref(hdspm);
2770 ucontrol->
value.enumerated.item[0] = psf;
2777 static int snd_hdspm_put_pref_sync_ref(
struct snd_kcontrol *kcontrol,
2781 int val, change = 0;
2783 if (!snd_hdspm_use_is_exclusive(hdspm))
2786 val = ucontrol->
value.enumerated.item[0];
2793 spin_lock_irq(&hdspm->
lock);
2794 if (val != hdspm_pref_sync_ref(hdspm))
2795 change = (0 == hdspm_set_pref_sync_ref(hdspm, val)) ? 1 : 0;
2797 spin_unlock_irq(&hdspm->
lock);
2802 #define HDSPM_AUTOSYNC_REF(xname, xindex) \
2803 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2806 .access = SNDRV_CTL_ELEM_ACCESS_READ, \
2807 .info = snd_hdspm_info_autosync_ref, \
2808 .get = snd_hdspm_get_autosync_ref, \
2811 static int hdspm_autosync_ref(
struct hdspm *hdspm)
2815 unsigned int syncref =
2826 switch (status2 & HDSPM_SelSyncRefMask) {
2846 static int snd_hdspm_info_autosync_ref(
struct snd_kcontrol *kcontrol,
2852 static char *texts[] = {
"WordClock",
"AES1",
"AES2",
"AES3",
2853 "AES4",
"AES5",
"AES6",
"AES7",
"AES8",
"None"};
2865 static char *texts[] = {
"Word Clock",
"MADI",
"TCO",
2866 "Sync In",
"None" };
2881 static int snd_hdspm_get_autosync_ref(
struct snd_kcontrol *kcontrol,
2886 ucontrol->
value.enumerated.item[0] = hdspm_autosync_ref(hdspm);
2891 #define HDSPM_LINE_OUT(xname, xindex) \
2892 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2895 .info = snd_hdspm_info_line_out, \
2896 .get = snd_hdspm_get_line_out, \
2897 .put = snd_hdspm_put_line_out \
2900 static int hdspm_line_out(
struct hdspm * hdspm)
2906 static int hdspm_set_line_output(
struct hdspm * hdspm,
int out)
2917 #define snd_hdspm_info_line_out snd_ctl_boolean_mono_info
2919 static int snd_hdspm_get_line_out(
struct snd_kcontrol *kcontrol,
2924 spin_lock_irq(&hdspm->
lock);
2925 ucontrol->
value.integer.value[0] = hdspm_line_out(hdspm);
2926 spin_unlock_irq(&hdspm->
lock);
2930 static int snd_hdspm_put_line_out(
struct snd_kcontrol *kcontrol,
2937 if (!snd_hdspm_use_is_exclusive(hdspm))
2939 val = ucontrol->
value.integer.value[0] & 1;
2940 spin_lock_irq(&hdspm->
lock);
2941 change = (
int) val != hdspm_line_out(hdspm);
2942 hdspm_set_line_output(hdspm, val);
2943 spin_unlock_irq(&hdspm->
lock);
2948 #define HDSPM_TX_64(xname, xindex) \
2949 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2952 .info = snd_hdspm_info_tx_64, \
2953 .get = snd_hdspm_get_tx_64, \
2954 .put = snd_hdspm_put_tx_64 \
2957 static int hdspm_tx_64(
struct hdspm * hdspm)
2962 static int hdspm_set_tx_64(
struct hdspm * hdspm,
int out)
2973 #define snd_hdspm_info_tx_64 snd_ctl_boolean_mono_info
2975 static int snd_hdspm_get_tx_64(
struct snd_kcontrol *kcontrol,
2980 spin_lock_irq(&hdspm->
lock);
2981 ucontrol->
value.integer.value[0] = hdspm_tx_64(hdspm);
2982 spin_unlock_irq(&hdspm->
lock);
2986 static int snd_hdspm_put_tx_64(
struct snd_kcontrol *kcontrol,
2993 if (!snd_hdspm_use_is_exclusive(hdspm))
2995 val = ucontrol->
value.integer.value[0] & 1;
2996 spin_lock_irq(&hdspm->
lock);
2997 change = (
int) val != hdspm_tx_64(hdspm);
2998 hdspm_set_tx_64(hdspm, val);
2999 spin_unlock_irq(&hdspm->
lock);
3004 #define HDSPM_C_TMS(xname, xindex) \
3005 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3008 .info = snd_hdspm_info_c_tms, \
3009 .get = snd_hdspm_get_c_tms, \
3010 .put = snd_hdspm_put_c_tms \
3013 static int hdspm_c_tms(
struct hdspm * hdspm)
3018 static int hdspm_set_c_tms(
struct hdspm * hdspm,
int out)
3029 #define snd_hdspm_info_c_tms snd_ctl_boolean_mono_info
3031 static int snd_hdspm_get_c_tms(
struct snd_kcontrol *kcontrol,
3036 spin_lock_irq(&hdspm->
lock);
3037 ucontrol->
value.integer.value[0] = hdspm_c_tms(hdspm);
3038 spin_unlock_irq(&hdspm->
lock);
3042 static int snd_hdspm_put_c_tms(
struct snd_kcontrol *kcontrol,
3049 if (!snd_hdspm_use_is_exclusive(hdspm))
3051 val = ucontrol->
value.integer.value[0] & 1;
3052 spin_lock_irq(&hdspm->
lock);
3053 change = (
int) val != hdspm_c_tms(hdspm);
3054 hdspm_set_c_tms(hdspm, val);
3055 spin_unlock_irq(&hdspm->
lock);
3060 #define HDSPM_SAFE_MODE(xname, xindex) \
3061 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3064 .info = snd_hdspm_info_safe_mode, \
3065 .get = snd_hdspm_get_safe_mode, \
3066 .put = snd_hdspm_put_safe_mode \
3069 static int hdspm_safe_mode(
struct hdspm * hdspm)
3074 static int hdspm_set_safe_mode(
struct hdspm * hdspm,
int out)
3085 #define snd_hdspm_info_safe_mode snd_ctl_boolean_mono_info
3087 static int snd_hdspm_get_safe_mode(
struct snd_kcontrol *kcontrol,
3092 spin_lock_irq(&hdspm->
lock);
3093 ucontrol->
value.integer.value[0] = hdspm_safe_mode(hdspm);
3094 spin_unlock_irq(&hdspm->
lock);
3098 static int snd_hdspm_put_safe_mode(
struct snd_kcontrol *kcontrol,
3105 if (!snd_hdspm_use_is_exclusive(hdspm))
3107 val = ucontrol->
value.integer.value[0] & 1;
3108 spin_lock_irq(&hdspm->
lock);
3109 change = (
int) val != hdspm_safe_mode(hdspm);
3110 hdspm_set_safe_mode(hdspm, val);
3111 spin_unlock_irq(&hdspm->
lock);
3116 #define HDSPM_EMPHASIS(xname, xindex) \
3117 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3120 .info = snd_hdspm_info_emphasis, \
3121 .get = snd_hdspm_get_emphasis, \
3122 .put = snd_hdspm_put_emphasis \
3125 static int hdspm_emphasis(
struct hdspm * hdspm)
3130 static int hdspm_set_emphasis(
struct hdspm * hdspm,
int emp)
3141 #define snd_hdspm_info_emphasis snd_ctl_boolean_mono_info
3143 static int snd_hdspm_get_emphasis(
struct snd_kcontrol *kcontrol,
3148 spin_lock_irq(&hdspm->
lock);
3149 ucontrol->
value.enumerated.item[0] = hdspm_emphasis(hdspm);
3150 spin_unlock_irq(&hdspm->
lock);
3154 static int snd_hdspm_put_emphasis(
struct snd_kcontrol *kcontrol,
3161 if (!snd_hdspm_use_is_exclusive(hdspm))
3163 val = ucontrol->
value.integer.value[0] & 1;
3164 spin_lock_irq(&hdspm->
lock);
3165 change = (
int) val != hdspm_emphasis(hdspm);
3166 hdspm_set_emphasis(hdspm, val);
3167 spin_unlock_irq(&hdspm->
lock);
3172 #define HDSPM_DOLBY(xname, xindex) \
3173 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3176 .info = snd_hdspm_info_dolby, \
3177 .get = snd_hdspm_get_dolby, \
3178 .put = snd_hdspm_put_dolby \
3181 static int hdspm_dolby(
struct hdspm * hdspm)
3186 static int hdspm_set_dolby(
struct hdspm * hdspm,
int dol)
3197 #define snd_hdspm_info_dolby snd_ctl_boolean_mono_info
3199 static int snd_hdspm_get_dolby(
struct snd_kcontrol *kcontrol,
3204 spin_lock_irq(&hdspm->
lock);
3205 ucontrol->
value.enumerated.item[0] = hdspm_dolby(hdspm);
3206 spin_unlock_irq(&hdspm->
lock);
3210 static int snd_hdspm_put_dolby(
struct snd_kcontrol *kcontrol,
3217 if (!snd_hdspm_use_is_exclusive(hdspm))
3219 val = ucontrol->
value.integer.value[0] & 1;
3220 spin_lock_irq(&hdspm->
lock);
3221 change = (
int) val != hdspm_dolby(hdspm);
3222 hdspm_set_dolby(hdspm, val);
3223 spin_unlock_irq(&hdspm->
lock);
3228 #define HDSPM_PROFESSIONAL(xname, xindex) \
3229 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3232 .info = snd_hdspm_info_professional, \
3233 .get = snd_hdspm_get_professional, \
3234 .put = snd_hdspm_put_professional \
3237 static int hdspm_professional(
struct hdspm * hdspm)
3242 static int hdspm_set_professional(
struct hdspm * hdspm,
int dol)
3253 #define snd_hdspm_info_professional snd_ctl_boolean_mono_info
3255 static int snd_hdspm_get_professional(
struct snd_kcontrol *kcontrol,
3260 spin_lock_irq(&hdspm->
lock);
3261 ucontrol->
value.enumerated.item[0] = hdspm_professional(hdspm);
3262 spin_unlock_irq(&hdspm->
lock);
3266 static int snd_hdspm_put_professional(
struct snd_kcontrol *kcontrol,
3273 if (!snd_hdspm_use_is_exclusive(hdspm))
3275 val = ucontrol->
value.integer.value[0] & 1;
3276 spin_lock_irq(&hdspm->
lock);
3277 change = (
int) val != hdspm_professional(hdspm);
3278 hdspm_set_professional(hdspm, val);
3279 spin_unlock_irq(&hdspm->
lock);
3283 #define HDSPM_INPUT_SELECT(xname, xindex) \
3284 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3287 .info = snd_hdspm_info_input_select, \
3288 .get = snd_hdspm_get_input_select, \
3289 .put = snd_hdspm_put_input_select \
3292 static int hdspm_input_select(
struct hdspm * hdspm)
3297 static int hdspm_set_input_select(
struct hdspm * hdspm,
int out)
3308 static int snd_hdspm_info_input_select(
struct snd_kcontrol *kcontrol,
3311 static char *texts[] = {
"optical",
"coaxial" };
3326 static int snd_hdspm_get_input_select(
struct snd_kcontrol *kcontrol,
3331 spin_lock_irq(&hdspm->
lock);
3332 ucontrol->
value.enumerated.item[0] = hdspm_input_select(hdspm);
3333 spin_unlock_irq(&hdspm->
lock);
3337 static int snd_hdspm_put_input_select(
struct snd_kcontrol *kcontrol,
3344 if (!snd_hdspm_use_is_exclusive(hdspm))
3346 val = ucontrol->
value.integer.value[0] & 1;
3347 spin_lock_irq(&hdspm->
lock);
3348 change = (
int) val != hdspm_input_select(hdspm);
3349 hdspm_set_input_select(hdspm, val);
3350 spin_unlock_irq(&hdspm->
lock);
3355 #define HDSPM_DS_WIRE(xname, xindex) \
3356 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3359 .info = snd_hdspm_info_ds_wire, \
3360 .get = snd_hdspm_get_ds_wire, \
3361 .put = snd_hdspm_put_ds_wire \
3364 static int hdspm_ds_wire(
struct hdspm * hdspm)
3369 static int hdspm_set_ds_wire(
struct hdspm * hdspm,
int ds)
3380 static int snd_hdspm_info_ds_wire(
struct snd_kcontrol *kcontrol,
3383 static char *texts[] = {
"Single",
"Double" };
3398 static int snd_hdspm_get_ds_wire(
struct snd_kcontrol *kcontrol,
3403 spin_lock_irq(&hdspm->
lock);
3404 ucontrol->
value.enumerated.item[0] = hdspm_ds_wire(hdspm);
3405 spin_unlock_irq(&hdspm->
lock);
3409 static int snd_hdspm_put_ds_wire(
struct snd_kcontrol *kcontrol,
3416 if (!snd_hdspm_use_is_exclusive(hdspm))
3418 val = ucontrol->
value.integer.value[0] & 1;
3419 spin_lock_irq(&hdspm->
lock);
3420 change = (
int) val != hdspm_ds_wire(hdspm);
3421 hdspm_set_ds_wire(hdspm, val);
3422 spin_unlock_irq(&hdspm->
lock);
3427 #define HDSPM_QS_WIRE(xname, xindex) \
3428 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3431 .info = snd_hdspm_info_qs_wire, \
3432 .get = snd_hdspm_get_qs_wire, \
3433 .put = snd_hdspm_put_qs_wire \
3436 static int hdspm_qs_wire(
struct hdspm * hdspm)
3445 static int hdspm_set_qs_wire(
struct hdspm * hdspm,
int mode)
3463 static int snd_hdspm_info_qs_wire(
struct snd_kcontrol *kcontrol,
3466 static char *texts[] = {
"Single",
"Double",
"Quad" };
3481 static int snd_hdspm_get_qs_wire(
struct snd_kcontrol *kcontrol,
3486 spin_lock_irq(&hdspm->
lock);
3487 ucontrol->
value.enumerated.item[0] = hdspm_qs_wire(hdspm);
3488 spin_unlock_irq(&hdspm->
lock);
3492 static int snd_hdspm_put_qs_wire(
struct snd_kcontrol *kcontrol,
3499 if (!snd_hdspm_use_is_exclusive(hdspm))
3501 val = ucontrol->
value.integer.value[0];
3506 spin_lock_irq(&hdspm->
lock);
3507 change = val != hdspm_qs_wire(hdspm);
3508 hdspm_set_qs_wire(hdspm, val);
3509 spin_unlock_irq(&hdspm->
lock);
3513 #define HDSPM_MADI_SPEEDMODE(xname, xindex) \
3514 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3517 .info = snd_hdspm_info_madi_speedmode, \
3518 .get = snd_hdspm_get_madi_speedmode, \
3519 .put = snd_hdspm_put_madi_speedmode \
3522 static int hdspm_madi_speedmode(
struct hdspm *hdspm)
3531 static int hdspm_set_madi_speedmode(
struct hdspm *hdspm,
int mode)
3549 static int snd_hdspm_info_madi_speedmode(
struct snd_kcontrol *kcontrol,
3552 static char *texts[] = {
"Single",
"Double",
"Quad" };
3567 static int snd_hdspm_get_madi_speedmode(
struct snd_kcontrol *kcontrol,
3572 spin_lock_irq(&hdspm->
lock);
3573 ucontrol->
value.enumerated.item[0] = hdspm_madi_speedmode(hdspm);
3574 spin_unlock_irq(&hdspm->
lock);
3578 static int snd_hdspm_put_madi_speedmode(
struct snd_kcontrol *kcontrol,
3585 if (!snd_hdspm_use_is_exclusive(hdspm))
3587 val = ucontrol->
value.integer.value[0];
3592 spin_lock_irq(&hdspm->
lock);
3593 change = val != hdspm_madi_speedmode(hdspm);
3594 hdspm_set_madi_speedmode(hdspm, val);
3595 spin_unlock_irq(&hdspm->
lock);
3599 #define HDSPM_MIXER(xname, xindex) \
3600 { .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \
3604 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
3605 SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
3606 .info = snd_hdspm_info_mixer, \
3607 .get = snd_hdspm_get_mixer, \
3608 .put = snd_hdspm_put_mixer \
3611 static int snd_hdspm_info_mixer(
struct snd_kcontrol *kcontrol,
3622 static int snd_hdspm_get_mixer(
struct snd_kcontrol *kcontrol,
3629 source = ucontrol->
value.integer.value[0];
3635 destination = ucontrol->
value.integer.value[1];
3636 if (destination < 0)
3641 spin_lock_irq(&hdspm->
lock);
3643 ucontrol->
value.integer.value[2] =
3644 hdspm_read_pb_gain(hdspm, destination,
3647 ucontrol->
value.integer.value[2] =
3648 hdspm_read_in_gain(hdspm, destination, source);
3650 spin_unlock_irq(&hdspm->
lock);
3655 static int snd_hdspm_put_mixer(
struct snd_kcontrol *kcontrol,
3664 if (!snd_hdspm_use_is_exclusive(hdspm))
3667 source = ucontrol->
value.integer.value[0];
3668 destination = ucontrol->
value.integer.value[1];
3675 gain = ucontrol->
value.integer.value[2];
3677 spin_lock_irq(&hdspm->
lock);
3680 change = gain != hdspm_read_pb_gain(hdspm, destination,
3684 change = gain != hdspm_read_in_gain(hdspm, destination,
3689 hdspm_write_pb_gain(hdspm, destination,
3693 hdspm_write_in_gain(hdspm, destination, source,
3696 spin_unlock_irq(&hdspm->
lock);
3706 #define HDSPM_PLAYBACK_MIXER \
3707 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3708 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_WRITE | \
3709 SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
3710 .info = snd_hdspm_info_playback_mixer, \
3711 .get = snd_hdspm_get_playback_mixer, \
3712 .put = snd_hdspm_put_playback_mixer \
3715 static int snd_hdspm_info_playback_mixer(
struct snd_kcontrol *kcontrol,
3726 static int snd_hdspm_get_playback_mixer(
struct snd_kcontrol *kcontrol,
3732 channel = ucontrol->
id.index - 1;
3737 spin_lock_irq(&hdspm->
lock);
3738 ucontrol->
value.integer.value[0] =
3739 (hdspm_read_pb_gain(hdspm, channel, channel)*64)/
UNITY_GAIN;
3740 spin_unlock_irq(&hdspm->
lock);
3745 static int snd_hdspm_put_playback_mixer(
struct snd_kcontrol *kcontrol,
3753 if (!snd_hdspm_use_is_exclusive(hdspm))
3756 channel = ucontrol->
id.index - 1;
3765 gain != hdspm_read_pb_gain(hdspm, channel,
3768 hdspm_write_pb_gain(hdspm, channel, channel,
3770 spin_unlock_irq(&hdspm->
lock);
3774 #define HDSPM_SYNC_CHECK(xname, xindex) \
3775 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3777 .private_value = xindex, \
3778 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
3779 .info = snd_hdspm_info_sync_check, \
3780 .get = snd_hdspm_get_sync_check \
3784 static int snd_hdspm_info_sync_check(
struct snd_kcontrol *kcontrol,
3787 static char *texts[] = {
"No Lock",
"Lock",
"Sync",
"N/A" };
3799 static int hdspm_wc_sync_check(
struct hdspm *hdspm)
3808 else if (status & HDSPM_wcLock)
3815 if (status2 & HDSPM_wcLock) {
3816 if (status2 & HDSPM_wcSync)
3828 if (status & 0x2000000)
3830 else if (status & 0x1000000)
3845 static int hdspm_madi_sync_check(
struct hdspm *hdspm)
3848 if (status & HDSPM_madiLock) {
3858 static int hdspm_s1_sync_check(
struct hdspm *hdspm,
int idx)
3864 lock = (status & (0x1<<
idx)) ? 1 : 0;
3865 sync = (status & (0x100<<
idx)) ? 1 : 0;
3875 static int hdspm_sync_in_sync_check(
struct hdspm *hdspm)
3877 int status, lock = 0, sync = 0;
3883 lock = (status & 0x400) ? 1 : 0;
3884 sync = (status & 0x800) ? 1 : 0;
3895 lock = (status & 0x100000) ? 1 : 0;
3896 sync = (status & 0x200000) ? 1 : 0;
3911 static int hdspm_aes_sync_check(
struct hdspm *hdspm,
int idx)
3916 lock = (status2 & (0x0080 >>
idx)) ? 1 : 0;
3917 sync = (status2 & (0x8000 >>
idx)) ? 1 : 0;
3927 static int hdspm_tco_sync_check(
struct hdspm *hdspm)
3950 if (status & 0x8000000)
3952 if (status & 0x4000000)
3966 static int snd_hdspm_get_sync_check(
struct snd_kcontrol *kcontrol,
3976 val = hdspm_wc_sync_check(hdspm);
break;
3978 val = hdspm_tco_sync_check(hdspm);
break;
3980 val = hdspm_sync_in_sync_check(hdspm);
break;
3982 val = hdspm_s1_sync_check(hdspm,
3990 val = hdspm_wc_sync_check(hdspm);
break;
3992 val = hdspm_tco_sync_check(hdspm);
break;
3994 val = hdspm_sync_in_sync_check(hdspm);
break;
3996 val = hdspm_s1_sync_check(hdspm, ucontrol->
id.index-1);
4003 val = hdspm_wc_sync_check(hdspm);
break;
4005 val = hdspm_madi_sync_check(hdspm);
break;
4007 val = hdspm_tco_sync_check(hdspm);
break;
4009 val = hdspm_sync_in_sync_check(hdspm);
break;
4014 val = hdspm_madi_sync_check(hdspm);
4020 val = hdspm_wc_sync_check(hdspm);
break;
4022 val = hdspm_tco_sync_check(hdspm);
break;
4024 val = hdspm_sync_in_sync_check(hdspm);
break;
4026 val = hdspm_aes_sync_check(hdspm,
4036 ucontrol->
value.enumerated.item[0] =
val;
4045 static void hdspm_tco_write(
struct hdspm *hdspm)
4047 unsigned int tc[4] = { 0, 0, 0, 0};
4049 switch (hdspm->
tco->input) {
4060 switch (hdspm->
tco->framerate) {
4077 HDSPM_TCO1_LTC_Format_MSB +
4084 switch (hdspm->
tco->wordclock) {
4095 switch (hdspm->
tco->samplerate) {
4106 switch (hdspm->
tco->pull) {
4134 #define HDSPM_TCO_SAMPLE_RATE(xname, xindex) \
4135 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4138 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\
4139 SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
4140 .info = snd_hdspm_info_tco_sample_rate, \
4141 .get = snd_hdspm_get_tco_sample_rate, \
4142 .put = snd_hdspm_put_tco_sample_rate \
4145 static int snd_hdspm_info_tco_sample_rate(
struct snd_kcontrol *kcontrol,
4148 static char *texts[] = {
"44.1 kHz",
"48 kHz" };
4163 static int snd_hdspm_get_tco_sample_rate(
struct snd_kcontrol *kcontrol,
4168 ucontrol->
value.enumerated.item[0] = hdspm->
tco->samplerate;
4173 static int snd_hdspm_put_tco_sample_rate(
struct snd_kcontrol *kcontrol,
4178 if (hdspm->
tco->samplerate != ucontrol->
value.enumerated.item[0]) {
4179 hdspm->
tco->samplerate = ucontrol->
value.enumerated.item[0];
4181 hdspm_tco_write(hdspm);
4190 #define HDSPM_TCO_PULL(xname, xindex) \
4191 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4194 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\
4195 SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
4196 .info = snd_hdspm_info_tco_pull, \
4197 .get = snd_hdspm_get_tco_pull, \
4198 .put = snd_hdspm_put_tco_pull \
4201 static int snd_hdspm_info_tco_pull(
struct snd_kcontrol *kcontrol,
4204 static char *texts[] = {
"0",
"+ 0.1 %",
"- 0.1 %",
"+ 4 %",
"- 4 %" };
4219 static int snd_hdspm_get_tco_pull(
struct snd_kcontrol *kcontrol,
4224 ucontrol->
value.enumerated.item[0] = hdspm->
tco->pull;
4229 static int snd_hdspm_put_tco_pull(
struct snd_kcontrol *kcontrol,
4234 if (hdspm->
tco->pull != ucontrol->
value.enumerated.item[0]) {
4235 hdspm->
tco->pull = ucontrol->
value.enumerated.item[0];
4237 hdspm_tco_write(hdspm);
4245 #define HDSPM_TCO_WCK_CONVERSION(xname, xindex) \
4246 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4249 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\
4250 SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
4251 .info = snd_hdspm_info_tco_wck_conversion, \
4252 .get = snd_hdspm_get_tco_wck_conversion, \
4253 .put = snd_hdspm_put_tco_wck_conversion \
4256 static int snd_hdspm_info_tco_wck_conversion(
struct snd_kcontrol *kcontrol,
4259 static char *texts[] = {
"1:1",
"44.1 -> 48",
"48 -> 44.1" };
4274 static int snd_hdspm_get_tco_wck_conversion(
struct snd_kcontrol *kcontrol,
4279 ucontrol->
value.enumerated.item[0] = hdspm->
tco->wordclock;
4284 static int snd_hdspm_put_tco_wck_conversion(
struct snd_kcontrol *kcontrol,
4289 if (hdspm->
tco->wordclock != ucontrol->
value.enumerated.item[0]) {
4290 hdspm->
tco->wordclock = ucontrol->
value.enumerated.item[0];
4292 hdspm_tco_write(hdspm);
4301 #define HDSPM_TCO_FRAME_RATE(xname, xindex) \
4302 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4305 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\
4306 SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
4307 .info = snd_hdspm_info_tco_frame_rate, \
4308 .get = snd_hdspm_get_tco_frame_rate, \
4309 .put = snd_hdspm_put_tco_frame_rate \
4312 static int snd_hdspm_info_tco_frame_rate(
struct snd_kcontrol *kcontrol,
4315 static char *texts[] = {
"24 fps",
"25 fps",
"29.97fps",
4316 "29.97 dfps",
"30 fps",
"30 dfps" };
4331 static int snd_hdspm_get_tco_frame_rate(
struct snd_kcontrol *kcontrol,
4336 ucontrol->
value.enumerated.item[0] = hdspm->
tco->framerate;
4341 static int snd_hdspm_put_tco_frame_rate(
struct snd_kcontrol *kcontrol,
4346 if (hdspm->
tco->framerate != ucontrol->
value.enumerated.item[0]) {
4347 hdspm->
tco->framerate = ucontrol->
value.enumerated.item[0];
4349 hdspm_tco_write(hdspm);
4358 #define HDSPM_TCO_SYNC_SOURCE(xname, xindex) \
4359 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4362 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\
4363 SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
4364 .info = snd_hdspm_info_tco_sync_source, \
4365 .get = snd_hdspm_get_tco_sync_source, \
4366 .put = snd_hdspm_put_tco_sync_source \
4369 static int snd_hdspm_info_tco_sync_source(
struct snd_kcontrol *kcontrol,
4372 static char *texts[] = {
"LTC",
"Video",
"WCK" };
4387 static int snd_hdspm_get_tco_sync_source(
struct snd_kcontrol *kcontrol,
4392 ucontrol->
value.enumerated.item[0] = hdspm->
tco->input;
4397 static int snd_hdspm_put_tco_sync_source(
struct snd_kcontrol *kcontrol,
4402 if (hdspm->
tco->input != ucontrol->
value.enumerated.item[0]) {
4403 hdspm->
tco->input = ucontrol->
value.enumerated.item[0];
4405 hdspm_tco_write(hdspm);
4414 #define HDSPM_TCO_WORD_TERM(xname, xindex) \
4415 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4418 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\
4419 SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
4420 .info = snd_hdspm_info_tco_word_term, \
4421 .get = snd_hdspm_get_tco_word_term, \
4422 .put = snd_hdspm_put_tco_word_term \
4425 static int snd_hdspm_info_tco_word_term(
struct snd_kcontrol *kcontrol,
4437 static int snd_hdspm_get_tco_word_term(
struct snd_kcontrol *kcontrol,
4442 ucontrol->
value.enumerated.item[0] = hdspm->
tco->term;
4448 static int snd_hdspm_put_tco_word_term(
struct snd_kcontrol *kcontrol,
4453 if (hdspm->
tco->term != ucontrol->
value.enumerated.item[0]) {
4454 hdspm->
tco->term = ucontrol->
value.enumerated.item[0];
4456 hdspm_tco_write(hdspm);
4615 static int hdspm_update_simple_mixer_controls(
struct hdspm * hdspm)
4639 static int snd_hdspm_create_controls(
struct snd_card *card,
4640 struct hdspm *hdspm)
4649 list = snd_hdspm_controls_madi;
4653 list = snd_hdspm_controls_madiface;
4654 limit =
ARRAY_SIZE(snd_hdspm_controls_madiface);
4657 list = snd_hdspm_controls_aio;
4661 list = snd_hdspm_controls_raydat;
4662 limit =
ARRAY_SIZE(snd_hdspm_controls_raydat);
4665 list = snd_hdspm_controls_aes32;
4666 limit =
ARRAY_SIZE(snd_hdspm_controls_aes32);
4671 for (idx = 0; idx <
limit; idx++) {
4681 snd_hdspm_playback_mixer.
name =
"Chn";
4689 for (idx = 0; idx <
limit; ++
idx) {
4690 snd_hdspm_playback_mixer.
index = idx + 1;
4701 list = snd_hdspm_controls_tco;
4703 for (idx = 0; idx <
limit; idx++) {
4725 char *pref_sync_ref;
4727 char *system_clock_mode;
4742 snd_iprintf(buffer,
"%s (Card #%d) Rev.%x Status2first3bits: %x\n",
4749 snd_iprintf(buffer,
"HW Serial: 0x%06x%06x\n",
4753 snd_iprintf(buffer,
"IRQ: %d Registers bus: 0x%lx VM: 0x%lx\n",
4756 snd_iprintf(buffer,
"--- System ---\n");
4759 "IRQ Pending: Audio=%d, MIDI0=%d, MIDI1=%d, IRQcount=%d\n",
4765 "HW pointer: id = %d, rawptr = %d (%d->%d) "
4766 "estimated= %ld (bytes)\n",
4769 (status & HDSPM_BufferPositionMask) %
4771 ((status & HDSPM_BufferPositionMask) - 64) %
4773 (
long) hdspm_hw_pointer(hdspm) * 4);
4776 "MIDI FIFO: Out1=0x%x, Out2=0x%x, In1=0x%x, In2=0x%x \n",
4782 "MIDIoverMADI FIFO: In=0x%x, Out=0x%x \n",
4786 "Register: ctrl1=0x%x, ctrl2=0x%x, status1=0x%x, "
4791 snd_iprintf(buffer,
"TCO module detected.\n");
4794 snd_iprintf(buffer,
" LTC valid, ");
4798 snd_iprintf(buffer,
"24 fps, ");
4801 snd_iprintf(buffer,
"25 fps, ");
4804 snd_iprintf(buffer,
"29.97 fps, ");
4807 snd_iprintf(buffer,
"30 fps, ");
4811 snd_iprintf(buffer,
"drop frame\n");
4813 snd_iprintf(buffer,
"full frame\n");
4816 snd_iprintf(buffer,
" no LTC\n");
4819 snd_iprintf(buffer,
" Video: NTSC\n");
4821 snd_iprintf(buffer,
" Video: PAL\n");
4823 snd_iprintf(buffer,
" No video\n");
4826 snd_iprintf(buffer,
" Sync: lock\n");
4828 snd_iprintf(buffer,
" Sync: no lock\n");
4834 freq_const = 110069313433624ULL;
4838 freq_const = 104857600000000ULL;
4845 snd_iprintf(buffer,
" period: %u\n", period);
4849 rate = div_u64(freq_const, period);
4857 snd_iprintf(buffer,
" Frequency: %u Hz\n",
4858 (
unsigned int) rate);
4863 frames += (ltc & 0x3) * 10;
4865 seconds = ltc & 0xF;
4867 seconds += (ltc & 0x7) * 10;
4869 minutes = ltc & 0xF;
4871 minutes += (ltc & 0x7) * 10;
4875 hours += (ltc & 0x3) * 10;
4877 " LTC In: %02d:%02d:%02d:%02d\n",
4878 hours, minutes, seconds, frames);
4881 snd_iprintf(buffer,
"No TCO module detected.\n");
4884 snd_iprintf(buffer,
"--- Settings ---\n");
4886 x = hdspm_get_latency(hdspm);
4889 "Size (Latency): %d samples (2 periods of %lu bytes)\n",
4892 snd_iprintf(buffer,
"Line out: %s\n",
4907 "ClearTrackMarker = %s, Transmit in %s Channel Mode, "
4915 system_clock_mode =
"AutoSync";
4917 system_clock_mode =
"Master";
4918 snd_iprintf(buffer,
"AutoSync Reference: %s\n", system_clock_mode);
4920 switch (hdspm_pref_sync_ref(hdspm)) {
4922 pref_sync_ref =
"Word Clock";
4925 pref_sync_ref =
"MADI Sync";
4928 pref_sync_ref =
"TCO";
4931 pref_sync_ref =
"Sync In";
4934 pref_sync_ref =
"XXXX Clock";
4937 snd_iprintf(buffer,
"Preferred Sync Reference: %s\n",
4940 snd_iprintf(buffer,
"System Clock Frequency: %d\n",
4944 snd_iprintf(buffer,
"--- Status:\n");
4949 snd_iprintf(buffer,
"Inputs MADI=%s, WordClock=%s\n",
4950 (status & HDSPM_madiLock) ? (x ?
"Sync" :
"Lock") :
4952 (status2 & HDSPM_wcLock) ? (x2 ?
"Sync" :
"Lock") :
4955 switch (hdspm_autosync_ref(hdspm)) {
4957 autosync_ref =
"Sync In";
4960 autosync_ref =
"TCO";
4963 autosync_ref =
"Word Clock";
4966 autosync_ref =
"MADI Sync";
4969 autosync_ref =
"Input not valid";
4972 autosync_ref =
"---";
4976 "AutoSync: Reference= %s, Freq=%d (MADI = %d, Word = %d)\n",
4977 autosync_ref, hdspm_external_sample_rate(hdspm),
4978 (status & HDSPM_madiFreqMask) >> 22,
4979 (status2 & HDSPM_wcFreqMask) >> 5);
4981 snd_iprintf(buffer,
"Input: %s, Mode=%s\n",
4986 snd_iprintf(buffer,
"\n");
4996 unsigned int timecode;
5005 snd_iprintf(buffer,
"%s (Card #%d) Rev.%x\n",
5009 snd_iprintf(buffer,
"IRQ: %d Registers bus: 0x%lx VM: 0x%lx\n",
5012 snd_iprintf(buffer,
"--- System ---\n");
5015 "IRQ Pending: Audio=%d, MIDI0=%d, MIDI1=%d, IRQcount=%d\n",
5016 status & HDSPM_audioIRQPending,
5017 (status & HDSPM_midi0IRQPending) ? 1 : 0,
5021 "HW pointer: id = %d, rawptr = %d (%d->%d) "
5022 "estimated= %ld (bytes)\n",
5023 ((status & HDSPM_BufferID) ? 1 : 0),
5024 (status & HDSPM_BufferPositionMask),
5025 (status & HDSPM_BufferPositionMask) %
5027 ((status & HDSPM_BufferPositionMask) - 64) %
5029 (
long) hdspm_hw_pointer(hdspm) * 4);
5032 "MIDI FIFO: Out1=0x%x, Out2=0x%x, In1=0x%x, In2=0x%x \n",
5038 "MIDIoverMADI FIFO: In=0x%x, Out=0x%x \n",
5042 "Register: ctrl1=0x%x, ctrl2=0x%x, status1=0x%x, "
5047 snd_iprintf(buffer,
"--- Settings ---\n");
5049 x = hdspm_get_latency(hdspm);
5052 "Size (Latency): %d samples (2 periods of %lu bytes)\n",
5055 snd_iprintf(buffer,
"Line out: %s\n",
5060 "ClearTrackMarker %s, Emphasis %s, Dolby %s\n",
5069 pref_syncref = hdspm_pref_sync_ref(hdspm);
5070 if (pref_syncref == 0)
5071 snd_iprintf(buffer,
"Preferred Sync Reference: Word Clock\n");
5073 snd_iprintf(buffer,
"Preferred Sync Reference: AES%d\n",
5076 snd_iprintf(buffer,
"System Clock Frequency: %d\n",
5079 snd_iprintf(buffer,
"Double speed: %s\n",
5081 "Double wire" :
"Single wire");
5082 snd_iprintf(buffer,
"Quad speed: %s\n",
5086 "Quad wire" :
"Single wire");
5088 snd_iprintf(buffer,
"--- Status:\n");
5090 snd_iprintf(buffer,
"Word: %s Frequency: %d\n",
5091 (status & HDSPM_AES32_wcLock) ?
"Sync " :
"No Lock",
5094 for (x = 0; x < 8; x++) {
5095 snd_iprintf(buffer,
"AES%d: %s Frequency: %d\n",
5098 "Sync " :
"No Lock",
5099 HDSPM_bit2freq((timecode >> (4*x)) & 0xF));
5102 switch (hdspm_autosync_ref(hdspm)) {
5104 autosync_ref =
"None";
break;
5106 autosync_ref =
"Word Clock";
break;
5108 autosync_ref =
"AES1";
break;
5110 autosync_ref =
"AES2";
break;
5112 autosync_ref =
"AES3";
break;
5114 autosync_ref =
"AES4";
break;
5116 autosync_ref =
"AES5";
break;
5118 autosync_ref =
"AES6";
break;
5120 autosync_ref =
"AES7";
break;
5122 autosync_ref =
"AES8";
break;
5124 autosync_ref =
"---";
break;
5126 snd_iprintf(buffer,
"AutoSync ref = %s\n", autosync_ref);
5128 snd_iprintf(buffer,
"\n");
5145 snd_iprintf(buffer,
"STATUS1: 0x%08x\n", status1);
5146 snd_iprintf(buffer,
"STATUS2: 0x%08x\n", status2);
5147 snd_iprintf(buffer,
"STATUS3: 0x%08x\n", status3);
5150 snd_iprintf(buffer,
"\n*** CLOCK MODE\n\n");
5152 snd_iprintf(buffer,
"Clock mode : %s\n",
5153 (hdspm_system_clock_mode(hdspm) == 0) ?
"master" :
"slave");
5154 snd_iprintf(buffer,
"System frequency: %d Hz\n",
5155 hdspm_get_system_sample_rate(hdspm));
5157 snd_iprintf(buffer,
"\n*** INPUT STATUS\n\n");
5162 for (i = 0; i < 8; i++) {
5163 snd_iprintf(buffer,
"s1_input %d: Lock %d, Sync %d, Freq %s\n",
5165 (status1 & lock) ? 1 : 0,
5166 (status1 & sync) ? 1 : 0,
5167 texts_freq[(status2 >> (i * 4)) & 0xF]);
5173 snd_iprintf(buffer,
"WC input: Lock %d, Sync %d, Freq %s\n",
5174 (status1 & 0x1000000) ? 1 : 0,
5175 (status1 & 0x2000000) ? 1 : 0,
5176 texts_freq[(status1 >> 16) & 0xF]);
5178 snd_iprintf(buffer,
"TCO input: Lock %d, Sync %d, Freq %s\n",
5179 (status1 & 0x4000000) ? 1 : 0,
5180 (status1 & 0x8000000) ? 1 : 0,
5181 texts_freq[(status1 >> 20) & 0xF]);
5183 snd_iprintf(buffer,
"SYNC IN: Lock %d, Sync %d, Freq %s\n",
5184 (status3 & 0x400) ? 1 : 0,
5185 (status3 & 0x800) ? 1 : 0,
5186 texts_freq[(status2 >> 12) & 0xF]);
5190 #ifdef CONFIG_SND_DEBUG
5199 for (i = 0; i < 256 ; i +=
j) {
5200 snd_iprintf(buffer,
"0x%08X: ", i);
5201 for (j = 0; j < 16; j += 4)
5202 snd_iprintf(buffer,
"%08X ", hdspm_read(hdspm, i + j));
5203 snd_iprintf(buffer,
"\n");
5209 static void snd_hdspm_proc_ports_in(
struct snd_info_entry *entry,
5215 snd_iprintf(buffer,
"# generated by hdspm\n");
5218 snd_iprintf(buffer,
"%d=%s\n", i+1, hdspm->
port_names_in[i]);
5222 static void snd_hdspm_proc_ports_out(
struct snd_info_entry *entry,
5228 snd_iprintf(buffer,
"# generated by hdspm\n");
5236 static void __devinit snd_hdspm_proc_init(
struct hdspm *hdspm)
5240 if (!snd_card_proc_new(hdspm->
card,
"hdspm", &entry)) {
5243 snd_info_set_text_ops(entry, hdspm,
5244 snd_hdspm_proc_read_aes32);
5247 snd_info_set_text_ops(entry, hdspm,
5248 snd_hdspm_proc_read_madi);
5255 snd_info_set_text_ops(entry, hdspm,
5256 snd_hdspm_proc_read_raydat);
5263 if (!snd_card_proc_new(hdspm->
card,
"ports.in", &entry)) {
5264 snd_info_set_text_ops(entry, hdspm, snd_hdspm_proc_ports_in);
5267 if (!snd_card_proc_new(hdspm->
card,
"ports.out", &entry)) {
5268 snd_info_set_text_ops(entry, hdspm, snd_hdspm_proc_ports_out);
5271 #ifdef CONFIG_SND_DEBUG
5273 if (!snd_card_proc_new(hdspm->
card,
"debug", &entry))
5274 snd_info_set_text_ops(entry, hdspm,
5275 snd_hdspm_proc_read_debug);
5283 static int snd_hdspm_set_defaults(
struct hdspm * hdspm)
5297 0x2 + 0x8 + 0x10 + 0x80 + 0x400 + 0x4000 + 0x1000000;
5306 0x2 + 0x8 + 0x10 + 0x80 + 0x400 + 0x4000 + 0x1000000;
5323 #ifdef SNDRV_BIG_ENDIAN
5331 hdspm_compute_period_size(hdspm);
5342 hdspm_set_rate(hdspm, 48000, 1);
5354 struct hdspm *hdspm = (
struct hdspm *) dev_id;
5382 if (!audio && !midi)
5399 while (i < hdspm->midiPorts) {
5400 if ((hdspm_read(hdspm,
5401 hdspm->
midi[i].statusIn) & 0xff) &&
5402 (status & hdspm->
midi[i].irq)) {
5409 hdspm->
midi[
i].pending = 1;
5432 return hdspm_hw_pointer(hdspm);
5448 runtime->
status->hw_ptr = hdspm_hw_pointer(hdspm);
5450 runtime->
status->hw_ptr = 0;
5456 oruntime->
status->hw_ptr =
5474 spin_lock_irq(&hdspm->
lock);
5484 if (other_pid > 0 && this_pid != other_pid) {
5492 spin_unlock_irq(&hdspm->
lock);
5499 spin_unlock_irq(&hdspm->
lock);
5507 spin_unlock_irq(&hdspm->
lock);
5511 spin_lock_irq(&hdspm->
lock);
5512 err = hdspm_set_rate(hdspm,
params_rate(params), 0);
5515 spin_unlock_irq(&hdspm->
lock);
5520 spin_unlock_irq(&hdspm->
lock);
5522 err = hdspm_set_interrupt_interval(hdspm,
5551 snd_hdspm_enable_out(hdspm, i, 1);
5554 (
unsigned char *) substream->
runtime->dma_area;
5555 snd_printdd(
"Allocated sample buffer for playback at %p\n",
5562 snd_hdspm_enable_in(hdspm, i, 1);
5565 (
unsigned char *) substream->
runtime->dma_area;
5566 snd_printdd(
"Allocated sample buffer for capture at %p\n",
5612 snd_hdspm_enable_out(hdspm, i, 0);
5617 snd_hdspm_enable_in(hdspm, i, 0);
5669 unsigned int cmd,
void *arg)
5673 return snd_hdspm_reset(substream);
5678 return snd_hdspm_channel_info(substream, info);
5693 spin_lock(&hdspm->
lock);
5697 running |= 1 << substream->
stream;
5700 running &= ~(1 << substream->
stream);
5704 spin_unlock(&hdspm->
lock);
5716 snd_pcm_trigger_done(s, substream);
5718 running |= 1 << s->
stream;
5720 running &= ~(1 << s->
stream);
5728 hdspm_silence_playback(hdspm);
5732 hdspm_silence_playback(hdspm);
5736 hdspm_silence_playback(hdspm);
5739 snd_pcm_trigger_done(substream, substream);
5740 if (!hdspm->
running && running)
5741 hdspm_start_audio(hdspm);
5742 else if (hdspm->
running && !running)
5743 hdspm_stop_audio(hdspm);
5745 spin_unlock(&hdspm->
lock);
5773 .period_bytes_min = (32 * 4),
5798 .period_bytes_min = (32 * 4),
5808 struct hdspm *hdspm = rule->
private;
5814 if (r->
min > 96000 && r->
max <= 192000) {
5821 }
else if (r->
min > 48000 && r->
max <= 96000) {
5828 }
else if (r->
max < 64000) {
5840 static int snd_hdspm_hw_rule_out_channels_rate(
struct snd_pcm_hw_params *params,
5843 struct hdspm *hdspm = rule->
private;
5849 if (r->
min > 96000 && r->
max <= 192000) {
5856 }
else if (r->
min > 48000 && r->
max <= 96000) {
5863 }
else if (r->
max < 64000) {
5878 struct hdspm *hdspm = rule->
private;
5909 static int snd_hdspm_hw_rule_rate_out_channels(
struct snd_pcm_hw_params *params,
5912 struct hdspm *hdspm = rule->
private;
5947 unsigned int list[3];
5948 struct hdspm *hdspm = rule->
private;
5961 unsigned int list[3];
5962 struct hdspm *hdspm = rule->
private;
5973 static unsigned int hdspm_aes32_sample_rates[] = {
5974 32000, 44100, 48000, 64000, 88200, 96000, 128000, 176400, 192000
5978 hdspm_hw_constraints_aes32_sample_rates = {
5979 .count =
ARRAY_SIZE(hdspm_aes32_sample_rates),
5980 .list = hdspm_aes32_sample_rates,
5989 spin_lock_irq(&hdspm->
lock);
5994 runtime->
hw = snd_hdspm_playback_subinfo;
5997 hdspm_stop_audio(hdspm);
6002 spin_unlock_irq(&hdspm->
lock);
6029 &hdspm_hw_constraints_aes32_sample_rates);
6032 snd_hdspm_hw_rule_rate_out_channels, hdspm,
6037 snd_hdspm_hw_rule_out_channels, hdspm,
6041 snd_hdspm_hw_rule_out_channels_rate, hdspm,
6051 spin_lock_irq(&hdspm->
lock);
6056 spin_unlock_irq(&hdspm->
lock);
6067 spin_lock_irq(&hdspm->
lock);
6069 runtime->
hw = snd_hdspm_capture_subinfo;
6072 hdspm_stop_audio(hdspm);
6077 spin_unlock_irq(&hdspm->
lock);
6103 &hdspm_hw_constraints_aes32_sample_rates);
6106 snd_hdspm_hw_rule_rate_in_channels, hdspm,
6111 snd_hdspm_hw_rule_in_channels, hdspm,
6115 snd_hdspm_hw_rule_in_channels_rate, hdspm,
6125 spin_lock_irq(&hdspm->
lock);
6130 spin_unlock_irq(&hdspm->
lock);
6140 static inline int copy_u32_le(
void __user *
dest,
void __iomem *
src)
6147 unsigned int cmd,
unsigned long arg)
6157 unsigned int statusregister;
6158 long unsigned int s;
6214 if (i & HDSPM_TCO1_LTC_Input_valid) {
6239 if (i & HDSPM_TCO1_Video_Input_Format_NTSC) {
6240 ltc.input_format =
ntsc;
6241 }
else if (i & HDSPM_TCO1_Video_Input_Format_PAL) {
6242 ltc.input_format =
pal;
6258 memset(&info, 0,
sizeof(info));
6259 spin_lock_irq(&hdspm->
lock);
6260 info.pref_sync_ref = hdspm_pref_sync_ref(hdspm);
6261 info.wordclock_sync_check = hdspm_wc_sync_check(hdspm);
6264 info.autosync_sample_rate =
6265 hdspm_external_sample_rate(hdspm);
6266 info.system_clock_mode = hdspm_system_clock_mode(hdspm);
6267 info.clock_source = hdspm_clock_source(hdspm);
6268 info.autosync_ref = hdspm_autosync_ref(hdspm);
6269 info.line_out = hdspm_line_out(hdspm);
6271 spin_unlock_irq(&hdspm->
lock);
6277 memset(&status, 0,
sizeof(status));
6279 status.card_type = hdspm->
io_type;
6281 status.autosync_source = hdspm_autosync_ref(hdspm);
6283 status.card_clock = 110069313433624ULL;
6289 status.card_specific.madi.sync_wc =
6290 hdspm_wc_sync_check(hdspm);
6291 status.card_specific.madi.sync_madi =
6292 hdspm_madi_sync_check(hdspm);
6293 status.card_specific.madi.sync_tco =
6294 hdspm_tco_sync_check(hdspm);
6295 status.card_specific.madi.sync_in =
6296 hdspm_sync_in_sync_check(hdspm);
6300 status.card_specific.madi.madi_input =
6302 status.card_specific.madi.channel_format =
6305 status.card_specific.madi.frame_format = 0;
6348 static struct snd_pcm_ops snd_hdspm_playback_ops = {
6349 .open = snd_hdspm_playback_open,
6350 .close = snd_hdspm_playback_release,
6351 .ioctl = snd_hdspm_ioctl,
6352 .hw_params = snd_hdspm_hw_params,
6353 .hw_free = snd_hdspm_hw_free,
6354 .prepare = snd_hdspm_prepare,
6355 .trigger = snd_hdspm_trigger,
6356 .pointer = snd_hdspm_hw_pointer,
6360 static struct snd_pcm_ops snd_hdspm_capture_ops = {
6361 .open = snd_hdspm_capture_open,
6362 .close = snd_hdspm_capture_release,
6363 .ioctl = snd_hdspm_ioctl,
6364 .hw_params = snd_hdspm_hw_params,
6365 .hw_free = snd_hdspm_hw_free,
6366 .prepare = snd_hdspm_prepare,
6367 .trigger = snd_hdspm_trigger,
6368 .pointer = snd_hdspm_hw_pointer,
6373 struct hdspm * hdspm)
6386 hw->
ops.open = snd_hdspm_hwdep_dummy_op;
6387 hw->
ops.ioctl = snd_hdspm_hwdep_ioctl;
6388 hw->
ops.ioctl_compat = snd_hdspm_hwdep_ioctl;
6389 hw->
ops.release = snd_hdspm_hwdep_dummy_op;
6398 static int __devinit snd_hdspm_preallocate_memory(
struct hdspm *hdspm)
6415 snd_printdd(
"Could not preallocate %zd Bytes\n", wanted);
6425 static void hdspm_set_sgbuf(
struct hdspm *hdspm,
6432 for (i = 0; i < (channels * 16); i++)
6433 hdspm_write(hdspm, reg + 4 * i,
6434 snd_pcm_sgbuf_get_addr(substream, 4096 * i));
6440 struct hdspm *hdspm)
6454 &snd_hdspm_playback_ops);
6456 &snd_hdspm_capture_ops);
6460 err = snd_hdspm_preallocate_memory(hdspm);
6467 static inline void snd_hdspm_initialize_midi_flush(
struct hdspm * hdspm)
6472 snd_hdspm_flush_midi_input(hdspm, i);
6476 struct hdspm * hdspm)
6481 err = snd_hdspm_create_pcm(card, hdspm);
6486 while (i < hdspm->midiPorts) {
6487 err = snd_hdspm_create_midi(card, hdspm, i);
6494 err = snd_hdspm_create_controls(card, hdspm);
6498 err = snd_hdspm_create_hwdep(card, hdspm);
6503 snd_hdspm_proc_init(hdspm);
6514 err = snd_hdspm_set_defaults(hdspm);
6519 hdspm_update_simple_mixer_controls(hdspm);
6535 struct hdspm *hdspm) {
6539 unsigned long io_extent;
6546 pci_read_config_word(hdspm->
pci,
6583 "HDSPM: unknown firmware revision %x\n",
6602 snd_printdd(
"grabbed memory region 0x%lx-0x%lx\n",
6603 hdspm->
port, hdspm->
port + io_extent - 1);
6608 "unable to remap region 0x%lx-0x%lx\n",
6609 hdspm->
port, hdspm->
port + io_extent - 1);
6612 snd_printdd(
"remapped region (0x%lx) 0x%lx-0x%lx\n",
6614 hdspm->
port + io_extent - 1);
6626 snd_printdd(
"kmalloc Mixer memory of %zd Bytes\n",
6629 if (!hdspm->
mixer) {
6631 "unable to kmalloc Mixer memory of %d Bytes\n",
6677 channel_map_unity_ss;
6679 channel_map_unity_ss;
6681 channel_map_unity_ss;
6732 channel_map_raydat_ss;
6734 channel_map_raydat_ds;
6736 channel_map_raydat_qs;
6738 channel_map_raydat_ss;
6741 texts_ports_raydat_ss;
6743 texts_ports_raydat_ds;
6745 texts_ports_raydat_qs;
6762 hdspm_tco_write(hdspm);
6776 hdspm_tco_write(hdspm);
6837 hdspm_midi_tasklet, (
unsigned long) hdspm);
6841 hdspm->
serial = (hdspm_read(hdspm,
6859 err = snd_hdspm_create_alsa_devices(card, hdspm);
6863 snd_hdspm_initialize_midi_flush(hdspm);
6869 static int snd_hdspm_free(
struct hdspm * hdspm)
6883 if (hdspm->
irq >= 0)
6899 static void snd_hdspm_card_free(
struct snd_card *card)
6904 snd_hdspm_free(hdspm);
6912 struct hdspm *hdspm;
6935 err = snd_hdspm_create(card, hdspm);
6961 pci_set_drvdata(pci, card);
6970 pci_set_drvdata(pci,
NULL);
6974 .name = KBUILD_MODNAME,
6975 .id_table = snd_hdspm_ids,
6976 .probe = snd_hdspm_probe,