sound/soc/codecs/rt715.c

Source file repositories/reference/linux-study-clean/sound/soc/codecs/rt715.c

File Facts

System
Linux kernel
Corpus path
sound/soc/codecs/rt715.c
Extension
.c
Size
33093 bytes
Lines
1134
Domain
Driver Families
Bucket
sound/soc
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 (ucontrol->value.integer.value[i] != rt715->kctl_2ch_vol_ori[i]) {
			k_vol_changed = 1;
			break;
		}
	}

	/* Can't use update bit function, so read the original value first */
	addr_h = mc->reg;
	addr_l = mc->rreg;

	if (mc->shift == RT715_DIR_OUT_SFT) /* output */
		val_h = 0x80;
	else /* input */
		val_h = 0x0;

	rt715_get_gain(rt715, addr_h, addr_l, val_h, &read_rl, &read_ll);

	if (snd_soc_dapm_get_bias_level(dapm) <= SND_SOC_BIAS_STANDBY)
		regmap_write(rt715->regmap,
				RT715_SET_AUDIO_POWER_STATE, AC_PWRST_D0);

	/* L Channel */
	rt715->kctl_2ch_vol_ori[0] = ucontrol->value.integer.value[0];
	/* for gain */
	val_ll = ((ucontrol->value.integer.value[0]) & 0x7f);
	if (val_ll > mc->max)
		val_ll = mc->max;
	/* keep mute status */
	val_ll |= read_ll & 0x80;

	/* R Channel */
	rt715->kctl_2ch_vol_ori[1] = ucontrol->value.integer.value[1];
	/* for gain */
	val_lr = ((ucontrol->value.integer.value[1]) & 0x7f);
	if (val_lr > mc->max)
		val_lr = mc->max;
	/* keep mute status */
	val_lr |= read_rl & 0x80;

	for (i = 0; i < 3; i++) { /* retry 3 times at most */

		if (val_ll == val_lr) {
			/* Set both L/R channels at the same time */
			val_h = (1 << mc->shift) | (3 << 4);
			regmap_write(rt715->regmap, addr_h,
				(val_h << 8) | val_ll);
			regmap_write(rt715->regmap, addr_l,
				(val_h << 8) | val_ll);
		} else {
			/* Lch*/
			val_h = (1 << mc->shift) | (1 << 5);
			regmap_write(rt715->regmap, addr_h,
				(val_h << 8) | val_ll);
			/* Rch */
			val_h = (1 << mc->shift) | (1 << 4);
			regmap_write(rt715->regmap, addr_l,
				(val_h << 8) | val_lr);
		}
		/* check result */
		if (mc->shift == RT715_DIR_OUT_SFT) /* output */
			val_h = 0x80;
		else /* input */
			val_h = 0x0;

		rt715_get_gain(rt715, addr_h, addr_l, val_h,
				&read_rl, &read_ll);
		if (read_rl == val_lr && read_ll == val_ll)
			break;
	}

	/* D0:power on state, D3: power saving mode */
	if (snd_soc_dapm_get_bias_level(dapm) <= SND_SOC_BIAS_STANDBY)
		regmap_write(rt715->regmap,
				RT715_SET_AUDIO_POWER_STATE, AC_PWRST_D3);
	return k_vol_changed;
}

static int rt715_set_amp_gain_get(struct snd_kcontrol *kcontrol,
				  struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
	struct rt715_priv *rt715 = snd_soc_component_get_drvdata(component);
	struct soc_mixer_control *mc =
		(struct soc_mixer_control *)kcontrol->private_value;
	unsigned int addr_h, addr_l, val_h;
	unsigned int read_ll, read_rl;

	addr_h = mc->reg;
	addr_l = mc->rreg;
	if (mc->shift == RT715_DIR_OUT_SFT) /* output */

Annotation

Implementation Notes