Unverified Commit 8e8c533b authored by Tzung-Bi Shih's avatar Tzung-Bi Shih Committed by Mark Brown
Browse files

ASoC: mediatek: mt6358: support WoV

parent b6bc07d4
Loading
Loading
Loading
Loading
+105 −0
Original line number Diff line number Diff line
@@ -93,6 +93,8 @@ struct mt6358_priv {
	int mtkaif_protocol;

	struct regulator *avdd_reg;

	int wov_enabled;
};

int mt6358_set_mtkaif_protocol(struct snd_soc_component *cmpnt,
@@ -464,6 +466,106 @@ static int mt6358_put_volsw(struct snd_kcontrol *kcontrol,
	return ret;
}

static void mt6358_restore_pga(struct mt6358_priv *priv);

static int mt6358_enable_wov_phase2(struct mt6358_priv *priv)
{
	/* analog */
	regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON13,
			   0xffff, 0x0000);
	regmap_update_bits(priv->regmap, MT6358_DCXO_CW14, 0xffff, 0xa2b5);
	regmap_update_bits(priv->regmap, MT6358_AUDENC_ANA_CON1,
			   0xffff, 0x0800);
	mt6358_restore_pga(priv);

	regmap_update_bits(priv->regmap, MT6358_DCXO_CW13, 0xffff, 0x9929);
	regmap_update_bits(priv->regmap, MT6358_AUDENC_ANA_CON9,
			   0xffff, 0x0025);
	regmap_update_bits(priv->regmap, MT6358_AUDENC_ANA_CON8,
			   0xffff, 0x0005);

	/* digital */
	regmap_update_bits(priv->regmap, MT6358_AUD_TOP_CKPDN_CON0,
			   0xffff, 0x0000);
	regmap_update_bits(priv->regmap, MT6358_GPIO_MODE3, 0xffff, 0x0120);
	regmap_update_bits(priv->regmap, MT6358_AFE_VOW_CFG0, 0xffff, 0xffff);
	regmap_update_bits(priv->regmap, MT6358_AFE_VOW_CFG1, 0xffff, 0x0200);
	regmap_update_bits(priv->regmap, MT6358_AFE_VOW_CFG2, 0xffff, 0x2424);
	regmap_update_bits(priv->regmap, MT6358_AFE_VOW_CFG3, 0xffff, 0xdbac);
	regmap_update_bits(priv->regmap, MT6358_AFE_VOW_CFG4, 0xffff, 0x029e);
	regmap_update_bits(priv->regmap, MT6358_AFE_VOW_CFG5, 0xffff, 0x0000);
	regmap_update_bits(priv->regmap, MT6358_AFE_VOW_POSDIV_CFG0,
			   0xffff, 0x0000);
	regmap_update_bits(priv->regmap, MT6358_AFE_VOW_HPF_CFG0,
			   0xffff, 0x0451);
	regmap_update_bits(priv->regmap, MT6358_AFE_VOW_TOP, 0xffff, 0x68d1);

	return 0;
}

static int mt6358_disable_wov_phase2(struct mt6358_priv *priv)
{
	/* digital */
	regmap_update_bits(priv->regmap, MT6358_AFE_VOW_TOP, 0xffff, 0xc000);
	regmap_update_bits(priv->regmap, MT6358_AFE_VOW_HPF_CFG0,
			   0xffff, 0x0450);
	regmap_update_bits(priv->regmap, MT6358_AFE_VOW_POSDIV_CFG0,
			   0xffff, 0x0c00);
	regmap_update_bits(priv->regmap, MT6358_AFE_VOW_CFG5, 0xffff, 0x0100);
	regmap_update_bits(priv->regmap, MT6358_AFE_VOW_CFG4, 0xffff, 0x006c);
	regmap_update_bits(priv->regmap, MT6358_AFE_VOW_CFG3, 0xffff, 0xa879);
	regmap_update_bits(priv->regmap, MT6358_AFE_VOW_CFG2, 0xffff, 0x2323);
	regmap_update_bits(priv->regmap, MT6358_AFE_VOW_CFG1, 0xffff, 0x0400);
	regmap_update_bits(priv->regmap, MT6358_AFE_VOW_CFG0, 0xffff, 0x0000);
	regmap_update_bits(priv->regmap, MT6358_GPIO_MODE3, 0xffff, 0x02d8);
	regmap_update_bits(priv->regmap, MT6358_AUD_TOP_CKPDN_CON0,
			   0xffff, 0x0000);

	/* analog */
	regmap_update_bits(priv->regmap, MT6358_AUDENC_ANA_CON8,
			   0xffff, 0x0004);
	regmap_update_bits(priv->regmap, MT6358_AUDENC_ANA_CON9,
			   0xffff, 0x0000);
	regmap_update_bits(priv->regmap, MT6358_DCXO_CW13, 0xffff, 0x9829);
	regmap_update_bits(priv->regmap, MT6358_AUDENC_ANA_CON1,
			   0xffff, 0x0000);
	mt6358_restore_pga(priv);
	regmap_update_bits(priv->regmap, MT6358_DCXO_CW14, 0xffff, 0xa2b5);
	regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON13,
			   0xffff, 0x0010);

	return 0;
}

static int mt6358_get_wov(struct snd_kcontrol *kcontrol,
			  struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *c = snd_soc_kcontrol_component(kcontrol);
	struct mt6358_priv *priv = snd_soc_component_get_drvdata(c);

	ucontrol->value.integer.value[0] = priv->wov_enabled;
	return 0;
}

static int mt6358_put_wov(struct snd_kcontrol *kcontrol,
			  struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *c = snd_soc_kcontrol_component(kcontrol);
	struct mt6358_priv *priv = snd_soc_component_get_drvdata(c);
	int enabled = ucontrol->value.integer.value[0];

	if (priv->wov_enabled != enabled) {
		if (enabled)
			mt6358_enable_wov_phase2(priv);
		else
			mt6358_disable_wov_phase2(priv);

		priv->wov_enabled = enabled;
	}

	return 0;
}

static const DECLARE_TLV_DB_SCALE(playback_tlv, -1000, 100, 0);
static const DECLARE_TLV_DB_SCALE(pga_tlv, 0, 600, 0);

@@ -483,6 +585,9 @@ static const struct snd_kcontrol_new mt6358_snd_controls[] = {
			     MT6358_AUDENC_ANA_CON0, MT6358_AUDENC_ANA_CON1,
			     8, 4, 0,
			     snd_soc_get_volsw, mt6358_put_volsw, pga_tlv),

	SOC_SINGLE_BOOL_EXT("Wake-on-Voice Phase2 Switch", 0,
			    mt6358_get_wov, mt6358_put_wov),
};

/* MUX */