/*
 * Driver for Digigram VX soundcards
 *
 * Common mixer part
 *
 * Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 */

#include <sound/driver.h>
#include <sound/core.h>
#include <sound/control.h>
#include <sound/vx_core.h>
#include "vx_cmd.h"


/*
 * write a codec data (24bit)
 */
static void vx_write_codec_reg(vx_core_t *chip, int codec, unsigned int data)
{
	unsigned long flags;

	snd_assert(chip->ops->write_codec, return);

	if (chip->chip_status & VX_STAT_IS_STALE)
		return;

	spin_lock_irqsave(&chip->lock, flags);
	chip->ops->write_codec(chip, codec, data);
	spin_unlock_irqrestore(&chip->lock, flags);
}

/*
 * Data type used to access the Codec
 */
typedef union {
	u32 l;
#ifdef SNDRV_BIG_ENDIAN
	struct w {
		u16 h;
		u16 l;
	} w;
	struct b {
		u8 hh;
		u8 mh;
		u8 ml;
		u8 ll;
	} b;
#else /* LITTLE_ENDIAN */
	struct w {
		u16 l;
		u16 h;
	} w;
	struct b {
		u8 ll;
		u8 ml;
		u8 mh;
		u8 hh;
	} b;
#endif
} vx_codec_data_t;

#define SET_CDC_DATA_SEL(di,s)          ((di).b.mh = (u8) (s))
#define SET_CDC_DATA_REG(di,r)          ((di).b.ml = (u8) (r))
#define SET_CDC_DATA_VAL(di,d)          ((di).b.ll = (u8) (d))
#define SET_CDC_DATA_INIT(di)           ((di).l = 0L, SET_CDC_DATA_SEL(di,XX_CODEC_SELECTOR))

/*
 * set up codec register and write the value
 * @codec: the codec id, 0 or 1
 * @reg: register index
 * @val: data value
 */
static void vx_set_codec_reg(vx_core_t *chip, int codec, int reg, int val)
{
	vx_codec_data_t data;
	/* DAC control register */
	SET_CDC_DATA_INIT(data);
	SET_CDC_DATA_REG(data, reg);
	SET_CDC_DATA_VAL(data, val);
	vx_write_codec_reg(chip, codec, data.l);
}


/*
 * vx_set_analog_output_level - set the output attenuation level
 * @codec: the output codec, 0 or 1.  (1 for VXP440 only)
 * @left: left output level, 0 = mute
 * @right: right output level
 */
static void vx_set_analog_output_level(vx_core_t *chip, int codec, int left, int right)
{
	left  = chip->hw->output_level_max - left;
	right = chip->hw->output_level_max - right;

	if (chip->ops->akm_write) {
		chip->ops->akm_write(chip, XX_CODEC_LEVEL_LEFT_REGISTER, left);
		chip->ops->akm_write(chip, XX_CODEC_LEVEL_RIGHT_REGISTER, right);
	} else {
		/* convert to attenuation level: 0 = 0dB (max), 0xe3 = -113.5 dB (min) */
		vx_set_codec_reg(chip, codec, XX_CODEC_LEVEL_LEFT_REGISTER, left);
		vx_set_codec_reg(chip, codec, XX_CODEC_LEVEL_RIGHT_REGISTER, right);
	}
}


/*
 * vx_toggle_dac_mute -  mute/unmute DAC
 * @mute: 0 = unmute, 1 = mute
 */

#define DAC_ATTEN_MIN	0x08
#define DAC_ATTEN_MAX	0x38

void vx_toggle_dac_mute(vx_core_t *chip, int mute)
{
	unsigned int i;
	for (i = 0; i < chip->hw->num_codecs; i++) {
		if (chip->ops->akm_write)
			chip->ops->akm_write(chip, XX_CODEC_DAC_CONTROL_REGISTER, mute); /* XXX */
		else
			vx_set_codec_reg(chip, i, XX_CODEC_DAC_CONTROL_REGISTER,
					 mute ? DAC_ATTEN_MAX : DAC_ATTEN_MIN);
	}
}

/*
 * vx_reset_codec - reset and initialize the codecs
 */
