root/sound/pci/ice1712/maya44.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. wm8776_write
  2. wm8776_write_bits
  3. maya_vol_info
  4. maya_vol_get
  5. maya_vol_put
  6. maya_sw_get
  7. maya_sw_put
  8. maya_set_gpio_bits
  9. maya_gpio_sw_get
  10. maya_gpio_sw_put
  11. wm8776_select_input
  12. maya_rec_src_info
  13. maya_rec_src_get
  14. maya_rec_src_put
  15. maya_pb_route_info
  16. maya_pb_route_shift
  17. maya_pb_route_get
  18. maya_pb_route_put
  19. maya44_add_controls
  20. wm8776_init
  21. set_rate
  22. maya44_init

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

/* [<][>][^][v][top][bottom][index][help] */