linux/sound/pci/rme9652/hdspm.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *   ALSA driver for RME Hammerfall DSP MADI audio interface(s)
 *
 *      Copyright (c) 2003 Winfried Ritsch (IEM)
 *      code based on hdsp.c   Paul Davis
 *                             Marcus Andersson
 *                             Thomas Charbonnel
 *      Modified 2006-06-01 for AES32 support by Remy Bruno
 *                                               <[email protected]>
 *
 *      Modified 2009-04-13 for proper metering by Florian Faber
 *                                               <[email protected]>
 *
 *      Modified 2009-04-14 for native float support by Florian Faber
 *                                               <[email protected]>
 *
 *      Modified 2009-04-26 fixed bug in rms metering by Florian Faber
 *                                               <[email protected]>
 *
 *      Modified 2009-04-30 added hw serial number support by Florian Faber
 *
 *      Modified 2011-01-14 added S/PDIF input on RayDATs by Adrian Knoth
 *
 *	Modified 2011-01-25 variable period sizes on RayDAT/AIO by Adrian Knoth
 *
 *      Modified 2019-05-23 fix AIO single speed ADAT capture and playback
 *      by [email protected]
 */

/* *************    Register Documentation   *******************************************************
 *
 * Work in progress! Documentation is based on the code in this file.
 *
 * --------- HDSPM_controlRegister ---------
 * :7654.3210:7654.3210:7654.3210:7654.3210: bit number per byte
 * :||||.||||:||||.||||:||||.||||:||||.||||:
 * :3322.2222:2222.1111:1111.1100:0000.0000: bit number
 * :1098.7654:3210.9876:5432.1098:7654.3210: 0..31
 * :||||.||||:||||.||||:||||.||||:||||.||||:
 * :8421.8421:8421.8421:8421.8421:8421.8421: hex digit
 * :    .    :    .    :    .    :  x .    :  HDSPM_AudioInterruptEnable \_ setting both bits
 * :    .    :    .    :    .    :    .   x:  HDSPM_Start                /  enables audio IO
 * :    .    :    .    :    .    :   x.    :  HDSPM_ClockModeMaster - 1: Master, 0: Slave
 * :    .    :    .    :    .    :    .210 :  HDSPM_LatencyMask - 3 Bit value for latency
 * :    .    :    .    :    .    :    .    :      0:64, 1:128, 2:256, 3:512,
 * :    .    :    .    :    .    :    .    :      4:1024, 5:2048, 6:4096, 7:8192
 * :x   .    :    .    :    .   x:xx  .    :  HDSPM_FrequencyMask
 * :    .    :    .    :    .    :10  .    :  HDSPM_Frequency1|HDSPM_Frequency0: 1=32K,2=44.1K,3=48K,0=??
 * :    .    :    .    :    .   x:    .    :  <MADI> HDSPM_DoubleSpeed
 * :x   .    :    .    :    .    :    .    :  <MADI> HDSPM_QuadSpeed
 * :    .  3 :    .  10:  2 .    :    .    :  HDSPM_SyncRefMask :
 * :    .    :    .   x:    .    :    .    :  HDSPM_SyncRef0
 * :    .    :    .  x :    .    :    .    :  HDSPM_SyncRef1
 * :    .    :    .    :  x .    :    .    :  <AES32> HDSPM_SyncRef2
 * :    .  x :    .    :    .    :    .    :  <AES32> HDSPM_SyncRef3
 * :    .    :    .  10:    .    :    .    :  <MADI> sync ref: 0:WC, 1:Madi, 2:TCO, 3:SyncIn
 * :    .  3 :    .  10:  2 .    :    .    :  <AES32>  0:WC, 1:AES1 ... 8:AES8, 9: TCO, 10:SyncIn?
 * :    .  x :    .    :    .    :    .    :  <MADIe> HDSPe_FLOAT_FORMAT
 * :    .    :    .    : x  .    :    .    :  <MADI> HDSPM_InputSelect0 : 0=optical,1=coax
 * :    .    :    .    :x   .    :    .    :  <MADI> HDSPM_InputSelect1
 * :    .    :    .x   :    .    :    .    :  <MADI> HDSPM_clr_tms
 * :    .    :    .    :    . x  :    .    :  <MADI> HDSPM_TX_64ch
 * :    .    :    .    :    . x  :    .    :  <AES32> HDSPM_Emphasis
 * :    .    :    .    :    .x   :    .    :  <MADI> HDSPM_AutoInp
 * :    .    :    . x  :    .    :    .    :  <MADI> HDSPM_SMUX
 * :    .    :    .x   :    .    :    .    :  <MADI> HDSPM_clr_tms
 * :    .    :   x.    :    .    :    .    :  <MADI> HDSPM_taxi_reset
 * :    .   x:    .    :    .    :    .    :  <MADI> HDSPM_LineOut
 * :    .   x:    .    :    .    :    .    :  <AES32> ??????????????????
 * :    .    :   x.    :    .    :    .    :  <AES32> HDSPM_WCK48
 * :    .    :    .    :    .x   :    .    :  <AES32> HDSPM_Dolby
 * :    .    : x  .    :    .    :    .    :  HDSPM_Midi0InterruptEnable
 * :    .    :x   .    :    .    :    .    :  HDSPM_Midi1InterruptEnable
 * :    .    :  x .    :    .    :    .    :  HDSPM_Midi2InterruptEnable
 * :    . x  :    .    :    .    :    .    :  <MADI> HDSPM_Midi3InterruptEnable
 * :    . x  :    .    :    .    :    .    :  <AES32> HDSPM_DS_DoubleWire
 * :    .x   :    .    :    .    :    .    :  <AES32> HDSPM_QS_DoubleWire
 * :   x.    :    .    :    .    :    .    :  <AES32> HDSPM_QS_QuadWire
 * :    .    :    .    :    .  x :    .    :  <AES32> HDSPM_Professional
 * : x  .    :    .    :    .    :    .    :  HDSPM_wclk_sel
 * :    .    :    .    :    .    :    .    :
 * :7654.3210:7654.3210:7654.3210:7654.3210: bit number per byte
 * :||||.||||:||||.||||:||||.||||:||||.||||:
 * :3322.2222:2222.1111:1111.1100:0000.0000: bit number
 * :1098.7654:3210.9876:5432.1098:7654.3210: 0..31
 * :||||.||||:||||.||||:||||.||||:||||.||||:
 * :8421.8421:8421.8421:8421.8421:8421.8421:hex digit
 *
 *
 *
 * AIO / RayDAT only
 *
 * ------------ HDSPM_WR_SETTINGS ----------
 * :3322.2222:2222.1111:1111.1100:0000.0000: bit number per byte
 * :1098.7654:3210.9876:5432.1098:7654.3210:
 * :||||.||||:||||.||||:||||.||||:||||.||||: bit number
 * :7654.3210:7654.3210:7654.3210:7654.3210: 0..31
 * :||||.||||:||||.||||:||||.||||:||||.||||:
 * :8421.8421:8421.8421:8421.8421:8421.8421: hex digit
 * :    .    :    .    :    .    :    .   x: HDSPM_c0Master 1: Master, 0: Slave
 * :    .    :    .    :    .    :    .  x : HDSPM_c0_SyncRef0
 * :    .    :    .    :    .    :    . x  : HDSPM_c0_SyncRef1
 * :    .    :    .    :    .    :    .x   : HDSPM_c0_SyncRef2
 * :    .    :    .    :    .    :   x.    : HDSPM_c0_SyncRef3
 * :    .    :    .    :    .    :   3.210 : HDSPM_c0_SyncRefMask:
 * :    .    :    .    :    .    :    .    :  RayDat: 0:WC, 1:AES, 2:SPDIF, 3..6: ADAT1..4,
 * :    .    :    .    :    .    :    .    :          9:TCO, 10:SyncIn
 * :    .    :    .    :    .    :    .    :  AIO: 0:WC, 1:AES, 2: SPDIF, 3: ATAT,
 * :    .    :    .    :    .    :    .    :          9:TCO, 10:SyncIn
 * :    .    :    .    :    .    :    .    :
 * :    .    :    .    :    .    :    .    :
 * :3322.2222:2222.1111:1111.1100:0000.0000: bit number per byte
 * :1098.7654:3210.9876:5432.1098:7654.3210:
 * :||||.||||:||||.||||:||||.||||:||||.||||: bit number
 * :7654.3210:7654.3210:7654.3210:7654.3210: 0..31
 * :||||.||||:||||.||||:||||.||||:||||.||||:
 * :8421.8421:8421.8421:8421.8421:8421.8421: hex digit
 *
 */
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/math64.h>
#include <linux/io.h>
#include <linux/nospec.h>

