sound/soc/codecs/rt5670.c

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

File Facts

System
Linux kernel
Corpus path
sound/soc/codecs/rt5670.c
Extension
.c
Size
103971 bytes
Lines
3346
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

if (val == 0x1 || val == 0x2) {
			rt5670->jack_type = SND_JACK_HEADSET;
			/* for push button */
			snd_soc_component_update_bits(component, RT5670_INT_IRQ_ST, 0x8, 0x8);
			snd_soc_component_update_bits(component, RT5670_IL_CMD, 0x40, 0x40);
			snd_soc_component_read(component, RT5670_IL_CMD);
		} else {
			snd_soc_component_update_bits(component, RT5670_GEN_CTRL3, 0x4, 0x4);
			rt5670->jack_type = SND_JACK_HEADPHONE;
			snd_soc_dapm_disable_pin(dapm, "Mic Det Power");
			snd_soc_dapm_sync(dapm);
		}
	} else {
		snd_soc_component_update_bits(component, RT5670_INT_IRQ_ST, 0x8, 0x0);
		snd_soc_component_update_bits(component, RT5670_GEN_CTRL3, 0x4, 0x4);
		rt5670->jack_type = 0;
		snd_soc_dapm_disable_pin(dapm, "Mic Det Power");
		snd_soc_dapm_sync(dapm);
	}

	return rt5670->jack_type;
}

void rt5670_jack_suspend(struct snd_soc_component *component)
{
	struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);

	rt5670->jack_type_saved = rt5670->jack_type;
	rt5670_headset_detect(component, 0);
}
EXPORT_SYMBOL_GPL(rt5670_jack_suspend);

void rt5670_jack_resume(struct snd_soc_component *component)
{
	struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);

	if (rt5670->jack_type_saved)
		rt5670_headset_detect(component, 1);
}
EXPORT_SYMBOL_GPL(rt5670_jack_resume);

static int rt5670_button_detect(struct snd_soc_component *component)
{
	int btn_type, val;

	val = snd_soc_component_read(component, RT5670_IL_CMD);
	btn_type = val & 0xff80;
	snd_soc_component_write(component, RT5670_IL_CMD, val);
	if (btn_type != 0) {
		msleep(20);
		val = snd_soc_component_read(component, RT5670_IL_CMD);
		snd_soc_component_write(component, RT5670_IL_CMD, val);
	}

	return btn_type;
}

static int rt5670_irq_detection(void *data)
{
	struct rt5670_priv *rt5670 = (struct rt5670_priv *)data;
	struct snd_soc_jack_gpio *gpio = &rt5670->hp_gpio;
	struct snd_soc_jack *jack = rt5670->jack;
	int val, btn_type, report = jack->status;

	if (rt5670->jd_mode == 1) /* 2 port */
		val = snd_soc_component_read(rt5670->component, RT5670_A_JD_CTRL1) & 0x0070;
	else
		val = snd_soc_component_read(rt5670->component, RT5670_A_JD_CTRL1) & 0x0020;

	switch (val) {
	/* jack in */
	case 0x30: /* 2 port */
	case 0x0: /* 1 port or 2 port */
		if (rt5670->jack_type == 0) {
			report = rt5670_headset_detect(rt5670->component, 1);
			/* for push button and jack out */
			gpio->debounce_time = 25;
			break;
		}
		btn_type = 0;
		if (snd_soc_component_read(rt5670->component, RT5670_INT_IRQ_ST) & 0x4) {
			/* button pressed */
			report = SND_JACK_HEADSET;
			btn_type = rt5670_button_detect(rt5670->component);
			switch (btn_type) {
			case 0x2000: /* up */
				report |= SND_JACK_BTN_1;
				break;
			case 0x0400: /* center */
				report |= SND_JACK_BTN_0;

Annotation

Implementation Notes