/*
 *  Support for Digigram Lola PCI-e boards
 *
 *  Copyright (c) 2011 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 <linux/kernel.h>
#include <linux/init.h>
#include <linux/vmalloc.h>
#include <linux/io.h>
#include <sound/core.h>
#include <sound/control.h>
#include <sound/pcm.h>
#include <sound/tlv.h>
#include "lola.h"

static int __devinit lola_init_pin(struct lola *chip, struct lola_pin *pin,
				   int dir, int nid)
{
	unsigned int val;
	int err;

	pin->nid = nid;
	err = lola_read_param(chip, nid, LOLA_PAR_AUDIO_WIDGET_CAP, &val);
	if (err < 0) {
		printk(KERN_ERR SFX "Can't read wcaps for 0x%x\n", nid);
		return err;
	}
	val &= 0x00f00fff; /* test TYPE and bits 0..11 */
	if (val == 0x00400200)    /* Type = 4, Digital = 1 */
		pin->is_analog = false;
	else if (val == 0x0040000a && dir == CAPT) /* Dig=0, InAmp/ovrd */
		pin->is_analog = true;
	else if (val == 0x0040000c && dir == PLAY) /* Dig=0, OutAmp/ovrd */
		pin->is_analog = true;
	else {
		printk(KERN_ERR SFX "Invalid wcaps 0x%x for 0x%x\n", val, nid);
		return -EINVAL;
	}

	/* analog parameters only following, so continue in case of Digital pin
	 */
	if (!pin->is_analog)
		return 0;

	if (dir == PLAY)
		err = lola_read_param(chip, nid, LOLA_PAR_AMP_OUT_CAP, &val);
	else
		err = lola_read_param(chip, nid, LOLA_PAR_AMP_IN_CAP, &val);
	if (err < 0) {
		printk(KERN_ERR SFX "Can't read AMP-caps for 0x%x\n", nid);
		return err;
	}

	pin->amp_mute = LOLA_AMP_MUTE_CAPABLE(val);
	pin->amp_step_size = LOLA_AMP_STEP_SIZE(val);
	pin->amp_num_steps = LOLA_AMP_NUM_STEPS(val);
	if (pin->amp_num_steps) {
		/* zero as mute state */
		pin->amp_num_steps++;
		pin->amp_step_size++;
	}
	pin->amp_offset = LOLA_AMP_OFFSET(val);

	err = lola_codec_read(chip, nid, LOLA_VERB_GET_MAX_LEVEL, 0, 0, &val,
			      NULL);
	if (err < 0) {
		printk(KERN_ERR SFX "Can't get MAX_LEVEL 0x%x\n", nid);
		return err;
	}
	pin->max_level = val & 0x3ff;   /* 10 bits */

	pin->config_default_reg = 0;
	pin->fixed_gain_list_len = 0;
	pin->cur_gain_step = 0;

	return 0;
}

int __devinit lola_init_pins(struct lola *chip, int dir, int *nidp)
{
	int i, err, nid;
	nid = *nidp;
	for (i = 0; i < chip->pin[dir].num_pins; i++, nid++) {
		err = lola_init_pin(chip, &chip->pin[dir].pins[i], dir, nid);
		if (err < 0)
			return err;
		if (chip->pin[dir].pins[i].is_analog)
			chip->pin[dir].num_analog_pins++;
	}
	*nidp = nid;
	return 0;
}

void lola_free_mixer(struct lola *chip)
{
	if (chip->mixer.array_saved)
		vfree(chip->mixer.array_saved);
}

