sound/soc/codecs/rt5651.c

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

File Facts

System
Linux kernel
Corpus path
sound/soc/codecs/rt5651.c
Extension
.c
Size
71196 bytes
Lines
2293
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 (SND_SOC_BIAS_STANDBY == snd_soc_dapm_get_bias_level(dapm)) {
			if (snd_soc_component_read(component, RT5651_PLL_MODE_1) & 0x9200)
				snd_soc_component_update_bits(component, RT5651_D_MISC,
						    0xc00, 0xc00);
		}
		break;
	case SND_SOC_BIAS_STANDBY:
		if (SND_SOC_BIAS_OFF == snd_soc_dapm_get_bias_level(dapm)) {
			snd_soc_component_update_bits(component, RT5651_PWR_ANLG1,
				RT5651_PWR_VREF1 | RT5651_PWR_MB |
				RT5651_PWR_BG | RT5651_PWR_VREF2,
				RT5651_PWR_VREF1 | RT5651_PWR_MB |
				RT5651_PWR_BG | RT5651_PWR_VREF2);
			usleep_range(10000, 15000);
			snd_soc_component_update_bits(component, RT5651_PWR_ANLG1,
				RT5651_PWR_FV1 | RT5651_PWR_FV2,
				RT5651_PWR_FV1 | RT5651_PWR_FV2);
			snd_soc_component_update_bits(component, RT5651_D_MISC, 0x1, 0x1);
		}
		break;

	case SND_SOC_BIAS_OFF:
		snd_soc_component_write(component, RT5651_D_MISC, 0x0010);
		snd_soc_component_write(component, RT5651_PWR_DIG1, 0x0000);
		snd_soc_component_write(component, RT5651_PWR_DIG2, 0x0000);
		snd_soc_component_write(component, RT5651_PWR_VOL, 0x0000);
		snd_soc_component_write(component, RT5651_PWR_MIXER, 0x0000);
		/* Do not touch the LDO voltage select bits on bias-off */
		snd_soc_component_update_bits(component, RT5651_PWR_ANLG1,
			~RT5651_PWR_LDO_DVO_MASK, 0);
		/* Leave PLL1 and jack-detect power as is, all others off */
		snd_soc_component_update_bits(component, RT5651_PWR_ANLG2,
				    ~(RT5651_PWR_PLL | RT5651_PWR_JD_M), 0);
		break;

	default:
		break;
	}

	return 0;
}

static void rt5651_enable_micbias1_for_ovcd(struct snd_soc_component *component)
{
	struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component);

	snd_soc_dapm_mutex_lock(dapm);
	snd_soc_dapm_force_enable_pin_unlocked(dapm, "LDO");
	snd_soc_dapm_force_enable_pin_unlocked(dapm, "micbias1");
	/* OVCD is unreliable when used with RCCLK as sysclk-source */
	snd_soc_dapm_force_enable_pin_unlocked(dapm, "Platform Clock");
	snd_soc_dapm_sync_unlocked(dapm);
	snd_soc_dapm_mutex_unlock(dapm);
}

static void rt5651_disable_micbias1_for_ovcd(struct snd_soc_component *component)
{
	struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component);

	snd_soc_dapm_mutex_lock(dapm);
	snd_soc_dapm_disable_pin_unlocked(dapm, "Platform Clock");
	snd_soc_dapm_disable_pin_unlocked(dapm, "micbias1");
	snd_soc_dapm_disable_pin_unlocked(dapm, "LDO");
	snd_soc_dapm_sync_unlocked(dapm);
	snd_soc_dapm_mutex_unlock(dapm);
}

static void rt5651_enable_micbias1_ovcd_irq(struct snd_soc_component *component)
{
	struct rt5651_priv *rt5651 = snd_soc_component_get_drvdata(component);

	snd_soc_component_update_bits(component, RT5651_IRQ_CTRL2,
		RT5651_IRQ_MB1_OC_MASK, RT5651_IRQ_MB1_OC_NOR);
	rt5651->ovcd_irq_enabled = true;
}

static void rt5651_disable_micbias1_ovcd_irq(struct snd_soc_component *component)
{
	struct rt5651_priv *rt5651 = snd_soc_component_get_drvdata(component);

	snd_soc_component_update_bits(component, RT5651_IRQ_CTRL2,
		RT5651_IRQ_MB1_OC_MASK, RT5651_IRQ_MB1_OC_BP);
	rt5651->ovcd_irq_enabled = false;
}

static void rt5651_clear_micbias1_ovcd(struct snd_soc_component *component)
{
	snd_soc_component_update_bits(component, RT5651_IRQ_CTRL2,
		RT5651_MB1_OC_CLR, 0);
}

Annotation

Implementation Notes