sound/soc/codecs/max9759.c

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

File Facts

System
Linux kernel
Corpus path
sound/soc/codecs/max9759.c
Extension
.c
Size
5440 bytes
Lines
199
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 max9759 {
	struct gpio_desc *gpiod_shutdown;
	struct gpio_desc *gpiod_mute;
	struct gpio_descs *gpiod_gain;
	bool is_mute;
	unsigned int gain;
};

static int pga_event(struct snd_soc_dapm_widget *w,
		     struct snd_kcontrol *control, int event)
{
	struct snd_soc_component *c = snd_soc_dapm_to_component(w->dapm);
	struct max9759 *priv = snd_soc_component_get_drvdata(c);

	if (SND_SOC_DAPM_EVENT_ON(event))
		gpiod_set_value_cansleep(priv->gpiod_shutdown, 0);
	else
		gpiod_set_value_cansleep(priv->gpiod_shutdown, 1);

	return 0;
}

/* From 6dB to 24dB in steps of 6dB */
static const DECLARE_TLV_DB_SCALE(speaker_gain_tlv, 600, 600, 0);

static int speaker_gain_control_get(struct snd_kcontrol *kcontrol,
				    struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *c = snd_kcontrol_chip(kcontrol);
	struct max9759 *priv = snd_soc_component_get_drvdata(c);

	ucontrol->value.integer.value[0] = priv->gain;

	return 0;
}

static const bool speaker_gain_table[4][2] = {
	/* G1, G2 */
	{true, true},	/* +6dB */
	{false, true},	/* +12dB */
	{true, false},	/* +18dB */
	{false, false},	/* +24dB */
};

static int speaker_gain_control_put(struct snd_kcontrol *kcontrol,
				    struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *c = snd_kcontrol_chip(kcontrol);
	struct max9759 *priv = snd_soc_component_get_drvdata(c);

	if (ucontrol->value.integer.value[0] < 0 ||
	    ucontrol->value.integer.value[0] > 3)
		return -EINVAL;

	priv->gain = ucontrol->value.integer.value[0];

	/* G1 */
	gpiod_set_value_cansleep(priv->gpiod_gain->desc[0],
				 speaker_gain_table[priv->gain][0]);
	/* G2 */
	gpiod_set_value_cansleep(priv->gpiod_gain->desc[1],
				 speaker_gain_table[priv->gain][1]);

	return 1;
}

static int speaker_mute_get(struct snd_kcontrol *kcontrol,
			    struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *c = snd_kcontrol_chip(kcontrol);
	struct max9759 *priv = snd_soc_component_get_drvdata(c);

	ucontrol->value.integer.value[0] = !priv->is_mute;

	return 0;
}

static int speaker_mute_put(struct snd_kcontrol *kcontrol,
			    struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *c = snd_kcontrol_chip(kcontrol);
	struct max9759 *priv = snd_soc_component_get_drvdata(c);

	priv->is_mute = !ucontrol->value.integer.value[0];

	gpiod_set_value_cansleep(priv->gpiod_mute, priv->is_mute);

	return 1;
}

Annotation

Implementation Notes