sound/hda/common/auto_parser.c

Source file repositories/reference/linux-study-clean/sound/hda/common/auto_parser.c

File Facts

System
Linux kernel
Corpus path
sound/hda/common/auto_parser.c
Extension
.c
Size
31586 bytes
Lines
1105
Domain
Driver Families
Bucket
sound/hda
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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 auto_out_pin {
	hda_nid_t pin;
	short seq;
};

static int compare_seq(const void *ap, const void *bp)
{
	const struct auto_out_pin *a = ap;
	const struct auto_out_pin *b = bp;
	return (int)(a->seq - b->seq);
}

/*
 * Sort an associated group of pins according to their sequence numbers.
 * then store it to a pin array.
 */
static void sort_pins_by_sequence(hda_nid_t *pins, struct auto_out_pin *list,
				  int num_pins)
{
	int i;
	sort(list, num_pins, sizeof(list[0]), compare_seq, NULL);
	for (i = 0; i < num_pins; i++)
		pins[i] = list[i].pin;
}


/* add the found input-pin to the cfg->inputs[] table */
static void add_auto_cfg_input_pin(struct hda_codec *codec, struct auto_pin_cfg *cfg,
				   hda_nid_t nid, int type)
{
	if (cfg->num_inputs < AUTO_CFG_MAX_INS) {
		cfg->inputs[cfg->num_inputs].pin = nid;
		cfg->inputs[cfg->num_inputs].type = type;
		cfg->inputs[cfg->num_inputs].has_boost_on_pin =
			nid_has_volume(codec, nid, HDA_INPUT);
		cfg->num_inputs++;
	}
}

static int compare_input_type(const void *ap, const void *bp)
{
	const struct auto_pin_cfg_item *a = ap;
	const struct auto_pin_cfg_item *b = bp;
	if (a->type != b->type)
		return (int)(a->type - b->type);

	/* If has both hs_mic and hp_mic, pick the hs_mic ahead of hp_mic. */
	if (a->is_headset_mic && b->is_headphone_mic)
		return -1; /* don't swap */
	else if (a->is_headphone_mic && b->is_headset_mic)
		return 1; /* swap */

	/* In case one has boost and the other one has not,
	   pick the one with boost first. */
	if (a->has_boost_on_pin != b->has_boost_on_pin)
		return (int)(b->has_boost_on_pin - a->has_boost_on_pin);

	/* Keep the original order */
	return a->order - b->order;
}

/* Reorder the surround channels
 * ALSA sequence is front/surr/clfe/side
 * HDA sequence is:
 *    4-ch: front/surr  =>  OK as it is
 *    6-ch: front/clfe/surr
 *    8-ch: front/clfe/rear/side|fc
 */
static void reorder_outputs(unsigned int nums, hda_nid_t *pins)
{
	switch (nums) {
	case 3:
	case 4:
		swap(pins[1], pins[2]);
		break;
	}
}

/* check whether the given pin has a proper pin I/O capability bit */
static bool check_pincap_validity(struct hda_codec *codec, hda_nid_t pin,
				  unsigned int dev)
{
	unsigned int pincap = snd_hda_query_pin_caps(codec, pin);

	/* some old hardware don't return the proper pincaps */
	if (!pincap)
		return true;

	switch (dev) {
	case AC_JACK_LINE_OUT:

Annotation

Implementation Notes