int __devinit lola_init_mixer_widget(struct lola *chip, int nid)
{
	unsigned int val;
	int err;

	err = lola_read_param(chip, nid, LOLA_PAR_AUDIO_WIDGET_CAP, &val);
	if (err < 0) {
		printk(KERN_ERR SFX "Can't read wcaps for 0x%x\n", nid);
		return err;
	}

	if ((val & 0xfff00000) != 0x02f00000) { /* test SubType and Type */
		snd_printdd("No valid mixer widget\n");
		return 0;
	}

	chip->mixer.nid = nid;
	chip->mixer.caps = val;
	chip->mixer.array = (struct lola_mixer_array __iomem *)
		(chip->bar[BAR1].remap_addr + LOLA_BAR1_SOURCE_GAIN_ENABLE);

	/* reserve memory to copy mixer data for sleep mode transitions */
	chip->mixer.array_saved = vmalloc(sizeof(struct lola_mixer_array));

	/* mixer matrix sources are physical input data and play streams */
	chip->mixer.src_stream_outs = chip->pcm[PLAY].num_streams;
	chip->mixer.src_phys_ins = chip->pin[CAPT].num_pins;

	/* mixer matrix destinations are record streams and physical output */
	chip->mixer.dest_stream_ins = chip->pcm[CAPT].num_streams;
	chip->mixer.dest_phys_outs = chip->pin[PLAY].num_pins;

	/* mixer matrix may have unused areas between PhysIn and
	 * Play or Record and PhysOut zones
	 */
	chip->mixer.src_stream_out_ofs = chip->mixer.src_phys_ins +
		LOLA_MIXER_SRC_INPUT_PLAY_SEPARATION(val);
	chip->mixer.dest_phys_out_ofs = chip->mixer.dest_stream_ins +
		LOLA_MIXER_DEST_REC_OUTPUT_SEPARATION(val);

	/* example : MixerMatrix of LoLa881 (LoLa16161 uses unused zones)
	 * +-+  0-------8------16-------8------16
	 * | |  |       |       |       |       |
	 * |s|  | INPUT |       | INPUT |       |
	 * | |->|  ->   |unused |  ->   |unused |
	 * |r|  |CAPTURE|       | OUTPUT|       |
	 * | |  |  MIX  |       |  MIX  |       |
	 * |c|  8--------------------------------
	 * | |  |       |       |       |       |
	 * | |  |       |       |       |       |
	 * |g|  |unused |unused |unused |unused |
	 * | |  |       |       |       |       |
	 * |a|  |       |       |       |       |
	 * | |  16-------------------------------
	 * |i|  |       |       |       |       |
	 * | |  | PLAYBK|       | PLAYBK|       |
	 * |n|->|  ->   |unused |  ->   |unused |
	 * | |  |CAPTURE|       | OUTPUT|       |
	 * | |  |  MIX  |       |  MIX  |       |
	 * |a|  8--------------------------------
	 * |r|  |       |       |       |       |
	 * |r|  |       |       |       |       |
	 * |a|  |unused |unused |unused |unused |
	 * |y|  |       |       |       |       |
	 * | |  |       |       |       |       |
	 * +++  16--|---------------|------------
	 *      +---V---------------V-----------+
	 *      |  dest_mix_gain_enable array   |
	 *      +-------------------------------+
	 */
	/* example : MixerMatrix of LoLa280
	 * +-+  0-------8-2
	 * | |  |       | |
	 * |s|  | INPUT | |     INPUT
	 * |r|->|  ->   | |      ->
	 * |c|  |CAPTURE| | <-  OUTPUT
	 * | |  |  MIX  | |      MIX
	 * |g|  8----------
	 * |a|  |       | |
	 * |i|  | PLAYBK| |     PLAYBACK
	 * |n|->|  ->   | |      ->
	 * | |  |CAPTURE| | <-  OUTPUT
	 * |a|  |  MIX  | |      MIX
	 * |r|  8---|----|-
	 * |r|  +---V----V-------------------+
	 * |a|  | dest_mix_gain_enable array |
	 * |y|  +----------------------------+
	 */
	if (chip->mixer.src_stream_out_ofs > MAX_AUDIO_INOUT_COUNT ||
	    chip->mixer.dest_phys_out_ofs > MAX_STREAM_IN_COUNT) {
		printk(KERN_ERR SFX "Invalid mixer widget size\n");
		return -EINVAL;
	}

	chip->mixer.src_mask = ((1U << chip->mixer.src_phys_ins) - 1) |
		(((1U << chip->mixer.src_stream_outs) - 1)
		 << chip->mixer.src_stream_out_ofs);
	chip->mixer.dest_mask = ((1U << chip->mixer.dest_stream_ins) - 1) |
		(((1U << chip->mixer.dest_phys_outs) - 1)
		 << chip->mixer.dest_phys_out_ofs);

	snd_printdd("Mixer src_mask=%x, dest_mask=%x\n",
		    chip->mixer.src_mask, chip->mixer.dest_mask);

	return 0;
}

