1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Driver for S3 SonicVibes soundcard 4 * Copyright (c) by Jaroslav Kysela <perex@perex.cz> 5 * 6 * BUGS: 7 * It looks like 86c617 rev 3 doesn't supports DDMA buffers above 16MB? 8 * Driver sometimes hangs... Nobody knows why at this moment... 9 */ 10 11 #include <linux/delay.h> 12 #include <linux/init.h> 13 #include <linux/interrupt.h> 14 #include <linux/pci.h> 15 #include <linux/slab.h> 16 #include <linux/gameport.h> 17 #include <linux/module.h> 18 #include <linux/dma-mapping.h> 19 #include <linux/io.h> 20 21 #include <sound/core.h> 22 #include <sound/pcm.h> 23 #include <sound/info.h> 24 #include <sound/control.h> 25 #include <sound/mpu401.h> 26 #include <sound/opl3.h> 27 #include <sound/initval.h> 28 29 MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>"); 30 MODULE_DESCRIPTION("S3 SonicVibes PCI"); 31 MODULE_LICENSE("GPL"); 32 33 #if IS_REACHABLE(CONFIG_GAMEPORT) 34 #define SUPPORT_JOYSTICK 1 35 #endif 36 37 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ 38 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ 39 static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ 40 static bool reverb[SNDRV_CARDS]; 41 static bool mge[SNDRV_CARDS]; 42 static unsigned int dmaio = 0x7a00; /* DDMA i/o address */ 43 44 module_param_array(index, int, NULL, 0444); 45 MODULE_PARM_DESC(index, "Index value for S3 SonicVibes soundcard."); 46 module_param_array(id, charp, NULL, 0444); 47 MODULE_PARM_DESC(id, "ID string for S3 SonicVibes soundcard."); 48 module_param_array(enable, bool, NULL, 0444); 49 MODULE_PARM_DESC(enable, "Enable S3 SonicVibes soundcard."); 50 module_param_array(reverb, bool, NULL, 0444); 51 MODULE_PARM_DESC(reverb, "Enable reverb (SRAM is present) for S3 SonicVibes soundcard."); 52 module_param_array(mge, bool, NULL, 0444); 53 MODULE_PARM_DESC(mge, "MIC Gain Enable for S3 SonicVibes soundcard."); 54 module_param_hw(dmaio, uint, ioport, 0444); 55 MODULE_PARM_DESC(dmaio, "DDMA i/o base address for S3 SonicVibes soundcard."); 56 57 /* 58 * Enhanced port direct registers 59 */ 60 61 #define SV_REG(sonic, x) ((sonic)->enh_port + SV_REG_##x) 62 63 #define SV_REG_CONTROL 0x00 /* R/W: CODEC/Mixer control register */ 64 #define SV_ENHANCED 0x01 /* audio mode select - enhanced mode */ 65 #define SV_TEST 0x02 /* test bit */ 66 #define SV_REVERB 0x04 /* reverb enable */ 67 #define SV_WAVETABLE 0x08 /* wavetable active / FM active if not set */ 68 #define SV_INTA 0x20 /* INTA driving - should be always 1 */ 69 #define SV_RESET 0x80 /* reset chip */ 70 #define SV_REG_IRQMASK 0x01 /* R/W: CODEC/Mixer interrupt mask register */ 71 #define SV_DMAA_MASK 0x01 /* mask DMA-A interrupt */ 72 #define SV_DMAC_MASK 0x04 /* mask DMA-C interrupt */ 73 #define SV_SPEC_MASK 0x08 /* special interrupt mask - should be always masked */ 74 #define SV_UD_MASK 0x40 /* Up/Down button interrupt mask */ 75 #define SV_MIDI_MASK 0x80 /* mask MIDI interrupt */ 76 #define SV_REG_STATUS 0x02 /* R/O: CODEC/Mixer status register */ 77 #define SV_DMAA_IRQ 0x01 /* DMA-A interrupt */ 78 #define SV_DMAC_IRQ 0x04 /* DMA-C interrupt */ 79 #define SV_SPEC_IRQ 0x08 /* special interrupt */ 80 #define SV_UD_IRQ 0x40 /* Up/Down interrupt */ 81 #define SV_MIDI_IRQ 0x80 /* MIDI interrupt */ 82 #define SV_REG_INDEX 0x04 /* R/W: CODEC/Mixer index address register */ 83 #define SV_MCE 0x40 /* mode change enable */ 84 #define SV_TRD 0x80 /* DMA transfer request disabled */ 85 #define SV_REG_DATA 0x05 /* R/W: CODEC/Mixer index data register */ 86 87 /* 88 * Enhanced port indirect registers 89 */ 90 91 #define SV_IREG_LEFT_ADC 0x00 /* Left ADC Input Control */ 92 #define SV_IREG_RIGHT_ADC 0x01 /* Right ADC Input Control */ 93 #define SV_IREG_LEFT_AUX1 0x02 /* Left AUX1 Input Control */ 94 #define SV_IREG_RIGHT_AUX1 0x03 /* Right AUX1 Input Control */ 95 #define SV_IREG_LEFT_CD 0x04 /* Left CD Input Control */ 96 #define SV_IREG_RIGHT_CD 0x05 /* Right CD Input Control */ 97 #define SV_IREG_LEFT_LINE 0x06 /* Left Line Input Control */ 98 #define SV_IREG_RIGHT_LINE 0x07 /* Right Line Input Control */ 99 #define SV_IREG_MIC 0x08 /* MIC Input Control */ 100 #define SV_IREG_GAME_PORT 0x09 /* Game Port Control */ 101 #define SV_IREG_LEFT_SYNTH 0x0a /* Left Synth Input Control */ 102 #define SV_IREG_RIGHT_SYNTH 0x0b /* Right Synth Input Control */ 103 #define SV_IREG_LEFT_AUX2 0x0c /* Left AUX2 Input Control */ 104 #define SV_IREG_RIGHT_AUX2 0x0d /* Right AUX2 Input Control */ 105 #define SV_IREG_LEFT_ANALOG 0x0e /* Left Analog Mixer Output Control */ 106 #define SV_IREG_RIGHT_ANALOG 0x0f /* Right Analog Mixer Output Control */ 107 #define SV_IREG_LEFT_PCM 0x10 /* Left PCM Input Control */ 108 #define SV_IREG_RIGHT_PCM 0x11 /* Right PCM Input Control */ 109 #define SV_IREG_DMA_DATA_FMT 0x12 /* DMA Data Format */ 110 #define SV_IREG_PC_ENABLE 0x13 /* Playback/Capture Enable Register */ 111 #define SV_IREG_UD_BUTTON 0x14 /* Up/Down Button Register */ 112 #define SV_IREG_REVISION 0x15 /* Revision */ 113 #define SV_IREG_ADC_OUTPUT_CTRL 0x16 /* ADC Output Control */ 114 #define SV_IREG_DMA_A_UPPER 0x18 /* DMA A Upper Base Count */ 115 #define SV_IREG_DMA_A_LOWER 0x19 /* DMA A Lower Base Count */ 116 #define SV_IREG_DMA_C_UPPER 0x1c /* DMA C Upper Base Count */ 117 #define SV_IREG_DMA_C_LOWER 0x1d /* DMA C Lower Base Count */ 118 #define SV_IREG_PCM_RATE_LOW 0x1e /* PCM Sampling Rate Low Byte */ 119 #define SV_IREG_PCM_RATE_HIGH 0x1f /* PCM Sampling Rate High Byte */ 120 #define SV_IREG_SYNTH_RATE_LOW 0x20 /* Synthesizer Sampling Rate Low Byte */ 121 #define SV_IREG_SYNTH_RATE_HIGH 0x21 /* Synthesizer Sampling Rate High Byte */ 122 #define SV_IREG_ADC_CLOCK 0x22 /* ADC Clock Source Selection */ 123 #define SV_IREG_ADC_ALT_RATE 0x23 /* ADC Alternative Sampling Rate Selection */ 124 #define SV_IREG_ADC_PLL_M 0x24 /* ADC PLL M Register */ 125 #define SV_IREG_ADC_PLL_N 0x25 /* ADC PLL N Register */ 126 #define SV_IREG_SYNTH_PLL_M 0x26 /* Synthesizer PLL M Register */ 127 #define SV_IREG_SYNTH_PLL_N 0x27 /* Synthesizer PLL N Register */ 128 #define SV_IREG_MPU401 0x2a /* MPU-401 UART Operation */ 129 #define SV_IREG_DRIVE_CTRL 0x2b /* Drive Control */ 130 #define SV_IREG_SRS_SPACE 0x2c /* SRS Space Control */ 131 #define SV_IREG_SRS_CENTER 0x2d /* SRS Center Control */ 132 #define SV_IREG_WAVE_SOURCE 0x2e /* Wavetable Sample Source Select */ 133 #define SV_IREG_ANALOG_POWER 0x30 /* Analog Power Down Control */ 134 #define SV_IREG_DIGITAL_POWER 0x31 /* Digital Power Down Control */ 135 136 #define SV_IREG_ADC_PLL SV_IREG_ADC_PLL_M 137 #define SV_IREG_SYNTH_PLL SV_IREG_SYNTH_PLL_M 138 139 /* 140 * DMA registers 141 */ 142 143 #define SV_DMA_ADDR0 0x00 144 #define SV_DMA_ADDR1 0x01 145 #define SV_DMA_ADDR2 0x02 146 #define SV_DMA_ADDR3 0x03 147 #define SV_DMA_COUNT0 0x04 148 #define SV_DMA_COUNT1 0x05 149 #define SV_DMA_COUNT2 0x06 150 #define SV_DMA_MODE 0x0b 151 #define SV_DMA_RESET 0x0d 152 #define SV_DMA_MASK 0x0f 153 154 /* 155 * Record sources 156 */ 157 158 #define SV_RECSRC_RESERVED (0x00<<5) 159 #define SV_RECSRC_CD (0x01<<5) 160 #define SV_RECSRC_DAC (0x02<<5) 161 #define SV_RECSRC_AUX2 (0x03<<5) 162 #define SV_RECSRC_LINE (0x04<<5) 163 #define SV_RECSRC_AUX1 (0x05<<5) 164 #define SV_RECSRC_MIC (0x06<<5) 165 #define SV_RECSRC_OUT (0x07<<5) 166 167 /* 168 * constants 169 */ 170 171 #define SV_FULLRATE 48000 172 #define SV_REFFREQUENCY 24576000 173 #define SV_ADCMULT 512 174 175 #define SV_MODE_PLAY 1 176 #define SV_MODE_CAPTURE 2 177 178 /* 179 180 */ 181 182 struct sonicvibes { 183 unsigned long dma1size; 184 unsigned long dma2size; 185 int irq; 186 187 unsigned long sb_port; 188 unsigned long enh_port; 189 unsigned long synth_port; 190 unsigned long midi_port; 191 unsigned long game_port; 192 unsigned int dmaa_port; 193 struct resource *res_dmaa; 194 unsigned int dmac_port; 195 struct resource *res_dmac; 196 197 unsigned char enable; 198 unsigned char irqmask; 199 unsigned char revision; 200 unsigned char format; 201 unsigned char srs_space; 202 unsigned char srs_center; 203 unsigned char mpu_switch; 204 unsigned char wave_source; 205 206 unsigned int mode; 207 208 struct pci_dev *pci; 209 struct snd_card *card; 210 struct snd_pcm *pcm; 211 struct snd_pcm_substream *playback_substream; 212 struct snd_pcm_substream *capture_substream; 213 struct snd_rawmidi *rmidi; 214 struct snd_hwdep *fmsynth; /* S3FM */ 215 216 spinlock_t reg_lock; 217 218 unsigned int p_dma_size; 219 unsigned int c_dma_size; 220 221 struct snd_kcontrol *master_mute; 222 struct snd_kcontrol *master_volume; 223 224 #ifdef SUPPORT_JOYSTICK 225 struct gameport *gameport; 226 #endif 227 }; 228 229 static const struct pci_device_id snd_sonic_ids[] = { 230 { PCI_VDEVICE(S3, 0xca00), 0, }, 231 { 0, } 232 }; 233 234 MODULE_DEVICE_TABLE(pci, snd_sonic_ids); 235 236 static const struct snd_ratden sonicvibes_adc_clock = { 237 .num_min = 4000 * 65536, 238 .num_max = 48000UL * 65536, 239 .num_step = 1, 240 .den = 65536, 241 }; 242 static const struct snd_pcm_hw_constraint_ratdens snd_sonicvibes_hw_constraints_adc_clock = { 243 .nrats = 1, 244 .rats = &sonicvibes_adc_clock, 245 }; 246 247 /* 248 * common I/O routines 249 */ 250 251 static inline void snd_sonicvibes_setdmaa(struct sonicvibes * sonic, 252 unsigned int addr, 253 unsigned int count) 254 { 255 count--; 256 outl(addr, sonic->dmaa_port + SV_DMA_ADDR0); 257 outl(count, sonic->dmaa_port + SV_DMA_COUNT0); 258 outb(0x18, sonic->dmaa_port + SV_DMA_MODE); 259 #if 0 260 dev_dbg(sonic->card->dev, "program dmaa: addr = 0x%x, paddr = 0x%x\n", 261 addr, inl(sonic->dmaa_port + SV_DMA_ADDR0)); 262 #endif 263 } 264 265 static inline void snd_sonicvibes_setdmac(struct sonicvibes * sonic, 266 unsigned int addr, 267 unsigned int count) 268 { 269 /* note: dmac is working in word mode!!! */ 270 count >>= 1; 271 count--; 272 outl(addr, sonic->dmac_port + SV_DMA_ADDR0); 273 outl(count, sonic->dmac_port + SV_DMA_COUNT0); 274 outb(0x14, sonic->dmac_port + SV_DMA_MODE); 275 #if 0 276 dev_dbg(sonic->card->dev, "program dmac: addr = 0x%x, paddr = 0x%x\n", 277 addr, inl(sonic->dmac_port + SV_DMA_ADDR0)); 278 #endif 279 } 280 281 static inline unsigned int snd_sonicvibes_getdmaa(struct sonicvibes * sonic) 282 { 283 return (inl(sonic->dmaa_port + SV_DMA_COUNT0) & 0xffffff) + 1; 284 } 285 286 static inline unsigned int snd_sonicvibes_getdmac(struct sonicvibes * sonic) 287 { 288 /* note: dmac is working in word mode!!! */ 289 return ((inl(sonic->dmac_port + SV_DMA_COUNT0) & 0xffffff) + 1) << 1; 290 } 291 292 static void snd_sonicvibes_out1(struct sonicvibes * sonic, 293 unsigned char reg, 294 unsigned char value) 295 { 296 outb(reg, SV_REG(sonic, INDEX)); 297 udelay(10); 298 outb(value, SV_REG(sonic, DATA)); 299 udelay(10); 300 } 301 302 static void snd_sonicvibes_out(struct sonicvibes * sonic, 303 unsigned char reg, 304 unsigned char value) 305 { 306 guard(spinlock_irqsave)(&sonic->reg_lock); 307 outb(reg, SV_REG(sonic, INDEX)); 308 udelay(10); 309 outb(value, SV_REG(sonic, DATA)); 310 udelay(10); 311 } 312 313 static unsigned char snd_sonicvibes_in1(struct sonicvibes * sonic, unsigned char reg) 314 { 315 unsigned char value; 316 317 outb(reg, SV_REG(sonic, INDEX)); 318 udelay(10); 319 value = inb(SV_REG(sonic, DATA)); 320 udelay(10); 321 return value; 322 } 323 324 static unsigned char snd_sonicvibes_in(struct sonicvibes * sonic, unsigned char reg) 325 { 326 unsigned char value; 327 328 guard(spinlock_irqsave)(&sonic->reg_lock); 329 outb(reg, SV_REG(sonic, INDEX)); 330 udelay(10); 331 value = inb(SV_REG(sonic, DATA)); 332 udelay(10); 333 return value; 334 } 335 336 #if 0 337 static void snd_sonicvibes_debug(struct sonicvibes * sonic) 338 { 339 dev_dbg(sonic->card->dev, 340 "SV REGS: INDEX = 0x%02x STATUS = 0x%02x\n", 341 inb(SV_REG(sonic, INDEX)), inb(SV_REG(sonic, STATUS))); 342 dev_dbg(sonic->card->dev, 343 " 0x00: left input = 0x%02x 0x20: synth rate low = 0x%02x\n", 344 snd_sonicvibes_in(sonic, 0x00), snd_sonicvibes_in(sonic, 0x20)); 345 dev_dbg(sonic->card->dev, 346 " 0x01: right input = 0x%02x 0x21: synth rate high = 0x%02x\n", 347 snd_sonicvibes_in(sonic, 0x01), snd_sonicvibes_in(sonic, 0x21)); 348 dev_dbg(sonic->card->dev, 349 " 0x02: left AUX1 = 0x%02x 0x22: ADC clock = 0x%02x\n", 350 snd_sonicvibes_in(sonic, 0x02), snd_sonicvibes_in(sonic, 0x22)); 351 dev_dbg(sonic->card->dev, 352 " 0x03: right AUX1 = 0x%02x 0x23: ADC alt rate = 0x%02x\n", 353 snd_sonicvibes_in(sonic, 0x03), snd_sonicvibes_in(sonic, 0x23)); 354 dev_dbg(sonic->card->dev, 355 " 0x04: left CD = 0x%02x 0x24: ADC pll M = 0x%02x\n", 356 snd_sonicvibes_in(sonic, 0x04), snd_sonicvibes_in(sonic, 0x24)); 357 dev_dbg(sonic->card->dev, 358 " 0x05: right CD = 0x%02x 0x25: ADC pll N = 0x%02x\n", 359 snd_sonicvibes_in(sonic, 0x05), snd_sonicvibes_in(sonic, 0x25)); 360 dev_dbg(sonic->card->dev, 361 " 0x06: left line = 0x%02x 0x26: Synth pll M = 0x%02x\n", 362 snd_sonicvibes_in(sonic, 0x06), snd_sonicvibes_in(sonic, 0x26)); 363 dev_dbg(sonic->card->dev, 364 " 0x07: right line = 0x%02x 0x27: Synth pll N = 0x%02x\n", 365 snd_sonicvibes_in(sonic, 0x07), snd_sonicvibes_in(sonic, 0x27)); 366 dev_dbg(sonic->card->dev, 367 " 0x08: MIC = 0x%02x 0x28: --- = 0x%02x\n", 368 snd_sonicvibes_in(sonic, 0x08), snd_sonicvibes_in(sonic, 0x28)); 369 dev_dbg(sonic->card->dev, 370 " 0x09: Game port = 0x%02x 0x29: --- = 0x%02x\n", 371 snd_sonicvibes_in(sonic, 0x09), snd_sonicvibes_in(sonic, 0x29)); 372 dev_dbg(sonic->card->dev, 373 " 0x0a: left synth = 0x%02x 0x2a: MPU401 = 0x%02x\n", 374 snd_sonicvibes_in(sonic, 0x0a), snd_sonicvibes_in(sonic, 0x2a)); 375 dev_dbg(sonic->card->dev, 376 " 0x0b: right synth = 0x%02x 0x2b: drive ctrl = 0x%02x\n", 377 snd_sonicvibes_in(sonic, 0x0b), snd_sonicvibes_in(sonic, 0x2b)); 378 dev_dbg(sonic->card->dev, 379 " 0x0c: left AUX2 = 0x%02x 0x2c: SRS space = 0x%02x\n", 380 snd_sonicvibes_in(sonic, 0x0c), snd_sonicvibes_in(sonic, 0x2c)); 381 dev_dbg(sonic->card->dev, 382 " 0x0d: right AUX2 = 0x%02x 0x2d: SRS center = 0x%02x\n", 383 snd_sonicvibes_in(sonic, 0x0d), snd_sonicvibes_in(sonic, 0x2d)); 384 dev_dbg(sonic->card->dev, 385 " 0x0e: left analog = 0x%02x 0x2e: wave source = 0x%02x\n", 386 snd_sonicvibes_in(sonic, 0x0e), snd_sonicvibes_in(sonic, 0x2e)); 387 dev_dbg(sonic->card->dev, 388 " 0x0f: right analog = 0x%02x 0x2f: --- = 0x%02x\n", 389 snd_sonicvibes_in(sonic, 0x0f), snd_sonicvibes_in(sonic, 0x2f)); 390 dev_dbg(sonic->card->dev, 391 " 0x10: left PCM = 0x%02x 0x30: analog power = 0x%02x\n", 392 snd_sonicvibes_in(sonic, 0x10), snd_sonicvibes_in(sonic, 0x30)); 393 dev_dbg(sonic->card->dev, 394 " 0x11: right PCM = 0x%02x 0x31: analog power = 0x%02x\n", 395 snd_sonicvibes_in(sonic, 0x11), snd_sonicvibes_in(sonic, 0x31)); 396 dev_dbg(sonic->card->dev, 397 " 0x12: DMA data format = 0x%02x 0x32: --- = 0x%02x\n", 398 snd_sonicvibes_in(sonic, 0x12), snd_sonicvibes_in(sonic, 0x32)); 399 dev_dbg(sonic->card->dev, 400 " 0x13: P/C enable = 0x%02x 0x33: --- = 0x%02x\n", 401 snd_sonicvibes_in(sonic, 0x13), snd_sonicvibes_in(sonic, 0x33)); 402 dev_dbg(sonic->card->dev, 403 " 0x14: U/D button = 0x%02x 0x34: --- = 0x%02x\n", 404 snd_sonicvibes_in(sonic, 0x14), snd_sonicvibes_in(sonic, 0x34)); 405 dev_dbg(sonic->card->dev, 406 " 0x15: revision = 0x%02x 0x35: --- = 0x%02x\n", 407 snd_sonicvibes_in(sonic, 0x15), snd_sonicvibes_in(sonic, 0x35)); 408 dev_dbg(sonic->card->dev, 409 " 0x16: ADC output ctrl = 0x%02x 0x36: --- = 0x%02x\n", 410 snd_sonicvibes_in(sonic, 0x16), snd_sonicvibes_in(sonic, 0x36)); 411 dev_dbg(sonic->card->dev, 412 " 0x17: --- = 0x%02x 0x37: --- = 0x%02x\n", 413 snd_sonicvibes_in(sonic, 0x17), snd_sonicvibes_in(sonic, 0x37)); 414 dev_dbg(sonic->card->dev, 415 " 0x18: DMA A upper cnt = 0x%02x 0x38: --- = 0x%02x\n", 416 snd_sonicvibes_in(sonic, 0x18), snd_sonicvibes_in(sonic, 0x38)); 417 dev_dbg(sonic->card->dev, 418 " 0x19: DMA A lower cnt = 0x%02x 0x39: --- = 0x%02x\n", 419 snd_sonicvibes_in(sonic, 0x19), snd_sonicvibes_in(sonic, 0x39)); 420 dev_dbg(sonic->card->dev, 421 " 0x1a: --- = 0x%02x 0x3a: --- = 0x%02x\n", 422 snd_sonicvibes_in(sonic, 0x1a), snd_sonicvibes_in(sonic, 0x3a)); 423 dev_dbg(sonic->card->dev, 424 " 0x1b: --- = 0x%02x 0x3b: --- = 0x%02x\n", 425 snd_sonicvibes_in(sonic, 0x1b), snd_sonicvibes_in(sonic, 0x3b)); 426 dev_dbg(sonic->card->dev, 427 " 0x1c: DMA C upper cnt = 0x%02x 0x3c: --- = 0x%02x\n", 428 snd_sonicvibes_in(sonic, 0x1c), snd_sonicvibes_in(sonic, 0x3c)); 429 dev_dbg(sonic->card->dev, 430 " 0x1d: DMA C upper cnt = 0x%02x 0x3d: --- = 0x%02x\n", 431 snd_sonicvibes_in(sonic, 0x1d), snd_sonicvibes_in(sonic, 0x3d)); 432 dev_dbg(sonic->card->dev, 433 " 0x1e: PCM rate low = 0x%02x 0x3e: --- = 0x%02x\n", 434 snd_sonicvibes_in(sonic, 0x1e), snd_sonicvibes_in(sonic, 0x3e)); 435 dev_dbg(sonic->card->dev, 436 " 0x1f: PCM rate high = 0x%02x 0x3f: --- = 0x%02x\n", 437 snd_sonicvibes_in(sonic, 0x1f), snd_sonicvibes_in(sonic, 0x3f)); 438 } 439 440 #endif 441 442 static void snd_sonicvibes_setfmt(struct sonicvibes * sonic, 443 unsigned char mask, 444 unsigned char value) 445 { 446 guard(spinlock_irqsave)(&sonic->reg_lock); 447 outb(SV_MCE | SV_IREG_DMA_DATA_FMT, SV_REG(sonic, INDEX)); 448 if (mask) { 449 sonic->format = inb(SV_REG(sonic, DATA)); 450 udelay(10); 451 } 452 sonic->format = (sonic->format & mask) | value; 453 outb(sonic->format, SV_REG(sonic, DATA)); 454 udelay(10); 455 outb(0, SV_REG(sonic, INDEX)); 456 udelay(10); 457 } 458 459 static void snd_sonicvibes_pll(unsigned int rate, 460 unsigned int *res_r, 461 unsigned int *res_m, 462 unsigned int *res_n) 463 { 464 unsigned int r, m = 0, n = 0; 465 unsigned int xm, xn, xr, xd, metric = ~0U; 466 467 if (rate < 625000 / SV_ADCMULT) 468 rate = 625000 / SV_ADCMULT; 469 if (rate > 150000000 / SV_ADCMULT) 470 rate = 150000000 / SV_ADCMULT; 471 /* slight violation of specs, needed for continuous sampling rates */ 472 for (r = 0; rate < 75000000 / SV_ADCMULT; r += 0x20, rate <<= 1); 473 for (xn = 3; xn < 33; xn++) /* 35 */ 474 for (xm = 3; xm < 257; xm++) { 475 xr = ((SV_REFFREQUENCY / SV_ADCMULT) * xm) / xn; 476 if (xr >= rate) 477 xd = xr - rate; 478 else 479 xd = rate - xr; 480 if (xd < metric) { 481 metric = xd; 482 m = xm - 2; 483 n = xn - 2; 484 } 485 } 486 *res_r = r; 487 *res_m = m; 488 *res_n = n; 489 #if 0 490 dev_dbg(sonic->card->dev, 491 "metric = %i, xm = %i, xn = %i\n", metric, xm, xn); 492 dev_dbg(sonic->card->dev, 493 "pll: m = 0x%x, r = 0x%x, n = 0x%x\n", reg, m, r, n); 494 #endif 495 } 496 497 static void snd_sonicvibes_setpll(struct sonicvibes * sonic, 498 unsigned char reg, 499 unsigned int rate) 500 { 501 unsigned int r, m, n; 502 503 snd_sonicvibes_pll(rate, &r, &m, &n); 504 if (sonic != NULL) { 505 guard(spinlock_irqsave)(&sonic->reg_lock); 506 snd_sonicvibes_out1(sonic, reg, m); 507 snd_sonicvibes_out1(sonic, reg + 1, r | n); 508 } 509 } 510 511 static void snd_sonicvibes_set_adc_rate(struct sonicvibes * sonic, unsigned int rate) 512 { 513 unsigned int div; 514 unsigned char clock; 515 516 div = 48000 / rate; 517 if (div > 8) 518 div = 8; 519 if ((48000 / div) == rate) { /* use the alternate clock */ 520 clock = 0x10; 521 } else { /* use the PLL source */ 522 clock = 0x00; 523 snd_sonicvibes_setpll(sonic, SV_IREG_ADC_PLL, rate); 524 } 525 guard(spinlock_irqsave)(&sonic->reg_lock); 526 snd_sonicvibes_out1(sonic, SV_IREG_ADC_ALT_RATE, (div - 1) << 4); 527 snd_sonicvibes_out1(sonic, SV_IREG_ADC_CLOCK, clock); 528 } 529 530 static int snd_sonicvibes_hw_constraint_dac_rate(struct snd_pcm_hw_params *params, 531 struct snd_pcm_hw_rule *rule) 532 { 533 unsigned int rate, div, r, m, n; 534 535 if (hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->min == 536 hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->max) { 537 rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->min; 538 div = 48000 / rate; 539 if (div > 8) 540 div = 8; 541 if ((48000 / div) == rate) { 542 params->rate_num = rate; 543 params->rate_den = 1; 544 } else { 545 snd_sonicvibes_pll(rate, &r, &m, &n); 546 snd_BUG_ON(SV_REFFREQUENCY % 16); 547 snd_BUG_ON(SV_ADCMULT % 512); 548 params->rate_num = (SV_REFFREQUENCY/16) * (n+2) * r; 549 params->rate_den = (SV_ADCMULT/512) * (m+2); 550 } 551 } 552 return 0; 553 } 554 555 static void snd_sonicvibes_set_dac_rate(struct sonicvibes * sonic, unsigned int rate) 556 { 557 unsigned int div; 558 559 div = DIV_ROUND_CLOSEST(rate * 65536, SV_FULLRATE); 560 if (div > 65535) 561 div = 65535; 562 guard(spinlock_irqsave)(&sonic->reg_lock); 563 snd_sonicvibes_out1(sonic, SV_IREG_PCM_RATE_HIGH, div >> 8); 564 snd_sonicvibes_out1(sonic, SV_IREG_PCM_RATE_LOW, div); 565 } 566 567 static int snd_sonicvibes_trigger(struct sonicvibes * sonic, int what, int cmd) 568 { 569 guard(spinlock)(&sonic->reg_lock); 570 if (cmd == SNDRV_PCM_TRIGGER_START) { 571 if (!(sonic->enable & what)) { 572 sonic->enable |= what; 573 snd_sonicvibes_out1(sonic, SV_IREG_PC_ENABLE, sonic->enable); 574 } 575 } else if (cmd == SNDRV_PCM_TRIGGER_STOP) { 576 if (sonic->enable & what) { 577 sonic->enable &= ~what; 578 snd_sonicvibes_out1(sonic, SV_IREG_PC_ENABLE, sonic->enable); 579 } 580 } else { 581 return -EINVAL; 582 } 583 return 0; 584 } 585 586 static irqreturn_t snd_sonicvibes_interrupt(int irq, void *dev_id) 587 { 588 struct sonicvibes *sonic = dev_id; 589 unsigned char status; 590 591 status = inb(SV_REG(sonic, STATUS)); 592 if (!(status & (SV_DMAA_IRQ | SV_DMAC_IRQ | SV_MIDI_IRQ))) 593 return IRQ_NONE; 594 if (status == 0xff) { /* failure */ 595 outb(sonic->irqmask = ~0, SV_REG(sonic, IRQMASK)); 596 dev_err(sonic->card->dev, 597 "IRQ failure - interrupts disabled!!\n"); 598 return IRQ_HANDLED; 599 } 600 if (sonic->pcm) { 601 if (status & SV_DMAA_IRQ) 602 snd_pcm_period_elapsed(sonic->playback_substream); 603 if (status & SV_DMAC_IRQ) 604 snd_pcm_period_elapsed(sonic->capture_substream); 605 } 606 if (sonic->rmidi) { 607 if (status & SV_MIDI_IRQ) 608 snd_mpu401_uart_interrupt(irq, sonic->rmidi->private_data); 609 } 610 if (status & SV_UD_IRQ) { 611 unsigned char udreg; 612 int vol, oleft, oright, mleft, mright; 613 614 scoped_guard(spinlock, &sonic->reg_lock) { 615 udreg = snd_sonicvibes_in1(sonic, SV_IREG_UD_BUTTON); 616 vol = udreg & 0x3f; 617 if (!(udreg & 0x40)) 618 vol = -vol; 619 oleft = mleft = snd_sonicvibes_in1(sonic, SV_IREG_LEFT_ANALOG); 620 oright = mright = snd_sonicvibes_in1(sonic, SV_IREG_RIGHT_ANALOG); 621 oleft &= 0x1f; 622 oright &= 0x1f; 623 oleft += vol; 624 if (oleft < 0) 625 oleft = 0; 626 if (oleft > 0x1f) 627 oleft = 0x1f; 628 oright += vol; 629 if (oright < 0) 630 oright = 0; 631 if (oright > 0x1f) 632 oright = 0x1f; 633 if (udreg & 0x80) { 634 mleft ^= 0x80; 635 mright ^= 0x80; 636 } 637 oleft |= mleft & 0x80; 638 oright |= mright & 0x80; 639 snd_sonicvibes_out1(sonic, SV_IREG_LEFT_ANALOG, oleft); 640 snd_sonicvibes_out1(sonic, SV_IREG_RIGHT_ANALOG, oright); 641 } 642 snd_ctl_notify(sonic->card, SNDRV_CTL_EVENT_MASK_VALUE, &sonic->master_mute->id); 643 snd_ctl_notify(sonic->card, SNDRV_CTL_EVENT_MASK_VALUE, &sonic->master_volume->id); 644 } 645 return IRQ_HANDLED; 646 } 647 648 /* 649 * PCM part 650 */ 651 652 static int snd_sonicvibes_playback_trigger(struct snd_pcm_substream *substream, 653 int cmd) 654 { 655 struct sonicvibes *sonic = snd_pcm_substream_chip(substream); 656 return snd_sonicvibes_trigger(sonic, 1, cmd); 657 } 658 659 static int snd_sonicvibes_capture_trigger(struct snd_pcm_substream *substream, 660 int cmd) 661 { 662 struct sonicvibes *sonic = snd_pcm_substream_chip(substream); 663 return snd_sonicvibes_trigger(sonic, 2, cmd); 664 } 665 666 static int snd_sonicvibes_playback_prepare(struct snd_pcm_substream *substream) 667 { 668 struct sonicvibes *sonic = snd_pcm_substream_chip(substream); 669 struct snd_pcm_runtime *runtime = substream->runtime; 670 unsigned char fmt = 0; 671 unsigned int size = snd_pcm_lib_buffer_bytes(substream); 672 unsigned int count = snd_pcm_lib_period_bytes(substream); 673 674 sonic->p_dma_size = size; 675 count--; 676 if (runtime->channels > 1) 677 fmt |= 1; 678 if (snd_pcm_format_width(runtime->format) == 16) 679 fmt |= 2; 680 snd_sonicvibes_setfmt(sonic, ~3, fmt); 681 snd_sonicvibes_set_dac_rate(sonic, runtime->rate); 682 guard(spinlock_irq)(&sonic->reg_lock); 683 snd_sonicvibes_setdmaa(sonic, runtime->dma_addr, size); 684 snd_sonicvibes_out1(sonic, SV_IREG_DMA_A_UPPER, count >> 8); 685 snd_sonicvibes_out1(sonic, SV_IREG_DMA_A_LOWER, count); 686 return 0; 687 } 688 689 static int snd_sonicvibes_capture_prepare(struct snd_pcm_substream *substream) 690 { 691 struct sonicvibes *sonic = snd_pcm_substream_chip(substream); 692 struct snd_pcm_runtime *runtime = substream->runtime; 693 unsigned char fmt = 0; 694 unsigned int size = snd_pcm_lib_buffer_bytes(substream); 695 unsigned int count = snd_pcm_lib_period_bytes(substream); 696 697 sonic->c_dma_size = size; 698 count >>= 1; 699 count--; 700 if (runtime->channels > 1) 701 fmt |= 0x10; 702 if (snd_pcm_format_width(runtime->format) == 16) 703 fmt |= 0x20; 704 snd_sonicvibes_setfmt(sonic, ~0x30, fmt); 705 snd_sonicvibes_set_adc_rate(sonic, runtime->rate); 706 guard(spinlock_irq)(&sonic->reg_lock); 707 snd_sonicvibes_setdmac(sonic, runtime->dma_addr, size); 708 snd_sonicvibes_out1(sonic, SV_IREG_DMA_C_UPPER, count >> 8); 709 snd_sonicvibes_out1(sonic, SV_IREG_DMA_C_LOWER, count); 710 return 0; 711 } 712 713 static snd_pcm_uframes_t snd_sonicvibes_playback_pointer(struct snd_pcm_substream *substream) 714 { 715 struct sonicvibes *sonic = snd_pcm_substream_chip(substream); 716 size_t ptr; 717 718 if (!(sonic->enable & 1)) 719 return 0; 720 ptr = sonic->p_dma_size - snd_sonicvibes_getdmaa(sonic); 721 return bytes_to_frames(substream->runtime, ptr); 722 } 723 724 static snd_pcm_uframes_t snd_sonicvibes_capture_pointer(struct snd_pcm_substream *substream) 725 { 726 struct sonicvibes *sonic = snd_pcm_substream_chip(substream); 727 size_t ptr; 728 if (!(sonic->enable & 2)) 729 return 0; 730 ptr = sonic->c_dma_size - snd_sonicvibes_getdmac(sonic); 731 return bytes_to_frames(substream->runtime, ptr); 732 } 733 734 static const struct snd_pcm_hardware snd_sonicvibes_playback = 735 { 736 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | 737 SNDRV_PCM_INFO_BLOCK_TRANSFER | 738 SNDRV_PCM_INFO_MMAP_VALID), 739 .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE, 740 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, 741 .rate_min = 4000, 742 .rate_max = 48000, 743 .channels_min = 1, 744 .channels_max = 2, 745 .buffer_bytes_max = (128*1024), 746 .period_bytes_min = 32, 747 .period_bytes_max = (128*1024), 748 .periods_min = 1, 749 .periods_max = 1024, 750 .fifo_size = 0, 751 }; 752 753 static const struct snd_pcm_hardware snd_sonicvibes_capture = 754 { 755 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | 756 SNDRV_PCM_INFO_BLOCK_TRANSFER | 757 SNDRV_PCM_INFO_MMAP_VALID), 758 .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE, 759 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, 760 .rate_min = 4000, 761 .rate_max = 48000, 762 .channels_min = 1, 763 .channels_max = 2, 764 .buffer_bytes_max = (128*1024), 765 .period_bytes_min = 32, 766 .period_bytes_max = (128*1024), 767 .periods_min = 1, 768 .periods_max = 1024, 769 .fifo_size = 0, 770 }; 771 772 static int snd_sonicvibes_playback_open(struct snd_pcm_substream *substream) 773 { 774 struct sonicvibes *sonic = snd_pcm_substream_chip(substream); 775 struct snd_pcm_runtime *runtime = substream->runtime; 776 777 sonic->mode |= SV_MODE_PLAY; 778 sonic->playback_substream = substream; 779 runtime->hw = snd_sonicvibes_playback; 780 snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, snd_sonicvibes_hw_constraint_dac_rate, NULL, SNDRV_PCM_HW_PARAM_RATE, -1); 781 return 0; 782 } 783 784 static int snd_sonicvibes_capture_open(struct snd_pcm_substream *substream) 785 { 786 struct sonicvibes *sonic = snd_pcm_substream_chip(substream); 787 struct snd_pcm_runtime *runtime = substream->runtime; 788 789 sonic->mode |= SV_MODE_CAPTURE; 790 sonic->capture_substream = substream; 791 runtime->hw = snd_sonicvibes_capture; 792 snd_pcm_hw_constraint_ratdens(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, 793 &snd_sonicvibes_hw_constraints_adc_clock); 794 return 0; 795 } 796 797 static int snd_sonicvibes_playback_close(struct snd_pcm_substream *substream) 798 { 799 struct sonicvibes *sonic = snd_pcm_substream_chip(substream); 800 801 sonic->playback_substream = NULL; 802 sonic->mode &= ~SV_MODE_PLAY; 803 return 0; 804 } 805 806 static int snd_sonicvibes_capture_close(struct snd_pcm_substream *substream) 807 { 808 struct sonicvibes *sonic = snd_pcm_substream_chip(substream); 809 810 sonic->capture_substream = NULL; 811 sonic->mode &= ~SV_MODE_CAPTURE; 812 return 0; 813 } 814 815 static const struct snd_pcm_ops snd_sonicvibes_playback_ops = { 816 .open = snd_sonicvibes_playback_open, 817 .close = snd_sonicvibes_playback_close, 818 .prepare = snd_sonicvibes_playback_prepare, 819 .trigger = snd_sonicvibes_playback_trigger, 820 .pointer = snd_sonicvibes_playback_pointer, 821 }; 822 823 static const struct snd_pcm_ops snd_sonicvibes_capture_ops = { 824 .open = snd_sonicvibes_capture_open, 825 .close = snd_sonicvibes_capture_close, 826 .prepare = snd_sonicvibes_capture_prepare, 827 .trigger = snd_sonicvibes_capture_trigger, 828 .pointer = snd_sonicvibes_capture_pointer, 829 }; 830 831 static int snd_sonicvibes_pcm(struct sonicvibes *sonic, int device) 832 { 833 struct snd_pcm *pcm; 834 int err; 835 836 err = snd_pcm_new(sonic->card, "s3_86c617", device, 1, 1, &pcm); 837 if (err < 0) 838 return err; 839 if (snd_BUG_ON(!pcm)) 840 return -EINVAL; 841 842 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_sonicvibes_playback_ops); 843 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_sonicvibes_capture_ops); 844 845 pcm->private_data = sonic; 846 pcm->info_flags = 0; 847 strscpy(pcm->name, "S3 SonicVibes"); 848 sonic->pcm = pcm; 849 850 snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV, 851 &sonic->pci->dev, 64*1024, 128*1024); 852 853 return 0; 854 } 855 856 /* 857 * Mixer part 858 */ 859 860 #define SONICVIBES_MUX(xname, xindex) \ 861 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ 862 .info = snd_sonicvibes_info_mux, \ 863 .get = snd_sonicvibes_get_mux, .put = snd_sonicvibes_put_mux } 864 865 static int snd_sonicvibes_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 866 { 867 static const char * const texts[7] = { 868 "CD", "PCM", "Aux1", "Line", "Aux0", "Mic", "Mix" 869 }; 870 871 return snd_ctl_enum_info(uinfo, 2, 7, texts); 872 } 873 874 static int snd_sonicvibes_get_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 875 { 876 struct sonicvibes *sonic = snd_kcontrol_chip(kcontrol); 877 878 guard(spinlock_irq)(&sonic->reg_lock); 879 ucontrol->value.enumerated.item[0] = ((snd_sonicvibes_in1(sonic, SV_IREG_LEFT_ADC) & SV_RECSRC_OUT) >> 5) - 1; 880 ucontrol->value.enumerated.item[1] = ((snd_sonicvibes_in1(sonic, SV_IREG_RIGHT_ADC) & SV_RECSRC_OUT) >> 5) - 1; 881 return 0; 882 } 883 884 static int snd_sonicvibes_put_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 885 { 886 struct sonicvibes *sonic = snd_kcontrol_chip(kcontrol); 887 unsigned short left, right, oval1, oval2; 888 int change; 889 890 if (ucontrol->value.enumerated.item[0] >= 7 || 891 ucontrol->value.enumerated.item[1] >= 7) 892 return -EINVAL; 893 left = (ucontrol->value.enumerated.item[0] + 1) << 5; 894 right = (ucontrol->value.enumerated.item[1] + 1) << 5; 895 guard(spinlock_irq)(&sonic->reg_lock); 896 oval1 = snd_sonicvibes_in1(sonic, SV_IREG_LEFT_ADC); 897 oval2 = snd_sonicvibes_in1(sonic, SV_IREG_RIGHT_ADC); 898 left = (oval1 & ~SV_RECSRC_OUT) | left; 899 right = (oval2 & ~SV_RECSRC_OUT) | right; 900 change = left != oval1 || right != oval2; 901 snd_sonicvibes_out1(sonic, SV_IREG_LEFT_ADC, left); 902 snd_sonicvibes_out1(sonic, SV_IREG_RIGHT_ADC, right); 903 return change; 904 } 905 906 #define SONICVIBES_SINGLE(xname, xindex, reg, shift, mask, invert) \ 907 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ 908 .info = snd_sonicvibes_info_single, \ 909 .get = snd_sonicvibes_get_single, .put = snd_sonicvibes_put_single, \ 910 .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24) } 911 912 static int snd_sonicvibes_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 913 { 914 int mask = (kcontrol->private_value >> 16) & 0xff; 915 916 uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER; 917 uinfo->count = 1; 918 uinfo->value.integer.min = 0; 919 uinfo->value.integer.max = mask; 920 return 0; 921 } 922 923 static int snd_sonicvibes_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 924 { 925 struct sonicvibes *sonic = snd_kcontrol_chip(kcontrol); 926 int reg = kcontrol->private_value & 0xff; 927 int shift = (kcontrol->private_value >> 8) & 0xff; 928 int mask = (kcontrol->private_value >> 16) & 0xff; 929 int invert = (kcontrol->private_value >> 24) & 0xff; 930 931 guard(spinlock_irq)(&sonic->reg_lock); 932 ucontrol->value.integer.value[0] = (snd_sonicvibes_in1(sonic, reg)>> shift) & mask; 933 if (invert) 934 ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0]; 935 return 0; 936 } 937 938 static int snd_sonicvibes_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 939 { 940 struct sonicvibes *sonic = snd_kcontrol_chip(kcontrol); 941 int reg = kcontrol->private_value & 0xff; 942 int shift = (kcontrol->private_value >> 8) & 0xff; 943 int mask = (kcontrol->private_value >> 16) & 0xff; 944 int invert = (kcontrol->private_value >> 24) & 0xff; 945 int change; 946 unsigned short val, oval; 947 948 val = (ucontrol->value.integer.value[0] & mask); 949 if (invert) 950 val = mask - val; 951 val <<= shift; 952 guard(spinlock_irq)(&sonic->reg_lock); 953 oval = snd_sonicvibes_in1(sonic, reg); 954 val = (oval & ~(mask << shift)) | val; 955 change = val != oval; 956 snd_sonicvibes_out1(sonic, reg, val); 957 return change; 958 } 959 960 #define SONICVIBES_DOUBLE(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert) \ 961 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ 962 .info = snd_sonicvibes_info_double, \ 963 .get = snd_sonicvibes_get_double, .put = snd_sonicvibes_put_double, \ 964 .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22) } 965 966 static int snd_sonicvibes_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 967 { 968 int mask = (kcontrol->private_value >> 24) & 0xff; 969 970 uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER; 971 uinfo->count = 2; 972 uinfo->value.integer.min = 0; 973 uinfo->value.integer.max = mask; 974 return 0; 975 } 976 977 static int snd_sonicvibes_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 978 { 979 struct sonicvibes *sonic = snd_kcontrol_chip(kcontrol); 980 int left_reg = kcontrol->private_value & 0xff; 981 int right_reg = (kcontrol->private_value >> 8) & 0xff; 982 int shift_left = (kcontrol->private_value >> 16) & 0x07; 983 int shift_right = (kcontrol->private_value >> 19) & 0x07; 984 int mask = (kcontrol->private_value >> 24) & 0xff; 985 int invert = (kcontrol->private_value >> 22) & 1; 986 987 guard(spinlock_irq)(&sonic->reg_lock); 988 ucontrol->value.integer.value[0] = (snd_sonicvibes_in1(sonic, left_reg) >> shift_left) & mask; 989 ucontrol->value.integer.value[1] = (snd_sonicvibes_in1(sonic, right_reg) >> shift_right) & mask; 990 if (invert) { 991 ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0]; 992 ucontrol->value.integer.value[1] = mask - ucontrol->value.integer.value[1]; 993 } 994 return 0; 995 } 996 997 static int snd_sonicvibes_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 998 { 999 struct sonicvibes *sonic = snd_kcontrol_chip(kcontrol); 1000 int left_reg = kcontrol->private_value & 0xff; 1001 int right_reg = (kcontrol->private_value >> 8) & 0xff; 1002 int shift_left = (kcontrol->private_value >> 16) & 0x07; 1003 int shift_right = (kcontrol->private_value >> 19) & 0x07; 1004 int mask = (kcontrol->private_value >> 24) & 0xff; 1005 int invert = (kcontrol->private_value >> 22) & 1; 1006 int change; 1007 unsigned short val1, val2, oval1, oval2; 1008 1009 val1 = ucontrol->value.integer.value[0] & mask; 1010 val2 = ucontrol->value.integer.value[1] & mask; 1011 if (invert) { 1012 val1 = mask - val1; 1013 val2 = mask - val2; 1014 } 1015 val1 <<= shift_left; 1016 val2 <<= shift_right; 1017 guard(spinlock_irq)(&sonic->reg_lock); 1018 oval1 = snd_sonicvibes_in1(sonic, left_reg); 1019 oval2 = snd_sonicvibes_in1(sonic, right_reg); 1020 val1 = (oval1 & ~(mask << shift_left)) | val1; 1021 val2 = (oval2 & ~(mask << shift_right)) | val2; 1022 change = val1 != oval1 || val2 != oval2; 1023 snd_sonicvibes_out1(sonic, left_reg, val1); 1024 snd_sonicvibes_out1(sonic, right_reg, val2); 1025 return change; 1026 } 1027 1028 static const struct snd_kcontrol_new snd_sonicvibes_controls[] = { 1029 SONICVIBES_DOUBLE("Capture Volume", 0, SV_IREG_LEFT_ADC, SV_IREG_RIGHT_ADC, 0, 0, 15, 0), 1030 SONICVIBES_DOUBLE("Aux Playback Switch", 0, SV_IREG_LEFT_AUX1, SV_IREG_RIGHT_AUX1, 7, 7, 1, 1), 1031 SONICVIBES_DOUBLE("Aux Playback Volume", 0, SV_IREG_LEFT_AUX1, SV_IREG_RIGHT_AUX1, 0, 0, 31, 1), 1032 SONICVIBES_DOUBLE("CD Playback Switch", 0, SV_IREG_LEFT_CD, SV_IREG_RIGHT_CD, 7, 7, 1, 1), 1033 SONICVIBES_DOUBLE("CD Playback Volume", 0, SV_IREG_LEFT_CD, SV_IREG_RIGHT_CD, 0, 0, 31, 1), 1034 SONICVIBES_DOUBLE("Line Playback Switch", 0, SV_IREG_LEFT_LINE, SV_IREG_RIGHT_LINE, 7, 7, 1, 1), 1035 SONICVIBES_DOUBLE("Line Playback Volume", 0, SV_IREG_LEFT_LINE, SV_IREG_RIGHT_LINE, 0, 0, 31, 1), 1036 SONICVIBES_SINGLE("Mic Playback Switch", 0, SV_IREG_MIC, 7, 1, 1), 1037 SONICVIBES_SINGLE("Mic Playback Volume", 0, SV_IREG_MIC, 0, 15, 1), 1038 SONICVIBES_SINGLE("Mic Boost", 0, SV_IREG_LEFT_ADC, 4, 1, 0), 1039 SONICVIBES_DOUBLE("Synth Playback Switch", 0, SV_IREG_LEFT_SYNTH, SV_IREG_RIGHT_SYNTH, 7, 7, 1, 1), 1040 SONICVIBES_DOUBLE("Synth Playback Volume", 0, SV_IREG_LEFT_SYNTH, SV_IREG_RIGHT_SYNTH, 0, 0, 31, 1), 1041 SONICVIBES_DOUBLE("Aux Playback Switch", 1, SV_IREG_LEFT_AUX2, SV_IREG_RIGHT_AUX2, 7, 7, 1, 1), 1042 SONICVIBES_DOUBLE("Aux Playback Volume", 1, SV_IREG_LEFT_AUX2, SV_IREG_RIGHT_AUX2, 0, 0, 31, 1), 1043 SONICVIBES_DOUBLE("Master Playback Switch", 0, SV_IREG_LEFT_ANALOG, SV_IREG_RIGHT_ANALOG, 7, 7, 1, 1), 1044 SONICVIBES_DOUBLE("Master Playback Volume", 0, SV_IREG_LEFT_ANALOG, SV_IREG_RIGHT_ANALOG, 0, 0, 31, 1), 1045 SONICVIBES_DOUBLE("PCM Playback Switch", 0, SV_IREG_LEFT_PCM, SV_IREG_RIGHT_PCM, 7, 7, 1, 1), 1046 SONICVIBES_DOUBLE("PCM Playback Volume", 0, SV_IREG_LEFT_PCM, SV_IREG_RIGHT_PCM, 0, 0, 63, 1), 1047 SONICVIBES_SINGLE("Loopback Capture Switch", 0, SV_IREG_ADC_OUTPUT_CTRL, 0, 1, 0), 1048 SONICVIBES_SINGLE("Loopback Capture Volume", 0, SV_IREG_ADC_OUTPUT_CTRL, 2, 63, 1), 1049 SONICVIBES_MUX("Capture Source", 0) 1050 }; 1051 1052 static void snd_sonicvibes_master_free(struct snd_kcontrol *kcontrol) 1053 { 1054 struct sonicvibes *sonic = snd_kcontrol_chip(kcontrol); 1055 sonic->master_mute = NULL; 1056 sonic->master_volume = NULL; 1057 } 1058 1059 static int snd_sonicvibes_mixer(struct sonicvibes *sonic) 1060 { 1061 struct snd_card *card; 1062 struct snd_kcontrol *kctl; 1063 unsigned int idx; 1064 int err; 1065 1066 if (snd_BUG_ON(!sonic || !sonic->card)) 1067 return -EINVAL; 1068 card = sonic->card; 1069 strscpy(card->mixername, "S3 SonicVibes"); 1070 1071 for (idx = 0; idx < ARRAY_SIZE(snd_sonicvibes_controls); idx++) { 1072 kctl = snd_ctl_new1(&snd_sonicvibes_controls[idx], sonic); 1073 err = snd_ctl_add(card, kctl); 1074 if (err < 0) 1075 return err; 1076 switch (idx) { 1077 case 0: 1078 case 1: kctl->private_free = snd_sonicvibes_master_free; break; 1079 } 1080 } 1081 return 0; 1082 } 1083 1084 /* 1085 1086 */ 1087 1088 static void snd_sonicvibes_proc_read(struct snd_info_entry *entry, 1089 struct snd_info_buffer *buffer) 1090 { 1091 struct sonicvibes *sonic = entry->private_data; 1092 unsigned char tmp; 1093 1094 tmp = sonic->srs_space & 0x0f; 1095 snd_iprintf(buffer, "SRS 3D : %s\n", 1096 str_off_on(sonic->srs_space & 0x80)); 1097 snd_iprintf(buffer, "SRS Space : %s\n", 1098 tmp == 0x00 ? "100%" : 1099 tmp == 0x01 ? "75%" : 1100 tmp == 0x02 ? "50%" : 1101 tmp == 0x03 ? "25%" : "0%"); 1102 tmp = sonic->srs_center & 0x0f; 1103 snd_iprintf(buffer, "SRS Center : %s\n", 1104 tmp == 0x00 ? "100%" : 1105 tmp == 0x01 ? "75%" : 1106 tmp == 0x02 ? "50%" : 1107 tmp == 0x03 ? "25%" : "0%"); 1108 tmp = sonic->wave_source & 0x03; 1109 snd_iprintf(buffer, "WaveTable Source : %s\n", 1110 tmp == 0x00 ? "on-board ROM" : 1111 tmp == 0x01 ? "PCI bus" : "on-board ROM + PCI bus"); 1112 tmp = sonic->mpu_switch; 1113 snd_iprintf(buffer, "Onboard synth : %s\n", str_on_off(tmp & 0x01)); 1114 snd_iprintf(buffer, "Ext. Rx to synth : %s\n", str_on_off(tmp & 0x02)); 1115 snd_iprintf(buffer, "MIDI to ext. Tx : %s\n", str_on_off(tmp & 0x04)); 1116 } 1117 1118 static void snd_sonicvibes_proc_init(struct sonicvibes *sonic) 1119 { 1120 snd_card_ro_proc_new(sonic->card, "sonicvibes", sonic, 1121 snd_sonicvibes_proc_read); 1122 } 1123 1124 /* 1125 1126 */ 1127 1128 #ifdef SUPPORT_JOYSTICK 1129 static const struct snd_kcontrol_new snd_sonicvibes_game_control = 1130 SONICVIBES_SINGLE("Joystick Speed", 0, SV_IREG_GAME_PORT, 1, 15, 0); 1131 1132 static int snd_sonicvibes_create_gameport(struct sonicvibes *sonic) 1133 { 1134 struct gameport *gp; 1135 int err; 1136 1137 sonic->gameport = gp = gameport_allocate_port(); 1138 if (!gp) { 1139 dev_err(sonic->card->dev, 1140 "sonicvibes: cannot allocate memory for gameport\n"); 1141 return -ENOMEM; 1142 } 1143 1144 gameport_set_name(gp, "SonicVibes Gameport"); 1145 gameport_set_phys(gp, "pci%s/gameport0", pci_name(sonic->pci)); 1146 gameport_set_dev_parent(gp, &sonic->pci->dev); 1147 gp->io = sonic->game_port; 1148 1149 gameport_register_port(gp); 1150 1151 err = snd_ctl_add(sonic->card, 1152 snd_ctl_new1(&snd_sonicvibes_game_control, sonic)); 1153 if (err < 0) 1154 return err; 1155 1156 return 0; 1157 } 1158 1159 static void snd_sonicvibes_free_gameport(struct sonicvibes *sonic) 1160 { 1161 if (sonic->gameport) { 1162 gameport_unregister_port(sonic->gameport); 1163 sonic->gameport = NULL; 1164 } 1165 } 1166 #else 1167 static inline int snd_sonicvibes_create_gameport(struct sonicvibes *sonic) { return -ENOSYS; } 1168 static inline void snd_sonicvibes_free_gameport(struct sonicvibes *sonic) { } 1169 #endif 1170 1171 static void snd_sonicvibes_free(struct snd_card *card) 1172 { 1173 struct sonicvibes *sonic = card->private_data; 1174 1175 snd_sonicvibes_free_gameport(sonic); 1176 pci_write_config_dword(sonic->pci, 0x40, sonic->dmaa_port); 1177 pci_write_config_dword(sonic->pci, 0x48, sonic->dmac_port); 1178 } 1179 1180 static int snd_sonicvibes_create(struct snd_card *card, 1181 struct pci_dev *pci, 1182 int reverb, 1183 int mge) 1184 { 1185 struct sonicvibes *sonic = card->private_data; 1186 unsigned int dmaa, dmac; 1187 int err; 1188 1189 /* enable PCI device */ 1190 err = pcim_enable_device(pci); 1191 if (err < 0) 1192 return err; 1193 /* check, if we can restrict PCI DMA transfers to 24 bits */ 1194 if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(24))) { 1195 dev_err(card->dev, 1196 "architecture does not support 24bit PCI busmaster DMA\n"); 1197 return -ENXIO; 1198 } 1199 1200 spin_lock_init(&sonic->reg_lock); 1201 sonic->card = card; 1202 sonic->pci = pci; 1203 sonic->irq = -1; 1204 1205 err = pcim_request_all_regions(pci, "S3 SonicVibes"); 1206 if (err < 0) 1207 return err; 1208 1209 sonic->sb_port = pci_resource_start(pci, 0); 1210 sonic->enh_port = pci_resource_start(pci, 1); 1211 sonic->synth_port = pci_resource_start(pci, 2); 1212 sonic->midi_port = pci_resource_start(pci, 3); 1213 sonic->game_port = pci_resource_start(pci, 4); 1214 1215 if (devm_request_irq(&pci->dev, pci->irq, snd_sonicvibes_interrupt, 1216 IRQF_SHARED, KBUILD_MODNAME, sonic)) { 1217 dev_err(card->dev, "unable to grab IRQ %d\n", pci->irq); 1218 return -EBUSY; 1219 } 1220 sonic->irq = pci->irq; 1221 card->sync_irq = sonic->irq; 1222 card->private_free = snd_sonicvibes_free; 1223 1224 pci_read_config_dword(pci, 0x40, &dmaa); 1225 pci_read_config_dword(pci, 0x48, &dmac); 1226 dmaio &= ~0x0f; 1227 dmaa &= ~0x0f; 1228 dmac &= ~0x0f; 1229 if (!dmaa) { 1230 dmaa = dmaio; 1231 dmaio += 0x10; 1232 dev_info(card->dev, 1233 "BIOS did not allocate DDMA channel A i/o, allocated at 0x%x\n", 1234 dmaa); 1235 } 1236 if (!dmac) { 1237 dmac = dmaio; 1238 dmaio += 0x10; 1239 dev_info(card->dev, 1240 "BIOS did not allocate DDMA channel C i/o, allocated at 0x%x\n", 1241 dmac); 1242 } 1243 pci_write_config_dword(pci, 0x40, dmaa); 1244 pci_write_config_dword(pci, 0x48, dmac); 1245 1246 sonic->res_dmaa = devm_request_region(&pci->dev, dmaa, 0x10, 1247 "S3 SonicVibes DDMA-A"); 1248 if (!sonic->res_dmaa) { 1249 dev_err(card->dev, 1250 "unable to grab DDMA-A port at 0x%x-0x%x\n", 1251 dmaa, dmaa + 0x10 - 1); 1252 return -EBUSY; 1253 } 1254 sonic->res_dmac = devm_request_region(&pci->dev, dmac, 0x10, 1255 "S3 SonicVibes DDMA-C"); 1256 if (!sonic->res_dmac) { 1257 dev_err(card->dev, 1258 "unable to grab DDMA-C port at 0x%x-0x%x\n", 1259 dmac, dmac + 0x10 - 1); 1260 return -EBUSY; 1261 } 1262 1263 pci_read_config_dword(pci, 0x40, &sonic->dmaa_port); 1264 pci_read_config_dword(pci, 0x48, &sonic->dmac_port); 1265 sonic->dmaa_port &= ~0x0f; 1266 sonic->dmac_port &= ~0x0f; 1267 pci_write_config_dword(pci, 0x40, sonic->dmaa_port | 9); /* enable + enhanced */ 1268 pci_write_config_dword(pci, 0x48, sonic->dmac_port | 9); /* enable */ 1269 /* ok.. initialize S3 SonicVibes chip */ 1270 outb(SV_RESET, SV_REG(sonic, CONTROL)); /* reset chip */ 1271 udelay(100); 1272 outb(0, SV_REG(sonic, CONTROL)); /* release reset */ 1273 udelay(100); 1274 outb(SV_ENHANCED | SV_INTA | (reverb ? SV_REVERB : 0), SV_REG(sonic, CONTROL)); 1275 inb(SV_REG(sonic, STATUS)); /* clear IRQs */ 1276 #if 1 1277 snd_sonicvibes_out(sonic, SV_IREG_DRIVE_CTRL, 0); /* drive current 16mA */ 1278 #else 1279 snd_sonicvibes_out(sonic, SV_IREG_DRIVE_CTRL, 0x40); /* drive current 8mA */ 1280 #endif 1281 snd_sonicvibes_out(sonic, SV_IREG_PC_ENABLE, sonic->enable = 0); /* disable playback & capture */ 1282 outb(sonic->irqmask = ~(SV_DMAA_MASK | SV_DMAC_MASK | SV_UD_MASK), SV_REG(sonic, IRQMASK)); 1283 inb(SV_REG(sonic, STATUS)); /* clear IRQs */ 1284 snd_sonicvibes_out(sonic, SV_IREG_ADC_CLOCK, 0); /* use PLL as clock source */ 1285 snd_sonicvibes_out(sonic, SV_IREG_ANALOG_POWER, 0); /* power up analog parts */ 1286 snd_sonicvibes_out(sonic, SV_IREG_DIGITAL_POWER, 0); /* power up digital parts */ 1287 snd_sonicvibes_setpll(sonic, SV_IREG_ADC_PLL, 8000); 1288 snd_sonicvibes_out(sonic, SV_IREG_SRS_SPACE, sonic->srs_space = 0x80); /* SRS space off */ 1289 snd_sonicvibes_out(sonic, SV_IREG_SRS_CENTER, sonic->srs_center = 0x00);/* SRS center off */ 1290 snd_sonicvibes_out(sonic, SV_IREG_MPU401, sonic->mpu_switch = 0x05); /* MPU-401 switch */ 1291 snd_sonicvibes_out(sonic, SV_IREG_WAVE_SOURCE, sonic->wave_source = 0x00); /* onboard ROM */ 1292 snd_sonicvibes_out(sonic, SV_IREG_PCM_RATE_LOW, (8000 * 65536 / SV_FULLRATE) & 0xff); 1293 snd_sonicvibes_out(sonic, SV_IREG_PCM_RATE_HIGH, ((8000 * 65536 / SV_FULLRATE) >> 8) & 0xff); 1294 snd_sonicvibes_out(sonic, SV_IREG_LEFT_ADC, mge ? 0xd0 : 0xc0); 1295 snd_sonicvibes_out(sonic, SV_IREG_RIGHT_ADC, 0xc0); 1296 snd_sonicvibes_out(sonic, SV_IREG_LEFT_AUX1, 0x9f); 1297 snd_sonicvibes_out(sonic, SV_IREG_RIGHT_AUX1, 0x9f); 1298 snd_sonicvibes_out(sonic, SV_IREG_LEFT_CD, 0x9f); 1299 snd_sonicvibes_out(sonic, SV_IREG_RIGHT_CD, 0x9f); 1300 snd_sonicvibes_out(sonic, SV_IREG_LEFT_LINE, 0x9f); 1301 snd_sonicvibes_out(sonic, SV_IREG_RIGHT_LINE, 0x9f); 1302 snd_sonicvibes_out(sonic, SV_IREG_MIC, 0x8f); 1303 snd_sonicvibes_out(sonic, SV_IREG_LEFT_SYNTH, 0x9f); 1304 snd_sonicvibes_out(sonic, SV_IREG_RIGHT_SYNTH, 0x9f); 1305 snd_sonicvibes_out(sonic, SV_IREG_LEFT_AUX2, 0x9f); 1306 snd_sonicvibes_out(sonic, SV_IREG_RIGHT_AUX2, 0x9f); 1307 snd_sonicvibes_out(sonic, SV_IREG_LEFT_ANALOG, 0x9f); 1308 snd_sonicvibes_out(sonic, SV_IREG_RIGHT_ANALOG, 0x9f); 1309 snd_sonicvibes_out(sonic, SV_IREG_LEFT_PCM, 0xbf); 1310 snd_sonicvibes_out(sonic, SV_IREG_RIGHT_PCM, 0xbf); 1311 snd_sonicvibes_out(sonic, SV_IREG_ADC_OUTPUT_CTRL, 0xfc); 1312 #if 0 1313 snd_sonicvibes_debug(sonic); 1314 #endif 1315 sonic->revision = snd_sonicvibes_in(sonic, SV_IREG_REVISION); 1316 1317 snd_sonicvibes_proc_init(sonic); 1318 return 0; 1319 } 1320 1321 /* 1322 * MIDI section 1323 */ 1324 1325 static const struct snd_kcontrol_new snd_sonicvibes_midi_controls[] = { 1326 SONICVIBES_SINGLE("SonicVibes Wave Source RAM", 0, SV_IREG_WAVE_SOURCE, 0, 1, 0), 1327 SONICVIBES_SINGLE("SonicVibes Wave Source RAM+ROM", 0, SV_IREG_WAVE_SOURCE, 1, 1, 0), 1328 SONICVIBES_SINGLE("SonicVibes Onboard Synth", 0, SV_IREG_MPU401, 0, 1, 0), 1329 SONICVIBES_SINGLE("SonicVibes External Rx to Synth", 0, SV_IREG_MPU401, 1, 1, 0), 1330 SONICVIBES_SINGLE("SonicVibes External Tx", 0, SV_IREG_MPU401, 2, 1, 0) 1331 }; 1332 1333 static int snd_sonicvibes_midi_input_open(struct snd_mpu401 * mpu) 1334 { 1335 struct sonicvibes *sonic = mpu->private_data; 1336 outb(sonic->irqmask &= ~SV_MIDI_MASK, SV_REG(sonic, IRQMASK)); 1337 return 0; 1338 } 1339 1340 static void snd_sonicvibes_midi_input_close(struct snd_mpu401 * mpu) 1341 { 1342 struct sonicvibes *sonic = mpu->private_data; 1343 outb(sonic->irqmask |= SV_MIDI_MASK, SV_REG(sonic, IRQMASK)); 1344 } 1345 1346 static int snd_sonicvibes_midi(struct sonicvibes *sonic, 1347 struct snd_rawmidi *rmidi) 1348 { 1349 struct snd_mpu401 * mpu = rmidi->private_data; 1350 struct snd_card *card = sonic->card; 1351 unsigned int idx; 1352 int err; 1353 1354 mpu->private_data = sonic; 1355 mpu->open_input = snd_sonicvibes_midi_input_open; 1356 mpu->close_input = snd_sonicvibes_midi_input_close; 1357 for (idx = 0; idx < ARRAY_SIZE(snd_sonicvibes_midi_controls); idx++) { 1358 err = snd_ctl_add(card, snd_ctl_new1(&snd_sonicvibes_midi_controls[idx], sonic)); 1359 if (err < 0) 1360 return err; 1361 } 1362 return 0; 1363 } 1364 1365 static int __snd_sonic_probe(struct pci_dev *pci, 1366 const struct pci_device_id *pci_id) 1367 { 1368 static int dev; 1369 struct snd_card *card; 1370 struct sonicvibes *sonic; 1371 struct snd_rawmidi *midi_uart; 1372 struct snd_opl3 *opl3; 1373 int err; 1374 1375 if (dev >= SNDRV_CARDS) 1376 return -ENODEV; 1377 if (!enable[dev]) { 1378 dev++; 1379 return -ENOENT; 1380 } 1381 1382 err = snd_devm_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE, 1383 sizeof(*sonic), &card); 1384 if (err < 0) 1385 return err; 1386 sonic = card->private_data; 1387 err = snd_sonicvibes_create(card, pci, 1388 reverb[dev] ? 1 : 0, 1389 mge[dev] ? 1 : 0); 1390 if (err < 0) 1391 return err; 1392 1393 strscpy(card->driver, "SonicVibes"); 1394 strscpy(card->shortname, "S3 SonicVibes"); 1395 sprintf(card->longname, "%s rev %i at 0x%llx, irq %i", 1396 card->shortname, 1397 sonic->revision, 1398 (unsigned long long)pci_resource_start(pci, 1), 1399 sonic->irq); 1400 1401 err = snd_sonicvibes_pcm(sonic, 0); 1402 if (err < 0) 1403 return err; 1404 err = snd_sonicvibes_mixer(sonic); 1405 if (err < 0) 1406 return err; 1407 err = snd_mpu401_uart_new(card, 0, MPU401_HW_SONICVIBES, 1408 sonic->midi_port, 1409 MPU401_INFO_INTEGRATED | 1410 MPU401_INFO_IRQ_HOOK, 1411 -1, &midi_uart); 1412 if (err < 0) 1413 return err; 1414 snd_sonicvibes_midi(sonic, midi_uart); 1415 err = snd_opl3_create(card, sonic->synth_port, 1416 sonic->synth_port + 2, 1417 OPL3_HW_OPL3_SV, 1, &opl3); 1418 if (err < 0) 1419 return err; 1420 err = snd_opl3_hwdep_new(opl3, 0, 1, NULL); 1421 if (err < 0) 1422 return err; 1423 1424 err = snd_sonicvibes_create_gameport(sonic); 1425 if (err < 0) 1426 return err; 1427 1428 err = snd_card_register(card); 1429 if (err < 0) 1430 return err; 1431 1432 pci_set_drvdata(pci, card); 1433 dev++; 1434 return 0; 1435 } 1436 1437 static int snd_sonic_probe(struct pci_dev *pci, 1438 const struct pci_device_id *pci_id) 1439 { 1440 return snd_card_free_on_error(&pci->dev, __snd_sonic_probe(pci, pci_id)); 1441 } 1442 1443 static struct pci_driver sonicvibes_driver = { 1444 .name = KBUILD_MODNAME, 1445 .id_table = snd_sonic_ids, 1446 .probe = snd_sonic_probe, 1447 }; 1448 1449 module_pci_driver(sonicvibes_driver); 1450