void vx_reset_codec(vx_core_t *chip, int cold_reset)
{
	unsigned int i;
	int port = chip->type >= VX_TYPE_VXPOCKET ? 0x75 : 0x65;

	chip->ops->reset_codec(chip);

	/* AKM codecs should be initialized in reset_codec callback */
	if (! chip->ops->akm_write) {
		/* initialize old codecs */
		for (i = 0; i < chip->hw->num_codecs; i++) {
			/* DAC control register (change level when zero crossing + mute) */
			vx_set_codec_reg(chip, i, XX_CODEC_DAC_CONTROL_REGISTER, DAC_ATTEN_MAX);
			/* ADC control register */
			vx_set_codec_reg(chip, i, XX_CODEC_ADC_CONTROL_REGISTER, 0x00);
			/* Port mode register */
			vx_set_codec_reg(chip, i, XX_CODEC_PORT_MODE_REGISTER, port);
			/* Clock control register */
			vx_set_codec_reg(chip, i, XX_CODEC_CLOCK_CONTROL_REGISTER, 0x00);
		}
	}

	/* mute analog output */
	for (i = 0; i < chip->hw->num_codecs; i++) {
		chip->output_level[i][0] = 0;
		chip->output_level[i][1] = 0;
		vx_set_analog_output_level(chip, i, 0, 0);
	}
}

/*
 * change the audio input source
 * @src: the target source (VX_AUDIO_SRC_XXX)
 */
static void vx_change_audio_source(vx_core_t *chip, int src)
{
	unsigned long flags;

	if (chip->chip_status & VX_STAT_IS_STALE)
		return;

	spin_lock_irqsave(&chip->lock, flags);
	chip->ops->change_audio_source(chip, src);
	spin_unlock_irqrestore(&chip->lock, flags);
}


/*
 * change the audio source if necessary and possible
 * returns 1 if the source is actually changed.
 */
int vx_sync_audio_source(vx_core_t *chip)
{
	if (chip->audio_source_target == chip->audio_source ||
	    chip->pcm_running)
		return 0;
	vx_change_audio_source(chip, chip->audio_source_target);
	chip->audio_source = chip->audio_source_target;
	return 1;
}


/*
 * audio level, mute, monitoring
 */
struct vx_audio_level {
	unsigned int has_level: 1;
	unsigned int has_monitor_level: 1;
	unsigned int has_mute: 1;
	unsigned int has_monitor_mute: 1;
	unsigned int mute;
	unsigned int monitor_mute;
	short level;
	short monitor_level;
};

static int vx_adjust_audio_level(vx_core_t *chip, int audio, int capture,
				 struct vx_audio_level *info)
{
	struct vx_rmh rmh;

	if (chip->chip_status & VX_STAT_IS_STALE)
		return -EBUSY;

        vx_init_rmh(&rmh, CMD_AUDIO_LEVEL_ADJUST);
	if (capture)
		rmh.Cmd[0] |= COMMAND_RECORD_MASK;
	/* Add Audio IO mask */
	rmh.Cmd[1] = 1 << audio;
	rmh.Cmd[2] = 0;
	if (info->has_level) {
		rmh.Cmd[0] |=  VALID_AUDIO_IO_DIGITAL_LEVEL;
		rmh.Cmd[2] |= info->level;
        }
	if (info->has_monitor_level) {
		rmh.Cmd[0] |=  VALID_AUDIO_IO_MONITORING_LEVEL;
		rmh.Cmd[2] |= ((unsigned int)info->monitor_level << 10);
        }
	if (info->has_mute) { 
		rmh.Cmd[0] |= VALID_AUDIO_IO_MUTE_LEVEL;
		if (info->mute)
			rmh.Cmd[2] |= AUDIO_IO_HAS_MUTE_LEVEL;
	}
	if (info->has_monitor_mute) {
		/* validate flag for M2 at least to unmute it */ 
		rmh.Cmd[0] |=  VALID_AUDIO_IO_MUTE_MONITORING_1 | VALID_AUDIO_IO_MUTE_MONITORING_2;
		if (info->monitor_mute)
			rmh.Cmd[2] |= AUDIO_IO_HAS_MUTE_MONITORING_1;
	}