static int lola_mixer_set_src_gain(struct lola *chip, unsigned int id,
				   unsigned short gain, bool on)
{
	unsigned int oldval, val;

	if (!(chip->mixer.src_mask & (1 << id)))
		return -EINVAL;
	oldval = val = readl(&chip->mixer.array->src_gain_enable);
	if (on)
		val |= (1 << id);
	else
		val &= ~(1 << id);
	/* test if values unchanged */
	if ((val == oldval) &&
	    (gain == readw(&chip->mixer.array->src_gain[id])))
		return 0;

	snd_printdd("lola_mixer_set_src_gain (id=%d, gain=%d) enable=%x\n",
			id, gain, val);
	writew(gain, &chip->mixer.array->src_gain[id]);
	writel(val, &chip->mixer.array->src_gain_enable);
	lola_codec_flush(chip);
	/* inform micro-controller about the new source gain */
	return lola_codec_write(chip, chip->mixer.nid,
				LOLA_VERB_SET_SOURCE_GAIN, id, 0);
}

#if 0 /* not used */
static int lola_mixer_set_src_gains(struct lola *chip, unsigned int mask,
				    unsigned short *gains)
{
	int i;

	if ((chip->mixer.src_mask & mask) != mask)
		return -EINVAL;
	for (i = 0; i < LOLA_MIXER_DIM; i++) {
		if (mask & (1 << i)) {
			writew(*gains, &chip->mixer.array->src_gain[i]);
			gains++;
		}
	}
	writel(mask, &chip->mixer.array->src_gain_enable);
	lola_codec_flush(chip);
	if (chip->mixer.caps & LOLA_PEAK_METER_CAN_AGC_MASK) {
		/* update for all srcs at once */
		return lola_codec_write(chip, chip->mixer.nid,
					LOLA_VERB_SET_SOURCE_GAIN, 0x80, 0);
	}
	/* update manually */
	for (i = 0; i < LOLA_MIXER_DIM; i++) {
		if (mask & (1 << i)) {
			lola_codec_write(chip, chip->mixer.nid,
					 LOLA_VERB_SET_SOURCE_GAIN, i, 0);
		}
	}
	return 0;
}
#endif /* not used */

static int lola_mixer_set_mapping_gain(struct lola *chip,
				       unsigned int src, unsigned int dest,
				       unsigned short gain, bool on)
{
	unsigned int val;

	if (!(chip->mixer.src_mask & (1 << src)) ||
	    !(chip->mixer.dest_mask & (1 << dest)))
		return -EINVAL;
	if (on)
		writew(gain, &chip->mixer.array->dest_mix_gain[dest][src]);
	val = readl(&chip->mixer.array->dest_mix_gain_enable[dest]);
	if (on)
		val |= (1 << src);
	else
		val &= ~(1 << src);
	writel(val, &chip->mixer.array->dest_mix_gain_enable[dest]);
	lola_codec_flush(chip);
	return lola_codec_write(chip, chip->mixer.nid, LOLA_VERB_SET_MIX_GAIN,
				src, dest);
}

#if 0 /* not used */
static int lola_mixer_set_dest_gains(struct lola *chip, unsigned int id,
				     unsigned int mask, unsigned short *gains)
{
	int i;

	if (!(chip->mixer.dest_mask & (1 << id)) ||
	    (chip->mixer.src_mask & mask) != mask)
		return -EINVAL;
	for (i = 0; i < LOLA_MIXER_DIM; i++) {
		if (mask & (1 << i)) {
			writew(*gains, &chip->mixer.array->dest_mix_gain[id][i]);
			gains++;
		}
	}
	writel(mask, &chip->mixer.array->dest_mix_gain_enable[id]);
	lola_codec_flush(chip);
	/* update for all dests at once */
	return lola_codec_write(chip, chip->mixer.nid,
				LOLA_VERB_SET_DESTINATION_GAIN, id, 0);
}
#endif /* not used */