#include <sound/core.h>
#include <sound/control.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/info.h>
#include <sound/asoundef.h>
#include <sound/rawmidi.h>
#include <sound/hwdep.h>
#include <sound/initval.h>

#include <sound/hdspm.h>

static int index[SNDRV_CARDS] =;	  /* Index 0-MAX */
static char *id[SNDRV_CARDS] =;	  /* ID for this card */
static bool enable[SNDRV_CARDS] =;/* Enable this card */

module_param_array();
MODULE_PARM_DESC();

module_param_array();
MODULE_PARM_DESC();

module_param_array();
MODULE_PARM_DESC();


MODULE_AUTHOR();
MODULE_DESCRIPTION();
MODULE_LICENSE();

/* --- Write registers. ---
  These are defined as byte-offsets from the iobase value.  */

#define HDSPM_WR_SETTINGS
#define HDSPM_outputBufferAddress
#define HDSPM_inputBufferAddress
#define HDSPM_controlRegister
#define HDSPM_interruptConfirmation
#define HDSPM_control2Reg
#define HDSPM_freqReg
#define HDSPM_midiDataOut0
#define HDSPM_midiDataOut1
#define HDSPM_eeprom_wr

/* DMA enable for 64 channels, only Bit 0 is relevant */
#define HDSPM_outputEnableBase
#define HDSPM_inputEnableBase

/* 16 page addresses for each of the 64 channels DMA buffer in and out
   (each 64k=16*4k) Buffer must be 4k aligned (which is default i386 ????) */
#define HDSPM_pageAddressBufferOut
#define HDSPM_pageAddressBufferIn

#define HDSPM_MADI_mixerBase

#define HDSPM_MATRIX_MIXER_SIZE

/* --- Read registers. ---
   These are defined as byte-offsets from the iobase value */
#define HDSPM_statusRegister
/*#define HDSPM_statusRegister2  96 */
/* after RME Windows driver sources, status2 is 4-byte word # 48 = word at
 * offset 192, for AES32 *and* MADI
 * => need to check that offset 192 is working on MADI */
#define HDSPM_statusRegister2
#define HDSPM_timecodeRegister

/* AIO, RayDAT */
#define HDSPM_RD_STATUS_0
#define HDSPM_RD_STATUS_1
#define HDSPM_RD_STATUS_2
#define HDSPM_RD_STATUS_3

#define HDSPM_RD_TCO
#define HDSPM_RD_PLL_FREQ
#define HDSPM_WR_TCO

#define HDSPM_TCO1_TCO_lock
#define HDSPM_TCO1_WCK_Input_Range_LSB
#define HDSPM_TCO1_WCK_Input_Range_MSB
#define HDSPM_TCO1_LTC_Input_valid
#define HDSPM_TCO1_WCK_Input_valid
#define HDSPM_TCO1_Video_Input_Format_NTSC
#define HDSPM_TCO1_Video_Input_Format_PAL

#define HDSPM_TCO1_set_TC
#define HDSPM_TCO1_set_drop_frame_flag
#define HDSPM_TCO1_LTC_Format_LSB
#define HDSPM_TCO1_LTC_Format_MSB

#define HDSPM_TCO2_TC_run
#define HDSPM_TCO2_WCK_IO_ratio_LSB
#define HDSPM_TCO2_WCK_IO_ratio_MSB
#define HDSPM_TCO2_set_num_drop_frames_LSB
#define HDSPM_TCO2_set_num_drop_frames_MSB
#define HDSPM_TCO2_set_jam_sync
#define HDSPM_TCO2_set_flywheel

#define HDSPM_TCO2_set_01_4
#define HDSPM_TCO2_set_pull_down
#define HDSPM_TCO2_set_pull_up
#define HDSPM_TCO2_set_freq
#define HDSPM_TCO2_set_term_75R
#define HDSPM_TCO2_set_input_LSB
#define HDSPM_TCO2_set_input_MSB
#define HDSPM_TCO2_set_freq_from_app


#define HDSPM_midiDataOut0
#define HDSPM_midiDataOut1
#define HDSPM_midiDataOut2

#define HDSPM_midiDataIn0
#define HDSPM_midiDataIn1
#define HDSPM_midiDataIn2
#define HDSPM_midiDataIn3

/* status is data bytes in MIDI-FIFO (0-128) */
#define HDSPM_midiStatusOut0
#define HDSPM_midiStatusOut1
#define HDSPM_midiStatusOut2

#define HDSPM_midiStatusIn0
#define HDSPM_midiStatusIn1
#define HDSPM_midiStatusIn2
#define HDSPM_midiStatusIn3


/* the meters are regular i/o-mapped registers, but offset
   considerably from the rest. the peak registers are reset
   when read; the least-significant 4 bits are full-scale counters;
   the actual peak value is in the most-significant 24 bits.
*/

#define HDSPM_MADI_INPUT_PEAK
#define HDSPM_MADI_PLAYBACK_PEAK
#define HDSPM_MADI_OUTPUT_PEAK

#define HDSPM_MADI_INPUT_RMS_L
#define HDSPM_MADI_PLAYBACK_RMS_L
#define HDSPM_MADI_OUTPUT_RMS_L

#define HDSPM_MADI_INPUT_RMS_H
#define HDSPM_MADI_PLAYBACK_RMS_H
#define HDSPM_MADI_OUTPUT_RMS_H

/* --- Control Register bits --------- */
#define HDSPM_Start

#define HDSPM_Latency0
#define HDSPM_Latency1
#define HDSPM_Latency2