	return vx_send_msg(chip, &rmh);
}

    
#if 0 // not used
static int vx_read_audio_level(vx_core_t *chip, int audio, int capture,
			       struct vx_audio_level *info)
{
	int err;
	struct vx_rmh rmh;

	memset(info, 0, sizeof(*info));
        vx_init_rmh(&rmh, CMD_GET_AUDIO_LEVELS);
	if (capture)
		rmh.Cmd[0] |= COMMAND_RECORD_MASK;
	/* Add Audio IO mask */
	rmh.Cmd[1] = 1 << audio;
	err = vx_send_msg(chip, &rmh);
	if (err < 0)
		return err;
	info.level = rmh.Stat[0] & MASK_DSP_WORD_LEVEL;
	info.monitor_level = (rmh.Stat[0] >> 10) & MASK_DSP_WORD_LEVEL;
	info.mute = (rmh.Stat[i] & AUDIO_IO_HAS_MUTE_LEVEL) ? 1 : 0;
	info.monitor_mute = (rmh.Stat[i] & AUDIO_IO_HAS_MUTE_MONITORING_1) ? 1 : 0;
	return 0;
}
#endif // not used

/*
 * set the monitoring level and mute state of the given audio
 * no more static, because must be called from vx_pcm to demute monitoring
 */
int vx_set_monitor_level(vx_core_t *chip, int audio, int level, int active)
{
	struct vx_audio_level info;

	memset(&info, 0, sizeof(info));
	info.has_monitor_level = 1;
	info.monitor_level = level;
	info.has_monitor_mute = 1;
	info.monitor_mute = !active;
	chip->audio_monitor[audio] = level;
	chip->audio_monitor_active[audio] = active;
	return vx_adjust_audio_level(chip, audio, 0, &info); /* playback only */
}


/*
 * set the mute status of the given audio
 */
static int vx_set_audio_switch(vx_core_t *chip, int audio, int active)
{
	struct vx_audio_level info;

	memset(&info, 0, sizeof(info));
	info.has_mute = 1;
	info.mute = !active;
	chip->audio_active[audio] = active;
	return vx_adjust_audio_level(chip, audio, 0, &info); /* playback only */
}

/*
 * set the mute status of the given audio
 */
static int vx_set_audio_gain(vx_core_t *chip, int audio, int capture, int level)
{
	struct vx_audio_level info;

	memset(&info, 0, sizeof(info));
	info.has_level = 1;
	info.level = level;
	chip->audio_gain[capture][audio] = level;
	return vx_adjust_audio_level(chip, audio, capture, &info);
}

/*
 * reset all audio levels
 */
static void vx_reset_audio_levels(vx_core_t *chip)
{
	unsigned int i, c;
	struct vx_audio_level info;

	memset(chip->audio_gain, 0, sizeof(chip->audio_gain));
	memset(chip->audio_active, 0, sizeof(chip->audio_active));
	memset(chip->audio_monitor, 0, sizeof(chip->audio_monitor));
	memset(chip->audio_monitor_active, 0, sizeof(chip->audio_monitor_active));

	for (c = 0; c < 2; c++) {
		for (i = 0; i < chip->hw->num_ins * 2; i++) {
			memset(&info, 0, sizeof(info));
			if (c == 0) {
				info.has_monitor_level = 1;
				info.has_mute = 1;
				info.has_monitor_mute = 1;
			}
			info.has_level = 1;
			info.level = CVAL_0DB; /* default: 0dB */
			vx_adjust_audio_level(chip, i, c, &info);
			chip->audio_gain[c][i] = CVAL_0DB;
			chip->audio_monitor[i] = CVAL_0DB;
		}
	}
}


/*
 * VU, peak meter record
 */

#define VU_METER_CHANNELS	2

struct vx_vu_meter {
	int saturated;
	int vu_level;
	int peak_level;
};

/*
 * get the VU and peak meter values
 * @audio: the audio index
 * @capture: 0 = playback, 1 = capture operation
 * @info: the array of vx_vu_meter records (size = 2).
 */
