root/sound/pci/ca0106/ca0106_mixer.c

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

DEFINITIONS

This source file includes following definitions.
  1. ca0106_spdif_enable
  2. ca0106_set_capture_source
  3. ca0106_set_i2c_capture_source
  4. ca0106_set_capture_mic_line_in
  5. ca0106_set_spdif_bits
  6. snd_ca0106_shared_spdif_get
  7. snd_ca0106_shared_spdif_put
  8. snd_ca0106_capture_source_info
  9. snd_ca0106_capture_source_get
  10. snd_ca0106_capture_source_put
  11. snd_ca0106_i2c_capture_source_info
  12. snd_ca0106_i2c_capture_source_get
  13. snd_ca0106_i2c_capture_source_put
  14. snd_ca0106_capture_line_in_side_out_info
  15. snd_ca0106_capture_mic_line_in_info
  16. snd_ca0106_capture_mic_line_in_get
  17. snd_ca0106_capture_mic_line_in_put
  18. snd_ca0106_spdif_info
  19. decode_spdif_bits
  20. snd_ca0106_spdif_get_default
  21. snd_ca0106_spdif_get_stream
  22. snd_ca0106_spdif_get_mask
  23. encode_spdif_bits
  24. snd_ca0106_spdif_put_default
  25. snd_ca0106_spdif_put_stream
  26. snd_ca0106_volume_info
  27. snd_ca0106_volume_get
  28. snd_ca0106_volume_put
  29. snd_ca0106_i2c_volume_info
  30. snd_ca0106_i2c_volume_get
  31. snd_ca0106_i2c_volume_put
  32. spi_mute_get
  33. spi_mute_put
  34. snd_ca0106_volume_spi_dac_ctl
  35. remove_ctl
  36. ctl_find
  37. rename_ctl
  38. add_slaves
  39. snd_ca0106_mixer
  40. snd_ca0106_mixer_suspend
  41. snd_ca0106_mixer_resume

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

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