sound/soc/codecs/sgtl5000.c

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

File Facts

System
Linux kernel
Corpus path
sound/soc/codecs/sgtl5000.c
Extension
.c
Size
52063 bytes
Lines
1840
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 sgtl5000_priv {
	int sysclk;	/* sysclk rate */
	int master;	/* i2s master or not */
	int fmt;	/* i2s data format */
	struct regulator_bulk_data supplies[SGTL5000_SUPPLY_NUM];
	int num_supplies;
	struct regmap *regmap;
	struct clk *mclk;
	int revision;
	u8 micbias_resistor;
	u8 micbias_voltage;
	u8 lrclk_strength;
	u8 sclk_strength;
	u16 mute_state[LAST_POWER_EVENT + 1];
};

static inline int hp_sel_input(struct snd_soc_component *component)
{
	return (snd_soc_component_read(component, SGTL5000_CHIP_ANA_CTRL) &
		SGTL5000_HP_SEL_MASK) >> SGTL5000_HP_SEL_SHIFT;
}

static inline u16 mute_output(struct snd_soc_component *component,
			      u16 mute_mask)
{
	u16 mute_reg = snd_soc_component_read(component,
					      SGTL5000_CHIP_ANA_CTRL);

	snd_soc_component_update_bits(component, SGTL5000_CHIP_ANA_CTRL,
			    mute_mask, mute_mask);
	return mute_reg;
}

static inline void restore_output(struct snd_soc_component *component,
				  u16 mute_mask, u16 mute_reg)
{
	snd_soc_component_update_bits(component, SGTL5000_CHIP_ANA_CTRL,
		mute_mask, mute_reg);
}

static void vag_power_on(struct snd_soc_component *component, u32 source)
{
	if (snd_soc_component_read(component, SGTL5000_CHIP_ANA_POWER) &
	    SGTL5000_VAG_POWERUP)
		return;

	snd_soc_component_update_bits(component, SGTL5000_CHIP_ANA_POWER,
			    SGTL5000_VAG_POWERUP, SGTL5000_VAG_POWERUP);

	/* When VAG powering on to get local loop from Line-In, the sleep
	 * is required to avoid loud pop.
	 */
	if (hp_sel_input(component) == SGTL5000_HP_SEL_LINE_IN &&
	    source == HP_POWER_EVENT)
		msleep(SGTL5000_VAG_POWERUP_DELAY);
}

static int vag_power_consumers(struct snd_soc_component *component,
			       u16 ana_pwr_reg, u32 source)
{
	int consumers = 0;

	/* count dac/adc consumers unconditional */
	if (ana_pwr_reg & SGTL5000_DAC_POWERUP)
		consumers++;
	if (ana_pwr_reg & SGTL5000_ADC_POWERUP)
		consumers++;

	/*
	 * If the event comes from HP and Line-In is selected,
	 * current action is 'DAC to be powered down'.
	 * As HP_POWERUP is not set when HP muxed to line-in,
	 * we need to keep VAG power ON.
	 */
	if (source == HP_POWER_EVENT) {
		if (hp_sel_input(component) == SGTL5000_HP_SEL_LINE_IN)
			consumers++;
	} else {
		if (ana_pwr_reg & SGTL5000_HP_POWERUP)
			consumers++;
	}

	return consumers;
}

static void vag_power_off(struct snd_soc_component *component, u32 source)
{
	u16 ana_pwr = snd_soc_component_read(component,
					     SGTL5000_CHIP_ANA_POWER);

Annotation

Implementation Notes