/*
 */

static int set_analog_volume(struct lola *chip, int dir,
			     unsigned int idx, unsigned int val,
			     bool external_call);

int lola_setup_all_analog_gains(struct lola *chip, int dir, bool mute)
{
	struct lola_pin *pin;
	int idx, max_idx;

	pin = chip->pin[dir].pins;
	max_idx = chip->pin[dir].num_pins;
	for (idx = 0; idx < max_idx; idx++) {
		if (pin[idx].is_analog) {
			unsigned int val = mute ? 0 : pin[idx].cur_gain_step;
			/* set volume and do not save the value */
			set_analog_volume(chip, dir, idx, val, false);
		}
	}
	return lola_codec_flush(chip);
}

void lola_save_mixer(struct lola *chip)
{
	/* mute analog output */
	if (chip->mixer.array_saved) {
		/* store contents of mixer array */
		memcpy_fromio(chip->mixer.array_saved, chip->mixer.array,
			      sizeof(*chip->mixer.array));
	}
	lola_setup_all_analog_gains(chip, PLAY, true); /* output mute */
}

void lola_restore_mixer(struct lola *chip)
{
	int i;

	/*lola_reset_setups(chip);*/
	if (chip->mixer.array_saved) {
		/* restore contents of mixer array */
		memcpy_toio(chip->mixer.array, chip->mixer.array_saved,
			    sizeof(*chip->mixer.array));
		/* inform micro-controller about all restored values
		 * and ignore return values
		 */
		for (i = 0; i < chip->mixer.src_phys_ins; i++)
			lola_codec_write(chip, chip->mixer.nid,
					 LOLA_VERB_SET_SOURCE_GAIN,
					 i, 0);
		for (i = 0; i < chip->mixer.src_stream_outs; i++)
			lola_codec_write(chip, chip->mixer.nid,
					 LOLA_VERB_SET_SOURCE_GAIN,
					 chip->mixer.src_stream_out_ofs + i, 0);
		for (i = 0; i < chip->mixer.dest_stream_ins; i++)
			lola_codec_write(chip, chip->mixer.nid,
					 LOLA_VERB_SET_DESTINATION_GAIN,
					 i, 0);
		for (i = 0; i < chip->mixer.dest_phys_outs; i++)
			lola_codec_write(chip, chip->mixer.nid,
					 LOLA_VERB_SET_DESTINATION_GAIN,
					 chip->mixer.dest_phys_out_ofs + i, 0);
		lola_codec_flush(chip);
	}
}

/*
 */

static int set_analog_volume(struct lola *chip, int dir,
			     unsigned int idx, unsigned int val,
			     bool external_call)
{
	struct lola_pin *pin;
	int err;

	if (idx >= chip->pin[dir].num_pins)
		return -EINVAL;
	pin = &chip->pin[dir].pins[idx];
	if (!pin->is_analog || pin->amp_num_steps <= val)
		return -EINVAL;
	if (external_call && pin->cur_gain_step == val)
		return 0;
	if (external_call)
		lola_codec_flush(chip);
	snd_printdd("set_analog_volume (dir=%d idx=%d, volume=%d)\n",
			dir, idx, val);
	err = lola_codec_write(chip, pin->nid,
			       LOLA_VERB_SET_AMP_GAIN_MUTE, val, 0);
	if (err < 0)
		return err;
	if (external_call)
		pin->cur_gain_step = val;
	return 0;
}

int lola_set_src_config(struct lola *chip, unsigned int src_mask, bool update)
{
	int ret = 0;
	int success = 0;
	int n, err;

	/* SRC can be activated and the dwInputSRCMask is valid? */
	if ((chip->input_src_caps_mask & src_mask) != src_mask)
		return -EINVAL;
	/* handle all even Inputs - SRC is a stereo setting !!! */
	for (n = 0; n < chip->pin[CAPT].num_pins; n += 2) {
		unsigned int mask = 3U << n; /* handle the stereo case */
		unsigned int new_src, src_state;
		if (!(chip->input_src_caps_mask & mask))
			continue;
		/* if one IO needs SRC, both stereo IO will get SRC */
		new_src = (src_mask & mask) != 0;
		if (update) {
			src_state = (chip->input_src_mask & mask) != 0;
			if (src_state == new_src)
				continue;   /* nothing to change for this IO */
		}
		err = lola_codec_write(chip, chip->pcm[CAPT].streams[n].nid,
				       LOLA_VERB_SET_SRC, new_src, 0);
		if (!err)
			success++;
		else
			ret = err;
	}
	if (success)
		ret = lola_codec_flush(chip);
	if (!ret)
		chip->input_src_mask = src_mask;
	return ret;
}

