示例#1
0
static int tas6424_dac_event(struct snd_soc_dapm_widget *w,
			     struct snd_kcontrol *kcontrol, int event)
{
	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
	struct tas6424_data *tas6424 = snd_soc_codec_get_drvdata(codec);

	dev_dbg(codec->dev, "%s() event=0x%0x\n", __func__, event);

	if (event & SND_SOC_DAPM_POST_PMU) {
		/* Observe codec shutdown-to-active time */
		msleep(12);

		/* Turn on TAS6424 periodic fault checking/handling */
		tas6424->last_fault1 = 0;
		tas6424->last_fault2 = 0;
		tas6424->last_warn = 0;
		schedule_delayed_work(&tas6424->fault_check_work,
				      msecs_to_jiffies(TAS6424_FAULT_CHECK_INTERVAL));
	} else if (event & SND_SOC_DAPM_PRE_PMD) {
		/* Disable TAS6424 periodic fault checking/handling */
		cancel_delayed_work_sync(&tas6424->fault_check_work);
	}

	return 0;
}
示例#2
0
文件: wm8997.c 项目: 513855417/linux
static int wm8997_sysclk_ev(struct snd_soc_dapm_widget *w,
			    struct snd_kcontrol *kcontrol, int event)
{
	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
	struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
	struct regmap *regmap = arizona->regmap;
	const struct reg_default *patch = NULL;
	int i, patch_size;

	switch (arizona->rev) {
	case 0:
		patch = wm8997_sysclk_reva_patch;
		patch_size = ARRAY_SIZE(wm8997_sysclk_reva_patch);
		break;
	default:
		break;
	}

	switch (event) {
	case SND_SOC_DAPM_POST_PMU:
		if (patch)
			for (i = 0; i < patch_size; i++)
				regmap_write_async(regmap, patch[i].reg,
						   patch[i].def);
		break;
	case SND_SOC_DAPM_PRE_PMD:
		break;
	default:
		return 0;
	}

	return arizona_dvfs_sysclk_ev(w, kcontrol, event);
}
示例#3
0
static int cs35l33_spkrdrv_event(struct snd_soc_dapm_widget *w,
	struct snd_kcontrol *kcontrol, int event)
{
	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
	struct cs35l33_private *priv = snd_soc_codec_get_drvdata(codec);

	switch (event) {
	case SND_SOC_DAPM_POST_PMU:
		if (!priv->amp_cal) {
			usleep_range(8000, 9000);
			priv->amp_cal = true;
			regmap_update_bits(priv->regmap, CS35L33_CLASSD_CTL,
				    CS35L33_AMP_CAL, 0);
			dev_dbg(codec->dev, "Amp calibration done\n");
		}
		dev_dbg(codec->dev, "Amp turned on\n");
		break;
	case SND_SOC_DAPM_POST_PMD:
		dev_dbg(codec->dev, "Amp turned off\n");
		break;
	default:
		dev_err(codec->dev, "Invalid event = 0x%x\n", event);
		break;
	}

	return 0;
}
示例#4
0
static int cs35l34_sdin_event(struct snd_soc_dapm_widget *w,
		struct snd_kcontrol *kcontrol, int event)
{
	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
	struct cs35l34_private *priv = snd_soc_codec_get_drvdata(codec);
	int ret;

	switch (event) {
	case SND_SOC_DAPM_PRE_PMU:
		if (priv->tdm_mode)
			regmap_update_bits(priv->regmap, CS35L34_PWRCTL3,
						CS35L34_PDN_TDM, 0x00);

		ret = regmap_update_bits(priv->regmap, CS35L34_PWRCTL1,
						CS35L34_PDN_ALL, 0);
		if (ret < 0) {
			dev_err(codec->dev, "Cannot set Power bits %d\n", ret);
			return ret;
		}
		usleep_range(5000, 5100);
	break;
	case SND_SOC_DAPM_POST_PMD:
		if (priv->tdm_mode) {
			regmap_update_bits(priv->regmap, CS35L34_PWRCTL3,
					CS35L34_PDN_TDM, CS35L34_PDN_TDM);
		}
		ret = regmap_update_bits(priv->regmap, CS35L34_PWRCTL1,
					CS35L34_PDN_ALL, CS35L34_PDN_ALL);
	break;
	default:
		pr_err("Invalid event = 0x%x\n", event);
	}
	return 0;
}
示例#5
0
static int cs35l34_main_amp_event(struct snd_soc_dapm_widget *w,
		struct snd_kcontrol *kcontrol, int event)
{
	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
	struct cs35l34_private *priv = snd_soc_codec_get_drvdata(codec);