static int vx_get_audio_vu_meter(vx_core_t *chip, int audio, int capture, struct vx_vu_meter *info)
{
	struct vx_rmh rmh;
	int i, err;

	if (chip->chip_status & VX_STAT_IS_STALE)
		return -EBUSY;

	vx_init_rmh(&rmh, CMD_AUDIO_VU_PIC_METER);
	rmh.LgStat += 2 * VU_METER_CHANNELS;
	if (capture)
		rmh.Cmd[0] |= COMMAND_RECORD_MASK;
    
        /* Add Audio IO mask */
	rmh.Cmd[1] = 0;
	for (i = 0; i < VU_METER_CHANNELS; i++)
		rmh.Cmd[1] |= 1 << (audio + i);
	err = vx_send_msg(chip, &rmh);
	if (err < 0)
		return err;
	/* Read response */
	for (i = 0; i < 2 * VU_METER_CHANNELS; i +=2) {
		info->saturated = (rmh.Stat[0] & (1 << (audio + i))) ? 1 : 0;
		info->vu_level = rmh.Stat[i + 1];
		info->peak_level = rmh.Stat[i + 2];
		info++;
	}
	return 0;
}
   

/*
 * control API entries
 */

/*
 * output level control
 */
static int vx_output_level_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
{
	vx_core_t *chip = snd_kcontrol_chip(kcontrol);
	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
	uinfo->count = 2;
	uinfo->value.integer.min = 0;
	uinfo->value.integer.max = chip->hw->output_level_max;
	return 0;
}

static int vx_output_level_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
{
	vx_core_t *chip = snd_kcontrol_chip(kcontrol);
	int codec = kcontrol->id.index;
	down(&chip->mixer_mutex);
	ucontrol->value.integer.value[0] = chip->output_level[codec][0];
	ucontrol->value.integer.value[1] = chip->output_level[codec][1];
	up(&chip->mixer_mutex);
	return 0;
}

static int vx_output_level_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
{
	vx_core_t *chip = snd_kcontrol_chip(kcontrol);
	int codec = kcontrol->id.index;
	down(&chip->mixer_mutex);
	if (ucontrol->value.integer.value[0] != chip->output_level[codec][0] ||
	    ucontrol->value.integer.value[1] != chip->output_level[codec][1]) {
		vx_set_analog_output_level(chip, codec,
					   ucontrol->value.integer.value[0],
					   ucontrol->value.integer.value[1]);
		chip->output_level[codec][0] = ucontrol->value.integer.value[0];
		chip->output_level[codec][1] = ucontrol->value.integer.value[1];
		up(&chip->mixer_mutex);
		return 1;
	}
	up(&chip->mixer_mutex);
	return 0;
}

static snd_kcontrol_new_t vx_control_output_level = {
	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
	.name =		"Master Playback Volume",
	.info =		vx_output_level_info,
	.get =		vx_output_level_get,
	.put =		vx_output_level_put,
};

/*
 * audio source select
 */
static int vx_audio_src_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
{
	static char *texts_mic[3] = {
		"Digital", "Line", "Mic"
	};
	static char *texts_vx2[2] = {
		"Digital", "Analog"
	};
	vx_core_t *chip = snd_kcontrol_chip(kcontrol);

	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
	uinfo->count = 1;
	if (chip->type >= VX_TYPE_VXPOCKET) {
		uinfo->value.enumerated.items = 3;
		if (uinfo->value.enumerated.item > 2)
			uinfo->value.enumerated.item = 2;
		strcpy(uinfo->value.enumerated.name,
		       texts_mic[uinfo->value.enumerated.item]);
	} else {
		uinfo->value.enumerated.items = 2;
		if (uinfo->value.enumerated.item > 1)
			uinfo->value.enumerated.item = 1;
		strcpy(uinfo->value.enumerated.name,
		       texts_vx2[uinfo->value.enumerated.item]);
	}
	return 0;
}

static int vx_audio_src_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
{
	vx_core_t *chip = snd_kcontrol_chip(kcontrol);
	ucontrol->value.enumerated.item[0] = chip->audio_source_target;
	return 0;
}

