sound/soc/codecs/inno_rk3036.c

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

File Facts

System
Linux kernel
Corpus path
sound/soc/codecs/inno_rk3036.c
Extension
.c
Size
14215 bytes
Lines
487
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 rk3036_codec_priv {
	void __iomem *base;
	struct clk *pclk;
	struct regmap *regmap;
	struct device *dev;
};

static const DECLARE_TLV_DB_MINMAX(rk3036_codec_hp_tlv, -39, 0);

static int rk3036_codec_antipop_info(struct snd_kcontrol *kcontrol,
				     struct snd_ctl_elem_info *uinfo)
{
	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
	uinfo->count = 2;
	uinfo->value.integer.min = 0;
	uinfo->value.integer.max = 1;

	return 0;
}

static int rk3036_codec_antipop_get(struct snd_kcontrol *kcontrol,
				    struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
	int val, regval;

	regval = snd_soc_component_read(component, INNO_R09);
	val = ((regval >> INNO_R09_HPL_ANITPOP_SHIFT) &
	       INNO_R09_HP_ANTIPOP_MSK) == INNO_R09_HP_ANTIPOP_ON;
	ucontrol->value.integer.value[0] = val;

	val = ((regval >> INNO_R09_HPR_ANITPOP_SHIFT) &
	       INNO_R09_HP_ANTIPOP_MSK) == INNO_R09_HP_ANTIPOP_ON;
	ucontrol->value.integer.value[1] = val;

	return 0;
}

static int rk3036_codec_antipop_put(struct snd_kcontrol *kcontrol,
				    struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
	int val, ret, regmsk;

	val = (ucontrol->value.integer.value[0] ?
	       INNO_R09_HP_ANTIPOP_ON : INNO_R09_HP_ANTIPOP_OFF) <<
	      INNO_R09_HPL_ANITPOP_SHIFT;
	val |= (ucontrol->value.integer.value[1] ?
		INNO_R09_HP_ANTIPOP_ON : INNO_R09_HP_ANTIPOP_OFF) <<
	       INNO_R09_HPR_ANITPOP_SHIFT;

	regmsk = INNO_R09_HP_ANTIPOP_MSK << INNO_R09_HPL_ANITPOP_SHIFT |
		 INNO_R09_HP_ANTIPOP_MSK << INNO_R09_HPR_ANITPOP_SHIFT;

	ret = snd_soc_component_update_bits(component, INNO_R09,
					    regmsk, val);
	if (ret < 0)
		return ret;

	return 0;
}

#define SOC_RK3036_CODEC_ANTIPOP_DECL(xname) \
{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
	.info = rk3036_codec_antipop_info, .get = rk3036_codec_antipop_get, \
	.put = rk3036_codec_antipop_put, }

static const struct snd_kcontrol_new rk3036_codec_dapm_controls[] = {
	SOC_DOUBLE_R_RANGE_TLV("Headphone Volume", INNO_R07, INNO_R08,
		INNO_HP_GAIN_SHIFT, INNO_HP_GAIN_N39DB,
		INNO_HP_GAIN_0DB, 0, rk3036_codec_hp_tlv),
	SOC_DOUBLE("Zero Cross Switch", INNO_R06, INNO_R06_VOUTL_CZ_SHIFT,
		INNO_R06_VOUTR_CZ_SHIFT, 1, 0),
	SOC_DOUBLE("Headphone Switch", INNO_R09, INNO_R09_HPL_MUTE_SHIFT,
		INNO_R09_HPR_MUTE_SHIFT, 1, 0),
	SOC_RK3036_CODEC_ANTIPOP_DECL("Anti-pop Switch"),
};

static const struct snd_kcontrol_new rk3036_codec_hpl_mixer_controls[] = {
	SOC_DAPM_SINGLE("DAC Left Out Switch", INNO_R09,
			INNO_R09_DACL_SWITCH_SHIFT, 1, 0),
};

static const struct snd_kcontrol_new rk3036_codec_hpr_mixer_controls[] = {
	SOC_DAPM_SINGLE("DAC Right Out Switch", INNO_R09,
			INNO_R09_DACR_SWITCH_SHIFT, 1, 0),
};

static const struct snd_kcontrol_new rk3036_codec_hpl_switch_controls[] = {
	SOC_DAPM_SINGLE("HP Left Out Switch", INNO_R05,

Annotation

Implementation Notes