	switch (event) {
	case SND_SOC_DAPM_POST_PMU:
		regmap_update_bits(priv->regmap, CS35L34_BST_CVTR_V_CTL,
				CS35L34_BST_CVTL_MASK, priv->pdata.boost_vtge);
		usleep_range(5000, 5100);
		regmap_update_bits(priv->regmap, CS35L34_PROTECT_CTL,
						CS35L34_MUTE, 0);
		break;
	case SND_SOC_DAPM_POST_PMD:
		regmap_update_bits(priv->regmap, CS35L34_BST_CVTR_V_CTL,
			CS35L34_BST_CVTL_MASK, 0);
		regmap_update_bits(priv->regmap, CS35L34_PROTECT_CTL,
			CS35L34_MUTE, CS35L34_MUTE);
		usleep_range(5000, 5100);
		break;
	default:
		pr_err("Invalid event = 0x%x\n", event);
	}
	return 0;
}
示例#6
0
static int rt5616_lout_event(struct snd_soc_dapm_widget *w,
			     struct snd_kcontrol *kcontrol, int event)
{
	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);

	switch (event) {
	case SND_SOC_DAPM_POST_PMU:
		snd_soc_update_bits(codec, RT5616_PWR_ANLG1,
				    RT5616_PWR_LM, RT5616_PWR_LM);
		snd_soc_update_bits(codec, RT5616_LOUT_CTRL1,
				    RT5616_L_MUTE | RT5616_R_MUTE, 0);
		break;

	case SND_SOC_DAPM_PRE_PMD:
		snd_soc_update_bits(codec, RT5616_LOUT_CTRL1,
				    RT5616_L_MUTE | RT5616_R_MUTE,
				    RT5616_L_MUTE | RT5616_R_MUTE);
		snd_soc_update_bits(codec, RT5616_PWR_ANLG1,
				    RT5616_PWR_LM, 0);
		break;

	default:
		return 0;
	}

	return 0;
}
示例#7
0
static int clk_sys_event(struct snd_soc_dapm_widget *w,
			 struct snd_kcontrol *kcontrol, int event)
{
	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
	struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);

	/* This should be done on init() for bypass paths */
	switch (wm9081->sysclk_source) {
	case WM9081_SYSCLK_MCLK:
		dev_dbg(codec->dev, "Using %dHz MCLK\n", wm9081->mclk_rate);
		break;
	case WM9081_SYSCLK_FLL_MCLK:
		dev_dbg(codec->dev, "Using %dHz MCLK with FLL\n",
			wm9081->mclk_rate);
		break;
	default:
		dev_err(codec->dev, "System clock not configured\n");
		return -EINVAL;
	}

	switch (event) {
	case SND_SOC_DAPM_PRE_PMU:
		configure_clock(codec);
		break;

	case SND_SOC_DAPM_POST_PMD:
		/* Disable the FLL if it's running */
		wm9081_set_fll(codec, 0, 0, 0);
		break;
	}

	return 0;
}
示例#8
0
static int wm8961_spk_event(struct snd_soc_dapm_widget *w,
			    struct snd_kcontrol *kcontrol, int event)
{
	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
	u16 pwr_reg = snd_soc_read(codec, WM8961_PWR_MGMT_2);
	u16 spk_reg = snd_soc_read(codec, WM8961_CLASS_D_CONTROL_1);