static int vx_audio_src_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
{
	vx_core_t *chip = snd_kcontrol_chip(kcontrol);
	down(&chip->mixer_mutex);
	if (chip->audio_source_target != ucontrol->value.enumerated.item[0]) {
		chip->audio_source_target = ucontrol->value.enumerated.item[0];
		vx_sync_audio_source(chip);
		up(&chip->mixer_mutex);
		return 1;
	}
	up(&chip->mixer_mutex);
	return 0;
}

static snd_kcontrol_new_t vx_control_audio_src = {
	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
	.name =		"Capture Source",
	.info =		vx_audio_src_info,
	.get =		vx_audio_src_get,
	.put =		vx_audio_src_put,
};

/*
 * clock mode selection
 */
static int vx_clock_mode_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
{
	static char *texts[3] = {
		"Auto", "Internal", "External"
	};

	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
	uinfo->count = 1;
	uinfo->value.enumerated.items = 3;
	if (uinfo->value.enumerated.item > 2)
		uinfo->value.enumerated.item = 2;
	strcpy(uinfo->value.enumerated.name,
	       texts[uinfo->value.enumerated.item]);
	return 0;
}

static int vx_clock_mode_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
{
	vx_core_t *chip = snd_kcontrol_chip(kcontrol);
	ucontrol->value.enumerated.item[0] = chip->clock_mode;
	return 0;
}

static int vx_clock_mode_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
{
	vx_core_t *chip = snd_kcontrol_chip(kcontrol);
	down(&chip->mixer_mutex);
	if (chip->clock_mode != ucontrol->value.enumerated.item[0]) {
		chip->clock_mode = ucontrol->value.enumerated.item[0];
		vx_set_clock(chip, chip->freq);
		up(&chip->mixer_mutex);
		return 1;
	}
	up(&chip->mixer_mutex);
	return 0;
}

static snd_kcontrol_new_t vx_control_clock_mode = {
	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
	.name =		"Clock Mode",
	.info =		vx_clock_mode_info,
	.get =		vx_clock_mode_get,
	.put =		vx_clock_mode_put,
};

/*
 * Audio Gain
 */
static int vx_audio_gain_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
{
	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
	uinfo->count = 2;
	uinfo->value.integer.min = 0;
	uinfo->value.integer.max = CVAL_MAX;
	return 0;
}

static int vx_audio_gain_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
{
	vx_core_t *chip = snd_kcontrol_chip(kcontrol);
	int audio = kcontrol->private_value & 0xff;
	int capture = (kcontrol->private_value >> 8) & 1;

	down(&chip->mixer_mutex);
	ucontrol->value.integer.value[0] = chip->audio_gain[capture][audio];
	ucontrol->value.integer.value[1] = chip->audio_gain[capture][audio+1];
	up(&chip->mixer_mutex);
	return 0;
}

static int vx_audio_gain_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
{
	vx_core_t *chip = snd_kcontrol_chip(kcontrol);
	int audio = kcontrol->private_value & 0xff;
	int capture = (kcontrol->private_value >> 8) & 1;

	down(&chip->mixer_mutex);
	if (ucontrol->value.integer.value[0] != chip->audio_gain[capture][audio] ||
	    ucontrol->value.integer.value[1] != chip->audio_gain[capture][audio+1]) {
		vx_set_audio_gain(chip, audio, capture, ucontrol->value.integer.value[0]);
		vx_set_audio_gain(chip, audio+1, capture, ucontrol->value.integer.value[1]);
		up(&chip->mixer_mutex);
		return 1;
	}
	up(&chip->mixer_mutex);
	return 0;
}

static int vx_audio_monitor_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
{
	vx_core_t *chip = snd_kcontrol_chip(kcontrol);
	int audio = kcontrol->private_value & 0xff;

	down(&chip->mixer_mutex);
	ucontrol->value.integer.value[0] = chip->audio_monitor[audio];
	ucontrol->value.integer.value[1] = chip->audio_monitor[audio+1];
	up(&chip->mixer_mutex);
	return 0;
}

