linux/sound/pci/ice1712/maya44.c
<<
>>
Prefs
   1/*
   2 *   ALSA driver for ICEnsemble VT1724 (Envy24HT)
   3 *
   4 *   Lowlevel functions for ESI Maya44 cards
   5 *
   6 *      Copyright (c) 2009 Takashi Iwai <tiwai@suse.de>
   7 *      Based on the patches by Rainer Zimmermann <mail@lightshed.de>
   8 *
   9 *   This program is free software; you can redistribute it and/or modify
  10 *   it under the terms of the GNU General Public License as published by
  11 *   the Free Software Foundation; either version 2 of the License, or
  12 *   (at your option) any later version.
  13 *
  14 *   This program is distributed in the hope that it will be useful,
  15 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17 *   GNU General Public License for more details.
  18 *
  19 *   You should have received a copy of the GNU General Public License
  20 *   along with this program; if not, write to the Free Software
  21 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  22 *
  23 */
  24
  25#include <linux/init.h>
  26#include <linux/slab.h>
  27#include <linux/io.h>
  28#include <sound/core.h>
  29#include <sound/control.h>
  30#include <sound/pcm.h>
  31#include <sound/tlv.h>
  32
  33#include "ice1712.h"
  34#include "envy24ht.h"
  35#include "maya44.h"
  36
  37/* WM8776 register indexes */
  38#define WM8776_REG_HEADPHONE_L          0x00
  39#define WM8776_REG_HEADPHONE_R          0x01
  40#define WM8776_REG_HEADPHONE_MASTER     0x02
  41#define WM8776_REG_DAC_ATTEN_L          0x03
  42#define WM8776_REG_DAC_ATTEN_R          0x04
  43#define WM8776_REG_DAC_ATTEN_MASTER     0x05
  44#define WM8776_REG_DAC_PHASE            0x06
  45#define WM8776_REG_DAC_CONTROL          0x07
  46#define WM8776_REG_DAC_MUTE             0x08
  47#define WM8776_REG_DAC_DEEMPH           0x09
  48#define WM8776_REG_DAC_IF_CONTROL       0x0a
  49#define WM8776_REG_ADC_IF_CONTROL       0x0b
  50#define WM8776_REG_MASTER_MODE_CONTROL  0x0c
  51#define WM8776_REG_POWERDOWN            0x0d
  52#define WM8776_REG_ADC_ATTEN_L          0x0e
  53#define WM8776_REG_ADC_ATTEN_R          0x0f
  54#define WM8776_REG_ADC_ALC1             0x10
  55#define WM8776_REG_ADC_ALC2             0x11
  56#define WM8776_REG_ADC_ALC3             0x12
  57#define WM8776_REG_ADC_NOISE_GATE       0x13
  58#define WM8776_REG_ADC_LIMITER          0x14
  59#define WM8776_REG_ADC_MUX              0x15
  60#define WM8776_REG_OUTPUT_MUX           0x16
  61#define WM8776_REG_RESET                0x17
  62
  63#define WM8776_NUM_REGS                 0x18
  64
  65/* clock ratio identifiers for snd_wm8776_set_rate() */
  66#define WM8776_CLOCK_RATIO_128FS        0
  67#define WM8776_CLOCK_RATIO_192FS        1
  68#define WM8776_CLOCK_RATIO_256FS        2
  69#define WM8776_CLOCK_RATIO_384FS        3
  70#define WM8776_CLOCK_RATIO_512FS        4
  71#define WM8776_CLOCK_RATIO_768FS        5
  72
  73enum { WM_VOL_HP, WM_VOL_DAC, WM_VOL_ADC, WM_NUM_VOLS };
  74enum { WM_SW_DAC, WM_SW_BYPASS, WM_NUM_SWITCHES };
  75
  76struct snd_wm8776 {
  77        unsigned char addr;
  78        unsigned short regs[WM8776_NUM_REGS];
  79        unsigned char volumes[WM_NUM_VOLS][2];
  80        unsigned int switch_bits;
  81};
  82
  83struct snd_maya44 {
  84        struct snd_ice1712 *ice;
  85        struct snd_wm8776 wm[2];
  86        struct mutex mutex;
  87};
  88
  89
  90/* write the given register and save the data to the cache */
  91static void wm8776_write(struct snd_ice1712 *ice, struct snd_wm8776 *wm,
  92                         unsigned char reg, unsigned short val)
  93{
  94        /*
  95         * WM8776 registers are up to 9 bits wide, bit 8 is placed in the LSB
  96         * of the address field
  97         */
  98        snd_vt1724_write_i2c(ice, wm->addr,
  99                             (reg << 1) | ((val >> 8) & 1),
 100                             val & 0xff);
 101        wm->regs[reg] = val;
 102}
 103
 104/*
 105 * update the given register with and/or mask and save the data to the cache
 106 */
 107static int wm8776_write_bits(struct snd_ice1712 *ice, struct snd_wm8776 *wm,
 108                             unsigned char reg,
 109                             unsigned short mask, unsigned short val)
 110{
 111        val |= wm->regs[reg] & ~mask;
 112        if (val != wm->regs[reg]) {
 113                wm8776_write(ice, wm, reg, val);
 114                return 1;
 115        }
 116        return 0;
 117}
 118
 119
 120/*
 121 * WM8776 volume controls
 122 */
 123
 124struct maya_vol_info {
 125        unsigned int maxval;            /* volume range: 0..maxval */
 126        unsigned char regs[2];          /* left and right registers */
 127        unsigned short mask;            /* value mask */
 128        unsigned short offset;          /* zero-value offset */
 129        unsigned short mute;            /* mute bit */
 130        unsigned short update;          /* update bits */
 131        unsigned char mux_bits[2];      /* extra bits for ADC mute */
 132};
 133
 134static struct maya_vol_info vol_info[WM_NUM_VOLS] = {
 135        [WM_VOL_HP] = {
 136                .maxval = 80,
 137                .regs = { WM8776_REG_HEADPHONE_L, WM8776_REG_HEADPHONE_R },
 138                .mask = 0x7f,
 139                .offset = 0x30,
 140                .mute = 0x00,
 141                .update = 0x180,        /* update and zero-cross enable */
 142        },
 143        [WM_VOL_DAC] = {
 144                .maxval = 255,
 145                .regs = { WM8776_REG_DAC_ATTEN_L, WM8776_REG_DAC_ATTEN_R },
 146                .mask = 0xff,
 147                .offset = 0x01,
 148                .mute = 0x00,
 149                .update = 0x100,        /* zero-cross enable */
 150        },
 151        [WM_VOL_ADC] = {
 152                .maxval = 91,
 153                .regs = { WM8776_REG_ADC_ATTEN_L, WM8776_REG_ADC_ATTEN_R },
 154                .mask = 0xff,
 155                .offset = 0xa5,
 156                .mute = 0xa5,
 157                .update = 0x100,        /* update */
 158                .mux_bits = { 0x80, 0x40 }, /* ADCMUX bits */
 159        },
 160};
 161
 162/*
 163 * dB tables
 164 */
 165/* headphone output: mute, -73..+6db (1db step) */
 166static const DECLARE_TLV_DB_SCALE(db_scale_hp, -7400, 100, 1);
 167/* DAC output: mute, -127..0db (0.5db step) */
 168static const DECLARE_TLV_DB_SCALE(db_scale_dac, -12750, 50, 1);
 169/* ADC gain: mute, -21..+24db (0.5db step) */
 170static const DECLARE_TLV_DB_SCALE(db_scale_adc, -2100, 50, 1);
 171
 172static int maya_vol_info(struct snd_kcontrol *kcontrol,
 173                         struct snd_ctl_elem_info *uinfo)
 174{
 175        unsigned int idx = kcontrol->private_value;
 176        struct maya_vol_info *vol = &vol_info[idx];
 177
 178        uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 179        uinfo->count = 2;
 180        uinfo->value.integer.min = 0;
 181        uinfo->value.integer.max = vol->maxval;
 182        return 0;
 183}
 184
 185static int maya_vol_get(struct snd_kcontrol *kcontrol,
 186                        struct snd_ctl_elem_value *ucontrol)
 187{
 188        struct snd_maya44 *chip = snd_kcontrol_chip(kcontrol);
 189        struct snd_wm8776 *wm =
 190                &chip->wm[snd_ctl_get_ioff(kcontrol, &ucontrol->id)];
 191        unsigned int idx = kcontrol->private_value;
 192
 193        mutex_lock(&chip->mutex);
 194        ucontrol->value.integer.value[0] = wm->volumes[idx][0];
 195        ucontrol->value.integer.value[1] = wm->volumes[idx][1];
 196        mutex_unlock(&chip->mutex);
 197        return 0;
 198}
 199
 200static int maya_vol_put(struct snd_kcontrol *kcontrol,
 201                        struct snd_ctl_elem_value *ucontrol)
 202{
 203        struct snd_maya44 *chip = snd_kcontrol_chip(kcontrol);
 204        struct snd_wm8776 *wm =
 205                &chip->wm[snd_ctl_get_ioff(kcontrol, &ucontrol->id)];
 206        unsigned int idx = kcontrol->private_value;
 207        struct maya_vol_info *vol = &vol_info[idx];
 208        unsigned int val, data;
 209        int ch, changed = 0;
 210
 211        mutex_lock(&chip->mutex);
 212        for (ch = 0; ch < 2; ch++) {
 213                val = ucontrol->value.integer.value[ch];
 214                if (val > vol->maxval)
 215                        val = vol->maxval;
 216                if (val == wm->volumes[idx][ch])
 217                        continue;
 218                if (!val)
 219                        data = vol->mute;
 220                else
 221                        data = (val - 1) + vol->offset;
 222                data |= vol->update;
 223                changed |= wm8776_write_bits(chip->ice, wm, vol->regs[ch],
 224                                             vol->mask | vol->update, data);
 225                if (vol->mux_bits[ch])
 226                        wm8776_write_bits(chip->ice, wm, WM8776_REG_ADC_MUX,
 227                                          vol->mux_bits[ch],
 228                                          val ? 0 : vol->mux_bits[ch]);
 229                wm->volumes[idx][ch] = val;
 230        }
 231        mutex_unlock(&chip->mutex);
 232        return changed;
 233}
 234
 235/*
 236 * WM8776 switch controls
 237 */
 238
 239#define COMPOSE_SW_VAL(idx, reg, mask)  ((idx) | ((reg) << 8) | ((mask) << 16))
 240#define GET_SW_VAL_IDX(val)     ((val) & 0xff)
 241#define GET_SW_VAL_REG(val)     (((val) >> 8) & 0xff)
 242#define GET_SW_VAL_MASK(val)    (((val) >> 16) & 0xff)
 243
 244#define maya_sw_info    snd_ctl_boolean_mono_info
 245
 246static int maya_sw_get(struct snd_kcontrol *kcontrol,
 247                       struct snd_ctl_elem_value *ucontrol)
 248{
 249        struct snd_maya44 *chip = snd_kcontrol_chip(kcontrol);
 250        struct snd_wm8776 *wm =
 251                &chip->wm[snd_ctl_get_ioff(kcontrol, &ucontrol->id)];
 252        unsigned int idx = GET_SW_VAL_IDX(kcontrol->private_value);
 253
 254        ucontrol->value.integer.value[0] = (wm->switch_bits >> idx) & 1;
 255        return 0;
 256}
 257
 258static int maya_sw_put(struct snd_kcontrol *kcontrol,
 259                       struct snd_ctl_elem_value *ucontrol)
 260{
 261        struct snd_maya44 *chip = snd_kcontrol_chip(kcontrol);
 262        struct snd_wm8776 *wm =
 263                &chip->wm[snd_ctl_get_ioff(kcontrol, &ucontrol->id)];
 264        unsigned int idx = GET_SW_VAL_IDX(kcontrol->private_value);
 265        unsigned int mask, val;
 266        int changed;
 267
 268        mutex_lock(&chip->mutex);
 269        mask = 1 << idx;
 270        wm->switch_bits &= ~mask;
 271        val = ucontrol->value.integer.value[0];
 272        if (val)
 273                wm->switch_bits |= mask;
 274        mask = GET_SW_VAL_MASK(kcontrol->private_value);
 275        changed = wm8776_write_bits(chip->ice, wm,
 276                                    GET_SW_VAL_REG(kcontrol->private_value),
 277                                    mask, val ? mask : 0);
 278        mutex_unlock(&chip->mutex);
 279        return changed;
 280}
 281
 282/*
 283 * GPIO pins (known ones for maya44)
 284 */
 285#define GPIO_PHANTOM_OFF        2
 286#define GPIO_MIC_RELAY          4
 287#define GPIO_SPDIF_IN_INV       5
 288#define GPIO_MUST_BE_0          7
 289
 290/*
 291 * GPIO switch controls
 292 */
 293
 294#define COMPOSE_GPIO_VAL(shift, inv)    ((shift) | ((inv) << 8))
 295#define GET_GPIO_VAL_SHIFT(val)         ((val) & 0xff)
 296#define GET_GPIO_VAL_INV(val)           (((val) >> 8) & 1)
 297
 298static int maya_set_gpio_bits(struct snd_ice1712 *ice, unsigned int mask,
 299                              unsigned int bits)
 300{
 301        unsigned int data;
 302        data = snd_ice1712_gpio_read(ice);
 303        if ((data & mask) == bits)
 304                return 0;
 305        snd_ice1712_gpio_write(ice, (data & ~mask) | bits);
 306        return 1;
 307}
 308
 309#define maya_gpio_sw_info       snd_ctl_boolean_mono_info
 310
 311static int maya_gpio_sw_get(struct snd_kcontrol *kcontrol,
 312                            struct snd_ctl_elem_value *ucontrol)
 313{
 314        struct snd_maya44 *chip = snd_kcontrol_chip(kcontrol);
 315        unsigned int shift = GET_GPIO_VAL_SHIFT(kcontrol->private_value);
 316        unsigned int val;
 317
 318        val = (snd_ice1712_gpio_read(chip->ice) >> shift) & 1;
 319        if (GET_GPIO_VAL_INV(kcontrol->private_value))
 320                val = !val;
 321        ucontrol->value.integer.value[0] = val;
 322        return 0;
 323}
 324
 325static int maya_gpio_sw_put(struct snd_kcontrol *kcontrol,
 326                            struct snd_ctl_elem_value *ucontrol)
 327{
 328        struct snd_maya44 *chip = snd_kcontrol_chip(kcontrol);
 329        unsigned int shift = GET_GPIO_VAL_SHIFT(kcontrol->private_value);
 330        unsigned int val, mask;
 331        int changed;
 332
 333        mutex_lock(&chip->mutex);
 334        mask = 1 << shift;
 335        val = ucontrol->value.integer.value[0];
 336        if (GET_GPIO_VAL_INV(kcontrol->private_value))
 337                val = !val;
 338        val = val ? mask : 0;
 339        changed = maya_set_gpio_bits(chip->ice, mask, val);
 340        mutex_unlock(&chip->mutex);
 341        return changed;
 342}
 343
 344/*
 345 * capture source selection
 346 */
 347
 348/* known working input slots (0-4) */
 349#define MAYA_LINE_IN    1       /* in-2 */
 350#define MAYA_MIC_IN     3       /* in-4 */
 351
 352static void wm8776_select_input(struct snd_maya44 *chip, int idx, int line)
 353{
 354        wm8776_write_bits(chip->ice, &chip->wm[idx], WM8776_REG_ADC_MUX,
 355                          0x1f, 1 << line);
 356}
 357
 358static int maya_rec_src_info(struct snd_kcontrol *kcontrol,
 359                             struct snd_ctl_elem_info *uinfo)
 360{
 361        static char *texts[] = { "Line", "Mic" };
 362
 363        uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
 364        uinfo->count = 1;
 365        uinfo->value.enumerated.items = ARRAY_SIZE(texts);
 366        if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
 367                uinfo->value.enumerated.item =
 368                        uinfo->value.enumerated.items - 1;
 369        strcpy(uinfo->value.enumerated.name,
 370               texts[uinfo->value.enumerated.item]);
 371        return 0;
 372}
 373
 374static int maya_rec_src_get(struct snd_kcontrol *kcontrol,
 375                            struct snd_ctl_elem_value *ucontrol)
 376{
 377        struct snd_maya44 *chip = snd_kcontrol_chip(kcontrol);
 378        int sel;
 379
 380        if (snd_ice1712_gpio_read(chip->ice) & (1 << GPIO_MIC_RELAY))
 381                sel = 1;
 382        else
 383                sel = 0;
 384        ucontrol->value.enumerated.item[0] = sel;
 385        return 0;
 386}
 387
 388static int maya_rec_src_put(struct snd_kcontrol *kcontrol,
 389                            struct snd_ctl_elem_value *ucontrol)
 390{
 391        struct snd_maya44 *chip = snd_kcontrol_chip(kcontrol);
 392        int sel = ucontrol->value.enumerated.item[0];
 393        int changed;
 394
 395        mutex_lock(&chip->mutex);
 396        changed = maya_set_gpio_bits(chip->ice, 1 << GPIO_MIC_RELAY,
 397                                     sel ? (1 << GPIO_MIC_RELAY) : 0);
 398        wm8776_select_input(chip, 0, sel ? MAYA_MIC_IN : MAYA_LINE_IN);
 399        mutex_unlock(&chip->mutex);
 400        return changed;
 401}
 402
 403/*
 404 * Maya44 routing switch settings have different meanings than the standard
 405 * ice1724 switches as defined in snd_vt1724_pro_route_info (ice1724.c).
 406 */
 407static int maya_pb_route_info(struct snd_kcontrol *kcontrol,
 408                              struct snd_ctl_elem_info *uinfo)
 409{
 410        static char *texts[] = {
 411                "PCM Out", /* 0 */
 412                "Input 1", "Input 2", "Input 3", "Input 4"
 413        };
 414
 415        uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
 416        uinfo->count = 1;
 417        uinfo->value.enumerated.items = ARRAY_SIZE(texts);
 418        if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
 419                uinfo->value.enumerated.item =
 420                        uinfo->value.enumerated.items - 1;
 421        strcpy(uinfo->value.enumerated.name,
 422               texts[uinfo->value.enumerated.item]);
 423        return 0;
 424}
 425
 426static int maya_pb_route_shift(int idx)
 427{
 428        static const unsigned char shift[10] =
 429                { 8, 20, 0, 3, 11, 23, 14, 26, 17, 29 };
 430        return shift[idx % 10];
 431}
 432
 433static int maya_pb_route_get(struct snd_kcontrol *kcontrol,
 434                             struct snd_ctl_elem_value *ucontrol)
 435{
 436        struct snd_maya44 *chip = snd_kcontrol_chip(kcontrol);
 437        int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
 438        ucontrol->value.enumerated.item[0] =
 439                snd_ice1724_get_route_val(chip->ice, maya_pb_route_shift(idx));
 440        return 0;
 441}
 442
 443static int maya_pb_route_put(struct snd_kcontrol *kcontrol,
 444                             struct snd_ctl_elem_value *ucontrol)
 445{
 446        struct snd_maya44 *chip = snd_kcontrol_chip(kcontrol);
 447        int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
 448        return snd_ice1724_put_route_val(chip->ice,
 449                                         ucontrol->value.enumerated.item[0],
 450                                         maya_pb_route_shift(idx));
 451}
 452
 453
 454/*
 455 * controls to be added
 456 */
 457
 458static struct snd_kcontrol_new maya_controls[] __devinitdata = {
 459        {
 460                .name = "Crossmix Playback Volume",
 461                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 462                .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
 463                        SNDRV_CTL_ELEM_ACCESS_TLV_READ,
 464                .info = maya_vol_info,
 465                .get = maya_vol_get,
 466                .put = maya_vol_put,
 467                .tlv = { .p = db_scale_hp },
 468                .private_value = WM_VOL_HP,
 469                .count = 2,
 470        },
 471        {
 472                .name = "PCM Playback Volume",
 473                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 474                .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
 475                        SNDRV_CTL_ELEM_ACCESS_TLV_READ,
 476                .info = maya_vol_info,
 477                .get = maya_vol_get,
 478                .put = maya_vol_put,
 479                .tlv = { .p = db_scale_dac },
 480                .private_value = WM_VOL_DAC,
 481                .count = 2,
 482        },
 483        {
 484                .name = "Line Capture Volume",
 485                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 486                .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
 487                        SNDRV_CTL_ELEM_ACCESS_TLV_READ,
 488                .info = maya_vol_info,
 489                .get = maya_vol_get,
 490                .put = maya_vol_put,
 491                .tlv = { .p = db_scale_adc },
 492                .private_value = WM_VOL_ADC,
 493                .count = 2,
 494        },
 495        {
 496                .name = "PCM Playback Switch",
 497                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 498                .info = maya_sw_info,
 499                .get = maya_sw_get,
 500                .put = maya_sw_put,
 501                .private_value = COMPOSE_SW_VAL(WM_SW_DAC,
 502                                                WM8776_REG_OUTPUT_MUX, 0x01),
 503                .count = 2,
 504        },
 505        {
 506                .name = "Bypass Playback Switch",
 507                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 508                .info = maya_sw_info,
 509                .get = maya_sw_get,
 510                .put = maya_sw_put,
 511                .private_value = COMPOSE_SW_VAL(WM_SW_BYPASS,
 512                                                WM8776_REG_OUTPUT_MUX, 0x04),
 513                .count = 2,
 514        },
 515        {
 516                .name = "Capture Source",
 517                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 518                .info = maya_rec_src_info,
 519                .get = maya_rec_src_get,
 520                .put = maya_rec_src_put,
 521        },
 522        {
 523                .name = "Mic Phantom Power Switch",
 524                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 525                .info = maya_gpio_sw_info,
 526                .get = maya_gpio_sw_get,
 527                .put = maya_gpio_sw_put,
 528                .private_value = COMPOSE_GPIO_VAL(GPIO_PHANTOM_OFF, 1),
 529        },
 530        {
 531                .name = "SPDIF Capture Switch",
 532                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 533                .info = maya_gpio_sw_info,
 534                .get = maya_gpio_sw_get,
 535                .put = maya_gpio_sw_put,
 536                .private_value = COMPOSE_GPIO_VAL(GPIO_SPDIF_IN_INV, 1),
 537        },
 538        {
 539                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 540                .name = "H/W Playback Route",
 541                .info = maya_pb_route_info,
 542                .get = maya_pb_route_get,
 543                .put = maya_pb_route_put,
 544                .count = 4,  /* FIXME: do controls 5-9 have any meaning? */
 545        },
 546};
 547
 548static int __devinit maya44_add_controls(struct snd_ice1712 *ice)
 549{
 550        int err, i;
 551
 552        for (i = 0; i < ARRAY_SIZE(maya_controls); i++) {
 553                err = snd_ctl_add(ice->card, snd_ctl_new1(&maya_controls[i],
 554                                                          ice->spec));
 555                if (err < 0)
 556                        return err;
 557        }
 558        return 0;
 559}
 560
 561
 562/*
 563 * initialize a wm8776 chip
 564 */
 565static void __devinit wm8776_init(struct snd_ice1712 *ice,
 566                                  struct snd_wm8776 *wm, unsigned int addr)
 567{
 568        static const unsigned short inits_wm8776[] = {
 569                0x02, 0x100, /* R2: headphone L+R muted + update */
 570                0x05, 0x100, /* R5: DAC output L+R muted + update */
 571                0x06, 0x000, /* R6: DAC output phase normal */
 572                0x07, 0x091, /* R7: DAC enable zero cross detection,
 573                                normal output */
 574                0x08, 0x000, /* R8: DAC soft mute off */
 575                0x09, 0x000, /* R9: no deemph, DAC zero detect disabled */
 576                0x0a, 0x022, /* R10: DAC I2C mode, std polarities, 24bit */
 577                0x0b, 0x022, /* R11: ADC I2C mode, std polarities, 24bit,
 578                                highpass filter enabled */
 579                0x0c, 0x042, /* R12: ADC+DAC slave, ADC+DAC 44,1kHz */
 580                0x0d, 0x000, /* R13: all power up */
 581                0x0e, 0x100, /* R14: ADC left muted,
 582                                enable zero cross detection */
 583                0x0f, 0x100, /* R15: ADC right muted,
 584                                enable zero cross detection */
 585                             /* R16: ALC...*/
 586                0x11, 0x000, /* R17: disable ALC */
 587                             /* R18: ALC...*/
 588                             /* R19: noise gate...*/
 589                0x15, 0x000, /* R21: ADC input mux init, mute all inputs */
 590                0x16, 0x001, /* R22: output mux, select DAC */
 591                0xff, 0xff
 592        };
 593
 594        const unsigned short *ptr;
 595        unsigned char reg;
 596        unsigned short data;
 597
 598        wm->addr = addr;
 599        /* enable DAC output; mute bypass, aux & all inputs */
 600        wm->switch_bits = (1 << WM_SW_DAC);
 601
 602        ptr = inits_wm8776;
 603        while (*ptr != 0xff) {
 604                reg = *ptr++;
 605                data = *ptr++;
 606                wm8776_write(ice, wm, reg, data);
 607        }
 608}
 609
 610
 611/*
 612 * change the rate on the WM8776 codecs.
 613 * this assumes that the VT17xx's rate is changed by the calling function.
 614 * NOTE: even though the WM8776's are running in slave mode and rate
 615 * selection is automatic, we need to call snd_wm8776_set_rate() here
 616 * to make sure some flags are set correctly.
 617 */
 618static void set_rate(struct snd_ice1712 *ice, unsigned int rate)
 619{
 620        struct snd_maya44 *chip = ice->spec;
 621        unsigned int ratio, adc_ratio, val;
 622        int i;
 623
 624        switch (rate) {
 625        case 192000:
 626                ratio = WM8776_CLOCK_RATIO_128FS;
 627                break;
 628        case 176400:
 629                ratio = WM8776_CLOCK_RATIO_128FS;
 630                break;
 631        case 96000:
 632                ratio = WM8776_CLOCK_RATIO_256FS;
 633                break;
 634        case 88200:
 635                ratio = WM8776_CLOCK_RATIO_384FS;
 636                break;
 637        case 48000:
 638                ratio = WM8776_CLOCK_RATIO_512FS;
 639                break;
 640        case 44100:
 641                ratio = WM8776_CLOCK_RATIO_512FS;
 642                break;
 643        case 32000:
 644                ratio = WM8776_CLOCK_RATIO_768FS;
 645                break;
 646        case 0:
 647                /* no hint - S/PDIF input is master, simply return */
 648                return;
 649        default:
 650                snd_BUG();
 651                return;
 652        }
 653
 654        /*
 655         * this currently sets the same rate for ADC and DAC, but limits
 656         * ADC rate to 256X (96kHz). For 256X mode (96kHz), this sets ADC
 657         * oversampling to 64x, as recommended by WM8776 datasheet.
 658         * Setting the rate is not really necessary in slave mode.
 659         */
 660        adc_ratio = ratio;
 661        if (adc_ratio < WM8776_CLOCK_RATIO_256FS)
 662                adc_ratio = WM8776_CLOCK_RATIO_256FS;
 663
 664        val = adc_ratio;
 665        if (adc_ratio == WM8776_CLOCK_RATIO_256FS)
 666                val |= 8;
 667        val |= ratio << 4;
 668
 669        mutex_lock(&chip->mutex);
 670        for (i = 0; i < 2; i++)
 671                wm8776_write_bits(ice, &chip->wm[i],
 672                                  WM8776_REG_MASTER_MODE_CONTROL,
 673                                  0x180, val);
 674        mutex_unlock(&chip->mutex);
 675}
 676
 677/*
 678 * supported sample rates (to override the default one)
 679 */
 680
 681static unsigned int rates[] = {
 682        32000, 44100, 48000, 64000, 88200, 96000, 176400, 192000
 683};
 684
 685/* playback rates: 32..192 kHz */
 686static struct snd_pcm_hw_constraint_list dac_rates = {
 687        .count = ARRAY_SIZE(rates),
 688        .list = rates,
 689        .mask = 0
 690};
 691
 692
 693/*
 694 * chip addresses on I2C bus
 695 */
 696static unsigned char wm8776_addr[2] __devinitdata = {
 697        0x34, 0x36, /* codec 0 & 1 */
 698};
 699
 700/*
 701 * initialize the chip
 702 */
 703static int __devinit maya44_init(struct snd_ice1712 *ice)
 704{
 705        int i;
 706        struct snd_maya44 *chip;
 707
 708        chip = kzalloc(sizeof(*chip), GFP_KERNEL);
 709        if (!chip)
 710                return -ENOMEM;
 711        mutex_init(&chip->mutex);
 712        chip->ice = ice;
 713        ice->spec = chip;
 714
 715        /* initialise codecs */
 716        ice->num_total_dacs = 4;
 717        ice->num_total_adcs = 4;
 718        ice->akm_codecs = 0;
 719
 720        for (i = 0; i < 2; i++) {
 721                wm8776_init(ice, &chip->wm[i], wm8776_addr[i]);
 722                wm8776_select_input(chip, i, MAYA_LINE_IN);
 723        }
 724
 725        /* set card specific rates */
 726        ice->hw_rates = &dac_rates;
 727
 728        /* register change rate notifier */
 729        ice->gpio.set_pro_rate = set_rate;
 730
 731        /* RDMA1 (2nd input channel) is used for ADC by default */
 732        ice->force_rdma1 = 1;
 733
 734        /* have an own routing control */
 735        ice->own_routing = 1;
 736
 737        return 0;
 738}
 739
 740
 741/*
 742 * Maya44 boards don't provide the EEPROM data except for the vendor IDs.
 743 * hence the driver needs to sets up it properly.
 744 */
 745
 746static unsigned char maya44_eeprom[] __devinitdata = {
 747        [ICE_EEP2_SYSCONF]     = 0x45,
 748                /* clock xin1=49.152MHz, mpu401, 2 stereo ADCs+DACs */
 749        [ICE_EEP2_ACLINK]      = 0x80,
 750                /* I2S */
 751        [ICE_EEP2_I2S]         = 0xf8,
 752                /* vol, 96k, 24bit, 192k */
 753        [ICE_EEP2_SPDIF]       = 0xc3,
 754                /* enable spdif out, spdif out supp, spdif-in, ext spdif out */
 755        [ICE_EEP2_GPIO_DIR]    = 0xff,
 756        [ICE_EEP2_GPIO_DIR1]   = 0xff,
 757        [ICE_EEP2_GPIO_DIR2]   = 0xff,
 758        [ICE_EEP2_GPIO_MASK]   = 0/*0x9f*/,
 759        [ICE_EEP2_GPIO_MASK1]  = 0/*0xff*/,
 760        [ICE_EEP2_GPIO_MASK2]  = 0/*0x7f*/,
 761        [ICE_EEP2_GPIO_STATE]  = (1 << GPIO_PHANTOM_OFF) |
 762                        (1 << GPIO_SPDIF_IN_INV),
 763        [ICE_EEP2_GPIO_STATE1] = 0x00,
 764        [ICE_EEP2_GPIO_STATE2] = 0x00,
 765};
 766
 767/* entry point */
 768struct snd_ice1712_card_info snd_vt1724_maya44_cards[] __devinitdata = {
 769        {
 770                .subvendor = VT1724_SUBDEVICE_MAYA44,
 771                .name = "ESI Maya44",
 772                .model = "maya44",
 773                .chip_init = maya44_init,
 774                .build_controls = maya44_add_controls,
 775                .eeprom_size = sizeof(maya44_eeprom),
 776                .eeprom_data = maya44_eeprom,
 777        },
 778        { } /* terminator */
 779};
 780