/*
 */
static int init_mixer_values(struct lola *chip)
{
	int i;

	/* all sample rate converters on */
	lola_set_src_config(chip, (1 << chip->pin[CAPT].num_pins) - 1, false);

	/* clear all mixer matrix settings */
	memset_io(chip->mixer.array, 0, sizeof(*chip->mixer.array));
	/* inform firmware about all updated matrix columns - capture part */
	for (i = 0; i < chip->mixer.dest_stream_ins; i++)
		lola_codec_write(chip, chip->mixer.nid,
				 LOLA_VERB_SET_DESTINATION_GAIN,
				 i, 0);
	/* inform firmware about all updated matrix columns - output part */
	for (i = 0; i < chip->mixer.dest_phys_outs; i++)
		lola_codec_write(chip, chip->mixer.nid,
				 LOLA_VERB_SET_DESTINATION_GAIN,
				 chip->mixer.dest_phys_out_ofs + i, 0);

	/* set all digital input source (master) gains to 0dB */
	for (i = 0; i < chip->mixer.src_phys_ins; i++)
		lola_mixer_set_src_gain(chip, i, 336, true); /* 0dB */

	/* set all digital playback source (master) gains to 0dB */
	for (i = 0; i < chip->mixer.src_stream_outs; i++)
		lola_mixer_set_src_gain(chip,
					i + chip->mixer.src_stream_out_ofs,
					336, true); /* 0dB */
	/* set gain value 0dB diagonally in matrix - part INPUT -> CAPTURE */
	for (i = 0; i < chip->mixer.dest_stream_ins; i++) {
		int src = i % chip->mixer.src_phys_ins;
		lola_mixer_set_mapping_gain(chip, src, i, 336, true);
	}
	/* set gain value 0dB diagonally in matrix , part PLAYBACK -> OUTPUT
	 * (LoLa280 : playback channel 0,2,4,6 linked to output channel 0)
	 * (LoLa280 : playback channel 1,3,5,7 linked to output channel 1)
	 */
	for (i = 0; i < chip->mixer.src_stream_outs; i++) {
		int src = chip->mixer.src_stream_out_ofs + i;
		int dst = chip->mixer.dest_phys_out_ofs +
			i % chip->mixer.dest_phys_outs;
		lola_mixer_set_mapping_gain(chip, src, dst, 336, true);
	}
	return 0;
}

/*
 * analog mixer control element
 */
static int lola_analog_vol_info(struct snd_kcontrol *kcontrol,
				struct snd_ctl_elem_info *uinfo)
{
	struct lola *chip = snd_kcontrol_chip(kcontrol);
	int dir = kcontrol->private_value;

	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
	uinfo->count = chip->pin[dir].num_pins;
	uinfo->value.integer.min = 0;
	uinfo->value.integer.max = chip->pin[dir].pins[0].amp_num_steps;
	return 0;
}

static int lola_analog_vol_get(struct snd_kcontrol *kcontrol,
			       struct snd_ctl_elem_value *ucontrol)
{
	struct lola *chip = snd_kcontrol_chip(kcontrol);
	int dir = kcontrol->private_value;
	int i;

	for (i = 0; i < chip->pin[dir].num_pins; i++)
		ucontrol->value.integer.value[i] =
			chip->pin[dir].pins[i].cur_gain_step;
	return 0;
}

static int lola_analog_vol_put(struct snd_kcontrol *kcontrol,
			       struct snd_ctl_elem_value *ucontrol)
{
	struct lola *chip = snd_kcontrol_chip(kcontrol);
	int dir = kcontrol->private_value;
	int i, err;