#define HDSPM_ClockModeMaster
#define HDSPM_c0Master

#define HDSPM_AudioInterruptEnable

#define HDSPM_Frequency0
#define HDSPM_Frequency1
#define HDSPM_DoubleSpeed
#define HDSPM_QuadSpeed

#define HDSPM_Professional
#define HDSPM_TX_64ch
#define HDSPM_Emphasis

#define HDSPM_AutoInp
#define HDSPM_Dolby

#define HDSPM_InputSelect0
#define HDSPM_InputSelect1

#define HDSPM_SyncRef2
#define HDSPM_SyncRef3

#define HDSPM_SMUX
#define HDSPM_clr_tms
#define HDSPM_taxi_reset
#define HDSPM_WCK48

#define HDSPM_Midi0InterruptEnable
#define HDSPM_Midi1InterruptEnable
#define HDSPM_Midi2InterruptEnable
#define HDSPM_Midi3InterruptEnable

#define HDSPM_LineOut
#define HDSPe_FLOAT_FORMAT

#define HDSPM_DS_DoubleWire
#define HDSPM_QS_DoubleWire
#define HDSPM_QS_QuadWire

#define HDSPM_wclk_sel

/* additional control register bits for AIO*/
#define HDSPM_c0_Wck48
#define HDSPM_c0_Input0
#define HDSPM_c0_Input1
#define HDSPM_c0_Spdif_Opt
#define HDSPM_c0_Pro
#define HDSPM_c0_clr_tms
#define HDSPM_c0_AEB1
#define HDSPM_c0_AEB2
#define HDSPM_c0_LineOut
#define HDSPM_c0_AD_GAIN0
#define HDSPM_c0_AD_GAIN1
#define HDSPM_c0_DA_GAIN0
#define HDSPM_c0_DA_GAIN1
#define HDSPM_c0_PH_GAIN0
#define HDSPM_c0_PH_GAIN1
#define HDSPM_c0_Sym6db


/* --- bit helper defines */
#define HDSPM_LatencyMask
#define HDSPM_FrequencyMask
#define HDSPM_InputMask
#define HDSPM_InputOptical
#define HDSPM_InputCoaxial
#define HDSPM_SyncRefMask

#define HDSPM_c0_SyncRef0
#define HDSPM_c0_SyncRef1
#define HDSPM_c0_SyncRef2
#define HDSPM_c0_SyncRef3
#define HDSPM_c0_SyncRefMask

#define HDSPM_SYNC_FROM_WORD
#define HDSPM_SYNC_FROM_MADI
#define HDSPM_SYNC_FROM_TCO
#define HDSPM_SYNC_FROM_SYNC_IN

#define HDSPM_Frequency32KHz
#define HDSPM_Frequency44_1KHz
#define HDSPM_Frequency48KHz
#define HDSPM_Frequency64KHz
#define HDSPM_Frequency88_2KHz
#define HDSPM_Frequency96KHz
#define HDSPM_Frequency128KHz
#define HDSPM_Frequency176_4KHz
#define HDSPM_Frequency192KHz


/* Synccheck Status */
#define HDSPM_SYNC_CHECK_NO_LOCK
#define HDSPM_SYNC_CHECK_LOCK
#define HDSPM_SYNC_CHECK_SYNC

/* AutoSync References - used by "autosync_ref" control switch */
#define HDSPM_AUTOSYNC_FROM_WORD
#define HDSPM_AUTOSYNC_FROM_MADI
#define HDSPM_AUTOSYNC_FROM_TCO
#define HDSPM_AUTOSYNC_FROM_SYNC_IN
#define HDSPM_AUTOSYNC_FROM_NONE

/* Possible sources of MADI input */
#define HDSPM_OPTICAL
#define HDSPM_COAXIAL

#define hdspm_encode_latency(x)
#define hdspm_decode_latency(x)

#define hdspm_encode_in(x)
#define hdspm_decode_in(x)

/* --- control2 register bits --- */
#define HDSPM_TMS
#define HDSPM_TCK
#define HDSPM_TDI
#define HDSPM_JTAG
#define HDSPM_PWDN
#define HDSPM_PROGRAM
#define HDSPM_CONFIG_MODE_0
#define HDSPM_CONFIG_MODE_1
/*#define HDSPM_VERSION_BIT     (1<<8) not defined any more*/
#define HDSPM_BIGENDIAN_MODE
#define HDSPM_RD_MULTIPLE

/* --- Status Register bits --- */ /* MADI ONLY */ /* Bits defined here and
     that do not conflict with specific bits for AES32 seem to be valid also
     for the AES32
 */
#define HDSPM_audioIRQPending
#define HDSPM_RX_64ch
#define HDSPM_AB_int

#define HDSPM_madiLock
#define HDSPM_madiSync

#define HDSPM_tcoLockMadi
#define HDSPM_tcoSync

#define HDSPM_syncInLock
#define HDSPM_syncInSync

#define HDSPM_BufferPositionMask
			/* since 64byte accurate, last 6 bits are not used */



#define HDSPM_DoubleSpeedStatus

#define HDSPM_madiFreq0
#define HDSPM_madiFreq1
#define HDSPM_madiFreq2
#define HDSPM_madiFreq3

#define HDSPM_BufferID
#define HDSPM_tco_detect
#define HDSPM_tcoLockAes

#define HDSPM_s2_tco_detect
#define HDSPM_s2_AEBO_D
#define HDSPM_s2_AEBI_D


#define HDSPM_midi0IRQPending
#define HDSPM_midi1IRQPending
#define HDSPM_midi2IRQPending
#define HDSPM_midi2IRQPendingAES
#define HDSPM_midi3IRQPending

/* --- status bit helpers */
#define HDSPM_madiFreqMask
#define HDSPM_madiFreq32
#define HDSPM_madiFreq44_1
#define HDSPM_madiFreq48
#define HDSPM_madiFreq64
#define HDSPM_madiFreq88_2
#define HDSPM_madiFreq96
#define HDSPM_madiFreq128
#define HDSPM_madiFreq176_4
#define HDSPM_madiFreq192

/* Status2 Register bits */ /* MADI ONLY */

#define HDSPM_version0
#define HDSPM_version1
#define HDSPM_version2

#define HDSPM_wcLock
#define HDSPM_wcSync

#define HDSPM_wc_freq0
#define HDSPM_wc_freq1
#define HDSPM_wc_freq2
#define HDSPM_wc_freq3

#define HDSPM_SyncRef0
#define HDSPM_SyncRef1

#define HDSPM_SelSyncRef0
#define HDSPM_SelSyncRef1
#define HDSPM_SelSyncRef2

#define HDSPM_wc_valid

#define HDSPM_wcFreqMask
#define HDSPM_wcFreq32
#define HDSPM_wcFreq44_1
#define HDSPM_wcFreq48
#define HDSPM_wcFreq64
#define HDSPM_wcFreq88_2
#define HDSPM_wcFreq96
#define HDSPM_wcFreq128
#define HDSPM_wcFreq176_4
#define HDSPM_wcFreq192

