linux/sound/pci/ice1712/wtm.c
<<
>>
Prefs
   1/*
   2 *      ALSA driver for ICEnsemble VT1724 (Envy24HT)
   3 *
   4 *      Lowlevel functions for Ego Sys Waveterminal 192M
   5 *
   6 *              Copyright (c) 2006 Guedez Clement <klem.dev@gmail.com>
   7 *              Some functions are taken from the Prodigy192 driver
   8 *              source
   9 *
  10 *      This program is free software; you can redistribute it and/or modify
  11 *      it under the terms of the GNU General Public License as published by
  12 *      the Free Software Foundation; either version 2 of the License, or
  13 *      (at your option) any later version.
  14 *
  15 *      This program is distributed in the hope that it will be useful,
  16 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
  17 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18 *      GNU General Public License for more details.
  19 *
  20 *      You should have received a copy of the GNU General Public License
  21 *      along with this program; if not, write to the Free Software
  22 *      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  23 *
  24 */
  25
  26
  27
  28#include <linux/delay.h>
  29#include <linux/interrupt.h>
  30#include <linux/init.h>
  31#include <sound/core.h>
  32#include <sound/tlv.h>
  33#include <linux/slab.h>
  34
  35#include "ice1712.h"
  36#include "envy24ht.h"
  37#include "wtm.h"
  38#include "stac946x.h"
  39
  40struct wtm_spec {
  41        /* rate change needs atomic mute/unmute of all dacs*/
  42        struct mutex mute_mutex;
  43};
  44
  45
  46/*
  47 *      2*ADC 6*DAC no1 ringbuffer r/w on i2c bus
  48 */
  49static inline void stac9460_put(struct snd_ice1712 *ice, int reg,
  50                                                unsigned char val)
  51{
  52        snd_vt1724_write_i2c(ice, STAC9460_I2C_ADDR, reg, val);
  53}
  54
  55static inline unsigned char stac9460_get(struct snd_ice1712 *ice, int reg)
  56{
  57        return snd_vt1724_read_i2c(ice, STAC9460_I2C_ADDR, reg);
  58}
  59
  60/*
  61 *      2*ADC 2*DAC no2 ringbuffer r/w on i2c bus
  62 */
  63static inline void stac9460_2_put(struct snd_ice1712 *ice, int reg,
  64                                                unsigned char val)
  65{
  66        snd_vt1724_write_i2c(ice, STAC9460_2_I2C_ADDR, reg, val);
  67}
  68
  69static inline unsigned char stac9460_2_get(struct snd_ice1712 *ice, int reg)
  70{
  71        return snd_vt1724_read_i2c(ice, STAC9460_2_I2C_ADDR, reg);
  72}
  73
  74
  75/*
  76 *      DAC mute control
  77 */
  78static void stac9460_dac_mute_all(struct snd_ice1712 *ice, unsigned char mute,
  79                                unsigned short int *change_mask)
  80{
  81        unsigned char new, old;
  82        int id, idx, change;
  83
  84        /*stac9460 1*/
  85        for (id = 0; id < 7; id++) {
  86                if (*change_mask & (0x01 << id)) {
  87                        if (id == 0)
  88                                idx = STAC946X_MASTER_VOLUME;
  89                        else
  90                                idx = STAC946X_LF_VOLUME - 1 + id;
  91                        old = stac9460_get(ice, idx);
  92                        new = (~mute << 7 & 0x80) | (old & ~0x80);
  93                        change = (new != old);
  94                        if (change) {
  95                                stac9460_put(ice, idx, new);
  96                                *change_mask = *change_mask | (0x01 << id);
  97                        } else {
  98                                *change_mask = *change_mask & ~(0x01 << id);
  99                        }
 100                }
 101        }
 102
 103        /*stac9460 2*/
 104        for (id = 0; id < 3; id++) {
 105                if (*change_mask & (0x01 << (id + 7))) {
 106                        if (id == 0)
 107                                idx = STAC946X_MASTER_VOLUME;
 108                        else
 109                                idx = STAC946X_LF_VOLUME - 1 + id;
 110                        old = stac9460_2_get(ice, idx);
 111                        new = (~mute << 7 & 0x80) | (old & ~0x80);
 112                        change = (new != old);
 113                        if (change) {
 114                                stac9460_2_put(ice, idx, new);
 115                                *change_mask = *change_mask | (0x01 << id);
 116                        } else {
 117                                *change_mask = *change_mask & ~(0x01 << id);
 118                        }
 119                }
 120        }
 121}
 122
 123
 124
 125#define stac9460_dac_mute_info          snd_ctl_boolean_mono_info
 126
 127static int stac9460_dac_mute_get(struct snd_kcontrol *kcontrol,
 128                                struct snd_ctl_elem_value *ucontrol)
 129{
 130        struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 131        struct wtm_spec *spec = ice->spec;
 132        unsigned char val;
 133        int idx, id;
 134
 135        mutex_lock(&spec->mute_mutex);
 136
 137        if (kcontrol->private_value) {
 138                idx = STAC946X_MASTER_VOLUME;
 139                id = 0;
 140        } else {
 141                id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
 142                idx = id + STAC946X_LF_VOLUME;
 143        }
 144        if (id < 6)
 145                val = stac9460_get(ice, idx);
 146        else
 147                val = stac9460_2_get(ice, idx - 6);
 148        ucontrol->value.integer.value[0] = (~val >> 7) & 0x1;
 149
 150        mutex_unlock(&spec->mute_mutex);
 151        return 0;
 152}
 153
 154static int stac9460_dac_mute_put(struct snd_kcontrol *kcontrol,
 155                                struct snd_ctl_elem_value *ucontrol)
 156{
 157        struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 158        unsigned char new, old;
 159        int id, idx;
 160        int change;
 161
 162        if (kcontrol->private_value) {
 163                idx = STAC946X_MASTER_VOLUME;
 164                old = stac9460_get(ice, idx);
 165                new = (~ucontrol->value.integer.value[0] << 7 & 0x80) |
 166                                                        (old & ~0x80);
 167                change = (new != old);
 168                if (change) {
 169                        stac9460_put(ice, idx, new);
 170                        stac9460_2_put(ice, idx, new);
 171                }
 172        } else {
 173                id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
 174                idx = id + STAC946X_LF_VOLUME;
 175                if (id < 6)
 176                        old = stac9460_get(ice, idx);
 177                else
 178                        old = stac9460_2_get(ice, idx - 6);
 179                new = (~ucontrol->value.integer.value[0] << 7 & 0x80) |
 180                                                        (old & ~0x80);
 181                change = (new != old);
 182                if (change) {
 183                        if (id < 6)
 184                                stac9460_put(ice, idx, new);
 185                        else
 186                                stac9460_2_put(ice, idx - 6, new);
 187                }
 188        }
 189        return change;
 190}
 191
 192/*
 193 *      DAC volume attenuation mixer control
 194 */
 195static int stac9460_dac_vol_info(struct snd_kcontrol *kcontrol,
 196                                struct snd_ctl_elem_info *uinfo)
 197{
 198        uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 199        uinfo->count = 1;
 200        uinfo->value.integer.min = 0;                   /* mute */
 201        uinfo->value.integer.max = 0x7f;                /* 0dB */
 202        return 0;
 203}
 204
 205static int stac9460_dac_vol_get(struct snd_kcontrol *kcontrol,
 206                                struct snd_ctl_elem_value *ucontrol)
 207{
 208        struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 209        int idx, id;
 210        unsigned char vol;
 211
 212        if (kcontrol->private_value) {
 213                idx = STAC946X_MASTER_VOLUME;
 214                id = 0;
 215        } else {
 216                id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
 217                idx = id + STAC946X_LF_VOLUME;
 218        }
 219        if (id < 6)
 220                vol = stac9460_get(ice, idx) & 0x7f;
 221        else
 222                vol = stac9460_2_get(ice, idx - 6) & 0x7f;
 223        ucontrol->value.integer.value[0] = 0x7f - vol;
 224        return 0;
 225}
 226
 227static int stac9460_dac_vol_put(struct snd_kcontrol *kcontrol,
 228                                struct snd_ctl_elem_value *ucontrol)
 229{
 230        struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 231        int idx, id;
 232        unsigned char tmp, ovol, nvol;
 233        int change;
 234
 235        if (kcontrol->private_value) {
 236                idx = STAC946X_MASTER_VOLUME;
 237                nvol = ucontrol->value.integer.value[0] & 0x7f;
 238                tmp = stac9460_get(ice, idx);
 239                ovol = 0x7f - (tmp & 0x7f);
 240                change = (ovol != nvol);
 241                if (change) {
 242                        stac9460_put(ice, idx, (0x7f - nvol) | (tmp & 0x80));
 243                        stac9460_2_put(ice, idx, (0x7f - nvol) | (tmp & 0x80));
 244                }
 245        } else {
 246                id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
 247                idx = id + STAC946X_LF_VOLUME;
 248                nvol = ucontrol->value.integer.value[0] & 0x7f;
 249                if (id < 6)
 250                        tmp = stac9460_get(ice, idx);
 251                else
 252                        tmp = stac9460_2_get(ice, idx - 6);
 253                ovol = 0x7f - (tmp & 0x7f);
 254                change = (ovol != nvol);
 255                if (change) {
 256                        if (id < 6)
 257                                stac9460_put(ice, idx, (0x7f - nvol) |
 258                                                        (tmp & 0x80));
 259                        else
 260                                stac9460_2_put(ice, idx-6, (0x7f - nvol) |
 261                                                        (tmp & 0x80));
 262                }
 263        }
 264        return change;
 265}
 266
 267/*
 268 * ADC mute control
 269 */
 270#define stac9460_adc_mute_info          snd_ctl_boolean_stereo_info
 271
 272static int stac9460_adc_mute_get(struct snd_kcontrol *kcontrol,
 273                                struct snd_ctl_elem_value *ucontrol)
 274{
 275        struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 276        unsigned char val;
 277        int i, id;
 278
 279        id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
 280        if (id == 0) {
 281                for (i = 0; i < 2; ++i) {
 282                        val = stac9460_get(ice, STAC946X_MIC_L_VOLUME + i);
 283                        ucontrol->value.integer.value[i] = ~val>>7 & 0x1;
 284                }
 285        } else {
 286                for (i = 0; i < 2; ++i) {
 287                        val = stac9460_2_get(ice, STAC946X_MIC_L_VOLUME + i);
 288                        ucontrol->value.integer.value[i] = ~val>>7 & 0x1;
 289                }
 290        }
 291        return 0;
 292}
 293
 294static int stac9460_adc_mute_put(struct snd_kcontrol *kcontrol,
 295                                struct snd_ctl_elem_value *ucontrol)
 296{
 297        struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 298        unsigned char new, old;
 299        int i, reg, id;
 300        int change;
 301
 302        id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
 303        if (id == 0) {
 304                for (i = 0; i < 2; ++i) {
 305                        reg = STAC946X_MIC_L_VOLUME + i;
 306                        old = stac9460_get(ice, reg);
 307                        new = (~ucontrol->value.integer.value[i]<<7&0x80) |
 308                                                                (old&~0x80);
 309                        change = (new != old);
 310                        if (change)
 311                                stac9460_put(ice, reg, new);
 312                }
 313        } else {
 314                for (i = 0; i < 2; ++i) {
 315                        reg = STAC946X_MIC_L_VOLUME + i;
 316                        old = stac9460_2_get(ice, reg);
 317                        new = (~ucontrol->value.integer.value[i]<<7&0x80) |
 318                                                                (old&~0x80);
 319                        change = (new != old);
 320                        if (change)
 321                                stac9460_2_put(ice, reg, new);
 322                }
 323        }
 324        return change;
 325}
 326
 327/*
 328 *ADC gain mixer control
 329 */
 330static int stac9460_adc_vol_info(struct snd_kcontrol *kcontrol,
 331                                struct snd_ctl_elem_info *uinfo)
 332{
 333        uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 334        uinfo->count = 2;
 335        uinfo->value.integer.min = 0;           /* 0dB */
 336        uinfo->value.integer.max = 0x0f;        /* 22.5dB */
 337        return 0;
 338}
 339
 340static int stac9460_adc_vol_get(struct snd_kcontrol *kcontrol,
 341                                struct snd_ctl_elem_value *ucontrol)
 342{
 343        struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 344        int i, reg, id;
 345        unsigned char vol;
 346
 347        id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
 348        if (id == 0) {
 349                for (i = 0; i < 2; ++i) {
 350                        reg = STAC946X_MIC_L_VOLUME + i;
 351                        vol = stac9460_get(ice, reg) & 0x0f;
 352                        ucontrol->value.integer.value[i] = 0x0f - vol;
 353                }
 354        } else {
 355                for (i = 0; i < 2; ++i) {
 356                        reg = STAC946X_MIC_L_VOLUME + i;
 357                        vol = stac9460_2_get(ice, reg) & 0x0f;
 358                        ucontrol->value.integer.value[i] = 0x0f - vol;
 359                }
 360        }
 361        return 0;
 362}
 363
 364static int stac9460_adc_vol_put(struct snd_kcontrol *kcontrol,
 365                                struct snd_ctl_elem_value *ucontrol)
 366{
 367        struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 368        int i, reg, id;
 369        unsigned char ovol, nvol;
 370        int change;
 371
 372        id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
 373        if (id == 0) {
 374                for (i = 0; i < 2; ++i) {
 375                        reg = STAC946X_MIC_L_VOLUME + i;
 376                        nvol = ucontrol->value.integer.value[i] & 0x0f;
 377                        ovol = 0x0f - stac9460_get(ice, reg);
 378                        change = ((ovol & 0x0f) != nvol);
 379                        if (change)
 380                                stac9460_put(ice, reg, (0x0f - nvol) |
 381                                                        (ovol & ~0x0f));
 382                }
 383        } else {
 384                for (i = 0; i < 2; ++i) {
 385                        reg = STAC946X_MIC_L_VOLUME + i;
 386                        nvol = ucontrol->value.integer.value[i] & 0x0f;
 387                        ovol = 0x0f - stac9460_2_get(ice, reg);
 388                        change = ((ovol & 0x0f) != nvol);
 389                        if (change)
 390                                stac9460_2_put(ice, reg, (0x0f - nvol) |
 391                                                        (ovol & ~0x0f));
 392                }
 393        }
 394        return change;
 395}
 396
 397/*
 398 * MIC / LINE switch fonction
 399 */
 400static int stac9460_mic_sw_info(struct snd_kcontrol *kcontrol,
 401                                struct snd_ctl_elem_info *uinfo)
 402{
 403        static const char * const texts[2] = { "Line In", "Mic" };
 404
 405        return snd_ctl_enum_info(uinfo, 1, 2, texts);
 406}
 407
 408
 409static int stac9460_mic_sw_get(struct snd_kcontrol *kcontrol,
 410                                struct snd_ctl_elem_value *ucontrol)
 411{
 412        struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 413        unsigned char val;
 414        int id;
 415
 416        id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
 417        if (id == 0)
 418                val = stac9460_get(ice, STAC946X_GENERAL_PURPOSE);
 419        else
 420                val = stac9460_2_get(ice, STAC946X_GENERAL_PURPOSE);
 421        ucontrol->value.enumerated.item[0] = (val >> 7) & 0x1;
 422        return 0;
 423}
 424
 425static int stac9460_mic_sw_put(struct snd_kcontrol *kcontrol,
 426                                struct snd_ctl_elem_value *ucontrol)
 427{
 428        struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 429        unsigned char new, old;
 430        int change, id;
 431
 432        id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
 433        if (id == 0)
 434                old = stac9460_get(ice, STAC946X_GENERAL_PURPOSE);
 435        else
 436                old = stac9460_2_get(ice, STAC946X_GENERAL_PURPOSE);
 437        new = (ucontrol->value.enumerated.item[0] << 7 & 0x80) | (old & ~0x80);
 438        change = (new != old);
 439        if (change) {
 440                if (id == 0)
 441                        stac9460_put(ice, STAC946X_GENERAL_PURPOSE, new);
 442                else
 443                        stac9460_2_put(ice, STAC946X_GENERAL_PURPOSE, new);
 444        }
 445        return change;
 446}
 447
 448
 449/*
 450 * Handler for setting correct codec rate - called when rate change is detected
 451 */
 452static void stac9460_set_rate_val(struct snd_ice1712 *ice, unsigned int rate)
 453{
 454        unsigned char old, new;
 455        unsigned short int changed;
 456        struct wtm_spec *spec = ice->spec;
 457
 458        if (rate == 0)  /* no hint - S/PDIF input is master, simply return */
 459                return;
 460        else if (rate <= 48000)
 461                new = 0x08;     /* 256x, base rate mode */
 462        else if (rate <= 96000)
 463                new = 0x11;     /* 256x, mid rate mode */
 464        else
 465                new = 0x12;     /* 128x, high rate mode */
 466
 467        old = stac9460_get(ice, STAC946X_MASTER_CLOCKING);
 468        if (old == new)
 469                return;
 470        /* change detected, setting master clock, muting first */
 471        /* due to possible conflicts with mute controls - mutexing */
 472        mutex_lock(&spec->mute_mutex);
 473        /* we have to remember current mute status for each DAC */
 474        changed = 0xFFFF;
 475        stac9460_dac_mute_all(ice, 0, &changed);
 476        /*printk(KERN_DEBUG "Rate change: %d, new MC: 0x%02x\n", rate, new);*/
 477        stac9460_put(ice, STAC946X_MASTER_CLOCKING, new);
 478        stac9460_2_put(ice, STAC946X_MASTER_CLOCKING, new);
 479        udelay(10);
 480        /* unmuting - only originally unmuted dacs -
 481        * i.e. those changed when muting */
 482        stac9460_dac_mute_all(ice, 1, &changed);
 483        mutex_unlock(&spec->mute_mutex);
 484}
 485
 486
 487/*Limits value in dB for fader*/
 488static const DECLARE_TLV_DB_SCALE(db_scale_dac, -19125, 75, 0);
 489static const DECLARE_TLV_DB_SCALE(db_scale_adc, 0, 150, 0);
 490
 491/*
 492 * Control tabs
 493 */
 494static struct snd_kcontrol_new stac9640_controls[] = {
 495        {
 496                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 497                .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
 498                            SNDRV_CTL_ELEM_ACCESS_TLV_READ),
 499                .name = "Master Playback Switch",
 500                .info = stac9460_dac_mute_info,
 501                .get = stac9460_dac_mute_get,
 502                .put = stac9460_dac_mute_put,
 503                .private_value = 1,
 504                .tlv = { .p = db_scale_dac }
 505        },
 506        {
 507                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 508                .name = "Master Playback Volume",
 509                .info = stac9460_dac_vol_info,
 510                .get = stac9460_dac_vol_get,
 511                .put = stac9460_dac_vol_put,
 512                .private_value = 1,
 513        },
 514        {
 515                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 516                .name = "MIC/Line Input Enum",
 517                .count = 2,
 518                .info = stac9460_mic_sw_info,
 519                .get = stac9460_mic_sw_get,
 520                .put = stac9460_mic_sw_put,
 521
 522        },
 523        {
 524                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 525                .name = "DAC Switch",
 526                .count = 8,
 527                .info = stac9460_dac_mute_info,
 528                .get = stac9460_dac_mute_get,
 529                .put = stac9460_dac_mute_put,
 530        },
 531        {
 532                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 533                .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
 534                            SNDRV_CTL_ELEM_ACCESS_TLV_READ),
 535
 536                .name = "DAC Volume",
 537                .count = 8,
 538                .info = stac9460_dac_vol_info,
 539                .get = stac9460_dac_vol_get,
 540                .put = stac9460_dac_vol_put,
 541                .tlv = { .p = db_scale_dac }
 542        },
 543        {
 544                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 545                .name = "ADC Switch",
 546                .count = 2,
 547                .info = stac9460_adc_mute_info,
 548                .get = stac9460_adc_mute_get,
 549                .put = stac9460_adc_mute_put,
 550        },
 551        {
 552                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 553                .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
 554                            SNDRV_CTL_ELEM_ACCESS_TLV_READ),
 555
 556                .name = "ADC Volume",
 557                .count = 2,
 558                .info = stac9460_adc_vol_info,
 559                .get = stac9460_adc_vol_get,
 560                .put = stac9460_adc_vol_put,
 561                .tlv = { .p = db_scale_adc }
 562        }
 563};
 564
 565
 566
 567/*INIT*/
 568static int wtm_add_controls(struct snd_ice1712 *ice)
 569{
 570        unsigned int i;
 571        int err;
 572
 573        for (i = 0; i < ARRAY_SIZE(stac9640_controls); i++) {
 574                err = snd_ctl_add(ice->card,
 575                                snd_ctl_new1(&stac9640_controls[i], ice));
 576                if (err < 0)
 577                        return err;
 578        }
 579        return 0;
 580}
 581
 582static int wtm_init(struct snd_ice1712 *ice)
 583{
 584        static unsigned short stac_inits_wtm[] = {
 585                STAC946X_RESET, 0,
 586                STAC946X_MASTER_CLOCKING, 0x11,
 587                (unsigned short)-1
 588        };
 589        unsigned short *p;
 590        struct wtm_spec *spec;
 591
 592        /*WTM 192M*/
 593        ice->num_total_dacs = 8;
 594        ice->num_total_adcs = 4;
 595        ice->force_rdma1 = 1;
 596
 597        /*init mutex for dac mute conflict*/
 598        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
 599        if (!spec)
 600                return -ENOMEM;
 601        ice->spec = spec;
 602        mutex_init(&spec->mute_mutex);
 603
 604
 605        /*initialize codec*/
 606        p = stac_inits_wtm;
 607        for (; *p != (unsigned short)-1; p += 2) {
 608                stac9460_put(ice, p[0], p[1]);
 609                stac9460_2_put(ice, p[0], p[1]);
 610        }
 611        ice->gpio.set_pro_rate = stac9460_set_rate_val;
 612        return 0;
 613}
 614
 615
 616static unsigned char wtm_eeprom[] = {
 617        [ICE_EEP2_SYSCONF]      = 0x67, /*SYSCONF: clock 192KHz, mpu401,
 618                                                        4ADC, 8DAC */
 619        [ICE_EEP2_ACLINK]       = 0x80, /* ACLINK : I2S */
 620        [ICE_EEP2_I2S]          = 0xf8, /* I2S: vol; 96k, 24bit, 192k */
 621        [ICE_EEP2_SPDIF]        = 0xc1, /*SPDIF: out-en, spidf ext out*/
 622        [ICE_EEP2_GPIO_DIR]     = 0x9f,
 623        [ICE_EEP2_GPIO_DIR1]    = 0xff,
 624        [ICE_EEP2_GPIO_DIR2]    = 0x7f,
 625        [ICE_EEP2_GPIO_MASK]    = 0x9f,
 626        [ICE_EEP2_GPIO_MASK1]   = 0xff,
 627        [ICE_EEP2_GPIO_MASK2]   = 0x7f,
 628        [ICE_EEP2_GPIO_STATE]   = 0x16,
 629        [ICE_EEP2_GPIO_STATE1]  = 0x80,
 630        [ICE_EEP2_GPIO_STATE2]  = 0x00,
 631};
 632
 633
 634/*entry point*/
 635struct snd_ice1712_card_info snd_vt1724_wtm_cards[] = {
 636        {
 637                .subvendor = VT1724_SUBDEVICE_WTM,
 638                .name = "ESI Waveterminal 192M",
 639                .model = "WT192M",
 640                .chip_init = wtm_init,
 641                .build_controls = wtm_add_controls,
 642                .eeprom_size = sizeof(wtm_eeprom),
 643                .eeprom_data = wtm_eeprom,
 644        },
 645        {} /*terminator*/
 646};
 647