sound/soc/codecs/bd28623.c

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

File Facts

System
Linux kernel
Corpus path
sound/soc/codecs/bd28623.c
Extension
.c
Size
5961 bytes
Lines
240
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 bd28623_priv {
	struct device *dev;
	struct regulator_bulk_data supplies[BD28623_NUM_SUPPLIES];
	struct gpio_desc *reset_gpio;
	struct gpio_desc *mute_gpio;

	int switch_spk;
};

static const struct snd_soc_dapm_widget bd28623_widgets[] = {
	SND_SOC_DAPM_DAC("DAC", "Playback", SND_SOC_NOPM, 0, 0),
	SND_SOC_DAPM_OUTPUT("OUT1P"),
	SND_SOC_DAPM_OUTPUT("OUT1N"),
	SND_SOC_DAPM_OUTPUT("OUT2P"),
	SND_SOC_DAPM_OUTPUT("OUT2N"),
};

static const struct snd_soc_dapm_route bd28623_routes[] = {
	{ "OUT1P", NULL, "DAC" },
	{ "OUT1N", NULL, "DAC" },
	{ "OUT2P", NULL, "DAC" },
	{ "OUT2N", NULL, "DAC" },
};

static int bd28623_power_on(struct bd28623_priv *bd)
{
	int ret;

	ret = regulator_bulk_enable(ARRAY_SIZE(bd->supplies), bd->supplies);
	if (ret) {
		dev_err(bd->dev, "Failed to enable supplies: %d\n", ret);
		return ret;
	}

	gpiod_set_value_cansleep(bd->reset_gpio, 0);
	usleep_range(300000, 400000);

	return 0;
}

static void bd28623_power_off(struct bd28623_priv *bd)
{
	gpiod_set_value_cansleep(bd->reset_gpio, 1);

	regulator_bulk_disable(ARRAY_SIZE(bd->supplies), bd->supplies);
}

static int bd28623_get_switch_spk(struct snd_kcontrol *kcontrol,
				  struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
	struct bd28623_priv *bd = snd_soc_component_get_drvdata(component);

	ucontrol->value.integer.value[0] = bd->switch_spk;

	return 0;
}

static int bd28623_set_switch_spk(struct snd_kcontrol *kcontrol,
				  struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
	struct bd28623_priv *bd = snd_soc_component_get_drvdata(component);

	if (bd->switch_spk == ucontrol->value.integer.value[0])
		return 0;

	bd->switch_spk = ucontrol->value.integer.value[0];

	gpiod_set_value_cansleep(bd->mute_gpio, bd->switch_spk ? 0 : 1);

	return 0;
}

static const struct snd_kcontrol_new bd28623_controls[] = {
	SOC_SINGLE_BOOL_EXT("Speaker Switch", 0,
			    bd28623_get_switch_spk, bd28623_set_switch_spk),
};

static int bd28623_codec_probe(struct snd_soc_component *component)
{
	struct bd28623_priv *bd = snd_soc_component_get_drvdata(component);
	int ret;

	bd->switch_spk = 1;

	ret = bd28623_power_on(bd);
	if (ret)
		return ret;

Annotation

Implementation Notes