#define HDSPM_status1_F_0
#define HDSPM_status1_F_1
#define HDSPM_status1_F_2
#define HDSPM_status1_F_3
#define HDSPM_status1_freqMask


#define HDSPM_SelSyncRefMask
#define HDSPM_SelSyncRef_WORD
#define HDSPM_SelSyncRef_MADI
#define HDSPM_SelSyncRef_TCO
#define HDSPM_SelSyncRef_SyncIn
#define HDSPM_SelSyncRef_NVALID

/*
   For AES32, bits for status, status2 and timecode are different
*/
/* status */
#define HDSPM_AES32_wcLock
#define HDSPM_AES32_wcSync
#define HDSPM_AES32_wcFreq_bit
/* (status >> HDSPM_AES32_wcFreq_bit) & 0xF gives WC frequency (cf function
  HDSPM_bit2freq */
#define HDSPM_AES32_syncref_bit
/* (status >> HDSPM_AES32_syncref_bit) & 0xF gives sync source */

#define HDSPM_AES32_AUTOSYNC_FROM_WORD
#define HDSPM_AES32_AUTOSYNC_FROM_AES1
#define HDSPM_AES32_AUTOSYNC_FROM_AES2
#define HDSPM_AES32_AUTOSYNC_FROM_AES3
#define HDSPM_AES32_AUTOSYNC_FROM_AES4
#define HDSPM_AES32_AUTOSYNC_FROM_AES5
#define HDSPM_AES32_AUTOSYNC_FROM_AES6
#define HDSPM_AES32_AUTOSYNC_FROM_AES7
#define HDSPM_AES32_AUTOSYNC_FROM_AES8
#define HDSPM_AES32_AUTOSYNC_FROM_TCO
#define HDSPM_AES32_AUTOSYNC_FROM_SYNC_IN
#define HDSPM_AES32_AUTOSYNC_FROM_NONE

/*  status2 */
/* HDSPM_LockAES_bit is given by HDSPM_LockAES >> (AES# - 1) */
#define HDSPM_LockAES
#define HDSPM_LockAES1
#define HDSPM_LockAES2
#define HDSPM_LockAES3
#define HDSPM_LockAES4
#define HDSPM_LockAES5
#define HDSPM_LockAES6
#define HDSPM_LockAES7
#define HDSPM_LockAES8
/*
   Timecode
   After windows driver sources, bits 4*i to 4*i+3 give the input frequency on
   AES i+1
 bits 3210
      0001  32kHz
      0010  44.1kHz
      0011  48kHz
      0100  64kHz
      0101  88.2kHz
      0110  96kHz
      0111  128kHz
      1000  176.4kHz
      1001  192kHz
  NB: Timecode register doesn't seem to work on AES32 card revision 230
*/

/* Mixer Values */
#define UNITY_GAIN
#define MINUS_INFINITY_GAIN

/* Number of channels for different Speed Modes */
#define MADI_SS_CHANNELS
#define MADI_DS_CHANNELS
#define MADI_QS_CHANNELS

#define RAYDAT_SS_CHANNELS
#define RAYDAT_DS_CHANNELS
#define RAYDAT_QS_CHANNELS

#define AIO_IN_SS_CHANNELS
#define AIO_IN_DS_CHANNELS
#define AIO_IN_QS_CHANNELS
#define AIO_OUT_SS_CHANNELS
#define AIO_OUT_DS_CHANNELS
#define AIO_OUT_QS_CHANNELS

#define AES32_CHANNELS

/* the size of a substream (1 mono data stream) */
#define HDSPM_CHANNEL_BUFFER_SAMPLES
#define HDSPM_CHANNEL_BUFFER_BYTES

/* the size of the area we need to allocate for DMA transfers. the
   size is the same regardless of the number of channels, and
   also the latency to use.
   for one direction !!!
*/
#define HDSPM_DMA_AREA_BYTES
#define HDSPM_DMA_AREA_KILOBYTES

#define HDSPM_RAYDAT_REV
#define HDSPM_AIO_REV
#define HDSPM_MADIFACE_REV

/* speed factor modes */
#define HDSPM_SPEED_SINGLE
#define HDSPM_SPEED_DOUBLE
#define HDSPM_SPEED_QUAD

/* names for speed modes */
static const char * const hdspm_speed_names[] =;

static const char *const texts_autosync_aes_tco[] =;
static const char *const texts_autosync_aes[] =;
static const char *const texts_autosync_madi_tco[] =;
static const char *const texts_autosync_madi[] =;

static const char *const texts_autosync_raydat_tco[] =;
static const char *const texts_autosync_raydat[] =;
static const char *const texts_autosync_aio_tco[] =;
static const char *const texts_autosync_aio[] =;

static const char *const texts_freq[] =;

static const char * const texts_ports_madi[] =;


static const char * const texts_ports_raydat_ss[] =;

static const char * const texts_ports_raydat_ds[] =;

static const char * const texts_ports_raydat_qs[] =;


static const char * const texts_ports_aio_in_ss[] =;

static const char * const texts_ports_aio_out_ss[] =;

static const char * const texts_ports_aio_in_ds[] =;

static const char * const texts_ports_aio_out_ds[] =;

static const char * const texts_ports_aio_in_qs[] =;

static const char * const texts_ports_aio_out_qs[] =;

static const char * const texts_ports_aes32[] =;

/* These tables map the ALSA channels 1..N to the channels that we
   need to use in order to find the relevant channel buffer. RME
   refers to this kind of mapping as between "the ADAT channel and
   the DMA channel." We index it using the logical audio channel,
   and the value is the DMA channel (i.e. channel buffer number)
   where the data for that channel can be read/written from/to.
*/

static const char channel_map_unity_ss[HDSPM_MAX_CHANNELS] =;

static const char channel_map_raydat_ss[HDSPM_MAX_CHANNELS] =;

static const char channel_map_raydat_ds[HDSPM_MAX_CHANNELS] =;

static const char channel_map_raydat_qs[HDSPM_MAX_CHANNELS] =;

static const char channel_map_aio_in_ss[HDSPM_MAX_CHANNELS] =;

static const char channel_map_aio_out_ss[HDSPM_MAX_CHANNELS] =;

static const char channel_map_aio_in_ds[HDSPM_MAX_CHANNELS] =;

static const char channel_map_aio_out_ds[HDSPM_MAX_CHANNELS] =;

static const char channel_map_aio_in_qs[HDSPM_MAX_CHANNELS] =;

static const char channel_map_aio_out_qs[HDSPM_MAX_CHANNELS] =;

static const char channel_map_aes32[HDSPM_MAX_CHANNELS] =;

struct hdspm_midi {};

struct hdspm_tco {};

struct hdspm {};


static const struct pci_device_id snd_hdspm_ids[] =;

MODULE_DEVICE_TABLE(pci, snd_hdspm_ids);

/* prototypes */
static int snd_hdspm_create_alsa_devices(struct snd_card *card,
					 struct hdspm *hdspm);
static int snd_hdspm_create_pcm(struct snd_card *card,
				struct hdspm *hdspm);

