Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 | /* SPDX-License-Identifier: GPL-2.0-or-later */ /* */ #ifndef __SOUND_AU88X0_H #define __SOUND_AU88X0_H #include <linux/pci.h> #include <linux/io.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/rawmidi.h> #include <sound/mpu401.h> #include <sound/hwdep.h> #include <sound/ac97_codec.h> #include <sound/tlv.h> #ifndef CHIP_AU8820 #include "au88x0_eq.h" #include "au88x0_a3d.h" #endif #ifndef CHIP_AU8810 #include "au88x0_wt.h" #endif #define hwread(x,y) readl((x)+(y)) #define hwwrite(x,y,z) writel((z),(x)+(y)) /* Vortex MPU401 defines. */ #define MIDI_CLOCK_DIV 0x61 /* Standart MPU401 defines. */ #define MPU401_RESET 0xff #define MPU401_ENTER_UART 0x3f #define MPU401_ACK 0xfe // Get src register value to convert from x to y. #define SRC_RATIO(x,y) ((((x<<15)/y) + 1)/2) /* FIFO software state constants. */ #define FIFO_STOP 0 #define FIFO_START 1 #define FIFO_PAUSE 2 /* IRQ flags */ #define IRQ_ERR_MASK 0x00ff #define IRQ_FATAL 0x0001 #define IRQ_PARITY 0x0002 #define IRQ_REG 0x0004 #define IRQ_FIFO 0x0008 #define IRQ_DMA 0x0010 #define IRQ_PCMOUT 0x0020 /* PCM OUT page crossing */ #define IRQ_TIMER 0x1000 #define IRQ_MIDI 0x2000 #define IRQ_MODEM 0x4000 /* ADB Resource */ #define VORTEX_RESOURCE_DMA 0x00000000 #define VORTEX_RESOURCE_SRC 0x00000001 #define VORTEX_RESOURCE_MIXIN 0x00000002 #define VORTEX_RESOURCE_MIXOUT 0x00000003 #define VORTEX_RESOURCE_A3D 0x00000004 #define VORTEX_RESOURCE_LAST 0x00000005 /* codec io: VORTEX_CODEC_IO bits */ #define VORTEX_CODEC_ID_SHIFT 24 #define VORTEX_CODEC_WRITE 0x00800000 #define VORTEX_CODEC_ADDSHIFT 16 #define VORTEX_CODEC_ADDMASK 0x7f0000 #define VORTEX_CODEC_DATSHIFT 0 #define VORTEX_CODEC_DATMASK 0xffff /* Check for SDAC bit in "Extended audio ID" AC97 register */ //#define VORTEX_IS_QUAD(x) (((x)->codec == NULL) ? 0 : ((x)->codec->ext_id&0x80)) #define VORTEX_IS_QUAD(x) ((x)->isquad) /* Check if chip has bug. */ #define IS_BAD_CHIP(x) (\ (x->rev == 0xfe && x->device == PCI_DEVICE_ID_AUREAL_VORTEX_2) || \ (x->rev == 0xfe && x->device == PCI_DEVICE_ID_AUREAL_ADVANTAGE)) /* PCM devices */ #define VORTEX_PCM_ADB 0 #define VORTEX_PCM_SPDIF 1 #define VORTEX_PCM_A3D 2 #define VORTEX_PCM_WT 3 #define VORTEX_PCM_I2S 4 #define VORTEX_PCM_LAST 5 #define MIX_CAPT(x) (vortex->mixcapt[x]) #define MIX_PLAYB(x) (vortex->mixplayb[x]) #define MIX_SPDIF(x) (vortex->mixspdif[x]) #define NR_WTPB 0x20 /* WT channels per each bank. */ #define NR_PCM 0x10 struct pcm_vol { struct snd_kcontrol *kctl; int active; int dma; int mixin[4]; int vol[4]; }; /* Structs */ typedef struct { //int this_08; /* Still unknown */ int fifo_enabled; /* this_24 */ int fifo_status; /* this_1c */ u32 dma_ctrl; /* this_78 (ADB), this_7c (WT) */ int dma_unknown; /* this_74 (ADB), this_78 (WT). WDM: +8 */ int cfg0; int cfg1; int nr_ch; /* Nr of PCM channels in use */ int type; /* Output type (ac97, a3d, spdif, i2s, dsp) */ int dma; /* Hardware DMA index. */ int dir; /* Stream Direction. */ u32 resources[5]; /* Virtual page extender stuff */ int nr_periods; int period_bytes; int period_real; int period_virt; struct snd_pcm_substream *substream; } stream_t; typedef struct snd_vortex vortex_t; struct snd_vortex { /* ALSA structs. */ struct snd_card *card; struct snd_pcm *pcm[VORTEX_PCM_LAST]; struct snd_rawmidi *rmidi; /* Legacy Midi interface. */ struct snd_ac97 *codec; /* Stream structs. */ stream_t dma_adb[NR_ADB]; int spdif_sr; #ifndef CHIP_AU8810 stream_t dma_wt[NR_WT]; wt_voice_t wt_voice[NR_WT]; /* WT register cache. */ s8 mixwt[(NR_WT / NR_WTPB) * 6]; /* WT mixin objects */ #endif /* Global resources */ s8 mixcapt[2]; s8 mixplayb[4]; #ifndef CHIP_AU8820 s8 mixspdif[2]; s8 mixa3d[2]; /* mixers which collect all a3d streams. */ s8 mixxtlk[2]; /* crosstalk canceler mixer inputs. */ #endif u32 fixed_res[5]; #ifndef CHIP_AU8820 /* Hardware equalizer structs */ eqlzr_t eq; /* A3D structs */ a3dsrc_t a3d[NR_A3D]; /* Xtalk canceler */ int xt_mode; /* 1: speakers, 0:headphones. */ #endif struct pcm_vol pcm_vol[NR_PCM]; int isquad; /* cache of extended ID codec flag. */ /* Gameport stuff. */ struct gameport *gameport; /* PCI hardware resources */ unsigned long io; void __iomem *mmio; unsigned int irq; spinlock_t lock; /* PCI device */ struct pci_dev *pci_dev; u16 vendor; u16 device; u8 rev; }; /* Functions. */ /* SRC */ static void vortex_adb_setsrc(vortex_t * vortex, int adbdma, unsigned int cvrt, int dir); /* DMA Engines. */ static void vortex_adbdma_setbuffers(vortex_t * vortex, int adbdma, int size, int count); static void vortex_adbdma_setmode(vortex_t * vortex, int adbdma, int ie, int dir, int fmt, int d, u32 offset); static void vortex_adbdma_setstartbuffer(vortex_t * vortex, int adbdma, int sb); #ifndef CHIP_AU8810 static void vortex_wtdma_setbuffers(vortex_t * vortex, int wtdma, int size, int count); static void vortex_wtdma_setmode(vortex_t * vortex, int wtdma, int ie, int fmt, int d, /*int e, */ u32 offset); static void vortex_wtdma_setstartbuffer(vortex_t * vortex, int wtdma, int sb); #endif static void vortex_adbdma_startfifo(vortex_t * vortex, int adbdma); //static void vortex_adbdma_stopfifo(vortex_t *vortex, int adbdma); static void vortex_adbdma_pausefifo(vortex_t * vortex, int adbdma); static void vortex_adbdma_resumefifo(vortex_t * vortex, int adbdma); static inline int vortex_adbdma_getlinearpos(vortex_t * vortex, int adbdma); static void vortex_adbdma_resetup(vortex_t *vortex, int adbdma); #ifndef CHIP_AU8810 static void vortex_wtdma_startfifo(vortex_t * vortex, int wtdma); static void vortex_wtdma_stopfifo(vortex_t * vortex, int wtdma); static void vortex_wtdma_pausefifo(vortex_t * vortex, int wtdma); static void vortex_wtdma_resumefifo(vortex_t * vortex, int wtdma); static inline int vortex_wtdma_getlinearpos(vortex_t * vortex, int wtdma); #endif /* global stuff. */ static void vortex_codec_init(vortex_t * vortex); static void vortex_codec_write(struct snd_ac97 * codec, unsigned short addr, unsigned short data); static unsigned short vortex_codec_read(struct snd_ac97 * codec, unsigned short addr); static void vortex_spdif_init(vortex_t * vortex, int spdif_sr, int spdif_mode); static int vortex_core_init(vortex_t * card); static int vortex_core_shutdown(vortex_t * card); static void vortex_enable_int(vortex_t * card); static irqreturn_t vortex_interrupt(int irq, void *dev_id); static int vortex_alsafmt_aspfmt(snd_pcm_format_t alsafmt, vortex_t *v); /* Connection stuff. */ static void vortex_connect_default(vortex_t * vortex, int en); static int vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch, int dir, int type, int subdev); static int vortex_adb_checkinout(vortex_t * vortex, int resmap[], int out, int restype); #ifndef CHIP_AU8810 static int vortex_wt_allocroute(vortex_t * vortex, int dma, int nr_ch); static void vortex_wt_connect(vortex_t * vortex, int en); static void vortex_wt_init(vortex_t * vortex); #endif static void vortex_route(vortex_t * vortex, int en, unsigned char channel, unsigned char source, unsigned char dest); #if 0 static void vortex_routes(vortex_t * vortex, int en, unsigned char channel, unsigned char source, unsigned char dest0, unsigned char dest1); #endif static void vortex_connection_mixin_mix(vortex_t * vortex, int en, unsigned char mixin, unsigned char mix, int a); static void vortex_mix_setinputvolumebyte(vortex_t * vortex, unsigned char mix, int mixin, unsigned char vol); static void vortex_mix_setvolumebyte(vortex_t * vortex, unsigned char mix, unsigned char vol); /* A3D functions. */ #ifndef CHIP_AU8820 static void vortex_Vort3D_enable(vortex_t * v); static void vortex_Vort3D_disable(vortex_t * v); static void vortex_Vort3D_connect(vortex_t * vortex, int en); static void vortex_Vort3D_InitializeSource(a3dsrc_t *a, int en, vortex_t *v); #endif /* Driver stuff. */ static int vortex_gameport_register(vortex_t * card); static void vortex_gameport_unregister(vortex_t * card); #ifndef CHIP_AU8820 static int vortex_eq_init(vortex_t * vortex); static int vortex_eq_free(vortex_t * vortex); #endif /* ALSA stuff. */ static int snd_vortex_new_pcm(vortex_t * vortex, int idx, int nr); static int snd_vortex_mixer(vortex_t * vortex); static int snd_vortex_midi(vortex_t * vortex); #endif |