static int vx_audio_monitor_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
{
	vx_core_t *chip = snd_kcontrol_chip(kcontrol);
	int audio = kcontrol->private_value & 0xff;

	down(&chip->mixer_mutex);
	if (ucontrol->value.integer.value[0] != chip->audio_monitor[audio] ||
	    ucontrol->value.integer.value[1] != chip->audio_monitor[audio+1]) {
		vx_set_monitor_level(chip, audio, ucontrol->value.integer.value[0],
				     chip->audio_monitor_active[audio]);
		vx_set_monitor_level(chip, audio+1, ucontrol->value.integer.value[1],
				     chip->audio_monitor_active[audio+1]);
		up(&chip->mixer_mutex);
		return 1;
	}
	up(&chip->mixer_mutex);
	return 0;
}

static int vx_audio_sw_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *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 vx_audio_sw_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
{
	vx_core_t *chip = snd_kcontrol_chip(kcontrol);
	int audio = kcontrol->private_value & 0xff;

	down(&chip->mixer_mutex);
	ucontrol->value.integer.value[0] = chip->audio_active[audio];
	ucontrol->value.integer.value[1] = chip->audio_active[audio+1];
	up(&chip->mixer_mutex);
	return 0;
}

static int vx_audio_sw_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
{
	vx_core_t *chip = snd_kcontrol_chip(kcontrol);
	int audio = kcontrol->private_value & 0xff;

	down(&chip->mixer_mutex);
	if (ucontrol->value.integer.value[0] != chip->audio_active[audio] ||
	    ucontrol->value.integer.value[1] != chip->audio_active[audio+1]) {
		vx_set_audio_switch(chip, audio, ucontrol->value.integer.value[0]);
		vx_set_audio_switch(chip, audio+1, ucontrol->value.integer.value[1]);
		up(&chip->mixer_mutex);
		return 1;
	}
	up(&chip->mixer_mutex);
	return 0;
}

static int vx_monitor_sw_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
{
	vx_core_t *chip = snd_kcontrol_chip(kcontrol);
	int audio = kcontrol->private_value & 0xff;

	down(&chip->mixer_mutex);
	ucontrol->value.integer.value[0] = chip->audio_monitor_active[audio];
	ucontrol->value.integer.value[1] = chip->audio_monitor_active[audio+1];
	up(&chip->mixer_mutex);
	return 0;
}

static int vx_monitor_sw_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
{
	vx_core_t *chip = snd_kcontrol_chip(kcontrol);
	int audio = kcontrol->private_value & 0xff;

	down(&chip->mixer_mutex);
	if (ucontrol->value.integer.value[0] != chip->audio_monitor_active[audio] ||
	    ucontrol->value.integer.value[1] != chip->audio_monitor_active[audio+1]) {
		vx_set_monitor_level(chip, audio, chip->audio_monitor[audio],
				     ucontrol->value.integer.value[0]);
		vx_set_monitor_level(chip, audio+1, chip->audio_monitor[audio+1],
				     ucontrol->value.integer.value[1]);
		up(&chip->mixer_mutex);
		return 1;
	}
	up(&chip->mixer_mutex);
	return 0;
}

static snd_kcontrol_new_t vx_control_audio_gain = {
	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
	/* name will be filled later */
	.info =         vx_audio_gain_info,
	.get =          vx_audio_gain_get,
	.put =          vx_audio_gain_put
};
static snd_kcontrol_new_t vx_control_output_switch = {
	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
	.name =         "PCM Playback Switch",
	.info =         vx_audio_sw_info,
	.get =          vx_audio_sw_get,
	.put =          vx_audio_sw_put
};
static snd_kcontrol_new_t vx_control_monitor_gain = {
	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
	.name =         "Monitoring Volume",
	.info =         vx_audio_gain_info,	/* shared */
	.get =          vx_audio_monitor_get,
	.put =          vx_audio_monitor_put
};
static snd_kcontrol_new_t vx_control_monitor_switch = {
	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
	.name =         "Monitoring Switch",
	.info =         vx_audio_sw_info,	/* shared */
	.get =          vx_monitor_sw_get,
	.put =          vx_monitor_sw_put
};


/*
 * IEC958 status bits
 */
