root/sound/ppc/awacs.c

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

DEFINITIONS

This source file includes following definitions.
  1. snd_pmac_screamer_wait
  2. snd_pmac_awacs_write
  3. snd_pmac_awacs_write_reg
  4. snd_pmac_awacs_write_noreg
  5. screamer_recalibrate
  6. snd_pmac_awacs_set_format
  7. snd_pmac_awacs_info_volume
  8. snd_pmac_awacs_get_volume
  9. snd_pmac_awacs_put_volume
  10. snd_pmac_awacs_get_switch
  11. snd_pmac_awacs_put_switch
  12. awacs_set_cuda
  13. awacs_amp_set_tone
  14. awacs_amp_set_vol
  15. awacs_amp_set_master
  16. awacs_amp_free
  17. snd_pmac_awacs_info_volume_amp
  18. snd_pmac_awacs_get_volume_amp
  19. snd_pmac_awacs_put_volume_amp
  20. snd_pmac_awacs_get_switch_amp
  21. snd_pmac_awacs_put_switch_amp
  22. snd_pmac_awacs_info_tone_amp
  23. snd_pmac_awacs_get_tone_amp
  24. snd_pmac_awacs_put_tone_amp
  25. snd_pmac_awacs_info_master_amp
  26. snd_pmac_awacs_get_master_amp
  27. snd_pmac_awacs_put_master_amp
  28. snd_pmac_screamer_mic_boost_info
  29. snd_pmac_screamer_mic_boost_get
  30. snd_pmac_screamer_mic_boost_put
  31. build_mixers
  32. awacs_restore_all_regs
  33. snd_pmac_awacs_suspend
  34. snd_pmac_awacs_resume
  35. snd_pmac_awacs_detect_headphone
  36. toggle_amp_mute
  37. snd_pmac_awacs_update_automute
  38. snd_pmac_awacs_init

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * PMac AWACS lowlevel functions
   4  *
   5  * Copyright (c) by Takashi Iwai <tiwai@suse.de>
   6  * code based on dmasound.c.
   7  */
   8 
   9 
  10 #include <linux/io.h>
  11 #include <asm/nvram.h>
  12 #include <linux/init.h>
  13 #include <linux/delay.h>
  14 #include <linux/slab.h>
  15 #include <sound/core.h>
  16 #include "pmac.h"
  17 
  18 
  19 #ifdef CONFIG_ADB_CUDA
  20 #define PMAC_AMP_AVAIL
  21 #endif
  22 
  23 #ifdef PMAC_AMP_AVAIL
  24 struct awacs_amp {
  25         unsigned char amp_master;
  26         unsigned char amp_vol[2][2];
  27         unsigned char amp_tone[2];
  28 };
  29 
  30 #define CHECK_CUDA_AMP() (sys_ctrler == SYS_CTRLER_CUDA)
  31 
  32 #endif /* PMAC_AMP_AVAIL */
  33 
  34 
  35 static void snd_pmac_screamer_wait(struct snd_pmac *chip)
  36 {
  37         long timeout = 2000;
  38         while (!(in_le32(&chip->awacs->codec_stat) & MASK_VALID)) {
  39                 mdelay(1);
  40                 if (! --timeout) {
  41                         snd_printd("snd_pmac_screamer_wait timeout\n");
  42                         break;
  43                 }
  44         }
  45 }
  46 
  47 /*
  48  * write AWACS register
  49  */
  50 static void
  51 snd_pmac_awacs_write(struct snd_pmac *chip, int val)
  52 {
  53         long timeout = 5000000;
  54 
  55         if (chip->model == PMAC_SCREAMER)
  56                 snd_pmac_screamer_wait(chip);
  57         out_le32(&chip->awacs->codec_ctrl, val | (chip->subframe << 22));
  58         while (in_le32(&chip->awacs->codec_ctrl) & MASK_NEWECMD) {
  59                 if (! --timeout) {
  60                         snd_printd("snd_pmac_awacs_write timeout\n");
  61                         break;
  62                 }
  63         }
  64 }
  65 
  66 static void
  67 snd_pmac_awacs_write_reg(struct snd_pmac *chip, int reg, int val)
  68 {
  69         snd_pmac_awacs_write(chip, val | (reg << 12));
  70         chip->awacs_reg[reg] = val;
  71 }
  72 
  73 static void
  74 snd_pmac_awacs_write_noreg(struct snd_pmac *chip, int reg, int val)
  75 {
  76         snd_pmac_awacs_write(chip, val | (reg << 12));
  77 }
  78 
  79 #ifdef CONFIG_PM
  80 /* Recalibrate chip */
  81 static void screamer_recalibrate(struct snd_pmac *chip)
  82 {
  83         if (chip->model != PMAC_SCREAMER)
  84                 return;
  85 
  86         /* Sorry for the horrible delays... I hope to get that improved
  87          * by making the whole PM process asynchronous in a future version
  88          */
  89         snd_pmac_awacs_write_noreg(chip, 1, chip->awacs_reg[1]);
  90         if (chip->manufacturer == 0x1)
  91                 /* delay for broken crystal part */
  92                 msleep(750);
  93         snd_pmac_awacs_write_noreg(chip, 1,
  94                                    chip->awacs_reg[1] | MASK_RECALIBRATE |
  95                                    MASK_CMUTE | MASK_AMUTE);
  96         snd_pmac_awacs_write_noreg(chip, 1, chip->awacs_reg[1]);
  97         snd_pmac_awacs_write_noreg(chip, 6, chip->awacs_reg[6]);
  98 }
  99 
 100 #else
 101 #define screamer_recalibrate(chip) /* NOP */
 102 #endif
 103 
 104 
 105 /*
 106  * additional callback to set the pcm format
 107  */
 108 static void snd_pmac_awacs_set_format(struct snd_pmac *chip)
 109 {
 110         chip->awacs_reg[1] &= ~MASK_SAMPLERATE;
 111         chip->awacs_reg[1] |= chip->rate_index << 3;
 112         snd_pmac_awacs_write_reg(chip, 1, chip->awacs_reg[1]);
 113 }
 114 
 115 
 116 /*
 117  * AWACS volume callbacks
 118  */
 119 /*
 120  * volumes: 0-15 stereo
 121  */
 122 static int snd_pmac_awacs_info_volume(struct snd_kcontrol *kcontrol,
 123                                       struct snd_ctl_elem_info *uinfo)
 124 {
 125         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 126         uinfo->count = 2;
 127         uinfo->value.integer.min = 0;
 128         uinfo->value.integer.max = 15;
 129         return 0;
 130 }
 131 
 132 static int snd_pmac_awacs_get_volume(struct snd_kcontrol *kcontrol,
 133                                      struct snd_ctl_elem_value *ucontrol)
 134 {
 135         struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
 136         int reg = kcontrol->private_value & 0xff;
 137         int lshift = (kcontrol->private_value >> 8) & 0xff;
 138         int inverted = (kcontrol->private_value >> 16) & 1;
 139         unsigned long flags;
 140         int vol[2];
 141 
 142         spin_lock_irqsave(&chip->reg_lock, flags);
 143         vol[0] = (chip->awacs_reg[reg] >> lshift) & 0xf;
 144         vol[1] = chip->awacs_reg[reg] & 0xf;
 145         spin_unlock_irqrestore(&chip->reg_lock, flags);
 146         if (inverted) {
 147                 vol[0] = 0x0f - vol[0];
 148                 vol[1] = 0x0f - vol[1];
 149         }
 150         ucontrol->value.integer.value[0] = vol[0];
 151         ucontrol->value.integer.value[1] = vol[1];
 152         return 0;
 153 }
 154 
 155 static int snd_pmac_awacs_put_volume(struct snd_kcontrol *kcontrol,
 156                                      struct snd_ctl_elem_value *ucontrol)
 157 {
 158         struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
 159         int reg = kcontrol->private_value & 0xff;
 160         int lshift = (kcontrol->private_value >> 8) & 0xff;
 161         int inverted = (kcontrol->private_value >> 16) & 1;
 162         int val, oldval;
 163         unsigned long flags;
 164         unsigned int vol[2];
 165 
 166         vol[0] = ucontrol->value.integer.value[0];
 167         vol[1] = ucontrol->value.integer.value[1];
 168         if (vol[0] > 0x0f || vol[1] > 0x0f)
 169                 return -EINVAL;
 170         if (inverted) {
 171                 vol[0] = 0x0f - vol[0];
 172                 vol[1] = 0x0f - vol[1];
 173         }
 174         vol[0] &= 0x0f;
 175         vol[1] &= 0x0f;
 176         spin_lock_irqsave(&chip->reg_lock, flags);
 177         oldval = chip->awacs_reg[reg];
 178         val = oldval & ~(0xf | (0xf << lshift));
 179         val |= vol[0] << lshift;
 180         val |= vol[1];
 181         if (oldval != val)
 182                 snd_pmac_awacs_write_reg(chip, reg, val);
 183         spin_unlock_irqrestore(&chip->reg_lock, flags);
 184         return oldval != reg;
 185 }
 186 
 187 
 188 #define AWACS_VOLUME(xname, xreg, xshift, xinverted) \
 189 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
 190   .info = snd_pmac_awacs_info_volume, \
 191   .get = snd_pmac_awacs_get_volume, \
 192   .put = snd_pmac_awacs_put_volume, \
 193   .private_value = (xreg) | ((xshift) << 8) | ((xinverted) << 16) }
 194 
 195 /*
 196  * mute master/ogain for AWACS: mono
 197  */
 198 static int snd_pmac_awacs_get_switch(struct snd_kcontrol *kcontrol,
 199                                      struct snd_ctl_elem_value *ucontrol)
 200 {
 201         struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
 202         int reg = kcontrol->private_value & 0xff;
 203         int shift = (kcontrol->private_value >> 8) & 0xff;
 204         int invert = (kcontrol->private_value >> 16) & 1;
 205         int val;
 206         unsigned long flags;
 207 
 208         spin_lock_irqsave(&chip->reg_lock, flags);
 209         val = (chip->awacs_reg[reg] >> shift) & 1;
 210         spin_unlock_irqrestore(&chip->reg_lock, flags);
 211         if (invert)
 212                 val = 1 - val;
 213         ucontrol->value.integer.value[0] = val;
 214         return 0;
 215 }
 216 
 217 static int snd_pmac_awacs_put_switch(struct snd_kcontrol *kcontrol,
 218                                      struct snd_ctl_elem_value *ucontrol)
 219 {
 220         struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
 221         int reg = kcontrol->private_value & 0xff;
 222         int shift = (kcontrol->private_value >> 8) & 0xff;
 223         int invert = (kcontrol->private_value >> 16) & 1;
 224         int mask = 1 << shift;
 225         int val, changed;
 226         unsigned long flags;
 227 
 228         spin_lock_irqsave(&chip->reg_lock, flags);
 229         val = chip->awacs_reg[reg] & ~mask;
 230         if (ucontrol->value.integer.value[0] != invert)
 231                 val |= mask;
 232         changed = chip->awacs_reg[reg] != val;
 233         if (changed)
 234                 snd_pmac_awacs_write_reg(chip, reg, val);
 235         spin_unlock_irqrestore(&chip->reg_lock, flags);
 236         return changed;
 237 }
 238 
 239 #define AWACS_SWITCH(xname, xreg, xshift, xinvert) \
 240 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
 241   .info = snd_pmac_boolean_mono_info, \
 242   .get = snd_pmac_awacs_get_switch, \
 243   .put = snd_pmac_awacs_put_switch, \
 244   .private_value = (xreg) | ((xshift) << 8) | ((xinvert) << 16) }
 245 
 246 
 247 #ifdef PMAC_AMP_AVAIL
 248 /*
 249  * controls for perch/whisper extension cards, e.g. G3 desktop
 250  *
 251  * TDA7433 connected via i2c address 0x45 (= 0x8a),
 252  * accessed through cuda
 253  */
 254 static void awacs_set_cuda(int reg, int val)
 255 {
 256         struct adb_request req;
 257         cuda_request(&req, NULL, 5, CUDA_PACKET, CUDA_GET_SET_IIC, 0x8a,
 258                         reg, val);
 259         while (! req.complete)
 260                 cuda_poll();
 261 }
 262 
 263 /*
 264  * level = 0 - 14, 7 = 0 dB
 265  */
 266 static void awacs_amp_set_tone(struct awacs_amp *amp, int bass, int treble)
 267 {
 268         amp->amp_tone[0] = bass;
 269         amp->amp_tone[1] = treble;
 270         if (bass > 7)
 271                 bass = (14 - bass) + 8;
 272         if (treble > 7)
 273                 treble = (14 - treble) + 8;
 274         awacs_set_cuda(2, (bass << 4) | treble);
 275 }
 276 
 277 /*
 278  * vol = 0 - 31 (attenuation), 32 = mute bit, stereo
 279  */
 280 static int awacs_amp_set_vol(struct awacs_amp *amp, int index,
 281                              int lvol, int rvol, int do_check)
 282 {
 283         if (do_check && amp->amp_vol[index][0] == lvol &&
 284                         amp->amp_vol[index][1] == rvol)
 285                 return 0;
 286         awacs_set_cuda(3 + index, lvol);
 287         awacs_set_cuda(5 + index, rvol);
 288         amp->amp_vol[index][0] = lvol;
 289         amp->amp_vol[index][1] = rvol;
 290         return 1;
 291 }
 292 
 293 /*
 294  * 0 = -79 dB, 79 = 0 dB, 99 = +20 dB
 295  */
 296 static void awacs_amp_set_master(struct awacs_amp *amp, int vol)
 297 {
 298         amp->amp_master = vol;
 299         if (vol <= 79)
 300                 vol = 32 + (79 - vol);
 301         else
 302                 vol = 32 - (vol - 79);
 303         awacs_set_cuda(1, vol);
 304 }
 305 
 306 static void awacs_amp_free(struct snd_pmac *chip)
 307 {
 308         struct awacs_amp *amp = chip->mixer_data;
 309         if (!amp)
 310                 return;
 311         kfree(amp);
 312         chip->mixer_data = NULL;
 313         chip->mixer_free = NULL;
 314 }
 315 
 316 
 317 /*
 318  * mixer controls
 319  */
 320 static int snd_pmac_awacs_info_volume_amp(struct snd_kcontrol *kcontrol,
 321                                           struct snd_ctl_elem_info *uinfo)
 322 {
 323         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 324         uinfo->count = 2;
 325         uinfo->value.integer.min = 0;
 326         uinfo->value.integer.max = 31;
 327         return 0;
 328 }
 329 
 330 static int snd_pmac_awacs_get_volume_amp(struct snd_kcontrol *kcontrol,
 331                                          struct snd_ctl_elem_value *ucontrol)
 332 {
 333         struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
 334         int index = kcontrol->private_value;
 335         struct awacs_amp *amp = chip->mixer_data;
 336 
 337         ucontrol->value.integer.value[0] = 31 - (amp->amp_vol[index][0] & 31);
 338         ucontrol->value.integer.value[1] = 31 - (amp->amp_vol[index][1] & 31);
 339         return 0;
 340 }
 341 
 342 static int snd_pmac_awacs_put_volume_amp(struct snd_kcontrol *kcontrol,
 343                                          struct snd_ctl_elem_value *ucontrol)
 344 {
 345         struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
 346         int index = kcontrol->private_value;
 347         int vol[2];
 348         struct awacs_amp *amp = chip->mixer_data;
 349 
 350         vol[0] = (31 - (ucontrol->value.integer.value[0] & 31))
 351                 | (amp->amp_vol[index][0] & 32);
 352         vol[1] = (31 - (ucontrol->value.integer.value[1] & 31))
 353                 | (amp->amp_vol[index][1] & 32);
 354         return awacs_amp_set_vol(amp, index, vol[0], vol[1], 1);
 355 }
 356 
 357 static int snd_pmac_awacs_get_switch_amp(struct snd_kcontrol *kcontrol,
 358                                          struct snd_ctl_elem_value *ucontrol)
 359 {
 360         struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
 361         int index = kcontrol->private_value;
 362         struct awacs_amp *amp = chip->mixer_data;
 363 
 364         ucontrol->value.integer.value[0] = (amp->amp_vol[index][0] & 32)
 365                                         ? 0 : 1;
 366         ucontrol->value.integer.value[1] = (amp->amp_vol[index][1] & 32)
 367                                         ? 0 : 1;
 368         return 0;
 369 }
 370 
 371 static int snd_pmac_awacs_put_switch_amp(struct snd_kcontrol *kcontrol,
 372                                          struct snd_ctl_elem_value *ucontrol)
 373 {
 374         struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
 375         int index = kcontrol->private_value;
 376         int vol[2];
 377         struct awacs_amp *amp = chip->mixer_data;
 378 
 379         vol[0] = (ucontrol->value.integer.value[0] ? 0 : 32)
 380                 | (amp->amp_vol[index][0] & 31);
 381         vol[1] = (ucontrol->value.integer.value[1] ? 0 : 32)
 382                 | (amp->amp_vol[index][1] & 31);
 383         return awacs_amp_set_vol(amp, index, vol[0], vol[1], 1);
 384 }
 385 
 386 static int snd_pmac_awacs_info_tone_amp(struct snd_kcontrol *kcontrol,
 387                                         struct snd_ctl_elem_info *uinfo)
 388 {
 389         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 390         uinfo->count = 1;
 391         uinfo->value.integer.min = 0;
 392         uinfo->value.integer.max = 14;
 393         return 0;
 394 }
 395 
 396 static int snd_pmac_awacs_get_tone_amp(struct snd_kcontrol *kcontrol,
 397                                        struct snd_ctl_elem_value *ucontrol)
 398 {
 399         struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
 400         int index = kcontrol->private_value;
 401         struct awacs_amp *amp = chip->mixer_data;
 402 
 403         ucontrol->value.integer.value[0] = amp->amp_tone[index];
 404         return 0;
 405 }
 406 
 407 static int snd_pmac_awacs_put_tone_amp(struct snd_kcontrol *kcontrol,
 408                                        struct snd_ctl_elem_value *ucontrol)
 409 {
 410         struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
 411         int index = kcontrol->private_value;
 412         struct awacs_amp *amp = chip->mixer_data;
 413         unsigned int val;
 414 
 415         val = ucontrol->value.integer.value[0];
 416         if (val > 14)
 417                 return -EINVAL;
 418         if (val != amp->amp_tone[index]) {
 419                 amp->amp_tone[index] = val;
 420                 awacs_amp_set_tone(amp, amp->amp_tone[0], amp->amp_tone[1]);
 421                 return 1;
 422         }
 423         return 0;
 424 }
 425 
 426 static int snd_pmac_awacs_info_master_amp(struct snd_kcontrol *kcontrol,
 427                                           struct snd_ctl_elem_info *uinfo)
 428 {
 429         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 430         uinfo->count = 1;
 431         uinfo->value.integer.min = 0;
 432         uinfo->value.integer.max = 99;
 433         return 0;
 434 }
 435 
 436 static int snd_pmac_awacs_get_master_amp(struct snd_kcontrol *kcontrol,
 437                                          struct snd_ctl_elem_value *ucontrol)
 438 {
 439         struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
 440         struct awacs_amp *amp = chip->mixer_data;
 441 
 442         ucontrol->value.integer.value[0] = amp->amp_master;
 443         return 0;
 444 }
 445 
 446 static int snd_pmac_awacs_put_master_amp(struct snd_kcontrol *kcontrol,
 447                                          struct snd_ctl_elem_value *ucontrol)
 448 {
 449         struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
 450         struct awacs_amp *amp = chip->mixer_data;
 451         unsigned int val;
 452 
 453         val = ucontrol->value.integer.value[0];
 454         if (val > 99)
 455                 return -EINVAL;
 456         if (val != amp->amp_master) {
 457                 amp->amp_master = val;
 458                 awacs_amp_set_master(amp, amp->amp_master);
 459                 return 1;
 460         }
 461         return 0;
 462 }
 463 
 464 #define AMP_CH_SPK      0
 465 #define AMP_CH_HD       1
 466 
 467 static struct snd_kcontrol_new snd_pmac_awacs_amp_vol[] = {
 468         { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 469           .name = "Speaker Playback Volume",
 470           .info = snd_pmac_awacs_info_volume_amp,
 471           .get = snd_pmac_awacs_get_volume_amp,
 472           .put = snd_pmac_awacs_put_volume_amp,
 473           .private_value = AMP_CH_SPK,
 474         },
 475         { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 476           .name = "Headphone Playback Volume",
 477           .info = snd_pmac_awacs_info_volume_amp,
 478           .get = snd_pmac_awacs_get_volume_amp,
 479           .put = snd_pmac_awacs_put_volume_amp,
 480           .private_value = AMP_CH_HD,
 481         },
 482         { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 483           .name = "Tone Control - Bass",
 484           .info = snd_pmac_awacs_info_tone_amp,
 485           .get = snd_pmac_awacs_get_tone_amp,
 486           .put = snd_pmac_awacs_put_tone_amp,
 487           .private_value = 0,
 488         },
 489         { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 490           .name = "Tone Control - Treble",
 491           .info = snd_pmac_awacs_info_tone_amp,
 492           .get = snd_pmac_awacs_get_tone_amp,
 493           .put = snd_pmac_awacs_put_tone_amp,
 494           .private_value = 1,
 495         },
 496         { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 497           .name = "Amp Master Playback Volume",
 498           .info = snd_pmac_awacs_info_master_amp,
 499           .get = snd_pmac_awacs_get_master_amp,
 500           .put = snd_pmac_awacs_put_master_amp,
 501         },
 502 };
 503 
 504 static const struct snd_kcontrol_new snd_pmac_awacs_amp_hp_sw = {
 505         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 506         .name = "Headphone Playback Switch",
 507         .info = snd_pmac_boolean_stereo_info,
 508         .get = snd_pmac_awacs_get_switch_amp,
 509         .put = snd_pmac_awacs_put_switch_amp,
 510         .private_value = AMP_CH_HD,
 511 };
 512 
 513 static const struct snd_kcontrol_new snd_pmac_awacs_amp_spk_sw = {
 514         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 515         .name = "Speaker Playback Switch",
 516         .info = snd_pmac_boolean_stereo_info,
 517         .get = snd_pmac_awacs_get_switch_amp,
 518         .put = snd_pmac_awacs_put_switch_amp,
 519         .private_value = AMP_CH_SPK,
 520 };
 521 
 522 #endif /* PMAC_AMP_AVAIL */
 523 
 524 
 525 /*
 526  * mic boost for screamer
 527  */
 528 static int snd_pmac_screamer_mic_boost_info(struct snd_kcontrol *kcontrol,
 529                                             struct snd_ctl_elem_info *uinfo)
 530 {
 531         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 532         uinfo->count = 1;
 533         uinfo->value.integer.min = 0;
 534         uinfo->value.integer.max = 3;
 535         return 0;
 536 }
 537 
 538 static int snd_pmac_screamer_mic_boost_get(struct snd_kcontrol *kcontrol,
 539                                            struct snd_ctl_elem_value *ucontrol)
 540 {
 541         struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
 542         int val = 0;
 543         unsigned long flags;
 544 
 545         spin_lock_irqsave(&chip->reg_lock, flags);
 546         if (chip->awacs_reg[6] & MASK_MIC_BOOST)
 547                 val |= 2;
 548         if (chip->awacs_reg[0] & MASK_GAINLINE)
 549                 val |= 1;
 550         spin_unlock_irqrestore(&chip->reg_lock, flags);
 551         ucontrol->value.integer.value[0] = val;
 552         return 0;
 553 }
 554 
 555 static int snd_pmac_screamer_mic_boost_put(struct snd_kcontrol *kcontrol,
 556                                            struct snd_ctl_elem_value *ucontrol)
 557 {
 558         struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
 559         int changed = 0;
 560         int val0, val6;
 561         unsigned long flags;
 562 
 563         spin_lock_irqsave(&chip->reg_lock, flags);
 564         val0 = chip->awacs_reg[0] & ~MASK_GAINLINE;
 565         val6 = chip->awacs_reg[6] & ~MASK_MIC_BOOST;
 566         if (ucontrol->value.integer.value[0] & 1)
 567                 val0 |= MASK_GAINLINE;
 568         if (ucontrol->value.integer.value[0] & 2)
 569                 val6 |= MASK_MIC_BOOST;
 570         if (val0 != chip->awacs_reg[0]) {
 571                 snd_pmac_awacs_write_reg(chip, 0, val0);
 572                 changed = 1;
 573         }
 574         if (val6 != chip->awacs_reg[6]) {
 575                 snd_pmac_awacs_write_reg(chip, 6, val6);
 576                 changed = 1;
 577         }
 578         spin_unlock_irqrestore(&chip->reg_lock, flags);
 579         return changed;
 580 }
 581 
 582 /*
 583  * lists of mixer elements
 584  */
 585 static struct snd_kcontrol_new snd_pmac_awacs_mixers[] = {
 586         AWACS_SWITCH("Master Capture Switch", 1, SHIFT_LOOPTHRU, 0),
 587         AWACS_VOLUME("Master Capture Volume", 0, 4, 0),
 588 /*      AWACS_SWITCH("Unknown Playback Switch", 6, SHIFT_PAROUT0, 0), */
 589 };
 590 
 591 static struct snd_kcontrol_new snd_pmac_screamer_mixers_beige[] = {
 592         AWACS_VOLUME("Master Playback Volume", 2, 6, 1),
 593         AWACS_VOLUME("Play-through Playback Volume", 5, 6, 1),
 594         AWACS_SWITCH("Line Capture Switch", 0, SHIFT_MUX_MIC, 0),
 595         AWACS_SWITCH("CD Capture Switch", 0, SHIFT_MUX_LINE, 0),
 596 };
 597 
 598 static struct snd_kcontrol_new snd_pmac_screamer_mixers_lo[] = {
 599         AWACS_VOLUME("Line out Playback Volume", 2, 6, 1),
 600 };
 601 
 602 static struct snd_kcontrol_new snd_pmac_screamer_mixers_imac[] = {
 603         AWACS_VOLUME("Play-through Playback Volume", 5, 6, 1),
 604         AWACS_SWITCH("CD Capture Switch", 0, SHIFT_MUX_CD, 0),
 605 };
 606 
 607 static struct snd_kcontrol_new snd_pmac_screamer_mixers_g4agp[] = {
 608         AWACS_VOLUME("Line out Playback Volume", 2, 6, 1),
 609         AWACS_VOLUME("Master Playback Volume", 5, 6, 1),
 610         AWACS_SWITCH("CD Capture Switch", 0, SHIFT_MUX_CD, 0),
 611         AWACS_SWITCH("Line Capture Switch", 0, SHIFT_MUX_MIC, 0),
 612 };
 613 
 614 static struct snd_kcontrol_new snd_pmac_awacs_mixers_pmac7500[] = {
 615         AWACS_VOLUME("Line out Playback Volume", 2, 6, 1),
 616         AWACS_SWITCH("CD Capture Switch", 0, SHIFT_MUX_CD, 0),
 617         AWACS_SWITCH("Line Capture Switch", 0, SHIFT_MUX_MIC, 0),
 618 };
 619 
 620 static struct snd_kcontrol_new snd_pmac_awacs_mixers_pmac5500[] = {
 621         AWACS_VOLUME("Headphone Playback Volume", 2, 6, 1),
 622 };
 623 
 624 static struct snd_kcontrol_new snd_pmac_awacs_mixers_pmac[] = {
 625         AWACS_VOLUME("Master Playback Volume", 2, 6, 1),
 626         AWACS_SWITCH("CD Capture Switch", 0, SHIFT_MUX_CD, 0),
 627 };
 628 
 629 /* FIXME: is this correct order?
 630  * screamer (powerbook G3 pismo) seems to have different bits...
 631  */
 632 static struct snd_kcontrol_new snd_pmac_awacs_mixers2[] = {
 633         AWACS_SWITCH("Line Capture Switch", 0, SHIFT_MUX_LINE, 0),
 634         AWACS_SWITCH("Mic Capture Switch", 0, SHIFT_MUX_MIC, 0),
 635 };
 636 
 637 static struct snd_kcontrol_new snd_pmac_screamer_mixers2[] = {
 638         AWACS_SWITCH("Line Capture Switch", 0, SHIFT_MUX_MIC, 0),
 639         AWACS_SWITCH("Mic Capture Switch", 0, SHIFT_MUX_LINE, 0),
 640 };
 641 
 642 static struct snd_kcontrol_new snd_pmac_awacs_mixers2_pmac5500[] = {
 643         AWACS_SWITCH("CD Capture Switch", 0, SHIFT_MUX_CD, 0),
 644 };
 645 
 646 static struct snd_kcontrol_new snd_pmac_awacs_master_sw =
 647 AWACS_SWITCH("Master Playback Switch", 1, SHIFT_HDMUTE, 1);
 648 
 649 static struct snd_kcontrol_new snd_pmac_awacs_master_sw_imac =
 650 AWACS_SWITCH("Line out Playback Switch", 1, SHIFT_HDMUTE, 1);
 651 
 652 static struct snd_kcontrol_new snd_pmac_awacs_master_sw_pmac5500 =
 653 AWACS_SWITCH("Headphone Playback Switch", 1, SHIFT_HDMUTE, 1);
 654 
 655 static struct snd_kcontrol_new snd_pmac_awacs_mic_boost[] = {
 656         AWACS_SWITCH("Mic Boost Capture Switch", 0, SHIFT_GAINLINE, 0),
 657 };
 658 
 659 static struct snd_kcontrol_new snd_pmac_screamer_mic_boost[] = {
 660         { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 661           .name = "Mic Boost Capture Volume",
 662           .info = snd_pmac_screamer_mic_boost_info,
 663           .get = snd_pmac_screamer_mic_boost_get,
 664           .put = snd_pmac_screamer_mic_boost_put,
 665         },
 666 };
 667 
 668 static struct snd_kcontrol_new snd_pmac_awacs_mic_boost_pmac7500[] =
 669 {
 670         AWACS_SWITCH("Line Boost Capture Switch", 0, SHIFT_GAINLINE, 0),
 671 };
 672 
 673 static struct snd_kcontrol_new snd_pmac_screamer_mic_boost_beige[] =
 674 {
 675         AWACS_SWITCH("Line Boost Capture Switch", 0, SHIFT_GAINLINE, 0),
 676         AWACS_SWITCH("CD Boost Capture Switch", 6, SHIFT_MIC_BOOST, 0),
 677 };
 678 
 679 static struct snd_kcontrol_new snd_pmac_screamer_mic_boost_imac[] =
 680 {
 681         AWACS_SWITCH("Line Boost Capture Switch", 0, SHIFT_GAINLINE, 0),
 682         AWACS_SWITCH("Mic Boost Capture Switch", 6, SHIFT_MIC_BOOST, 0),
 683 };
 684 
 685 static struct snd_kcontrol_new snd_pmac_awacs_speaker_vol[] = {
 686         AWACS_VOLUME("Speaker Playback Volume", 4, 6, 1),
 687 };
 688 
 689 static struct snd_kcontrol_new snd_pmac_awacs_speaker_sw =
 690 AWACS_SWITCH("Speaker Playback Switch", 1, SHIFT_SPKMUTE, 1);
 691 
 692 static struct snd_kcontrol_new snd_pmac_awacs_speaker_sw_imac1 =
 693 AWACS_SWITCH("Speaker Playback Switch", 1, SHIFT_PAROUT1, 1);
 694 
 695 static struct snd_kcontrol_new snd_pmac_awacs_speaker_sw_imac2 =
 696 AWACS_SWITCH("Speaker Playback Switch", 1, SHIFT_PAROUT1, 0);
 697 
 698 
 699 /*
 700  * add new mixer elements to the card
 701  */
 702 static int build_mixers(struct snd_pmac *chip, int nums,
 703                         struct snd_kcontrol_new *mixers)
 704 {
 705         int i, err;
 706 
 707         for (i = 0; i < nums; i++) {
 708                 err = snd_ctl_add(chip->card, snd_ctl_new1(&mixers[i], chip));
 709                 if (err < 0)
 710                         return err;
 711         }
 712         return 0;
 713 }
 714 
 715 
 716 /*
 717  * restore all registers
 718  */
 719 static void awacs_restore_all_regs(struct snd_pmac *chip)
 720 {
 721         snd_pmac_awacs_write_noreg(chip, 0, chip->awacs_reg[0]);
 722         snd_pmac_awacs_write_noreg(chip, 1, chip->awacs_reg[1]);
 723         snd_pmac_awacs_write_noreg(chip, 2, chip->awacs_reg[2]);
 724         snd_pmac_awacs_write_noreg(chip, 4, chip->awacs_reg[4]);
 725         if (chip->model == PMAC_SCREAMER) {
 726                 snd_pmac_awacs_write_noreg(chip, 5, chip->awacs_reg[5]);
 727                 snd_pmac_awacs_write_noreg(chip, 6, chip->awacs_reg[6]);
 728                 snd_pmac_awacs_write_noreg(chip, 7, chip->awacs_reg[7]);
 729         }
 730 }
 731 
 732 #ifdef CONFIG_PM
 733 static void snd_pmac_awacs_suspend(struct snd_pmac *chip)
 734 {
 735         snd_pmac_awacs_write_noreg(chip, 1, (chip->awacs_reg[1]
 736                                              | MASK_AMUTE | MASK_CMUTE));
 737 }
 738 
 739 static void snd_pmac_awacs_resume(struct snd_pmac *chip)
 740 {
 741         if (of_machine_is_compatible("PowerBook3,1")
 742             || of_machine_is_compatible("PowerBook3,2")) {
 743                 msleep(100);
 744                 snd_pmac_awacs_write_reg(chip, 1,
 745                         chip->awacs_reg[1] & ~MASK_PAROUT);
 746                 msleep(300);
 747         }
 748 
 749         awacs_restore_all_regs(chip);
 750         if (chip->model == PMAC_SCREAMER) {
 751                 /* reset power bits in reg 6 */
 752                 mdelay(5);
 753                 snd_pmac_awacs_write_noreg(chip, 6, chip->awacs_reg[6]);
 754         }
 755         screamer_recalibrate(chip);
 756 #ifdef PMAC_AMP_AVAIL
 757         if (chip->mixer_data) {
 758                 struct awacs_amp *amp = chip->mixer_data;
 759                 awacs_amp_set_vol(amp, 0,
 760                                   amp->amp_vol[0][0], amp->amp_vol[0][1], 0);
 761                 awacs_amp_set_vol(amp, 1,
 762                                   amp->amp_vol[1][0], amp->amp_vol[1][1], 0);
 763                 awacs_amp_set_tone(amp, amp->amp_tone[0], amp->amp_tone[1]);
 764                 awacs_amp_set_master(amp, amp->amp_master);
 765         }
 766 #endif
 767 }
 768 #endif /* CONFIG_PM */
 769 
 770 #define IS_PM7500 (of_machine_is_compatible("AAPL,7500") \
 771                 || of_machine_is_compatible("AAPL,8500") \
 772                 || of_machine_is_compatible("AAPL,9500"))
 773 #define IS_PM5500 (of_machine_is_compatible("AAPL,e411"))
 774 #define IS_BEIGE (of_machine_is_compatible("AAPL,Gossamer"))
 775 #define IS_IMAC1 (of_machine_is_compatible("PowerMac2,1"))
 776 #define IS_IMAC2 (of_machine_is_compatible("PowerMac2,2") \
 777                 || of_machine_is_compatible("PowerMac4,1"))
 778 #define IS_G4AGP (of_machine_is_compatible("PowerMac3,1"))
 779 #define IS_LOMBARD (of_machine_is_compatible("PowerBook1,1"))
 780 
 781 static int imac1, imac2;
 782 
 783 #ifdef PMAC_SUPPORT_AUTOMUTE
 784 /*
 785  * auto-mute stuffs
 786  */
 787 static int snd_pmac_awacs_detect_headphone(struct snd_pmac *chip)
 788 {
 789         return (in_le32(&chip->awacs->codec_stat) & chip->hp_stat_mask) ? 1 : 0;
 790 }
 791 
 792 #ifdef PMAC_AMP_AVAIL
 793 static int toggle_amp_mute(struct awacs_amp *amp, int index, int mute)
 794 {
 795         int vol[2];
 796         vol[0] = amp->amp_vol[index][0] & 31;
 797         vol[1] = amp->amp_vol[index][1] & 31;
 798         if (mute) {
 799                 vol[0] |= 32;
 800                 vol[1] |= 32;
 801         }
 802         return awacs_amp_set_vol(amp, index, vol[0], vol[1], 1);
 803 }
 804 #endif
 805 
 806 static void snd_pmac_awacs_update_automute(struct snd_pmac *chip, int do_notify)
 807 {
 808         if (chip->auto_mute) {
 809 #ifdef PMAC_AMP_AVAIL
 810                 if (chip->mixer_data) {
 811                         struct awacs_amp *amp = chip->mixer_data;
 812                         int changed;
 813                         if (snd_pmac_awacs_detect_headphone(chip)) {
 814                                 changed = toggle_amp_mute(amp, AMP_CH_HD, 0);
 815                                 changed |= toggle_amp_mute(amp, AMP_CH_SPK, 1);
 816                         } else {
 817                                 changed = toggle_amp_mute(amp, AMP_CH_HD, 1);
 818                                 changed |= toggle_amp_mute(amp, AMP_CH_SPK, 0);
 819                         }
 820                         if (do_notify && ! changed)
 821                                 return;
 822                 } else
 823 #endif
 824                 {
 825                         int reg = chip->awacs_reg[1]
 826                                 | (MASK_HDMUTE | MASK_SPKMUTE);
 827                         if (imac1) {
 828                                 reg &= ~MASK_SPKMUTE;
 829                                 reg |= MASK_PAROUT1;
 830                         } else if (imac2) {
 831                                 reg &= ~MASK_SPKMUTE;
 832                                 reg &= ~MASK_PAROUT1;
 833                         }
 834                         if (snd_pmac_awacs_detect_headphone(chip))
 835                                 reg &= ~MASK_HDMUTE;
 836                         else if (imac1)
 837                                 reg &= ~MASK_PAROUT1;
 838                         else if (imac2)
 839                                 reg |= MASK_PAROUT1;
 840                         else
 841                                 reg &= ~MASK_SPKMUTE;
 842                         if (do_notify && reg == chip->awacs_reg[1])
 843                                 return;
 844                         snd_pmac_awacs_write_reg(chip, 1, reg);
 845                 }
 846                 if (do_notify) {
 847                         snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
 848                                        &chip->master_sw_ctl->id);
 849                         snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
 850                                        &chip->speaker_sw_ctl->id);
 851                         snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
 852                                        &chip->hp_detect_ctl->id);
 853                 }
 854         }
 855 }
 856 #endif /* PMAC_SUPPORT_AUTOMUTE */
 857 
 858 
 859 /*
 860  * initialize chip
 861  */
 862 int
 863 snd_pmac_awacs_init(struct snd_pmac *chip)
 864 {
 865         int pm7500 = IS_PM7500;
 866         int pm5500 = IS_PM5500;
 867         int beige = IS_BEIGE;
 868         int g4agp = IS_G4AGP;
 869         int lombard = IS_LOMBARD;
 870         int imac;
 871         int err, vol;
 872         struct snd_kcontrol *vmaster_sw, *vmaster_vol;
 873         struct snd_kcontrol *master_vol, *speaker_vol;
 874 
 875         imac1 = IS_IMAC1;
 876         imac2 = IS_IMAC2;
 877         imac = imac1 || imac2;
 878         /* looks like MASK_GAINLINE triggers something, so we set here
 879          * as start-up
 880          */
 881         chip->awacs_reg[0] = MASK_MUX_CD | 0xff | MASK_GAINLINE;
 882         chip->awacs_reg[1] = MASK_CMUTE | MASK_AMUTE;
 883         /* FIXME: Only machines with external SRS module need MASK_PAROUT */
 884         if (chip->has_iic || chip->device_id == 0x5 ||
 885             /* chip->_device_id == 0x8 || */
 886             chip->device_id == 0xb)
 887                 chip->awacs_reg[1] |= MASK_PAROUT;
 888         /* get default volume from nvram */
 889         // vol = (~nvram_read_byte(0x1308) & 7) << 1;
 890         // vol = ((pmac_xpram_read( 8 ) & 7 ) << 1 );
 891         vol = 0x0f; /* no, on alsa, muted as default */
 892         vol = vol + (vol << 6);
 893         chip->awacs_reg[2] = vol;
 894         chip->awacs_reg[4] = vol;
 895         if (chip->model == PMAC_SCREAMER) {
 896                 /* FIXME: screamer has loopthru vol control */
 897                 chip->awacs_reg[5] = vol;
 898                 /* FIXME: maybe should be vol << 3 for PCMCIA speaker */
 899                 chip->awacs_reg[6] = MASK_MIC_BOOST;
 900                 chip->awacs_reg[7] = 0;
 901         }
 902 
 903         awacs_restore_all_regs(chip);
 904         chip->manufacturer = (in_le32(&chip->awacs->codec_stat) >> 8) & 0xf;
 905         screamer_recalibrate(chip);
 906 
 907         chip->revision = (in_le32(&chip->awacs->codec_stat) >> 12) & 0xf;
 908 #ifdef PMAC_AMP_AVAIL
 909         if (chip->revision == 3 && chip->has_iic && CHECK_CUDA_AMP()) {
 910                 struct awacs_amp *amp = kzalloc(sizeof(*amp), GFP_KERNEL);
 911                 if (! amp)
 912                         return -ENOMEM;
 913                 chip->mixer_data = amp;
 914                 chip->mixer_free = awacs_amp_free;
 915                 /* mute and zero vol */
 916                 awacs_amp_set_vol(amp, 0, 63, 63, 0);
 917                 awacs_amp_set_vol(amp, 1, 63, 63, 0);
 918                 awacs_amp_set_tone(amp, 7, 7); /* 0 dB */
 919                 awacs_amp_set_master(amp, 79); /* 0 dB */
 920         }
 921 #endif /* PMAC_AMP_AVAIL */
 922 
 923         if (chip->hp_stat_mask == 0) {
 924                 /* set headphone-jack detection bit */
 925                 switch (chip->model) {
 926                 case PMAC_AWACS:
 927                         chip->hp_stat_mask = pm7500 || pm5500 ? MASK_HDPCONN
 928                                 : MASK_LOCONN;
 929                         break;
 930                 case PMAC_SCREAMER:
 931                         switch (chip->device_id) {
 932                         case 0x08:
 933                         case 0x0B:
 934                                 chip->hp_stat_mask = imac
 935                                         ? MASK_LOCONN_IMAC |
 936                                         MASK_HDPLCONN_IMAC |
 937                                         MASK_HDPRCONN_IMAC
 938                                         : MASK_HDPCONN;
 939                                 break;
 940                         case 0x00:
 941                         case 0x05:
 942                                 chip->hp_stat_mask = MASK_LOCONN;
 943                                 break;
 944                         default:
 945                                 chip->hp_stat_mask = MASK_HDPCONN;
 946                                 break;
 947                         }
 948                         break;
 949                 default:
 950                         snd_BUG();
 951                         break;
 952                 }
 953         }
 954 
 955         /*
 956          * build mixers
 957          */
 958         strcpy(chip->card->mixername, "PowerMac AWACS");
 959 
 960         err = build_mixers(chip, ARRAY_SIZE(snd_pmac_awacs_mixers),
 961                                 snd_pmac_awacs_mixers);
 962         if (err < 0)
 963                 return err;
 964         if (beige || g4agp)
 965                 ;
 966         else if (chip->model == PMAC_SCREAMER || pm5500)
 967                 err = build_mixers(chip, ARRAY_SIZE(snd_pmac_screamer_mixers2),
 968                                    snd_pmac_screamer_mixers2);
 969         else if (!pm7500)
 970                 err = build_mixers(chip, ARRAY_SIZE(snd_pmac_awacs_mixers2),
 971                                    snd_pmac_awacs_mixers2);
 972         if (err < 0)
 973                 return err;
 974         if (pm5500) {
 975                 err = build_mixers(chip,
 976                                    ARRAY_SIZE(snd_pmac_awacs_mixers2_pmac5500),
 977                                    snd_pmac_awacs_mixers2_pmac5500);
 978                 if (err < 0)
 979                         return err;
 980         }
 981         master_vol = NULL;
 982         if (pm7500)
 983                 err = build_mixers(chip,
 984                                    ARRAY_SIZE(snd_pmac_awacs_mixers_pmac7500),
 985                                    snd_pmac_awacs_mixers_pmac7500);
 986         else if (pm5500)
 987                 err = snd_ctl_add(chip->card,
 988                     (master_vol = snd_ctl_new1(snd_pmac_awacs_mixers_pmac5500,
 989                                                 chip)));
 990         else if (beige)
 991                 err = build_mixers(chip,
 992                                    ARRAY_SIZE(snd_pmac_screamer_mixers_beige),
 993                                    snd_pmac_screamer_mixers_beige);
 994         else if (imac || lombard) {
 995                 err = snd_ctl_add(chip->card,
 996                     (master_vol = snd_ctl_new1(snd_pmac_screamer_mixers_lo,
 997                                                 chip)));
 998                 if (err < 0)
 999                         return err;
1000                 err = build_mixers(chip,
1001                                    ARRAY_SIZE(snd_pmac_screamer_mixers_imac),
1002                                    snd_pmac_screamer_mixers_imac);
1003         } else if (g4agp)
1004                 err = build_mixers(chip,
1005                                    ARRAY_SIZE(snd_pmac_screamer_mixers_g4agp),
1006                                    snd_pmac_screamer_mixers_g4agp);
1007         else
1008                 err = build_mixers(chip,
1009                                    ARRAY_SIZE(snd_pmac_awacs_mixers_pmac),
1010                                    snd_pmac_awacs_mixers_pmac);
1011         if (err < 0)
1012                 return err;
1013         chip->master_sw_ctl = snd_ctl_new1((pm7500 || imac || g4agp || lombard)
1014                         ? &snd_pmac_awacs_master_sw_imac
1015                         : pm5500
1016                         ? &snd_pmac_awacs_master_sw_pmac5500
1017                         : &snd_pmac_awacs_master_sw, chip);
1018         err = snd_ctl_add(chip->card, chip->master_sw_ctl);
1019         if (err < 0)
1020                 return err;
1021 #ifdef PMAC_AMP_AVAIL
1022         if (chip->mixer_data) {
1023                 /* use amplifier.  the signal is connected from route A
1024                  * to the amp.  the amp has its headphone and speaker
1025                  * volumes and mute switches, so we use them instead of
1026                  * screamer registers.
1027                  * in this case, it seems the route C is not used.
1028                  */
1029                 err = build_mixers(chip, ARRAY_SIZE(snd_pmac_awacs_amp_vol),
1030                                         snd_pmac_awacs_amp_vol);
1031                 if (err < 0)
1032                         return err;
1033                 /* overwrite */
1034                 chip->master_sw_ctl = snd_ctl_new1(&snd_pmac_awacs_amp_hp_sw,
1035                                                         chip);
1036                 err = snd_ctl_add(chip->card, chip->master_sw_ctl);
1037                 if (err < 0)
1038                         return err;
1039                 chip->speaker_sw_ctl = snd_ctl_new1(&snd_pmac_awacs_amp_spk_sw,
1040                                                         chip);
1041                 err = snd_ctl_add(chip->card, chip->speaker_sw_ctl);
1042                 if (err < 0)
1043                         return err;
1044         } else
1045 #endif /* PMAC_AMP_AVAIL */
1046         {
1047                 /* route A = headphone, route C = speaker */
1048                 err = snd_ctl_add(chip->card,
1049                     (speaker_vol = snd_ctl_new1(snd_pmac_awacs_speaker_vol,
1050                                                 chip)));
1051                 if (err < 0)
1052                         return err;
1053                 chip->speaker_sw_ctl = snd_ctl_new1(imac1
1054                                 ? &snd_pmac_awacs_speaker_sw_imac1
1055                                 : imac2
1056                                 ? &snd_pmac_awacs_speaker_sw_imac2
1057                                 : &snd_pmac_awacs_speaker_sw, chip);
1058                 err = snd_ctl_add(chip->card, chip->speaker_sw_ctl);
1059                 if (err < 0)
1060                         return err;
1061         }
1062 
1063         if (pm5500 || imac || lombard) {
1064                 vmaster_sw = snd_ctl_make_virtual_master(
1065                         "Master Playback Switch", (unsigned int *) NULL);
1066                 err = snd_ctl_add_slave_uncached(vmaster_sw,
1067                                                  chip->master_sw_ctl);
1068                 if (err < 0)
1069                         return err;
1070                 err = snd_ctl_add_slave_uncached(vmaster_sw,
1071                                                   chip->speaker_sw_ctl);
1072                 if (err < 0)
1073                         return err;
1074                 err = snd_ctl_add(chip->card, vmaster_sw);
1075                 if (err < 0)
1076                         return err;
1077                 vmaster_vol = snd_ctl_make_virtual_master(
1078                         "Master Playback Volume", (unsigned int *) NULL);
1079                 err = snd_ctl_add_slave(vmaster_vol, master_vol);
1080                 if (err < 0)
1081                         return err;
1082                 err = snd_ctl_add_slave(vmaster_vol, speaker_vol);
1083                 if (err < 0)
1084                         return err;
1085                 err = snd_ctl_add(chip->card, vmaster_vol);
1086                 if (err < 0)
1087                         return err;
1088         }
1089 
1090         if (beige || g4agp)
1091                 err = build_mixers(chip,
1092                                 ARRAY_SIZE(snd_pmac_screamer_mic_boost_beige),
1093                                 snd_pmac_screamer_mic_boost_beige);
1094         else if (imac)
1095                 err = build_mixers(chip,
1096                                 ARRAY_SIZE(snd_pmac_screamer_mic_boost_imac),
1097                                 snd_pmac_screamer_mic_boost_imac);
1098         else if (chip->model == PMAC_SCREAMER)
1099                 err = build_mixers(chip,
1100                                 ARRAY_SIZE(snd_pmac_screamer_mic_boost),
1101                                 snd_pmac_screamer_mic_boost);
1102         else if (pm7500)
1103                 err = build_mixers(chip,
1104                                 ARRAY_SIZE(snd_pmac_awacs_mic_boost_pmac7500),
1105                                 snd_pmac_awacs_mic_boost_pmac7500);
1106         else
1107                 err = build_mixers(chip, ARRAY_SIZE(snd_pmac_awacs_mic_boost),
1108                                 snd_pmac_awacs_mic_boost);
1109         if (err < 0)
1110                 return err;
1111 
1112         /*
1113          * set lowlevel callbacks
1114          */
1115         chip->set_format = snd_pmac_awacs_set_format;
1116 #ifdef CONFIG_PM
1117         chip->suspend = snd_pmac_awacs_suspend;
1118         chip->resume = snd_pmac_awacs_resume;
1119 #endif
1120 #ifdef PMAC_SUPPORT_AUTOMUTE
1121         err = snd_pmac_add_automute(chip);
1122         if (err < 0)
1123                 return err;
1124         chip->detect_headphone = snd_pmac_awacs_detect_headphone;
1125         chip->update_automute = snd_pmac_awacs_update_automute;
1126         snd_pmac_awacs_update_automute(chip, 0); /* update the status only */
1127 #endif
1128         if (chip->model == PMAC_SCREAMER) {
1129                 snd_pmac_awacs_write_noreg(chip, 6, chip->awacs_reg[6]);
1130                 snd_pmac_awacs_write_noreg(chip, 0, chip->awacs_reg[0]);
1131         }
1132 
1133         return 0;
1134 }

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