Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  *   ALSA driver for ICEnsemble ICE1724 (Envy24)
0004  *
0005  *   Lowlevel functions for Terratec PHASE 22
0006  *
0007  *  Copyright (c) 2005 Misha Zhilin <misha@epiphan.com>
0008  */
0009 
0010 /* PHASE 22 overview:
0011  *   Audio controller: VIA Envy24HT-S (slightly trimmed down Envy24HT, 4in/4out)
0012  *   Analog chip: AK4524 (partially via Philip's 74HCT125)
0013  *   Digital receiver: CS8414-CS (supported in this release)
0014  *      PHASE 22 revision 2.0 and Terrasoniq/Musonik TS22PCI have CS8416
0015  *      (support status unknown, please test and report)
0016  *
0017  *   Envy connects to AK4524
0018  *  - CS directly from GPIO 10
0019  *  - CCLK via 74HCT125's gate #4 from GPIO 4
0020  *  - CDTI via 74HCT125's gate #2 from GPIO 5
0021  *      CDTI may be completely blocked by 74HCT125's gate #1
0022  *      controlled by GPIO 3
0023  */
0024 
0025 /* PHASE 28 overview:
0026  *   Audio controller: VIA Envy24HT (full untrimmed version, 4in/8out)
0027  *   Analog chip: WM8770 (8 channel 192k DAC, 2 channel 96k ADC)
0028  *   Digital receiver: CS8414-CS (supported in this release)
0029  */
0030 
0031 #include <linux/delay.h>
0032 #include <linux/interrupt.h>
0033 #include <linux/init.h>
0034 #include <linux/slab.h>
0035 #include <linux/mutex.h>
0036 
0037 #include <sound/core.h>
0038 
0039 #include "ice1712.h"
0040 #include "envy24ht.h"
0041 #include "phase.h"
0042 #include <sound/tlv.h>
0043 
0044 /* AC97 register cache for Phase28 */
0045 struct phase28_spec {
0046     unsigned short master[2];
0047     unsigned short vol[8];
0048 };
0049 
0050 /* WM8770 registers */
0051 #define WM_DAC_ATTEN        0x00    /* DAC1-8 analog attenuation */
0052 #define WM_DAC_MASTER_ATTEN 0x08    /* DAC master analog attenuation */
0053 #define WM_DAC_DIG_ATTEN    0x09    /* DAC1-8 digital attenuation */
0054 #define WM_DAC_DIG_MASTER_ATTEN 0x11    /* DAC master digital attenuation */
0055 #define WM_PHASE_SWAP       0x12    /* DAC phase */
0056 #define WM_DAC_CTRL1        0x13    /* DAC control bits */
0057 #define WM_MUTE         0x14    /* mute controls */
0058 #define WM_DAC_CTRL2        0x15    /* de-emphasis and zefo-flag */
0059 #define WM_INT_CTRL     0x16    /* interface control */
0060 #define WM_MASTER       0x17    /* master clock and mode */
0061 #define WM_POWERDOWN        0x18    /* power-down controls */
0062 #define WM_ADC_GAIN     0x19    /* ADC gain L(19)/R(1a) */
0063 #define WM_ADC_MUX      0x1b    /* input MUX */
0064 #define WM_OUT_MUX1     0x1c    /* output MUX */
0065 #define WM_OUT_MUX2     0x1e    /* output MUX */
0066 #define WM_RESET        0x1f    /* software reset */
0067 
0068 
0069 /*
0070  * Logarithmic volume values for WM8770
0071  * Computed as 20 * Log10(255 / x)
0072  */
0073 static const unsigned char wm_vol[256] = {
0074     127, 48, 42, 39, 36, 34, 33, 31, 30, 29, 28, 27, 27, 26, 25, 25, 24,
0075     24, 23, 23, 22, 22, 21, 21, 21, 20, 20, 20, 19, 19, 19, 18, 18, 18, 18,
0076     17, 17, 17, 17, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14,
0077     14, 13, 13, 13, 13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11,
0078     11, 11, 11, 11, 11, 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9,
0079     9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7,
0080     7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5,
0081     5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
0082     4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
0083     3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
0084     2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0085     1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0086 };
0087 
0088 #define WM_VOL_MAX  (sizeof(wm_vol) - 1)
0089 #define WM_VOL_MUTE 0x8000
0090 
0091 static const struct snd_akm4xxx akm_phase22 = {
0092     .type = SND_AK4524,
0093     .num_dacs = 2,
0094     .num_adcs = 2,
0095 };
0096 
0097 static const struct snd_ak4xxx_private akm_phase22_priv = {
0098     .caddr =    2,
0099     .cif =      1,
0100     .data_mask =    1 << 4,
0101     .clk_mask = 1 << 5,
0102     .cs_mask =  1 << 10,
0103     .cs_addr =  1 << 10,
0104     .cs_none =  0,
0105     .add_flags =    1 << 3,
0106     .mask_flags =   0,
0107 };
0108 
0109 static int phase22_init(struct snd_ice1712 *ice)
0110 {
0111     struct snd_akm4xxx *ak;
0112     int err;
0113 
0114     /* Configure DAC/ADC description for generic part of ice1724 */
0115     switch (ice->eeprom.subvendor) {
0116     case VT1724_SUBDEVICE_PHASE22:
0117     case VT1724_SUBDEVICE_TS22:
0118         ice->num_total_dacs = 2;
0119         ice->num_total_adcs = 2;
0120         ice->vt1720 = 1; /* Envy24HT-S have 16 bit wide GPIO */
0121         break;
0122     default:
0123         snd_BUG();
0124         return -EINVAL;
0125     }
0126 
0127     /* Initialize analog chips */
0128     ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
0129     ak = ice->akm;
0130     if (!ak)
0131         return -ENOMEM;
0132     ice->akm_codecs = 1;
0133     switch (ice->eeprom.subvendor) {
0134     case VT1724_SUBDEVICE_PHASE22:
0135     case VT1724_SUBDEVICE_TS22:
0136         err = snd_ice1712_akm4xxx_init(ak, &akm_phase22,
0137                         &akm_phase22_priv, ice);
0138         if (err < 0)
0139             return err;
0140         break;
0141     }
0142 
0143     return 0;
0144 }
0145 
0146 static int phase22_add_controls(struct snd_ice1712 *ice)
0147 {
0148     int err = 0;
0149 
0150     switch (ice->eeprom.subvendor) {
0151     case VT1724_SUBDEVICE_PHASE22:
0152     case VT1724_SUBDEVICE_TS22:
0153         err = snd_ice1712_akm4xxx_build_controls(ice);
0154         if (err < 0)
0155             return err;
0156     }
0157     return 0;
0158 }
0159 
0160 static const unsigned char phase22_eeprom[] = {
0161     [ICE_EEP2_SYSCONF]     = 0x28,  /* clock 512, mpu 401,
0162                     spdif-in/1xADC, 1xDACs */
0163     [ICE_EEP2_ACLINK]      = 0x80,  /* I2S */
0164     [ICE_EEP2_I2S]         = 0xf0,  /* vol, 96k, 24bit */
0165     [ICE_EEP2_SPDIF]       = 0xc3,  /* out-en, out-int, spdif-in */
0166     [ICE_EEP2_GPIO_DIR]    = 0xff,
0167     [ICE_EEP2_GPIO_DIR1]   = 0xff,
0168     [ICE_EEP2_GPIO_DIR2]   = 0xff,
0169     [ICE_EEP2_GPIO_MASK]   = 0x00,
0170     [ICE_EEP2_GPIO_MASK1]  = 0x00,
0171     [ICE_EEP2_GPIO_MASK2]  = 0x00,
0172     [ICE_EEP2_GPIO_STATE]  = 0x00,
0173     [ICE_EEP2_GPIO_STATE1] = 0x00,
0174     [ICE_EEP2_GPIO_STATE2] = 0x00,
0175 };
0176 
0177 static const unsigned char phase28_eeprom[] = {
0178     [ICE_EEP2_SYSCONF]     = 0x2b,  /* clock 512, mpu401,
0179                     spdif-in/1xADC, 4xDACs */
0180     [ICE_EEP2_ACLINK]      = 0x80,  /* I2S */
0181     [ICE_EEP2_I2S]         = 0xfc,  /* vol, 96k, 24bit, 192k */
0182     [ICE_EEP2_SPDIF]       = 0xc3,  /* out-en, out-int, spdif-in */
0183     [ICE_EEP2_GPIO_DIR]    = 0xff,
0184     [ICE_EEP2_GPIO_DIR1]   = 0xff,
0185     [ICE_EEP2_GPIO_DIR2]   = 0x5f,
0186     [ICE_EEP2_GPIO_MASK]   = 0x00,
0187     [ICE_EEP2_GPIO_MASK1]  = 0x00,
0188     [ICE_EEP2_GPIO_MASK2]  = 0x00,
0189     [ICE_EEP2_GPIO_STATE]  = 0x00,
0190     [ICE_EEP2_GPIO_STATE1] = 0x00,
0191     [ICE_EEP2_GPIO_STATE2] = 0x00,
0192 };
0193 
0194 /*
0195  * write data in the SPI mode
0196  */
0197 static void phase28_spi_write(struct snd_ice1712 *ice, unsigned int cs,
0198                 unsigned int data, int bits)
0199 {
0200     unsigned int tmp;
0201     int i;
0202 
0203     tmp = snd_ice1712_gpio_read(ice);
0204 
0205     snd_ice1712_gpio_set_mask(ice, ~(PHASE28_WM_RW|PHASE28_SPI_MOSI|
0206                     PHASE28_SPI_CLK|PHASE28_WM_CS));
0207     tmp |= PHASE28_WM_RW;
0208     tmp &= ~cs;
0209     snd_ice1712_gpio_write(ice, tmp);
0210     udelay(1);
0211 
0212     for (i = bits - 1; i >= 0; i--) {
0213         tmp &= ~PHASE28_SPI_CLK;
0214         snd_ice1712_gpio_write(ice, tmp);
0215         udelay(1);
0216         if (data & (1 << i))
0217             tmp |= PHASE28_SPI_MOSI;
0218         else
0219             tmp &= ~PHASE28_SPI_MOSI;
0220         snd_ice1712_gpio_write(ice, tmp);
0221         udelay(1);
0222         tmp |= PHASE28_SPI_CLK;
0223         snd_ice1712_gpio_write(ice, tmp);
0224         udelay(1);
0225     }
0226 
0227     tmp &= ~PHASE28_SPI_CLK;
0228     tmp |= cs;
0229     snd_ice1712_gpio_write(ice, tmp);
0230     udelay(1);
0231     tmp |= PHASE28_SPI_CLK;
0232     snd_ice1712_gpio_write(ice, tmp);
0233     udelay(1);
0234 }
0235 
0236 /*
0237  * get the current register value of WM codec
0238  */
0239 static unsigned short wm_get(struct snd_ice1712 *ice, int reg)
0240 {
0241     reg <<= 1;
0242     return ((unsigned short)ice->akm[0].images[reg] << 8) |
0243         ice->akm[0].images[reg + 1];
0244 }
0245 
0246 /*
0247  * set the register value of WM codec
0248  */
0249 static void wm_put_nocache(struct snd_ice1712 *ice, int reg, unsigned short val)
0250 {
0251     phase28_spi_write(ice, PHASE28_WM_CS, (reg << 9) | (val & 0x1ff), 16);
0252 }
0253 
0254 /*
0255  * set the register value of WM codec and remember it
0256  */
0257 static void wm_put(struct snd_ice1712 *ice, int reg, unsigned short val)
0258 {
0259     wm_put_nocache(ice, reg, val);
0260     reg <<= 1;
0261     ice->akm[0].images[reg] = val >> 8;
0262     ice->akm[0].images[reg + 1] = val;
0263 }
0264 
0265 static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index,
0266             unsigned short vol, unsigned short master)
0267 {
0268     unsigned char nvol;
0269 
0270     if ((master & WM_VOL_MUTE) || (vol & WM_VOL_MUTE))
0271         nvol = 0;
0272     else
0273         nvol = 127 - wm_vol[(((vol & ~WM_VOL_MUTE) *
0274             (master & ~WM_VOL_MUTE)) / 127) & WM_VOL_MAX];
0275 
0276     wm_put(ice, index, nvol);
0277     wm_put_nocache(ice, index, 0x180 | nvol);
0278 }
0279 
0280 /*
0281  * DAC mute control
0282  */
0283 #define wm_pcm_mute_info    snd_ctl_boolean_mono_info
0284 
0285 static int wm_pcm_mute_get(struct snd_kcontrol *kcontrol,
0286                 struct snd_ctl_elem_value *ucontrol)
0287 {
0288     struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
0289 
0290     mutex_lock(&ice->gpio_mutex);
0291     ucontrol->value.integer.value[0] = (wm_get(ice, WM_MUTE) & 0x10) ?
0292                         0 : 1;
0293     mutex_unlock(&ice->gpio_mutex);
0294     return 0;
0295 }
0296 
0297 static int wm_pcm_mute_put(struct snd_kcontrol *kcontrol,
0298                 struct snd_ctl_elem_value *ucontrol)
0299 {
0300     struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
0301     unsigned short nval, oval;
0302     int change;
0303 
0304     snd_ice1712_save_gpio_status(ice);
0305     oval = wm_get(ice, WM_MUTE);
0306     nval = (oval & ~0x10) | (ucontrol->value.integer.value[0] ? 0 : 0x10);
0307     change = (nval != oval);
0308     if (change)
0309         wm_put(ice, WM_MUTE, nval);
0310     snd_ice1712_restore_gpio_status(ice);
0311 
0312     return change;
0313 }
0314 
0315 /*
0316  * Master volume attenuation mixer control
0317  */
0318 static int wm_master_vol_info(struct snd_kcontrol *kcontrol,
0319                 struct snd_ctl_elem_info *uinfo)
0320 {
0321     uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
0322     uinfo->count = 2;
0323     uinfo->value.integer.min = 0;
0324     uinfo->value.integer.max = WM_VOL_MAX;
0325     return 0;
0326 }
0327 
0328 static int wm_master_vol_get(struct snd_kcontrol *kcontrol,
0329                 struct snd_ctl_elem_value *ucontrol)
0330 {
0331     struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
0332     struct phase28_spec *spec = ice->spec;
0333     int i;
0334     for (i = 0; i < 2; i++)
0335         ucontrol->value.integer.value[i] = spec->master[i] &
0336                             ~WM_VOL_MUTE;
0337     return 0;
0338 }
0339 
0340 static int wm_master_vol_put(struct snd_kcontrol *kcontrol,
0341                 struct snd_ctl_elem_value *ucontrol)
0342 {
0343     struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
0344     struct phase28_spec *spec = ice->spec;
0345     int ch, change = 0;
0346 
0347     snd_ice1712_save_gpio_status(ice);
0348     for (ch = 0; ch < 2; ch++) {
0349         unsigned int vol = ucontrol->value.integer.value[ch];
0350         if (vol > WM_VOL_MAX)
0351             continue;
0352         vol |= spec->master[ch] & WM_VOL_MUTE;
0353         if (vol != spec->master[ch]) {
0354             int dac;
0355             spec->master[ch] = vol;
0356             for (dac = 0; dac < ice->num_total_dacs; dac += 2)
0357                 wm_set_vol(ice, WM_DAC_ATTEN + dac + ch,
0358                        spec->vol[dac + ch],
0359                        spec->master[ch]);
0360             change = 1;
0361         }
0362     }
0363     snd_ice1712_restore_gpio_status(ice);
0364     return change;
0365 }
0366 
0367 static int phase28_init(struct snd_ice1712 *ice)
0368 {
0369     static const unsigned short wm_inits_phase28[] = {
0370         /* These come first to reduce init pop noise */
0371         0x1b, 0x044,    /* ADC Mux (AC'97 source) */
0372         0x1c, 0x00B,    /* Out Mux1 (VOUT1 = DAC+AUX, VOUT2 = DAC) */
0373         0x1d, 0x009,    /* Out Mux2 (VOUT2 = DAC, VOUT3 = DAC) */
0374 
0375         0x18, 0x000,    /* All power-up */
0376 
0377         0x16, 0x122,    /* I2S, normal polarity, 24bit */
0378         0x17, 0x022,    /* 256fs, slave mode */
0379         0x00, 0,    /* DAC1 analog mute */
0380         0x01, 0,    /* DAC2 analog mute */
0381         0x02, 0,    /* DAC3 analog mute */
0382         0x03, 0,    /* DAC4 analog mute */
0383         0x04, 0,    /* DAC5 analog mute */
0384         0x05, 0,    /* DAC6 analog mute */
0385         0x06, 0,    /* DAC7 analog mute */
0386         0x07, 0,    /* DAC8 analog mute */
0387         0x08, 0x100,    /* master analog mute */
0388         0x09, 0xff, /* DAC1 digital full */
0389         0x0a, 0xff, /* DAC2 digital full */
0390         0x0b, 0xff, /* DAC3 digital full */
0391         0x0c, 0xff, /* DAC4 digital full */
0392         0x0d, 0xff, /* DAC5 digital full */
0393         0x0e, 0xff, /* DAC6 digital full */
0394         0x0f, 0xff, /* DAC7 digital full */
0395         0x10, 0xff, /* DAC8 digital full */
0396         0x11, 0x1ff,    /* master digital full */
0397         0x12, 0x000,    /* phase normal */
0398         0x13, 0x090,    /* unmute DAC L/R */
0399         0x14, 0x000,    /* all unmute */
0400         0x15, 0x000,    /* no deemphasis, no ZFLG */
0401         0x19, 0x000,    /* -12dB ADC/L */
0402         0x1a, 0x000,    /* -12dB ADC/R */
0403         (unsigned short)-1
0404     };
0405 
0406     unsigned int tmp;
0407     struct snd_akm4xxx *ak;
0408     struct phase28_spec *spec;
0409     const unsigned short *p;
0410     int i;
0411 
0412     ice->num_total_dacs = 8;
0413     ice->num_total_adcs = 2;
0414 
0415     spec = kzalloc(sizeof(*spec), GFP_KERNEL);
0416     if (!spec)
0417         return -ENOMEM;
0418     ice->spec = spec;
0419 
0420     /* Initialize analog chips */
0421     ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
0422     ak = ice->akm;
0423     if (!ak)
0424         return -ENOMEM;
0425     ice->akm_codecs = 1;
0426 
0427     snd_ice1712_gpio_set_dir(ice, 0x5fffff); /* fix this for time being */
0428 
0429     /* reset the wm codec as the SPI mode */
0430     snd_ice1712_save_gpio_status(ice);
0431     snd_ice1712_gpio_set_mask(ice, ~(PHASE28_WM_RESET|PHASE28_WM_CS|
0432                     PHASE28_HP_SEL));
0433 
0434     tmp = snd_ice1712_gpio_read(ice);
0435     tmp &= ~PHASE28_WM_RESET;
0436     snd_ice1712_gpio_write(ice, tmp);
0437     udelay(1);
0438     tmp |= PHASE28_WM_CS;
0439     snd_ice1712_gpio_write(ice, tmp);
0440     udelay(1);
0441     tmp |= PHASE28_WM_RESET;
0442     snd_ice1712_gpio_write(ice, tmp);
0443     udelay(1);
0444 
0445     p = wm_inits_phase28;
0446     for (; *p != (unsigned short)-1; p += 2)
0447         wm_put(ice, p[0], p[1]);
0448 
0449     snd_ice1712_restore_gpio_status(ice);
0450 
0451     spec->master[0] = WM_VOL_MUTE;
0452     spec->master[1] = WM_VOL_MUTE;
0453     for (i = 0; i < ice->num_total_dacs; i++) {
0454         spec->vol[i] = WM_VOL_MUTE;
0455         wm_set_vol(ice, i, spec->vol[i], spec->master[i % 2]);
0456     }
0457 
0458     return 0;
0459 }
0460 
0461 /*
0462  * DAC volume attenuation mixer control
0463  */
0464 static int wm_vol_info(struct snd_kcontrol *kcontrol,
0465             struct snd_ctl_elem_info *uinfo)
0466 {
0467     int voices = kcontrol->private_value >> 8;
0468     uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
0469     uinfo->count = voices;
0470     uinfo->value.integer.min = 0;       /* mute (-101dB) */
0471     uinfo->value.integer.max = 0x7F;    /* 0dB */
0472     return 0;
0473 }
0474 
0475 static int wm_vol_get(struct snd_kcontrol *kcontrol,
0476             struct snd_ctl_elem_value *ucontrol)
0477 {
0478     struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
0479     struct phase28_spec *spec = ice->spec;
0480     int i, ofs, voices;
0481 
0482     voices = kcontrol->private_value >> 8;
0483     ofs = kcontrol->private_value & 0xff;
0484     for (i = 0; i < voices; i++)
0485         ucontrol->value.integer.value[i] =
0486             spec->vol[ofs+i] & ~WM_VOL_MUTE;
0487     return 0;
0488 }
0489 
0490 static int wm_vol_put(struct snd_kcontrol *kcontrol,
0491             struct snd_ctl_elem_value *ucontrol)
0492 {
0493     struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
0494     struct phase28_spec *spec = ice->spec;
0495     int i, idx, ofs, voices;
0496     int change = 0;
0497 
0498     voices = kcontrol->private_value >> 8;
0499     ofs = kcontrol->private_value & 0xff;
0500     snd_ice1712_save_gpio_status(ice);
0501     for (i = 0; i < voices; i++) {
0502         unsigned int vol;
0503         vol = ucontrol->value.integer.value[i];
0504         if (vol > 0x7f)
0505             continue;
0506         vol |= spec->vol[ofs+i] & WM_VOL_MUTE;
0507         if (vol != spec->vol[ofs+i]) {
0508             spec->vol[ofs+i] = vol;
0509             idx  = WM_DAC_ATTEN + ofs + i;
0510             wm_set_vol(ice, idx, spec->vol[ofs+i],
0511                    spec->master[i]);
0512             change = 1;
0513         }
0514     }
0515     snd_ice1712_restore_gpio_status(ice);
0516     return change;
0517 }
0518 
0519 /*
0520  * WM8770 mute control
0521  */
0522 static int wm_mute_info(struct snd_kcontrol *kcontrol,
0523             struct snd_ctl_elem_info *uinfo) {
0524     uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
0525     uinfo->count = kcontrol->private_value >> 8;
0526     uinfo->value.integer.min = 0;
0527     uinfo->value.integer.max = 1;
0528     return 0;
0529 }
0530 
0531 static int wm_mute_get(struct snd_kcontrol *kcontrol,
0532             struct snd_ctl_elem_value *ucontrol)
0533 {
0534     struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
0535     struct phase28_spec *spec = ice->spec;
0536     int voices, ofs, i;
0537 
0538     voices = kcontrol->private_value >> 8;
0539     ofs = kcontrol->private_value & 0xFF;
0540 
0541     for (i = 0; i < voices; i++)
0542         ucontrol->value.integer.value[i] =
0543             (spec->vol[ofs+i] & WM_VOL_MUTE) ? 0 : 1;
0544     return 0;
0545 }
0546 
0547 static int wm_mute_put(struct snd_kcontrol *kcontrol,
0548             struct snd_ctl_elem_value *ucontrol)
0549 {
0550     struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
0551     struct phase28_spec *spec = ice->spec;
0552     int change = 0, voices, ofs, i;
0553 
0554     voices = kcontrol->private_value >> 8;
0555     ofs = kcontrol->private_value & 0xFF;
0556 
0557     snd_ice1712_save_gpio_status(ice);
0558     for (i = 0; i < voices; i++) {
0559         int val = (spec->vol[ofs + i] & WM_VOL_MUTE) ? 0 : 1;
0560         if (ucontrol->value.integer.value[i] != val) {
0561             spec->vol[ofs + i] &= ~WM_VOL_MUTE;
0562             spec->vol[ofs + i] |=
0563                 ucontrol->value.integer.value[i] ? 0 :
0564                 WM_VOL_MUTE;
0565             wm_set_vol(ice, ofs + i, spec->vol[ofs + i],
0566                     spec->master[i]);
0567             change = 1;
0568         }
0569     }
0570     snd_ice1712_restore_gpio_status(ice);
0571 
0572     return change;
0573 }
0574 
0575 /*
0576  * WM8770 master mute control
0577  */
0578 #define wm_master_mute_info     snd_ctl_boolean_stereo_info
0579 
0580 static int wm_master_mute_get(struct snd_kcontrol *kcontrol,
0581                 struct snd_ctl_elem_value *ucontrol)
0582 {
0583     struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
0584     struct phase28_spec *spec = ice->spec;
0585 
0586     ucontrol->value.integer.value[0] =
0587         (spec->master[0] & WM_VOL_MUTE) ? 0 : 1;
0588     ucontrol->value.integer.value[1] =
0589         (spec->master[1] & WM_VOL_MUTE) ? 0 : 1;
0590     return 0;
0591 }
0592 
0593 static int wm_master_mute_put(struct snd_kcontrol *kcontrol,
0594                 struct snd_ctl_elem_value *ucontrol)
0595 {
0596     struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
0597     struct phase28_spec *spec = ice->spec;
0598     int change = 0, i;
0599 
0600     snd_ice1712_save_gpio_status(ice);
0601     for (i = 0; i < 2; i++) {
0602         int val = (spec->master[i] & WM_VOL_MUTE) ? 0 : 1;
0603         if (ucontrol->value.integer.value[i] != val) {
0604             int dac;
0605             spec->master[i] &= ~WM_VOL_MUTE;
0606             spec->master[i] |=
0607                 ucontrol->value.integer.value[i] ? 0 :
0608                 WM_VOL_MUTE;
0609             for (dac = 0; dac < ice->num_total_dacs; dac += 2)
0610                 wm_set_vol(ice, WM_DAC_ATTEN + dac + i,
0611                         spec->vol[dac + i],
0612                         spec->master[i]);
0613             change = 1;
0614         }
0615     }
0616     snd_ice1712_restore_gpio_status(ice);
0617 
0618     return change;
0619 }
0620 
0621 /* digital master volume */
0622 #define PCM_0dB 0xff
0623 #define PCM_RES 128 /* -64dB */
0624 #define PCM_MIN (PCM_0dB - PCM_RES)
0625 static int wm_pcm_vol_info(struct snd_kcontrol *kcontrol,
0626                 struct snd_ctl_elem_info *uinfo)
0627 {
0628     uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
0629     uinfo->count = 1;
0630     uinfo->value.integer.min = 0;       /* mute (-64dB) */
0631     uinfo->value.integer.max = PCM_RES; /* 0dB */
0632     return 0;
0633 }
0634 
0635 static int wm_pcm_vol_get(struct snd_kcontrol *kcontrol,
0636                 struct snd_ctl_elem_value *ucontrol)
0637 {
0638     struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
0639     unsigned short val;
0640 
0641     mutex_lock(&ice->gpio_mutex);
0642     val = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff;
0643     val = val > PCM_MIN ? (val - PCM_MIN) : 0;
0644     ucontrol->value.integer.value[0] = val;
0645     mutex_unlock(&ice->gpio_mutex);
0646     return 0;
0647 }
0648 
0649 static int wm_pcm_vol_put(struct snd_kcontrol *kcontrol,
0650                 struct snd_ctl_elem_value *ucontrol)
0651 {
0652     struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
0653     unsigned short ovol, nvol;
0654     int change = 0;
0655 
0656     nvol = ucontrol->value.integer.value[0];
0657     if (nvol > PCM_RES)
0658         return -EINVAL;
0659     snd_ice1712_save_gpio_status(ice);
0660     nvol = (nvol ? (nvol + PCM_MIN) : 0) & 0xff;
0661     ovol = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff;
0662     if (ovol != nvol) {
0663         wm_put(ice, WM_DAC_DIG_MASTER_ATTEN, nvol); /* prelatch */
0664         /* update */
0665         wm_put_nocache(ice, WM_DAC_DIG_MASTER_ATTEN, nvol | 0x100);
0666         change = 1;
0667     }
0668     snd_ice1712_restore_gpio_status(ice);
0669     return change;
0670 }
0671 
0672 /*
0673  * Deemphasis
0674  */
0675 #define phase28_deemp_info  snd_ctl_boolean_mono_info
0676 
0677 static int phase28_deemp_get(struct snd_kcontrol *kcontrol,
0678                 struct snd_ctl_elem_value *ucontrol)
0679 {
0680     struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
0681     ucontrol->value.integer.value[0] = (wm_get(ice, WM_DAC_CTRL2) & 0xf) ==
0682                         0xf;
0683     return 0;
0684 }
0685 
0686 static int phase28_deemp_put(struct snd_kcontrol *kcontrol,
0687                 struct snd_ctl_elem_value *ucontrol)
0688 {
0689     struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
0690     int temp, temp2;
0691     temp = wm_get(ice, WM_DAC_CTRL2);
0692     temp2 = temp;
0693     if (ucontrol->value.integer.value[0])
0694         temp |= 0xf;
0695     else
0696         temp &= ~0xf;
0697     if (temp != temp2) {
0698         wm_put(ice, WM_DAC_CTRL2, temp);
0699         return 1;
0700     }
0701     return 0;
0702 }
0703 
0704 /*
0705  * ADC Oversampling
0706  */
0707 static int phase28_oversampling_info(struct snd_kcontrol *k,
0708                     struct snd_ctl_elem_info *uinfo)
0709 {
0710     static const char * const texts[2] = { "128x", "64x"    };
0711 
0712     return snd_ctl_enum_info(uinfo, 1, 2, texts);
0713 }
0714 
0715 static int phase28_oversampling_get(struct snd_kcontrol *kcontrol,
0716                     struct snd_ctl_elem_value *ucontrol)
0717 {
0718     struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
0719     ucontrol->value.enumerated.item[0] = (wm_get(ice, WM_MASTER) & 0x8) ==
0720                         0x8;
0721     return 0;
0722 }
0723 
0724 static int phase28_oversampling_put(struct snd_kcontrol *kcontrol,
0725                     struct snd_ctl_elem_value *ucontrol)
0726 {
0727     int temp, temp2;
0728     struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
0729 
0730     temp = wm_get(ice, WM_MASTER);
0731     temp2 = temp;
0732 
0733     if (ucontrol->value.enumerated.item[0])
0734         temp |= 0x8;
0735     else
0736         temp &= ~0x8;
0737 
0738     if (temp != temp2) {
0739         wm_put(ice, WM_MASTER, temp);
0740         return 1;
0741     }
0742     return 0;
0743 }
0744 
0745 static const DECLARE_TLV_DB_SCALE(db_scale_wm_dac, -12700, 100, 1);
0746 static const DECLARE_TLV_DB_SCALE(db_scale_wm_pcm, -6400, 50, 1);
0747 
0748 static const struct snd_kcontrol_new phase28_dac_controls[] = {
0749     {
0750         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0751         .name = "Master Playback Switch",
0752         .info = wm_master_mute_info,
0753         .get = wm_master_mute_get,
0754         .put = wm_master_mute_put
0755     },
0756     {
0757         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0758         .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
0759                SNDRV_CTL_ELEM_ACCESS_TLV_READ),
0760         .name = "Master Playback Volume",
0761         .info = wm_master_vol_info,
0762         .get = wm_master_vol_get,
0763         .put = wm_master_vol_put,
0764         .tlv = { .p = db_scale_wm_dac }
0765     },
0766     {
0767         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0768         .name = "Front Playback Switch",
0769         .info = wm_mute_info,
0770         .get = wm_mute_get,
0771         .put = wm_mute_put,
0772         .private_value = (2 << 8) | 0
0773     },
0774     {
0775         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0776         .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
0777                SNDRV_CTL_ELEM_ACCESS_TLV_READ),
0778         .name = "Front Playback Volume",
0779         .info = wm_vol_info,
0780         .get = wm_vol_get,
0781         .put = wm_vol_put,
0782         .private_value = (2 << 8) | 0,
0783         .tlv = { .p = db_scale_wm_dac }
0784     },
0785     {
0786         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0787         .name = "Rear Playback Switch",
0788         .info = wm_mute_info,
0789         .get = wm_mute_get,
0790         .put = wm_mute_put,
0791         .private_value = (2 << 8) | 2
0792     },
0793     {
0794         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0795         .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
0796                SNDRV_CTL_ELEM_ACCESS_TLV_READ),
0797         .name = "Rear Playback Volume",
0798         .info = wm_vol_info,
0799         .get = wm_vol_get,
0800         .put = wm_vol_put,
0801         .private_value = (2 << 8) | 2,
0802         .tlv = { .p = db_scale_wm_dac }
0803     },
0804     {
0805         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0806         .name = "Center Playback Switch",
0807         .info = wm_mute_info,
0808         .get = wm_mute_get,
0809         .put = wm_mute_put,
0810         .private_value = (1 << 8) | 4
0811     },
0812     {
0813         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0814         .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
0815                SNDRV_CTL_ELEM_ACCESS_TLV_READ),
0816         .name = "Center Playback Volume",
0817         .info = wm_vol_info,
0818         .get = wm_vol_get,
0819         .put = wm_vol_put,
0820         .private_value = (1 << 8) | 4,
0821         .tlv = { .p = db_scale_wm_dac }
0822     },
0823     {
0824         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0825         .name = "LFE Playback Switch",
0826         .info = wm_mute_info,
0827         .get = wm_mute_get,
0828         .put = wm_mute_put,
0829         .private_value = (1 << 8) | 5
0830     },
0831     {
0832         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0833         .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
0834                SNDRV_CTL_ELEM_ACCESS_TLV_READ),
0835         .name = "LFE Playback Volume",
0836         .info = wm_vol_info,
0837         .get = wm_vol_get,
0838         .put = wm_vol_put,
0839         .private_value = (1 << 8) | 5,
0840         .tlv = { .p = db_scale_wm_dac }
0841     },
0842     {
0843         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0844         .name = "Side Playback Switch",
0845         .info = wm_mute_info,
0846         .get = wm_mute_get,
0847         .put = wm_mute_put,
0848         .private_value = (2 << 8) | 6
0849     },
0850     {
0851         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0852         .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
0853                SNDRV_CTL_ELEM_ACCESS_TLV_READ),
0854         .name = "Side Playback Volume",
0855         .info = wm_vol_info,
0856         .get = wm_vol_get,
0857         .put = wm_vol_put,
0858         .private_value = (2 << 8) | 6,
0859         .tlv = { .p = db_scale_wm_dac }
0860     }
0861 };
0862 
0863 static const struct snd_kcontrol_new wm_controls[] = {
0864     {
0865         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0866         .name = "PCM Playback Switch",
0867         .info = wm_pcm_mute_info,
0868         .get = wm_pcm_mute_get,
0869         .put = wm_pcm_mute_put
0870     },
0871     {
0872         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0873         .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
0874                SNDRV_CTL_ELEM_ACCESS_TLV_READ),
0875         .name = "PCM Playback Volume",
0876         .info = wm_pcm_vol_info,
0877         .get = wm_pcm_vol_get,
0878         .put = wm_pcm_vol_put,
0879         .tlv = { .p = db_scale_wm_pcm }
0880     },
0881     {
0882         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0883         .name = "DAC Deemphasis Switch",
0884         .info = phase28_deemp_info,
0885         .get = phase28_deemp_get,
0886         .put = phase28_deemp_put
0887     },
0888     {
0889         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0890         .name = "ADC Oversampling",
0891         .info = phase28_oversampling_info,
0892         .get = phase28_oversampling_get,
0893         .put = phase28_oversampling_put
0894     }
0895 };
0896 
0897 static int phase28_add_controls(struct snd_ice1712 *ice)
0898 {
0899     unsigned int i, counts;
0900     int err;
0901 
0902     counts = ARRAY_SIZE(phase28_dac_controls);
0903     for (i = 0; i < counts; i++) {
0904         err = snd_ctl_add(ice->card,
0905                     snd_ctl_new1(&phase28_dac_controls[i],
0906                             ice));
0907         if (err < 0)
0908             return err;
0909     }
0910 
0911     for (i = 0; i < ARRAY_SIZE(wm_controls); i++) {
0912         err = snd_ctl_add(ice->card,
0913                     snd_ctl_new1(&wm_controls[i], ice));
0914         if (err < 0)
0915             return err;
0916     }
0917 
0918     return 0;
0919 }
0920 
0921 struct snd_ice1712_card_info snd_vt1724_phase_cards[] = {
0922     {
0923         .subvendor = VT1724_SUBDEVICE_PHASE22,
0924         .name = "Terratec PHASE 22",
0925         .model = "phase22",
0926         .chip_init = phase22_init,
0927         .build_controls = phase22_add_controls,
0928         .eeprom_size = sizeof(phase22_eeprom),
0929         .eeprom_data = phase22_eeprom,
0930     },
0931     {
0932         .subvendor = VT1724_SUBDEVICE_PHASE28,
0933         .name = "Terratec PHASE 28",
0934         .model = "phase28",
0935         .chip_init = phase28_init,
0936         .build_controls = phase28_add_controls,
0937         .eeprom_size = sizeof(phase28_eeprom),
0938         .eeprom_data = phase28_eeprom,
0939     },
0940     {
0941         .subvendor = VT1724_SUBDEVICE_TS22,
0942         .name = "Terrasoniq TS22 PCI",
0943         .model = "TS22",
0944         .chip_init = phase22_init,
0945         .build_controls = phase22_add_controls,
0946         .eeprom_size = sizeof(phase22_eeprom),
0947         .eeprom_data = phase22_eeprom,
0948     },
0949     { } /* terminator */
0950 };