static int vx_iec958_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
{
	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
	uinfo->count = 1;
	return 0;
}

static int vx_iec958_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
{
	vx_core_t *chip = snd_kcontrol_chip(kcontrol);

	down(&chip->mixer_mutex);
	ucontrol->value.iec958.status[0] = (chip->uer_bits >> 0) & 0xff;
	ucontrol->value.iec958.status[1] = (chip->uer_bits >> 8) & 0xff;
	ucontrol->value.iec958.status[2] = (chip->uer_bits >> 16) & 0xff;
	ucontrol->value.iec958.status[3] = (chip->uer_bits >> 24) & 0xff;
	up(&chip->mixer_mutex);
        return 0;
}

static int vx_iec958_mask_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
{
	ucontrol->value.iec958.status[0] = 0xff;
	ucontrol->value.iec958.status[1] = 0xff;
	ucontrol->value.iec958.status[2] = 0xff;
	ucontrol->value.iec958.status[3] = 0xff;
        return 0;
}

static int vx_iec958_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
{
	vx_core_t *chip = snd_kcontrol_chip(kcontrol);
	unsigned int val;

	val = (ucontrol->value.iec958.status[0] << 0) |
	      (ucontrol->value.iec958.status[1] << 8) |
	      (ucontrol->value.iec958.status[2] << 16) |
	      (ucontrol->value.iec958.status[3] << 24);
	down(&chip->mixer_mutex);
	if (chip->uer_bits != val) {
		chip->uer_bits = val;
		vx_set_iec958_status(chip, val);
		up(&chip->mixer_mutex);
		return 1;
	}
	up(&chip->mixer_mutex);
	return 0;
}

static snd_kcontrol_new_t vx_control_iec958_mask = {
	.access =	SNDRV_CTL_ELEM_ACCESS_READ,
	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
	.name =		SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
	.info =		vx_iec958_info,	/* shared */
	.get =		vx_iec958_mask_get,
};

static snd_kcontrol_new_t vx_control_iec958 = {
	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
	.name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
	.info =         vx_iec958_info,
	.get =          vx_iec958_get,
	.put =          vx_iec958_put
};


/*
 * VU meter
 */

#define METER_MAX	0xff
#define METER_SHIFT	16

static int vx_vu_meter_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
{
	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
	uinfo->count = 2;
	uinfo->value.integer.min = 0;
	uinfo->value.integer.max = METER_MAX;
	return 0;
}

static int vx_vu_meter_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
{
	vx_core_t *chip = snd_kcontrol_chip(kcontrol);
	struct vx_vu_meter meter[2];
	int audio = kcontrol->private_value & 0xff;
	int capture = (kcontrol->private_value >> 8) & 1;

	vx_get_audio_vu_meter(chip, audio, capture, meter);
	ucontrol->value.integer.value[0] = meter[0].vu_level >> METER_SHIFT;
	ucontrol->value.integer.value[1] = meter[1].vu_level >> METER_SHIFT;
	return 0;
}

static int vx_peak_meter_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
{
	vx_core_t *chip = snd_kcontrol_chip(kcontrol);
	struct vx_vu_meter meter[2];
	int audio = kcontrol->private_value & 0xff;
	int capture = (kcontrol->private_value >> 8) & 1;

	vx_get_audio_vu_meter(chip, audio, capture, meter);
	ucontrol->value.integer.value[0] = meter[0].peak_level >> METER_SHIFT;
	ucontrol->value.integer.value[1] = meter[1].peak_level >> METER_SHIFT;
	return 0;
}

static int vx_saturation_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *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 vx_saturation_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
{
	vx_core_t *chip = snd_kcontrol_chip(kcontrol);
	struct vx_vu_meter meter[2];
	int audio = kcontrol->private_value & 0xff;

	vx_get_audio_vu_meter(chip, audio, 1, meter); /* capture only */
	ucontrol->value.integer.value[0] = meter[0].saturated;
	ucontrol->value.integer.value[1] = meter[1].saturated;
	return 0;
}

static snd_kcontrol_new_t vx_control_vu_meter = {
	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
	.access =	SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
	/* name will be filled later */
	.info =		vx_vu_meter_info,
	.get =		vx_vu_meter_get,
};

