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>
38 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
62 #define SV_REG(sonic, x) ((sonic)->enh_port + SV_REG_##x)
65 #define SV_ENHANCED 0x01 /* audio mode select - enhanced mode */
69 #define SV_INTA 0x20 /* INTA driving - should be always 1 */
72 #define SV_DMAA_MASK 0x01 /* mask DMA-A interrupt */
73 #define SV_DMAC_MASK 0x04 /* mask DMA-C interrupt */
74 #define SV_SPEC_MASK 0x08 /* special interrupt mask - should be always masked */
78 #define SV_DMAA_IRQ 0x01 /* DMA-A interrupt */
79 #define SV_DMAC_IRQ 0x04 /* DMA-C interrupt */
92 #define SV_IREG_LEFT_ADC 0x00 /* Left ADC Input Control */
93 #define SV_IREG_RIGHT_ADC 0x01 /* Right ADC Input Control */
114 #define SV_IREG_ADC_OUTPUT_CTRL 0x16 /* ADC Output Control */
123 #define SV_IREG_ADC_CLOCK 0x22 /* ADC Clock Source Selection */
124 #define SV_IREG_ADC_ALT_RATE 0x23 /* ADC Alternative Sampling Rate Selection */
125 #define SV_IREG_ADC_PLL_M 0x24 /* ADC PLL M Register */
126 #define SV_IREG_ADC_PLL_N 0x25 /* ADC PLL N Register */
129 #define SV_IREG_MPU401 0x2a /* MPU-401 UART Operation */
256 count--; in snd_sonicvibes_setdmaa()
257 outl(addr, sonic->dmaa_port + SV_DMA_ADDR0); in snd_sonicvibes_setdmaa()
258 outl(count, sonic->dmaa_port + SV_DMA_COUNT0); in snd_sonicvibes_setdmaa()
259 outb(0x18, sonic->dmaa_port + SV_DMA_MODE); in snd_sonicvibes_setdmaa()
261 dev_dbg(sonic->card->dev, "program dmaa: addr = 0x%x, paddr = 0x%x\n", in snd_sonicvibes_setdmaa()
262 addr, inl(sonic->dmaa_port + SV_DMA_ADDR0)); in snd_sonicvibes_setdmaa()
272 count--; in snd_sonicvibes_setdmac()
273 outl(addr, sonic->dmac_port + SV_DMA_ADDR0); in snd_sonicvibes_setdmac()
274 outl(count, sonic->dmac_port + SV_DMA_COUNT0); in snd_sonicvibes_setdmac()
275 outb(0x14, sonic->dmac_port + SV_DMA_MODE); in snd_sonicvibes_setdmac()
277 dev_dbg(sonic->card->dev, "program dmac: addr = 0x%x, paddr = 0x%x\n", in snd_sonicvibes_setdmac()
278 addr, inl(sonic->dmac_port + SV_DMA_ADDR0)); in snd_sonicvibes_setdmac()
284 return (inl(sonic->dmaa_port + SV_DMA_COUNT0) & 0xffffff) + 1; in snd_sonicvibes_getdmaa()
290 return ((inl(sonic->dmac_port + SV_DMA_COUNT0) & 0xffffff) + 1) << 1; in snd_sonicvibes_getdmac()
309 spin_lock_irqsave(&sonic->reg_lock, flags); in snd_sonicvibes_out()
314 spin_unlock_irqrestore(&sonic->reg_lock, flags); in snd_sonicvibes_out()
333 spin_lock_irqsave(&sonic->reg_lock, flags); in snd_sonicvibes_in()
338 spin_unlock_irqrestore(&sonic->reg_lock, flags); in snd_sonicvibes_in()
345 dev_dbg(sonic->card->dev,
348 dev_dbg(sonic->card->dev,
351 dev_dbg(sonic->card->dev,
354 dev_dbg(sonic->card->dev,
355 " 0x02: left AUX1 = 0x%02x 0x22: ADC clock = 0x%02x\n",
357 dev_dbg(sonic->card->dev,
358 " 0x03: right AUX1 = 0x%02x 0x23: ADC alt rate = 0x%02x\n",
360 dev_dbg(sonic->card->dev,
361 " 0x04: left CD = 0x%02x 0x24: ADC pll M = 0x%02x\n",
363 dev_dbg(sonic->card->dev,
364 " 0x05: right CD = 0x%02x 0x25: ADC pll N = 0x%02x\n",
366 dev_dbg(sonic->card->dev,
369 dev_dbg(sonic->card->dev,
372 dev_dbg(sonic->card->dev,
373 " 0x08: MIC = 0x%02x 0x28: --- = 0x%02x\n",
375 dev_dbg(sonic->card->dev,
376 " 0x09: Game port = 0x%02x 0x29: --- = 0x%02x\n",
378 dev_dbg(sonic->card->dev,
381 dev_dbg(sonic->card->dev,
384 dev_dbg(sonic->card->dev,
387 dev_dbg(sonic->card->dev,
390 dev_dbg(sonic->card->dev,
393 dev_dbg(sonic->card->dev,
394 " 0x0f: right analog = 0x%02x 0x2f: --- = 0x%02x\n",
396 dev_dbg(sonic->card->dev,
399 dev_dbg(sonic->card->dev,
402 dev_dbg(sonic->card->dev,
403 " 0x12: DMA data format = 0x%02x 0x32: --- = 0x%02x\n",
405 dev_dbg(sonic->card->dev,
406 " 0x13: P/C enable = 0x%02x 0x33: --- = 0x%02x\n",
408 dev_dbg(sonic->card->dev,
409 " 0x14: U/D button = 0x%02x 0x34: --- = 0x%02x\n",
411 dev_dbg(sonic->card->dev,
412 " 0x15: revision = 0x%02x 0x35: --- = 0x%02x\n",
414 dev_dbg(sonic->card->dev,
415 " 0x16: ADC output ctrl = 0x%02x 0x36: --- = 0x%02x\n",
417 dev_dbg(sonic->card->dev,
418 " 0x17: --- = 0x%02x 0x37: --- = 0x%02x\n",
420 dev_dbg(sonic->card->dev,
421 " 0x18: DMA A upper cnt = 0x%02x 0x38: --- = 0x%02x\n",
423 dev_dbg(sonic->card->dev,
424 " 0x19: DMA A lower cnt = 0x%02x 0x39: --- = 0x%02x\n",
426 dev_dbg(sonic->card->dev,
427 " 0x1a: --- = 0x%02x 0x3a: --- = 0x%02x\n",
429 dev_dbg(sonic->card->dev,
430 " 0x1b: --- = 0x%02x 0x3b: --- = 0x%02x\n",
432 dev_dbg(sonic->card->dev,
433 " 0x1c: DMA C upper cnt = 0x%02x 0x3c: --- = 0x%02x\n",
435 dev_dbg(sonic->card->dev,
436 " 0x1d: DMA C upper cnt = 0x%02x 0x3d: --- = 0x%02x\n",
438 dev_dbg(sonic->card->dev,
439 " 0x1e: PCM rate low = 0x%02x 0x3e: --- = 0x%02x\n",
441 dev_dbg(sonic->card->dev,
442 " 0x1f: PCM rate high = 0x%02x 0x3f: --- = 0x%02x\n",
454 spin_lock_irqsave(&sonic->reg_lock, flags); in snd_sonicvibes_setfmt()
457 sonic->format = inb(SV_REG(sonic, DATA)); in snd_sonicvibes_setfmt()
460 sonic->format = (sonic->format & mask) | value; in snd_sonicvibes_setfmt()
461 outb(sonic->format, SV_REG(sonic, DATA)); in snd_sonicvibes_setfmt()
465 spin_unlock_irqrestore(&sonic->reg_lock, flags); in snd_sonicvibes_setfmt()
486 xd = xr - rate; in snd_sonicvibes_pll()
488 xd = rate - xr; in snd_sonicvibes_pll()
491 m = xm - 2; in snd_sonicvibes_pll()
492 n = xn - 2; in snd_sonicvibes_pll()
499 dev_dbg(sonic->card->dev, in snd_sonicvibes_pll()
501 dev_dbg(sonic->card->dev, in snd_sonicvibes_pll()
515 spin_lock_irqsave(&sonic->reg_lock, flags); in snd_sonicvibes_setpll()
518 spin_unlock_irqrestore(&sonic->reg_lock, flags); in snd_sonicvibes_setpll()
537 spin_lock_irqsave(&sonic->reg_lock, flags); in snd_sonicvibes_set_adc_rate()
538 snd_sonicvibes_out1(sonic, SV_IREG_ADC_ALT_RATE, (div - 1) << 4); in snd_sonicvibes_set_adc_rate()
540 spin_unlock_irqrestore(&sonic->reg_lock, flags); in snd_sonicvibes_set_adc_rate()
548 if (hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->min == in snd_sonicvibes_hw_constraint_dac_rate()
549 hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->max) { in snd_sonicvibes_hw_constraint_dac_rate()
550 rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->min; in snd_sonicvibes_hw_constraint_dac_rate()
555 params->rate_num = rate; in snd_sonicvibes_hw_constraint_dac_rate()
556 params->rate_den = 1; in snd_sonicvibes_hw_constraint_dac_rate()
561 params->rate_num = (SV_REFFREQUENCY/16) * (n+2) * r; in snd_sonicvibes_hw_constraint_dac_rate()
562 params->rate_den = (SV_ADCMULT/512) * (m+2); in snd_sonicvibes_hw_constraint_dac_rate()
576 spin_lock_irqsave(&sonic->reg_lock, flags); in snd_sonicvibes_set_dac_rate()
579 spin_unlock_irqrestore(&sonic->reg_lock, flags); in snd_sonicvibes_set_dac_rate()
586 spin_lock(&sonic->reg_lock); in snd_sonicvibes_trigger()
588 if (!(sonic->enable & what)) { in snd_sonicvibes_trigger()
589 sonic->enable |= what; in snd_sonicvibes_trigger()
590 snd_sonicvibes_out1(sonic, SV_IREG_PC_ENABLE, sonic->enable); in snd_sonicvibes_trigger()
593 if (sonic->enable & what) { in snd_sonicvibes_trigger()
594 sonic->enable &= ~what; in snd_sonicvibes_trigger()
595 snd_sonicvibes_out1(sonic, SV_IREG_PC_ENABLE, sonic->enable); in snd_sonicvibes_trigger()
598 result = -EINVAL; in snd_sonicvibes_trigger()
600 spin_unlock(&sonic->reg_lock); in snd_sonicvibes_trigger()
613 outb(sonic->irqmask = ~0, SV_REG(sonic, IRQMASK)); in snd_sonicvibes_interrupt()
614 dev_err(sonic->card->dev, in snd_sonicvibes_interrupt()
615 "IRQ failure - interrupts disabled!!\n"); in snd_sonicvibes_interrupt()
618 if (sonic->pcm) { in snd_sonicvibes_interrupt()
620 snd_pcm_period_elapsed(sonic->playback_substream); in snd_sonicvibes_interrupt()
622 snd_pcm_period_elapsed(sonic->capture_substream); in snd_sonicvibes_interrupt()
624 if (sonic->rmidi) { in snd_sonicvibes_interrupt()
626 snd_mpu401_uart_interrupt(irq, sonic->rmidi->private_data); in snd_sonicvibes_interrupt()
632 spin_lock(&sonic->reg_lock); in snd_sonicvibes_interrupt()
636 vol = -vol; in snd_sonicvibes_interrupt()
659 spin_unlock(&sonic->reg_lock); in snd_sonicvibes_interrupt()
660 snd_ctl_notify(sonic->card, SNDRV_CTL_EVENT_MASK_VALUE, &sonic->master_mute->id); in snd_sonicvibes_interrupt()
661 snd_ctl_notify(sonic->card, SNDRV_CTL_EVENT_MASK_VALUE, &sonic->master_volume->id); in snd_sonicvibes_interrupt()
687 struct snd_pcm_runtime *runtime = substream->runtime; in snd_sonicvibes_playback_prepare()
692 sonic->p_dma_size = size; in snd_sonicvibes_playback_prepare()
693 count--; in snd_sonicvibes_playback_prepare()
694 if (runtime->channels > 1) in snd_sonicvibes_playback_prepare()
696 if (snd_pcm_format_width(runtime->format) == 16) in snd_sonicvibes_playback_prepare()
699 snd_sonicvibes_set_dac_rate(sonic, runtime->rate); in snd_sonicvibes_playback_prepare()
700 spin_lock_irq(&sonic->reg_lock); in snd_sonicvibes_playback_prepare()
701 snd_sonicvibes_setdmaa(sonic, runtime->dma_addr, size); in snd_sonicvibes_playback_prepare()
704 spin_unlock_irq(&sonic->reg_lock); in snd_sonicvibes_playback_prepare()
711 struct snd_pcm_runtime *runtime = substream->runtime; in snd_sonicvibes_capture_prepare()
716 sonic->c_dma_size = size; in snd_sonicvibes_capture_prepare()
718 count--; in snd_sonicvibes_capture_prepare()
719 if (runtime->channels > 1) in snd_sonicvibes_capture_prepare()
721 if (snd_pcm_format_width(runtime->format) == 16) in snd_sonicvibes_capture_prepare()
724 snd_sonicvibes_set_adc_rate(sonic, runtime->rate); in snd_sonicvibes_capture_prepare()
725 spin_lock_irq(&sonic->reg_lock); in snd_sonicvibes_capture_prepare()
726 snd_sonicvibes_setdmac(sonic, runtime->dma_addr, size); in snd_sonicvibes_capture_prepare()
729 spin_unlock_irq(&sonic->reg_lock); in snd_sonicvibes_capture_prepare()
738 if (!(sonic->enable & 1)) in snd_sonicvibes_playback_pointer()
740 ptr = sonic->p_dma_size - snd_sonicvibes_getdmaa(sonic); in snd_sonicvibes_playback_pointer()
741 return bytes_to_frames(substream->runtime, ptr); in snd_sonicvibes_playback_pointer()
748 if (!(sonic->enable & 2)) in snd_sonicvibes_capture_pointer()
750 ptr = sonic->c_dma_size - snd_sonicvibes_getdmac(sonic); in snd_sonicvibes_capture_pointer()
751 return bytes_to_frames(substream->runtime, ptr); in snd_sonicvibes_capture_pointer()
795 struct snd_pcm_runtime *runtime = substream->runtime; in snd_sonicvibes_playback_open()
797 sonic->mode |= SV_MODE_PLAY; in snd_sonicvibes_playback_open()
798 sonic->playback_substream = substream; in snd_sonicvibes_playback_open()
799 runtime->hw = snd_sonicvibes_playback; in snd_sonicvibes_playback_open()
800 …SNDRV_PCM_HW_PARAM_RATE, snd_sonicvibes_hw_constraint_dac_rate, NULL, SNDRV_PCM_HW_PARAM_RATE, -1); in snd_sonicvibes_playback_open()
807 struct snd_pcm_runtime *runtime = substream->runtime; in snd_sonicvibes_capture_open()
809 sonic->mode |= SV_MODE_CAPTURE; in snd_sonicvibes_capture_open()
810 sonic->capture_substream = substream; in snd_sonicvibes_capture_open()
811 runtime->hw = snd_sonicvibes_capture; in snd_sonicvibes_capture_open()
821 sonic->playback_substream = NULL; in snd_sonicvibes_playback_close()
822 sonic->mode &= ~SV_MODE_PLAY; in snd_sonicvibes_playback_close()
830 sonic->capture_substream = NULL; in snd_sonicvibes_capture_close()
831 sonic->mode &= ~SV_MODE_CAPTURE; in snd_sonicvibes_capture_close()
856 if ((err = snd_pcm_new(sonic->card, "s3_86c617", device, 1, 1, &pcm)) < 0) 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()
1101 case 1: kctl->private_free = snd_sonicvibes_master_free; break; in snd_sonicvibes_mixer()
1114 struct sonicvibes *sonic = entry->private_data; in snd_sonicvibes_proc_read()
1117 tmp = sonic->srs_space & 0x0f; in snd_sonicvibes_proc_read()
1119 sonic->srs_space & 0x80 ? "off" : "on"); in snd_sonicvibes_proc_read()
1125 tmp = sonic->srs_center & 0x0f; in snd_sonicvibes_proc_read()
1131 tmp = sonic->wave_source & 0x03; in snd_sonicvibes_proc_read()
1133 tmp == 0x00 ? "on-board ROM" : in snd_sonicvibes_proc_read()
1134 tmp == 0x01 ? "PCI bus" : "on-board ROM + PCI bus"); in snd_sonicvibes_proc_read()
1135 tmp = sonic->mpu_switch; in snd_sonicvibes_proc_read()
1143 snd_card_ro_proc_new(sonic->card, "sonicvibes", sonic, in snd_sonicvibes_proc_init()
1160 sonic->gameport = gp = gameport_allocate_port(); in snd_sonicvibes_create_gameport()
1162 dev_err(sonic->card->dev, in snd_sonicvibes_create_gameport()
1164 return -ENOMEM; in snd_sonicvibes_create_gameport()
1168 gameport_set_phys(gp, "pci%s/gameport0", pci_name(sonic->pci)); in snd_sonicvibes_create_gameport()
1169 gameport_set_dev_parent(gp, &sonic->pci->dev); in snd_sonicvibes_create_gameport()
1170 gp->io = sonic->game_port; in snd_sonicvibes_create_gameport()
1174 err = snd_ctl_add(sonic->card, in snd_sonicvibes_create_gameport()
1184 if (sonic->gameport) { in snd_sonicvibes_free_gameport()
1185 gameport_unregister_port(sonic->gameport); in snd_sonicvibes_free_gameport()
1186 sonic->gameport = NULL; in snd_sonicvibes_free_gameport()
1190 static inline int snd_sonicvibes_create_gameport(struct sonicvibes *sonic) { return -ENOSYS; } in snd_sonicvibes_create_gameport()
1197 pci_write_config_dword(sonic->pci, 0x40, sonic->dmaa_port); in snd_sonicvibes_free()
1198 pci_write_config_dword(sonic->pci, 0x48, sonic->dmac_port); in snd_sonicvibes_free()
1199 if (sonic->irq >= 0) in snd_sonicvibes_free()
1200 free_irq(sonic->irq, sonic); in snd_sonicvibes_free()
1201 release_and_free_resource(sonic->res_dmaa); in snd_sonicvibes_free()
1202 release_and_free_resource(sonic->res_dmac); in snd_sonicvibes_free()
1203 pci_release_regions(sonic->pci); in snd_sonicvibes_free()
1204 pci_disable_device(sonic->pci); in snd_sonicvibes_free()
1211 struct sonicvibes *sonic = device->device_data; in snd_sonicvibes_dev_free()
1233 if (dma_set_mask(&pci->dev, DMA_BIT_MASK(24)) < 0 || in snd_sonicvibes_create()
1234 dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(24)) < 0) { in snd_sonicvibes_create()
1235 dev_err(card->dev, in snd_sonicvibes_create()
1238 return -ENXIO; in snd_sonicvibes_create()
1244 return -ENOMEM; in snd_sonicvibes_create()
1246 spin_lock_init(&sonic->reg_lock); in snd_sonicvibes_create()
1247 sonic->card = card; in snd_sonicvibes_create()
1248 sonic->pci = pci; in snd_sonicvibes_create()
1249 sonic->irq = -1; in snd_sonicvibes_create()
1257 sonic->sb_port = pci_resource_start(pci, 0); in snd_sonicvibes_create()
1258 sonic->enh_port = pci_resource_start(pci, 1); in snd_sonicvibes_create()
1259 sonic->synth_port = pci_resource_start(pci, 2); in snd_sonicvibes_create()
1260 sonic->midi_port = pci_resource_start(pci, 3); in snd_sonicvibes_create()
1261 sonic->game_port = pci_resource_start(pci, 4); in snd_sonicvibes_create()
1263 if (request_irq(pci->irq, snd_sonicvibes_interrupt, IRQF_SHARED, in snd_sonicvibes_create()
1265 dev_err(card->dev, "unable to grab IRQ %d\n", pci->irq); in snd_sonicvibes_create()
1267 return -EBUSY; in snd_sonicvibes_create()
1269 sonic->irq = pci->irq; in snd_sonicvibes_create()
1270 card->sync_irq = sonic->irq; in snd_sonicvibes_create()
1280 dev_info(card->dev, in snd_sonicvibes_create()
1281 "BIOS did not allocate DDMA channel A i/o, allocated at 0x%x\n", in snd_sonicvibes_create()
1287 dev_info(card->dev, in snd_sonicvibes_create()
1288 "BIOS did not allocate DDMA channel C i/o, allocated at 0x%x\n", in snd_sonicvibes_create()
1294 if ((sonic->res_dmaa = request_region(dmaa, 0x10, "S3 SonicVibes DDMA-A")) == NULL) { in snd_sonicvibes_create()
1296 dev_err(card->dev, in snd_sonicvibes_create()
1297 "unable to grab DDMA-A port at 0x%x-0x%x\n", in snd_sonicvibes_create()
1298 dmaa, dmaa + 0x10 - 1); in snd_sonicvibes_create()
1299 return -EBUSY; in snd_sonicvibes_create()
1301 if ((sonic->res_dmac = request_region(dmac, 0x10, "S3 SonicVibes DDMA-C")) == NULL) { in snd_sonicvibes_create()
1303 dev_err(card->dev, in snd_sonicvibes_create()
1304 "unable to grab DDMA-C port at 0x%x-0x%x\n", in snd_sonicvibes_create()
1305 dmac, dmac + 0x10 - 1); in snd_sonicvibes_create()
1306 return -EBUSY; in snd_sonicvibes_create()
1309 pci_read_config_dword(pci, 0x40, &sonic->dmaa_port); in snd_sonicvibes_create()
1310 pci_read_config_dword(pci, 0x48, &sonic->dmac_port); in snd_sonicvibes_create()
1311 sonic->dmaa_port &= ~0x0f; in snd_sonicvibes_create()
1312 sonic->dmac_port &= ~0x0f; in snd_sonicvibes_create()
1313 pci_write_config_dword(pci, 0x40, sonic->dmaa_port | 9); /* enable + enhanced */ in snd_sonicvibes_create()
1314 pci_write_config_dword(pci, 0x48, sonic->dmac_port | 9); /* enable */ in snd_sonicvibes_create()
1327 snd_sonicvibes_out(sonic, SV_IREG_PC_ENABLE, sonic->enable = 0); /* disable playback & capture */ in snd_sonicvibes_create()
1328 outb(sonic->irqmask = ~(SV_DMAA_MASK | SV_DMAC_MASK | SV_UD_MASK), SV_REG(sonic, IRQMASK)); in snd_sonicvibes_create()
1334 snd_sonicvibes_out(sonic, SV_IREG_SRS_SPACE, sonic->srs_space = 0x80); /* SRS space off */ in snd_sonicvibes_create()
1335 snd_sonicvibes_out(sonic, SV_IREG_SRS_CENTER, sonic->srs_center = 0x00);/* SRS center off */ in snd_sonicvibes_create()
1336 snd_sonicvibes_out(sonic, SV_IREG_MPU401, sonic->mpu_switch = 0x05); /* MPU-401 switch */ in snd_sonicvibes_create()
1337 snd_sonicvibes_out(sonic, SV_IREG_WAVE_SOURCE, sonic->wave_source = 0x00); /* onboard ROM */ in snd_sonicvibes_create()
1361 sonic->revision = snd_sonicvibes_in(sonic, SV_IREG_REVISION); in snd_sonicvibes_create()
1388 struct sonicvibes *sonic = mpu->private_data; in snd_sonicvibes_midi_input_open()
1389 outb(sonic->irqmask &= ~SV_MIDI_MASK, SV_REG(sonic, IRQMASK)); in snd_sonicvibes_midi_input_open()
1395 struct sonicvibes *sonic = mpu->private_data; in snd_sonicvibes_midi_input_close()
1396 outb(sonic->irqmask |= SV_MIDI_MASK, SV_REG(sonic, IRQMASK)); in snd_sonicvibes_midi_input_close()
1402 struct snd_mpu401 * mpu = rmidi->private_data; in snd_sonicvibes_midi()
1403 struct snd_card *card = sonic->card; in snd_sonicvibes_midi()
1407 mpu->private_data = sonic; in snd_sonicvibes_midi()
1408 mpu->open_input = snd_sonicvibes_midi_input_open; in snd_sonicvibes_midi()
1409 mpu->close_input = snd_sonicvibes_midi_input_close; in snd_sonicvibes_midi()
1427 return -ENODEV; in snd_sonic_probe()
1430 return -ENOENT; in snd_sonic_probe()
1433 err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE, in snd_sonic_probe()
1441 return -ENODEV; in snd_sonic_probe()
1452 strcpy(card->driver, "SonicVibes"); in snd_sonic_probe()
1453 strcpy(card->shortname, "S3 SonicVibes"); in snd_sonic_probe()
1454 sprintf(card->longname, "%s rev %i at 0x%llx, irq %i", in snd_sonic_probe()
1455 card->shortname, in snd_sonic_probe()
1456 sonic->revision, in snd_sonic_probe()
1458 sonic->irq); in snd_sonic_probe()
1469 sonic->midi_port, in snd_sonic_probe()
1472 -1, &midi_uart)) < 0) { in snd_sonic_probe()
1477 if ((err = snd_opl3_create(card, sonic->synth_port, in snd_sonic_probe()
1478 sonic->synth_port + 2, in snd_sonic_probe()