linux/sound/pci/ice1712/prodigy_hifi.c
<<
>>
Prefs
   1/*
   2 *   ALSA driver for ICEnsemble VT1724 (Envy24HT)
   3 *
   4 *   Lowlevel functions for Audiotrak Prodigy 7.1 Hifi
   5 *   based on pontis.c
   6 *
   7 *      Copyright (c) 2007 Julian Scheel <julian@jusst.de>
   8 *      Copyright (c) 2007 allank
   9 *      Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
  10 *
  11 *   This program is free software; you can redistribute it and/or modify
  12 *   it under the terms of the GNU General Public License as published by
  13 *   the Free Software Foundation; either version 2 of the License, or
  14 *   (at your option) any later version.
  15 *
  16 *   This program is distributed in the hope that it will be useful,
  17 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  18 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19 *   GNU General Public License for more details.
  20 *
  21 *   You should have received a copy of the GNU General Public License
  22 *   along with this program; if not, write to the Free Software
  23 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  24 *
  25 */
  26
  27
  28#include <asm/io.h>
  29#include <linux/delay.h>
  30#include <linux/interrupt.h>
  31#include <linux/init.h>
  32#include <linux/slab.h>
  33#include <linux/mutex.h>
  34
  35#include <sound/core.h>
  36#include <sound/info.h>
  37#include <sound/tlv.h>
  38
  39#include "ice1712.h"
  40#include "envy24ht.h"
  41#include "prodigy_hifi.h"
  42
  43struct prodigy_hifi_spec {
  44        unsigned short master[2];
  45        unsigned short vol[8];
  46};
  47
  48/* I2C addresses */
  49#define WM_DEV          0x34
  50
  51/* WM8776 registers */
  52#define WM_HP_ATTEN_L           0x00    /* headphone left attenuation */
  53#define WM_HP_ATTEN_R           0x01    /* headphone left attenuation */
  54#define WM_HP_MASTER            0x02    /* headphone master (both channels),
  55                                                override LLR */
  56#define WM_DAC_ATTEN_L          0x03    /* digital left attenuation */
  57#define WM_DAC_ATTEN_R          0x04
  58#define WM_DAC_MASTER           0x05
  59#define WM_PHASE_SWAP           0x06    /* DAC phase swap */
  60#define WM_DAC_CTRL1            0x07
  61#define WM_DAC_MUTE             0x08
  62#define WM_DAC_CTRL2            0x09
  63#define WM_DAC_INT              0x0a
  64#define WM_ADC_INT              0x0b
  65#define WM_MASTER_CTRL          0x0c
  66#define WM_POWERDOWN            0x0d
  67#define WM_ADC_ATTEN_L          0x0e
  68#define WM_ADC_ATTEN_R          0x0f
  69#define WM_ALC_CTRL1            0x10
  70#define WM_ALC_CTRL2            0x11
  71#define WM_ALC_CTRL3            0x12
  72#define WM_NOISE_GATE           0x13
  73#define WM_LIMITER              0x14
  74#define WM_ADC_MUX              0x15
  75#define WM_OUT_MUX              0x16
  76#define WM_RESET                0x17
  77
  78/* Analog Recording Source :- Mic, LineIn, CD/Video, */
  79
  80/* implement capture source select control for WM8776 */
  81
  82#define WM_AIN1 "AIN1"
  83#define WM_AIN2 "AIN2"
  84#define WM_AIN3 "AIN3"
  85#define WM_AIN4 "AIN4"
  86#define WM_AIN5 "AIN5"
  87
  88/* GPIO pins of envy24ht connected to wm8766 */
  89#define WM8766_SPI_CLK   (1<<17) /* CLK, Pin97 on ICE1724 */
  90#define WM8766_SPI_MD     (1<<16) /* DATA VT1724 -> WM8766, Pin96 */
  91#define WM8766_SPI_ML     (1<<18) /* Latch, Pin98 */
  92
  93/* WM8766 registers */
  94#define WM8766_DAC_CTRL  0x02   /* DAC Control */
  95#define WM8766_INT_CTRL  0x03   /* Interface Control */
  96#define WM8766_DAC_CTRL2        0x09
  97#define WM8766_DAC_CTRL3        0x0a
  98#define WM8766_RESET        0x1f
  99#define WM8766_LDA1          0x00
 100#define WM8766_LDA2          0x04
 101#define WM8766_LDA3          0x06
 102#define WM8766_RDA1          0x01
 103#define WM8766_RDA2          0x05
 104#define WM8766_RDA3          0x07
 105#define WM8766_MUTE1        0x0C
 106#define WM8766_MUTE2        0x0F
 107
 108
 109/*
 110 * Prodigy HD2
 111 */
 112#define AK4396_ADDR    0x00
 113#define AK4396_CSN    (1 << 8)    /* CSN->GPIO8, pin 75 */
 114#define AK4396_CCLK   (1 << 9)    /* CCLK->GPIO9, pin 76 */
 115#define AK4396_CDTI   (1 << 10)   /* CDTI->GPIO10, pin 77 */
 116
 117/* ak4396 registers */
 118#define AK4396_CTRL1        0x00
 119#define AK4396_CTRL2        0x01
 120#define AK4396_CTRL3        0x02
 121#define AK4396_LCH_ATT    0x03
 122#define AK4396_RCH_ATT    0x04
 123
 124
 125/*
 126 * get the current register value of WM codec
 127 */
 128static unsigned short wm_get(struct snd_ice1712 *ice, int reg)
 129{
 130        reg <<= 1;
 131        return ((unsigned short)ice->akm[0].images[reg] << 8) |
 132                ice->akm[0].images[reg + 1];
 133}
 134
 135/*
 136 * set the register value of WM codec and remember it
 137 */
 138static void wm_put_nocache(struct snd_ice1712 *ice, int reg, unsigned short val)
 139{
 140        unsigned short cval;
 141        cval = (reg << 9) | val;
 142        snd_vt1724_write_i2c(ice, WM_DEV, cval >> 8, cval & 0xff);
 143}
 144
 145static void wm_put(struct snd_ice1712 *ice, int reg, unsigned short val)
 146{
 147        wm_put_nocache(ice, reg, val);
 148        reg <<= 1;
 149        ice->akm[0].images[reg] = val >> 8;
 150        ice->akm[0].images[reg + 1] = val;
 151}
 152
 153/*
 154 * write data in the SPI mode
 155 */
 156
 157static void set_gpio_bit(struct snd_ice1712 *ice, unsigned int bit, int val)
 158{
 159        unsigned int tmp = snd_ice1712_gpio_read(ice);
 160        if (val)
 161                tmp |= bit;
 162        else
 163                tmp &= ~bit;
 164        snd_ice1712_gpio_write(ice, tmp);
 165}
 166
 167/*
 168 * SPI implementation for WM8766 codec - only writing supported, no readback
 169 */
 170
 171static void wm8766_spi_send_word(struct snd_ice1712 *ice, unsigned int data)
 172{
 173        int i;
 174        for (i = 0; i < 16; i++) {
 175                set_gpio_bit(ice, WM8766_SPI_CLK, 0);
 176                udelay(1);
 177                set_gpio_bit(ice, WM8766_SPI_MD, data & 0x8000);
 178                udelay(1);
 179                set_gpio_bit(ice, WM8766_SPI_CLK, 1);
 180                udelay(1);
 181                data <<= 1;
 182        }
 183}
 184
 185static void wm8766_spi_write(struct snd_ice1712 *ice, unsigned int reg,
 186                             unsigned int data)
 187{
 188        unsigned int block;
 189
 190        snd_ice1712_gpio_set_dir(ice, WM8766_SPI_MD|
 191                                        WM8766_SPI_CLK|WM8766_SPI_ML);
 192        snd_ice1712_gpio_set_mask(ice, ~(WM8766_SPI_MD|
 193                                        WM8766_SPI_CLK|WM8766_SPI_ML));
 194        /* latch must be low when writing */
 195        set_gpio_bit(ice, WM8766_SPI_ML, 0);
 196        block = (reg << 9) | (data & 0x1ff);
 197        wm8766_spi_send_word(ice, block); /* REGISTER ADDRESS */
 198        /* release latch */
 199        set_gpio_bit(ice, WM8766_SPI_ML, 1);
 200        udelay(1);
 201        /* restore */
 202        snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask);
 203        snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);
 204}
 205
 206
 207/*
 208 * serial interface for ak4396 - only writing supported, no readback
 209 */
 210
 211static void ak4396_send_word(struct snd_ice1712 *ice, unsigned int data)
 212{
 213        int i;
 214        for (i = 0; i < 16; i++) {
 215                set_gpio_bit(ice, AK4396_CCLK, 0);
 216                udelay(1);
 217                set_gpio_bit(ice, AK4396_CDTI, data & 0x8000);
 218                udelay(1);
 219                set_gpio_bit(ice, AK4396_CCLK, 1);
 220                udelay(1);
 221                data <<= 1;
 222        }
 223}
 224
 225static void ak4396_write(struct snd_ice1712 *ice, unsigned int reg,
 226                         unsigned int data)
 227{
 228        unsigned int block;
 229
 230        snd_ice1712_gpio_set_dir(ice, AK4396_CSN|AK4396_CCLK|AK4396_CDTI);
 231        snd_ice1712_gpio_set_mask(ice, ~(AK4396_CSN|AK4396_CCLK|AK4396_CDTI));
 232        /* latch must be low when writing */
 233        set_gpio_bit(ice, AK4396_CSN, 0); 
 234        block =  ((AK4396_ADDR & 0x03) << 14) | (1 << 13) |
 235                        ((reg & 0x1f) << 8) | (data & 0xff);
 236        ak4396_send_word(ice, block); /* REGISTER ADDRESS */
 237        /* release latch */
 238        set_gpio_bit(ice, AK4396_CSN, 1);
 239        udelay(1);
 240        /* restore */
 241        snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask);
 242        snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);
 243}
 244
 245
 246/*
 247 * ak4396 mixers
 248 */
 249
 250
 251
 252/*
 253 * DAC volume attenuation mixer control (-64dB to 0dB)
 254 */
 255
 256static int ak4396_dac_vol_info(struct snd_kcontrol *kcontrol,
 257                               struct snd_ctl_elem_info *uinfo)
 258{
 259        uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 260        uinfo->count = 2;
 261        uinfo->value.integer.min = 0;   /* mute */
 262        uinfo->value.integer.max = 0xFF; /* linear */
 263        return 0;
 264}
 265
 266static int ak4396_dac_vol_get(struct snd_kcontrol *kcontrol,
 267                              struct snd_ctl_elem_value *ucontrol)
 268{
 269        struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 270        struct prodigy_hifi_spec *spec = ice->spec;
 271        int i;
 272        
 273        for (i = 0; i < 2; i++)
 274                ucontrol->value.integer.value[i] = spec->vol[i];
 275
 276        return 0;
 277}
 278
 279static int ak4396_dac_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 280{
 281        struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 282        struct prodigy_hifi_spec *spec = ice->spec;
 283        int i;
 284        int change = 0;
 285        
 286        mutex_lock(&ice->gpio_mutex);
 287        for (i = 0; i < 2; i++) {
 288                if (ucontrol->value.integer.value[i] != spec->vol[i]) {
 289                        spec->vol[i] = ucontrol->value.integer.value[i];
 290                        ak4396_write(ice, AK4396_LCH_ATT + i,
 291                                     spec->vol[i] & 0xff);
 292                        change = 1;
 293                }
 294        }
 295        mutex_unlock(&ice->gpio_mutex);
 296        return change;
 297}
 298
 299static const DECLARE_TLV_DB_SCALE(db_scale_wm_dac, -12700, 100, 1);
 300
 301static struct snd_kcontrol_new prodigy_hd2_controls[] __devinitdata = {
 302    {
 303        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 304        .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
 305                SNDRV_CTL_ELEM_ACCESS_TLV_READ),
 306        .name = "Front Playback Volume",
 307        .info = ak4396_dac_vol_info,
 308        .get = ak4396_dac_vol_get,
 309        .put = ak4396_dac_vol_put,
 310        .tlv = { .p = db_scale_wm_dac },
 311    },
 312};
 313
 314
 315/* --------------- */
 316
 317/*
 318 * Logarithmic volume values for WM87*6
 319 * Computed as 20 * Log10(255 / x)
 320 */
 321static const unsigned char wm_vol[256] = {
 322        127, 48, 42, 39, 36, 34, 33, 31, 30, 29, 28, 27, 27, 26, 25, 25, 24, 24, 23,
 323        23, 22, 22, 21, 21, 21, 20, 20, 20, 19, 19, 19, 18, 18, 18, 18, 17, 17, 17,
 324        17, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 13, 13, 13,
 325        13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11, 11, 11, 11, 11, 11,
 326        11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8,
 327        8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6,
 328        6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
 329        5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3,
 330        3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
 331        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
 332        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 333        0, 0
 334};
 335
 336#define WM_VOL_MAX      (sizeof(wm_vol) - 1)
 337#define WM_VOL_MUTE     0x8000
 338
 339
 340#define DAC_0dB 0xff
 341#define DAC_RES 128
 342#define DAC_MIN (DAC_0dB - DAC_RES)
 343
 344
 345static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index,
 346                       unsigned short vol, unsigned short master)
 347{
 348        unsigned char nvol;
 349        
 350        if ((master & WM_VOL_MUTE) || (vol & WM_VOL_MUTE))
 351                nvol = 0;
 352        else {
 353                nvol = (((vol & ~WM_VOL_MUTE) * (master & ~WM_VOL_MUTE)) / 128)
 354                                & WM_VOL_MAX;
 355                nvol = (nvol ? (nvol + DAC_MIN) : 0) & 0xff;
 356        }
 357        
 358        wm_put(ice, index, nvol);
 359        wm_put_nocache(ice, index, 0x100 | nvol);
 360}
 361
 362static void wm8766_set_vol(struct snd_ice1712 *ice, unsigned int index,
 363                           unsigned short vol, unsigned short master)
 364{
 365        unsigned char nvol;
 366        
 367        if ((master & WM_VOL_MUTE) || (vol & WM_VOL_MUTE))
 368                nvol = 0;
 369        else {
 370                nvol = (((vol & ~WM_VOL_MUTE) * (master & ~WM_VOL_MUTE)) / 128)
 371                                & WM_VOL_MAX;
 372                nvol = (nvol ? (nvol + DAC_MIN) : 0) & 0xff;
 373        }
 374
 375        wm8766_spi_write(ice, index, (0x0100 | nvol));
 376}
 377
 378
 379/*
 380 * DAC volume attenuation mixer control (-64dB to 0dB)
 381 */
 382
 383static int wm_dac_vol_info(struct snd_kcontrol *kcontrol,
 384                           struct snd_ctl_elem_info *uinfo)
 385{
 386        uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 387        uinfo->count = 2;
 388        uinfo->value.integer.min = 0;   /* mute */
 389        uinfo->value.integer.max = DAC_RES;     /* 0dB, 0.5dB step */
 390        return 0;
 391}
 392
 393static int wm_dac_vol_get(struct snd_kcontrol *kcontrol,
 394                          struct snd_ctl_elem_value *ucontrol)
 395{
 396        struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 397        struct prodigy_hifi_spec *spec = ice->spec;
 398        int i;
 399
 400        for (i = 0; i < 2; i++)
 401                ucontrol->value.integer.value[i] =
 402                        spec->vol[2 + i] & ~WM_VOL_MUTE;
 403        return 0;
 404}
 405
 406static int wm_dac_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 407{
 408        struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 409        struct prodigy_hifi_spec *spec = ice->spec;
 410        int i, idx, change = 0;
 411
 412        mutex_lock(&ice->gpio_mutex);
 413        for (i = 0; i < 2; i++) {
 414                if (ucontrol->value.integer.value[i] != spec->vol[2 + i]) {
 415                        idx = WM_DAC_ATTEN_L + i;
 416                        spec->vol[2 + i] &= WM_VOL_MUTE;
 417                        spec->vol[2 + i] |= ucontrol->value.integer.value[i];
 418                        wm_set_vol(ice, idx, spec->vol[2 + i], spec->master[i]);
 419                        change = 1;
 420                }
 421        }
 422        mutex_unlock(&ice->gpio_mutex);
 423        return change;
 424}
 425
 426
 427/*
 428 * WM8766 DAC volume attenuation mixer control
 429 */
 430static int wm8766_vol_info(struct snd_kcontrol *kcontrol,
 431                           struct snd_ctl_elem_info *uinfo)
 432{
 433        int voices = kcontrol->private_value >> 8;
 434        uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 435        uinfo->count = voices;
 436        uinfo->value.integer.min = 0;           /* mute */
 437        uinfo->value.integer.max = DAC_RES;     /* 0dB */
 438        return 0;
 439}
 440
 441static int wm8766_vol_get(struct snd_kcontrol *kcontrol,
 442                          struct snd_ctl_elem_value *ucontrol)
 443{
 444        struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 445        struct prodigy_hifi_spec *spec = ice->spec;
 446        int i, ofs, voices;
 447
 448        voices = kcontrol->private_value >> 8;
 449        ofs = kcontrol->private_value & 0xff;
 450        for (i = 0; i < voices; i++)
 451                ucontrol->value.integer.value[i] = spec->vol[ofs + i];
 452        return 0;
 453}
 454
 455static int wm8766_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 456{
 457        struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 458        struct prodigy_hifi_spec *spec = ice->spec;
 459        int i, idx, ofs, voices;
 460        int change = 0;
 461
 462        voices = kcontrol->private_value >> 8;
 463        ofs = kcontrol->private_value & 0xff;
 464        mutex_lock(&ice->gpio_mutex);
 465        for (i = 0; i < voices; i++) {
 466                if (ucontrol->value.integer.value[i] != spec->vol[ofs + i]) {
 467                        idx = WM8766_LDA1 + ofs + i;
 468                        spec->vol[ofs + i] &= WM_VOL_MUTE;
 469                        spec->vol[ofs + i] |= ucontrol->value.integer.value[i];
 470                        wm8766_set_vol(ice, idx,
 471                                       spec->vol[ofs + i], spec->master[i]);
 472                        change = 1;
 473                }
 474        }
 475        mutex_unlock(&ice->gpio_mutex);
 476        return change;
 477}
 478
 479/*
 480 * Master volume attenuation mixer control / applied to WM8776+WM8766
 481 */
 482static int wm_master_vol_info(struct snd_kcontrol *kcontrol,
 483                              struct snd_ctl_elem_info *uinfo)
 484{
 485        uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 486        uinfo->count = 2;
 487        uinfo->value.integer.min = 0;
 488        uinfo->value.integer.max = DAC_RES;
 489        return 0;
 490}
 491
 492static int wm_master_vol_get(struct snd_kcontrol *kcontrol,
 493                             struct snd_ctl_elem_value *ucontrol)
 494{
 495        struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 496        struct prodigy_hifi_spec *spec = ice->spec;
 497        int i;
 498        for (i = 0; i < 2; i++)
 499                ucontrol->value.integer.value[i] = spec->master[i];
 500        return 0;
 501}
 502
 503static int wm_master_vol_put(struct snd_kcontrol *kcontrol,
 504                             struct snd_ctl_elem_value *ucontrol)
 505{
 506        struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 507        struct prodigy_hifi_spec *spec = ice->spec;
 508        int ch, change = 0;
 509
 510        mutex_lock(&ice->gpio_mutex);
 511        for (ch = 0; ch < 2; ch++) {
 512                if (ucontrol->value.integer.value[ch] != spec->master[ch]) {
 513                        spec->master[ch] = ucontrol->value.integer.value[ch];
 514
 515                        /* Apply to front DAC */
 516                        wm_set_vol(ice, WM_DAC_ATTEN_L + ch,
 517                                   spec->vol[2 + ch], spec->master[ch]);
 518
 519                        wm8766_set_vol(ice, WM8766_LDA1 + ch,
 520                                       spec->vol[0 + ch], spec->master[ch]);
 521
 522                        wm8766_set_vol(ice, WM8766_LDA2 + ch,
 523                                       spec->vol[4 + ch], spec->master[ch]);
 524
 525                        wm8766_set_vol(ice, WM8766_LDA3 + ch,
 526                                       spec->vol[6 + ch], spec->master[ch]);
 527                        change = 1;
 528                }
 529        }
 530        mutex_unlock(&ice->gpio_mutex); 
 531        return change;
 532}
 533
 534
 535/* KONSTI */
 536
 537static int wm_adc_mux_enum_info(struct snd_kcontrol *kcontrol,
 538                                struct snd_ctl_elem_info *uinfo)
 539{
 540        static char* texts[32] = {
 541                "NULL", WM_AIN1, WM_AIN2, WM_AIN1 "+" WM_AIN2,
 542                WM_AIN3, WM_AIN1 "+" WM_AIN3, WM_AIN2 "+" WM_AIN3,
 543                WM_AIN1 "+" WM_AIN2 "+" WM_AIN3,
 544                WM_AIN4, WM_AIN1 "+" WM_AIN4, WM_AIN2 "+" WM_AIN4,
 545                WM_AIN1 "+" WM_AIN2 "+" WM_AIN4,
 546                WM_AIN3 "+" WM_AIN4, WM_AIN1 "+" WM_AIN3 "+" WM_AIN4,
 547                WM_AIN2 "+" WM_AIN3 "+" WM_AIN4,
 548                WM_AIN1 "+" WM_AIN2 "+" WM_AIN3 "+" WM_AIN4,
 549                WM_AIN5, WM_AIN1 "+" WM_AIN5, WM_AIN2 "+" WM_AIN5,
 550                WM_AIN1 "+" WM_AIN2 "+" WM_AIN5,
 551                WM_AIN3 "+" WM_AIN5, WM_AIN1 "+" WM_AIN3 "+" WM_AIN5,
 552                WM_AIN2 "+" WM_AIN3 "+" WM_AIN5,
 553                WM_AIN1 "+" WM_AIN2 "+" WM_AIN3 "+" WM_AIN5,
 554                WM_AIN4 "+" WM_AIN5, WM_AIN1 "+" WM_AIN4 "+" WM_AIN5,
 555                WM_AIN2 "+" WM_AIN4 "+" WM_AIN5,
 556                WM_AIN1 "+" WM_AIN2 "+" WM_AIN4 "+" WM_AIN5,
 557                WM_AIN3 "+" WM_AIN4 "+" WM_AIN5,
 558                WM_AIN1 "+" WM_AIN3 "+" WM_AIN4 "+" WM_AIN5,
 559                WM_AIN2 "+" WM_AIN3 "+" WM_AIN4 "+" WM_AIN5,
 560                WM_AIN1 "+" WM_AIN2 "+" WM_AIN3 "+" WM_AIN4 "+" WM_AIN5
 561        };
 562
 563        uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
 564        uinfo->count = 1;
 565        uinfo->value.enumerated.items = 32;
 566        if (uinfo->value.enumerated.item > 31)
 567                uinfo->value.enumerated.item = 31;
 568        strcpy(uinfo->value.enumerated.name,
 569               texts[uinfo->value.enumerated.item]);
 570        return 0;
 571}
 572
 573static int wm_adc_mux_enum_get(struct snd_kcontrol *kcontrol,
 574                               struct snd_ctl_elem_value *ucontrol)
 575{
 576        struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 577
 578        mutex_lock(&ice->gpio_mutex);
 579        ucontrol->value.integer.value[0] = wm_get(ice, WM_ADC_MUX) & 0x1f;
 580        mutex_unlock(&ice->gpio_mutex);
 581        return 0;
 582}
 583
 584static int wm_adc_mux_enum_put(struct snd_kcontrol *kcontrol,
 585                               struct snd_ctl_elem_value *ucontrol)
 586{
 587        struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 588        unsigned short oval, nval;
 589        int change = 0;
 590
 591        mutex_lock(&ice->gpio_mutex);
 592        oval = wm_get(ice, WM_ADC_MUX);
 593        nval = (oval & 0xe0) | ucontrol->value.integer.value[0];
 594        if (nval != oval) {
 595                wm_put(ice, WM_ADC_MUX, nval);
 596                change = 1;
 597        }
 598        mutex_unlock(&ice->gpio_mutex);
 599        return change;
 600}
 601
 602/* KONSTI */
 603
 604/*
 605 * ADC gain mixer control (-64dB to 0dB)
 606 */
 607
 608#define ADC_0dB 0xcf
 609#define ADC_RES 128
 610#define ADC_MIN (ADC_0dB - ADC_RES)
 611
 612static int wm_adc_vol_info(struct snd_kcontrol *kcontrol,
 613                           struct snd_ctl_elem_info *uinfo)
 614{
 615        uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 616        uinfo->count = 2;
 617        uinfo->value.integer.min = 0;   /* mute (-64dB) */
 618        uinfo->value.integer.max = ADC_RES;     /* 0dB, 0.5dB step */
 619        return 0;
 620}
 621
 622static int wm_adc_vol_get(struct snd_kcontrol *kcontrol,
 623                          struct snd_ctl_elem_value *ucontrol)
 624{
 625        struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 626        unsigned short val;
 627        int i;
 628
 629        mutex_lock(&ice->gpio_mutex);
 630        for (i = 0; i < 2; i++) {
 631                val = wm_get(ice, WM_ADC_ATTEN_L + i) & 0xff;
 632                val = val > ADC_MIN ? (val - ADC_MIN) : 0;
 633                ucontrol->value.integer.value[i] = val;
 634        }
 635        mutex_unlock(&ice->gpio_mutex);
 636        return 0;
 637}
 638
 639static int wm_adc_vol_put(struct snd_kcontrol *kcontrol,
 640                          struct snd_ctl_elem_value *ucontrol)
 641{
 642        struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 643        unsigned short ovol, nvol;
 644        int i, idx, change = 0;
 645
 646        mutex_lock(&ice->gpio_mutex);
 647        for (i = 0; i < 2; i++) {
 648                nvol = ucontrol->value.integer.value[i];
 649                nvol = nvol ? (nvol + ADC_MIN) : 0;
 650                idx  = WM_ADC_ATTEN_L + i;
 651                ovol = wm_get(ice, idx) & 0xff;
 652                if (ovol != nvol) {
 653                        wm_put(ice, idx, nvol);
 654                        change = 1;
 655                }
 656        }
 657        mutex_unlock(&ice->gpio_mutex);
 658        return change;
 659}
 660
 661/*
 662 * ADC input mux mixer control
 663 */
 664#define wm_adc_mux_info         snd_ctl_boolean_mono_info
 665
 666static int wm_adc_mux_get(struct snd_kcontrol *kcontrol,
 667                          struct snd_ctl_elem_value *ucontrol)
 668{
 669        struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 670        int bit = kcontrol->private_value;
 671
 672        mutex_lock(&ice->gpio_mutex);
 673        ucontrol->value.integer.value[0] =
 674                (wm_get(ice, WM_ADC_MUX) & (1 << bit)) ? 1 : 0;
 675        mutex_unlock(&ice->gpio_mutex);
 676        return 0;
 677}
 678
 679static int wm_adc_mux_put(struct snd_kcontrol *kcontrol,
 680                          struct snd_ctl_elem_value *ucontrol)
 681{
 682        struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 683        int bit = kcontrol->private_value;
 684        unsigned short oval, nval;
 685        int change;
 686
 687        mutex_lock(&ice->gpio_mutex);
 688        nval = oval = wm_get(ice, WM_ADC_MUX);
 689        if (ucontrol->value.integer.value[0])
 690                nval |= (1 << bit);
 691        else
 692                nval &= ~(1 << bit);
 693        change = nval != oval;
 694        if (change) {
 695                wm_put(ice, WM_ADC_MUX, nval);
 696        }
 697        mutex_unlock(&ice->gpio_mutex);
 698        return 0;
 699}
 700
 701/*
 702 * Analog bypass (In -> Out)
 703 */
 704#define wm_bypass_info          snd_ctl_boolean_mono_info
 705
 706static int wm_bypass_get(struct snd_kcontrol *kcontrol,
 707                         struct snd_ctl_elem_value *ucontrol)
 708{
 709        struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 710
 711        mutex_lock(&ice->gpio_mutex);
 712        ucontrol->value.integer.value[0] =
 713                (wm_get(ice, WM_OUT_MUX) & 0x04) ? 1 : 0;
 714        mutex_unlock(&ice->gpio_mutex);
 715        return 0;
 716}
 717
 718static int wm_bypass_put(struct snd_kcontrol *kcontrol,
 719                         struct snd_ctl_elem_value *ucontrol)
 720{
 721        struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 722        unsigned short val, oval;
 723        int change = 0;
 724
 725        mutex_lock(&ice->gpio_mutex);
 726        val = oval = wm_get(ice, WM_OUT_MUX);
 727        if (ucontrol->value.integer.value[0])
 728                val |= 0x04;
 729        else
 730                val &= ~0x04;
 731        if (val != oval) {
 732                wm_put(ice, WM_OUT_MUX, val);
 733                change = 1;
 734        }
 735        mutex_unlock(&ice->gpio_mutex);
 736        return change;
 737}
 738
 739/*
 740 * Left/Right swap
 741 */
 742#define wm_chswap_info          snd_ctl_boolean_mono_info
 743
 744static int wm_chswap_get(struct snd_kcontrol *kcontrol,
 745                         struct snd_ctl_elem_value *ucontrol)
 746{
 747        struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 748
 749        mutex_lock(&ice->gpio_mutex);
 750        ucontrol->value.integer.value[0] =
 751                        (wm_get(ice, WM_DAC_CTRL1) & 0xf0) != 0x90;
 752        mutex_unlock(&ice->gpio_mutex);
 753        return 0;
 754}
 755
 756static int wm_chswap_put(struct snd_kcontrol *kcontrol,
 757                         struct snd_ctl_elem_value *ucontrol)
 758{
 759        struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 760        unsigned short val, oval;
 761        int change = 0;
 762
 763        mutex_lock(&ice->gpio_mutex);
 764        oval = wm_get(ice, WM_DAC_CTRL1);
 765        val = oval & 0x0f;
 766        if (ucontrol->value.integer.value[0])
 767                val |= 0x60;
 768        else
 769                val |= 0x90;
 770        if (val != oval) {
 771                wm_put(ice, WM_DAC_CTRL1, val);
 772                wm_put_nocache(ice, WM_DAC_CTRL1, val);
 773                change = 1;
 774        }
 775        mutex_unlock(&ice->gpio_mutex);
 776        return change;
 777}
 778
 779
 780/*
 781 * mixers
 782 */
 783
 784static struct snd_kcontrol_new prodigy_hifi_controls[] __devinitdata = {
 785        {
 786                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 787                .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
 788                           SNDRV_CTL_ELEM_ACCESS_TLV_READ),
 789                .name = "Master Playback Volume",
 790                .info = wm_master_vol_info,
 791                .get = wm_master_vol_get,
 792                .put = wm_master_vol_put,
 793                .tlv = { .p = db_scale_wm_dac }
 794        },
 795        {
 796                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 797                .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
 798                           SNDRV_CTL_ELEM_ACCESS_TLV_READ),
 799                .name = "Front Playback Volume",
 800                .info = wm_dac_vol_info,
 801                .get = wm_dac_vol_get,
 802                .put = wm_dac_vol_put,
 803                .tlv = { .p = db_scale_wm_dac },
 804        },
 805        {
 806                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 807                .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
 808                           SNDRV_CTL_ELEM_ACCESS_TLV_READ),
 809                .name = "Rear Playback Volume",
 810                .info = wm8766_vol_info,
 811                .get = wm8766_vol_get,
 812                .put = wm8766_vol_put,
 813                .private_value = (2 << 8) | 0,
 814                .tlv = { .p = db_scale_wm_dac },
 815        },
 816        {
 817                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 818                .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
 819                           SNDRV_CTL_ELEM_ACCESS_TLV_READ),
 820                .name = "Center Playback Volume",
 821                .info = wm8766_vol_info,
 822                .get = wm8766_vol_get,
 823                .put = wm8766_vol_put,
 824                .private_value = (1 << 8) | 4,
 825                .tlv = { .p = db_scale_wm_dac }
 826        },
 827        {
 828                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 829                .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
 830                           SNDRV_CTL_ELEM_ACCESS_TLV_READ),
 831                .name = "LFE Playback Volume",
 832                .info = wm8766_vol_info,
 833                .get = wm8766_vol_get,
 834                .put = wm8766_vol_put,
 835                .private_value = (1 << 8) | 5,
 836                .tlv = { .p = db_scale_wm_dac }
 837        },
 838        {
 839                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 840                .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
 841                           SNDRV_CTL_ELEM_ACCESS_TLV_READ),
 842                .name = "Side Playback Volume",
 843                .info = wm8766_vol_info,
 844                .get = wm8766_vol_get,
 845                .put = wm8766_vol_put,
 846                .private_value = (2 << 8) | 6,
 847                .tlv = { .p = db_scale_wm_dac },
 848        },
 849        {
 850                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 851                .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
 852                           SNDRV_CTL_ELEM_ACCESS_TLV_READ),
 853                .name = "Capture Volume",
 854                .info = wm_adc_vol_info,
 855                .get = wm_adc_vol_get,
 856                .put = wm_adc_vol_put,
 857                .tlv = { .p = db_scale_wm_dac },
 858        },
 859        {
 860                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 861                .name = "CD Capture Switch",
 862                .info = wm_adc_mux_info,
 863                .get = wm_adc_mux_get,
 864                .put = wm_adc_mux_put,
 865                .private_value = 0,
 866        },
 867        {
 868                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 869                .name = "Line Capture Switch",
 870                .info = wm_adc_mux_info,
 871                .get = wm_adc_mux_get,
 872                .put = wm_adc_mux_put,
 873                .private_value = 1,
 874        },
 875        {
 876                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 877                .name = "Analog Bypass Switch",
 878                .info = wm_bypass_info,
 879                .get = wm_bypass_get,
 880                .put = wm_bypass_put,
 881        },
 882        {
 883                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 884                .name = "Swap Output Channels",
 885                .info = wm_chswap_info,
 886                .get = wm_chswap_get,
 887                .put = wm_chswap_put,
 888        },
 889        {
 890                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 891                .name = "Analog Capture Source",
 892                .info = wm_adc_mux_enum_info,
 893                .get = wm_adc_mux_enum_get,
 894                .put = wm_adc_mux_enum_put,
 895        },
 896};
 897
 898/*
 899 * WM codec registers
 900 */
 901static void wm_proc_regs_write(struct snd_info_entry *entry,
 902                               struct snd_info_buffer *buffer)
 903{
 904        struct snd_ice1712 *ice = entry->private_data;
 905        char line[64];
 906        unsigned int reg, val;
 907        mutex_lock(&ice->gpio_mutex);
 908        while (!snd_info_get_line(buffer, line, sizeof(line))) {
 909                if (sscanf(line, "%x %x", &reg, &val) != 2)
 910                        continue;
 911                if (reg <= 0x17 && val <= 0xffff)
 912                        wm_put(ice, reg, val);
 913        }
 914        mutex_unlock(&ice->gpio_mutex);
 915}
 916
 917static void wm_proc_regs_read(struct snd_info_entry *entry,
 918                              struct snd_info_buffer *buffer)
 919{
 920        struct snd_ice1712 *ice = entry->private_data;
 921        int reg, val;
 922
 923        mutex_lock(&ice->gpio_mutex);
 924        for (reg = 0; reg <= 0x17; reg++) {
 925                val = wm_get(ice, reg);
 926                snd_iprintf(buffer, "%02x = %04x\n", reg, val);
 927        }
 928        mutex_unlock(&ice->gpio_mutex);
 929}
 930
 931static void wm_proc_init(struct snd_ice1712 *ice)
 932{
 933        struct snd_info_entry *entry;
 934        if (!snd_card_proc_new(ice->card, "wm_codec", &entry)) {
 935                snd_info_set_text_ops(entry, ice, wm_proc_regs_read);
 936                entry->mode |= S_IWUSR;
 937                entry->c.text.write = wm_proc_regs_write;
 938        }
 939}
 940
 941static int __devinit prodigy_hifi_add_controls(struct snd_ice1712 *ice)
 942{
 943        unsigned int i;
 944        int err;
 945
 946        for (i = 0; i < ARRAY_SIZE(prodigy_hifi_controls); i++) {
 947                err = snd_ctl_add(ice->card,
 948                                  snd_ctl_new1(&prodigy_hifi_controls[i], ice));
 949                if (err < 0)
 950                        return err;
 951        }
 952
 953        wm_proc_init(ice);
 954
 955        return 0;
 956}
 957
 958static int __devinit prodigy_hd2_add_controls(struct snd_ice1712 *ice)
 959{
 960        unsigned int i;
 961        int err;
 962
 963        for (i = 0; i < ARRAY_SIZE(prodigy_hd2_controls); i++) {
 964                err = snd_ctl_add(ice->card,
 965                                  snd_ctl_new1(&prodigy_hd2_controls[i], ice));
 966                if (err < 0)
 967                        return err;
 968        }
 969
 970        wm_proc_init(ice);
 971
 972        return 0;
 973}
 974
 975
 976/*
 977 * initialize the chip
 978 */
 979static int __devinit prodigy_hifi_init(struct snd_ice1712 *ice)
 980{
 981        static unsigned short wm_inits[] = {
 982                /* These come first to reduce init pop noise */
 983                WM_ADC_MUX,     0x0003, /* ADC mute */
 984                /* 0x00c0 replaced by 0x0003 */
 985                
 986                WM_DAC_MUTE,    0x0001, /* DAC softmute */
 987                WM_DAC_CTRL1,   0x0000, /* DAC mute */
 988
 989                WM_POWERDOWN,   0x0008, /* All power-up except HP */
 990                WM_RESET,       0x0000, /* reset */
 991        };
 992        static unsigned short wm_inits2[] = {
 993                WM_MASTER_CTRL,  0x0022, /* 256fs, slave mode */
 994                WM_DAC_INT,     0x0022, /* I2S, normal polarity, 24bit */
 995                WM_ADC_INT,     0x0022, /* I2S, normal polarity, 24bit */
 996                WM_DAC_CTRL1,   0x0090, /* DAC L/R */
 997                WM_OUT_MUX,     0x0001, /* OUT DAC */
 998                WM_HP_ATTEN_L,  0x0179, /* HP 0dB */
 999                WM_HP_ATTEN_R,  0x0179, /* HP 0dB */
1000                WM_DAC_ATTEN_L, 0x0000, /* DAC 0dB */
1001                WM_DAC_ATTEN_L, 0x0100, /* DAC 0dB */
1002                WM_DAC_ATTEN_R, 0x0000, /* DAC 0dB */
1003                WM_DAC_ATTEN_R, 0x0100, /* DAC 0dB */
1004                WM_PHASE_SWAP,  0x0000, /* phase normal */
1005#if 0
1006                WM_DAC_MASTER,  0x0100, /* DAC master muted */
1007#endif
1008                WM_DAC_CTRL2,   0x0000, /* no deemphasis, no ZFLG */
1009                WM_ADC_ATTEN_L, 0x0000, /* ADC muted */
1010                WM_ADC_ATTEN_R, 0x0000, /* ADC muted */
1011#if 1
1012                WM_ALC_CTRL1,   0x007b, /* */
1013                WM_ALC_CTRL2,   0x0000, /* */
1014                WM_ALC_CTRL3,   0x0000, /* */
1015                WM_NOISE_GATE,  0x0000, /* */
1016#endif
1017                WM_DAC_MUTE,    0x0000, /* DAC unmute */
1018                WM_ADC_MUX,     0x0003, /* ADC unmute, both CD/Line On */
1019        };
1020        static unsigned short wm8766_inits[] = {
1021                WM8766_RESET,      0x0000,
1022                WM8766_DAC_CTRL,        0x0120,
1023                WM8766_INT_CTRL,        0x0022, /* I2S Normal Mode, 24 bit */
1024                WM8766_DAC_CTRL2,       0x0001,
1025                WM8766_DAC_CTRL3,       0x0080,
1026                WM8766_LDA1,        0x0100,
1027                WM8766_LDA2,        0x0100,
1028                WM8766_LDA3,        0x0100,
1029                WM8766_RDA1,        0x0100,
1030                WM8766_RDA2,        0x0100,
1031                WM8766_RDA3,        0x0100,
1032                WM8766_MUTE1,      0x0000,
1033                WM8766_MUTE2,      0x0000,
1034        };
1035
1036        struct prodigy_hifi_spec *spec;
1037        unsigned int i;
1038
1039        ice->vt1720 = 0;
1040        ice->vt1724 = 1;
1041
1042        ice->num_total_dacs = 8;
1043        ice->num_total_adcs = 1;
1044
1045        /* HACK - use this as the SPDIF source.
1046        * don't call snd_ice1712_gpio_get/put(), otherwise it's overwritten
1047        */
1048        ice->gpio.saved[0] = 0;
1049        /* to remeber the register values */
1050
1051        ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
1052        if (! ice->akm)
1053                return -ENOMEM;
1054        ice->akm_codecs = 1;
1055
1056        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1057        if (!spec)
1058                return -ENOMEM;
1059        ice->spec = spec;
1060
1061        /* initialize WM8776 codec */
1062        for (i = 0; i < ARRAY_SIZE(wm_inits); i += 2)
1063                wm_put(ice, wm_inits[i], wm_inits[i+1]);
1064        schedule_timeout_uninterruptible(1);
1065        for (i = 0; i < ARRAY_SIZE(wm_inits2); i += 2)
1066                wm_put(ice, wm_inits2[i], wm_inits2[i+1]);
1067
1068        /* initialize WM8766 codec */
1069        for (i = 0; i < ARRAY_SIZE(wm8766_inits); i += 2)
1070                wm8766_spi_write(ice, wm8766_inits[i], wm8766_inits[i+1]);
1071
1072
1073        return 0;
1074}
1075
1076
1077/*
1078 * initialize the chip
1079 */
1080static void ak4396_init(struct snd_ice1712 *ice)
1081{
1082        static unsigned short ak4396_inits[] = {
1083                AK4396_CTRL1,      0x87,   /* I2S Normal Mode, 24 bit */
1084                AK4396_CTRL2,      0x02,
1085                AK4396_CTRL3,      0x00, 
1086                AK4396_LCH_ATT,  0x00,
1087                AK4396_RCH_ATT,  0x00,
1088        };
1089
1090        unsigned int i;
1091
1092        /* initialize ak4396 codec */
1093        /* reset codec */
1094        ak4396_write(ice, AK4396_CTRL1, 0x86);
1095        msleep(100);
1096        ak4396_write(ice, AK4396_CTRL1, 0x87);
1097
1098        for (i = 0; i < ARRAY_SIZE(ak4396_inits); i += 2)
1099                ak4396_write(ice, ak4396_inits[i], ak4396_inits[i+1]);
1100}
1101
1102#ifdef CONFIG_PM
1103static int prodigy_hd2_resume(struct snd_ice1712 *ice)
1104{
1105        /* initialize ak4396 codec and restore previous mixer volumes */
1106        struct prodigy_hifi_spec *spec = ice->spec;
1107        int i;
1108        mutex_lock(&ice->gpio_mutex);
1109        ak4396_init(ice);
1110        for (i = 0; i < 2; i++)
1111                ak4396_write(ice, AK4396_LCH_ATT + i, spec->vol[i] & 0xff);
1112        mutex_unlock(&ice->gpio_mutex);
1113        return 0;
1114}
1115#endif
1116
1117static int __devinit prodigy_hd2_init(struct snd_ice1712 *ice)
1118{
1119        struct prodigy_hifi_spec *spec;
1120
1121        ice->vt1720 = 0;
1122        ice->vt1724 = 1;
1123
1124        ice->num_total_dacs = 1;
1125        ice->num_total_adcs = 1;
1126
1127        /* HACK - use this as the SPDIF source.
1128        * don't call snd_ice1712_gpio_get/put(), otherwise it's overwritten
1129        */
1130        ice->gpio.saved[0] = 0;
1131        /* to remeber the register values */
1132
1133        ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
1134        if (! ice->akm)
1135                return -ENOMEM;
1136        ice->akm_codecs = 1;
1137
1138        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1139        if (!spec)
1140                return -ENOMEM;
1141        ice->spec = spec;
1142
1143#ifdef CONFIG_PM
1144        ice->pm_resume = &prodigy_hd2_resume;
1145        ice->pm_suspend_enabled = 1;
1146#endif
1147
1148        ak4396_init(ice);
1149
1150        return 0;
1151}
1152
1153
1154static unsigned char prodigy71hifi_eeprom[] __devinitdata = {
1155        0x4b,   /* SYSCONF: clock 512, spdif-in/ADC, 4DACs */
1156        0x80,   /* ACLINK: I2S */
1157        0xfc,   /* I2S: vol, 96k, 24bit, 192k */
1158        0xc3,   /* SPDIF: out-en, out-int, spdif-in */
1159        0xff,   /* GPIO_DIR */
1160        0xff,   /* GPIO_DIR1 */
1161        0x5f,   /* GPIO_DIR2 */
1162        0x00,   /* GPIO_MASK */
1163        0x00,   /* GPIO_MASK1 */
1164        0x00,   /* GPIO_MASK2 */
1165        0x00,   /* GPIO_STATE */
1166        0x00,   /* GPIO_STATE1 */
1167        0x00,   /* GPIO_STATE2 */
1168};
1169
1170static unsigned char prodigyhd2_eeprom[] __devinitdata = {
1171        0x4b,   /* SYSCONF: clock 512, spdif-in/ADC, 4DACs */
1172        0x80,   /* ACLINK: I2S */
1173        0xfc,   /* I2S: vol, 96k, 24bit, 192k */
1174        0xc3,   /* SPDIF: out-en, out-int, spdif-in */
1175        0xff,   /* GPIO_DIR */
1176        0xff,   /* GPIO_DIR1 */
1177        0x5f,   /* GPIO_DIR2 */
1178        0x00,   /* GPIO_MASK */
1179        0x00,   /* GPIO_MASK1 */
1180        0x00,   /* GPIO_MASK2 */
1181        0x00,   /* GPIO_STATE */
1182        0x00,   /* GPIO_STATE1 */
1183        0x00,   /* GPIO_STATE2 */
1184};
1185
1186static unsigned char fortissimo4_eeprom[] __devinitdata = {
1187        0x43,   /* SYSCONF: clock 512, ADC, 4DACs */    
1188        0x80,   /* ACLINK: I2S */
1189        0xfc,   /* I2S: vol, 96k, 24bit, 192k */
1190        0xc1,   /* SPDIF: out-en, out-int */
1191        0xff,   /* GPIO_DIR */
1192        0xff,   /* GPIO_DIR1 */
1193        0x5f,   /* GPIO_DIR2 */
1194        0x00,   /* GPIO_MASK */
1195        0x00,   /* GPIO_MASK1 */
1196        0x00,   /* GPIO_MASK2 */
1197        0x00,   /* GPIO_STATE */
1198        0x00,   /* GPIO_STATE1 */
1199        0x00,   /* GPIO_STATE2 */
1200};
1201
1202/* entry point */
1203struct snd_ice1712_card_info snd_vt1724_prodigy_hifi_cards[] __devinitdata = {
1204        {
1205                .subvendor = VT1724_SUBDEVICE_PRODIGY_HIFI,
1206                .name = "Audiotrak Prodigy 7.1 HiFi",
1207                .model = "prodigy71hifi",
1208                .chip_init = prodigy_hifi_init,
1209                .build_controls = prodigy_hifi_add_controls,
1210                .eeprom_size = sizeof(prodigy71hifi_eeprom),
1211                .eeprom_data = prodigy71hifi_eeprom,
1212                .driver = "Prodigy71HIFI",
1213        },
1214        {
1215        .subvendor = VT1724_SUBDEVICE_PRODIGY_HD2,
1216        .name = "Audiotrak Prodigy HD2",
1217        .model = "prodigyhd2",
1218        .chip_init = prodigy_hd2_init,
1219        .build_controls = prodigy_hd2_add_controls,
1220        .eeprom_size = sizeof(prodigyhd2_eeprom),
1221        .eeprom_data = prodigyhd2_eeprom,
1222        .driver = "Prodigy71HD2",
1223        },
1224        {
1225                .subvendor = VT1724_SUBDEVICE_FORTISSIMO4,
1226                .name = "Hercules Fortissimo IV",
1227                .model = "fortissimo4",
1228                .chip_init = prodigy_hifi_init,
1229                .build_controls = prodigy_hifi_add_controls,
1230                .eeprom_size = sizeof(fortissimo4_eeprom),
1231                .eeprom_data = fortissimo4_eeprom,
1232                .driver = "Fortissimo4",
1233        },
1234        { } /* terminator */
1235};
1236
1237