sound/soc/codecs/rt9123.c

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

File Facts

System
Linux kernel
Corpus path
sound/soc/codecs/rt9123.c
Extension
.c
Size
13683 bytes
Lines
501
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 rt9123_priv {
	struct gpio_desc *enable;
	unsigned int dai_fmt;
	int tdm_slots;
	int tdm_slot_width;
};

static int rt9123_enable_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
			       int event)
{
	struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
	struct device *dev = comp->dev;
	unsigned int enable;
	int ret;

	switch (event) {
	case SND_SOC_DAPM_POST_PMU:
		enable = 1;
		break;
	case SND_SOC_DAPM_POST_PMD:
		enable = 0;
		break;
	default:
		return -EINVAL;
	}

	ret = pm_runtime_resume_and_get(dev);
	if (ret)
		return ret;

	/* AMPON bit is located in volatile RG, use pm_runtime to guarantee the RG access */
	snd_soc_component_write_field(comp, RT9123_REG_AMPCTRL, RT9123_MASK_AMPON, enable);

	pm_runtime_put_autosuspend(dev);

	return 0;
}

static const struct snd_soc_dapm_widget rt9123_dapm_widgets[] = {
	SND_SOC_DAPM_OUTPUT("SPK"),
	SND_SOC_DAPM_OUT_DRV_E("Amp Drv", SND_SOC_NOPM, 0, 0, NULL, 0, rt9123_enable_event,
			       SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
};

static const struct snd_soc_dapm_route rt9123_dapm_routes[] = {
	{ "Amp Drv", NULL, "HiFi Playback" },
	{ "SPK", NULL, "Amp Drv" },
};

static const DECLARE_TLV_DB_SCALE(dig_tlv, -10375, 25, 0);
static const DECLARE_TLV_DB_RANGE(ana_tlv,
				  0, 0, TLV_DB_SCALE_ITEM(-1200, 0, 0),
				  1, 9, TLV_DB_SCALE_ITEM(0, 150, 0),
				  10, 10, TLV_DB_SCALE_ITEM(1400, 0, 0));
static const char * const pwmfreq_text[] = { "300KHz", "325KHz", "350KHz", "375KHz" };
static const struct soc_enum rt9123_pwm_freq_enum =
	SOC_ENUM_SINGLE(RT9123_REG_AMPCTRL, 4, ARRAY_SIZE(pwmfreq_text), pwmfreq_text);
static const char * const i2sch_text[] = { "(L+R)/2", "LCH", "RCH", "(L+R)/2" };
static const struct soc_enum rt9123_i2sch_select_enum =
	SOC_ENUM_SINGLE(RT9123_REG_I2SOPT, 4, ARRAY_SIZE(i2sch_text), i2sch_text);

static int rt9123_kcontrol_name_comp(struct snd_kcontrol *kcontrol, const char *s)
{
	struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
	const char *kctlname = kcontrol->id.name;

	if (comp && comp->name_prefix)
		kctlname += strlen(comp->name_prefix) + 1;

	return strcmp(kctlname, s);
}

static int rt9123_xhandler_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
	struct device *dev = comp->dev;
	int ret;

	ret = pm_runtime_resume_and_get(dev);
	if (ret)
		return ret;

	/*
	 * Since the RG bitfield for 'Speaker Volume' and 'PWM Frequency Select' are located in
	 * volatile RG address, special handling here with pm runtime API to guarantee RG read
	 * operation.
	 */
	if (rt9123_kcontrol_name_comp(kcontrol, "Speaker Volume") == 0)
		ret = snd_soc_get_volsw(kcontrol, ucontrol);
	else

Annotation

Implementation Notes