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)  *   ALSA driver for ICEnsemble VT1724 (Envy24HT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  *   Lowlevel functions for Audiotrak Prodigy 7.1 Hifi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  *   based on pontis.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8)  *      Copyright (c) 2007 Julian Scheel <julian@jusst.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9)  *      Copyright (c) 2007 allank
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10)  *      Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) #include <sound/core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) #include <sound/info.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) #include <sound/tlv.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) #include "ice1712.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) #include "envy24ht.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) #include "prodigy_hifi.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) struct prodigy_hifi_spec {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) 	unsigned short master[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) 	unsigned short vol[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) /* I2C addresses */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) #define WM_DEV		0x34
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) /* WM8776 registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) #define WM_HP_ATTEN_L		0x00	/* headphone left attenuation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) #define WM_HP_ATTEN_R		0x01	/* headphone left attenuation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) #define WM_HP_MASTER		0x02	/* headphone master (both channels),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) 						override LLR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) #define WM_DAC_ATTEN_L		0x03	/* digital left attenuation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) #define WM_DAC_ATTEN_R		0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) #define WM_DAC_MASTER		0x05
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) #define WM_PHASE_SWAP		0x06	/* DAC phase swap */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) #define WM_DAC_CTRL1		0x07
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) #define WM_DAC_MUTE		0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) #define WM_DAC_CTRL2		0x09
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) #define WM_DAC_INT		0x0a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) #define WM_ADC_INT		0x0b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) #define WM_MASTER_CTRL		0x0c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) #define WM_POWERDOWN		0x0d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) #define WM_ADC_ATTEN_L		0x0e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) #define WM_ADC_ATTEN_R		0x0f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) #define WM_ALC_CTRL1		0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) #define WM_ALC_CTRL2		0x11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) #define WM_ALC_CTRL3		0x12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) #define WM_NOISE_GATE		0x13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) #define WM_LIMITER		0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) #define WM_ADC_MUX		0x15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) #define WM_OUT_MUX		0x16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) #define WM_RESET		0x17
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) /* Analog Recording Source :- Mic, LineIn, CD/Video, */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) /* implement capture source select control for WM8776 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) #define WM_AIN1 "AIN1"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) #define WM_AIN2 "AIN2"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) #define WM_AIN3 "AIN3"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) #define WM_AIN4 "AIN4"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) #define WM_AIN5 "AIN5"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) /* GPIO pins of envy24ht connected to wm8766 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) #define WM8766_SPI_CLK	 (1<<17) /* CLK, Pin97 on ICE1724 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) #define WM8766_SPI_MD	  (1<<16) /* DATA VT1724 -> WM8766, Pin96 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) #define WM8766_SPI_ML	  (1<<18) /* Latch, Pin98 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) /* WM8766 registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) #define WM8766_DAC_CTRL	 0x02   /* DAC Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) #define WM8766_INT_CTRL	 0x03   /* Interface Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) #define WM8766_DAC_CTRL2	0x09
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) #define WM8766_DAC_CTRL3	0x0a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) #define WM8766_RESET	    0x1f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) #define WM8766_LDA1	     0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) #define WM8766_LDA2	     0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) #define WM8766_LDA3	     0x06
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) #define WM8766_RDA1	     0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) #define WM8766_RDA2	     0x05
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) #define WM8766_RDA3	     0x07
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) #define WM8766_MUTE1	    0x0C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) #define WM8766_MUTE2	    0x0F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95)  * Prodigy HD2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) #define AK4396_ADDR    0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) #define AK4396_CSN    (1 << 8)    /* CSN->GPIO8, pin 75 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) #define AK4396_CCLK   (1 << 9)    /* CCLK->GPIO9, pin 76 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) #define AK4396_CDTI   (1 << 10)   /* CDTI->GPIO10, pin 77 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) /* ak4396 registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) #define AK4396_CTRL1	    0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) #define AK4396_CTRL2	    0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) #define AK4396_CTRL3	    0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) #define AK4396_LCH_ATT	  0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) #define AK4396_RCH_ATT	  0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111)  * get the current register value of WM codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) static unsigned short wm_get(struct snd_ice1712 *ice, int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 	reg <<= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 	return ((unsigned short)ice->akm[0].images[reg] << 8) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 		ice->akm[0].images[reg + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121)  * set the register value of WM codec and remember it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) static void wm_put_nocache(struct snd_ice1712 *ice, int reg, unsigned short val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 	unsigned short cval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) 	cval = (reg << 9) | val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) 	snd_vt1724_write_i2c(ice, WM_DEV, cval >> 8, cval & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) static void wm_put(struct snd_ice1712 *ice, int reg, unsigned short val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 	wm_put_nocache(ice, reg, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 	reg <<= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 	ice->akm[0].images[reg] = val >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 	ice->akm[0].images[reg + 1] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139)  * write data in the SPI mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) static void set_gpio_bit(struct snd_ice1712 *ice, unsigned int bit, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 	unsigned int tmp = snd_ice1712_gpio_read(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 	if (val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 		tmp |= bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 		tmp &= ~bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) 	snd_ice1712_gpio_write(ice, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153)  * SPI implementation for WM8766 codec - only writing supported, no readback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) static void wm8766_spi_send_word(struct snd_ice1712 *ice, unsigned int data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 	for (i = 0; i < 16; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 		set_gpio_bit(ice, WM8766_SPI_CLK, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 		udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 		set_gpio_bit(ice, WM8766_SPI_MD, data & 0x8000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 		udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 		set_gpio_bit(ice, WM8766_SPI_CLK, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 		udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 		data <<= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) static void wm8766_spi_write(struct snd_ice1712 *ice, unsigned int reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 			     unsigned int data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 	unsigned int block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 	snd_ice1712_gpio_set_dir(ice, WM8766_SPI_MD|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 					WM8766_SPI_CLK|WM8766_SPI_ML);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 	snd_ice1712_gpio_set_mask(ice, ~(WM8766_SPI_MD|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 					WM8766_SPI_CLK|WM8766_SPI_ML));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 	/* latch must be low when writing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 	set_gpio_bit(ice, WM8766_SPI_ML, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 	block = (reg << 9) | (data & 0x1ff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 	wm8766_spi_send_word(ice, block); /* REGISTER ADDRESS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 	/* release latch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 	set_gpio_bit(ice, WM8766_SPI_ML, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 	udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 	/* restore */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 	snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 	snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193)  * serial interface for ak4396 - only writing supported, no readback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) static void ak4396_send_word(struct snd_ice1712 *ice, unsigned int data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 	for (i = 0; i < 16; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 		set_gpio_bit(ice, AK4396_CCLK, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 		udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 		set_gpio_bit(ice, AK4396_CDTI, data & 0x8000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 		udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 		set_gpio_bit(ice, AK4396_CCLK, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 		udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 		data <<= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) static void ak4396_write(struct snd_ice1712 *ice, unsigned int reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 			 unsigned int data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 	unsigned int block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 	snd_ice1712_gpio_set_dir(ice, AK4396_CSN|AK4396_CCLK|AK4396_CDTI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 	snd_ice1712_gpio_set_mask(ice, ~(AK4396_CSN|AK4396_CCLK|AK4396_CDTI));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 	/* latch must be low when writing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 	set_gpio_bit(ice, AK4396_CSN, 0); 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 	block =  ((AK4396_ADDR & 0x03) << 14) | (1 << 13) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 			((reg & 0x1f) << 8) | (data & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 	ak4396_send_word(ice, block); /* REGISTER ADDRESS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 	/* release latch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 	set_gpio_bit(ice, AK4396_CSN, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 	udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 	/* restore */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 	snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 	snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232)  * ak4396 mixers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233)  */
^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) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238)  * DAC volume attenuation mixer control (-64dB to 0dB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) static int ak4396_dac_vol_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 			       struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 	uinfo->count = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 	uinfo->value.integer.min = 0;   /* mute */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 	uinfo->value.integer.max = 0xFF; /* linear */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) static int ak4396_dac_vol_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 			      struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 	struct prodigy_hifi_spec *spec = ice->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 	for (i = 0; i < 2; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 		ucontrol->value.integer.value[i] = spec->vol[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 	return 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) static int ak4396_dac_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 	struct prodigy_hifi_spec *spec = ice->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 	int change = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 	mutex_lock(&ice->gpio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 	for (i = 0; i < 2; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 		if (ucontrol->value.integer.value[i] != spec->vol[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 			spec->vol[i] = ucontrol->value.integer.value[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 			ak4396_write(ice, AK4396_LCH_ATT + i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 				     spec->vol[i] & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 			change = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 	mutex_unlock(&ice->gpio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 	return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) static const DECLARE_TLV_DB_SCALE(db_scale_wm_dac, -12700, 100, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) static const DECLARE_TLV_DB_LINEAR(ak4396_db_scale, TLV_DB_GAIN_MUTE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) static const struct snd_kcontrol_new prodigy_hd2_controls[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288)     {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 	.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 		SNDRV_CTL_ELEM_ACCESS_TLV_READ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 	.name = "Front Playback Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 	.info = ak4396_dac_vol_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 	.get = ak4396_dac_vol_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 	.put = ak4396_dac_vol_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 	.tlv = { .p = ak4396_db_scale },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297)     },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) /* --------------- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) #define WM_VOL_MAX	255
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) #define WM_VOL_MUTE	0x8000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) #define DAC_0dB	0xff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) #define DAC_RES	128
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) #define DAC_MIN	(DAC_0dB - DAC_RES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 		       unsigned short vol, unsigned short master)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 	unsigned char nvol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 	if ((master & WM_VOL_MUTE) || (vol & WM_VOL_MUTE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 		nvol = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 		nvol = (((vol & ~WM_VOL_MUTE) * (master & ~WM_VOL_MUTE)) / 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 				& WM_VOL_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 		nvol = (nvol ? (nvol + DAC_MIN) : 0) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 	wm_put(ice, index, nvol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 	wm_put_nocache(ice, index, 0x100 | nvol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) static void wm8766_set_vol(struct snd_ice1712 *ice, unsigned int index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 			   unsigned short vol, unsigned short master)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 	unsigned char nvol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 	if ((master & WM_VOL_MUTE) || (vol & WM_VOL_MUTE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 		nvol = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 		nvol = (((vol & ~WM_VOL_MUTE) * (master & ~WM_VOL_MUTE)) / 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 				& WM_VOL_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 		nvol = (nvol ? (nvol + DAC_MIN) : 0) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 	wm8766_spi_write(ice, index, (0x0100 | nvol));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347)  * DAC volume attenuation mixer control (-64dB to 0dB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) static int wm_dac_vol_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 			   struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 	uinfo->count = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 	uinfo->value.integer.min = 0;	/* mute */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 	uinfo->value.integer.max = DAC_RES;	/* 0dB, 0.5dB step */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) static int wm_dac_vol_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 			  struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 	struct prodigy_hifi_spec *spec = ice->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 	for (i = 0; i < 2; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 		ucontrol->value.integer.value[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 			spec->vol[2 + i] & ~WM_VOL_MUTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) static int wm_dac_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 	struct prodigy_hifi_spec *spec = ice->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 	int i, idx, change = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 	mutex_lock(&ice->gpio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 	for (i = 0; i < 2; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 		if (ucontrol->value.integer.value[i] != spec->vol[2 + i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 			idx = WM_DAC_ATTEN_L + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 			spec->vol[2 + i] &= WM_VOL_MUTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 			spec->vol[2 + i] |= ucontrol->value.integer.value[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 			wm_set_vol(ice, idx, spec->vol[2 + i], spec->master[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 			change = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 	mutex_unlock(&ice->gpio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 	return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395)  * WM8766 DAC volume attenuation mixer control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) static int wm8766_vol_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 			   struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 	int voices = kcontrol->private_value >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 	uinfo->count = voices;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 	uinfo->value.integer.min = 0;		/* mute */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 	uinfo->value.integer.max = DAC_RES;	/* 0dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) static int wm8766_vol_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 			  struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 	struct prodigy_hifi_spec *spec = ice->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 	int i, ofs, voices;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 	voices = kcontrol->private_value >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 	ofs = kcontrol->private_value & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 	for (i = 0; i < voices; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 		ucontrol->value.integer.value[i] = spec->vol[ofs + i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) static int wm8766_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 	struct prodigy_hifi_spec *spec = ice->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 	int i, idx, ofs, voices;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 	int change = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 	voices = kcontrol->private_value >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 	ofs = kcontrol->private_value & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 	mutex_lock(&ice->gpio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 	for (i = 0; i < voices; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 		if (ucontrol->value.integer.value[i] != spec->vol[ofs + i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 			idx = WM8766_LDA1 + ofs + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 			spec->vol[ofs + i] &= WM_VOL_MUTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 			spec->vol[ofs + i] |= ucontrol->value.integer.value[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 			wm8766_set_vol(ice, idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 				       spec->vol[ofs + i], spec->master[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 			change = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 	mutex_unlock(&ice->gpio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 	return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) }
^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)  * Master volume attenuation mixer control / applied to WM8776+WM8766
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) static int wm_master_vol_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 			      struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 	uinfo->count = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 	uinfo->value.integer.min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 	uinfo->value.integer.max = DAC_RES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) static int wm_master_vol_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 			     struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 	struct prodigy_hifi_spec *spec = ice->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 	for (i = 0; i < 2; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 		ucontrol->value.integer.value[i] = spec->master[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) static int wm_master_vol_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 			     struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 	struct prodigy_hifi_spec *spec = ice->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 	int ch, change = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 	mutex_lock(&ice->gpio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 	for (ch = 0; ch < 2; ch++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 		if (ucontrol->value.integer.value[ch] != spec->master[ch]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 			spec->master[ch] = ucontrol->value.integer.value[ch];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 			/* Apply to front DAC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 			wm_set_vol(ice, WM_DAC_ATTEN_L + ch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 				   spec->vol[2 + ch], spec->master[ch]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 			wm8766_set_vol(ice, WM8766_LDA1 + ch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 				       spec->vol[0 + ch], spec->master[ch]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 			wm8766_set_vol(ice, WM8766_LDA2 + ch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 				       spec->vol[4 + ch], spec->master[ch]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 			wm8766_set_vol(ice, WM8766_LDA3 + ch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 				       spec->vol[6 + ch], spec->master[ch]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 			change = 1;
^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) 	mutex_unlock(&ice->gpio_mutex);	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 	return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) /* KONSTI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) static int wm_adc_mux_enum_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 				struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 	static const char * const texts[32] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 		"NULL", WM_AIN1, WM_AIN2, WM_AIN1 "+" WM_AIN2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 		WM_AIN3, WM_AIN1 "+" WM_AIN3, WM_AIN2 "+" WM_AIN3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 		WM_AIN1 "+" WM_AIN2 "+" WM_AIN3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 		WM_AIN4, WM_AIN1 "+" WM_AIN4, WM_AIN2 "+" WM_AIN4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 		WM_AIN1 "+" WM_AIN2 "+" WM_AIN4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 		WM_AIN3 "+" WM_AIN4, WM_AIN1 "+" WM_AIN3 "+" WM_AIN4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 		WM_AIN2 "+" WM_AIN3 "+" WM_AIN4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 		WM_AIN1 "+" WM_AIN2 "+" WM_AIN3 "+" WM_AIN4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 		WM_AIN5, WM_AIN1 "+" WM_AIN5, WM_AIN2 "+" WM_AIN5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 		WM_AIN1 "+" WM_AIN2 "+" WM_AIN5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 		WM_AIN3 "+" WM_AIN5, WM_AIN1 "+" WM_AIN3 "+" WM_AIN5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 		WM_AIN2 "+" WM_AIN3 "+" WM_AIN5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 		WM_AIN1 "+" WM_AIN2 "+" WM_AIN3 "+" WM_AIN5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 		WM_AIN4 "+" WM_AIN5, WM_AIN1 "+" WM_AIN4 "+" WM_AIN5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 		WM_AIN2 "+" WM_AIN4 "+" WM_AIN5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 		WM_AIN1 "+" WM_AIN2 "+" WM_AIN4 "+" WM_AIN5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 		WM_AIN3 "+" WM_AIN4 "+" WM_AIN5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 		WM_AIN1 "+" WM_AIN3 "+" WM_AIN4 "+" WM_AIN5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 		WM_AIN2 "+" WM_AIN3 "+" WM_AIN4 "+" WM_AIN5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 		WM_AIN1 "+" WM_AIN2 "+" WM_AIN3 "+" WM_AIN4 "+" WM_AIN5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 	return snd_ctl_enum_info(uinfo, 1, 32, texts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) static int wm_adc_mux_enum_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 			       struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 	mutex_lock(&ice->gpio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 	ucontrol->value.enumerated.item[0] = wm_get(ice, WM_ADC_MUX) & 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 	mutex_unlock(&ice->gpio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) static int wm_adc_mux_enum_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 			       struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 	unsigned short oval, nval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 	int change = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 	mutex_lock(&ice->gpio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 	oval = wm_get(ice, WM_ADC_MUX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 	nval = (oval & 0xe0) | ucontrol->value.enumerated.item[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 	if (nval != oval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 		wm_put(ice, WM_ADC_MUX, nval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 		change = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 	mutex_unlock(&ice->gpio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 	return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) /* KONSTI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565)  * ADC gain mixer control (-64dB to 0dB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) #define ADC_0dB	0xcf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) #define ADC_RES	128
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) #define ADC_MIN	(ADC_0dB - ADC_RES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) static int wm_adc_vol_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 			   struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 	uinfo->count = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 	uinfo->value.integer.min = 0;	/* mute (-64dB) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 	uinfo->value.integer.max = ADC_RES;	/* 0dB, 0.5dB step */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) static int wm_adc_vol_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 			  struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 	unsigned short val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 	mutex_lock(&ice->gpio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 	for (i = 0; i < 2; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 		val = wm_get(ice, WM_ADC_ATTEN_L + i) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 		val = val > ADC_MIN ? (val - ADC_MIN) : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 		ucontrol->value.integer.value[i] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 	mutex_unlock(&ice->gpio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) static int wm_adc_vol_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 			  struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 	unsigned short ovol, nvol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 	int i, idx, change = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 	mutex_lock(&ice->gpio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 	for (i = 0; i < 2; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 		nvol = ucontrol->value.integer.value[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 		nvol = nvol ? (nvol + ADC_MIN) : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 		idx  = WM_ADC_ATTEN_L + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 		ovol = wm_get(ice, idx) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 		if (ovol != nvol) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 			wm_put(ice, idx, nvol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 			change = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 	mutex_unlock(&ice->gpio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 	return change;
^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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622)  * ADC input mux mixer control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) #define wm_adc_mux_info		snd_ctl_boolean_mono_info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) static int wm_adc_mux_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 			  struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 	int bit = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 	mutex_lock(&ice->gpio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 	ucontrol->value.integer.value[0] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 		(wm_get(ice, WM_ADC_MUX) & (1 << bit)) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 	mutex_unlock(&ice->gpio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) static int wm_adc_mux_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 			  struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 	int bit = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 	unsigned short oval, nval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 	int change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 	mutex_lock(&ice->gpio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 	nval = oval = wm_get(ice, WM_ADC_MUX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 	if (ucontrol->value.integer.value[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 		nval |= (1 << bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 		nval &= ~(1 << bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 	change = nval != oval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 	if (change) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 		wm_put(ice, WM_ADC_MUX, nval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 	mutex_unlock(&ice->gpio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662)  * Analog bypass (In -> Out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) #define wm_bypass_info		snd_ctl_boolean_mono_info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) static int wm_bypass_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 			 struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 	mutex_lock(&ice->gpio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 	ucontrol->value.integer.value[0] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 		(wm_get(ice, WM_OUT_MUX) & 0x04) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 	mutex_unlock(&ice->gpio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) static int wm_bypass_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 			 struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 	unsigned short val, oval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 	int change = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 	mutex_lock(&ice->gpio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 	val = oval = wm_get(ice, WM_OUT_MUX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 	if (ucontrol->value.integer.value[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 		val |= 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 		val &= ~0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 	if (val != oval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 		wm_put(ice, WM_OUT_MUX, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 		change = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 	mutex_unlock(&ice->gpio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 	return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700)  * Left/Right swap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) #define wm_chswap_info		snd_ctl_boolean_mono_info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) static int wm_chswap_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 			 struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 	mutex_lock(&ice->gpio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 	ucontrol->value.integer.value[0] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 			(wm_get(ice, WM_DAC_CTRL1) & 0xf0) != 0x90;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 	mutex_unlock(&ice->gpio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) static int wm_chswap_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 			 struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 	unsigned short val, oval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 	int change = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 	mutex_lock(&ice->gpio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 	oval = wm_get(ice, WM_DAC_CTRL1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 	val = oval & 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 	if (ucontrol->value.integer.value[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 		val |= 0x60;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 		val |= 0x90;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 	if (val != oval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 		wm_put(ice, WM_DAC_CTRL1, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 		wm_put_nocache(ice, WM_DAC_CTRL1, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 		change = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 	mutex_unlock(&ice->gpio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 	return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741)  * mixers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) static const struct snd_kcontrol_new prodigy_hifi_controls[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 			   SNDRV_CTL_ELEM_ACCESS_TLV_READ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 		.name = "Master Playback Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 		.info = wm_master_vol_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 		.get = wm_master_vol_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 		.put = wm_master_vol_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 		.tlv = { .p = db_scale_wm_dac }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 			   SNDRV_CTL_ELEM_ACCESS_TLV_READ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 		.name = "Front Playback Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 		.info = wm_dac_vol_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 		.get = wm_dac_vol_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 		.put = wm_dac_vol_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 		.tlv = { .p = db_scale_wm_dac },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 			   SNDRV_CTL_ELEM_ACCESS_TLV_READ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 		.name = "Rear Playback Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 		.info = wm8766_vol_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 		.get = wm8766_vol_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 		.put = wm8766_vol_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 		.private_value = (2 << 8) | 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 		.tlv = { .p = db_scale_wm_dac },
^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) 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 			   SNDRV_CTL_ELEM_ACCESS_TLV_READ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 		.name = "Center Playback Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 		.info = wm8766_vol_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 		.get = wm8766_vol_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 		.put = wm8766_vol_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 		.private_value = (1 << 8) | 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 		.tlv = { .p = db_scale_wm_dac }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 			   SNDRV_CTL_ELEM_ACCESS_TLV_READ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 		.name = "LFE Playback Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 		.info = wm8766_vol_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 		.get = wm8766_vol_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 		.put = wm8766_vol_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 		.private_value = (1 << 8) | 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 		.tlv = { .p = db_scale_wm_dac }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 			   SNDRV_CTL_ELEM_ACCESS_TLV_READ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 		.name = "Side Playback Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 		.info = wm8766_vol_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 		.get = wm8766_vol_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 		.put = wm8766_vol_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 		.private_value = (2 << 8) | 6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 		.tlv = { .p = db_scale_wm_dac },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 			   SNDRV_CTL_ELEM_ACCESS_TLV_READ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 		.name = "Capture Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 		.info = wm_adc_vol_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 		.get = wm_adc_vol_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 		.put = wm_adc_vol_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 		.tlv = { .p = db_scale_wm_dac },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 		.name = "CD Capture Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 		.info = wm_adc_mux_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 		.get = wm_adc_mux_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 		.put = wm_adc_mux_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 		.private_value = 0,
^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) 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 		.name = "Line Capture Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 		.info = wm_adc_mux_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 		.get = wm_adc_mux_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 		.put = wm_adc_mux_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 		.private_value = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 		.name = "Analog Bypass Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 		.info = wm_bypass_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 		.get = wm_bypass_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 		.put = wm_bypass_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 		.name = "Swap Output Channels",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 		.info = wm_chswap_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 		.get = wm_chswap_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 		.put = wm_chswap_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 		.name = "Analog Capture Source",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 		.info = wm_adc_mux_enum_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 		.get = wm_adc_mux_enum_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 		.put = wm_adc_mux_enum_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859)  * WM codec registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) static void wm_proc_regs_write(struct snd_info_entry *entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 			       struct snd_info_buffer *buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 	struct snd_ice1712 *ice = entry->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 	char line[64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 	unsigned int reg, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 	mutex_lock(&ice->gpio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 	while (!snd_info_get_line(buffer, line, sizeof(line))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 		if (sscanf(line, "%x %x", &reg, &val) != 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 		if (reg <= 0x17 && val <= 0xffff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 			wm_put(ice, reg, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 	mutex_unlock(&ice->gpio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) static void wm_proc_regs_read(struct snd_info_entry *entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 			      struct snd_info_buffer *buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 	struct snd_ice1712 *ice = entry->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 	int reg, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 	mutex_lock(&ice->gpio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 	for (reg = 0; reg <= 0x17; reg++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 		val = wm_get(ice, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 		snd_iprintf(buffer, "%02x = %04x\n", reg, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 	mutex_unlock(&ice->gpio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) static void wm_proc_init(struct snd_ice1712 *ice)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 	snd_card_rw_proc_new(ice->card, "wm_codec", ice, wm_proc_regs_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 			     wm_proc_regs_write);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) static int prodigy_hifi_add_controls(struct snd_ice1712 *ice)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 	for (i = 0; i < ARRAY_SIZE(prodigy_hifi_controls); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 		err = snd_ctl_add(ice->card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 				  snd_ctl_new1(&prodigy_hifi_controls[i], ice));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 		if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 	wm_proc_init(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) static int prodigy_hd2_add_controls(struct snd_ice1712 *ice)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 	for (i = 0; i < ARRAY_SIZE(prodigy_hd2_controls); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 		err = snd_ctl_add(ice->card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 				  snd_ctl_new1(&prodigy_hd2_controls[i], ice));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 		if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 	wm_proc_init(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) static void wm8766_init(struct snd_ice1712 *ice)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 	static const unsigned short wm8766_inits[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 		WM8766_RESET,	   0x0000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 		WM8766_DAC_CTRL,	0x0120,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 		WM8766_INT_CTRL,	0x0022, /* I2S Normal Mode, 24 bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 		WM8766_DAC_CTRL2,       0x0001,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 		WM8766_DAC_CTRL3,       0x0080,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 		WM8766_LDA1,	    0x0100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 		WM8766_LDA2,	    0x0100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 		WM8766_LDA3,	    0x0100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 		WM8766_RDA1,	    0x0100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 		WM8766_RDA2,	    0x0100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 		WM8766_RDA3,	    0x0100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 		WM8766_MUTE1,	   0x0000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 		WM8766_MUTE2,	   0x0000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 	for (i = 0; i < ARRAY_SIZE(wm8766_inits); i += 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 		wm8766_spi_write(ice, wm8766_inits[i], wm8766_inits[i + 1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) static void wm8776_init(struct snd_ice1712 *ice)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 	static const unsigned short wm8776_inits[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 		/* These come first to reduce init pop noise */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 		WM_ADC_MUX,	0x0003,	/* ADC mute */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 		/* 0x00c0 replaced by 0x0003 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 		
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 		WM_DAC_MUTE,	0x0001,	/* DAC softmute */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 		WM_DAC_CTRL1,	0x0000,	/* DAC mute */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 		WM_POWERDOWN,	0x0008,	/* All power-up except HP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 		WM_RESET,	0x0000,	/* reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 	for (i = 0; i < ARRAY_SIZE(wm8776_inits); i += 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 		wm_put(ice, wm8776_inits[i], wm8776_inits[i + 1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) static int prodigy_hifi_resume(struct snd_ice1712 *ice)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 	static const unsigned short wm8776_reinit_registers[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 		WM_MASTER_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 		WM_DAC_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 		WM_ADC_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 		WM_OUT_MUX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 		WM_HP_ATTEN_L,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 		WM_HP_ATTEN_R,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 		WM_PHASE_SWAP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 		WM_DAC_CTRL2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 		WM_ADC_ATTEN_L,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 		WM_ADC_ATTEN_R,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 		WM_ALC_CTRL1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 		WM_ALC_CTRL2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 		WM_ALC_CTRL3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 		WM_NOISE_GATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 		WM_ADC_MUX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 		/* no DAC attenuation here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 	struct prodigy_hifi_spec *spec = ice->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 	int i, ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 	mutex_lock(&ice->gpio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 	/* reinitialize WM8776 and re-apply old register values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 	wm8776_init(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 	schedule_timeout_uninterruptible(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 	for (i = 0; i < ARRAY_SIZE(wm8776_reinit_registers); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 		wm_put(ice, wm8776_reinit_registers[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 		       wm_get(ice, wm8776_reinit_registers[i]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 	/* reinitialize WM8766 and re-apply volumes for all DACs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 	wm8766_init(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 	for (ch = 0; ch < 2; ch++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 		wm_set_vol(ice, WM_DAC_ATTEN_L + ch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 			   spec->vol[2 + ch], spec->master[ch]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 		wm8766_set_vol(ice, WM8766_LDA1 + ch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 			       spec->vol[0 + ch], spec->master[ch]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 		wm8766_set_vol(ice, WM8766_LDA2 + ch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 			       spec->vol[4 + ch], spec->master[ch]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 		wm8766_set_vol(ice, WM8766_LDA3 + ch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 			       spec->vol[6 + ch], spec->master[ch]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 	/* unmute WM8776 DAC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 	wm_put(ice, WM_DAC_MUTE, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 	wm_put(ice, WM_DAC_CTRL1, 0x90);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 	mutex_unlock(&ice->gpio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032)  * initialize the chip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) static int prodigy_hifi_init(struct snd_ice1712 *ice)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 	static const unsigned short wm8776_defaults[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 		WM_MASTER_CTRL,  0x0022, /* 256fs, slave mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 		WM_DAC_INT,	0x0022,	/* I2S, normal polarity, 24bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 		WM_ADC_INT,	0x0022,	/* I2S, normal polarity, 24bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 		WM_DAC_CTRL1,	0x0090,	/* DAC L/R */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 		WM_OUT_MUX,	0x0001,	/* OUT DAC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 		WM_HP_ATTEN_L,	0x0179,	/* HP 0dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 		WM_HP_ATTEN_R,	0x0179,	/* HP 0dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 		WM_DAC_ATTEN_L,	0x0000,	/* DAC 0dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 		WM_DAC_ATTEN_L,	0x0100,	/* DAC 0dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 		WM_DAC_ATTEN_R,	0x0000,	/* DAC 0dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 		WM_DAC_ATTEN_R,	0x0100,	/* DAC 0dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 		WM_PHASE_SWAP,	0x0000,	/* phase normal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 		WM_DAC_MASTER,	0x0100,	/* DAC master muted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 		WM_DAC_CTRL2,	0x0000,	/* no deemphasis, no ZFLG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 		WM_ADC_ATTEN_L,	0x0000,	/* ADC muted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 		WM_ADC_ATTEN_R,	0x0000,	/* ADC muted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) #if 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 		WM_ALC_CTRL1,	0x007b,	/* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 		WM_ALC_CTRL2,	0x0000,	/* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 		WM_ALC_CTRL3,	0x0000,	/* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 		WM_NOISE_GATE,	0x0000,	/* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 		WM_DAC_MUTE,	0x0000,	/* DAC unmute */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 		WM_ADC_MUX,	0x0003,	/* ADC unmute, both CD/Line On */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 	struct prodigy_hifi_spec *spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 	ice->vt1720 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 	ice->vt1724 = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 	ice->num_total_dacs = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 	ice->num_total_adcs = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 	/* HACK - use this as the SPDIF source.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 	* don't call snd_ice1712_gpio_get/put(), otherwise it's overwritten
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 	*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 	ice->gpio.saved[0] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 	/* to remember the register values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 	ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 	if (! ice->akm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 	ice->akm_codecs = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 	if (!spec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 	ice->spec = spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 	/* initialize WM8776 codec */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 	wm8776_init(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 	schedule_timeout_uninterruptible(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 	for (i = 0; i < ARRAY_SIZE(wm8776_defaults); i += 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 		wm_put(ice, wm8776_defaults[i], wm8776_defaults[i + 1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 	wm8766_init(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 	ice->pm_resume = &prodigy_hifi_resume;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 	ice->pm_suspend_enabled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107)  * initialize the chip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) static void ak4396_init(struct snd_ice1712 *ice)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 	static const unsigned short ak4396_inits[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 		AK4396_CTRL1,	   0x87,   /* I2S Normal Mode, 24 bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 		AK4396_CTRL2,	   0x02,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 		AK4396_CTRL3,	   0x00, 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 		AK4396_LCH_ATT,	 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 		AK4396_RCH_ATT,	 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 	/* initialize ak4396 codec */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 	/* reset codec */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 	ak4396_write(ice, AK4396_CTRL1, 0x86);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 	msleep(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 	ak4396_write(ice, AK4396_CTRL1, 0x87);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 	for (i = 0; i < ARRAY_SIZE(ak4396_inits); i += 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 		ak4396_write(ice, ak4396_inits[i], ak4396_inits[i+1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) static int prodigy_hd2_resume(struct snd_ice1712 *ice)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 	/* initialize ak4396 codec and restore previous mixer volumes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 	struct prodigy_hifi_spec *spec = ice->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) 	mutex_lock(&ice->gpio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) 	ak4396_init(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) 	for (i = 0; i < 2; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 		ak4396_write(ice, AK4396_LCH_ATT + i, spec->vol[i] & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 	mutex_unlock(&ice->gpio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) static int prodigy_hd2_init(struct snd_ice1712 *ice)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 	struct prodigy_hifi_spec *spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 	ice->vt1720 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 	ice->vt1724 = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 	ice->num_total_dacs = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 	ice->num_total_adcs = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 	/* HACK - use this as the SPDIF source.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 	* don't call snd_ice1712_gpio_get/put(), otherwise it's overwritten
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 	*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 	ice->gpio.saved[0] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 	/* to remember the register values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 	ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 	if (! ice->akm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 	ice->akm_codecs = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 	if (!spec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) 	ice->spec = spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) 	ice->pm_resume = &prodigy_hd2_resume;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) 	ice->pm_suspend_enabled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) 	ak4396_init(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) static const unsigned char prodigy71hifi_eeprom[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 	0x4b,   /* SYSCONF: clock 512, spdif-in/ADC, 4DACs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 	0x80,   /* ACLINK: I2S */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) 	0xfc,   /* I2S: vol, 96k, 24bit, 192k */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 	0xc3,   /* SPDIF: out-en, out-int, spdif-in */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 	0xff,   /* GPIO_DIR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) 	0xff,   /* GPIO_DIR1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 	0x5f,   /* GPIO_DIR2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) 	0x00,   /* GPIO_MASK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) 	0x00,   /* GPIO_MASK1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) 	0x00,   /* GPIO_MASK2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) 	0x00,   /* GPIO_STATE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 	0x00,   /* GPIO_STATE1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 	0x00,   /* GPIO_STATE2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) static const unsigned char prodigyhd2_eeprom[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 	0x4b,   /* SYSCONF: clock 512, spdif-in/ADC, 4DACs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 	0x80,   /* ACLINK: I2S */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) 	0xfc,   /* I2S: vol, 96k, 24bit, 192k */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 	0xc3,   /* SPDIF: out-en, out-int, spdif-in */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 	0xff,   /* GPIO_DIR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 	0xff,   /* GPIO_DIR1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 	0x5f,   /* GPIO_DIR2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 	0x00,   /* GPIO_MASK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 	0x00,   /* GPIO_MASK1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 	0x00,   /* GPIO_MASK2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 	0x00,   /* GPIO_STATE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 	0x00,   /* GPIO_STATE1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) 	0x00,   /* GPIO_STATE2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) static const unsigned char fortissimo4_eeprom[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) 	0x43,   /* SYSCONF: clock 512, ADC, 4DACs */	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 	0x80,   /* ACLINK: I2S */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) 	0xfc,   /* I2S: vol, 96k, 24bit, 192k */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) 	0xc1,   /* SPDIF: out-en, out-int */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) 	0xff,   /* GPIO_DIR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 	0xff,   /* GPIO_DIR1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 	0x5f,   /* GPIO_DIR2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 	0x00,   /* GPIO_MASK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 	0x00,   /* GPIO_MASK1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) 	0x00,   /* GPIO_MASK2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 	0x00,   /* GPIO_STATE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) 	0x00,   /* GPIO_STATE1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 	0x00,   /* GPIO_STATE2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) /* entry point */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) struct snd_ice1712_card_info snd_vt1724_prodigy_hifi_cards[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) 		.subvendor = VT1724_SUBDEVICE_PRODIGY_HIFI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 		.name = "Audiotrak Prodigy 7.1 HiFi",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) 		.model = "prodigy71hifi",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) 		.chip_init = prodigy_hifi_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) 		.build_controls = prodigy_hifi_add_controls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) 		.eeprom_size = sizeof(prodigy71hifi_eeprom),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) 		.eeprom_data = prodigy71hifi_eeprom,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) 		.driver = "Prodigy71HIFI",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) 	.subvendor = VT1724_SUBDEVICE_PRODIGY_HD2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) 	.name = "Audiotrak Prodigy HD2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) 	.model = "prodigyhd2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) 	.chip_init = prodigy_hd2_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) 	.build_controls = prodigy_hd2_add_controls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) 	.eeprom_size = sizeof(prodigyhd2_eeprom),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) 	.eeprom_data = prodigyhd2_eeprom,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) 	.driver = "Prodigy71HD2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) 		.subvendor = VT1724_SUBDEVICE_FORTISSIMO4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) 		.name = "Hercules Fortissimo IV",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) 		.model = "fortissimo4",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) 		.chip_init = prodigy_hifi_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) 		.build_controls = prodigy_hifi_add_controls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) 		.eeprom_size = sizeof(fortissimo4_eeprom),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) 		.eeprom_data = fortissimo4_eeprom,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) 		.driver = "Fortissimo4",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) 	{ } /* terminator */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265)