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.
87 unsigned long port; /* port of ESS chip */
88 unsigned long ctrl_port; /* Control port of ESS chip */
89 int irq; /* IRQ number of ESS chip */
92 unsigned short version; /* version of ESS chip */
93 int caps; /* Chip capabilities */
128 #define ES18XX_PCM2 0x0001 /* Has two useable PCM */
129 #define ES18XX_SPATIALIZER 0x0002 /* Has 3D Spatializer */
130 #define ES18XX_RECMIX 0x0004 /* Has record mixer */
131 #define ES18XX_DUPLEX_MONO 0x0008 /* Has mono duplex only */
135 #define ES18XX_HWV 0x0080 /* Has separate hardware volume mixer controls*/
139 #define ES18XX_CONTROL 0x0800 /* Has control ports */
158 static int snd_es18xx_dsp_command(struct snd_es18xx *chip, unsigned char val) in snd_es18xx_dsp_command() argument
162 for(i = MILLISECOND; i; i--) in snd_es18xx_dsp_command()
163 if ((inb(chip->port + 0x0C) & 0x80) == 0) { in snd_es18xx_dsp_command()
164 outb(val, chip->port + 0x0C); in snd_es18xx_dsp_command()
167 dev_err(chip->card->dev, "dsp_command: timeout (0x%x)\n", val); in snd_es18xx_dsp_command()
168 return -EINVAL; in snd_es18xx_dsp_command()
171 static int snd_es18xx_dsp_get_byte(struct snd_es18xx *chip) in snd_es18xx_dsp_get_byte() argument
175 for(i = MILLISECOND/10; i; i--) in snd_es18xx_dsp_get_byte()
176 if (inb(chip->port + 0x0C) & 0x40) in snd_es18xx_dsp_get_byte()
177 return inb(chip->port + 0x0A); in snd_es18xx_dsp_get_byte()
178 dev_err(chip->card->dev, "dsp_get_byte failed: 0x%lx = 0x%x!!!\n", in snd_es18xx_dsp_get_byte()
179 chip->port + 0x0A, inb(chip->port + 0x0A)); in snd_es18xx_dsp_get_byte()
180 return -ENODEV; in snd_es18xx_dsp_get_byte()
185 static int snd_es18xx_write(struct snd_es18xx *chip, in snd_es18xx_write() argument
191 spin_lock_irqsave(&chip->reg_lock, flags); in snd_es18xx_write()
192 ret = snd_es18xx_dsp_command(chip, reg); in snd_es18xx_write()
195 ret = snd_es18xx_dsp_command(chip, data); in snd_es18xx_write()
197 spin_unlock_irqrestore(&chip->reg_lock, flags); in snd_es18xx_write()
199 dev_dbg(chip->card->dev, "Reg %02x set to %02x\n", reg, data); in snd_es18xx_write()
204 static int snd_es18xx_read(struct snd_es18xx *chip, unsigned char reg) in snd_es18xx_read() argument
208 spin_lock_irqsave(&chip->reg_lock, flags); in snd_es18xx_read()
209 ret = snd_es18xx_dsp_command(chip, 0xC0); in snd_es18xx_read()
212 ret = snd_es18xx_dsp_command(chip, reg); in snd_es18xx_read()
215 data = snd_es18xx_dsp_get_byte(chip); in snd_es18xx_read()
218 dev_dbg(chip->card->dev, "Reg %02x now is %02x (%d)\n", reg, data, ret); in snd_es18xx_read()
221 spin_unlock_irqrestore(&chip->reg_lock, flags); in snd_es18xx_read()
226 static int snd_es18xx_bits(struct snd_es18xx *chip, unsigned char reg, in snd_es18xx_bits() argument
232 spin_lock_irqsave(&chip->reg_lock, flags); in snd_es18xx_bits()
233 ret = snd_es18xx_dsp_command(chip, 0xC0); in snd_es18xx_bits()
236 ret = snd_es18xx_dsp_command(chip, reg); in snd_es18xx_bits()
239 ret = snd_es18xx_dsp_get_byte(chip); in snd_es18xx_bits()
246 ret = snd_es18xx_dsp_command(chip, reg); in snd_es18xx_bits()
250 ret = snd_es18xx_dsp_command(chip, new); in snd_es18xx_bits()
254 dev_dbg(chip->card->dev, "Reg %02x was %02x, set to %02x (%d)\n", in snd_es18xx_bits()
260 spin_unlock_irqrestore(&chip->reg_lock, flags); in snd_es18xx_bits()
264 static inline void snd_es18xx_mixer_write(struct snd_es18xx *chip, in snd_es18xx_mixer_write() argument
268 spin_lock_irqsave(&chip->mixer_lock, flags); in snd_es18xx_mixer_write()
269 outb(reg, chip->port + 0x04); in snd_es18xx_mixer_write()
270 outb(data, chip->port + 0x05); in snd_es18xx_mixer_write()
271 spin_unlock_irqrestore(&chip->mixer_lock, flags); in snd_es18xx_mixer_write()
273 dev_dbg(chip->card->dev, "Mixer reg %02x set to %02x\n", reg, data); in snd_es18xx_mixer_write()
277 static inline int snd_es18xx_mixer_read(struct snd_es18xx *chip, unsigned char reg) in snd_es18xx_mixer_read() argument
281 spin_lock_irqsave(&chip->mixer_lock, flags); in snd_es18xx_mixer_read()
282 outb(reg, chip->port + 0x04); in snd_es18xx_mixer_read()
283 data = inb(chip->port + 0x05); in snd_es18xx_mixer_read()
284 spin_unlock_irqrestore(&chip->mixer_lock, flags); in snd_es18xx_mixer_read()
286 dev_dbg(chip->card->dev, "Mixer reg %02x now is %02x\n", reg, data); in snd_es18xx_mixer_read()
292 static inline int snd_es18xx_mixer_bits(struct snd_es18xx *chip, unsigned char reg, in snd_es18xx_mixer_bits() argument
297 spin_lock_irqsave(&chip->mixer_lock, flags); in snd_es18xx_mixer_bits()
298 outb(reg, chip->port + 0x04); in snd_es18xx_mixer_bits()
299 old = inb(chip->port + 0x05); in snd_es18xx_mixer_bits()
303 outb(new, chip->port + 0x05); in snd_es18xx_mixer_bits()
305 dev_dbg(chip->card->dev, "Mixer reg %02x was %02x, set to %02x\n", in snd_es18xx_mixer_bits()
309 spin_unlock_irqrestore(&chip->mixer_lock, flags); in snd_es18xx_mixer_bits()
313 static inline int snd_es18xx_mixer_writable(struct snd_es18xx *chip, unsigned char reg, in snd_es18xx_mixer_writable() argument
318 spin_lock_irqsave(&chip->mixer_lock, flags); in snd_es18xx_mixer_writable()
319 outb(reg, chip->port + 0x04); in snd_es18xx_mixer_writable()
320 old = inb(chip->port + 0x05); in snd_es18xx_mixer_writable()
322 outb(expected, chip->port + 0x05); in snd_es18xx_mixer_writable()
323 new = inb(chip->port + 0x05); in snd_es18xx_mixer_writable()
324 spin_unlock_irqrestore(&chip->mixer_lock, flags); in snd_es18xx_mixer_writable()
326 dev_dbg(chip->card->dev, "Mixer reg %02x was %02x, set to %02x, now is %02x\n", in snd_es18xx_mixer_writable()
333 static int snd_es18xx_reset(struct snd_es18xx *chip) in snd_es18xx_reset() argument
336 outb(0x03, chip->port + 0x06); in snd_es18xx_reset()
337 inb(chip->port + 0x06); in snd_es18xx_reset()
338 outb(0x00, chip->port + 0x06); in snd_es18xx_reset()
339 for(i = 0; i < MILLISECOND && !(inb(chip->port + 0x0E) & 0x80); i++); in snd_es18xx_reset()
340 if (inb(chip->port + 0x0A) != 0xAA) in snd_es18xx_reset()
341 return -1; in snd_es18xx_reset()
345 static int snd_es18xx_reset_fifo(struct snd_es18xx *chip) in snd_es18xx_reset_fifo() argument
347 outb(0x02, chip->port + 0x06); in snd_es18xx_reset_fifo()
348 inb(chip->port + 0x06); in snd_es18xx_reset_fifo()
349 outb(0x00, chip->port + 0x06); in snd_es18xx_reset_fifo()
394 static void snd_es18xx_rate_set(struct snd_es18xx *chip, in snd_es18xx_rate_set() argument
399 struct snd_pcm_runtime *runtime = substream->runtime; in snd_es18xx_rate_set()
400 if (chip->caps & ES18XX_NEW_RATE) { in snd_es18xx_rate_set()
401 if (runtime->rate_num == new_clocks[0].num) in snd_es18xx_rate_set()
402 bits = 128 - runtime->rate_den; in snd_es18xx_rate_set()
404 bits = 256 - runtime->rate_den; in snd_es18xx_rate_set()
406 if (runtime->rate_num == old_clocks[0].num) in snd_es18xx_rate_set()
407 bits = 256 - runtime->rate_den; in snd_es18xx_rate_set()
409 bits = 128 - runtime->rate_den; in snd_es18xx_rate_set()
413 div0 = 256 - 7160000*20/(8*82*runtime->rate); in snd_es18xx_rate_set()
415 if ((chip->caps & ES18XX_PCM2) && mode == DAC2) { in snd_es18xx_rate_set()
416 snd_es18xx_mixer_write(chip, 0x70, bits); in snd_es18xx_rate_set()
421 snd_es18xx_write(chip, 0xA2, div0); in snd_es18xx_rate_set()
422 snd_es18xx_mixer_write(chip, 0x72, div0); in snd_es18xx_rate_set()
424 snd_es18xx_write(chip, 0xA1, bits); in snd_es18xx_rate_set()
425 snd_es18xx_write(chip, 0xA2, div0); in snd_es18xx_rate_set()
432 struct snd_es18xx *chip = snd_pcm_substream_chip(substream); in snd_es18xx_playback_hw_params() local
441 if (substream->number == 0 && (chip->caps & ES18XX_PCM2)) { in snd_es18xx_playback_hw_params()
442 if ((chip->caps & ES18XX_DUPLEX_MONO) && in snd_es18xx_playback_hw_params()
443 (chip->capture_a_substream) && in snd_es18xx_playback_hw_params()
446 return -EBUSY; in snd_es18xx_playback_hw_params()
448 chip->dma2_shift = shift; in snd_es18xx_playback_hw_params()
450 chip->dma1_shift = shift; in snd_es18xx_playback_hw_params()
455 static int snd_es18xx_playback1_prepare(struct snd_es18xx *chip, in snd_es18xx_playback1_prepare() argument
458 struct snd_pcm_runtime *runtime = substream->runtime; in snd_es18xx_playback1_prepare()
462 snd_es18xx_rate_set(chip, substream, DAC2); in snd_es18xx_playback1_prepare()
465 count = 0x10000 - count; in snd_es18xx_playback1_prepare()
466 snd_es18xx_mixer_write(chip, 0x74, count & 0xff); in snd_es18xx_playback1_prepare()
467 snd_es18xx_mixer_write(chip, 0x76, count >> 8); in snd_es18xx_playback1_prepare()
470 snd_es18xx_mixer_bits(chip, 0x7A, 0x07, in snd_es18xx_playback1_prepare()
471 ((runtime->channels == 1) ? 0x00 : 0x02) | in snd_es18xx_playback1_prepare()
472 (snd_pcm_format_width(runtime->format) == 16 ? 0x01 : 0x00) | in snd_es18xx_playback1_prepare()
473 (snd_pcm_format_unsigned(runtime->format) ? 0x00 : 0x04)); in snd_es18xx_playback1_prepare()
476 snd_dma_program(chip->dma2, runtime->dma_addr, size, DMA_MODE_WRITE | DMA_AUTOINIT); in snd_es18xx_playback1_prepare()
481 static int snd_es18xx_playback1_trigger(struct snd_es18xx *chip, in snd_es18xx_playback1_trigger() argument
488 if (chip->active & DAC2) in snd_es18xx_playback1_trigger()
490 chip->active |= DAC2; in snd_es18xx_playback1_trigger()
492 if (chip->dma2 >= 4) in snd_es18xx_playback1_trigger()
493 snd_es18xx_mixer_write(chip, 0x78, 0xb3); in snd_es18xx_playback1_trigger()
495 snd_es18xx_mixer_write(chip, 0x78, 0x93); in snd_es18xx_playback1_trigger()
499 if (chip->caps & ES18XX_PCM2) in snd_es18xx_playback1_trigger()
501 snd_es18xx_mixer_write(chip, 0x7C, chip->audio2_vol); in snd_es18xx_playback1_trigger()
504 snd_es18xx_dsp_command(chip, 0xD1); in snd_es18xx_playback1_trigger()
509 if (!(chip->active & DAC2)) in snd_es18xx_playback1_trigger()
511 chip->active &= ~DAC2; in snd_es18xx_playback1_trigger()
513 snd_es18xx_mixer_write(chip, 0x78, 0x00); in snd_es18xx_playback1_trigger()
516 if (chip->caps & ES18XX_PCM2) in snd_es18xx_playback1_trigger()
518 snd_es18xx_mixer_write(chip, 0x7C, 0); in snd_es18xx_playback1_trigger()
521 snd_es18xx_dsp_command(chip, 0xD3); in snd_es18xx_playback1_trigger()
525 return -EINVAL; in snd_es18xx_playback1_trigger()
534 struct snd_es18xx *chip = snd_pcm_substream_chip(substream); in snd_es18xx_capture_hw_params() local
538 if ((chip->caps & ES18XX_DUPLEX_MONO) && in snd_es18xx_capture_hw_params()
539 chip->playback_a_substream && in snd_es18xx_capture_hw_params()
542 return -EBUSY; in snd_es18xx_capture_hw_params()
548 chip->dma1_shift = shift; in snd_es18xx_capture_hw_params()
554 struct snd_es18xx *chip = snd_pcm_substream_chip(substream); in snd_es18xx_capture_prepare() local
555 struct snd_pcm_runtime *runtime = substream->runtime; in snd_es18xx_capture_prepare()
559 snd_es18xx_reset_fifo(chip); in snd_es18xx_capture_prepare()
562 snd_es18xx_bits(chip, 0xA8, 0x03, runtime->channels == 1 ? 0x02 : 0x01); in snd_es18xx_capture_prepare()
564 snd_es18xx_rate_set(chip, substream, ADC1); in snd_es18xx_capture_prepare()
567 count = 0x10000 - count; in snd_es18xx_capture_prepare()
568 snd_es18xx_write(chip, 0xA4, count & 0xff); in snd_es18xx_capture_prepare()
569 snd_es18xx_write(chip, 0xA5, count >> 8); in snd_es18xx_capture_prepare()
576 snd_es18xx_write(chip, 0xB7, in snd_es18xx_capture_prepare()
577 snd_pcm_format_unsigned(runtime->format) ? 0x51 : 0x71); in snd_es18xx_capture_prepare()
578 snd_es18xx_write(chip, 0xB7, 0x90 | in snd_es18xx_capture_prepare()
579 ((runtime->channels == 1) ? 0x40 : 0x08) | in snd_es18xx_capture_prepare()
580 (snd_pcm_format_width(runtime->format) == 16 ? 0x04 : 0x00) | in snd_es18xx_capture_prepare()
581 (snd_pcm_format_unsigned(runtime->format) ? 0x00 : 0x20)); in snd_es18xx_capture_prepare()
584 snd_dma_program(chip->dma1, runtime->dma_addr, size, DMA_MODE_READ | DMA_AUTOINIT); in snd_es18xx_capture_prepare()
592 struct snd_es18xx *chip = snd_pcm_substream_chip(substream); in snd_es18xx_capture_trigger() local
597 if (chip->active & ADC1) in snd_es18xx_capture_trigger()
599 chip->active |= ADC1; in snd_es18xx_capture_trigger()
601 snd_es18xx_write(chip, 0xB8, 0x0f); in snd_es18xx_capture_trigger()
605 if (!(chip->active & ADC1)) in snd_es18xx_capture_trigger()
607 chip->active &= ~ADC1; in snd_es18xx_capture_trigger()
609 snd_es18xx_write(chip, 0xB8, 0x00); in snd_es18xx_capture_trigger()
612 return -EINVAL; in snd_es18xx_capture_trigger()
618 static int snd_es18xx_playback2_prepare(struct snd_es18xx *chip, in snd_es18xx_playback2_prepare() argument
621 struct snd_pcm_runtime *runtime = substream->runtime; in snd_es18xx_playback2_prepare()
625 snd_es18xx_reset_fifo(chip); in snd_es18xx_playback2_prepare()
628 snd_es18xx_bits(chip, 0xA8, 0x03, runtime->channels == 1 ? 0x02 : 0x01); in snd_es18xx_playback2_prepare()
630 snd_es18xx_rate_set(chip, substream, DAC1); in snd_es18xx_playback2_prepare()
633 count = 0x10000 - count; in snd_es18xx_playback2_prepare()
634 snd_es18xx_write(chip, 0xA4, count & 0xff); in snd_es18xx_playback2_prepare()
635 snd_es18xx_write(chip, 0xA5, count >> 8); in snd_es18xx_playback2_prepare()
638 snd_es18xx_write(chip, 0xB6, in snd_es18xx_playback2_prepare()
639 snd_pcm_format_unsigned(runtime->format) ? 0x80 : 0x00); in snd_es18xx_playback2_prepare()
640 snd_es18xx_write(chip, 0xB7, in snd_es18xx_playback2_prepare()
641 snd_pcm_format_unsigned(runtime->format) ? 0x51 : 0x71); in snd_es18xx_playback2_prepare()
642 snd_es18xx_write(chip, 0xB7, 0x90 | in snd_es18xx_playback2_prepare()
643 (runtime->channels == 1 ? 0x40 : 0x08) | in snd_es18xx_playback2_prepare()
644 (snd_pcm_format_width(runtime->format) == 16 ? 0x04 : 0x00) | in snd_es18xx_playback2_prepare()
645 (snd_pcm_format_unsigned(runtime->format) ? 0x00 : 0x20)); in snd_es18xx_playback2_prepare()
648 snd_dma_program(chip->dma1, runtime->dma_addr, size, DMA_MODE_WRITE | DMA_AUTOINIT); in snd_es18xx_playback2_prepare()
653 static int snd_es18xx_playback2_trigger(struct snd_es18xx *chip, in snd_es18xx_playback2_trigger() argument
660 if (chip->active & DAC1) in snd_es18xx_playback2_trigger()
662 chip->active |= DAC1; in snd_es18xx_playback2_trigger()
664 snd_es18xx_write(chip, 0xB8, 0x05); in snd_es18xx_playback2_trigger()
669 snd_es18xx_dsp_command(chip, 0xD1); in snd_es18xx_playback2_trigger()
674 if (!(chip->active & DAC1)) in snd_es18xx_playback2_trigger()
676 chip->active &= ~DAC1; in snd_es18xx_playback2_trigger()
678 snd_es18xx_write(chip, 0xB8, 0x00); in snd_es18xx_playback2_trigger()
683 snd_es18xx_dsp_command(chip, 0xD3); in snd_es18xx_playback2_trigger()
687 return -EINVAL; in snd_es18xx_playback2_trigger()
695 struct snd_es18xx *chip = snd_pcm_substream_chip(substream); in snd_es18xx_playback_prepare() local
696 if (substream->number == 0 && (chip->caps & ES18XX_PCM2)) in snd_es18xx_playback_prepare()
697 return snd_es18xx_playback1_prepare(chip, substream); in snd_es18xx_playback_prepare()
699 return snd_es18xx_playback2_prepare(chip, substream); in snd_es18xx_playback_prepare()
705 struct snd_es18xx *chip = snd_pcm_substream_chip(substream); in snd_es18xx_playback_trigger() local
706 if (substream->number == 0 && (chip->caps & ES18XX_PCM2)) in snd_es18xx_playback_trigger()
707 return snd_es18xx_playback1_trigger(chip, substream, cmd); in snd_es18xx_playback_trigger()
709 return snd_es18xx_playback2_trigger(chip, substream, cmd); in snd_es18xx_playback_trigger()
715 struct snd_es18xx *chip = card->private_data; in snd_es18xx_interrupt() local
718 if (chip->caps & ES18XX_CONTROL) { in snd_es18xx_interrupt()
720 status = inb(chip->ctrl_port + 6); in snd_es18xx_interrupt()
723 status = snd_es18xx_mixer_read(chip, 0x7f) >> 4; in snd_es18xx_interrupt()
728 if (inb(chip->port + 0x0C) & 0x01) in snd_es18xx_interrupt()
730 if (snd_es18xx_mixer_read(chip, 0x7A) & 0x80) in snd_es18xx_interrupt()
732 if ((chip->caps & ES18XX_HWV) && in snd_es18xx_interrupt()
733 snd_es18xx_mixer_read(chip, 0x64) & 0x10) in snd_es18xx_interrupt()
740 if (chip->active & DAC2) in snd_es18xx_interrupt()
741 snd_pcm_period_elapsed(chip->playback_a_substream); in snd_es18xx_interrupt()
743 snd_es18xx_mixer_bits(chip, 0x7A, 0x80, 0x00); in snd_es18xx_interrupt()
747 if (chip->active & ADC1) in snd_es18xx_interrupt()
748 snd_pcm_period_elapsed(chip->capture_a_substream); in snd_es18xx_interrupt()
750 else if (chip->active & DAC1) in snd_es18xx_interrupt()
751 snd_pcm_period_elapsed(chip->playback_b_substream); in snd_es18xx_interrupt()
753 inb(chip->port + 0x0E); in snd_es18xx_interrupt()
757 if ((status & MPU_IRQ) && chip->rmidi) in snd_es18xx_interrupt()
758 snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data); in snd_es18xx_interrupt()
763 if (chip->caps & ES18XX_HWV) { in snd_es18xx_interrupt()
764 split = snd_es18xx_mixer_read(chip, 0x64) & 0x80; in snd_es18xx_interrupt()
766 &chip->hw_switch->id); in snd_es18xx_interrupt()
768 &chip->hw_volume->id); in snd_es18xx_interrupt()
772 &chip->master_switch->id); in snd_es18xx_interrupt()
774 &chip->master_volume->id); in snd_es18xx_interrupt()
777 snd_es18xx_mixer_write(chip, 0x66, 0x00); in snd_es18xx_interrupt()
784 struct snd_es18xx *chip = snd_pcm_substream_chip(substream); in snd_es18xx_playback_pointer() local
788 if (substream->number == 0 && (chip->caps & ES18XX_PCM2)) { in snd_es18xx_playback_pointer()
789 if (!(chip->active & DAC2)) in snd_es18xx_playback_pointer()
791 pos = snd_dma_pointer(chip->dma2, size); in snd_es18xx_playback_pointer()
792 return pos >> chip->dma2_shift; in snd_es18xx_playback_pointer()
794 if (!(chip->active & DAC1)) in snd_es18xx_playback_pointer()
796 pos = snd_dma_pointer(chip->dma1, size); in snd_es18xx_playback_pointer()
797 return pos >> chip->dma1_shift; in snd_es18xx_playback_pointer()
803 struct snd_es18xx *chip = snd_pcm_substream_chip(substream); in snd_es18xx_capture_pointer() local
807 if (!(chip->active & ADC1)) in snd_es18xx_capture_pointer()
809 pos = snd_dma_pointer(chip->dma1, size); in snd_es18xx_capture_pointer()
810 return pos >> chip->dma1_shift; in snd_es18xx_capture_pointer()
855 struct snd_pcm_runtime *runtime = substream->runtime; in snd_es18xx_playback_open()
856 struct snd_es18xx *chip = snd_pcm_substream_chip(substream); in snd_es18xx_playback_open() local
858 if (substream->number == 0 && (chip->caps & ES18XX_PCM2)) { in snd_es18xx_playback_open()
859 if ((chip->caps & ES18XX_DUPLEX_MONO) && in snd_es18xx_playback_open()
860 chip->capture_a_substream && in snd_es18xx_playback_open()
861 chip->capture_a_substream->runtime->channels != 1) in snd_es18xx_playback_open()
862 return -EAGAIN; in snd_es18xx_playback_open()
863 chip->playback_a_substream = substream; in snd_es18xx_playback_open()
864 } else if (substream->number <= 1) { in snd_es18xx_playback_open()
865 if (chip->capture_a_substream) in snd_es18xx_playback_open()
866 return -EAGAIN; in snd_es18xx_playback_open()
867 chip->playback_b_substream = substream; in snd_es18xx_playback_open()
870 return -EINVAL; in snd_es18xx_playback_open()
872 substream->runtime->hw = snd_es18xx_playback; in snd_es18xx_playback_open()
874 (chip->caps & ES18XX_NEW_RATE) ? &new_hw_constraints_clocks : &old_hw_constraints_clocks); in snd_es18xx_playback_open()
880 struct snd_pcm_runtime *runtime = substream->runtime; in snd_es18xx_capture_open()
881 struct snd_es18xx *chip = snd_pcm_substream_chip(substream); in snd_es18xx_capture_open() local
883 if (chip->playback_b_substream) in snd_es18xx_capture_open()
884 return -EAGAIN; in snd_es18xx_capture_open()
885 if ((chip->caps & ES18XX_DUPLEX_MONO) && in snd_es18xx_capture_open()
886 chip->playback_a_substream && in snd_es18xx_capture_open()
887 chip->playback_a_substream->runtime->channels != 1) in snd_es18xx_capture_open()
888 return -EAGAIN; in snd_es18xx_capture_open()
889 chip->capture_a_substream = substream; in snd_es18xx_capture_open()
890 substream->runtime->hw = snd_es18xx_capture; in snd_es18xx_capture_open()
892 (chip->caps & ES18XX_NEW_RATE) ? &new_hw_constraints_clocks : &old_hw_constraints_clocks); in snd_es18xx_capture_open()
898 struct snd_es18xx *chip = snd_pcm_substream_chip(substream); in snd_es18xx_playback_close() local
900 if (substream->number == 0 && (chip->caps & ES18XX_PCM2)) in snd_es18xx_playback_close()
901 chip->playback_a_substream = NULL; in snd_es18xx_playback_close()
903 chip->playback_b_substream = NULL; in snd_es18xx_playback_close()
910 struct snd_es18xx *chip = snd_pcm_substream_chip(substream); in snd_es18xx_capture_close() local
912 chip->capture_a_substream = NULL; in snd_es18xx_capture_close()
945 struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol); in snd_es18xx_info_mux() local
947 switch (chip->version) { in snd_es18xx_info_mux()
958 return -EINVAL; in snd_es18xx_info_mux()
965 struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol); in snd_es18xx_get_mux() local
966 int muxSource = snd_es18xx_mixer_read(chip, 0x1c) & 0x07; in snd_es18xx_get_mux()
967 if (!(chip->version == 0x1869 || chip->version == 0x1879)) { in snd_es18xx_get_mux()
970 (chip->version == 0x1887 || chip->version == 0x1888) && in snd_es18xx_get_mux()
971 (snd_es18xx_mixer_read(chip, 0x7a) & 0x08) in snd_es18xx_get_mux()
975 ucontrol->value.enumerated.item[0] = muxSource; in snd_es18xx_get_mux()
982 struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol); in snd_es18xx_put_mux() local
983 unsigned char val = ucontrol->value.enumerated.item[0]; in snd_es18xx_put_mux()
986 switch (chip->version) { in snd_es18xx_put_mux()
991 return -EINVAL; in snd_es18xx_put_mux()
993 retVal = snd_es18xx_mixer_bits(chip, 0x7a, 0x08, 0x08) != 0x08; in snd_es18xx_put_mux()
996 retVal = snd_es18xx_mixer_bits(chip, 0x7a, 0x08, 0x00) != 0x00; in snd_es18xx_put_mux()
1002 return -EINVAL; in snd_es18xx_put_mux()
1009 return -EINVAL; in snd_es18xx_put_mux()
1012 return -EINVAL; in snd_es18xx_put_mux()
1014 return (snd_es18xx_mixer_bits(chip, 0x1c, 0x07, val) != val) || retVal; in snd_es18xx_put_mux()
1021 struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol); in snd_es18xx_get_spatializer_enable() local
1022 unsigned char val = snd_es18xx_mixer_read(chip, 0x50); in snd_es18xx_get_spatializer_enable()
1023 ucontrol->value.integer.value[0] = !!(val & 8); in snd_es18xx_get_spatializer_enable()
1029 struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol); in snd_es18xx_put_spatializer_enable() local
1032 nval = ucontrol->value.integer.value[0] ? 0x0c : 0x04; in snd_es18xx_put_spatializer_enable()
1033 oval = snd_es18xx_mixer_read(chip, 0x50) & 0x0c; in snd_es18xx_put_spatializer_enable()
1036 snd_es18xx_mixer_write(chip, 0x50, nval & ~0x04); in snd_es18xx_put_spatializer_enable()
1037 snd_es18xx_mixer_write(chip, 0x50, nval); in snd_es18xx_put_spatializer_enable()
1044 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in snd_es18xx_info_hw_volume()
1045 uinfo->count = 2; in snd_es18xx_info_hw_volume()
1046 uinfo->value.integer.min = 0; in snd_es18xx_info_hw_volume()
1047 uinfo->value.integer.max = 63; in snd_es18xx_info_hw_volume()
1053 struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol); in snd_es18xx_get_hw_volume() local
1054 ucontrol->value.integer.value[0] = snd_es18xx_mixer_read(chip, 0x61) & 0x3f; in snd_es18xx_get_hw_volume()
1055 ucontrol->value.integer.value[1] = snd_es18xx_mixer_read(chip, 0x63) & 0x3f; in snd_es18xx_get_hw_volume()
1063 struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol); in snd_es18xx_get_hw_switch() local
1064 ucontrol->value.integer.value[0] = !(snd_es18xx_mixer_read(chip, 0x61) & 0x40); in snd_es18xx_get_hw_switch()
1065 ucontrol->value.integer.value[1] = !(snd_es18xx_mixer_read(chip, 0x63) & 0x40); in snd_es18xx_get_hw_switch()
1071 struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol); in snd_es18xx_hwv_free() local
1072 chip->master_volume = NULL; in snd_es18xx_hwv_free()
1073 chip->master_switch = NULL; in snd_es18xx_hwv_free()
1074 chip->hw_volume = NULL; in snd_es18xx_hwv_free()
1075 chip->hw_switch = NULL; in snd_es18xx_hwv_free()
1078 static int snd_es18xx_reg_bits(struct snd_es18xx *chip, unsigned char reg, in snd_es18xx_reg_bits() argument
1082 return snd_es18xx_mixer_bits(chip, reg, mask, val); in snd_es18xx_reg_bits()
1084 return snd_es18xx_bits(chip, reg, mask, val); in snd_es18xx_reg_bits()
1087 static int snd_es18xx_reg_read(struct snd_es18xx *chip, unsigned char reg) in snd_es18xx_reg_read() argument
1090 return snd_es18xx_mixer_read(chip, reg); in snd_es18xx_reg_read()
1092 return snd_es18xx_read(chip, reg); in snd_es18xx_reg_read()
1106 int mask = (kcontrol->private_value >> 16) & 0xff; in snd_es18xx_info_single()
1108 uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER; in snd_es18xx_info_single()
1109 uinfo->count = 1; in snd_es18xx_info_single()
1110 uinfo->value.integer.min = 0; in snd_es18xx_info_single()
1111 uinfo->value.integer.max = mask; in snd_es18xx_info_single()
1117 struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol); in snd_es18xx_get_single() local
1118 int reg = kcontrol->private_value & 0xff; in snd_es18xx_get_single()
1119 int shift = (kcontrol->private_value >> 8) & 0xff; in snd_es18xx_get_single()
1120 int mask = (kcontrol->private_value >> 16) & 0xff; in snd_es18xx_get_single()
1121 int invert = (kcontrol->private_value >> 24) & ES18XX_FL_INVERT; in snd_es18xx_get_single()
1122 int pm_port = (kcontrol->private_value >> 24) & ES18XX_FL_PMPORT; in snd_es18xx_get_single()
1126 val = inb(chip->port + ES18XX_PM); in snd_es18xx_get_single()
1128 val = snd_es18xx_reg_read(chip, reg); in snd_es18xx_get_single()
1129 ucontrol->value.integer.value[0] = (val >> shift) & mask; in snd_es18xx_get_single()
1131 ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0]; in snd_es18xx_get_single()
1137 struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol); in snd_es18xx_put_single() local
1138 int reg = kcontrol->private_value & 0xff; in snd_es18xx_put_single()
1139 int shift = (kcontrol->private_value >> 8) & 0xff; in snd_es18xx_put_single()
1140 int mask = (kcontrol->private_value >> 16) & 0xff; in snd_es18xx_put_single()
1141 int invert = (kcontrol->private_value >> 24) & ES18XX_FL_INVERT; in snd_es18xx_put_single()
1142 int pm_port = (kcontrol->private_value >> 24) & ES18XX_FL_PMPORT; in snd_es18xx_put_single()
1145 val = (ucontrol->value.integer.value[0] & mask); in snd_es18xx_put_single()
1147 val = mask - val; in snd_es18xx_put_single()
1151 unsigned char cur = inb(chip->port + ES18XX_PM); in snd_es18xx_put_single()
1155 outb((cur & ~mask) | val, chip->port + ES18XX_PM); in snd_es18xx_put_single()
1159 return snd_es18xx_reg_bits(chip, reg, mask, val) != val; in snd_es18xx_put_single()
1170 int mask = (kcontrol->private_value >> 24) & 0xff; in snd_es18xx_info_double()
1172 uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER; in snd_es18xx_info_double()
1173 uinfo->count = 2; in snd_es18xx_info_double()
1174 uinfo->value.integer.min = 0; in snd_es18xx_info_double()
1175 uinfo->value.integer.max = mask; in snd_es18xx_info_double()
1181 struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol); in snd_es18xx_get_double() local
1182 int left_reg = kcontrol->private_value & 0xff; in snd_es18xx_get_double()
1183 int right_reg = (kcontrol->private_value >> 8) & 0xff; in snd_es18xx_get_double()
1184 int shift_left = (kcontrol->private_value >> 16) & 0x07; in snd_es18xx_get_double()
1185 int shift_right = (kcontrol->private_value >> 19) & 0x07; in snd_es18xx_get_double()
1186 int mask = (kcontrol->private_value >> 24) & 0xff; in snd_es18xx_get_double()
1187 int invert = (kcontrol->private_value >> 22) & 1; in snd_es18xx_get_double()
1190 left = snd_es18xx_reg_read(chip, left_reg); in snd_es18xx_get_double()
1192 right = snd_es18xx_reg_read(chip, right_reg); in snd_es18xx_get_double()
1195 ucontrol->value.integer.value[0] = (left >> shift_left) & mask; in snd_es18xx_get_double()
1196 ucontrol->value.integer.value[1] = (right >> shift_right) & mask; in snd_es18xx_get_double()
1198 ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0]; in snd_es18xx_get_double()
1199 ucontrol->value.integer.value[1] = mask - ucontrol->value.integer.value[1]; in snd_es18xx_get_double()
1206 struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol); in snd_es18xx_put_double() local
1207 int left_reg = kcontrol->private_value & 0xff; in snd_es18xx_put_double()
1208 int right_reg = (kcontrol->private_value >> 8) & 0xff; in snd_es18xx_put_double()
1209 int shift_left = (kcontrol->private_value >> 16) & 0x07; in snd_es18xx_put_double()
1210 int shift_right = (kcontrol->private_value >> 19) & 0x07; in snd_es18xx_put_double()
1211 int mask = (kcontrol->private_value >> 24) & 0xff; in snd_es18xx_put_double()
1212 int invert = (kcontrol->private_value >> 22) & 1; in snd_es18xx_put_double()
1216 val1 = ucontrol->value.integer.value[0] & mask; in snd_es18xx_put_double()
1217 val2 = ucontrol->value.integer.value[1] & mask; in snd_es18xx_put_double()
1219 val1 = mask - val1; in snd_es18xx_put_double()
1220 val2 = mask - val2; in snd_es18xx_put_double()
1228 if (snd_es18xx_reg_bits(chip, left_reg, mask1, val1) != val1) in snd_es18xx_put_double()
1230 if (snd_es18xx_reg_bits(chip, right_reg, mask2, val2) != val2) in snd_es18xx_put_double()
1233 change = (snd_es18xx_reg_bits(chip, left_reg, mask1 | mask2, in snd_es18xx_put_double()
1305 ES18XX_SINGLE("3D Control - Level", 0, 0x52, 0, 63, 0),
1308 .name = "3D Control - Switch",
1344 static int snd_es18xx_config_read(struct snd_es18xx *chip, unsigned char reg) in snd_es18xx_config_read() argument
1346 outb(reg, chip->ctrl_port); in snd_es18xx_config_read()
1347 return inb(chip->ctrl_port + 1); in snd_es18xx_config_read()
1350 static void snd_es18xx_config_write(struct snd_es18xx *chip, in snd_es18xx_config_write() argument
1355 outb(reg, chip->ctrl_port); in snd_es18xx_config_write()
1356 outb(data, chip->ctrl_port + 1); in snd_es18xx_config_write()
1358 dev_dbg(chip->card->dev, "Config reg %02x set to %02x\n", reg, data); in snd_es18xx_config_write()
1362 static int snd_es18xx_initialize(struct snd_es18xx *chip, in snd_es18xx_initialize() argument
1369 snd_es18xx_dsp_command(chip, 0xC6); in snd_es18xx_initialize()
1371 snd_es18xx_mixer_write(chip, 0x00, 0x00); in snd_es18xx_initialize()
1374 snd_es18xx_write(chip, 0xB9, 2); in snd_es18xx_initialize()
1375 if (chip->caps & ES18XX_CONTROL) { in snd_es18xx_initialize()
1377 snd_es18xx_config_write(chip, 0x27, chip->irq); in snd_es18xx_initialize()
1380 snd_es18xx_config_write(chip, 0x62, fm_port >> 8); in snd_es18xx_initialize()
1381 snd_es18xx_config_write(chip, 0x63, fm_port & 0xff); in snd_es18xx_initialize()
1384 /* MPU-401 I/O */ in snd_es18xx_initialize()
1385 snd_es18xx_config_write(chip, 0x64, mpu_port >> 8); in snd_es18xx_initialize()
1386 snd_es18xx_config_write(chip, 0x65, mpu_port & 0xff); in snd_es18xx_initialize()
1387 /* MPU-401 IRQ */ in snd_es18xx_initialize()
1388 snd_es18xx_config_write(chip, 0x28, chip->irq); in snd_es18xx_initialize()
1391 snd_es18xx_config_write(chip, 0x70, chip->irq); in snd_es18xx_initialize()
1393 snd_es18xx_config_write(chip, 0x72, chip->irq); in snd_es18xx_initialize()
1395 snd_es18xx_config_write(chip, 0x74, chip->dma1); in snd_es18xx_initialize()
1397 snd_es18xx_config_write(chip, 0x75, chip->dma2); in snd_es18xx_initialize()
1400 snd_es18xx_write(chip, 0xB1, 0x50); in snd_es18xx_initialize()
1402 snd_es18xx_mixer_write(chip, 0x7A, 0x40); in snd_es18xx_initialize()
1404 snd_es18xx_write(chip, 0xB2, 0x50); in snd_es18xx_initialize()
1406 snd_es18xx_mixer_write(chip, 0x64, 0x42); in snd_es18xx_initialize()
1408 snd_es18xx_mixer_bits(chip, 0x48, 0x10, 0x10); in snd_es18xx_initialize()
1412 switch (chip->irq) { in snd_es18xx_initialize()
1427 dev_err(chip->card->dev, "invalid irq %d\n", chip->irq); in snd_es18xx_initialize()
1428 return -ENODEV; in snd_es18xx_initialize()
1430 switch (chip->dma1) { in snd_es18xx_initialize()
1441 dev_err(chip->card->dev, "invalid dma1 %d\n", chip->dma1); in snd_es18xx_initialize()
1442 return -ENODEV; in snd_es18xx_initialize()
1444 switch (chip->dma2) { in snd_es18xx_initialize()
1458 dev_err(chip->card->dev, "invalid dma2 %d\n", chip->dma2); in snd_es18xx_initialize()
1459 return -ENODEV; in snd_es18xx_initialize()
1463 snd_es18xx_write(chip, 0xB1, 0x50 | (irqmask << 2)); in snd_es18xx_initialize()
1465 snd_es18xx_write(chip, 0xB2, 0x50 | (dma1mask << 2)); in snd_es18xx_initialize()
1467 snd_es18xx_mixer_bits(chip, 0x7d, 0x07, 0x04 | dma2mask); in snd_es18xx_initialize()
1470 snd_es18xx_mixer_write(chip, 0x7A, 0x68); in snd_es18xx_initialize()
1472 snd_es18xx_mixer_write(chip, 0x64, 0x06); in snd_es18xx_initialize()
1477 snd_es18xx_mixer_write(chip, 0x40, in snd_es18xx_initialize()
1480 snd_es18xx_mixer_write(chip, 0x7f, ((irqmask + 1) << 1) | 0x01); in snd_es18xx_initialize()
1482 if (chip->caps & ES18XX_NEW_RATE) { in snd_es18xx_initialize()
1486 snd_es18xx_mixer_write(chip, 0x71, 0x32); in snd_es18xx_initialize()
1488 if (!(chip->caps & ES18XX_PCM2)) { in snd_es18xx_initialize()
1490 snd_es18xx_write(chip, 0xB7, 0x80); in snd_es18xx_initialize()
1492 if (chip->caps & ES18XX_SPATIALIZER) { in snd_es18xx_initialize()
1494 snd_es18xx_mixer_write(chip, 0x54, 0x8f); in snd_es18xx_initialize()
1495 snd_es18xx_mixer_write(chip, 0x56, 0x95); in snd_es18xx_initialize()
1496 snd_es18xx_mixer_write(chip, 0x58, 0x94); in snd_es18xx_initialize()
1497 snd_es18xx_mixer_write(chip, 0x5a, 0x80); in snd_es18xx_initialize()
1500 switch (chip->version) { in snd_es18xx_initialize()
1503 //so a Switch control has been added to toggle this 0x71 bit on/off: in snd_es18xx_initialize()
1504 //snd_es18xx_mixer_bits(chip, 0x71, 0x40, 0x40); in snd_es18xx_initialize()
1507 snd_es18xx_config_write(chip, 0x29, snd_es18xx_config_read(chip, 0x29) | 0x40); in snd_es18xx_initialize()
1511 if (chip->caps & ES18XX_MUTEREC) in snd_es18xx_initialize()
1513 if (chip->caps & ES18XX_RECMIX) in snd_es18xx_initialize()
1514 snd_es18xx_mixer_write(chip, 0x1c, 0x05 | mask); in snd_es18xx_initialize()
1516 snd_es18xx_mixer_write(chip, 0x1c, 0x00 | mask); in snd_es18xx_initialize()
1517 snd_es18xx_write(chip, 0xb4, 0x00); in snd_es18xx_initialize()
1521 snd_es18xx_dsp_command(chip, 0xD1); in snd_es18xx_initialize()
1527 static int snd_es18xx_identify(struct snd_card *card, struct snd_es18xx *chip) in snd_es18xx_identify() argument
1532 if (snd_es18xx_reset(chip) < 0) { in snd_es18xx_identify()
1533 dev_err(card->dev, "reset at 0x%lx failed!!!\n", chip->port); in snd_es18xx_identify()
1534 return -ENODEV; in snd_es18xx_identify()
1537 snd_es18xx_dsp_command(chip, 0xe7); in snd_es18xx_identify()
1538 hi = snd_es18xx_dsp_get_byte(chip); in snd_es18xx_identify()
1542 lo = snd_es18xx_dsp_get_byte(chip); in snd_es18xx_identify()
1544 return -ENODEV; in snd_es18xx_identify()
1547 chip->version = 0x488; in snd_es18xx_identify()
1551 return -ENODEV; in snd_es18xx_identify()
1554 chip->version = 0x688; in snd_es18xx_identify()
1558 outb(0x40, chip->port + 0x04); in snd_es18xx_identify()
1560 hi = inb(chip->port + 0x05); in snd_es18xx_identify()
1562 lo = inb(chip->port + 0x05); in snd_es18xx_identify()
1564 chip->version = hi << 8 | lo; in snd_es18xx_identify()
1565 chip->ctrl_port = inb(chip->port + 0x05) << 8; in snd_es18xx_identify()
1567 chip->ctrl_port += inb(chip->port + 0x05); in snd_es18xx_identify()
1569 if (!devm_request_region(card->dev, chip->ctrl_port, 8, in snd_es18xx_identify()
1570 "ES18xx - CTRL")) { in snd_es18xx_identify()
1571 dev_err(card->dev, "unable go grab port 0x%lx\n", chip->ctrl_port); in snd_es18xx_identify()
1572 return -EBUSY; in snd_es18xx_identify()
1578 /* If has Hardware volume */ in snd_es18xx_identify()
1579 if (snd_es18xx_mixer_writable(chip, 0x64, 0x04)) { in snd_es18xx_identify()
1580 /* If has Audio2 */ in snd_es18xx_identify()
1581 if (snd_es18xx_mixer_writable(chip, 0x70, 0x7f)) { in snd_es18xx_identify()
1582 /* If has volume count */ in snd_es18xx_identify()
1583 if (snd_es18xx_mixer_writable(chip, 0x64, 0x20)) { in snd_es18xx_identify()
1584 chip->version = 0x1887; in snd_es18xx_identify()
1586 chip->version = 0x1888; in snd_es18xx_identify()
1589 chip->version = 0x1788; in snd_es18xx_identify()
1593 chip->version = 0x1688; in snd_es18xx_identify()
1598 struct snd_es18xx *chip, in snd_es18xx_probe() argument
1602 if (snd_es18xx_identify(card, chip) < 0) { in snd_es18xx_probe()
1603 dev_err(card->dev, "[0x%lx] ESS chip not found\n", chip->port); in snd_es18xx_probe()
1604 return -ENODEV; in snd_es18xx_probe()
1607 switch (chip->version) { in snd_es18xx_probe()
1609 chip->caps = ES18XX_DUPLEX_MONO | ES18XX_DUPLEX_SAME | ES18XX_CONTROL | ES18XX_GPO_2BIT; in snd_es18xx_probe()
1612chip->caps = ES18XX_PCM2 | ES18XX_SPATIALIZER | ES18XX_RECMIX | ES18XX_NEW_RATE | ES18XX_AUXB | ES… in snd_es18xx_probe()
1615 chip->caps = ES18XX_DUPLEX_MONO | ES18XX_DUPLEX_SAME | ES18XX_I2S | ES18XX_CONTROL; in snd_es18xx_probe()
1618chip->caps = ES18XX_PCM2 | ES18XX_SPATIALIZER | ES18XX_RECMIX | ES18XX_NEW_RATE | ES18XX_AUXB | ES… in snd_es18xx_probe()
1622 chip->caps = ES18XX_PCM2 | ES18XX_RECMIX | ES18XX_AUXB | ES18XX_DUPLEX_SAME | ES18XX_GPO_2BIT; in snd_es18xx_probe()
1625 dev_err(card->dev, "[0x%lx] unsupported chip ES%x\n", in snd_es18xx_probe()
1626 chip->port, chip->version); in snd_es18xx_probe()
1627 return -ENODEV; in snd_es18xx_probe()
1630 dev_dbg(card->dev, "[0x%lx] ESS%x chip found\n", chip->port, chip->version); in snd_es18xx_probe()
1632 if (chip->dma1 == chip->dma2) in snd_es18xx_probe()
1633 chip->caps &= ~(ES18XX_PCM2 | ES18XX_DUPLEX_SAME); in snd_es18xx_probe()
1635 return snd_es18xx_initialize(chip, mpu_port, fm_port); in snd_es18xx_probe()
1658 struct snd_es18xx *chip = card->private_data; in snd_es18xx_pcm() local
1663 sprintf(str, "ES%x", chip->version); in snd_es18xx_pcm()
1664 if (chip->caps & ES18XX_PCM2) in snd_es18xx_pcm()
1675 pcm->private_data = chip; in snd_es18xx_pcm()
1676 pcm->info_flags = 0; in snd_es18xx_pcm()
1677 if (chip->caps & ES18XX_DUPLEX_SAME) in snd_es18xx_pcm()
1678 pcm->info_flags |= SNDRV_PCM_INFO_JOINT_DUPLEX; in snd_es18xx_pcm()
1679 if (! (chip->caps & ES18XX_PCM2)) in snd_es18xx_pcm()
1680 pcm->info_flags |= SNDRV_PCM_INFO_HALF_DUPLEX; in snd_es18xx_pcm()
1681 sprintf(pcm->name, "ESS AudioDrive ES%x", chip->version); in snd_es18xx_pcm()
1682 chip->pcm = pcm; in snd_es18xx_pcm()
1684 snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV, card->dev, in snd_es18xx_pcm()
1686 chip->dma1 > 3 || chip->dma2 > 3 ? 128*1024 : 64*1024); in snd_es18xx_pcm()
1694 struct snd_es18xx *chip = card->private_data; in snd_es18xx_suspend() local
1699 chip->pm_reg = (unsigned char)snd_es18xx_read(chip, ES18XX_PM); in snd_es18xx_suspend()
1700 chip->pm_reg |= (ES18XX_PM_FM | ES18XX_PM_SUS); in snd_es18xx_suspend()
1701 snd_es18xx_write(chip, ES18XX_PM, chip->pm_reg); in snd_es18xx_suspend()
1702 snd_es18xx_write(chip, ES18XX_PM, chip->pm_reg ^= ES18XX_PM_SUS); in snd_es18xx_suspend()
1709 struct snd_es18xx *chip = card->private_data; in snd_es18xx_resume() local
1712 snd_es18xx_write(chip, ES18XX_PM, chip->pm_reg ^= ES18XX_PM_FM); in snd_es18xx_resume()
1725 struct snd_es18xx *chip = card->private_data; in snd_es18xx_new_device() local
1727 chip->card = card; in snd_es18xx_new_device()
1728 spin_lock_init(&chip->reg_lock); in snd_es18xx_new_device()
1729 spin_lock_init(&chip->mixer_lock); in snd_es18xx_new_device()
1730 chip->port = port; in snd_es18xx_new_device()
1731 chip->irq = -1; in snd_es18xx_new_device()
1732 chip->dma1 = -1; in snd_es18xx_new_device()
1733 chip->dma2 = -1; in snd_es18xx_new_device()
1734 chip->audio2_vol = 0x00; in snd_es18xx_new_device()
1735 chip->active = 0; in snd_es18xx_new_device()
1737 if (!devm_request_region(card->dev, port, 16, "ES18xx")) { in snd_es18xx_new_device()
1738 dev_err(card->dev, "unable to grab ports 0x%lx-0x%lx\n", port, port + 16 - 1); in snd_es18xx_new_device()
1739 return -EBUSY; in snd_es18xx_new_device()
1742 if (devm_request_irq(card->dev, irq, snd_es18xx_interrupt, 0, "ES18xx", in snd_es18xx_new_device()
1744 dev_err(card->dev, "unable to grab IRQ %d\n", irq); in snd_es18xx_new_device()
1745 return -EBUSY; in snd_es18xx_new_device()
1747 chip->irq = irq; in snd_es18xx_new_device()
1748 card->sync_irq = chip->irq; in snd_es18xx_new_device()
1750 if (snd_devm_request_dma(card->dev, dma1, "ES18xx DMA 1")) { in snd_es18xx_new_device()
1751 dev_err(card->dev, "unable to grab DMA1 %d\n", dma1); in snd_es18xx_new_device()
1752 return -EBUSY; in snd_es18xx_new_device()
1754 chip->dma1 = dma1; in snd_es18xx_new_device()
1757 snd_devm_request_dma(card->dev, dma2, "ES18xx DMA 2")) { in snd_es18xx_new_device()
1758 dev_err(card->dev, "unable to grab DMA2 %d\n", dma2); in snd_es18xx_new_device()
1759 return -EBUSY; in snd_es18xx_new_device()
1761 chip->dma2 = dma2; in snd_es18xx_new_device()
1763 if (snd_es18xx_probe(card, chip, mpu_port, fm_port) < 0) in snd_es18xx_new_device()
1764 return -ENODEV; in snd_es18xx_new_device()
1770 struct snd_es18xx *chip = card->private_data; in snd_es18xx_mixer() local
1774 strscpy(card->mixername, chip->pcm->name); in snd_es18xx_mixer()
1778 kctl = snd_ctl_new1(&snd_es18xx_base_controls[idx], chip); in snd_es18xx_mixer()
1779 if (chip->caps & ES18XX_HWV) { in snd_es18xx_mixer()
1782 chip->master_volume = kctl; in snd_es18xx_mixer()
1783 kctl->private_free = snd_es18xx_hwv_free; in snd_es18xx_mixer()
1786 chip->master_switch = kctl; in snd_es18xx_mixer()
1787 kctl->private_free = snd_es18xx_hwv_free; in snd_es18xx_mixer()
1795 if (chip->caps & ES18XX_PCM2) { in snd_es18xx_mixer()
1797 err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_pcm2_controls[idx], chip)); in snd_es18xx_mixer()
1803 err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_pcm1_controls[idx], chip)); in snd_es18xx_mixer()
1809 if (chip->caps & ES18XX_RECMIX) { in snd_es18xx_mixer()
1811 err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_recmix_controls[idx], chip)); in snd_es18xx_mixer()
1816 switch (chip->version) { in snd_es18xx_mixer()
1818 err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_micpre1_control, chip)); in snd_es18xx_mixer()
1824 err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_micpre2_control, chip)); in snd_es18xx_mixer()
1829 if (chip->caps & ES18XX_SPATIALIZER) { in snd_es18xx_mixer()
1831 err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_spatializer_controls[idx], chip)); in snd_es18xx_mixer()
1836 if (chip->caps & ES18XX_HWV) { in snd_es18xx_mixer()
1839 kctl = snd_ctl_new1(&snd_es18xx_hw_volume_controls[idx], chip); in snd_es18xx_mixer()
1841 chip->hw_volume = kctl; in snd_es18xx_mixer()
1843 chip->hw_switch = kctl; in snd_es18xx_mixer()
1844 kctl->private_free = snd_es18xx_hwv_free; in snd_es18xx_mixer()
1853 if (chip->version != 0x1868) { in snd_es18xx_mixer()
1855 chip)); in snd_es18xx_mixer()
1859 if (chip->version == 0x1869) { in snd_es18xx_mixer()
1863 chip)); in snd_es18xx_mixer()
1867 } else if (chip->version == 0x1878) { in snd_es18xx_mixer()
1869 chip)); in snd_es18xx_mixer()
1872 } else if (chip->version == 0x1879) { in snd_es18xx_mixer()
1876 chip)); in snd_es18xx_mixer()
1881 if (chip->caps & ES18XX_GPO_2BIT) { in snd_es18xx_mixer()
1885 chip)); in snd_es18xx_mixer()
1896 …THOR("Christian Fischbach <fishbach@pool.informatik.rwth-aachen.de>, Abramo Bagnara <abramo@alsa-p…
1900 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
1901 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ variable
1908 static long mpu_port[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -1};
1919 module_param_array(id, charp, NULL, 0444);
1920 MODULE_PARM_DESC(id, "ID string for ES18xx soundcard.");
1930 MODULE_PARM_DESC(mpu_port, "MPU-401 port # for ES18xx driver.");
1946 { .id = "ESS1869" },
1947 { .id = "ESS1879" },
1948 { .id = "" } /* end */
1957 dev_err(&pdev->dev, "PnP configure failure (out of resources?)\n"); in snd_audiodrive_pnp_init_main()
1958 return -EBUSY; in snd_audiodrive_pnp_init_main()
1960 /* ok. hack using Vendor-Defined Card-Level registers */ in snd_audiodrive_pnp_init_main()
1961 /* skip csn and logdev initialization - already done in isapnp_configure */ in snd_audiodrive_pnp_init_main()
1966 isapnp_write_byte(0x28, pnp_irq(pdev, 0)); /* MPU-401 IRQ Number */ in snd_audiodrive_pnp_init_main()
1976 dev_dbg(&pdev->dev, in snd_audiodrive_pnp_init_main()
1979 dev_dbg(&pdev->dev, in snd_audiodrive_pnp_init_main()
1985 static int snd_audiodrive_pnp(int dev, struct snd_es18xx *chip, in snd_audiodrive_pnp() argument
1988 chip->dev = pdev; in snd_audiodrive_pnp()
1989 if (snd_audiodrive_pnp_init_main(dev, chip->dev) < 0) in snd_audiodrive_pnp()
1990 return -EBUSY; in snd_audiodrive_pnp()
1995 /* ESS 1868 (integrated on Compaq dual P-Pro motherboard and Genius 18PnP 3D) */
1996 { .id = "ESS1868", .devs = { { "ESS1868" }, { "ESS0000" } } },
1998 { .id = "ESS1868", .devs = { { "ESS8601" }, { "ESS8600" } } },
2000 { .id = "ESS1868", .devs = { { "ESS8611" }, { "ESS8610" } } },
2002 { .id = "ESS0003", .devs = { { "ESS1869" }, { "ESS0006" } } },
2004 { .id = "ESS1869", .devs = { { "ESS1869" }, { "ESS0006" } } },
2006 { .id = "ESS1878", .devs = { { "ESS1878" }, { "ESS0004" } } },
2008 { .id = "ESS1879", .devs = { { "ESS1879" }, { "ESS0009" } } },
2009 /* --- */
2010 { .id = "" } /* end */
2015 static int snd_audiodrive_pnpc(int dev, struct snd_es18xx *chip, in snd_audiodrive_pnpc() argument
2017 const struct pnp_card_device_id *id) in snd_audiodrive_pnpc() argument
2019 chip->dev = pnp_request_card_device(card, id->devs[0].id, NULL); in snd_audiodrive_pnpc()
2020 if (chip->dev == NULL) in snd_audiodrive_pnpc()
2021 return -EBUSY; in snd_audiodrive_pnpc()
2023 chip->devc = pnp_request_card_device(card, id->devs[1].id, NULL); in snd_audiodrive_pnpc()
2024 if (chip->devc == NULL) in snd_audiodrive_pnpc()
2025 return -EBUSY; in snd_audiodrive_pnpc()
2028 if (pnp_activate_dev(chip->devc) < 0) { in snd_audiodrive_pnpc()
2029 dev_err(chip->card->dev, in snd_audiodrive_pnpc()
2031 return -EAGAIN; in snd_audiodrive_pnpc()
2033 dev_dbg(chip->card->dev, "pnp: port=0x%llx\n", in snd_audiodrive_pnpc()
2034 (unsigned long long)pnp_port_start(chip->devc, 0)); in snd_audiodrive_pnpc()
2035 if (snd_audiodrive_pnp_init_main(dev, chip->dev) < 0) in snd_audiodrive_pnpc()
2036 return -EBUSY; in snd_audiodrive_pnpc()
2051 return snd_devm_card_new(pdev, index[dev], id[dev], THIS_MODULE, in snd_es18xx_card_new()
2057 struct snd_es18xx *chip = card->private_data; in snd_audiodrive_probe() local
2067 sprintf(card->driver, "ES%x", chip->version); in snd_audiodrive_probe()
2069 sprintf(card->shortname, "ESS AudioDrive ES%x", chip->version); in snd_audiodrive_probe()
2071 sprintf(card->longname, "%s at 0x%lx, irq %d, dma1 %d, dma2 %d", in snd_audiodrive_probe()
2072 card->shortname, in snd_audiodrive_probe()
2073 chip->port, in snd_audiodrive_probe()
2076 sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d", in snd_audiodrive_probe()
2077 card->shortname, in snd_audiodrive_probe()
2078 chip->port, in snd_audiodrive_probe()
2092 dev_warn(card->dev, in snd_audiodrive_probe()
2105 -1, &chip->rmidi); in snd_audiodrive_probe()
2136 static const int possible_irqs[] = {5, 9, 10, 7, 11, 12, -1}; in snd_es18xx_isa_probe()
2137 static const int possible_dmas[] = {1, 0, 3, 5, -1}; in snd_es18xx_isa_probe()
2143 return -EBUSY; in snd_es18xx_isa_probe()
2150 return -EBUSY; in snd_es18xx_isa_probe()
2157 return -EBUSY; in snd_es18xx_isa_probe()
2206 const struct pnp_device_id *id) in snd_audiodrive_pnp_detect() argument
2213 return -ENOENT; /* we have another procedure - card */ in snd_audiodrive_pnp_detect()
2219 return -ENODEV; in snd_audiodrive_pnp_detect()
2221 err = snd_es18xx_card_new(&pdev->dev, dev, &card); in snd_audiodrive_pnp_detect()
2224 err = snd_audiodrive_pnp(dev, card->private_data, pdev); in snd_audiodrive_pnp_detect()
2247 .name = "es18xx-pnpbios",
2268 return -ENODEV; in snd_audiodrive_pnpc_detect()
2270 res = snd_es18xx_card_new(&pcard->card->dev, dev, &card); in snd_audiodrive_pnpc_detect()
2274 res = snd_audiodrive_pnpc(dev, card->private_data, pcard, pid); in snd_audiodrive_pnpc_detect()