sound/soc/codecs/cpcap.c

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

File Facts

System
Linux kernel
Corpus path
sound/soc/codecs/cpcap.c
Extension
.c
Size
57425 bytes
Lines
1885
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 cpcap_reg_info {
	u16 reg;
	u16 mask;
	u16 val;
};

static const struct cpcap_reg_info cpcap_default_regs[] = {
	{ CPCAP_REG_VAUDIOC, 0x003F, 0x0000 },
	{ CPCAP_REG_CC, 0xFFFF, 0x0000 },
	{ CPCAP_REG_CC, 0xFFFF, 0x0000 },
	{ CPCAP_REG_CDI, 0xBFFF, 0x0000 },
	{ CPCAP_REG_SDAC, 0x0FFF, 0x0000 },
	{ CPCAP_REG_SDACDI, 0x3FFF, 0x0000 },
	{ CPCAP_REG_TXI, 0x0FDF, 0x0000 },
	{ CPCAP_REG_TXMP, 0x0FFF, 0x0400 },
	{ CPCAP_REG_RXOA, 0x01FF, 0x0000 },
	{ CPCAP_REG_RXVC, 0xFF3C, 0x0000 },
	{ CPCAP_REG_RXCOA, 0x07FF, 0x0000 },
	{ CPCAP_REG_RXSDOA, 0x1FFF, 0x0000 },
	{ CPCAP_REG_RXEPOA, 0x7FFF, 0x0000 },
	{ CPCAP_REG_A2LA, BIT(CPCAP_BIT_A2_FREE_RUN),
	  BIT(CPCAP_BIT_A2_FREE_RUN) },
};

enum cpcap_dai {
	CPCAP_DAI_HIFI,
	CPCAP_DAI_VOICE,
};

struct cpcap_audio {
	struct snd_soc_component *component;
	struct regmap *regmap;

	u16 vendor;

	int codec_clk_id;
	int codec_freq;
	int codec_format;
	struct regulator *vaudio;
	int hsirq;
	int mb2irq;
	struct snd_soc_jack jack;
};

static int cpcap_st_workaround(struct snd_soc_dapm_widget *w,
			       struct snd_kcontrol *kcontrol, int event)
{
	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
	struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
	int err = 0;

	/* Only CPCAP from ST requires workaround */
	if (cpcap->vendor != CPCAP_VENDOR_ST)
		return 0;

	switch (event) {
	case SND_SOC_DAPM_PRE_PMU:
		err = regmap_write(cpcap->regmap, CPCAP_REG_TEST,
				   STM_STDAC_EN_TEST_PRE);
		if (err)
			return err;
		err = regmap_write(cpcap->regmap, CPCAP_REG_ST_TEST1,
				   STM_STDAC_EN_ST_TEST1_PRE);
		break;
	case SND_SOC_DAPM_POST_PMU:
		msleep(STM_STDAC_ACTIVATE_RAMP_TIME);

		err = regmap_write(cpcap->regmap, CPCAP_REG_ST_TEST1,
				   STM_STDAC_EN_ST_TEST1_POST);
		if (err)
			return err;
		err = regmap_write(cpcap->regmap, CPCAP_REG_TEST,
				   STM_STDAC_EN_TEST_POST);
		break;
	default:
		break;
	}

	return err;
}

/* Capture Gain Control: 0dB to 31dB in 1dB steps */
static const DECLARE_TLV_DB_SCALE(mic_gain_tlv, 0, 100, 0);

/* Playback Gain Control: -33dB to 12dB in 3dB steps */
static const DECLARE_TLV_DB_SCALE(vol_tlv, -3300, 300, 0);

static const struct snd_kcontrol_new cpcap_snd_controls[] = {
	/* Playback Gain */
	SOC_SINGLE_TLV("HiFi Playback Volume",

Annotation

Implementation Notes