Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[ALSA] Add HDSP MADI driver

HDSPM driver,PCI drivers,RME9652 driver
Added RME Hammerfall DSP MADI driver by Winfried Ritsch.
(Moved from alsa-driver tree to mainline.)

Signed-off-by: Takashi Iwai <tiwai@suse.de>

authored by

Takashi Iwai and committed by
Jaroslav Kysela
763f356c 37538928

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