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 */
90 int irq; /* IRQ number of ESS chip */
93 unsigned short version; /* version of ESS chip */
94 int caps; /* Chip capabilities */
129 #define ES18XX_PCM2 0x0001 /* Has two useable PCM */
130 #define ES18XX_SPATIALIZER 0x0002 /* Has 3D Spatializer */
131 #define ES18XX_RECMIX 0x0004 /* Has record mixer */
132 #define ES18XX_DUPLEX_MONO 0x0008 /* Has mono duplex only */
136 #define ES18XX_HWV 0x0080 /* Has separate hardware volume mixer controls*/
140 #define ES18XX_CONTROL 0x0800 /* Has control ports */
159 static int snd_es18xx_dsp_command(struct snd_es18xx *chip, unsigned char val) in snd_es18xx_dsp_command() argument
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()
172 static int snd_es18xx_dsp_get_byte(struct snd_es18xx *chip) in snd_es18xx_dsp_get_byte() argument
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()
186 static int snd_es18xx_write(struct snd_es18xx *chip, in snd_es18xx_write() argument
192 spin_lock_irqsave(&chip->reg_lock, flags); in snd_es18xx_write()
193 ret = snd_es18xx_dsp_command(chip, reg); in snd_es18xx_write()
196 ret = snd_es18xx_dsp_command(chip, data); in snd_es18xx_write()
198 spin_unlock_irqrestore(&chip->reg_lock, flags); in snd_es18xx_write()
205 static int snd_es18xx_read(struct snd_es18xx *chip, unsigned char reg) in snd_es18xx_read() argument
209 spin_lock_irqsave(&chip->reg_lock, flags); in snd_es18xx_read()
210 ret = snd_es18xx_dsp_command(chip, 0xC0); in snd_es18xx_read()
213 ret = snd_es18xx_dsp_command(chip, reg); in snd_es18xx_read()
216 data = snd_es18xx_dsp_get_byte(chip); in snd_es18xx_read()
222 spin_unlock_irqrestore(&chip->reg_lock, flags); in snd_es18xx_read()
227 static int snd_es18xx_bits(struct snd_es18xx *chip, unsigned char reg, in snd_es18xx_bits() argument
233 spin_lock_irqsave(&chip->reg_lock, flags); in snd_es18xx_bits()
234 ret = snd_es18xx_dsp_command(chip, 0xC0); in snd_es18xx_bits()
237 ret = snd_es18xx_dsp_command(chip, reg); in snd_es18xx_bits()
240 ret = snd_es18xx_dsp_get_byte(chip); in snd_es18xx_bits()
247 ret = snd_es18xx_dsp_command(chip, reg); in snd_es18xx_bits()
251 ret = snd_es18xx_dsp_command(chip, new); in snd_es18xx_bits()
261 spin_unlock_irqrestore(&chip->reg_lock, flags); in snd_es18xx_bits()
265 static inline void snd_es18xx_mixer_write(struct snd_es18xx *chip, in snd_es18xx_mixer_write() argument
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()
278 static inline int snd_es18xx_mixer_read(struct snd_es18xx *chip, unsigned char reg) in snd_es18xx_mixer_read() argument
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()
293 static inline int snd_es18xx_mixer_bits(struct snd_es18xx *chip, unsigned char reg, in snd_es18xx_mixer_bits() argument
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()
314 static inline int snd_es18xx_mixer_writable(struct snd_es18xx *chip, unsigned char reg, in snd_es18xx_mixer_writable() argument
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()
334 static int snd_es18xx_reset(struct snd_es18xx *chip) in snd_es18xx_reset() argument
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()
346 static int snd_es18xx_reset_fifo(struct snd_es18xx *chip) in snd_es18xx_reset_fifo() argument
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()
395 static void snd_es18xx_rate_set(struct snd_es18xx *chip, in snd_es18xx_rate_set() argument
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()
417 snd_es18xx_mixer_write(chip, 0x70, bits); in snd_es18xx_rate_set()
422 snd_es18xx_write(chip, 0xA2, div0); in snd_es18xx_rate_set()
423 snd_es18xx_mixer_write(chip, 0x72, div0); in snd_es18xx_rate_set()
425 snd_es18xx_write(chip, 0xA1, bits); in snd_es18xx_rate_set()
426 snd_es18xx_write(chip, 0xA2, div0); in snd_es18xx_rate_set()
433 struct snd_es18xx *chip = snd_pcm_substream_chip(substream); in snd_es18xx_playback_hw_params() local
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()
456 static int snd_es18xx_playback1_prepare(struct snd_es18xx *chip, in snd_es18xx_playback1_prepare() argument
459 struct snd_pcm_runtime *runtime = substream->runtime; in snd_es18xx_playback1_prepare()
463 snd_es18xx_rate_set(chip, substream, DAC2); in snd_es18xx_playback1_prepare()
466 count = 0x10000 - count; in snd_es18xx_playback1_prepare()
467 snd_es18xx_mixer_write(chip, 0x74, count & 0xff); in snd_es18xx_playback1_prepare()
468 snd_es18xx_mixer_write(chip, 0x76, count >> 8); in snd_es18xx_playback1_prepare()
471 snd_es18xx_mixer_bits(chip, 0x7A, 0x07, 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()
482 static int snd_es18xx_playback1_trigger(struct snd_es18xx *chip, in snd_es18xx_playback1_trigger() argument
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()
494 snd_es18xx_mixer_write(chip, 0x78, 0xb3); in snd_es18xx_playback1_trigger()
496 snd_es18xx_mixer_write(chip, 0x78, 0x93); 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()
505 snd_es18xx_dsp_command(chip, 0xD1); in snd_es18xx_playback1_trigger()
510 if (!(chip->active & DAC2)) in snd_es18xx_playback1_trigger()
512 chip->active &= ~DAC2; in snd_es18xx_playback1_trigger()
514 snd_es18xx_mixer_write(chip, 0x78, 0x00); in snd_es18xx_playback1_trigger()
517 if (chip->caps & ES18XX_PCM2) in snd_es18xx_playback1_trigger()
519 snd_es18xx_mixer_write(chip, 0x7C, 0); in snd_es18xx_playback1_trigger()
522 snd_es18xx_dsp_command(chip, 0xD3); in snd_es18xx_playback1_trigger()
526 return -EINVAL; in snd_es18xx_playback1_trigger()
535 struct snd_es18xx *chip = snd_pcm_substream_chip(substream); in snd_es18xx_capture_hw_params() local
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()
555 struct snd_es18xx *chip = snd_pcm_substream_chip(substream); in snd_es18xx_capture_prepare() local
556 struct snd_pcm_runtime *runtime = substream->runtime; in snd_es18xx_capture_prepare()
560 snd_es18xx_reset_fifo(chip); in snd_es18xx_capture_prepare()
563 snd_es18xx_bits(chip, 0xA8, 0x03, runtime->channels == 1 ? 0x02 : 0x01); in snd_es18xx_capture_prepare()
565 snd_es18xx_rate_set(chip, substream, ADC1); in snd_es18xx_capture_prepare()
568 count = 0x10000 - count; in snd_es18xx_capture_prepare()
569 snd_es18xx_write(chip, 0xA4, count & 0xff); in snd_es18xx_capture_prepare()
570 snd_es18xx_write(chip, 0xA5, count >> 8); in snd_es18xx_capture_prepare()
577 snd_es18xx_write(chip, 0xB7, in snd_es18xx_capture_prepare()
578 snd_pcm_format_unsigned(runtime->format) ? 0x51 : 0x71); in snd_es18xx_capture_prepare()
579 snd_es18xx_write(chip, 0xB7, 0x90 | 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()
593 struct snd_es18xx *chip = snd_pcm_substream_chip(substream); in snd_es18xx_capture_trigger() local
598 if (chip->active & ADC1) in snd_es18xx_capture_trigger()
600 chip->active |= ADC1; in snd_es18xx_capture_trigger()
602 snd_es18xx_write(chip, 0xB8, 0x0f); in snd_es18xx_capture_trigger()
606 if (!(chip->active & ADC1)) in snd_es18xx_capture_trigger()
608 chip->active &= ~ADC1; in snd_es18xx_capture_trigger()
610 snd_es18xx_write(chip, 0xB8, 0x00); in snd_es18xx_capture_trigger()
613 return -EINVAL; in snd_es18xx_capture_trigger()
619 static int snd_es18xx_playback2_prepare(struct snd_es18xx *chip, in snd_es18xx_playback2_prepare() argument
622 struct snd_pcm_runtime *runtime = substream->runtime; in snd_es18xx_playback2_prepare()
626 snd_es18xx_reset_fifo(chip); in snd_es18xx_playback2_prepare()
629 snd_es18xx_bits(chip, 0xA8, 0x03, runtime->channels == 1 ? 0x02 : 0x01); in snd_es18xx_playback2_prepare()
631 snd_es18xx_rate_set(chip, substream, DAC1); in snd_es18xx_playback2_prepare()
634 count = 0x10000 - count; in snd_es18xx_playback2_prepare()
635 snd_es18xx_write(chip, 0xA4, count & 0xff); in snd_es18xx_playback2_prepare()
636 snd_es18xx_write(chip, 0xA5, count >> 8); in snd_es18xx_playback2_prepare()
639 snd_es18xx_write(chip, 0xB6, in snd_es18xx_playback2_prepare()
640 snd_pcm_format_unsigned(runtime->format) ? 0x80 : 0x00); in snd_es18xx_playback2_prepare()
641 snd_es18xx_write(chip, 0xB7, in snd_es18xx_playback2_prepare()
642 snd_pcm_format_unsigned(runtime->format) ? 0x51 : 0x71); in snd_es18xx_playback2_prepare()
643 snd_es18xx_write(chip, 0xB7, 0x90 | 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()
654 static int snd_es18xx_playback2_trigger(struct snd_es18xx *chip, in snd_es18xx_playback2_trigger() argument
661 if (chip->active & DAC1) in snd_es18xx_playback2_trigger()
663 chip->active |= DAC1; in snd_es18xx_playback2_trigger()
665 snd_es18xx_write(chip, 0xB8, 0x05); in snd_es18xx_playback2_trigger()
670 snd_es18xx_dsp_command(chip, 0xD1); in snd_es18xx_playback2_trigger()
675 if (!(chip->active & DAC1)) in snd_es18xx_playback2_trigger()
677 chip->active &= ~DAC1; in snd_es18xx_playback2_trigger()
679 snd_es18xx_write(chip, 0xB8, 0x00); in snd_es18xx_playback2_trigger()
684 snd_es18xx_dsp_command(chip, 0xD3); in snd_es18xx_playback2_trigger()
688 return -EINVAL; in snd_es18xx_playback2_trigger()
696 struct snd_es18xx *chip = snd_pcm_substream_chip(substream); in snd_es18xx_playback_prepare() local
697 if (substream->number == 0 && (chip->caps & ES18XX_PCM2)) in snd_es18xx_playback_prepare()
698 return snd_es18xx_playback1_prepare(chip, substream); in snd_es18xx_playback_prepare()
700 return snd_es18xx_playback2_prepare(chip, substream); in snd_es18xx_playback_prepare()
706 struct snd_es18xx *chip = snd_pcm_substream_chip(substream); in snd_es18xx_playback_trigger() local
707 if (substream->number == 0 && (chip->caps & ES18XX_PCM2)) in snd_es18xx_playback_trigger()
708 return snd_es18xx_playback1_trigger(chip, substream, cmd); in snd_es18xx_playback_trigger()
710 return snd_es18xx_playback2_trigger(chip, substream, cmd); in snd_es18xx_playback_trigger()
716 struct snd_es18xx *chip = card->private_data; in snd_es18xx_interrupt() local
719 if (chip->caps & ES18XX_CONTROL) { in snd_es18xx_interrupt()
721 status = inb(chip->ctrl_port + 6); in snd_es18xx_interrupt()
724 status = snd_es18xx_mixer_read(chip, 0x7f) >> 4; in snd_es18xx_interrupt()
729 if (inb(chip->port + 0x0C) & 0x01) in snd_es18xx_interrupt()
731 if (snd_es18xx_mixer_read(chip, 0x7A) & 0x80) in snd_es18xx_interrupt()
733 if ((chip->caps & ES18XX_HWV) && in snd_es18xx_interrupt()
734 snd_es18xx_mixer_read(chip, 0x64) & 0x10) 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()
744 snd_es18xx_mixer_bits(chip, 0x7A, 0x80, 0x00); 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()
765 split = snd_es18xx_mixer_read(chip, 0x64) & 0x80; 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()
778 snd_es18xx_mixer_write(chip, 0x66, 0x00); in snd_es18xx_interrupt()
785 struct snd_es18xx *chip = snd_pcm_substream_chip(substream); 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()
804 struct snd_es18xx *chip = snd_pcm_substream_chip(substream); 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()
857 struct snd_es18xx *chip = snd_pcm_substream_chip(substream); in snd_es18xx_playback_open() local
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()
882 struct snd_es18xx *chip = snd_pcm_substream_chip(substream); in snd_es18xx_capture_open() local
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()
899 struct snd_es18xx *chip = snd_pcm_substream_chip(substream); in snd_es18xx_playback_close() local
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()
911 struct snd_es18xx *chip = snd_pcm_substream_chip(substream); in snd_es18xx_capture_close() local
913 chip->capture_a_substream = NULL; in snd_es18xx_capture_close()
946 struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol); in snd_es18xx_info_mux() local
948 switch (chip->version) { in snd_es18xx_info_mux()
959 return -EINVAL; in snd_es18xx_info_mux()
966 struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol); in snd_es18xx_get_mux() local
967 int muxSource = snd_es18xx_mixer_read(chip, 0x1c) & 0x07; in snd_es18xx_get_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()
972 (snd_es18xx_mixer_read(chip, 0x7a) & 0x08) in snd_es18xx_get_mux()
976 ucontrol->value.enumerated.item[0] = muxSource; in snd_es18xx_get_mux()
983 struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol); in snd_es18xx_put_mux() local
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()
994 retVal = snd_es18xx_mixer_bits(chip, 0x7a, 0x08, 0x08) != 0x08; in snd_es18xx_put_mux()
997 retVal = snd_es18xx_mixer_bits(chip, 0x7a, 0x08, 0x00) != 0x00; 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()
1015 return (snd_es18xx_mixer_bits(chip, 0x1c, 0x07, val) != val) || retVal; in snd_es18xx_put_mux()
1022 struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol); in snd_es18xx_get_spatializer_enable() local
1023 unsigned char val = snd_es18xx_mixer_read(chip, 0x50); in snd_es18xx_get_spatializer_enable()
1024 ucontrol->value.integer.value[0] = !!(val & 8); in snd_es18xx_get_spatializer_enable()
1030 struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol); in snd_es18xx_put_spatializer_enable() local
1033 nval = ucontrol->value.integer.value[0] ? 0x0c : 0x04; in snd_es18xx_put_spatializer_enable()
1034 oval = snd_es18xx_mixer_read(chip, 0x50) & 0x0c; in snd_es18xx_put_spatializer_enable()
1037 snd_es18xx_mixer_write(chip, 0x50, nval & ~0x04); in snd_es18xx_put_spatializer_enable()
1038 snd_es18xx_mixer_write(chip, 0x50, nval); 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()
1054 struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol); in snd_es18xx_get_hw_volume() local
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()
1064 struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol); in snd_es18xx_get_hw_switch() local
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()
1072 struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol); in snd_es18xx_hwv_free() local
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()
1079 static int snd_es18xx_reg_bits(struct snd_es18xx *chip, unsigned char reg, in snd_es18xx_reg_bits() argument
1083 return snd_es18xx_mixer_bits(chip, reg, mask, val); in snd_es18xx_reg_bits()
1085 return snd_es18xx_bits(chip, reg, mask, val); in snd_es18xx_reg_bits()
1088 static int snd_es18xx_reg_read(struct snd_es18xx *chip, unsigned char reg) in snd_es18xx_reg_read() argument
1091 return snd_es18xx_mixer_read(chip, reg); in snd_es18xx_reg_read()
1093 return snd_es18xx_read(chip, reg); in snd_es18xx_reg_read()
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()
1118 struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol); in snd_es18xx_get_single() local
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()
1129 val = snd_es18xx_reg_read(chip, reg); 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()
1138 struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol); in snd_es18xx_put_single() local
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()
1160 return snd_es18xx_reg_bits(chip, reg, mask, val) != val; 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()
1182 struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol); in snd_es18xx_get_double() local
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()
1191 left = snd_es18xx_reg_read(chip, left_reg); in snd_es18xx_get_double()
1193 right = snd_es18xx_reg_read(chip, right_reg); 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()
1207 struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol); in snd_es18xx_put_double() local
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()
1229 if (snd_es18xx_reg_bits(chip, left_reg, mask1, val1) != val1) in snd_es18xx_put_double()
1231 if (snd_es18xx_reg_bits(chip, right_reg, mask2, val2) != val2) in snd_es18xx_put_double()
1234 change = (snd_es18xx_reg_bits(chip, left_reg, mask1 | mask2, in snd_es18xx_put_double()
1306 ES18XX_SINGLE("3D Control - Level", 0, 0x52, 0, 63, 0),
1309 .name = "3D Control - Switch",
1345 static int snd_es18xx_config_read(struct snd_es18xx *chip, unsigned char reg) in snd_es18xx_config_read() argument
1349 outb(reg, chip->ctrl_port); in snd_es18xx_config_read()
1350 data = inb(chip->ctrl_port + 1); in snd_es18xx_config_read()
1354 static void snd_es18xx_config_write(struct snd_es18xx *chip, in snd_es18xx_config_write() argument
1359 outb(reg, chip->ctrl_port); in snd_es18xx_config_write()
1360 outb(data, chip->ctrl_port + 1); in snd_es18xx_config_write()
1366 static int snd_es18xx_initialize(struct snd_es18xx *chip, in snd_es18xx_initialize() argument
1373 snd_es18xx_dsp_command(chip, 0xC6); in snd_es18xx_initialize()
1375 snd_es18xx_mixer_write(chip, 0x00, 0x00); in snd_es18xx_initialize()
1378 snd_es18xx_write(chip, 0xB9, 2); in snd_es18xx_initialize()
1379 if (chip->caps & ES18XX_CONTROL) { in snd_es18xx_initialize()
1381 snd_es18xx_config_write(chip, 0x27, chip->irq); in snd_es18xx_initialize()
1384 snd_es18xx_config_write(chip, 0x62, fm_port >> 8); in snd_es18xx_initialize()
1385 snd_es18xx_config_write(chip, 0x63, fm_port & 0xff); in snd_es18xx_initialize()
1388 /* MPU-401 I/O */ in snd_es18xx_initialize()
1389 snd_es18xx_config_write(chip, 0x64, mpu_port >> 8); in snd_es18xx_initialize()
1390 snd_es18xx_config_write(chip, 0x65, mpu_port & 0xff); in snd_es18xx_initialize()
1391 /* MPU-401 IRQ */ in snd_es18xx_initialize()
1392 snd_es18xx_config_write(chip, 0x28, chip->irq); in snd_es18xx_initialize()
1395 snd_es18xx_config_write(chip, 0x70, chip->irq); in snd_es18xx_initialize()
1397 snd_es18xx_config_write(chip, 0x72, chip->irq); in snd_es18xx_initialize()
1399 snd_es18xx_config_write(chip, 0x74, chip->dma1); in snd_es18xx_initialize()
1401 snd_es18xx_config_write(chip, 0x75, chip->dma2); in snd_es18xx_initialize()
1404 snd_es18xx_write(chip, 0xB1, 0x50); in snd_es18xx_initialize()
1406 snd_es18xx_mixer_write(chip, 0x7A, 0x40); in snd_es18xx_initialize()
1408 snd_es18xx_write(chip, 0xB2, 0x50); in snd_es18xx_initialize()
1410 snd_es18xx_mixer_write(chip, 0x64, 0x42); in snd_es18xx_initialize()
1412 snd_es18xx_mixer_bits(chip, 0x48, 0x10, 0x10); in snd_es18xx_initialize()
1416 switch (chip->irq) { in snd_es18xx_initialize()
1431 snd_printk(KERN_ERR "invalid irq %d\n", chip->irq); in snd_es18xx_initialize()
1432 return -ENODEV; in snd_es18xx_initialize()
1434 switch (chip->dma1) { in snd_es18xx_initialize()
1445 snd_printk(KERN_ERR "invalid dma1 %d\n", chip->dma1); in snd_es18xx_initialize()
1446 return -ENODEV; in snd_es18xx_initialize()
1448 switch (chip->dma2) { in snd_es18xx_initialize()
1462 snd_printk(KERN_ERR "invalid dma2 %d\n", chip->dma2); in snd_es18xx_initialize()
1463 return -ENODEV; in snd_es18xx_initialize()
1467 snd_es18xx_write(chip, 0xB1, 0x50 | (irqmask << 2)); in snd_es18xx_initialize()
1469 snd_es18xx_write(chip, 0xB2, 0x50 | (dma1mask << 2)); in snd_es18xx_initialize()
1471 snd_es18xx_mixer_bits(chip, 0x7d, 0x07, 0x04 | dma2mask); in snd_es18xx_initialize()
1474 snd_es18xx_mixer_write(chip, 0x7A, 0x68); in snd_es18xx_initialize()
1476 snd_es18xx_mixer_write(chip, 0x64, 0x06); in snd_es18xx_initialize()
1481 snd_es18xx_mixer_write(chip, 0x40, in snd_es18xx_initialize()
1484 snd_es18xx_mixer_write(chip, 0x7f, ((irqmask + 1) << 1) | 0x01); in snd_es18xx_initialize()
1486 if (chip->caps & ES18XX_NEW_RATE) { in snd_es18xx_initialize()
1490 snd_es18xx_mixer_write(chip, 0x71, 0x32); in snd_es18xx_initialize()
1492 if (!(chip->caps & ES18XX_PCM2)) { in snd_es18xx_initialize()
1494 snd_es18xx_write(chip, 0xB7, 0x80); in snd_es18xx_initialize()
1496 if (chip->caps & ES18XX_SPATIALIZER) { in snd_es18xx_initialize()
1498 snd_es18xx_mixer_write(chip, 0x54, 0x8f); in snd_es18xx_initialize()
1499 snd_es18xx_mixer_write(chip, 0x56, 0x95); in snd_es18xx_initialize()
1500 snd_es18xx_mixer_write(chip, 0x58, 0x94); in snd_es18xx_initialize()
1501 snd_es18xx_mixer_write(chip, 0x5a, 0x80); in snd_es18xx_initialize()
1504 switch (chip->version) { in snd_es18xx_initialize()
1507 //so a Switch control has been added to toggle this 0x71 bit on/off: in snd_es18xx_initialize()
1508 //snd_es18xx_mixer_bits(chip, 0x71, 0x40, 0x40); in snd_es18xx_initialize()
1511 snd_es18xx_config_write(chip, 0x29, snd_es18xx_config_read(chip, 0x29) | 0x40); in snd_es18xx_initialize()
1515 if (chip->caps & ES18XX_MUTEREC) in snd_es18xx_initialize()
1517 if (chip->caps & ES18XX_RECMIX) in snd_es18xx_initialize()
1518 snd_es18xx_mixer_write(chip, 0x1c, 0x05 | mask); in snd_es18xx_initialize()
1520 snd_es18xx_mixer_write(chip, 0x1c, 0x00 | mask); in snd_es18xx_initialize()
1521 snd_es18xx_write(chip, 0xb4, 0x00); in snd_es18xx_initialize()
1525 snd_es18xx_dsp_command(chip, 0xD1); in snd_es18xx_initialize()
1531 static int snd_es18xx_identify(struct snd_card *card, struct snd_es18xx *chip) in snd_es18xx_identify() argument
1536 if (snd_es18xx_reset(chip) < 0) { in snd_es18xx_identify()
1537 snd_printk(KERN_ERR "reset at 0x%lx failed!!!\n", chip->port); in snd_es18xx_identify()
1538 return -ENODEV; in snd_es18xx_identify()
1541 snd_es18xx_dsp_command(chip, 0xe7); in snd_es18xx_identify()
1542 hi = snd_es18xx_dsp_get_byte(chip); in snd_es18xx_identify()
1546 lo = snd_es18xx_dsp_get_byte(chip); in snd_es18xx_identify()
1548 return -ENODEV; in snd_es18xx_identify()
1551 chip->version = 0x488; in snd_es18xx_identify()
1555 return -ENODEV; in snd_es18xx_identify()
1558 chip->version = 0x688; in snd_es18xx_identify()
1562 outb(0x40, chip->port + 0x04); in snd_es18xx_identify()
1564 hi = inb(chip->port + 0x05); in snd_es18xx_identify()
1566 lo = inb(chip->port + 0x05); in snd_es18xx_identify()
1568 chip->version = hi << 8 | lo; in snd_es18xx_identify()
1569 chip->ctrl_port = inb(chip->port + 0x05) << 8; in snd_es18xx_identify()
1571 chip->ctrl_port += inb(chip->port + 0x05); in snd_es18xx_identify()
1573 if (!devm_request_region(card->dev, chip->ctrl_port, 8, in snd_es18xx_identify()
1574 "ES18xx - CTRL")) { in snd_es18xx_identify()
1575 snd_printk(KERN_ERR PFX "unable go grab port 0x%lx\n", chip->ctrl_port); in snd_es18xx_identify()
1576 return -EBUSY; in snd_es18xx_identify()
1582 /* If has Hardware volume */ in snd_es18xx_identify()
1583 if (snd_es18xx_mixer_writable(chip, 0x64, 0x04)) { in snd_es18xx_identify()
1584 /* If has Audio2 */ in snd_es18xx_identify()
1585 if (snd_es18xx_mixer_writable(chip, 0x70, 0x7f)) { in snd_es18xx_identify()
1586 /* If has volume count */ in snd_es18xx_identify()
1587 if (snd_es18xx_mixer_writable(chip, 0x64, 0x20)) { in snd_es18xx_identify()
1588 chip->version = 0x1887; in snd_es18xx_identify()
1590 chip->version = 0x1888; in snd_es18xx_identify()
1593 chip->version = 0x1788; in snd_es18xx_identify()
1597 chip->version = 0x1688; in snd_es18xx_identify()
1602 struct snd_es18xx *chip, in snd_es18xx_probe() argument
1606 if (snd_es18xx_identify(card, chip) < 0) { in snd_es18xx_probe()
1607 snd_printk(KERN_ERR PFX "[0x%lx] ESS chip not found\n", chip->port); in snd_es18xx_probe()
1608 return -ENODEV; in snd_es18xx_probe()
1611 switch (chip->version) { in snd_es18xx_probe()
1613 chip->caps = ES18XX_DUPLEX_MONO | ES18XX_DUPLEX_SAME | ES18XX_CONTROL | ES18XX_GPO_2BIT; in snd_es18xx_probe()
1616 …chip->caps = ES18XX_PCM2 | ES18XX_SPATIALIZER | ES18XX_RECMIX | ES18XX_NEW_RATE | ES18XX_AUXB | ES… in snd_es18xx_probe()
1619 chip->caps = ES18XX_DUPLEX_MONO | ES18XX_DUPLEX_SAME | ES18XX_I2S | ES18XX_CONTROL; in snd_es18xx_probe()
1622 …chip->caps = ES18XX_PCM2 | ES18XX_SPATIALIZER | ES18XX_RECMIX | ES18XX_NEW_RATE | ES18XX_AUXB | ES… in snd_es18xx_probe()
1626 chip->caps = ES18XX_PCM2 | ES18XX_RECMIX | ES18XX_AUXB | ES18XX_DUPLEX_SAME | ES18XX_GPO_2BIT; in snd_es18xx_probe()
1629 snd_printk(KERN_ERR "[0x%lx] unsupported chip ES%x\n", in snd_es18xx_probe()
1630 chip->port, chip->version); in snd_es18xx_probe()
1631 return -ENODEV; in snd_es18xx_probe()
1634 snd_printd("[0x%lx] ESS%x chip found\n", chip->port, chip->version); in snd_es18xx_probe()
1636 if (chip->dma1 == chip->dma2) in snd_es18xx_probe()
1637 chip->caps &= ~(ES18XX_PCM2 | ES18XX_DUPLEX_SAME); in snd_es18xx_probe()
1639 return snd_es18xx_initialize(chip, mpu_port, fm_port); in snd_es18xx_probe()
1662 struct snd_es18xx *chip = card->private_data; in snd_es18xx_pcm() local
1667 sprintf(str, "ES%x", chip->version); in snd_es18xx_pcm()
1668 if (chip->caps & ES18XX_PCM2) in snd_es18xx_pcm()
1679 pcm->private_data = chip; in snd_es18xx_pcm()
1680 pcm->info_flags = 0; in snd_es18xx_pcm()
1681 if (chip->caps & ES18XX_DUPLEX_SAME) in snd_es18xx_pcm()
1682 pcm->info_flags |= SNDRV_PCM_INFO_JOINT_DUPLEX; in snd_es18xx_pcm()
1683 if (! (chip->caps & ES18XX_PCM2)) in snd_es18xx_pcm()
1684 pcm->info_flags |= SNDRV_PCM_INFO_HALF_DUPLEX; in snd_es18xx_pcm()
1685 sprintf(pcm->name, "ESS AudioDrive ES%x", chip->version); in snd_es18xx_pcm()
1686 chip->pcm = pcm; in snd_es18xx_pcm()
1688 snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV, card->dev, in snd_es18xx_pcm()
1690 chip->dma1 > 3 || chip->dma2 > 3 ? 128*1024 : 64*1024); in snd_es18xx_pcm()
1698 struct snd_es18xx *chip = card->private_data; in snd_es18xx_suspend() local
1703 chip->pm_reg = (unsigned char)snd_es18xx_read(chip, ES18XX_PM); in snd_es18xx_suspend()
1704 chip->pm_reg |= (ES18XX_PM_FM | ES18XX_PM_SUS); in snd_es18xx_suspend()
1705 snd_es18xx_write(chip, ES18XX_PM, chip->pm_reg); in snd_es18xx_suspend()
1706 snd_es18xx_write(chip, ES18XX_PM, chip->pm_reg ^= ES18XX_PM_SUS); in snd_es18xx_suspend()
1713 struct snd_es18xx *chip = card->private_data; in snd_es18xx_resume() local
1716 snd_es18xx_write(chip, ES18XX_PM, chip->pm_reg ^= ES18XX_PM_FM); in snd_es18xx_resume()
1729 struct snd_es18xx *chip = card->private_data; in snd_es18xx_new_device() local
1731 spin_lock_init(&chip->reg_lock); in snd_es18xx_new_device()
1732 spin_lock_init(&chip->mixer_lock); in snd_es18xx_new_device()
1733 chip->port = port; in snd_es18xx_new_device()
1734 chip->irq = -1; in snd_es18xx_new_device()
1735 chip->dma1 = -1; in snd_es18xx_new_device()
1736 chip->dma2 = -1; in snd_es18xx_new_device()
1737 chip->audio2_vol = 0x00; in snd_es18xx_new_device()
1738 chip->active = 0; in snd_es18xx_new_device()
1740 if (!devm_request_region(card->dev, port, 16, "ES18xx")) { in snd_es18xx_new_device()
1741 snd_printk(KERN_ERR PFX "unable to grap ports 0x%lx-0x%lx\n", port, port + 16 - 1); in snd_es18xx_new_device()
1742 return -EBUSY; in snd_es18xx_new_device()
1745 if (devm_request_irq(card->dev, irq, snd_es18xx_interrupt, 0, "ES18xx", in snd_es18xx_new_device()
1748 return -EBUSY; in snd_es18xx_new_device()
1750 chip->irq = irq; in snd_es18xx_new_device()
1751 card->sync_irq = chip->irq; in snd_es18xx_new_device()
1753 if (snd_devm_request_dma(card->dev, dma1, "ES18xx DMA 1")) { in snd_es18xx_new_device()
1755 return -EBUSY; in snd_es18xx_new_device()
1757 chip->dma1 = dma1; in snd_es18xx_new_device()
1760 snd_devm_request_dma(card->dev, dma2, "ES18xx DMA 2")) { in snd_es18xx_new_device()
1762 return -EBUSY; in snd_es18xx_new_device()
1764 chip->dma2 = dma2; in snd_es18xx_new_device()
1766 if (snd_es18xx_probe(card, chip, mpu_port, fm_port) < 0) in snd_es18xx_new_device()
1767 return -ENODEV; in snd_es18xx_new_device()
1773 struct snd_es18xx *chip = card->private_data; in snd_es18xx_mixer() local
1777 strcpy(card->mixername, chip->pcm->name); in snd_es18xx_mixer()
1781 kctl = snd_ctl_new1(&snd_es18xx_base_controls[idx], chip); in snd_es18xx_mixer()
1782 if (chip->caps & ES18XX_HWV) { in snd_es18xx_mixer()
1785 chip->master_volume = kctl; in snd_es18xx_mixer()
1786 kctl->private_free = snd_es18xx_hwv_free; in snd_es18xx_mixer()
1789 chip->master_switch = kctl; in snd_es18xx_mixer()
1790 kctl->private_free = snd_es18xx_hwv_free; in snd_es18xx_mixer()
1798 if (chip->caps & ES18XX_PCM2) { in snd_es18xx_mixer()
1800 err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_pcm2_controls[idx], chip)); in snd_es18xx_mixer()
1806 err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_pcm1_controls[idx], chip)); in snd_es18xx_mixer()
1812 if (chip->caps & ES18XX_RECMIX) { in snd_es18xx_mixer()
1814 err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_recmix_controls[idx], chip)); in snd_es18xx_mixer()
1819 switch (chip->version) { in snd_es18xx_mixer()
1821 err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_micpre1_control, chip)); in snd_es18xx_mixer()
1827 err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_micpre2_control, chip)); in snd_es18xx_mixer()
1832 if (chip->caps & ES18XX_SPATIALIZER) { in snd_es18xx_mixer()
1834 err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_spatializer_controls[idx], chip)); in snd_es18xx_mixer()
1839 if (chip->caps & ES18XX_HWV) { in snd_es18xx_mixer()
1842 kctl = snd_ctl_new1(&snd_es18xx_hw_volume_controls[idx], chip); in snd_es18xx_mixer()
1844 chip->hw_volume = kctl; in snd_es18xx_mixer()
1846 chip->hw_switch = kctl; in snd_es18xx_mixer()
1847 kctl->private_free = snd_es18xx_hwv_free; in snd_es18xx_mixer()
1856 if (chip->version != 0x1868) { in snd_es18xx_mixer()
1858 chip)); in snd_es18xx_mixer()
1862 if (chip->version == 0x1869) { in snd_es18xx_mixer()
1866 chip)); in snd_es18xx_mixer()
1870 } else if (chip->version == 0x1878) { in snd_es18xx_mixer()
1872 chip)); in snd_es18xx_mixer()
1875 } else if (chip->version == 0x1879) { in snd_es18xx_mixer()
1879 chip)); in snd_es18xx_mixer()
1884 if (chip->caps & ES18XX_GPO_2BIT) { in snd_es18xx_mixer()
1888 chip)); in snd_es18xx_mixer()
1899 …THOR("Christian Fischbach <fishbach@pool.informatik.rwth-aachen.de>, Abramo Bagnara <abramo@alsa-p…
1903 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
1904 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ variable
1911 static long mpu_port[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -1};
1922 module_param_array(id, charp, NULL, 0444);
1923 MODULE_PARM_DESC(id, "ID string for ES18xx soundcard.");
1933 MODULE_PARM_DESC(mpu_port, "MPU-401 port # for ES18xx driver.");
1949 { .id = "ESS1869" },
1950 { .id = "ESS1879" },
1951 { .id = "" } /* end */
1961 return -EBUSY; in snd_audiodrive_pnp_init_main()
1963 /* ok. hack using Vendor-Defined Card-Level registers */ in snd_audiodrive_pnp_init_main()
1964 /* skip csn and logdev initialization - already done in isapnp_configure */ in snd_audiodrive_pnp_init_main()
1969 isapnp_write_byte(0x28, pnp_irq(pdev, 0)); /* MPU-401 IRQ Number */ in snd_audiodrive_pnp_init_main()
1984 static int snd_audiodrive_pnp(int dev, struct snd_es18xx *chip, in snd_audiodrive_pnp() argument
1987 chip->dev = pdev; in snd_audiodrive_pnp()
1988 if (snd_audiodrive_pnp_init_main(dev, chip->dev) < 0) in snd_audiodrive_pnp()
1989 return -EBUSY; in snd_audiodrive_pnp()
1994 /* ESS 1868 (integrated on Compaq dual P-Pro motherboard and Genius 18PnP 3D) */
1995 { .id = "ESS1868", .devs = { { "ESS1868" }, { "ESS0000" } } },
1997 { .id = "ESS1868", .devs = { { "ESS8601" }, { "ESS8600" } } },
1999 { .id = "ESS1868", .devs = { { "ESS8611" }, { "ESS8610" } } },
2001 { .id = "ESS0003", .devs = { { "ESS1869" }, { "ESS0006" } } },
2003 { .id = "ESS1869", .devs = { { "ESS1869" }, { "ESS0006" } } },
2005 { .id = "ESS1878", .devs = { { "ESS1878" }, { "ESS0004" } } },
2007 { .id = "ESS1879", .devs = { { "ESS1879" }, { "ESS0009" } } },
2008 /* --- */
2009 { .id = "" } /* end */
2014 static int snd_audiodrive_pnpc(int dev, struct snd_es18xx *chip, in snd_audiodrive_pnpc() argument
2016 const struct pnp_card_device_id *id) in snd_audiodrive_pnpc() argument
2018 chip->dev = pnp_request_card_device(card, id->devs[0].id, NULL); in snd_audiodrive_pnpc()
2019 if (chip->dev == NULL) in snd_audiodrive_pnpc()
2020 return -EBUSY; in snd_audiodrive_pnpc()
2022 chip->devc = pnp_request_card_device(card, id->devs[1].id, NULL); in snd_audiodrive_pnpc()
2023 if (chip->devc == NULL) in snd_audiodrive_pnpc()
2024 return -EBUSY; in snd_audiodrive_pnpc()
2027 if (pnp_activate_dev(chip->devc) < 0) { in snd_audiodrive_pnpc()
2029 return -EAGAIN; in snd_audiodrive_pnpc()
2032 (unsigned long long)pnp_port_start(chip->devc, 0)); in snd_audiodrive_pnpc()
2033 if (snd_audiodrive_pnp_init_main(dev, chip->dev) < 0) in snd_audiodrive_pnpc()
2034 return -EBUSY; in snd_audiodrive_pnpc()
2049 return snd_devm_card_new(pdev, index[dev], id[dev], THIS_MODULE, in snd_es18xx_card_new()
2055 struct snd_es18xx *chip = card->private_data; in snd_audiodrive_probe() local
2065 sprintf(card->driver, "ES%x", chip->version); in snd_audiodrive_probe()
2067 sprintf(card->shortname, "ESS AudioDrive ES%x", chip->version); in snd_audiodrive_probe()
2069 sprintf(card->longname, "%s at 0x%lx, irq %d, dma1 %d, dma2 %d", in snd_audiodrive_probe()
2070 card->shortname, in snd_audiodrive_probe()
2071 chip->port, in snd_audiodrive_probe()
2074 sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d", in snd_audiodrive_probe()
2075 card->shortname, in snd_audiodrive_probe()
2076 chip->port, in snd_audiodrive_probe()
2103 -1, &chip->rmidi); in snd_audiodrive_probe()
2134 static const int possible_irqs[] = {5, 9, 10, 7, 11, 12, -1}; in snd_es18xx_isa_probe()
2135 static const int possible_dmas[] = {1, 0, 3, 5, -1}; in snd_es18xx_isa_probe()
2141 return -EBUSY; in snd_es18xx_isa_probe()
2148 return -EBUSY; in snd_es18xx_isa_probe()
2155 return -EBUSY; in snd_es18xx_isa_probe()
2204 const struct pnp_device_id *id) in snd_audiodrive_pnp_detect() argument
2211 return -ENOENT; /* we have another procedure - card */ in snd_audiodrive_pnp_detect()
2217 return -ENODEV; in snd_audiodrive_pnp_detect()
2219 err = snd_es18xx_card_new(&pdev->dev, dev, &card); in snd_audiodrive_pnp_detect()
2222 err = snd_audiodrive_pnp(dev, card->private_data, pdev); in snd_audiodrive_pnp_detect()
2245 .name = "es18xx-pnpbios",
2266 return -ENODEV; in snd_audiodrive_pnpc_detect()
2268 res = snd_es18xx_card_new(&pcard->card->dev, dev, &card); in snd_audiodrive_pnpc_detect()
2272 res = snd_audiodrive_pnpc(dev, card->private_data, pcard, pid); in snd_audiodrive_pnpc_detect()