sound/pci/au88x0/au88x0_pcm.c

Source file repositories/reference/linux-study-clean/sound/pci/au88x0/au88x0_pcm.c

File Facts

System
Linux kernel
Corpus path
sound/pci/au88x0/au88x0_pcm.c
Extension
.c
Size
19556 bytes
Lines
683
Domain
Driver Families
Bucket
sound/pci
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_A3D) {
			runtime->hw = snd_vortex_playback_hw_a3d;
		}
#endif
		if (VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_SPDIF) {
			runtime->hw = snd_vortex_playback_hw_spdif;
			switch (vortex->spdif_sr) {
			case 32000:
				runtime->hw.rates = SNDRV_PCM_RATE_32000;
				break;
			case 44100:
				runtime->hw.rates = SNDRV_PCM_RATE_44100;
				break;
			case 48000:
				runtime->hw.rates = SNDRV_PCM_RATE_48000;
				break;
			}
		}
		if (VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_ADB
		    || VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_I2S)
			runtime->hw = snd_vortex_playback_hw_adb;
#ifdef CHIP_AU8830
		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
			VORTEX_IS_QUAD(vortex) &&
			VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_ADB) {
			runtime->hw.channels_max = 4;
			snd_pcm_hw_constraint_list(runtime, 0,
				SNDRV_PCM_HW_PARAM_CHANNELS,
				&hw_constraints_au8830_channels);
		}
#endif
		substream->runtime->private_data = NULL;
	}
#ifndef CHIP_AU8810
	else {
		runtime->hw = snd_vortex_playback_hw_wt;
		substream->runtime->private_data = NULL;
	}
#endif
	return 0;
}

/* close callback */
static int snd_vortex_pcm_close(struct snd_pcm_substream *substream)
{
	//vortex_t *chip = snd_pcm_substream_chip(substream);
	stream_t *stream = (stream_t *) substream->runtime->private_data;

	// the hardware-specific codes will be here
	if (stream != NULL) {
		stream->substream = NULL;
		stream->nr_ch = 0;
	}
	substream->runtime->private_data = NULL;
	return 0;
}

/* hw_params callback */
static int
snd_vortex_pcm_hw_params(struct snd_pcm_substream *substream,
			 struct snd_pcm_hw_params *hw_params)
{
	vortex_t *chip = snd_pcm_substream_chip(substream);
	stream_t *stream = (stream_t *) (substream->runtime->private_data);

	/*
	   pr_info( "Vortex: periods %d, period_bytes %d, channels = %d\n", params_periods(hw_params),
	   params_period_bytes(hw_params), params_channels(hw_params));
	 */
	spin_lock_irq(&chip->lock);
	// Make audio routes and config buffer DMA.
	if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) {
		int dma, type = VORTEX_PCM_TYPE(substream->pcm);
		/* Dealloc any routes. */
		if (stream != NULL)
			vortex_adb_allocroute(chip, stream->dma,
					      stream->nr_ch, stream->dir,
					      stream->type,
					      substream->number);
		/* Alloc routes. */
		dma =
		    vortex_adb_allocroute(chip, -1,
					  params_channels(hw_params),
					  substream->stream, type,
					  substream->number);
		if (dma < 0) {
			spin_unlock_irq(&chip->lock);
			return dma;
		}
		stream = substream->runtime->private_data = &chip->dma_adb[dma];

Annotation

Implementation Notes