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