sound/soc/codecs/uda1334.c

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

File Facts

System
Linux kernel
Corpus path
sound/soc/codecs/uda1334.c
Extension
.c
Size
7623 bytes
Lines
295
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 uda1334_priv {
	struct gpio_desc *mute;
	struct gpio_desc *deemph;
	unsigned int sysclk;
	unsigned int rate_constraint_list[UDA1334_NUM_RATES];
	struct snd_pcm_hw_constraint_list rate_constraint;
};

static const struct snd_soc_dapm_widget uda1334_dapm_widgets[] = {
SND_SOC_DAPM_DAC("DAC", "Playback", SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_OUTPUT("LINEVOUTL"),
SND_SOC_DAPM_OUTPUT("LINEVOUTR"),
};

static const struct snd_soc_dapm_route uda1334_dapm_routes[] = {
	{ "LINEVOUTL", NULL, "DAC" },
	{ "LINEVOUTR", NULL, "DAC" },
};

static int uda1334_put_deemph(struct snd_kcontrol *kcontrol,
			      struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
	struct uda1334_priv *uda1334 = snd_soc_component_get_drvdata(component);
	int deemph = ucontrol->value.integer.value[0];

	if (deemph > 1)
		return -EINVAL;

	gpiod_set_value_cansleep(uda1334->deemph, deemph);

	return 0;
};

static int uda1334_get_deemph(struct snd_kcontrol *kcontrol,
			      struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
	struct uda1334_priv *uda1334 = snd_soc_component_get_drvdata(component);
	int ret;

	ret = gpiod_get_value_cansleep(uda1334->deemph);
	if (ret < 0)
		return -EINVAL;

	ucontrol->value.integer.value[0] = ret;

	return 0;
};

static const struct snd_kcontrol_new uda1334_snd_controls[] = {
	SOC_SINGLE_BOOL_EXT("Playback Deemphasis Switch", 0,
			    uda1334_get_deemph, uda1334_put_deemph),
};

static const struct {
	int value;
	int ratio;
} lrclk_ratios[UDA1334_NUM_RATES] = {
	{ 1, 128 },
	{ 2, 192 },
	{ 3, 256 },
	{ 4, 384 },
	{ 5, 512 },
	{ 6, 768 },
};

static int uda1334_startup(struct snd_pcm_substream *substream,
			   struct snd_soc_dai *dai)
{
	struct snd_soc_component *component = dai->component;
	struct uda1334_priv *uda1334 = snd_soc_component_get_drvdata(component);

	/*
	 * The set of sample rates that can be supported depends on the
	 * MCLK supplied to the CODEC - enforce this.
	 */
	if (!uda1334->sysclk) {
		dev_err(component->dev,
			"No MCLK configured, call set_sysclk() on init\n");
		return -EINVAL;
	}

	snd_pcm_hw_constraint_list(substream->runtime, 0,
				   SNDRV_PCM_HW_PARAM_RATE,
				   &uda1334->rate_constraint);

	gpiod_set_value_cansleep(uda1334->mute, 1);

	return 0;

Annotation

Implementation Notes