sound/pci/lola/lola_mixer.c

Source file repositories/reference/linux-study-clean/sound/pci/lola/lola_mixer.c

File Facts

System
Linux kernel
Corpus path
sound/pci/lola/lola_mixer.c
Extension
.c
Size
24118 bytes
Lines
843
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 (mask & (1 << i)) {
			writew(*gains, &chip->mixer.array->src_gain[i]);
			gains++;
		}
	}
	writel(mask, &chip->mixer.array->src_gain_enable);
	lola_codec_flush(chip);
	if (chip->mixer.caps & LOLA_PEAK_METER_CAN_AGC_MASK) {
		/* update for all srcs at once */
		return lola_codec_write(chip, chip->mixer.nid,
					LOLA_VERB_SET_SOURCE_GAIN, 0x80, 0);
	}
	/* update manually */
	for (i = 0; i < LOLA_MIXER_DIM; i++) {
		if (mask & (1 << i)) {
			lola_codec_write(chip, chip->mixer.nid,
					 LOLA_VERB_SET_SOURCE_GAIN, i, 0);
		}
	}
	return 0;
}
#endif /* not used */

static int lola_mixer_set_mapping_gain(struct lola *chip,
				       unsigned int src, unsigned int dest,
				       unsigned short gain, bool on)
{
	unsigned int val;

	if (!(chip->mixer.src_mask & (1 << src)) ||
	    !(chip->mixer.dest_mask & (1 << dest)))
		return -EINVAL;
	if (on)
		writew(gain, &chip->mixer.array->dest_mix_gain[dest][src]);
	val = readl(&chip->mixer.array->dest_mix_gain_enable[dest]);
	if (on)
		val |= (1 << src);
	else
		val &= ~(1 << src);
	writel(val, &chip->mixer.array->dest_mix_gain_enable[dest]);
	lola_codec_flush(chip);
	return lola_codec_write(chip, chip->mixer.nid, LOLA_VERB_SET_MIX_GAIN,
				src, dest);
}

#if 0 /* not used */
static int lola_mixer_set_dest_gains(struct lola *chip, unsigned int id,
				     unsigned int mask, unsigned short *gains)
{
	int i;

	if (!(chip->mixer.dest_mask & (1 << id)) ||
	    (chip->mixer.src_mask & mask) != mask)
		return -EINVAL;
	for (i = 0; i < LOLA_MIXER_DIM; i++) {
		if (mask & (1 << i)) {
			writew(*gains, &chip->mixer.array->dest_mix_gain[id][i]);
			gains++;
		}
	}
	writel(mask, &chip->mixer.array->dest_mix_gain_enable[id]);
	lola_codec_flush(chip);
	/* update for all dests at once */
	return lola_codec_write(chip, chip->mixer.nid,
				LOLA_VERB_SET_DESTINATION_GAIN, id, 0);
}
#endif /* not used */

/*
 */

static int set_analog_volume(struct lola *chip, int dir,
			     unsigned int idx, unsigned int val,
			     bool external_call);

int lola_setup_all_analog_gains(struct lola *chip, int dir, bool mute)
{
	struct lola_pin *pin;
	int idx, max_idx;

	pin = chip->pin[dir].pins;
	max_idx = chip->pin[dir].num_pins;
	for (idx = 0; idx < max_idx; idx++) {
		if (pin[idx].is_analog) {
			unsigned int val = mute ? 0 : pin[idx].cur_gain_step;
			/* set volume and do not save the value */
			set_analog_volume(chip, dir, idx, val, false);
		}
	}
	return lola_codec_flush(chip);

Annotation

Implementation Notes