	for (i = 0; i < chip->pin[dir].num_pins; i++) {
		err = set_analog_volume(chip, dir, i,
					ucontrol->value.integer.value[i],
					true);
		if (err < 0)
			return err;
	}
	return 0;
}

static int lola_analog_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
			       unsigned int size, unsigned int __user *tlv)
{
	struct lola *chip = snd_kcontrol_chip(kcontrol);
	int dir = kcontrol->private_value;
	unsigned int val1, val2;
	struct lola_pin *pin;

	if (size < 4 * sizeof(unsigned int))
		return -ENOMEM;
	pin = &chip->pin[dir].pins[0];

	val2 = pin->amp_step_size * 25;
	val1 = -1 * (int)pin->amp_offset * (int)val2;
#ifdef TLV_DB_SCALE_MUTE
	val2 |= TLV_DB_SCALE_MUTE;
#endif
	if (put_user(SNDRV_CTL_TLVT_DB_SCALE, tlv))
		return -EFAULT;
	if (put_user(2 * sizeof(unsigned int), tlv + 1))
		return -EFAULT;
	if (put_user(val1, tlv + 2))
		return -EFAULT;
	if (put_user(val2, tlv + 3))
		return -EFAULT;
	return 0;
}

static struct snd_kcontrol_new lola_analog_mixer __devinitdata = {
	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
	.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
		   SNDRV_CTL_ELEM_ACCESS_TLV_READ |
		   SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK),
	.info = lola_analog_vol_info,
	.get = lola_analog_vol_get,
	.put = lola_analog_vol_put,
	.tlv.c = lola_analog_vol_tlv,
};

static int __devinit create_analog_mixer(struct lola *chip, int dir, char *name)
{
	if (!chip->pin[dir].num_pins)
		return 0;
	/* no analog volumes on digital only adapters */
	if (chip->pin[dir].num_pins != chip->pin[dir].num_analog_pins)
		return 0;
	lola_analog_mixer.name = name;
	lola_analog_mixer.private_value = dir;
	return snd_ctl_add(chip->card,
			   snd_ctl_new1(&lola_analog_mixer, chip));
}

/*
 * Hardware sample rate converter on digital input
 */
static int lola_input_src_info(struct snd_kcontrol *kcontrol,
			       struct snd_ctl_elem_info *uinfo)
{
	struct lola *chip = snd_kcontrol_chip(kcontrol);

	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
	uinfo->count = chip->pin[CAPT].num_pins;
	uinfo->value.integer.min = 0;
	uinfo->value.integer.max = 1;
	return 0;
}

static int lola_input_src_get(struct snd_kcontrol *kcontrol,
			      struct snd_ctl_elem_value *ucontrol)
{
	struct lola *chip = snd_kcontrol_chip(kcontrol);
	int i;

	for (i = 0; i < chip->pin[CAPT].num_pins; i++)
		ucontrol->value.integer.value[i] =
			!!(chip->input_src_mask & (1 << i));
	return 0;
}

static int lola_input_src_put(struct snd_kcontrol *kcontrol,
			      struct snd_ctl_elem_value *ucontrol)
{
	struct lola *chip = snd_kcontrol_chip(kcontrol);
	int i;
	unsigned int mask;

	mask = 0;
	for (i = 0; i < chip->pin[CAPT].num_pins; i++)
		if (ucontrol->value.integer.value[i])
			mask |= 1 << i;
	return lola_set_src_config(chip, mask, true);
}

static struct snd_kcontrol_new lola_input_src_mixer __devinitdata = {
	.name = "Digital SRC Capture Switch",
	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
	.info = lola_input_src_info,
	.get = lola_input_src_get,
	.put = lola_input_src_put,
};

/*
 * Lola16161 or Lola881 can have Hardware sample rate converters
 * on its digital input pins
 */
static int __devinit create_input_src_mixer(struct lola *chip)
{
	if (!chip->input_src_caps_mask)
		return 0;

	return snd_ctl_add(chip->card,
			   snd_ctl_new1(&lola_input_src_mixer, chip));
}

/*
 * src gain mixer
 */