	if (event & SND_SOC_DAPM_POST_PMU) {
		/* Enable the PGA */
		pwr_reg |= WM8961_SPKL_PGA | WM8961_SPKR_PGA;
		snd_soc_write(codec, WM8961_PWR_MGMT_2, pwr_reg);

		/* Enable the amplifier */
		spk_reg |= WM8961_SPKL_ENA | WM8961_SPKR_ENA;
		snd_soc_write(codec, WM8961_CLASS_D_CONTROL_1, spk_reg);
	}

	if (event & SND_SOC_DAPM_PRE_PMD) {
		/* Disable the amplifier */
		spk_reg &= ~(WM8961_SPKL_ENA | WM8961_SPKR_ENA);
		snd_soc_write(codec, WM8961_CLASS_D_CONTROL_1, spk_reg);

		/* Disable the PGA */
		pwr_reg &= ~(WM8961_SPKL_PGA | WM8961_SPKR_PGA);
		snd_soc_write(codec, WM8961_PWR_MGMT_2, pwr_reg);
	}

	return 0;
}
示例#9
0
文件: adau17x1.c 项目: 020gzh/linux
static int adau17x1_pll_event(struct snd_soc_dapm_widget *w,
	struct snd_kcontrol *kcontrol, int event)
{
	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
	struct adau *adau = snd_soc_codec_get_drvdata(codec);
	int ret;

	if (SND_SOC_DAPM_EVENT_ON(event)) {
		adau->pll_regs[5] = 1;
	} else {
		adau->pll_regs[5] = 0;
		/* Bypass the PLL when disabled, otherwise registers will become
		 * inaccessible. */
		regmap_update_bits(adau->regmap, ADAU17X1_CLOCK_CONTROL,
			ADAU17X1_CLOCK_CONTROL_CORECLK_SRC_PLL, 0);
	}

	/* The PLL register is 6 bytes long and can only be written at once. */
	ret = regmap_raw_write(adau->regmap, ADAU17X1_PLL_CONTROL,
			adau->pll_regs, ARRAY_SIZE(adau->pll_regs));

	if (SND_SOC_DAPM_EVENT_ON(event)) {
		mdelay(5);
		regmap_update_bits(adau->regmap, ADAU17X1_CLOCK_CONTROL,
			ADAU17X1_CLOCK_CONTROL_CORECLK_SRC_PLL,
			ADAU17X1_CLOCK_CONTROL_CORECLK_SRC_PLL);
	}

	return 0;
}
示例#10
0
文件: adav80x.c 项目: 383530895/linux
static int adav80x_dapm_pll_check(struct snd_soc_dapm_widget *source,
			 struct snd_soc_dapm_widget *sink)
{
	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
	struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);

	return adav80x->pll_src == ADAV80X_PLL_SRC_XTAL;
}
示例#11
0
static int pm8916_wcd_analog_enable_micbias_int2(struct
						  snd_soc_dapm_widget
						  *w, struct snd_kcontrol
						  *kcontrol, int event)
{
	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
	struct pm8916_wcd_analog_priv *wcd = snd_soc_codec_get_drvdata(codec);

	return pm8916_wcd_analog_enable_micbias_int(codec, event, w->reg,
						     wcd->micbias2_cap_mode);
}
示例#12
0
文件: rx51.c 项目: DenisLug/mptcp
static int rx51_hp_event(struct snd_soc_dapm_widget *w,
			 struct snd_kcontrol *k, int event)
{
	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);

	if (SND_SOC_DAPM_EVENT_ON(event))
		tpa6130a2_stereo_enable(codec, 1);
	else
		tpa6130a2_stereo_enable(codec, 0);

	return 0;
}
示例#13
0
static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source,
			       struct snd_soc_dapm_widget *sink)
{
	unsigned int val;

	val = snd_soc_read(snd_soc_dapm_to_codec(source->dapm), RT5616_GLB_CLK);
	val &= RT5616_SCLK_SRC_MASK;
	if (val == RT5616_SCLK_SRC_PLL1)
		return 1;
	else
		return 0;
}
示例#14
0
static int aiftx_power_control(struct snd_soc_dapm_widget *w,
		struct snd_kcontrol *k, int  event)
{
	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
	struct nau8540 *nau8540 = snd_soc_codec_get_drvdata(codec);

