// SPDX-License-Identifier: GPL-2.0-or-later /* * Maintained by Jaroslav Kysela <[email protected]> * Originated by [email protected] * Fri Feb 19 15:55:28 MST 1999 * Routines for control of Trident 4DWave (DX and NX) chip * * BUGS: * * TODO: * --- * * SiS7018 S/PDIF support by Thomas Winischhofer <[email protected]> */ #include <linux/delay.h> #include <linux/init.h> #include <linux/interrupt.h> #include <linux/pci.h> #include <linux/slab.h> #include <linux/vmalloc.h> #include <linux/gameport.h> #include <linux/dma-mapping.h> #include <linux/export.h> #include <linux/io.h> #include <sound/core.h> #include <sound/info.h> #include <sound/control.h> #include <sound/tlv.h> #include "trident.h" #include <sound/asoundef.h> static int snd_trident_pcm_mixer_build(struct snd_trident *trident, struct snd_trident_voice * voice, struct snd_pcm_substream *substream); static int snd_trident_pcm_mixer_free(struct snd_trident *trident, struct snd_trident_voice * voice, struct snd_pcm_substream *substream); static irqreturn_t snd_trident_interrupt(int irq, void *dev_id); static int snd_trident_sis_reset(struct snd_trident *trident); static void snd_trident_clear_voices(struct snd_trident * trident, unsigned short v_min, unsigned short v_max); static void snd_trident_free(struct snd_card *card); /* * common I/O routines */ #if 0 static void snd_trident_print_voice_regs(struct snd_trident *trident, int voice) { unsigned int val, tmp; dev_dbg(trident->card->dev, "Trident voice %i:\n", voice); outb(voice, TRID_REG(trident, T4D_LFO_GC_CIR)); val = inl(TRID_REG(trident, CH_LBA)); dev_dbg(trident->card->dev, "LBA: 0x%x\n", val); val = inl(TRID_REG(trident, CH_GVSEL_PAN_VOL_CTRL_EC)); dev_dbg(trident->card->dev, "GVSel: %i\n", val >> 31); dev_dbg(trident->card->dev, "Pan: 0x%x\n", (val >> 24) & 0x7f); dev_dbg(trident->card->dev, "Vol: 0x%x\n", (val >> 16) & 0xff); dev_dbg(trident->card->dev, "CTRL: 0x%x\n", (val >> 12) & 0x0f); dev_dbg(trident->card->dev, "EC: 0x%x\n", val & 0x0fff); if (trident->device != TRIDENT_DEVICE_ID_NX) { val = inl(TRID_REG(trident, CH_DX_CSO_ALPHA_FMS)); dev_dbg(trident->card->dev, "CSO: 0x%x\n", val >> 16); dev_dbg(trident->card->dev, "Alpha: 0x%x\n", (val >> 4) & 0x0fff); dev_dbg(trident->card->dev, "FMS: 0x%x\n", val & 0x0f); val = inl(TRID_REG(trident, CH_DX_ESO_DELTA)); dev_dbg(trident->card->dev, "ESO: 0x%x\n", val >> 16); dev_dbg(trident->card->dev, "Delta: 0x%x\n", val & 0xffff); val = inl(TRID_REG(trident, CH_DX_FMC_RVOL_CVOL)); } else { // TRIDENT_DEVICE_ID_NX val = inl(TRID_REG(trident, CH_NX_DELTA_CSO)); tmp = (val >> 24) & 0xff; dev_dbg(trident->card->dev, "CSO: 0x%x\n", val & 0x00ffffff); val = inl(TRID_REG(trident, CH_NX_DELTA_ESO)); tmp |= (val >> 16) & 0xff00; dev_dbg(trident->card->dev, "Delta: 0x%x\n", tmp); dev_dbg(trident->card->dev, "ESO: 0x%x\n", val & 0x00ffffff); val = inl(TRID_REG(trident, CH_NX_ALPHA_FMS_FMC_RVOL_CVOL)); dev_dbg(trident->card->dev, "Alpha: 0x%x\n", val >> 20); dev_dbg(trident->card->dev, "FMS: 0x%x\n", (val >> 16) & 0x0f); } dev_dbg(trident->card->dev, "FMC: 0x%x\n", (val >> 14) & 3); dev_dbg(trident->card->dev, "RVol: 0x%x\n", (val >> 7) & 0x7f); dev_dbg(trident->card->dev, "CVol: 0x%x\n", val & 0x7f); } #endif /*--------------------------------------------------------------------------- unsigned short snd_trident_codec_read(struct snd_ac97 *ac97, unsigned short reg) Description: This routine will do all of the reading from the external CODEC (AC97). Parameters: ac97 - ac97 codec structure reg - CODEC register index, from AC97 Hal. returns: 16 bit value read from the AC97. ---------------------------------------------------------------------------*/ static unsigned short snd_trident_codec_read(struct snd_ac97 *ac97, unsigned short reg) { … } /*--------------------------------------------------------------------------- void snd_trident_codec_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short wdata) Description: This routine will do all of the writing to the external CODEC (AC97). Parameters: ac97 - ac97 codec structure reg - CODEC register index, from AC97 Hal. data - Lower 16 bits are the data to write to CODEC. returns: TRUE if everything went ok, else FALSE. ---------------------------------------------------------------------------*/ static void snd_trident_codec_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short wdata) { … } /*--------------------------------------------------------------------------- void snd_trident_enable_eso(struct snd_trident *trident) Description: This routine will enable end of loop interrupts. End of loop interrupts will occur when a running channel reaches ESO. Also enables middle of loop interrupts. Parameters: trident - pointer to target device class for 4DWave. ---------------------------------------------------------------------------*/ static void snd_trident_enable_eso(struct snd_trident * trident) { … } /*--------------------------------------------------------------------------- void snd_trident_disable_eso(struct snd_trident *trident) Description: This routine will disable end of loop interrupts. End of loop interrupts will occur when a running channel reaches ESO. Also disables middle of loop interrupts. Parameters: trident - pointer to target device class for 4DWave. returns: TRUE if everything went ok, else FALSE. ---------------------------------------------------------------------------*/ static void snd_trident_disable_eso(struct snd_trident * trident) { … } /*--------------------------------------------------------------------------- void snd_trident_start_voice(struct snd_trident * trident, unsigned int voice) Description: Start a voice, any channel 0 thru 63. This routine automatically handles the fact that there are more than 32 channels available. Parameters : voice - Voice number 0 thru n. trident - pointer to target device class for 4DWave. Return Value: None. ---------------------------------------------------------------------------*/ void snd_trident_start_voice(struct snd_trident * trident, unsigned int voice) { … } EXPORT_SYMBOL(…); /*--------------------------------------------------------------------------- void snd_trident_stop_voice(struct snd_trident * trident, unsigned int voice) Description: Stop a voice, any channel 0 thru 63. This routine automatically handles the fact that there are more than 32 channels available. Parameters : voice - Voice number 0 thru n. trident - pointer to target device class for 4DWave. Return Value: None. ---------------------------------------------------------------------------*/ void snd_trident_stop_voice(struct snd_trident * trident, unsigned int voice) { … } EXPORT_SYMBOL(…); /*--------------------------------------------------------------------------- int snd_trident_allocate_pcm_channel(struct snd_trident *trident) Description: Allocate hardware channel in Bank B (32-63). Parameters : trident - pointer to target device class for 4DWave. Return Value: hardware channel - 32-63 or -1 when no channel is available ---------------------------------------------------------------------------*/ static int snd_trident_allocate_pcm_channel(struct snd_trident * trident) { … } /*--------------------------------------------------------------------------- void snd_trident_free_pcm_channel(int channel) Description: Free hardware channel in Bank B (32-63) Parameters : trident - pointer to target device class for 4DWave. channel - hardware channel number 0-63 Return Value: none ---------------------------------------------------------------------------*/ static void snd_trident_free_pcm_channel(struct snd_trident *trident, int channel) { … } /*--------------------------------------------------------------------------- unsigned int snd_trident_allocate_synth_channel(void) Description: Allocate hardware channel in Bank A (0-31). Parameters : trident - pointer to target device class for 4DWave. Return Value: hardware channel - 0-31 or -1 when no channel is available ---------------------------------------------------------------------------*/ static int snd_trident_allocate_synth_channel(struct snd_trident * trident) { … } /*--------------------------------------------------------------------------- void snd_trident_free_synth_channel( int channel ) Description: Free hardware channel in Bank B (0-31). Parameters : trident - pointer to target device class for 4DWave. channel - hardware channel number 0-63 Return Value: none ---------------------------------------------------------------------------*/ static void snd_trident_free_synth_channel(struct snd_trident *trident, int channel) { … } /*--------------------------------------------------------------------------- snd_trident_write_voice_regs Description: This routine will complete and write the 5 hardware channel registers to hardware. Parameters: trident - pointer to target device class for 4DWave. voice - synthesizer voice structure Each register field. ---------------------------------------------------------------------------*/ void snd_trident_write_voice_regs(struct snd_trident * trident, struct snd_trident_voice * voice) { … } EXPORT_SYMBOL(…); /*--------------------------------------------------------------------------- snd_trident_write_cso_reg Description: This routine will write the new CSO offset register to hardware. Parameters: trident - pointer to target device class for 4DWave. voice - synthesizer voice structure CSO - new CSO value ---------------------------------------------------------------------------*/ static void snd_trident_write_cso_reg(struct snd_trident * trident, struct snd_trident_voice * voice, unsigned int CSO) { … } /*--------------------------------------------------------------------------- snd_trident_write_eso_reg Description: This routine will write the new ESO offset register to hardware. Parameters: trident - pointer to target device class for 4DWave. voice - synthesizer voice structure ESO - new ESO value ---------------------------------------------------------------------------*/ static void snd_trident_write_eso_reg(struct snd_trident * trident, struct snd_trident_voice * voice, unsigned int ESO) { … } /*--------------------------------------------------------------------------- snd_trident_write_vol_reg Description: This routine will write the new voice volume register to hardware. Parameters: trident - pointer to target device class for 4DWave. voice - synthesizer voice structure Vol - new voice volume ---------------------------------------------------------------------------*/ static void snd_trident_write_vol_reg(struct snd_trident * trident, struct snd_trident_voice * voice, unsigned int Vol) { … } /*--------------------------------------------------------------------------- snd_trident_write_pan_reg Description: This routine will write the new voice pan register to hardware. Parameters: trident - pointer to target device class for 4DWave. voice - synthesizer voice structure Pan - new pan value ---------------------------------------------------------------------------*/ static void snd_trident_write_pan_reg(struct snd_trident * trident, struct snd_trident_voice * voice, unsigned int Pan) { … } /*--------------------------------------------------------------------------- snd_trident_write_rvol_reg Description: This routine will write the new reverb volume register to hardware. Parameters: trident - pointer to target device class for 4DWave. voice - synthesizer voice structure RVol - new reverb volume ---------------------------------------------------------------------------*/ static void snd_trident_write_rvol_reg(struct snd_trident * trident, struct snd_trident_voice * voice, unsigned int RVol) { … } /*--------------------------------------------------------------------------- snd_trident_write_cvol_reg Description: This routine will write the new chorus volume register to hardware. Parameters: trident - pointer to target device class for 4DWave. voice - synthesizer voice structure CVol - new chorus volume ---------------------------------------------------------------------------*/ static void snd_trident_write_cvol_reg(struct snd_trident * trident, struct snd_trident_voice * voice, unsigned int CVol) { … } /*--------------------------------------------------------------------------- snd_trident_convert_rate Description: This routine converts rate in HZ to hardware delta value. Parameters: trident - pointer to target device class for 4DWave. rate - Real or Virtual channel number. Returns: Delta value. ---------------------------------------------------------------------------*/ static unsigned int snd_trident_convert_rate(unsigned int rate) { … } /*--------------------------------------------------------------------------- snd_trident_convert_adc_rate Description: This routine converts rate in HZ to hardware delta value. Parameters: trident - pointer to target device class for 4DWave. rate - Real or Virtual channel number. Returns: Delta value. ---------------------------------------------------------------------------*/ static unsigned int snd_trident_convert_adc_rate(unsigned int rate) { … } /*--------------------------------------------------------------------------- snd_trident_spurious_threshold Description: This routine converts rate in HZ to spurious threshold. Parameters: trident - pointer to target device class for 4DWave. rate - Real or Virtual channel number. Returns: Delta value. ---------------------------------------------------------------------------*/ static unsigned int snd_trident_spurious_threshold(unsigned int rate, unsigned int period_size) { … } /*--------------------------------------------------------------------------- snd_trident_control_mode Description: This routine returns a control mode for a PCM channel. Parameters: trident - pointer to target device class for 4DWave. substream - PCM substream Returns: Control value. ---------------------------------------------------------------------------*/ static unsigned int snd_trident_control_mode(struct snd_pcm_substream *substream) { … } /* * PCM part */ /*--------------------------------------------------------------------------- snd_trident_allocate_pcm_mem Description: Allocate PCM ring buffer for given substream Parameters: substream - PCM substream class hw_params - hardware parameters Returns: Error status ---------------------------------------------------------------------------*/ static int snd_trident_allocate_pcm_mem(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hw_params) { … } /*--------------------------------------------------------------------------- snd_trident_allocate_evoice Description: Allocate extra voice as interrupt generator Parameters: substream - PCM substream class hw_params - hardware parameters Returns: Error status ---------------------------------------------------------------------------*/ static int snd_trident_allocate_evoice(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hw_params) { … } /*--------------------------------------------------------------------------- snd_trident_hw_params Description: Set the hardware parameters for the playback device. Parameters: substream - PCM substream class hw_params - hardware parameters Returns: Error status ---------------------------------------------------------------------------*/ static int snd_trident_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hw_params) { … } /*--------------------------------------------------------------------------- snd_trident_playback_hw_free Description: Release the hardware resources for the playback device. Parameters: substream - PCM substream class Returns: Error status ---------------------------------------------------------------------------*/ static int snd_trident_hw_free(struct snd_pcm_substream *substream) { … } /*--------------------------------------------------------------------------- snd_trident_playback_prepare Description: Prepare playback device for playback. Parameters: substream - PCM substream class Returns: Error status ---------------------------------------------------------------------------*/ static int snd_trident_playback_prepare(struct snd_pcm_substream *substream) { … } /*--------------------------------------------------------------------------- snd_trident_capture_hw_params Description: Set the hardware parameters for the capture device. Parameters: substream - PCM substream class hw_params - hardware parameters Returns: Error status ---------------------------------------------------------------------------*/ static int snd_trident_capture_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hw_params) { … } /*--------------------------------------------------------------------------- snd_trident_capture_prepare Description: Prepare capture device for playback. Parameters: substream - PCM substream class Returns: Error status ---------------------------------------------------------------------------*/ static int snd_trident_capture_prepare(struct snd_pcm_substream *substream) { … } /*--------------------------------------------------------------------------- snd_trident_si7018_capture_hw_params Description: Set the hardware parameters for the capture device. Parameters: substream - PCM substream class hw_params - hardware parameters Returns: Error status ---------------------------------------------------------------------------*/ static int snd_trident_si7018_capture_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hw_params) { … } /*--------------------------------------------------------------------------- snd_trident_si7018_capture_hw_free Description: Release the hardware resources for the capture device. Parameters: substream - PCM substream class Returns: Error status ---------------------------------------------------------------------------*/ static int snd_trident_si7018_capture_hw_free(struct snd_pcm_substream *substream) { … } /*--------------------------------------------------------------------------- snd_trident_si7018_capture_prepare Description: Prepare capture device for playback. Parameters: substream - PCM substream class Returns: Error status ---------------------------------------------------------------------------*/ static int snd_trident_si7018_capture_prepare(struct snd_pcm_substream *substream) { … } /*--------------------------------------------------------------------------- snd_trident_foldback_prepare Description: Prepare foldback capture device for playback. Parameters: substream - PCM substream class Returns: Error status ---------------------------------------------------------------------------*/ static int snd_trident_foldback_prepare(struct snd_pcm_substream *substream) { … } /*--------------------------------------------------------------------------- snd_trident_spdif_hw_params Description: Set the hardware parameters for the spdif device. Parameters: substream - PCM substream class hw_params - hardware parameters Returns: Error status ---------------------------------------------------------------------------*/ static int snd_trident_spdif_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hw_params) { … } /*--------------------------------------------------------------------------- snd_trident_spdif_prepare Description: Prepare SPDIF device for playback. Parameters: substream - PCM substream class Returns: Error status ---------------------------------------------------------------------------*/ static int snd_trident_spdif_prepare(struct snd_pcm_substream *substream) { … } /*--------------------------------------------------------------------------- snd_trident_trigger Description: Start/stop devices Parameters: substream - PCM substream class cmd - trigger command (STOP, GO) Returns: Error status ---------------------------------------------------------------------------*/ static int snd_trident_trigger(struct snd_pcm_substream *substream, int cmd) { … } /*--------------------------------------------------------------------------- snd_trident_playback_pointer Description: This routine return the playback position Parameters: substream - PCM substream class Returns: position of buffer ---------------------------------------------------------------------------*/ static snd_pcm_uframes_t snd_trident_playback_pointer(struct snd_pcm_substream *substream) { … } /*--------------------------------------------------------------------------- snd_trident_capture_pointer Description: This routine return the capture position Parameters: pcm1 - PCM device class Returns: position of buffer ---------------------------------------------------------------------------*/ static snd_pcm_uframes_t snd_trident_capture_pointer(struct snd_pcm_substream *substream) { … } /*--------------------------------------------------------------------------- snd_trident_spdif_pointer Description: This routine return the SPDIF playback position Parameters: substream - PCM substream class Returns: position of buffer ---------------------------------------------------------------------------*/ static snd_pcm_uframes_t snd_trident_spdif_pointer(struct snd_pcm_substream *substream) { … } /* * Playback support device description */ static const struct snd_pcm_hardware snd_trident_playback = …; /* * Capture support device description */ static const struct snd_pcm_hardware snd_trident_capture = …; /* * Foldback capture support device description */ static const struct snd_pcm_hardware snd_trident_foldback = …; /* * SPDIF playback support device description */ static const struct snd_pcm_hardware snd_trident_spdif = …; static const struct snd_pcm_hardware snd_trident_spdif_7018 = …; static void snd_trident_pcm_free_substream(struct snd_pcm_runtime *runtime) { … } static int snd_trident_playback_open(struct snd_pcm_substream *substream) { … } /*--------------------------------------------------------------------------- snd_trident_playback_close Description: This routine will close the 4DWave playback device. For now we will simply free the dma transfer buffer. Parameters: substream - PCM substream class ---------------------------------------------------------------------------*/ static int snd_trident_playback_close(struct snd_pcm_substream *substream) { … } /*--------------------------------------------------------------------------- snd_trident_spdif_open Description: This routine will open the 4DWave SPDIF device. Parameters: substream - PCM substream class Returns: status - success or failure flag ---------------------------------------------------------------------------*/ static int snd_trident_spdif_open(struct snd_pcm_substream *substream) { … } /*--------------------------------------------------------------------------- snd_trident_spdif_close Description: This routine will close the 4DWave SPDIF device. Parameters: substream - PCM substream class ---------------------------------------------------------------------------*/ static int snd_trident_spdif_close(struct snd_pcm_substream *substream) { … } /*--------------------------------------------------------------------------- snd_trident_capture_open Description: This routine will open the 4DWave capture device. Parameters: substream - PCM substream class Returns: status - success or failure flag ---------------------------------------------------------------------------*/ static int snd_trident_capture_open(struct snd_pcm_substream *substream) { … } /*--------------------------------------------------------------------------- snd_trident_capture_close Description: This routine will close the 4DWave capture device. For now we will simply free the dma transfer buffer. Parameters: substream - PCM substream class ---------------------------------------------------------------------------*/ static int snd_trident_capture_close(struct snd_pcm_substream *substream) { … } /*--------------------------------------------------------------------------- snd_trident_foldback_open Description: This routine will open the 4DWave foldback capture device. Parameters: substream - PCM substream class Returns: status - success or failure flag ---------------------------------------------------------------------------*/ static int snd_trident_foldback_open(struct snd_pcm_substream *substream) { … } /*--------------------------------------------------------------------------- snd_trident_foldback_close Description: This routine will close the 4DWave foldback capture device. For now we will simply free the dma transfer buffer. Parameters: substream - PCM substream class ---------------------------------------------------------------------------*/ static int snd_trident_foldback_close(struct snd_pcm_substream *substream) { … } /*--------------------------------------------------------------------------- PCM operations ---------------------------------------------------------------------------*/ static const struct snd_pcm_ops snd_trident_playback_ops = …; static const struct snd_pcm_ops snd_trident_nx_playback_ops = …; static const struct snd_pcm_ops snd_trident_capture_ops = …; static const struct snd_pcm_ops snd_trident_si7018_capture_ops = …; static const struct snd_pcm_ops snd_trident_foldback_ops = …; static const struct snd_pcm_ops snd_trident_nx_foldback_ops = …; static const struct snd_pcm_ops snd_trident_spdif_ops = …; static const struct snd_pcm_ops snd_trident_spdif_7018_ops = …; /*--------------------------------------------------------------------------- snd_trident_pcm Description: This routine registers the 4DWave device for PCM support. Parameters: trident - pointer to target device class for 4DWave. Returns: None ---------------------------------------------------------------------------*/ int snd_trident_pcm(struct snd_trident *trident, int device) { … } /*--------------------------------------------------------------------------- snd_trident_foldback_pcm Description: This routine registers the 4DWave device for foldback PCM support. Parameters: trident - pointer to target device class for 4DWave. Returns: None ---------------------------------------------------------------------------*/ int snd_trident_foldback_pcm(struct snd_trident *trident, int device) { … } /*--------------------------------------------------------------------------- snd_trident_spdif Description: This routine registers the 4DWave-NX device for SPDIF support. Parameters: trident - pointer to target device class for 4DWave-NX. Returns: None ---------------------------------------------------------------------------*/ int snd_trident_spdif_pcm(struct snd_trident *trident, int device) { … } /* * Mixer part */ /*--------------------------------------------------------------------------- snd_trident_spdif_control Description: enable/disable S/PDIF out from ac97 mixer ---------------------------------------------------------------------------*/ #define snd_trident_spdif_control_info … static int snd_trident_spdif_control_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { … } static int snd_trident_spdif_control_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { … } static const struct snd_kcontrol_new snd_trident_spdif_control = …; /*--------------------------------------------------------------------------- snd_trident_spdif_default Description: put/get the S/PDIF default settings ---------------------------------------------------------------------------*/ static int snd_trident_spdif_default_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { … } static int snd_trident_spdif_default_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { … } static int snd_trident_spdif_default_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { … } static const struct snd_kcontrol_new snd_trident_spdif_default = …; /*--------------------------------------------------------------------------- snd_trident_spdif_mask Description: put/get the S/PDIF mask ---------------------------------------------------------------------------*/ static int snd_trident_spdif_mask_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { … } static int snd_trident_spdif_mask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { … } static const struct snd_kcontrol_new snd_trident_spdif_mask = …; /*--------------------------------------------------------------------------- snd_trident_spdif_stream Description: put/get the S/PDIF stream settings ---------------------------------------------------------------------------*/ static int snd_trident_spdif_stream_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { … } static int snd_trident_spdif_stream_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { … } static int snd_trident_spdif_stream_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { … } static const struct snd_kcontrol_new snd_trident_spdif_stream = …; /*--------------------------------------------------------------------------- snd_trident_ac97_control Description: enable/disable rear path for ac97 ---------------------------------------------------------------------------*/ #define snd_trident_ac97_control_info … static int snd_trident_ac97_control_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { … } static int snd_trident_ac97_control_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { … } static const struct snd_kcontrol_new snd_trident_ac97_rear_control = …; /*--------------------------------------------------------------------------- snd_trident_vol_control Description: wave & music volume control ---------------------------------------------------------------------------*/ static int snd_trident_vol_control_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { … } static int snd_trident_vol_control_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { … } static const DECLARE_TLV_DB_SCALE(db_scale_gvol, -6375, 25, 0); static int snd_trident_vol_control_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { … } static const struct snd_kcontrol_new snd_trident_vol_music_control = …; static const struct snd_kcontrol_new snd_trident_vol_wave_control = …; /*--------------------------------------------------------------------------- snd_trident_pcm_vol_control Description: PCM front volume control ---------------------------------------------------------------------------*/ static int snd_trident_pcm_vol_control_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { … } static int snd_trident_pcm_vol_control_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { … } static int snd_trident_pcm_vol_control_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { … } static const struct snd_kcontrol_new snd_trident_pcm_vol_control = …; /*--------------------------------------------------------------------------- snd_trident_pcm_pan_control Description: PCM front pan control ---------------------------------------------------------------------------*/ static int snd_trident_pcm_pan_control_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { … } static int snd_trident_pcm_pan_control_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { … } static int snd_trident_pcm_pan_control_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { … } static const struct snd_kcontrol_new snd_trident_pcm_pan_control = …; /*--------------------------------------------------------------------------- snd_trident_pcm_rvol_control Description: PCM reverb volume control ---------------------------------------------------------------------------*/ static int snd_trident_pcm_rvol_control_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { … } static int snd_trident_pcm_rvol_control_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { … } static int snd_trident_pcm_rvol_control_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { … } static const DECLARE_TLV_DB_SCALE(db_scale_crvol, -3175, 25, 1); static const struct snd_kcontrol_new snd_trident_pcm_rvol_control = …; /*--------------------------------------------------------------------------- snd_trident_pcm_cvol_control Description: PCM chorus volume control ---------------------------------------------------------------------------*/ static int snd_trident_pcm_cvol_control_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { … } static int snd_trident_pcm_cvol_control_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { … } static int snd_trident_pcm_cvol_control_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { … } static const struct snd_kcontrol_new snd_trident_pcm_cvol_control = …; static void snd_trident_notify_pcm_change1(struct snd_card *card, struct snd_kcontrol *kctl, int num, int activate) { … } static void snd_trident_notify_pcm_change(struct snd_trident *trident, struct snd_trident_pcm_mixer *tmix, int num, int activate) { … } static int snd_trident_pcm_mixer_build(struct snd_trident *trident, struct snd_trident_voice *voice, struct snd_pcm_substream *substream) { … } static int snd_trident_pcm_mixer_free(struct snd_trident *trident, struct snd_trident_voice *voice, struct snd_pcm_substream *substream) { … } /*--------------------------------------------------------------------------- snd_trident_mixer Description: This routine registers the 4DWave device for mixer support. Parameters: trident - pointer to target device class for 4DWave. Returns: None ---------------------------------------------------------------------------*/ static int snd_trident_mixer(struct snd_trident *trident, int pcm_spdif_device) { … } /* * gameport interface */ #if IS_REACHABLE(CONFIG_GAMEPORT) static unsigned char snd_trident_gameport_read(struct gameport *gameport) { … } static void snd_trident_gameport_trigger(struct gameport *gameport) { … } static int snd_trident_gameport_cooked_read(struct gameport *gameport, int *axes, int *buttons) { … } static int snd_trident_gameport_open(struct gameport *gameport, int mode) { … } int snd_trident_create_gameport(struct snd_trident *chip) { … } static inline void snd_trident_free_gameport(struct snd_trident *chip) { … } #else int snd_trident_create_gameport(struct snd_trident *chip) { return -ENOSYS; } static inline void snd_trident_free_gameport(struct snd_trident *chip) { } #endif /* CONFIG_GAMEPORT */ /* * delay for 1 tick */ static inline void do_delay(struct snd_trident *chip) { … } /* * SiS reset routine */ static int snd_trident_sis_reset(struct snd_trident *trident) { … } /* * /proc interface */ static void snd_trident_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) { … } static void snd_trident_proc_init(struct snd_trident *trident) { … } /*--------------------------------------------------------------------------- snd_trident_tlb_alloc Description: Allocate and set up the TLB page table on 4D NX. Each entry has 4 bytes (physical PCI address). Parameters: trident - pointer to target device class for 4DWave. Returns: 0 or negative error code ---------------------------------------------------------------------------*/ static int snd_trident_tlb_alloc(struct snd_trident *trident) { … } /* * initialize 4D DX chip */ static void snd_trident_stop_all_voices(struct snd_trident *trident) { … } static int snd_trident_4d_dx_init(struct snd_trident *trident) { … } /* * initialize 4D NX chip */ static int snd_trident_4d_nx_init(struct snd_trident *trident) { … } /* * initialize sis7018 chip */ static int snd_trident_sis_init(struct snd_trident *trident) { … } /*--------------------------------------------------------------------------- snd_trident_create Description: This routine will create the device specific class for the 4DWave card. It will also perform basic initialization. Parameters: card - which card to create pci - interface to PCI bus resource info dma1ptr - playback dma buffer dma2ptr - capture dma buffer irqptr - interrupt resource info Returns: 4DWave device class private data ---------------------------------------------------------------------------*/ int snd_trident_create(struct snd_card *card, struct pci_dev *pci, int pcm_streams, int pcm_spdif_device, int max_wavetable_size) { … } /*--------------------------------------------------------------------------- snd_trident_free Description: This routine will free the device specific class for the 4DWave card. Parameters: card - card to release Returns: None. ---------------------------------------------------------------------------*/ static void snd_trident_free(struct snd_card *card) { … } /*--------------------------------------------------------------------------- snd_trident_interrupt Description: ISR for Trident 4DWave device Parameters: trident - device specific private data for 4DWave card Problems: It seems that Trident chips generates interrupts more than one time in special cases. The spurious interrupts are detected via sample timer (T4D_STIMER) and computing corresponding delta value. The limits are detected with the method try & fail so it is possible that it won't work on all computers. [jaroslav] Returns: None. ---------------------------------------------------------------------------*/ static irqreturn_t snd_trident_interrupt(int irq, void *dev_id) { … } struct snd_trident_voice *snd_trident_alloc_voice(struct snd_trident * trident, int type, int client, int port) { … } EXPORT_SYMBOL(…); void snd_trident_free_voice(struct snd_trident * trident, struct snd_trident_voice *voice) { … } EXPORT_SYMBOL(…); static void snd_trident_clear_voices(struct snd_trident * trident, unsigned short v_min, unsigned short v_max) { … } #ifdef CONFIG_PM_SLEEP static int snd_trident_suspend(struct device *dev) { … } static int snd_trident_resume(struct device *dev) { … } SIMPLE_DEV_PM_OPS(snd_trident_pm, snd_trident_suspend, snd_trident_resume); #endif /* CONFIG_PM_SLEEP */