sound/pci/emu10k1/emupcm.c

Source file repositories/reference/linux-study-clean/sound/pci/emu10k1/emupcm.c

File Facts

System
Linux kernel
Corpus path
sound/pci/emu10k1/emupcm.c
Extension
.c
Size
57195 bytes
Lines
1837
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 (epcm->voices[i]) {
			snd_emu10k1_voice_free(epcm->emu, epcm->voices[i]);
			epcm->voices[i] = NULL;
		}
	}
}

static int snd_emu10k1_pcm_channel_alloc(struct snd_emu10k1_pcm *epcm,
					 int type, int count, int channels)
{
	int err;

	snd_emu10k1_pcm_free_voices(epcm);

	err = snd_emu10k1_voice_alloc(epcm->emu,
				      type, count, channels,
				      epcm, &epcm->voices[0]);
	if (err < 0)
		return err;

	if (epcm->extra == NULL) {
		// The hardware supports only (half-)loop interrupts, so to support an
		// arbitrary number of periods per buffer, we use an extra voice with a
		// period-sized loop as the interrupt source. Additionally, the interrupt
		// timing of the hardware is "suboptimal" and needs some compensation.
		err = snd_emu10k1_voice_alloc(epcm->emu,
					      type + 1, 1, 1,
					      epcm, &epcm->extra);
		if (err < 0) {
			/*
			dev_dbg(emu->card->dev, "pcm_channel_alloc: "
			       "failed extra: voices=%d, frame=%d\n",
			       voices, frame);
			*/
			snd_emu10k1_pcm_free_voices(epcm);
			return err;
		}
		epcm->extra->interrupt = snd_emu10k1_pcm_interrupt;
	}

	return 0;
}

// Primes 2-7 and 2^n multiples thereof, up to 16.
static const unsigned int efx_capture_channels[] = {
	1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16
};

static const struct snd_pcm_hw_constraint_list hw_constraints_efx_capture_channels = {
	.count = ARRAY_SIZE(efx_capture_channels),
	.list = efx_capture_channels,
	.mask = 0
};

static const unsigned int capture_buffer_sizes[31] = {
	384,	448,	512,	640,
	384*2,	448*2,	512*2,	640*2,
	384*4,	448*4,	512*4,	640*4,
	384*8,	448*8,	512*8,	640*8,
	384*16,	448*16,	512*16,	640*16,
	384*32,	448*32,	512*32,	640*32,
	384*64,	448*64,	512*64,	640*64,
	384*128,448*128,512*128
};

static const struct snd_pcm_hw_constraint_list hw_constraints_capture_buffer_sizes = {
	.count = 31,
	.list = capture_buffer_sizes,
	.mask = 0
};

static unsigned int snd_emu10k1_capture_rate_reg(unsigned int rate)
{
	switch (rate) {
	case 8000:	return ADCCR_SAMPLERATE_8;
	case 11025:	return ADCCR_SAMPLERATE_11;
	case 16000:	return ADCCR_SAMPLERATE_16;
	case 22050:	return ADCCR_SAMPLERATE_22;
	case 24000:	return ADCCR_SAMPLERATE_24;
	case 32000:	return ADCCR_SAMPLERATE_32;
	case 44100:	return ADCCR_SAMPLERATE_44;
	case 48000:	return ADCCR_SAMPLERATE_48;
	default:
			snd_BUG();
			return ADCCR_SAMPLERATE_8;
	}
}

static unsigned int snd_emu10k1_audigy_capture_rate_reg(unsigned int rate)
{

Annotation

Implementation Notes