sound/soc/codecs/cs4271.c

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

File Facts

System
Linux kernel
Corpus path
sound/soc/codecs/cs4271.c
Extension
.c
Size
21150 bytes
Lines
732
Domain
Driver Families
Bucket
sound/soc
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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 cs4271_private {
	unsigned int			mclk;
	bool				master;
	bool				deemph;
	struct regmap			*regmap;
	/* Current sample rate for de-emphasis control */
	int				rate;
	/* GPIO driving Reset pin, if any */
	struct gpio_desc		*reset;
	/* enable soft reset workaround */
	bool				enable_soft_reset;
	struct regulator_bulk_data      supplies[ARRAY_SIZE(supply_names)];
	struct clk *clk;
};

static const struct snd_soc_dapm_widget cs4271_dapm_widgets[] = {
SND_SOC_DAPM_INPUT("AINA"),
SND_SOC_DAPM_INPUT("AINB"),

SND_SOC_DAPM_OUTPUT("AOUTA+"),
SND_SOC_DAPM_OUTPUT("AOUTA-"),
SND_SOC_DAPM_OUTPUT("AOUTB+"),
SND_SOC_DAPM_OUTPUT("AOUTB-"),
};

static const struct snd_soc_dapm_route cs4271_dapm_routes[] = {
	{ "Capture", NULL, "AINA" },
	{ "Capture", NULL, "AINB" },

	{ "AOUTA+", NULL, "Playback" },
	{ "AOUTA-", NULL, "Playback" },
	{ "AOUTB+", NULL, "Playback" },
	{ "AOUTB-", NULL, "Playback" },
};

/*
 * @freq is the desired MCLK rate
 * MCLK rate should (c) be the sample rate, multiplied by one of the
 * ratios listed in cs4271_mclk_fs_ratios table
 */
static int cs4271_set_dai_sysclk(struct snd_soc_dai *codec_dai,
				 int clk_id, unsigned int freq, int dir)
{
	struct snd_soc_component *component = codec_dai->component;
	struct cs4271_private *cs4271 = snd_soc_component_get_drvdata(component);

	cs4271->mclk = freq;
	return 0;
}

static int cs4271_set_dai_fmt(struct snd_soc_dai *codec_dai,
			      unsigned int format)
{
	struct snd_soc_component *component = codec_dai->component;
	struct cs4271_private *cs4271 = snd_soc_component_get_drvdata(component);
	unsigned int val = 0;
	int ret;

	switch (format & SND_SOC_DAIFMT_MASTER_MASK) {
	case SND_SOC_DAIFMT_CBC_CFC:
		cs4271->master = false;
		break;
	case SND_SOC_DAIFMT_CBP_CFP:
		cs4271->master = true;
		val |= CS4271_MODE1_MASTER;
		break;
	default:
		dev_err(component->dev, "Invalid DAI format\n");
		return -EINVAL;
	}

	switch (format & SND_SOC_DAIFMT_FORMAT_MASK) {
	case SND_SOC_DAIFMT_LEFT_J:
		val |= CS4271_MODE1_DAC_DIF_LJ;
		ret = regmap_update_bits(cs4271->regmap, CS4271_ADCCTL,
			CS4271_ADCCTL_ADC_DIF_MASK, CS4271_ADCCTL_ADC_DIF_LJ);
		if (ret < 0)
			return ret;
		break;
	case SND_SOC_DAIFMT_I2S:
		val |= CS4271_MODE1_DAC_DIF_I2S;
		ret = regmap_update_bits(cs4271->regmap, CS4271_ADCCTL,
			CS4271_ADCCTL_ADC_DIF_MASK, CS4271_ADCCTL_ADC_DIF_I2S);
		if (ret < 0)
			return ret;
		break;
	default:
		dev_err(component->dev, "Invalid DAI format\n");
		return -EINVAL;
	}

Annotation

Implementation Notes