sound/soc/codecs/rt5682s.c

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

File Facts

System
Linux kernel
Corpus path
sound/soc/codecs/rt5682s.c
Extension
.c
Size
102446 bytes
Lines
3350
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

switch (val) {
		case 0x1:
		case 0x2:
			jack_type = SND_JACK_HEADSET;
			snd_soc_component_write(component, RT5682S_SAR_IL_CMD_3, 0x024c);
			snd_soc_component_update_bits(component, RT5682S_CBJ_CTRL_1,
				RT5682S_FAST_OFF_MASK, RT5682S_FAST_OFF_DIS);
			snd_soc_component_update_bits(component, RT5682S_SAR_IL_CMD_1,
				RT5682S_SAR_SEL_MB1_2_MASK, val << RT5682S_SAR_SEL_MB1_2_SFT);
			rt5682s_enable_push_button_irq(component);
			rt5682s_sar_power_mode(component, SAR_PWR_SAVING);
			break;
		default:
			jack_type = SND_JACK_HEADPHONE;
			break;
		}
		snd_soc_component_update_bits(component, RT5682S_HP_CHARGE_PUMP_2,
			RT5682S_OSW_L_MASK | RT5682S_OSW_R_MASK,
			RT5682S_OSW_L_EN | RT5682S_OSW_R_EN);
		usleep_range(35000, 40000);
	} else {
		rt5682s_sar_power_mode(component, SAR_PWR_OFF);
		rt5682s_disable_push_button_irq(component);
		snd_soc_component_update_bits(component, RT5682S_CBJ_CTRL_1,
			RT5682S_TRIG_JD_MASK, RT5682S_TRIG_JD_LOW);

		if (!rt5682s->wclk_enabled) {
			snd_soc_component_update_bits(component,
				RT5682S_PWR_ANLG_1, RT5682S_PWR_VREF2 | RT5682S_PWR_MB, 0);
		}

		snd_soc_component_update_bits(component, RT5682S_PWR_ANLG_3,
			RT5682S_PWR_CBJ, 0);
		snd_soc_component_update_bits(component, RT5682S_CBJ_CTRL_1,
			RT5682S_FAST_OFF_MASK, RT5682S_FAST_OFF_DIS);
		snd_soc_component_update_bits(component, RT5682S_CBJ_CTRL_3,
			RT5682S_CBJ_IN_BUF_MASK, RT5682S_CBJ_IN_BUF_DIS);
		jack_type = 0;
	}

	dev_dbg(component->dev, "jack_type = %d\n", jack_type);

	return jack_type;
}

static void rt5682s_jack_detect_handler(struct work_struct *work)
{
	struct rt5682s_priv *rt5682s =
		container_of(work, struct rt5682s_priv, jack_detect_work.work);
	struct snd_soc_dapm_context *dapm;
	int val, btn_type;

	if (!rt5682s->component ||
	    !snd_soc_card_is_instantiated(rt5682s->component->card)) {
		/* card not yet ready, try later */
		mod_delayed_work(system_power_efficient_wq,
				 &rt5682s->jack_detect_work, msecs_to_jiffies(15));
		return;
	}

	dapm = snd_soc_component_to_dapm(rt5682s->component);

	snd_soc_dapm_mutex_lock(dapm);
	mutex_lock(&rt5682s->calibrate_mutex);
	mutex_lock(&rt5682s->wclk_mutex);

	val = snd_soc_component_read(rt5682s->component, RT5682S_AJD1_CTRL)
		& RT5682S_JDH_RS_MASK;
	if (!val) {
		/* jack in */
		if (rt5682s->jack_type == 0) {
			/* jack was out, report jack type */
			rt5682s->jack_type = rt5682s_headset_detect(rt5682s->component, 1);
			rt5682s->irq_work_delay_time = 0;
		} else if ((rt5682s->jack_type & SND_JACK_HEADSET) == SND_JACK_HEADSET) {
			/* jack is already in, report button event */
			rt5682s->jack_type = SND_JACK_HEADSET;
			btn_type = rt5682s_button_detect(rt5682s->component);
			/**
			 * rt5682s can report three kinds of button behavior,
			 * one click, double click and hold. However,
			 * currently we will report button pressed/released
			 * event. So all the three button behaviors are
			 * treated as button pressed.
			 */
			switch (btn_type) {
			case 0x8000:
			case 0x4000:
			case 0x2000:
				rt5682s->jack_type |= SND_JACK_BTN_0;

Annotation

Implementation Notes