sound/soc/codecs/wm8994.c

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

File Facts

System
Linux kernel
Corpus path
sound/soc/codecs/wm8994.c
Extension
.c
Size
136207 bytes
Lines
4711
Domain
Driver Families
Bucket
sound/soc
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 wm8994_reg_mask {
	unsigned int reg;
	unsigned int mask;
};

static struct wm8994_reg_mask wm8994_vu_bits[] = {
	{ WM8994_LEFT_LINE_INPUT_1_2_VOLUME, WM8994_IN1_VU },
	{ WM8994_RIGHT_LINE_INPUT_1_2_VOLUME, WM8994_IN1_VU },
	{ WM8994_LEFT_LINE_INPUT_3_4_VOLUME, WM8994_IN2_VU },
	{ WM8994_RIGHT_LINE_INPUT_3_4_VOLUME, WM8994_IN2_VU },
	{ WM8994_SPEAKER_VOLUME_LEFT, WM8994_SPKOUT_VU },
	{ WM8994_SPEAKER_VOLUME_RIGHT, WM8994_SPKOUT_VU },
	{ WM8994_LEFT_OUTPUT_VOLUME, WM8994_HPOUT1_VU },
	{ WM8994_RIGHT_OUTPUT_VOLUME, WM8994_HPOUT1_VU },
	{ WM8994_LEFT_OPGA_VOLUME, WM8994_MIXOUT_VU },
	{ WM8994_RIGHT_OPGA_VOLUME, WM8994_MIXOUT_VU },

	{ WM8994_AIF1_DAC1_LEFT_VOLUME, WM8994_AIF1DAC1_VU },
	{ WM8994_AIF1_DAC1_RIGHT_VOLUME, WM8994_AIF1DAC1_VU },
	{ WM8994_AIF2_DAC_LEFT_VOLUME, WM8994_AIF2DAC_VU },
	{ WM8994_AIF2_DAC_RIGHT_VOLUME, WM8994_AIF2DAC_VU },
	{ WM8994_AIF1_ADC1_LEFT_VOLUME, WM8994_AIF1ADC1_VU },
	{ WM8994_AIF1_ADC1_RIGHT_VOLUME, WM8994_AIF1ADC1_VU },
	{ WM8994_AIF2_ADC_LEFT_VOLUME, WM8994_AIF2ADC_VU },
	{ WM8994_AIF2_ADC_RIGHT_VOLUME, WM8994_AIF1ADC2_VU },
	{ WM8994_DAC1_LEFT_VOLUME, WM8994_DAC1_VU },
	{ WM8994_DAC1_RIGHT_VOLUME, WM8994_DAC1_VU },
	{ WM8994_DAC2_LEFT_VOLUME, WM8994_DAC2_VU },
	{ WM8994_DAC2_RIGHT_VOLUME, WM8994_DAC2_VU },
};

/* VU bitfields for ADC2, DAC2 not available on WM1811 */
static struct wm8994_reg_mask wm8994_adc2_dac2_vu_bits[] = {
	{ WM8994_AIF1_DAC2_LEFT_VOLUME, WM8994_AIF1DAC2_VU },
	{ WM8994_AIF1_DAC2_RIGHT_VOLUME, WM8994_AIF1DAC2_VU },
	{ WM8994_AIF1_ADC2_LEFT_VOLUME, WM8994_AIF1ADC2_VU },
	{ WM8994_AIF1_ADC2_RIGHT_VOLUME, WM8994_AIF1ADC2_VU },
};

static int wm8994_drc_base[] = {
	WM8994_AIF1_DRC1_1,
	WM8994_AIF1_DRC2_1,
	WM8994_AIF2_DRC_1,
};

static int wm8994_retune_mobile_base[] = {
	WM8994_AIF1_DAC1_EQ_GAINS_1,
	WM8994_AIF1_DAC2_EQ_GAINS_1,
	WM8994_AIF2_EQ_GAINS_1,
};

static const struct wm8958_micd_rate micdet_rates[] = {
	{ 32768,       true,  1, 4 },
	{ 32768,       false, 1, 1 },
	{ 44100 * 256, true,  7, 10 },
	{ 44100 * 256, false, 7, 10 },
};

static const struct wm8958_micd_rate jackdet_rates[] = {
	{ 32768,       true,  0, 1 },
	{ 32768,       false, 0, 1 },
	{ 44100 * 256, true,  10, 10 },
	{ 44100 * 256, false, 7, 8 },
};

static void wm8958_micd_set_rate(struct snd_soc_component *component)
{
	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
	struct wm8994 *control = wm8994->wm8994;
	int best, i, sysclk, val;
	bool idle;
	const struct wm8958_micd_rate *rates;
	int num_rates;

	idle = !wm8994->jack_mic;

	sysclk = snd_soc_component_read(component, WM8994_CLOCKING_1);
	if (sysclk & WM8994_SYSCLK_SRC)
		sysclk = wm8994->aifclk[1];
	else
		sysclk = wm8994->aifclk[0];

	if (control->pdata.micd_rates) {
		rates = control->pdata.micd_rates;
		num_rates = control->pdata.num_micd_rates;
	} else if (wm8994->jackdet) {
		rates = jackdet_rates;
		num_rates = ARRAY_SIZE(jackdet_rates);
	} else {
		rates = micdet_rates;

Annotation

Implementation Notes