Lines Matching +full:mic +full:- +full:pos

1 // SPDX-License-Identifier: GPL-2.0-or-later
4 * Copyright (c) by Christian Fischbach <fishbach@pool.informatik.rwth-aachen.de>
5 * Copyright (c) by Abramo Bagnara <abramo@alsa-project.org>
10 * - There are pops (we can't delay in trigger function, cause midlevel
13 * - Support for 16 bit DMA seems to be broken. I've no hardware to tune it.
18 * - The chip has one half duplex pcm (with very limited full duplex support).
20 * - Duplex stereophonic sound is impossible.
21 * - Record and playback must share the same frequency rate.
23 * - The driver use dma2 for playback and dma1 for capture.
29 * - there are a first full duplex pcm and a second playback only pcm
32 * - there is support for the capture volume and ESS Spatializer 3D effect.
34 * - contrarily to some pages in DS_1869.PDF the rates can be set
37 * - Zoom Video is implemented by sharing the FM DAC, thus the user can
43 * - There is a major trouble I noted:
57 * - When Zoom Video is enabled (reg 0x71 bit 6 toggled on) the PCM playback
163 for(i = MILLISECOND; i; i--) in snd_es18xx_dsp_command()
164 if ((inb(chip->port + 0x0C) & 0x80) == 0) { in snd_es18xx_dsp_command()
165 outb(val, chip->port + 0x0C); in snd_es18xx_dsp_command()
169 return -EINVAL; in snd_es18xx_dsp_command()
176 for(i = MILLISECOND/10; i; i--) in snd_es18xx_dsp_get_byte()
177 if (inb(chip->port + 0x0C) & 0x40) in snd_es18xx_dsp_get_byte()
178 return inb(chip->port + 0x0A); in snd_es18xx_dsp_get_byte()
180 chip->port + 0x0A, inb(chip->port + 0x0A)); in snd_es18xx_dsp_get_byte()
181 return -ENODEV; in snd_es18xx_dsp_get_byte()
192 spin_lock_irqsave(&chip->reg_lock, flags); in snd_es18xx_write()
198 spin_unlock_irqrestore(&chip->reg_lock, flags); in snd_es18xx_write()
209 spin_lock_irqsave(&chip->reg_lock, flags); in snd_es18xx_read()
222 spin_unlock_irqrestore(&chip->reg_lock, flags); in snd_es18xx_read()
233 spin_lock_irqsave(&chip->reg_lock, flags); in snd_es18xx_bits()
261 spin_unlock_irqrestore(&chip->reg_lock, flags); in snd_es18xx_bits()
269 spin_lock_irqsave(&chip->mixer_lock, flags); in snd_es18xx_mixer_write()
270 outb(reg, chip->port + 0x04); in snd_es18xx_mixer_write()
271 outb(data, chip->port + 0x05); in snd_es18xx_mixer_write()
272 spin_unlock_irqrestore(&chip->mixer_lock, flags); in snd_es18xx_mixer_write()
282 spin_lock_irqsave(&chip->mixer_lock, flags); in snd_es18xx_mixer_read()
283 outb(reg, chip->port + 0x04); in snd_es18xx_mixer_read()
284 data = inb(chip->port + 0x05); in snd_es18xx_mixer_read()
285 spin_unlock_irqrestore(&chip->mixer_lock, flags); in snd_es18xx_mixer_read()
298 spin_lock_irqsave(&chip->mixer_lock, flags); in snd_es18xx_mixer_bits()
299 outb(reg, chip->port + 0x04); in snd_es18xx_mixer_bits()
300 old = inb(chip->port + 0x05); in snd_es18xx_mixer_bits()
304 outb(new, chip->port + 0x05); in snd_es18xx_mixer_bits()
310 spin_unlock_irqrestore(&chip->mixer_lock, flags); in snd_es18xx_mixer_bits()
319 spin_lock_irqsave(&chip->mixer_lock, flags); in snd_es18xx_mixer_writable()
320 outb(reg, chip->port + 0x04); in snd_es18xx_mixer_writable()
321 old = inb(chip->port + 0x05); in snd_es18xx_mixer_writable()
323 outb(expected, chip->port + 0x05); in snd_es18xx_mixer_writable()
324 new = inb(chip->port + 0x05); in snd_es18xx_mixer_writable()
325 spin_unlock_irqrestore(&chip->mixer_lock, flags); in snd_es18xx_mixer_writable()
337 outb(0x03, chip->port + 0x06); in snd_es18xx_reset()
338 inb(chip->port + 0x06); in snd_es18xx_reset()
339 outb(0x00, chip->port + 0x06); in snd_es18xx_reset()
340 for(i = 0; i < MILLISECOND && !(inb(chip->port + 0x0E) & 0x80); i++); in snd_es18xx_reset()
341 if (inb(chip->port + 0x0A) != 0xAA) in snd_es18xx_reset()
342 return -1; in snd_es18xx_reset()
348 outb(0x02, chip->port + 0x06); in snd_es18xx_reset_fifo()
349 inb(chip->port + 0x06); in snd_es18xx_reset_fifo()
350 outb(0x00, chip->port + 0x06); in snd_es18xx_reset_fifo()
400 struct snd_pcm_runtime *runtime = substream->runtime; in snd_es18xx_rate_set()
401 if (chip->caps & ES18XX_NEW_RATE) { in snd_es18xx_rate_set()
402 if (runtime->rate_num == new_clocks[0].num) in snd_es18xx_rate_set()
403 bits = 128 - runtime->rate_den; in snd_es18xx_rate_set()
405 bits = 256 - runtime->rate_den; in snd_es18xx_rate_set()
407 if (runtime->rate_num == old_clocks[0].num) in snd_es18xx_rate_set()
408 bits = 256 - runtime->rate_den; in snd_es18xx_rate_set()
410 bits = 128 - runtime->rate_den; in snd_es18xx_rate_set()
414 div0 = 256 - 7160000*20/(8*82*runtime->rate); in snd_es18xx_rate_set()
416 if ((chip->caps & ES18XX_PCM2) && mode == DAC2) { in snd_es18xx_rate_set()
442 if (substream->number == 0 && (chip->caps & ES18XX_PCM2)) { in snd_es18xx_playback_hw_params()
443 if ((chip->caps & ES18XX_DUPLEX_MONO) && in snd_es18xx_playback_hw_params()
444 (chip->capture_a_substream) && in snd_es18xx_playback_hw_params()
447 return -EBUSY; in snd_es18xx_playback_hw_params()
449 chip->dma2_shift = shift; in snd_es18xx_playback_hw_params()
451 chip->dma1_shift = shift; in snd_es18xx_playback_hw_params()
459 struct snd_pcm_runtime *runtime = substream->runtime; in snd_es18xx_playback1_prepare()
466 count = 0x10000 - count; in snd_es18xx_playback1_prepare()
472 ((runtime->channels == 1) ? 0x00 : 0x02) | in snd_es18xx_playback1_prepare()
473 (snd_pcm_format_width(runtime->format) == 16 ? 0x01 : 0x00) | in snd_es18xx_playback1_prepare()
474 (snd_pcm_format_unsigned(runtime->format) ? 0x00 : 0x04)); in snd_es18xx_playback1_prepare()
477 snd_dma_program(chip->dma2, runtime->dma_addr, size, DMA_MODE_WRITE | DMA_AUTOINIT); in snd_es18xx_playback1_prepare()
489 if (chip->active & DAC2) in snd_es18xx_playback1_trigger()
491 chip->active |= DAC2; in snd_es18xx_playback1_trigger()
493 if (chip->dma2 >= 4) in snd_es18xx_playback1_trigger()
500 if (chip->caps & ES18XX_PCM2) in snd_es18xx_playback1_trigger()
502 snd_es18xx_mixer_write(chip, 0x7C, chip->audio2_vol); in snd_es18xx_playback1_trigger()
510 if (!(chip->active & DAC2)) in snd_es18xx_playback1_trigger()
512 chip->active &= ~DAC2; in snd_es18xx_playback1_trigger()
517 if (chip->caps & ES18XX_PCM2) in snd_es18xx_playback1_trigger()
526 return -EINVAL; in snd_es18xx_playback1_trigger()
539 if ((chip->caps & ES18XX_DUPLEX_MONO) && in snd_es18xx_capture_hw_params()
540 chip->playback_a_substream && in snd_es18xx_capture_hw_params()
543 return -EBUSY; in snd_es18xx_capture_hw_params()
549 chip->dma1_shift = shift; in snd_es18xx_capture_hw_params()
556 struct snd_pcm_runtime *runtime = substream->runtime; in snd_es18xx_capture_prepare()
563 snd_es18xx_bits(chip, 0xA8, 0x03, runtime->channels == 1 ? 0x02 : 0x01); in snd_es18xx_capture_prepare()
568 count = 0x10000 - count; in snd_es18xx_capture_prepare()
578 snd_pcm_format_unsigned(runtime->format) ? 0x51 : 0x71); in snd_es18xx_capture_prepare()
580 ((runtime->channels == 1) ? 0x40 : 0x08) | in snd_es18xx_capture_prepare()
581 (snd_pcm_format_width(runtime->format) == 16 ? 0x04 : 0x00) | in snd_es18xx_capture_prepare()
582 (snd_pcm_format_unsigned(runtime->format) ? 0x00 : 0x20)); in snd_es18xx_capture_prepare()
585 snd_dma_program(chip->dma1, runtime->dma_addr, size, DMA_MODE_READ | DMA_AUTOINIT); in snd_es18xx_capture_prepare()
598 if (chip->active & ADC1) in snd_es18xx_capture_trigger()
600 chip->active |= ADC1; in snd_es18xx_capture_trigger()
606 if (!(chip->active & ADC1)) in snd_es18xx_capture_trigger()
608 chip->active &= ~ADC1; in snd_es18xx_capture_trigger()
613 return -EINVAL; in snd_es18xx_capture_trigger()
622 struct snd_pcm_runtime *runtime = substream->runtime; in snd_es18xx_playback2_prepare()
629 snd_es18xx_bits(chip, 0xA8, 0x03, runtime->channels == 1 ? 0x02 : 0x01); in snd_es18xx_playback2_prepare()
634 count = 0x10000 - count; in snd_es18xx_playback2_prepare()
640 snd_pcm_format_unsigned(runtime->format) ? 0x80 : 0x00); in snd_es18xx_playback2_prepare()
642 snd_pcm_format_unsigned(runtime->format) ? 0x51 : 0x71); in snd_es18xx_playback2_prepare()
644 (runtime->channels == 1 ? 0x40 : 0x08) | in snd_es18xx_playback2_prepare()
645 (snd_pcm_format_width(runtime->format) == 16 ? 0x04 : 0x00) | in snd_es18xx_playback2_prepare()
646 (snd_pcm_format_unsigned(runtime->format) ? 0x00 : 0x20)); in snd_es18xx_playback2_prepare()
649 snd_dma_program(chip->dma1, runtime->dma_addr, size, DMA_MODE_WRITE | DMA_AUTOINIT); in snd_es18xx_playback2_prepare()
661 if (chip->active & DAC1) in snd_es18xx_playback2_trigger()
663 chip->active |= DAC1; in snd_es18xx_playback2_trigger()
675 if (!(chip->active & DAC1)) in snd_es18xx_playback2_trigger()
677 chip->active &= ~DAC1; in snd_es18xx_playback2_trigger()
688 return -EINVAL; in snd_es18xx_playback2_trigger()
697 if (substream->number == 0 && (chip->caps & ES18XX_PCM2)) in snd_es18xx_playback_prepare()
707 if (substream->number == 0 && (chip->caps & ES18XX_PCM2)) in snd_es18xx_playback_trigger()
716 struct snd_es18xx *chip = card->private_data; in snd_es18xx_interrupt()
719 if (chip->caps & ES18XX_CONTROL) { in snd_es18xx_interrupt()
721 status = inb(chip->ctrl_port + 6); in snd_es18xx_interrupt()
729 if (inb(chip->port + 0x0C) & 0x01) in snd_es18xx_interrupt()
733 if ((chip->caps & ES18XX_HWV) && in snd_es18xx_interrupt()
741 if (chip->active & DAC2) in snd_es18xx_interrupt()
742 snd_pcm_period_elapsed(chip->playback_a_substream); in snd_es18xx_interrupt()
748 if (chip->active & ADC1) in snd_es18xx_interrupt()
749 snd_pcm_period_elapsed(chip->capture_a_substream); in snd_es18xx_interrupt()
751 else if (chip->active & DAC1) in snd_es18xx_interrupt()
752 snd_pcm_period_elapsed(chip->playback_b_substream); in snd_es18xx_interrupt()
754 inb(chip->port + 0x0E); in snd_es18xx_interrupt()
758 if ((status & MPU_IRQ) && chip->rmidi) in snd_es18xx_interrupt()
759 snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data); in snd_es18xx_interrupt()
764 if (chip->caps & ES18XX_HWV) { in snd_es18xx_interrupt()
767 &chip->hw_switch->id); in snd_es18xx_interrupt()
769 &chip->hw_volume->id); in snd_es18xx_interrupt()
773 &chip->master_switch->id); in snd_es18xx_interrupt()
775 &chip->master_volume->id); in snd_es18xx_interrupt()
787 int pos; in snd_es18xx_playback_pointer() local
789 if (substream->number == 0 && (chip->caps & ES18XX_PCM2)) { in snd_es18xx_playback_pointer()
790 if (!(chip->active & DAC2)) in snd_es18xx_playback_pointer()
792 pos = snd_dma_pointer(chip->dma2, size); in snd_es18xx_playback_pointer()
793 return pos >> chip->dma2_shift; in snd_es18xx_playback_pointer()
795 if (!(chip->active & DAC1)) in snd_es18xx_playback_pointer()
797 pos = snd_dma_pointer(chip->dma1, size); in snd_es18xx_playback_pointer()
798 return pos >> chip->dma1_shift; in snd_es18xx_playback_pointer()
806 int pos; in snd_es18xx_capture_pointer() local
808 if (!(chip->active & ADC1)) in snd_es18xx_capture_pointer()
810 pos = snd_dma_pointer(chip->dma1, size); in snd_es18xx_capture_pointer()
811 return pos >> chip->dma1_shift; in snd_es18xx_capture_pointer()
856 struct snd_pcm_runtime *runtime = substream->runtime; in snd_es18xx_playback_open()
859 if (substream->number == 0 && (chip->caps & ES18XX_PCM2)) { in snd_es18xx_playback_open()
860 if ((chip->caps & ES18XX_DUPLEX_MONO) && in snd_es18xx_playback_open()
861 chip->capture_a_substream && in snd_es18xx_playback_open()
862 chip->capture_a_substream->runtime->channels != 1) in snd_es18xx_playback_open()
863 return -EAGAIN; in snd_es18xx_playback_open()
864 chip->playback_a_substream = substream; in snd_es18xx_playback_open()
865 } else if (substream->number <= 1) { in snd_es18xx_playback_open()
866 if (chip->capture_a_substream) in snd_es18xx_playback_open()
867 return -EAGAIN; in snd_es18xx_playback_open()
868 chip->playback_b_substream = substream; in snd_es18xx_playback_open()
871 return -EINVAL; in snd_es18xx_playback_open()
873 substream->runtime->hw = snd_es18xx_playback; in snd_es18xx_playback_open()
875 (chip->caps & ES18XX_NEW_RATE) ? &new_hw_constraints_clocks : &old_hw_constraints_clocks); in snd_es18xx_playback_open()
881 struct snd_pcm_runtime *runtime = substream->runtime; in snd_es18xx_capture_open()
884 if (chip->playback_b_substream) in snd_es18xx_capture_open()
885 return -EAGAIN; in snd_es18xx_capture_open()
886 if ((chip->caps & ES18XX_DUPLEX_MONO) && in snd_es18xx_capture_open()
887 chip->playback_a_substream && in snd_es18xx_capture_open()
888 chip->playback_a_substream->runtime->channels != 1) in snd_es18xx_capture_open()
889 return -EAGAIN; in snd_es18xx_capture_open()
890 chip->capture_a_substream = substream; in snd_es18xx_capture_open()
891 substream->runtime->hw = snd_es18xx_capture; in snd_es18xx_capture_open()
893 (chip->caps & ES18XX_NEW_RATE) ? &new_hw_constraints_clocks : &old_hw_constraints_clocks); in snd_es18xx_capture_open()
901 if (substream->number == 0 && (chip->caps & ES18XX_PCM2)) in snd_es18xx_playback_close()
902 chip->playback_a_substream = NULL; in snd_es18xx_playback_close()
904 chip->playback_b_substream = NULL; in snd_es18xx_playback_close()
913 chip->capture_a_substream = NULL; in snd_es18xx_capture_close()
940 "Mic", "CD", "Line", "Master", "Mix" in snd_es18xx_info_mux()
943 "Mic", "Mic Master", "CD", "AOUT", in snd_es18xx_info_mux()
948 switch (chip->version) { in snd_es18xx_info_mux()
959 return -EINVAL; in snd_es18xx_info_mux()
968 if (!(chip->version == 0x1869 || chip->version == 0x1879)) { in snd_es18xx_get_mux()
971 (chip->version == 0x1887 || chip->version == 0x1888) && in snd_es18xx_get_mux()
976 ucontrol->value.enumerated.item[0] = muxSource; in snd_es18xx_get_mux()
984 unsigned char val = ucontrol->value.enumerated.item[0]; in snd_es18xx_put_mux()
987 switch (chip->version) { in snd_es18xx_put_mux()
992 return -EINVAL; in snd_es18xx_put_mux()
1003 return -EINVAL; in snd_es18xx_put_mux()
1010 return -EINVAL; in snd_es18xx_put_mux()
1013 return -EINVAL; in snd_es18xx_put_mux()
1024 ucontrol->value.integer.value[0] = !!(val & 8); in snd_es18xx_get_spatializer_enable()
1033 nval = ucontrol->value.integer.value[0] ? 0x0c : 0x04; in snd_es18xx_put_spatializer_enable()
1045 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in snd_es18xx_info_hw_volume()
1046 uinfo->count = 2; in snd_es18xx_info_hw_volume()
1047 uinfo->value.integer.min = 0; in snd_es18xx_info_hw_volume()
1048 uinfo->value.integer.max = 63; in snd_es18xx_info_hw_volume()
1055 ucontrol->value.integer.value[0] = snd_es18xx_mixer_read(chip, 0x61) & 0x3f; in snd_es18xx_get_hw_volume()
1056 ucontrol->value.integer.value[1] = snd_es18xx_mixer_read(chip, 0x63) & 0x3f; in snd_es18xx_get_hw_volume()
1065 ucontrol->value.integer.value[0] = !(snd_es18xx_mixer_read(chip, 0x61) & 0x40); in snd_es18xx_get_hw_switch()
1066 ucontrol->value.integer.value[1] = !(snd_es18xx_mixer_read(chip, 0x63) & 0x40); in snd_es18xx_get_hw_switch()
1073 chip->master_volume = NULL; in snd_es18xx_hwv_free()
1074 chip->master_switch = NULL; in snd_es18xx_hwv_free()
1075 chip->hw_volume = NULL; in snd_es18xx_hwv_free()
1076 chip->hw_switch = NULL; in snd_es18xx_hwv_free()
1107 int mask = (kcontrol->private_value >> 16) & 0xff; in snd_es18xx_info_single()
1109 uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER; in snd_es18xx_info_single()
1110 uinfo->count = 1; in snd_es18xx_info_single()
1111 uinfo->value.integer.min = 0; in snd_es18xx_info_single()
1112 uinfo->value.integer.max = mask; in snd_es18xx_info_single()
1119 int reg = kcontrol->private_value & 0xff; in snd_es18xx_get_single()
1120 int shift = (kcontrol->private_value >> 8) & 0xff; in snd_es18xx_get_single()
1121 int mask = (kcontrol->private_value >> 16) & 0xff; in snd_es18xx_get_single()
1122 int invert = (kcontrol->private_value >> 24) & ES18XX_FL_INVERT; in snd_es18xx_get_single()
1123 int pm_port = (kcontrol->private_value >> 24) & ES18XX_FL_PMPORT; in snd_es18xx_get_single()
1127 val = inb(chip->port + ES18XX_PM); in snd_es18xx_get_single()
1130 ucontrol->value.integer.value[0] = (val >> shift) & mask; in snd_es18xx_get_single()
1132 ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0]; in snd_es18xx_get_single()
1139 int reg = kcontrol->private_value & 0xff; in snd_es18xx_put_single()
1140 int shift = (kcontrol->private_value >> 8) & 0xff; in snd_es18xx_put_single()
1141 int mask = (kcontrol->private_value >> 16) & 0xff; in snd_es18xx_put_single()
1142 int invert = (kcontrol->private_value >> 24) & ES18XX_FL_INVERT; in snd_es18xx_put_single()
1143 int pm_port = (kcontrol->private_value >> 24) & ES18XX_FL_PMPORT; in snd_es18xx_put_single()
1146 val = (ucontrol->value.integer.value[0] & mask); in snd_es18xx_put_single()
1148 val = mask - val; in snd_es18xx_put_single()
1152 unsigned char cur = inb(chip->port + ES18XX_PM); in snd_es18xx_put_single()
1156 outb((cur & ~mask) | val, chip->port + ES18XX_PM); in snd_es18xx_put_single()
1171 int mask = (kcontrol->private_value >> 24) & 0xff; in snd_es18xx_info_double()
1173 uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER; in snd_es18xx_info_double()
1174 uinfo->count = 2; in snd_es18xx_info_double()
1175 uinfo->value.integer.min = 0; in snd_es18xx_info_double()
1176 uinfo->value.integer.max = mask; in snd_es18xx_info_double()
1183 int left_reg = kcontrol->private_value & 0xff; in snd_es18xx_get_double()
1184 int right_reg = (kcontrol->private_value >> 8) & 0xff; in snd_es18xx_get_double()
1185 int shift_left = (kcontrol->private_value >> 16) & 0x07; in snd_es18xx_get_double()
1186 int shift_right = (kcontrol->private_value >> 19) & 0x07; in snd_es18xx_get_double()
1187 int mask = (kcontrol->private_value >> 24) & 0xff; in snd_es18xx_get_double()
1188 int invert = (kcontrol->private_value >> 22) & 1; in snd_es18xx_get_double()
1196 ucontrol->value.integer.value[0] = (left >> shift_left) & mask; in snd_es18xx_get_double()
1197 ucontrol->value.integer.value[1] = (right >> shift_right) & mask; in snd_es18xx_get_double()
1199 ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0]; in snd_es18xx_get_double()
1200 ucontrol->value.integer.value[1] = mask - ucontrol->value.integer.value[1]; in snd_es18xx_get_double()
1208 int left_reg = kcontrol->private_value & 0xff; in snd_es18xx_put_double()
1209 int right_reg = (kcontrol->private_value >> 8) & 0xff; in snd_es18xx_put_double()
1210 int shift_left = (kcontrol->private_value >> 16) & 0x07; in snd_es18xx_put_double()
1211 int shift_right = (kcontrol->private_value >> 19) & 0x07; in snd_es18xx_put_double()
1212 int mask = (kcontrol->private_value >> 24) & 0xff; in snd_es18xx_put_double()
1213 int invert = (kcontrol->private_value >> 22) & 1; in snd_es18xx_put_double()
1217 val1 = ucontrol->value.integer.value[0] & mask; in snd_es18xx_put_double()
1218 val2 = ucontrol->value.integer.value[1] & mask; in snd_es18xx_put_double()
1220 val1 = mask - val1; in snd_es18xx_put_double()
1221 val2 = mask - val2; in snd_es18xx_put_double()
1252 ES18XX_DOUBLE("Mic Playback Volume", 0, 0x1a, 0x1a, 4, 0, 15, 0),
1267 ES18XX_DOUBLE("Mic Capture Volume", 0, 0x68, 0x68, 4, 0, 15, 0),
1306 ES18XX_SINGLE("3D Control - Level", 0, 0x52, 0, 63, 0),
1309 .name = "3D Control - Switch",
1317 ES18XX_SINGLE("Mic Boost (+26dB)", 0, 0xa9, 2, 1, 0);
1320 ES18XX_SINGLE("Mic Boost (+26dB)", 0, 0x7d, 3, 1, 0);
1347 outb(reg, chip->ctrl_port); in snd_es18xx_config_read()
1348 return inb(chip->ctrl_port + 1); in snd_es18xx_config_read()
1356 outb(reg, chip->ctrl_port); in snd_es18xx_config_write()
1357 outb(data, chip->ctrl_port + 1); in snd_es18xx_config_write()
1376 if (chip->caps & ES18XX_CONTROL) { in snd_es18xx_initialize()
1378 snd_es18xx_config_write(chip, 0x27, chip->irq); in snd_es18xx_initialize()
1385 /* MPU-401 I/O */ in snd_es18xx_initialize()
1388 /* MPU-401 IRQ */ in snd_es18xx_initialize()
1389 snd_es18xx_config_write(chip, 0x28, chip->irq); in snd_es18xx_initialize()
1392 snd_es18xx_config_write(chip, 0x70, chip->irq); in snd_es18xx_initialize()
1394 snd_es18xx_config_write(chip, 0x72, chip->irq); in snd_es18xx_initialize()
1396 snd_es18xx_config_write(chip, 0x74, chip->dma1); in snd_es18xx_initialize()
1398 snd_es18xx_config_write(chip, 0x75, chip->dma2); in snd_es18xx_initialize()
1413 switch (chip->irq) { in snd_es18xx_initialize()
1428 snd_printk(KERN_ERR "invalid irq %d\n", chip->irq); in snd_es18xx_initialize()
1429 return -ENODEV; in snd_es18xx_initialize()
1431 switch (chip->dma1) { in snd_es18xx_initialize()
1442 snd_printk(KERN_ERR "invalid dma1 %d\n", chip->dma1); in snd_es18xx_initialize()
1443 return -ENODEV; in snd_es18xx_initialize()
1445 switch (chip->dma2) { in snd_es18xx_initialize()
1459 snd_printk(KERN_ERR "invalid dma2 %d\n", chip->dma2); in snd_es18xx_initialize()
1460 return -ENODEV; in snd_es18xx_initialize()
1483 if (chip->caps & ES18XX_NEW_RATE) { in snd_es18xx_initialize()
1489 if (!(chip->caps & ES18XX_PCM2)) { in snd_es18xx_initialize()
1493 if (chip->caps & ES18XX_SPATIALIZER) { in snd_es18xx_initialize()
1501 switch (chip->version) { in snd_es18xx_initialize()
1512 if (chip->caps & ES18XX_MUTEREC) in snd_es18xx_initialize()
1514 if (chip->caps & ES18XX_RECMIX) in snd_es18xx_initialize()
1534 snd_printk(KERN_ERR "reset at 0x%lx failed!!!\n", chip->port); in snd_es18xx_identify()
1535 return -ENODEV; in snd_es18xx_identify()
1545 return -ENODEV; in snd_es18xx_identify()
1548 chip->version = 0x488; in snd_es18xx_identify()
1552 return -ENODEV; in snd_es18xx_identify()
1555 chip->version = 0x688; in snd_es18xx_identify()
1559 outb(0x40, chip->port + 0x04); in snd_es18xx_identify()
1561 hi = inb(chip->port + 0x05); in snd_es18xx_identify()
1563 lo = inb(chip->port + 0x05); in snd_es18xx_identify()
1565 chip->version = hi << 8 | lo; in snd_es18xx_identify()
1566 chip->ctrl_port = inb(chip->port + 0x05) << 8; in snd_es18xx_identify()
1568 chip->ctrl_port += inb(chip->port + 0x05); in snd_es18xx_identify()
1570 if (!devm_request_region(card->dev, chip->ctrl_port, 8, in snd_es18xx_identify()
1571 "ES18xx - CTRL")) { in snd_es18xx_identify()
1572 snd_printk(KERN_ERR PFX "unable go grab port 0x%lx\n", chip->ctrl_port); in snd_es18xx_identify()
1573 return -EBUSY; in snd_es18xx_identify()
1585 chip->version = 0x1887; in snd_es18xx_identify()
1587 chip->version = 0x1888; in snd_es18xx_identify()
1590 chip->version = 0x1788; in snd_es18xx_identify()
1594 chip->version = 0x1688; in snd_es18xx_identify()
1604 snd_printk(KERN_ERR PFX "[0x%lx] ESS chip not found\n", chip->port); in snd_es18xx_probe()
1605 return -ENODEV; in snd_es18xx_probe()
1608 switch (chip->version) { in snd_es18xx_probe()
1610 chip->caps = ES18XX_DUPLEX_MONO | ES18XX_DUPLEX_SAME | ES18XX_CONTROL | ES18XX_GPO_2BIT; in snd_es18xx_probe()
1613 …chip->caps = ES18XX_PCM2 | ES18XX_SPATIALIZER | ES18XX_RECMIX | ES18XX_NEW_RATE | ES18XX_AUXB | ES… in snd_es18xx_probe()
1616 chip->caps = ES18XX_DUPLEX_MONO | ES18XX_DUPLEX_SAME | ES18XX_I2S | ES18XX_CONTROL; in snd_es18xx_probe()
1619 …chip->caps = ES18XX_PCM2 | ES18XX_SPATIALIZER | ES18XX_RECMIX | ES18XX_NEW_RATE | ES18XX_AUXB | ES… in snd_es18xx_probe()
1623 chip->caps = ES18XX_PCM2 | ES18XX_RECMIX | ES18XX_AUXB | ES18XX_DUPLEX_SAME | ES18XX_GPO_2BIT; in snd_es18xx_probe()
1627 chip->port, chip->version); in snd_es18xx_probe()
1628 return -ENODEV; in snd_es18xx_probe()
1631 snd_printd("[0x%lx] ESS%x chip found\n", chip->port, chip->version); in snd_es18xx_probe()
1633 if (chip->dma1 == chip->dma2) in snd_es18xx_probe()
1634 chip->caps &= ~(ES18XX_PCM2 | ES18XX_DUPLEX_SAME); in snd_es18xx_probe()
1659 struct snd_es18xx *chip = card->private_data; in snd_es18xx_pcm()
1664 sprintf(str, "ES%x", chip->version); in snd_es18xx_pcm()
1665 if (chip->caps & ES18XX_PCM2) in snd_es18xx_pcm()
1676 pcm->private_data = chip; in snd_es18xx_pcm()
1677 pcm->info_flags = 0; in snd_es18xx_pcm()
1678 if (chip->caps & ES18XX_DUPLEX_SAME) in snd_es18xx_pcm()
1679 pcm->info_flags |= SNDRV_PCM_INFO_JOINT_DUPLEX; in snd_es18xx_pcm()
1680 if (! (chip->caps & ES18XX_PCM2)) in snd_es18xx_pcm()
1681 pcm->info_flags |= SNDRV_PCM_INFO_HALF_DUPLEX; in snd_es18xx_pcm()
1682 sprintf(pcm->name, "ESS AudioDrive ES%x", chip->version); in snd_es18xx_pcm()
1683 chip->pcm = pcm; in snd_es18xx_pcm()
1685 snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV, card->dev, in snd_es18xx_pcm()
1687 chip->dma1 > 3 || chip->dma2 > 3 ? 128*1024 : 64*1024); in snd_es18xx_pcm()
1695 struct snd_es18xx *chip = card->private_data; in snd_es18xx_suspend()
1700 chip->pm_reg = (unsigned char)snd_es18xx_read(chip, ES18XX_PM); in snd_es18xx_suspend()
1701 chip->pm_reg |= (ES18XX_PM_FM | ES18XX_PM_SUS); in snd_es18xx_suspend()
1702 snd_es18xx_write(chip, ES18XX_PM, chip->pm_reg); in snd_es18xx_suspend()
1703 snd_es18xx_write(chip, ES18XX_PM, chip->pm_reg ^= ES18XX_PM_SUS); in snd_es18xx_suspend()
1710 struct snd_es18xx *chip = card->private_data; in snd_es18xx_resume()
1713 snd_es18xx_write(chip, ES18XX_PM, chip->pm_reg ^= ES18XX_PM_FM); in snd_es18xx_resume()
1726 struct snd_es18xx *chip = card->private_data; in snd_es18xx_new_device()
1728 spin_lock_init(&chip->reg_lock); in snd_es18xx_new_device()
1729 spin_lock_init(&chip->mixer_lock); in snd_es18xx_new_device()
1730 chip->port = port; in snd_es18xx_new_device()
1731 chip->irq = -1; in snd_es18xx_new_device()
1732 chip->dma1 = -1; in snd_es18xx_new_device()
1733 chip->dma2 = -1; in snd_es18xx_new_device()
1734 chip->audio2_vol = 0x00; in snd_es18xx_new_device()
1735 chip->active = 0; in snd_es18xx_new_device()
1737 if (!devm_request_region(card->dev, port, 16, "ES18xx")) { in snd_es18xx_new_device()
1738 snd_printk(KERN_ERR PFX "unable to grap ports 0x%lx-0x%lx\n", port, port + 16 - 1); in snd_es18xx_new_device()
1739 return -EBUSY; in snd_es18xx_new_device()
1742 if (devm_request_irq(card->dev, irq, snd_es18xx_interrupt, 0, "ES18xx", in snd_es18xx_new_device()
1745 return -EBUSY; in snd_es18xx_new_device()
1747 chip->irq = irq; in snd_es18xx_new_device()
1748 card->sync_irq = chip->irq; in snd_es18xx_new_device()
1750 if (snd_devm_request_dma(card->dev, dma1, "ES18xx DMA 1")) { in snd_es18xx_new_device()
1752 return -EBUSY; in snd_es18xx_new_device()
1754 chip->dma1 = dma1; in snd_es18xx_new_device()
1757 snd_devm_request_dma(card->dev, dma2, "ES18xx DMA 2")) { in snd_es18xx_new_device()
1759 return -EBUSY; in snd_es18xx_new_device()
1761 chip->dma2 = dma2; in snd_es18xx_new_device()
1764 return -ENODEV; in snd_es18xx_new_device()
1770 struct snd_es18xx *chip = card->private_data; in snd_es18xx_mixer()
1774 strcpy(card->mixername, chip->pcm->name); in snd_es18xx_mixer()
1779 if (chip->caps & ES18XX_HWV) { in snd_es18xx_mixer()
1782 chip->master_volume = kctl; in snd_es18xx_mixer()
1783 kctl->private_free = snd_es18xx_hwv_free; in snd_es18xx_mixer()
1786 chip->master_switch = kctl; in snd_es18xx_mixer()
1787 kctl->private_free = snd_es18xx_hwv_free; in snd_es18xx_mixer()
1795 if (chip->caps & ES18XX_PCM2) { in snd_es18xx_mixer()
1809 if (chip->caps & ES18XX_RECMIX) { in snd_es18xx_mixer()
1816 switch (chip->version) { in snd_es18xx_mixer()
1829 if (chip->caps & ES18XX_SPATIALIZER) { in snd_es18xx_mixer()
1836 if (chip->caps & ES18XX_HWV) { in snd_es18xx_mixer()
1841 chip->hw_volume = kctl; in snd_es18xx_mixer()
1843 chip->hw_switch = kctl; in snd_es18xx_mixer()
1844 kctl->private_free = snd_es18xx_hwv_free; in snd_es18xx_mixer()
1853 if (chip->version != 0x1868) { in snd_es18xx_mixer()
1859 if (chip->version == 0x1869) { in snd_es18xx_mixer()
1867 } else if (chip->version == 0x1878) { in snd_es18xx_mixer()
1872 } else if (chip->version == 0x1879) { in snd_es18xx_mixer()
1881 if (chip->caps & ES18XX_GPO_2BIT) { in snd_es18xx_mixer()
1896 …THOR("Christian Fischbach <fishbach@pool.informatik.rwth-aachen.de>, Abramo Bagnara <abramo@alsa-p…
1900 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
1908 static long mpu_port[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -1};
1930 MODULE_PARM_DESC(mpu_port, "MPU-401 port # for ES18xx driver.");
1958 return -EBUSY; in snd_audiodrive_pnp_init_main()
1960 /* ok. hack using Vendor-Defined Card-Level registers */ in snd_audiodrive_pnp_init_main()
1961 /* skip csn and logdev initialization - already done in isapnp_configure */ in snd_audiodrive_pnp_init_main()
1966 isapnp_write_byte(0x28, pnp_irq(pdev, 0)); /* MPU-401 IRQ Number */ in snd_audiodrive_pnp_init_main()
1984 chip->dev = pdev; in snd_audiodrive_pnp()
1985 if (snd_audiodrive_pnp_init_main(dev, chip->dev) < 0) in snd_audiodrive_pnp()
1986 return -EBUSY; in snd_audiodrive_pnp()
1991 /* ESS 1868 (integrated on Compaq dual P-Pro motherboard and Genius 18PnP 3D) */
2005 /* --- */
2015 chip->dev = pnp_request_card_device(card, id->devs[0].id, NULL); in snd_audiodrive_pnpc()
2016 if (chip->dev == NULL) in snd_audiodrive_pnpc()
2017 return -EBUSY; in snd_audiodrive_pnpc()
2019 chip->devc = pnp_request_card_device(card, id->devs[1].id, NULL); in snd_audiodrive_pnpc()
2020 if (chip->devc == NULL) in snd_audiodrive_pnpc()
2021 return -EBUSY; in snd_audiodrive_pnpc()
2024 if (pnp_activate_dev(chip->devc) < 0) { in snd_audiodrive_pnpc()
2026 return -EAGAIN; in snd_audiodrive_pnpc()
2029 (unsigned long long)pnp_port_start(chip->devc, 0)); in snd_audiodrive_pnpc()
2030 if (snd_audiodrive_pnp_init_main(dev, chip->dev) < 0) in snd_audiodrive_pnpc()
2031 return -EBUSY; in snd_audiodrive_pnpc()
2052 struct snd_es18xx *chip = card->private_data; in snd_audiodrive_probe()
2062 sprintf(card->driver, "ES%x", chip->version); in snd_audiodrive_probe()
2064 sprintf(card->shortname, "ESS AudioDrive ES%x", chip->version); in snd_audiodrive_probe()
2066 sprintf(card->longname, "%s at 0x%lx, irq %d, dma1 %d, dma2 %d", in snd_audiodrive_probe()
2067 card->shortname, in snd_audiodrive_probe()
2068 chip->port, in snd_audiodrive_probe()
2071 sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d", in snd_audiodrive_probe()
2072 card->shortname, in snd_audiodrive_probe()
2073 chip->port, in snd_audiodrive_probe()
2100 -1, &chip->rmidi); in snd_audiodrive_probe()
2131 static const int possible_irqs[] = {5, 9, 10, 7, 11, 12, -1}; in snd_es18xx_isa_probe()
2132 static const int possible_dmas[] = {1, 0, 3, 5, -1}; in snd_es18xx_isa_probe()
2138 return -EBUSY; in snd_es18xx_isa_probe()
2145 return -EBUSY; in snd_es18xx_isa_probe()
2152 return -EBUSY; in snd_es18xx_isa_probe()
2208 return -ENOENT; /* we have another procedure - card */ in snd_audiodrive_pnp_detect()
2214 return -ENODEV; in snd_audiodrive_pnp_detect()
2216 err = snd_es18xx_card_new(&pdev->dev, dev, &card); in snd_audiodrive_pnp_detect()
2219 err = snd_audiodrive_pnp(dev, card->private_data, pdev); in snd_audiodrive_pnp_detect()
2242 .name = "es18xx-pnpbios",
2263 return -ENODEV; in snd_audiodrive_pnpc_detect()
2265 res = snd_es18xx_card_new(&pcard->card->dev, dev, &card); in snd_audiodrive_pnpc_detect()
2269 res = snd_audiodrive_pnpc(dev, card->private_data, pcard, pid); in snd_audiodrive_pnpc_detect()