sound/soc/codecs/max98925.c

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

File Facts

System
Linux kernel
Corpus path
sound/soc/codecs/max98925.c
Extension
.c
Size
18429 bytes
Lines
647
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 (rate_table[i].rate >= rate) {
			*value = rate_table[i].sr;
			*n = rate_table[i].divisors[clock][0];
			*m = rate_table[i].divisors[clock][1];
			ret = 0;
			break;
		}
	}
	return ret;
}

static void max98925_set_sense_data(struct max98925_priv *max98925)
{
	/* set VMON slots */
	regmap_update_bits(max98925->regmap,
		MAX98925_DOUT_CFG_VMON,
		M98925_DAI_VMON_EN_MASK, M98925_DAI_VMON_EN_MASK);
	regmap_update_bits(max98925->regmap,
		MAX98925_DOUT_CFG_VMON,
		M98925_DAI_VMON_SLOT_MASK,
		max98925->v_slot << M98925_DAI_VMON_SLOT_SHIFT);
	/* set IMON slots */
	regmap_update_bits(max98925->regmap,
		MAX98925_DOUT_CFG_IMON,
		M98925_DAI_IMON_EN_MASK, M98925_DAI_IMON_EN_MASK);
	regmap_update_bits(max98925->regmap,
		MAX98925_DOUT_CFG_IMON,
		M98925_DAI_IMON_SLOT_MASK,
		max98925->i_slot << M98925_DAI_IMON_SLOT_SHIFT);
}

static int max98925_dai_set_fmt(struct snd_soc_dai *codec_dai,
				 unsigned int fmt)
{
	struct snd_soc_component *component = codec_dai->component;
	struct max98925_priv *max98925 = snd_soc_component_get_drvdata(component);
	unsigned int invert = 0;

	dev_dbg(component->dev, "%s: fmt 0x%08X\n", __func__, fmt);
	switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
	case SND_SOC_DAIFMT_CBC_CFC:
		regmap_update_bits(max98925->regmap,
			MAX98925_DAI_CLK_MODE2,
			M98925_DAI_MAS_MASK, 0);
		max98925_set_sense_data(max98925);
		break;
	case SND_SOC_DAIFMT_CBP_CFP:
		/*
		 * set left channel DAI to provider mode,
		 * right channel always consumer
		 */
		regmap_update_bits(max98925->regmap,
			MAX98925_DAI_CLK_MODE2,
			M98925_DAI_MAS_MASK, M98925_DAI_MAS_MASK);
		break;
	default:
		dev_err(component->dev, "DAI clock mode unsupported");
		return -EINVAL;
	}

	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
	case SND_SOC_DAIFMT_NB_NF:
		break;
	case SND_SOC_DAIFMT_NB_IF:
		invert = M98925_DAI_WCI_MASK;
		break;
	case SND_SOC_DAIFMT_IB_NF:
		invert = M98925_DAI_BCI_MASK;
		break;
	case SND_SOC_DAIFMT_IB_IF:
		invert = M98925_DAI_BCI_MASK | M98925_DAI_WCI_MASK;
		break;
	default:
		dev_err(component->dev, "DAI invert mode unsupported");
		return -EINVAL;
	}

	regmap_update_bits(max98925->regmap, MAX98925_FORMAT,
			M98925_DAI_BCI_MASK | M98925_DAI_WCI_MASK, invert);
	return 0;
}

static int max98925_set_clock(struct max98925_priv *max98925,
		struct snd_pcm_hw_params *params)
{
	unsigned int dai_sr = 0, clock, mdll, n, m;
	struct snd_soc_component *component = max98925->component;
	int rate = params_rate(params);
	/* BCLK/LRCLK ratio calculation */
	int blr_clk_ratio = params_channels(params) * max98925->ch_size;

Annotation

Implementation Notes