sound/pci/ctxfi/ctatc.c

Source file repositories/reference/linux-study-clean/sound/pci/ctxfi/ctatc.c

File Facts

System
Linux kernel
Corpus path
sound/pci/ctxfi/ctatc.c
Extension
.c
Size
44324 bytes
Lines
1796
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

struct src_node_conf_t {
	unsigned int pitch;
	unsigned int msr:8;
	unsigned int mix_msr:8;
	unsigned int imp_msr:8;
	unsigned int vo:1;
};

static void setup_src_node_conf(struct ct_atc *atc, struct ct_atc_pcm *apcm,
				struct src_node_conf_t *conf, int *n_srcc)
{
	unsigned int pitch;

	/* get pitch and convert to fixed-point 8.24 format. */
	pitch = atc_get_pitch((atc->rsr * atc->msr),
				apcm->substream->runtime->rate);
	*n_srcc = 0;

	if (1 == atc->msr) { /* FIXME: do we really need SRC here if pitch==1 */
		*n_srcc = apcm->substream->runtime->channels;
		conf[0].pitch = pitch;
		conf[0].mix_msr = conf[0].imp_msr = conf[0].msr = 1;
		conf[0].vo = 1;
	} else if (2 <= atc->msr) {
		if (0x8000000 < pitch) {
			/* Need two-stage SRCs, SRCIMPs and
			 * AMIXERs for converting format */
			conf[0].pitch = (atc->msr << 24);
			conf[0].msr = conf[0].mix_msr = 1;
			conf[0].imp_msr = atc->msr;
			conf[0].vo = 0;
			conf[1].pitch = atc_get_pitch(atc->rsr,
					apcm->substream->runtime->rate);
			conf[1].msr = conf[1].mix_msr = conf[1].imp_msr = 1;
			conf[1].vo = 1;
			*n_srcc = apcm->substream->runtime->channels * 2;
		} else if (0x1000000 < pitch) {
			/* Need one-stage SRCs, SRCIMPs and
			 * AMIXERs for converting format */
			conf[0].pitch = pitch;
			conf[0].msr = conf[0].mix_msr
				    = conf[0].imp_msr = atc->msr;
			conf[0].vo = 1;
			*n_srcc = apcm->substream->runtime->channels;
		}
	}
}

static int
atc_pcm_capture_get_resources(struct ct_atc *atc, struct ct_atc_pcm *apcm)
{
	struct src_mgr *src_mgr = atc->rsc_mgrs[SRC];
	struct srcimp_mgr *srcimp_mgr = atc->rsc_mgrs[SRCIMP];
	struct amixer_mgr *amixer_mgr = atc->rsc_mgrs[AMIXER];
	struct sum_mgr *sum_mgr = atc->rsc_mgrs[SUM];
	struct src_desc src_dsc = {0};
	struct src *src;
	struct srcimp_desc srcimp_dsc = {0};
	struct srcimp *srcimp;
	struct amixer_desc mix_dsc = {0};
	struct sum_desc sum_dsc = {0};
	unsigned int pitch;
	int multi, err, i;
	int n_srcimp, n_amixer, n_srcc, n_sum;
	struct src_node_conf_t src_node_conf[2] = {{0} };

	/* first release old resources */
	atc_pcm_release_resources(atc, apcm);

	/* The numbers of converting SRCs and SRCIMPs should be determined
	 * by pitch value. */

	multi = apcm->substream->runtime->channels;

	/* get pitch and convert to fixed-point 8.24 format. */
	pitch = atc_get_pitch((atc->rsr * atc->msr),
				apcm->substream->runtime->rate);

	setup_src_node_conf(atc, apcm, src_node_conf, &n_srcc);
	n_sum = (1 == multi) ? 1 : 0;
	n_amixer = n_sum * 2 + n_srcc;
	n_srcimp = n_srcc;
	if ((multi > 1) && (0x8000000 >= pitch)) {
		/* Need extra AMIXERs and SRCIMPs for special treatment
		 * of interleaved recording of conjugate channels */
		n_amixer += multi * atc->msr;
		n_srcimp += multi * atc->msr;
	} else {
		n_srcimp += multi;
	}

Annotation

Implementation Notes