static snd_kcontrol_new_t vx_control_peak_meter = {
	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
	.access =	SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
	/* name will be filled later */
	.info =		vx_vu_meter_info,	/* shared */
	.get =		vx_peak_meter_get,
};

static snd_kcontrol_new_t vx_control_saturation = {
	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
	.name =		"Input Saturation",
	.access =	SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
	.info =		vx_saturation_info,
	.get =		vx_saturation_get,
};



/*
 *
 */

int snd_vx_mixer_new(vx_core_t *chip)
{
	unsigned int i, c;
	int err;
	snd_kcontrol_new_t temp;
	snd_card_t *card = chip->card;
	char name[32];

	strcpy(card->mixername, card->driver);

	/* output level controls */
	for (i = 0; i < chip->hw->num_outs; i++) {
		temp = vx_control_output_level;
		temp.index = i;
		if ((err = snd_ctl_add(card, snd_ctl_new1(&temp, chip))) < 0)
			return err;
	}

	/* PCM volumes, switches, monitoring */
	for (i = 0; i < chip->hw->num_outs; i++) {
		int val = i * 2;
		temp = vx_control_audio_gain;
		temp.index = i;
		temp.name = "PCM Playback Volume";
		temp.private_value = val;
		if ((err = snd_ctl_add(card, snd_ctl_new1(&temp, chip))) < 0)
			return err;
		temp = vx_control_output_switch;
		temp.index = i;
		temp.private_value = val;
		if ((err = snd_ctl_add(card, snd_ctl_new1(&temp, chip))) < 0)
			return err;
		temp = vx_control_monitor_gain;
		temp.index = i;
		temp.private_value = val;
		if ((err = snd_ctl_add(card, snd_ctl_new1(&temp, chip))) < 0)
			return err;
		temp = vx_control_monitor_switch;
		temp.index = i;
		temp.private_value = val;
		if ((err = snd_ctl_add(card, snd_ctl_new1(&temp, chip))) < 0)
			return err;
	}
	for (i = 0; i < chip->hw->num_outs; i++) {
		temp = vx_control_audio_gain;
		temp.index = i;
		temp.name = "PCM Capture Volume";
		temp.private_value = (i * 2) | (1 << 8);
		if ((err = snd_ctl_add(card, snd_ctl_new1(&temp, chip))) < 0)
			return err;
	}

	/* Audio source */
	if ((err = snd_ctl_add(card, snd_ctl_new1(&vx_control_audio_src, chip))) < 0)
		return err;
	/* clock mode */
	if ((err = snd_ctl_add(card, snd_ctl_new1(&vx_control_clock_mode, chip))) < 0)
		return err;
	/* IEC958 controls */
	if ((err = snd_ctl_add(card, snd_ctl_new1(&vx_control_iec958_mask, chip))) < 0)
		return err;
	if ((err = snd_ctl_add(card, snd_ctl_new1(&vx_control_iec958, chip))) < 0)
		return err;
	/* VU, peak, saturation meters */
	for (c = 0; c < 2; c++) {
		static char *dir[2] = { "Output", "Input" };
		for (i = 0; i < chip->hw->num_ins; i++) {
			int val = (i * 2) | (c << 8);
			if (c == 1) {
				temp = vx_control_saturation;
				temp.index = i;
				temp.private_value = val;
				if ((err = snd_ctl_add(card, snd_ctl_new1(&temp, chip))) < 0)
					return err;
			}
			sprintf(name, "%s VU Meter", dir[c]);
			temp = vx_control_vu_meter;
			temp.index = i;
			temp.name = name;
			temp.private_value = val;
			if ((err = snd_ctl_add(card, snd_ctl_new1(&temp, chip))) < 0)
				return err;
			sprintf(name, "%s Peak Meter", dir[c]);
			temp = vx_control_peak_meter;
			temp.index = i;
			temp.name = name;
			temp.private_value = val;
			if ((err = snd_ctl_add(card, snd_ctl_new1(&temp, chip))) < 0)
				return err;
		}
	}
	vx_reset_audio_levels(chip);
	return 0;
}