static inline void snd_hdspm_initialize_midi_flush(struct hdspm *hdspm);
static inline int hdspm_get_pll_freq(struct hdspm *hdspm);
static int hdspm_update_simple_mixer_controls(struct hdspm *hdspm);
static int hdspm_autosync_ref(struct hdspm *hdspm);
static int hdspm_set_toggle_setting(struct hdspm *hdspm, u32 regmask, int out);
static int snd_hdspm_set_defaults(struct hdspm *hdspm);
static int hdspm_system_clock_mode(struct hdspm *hdspm);
static void hdspm_set_channel_dma_addr(struct hdspm *hdspm,
				       struct snd_pcm_substream *substream,
				       unsigned int reg, int channels);

static int hdspm_aes_sync_check(struct hdspm *hdspm, int idx);
static int hdspm_wc_sync_check(struct hdspm *hdspm);
static int hdspm_tco_sync_check(struct hdspm *hdspm);
static int hdspm_sync_in_sync_check(struct hdspm *hdspm);

static int hdspm_get_aes_sample_rate(struct hdspm *hdspm, int index);
static int hdspm_get_tco_sample_rate(struct hdspm *hdspm);
static int hdspm_get_wc_sample_rate(struct hdspm *hdspm);



static inline int HDSPM_bit2freq(int n)
{}

static bool hdspm_is_raydat_or_aio(struct hdspm *hdspm)
{}


/* Write/read to/from HDSPM with Adresses in Bytes
   not words but only 32Bit writes are allowed */

static inline void hdspm_write(struct hdspm * hdspm, unsigned int reg,
			       unsigned int val)
{}

static inline unsigned int hdspm_read(struct hdspm * hdspm, unsigned int reg)
{}

/* for each output channel (chan) I have an Input (in) and Playback (pb) Fader
   mixer is write only on hardware so we have to cache him for read
   each fader is a u32, but uses only the first 16 bit */

static inline int hdspm_read_in_gain(struct hdspm * hdspm, unsigned int chan,
				     unsigned int in)
{}

static inline int hdspm_read_pb_gain(struct hdspm * hdspm, unsigned int chan,
				     unsigned int pb)
{}

static int hdspm_write_in_gain(struct hdspm *hdspm, unsigned int chan,
				      unsigned int in, unsigned short data)
{}

static int hdspm_write_pb_gain(struct hdspm *hdspm, unsigned int chan,
				      unsigned int pb, unsigned short data)
{}


/* enable DMA for specific channels, now available for DSP-MADI */
static inline void snd_hdspm_enable_in(struct hdspm * hdspm, int i, int v)
{}

static inline void snd_hdspm_enable_out(struct hdspm * hdspm, int i, int v)
{}

/* check if same process is writing and reading */
static int snd_hdspm_use_is_exclusive(struct hdspm *hdspm)
{}

/* round arbitrary sample rates to commonly known rates */
static int hdspm_round_frequency(int rate)
{}

/* QS and DS rates normally can not be detected
 * automatically by the card. Only exception is MADI
 * in 96k frame mode.
 *
 * So if we read SS values (32 .. 48k), check for
 * user-provided DS/QS bits in the control register
 * and multiply the base frequency accordingly.
 */
static int hdspm_rate_multiplier(struct hdspm *hdspm, int rate)
{}

/* check for external sample rate, returns the sample rate in Hz*/
static int hdspm_external_sample_rate(struct hdspm *hdspm)
{}

/* return latency in samples per period */
static int hdspm_get_latency(struct hdspm *hdspm)
{}

/* Latency function */
static inline void hdspm_compute_period_size(struct hdspm *hdspm)
{}


static snd_pcm_uframes_t hdspm_hw_pointer(struct hdspm *hdspm)
{}


static inline void hdspm_start_audio(struct hdspm * s)
{}

static inline void hdspm_stop_audio(struct hdspm * s)
{}

/* should I silence all or only opened ones ? doit all for first even is 4MB*/
static void hdspm_silence_playback(struct hdspm *hdspm)
{}

static int hdspm_set_interrupt_interval(struct hdspm *s, unsigned int frames)
{}

static u64 hdspm_calc_dds_value(struct hdspm *hdspm, u64 period)
{}


static void hdspm_set_dds_value(struct hdspm *hdspm, int rate)
{}

/* dummy set rate lets see what happens */
static int hdspm_set_rate(struct hdspm * hdspm, int rate, int called_internally)
{}

/* mainly for init to 0 on load */
static void all_in_all_mixer(struct hdspm * hdspm, int sgain)
{}

/*----------------------------------------------------------------------------
   MIDI
  ----------------------------------------------------------------------------*/

static inline unsigned char snd_hdspm_midi_read_byte (struct hdspm *hdspm,
						      int id)
{}

static inline void snd_hdspm_midi_write_byte (struct hdspm *hdspm, int id,
					      int val)
{}

static inline int snd_hdspm_midi_input_available (struct hdspm *hdspm, int id)
{}

static inline int snd_hdspm_midi_output_possible (struct hdspm *hdspm, int id)
{}

static void snd_hdspm_flush_midi_input(struct hdspm *hdspm, int id)
{}

static int snd_hdspm_midi_output_write (struct hdspm_midi *hmidi)
{}

static int snd_hdspm_midi_input_read (struct hdspm_midi *hmidi)
{}

static void
snd_hdspm_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
{}

static void snd_hdspm_midi_output_timer(struct timer_list *t)
{}

static void
snd_hdspm_midi_output_trigger(struct snd_rawmidi_substream *substream, int up)
{}

static int snd_hdspm_midi_input_open(struct snd_rawmidi_substream *substream)
{}

static int snd_hdspm_midi_output_open(struct snd_rawmidi_substream *substream)
{}

static int snd_hdspm_midi_input_close(struct snd_rawmidi_substream *substream)
{}

static int snd_hdspm_midi_output_close(struct snd_rawmidi_substream *substream)
{}

static const struct snd_rawmidi_ops snd_hdspm_midi_output =;

static const struct snd_rawmidi_ops snd_hdspm_midi_input =;

static int snd_hdspm_create_midi(struct snd_card *card,
				 struct hdspm *hdspm, int id)
{}


static void hdspm_midi_work(struct work_struct *work)
{}


/*-----------------------------------------------------------------------------
  Status Interface
  ----------------------------------------------------------------------------*/

/* get the system sample rate which is set */


static inline int hdspm_get_pll_freq(struct hdspm *hdspm)
{}

/*
 * Calculate the real sample rate from the
 * current DDS value.
 */
static int hdspm_get_system_sample_rate(struct hdspm *hdspm)
{}


#define HDSPM_SYSTEM_SAMPLE_RATE(xname, xindex)

static int snd_hdspm_info_system_sample_rate(struct snd_kcontrol *kcontrol,
					     struct snd_ctl_elem_info *uinfo)
{}


static int snd_hdspm_get_system_sample_rate(struct snd_kcontrol *kcontrol,
					    struct snd_ctl_elem_value *
					    ucontrol)
{}

static int snd_hdspm_put_system_sample_rate(struct snd_kcontrol *kcontrol,
					    struct snd_ctl_elem_value *
					    ucontrol)
{}


