Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *  Support for Digigram Lola PCI-e boards
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *  Copyright (c) 2011 Takashi Iwai <tiwai@suse.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/vmalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <sound/core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <sound/control.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <sound/pcm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <sound/tlv.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include "lola.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) static int lola_init_pin(struct lola *chip, struct lola_pin *pin,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 			 int dir, int nid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 	unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 	pin->nid = nid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 	err = lola_read_param(chip, nid, LOLA_PAR_AUDIO_WIDGET_CAP, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 	if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 		dev_err(chip->card->dev, "Can't read wcaps for 0x%x\n", nid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	val &= 0x00f00fff; /* test TYPE and bits 0..11 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	if (val == 0x00400200)    /* Type = 4, Digital = 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 		pin->is_analog = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	else if (val == 0x0040000a && dir == CAPT) /* Dig=0, InAmp/ovrd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 		pin->is_analog = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	else if (val == 0x0040000c && dir == PLAY) /* Dig=0, OutAmp/ovrd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 		pin->is_analog = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 		dev_err(chip->card->dev, "Invalid wcaps 0x%x for 0x%x\n", val, nid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	/* analog parameters only following, so continue in case of Digital pin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	if (!pin->is_analog)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	if (dir == PLAY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 		err = lola_read_param(chip, nid, LOLA_PAR_AMP_OUT_CAP, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 		err = lola_read_param(chip, nid, LOLA_PAR_AMP_IN_CAP, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 		dev_err(chip->card->dev, "Can't read AMP-caps for 0x%x\n", nid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	pin->amp_mute = LOLA_AMP_MUTE_CAPABLE(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	pin->amp_step_size = LOLA_AMP_STEP_SIZE(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	pin->amp_num_steps = LOLA_AMP_NUM_STEPS(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	if (pin->amp_num_steps) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 		/* zero as mute state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 		pin->amp_num_steps++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 		pin->amp_step_size++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	pin->amp_offset = LOLA_AMP_OFFSET(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	err = lola_codec_read(chip, nid, LOLA_VERB_GET_MAX_LEVEL, 0, 0, &val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 			      NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 		dev_err(chip->card->dev, "Can't get MAX_LEVEL 0x%x\n", nid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	pin->max_level = val & 0x3ff;   /* 10 bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	pin->config_default_reg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	pin->fixed_gain_list_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	pin->cur_gain_step = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) int lola_init_pins(struct lola *chip, int dir, int *nidp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	int i, err, nid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	nid = *nidp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	for (i = 0; i < chip->pin[dir].num_pins; i++, nid++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 		err = lola_init_pin(chip, &chip->pin[dir].pins[i], dir, nid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 		if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 		if (chip->pin[dir].pins[i].is_analog)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 			chip->pin[dir].num_analog_pins++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	*nidp = nid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) void lola_free_mixer(struct lola *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	vfree(chip->mixer.array_saved);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) int lola_init_mixer_widget(struct lola *chip, int nid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	err = lola_read_param(chip, nid, LOLA_PAR_AUDIO_WIDGET_CAP, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 		dev_err(chip->card->dev, "Can't read wcaps for 0x%x\n", nid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	if ((val & 0xfff00000) != 0x02f00000) { /* test SubType and Type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 		dev_dbg(chip->card->dev, "No valid mixer widget\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	chip->mixer.nid = nid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	chip->mixer.caps = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	chip->mixer.array = (struct lola_mixer_array __iomem *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 		(chip->bar[BAR1].remap_addr + LOLA_BAR1_SOURCE_GAIN_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	/* reserve memory to copy mixer data for sleep mode transitions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	chip->mixer.array_saved = vmalloc(sizeof(struct lola_mixer_array));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	/* mixer matrix sources are physical input data and play streams */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	chip->mixer.src_stream_outs = chip->pcm[PLAY].num_streams;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	chip->mixer.src_phys_ins = chip->pin[CAPT].num_pins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	/* mixer matrix destinations are record streams and physical output */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	chip->mixer.dest_stream_ins = chip->pcm[CAPT].num_streams;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	chip->mixer.dest_phys_outs = chip->pin[PLAY].num_pins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	/* mixer matrix may have unused areas between PhysIn and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	 * Play or Record and PhysOut zones
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	chip->mixer.src_stream_out_ofs = chip->mixer.src_phys_ins +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 		LOLA_MIXER_SRC_INPUT_PLAY_SEPARATION(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	chip->mixer.dest_phys_out_ofs = chip->mixer.dest_stream_ins +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 		LOLA_MIXER_DEST_REC_OUTPUT_SEPARATION(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	/* example : MixerMatrix of LoLa881 (LoLa16161 uses unused zones)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	 * +-+  0-------8------16-------8------16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	 * | |  |       |       |       |       |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	 * |s|  | INPUT |       | INPUT |       |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	 * | |->|  ->   |unused |  ->   |unused |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	 * |r|  |CAPTURE|       | OUTPUT|       |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	 * | |  |  MIX  |       |  MIX  |       |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	 * |c|  8--------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	 * | |  |       |       |       |       |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	 * | |  |       |       |       |       |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	 * |g|  |unused |unused |unused |unused |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	 * | |  |       |       |       |       |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	 * |a|  |       |       |       |       |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	 * | |  16-------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	 * |i|  |       |       |       |       |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	 * | |  | PLAYBK|       | PLAYBK|       |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	 * |n|->|  ->   |unused |  ->   |unused |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	 * | |  |CAPTURE|       | OUTPUT|       |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	 * | |  |  MIX  |       |  MIX  |       |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	 * |a|  8--------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	 * |r|  |       |       |       |       |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	 * |r|  |       |       |       |       |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	 * |a|  |unused |unused |unused |unused |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	 * |y|  |       |       |       |       |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	 * | |  |       |       |       |       |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	 * +++  16--|---------------|------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	 *      +---V---------------V-----------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	 *      |  dest_mix_gain_enable array   |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	 *      +-------------------------------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	/* example : MixerMatrix of LoLa280
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	 * +-+  0-------8-2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	 * | |  |       | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	 * |s|  | INPUT | |     INPUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	 * |r|->|  ->   | |      ->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	 * |c|  |CAPTURE| | <-  OUTPUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	 * | |  |  MIX  | |      MIX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	 * |g|  8----------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	 * |a|  |       | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	 * |i|  | PLAYBK| |     PLAYBACK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	 * |n|->|  ->   | |      ->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	 * | |  |CAPTURE| | <-  OUTPUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	 * |a|  |  MIX  | |      MIX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	 * |r|  8---|----|-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	 * |r|  +---V----V-------------------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	 * |a|  | dest_mix_gain_enable array |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	 * |y|  +----------------------------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	if (chip->mixer.src_stream_out_ofs > MAX_AUDIO_INOUT_COUNT ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	    chip->mixer.dest_phys_out_ofs > MAX_STREAM_IN_COUNT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 		dev_err(chip->card->dev, "Invalid mixer widget size\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	chip->mixer.src_mask = ((1U << chip->mixer.src_phys_ins) - 1) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 		(((1U << chip->mixer.src_stream_outs) - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 		 << chip->mixer.src_stream_out_ofs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	chip->mixer.dest_mask = ((1U << chip->mixer.dest_stream_ins) - 1) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 		(((1U << chip->mixer.dest_phys_outs) - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 		 << chip->mixer.dest_phys_out_ofs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	dev_dbg(chip->card->dev, "Mixer src_mask=%x, dest_mask=%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 		    chip->mixer.src_mask, chip->mixer.dest_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) static int lola_mixer_set_src_gain(struct lola *chip, unsigned int id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 				   unsigned short gain, bool on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	unsigned int oldval, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	if (!(chip->mixer.src_mask & (1 << id)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	oldval = val = readl(&chip->mixer.array->src_gain_enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	if (on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 		val |= (1 << id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 		val &= ~(1 << id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	/* test if values unchanged */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	if ((val == oldval) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	    (gain == readw(&chip->mixer.array->src_gain[id])))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	dev_dbg(chip->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 		"lola_mixer_set_src_gain (id=%d, gain=%d) enable=%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 			id, gain, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	writew(gain, &chip->mixer.array->src_gain[id]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	writel(val, &chip->mixer.array->src_gain_enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	lola_codec_flush(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	/* inform micro-controller about the new source gain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	return lola_codec_write(chip, chip->mixer.nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 				LOLA_VERB_SET_SOURCE_GAIN, id, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) #if 0 /* not used */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) static int lola_mixer_set_src_gains(struct lola *chip, unsigned int mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 				    unsigned short *gains)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	if ((chip->mixer.src_mask & mask) != mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	for (i = 0; i < LOLA_MIXER_DIM; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 		if (mask & (1 << i)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 			writew(*gains, &chip->mixer.array->src_gain[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 			gains++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	writel(mask, &chip->mixer.array->src_gain_enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	lola_codec_flush(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	if (chip->mixer.caps & LOLA_PEAK_METER_CAN_AGC_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 		/* update for all srcs at once */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 		return lola_codec_write(chip, chip->mixer.nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 					LOLA_VERB_SET_SOURCE_GAIN, 0x80, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	/* update manually */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 	for (i = 0; i < LOLA_MIXER_DIM; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 		if (mask & (1 << i)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 			lola_codec_write(chip, chip->mixer.nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 					 LOLA_VERB_SET_SOURCE_GAIN, i, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) #endif /* not used */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) static int lola_mixer_set_mapping_gain(struct lola *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 				       unsigned int src, unsigned int dest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 				       unsigned short gain, bool on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	if (!(chip->mixer.src_mask & (1 << src)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 	    !(chip->mixer.dest_mask & (1 << dest)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	if (on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 		writew(gain, &chip->mixer.array->dest_mix_gain[dest][src]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	val = readl(&chip->mixer.array->dest_mix_gain_enable[dest]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	if (on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 		val |= (1 << src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 		val &= ~(1 << src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	writel(val, &chip->mixer.array->dest_mix_gain_enable[dest]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	lola_codec_flush(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	return lola_codec_write(chip, chip->mixer.nid, LOLA_VERB_SET_MIX_GAIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 				src, dest);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) #if 0 /* not used */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) static int lola_mixer_set_dest_gains(struct lola *chip, unsigned int id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 				     unsigned int mask, unsigned short *gains)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	if (!(chip->mixer.dest_mask & (1 << id)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	    (chip->mixer.src_mask & mask) != mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	for (i = 0; i < LOLA_MIXER_DIM; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 		if (mask & (1 << i)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 			writew(*gains, &chip->mixer.array->dest_mix_gain[id][i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 			gains++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	writel(mask, &chip->mixer.array->dest_mix_gain_enable[id]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	lola_codec_flush(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	/* update for all dests at once */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	return lola_codec_write(chip, chip->mixer.nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 				LOLA_VERB_SET_DESTINATION_GAIN, id, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) #endif /* not used */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) static int set_analog_volume(struct lola *chip, int dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 			     unsigned int idx, unsigned int val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 			     bool external_call);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) int lola_setup_all_analog_gains(struct lola *chip, int dir, bool mute)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	struct lola_pin *pin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	int idx, max_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	pin = chip->pin[dir].pins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	max_idx = chip->pin[dir].num_pins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	for (idx = 0; idx < max_idx; idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 		if (pin[idx].is_analog) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 			unsigned int val = mute ? 0 : pin[idx].cur_gain_step;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 			/* set volume and do not save the value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 			set_analog_volume(chip, dir, idx, val, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	return lola_codec_flush(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) void lola_save_mixer(struct lola *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	/* mute analog output */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	if (chip->mixer.array_saved) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 		/* store contents of mixer array */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 		memcpy_fromio(chip->mixer.array_saved, chip->mixer.array,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 			      sizeof(*chip->mixer.array));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 	lola_setup_all_analog_gains(chip, PLAY, true); /* output mute */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) void lola_restore_mixer(struct lola *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 	/*lola_reset_setups(chip);*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	if (chip->mixer.array_saved) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 		/* restore contents of mixer array */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 		memcpy_toio(chip->mixer.array, chip->mixer.array_saved,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 			    sizeof(*chip->mixer.array));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 		/* inform micro-controller about all restored values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 		 * and ignore return values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 		for (i = 0; i < chip->mixer.src_phys_ins; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 			lola_codec_write(chip, chip->mixer.nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 					 LOLA_VERB_SET_SOURCE_GAIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 					 i, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 		for (i = 0; i < chip->mixer.src_stream_outs; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 			lola_codec_write(chip, chip->mixer.nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 					 LOLA_VERB_SET_SOURCE_GAIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 					 chip->mixer.src_stream_out_ofs + i, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 		for (i = 0; i < chip->mixer.dest_stream_ins; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 			lola_codec_write(chip, chip->mixer.nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 					 LOLA_VERB_SET_DESTINATION_GAIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 					 i, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 		for (i = 0; i < chip->mixer.dest_phys_outs; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 			lola_codec_write(chip, chip->mixer.nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 					 LOLA_VERB_SET_DESTINATION_GAIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 					 chip->mixer.dest_phys_out_ofs + i, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 		lola_codec_flush(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) static int set_analog_volume(struct lola *chip, int dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 			     unsigned int idx, unsigned int val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 			     bool external_call)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	struct lola_pin *pin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 	if (idx >= chip->pin[dir].num_pins)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 	pin = &chip->pin[dir].pins[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 	if (!pin->is_analog || pin->amp_num_steps <= val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 	if (external_call && pin->cur_gain_step == val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 	if (external_call)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 		lola_codec_flush(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 	dev_dbg(chip->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 		"set_analog_volume (dir=%d idx=%d, volume=%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 			dir, idx, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 	err = lola_codec_write(chip, pin->nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 			       LOLA_VERB_SET_AMP_GAIN_MUTE, val, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 	if (external_call)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 		pin->cur_gain_step = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) int lola_set_src_config(struct lola *chip, unsigned int src_mask, bool update)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 	int success = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 	int n, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 	/* SRC can be activated and the dwInputSRCMask is valid? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 	if ((chip->input_src_caps_mask & src_mask) != src_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 	/* handle all even Inputs - SRC is a stereo setting !!! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 	for (n = 0; n < chip->pin[CAPT].num_pins; n += 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 		unsigned int mask = 3U << n; /* handle the stereo case */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 		unsigned int new_src, src_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 		if (!(chip->input_src_caps_mask & mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 		/* if one IO needs SRC, both stereo IO will get SRC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 		new_src = (src_mask & mask) != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 		if (update) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 			src_state = (chip->input_src_mask & mask) != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 			if (src_state == new_src)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 				continue;   /* nothing to change for this IO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 		err = lola_codec_write(chip, chip->pcm[CAPT].streams[n].nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 				       LOLA_VERB_SET_SRC, new_src, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 		if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 			success++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 			ret = err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 	if (success)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 		ret = lola_codec_flush(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 	if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 		chip->input_src_mask = src_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) static int init_mixer_values(struct lola *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 	/* all sample rate converters on */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 	lola_set_src_config(chip, (1 << chip->pin[CAPT].num_pins) - 1, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 	/* clear all mixer matrix settings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 	memset_io(chip->mixer.array, 0, sizeof(*chip->mixer.array));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 	/* inform firmware about all updated matrix columns - capture part */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 	for (i = 0; i < chip->mixer.dest_stream_ins; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 		lola_codec_write(chip, chip->mixer.nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 				 LOLA_VERB_SET_DESTINATION_GAIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 				 i, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 	/* inform firmware about all updated matrix columns - output part */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 	for (i = 0; i < chip->mixer.dest_phys_outs; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 		lola_codec_write(chip, chip->mixer.nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 				 LOLA_VERB_SET_DESTINATION_GAIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 				 chip->mixer.dest_phys_out_ofs + i, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 	/* set all digital input source (master) gains to 0dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 	for (i = 0; i < chip->mixer.src_phys_ins; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 		lola_mixer_set_src_gain(chip, i, 336, true); /* 0dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 	/* set all digital playback source (master) gains to 0dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 	for (i = 0; i < chip->mixer.src_stream_outs; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 		lola_mixer_set_src_gain(chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 					i + chip->mixer.src_stream_out_ofs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 					336, true); /* 0dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 	/* set gain value 0dB diagonally in matrix - part INPUT -> CAPTURE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 	for (i = 0; i < chip->mixer.dest_stream_ins; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 		int src = i % chip->mixer.src_phys_ins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 		lola_mixer_set_mapping_gain(chip, src, i, 336, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 	/* set gain value 0dB diagonally in matrix , part PLAYBACK -> OUTPUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 	 * (LoLa280 : playback channel 0,2,4,6 linked to output channel 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 	 * (LoLa280 : playback channel 1,3,5,7 linked to output channel 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 	for (i = 0; i < chip->mixer.src_stream_outs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 		int src = chip->mixer.src_stream_out_ofs + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 		int dst = chip->mixer.dest_phys_out_ofs +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 			i % chip->mixer.dest_phys_outs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 		lola_mixer_set_mapping_gain(chip, src, dst, 336, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)  * analog mixer control element
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) static int lola_analog_vol_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 				struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 	struct lola *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 	int dir = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 	uinfo->count = chip->pin[dir].num_pins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 	uinfo->value.integer.min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 	uinfo->value.integer.max = chip->pin[dir].pins[0].amp_num_steps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) static int lola_analog_vol_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 			       struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 	struct lola *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 	int dir = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 	for (i = 0; i < chip->pin[dir].num_pins; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 		ucontrol->value.integer.value[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 			chip->pin[dir].pins[i].cur_gain_step;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) static int lola_analog_vol_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 			       struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 	struct lola *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 	int dir = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 	int i, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 	for (i = 0; i < chip->pin[dir].num_pins; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 		err = set_analog_volume(chip, dir, i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 					ucontrol->value.integer.value[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 					true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 		if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) static int lola_analog_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 			       unsigned int size, unsigned int __user *tlv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 	struct lola *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 	int dir = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 	unsigned int val1, val2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 	struct lola_pin *pin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 	if (size < 4 * sizeof(unsigned int))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 	pin = &chip->pin[dir].pins[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 	val2 = pin->amp_step_size * 25;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 	val1 = -1 * (int)pin->amp_offset * (int)val2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) #ifdef TLV_DB_SCALE_MUTE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 	val2 |= TLV_DB_SCALE_MUTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 	if (put_user(SNDRV_CTL_TLVT_DB_SCALE, tlv))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 	if (put_user(2 * sizeof(unsigned int), tlv + 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 	if (put_user(val1, tlv + 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 	if (put_user(val2, tlv + 3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) static struct snd_kcontrol_new lola_analog_mixer = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 	.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 		   SNDRV_CTL_ELEM_ACCESS_TLV_READ |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 		   SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 	.info = lola_analog_vol_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 	.get = lola_analog_vol_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 	.put = lola_analog_vol_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 	.tlv.c = lola_analog_vol_tlv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) static int create_analog_mixer(struct lola *chip, int dir, char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 	if (!chip->pin[dir].num_pins)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 	/* no analog volumes on digital only adapters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 	if (chip->pin[dir].num_pins != chip->pin[dir].num_analog_pins)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 	lola_analog_mixer.name = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 	lola_analog_mixer.private_value = dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 	return snd_ctl_add(chip->card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 			   snd_ctl_new1(&lola_analog_mixer, chip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)  * Hardware sample rate converter on digital input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) static int lola_input_src_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 			       struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 	struct lola *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 	uinfo->count = chip->pin[CAPT].num_pins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 	uinfo->value.integer.min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 	uinfo->value.integer.max = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) static int lola_input_src_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 			      struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 	struct lola *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 	for (i = 0; i < chip->pin[CAPT].num_pins; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 		ucontrol->value.integer.value[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 			!!(chip->input_src_mask & (1 << i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) static int lola_input_src_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 			      struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 	struct lola *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 	unsigned int mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 	mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 	for (i = 0; i < chip->pin[CAPT].num_pins; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 		if (ucontrol->value.integer.value[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 			mask |= 1 << i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 	return lola_set_src_config(chip, mask, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) static const struct snd_kcontrol_new lola_input_src_mixer = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 	.name = "Digital SRC Capture Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 	.info = lola_input_src_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 	.get = lola_input_src_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) 	.put = lola_input_src_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)  * Lola16161 or Lola881 can have Hardware sample rate converters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)  * on its digital input pins
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) static int create_input_src_mixer(struct lola *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 	if (!chip->input_src_caps_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 	return snd_ctl_add(chip->card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 			   snd_ctl_new1(&lola_input_src_mixer, chip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)  * src gain mixer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) static int lola_src_gain_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 			      struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 	unsigned int count = (kcontrol->private_value >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) 	uinfo->count = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 	uinfo->value.integer.min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 	uinfo->value.integer.max = 409;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) static int lola_src_gain_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 			     struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 	struct lola *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 	unsigned int ofs = kcontrol->private_value & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 	unsigned int count = (kcontrol->private_value >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 	unsigned int mask, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) 	mask = readl(&chip->mixer.array->src_gain_enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) 	for (i = 0; i < count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) 		unsigned int idx = ofs + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) 		unsigned short val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) 		if (!(chip->mixer.src_mask & (1 << idx)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 		if (mask & (1 << idx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) 			val = readw(&chip->mixer.array->src_gain[idx]) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 			val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) 		ucontrol->value.integer.value[i] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) static int lola_src_gain_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) 			     struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) 	struct lola *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) 	unsigned int ofs = kcontrol->private_value & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) 	unsigned int count = (kcontrol->private_value >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) 	int i, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) 	for (i = 0; i < count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) 		unsigned int idx = ofs + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) 		unsigned short val = ucontrol->value.integer.value[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 		if (val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 			val--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) 		err = lola_mixer_set_src_gain(chip, idx, val, !!val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) 		if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) /* raw value: 0 = -84dB, 336 = 0dB, 408=18dB, incremented 1 for mute */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) static const DECLARE_TLV_DB_SCALE(lola_src_gain_tlv, -8425, 25, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) static struct snd_kcontrol_new lola_src_gain_mixer = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) 	.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) 		   SNDRV_CTL_ELEM_ACCESS_TLV_READ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) 	.info = lola_src_gain_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) 	.get = lola_src_gain_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) 	.put = lola_src_gain_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) 	.tlv.p = lola_src_gain_tlv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) static int create_src_gain_mixer(struct lola *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) 				 int num, int ofs, char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) 	lola_src_gain_mixer.name = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) 	lola_src_gain_mixer.private_value = ofs + (num << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) 	return snd_ctl_add(chip->card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) 			   snd_ctl_new1(&lola_src_gain_mixer, chip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) #if 0 /* not used */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738)  * destination gain (matrix-like) mixer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) static int lola_dest_gain_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) 			       struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) 	unsigned int src_num = (kcontrol->private_value >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) 	uinfo->count = src_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) 	uinfo->value.integer.min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) 	uinfo->value.integer.max = 433;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) static int lola_dest_gain_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) 			      struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) 	struct lola *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) 	unsigned int src_ofs = kcontrol->private_value & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) 	unsigned int src_num = (kcontrol->private_value >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) 	unsigned int dst_ofs = (kcontrol->private_value >> 16) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) 	unsigned int dst, mask, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) 	dst = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + dst_ofs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) 	mask = readl(&chip->mixer.array->dest_mix_gain_enable[dst]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) 	for (i = 0; i < src_num; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) 		unsigned int src = src_ofs + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) 		unsigned short val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) 		if (!(chip->mixer.src_mask & (1 << src)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) 		if (mask & (1 << dst))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) 			val = readw(&chip->mixer.array->dest_mix_gain[dst][src]) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) 			val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) 		ucontrol->value.integer.value[i] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) static int lola_dest_gain_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) 			      struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) 	struct lola *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) 	unsigned int src_ofs = kcontrol->private_value & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) 	unsigned int src_num = (kcontrol->private_value >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) 	unsigned int dst_ofs = (kcontrol->private_value >> 16) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) 	unsigned int dst, mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) 	unsigned short gains[MAX_STREAM_COUNT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) 	int i, num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) 	mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) 	num = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) 	for (i = 0; i < src_num; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) 		unsigned short val = ucontrol->value.integer.value[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) 		if (val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) 			gains[num++] = val - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) 			mask |= 1 << i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) 	mask <<= src_ofs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) 	dst = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + dst_ofs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) 	return lola_mixer_set_dest_gains(chip, dst, mask, gains);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) static const DECLARE_TLV_DB_SCALE(lola_dest_gain_tlv, -8425, 25, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) static struct snd_kcontrol_new lola_dest_gain_mixer = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) 	.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) 		   SNDRV_CTL_ELEM_ACCESS_TLV_READ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) 	.info = lola_dest_gain_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) 	.get = lola_dest_gain_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) 	.put = lola_dest_gain_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) 	.tlv.p = lola_dest_gain_tlv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) static int create_dest_gain_mixer(struct lola *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) 				  int src_num, int src_ofs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) 				  int num, int ofs, char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) 	lola_dest_gain_mixer.count = num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) 	lola_dest_gain_mixer.name = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) 	lola_dest_gain_mixer.private_value =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) 		src_ofs + (src_num << 8) + (ofs << 16) + (num << 24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) 	return snd_ctl_add(chip->card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) 			  snd_ctl_new1(&lola_dest_gain_mixer, chip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) #endif /* not used */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) int lola_create_mixer(struct lola *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) 	err = create_analog_mixer(chip, PLAY, "Analog Playback Volume");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) 	err = create_analog_mixer(chip, CAPT, "Analog Capture Volume");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) 	err = create_input_src_mixer(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) 	err = create_src_gain_mixer(chip, chip->mixer.src_phys_ins, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) 				    "Digital Capture Volume");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) 	err = create_src_gain_mixer(chip, chip->mixer.src_stream_outs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) 				    chip->mixer.src_stream_out_ofs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) 				    "Digital Playback Volume");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) /* FIXME: buggy mixer matrix handling */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) 	err = create_dest_gain_mixer(chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) 				     chip->mixer.src_phys_ins, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) 				     chip->mixer.dest_stream_ins, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) 				     "Line Capture Volume");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) 	err = create_dest_gain_mixer(chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) 				     chip->mixer.src_stream_outs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) 				     chip->mixer.src_stream_out_ofs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) 				     chip->mixer.dest_stream_ins, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) 				     "Stream-Loopback Capture Volume");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) 	err = create_dest_gain_mixer(chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) 				     chip->mixer.src_phys_ins, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) 				     chip->mixer.dest_phys_outs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) 				     chip->mixer.dest_phys_out_ofs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) 				     "Line-Loopback Playback Volume");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) 	err = create_dest_gain_mixer(chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) 				     chip->mixer.src_stream_outs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) 				     chip->mixer.src_stream_out_ofs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) 				     chip->mixer.dest_phys_outs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) 				     chip->mixer.dest_phys_out_ofs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) 				     "Stream Playback Volume");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) #endif /* FIXME */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) 	return init_mixer_values(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) }