sound/soc/codecs/ak4642.c

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

File Facts

System
Linux kernel
Corpus path
sound/soc/codecs/ak4642.c
Extension
.c
Size
17859 bytes
Lines
696
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

struct ak4642_drvdata {
	const struct regmap_config *regmap_config;
	int extended_frequencies;
};

struct ak4642_priv {
	const struct ak4642_drvdata *drvdata;
	struct clk *mcko;
};

/*
 * Playback Volume (table 39)
 *
 * max : 0x00 : +12.0 dB
 *       ( 0.5 dB step )
 * min : 0xFE : -115.0 dB
 * mute: 0xFF
 */
static const DECLARE_TLV_DB_SCALE(out_tlv, -11550, 50, 1);

static const struct snd_kcontrol_new ak4642_snd_controls[] = {

	SOC_DOUBLE_R_TLV("Digital Playback Volume", L_DVC, R_DVC,
			 0, 0xFF, 1, out_tlv),
	SOC_SINGLE("ALC Capture Switch", ALC_CTL1, 5, 1, 0),
	SOC_SINGLE("ALC Capture ZC Switch", ALC_CTL1, 4, 1, 1),
};

static const struct snd_kcontrol_new ak4642_headphone_control =
	SOC_DAPM_SINGLE("Switch", PW_MGMT2, 6, 1, 0);

static const struct snd_kcontrol_new ak4642_lout_mixer_controls[] = {
	SOC_DAPM_SINGLE("DACL", SG_SL1, 4, 1, 0),
};

/* event handlers */
static int ak4642_lout_event(struct snd_soc_dapm_widget *w,
			     struct snd_kcontrol *kcontrol, int event)
{
	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);

	switch (event) {
	case SND_SOC_DAPM_PRE_PMD:
	case SND_SOC_DAPM_PRE_PMU:
		/* Power save mode ON */
		snd_soc_component_update_bits(component, SG_SL2, LOPS, LOPS);
		break;
	case SND_SOC_DAPM_POST_PMU:
	case SND_SOC_DAPM_POST_PMD:
		/* Power save mode OFF */
		msleep(300);
		snd_soc_component_update_bits(component, SG_SL2, LOPS, 0);
		break;
	}

	return 0;
}

static const struct snd_soc_dapm_widget ak4642_dapm_widgets[] = {

	/* Outputs */
	SND_SOC_DAPM_OUTPUT("HPOUTL"),
	SND_SOC_DAPM_OUTPUT("HPOUTR"),
	SND_SOC_DAPM_OUTPUT("LINEOUT"),

	SND_SOC_DAPM_PGA("HPL Out", PW_MGMT2, 5, 0, NULL, 0),
	SND_SOC_DAPM_PGA("HPR Out", PW_MGMT2, 4, 0, NULL, 0),
	SND_SOC_DAPM_SWITCH("Headphone Enable", SND_SOC_NOPM, 0, 0,
			    &ak4642_headphone_control),

	SND_SOC_DAPM_PGA("DACH", MD_CTL4, 0, 0, NULL, 0),

	SND_SOC_DAPM_MIXER_E("LINEOUT Mixer", PW_MGMT1, 3, 0,
			   &ak4642_lout_mixer_controls[0],
			   ARRAY_SIZE(ak4642_lout_mixer_controls),
			   ak4642_lout_event,
			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),

	/* DAC */
	SND_SOC_DAPM_DAC("DAC", NULL, PW_MGMT1, 2, 0),
};

static const struct snd_soc_dapm_route ak4642_intercon[] = {

	/* Outputs */
	{"HPOUTL", NULL, "HPL Out"},
	{"HPOUTR", NULL, "HPR Out"},
	{"LINEOUT", NULL, "LINEOUT Mixer"},

Annotation

Implementation Notes