/*
 * Returns the WordClock sample rate class for the given card.
 */
static int hdspm_get_wc_sample_rate(struct hdspm *hdspm)
{}


/*
 * Returns the TCO sample rate class for the given card.
 */
static int hdspm_get_tco_sample_rate(struct hdspm *hdspm)
{}


/*
 * Returns the SYNC_IN sample rate class for the given card.
 */
static int hdspm_get_sync_in_sample_rate(struct hdspm *hdspm)
{}

/*
 * Returns the AES sample rate class for the given card.
 */
static int hdspm_get_aes_sample_rate(struct hdspm *hdspm, int index)
{}

/*
 * Returns the sample rate class for input source <idx> for
 * 'new style' cards like the AIO and RayDAT.
 */
static int hdspm_get_s1_sample_rate(struct hdspm *hdspm, unsigned int idx)
{}

#define ENUMERATED_CTL_INFO(info, texts)


/* Helper function to query the external sample rate and return the
 * corresponding enum to be returned to userspace.
 */
static int hdspm_external_rate_to_enum(struct hdspm *hdspm)
{}


#define HDSPM_AUTOSYNC_SAMPLE_RATE(xname, xindex)


static int snd_hdspm_info_autosync_sample_rate(struct snd_kcontrol *kcontrol,
					       struct snd_ctl_elem_info *uinfo)
{}


static int snd_hdspm_get_autosync_sample_rate(struct snd_kcontrol *kcontrol,
					      struct snd_ctl_elem_value *
					      ucontrol)
{}


#define HDSPM_SYSTEM_CLOCK_MODE(xname, xindex)


/*
 * Returns the system clock mode for the given card.
 * @returns 0 - master, 1 - slave
 */
static int hdspm_system_clock_mode(struct hdspm *hdspm)
{}


/*
 * Sets the system clock mode.
 * @param mode 0 - master, 1 - slave
 */
static void hdspm_set_system_clock_mode(struct hdspm *hdspm, int mode)
{}


static int snd_hdspm_info_system_clock_mode(struct snd_kcontrol *kcontrol,
					    struct snd_ctl_elem_info *uinfo)
{}

static int snd_hdspm_get_system_clock_mode(struct snd_kcontrol *kcontrol,
					   struct snd_ctl_elem_value *ucontrol)
{}

static int snd_hdspm_put_system_clock_mode(struct snd_kcontrol *kcontrol,
					   struct snd_ctl_elem_value *ucontrol)
{}


#define HDSPM_INTERNAL_CLOCK(xname, xindex)


static int hdspm_clock_source(struct hdspm * hdspm)
{}

static int hdspm_set_clock_source(struct hdspm * hdspm, int mode)
{}

static int snd_hdspm_info_clock_source(struct snd_kcontrol *kcontrol,
				       struct snd_ctl_elem_info *uinfo)
{}

static int snd_hdspm_get_clock_source(struct snd_kcontrol *kcontrol,
				      struct snd_ctl_elem_value *ucontrol)
{}

static int snd_hdspm_put_clock_source(struct snd_kcontrol *kcontrol,
				      struct snd_ctl_elem_value *ucontrol)
{}


#define HDSPM_PREF_SYNC_REF(xname, xindex)


/*
 * Returns the current preferred sync reference setting.
 * The semantics of the return value are depending on the
 * card, please see the comments for clarification.
 */
static int hdspm_pref_sync_ref(struct hdspm * hdspm)
{}


/*
 * Set the preferred sync reference to <pref>. The semantics
 * of <pref> are depending on the card type, see the comments
 * for clarification.
 */
static int hdspm_set_pref_sync_ref(struct hdspm * hdspm, int pref)
{}


static int snd_hdspm_info_pref_sync_ref(struct snd_kcontrol *kcontrol,
					struct snd_ctl_elem_info *uinfo)
{}

static int snd_hdspm_get_pref_sync_ref(struct snd_kcontrol *kcontrol,
				       struct snd_ctl_elem_value *ucontrol)
{}

static int snd_hdspm_put_pref_sync_ref(struct snd_kcontrol *kcontrol,
				       struct snd_ctl_elem_value *ucontrol)
{}


#define HDSPM_AUTOSYNC_REF(xname, xindex)

static int hdspm_autosync_ref(struct hdspm *hdspm)
{}


static int snd_hdspm_info_autosync_ref(struct snd_kcontrol *kcontrol,
				       struct snd_ctl_elem_info *uinfo)
{}

static int snd_hdspm_get_autosync_ref(struct snd_kcontrol *kcontrol,
				      struct snd_ctl_elem_value *ucontrol)
{}



#define HDSPM_TCO_VIDEO_INPUT_FORMAT(xname)

static int snd_hdspm_info_tco_video_input_format(struct snd_kcontrol *kcontrol,
				       struct snd_ctl_elem_info *uinfo)
{}

static int snd_hdspm_get_tco_video_input_format(struct snd_kcontrol *kcontrol,
				      struct snd_ctl_elem_value *ucontrol)
{}



#define HDSPM_TCO_LTC_FRAMES(xname)

static int snd_hdspm_info_tco_ltc_frames(struct snd_kcontrol *kcontrol,
				       struct snd_ctl_elem_info *uinfo)
{}

static int hdspm_tco_ltc_frames(struct hdspm *hdspm)
{}

static int snd_hdspm_get_tco_ltc_frames(struct snd_kcontrol *kcontrol,
				      struct snd_ctl_elem_value *ucontrol)
{}

#define HDSPM_TOGGLE_SETTING(xname, xindex)

static int hdspm_toggle_setting(struct hdspm *hdspm, u32 regmask)
{}

static int hdspm_set_toggle_setting(struct hdspm *hdspm, u32 regmask, int out)
{}

#define snd_hdspm_info_toggle_setting

static int snd_hdspm_get_toggle_setting(struct snd_kcontrol *kcontrol,
			       struct snd_ctl_elem_value *ucontrol)
{}

static int snd_hdspm_put_toggle_setting(struct snd_kcontrol *kcontrol,
			       struct snd_ctl_elem_value *ucontrol)
{}

#define HDSPM_INPUT_SELECT(xname, xindex)

static int hdspm_input_select(struct hdspm * hdspm)
{}

static int hdspm_set_input_select(struct hdspm * hdspm, int out)
{}

static int snd_hdspm_info_input_select(struct snd_kcontrol *kcontrol,
				       struct snd_ctl_elem_info *uinfo)
{}

static int snd_hdspm_get_input_select(struct snd_kcontrol *kcontrol,
				      struct snd_ctl_elem_value *ucontrol)
{}

static int snd_hdspm_put_input_select(struct snd_kcontrol *kcontrol,
				      struct snd_ctl_elem_value *ucontrol)
{}


#define HDSPM_DS_WIRE(xname, xindex)

static int hdspm_ds_wire(struct hdspm * hdspm)
{}

static int hdspm_set_ds_wire(struct hdspm * hdspm, int ds)
{}

static int snd_hdspm_info_ds_wire(struct snd_kcontrol *kcontrol,
				  struct snd_ctl_elem_info *uinfo)
{}

