linux/sound/pci/ice1712/phase.c
<<
>>
Prefs
   1/*
   2 *   ALSA driver for ICEnsemble ICE1724 (Envy24)
   3 *
   4 *   Lowlevel functions for Terratec PHASE 22
   5 *
   6 *      Copyright (c) 2005 Misha Zhilin <misha@epiphan.com>
   7 *
   8 *   This program is free software; you can redistribute it and/or modify
   9 *   it under the terms of the GNU General Public License as published by
  10 *   the Free Software Foundation; either version 2 of the License, or
  11 *   (at your option) any later version.
  12 *
  13 *   This program is distributed in the hope that it will be useful,
  14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 *   GNU General Public License for more details.
  17 *
  18 *   You should have received a copy of the GNU General Public License
  19 *   along with this program; if not, write to the Free Software
  20 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  21 *
  22 */
  23
  24/* PHASE 22 overview:
  25 *   Audio controller: VIA Envy24HT-S (slightly trimmed down Envy24HT, 4in/4out)
  26 *   Analog chip: AK4524 (partially via Philip's 74HCT125)
  27 *   Digital receiver: CS8414-CS (supported in this release)
  28 *              PHASE 22 revision 2.0 and Terrasoniq/Musonik TS22PCI have CS8416
  29 *              (support status unknown, please test and report)
  30 *
  31 *   Envy connects to AK4524
  32 *      - CS directly from GPIO 10
  33 *      - CCLK via 74HCT125's gate #4 from GPIO 4
  34 *      - CDTI via 74HCT125's gate #2 from GPIO 5
  35 *              CDTI may be completely blocked by 74HCT125's gate #1
  36 *              controlled by GPIO 3
  37 */
  38
  39/* PHASE 28 overview:
  40 *   Audio controller: VIA Envy24HT (full untrimmed version, 4in/8out)
  41 *   Analog chip: WM8770 (8 channel 192k DAC, 2 channel 96k ADC)
  42 *   Digital receiver: CS8414-CS (supported in this release)
  43 */
  44
  45#include <asm/io.h>
  46#include <linux/delay.h>
  47#include <linux/interrupt.h>
  48#include <linux/init.h>
  49#include <linux/slab.h>
  50#include <linux/mutex.h>
  51
  52#include <sound/core.h>
  53
  54#include "ice1712.h"
  55#include "envy24ht.h"
  56#include "phase.h"
  57#include <sound/tlv.h>
  58
  59/* AC97 register cache for Phase28 */
  60struct phase28_spec {
  61        unsigned short master[2];
  62        unsigned short vol[8];
  63};
  64
  65/* WM8770 registers */
  66#define WM_DAC_ATTEN            0x00    /* DAC1-8 analog attenuation */
  67#define WM_DAC_MASTER_ATTEN     0x08    /* DAC master analog attenuation */
  68#define WM_DAC_DIG_ATTEN        0x09    /* DAC1-8 digital attenuation */
  69#define WM_DAC_DIG_MASTER_ATTEN 0x11    /* DAC master digital attenuation */
  70#define WM_PHASE_SWAP           0x12    /* DAC phase */
  71#define WM_DAC_CTRL1            0x13    /* DAC control bits */
  72#define WM_MUTE                 0x14    /* mute controls */
  73#define WM_DAC_CTRL2            0x15    /* de-emphasis and zefo-flag */
  74#define WM_INT_CTRL             0x16    /* interface control */
  75#define WM_MASTER               0x17    /* master clock and mode */
  76#define WM_POWERDOWN            0x18    /* power-down controls */
  77#define WM_ADC_GAIN             0x19    /* ADC gain L(19)/R(1a) */
  78#define WM_ADC_MUX              0x1b    /* input MUX */
  79#define WM_OUT_MUX1             0x1c    /* output MUX */
  80#define WM_OUT_MUX2             0x1e    /* output MUX */
  81#define WM_RESET                0x1f    /* software reset */
  82
  83
  84/*
  85 * Logarithmic volume values for WM8770
  86 * Computed as 20 * Log10(255 / x)
  87 */
  88static const unsigned char wm_vol[256] = {
  89        127, 48, 42, 39, 36, 34, 33, 31, 30, 29, 28, 27, 27, 26, 25, 25, 24,
  90        24, 23, 23, 22, 22, 21, 21, 21, 20, 20, 20, 19, 19, 19, 18, 18, 18, 18,
  91        17, 17, 17, 17, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14,
  92        14, 13, 13, 13, 13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11,
  93        11, 11, 11, 11, 11, 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9,
  94        9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7,
  95        7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5,
  96        5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
  97        4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
  98        3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
  99        2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
 100        1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
 101};
 102
 103#define WM_VOL_MAX      (sizeof(wm_vol) - 1)
 104#define WM_VOL_MUTE     0x8000
 105
 106static struct snd_akm4xxx akm_phase22 __devinitdata = {
 107        .type = SND_AK4524,
 108        .num_dacs = 2,
 109        .num_adcs = 2,
 110};
 111
 112static struct snd_ak4xxx_private akm_phase22_priv __devinitdata = {
 113        .caddr =        2,
 114        .cif =          1,
 115        .data_mask =    1 << 4,
 116        .clk_mask =     1 << 5,
 117        .cs_mask =      1 << 10,
 118        .cs_addr =      1 << 10,
 119        .cs_none =      0,
 120        .add_flags =    1 << 3,
 121        .mask_flags =   0,
 122};
 123
 124static int __devinit phase22_init(struct snd_ice1712 *ice)
 125{
 126        struct snd_akm4xxx *ak;
 127        int err;
 128
 129        /* Configure DAC/ADC description for generic part of ice1724 */
 130        switch (ice->eeprom.subvendor) {
 131        case VT1724_SUBDEVICE_PHASE22:
 132        case VT1724_SUBDEVICE_TS22:
 133                ice->num_total_dacs = 2;
 134                ice->num_total_adcs = 2;
 135                ice->vt1720 = 1; /* Envy24HT-S have 16 bit wide GPIO */
 136                break;
 137        default:
 138                snd_BUG();
 139                return -EINVAL;
 140        }
 141
 142        /* Initialize analog chips */
 143        ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
 144        ak = ice->akm;
 145        if (!ak)
 146                return -ENOMEM;
 147        ice->akm_codecs = 1;
 148        switch (ice->eeprom.subvendor) {
 149        case VT1724_SUBDEVICE_PHASE22:
 150        case VT1724_SUBDEVICE_TS22:
 151                err = snd_ice1712_akm4xxx_init(ak, &akm_phase22,
 152                                                &akm_phase22_priv, ice);
 153                if (err < 0)
 154                        return err;
 155                break;
 156        }
 157
 158        return 0;
 159}
 160
 161static int __devinit phase22_add_controls(struct snd_ice1712 *ice)
 162{
 163        int err = 0;
 164
 165        switch (ice->eeprom.subvendor) {
 166        case VT1724_SUBDEVICE_PHASE22:
 167        case VT1724_SUBDEVICE_TS22:
 168                err = snd_ice1712_akm4xxx_build_controls(ice);
 169                if (err < 0)
 170                        return err;
 171        }
 172        return 0;
 173}
 174
 175static unsigned char phase22_eeprom[] __devinitdata = {
 176        [ICE_EEP2_SYSCONF]     = 0x28,  /* clock 512, mpu 401,
 177                                        spdif-in/1xADC, 1xDACs */
 178        [ICE_EEP2_ACLINK]      = 0x80,  /* I2S */
 179        [ICE_EEP2_I2S]         = 0xf0,  /* vol, 96k, 24bit */
 180        [ICE_EEP2_SPDIF]       = 0xc3,  /* out-en, out-int, spdif-in */
 181        [ICE_EEP2_GPIO_DIR]    = 0xff,
 182        [ICE_EEP2_GPIO_DIR1]   = 0xff,
 183        [ICE_EEP2_GPIO_DIR2]   = 0xff,
 184        [ICE_EEP2_GPIO_MASK]   = 0x00,
 185        [ICE_EEP2_GPIO_MASK1]  = 0x00,
 186        [ICE_EEP2_GPIO_MASK2]  = 0x00,
 187        [ICE_EEP2_GPIO_STATE]  = 0x00,
 188        [ICE_EEP2_GPIO_STATE1] = 0x00,
 189        [ICE_EEP2_GPIO_STATE2] = 0x00,
 190};
 191
 192static unsigned char phase28_eeprom[] __devinitdata = {
 193        [ICE_EEP2_SYSCONF]     = 0x2b,  /* clock 512, mpu401,
 194                                        spdif-in/1xADC, 4xDACs */
 195        [ICE_EEP2_ACLINK]      = 0x80,  /* I2S */
 196        [ICE_EEP2_I2S]         = 0xfc,  /* vol, 96k, 24bit, 192k */
 197        [ICE_EEP2_SPDIF]       = 0xc3,  /* out-en, out-int, spdif-in */
 198        [ICE_EEP2_GPIO_DIR]    = 0xff,
 199        [ICE_EEP2_GPIO_DIR1]   = 0xff,
 200        [ICE_EEP2_GPIO_DIR2]   = 0x5f,
 201        [ICE_EEP2_GPIO_MASK]   = 0x00,
 202        [ICE_EEP2_GPIO_MASK1]  = 0x00,
 203        [ICE_EEP2_GPIO_MASK2]  = 0x00,
 204        [ICE_EEP2_GPIO_STATE]  = 0x00,
 205        [ICE_EEP2_GPIO_STATE1] = 0x00,
 206        [ICE_EEP2_GPIO_STATE2] = 0x00,
 207};
 208
 209/*
 210 * write data in the SPI mode
 211 */
 212static void phase28_spi_write(struct snd_ice1712 *ice, unsigned int cs,
 213                                unsigned int data, int bits)
 214{
 215        unsigned int tmp;
 216        int i;
 217
 218        tmp = snd_ice1712_gpio_read(ice);
 219
 220        snd_ice1712_gpio_set_mask(ice, ~(PHASE28_WM_RW|PHASE28_SPI_MOSI|
 221                                        PHASE28_SPI_CLK|PHASE28_WM_CS));
 222        tmp |= PHASE28_WM_RW;
 223        tmp &= ~cs;
 224        snd_ice1712_gpio_write(ice, tmp);
 225        udelay(1);
 226
 227        for (i = bits - 1; i >= 0; i--) {
 228                tmp &= ~PHASE28_SPI_CLK;
 229                snd_ice1712_gpio_write(ice, tmp);
 230                udelay(1);
 231                if (data & (1 << i))
 232                        tmp |= PHASE28_SPI_MOSI;
 233                else
 234                        tmp &= ~PHASE28_SPI_MOSI;
 235                snd_ice1712_gpio_write(ice, tmp);
 236                udelay(1);
 237                tmp |= PHASE28_SPI_CLK;
 238                snd_ice1712_gpio_write(ice, tmp);
 239                udelay(1);
 240        }
 241
 242        tmp &= ~PHASE28_SPI_CLK;
 243        tmp |= cs;
 244        snd_ice1712_gpio_write(ice, tmp);
 245        udelay(1);
 246        tmp |= PHASE28_SPI_CLK;
 247        snd_ice1712_gpio_write(ice, tmp);
 248        udelay(1);
 249}
 250
 251/*
 252 * get the current register value of WM codec
 253 */
 254static unsigned short wm_get(struct snd_ice1712 *ice, int reg)
 255{
 256        reg <<= 1;
 257        return ((unsigned short)ice->akm[0].images[reg] << 8) |
 258                ice->akm[0].images[reg + 1];
 259}
 260
 261/*
 262 * set the register value of WM codec
 263 */
 264static void wm_put_nocache(struct snd_ice1712 *ice, int reg, unsigned short val)
 265{
 266        phase28_spi_write(ice, PHASE28_WM_CS, (reg << 9) | (val & 0x1ff), 16);
 267}
 268
 269/*
 270 * set the register value of WM codec and remember it
 271 */
 272static void wm_put(struct snd_ice1712 *ice, int reg, unsigned short val)
 273{
 274        wm_put_nocache(ice, reg, val);
 275        reg <<= 1;
 276        ice->akm[0].images[reg] = val >> 8;
 277        ice->akm[0].images[reg + 1] = val;
 278}
 279
 280static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index,
 281                        unsigned short vol, unsigned short master)
 282{
 283        unsigned char nvol;
 284
 285        if ((master & WM_VOL_MUTE) || (vol & WM_VOL_MUTE))
 286                nvol = 0;
 287        else
 288                nvol = 127 - wm_vol[(((vol & ~WM_VOL_MUTE) *
 289                        (master & ~WM_VOL_MUTE)) / 127) & WM_VOL_MAX];
 290
 291        wm_put(ice, index, nvol);
 292        wm_put_nocache(ice, index, 0x180 | nvol);
 293}
 294
 295/*
 296 * DAC mute control
 297 */
 298#define wm_pcm_mute_info        snd_ctl_boolean_mono_info
 299
 300static int wm_pcm_mute_get(struct snd_kcontrol *kcontrol,
 301                                struct snd_ctl_elem_value *ucontrol)
 302{
 303        struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 304
 305        mutex_lock(&ice->gpio_mutex);
 306        ucontrol->value.integer.value[0] = (wm_get(ice, WM_MUTE) & 0x10) ?
 307                                                0 : 1;
 308        mutex_unlock(&ice->gpio_mutex);
 309        return 0;
 310}
 311
 312static int wm_pcm_mute_put(struct snd_kcontrol *kcontrol,
 313                                struct snd_ctl_elem_value *ucontrol)
 314{
 315        struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 316        unsigned short nval, oval;
 317        int change;
 318
 319        snd_ice1712_save_gpio_status(ice);
 320        oval = wm_get(ice, WM_MUTE);
 321        nval = (oval & ~0x10) | (ucontrol->value.integer.value[0] ? 0 : 0x10);
 322        change = (nval != oval);
 323        if (change)
 324                wm_put(ice, WM_MUTE, nval);
 325        snd_ice1712_restore_gpio_status(ice);
 326
 327        return change;
 328}
 329
 330/*
 331 * Master volume attenuation mixer control
 332 */
 333static int wm_master_vol_info(struct snd_kcontrol *kcontrol,
 334                                struct snd_ctl_elem_info *uinfo)
 335{
 336        uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 337        uinfo->count = 2;
 338        uinfo->value.integer.min = 0;
 339        uinfo->value.integer.max = WM_VOL_MAX;
 340        return 0;
 341}
 342
 343static int wm_master_vol_get(struct snd_kcontrol *kcontrol,
 344                                struct snd_ctl_elem_value *ucontrol)
 345{
 346        struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 347        struct phase28_spec *spec = ice->spec;
 348        int i;
 349        for (i = 0; i < 2; i++)
 350                ucontrol->value.integer.value[i] = spec->master[i] &
 351                                                        ~WM_VOL_MUTE;
 352        return 0;
 353}
 354
 355static int wm_master_vol_put(struct snd_kcontrol *kcontrol,
 356                                struct snd_ctl_elem_value *ucontrol)
 357{
 358        struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 359        struct phase28_spec *spec = ice->spec;
 360        int ch, change = 0;
 361
 362        snd_ice1712_save_gpio_status(ice);
 363        for (ch = 0; ch < 2; ch++) {
 364                unsigned int vol = ucontrol->value.integer.value[ch];
 365                if (vol > WM_VOL_MAX)
 366                        continue;
 367                vol |= spec->master[ch] & WM_VOL_MUTE;
 368                if (vol != spec->master[ch]) {
 369                        int dac;
 370                        spec->master[ch] = vol;
 371                        for (dac = 0; dac < ice->num_total_dacs; dac += 2)
 372                                wm_set_vol(ice, WM_DAC_ATTEN + dac + ch,
 373                                           spec->vol[dac + ch],
 374                                           spec->master[ch]);
 375                        change = 1;
 376                }
 377        }
 378        snd_ice1712_restore_gpio_status(ice);
 379        return change;
 380}
 381
 382static int __devinit phase28_init(struct snd_ice1712 *ice)
 383{
 384        static const unsigned short wm_inits_phase28[] = {
 385                /* These come first to reduce init pop noise */
 386                0x1b, 0x044,    /* ADC Mux (AC'97 source) */
 387                0x1c, 0x00B,    /* Out Mux1 (VOUT1 = DAC+AUX, VOUT2 = DAC) */
 388                0x1d, 0x009,    /* Out Mux2 (VOUT2 = DAC, VOUT3 = DAC) */
 389
 390                0x18, 0x000,    /* All power-up */
 391
 392                0x16, 0x122,    /* I2S, normal polarity, 24bit */
 393                0x17, 0x022,    /* 256fs, slave mode */
 394                0x00, 0,        /* DAC1 analog mute */
 395                0x01, 0,        /* DAC2 analog mute */
 396                0x02, 0,        /* DAC3 analog mute */
 397                0x03, 0,        /* DAC4 analog mute */
 398                0x04, 0,        /* DAC5 analog mute */
 399                0x05, 0,        /* DAC6 analog mute */
 400                0x06, 0,        /* DAC7 analog mute */
 401                0x07, 0,        /* DAC8 analog mute */
 402                0x08, 0x100,    /* master analog mute */
 403                0x09, 0xff,     /* DAC1 digital full */
 404                0x0a, 0xff,     /* DAC2 digital full */
 405                0x0b, 0xff,     /* DAC3 digital full */
 406                0x0c, 0xff,     /* DAC4 digital full */
 407                0x0d, 0xff,     /* DAC5 digital full */
 408                0x0e, 0xff,     /* DAC6 digital full */
 409                0x0f, 0xff,     /* DAC7 digital full */
 410                0x10, 0xff,     /* DAC8 digital full */
 411                0x11, 0x1ff,    /* master digital full */
 412                0x12, 0x000,    /* phase normal */
 413                0x13, 0x090,    /* unmute DAC L/R */
 414                0x14, 0x000,    /* all unmute */
 415                0x15, 0x000,    /* no deemphasis, no ZFLG */
 416                0x19, 0x000,    /* -12dB ADC/L */
 417                0x1a, 0x000,    /* -12dB ADC/R */
 418                (unsigned short)-1
 419        };
 420
 421        unsigned int tmp;
 422        struct snd_akm4xxx *ak;
 423        struct phase28_spec *spec;
 424        const unsigned short *p;
 425        int i;
 426
 427        ice->num_total_dacs = 8;
 428        ice->num_total_adcs = 2;
 429
 430        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
 431        if (!spec)
 432                return -ENOMEM;
 433        ice->spec = spec;
 434
 435        /* Initialize analog chips */
 436        ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
 437        ak = ice->akm;
 438        if (!ak)
 439                return -ENOMEM;
 440        ice->akm_codecs = 1;
 441
 442        snd_ice1712_gpio_set_dir(ice, 0x5fffff); /* fix this for time being */
 443
 444        /* reset the wm codec as the SPI mode */
 445        snd_ice1712_save_gpio_status(ice);
 446        snd_ice1712_gpio_set_mask(ice, ~(PHASE28_WM_RESET|PHASE28_WM_CS|
 447                                        PHASE28_HP_SEL));
 448
 449        tmp = snd_ice1712_gpio_read(ice);
 450        tmp &= ~PHASE28_WM_RESET;
 451        snd_ice1712_gpio_write(ice, tmp);
 452        udelay(1);
 453        tmp |= PHASE28_WM_CS;
 454        snd_ice1712_gpio_write(ice, tmp);
 455        udelay(1);
 456        tmp |= PHASE28_WM_RESET;
 457        snd_ice1712_gpio_write(ice, tmp);
 458        udelay(1);
 459
 460        p = wm_inits_phase28;
 461        for (; *p != (unsigned short)-1; p += 2)
 462                wm_put(ice, p[0], p[1]);
 463
 464        snd_ice1712_restore_gpio_status(ice);
 465
 466        spec->master[0] = WM_VOL_MUTE;
 467        spec->master[1] = WM_VOL_MUTE;
 468        for (i = 0; i < ice->num_total_dacs; i++) {
 469                spec->vol[i] = WM_VOL_MUTE;
 470                wm_set_vol(ice, i, spec->vol[i], spec->master[i % 2]);
 471        }
 472
 473        return 0;
 474}
 475
 476/*
 477 * DAC volume attenuation mixer control
 478 */
 479static int wm_vol_info(struct snd_kcontrol *kcontrol,
 480                        struct snd_ctl_elem_info *uinfo)
 481{
 482        int voices = kcontrol->private_value >> 8;
 483        uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 484        uinfo->count = voices;
 485        uinfo->value.integer.min = 0;           /* mute (-101dB) */
 486        uinfo->value.integer.max = 0x7F;        /* 0dB */
 487        return 0;
 488}
 489
 490static int wm_vol_get(struct snd_kcontrol *kcontrol,
 491                        struct snd_ctl_elem_value *ucontrol)
 492{
 493        struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 494        struct phase28_spec *spec = ice->spec;
 495        int i, ofs, voices;
 496
 497        voices = kcontrol->private_value >> 8;
 498        ofs = kcontrol->private_value & 0xff;
 499        for (i = 0; i < voices; i++)
 500                ucontrol->value.integer.value[i] =
 501                        spec->vol[ofs+i] & ~WM_VOL_MUTE;
 502        return 0;
 503}
 504
 505static int wm_vol_put(struct snd_kcontrol *kcontrol,
 506                        struct snd_ctl_elem_value *ucontrol)
 507{
 508        struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 509        struct phase28_spec *spec = ice->spec;
 510        int i, idx, ofs, voices;
 511        int change = 0;
 512
 513        voices = kcontrol->private_value >> 8;
 514        ofs = kcontrol->private_value & 0xff;
 515        snd_ice1712_save_gpio_status(ice);
 516        for (i = 0; i < voices; i++) {
 517                unsigned int vol;
 518                vol = ucontrol->value.integer.value[i];
 519                if (vol > 0x7f)
 520                        continue;
 521                vol |= spec->vol[ofs+i] & WM_VOL_MUTE;
 522                if (vol != spec->vol[ofs+i]) {
 523                        spec->vol[ofs+i] = vol;
 524                        idx  = WM_DAC_ATTEN + ofs + i;
 525                        wm_set_vol(ice, idx, spec->vol[ofs+i],
 526                                   spec->master[i]);
 527                        change = 1;
 528                }
 529        }
 530        snd_ice1712_restore_gpio_status(ice);
 531        return change;
 532}
 533
 534/*
 535 * WM8770 mute control
 536 */
 537static int wm_mute_info(struct snd_kcontrol *kcontrol,
 538                        struct snd_ctl_elem_info *uinfo) {
 539        uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 540        uinfo->count = kcontrol->private_value >> 8;
 541        uinfo->value.integer.min = 0;
 542        uinfo->value.integer.max = 1;
 543        return 0;
 544}
 545
 546static int wm_mute_get(struct snd_kcontrol *kcontrol,
 547                        struct snd_ctl_elem_value *ucontrol)
 548{
 549        struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 550        struct phase28_spec *spec = ice->spec;
 551        int voices, ofs, i;
 552
 553        voices = kcontrol->private_value >> 8;
 554        ofs = kcontrol->private_value & 0xFF;
 555
 556        for (i = 0; i < voices; i++)
 557                ucontrol->value.integer.value[i] =
 558                        (spec->vol[ofs+i] & WM_VOL_MUTE) ? 0 : 1;
 559        return 0;
 560}
 561
 562static int wm_mute_put(struct snd_kcontrol *kcontrol,
 563                        struct snd_ctl_elem_value *ucontrol)
 564{
 565        struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 566        struct phase28_spec *spec = ice->spec;
 567        int change = 0, voices, ofs, i;
 568
 569        voices = kcontrol->private_value >> 8;
 570        ofs = kcontrol->private_value & 0xFF;
 571
 572        snd_ice1712_save_gpio_status(ice);
 573        for (i = 0; i < voices; i++) {
 574                int val = (spec->vol[ofs + i] & WM_VOL_MUTE) ? 0 : 1;
 575                if (ucontrol->value.integer.value[i] != val) {
 576                        spec->vol[ofs + i] &= ~WM_VOL_MUTE;
 577                        spec->vol[ofs + i] |=
 578                                ucontrol->value.integer.value[i] ? 0 :
 579                                WM_VOL_MUTE;
 580                        wm_set_vol(ice, ofs + i, spec->vol[ofs + i],
 581                                        spec->master[i]);
 582                        change = 1;
 583                }
 584        }
 585        snd_ice1712_restore_gpio_status(ice);
 586
 587        return change;
 588}
 589
 590/*
 591 * WM8770 master mute control
 592 */
 593#define wm_master_mute_info             snd_ctl_boolean_stereo_info
 594
 595static int wm_master_mute_get(struct snd_kcontrol *kcontrol,
 596                                struct snd_ctl_elem_value *ucontrol)
 597{
 598        struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 599        struct phase28_spec *spec = ice->spec;
 600
 601        ucontrol->value.integer.value[0] =
 602                (spec->master[0] & WM_VOL_MUTE) ? 0 : 1;
 603        ucontrol->value.integer.value[1] =
 604                (spec->master[1] & WM_VOL_MUTE) ? 0 : 1;
 605        return 0;
 606}
 607
 608static int wm_master_mute_put(struct snd_kcontrol *kcontrol,
 609                                struct snd_ctl_elem_value *ucontrol)
 610{
 611        struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 612        struct phase28_spec *spec = ice->spec;
 613        int change = 0, i;
 614
 615        snd_ice1712_save_gpio_status(ice);
 616        for (i = 0; i < 2; i++) {
 617                int val = (spec->master[i] & WM_VOL_MUTE) ? 0 : 1;
 618                if (ucontrol->value.integer.value[i] != val) {
 619                        int dac;
 620                        spec->master[i] &= ~WM_VOL_MUTE;
 621                        spec->master[i] |=
 622                                ucontrol->value.integer.value[i] ? 0 :
 623                                WM_VOL_MUTE;
 624                        for (dac = 0; dac < ice->num_total_dacs; dac += 2)
 625                                wm_set_vol(ice, WM_DAC_ATTEN + dac + i,
 626                                                spec->vol[dac + i],
 627                                                spec->master[i]);
 628                        change = 1;
 629                }
 630        }
 631        snd_ice1712_restore_gpio_status(ice);
 632
 633        return change;
 634}
 635
 636/* digital master volume */
 637#define PCM_0dB 0xff
 638#define PCM_RES 128     /* -64dB */
 639#define PCM_MIN (PCM_0dB - PCM_RES)
 640static int wm_pcm_vol_info(struct snd_kcontrol *kcontrol,
 641                                struct snd_ctl_elem_info *uinfo)
 642{
 643        uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 644        uinfo->count = 1;
 645        uinfo->value.integer.min = 0;           /* mute (-64dB) */
 646        uinfo->value.integer.max = PCM_RES;     /* 0dB */
 647        return 0;
 648}
 649
 650static int wm_pcm_vol_get(struct snd_kcontrol *kcontrol,
 651                                struct snd_ctl_elem_value *ucontrol)
 652{
 653        struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 654        unsigned short val;
 655
 656        mutex_lock(&ice->gpio_mutex);
 657        val = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff;
 658        val = val > PCM_MIN ? (val - PCM_MIN) : 0;
 659        ucontrol->value.integer.value[0] = val;
 660        mutex_unlock(&ice->gpio_mutex);
 661        return 0;
 662}
 663
 664static int wm_pcm_vol_put(struct snd_kcontrol *kcontrol,
 665                                struct snd_ctl_elem_value *ucontrol)
 666{
 667        struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 668        unsigned short ovol, nvol;
 669        int change = 0;
 670
 671        nvol = ucontrol->value.integer.value[0];
 672        if (nvol > PCM_RES)
 673                return -EINVAL;
 674        snd_ice1712_save_gpio_status(ice);
 675        nvol = (nvol ? (nvol + PCM_MIN) : 0) & 0xff;
 676        ovol = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff;
 677        if (ovol != nvol) {
 678                wm_put(ice, WM_DAC_DIG_MASTER_ATTEN, nvol); /* prelatch */
 679                /* update */
 680                wm_put_nocache(ice, WM_DAC_DIG_MASTER_ATTEN, nvol | 0x100);
 681                change = 1;
 682        }
 683        snd_ice1712_restore_gpio_status(ice);
 684        return change;
 685}
 686
 687/*
 688 * Deemphasis
 689 */
 690#define phase28_deemp_info      snd_ctl_boolean_mono_info
 691
 692static int phase28_deemp_get(struct snd_kcontrol *kcontrol,
 693                                struct snd_ctl_elem_value *ucontrol)
 694{
 695        struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 696        ucontrol->value.integer.value[0] = (wm_get(ice, WM_DAC_CTRL2) & 0xf) ==
 697                                                0xf;
 698        return 0;
 699}
 700
 701static int phase28_deemp_put(struct snd_kcontrol *kcontrol,
 702                                struct snd_ctl_elem_value *ucontrol)
 703{
 704        struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 705        int temp, temp2;
 706        temp = wm_get(ice, WM_DAC_CTRL2);
 707        temp2 = temp;
 708        if (ucontrol->value.integer.value[0])
 709                temp |= 0xf;
 710        else
 711                temp &= ~0xf;
 712        if (temp != temp2) {
 713                wm_put(ice, WM_DAC_CTRL2, temp);
 714                return 1;
 715        }
 716        return 0;
 717}
 718
 719/*
 720 * ADC Oversampling
 721 */
 722static int phase28_oversampling_info(struct snd_kcontrol *k,
 723                                        struct snd_ctl_elem_info *uinfo)
 724{
 725        static char *texts[2] = { "128x", "64x" };
 726
 727        uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
 728        uinfo->count = 1;
 729        uinfo->value.enumerated.items = 2;
 730
 731        if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
 732                uinfo->value.enumerated.item = uinfo->value.enumerated.items -
 733                                                1;
 734        strcpy(uinfo->value.enumerated.name,
 735                texts[uinfo->value.enumerated.item]);
 736
 737        return 0;
 738}
 739
 740static int phase28_oversampling_get(struct snd_kcontrol *kcontrol,
 741                                        struct snd_ctl_elem_value *ucontrol)
 742{
 743        struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 744        ucontrol->value.enumerated.item[0] = (wm_get(ice, WM_MASTER) & 0x8) ==
 745                                                0x8;
 746        return 0;
 747}
 748
 749static int phase28_oversampling_put(struct snd_kcontrol *kcontrol,
 750                                        struct snd_ctl_elem_value *ucontrol)
 751{
 752        int temp, temp2;
 753        struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 754
 755        temp = wm_get(ice, WM_MASTER);
 756        temp2 = temp;
 757
 758        if (ucontrol->value.enumerated.item[0])
 759                temp |= 0x8;
 760        else
 761                temp &= ~0x8;
 762
 763        if (temp != temp2) {
 764                wm_put(ice, WM_MASTER, temp);
 765                return 1;
 766        }
 767        return 0;
 768}
 769
 770static const DECLARE_TLV_DB_SCALE(db_scale_wm_dac, -12700, 100, 1);
 771static const DECLARE_TLV_DB_SCALE(db_scale_wm_pcm, -6400, 50, 1);
 772
 773static struct snd_kcontrol_new phase28_dac_controls[] __devinitdata = {
 774        {
 775                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 776                .name = "Master Playback Switch",
 777                .info = wm_master_mute_info,
 778                .get = wm_master_mute_get,
 779                .put = wm_master_mute_put
 780        },
 781        {
 782                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 783                .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
 784                           SNDRV_CTL_ELEM_ACCESS_TLV_READ),
 785                .name = "Master Playback Volume",
 786                .info = wm_master_vol_info,
 787                .get = wm_master_vol_get,
 788                .put = wm_master_vol_put,
 789                .tlv = { .p = db_scale_wm_dac }
 790        },
 791        {
 792                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 793                .name = "Front Playback Switch",
 794                .info = wm_mute_info,
 795                .get = wm_mute_get,
 796                .put = wm_mute_put,
 797                .private_value = (2 << 8) | 0
 798        },
 799        {
 800                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 801                .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
 802                           SNDRV_CTL_ELEM_ACCESS_TLV_READ),
 803                .name = "Front Playback Volume",
 804                .info = wm_vol_info,
 805                .get = wm_vol_get,
 806                .put = wm_vol_put,
 807                .private_value = (2 << 8) | 0,
 808                .tlv = { .p = db_scale_wm_dac }
 809        },
 810        {
 811                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 812                .name = "Rear Playback Switch",
 813                .info = wm_mute_info,
 814                .get = wm_mute_get,
 815                .put = wm_mute_put,
 816                .private_value = (2 << 8) | 2
 817        },
 818        {
 819                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 820                .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
 821                           SNDRV_CTL_ELEM_ACCESS_TLV_READ),
 822                .name = "Rear Playback Volume",
 823                .info = wm_vol_info,
 824                .get = wm_vol_get,
 825                .put = wm_vol_put,
 826                .private_value = (2 << 8) | 2,
 827                .tlv = { .p = db_scale_wm_dac }
 828        },
 829        {
 830                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 831                .name = "Center Playback Switch",
 832                .info = wm_mute_info,
 833                .get = wm_mute_get,
 834                .put = wm_mute_put,
 835                .private_value = (1 << 8) | 4
 836        },
 837        {
 838                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 839                .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
 840                           SNDRV_CTL_ELEM_ACCESS_TLV_READ),
 841                .name = "Center Playback Volume",
 842                .info = wm_vol_info,
 843                .get = wm_vol_get,
 844                .put = wm_vol_put,
 845                .private_value = (1 << 8) | 4,
 846                .tlv = { .p = db_scale_wm_dac }
 847        },
 848        {
 849                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 850                .name = "LFE Playback Switch",
 851                .info = wm_mute_info,
 852                .get = wm_mute_get,
 853                .put = wm_mute_put,
 854                .private_value = (1 << 8) | 5
 855        },
 856        {
 857                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 858                .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
 859                           SNDRV_CTL_ELEM_ACCESS_TLV_READ),
 860                .name = "LFE Playback Volume",
 861                .info = wm_vol_info,
 862                .get = wm_vol_get,
 863                .put = wm_vol_put,
 864                .private_value = (1 << 8) | 5,
 865                .tlv = { .p = db_scale_wm_dac }
 866        },
 867        {
 868                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 869                .name = "Side Playback Switch",
 870                .info = wm_mute_info,
 871                .get = wm_mute_get,
 872                .put = wm_mute_put,
 873                .private_value = (2 << 8) | 6
 874        },
 875        {
 876                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 877                .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
 878                           SNDRV_CTL_ELEM_ACCESS_TLV_READ),
 879                .name = "Side Playback Volume",
 880                .info = wm_vol_info,
 881                .get = wm_vol_get,
 882                .put = wm_vol_put,
 883                .private_value = (2 << 8) | 6,
 884                .tlv = { .p = db_scale_wm_dac }
 885        }
 886};
 887
 888static struct snd_kcontrol_new wm_controls[] __devinitdata = {
 889        {
 890                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 891                .name = "PCM Playback Switch",
 892                .info = wm_pcm_mute_info,
 893                .get = wm_pcm_mute_get,
 894                .put = wm_pcm_mute_put
 895        },
 896        {
 897                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 898                .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
 899                           SNDRV_CTL_ELEM_ACCESS_TLV_READ),
 900                .name = "PCM Playback Volume",
 901                .info = wm_pcm_vol_info,
 902                .get = wm_pcm_vol_get,
 903                .put = wm_pcm_vol_put,
 904                .tlv = { .p = db_scale_wm_pcm }
 905        },
 906        {
 907                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 908                .name = "DAC Deemphasis Switch",
 909                .info = phase28_deemp_info,
 910                .get = phase28_deemp_get,
 911                .put = phase28_deemp_put
 912        },
 913        {
 914                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 915                .name = "ADC Oversampling",
 916                .info = phase28_oversampling_info,
 917                .get = phase28_oversampling_get,
 918                .put = phase28_oversampling_put
 919        }
 920};
 921
 922static int __devinit phase28_add_controls(struct snd_ice1712 *ice)
 923{
 924        unsigned int i, counts;
 925        int err;
 926
 927        counts = ARRAY_SIZE(phase28_dac_controls);
 928        for (i = 0; i < counts; i++) {
 929                err = snd_ctl_add(ice->card,
 930                                        snd_ctl_new1(&phase28_dac_controls[i],
 931                                                        ice));
 932                if (err < 0)
 933                        return err;
 934        }
 935
 936        for (i = 0; i < ARRAY_SIZE(wm_controls); i++) {
 937                err = snd_ctl_add(ice->card,
 938                                        snd_ctl_new1(&wm_controls[i], ice));
 939                if (err < 0)
 940                        return err;
 941        }
 942
 943        return 0;
 944}
 945
 946struct snd_ice1712_card_info snd_vt1724_phase_cards[] __devinitdata = {
 947        {
 948                .subvendor = VT1724_SUBDEVICE_PHASE22,
 949                .name = "Terratec PHASE 22",
 950                .model = "phase22",
 951                .chip_init = phase22_init,
 952                .build_controls = phase22_add_controls,
 953                .eeprom_size = sizeof(phase22_eeprom),
 954                .eeprom_data = phase22_eeprom,
 955        },
 956        {
 957                .subvendor = VT1724_SUBDEVICE_PHASE28,
 958                .name = "Terratec PHASE 28",
 959                .model = "phase28",
 960                .chip_init = phase28_init,
 961                .build_controls = phase28_add_controls,
 962                .eeprom_size = sizeof(phase28_eeprom),
 963                .eeprom_data = phase28_eeprom,
 964        },
 965        {
 966                .subvendor = VT1724_SUBDEVICE_TS22,
 967                .name = "Terrasoniq TS22 PCI",
 968                .model = "TS22",
 969                .chip_init = phase22_init,
 970                .build_controls = phase22_add_controls,
 971                .eeprom_size = sizeof(phase22_eeprom),
 972                .eeprom_data = phase22_eeprom,
 973        },
 974        { } /* terminator */
 975};
 976