static int lola_src_gain_info(struct snd_kcontrol *kcontrol,
			      struct snd_ctl_elem_info *uinfo)
{
	unsigned int count = (kcontrol->private_value >> 8) & 0xff;

	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
	uinfo->count = count;
	uinfo->value.integer.min = 0;
	uinfo->value.integer.max = 409;
	return 0;
}

static int lola_src_gain_get(struct snd_kcontrol *kcontrol,
			     struct snd_ctl_elem_value *ucontrol)
{
	struct lola *chip = snd_kcontrol_chip(kcontrol);
	unsigned int ofs = kcontrol->private_value & 0xff;
	unsigned int count = (kcontrol->private_value >> 8) & 0xff;
	unsigned int mask, i;

	mask = readl(&chip->mixer.array->src_gain_enable);
	for (i = 0; i < count; i++) {
		unsigned int idx = ofs + i;
		unsigned short val;
		if (!(chip->mixer.src_mask & (1 << idx)))
			return -EINVAL;
		if (mask & (1 << idx))
			val = readw(&chip->mixer.array->src_gain[idx]) + 1;
		else
			val = 0;
		ucontrol->value.integer.value[i] = val;
	}
	return 0;
}

static int lola_src_gain_put(struct snd_kcontrol *kcontrol,
			     struct snd_ctl_elem_value *ucontrol)
{
	struct lola *chip = snd_kcontrol_chip(kcontrol);
	unsigned int ofs = kcontrol->private_value & 0xff;
	unsigned int count = (kcontrol->private_value >> 8) & 0xff;
	int i, err;

	for (i = 0; i < count; i++) {
		unsigned int idx = ofs + i;
		unsigned short val = ucontrol->value.integer.value[i];
		if (val)
			val--;
		err = lola_mixer_set_src_gain(chip, idx, val, !!val);
		if (err < 0)
			return err;
	}
	return 0;
}

/* raw value: 0 = -84dB, 336 = 0dB, 408=18dB, incremented 1 for mute */
static const DECLARE_TLV_DB_SCALE(lola_src_gain_tlv, -8425, 25, 1);

static struct snd_kcontrol_new lola_src_gain_mixer __devinitdata = {
	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
	.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
		   SNDRV_CTL_ELEM_ACCESS_TLV_READ),
	.info = lola_src_gain_info,
	.get = lola_src_gain_get,
	.put = lola_src_gain_put,
	.tlv.p = lola_src_gain_tlv,
};

static int __devinit create_src_gain_mixer(struct lola *chip,
					   int num, int ofs, char *name)
{
	lola_src_gain_mixer.name = name;
	lola_src_gain_mixer.private_value = ofs + (num << 8);
	return snd_ctl_add(chip->card,
			   snd_ctl_new1(&lola_src_gain_mixer, chip));
}

#if 0 /* not used */
/*
 * destination gain (matrix-like) mixer
 */
static int lola_dest_gain_info(struct snd_kcontrol *kcontrol,
			       struct snd_ctl_elem_info *uinfo)
{
	unsigned int src_num = (kcontrol->private_value >> 8) & 0xff;

	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
	uinfo->count = src_num;
	uinfo->value.integer.min = 0;
	uinfo->value.integer.max = 433;
	return 0;
}

static int lola_dest_gain_get(struct snd_kcontrol *kcontrol,
			      struct snd_ctl_elem_value *ucontrol)
{
	struct lola *chip = snd_kcontrol_chip(kcontrol);
	unsigned int src_ofs = kcontrol->private_value & 0xff;
	unsigned int src_num = (kcontrol->private_value >> 8) & 0xff;
	unsigned int dst_ofs = (kcontrol->private_value >> 16) & 0xff;
	unsigned int dst, mask, i;

	dst = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + dst_ofs;
	mask = readl(&chip->mixer.array->dest_mix_gain_enable[dst]);
	for (i = 0; i < src_num; i++) {
		unsigned int src = src_ofs + i;
		unsigned short val;
		if (!(chip->mixer.src_mask & (1 << src)))
			return -EINVAL;
		if (mask & (1 << dst))
			val = readw(&chip->mixer.array->dest_mix_gain[dst][src]) + 1;
		else
			val = 0;
		ucontrol->value.integer.value[i] = val;
	}
	return 0;
}

