📄 hdsp.c
字号:
/* * ALSA driver for RME Hammerfall DSP audio interface(s) * * Copyright (c) 2002 Paul Davis * Marcus Andersson * Thomas Charbonnel * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */#include <sound/driver.h>#include <linux/init.h>#include <linux/delay.h>#include <linux/interrupt.h>#include <linux/slab.h>#include <linux/pci.h>#include <linux/moduleparam.h>#include <sound/core.h>#include <sound/control.h>#include <sound/pcm.h>#include <sound/info.h>#include <sound/asoundef.h>#include <sound/rawmidi.h>#include <sound/hwdep.h>#include <sound/initval.h>#include <sound/hdsp.h>#include <asm/byteorder.h>#include <asm/current.h>#include <asm/io.h>static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */static int precise_ptr[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = 0 }; /* Enable precise pointer */static int line_outs_monitor[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = 0}; /* Send all inputs/playback to line outs */static int boot_devs;module_param_array(index, int, boot_devs, 0444);MODULE_PARM_DESC(index, "Index value for RME Hammerfall DSP interface.");MODULE_PARM_SYNTAX(index, SNDRV_INDEX_DESC);module_param_array(id, charp, boot_devs, 0444);MODULE_PARM_DESC(id, "ID string for RME Hammerfall DSP interface.");MODULE_PARM_SYNTAX(id, SNDRV_ID_DESC);module_param_array(enable, bool, boot_devs, 0444);MODULE_PARM_DESC(enable, "Enable/disable specific Hammerfall DSP soundcards.");MODULE_PARM_SYNTAX(enable, SNDRV_ENABLE_DESC);module_param_array(precise_ptr, bool, boot_devs, 0444);MODULE_PARM_DESC(precise_ptr, "Enable precise pointer (doesn't work reliably).");MODULE_PARM_SYNTAX(precise_ptr, SNDRV_ENABLED "," SNDRV_BOOLEAN_FALSE_DESC);module_param_array(line_outs_monitor, bool, boot_devs, 0444);MODULE_PARM_DESC(line_outs_monitor, "Send all input and playback streams to line outs by default.");MODULE_PARM_SYNTAX(line_outs_monitor, SNDRV_ENABLED "," SNDRV_BOOLEAN_FALSE_DESC);MODULE_AUTHOR("Paul Davis <paul@linuxaudiosystems.com>, Marcus Andersson, Thomas Charbonnel <thomas@undata.org>");MODULE_DESCRIPTION("RME Hammerfall DSP");MODULE_LICENSE("GPL");MODULE_CLASSES("{sound}");MODULE_DEVICES("{{RME Hammerfall-DSP}," "{RME HDSP-9652}," "{RME HDSP-9632}}");#define HDSP_MAX_CHANNELS 26#define HDSP_MAX_DS_CHANNELS 14#define HDSP_MAX_QS_CHANNELS 8#define DIGIFACE_SS_CHANNELS 26#define DIGIFACE_DS_CHANNELS 14#define MULTIFACE_SS_CHANNELS 18#define MULTIFACE_DS_CHANNELS 14#define H9652_SS_CHANNELS 26#define H9652_DS_CHANNELS 14/* This does not include possible Analog Extension Boards AEBs are detected at card initialization*/#define H9632_SS_CHANNELS 12#define H9632_DS_CHANNELS 8#define H9632_QS_CHANNELS 4/* Write registers. These are defined as byte-offsets from the iobase value. */#define HDSP_resetPointer 0#define HDSP_outputBufferAddress 32#define HDSP_inputBufferAddress 36#define HDSP_controlRegister 64#define HDSP_interruptConfirmation 96#define HDSP_outputEnable 128#define HDSP_control2Reg 256#define HDSP_midiDataOut0 352#define HDSP_midiDataOut1 356#define HDSP_fifoData 368#define HDSP_inputEnable 384/* Read registers. These are defined as byte-offsets from the iobase value */#define HDSP_statusRegister 0#define HDSP_timecode 128#define HDSP_status2Register 192#define HDSP_midiDataOut0 352#define HDSP_midiDataOut1 356#define HDSP_midiDataIn0 360#define HDSP_midiDataIn1 364#define HDSP_midiStatusOut0 384#define HDSP_midiStatusOut1 388#define HDSP_midiStatusIn0 392#define HDSP_midiStatusIn1 396#define HDSP_fifoStatus 400/* 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 HDSP_playbackPeakLevel 4096 /* 26 * 32 bit values */#define HDSP_inputPeakLevel 4224 /* 26 * 32 bit values */#define HDSP_outputPeakLevel 4352 /* (26+2) * 32 bit values */#define HDSP_playbackRmsLevel 4612 /* 26 * 64 bit values */#define HDSP_inputRmsLevel 4868 /* 26 * 64 bit values *//* This is for H9652 cards Peak values are read downward from the base Rms values are read upward There are rms values for the outputs too 26*3 values are read in ss mode 14*3 in ds mode, with no gap between values*/#define HDSP_9652_peakBase 7164 #define HDSP_9652_rmsBase 4096/* c.f. the hdsp_9632_meters_t struct */#define HDSP_9632_metersBase 4096#define HDSP_IO_EXTENT 7168/* control2 register bits */#define HDSP_TMS 0x01#define HDSP_TCK 0x02#define HDSP_TDI 0x04#define HDSP_JTAG 0x08#define HDSP_PWDN 0x10#define HDSP_PROGRAM 0x020#define HDSP_CONFIG_MODE_0 0x040#define HDSP_CONFIG_MODE_1 0x080#define HDSP_VERSION_BIT 0x100#define HDSP_BIGENDIAN_MODE 0x200#define HDSP_RD_MULTIPLE 0x400#define HDSP_9652_ENABLE_MIXER 0x800#define HDSP_TDO 0x10000000#define HDSP_S_PROGRAM (HDSP_PROGRAM|HDSP_CONFIG_MODE_0)#define HDSP_S_LOAD (HDSP_PROGRAM|HDSP_CONFIG_MODE_1)/* Control Register bits */#define HDSP_Start (1<<0) /* start engine */#define HDSP_Latency0 (1<<1) /* buffer size = 2^n where n is defined by Latency{2,1,0} */#define HDSP_Latency1 (1<<2) /* [ see above ] */#define HDSP_Latency2 (1<<3) /* [ see above ] */#define HDSP_ClockModeMaster (1<<4) /* 1=Master, 0=Slave/Autosync */#define HDSP_AudioInterruptEnable (1<<5) /* what do you think ? */#define HDSP_Frequency0 (1<<6) /* 0=44.1kHz/88.2kHz/176.4kHz 1=48kHz/96kHz/192kHz */#define HDSP_Frequency1 (1<<7) /* 0=32kHz/64kHz/128kHz */#define HDSP_DoubleSpeed (1<<8) /* 0=normal speed, 1=double speed */#define HDSP_SPDIFProfessional (1<<9) /* 0=consumer, 1=professional */#define HDSP_SPDIFEmphasis (1<<10) /* 0=none, 1=on */#define HDSP_SPDIFNonAudio (1<<11) /* 0=off, 1=on */#define HDSP_SPDIFOpticalOut (1<<12) /* 1=use 1st ADAT connector for SPDIF, 0=do not */#define HDSP_SyncRef2 (1<<13) #define HDSP_SPDIFInputSelect0 (1<<14) #define HDSP_SPDIFInputSelect1 (1<<15) #define HDSP_SyncRef0 (1<<16) #define HDSP_SyncRef1 (1<<17)#define HDSP_AnalogExtensionBoard (1<<18) /* For H9632 cards */ #define HDSP_XLRBreakoutCable (1<<20) /* For H9632 cards */#define HDSP_Midi0InterruptEnable (1<<22)#define HDSP_Midi1InterruptEnable (1<<23)#define HDSP_LineOut (1<<24)#define HDSP_ADGain0 (1<<25) /* From here : H9632 specific */#define HDSP_ADGain1 (1<<26)#define HDSP_DAGain0 (1<<27)#define HDSP_DAGain1 (1<<28)#define HDSP_PhoneGain0 (1<<29)#define HDSP_PhoneGain1 (1<<30)#define HDSP_QuadSpeed (1<<31)#define HDSP_ADGainMask (HDSP_ADGain0|HDSP_ADGain1)#define HDSP_ADGainMinus10dBV HDSP_ADGainMask#define HDSP_ADGainPlus4dBu (HDSP_ADGain0)#define HDSP_ADGainLowGain 0#define HDSP_DAGainMask (HDSP_DAGain0|HDSP_DAGain1)#define HDSP_DAGainHighGain HDSP_DAGainMask#define HDSP_DAGainPlus4dBu (HDSP_DAGain0)#define HDSP_DAGainMinus10dBV 0#define HDSP_PhoneGainMask (HDSP_PhoneGain0|HDSP_PhoneGain1)#define HDSP_PhoneGain0dB HDSP_PhoneGainMask#define HDSP_PhoneGainMinus6dB (HDSP_PhoneGain0)#define HDSP_PhoneGainMinus12dB 0#define HDSP_LatencyMask (HDSP_Latency0|HDSP_Latency1|HDSP_Latency2)#define HDSP_FrequencyMask (HDSP_Frequency0|HDSP_Frequency1|HDSP_DoubleSpeed|HDSP_QuadSpeed)#define HDSP_SPDIFInputMask (HDSP_SPDIFInputSelect0|HDSP_SPDIFInputSelect1)#define HDSP_SPDIFInputADAT1 0#define HDSP_SPDIFInputCoaxial (HDSP_SPDIFInputSelect0)#define HDSP_SPDIFInputCdrom (HDSP_SPDIFInputSelect1)#define HDSP_SPDIFInputAES (HDSP_SPDIFInputSelect0|HDSP_SPDIFInputSelect1)#define HDSP_SyncRefMask (HDSP_SyncRef0|HDSP_SyncRef1|HDSP_SyncRef2)#define HDSP_SyncRef_ADAT1 0#define HDSP_SyncRef_ADAT2 (HDSP_SyncRef0)#define HDSP_SyncRef_ADAT3 (HDSP_SyncRef1)#define HDSP_SyncRef_SPDIF (HDSP_SyncRef0|HDSP_SyncRef1)#define HDSP_SyncRef_WORD (HDSP_SyncRef2)#define HDSP_SyncRef_ADAT_SYNC (HDSP_SyncRef0|HDSP_SyncRef2)/* Sample Clock Sources */#define HDSP_CLOCK_SOURCE_AUTOSYNC 0#define HDSP_CLOCK_SOURCE_INTERNAL_32KHZ 1#define HDSP_CLOCK_SOURCE_INTERNAL_44_1KHZ 2#define HDSP_CLOCK_SOURCE_INTERNAL_48KHZ 3#define HDSP_CLOCK_SOURCE_INTERNAL_64KHZ 4#define HDSP_CLOCK_SOURCE_INTERNAL_88_2KHZ 5#define HDSP_CLOCK_SOURCE_INTERNAL_96KHZ 6#define HDSP_CLOCK_SOURCE_INTERNAL_128KHZ 7#define HDSP_CLOCK_SOURCE_INTERNAL_176_4KHZ 8#define HDSP_CLOCK_SOURCE_INTERNAL_192KHZ 9/* Preferred sync reference choices - used by "pref_sync_ref" control switch */#define HDSP_SYNC_FROM_WORD 0#define HDSP_SYNC_FROM_SPDIF 1#define HDSP_SYNC_FROM_ADAT1 2#define HDSP_SYNC_FROM_ADAT_SYNC 3#define HDSP_SYNC_FROM_ADAT2 4#define HDSP_SYNC_FROM_ADAT3 5/* SyncCheck status */#define HDSP_SYNC_CHECK_NO_LOCK 0#define HDSP_SYNC_CHECK_LOCK 1#define HDSP_SYNC_CHECK_SYNC 2/* AutoSync references - used by "autosync_ref" control switch */#define HDSP_AUTOSYNC_FROM_WORD 0#define HDSP_AUTOSYNC_FROM_ADAT_SYNC 1#define HDSP_AUTOSYNC_FROM_SPDIF 2#define HDSP_AUTOSYNC_FROM_NONE 3#define HDSP_AUTOSYNC_FROM_ADAT1 4#define HDSP_AUTOSYNC_FROM_ADAT2 5#define HDSP_AUTOSYNC_FROM_ADAT3 6/* Possible sources of S/PDIF input */#define HDSP_SPDIFIN_OPTICAL 0 /* optical (ADAT1) */#define HDSP_SPDIFIN_COAXIAL 1 /* coaxial (RCA) */#define HDSP_SPDIFIN_INTERNAL 2 /* internal (CDROM) */#define HDSP_SPDIFIN_AES 3 /* xlr for H9632 (AES)*/#define HDSP_Frequency32KHz HDSP_Frequency0#define HDSP_Frequency44_1KHz HDSP_Frequency1#define HDSP_Frequency48KHz (HDSP_Frequency1|HDSP_Frequency0)#define HDSP_Frequency64KHz (HDSP_DoubleSpeed|HDSP_Frequency0)#define HDSP_Frequency88_2KHz (HDSP_DoubleSpeed|HDSP_Frequency1)#define HDSP_Frequency96KHz (HDSP_DoubleSpeed|HDSP_Frequency1|HDSP_Frequency0)/* For H9632 cards */#define HDSP_Frequency128KHz (HDSP_QuadSpeed|HDSP_DoubleSpeed|HDSP_Frequency0)#define HDSP_Frequency176_4KHz (HDSP_QuadSpeed|HDSP_DoubleSpeed|HDSP_Frequency1)#define HDSP_Frequency192KHz (HDSP_QuadSpeed|HDSP_DoubleSpeed|HDSP_Frequency1|HDSP_Frequency0)#define hdsp_encode_latency(x) (((x)<<1) & HDSP_LatencyMask)#define hdsp_decode_latency(x) (((x) & HDSP_LatencyMask)>>1)#define hdsp_encode_spdif_in(x) (((x)&0x3)<<14)#define hdsp_decode_spdif_in(x) (((x)>>14)&0x3)/* Status Register bits */#define HDSP_audioIRQPending (1<<0)#define HDSP_Lock2 (1<<1) /* this is for Digiface and H9652 */#define HDSP_spdifFrequency3 HDSP_Lock2 /* this is for H9632 only */#define HDSP_Lock1 (1<<2)#define HDSP_Lock0 (1<<3)#define HDSP_SPDIFSync (1<<4)#define HDSP_TimecodeLock (1<<5)#define HDSP_BufferPositionMask 0x000FFC0 /* Bit 6..15 : h/w buffer pointer */#define HDSP_Sync2 (1<<16)#define HDSP_Sync1 (1<<17)#define HDSP_Sync0 (1<<18)#define HDSP_DoubleSpeedStatus (1<<19)#define HDSP_ConfigError (1<<20)#define HDSP_DllError (1<<21)#define HDSP_spdifFrequency0 (1<<22)#define HDSP_spdifFrequency1 (1<<23)#define HDSP_spdifFrequency2 (1<<24)#define HDSP_SPDIFErrorFlag (1<<25)#define HDSP_BufferID (1<<26)#define HDSP_TimecodeSync (1<<27)#define HDSP_AEBO (1<<28) /* H9632 specific Analog Extension Boards */#define HDSP_AEBI (1<<29) /* 0 = present, 1 = absent */#define HDSP_midi0IRQPending (1<<30) #define HDSP_midi1IRQPending (1<<31)#define HDSP_spdifFrequencyMask (HDSP_spdifFrequency0|HDSP_spdifFrequency1|HDSP_spdifFrequency2)#define HDSP_spdifFrequency32KHz (HDSP_spdifFrequency0)#define HDSP_spdifFrequency44_1KHz (HDSP_spdifFrequency1)#define HDSP_spdifFrequency48KHz (HDSP_spdifFrequency0|HDSP_spdifFrequency1)#define HDSP_spdifFrequency64KHz (HDSP_spdifFrequency2)#define HDSP_spdifFrequency88_2KHz (HDSP_spdifFrequency0|HDSP_spdifFrequency2)#define HDSP_spdifFrequency96KHz (HDSP_spdifFrequency2|HDSP_spdifFrequency1)/* This is for H9632 cards */#define HDSP_spdifFrequency128KHz HDSP_spdifFrequencyMask#define HDSP_spdifFrequency176_4KHz HDSP_spdifFrequency3#define HDSP_spdifFrequency192KHz (HDSP_spdifFrequency3|HDSP_spdifFrequency0)/* Status2 Register bits */#define HDSP_version0 (1<<0)#define HDSP_version1 (1<<1)#define HDSP_version2 (1<<2)#define HDSP_wc_lock (1<<3)#define HDSP_wc_sync (1<<4)#define HDSP_inp_freq0 (1<<5)#define HDSP_inp_freq1 (1<<6)#define HDSP_inp_freq2 (1<<7)#define HDSP_SelSyncRef0 (1<<8)#define HDSP_SelSyncRef1 (1<<9)#define HDSP_SelSyncRef2 (1<<10)#define HDSP_wc_valid (HDSP_wc_lock|HDSP_wc_sync)#define HDSP_systemFrequencyMask (HDSP_inp_freq0|HDSP_inp_freq1|HDSP_inp_freq2)#define HDSP_systemFrequency32 (HDSP_inp_freq0)#define HDSP_systemFrequency44_1 (HDSP_inp_freq1)#define HDSP_systemFrequency48 (HDSP_inp_freq0|HDSP_inp_freq1)#define HDSP_systemFrequency64 (HDSP_inp_freq2)#define HDSP_systemFrequency88_2 (HDSP_inp_freq0|HDSP_inp_freq2)#define HDSP_systemFrequency96 (HDSP_inp_freq1|HDSP_inp_freq2)/* FIXME : more values for 9632 cards ? */#define HDSP_SelSyncRefMask (HDSP_SelSyncRef0|HDSP_SelSyncRef1|HDSP_SelSyncRef2)#define HDSP_SelSyncRef_ADAT1 0#define HDSP_SelSyncRef_ADAT2 (HDSP_SelSyncRef0)#define HDSP_SelSyncRef_ADAT3 (HDSP_SelSyncRef1)#define HDSP_SelSyncRef_SPDIF (HDSP_SelSyncRef0|HDSP_SelSyncRef1)#define HDSP_SelSyncRef_WORD (HDSP_SelSyncRef2)#define HDSP_SelSyncRef_ADAT_SYNC (HDSP_SelSyncRef0|HDSP_SelSyncRef2)/* Card state flags */#define HDSP_InitializationComplete (1<<0)#define HDSP_FirmwareLoaded (1<<1)#define HDSP_FirmwareCached (1<<2)/* FIFO wait times, defined in terms of 1/10ths of msecs */#define HDSP_LONG_WAIT 5000#define HDSP_SHORT_WAIT 30#define UNITY_GAIN 32768#define MINUS_INFINITY_GAIN 0#ifndef PCI_VENDOR_ID_XILINX#define PCI_VENDOR_ID_XILINX 0x10ee#endif#ifndef PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP#define PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP 0x3fc5#endif/* the size of a substream (1 mono data stream) */#define HDSP_CHANNEL_BUFFER_SAMPLES (16*1024)#define HDSP_CHANNEL_BUFFER_BYTES (4*HDSP_CHANNEL_BUFFER_SAMPLES)/* the size of the area we need to allocate for DMA transfers. the size is the same regardless of the number of channels - the Multiface still uses the same memory area. Note that we allocate 1 more channel than is apparently needed because the h/w seems to write 1 byte beyond the end of the last page. Sigh.*/#define HDSP_DMA_AREA_BYTES ((HDSP_MAX_CHANNELS+1) * HDSP_CHANNEL_BUFFER_BYTES)#define HDSP_DMA_AREA_KILOBYTES (HDSP_DMA_AREA_BYTES/1024)typedef struct _hdsp hdsp_t;typedef struct _hdsp_midi hdsp_midi_t;typedef struct _hdsp_9632_meters hdsp_9632_meters_t;struct _hdsp_9632_meters { u32 input_peak[16]; u32 playback_peak[16]; u32 output_peak[16]; u32 xxx_peak[16]; u32 padding[64]; u32 input_rms_low[16]; u32 playback_rms_low[16]; u32 output_rms_low[16]; u32 xxx_rms_low[16]; u32 input_rms_high[16]; u32 playback_rms_high[16]; u32 output_rms_high[16]; u32 xxx_rms_high[16];};struct _hdsp_midi { hdsp_t *hdsp; int id; snd_rawmidi_t *rmidi; snd_rawmidi_substream_t *input; snd_rawmidi_substream_t *output; char istimer; /* timer in use */ struct timer_list timer; spinlock_t lock; int pending;};struct _hdsp { spinlock_t lock; snd_pcm_substream_t *capture_substream; snd_pcm_substream_t *playback_substream; hdsp_midi_t midi[2]; struct tasklet_struct midi_tasklet; int precise_ptr;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -