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