linux/sound/pci/ca0106/ca0106_mixer.c
<<
>>
Prefs
   1/*
   2 *  Copyright (c) 2004 James Courtier-Dutton <James@superbug.demon.co.uk>
   3 *  Driver CA0106 chips. e.g. Sound Blaster Audigy LS and Live 24bit
   4 *  Version: 0.0.18
   5 *
   6 *  FEATURES currently supported:
   7 *    See ca0106_main.c for features.
   8 * 
   9 *  Changelog:
  10 *    Support interrupts per period.
  11 *    Removed noise from Center/LFE channel when in Analog mode.
  12 *    Rename and remove mixer controls.
  13 *  0.0.6
  14 *    Use separate card based DMA buffer for periods table list.
  15 *  0.0.7
  16 *    Change remove and rename ctrls into lists.
  17 *  0.0.8
  18 *    Try to fix capture sources.
  19 *  0.0.9
  20 *    Fix AC3 output.
  21 *    Enable S32_LE format support.
  22 *  0.0.10
  23 *    Enable playback 48000 and 96000 rates. (Rates other that these do not work, even with "plug:front".)
  24 *  0.0.11
  25 *    Add Model name recognition.
  26 *  0.0.12
  27 *    Correct interrupt timing. interrupt at end of period, instead of in the middle of a playback period.
  28 *    Remove redundent "voice" handling.
  29 *  0.0.13
  30 *    Single trigger call for multi channels.
  31 *  0.0.14
  32 *    Set limits based on what the sound card hardware can do.
  33 *    playback periods_min=2, periods_max=8
  34 *    capture hw constraints require period_size = n * 64 bytes.
  35 *    playback hw constraints require period_size = n * 64 bytes.
  36 *  0.0.15
  37 *    Separated ca0106.c into separate functional .c files.
  38 *  0.0.16
  39 *    Modified Copyright message.
  40 *  0.0.17
  41 *    Implement Mic and Line in Capture.
  42 *  0.0.18
  43 *    Add support for mute control on SB Live 24bit (cards w/ SPI DAC)
  44 *
  45 *  This code was initially based on code from ALSA's emu10k1x.c which is:
  46 *  Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com>
  47 *
  48 *   This program is free software; you can redistribute it and/or modify
  49 *   it under the terms of the GNU General Public License as published by
  50 *   the Free Software Foundation; either version 2 of the License, or
  51 *   (at your option) any later version.
  52 *
  53 *   This program is distributed in the hope that it will be useful,
  54 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  55 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  56 *   GNU General Public License for more details.
  57 *
  58 *   You should have received a copy of the GNU General Public License
  59 *   along with this program; if not, write to the Free Software
  60 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  61 *
  62 */
  63#include <linux/delay.h>
  64#include <linux/init.h>
  65#include <linux/interrupt.h>
  66#include <linux/moduleparam.h>
  67#include <sound/core.h>
  68#include <sound/initval.h>
  69#include <sound/pcm.h>
  70#include <sound/ac97_codec.h>
  71#include <sound/info.h>
  72#include <sound/tlv.h>
  73#include <asm/io.h>
  74
  75#include "ca0106.h"
  76
  77static void ca0106_spdif_enable(struct snd_ca0106 *emu)
  78{
  79        unsigned int val;
  80
  81        if (emu->spdif_enable) {
  82                /* Digital */
  83                snd_ca0106_ptr_write(emu, SPDIF_SELECT1, 0, 0xf);
  84                snd_ca0106_ptr_write(emu, SPDIF_SELECT2, 0, 0x0b000000);
  85                val = snd_ca0106_ptr_read(emu, CAPTURE_CONTROL, 0) & ~0x1000;
  86                snd_ca0106_ptr_write(emu, CAPTURE_CONTROL, 0, val);
  87                val = inl(emu->port + GPIO) & ~0x101;
  88                outl(val, emu->port + GPIO);
  89
  90        } else {
  91                /* Analog */
  92                snd_ca0106_ptr_write(emu, SPDIF_SELECT1, 0, 0xf);
  93                snd_ca0106_ptr_write(emu, SPDIF_SELECT2, 0, 0x000f0000);
  94                val = snd_ca0106_ptr_read(emu, CAPTURE_CONTROL, 0) | 0x1000;
  95                snd_ca0106_ptr_write(emu, CAPTURE_CONTROL, 0, val);
  96                val = inl(emu->port + GPIO) | 0x101;
  97                outl(val, emu->port + GPIO);
  98        }
  99}
 100
 101static void ca0106_set_capture_source(struct snd_ca0106 *emu)
 102{
 103        unsigned int val = emu->capture_source;
 104        unsigned int source, mask;
 105        source = (val << 28) | (val << 24) | (val << 20) | (val << 16);
 106        mask = snd_ca0106_ptr_read(emu, CAPTURE_SOURCE, 0) & 0xffff;
 107        snd_ca0106_ptr_write(emu, CAPTURE_SOURCE, 0, source | mask);
 108}
 109
 110static void ca0106_set_i2c_capture_source(struct snd_ca0106 *emu,
 111                                          unsigned int val, int force)
 112{
 113        unsigned int ngain, ogain;
 114        u32 source;
 115
 116        snd_ca0106_i2c_write(emu, ADC_MUX, 0); /* Mute input */
 117        ngain = emu->i2c_capture_volume[val][0]; /* Left */
 118        ogain = emu->i2c_capture_volume[emu->i2c_capture_source][0]; /* Left */
 119        if (force || ngain != ogain)
 120                snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCL, ngain & 0xff);
 121        ngain = emu->i2c_capture_volume[val][1]; /* Right */
 122        ogain = emu->i2c_capture_volume[emu->i2c_capture_source][1]; /* Right */
 123        if (force || ngain != ogain)
 124                snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCR, ngain & 0xff);
 125        source = 1 << val;
 126        snd_ca0106_i2c_write(emu, ADC_MUX, source); /* Set source */
 127        emu->i2c_capture_source = val;
 128}
 129
 130static void ca0106_set_capture_mic_line_in(struct snd_ca0106 *emu)
 131{
 132        u32 tmp;
 133
 134        if (emu->capture_mic_line_in) {
 135                /* snd_ca0106_i2c_write(emu, ADC_MUX, 0); */ /* Mute input */
 136                tmp = inl(emu->port+GPIO) & ~0x400;
 137                tmp = tmp | 0x400;
 138                outl(tmp, emu->port+GPIO);
 139                /* snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_MIC); */
 140        } else {
 141                /* snd_ca0106_i2c_write(emu, ADC_MUX, 0); */ /* Mute input */
 142                tmp = inl(emu->port+GPIO) & ~0x400;
 143                outl(tmp, emu->port+GPIO);
 144                /* snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_LINEIN); */
 145        }
 146}
 147
 148static void ca0106_set_spdif_bits(struct snd_ca0106 *emu, int idx)
 149{
 150        snd_ca0106_ptr_write(emu, SPCS0 + idx, 0, emu->spdif_str_bits[idx]);
 151}
 152
 153/*
 154 */
 155static const DECLARE_TLV_DB_SCALE(snd_ca0106_db_scale1, -5175, 25, 1);
 156static const DECLARE_TLV_DB_SCALE(snd_ca0106_db_scale2, -10350, 50, 1);
 157
 158#define snd_ca0106_shared_spdif_info    snd_ctl_boolean_mono_info
 159
 160static int snd_ca0106_shared_spdif_get(struct snd_kcontrol *kcontrol,
 161                                        struct snd_ctl_elem_value *ucontrol)
 162{
 163        struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
 164
 165        ucontrol->value.integer.value[0] = emu->spdif_enable;
 166        return 0;
 167}
 168
 169static int snd_ca0106_shared_spdif_put(struct snd_kcontrol *kcontrol,
 170                                        struct snd_ctl_elem_value *ucontrol)
 171{
 172        struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
 173        unsigned int val;
 174        int change = 0;
 175
 176        val = !!ucontrol->value.integer.value[0];
 177        change = (emu->spdif_enable != val);
 178        if (change) {
 179                emu->spdif_enable = val;
 180                ca0106_spdif_enable(emu);
 181        }
 182        return change;
 183}
 184
 185static int snd_ca0106_capture_source_info(struct snd_kcontrol *kcontrol,
 186                                          struct snd_ctl_elem_info *uinfo)
 187{
 188        static char *texts[6] = {
 189                "IEC958 out", "i2s mixer out", "IEC958 in", "i2s in", "AC97 in", "SRC out"
 190        };
 191
 192        uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
 193        uinfo->count = 1;
 194        uinfo->value.enumerated.items = 6;
 195        if (uinfo->value.enumerated.item > 5)
 196                uinfo->value.enumerated.item = 5;
 197        strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
 198        return 0;
 199}
 200
 201static int snd_ca0106_capture_source_get(struct snd_kcontrol *kcontrol,
 202                                        struct snd_ctl_elem_value *ucontrol)
 203{
 204        struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
 205
 206        ucontrol->value.enumerated.item[0] = emu->capture_source;
 207        return 0;
 208}
 209
 210static int snd_ca0106_capture_source_put(struct snd_kcontrol *kcontrol,
 211                                        struct snd_ctl_elem_value *ucontrol)
 212{
 213        struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
 214        unsigned int val;
 215        int change = 0;
 216
 217        val = ucontrol->value.enumerated.item[0] ;
 218        if (val >= 6)
 219                return -EINVAL;
 220        change = (emu->capture_source != val);
 221        if (change) {
 222                emu->capture_source = val;
 223                ca0106_set_capture_source(emu);
 224        }
 225        return change;
 226}
 227
 228static int snd_ca0106_i2c_capture_source_info(struct snd_kcontrol *kcontrol,
 229                                          struct snd_ctl_elem_info *uinfo)
 230{
 231        static char *texts[6] = {
 232                "Phone", "Mic", "Line in", "Aux"
 233        };
 234
 235        uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
 236        uinfo->count = 1;
 237        uinfo->value.enumerated.items = 4;
 238        if (uinfo->value.enumerated.item > 3)
 239                uinfo->value.enumerated.item = 3;
 240        strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
 241        return 0;
 242}
 243
 244static int snd_ca0106_i2c_capture_source_get(struct snd_kcontrol *kcontrol,
 245                                        struct snd_ctl_elem_value *ucontrol)
 246{
 247        struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
 248
 249        ucontrol->value.enumerated.item[0] = emu->i2c_capture_source;
 250        return 0;
 251}
 252
 253static int snd_ca0106_i2c_capture_source_put(struct snd_kcontrol *kcontrol,
 254                                        struct snd_ctl_elem_value *ucontrol)
 255{
 256        struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
 257        unsigned int source_id;
 258        int change = 0;
 259        /* If the capture source has changed,
 260         * update the capture volume from the cached value
 261         * for the particular source.
 262         */
 263        source_id = ucontrol->value.enumerated.item[0] ;
 264        if (source_id >= 4)
 265                return -EINVAL;
 266        change = (emu->i2c_capture_source != source_id);
 267        if (change) {
 268                ca0106_set_i2c_capture_source(emu, source_id, 0);
 269        }
 270        return change;
 271}
 272
 273static int snd_ca0106_capture_line_in_side_out_info(struct snd_kcontrol *kcontrol,
 274                                               struct snd_ctl_elem_info *uinfo)
 275{
 276        static char *texts[2] = { "Side out", "Line in" };
 277
 278        uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
 279        uinfo->count = 1;
 280        uinfo->value.enumerated.items = 2;
 281        if (uinfo->value.enumerated.item > 1)
 282                uinfo->value.enumerated.item = 1;
 283        strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
 284        return 0;
 285}
 286
 287static int snd_ca0106_capture_mic_line_in_info(struct snd_kcontrol *kcontrol,
 288                                               struct snd_ctl_elem_info *uinfo)
 289{
 290        static char *texts[2] = { "Line in", "Mic in" };
 291
 292        uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
 293        uinfo->count = 1;
 294        uinfo->value.enumerated.items = 2;
 295        if (uinfo->value.enumerated.item > 1)
 296                uinfo->value.enumerated.item = 1;
 297        strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
 298        return 0;
 299}
 300
 301static int snd_ca0106_capture_mic_line_in_get(struct snd_kcontrol *kcontrol,
 302                                        struct snd_ctl_elem_value *ucontrol)
 303{
 304        struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
 305
 306        ucontrol->value.enumerated.item[0] = emu->capture_mic_line_in;
 307        return 0;
 308}
 309
 310static int snd_ca0106_capture_mic_line_in_put(struct snd_kcontrol *kcontrol,
 311                                        struct snd_ctl_elem_value *ucontrol)
 312{
 313        struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
 314        unsigned int val;
 315        int change = 0;
 316
 317        val = ucontrol->value.enumerated.item[0] ;
 318        if (val > 1)
 319                return -EINVAL;
 320        change = (emu->capture_mic_line_in != val);
 321        if (change) {
 322                emu->capture_mic_line_in = val;
 323                ca0106_set_capture_mic_line_in(emu);
 324        }
 325        return change;
 326}
 327
 328static struct snd_kcontrol_new snd_ca0106_capture_mic_line_in =
 329{
 330        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
 331        .name =         "Shared Mic/Line in Capture Switch",
 332        .info =         snd_ca0106_capture_mic_line_in_info,
 333        .get =          snd_ca0106_capture_mic_line_in_get,
 334        .put =          snd_ca0106_capture_mic_line_in_put
 335};
 336
 337static struct snd_kcontrol_new snd_ca0106_capture_line_in_side_out =
 338{
 339        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
 340        .name =         "Shared Line in/Side out Capture Switch",
 341        .info =         snd_ca0106_capture_line_in_side_out_info,
 342        .get =          snd_ca0106_capture_mic_line_in_get,
 343        .put =          snd_ca0106_capture_mic_line_in_put
 344};
 345
 346
 347static int snd_ca0106_spdif_info(struct snd_kcontrol *kcontrol,
 348                                 struct snd_ctl_elem_info *uinfo)
 349{
 350        uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
 351        uinfo->count = 1;
 352        return 0;
 353}
 354
 355static void decode_spdif_bits(unsigned char *status, unsigned int bits)
 356{
 357        status[0] = (bits >> 0) & 0xff;
 358        status[1] = (bits >> 8) & 0xff;
 359        status[2] = (bits >> 16) & 0xff;
 360        status[3] = (bits >> 24) & 0xff;
 361}
 362
 363static int snd_ca0106_spdif_get_default(struct snd_kcontrol *kcontrol,
 364                                 struct snd_ctl_elem_value *ucontrol)
 365{
 366        struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
 367        unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
 368
 369        decode_spdif_bits(ucontrol->value.iec958.status,
 370                          emu->spdif_bits[idx]);
 371        return 0;
 372}
 373
 374static int snd_ca0106_spdif_get_stream(struct snd_kcontrol *kcontrol,
 375                                 struct snd_ctl_elem_value *ucontrol)
 376{
 377        struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
 378        unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
 379
 380        decode_spdif_bits(ucontrol->value.iec958.status,
 381                          emu->spdif_str_bits[idx]);
 382        return 0;
 383}
 384
 385static int snd_ca0106_spdif_get_mask(struct snd_kcontrol *kcontrol,
 386                                      struct snd_ctl_elem_value *ucontrol)
 387{
 388        ucontrol->value.iec958.status[0] = 0xff;
 389        ucontrol->value.iec958.status[1] = 0xff;
 390        ucontrol->value.iec958.status[2] = 0xff;
 391        ucontrol->value.iec958.status[3] = 0xff;
 392        return 0;
 393}
 394
 395static unsigned int encode_spdif_bits(unsigned char *status)
 396{
 397        return ((unsigned int)status[0] << 0) |
 398                ((unsigned int)status[1] << 8) |
 399                ((unsigned int)status[2] << 16) |
 400                ((unsigned int)status[3] << 24);
 401}
 402
 403static int snd_ca0106_spdif_put_default(struct snd_kcontrol *kcontrol,
 404                                 struct snd_ctl_elem_value *ucontrol)
 405{
 406        struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
 407        unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
 408        unsigned int val;
 409
 410        val = encode_spdif_bits(ucontrol->value.iec958.status);
 411        if (val != emu->spdif_bits[idx]) {
 412                emu->spdif_bits[idx] = val;
 413                /* FIXME: this isn't safe, but needed to keep the compatibility
 414                 * with older alsa-lib config
 415                 */
 416                emu->spdif_str_bits[idx] = val;
 417                ca0106_set_spdif_bits(emu, idx);
 418                return 1;
 419        }
 420        return 0;
 421}
 422
 423static int snd_ca0106_spdif_put_stream(struct snd_kcontrol *kcontrol,
 424                                 struct snd_ctl_elem_value *ucontrol)
 425{
 426        struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
 427        unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
 428        unsigned int val;
 429
 430        val = encode_spdif_bits(ucontrol->value.iec958.status);
 431        if (val != emu->spdif_str_bits[idx]) {
 432                emu->spdif_str_bits[idx] = val;
 433                ca0106_set_spdif_bits(emu, idx);
 434                return 1;
 435        }
 436        return 0;
 437}
 438
 439static int snd_ca0106_volume_info(struct snd_kcontrol *kcontrol,
 440                                  struct snd_ctl_elem_info *uinfo)
 441{
 442        uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 443        uinfo->count = 2;
 444        uinfo->value.integer.min = 0;
 445        uinfo->value.integer.max = 255;
 446        return 0;
 447}
 448
 449static int snd_ca0106_volume_get(struct snd_kcontrol *kcontrol,
 450                                 struct snd_ctl_elem_value *ucontrol)
 451{
 452        struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
 453        unsigned int value;
 454        int channel_id, reg;
 455
 456        channel_id = (kcontrol->private_value >> 8) & 0xff;
 457        reg = kcontrol->private_value & 0xff;
 458
 459        value = snd_ca0106_ptr_read(emu, reg, channel_id);
 460        ucontrol->value.integer.value[0] = 0xff - ((value >> 24) & 0xff); /* Left */
 461        ucontrol->value.integer.value[1] = 0xff - ((value >> 16) & 0xff); /* Right */
 462        return 0;
 463}
 464
 465static int snd_ca0106_volume_put(struct snd_kcontrol *kcontrol,
 466                                 struct snd_ctl_elem_value *ucontrol)
 467{
 468        struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
 469        unsigned int oval, nval;
 470        int channel_id, reg;
 471
 472        channel_id = (kcontrol->private_value >> 8) & 0xff;
 473        reg = kcontrol->private_value & 0xff;
 474
 475        oval = snd_ca0106_ptr_read(emu, reg, channel_id);
 476        nval = ((0xff - ucontrol->value.integer.value[0]) << 24) |
 477                ((0xff - ucontrol->value.integer.value[1]) << 16);
 478        nval |= ((0xff - ucontrol->value.integer.value[0]) << 8) |
 479                ((0xff - ucontrol->value.integer.value[1]) );
 480        if (oval == nval)
 481                return 0;
 482        snd_ca0106_ptr_write(emu, reg, channel_id, nval);
 483        return 1;
 484}
 485
 486static int snd_ca0106_i2c_volume_info(struct snd_kcontrol *kcontrol,
 487                                  struct snd_ctl_elem_info *uinfo)
 488{
 489        uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 490        uinfo->count = 2;
 491        uinfo->value.integer.min = 0;
 492        uinfo->value.integer.max = 255;
 493        return 0;
 494}
 495
 496static int snd_ca0106_i2c_volume_get(struct snd_kcontrol *kcontrol,
 497                                 struct snd_ctl_elem_value *ucontrol)
 498{
 499        struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
 500        int source_id;
 501
 502        source_id = kcontrol->private_value;
 503
 504        ucontrol->value.integer.value[0] = emu->i2c_capture_volume[source_id][0];
 505        ucontrol->value.integer.value[1] = emu->i2c_capture_volume[source_id][1];
 506        return 0;
 507}
 508
 509static int snd_ca0106_i2c_volume_put(struct snd_kcontrol *kcontrol,
 510                                 struct snd_ctl_elem_value *ucontrol)
 511{
 512        struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
 513        unsigned int ogain;
 514        unsigned int ngain;
 515        int source_id;
 516        int change = 0;
 517
 518        source_id = kcontrol->private_value;
 519        ogain = emu->i2c_capture_volume[source_id][0]; /* Left */
 520        ngain = ucontrol->value.integer.value[0];
 521        if (ngain > 0xff)
 522                return -EINVAL;
 523        if (ogain != ngain) {
 524                if (emu->i2c_capture_source == source_id)
 525                        snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCL, ((ngain) & 0xff) );
 526                emu->i2c_capture_volume[source_id][0] = ucontrol->value.integer.value[0];
 527                change = 1;
 528        }
 529        ogain = emu->i2c_capture_volume[source_id][1]; /* Right */
 530        ngain = ucontrol->value.integer.value[1];
 531        if (ngain > 0xff)
 532                return -EINVAL;
 533        if (ogain != ngain) {
 534                if (emu->i2c_capture_source == source_id)
 535                        snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCR, ((ngain) & 0xff));
 536                emu->i2c_capture_volume[source_id][1] = ucontrol->value.integer.value[1];
 537                change = 1;
 538        }
 539
 540        return change;
 541}
 542
 543#define spi_mute_info   snd_ctl_boolean_mono_info
 544
 545static int spi_mute_get(struct snd_kcontrol *kcontrol,
 546                        struct snd_ctl_elem_value *ucontrol)
 547{
 548        struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
 549        unsigned int reg = kcontrol->private_value >> SPI_REG_SHIFT;
 550        unsigned int bit = kcontrol->private_value & SPI_REG_MASK;
 551
 552        ucontrol->value.integer.value[0] = !(emu->spi_dac_reg[reg] & bit);
 553        return 0;
 554}
 555
 556static int spi_mute_put(struct snd_kcontrol *kcontrol,
 557                        struct snd_ctl_elem_value *ucontrol)
 558{
 559        struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
 560        unsigned int reg = kcontrol->private_value >> SPI_REG_SHIFT;
 561        unsigned int bit = kcontrol->private_value & SPI_REG_MASK;
 562        int ret;
 563
 564        ret = emu->spi_dac_reg[reg] & bit;
 565        if (ucontrol->value.integer.value[0]) {
 566                if (!ret)       /* bit already cleared, do nothing */
 567                        return 0;
 568                emu->spi_dac_reg[reg] &= ~bit;
 569        } else {
 570                if (ret)        /* bit already set, do nothing */
 571                        return 0;
 572                emu->spi_dac_reg[reg] |= bit;
 573        }
 574
 575        ret = snd_ca0106_spi_write(emu, emu->spi_dac_reg[reg]);
 576        return ret ? -EINVAL : 1;
 577}
 578
 579#define CA_VOLUME(xname,chid,reg) \
 580{                                                               \
 581        .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,     \
 582        .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |             \
 583                  SNDRV_CTL_ELEM_ACCESS_TLV_READ,               \
 584        .info =  snd_ca0106_volume_info,                        \
 585        .get =   snd_ca0106_volume_get,                         \
 586        .put =   snd_ca0106_volume_put,                         \
 587        .tlv = { .p = snd_ca0106_db_scale1 },                   \
 588        .private_value = ((chid) << 8) | (reg)                  \
 589}
 590
 591static struct snd_kcontrol_new snd_ca0106_volume_ctls[] = {
 592        CA_VOLUME("Analog Front Playback Volume",
 593                  CONTROL_FRONT_CHANNEL, PLAYBACK_VOLUME2),
 594        CA_VOLUME("Analog Rear Playback Volume",
 595                  CONTROL_REAR_CHANNEL, PLAYBACK_VOLUME2),
 596        CA_VOLUME("Analog Center/LFE Playback Volume",
 597                  CONTROL_CENTER_LFE_CHANNEL, PLAYBACK_VOLUME2),
 598        CA_VOLUME("Analog Side Playback Volume",
 599                  CONTROL_UNKNOWN_CHANNEL, PLAYBACK_VOLUME2),
 600
 601        CA_VOLUME("IEC958 Front Playback Volume",
 602                  CONTROL_FRONT_CHANNEL, PLAYBACK_VOLUME1),
 603        CA_VOLUME("IEC958 Rear Playback Volume",
 604                  CONTROL_REAR_CHANNEL, PLAYBACK_VOLUME1),
 605        CA_VOLUME("IEC958 Center/LFE Playback Volume",
 606                  CONTROL_CENTER_LFE_CHANNEL, PLAYBACK_VOLUME1),
 607        CA_VOLUME("IEC958 Unknown Playback Volume",
 608                  CONTROL_UNKNOWN_CHANNEL, PLAYBACK_VOLUME1),
 609
 610        CA_VOLUME("CAPTURE feedback Playback Volume",
 611                  1, CAPTURE_CONTROL),
 612
 613        {
 614                .access =       SNDRV_CTL_ELEM_ACCESS_READ,
 615                .iface =        SNDRV_CTL_ELEM_IFACE_PCM,
 616                .name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
 617                .count =        4,
 618                .info =         snd_ca0106_spdif_info,
 619                .get =          snd_ca0106_spdif_get_mask
 620        },
 621        {
 622                .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
 623                .name =         "IEC958 Playback Switch",
 624                .info =         snd_ca0106_shared_spdif_info,
 625                .get =          snd_ca0106_shared_spdif_get,
 626                .put =          snd_ca0106_shared_spdif_put
 627        },
 628        {
 629                .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
 630                .name =         "Digital Source Capture Enum",
 631                .info =         snd_ca0106_capture_source_info,
 632                .get =          snd_ca0106_capture_source_get,
 633                .put =          snd_ca0106_capture_source_put
 634        },
 635        {
 636                .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
 637                .name =         "Analog Source Capture Enum",
 638                .info =         snd_ca0106_i2c_capture_source_info,
 639                .get =          snd_ca0106_i2c_capture_source_get,
 640                .put =          snd_ca0106_i2c_capture_source_put
 641        },
 642        {
 643                .iface =        SNDRV_CTL_ELEM_IFACE_PCM,
 644                .name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
 645                .count =        4,
 646                .info =         snd_ca0106_spdif_info,
 647                .get =          snd_ca0106_spdif_get_default,
 648                .put =          snd_ca0106_spdif_put_default
 649        },
 650        {
 651                .iface =        SNDRV_CTL_ELEM_IFACE_PCM,
 652                .name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM),
 653                .count =        4,
 654                .info =         snd_ca0106_spdif_info,
 655                .get =          snd_ca0106_spdif_get_stream,
 656                .put =          snd_ca0106_spdif_put_stream
 657        },
 658};
 659
 660#define I2C_VOLUME(xname,chid) \
 661{                                                               \
 662        .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,     \
 663        .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |             \
 664                  SNDRV_CTL_ELEM_ACCESS_TLV_READ,               \
 665        .info =  snd_ca0106_i2c_volume_info,                    \
 666        .get =   snd_ca0106_i2c_volume_get,                     \
 667        .put =   snd_ca0106_i2c_volume_put,                     \
 668        .tlv = { .p = snd_ca0106_db_scale2 },                   \
 669        .private_value = chid                                   \
 670}
 671
 672static struct snd_kcontrol_new snd_ca0106_volume_i2c_adc_ctls[] = {
 673        I2C_VOLUME("Phone Capture Volume", 0),
 674        I2C_VOLUME("Mic Capture Volume", 1),
 675        I2C_VOLUME("Line in Capture Volume", 2),
 676        I2C_VOLUME("Aux Capture Volume", 3),
 677};
 678
 679static const int spi_dmute_reg[] = {
 680        SPI_DMUTE0_REG,
 681        SPI_DMUTE1_REG,
 682        SPI_DMUTE2_REG,
 683        0,
 684        SPI_DMUTE4_REG,
 685};
 686static const int spi_dmute_bit[] = {
 687        SPI_DMUTE0_BIT,
 688        SPI_DMUTE1_BIT,
 689        SPI_DMUTE2_BIT,
 690        0,
 691        SPI_DMUTE4_BIT,
 692};
 693
 694static struct snd_kcontrol_new
 695snd_ca0106_volume_spi_dac_ctl(struct snd_ca0106_details *details,
 696                              int channel_id)
 697{
 698        struct snd_kcontrol_new spi_switch = {0};
 699        int reg, bit;
 700        int dac_id;
 701
 702        spi_switch.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
 703        spi_switch.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
 704        spi_switch.info = spi_mute_info;
 705        spi_switch.get = spi_mute_get;
 706        spi_switch.put = spi_mute_put;
 707
 708        switch (channel_id) {
 709        case PCM_FRONT_CHANNEL:
 710                spi_switch.name = "Analog Front Playback Switch";
 711                dac_id = (details->spi_dac & 0xf000) >> (4 * 3);
 712                break;
 713        case PCM_REAR_CHANNEL:
 714                spi_switch.name = "Analog Rear Playback Switch";
 715                dac_id = (details->spi_dac & 0x0f00) >> (4 * 2);
 716                break;
 717        case PCM_CENTER_LFE_CHANNEL:
 718                spi_switch.name = "Analog Center/LFE Playback Switch";
 719                dac_id = (details->spi_dac & 0x00f0) >> (4 * 1);
 720                break;
 721        case PCM_UNKNOWN_CHANNEL:
 722                spi_switch.name = "Analog Side Playback Switch";
 723                dac_id = (details->spi_dac & 0x000f) >> (4 * 0);
 724                break;
 725        default:
 726                /* Unused channel */
 727                spi_switch.name = NULL;
 728                dac_id = 0;
 729        }
 730        reg = spi_dmute_reg[dac_id];
 731        bit = spi_dmute_bit[dac_id];
 732
 733        spi_switch.private_value = (reg << SPI_REG_SHIFT) | bit;
 734
 735        return spi_switch;
 736}
 737
 738static int remove_ctl(struct snd_card *card, const char *name)
 739{
 740        struct snd_ctl_elem_id id;
 741        memset(&id, 0, sizeof(id));
 742        strcpy(id.name, name);
 743        id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
 744        return snd_ctl_remove_id(card, &id);
 745}
 746
 747static struct snd_kcontrol *ctl_find(struct snd_card *card, const char *name)
 748{
 749        struct snd_ctl_elem_id sid;
 750        memset(&sid, 0, sizeof(sid));
 751        /* FIXME: strcpy is bad. */
 752        strcpy(sid.name, name);
 753        sid.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
 754        return snd_ctl_find_id(card, &sid);
 755}
 756
 757static int rename_ctl(struct snd_card *card, const char *src, const char *dst)
 758{
 759        struct snd_kcontrol *kctl = ctl_find(card, src);
 760        if (kctl) {
 761                strcpy(kctl->id.name, dst);
 762                return 0;
 763        }
 764        return -ENOENT;
 765}
 766
 767#define ADD_CTLS(emu, ctls)                                             \
 768        do {                                                            \
 769                int i, _err;                                            \
 770                for (i = 0; i < ARRAY_SIZE(ctls); i++) {                \
 771                        _err = snd_ctl_add(card, snd_ctl_new1(&ctls[i], emu)); \
 772                        if (_err < 0)                                   \
 773                                return _err;                            \
 774                }                                                       \
 775        } while (0)
 776
 777static
 778DECLARE_TLV_DB_SCALE(snd_ca0106_master_db_scale, -6375, 25, 1);
 779
 780static char *slave_vols[] = {
 781        "Analog Front Playback Volume",
 782        "Analog Rear Playback Volume",
 783        "Analog Center/LFE Playback Volume",
 784        "Analog Side Playback Volume",
 785        "IEC958 Front Playback Volume",
 786        "IEC958 Rear Playback Volume",
 787        "IEC958 Center/LFE Playback Volume",
 788        "IEC958 Unknown Playback Volume",
 789        "CAPTURE feedback Playback Volume",
 790        NULL
 791};
 792
 793static char *slave_sws[] = {
 794        "Analog Front Playback Switch",
 795        "Analog Rear Playback Switch",
 796        "Analog Center/LFE Playback Switch",
 797        "Analog Side Playback Switch",
 798        "IEC958 Playback Switch",
 799        NULL
 800};
 801
 802static void add_slaves(struct snd_card *card,
 803                                 struct snd_kcontrol *master, char **list)
 804{
 805        for (; *list; list++) {
 806                struct snd_kcontrol *slave = ctl_find(card, *list);
 807                if (slave)
 808                        snd_ctl_add_slave(master, slave);
 809        }
 810}
 811
 812int snd_ca0106_mixer(struct snd_ca0106 *emu)
 813{
 814        int err;
 815        struct snd_card *card = emu->card;
 816        char **c;
 817        struct snd_kcontrol *vmaster;
 818        static char *ca0106_remove_ctls[] = {
 819                "Master Mono Playback Switch",
 820                "Master Mono Playback Volume",
 821                "3D Control - Switch",
 822                "3D Control Sigmatel - Depth",
 823                "PCM Playback Switch",
 824                "PCM Playback Volume",
 825                "CD Playback Switch",
 826                "CD Playback Volume",
 827                "Phone Playback Switch",
 828                "Phone Playback Volume",
 829                "Video Playback Switch",
 830                "Video Playback Volume",
 831                "Beep Playback Switch",
 832                "Beep Playback Volume",
 833                "Mono Output Select",
 834                "Capture Source",
 835                "Capture Switch",
 836                "Capture Volume",
 837                "External Amplifier",
 838                "Sigmatel 4-Speaker Stereo Playback Switch",
 839                "Surround Phase Inversion Playback Switch",
 840                NULL
 841        };
 842        static char *ca0106_rename_ctls[] = {
 843                "Master Playback Switch", "Capture Switch",
 844                "Master Playback Volume", "Capture Volume",
 845                "Line Playback Switch", "AC97 Line Capture Switch",
 846                "Line Playback Volume", "AC97 Line Capture Volume",
 847                "Aux Playback Switch", "AC97 Aux Capture Switch",
 848                "Aux Playback Volume", "AC97 Aux Capture Volume",
 849                "Mic Playback Switch", "AC97 Mic Capture Switch",
 850                "Mic Playback Volume", "AC97 Mic Capture Volume",
 851                "Mic Select", "AC97 Mic Select",
 852                "Mic Boost (+20dB)", "AC97 Mic Boost (+20dB)",
 853                NULL
 854        };
 855#if 1
 856        for (c = ca0106_remove_ctls; *c; c++)
 857                remove_ctl(card, *c);
 858        for (c = ca0106_rename_ctls; *c; c += 2)
 859                rename_ctl(card, c[0], c[1]);
 860#endif
 861
 862        ADD_CTLS(emu, snd_ca0106_volume_ctls);
 863        if (emu->details->i2c_adc == 1) {
 864                ADD_CTLS(emu, snd_ca0106_volume_i2c_adc_ctls);
 865                if (emu->details->gpio_type == 1)
 866                        err = snd_ctl_add(card, snd_ctl_new1(&snd_ca0106_capture_mic_line_in, emu));
 867                else  /* gpio_type == 2 */
 868                        err = snd_ctl_add(card, snd_ctl_new1(&snd_ca0106_capture_line_in_side_out, emu));
 869                if (err < 0)
 870                        return err;
 871        }
 872        if (emu->details->spi_dac) {
 873                int i;
 874                for (i = 0;; i++) {
 875                        struct snd_kcontrol_new ctl;
 876                        ctl = snd_ca0106_volume_spi_dac_ctl(emu->details, i);
 877                        if (!ctl.name)
 878                                break;
 879                        err = snd_ctl_add(card, snd_ctl_new1(&ctl, emu));
 880                        if (err < 0)
 881                                return err;
 882                }
 883        }
 884
 885        /* Create virtual master controls */
 886        vmaster = snd_ctl_make_virtual_master("Master Playback Volume",
 887                                              snd_ca0106_master_db_scale);
 888        if (!vmaster)
 889                return -ENOMEM;
 890        err = snd_ctl_add(card, vmaster);
 891        if (err < 0)
 892                return err;
 893        add_slaves(card, vmaster, slave_vols);
 894
 895        if (emu->details->spi_dac) {
 896                vmaster = snd_ctl_make_virtual_master("Master Playback Switch",
 897                                                      NULL);
 898                if (!vmaster)
 899                        return -ENOMEM;
 900                err = snd_ctl_add(card, vmaster);
 901                if (err < 0)
 902                        return err;
 903                add_slaves(card, vmaster, slave_sws);
 904        }
 905
 906        strcpy(card->mixername, "CA0106");
 907        return 0;
 908}
 909
 910#ifdef CONFIG_PM_SLEEP
 911struct ca0106_vol_tbl {
 912        unsigned int channel_id;
 913        unsigned int reg;
 914};
 915
 916static struct ca0106_vol_tbl saved_volumes[NUM_SAVED_VOLUMES] = {
 917        { CONTROL_FRONT_CHANNEL, PLAYBACK_VOLUME2 },
 918        { CONTROL_REAR_CHANNEL, PLAYBACK_VOLUME2 },
 919        { CONTROL_CENTER_LFE_CHANNEL, PLAYBACK_VOLUME2 },
 920        { CONTROL_UNKNOWN_CHANNEL, PLAYBACK_VOLUME2 },
 921        { CONTROL_FRONT_CHANNEL, PLAYBACK_VOLUME1 },
 922        { CONTROL_REAR_CHANNEL, PLAYBACK_VOLUME1 },
 923        { CONTROL_CENTER_LFE_CHANNEL, PLAYBACK_VOLUME1 },
 924        { CONTROL_UNKNOWN_CHANNEL, PLAYBACK_VOLUME1 },
 925        { 1, CAPTURE_CONTROL },
 926};
 927
 928void snd_ca0106_mixer_suspend(struct snd_ca0106 *chip)
 929{
 930        int i;
 931
 932        /* save volumes */
 933        for (i = 0; i < NUM_SAVED_VOLUMES; i++)
 934                chip->saved_vol[i] =
 935                        snd_ca0106_ptr_read(chip, saved_volumes[i].reg,
 936                                            saved_volumes[i].channel_id);
 937}
 938
 939void snd_ca0106_mixer_resume(struct snd_ca0106  *chip)
 940{
 941        int i;
 942
 943        for (i = 0; i < NUM_SAVED_VOLUMES; i++)
 944                snd_ca0106_ptr_write(chip, saved_volumes[i].reg,
 945                                     saved_volumes[i].channel_id,
 946                                     chip->saved_vol[i]);
 947
 948        ca0106_spdif_enable(chip);
 949        ca0106_set_capture_source(chip);
 950        ca0106_set_i2c_capture_source(chip, chip->i2c_capture_source, 1);
 951        for (i = 0; i < 4; i++)
 952                ca0106_set_spdif_bits(chip, i);
 953        if (chip->details->i2c_adc)
 954                ca0106_set_capture_mic_line_in(chip);
 955}
 956#endif /* CONFIG_PM_SLEEP */
 957