^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Driver for generic ESS AudioDrive ES18xx soundcards
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (c) by Christian Fischbach <fishbach@pool.informatik.rwth-aachen.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) by Abramo Bagnara <abramo@alsa-project.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) /* GENERAL NOTES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * BUGS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * - There are pops (we can't delay in trigger function, cause midlevel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * often need to trigger down and then up very quickly).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * Any ideas?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * - Support for 16 bit DMA seems to be broken. I've no hardware to tune it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * ES1868 NOTES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * - The chip has one half duplex pcm (with very limited full duplex support).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * - Duplex stereophonic sound is impossible.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * - Record and playback must share the same frequency rate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * - The driver use dma2 for playback and dma1 for capture.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * ES1869 NOTES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * - there are a first full duplex pcm and a second playback only pcm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * (incompatible with first pcm capture)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * - there is support for the capture volume and ESS Spatializer 3D effect.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * - contrarily to some pages in DS_1869.PDF the rates can be set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * independently.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * - Zoom Video is implemented by sharing the FM DAC, thus the user can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * have either FM playback or Video playback but not both simultaneously.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * The Video Playback Switch mixer control toggles this choice.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * BUGS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * - There is a major trouble I noted:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * using both channel for playback stereo 16 bit samples at 44100 Hz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * the second pcm (Audio1) DMA slows down irregularly and sound is garbled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * The same happens using Audio1 for captureing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * The Windows driver does not suffer of this (although it use Audio1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * only for captureing). I'm unable to discover why.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * ES1879 NOTES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * - When Zoom Video is enabled (reg 0x71 bit 6 toggled on) the PCM playback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * seems to be effected (speaker_test plays a lower frequency). Can't find
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * anything in the datasheet to account for this, so a Video Playback Switch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * control has been included to allow ZV to be enabled only when necessary.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * Then again on at least one test system the 0x71 bit 6 enable bit is not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) * needed for ZV, so maybe the datasheet is entirely wrong here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #include <linux/isa.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #include <linux/pnp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #include <linux/isapnp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #include <asm/dma.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #include <sound/core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #include <sound/control.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #include <sound/pcm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #include <sound/pcm_params.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #include <sound/mpu401.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #include <sound/opl3.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define SNDRV_LEGACY_FIND_FREE_IRQ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define SNDRV_LEGACY_FIND_FREE_DMA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #include <sound/initval.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define PFX "es18xx: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) struct snd_es18xx {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) unsigned long port; /* port of ESS chip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) unsigned long ctrl_port; /* Control port of ESS chip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) struct resource *res_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) struct resource *res_mpu_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) struct resource *res_ctrl_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) int irq; /* IRQ number of ESS chip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) int dma1; /* DMA1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) int dma2; /* DMA2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) unsigned short version; /* version of ESS chip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) int caps; /* Chip capabilities */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) unsigned short audio2_vol; /* volume level of audio2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) unsigned short active; /* active channel mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) unsigned int dma1_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) unsigned int dma2_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) struct snd_pcm *pcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) struct snd_pcm_substream *playback_a_substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) struct snd_pcm_substream *capture_a_substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) struct snd_pcm_substream *playback_b_substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) struct snd_rawmidi *rmidi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) struct snd_kcontrol *hw_volume;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) struct snd_kcontrol *hw_switch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) struct snd_kcontrol *master_volume;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) struct snd_kcontrol *master_switch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) spinlock_t reg_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) spinlock_t mixer_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) unsigned char pm_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) #ifdef CONFIG_PNP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) struct pnp_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) struct pnp_dev *devc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) #define AUDIO1_IRQ 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) #define AUDIO2_IRQ 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) #define HWV_IRQ 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) #define MPU_IRQ 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) #define ES18XX_PCM2 0x0001 /* Has two useable PCM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) #define ES18XX_SPATIALIZER 0x0002 /* Has 3D Spatializer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) #define ES18XX_RECMIX 0x0004 /* Has record mixer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) #define ES18XX_DUPLEX_MONO 0x0008 /* Has mono duplex only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) #define ES18XX_DUPLEX_SAME 0x0010 /* Playback and record must share the same rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) #define ES18XX_NEW_RATE 0x0020 /* More precise rate setting */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) #define ES18XX_AUXB 0x0040 /* AuxB mixer control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) #define ES18XX_HWV 0x0080 /* Has separate hardware volume mixer controls*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) #define ES18XX_MONO 0x0100 /* Mono_in mixer control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) #define ES18XX_I2S 0x0200 /* I2S mixer control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) #define ES18XX_MUTEREC 0x0400 /* Record source can be muted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) #define ES18XX_CONTROL 0x0800 /* Has control ports */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) #define ES18XX_GPO_2BIT 0x1000 /* GPO0,1 controlled by PM port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) /* Power Management */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) #define ES18XX_PM 0x07
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) #define ES18XX_PM_GPO0 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) #define ES18XX_PM_GPO1 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) #define ES18XX_PM_PDR 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) #define ES18XX_PM_ANA 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) #define ES18XX_PM_FM 0x020
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) #define ES18XX_PM_SUS 0x080
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) /* Lowlevel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) #define DAC1 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) #define ADC1 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) #define DAC2 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) #define MILLISECOND 10000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) static int snd_es18xx_dsp_command(struct snd_es18xx *chip, unsigned char val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) for(i = MILLISECOND; i; i--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) if ((inb(chip->port + 0x0C) & 0x80) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) outb(val, chip->port + 0x0C);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) snd_printk(KERN_ERR "dsp_command: timeout (0x%x)\n", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) static int snd_es18xx_dsp_get_byte(struct snd_es18xx *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) for(i = MILLISECOND/10; i; i--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) if (inb(chip->port + 0x0C) & 0x40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) return inb(chip->port + 0x0A);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) snd_printk(KERN_ERR "dsp_get_byte failed: 0x%lx = 0x%x!!!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) chip->port + 0x0A, inb(chip->port + 0x0A));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) #undef REG_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) static int snd_es18xx_write(struct snd_es18xx *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) unsigned char reg, unsigned char data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) spin_lock_irqsave(&chip->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) ret = snd_es18xx_dsp_command(chip, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) ret = snd_es18xx_dsp_command(chip, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) spin_unlock_irqrestore(&chip->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) #ifdef REG_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) snd_printk(KERN_DEBUG "Reg %02x set to %02x\n", reg, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) static int snd_es18xx_read(struct snd_es18xx *chip, unsigned char reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) int ret, data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) spin_lock_irqsave(&chip->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) ret = snd_es18xx_dsp_command(chip, 0xC0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) ret = snd_es18xx_dsp_command(chip, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) data = snd_es18xx_dsp_get_byte(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) ret = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) #ifdef REG_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) snd_printk(KERN_DEBUG "Reg %02x now is %02x (%d)\n", reg, data, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) spin_unlock_irqrestore(&chip->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) /* Return old value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) static int snd_es18xx_bits(struct snd_es18xx *chip, unsigned char reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) unsigned char mask, unsigned char val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) unsigned char old, new, oval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) spin_lock_irqsave(&chip->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) ret = snd_es18xx_dsp_command(chip, 0xC0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) ret = snd_es18xx_dsp_command(chip, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) ret = snd_es18xx_dsp_get_byte(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) old = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) oval = old & mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) if (val != oval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) ret = snd_es18xx_dsp_command(chip, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) new = (old & ~mask) | (val & mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) ret = snd_es18xx_dsp_command(chip, new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) #ifdef REG_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) snd_printk(KERN_DEBUG "Reg %02x was %02x, set to %02x (%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) reg, old, new, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) ret = oval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) spin_unlock_irqrestore(&chip->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) static inline void snd_es18xx_mixer_write(struct snd_es18xx *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) unsigned char reg, unsigned char data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) spin_lock_irqsave(&chip->mixer_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) outb(reg, chip->port + 0x04);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) outb(data, chip->port + 0x05);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) spin_unlock_irqrestore(&chip->mixer_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) #ifdef REG_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) snd_printk(KERN_DEBUG "Mixer reg %02x set to %02x\n", reg, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) static inline int snd_es18xx_mixer_read(struct snd_es18xx *chip, unsigned char reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) int data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) spin_lock_irqsave(&chip->mixer_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) outb(reg, chip->port + 0x04);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) data = inb(chip->port + 0x05);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) spin_unlock_irqrestore(&chip->mixer_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) #ifdef REG_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) snd_printk(KERN_DEBUG "Mixer reg %02x now is %02x\n", reg, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) return data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) /* Return old value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) static inline int snd_es18xx_mixer_bits(struct snd_es18xx *chip, unsigned char reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) unsigned char mask, unsigned char val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) unsigned char old, new, oval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) spin_lock_irqsave(&chip->mixer_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) outb(reg, chip->port + 0x04);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) old = inb(chip->port + 0x05);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) oval = old & mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) if (val != oval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) new = (old & ~mask) | (val & mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) outb(new, chip->port + 0x05);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) #ifdef REG_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) snd_printk(KERN_DEBUG "Mixer reg %02x was %02x, set to %02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) reg, old, new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) spin_unlock_irqrestore(&chip->mixer_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) return oval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) static inline int snd_es18xx_mixer_writable(struct snd_es18xx *chip, unsigned char reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) unsigned char mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) int old, expected, new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) spin_lock_irqsave(&chip->mixer_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) outb(reg, chip->port + 0x04);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) old = inb(chip->port + 0x05);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) expected = old ^ mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) outb(expected, chip->port + 0x05);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) new = inb(chip->port + 0x05);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) spin_unlock_irqrestore(&chip->mixer_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) #ifdef REG_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) snd_printk(KERN_DEBUG "Mixer reg %02x was %02x, set to %02x, now is %02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) reg, old, expected, new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) return expected == new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) static int snd_es18xx_reset(struct snd_es18xx *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) outb(0x03, chip->port + 0x06);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) inb(chip->port + 0x06);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) outb(0x00, chip->port + 0x06);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) for(i = 0; i < MILLISECOND && !(inb(chip->port + 0x0E) & 0x80); i++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) if (inb(chip->port + 0x0A) != 0xAA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) static int snd_es18xx_reset_fifo(struct snd_es18xx *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) outb(0x02, chip->port + 0x06);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) inb(chip->port + 0x06);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) outb(0x00, chip->port + 0x06);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) static const struct snd_ratnum new_clocks[2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) .num = 793800,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) .den_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) .den_max = 128,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) .den_step = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) .num = 768000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) .den_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) .den_max = 128,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) .den_step = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) static const struct snd_pcm_hw_constraint_ratnums new_hw_constraints_clocks = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) .nrats = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) .rats = new_clocks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) static const struct snd_ratnum old_clocks[2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) .num = 795444,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) .den_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) .den_max = 128,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) .den_step = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) .num = 397722,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) .den_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) .den_max = 128,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) .den_step = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) static const struct snd_pcm_hw_constraint_ratnums old_hw_constraints_clocks = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) .nrats = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) .rats = old_clocks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) static void snd_es18xx_rate_set(struct snd_es18xx *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) int mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) unsigned int bits, div0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) if (chip->caps & ES18XX_NEW_RATE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) if (runtime->rate_num == new_clocks[0].num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) bits = 128 - runtime->rate_den;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) bits = 256 - runtime->rate_den;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) if (runtime->rate_num == old_clocks[0].num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) bits = 256 - runtime->rate_den;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) bits = 128 - runtime->rate_den;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) /* set filter register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) div0 = 256 - 7160000*20/(8*82*runtime->rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) if ((chip->caps & ES18XX_PCM2) && mode == DAC2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) snd_es18xx_mixer_write(chip, 0x70, bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) * Comment from kernel oss driver:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) * FKS: fascinating: 0x72 doesn't seem to work.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) snd_es18xx_write(chip, 0xA2, div0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) snd_es18xx_mixer_write(chip, 0x72, div0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) snd_es18xx_write(chip, 0xA1, bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) snd_es18xx_write(chip, 0xA2, div0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) static int snd_es18xx_playback_hw_params(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) struct snd_pcm_hw_params *hw_params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) struct snd_es18xx *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) int shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) shift = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) if (params_channels(hw_params) == 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) shift++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) if (snd_pcm_format_width(params_format(hw_params)) == 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) shift++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) if (substream->number == 0 && (chip->caps & ES18XX_PCM2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) if ((chip->caps & ES18XX_DUPLEX_MONO) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) (chip->capture_a_substream) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) params_channels(hw_params) != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) _snd_pcm_hw_param_setempty(hw_params, SNDRV_PCM_HW_PARAM_CHANNELS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) chip->dma2_shift = shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) chip->dma1_shift = shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) static int snd_es18xx_playback1_prepare(struct snd_es18xx *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) unsigned int size = snd_pcm_lib_buffer_bytes(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) unsigned int count = snd_pcm_lib_period_bytes(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) snd_es18xx_rate_set(chip, substream, DAC2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) /* Transfer Count Reload */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) count = 0x10000 - count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) snd_es18xx_mixer_write(chip, 0x74, count & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) snd_es18xx_mixer_write(chip, 0x76, count >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) /* Set format */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) snd_es18xx_mixer_bits(chip, 0x7A, 0x07,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) ((runtime->channels == 1) ? 0x00 : 0x02) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) (snd_pcm_format_width(runtime->format) == 16 ? 0x01 : 0x00) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) (snd_pcm_format_unsigned(runtime->format) ? 0x00 : 0x04));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) /* Set DMA controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) snd_dma_program(chip->dma2, runtime->dma_addr, size, DMA_MODE_WRITE | DMA_AUTOINIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) static int snd_es18xx_playback1_trigger(struct snd_es18xx *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) case SNDRV_PCM_TRIGGER_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) case SNDRV_PCM_TRIGGER_RESUME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) if (chip->active & DAC2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) chip->active |= DAC2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) /* Start DMA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) if (chip->dma2 >= 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) snd_es18xx_mixer_write(chip, 0x78, 0xb3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) snd_es18xx_mixer_write(chip, 0x78, 0x93);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) #ifdef AVOID_POPS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) /* Avoid pops */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) mdelay(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) if (chip->caps & ES18XX_PCM2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) /* Restore Audio 2 volume */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) snd_es18xx_mixer_write(chip, 0x7C, chip->audio2_vol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) /* Enable PCM output */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) snd_es18xx_dsp_command(chip, 0xD1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) case SNDRV_PCM_TRIGGER_STOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) case SNDRV_PCM_TRIGGER_SUSPEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) if (!(chip->active & DAC2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) chip->active &= ~DAC2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) /* Stop DMA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) snd_es18xx_mixer_write(chip, 0x78, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) #ifdef AVOID_POPS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) mdelay(25);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) if (chip->caps & ES18XX_PCM2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) /* Set Audio 2 volume to 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) snd_es18xx_mixer_write(chip, 0x7C, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) /* Disable PCM output */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) snd_es18xx_dsp_command(chip, 0xD3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) static int snd_es18xx_capture_hw_params(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) struct snd_pcm_hw_params *hw_params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) struct snd_es18xx *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) int shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) shift = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) if ((chip->caps & ES18XX_DUPLEX_MONO) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) chip->playback_a_substream &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) params_channels(hw_params) != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) _snd_pcm_hw_param_setempty(hw_params, SNDRV_PCM_HW_PARAM_CHANNELS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) if (params_channels(hw_params) == 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) shift++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) if (snd_pcm_format_width(params_format(hw_params)) == 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) shift++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) chip->dma1_shift = shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) static int snd_es18xx_capture_prepare(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) struct snd_es18xx *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) unsigned int size = snd_pcm_lib_buffer_bytes(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) unsigned int count = snd_pcm_lib_period_bytes(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) snd_es18xx_reset_fifo(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) /* Set stereo/mono */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) snd_es18xx_bits(chip, 0xA8, 0x03, runtime->channels == 1 ? 0x02 : 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) snd_es18xx_rate_set(chip, substream, ADC1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) /* Transfer Count Reload */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) count = 0x10000 - count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) snd_es18xx_write(chip, 0xA4, count & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) snd_es18xx_write(chip, 0xA5, count >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) #ifdef AVOID_POPS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) mdelay(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) /* Set format */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) snd_es18xx_write(chip, 0xB7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) snd_pcm_format_unsigned(runtime->format) ? 0x51 : 0x71);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) snd_es18xx_write(chip, 0xB7, 0x90 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) ((runtime->channels == 1) ? 0x40 : 0x08) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) (snd_pcm_format_width(runtime->format) == 16 ? 0x04 : 0x00) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) (snd_pcm_format_unsigned(runtime->format) ? 0x00 : 0x20));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) /* Set DMA controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) snd_dma_program(chip->dma1, runtime->dma_addr, size, DMA_MODE_READ | DMA_AUTOINIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) static int snd_es18xx_capture_trigger(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) struct snd_es18xx *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) case SNDRV_PCM_TRIGGER_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) case SNDRV_PCM_TRIGGER_RESUME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) if (chip->active & ADC1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) chip->active |= ADC1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) /* Start DMA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) snd_es18xx_write(chip, 0xB8, 0x0f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) case SNDRV_PCM_TRIGGER_STOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) case SNDRV_PCM_TRIGGER_SUSPEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) if (!(chip->active & ADC1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) chip->active &= ~ADC1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) /* Stop DMA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) snd_es18xx_write(chip, 0xB8, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) static int snd_es18xx_playback2_prepare(struct snd_es18xx *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) unsigned int size = snd_pcm_lib_buffer_bytes(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) unsigned int count = snd_pcm_lib_period_bytes(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) snd_es18xx_reset_fifo(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) /* Set stereo/mono */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) snd_es18xx_bits(chip, 0xA8, 0x03, runtime->channels == 1 ? 0x02 : 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) snd_es18xx_rate_set(chip, substream, DAC1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) /* Transfer Count Reload */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) count = 0x10000 - count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) snd_es18xx_write(chip, 0xA4, count & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) snd_es18xx_write(chip, 0xA5, count >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) /* Set format */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) snd_es18xx_write(chip, 0xB6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) snd_pcm_format_unsigned(runtime->format) ? 0x80 : 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) snd_es18xx_write(chip, 0xB7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) snd_pcm_format_unsigned(runtime->format) ? 0x51 : 0x71);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) snd_es18xx_write(chip, 0xB7, 0x90 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) (runtime->channels == 1 ? 0x40 : 0x08) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) (snd_pcm_format_width(runtime->format) == 16 ? 0x04 : 0x00) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) (snd_pcm_format_unsigned(runtime->format) ? 0x00 : 0x20));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) /* Set DMA controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) snd_dma_program(chip->dma1, runtime->dma_addr, size, DMA_MODE_WRITE | DMA_AUTOINIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) static int snd_es18xx_playback2_trigger(struct snd_es18xx *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) case SNDRV_PCM_TRIGGER_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) case SNDRV_PCM_TRIGGER_RESUME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) if (chip->active & DAC1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) chip->active |= DAC1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) /* Start DMA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) snd_es18xx_write(chip, 0xB8, 0x05);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) #ifdef AVOID_POPS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) /* Avoid pops */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) mdelay(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) /* Enable Audio 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) snd_es18xx_dsp_command(chip, 0xD1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) case SNDRV_PCM_TRIGGER_STOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) case SNDRV_PCM_TRIGGER_SUSPEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) if (!(chip->active & DAC1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) chip->active &= ~DAC1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) /* Stop DMA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) snd_es18xx_write(chip, 0xB8, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) #ifdef AVOID_POPS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) /* Avoid pops */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) mdelay(25);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) /* Disable Audio 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) snd_es18xx_dsp_command(chip, 0xD3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) static int snd_es18xx_playback_prepare(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) struct snd_es18xx *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) if (substream->number == 0 && (chip->caps & ES18XX_PCM2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) return snd_es18xx_playback1_prepare(chip, substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) return snd_es18xx_playback2_prepare(chip, substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) static int snd_es18xx_playback_trigger(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) struct snd_es18xx *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) if (substream->number == 0 && (chip->caps & ES18XX_PCM2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) return snd_es18xx_playback1_trigger(chip, substream, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) return snd_es18xx_playback2_trigger(chip, substream, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) static irqreturn_t snd_es18xx_interrupt(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) struct snd_card *card = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) struct snd_es18xx *chip = card->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) unsigned char status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) if (chip->caps & ES18XX_CONTROL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) /* Read Interrupt status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) status = inb(chip->ctrl_port + 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) /* Read Interrupt status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) status = snd_es18xx_mixer_read(chip, 0x7f) >> 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) if (inb(chip->port + 0x0C) & 0x01)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) status |= AUDIO1_IRQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) if (snd_es18xx_mixer_read(chip, 0x7A) & 0x80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) status |= AUDIO2_IRQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) if ((chip->caps & ES18XX_HWV) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) snd_es18xx_mixer_read(chip, 0x64) & 0x10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) status |= HWV_IRQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) /* Audio 1 & Audio 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) if (status & AUDIO2_IRQ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) if (chip->active & DAC2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) snd_pcm_period_elapsed(chip->playback_a_substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) /* ack interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) snd_es18xx_mixer_bits(chip, 0x7A, 0x80, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) if (status & AUDIO1_IRQ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) /* ok.. capture is active */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) if (chip->active & ADC1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) snd_pcm_period_elapsed(chip->capture_a_substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) /* ok.. playback2 is active */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) else if (chip->active & DAC1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) snd_pcm_period_elapsed(chip->playback_b_substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) /* ack interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) inb(chip->port + 0x0E);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) /* MPU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) if ((status & MPU_IRQ) && chip->rmidi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) /* Hardware volume */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) if (status & HWV_IRQ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) int split = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) if (chip->caps & ES18XX_HWV) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) split = snd_es18xx_mixer_read(chip, 0x64) & 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) &chip->hw_switch->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) &chip->hw_volume->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) if (!split) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) &chip->master_switch->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) &chip->master_volume->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) /* ack interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) snd_es18xx_mixer_write(chip, 0x66, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) static snd_pcm_uframes_t snd_es18xx_playback_pointer(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) struct snd_es18xx *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) unsigned int size = snd_pcm_lib_buffer_bytes(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) int pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) if (substream->number == 0 && (chip->caps & ES18XX_PCM2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) if (!(chip->active & DAC2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) pos = snd_dma_pointer(chip->dma2, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) return pos >> chip->dma2_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) if (!(chip->active & DAC1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) pos = snd_dma_pointer(chip->dma1, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) return pos >> chip->dma1_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) static snd_pcm_uframes_t snd_es18xx_capture_pointer(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) struct snd_es18xx *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) unsigned int size = snd_pcm_lib_buffer_bytes(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) int pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) if (!(chip->active & ADC1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) pos = snd_dma_pointer(chip->dma1, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) return pos >> chip->dma1_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) static const struct snd_pcm_hardware snd_es18xx_playback =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) SNDRV_PCM_INFO_RESUME |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) SNDRV_PCM_INFO_MMAP_VALID),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) .formats = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S8 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) .rate_min = 4000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) .rate_max = 48000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) .channels_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) .channels_max = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) .buffer_bytes_max = 65536,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) .period_bytes_min = 64,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) .period_bytes_max = 65536,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) .periods_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) .periods_max = 1024,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) .fifo_size = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) static const struct snd_pcm_hardware snd_es18xx_capture =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) SNDRV_PCM_INFO_RESUME |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) SNDRV_PCM_INFO_MMAP_VALID),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) .formats = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S8 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) .rate_min = 4000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) .rate_max = 48000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) .channels_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) .channels_max = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) .buffer_bytes_max = 65536,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) .period_bytes_min = 64,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) .period_bytes_max = 65536,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) .periods_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) .periods_max = 1024,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) .fifo_size = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) static int snd_es18xx_playback_open(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) struct snd_es18xx *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) if (substream->number == 0 && (chip->caps & ES18XX_PCM2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) if ((chip->caps & ES18XX_DUPLEX_MONO) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) chip->capture_a_substream &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) chip->capture_a_substream->runtime->channels != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) chip->playback_a_substream = substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) } else if (substream->number <= 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) if (chip->capture_a_substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) chip->playback_b_substream = substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) snd_BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) substream->runtime->hw = snd_es18xx_playback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) snd_pcm_hw_constraint_ratnums(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) (chip->caps & ES18XX_NEW_RATE) ? &new_hw_constraints_clocks : &old_hw_constraints_clocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) static int snd_es18xx_capture_open(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) struct snd_es18xx *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) if (chip->playback_b_substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) if ((chip->caps & ES18XX_DUPLEX_MONO) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) chip->playback_a_substream &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) chip->playback_a_substream->runtime->channels != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) chip->capture_a_substream = substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) substream->runtime->hw = snd_es18xx_capture;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) snd_pcm_hw_constraint_ratnums(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) (chip->caps & ES18XX_NEW_RATE) ? &new_hw_constraints_clocks : &old_hw_constraints_clocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) static int snd_es18xx_playback_close(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) struct snd_es18xx *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) if (substream->number == 0 && (chip->caps & ES18XX_PCM2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) chip->playback_a_substream = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) chip->playback_b_substream = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) static int snd_es18xx_capture_close(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) struct snd_es18xx *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) chip->capture_a_substream = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) * MIXER part
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) /* Record source mux routines:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) * Depending on the chipset this mux switches between 4, 5, or 8 possible inputs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) * bit table for the 4/5 source mux:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) * reg 1C:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) * b2 b1 b0 muxSource
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) * x 0 x microphone
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) * 0 1 x CD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) * 1 1 0 line
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) * 1 1 1 mixer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) * if it's "mixer" and it's a 5 source mux chipset then reg 7A bit 3 determines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) * either the play mixer or the capture mixer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) * "map4Source" translates from source number to reg bit pattern
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) * "invMap4Source" translates from reg bit pattern to source number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) static int snd_es18xx_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) static const char * const texts5Source[5] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) "Mic", "CD", "Line", "Master", "Mix"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) static const char * const texts8Source[8] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) "Mic", "Mic Master", "CD", "AOUT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) "Mic1", "Mix", "Line", "Master"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) switch (chip->version) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) case 0x1868:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) case 0x1878:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) return snd_ctl_enum_info(uinfo, 1, 4, texts5Source);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) case 0x1887:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) case 0x1888:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) return snd_ctl_enum_info(uinfo, 1, 5, texts5Source);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) case 0x1869: /* DS somewhat contradictory for 1869: could be 5 or 8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) case 0x1879:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) return snd_ctl_enum_info(uinfo, 1, 8, texts8Source);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) static int snd_es18xx_get_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) static const unsigned char invMap4Source[8] = {0, 0, 1, 1, 0, 0, 2, 3};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) int muxSource = snd_es18xx_mixer_read(chip, 0x1c) & 0x07;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) if (!(chip->version == 0x1869 || chip->version == 0x1879)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) muxSource = invMap4Source[muxSource];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) if (muxSource==3 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) (chip->version == 0x1887 || chip->version == 0x1888) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) (snd_es18xx_mixer_read(chip, 0x7a) & 0x08)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) muxSource = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) ucontrol->value.enumerated.item[0] = muxSource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) static int snd_es18xx_put_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) static const unsigned char map4Source[4] = {0, 2, 6, 7};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) unsigned char val = ucontrol->value.enumerated.item[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) unsigned char retVal = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) switch (chip->version) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) /* 5 source chips */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) case 0x1887:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) case 0x1888:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) if (val > 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) if (val == 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) retVal = snd_es18xx_mixer_bits(chip, 0x7a, 0x08, 0x08) != 0x08;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) val = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) retVal = snd_es18xx_mixer_bits(chip, 0x7a, 0x08, 0x00) != 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) /* 4 source chips */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) case 0x1868:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) case 0x1878:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) if (val > 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) val = map4Source[val];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) /* 8 source chips */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) case 0x1869:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) case 0x1879:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) if (val > 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) return (snd_es18xx_mixer_bits(chip, 0x1c, 0x07, val) != val) || retVal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) #define snd_es18xx_info_spatializer_enable snd_ctl_boolean_mono_info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) static int snd_es18xx_get_spatializer_enable(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) unsigned char val = snd_es18xx_mixer_read(chip, 0x50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) ucontrol->value.integer.value[0] = !!(val & 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) static int snd_es18xx_put_spatializer_enable(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) unsigned char oval, nval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) int change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) nval = ucontrol->value.integer.value[0] ? 0x0c : 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) oval = snd_es18xx_mixer_read(chip, 0x50) & 0x0c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) change = nval != oval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) if (change) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) snd_es18xx_mixer_write(chip, 0x50, nval & ~0x04);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) snd_es18xx_mixer_write(chip, 0x50, nval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) static int snd_es18xx_info_hw_volume(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) uinfo->count = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) uinfo->value.integer.min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) uinfo->value.integer.max = 63;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) static int snd_es18xx_get_hw_volume(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) ucontrol->value.integer.value[0] = snd_es18xx_mixer_read(chip, 0x61) & 0x3f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) ucontrol->value.integer.value[1] = snd_es18xx_mixer_read(chip, 0x63) & 0x3f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) #define snd_es18xx_info_hw_switch snd_ctl_boolean_stereo_info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) static int snd_es18xx_get_hw_switch(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) ucontrol->value.integer.value[0] = !(snd_es18xx_mixer_read(chip, 0x61) & 0x40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) ucontrol->value.integer.value[1] = !(snd_es18xx_mixer_read(chip, 0x63) & 0x40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) static void snd_es18xx_hwv_free(struct snd_kcontrol *kcontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) chip->master_volume = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) chip->master_switch = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) chip->hw_volume = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) chip->hw_switch = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) static int snd_es18xx_reg_bits(struct snd_es18xx *chip, unsigned char reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) unsigned char mask, unsigned char val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) if (reg < 0xa0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) return snd_es18xx_mixer_bits(chip, reg, mask, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) return snd_es18xx_bits(chip, reg, mask, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) static int snd_es18xx_reg_read(struct snd_es18xx *chip, unsigned char reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) if (reg < 0xa0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) return snd_es18xx_mixer_read(chip, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) return snd_es18xx_read(chip, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) #define ES18XX_SINGLE(xname, xindex, reg, shift, mask, flags) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) .info = snd_es18xx_info_single, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) .get = snd_es18xx_get_single, .put = snd_es18xx_put_single, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) .private_value = reg | (shift << 8) | (mask << 16) | (flags << 24) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) #define ES18XX_FL_INVERT (1 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) #define ES18XX_FL_PMPORT (1 << 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) static int snd_es18xx_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) int mask = (kcontrol->private_value >> 16) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) uinfo->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) uinfo->value.integer.min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) uinfo->value.integer.max = mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) static int snd_es18xx_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) int reg = kcontrol->private_value & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) int shift = (kcontrol->private_value >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) int mask = (kcontrol->private_value >> 16) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) int invert = (kcontrol->private_value >> 24) & ES18XX_FL_INVERT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) int pm_port = (kcontrol->private_value >> 24) & ES18XX_FL_PMPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) if (pm_port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) val = inb(chip->port + ES18XX_PM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) val = snd_es18xx_reg_read(chip, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) ucontrol->value.integer.value[0] = (val >> shift) & mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) if (invert)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) static int snd_es18xx_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) int reg = kcontrol->private_value & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) int shift = (kcontrol->private_value >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) int mask = (kcontrol->private_value >> 16) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) int invert = (kcontrol->private_value >> 24) & ES18XX_FL_INVERT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) int pm_port = (kcontrol->private_value >> 24) & ES18XX_FL_PMPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) unsigned char val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) val = (ucontrol->value.integer.value[0] & mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) if (invert)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) val = mask - val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) mask <<= shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) val <<= shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) if (pm_port) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) unsigned char cur = inb(chip->port + ES18XX_PM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) if ((cur & mask) == val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) outb((cur & ~mask) | val, chip->port + ES18XX_PM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) return snd_es18xx_reg_bits(chip, reg, mask, val) != val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) #define ES18XX_DOUBLE(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) .info = snd_es18xx_info_double, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) .get = snd_es18xx_get_double, .put = snd_es18xx_put_double, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) static int snd_es18xx_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) int mask = (kcontrol->private_value >> 24) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) uinfo->count = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) uinfo->value.integer.min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) uinfo->value.integer.max = mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) static int snd_es18xx_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) int left_reg = kcontrol->private_value & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) int right_reg = (kcontrol->private_value >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) int shift_left = (kcontrol->private_value >> 16) & 0x07;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) int shift_right = (kcontrol->private_value >> 19) & 0x07;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) int mask = (kcontrol->private_value >> 24) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) int invert = (kcontrol->private_value >> 22) & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) unsigned char left, right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) left = snd_es18xx_reg_read(chip, left_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) if (left_reg != right_reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) right = snd_es18xx_reg_read(chip, right_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) right = left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) ucontrol->value.integer.value[0] = (left >> shift_left) & mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) ucontrol->value.integer.value[1] = (right >> shift_right) & mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) if (invert) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) ucontrol->value.integer.value[1] = mask - ucontrol->value.integer.value[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) static int snd_es18xx_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) int left_reg = kcontrol->private_value & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) int right_reg = (kcontrol->private_value >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) int shift_left = (kcontrol->private_value >> 16) & 0x07;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) int shift_right = (kcontrol->private_value >> 19) & 0x07;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) int mask = (kcontrol->private_value >> 24) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) int invert = (kcontrol->private_value >> 22) & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) int change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) unsigned char val1, val2, mask1, mask2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) val1 = ucontrol->value.integer.value[0] & mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) val2 = ucontrol->value.integer.value[1] & mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) if (invert) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) val1 = mask - val1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) val2 = mask - val2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) val1 <<= shift_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) val2 <<= shift_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) mask1 = mask << shift_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) mask2 = mask << shift_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) if (left_reg != right_reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) change = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) if (snd_es18xx_reg_bits(chip, left_reg, mask1, val1) != val1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) change = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) if (snd_es18xx_reg_bits(chip, right_reg, mask2, val2) != val2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) change = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) change = (snd_es18xx_reg_bits(chip, left_reg, mask1 | mask2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) val1 | val2) != (val1 | val2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) /* Mixer controls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) * These arrays contain setup data for mixer controls.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) * The controls that are universal to all chipsets are fully initialized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) * here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) static const struct snd_kcontrol_new snd_es18xx_base_controls[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) ES18XX_DOUBLE("Master Playback Volume", 0, 0x60, 0x62, 0, 0, 63, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) ES18XX_DOUBLE("Master Playback Switch", 0, 0x60, 0x62, 6, 6, 1, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) ES18XX_DOUBLE("Line Playback Volume", 0, 0x3e, 0x3e, 4, 0, 15, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) ES18XX_DOUBLE("CD Playback Volume", 0, 0x38, 0x38, 4, 0, 15, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) ES18XX_DOUBLE("FM Playback Volume", 0, 0x36, 0x36, 4, 0, 15, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) ES18XX_DOUBLE("Mic Playback Volume", 0, 0x1a, 0x1a, 4, 0, 15, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) ES18XX_DOUBLE("Aux Playback Volume", 0, 0x3a, 0x3a, 4, 0, 15, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) ES18XX_SINGLE("Record Monitor", 0, 0xa8, 3, 1, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) ES18XX_DOUBLE("Capture Volume", 0, 0xb4, 0xb4, 4, 0, 15, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) .name = "Capture Source",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) .info = snd_es18xx_info_mux,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) .get = snd_es18xx_get_mux,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) .put = snd_es18xx_put_mux,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) static const struct snd_kcontrol_new snd_es18xx_recmix_controls[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) ES18XX_DOUBLE("PCM Capture Volume", 0, 0x69, 0x69, 4, 0, 15, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) ES18XX_DOUBLE("Mic Capture Volume", 0, 0x68, 0x68, 4, 0, 15, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) ES18XX_DOUBLE("Line Capture Volume", 0, 0x6e, 0x6e, 4, 0, 15, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) ES18XX_DOUBLE("FM Capture Volume", 0, 0x6b, 0x6b, 4, 0, 15, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) ES18XX_DOUBLE("CD Capture Volume", 0, 0x6a, 0x6a, 4, 0, 15, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) ES18XX_DOUBLE("Aux Capture Volume", 0, 0x6c, 0x6c, 4, 0, 15, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) * The chipset specific mixer controls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) static const struct snd_kcontrol_new snd_es18xx_opt_speaker =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) ES18XX_SINGLE("Beep Playback Volume", 0, 0x3c, 0, 7, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) static const struct snd_kcontrol_new snd_es18xx_opt_1869[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) ES18XX_SINGLE("Capture Switch", 0, 0x1c, 4, 1, ES18XX_FL_INVERT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) ES18XX_SINGLE("Video Playback Switch", 0, 0x7f, 0, 1, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) ES18XX_DOUBLE("Mono Playback Volume", 0, 0x6d, 0x6d, 4, 0, 15, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) ES18XX_DOUBLE("Mono Capture Volume", 0, 0x6f, 0x6f, 4, 0, 15, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) static const struct snd_kcontrol_new snd_es18xx_opt_1878 =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) ES18XX_DOUBLE("Video Playback Volume", 0, 0x68, 0x68, 4, 0, 15, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) static const struct snd_kcontrol_new snd_es18xx_opt_1879[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) ES18XX_SINGLE("Video Playback Switch", 0, 0x71, 6, 1, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) ES18XX_DOUBLE("Video Playback Volume", 0, 0x6d, 0x6d, 4, 0, 15, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) ES18XX_DOUBLE("Video Capture Volume", 0, 0x6f, 0x6f, 4, 0, 15, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) static const struct snd_kcontrol_new snd_es18xx_pcm1_controls[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) ES18XX_DOUBLE("PCM Playback Volume", 0, 0x14, 0x14, 4, 0, 15, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) static const struct snd_kcontrol_new snd_es18xx_pcm2_controls[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) ES18XX_DOUBLE("PCM Playback Volume", 0, 0x7c, 0x7c, 4, 0, 15, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) ES18XX_DOUBLE("PCM Playback Volume", 1, 0x14, 0x14, 4, 0, 15, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) static const struct snd_kcontrol_new snd_es18xx_spatializer_controls[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) ES18XX_SINGLE("3D Control - Level", 0, 0x52, 0, 63, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) .name = "3D Control - Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) .info = snd_es18xx_info_spatializer_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) .get = snd_es18xx_get_spatializer_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) .put = snd_es18xx_put_spatializer_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) static const struct snd_kcontrol_new snd_es18xx_micpre1_control =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) ES18XX_SINGLE("Mic Boost (+26dB)", 0, 0xa9, 2, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) static const struct snd_kcontrol_new snd_es18xx_micpre2_control =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) ES18XX_SINGLE("Mic Boost (+26dB)", 0, 0x7d, 3, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) static const struct snd_kcontrol_new snd_es18xx_hw_volume_controls[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) .name = "Hardware Master Playback Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) .access = SNDRV_CTL_ELEM_ACCESS_READ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) .info = snd_es18xx_info_hw_volume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) .get = snd_es18xx_get_hw_volume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) .name = "Hardware Master Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) .access = SNDRV_CTL_ELEM_ACCESS_READ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) .info = snd_es18xx_info_hw_switch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) .get = snd_es18xx_get_hw_switch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) ES18XX_SINGLE("Hardware Master Volume Split", 0, 0x64, 7, 1, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) static const struct snd_kcontrol_new snd_es18xx_opt_gpo_2bit[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) ES18XX_SINGLE("GPO0 Switch", 0, ES18XX_PM, 0, 1, ES18XX_FL_PMPORT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) ES18XX_SINGLE("GPO1 Switch", 0, ES18XX_PM, 1, 1, ES18XX_FL_PMPORT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) static int snd_es18xx_config_read(struct snd_es18xx *chip, unsigned char reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) int data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) outb(reg, chip->ctrl_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) data = inb(chip->ctrl_port + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) return data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) static void snd_es18xx_config_write(struct snd_es18xx *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) unsigned char reg, unsigned char data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) /* No need for spinlocks, this function is used only in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) otherwise protected init code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) outb(reg, chip->ctrl_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) outb(data, chip->ctrl_port + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) #ifdef REG_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) snd_printk(KERN_DEBUG "Config reg %02x set to %02x\n", reg, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) static int snd_es18xx_initialize(struct snd_es18xx *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) unsigned long mpu_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) unsigned long fm_port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) int mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) /* enable extended mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) snd_es18xx_dsp_command(chip, 0xC6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) /* Reset mixer registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) snd_es18xx_mixer_write(chip, 0x00, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) /* Audio 1 DMA demand mode (4 bytes/request) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) snd_es18xx_write(chip, 0xB9, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) if (chip->caps & ES18XX_CONTROL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) /* Hardware volume IRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) snd_es18xx_config_write(chip, 0x27, chip->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) if (fm_port > 0 && fm_port != SNDRV_AUTO_PORT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) /* FM I/O */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) snd_es18xx_config_write(chip, 0x62, fm_port >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) snd_es18xx_config_write(chip, 0x63, fm_port & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) if (mpu_port > 0 && mpu_port != SNDRV_AUTO_PORT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) /* MPU-401 I/O */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) snd_es18xx_config_write(chip, 0x64, mpu_port >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) snd_es18xx_config_write(chip, 0x65, mpu_port & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) /* MPU-401 IRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) snd_es18xx_config_write(chip, 0x28, chip->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) /* Audio1 IRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) snd_es18xx_config_write(chip, 0x70, chip->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) /* Audio2 IRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) snd_es18xx_config_write(chip, 0x72, chip->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) /* Audio1 DMA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) snd_es18xx_config_write(chip, 0x74, chip->dma1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) /* Audio2 DMA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) snd_es18xx_config_write(chip, 0x75, chip->dma2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) /* Enable Audio 1 IRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) snd_es18xx_write(chip, 0xB1, 0x50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) /* Enable Audio 2 IRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) snd_es18xx_mixer_write(chip, 0x7A, 0x40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) /* Enable Audio 1 DMA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) snd_es18xx_write(chip, 0xB2, 0x50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) /* Enable MPU and hardware volume interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) snd_es18xx_mixer_write(chip, 0x64, 0x42);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) /* Enable ESS wavetable input */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) snd_es18xx_mixer_bits(chip, 0x48, 0x10, 0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) int irqmask, dma1mask, dma2mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) switch (chip->irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) case 9:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) irqmask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) case 5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) irqmask = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) case 7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) irqmask = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) case 10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) irqmask = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) snd_printk(KERN_ERR "invalid irq %d\n", chip->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) switch (chip->dma1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) dma1mask = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) dma1mask = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) dma1mask = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) snd_printk(KERN_ERR "invalid dma1 %d\n", chip->dma1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) switch (chip->dma2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) dma2mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) dma2mask = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) dma2mask = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) case 5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) dma2mask = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) snd_printk(KERN_ERR "invalid dma2 %d\n", chip->dma2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) /* Enable and set Audio 1 IRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) snd_es18xx_write(chip, 0xB1, 0x50 | (irqmask << 2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) /* Enable and set Audio 1 DMA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) snd_es18xx_write(chip, 0xB2, 0x50 | (dma1mask << 2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) /* Set Audio 2 DMA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) snd_es18xx_mixer_bits(chip, 0x7d, 0x07, 0x04 | dma2mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) /* Enable Audio 2 IRQ and DMA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) Set capture mixer input */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) snd_es18xx_mixer_write(chip, 0x7A, 0x68);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) /* Enable and set hardware volume interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) snd_es18xx_mixer_write(chip, 0x64, 0x06);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) if (mpu_port > 0 && mpu_port != SNDRV_AUTO_PORT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) /* MPU401 share irq with audio
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) Joystick enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) FM enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) snd_es18xx_mixer_write(chip, 0x40,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) 0x43 | (mpu_port & 0xf0) >> 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) snd_es18xx_mixer_write(chip, 0x7f, ((irqmask + 1) << 1) | 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) if (chip->caps & ES18XX_NEW_RATE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) /* Change behaviour of register A1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) 4x oversampling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) 2nd channel DAC asynchronous */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) snd_es18xx_mixer_write(chip, 0x71, 0x32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) if (!(chip->caps & ES18XX_PCM2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) /* Enable DMA FIFO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) snd_es18xx_write(chip, 0xB7, 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) if (chip->caps & ES18XX_SPATIALIZER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) /* Set spatializer parameters to recommended values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) snd_es18xx_mixer_write(chip, 0x54, 0x8f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) snd_es18xx_mixer_write(chip, 0x56, 0x95);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) snd_es18xx_mixer_write(chip, 0x58, 0x94);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) snd_es18xx_mixer_write(chip, 0x5a, 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) /* Flip the "enable I2S" bits for those chipsets that need it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) switch (chip->version) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) case 0x1879:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) //Leaving I2S enabled on the 1879 screws up the PCM playback (rate effected somehow)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) //so a Switch control has been added to toggle this 0x71 bit on/off:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) //snd_es18xx_mixer_bits(chip, 0x71, 0x40, 0x40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) /* Note: we fall through on purpose here. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) case 0x1878:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) snd_es18xx_config_write(chip, 0x29, snd_es18xx_config_read(chip, 0x29) | 0x40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) /* Mute input source */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) if (chip->caps & ES18XX_MUTEREC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) mask = 0x10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) if (chip->caps & ES18XX_RECMIX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) snd_es18xx_mixer_write(chip, 0x1c, 0x05 | mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) snd_es18xx_mixer_write(chip, 0x1c, 0x00 | mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) snd_es18xx_write(chip, 0xb4, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) #ifndef AVOID_POPS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) /* Enable PCM output */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) snd_es18xx_dsp_command(chip, 0xD1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) static int snd_es18xx_identify(struct snd_es18xx *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) int hi,lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) /* reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) if (snd_es18xx_reset(chip) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) snd_printk(KERN_ERR "reset at 0x%lx failed!!!\n", chip->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) snd_es18xx_dsp_command(chip, 0xe7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) hi = snd_es18xx_dsp_get_byte(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) if (hi < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) return hi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) lo = snd_es18xx_dsp_get_byte(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) if ((lo & 0xf0) != 0x80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) if (hi == 0x48) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) chip->version = 0x488;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) if (hi != 0x68) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) if ((lo & 0x0f) < 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) chip->version = 0x688;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) outb(0x40, chip->port + 0x04);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) hi = inb(chip->port + 0x05);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) lo = inb(chip->port + 0x05);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) if (hi != lo) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) chip->version = hi << 8 | lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) chip->ctrl_port = inb(chip->port + 0x05) << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) chip->ctrl_port += inb(chip->port + 0x05);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) if ((chip->res_ctrl_port = request_region(chip->ctrl_port, 8, "ES18xx - CTRL")) == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) snd_printk(KERN_ERR PFX "unable go grab port 0x%lx\n", chip->ctrl_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) /* If has Hardware volume */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) if (snd_es18xx_mixer_writable(chip, 0x64, 0x04)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) /* If has Audio2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) if (snd_es18xx_mixer_writable(chip, 0x70, 0x7f)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) /* If has volume count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) if (snd_es18xx_mixer_writable(chip, 0x64, 0x20)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) chip->version = 0x1887;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) chip->version = 0x1888;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) chip->version = 0x1788;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) chip->version = 0x1688;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) static int snd_es18xx_probe(struct snd_es18xx *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) unsigned long mpu_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) unsigned long fm_port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) if (snd_es18xx_identify(chip) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) snd_printk(KERN_ERR PFX "[0x%lx] ESS chip not found\n", chip->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) switch (chip->version) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) case 0x1868:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) chip->caps = ES18XX_DUPLEX_MONO | ES18XX_DUPLEX_SAME | ES18XX_CONTROL | ES18XX_GPO_2BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) case 0x1869:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) chip->caps = ES18XX_PCM2 | ES18XX_SPATIALIZER | ES18XX_RECMIX | ES18XX_NEW_RATE | ES18XX_AUXB | ES18XX_MONO | ES18XX_MUTEREC | ES18XX_CONTROL | ES18XX_HWV | ES18XX_GPO_2BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) case 0x1878:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) chip->caps = ES18XX_DUPLEX_MONO | ES18XX_DUPLEX_SAME | ES18XX_I2S | ES18XX_CONTROL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) case 0x1879:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) chip->caps = ES18XX_PCM2 | ES18XX_SPATIALIZER | ES18XX_RECMIX | ES18XX_NEW_RATE | ES18XX_AUXB | ES18XX_I2S | ES18XX_CONTROL | ES18XX_HWV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) case 0x1887:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) case 0x1888:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) chip->caps = ES18XX_PCM2 | ES18XX_RECMIX | ES18XX_AUXB | ES18XX_DUPLEX_SAME | ES18XX_GPO_2BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) snd_printk(KERN_ERR "[0x%lx] unsupported chip ES%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) chip->port, chip->version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) snd_printd("[0x%lx] ESS%x chip found\n", chip->port, chip->version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) if (chip->dma1 == chip->dma2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) chip->caps &= ~(ES18XX_PCM2 | ES18XX_DUPLEX_SAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) return snd_es18xx_initialize(chip, mpu_port, fm_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) static const struct snd_pcm_ops snd_es18xx_playback_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) .open = snd_es18xx_playback_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) .close = snd_es18xx_playback_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) .hw_params = snd_es18xx_playback_hw_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) .prepare = snd_es18xx_playback_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) .trigger = snd_es18xx_playback_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) .pointer = snd_es18xx_playback_pointer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) static const struct snd_pcm_ops snd_es18xx_capture_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) .open = snd_es18xx_capture_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) .close = snd_es18xx_capture_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) .hw_params = snd_es18xx_capture_hw_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) .prepare = snd_es18xx_capture_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) .trigger = snd_es18xx_capture_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) .pointer = snd_es18xx_capture_pointer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) static int snd_es18xx_pcm(struct snd_card *card, int device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) struct snd_es18xx *chip = card->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) struct snd_pcm *pcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) char str[16];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) sprintf(str, "ES%x", chip->version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) if (chip->caps & ES18XX_PCM2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) err = snd_pcm_new(card, str, device, 2, 1, &pcm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) err = snd_pcm_new(card, str, device, 1, 1, &pcm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_es18xx_playback_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_es18xx_capture_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) /* global setup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) pcm->private_data = chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) pcm->info_flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) if (chip->caps & ES18XX_DUPLEX_SAME)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) pcm->info_flags |= SNDRV_PCM_INFO_JOINT_DUPLEX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) if (! (chip->caps & ES18XX_PCM2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) pcm->info_flags |= SNDRV_PCM_INFO_HALF_DUPLEX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) sprintf(pcm->name, "ESS AudioDrive ES%x", chip->version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) chip->pcm = pcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV, card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) 64*1024,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) chip->dma1 > 3 || chip->dma2 > 3 ? 128*1024 : 64*1024);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) /* Power Management support functions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) static int snd_es18xx_suspend(struct snd_card *card, pm_message_t state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) struct snd_es18xx *chip = card->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) /* power down */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) chip->pm_reg = (unsigned char)snd_es18xx_read(chip, ES18XX_PM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) chip->pm_reg |= (ES18XX_PM_FM | ES18XX_PM_SUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) snd_es18xx_write(chip, ES18XX_PM, chip->pm_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) snd_es18xx_write(chip, ES18XX_PM, chip->pm_reg ^= ES18XX_PM_SUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) static int snd_es18xx_resume(struct snd_card *card)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) struct snd_es18xx *chip = card->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) /* restore PM register, we won't wake till (not 0x07) i/o activity though */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) snd_es18xx_write(chip, ES18XX_PM, chip->pm_reg ^= ES18XX_PM_FM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) snd_power_change_state(card, SNDRV_CTL_POWER_D0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) #endif /* CONFIG_PM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) static int snd_es18xx_free(struct snd_card *card)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) struct snd_es18xx *chip = card->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) release_and_free_resource(chip->res_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) release_and_free_resource(chip->res_ctrl_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) release_and_free_resource(chip->res_mpu_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) if (chip->irq >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) free_irq(chip->irq, (void *) card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) if (chip->dma1 >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) disable_dma(chip->dma1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) free_dma(chip->dma1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) if (chip->dma2 >= 0 && chip->dma1 != chip->dma2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) disable_dma(chip->dma2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) free_dma(chip->dma2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) static int snd_es18xx_dev_free(struct snd_device *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) return snd_es18xx_free(device->card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) static int snd_es18xx_new_device(struct snd_card *card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) unsigned long port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) unsigned long mpu_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) unsigned long fm_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) int irq, int dma1, int dma2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) struct snd_es18xx *chip = card->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) static const struct snd_device_ops ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) .dev_free = snd_es18xx_dev_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) spin_lock_init(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) spin_lock_init(&chip->mixer_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) chip->port = port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) chip->irq = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) chip->dma1 = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) chip->dma2 = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) chip->audio2_vol = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) chip->active = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) chip->res_port = request_region(port, 16, "ES18xx");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) if (chip->res_port == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) snd_es18xx_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) snd_printk(KERN_ERR PFX "unable to grap ports 0x%lx-0x%lx\n", port, port + 16 - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) if (request_irq(irq, snd_es18xx_interrupt, 0, "ES18xx",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) (void *) card)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) snd_es18xx_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) snd_printk(KERN_ERR PFX "unable to grap IRQ %d\n", irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) chip->irq = irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) card->sync_irq = chip->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) if (request_dma(dma1, "ES18xx DMA 1")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) snd_es18xx_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) snd_printk(KERN_ERR PFX "unable to grap DMA1 %d\n", dma1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) chip->dma1 = dma1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) if (dma2 != dma1 && request_dma(dma2, "ES18xx DMA 2")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) snd_es18xx_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) snd_printk(KERN_ERR PFX "unable to grap DMA2 %d\n", dma2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) chip->dma2 = dma2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) if (snd_es18xx_probe(chip, mpu_port, fm_port) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) snd_es18xx_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) snd_es18xx_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) static int snd_es18xx_mixer(struct snd_card *card)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) struct snd_es18xx *chip = card->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) unsigned int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) strcpy(card->mixername, chip->pcm->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) for (idx = 0; idx < ARRAY_SIZE(snd_es18xx_base_controls); idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) struct snd_kcontrol *kctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) kctl = snd_ctl_new1(&snd_es18xx_base_controls[idx], chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) if (chip->caps & ES18XX_HWV) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) switch (idx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) chip->master_volume = kctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) kctl->private_free = snd_es18xx_hwv_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) chip->master_switch = kctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) kctl->private_free = snd_es18xx_hwv_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) if ((err = snd_ctl_add(card, kctl)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) if (chip->caps & ES18XX_PCM2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) for (idx = 0; idx < ARRAY_SIZE(snd_es18xx_pcm2_controls); idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_pcm2_controls[idx], chip))) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) for (idx = 0; idx < ARRAY_SIZE(snd_es18xx_pcm1_controls); idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_pcm1_controls[idx], chip))) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) if (chip->caps & ES18XX_RECMIX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) for (idx = 0; idx < ARRAY_SIZE(snd_es18xx_recmix_controls); idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_recmix_controls[idx], chip))) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) switch (chip->version) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_micpre1_control, chip))) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) case 0x1869:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) case 0x1879:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_micpre2_control, chip))) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) if (chip->caps & ES18XX_SPATIALIZER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) for (idx = 0; idx < ARRAY_SIZE(snd_es18xx_spatializer_controls); idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_spatializer_controls[idx], chip))) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) if (chip->caps & ES18XX_HWV) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) for (idx = 0; idx < ARRAY_SIZE(snd_es18xx_hw_volume_controls); idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) struct snd_kcontrol *kctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) kctl = snd_ctl_new1(&snd_es18xx_hw_volume_controls[idx], chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) if (idx == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) chip->hw_volume = kctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) chip->hw_switch = kctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) kctl->private_free = snd_es18xx_hwv_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) if ((err = snd_ctl_add(card, kctl)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) /* finish initializing other chipset specific controls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) if (chip->version != 0x1868) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_opt_speaker,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) chip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) if (chip->version == 0x1869) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) for (idx = 0; idx < ARRAY_SIZE(snd_es18xx_opt_1869); idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) err = snd_ctl_add(card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) snd_ctl_new1(&snd_es18xx_opt_1869[idx],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) chip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) } else if (chip->version == 0x1878) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_opt_1878,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) chip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) } else if (chip->version == 0x1879) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) for (idx = 0; idx < ARRAY_SIZE(snd_es18xx_opt_1879); idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) err = snd_ctl_add(card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) snd_ctl_new1(&snd_es18xx_opt_1879[idx],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) chip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) if (chip->caps & ES18XX_GPO_2BIT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) for (idx = 0; idx < ARRAY_SIZE(snd_es18xx_opt_gpo_2bit); idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) err = snd_ctl_add(card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) snd_ctl_new1(&snd_es18xx_opt_gpo_2bit[idx],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) chip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) /* Card level */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) MODULE_AUTHOR("Christian Fischbach <fishbach@pool.informatik.rwth-aachen.de>, Abramo Bagnara <abramo@alsa-project.org>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) MODULE_DESCRIPTION("ESS ES18xx AudioDrive");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) MODULE_SUPPORTED_DEVICE("{{ESS,ES1868 PnP AudioDrive},"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) "{ESS,ES1869 PnP AudioDrive},"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) "{ESS,ES1878 PnP AudioDrive},"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) "{ESS,ES1879 PnP AudioDrive},"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) "{ESS,ES1887 PnP AudioDrive},"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) "{ESS,ES1888 PnP AudioDrive},"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) "{ESS,ES1887 AudioDrive},"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) "{ESS,ES1888 AudioDrive}}");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) #ifdef CONFIG_PNP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) static bool isapnp[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x220,0x240,0x260,0x280 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) #ifndef CONFIG_PNP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) static long mpu_port[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -1};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) static long mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) static long fm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 5,7,9,10 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) static int dma2[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) module_param_array(index, int, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) MODULE_PARM_DESC(index, "Index value for ES18xx soundcard.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) module_param_array(id, charp, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) MODULE_PARM_DESC(id, "ID string for ES18xx soundcard.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) module_param_array(enable, bool, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) MODULE_PARM_DESC(enable, "Enable ES18xx soundcard.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) #ifdef CONFIG_PNP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) module_param_array(isapnp, bool, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) MODULE_PARM_DESC(isapnp, "PnP detection for specified soundcard.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) module_param_hw_array(port, long, ioport, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) MODULE_PARM_DESC(port, "Port # for ES18xx driver.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) module_param_hw_array(mpu_port, long, ioport, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) MODULE_PARM_DESC(mpu_port, "MPU-401 port # for ES18xx driver.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) module_param_hw_array(fm_port, long, ioport, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) MODULE_PARM_DESC(fm_port, "FM port # for ES18xx driver.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) module_param_hw_array(irq, int, irq, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) MODULE_PARM_DESC(irq, "IRQ # for ES18xx driver.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) module_param_hw_array(dma1, int, dma, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) MODULE_PARM_DESC(dma1, "DMA 1 # for ES18xx driver.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) module_param_hw_array(dma2, int, dma, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) MODULE_PARM_DESC(dma2, "DMA 2 # for ES18xx driver.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) #ifdef CONFIG_PNP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) static int isa_registered;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) static int pnp_registered;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) static int pnpc_registered;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) static const struct pnp_device_id snd_audiodrive_pnpbiosids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) { .id = "ESS1869" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) { .id = "ESS1879" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) { .id = "" } /* end */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) MODULE_DEVICE_TABLE(pnp, snd_audiodrive_pnpbiosids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) /* PnP main device initialization */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) static int snd_audiodrive_pnp_init_main(int dev, struct pnp_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) if (pnp_activate_dev(pdev) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) snd_printk(KERN_ERR PFX "PnP configure failure (out of resources?)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) /* ok. hack using Vendor-Defined Card-Level registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) /* skip csn and logdev initialization - already done in isapnp_configure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) if (pnp_device_is_isapnp(pdev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) isapnp_cfg_begin(isapnp_card_number(pdev), isapnp_csn_number(pdev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) isapnp_write_byte(0x27, pnp_irq(pdev, 0)); /* Hardware Volume IRQ Number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) if (mpu_port[dev] != SNDRV_AUTO_PORT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) isapnp_write_byte(0x28, pnp_irq(pdev, 0)); /* MPU-401 IRQ Number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) isapnp_write_byte(0x72, pnp_irq(pdev, 0)); /* second IRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) isapnp_cfg_end();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) port[dev] = pnp_port_start(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) fm_port[dev] = pnp_port_start(pdev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) mpu_port[dev] = pnp_port_start(pdev, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) dma1[dev] = pnp_dma(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) dma2[dev] = pnp_dma(pdev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) irq[dev] = pnp_irq(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) snd_printdd("PnP ES18xx: port=0x%lx, fm port=0x%lx, mpu port=0x%lx\n", port[dev], fm_port[dev], mpu_port[dev]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) snd_printdd("PnP ES18xx: dma1=%i, dma2=%i, irq=%i\n", dma1[dev], dma2[dev], irq[dev]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) static int snd_audiodrive_pnp(int dev, struct snd_es18xx *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) struct pnp_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) chip->dev = pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) if (snd_audiodrive_pnp_init_main(dev, chip->dev) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) static const struct pnp_card_device_id snd_audiodrive_pnpids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) /* ESS 1868 (integrated on Compaq dual P-Pro motherboard and Genius 18PnP 3D) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) { .id = "ESS1868", .devs = { { "ESS1868" }, { "ESS0000" } } },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) /* ESS 1868 (integrated on Maxisound Cards) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) { .id = "ESS1868", .devs = { { "ESS8601" }, { "ESS8600" } } },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) /* ESS 1868 (integrated on Maxisound Cards) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) { .id = "ESS1868", .devs = { { "ESS8611" }, { "ESS8610" } } },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) /* ESS ES1869 Plug and Play AudioDrive */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) { .id = "ESS0003", .devs = { { "ESS1869" }, { "ESS0006" } } },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) /* ESS 1869 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) { .id = "ESS1869", .devs = { { "ESS1869" }, { "ESS0006" } } },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) /* ESS 1878 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) { .id = "ESS1878", .devs = { { "ESS1878" }, { "ESS0004" } } },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) /* ESS 1879 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) { .id = "ESS1879", .devs = { { "ESS1879" }, { "ESS0009" } } },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) /* --- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) { .id = "" } /* end */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) MODULE_DEVICE_TABLE(pnp_card, snd_audiodrive_pnpids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) static int snd_audiodrive_pnpc(int dev, struct snd_es18xx *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) struct pnp_card_link *card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) const struct pnp_card_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) chip->dev = pnp_request_card_device(card, id->devs[0].id, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) if (chip->dev == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) chip->devc = pnp_request_card_device(card, id->devs[1].id, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) if (chip->devc == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) /* Control port initialization */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) if (pnp_activate_dev(chip->devc) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) snd_printk(KERN_ERR PFX "PnP control configure failure (out of resources?)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) snd_printdd("pnp: port=0x%llx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) (unsigned long long)pnp_port_start(chip->devc, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) if (snd_audiodrive_pnp_init_main(dev, chip->dev) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) #endif /* CONFIG_PNP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) #ifdef CONFIG_PNP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) #define is_isapnp_selected(dev) isapnp[dev]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) #define is_isapnp_selected(dev) 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) static int snd_es18xx_card_new(struct device *pdev, int dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) struct snd_card **cardp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) return snd_card_new(pdev, index[dev], id[dev], THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) sizeof(struct snd_es18xx), cardp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) static int snd_audiodrive_probe(struct snd_card *card, int dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) struct snd_es18xx *chip = card->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) struct snd_opl3 *opl3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) err = snd_es18xx_new_device(card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) port[dev], mpu_port[dev], fm_port[dev],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) irq[dev], dma1[dev], dma2[dev]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) sprintf(card->driver, "ES%x", chip->version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) sprintf(card->shortname, "ESS AudioDrive ES%x", chip->version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) if (dma1[dev] != dma2[dev])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) sprintf(card->longname, "%s at 0x%lx, irq %d, dma1 %d, dma2 %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) card->shortname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) chip->port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) irq[dev], dma1[dev], dma2[dev]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) card->shortname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) chip->port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) irq[dev], dma1[dev]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) err = snd_es18xx_pcm(card, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) err = snd_es18xx_mixer(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) if (fm_port[dev] > 0 && fm_port[dev] != SNDRV_AUTO_PORT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) if (snd_opl3_create(card, fm_port[dev], fm_port[dev] + 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) OPL3_HW_OPL3, 0, &opl3) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) snd_printk(KERN_WARNING PFX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) "opl3 not detected at 0x%lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) fm_port[dev]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) err = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) err = snd_mpu401_uart_new(card, 0, MPU401_HW_ES18XX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) mpu_port[dev], MPU401_INFO_IRQ_HOOK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) -1, &chip->rmidi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) return snd_card_register(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) static int snd_es18xx_isa_match(struct device *pdev, unsigned int dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) return enable[dev] && !is_isapnp_selected(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) static int snd_es18xx_isa_probe1(int dev, struct device *devptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) struct snd_card *card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) err = snd_es18xx_card_new(devptr, dev, &card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) if ((err = snd_audiodrive_probe(card, dev)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) dev_set_drvdata(devptr, card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) static int snd_es18xx_isa_probe(struct device *pdev, unsigned int dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) static const int possible_irqs[] = {5, 9, 10, 7, 11, 12, -1};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) static const int possible_dmas[] = {1, 0, 3, 5, -1};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) if (irq[dev] == SNDRV_AUTO_IRQ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) if ((irq[dev] = snd_legacy_find_free_irq(possible_irqs)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) snd_printk(KERN_ERR PFX "unable to find a free IRQ\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) if (dma1[dev] == SNDRV_AUTO_DMA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) if ((dma1[dev] = snd_legacy_find_free_dma(possible_dmas)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) snd_printk(KERN_ERR PFX "unable to find a free DMA1\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) if (dma2[dev] == SNDRV_AUTO_DMA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) if ((dma2[dev] = snd_legacy_find_free_dma(possible_dmas)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) snd_printk(KERN_ERR PFX "unable to find a free DMA2\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) if (port[dev] != SNDRV_AUTO_PORT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) return snd_es18xx_isa_probe1(dev, pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) static const unsigned long possible_ports[] = {0x220, 0x240, 0x260, 0x280};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) for (i = 0; i < ARRAY_SIZE(possible_ports); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) port[dev] = possible_ports[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) err = snd_es18xx_isa_probe1(dev, pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) if (! err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) static int snd_es18xx_isa_remove(struct device *devptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) unsigned int dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) snd_card_free(dev_get_drvdata(devptr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) static int snd_es18xx_isa_suspend(struct device *dev, unsigned int n,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) pm_message_t state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) return snd_es18xx_suspend(dev_get_drvdata(dev), state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) static int snd_es18xx_isa_resume(struct device *dev, unsigned int n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) return snd_es18xx_resume(dev_get_drvdata(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) #define DEV_NAME "es18xx"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) static struct isa_driver snd_es18xx_isa_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) .match = snd_es18xx_isa_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) .probe = snd_es18xx_isa_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) .remove = snd_es18xx_isa_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) .suspend = snd_es18xx_isa_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) .resume = snd_es18xx_isa_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) .name = DEV_NAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) #ifdef CONFIG_PNP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) static int snd_audiodrive_pnp_detect(struct pnp_dev *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) const struct pnp_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) static int dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) struct snd_card *card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) if (pnp_device_is_isapnp(pdev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) return -ENOENT; /* we have another procedure - card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) for (; dev < SNDRV_CARDS; dev++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) if (enable[dev] && isapnp[dev])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) if (dev >= SNDRV_CARDS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) err = snd_es18xx_card_new(&pdev->dev, dev, &card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) if ((err = snd_audiodrive_pnp(dev, card->private_data, pdev)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) if ((err = snd_audiodrive_probe(card, dev)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) pnp_set_drvdata(pdev, card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) dev++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) static void snd_audiodrive_pnp_remove(struct pnp_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) snd_card_free(pnp_get_drvdata(pdev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) static int snd_audiodrive_pnp_suspend(struct pnp_dev *pdev, pm_message_t state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) return snd_es18xx_suspend(pnp_get_drvdata(pdev), state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) static int snd_audiodrive_pnp_resume(struct pnp_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) return snd_es18xx_resume(pnp_get_drvdata(pdev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) static struct pnp_driver es18xx_pnp_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) .name = "es18xx-pnpbios",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) .id_table = snd_audiodrive_pnpbiosids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) .probe = snd_audiodrive_pnp_detect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) .remove = snd_audiodrive_pnp_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) .suspend = snd_audiodrive_pnp_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) .resume = snd_audiodrive_pnp_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) static int snd_audiodrive_pnpc_detect(struct pnp_card_link *pcard,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) const struct pnp_card_device_id *pid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) static int dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) struct snd_card *card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) for ( ; dev < SNDRV_CARDS; dev++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) if (enable[dev] && isapnp[dev])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) if (dev >= SNDRV_CARDS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) res = snd_es18xx_card_new(&pcard->card->dev, dev, &card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) if (res < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) if ((res = snd_audiodrive_pnpc(dev, card->private_data, pcard, pid)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) if ((res = snd_audiodrive_probe(card, dev)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) pnp_set_card_drvdata(pcard, card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) dev++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) static void snd_audiodrive_pnpc_remove(struct pnp_card_link *pcard)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) snd_card_free(pnp_get_card_drvdata(pcard));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) pnp_set_card_drvdata(pcard, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) static int snd_audiodrive_pnpc_suspend(struct pnp_card_link *pcard, pm_message_t state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) return snd_es18xx_suspend(pnp_get_card_drvdata(pcard), state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) static int snd_audiodrive_pnpc_resume(struct pnp_card_link *pcard)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) return snd_es18xx_resume(pnp_get_card_drvdata(pcard));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) static struct pnp_card_driver es18xx_pnpc_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) .flags = PNP_DRIVER_RES_DISABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) .name = "es18xx",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) .id_table = snd_audiodrive_pnpids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) .probe = snd_audiodrive_pnpc_detect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) .remove = snd_audiodrive_pnpc_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) .suspend = snd_audiodrive_pnpc_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) .resume = snd_audiodrive_pnpc_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) #endif /* CONFIG_PNP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) static int __init alsa_card_es18xx_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) err = isa_register_driver(&snd_es18xx_isa_driver, SNDRV_CARDS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) #ifdef CONFIG_PNP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) isa_registered = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) err = pnp_register_driver(&es18xx_pnp_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) pnp_registered = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) err = pnp_register_card_driver(&es18xx_pnpc_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) pnpc_registered = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) if (isa_registered || pnp_registered)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) static void __exit alsa_card_es18xx_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) #ifdef CONFIG_PNP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) if (pnpc_registered)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) pnp_unregister_card_driver(&es18xx_pnpc_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) if (pnp_registered)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) pnp_unregister_driver(&es18xx_pnp_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) if (isa_registered)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) isa_unregister_driver(&snd_es18xx_isa_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) module_init(alsa_card_es18xx_init)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) module_exit(alsa_card_es18xx_exit)