	if (SND_SOC_DAPM_EVENT_OFF(event)) {
		regmap_write(nau8540->regmap, NAU8540_REG_RST, 0x0001);
		regmap_write(nau8540->regmap, NAU8540_REG_RST, 0x0000);
	}
	return 0;
}
示例#15
0
static int pll_event(struct snd_soc_dapm_widget *w,
		     struct snd_kcontrol *kcontrol, int event)
{
	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
	int ret;

	if (SND_SOC_DAPM_EVENT_ON(event))
		ret = power_up_audio_plls(codec);
	else
		ret = power_down_audio_plls(codec);

	return ret;
}
示例#16
0
static int sn95031_dmic56_event(struct snd_soc_dapm_widget *w,
                                struct snd_kcontrol *k, int event)
{
    struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
    unsigned int ldo = 0;

    if (SND_SOC_DAPM_EVENT_ON(event))
        ldo = BIT(7)|BIT(6);

    /* program DMIC LDO */
    snd_soc_update_bits(codec, SN95031_MICBIAS, BIT(7)|BIT(6), ldo);
    return 0;
}
示例#17
0
文件: wm8988.c 项目: 020gzh/linux
static int wm8988_lrc_control(struct snd_soc_dapm_widget *w,
			      struct snd_kcontrol *kcontrol, int event)
{
	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
	u16 adctl2 = snd_soc_read(codec, WM8988_ADCTL2);

	/* Use the DAC to gate LRC if active, otherwise use ADC */
	if (snd_soc_read(codec, WM8988_PWR2) & 0x180)
		adctl2 &= ~0x4;
	else
		adctl2 |= 0x4;

	return snd_soc_write(codec, WM8988_ADCTL2, adctl2);
}
示例#18
0
static int adau1761_dejitter_fixup(struct snd_soc_dapm_widget *w,
	struct snd_kcontrol *kcontrol, int event)
{
	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
	struct adau *adau = snd_soc_codec_get_drvdata(codec);

	/* After any power changes have been made the dejitter circuit
	 * has to be reinitialized. */
	regmap_write(adau->regmap, ADAU1761_DEJITTER, 0);
	if (!adau->master)
		regmap_write(adau->regmap, ADAU1761_DEJITTER, 3);

	return 0;
}
示例#19
0
static int aic31xx_dapm_power_event(struct snd_soc_dapm_widget *w,
				    struct snd_kcontrol *kcontrol, int event)
{
	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
	struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec);
	unsigned int reg = AIC31XX_DACFLAG1;
	unsigned int mask;

	switch (WIDGET_BIT(w->reg, w->shift)) {
	case WIDGET_BIT(AIC31XX_DACSETUP, 7):
		mask = AIC31XX_LDACPWRSTATUS_MASK;
		break;
	case WIDGET_BIT(AIC31XX_DACSETUP, 6):
		mask = AIC31XX_RDACPWRSTATUS_MASK;
		break;
	case WIDGET_BIT(AIC31XX_HPDRIVER, 7):
		mask = AIC31XX_HPLDRVPWRSTATUS_MASK;
		break;
	case WIDGET_BIT(AIC31XX_HPDRIVER, 6):
		mask = AIC31XX_HPRDRVPWRSTATUS_MASK;
		break;
	case WIDGET_BIT(AIC31XX_SPKAMP, 7):
		mask = AIC31XX_SPLDRVPWRSTATUS_MASK;
		break;
	case WIDGET_BIT(AIC31XX_SPKAMP, 6):
		mask = AIC31XX_SPRDRVPWRSTATUS_MASK;
		break;
	case WIDGET_BIT(AIC31XX_ADCSETUP, 7):
		mask = AIC31XX_ADCPWRSTATUS_MASK;
		reg = AIC31XX_ADCFLAG;
		break;
	default:
		dev_err(codec->dev, "Unknown widget '%s' calling %s\n",
			w->name, __func__);
		return -EINVAL;
	}

	switch (event) {
	case SND_SOC_DAPM_POST_PMU:
		return aic31xx_wait_bits(aic31xx, reg, mask, mask, 5000, 100);
	case SND_SOC_DAPM_POST_PMD:
		return aic31xx_wait_bits(aic31xx, reg, mask, 0, 5000, 100);
	default:
		dev_dbg(codec->dev,
			"Unhandled dapm widget event %d from %s\n",
			event, w->name);
	}
	return 0;
}
示例#20
0
文件: cs42l73.c 项目: acton393/linux
static int cs42l73_spklo_spk_amp_event(struct snd_soc_dapm_widget *w,
	struct snd_kcontrol *kcontrol, int event)
{
	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
	struct cs42l73_private *priv = snd_soc_codec_get_drvdata(codec);
	switch (event) {
	case SND_SOC_DAPM_POST_PMD:
		/* 150 ms delay between setting PDN and MCLKDIS */
		priv->shutdwn_delay = 150;
		break;
	default:
		pr_err("Invalid event = 0x%x\n", event);
	}
	return 0;
}
示例#21
0
文件: wm8991.c 项目: 020gzh/linux
/*
 * _DAPM_ Controls
 */
