sound/soc/codecs/rt721-sdca.c

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

File Facts

System
Linux kernel
Corpus path
sound/soc/codecs/rt721-sdca.c
Extension
.c
Size
49096 bytes
Lines
1562
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 (ret != -EACCES) {
			dev_err(component->dev, "%s: failed to resume %d\n", __func__, ret);
			return ret;
		}
		/* pm_runtime not enabled yet */
		dev_dbg(component->dev,	"%s: skipping jack init for now\n", __func__);
		return 0;
	}

	rt721_sdca_jack_init(rt721);

	pm_runtime_put_autosuspend(component->dev);

	return 0;
}

/* For SDCA control DAC/ADC Gain */
static int rt721_sdca_set_gain_put(struct snd_kcontrol *kcontrol,
		struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
	struct soc_mixer_control *mc =
		(struct soc_mixer_control *)kcontrol->private_value;
	struct rt721_sdca_priv *rt721 = snd_soc_component_get_drvdata(component);
	unsigned int read_l, read_r, gain_l_val, gain_r_val;
	unsigned int adc_vol_flag = 0, changed = 0;
	unsigned int lvalue, rvalue;
	const unsigned int interval_offset = 0xc0;
	const unsigned int tendA = 0x200;
	const unsigned int tendB = 0xa00;

	if (strstr(ucontrol->id.name, "FU1E Capture Volume") ||
		strstr(ucontrol->id.name, "FU0F Capture Volume"))
		adc_vol_flag = 1;

	regmap_read(rt721->mbq_regmap, mc->reg, &lvalue);
	regmap_read(rt721->mbq_regmap, mc->rreg, &rvalue);

	/* L Channel */
	gain_l_val = ucontrol->value.integer.value[0];
	if (gain_l_val > mc->max)
		gain_l_val = mc->max;

	if (mc->shift == 8) {
		/* boost gain */
		gain_l_val = gain_l_val * tendB;
	} else if (mc->shift == 1) {
		/* FU33 boost gain */
		if (gain_l_val == 0)
			gain_l_val = 0x8000;
		else
			gain_l_val = (gain_l_val - 1) * tendA;
	} else {
		/* ADC/DAC gain */
		if (adc_vol_flag)
			gain_l_val = 0x1e00 - ((mc->max - gain_l_val) * interval_offset);
		else
			gain_l_val = 0 - ((mc->max - gain_l_val) * interval_offset);
		gain_l_val &= 0xffff;
	}

	/* R Channel */
	gain_r_val = ucontrol->value.integer.value[1];
	if (gain_r_val > mc->max)
		gain_r_val = mc->max;

	if (mc->shift == 8) {
		/* boost gain */
		gain_r_val = gain_r_val * tendB;
	} else if (mc->shift == 1) {
		/* FU33 boost gain */
		if (gain_r_val == 0)
			gain_r_val = 0x8000;
		else
			gain_r_val = (gain_r_val - 1) * tendA;
	} else {
		/* ADC/DAC gain */
		if (adc_vol_flag)
			gain_r_val = 0x1e00 - ((mc->max - gain_r_val) * interval_offset);
		else
			gain_r_val = 0 - ((mc->max - gain_r_val) * interval_offset);
		gain_r_val &= 0xffff;
	}

	if (lvalue != gain_l_val || rvalue != gain_r_val)
		changed = 1;
	else
		return 0;

	/* Lch*/

Annotation

Implementation Notes