static int snd_hdspm_get_ds_wire(struct snd_kcontrol *kcontrol,
				 struct snd_ctl_elem_value *ucontrol)
{}

static int snd_hdspm_put_ds_wire(struct snd_kcontrol *kcontrol,
				 struct snd_ctl_elem_value *ucontrol)
{}


#define HDSPM_QS_WIRE(xname, xindex)

static int hdspm_qs_wire(struct hdspm * hdspm)
{}

static int hdspm_set_qs_wire(struct hdspm * hdspm, int mode)
{}

static int snd_hdspm_info_qs_wire(struct snd_kcontrol *kcontrol,
				       struct snd_ctl_elem_info *uinfo)
{}

static int snd_hdspm_get_qs_wire(struct snd_kcontrol *kcontrol,
				      struct snd_ctl_elem_value *ucontrol)
{}

static int snd_hdspm_put_qs_wire(struct snd_kcontrol *kcontrol,
				      struct snd_ctl_elem_value *ucontrol)
{}

#define HDSPM_CONTROL_TRISTATE(xname, xindex)

static int hdspm_tristate(struct hdspm *hdspm, u32 regmask)
{}

static int hdspm_set_tristate(struct hdspm *hdspm, int mode, u32 regmask)
{}

static int snd_hdspm_info_tristate(struct snd_kcontrol *kcontrol,
				       struct snd_ctl_elem_info *uinfo)
{}

static int snd_hdspm_get_tristate(struct snd_kcontrol *kcontrol,
				      struct snd_ctl_elem_value *ucontrol)
{}

static int snd_hdspm_put_tristate(struct snd_kcontrol *kcontrol,
				      struct snd_ctl_elem_value *ucontrol)
{}

#define HDSPM_MADI_SPEEDMODE(xname, xindex)

static int hdspm_madi_speedmode(struct hdspm *hdspm)
{}

static int hdspm_set_madi_speedmode(struct hdspm *hdspm, int mode)
{}

static int snd_hdspm_info_madi_speedmode(struct snd_kcontrol *kcontrol,
				       struct snd_ctl_elem_info *uinfo)
{}

static int snd_hdspm_get_madi_speedmode(struct snd_kcontrol *kcontrol,
				      struct snd_ctl_elem_value *ucontrol)
{}

static int snd_hdspm_put_madi_speedmode(struct snd_kcontrol *kcontrol,
				      struct snd_ctl_elem_value *ucontrol)
{}

#define HDSPM_MIXER(xname, xindex)

static int snd_hdspm_info_mixer(struct snd_kcontrol *kcontrol,
				struct snd_ctl_elem_info *uinfo)
{}

static int snd_hdspm_get_mixer(struct snd_kcontrol *kcontrol,
			       struct snd_ctl_elem_value *ucontrol)
{}

static int snd_hdspm_put_mixer(struct snd_kcontrol *kcontrol,
			       struct snd_ctl_elem_value *ucontrol)
{}

/* The simple mixer control(s) provide gain control for the
   basic 1:1 mappings of playback streams to output
   streams.
*/

#define HDSPM_PLAYBACK_MIXER

static int snd_hdspm_info_playback_mixer(struct snd_kcontrol *kcontrol,
					 struct snd_ctl_elem_info *uinfo)
{}

static int snd_hdspm_get_playback_mixer(struct snd_kcontrol *kcontrol,
					struct snd_ctl_elem_value *ucontrol)
{}

static int snd_hdspm_put_playback_mixer(struct snd_kcontrol *kcontrol,
					struct snd_ctl_elem_value *ucontrol)
{}

#define HDSPM_SYNC_CHECK(xname, xindex)

#define HDSPM_TCO_LOCK_CHECK(xname, xindex)



static int snd_hdspm_info_sync_check(struct snd_kcontrol *kcontrol,
				     struct snd_ctl_elem_info *uinfo)
{}

static int snd_hdspm_tco_info_lock_check(struct snd_kcontrol *kcontrol,
				     struct snd_ctl_elem_info *uinfo)
{}

static int hdspm_wc_sync_check(struct hdspm *hdspm)
{}


static int hdspm_madi_sync_check(struct hdspm *hdspm)
{}


static int hdspm_s1_sync_check(struct hdspm *hdspm, int idx)
{}


static int hdspm_sync_in_sync_check(struct hdspm *hdspm)
{}

static int hdspm_aes_sync_check(struct hdspm *hdspm, int idx)
{}

static int hdspm_tco_input_check(struct hdspm *hdspm, u32 mask)
{}


static int hdspm_tco_sync_check(struct hdspm *hdspm)
{}


static int snd_hdspm_get_sync_check(struct snd_kcontrol *kcontrol,
				    struct snd_ctl_elem_value *ucontrol)
{}



/*
 * TCO controls
 */
static void hdspm_tco_write(struct hdspm *hdspm)
{}


#define HDSPM_TCO_SAMPLE_RATE(xname, xindex)

static int snd_hdspm_info_tco_sample_rate(struct snd_kcontrol *kcontrol,
					  struct snd_ctl_elem_info *uinfo)
{}

static int snd_hdspm_get_tco_sample_rate(struct snd_kcontrol *kcontrol,
				      struct snd_ctl_elem_value *ucontrol)
{}

static int snd_hdspm_put_tco_sample_rate(struct snd_kcontrol *kcontrol,
					 struct snd_ctl_elem_value *ucontrol)
{}


#define HDSPM_TCO_PULL(xname, xindex)

static int snd_hdspm_info_tco_pull(struct snd_kcontrol *kcontrol,
				   struct snd_ctl_elem_info *uinfo)
{}

static int snd_hdspm_get_tco_pull(struct snd_kcontrol *kcontrol,
				  struct snd_ctl_elem_value *ucontrol)
{}

static int snd_hdspm_put_tco_pull(struct snd_kcontrol *kcontrol,
				  struct snd_ctl_elem_value *ucontrol)
{}

#define HDSPM_TCO_WCK_CONVERSION(xname, xindex)

static int snd_hdspm_info_tco_wck_conversion(struct snd_kcontrol *kcontrol,
					     struct snd_ctl_elem_info *uinfo)
{}

static int snd_hdspm_get_tco_wck_conversion(struct snd_kcontrol *kcontrol,
					    struct snd_ctl_elem_value *ucontrol)
{}

static int snd_hdspm_put_tco_wck_conversion(struct snd_kcontrol *kcontrol,
					    struct snd_ctl_elem_value *ucontrol)
{}


#define HDSPM_TCO_FRAME_RATE(xname, xindex)

static int snd_hdspm_info_tco_frame_rate(struct snd_kcontrol *kcontrol,
					  struct snd_ctl_elem_info *uinfo)
{}

static int snd_hdspm_get_tco_frame_rate(struct snd_kcontrol *kcontrol,
					struct snd_ctl_elem_value *ucontrol)
{}

static int snd_hdspm_put_tco_frame_rate(struct snd_kcontrol *kcontrol,
					struct snd_ctl_elem_value *ucontrol)
{}


#define HDSPM_TCO_SYNC_SOURCE(xname, xindex)

