static int pcxhr_monitor_sw_put(struct snd_kcontrol *kcontrol,
				struct snd_ctl_elem_value *ucontrol)
{
	struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
	int changed = 0;
	int i;

	mutex_lock(&chip->mgr->mixer_mutex);
	for (i = 0; i < 2; i++) {
		if (chip->monitoring_active[i] !=
		    ucontrol->value.integer.value[i]) {
			chip->monitoring_active[i] =
				!!ucontrol->value.integer.value[i];
			changed |= (1<<i); 
		}
	}
	if (changed & 0x01)
		
		pcxhr_update_audio_pipe_level(chip, 0, 0);
	if (changed & 0x02)
		
		pcxhr_update_audio_pipe_level(chip, 0, 1);

	mutex_unlock(&chip->mgr->mixer_mutex);
	return (changed != 0);
}
static int pcxhr_pcm_vol_put(struct snd_kcontrol *kcontrol,
			     struct snd_ctl_elem_value *ucontrol)
{
	struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
	int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);	
	int changed = 0;
	int is_capture = kcontrol->private_value;
	int *stored_volume;
	int i;

	mutex_lock(&chip->mgr->mixer_mutex);
	if (is_capture)		
		stored_volume = chip->digital_capture_volume;
	else			
		stored_volume = chip->digital_playback_volume[idx];
	for (i = 0; i < 2; i++) {
		int vol = ucontrol->value.integer.value[i];
		if (vol < PCXHR_DIGITAL_LEVEL_MIN ||
		    vol > PCXHR_DIGITAL_LEVEL_MAX)
			continue;
		if (stored_volume[i] != vol) {
			stored_volume[i] = vol;
			changed = 1;
			if (is_capture)	
				pcxhr_update_audio_pipe_level(chip, 1, i);
		}
	}
	if (!is_capture && changed)	
		pcxhr_update_playback_stream_level(chip, idx);
	mutex_unlock(&chip->mgr->mixer_mutex);
	return changed;
}
static int pcxhr_pcm_vol_put(struct snd_kcontrol *kcontrol,
			     struct snd_ctl_elem_value *ucontrol)
{
	struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
	int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);		/* index */
	int changed = 0;
	int is_capture = kcontrol->private_value;
	int *stored_volume;
	int i;

	down(&chip->mgr->mixer_mutex);
	if (is_capture)
		stored_volume = chip->digital_capture_volume;		/* digital capture */
	else
		stored_volume = chip->digital_playback_volume[idx];	/* digital playback */
	for (i = 0; i < 2; i++) {
		if (stored_volume[i] != ucontrol->value.integer.value[i]) {
			stored_volume[i] = ucontrol->value.integer.value[i];
			changed = 1;
			if (is_capture)	/* update capture volume */
				pcxhr_update_audio_pipe_level(chip, 1, i);
		}
	}
	if (! is_capture && changed)
		pcxhr_update_playback_stream_level(chip, idx);	/* update playback volume */
	up(&chip->mgr->mixer_mutex);
	return changed;
}
static int pcxhr_monitor_sw_put(struct snd_kcontrol *kcontrol,
				struct snd_ctl_elem_value *ucontrol)
{
	struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
	int changed = 0;
	int i;

	down(&chip->mgr->mixer_mutex);
	for (i = 0; i < 2; i++) {
		if (chip->monitoring_active[i] != ucontrol->value.integer.value[i]) {
			chip->monitoring_active[i] = ucontrol->value.integer.value[i];
			changed |= (1<<i); /* mask 0x01 and 0x02 */
		}
	}
	if(changed & 0x01)
		/* update left monitoring volume and mute */
		pcxhr_update_audio_pipe_level(chip, 0, 0);
	if(changed & 0x02)
		/* update right monitoring volume and mute */
		pcxhr_update_audio_pipe_level(chip, 0, 1);

	up(&chip->mgr->mixer_mutex);
	return (changed != 0);
}
static int pcxhr_monitor_vol_put(struct snd_kcontrol *kcontrol,
				 struct snd_ctl_elem_value *ucontrol)
{
	struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
	int changed = 0;
	int i;

	down(&chip->mgr->mixer_mutex);
	for (i = 0; i < 2; i++) {
		if (chip->monitoring_volume[i] != ucontrol->value.integer.value[i]) {
			chip->monitoring_volume[i] = ucontrol->value.integer.value[i];
			if(chip->monitoring_active[i])	/* do only when monitoring is unmuted */
				/* update monitoring volume and mute */
				pcxhr_update_audio_pipe_level(chip, 0, i);
			changed = 1;
		}
	}
	up(&chip->mgr->mixer_mutex);
	return changed;
}
static int pcxhr_monitor_vol_put(struct snd_kcontrol *kcontrol,
				 struct snd_ctl_elem_value *ucontrol)
{
	struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
	int changed = 0;
	int i;

	mutex_lock(&chip->mgr->mixer_mutex);
	for (i = 0; i < 2; i++) {
		if (chip->monitoring_volume[i] !=
		    ucontrol->value.integer.value[i]) {
			chip->monitoring_volume[i] =
				ucontrol->value.integer.value[i];
			if (chip->monitoring_active[i])
				
				
				pcxhr_update_audio_pipe_level(chip, 0, i);
			changed = 1;
		}
	}
	mutex_unlock(&chip->mgr->mixer_mutex);
	return changed;
}