static int lola_dest_gain_put(struct snd_kcontrol *kcontrol,
			      struct snd_ctl_elem_value *ucontrol)
{
	struct lola *chip = snd_kcontrol_chip(kcontrol);
	unsigned int src_ofs = kcontrol->private_value & 0xff;
	unsigned int src_num = (kcontrol->private_value >> 8) & 0xff;
	unsigned int dst_ofs = (kcontrol->private_value >> 16) & 0xff;
	unsigned int dst, mask;
	unsigned short gains[MAX_STREAM_COUNT];
	int i, num;

	mask = 0;
	num = 0;
	for (i = 0; i < src_num; i++) {
		unsigned short val = ucontrol->value.integer.value[i];
		if (val) {
			gains[num++] = val - 1;
			mask |= 1 << i;
		}
	}
	mask <<= src_ofs;
	dst = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + dst_ofs;
	return lola_mixer_set_dest_gains(chip, dst, mask, gains);
}

static const DECLARE_TLV_DB_SCALE(lola_dest_gain_tlv, -8425, 25, 1);

static struct snd_kcontrol_new lola_dest_gain_mixer __devinitdata = {
	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
	.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
		   SNDRV_CTL_ELEM_ACCESS_TLV_READ),
	.info = lola_dest_gain_info,
	.get = lola_dest_gain_get,
	.put = lola_dest_gain_put,
	.tlv.p = lola_dest_gain_tlv,
};

static int __devinit create_dest_gain_mixer(struct lola *chip,
					    int src_num, int src_ofs,
					    int num, int ofs, char *name)
{
	lola_dest_gain_mixer.count = num;
	lola_dest_gain_mixer.name = name;
	lola_dest_gain_mixer.private_value =
		src_ofs + (src_num << 8) + (ofs << 16) + (num << 24);
	return snd_ctl_add(chip->card,
			  snd_ctl_new1(&lola_dest_gain_mixer, chip));
}
#endif /* not used */

/*
 */
int __devinit lola_create_mixer(struct lola *chip)
{
	int err;

	err = create_analog_mixer(chip, PLAY, "Analog Playback Volume");
	if (err < 0)
		return err;
	err = create_analog_mixer(chip, CAPT, "Analog Capture Volume");
	if (err < 0)
		return err;
	err = create_input_src_mixer(chip);
	if (err < 0)
		return err;
	err = create_src_gain_mixer(chip, chip->mixer.src_phys_ins, 0,
				    "Digital Capture Volume");
	if (err < 0)
		return err;
	err = create_src_gain_mixer(chip, chip->mixer.src_stream_outs,
				    chip->mixer.src_stream_out_ofs,
				    "Digital Playback Volume");
	if (err < 0)
		return err;
#if 0
/* FIXME: buggy mixer matrix handling */
	err = create_dest_gain_mixer(chip,
				     chip->mixer.src_phys_ins, 0,
				     chip->mixer.dest_stream_ins, 0,
				     "Line Capture Volume");
	if (err < 0)
		return err;
	err = create_dest_gain_mixer(chip,
				     chip->mixer.src_stream_outs,
				     chip->mixer.src_stream_out_ofs,
				     chip->mixer.dest_stream_ins, 0,
				     "Stream-Loopback Capture Volume");
	if (err < 0)
		return err;
	err = create_dest_gain_mixer(chip,
				     chip->mixer.src_phys_ins, 0,
				     chip->mixer.dest_phys_outs,
				     chip->mixer.dest_phys_out_ofs,
				     "Line-Loopback Playback Volume");
	if (err < 0)
		return err;
	err = create_dest_gain_mixer(chip,
				     chip->mixer.src_stream_outs,
				     chip->mixer.src_stream_out_ofs,
				     chip->mixer.dest_phys_outs,
				     chip->mixer.dest_phys_out_ofs,
				     "Stream Playback Volume");
	if (err < 0)
		return err;
#endif /* FIXME */
	return init_mixer_values(chip);
}