static int snd_hdspm_info_tco_sync_source(struct snd_kcontrol *kcontrol,
					  struct snd_ctl_elem_info *uinfo)
{}

static int snd_hdspm_get_tco_sync_source(struct snd_kcontrol *kcontrol,
					 struct snd_ctl_elem_value *ucontrol)
{}

static int snd_hdspm_put_tco_sync_source(struct snd_kcontrol *kcontrol,
					 struct snd_ctl_elem_value *ucontrol)
{}


#define HDSPM_TCO_WORD_TERM(xname, xindex)

static int snd_hdspm_info_tco_word_term(struct snd_kcontrol *kcontrol,
					struct snd_ctl_elem_info *uinfo)
{}


static int snd_hdspm_get_tco_word_term(struct snd_kcontrol *kcontrol,
				       struct snd_ctl_elem_value *ucontrol)
{}


static int snd_hdspm_put_tco_word_term(struct snd_kcontrol *kcontrol,
				       struct snd_ctl_elem_value *ucontrol)
{}




static const struct snd_kcontrol_new snd_hdspm_controls_madi[] =;


static const struct snd_kcontrol_new snd_hdspm_controls_madiface[] =;

static const struct snd_kcontrol_new snd_hdspm_controls_aio[] =;

static const struct snd_kcontrol_new snd_hdspm_controls_raydat[] =;

static const struct snd_kcontrol_new snd_hdspm_controls_aes32[] =;



/* Control elements for the optional TCO module */
static const struct snd_kcontrol_new snd_hdspm_controls_tco[] =;


static struct snd_kcontrol_new snd_hdspm_playback_mixer =;


static int hdspm_update_simple_mixer_controls(struct hdspm * hdspm)
{}


static int snd_hdspm_create_controls(struct snd_card *card,
					struct hdspm *hdspm)
{}

/*------------------------------------------------------------
   /proc interface
 ------------------------------------------------------------*/

static void
snd_hdspm_proc_read_tco(struct snd_info_entry *entry,
					struct snd_info_buffer *buffer)
{}

static void
snd_hdspm_proc_read_madi(struct snd_info_entry *entry,
			 struct snd_info_buffer *buffer)
{}

static void
snd_hdspm_proc_read_aes32(struct snd_info_entry * entry,
			  struct snd_info_buffer *buffer)
{}

static void
snd_hdspm_proc_read_raydat(struct snd_info_entry *entry,
			 struct snd_info_buffer *buffer)
{}

#ifdef CONFIG_SND_DEBUG
static void
snd_hdspm_proc_read_debug(struct snd_info_entry *entry,
			  struct snd_info_buffer *buffer)
{}
#endif


static void snd_hdspm_proc_ports_in(struct snd_info_entry *entry,
			  struct snd_info_buffer *buffer)
{}

static void snd_hdspm_proc_ports_out(struct snd_info_entry *entry,
			  struct snd_info_buffer *buffer)
{}


static void snd_hdspm_proc_init(struct hdspm *hdspm)
{}

/*------------------------------------------------------------
   hdspm intitialize
 ------------------------------------------------------------*/

static int snd_hdspm_set_defaults(struct hdspm * hdspm)
{}


/*------------------------------------------------------------
   interrupt
 ------------------------------------------------------------*/

static irqreturn_t snd_hdspm_interrupt(int irq, void *dev_id)
{}

/*------------------------------------------------------------
   pcm interface
  ------------------------------------------------------------*/


static snd_pcm_uframes_t snd_hdspm_hw_pointer(struct snd_pcm_substream
					      *substream)
{}


static int snd_hdspm_reset(struct snd_pcm_substream *substream)
{}

static int snd_hdspm_hw_params(struct snd_pcm_substream *substream,
			       struct snd_pcm_hw_params *params)
{}

static int snd_hdspm_hw_free(struct snd_pcm_substream *substream)
{}


static int snd_hdspm_channel_info(struct snd_pcm_substream *substream,
		struct snd_pcm_channel_info *info)
{}


static int snd_hdspm_ioctl(struct snd_pcm_substream *substream,
		unsigned int cmd, void *arg)
{}

static int snd_hdspm_trigger(struct snd_pcm_substream *substream, int cmd)
{}

static int snd_hdspm_prepare(struct snd_pcm_substream *substream)
{}

static const struct snd_pcm_hardware snd_hdspm_playback_subinfo =;

static const struct snd_pcm_hardware snd_hdspm_capture_subinfo =;

static int snd_hdspm_hw_rule_in_channels_rate(struct snd_pcm_hw_params *params,
					   struct snd_pcm_hw_rule *rule)
{}

static int snd_hdspm_hw_rule_out_channels_rate(struct snd_pcm_hw_params *params,
					   struct snd_pcm_hw_rule * rule)
{}

static int snd_hdspm_hw_rule_rate_in_channels(struct snd_pcm_hw_params *params,
					   struct snd_pcm_hw_rule * rule)
{}
static int snd_hdspm_hw_rule_rate_out_channels(struct snd_pcm_hw_params *params,
					   struct snd_pcm_hw_rule *rule)
{}

static int snd_hdspm_hw_rule_in_channels(struct snd_pcm_hw_params *params,
				      struct snd_pcm_hw_rule *rule)
{}

static int snd_hdspm_hw_rule_out_channels(struct snd_pcm_hw_params *params,
				      struct snd_pcm_hw_rule *rule)
{}

static int snd_hdspm_open(struct snd_pcm_substream *substream)
{}

static int snd_hdspm_release(struct snd_pcm_substream *substream)
{}

static int snd_hdspm_hwdep_dummy_op(struct snd_hwdep *hw, struct file *file)
{}

static int snd_hdspm_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
		unsigned int cmd, unsigned long arg)
{}

static const struct snd_pcm_ops snd_hdspm_ops =;

static int snd_hdspm_create_hwdep(struct snd_card *card,
				  struct hdspm *hdspm)
{}


/*------------------------------------------------------------
   memory interface
 ------------------------------------------------------------*/
static int snd_hdspm_preallocate_memory(struct hdspm *hdspm)
{}

/* Inform the card what DMA addresses to use for the indicated channel. */
/* Each channel got 16 4K pages allocated for DMA transfers. */
static void hdspm_set_channel_dma_addr(struct hdspm *hdspm,
				       struct snd_pcm_substream *substream,
				       unsigned int reg, int channel)
{}


/* ------------- ALSA Devices ---------------------------- */
static int snd_hdspm_create_pcm(struct snd_card *card,
				struct hdspm *hdspm)
{}

static inline void snd_hdspm_initialize_midi_flush(struct hdspm * hdspm)
{}

static int snd_hdspm_create_alsa_devices(struct snd_card *card,
					 struct hdspm *hdspm)
{}

static int snd_hdspm_create(struct snd_card *card,
			    struct hdspm *hdspm)
{}


static void snd_hdspm_card_free(struct snd_card *card)
{}


static int snd_hdspm_probe(struct pci_dev *pci,
			   const struct pci_device_id *pci_id)
{}

static struct pci_driver hdspm_driver =;

module_pci_driver();