static int outmixer_event(struct snd_soc_dapm_widget *w,
			  struct snd_kcontrol *kcontrol, int event)
{
	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
	u32 reg_shift = kcontrol->private_value & 0xfff;
	int ret = 0;
	u16 reg;

	switch (reg_shift) {
	case WM8991_SPEAKER_MIXER | (WM8991_LDSPK_BIT << 8):
		reg = snd_soc_read(codec, WM8991_OUTPUT_MIXER1);
		if (reg & WM8991_LDLO) {
			printk(KERN_WARNING
			       "Cannot set as Output Mixer 1 LDLO Set\n");
			ret = -1;
		}
		break;

	case WM8991_SPEAKER_MIXER | (WM8991_RDSPK_BIT << 8):
		reg = snd_soc_read(codec, WM8991_OUTPUT_MIXER2);
		if (reg & WM8991_RDRO) {
			printk(KERN_WARNING
			       "Cannot set as Output Mixer 2 RDRO Set\n");
			ret = -1;
		}
		break;

	case WM8991_OUTPUT_MIXER1 | (WM8991_LDLO_BIT << 8):
		reg = snd_soc_read(codec, WM8991_SPEAKER_MIXER);
		if (reg & WM8991_LDSPK) {
			printk(KERN_WARNING
			       "Cannot set as Speaker Mixer LDSPK Set\n");
			ret = -1;
		}
		break;

	case WM8991_OUTPUT_MIXER2 | (WM8991_RDRO_BIT << 8):
		reg = snd_soc_read(codec, WM8991_SPEAKER_MIXER);
		if (reg & WM8991_RDSPK) {
			printk(KERN_WARNING
			       "Cannot set as Speaker Mixer RDSPK Set\n");
			ret = -1;
		}
		break;
	}

	return ret;
}
示例#22
0
文件: wm9713.c 项目: a2hojsjsjs/linux
static int wm9713_voice_shutdown(struct snd_soc_dapm_widget *w,
				 struct snd_kcontrol *kcontrol, int event)
{
	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);

	if (WARN_ON(event != SND_SOC_DAPM_PRE_PMD))
		return -EINVAL;

	/* Gracefully shut down the voice interface. */
	snd_soc_update_bits(codec, AC97_HANDSET_RATE, 0x0f00, 0x0200);
	schedule_timeout_interruptible(msecs_to_jiffies(1));
	snd_soc_update_bits(codec, AC97_HANDSET_RATE, 0x0f00, 0x0f00);
	snd_soc_update_bits(codec, AC97_EXTENDED_MID, 0x1000, 0x1000);

	return 0;
}
示例#23
0
static int sn95031_vihf_event(struct snd_soc_dapm_widget *w,
                              struct snd_kcontrol *kcontrol, int event)
{
    struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);

    if (SND_SOC_DAPM_EVENT_ON(event)) {
        pr_debug("VIHF SND_SOC_DAPM_EVENT_ON doing rail startup now\n");
        /* power up the rail */
        snd_soc_write(codec, SN95031_VIHF, 0x27);
        msleep(1);
    } else if (SND_SOC_DAPM_EVENT_OFF(event)) {
        pr_debug("VIHF SND_SOC_DAPM_EVENT_OFF doing rail shutdown\n");
        snd_soc_write(codec, SN95031_VIHF, 0x24);
    }
    return 0;
}
示例#24
0
文件: rt5640.c 项目: roysuman/linux
/**
 * set_dmic_clk - Set parameter of dmic.
 *
 * @w: DAPM widget.
 * @kcontrol: The kcontrol of this widget.
 * @event: Event id.
 *
 */
