Lines Matching +full:adc +full:- +full:alt +full:- +full:channel
1 // SPDX-License-Identifier: GPL-2.0-or-later
18 #include <linux/dma-mapping.h>
37 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
61 #define SV_REG(sonic, x) ((sonic)->enh_port + SV_REG_##x)
64 #define SV_ENHANCED 0x01 /* audio mode select - enhanced mode */
68 #define SV_INTA 0x20 /* INTA driving - should be always 1 */
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 */
77 #define SV_DMAA_IRQ 0x01 /* DMA-A interrupt */
78 #define SV_DMAC_IRQ 0x04 /* DMA-C interrupt */
91 #define SV_IREG_LEFT_ADC 0x00 /* Left ADC Input Control */
92 #define SV_IREG_RIGHT_ADC 0x01 /* Right ADC Input Control */
113 #define SV_IREG_ADC_OUTPUT_CTRL 0x16 /* ADC Output Control */
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 */
128 #define SV_IREG_MPU401 0x2a /* MPU-401 UART Operation */
255 count--; in snd_sonicvibes_setdmaa()
256 outl(addr, sonic->dmaa_port + SV_DMA_ADDR0); in snd_sonicvibes_setdmaa()
257 outl(count, sonic->dmaa_port + SV_DMA_COUNT0); in snd_sonicvibes_setdmaa()
258 outb(0x18, sonic->dmaa_port + SV_DMA_MODE); in snd_sonicvibes_setdmaa()
260 dev_dbg(sonic->card->dev, "program dmaa: addr = 0x%x, paddr = 0x%x\n", in snd_sonicvibes_setdmaa()
261 addr, inl(sonic->dmaa_port + SV_DMA_ADDR0)); in snd_sonicvibes_setdmaa()
271 count--; in snd_sonicvibes_setdmac()
272 outl(addr, sonic->dmac_port + SV_DMA_ADDR0); in snd_sonicvibes_setdmac()
273 outl(count, sonic->dmac_port + SV_DMA_COUNT0); in snd_sonicvibes_setdmac()
274 outb(0x14, sonic->dmac_port + SV_DMA_MODE); in snd_sonicvibes_setdmac()
276 dev_dbg(sonic->card->dev, "program dmac: addr = 0x%x, paddr = 0x%x\n", in snd_sonicvibes_setdmac()
277 addr, inl(sonic->dmac_port + SV_DMA_ADDR0)); in snd_sonicvibes_setdmac()
283 return (inl(sonic->dmaa_port + SV_DMA_COUNT0) & 0xffffff) + 1; in snd_sonicvibes_getdmaa()
289 return ((inl(sonic->dmac_port + SV_DMA_COUNT0) & 0xffffff) + 1) << 1; in snd_sonicvibes_getdmac()
308 spin_lock_irqsave(&sonic->reg_lock, flags); in snd_sonicvibes_out()
313 spin_unlock_irqrestore(&sonic->reg_lock, flags); in snd_sonicvibes_out()
332 spin_lock_irqsave(&sonic->reg_lock, flags); in snd_sonicvibes_in()
337 spin_unlock_irqrestore(&sonic->reg_lock, flags); in snd_sonicvibes_in()
344 dev_dbg(sonic->card->dev,
347 dev_dbg(sonic->card->dev,
350 dev_dbg(sonic->card->dev,
353 dev_dbg(sonic->card->dev,
354 " 0x02: left AUX1 = 0x%02x 0x22: ADC clock = 0x%02x\n",
356 dev_dbg(sonic->card->dev,
357 " 0x03: right AUX1 = 0x%02x 0x23: ADC alt rate = 0x%02x\n",
359 dev_dbg(sonic->card->dev,
360 " 0x04: left CD = 0x%02x 0x24: ADC pll M = 0x%02x\n",
362 dev_dbg(sonic->card->dev,
363 " 0x05: right CD = 0x%02x 0x25: ADC pll N = 0x%02x\n",
365 dev_dbg(sonic->card->dev,
368 dev_dbg(sonic->card->dev,
371 dev_dbg(sonic->card->dev,
372 " 0x08: MIC = 0x%02x 0x28: --- = 0x%02x\n",
374 dev_dbg(sonic->card->dev,
375 " 0x09: Game port = 0x%02x 0x29: --- = 0x%02x\n",
377 dev_dbg(sonic->card->dev,
380 dev_dbg(sonic->card->dev,
383 dev_dbg(sonic->card->dev,
386 dev_dbg(sonic->card->dev,
389 dev_dbg(sonic->card->dev,
392 dev_dbg(sonic->card->dev,
393 " 0x0f: right analog = 0x%02x 0x2f: --- = 0x%02x\n",
395 dev_dbg(sonic->card->dev,
398 dev_dbg(sonic->card->dev,
401 dev_dbg(sonic->card->dev,
402 " 0x12: DMA data format = 0x%02x 0x32: --- = 0x%02x\n",
404 dev_dbg(sonic->card->dev,
405 " 0x13: P/C enable = 0x%02x 0x33: --- = 0x%02x\n",
407 dev_dbg(sonic->card->dev,
408 " 0x14: U/D button = 0x%02x 0x34: --- = 0x%02x\n",
410 dev_dbg(sonic->card->dev,
411 " 0x15: revision = 0x%02x 0x35: --- = 0x%02x\n",
413 dev_dbg(sonic->card->dev,
414 " 0x16: ADC output ctrl = 0x%02x 0x36: --- = 0x%02x\n",
416 dev_dbg(sonic->card->dev,
417 " 0x17: --- = 0x%02x 0x37: --- = 0x%02x\n",
419 dev_dbg(sonic->card->dev,
420 " 0x18: DMA A upper cnt = 0x%02x 0x38: --- = 0x%02x\n",
422 dev_dbg(sonic->card->dev,
423 " 0x19: DMA A lower cnt = 0x%02x 0x39: --- = 0x%02x\n",
425 dev_dbg(sonic->card->dev,
426 " 0x1a: --- = 0x%02x 0x3a: --- = 0x%02x\n",
428 dev_dbg(sonic->card->dev,
429 " 0x1b: --- = 0x%02x 0x3b: --- = 0x%02x\n",
431 dev_dbg(sonic->card->dev,
432 " 0x1c: DMA C upper cnt = 0x%02x 0x3c: --- = 0x%02x\n",
434 dev_dbg(sonic->card->dev,
435 " 0x1d: DMA C upper cnt = 0x%02x 0x3d: --- = 0x%02x\n",
437 dev_dbg(sonic->card->dev,
438 " 0x1e: PCM rate low = 0x%02x 0x3e: --- = 0x%02x\n",
440 dev_dbg(sonic->card->dev,
441 " 0x1f: PCM rate high = 0x%02x 0x3f: --- = 0x%02x\n",
453 spin_lock_irqsave(&sonic->reg_lock, flags); in snd_sonicvibes_setfmt()
456 sonic->format = inb(SV_REG(sonic, DATA)); in snd_sonicvibes_setfmt()
459 sonic->format = (sonic->format & mask) | value; in snd_sonicvibes_setfmt()
460 outb(sonic->format, SV_REG(sonic, DATA)); in snd_sonicvibes_setfmt()
464 spin_unlock_irqrestore(&sonic->reg_lock, flags); in snd_sonicvibes_setfmt()
485 xd = xr - rate; in snd_sonicvibes_pll()
487 xd = rate - xr; in snd_sonicvibes_pll()
490 m = xm - 2; in snd_sonicvibes_pll()
491 n = xn - 2; in snd_sonicvibes_pll()
498 dev_dbg(sonic->card->dev, in snd_sonicvibes_pll()
500 dev_dbg(sonic->card->dev, in snd_sonicvibes_pll()
514 spin_lock_irqsave(&sonic->reg_lock, flags); in snd_sonicvibes_setpll()
517 spin_unlock_irqrestore(&sonic->reg_lock, flags); in snd_sonicvibes_setpll()
536 spin_lock_irqsave(&sonic->reg_lock, flags); in snd_sonicvibes_set_adc_rate()
537 snd_sonicvibes_out1(sonic, SV_IREG_ADC_ALT_RATE, (div - 1) << 4); in snd_sonicvibes_set_adc_rate()
539 spin_unlock_irqrestore(&sonic->reg_lock, flags); in snd_sonicvibes_set_adc_rate()
547 if (hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->min == in snd_sonicvibes_hw_constraint_dac_rate()
548 hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->max) { in snd_sonicvibes_hw_constraint_dac_rate()
549 rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->min; in snd_sonicvibes_hw_constraint_dac_rate()
554 params->rate_num = rate; in snd_sonicvibes_hw_constraint_dac_rate()
555 params->rate_den = 1; in snd_sonicvibes_hw_constraint_dac_rate()
560 params->rate_num = (SV_REFFREQUENCY/16) * (n+2) * r; in snd_sonicvibes_hw_constraint_dac_rate()
561 params->rate_den = (SV_ADCMULT/512) * (m+2); in snd_sonicvibes_hw_constraint_dac_rate()
575 spin_lock_irqsave(&sonic->reg_lock, flags); in snd_sonicvibes_set_dac_rate()
578 spin_unlock_irqrestore(&sonic->reg_lock, flags); in snd_sonicvibes_set_dac_rate()
585 spin_lock(&sonic->reg_lock); in snd_sonicvibes_trigger()
587 if (!(sonic->enable & what)) { in snd_sonicvibes_trigger()
588 sonic->enable |= what; in snd_sonicvibes_trigger()
589 snd_sonicvibes_out1(sonic, SV_IREG_PC_ENABLE, sonic->enable); in snd_sonicvibes_trigger()
592 if (sonic->enable & what) { in snd_sonicvibes_trigger()
593 sonic->enable &= ~what; in snd_sonicvibes_trigger()
594 snd_sonicvibes_out1(sonic, SV_IREG_PC_ENABLE, sonic->enable); in snd_sonicvibes_trigger()
597 result = -EINVAL; in snd_sonicvibes_trigger()
599 spin_unlock(&sonic->reg_lock); in snd_sonicvibes_trigger()
612 outb(sonic->irqmask = ~0, SV_REG(sonic, IRQMASK)); in snd_sonicvibes_interrupt()
613 dev_err(sonic->card->dev, in snd_sonicvibes_interrupt()
614 "IRQ failure - interrupts disabled!!\n"); in snd_sonicvibes_interrupt()
617 if (sonic->pcm) { in snd_sonicvibes_interrupt()
619 snd_pcm_period_elapsed(sonic->playback_substream); in snd_sonicvibes_interrupt()
621 snd_pcm_period_elapsed(sonic->capture_substream); in snd_sonicvibes_interrupt()
623 if (sonic->rmidi) { in snd_sonicvibes_interrupt()
625 snd_mpu401_uart_interrupt(irq, sonic->rmidi->private_data); in snd_sonicvibes_interrupt()
631 spin_lock(&sonic->reg_lock); in snd_sonicvibes_interrupt()
635 vol = -vol; in snd_sonicvibes_interrupt()
658 spin_unlock(&sonic->reg_lock); in snd_sonicvibes_interrupt()
659 snd_ctl_notify(sonic->card, SNDRV_CTL_EVENT_MASK_VALUE, &sonic->master_mute->id); in snd_sonicvibes_interrupt()
660 snd_ctl_notify(sonic->card, SNDRV_CTL_EVENT_MASK_VALUE, &sonic->master_volume->id); in snd_sonicvibes_interrupt()
686 struct snd_pcm_runtime *runtime = substream->runtime; in snd_sonicvibes_playback_prepare()
691 sonic->p_dma_size = size; in snd_sonicvibes_playback_prepare()
692 count--; in snd_sonicvibes_playback_prepare()
693 if (runtime->channels > 1) in snd_sonicvibes_playback_prepare()
695 if (snd_pcm_format_width(runtime->format) == 16) in snd_sonicvibes_playback_prepare()
698 snd_sonicvibes_set_dac_rate(sonic, runtime->rate); in snd_sonicvibes_playback_prepare()
699 spin_lock_irq(&sonic->reg_lock); in snd_sonicvibes_playback_prepare()
700 snd_sonicvibes_setdmaa(sonic, runtime->dma_addr, size); in snd_sonicvibes_playback_prepare()
703 spin_unlock_irq(&sonic->reg_lock); in snd_sonicvibes_playback_prepare()
710 struct snd_pcm_runtime *runtime = substream->runtime; in snd_sonicvibes_capture_prepare()
715 sonic->c_dma_size = size; in snd_sonicvibes_capture_prepare()
717 count--; in snd_sonicvibes_capture_prepare()
718 if (runtime->channels > 1) in snd_sonicvibes_capture_prepare()
720 if (snd_pcm_format_width(runtime->format) == 16) in snd_sonicvibes_capture_prepare()
723 snd_sonicvibes_set_adc_rate(sonic, runtime->rate); in snd_sonicvibes_capture_prepare()
724 spin_lock_irq(&sonic->reg_lock); in snd_sonicvibes_capture_prepare()
725 snd_sonicvibes_setdmac(sonic, runtime->dma_addr, size); in snd_sonicvibes_capture_prepare()
728 spin_unlock_irq(&sonic->reg_lock); in snd_sonicvibes_capture_prepare()
737 if (!(sonic->enable & 1)) in snd_sonicvibes_playback_pointer()
739 ptr = sonic->p_dma_size - snd_sonicvibes_getdmaa(sonic); in snd_sonicvibes_playback_pointer()
740 return bytes_to_frames(substream->runtime, ptr); in snd_sonicvibes_playback_pointer()
747 if (!(sonic->enable & 2)) in snd_sonicvibes_capture_pointer()
749 ptr = sonic->c_dma_size - snd_sonicvibes_getdmac(sonic); in snd_sonicvibes_capture_pointer()
750 return bytes_to_frames(substream->runtime, ptr); in snd_sonicvibes_capture_pointer()
794 struct snd_pcm_runtime *runtime = substream->runtime; in snd_sonicvibes_playback_open()
796 sonic->mode |= SV_MODE_PLAY; in snd_sonicvibes_playback_open()
797 sonic->playback_substream = substream; in snd_sonicvibes_playback_open()
798 runtime->hw = snd_sonicvibes_playback; in snd_sonicvibes_playback_open()
799 …SNDRV_PCM_HW_PARAM_RATE, snd_sonicvibes_hw_constraint_dac_rate, NULL, SNDRV_PCM_HW_PARAM_RATE, -1); in snd_sonicvibes_playback_open()
806 struct snd_pcm_runtime *runtime = substream->runtime; in snd_sonicvibes_capture_open()
808 sonic->mode |= SV_MODE_CAPTURE; in snd_sonicvibes_capture_open()
809 sonic->capture_substream = substream; in snd_sonicvibes_capture_open()
810 runtime->hw = snd_sonicvibes_capture; in snd_sonicvibes_capture_open()
820 sonic->playback_substream = NULL; in snd_sonicvibes_playback_close()
821 sonic->mode &= ~SV_MODE_PLAY; in snd_sonicvibes_playback_close()
829 sonic->capture_substream = NULL; in snd_sonicvibes_capture_close()
830 sonic->mode &= ~SV_MODE_CAPTURE; in snd_sonicvibes_capture_close()
855 err = snd_pcm_new(sonic->card, "s3_86c617", device, 1, 1, &pcm); in snd_sonicvibes_pcm()
859 return -EINVAL; in snd_sonicvibes_pcm()
864 pcm->private_data = sonic; in snd_sonicvibes_pcm()
865 pcm->info_flags = 0; in snd_sonicvibes_pcm()
866 strcpy(pcm->name, "S3 SonicVibes"); in snd_sonicvibes_pcm()
867 sonic->pcm = pcm; in snd_sonicvibes_pcm()
870 &sonic->pci->dev, 64*1024, 128*1024); in snd_sonicvibes_pcm()
897 spin_lock_irq(&sonic->reg_lock); in snd_sonicvibes_get_mux()
898 …ucontrol->value.enumerated.item[0] = ((snd_sonicvibes_in1(sonic, SV_IREG_LEFT_ADC) & SV_RECSRC_OUT… in snd_sonicvibes_get_mux()
899 …ucontrol->value.enumerated.item[1] = ((snd_sonicvibes_in1(sonic, SV_IREG_RIGHT_ADC) & SV_RECSRC_OU… in snd_sonicvibes_get_mux()
900 spin_unlock_irq(&sonic->reg_lock); in snd_sonicvibes_get_mux()
910 if (ucontrol->value.enumerated.item[0] >= 7 || in snd_sonicvibes_put_mux()
911 ucontrol->value.enumerated.item[1] >= 7) in snd_sonicvibes_put_mux()
912 return -EINVAL; in snd_sonicvibes_put_mux()
913 left = (ucontrol->value.enumerated.item[0] + 1) << 5; in snd_sonicvibes_put_mux()
914 right = (ucontrol->value.enumerated.item[1] + 1) << 5; in snd_sonicvibes_put_mux()
915 spin_lock_irq(&sonic->reg_lock); in snd_sonicvibes_put_mux()
923 spin_unlock_irq(&sonic->reg_lock); in snd_sonicvibes_put_mux()
935 int mask = (kcontrol->private_value >> 16) & 0xff; in snd_sonicvibes_info_single()
937 uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER; in snd_sonicvibes_info_single()
938 uinfo->count = 1; in snd_sonicvibes_info_single()
939 uinfo->value.integer.min = 0; in snd_sonicvibes_info_single()
940 uinfo->value.integer.max = mask; in snd_sonicvibes_info_single()
947 int reg = kcontrol->private_value & 0xff; in snd_sonicvibes_get_single()
948 int shift = (kcontrol->private_value >> 8) & 0xff; in snd_sonicvibes_get_single()
949 int mask = (kcontrol->private_value >> 16) & 0xff; in snd_sonicvibes_get_single()
950 int invert = (kcontrol->private_value >> 24) & 0xff; in snd_sonicvibes_get_single()
952 spin_lock_irq(&sonic->reg_lock); in snd_sonicvibes_get_single()
953 ucontrol->value.integer.value[0] = (snd_sonicvibes_in1(sonic, reg)>> shift) & mask; in snd_sonicvibes_get_single()
954 spin_unlock_irq(&sonic->reg_lock); in snd_sonicvibes_get_single()
956 ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0]; in snd_sonicvibes_get_single()
963 int reg = kcontrol->private_value & 0xff; in snd_sonicvibes_put_single()
964 int shift = (kcontrol->private_value >> 8) & 0xff; in snd_sonicvibes_put_single()
965 int mask = (kcontrol->private_value >> 16) & 0xff; in snd_sonicvibes_put_single()
966 int invert = (kcontrol->private_value >> 24) & 0xff; in snd_sonicvibes_put_single()
970 val = (ucontrol->value.integer.value[0] & mask); in snd_sonicvibes_put_single()
972 val = mask - val; in snd_sonicvibes_put_single()
974 spin_lock_irq(&sonic->reg_lock); in snd_sonicvibes_put_single()
979 spin_unlock_irq(&sonic->reg_lock); in snd_sonicvibes_put_single()
991 int mask = (kcontrol->private_value >> 24) & 0xff; in snd_sonicvibes_info_double()
993 uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER; in snd_sonicvibes_info_double()
994 uinfo->count = 2; in snd_sonicvibes_info_double()
995 uinfo->value.integer.min = 0; in snd_sonicvibes_info_double()
996 uinfo->value.integer.max = mask; in snd_sonicvibes_info_double()
1003 int left_reg = kcontrol->private_value & 0xff; in snd_sonicvibes_get_double()
1004 int right_reg = (kcontrol->private_value >> 8) & 0xff; in snd_sonicvibes_get_double()
1005 int shift_left = (kcontrol->private_value >> 16) & 0x07; in snd_sonicvibes_get_double()
1006 int shift_right = (kcontrol->private_value >> 19) & 0x07; in snd_sonicvibes_get_double()
1007 int mask = (kcontrol->private_value >> 24) & 0xff; in snd_sonicvibes_get_double()
1008 int invert = (kcontrol->private_value >> 22) & 1; in snd_sonicvibes_get_double()
1010 spin_lock_irq(&sonic->reg_lock); in snd_sonicvibes_get_double()
1011 ucontrol->value.integer.value[0] = (snd_sonicvibes_in1(sonic, left_reg) >> shift_left) & mask; in snd_sonicvibes_get_double()
1012 ucontrol->value.integer.value[1] = (snd_sonicvibes_in1(sonic, right_reg) >> shift_right) & mask; in snd_sonicvibes_get_double()
1013 spin_unlock_irq(&sonic->reg_lock); in snd_sonicvibes_get_double()
1015 ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0]; in snd_sonicvibes_get_double()
1016 ucontrol->value.integer.value[1] = mask - ucontrol->value.integer.value[1]; in snd_sonicvibes_get_double()
1024 int left_reg = kcontrol->private_value & 0xff; in snd_sonicvibes_put_double()
1025 int right_reg = (kcontrol->private_value >> 8) & 0xff; in snd_sonicvibes_put_double()
1026 int shift_left = (kcontrol->private_value >> 16) & 0x07; in snd_sonicvibes_put_double()
1027 int shift_right = (kcontrol->private_value >> 19) & 0x07; in snd_sonicvibes_put_double()
1028 int mask = (kcontrol->private_value >> 24) & 0xff; in snd_sonicvibes_put_double()
1029 int invert = (kcontrol->private_value >> 22) & 1; in snd_sonicvibes_put_double()
1033 val1 = ucontrol->value.integer.value[0] & mask; in snd_sonicvibes_put_double()
1034 val2 = ucontrol->value.integer.value[1] & mask; in snd_sonicvibes_put_double()
1036 val1 = mask - val1; in snd_sonicvibes_put_double()
1037 val2 = mask - val2; in snd_sonicvibes_put_double()
1041 spin_lock_irq(&sonic->reg_lock); in snd_sonicvibes_put_double()
1049 spin_unlock_irq(&sonic->reg_lock); in snd_sonicvibes_put_double()
1080 sonic->master_mute = NULL; in snd_sonicvibes_master_free()
1081 sonic->master_volume = NULL; in snd_sonicvibes_master_free()
1091 if (snd_BUG_ON(!sonic || !sonic->card)) in snd_sonicvibes_mixer()
1092 return -EINVAL; in snd_sonicvibes_mixer()
1093 card = sonic->card; in snd_sonicvibes_mixer()
1094 strcpy(card->mixername, "S3 SonicVibes"); in snd_sonicvibes_mixer()
1103 case 1: kctl->private_free = snd_sonicvibes_master_free; break; in snd_sonicvibes_mixer()
1116 struct sonicvibes *sonic = entry->private_data; in snd_sonicvibes_proc_read()
1119 tmp = sonic->srs_space & 0x0f; in snd_sonicvibes_proc_read()
1121 sonic->srs_space & 0x80 ? "off" : "on"); in snd_sonicvibes_proc_read()
1127 tmp = sonic->srs_center & 0x0f; in snd_sonicvibes_proc_read()
1133 tmp = sonic->wave_source & 0x03; in snd_sonicvibes_proc_read()
1135 tmp == 0x00 ? "on-board ROM" : in snd_sonicvibes_proc_read()
1136 tmp == 0x01 ? "PCI bus" : "on-board ROM + PCI bus"); in snd_sonicvibes_proc_read()
1137 tmp = sonic->mpu_switch; in snd_sonicvibes_proc_read()
1145 snd_card_ro_proc_new(sonic->card, "sonicvibes", sonic, in snd_sonicvibes_proc_init()
1162 sonic->gameport = gp = gameport_allocate_port(); in snd_sonicvibes_create_gameport()
1164 dev_err(sonic->card->dev, in snd_sonicvibes_create_gameport()
1166 return -ENOMEM; in snd_sonicvibes_create_gameport()
1170 gameport_set_phys(gp, "pci%s/gameport0", pci_name(sonic->pci)); in snd_sonicvibes_create_gameport()
1171 gameport_set_dev_parent(gp, &sonic->pci->dev); in snd_sonicvibes_create_gameport()
1172 gp->io = sonic->game_port; in snd_sonicvibes_create_gameport()
1176 err = snd_ctl_add(sonic->card, in snd_sonicvibes_create_gameport()
1186 if (sonic->gameport) { in snd_sonicvibes_free_gameport()
1187 gameport_unregister_port(sonic->gameport); in snd_sonicvibes_free_gameport()
1188 sonic->gameport = NULL; in snd_sonicvibes_free_gameport()
1192 static inline int snd_sonicvibes_create_gameport(struct sonicvibes *sonic) { return -ENOSYS; } in snd_sonicvibes_create_gameport()
1198 struct sonicvibes *sonic = card->private_data; in snd_sonicvibes_free()
1201 pci_write_config_dword(sonic->pci, 0x40, sonic->dmaa_port); in snd_sonicvibes_free()
1202 pci_write_config_dword(sonic->pci, 0x48, sonic->dmac_port); in snd_sonicvibes_free()
1210 struct sonicvibes *sonic = card->private_data; in snd_sonicvibes_create()
1219 if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(24))) { in snd_sonicvibes_create()
1220 dev_err(card->dev, in snd_sonicvibes_create()
1222 return -ENXIO; in snd_sonicvibes_create()
1225 spin_lock_init(&sonic->reg_lock); in snd_sonicvibes_create()
1226 sonic->card = card; in snd_sonicvibes_create()
1227 sonic->pci = pci; in snd_sonicvibes_create()
1228 sonic->irq = -1; in snd_sonicvibes_create()
1234 sonic->sb_port = pci_resource_start(pci, 0); in snd_sonicvibes_create()
1235 sonic->enh_port = pci_resource_start(pci, 1); in snd_sonicvibes_create()
1236 sonic->synth_port = pci_resource_start(pci, 2); in snd_sonicvibes_create()
1237 sonic->midi_port = pci_resource_start(pci, 3); in snd_sonicvibes_create()
1238 sonic->game_port = pci_resource_start(pci, 4); in snd_sonicvibes_create()
1240 if (devm_request_irq(&pci->dev, pci->irq, snd_sonicvibes_interrupt, in snd_sonicvibes_create()
1242 dev_err(card->dev, "unable to grab IRQ %d\n", pci->irq); in snd_sonicvibes_create()
1243 return -EBUSY; in snd_sonicvibes_create()
1245 sonic->irq = pci->irq; in snd_sonicvibes_create()
1246 card->sync_irq = sonic->irq; in snd_sonicvibes_create()
1247 card->private_free = snd_sonicvibes_free; in snd_sonicvibes_create()
1257 dev_info(card->dev, in snd_sonicvibes_create()
1258 "BIOS did not allocate DDMA channel A i/o, allocated at 0x%x\n", in snd_sonicvibes_create()
1264 dev_info(card->dev, in snd_sonicvibes_create()
1265 "BIOS did not allocate DDMA channel C i/o, allocated at 0x%x\n", in snd_sonicvibes_create()
1271 sonic->res_dmaa = devm_request_region(&pci->dev, dmaa, 0x10, in snd_sonicvibes_create()
1272 "S3 SonicVibes DDMA-A"); in snd_sonicvibes_create()
1273 if (!sonic->res_dmaa) { in snd_sonicvibes_create()
1274 dev_err(card->dev, in snd_sonicvibes_create()
1275 "unable to grab DDMA-A port at 0x%x-0x%x\n", in snd_sonicvibes_create()
1276 dmaa, dmaa + 0x10 - 1); in snd_sonicvibes_create()
1277 return -EBUSY; in snd_sonicvibes_create()
1279 sonic->res_dmac = devm_request_region(&pci->dev, dmac, 0x10, in snd_sonicvibes_create()
1280 "S3 SonicVibes DDMA-C"); in snd_sonicvibes_create()
1281 if (!sonic->res_dmac) { in snd_sonicvibes_create()
1282 dev_err(card->dev, in snd_sonicvibes_create()
1283 "unable to grab DDMA-C port at 0x%x-0x%x\n", in snd_sonicvibes_create()
1284 dmac, dmac + 0x10 - 1); in snd_sonicvibes_create()
1285 return -EBUSY; in snd_sonicvibes_create()
1288 pci_read_config_dword(pci, 0x40, &sonic->dmaa_port); in snd_sonicvibes_create()
1289 pci_read_config_dword(pci, 0x48, &sonic->dmac_port); in snd_sonicvibes_create()
1290 sonic->dmaa_port &= ~0x0f; in snd_sonicvibes_create()
1291 sonic->dmac_port &= ~0x0f; in snd_sonicvibes_create()
1292 pci_write_config_dword(pci, 0x40, sonic->dmaa_port | 9); /* enable + enhanced */ in snd_sonicvibes_create()
1293 pci_write_config_dword(pci, 0x48, sonic->dmac_port | 9); /* enable */ in snd_sonicvibes_create()
1306 snd_sonicvibes_out(sonic, SV_IREG_PC_ENABLE, sonic->enable = 0); /* disable playback & capture */ in snd_sonicvibes_create()
1307 outb(sonic->irqmask = ~(SV_DMAA_MASK | SV_DMAC_MASK | SV_UD_MASK), SV_REG(sonic, IRQMASK)); in snd_sonicvibes_create()
1313 snd_sonicvibes_out(sonic, SV_IREG_SRS_SPACE, sonic->srs_space = 0x80); /* SRS space off */ in snd_sonicvibes_create()
1314 snd_sonicvibes_out(sonic, SV_IREG_SRS_CENTER, sonic->srs_center = 0x00);/* SRS center off */ in snd_sonicvibes_create()
1315 snd_sonicvibes_out(sonic, SV_IREG_MPU401, sonic->mpu_switch = 0x05); /* MPU-401 switch */ in snd_sonicvibes_create()
1316 snd_sonicvibes_out(sonic, SV_IREG_WAVE_SOURCE, sonic->wave_source = 0x00); /* onboard ROM */ in snd_sonicvibes_create()
1340 sonic->revision = snd_sonicvibes_in(sonic, SV_IREG_REVISION); in snd_sonicvibes_create()
1360 struct sonicvibes *sonic = mpu->private_data; in snd_sonicvibes_midi_input_open()
1361 outb(sonic->irqmask &= ~SV_MIDI_MASK, SV_REG(sonic, IRQMASK)); in snd_sonicvibes_midi_input_open()
1367 struct sonicvibes *sonic = mpu->private_data; in snd_sonicvibes_midi_input_close()
1368 outb(sonic->irqmask |= SV_MIDI_MASK, SV_REG(sonic, IRQMASK)); in snd_sonicvibes_midi_input_close()
1374 struct snd_mpu401 * mpu = rmidi->private_data; in snd_sonicvibes_midi()
1375 struct snd_card *card = sonic->card; in snd_sonicvibes_midi()
1379 mpu->private_data = sonic; in snd_sonicvibes_midi()
1380 mpu->open_input = snd_sonicvibes_midi_input_open; in snd_sonicvibes_midi()
1381 mpu->close_input = snd_sonicvibes_midi_input_close; in snd_sonicvibes_midi()
1401 return -ENODEV; in __snd_sonic_probe()
1404 return -ENOENT; in __snd_sonic_probe()
1407 err = snd_devm_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE, in __snd_sonic_probe()
1411 sonic = card->private_data; in __snd_sonic_probe()
1418 strcpy(card->driver, "SonicVibes"); in __snd_sonic_probe()
1419 strcpy(card->shortname, "S3 SonicVibes"); in __snd_sonic_probe()
1420 sprintf(card->longname, "%s rev %i at 0x%llx, irq %i", in __snd_sonic_probe()
1421 card->shortname, in __snd_sonic_probe()
1422 sonic->revision, in __snd_sonic_probe()
1424 sonic->irq); in __snd_sonic_probe()
1433 sonic->midi_port, in __snd_sonic_probe()
1436 -1, &midi_uart); in __snd_sonic_probe()
1440 err = snd_opl3_create(card, sonic->synth_port, in __snd_sonic_probe()
1441 sonic->synth_port + 2, in __snd_sonic_probe()
1465 return snd_card_free_on_error(&pci->dev, __snd_sonic_probe(pci, pci_id)); in snd_sonic_probe()