// SPDX-License-Identifier: GPL-2.0-or-later /* * Maintained by Jaroslav Kysela <perex@perex.cz> * Originated by audio@tridentmicro.com * 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 <thomas@winischhofer.net>
*/
/*--------------------------------------------------------------------------- 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.
---------------------------------------------------------------------------*/ staticunsignedshort snd_trident_codec_read(struct snd_ac97 *ac97, unsignedshort reg)
{ unsignedint data = 0, treg; unsignedshort count = 0xffff; unsignedlong flags; struct snd_trident *trident = ac97->private_data;
spin_lock_irqsave(&trident->reg_lock, flags); if (trident->device == TRIDENT_DEVICE_ID_DX) {
data = (DX_AC97_BUSY_READ | (reg & 0x000000ff));
outl(data, TRID_REG(trident, DX_ACR1_AC97_R)); do {
data = inl(TRID_REG(trident, DX_ACR1_AC97_R)); if ((data & DX_AC97_BUSY_READ) == 0) break;
} while (--count);
} elseif (trident->device == TRIDENT_DEVICE_ID_NX) {
data = (NX_AC97_BUSY_READ | (reg & 0x000000ff));
treg = ac97->num == 0 ? NX_ACR2_AC97_R_PRIMARY : NX_ACR3_AC97_R_SECONDARY;
outl(data, TRID_REG(trident, treg)); do {
data = inl(TRID_REG(trident, treg)); if ((data & 0x00000C00) == 0) break;
} while (--count);
} elseif (trident->device == TRIDENT_DEVICE_ID_SI7018) {
data = SI_AC97_BUSY_READ | SI_AC97_AUDIO_BUSY | (reg & 0x000000ff); if (ac97->num == 1)
data |= SI_AC97_SECONDARY;
outl(data, TRID_REG(trident, SI_AC97_READ)); do {
data = inl(TRID_REG(trident, SI_AC97_READ)); if ((data & (SI_AC97_BUSY_READ)) == 0) break;
} while (--count);
}
if (count == 0 && !trident->ac97_detect) {
dev_err(trident->card->dev, "ac97 codec read TIMEOUT [0x%x/0x%x]!!!\n",
reg, data);
data = 0;
}
/*--------------------------------------------------------------------------- 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.
---------------------------------------------------------------------------*/ staticvoid snd_trident_codec_write(struct snd_ac97 *ac97, unsignedshort reg, unsignedshort wdata)
{ unsignedint address, data; unsignedshort count = 0xffff; unsignedlong flags; struct snd_trident *trident = ac97->private_data;
data = ((unsignedlong) wdata) << 16;
spin_lock_irqsave(&trident->reg_lock, flags); if (trident->device == TRIDENT_DEVICE_ID_DX) {
address = DX_ACR0_AC97_W;
/* read AC-97 write register status */ do { if ((inw(TRID_REG(trident, address)) & DX_AC97_BUSY_WRITE) == 0) break;
} while (--count);
/*--------------------------------------------------------------------------- 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.
---------------------------------------------------------------------------*/
val = inl(TRID_REG(trident, T4D_LFO_GC_CIR));
val |= ENDLP_IE;
val |= MIDLP_IE; if (trident->device == TRIDENT_DEVICE_ID_SI7018)
val |= BANK_B_EN;
outl(val, TRID_REG(trident, T4D_LFO_GC_CIR));
}
/*--------------------------------------------------------------------------- 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.
---------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------- 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
---------------------------------------------------------------------------*/
staticint snd_trident_allocate_pcm_channel(struct snd_trident * trident)
{ int idx;
/*--------------------------------------------------------------------------- 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
---------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------- 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
---------------------------------------------------------------------------*/
staticint snd_trident_allocate_synth_channel(struct snd_trident * trident)
{ int idx;
/*--------------------------------------------------------------------------- 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
---------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------- 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.
---------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------- 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
---------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------- 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
---------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------- 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
---------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------- 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
---------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------- 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
---------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------- 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
---------------------------------------------------------------------------*/
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.
---------------------------------------------------------------------------*/ staticunsignedint snd_trident_convert_rate(unsignedint rate)
{ unsignedint delta;
// We special case 44100 and 8000 since rounding with the equation // does not give us an accurate enough value. For 11025 and 22050 // the equation gives us the best answer. All other frequencies will // also use the equation. JDW if (rate == 44100)
delta = 0xeb3; elseif (rate == 8000)
delta = 0x2ab; elseif (rate == 48000)
delta = 0x1000; else
delta = DIV_ROUND_CLOSEST(rate << 12, 48000) & 0x0000ffff; return delta;
}
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.
---------------------------------------------------------------------------*/ staticunsignedint snd_trident_convert_adc_rate(unsignedint rate)
{ unsignedint delta;
// We special case 44100 and 8000 since rounding with the equation // does not give us an accurate enough value. For 11025 and 22050 // the equation gives us the best answer. All other frequencies will // also use the equation. JDW if (rate == 44100)
delta = 0x116a; elseif (rate == 8000)
delta = 0x6000; elseif (rate == 48000)
delta = 0x1000; else
delta = ((48000 << 12) / rate) & 0x0000ffff; return delta;
}
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.
---------------------------------------------------------------------------*/ staticunsignedint snd_trident_spurious_threshold(unsignedint rate, unsignedint period_size)
{ unsignedint res = (rate * period_size) / 48000; if (res < 64)
res = res / 2; else
res -= 32; return res;
}
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.
---------------------------------------------------------------------------*/ staticunsignedint snd_trident_control_mode(struct snd_pcm_substream *substream)
{ unsignedint CTRL; struct snd_pcm_runtime *runtime = substream->runtime;
/* set ctrl mode CTRL default: 8-bit (unsigned) mono, loop mode enabled
*/
CTRL = 0x00000001; if (snd_pcm_format_width(runtime->format) == 16)
CTRL |= 0x00000008; // 16-bit data if (snd_pcm_format_signed(runtime->format))
CTRL |= 0x00000002; // signed data if (runtime->channels > 1)
CTRL |= 0x00000004; // stereo data return CTRL;
}
/* * 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
---------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------- 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
---------------------------------------------------------------------------*/
staticint snd_trident_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hw_params)
{ int err;
/*--------------------------------------------------------------------------- snd_trident_playback_hw_free Description: Release the hardware resources for the playback device. Parameters: substream - PCM substream class Returns: Error status
---------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------- 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
---------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------- 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
---------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------- snd_trident_si7018_capture_hw_free Description: Release the hardware resources for the capture device. Parameters: substream - PCM substream class Returns: Error status
---------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------- 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
---------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------- snd_trident_playback_pointer Description: This routine return the playback position Parameters: substream - PCM substream class
Returns: position of buffer
---------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------- snd_trident_capture_pointer Description: This routine return the capture position Parameters: pcm1 - PCM device class
Returns: position of buffer
---------------------------------------------------------------------------*/
result = inw(TRID_REG(trident, T4D_SBBL_SBCL)); if (runtime->channels > 1)
result >>= 1; if (result > 0)
result = runtime->buffer_size - result;
return result;
}
/*--------------------------------------------------------------------------- snd_trident_spdif_pointer Description: This routine return the SPDIF playback position Parameters: substream - PCM substream class
Returns: position of buffer
---------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------- 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
/*--------------------------------------------------------------------------- snd_trident_spdif_open Description: This routine will open the 4DWave SPDIF device.
Parameters: substream - PCM substream class
Returns: status - success or failure flag
---------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------- snd_trident_spdif_close Description: This routine will close the 4DWave SPDIF device. Parameters: substream - PCM substream class
/*--------------------------------------------------------------------------- snd_trident_capture_open Description: This routine will open the 4DWave capture device.
/*--------------------------------------------------------------------------- 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
/*--------------------------------------------------------------------------- snd_trident_foldback_open Description: This routine will open the 4DWave foldback capture device.
/*--------------------------------------------------------------------------- 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
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.