static int set_dmic_clk(struct snd_soc_dapm_widget *w,
	struct snd_kcontrol *kcontrol, int event)
{
	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
	struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
	int idx, rate;

	rate = rt5640->sysclk / rl6231_get_pre_div(rt5640->regmap,
		RT5640_ADDA_CLK1, RT5640_I2S_PD1_SFT);
	idx = rl6231_calc_dmic_clk(rate);
	if (idx < 0)
		dev_err(codec->dev, "Failed to set DMIC clock\n");
	else
		snd_soc_update_bits(codec, RT5640_DMIC, RT5640_DMIC_CLK_MASK,
					idx << RT5640_DMIC_CLK_SFT);
	return idx;
}
示例#25
0
static int pm8916_wcd_analog_enable_spk_pa(struct snd_soc_dapm_widget *w,
					    struct snd_kcontrol *kcontrol,
					    int event)
{
	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);

	switch (event) {
	case SND_SOC_DAPM_PRE_PMU:
		snd_soc_update_bits(codec, CDC_A_SPKR_PWRSTG_CTL,
				    SPKR_PWRSTG_CTL_DAC_EN_MASK |
				    SPKR_PWRSTG_CTL_BBM_MASK |
				    SPKR_PWRSTG_CTL_HBRDGE_EN_MASK |
				    SPKR_PWRSTG_CTL_CLAMP_EN_MASK,
				    SPKR_PWRSTG_CTL_DAC_EN|
				    SPKR_PWRSTG_CTL_BBM_EN |
				    SPKR_PWRSTG_CTL_HBRDGE_EN |
				    SPKR_PWRSTG_CTL_CLAMP_EN);

		snd_soc_update_bits(codec, CDC_A_RX_EAR_CTL,
				    RX_EAR_CTL_SPK_VBAT_LDO_EN_MASK,
				    RX_EAR_CTL_SPK_VBAT_LDO_EN_ENABLE);
		break;
	case SND_SOC_DAPM_POST_PMU:
		snd_soc_update_bits(codec, CDC_A_SPKR_DRV_CTL,
				    SPKR_DRV_CTL_DEF_MASK,
				    SPKR_DRV_CTL_DEF_VAL);
		snd_soc_update_bits(codec, w->reg,
				    SPKR_DRV_CLASSD_PA_EN_MASK,
				    SPKR_DRV_CLASSD_PA_EN_ENABLE);
		break;
	case SND_SOC_DAPM_POST_PMD:
		snd_soc_update_bits(codec, CDC_A_SPKR_PWRSTG_CTL,
				    SPKR_PWRSTG_CTL_DAC_EN_MASK|
				    SPKR_PWRSTG_CTL_BBM_MASK |
				    SPKR_PWRSTG_CTL_HBRDGE_EN_MASK |
				    SPKR_PWRSTG_CTL_CLAMP_EN_MASK, 0);

		snd_soc_update_bits(codec, CDC_A_SPKR_DAC_CTL,
				    SPKR_DAC_CTL_DAC_RESET_MASK,
				    SPKR_DAC_CTL_DAC_RESET_NORMAL);
		snd_soc_update_bits(codec, CDC_A_RX_EAR_CTL,
				    RX_EAR_CTL_SPK_VBAT_LDO_EN_MASK, 0);
		break;
	}
	return 0;
}
示例#26
0
static int msm8916_wcd_digital_enable_interpolator(
						struct snd_soc_dapm_widget *w,
						struct snd_kcontrol *kcontrol,
						int event)
{
	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);

	switch (event) {
	case SND_SOC_DAPM_POST_PMU:
		/* apply the digital gain after the interpolator is enabled */
		usleep_range(10000, 10100);
		snd_soc_write(codec, rx_gain_reg[w->shift],
			      snd_soc_read(codec, rx_gain_reg[w->shift]));
		break;
	}
	return 0;
}
示例#27
0
static int tas5720_dac_event(struct snd_soc_dapm_widget *w,
			     struct snd_kcontrol *kcontrol, int event)
{
	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
	struct tas5720_data *tas5720 = snd_soc_codec_get_drvdata(codec);
	int ret;

