• Home
  • Raw
  • Download

Lines Matching +full:has +full:- +full:chip +full:- +full:id

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
60 * control has been included to allow ZV to be enabled only when necessary.
88 unsigned long port; /* port of ESS chip */
89 unsigned long ctrl_port; /* Control port of ESS chip */
93 int irq; /* IRQ number of ESS chip */
96 unsigned short version; /* version of ESS chip */
97 int caps; /* Chip capabilities */
132 #define ES18XX_PCM2 0x0001 /* Has two useable PCM */
133 #define ES18XX_SPATIALIZER 0x0002 /* Has 3D Spatializer */
134 #define ES18XX_RECMIX 0x0004 /* Has record mixer */
135 #define ES18XX_DUPLEX_MONO 0x0008 /* Has mono duplex only */
139 #define ES18XX_HWV 0x0080 /* Has separate hardware volume mixer controls*/
143 #define ES18XX_CONTROL 0x0800 /* Has control ports */
162 static int snd_es18xx_dsp_command(struct snd_es18xx *chip, unsigned char val) in snd_es18xx_dsp_command() argument
166 for(i = MILLISECOND; i; i--) in snd_es18xx_dsp_command()
167 if ((inb(chip->port + 0x0C) & 0x80) == 0) { in snd_es18xx_dsp_command()
168 outb(val, chip->port + 0x0C); in snd_es18xx_dsp_command()
172 return -EINVAL; in snd_es18xx_dsp_command()
175 static int snd_es18xx_dsp_get_byte(struct snd_es18xx *chip) in snd_es18xx_dsp_get_byte() argument
179 for(i = MILLISECOND/10; i; i--) in snd_es18xx_dsp_get_byte()
180 if (inb(chip->port + 0x0C) & 0x40) in snd_es18xx_dsp_get_byte()
181 return inb(chip->port + 0x0A); in snd_es18xx_dsp_get_byte()
183 chip->port + 0x0A, inb(chip->port + 0x0A)); in snd_es18xx_dsp_get_byte()
184 return -ENODEV; in snd_es18xx_dsp_get_byte()
189 static int snd_es18xx_write(struct snd_es18xx *chip, in snd_es18xx_write() argument
195 spin_lock_irqsave(&chip->reg_lock, flags); in snd_es18xx_write()
196 ret = snd_es18xx_dsp_command(chip, reg); in snd_es18xx_write()
199 ret = snd_es18xx_dsp_command(chip, data); in snd_es18xx_write()
201 spin_unlock_irqrestore(&chip->reg_lock, flags); in snd_es18xx_write()
208 static int snd_es18xx_read(struct snd_es18xx *chip, unsigned char reg) in snd_es18xx_read() argument
212 spin_lock_irqsave(&chip->reg_lock, flags); in snd_es18xx_read()
213 ret = snd_es18xx_dsp_command(chip, 0xC0); in snd_es18xx_read()
216 ret = snd_es18xx_dsp_command(chip, reg); in snd_es18xx_read()
219 data = snd_es18xx_dsp_get_byte(chip); in snd_es18xx_read()
225 spin_unlock_irqrestore(&chip->reg_lock, flags); in snd_es18xx_read()
230 static int snd_es18xx_bits(struct snd_es18xx *chip, unsigned char reg, in snd_es18xx_bits() argument
236 spin_lock_irqsave(&chip->reg_lock, flags); in snd_es18xx_bits()
237 ret = snd_es18xx_dsp_command(chip, 0xC0); in snd_es18xx_bits()
240 ret = snd_es18xx_dsp_command(chip, reg); in snd_es18xx_bits()
243 ret = snd_es18xx_dsp_get_byte(chip); in snd_es18xx_bits()
250 ret = snd_es18xx_dsp_command(chip, reg); in snd_es18xx_bits()
254 ret = snd_es18xx_dsp_command(chip, new); in snd_es18xx_bits()
264 spin_unlock_irqrestore(&chip->reg_lock, flags); in snd_es18xx_bits()
268 static inline void snd_es18xx_mixer_write(struct snd_es18xx *chip, in snd_es18xx_mixer_write() argument
272 spin_lock_irqsave(&chip->mixer_lock, flags); in snd_es18xx_mixer_write()
273 outb(reg, chip->port + 0x04); in snd_es18xx_mixer_write()
274 outb(data, chip->port + 0x05); in snd_es18xx_mixer_write()
275 spin_unlock_irqrestore(&chip->mixer_lock, flags); in snd_es18xx_mixer_write()
281 static inline int snd_es18xx_mixer_read(struct snd_es18xx *chip, unsigned char reg) in snd_es18xx_mixer_read() argument
285 spin_lock_irqsave(&chip->mixer_lock, flags); in snd_es18xx_mixer_read()
286 outb(reg, chip->port + 0x04); in snd_es18xx_mixer_read()
287 data = inb(chip->port + 0x05); in snd_es18xx_mixer_read()
288 spin_unlock_irqrestore(&chip->mixer_lock, flags); in snd_es18xx_mixer_read()
296 static inline int snd_es18xx_mixer_bits(struct snd_es18xx *chip, unsigned char reg, in snd_es18xx_mixer_bits() argument
301 spin_lock_irqsave(&chip->mixer_lock, flags); in snd_es18xx_mixer_bits()
302 outb(reg, chip->port + 0x04); in snd_es18xx_mixer_bits()
303 old = inb(chip->port + 0x05); in snd_es18xx_mixer_bits()
307 outb(new, chip->port + 0x05); in snd_es18xx_mixer_bits()
313 spin_unlock_irqrestore(&chip->mixer_lock, flags); in snd_es18xx_mixer_bits()
317 static inline int snd_es18xx_mixer_writable(struct snd_es18xx *chip, unsigned char reg, in snd_es18xx_mixer_writable() argument
322 spin_lock_irqsave(&chip->mixer_lock, flags); in snd_es18xx_mixer_writable()
323 outb(reg, chip->port + 0x04); in snd_es18xx_mixer_writable()
324 old = inb(chip->port + 0x05); in snd_es18xx_mixer_writable()
326 outb(expected, chip->port + 0x05); in snd_es18xx_mixer_writable()
327 new = inb(chip->port + 0x05); in snd_es18xx_mixer_writable()
328 spin_unlock_irqrestore(&chip->mixer_lock, flags); in snd_es18xx_mixer_writable()
337 static int snd_es18xx_reset(struct snd_es18xx *chip) in snd_es18xx_reset() argument
340 outb(0x03, chip->port + 0x06); in snd_es18xx_reset()
341 inb(chip->port + 0x06); in snd_es18xx_reset()
342 outb(0x00, chip->port + 0x06); in snd_es18xx_reset()
343 for(i = 0; i < MILLISECOND && !(inb(chip->port + 0x0E) & 0x80); i++); in snd_es18xx_reset()
344 if (inb(chip->port + 0x0A) != 0xAA) in snd_es18xx_reset()
345 return -1; in snd_es18xx_reset()
349 static int snd_es18xx_reset_fifo(struct snd_es18xx *chip) in snd_es18xx_reset_fifo() argument
351 outb(0x02, chip->port + 0x06); in snd_es18xx_reset_fifo()
352 inb(chip->port + 0x06); in snd_es18xx_reset_fifo()
353 outb(0x00, chip->port + 0x06); in snd_es18xx_reset_fifo()
398 static void snd_es18xx_rate_set(struct snd_es18xx *chip, in snd_es18xx_rate_set() argument
403 struct snd_pcm_runtime *runtime = substream->runtime; in snd_es18xx_rate_set()
404 if (chip->caps & ES18XX_NEW_RATE) { in snd_es18xx_rate_set()
405 if (runtime->rate_num == new_clocks[0].num) in snd_es18xx_rate_set()
406 bits = 128 - runtime->rate_den; in snd_es18xx_rate_set()
408 bits = 256 - runtime->rate_den; in snd_es18xx_rate_set()
410 if (runtime->rate_num == old_clocks[0].num) in snd_es18xx_rate_set()
411 bits = 256 - runtime->rate_den; in snd_es18xx_rate_set()
413 bits = 128 - runtime->rate_den; in snd_es18xx_rate_set()
417 div0 = 256 - 7160000*20/(8*82*runtime->rate); in snd_es18xx_rate_set()
419 if ((chip->caps & ES18XX_PCM2) && mode == DAC2) { in snd_es18xx_rate_set()
420 snd_es18xx_mixer_write(chip, 0x70, bits); in snd_es18xx_rate_set()
425 snd_es18xx_write(chip, 0xA2, div0); in snd_es18xx_rate_set()
426 snd_es18xx_mixer_write(chip, 0x72, div0); in snd_es18xx_rate_set()
428 snd_es18xx_write(chip, 0xA1, bits); in snd_es18xx_rate_set()
429 snd_es18xx_write(chip, 0xA2, div0); in snd_es18xx_rate_set()
436 struct snd_es18xx *chip = snd_pcm_substream_chip(substream); in snd_es18xx_playback_hw_params() local
445 if (substream->number == 0 && (chip->caps & ES18XX_PCM2)) { in snd_es18xx_playback_hw_params()
446 if ((chip->caps & ES18XX_DUPLEX_MONO) && in snd_es18xx_playback_hw_params()
447 (chip->capture_a_substream) && in snd_es18xx_playback_hw_params()
450 return -EBUSY; in snd_es18xx_playback_hw_params()
452 chip->dma2_shift = shift; in snd_es18xx_playback_hw_params()
454 chip->dma1_shift = shift; in snd_es18xx_playback_hw_params()
459 static int snd_es18xx_playback1_prepare(struct snd_es18xx *chip, in snd_es18xx_playback1_prepare() argument
462 struct snd_pcm_runtime *runtime = substream->runtime; in snd_es18xx_playback1_prepare()
466 snd_es18xx_rate_set(chip, substream, DAC2); in snd_es18xx_playback1_prepare()
469 count = 0x10000 - count; in snd_es18xx_playback1_prepare()
470 snd_es18xx_mixer_write(chip, 0x74, count & 0xff); in snd_es18xx_playback1_prepare()
471 snd_es18xx_mixer_write(chip, 0x76, count >> 8); in snd_es18xx_playback1_prepare()
474 snd_es18xx_mixer_bits(chip, 0x7A, 0x07, in snd_es18xx_playback1_prepare()
475 ((runtime->channels == 1) ? 0x00 : 0x02) | in snd_es18xx_playback1_prepare()
476 (snd_pcm_format_width(runtime->format) == 16 ? 0x01 : 0x00) | in snd_es18xx_playback1_prepare()
477 (snd_pcm_format_unsigned(runtime->format) ? 0x00 : 0x04)); in snd_es18xx_playback1_prepare()
480 snd_dma_program(chip->dma2, runtime->dma_addr, size, DMA_MODE_WRITE | DMA_AUTOINIT); in snd_es18xx_playback1_prepare()
485 static int snd_es18xx_playback1_trigger(struct snd_es18xx *chip, in snd_es18xx_playback1_trigger() argument
492 if (chip->active & DAC2) in snd_es18xx_playback1_trigger()
494 chip->active |= DAC2; in snd_es18xx_playback1_trigger()
496 if (chip->dma2 >= 4) in snd_es18xx_playback1_trigger()
497 snd_es18xx_mixer_write(chip, 0x78, 0xb3); in snd_es18xx_playback1_trigger()
499 snd_es18xx_mixer_write(chip, 0x78, 0x93); in snd_es18xx_playback1_trigger()
503 if (chip->caps & ES18XX_PCM2) in snd_es18xx_playback1_trigger()
505 snd_es18xx_mixer_write(chip, 0x7C, chip->audio2_vol); in snd_es18xx_playback1_trigger()
508 snd_es18xx_dsp_command(chip, 0xD1); in snd_es18xx_playback1_trigger()
513 if (!(chip->active & DAC2)) in snd_es18xx_playback1_trigger()
515 chip->active &= ~DAC2; in snd_es18xx_playback1_trigger()
517 snd_es18xx_mixer_write(chip, 0x78, 0x00); in snd_es18xx_playback1_trigger()
520 if (chip->caps & ES18XX_PCM2) in snd_es18xx_playback1_trigger()
522 snd_es18xx_mixer_write(chip, 0x7C, 0); in snd_es18xx_playback1_trigger()
525 snd_es18xx_dsp_command(chip, 0xD3); in snd_es18xx_playback1_trigger()
529 return -EINVAL; in snd_es18xx_playback1_trigger()
538 struct snd_es18xx *chip = snd_pcm_substream_chip(substream); in snd_es18xx_capture_hw_params() local
542 if ((chip->caps & ES18XX_DUPLEX_MONO) && in snd_es18xx_capture_hw_params()
543 chip->playback_a_substream && in snd_es18xx_capture_hw_params()
546 return -EBUSY; in snd_es18xx_capture_hw_params()
552 chip->dma1_shift = shift; in snd_es18xx_capture_hw_params()
558 struct snd_es18xx *chip = snd_pcm_substream_chip(substream); in snd_es18xx_capture_prepare() local
559 struct snd_pcm_runtime *runtime = substream->runtime; in snd_es18xx_capture_prepare()
563 snd_es18xx_reset_fifo(chip); in snd_es18xx_capture_prepare()
566 snd_es18xx_bits(chip, 0xA8, 0x03, runtime->channels == 1 ? 0x02 : 0x01); in snd_es18xx_capture_prepare()
568 snd_es18xx_rate_set(chip, substream, ADC1); in snd_es18xx_capture_prepare()
571 count = 0x10000 - count; in snd_es18xx_capture_prepare()
572 snd_es18xx_write(chip, 0xA4, count & 0xff); in snd_es18xx_capture_prepare()
573 snd_es18xx_write(chip, 0xA5, count >> 8); in snd_es18xx_capture_prepare()
580 snd_es18xx_write(chip, 0xB7, in snd_es18xx_capture_prepare()
581 snd_pcm_format_unsigned(runtime->format) ? 0x51 : 0x71); in snd_es18xx_capture_prepare()
582 snd_es18xx_write(chip, 0xB7, 0x90 | in snd_es18xx_capture_prepare()
583 ((runtime->channels == 1) ? 0x40 : 0x08) | in snd_es18xx_capture_prepare()
584 (snd_pcm_format_width(runtime->format) == 16 ? 0x04 : 0x00) | in snd_es18xx_capture_prepare()
585 (snd_pcm_format_unsigned(runtime->format) ? 0x00 : 0x20)); in snd_es18xx_capture_prepare()
588 snd_dma_program(chip->dma1, runtime->dma_addr, size, DMA_MODE_READ | DMA_AUTOINIT); in snd_es18xx_capture_prepare()
596 struct snd_es18xx *chip = snd_pcm_substream_chip(substream); in snd_es18xx_capture_trigger() local
601 if (chip->active & ADC1) in snd_es18xx_capture_trigger()
603 chip->active |= ADC1; in snd_es18xx_capture_trigger()
605 snd_es18xx_write(chip, 0xB8, 0x0f); in snd_es18xx_capture_trigger()
609 if (!(chip->active & ADC1)) in snd_es18xx_capture_trigger()
611 chip->active &= ~ADC1; in snd_es18xx_capture_trigger()
613 snd_es18xx_write(chip, 0xB8, 0x00); in snd_es18xx_capture_trigger()
616 return -EINVAL; in snd_es18xx_capture_trigger()
622 static int snd_es18xx_playback2_prepare(struct snd_es18xx *chip, in snd_es18xx_playback2_prepare() argument
625 struct snd_pcm_runtime *runtime = substream->runtime; in snd_es18xx_playback2_prepare()
629 snd_es18xx_reset_fifo(chip); in snd_es18xx_playback2_prepare()
632 snd_es18xx_bits(chip, 0xA8, 0x03, runtime->channels == 1 ? 0x02 : 0x01); in snd_es18xx_playback2_prepare()
634 snd_es18xx_rate_set(chip, substream, DAC1); in snd_es18xx_playback2_prepare()
637 count = 0x10000 - count; in snd_es18xx_playback2_prepare()
638 snd_es18xx_write(chip, 0xA4, count & 0xff); in snd_es18xx_playback2_prepare()
639 snd_es18xx_write(chip, 0xA5, count >> 8); in snd_es18xx_playback2_prepare()
642 snd_es18xx_write(chip, 0xB6, in snd_es18xx_playback2_prepare()
643 snd_pcm_format_unsigned(runtime->format) ? 0x80 : 0x00); in snd_es18xx_playback2_prepare()
644 snd_es18xx_write(chip, 0xB7, in snd_es18xx_playback2_prepare()
645 snd_pcm_format_unsigned(runtime->format) ? 0x51 : 0x71); in snd_es18xx_playback2_prepare()
646 snd_es18xx_write(chip, 0xB7, 0x90 | in snd_es18xx_playback2_prepare()
647 (runtime->channels == 1 ? 0x40 : 0x08) | in snd_es18xx_playback2_prepare()
648 (snd_pcm_format_width(runtime->format) == 16 ? 0x04 : 0x00) | in snd_es18xx_playback2_prepare()
649 (snd_pcm_format_unsigned(runtime->format) ? 0x00 : 0x20)); in snd_es18xx_playback2_prepare()
652 snd_dma_program(chip->dma1, runtime->dma_addr, size, DMA_MODE_WRITE | DMA_AUTOINIT); in snd_es18xx_playback2_prepare()
657 static int snd_es18xx_playback2_trigger(struct snd_es18xx *chip, in snd_es18xx_playback2_trigger() argument
664 if (chip->active & DAC1) in snd_es18xx_playback2_trigger()
666 chip->active |= DAC1; in snd_es18xx_playback2_trigger()
668 snd_es18xx_write(chip, 0xB8, 0x05); in snd_es18xx_playback2_trigger()
673 snd_es18xx_dsp_command(chip, 0xD1); in snd_es18xx_playback2_trigger()
678 if (!(chip->active & DAC1)) in snd_es18xx_playback2_trigger()
680 chip->active &= ~DAC1; in snd_es18xx_playback2_trigger()
682 snd_es18xx_write(chip, 0xB8, 0x00); in snd_es18xx_playback2_trigger()
687 snd_es18xx_dsp_command(chip, 0xD3); in snd_es18xx_playback2_trigger()
691 return -EINVAL; in snd_es18xx_playback2_trigger()
699 struct snd_es18xx *chip = snd_pcm_substream_chip(substream); in snd_es18xx_playback_prepare() local
700 if (substream->number == 0 && (chip->caps & ES18XX_PCM2)) in snd_es18xx_playback_prepare()
701 return snd_es18xx_playback1_prepare(chip, substream); in snd_es18xx_playback_prepare()
703 return snd_es18xx_playback2_prepare(chip, substream); in snd_es18xx_playback_prepare()
709 struct snd_es18xx *chip = snd_pcm_substream_chip(substream); in snd_es18xx_playback_trigger() local
710 if (substream->number == 0 && (chip->caps & ES18XX_PCM2)) in snd_es18xx_playback_trigger()
711 return snd_es18xx_playback1_trigger(chip, substream, cmd); in snd_es18xx_playback_trigger()
713 return snd_es18xx_playback2_trigger(chip, substream, cmd); in snd_es18xx_playback_trigger()
719 struct snd_es18xx *chip = card->private_data; in snd_es18xx_interrupt() local
722 if (chip->caps & ES18XX_CONTROL) { in snd_es18xx_interrupt()
724 status = inb(chip->ctrl_port + 6); in snd_es18xx_interrupt()
727 status = snd_es18xx_mixer_read(chip, 0x7f) >> 4; in snd_es18xx_interrupt()
732 if (inb(chip->port + 0x0C) & 0x01) in snd_es18xx_interrupt()
734 if (snd_es18xx_mixer_read(chip, 0x7A) & 0x80) in snd_es18xx_interrupt()
736 if ((chip->caps & ES18XX_HWV) && in snd_es18xx_interrupt()
737 snd_es18xx_mixer_read(chip, 0x64) & 0x10) in snd_es18xx_interrupt()
744 if (chip->active & DAC2) in snd_es18xx_interrupt()
745 snd_pcm_period_elapsed(chip->playback_a_substream); in snd_es18xx_interrupt()
747 snd_es18xx_mixer_bits(chip, 0x7A, 0x80, 0x00); in snd_es18xx_interrupt()
751 if (chip->active & ADC1) in snd_es18xx_interrupt()
752 snd_pcm_period_elapsed(chip->capture_a_substream); in snd_es18xx_interrupt()
754 else if (chip->active & DAC1) in snd_es18xx_interrupt()
755 snd_pcm_period_elapsed(chip->playback_b_substream); in snd_es18xx_interrupt()
757 inb(chip->port + 0x0E); in snd_es18xx_interrupt()
761 if ((status & MPU_IRQ) && chip->rmidi) in snd_es18xx_interrupt()
762 snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data); in snd_es18xx_interrupt()
767 if (chip->caps & ES18XX_HWV) { in snd_es18xx_interrupt()
768 split = snd_es18xx_mixer_read(chip, 0x64) & 0x80; in snd_es18xx_interrupt()
770 &chip->hw_switch->id); in snd_es18xx_interrupt()
772 &chip->hw_volume->id); in snd_es18xx_interrupt()
776 &chip->master_switch->id); in snd_es18xx_interrupt()
778 &chip->master_volume->id); in snd_es18xx_interrupt()
781 snd_es18xx_mixer_write(chip, 0x66, 0x00); in snd_es18xx_interrupt()
788 struct snd_es18xx *chip = snd_pcm_substream_chip(substream); in snd_es18xx_playback_pointer() local
792 if (substream->number == 0 && (chip->caps & ES18XX_PCM2)) { in snd_es18xx_playback_pointer()
793 if (!(chip->active & DAC2)) in snd_es18xx_playback_pointer()
795 pos = snd_dma_pointer(chip->dma2, size); in snd_es18xx_playback_pointer()
796 return pos >> chip->dma2_shift; in snd_es18xx_playback_pointer()
798 if (!(chip->active & DAC1)) in snd_es18xx_playback_pointer()
800 pos = snd_dma_pointer(chip->dma1, size); in snd_es18xx_playback_pointer()
801 return pos >> chip->dma1_shift; in snd_es18xx_playback_pointer()
807 struct snd_es18xx *chip = snd_pcm_substream_chip(substream); in snd_es18xx_capture_pointer() local
811 if (!(chip->active & ADC1)) in snd_es18xx_capture_pointer()
813 pos = snd_dma_pointer(chip->dma1, size); in snd_es18xx_capture_pointer()
814 return pos >> chip->dma1_shift; in snd_es18xx_capture_pointer()
859 struct snd_pcm_runtime *runtime = substream->runtime; in snd_es18xx_playback_open()
860 struct snd_es18xx *chip = snd_pcm_substream_chip(substream); in snd_es18xx_playback_open() local
862 if (substream->number == 0 && (chip->caps & ES18XX_PCM2)) { in snd_es18xx_playback_open()
863 if ((chip->caps & ES18XX_DUPLEX_MONO) && in snd_es18xx_playback_open()
864 chip->capture_a_substream && in snd_es18xx_playback_open()
865 chip->capture_a_substream->runtime->channels != 1) in snd_es18xx_playback_open()
866 return -EAGAIN; in snd_es18xx_playback_open()
867 chip->playback_a_substream = substream; in snd_es18xx_playback_open()
868 } else if (substream->number <= 1) { in snd_es18xx_playback_open()
869 if (chip->capture_a_substream) in snd_es18xx_playback_open()
870 return -EAGAIN; in snd_es18xx_playback_open()
871 chip->playback_b_substream = substream; in snd_es18xx_playback_open()
874 return -EINVAL; in snd_es18xx_playback_open()
876 substream->runtime->hw = snd_es18xx_playback; in snd_es18xx_playback_open()
878 (chip->caps & ES18XX_NEW_RATE) ? &new_hw_constraints_clocks : &old_hw_constraints_clocks); in snd_es18xx_playback_open()
884 struct snd_pcm_runtime *runtime = substream->runtime; in snd_es18xx_capture_open()
885 struct snd_es18xx *chip = snd_pcm_substream_chip(substream); in snd_es18xx_capture_open() local
887 if (chip->playback_b_substream) in snd_es18xx_capture_open()
888 return -EAGAIN; in snd_es18xx_capture_open()
889 if ((chip->caps & ES18XX_DUPLEX_MONO) && in snd_es18xx_capture_open()
890 chip->playback_a_substream && in snd_es18xx_capture_open()
891 chip->playback_a_substream->runtime->channels != 1) in snd_es18xx_capture_open()
892 return -EAGAIN; in snd_es18xx_capture_open()
893 chip->capture_a_substream = substream; in snd_es18xx_capture_open()
894 substream->runtime->hw = snd_es18xx_capture; in snd_es18xx_capture_open()
896 (chip->caps & ES18XX_NEW_RATE) ? &new_hw_constraints_clocks : &old_hw_constraints_clocks); in snd_es18xx_capture_open()
902 struct snd_es18xx *chip = snd_pcm_substream_chip(substream); in snd_es18xx_playback_close() local
904 if (substream->number == 0 && (chip->caps & ES18XX_PCM2)) in snd_es18xx_playback_close()
905 chip->playback_a_substream = NULL; in snd_es18xx_playback_close()
907 chip->playback_b_substream = NULL; in snd_es18xx_playback_close()
914 struct snd_es18xx *chip = snd_pcm_substream_chip(substream); in snd_es18xx_capture_close() local
916 chip->capture_a_substream = NULL; in snd_es18xx_capture_close()
949 struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol); in snd_es18xx_info_mux() local
951 switch (chip->version) { in snd_es18xx_info_mux()
962 return -EINVAL; in snd_es18xx_info_mux()
969 struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol); in snd_es18xx_get_mux() local
970 int muxSource = snd_es18xx_mixer_read(chip, 0x1c) & 0x07; in snd_es18xx_get_mux()
971 if (!(chip->version == 0x1869 || chip->version == 0x1879)) { in snd_es18xx_get_mux()
974 (chip->version == 0x1887 || chip->version == 0x1888) && in snd_es18xx_get_mux()
975 (snd_es18xx_mixer_read(chip, 0x7a) & 0x08) in snd_es18xx_get_mux()
979 ucontrol->value.enumerated.item[0] = muxSource; in snd_es18xx_get_mux()
986 struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol); in snd_es18xx_put_mux() local
987 unsigned char val = ucontrol->value.enumerated.item[0]; in snd_es18xx_put_mux()
990 switch (chip->version) { in snd_es18xx_put_mux()
995 return -EINVAL; in snd_es18xx_put_mux()
997 retVal = snd_es18xx_mixer_bits(chip, 0x7a, 0x08, 0x08) != 0x08; in snd_es18xx_put_mux()
1000 retVal = snd_es18xx_mixer_bits(chip, 0x7a, 0x08, 0x00) != 0x00; in snd_es18xx_put_mux()
1006 return -EINVAL; in snd_es18xx_put_mux()
1013 return -EINVAL; in snd_es18xx_put_mux()
1016 return -EINVAL; in snd_es18xx_put_mux()
1018 return (snd_es18xx_mixer_bits(chip, 0x1c, 0x07, val) != val) || retVal; in snd_es18xx_put_mux()
1025 struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol); in snd_es18xx_get_spatializer_enable() local
1026 unsigned char val = snd_es18xx_mixer_read(chip, 0x50); in snd_es18xx_get_spatializer_enable()
1027 ucontrol->value.integer.value[0] = !!(val & 8); in snd_es18xx_get_spatializer_enable()
1033 struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol); in snd_es18xx_put_spatializer_enable() local
1036 nval = ucontrol->value.integer.value[0] ? 0x0c : 0x04; in snd_es18xx_put_spatializer_enable()
1037 oval = snd_es18xx_mixer_read(chip, 0x50) & 0x0c; in snd_es18xx_put_spatializer_enable()
1040 snd_es18xx_mixer_write(chip, 0x50, nval & ~0x04); in snd_es18xx_put_spatializer_enable()
1041 snd_es18xx_mixer_write(chip, 0x50, nval); in snd_es18xx_put_spatializer_enable()
1048 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in snd_es18xx_info_hw_volume()
1049 uinfo->count = 2; in snd_es18xx_info_hw_volume()
1050 uinfo->value.integer.min = 0; in snd_es18xx_info_hw_volume()
1051 uinfo->value.integer.max = 63; in snd_es18xx_info_hw_volume()
1057 struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol); in snd_es18xx_get_hw_volume() local
1058 ucontrol->value.integer.value[0] = snd_es18xx_mixer_read(chip, 0x61) & 0x3f; in snd_es18xx_get_hw_volume()
1059 ucontrol->value.integer.value[1] = snd_es18xx_mixer_read(chip, 0x63) & 0x3f; in snd_es18xx_get_hw_volume()
1067 struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol); in snd_es18xx_get_hw_switch() local
1068 ucontrol->value.integer.value[0] = !(snd_es18xx_mixer_read(chip, 0x61) & 0x40); in snd_es18xx_get_hw_switch()
1069 ucontrol->value.integer.value[1] = !(snd_es18xx_mixer_read(chip, 0x63) & 0x40); in snd_es18xx_get_hw_switch()
1075 struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol); in snd_es18xx_hwv_free() local
1076 chip->master_volume = NULL; in snd_es18xx_hwv_free()
1077 chip->master_switch = NULL; in snd_es18xx_hwv_free()
1078 chip->hw_volume = NULL; in snd_es18xx_hwv_free()
1079 chip->hw_switch = NULL; in snd_es18xx_hwv_free()
1082 static int snd_es18xx_reg_bits(struct snd_es18xx *chip, unsigned char reg, in snd_es18xx_reg_bits() argument
1086 return snd_es18xx_mixer_bits(chip, reg, mask, val); in snd_es18xx_reg_bits()
1088 return snd_es18xx_bits(chip, reg, mask, val); in snd_es18xx_reg_bits()
1091 static int snd_es18xx_reg_read(struct snd_es18xx *chip, unsigned char reg) in snd_es18xx_reg_read() argument
1094 return snd_es18xx_mixer_read(chip, reg); in snd_es18xx_reg_read()
1096 return snd_es18xx_read(chip, reg); in snd_es18xx_reg_read()
1110 int mask = (kcontrol->private_value >> 16) & 0xff; in snd_es18xx_info_single()
1112 uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER; in snd_es18xx_info_single()
1113 uinfo->count = 1; in snd_es18xx_info_single()
1114 uinfo->value.integer.min = 0; in snd_es18xx_info_single()
1115 uinfo->value.integer.max = mask; in snd_es18xx_info_single()
1121 struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol); in snd_es18xx_get_single() local
1122 int reg = kcontrol->private_value & 0xff; in snd_es18xx_get_single()
1123 int shift = (kcontrol->private_value >> 8) & 0xff; in snd_es18xx_get_single()
1124 int mask = (kcontrol->private_value >> 16) & 0xff; in snd_es18xx_get_single()
1125 int invert = (kcontrol->private_value >> 24) & ES18XX_FL_INVERT; in snd_es18xx_get_single()
1126 int pm_port = (kcontrol->private_value >> 24) & ES18XX_FL_PMPORT; in snd_es18xx_get_single()
1130 val = inb(chip->port + ES18XX_PM); in snd_es18xx_get_single()
1132 val = snd_es18xx_reg_read(chip, reg); in snd_es18xx_get_single()
1133 ucontrol->value.integer.value[0] = (val >> shift) & mask; in snd_es18xx_get_single()
1135 ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0]; in snd_es18xx_get_single()
1141 struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol); in snd_es18xx_put_single() local
1142 int reg = kcontrol->private_value & 0xff; in snd_es18xx_put_single()
1143 int shift = (kcontrol->private_value >> 8) & 0xff; in snd_es18xx_put_single()
1144 int mask = (kcontrol->private_value >> 16) & 0xff; in snd_es18xx_put_single()
1145 int invert = (kcontrol->private_value >> 24) & ES18XX_FL_INVERT; in snd_es18xx_put_single()
1146 int pm_port = (kcontrol->private_value >> 24) & ES18XX_FL_PMPORT; in snd_es18xx_put_single()
1149 val = (ucontrol->value.integer.value[0] & mask); in snd_es18xx_put_single()
1151 val = mask - val; in snd_es18xx_put_single()
1155 unsigned char cur = inb(chip->port + ES18XX_PM); in snd_es18xx_put_single()
1159 outb((cur & ~mask) | val, chip->port + ES18XX_PM); in snd_es18xx_put_single()
1163 return snd_es18xx_reg_bits(chip, reg, mask, val) != val; in snd_es18xx_put_single()
1174 int mask = (kcontrol->private_value >> 24) & 0xff; in snd_es18xx_info_double()
1176 uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER; in snd_es18xx_info_double()
1177 uinfo->count = 2; in snd_es18xx_info_double()
1178 uinfo->value.integer.min = 0; in snd_es18xx_info_double()
1179 uinfo->value.integer.max = mask; in snd_es18xx_info_double()
1185 struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol); in snd_es18xx_get_double() local
1186 int left_reg = kcontrol->private_value & 0xff; in snd_es18xx_get_double()
1187 int right_reg = (kcontrol->private_value >> 8) & 0xff; in snd_es18xx_get_double()
1188 int shift_left = (kcontrol->private_value >> 16) & 0x07; in snd_es18xx_get_double()
1189 int shift_right = (kcontrol->private_value >> 19) & 0x07; in snd_es18xx_get_double()
1190 int mask = (kcontrol->private_value >> 24) & 0xff; in snd_es18xx_get_double()
1191 int invert = (kcontrol->private_value >> 22) & 1; in snd_es18xx_get_double()
1194 left = snd_es18xx_reg_read(chip, left_reg); in snd_es18xx_get_double()
1196 right = snd_es18xx_reg_read(chip, right_reg); in snd_es18xx_get_double()
1199 ucontrol->value.integer.value[0] = (left >> shift_left) & mask; in snd_es18xx_get_double()
1200 ucontrol->value.integer.value[1] = (right >> shift_right) & mask; in snd_es18xx_get_double()
1202 ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0]; in snd_es18xx_get_double()
1203 ucontrol->value.integer.value[1] = mask - ucontrol->value.integer.value[1]; in snd_es18xx_get_double()
1210 struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol); in snd_es18xx_put_double() local
1211 int left_reg = kcontrol->private_value & 0xff; in snd_es18xx_put_double()
1212 int right_reg = (kcontrol->private_value >> 8) & 0xff; in snd_es18xx_put_double()
1213 int shift_left = (kcontrol->private_value >> 16) & 0x07; in snd_es18xx_put_double()
1214 int shift_right = (kcontrol->private_value >> 19) & 0x07; in snd_es18xx_put_double()
1215 int mask = (kcontrol->private_value >> 24) & 0xff; in snd_es18xx_put_double()
1216 int invert = (kcontrol->private_value >> 22) & 1; in snd_es18xx_put_double()
1220 val1 = ucontrol->value.integer.value[0] & mask; in snd_es18xx_put_double()
1221 val2 = ucontrol->value.integer.value[1] & mask; in snd_es18xx_put_double()
1223 val1 = mask - val1; in snd_es18xx_put_double()
1224 val2 = mask - val2; in snd_es18xx_put_double()
1232 if (snd_es18xx_reg_bits(chip, left_reg, mask1, val1) != val1) in snd_es18xx_put_double()
1234 if (snd_es18xx_reg_bits(chip, right_reg, mask2, val2) != val2) in snd_es18xx_put_double()
1237 change = (snd_es18xx_reg_bits(chip, left_reg, mask1 | mask2, in snd_es18xx_put_double()
1309 ES18XX_SINGLE("3D Control - Level", 0, 0x52, 0, 63, 0),
1312 .name = "3D Control - Switch",
1348 static int snd_es18xx_config_read(struct snd_es18xx *chip, unsigned char reg) in snd_es18xx_config_read() argument
1352 outb(reg, chip->ctrl_port); in snd_es18xx_config_read()
1353 data = inb(chip->ctrl_port + 1); in snd_es18xx_config_read()
1357 static void snd_es18xx_config_write(struct snd_es18xx *chip, in snd_es18xx_config_write() argument
1362 outb(reg, chip->ctrl_port); in snd_es18xx_config_write()
1363 outb(data, chip->ctrl_port + 1); in snd_es18xx_config_write()
1369 static int snd_es18xx_initialize(struct snd_es18xx *chip, in snd_es18xx_initialize() argument
1376 snd_es18xx_dsp_command(chip, 0xC6); in snd_es18xx_initialize()
1378 snd_es18xx_mixer_write(chip, 0x00, 0x00); in snd_es18xx_initialize()
1381 snd_es18xx_write(chip, 0xB9, 2); in snd_es18xx_initialize()
1382 if (chip->caps & ES18XX_CONTROL) { in snd_es18xx_initialize()
1384 snd_es18xx_config_write(chip, 0x27, chip->irq); in snd_es18xx_initialize()
1387 snd_es18xx_config_write(chip, 0x62, fm_port >> 8); in snd_es18xx_initialize()
1388 snd_es18xx_config_write(chip, 0x63, fm_port & 0xff); in snd_es18xx_initialize()
1391 /* MPU-401 I/O */ in snd_es18xx_initialize()
1392 snd_es18xx_config_write(chip, 0x64, mpu_port >> 8); in snd_es18xx_initialize()
1393 snd_es18xx_config_write(chip, 0x65, mpu_port & 0xff); in snd_es18xx_initialize()
1394 /* MPU-401 IRQ */ in snd_es18xx_initialize()
1395 snd_es18xx_config_write(chip, 0x28, chip->irq); in snd_es18xx_initialize()
1398 snd_es18xx_config_write(chip, 0x70, chip->irq); in snd_es18xx_initialize()
1400 snd_es18xx_config_write(chip, 0x72, chip->irq); in snd_es18xx_initialize()
1402 snd_es18xx_config_write(chip, 0x74, chip->dma1); in snd_es18xx_initialize()
1404 snd_es18xx_config_write(chip, 0x75, chip->dma2); in snd_es18xx_initialize()
1407 snd_es18xx_write(chip, 0xB1, 0x50); in snd_es18xx_initialize()
1409 snd_es18xx_mixer_write(chip, 0x7A, 0x40); in snd_es18xx_initialize()
1411 snd_es18xx_write(chip, 0xB2, 0x50); in snd_es18xx_initialize()
1413 snd_es18xx_mixer_write(chip, 0x64, 0x42); in snd_es18xx_initialize()
1415 snd_es18xx_mixer_bits(chip, 0x48, 0x10, 0x10); in snd_es18xx_initialize()
1419 switch (chip->irq) { in snd_es18xx_initialize()
1434 snd_printk(KERN_ERR "invalid irq %d\n", chip->irq); in snd_es18xx_initialize()
1435 return -ENODEV; in snd_es18xx_initialize()
1437 switch (chip->dma1) { in snd_es18xx_initialize()
1448 snd_printk(KERN_ERR "invalid dma1 %d\n", chip->dma1); in snd_es18xx_initialize()
1449 return -ENODEV; in snd_es18xx_initialize()
1451 switch (chip->dma2) { in snd_es18xx_initialize()
1465 snd_printk(KERN_ERR "invalid dma2 %d\n", chip->dma2); in snd_es18xx_initialize()
1466 return -ENODEV; in snd_es18xx_initialize()
1470 snd_es18xx_write(chip, 0xB1, 0x50 | (irqmask << 2)); in snd_es18xx_initialize()
1472 snd_es18xx_write(chip, 0xB2, 0x50 | (dma1mask << 2)); in snd_es18xx_initialize()
1474 snd_es18xx_mixer_bits(chip, 0x7d, 0x07, 0x04 | dma2mask); in snd_es18xx_initialize()
1477 snd_es18xx_mixer_write(chip, 0x7A, 0x68); in snd_es18xx_initialize()
1479 snd_es18xx_mixer_write(chip, 0x64, 0x06); in snd_es18xx_initialize()
1484 snd_es18xx_mixer_write(chip, 0x40, in snd_es18xx_initialize()
1487 snd_es18xx_mixer_write(chip, 0x7f, ((irqmask + 1) << 1) | 0x01); in snd_es18xx_initialize()
1489 if (chip->caps & ES18XX_NEW_RATE) { in snd_es18xx_initialize()
1493 snd_es18xx_mixer_write(chip, 0x71, 0x32); in snd_es18xx_initialize()
1495 if (!(chip->caps & ES18XX_PCM2)) { in snd_es18xx_initialize()
1497 snd_es18xx_write(chip, 0xB7, 0x80); in snd_es18xx_initialize()
1499 if (chip->caps & ES18XX_SPATIALIZER) { in snd_es18xx_initialize()
1501 snd_es18xx_mixer_write(chip, 0x54, 0x8f); in snd_es18xx_initialize()
1502 snd_es18xx_mixer_write(chip, 0x56, 0x95); in snd_es18xx_initialize()
1503 snd_es18xx_mixer_write(chip, 0x58, 0x94); in snd_es18xx_initialize()
1504 snd_es18xx_mixer_write(chip, 0x5a, 0x80); in snd_es18xx_initialize()
1507 switch (chip->version) { in snd_es18xx_initialize()
1510 //so a Switch control has been added to toggle this 0x71 bit on/off: in snd_es18xx_initialize()
1511 //snd_es18xx_mixer_bits(chip, 0x71, 0x40, 0x40); in snd_es18xx_initialize()
1514 snd_es18xx_config_write(chip, 0x29, snd_es18xx_config_read(chip, 0x29) | 0x40); in snd_es18xx_initialize()
1518 if (chip->caps & ES18XX_MUTEREC) in snd_es18xx_initialize()
1520 if (chip->caps & ES18XX_RECMIX) in snd_es18xx_initialize()
1521 snd_es18xx_mixer_write(chip, 0x1c, 0x05 | mask); in snd_es18xx_initialize()
1523 snd_es18xx_mixer_write(chip, 0x1c, 0x00 | mask); in snd_es18xx_initialize()
1524 snd_es18xx_write(chip, 0xb4, 0x00); in snd_es18xx_initialize()
1528 snd_es18xx_dsp_command(chip, 0xD1); in snd_es18xx_initialize()
1534 static int snd_es18xx_identify(struct snd_es18xx *chip) in snd_es18xx_identify() argument
1539 if (snd_es18xx_reset(chip) < 0) { in snd_es18xx_identify()
1540 snd_printk(KERN_ERR "reset at 0x%lx failed!!!\n", chip->port); in snd_es18xx_identify()
1541 return -ENODEV; in snd_es18xx_identify()
1544 snd_es18xx_dsp_command(chip, 0xe7); in snd_es18xx_identify()
1545 hi = snd_es18xx_dsp_get_byte(chip); in snd_es18xx_identify()
1549 lo = snd_es18xx_dsp_get_byte(chip); in snd_es18xx_identify()
1551 return -ENODEV; in snd_es18xx_identify()
1554 chip->version = 0x488; in snd_es18xx_identify()
1558 return -ENODEV; in snd_es18xx_identify()
1561 chip->version = 0x688; in snd_es18xx_identify()
1565 outb(0x40, chip->port + 0x04); in snd_es18xx_identify()
1567 hi = inb(chip->port + 0x05); in snd_es18xx_identify()
1569 lo = inb(chip->port + 0x05); in snd_es18xx_identify()
1571 chip->version = hi << 8 | lo; in snd_es18xx_identify()
1572 chip->ctrl_port = inb(chip->port + 0x05) << 8; in snd_es18xx_identify()
1574 chip->ctrl_port += inb(chip->port + 0x05); in snd_es18xx_identify()
1576 if ((chip->res_ctrl_port = request_region(chip->ctrl_port, 8, "ES18xx - CTRL")) == NULL) { in snd_es18xx_identify()
1577 snd_printk(KERN_ERR PFX "unable go grab port 0x%lx\n", chip->ctrl_port); in snd_es18xx_identify()
1578 return -EBUSY; in snd_es18xx_identify()
1584 /* If has Hardware volume */ in snd_es18xx_identify()
1585 if (snd_es18xx_mixer_writable(chip, 0x64, 0x04)) { in snd_es18xx_identify()
1586 /* If has Audio2 */ in snd_es18xx_identify()
1587 if (snd_es18xx_mixer_writable(chip, 0x70, 0x7f)) { in snd_es18xx_identify()
1588 /* If has volume count */ in snd_es18xx_identify()
1589 if (snd_es18xx_mixer_writable(chip, 0x64, 0x20)) { in snd_es18xx_identify()
1590 chip->version = 0x1887; in snd_es18xx_identify()
1592 chip->version = 0x1888; in snd_es18xx_identify()
1595 chip->version = 0x1788; in snd_es18xx_identify()
1599 chip->version = 0x1688; in snd_es18xx_identify()
1603 static int snd_es18xx_probe(struct snd_es18xx *chip, in snd_es18xx_probe() argument
1607 if (snd_es18xx_identify(chip) < 0) { in snd_es18xx_probe()
1608 snd_printk(KERN_ERR PFX "[0x%lx] ESS chip not found\n", chip->port); in snd_es18xx_probe()
1609 return -ENODEV; in snd_es18xx_probe()
1612 switch (chip->version) { in snd_es18xx_probe()
1614 chip->caps = ES18XX_DUPLEX_MONO | ES18XX_DUPLEX_SAME | ES18XX_CONTROL | ES18XX_GPO_2BIT; in snd_es18xx_probe()
1617chip->caps = ES18XX_PCM2 | ES18XX_SPATIALIZER | ES18XX_RECMIX | ES18XX_NEW_RATE | ES18XX_AUXB | ES… in snd_es18xx_probe()
1620 chip->caps = ES18XX_DUPLEX_MONO | ES18XX_DUPLEX_SAME | ES18XX_I2S | ES18XX_CONTROL; in snd_es18xx_probe()
1623chip->caps = ES18XX_PCM2 | ES18XX_SPATIALIZER | ES18XX_RECMIX | ES18XX_NEW_RATE | ES18XX_AUXB | ES… in snd_es18xx_probe()
1627 chip->caps = ES18XX_PCM2 | ES18XX_RECMIX | ES18XX_AUXB | ES18XX_DUPLEX_SAME | ES18XX_GPO_2BIT; in snd_es18xx_probe()
1630 snd_printk(KERN_ERR "[0x%lx] unsupported chip ES%x\n", in snd_es18xx_probe()
1631 chip->port, chip->version); in snd_es18xx_probe()
1632 return -ENODEV; in snd_es18xx_probe()
1635 snd_printd("[0x%lx] ESS%x chip found\n", chip->port, chip->version); in snd_es18xx_probe()
1637 if (chip->dma1 == chip->dma2) in snd_es18xx_probe()
1638 chip->caps &= ~(ES18XX_PCM2 | ES18XX_DUPLEX_SAME); in snd_es18xx_probe()
1640 return snd_es18xx_initialize(chip, mpu_port, fm_port); in snd_es18xx_probe()
1663 struct snd_es18xx *chip = card->private_data; in snd_es18xx_pcm() local
1668 sprintf(str, "ES%x", chip->version); in snd_es18xx_pcm()
1669 if (chip->caps & ES18XX_PCM2) in snd_es18xx_pcm()
1680 pcm->private_data = chip; in snd_es18xx_pcm()
1681 pcm->info_flags = 0; in snd_es18xx_pcm()
1682 if (chip->caps & ES18XX_DUPLEX_SAME) in snd_es18xx_pcm()
1683 pcm->info_flags |= SNDRV_PCM_INFO_JOINT_DUPLEX; in snd_es18xx_pcm()
1684 if (! (chip->caps & ES18XX_PCM2)) in snd_es18xx_pcm()
1685 pcm->info_flags |= SNDRV_PCM_INFO_HALF_DUPLEX; in snd_es18xx_pcm()
1686 sprintf(pcm->name, "ESS AudioDrive ES%x", chip->version); in snd_es18xx_pcm()
1687 chip->pcm = pcm; in snd_es18xx_pcm()
1689 snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV, card->dev, in snd_es18xx_pcm()
1691 chip->dma1 > 3 || chip->dma2 > 3 ? 128*1024 : 64*1024); in snd_es18xx_pcm()
1699 struct snd_es18xx *chip = card->private_data; in snd_es18xx_suspend() local
1704 chip->pm_reg = (unsigned char)snd_es18xx_read(chip, ES18XX_PM); in snd_es18xx_suspend()
1705 chip->pm_reg |= (ES18XX_PM_FM | ES18XX_PM_SUS); in snd_es18xx_suspend()
1706 snd_es18xx_write(chip, ES18XX_PM, chip->pm_reg); in snd_es18xx_suspend()
1707 snd_es18xx_write(chip, ES18XX_PM, chip->pm_reg ^= ES18XX_PM_SUS); in snd_es18xx_suspend()
1714 struct snd_es18xx *chip = card->private_data; in snd_es18xx_resume() local
1717 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_free() local
1728 release_and_free_resource(chip->res_port); in snd_es18xx_free()
1729 release_and_free_resource(chip->res_ctrl_port); in snd_es18xx_free()
1730 release_and_free_resource(chip->res_mpu_port); in snd_es18xx_free()
1731 if (chip->irq >= 0) in snd_es18xx_free()
1732 free_irq(chip->irq, (void *) card); in snd_es18xx_free()
1733 if (chip->dma1 >= 0) { in snd_es18xx_free()
1734 disable_dma(chip->dma1); in snd_es18xx_free()
1735 free_dma(chip->dma1); in snd_es18xx_free()
1737 if (chip->dma2 >= 0 && chip->dma1 != chip->dma2) { in snd_es18xx_free()
1738 disable_dma(chip->dma2); in snd_es18xx_free()
1739 free_dma(chip->dma2); in snd_es18xx_free()
1746 return snd_es18xx_free(device->card); in snd_es18xx_dev_free()
1755 struct snd_es18xx *chip = card->private_data; in snd_es18xx_new_device() local
1761 spin_lock_init(&chip->reg_lock); in snd_es18xx_new_device()
1762 spin_lock_init(&chip->mixer_lock); in snd_es18xx_new_device()
1763 chip->port = port; in snd_es18xx_new_device()
1764 chip->irq = -1; in snd_es18xx_new_device()
1765 chip->dma1 = -1; in snd_es18xx_new_device()
1766 chip->dma2 = -1; in snd_es18xx_new_device()
1767 chip->audio2_vol = 0x00; in snd_es18xx_new_device()
1768 chip->active = 0; in snd_es18xx_new_device()
1770 chip->res_port = request_region(port, 16, "ES18xx"); in snd_es18xx_new_device()
1771 if (chip->res_port == NULL) { in snd_es18xx_new_device()
1773 snd_printk(KERN_ERR PFX "unable to grap ports 0x%lx-0x%lx\n", port, port + 16 - 1); in snd_es18xx_new_device()
1774 return -EBUSY; in snd_es18xx_new_device()
1781 return -EBUSY; in snd_es18xx_new_device()
1783 chip->irq = irq; in snd_es18xx_new_device()
1784 card->sync_irq = chip->irq; in snd_es18xx_new_device()
1789 return -EBUSY; in snd_es18xx_new_device()
1791 chip->dma1 = dma1; in snd_es18xx_new_device()
1796 return -EBUSY; in snd_es18xx_new_device()
1798 chip->dma2 = dma2; in snd_es18xx_new_device()
1800 if (snd_es18xx_probe(chip, mpu_port, fm_port) < 0) { in snd_es18xx_new_device()
1802 return -ENODEV; in snd_es18xx_new_device()
1804 err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops); in snd_es18xx_new_device()
1814 struct snd_es18xx *chip = card->private_data; in snd_es18xx_mixer() local
1818 strcpy(card->mixername, chip->pcm->name); in snd_es18xx_mixer()
1822 kctl = snd_ctl_new1(&snd_es18xx_base_controls[idx], chip); in snd_es18xx_mixer()
1823 if (chip->caps & ES18XX_HWV) { in snd_es18xx_mixer()
1826 chip->master_volume = kctl; in snd_es18xx_mixer()
1827 kctl->private_free = snd_es18xx_hwv_free; in snd_es18xx_mixer()
1830 chip->master_switch = kctl; in snd_es18xx_mixer()
1831 kctl->private_free = snd_es18xx_hwv_free; in snd_es18xx_mixer()
1838 if (chip->caps & ES18XX_PCM2) { in snd_es18xx_mixer()
1840 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_pcm2_controls[idx], chip))) < 0) in snd_es18xx_mixer()
1845 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_pcm1_controls[idx], chip))) < 0) in snd_es18xx_mixer()
1850 if (chip->caps & ES18XX_RECMIX) { in snd_es18xx_mixer()
1852 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_recmix_controls[idx], chip))) < 0) in snd_es18xx_mixer()
1856 switch (chip->version) { in snd_es18xx_mixer()
1858 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_micpre1_control, chip))) < 0) in snd_es18xx_mixer()
1863 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_micpre2_control, chip))) < 0) in snd_es18xx_mixer()
1867 if (chip->caps & ES18XX_SPATIALIZER) { in snd_es18xx_mixer()
1869 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_spatializer_controls[idx], chip))) < 0) in snd_es18xx_mixer()
1873 if (chip->caps & ES18XX_HWV) { in snd_es18xx_mixer()
1876 kctl = snd_ctl_new1(&snd_es18xx_hw_volume_controls[idx], chip); in snd_es18xx_mixer()
1878 chip->hw_volume = kctl; in snd_es18xx_mixer()
1880 chip->hw_switch = kctl; in snd_es18xx_mixer()
1881 kctl->private_free = snd_es18xx_hwv_free; in snd_es18xx_mixer()
1889 if (chip->version != 0x1868) { in snd_es18xx_mixer()
1891 chip)); in snd_es18xx_mixer()
1895 if (chip->version == 0x1869) { in snd_es18xx_mixer()
1899 chip)); in snd_es18xx_mixer()
1903 } else if (chip->version == 0x1878) { in snd_es18xx_mixer()
1905 chip)); in snd_es18xx_mixer()
1908 } else if (chip->version == 0x1879) { in snd_es18xx_mixer()
1912 chip)); in snd_es18xx_mixer()
1917 if (chip->caps & ES18XX_GPO_2BIT) { in snd_es18xx_mixer()
1921 chip)); in snd_es18xx_mixer()
1932 …THOR("Christian Fischbach <fishbach@pool.informatik.rwth-aachen.de>, Abramo Bagnara <abramo@alsa-p…
1944 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
1945 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ variable
1952 static long mpu_port[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -1};
1963 module_param_array(id, charp, NULL, 0444);
1964 MODULE_PARM_DESC(id, "ID string for ES18xx soundcard.");
1974 MODULE_PARM_DESC(mpu_port, "MPU-401 port # for ES18xx driver.");
1990 { .id = "ESS1869" },
1991 { .id = "ESS1879" },
1992 { .id = "" } /* end */
2002 return -EBUSY; in snd_audiodrive_pnp_init_main()
2004 /* ok. hack using Vendor-Defined Card-Level registers */ in snd_audiodrive_pnp_init_main()
2005 /* skip csn and logdev initialization - already done in isapnp_configure */ in snd_audiodrive_pnp_init_main()
2010 isapnp_write_byte(0x28, pnp_irq(pdev, 0)); /* MPU-401 IRQ Number */ in snd_audiodrive_pnp_init_main()
2025 static int snd_audiodrive_pnp(int dev, struct snd_es18xx *chip, in snd_audiodrive_pnp() argument
2028 chip->dev = pdev; in snd_audiodrive_pnp()
2029 if (snd_audiodrive_pnp_init_main(dev, chip->dev) < 0) in snd_audiodrive_pnp()
2030 return -EBUSY; in snd_audiodrive_pnp()
2035 /* ESS 1868 (integrated on Compaq dual P-Pro motherboard and Genius 18PnP 3D) */
2036 { .id = "ESS1868", .devs = { { "ESS1868" }, { "ESS0000" } } },
2038 { .id = "ESS1868", .devs = { { "ESS8601" }, { "ESS8600" } } },
2040 { .id = "ESS1868", .devs = { { "ESS8611" }, { "ESS8610" } } },
2042 { .id = "ESS0003", .devs = { { "ESS1869" }, { "ESS0006" } } },
2044 { .id = "ESS1869", .devs = { { "ESS1869" }, { "ESS0006" } } },
2046 { .id = "ESS1878", .devs = { { "ESS1878" }, { "ESS0004" } } },
2048 { .id = "ESS1879", .devs = { { "ESS1879" }, { "ESS0009" } } },
2049 /* --- */
2050 { .id = "" } /* end */
2055 static int snd_audiodrive_pnpc(int dev, struct snd_es18xx *chip, in snd_audiodrive_pnpc() argument
2057 const struct pnp_card_device_id *id) in snd_audiodrive_pnpc() argument
2059 chip->dev = pnp_request_card_device(card, id->devs[0].id, NULL); in snd_audiodrive_pnpc()
2060 if (chip->dev == NULL) in snd_audiodrive_pnpc()
2061 return -EBUSY; in snd_audiodrive_pnpc()
2063 chip->devc = pnp_request_card_device(card, id->devs[1].id, NULL); in snd_audiodrive_pnpc()
2064 if (chip->devc == NULL) in snd_audiodrive_pnpc()
2065 return -EBUSY; in snd_audiodrive_pnpc()
2068 if (pnp_activate_dev(chip->devc) < 0) { in snd_audiodrive_pnpc()
2070 return -EAGAIN; in snd_audiodrive_pnpc()
2073 (unsigned long long)pnp_port_start(chip->devc, 0)); in snd_audiodrive_pnpc()
2074 if (snd_audiodrive_pnp_init_main(dev, chip->dev) < 0) in snd_audiodrive_pnpc()
2075 return -EBUSY; in snd_audiodrive_pnpc()
2090 return snd_card_new(pdev, index[dev], id[dev], THIS_MODULE, in snd_es18xx_card_new()
2096 struct snd_es18xx *chip = card->private_data; in snd_audiodrive_probe() local
2106 sprintf(card->driver, "ES%x", chip->version); in snd_audiodrive_probe()
2108 sprintf(card->shortname, "ESS AudioDrive ES%x", chip->version); in snd_audiodrive_probe()
2110 sprintf(card->longname, "%s at 0x%lx, irq %d, dma1 %d, dma2 %d", in snd_audiodrive_probe()
2111 card->shortname, in snd_audiodrive_probe()
2112 chip->port, in snd_audiodrive_probe()
2115 sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d", in snd_audiodrive_probe()
2116 card->shortname, in snd_audiodrive_probe()
2117 chip->port, in snd_audiodrive_probe()
2144 -1, &chip->rmidi); in snd_audiodrive_probe()
2176 static const int possible_irqs[] = {5, 9, 10, 7, 11, 12, -1}; in snd_es18xx_isa_probe()
2177 static const int possible_dmas[] = {1, 0, 3, 5, -1}; in snd_es18xx_isa_probe()
2182 return -EBUSY; in snd_es18xx_isa_probe()
2188 return -EBUSY; in snd_es18xx_isa_probe()
2194 return -EBUSY; in snd_es18xx_isa_probe()
2251 const struct pnp_device_id *id) in snd_audiodrive_pnp_detect() argument
2258 return -ENOENT; /* we have another procedure - card */ in snd_audiodrive_pnp_detect()
2264 return -ENODEV; in snd_audiodrive_pnp_detect()
2266 err = snd_es18xx_card_new(&pdev->dev, dev, &card); in snd_audiodrive_pnp_detect()
2269 if ((err = snd_audiodrive_pnp(dev, card->private_data, pdev)) < 0) { in snd_audiodrive_pnp_detect()
2299 .name = "es18xx-pnpbios",
2321 return -ENODEV; in snd_audiodrive_pnpc_detect()
2323 res = snd_es18xx_card_new(&pcard->card->dev, dev, &card); in snd_audiodrive_pnpc_detect()
2327 if ((res = snd_audiodrive_pnpc(dev, card->private_data, pcard, pid)) < 0) { in snd_audiodrive_pnpc_detect()