示例#1
0
/*
 * Update the DC servo calibration on gain changes
 */
static int wm8993_put_dc_servo(struct snd_kcontrol *kcontrol,
			       struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
	struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
	int ret;

	ret = snd_soc_put_volsw_2r(kcontrol, ucontrol);

	/* Updating the analogue gains invalidates the DC servo cache */
	hubs->class_w_dcs = 0;

	/* If we're applying an offset correction then updating the
	 * callibration would be likely to introduce further offsets. */
	if (hubs->dcs_codes || hubs->no_series_update)
		return ret;

	/* Only need to do this if the outputs are active */
	if (snd_soc_read(codec, WM8993_POWER_MANAGEMENT_1)
	    & (WM8993_HPOUT1L_ENA | WM8993_HPOUT1R_ENA))
		snd_soc_update_bits(codec,
				    WM8993_DC_SERVO_0,
				    WM8993_DCS_TRIG_SINGLE_0 |
				    WM8993_DCS_TRIG_SINGLE_1,
				    WM8993_DCS_TRIG_SINGLE_0 |
				    WM8993_DCS_TRIG_SINGLE_1);

	return ret;
}
示例#2
0
static int wm8350_put_volsw_2r_vu(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
	struct wm8350_out_ramp *or = codec->private_data;
	struct wm8350_output *out1 = &or->out1, *out2 = &or->out2;
	int ret, reg = kcontrol->private_value & 0xff;
	u16 val;
	
	/* we cache the OUT1/2 volumes when the codec is inactive to keep 
	 * pops to a low during ramping */
	if (reg == WM8350_LOUT1_VOLUME) {
		out1->left_vol = ucontrol->value.integer.value[0];
		out1->right_vol = ucontrol->value.integer.value[1];
		if (!codec->active)
			return 1;
	} else if (reg == WM8350_LOUT2_VOLUME) {
		out2->left_vol = ucontrol->value.integer.value[0];
		out2->right_vol = ucontrol->value.integer.value[1];
		if (!codec->active)
			return 1;
	}
	
	ret = snd_soc_put_volsw_2r(kcontrol, ucontrol);
	if (ret < 0)
		return ret;
		
	/* now hit the volume update bits (always bit 8) */
	val = wm8350_codec_read(codec, reg);
	wm8350_codec_write(codec, reg, val | WM8350_OUT1_VU);
	return 1;
}
示例#3
0
static int wm8350_put_volsw_2r_vu(struct snd_kcontrol *kcontrol,
				  struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
	struct wm8350_data *wm8350_priv = codec->private_data;
	struct wm8350_output *out = NULL;
	struct soc_mixer_control *mc =
		(struct soc_mixer_control *)kcontrol->private_value;
	int ret;
	unsigned int reg = mc->reg;
	u16 val;

	/* For OUT1 and OUT2 we shadow the values and only actually write
	 * them out when active in order to ensure the amplifier comes on
	 * as quietly as possible. */
	switch (reg) {
	case WM8350_LOUT1_VOLUME:
		out = &wm8350_priv->out1;
		break;
	case WM8350_LOUT2_VOLUME:
		out = &wm8350_priv->out2;
		break;
	default:
		break;
	}

	if (out) {
		out->left_vol = ucontrol->value.integer.value[0];
		out->right_vol = ucontrol->value.integer.value[1];
		if (!out->active)
			return 1;
	}

	ret = snd_soc_put_volsw_2r(kcontrol, ucontrol);
	if (ret < 0)
		return ret;

	/* now hit the volume update bits (always bit 8) */
	val = wm8350_codec_read(codec, reg);
	wm8350_codec_write(codec, reg, val | WM8350_OUT1_VU);
	return 1;
}
示例#4
0
/*
 * Update the DC servo calibration on gain changes
 */
static int wm8993_put_dc_servo(struct snd_kcontrol *kcontrol,
			       struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
	int ret;

	ret = snd_soc_put_volsw_2r(kcontrol, ucontrol);

	/* Only need to do this if the outputs are active */
	if (snd_soc_read(codec, WM8993_POWER_MANAGEMENT_1)
	    & (WM8993_HPOUT1L_ENA | WM8993_HPOUT1R_ENA))
		snd_soc_update_bits(codec,
				    WM8993_DC_SERVO_0,
				    WM8993_DCS_TRIG_SINGLE_0 |
				    WM8993_DCS_TRIG_SINGLE_1,
				    WM8993_DCS_TRIG_SINGLE_0 |
				    WM8993_DCS_TRIG_SINGLE_1);

	return ret;
}
示例#5
0
static int cs42888_out_vu(struct snd_kcontrol *kcontrol,
			 struct snd_ctl_elem_value *ucontrol)
{
	struct soc_mixer_control *mc =
		(struct soc_mixer_control *)kcontrol->private_value;
	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
	unsigned int reg = mc->reg;
	unsigned int reg2 = mc->rreg;
	int ret;
	u16 val;

	ret = snd_soc_put_volsw_2r(kcontrol, ucontrol);
	if (ret < 0)
		return ret;

	/* Now write again with the volume update bit set */
	val = cs42888_read_reg_cache(codec, reg);
	ret = cs42888_i2c_write(codec, reg, val);

	val = cs42888_read_reg_cache(codec, reg2);
	ret = cs42888_i2c_write(codec, reg2, val);
	return 0;
}