sound/soc/codecs/max98388.c

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

File Facts

System
Linux kernel
Corpus path
sound/soc/codecs/max98388.c
Extension
.c
Size
31727 bytes
Lines
1014
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 (!ret) {
			dev_info(dev, "Reset completed (retry:%d)\n", count);
			return;
		}
		count++;
	}
	dev_err(dev, "Reset failed. (ret:%d)\n", ret);
}

static int max98388_probe(struct snd_soc_component *component)
{
	struct max98388_priv *max98388 = snd_soc_component_get_drvdata(component);

	/* Software Reset */
	max98388_reset(max98388, component->dev);

	/* General channel source configuration */
	regmap_write(max98388->regmap,
		     MAX98388_R2059_PCM_RX_SRC2,
		     0x10);

	/* Enable DC blocker */
	regmap_write(max98388->regmap,
		     MAX98388_R2091_SPK_CH_CFG,
		     0x1);
	/* Enable IMON VMON DC blocker */
	regmap_write(max98388->regmap,
		     MAX98388_R20A0_IV_DATA_DSP_CTRL,
		     0x3);
	/* TX slot configuration */
	regmap_write(max98388->regmap,
		     MAX98388_R2044_PCM_TX_CTRL1,
		     max98388->v_slot);

	regmap_write(max98388->regmap,
		     MAX98388_R2045_PCM_TX_CTRL2,
		     max98388->i_slot);
	/* Enable Auto-restart behavior by default */
	regmap_write(max98388->regmap,
		     MAX98388_R210E_AUTO_RESTART, 0xF);
	/* Set interleave mode */
	if (max98388->interleave_mode)
		regmap_update_bits(max98388->regmap,
				   MAX98388_R2040_PCM_MODE_CFG,
				   MAX98388_PCM_TX_CH_INTERLEAVE_MASK,
				   MAX98388_PCM_TX_CH_INTERLEAVE_MASK);

	/* Speaker Amplifier Channel Enable */
	regmap_update_bits(max98388->regmap,
			   MAX98388_R209F_SPK_CH_AMP_EN,
			   MAX98388_SPK_EN_MASK, 1);

	return 0;
}

static int max98388_dai_set_fmt(struct snd_soc_dai *codec_dai,
				unsigned int fmt)
{
	struct snd_soc_component *component = codec_dai->component;
	struct max98388_priv *max98388 = snd_soc_component_get_drvdata(component);
	unsigned int format = 0;
	unsigned int invert = 0;

	dev_dbg(component->dev, "%s: fmt 0x%08X\n", __func__, fmt);

	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
	case SND_SOC_DAIFMT_NB_NF:
		break;
	case SND_SOC_DAIFMT_IB_NF:
		invert = MAX98388_PCM_MODE_CFG_PCM_BCLKEDGE;
		break;
	default:
		dev_err(component->dev, "DAI invert mode unsupported\n");
		return -EINVAL;
	}

	regmap_update_bits(max98388->regmap,
			   MAX98388_R2041_PCM_CLK_SETUP,
			   MAX98388_PCM_MODE_CFG_PCM_BCLKEDGE,
			   invert);

	/* interface format */
	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
	case SND_SOC_DAIFMT_I2S:
		format = MAX98388_PCM_FORMAT_I2S;
		break;
	case SND_SOC_DAIFMT_LEFT_J:
		format = MAX98388_PCM_FORMAT_LJ;
		break;
	case SND_SOC_DAIFMT_DSP_A:

Annotation

Implementation Notes