^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 Terratec Aureon cards
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (c) 2003 Takashi Iwai <tiwai@suse.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * NOTES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * - we reuse the struct snd_akm4xxx record for storing the wm8770 codec data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * both wm and akm codecs are pretty similar, so we can integrate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * both controls in the future, once if wm codecs are reused in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * many boards.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * - DAC digital volumes are not implemented in the mixer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * if they show better response than DAC analog volumes, we can use them
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * instead.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * Lowlevel functions for AudioTrak Prodigy 7.1 (and possibly 192) cards
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * Copyright (c) 2003 Dimitromanolakis Apostolos <apostol@cs.utoronto.ca>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * version 0.82: Stable / not all features work yet (no communication with AC97 secondary)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * added 64x/128x oversampling switch (should be 64x only for 96khz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * fixed some recording labels (still need to check the rest)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * recording is working probably thanks to correct wm8770 initialization
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * version 0.5: Initial release:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * working: analog output, mixer, headphone amplifier switch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * not working: prety much everything else, at least i could verify that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * we have no digital output, no capture, pretty bad clicks and poops
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * on mixer switch and other coll stuff.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <sound/core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include "ice1712.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include "envy24ht.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #include "aureon.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #include <sound/tlv.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) /* AC97 register cache for Aureon */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) struct aureon_spec {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) unsigned short stac9744[64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) unsigned int cs8415_mux;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) unsigned short master[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) unsigned short vol[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) unsigned char pca9554_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) /* WM8770 registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define WM_DAC_ATTEN 0x00 /* DAC1-8 analog attenuation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define WM_DAC_MASTER_ATTEN 0x08 /* DAC master analog attenuation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define WM_DAC_DIG_ATTEN 0x09 /* DAC1-8 digital attenuation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define WM_DAC_DIG_MASTER_ATTEN 0x11 /* DAC master digital attenuation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define WM_PHASE_SWAP 0x12 /* DAC phase */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define WM_DAC_CTRL1 0x13 /* DAC control bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define WM_MUTE 0x14 /* mute controls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define WM_DAC_CTRL2 0x15 /* de-emphasis and zefo-flag */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define WM_INT_CTRL 0x16 /* interface control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define WM_MASTER 0x17 /* master clock and mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define WM_POWERDOWN 0x18 /* power-down controls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define WM_ADC_GAIN 0x19 /* ADC gain L(19)/R(1a) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define WM_ADC_MUX 0x1b /* input MUX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define WM_OUT_MUX1 0x1c /* output MUX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define WM_OUT_MUX2 0x1e /* output MUX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define WM_RESET 0x1f /* software reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) /* CS8415A registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define CS8415_CTRL1 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define CS8415_CTRL2 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define CS8415_QSUB 0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define CS8415_RATIO 0x1E
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define CS8415_C_BUFFER 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define CS8415_ID 0x7F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) /* PCA9554 registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define PCA9554_DEV 0x40 /* I2C device address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define PCA9554_IN 0x00 /* input port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define PCA9554_OUT 0x01 /* output port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define PCA9554_INVERT 0x02 /* input invert */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define PCA9554_DIR 0x03 /* port directions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) * Aureon Universe additional controls using PCA9554
^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) * Send data to pca9554
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) static void aureon_pca9554_write(struct snd_ice1712 *ice, unsigned char reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) unsigned char data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) unsigned int tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) unsigned char dev = PCA9554_DEV; /* ID 0100000, write */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) unsigned char val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) tmp = snd_ice1712_gpio_read(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) snd_ice1712_gpio_set_mask(ice, ~(AUREON_SPI_MOSI|AUREON_SPI_CLK|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) AUREON_WM_RW|AUREON_WM_CS|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) AUREON_CS8415_CS));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) tmp |= AUREON_WM_RW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) tmp |= AUREON_CS8415_CS | AUREON_WM_CS; /* disable SPI devices */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) tmp &= ~AUREON_SPI_MOSI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) tmp &= ~AUREON_SPI_CLK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) snd_ice1712_gpio_write(ice, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) udelay(50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) * send i2c stop condition and start condition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) * to obtain sane state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) tmp |= AUREON_SPI_CLK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) snd_ice1712_gpio_write(ice, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) udelay(50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) tmp |= AUREON_SPI_MOSI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) snd_ice1712_gpio_write(ice, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) udelay(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) tmp &= ~AUREON_SPI_MOSI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) snd_ice1712_gpio_write(ice, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) udelay(50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) tmp &= ~AUREON_SPI_CLK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) snd_ice1712_gpio_write(ice, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) udelay(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) * send device address, command and value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) * skipping ack cycles in between
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) for (j = 0; j < 3; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) switch (j) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) val = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) val = reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) val = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) for (i = 7; i >= 0; i--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) tmp &= ~AUREON_SPI_CLK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) snd_ice1712_gpio_write(ice, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) udelay(40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) if (val & (1 << i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) tmp |= AUREON_SPI_MOSI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) tmp &= ~AUREON_SPI_MOSI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) snd_ice1712_gpio_write(ice, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) udelay(40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) tmp |= AUREON_SPI_CLK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) snd_ice1712_gpio_write(ice, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) udelay(40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) tmp &= ~AUREON_SPI_CLK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) snd_ice1712_gpio_write(ice, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) udelay(40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) tmp |= AUREON_SPI_CLK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) snd_ice1712_gpio_write(ice, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) udelay(40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) tmp &= ~AUREON_SPI_CLK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) snd_ice1712_gpio_write(ice, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) udelay(40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) tmp &= ~AUREON_SPI_CLK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) snd_ice1712_gpio_write(ice, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) udelay(40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) tmp &= ~AUREON_SPI_MOSI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) snd_ice1712_gpio_write(ice, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) udelay(40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) tmp |= AUREON_SPI_CLK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) snd_ice1712_gpio_write(ice, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) udelay(50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) tmp |= AUREON_SPI_MOSI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) snd_ice1712_gpio_write(ice, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) udelay(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) static int aureon_universe_inmux_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) static const char * const texts[3] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) {"Internal Aux", "Wavetable", "Rear Line-In"};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) return snd_ctl_enum_info(uinfo, 1, 3, texts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) static int aureon_universe_inmux_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) struct aureon_spec *spec = ice->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) ucontrol->value.enumerated.item[0] = spec->pca9554_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) static int aureon_universe_inmux_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) struct aureon_spec *spec = ice->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) unsigned char oval, nval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) int change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) nval = ucontrol->value.enumerated.item[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) if (nval >= 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) snd_ice1712_save_gpio_status(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) oval = spec->pca9554_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) change = (oval != nval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) if (change) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) aureon_pca9554_write(ice, PCA9554_OUT, nval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) spec->pca9554_out = nval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) snd_ice1712_restore_gpio_status(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) static void aureon_ac97_write(struct snd_ice1712 *ice, unsigned short reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) unsigned short val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) struct aureon_spec *spec = ice->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) unsigned int tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) /* Send address to XILINX chip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) tmp = (snd_ice1712_gpio_read(ice) & ~0xFF) | (reg & 0x7F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) snd_ice1712_gpio_write(ice, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) tmp |= AUREON_AC97_ADDR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) snd_ice1712_gpio_write(ice, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) tmp &= ~AUREON_AC97_ADDR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) snd_ice1712_gpio_write(ice, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) /* Send low-order byte to XILINX chip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) tmp &= ~AUREON_AC97_DATA_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) tmp |= val & AUREON_AC97_DATA_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) snd_ice1712_gpio_write(ice, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) tmp |= AUREON_AC97_DATA_LOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) snd_ice1712_gpio_write(ice, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) tmp &= ~AUREON_AC97_DATA_LOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) snd_ice1712_gpio_write(ice, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) /* Send high-order byte to XILINX chip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) tmp &= ~AUREON_AC97_DATA_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) tmp |= (val >> 8) & AUREON_AC97_DATA_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) snd_ice1712_gpio_write(ice, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) tmp |= AUREON_AC97_DATA_HIGH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) snd_ice1712_gpio_write(ice, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) tmp &= ~AUREON_AC97_DATA_HIGH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) snd_ice1712_gpio_write(ice, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) /* Instruct XILINX chip to parse the data to the STAC9744 chip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) tmp |= AUREON_AC97_COMMIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) snd_ice1712_gpio_write(ice, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) tmp &= ~AUREON_AC97_COMMIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) snd_ice1712_gpio_write(ice, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) /* Store the data in out private buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) spec->stac9744[(reg & 0x7F) >> 1] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) static unsigned short aureon_ac97_read(struct snd_ice1712 *ice, unsigned short reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) struct aureon_spec *spec = ice->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) return spec->stac9744[(reg & 0x7F) >> 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) }
^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) * Initialize STAC9744 chip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) static int aureon_ac97_init(struct snd_ice1712 *ice)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) struct aureon_spec *spec = ice->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) static const unsigned short ac97_defaults[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 0x00, 0x9640,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 0x02, 0x8000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 0x04, 0x8000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 0x06, 0x8000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 0x0C, 0x8008,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 0x0E, 0x8008,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 0x10, 0x8808,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 0x12, 0x8808,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 0x14, 0x8808,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 0x16, 0x8808,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 0x18, 0x8808,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 0x1C, 0x8000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 0x26, 0x000F,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 0x28, 0x0201,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 0x2C, 0xBB80,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 0x32, 0xBB80,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 0x7C, 0x8384,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 0x7E, 0x7644,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) (unsigned short)-1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) unsigned int tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) /* Cold reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) tmp = (snd_ice1712_gpio_read(ice) | AUREON_AC97_RESET) & ~AUREON_AC97_DATA_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) snd_ice1712_gpio_write(ice, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) udelay(3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) tmp &= ~AUREON_AC97_RESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) snd_ice1712_gpio_write(ice, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) udelay(3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) tmp |= AUREON_AC97_RESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) snd_ice1712_gpio_write(ice, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) udelay(3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) memset(&spec->stac9744, 0, sizeof(spec->stac9744));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) for (i = 0; ac97_defaults[i] != (unsigned short)-1; i += 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) spec->stac9744[(ac97_defaults[i]) >> 1] = ac97_defaults[i+1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) /* Unmute AC'97 master volume permanently - muting is done by WM8770 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) aureon_ac97_write(ice, AC97_MASTER, 0x0000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) return 0;
^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) #define AUREON_AC97_STEREO 0x80
^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) * AC'97 volume controls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) static int aureon_ac97_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) uinfo->count = kcontrol->private_value & AUREON_AC97_STEREO ? 2 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) uinfo->value.integer.min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) uinfo->value.integer.max = 31;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) static int aureon_ac97_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) unsigned short vol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) mutex_lock(&ice->gpio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) vol = aureon_ac97_read(ice, kcontrol->private_value & 0x7F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) ucontrol->value.integer.value[0] = 0x1F - (vol & 0x1F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) if (kcontrol->private_value & AUREON_AC97_STEREO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) ucontrol->value.integer.value[1] = 0x1F - ((vol >> 8) & 0x1F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) mutex_unlock(&ice->gpio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) static int aureon_ac97_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) unsigned short ovol, nvol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) int change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) snd_ice1712_save_gpio_status(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) ovol = aureon_ac97_read(ice, kcontrol->private_value & 0x7F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) nvol = (0x1F - ucontrol->value.integer.value[0]) & 0x001F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) if (kcontrol->private_value & AUREON_AC97_STEREO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) nvol |= ((0x1F - ucontrol->value.integer.value[1]) << 8) & 0x1F00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) nvol |= ovol & ~0x1F1F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) change = (ovol != nvol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) if (change)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) aureon_ac97_write(ice, kcontrol->private_value & 0x7F, nvol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) snd_ice1712_restore_gpio_status(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) return change;
^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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) * AC'97 mute controls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) #define aureon_ac97_mute_info snd_ctl_boolean_mono_info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) static int aureon_ac97_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) mutex_lock(&ice->gpio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) ucontrol->value.integer.value[0] = aureon_ac97_read(ice,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) kcontrol->private_value & 0x7F) & 0x8000 ? 0 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) mutex_unlock(&ice->gpio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) static int aureon_ac97_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) unsigned short ovol, nvol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) int change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) snd_ice1712_save_gpio_status(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) ovol = aureon_ac97_read(ice, kcontrol->private_value & 0x7F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) nvol = (ucontrol->value.integer.value[0] ? 0x0000 : 0x8000) | (ovol & ~0x8000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) change = (ovol != nvol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) if (change)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) aureon_ac97_write(ice, kcontrol->private_value & 0x7F, nvol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) snd_ice1712_restore_gpio_status(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) * AC'97 mute controls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) #define aureon_ac97_micboost_info snd_ctl_boolean_mono_info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) static int aureon_ac97_micboost_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) mutex_lock(&ice->gpio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) ucontrol->value.integer.value[0] = aureon_ac97_read(ice, AC97_MIC) & 0x0020 ? 0 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) mutex_unlock(&ice->gpio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) static int aureon_ac97_micboost_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) unsigned short ovol, nvol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) int change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) snd_ice1712_save_gpio_status(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) ovol = aureon_ac97_read(ice, AC97_MIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) nvol = (ucontrol->value.integer.value[0] ? 0x0000 : 0x0020) | (ovol & ~0x0020);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) change = (ovol != nvol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) if (change)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) aureon_ac97_write(ice, AC97_MIC, nvol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) snd_ice1712_restore_gpio_status(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) return change;
^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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) * write data in the SPI mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) static void aureon_spi_write(struct snd_ice1712 *ice, unsigned int cs, unsigned int data, int bits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) unsigned int tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) unsigned int mosi, clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) tmp = snd_ice1712_gpio_read(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71XT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) snd_ice1712_gpio_set_mask(ice, ~(PRODIGY_SPI_MOSI|PRODIGY_SPI_CLK|PRODIGY_WM_CS));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) mosi = PRODIGY_SPI_MOSI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) clk = PRODIGY_SPI_CLK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) snd_ice1712_gpio_set_mask(ice, ~(AUREON_WM_RW|AUREON_SPI_MOSI|AUREON_SPI_CLK|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) AUREON_WM_CS|AUREON_CS8415_CS));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) mosi = AUREON_SPI_MOSI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) clk = AUREON_SPI_CLK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) tmp |= AUREON_WM_RW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) tmp &= ~cs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) snd_ice1712_gpio_write(ice, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) for (i = bits - 1; i >= 0; i--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) tmp &= ~clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) snd_ice1712_gpio_write(ice, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) if (data & (1 << i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) tmp |= mosi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) tmp &= ~mosi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) snd_ice1712_gpio_write(ice, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) tmp |= clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) snd_ice1712_gpio_write(ice, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) tmp &= ~clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) tmp |= cs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) snd_ice1712_gpio_write(ice, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) tmp |= clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) snd_ice1712_gpio_write(ice, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) * Read data in SPI mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) static void aureon_spi_read(struct snd_ice1712 *ice, unsigned int cs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) unsigned int data, int bits, unsigned char *buffer, int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) unsigned int tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) tmp = (snd_ice1712_gpio_read(ice) & ~AUREON_SPI_CLK) | AUREON_CS8415_CS|AUREON_WM_CS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) snd_ice1712_gpio_write(ice, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) tmp &= ~cs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) snd_ice1712_gpio_write(ice, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) for (i = bits-1; i >= 0; i--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) if (data & (1 << i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) tmp |= AUREON_SPI_MOSI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) tmp &= ~AUREON_SPI_MOSI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) snd_ice1712_gpio_write(ice, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) tmp |= AUREON_SPI_CLK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) snd_ice1712_gpio_write(ice, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) tmp &= ~AUREON_SPI_CLK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) snd_ice1712_gpio_write(ice, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) for (j = 0; j < size; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) unsigned char outdata = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) for (i = 7; i >= 0; i--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) tmp = snd_ice1712_gpio_read(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) outdata <<= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) outdata |= (tmp & AUREON_SPI_MISO) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) tmp |= AUREON_SPI_CLK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) snd_ice1712_gpio_write(ice, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) tmp &= ~AUREON_SPI_CLK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) snd_ice1712_gpio_write(ice, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) buffer[j] = outdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) tmp |= cs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) snd_ice1712_gpio_write(ice, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) static unsigned char aureon_cs8415_get(struct snd_ice1712 *ice, int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) unsigned char val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) aureon_spi_write(ice, AUREON_CS8415_CS, 0x2000 | reg, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) aureon_spi_read(ice, AUREON_CS8415_CS, 0x21, 8, &val, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) static void aureon_cs8415_read(struct snd_ice1712 *ice, int reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) unsigned char *buffer, int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) aureon_spi_write(ice, AUREON_CS8415_CS, 0x2000 | reg, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) aureon_spi_read(ice, AUREON_CS8415_CS, 0x21, 8, buffer, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) static void aureon_cs8415_put(struct snd_ice1712 *ice, int reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) unsigned char val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) aureon_spi_write(ice, AUREON_CS8415_CS, 0x200000 | (reg << 8) | val, 24);
^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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) * get the current register value of WM codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) static unsigned short wm_get(struct snd_ice1712 *ice, int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) reg <<= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) return ((unsigned short)ice->akm[0].images[reg] << 8) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) ice->akm[0].images[reg + 1];
^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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) * set the register value of WM codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) static void wm_put_nocache(struct snd_ice1712 *ice, int reg, unsigned short val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) aureon_spi_write(ice,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) ((ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71XT) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) PRODIGY_WM_CS : AUREON_WM_CS),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) (reg << 9) | (val & 0x1ff), 16);
^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) * set the register value of WM codec and remember it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) static void wm_put(struct snd_ice1712 *ice, int reg, unsigned short val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) wm_put_nocache(ice, reg, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) reg <<= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) ice->akm[0].images[reg] = val >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) ice->akm[0].images[reg + 1] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) #define aureon_mono_bool_info snd_ctl_boolean_mono_info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) * AC'97 master playback mute controls (Mute on WM8770 chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) #define aureon_ac97_mmute_info snd_ctl_boolean_mono_info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) static int aureon_ac97_mmute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) mutex_lock(&ice->gpio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) ucontrol->value.integer.value[0] = (wm_get(ice, WM_OUT_MUX1) >> 1) & 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) mutex_unlock(&ice->gpio_mutex);
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) static int aureon_ac97_mmute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) unsigned short ovol, nvol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) int change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) snd_ice1712_save_gpio_status(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) ovol = wm_get(ice, WM_OUT_MUX1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) nvol = (ovol & ~0x02) | (ucontrol->value.integer.value[0] ? 0x02 : 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) change = (ovol != nvol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) if (change)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) wm_put(ice, WM_OUT_MUX1, nvol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) snd_ice1712_restore_gpio_status(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) static const DECLARE_TLV_DB_SCALE(db_scale_wm_dac, -10000, 100, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) static const DECLARE_TLV_DB_SCALE(db_scale_wm_pcm, -6400, 50, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) static const DECLARE_TLV_DB_SCALE(db_scale_wm_adc, -1200, 100, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) static const DECLARE_TLV_DB_SCALE(db_scale_ac97_master, -4650, 150, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) static const DECLARE_TLV_DB_SCALE(db_scale_ac97_gain, -3450, 150, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) #define WM_VOL_MAX 100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) #define WM_VOL_CNT 101 /* 0dB .. -100dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) #define WM_VOL_MUTE 0x8000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index, unsigned short vol, unsigned short master)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) unsigned char nvol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) if ((master & WM_VOL_MUTE) || (vol & WM_VOL_MUTE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) nvol = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) nvol = ((vol % WM_VOL_CNT) * (master % WM_VOL_CNT)) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) WM_VOL_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) nvol += 0x1b;
^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) wm_put(ice, index, nvol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) wm_put_nocache(ice, index, 0x180 | nvol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) }
^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) * DAC mute control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) #define wm_pcm_mute_info snd_ctl_boolean_mono_info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) static int wm_pcm_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) mutex_lock(&ice->gpio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) ucontrol->value.integer.value[0] = (wm_get(ice, WM_MUTE) & 0x10) ? 0 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) mutex_unlock(&ice->gpio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) static int wm_pcm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) unsigned short nval, oval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) int change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) snd_ice1712_save_gpio_status(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) oval = wm_get(ice, WM_MUTE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) nval = (oval & ~0x10) | (ucontrol->value.integer.value[0] ? 0 : 0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) change = (oval != nval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) if (change)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) wm_put(ice, WM_MUTE, nval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) snd_ice1712_restore_gpio_status(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) * Master volume attenuation mixer control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) static int wm_master_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) uinfo->count = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) uinfo->value.integer.min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) uinfo->value.integer.max = WM_VOL_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) static int wm_master_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) struct aureon_spec *spec = ice->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) for (i = 0; i < 2; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) ucontrol->value.integer.value[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) spec->master[i] & ~WM_VOL_MUTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) static int wm_master_vol_put(struct snd_kcontrol *kcontrol, 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 snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) struct aureon_spec *spec = ice->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) int ch, change = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) snd_ice1712_save_gpio_status(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) for (ch = 0; ch < 2; ch++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) unsigned int vol = ucontrol->value.integer.value[ch];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) if (vol > WM_VOL_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) vol = WM_VOL_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) vol |= spec->master[ch] & WM_VOL_MUTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) if (vol != spec->master[ch]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) int dac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) spec->master[ch] = vol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) for (dac = 0; dac < ice->num_total_dacs; dac += 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) wm_set_vol(ice, WM_DAC_ATTEN + dac + ch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) spec->vol[dac + ch],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) spec->master[ch]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) change = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) snd_ice1712_restore_gpio_status(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) * DAC volume attenuation mixer control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) static int wm_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) int voices = kcontrol->private_value >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) uinfo->count = voices;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) uinfo->value.integer.min = 0; /* mute (-101dB) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) uinfo->value.integer.max = WM_VOL_MAX; /* 0dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) static int wm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) struct aureon_spec *spec = ice->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) int i, ofs, voices;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) voices = kcontrol->private_value >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) ofs = kcontrol->private_value & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) for (i = 0; i < voices; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) ucontrol->value.integer.value[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) spec->vol[ofs+i] & ~WM_VOL_MUTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) static int wm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) struct aureon_spec *spec = ice->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) int i, idx, ofs, voices;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) int change = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) voices = kcontrol->private_value >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) ofs = kcontrol->private_value & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) snd_ice1712_save_gpio_status(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) for (i = 0; i < voices; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) unsigned int vol = ucontrol->value.integer.value[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) if (vol > WM_VOL_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) vol = WM_VOL_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) vol |= spec->vol[ofs+i] & WM_VOL_MUTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) if (vol != spec->vol[ofs+i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) spec->vol[ofs+i] = vol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) idx = WM_DAC_ATTEN + ofs + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) wm_set_vol(ice, idx, spec->vol[ofs + i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) spec->master[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) change = 1;
^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) snd_ice1712_restore_gpio_status(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) * WM8770 mute control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) static int wm_mute_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) uinfo->count = kcontrol->private_value >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) uinfo->value.integer.min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) uinfo->value.integer.max = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) static int wm_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) struct aureon_spec *spec = ice->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) int voices, ofs, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) voices = kcontrol->private_value >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) ofs = kcontrol->private_value & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) for (i = 0; i < voices; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) ucontrol->value.integer.value[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) (spec->vol[ofs + i] & WM_VOL_MUTE) ? 0 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) static int wm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) struct aureon_spec *spec = ice->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) int change = 0, voices, ofs, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) voices = kcontrol->private_value >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) ofs = kcontrol->private_value & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) snd_ice1712_save_gpio_status(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) for (i = 0; i < voices; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) int val = (spec->vol[ofs + i] & WM_VOL_MUTE) ? 0 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) if (ucontrol->value.integer.value[i] != val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) spec->vol[ofs + i] &= ~WM_VOL_MUTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) spec->vol[ofs + i] |=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) ucontrol->value.integer.value[i] ? 0 : WM_VOL_MUTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) wm_set_vol(ice, ofs + i, spec->vol[ofs + i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) spec->master[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) change = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) snd_ice1712_restore_gpio_status(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) * WM8770 master mute control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) #define wm_master_mute_info snd_ctl_boolean_stereo_info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) static int wm_master_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) struct aureon_spec *spec = ice->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) ucontrol->value.integer.value[0] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) (spec->master[0] & WM_VOL_MUTE) ? 0 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) ucontrol->value.integer.value[1] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) (spec->master[1] & WM_VOL_MUTE) ? 0 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) static int wm_master_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) struct aureon_spec *spec = ice->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) int change = 0, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) snd_ice1712_save_gpio_status(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) for (i = 0; i < 2; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) int val = (spec->master[i] & WM_VOL_MUTE) ? 0 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) if (ucontrol->value.integer.value[i] != val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) int dac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) spec->master[i] &= ~WM_VOL_MUTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) spec->master[i] |=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) ucontrol->value.integer.value[i] ? 0 : WM_VOL_MUTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) for (dac = 0; dac < ice->num_total_dacs; dac += 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) wm_set_vol(ice, WM_DAC_ATTEN + dac + i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) spec->vol[dac + i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) spec->master[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) change = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) snd_ice1712_restore_gpio_status(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) /* digital master volume */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) #define PCM_0dB 0xff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) #define PCM_RES 128 /* -64dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) #define PCM_MIN (PCM_0dB - PCM_RES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) static int wm_pcm_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) uinfo->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) uinfo->value.integer.min = 0; /* mute (-64dB) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) uinfo->value.integer.max = PCM_RES; /* 0dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) static int wm_pcm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) unsigned short val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) mutex_lock(&ice->gpio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) val = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) val = val > PCM_MIN ? (val - PCM_MIN) : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) ucontrol->value.integer.value[0] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) mutex_unlock(&ice->gpio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) static int wm_pcm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) unsigned short ovol, nvol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) int change = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) nvol = ucontrol->value.integer.value[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) if (nvol > PCM_RES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) snd_ice1712_save_gpio_status(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) nvol = (nvol ? (nvol + PCM_MIN) : 0) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) ovol = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) if (ovol != nvol) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) wm_put(ice, WM_DAC_DIG_MASTER_ATTEN, nvol); /* prelatch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) wm_put_nocache(ice, WM_DAC_DIG_MASTER_ATTEN, nvol | 0x100); /* update */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) change = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) snd_ice1712_restore_gpio_status(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) * ADC mute control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) #define wm_adc_mute_info snd_ctl_boolean_stereo_info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) static int wm_adc_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) unsigned short val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) mutex_lock(&ice->gpio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) for (i = 0; i < 2; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) val = wm_get(ice, WM_ADC_GAIN + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) ucontrol->value.integer.value[i] = ~val>>5 & 0x1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) mutex_unlock(&ice->gpio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) static int wm_adc_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) unsigned short new, old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) int i, change = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) snd_ice1712_save_gpio_status(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) for (i = 0; i < 2; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) old = wm_get(ice, WM_ADC_GAIN + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) new = (~ucontrol->value.integer.value[i]<<5&0x20) | (old&~0x20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) if (new != old) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) wm_put(ice, WM_ADC_GAIN + i, new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) change = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) snd_ice1712_restore_gpio_status(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) * ADC gain mixer control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) static int wm_adc_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) uinfo->count = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) uinfo->value.integer.min = 0; /* -12dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) uinfo->value.integer.max = 0x1f; /* 19dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) static int wm_adc_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) int i, idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) unsigned short vol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) mutex_lock(&ice->gpio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) for (i = 0; i < 2; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) idx = WM_ADC_GAIN + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) vol = wm_get(ice, idx) & 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) ucontrol->value.integer.value[i] = vol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) mutex_unlock(&ice->gpio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) static int wm_adc_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) int i, idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) unsigned short ovol, nvol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) int change = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) snd_ice1712_save_gpio_status(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) for (i = 0; i < 2; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) idx = WM_ADC_GAIN + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) nvol = ucontrol->value.integer.value[i] & 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) ovol = wm_get(ice, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) if ((ovol & 0x1f) != nvol) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) wm_put(ice, idx, nvol | (ovol & ~0x1f));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) change = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) snd_ice1712_restore_gpio_status(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) * ADC input mux mixer control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) static int wm_adc_mux_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) static const char * const texts[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) "CD", /* AIN1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) "Aux", /* AIN2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) "Line", /* AIN3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) "Mic", /* AIN4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) "AC97" /* AIN5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) static const char * const universe_texts[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) "Aux1", /* AIN1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) "CD", /* AIN2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) "Phono", /* AIN3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) "Line", /* AIN4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) "Aux2", /* AIN5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) "Mic", /* AIN6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) "Aux3", /* AIN7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) "AC97" /* AIN8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON71_UNIVERSE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) return snd_ctl_enum_info(uinfo, 2, 8, universe_texts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) return snd_ctl_enum_info(uinfo, 2, 5, texts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) static int wm_adc_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) unsigned short val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) mutex_lock(&ice->gpio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) val = wm_get(ice, WM_ADC_MUX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) ucontrol->value.enumerated.item[0] = val & 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) ucontrol->value.enumerated.item[1] = (val >> 4) & 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) mutex_unlock(&ice->gpio_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) static int wm_adc_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) unsigned short oval, nval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) int change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) snd_ice1712_save_gpio_status(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) oval = wm_get(ice, WM_ADC_MUX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) nval = oval & ~0x77;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) nval |= ucontrol->value.enumerated.item[0] & 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) nval |= (ucontrol->value.enumerated.item[1] & 7) << 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) change = (oval != nval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) if (change)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) wm_put(ice, WM_ADC_MUX, nval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) snd_ice1712_restore_gpio_status(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) * CS8415 Input mux
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) static int aureon_cs8415_mux_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) static const char * const aureon_texts[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) "CD", /* RXP0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) "Optical" /* RXP1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) static const char * const prodigy_texts[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) "CD",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) "Coax"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) return snd_ctl_enum_info(uinfo, 1, 2, prodigy_texts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) return snd_ctl_enum_info(uinfo, 1, 2, aureon_texts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) static int aureon_cs8415_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) struct aureon_spec *spec = ice->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) /* snd_ice1712_save_gpio_status(ice); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) /* val = aureon_cs8415_get(ice, CS8415_CTRL2); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) ucontrol->value.enumerated.item[0] = spec->cs8415_mux;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) /* snd_ice1712_restore_gpio_status(ice); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) static int aureon_cs8415_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) struct aureon_spec *spec = ice->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) unsigned short oval, nval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) int change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) snd_ice1712_save_gpio_status(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) oval = aureon_cs8415_get(ice, CS8415_CTRL2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) nval = oval & ~0x07;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) nval |= ucontrol->value.enumerated.item[0] & 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) change = (oval != nval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) if (change)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) aureon_cs8415_put(ice, CS8415_CTRL2, nval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) snd_ice1712_restore_gpio_status(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) spec->cs8415_mux = ucontrol->value.enumerated.item[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) static int aureon_cs8415_rate_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) uinfo->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) uinfo->value.integer.min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) uinfo->value.integer.max = 192000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) static int aureon_cs8415_rate_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) unsigned char ratio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) ratio = aureon_cs8415_get(ice, CS8415_RATIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) ucontrol->value.integer.value[0] = (int)((unsigned int)ratio * 750);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) * CS8415A Mute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) #define aureon_cs8415_mute_info snd_ctl_boolean_mono_info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) static int aureon_cs8415_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) snd_ice1712_save_gpio_status(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) ucontrol->value.integer.value[0] = (aureon_cs8415_get(ice, CS8415_CTRL1) & 0x20) ? 0 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) snd_ice1712_restore_gpio_status(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) static int aureon_cs8415_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) unsigned char oval, nval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) int change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) snd_ice1712_save_gpio_status(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) oval = aureon_cs8415_get(ice, CS8415_CTRL1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) if (ucontrol->value.integer.value[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) nval = oval & ~0x20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) nval = oval | 0x20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) change = (oval != nval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) if (change)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) aureon_cs8415_put(ice, CS8415_CTRL1, nval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) snd_ice1712_restore_gpio_status(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) * CS8415A Q-Sub info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) static int aureon_cs8415_qsub_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) uinfo->count = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) static int aureon_cs8415_qsub_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) snd_ice1712_save_gpio_status(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) aureon_cs8415_read(ice, CS8415_QSUB, ucontrol->value.bytes.data, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) snd_ice1712_restore_gpio_status(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) static int aureon_cs8415_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) uinfo->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) static int aureon_cs8415_mask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) memset(ucontrol->value.iec958.status, 0xFF, 24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) static int aureon_cs8415_spdif_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) snd_ice1712_save_gpio_status(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) aureon_cs8415_read(ice, CS8415_C_BUFFER, ucontrol->value.iec958.status, 24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) snd_ice1712_restore_gpio_status(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) * Headphone Amplifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) static int aureon_set_headphone_amp(struct snd_ice1712 *ice, int enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) unsigned int tmp, tmp2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) tmp2 = tmp = snd_ice1712_gpio_read(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) if (enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) tmp |= AUREON_HP_SEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) tmp |= PRODIGY_HP_SEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) tmp &= ~AUREON_HP_SEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) tmp &= ~PRODIGY_HP_SEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) if (tmp != tmp2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) snd_ice1712_gpio_write(ice, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) static int aureon_get_headphone_amp(struct snd_ice1712 *ice)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) unsigned int tmp = snd_ice1712_gpio_read(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) return (tmp & AUREON_HP_SEL) != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) #define aureon_hpamp_info snd_ctl_boolean_mono_info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) static int aureon_hpamp_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) ucontrol->value.integer.value[0] = aureon_get_headphone_amp(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) static int aureon_hpamp_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) return aureon_set_headphone_amp(ice, ucontrol->value.integer.value[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) * Deemphasis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) #define aureon_deemp_info snd_ctl_boolean_mono_info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) static int aureon_deemp_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) ucontrol->value.integer.value[0] = (wm_get(ice, WM_DAC_CTRL2) & 0xf) == 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) static int aureon_deemp_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) int temp, temp2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) temp2 = temp = wm_get(ice, WM_DAC_CTRL2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) if (ucontrol->value.integer.value[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) temp |= 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) temp &= ~0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) if (temp != temp2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) wm_put(ice, WM_DAC_CTRL2, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) * ADC Oversampling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) static int aureon_oversampling_info(struct snd_kcontrol *k, struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) static const char * const texts[2] = { "128x", "64x" };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) return snd_ctl_enum_info(uinfo, 1, 2, texts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) static int aureon_oversampling_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) ucontrol->value.enumerated.item[0] = (wm_get(ice, WM_MASTER) & 0x8) == 0x8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) static int aureon_oversampling_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) int temp, temp2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) temp2 = temp = wm_get(ice, WM_MASTER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) if (ucontrol->value.enumerated.item[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) temp |= 0x8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) temp &= ~0x8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) if (temp != temp2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) wm_put(ice, WM_MASTER, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) * mixers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) static const struct snd_kcontrol_new aureon_dac_controls[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) .name = "Master Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) .info = wm_master_mute_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) .get = wm_master_mute_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) .put = wm_master_mute_put
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) SNDRV_CTL_ELEM_ACCESS_TLV_READ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) .name = "Master Playback Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) .info = wm_master_vol_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) .get = wm_master_vol_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) .put = wm_master_vol_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) .tlv = { .p = db_scale_wm_dac }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) .name = "Front Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) .info = wm_mute_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) .get = wm_mute_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) .put = wm_mute_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) .private_value = (2 << 8) | 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) SNDRV_CTL_ELEM_ACCESS_TLV_READ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) .name = "Front Playback Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) .info = wm_vol_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) .get = wm_vol_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) .put = wm_vol_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) .private_value = (2 << 8) | 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) .tlv = { .p = db_scale_wm_dac }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) .name = "Rear Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) .info = wm_mute_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) .get = wm_mute_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) .put = wm_mute_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) .private_value = (2 << 8) | 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) SNDRV_CTL_ELEM_ACCESS_TLV_READ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) .name = "Rear Playback Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) .info = wm_vol_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) .get = wm_vol_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) .put = wm_vol_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) .private_value = (2 << 8) | 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) .tlv = { .p = db_scale_wm_dac }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) .name = "Center Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) .info = wm_mute_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) .get = wm_mute_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) .put = wm_mute_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) .private_value = (1 << 8) | 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) SNDRV_CTL_ELEM_ACCESS_TLV_READ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) .name = "Center Playback Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) .info = wm_vol_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) .get = wm_vol_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) .put = wm_vol_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) .private_value = (1 << 8) | 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) .tlv = { .p = db_scale_wm_dac }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) .name = "LFE Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) .info = wm_mute_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) .get = wm_mute_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) .put = wm_mute_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) .private_value = (1 << 8) | 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) SNDRV_CTL_ELEM_ACCESS_TLV_READ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) .name = "LFE Playback Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) .info = wm_vol_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) .get = wm_vol_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) .put = wm_vol_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) .private_value = (1 << 8) | 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) .tlv = { .p = db_scale_wm_dac }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) .name = "Side Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) .info = wm_mute_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) .get = wm_mute_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) .put = wm_mute_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) .private_value = (2 << 8) | 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) SNDRV_CTL_ELEM_ACCESS_TLV_READ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) .name = "Side Playback Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) .info = wm_vol_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) .get = wm_vol_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) .put = wm_vol_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) .private_value = (2 << 8) | 6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) .tlv = { .p = db_scale_wm_dac }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) static const struct snd_kcontrol_new wm_controls[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) .name = "PCM Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) .info = wm_pcm_mute_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) .get = wm_pcm_mute_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) .put = wm_pcm_mute_put
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) SNDRV_CTL_ELEM_ACCESS_TLV_READ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) .name = "PCM Playback Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) .info = wm_pcm_vol_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) .get = wm_pcm_vol_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) .put = wm_pcm_vol_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) .tlv = { .p = db_scale_wm_pcm }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) .name = "Capture Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) .info = wm_adc_mute_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) .get = wm_adc_mute_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) .put = wm_adc_mute_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) SNDRV_CTL_ELEM_ACCESS_TLV_READ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) .name = "Capture Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) .info = wm_adc_vol_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) .get = wm_adc_vol_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) .put = wm_adc_vol_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) .tlv = { .p = db_scale_wm_adc }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) .name = "Capture Source",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) .info = wm_adc_mux_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) .get = wm_adc_mux_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) .put = wm_adc_mux_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) .private_value = 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) .name = "External Amplifier",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) .info = aureon_hpamp_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) .get = aureon_hpamp_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) .put = aureon_hpamp_put
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) .name = "DAC Deemphasis Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) .info = aureon_deemp_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) .get = aureon_deemp_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) .put = aureon_deemp_put
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) .name = "ADC Oversampling",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) .info = aureon_oversampling_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) .get = aureon_oversampling_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) .put = aureon_oversampling_put
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) static const struct snd_kcontrol_new ac97_controls[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) .name = "AC97 Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) .info = aureon_ac97_mmute_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) .get = aureon_ac97_mmute_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) .put = aureon_ac97_mmute_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) .private_value = AC97_MASTER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) SNDRV_CTL_ELEM_ACCESS_TLV_READ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) .name = "AC97 Playback Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) .info = aureon_ac97_vol_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) .get = aureon_ac97_vol_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) .put = aureon_ac97_vol_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) .private_value = AC97_MASTER|AUREON_AC97_STEREO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) .tlv = { .p = db_scale_ac97_master }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) .name = "CD Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) .info = aureon_ac97_mute_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) .get = aureon_ac97_mute_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) .put = aureon_ac97_mute_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) .private_value = AC97_CD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) SNDRV_CTL_ELEM_ACCESS_TLV_READ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) .name = "CD Playback Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) .info = aureon_ac97_vol_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) .get = aureon_ac97_vol_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) .put = aureon_ac97_vol_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) .private_value = AC97_CD|AUREON_AC97_STEREO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) .tlv = { .p = db_scale_ac97_gain }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) .name = "Aux Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) .info = aureon_ac97_mute_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) .get = aureon_ac97_mute_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) .put = aureon_ac97_mute_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) .private_value = AC97_AUX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) SNDRV_CTL_ELEM_ACCESS_TLV_READ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) .name = "Aux Playback Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) .info = aureon_ac97_vol_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) .get = aureon_ac97_vol_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) .put = aureon_ac97_vol_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) .private_value = AC97_AUX|AUREON_AC97_STEREO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) .tlv = { .p = db_scale_ac97_gain }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) .name = "Line Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) .info = aureon_ac97_mute_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) .get = aureon_ac97_mute_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) .put = aureon_ac97_mute_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) .private_value = AC97_LINE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) SNDRV_CTL_ELEM_ACCESS_TLV_READ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) .name = "Line Playback Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) .info = aureon_ac97_vol_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) .get = aureon_ac97_vol_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) .put = aureon_ac97_vol_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) .private_value = AC97_LINE|AUREON_AC97_STEREO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) .tlv = { .p = db_scale_ac97_gain }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) .name = "Mic Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) .info = aureon_ac97_mute_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) .get = aureon_ac97_mute_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) .put = aureon_ac97_mute_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) .private_value = AC97_MIC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) SNDRV_CTL_ELEM_ACCESS_TLV_READ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) .name = "Mic Playback Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) .info = aureon_ac97_vol_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) .get = aureon_ac97_vol_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) .put = aureon_ac97_vol_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) .private_value = AC97_MIC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) .tlv = { .p = db_scale_ac97_gain }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) .name = "Mic Boost (+20dB)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) .info = aureon_ac97_micboost_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) .get = aureon_ac97_micboost_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) .put = aureon_ac97_micboost_put
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) static const struct snd_kcontrol_new universe_ac97_controls[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) .name = "AC97 Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) .info = aureon_ac97_mmute_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) .get = aureon_ac97_mmute_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) .put = aureon_ac97_mmute_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) .private_value = AC97_MASTER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) SNDRV_CTL_ELEM_ACCESS_TLV_READ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) .name = "AC97 Playback Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) .info = aureon_ac97_vol_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) .get = aureon_ac97_vol_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) .put = aureon_ac97_vol_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) .private_value = AC97_MASTER|AUREON_AC97_STEREO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) .tlv = { .p = db_scale_ac97_master }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) .name = "CD Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) .info = aureon_ac97_mute_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) .get = aureon_ac97_mute_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) .put = aureon_ac97_mute_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) .private_value = AC97_AUX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) SNDRV_CTL_ELEM_ACCESS_TLV_READ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) .name = "CD Playback Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) .info = aureon_ac97_vol_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) .get = aureon_ac97_vol_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) .put = aureon_ac97_vol_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) .private_value = AC97_AUX|AUREON_AC97_STEREO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) .tlv = { .p = db_scale_ac97_gain }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) .name = "Phono Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) .info = aureon_ac97_mute_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) .get = aureon_ac97_mute_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) .put = aureon_ac97_mute_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) .private_value = AC97_CD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) SNDRV_CTL_ELEM_ACCESS_TLV_READ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) .name = "Phono Playback Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) .info = aureon_ac97_vol_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) .get = aureon_ac97_vol_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) .put = aureon_ac97_vol_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) .private_value = AC97_CD|AUREON_AC97_STEREO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) .tlv = { .p = db_scale_ac97_gain }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) .name = "Line Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) .info = aureon_ac97_mute_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) .get = aureon_ac97_mute_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) .put = aureon_ac97_mute_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) .private_value = AC97_LINE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) SNDRV_CTL_ELEM_ACCESS_TLV_READ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) .name = "Line Playback Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) .info = aureon_ac97_vol_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) .get = aureon_ac97_vol_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) .put = aureon_ac97_vol_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) .private_value = AC97_LINE|AUREON_AC97_STEREO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) .tlv = { .p = db_scale_ac97_gain }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) .name = "Mic Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) .info = aureon_ac97_mute_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) .get = aureon_ac97_mute_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) .put = aureon_ac97_mute_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) .private_value = AC97_MIC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) SNDRV_CTL_ELEM_ACCESS_TLV_READ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) .name = "Mic Playback Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) .info = aureon_ac97_vol_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) .get = aureon_ac97_vol_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) .put = aureon_ac97_vol_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) .private_value = AC97_MIC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) .tlv = { .p = db_scale_ac97_gain }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) .name = "Mic Boost (+20dB)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) .info = aureon_ac97_micboost_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) .get = aureon_ac97_micboost_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) .put = aureon_ac97_micboost_put
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) .name = "Aux Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) .info = aureon_ac97_mute_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) .get = aureon_ac97_mute_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) .put = aureon_ac97_mute_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) .private_value = AC97_VIDEO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) SNDRV_CTL_ELEM_ACCESS_TLV_READ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) .name = "Aux Playback Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) .info = aureon_ac97_vol_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) .get = aureon_ac97_vol_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) .put = aureon_ac97_vol_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) .private_value = AC97_VIDEO|AUREON_AC97_STEREO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) .tlv = { .p = db_scale_ac97_gain }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) .name = "Aux Source",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) .info = aureon_universe_inmux_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) .get = aureon_universe_inmux_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) .put = aureon_universe_inmux_put
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) static const struct snd_kcontrol_new cs8415_controls[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, SWITCH),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) .info = aureon_cs8415_mute_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) .get = aureon_cs8415_mute_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) .put = aureon_cs8415_mute_put
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, NONE) "Source",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) .info = aureon_cs8415_mux_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) .get = aureon_cs8415_mux_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) .put = aureon_cs8415_mux_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) .iface = SNDRV_CTL_ELEM_IFACE_PCM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) .name = SNDRV_CTL_NAME_IEC958("Q-subcode ", CAPTURE, DEFAULT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) .info = aureon_cs8415_qsub_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) .get = aureon_cs8415_qsub_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) .iface = SNDRV_CTL_ELEM_IFACE_PCM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, MASK),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) .access = SNDRV_CTL_ELEM_ACCESS_READ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) .info = aureon_cs8415_spdif_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) .get = aureon_cs8415_mask_get
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) .iface = SNDRV_CTL_ELEM_IFACE_PCM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, DEFAULT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) .info = aureon_cs8415_spdif_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) .get = aureon_cs8415_spdif_get
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) .iface = SNDRV_CTL_ELEM_IFACE_PCM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, NONE) "Rate",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) .info = aureon_cs8415_rate_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) .get = aureon_cs8415_rate_get
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) static int aureon_add_controls(struct snd_ice1712 *ice)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) unsigned int i, counts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) counts = ARRAY_SIZE(aureon_dac_controls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON51_SKY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) counts -= 2; /* no side */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) for (i = 0; i < counts; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) err = snd_ctl_add(ice->card, snd_ctl_new1(&aureon_dac_controls[i], ice));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) for (i = 0; i < ARRAY_SIZE(wm_controls); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) err = snd_ctl_add(ice->card, snd_ctl_new1(&wm_controls[i], ice));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON71_UNIVERSE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) for (i = 0; i < ARRAY_SIZE(universe_ac97_controls); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) err = snd_ctl_add(ice->card, snd_ctl_new1(&universe_ac97_controls[i], ice));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) } else if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) for (i = 0; i < ARRAY_SIZE(ac97_controls); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) err = snd_ctl_add(ice->card, snd_ctl_new1(&ac97_controls[i], ice));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) unsigned char id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) snd_ice1712_save_gpio_status(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) id = aureon_cs8415_get(ice, CS8415_ID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) if (id != 0x41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) dev_info(ice->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) "No CS8415 chip. Skipping CS8415 controls.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) else if ((id & 0x0F) != 0x01)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) dev_info(ice->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) "Detected unsupported CS8415 rev. (%c)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) (char)((id & 0x0F) + 'A' - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) for (i = 0; i < ARRAY_SIZE(cs8415_controls); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) struct snd_kcontrol *kctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) err = snd_ctl_add(ice->card, (kctl = snd_ctl_new1(&cs8415_controls[i], ice)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) if (i > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) kctl->id.device = ice->pcm->device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) snd_ice1712_restore_gpio_status(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) * reset the chip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) static int aureon_reset(struct snd_ice1712 *ice)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) static const unsigned short wm_inits_aureon[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) /* These come first to reduce init pop noise */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) 0x1b, 0x044, /* ADC Mux (AC'97 source) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) 0x1c, 0x00B, /* Out Mux1 (VOUT1 = DAC+AUX, VOUT2 = DAC) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) 0x1d, 0x009, /* Out Mux2 (VOUT2 = DAC, VOUT3 = DAC) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) 0x18, 0x000, /* All power-up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) 0x16, 0x122, /* I2S, normal polarity, 24bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) 0x17, 0x022, /* 256fs, slave mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) 0x00, 0, /* DAC1 analog mute */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) 0x01, 0, /* DAC2 analog mute */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) 0x02, 0, /* DAC3 analog mute */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) 0x03, 0, /* DAC4 analog mute */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) 0x04, 0, /* DAC5 analog mute */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) 0x05, 0, /* DAC6 analog mute */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) 0x06, 0, /* DAC7 analog mute */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) 0x07, 0, /* DAC8 analog mute */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) 0x08, 0x100, /* master analog mute */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) 0x09, 0xff, /* DAC1 digital full */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) 0x0a, 0xff, /* DAC2 digital full */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) 0x0b, 0xff, /* DAC3 digital full */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) 0x0c, 0xff, /* DAC4 digital full */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) 0x0d, 0xff, /* DAC5 digital full */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) 0x0e, 0xff, /* DAC6 digital full */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) 0x0f, 0xff, /* DAC7 digital full */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) 0x10, 0xff, /* DAC8 digital full */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) 0x11, 0x1ff, /* master digital full */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) 0x12, 0x000, /* phase normal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) 0x13, 0x090, /* unmute DAC L/R */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) 0x14, 0x000, /* all unmute */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) 0x15, 0x000, /* no deemphasis, no ZFLG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) 0x19, 0x000, /* -12dB ADC/L */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) 0x1a, 0x000, /* -12dB ADC/R */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) (unsigned short)-1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) static const unsigned short wm_inits_prodigy[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) /* These come first to reduce init pop noise */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) 0x1b, 0x000, /* ADC Mux */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) 0x1c, 0x009, /* Out Mux1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) 0x1d, 0x009, /* Out Mux2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) 0x18, 0x000, /* All power-up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) 0x16, 0x022, /* I2S, normal polarity, 24bit, high-pass on */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) 0x17, 0x006, /* 128fs, slave mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) 0x00, 0, /* DAC1 analog mute */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) 0x01, 0, /* DAC2 analog mute */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) 0x02, 0, /* DAC3 analog mute */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) 0x03, 0, /* DAC4 analog mute */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) 0x04, 0, /* DAC5 analog mute */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) 0x05, 0, /* DAC6 analog mute */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) 0x06, 0, /* DAC7 analog mute */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) 0x07, 0, /* DAC8 analog mute */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) 0x08, 0x100, /* master analog mute */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) 0x09, 0x7f, /* DAC1 digital full */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) 0x0a, 0x7f, /* DAC2 digital full */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) 0x0b, 0x7f, /* DAC3 digital full */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) 0x0c, 0x7f, /* DAC4 digital full */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) 0x0d, 0x7f, /* DAC5 digital full */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) 0x0e, 0x7f, /* DAC6 digital full */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) 0x0f, 0x7f, /* DAC7 digital full */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) 0x10, 0x7f, /* DAC8 digital full */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) 0x11, 0x1FF, /* master digital full */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) 0x12, 0x000, /* phase normal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) 0x13, 0x090, /* unmute DAC L/R */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) 0x14, 0x000, /* all unmute */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) 0x15, 0x000, /* no deemphasis, no ZFLG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) 0x19, 0x000, /* -12dB ADC/L */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) 0x1a, 0x000, /* -12dB ADC/R */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) (unsigned short)-1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) static const unsigned short cs_inits[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) 0x0441, /* RUN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) 0x0180, /* no mute, OMCK output on RMCK pin */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) 0x0201, /* S/PDIF source on RXP1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) 0x0605, /* slave, 24bit, MSB on second OSCLK, SDOUT for right channel when OLRCK is high */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) (unsigned short)-1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) unsigned int tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) const unsigned short *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) struct aureon_spec *spec = ice->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) err = aureon_ac97_init(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) if (err != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) snd_ice1712_gpio_set_dir(ice, 0x5fffff); /* fix this for the time being */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) /* reset the wm codec as the SPI mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) snd_ice1712_save_gpio_status(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) snd_ice1712_gpio_set_mask(ice, ~(AUREON_WM_RESET|AUREON_WM_CS|AUREON_CS8415_CS|AUREON_HP_SEL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) tmp = snd_ice1712_gpio_read(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) tmp &= ~AUREON_WM_RESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) snd_ice1712_gpio_write(ice, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) tmp |= AUREON_WM_CS | AUREON_CS8415_CS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) snd_ice1712_gpio_write(ice, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) tmp |= AUREON_WM_RESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) snd_ice1712_gpio_write(ice, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) /* initialize WM8770 codec */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71XT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) p = wm_inits_prodigy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) p = wm_inits_aureon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) for (; *p != (unsigned short)-1; p += 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) wm_put(ice, p[0], p[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) /* initialize CS8415A codec */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) for (p = cs_inits; *p != (unsigned short)-1; p++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) aureon_spi_write(ice, AUREON_CS8415_CS, *p | 0x200000, 24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) spec->cs8415_mux = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) aureon_set_headphone_amp(ice, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) snd_ice1712_restore_gpio_status(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) /* initialize PCA9554 pin directions & set default input */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) aureon_pca9554_write(ice, PCA9554_DIR, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) aureon_pca9554_write(ice, PCA9554_OUT, 0x00); /* internal AUX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) * suspend/resume
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) static int aureon_resume(struct snd_ice1712 *ice)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) struct aureon_spec *spec = ice->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) int err, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) err = aureon_reset(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) if (err != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) /* workaround for poking volume with alsamixer after resume:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) * just set stored volume again */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) for (i = 0; i < ice->num_total_dacs; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) wm_set_vol(ice, i, spec->vol[i], spec->master[i % 2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) * initialize the chip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) static int aureon_init(struct snd_ice1712 *ice)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) struct aureon_spec *spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) int i, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) spec = kzalloc(sizeof(*spec), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) if (!spec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) ice->spec = spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON51_SKY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) ice->num_total_dacs = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) ice->num_total_adcs = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) /* aureon 7.1 and prodigy 7.1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) ice->num_total_dacs = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) ice->num_total_adcs = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) /* to remember the register values of CS8415 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) if (!ice->akm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) ice->akm_codecs = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) err = aureon_reset(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) if (err != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) spec->master[0] = WM_VOL_MUTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) spec->master[1] = WM_VOL_MUTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) for (i = 0; i < ice->num_total_dacs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) spec->vol[i] = WM_VOL_MUTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) wm_set_vol(ice, i, spec->vol[i], spec->master[i % 2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) ice->pm_resume = aureon_resume;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) ice->pm_suspend_enabled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) * Aureon boards don't provide the EEPROM data except for the vendor IDs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) * hence the driver needs to sets up it properly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) static const unsigned char aureon51_eeprom[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) [ICE_EEP2_SYSCONF] = 0x0a, /* clock 512, spdif-in/ADC, 3DACs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) [ICE_EEP2_ACLINK] = 0x80, /* I2S */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) [ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) [ICE_EEP2_GPIO_DIR] = 0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) [ICE_EEP2_GPIO_DIR1] = 0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) [ICE_EEP2_GPIO_DIR2] = 0x5f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) [ICE_EEP2_GPIO_MASK] = 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) [ICE_EEP2_GPIO_MASK1] = 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) [ICE_EEP2_GPIO_MASK2] = 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) [ICE_EEP2_GPIO_STATE] = 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) [ICE_EEP2_GPIO_STATE1] = 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) [ICE_EEP2_GPIO_STATE2] = 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) static const unsigned char aureon71_eeprom[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) [ICE_EEP2_SYSCONF] = 0x0b, /* clock 512, spdif-in/ADC, 4DACs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) [ICE_EEP2_ACLINK] = 0x80, /* I2S */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) [ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) [ICE_EEP2_GPIO_DIR] = 0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) [ICE_EEP2_GPIO_DIR1] = 0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) [ICE_EEP2_GPIO_DIR2] = 0x5f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) [ICE_EEP2_GPIO_MASK] = 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) [ICE_EEP2_GPIO_MASK1] = 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) [ICE_EEP2_GPIO_MASK2] = 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) [ICE_EEP2_GPIO_STATE] = 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) [ICE_EEP2_GPIO_STATE1] = 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) [ICE_EEP2_GPIO_STATE2] = 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) #define prodigy71_eeprom aureon71_eeprom
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) static const unsigned char aureon71_universe_eeprom[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) [ICE_EEP2_SYSCONF] = 0x2b, /* clock 512, mpu401, spdif-in/ADC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) * 4DACs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) [ICE_EEP2_ACLINK] = 0x80, /* I2S */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) [ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) [ICE_EEP2_GPIO_DIR] = 0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) [ICE_EEP2_GPIO_DIR1] = 0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) [ICE_EEP2_GPIO_DIR2] = 0x5f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) [ICE_EEP2_GPIO_MASK] = 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) [ICE_EEP2_GPIO_MASK1] = 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) [ICE_EEP2_GPIO_MASK2] = 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) [ICE_EEP2_GPIO_STATE] = 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) [ICE_EEP2_GPIO_STATE1] = 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) [ICE_EEP2_GPIO_STATE2] = 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) static const unsigned char prodigy71lt_eeprom[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) [ICE_EEP2_SYSCONF] = 0x4b, /* clock 384, spdif-in/ADC, 4DACs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) [ICE_EEP2_ACLINK] = 0x80, /* I2S */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) [ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) [ICE_EEP2_GPIO_DIR] = 0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) [ICE_EEP2_GPIO_DIR1] = 0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) [ICE_EEP2_GPIO_DIR2] = 0x5f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) [ICE_EEP2_GPIO_MASK] = 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) [ICE_EEP2_GPIO_MASK1] = 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) [ICE_EEP2_GPIO_MASK2] = 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) [ICE_EEP2_GPIO_STATE] = 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) [ICE_EEP2_GPIO_STATE1] = 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) [ICE_EEP2_GPIO_STATE2] = 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) #define prodigy71xt_eeprom prodigy71lt_eeprom
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) /* entry point */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) struct snd_ice1712_card_info snd_vt1724_aureon_cards[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) .subvendor = VT1724_SUBDEVICE_AUREON51_SKY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) .name = "Terratec Aureon 5.1-Sky",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) .model = "aureon51",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) .chip_init = aureon_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) .build_controls = aureon_add_controls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) .eeprom_size = sizeof(aureon51_eeprom),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) .eeprom_data = aureon51_eeprom,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) .driver = "Aureon51",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) .subvendor = VT1724_SUBDEVICE_AUREON71_SPACE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) .name = "Terratec Aureon 7.1-Space",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) .model = "aureon71",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) .chip_init = aureon_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) .build_controls = aureon_add_controls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) .eeprom_size = sizeof(aureon71_eeprom),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) .eeprom_data = aureon71_eeprom,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) .driver = "Aureon71",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) .subvendor = VT1724_SUBDEVICE_AUREON71_UNIVERSE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) .name = "Terratec Aureon 7.1-Universe",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) .model = "universe",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) .chip_init = aureon_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) .build_controls = aureon_add_controls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) .eeprom_size = sizeof(aureon71_universe_eeprom),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) .eeprom_data = aureon71_universe_eeprom,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) .driver = "Aureon71Univ", /* keep in 15 letters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) .subvendor = VT1724_SUBDEVICE_PRODIGY71,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) .name = "Audiotrak Prodigy 7.1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) .model = "prodigy71",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) .chip_init = aureon_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) .build_controls = aureon_add_controls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) .eeprom_size = sizeof(prodigy71_eeprom),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) .eeprom_data = prodigy71_eeprom,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) .driver = "Prodigy71", /* should be identical with Aureon71 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) .subvendor = VT1724_SUBDEVICE_PRODIGY71LT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) .name = "Audiotrak Prodigy 7.1 LT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) .model = "prodigy71lt",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) .chip_init = aureon_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) .build_controls = aureon_add_controls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) .eeprom_size = sizeof(prodigy71lt_eeprom),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) .eeprom_data = prodigy71lt_eeprom,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) .driver = "Prodigy71LT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) .subvendor = VT1724_SUBDEVICE_PRODIGY71XT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) .name = "Audiotrak Prodigy 7.1 XT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) .model = "prodigy71xt",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) .chip_init = aureon_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) .build_controls = aureon_add_controls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) .eeprom_size = sizeof(prodigy71xt_eeprom),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) .eeprom_data = prodigy71xt_eeprom,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) .driver = "Prodigy71LT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) { } /* terminator */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) };