	if (event & SND_SOC_DAPM_POST_PMU) {
		/* Take TAS5720 out of shutdown mode */
		ret = snd_soc_update_bits(codec, TAS5720_POWER_CTRL_REG,
					  TAS5720_SDZ, TAS5720_SDZ);
		if (ret < 0) {
			dev_err(codec->dev, "error waking codec: %d\n", ret);
			return ret;
		}

		/*
		 * Observe codec shutdown-to-active time. The datasheet only
		 * lists a nominal value however just use-it as-is without
		 * additional padding to minimize the delay introduced in
		 * starting to play audio (actually there is other setup done
		 * by the ASoC framework that will provide additional delays,
		 * so we should always be safe).
		 */
		msleep(25);

		/* Turn on TAS5720 periodic fault checking/handling */
		tas5720->last_fault = 0;
		schedule_delayed_work(&tas5720->fault_check_work,
				msecs_to_jiffies(TAS5720_FAULT_CHECK_INTERVAL));
	} else if (event & SND_SOC_DAPM_PRE_PMD) {
		/* Disable TAS5720 periodic fault checking/handling */
		cancel_delayed_work_sync(&tas5720->fault_check_work);

		/* Place TAS5720 in shutdown mode to minimize current draw */
		ret = snd_soc_update_bits(codec, TAS5720_POWER_CTRL_REG,
					  TAS5720_SDZ, 0);
		if (ret < 0) {
			dev_err(codec->dev, "error shutting down codec: %d\n",
				ret);
			return ret;
		}
	}

	return 0;
}
示例#28
0
static int sn95031_dmic34_event(struct snd_soc_dapm_widget *w,
                                struct snd_kcontrol *k, int event)
{
    struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
    unsigned int ldo = 0, clk_dir = 0, data_dir = 0;

    if (SND_SOC_DAPM_EVENT_ON(event)) {
        ldo = BIT(5)|BIT(4);
        clk_dir = BIT(2);
        data_dir = BIT(1);
    }
    /* program DMIC LDO, clock and set clock */
    snd_soc_update_bits(codec, SN95031_MICBIAS, BIT(5)|BIT(4), ldo);
    snd_soc_update_bits(codec, SN95031_DMICBUF0123, BIT(2), clk_dir);
    snd_soc_update_bits(codec, SN95031_DMICBUF45, BIT(1), data_dir);
    return 0;
}
示例#29
0
/* event handlers */
static int ak4671_out2_event(struct snd_soc_dapm_widget *w,
		struct snd_kcontrol *kcontrol, int event)
{
	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);

	switch (event) {
	case SND_SOC_DAPM_POST_PMU:
		snd_soc_update_bits(codec, AK4671_LOUT2_POWER_MANAGERMENT,
				    AK4671_MUTEN, AK4671_MUTEN);
		break;
	case SND_SOC_DAPM_PRE_PMD:
		snd_soc_update_bits(codec, AK4671_LOUT2_POWER_MANAGERMENT,
				    AK4671_MUTEN, 0);
		break;
	}

	return 0;
}
示例#30
0
static int wm9712_hp_mixer_get(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol);
	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(dapm);
	struct wm9712_priv *wm9712 = snd_soc_codec_get_drvdata(codec);
	struct soc_mixer_control *mc =
		(struct soc_mixer_control *)kcontrol->private_value;
	unsigned int shift, mixer;

	mixer = mc->shift >> 8;
	shift = mc->shift & 0xff;

	ucontrol->value.integer.value[0] =
		(wm9712->hp_mixer[mixer] >> shift) & 1;

	return 0;
}