- Timestamp:
- Jul 23, 2006, 11:54:27 AM (19 years ago)
- Location:
- GPL/trunk
- Files:
-
- 39 edited
-
alsa-kernel/core/control.c (modified) (3 diffs)
-
alsa-kernel/core/pcm_native.c (modified) (1 diff)
-
alsa-kernel/core/seq/seq_ports.c (modified) (2 diffs)
-
alsa-kernel/drivers/mpu401/mpu401_uart.c (modified) (11 diffs)
-
alsa-kernel/include/sound/ac97_codec.h (modified) (8 diffs)
-
alsa-kernel/include/sound/asound.h (modified) (3 diffs)
-
alsa-kernel/include/sound/compat_22.h (modified) (1 diff)
-
alsa-kernel/include/sound/control.h (modified) (2 diffs)
-
alsa-kernel/include/sound/mpu401.h (modified) (3 diffs)
-
alsa-kernel/pci/ac97/ac97_codec.c (modified) (21 diffs)
-
alsa-kernel/pci/ac97/ac97_patch.c (modified) (7 diffs)
-
alsa-kernel/pci/ac97/ac97_patch.h (modified) (1 diff)
-
alsa-kernel/pci/ac97/ac97_pcm.c (modified) (4 diffs)
-
alsa-kernel/pci/bt87x.c (modified) (1 diff)
-
alsa-kernel/pci/ca0106/ca0106_main.c (modified) (2 diffs)
-
alsa-kernel/pci/ca0106/ca0106_mixer.c (modified) (2 diffs)
-
alsa-kernel/pci/cmipci.c (modified) (2 diffs)
-
alsa-kernel/pci/cs4281.c (modified) (2 diffs)
-
alsa-kernel/pci/cs46xx/cs46xx_lib.c (modified) (2 diffs)
-
alsa-kernel/pci/es1938.c (modified) (1 diff)
-
alsa-kernel/pci/es1968.c (modified) (1 diff)
-
alsa-kernel/pci/fm801.c (modified) (1 diff)
-
alsa-kernel/pci/hda/hda_codec.c (modified) (59 diffs)
-
alsa-kernel/pci/hda/hda_intel.c (modified) (7 diffs)
-
alsa-kernel/pci/hda/hda_patch.h (modified) (2 diffs)
-
alsa-kernel/pci/hda/makefile.os2 (modified) (1 diff)
-
alsa-kernel/pci/hda/patch_analog.c (modified) (14 diffs)
-
alsa-kernel/pci/hda/patch_realtek.c (modified) (98 diffs)
-
alsa-kernel/pci/hda/patch_sigmatel.c (modified) (17 diffs)
-
alsa-kernel/pci/intel8x0.c (modified) (6 diffs)
-
alsa-kernel/pci/maestro3.c (modified) (1 diff)
-
alsa-kernel/pci/sonicvibes.c (modified) (1 diff)
-
alsa-kernel/pci/trident/trident.c (modified) (1 diff)
-
alsa-kernel/pci/via82xx.c (modified) (7 diffs)
-
alsa-kernel/pci/ymfpci/ymfpci.c (modified) (1 diff)
-
alsa-kernel/synth/emux/soundfont.c (modified) (1 diff)
-
include/version.mak (modified) (1 diff)
-
lib32/ioctl.c (modified) (3 diffs)
-
lib32/sound.c (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
GPL/trunk/alsa-kernel/core/control.c
r76 r77 244 244 kctl.get = ncontrol->get; 245 245 kctl.put = ncontrol->put; 246 kctl.tlv = ncontrol->tlv; 246 247 kctl.private_value = ncontrol->private_value; 247 248 kctl.private_data = private_data; … … 1036 1037 #endif 1037 1038 1039 static int snd_ctl_tlv_read(struct snd_card *card, 1040 struct snd_ctl_tlv __user *_tlv) 1041 { 1042 struct snd_ctl_tlv tlv; 1043 struct snd_kcontrol *kctl; 1044 unsigned int len; 1045 int err = 0; 1046 1047 if (copy_from_user(&tlv, _tlv, sizeof(tlv))) 1048 return -EFAULT; 1049 if (tlv.length < sizeof(unsigned int) * 3) 1050 return -EINVAL; 1051 down_read(&card->controls_rwsem); 1052 kctl = snd_ctl_find_numid(card, tlv.numid); 1053 if (kctl == NULL) { 1054 err = -ENOENT; 1055 goto __kctl_end; 1056 } 1057 if (kctl->tlv == NULL) { 1058 err = -ENXIO; 1059 goto __kctl_end; 1060 } 1061 len = kctl->tlv[1] + 2 * sizeof(unsigned int); 1062 if (tlv.length < len) { 1063 err = -ENOMEM; 1064 goto __kctl_end; 1065 } 1066 if (copy_to_user(_tlv->tlv, kctl->tlv, len)) 1067 err = -EFAULT; 1068 __kctl_end: 1069 up_read(&card->controls_rwsem); 1070 return err; 1071 } 1072 1038 1073 static int snd_ctl_ioctl(struct inode *inode, struct file *file, 1039 1074 unsigned int cmd, unsigned long arg) … … 1081 1116 case SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS: 1082 1117 return snd_ctl_subscribe_events(ctl, (int *) arg); 1118 case SNDRV_CTL_IOCTL_TLV_READ: 1119 return snd_ctl_tlv_read(card, argp); 1083 1120 case SNDRV_CTL_IOCTL_POWER: 1084 1121 if (get_user(err, (int *)arg)) -
GPL/trunk/alsa-kernel/core/pcm_native.c
r76 r77 1447 1447 } 1448 1448 up_read(&snd_pcm_link_rwsem); 1449 if (! num_drecs)1450 goto _error;1451 1449 1452 1450 snd_pcm_stream_lock_irq(substream); -
GPL/trunk/alsa-kernel/core/seq/seq_ports.c
r34 r77 222 222 struct list_head *p, *n; 223 223 224 down_write(&grp->list_mutex);225 224 list_for_each_safe(p, n, &grp->list_head) { 226 225 struct snd_seq_subscribers *subs; … … 260 259 } 261 260 } 262 up_write(&grp->list_mutex);263 261 } 264 262 -
GPL/trunk/alsa-kernel/drivers/mpu401/mpu401_uart.c
r34 r77 91 91 } 92 92 93 static void uart_interrupt_tx(struct snd_mpu401 *mpu) 94 { 95 if (test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode) && 96 test_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode)) { 97 spin_lock(&mpu->output_lock); 98 snd_mpu401_uart_output_write(mpu); 99 spin_unlock(&mpu->output_lock); 100 } 101 } 102 93 103 static void _snd_mpu401_uart_interrupt(struct snd_mpu401 *mpu) 94 104 { 95 spin_lock(&mpu->input_lock); 96 if (test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode)) { 97 snd_mpu401_uart_input_read(mpu); 98 } else { 99 snd_mpu401_uart_clear_rx(mpu); 100 } 101 spin_unlock(&mpu->input_lock); 102 /* ok. for better Tx performance try do some output when input is done */ 103 if (test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode) && 104 test_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode)) { 105 spin_lock(&mpu->output_lock); 106 snd_mpu401_uart_output_write(mpu); 107 spin_unlock(&mpu->output_lock); 108 } 105 if (mpu->info_flags & MPU401_INFO_INPUT) { 106 spin_lock(&mpu->input_lock); 107 if (test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode)) 108 snd_mpu401_uart_input_read(mpu); 109 else 110 snd_mpu401_uart_clear_rx(mpu); 111 spin_unlock(&mpu->input_lock); 112 } 113 if (! (mpu->info_flags & MPU401_INFO_TX_IRQ)) 114 /* ok. for better Tx performance try do some output 115 when input is done */ 116 uart_interrupt_tx(mpu); 109 117 } 110 118 … … 126 134 return IRQ_HANDLED; 127 135 } 136 137 /** 138 * snd_mpu401_uart_interrupt_tx - generic MPU401-UART transmit irq handler 139 * @irq: the irq number 140 * @dev_id: mpu401 instance 141 * @regs: the reigster 142 * 143 * Processes the interrupt for MPU401-UART output. 144 */ 145 irqreturn_t snd_mpu401_uart_interrupt_tx(int irq, void *dev_id, 146 struct pt_regs *regs) 147 { 148 struct snd_mpu401 *mpu = dev_id; 149 150 if (mpu == NULL) 151 return IRQ_NONE; 152 uart_interrupt_tx(mpu); 153 return IRQ_HANDLED; 154 } 155 156 EXPORT_SYMBOL(snd_mpu401_uart_interrupt_tx); 128 157 129 158 /* … … 327 356 unsigned char byte; 328 357 329 while (max-- > 0) { 330 if (snd_mpu401_input_avail(mpu)) { 331 byte = mpu->read(mpu, MPU401D(mpu)); 332 if (test_bit(MPU401_MODE_BIT_INPUT_TRIGGER, &mpu->mode)) 333 snd_rawmidi_receive(mpu->substream_input, &byte, 1); 334 } else { 335 break; /* input not available */ 336 } 358 while (max-- > 0) { 359 if (! snd_mpu401_input_avail(mpu)) 360 break; /* input not available */ 361 byte = mpu->read(mpu, MPU401D(mpu)); 362 if (test_bit(MPU401_MODE_BIT_INPUT_TRIGGER, &mpu->mode)) 363 snd_rawmidi_receive(mpu->substream_input, &byte, 1); 337 364 } 338 365 } … … 355 382 int max = 256, timeout; 356 383 357 do {358 if (snd_rawmidi_transmit_peek(mpu->substream_output, &byte, 1) == 1) { 359 for (timeout = 100; timeout > 0; timeout--) {360 if (snd_mpu401_output_ready(mpu)) {361 mpu->write(mpu, byte, MPU401D(mpu)); 362 snd_rawmidi_transmit_ack(mpu->substream_output, 1);363 break; 364 } 365 } 366 if (timeout == 0) 367 break; /* Tx FIFO full - try again later */ 368 } else {369 snd_mpu401_uart_remove_timer (mpu, 0);370 break; /* no other data - leave the tx loop */371 }384 do { 385 if (snd_rawmidi_transmit_peek(mpu->substream_output, 386 &byte, 1) == 1) { 387 for (timeout = 100; timeout > 0; timeout--) { 388 if (snd_mpu401_output_ready(mpu)) 389 break; 390 } 391 if (timeout == 0) 392 break; /* Tx FIFO full - try again later */ 393 mpu->write(mpu, byte, MPU401D(mpu)); 394 snd_rawmidi_transmit_ack(mpu->substream_output, 1); 395 } else { 396 snd_mpu401_uart_remove_timer (mpu, 0); 397 break; /* no other data - leave the tx loop */ 398 } 372 399 } while (--max > 0); 373 400 } … … 388 415 * since the output timer might have been removed in 389 416 * snd_mpu401_uart_output_write(). 390 */391 snd_mpu401_uart_add_timer(mpu, 0); 392 417 */ 418 if (! (mpu->info_flags & MPU401_INFO_TX_IRQ)) 419 snd_mpu401_uart_add_timer(mpu, 0); 393 420 /* output pending data */ 394 421 spin_lock_irqsave(&mpu->output_lock, flags); 395 422 snd_mpu401_uart_output_write(mpu); 396 423 spin_unlock_irqrestore(&mpu->output_lock, flags); 397 } else { 398 snd_mpu401_uart_remove_timer(mpu, 0); 399 clear_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode); 424 } else { 425 if (! (mpu->info_flags & MPU401_INFO_TX_IRQ)) 426 snd_mpu401_uart_remove_timer(mpu, 0); 427 clear_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode); 400 428 } 401 429 } … … 437 465 * @hardware: the hardware type, MPU401_HW_XXXX 438 466 * @port: the base address of MPU401 port 439 * @in tegrated: non-zero if the port was already reserved by the chip467 * @info_flags: bitflags MPU401_INFO_XXX 440 468 * @irq: the irq number, -1 if no interrupt for mpu 441 469 * @irq_flags: the irq request flags (SA_XXX), 0 if irq was already reserved. … … 451 479 */ 452 480 int snd_mpu401_uart_new(struct snd_card *card, int device, 453 unsigned short hardware, 454 unsigned long port, int integrated, 481 unsigned short hardware, 482 unsigned long port, 483 unsigned int info_flags, 455 484 int irq, int irq_flags, 456 485 struct snd_rawmidi ** rrawmidi) 457 486 { 458 487 struct snd_mpu401 *mpu; 459 struct snd_rawmidi *rmidi; 488 struct snd_rawmidi *rmidi; 489 int in_enable, out_enable; 460 490 int err; 461 491 462 492 if (rrawmidi) 463 *rrawmidi = NULL; 464 if ((err = snd_rawmidi_new(card, "MPU-401U", device, 1, 1, &rmidi)) < 0) 465 return err; 493 *rrawmidi = NULL; 494 if (! (info_flags & (MPU401_INFO_INPUT | MPU401_INFO_OUTPUT))) 495 info_flags |= MPU401_INFO_INPUT | MPU401_INFO_OUTPUT; 496 in_enable = (info_flags & MPU401_INFO_INPUT) ? 1 : 0; 497 out_enable = (info_flags & MPU401_INFO_OUTPUT) ? 1 : 0; 498 if ((err = snd_rawmidi_new(card, "MPU-401U", device, 499 out_enable, in_enable, &rmidi)) < 0) 500 return err; 466 501 mpu = (struct snd_mpu401 *)kzalloc(sizeof(*mpu), GFP_KERNEL); 467 502 if (mpu == NULL) { … … 475 510 spin_lock_init(&mpu->output_lock); 476 511 spin_lock_init(&mpu->timer_lock); 477 mpu->hardware = hardware;478 if (!integrated) {512 mpu->hardware = hardware; 513 if (! (info_flags & MPU401_INFO_INTEGRATED)) { 479 514 int res_size = hardware == MPU401_HW_PC98II ? 4 : 2; 480 515 if ((mpu->res = request_region(port, res_size, "MPU401 UART")) == NULL) { … … 483 518 return -EBUSY; 484 519 } 485 } 486 switch (hardware) { 487 case MPU401_HW_AUREAL: 520 } 521 if (info_flags & MPU401_INFO_MMIO) { 488 522 mpu->write = mpu401_write_mmio; 489 mpu->read = mpu401_read_mmio; 490 break; 491 default: 523 mpu->read = mpu401_read_mmio; 524 } else { 492 525 mpu->write = mpu401_write_port; 493 526 mpu->read = mpu401_read_port; 494 break;495 527 } 496 528 mpu->port = port; … … 505 537 return -EBUSY; 506 538 } 507 } 539 } 540 mpu->info_flags = info_flags; 508 541 mpu->irq = irq; 509 542 mpu->irq_flags = irq_flags; … … 511 544 sprintf(rmidi->name, "%s MIDI", card->shortname); 512 545 else 513 sprintf(rmidi->name, "MPU-401 MIDI %d-%d", card->number, device); 514 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_mpu401_uart_output); 515 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_mpu401_uart_input); 516 rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | 517 SNDRV_RAWMIDI_INFO_INPUT | 518 SNDRV_RAWMIDI_INFO_DUPLEX; 519 mpu->rmidi = rmidi; 546 sprintf(rmidi->name, "MPU-401 MIDI %d-%d", card->number, device); 547 if (out_enable) { 548 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, 549 &snd_mpu401_uart_output); 550 rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT; 551 } 552 if (in_enable) { 553 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, 554 &snd_mpu401_uart_input); 555 rmidi->info_flags |= SNDRV_RAWMIDI_INFO_INPUT; 556 if (out_enable) 557 rmidi->info_flags |= SNDRV_RAWMIDI_INFO_DUPLEX; 558 } 559 mpu->rmidi = rmidi; 520 560 if (rrawmidi) 521 561 *rrawmidi = rmidi; -
GPL/trunk/alsa-kernel/include/sound/ac97_codec.h
r76 r77 32 32 #include "info.h" 33 33 34 #define CONFIG_SND_AC97_POWER_SAVE /* experimental !!! */ 34 35 /* 35 36 * AC'97 codec registers … … 141 142 #define AC97_GP_DRSS_78 0x0400 /* LR 7+8 */ 142 143 144 /* powerdown bits */ 145 #define AC97_PD_ADC_STATUS 0x0001 /* ADC status (RO) */ 146 #define AC97_PD_DAC_STATUS 0x0002 /* DAC status (RO) */ 147 #define AC97_PD_MIXER_STATUS 0x0004 /* Analog mixer status (RO) */ 148 #define AC97_PD_VREF_STATUS 0x0008 /* Vref status (RO) */ 149 #define AC97_PD_PR0 0x0100 /* Power down PCM ADCs and input MUX */ 150 #define AC97_PD_PR1 0x0200 /* Power down PCM front DAC */ 151 #define AC97_PD_PR2 0x0400 /* Power down Mixer (Vref still on) */ 152 #define AC97_PD_PR3 0x0800 /* Power down Mixer (Vref off) */ 153 #define AC97_PD_PR4 0x1000 /* Power down AC-Link */ 154 #define AC97_PD_PR5 0x2000 /* Disable internal clock usage */ 155 #define AC97_PD_PR6 0x4000 /* Headphone amplifier */ 156 #define AC97_PD_EAPD 0x8000 /* External Amplifer Power Down (EAPD) */ 157 143 158 /* extended audio ID bit defines */ 144 159 #define AC97_EI_VRA 0x0001 /* Variable bit rate supported */ … … 266 281 /* specific - Analog Devices */ 267 282 #define AC97_AD_TEST 0x5a /* test register */ 283 #define AC97_AD_TEST2 0x5c /* undocumented test register 2 */ 268 284 #define AC97_AD_CODEC_CFG 0x70 /* codec configuration */ 269 285 #define AC97_AD_JACK_SPDIF 0x72 /* Jack Sense & S/PDIF */ … … 359 375 #define AC97_SCAP_DETECT_BY_VENDOR (1<<8) /* use vendor registers for read tests */ 360 376 #define AC97_SCAP_NO_SPDIF (1<<9) /* don't build SPDIF controls */ 377 #define AC97_SCAP_EAPD_LED (1<<10) /* EAPD as mute LED */ 361 378 362 379 /* ac97->flags */ … … 379 396 #define AC97_HAS_NO_TONE (1<<16) /* no Tone volume */ 380 397 #define AC97_HAS_NO_STD_PCM (1<<17) /* no standard AC97 PCM volume and mute */ 398 #define AC97_HAS_NO_AUX (1<<18) /* no standard AC97 AUX volume and mute */ 381 399 382 400 /* rates indexes */ … … 489 507 /* jack-sharing info */ 490 508 unsigned char indep_surround; 491 unsigned char channel_mode; 509 unsigned char channel_mode; 510 511 #ifdef CONFIG_SND_AC97_POWER_SAVE 512 unsigned int power_up; /* power states */ 513 struct workqueue_struct *power_workq; 514 struct work_struct power_work; 515 #endif 492 516 struct device dev; 493 517 }; … … 531 555 int snd_ac97_update(struct snd_ac97 *ac97, unsigned short reg, unsigned short value); 532 556 int snd_ac97_update_bits(struct snd_ac97 *ac97, unsigned short reg, unsigned short mask, unsigned short value); 557 #ifdef CONFIG_SND_AC97_POWER_SAVE 558 int snd_ac97_update_power(struct snd_ac97 *ac97, int reg, int powerup); 559 #else 560 static inline int snd_ac97_update_power(struct snd_ac97 *ac97, int reg, 561 int powerup) 562 { 563 return 0; 564 } 565 #endif 533 566 #ifdef CONFIG_PM 534 567 void snd_ac97_suspend(struct snd_ac97 *ac97); … … 588 621 unsigned int spdif; /* spdif pcm */ 589 622 #endif 590 unsigned short aslots; /* active slots */ 591 unsigned int rates; /* available rates */ 623 unsigned short aslots; /* active slots */ 624 unsigned short cur_dbl; /* current double-rate state */ 625 unsigned int rates; /* available rates */ 592 626 struct { 593 627 unsigned short slots; /* driver input: requested AC97 slot numbers */ -
GPL/trunk/alsa-kernel/include/sound/asound.h
r36 r77 714 714 ****************************************************************************/ 715 715 716 #define SNDRV_CTL_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 3)716 #define SNDRV_CTL_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 4) 717 717 718 718 struct snd_ctl_card_info { … … 844 844 }; 845 845 846 struct snd_ctl_tlv { 847 unsigned int numid; /* control element numeric identification */ 848 unsigned int length; /* in bytes aligned to 4 */ 849 unsigned int tlv[1]; /* first TLV */ 850 }; 851 846 852 enum { 847 853 SNDRV_CTL_IOCTL_PVERSION = _IOR('U', 0x00, int), … … 856 862 SNDRV_CTL_IOCTL_ELEM_ADD = _IOWR('U', 0x17, struct snd_ctl_elem_info), 857 863 SNDRV_CTL_IOCTL_ELEM_REPLACE = _IOWR('U', 0x18, struct snd_ctl_elem_info), 858 SNDRV_CTL_IOCTL_ELEM_REMOVE = _IOWR('U', 0x19, struct snd_ctl_elem_id), 864 SNDRV_CTL_IOCTL_ELEM_REMOVE = _IOWR('U', 0x19, struct snd_ctl_elem_id), 865 SNDRV_CTL_IOCTL_TLV_READ = _IOWR('U', 0x1a, struct snd_ctl_tlv), 859 866 SNDRV_CTL_IOCTL_HWDEP_NEXT_DEVICE = _IOWR('U', 0x20, int), 860 867 SNDRV_CTL_IOCTL_HWDEP_INFO = _IOR('U', 0x21, struct snd_hwdep_info), -
GPL/trunk/alsa-kernel/include/sound/compat_22.h
r32 r77 122 122 #define list_for_each_safe(pos, npos, head) \ 123 123 for (pos = (head)->next, npos = pos->next ; pos != (head); pos = npos, npos = pos->next) 124 125 /** 126 * list_for_each_entry - iterate over list of given type 127 * @pos: the type * to use as a loop counter. 128 * @head: the head for your list. 129 * @member: the name of the list_struct within the struct. 130 */ 131 #define list_for_each_entry(pos, head, member) \ 132 for (pos = list_entry((head)->next, typeof(*pos), member); \ 133 pos->member.next, &pos->member != (head); \ 134 pos = list_entry(pos->member.next, typeof(*pos), member)) 124 135 125 136 #ifndef IORESOURCE_IO -
GPL/trunk/alsa-kernel/include/sound/control.h
r32 r77 40 40 snd_kcontrol_get_t *get; 41 41 snd_kcontrol_put_t *put; 42 unsigned int *tlv; 42 43 unsigned long private_value; 43 44 }; … … 55 56 snd_kcontrol_info_t *info; 56 57 snd_kcontrol_get_t *get; 57 snd_kcontrol_put_t *put; 58 snd_kcontrol_put_t *put; 59 unsigned int *tlv; 58 60 unsigned long private_value; 59 61 #ifdef TARGET_OS2 -
GPL/trunk/alsa-kernel/include/sound/mpu401.h
r32 r77 46 46 #define MPU401_HW_AUREAL 19 /* Aureal Vortex */ 47 47 48 #define MPU401_INFO_INPUT (1 << 0) /* input stream */ 49 #define MPU401_INFO_OUTPUT (1 << 1) /* output stream */ 50 #define MPU401_INFO_INTEGRATED (1 << 2) /* integrated h/w port */ 51 #define MPU401_INFO_MMIO (1 << 3) /* MMIO access */ 52 #define MPU401_INFO_TX_IRQ (1 << 4) /* independent TX irq */ 53 48 54 #define MPU401_MODE_BIT_INPUT 0 49 55 #define MPU401_MODE_BIT_OUTPUT 1 … … 62 68 struct snd_rawmidi *rmidi; 63 69 64 unsigned short hardware; /* MPU401_HW_XXXX */ 70 unsigned short hardware; /* MPU401_HW_XXXX */ 71 unsigned int info_flags; /* MPU401_INFO_XXX */ 65 72 unsigned long port; /* base port of MPU-401 chip */ 66 73 unsigned long cport; /* port + 1 (usually) */ … … 100 107 */ 101 108 102 irqreturn_t snd_mpu401_uart_interrupt(int irq, void *dev_id, struct pt_regs *regs); 109 irqreturn_t snd_mpu401_uart_interrupt(int irq, void *dev_id, 110 struct pt_regs *regs); 111 irqreturn_t snd_mpu401_uart_interrupt_tx(int irq, void *dev_id, 112 struct pt_regs *regs); 103 113 104 114 int snd_mpu401_uart_new(struct snd_card *card, 105 115 int device, 106 116 unsigned short hardware, 107 unsigned long port,108 int integrated,117 unsigned long port, 118 unsigned int info_flags, 109 119 int irq, 110 120 int irq_flags, -
GPL/trunk/alsa-kernel/pci/ac97/ac97_codec.c
r76 r77 47 47 MODULE_PARM_DESC(enable_loopback, "Enable AC97 ADC/DAC Loopback Control"); 48 48 49 #ifdef CONFIG_SND_AC97_POWER_SAVE 50 static int power_save = 1; 51 //module_param(power_save, bool, 0644); 52 MODULE_PARM_DESC(power_save, "Enable AC97 power-saving control"); 53 #endif 49 54 /* 50 55 … … 152 157 { 0x4e534350, 0xffffffff, "LM4550", NULL, NULL }, 153 158 { 0x4e534350, 0xffffffff, "LM4550", patch_lm4550, NULL }, // volume wrap fix 154 { 0x50534304, 0xffffffff, "UCB1400", NULL,NULL },159 { 0x50534304, 0xffffffff, "UCB1400", patch_ucb1400, NULL }, 155 160 { 0x53494c20, 0xffffffe0, "Si3036,8", mpatch_si3036, mpatch_si3036, AC97_MODEM_PATCH }, 156 161 { 0x54524102, 0xffffffff, "TR28022", NULL, NULL }, … … 186 191 }; 187 192 193 static void update_power_regs(struct snd_ac97 *ac97); 188 194 189 195 /* … … 543 549 } 544 550 err = snd_ac97_update_bits(ac97, reg, val_mask, val); 545 snd_ac97_page_restore(ac97, page_save); 551 snd_ac97_page_restore(ac97, page_save); 552 #ifdef CONFIG_SND_AC97_POWER_SAVE 553 /* check analog mixer power-down */ 554 if ((val_mask & 0x8000) && 555 (kcontrol->private_value & (1<<30))) { 556 if (val & 0x8000) 557 ac97->power_up &= ~(1 << (reg>>1)); 558 else 559 ac97->power_up |= 1 << (reg>>1); 560 if (power_save) 561 update_power_regs(ac97); 562 } 563 #endif 546 564 return err; 547 565 } … … 951 969 static int snd_ac97_free(struct snd_ac97 *ac97) 952 970 { 953 if (ac97) { 954 snd_ac97_proc_done(ac97); 955 if (ac97->bus) 956 ac97->bus->codec[ac97->num] = NULL; 957 if (ac97->private_free) 958 ac97->private_free(ac97); 959 kfree(ac97); 960 } 961 return 0; 971 if (ac97) { 972 #ifdef CONFIG_SND_AC97_POWER_SAVE 973 if (ac97->power_workq) 974 destroy_workqueue(ac97->power_workq); 975 #endif 976 snd_ac97_proc_done(ac97); 977 if (ac97->bus) 978 ac97->bus->codec[ac97->num] = NULL; 979 if (ac97->private_free) 980 ac97->private_free(ac97); 981 kfree(ac97); 982 } 983 return 0; 962 984 } 963 985 … … 1107 1129 * create mute switch(es) for normal stereo controls 1108 1130 */ 1109 static int snd_ac97_cmute_new_stereo(struct snd_card *card, char *name, int reg, int check_stereo, struct snd_ac97 *ac97) 1131 static int snd_ac97_cmute_new_stereo(struct snd_card *card, char *name, int reg, 1132 int check_stereo, int check_amix, 1133 struct snd_ac97 *ac97) 1110 1134 { 1111 1135 struct snd_kcontrol *kctl; … … 1135 1159 if (mute_mask == 0x8080) { 1136 1160 tmp.private_value = reg | (15 << 8) | (7 << 12) | (1 << 16) | (1 << 24); 1161 if (check_amix) 1162 tmp.private_value |= (1 << 30); 1137 1163 } else { 1138 1164 tmp.private_value = reg | (15 << 8) | (1 << 16) | (1 << 24); 1165 if (check_amix) 1166 tmp.private_value |= (1 << 30); 1139 1167 } 1140 1168 kctl = snd_ctl_new1(&tmp, ac97); … … 1212 1240 * create a mute-switch and a volume for normal stereo/mono controls 1213 1241 */ 1214 static int snd_ac97_cmix_new_stereo(struct snd_card *card, const char *pfx, int reg, int check_stereo, struct snd_ac97 *ac97) 1242 static int snd_ac97_cmix_new_stereo(struct snd_card *card, const char *pfx, 1243 int reg, int check_stereo, int check_amix, 1244 struct snd_ac97 *ac97) 1215 1245 { 1216 1246 int err; … … 1222 1252 1223 1253 if (snd_ac97_try_bit(ac97, reg, 15)) { 1224 sprintf(name, "%s Switch", pfx); 1225 if ((err = snd_ac97_cmute_new_stereo(card, name, reg, check_stereo, ac97)) < 0) 1254 sprintf(name, "%s Switch", pfx); 1255 if ((err = snd_ac97_cmute_new_stereo(card, name, reg, 1256 check_stereo, check_amix, 1257 ac97)) < 0) 1226 1258 return err; 1227 1259 } … … 1235 1267 } 1236 1268 1237 #define snd_ac97_cmix_new(card, pfx, reg, ac97) snd_ac97_cmix_new_stereo(card, pfx, reg, 0, ac97) 1238 #define snd_ac97_cmute_new(card, name, reg, ac97) snd_ac97_cmute_new_stereo(card, name, reg, 0, ac97) 1269 #define snd_ac97_cmix_new(card, pfx, reg, acheck, ac97) \ 1270 snd_ac97_cmix_new_stereo(card, pfx, reg, 0, acheck, ac97) 1271 #define snd_ac97_cmute_new(card, name, reg, acheck, ac97) \ 1272 snd_ac97_cmute_new_stereo(card, name, reg, 0, acheck, ac97) 1239 1273 1240 1274 static unsigned int snd_ac97_determine_spdif_rates(struct snd_ac97 *ac97); … … 1252 1286 if (snd_ac97_try_volume_mix(ac97, AC97_MASTER)) { 1253 1287 #ifndef TARGET_OS2 1254 if (ac97->flags & AC97_HAS_NO_MASTER_VOL) 1255 err = snd_ac97_cmute_new(card, "Master Playback Switch", AC97_MASTER, ac97); 1256 else 1288 if (ac97->flags & AC97_HAS_NO_MASTER_VOL) 1289 err = snd_ac97_cmute_new(card, "Master Playback Switch", 1290 AC97_MASTER, 0, ac97); 1291 else 1257 1292 #endif 1258 err = snd_ac97_cmix_new(card, "Master Playback", AC97_MASTER, ac97); 1259 if (err < 0) 1260 return err; 1293 err = snd_ac97_cmix_new(card, "Master Playback", 1294 AC97_MASTER, 0, ac97); 1295 if (err < 0) 1296 return err; 1261 1297 } 1262 1298 1263 1299 ac97->regs[AC97_CENTER_LFE_MASTER] = 0x8080; 1264 1300 1265 /* build center controls */ 1266 if (snd_ac97_try_volume_mix(ac97, AC97_CENTER_LFE_MASTER)) { 1301 /* build center controls */ 1302 if ((snd_ac97_try_volume_mix(ac97, AC97_CENTER_LFE_MASTER)) 1303 && !(ac97->flags & AC97_AD_MULTI)) { 1267 1304 if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_center[0], ac97))) < 0) 1268 1305 return err; … … 1275 1312 } 1276 1313 1277 /* build LFE controls */ 1278 if (snd_ac97_try_volume_mix(ac97, AC97_CENTER_LFE_MASTER+1)) { 1314 /* build LFE controls */ 1315 if ((snd_ac97_try_volume_mix(ac97, AC97_CENTER_LFE_MASTER+1)) 1316 && !(ac97->flags & AC97_AD_MULTI)) { 1279 1317 if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_lfe[0], ac97))) < 0) 1280 1318 return err; … … 1287 1325 } 1288 1326 1289 /* build surround controls */ 1290 if (snd_ac97_try_volume_mix(ac97, AC97_SURROUND_MASTER)) { 1291 /* Surround Master (0x38) is with stereo mutes */ 1292 if ((err = snd_ac97_cmix_new_stereo(card, "Surround Playback", AC97_SURROUND_MASTER, 1, ac97)) < 0) 1327 /* build surround controls */ 1328 if ((snd_ac97_try_volume_mix(ac97, AC97_SURROUND_MASTER)) 1329 && !(ac97->flags & AC97_AD_MULTI)) { 1330 /* Surround Master (0x38) is with stereo mutes */ 1331 if ((err = snd_ac97_cmix_new_stereo(card, "Surround Playback", 1332 AC97_SURROUND_MASTER, 1, 0, 1333 ac97)) < 0) 1293 1334 return err; 1294 1335 } 1295 1336 1296 1337 /* build headphone controls */ 1297 if (snd_ac97_try_volume_mix(ac97, AC97_HEADPHONE)) { 1298 if ((err = snd_ac97_cmix_new(card, "Headphone Playback", AC97_HEADPHONE, ac97)) < 0) 1299 return err; 1338 if (snd_ac97_try_volume_mix(ac97, AC97_HEADPHONE)) { 1339 if ((err = snd_ac97_cmix_new(card, "Headphone Playback", 1340 AC97_HEADPHONE, 0, ac97)) < 0) 1341 return err; 1300 1342 } 1301 1343 1302 1344 /* build master mono controls */ 1303 if (snd_ac97_try_volume_mix(ac97, AC97_MASTER_MONO)) { 1304 if ((err = snd_ac97_cmix_new(card, "Master Mono Playback", AC97_MASTER_MONO, ac97)) < 0) 1305 return err; 1345 if (snd_ac97_try_volume_mix(ac97, AC97_MASTER_MONO)) { 1346 if ((err = snd_ac97_cmix_new(card, "Master Mono Playback", 1347 AC97_MASTER_MONO, 0, ac97)) < 0) 1348 return err; 1306 1349 } 1307 1350 … … 1334 1377 /* build Phone controls */ 1335 1378 if (!(ac97->flags & AC97_HAS_NO_PHONE)) { 1336 if (snd_ac97_try_volume_mix(ac97, AC97_PHONE)) { 1337 if ((err = snd_ac97_cmix_new(card, "Phone Playback", AC97_PHONE, ac97)) < 0) 1338 return err; 1339 } 1340 } 1379 if (snd_ac97_try_volume_mix(ac97, AC97_PHONE)) { 1380 if ((err = snd_ac97_cmix_new(card, "Phone Playback", 1381 AC97_PHONE, 1, ac97)) < 0) 1382 return err; 1383 } 1384 } 1341 1385 1342 1386 /* build MIC controls */ 1343 1387 if (!(ac97->flags & AC97_HAS_NO_MIC)) { 1344 if (snd_ac97_try_volume_mix(ac97, AC97_MIC)) { 1345 if ((err = snd_ac97_cmix_new(card, "Mic Playback", AC97_MIC, ac97)) < 0) 1346 return err; 1347 if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_mic_boost, ac97))) < 0) 1348 return err; 1349 } 1350 } 1388 if (snd_ac97_try_volume_mix(ac97, AC97_MIC)) { 1389 if ((err = snd_ac97_cmix_new(card, "Mic Playback", 1390 AC97_MIC, 1, ac97)) < 0) 1391 return err; 1392 if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_mic_boost, ac97))) < 0) 1393 return err; 1394 } 1395 } 1351 1396 1352 1397 /* build Line controls */ 1353 if (snd_ac97_try_volume_mix(ac97, AC97_LINE)) { 1354 if ((err = snd_ac97_cmix_new(card, "Line Playback", AC97_LINE, ac97)) < 0) 1355 return err; 1398 if (snd_ac97_try_volume_mix(ac97, AC97_LINE)) { 1399 if ((err = snd_ac97_cmix_new(card, "Line Playback", 1400 AC97_LINE, 1, ac97)) < 0) 1401 return err; 1356 1402 } 1357 1403 1358 1404 /* build CD controls */ 1359 1405 if (!(ac97->flags & AC97_HAS_NO_CD)) { 1360 if (snd_ac97_try_volume_mix(ac97, AC97_CD)) { 1361 if ((err = snd_ac97_cmix_new(card, "CD Playback", AC97_CD, ac97)) < 0) 1362 return err; 1363 } 1364 } 1406 if (snd_ac97_try_volume_mix(ac97, AC97_CD)) { 1407 if ((err = snd_ac97_cmix_new(card, "CD Playback", 1408 AC97_CD, 1, ac97)) < 0) 1409 return err; 1410 } 1411 } 1365 1412 1366 1413 /* build Video controls */ 1367 1414 if (!(ac97->flags & AC97_HAS_NO_VIDEO)) { 1368 if (snd_ac97_try_volume_mix(ac97, AC97_VIDEO)) { 1369 if ((err = snd_ac97_cmix_new(card, "Video Playback", AC97_VIDEO, ac97)) < 0) 1370 return err; 1371 } 1372 } 1373 1374 /* build Aux controls */ 1375 if (snd_ac97_try_volume_mix(ac97, AC97_AUX)) { 1376 if ((err = snd_ac97_cmix_new(card, "Aux Playback", AC97_AUX, ac97)) < 0) 1377 return err; 1415 if (snd_ac97_try_volume_mix(ac97, AC97_VIDEO)) { 1416 if ((err = snd_ac97_cmix_new(card, "Video Playback", 1417 AC97_VIDEO, 1, ac97)) < 0) 1418 return err; 1419 } 1420 } 1421 1422 /* build Aux controls */ 1423 if (!(ac97->flags & AC97_HAS_NO_AUX)) { 1424 if (snd_ac97_try_volume_mix(ac97, AC97_AUX)) { 1425 if ((err = snd_ac97_cmix_new(card, "Aux Playback", 1426 AC97_AUX, 1, ac97)) < 0) 1427 return err; 1428 } 1378 1429 } 1379 1430 … … 1408 1459 if (!(ac97->flags & AC97_HAS_NO_STD_PCM)) { 1409 1460 #ifndef TARGET_OS2 1410 if (ac97->flags & AC97_HAS_NO_PCM_VOL) 1411 err = snd_ac97_cmute_new(card, "PCM Playback Switch", AC97_PCM, ac97); 1412 else 1461 if (ac97->flags & AC97_HAS_NO_PCM_VOL) 1462 err = snd_ac97_cmute_new(card, 1463 "PCM Playback Switch", 1464 AC97_PCM, 0, ac97); 1465 else 1413 1466 #endif 1414 err = snd_ac97_cmix_new(card, "PCM Playback", AC97_PCM, ac97); 1415 if (err < 0) 1416 return err; 1417 } 1467 err = snd_ac97_cmix_new(card, "PCM Playback", 1468 AC97_PCM, 0, ac97); 1469 if (err < 0) 1470 return err; 1471 } 1418 1472 } 1419 1473 … … 1422 1476 if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_control_capture_src, ac97))) < 0) 1423 1477 return err; 1424 if (snd_ac97_try_bit(ac97, AC97_REC_GAIN, 15)) { 1425 if ((err = snd_ac97_cmute_new(card, "Capture Switch", AC97_REC_GAIN, ac97)) < 0) 1426 return err; 1478 if (snd_ac97_try_bit(ac97, AC97_REC_GAIN, 15)) { 1479 err = snd_ac97_cmute_new(card, "Capture Switch", 1480 AC97_REC_GAIN, 0, ac97); 1481 if (err < 0) 1482 return err; 1427 1483 } 1428 1484 if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_control_capture_vol, ac97))) < 0) … … 1858 1914 static struct snd_ac97_build_ops null_build_ops; 1859 1915 1916 #ifdef CONFIG_SND_AC97_POWER_SAVE 1917 static void do_update_power(void *data) 1918 { 1919 update_power_regs(data); 1920 } 1921 #endif 1922 1860 1923 /** 1861 1924 * snd_ac97_mixer - create an Codec97 component … … 1912 1975 init_MUTEX(&ac97->reg_mutex); 1913 1976 init_MUTEX(&ac97->page_mutex); 1914 1977 #ifdef CONFIG_SND_AC97_POWER_SAVE 1978 ac97->power_workq = create_workqueue("ac97"); 1979 INIT_WORK(&ac97->power_work, do_update_power, ac97); 1980 #endif 1915 1981 #ifdef CONFIG_PCI 1916 1982 if (ac97->pci) { … … 2146 2212 } 2147 2213 } 2148 /* make sure the proper powerdown bits are cleared */ 2149 if (ac97->scaps && ac97_is_audio(ac97)) { 2150 reg = snd_ac97_read(ac97, AC97_EXTENDED_STATUS); 2151 if (ac97->scaps & AC97_SCAP_SURROUND_DAC) 2152 reg &= ~AC97_EA_PRJ; 2153 if (ac97->scaps & AC97_SCAP_CENTER_LFE_DAC) 2154 reg &= ~(AC97_EA_PRI | AC97_EA_PRK); 2155 snd_ac97_write_cache(ac97, AC97_EXTENDED_STATUS, reg); 2156 } 2214 /* make sure the proper powerdown bits are cleared */ 2215 if (ac97_is_audio(ac97)) 2216 update_power_regs(ac97); 2157 2217 snd_ac97_proc_init(ac97); 2158 2218 if ((err = snd_device_new(card, SNDRV_DEV_CODEC, ac97, &ops)) < 0) { … … 2181 2241 } 2182 2242 2183 power = ac97->regs[AC97_POWERDOWN] | 0x8000; /* EAPD */ 2184 power |= 0x4000; /* Headphone amplifier powerdown */ 2185 power |= 0x0300; /* ADC & DAC powerdown */ 2243 /* surround, CLFE, mic powerdown */ 2244 power = ac97->regs[AC97_EXTENDED_STATUS]; 2245 if (ac97->scaps & AC97_SCAP_SURROUND_DAC) 2246 power |= AC97_EA_PRJ; 2247 if (ac97->scaps & AC97_SCAP_CENTER_LFE_DAC) 2248 power |= AC97_EA_PRI | AC97_EA_PRK; 2249 power |= AC97_EA_PRL; 2250 snd_ac97_write(ac97, AC97_EXTENDED_STATUS, power); 2251 2252 /* powerdown external amplifier */ 2253 if (ac97->scaps & AC97_SCAP_INV_EAPD) 2254 power = ac97->regs[AC97_POWERDOWN] & ~AC97_PD_EAPD; 2255 else if (! (ac97->scaps & AC97_SCAP_EAPD_LED)) 2256 power = ac97->regs[AC97_POWERDOWN] | AC97_PD_EAPD; 2257 power |= AC97_PD_PR6; /* Headphone amplifier powerdown */ 2258 power |= AC97_PD_PR0 | AC97_PD_PR1; /* ADC & DAC powerdown */ 2186 2259 snd_ac97_write(ac97, AC97_POWERDOWN, power); 2187 2260 udelay(100); 2188 power |= 0x0400; /* Analog Mixer powerdown (Vref on) */ 2189 snd_ac97_write(ac97, AC97_POWERDOWN, power); 2190 udelay(100); 2191 #if 0 2192 /* FIXME: this causes click noises on some boards at resume */ 2193 power |= 0x3800; /* AC-link powerdown, internal Clk disable */ 2194 snd_ac97_write(ac97, AC97_POWERDOWN, power); 2261 power |= AC97_PD_PR2 | AC97_PD_PR3; /* Analog Mixer powerdown */ 2262 snd_ac97_write(ac97, AC97_POWERDOWN, power); 2263 #ifdef CONFIG_SND_AC97_POWER_SAVE 2264 if (power_save) { 2265 udelay(100); 2266 /* AC-link powerdown, internal Clk disable */ 2267 /* FIXME: this may cause click noises on some boards */ 2268 power |= AC97_PD_PR4 | AC97_PD_PR5; 2269 snd_ac97_write(ac97, AC97_POWERDOWN, power); 2270 } 2195 2271 #endif 2196 2272 } 2197 2273 2274 2275 struct ac97_power_reg { 2276 unsigned short reg; 2277 unsigned short power_reg; 2278 unsigned short mask; 2279 }; 2280 2281 enum { PWIDX_ADC, PWIDX_FRONT, PWIDX_CLFE, PWIDX_SURR, PWIDX_MIC, PWIDX_SIZE }; 2282 2283 static struct ac97_power_reg power_regs[PWIDX_SIZE] = { 2284 [PWIDX_ADC] = { AC97_PCM_LR_ADC_RATE, AC97_POWERDOWN, AC97_PD_PR0}, 2285 [PWIDX_FRONT] = { AC97_PCM_FRONT_DAC_RATE, AC97_POWERDOWN, AC97_PD_PR1}, 2286 [PWIDX_CLFE] = { AC97_PCM_LFE_DAC_RATE, AC97_EXTENDED_STATUS, 2287 AC97_EA_PRI | AC97_EA_PRK}, 2288 [PWIDX_SURR] = { AC97_PCM_SURR_DAC_RATE, AC97_EXTENDED_STATUS, 2289 AC97_EA_PRJ}, 2290 [PWIDX_MIC] = { AC97_PCM_MIC_ADC_RATE, AC97_EXTENDED_STATUS, 2291 AC97_EA_PRL}, 2292 }; 2293 2294 #ifdef CONFIG_SND_AC97_POWER_SAVE 2295 /** 2296 * snd_ac97_update_power - update the powerdown register 2297 * @ac97: the codec instance 2298 * @reg: the rate register, e.g. AC97_PCM_FRONT_DAC_RATE 2299 * @powerup: non-zero when power up the part 2300 * 2301 * Update the AC97 powerdown register bits of the given part. 2302 */ 2303 int snd_ac97_update_power(struct snd_ac97 *ac97, int reg, int powerup) 2304 { 2305 int i; 2306 2307 if (! ac97) 2308 return 0; 2309 2310 if (reg) { 2311 /* SPDIF requires DAC power, too */ 2312 if (reg == AC97_SPDIF) 2313 reg = AC97_PCM_FRONT_DAC_RATE; 2314 for (i = 0; i < PWIDX_SIZE; i++) { 2315 if (power_regs[i].reg == reg) { 2316 if (powerup) 2317 ac97->power_up |= (1 << i); 2318 else 2319 ac97->power_up &= ~(1 << i); 2320 break; 2321 } 2322 } 2323 } 2324 2325 if (! power_save) 2326 return 0; 2327 2328 if (! powerup && ac97->power_workq) 2329 /* adjust power-down bits after two seconds delay 2330 * (for avoiding loud click noises for many (OSS) apps 2331 * that open/close frequently) 2332 */ 2333 queue_delayed_work(ac97->power_workq, &ac97->power_work, HZ*2); 2334 else 2335 update_power_regs(ac97); 2336 2337 return 0; 2338 } 2339 2340 EXPORT_SYMBOL(snd_ac97_update_power); 2341 #endif /* CONFIG_SND_AC97_POWER_SAVE */ 2342 2343 static void update_power_regs(struct snd_ac97 *ac97) 2344 { 2345 unsigned int power_up, bits; 2346 int i; 2347 2348 #ifdef CONFIG_SND_AC97_POWER_SAVE 2349 if (power_save) 2350 power_up = ac97->power_up; 2351 else { 2352 #endif 2353 power_up = (1 << PWIDX_FRONT) | (1 << PWIDX_ADC); 2354 power_up |= (1 << PWIDX_MIC); 2355 if (ac97->scaps & AC97_SCAP_SURROUND_DAC) 2356 power_up |= (1 << PWIDX_SURR); 2357 if (ac97->scaps & AC97_SCAP_CENTER_LFE_DAC) 2358 power_up |= (1 << PWIDX_CLFE); 2359 #ifdef CONFIG_SND_AC97_POWER_SAVE 2360 } 2361 #endif 2362 if (power_up) { 2363 if (ac97->regs[AC97_POWERDOWN] & AC97_PD_PR2) { 2364 /* needs power-up analog mix and vref */ 2365 snd_ac97_update_bits(ac97, AC97_POWERDOWN, 2366 AC97_PD_PR3, 0); 2367 msleep(1); 2368 snd_ac97_update_bits(ac97, AC97_POWERDOWN, 2369 AC97_PD_PR2, 0); 2370 } 2371 } 2372 for (i = 0; i < PWIDX_SIZE; i++) { 2373 if (power_up & (1 << i)) 2374 bits = 0; 2375 else 2376 bits = power_regs[i].mask; 2377 snd_ac97_update_bits(ac97, power_regs[i].power_reg, 2378 power_regs[i].mask, bits); 2379 } 2380 if (! power_up) { 2381 if (! (ac97->regs[AC97_POWERDOWN] & AC97_PD_PR2)) { 2382 /* power down analog mix and vref */ 2383 snd_ac97_update_bits(ac97, AC97_POWERDOWN, 2384 AC97_PD_PR2, AC97_PD_PR2); 2385 snd_ac97_update_bits(ac97, AC97_POWERDOWN, 2386 AC97_PD_PR3, AC97_PD_PR3); 2387 } 2388 } 2389 } 2198 2390 2199 2391 #ifdef CONFIG_PM … … 2507 2699 msw->put = master_mute_sw_put; 2508 2700 snd_ac97_remove_ctl(ac97, "External Amplifier", NULL); 2509 snd_ac97_update_bits(ac97, AC97_POWERDOWN, 0x8000, 0x8000); /* mute LED on */ 2701 snd_ac97_update_bits(ac97, AC97_POWERDOWN, 0x8000, 0x8000); /* mute LED on */ 2702 ac97->scaps |= AC97_SCAP_EAPD_LED; 2510 2703 return 0; 2511 2704 } -
GPL/trunk/alsa-kernel/pci/ac97/ac97_patch.c
r76 r77 461 461 int patch_wolfson05(struct snd_ac97 * ac97) 462 462 { 463 /* WM9705, WM9710 */ 464 ac97->build_ops = &patch_wolfson_wm9705_ops; 465 return 0; 463 /* WM9705, WM9710 */ 464 ac97->build_ops = &patch_wolfson_wm9705_ops; 465 #ifdef CONFIG_TOUCHSCREEN_WM9705 466 /* WM9705 touchscreen uses AUX and VIDEO for touch */ 467 ac97->flags |= AC97_HAS_NO_VIDEO | AC97_HAS_NO_AUX; 468 #endif 469 return 0; 466 470 } 467 471 … … 1366 1370 snd_ac97_restore_iec958(ac97); 1367 1371 } 1372 1373 static void ad1888_resume(struct snd_ac97 *ac97) 1374 { 1375 ad18xx_resume(ac97); 1376 snd_ac97_write_cache(ac97, AC97_CODEC_CLASS_REV, 0x8080); 1377 } 1378 1368 1379 #endif 1369 1380 … … 1626 1637 */ 1627 1638 static unsigned int ad1981_jacks_blacklist[] = { 1628 0x10140554, /* Thinkpad T42p/R50p */ 1629 0 /* end */ 1639 0x10140537, /* Thinkpad T41p */ 1640 0x10140554, /* Thinkpad T42p/R50p */ 1641 0 /* end */ 1630 1642 }; 1631 1643 … … 1810 1822 .get = snd_ac97_ad1888_lohpsel_get, 1811 1823 .put = snd_ac97_ad1888_lohpsel_put 1812 }, 1824 }, 1825 AC97_SINGLE("V_REFOUT Enable", AC97_AD_MISC, 2, 1, 1), 1826 AC97_SINGLE("High Pass Filter Enable", AC97_AD_TEST2, 12, 1, 1), 1813 1827 AC97_SINGLE("Spread Front to Surround and Center/LFE", AC97_AD_MISC, 7, 1, 0), 1814 1828 { … … 1838 1852 .build_specific = patch_ad1888_specific, 1839 1853 #ifdef CONFIG_PM 1840 .resume = ad18xx_resume,1854 .resume = ad1888_resume, 1841 1855 #endif 1842 1856 .update_jacks = ad1888_update_jacks, … … 2046 2060 /* Enable SPDIF-IN only on Rev.E and above */ 2047 2061 val = snd_ac97_read(ac97, AC97_ALC650_CLOCK); 2048 /* SPDIF IN with pin 47 */ 2049 if (ac97->spec.dev_flags) 2050 val |= 0x03; /* enable */ 2051 else 2052 val &= ~0x03; /* disable */ 2062 /* SPDIF IN with pin 47 */ 2063 if (ac97->spec.dev_flags && 2064 /* ASUS A6KM requires EAPD */ 2065 ! (ac97->subsystem_vendor == 0x1043 && 2066 ac97->subsystem_device == 0x1103)) 2067 val |= 0x03; /* enable */ 2068 else 2069 val &= ~0x03; /* disable */ 2053 2070 snd_ac97_write_cache(ac97, AC97_ALC650_CLOCK, val); 2054 2071 … … 2855 2872 } 2856 2873 2874 /* 2875 * UCB1400 codec (http://www.semiconductors.philips.com/acrobat_download/datasheets/UCB1400-02.pdf) 2876 */ 2877 static const struct snd_kcontrol_new snd_ac97_controls_ucb1400[] = { 2878 /* enable/disable headphone driver which allows direct connection to 2879 stereo headphone without the use of external DC blocking 2880 capacitors */ 2881 AC97_SINGLE("Headphone Driver", 0x6a, 6, 1, 0), 2882 /* Filter used to compensate the DC offset is added in the ADC to remove idle 2883 tones from the audio band. */ 2884 AC97_SINGLE("DC Filter", 0x6a, 4, 1, 0), 2885 /* Control smart-low-power mode feature. Allows automatic power down 2886 of unused blocks in the ADC analog front end and the PLL. */ 2887 AC97_SINGLE("Smart Low Power Mode", 0x6c, 4, 3, 0), 2888 }; 2889 2890 static int patch_ucb1400_specific(struct snd_ac97 * ac97) 2891 { 2892 int idx, err; 2893 for (idx = 0; idx < ARRAY_SIZE(snd_ac97_controls_ucb1400); idx++) 2894 if ((err = snd_ctl_add(ac97->bus->card, snd_ctl_new1(&snd_ac97_controls_ucb1400[idx], ac97))) < 0) 2895 return err; 2896 return 0; 2897 } 2898 2899 static struct snd_ac97_build_ops patch_ucb1400_ops = { 2900 .build_specific = patch_ucb1400_specific, 2901 }; 2902 2903 int patch_ucb1400(struct snd_ac97 * ac97) 2904 { 2905 ac97->build_ops = &patch_ucb1400_ops; 2906 /* enable headphone driver and smart low power mode by default */ 2907 snd_ac97_write(ac97, 0x6a, 0x0050); 2908 snd_ac97_write(ac97, 0x6c, 0x0030); 2909 return 0; 2910 } -
GPL/trunk/alsa-kernel/pci/ac97/ac97_patch.h
r76 r77 59 59 int patch_vt1617a(struct snd_ac97 * ac97); 60 60 int patch_it2646(struct snd_ac97 * ac97); 61 int patch_ucb1400(struct snd_ac97 * ac97); 61 62 int mpatch_si3036(struct snd_ac97 * ac97); 62 63 int patch_lm4550(struct snd_ac97 * ac97); -
GPL/trunk/alsa-kernel/pci/ac97/ac97_pcm.c
r72 r77 259 259 int dbl; 260 260 unsigned int tmp; 261 261 262 262 dbl = rate > 48000; 263 263 if (dbl) { … … 268 268 } 269 269 270 snd_ac97_update_power(ac97, reg, 1); 270 271 switch (reg) { 271 272 case AC97_PCM_MIC_ADC_RATE: … … 600 601 goto error; 601 602 } 602 } 603 } 604 pcm->cur_dbl = r; 603 605 spin_unlock_irq(&pcm->bus->bus_lock); 604 606 for (i = 3; i < 12; i++) { … … 640 642 int snd_ac97_pcm_close(struct ac97_pcm *pcm) 641 643 { 642 struct snd_ac97_bus *bus; 643 unsigned short slots = pcm->aslots; 644 int i, cidx; 645 646 bus = pcm->bus; 647 spin_lock_irq(&pcm->bus->bus_lock); 648 for (i = 3; i < 12; i++) { 649 if (!(slots & (1 << i))) 650 continue; 651 for (cidx = 0; cidx < 4; cidx++) 652 bus->used_slots[pcm->stream][cidx] &= ~(1 << i); 653 } 654 pcm->aslots = 0; 655 spin_unlock_irq(&pcm->bus->bus_lock); 656 return 0; 644 struct snd_ac97_bus *bus; 645 unsigned short slots = pcm->aslots; 646 int i, cidx; 647 648 #ifdef CONFIG_SND_AC97_POWER_SAVE 649 int r = pcm->cur_dbl; 650 for (i = 3; i < 12; i++) { 651 if (!(slots & (1 << i))) 652 continue; 653 for (cidx = 0; cidx < 4; cidx++) { 654 if (pcm->r[r].rslots[cidx] & (1 << i)) { 655 int reg = get_slot_reg(pcm, cidx, i, r); 656 snd_ac97_update_power(pcm->r[r].codec[cidx], 657 reg, 0); 658 } 659 } 660 } 661 #endif 662 663 bus = pcm->bus; 664 spin_lock_irq(&pcm->bus->bus_lock); 665 for (i = 3; i < 12; i++) { 666 if (!(slots & (1 << i))) 667 continue; 668 for (cidx = 0; cidx < 4; cidx++) 669 bus->used_slots[pcm->stream][cidx] &= ~(1 << i); 670 } 671 pcm->aslots = 0; 672 pcm->cur_dbl = 0; 673 spin_unlock_irq(&pcm->bus->bus_lock); 674 return 0; 657 675 } 658 676 -
GPL/trunk/alsa-kernel/pci/bt87x.c
r76 r77 792 792 BT_DEVICE(879, 0x0070, 0x13eb, 32000), /* Hauppauge WinTV series */ 793 793 BT_DEVICE(878, 0x0070, 0xff01, 44100), /* Viewcast Osprey 200 */ 794 /* Leadtek Winfast tv 2000xp delux */ 795 BT_DEVICE(878, 0x107d, 0x6606, 32000), 796 /* Voodoo TV 200 */ 797 BT_DEVICE(878, 0x121a, 0x3000, 32000), 794 798 /* AVerMedia Studio No. 103, 203, ...? */ 795 799 BT_DEVICE(878, 0x1461, 0x0003, 48000), 796 /* Leadtek Winfast tv 2000xp delux */797 BT_DEVICE(878, 0x107d, 0x6606, 32000),798 800 {0} 799 801 }; -
GPL/trunk/alsa-kernel/pci/ca0106/ca0106_main.c
r76 r77 186 186 /* New Audigy SE. Has a different DAC. */ 187 187 /* SB0570: 188 * CTRL:CA0106-DAT189 * ADC: WM8768GEDS190 * DAC: WM87 75EDS188 * CTRL:CA0106-DAT 189 * ADC: WM8775EDS 190 * DAC: WM8768GEDS 191 191 */ 192 192 { .serial = 0x100a1102, … … 1181 1181 0x02ff, 1182 1182 0x0400, 1183 0x0520,1184 0x0600, 1183 0x0520, 1184 0x0620, /* Set 24 bit. Was 0x0600 */ 1185 1185 0x08ff, 1186 1186 0x0aff, -
GPL/trunk/alsa-kernel/pci/ca0106/ca0106_mixer.c
r76 r77 71 71 #include <sound/ac97_codec.h> 72 72 #include <sound/info.h> 73 #include <sound/tlv.h> 73 74 74 75 #include "ca0106.h" 76 77 static DECLARE_TLV_DB_SCALE(snd_ca0106_db_scale, -5150, 75, 1); 75 78 76 79 static int snd_ca0106_shared_spdif_info(struct snd_kcontrol *kcontrol, … … 335 338 .info = snd_ca0106_volume_info, \ 336 339 .get = snd_ca0106_volume_get, \ 337 .put = snd_ca0106_volume_put, \ 340 .put = snd_ca0106_volume_put, \ 341 .tlv = snd_ca0106_db_scale, \ 338 342 .private_value = ((chid) << 8) | (reg) \ 339 343 } -
GPL/trunk/alsa-kernel/pci/cmipci.c
r34 r77 2151 2151 CMIPCI_SB_VOL_MONO("Phone Playback Volume", CM_REG_EXTENT_IND, 5, 7), 2152 2152 CMIPCI_DOUBLE("Phone Playback Switch", CM_REG_EXTENT_IND, CM_REG_EXTENT_IND, 4, 4, 1, 0, 0), 2153 CMIPCI_DOUBLE("PC Speaker Play nack Switch", CM_REG_EXTENT_IND, CM_REG_EXTENT_IND, 3, 3, 1, 0, 0),2153 CMIPCI_DOUBLE("PC Speaker Playback Switch", CM_REG_EXTENT_IND, CM_REG_EXTENT_IND, 3, 3, 1, 0, 0), 2154 2154 CMIPCI_DOUBLE("Mic Boost Capture Switch", CM_REG_EXTENT_IND, CM_REG_EXTENT_IND, 0, 0, 1, 0, 0), 2155 2155 }; … … 2941 2941 if (iomidi > 0) { 2942 2942 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_CMIPCI, 2943 iomidi, integrated_midi, 2943 iomidi, 2944 (integrated_midi ? 2945 MPU401_INFO_INTEGRATED : 0), 2944 2946 cm->irq, 0, &cm->rmidi)) < 0) { 2945 2947 printk(KERN_ERR "cmipci: no UART401 device at 0x%lx\n", iomidi); -
GPL/trunk/alsa-kernel/pci/cs4281.c
r76 r77 1426 1426 chip->ba0_addr = pci_resource_start(pci, 0); 1427 1427 chip->ba1_addr = pci_resource_start(pci, 1); 1428 if (request_irq(pci->irq, snd_cs4281_interrupt, SA_INTERRUPT|SA_SHIRQ, "CS4281", (void *)chip)) {1429 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);1430 snd_cs4281_free(chip);1431 return -ENOMEM;1432 }1433 chip->irq = pci->irq;1434 1435 1428 chip->ba0 = (unsigned long) ioremap_nocache(chip->ba0_addr, pci_resource_len(pci, 0)); 1436 1429 chip->ba1 = (unsigned long) ioremap_nocache(chip->ba1_addr, pci_resource_len(pci, 1)); … … 1439 1432 return -ENOMEM; 1440 1433 } 1434 1435 if (request_irq(pci->irq, snd_cs4281_interrupt, SA_INTERRUPT|SA_SHIRQ, "CS4281", (void *)chip)) { 1436 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq); 1437 snd_cs4281_free(chip); 1438 return -ENOMEM; 1439 } 1440 chip->irq = pci->irq; 1441 1441 1442 1442 tmp = snd_cs4281_chip_init(chip); -
GPL/trunk/alsa-kernel/pci/cs46xx/cs46xx_lib.c
r76 r77 2878 2878 snd_cs46xx_hw_stop(chip); 2879 2879 2880 if (chip->irq >= 0) 2881 free_irq(chip->irq, chip); 2882 2880 2883 for (idx = 0; idx < 5; idx++) { 2881 2884 struct snd_cs46xx_region *region = &chip->region.idx[idx]; … … 2884 2887 release_and_free_resource(region->resource); 2885 2888 } 2886 if (chip->irq >= 0)2887 free_irq(chip->irq, chip);2888 2889 2889 2890 if (chip->active_ctrl) -
GPL/trunk/alsa-kernel/pci/es1938.c
r34 r77 1750 1750 } 1751 1751 } 1752 if (snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, 1753 chip->mpu_port, 1, chip->irq, 0, &chip->rmidi) < 0) { 1752 if (snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, 1753 chip->mpu_port, MPU401_INFO_INTEGRATED, 1754 chip->irq, 0, &chip->rmidi) < 0) { 1754 1755 printk(KERN_ERR "es1938: unable to initialize MPU-401\n"); 1755 1756 } else { -
GPL/trunk/alsa-kernel/pci/es1968.c
r76 r77 2776 2776 if (enable_mpu[dev]) { 2777 2777 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, 2778 chip->io_port + ESM_MPU401_PORT, 1, 2778 chip->io_port + ESM_MPU401_PORT, 2779 MPU401_INFO_INTEGRATED, 2779 2780 chip->irq, 0, &chip->rmidi)) < 0) { 2780 2781 printk(KERN_WARNING "es1968: skipping MPU-401 MIDI support..\n"); -
GPL/trunk/alsa-kernel/pci/fm801.c
r32 r77 1434 1434 return err; 1435 1435 } 1436 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_FM801, 1437 FM801_REG(chip, MPU401_DATA), 1, 1436 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_FM801, 1437 FM801_REG(chip, MPU401_DATA), 1438 MPU401_INFO_INTEGRATED, 1438 1439 chip->irq, 0, &chip->rmidi)) < 0) { 1439 1440 snd_card_free(card); -
GPL/trunk/alsa-kernel/pci/hda/hda_codec.c
r76 r77 43 43 44 44 struct hda_vendor_id { 45 unsigned int id;46 const char *name;45 unsigned int id; 46 const char *name; 47 47 }; 48 48 49 49 /* codec vendor labels */ 50 50 static struct hda_vendor_id hda_vendor_ids[] = { 51 { 0x10ec, "Realtek" },52 { 0x11d4, "Analog Devices" },53 { 0x13f6, "C-Media" },54 { 0x434d, "C-Media" },55 { 0x8384, "SigmaTel" },56 {0} /* terminator */51 { 0x10ec, "Realtek" }, 52 { 0x11d4, "Analog Devices" }, 53 { 0x13f6, "C-Media" }, 54 { 0x434d, "C-Media" }, 55 { 0x8384, "SigmaTel" }, 56 {0} /* terminator */ 57 57 }; 58 58 … … 74 74 */ 75 75 unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid, int direct, 76 unsigned int verb, unsigned int parm)77 { 78 unsigned int res;79 down(&codec->bus->cmd_mutex);80 if (! codec->bus->ops.command(codec, nid, direct, verb, parm))81 res = codec->bus->ops.get_response(codec);82 else83 res = (unsigned int)-1;84 up(&codec->bus->cmd_mutex);85 return res;76 unsigned int verb, unsigned int parm) 77 { 78 unsigned int res; 79 down(&codec->bus->cmd_mutex); 80 if (! codec->bus->ops.command(codec, nid, direct, verb, parm)) 81 res = codec->bus->ops.get_response(codec); 82 else 83 res = (unsigned int)-1; 84 up(&codec->bus->cmd_mutex); 85 return res; 86 86 } 87 87 … … 99 99 */ 100 100 int snd_hda_codec_write(struct hda_codec *codec, hda_nid_t nid, int direct, 101 unsigned int verb, unsigned int parm)102 { 103 int err;104 down(&codec->bus->cmd_mutex);105 err = codec->bus->ops.command(codec, nid, direct, verb, parm);106 up(&codec->bus->cmd_mutex);107 return err;101 unsigned int verb, unsigned int parm) 102 { 103 int err; 104 down(&codec->bus->cmd_mutex); 105 err = codec->bus->ops.command(codec, nid, direct, verb, parm); 106 up(&codec->bus->cmd_mutex); 107 return err; 108 108 } 109 109 … … 118 118 void snd_hda_sequence_write(struct hda_codec *codec, const struct hda_verb *seq) 119 119 { 120 for (; seq->nid; seq++)121 snd_hda_codec_write(codec, seq->nid, 0, seq->verb, seq->param);120 for (; seq->nid; seq++) 121 snd_hda_codec_write(codec, seq->nid, 0, seq->verb, seq->param); 122 122 } 123 123 … … 133 133 int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid, hda_nid_t *start_id) 134 134 { 135 unsigned int parm;136 137 parm = snd_hda_param_read(codec, nid, AC_PAR_NODE_COUNT);138 *start_id = (parm >> 16) & 0x7fff;139 return (int)(parm & 0x7fff);135 unsigned int parm; 136 137 parm = snd_hda_param_read(codec, nid, AC_PAR_NODE_COUNT); 138 *start_id = (parm >> 16) & 0x7fff; 139 return (int)(parm & 0x7fff); 140 140 } 141 141 … … 153 153 */ 154 154 int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, 155 hda_nid_t *conn_list, int max_conns)156 { 157 unsigned int parm;158 int i, conn_len, conns;159 unsigned int shift, num_elems, mask;160 hda_nid_t prev_nid;161 162 snd_assert(conn_list && max_conns > 0, return -EINVAL);163 164 parm = snd_hda_param_read(codec, nid, AC_PAR_CONNLIST_LEN);165 if (parm & AC_CLIST_LONG) {166 /* long form */167 shift = 16;168 num_elems = 2;169 } else {170 /* short form */171 shift = 8;172 num_elems = 4;173 }174 conn_len = parm & AC_CLIST_LENGTH;175 mask = (1 << (shift-1)) - 1;176 177 if (! conn_len)178 return 0; /* no connection */179 180 if (conn_len == 1) {181 /* single connection */182 parm = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_LIST, 0);183 conn_list[0] = parm & mask;184 return 1;185 }186 187 /* multi connection */188 conns = 0;189 prev_nid = 0;190 for (i = 0; i < conn_len; i++) {191 int range_val;192 hda_nid_t val, n;193 194 if (i % num_elems == 0)195 parm = snd_hda_codec_read(codec, nid, 0,196 AC_VERB_GET_CONNECT_LIST, i);197 range_val = !! (parm & (1 << (shift-1))); /* ranges */198 val = parm & mask;199 parm >>= shift;200 if (range_val) {201 /* ranges between the previous and this one */202 if (! prev_nid || prev_nid >= val) {203 snd_printk(KERN_WARNING "hda_codec: invalid dep_range_val %x:%x\n", prev_nid, val);204 continue;205 }206 for (n = prev_nid + 1; n <= val; n++) {207 if (conns >= max_conns) {208 snd_printk(KERN_ERR "Too many connections\n");209 return -EINVAL;210 }211 conn_list[conns++] = n;212 }213 } else {214 if (conns >= max_conns) {215 snd_printk(KERN_ERR "Too many connections\n");216 return -EINVAL;217 }218 conn_list[conns++] = val;219 }220 prev_nid = val;221 }222 return conns;155 hda_nid_t *conn_list, int max_conns) 156 { 157 unsigned int parm; 158 int i, conn_len, conns; 159 unsigned int shift, num_elems, mask; 160 hda_nid_t prev_nid; 161 162 snd_assert(conn_list && max_conns > 0, return -EINVAL); 163 164 parm = snd_hda_param_read(codec, nid, AC_PAR_CONNLIST_LEN); 165 if (parm & AC_CLIST_LONG) { 166 /* long form */ 167 shift = 16; 168 num_elems = 2; 169 } else { 170 /* short form */ 171 shift = 8; 172 num_elems = 4; 173 } 174 conn_len = parm & AC_CLIST_LENGTH; 175 mask = (1 << (shift-1)) - 1; 176 177 if (! conn_len) 178 return 0; /* no connection */ 179 180 if (conn_len == 1) { 181 /* single connection */ 182 parm = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_LIST, 0); 183 conn_list[0] = parm & mask; 184 return 1; 185 } 186 187 /* multi connection */ 188 conns = 0; 189 prev_nid = 0; 190 for (i = 0; i < conn_len; i++) { 191 int range_val; 192 hda_nid_t val, n; 193 194 if (i % num_elems == 0) 195 parm = snd_hda_codec_read(codec, nid, 0, 196 AC_VERB_GET_CONNECT_LIST, i); 197 range_val = !! (parm & (1 << (shift-1))); /* ranges */ 198 val = parm & mask; 199 parm >>= shift; 200 if (range_val) { 201 /* ranges between the previous and this one */ 202 if (! prev_nid || prev_nid >= val) { 203 snd_printk(KERN_WARNING "hda_codec: invalid dep_range_val %x:%x\n", prev_nid, val); 204 continue; 205 } 206 for (n = prev_nid + 1; n <= val; n++) { 207 if (conns >= max_conns) { 208 snd_printk(KERN_ERR "Too many connections\n"); 209 return -EINVAL; 210 } 211 conn_list[conns++] = n; 212 } 213 } else { 214 if (conns >= max_conns) { 215 snd_printk(KERN_ERR "Too many connections\n"); 216 return -EINVAL; 217 } 218 conn_list[conns++] = val; 219 } 220 prev_nid = val; 221 } 222 return conns; 223 223 } 224 224 … … 238 238 int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex) 239 239 { 240 struct hda_bus_unsolicited *unsol;241 unsigned int wp;242 243 if ((unsol = bus->unsol) == NULL)244 return 0;245 246 wp = (unsol->wp + 1) % HDA_UNSOL_QUEUE_SIZE;247 unsol->wp = wp;248 249 wp <<= 1;250 unsol->queue[wp] = res;251 unsol->queue[wp + 1] = res_ex;252 253 queue_work(unsol->workq, &unsol->work);254 255 return 0;240 struct hda_bus_unsolicited *unsol; 241 unsigned int wp; 242 243 if ((unsol = bus->unsol) == NULL) 244 return 0; 245 246 wp = (unsol->wp + 1) % HDA_UNSOL_QUEUE_SIZE; 247 unsol->wp = wp; 248 249 wp <<= 1; 250 unsol->queue[wp] = res; 251 unsol->queue[wp + 1] = res_ex; 252 253 queue_work(unsol->workq, &unsol->work); 254 255 return 0; 256 256 } 257 257 … … 261 261 static void process_unsol_events(void *data) 262 262 { 263 struct hda_bus *bus = data;264 struct hda_bus_unsolicited *unsol = bus->unsol;265 struct hda_codec *codec;266 unsigned int rp, caddr, res;267 268 while (unsol->rp != unsol->wp) {269 rp = (unsol->rp + 1) % HDA_UNSOL_QUEUE_SIZE;270 unsol->rp = rp;271 rp <<= 1;272 res = unsol->queue[rp];273 caddr = unsol->queue[rp + 1];274 if (! (caddr & (1 << 4))) /* no unsolicited event? */275 continue;276 codec = bus->caddr_tbl[caddr & 0x0f];277 if (codec && codec->patch_ops.unsol_event)278 codec->patch_ops.unsol_event(codec, res);279 }263 struct hda_bus *bus = data; 264 struct hda_bus_unsolicited *unsol = bus->unsol; 265 struct hda_codec *codec; 266 unsigned int rp, caddr, res; 267 268 while (unsol->rp != unsol->wp) { 269 rp = (unsol->rp + 1) % HDA_UNSOL_QUEUE_SIZE; 270 unsol->rp = rp; 271 rp <<= 1; 272 res = unsol->queue[rp]; 273 caddr = unsol->queue[rp + 1]; 274 if (! (caddr & (1 << 4))) /* no unsolicited event? */ 275 continue; 276 codec = bus->caddr_tbl[caddr & 0x0f]; 277 if (codec && codec->patch_ops.unsol_event) 278 codec->patch_ops.unsol_event(codec, res); 279 } 280 280 } 281 281 … … 285 285 static int init_unsol_queue(struct hda_bus *bus) 286 286 { 287 struct hda_bus_unsolicited *unsol;288 289 if (bus->unsol) /* already initialized */290 return 0;291 292 unsol = kzalloc(sizeof(*unsol), GFP_KERNEL);293 if (! unsol) {294 snd_printk(KERN_ERR "hda_codec: can't allocate unsolicited queue\n");295 return -ENOMEM;296 }297 unsol->workq = create_workqueue("hda_codec");298 if (! unsol->workq) {299 snd_printk(KERN_ERR "hda_codec: can't create workqueue\n");300 kfree(unsol);301 return -ENOMEM;302 }303 INIT_WORK(&unsol->work, process_unsol_events, bus);304 bus->unsol = unsol;305 return 0;287 struct hda_bus_unsolicited *unsol; 288 289 if (bus->unsol) /* already initialized */ 290 return 0; 291 292 unsol = kzalloc(sizeof(*unsol), GFP_KERNEL); 293 if (! unsol) { 294 snd_printk(KERN_ERR "hda_codec: can't allocate unsolicited queue\n"); 295 return -ENOMEM; 296 } 297 unsol->workq = create_workqueue("hda_codec"); 298 if (! unsol->workq) { 299 snd_printk(KERN_ERR "hda_codec: can't create workqueue\n"); 300 kfree(unsol); 301 return -ENOMEM; 302 } 303 INIT_WORK(&unsol->work, process_unsol_events, bus); 304 bus->unsol = unsol; 305 return 0; 306 306 } 307 307 … … 313 313 static int snd_hda_bus_free(struct hda_bus *bus) 314 314 { 315 struct list_head *p, *n;316 317 if (! bus)318 return 0;319 if (bus->unsol) {320 destroy_workqueue(bus->unsol->workq);321 kfree(bus->unsol);322 }323 list_for_each_safe(p, n, &bus->codec_list) {324 struct hda_codec *codec = list_entry(p, struct hda_codec, list);325 snd_hda_codec_free(codec);326 }327 if (bus->ops.private_free)328 bus->ops.private_free(bus);329 kfree(bus);330 return 0;315 struct list_head *p, *n; 316 317 if (! bus) 318 return 0; 319 if (bus->unsol) { 320 destroy_workqueue(bus->unsol->workq); 321 kfree(bus->unsol); 322 } 323 list_for_each_safe(p, n, &bus->codec_list) { 324 struct hda_codec *codec = list_entry(p, struct hda_codec, list); 325 snd_hda_codec_free(codec); 326 } 327 if (bus->ops.private_free) 328 bus->ops.private_free(bus); 329 kfree(bus); 330 return 0; 331 331 } 332 332 333 333 static int snd_hda_bus_dev_free(struct snd_device *device) 334 334 { 335 struct hda_bus *bus = device->device_data;336 return snd_hda_bus_free(bus);335 struct hda_bus *bus = device->device_data; 336 return snd_hda_bus_free(bus); 337 337 } 338 338 … … 346 346 */ 347 347 int snd_hda_bus_new(struct snd_card *card, const struct hda_bus_template *temp, 348 struct hda_bus **busp)349 { 350 struct hda_bus *bus;351 int err;352 static struct snd_device_ops dev_ops = {353 .dev_free = snd_hda_bus_dev_free,354 };355 356 snd_assert(temp, return -EINVAL);357 snd_assert(temp->ops.command && temp->ops.get_response, return -EINVAL);358 359 if (busp)360 *busp = NULL;361 362 bus = kzalloc(sizeof(*bus), GFP_KERNEL);363 if (bus == NULL) {364 snd_printk(KERN_ERR "can't allocate struct hda_bus\n");365 return -ENOMEM;366 }367 368 bus->card = card;369 bus->private_data = temp->private_data;370 bus->pci = temp->pci;371 bus->modelname = temp->modelname;372 bus->ops = temp->ops;373 374 init_MUTEX(&bus->cmd_mutex);375 INIT_LIST_HEAD(&bus->codec_list);376 377 if ((err = snd_device_new(card, SNDRV_DEV_BUS, bus, &dev_ops)) < 0) {378 snd_hda_bus_free(bus);379 return err;380 }381 if (busp)382 *busp = bus;383 return 0;348 struct hda_bus **busp) 349 { 350 struct hda_bus *bus; 351 int err; 352 static struct snd_device_ops dev_ops = { 353 .dev_free = snd_hda_bus_dev_free, 354 }; 355 356 snd_assert(temp, return -EINVAL); 357 snd_assert(temp->ops.command && temp->ops.get_response, return -EINVAL); 358 359 if (busp) 360 *busp = NULL; 361 362 bus = kzalloc(sizeof(*bus), GFP_KERNEL); 363 if (bus == NULL) { 364 snd_printk(KERN_ERR "can't allocate struct hda_bus\n"); 365 return -ENOMEM; 366 } 367 368 bus->card = card; 369 bus->private_data = temp->private_data; 370 bus->pci = temp->pci; 371 bus->modelname = temp->modelname; 372 bus->ops = temp->ops; 373 374 init_MUTEX(&bus->cmd_mutex); 375 INIT_LIST_HEAD(&bus->codec_list); 376 377 if ((err = snd_device_new(card, SNDRV_DEV_BUS, bus, &dev_ops)) < 0) { 378 snd_hda_bus_free(bus); 379 return err; 380 } 381 if (busp) 382 *busp = bus; 383 return 0; 384 384 } 385 385 … … 390 390 static const struct hda_codec_preset *find_codec_preset(struct hda_codec *codec) 391 391 { 392 const struct hda_codec_preset **tbl, *preset; 393 394 for (tbl = hda_preset_tables; *tbl; tbl++) { 395 for (preset = *tbl; preset->id; preset++) { 396 u32 mask = preset->mask; 397 if (! mask) 398 mask = ~0; 399 if (preset->id == (codec->vendor_id & mask)) 400 return preset; 401 } 402 } 403 return NULL; 392 const struct hda_codec_preset **tbl, *preset; 393 394 for (tbl = hda_preset_tables; *tbl; tbl++) { 395 for (preset = *tbl; preset->id; preset++) { 396 u32 mask = preset->mask; 397 if (! mask) 398 mask = ~0; 399 if (preset->id == (codec->vendor_id & mask)) 400 if (preset->id == (codec->vendor_id & mask) && 401 (! preset->rev || 402 preset->rev == codec->revision_id)) 403 return preset; 404 } 405 } 406 return NULL; 404 407 } 405 408 … … 408 411 */ 409 412 void snd_hda_get_codec_name(struct hda_codec *codec, 410 char *name, int namelen)411 { 412 const struct hda_vendor_id *c;413 const char *vendor = NULL;414 u16 vendor_id = codec->vendor_id >> 16;415 char tmp[16];416 417 for (c = hda_vendor_ids; c->id; c++) {418 if (c->id == vendor_id) {419 vendor = c->name;420 break;421 }422 }423 if (! vendor) {424 sprintf(tmp, "Generic %04x", vendor_id);425 vendor = tmp;426 }427 if (codec->preset && codec->preset->name)428 sprintf(name, "%s %s", vendor, codec->preset->name);429 else430 sprintf(name, "%s ID %x", vendor, codec->vendor_id & 0xffff);413 char *name, int namelen) 414 { 415 const struct hda_vendor_id *c; 416 const char *vendor = NULL; 417 u16 vendor_id = codec->vendor_id >> 16; 418 char tmp[16]; 419 420 for (c = hda_vendor_ids; c->id; c++) { 421 if (c->id == vendor_id) { 422 vendor = c->name; 423 break; 424 } 425 } 426 if (! vendor) { 427 sprintf(tmp, "Generic %04x", vendor_id); 428 vendor = tmp; 429 } 430 if (codec->preset && codec->preset->name) 431 sprintf(name, "%s %s", vendor, codec->preset->name); 432 else 433 sprintf(name, "%s ID %x", vendor, codec->vendor_id & 0xffff); 431 434 } 432 435 … … 436 439 static void setup_fg_nodes(struct hda_codec *codec) 437 440 { 438 int i, total_nodes;439 hda_nid_t nid;440 441 total_nodes = snd_hda_get_sub_nodes(codec, AC_NODE_ROOT, &nid);442 for (i = 0; i < total_nodes; i++, nid++) {443 switch((snd_hda_param_read(codec, nid, AC_PAR_FUNCTION_TYPE) & 0xff)) {444 case AC_GRP_AUDIO_FUNCTION:445 codec->afg = nid;446 break;447 case AC_GRP_MODEM_FUNCTION:448 codec->mfg = nid;449 break;450 default:451 break;452 }453 }441 int i, total_nodes; 442 hda_nid_t nid; 443 444 total_nodes = snd_hda_get_sub_nodes(codec, AC_NODE_ROOT, &nid); 445 for (i = 0; i < total_nodes; i++, nid++) { 446 switch((snd_hda_param_read(codec, nid, AC_PAR_FUNCTION_TYPE) & 0xff)) { 447 case AC_GRP_AUDIO_FUNCTION: 448 codec->afg = nid; 449 break; 450 case AC_GRP_MODEM_FUNCTION: 451 codec->mfg = nid; 452 break; 453 default: 454 break; 455 } 456 } 454 457 } 455 458 … … 459 462 static int read_widget_caps(struct hda_codec *codec, hda_nid_t fg_node) 460 463 { 461 int i;462 hda_nid_t nid;463 464 codec->num_nodes = snd_hda_get_sub_nodes(codec, fg_node,465 &codec->start_nid);466 codec->wcaps = kmalloc(codec->num_nodes * 4, GFP_KERNEL);467 if (! codec->wcaps)468 return -ENOMEM;469 nid = codec->start_nid;470 for (i = 0; i < codec->num_nodes; i++, nid++)471 codec->wcaps[i] = snd_hda_param_read(codec, nid,472 AC_PAR_AUDIO_WIDGET_CAP);473 return 0;464 int i; 465 hda_nid_t nid; 466 467 codec->num_nodes = snd_hda_get_sub_nodes(codec, fg_node, 468 &codec->start_nid); 469 codec->wcaps = kmalloc(codec->num_nodes * 4, GFP_KERNEL); 470 if (! codec->wcaps) 471 return -ENOMEM; 472 nid = codec->start_nid; 473 for (i = 0; i < codec->num_nodes; i++, nid++) 474 codec->wcaps[i] = snd_hda_param_read(codec, nid, 475 AC_PAR_AUDIO_WIDGET_CAP); 476 return 0; 474 477 } 475 478 … … 480 483 static void snd_hda_codec_free(struct hda_codec *codec) 481 484 { 482 if (! codec)483 return;484 list_del(&codec->list);485 codec->bus->caddr_tbl[codec->addr] = NULL;486 if (codec->patch_ops.free)487 codec->patch_ops.free(codec);488 kfree(codec->amp_info);489 kfree(codec->wcaps);490 kfree(codec);485 if (! codec) 486 return; 487 list_del(&codec->list); 488 codec->bus->caddr_tbl[codec->addr] = NULL; 489 if (codec->patch_ops.free) 490 codec->patch_ops.free(codec); 491 kfree(codec->amp_info); 492 kfree(codec->wcaps); 493 kfree(codec); 491 494 } 492 495 … … 502 505 */ 503 506 int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, 504 struct hda_codec **codecp)505 { 506 struct hda_codec *codec;507 char component[13];508 int err;509 510 snd_assert(bus, return -EINVAL);511 snd_assert(codec_addr <= HDA_MAX_CODEC_ADDRESS, return -EINVAL);512 513 if (bus->caddr_tbl[codec_addr]) {514 snd_printk(KERN_ERR "hda_codec: address 0x%x is already occupied\n", codec_addr);515 return -EBUSY;516 }517 518 codec = kzalloc(sizeof(*codec), GFP_KERNEL);519 if (codec == NULL) {520 snd_printk(KERN_ERR "can't allocate struct hda_codec\n");521 return -ENOMEM;522 }523 524 codec->bus = bus;525 codec->addr = codec_addr;526 init_MUTEX(&codec->spdif_mutex);527 init_amp_hash(codec);528 529 list_add_tail(&codec->list, &bus->codec_list);530 bus->caddr_tbl[codec_addr] = codec;531 532 codec->vendor_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_VENDOR_ID);533 if (codec->vendor_id == -1)534 /* read again, hopefully the access method was corrected535 * in the last read...536 */537 codec->vendor_id = snd_hda_param_read(codec, AC_NODE_ROOT,538 AC_PAR_VENDOR_ID);539 codec->subsystem_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_SUBSYSTEM_ID);540 codec->revision_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_REV_ID);541 542 setup_fg_nodes(codec);543 if (! codec->afg && ! codec->mfg) {544 snd_printdd("hda_codec: no AFG or MFG node found\n");545 snd_hda_codec_free(codec);546 return -ENODEV;547 }548 549 if (read_widget_caps(codec, codec->afg ? codec->afg : codec->mfg) < 0) {550 snd_printk(KERN_ERR "hda_codec: cannot malloc\n");551 snd_hda_codec_free(codec);552 return -ENOMEM;553 }554 555 if (! codec->subsystem_id) {556 hda_nid_t nid = codec->afg ? codec->afg : codec->mfg;557 codec->subsystem_id = snd_hda_codec_read(codec, nid, 0,558 AC_VERB_GET_SUBSYSTEM_ID,559 0);560 }561 562 codec->preset = find_codec_preset(codec);563 if (! *bus->card->mixername)564 snd_hda_get_codec_name(codec, bus->card->mixername,565 sizeof(bus->card->mixername));566 567 if (codec->preset && codec->preset->patch)568 err = codec->preset->patch(codec);569 else570 err = snd_hda_parse_generic_codec(codec);571 if (err < 0) {572 snd_hda_codec_free(codec);573 return err;574 }575 576 if (codec->patch_ops.unsol_event)577 init_unsol_queue(bus);578 579 snd_hda_codec_proc_new(codec);580 581 sprintf(component, "HDA:%08x", codec->vendor_id);582 snd_component_add(codec->bus->card, component);583 584 if (codecp)585 *codecp = codec;586 return 0;507 struct hda_codec **codecp) 508 { 509 struct hda_codec *codec; 510 char component[13]; 511 int err; 512 513 snd_assert(bus, return -EINVAL); 514 snd_assert(codec_addr <= HDA_MAX_CODEC_ADDRESS, return -EINVAL); 515 516 if (bus->caddr_tbl[codec_addr]) { 517 snd_printk(KERN_ERR "hda_codec: address 0x%x is already occupied\n", codec_addr); 518 return -EBUSY; 519 } 520 521 codec = kzalloc(sizeof(*codec), GFP_KERNEL); 522 if (codec == NULL) { 523 snd_printk(KERN_ERR "can't allocate struct hda_codec\n"); 524 return -ENOMEM; 525 } 526 527 codec->bus = bus; 528 codec->addr = codec_addr; 529 init_MUTEX(&codec->spdif_mutex); 530 init_amp_hash(codec); 531 532 list_add_tail(&codec->list, &bus->codec_list); 533 bus->caddr_tbl[codec_addr] = codec; 534 535 codec->vendor_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_VENDOR_ID); 536 if (codec->vendor_id == -1) 537 /* read again, hopefully the access method was corrected 538 * in the last read... 539 */ 540 codec->vendor_id = snd_hda_param_read(codec, AC_NODE_ROOT, 541 AC_PAR_VENDOR_ID); 542 codec->subsystem_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_SUBSYSTEM_ID); 543 codec->revision_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_REV_ID); 544 545 setup_fg_nodes(codec); 546 if (! codec->afg && ! codec->mfg) { 547 snd_printdd("hda_codec: no AFG or MFG node found\n"); 548 snd_hda_codec_free(codec); 549 return -ENODEV; 550 } 551 552 if (read_widget_caps(codec, codec->afg ? codec->afg : codec->mfg) < 0) { 553 snd_printk(KERN_ERR "hda_codec: cannot malloc\n"); 554 snd_hda_codec_free(codec); 555 return -ENOMEM; 556 } 557 558 if (! codec->subsystem_id) { 559 hda_nid_t nid = codec->afg ? codec->afg : codec->mfg; 560 codec->subsystem_id = snd_hda_codec_read(codec, nid, 0, 561 AC_VERB_GET_SUBSYSTEM_ID, 562 0); 563 } 564 565 codec->preset = find_codec_preset(codec); 566 if (! *bus->card->mixername) 567 snd_hda_get_codec_name(codec, bus->card->mixername, 568 sizeof(bus->card->mixername)); 569 570 if (codec->preset && codec->preset->patch) 571 err = codec->preset->patch(codec); 572 else 573 err = snd_hda_parse_generic_codec(codec); 574 if (err < 0) { 575 snd_hda_codec_free(codec); 576 return err; 577 } 578 579 if (codec->patch_ops.unsol_event) 580 init_unsol_queue(bus); 581 582 snd_hda_codec_proc_new(codec); 583 584 sprintf(component, "HDA:%08x", codec->vendor_id); 585 snd_component_add(codec->bus->card, component); 586 587 if (codecp) 588 *codecp = codec; 589 return 0; 587 590 } 588 591 … … 596 599 */ 597 600 void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, u32 stream_tag, 598 int channel_id, int format)599 { 600 if (! nid)601 return;602 603 snd_printdd("hda_codec_setup_stream: NID=0x%x, stream=0x%x, channel=%d, format=0x%x\n",604 nid, stream_tag, channel_id, format);605 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CHANNEL_STREAMID,606 (stream_tag << 4) | channel_id);607 msleep(1);608 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_STREAM_FORMAT, format);601 int channel_id, int format) 602 { 603 if (! nid) 604 return; 605 606 snd_printdd("hda_codec_setup_stream: NID=0x%x, stream=0x%x, channel=%d, format=0x%x\n", 607 nid, stream_tag, channel_id, format); 608 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CHANNEL_STREAMID, 609 (stream_tag << 4) | channel_id); 610 msleep(1); 611 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_STREAM_FORMAT, format); 609 612 } 610 613 … … 622 625 static void init_amp_hash(struct hda_codec *codec) 623 626 { 624 memset(codec->amp_hash, 0xff, sizeof(codec->amp_hash));625 codec->num_amp_entries = 0;626 codec->amp_info_size = 0;627 codec->amp_info = NULL;627 memset(codec->amp_hash, 0xff, sizeof(codec->amp_hash)); 628 codec->num_amp_entries = 0; 629 codec->amp_info_size = 0; 630 codec->amp_info = NULL; 628 631 } 629 632 … … 631 634 static struct hda_amp_info *get_alloc_amp_hash(struct hda_codec *codec, u32 key) 632 635 { 633 u16 idx = key % (u16)ARRAY_SIZE(codec->amp_hash);634 u16 cur = codec->amp_hash[idx];635 struct hda_amp_info *info;636 637 while (cur != 0xffff) {638 info = &codec->amp_info[cur];639 if (info->key == key)640 return info;641 cur = info->next;642 }643 644 /* add a new hash entry */645 if (codec->num_amp_entries >= codec->amp_info_size) {646 /* reallocate the array */647 int new_size = codec->amp_info_size + 64;648 struct hda_amp_info *new_info = kcalloc(new_size, sizeof(struct hda_amp_info),649 GFP_KERNEL);650 if (! new_info) {651 snd_printk(KERN_ERR "hda_codec: can't malloc amp_info\n");652 return NULL;653 }654 if (codec->amp_info) {655 memcpy(new_info, codec->amp_info,656 codec->amp_info_size * sizeof(struct hda_amp_info));657 kfree(codec->amp_info);658 }659 codec->amp_info_size = new_size;660 codec->amp_info = new_info;661 }662 cur = codec->num_amp_entries++;663 info = &codec->amp_info[cur];664 info->key = key;665 info->status = 0; /* not initialized yet */666 info->next = codec->amp_hash[idx];667 codec->amp_hash[idx] = cur;668 669 return info;636 u16 idx = key % (u16)ARRAY_SIZE(codec->amp_hash); 637 u16 cur = codec->amp_hash[idx]; 638 struct hda_amp_info *info; 639 640 while (cur != 0xffff) { 641 info = &codec->amp_info[cur]; 642 if (info->key == key) 643 return info; 644 cur = info->next; 645 } 646 647 /* add a new hash entry */ 648 if (codec->num_amp_entries >= codec->amp_info_size) { 649 /* reallocate the array */ 650 int new_size = codec->amp_info_size + 64; 651 struct hda_amp_info *new_info = kcalloc(new_size, sizeof(struct hda_amp_info), 652 GFP_KERNEL); 653 if (! new_info) { 654 snd_printk(KERN_ERR "hda_codec: can't malloc amp_info\n"); 655 return NULL; 656 } 657 if (codec->amp_info) { 658 memcpy(new_info, codec->amp_info, 659 codec->amp_info_size * sizeof(struct hda_amp_info)); 660 kfree(codec->amp_info); 661 } 662 codec->amp_info_size = new_size; 663 codec->amp_info = new_info; 664 } 665 cur = codec->num_amp_entries++; 666 info = &codec->amp_info[cur]; 667 info->key = key; 668 info->status = 0; /* not initialized yet */ 669 info->next = codec->amp_hash[idx]; 670 codec->amp_hash[idx] = cur; 671 672 return info; 670 673 } 671 674 … … 675 678 static u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction) 676 679 { 677 struct hda_amp_info *info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, 0));678 679 if (! info)680 return 0;681 if (! (info->status & INFO_AMP_CAPS)) {682 if (! (get_wcaps(codec, nid) & AC_WCAP_AMP_OVRD))683 nid = codec->afg;684 info->amp_caps = snd_hda_param_read(codec, nid, direction == HDA_OUTPUT ?685 AC_PAR_AMP_OUT_CAP : AC_PAR_AMP_IN_CAP);686 info->status |= INFO_AMP_CAPS;687 }688 return info->amp_caps;680 struct hda_amp_info *info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, 0)); 681 682 if (! info) 683 return 0; 684 if (! (info->status & INFO_AMP_CAPS)) { 685 if (! (get_wcaps(codec, nid) & AC_WCAP_AMP_OVRD)) 686 nid = codec->afg; 687 info->amp_caps = snd_hda_param_read(codec, nid, direction == HDA_OUTPUT ? 688 AC_PAR_AMP_OUT_CAP : AC_PAR_AMP_IN_CAP); 689 info->status |= INFO_AMP_CAPS; 690 } 691 return info->amp_caps; 689 692 } 690 693 … … 694 697 */ 695 698 static unsigned int get_vol_mute(struct hda_codec *codec, struct hda_amp_info *info, 696 hda_nid_t nid, int ch, int direction, int index)697 { 698 u32 val, parm;699 700 if (info->status & INFO_AMP_VOL(ch))701 return info->vol[ch];702 703 parm = ch ? AC_AMP_GET_RIGHT : AC_AMP_GET_LEFT;704 parm |= direction == HDA_OUTPUT ? AC_AMP_GET_OUTPUT : AC_AMP_GET_INPUT;705 parm |= index;706 val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_AMP_GAIN_MUTE, parm);707 info->vol[ch] = val & 0xff;708 info->status |= INFO_AMP_VOL(ch);709 return info->vol[ch];699 hda_nid_t nid, int ch, int direction, int index) 700 { 701 u32 val, parm; 702 703 if (info->status & INFO_AMP_VOL(ch)) 704 return info->vol[ch]; 705 706 parm = ch ? AC_AMP_GET_RIGHT : AC_AMP_GET_LEFT; 707 parm |= direction == HDA_OUTPUT ? AC_AMP_GET_OUTPUT : AC_AMP_GET_INPUT; 708 parm |= index; 709 val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_AMP_GAIN_MUTE, parm); 710 info->vol[ch] = val & 0xff; 711 info->status |= INFO_AMP_VOL(ch); 712 return info->vol[ch]; 710 713 } 711 714 … … 714 717 */ 715 718 static void put_vol_mute(struct hda_codec *codec, struct hda_amp_info *info, 716 hda_nid_t nid, int ch, int direction, int index, int val)717 { 718 u32 parm;719 720 parm = ch ? AC_AMP_SET_RIGHT : AC_AMP_SET_LEFT;721 parm |= direction == HDA_OUTPUT ? AC_AMP_SET_OUTPUT : AC_AMP_SET_INPUT;722 parm |= index << AC_AMP_SET_INDEX_SHIFT;723 parm |= val;724 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, parm);725 info->vol[ch] = val;719 hda_nid_t nid, int ch, int direction, int index, int val) 720 { 721 u32 parm; 722 723 parm = ch ? AC_AMP_SET_RIGHT : AC_AMP_SET_LEFT; 724 parm |= direction == HDA_OUTPUT ? AC_AMP_SET_OUTPUT : AC_AMP_SET_INPUT; 725 parm |= index << AC_AMP_SET_INDEX_SHIFT; 726 parm |= val; 727 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, parm); 728 info->vol[ch] = val; 726 729 } 727 730 … … 732 735 int direction, int index) 733 736 { 734 struct hda_amp_info *info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, index));735 if (! info)736 return 0;737 return get_vol_mute(codec, info, nid, ch, direction, index);737 struct hda_amp_info *info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, index)); 738 if (! info) 739 return 0; 740 return get_vol_mute(codec, info, nid, ch, direction, index); 738 741 } 739 742 … … 744 747 int direction, int idx, int mask, int val) 745 748 { 746 struct hda_amp_info *info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, idx));747 748 if (! info)749 return 0;750 val &= mask;751 val |= get_vol_mute(codec, info, nid, ch, direction, idx) & ~mask;752 if (info->vol[ch] == val && ! codec->in_resume)753 return 0;754 put_vol_mute(codec, info, nid, ch, direction, idx, val);755 return 1;749 struct hda_amp_info *info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, idx)); 750 751 if (! info) 752 return 0; 753 val &= mask; 754 val |= get_vol_mute(codec, info, nid, ch, direction, idx) & ~mask; 755 if (info->vol[ch] == val && ! codec->in_resume) 756 return 0; 757 put_vol_mute(codec, info, nid, ch, direction, idx, val); 758 return 1; 756 759 } 757 760 … … 769 772 int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 770 773 { 771 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);772 u16 nid = get_amp_nid(kcontrol);773 u8 chs = get_amp_channels(kcontrol);774 int dir = get_amp_direction(kcontrol);775 u32 caps;776 777 caps = query_amp_caps(codec, nid, dir);778 caps = (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT; /* num steps */779 if (! caps) {780 printk(KERN_WARNING "hda_codec: num_steps = 0 for NID=0x%x\n", nid);781 return -EINVAL;782 }783 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;784 uinfo->count = chs == 3 ? 2 : 1;785 uinfo->value.integer.min = 0;786 uinfo->value.integer.max = caps;787 return 0;774 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 775 u16 nid = get_amp_nid(kcontrol); 776 u8 chs = get_amp_channels(kcontrol); 777 int dir = get_amp_direction(kcontrol); 778 u32 caps; 779 780 caps = query_amp_caps(codec, nid, dir); 781 caps = (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT; /* num steps */ 782 if (! caps) { 783 printk(KERN_WARNING "hda_codec: num_steps = 0 for NID=0x%x\n", nid); 784 return -EINVAL; 785 } 786 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 787 uinfo->count = chs == 3 ? 2 : 1; 788 uinfo->value.integer.min = 0; 789 uinfo->value.integer.max = caps; 790 return 0; 788 791 } 789 792 790 793 int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 791 794 { 792 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);793 hda_nid_t nid = get_amp_nid(kcontrol);794 int chs = get_amp_channels(kcontrol);795 int dir = get_amp_direction(kcontrol);796 int idx = get_amp_index(kcontrol);797 long *valp = ucontrol->value.integer.value;798 799 if (chs & 1)800 *valp++ = snd_hda_codec_amp_read(codec, nid, 0, dir, idx) & 0x7f;801 if (chs & 2)802 *valp = snd_hda_codec_amp_read(codec, nid, 1, dir, idx) & 0x7f;803 return 0;795 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 796 hda_nid_t nid = get_amp_nid(kcontrol); 797 int chs = get_amp_channels(kcontrol); 798 int dir = get_amp_direction(kcontrol); 799 int idx = get_amp_index(kcontrol); 800 long *valp = ucontrol->value.integer.value; 801 802 if (chs & 1) 803 *valp++ = snd_hda_codec_amp_read(codec, nid, 0, dir, idx) & 0x7f; 804 if (chs & 2) 805 *valp = snd_hda_codec_amp_read(codec, nid, 1, dir, idx) & 0x7f; 806 return 0; 804 807 } 805 808 806 809 int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 807 810 { 808 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);809 hda_nid_t nid = get_amp_nid(kcontrol);810 int chs = get_amp_channels(kcontrol);811 int dir = get_amp_direction(kcontrol);812 int idx = get_amp_index(kcontrol);813 long *valp = ucontrol->value.integer.value;814 int change = 0;815 816 if (chs & 1) {817 change = snd_hda_codec_amp_update(codec, nid, 0, dir, idx,818 0x7f, *valp);819 valp++;820 }821 if (chs & 2)822 change |= snd_hda_codec_amp_update(codec, nid, 1, dir, idx,823 0x7f, *valp);824 return change;811 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 812 hda_nid_t nid = get_amp_nid(kcontrol); 813 int chs = get_amp_channels(kcontrol); 814 int dir = get_amp_direction(kcontrol); 815 int idx = get_amp_index(kcontrol); 816 long *valp = ucontrol->value.integer.value; 817 int change = 0; 818 819 if (chs & 1) { 820 change = snd_hda_codec_amp_update(codec, nid, 0, dir, idx, 821 0x7f, *valp); 822 valp++; 823 } 824 if (chs & 2) 825 change |= snd_hda_codec_amp_update(codec, nid, 1, dir, idx, 826 0x7f, *valp); 827 return change; 825 828 } 826 829 … … 828 831 int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 829 832 { 830 int chs = get_amp_channels(kcontrol);831 832 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;833 uinfo->count = chs == 3 ? 2 : 1;834 uinfo->value.integer.min = 0;835 uinfo->value.integer.max = 1;836 return 0;833 int chs = get_amp_channels(kcontrol); 834 835 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; 836 uinfo->count = chs == 3 ? 2 : 1; 837 uinfo->value.integer.min = 0; 838 uinfo->value.integer.max = 1; 839 return 0; 837 840 } 838 841 839 842 int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 840 843 { 841 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);842 hda_nid_t nid = get_amp_nid(kcontrol);843 int chs = get_amp_channels(kcontrol);844 int dir = get_amp_direction(kcontrol);845 int idx = get_amp_index(kcontrol);846 long *valp = ucontrol->value.integer.value;847 848 if (chs & 1)849 *valp++ = (snd_hda_codec_amp_read(codec, nid, 0, dir, idx) & 0x80) ? 0 : 1;850 if (chs & 2)851 *valp = (snd_hda_codec_amp_read(codec, nid, 1, dir, idx) & 0x80) ? 0 : 1;852 return 0;844 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 845 hda_nid_t nid = get_amp_nid(kcontrol); 846 int chs = get_amp_channels(kcontrol); 847 int dir = get_amp_direction(kcontrol); 848 int idx = get_amp_index(kcontrol); 849 long *valp = ucontrol->value.integer.value; 850 851 if (chs & 1) 852 *valp++ = (snd_hda_codec_amp_read(codec, nid, 0, dir, idx) & 0x80) ? 0 : 1; 853 if (chs & 2) 854 *valp = (snd_hda_codec_amp_read(codec, nid, 1, dir, idx) & 0x80) ? 0 : 1; 855 return 0; 853 856 } 854 857 855 858 int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 856 859 { 857 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);858 hda_nid_t nid = get_amp_nid(kcontrol);859 int chs = get_amp_channels(kcontrol);860 int dir = get_amp_direction(kcontrol);861 int idx = get_amp_index(kcontrol);862 long *valp = ucontrol->value.integer.value;863 int change = 0;864 865 if (chs & 1) {866 change = snd_hda_codec_amp_update(codec, nid, 0, dir, idx,867 0x80, *valp ? 0 : 0x80);868 valp++;869 }870 if (chs & 2)871 change |= snd_hda_codec_amp_update(codec, nid, 1, dir, idx,872 0x80, *valp ? 0 : 0x80);873 874 return change;860 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 861 hda_nid_t nid = get_amp_nid(kcontrol); 862 int chs = get_amp_channels(kcontrol); 863 int dir = get_amp_direction(kcontrol); 864 int idx = get_amp_index(kcontrol); 865 long *valp = ucontrol->value.integer.value; 866 int change = 0; 867 868 if (chs & 1) { 869 change = snd_hda_codec_amp_update(codec, nid, 0, dir, idx, 870 0x80, *valp ? 0 : 0x80); 871 valp++; 872 } 873 if (chs & 2) 874 change |= snd_hda_codec_amp_update(codec, nid, 1, dir, idx, 875 0x80, *valp ? 0 : 0x80); 876 877 return change; 875 878 } 876 879 … … 886 889 int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 887 890 { 888 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);889 unsigned long pval;890 int err;891 892 down(&codec->spdif_mutex); /* reuse spdif_mutex */893 pval = kcontrol->private_value;894 kcontrol->private_value = pval & ~AMP_VAL_IDX_MASK; /* index 0 */895 err = snd_hda_mixer_amp_switch_get(kcontrol, ucontrol);896 kcontrol->private_value = pval;897 up(&codec->spdif_mutex);898 return err;891 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 892 unsigned long pval; 893 int err; 894 895 down(&codec->spdif_mutex); /* reuse spdif_mutex */ 896 pval = kcontrol->private_value; 897 kcontrol->private_value = pval & ~AMP_VAL_IDX_MASK; /* index 0 */ 898 err = snd_hda_mixer_amp_switch_get(kcontrol, ucontrol); 899 kcontrol->private_value = pval; 900 up(&codec->spdif_mutex); 901 return err; 899 902 } 900 903 901 904 int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 902 905 { 903 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);904 unsigned long pval;905 int i, indices, err = 0, change = 0;906 907 down(&codec->spdif_mutex); /* reuse spdif_mutex */908 pval = kcontrol->private_value;909 indices = (pval & AMP_VAL_IDX_MASK) >> AMP_VAL_IDX_SHIFT;910 for (i = 0; i < indices; i++) {911 kcontrol->private_value = (pval & ~AMP_VAL_IDX_MASK) | (i << AMP_VAL_IDX_SHIFT);912 err = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);913 if (err < 0)914 break;915 change |= err;916 }917 kcontrol->private_value = pval;918 up(&codec->spdif_mutex);919 return err < 0 ? err : change;906 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 907 unsigned long pval; 908 int i, indices, err = 0, change = 0; 909 910 down(&codec->spdif_mutex); /* reuse spdif_mutex */ 911 pval = kcontrol->private_value; 912 indices = (pval & AMP_VAL_IDX_MASK) >> AMP_VAL_IDX_SHIFT; 913 for (i = 0; i < indices; i++) { 914 kcontrol->private_value = (pval & ~AMP_VAL_IDX_MASK) | (i << AMP_VAL_IDX_SHIFT); 915 err = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol); 916 if (err < 0) 917 break; 918 change |= err; 919 } 920 kcontrol->private_value = pval; 921 up(&codec->spdif_mutex); 922 return err < 0 ? err : change; 920 923 } 921 924 … … 926 929 static int snd_hda_spdif_mask_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 927 930 { 928 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;929 uinfo->count = 1;930 return 0;931 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; 932 uinfo->count = 1; 933 return 0; 931 934 } 932 935 933 936 static int snd_hda_spdif_cmask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 934 937 { 935 ucontrol->value.iec958.status[0] = IEC958_AES0_PROFESSIONAL |936 IEC958_AES0_NONAUDIO |937 IEC958_AES0_CON_EMPHASIS_5015 |938 IEC958_AES0_CON_NOT_COPYRIGHT;939 ucontrol->value.iec958.status[1] = IEC958_AES1_CON_CATEGORY |940 IEC958_AES1_CON_ORIGINAL;941 return 0;938 ucontrol->value.iec958.status[0] = IEC958_AES0_PROFESSIONAL | 939 IEC958_AES0_NONAUDIO | 940 IEC958_AES0_CON_EMPHASIS_5015 | 941 IEC958_AES0_CON_NOT_COPYRIGHT; 942 ucontrol->value.iec958.status[1] = IEC958_AES1_CON_CATEGORY | 943 IEC958_AES1_CON_ORIGINAL; 944 return 0; 942 945 } 943 946 944 947 static int snd_hda_spdif_pmask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 945 948 { 946 ucontrol->value.iec958.status[0] = IEC958_AES0_PROFESSIONAL |947 IEC958_AES0_NONAUDIO |948 IEC958_AES0_PRO_EMPHASIS_5015;949 return 0;949 ucontrol->value.iec958.status[0] = IEC958_AES0_PROFESSIONAL | 950 IEC958_AES0_NONAUDIO | 951 IEC958_AES0_PRO_EMPHASIS_5015; 952 return 0; 950 953 } 951 954 952 955 static int snd_hda_spdif_default_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 953 956 { 954 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);955 956 ucontrol->value.iec958.status[0] = codec->spdif_status & 0xff;957 ucontrol->value.iec958.status[1] = (codec->spdif_status >> 8) & 0xff;958 ucontrol->value.iec958.status[2] = (codec->spdif_status >> 16) & 0xff;959 ucontrol->value.iec958.status[3] = (codec->spdif_status >> 24) & 0xff;960 961 return 0;957 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 958 959 ucontrol->value.iec958.status[0] = codec->spdif_status & 0xff; 960 ucontrol->value.iec958.status[1] = (codec->spdif_status >> 8) & 0xff; 961 ucontrol->value.iec958.status[2] = (codec->spdif_status >> 16) & 0xff; 962 ucontrol->value.iec958.status[3] = (codec->spdif_status >> 24) & 0xff; 963 964 return 0; 962 965 } 963 966 … … 967 970 static unsigned short convert_from_spdif_status(unsigned int sbits) 968 971 { 969 unsigned short val = 0;970 971 if (sbits & IEC958_AES0_PROFESSIONAL)972 val |= 1 << 6;973 if (sbits & IEC958_AES0_NONAUDIO)974 val |= 1 << 5;975 if (sbits & IEC958_AES0_PROFESSIONAL) {976 if ((sbits & IEC958_AES0_PRO_EMPHASIS) == IEC958_AES0_PRO_EMPHASIS_5015)977 val |= 1 << 3;978 } else {979 if ((sbits & IEC958_AES0_CON_EMPHASIS) == IEC958_AES0_CON_EMPHASIS_5015)980 val |= 1 << 3;981 if (! (sbits & IEC958_AES0_CON_NOT_COPYRIGHT))982 val |= 1 << 4;983 if (sbits & (IEC958_AES1_CON_ORIGINAL << 8))984 val |= 1 << 7;985 val |= sbits & (IEC958_AES1_CON_CATEGORY << 8);986 }987 return val;972 unsigned short val = 0; 973 974 if (sbits & IEC958_AES0_PROFESSIONAL) 975 val |= 1 << 6; 976 if (sbits & IEC958_AES0_NONAUDIO) 977 val |= 1 << 5; 978 if (sbits & IEC958_AES0_PROFESSIONAL) { 979 if ((sbits & IEC958_AES0_PRO_EMPHASIS) == IEC958_AES0_PRO_EMPHASIS_5015) 980 val |= 1 << 3; 981 } else { 982 if ((sbits & IEC958_AES0_CON_EMPHASIS) == IEC958_AES0_CON_EMPHASIS_5015) 983 val |= 1 << 3; 984 if (! (sbits & IEC958_AES0_CON_NOT_COPYRIGHT)) 985 val |= 1 << 4; 986 if (sbits & (IEC958_AES1_CON_ORIGINAL << 8)) 987 val |= 1 << 7; 988 val |= sbits & (IEC958_AES1_CON_CATEGORY << 8); 989 } 990 return val; 988 991 } 989 992 … … 992 995 static unsigned int convert_to_spdif_status(unsigned short val) 993 996 { 994 unsigned int sbits = 0;995 996 if (val & (1 << 5))997 sbits |= IEC958_AES0_NONAUDIO;998 if (val & (1 << 6))999 sbits |= IEC958_AES0_PROFESSIONAL;1000 if (sbits & IEC958_AES0_PROFESSIONAL) {1001 if (sbits & (1 << 3))1002 sbits |= IEC958_AES0_PRO_EMPHASIS_5015;1003 } else {1004 if (val & (1 << 3))1005 sbits |= IEC958_AES0_CON_EMPHASIS_5015;1006 if (! (val & (1 << 4)))1007 sbits |= IEC958_AES0_CON_NOT_COPYRIGHT;1008 if (val & (1 << 7))1009 sbits |= (IEC958_AES1_CON_ORIGINAL << 8);1010 sbits |= val & (0x7f << 8);1011 }1012 return sbits;997 unsigned int sbits = 0; 998 999 if (val & (1 << 5)) 1000 sbits |= IEC958_AES0_NONAUDIO; 1001 if (val & (1 << 6)) 1002 sbits |= IEC958_AES0_PROFESSIONAL; 1003 if (sbits & IEC958_AES0_PROFESSIONAL) { 1004 if (sbits & (1 << 3)) 1005 sbits |= IEC958_AES0_PRO_EMPHASIS_5015; 1006 } else { 1007 if (val & (1 << 3)) 1008 sbits |= IEC958_AES0_CON_EMPHASIS_5015; 1009 if (! (val & (1 << 4))) 1010 sbits |= IEC958_AES0_CON_NOT_COPYRIGHT; 1011 if (val & (1 << 7)) 1012 sbits |= (IEC958_AES1_CON_ORIGINAL << 8); 1013 sbits |= val & (0x7f << 8); 1014 } 1015 return sbits; 1013 1016 } 1014 1017 1015 1018 static int snd_hda_spdif_default_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 1016 1019 { 1017 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);1018 hda_nid_t nid = kcontrol->private_value;1019 unsigned short val;1020 int change;1021 1022 down(&codec->spdif_mutex);1023 codec->spdif_status = ucontrol->value.iec958.status[0] |1024 ((unsigned int)ucontrol->value.iec958.status[1] << 8) |1025 ((unsigned int)ucontrol->value.iec958.status[2] << 16) |1026 ((unsigned int)ucontrol->value.iec958.status[3] << 24);1027 val = convert_from_spdif_status(codec->spdif_status);1028 val |= codec->spdif_ctls & 1;1029 change = codec->spdif_ctls != val;1030 codec->spdif_ctls = val;1031 1032 if (change || codec->in_resume) {1033 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, val & 0xff);1034 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_2, val >> 8);1035 }1036 1037 up(&codec->spdif_mutex);1038 return change;1020 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1021 hda_nid_t nid = kcontrol->private_value; 1022 unsigned short val; 1023 int change; 1024 1025 down(&codec->spdif_mutex); 1026 codec->spdif_status = ucontrol->value.iec958.status[0] | 1027 ((unsigned int)ucontrol->value.iec958.status[1] << 8) | 1028 ((unsigned int)ucontrol->value.iec958.status[2] << 16) | 1029 ((unsigned int)ucontrol->value.iec958.status[3] << 24); 1030 val = convert_from_spdif_status(codec->spdif_status); 1031 val |= codec->spdif_ctls & 1; 1032 change = codec->spdif_ctls != val; 1033 codec->spdif_ctls = val; 1034 1035 if (change || codec->in_resume) { 1036 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, val & 0xff); 1037 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_2, val >> 8); 1038 } 1039 1040 up(&codec->spdif_mutex); 1041 return change; 1039 1042 } 1040 1043 1041 1044 static int snd_hda_spdif_out_switch_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 1042 1045 { 1043 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;1044 uinfo->count = 1;1045 uinfo->value.integer.min = 0;1046 uinfo->value.integer.max = 1;1047 return 0;1046 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; 1047 uinfo->count = 1; 1048 uinfo->value.integer.min = 0; 1049 uinfo->value.integer.max = 1; 1050 return 0; 1048 1051 } 1049 1052 1050 1053 static int snd_hda_spdif_out_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 1051 1054 { 1052 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);1053 1054 ucontrol->value.integer.value[0] = codec->spdif_ctls & 1;1055 return 0;1055 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1056 1057 ucontrol->value.integer.value[0] = codec->spdif_ctls & 1; 1058 return 0; 1056 1059 } 1057 1060 1058 1061 static int snd_hda_spdif_out_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 1059 1062 { 1060 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);1061 hda_nid_t nid = kcontrol->private_value;1062 unsigned short val;1063 int change;1064 1065 down(&codec->spdif_mutex);1066 val = codec->spdif_ctls & ~1;1067 if (ucontrol->value.integer.value[0])1068 val |= 1;1069 change = codec->spdif_ctls != val;1070 if (change || codec->in_resume) {1071 codec->spdif_ctls = val;1072 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, val & 0xff);1073 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,1074 AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT |1075 AC_AMP_SET_OUTPUT | ((val & 1) ? 0 : 0x80));1076 }1077 up(&codec->spdif_mutex);1078 return change;1063 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1064 hda_nid_t nid = kcontrol->private_value; 1065 unsigned short val; 1066 int change; 1067 1068 down(&codec->spdif_mutex); 1069 val = codec->spdif_ctls & ~1; 1070 if (ucontrol->value.integer.value[0]) 1071 val |= 1; 1072 change = codec->spdif_ctls != val; 1073 if (change || codec->in_resume) { 1074 codec->spdif_ctls = val; 1075 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, val & 0xff); 1076 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 1077 AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | 1078 AC_AMP_SET_OUTPUT | ((val & 1) ? 0 : 0x80)); 1079 } 1080 up(&codec->spdif_mutex); 1081 return change; 1079 1082 } 1080 1083 1081 1084 static struct snd_kcontrol_new dig_mixes[] = { 1082 {1083 .access = SNDRV_CTL_ELEM_ACCESS_READ,1084 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,1085 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK),1086 .info = snd_hda_spdif_mask_info,1087 .get = snd_hda_spdif_cmask_get,1088 },1089 {1090 .access = SNDRV_CTL_ELEM_ACCESS_READ,1091 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,1092 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PRO_MASK),1093 .info = snd_hda_spdif_mask_info,1094 .get = snd_hda_spdif_pmask_get,1095 },1096 {1097 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,1098 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),1099 .info = snd_hda_spdif_mask_info,1100 .get = snd_hda_spdif_default_get,1101 .put = snd_hda_spdif_default_put,1102 },1103 {1104 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,1105 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH),1106 .info = snd_hda_spdif_out_switch_info,1107 .get = snd_hda_spdif_out_switch_get,1108 .put = snd_hda_spdif_out_switch_put,1109 },1110 {0} /* end */1085 { 1086 .access = SNDRV_CTL_ELEM_ACCESS_READ, 1087 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1088 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK), 1089 .info = snd_hda_spdif_mask_info, 1090 .get = snd_hda_spdif_cmask_get, 1091 }, 1092 { 1093 .access = SNDRV_CTL_ELEM_ACCESS_READ, 1094 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1095 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PRO_MASK), 1096 .info = snd_hda_spdif_mask_info, 1097 .get = snd_hda_spdif_pmask_get, 1098 }, 1099 { 1100 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1101 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), 1102 .info = snd_hda_spdif_mask_info, 1103 .get = snd_hda_spdif_default_get, 1104 .put = snd_hda_spdif_default_put, 1105 }, 1106 { 1107 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1108 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH), 1109 .info = snd_hda_spdif_out_switch_info, 1110 .get = snd_hda_spdif_out_switch_get, 1111 .put = snd_hda_spdif_out_switch_put, 1112 }, 1113 {0} /* end */ 1111 1114 }; 1112 1115 … … 1123 1126 int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid) 1124 1127 { 1125 int err;1126 struct snd_kcontrol *kctl;1127 struct snd_kcontrol_new *dig_mix;1128 1129 for (dig_mix = dig_mixes; dig_mix->name; dig_mix++) {1130 kctl = snd_ctl_new1(dig_mix, codec);1131 kctl->private_value = nid;1132 if ((err = snd_ctl_add(codec->bus->card, kctl)) < 0)1133 return err;1134 }1135 codec->spdif_ctls = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_DIGI_CONVERT, 0);1136 codec->spdif_status = convert_to_spdif_status(codec->spdif_ctls);1137 return 0;1128 int err; 1129 struct snd_kcontrol *kctl; 1130 struct snd_kcontrol_new *dig_mix; 1131 1132 for (dig_mix = dig_mixes; dig_mix->name; dig_mix++) { 1133 kctl = snd_ctl_new1(dig_mix, codec); 1134 kctl->private_value = nid; 1135 if ((err = snd_ctl_add(codec->bus->card, kctl)) < 0) 1136 return err; 1137 } 1138 codec->spdif_ctls = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_DIGI_CONVERT, 0); 1139 codec->spdif_status = convert_to_spdif_status(codec->spdif_ctls); 1140 return 0; 1138 1141 } 1139 1142 … … 1146 1149 static int snd_hda_spdif_in_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 1147 1150 { 1148 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);1149 1150 ucontrol->value.integer.value[0] = codec->spdif_in_enable;1151 return 0;1151 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1152 1153 ucontrol->value.integer.value[0] = codec->spdif_in_enable; 1154 return 0; 1152 1155 } 1153 1156 1154 1157 static int snd_hda_spdif_in_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 1155 1158 { 1156 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);1157 hda_nid_t nid = kcontrol->private_value;1158 unsigned int val = !!ucontrol->value.integer.value[0];1159 int change;1160 1161 down(&codec->spdif_mutex);1162 change = codec->spdif_in_enable != val;1163 if (change || codec->in_resume) {1164 codec->spdif_in_enable = val;1165 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, val);1166 }1167 up(&codec->spdif_mutex);1168 return change;1159 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1160 hda_nid_t nid = kcontrol->private_value; 1161 unsigned int val = !!ucontrol->value.integer.value[0]; 1162 int change; 1163 1164 down(&codec->spdif_mutex); 1165 change = codec->spdif_in_enable != val; 1166 if (change || codec->in_resume) { 1167 codec->spdif_in_enable = val; 1168 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, val); 1169 } 1170 up(&codec->spdif_mutex); 1171 return change; 1169 1172 } 1170 1173 1171 1174 static int snd_hda_spdif_in_status_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 1172 1175 { 1173 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);1174 hda_nid_t nid = kcontrol->private_value;1175 unsigned short val;1176 unsigned int sbits;1177 1178 val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_DIGI_CONVERT, 0);1179 sbits = convert_to_spdif_status(val);1180 ucontrol->value.iec958.status[0] = sbits;1181 ucontrol->value.iec958.status[1] = sbits >> 8;1182 ucontrol->value.iec958.status[2] = sbits >> 16;1183 ucontrol->value.iec958.status[3] = sbits >> 24;1184 return 0;1176 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1177 hda_nid_t nid = kcontrol->private_value; 1178 unsigned short val; 1179 unsigned int sbits; 1180 1181 val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_DIGI_CONVERT, 0); 1182 sbits = convert_to_spdif_status(val); 1183 ucontrol->value.iec958.status[0] = sbits; 1184 ucontrol->value.iec958.status[1] = sbits >> 8; 1185 ucontrol->value.iec958.status[2] = sbits >> 16; 1186 ucontrol->value.iec958.status[3] = sbits >> 24; 1187 return 0; 1185 1188 } 1186 1189 1187 1190 static struct snd_kcontrol_new dig_in_ctls[] = { 1188 {1189 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,1190 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH),1191 .info = snd_hda_spdif_in_switch_info,1192 .get = snd_hda_spdif_in_switch_get,1193 .put = snd_hda_spdif_in_switch_put,1194 },1195 {1196 .access = SNDRV_CTL_ELEM_ACCESS_READ,1197 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,1198 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,DEFAULT),1199 .info = snd_hda_spdif_mask_info,1200 .get = snd_hda_spdif_in_status_get,1201 },1202 {0} /* end */1191 { 1192 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1193 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), 1194 .info = snd_hda_spdif_in_switch_info, 1195 .get = snd_hda_spdif_in_switch_get, 1196 .put = snd_hda_spdif_in_switch_put, 1197 }, 1198 { 1199 .access = SNDRV_CTL_ELEM_ACCESS_READ, 1200 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1201 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,DEFAULT), 1202 .info = snd_hda_spdif_mask_info, 1203 .get = snd_hda_spdif_in_status_get, 1204 }, 1205 {0} /* end */ 1203 1206 }; 1204 1207 … … 1215 1218 int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid) 1216 1219 { 1217 int err;1218 struct snd_kcontrol *kctl;1219 struct snd_kcontrol_new *dig_mix;1220 1221 for (dig_mix = dig_in_ctls; dig_mix->name; dig_mix++) {1222 kctl = snd_ctl_new1(dig_mix, codec);1223 kctl->private_value = nid;1224 if ((err = snd_ctl_add(codec->bus->card, kctl)) < 0)1225 return err;1226 }1227 codec->spdif_in_enable = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_DIGI_CONVERT, 0) & 1;1228 return 0;1220 int err; 1221 struct snd_kcontrol *kctl; 1222 struct snd_kcontrol_new *dig_mix; 1223 1224 for (dig_mix = dig_in_ctls; dig_mix->name; dig_mix++) { 1225 kctl = snd_ctl_new1(dig_mix, codec); 1226 kctl->private_value = nid; 1227 if ((err = snd_ctl_add(codec->bus->card, kctl)) < 0) 1228 return err; 1229 } 1230 codec->spdif_in_enable = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_DIGI_CONVERT, 0) & 1; 1231 return 0; 1229 1232 } 1230 1233 … … 1234 1237 */ 1235 1238 static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg, 1236 unsigned int power_state)1237 { 1238 hda_nid_t nid, nid_start;1239 int nodes;1240 1241 snd_hda_codec_write(codec, fg, 0, AC_VERB_SET_POWER_STATE,1242 power_state);1243 1244 nodes = snd_hda_get_sub_nodes(codec, fg, &nid_start);1245 for (nid = nid_start; nid < nodes + nid_start; nid++) {1246 if (get_wcaps(codec, nid) & AC_WCAP_POWER)1247 snd_hda_codec_write(codec, nid, 0,1248 AC_VERB_SET_POWER_STATE,1249 power_state);1250 }1251 1252 if (power_state == AC_PWRST_D0)1253 msleep(10);1239 unsigned int power_state) 1240 { 1241 hda_nid_t nid, nid_start; 1242 int nodes; 1243 1244 snd_hda_codec_write(codec, fg, 0, AC_VERB_SET_POWER_STATE, 1245 power_state); 1246 1247 nodes = snd_hda_get_sub_nodes(codec, fg, &nid_start); 1248 for (nid = nid_start; nid < nodes + nid_start; nid++) { 1249 if (get_wcaps(codec, nid) & AC_WCAP_POWER) 1250 snd_hda_codec_write(codec, nid, 0, 1251 AC_VERB_SET_POWER_STATE, 1252 power_state); 1253 } 1254 1255 if (power_state == AC_PWRST_D0) 1256 msleep(10); 1254 1257 } 1255 1258 … … 1265 1268 int snd_hda_build_controls(struct hda_bus *bus) 1266 1269 { 1267 struct list_head *p;1268 1269 /* build controls */1270 list_for_each(p, &bus->codec_list) {1271 struct hda_codec *codec = list_entry(p, struct hda_codec, list);1272 int err;1273 if (! codec->patch_ops.build_controls)1274 continue;1275 err = codec->patch_ops.build_controls(codec);1276 if (err < 0)1277 return err;1278 }1279 1280 /* initialize */1281 list_for_each(p, &bus->codec_list) {1282 struct hda_codec *codec = list_entry(p, struct hda_codec, list);1283 int err;1284 hda_set_power_state(codec,1285 codec->afg ? codec->afg : codec->mfg,1286 AC_PWRST_D0);1287 if (! codec->patch_ops.init)1288 continue;1289 err = codec->patch_ops.init(codec);1290 if (err < 0)1291 return err;1292 }1293 return 0;1270 struct list_head *p; 1271 1272 /* build controls */ 1273 list_for_each(p, &bus->codec_list) { 1274 struct hda_codec *codec = list_entry(p, struct hda_codec, list); 1275 int err; 1276 if (! codec->patch_ops.build_controls) 1277 continue; 1278 err = codec->patch_ops.build_controls(codec); 1279 if (err < 0) 1280 return err; 1281 } 1282 1283 /* initialize */ 1284 list_for_each(p, &bus->codec_list) { 1285 struct hda_codec *codec = list_entry(p, struct hda_codec, list); 1286 int err; 1287 hda_set_power_state(codec, 1288 codec->afg ? codec->afg : codec->mfg, 1289 AC_PWRST_D0); 1290 if (! codec->patch_ops.init) 1291 continue; 1292 err = codec->patch_ops.init(codec); 1293 if (err < 0) 1294 return err; 1295 } 1296 return 0; 1294 1297 } 1295 1298 … … 1299 1302 */ 1300 1303 struct hda_rate_tbl { 1301 unsigned int hz;1302 unsigned int alsa_bits;1303 unsigned int hda_fmt;1304 unsigned int hz; 1305 unsigned int alsa_bits; 1306 unsigned int hda_fmt; 1304 1307 }; 1305 1308 1306 1309 static struct hda_rate_tbl rate_bits[] = { 1307 /* rate in Hz, ALSA rate bitmask, HDA format value */1308 1309 /* autodetected value used in snd_hda_query_supported_pcm */1310 { 8000, SNDRV_PCM_RATE_8000, 0x0500 }, /* 1/6 x 48 */1311 { 11025, SNDRV_PCM_RATE_11025, 0x4300 }, /* 1/4 x 44 */1312 { 16000, SNDRV_PCM_RATE_16000, 0x0200 }, /* 1/3 x 48 */1313 { 22050, SNDRV_PCM_RATE_22050, 0x4100 }, /* 1/2 x 44 */1314 { 32000, SNDRV_PCM_RATE_32000, 0x0a00 }, /* 2/3 x 48 */1315 { 44100, SNDRV_PCM_RATE_44100, 0x4000 }, /* 44 */1316 { 48000, SNDRV_PCM_RATE_48000, 0x0000 }, /* 48 */1317 { 88200, SNDRV_PCM_RATE_88200, 0x4800 }, /* 2 x 44 */1318 { 96000, SNDRV_PCM_RATE_96000, 0x0800 }, /* 2 x 48 */1319 { 176400, SNDRV_PCM_RATE_176400, 0x5800 },/* 4 x 44 */1320 { 192000, SNDRV_PCM_RATE_192000, 0x1800 }, /* 4 x 48 */1321 1322 /* not autodetected value */1323 { 9600, SNDRV_PCM_RATE_KNOT, 0x0400 }, /* 1/5 x 48 */1324 1325 { 0 } /* terminator */1310 /* rate in Hz, ALSA rate bitmask, HDA format value */ 1311 1312 /* autodetected value used in snd_hda_query_supported_pcm */ 1313 { 8000, SNDRV_PCM_RATE_8000, 0x0500 }, /* 1/6 x 48 */ 1314 { 11025, SNDRV_PCM_RATE_11025, 0x4300 }, /* 1/4 x 44 */ 1315 { 16000, SNDRV_PCM_RATE_16000, 0x0200 }, /* 1/3 x 48 */ 1316 { 22050, SNDRV_PCM_RATE_22050, 0x4100 }, /* 1/2 x 44 */ 1317 { 32000, SNDRV_PCM_RATE_32000, 0x0a00 }, /* 2/3 x 48 */ 1318 { 44100, SNDRV_PCM_RATE_44100, 0x4000 }, /* 44 */ 1319 { 48000, SNDRV_PCM_RATE_48000, 0x0000 }, /* 48 */ 1320 { 88200, SNDRV_PCM_RATE_88200, 0x4800 }, /* 2 x 44 */ 1321 { 96000, SNDRV_PCM_RATE_96000, 0x0800 }, /* 2 x 48 */ 1322 { 176400, SNDRV_PCM_RATE_176400, 0x5800 },/* 4 x 44 */ 1323 { 192000, SNDRV_PCM_RATE_192000, 0x1800 }, /* 4 x 48 */ 1324 1325 /* not autodetected value */ 1326 { 9600, SNDRV_PCM_RATE_KNOT, 0x0400 }, /* 1/5 x 48 */ 1327 1328 { 0 } /* terminator */ 1326 1329 }; 1327 1330 … … 1338 1341 */ 1339 1342 unsigned int snd_hda_calc_stream_format(unsigned int rate, 1340 unsigned int channels,1341 unsigned int format,1342 unsigned int maxbps)1343 { 1344 int i;1345 unsigned int val = 0;1346 1347 for (i = 0; rate_bits[i].hz; i++)1348 if (rate_bits[i].hz == rate) {1349 val = rate_bits[i].hda_fmt;1350 break;1351 }1352 if (! rate_bits[i].hz) {1353 snd_printdd("invalid rate %d\n", rate);1354 return 0;1355 }1356 1357 if (channels == 0 || channels > 8) {1358 snd_printdd("invalid channels %d\n", channels);1359 return 0;1360 }1361 val |= channels - 1;1362 1363 switch (snd_pcm_format_width(format)) {1364 case 8: val |= 0x00; break;1365 case 16: val |= 0x10; break;1366 case 20:1367 case 24:1368 case 32:1369 if (maxbps >= 32)1370 val |= 0x40;1371 else if (maxbps >= 24)1372 val |= 0x30;1373 else1374 val |= 0x20;1375 break;1376 default:1377 snd_printdd("invalid format width %d\n", snd_pcm_format_width(format));1378 return 0;1379 }1380 1381 return val;1343 unsigned int channels, 1344 unsigned int format, 1345 unsigned int maxbps) 1346 { 1347 int i; 1348 unsigned int val = 0; 1349 1350 for (i = 0; rate_bits[i].hz; i++) 1351 if (rate_bits[i].hz == rate) { 1352 val = rate_bits[i].hda_fmt; 1353 break; 1354 } 1355 if (! rate_bits[i].hz) { 1356 snd_printdd("invalid rate %d\n", rate); 1357 return 0; 1358 } 1359 1360 if (channels == 0 || channels > 8) { 1361 snd_printdd("invalid channels %d\n", channels); 1362 return 0; 1363 } 1364 val |= channels - 1; 1365 1366 switch (snd_pcm_format_width(format)) { 1367 case 8: val |= 0x00; break; 1368 case 16: val |= 0x10; break; 1369 case 20: 1370 case 24: 1371 case 32: 1372 if (maxbps >= 32) 1373 val |= 0x40; 1374 else if (maxbps >= 24) 1375 val |= 0x30; 1376 else 1377 val |= 0x20; 1378 break; 1379 default: 1380 snd_printdd("invalid format width %d\n", snd_pcm_format_width(format)); 1381 return 0; 1382 } 1383 1384 return val; 1382 1385 } 1383 1386 … … 1396 1399 */ 1397 1400 int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, 1398 u32 *ratesp, u64 *formatsp, unsigned int *bpsp)1399 { 1400 int i;1401 unsigned int val, streams;1402 1403 val = 0;1404 if (nid != codec->afg &&1405 (get_wcaps(codec, nid) & AC_WCAP_FORMAT_OVRD)) {1406 val = snd_hda_param_read(codec, nid, AC_PAR_PCM);1407 if (val == -1)1408 return -EIO;1409 }1410 if (! val)1411 val = snd_hda_param_read(codec, codec->afg, AC_PAR_PCM);1412 1413 if (ratesp) {1414 u32 rates = 0;1415 for (i = 0; rate_bits[i].hz; i++) {1416 if (val & (1 << i))1417 rates |= rate_bits[i].alsa_bits;1418 }1419 *ratesp = rates;1420 }1421 1422 if (formatsp || bpsp) {1423 u64 formats = 0;1424 unsigned int bps;1425 unsigned int wcaps;1426 1427 wcaps = get_wcaps(codec, nid);1428 streams = snd_hda_param_read(codec, nid, AC_PAR_STREAM);1429 if (streams == -1)1430 return -EIO;1431 if (! streams) {1432 streams = snd_hda_param_read(codec, codec->afg, AC_PAR_STREAM);1433 if (streams == -1)1434 return -EIO;1435 }1436 1437 bps = 0;1438 if (streams & AC_SUPFMT_PCM) {1439 if (val & AC_SUPPCM_BITS_8) {1440 formats |= SNDRV_PCM_FMTBIT_U8;1441 bps = 8;1442 }1443 if (val & AC_SUPPCM_BITS_16) {1444 formats |= SNDRV_PCM_FMTBIT_S16_LE;1445 bps = 16;1446 }1447 if (wcaps & AC_WCAP_DIGITAL) {1448 if (val & AC_SUPPCM_BITS_32)1449 formats |= SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE;1450 if (val & (AC_SUPPCM_BITS_20|AC_SUPPCM_BITS_24))1451 formats |= SNDRV_PCM_FMTBIT_S32_LE;1452 if (val & AC_SUPPCM_BITS_24)1453 bps = 24;1454 else if (val & AC_SUPPCM_BITS_20)1455 bps = 20;1456 } else if (val & (AC_SUPPCM_BITS_20|AC_SUPPCM_BITS_24|AC_SUPPCM_BITS_32)) {1457 formats |= SNDRV_PCM_FMTBIT_S32_LE;1458 if (val & AC_SUPPCM_BITS_32)1459 bps = 32;1460 else if (val & AC_SUPPCM_BITS_20)1461 bps = 20;1462 else if (val & AC_SUPPCM_BITS_24)1463 bps = 24;1464 }1465 }1466 else if (streams == AC_SUPFMT_FLOAT32) { /* should be exclusive */1467 formats |= SNDRV_PCM_FMTBIT_FLOAT_LE;1468 bps = 32;1469 } else if (streams == AC_SUPFMT_AC3) { /* should be exclusive */1470 /* temporary hack: we have still no proper support1471 * for the direct AC3 stream...1472 */1473 formats |= SNDRV_PCM_FMTBIT_U8;1474 bps = 8;1475 }1476 if (formatsp)1477 *formatsp = formats;1478 if (bpsp)1479 *bpsp = bps;1480 }1481 1482 return 0;1401 u32 *ratesp, u64 *formatsp, unsigned int *bpsp) 1402 { 1403 int i; 1404 unsigned int val, streams; 1405 1406 val = 0; 1407 if (nid != codec->afg && 1408 (get_wcaps(codec, nid) & AC_WCAP_FORMAT_OVRD)) { 1409 val = snd_hda_param_read(codec, nid, AC_PAR_PCM); 1410 if (val == -1) 1411 return -EIO; 1412 } 1413 if (! val) 1414 val = snd_hda_param_read(codec, codec->afg, AC_PAR_PCM); 1415 1416 if (ratesp) { 1417 u32 rates = 0; 1418 for (i = 0; rate_bits[i].hz; i++) { 1419 if (val & (1 << i)) 1420 rates |= rate_bits[i].alsa_bits; 1421 } 1422 *ratesp = rates; 1423 } 1424 1425 if (formatsp || bpsp) { 1426 u64 formats = 0; 1427 unsigned int bps; 1428 unsigned int wcaps; 1429 1430 wcaps = get_wcaps(codec, nid); 1431 streams = snd_hda_param_read(codec, nid, AC_PAR_STREAM); 1432 if (streams == -1) 1433 return -EIO; 1434 if (! streams) { 1435 streams = snd_hda_param_read(codec, codec->afg, AC_PAR_STREAM); 1436 if (streams == -1) 1437 return -EIO; 1438 } 1439 1440 bps = 0; 1441 if (streams & AC_SUPFMT_PCM) { 1442 if (val & AC_SUPPCM_BITS_8) { 1443 formats |= SNDRV_PCM_FMTBIT_U8; 1444 bps = 8; 1445 } 1446 if (val & AC_SUPPCM_BITS_16) { 1447 formats |= SNDRV_PCM_FMTBIT_S16_LE; 1448 bps = 16; 1449 } 1450 if (wcaps & AC_WCAP_DIGITAL) { 1451 if (val & AC_SUPPCM_BITS_32) 1452 formats |= SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE; 1453 if (val & (AC_SUPPCM_BITS_20|AC_SUPPCM_BITS_24)) 1454 formats |= SNDRV_PCM_FMTBIT_S32_LE; 1455 if (val & AC_SUPPCM_BITS_24) 1456 bps = 24; 1457 else if (val & AC_SUPPCM_BITS_20) 1458 bps = 20; 1459 } else if (val & (AC_SUPPCM_BITS_20|AC_SUPPCM_BITS_24|AC_SUPPCM_BITS_32)) { 1460 formats |= SNDRV_PCM_FMTBIT_S32_LE; 1461 if (val & AC_SUPPCM_BITS_32) 1462 bps = 32; 1463 else if (val & AC_SUPPCM_BITS_20) 1464 bps = 20; 1465 else if (val & AC_SUPPCM_BITS_24) 1466 bps = 24; 1467 } 1468 } 1469 else if (streams == AC_SUPFMT_FLOAT32) { /* should be exclusive */ 1470 formats |= SNDRV_PCM_FMTBIT_FLOAT_LE; 1471 bps = 32; 1472 } else if (streams == AC_SUPFMT_AC3) { /* should be exclusive */ 1473 /* temporary hack: we have still no proper support 1474 * for the direct AC3 stream... 1475 */ 1476 formats |= SNDRV_PCM_FMTBIT_U8; 1477 bps = 8; 1478 } 1479 if (formatsp) 1480 *formatsp = formats; 1481 if (bpsp) 1482 *bpsp = bps; 1483 } 1484 1485 return 0; 1483 1486 } 1484 1487 … … 1489 1492 */ 1490 1493 int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid, 1491 unsigned int format)1492 { 1493 int i;1494 unsigned int val = 0, rate, stream;1495 1496 if (nid != codec->afg &&1497 (get_wcaps(codec, nid) & AC_WCAP_FORMAT_OVRD)) {1498 val = snd_hda_param_read(codec, nid, AC_PAR_PCM);1499 if (val == -1)1500 return 0;1501 }1502 if (! val) {1503 val = snd_hda_param_read(codec, codec->afg, AC_PAR_PCM);1504 if (val == -1)1505 return 0;1506 }1507 1508 rate = format & 0xff00;1509 for (i = 0; rate_bits[i].hz; i++)1510 if (rate_bits[i].hda_fmt == rate) {1511 if (val & (1 << i))1512 break;1513 return 0;1514 }1515 if (! rate_bits[i].hz)1516 return 0;1517 1518 stream = snd_hda_param_read(codec, nid, AC_PAR_STREAM);1519 if (stream == -1)1520 return 0;1521 if (! stream && nid != codec->afg)1522 stream = snd_hda_param_read(codec, codec->afg, AC_PAR_STREAM);1523 if (! stream || stream == -1)1524 return 0;1525 1526 if (stream & AC_SUPFMT_PCM) {1527 switch (format & 0xf0) {1528 case 0x00:1529 if (! (val & AC_SUPPCM_BITS_8))1530 return 0;1531 break;1532 case 0x10:1533 if (! (val & AC_SUPPCM_BITS_16))1534 return 0;1535 break;1536 case 0x20:1537 if (! (val & AC_SUPPCM_BITS_20))1538 return 0;1539 break;1540 case 0x30:1541 if (! (val & AC_SUPPCM_BITS_24))1542 return 0;1543 break;1544 case 0x40:1545 if (! (val & AC_SUPPCM_BITS_32))1546 return 0;1547 break;1548 default:1549 return 0;1550 }1551 } else {1552 /* FIXME: check for float32 and AC3? */1553 }1554 1555 return 1;1494 unsigned int format) 1495 { 1496 int i; 1497 unsigned int val = 0, rate, stream; 1498 1499 if (nid != codec->afg && 1500 (get_wcaps(codec, nid) & AC_WCAP_FORMAT_OVRD)) { 1501 val = snd_hda_param_read(codec, nid, AC_PAR_PCM); 1502 if (val == -1) 1503 return 0; 1504 } 1505 if (! val) { 1506 val = snd_hda_param_read(codec, codec->afg, AC_PAR_PCM); 1507 if (val == -1) 1508 return 0; 1509 } 1510 1511 rate = format & 0xff00; 1512 for (i = 0; rate_bits[i].hz; i++) 1513 if (rate_bits[i].hda_fmt == rate) { 1514 if (val & (1 << i)) 1515 break; 1516 return 0; 1517 } 1518 if (! rate_bits[i].hz) 1519 return 0; 1520 1521 stream = snd_hda_param_read(codec, nid, AC_PAR_STREAM); 1522 if (stream == -1) 1523 return 0; 1524 if (! stream && nid != codec->afg) 1525 stream = snd_hda_param_read(codec, codec->afg, AC_PAR_STREAM); 1526 if (! stream || stream == -1) 1527 return 0; 1528 1529 if (stream & AC_SUPFMT_PCM) { 1530 switch (format & 0xf0) { 1531 case 0x00: 1532 if (! (val & AC_SUPPCM_BITS_8)) 1533 return 0; 1534 break; 1535 case 0x10: 1536 if (! (val & AC_SUPPCM_BITS_16)) 1537 return 0; 1538 break; 1539 case 0x20: 1540 if (! (val & AC_SUPPCM_BITS_20)) 1541 return 0; 1542 break; 1543 case 0x30: 1544 if (! (val & AC_SUPPCM_BITS_24)) 1545 return 0; 1546 break; 1547 case 0x40: 1548 if (! (val & AC_SUPPCM_BITS_32)) 1549 return 0; 1550 break; 1551 default: 1552 return 0; 1553 } 1554 } else { 1555 /* FIXME: check for float32 and AC3? */ 1556 } 1557 1558 return 1; 1556 1559 } 1557 1560 … … 1560 1563 */ 1561 1564 static int hda_pcm_default_open_close(struct hda_pcm_stream *hinfo, 1562 struct hda_codec *codec,1563 struct snd_pcm_substream *substream)1564 { 1565 return 0;1565 struct hda_codec *codec, 1566 struct snd_pcm_substream *substream) 1567 { 1568 return 0; 1566 1569 } 1567 1570 1568 1571 static int hda_pcm_default_prepare(struct hda_pcm_stream *hinfo, 1569 struct hda_codec *codec,1570 unsigned int stream_tag,1571 unsigned int format,1572 struct snd_pcm_substream *substream)1573 { 1574 snd_hda_codec_setup_stream(codec, hinfo->nid, stream_tag, 0, format);1575 return 0;1572 struct hda_codec *codec, 1573 unsigned int stream_tag, 1574 unsigned int format, 1575 struct snd_pcm_substream *substream) 1576 { 1577 snd_hda_codec_setup_stream(codec, hinfo->nid, stream_tag, 0, format); 1578 return 0; 1576 1579 } 1577 1580 1578 1581 static int hda_pcm_default_cleanup(struct hda_pcm_stream *hinfo, 1579 struct hda_codec *codec,1580 struct snd_pcm_substream *substream)1581 { 1582 snd_hda_codec_setup_stream(codec, hinfo->nid, 0, 0, 0);1583 return 0;1582 struct hda_codec *codec, 1583 struct snd_pcm_substream *substream) 1584 { 1585 snd_hda_codec_setup_stream(codec, hinfo->nid, 0, 0, 0); 1586 return 0; 1584 1587 } 1585 1588 1586 1589 static int set_pcm_default_values(struct hda_codec *codec, struct hda_pcm_stream *info) 1587 1590 { 1588 if (info->nid) {1589 /* query support PCM information from the given NID */1590 if (! info->rates || ! info->formats)1591 snd_hda_query_supported_pcm(codec, info->nid,1592 info->rates ? NULL : &info->rates,1593 info->formats ? NULL : &info->formats,1594 info->maxbps ? NULL : &info->maxbps);1595 }1596 if (info->ops.open == NULL)1597 info->ops.open = hda_pcm_default_open_close;1598 if (info->ops.close == NULL)1599 info->ops.close = hda_pcm_default_open_close;1600 if (info->ops.prepare == NULL) {1601 snd_assert(info->nid, return -EINVAL);1602 info->ops.prepare = hda_pcm_default_prepare;1603 }1604 if (info->ops.cleanup == NULL) {1605 snd_assert(info->nid, return -EINVAL);1606 info->ops.cleanup = hda_pcm_default_cleanup;1607 }1608 return 0;1591 if (info->nid) { 1592 /* query support PCM information from the given NID */ 1593 if (! info->rates || ! info->formats) 1594 snd_hda_query_supported_pcm(codec, info->nid, 1595 info->rates ? NULL : &info->rates, 1596 info->formats ? NULL : &info->formats, 1597 info->maxbps ? NULL : &info->maxbps); 1598 } 1599 if (info->ops.open == NULL) 1600 info->ops.open = hda_pcm_default_open_close; 1601 if (info->ops.close == NULL) 1602 info->ops.close = hda_pcm_default_open_close; 1603 if (info->ops.prepare == NULL) { 1604 snd_assert(info->nid, return -EINVAL); 1605 info->ops.prepare = hda_pcm_default_prepare; 1606 } 1607 if (info->ops.cleanup == NULL) { 1608 snd_assert(info->nid, return -EINVAL); 1609 info->ops.cleanup = hda_pcm_default_cleanup; 1610 } 1611 return 0; 1609 1612 } 1610 1613 … … 1637 1640 int snd_hda_build_pcms(struct hda_bus *bus) 1638 1641 { 1639 struct list_head *p;1640 1641 list_for_each(p, &bus->codec_list) {1642 struct hda_codec *codec = list_entry(p, struct hda_codec, list);1643 unsigned int pcm, s;1644 int err;1645 if (! codec->patch_ops.build_pcms)1646 continue;1647 err = codec->patch_ops.build_pcms(codec);1648 if (err < 0)1649 return err;1650 for (pcm = 0; pcm < codec->num_pcms; pcm++) {1651 for (s = 0; s < 2; s++) {1652 struct hda_pcm_stream *info;1653 info = &codec->pcm_info[pcm].stream[s];1654 if (! info->substreams)1655 continue;1656 err = set_pcm_default_values(codec, info);1657 if (err < 0)1658 return err;1659 }1660 }1661 }1662 return 0;1642 struct list_head *p; 1643 1644 list_for_each(p, &bus->codec_list) { 1645 struct hda_codec *codec = list_entry(p, struct hda_codec, list); 1646 unsigned int pcm, s; 1647 int err; 1648 if (! codec->patch_ops.build_pcms) 1649 continue; 1650 err = codec->patch_ops.build_pcms(codec); 1651 if (err < 0) 1652 return err; 1653 for (pcm = 0; pcm < codec->num_pcms; pcm++) { 1654 for (s = 0; s < 2; s++) { 1655 struct hda_pcm_stream *info; 1656 info = &codec->pcm_info[pcm].stream[s]; 1657 if (! info->substreams) 1658 continue; 1659 err = set_pcm_default_values(codec, info); 1660 if (err < 0) 1661 return err; 1662 } 1663 } 1664 } 1665 return 0; 1663 1666 } 1664 1667 … … 1677 1680 int snd_hda_check_board_config(struct hda_codec *codec, const struct hda_board_config *tbl) 1678 1681 { 1679 const struct hda_board_config *c;1680 1681 if (codec->bus->modelname) {1682 for (c = tbl; c->modelname || c->pci_subvendor; c++) {1683 if (c->modelname &&1684 ! strcmp(codec->bus->modelname, c->modelname)) {1685 snd_printd(KERN_INFO "hda_codec: model '%s' is selected\n", c->modelname);1686 return c->config;1687 }1688 }1689 }1690 1691 if (codec->bus->pci) {1692 u16 subsystem_vendor, subsystem_device;1693 pci_read_config_word(codec->bus->pci, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vendor);1694 pci_read_config_word(codec->bus->pci, PCI_SUBSYSTEM_ID, &subsystem_device);1695 for (c = tbl; c->modelname || c->pci_subvendor; c++) {1696 if (c->pci_subvendor == subsystem_vendor &&1697 (! c->pci_subdevice /* all match */||1698 (c->pci_subdevice == subsystem_device))) {1699 snd_printdd(KERN_INFO "hda_codec: PCI %x:%x, codec config %d is selected\n",1700 subsystem_vendor, subsystem_device, c->config);1701 return c->config;1702 }1703 }1704 }1705 return -1;1682 const struct hda_board_config *c; 1683 1684 if (codec->bus->modelname) { 1685 for (c = tbl; c->modelname || c->pci_subvendor; c++) { 1686 if (c->modelname && 1687 ! strcmp(codec->bus->modelname, c->modelname)) { 1688 snd_printd(KERN_INFO "hda_codec: model '%s' is selected\n", c->modelname); 1689 return c->config; 1690 } 1691 } 1692 } 1693 1694 if (codec->bus->pci) { 1695 u16 subsystem_vendor, subsystem_device; 1696 pci_read_config_word(codec->bus->pci, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vendor); 1697 pci_read_config_word(codec->bus->pci, PCI_SUBSYSTEM_ID, &subsystem_device); 1698 for (c = tbl; c->modelname || c->pci_subvendor; c++) { 1699 if (c->pci_subvendor == subsystem_vendor && 1700 (! c->pci_subdevice /* all match */|| 1701 (c->pci_subdevice == subsystem_device))) { 1702 snd_printdd(KERN_INFO "hda_codec: PCI %x:%x, codec config %d is selected\n", 1703 subsystem_vendor, subsystem_device, c->config); 1704 return c->config; 1705 } 1706 } 1707 } 1708 return -1; 1706 1709 } 1707 1710 … … 1718 1721 int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew) 1719 1722 { 1720 int err;1721 1722 for (; knew->name; knew++) {1723 struct snd_kcontrol *kctl;1724 kctl = snd_ctl_new1(knew, codec);1725 if (! kctl)1726 return -ENOMEM;1727 err = snd_ctl_add(codec->bus->card, kctl);1728 if (err < 0) {1729 if (! codec->addr)1730 return err;1731 kctl = snd_ctl_new1(knew, codec);1732 if (! kctl)1733 return -ENOMEM;1734 kctl->id.device = codec->addr;1735 if ((err = snd_ctl_add(codec->bus->card, kctl)) < 0)1736 return err;1737 }1738 }1739 return 0;1723 int err; 1724 1725 for (; knew->name; knew++) { 1726 struct snd_kcontrol *kctl; 1727 kctl = snd_ctl_new1(knew, codec); 1728 if (! kctl) 1729 return -ENOMEM; 1730 err = snd_ctl_add(codec->bus->card, kctl); 1731 if (err < 0) { 1732 if (! codec->addr) 1733 return err; 1734 kctl = snd_ctl_new1(knew, codec); 1735 if (! kctl) 1736 return -ENOMEM; 1737 kctl->id.device = codec->addr; 1738 if ((err = snd_ctl_add(codec->bus->card, kctl)) < 0) 1739 return err; 1740 } 1741 } 1742 return 0; 1740 1743 } 1741 1744 … … 1745 1748 */ 1746 1749 int snd_hda_ch_mode_info(struct hda_codec *codec, struct snd_ctl_elem_info *uinfo, 1747 const struct hda_channel_mode *chmode, int num_chmodes)1748 { 1749 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;1750 uinfo->count = 1;1751 uinfo->value.enumerated.items = num_chmodes;1752 if (uinfo->value.enumerated.item >= num_chmodes)1753 uinfo->value.enumerated.item = num_chmodes - 1;1754 sprintf(uinfo->value.enumerated.name, "%dch",1755 chmode[uinfo->value.enumerated.item].channels);1756 return 0;1750 const struct hda_channel_mode *chmode, int num_chmodes) 1751 { 1752 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 1753 uinfo->count = 1; 1754 uinfo->value.enumerated.items = num_chmodes; 1755 if (uinfo->value.enumerated.item >= num_chmodes) 1756 uinfo->value.enumerated.item = num_chmodes - 1; 1757 sprintf(uinfo->value.enumerated.name, "%dch", 1758 chmode[uinfo->value.enumerated.item].channels); 1759 return 0; 1757 1760 } 1758 1761 1759 1762 int snd_hda_ch_mode_get(struct hda_codec *codec, struct snd_ctl_elem_value *ucontrol, 1760 const struct hda_channel_mode *chmode, int num_chmodes,1761 int max_channels)1762 { 1763 int i;1764 1765 for (i = 0; i < num_chmodes; i++) {1766 if (max_channels == chmode[i].channels) {1767 ucontrol->value.enumerated.item[0] = i;1768 break;1769 }1770 }1771 return 0;1763 const struct hda_channel_mode *chmode, int num_chmodes, 1764 int max_channels) 1765 { 1766 int i; 1767 1768 for (i = 0; i < num_chmodes; i++) { 1769 if (max_channels == chmode[i].channels) { 1770 ucontrol->value.enumerated.item[0] = i; 1771 break; 1772 } 1773 } 1774 return 0; 1772 1775 } 1773 1776 1774 1777 int snd_hda_ch_mode_put(struct hda_codec *codec, struct snd_ctl_elem_value *ucontrol, 1775 const struct hda_channel_mode *chmode, int num_chmodes,1776 int *max_channelsp)1777 { 1778 unsigned int mode;1779 1780 mode = ucontrol->value.enumerated.item[0];1781 snd_assert(mode < num_chmodes, return -EINVAL);1782 if (*max_channelsp == chmode[mode].channels && ! codec->in_resume)1783 return 0;1784 /* change the current channel setting */1785 *max_channelsp = chmode[mode].channels;1786 if (chmode[mode].sequence)1787 snd_hda_sequence_write(codec, chmode[mode].sequence);1788 return 1;1778 const struct hda_channel_mode *chmode, int num_chmodes, 1779 int *max_channelsp) 1780 { 1781 unsigned int mode; 1782 1783 mode = ucontrol->value.enumerated.item[0]; 1784 snd_assert(mode < num_chmodes, return -EINVAL); 1785 if (*max_channelsp == chmode[mode].channels && ! codec->in_resume) 1786 return 0; 1787 /* change the current channel setting */ 1788 *max_channelsp = chmode[mode].channels; 1789 if (chmode[mode].sequence) 1790 snd_hda_sequence_write(codec, chmode[mode].sequence); 1791 return 1; 1789 1792 } 1790 1793 … … 1794 1797 int snd_hda_input_mux_info(const struct hda_input_mux *imux, struct snd_ctl_elem_info *uinfo) 1795 1798 { 1796 unsigned int index;1797 1798 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;1799 uinfo->count = 1;1800 uinfo->value.enumerated.items = imux->num_items;1801 index = uinfo->value.enumerated.item;1802 if (index >= imux->num_items)1803 index = imux->num_items - 1;1804 strcpy(uinfo->value.enumerated.name, imux->items[index].label);1805 return 0;1799 unsigned int index; 1800 1801 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 1802 uinfo->count = 1; 1803 uinfo->value.enumerated.items = imux->num_items; 1804 index = uinfo->value.enumerated.item; 1805 if (index >= imux->num_items) 1806 index = imux->num_items - 1; 1807 strcpy(uinfo->value.enumerated.name, imux->items[index].label); 1808 return 0; 1806 1809 } 1807 1810 1808 1811 int snd_hda_input_mux_put(struct hda_codec *codec, const struct hda_input_mux *imux, 1809 struct snd_ctl_elem_value *ucontrol, hda_nid_t nid,1810 unsigned int *cur_val)1811 { 1812 unsigned int idx;1813 1814 idx = ucontrol->value.enumerated.item[0];1815 if (idx >= imux->num_items)1816 idx = imux->num_items - 1;1817 if (*cur_val == idx && ! codec->in_resume)1818 return 0;1819 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL,1820 imux->items[idx].index);1821 *cur_val = idx;1822 return 1;1812 struct snd_ctl_elem_value *ucontrol, hda_nid_t nid, 1813 unsigned int *cur_val) 1814 { 1815 unsigned int idx; 1816 1817 idx = ucontrol->value.enumerated.item[0]; 1818 if (idx >= imux->num_items) 1819 idx = imux->num_items - 1; 1820 if (*cur_val == idx && ! codec->in_resume) 1821 return 0; 1822 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, 1823 imux->items[idx].index); 1824 *cur_val = idx; 1825 return 1; 1823 1826 } 1824 1827 … … 1833 1836 int snd_hda_multi_out_dig_open(struct hda_codec *codec, struct hda_multi_out *mout) 1834 1837 { 1835 down(&codec->spdif_mutex);1836 if (mout->dig_out_used) {1837 up(&codec->spdif_mutex);1838 return -EBUSY; /* already being used */1839 }1840 mout->dig_out_used = HDA_DIG_EXCLUSIVE;1841 up(&codec->spdif_mutex);1842 return 0;1838 down(&codec->spdif_mutex); 1839 if (mout->dig_out_used) { 1840 up(&codec->spdif_mutex); 1841 return -EBUSY; /* already being used */ 1842 } 1843 mout->dig_out_used = HDA_DIG_EXCLUSIVE; 1844 up(&codec->spdif_mutex); 1845 return 0; 1843 1846 } 1844 1847 … … 1848 1851 int snd_hda_multi_out_dig_close(struct hda_codec *codec, struct hda_multi_out *mout) 1849 1852 { 1850 down(&codec->spdif_mutex);1851 mout->dig_out_used = 0;1852 up(&codec->spdif_mutex);1853 return 0;1853 down(&codec->spdif_mutex); 1854 mout->dig_out_used = 0; 1855 up(&codec->spdif_mutex); 1856 return 0; 1854 1857 } 1855 1858 … … 1858 1861 */ 1859 1862 int snd_hda_multi_out_analog_open(struct hda_codec *codec, struct hda_multi_out *mout, 1860 struct snd_pcm_substream *substream)1861 { 1862 substream->runtime->hw.channels_max = mout->max_channels;1863 return snd_pcm_hw_constraint_step(substream->runtime, 0,1864 SNDRV_PCM_HW_PARAM_CHANNELS, 2);1863 struct snd_pcm_substream *substream) 1864 { 1865 substream->runtime->hw.channels_max = mout->max_channels; 1866 return snd_pcm_hw_constraint_step(substream->runtime, 0, 1867 SNDRV_PCM_HW_PARAM_CHANNELS, 2); 1865 1868 } 1866 1869 … … 1870 1873 */ 1871 1874 int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_out *mout, 1872 unsigned int stream_tag,1873 unsigned int format,1874 struct snd_pcm_substream *substream)1875 { 1876 hda_nid_t *nids = mout->dac_nids;1877 int chs = substream->runtime->channels;1878 int i;1879 1880 down(&codec->spdif_mutex);1881 if (mout->dig_out_nid && mout->dig_out_used != HDA_DIG_EXCLUSIVE) {1882 if (chs == 2 &&1883 snd_hda_is_supported_format(codec, mout->dig_out_nid, format) &&1884 ! (codec->spdif_status & IEC958_AES0_NONAUDIO)) {1885 mout->dig_out_used = HDA_DIG_ANALOG_DUP;1886 /* setup digital receiver */1887 snd_hda_codec_setup_stream(codec, mout->dig_out_nid,1888 stream_tag, 0, format);1889 } else {1890 mout->dig_out_used = 0;1891 snd_hda_codec_setup_stream(codec, mout->dig_out_nid, 0, 0, 0);1892 }1893 }1894 up(&codec->spdif_mutex);1895 1896 /* front */1897 snd_hda_codec_setup_stream(codec, nids[HDA_FRONT], stream_tag, 0, format);1898 if (mout->hp_nid)1899 /* headphone out will just decode front left/right (stereo) */1900 snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag, 0, format);1901 /* extra outputs copied from front */1902 for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++)1903 if (mout->extra_out_nid[i])1904 snd_hda_codec_setup_stream(codec,1905 mout->extra_out_nid[i],1906 stream_tag, 0, format);1907 1908 /* surrounds */1909 for (i = 1; i < mout->num_dacs; i++) {1910 if (chs >= (i + 1) * 2) /* independent out */1911 snd_hda_codec_setup_stream(codec, nids[i], stream_tag, i * 2,1912 format);1913 else /* copy front */1914 snd_hda_codec_setup_stream(codec, nids[i], stream_tag, 0,1915 format);1916 }1917 return 0;1875 unsigned int stream_tag, 1876 unsigned int format, 1877 struct snd_pcm_substream *substream) 1878 { 1879 hda_nid_t *nids = mout->dac_nids; 1880 int chs = substream->runtime->channels; 1881 int i; 1882 1883 down(&codec->spdif_mutex); 1884 if (mout->dig_out_nid && mout->dig_out_used != HDA_DIG_EXCLUSIVE) { 1885 if (chs == 2 && 1886 snd_hda_is_supported_format(codec, mout->dig_out_nid, format) && 1887 ! (codec->spdif_status & IEC958_AES0_NONAUDIO)) { 1888 mout->dig_out_used = HDA_DIG_ANALOG_DUP; 1889 /* setup digital receiver */ 1890 snd_hda_codec_setup_stream(codec, mout->dig_out_nid, 1891 stream_tag, 0, format); 1892 } else { 1893 mout->dig_out_used = 0; 1894 snd_hda_codec_setup_stream(codec, mout->dig_out_nid, 0, 0, 0); 1895 } 1896 } 1897 up(&codec->spdif_mutex); 1898 1899 /* front */ 1900 snd_hda_codec_setup_stream(codec, nids[HDA_FRONT], stream_tag, 0, format); 1901 if (mout->hp_nid) 1902 /* headphone out will just decode front left/right (stereo) */ 1903 snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag, 0, format); 1904 /* extra outputs copied from front */ 1905 for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++) 1906 if (mout->extra_out_nid[i]) 1907 snd_hda_codec_setup_stream(codec, 1908 mout->extra_out_nid[i], 1909 stream_tag, 0, format); 1910 1911 /* surrounds */ 1912 for (i = 1; i < mout->num_dacs; i++) { 1913 if (chs >= (i + 1) * 2) /* independent out */ 1914 snd_hda_codec_setup_stream(codec, nids[i], stream_tag, i * 2, 1915 format); 1916 else /* copy front */ 1917 snd_hda_codec_setup_stream(codec, nids[i], stream_tag, 0, 1918 format); 1919 } 1920 return 0; 1918 1921 } 1919 1922 … … 1923 1926 int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec, struct hda_multi_out *mout) 1924 1927 { 1925 hda_nid_t *nids = mout->dac_nids;1926 int i;1927 1928 for (i = 0; i < mout->num_dacs; i++)1929 snd_hda_codec_setup_stream(codec, nids[i], 0, 0, 0);1930 if (mout->hp_nid)1931 snd_hda_codec_setup_stream(codec, mout->hp_nid, 0, 0, 0);1932 for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++)1933 if (mout->extra_out_nid[i])1934 snd_hda_codec_setup_stream(codec,1935 mout->extra_out_nid[i],1936 0, 0, 0);1937 down(&codec->spdif_mutex);1938 if (mout->dig_out_nid && mout->dig_out_used == HDA_DIG_ANALOG_DUP) {1939 snd_hda_codec_setup_stream(codec, mout->dig_out_nid, 0, 0, 0);1940 mout->dig_out_used = 0;1941 }1942 up(&codec->spdif_mutex);1943 return 0;1928 hda_nid_t *nids = mout->dac_nids; 1929 int i; 1930 1931 for (i = 0; i < mout->num_dacs; i++) 1932 snd_hda_codec_setup_stream(codec, nids[i], 0, 0, 0); 1933 if (mout->hp_nid) 1934 snd_hda_codec_setup_stream(codec, mout->hp_nid, 0, 0, 0); 1935 for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++) 1936 if (mout->extra_out_nid[i]) 1937 snd_hda_codec_setup_stream(codec, 1938 mout->extra_out_nid[i], 1939 0, 0, 0); 1940 down(&codec->spdif_mutex); 1941 if (mout->dig_out_nid && mout->dig_out_used == HDA_DIG_ANALOG_DUP) { 1942 snd_hda_codec_setup_stream(codec, mout->dig_out_nid, 0, 0, 0); 1943 mout->dig_out_used = 0; 1944 } 1945 up(&codec->spdif_mutex); 1946 return 0; 1944 1947 } 1945 1948 … … 1950 1953 static int is_in_nid_list(hda_nid_t nid, hda_nid_t *list) 1951 1954 { 1952 for (; *list; list++)1953 if (*list == nid)1954 return 1;1955 return 0;1955 for (; *list; list++) 1956 if (*list == nid) 1957 return 1; 1958 return 0; 1956 1959 } 1957 1960 … … 1974 1977 */ 1975 1978 int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *cfg, 1976 hda_nid_t *ignore_nids) 1977 { 1978 hda_nid_t nid, nid_start; 1979 int i, j, nodes; 1980 short seq, assoc_line_out, sequences[ARRAY_SIZE(cfg->line_out_pins)]; 1981 1982 memset(cfg, 0, sizeof(*cfg)); 1983 1984 memset(sequences, 0, sizeof(sequences)); 1985 assoc_line_out = 0; 1986 1987 nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid_start); 1988 for (nid = nid_start; nid < nodes + nid_start; nid++) { 1989 unsigned int wid_caps = get_wcaps(codec, nid); 1990 unsigned int wid_type = (wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; 1991 unsigned int def_conf; 1992 short assoc, loc; 1993 1994 /* read all default configuration for pin complex */ 1995 if (wid_type != AC_WID_PIN) 1996 continue; 1997 /* ignore the given nids (e.g. pc-beep returns error) */ 1998 if (ignore_nids && is_in_nid_list(nid, ignore_nids)) 1999 continue; 2000 2001 def_conf = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONFIG_DEFAULT, 0); 2002 if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE) 2003 continue; 2004 loc = get_defcfg_location(def_conf); 2005 switch (get_defcfg_device(def_conf)) { 2006 case AC_JACK_LINE_OUT: 2007 seq = get_defcfg_sequence(def_conf); 2008 assoc = get_defcfg_association(def_conf); 2009 if (! assoc) 2010 continue; 2011 if (! assoc_line_out) 2012 assoc_line_out = assoc; 2013 else if (assoc_line_out != assoc) 2014 continue; 2015 if (cfg->line_outs >= ARRAY_SIZE(cfg->line_out_pins)) 2016 continue; 2017 cfg->line_out_pins[cfg->line_outs] = nid; 2018 sequences[cfg->line_outs] = seq; 2019 cfg->line_outs++; 2020 break; 2021 case AC_JACK_SPEAKER: 2022 if (cfg->speaker_outs >= ARRAY_SIZE(cfg->speaker_pins)) 2023 continue; 2024 cfg->speaker_pins[cfg->speaker_outs] = nid; 2025 cfg->speaker_outs++; 2026 break; 2027 case AC_JACK_HP_OUT: 2028 cfg->hp_pin = nid; 2029 break; 2030 case AC_JACK_MIC_IN: 2031 if (loc == AC_JACK_LOC_FRONT) 2032 cfg->input_pins[AUTO_PIN_FRONT_MIC] = nid; 2033 else 2034 cfg->input_pins[AUTO_PIN_MIC] = nid; 2035 break; 2036 case AC_JACK_LINE_IN: 2037 if (loc == AC_JACK_LOC_FRONT) 2038 cfg->input_pins[AUTO_PIN_FRONT_LINE] = nid; 2039 else 2040 cfg->input_pins[AUTO_PIN_LINE] = nid; 2041 break; 2042 case AC_JACK_CD: 2043 cfg->input_pins[AUTO_PIN_CD] = nid; 2044 break; 2045 case AC_JACK_AUX: 2046 cfg->input_pins[AUTO_PIN_AUX] = nid; 2047 break; 2048 case AC_JACK_SPDIF_OUT: 2049 cfg->dig_out_pin = nid; 2050 break; 2051 case AC_JACK_SPDIF_IN: 2052 cfg->dig_in_pin = nid; 2053 break; 2054 } 2055 } 2056 2057 /* sort by sequence */ 2058 for (i = 0; i < cfg->line_outs; i++) 2059 for (j = i + 1; j < cfg->line_outs; j++) 2060 if (sequences[i] > sequences[j]) { 2061 seq = sequences[i]; 2062 sequences[i] = sequences[j]; 2063 sequences[j] = seq; 2064 nid = cfg->line_out_pins[i]; 2065 cfg->line_out_pins[i] = cfg->line_out_pins[j]; 2066 cfg->line_out_pins[j] = nid; 2067 } 2068 2069 /* Reorder the surround channels 2070 * ALSA sequence is front/surr/clfe/side 2071 * HDA sequence is: 2072 * 4-ch: front/surr => OK as it is 2073 * 6-ch: front/clfe/surr 2074 * 8-ch: front/clfe/side/surr 2075 */ 2076 switch (cfg->line_outs) { 2077 case 3: 2078 nid = cfg->line_out_pins[1]; 2079 cfg->line_out_pins[1] = cfg->line_out_pins[2]; 2080 cfg->line_out_pins[2] = nid; 2081 break; 2082 case 4: 2083 nid = cfg->line_out_pins[1]; 2084 cfg->line_out_pins[1] = cfg->line_out_pins[3]; 2085 cfg->line_out_pins[3] = cfg->line_out_pins[2]; 2086 cfg->line_out_pins[2] = nid; 2087 break; 2088 } 2089 /* 2090 * debug prints of the parsed results 2091 */ 2092 snd_printd("autoconfig: line_outs=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n", 2093 cfg->line_outs, cfg->line_out_pins[0], cfg->line_out_pins[1], 2094 cfg->line_out_pins[2], cfg->line_out_pins[3], 2095 cfg->line_out_pins[4]); 2096 snd_printd(" speaker_outs=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n", 2097 cfg->speaker_outs, cfg->speaker_pins[0], 2098 cfg->speaker_pins[1], cfg->speaker_pins[2], 2099 cfg->speaker_pins[3], cfg->speaker_pins[4]); 2100 snd_printd(" hp=0x%x, dig_out=0x%x, din_in=0x%x\n", 2101 cfg->hp_pin, cfg->dig_out_pin, cfg->dig_in_pin); 2102 snd_printd(" inputs: mic=0x%x, fmic=0x%x, line=0x%x, fline=0x%x," 2103 " cd=0x%x, aux=0x%x\n", 2104 cfg->input_pins[AUTO_PIN_MIC], 2105 cfg->input_pins[AUTO_PIN_FRONT_MIC], 2106 cfg->input_pins[AUTO_PIN_LINE], 2107 cfg->input_pins[AUTO_PIN_FRONT_LINE], 2108 cfg->input_pins[AUTO_PIN_CD], 2109 cfg->input_pins[AUTO_PIN_AUX]); 2110 2111 /* 2112 * FIX-UP: if no line-outs are detected, try to use speaker or HP pin 2113 * as a primary output 2114 */ 2115 if (! cfg->line_outs) { 2116 if (cfg->speaker_outs) { 2117 cfg->line_outs = cfg->speaker_outs; 2118 memcpy(cfg->line_out_pins, cfg->speaker_pins, 2119 sizeof(cfg->speaker_pins)); 2120 cfg->speaker_outs = 0; 2121 memset(cfg->speaker_pins, 0, sizeof(cfg->speaker_pins)); 2122 } else if (cfg->hp_pin) { 2123 cfg->line_outs = 1; 2124 cfg->line_out_pins[0] = cfg->hp_pin; 2125 cfg->hp_pin = 0; 1979 hda_nid_t *ignore_nids) 1980 { 1981 hda_nid_t nid, nid_start; 1982 int i, j, nodes; 1983 short seq, assoc_line_out, sequences[ARRAY_SIZE(cfg->line_out_pins)]; 1984 1985 memset(cfg, 0, sizeof(*cfg)); 1986 1987 memset(sequences, 0, sizeof(sequences)); 1988 assoc_line_out = 0; 1989 1990 nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid_start); 1991 for (nid = nid_start; nid < nodes + nid_start; nid++) { 1992 unsigned int wid_caps = get_wcaps(codec, nid); 1993 unsigned int wid_type = (wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; 1994 unsigned int def_conf; 1995 short assoc, loc; 1996 1997 /* read all default configuration for pin complex */ 1998 if (wid_type != AC_WID_PIN) 1999 continue; 2000 /* ignore the given nids (e.g. pc-beep returns error) */ 2001 if (ignore_nids && is_in_nid_list(nid, ignore_nids)) 2002 continue; 2003 2004 def_conf = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONFIG_DEFAULT, 0); 2005 if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE) 2006 continue; 2007 loc = get_defcfg_location(def_conf); 2008 switch (get_defcfg_device(def_conf)) { 2009 case AC_JACK_LINE_OUT: 2010 seq = get_defcfg_sequence(def_conf); 2011 assoc = get_defcfg_association(def_conf); 2012 if (! assoc) 2013 continue; 2014 if (! assoc_line_out) 2015 assoc_line_out = assoc; 2016 else if (assoc_line_out != assoc) 2017 continue; 2018 if (cfg->line_outs >= ARRAY_SIZE(cfg->line_out_pins)) 2019 continue; 2020 cfg->line_out_pins[cfg->line_outs] = nid; 2021 sequences[cfg->line_outs] = seq; 2022 cfg->line_outs++; 2023 break; 2024 case AC_JACK_SPEAKER: 2025 if (cfg->speaker_outs >= ARRAY_SIZE(cfg->speaker_pins)) 2026 continue; 2027 cfg->speaker_pins[cfg->speaker_outs] = nid; 2028 cfg->speaker_outs++; 2029 break; 2030 case AC_JACK_HP_OUT: 2031 cfg->hp_pin = nid; 2032 break; 2033 case AC_JACK_MIC_IN: 2034 if (loc == AC_JACK_LOC_FRONT) 2035 cfg->input_pins[AUTO_PIN_FRONT_MIC] = nid; 2036 else 2037 cfg->input_pins[AUTO_PIN_MIC] = nid; 2038 break; 2039 case AC_JACK_LINE_IN: 2040 if (loc == AC_JACK_LOC_FRONT) 2041 cfg->input_pins[AUTO_PIN_FRONT_LINE] = nid; 2042 else 2043 cfg->input_pins[AUTO_PIN_LINE] = nid; 2044 break; 2045 case AC_JACK_CD: 2046 cfg->input_pins[AUTO_PIN_CD] = nid; 2047 break; 2048 case AC_JACK_AUX: 2049 cfg->input_pins[AUTO_PIN_AUX] = nid; 2050 break; 2051 case AC_JACK_SPDIF_OUT: 2052 cfg->dig_out_pin = nid; 2053 break; 2054 case AC_JACK_SPDIF_IN: 2055 cfg->dig_in_pin = nid; 2056 break; 2057 } 2058 } 2059 2060 /* sort by sequence */ 2061 for (i = 0; i < cfg->line_outs; i++) 2062 for (j = i + 1; j < cfg->line_outs; j++) 2063 if (sequences[i] > sequences[j]) { 2064 seq = sequences[i]; 2065 sequences[i] = sequences[j]; 2066 sequences[j] = seq; 2067 nid = cfg->line_out_pins[i]; 2068 cfg->line_out_pins[i] = cfg->line_out_pins[j]; 2069 cfg->line_out_pins[j] = nid; 2126 2070 } 2071 2072 /* Reorder the surround channels 2073 * ALSA sequence is front/surr/clfe/side 2074 * HDA sequence is: 2075 * 4-ch: front/surr => OK as it is 2076 * 6-ch: front/clfe/surr 2077 * 8-ch: front/clfe/side/surr 2078 */ 2079 switch (cfg->line_outs) { 2080 case 3: 2081 nid = cfg->line_out_pins[1]; 2082 cfg->line_out_pins[1] = cfg->line_out_pins[2]; 2083 cfg->line_out_pins[2] = nid; 2084 break; 2085 case 4: 2086 nid = cfg->line_out_pins[1]; 2087 cfg->line_out_pins[1] = cfg->line_out_pins[3]; 2088 cfg->line_out_pins[3] = cfg->line_out_pins[2]; 2089 cfg->line_out_pins[2] = nid; 2090 break; 2091 } 2092 /* 2093 * debug prints of the parsed results 2094 */ 2095 snd_printd("autoconfig: line_outs=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n", 2096 cfg->line_outs, cfg->line_out_pins[0], cfg->line_out_pins[1], 2097 cfg->line_out_pins[2], cfg->line_out_pins[3], 2098 cfg->line_out_pins[4]); 2099 snd_printd(" speaker_outs=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n", 2100 cfg->speaker_outs, cfg->speaker_pins[0], 2101 cfg->speaker_pins[1], cfg->speaker_pins[2], 2102 cfg->speaker_pins[3], cfg->speaker_pins[4]); 2103 snd_printd(" hp=0x%x, dig_out=0x%x, din_in=0x%x\n", 2104 cfg->hp_pin, cfg->dig_out_pin, cfg->dig_in_pin); 2105 snd_printd(" inputs: mic=0x%x, fmic=0x%x, line=0x%x, fline=0x%x," 2106 " cd=0x%x, aux=0x%x\n", 2107 cfg->input_pins[AUTO_PIN_MIC], 2108 cfg->input_pins[AUTO_PIN_FRONT_MIC], 2109 cfg->input_pins[AUTO_PIN_LINE], 2110 cfg->input_pins[AUTO_PIN_FRONT_LINE], 2111 cfg->input_pins[AUTO_PIN_CD], 2112 cfg->input_pins[AUTO_PIN_AUX]); 2113 2114 /* 2115 * FIX-UP: if no line-outs are detected, try to use speaker or HP pin 2116 * as a primary output 2117 */ 2118 if (! cfg->line_outs) { 2119 if (cfg->speaker_outs) { 2120 cfg->line_outs = cfg->speaker_outs; 2121 memcpy(cfg->line_out_pins, cfg->speaker_pins, 2122 sizeof(cfg->speaker_pins)); 2123 cfg->speaker_outs = 0; 2124 memset(cfg->speaker_pins, 0, sizeof(cfg->speaker_pins)); 2125 } else if (cfg->hp_pin) { 2126 cfg->line_outs = 1; 2127 cfg->line_out_pins[0] = cfg->hp_pin; 2128 cfg->hp_pin = 0; 2127 2129 } 2128 2129 return 0; 2130 } 2131 2132 return 0; 2130 2133 } 2131 2134 2132 2135 /* labels for input pins */ 2133 2136 const char *auto_pin_cfg_labels[AUTO_PIN_LAST] = { 2134 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux"2137 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux" 2135 2138 }; 2136 2139 … … 2150 2153 int snd_hda_suspend(struct hda_bus *bus, pm_message_t state) 2151 2154 { 2152 struct list_head *p;2153 2154 /* FIXME: should handle power widget capabilities */2155 list_for_each(p, &bus->codec_list) {2156 struct hda_codec *codec = list_entry(p, struct hda_codec, list);2157 if (codec->patch_ops.suspend)2158 codec->patch_ops.suspend(codec, state);2159 hda_set_power_state(codec,2160 codec->afg ? codec->afg : codec->mfg,2161 AC_PWRST_D3);2162 }2163 return 0;2155 struct list_head *p; 2156 2157 /* FIXME: should handle power widget capabilities */ 2158 list_for_each(p, &bus->codec_list) { 2159 struct hda_codec *codec = list_entry(p, struct hda_codec, list); 2160 if (codec->patch_ops.suspend) 2161 codec->patch_ops.suspend(codec, state); 2162 hda_set_power_state(codec, 2163 codec->afg ? codec->afg : codec->mfg, 2164 AC_PWRST_D3); 2165 } 2166 return 0; 2164 2167 } 2165 2168 … … 2173 2176 int snd_hda_resume(struct hda_bus *bus) 2174 2177 { 2175 struct list_head *p;2176 2177 list_for_each(p, &bus->codec_list) {2178 struct hda_codec *codec = list_entry(p, struct hda_codec, list);2179 hda_set_power_state(codec,2180 codec->afg ? codec->afg : codec->mfg,2181 AC_PWRST_D0);2182 if (codec->patch_ops.resume)2183 codec->patch_ops.resume(codec);2184 }2185 return 0;2178 struct list_head *p; 2179 2180 list_for_each(p, &bus->codec_list) { 2181 struct hda_codec *codec = list_entry(p, struct hda_codec, list); 2182 hda_set_power_state(codec, 2183 codec->afg ? codec->afg : codec->mfg, 2184 AC_PWRST_D0); 2185 if (codec->patch_ops.resume) 2186 codec->patch_ops.resume(codec); 2187 } 2188 return 0; 2186 2189 } 2187 2190 … … 2197 2200 int snd_hda_resume_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew) 2198 2201 { 2199 struct snd_ctl_elem_value *val;2200 2201 val = kmalloc(sizeof(*val), GFP_KERNEL);2202 if (! val)2203 return -ENOMEM;2204 codec->in_resume = 1;2205 for (; knew->name; knew++) {2206 int i, count;2207 count = knew->count ? knew->count : 1;2208 for (i = 0; i < count; i++) {2209 memset(val, 0, sizeof(*val));2210 val->id.iface = knew->iface;2211 val->id.device = knew->device;2212 val->id.subdevice = knew->subdevice;2213 strcpy(val->id.name, knew->name);2214 val->id.index = knew->index ? knew->index : i;2215 /* Assume that get callback reads only from cache,2216 * not accessing to the real hardware2217 */2218 if (snd_ctl_elem_read(codec->bus->card, val) < 0)2219 continue;2220 snd_ctl_elem_write(codec->bus->card, NULL, val);2221 }2222 }2223 codec->in_resume = 0;2224 kfree(val);2225 return 0;2202 struct snd_ctl_elem_value *val; 2203 2204 val = kmalloc(sizeof(*val), GFP_KERNEL); 2205 if (! val) 2206 return -ENOMEM; 2207 codec->in_resume = 1; 2208 for (; knew->name; knew++) { 2209 int i, count; 2210 count = knew->count ? knew->count : 1; 2211 for (i = 0; i < count; i++) { 2212 memset(val, 0, sizeof(*val)); 2213 val->id.iface = knew->iface; 2214 val->id.device = knew->device; 2215 val->id.subdevice = knew->subdevice; 2216 strcpy(val->id.name, knew->name); 2217 val->id.index = knew->index ? knew->index : i; 2218 /* Assume that get callback reads only from cache, 2219 * not accessing to the real hardware 2220 */ 2221 if (snd_ctl_elem_read(codec->bus->card, val) < 0) 2222 continue; 2223 snd_ctl_elem_write(codec->bus->card, NULL, val); 2224 } 2225 } 2226 codec->in_resume = 0; 2227 kfree(val); 2228 return 0; 2226 2229 } 2227 2230 … … 2232 2235 int snd_hda_resume_spdif_out(struct hda_codec *codec) 2233 2236 { 2234 return snd_hda_resume_ctls(codec, dig_mixes);2237 return snd_hda_resume_ctls(codec, dig_mixes); 2235 2238 } 2236 2239 … … 2241 2244 int snd_hda_resume_spdif_in(struct hda_codec *codec) 2242 2245 { 2243 return snd_hda_resume_ctls(codec, dig_in_ctls);2246 return snd_hda_resume_ctls(codec, dig_in_ctls); 2244 2247 } 2245 2248 #endif … … 2270 2273 static int __init alsa_hda_init(void) 2271 2274 { 2272 return 0;2275 return 0; 2273 2276 } 2274 2277 -
GPL/trunk/alsa-kernel/pci/hda/hda_intel.c
r76 r77 80 80 "{Intel, ESB2}," 81 81 "{Intel, ICH8}," 82 "{ATI, SB450}," 82 "{ATI, SB450}," 83 "{ATI, RS600}," 83 84 "{VIA, VT8251}," 84 85 "{VIA, VT8237A}," … … 166 167 #define ULI_NUM_PLAYBACK 6 167 168 169 /* ATI HDMI has 1 playback and 0 capture */ 170 #define ATIHDMI_CAPTURE_INDEX 0 171 #define ATIHDMI_NUM_CAPTURE 0 172 #define ATIHDMI_PLAYBACK_INDEX 0 173 #define ATIHDMI_NUM_PLAYBACK 1 174 168 175 /* this number is statically defined for simplicity */ 169 176 #define MAX_AZX_DEV 16 … … 329 336 enum { 330 337 AZX_DRIVER_ICH, 331 AZX_DRIVER_ATI, 338 AZX_DRIVER_ATI, 339 AZX_DRIVER_ATIHDMI, 332 340 AZX_DRIVER_VIA, 333 341 AZX_DRIVER_SIS, … … 338 346 static char *driver_short_names[] __devinitdata = { 339 347 [AZX_DRIVER_ICH] = "HDA Intel", 340 [AZX_DRIVER_ATI] = "HDA ATI SB", 348 [AZX_DRIVER_ATI] = "HDA ATI SB", 349 [AZX_DRIVER_ATIHDMI] = "HDA ATI HDMI", 341 350 [AZX_DRIVER_VIA] = "HDA VIA VT82xx", 342 351 [AZX_DRIVER_SIS] = "HDA SIS966", … … 1392 1401 } 1393 1402 1403 if (chip->irq >= 0) 1404 free_irq(chip->irq, (void*)chip); 1394 1405 if (chip->remap_addr) 1395 1406 iounmap(chip->remap_addr); 1396 if (chip->irq >= 0)1397 free_irq(chip->irq, (void*)chip);1398 1407 1399 1408 if (chip->bdl.area) … … 1493 1502 chip->playback_index_offset = ULI_PLAYBACK_INDEX; 1494 1503 chip->capture_index_offset = ULI_CAPTURE_INDEX; 1504 break; 1505 case AZX_DRIVER_ATIHDMI: 1506 chip->playback_streams = ATIHDMI_NUM_PLAYBACK; 1507 chip->capture_streams = ATIHDMI_NUM_CAPTURE; 1508 chip->playback_index_offset = ATIHDMI_PLAYBACK_INDEX; 1509 chip->capture_index_offset = ATIHDMI_CAPTURE_INDEX; 1495 1510 break; 1496 1511 default: … … 1618 1633 { 0x8086, 0x269a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ICH }, /* ESB2 */ 1619 1634 { 0x8086, 0x284b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ICH }, /* ICH8 */ 1620 { 0x1002, 0x437b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATI }, /* ATI SB450 */ 1635 { 0x1002, 0x437b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATI }, /* ATI SB450 */ 1636 { 0x1002, 0x793b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATIHDMI }, /* ATI RS600 HDMI */ 1621 1637 { 0x1106, 0x3288, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_VIA }, /* VIA VT8251/VT8237A */ 1622 1638 { 0x1039, 0x7502, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_SIS }, /* SIS966 */ -
GPL/trunk/alsa-kernel/pci/hda/hda_patch.h
r69 r77 13 13 /* SiLabs 3054/3055 modem codecs */ 14 14 extern struct hda_codec_preset snd_hda_preset_si3054[]; 15 /* ATI HDMI codecs */ 16 extern struct hda_codec_preset snd_hda_preset_atihdmi[]; 15 17 16 18 static const struct hda_codec_preset *hda_preset_tables[] = { … … 19 21 snd_hda_preset_analog, 20 22 snd_hda_preset_sigmatel, 21 snd_hda_preset_si3054, 23 snd_hda_preset_si3054, 24 snd_hda_preset_atihdmi, 22 25 NULL 23 26 }; -
GPL/trunk/alsa-kernel/pci/hda/makefile.os2
r69 r77 15 15 FILE1 = hda_intel.obj hda_codec.obj hda_generic.obj patch_realtek.obj 16 16 FILE2 = patch_cmedia.obj hda_proc.obj patch_analog.obj patch_sigmatel.obj 17 FILE3 = patch_si3054.obj 17 FILE3 = patch_si3054.obj patch_atihdmi.obj 18 18 FILE4 = 19 19 FILE5 = -
GPL/trunk/alsa-kernel/pci/hda/patch_analog.c
r76 r77 786 786 { .pci_subvendor = 0x10de, .pci_subdevice = 0xcb84, 787 787 .config = AD1986A_3STACK }, /* ASUS A8N-VM CSM */ 788 { .pci_subvendor = 0x1043, .pci_subdevice = 0x81b3, 789 .config = AD1986A_3STACK }, /* ASUS P5RD2-VM / P5GPL-X SE */ 788 790 { .modelname = "laptop", .config = AD1986A_LAPTOP }, 789 791 { .pci_subvendor = 0x144d, .pci_subdevice = 0xc01e, … … 793 795 { .pci_subvendor = 0x1043, .pci_subdevice = 0x818f, 794 796 .config = AD1986A_LAPTOP }, /* ASUS P5GV-MX */ 797 { .pci_subvendor = 0x144d, .pci_subdevice = 0xc023, 798 .config = AD1986A_LAPTOP_EAPD }, /* Samsung X60 Chane */ 795 799 { .modelname = "laptop-eapd", .config = AD1986A_LAPTOP_EAPD }, 796 800 { .pci_subvendor = 0x144d, .pci_subdevice = 0xc024, 797 801 .config = AD1986A_LAPTOP_EAPD }, /* Samsung R65-T2300 Charis */ 798 802 { .pci_subvendor = 0x1043, .pci_subdevice = 0x1213, 799 .config = AD1986A_LAPTOP_EAPD }, /* ASUS A6J */ 803 .config = AD1986A_LAPTOP_EAPD }, /* ASUS A6J */ 804 { .pci_subvendor = 0x1043, .pci_subdevice = 0x11f7, 805 .config = AD1986A_LAPTOP_EAPD }, /* ASUS U5A */ 806 { .pci_subvendor = 0x1043, .pci_subdevice = 0x1297, 807 .config = AD1986A_LAPTOP_EAPD }, /* ASUS Z62F */ 808 { .pci_subvendor = 0x103c, .pci_subdevice = 0x30af, 809 .config = AD1986A_LAPTOP_EAPD }, /* HP Compaq Presario B2800 */ 810 { .pci_subvendor = 0x17aa, .pci_subdevice = 0x2066, 811 .config = AD1986A_LAPTOP_EAPD }, /* Lenovo 3000 N100-07684JU */ 800 812 {0} 801 813 }; … … 947 959 { 948 960 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 949 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Route",961 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source", 950 962 .info = ad1983_spdif_route_info, 951 963 .get = ad1983_spdif_route_get, … … 1086 1098 /* identical with AD1983 */ 1087 1099 { 1088 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,1089 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Route",1100 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1101 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source", 1090 1102 .info = ad1983_spdif_route_info, 1091 1103 .get = ad1983_spdif_route_get, 1092 1104 .put = ad1983_spdif_route_put, 1093 },1105 }, 1094 1106 {0} /* end */ 1095 1107 }; … … 1301 1313 .put = ad198x_mux_enum_put, 1302 1314 }, 1315 /* identical with AD1983 */ 1316 { 1317 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1318 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source", 1319 .info = ad1983_spdif_route_info, 1320 .get = ad1983_spdif_route_get, 1321 .put = ad1983_spdif_route_put, 1322 }, 1303 1323 {0} /* end */ 1304 1324 }; … … 1313 1333 } 1314 1334 1335 /* configuration for Lenovo Thinkpad T60 */ 1336 static struct snd_kcontrol_new ad1981_thinkpad_mixers[] = { 1337 HDA_CODEC_VOLUME("Master Playback Volume", 0x05, 0x0, HDA_OUTPUT), 1338 HDA_CODEC_MUTE("Master Playback Switch", 0x05, 0x0, HDA_OUTPUT), 1339 HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT), 1340 HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT), 1341 HDA_CODEC_VOLUME("Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT), 1342 HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT), 1343 HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT), 1344 HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT), 1345 HDA_CODEC_VOLUME("Mic Boost", 0x08, 0x0, HDA_INPUT), 1346 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT), 1347 HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT), 1348 { 1349 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1350 .name = "Capture Source", 1351 .info = ad198x_mux_enum_info, 1352 .get = ad198x_mux_enum_get, 1353 .put = ad198x_mux_enum_put, 1354 }, 1355 {0} /* end */ 1356 }; 1357 1358 static struct hda_input_mux ad1981_thinkpad_capture_source = { 1359 .num_items = 3, 1360 .items = { 1361 { "Mic", 0x0 }, 1362 { "Mix", 0x2 }, 1363 { "CD", 0x4 }, 1364 }, 1365 }; 1366 1315 1367 /* models */ 1316 enum { AD1981_BASIC, AD1981_HP };1368 enum { AD1981_BASIC, AD1981_HP, AD1981_THINKPAD }; 1317 1369 1318 1370 static struct hda_board_config ad1981_cfg_tbl[] = { … … 1322 1374 { .pci_subvendor = 0x103c, .pci_subdevice = 0x309f, 1323 1375 .config = AD1981_HP }, /* HP nx9420 AngelFire */ 1376 { .pci_subvendor = 0x30b0, .pci_subdevice = 0x103c, 1377 .config = AD1981_HP }, /* HP nx6320 (reversed SSID, H/W bug) */ 1378 { .modelname = "basic", .config = AD1981_BASIC }, 1379 { .modelname = "thinkpad", .config = AD1981_THINKPAD }, 1380 /* Lenovo Thinkpad T60/X60/Z6xx */ 1381 { .pci_subvendor = 0x17aa, .config = AD1981_THINKPAD }, 1382 { .pci_subvendor = 0x1014, .pci_subdevice = 0x0597, 1383 .config = AD1981_THINKPAD }, /* Z60m/t */ 1324 1384 { .modelname = "basic", .config = AD1981_BASIC }, 1325 1385 {0} … … 1367 1427 codec->patch_ops.unsol_event = ad1981_hp_unsol_event; 1368 1428 break; 1429 case AD1981_THINKPAD: 1430 spec->mixers[0] = ad1981_thinkpad_mixers; 1431 spec->multiout.dig_out_nid = 0; 1432 spec->input_mux = &ad1981_thinkpad_capture_source; 1433 break; 1369 1434 } 1370 1371 1435 return 0; 1372 1436 } … … 1474 1538 #define AD1988A_REV2 0x100200 1475 1539 1476 1540 #define is_rev2(codec) \ 1541 ((codec)->vendor_id == 0x11d41988 && \ 1542 (codec)->revision_id == AD1988A_REV2) 1477 1543 /* 1478 1544 * mixers … … 2121 2187 /* A B C D E F G H */ 2122 2188 0x04, 0x05, 0x0a, 0x04, 0x06, 0x05, 0x0a, 0x06 2123 };2124 if (codec->revision_id == AD1988A_REV2)2189 }; 2190 if (is_rev2(codec)) 2125 2191 return idx_to_dac_rev2[idx]; 2126 2192 else … … 2491 2557 codec->spec = spec; 2492 2558 2493 if (codec->revision_id == AD1988A_REV2)2559 if (is_rev2(codec)) 2494 2560 snd_printk(KERN_INFO "patch_analog: AD1988A rev.2 is detected, enable workarounds\n"); 2495 2561 … … 2516 2582 case AD1988_6STACK_DIG: 2517 2583 spec->multiout.max_channels = 8; 2518 spec->multiout.num_dacs = 4;2519 if (codec->revision_id == AD1988A_REV2)2584 spec->multiout.num_dacs = 4; 2585 if (is_rev2(codec)) 2520 2586 spec->multiout.dac_nids = ad1988_6stack_dac_nids_rev2; 2521 2587 else 2522 2588 spec->multiout.dac_nids = ad1988_6stack_dac_nids; 2523 2589 spec->input_mux = &ad1988_6stack_capture_source; 2524 spec->num_mixers = 2;2525 if (codec->revision_id == AD1988A_REV2)2590 spec->num_mixers = 2; 2591 if (is_rev2(codec)) 2526 2592 spec->mixers[0] = ad1988_6stack_mixers1_rev2; 2527 2593 else … … 2538 2604 case AD1988_3STACK_DIG: 2539 2605 spec->multiout.max_channels = 6; 2540 spec->multiout.num_dacs = 3;2541 if (codec->revision_id == AD1988A_REV2)2606 spec->multiout.num_dacs = 3; 2607 if (is_rev2(codec)) 2542 2608 spec->multiout.dac_nids = ad1988_3stack_dac_nids_rev2; 2543 2609 else … … 2546 2612 spec->channel_mode = ad1988_3stack_modes; 2547 2613 spec->num_channel_mode = ARRAY_SIZE(ad1988_3stack_modes); 2548 spec->num_mixers = 2;2549 if (codec->revision_id == AD1988A_REV2)2614 spec->num_mixers = 2; 2615 if (is_rev2(codec)) 2550 2616 spec->mixers[0] = ad1988_3stack_mixers1_rev2; 2551 2617 else -
GPL/trunk/alsa-kernel/pci/hda/patch_realtek.c
r76 r77 36 36 /* ALC880 board config type */ 37 37 enum { 38 ALC880_3ST,39 ALC880_3ST_DIG,40 ALC880_5ST,41 ALC880_5ST_DIG,42 ALC880_W810,43 ALC880_Z71V,44 ALC880_6ST,45 ALC880_6ST_DIG,46 ALC880_F1734,47 ALC880_ASUS,48 ALC880_ASUS_DIG,49 ALC880_ASUS_W1V,50 ALC880_ASUS_DIG2,51 ALC880_UNIWILL_DIG,52 ALC880_CLEVO,53 ALC880_TCL_S700,54 ALC880_LG,55 ALC880_LG_LW,38 ALC880_3ST, 39 ALC880_3ST_DIG, 40 ALC880_5ST, 41 ALC880_5ST_DIG, 42 ALC880_W810, 43 ALC880_Z71V, 44 ALC880_6ST, 45 ALC880_6ST_DIG, 46 ALC880_F1734, 47 ALC880_ASUS, 48 ALC880_ASUS_DIG, 49 ALC880_ASUS_W1V, 50 ALC880_ASUS_DIG2, 51 ALC880_UNIWILL_DIG, 52 ALC880_CLEVO, 53 ALC880_TCL_S700, 54 ALC880_LG, 55 ALC880_LG_LW, 56 56 #ifdef CONFIG_SND_DEBUG 57 ALC880_TEST,57 ALC880_TEST, 58 58 #endif 59 ALC880_AUTO,60 ALC880_MODEL_LAST /* last tag */59 ALC880_AUTO, 60 ALC880_MODEL_LAST /* last tag */ 61 61 }; 62 62 63 63 /* ALC260 models */ 64 64 enum { 65 ALC260_BASIC,66 ALC260_HP,67 ALC260_HP_3013,68 ALC260_FUJITSU_S702X,69 ALC260_ACER,65 ALC260_BASIC, 66 ALC260_HP, 67 ALC260_HP_3013, 68 ALC260_FUJITSU_S702X, 69 ALC260_ACER, 70 70 #ifdef CONFIG_SND_DEBUG 71 ALC260_TEST,71 ALC260_TEST, 72 72 #endif 73 ALC260_AUTO,74 ALC260_MODEL_LAST /* last tag */73 ALC260_AUTO, 74 ALC260_MODEL_LAST /* last tag */ 75 75 }; 76 76 77 77 /* ALC262 models */ 78 78 enum { 79 ALC262_BASIC, 80 ALC262_FUJITSU, 81 ALC262_AUTO, 82 ALC262_MODEL_LAST /* last tag */ 79 ALC262_BASIC, 80 ALC262_FUJITSU, 81 ALC262_HP_BPC, 82 ALC262_AUTO, 83 ALC262_MODEL_LAST /* last tag */ 83 84 }; 84 85 85 86 /* ALC861 models */ 86 87 enum { 87 ALC861_3ST, 88 ALC861_3ST_DIG, 89 ALC861_6ST_DIG, 90 ALC861_AUTO, 91 ALC861_MODEL_LAST, 88 ALC861_3ST, 89 ALC660_3ST, 90 ALC861_3ST_DIG, 91 ALC861_6ST_DIG, 92 ALC861_AUTO, 93 ALC861_MODEL_LAST, 92 94 }; 93 95 94 96 /* ALC882 models */ 95 97 enum { 96 ALC882_3ST_DIG, 97 ALC882_6ST_DIG, 98 ALC882_AUTO, 99 ALC882_MODEL_LAST, 98 ALC882_3ST_DIG, 99 ALC882_6ST_DIG, 100 ALC882_AUTO, 101 ALC882_MODEL_LAST, 102 }; 103 104 /* ALC883 models */ 105 enum { 106 ALC883_3ST_2ch_DIG, 107 ALC883_3ST_6ch_DIG, 108 ALC883_3ST_6ch, 109 ALC883_6ST_DIG, 110 ALC888_DEMO_BOARD, 111 ALC883_AUTO, 112 ALC883_MODEL_LAST, 100 113 }; 101 114 … … 104 117 105 118 struct alc_spec { 106 /* codec parameterization */ 107 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */ 108 unsigned int num_mixers; 109 110 const struct hda_verb *init_verbs[5]; /* initialization verbs 111 * don't forget NULL termination! 112 */ 113 unsigned int num_init_verbs; 114 115 char *stream_name_analog; /* analog PCM stream */ 116 struct hda_pcm_stream *stream_analog_playback; 117 struct hda_pcm_stream *stream_analog_capture; 118 119 char *stream_name_digital; /* digital PCM stream */ 120 struct hda_pcm_stream *stream_digital_playback; 121 struct hda_pcm_stream *stream_digital_capture; 122 123 /* playback */ 124 struct hda_multi_out multiout; /* playback set-up 125 * max_channels, dacs must be set 126 * dig_out_nid and hp_nid are optional 127 */ 128 129 /* capture */ 130 unsigned int num_adc_nids; 131 hda_nid_t *adc_nids; 132 hda_nid_t dig_in_nid; /* digital-in NID; optional */ 133 134 /* capture source */ 135 const struct hda_input_mux *input_mux; 136 unsigned int cur_mux[3]; 137 138 /* channel model */ 139 const struct hda_channel_mode *channel_mode; 140 int num_channel_mode; 141 142 /* PCM information */ 143 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */ 144 145 /* dynamic controls, init_verbs and input_mux */ 146 struct auto_pin_cfg autocfg; 147 unsigned int num_kctl_alloc, num_kctl_used; 148 struct snd_kcontrol_new *kctl_alloc; 149 struct hda_input_mux private_imux; 150 hda_nid_t private_dac_nids[5]; 151 152 /* hooks */ 153 void (*init_hook)(struct hda_codec *codec); 154 void (*unsol_event)(struct hda_codec *codec, unsigned int res); 155 156 /* for pin sensing */ 157 unsigned int sense_updated: 1; 158 unsigned int jack_present: 1; 119 /* codec parameterization */ 120 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */ 121 unsigned int num_mixers; 122 123 const struct hda_verb *init_verbs[5]; /* initialization verbs 124 * don't forget NULL 125 * termination! 126 */ 127 unsigned int num_init_verbs; 128 129 char *stream_name_analog; /* analog PCM stream */ 130 struct hda_pcm_stream *stream_analog_playback; 131 struct hda_pcm_stream *stream_analog_capture; 132 133 char *stream_name_digital; /* digital PCM stream */ 134 struct hda_pcm_stream *stream_digital_playback; 135 struct hda_pcm_stream *stream_digital_capture; 136 137 /* playback */ 138 struct hda_multi_out multiout; /* playback set-up 139 * max_channels, dacs must be set 140 * dig_out_nid and hp_nid are optional 141 */ 142 143 /* capture */ 144 unsigned int num_adc_nids; 145 hda_nid_t *adc_nids; 146 hda_nid_t dig_in_nid; /* digital-in NID; optional */ 147 148 /* capture source */ 149 const struct hda_input_mux *input_mux; 150 unsigned int cur_mux[3]; 151 152 /* channel model */ 153 const struct hda_channel_mode *channel_mode; 154 int num_channel_mode; 155 156 /* PCM information */ 157 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */ 158 159 /* dynamic controls, init_verbs and input_mux */ 160 struct auto_pin_cfg autocfg; 161 unsigned int num_kctl_alloc, num_kctl_used; 162 struct snd_kcontrol_new *kctl_alloc; 163 struct hda_input_mux private_imux; 164 hda_nid_t private_dac_nids[5]; 165 166 /* hooks */ 167 void (*init_hook)(struct hda_codec *codec); 168 void (*unsol_event)(struct hda_codec *codec, unsigned int res); 169 170 /* for pin sensing */ 171 unsigned int sense_updated: 1; 172 unsigned int jack_present: 1; 159 173 }; 160 174 … … 163 177 */ 164 178 struct alc_config_preset { 165 struct snd_kcontrol_new *mixers[5]; /* should be identical size with spec */166 const struct hda_verb *init_verbs[5];167 unsigned int num_dacs;168 hda_nid_t *dac_nids;169 hda_nid_t dig_out_nid; /* optional */170 hda_nid_t hp_nid; /* optional */171 unsigned int num_adc_nids;172 hda_nid_t *adc_nids;173 hda_nid_t dig_in_nid;174 unsigned int num_channel_mode;175 const struct hda_channel_mode *channel_mode;176 const struct hda_input_mux *input_mux;177 void (*unsol_event)(struct hda_codec *, unsigned int);178 void (*init_hook)(struct hda_codec *);179 struct snd_kcontrol_new *mixers[5]; /* should be identical size with spec */ 180 const struct hda_verb *init_verbs[5]; 181 unsigned int num_dacs; 182 hda_nid_t *dac_nids; 183 hda_nid_t dig_out_nid; /* optional */ 184 hda_nid_t hp_nid; /* optional */ 185 unsigned int num_adc_nids; 186 hda_nid_t *adc_nids; 187 hda_nid_t dig_in_nid; 188 unsigned int num_channel_mode; 189 const struct hda_channel_mode *channel_mode; 190 const struct hda_input_mux *input_mux; 191 void (*unsol_event)(struct hda_codec *, unsigned int); 192 void (*init_hook)(struct hda_codec *); 179 193 }; 180 194 … … 185 199 static int alc_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 186 200 { 187 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);188 struct alc_spec *spec = codec->spec;189 return snd_hda_input_mux_info(spec->input_mux, uinfo);201 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 202 struct alc_spec *spec = codec->spec; 203 return snd_hda_input_mux_info(spec->input_mux, uinfo); 190 204 } 191 205 192 206 static int alc_mux_enum_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 193 207 { 194 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);195 struct alc_spec *spec = codec->spec;196 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);197 198 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];199 return 0;208 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 209 struct alc_spec *spec = codec->spec; 210 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 211 212 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx]; 213 return 0; 200 214 } 201 215 202 216 static int alc_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 203 217 { 204 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);205 struct alc_spec *spec = codec->spec;206 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);207 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,208 spec->adc_nids[adc_idx], &spec->cur_mux[adc_idx]);218 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 219 struct alc_spec *spec = codec->spec; 220 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 221 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, 222 spec->adc_nids[adc_idx], &spec->cur_mux[adc_idx]); 209 223 } 210 224 … … 215 229 static int alc_ch_mode_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 216 230 { 217 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 218 struct alc_spec *spec = codec->spec; 219 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode, 220 spec->num_channel_mode); 221 } 222 223 static int alc_ch_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 224 { 225 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 226 struct alc_spec *spec = codec->spec; 227 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode, 228 spec->num_channel_mode, spec->multiout.max_channels); 229 } 230 231 static int alc_ch_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 232 { 233 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 234 struct alc_spec *spec = codec->spec; 235 return snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode, 236 spec->num_channel_mode, &spec->multiout.max_channels); 231 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 232 struct alc_spec *spec = codec->spec; 233 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode, 234 spec->num_channel_mode); 235 } 236 237 static int alc_ch_mode_get(struct snd_kcontrol *kcontrol, 238 struct snd_ctl_elem_value *ucontrol) 239 { 240 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 241 struct alc_spec *spec = codec->spec; 242 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode, 243 spec->num_channel_mode, 244 spec->multiout.max_channels); 245 } 246 247 static int alc_ch_mode_put(struct snd_kcontrol *kcontrol, 248 struct snd_ctl_elem_value *ucontrol) 249 { 250 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 251 struct alc_spec *spec = codec->spec; 252 return snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode, 253 spec->num_channel_mode, 254 &spec->multiout.max_channels); 237 255 } 238 256 … … 250 268 */ 251 269 static char *alc_pin_mode_names[] = { 252 "Mic 50pc bias", "Mic 80pc bias",253 "Line in", "Line out", "Headphone out",270 "Mic 50pc bias", "Mic 80pc bias", 271 "Line in", "Line out", "Headphone out", 254 272 }; 255 273 static unsigned char alc_pin_mode_values[] = { 256 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,274 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP, 257 275 }; 258 276 /* The control can present all 5 options, or it can limit the options based … … 267 285 */ 268 286 static signed char alc_pin_mode_dir_info[3][2] = { 269 { 0, 2 }, /* ALC_PIN_DIR_IN */270 { 3, 4 }, /* ALC_PIN_DIR_OUT */271 { 0, 4 }, /* ALC_PIN_DIR_INOUT */287 { 0, 2 }, /* ALC_PIN_DIR_IN */ 288 { 3, 4 }, /* ALC_PIN_DIR_OUT */ 289 { 0, 4 }, /* ALC_PIN_DIR_INOUT */ 272 290 }; 273 291 #define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0]) 274 292 #define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1]) 275 293 #define alc_pin_mode_n_items(_dir) \ 276 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)294 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1) 277 295 278 296 static int alc_pin_mode_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 279 297 { 280 unsigned int item_num = uinfo->value.enumerated.item;281 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;282 283 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;284 uinfo->count = 1;285 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);286 287 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))288 item_num = alc_pin_mode_min(dir);289 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);290 return 0;298 unsigned int item_num = uinfo->value.enumerated.item; 299 unsigned char dir = (kcontrol->private_value >> 16) & 0xff; 300 301 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 302 uinfo->count = 1; 303 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir); 304 305 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir)) 306 item_num = alc_pin_mode_min(dir); 307 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]); 308 return 0; 291 309 } 292 310 293 311 static int alc_pin_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 294 312 { 295 unsigned int i;296 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);297 hda_nid_t nid = kcontrol->private_value & 0xffff;298 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;299 long *valp = ucontrol->value.integer.value;300 unsigned int pinctl = snd_hda_codec_read(codec,nid,0,AC_VERB_GET_PIN_WIDGET_CONTROL,0x00);301 302 /* Find enumerated value for current pinctl setting */303 i = alc_pin_mode_min(dir);304 while (alc_pin_mode_values[i]!=pinctl && i<=alc_pin_mode_max(dir))305 i++;306 *valp = i<=alc_pin_mode_max(dir)?i:alc_pin_mode_min(dir);307 return 0;313 unsigned int i; 314 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 315 hda_nid_t nid = kcontrol->private_value & 0xffff; 316 unsigned char dir = (kcontrol->private_value >> 16) & 0xff; 317 long *valp = ucontrol->value.integer.value; 318 unsigned int pinctl = snd_hda_codec_read(codec,nid,0,AC_VERB_GET_PIN_WIDGET_CONTROL,0x00); 319 320 /* Find enumerated value for current pinctl setting */ 321 i = alc_pin_mode_min(dir); 322 while (alc_pin_mode_values[i]!=pinctl && i<=alc_pin_mode_max(dir)) 323 i++; 324 *valp = i<=alc_pin_mode_max(dir)?i:alc_pin_mode_min(dir); 325 return 0; 308 326 } 309 327 310 328 static int alc_pin_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 311 329 { 312 signed int change;313 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);314 hda_nid_t nid = kcontrol->private_value & 0xffff;315 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;316 long val = *ucontrol->value.integer.value;317 unsigned int pinctl = snd_hda_codec_read(codec,nid,0,AC_VERB_GET_PIN_WIDGET_CONTROL,0x00);318 319 if (val<alc_pin_mode_min(dir) || val>alc_pin_mode_max(dir))320 val = alc_pin_mode_min(dir);321 322 change = pinctl != alc_pin_mode_values[val];323 if (change) {324 /* Set pin mode to that requested */325 snd_hda_codec_write(codec,nid,0,AC_VERB_SET_PIN_WIDGET_CONTROL,326 alc_pin_mode_values[val]);327 328 /* Also enable the retasking pin's input/output as required329 * for the requested pin mode. Enum values of 2 or less are330 * input modes.331 *332 * Dynamically switching the input/output buffers probably333 * reduces noise slightly, particularly on input. However,334 * havingboth input and output buffers enabled335 * simultaneously doesn't seem to be problematic.336 */337 if (val <= 2) {338 snd_hda_codec_write(codec,nid,0,AC_VERB_SET_AMP_GAIN_MUTE,339 AMP_OUT_MUTE);340 snd_hda_codec_write(codec,nid,0,AC_VERB_SET_AMP_GAIN_MUTE,341 AMP_IN_UNMUTE(0));342 } else {343 snd_hda_codec_write(codec,nid,0,AC_VERB_SET_AMP_GAIN_MUTE,344 AMP_IN_MUTE(0));345 snd_hda_codec_write(codec,nid,0,AC_VERB_SET_AMP_GAIN_MUTE,346 AMP_OUT_UNMUTE);347 }348 }349 return change;330 signed int change; 331 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 332 hda_nid_t nid = kcontrol->private_value & 0xffff; 333 unsigned char dir = (kcontrol->private_value >> 16) & 0xff; 334 long val = *ucontrol->value.integer.value; 335 unsigned int pinctl = snd_hda_codec_read(codec,nid,0,AC_VERB_GET_PIN_WIDGET_CONTROL,0x00); 336 337 if (val<alc_pin_mode_min(dir) || val>alc_pin_mode_max(dir)) 338 val = alc_pin_mode_min(dir); 339 340 change = pinctl != alc_pin_mode_values[val]; 341 if (change) { 342 /* Set pin mode to that requested */ 343 snd_hda_codec_write(codec,nid,0,AC_VERB_SET_PIN_WIDGET_CONTROL, 344 alc_pin_mode_values[val]); 345 346 /* Also enable the retasking pin's input/output as required 347 * for the requested pin mode. Enum values of 2 or less are 348 * input modes. 349 * 350 * Dynamically switching the input/output buffers probably 351 * reduces noise slightly, particularly on input. However, 352 * havingboth input and output buffers enabled 353 * simultaneously doesn't seem to be problematic. 354 */ 355 if (val <= 2) { 356 snd_hda_codec_write(codec,nid,0,AC_VERB_SET_AMP_GAIN_MUTE, 357 AMP_OUT_MUTE); 358 snd_hda_codec_write(codec,nid,0,AC_VERB_SET_AMP_GAIN_MUTE, 359 AMP_IN_UNMUTE(0)); 360 } else { 361 snd_hda_codec_write(codec,nid,0,AC_VERB_SET_AMP_GAIN_MUTE, 362 AMP_IN_MUTE(0)); 363 snd_hda_codec_write(codec,nid,0,AC_VERB_SET_AMP_GAIN_MUTE, 364 AMP_OUT_UNMUTE); 365 } 366 } 367 return change; 350 368 } 351 369 352 370 #define ALC_PIN_MODE(xname, nid, dir) \ 353 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \354 .info = alc_pin_mode_info, \355 .get = alc_pin_mode_get, \356 .put = alc_pin_mode_put, \357 .private_value = nid | (dir<<16) }371 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 372 .info = alc_pin_mode_info, \ 373 .get = alc_pin_mode_get, \ 374 .put = alc_pin_mode_put, \ 375 .private_value = nid | (dir<<16) } 358 376 359 377 /* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged … … 365 383 static int alc_gpio_data_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 366 384 { 367 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;368 uinfo->count = 1;369 uinfo->value.integer.min = 0;370 uinfo->value.integer.max = 1;371 return 0;385 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; 386 uinfo->count = 1; 387 uinfo->value.integer.min = 0; 388 uinfo->value.integer.max = 1; 389 return 0; 372 390 } 373 391 static int alc_gpio_data_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 374 392 { 375 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);376 hda_nid_t nid = kcontrol->private_value & 0xffff;377 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;378 long *valp = ucontrol->value.integer.value;379 unsigned int val = snd_hda_codec_read(codec,nid,0,AC_VERB_GET_GPIO_DATA,0x00);380 381 *valp = (val & mask) != 0;382 return 0;393 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 394 hda_nid_t nid = kcontrol->private_value & 0xffff; 395 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 396 long *valp = ucontrol->value.integer.value; 397 unsigned int val = snd_hda_codec_read(codec,nid,0,AC_VERB_GET_GPIO_DATA,0x00); 398 399 *valp = (val & mask) != 0; 400 return 0; 383 401 } 384 402 static int alc_gpio_data_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 385 403 { 386 signed int change;387 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);388 hda_nid_t nid = kcontrol->private_value & 0xffff;389 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;390 long val = *ucontrol->value.integer.value;391 unsigned int gpio_data = snd_hda_codec_read(codec,nid,0,AC_VERB_GET_GPIO_DATA,0x00);392 393 /* Set/unset the masked GPIO bit(s) as needed */394 change = (val==0?0:mask) != (gpio_data & mask);395 if (val==0)396 gpio_data &= ~mask;397 else398 gpio_data |= mask;399 snd_hda_codec_write(codec,nid,0,AC_VERB_SET_GPIO_DATA,gpio_data);400 401 return change;404 signed int change; 405 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 406 hda_nid_t nid = kcontrol->private_value & 0xffff; 407 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 408 long val = *ucontrol->value.integer.value; 409 unsigned int gpio_data = snd_hda_codec_read(codec,nid,0,AC_VERB_GET_GPIO_DATA,0x00); 410 411 /* Set/unset the masked GPIO bit(s) as needed */ 412 change = (val==0?0:mask) != (gpio_data & mask); 413 if (val==0) 414 gpio_data &= ~mask; 415 else 416 gpio_data |= mask; 417 snd_hda_codec_write(codec,nid,0,AC_VERB_SET_GPIO_DATA,gpio_data); 418 419 return change; 402 420 } 403 421 #define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \ 404 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \405 .info = alc_gpio_data_info, \406 .get = alc_gpio_data_get, \407 .put = alc_gpio_data_put, \408 .private_value = nid | (mask<<16) }422 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 423 .info = alc_gpio_data_info, \ 424 .get = alc_gpio_data_get, \ 425 .put = alc_gpio_data_put, \ 426 .private_value = nid | (mask<<16) } 409 427 #endif /* CONFIG_SND_DEBUG */ 410 428 … … 419 437 static int alc_spdif_ctrl_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 420 438 { 421 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;422 uinfo->count = 1;423 uinfo->value.integer.min = 0;424 uinfo->value.integer.max = 1;425 return 0;439 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; 440 uinfo->count = 1; 441 uinfo->value.integer.min = 0; 442 uinfo->value.integer.max = 1; 443 return 0; 426 444 } 427 445 static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 428 446 { 429 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);430 hda_nid_t nid = kcontrol->private_value & 0xffff;431 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;432 long *valp = ucontrol->value.integer.value;433 unsigned int val = snd_hda_codec_read(codec,nid,0,AC_VERB_GET_DIGI_CONVERT,0x00);434 435 *valp = (val & mask) != 0;436 return 0;447 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 448 hda_nid_t nid = kcontrol->private_value & 0xffff; 449 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 450 long *valp = ucontrol->value.integer.value; 451 unsigned int val = snd_hda_codec_read(codec,nid,0,AC_VERB_GET_DIGI_CONVERT,0x00); 452 453 *valp = (val & mask) != 0; 454 return 0; 437 455 } 438 456 static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 439 457 { 440 signed int change;441 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);442 hda_nid_t nid = kcontrol->private_value & 0xffff;443 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;444 long val = *ucontrol->value.integer.value;445 unsigned int ctrl_data = snd_hda_codec_read(codec,nid,0,AC_VERB_GET_DIGI_CONVERT,0x00);446 447 /* Set/unset the masked control bit(s) as needed */448 change = (val==0?0:mask) != (ctrl_data & mask);449 if (val==0)450 ctrl_data &= ~mask;451 else452 ctrl_data |= mask;453 snd_hda_codec_write(codec,nid,0,AC_VERB_SET_DIGI_CONVERT_1,ctrl_data);454 455 return change;458 signed int change; 459 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 460 hda_nid_t nid = kcontrol->private_value & 0xffff; 461 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 462 long val = *ucontrol->value.integer.value; 463 unsigned int ctrl_data = snd_hda_codec_read(codec,nid,0,AC_VERB_GET_DIGI_CONVERT,0x00); 464 465 /* Set/unset the masked control bit(s) as needed */ 466 change = (val==0?0:mask) != (ctrl_data & mask); 467 if (val==0) 468 ctrl_data &= ~mask; 469 else 470 ctrl_data |= mask; 471 snd_hda_codec_write(codec,nid,0,AC_VERB_SET_DIGI_CONVERT_1,ctrl_data); 472 473 return change; 456 474 } 457 475 #define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \ 458 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \459 .info = alc_spdif_ctrl_info, \460 .get = alc_spdif_ctrl_get, \461 .put = alc_spdif_ctrl_put, \462 .private_value = nid | (mask<<16) }476 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 477 .info = alc_spdif_ctrl_info, \ 478 .get = alc_spdif_ctrl_get, \ 479 .put = alc_spdif_ctrl_put, \ 480 .private_value = nid | (mask<<16) } 463 481 #endif /* CONFIG_SND_DEBUG */ 464 482 … … 468 486 static void setup_preset(struct alc_spec *spec, const struct alc_config_preset *preset) 469 487 { 470 int i;471 472 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)473 spec->mixers[spec->num_mixers++] = preset->mixers[i];474 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i]; i++)475 spec->init_verbs[spec->num_init_verbs++] = preset->init_verbs[i];476 477 spec->channel_mode = preset->channel_mode;478 spec->num_channel_mode = preset->num_channel_mode;479 480 spec->multiout.max_channels = spec->channel_mode[0].channels;481 482 spec->multiout.num_dacs = preset->num_dacs;483 spec->multiout.dac_nids = preset->dac_nids;484 spec->multiout.dig_out_nid = preset->dig_out_nid;485 spec->multiout.hp_nid = preset->hp_nid;486 487 spec->input_mux = preset->input_mux;488 489 spec->num_adc_nids = preset->num_adc_nids;490 spec->adc_nids = preset->adc_nids;491 spec->dig_in_nid = preset->dig_in_nid;492 spec->unsol_event = preset->unsol_event;493 spec->init_hook = preset->init_hook;488 int i; 489 490 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++) 491 spec->mixers[spec->num_mixers++] = preset->mixers[i]; 492 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i]; i++) 493 spec->init_verbs[spec->num_init_verbs++] = preset->init_verbs[i]; 494 495 spec->channel_mode = preset->channel_mode; 496 spec->num_channel_mode = preset->num_channel_mode; 497 498 spec->multiout.max_channels = spec->channel_mode[0].channels; 499 500 spec->multiout.num_dacs = preset->num_dacs; 501 spec->multiout.dac_nids = preset->dac_nids; 502 spec->multiout.dig_out_nid = preset->dig_out_nid; 503 spec->multiout.hp_nid = preset->hp_nid; 504 505 spec->input_mux = preset->input_mux; 506 507 spec->num_adc_nids = preset->num_adc_nids; 508 spec->adc_nids = preset->adc_nids; 509 spec->dig_in_nid = preset->dig_in_nid; 510 spec->unsol_event = preset->unsol_event; 511 spec->init_hook = preset->init_hook; 494 512 } 495 513 … … 503 521 504 522 static hda_nid_t alc880_dac_nids[4] = { 505 /* front, rear, clfe, rear_surr */506 0x02, 0x05, 0x04, 0x03523 /* front, rear, clfe, rear_surr */ 524 0x02, 0x05, 0x04, 0x03 507 525 }; 508 526 509 527 static hda_nid_t alc880_adc_nids[3] = { 510 /* ADC0-2 */511 0x07, 0x08, 0x09,528 /* ADC0-2 */ 529 0x07, 0x08, 0x09, 512 530 }; 513 531 … … 517 535 */ 518 536 static hda_nid_t alc880_adc_nids_alt[2] = { 519 /* ADC1-2 */520 0x08, 0x09,537 /* ADC1-2 */ 538 0x08, 0x09, 521 539 }; 522 540 … … 525 543 526 544 static struct hda_input_mux alc880_capture_source = { 527 .num_items = 4,528 .items = {529 { "Mic", 0x0 },530 { "Front Mic", 0x3 },531 { "Line", 0x2 },532 { "CD", 0x4 },533 },545 .num_items = 4, 546 .items = { 547 { "Mic", 0x0 }, 548 { "Front Mic", 0x3 }, 549 { "Line", 0x2 }, 550 { "CD", 0x4 }, 551 }, 534 552 }; 535 553 … … 537 555 /* 2ch mode */ 538 556 static struct hda_verb alc880_threestack_ch2_init[] = { 539 /* set line-in to input, mute it */540 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },541 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },542 /* set mic-in to input vref 80%, mute it */543 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },544 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },545 {0} /* end */557 /* set line-in to input, mute it */ 558 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 559 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 560 /* set mic-in to input vref 80%, mute it */ 561 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 562 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 563 {0} /* end */ 546 564 }; 547 565 548 566 /* 6ch mode */ 549 567 static struct hda_verb alc880_threestack_ch6_init[] = { 550 /* set line-in to output, unmute it */551 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },552 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },553 /* set mic-in to output, unmute it */554 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },555 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },556 {0} /* end */568 /* set line-in to output, unmute it */ 569 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 570 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 571 /* set mic-in to output, unmute it */ 572 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 573 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 574 {0} /* end */ 557 575 }; 558 576 559 577 static struct hda_channel_mode alc880_threestack_modes[2] = { 560 { 2, alc880_threestack_ch2_init },561 { 6, alc880_threestack_ch6_init },578 { 2, alc880_threestack_ch2_init }, 579 { 6, alc880_threestack_ch6_init }, 562 580 }; 563 581 564 582 static struct snd_kcontrol_new alc880_three_stack_mixer[] = { 565 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),566 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),567 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),568 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),569 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),570 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),571 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),572 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),573 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),574 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),575 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),576 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),577 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),578 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),579 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),580 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),581 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),582 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),583 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),584 {585 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,586 .name = "Channel Mode",587 .info = alc_ch_mode_info,588 .get = alc_ch_mode_get,589 .put = alc_ch_mode_put,590 },591 {0} /* end */583 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 584 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 585 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 586 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT), 587 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 588 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 589 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 590 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 591 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 592 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 593 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 594 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 595 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 596 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 597 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT), 598 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT), 599 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 600 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 601 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT), 602 { 603 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 604 .name = "Channel Mode", 605 .info = alc_ch_mode_info, 606 .get = alc_ch_mode_get, 607 .put = alc_ch_mode_put, 608 }, 609 {0} /* end */ 592 610 }; 593 611 594 612 /* capture mixer elements */ 595 613 static struct snd_kcontrol_new alc880_capture_mixer[] = { 596 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),597 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),598 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),599 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),600 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),601 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),602 {603 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,604 /* The multiple "Capture Source" controls confuse alsamixer605 * So call somewhat different..606 * FIXME: the controls appear in the "playback" view!607 */608 /* .name = "Capture Source", */609 .name = "Input Source",610 .count = 3,611 .info = alc_mux_enum_info,612 .get = alc_mux_enum_get,613 .put = alc_mux_enum_put,614 },615 {0} /* end */614 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT), 615 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT), 616 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT), 617 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT), 618 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT), 619 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT), 620 { 621 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 622 /* The multiple "Capture Source" controls confuse alsamixer 623 * So call somewhat different.. 624 * FIXME: the controls appear in the "playback" view! 625 */ 626 /* .name = "Capture Source", */ 627 .name = "Input Source", 628 .count = 3, 629 .info = alc_mux_enum_info, 630 .get = alc_mux_enum_get, 631 .put = alc_mux_enum_put, 632 }, 633 {0} /* end */ 616 634 }; 617 635 618 636 /* capture mixer elements (in case NID 0x07 not available) */ 619 637 static struct snd_kcontrol_new alc880_capture_alt_mixer[] = { 620 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),621 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),622 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),623 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),624 {625 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,626 /* The multiple "Capture Source" controls confuse alsamixer627 * So call somewhat different..628 * FIXME: the controls appear in the "playback" view!629 */630 /* .name = "Capture Source", */631 .name = "Input Source",632 .count = 2,633 .info = alc_mux_enum_info,634 .get = alc_mux_enum_get,635 .put = alc_mux_enum_put,636 },637 {0} /* end */638 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 639 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 640 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), 641 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), 642 { 643 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 644 /* The multiple "Capture Source" controls confuse alsamixer 645 * So call somewhat different.. 646 * FIXME: the controls appear in the "playback" view! 647 */ 648 /* .name = "Capture Source", */ 649 .name = "Input Source", 650 .count = 2, 651 .info = alc_mux_enum_info, 652 .get = alc_mux_enum_get, 653 .put = alc_mux_enum_put, 654 }, 655 {0} /* end */ 638 656 }; 639 657 … … 650 668 /* additional mixers to alc880_three_stack_mixer */ 651 669 static struct snd_kcontrol_new alc880_five_stack_mixer[] = { 652 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),653 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),654 {0} /* end */670 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 671 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT), 672 {0} /* end */ 655 673 }; 656 674 … … 658 676 /* 6ch mode */ 659 677 static struct hda_verb alc880_fivestack_ch6_init[] = { 660 /* set line-in to input, mute it */661 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },662 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },663 {0} /* end */678 /* set line-in to input, mute it */ 679 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 680 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 681 {0} /* end */ 664 682 }; 665 683 666 684 /* 8ch mode */ 667 685 static struct hda_verb alc880_fivestack_ch8_init[] = { 668 /* set line-in to output, unmute it */669 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },670 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },671 {0} /* end */686 /* set line-in to output, unmute it */ 687 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 688 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 689 {0} /* end */ 672 690 }; 673 691 674 692 static struct hda_channel_mode alc880_fivestack_modes[2] = { 675 { 6, alc880_fivestack_ch6_init },676 { 8, alc880_fivestack_ch8_init },693 { 6, alc880_fivestack_ch6_init }, 694 { 8, alc880_fivestack_ch8_init }, 677 695 }; 678 696 … … 687 705 688 706 static hda_nid_t alc880_6st_dac_nids[4] = { 689 /* front, rear, clfe, rear_surr */690 0x02, 0x03, 0x04, 0x05707 /* front, rear, clfe, rear_surr */ 708 0x02, 0x03, 0x04, 0x05 691 709 }; 692 710 693 711 static struct hda_input_mux alc880_6stack_capture_source = { 694 .num_items = 4,695 .items = {696 { "Mic", 0x0 },697 { "Front Mic", 0x1 },698 { "Line", 0x2 },699 { "CD", 0x4 },700 },712 .num_items = 4, 713 .items = { 714 { "Mic", 0x0 }, 715 { "Front Mic", 0x1 }, 716 { "Line", 0x2 }, 717 { "CD", 0x4 }, 718 }, 701 719 }; 702 720 703 721 /* fixed 8-channels */ 704 722 static struct hda_channel_mode alc880_sixstack_modes[1] = { 705 { 8, NULL },723 { 8, NULL }, 706 724 }; 707 725 708 726 static struct snd_kcontrol_new alc880_six_stack_mixer[] = { 709 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),710 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),711 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),712 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),713 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),714 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),715 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),716 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),717 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),718 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),719 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),720 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),721 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),722 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),723 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),724 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),725 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),726 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),727 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),728 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),729 {730 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,731 .name = "Channel Mode",732 .info = alc_ch_mode_info,733 .get = alc_ch_mode_get,734 .put = alc_ch_mode_put,735 },736 {0} /* end */727 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 728 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 729 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 730 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 731 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 732 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 733 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 734 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 735 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 736 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 737 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 738 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 739 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 740 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 741 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 742 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 743 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 744 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 745 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 746 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 747 { 748 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 749 .name = "Channel Mode", 750 .info = alc_ch_mode_info, 751 .get = alc_ch_mode_get, 752 .put = alc_ch_mode_put, 753 }, 754 {0} /* end */ 737 755 }; 738 756 … … 764 782 765 783 static hda_nid_t alc880_w810_dac_nids[3] = { 766 /* front, rear/surround, clfe */767 0x02, 0x03, 0x04784 /* front, rear/surround, clfe */ 785 0x02, 0x03, 0x04 768 786 }; 769 787 770 788 /* fixed 6 channels */ 771 789 static struct hda_channel_mode alc880_w810_modes[1] = { 772 { 6, NULL }790 { 6, NULL } 773 791 }; 774 792 775 793 /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */ 776 794 static struct snd_kcontrol_new alc880_w810_base_mixer[] = { 777 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),778 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),779 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),780 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),781 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),782 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),783 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),784 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),785 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),786 {0} /* end */795 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 796 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 797 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 798 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 799 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 800 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 801 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 802 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 803 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 804 {0} /* end */ 787 805 }; 788 806 … … 796 814 797 815 static hda_nid_t alc880_z71v_dac_nids[1] = { 798 0x02816 0x02 799 817 }; 800 818 #define ALC880_Z71V_HP_DAC 0x03 … … 802 820 /* fixed 2 channels */ 803 821 static struct hda_channel_mode alc880_2_jack_modes[1] = { 804 { 2, NULL }822 { 2, NULL } 805 823 }; 806 824 807 825 static struct snd_kcontrol_new alc880_z71v_mixer[] = { 808 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),809 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),810 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),811 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),812 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),813 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),814 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),815 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),816 {0} /* end */826 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 827 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 828 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 829 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT), 830 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 831 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 832 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 833 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 834 {0} /* end */ 817 835 }; 818 836 … … 827 845 828 846 static hda_nid_t alc880_f1734_dac_nids[1] = { 829 0x03847 0x03 830 848 }; 831 849 #define ALC880_F1734_HP_DAC 0x02 832 850 833 851 static struct snd_kcontrol_new alc880_f1734_mixer[] = { 834 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),835 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),836 HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),837 HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x0d, 2, HDA_INPUT),838 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),839 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),840 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),841 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),842 {0} /* end */852 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 853 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 854 HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 855 HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 856 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 857 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 858 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 859 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 860 {0} /* end */ 843 861 }; 844 862 … … 857 875 858 876 static struct snd_kcontrol_new alc880_asus_mixer[] = { 859 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),860 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),861 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),862 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),863 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),864 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),865 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),866 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),867 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),868 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),869 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),870 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),871 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),872 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),873 {874 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,875 .name = "Channel Mode",876 .info = alc_ch_mode_info,877 .get = alc_ch_mode_get,878 .put = alc_ch_mode_put,879 },880 {0} /* end */877 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 878 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 879 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 880 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 881 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 882 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 883 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 884 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 885 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 886 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 887 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 888 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 889 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 890 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 891 { 892 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 893 .name = "Channel Mode", 894 .info = alc_ch_mode_info, 895 .get = alc_ch_mode_get, 896 .put = alc_ch_mode_put, 897 }, 898 {0} /* end */ 881 899 }; 882 900 … … 892 910 /* additional mixers to alc880_asus_mixer */ 893 911 static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = { 894 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),895 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),896 {0} /* end */912 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT), 913 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT), 914 {0} /* end */ 897 915 }; 898 916 899 917 /* additional mixers to alc880_asus_mixer */ 900 918 static struct snd_kcontrol_new alc880_pcbeep_mixer[] = { 901 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),902 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),903 {0} /* end */919 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 920 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 921 {0} /* end */ 904 922 }; 905 923 906 924 /* TCL S700 */ 907 925 static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = { 908 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),909 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),910 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),911 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),912 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),913 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),914 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),915 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),916 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),917 {918 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,919 /* The multiple "Capture Source" controls confuse alsamixer920 * So call somewhat different..921 * FIXME: the controls appear in the "playback" view!922 */923 /* .name = "Capture Source", */924 .name = "Input Source",925 .count = 1,926 .info = alc_mux_enum_info,927 .get = alc_mux_enum_get,928 .put = alc_mux_enum_put,929 },930 {0} /* end */926 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 927 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 928 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 929 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT), 930 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT), 931 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT), 932 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT), 933 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 934 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 935 { 936 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 937 /* The multiple "Capture Source" controls confuse alsamixer 938 * So call somewhat different.. 939 * FIXME: the controls appear in the "playback" view! 940 */ 941 /* .name = "Capture Source", */ 942 .name = "Input Source", 943 .count = 1, 944 .info = alc_mux_enum_info, 945 .get = alc_mux_enum_get, 946 .put = alc_mux_enum_put, 947 }, 948 {0} /* end */ 931 949 }; 932 950 … … 936 954 static int alc_build_controls(struct hda_codec *codec) 937 955 { 938 struct alc_spec *spec = codec->spec;939 int err;940 int i;941 942 for (i = 0; i < spec->num_mixers; i++) {943 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);944 if (err < 0)945 return err;946 }947 948 if (spec->multiout.dig_out_nid) {949 err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid);950 if (err < 0)951 return err;952 }953 if (spec->dig_in_nid) {954 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);955 if (err < 0)956 return err;957 }958 return 0;956 struct alc_spec *spec = codec->spec; 957 int err; 958 int i; 959 960 for (i = 0; i < spec->num_mixers; i++) { 961 err = snd_hda_add_new_ctls(codec, spec->mixers[i]); 962 if (err < 0) 963 return err; 964 } 965 966 if (spec->multiout.dig_out_nid) { 967 err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid); 968 if (err < 0) 969 return err; 970 } 971 if (spec->dig_in_nid) { 972 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid); 973 if (err < 0) 974 return err; 975 } 976 return 0; 959 977 } 960 978 … … 968 986 */ 969 987 static struct hda_verb alc880_volume_init_verbs[] = { 970 /*971 * Unmute ADC0-2 and set the default input to mic-in972 */973 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},974 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},975 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},976 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},977 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},978 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},979 980 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback981 * mixer widget982 * Note: PASD motherboards uses the Line In 2 as the input for front panel983 * mic (mic 2)984 */985 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */986 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},987 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},988 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},989 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},990 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},991 992 /*993 * Set up output mixers (0x0c - 0x0f)994 */995 /* set vol=0 to output mixers */996 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},997 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},998 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},999 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},1000 /* set up input amps for analog loopback */1001 /* Amp Indices: DAC = 0, mixer = 1 */1002 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},1003 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},1004 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},1005 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},1006 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},1007 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},1008 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},1009 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},1010 1011 {0}988 /* 989 * Unmute ADC0-2 and set the default input to mic-in 990 */ 991 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 992 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 993 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 994 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 995 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 996 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 997 998 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 999 * mixer widget 1000 * Note: PASD motherboards uses the Line In 2 as the input for front panel 1001 * mic (mic 2) 1002 */ 1003 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 1004 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1005 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 1006 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 1007 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 1008 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 1009 1010 /* 1011 * Set up output mixers (0x0c - 0x0f) 1012 */ 1013 /* set vol=0 to output mixers */ 1014 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1015 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1016 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1017 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1018 /* set up input amps for analog loopback */ 1019 /* Amp Indices: DAC = 0, mixer = 1 */ 1020 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1021 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1022 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1023 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1024 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1025 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1026 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1027 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1028 1029 {0} 1012 1030 }; 1013 1031 … … 1017 1035 */ 1018 1036 static struct hda_verb alc880_pin_3stack_init_verbs[] = { 1019 /*1020 * preset connection lists of input pins1021 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround1022 */1023 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */1024 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */1025 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */1026 1027 /*1028 * Set pin mode and muting1029 */1030 /* set front pin widgets 0x14 for output */1031 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},1032 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},1033 /* Mic1 (rear panel) pin widget for input and vref at 80% */1034 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},1035 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},1036 /* Mic2 (as headphone out) for HP output */1037 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},1038 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},1039 /* Line In pin widget for input */1040 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},1041 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},1042 /* Line2 (as front mic) pin widget for input and vref at 80% */1043 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},1044 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},1045 /* CD pin widget for input */1046 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},1047 1048 {0}1037 /* 1038 * preset connection lists of input pins 1039 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround 1040 */ 1041 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 1042 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 1043 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */ 1044 1045 /* 1046 * Set pin mode and muting 1047 */ 1048 /* set front pin widgets 0x14 for output */ 1049 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1050 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1051 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 1052 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1053 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1054 /* Mic2 (as headphone out) for HP output */ 1055 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1056 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1057 /* Line In pin widget for input */ 1058 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1059 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1060 /* Line2 (as front mic) pin widget for input and vref at 80% */ 1061 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1062 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1063 /* CD pin widget for input */ 1064 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1065 1066 {0} 1049 1067 }; 1050 1068 … … 1055 1073 */ 1056 1074 static struct hda_verb alc880_pin_5stack_init_verbs[] = { 1057 /*1058 * preset connection lists of input pins1059 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround1060 */1061 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */1062 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */1063 1064 /*1065 * Set pin mode and muting1066 */1067 /* set pin widgets 0x14-0x17 for output */1068 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},1069 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},1070 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},1071 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},1072 /* unmute pins for output (no gain on this amp) */1073 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},1074 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},1075 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},1076 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},1077 1078 /* Mic1 (rear panel) pin widget for input and vref at 80% */1079 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},1080 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},1081 /* Mic2 (as headphone out) for HP output */1082 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},1083 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},1084 /* Line In pin widget for input */1085 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},1086 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},1087 /* Line2 (as front mic) pin widget for input and vref at 80% */1088 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},1089 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},1090 /* CD pin widget for input */1091 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},1092 1093 {0}1075 /* 1076 * preset connection lists of input pins 1077 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround 1078 */ 1079 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 1080 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */ 1081 1082 /* 1083 * Set pin mode and muting 1084 */ 1085 /* set pin widgets 0x14-0x17 for output */ 1086 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1087 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1088 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1089 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1090 /* unmute pins for output (no gain on this amp) */ 1091 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1092 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1093 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1094 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1095 1096 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 1097 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1098 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1099 /* Mic2 (as headphone out) for HP output */ 1100 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1101 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1102 /* Line In pin widget for input */ 1103 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1104 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1105 /* Line2 (as front mic) pin widget for input and vref at 80% */ 1106 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1107 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1108 /* CD pin widget for input */ 1109 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1110 1111 {0} 1094 1112 }; 1095 1113 … … 1099 1117 */ 1100 1118 static struct hda_verb alc880_pin_w810_init_verbs[] = { 1101 /* hphone/speaker input selector: front DAC */1102 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},1103 1104 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},1105 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},1106 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},1107 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},1108 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},1109 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},1110 1111 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},1112 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},1113 1114 {0}1119 /* hphone/speaker input selector: front DAC */ 1120 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0}, 1121 1122 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1123 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1124 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1125 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1126 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1127 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1128 1129 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1130 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1131 1132 {0} 1115 1133 }; 1116 1134 … … 1120 1138 */ 1121 1139 static struct hda_verb alc880_pin_z71v_init_verbs[] = { 1122 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},1123 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},1124 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},1125 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},1126 1127 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},1128 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},1129 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},1130 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},1131 1132 {0}1140 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1141 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1142 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1143 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1144 1145 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1146 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1147 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1148 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1149 1150 {0} 1133 1151 }; 1134 1152 … … 1139 1157 */ 1140 1158 static struct hda_verb alc880_pin_6stack_init_verbs[] = { 1141 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */1142 1143 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},1144 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},1145 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},1146 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},1147 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},1148 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},1149 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},1150 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},1151 1152 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},1153 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},1154 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},1155 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},1156 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},1157 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},1158 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},1159 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},1160 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},1161 1162 {0}1159 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 1160 1161 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1162 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1163 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1164 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1165 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1166 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1167 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1168 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1169 1170 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1171 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1172 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1173 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1174 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1175 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1176 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1177 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1178 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1179 1180 {0} 1163 1181 }; 1164 1182 … … 1169 1187 */ 1170 1188 static struct hda_verb alc880_pin_f1734_init_verbs[] = { 1171 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},1172 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},1173 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},1174 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},1175 1176 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},1177 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},1178 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},1179 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},1180 1181 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},1182 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},1183 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},1184 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},1185 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},1186 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},1187 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},1188 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},1189 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},1190 1191 {0}1189 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, 1190 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, 1191 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, 1192 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, 1193 1194 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1195 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1196 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1197 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1198 1199 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1200 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1201 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1202 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1203 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1204 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1205 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1206 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1207 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1208 1209 {0} 1192 1210 }; 1193 1211 … … 1198 1216 */ 1199 1217 static struct hda_verb alc880_pin_asus_init_verbs[] = { 1200 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},1201 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},1202 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},1203 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},1204 1205 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},1206 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},1207 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},1208 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},1209 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},1210 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},1211 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},1212 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},1213 1214 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},1215 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},1216 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},1217 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},1218 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},1219 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},1220 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},1221 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},1222 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},1223 1224 {0}1218 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, 1219 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, 1220 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, 1221 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, 1222 1223 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1224 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1225 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1226 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1227 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1228 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1229 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1230 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1231 1232 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1233 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1234 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1235 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1236 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1237 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1238 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1239 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1240 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1241 1242 {0} 1225 1243 }; 1226 1244 1227 1245 /* Enable GPIO mask and set output */ 1228 1246 static struct hda_verb alc880_gpio1_init_verbs[] = { 1229 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},1230 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},1231 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},1232 1233 {0}1247 {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, 1248 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 1249 {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, 1250 1251 {0} 1234 1252 }; 1235 1253 1236 1254 /* Enable GPIO mask and set output */ 1237 1255 static struct hda_verb alc880_gpio2_init_verbs[] = { 1238 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},1239 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},1240 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},1241 1242 {0}1256 {0x01, AC_VERB_SET_GPIO_MASK, 0x02}, 1257 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02}, 1258 {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, 1259 1260 {0} 1243 1261 }; 1244 1262 1245 1263 /* Clevo m520g init */ 1246 1264 static struct hda_verb alc880_pin_clevo_init_verbs[] = { 1247 /* headphone output */1248 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},1249 /* line-out */1250 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},1251 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},1252 /* Line-in */1253 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},1254 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},1255 /* CD */1256 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},1257 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},1258 /* Mic1 (rear panel) */1259 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},1260 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},1261 /* Mic2 (front panel) */1262 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},1263 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},1264 /* headphone */1265 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},1266 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},1267 /* change to EAPD mode */1268 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},1269 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},1270 1271 {0}1265 /* headphone output */ 1266 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01}, 1267 /* line-out */ 1268 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1269 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1270 /* Line-in */ 1271 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1272 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1273 /* CD */ 1274 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1275 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1276 /* Mic1 (rear panel) */ 1277 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1278 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1279 /* Mic2 (front panel) */ 1280 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1281 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1282 /* headphone */ 1283 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1284 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1285 /* change to EAPD mode */ 1286 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 1287 {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, 1288 1289 {0} 1272 1290 }; 1273 1291 1274 1292 static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = { 1275 /* Headphone output */1276 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},1277 /* Front output*/1278 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},1279 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},1280 1281 /* Line In pin widget for input */1282 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},1283 /* CD pin widget for input */1284 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},1285 /* Mic1 (rear panel) pin widget for input and vref at 80% */1286 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},1287 1288 /* change to EAPD mode */1289 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},1290 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},1291 1292 {0}1293 /* Headphone output */ 1294 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1295 /* Front output*/ 1296 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1297 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 1298 1299 /* Line In pin widget for input */ 1300 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1301 /* CD pin widget for input */ 1302 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1303 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 1304 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1305 1306 /* change to EAPD mode */ 1307 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 1308 {0x20, AC_VERB_SET_PROC_COEF, 0x3070}, 1309 1310 {0} 1293 1311 }; 1294 1312 … … 1509 1527 static int alc_init(struct hda_codec *codec) 1510 1528 { 1511 struct alc_spec *spec = codec->spec;1512 unsigned int i;1513 1514 for (i = 0; i < spec->num_init_verbs; i++)1515 snd_hda_sequence_write(codec, spec->init_verbs[i]);1516 if (spec->init_hook)1517 spec->init_hook(codec);1518 return 0;1529 struct alc_spec *spec = codec->spec; 1530 unsigned int i; 1531 1532 for (i = 0; i < spec->num_init_verbs; i++) 1533 snd_hda_sequence_write(codec, spec->init_verbs[i]); 1534 if (spec->init_hook) 1535 spec->init_hook(codec); 1536 return 0; 1519 1537 } 1520 1538 … … 1533 1551 static int alc_resume(struct hda_codec *codec) 1534 1552 { 1535 struct alc_spec *spec = codec->spec;1536 int i;1537 1538 alc_init(codec);1539 for (i = 0; i < spec->num_mixers; i++)1540 snd_hda_resume_ctls(codec, spec->mixers[i]);1541 if (spec->multiout.dig_out_nid)1542 snd_hda_resume_spdif_out(codec);1543 if (spec->dig_in_nid)1544 snd_hda_resume_spdif_in(codec);1545 1546 return 0;1553 struct alc_spec *spec = codec->spec; 1554 int i; 1555 1556 alc_init(codec); 1557 for (i = 0; i < spec->num_mixers; i++) 1558 snd_hda_resume_ctls(codec, spec->mixers[i]); 1559 if (spec->multiout.dig_out_nid) 1560 snd_hda_resume_spdif_out(codec); 1561 if (spec->dig_in_nid) 1562 snd_hda_resume_spdif_in(codec); 1563 1564 return 0; 1547 1565 } 1548 1566 #endif … … 1552 1570 */ 1553 1571 static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo, 1554 struct hda_codec *codec,1555 struct snd_pcm_substream *substream)1556 { 1557 struct alc_spec *spec = codec->spec;1558 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);1572 struct hda_codec *codec, 1573 struct snd_pcm_substream *substream) 1574 { 1575 struct alc_spec *spec = codec->spec; 1576 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream); 1559 1577 } 1560 1578 1561 1579 static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 1562 struct hda_codec *codec,1563 unsigned int stream_tag,1564 unsigned int format,1565 struct snd_pcm_substream *substream)1566 { 1567 struct alc_spec *spec = codec->spec;1568 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag,1569 format, substream);1580 struct hda_codec *codec, 1581 unsigned int stream_tag, 1582 unsigned int format, 1583 struct snd_pcm_substream *substream) 1584 { 1585 struct alc_spec *spec = codec->spec; 1586 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag, 1587 format, substream); 1570 1588 } 1571 1589 1572 1590 static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, 1573 struct hda_codec *codec,1574 struct snd_pcm_substream *substream)1575 { 1576 struct alc_spec *spec = codec->spec;1577 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);1591 struct hda_codec *codec, 1592 struct snd_pcm_substream *substream) 1593 { 1594 struct alc_spec *spec = codec->spec; 1595 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); 1578 1596 } 1579 1597 … … 1582 1600 */ 1583 1601 static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo, 1584 struct hda_codec *codec,1585 struct snd_pcm_substream *substream)1586 { 1587 struct alc_spec *spec = codec->spec;1588 return snd_hda_multi_out_dig_open(codec, &spec->multiout);1602 struct hda_codec *codec, 1603 struct snd_pcm_substream *substream) 1604 { 1605 struct alc_spec *spec = codec->spec; 1606 return snd_hda_multi_out_dig_open(codec, &spec->multiout); 1589 1607 } 1590 1608 1591 1609 static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, 1592 struct hda_codec *codec,1593 struct snd_pcm_substream *substream)1594 { 1595 struct alc_spec *spec = codec->spec;1596 return snd_hda_multi_out_dig_close(codec, &spec->multiout);1610 struct hda_codec *codec, 1611 struct snd_pcm_substream *substream) 1612 { 1613 struct alc_spec *spec = codec->spec; 1614 return snd_hda_multi_out_dig_close(codec, &spec->multiout); 1597 1615 } 1598 1616 … … 1601 1619 */ 1602 1620 static int alc880_capture_pcm_prepare(struct hda_pcm_stream *hinfo, 1603 struct hda_codec *codec,1604 unsigned int stream_tag,1605 unsigned int format,1606 struct snd_pcm_substream *substream)1607 { 1608 struct alc_spec *spec = codec->spec;1609 1610 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],1611 stream_tag, 0, format);1612 return 0;1621 struct hda_codec *codec, 1622 unsigned int stream_tag, 1623 unsigned int format, 1624 struct snd_pcm_substream *substream) 1625 { 1626 struct alc_spec *spec = codec->spec; 1627 1628 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], 1629 stream_tag, 0, format); 1630 return 0; 1613 1631 } 1614 1632 1615 1633 static int alc880_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, 1616 struct hda_codec *codec,1617 struct snd_pcm_substream *substream)1618 { 1619 struct alc_spec *spec = codec->spec;1620 1621 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], 0, 0, 0);1622 return 0;1634 struct hda_codec *codec, 1635 struct snd_pcm_substream *substream) 1636 { 1637 struct alc_spec *spec = codec->spec; 1638 1639 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], 0, 0, 0); 1640 return 0; 1623 1641 } 1624 1642 … … 1627 1645 */ 1628 1646 static struct hda_pcm_stream alc880_pcm_analog_playback = { 1629 .substreams = 1,1630 .channels_min = 2,1631 .channels_max = 8,1632 /* NID is set in alc_build_pcms */1633 .ops = {1634 .open = alc880_playback_pcm_open,1635 .prepare = alc880_playback_pcm_prepare,1636 .cleanup = alc880_playback_pcm_cleanup1637 },1647 .substreams = 1, 1648 .channels_min = 2, 1649 .channels_max = 8, 1650 /* NID is set in alc_build_pcms */ 1651 .ops = { 1652 .open = alc880_playback_pcm_open, 1653 .prepare = alc880_playback_pcm_prepare, 1654 .cleanup = alc880_playback_pcm_cleanup 1655 }, 1638 1656 }; 1639 1657 1640 1658 static struct hda_pcm_stream alc880_pcm_analog_capture = { 1641 .substreams = 2,1642 .channels_min = 2,1643 .channels_max = 2,1644 /* NID is set in alc_build_pcms */1645 .ops = {1646 .prepare = alc880_capture_pcm_prepare,1647 .cleanup = alc880_capture_pcm_cleanup1648 },1659 .substreams = 2, 1660 .channels_min = 2, 1661 .channels_max = 2, 1662 /* NID is set in alc_build_pcms */ 1663 .ops = { 1664 .prepare = alc880_capture_pcm_prepare, 1665 .cleanup = alc880_capture_pcm_cleanup 1666 }, 1649 1667 }; 1650 1668 1651 1669 static struct hda_pcm_stream alc880_pcm_digital_playback = { 1652 .substreams = 1,1653 .channels_min = 2,1654 .channels_max = 2,1655 /* NID is set in alc_build_pcms */1656 .ops = {1657 .open = alc880_dig_playback_pcm_open,1658 .close = alc880_dig_playback_pcm_close1659 },1670 .substreams = 1, 1671 .channels_min = 2, 1672 .channels_max = 2, 1673 /* NID is set in alc_build_pcms */ 1674 .ops = { 1675 .open = alc880_dig_playback_pcm_open, 1676 .close = alc880_dig_playback_pcm_close 1677 }, 1660 1678 }; 1661 1679 1662 1680 static struct hda_pcm_stream alc880_pcm_digital_capture = { 1663 .substreams = 1,1664 .channels_min = 2,1665 .channels_max = 2,1666 /* NID is set in alc_build_pcms */1681 .substreams = 1, 1682 .channels_min = 2, 1683 .channels_max = 2, 1684 /* NID is set in alc_build_pcms */ 1667 1685 }; 1668 1686 1669 1687 /* Used by alc_build_pcms to flag that a PCM has no playback stream */ 1670 1688 static struct hda_pcm_stream alc_pcm_null_playback = { 1671 .substreams = 0,1672 .channels_min = 0,1673 .channels_max = 0,1689 .substreams = 0, 1690 .channels_min = 0, 1691 .channels_max = 0, 1674 1692 }; 1675 1693 1676 1694 static int alc_build_pcms(struct hda_codec *codec) 1677 1695 { 1678 struct alc_spec *spec = codec->spec;1679 struct hda_pcm *info = spec->pcm_rec;1680 int i;1681 1682 codec->num_pcms = 1;1683 codec->pcm_info = info;1684 1685 info->name = spec->stream_name_analog;1686 if (spec->stream_analog_playback) {1687 snd_assert(spec->multiout.dac_nids, return -EINVAL);1688 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);1689 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];1690 }1691 if (spec->stream_analog_capture) {1692 snd_assert(spec->adc_nids, return -EINVAL);1693 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);1694 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];1695 }1696 1697 if (spec->channel_mode) {1698 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;1699 for (i = 0; i < spec->num_channel_mode; i++) {1700 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {1701 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;1702 }1703 }1704 }1705 1706 /* If the use of more than one ADC is requested for the current1707 * model, configure a second analog capture-only PCM.1708 */1709 if (spec->num_adc_nids > 1) {1710 codec->num_pcms++;1711 info++;1712 info->name = spec->stream_name_analog;1713 /* No playback stream for second PCM */1714 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = alc_pcm_null_playback;1715 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;1716 if (spec->stream_analog_capture) {1717 snd_assert(spec->adc_nids, return -EINVAL);1718 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);1719 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[1];1720 }1721 }1722 1723 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {1724 codec->num_pcms++;1725 info++;1726 info->name = spec->stream_name_digital;1727 if (spec->multiout.dig_out_nid &&1728 spec->stream_digital_playback) {1729 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);1730 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;1731 }1732 if (spec->dig_in_nid &&1733 spec->stream_digital_capture) {1734 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);1735 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;1736 }1737 }1738 1739 return 0;1696 struct alc_spec *spec = codec->spec; 1697 struct hda_pcm *info = spec->pcm_rec; 1698 int i; 1699 1700 codec->num_pcms = 1; 1701 codec->pcm_info = info; 1702 1703 info->name = spec->stream_name_analog; 1704 if (spec->stream_analog_playback) { 1705 snd_assert(spec->multiout.dac_nids, return -EINVAL); 1706 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback); 1707 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0]; 1708 } 1709 if (spec->stream_analog_capture) { 1710 snd_assert(spec->adc_nids, return -EINVAL); 1711 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture); 1712 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0]; 1713 } 1714 1715 if (spec->channel_mode) { 1716 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0; 1717 for (i = 0; i < spec->num_channel_mode; i++) { 1718 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) { 1719 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels; 1720 } 1721 } 1722 } 1723 1724 /* If the use of more than one ADC is requested for the current 1725 * model, configure a second analog capture-only PCM. 1726 */ 1727 if (spec->num_adc_nids > 1) { 1728 codec->num_pcms++; 1729 info++; 1730 info->name = spec->stream_name_analog; 1731 /* No playback stream for second PCM */ 1732 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = alc_pcm_null_playback; 1733 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0; 1734 if (spec->stream_analog_capture) { 1735 snd_assert(spec->adc_nids, return -EINVAL); 1736 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture); 1737 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[1]; 1738 } 1739 } 1740 1741 if (spec->multiout.dig_out_nid || spec->dig_in_nid) { 1742 codec->num_pcms++; 1743 info++; 1744 info->name = spec->stream_name_digital; 1745 if (spec->multiout.dig_out_nid && 1746 spec->stream_digital_playback) { 1747 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback); 1748 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid; 1749 } 1750 if (spec->dig_in_nid && 1751 spec->stream_digital_capture) { 1752 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture); 1753 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid; 1754 } 1755 } 1756 1757 return 0; 1740 1758 } 1741 1759 1742 1760 static void alc_free(struct hda_codec *codec) 1743 1761 { 1744 struct alc_spec *spec = codec->spec;1745 unsigned int i;1746 1747 if (! spec)1748 return;1749 1750 if (spec->kctl_alloc) {1751 for (i = 0; i < spec->num_kctl_used; i++)1752 kfree(spec->kctl_alloc[i].name);1753 kfree(spec->kctl_alloc);1754 }1755 kfree(spec);1762 struct alc_spec *spec = codec->spec; 1763 unsigned int i; 1764 1765 if (! spec) 1766 return; 1767 1768 if (spec->kctl_alloc) { 1769 for (i = 0; i < spec->num_kctl_used; i++) 1770 kfree(spec->kctl_alloc[i].name); 1771 kfree(spec->kctl_alloc); 1772 } 1773 kfree(spec); 1756 1774 } 1757 1775 … … 1759 1777 */ 1760 1778 static struct hda_codec_ops alc_patch_ops = { 1761 .build_controls = alc_build_controls,1762 .build_pcms = alc_build_pcms,1763 .init = alc_init,1764 .free = alc_free,1765 .unsol_event = alc_unsol_event,1779 .build_controls = alc_build_controls, 1780 .build_pcms = alc_build_pcms, 1781 .init = alc_init, 1782 .free = alc_free, 1783 .unsol_event = alc_unsol_event, 1766 1784 #ifdef CONFIG_PM 1767 .resume = alc_resume,1785 .resume = alc_resume, 1768 1786 #endif 1769 1787 }; … … 1778 1796 #ifdef CONFIG_SND_DEBUG 1779 1797 static hda_nid_t alc880_test_dac_nids[4] = { 1780 0x02, 0x03, 0x04, 0x051798 0x02, 0x03, 0x04, 0x05 1781 1799 }; 1782 1800 1783 1801 static struct hda_input_mux alc880_test_capture_source = { 1784 .num_items = 7,1785 .items = {1786 { "In-1", 0x0 },1787 { "In-2", 0x1 },1788 { "In-3", 0x2 },1789 { "In-4", 0x3 },1790 { "CD", 0x4 },1791 { "Front", 0x5 },1792 { "Surround", 0x6 },1793 },1802 .num_items = 7, 1803 .items = { 1804 { "In-1", 0x0 }, 1805 { "In-2", 0x1 }, 1806 { "In-3", 0x2 }, 1807 { "In-4", 0x3 }, 1808 { "CD", 0x4 }, 1809 { "Front", 0x5 }, 1810 { "Surround", 0x6 }, 1811 }, 1794 1812 }; 1795 1813 1796 1814 static struct hda_channel_mode alc880_test_modes[4] = { 1797 { 2, NULL },1798 { 4, NULL },1799 { 6, NULL },1800 { 8, NULL },1815 { 2, NULL }, 1816 { 4, NULL }, 1817 { 6, NULL }, 1818 { 8, NULL }, 1801 1819 }; 1802 1820 1803 1821 static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 1804 1822 { 1805 static char *texts[] = {1806 "N/A", "Line Out", "HP Out",1807 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"1808 };1809 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;1810 uinfo->count = 1;1811 uinfo->value.enumerated.items = 8;1812 if (uinfo->value.enumerated.item >= 8)1813 uinfo->value.enumerated.item = 7;1814 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);1815 return 0;1823 static char *texts[] = { 1824 "N/A", "Line Out", "HP Out", 1825 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%" 1826 }; 1827 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 1828 uinfo->count = 1; 1829 uinfo->value.enumerated.items = 8; 1830 if (uinfo->value.enumerated.item >= 8) 1831 uinfo->value.enumerated.item = 7; 1832 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); 1833 return 0; 1816 1834 } 1817 1835 1818 1836 static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 1819 1837 { 1820 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);1821 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;1822 unsigned int pin_ctl, item = 0;1823 1824 pin_ctl = snd_hda_codec_read(codec, nid, 0,1825 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);1826 if (pin_ctl & AC_PINCTL_OUT_EN) {1827 if (pin_ctl & AC_PINCTL_HP_EN)1828 item = 2;1829 else1830 item = 1;1831 } else if (pin_ctl & AC_PINCTL_IN_EN) {1832 switch (pin_ctl & AC_PINCTL_VREFEN) {1833 case AC_PINCTL_VREF_HIZ: item = 3; break;1834 case AC_PINCTL_VREF_50: item = 4; break;1835 case AC_PINCTL_VREF_GRD: item = 5; break;1836 case AC_PINCTL_VREF_80: item = 6; break;1837 case AC_PINCTL_VREF_100: item = 7; break;1838 }1839 }1840 ucontrol->value.enumerated.item[0] = item;1841 return 0;1838 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1839 hda_nid_t nid = (hda_nid_t)kcontrol->private_value; 1840 unsigned int pin_ctl, item = 0; 1841 1842 pin_ctl = snd_hda_codec_read(codec, nid, 0, 1843 AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 1844 if (pin_ctl & AC_PINCTL_OUT_EN) { 1845 if (pin_ctl & AC_PINCTL_HP_EN) 1846 item = 2; 1847 else 1848 item = 1; 1849 } else if (pin_ctl & AC_PINCTL_IN_EN) { 1850 switch (pin_ctl & AC_PINCTL_VREFEN) { 1851 case AC_PINCTL_VREF_HIZ: item = 3; break; 1852 case AC_PINCTL_VREF_50: item = 4; break; 1853 case AC_PINCTL_VREF_GRD: item = 5; break; 1854 case AC_PINCTL_VREF_80: item = 6; break; 1855 case AC_PINCTL_VREF_100: item = 7; break; 1856 } 1857 } 1858 ucontrol->value.enumerated.item[0] = item; 1859 return 0; 1842 1860 } 1843 1861 1844 1862 static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 1845 1863 { 1846 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);1847 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;1848 static unsigned int ctls[] = {1849 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,1850 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,1851 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,1852 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,1853 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,1854 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,1855 };1856 unsigned int old_ctl, new_ctl;1857 1858 old_ctl = snd_hda_codec_read(codec, nid, 0,1859 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);1860 new_ctl = ctls[ucontrol->value.enumerated.item[0]];1861 if (old_ctl != new_ctl) {1862 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, new_ctl);1863 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,1864 ucontrol->value.enumerated.item[0] >= 3 ? 0xb080 : 0xb000);1865 return 1;1866 }1867 return 0;1864 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1865 hda_nid_t nid = (hda_nid_t)kcontrol->private_value; 1866 static unsigned int ctls[] = { 1867 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN, 1868 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ, 1869 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50, 1870 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD, 1871 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80, 1872 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100, 1873 }; 1874 unsigned int old_ctl, new_ctl; 1875 1876 old_ctl = snd_hda_codec_read(codec, nid, 0, 1877 AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 1878 new_ctl = ctls[ucontrol->value.enumerated.item[0]]; 1879 if (old_ctl != new_ctl) { 1880 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, new_ctl); 1881 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 1882 ucontrol->value.enumerated.item[0] >= 3 ? 0xb080 : 0xb000); 1883 return 1; 1884 } 1885 return 0; 1868 1886 } 1869 1887 1870 1888 static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 1871 1889 { 1872 static char *texts[] = {1873 "Front", "Surround", "CLFE", "Side"1874 };1875 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;1876 uinfo->count = 1;1877 uinfo->value.enumerated.items = 4;1878 if (uinfo->value.enumerated.item >= 4)1879 uinfo->value.enumerated.item = 3;1880 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);1881 return 0;1890 static char *texts[] = { 1891 "Front", "Surround", "CLFE", "Side" 1892 }; 1893 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 1894 uinfo->count = 1; 1895 uinfo->value.enumerated.items = 4; 1896 if (uinfo->value.enumerated.item >= 4) 1897 uinfo->value.enumerated.item = 3; 1898 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); 1899 return 0; 1882 1900 } 1883 1901 1884 1902 static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 1885 1903 { 1886 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);1887 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;1888 unsigned int sel;1889 1890 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);1891 ucontrol->value.enumerated.item[0] = sel & 3;1892 return 0;1904 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1905 hda_nid_t nid = (hda_nid_t)kcontrol->private_value; 1906 unsigned int sel; 1907 1908 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0); 1909 ucontrol->value.enumerated.item[0] = sel & 3; 1910 return 0; 1893 1911 } 1894 1912 1895 1913 static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 1896 1914 { 1897 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);1898 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;1899 unsigned int sel;1900 1901 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;1902 if (ucontrol->value.enumerated.item[0] != sel) {1903 sel = ucontrol->value.enumerated.item[0] & 3;1904 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, sel);1905 return 1;1906 }1907 return 0;1915 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1916 hda_nid_t nid = (hda_nid_t)kcontrol->private_value; 1917 unsigned int sel; 1918 1919 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3; 1920 if (ucontrol->value.enumerated.item[0] != sel) { 1921 sel = ucontrol->value.enumerated.item[0] & 3; 1922 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, sel); 1923 return 1; 1924 } 1925 return 0; 1908 1926 } 1909 1927 1910 1928 #define PIN_CTL_TEST(xname,nid) { \ 1911 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \1912 .name = xname, \1913 .info = alc_test_pin_ctl_info, \1914 .get = alc_test_pin_ctl_get, \1915 .put = alc_test_pin_ctl_put, \1916 .private_value = nid \1917 }1929 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 1930 .name = xname, \ 1931 .info = alc_test_pin_ctl_info, \ 1932 .get = alc_test_pin_ctl_get, \ 1933 .put = alc_test_pin_ctl_put, \ 1934 .private_value = nid \ 1935 } 1918 1936 1919 1937 #define PIN_SRC_TEST(xname,nid) { \ 1920 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \1921 .name = xname, \1922 .info = alc_test_pin_src_info, \1923 .get = alc_test_pin_src_get, \1924 .put = alc_test_pin_src_put, \1925 .private_value = nid \1926 }1938 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 1939 .name = xname, \ 1940 .info = alc_test_pin_src_info, \ 1941 .get = alc_test_pin_src_get, \ 1942 .put = alc_test_pin_src_put, \ 1943 .private_value = nid \ 1944 } 1927 1945 1928 1946 static struct snd_kcontrol_new alc880_test_mixer[] = { 1929 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),1930 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),1931 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),1932 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),1933 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),1934 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),1935 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),1936 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),1937 PIN_CTL_TEST("Front Pin Mode", 0x14),1938 PIN_CTL_TEST("Surround Pin Mode", 0x15),1939 PIN_CTL_TEST("CLFE Pin Mode", 0x16),1940 PIN_CTL_TEST("Side Pin Mode", 0x17),1941 PIN_CTL_TEST("In-1 Pin Mode", 0x18),1942 PIN_CTL_TEST("In-2 Pin Mode", 0x19),1943 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),1944 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),1945 PIN_SRC_TEST("In-1 Pin Source", 0x18),1946 PIN_SRC_TEST("In-2 Pin Source", 0x19),1947 PIN_SRC_TEST("In-3 Pin Source", 0x1a),1948 PIN_SRC_TEST("In-4 Pin Source", 0x1b),1949 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),1950 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),1951 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),1952 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),1953 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),1954 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),1955 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),1956 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),1957 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),1958 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),1959 {1960 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,1961 .name = "Channel Mode",1962 .info = alc_ch_mode_info,1963 .get = alc_ch_mode_get,1964 .put = alc_ch_mode_put,1965 },1966 {0} /* end */1947 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1948 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 1949 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT), 1950 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 1951 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 1952 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 1953 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT), 1954 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 1955 PIN_CTL_TEST("Front Pin Mode", 0x14), 1956 PIN_CTL_TEST("Surround Pin Mode", 0x15), 1957 PIN_CTL_TEST("CLFE Pin Mode", 0x16), 1958 PIN_CTL_TEST("Side Pin Mode", 0x17), 1959 PIN_CTL_TEST("In-1 Pin Mode", 0x18), 1960 PIN_CTL_TEST("In-2 Pin Mode", 0x19), 1961 PIN_CTL_TEST("In-3 Pin Mode", 0x1a), 1962 PIN_CTL_TEST("In-4 Pin Mode", 0x1b), 1963 PIN_SRC_TEST("In-1 Pin Source", 0x18), 1964 PIN_SRC_TEST("In-2 Pin Source", 0x19), 1965 PIN_SRC_TEST("In-3 Pin Source", 0x1a), 1966 PIN_SRC_TEST("In-4 Pin Source", 0x1b), 1967 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT), 1968 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT), 1969 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT), 1970 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT), 1971 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT), 1972 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT), 1973 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT), 1974 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT), 1975 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT), 1976 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT), 1977 { 1978 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1979 .name = "Channel Mode", 1980 .info = alc_ch_mode_info, 1981 .get = alc_ch_mode_get, 1982 .put = alc_ch_mode_put, 1983 }, 1984 {0} /* end */ 1967 1985 }; 1968 1986 1969 1987 static struct hda_verb alc880_test_init_verbs[] = { 1970 /* Unmute inputs of 0x0c - 0x0f */1971 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},1972 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},1973 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},1974 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},1975 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},1976 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},1977 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},1978 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},1979 /* Vol output for 0x0c-0x0f */1980 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},1981 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},1982 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},1983 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},1984 /* Set output pins 0x14-0x17 */1985 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},1986 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},1987 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},1988 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},1989 /* Unmute output pins 0x14-0x17 */1990 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},1991 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},1992 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},1993 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},1994 /* Set input pins 0x18-0x1c */1995 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},1996 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},1997 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},1998 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},1999 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},2000 /* Mute input pins 0x18-0x1b */2001 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},2002 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},2003 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},2004 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},2005 /* ADC set up */2006 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},2007 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},2008 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},2009 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},2010 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},2011 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},2012 /* Analog input/passthru */2013 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},2014 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},2015 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},2016 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},2017 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},2018 {0}1988 /* Unmute inputs of 0x0c - 0x0f */ 1989 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1990 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 1991 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1992 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 1993 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1994 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 1995 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1996 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 1997 /* Vol output for 0x0c-0x0f */ 1998 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1999 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 2000 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 2001 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 2002 /* Set output pins 0x14-0x17 */ 2003 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2004 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2005 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2006 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2007 /* Unmute output pins 0x14-0x17 */ 2008 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2009 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2010 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2011 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2012 /* Set input pins 0x18-0x1c */ 2013 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2014 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2015 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2016 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2017 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2018 /* Mute input pins 0x18-0x1b */ 2019 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2020 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2021 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2022 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2023 /* ADC set up */ 2024 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2025 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 2026 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2027 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 2028 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2029 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 2030 /* Analog input/passthru */ 2031 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2032 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 2033 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 2034 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 2035 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 2036 {0} 2019 2037 }; 2020 2038 #endif … … 2024 2042 2025 2043 static struct hda_board_config alc880_cfg_tbl[] = { 2026 /* Back 3 jack, front 2 jack */ 2027 { .modelname = "3stack", .config = ALC880_3ST }, 2028 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe200, .config = ALC880_3ST }, 2029 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe201, .config = ALC880_3ST }, 2030 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe202, .config = ALC880_3ST }, 2031 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe203, .config = ALC880_3ST }, 2032 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe204, .config = ALC880_3ST }, 2033 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe205, .config = ALC880_3ST }, 2034 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe206, .config = ALC880_3ST }, 2035 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe207, .config = ALC880_3ST }, 2036 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe208, .config = ALC880_3ST }, 2037 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe209, .config = ALC880_3ST }, 2038 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20a, .config = ALC880_3ST }, 2039 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20b, .config = ALC880_3ST }, 2040 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20c, .config = ALC880_3ST }, 2041 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20d, .config = ALC880_3ST }, 2042 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20e, .config = ALC880_3ST }, 2043 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20f, .config = ALC880_3ST }, 2044 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe210, .config = ALC880_3ST }, 2045 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe211, .config = ALC880_3ST }, 2046 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe214, .config = ALC880_3ST }, 2047 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe302, .config = ALC880_3ST }, 2048 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe303, .config = ALC880_3ST }, 2049 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe304, .config = ALC880_3ST }, 2050 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe306, .config = ALC880_3ST }, 2051 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe307, .config = ALC880_3ST }, 2052 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe404, .config = ALC880_3ST }, 2053 { .pci_subvendor = 0x8086, .pci_subdevice = 0xa101, .config = ALC880_3ST }, 2054 { .pci_subvendor = 0x107b, .pci_subdevice = 0x3031, .config = ALC880_3ST }, 2055 { .pci_subvendor = 0x107b, .pci_subdevice = 0x4036, .config = ALC880_3ST }, 2056 { .pci_subvendor = 0x107b, .pci_subdevice = 0x4037, .config = ALC880_3ST }, 2057 { .pci_subvendor = 0x107b, .pci_subdevice = 0x4038, .config = ALC880_3ST }, 2058 { .pci_subvendor = 0x107b, .pci_subdevice = 0x4040, .config = ALC880_3ST }, 2059 { .pci_subvendor = 0x107b, .pci_subdevice = 0x4041, .config = ALC880_3ST }, 2060 /* TCL S700 */ 2061 { .pci_subvendor = 0x19db, .pci_subdevice = 0x4188, .config = ALC880_TCL_S700 }, 2062 2063 /* Back 3 jack, front 2 jack (Internal add Aux-In) */ 2064 { .pci_subvendor = 0x1025, .pci_subdevice = 0xe310, .config = ALC880_3ST }, 2065 { .pci_subvendor = 0x104d, .pci_subdevice = 0x81d6, .config = ALC880_3ST }, 2066 { .pci_subvendor = 0x104d, .pci_subdevice = 0x81a0, .config = ALC880_3ST }, 2067 2068 /* Back 3 jack plus 1 SPDIF out jack, front 2 jack */ 2069 { .modelname = "3stack-digout", .config = ALC880_3ST_DIG }, 2070 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe308, .config = ALC880_3ST_DIG }, 2071 { .pci_subvendor = 0x1025, .pci_subdevice = 0x0070, .config = ALC880_3ST_DIG }, 2072 /* Clevo m520G NB */ 2073 { .pci_subvendor = 0x1558, .pci_subdevice = 0x0520, .config = ALC880_CLEVO }, 2074 2075 /* Back 3 jack plus 1 SPDIF out jack, front 2 jack (Internal add Aux-In)*/ 2076 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe305, .config = ALC880_3ST_DIG }, 2077 { .pci_subvendor = 0x8086, .pci_subdevice = 0xd402, .config = ALC880_3ST_DIG }, 2078 { .pci_subvendor = 0x1025, .pci_subdevice = 0xe309, .config = ALC880_3ST_DIG }, 2079 2080 /* Back 5 jack, front 2 jack */ 2081 { .modelname = "5stack", .config = ALC880_5ST }, 2082 { .pci_subvendor = 0x107b, .pci_subdevice = 0x3033, .config = ALC880_5ST }, 2083 { .pci_subvendor = 0x107b, .pci_subdevice = 0x4039, .config = ALC880_5ST }, 2084 { .pci_subvendor = 0x107b, .pci_subdevice = 0x3032, .config = ALC880_5ST }, 2085 { .pci_subvendor = 0x103c, .pci_subdevice = 0x2a09, .config = ALC880_5ST }, 2086 { .pci_subvendor = 0x1043, .pci_subdevice = 0x814e, .config = ALC880_5ST }, 2087 2088 /* Back 5 jack plus 1 SPDIF out jack, front 2 jack */ 2089 { .modelname = "5stack-digout", .config = ALC880_5ST_DIG }, 2090 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe224, .config = ALC880_5ST_DIG }, 2091 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe400, .config = ALC880_5ST_DIG }, 2092 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe401, .config = ALC880_5ST_DIG }, 2093 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe402, .config = ALC880_5ST_DIG }, 2094 { .pci_subvendor = 0x8086, .pci_subdevice = 0xd400, .config = ALC880_5ST_DIG }, 2095 { .pci_subvendor = 0x8086, .pci_subdevice = 0xd401, .config = ALC880_5ST_DIG }, 2096 { .pci_subvendor = 0x8086, .pci_subdevice = 0xa100, .config = ALC880_5ST_DIG }, 2097 { .pci_subvendor = 0x1565, .pci_subdevice = 0x8202, .config = ALC880_5ST_DIG }, 2098 { .pci_subvendor = 0x1019, .pci_subdevice = 0xa880, .config = ALC880_5ST_DIG }, 2099 { .pci_subvendor = 0xa0a0, .pci_subdevice = 0x0560, .config = ALC880_5ST_DIG }, /* Aopen i915GMm-HFS */ 2100 /* { .pci_subvendor = 0x1019, .pci_subdevice = 0xa884, .config = ALC880_5ST_DIG }, */ /* conflict with 6stack */ 2101 { .pci_subvendor = 0x1695, .pci_subdevice = 0x400d, .config = ALC880_5ST_DIG }, 2102 /* note subvendor = 0 below */ 2103 /* { .pci_subvendor = 0x0000, .pci_subdevice = 0x8086, .config = ALC880_5ST_DIG }, */ 2104 2105 { .modelname = "w810", .config = ALC880_W810 }, 2106 { .pci_subvendor = 0x161f, .pci_subdevice = 0x203d, .config = ALC880_W810 }, 2107 2108 { .modelname = "z71v", .config = ALC880_Z71V }, 2109 { .pci_subvendor = 0x1043, .pci_subdevice = 0x1964, .config = ALC880_Z71V }, 2110 2111 { .modelname = "6stack", .config = ALC880_6ST }, 2112 { .pci_subvendor = 0x1043, .pci_subdevice = 0x8196, .config = ALC880_6ST }, /* ASUS P5GD1-HVM */ 2113 { .pci_subvendor = 0x1043, .pci_subdevice = 0x81b4, .config = ALC880_6ST }, 2114 { .pci_subvendor = 0x1019, .pci_subdevice = 0xa884, .config = ALC880_6ST }, /* Acer APFV */ 2115 { .pci_subvendor = 0x1458, .pci_subdevice = 0xa102, .config = ALC880_6ST }, /* Gigabyte K8N51 */ 2116 2117 { .modelname = "6stack-digout", .config = ALC880_6ST_DIG }, 2118 { .pci_subvendor = 0x2668, .pci_subdevice = 0x8086, .config = ALC880_6ST_DIG }, 2119 { .pci_subvendor = 0x8086, .pci_subdevice = 0x2668, .config = ALC880_6ST_DIG }, 2120 { .pci_subvendor = 0x1462, .pci_subdevice = 0x1150, .config = ALC880_6ST_DIG }, 2121 { .pci_subvendor = 0xe803, .pci_subdevice = 0x1019, .config = ALC880_6ST_DIG }, 2122 { .pci_subvendor = 0x1039, .pci_subdevice = 0x1234, .config = ALC880_6ST_DIG }, 2123 { .pci_subvendor = 0x1025, .pci_subdevice = 0x0077, .config = ALC880_6ST_DIG }, 2124 { .pci_subvendor = 0x1025, .pci_subdevice = 0x0078, .config = ALC880_6ST_DIG }, 2125 { .pci_subvendor = 0x1025, .pci_subdevice = 0x0087, .config = ALC880_6ST_DIG }, 2126 { .pci_subvendor = 0x1297, .pci_subdevice = 0xc790, .config = ALC880_6ST_DIG }, /* Shuttle ST20G5 */ 2127 { .pci_subvendor = 0x1509, .pci_subdevice = 0x925d, .config = ALC880_6ST_DIG }, /* FIC P4M-915GD1 */ 2128 2129 { .modelname = "asus", .config = ALC880_ASUS }, 2130 { .pci_subvendor = 0x1043, .pci_subdevice = 0x1964, .config = ALC880_ASUS_DIG }, 2131 { .pci_subvendor = 0x1043, .pci_subdevice = 0x1973, .config = ALC880_ASUS_DIG }, 2132 { .pci_subvendor = 0x1043, .pci_subdevice = 0x19b3, .config = ALC880_ASUS_DIG }, 2133 { .pci_subvendor = 0x1043, .pci_subdevice = 0x1113, .config = ALC880_ASUS_DIG }, 2134 { .pci_subvendor = 0x1043, .pci_subdevice = 0x1173, .config = ALC880_ASUS_DIG }, 2135 { .pci_subvendor = 0x1043, .pci_subdevice = 0x1993, .config = ALC880_ASUS }, 2136 { .pci_subvendor = 0x1043, .pci_subdevice = 0x10c3, .config = ALC880_ASUS_DIG }, 2137 { .pci_subvendor = 0x1043, .pci_subdevice = 0x1133, .config = ALC880_ASUS }, 2138 { .pci_subvendor = 0x1043, .pci_subdevice = 0x1123, .config = ALC880_ASUS_DIG }, 2139 { .pci_subvendor = 0x1043, .pci_subdevice = 0x1143, .config = ALC880_ASUS }, 2140 { .pci_subvendor = 0x1043, .pci_subdevice = 0x10b3, .config = ALC880_ASUS_W1V }, 2141 { .pci_subvendor = 0x1043, .pci_subdevice = 0x8181, .config = ALC880_ASUS_DIG }, /* ASUS P4GPL-X */ 2142 { .pci_subvendor = 0x1558, .pci_subdevice = 0x5401, .config = ALC880_ASUS_DIG2 }, 2143 2144 { .modelname = "uniwill", .config = ALC880_UNIWILL_DIG }, 2145 { .pci_subvendor = 0x1584, .pci_subdevice = 0x9050, .config = ALC880_UNIWILL_DIG }, 2146 2147 { .modelname = "F1734", .config = ALC880_F1734 }, 2148 { .pci_subvendor = 0x1734, .pci_subdevice = 0x107c, .config = ALC880_F1734 }, 2149 { .pci_subvendor = 0x1584, .pci_subdevice = 0x9054, .config = ALC880_F1734 }, 2150 2151 { .modelname = "lg", .config = ALC880_LG }, 2152 { .pci_subvendor = 0x1854, .pci_subdevice = 0x003b, .config = ALC880_LG }, 2153 { .modelname = "lg-lw", .config = ALC880_LG_LW }, 2154 { .pci_subvendor = 0x1854, .pci_subdevice = 0x0018, .config = ALC880_LG_LW }, 2044 /* Back 3 jack, front 2 jack */ 2045 { .modelname = "3stack", .config = ALC880_3ST }, 2046 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe200, .config = ALC880_3ST }, 2047 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe201, .config = ALC880_3ST }, 2048 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe202, .config = ALC880_3ST }, 2049 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe203, .config = ALC880_3ST }, 2050 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe204, .config = ALC880_3ST }, 2051 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe205, .config = ALC880_3ST }, 2052 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe206, .config = ALC880_3ST }, 2053 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe207, .config = ALC880_3ST }, 2054 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe208, .config = ALC880_3ST }, 2055 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe209, .config = ALC880_3ST }, 2056 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20a, .config = ALC880_3ST }, 2057 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20b, .config = ALC880_3ST }, 2058 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20c, .config = ALC880_3ST }, 2059 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20d, .config = ALC880_3ST }, 2060 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20e, .config = ALC880_3ST }, 2061 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20f, .config = ALC880_3ST }, 2062 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe210, .config = ALC880_3ST }, 2063 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe211, .config = ALC880_3ST }, 2064 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe214, .config = ALC880_3ST }, 2065 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe302, .config = ALC880_3ST }, 2066 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe303, .config = ALC880_3ST }, 2067 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe304, .config = ALC880_3ST }, 2068 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe306, .config = ALC880_3ST }, 2069 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe307, .config = ALC880_3ST }, 2070 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe404, .config = ALC880_3ST }, 2071 { .pci_subvendor = 0x8086, .pci_subdevice = 0xa101, .config = ALC880_3ST }, 2072 { .pci_subvendor = 0x107b, .pci_subdevice = 0x3031, .config = ALC880_3ST }, 2073 { .pci_subvendor = 0x107b, .pci_subdevice = 0x4036, .config = ALC880_3ST }, 2074 { .pci_subvendor = 0x107b, .pci_subdevice = 0x4037, .config = ALC880_3ST }, 2075 { .pci_subvendor = 0x107b, .pci_subdevice = 0x4038, .config = ALC880_3ST }, 2076 { .pci_subvendor = 0x107b, .pci_subdevice = 0x4040, .config = ALC880_3ST }, 2077 { .pci_subvendor = 0x107b, .pci_subdevice = 0x4041, .config = ALC880_3ST }, 2078 /* TCL S700 */ 2079 { .pci_subvendor = 0x19db, .pci_subdevice = 0x4188, .config = ALC880_TCL_S700 }, 2080 2081 /* Back 3 jack, front 2 jack (Internal add Aux-In) */ 2082 { .pci_subvendor = 0x1025, .pci_subdevice = 0xe310, .config = ALC880_3ST }, 2083 { .pci_subvendor = 0x104d, .pci_subdevice = 0x81d6, .config = ALC880_3ST }, 2084 { .pci_subvendor = 0x104d, .pci_subdevice = 0x81a0, .config = ALC880_3ST }, 2085 2086 /* Back 3 jack plus 1 SPDIF out jack, front 2 jack */ 2087 { .modelname = "3stack-digout", .config = ALC880_3ST_DIG }, 2088 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe308, .config = ALC880_3ST_DIG }, 2089 { .pci_subvendor = 0x1025, .pci_subdevice = 0x0070, .config = ALC880_3ST_DIG }, 2090 /* Clevo m520G NB */ 2091 { .pci_subvendor = 0x1558, .pci_subdevice = 0x0520, .config = ALC880_CLEVO }, 2092 2093 /* Back 3 jack plus 1 SPDIF out jack, front 2 jack (Internal add Aux-In)*/ 2094 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe305, .config = ALC880_3ST_DIG }, 2095 { .pci_subvendor = 0x8086, .pci_subdevice = 0xd402, .config = ALC880_3ST_DIG }, 2096 { .pci_subvendor = 0x1025, .pci_subdevice = 0xe309, .config = ALC880_3ST_DIG }, 2097 2098 /* Back 5 jack, front 2 jack */ 2099 { .modelname = "5stack", .config = ALC880_5ST }, 2100 { .pci_subvendor = 0x107b, .pci_subdevice = 0x3033, .config = ALC880_5ST }, 2101 { .pci_subvendor = 0x107b, .pci_subdevice = 0x4039, .config = ALC880_5ST }, 2102 { .pci_subvendor = 0x107b, .pci_subdevice = 0x3032, .config = ALC880_5ST }, 2103 { .pci_subvendor = 0x103c, .pci_subdevice = 0x2a09, .config = ALC880_5ST }, 2104 { .pci_subvendor = 0x1043, .pci_subdevice = 0x814e, .config = ALC880_5ST }, 2105 2106 /* Back 5 jack plus 1 SPDIF out jack, front 2 jack */ 2107 { .modelname = "5stack-digout", .config = ALC880_5ST_DIG }, 2108 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe224, .config = ALC880_5ST_DIG }, 2109 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe400, .config = ALC880_5ST_DIG }, 2110 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe401, .config = ALC880_5ST_DIG }, 2111 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe402, .config = ALC880_5ST_DIG }, 2112 { .pci_subvendor = 0x8086, .pci_subdevice = 0xd400, .config = ALC880_5ST_DIG }, 2113 { .pci_subvendor = 0x8086, .pci_subdevice = 0xd401, .config = ALC880_5ST_DIG }, 2114 { .pci_subvendor = 0x8086, .pci_subdevice = 0xa100, .config = ALC880_5ST_DIG }, 2115 { .pci_subvendor = 0x1565, .pci_subdevice = 0x8202, .config = ALC880_5ST_DIG }, 2116 { .pci_subvendor = 0x1019, .pci_subdevice = 0xa880, .config = ALC880_5ST_DIG }, 2117 { .pci_subvendor = 0xa0a0, .pci_subdevice = 0x0560, .config = ALC880_5ST_DIG }, /* Aopen i915GMm-HFS */ 2118 /* { .pci_subvendor = 0x1019, .pci_subdevice = 0xa884, .config = ALC880_5ST_DIG }, */ /* conflict with 6stack */ 2119 { .pci_subvendor = 0x1695, .pci_subdevice = 0x400d, .config = ALC880_5ST_DIG }, 2120 /* note subvendor = 0 below */ 2121 /* { .pci_subvendor = 0x0000, .pci_subdevice = 0x8086, .config = ALC880_5ST_DIG }, */ 2122 2123 { .modelname = "w810", .config = ALC880_W810 }, 2124 { .pci_subvendor = 0x161f, .pci_subdevice = 0x203d, .config = ALC880_W810 }, 2125 2126 { .modelname = "z71v", .config = ALC880_Z71V }, 2127 { .pci_subvendor = 0x1043, .pci_subdevice = 0x1964, .config = ALC880_Z71V }, 2128 2129 { .modelname = "6stack", .config = ALC880_6ST }, 2130 { .pci_subvendor = 0x1043, .pci_subdevice = 0x8196, .config = ALC880_6ST }, /* ASUS P5GD1-HVM */ 2131 { .pci_subvendor = 0x1043, .pci_subdevice = 0x81b4, .config = ALC880_6ST }, 2132 { .pci_subvendor = 0x1019, .pci_subdevice = 0xa884, .config = ALC880_6ST }, /* Acer APFV */ 2133 { .pci_subvendor = 0x1458, .pci_subdevice = 0xa102, .config = ALC880_6ST }, /* Gigabyte K8N51 */ 2134 2135 { .modelname = "6stack-digout", .config = ALC880_6ST_DIG }, 2136 { .pci_subvendor = 0x2668, .pci_subdevice = 0x8086, .config = ALC880_6ST_DIG }, 2137 { .pci_subvendor = 0x8086, .pci_subdevice = 0x2668, .config = ALC880_6ST_DIG }, 2138 { .pci_subvendor = 0x1462, .pci_subdevice = 0x1150, .config = ALC880_6ST_DIG }, 2139 { .pci_subvendor = 0xe803, .pci_subdevice = 0x1019, .config = ALC880_6ST_DIG }, 2140 { .pci_subvendor = 0x1039, .pci_subdevice = 0x1234, .config = ALC880_6ST_DIG }, 2141 { .pci_subvendor = 0x1025, .pci_subdevice = 0x0077, .config = ALC880_6ST_DIG }, 2142 { .pci_subvendor = 0x1025, .pci_subdevice = 0x0078, .config = ALC880_6ST_DIG }, 2143 { .pci_subvendor = 0x1025, .pci_subdevice = 0x0087, .config = ALC880_6ST_DIG }, 2144 { .pci_subvendor = 0x1297, .pci_subdevice = 0xc790, .config = ALC880_6ST_DIG }, /* Shuttle ST20G5 */ 2145 { .pci_subvendor = 0x1509, .pci_subdevice = 0x925d, .config = ALC880_6ST_DIG }, /* FIC P4M-915GD1 */ 2146 2147 { .modelname = "asus", .config = ALC880_ASUS }, 2148 { .pci_subvendor = 0x1043, .pci_subdevice = 0x1964, .config = ALC880_ASUS_DIG }, 2149 { .pci_subvendor = 0x1043, .pci_subdevice = 0x1973, .config = ALC880_ASUS_DIG }, 2150 { .pci_subvendor = 0x1043, .pci_subdevice = 0x19b3, .config = ALC880_ASUS_DIG }, 2151 { .pci_subvendor = 0x1043, .pci_subdevice = 0x1113, .config = ALC880_ASUS_DIG }, 2152 { .pci_subvendor = 0x1043, .pci_subdevice = 0x1173, .config = ALC880_ASUS_DIG }, 2153 { .pci_subvendor = 0x1043, .pci_subdevice = 0x1993, .config = ALC880_ASUS }, 2154 { .pci_subvendor = 0x1043, .pci_subdevice = 0x10c3, .config = ALC880_ASUS_DIG }, 2155 { .pci_subvendor = 0x1043, .pci_subdevice = 0x1133, .config = ALC880_ASUS }, 2156 { .pci_subvendor = 0x1043, .pci_subdevice = 0x1123, .config = ALC880_ASUS_DIG }, 2157 { .pci_subvendor = 0x1043, .pci_subdevice = 0x1143, .config = ALC880_ASUS }, 2158 { .pci_subvendor = 0x1043, .pci_subdevice = 0x10b3, .config = ALC880_ASUS_W1V }, 2159 { .pci_subvendor = 0x1043, .pci_subdevice = 0x8181, .config = ALC880_ASUS_DIG }, /* ASUS P4GPL-X */ 2160 { .pci_subvendor = 0x1558, .pci_subdevice = 0x5401, .config = ALC880_ASUS_DIG2 }, 2161 2162 { .modelname = "uniwill", .config = ALC880_UNIWILL_DIG }, 2163 { .pci_subvendor = 0x1584, .pci_subdevice = 0x9050, .config = ALC880_UNIWILL_DIG }, 2164 2165 { .modelname = "F1734", .config = ALC880_F1734 }, 2166 { .pci_subvendor = 0x1734, .pci_subdevice = 0x107c, .config = ALC880_F1734 }, 2167 { .pci_subvendor = 0x1584, .pci_subdevice = 0x9054, .config = ALC880_F1734 }, 2168 2169 { .modelname = "lg", .config = ALC880_LG }, 2170 { .pci_subvendor = 0x1854, .pci_subdevice = 0x003b, .config = ALC880_LG }, 2171 { .pci_subvendor = 0x1854, .pci_subdevice = 0x0068, .config = ALC880_LG }, 2172 { .modelname = "lg-lw", .config = ALC880_LG_LW }, 2173 { .pci_subvendor = 0x1854, .pci_subdevice = 0x0018, .config = ALC880_LG_LW }, 2155 2174 2156 2175 #ifdef CONFIG_SND_DEBUG 2157 { .modelname = "test", .config = ALC880_TEST },2176 { .modelname = "test", .config = ALC880_TEST }, 2158 2177 #endif 2159 { .modelname = "auto", .config = ALC880_AUTO },2160 2161 {0}2178 { .modelname = "auto", .config = ALC880_AUTO }, 2179 2180 {0} 2162 2181 }; 2163 2182 … … 2166 2185 */ 2167 2186 static struct alc_config_preset alc880_presets[] = { 2168 [ALC880_3ST] = {2169 .mixers = { alc880_three_stack_mixer },2170 .init_verbs = { alc880_volume_init_verbs, alc880_pin_3stack_init_verbs },2171 .num_dacs = ARRAY_SIZE(alc880_dac_nids),2172 .dac_nids = alc880_dac_nids,2173 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),2174 .channel_mode = alc880_threestack_modes,2175 .input_mux = &alc880_capture_source,2176 },2177 [ALC880_3ST_DIG] = {2178 .mixers = { alc880_three_stack_mixer },2179 .init_verbs = { alc880_volume_init_verbs, alc880_pin_3stack_init_verbs },2180 .num_dacs = ARRAY_SIZE(alc880_dac_nids),2181 .dac_nids = alc880_dac_nids,2182 .dig_out_nid = ALC880_DIGOUT_NID,2183 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),2184 .channel_mode = alc880_threestack_modes,2185 .input_mux = &alc880_capture_source,2186 },2187 [ALC880_TCL_S700] = {2188 .mixers = { alc880_tcl_s700_mixer },2189 .init_verbs = { alc880_volume_init_verbs,2190 alc880_pin_tcl_S700_init_verbs,2191 alc880_gpio2_init_verbs },2192 .num_dacs = ARRAY_SIZE(alc880_dac_nids),2193 .dac_nids = alc880_dac_nids,2194 .hp_nid = 0x03,2195 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),2196 .channel_mode = alc880_2_jack_modes,2197 .input_mux = &alc880_capture_source,2198 },2199 [ALC880_5ST] = {2200 .mixers = { alc880_three_stack_mixer, alc880_five_stack_mixer},2201 .init_verbs = { alc880_volume_init_verbs, alc880_pin_5stack_init_verbs },2202 .num_dacs = ARRAY_SIZE(alc880_dac_nids),2203 .dac_nids = alc880_dac_nids,2204 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),2205 .channel_mode = alc880_fivestack_modes,2206 .input_mux = &alc880_capture_source,2207 },2208 [ALC880_5ST_DIG] = {2209 .mixers = { alc880_three_stack_mixer, alc880_five_stack_mixer },2210 .init_verbs = { alc880_volume_init_verbs, alc880_pin_5stack_init_verbs },2211 .num_dacs = ARRAY_SIZE(alc880_dac_nids),2212 .dac_nids = alc880_dac_nids,2213 .dig_out_nid = ALC880_DIGOUT_NID,2214 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),2215 .channel_mode = alc880_fivestack_modes,2216 .input_mux = &alc880_capture_source,2217 },2218 [ALC880_6ST] = {2219 .mixers = { alc880_six_stack_mixer },2220 .init_verbs = { alc880_volume_init_verbs, alc880_pin_6stack_init_verbs },2221 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),2222 .dac_nids = alc880_6st_dac_nids,2223 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),2224 .channel_mode = alc880_sixstack_modes,2225 .input_mux = &alc880_6stack_capture_source,2226 },2227 [ALC880_6ST_DIG] = {2228 .mixers = { alc880_six_stack_mixer },2229 .init_verbs = { alc880_volume_init_verbs, alc880_pin_6stack_init_verbs },2230 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),2231 .dac_nids = alc880_6st_dac_nids,2232 .dig_out_nid = ALC880_DIGOUT_NID,2233 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),2234 .channel_mode = alc880_sixstack_modes,2235 .input_mux = &alc880_6stack_capture_source,2236 },2237 [ALC880_W810] = {2238 .mixers = { alc880_w810_base_mixer },2239 .init_verbs = { alc880_volume_init_verbs, alc880_pin_w810_init_verbs,2240 alc880_gpio2_init_verbs },2241 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),2242 .dac_nids = alc880_w810_dac_nids,2243 .dig_out_nid = ALC880_DIGOUT_NID,2244 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),2245 .channel_mode = alc880_w810_modes,2246 .input_mux = &alc880_capture_source,2247 },2248 [ALC880_Z71V] = {2249 .mixers = { alc880_z71v_mixer },2250 .init_verbs = { alc880_volume_init_verbs, alc880_pin_z71v_init_verbs },2251 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),2252 .dac_nids = alc880_z71v_dac_nids,2253 .dig_out_nid = ALC880_DIGOUT_NID,2254 .hp_nid = 0x03,2255 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),2256 .channel_mode = alc880_2_jack_modes,2257 .input_mux = &alc880_capture_source,2258 },2259 [ALC880_F1734] = {2260 .mixers = { alc880_f1734_mixer },2261 .init_verbs = { alc880_volume_init_verbs, alc880_pin_f1734_init_verbs },2262 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),2263 .dac_nids = alc880_f1734_dac_nids,2264 .hp_nid = 0x02,2265 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),2266 .channel_mode = alc880_2_jack_modes,2267 .input_mux = &alc880_capture_source,2268 },2269 [ALC880_ASUS] = {2270 .mixers = { alc880_asus_mixer },2271 .init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs,2272 alc880_gpio1_init_verbs },2273 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),2274 .dac_nids = alc880_asus_dac_nids,2275 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),2276 .channel_mode = alc880_asus_modes,2277 .input_mux = &alc880_capture_source,2278 },2279 [ALC880_ASUS_DIG] = {2280 .mixers = { alc880_asus_mixer },2281 .init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs,2282 alc880_gpio1_init_verbs },2283 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),2284 .dac_nids = alc880_asus_dac_nids,2285 .dig_out_nid = ALC880_DIGOUT_NID,2286 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),2287 .channel_mode = alc880_asus_modes,2288 .input_mux = &alc880_capture_source,2289 },2290 [ALC880_ASUS_DIG2] = {2291 .mixers = { alc880_asus_mixer },2292 .init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs,2293 alc880_gpio2_init_verbs }, /* use GPIO2 */2294 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),2295 .dac_nids = alc880_asus_dac_nids,2296 .dig_out_nid = ALC880_DIGOUT_NID,2297 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),2298 .channel_mode = alc880_asus_modes,2299 .input_mux = &alc880_capture_source,2300 },2301 [ALC880_ASUS_W1V] = {2302 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },2303 .init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs,2304 alc880_gpio1_init_verbs },2305 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),2306 .dac_nids = alc880_asus_dac_nids,2307 .dig_out_nid = ALC880_DIGOUT_NID,2308 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),2309 .channel_mode = alc880_asus_modes,2310 .input_mux = &alc880_capture_source,2311 },2312 [ALC880_UNIWILL_DIG] = {2313 .mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },2314 .init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs },2315 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),2316 .dac_nids = alc880_asus_dac_nids,2317 .dig_out_nid = ALC880_DIGOUT_NID,2318 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),2319 .channel_mode = alc880_asus_modes,2320 .input_mux = &alc880_capture_source,2321 },2322 [ALC880_CLEVO] = {2323 .mixers = { alc880_three_stack_mixer },2324 .init_verbs = { alc880_volume_init_verbs,2325 alc880_pin_clevo_init_verbs },2326 .num_dacs = ARRAY_SIZE(alc880_dac_nids),2327 .dac_nids = alc880_dac_nids,2328 .hp_nid = 0x03,2329 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),2330 .channel_mode = alc880_threestack_modes,2331 .input_mux = &alc880_capture_source,2332 },2333 [ALC880_LG] = {2334 .mixers = { alc880_lg_mixer },2335 .init_verbs = { alc880_volume_init_verbs,2336 alc880_lg_init_verbs },2337 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),2338 .dac_nids = alc880_lg_dac_nids,2339 .dig_out_nid = ALC880_DIGOUT_NID,2340 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),2341 .channel_mode = alc880_lg_ch_modes,2342 .input_mux = &alc880_lg_capture_source,2343 .unsol_event = alc880_lg_unsol_event,2344 .init_hook = alc880_lg_automute,2345 },2346 [ALC880_LG_LW] = {2347 .mixers = { alc880_lg_lw_mixer },2348 .init_verbs = { alc880_volume_init_verbs,2349 alc880_lg_lw_init_verbs },2350 .num_dacs = 1,2351 .dac_nids = alc880_dac_nids,2352 .dig_out_nid = ALC880_DIGOUT_NID,2353 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),2354 .channel_mode = alc880_2_jack_modes,2355 .input_mux = &alc880_lg_lw_capture_source,2356 .unsol_event = alc880_lg_lw_unsol_event,2357 .init_hook = alc880_lg_lw_automute,2358 },2187 [ALC880_3ST] = { 2188 .mixers = { alc880_three_stack_mixer }, 2189 .init_verbs = { alc880_volume_init_verbs, alc880_pin_3stack_init_verbs }, 2190 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 2191 .dac_nids = alc880_dac_nids, 2192 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 2193 .channel_mode = alc880_threestack_modes, 2194 .input_mux = &alc880_capture_source, 2195 }, 2196 [ALC880_3ST_DIG] = { 2197 .mixers = { alc880_three_stack_mixer }, 2198 .init_verbs = { alc880_volume_init_verbs, alc880_pin_3stack_init_verbs }, 2199 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 2200 .dac_nids = alc880_dac_nids, 2201 .dig_out_nid = ALC880_DIGOUT_NID, 2202 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 2203 .channel_mode = alc880_threestack_modes, 2204 .input_mux = &alc880_capture_source, 2205 }, 2206 [ALC880_TCL_S700] = { 2207 .mixers = { alc880_tcl_s700_mixer }, 2208 .init_verbs = { alc880_volume_init_verbs, 2209 alc880_pin_tcl_S700_init_verbs, 2210 alc880_gpio2_init_verbs }, 2211 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 2212 .dac_nids = alc880_dac_nids, 2213 .hp_nid = 0x03, 2214 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 2215 .channel_mode = alc880_2_jack_modes, 2216 .input_mux = &alc880_capture_source, 2217 }, 2218 [ALC880_5ST] = { 2219 .mixers = { alc880_three_stack_mixer, alc880_five_stack_mixer}, 2220 .init_verbs = { alc880_volume_init_verbs, alc880_pin_5stack_init_verbs }, 2221 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 2222 .dac_nids = alc880_dac_nids, 2223 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes), 2224 .channel_mode = alc880_fivestack_modes, 2225 .input_mux = &alc880_capture_source, 2226 }, 2227 [ALC880_5ST_DIG] = { 2228 .mixers = { alc880_three_stack_mixer, alc880_five_stack_mixer }, 2229 .init_verbs = { alc880_volume_init_verbs, alc880_pin_5stack_init_verbs }, 2230 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 2231 .dac_nids = alc880_dac_nids, 2232 .dig_out_nid = ALC880_DIGOUT_NID, 2233 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes), 2234 .channel_mode = alc880_fivestack_modes, 2235 .input_mux = &alc880_capture_source, 2236 }, 2237 [ALC880_6ST] = { 2238 .mixers = { alc880_six_stack_mixer }, 2239 .init_verbs = { alc880_volume_init_verbs, alc880_pin_6stack_init_verbs }, 2240 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids), 2241 .dac_nids = alc880_6st_dac_nids, 2242 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes), 2243 .channel_mode = alc880_sixstack_modes, 2244 .input_mux = &alc880_6stack_capture_source, 2245 }, 2246 [ALC880_6ST_DIG] = { 2247 .mixers = { alc880_six_stack_mixer }, 2248 .init_verbs = { alc880_volume_init_verbs, alc880_pin_6stack_init_verbs }, 2249 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids), 2250 .dac_nids = alc880_6st_dac_nids, 2251 .dig_out_nid = ALC880_DIGOUT_NID, 2252 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes), 2253 .channel_mode = alc880_sixstack_modes, 2254 .input_mux = &alc880_6stack_capture_source, 2255 }, 2256 [ALC880_W810] = { 2257 .mixers = { alc880_w810_base_mixer }, 2258 .init_verbs = { alc880_volume_init_verbs, alc880_pin_w810_init_verbs, 2259 alc880_gpio2_init_verbs }, 2260 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids), 2261 .dac_nids = alc880_w810_dac_nids, 2262 .dig_out_nid = ALC880_DIGOUT_NID, 2263 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes), 2264 .channel_mode = alc880_w810_modes, 2265 .input_mux = &alc880_capture_source, 2266 }, 2267 [ALC880_Z71V] = { 2268 .mixers = { alc880_z71v_mixer }, 2269 .init_verbs = { alc880_volume_init_verbs, alc880_pin_z71v_init_verbs }, 2270 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids), 2271 .dac_nids = alc880_z71v_dac_nids, 2272 .dig_out_nid = ALC880_DIGOUT_NID, 2273 .hp_nid = 0x03, 2274 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 2275 .channel_mode = alc880_2_jack_modes, 2276 .input_mux = &alc880_capture_source, 2277 }, 2278 [ALC880_F1734] = { 2279 .mixers = { alc880_f1734_mixer }, 2280 .init_verbs = { alc880_volume_init_verbs, alc880_pin_f1734_init_verbs }, 2281 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids), 2282 .dac_nids = alc880_f1734_dac_nids, 2283 .hp_nid = 0x02, 2284 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 2285 .channel_mode = alc880_2_jack_modes, 2286 .input_mux = &alc880_capture_source, 2287 }, 2288 [ALC880_ASUS] = { 2289 .mixers = { alc880_asus_mixer }, 2290 .init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs, 2291 alc880_gpio1_init_verbs }, 2292 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 2293 .dac_nids = alc880_asus_dac_nids, 2294 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 2295 .channel_mode = alc880_asus_modes, 2296 .input_mux = &alc880_capture_source, 2297 }, 2298 [ALC880_ASUS_DIG] = { 2299 .mixers = { alc880_asus_mixer }, 2300 .init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs, 2301 alc880_gpio1_init_verbs }, 2302 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 2303 .dac_nids = alc880_asus_dac_nids, 2304 .dig_out_nid = ALC880_DIGOUT_NID, 2305 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 2306 .channel_mode = alc880_asus_modes, 2307 .input_mux = &alc880_capture_source, 2308 }, 2309 [ALC880_ASUS_DIG2] = { 2310 .mixers = { alc880_asus_mixer }, 2311 .init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs, 2312 alc880_gpio2_init_verbs }, /* use GPIO2 */ 2313 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 2314 .dac_nids = alc880_asus_dac_nids, 2315 .dig_out_nid = ALC880_DIGOUT_NID, 2316 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 2317 .channel_mode = alc880_asus_modes, 2318 .input_mux = &alc880_capture_source, 2319 }, 2320 [ALC880_ASUS_W1V] = { 2321 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer }, 2322 .init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs, 2323 alc880_gpio1_init_verbs }, 2324 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 2325 .dac_nids = alc880_asus_dac_nids, 2326 .dig_out_nid = ALC880_DIGOUT_NID, 2327 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 2328 .channel_mode = alc880_asus_modes, 2329 .input_mux = &alc880_capture_source, 2330 }, 2331 [ALC880_UNIWILL_DIG] = { 2332 .mixers = { alc880_asus_mixer, alc880_pcbeep_mixer }, 2333 .init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs }, 2334 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 2335 .dac_nids = alc880_asus_dac_nids, 2336 .dig_out_nid = ALC880_DIGOUT_NID, 2337 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 2338 .channel_mode = alc880_asus_modes, 2339 .input_mux = &alc880_capture_source, 2340 }, 2341 [ALC880_CLEVO] = { 2342 .mixers = { alc880_three_stack_mixer }, 2343 .init_verbs = { alc880_volume_init_verbs, 2344 alc880_pin_clevo_init_verbs }, 2345 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 2346 .dac_nids = alc880_dac_nids, 2347 .hp_nid = 0x03, 2348 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 2349 .channel_mode = alc880_threestack_modes, 2350 .input_mux = &alc880_capture_source, 2351 }, 2352 [ALC880_LG] = { 2353 .mixers = { alc880_lg_mixer }, 2354 .init_verbs = { alc880_volume_init_verbs, 2355 alc880_lg_init_verbs }, 2356 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids), 2357 .dac_nids = alc880_lg_dac_nids, 2358 .dig_out_nid = ALC880_DIGOUT_NID, 2359 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes), 2360 .channel_mode = alc880_lg_ch_modes, 2361 .input_mux = &alc880_lg_capture_source, 2362 .unsol_event = alc880_lg_unsol_event, 2363 .init_hook = alc880_lg_automute, 2364 }, 2365 [ALC880_LG_LW] = { 2366 .mixers = { alc880_lg_lw_mixer }, 2367 .init_verbs = { alc880_volume_init_verbs, 2368 alc880_lg_lw_init_verbs }, 2369 .num_dacs = 1, 2370 .dac_nids = alc880_dac_nids, 2371 .dig_out_nid = ALC880_DIGOUT_NID, 2372 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 2373 .channel_mode = alc880_2_jack_modes, 2374 .input_mux = &alc880_lg_lw_capture_source, 2375 .unsol_event = alc880_lg_lw_unsol_event, 2376 .init_hook = alc880_lg_lw_automute, 2377 }, 2359 2378 #ifdef CONFIG_SND_DEBUG 2360 [ALC880_TEST] = {2361 .mixers = { alc880_test_mixer },2362 .init_verbs = { alc880_test_init_verbs },2363 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),2364 .dac_nids = alc880_test_dac_nids,2365 .dig_out_nid = ALC880_DIGOUT_NID,2366 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),2367 .channel_mode = alc880_test_modes,2368 .input_mux = &alc880_test_capture_source,2369 },2379 [ALC880_TEST] = { 2380 .mixers = { alc880_test_mixer }, 2381 .init_verbs = { alc880_test_init_verbs }, 2382 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids), 2383 .dac_nids = alc880_test_dac_nids, 2384 .dig_out_nid = ALC880_DIGOUT_NID, 2385 .num_channel_mode = ARRAY_SIZE(alc880_test_modes), 2386 .channel_mode = alc880_test_modes, 2387 .input_mux = &alc880_test_capture_source, 2388 }, 2370 2389 #endif 2371 2390 }; … … 2379 2398 2380 2399 enum { 2381 ALC_CTL_WIDGET_VOL,2382 ALC_CTL_WIDGET_MUTE,2383 ALC_CTL_BIND_MUTE,2400 ALC_CTL_WIDGET_VOL, 2401 ALC_CTL_WIDGET_MUTE, 2402 ALC_CTL_BIND_MUTE, 2384 2403 }; 2385 2404 static struct snd_kcontrol_new alc880_control_templates[] = { 2386 HDA_CODEC_VOLUME(NULL, 0, 0, 0),2387 HDA_CODEC_MUTE(NULL, 0, 0, 0),2388 HDA_BIND_MUTE(NULL, 0, 0, 0),2405 HDA_CODEC_VOLUME(NULL, 0, 0, 0), 2406 HDA_CODEC_MUTE(NULL, 0, 0, 0), 2407 HDA_BIND_MUTE(NULL, 0, 0, 0), 2389 2408 }; 2390 2409 … … 2392 2411 static int add_control(struct alc_spec *spec, int type, const char *name, unsigned long val) 2393 2412 { 2394 struct snd_kcontrol_new *knew;2395 2396 if (spec->num_kctl_used >= spec->num_kctl_alloc) {2397 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;2398 2399 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL); /* array + terminator */2400 if (! knew)2401 return -ENOMEM;2402 if (spec->kctl_alloc) {2403 memcpy(knew, spec->kctl_alloc, sizeof(*knew) * spec->num_kctl_alloc);2404 kfree(spec->kctl_alloc);2405 }2406 spec->kctl_alloc = knew;2407 spec->num_kctl_alloc = num;2408 }2409 2410 knew = &spec->kctl_alloc[spec->num_kctl_used];2411 *knew = alc880_control_templates[type];2412 knew->name = kstrdup(name, GFP_KERNEL);2413 if (! knew->name)2414 return -ENOMEM;2415 knew->private_value = val;2416 spec->num_kctl_used++;2417 return 0;2413 struct snd_kcontrol_new *knew; 2414 2415 if (spec->num_kctl_used >= spec->num_kctl_alloc) { 2416 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC; 2417 2418 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL); /* array + terminator */ 2419 if (! knew) 2420 return -ENOMEM; 2421 if (spec->kctl_alloc) { 2422 memcpy(knew, spec->kctl_alloc, sizeof(*knew) * spec->num_kctl_alloc); 2423 kfree(spec->kctl_alloc); 2424 } 2425 spec->kctl_alloc = knew; 2426 spec->num_kctl_alloc = num; 2427 } 2428 2429 knew = &spec->kctl_alloc[spec->num_kctl_used]; 2430 *knew = alc880_control_templates[type]; 2431 knew->name = kstrdup(name, GFP_KERNEL); 2432 if (! knew->name) 2433 return -ENOMEM; 2434 knew->private_value = val; 2435 spec->num_kctl_used++; 2436 return 0; 2418 2437 } 2419 2438 … … 2433 2452 static int alc880_auto_fill_dac_nids(struct alc_spec *spec, const struct auto_pin_cfg *cfg) 2434 2453 { 2435 hda_nid_t nid;2436 int assigned[4];2437 int i, j;2438 2439 memset(assigned, 0, sizeof(assigned));2440 spec->multiout.dac_nids = spec->private_dac_nids;2441 2442 /* check the pins hardwired to audio widget */2443 for (i = 0; i < cfg->line_outs; i++) {2444 nid = cfg->line_out_pins[i];2445 if (alc880_is_fixed_pin(nid)) {2446 int idx = alc880_fixed_pin_idx(nid);2447 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);2448 assigned[idx] = 1;2449 }2450 }2451 /* left pins can be connect to any audio widget */2452 for (i = 0; i < cfg->line_outs; i++) {2453 nid = cfg->line_out_pins[i];2454 if (alc880_is_fixed_pin(nid))2455 continue;2456 /* search for an empty channel */2457 for (j = 0; j < cfg->line_outs; j++) {2458 if (! assigned[j]) {2459 spec->multiout.dac_nids[i] = alc880_idx_to_dac(j);2460 assigned[j] = 1;2461 break;2462 }2463 }2464 }2465 spec->multiout.num_dacs = cfg->line_outs;2466 return 0;2454 hda_nid_t nid; 2455 int assigned[4]; 2456 int i, j; 2457 2458 memset(assigned, 0, sizeof(assigned)); 2459 spec->multiout.dac_nids = spec->private_dac_nids; 2460 2461 /* check the pins hardwired to audio widget */ 2462 for (i = 0; i < cfg->line_outs; i++) { 2463 nid = cfg->line_out_pins[i]; 2464 if (alc880_is_fixed_pin(nid)) { 2465 int idx = alc880_fixed_pin_idx(nid); 2466 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx); 2467 assigned[idx] = 1; 2468 } 2469 } 2470 /* left pins can be connect to any audio widget */ 2471 for (i = 0; i < cfg->line_outs; i++) { 2472 nid = cfg->line_out_pins[i]; 2473 if (alc880_is_fixed_pin(nid)) 2474 continue; 2475 /* search for an empty channel */ 2476 for (j = 0; j < cfg->line_outs; j++) { 2477 if (! assigned[j]) { 2478 spec->multiout.dac_nids[i] = alc880_idx_to_dac(j); 2479 assigned[j] = 1; 2480 break; 2481 } 2482 } 2483 } 2484 spec->multiout.num_dacs = cfg->line_outs; 2485 return 0; 2467 2486 } 2468 2487 2469 2488 /* add playback controls from the parsed DAC table */ 2470 2489 static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec, 2471 const struct auto_pin_cfg *cfg)2472 { 2473 char name[32];2474 static const char *chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" };2475 hda_nid_t nid;2476 int i, err;2477 2478 for (i = 0; i < cfg->line_outs; i++) {2479 if (! spec->multiout.dac_nids[i])2480 continue;2481 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));2482 if (i == 2) {2483 /* Center/LFE */2484 if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Center Playback Volume",2485 HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT))) < 0)2486 return err;2487 if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "LFE Playback Volume",2488 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0)2489 return err;2490 if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "Center Playback Switch",2491 HDA_COMPOSE_AMP_VAL(nid, 1, 2, HDA_INPUT))) < 0)2492 return err;2493 if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "LFE Playback Switch",2494 HDA_COMPOSE_AMP_VAL(nid, 2, 2, HDA_INPUT))) < 0)2495 return err;2496 } else {2497 sprintf(name, "%s Playback Volume", chname[i]);2498 if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name,2499 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)2500 return err;2501 sprintf(name, "%s Playback Switch", chname[i]);2502 if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name,2503 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT))) < 0)2504 return err;2505 }2506 }2507 return 0;2490 const struct auto_pin_cfg *cfg) 2491 { 2492 char name[32]; 2493 static const char *chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" }; 2494 hda_nid_t nid; 2495 int i, err; 2496 2497 for (i = 0; i < cfg->line_outs; i++) { 2498 if (! spec->multiout.dac_nids[i]) 2499 continue; 2500 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i])); 2501 if (i == 2) { 2502 /* Center/LFE */ 2503 if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Center Playback Volume", 2504 HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT))) < 0) 2505 return err; 2506 if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "LFE Playback Volume", 2507 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0) 2508 return err; 2509 if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "Center Playback Switch", 2510 HDA_COMPOSE_AMP_VAL(nid, 1, 2, HDA_INPUT))) < 0) 2511 return err; 2512 if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "LFE Playback Switch", 2513 HDA_COMPOSE_AMP_VAL(nid, 2, 2, HDA_INPUT))) < 0) 2514 return err; 2515 } else { 2516 sprintf(name, "%s Playback Volume", chname[i]); 2517 if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 2518 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) 2519 return err; 2520 sprintf(name, "%s Playback Switch", chname[i]); 2521 if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name, 2522 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT))) < 0) 2523 return err; 2524 } 2525 } 2526 return 0; 2508 2527 } 2509 2528 2510 2529 /* add playback controls for speaker and HP outputs */ 2511 2530 static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin, 2512 const char *pfx)2513 { 2514 hda_nid_t nid;2515 int err;2516 char name[32];2517 2518 if (! pin)2519 return 0;2520 2521 if (alc880_is_fixed_pin(pin)) {2522 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));2523 /* specify the DAC as the extra output */2524 if (! spec->multiout.hp_nid)2525 spec->multiout.hp_nid = nid;2526 else2527 spec->multiout.extra_out_nid[0] = nid;2528 /* control HP volume/switch on the output mixer amp */2529 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));2530 sprintf(name, "%s Playback Volume", pfx);2531 if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name,2532 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)2533 return err;2534 sprintf(name, "%s Playback Switch", pfx);2535 if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name,2536 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT))) < 0)2537 return err;2538 } else if (alc880_is_multi_pin(pin)) {2539 /* set manual connection */2540 /* we have only a switch on HP-out PIN */2541 sprintf(name, "%s Playback Switch", pfx);2542 if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,2543 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT))) < 0)2544 return err;2545 }2546 return 0;2531 const char *pfx) 2532 { 2533 hda_nid_t nid; 2534 int err; 2535 char name[32]; 2536 2537 if (! pin) 2538 return 0; 2539 2540 if (alc880_is_fixed_pin(pin)) { 2541 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); 2542 /* specify the DAC as the extra output */ 2543 if (! spec->multiout.hp_nid) 2544 spec->multiout.hp_nid = nid; 2545 else 2546 spec->multiout.extra_out_nid[0] = nid; 2547 /* control HP volume/switch on the output mixer amp */ 2548 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin)); 2549 sprintf(name, "%s Playback Volume", pfx); 2550 if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 2551 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) 2552 return err; 2553 sprintf(name, "%s Playback Switch", pfx); 2554 if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name, 2555 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT))) < 0) 2556 return err; 2557 } else if (alc880_is_multi_pin(pin)) { 2558 /* set manual connection */ 2559 /* we have only a switch on HP-out PIN */ 2560 sprintf(name, "%s Playback Switch", pfx); 2561 if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, 2562 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT))) < 0) 2563 return err; 2564 } 2565 return 0; 2547 2566 } 2548 2567 2549 2568 /* create input playback/capture controls for the given pin */ 2550 2569 static int new_analog_input(struct alc_spec *spec, hda_nid_t pin, const char *ctlname, 2551 int idx, hda_nid_t mix_nid)2552 { 2553 char name[32];2554 int err;2555 2556 sprintf(name, "%s Playback Volume", ctlname);2557 if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name,2558 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT))) < 0)2559 return err;2560 sprintf(name, "%s Playback Switch", ctlname);2561 if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,2562 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT))) < 0)2563 return err;2564 return 0;2570 int idx, hda_nid_t mix_nid) 2571 { 2572 char name[32]; 2573 int err; 2574 2575 sprintf(name, "%s Playback Volume", ctlname); 2576 if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 2577 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT))) < 0) 2578 return err; 2579 sprintf(name, "%s Playback Switch", ctlname); 2580 if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, 2581 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT))) < 0) 2582 return err; 2583 return 0; 2565 2584 } 2566 2585 2567 2586 /* create playback/capture controls for input pins */ 2568 2587 static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec, 2569 const struct auto_pin_cfg *cfg)2570 { 2571 struct hda_input_mux *imux = &spec->private_imux;2572 int i, err, idx;2573 2574 for (i = 0; i < AUTO_PIN_LAST; i++) {2575 if (alc880_is_input_pin(cfg->input_pins[i])) {2576 idx = alc880_input_pin_idx(cfg->input_pins[i]);2577 err = new_analog_input(spec, cfg->input_pins[i],2578 auto_pin_cfg_labels[i],2579 idx, 0x0b);2580 if (err < 0)2581 return err;2582 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];2583 imux->items[imux->num_items].index = alc880_input_pin_idx(cfg->input_pins[i]);2584 imux->num_items++;2585 }2586 }2587 return 0;2588 const struct auto_pin_cfg *cfg) 2589 { 2590 struct hda_input_mux *imux = &spec->private_imux; 2591 int i, err, idx; 2592 2593 for (i = 0; i < AUTO_PIN_LAST; i++) { 2594 if (alc880_is_input_pin(cfg->input_pins[i])) { 2595 idx = alc880_input_pin_idx(cfg->input_pins[i]); 2596 err = new_analog_input(spec, cfg->input_pins[i], 2597 auto_pin_cfg_labels[i], 2598 idx, 0x0b); 2599 if (err < 0) 2600 return err; 2601 imux->items[imux->num_items].label = auto_pin_cfg_labels[i]; 2602 imux->items[imux->num_items].index = alc880_input_pin_idx(cfg->input_pins[i]); 2603 imux->num_items++; 2604 } 2605 } 2606 return 0; 2588 2607 } 2589 2608 2590 2609 static void alc880_auto_set_output_and_unmute(struct hda_codec *codec, 2591 hda_nid_t nid, int pin_type,2592 int dac_idx)2593 { 2594 /* set as output */2595 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);2596 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);2597 /* need the manual connection? */2598 if (alc880_is_multi_pin(nid)) {2599 struct alc_spec *spec = codec->spec;2600 int idx = alc880_multi_pin_idx(nid);2601 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,2602 AC_VERB_SET_CONNECT_SEL,2603 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));2604 }2610 hda_nid_t nid, int pin_type, 2611 int dac_idx) 2612 { 2613 /* set as output */ 2614 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type); 2615 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); 2616 /* need the manual connection? */ 2617 if (alc880_is_multi_pin(nid)) { 2618 struct alc_spec *spec = codec->spec; 2619 int idx = alc880_multi_pin_idx(nid); 2620 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0, 2621 AC_VERB_SET_CONNECT_SEL, 2622 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx])); 2623 } 2605 2624 } 2606 2625 2607 2626 static void alc880_auto_init_multi_out(struct hda_codec *codec) 2608 2627 { 2609 struct alc_spec *spec = codec->spec;2610 int i;2611 2612 for (i = 0; i < spec->autocfg.line_outs; i++) {2613 hda_nid_t nid = spec->autocfg.line_out_pins[i];2614 alc880_auto_set_output_and_unmute(codec, nid, PIN_OUT, i);2615 }2628 struct alc_spec *spec = codec->spec; 2629 int i; 2630 2631 for (i = 0; i < spec->autocfg.line_outs; i++) { 2632 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 2633 alc880_auto_set_output_and_unmute(codec, nid, PIN_OUT, i); 2634 } 2616 2635 } 2617 2636 2618 2637 static void alc880_auto_init_extra_out(struct hda_codec *codec) 2619 2638 { 2620 struct alc_spec *spec = codec->spec;2621 hda_nid_t pin;2622 2623 pin = spec->autocfg.speaker_pins[0];2624 if (pin) /* connect to front */2625 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);2626 pin = spec->autocfg.hp_pin;2627 if (pin) /* connect to front */2628 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);2639 struct alc_spec *spec = codec->spec; 2640 hda_nid_t pin; 2641 2642 pin = spec->autocfg.speaker_pins[0]; 2643 if (pin) /* connect to front */ 2644 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); 2645 pin = spec->autocfg.hp_pin; 2646 if (pin) /* connect to front */ 2647 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 2629 2648 } 2630 2649 2631 2650 static void alc880_auto_init_analog_input(struct hda_codec *codec) 2632 2651 { 2633 struct alc_spec *spec = codec->spec;2634 int i;2635 2636 for (i = 0; i < AUTO_PIN_LAST; i++) {2637 hda_nid_t nid = spec->autocfg.input_pins[i];2638 if (alc880_is_input_pin(nid)) {2639 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,2640 i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN);2641 if (nid != ALC880_PIN_CD_NID)2642 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,2643 AMP_OUT_MUTE);2644 }2645 }2652 struct alc_spec *spec = codec->spec; 2653 int i; 2654 2655 for (i = 0; i < AUTO_PIN_LAST; i++) { 2656 hda_nid_t nid = spec->autocfg.input_pins[i]; 2657 if (alc880_is_input_pin(nid)) { 2658 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 2659 i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN); 2660 if (nid != ALC880_PIN_CD_NID) 2661 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 2662 AMP_OUT_MUTE); 2663 } 2664 } 2646 2665 } 2647 2666 … … 2650 2669 static int alc880_parse_auto_config(struct hda_codec *codec) 2651 2670 { 2652 struct alc_spec *spec = codec->spec;2653 int err;2654 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };2655 2656 if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,2657 alc880_ignore)) < 0)2658 return err;2659 if (! spec->autocfg.line_outs)2660 return 0; /* can't find valid BIOS pin config */2661 2662 if ((err = alc880_auto_fill_dac_nids(spec, &spec->autocfg)) < 0 ||2663 (err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 ||2664 (err = alc880_auto_create_extra_out(spec,2665 spec->autocfg.speaker_pins[0],2666 "Speaker")) < 0 ||2667 (err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pin,2668 "Headphone")) < 0 ||2669 (err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0)2670 return err;2671 2672 spec->multiout.max_channels = spec->multiout.num_dacs * 2;2673 2674 if (spec->autocfg.dig_out_pin)2675 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;2676 if (spec->autocfg.dig_in_pin)2677 spec->dig_in_nid = ALC880_DIGIN_NID;2678 2679 if (spec->kctl_alloc)2680 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;2681 2682 spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs;2683 2684 spec->input_mux = &spec->private_imux;2685 2686 return 1;2671 struct alc_spec *spec = codec->spec; 2672 int err; 2673 static hda_nid_t alc880_ignore[] = { 0x1d, 0 }; 2674 2675 if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 2676 alc880_ignore)) < 0) 2677 return err; 2678 if (! spec->autocfg.line_outs) 2679 return 0; /* can't find valid BIOS pin config */ 2680 2681 if ((err = alc880_auto_fill_dac_nids(spec, &spec->autocfg)) < 0 || 2682 (err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 || 2683 (err = alc880_auto_create_extra_out(spec, 2684 spec->autocfg.speaker_pins[0], 2685 "Speaker")) < 0 || 2686 (err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pin, 2687 "Headphone")) < 0 || 2688 (err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0) 2689 return err; 2690 2691 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 2692 2693 if (spec->autocfg.dig_out_pin) 2694 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID; 2695 if (spec->autocfg.dig_in_pin) 2696 spec->dig_in_nid = ALC880_DIGIN_NID; 2697 2698 if (spec->kctl_alloc) 2699 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 2700 2701 spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs; 2702 2703 spec->input_mux = &spec->private_imux; 2704 2705 return 1; 2687 2706 } 2688 2707 … … 2701 2720 static int patch_alc880(struct hda_codec *codec) 2702 2721 { 2703 struct alc_spec *spec;2704 int board_config;2705 int err;2706 2707 spec = kzalloc(sizeof(*spec), GFP_KERNEL);2708 if (spec == NULL)2709 return -ENOMEM;2710 2711 codec->spec = spec;2712 2713 board_config = snd_hda_check_board_config(codec, alc880_cfg_tbl);2714 if (board_config < 0 || board_config >= ALC880_MODEL_LAST) {2715 printk(KERN_INFO "hda_codec: Unknown model for ALC880, trying auto-probe from BIOS...\n");2716 board_config = ALC880_AUTO;2717 }2718 2719 if (board_config == ALC880_AUTO) {2720 /* automatic parse from the BIOS config */2721 err = alc880_parse_auto_config(codec);2722 if (err < 0) {2723 alc_free(codec);2724 return err;2725 } else if (! err) {2726 printk(KERN_INFO "hda_codec: Cannot set up configuration from BIOS. Using 3-stack mode...\n");2727 board_config = ALC880_3ST;2728 }2729 }2730 2731 if (board_config != ALC880_AUTO)2732 setup_preset(spec, &alc880_presets[board_config]);2733 2734 spec->stream_name_analog = "ALC880 Analog";2735 spec->stream_analog_playback = &alc880_pcm_analog_playback;2736 spec->stream_analog_capture = &alc880_pcm_analog_capture;2737 2738 spec->stream_name_digital = "ALC880 Digital";2739 spec->stream_digital_playback = &alc880_pcm_digital_playback;2740 spec->stream_digital_capture = &alc880_pcm_digital_capture;2741 2742 if (! spec->adc_nids && spec->input_mux) {2743 /* check whether NID 0x07 is valid */2744 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);2745 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */2746 if (wcap != AC_WID_AUD_IN) {2747 spec->adc_nids = alc880_adc_nids_alt;2748 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);2749 spec->mixers[spec->num_mixers] = alc880_capture_alt_mixer;2750 spec->num_mixers++;2751 } else {2752 spec->adc_nids = alc880_adc_nids;2753 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);2754 spec->mixers[spec->num_mixers] = alc880_capture_mixer;2755 spec->num_mixers++;2756 }2757 }2758 2759 codec->patch_ops = alc_patch_ops;2760 if (board_config == ALC880_AUTO)2761 spec->init_hook = alc880_auto_init;2762 2763 return 0;2722 struct alc_spec *spec; 2723 int board_config; 2724 int err; 2725 2726 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 2727 if (spec == NULL) 2728 return -ENOMEM; 2729 2730 codec->spec = spec; 2731 2732 board_config = snd_hda_check_board_config(codec, alc880_cfg_tbl); 2733 if (board_config < 0 || board_config >= ALC880_MODEL_LAST) { 2734 printk(KERN_INFO "hda_codec: Unknown model for ALC880, trying auto-probe from BIOS...\n"); 2735 board_config = ALC880_AUTO; 2736 } 2737 2738 if (board_config == ALC880_AUTO) { 2739 /* automatic parse from the BIOS config */ 2740 err = alc880_parse_auto_config(codec); 2741 if (err < 0) { 2742 alc_free(codec); 2743 return err; 2744 } else if (! err) { 2745 printk(KERN_INFO "hda_codec: Cannot set up configuration from BIOS. Using 3-stack mode...\n"); 2746 board_config = ALC880_3ST; 2747 } 2748 } 2749 2750 if (board_config != ALC880_AUTO) 2751 setup_preset(spec, &alc880_presets[board_config]); 2752 2753 spec->stream_name_analog = "ALC880 Analog"; 2754 spec->stream_analog_playback = &alc880_pcm_analog_playback; 2755 spec->stream_analog_capture = &alc880_pcm_analog_capture; 2756 2757 spec->stream_name_digital = "ALC880 Digital"; 2758 spec->stream_digital_playback = &alc880_pcm_digital_playback; 2759 spec->stream_digital_capture = &alc880_pcm_digital_capture; 2760 2761 if (! spec->adc_nids && spec->input_mux) { 2762 /* check whether NID 0x07 is valid */ 2763 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]); 2764 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */ 2765 if (wcap != AC_WID_AUD_IN) { 2766 spec->adc_nids = alc880_adc_nids_alt; 2767 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt); 2768 spec->mixers[spec->num_mixers] = alc880_capture_alt_mixer; 2769 spec->num_mixers++; 2770 } else { 2771 spec->adc_nids = alc880_adc_nids; 2772 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids); 2773 spec->mixers[spec->num_mixers] = alc880_capture_mixer; 2774 spec->num_mixers++; 2775 } 2776 } 2777 2778 codec->patch_ops = alc_patch_ops; 2779 if (board_config == ALC880_AUTO) 2780 spec->init_hook = alc880_auto_init; 2781 2782 return 0; 2764 2783 } 2765 2784 … … 2770 2789 2771 2790 static hda_nid_t alc260_dac_nids[1] = { 2772 /* front */2773 0x02,2791 /* front */ 2792 0x02, 2774 2793 }; 2775 2794 2776 2795 static hda_nid_t alc260_adc_nids[1] = { 2777 /* ADC0 */2778 0x04,2796 /* ADC0 */ 2797 0x04, 2779 2798 }; 2780 2799 2781 2800 static hda_nid_t alc260_adc_nids_alt[1] = { 2782 /* ADC1 */2783 0x05,2801 /* ADC1 */ 2802 0x05, 2784 2803 }; 2785 2804 2786 2805 static hda_nid_t alc260_hp_adc_nids[2] = { 2787 /* ADC1, 0 */2788 0x05, 0x042806 /* ADC1, 0 */ 2807 0x05, 0x04 2789 2808 }; 2790 2809 … … 2793 2812 */ 2794 2813 static hda_nid_t alc260_dual_adc_nids[2] = { 2795 /* ADC0, ADC1 */2796 0x04, 0x052814 /* ADC0, ADC1 */ 2815 0x04, 0x05 2797 2816 }; 2798 2817 … … 2801 2820 2802 2821 static struct hda_input_mux alc260_capture_source = { 2803 .num_items = 4,2804 .items = {2805 { "Mic", 0x0 },2806 { "Front Mic", 0x1 },2807 { "Line", 0x2 },2808 { "CD", 0x4 },2809 },2822 .num_items = 4, 2823 .items = { 2824 { "Mic", 0x0 }, 2825 { "Front Mic", 0x1 }, 2826 { "Line", 0x2 }, 2827 { "CD", 0x4 }, 2828 }, 2810 2829 }; 2811 2830 … … 2814 2833 */ 2815 2834 static struct hda_input_mux alc260_fujitsu_capture_source = { 2816 .num_items = 3,2817 .items = {2818 { "Mic/Line", 0x0 },2819 { "CD", 0x4 },2820 { "Headphone", 0x2 },2821 },2835 .num_items = 3, 2836 .items = { 2837 { "Mic/Line", 0x0 }, 2838 { "CD", 0x4 }, 2839 { "Headphone", 0x2 }, 2840 }, 2822 2841 }; 2823 2842 … … 2827 2846 */ 2828 2847 static struct hda_input_mux alc260_acer_capture_source = { 2829 .num_items = 3,2830 .items = {2831 { "Mic", 0x0 },2832 { "Line", 0x2 },2833 { "CD", 0x4 },2834 },2848 .num_items = 3, 2849 .items = { 2850 { "Mic", 0x0 }, 2851 { "Line", 0x2 }, 2852 { "CD", 0x4 }, 2853 }, 2835 2854 }; 2836 2855 … … 2842 2861 */ 2843 2862 static struct hda_channel_mode alc260_modes[1] = { 2844 { 2, NULL },2863 { 2, NULL }, 2845 2864 }; 2846 2865 … … 2856 2875 2857 2876 static struct snd_kcontrol_new alc260_base_output_mixer[] = { 2858 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),2859 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),2860 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),2861 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),2862 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),2863 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),2864 {0} /* end */2877 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT), 2878 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT), 2879 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT), 2880 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT), 2881 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), 2882 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT), 2883 {0} /* end */ 2865 2884 }; 2866 2885 2867 2886 static struct snd_kcontrol_new alc260_input_mixer[] = { 2868 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),2869 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),2870 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),2871 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),2872 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),2873 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),2874 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),2875 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),2876 {0} /* end */2887 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 2888 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 2889 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), 2890 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), 2891 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 2892 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), 2893 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT), 2894 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT), 2895 {0} /* end */ 2877 2896 }; 2878 2897 2879 2898 static struct snd_kcontrol_new alc260_pc_beep_mixer[] = { 2880 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),2881 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),2882 {0} /* end */2899 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT), 2900 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT), 2901 {0} /* end */ 2883 2902 }; 2884 2903 2885 2904 static struct snd_kcontrol_new alc260_hp_3013_mixer[] = { 2886 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),2887 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),2888 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),2889 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),2890 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),2891 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),2892 HDA_CODEC_VOLUME_MONO("iSpeaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),2893 HDA_CODEC_MUTE_MONO("iSpeaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),2894 {0} /* end */2905 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT), 2906 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT), 2907 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT), 2908 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT), 2909 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT), 2910 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 2911 HDA_CODEC_VOLUME_MONO("iSpeaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), 2912 HDA_CODEC_MUTE_MONO("iSpeaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT), 2913 {0} /* end */ 2895 2914 }; 2896 2915 2897 2916 static struct snd_kcontrol_new alc260_fujitsu_mixer[] = { 2898 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),2899 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),2900 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),2901 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),2902 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),2903 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),2904 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),2905 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),2906 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),2907 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),2908 HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),2909 HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x09, 2, HDA_INPUT),2910 {0} /* end */2917 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT), 2918 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT), 2919 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT), 2920 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 2921 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 2922 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT), 2923 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT), 2924 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN), 2925 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT), 2926 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT), 2927 HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT), 2928 HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x09, 2, HDA_INPUT), 2929 {0} /* end */ 2911 2930 }; 2912 2931 2913 2932 static struct snd_kcontrol_new alc260_acer_mixer[] = { 2914 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),2915 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),2916 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),2917 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),2918 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),2919 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),2920 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),2921 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),2922 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),2923 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),2924 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),2925 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),2926 {0} /* end */2933 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), 2934 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT), 2935 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 2936 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 2937 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 2938 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), 2939 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), 2940 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), 2941 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), 2942 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT), 2943 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT), 2944 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT), 2945 {0} /* end */ 2927 2946 }; 2928 2947 2929 2948 /* capture mixer elements */ 2930 2949 static struct snd_kcontrol_new alc260_capture_mixer[] = { 2931 HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),2932 HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),2933 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x05, 0x0, HDA_INPUT),2934 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x05, 0x0, HDA_INPUT),2935 {2936 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,2937 /* The multiple "Capture Source" controls confuse alsamixer2938 * So call somewhat different..2939 * FIXME: the controls appear in the "playback" view!2940 */2941 /* .name = "Capture Source", */2942 .name = "Input Source",2943 .count = 2,2944 .info = alc_mux_enum_info,2945 .get = alc_mux_enum_get,2946 .put = alc_mux_enum_put,2947 },2948 {0} /* end */2950 HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT), 2951 HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT), 2952 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x05, 0x0, HDA_INPUT), 2953 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x05, 0x0, HDA_INPUT), 2954 { 2955 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2956 /* The multiple "Capture Source" controls confuse alsamixer 2957 * So call somewhat different.. 2958 * FIXME: the controls appear in the "playback" view! 2959 */ 2960 /* .name = "Capture Source", */ 2961 .name = "Input Source", 2962 .count = 2, 2963 .info = alc_mux_enum_info, 2964 .get = alc_mux_enum_get, 2965 .put = alc_mux_enum_put, 2966 }, 2967 {0} /* end */ 2949 2968 }; 2950 2969 2951 2970 static struct snd_kcontrol_new alc260_capture_alt_mixer[] = { 2952 HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),2953 HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),2954 {2955 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,2956 /* The multiple "Capture Source" controls confuse alsamixer2957 * So call somewhat different..2958 * FIXME: the controls appear in the "playback" view!2959 */2960 /* .name = "Capture Source", */2961 .name = "Input Source",2962 .count = 1,2963 .info = alc_mux_enum_info,2964 .get = alc_mux_enum_get,2965 .put = alc_mux_enum_put,2966 },2967 {0} /* end */2971 HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT), 2972 HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT), 2973 { 2974 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2975 /* The multiple "Capture Source" controls confuse alsamixer 2976 * So call somewhat different.. 2977 * FIXME: the controls appear in the "playback" view! 2978 */ 2979 /* .name = "Capture Source", */ 2980 .name = "Input Source", 2981 .count = 1, 2982 .info = alc_mux_enum_info, 2983 .get = alc_mux_enum_get, 2984 .put = alc_mux_enum_put, 2985 }, 2986 {0} /* end */ 2968 2987 }; 2969 2988 … … 2972 2991 */ 2973 2992 static struct hda_verb alc260_init_verbs[] = { 2974 /* Line In pin widget for input */ 2975 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2976 /* CD pin widget for input */ 2977 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2978 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 2979 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2980 /* Mic2 (front panel) pin widget for input and vref at 80% */ 2981 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2982 /* LINE-2 is used for line-out in rear */ 2983 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2984 /* select line-out */ 2985 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00}, 2986 /* LINE-OUT pin */ 2987 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2988 /* enable HP */ 2989 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2990 /* enable Mono */ 2991 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2992 /* mute capture amp left and right */ 2993 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2994 /* set connection select to line in (default select for this ADC) */ 2995 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02}, 2996 /* mute capture amp left and right */ 2997 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2998 /* set connection select to line in (default select for this ADC) */ 2999 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02}, 3000 /* set vol=0 Line-Out mixer amp left and right */ 3001 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3002 /* unmute pin widget amp left and right (no gain on this amp) */ 3003 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3004 /* set vol=0 HP mixer amp left and right */ 3005 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3006 /* unmute pin widget amp left and right (no gain on this amp) */ 3007 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3008 /* set vol=0 Mono mixer amp left and right */ 3009 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3010 /* unmute pin widget amp left and right (no gain on this amp) */ 3011 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3012 /* unmute LINE-2 out pin */ 3013 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3014 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */ 3015 /* mute CD */ 3016 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 3017 /* mute Line In */ 3018 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 3019 /* mute Mic */ 3020 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3021 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */ 3022 /* mute Front out path */ 3023 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3024 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3025 /* mute Headphone out path */ 3026 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3027 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3028 /* mute Mono out path */ 3029 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3030 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3031 {0} 3032 }; 3033 2993 /* Line In pin widget for input */ 2994 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2995 /* CD pin widget for input */ 2996 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2997 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 2998 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2999 /* Mic2 (front panel) pin widget for input and vref at 80% */ 3000 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3001 /* LINE-2 is used for line-out in rear */ 3002 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3003 /* select line-out */ 3004 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00}, 3005 /* LINE-OUT pin */ 3006 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3007 /* enable HP */ 3008 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3009 /* enable Mono */ 3010 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3011 /* mute capture amp left and right */ 3012 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3013 /* set connection select to line in (default select for this ADC) */ 3014 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02}, 3015 /* mute capture amp left and right */ 3016 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3017 /* set connection select to line in (default select for this ADC) */ 3018 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02}, 3019 /* set vol=0 Line-Out mixer amp left and right */ 3020 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3021 /* unmute pin widget amp left and right (no gain on this amp) */ 3022 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3023 /* set vol=0 HP mixer amp left and right */ 3024 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3025 /* unmute pin widget amp left and right (no gain on this amp) */ 3026 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3027 /* set vol=0 Mono mixer amp left and right */ 3028 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3029 /* unmute pin widget amp left and right (no gain on this amp) */ 3030 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3031 /* unmute LINE-2 out pin */ 3032 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3033 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */ 3034 /* mute CD */ 3035 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 3036 /* mute Line In */ 3037 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 3038 /* mute Mic */ 3039 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3040 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */ 3041 /* mute Front out path */ 3042 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3043 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3044 /* mute Headphone out path */ 3045 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3046 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3047 /* mute Mono out path */ 3048 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3049 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3050 {0} 3051 }; 3052 3053 #if 0 /* should be identical with alc260_init_verbs? */ 3034 3054 static struct hda_verb alc260_hp_init_verbs[] = { 3035 /* Headphone and output */ 3036 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 3037 /* mono output */ 3038 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 3039 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 3040 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 3041 /* Mic2 (front panel) pin widget for input and vref at 80% */ 3042 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 3043 /* Line In pin widget for input */ 3044 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 3045 /* Line-2 pin widget for output */ 3046 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 3047 /* CD pin widget for input */ 3048 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 3049 /* unmute amp left and right */ 3050 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000}, 3051 /* set connection select to line in (default select for this ADC) */ 3052 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02}, 3053 /* unmute Line-Out mixer amp left and right (volume = 0) */ 3054 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 3055 /* mute pin widget amp left and right (no gain on this amp) */ 3056 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 3057 /* unmute HP mixer amp left and right (volume = 0) */ 3058 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 3059 /* mute pin widget amp left and right (no gain on this amp) */ 3060 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 3061 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */ 3062 /* unmute CD */ 3063 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, 3064 /* unmute Line In */ 3065 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, 3066 /* unmute Mic */ 3067 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3068 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */ 3069 /* Unmute Front out path */ 3070 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3071 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3072 /* Unmute Headphone out path */ 3073 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3074 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3075 /* Unmute Mono out path */ 3076 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3077 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3078 {0} 3079 }; 3055 /* Headphone and output */ 3056 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 3057 /* mono output */ 3058 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 3059 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 3060 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 3061 /* Mic2 (front panel) pin widget for input and vref at 80% */ 3062 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 3063 /* Line In pin widget for input */ 3064 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 3065 /* Line-2 pin widget for output */ 3066 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 3067 /* CD pin widget for input */ 3068 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 3069 /* unmute amp left and right */ 3070 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000}, 3071 /* set connection select to line in (default select for this ADC) */ 3072 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02}, 3073 /* unmute Line-Out mixer amp left and right (volume = 0) */ 3074 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 3075 /* mute pin widget amp left and right (no gain on this amp) */ 3076 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 3077 /* unmute HP mixer amp left and right (volume = 0) */ 3078 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 3079 /* mute pin widget amp left and right (no gain on this amp) */ 3080 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 3081 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */ 3082 /* unmute CD */ 3083 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, 3084 /* unmute Line In */ 3085 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, 3086 /* unmute Mic */ 3087 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3088 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */ 3089 /* Unmute Front out path */ 3090 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3091 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3092 /* Unmute Headphone out path */ 3093 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3094 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3095 /* Unmute Mono out path */ 3096 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3097 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3098 {0} 3099 }; 3100 #endif 3080 3101 3081 3102 static struct hda_verb alc260_hp_3013_init_verbs[] = { 3082 /* Line out and output */3083 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},3084 /* mono output */3085 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},3086 /* Mic1 (rear panel) pin widget for input and vref at 80% */3087 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},3088 /* Mic2 (front panel) pin widget for input and vref at 80% */3089 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},3090 /* Line In pin widget for input */3091 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},3092 /* Headphone pin widget for output */3093 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},3094 /* CD pin widget for input */3095 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},3096 /* unmute amp left and right */3097 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},3098 /* set connection select to line in (default select for this ADC) */3099 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},3100 /* unmute Line-Out mixer amp left and right (volume = 0) */3101 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},3102 /* mute pin widget amp left and right (no gain on this amp) */3103 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},3104 /* unmute HP mixer amp left and right (volume = 0) */3105 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},3106 /* mute pin widget amp left and right (no gain on this amp) */3107 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},3108 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */3109 /* unmute CD */3110 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},3111 /* unmute Line In */3112 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},3113 /* unmute Mic */3114 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},3115 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */3116 /* Unmute Front out path */3117 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},3118 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},3119 /* Unmute Headphone out path */3120 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},3121 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},3122 /* Unmute Mono out path */3123 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},3124 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},3125 {0}3103 /* Line out and output */ 3104 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 3105 /* mono output */ 3106 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 3107 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 3108 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 3109 /* Mic2 (front panel) pin widget for input and vref at 80% */ 3110 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 3111 /* Line In pin widget for input */ 3112 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 3113 /* Headphone pin widget for output */ 3114 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 3115 /* CD pin widget for input */ 3116 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 3117 /* unmute amp left and right */ 3118 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000}, 3119 /* set connection select to line in (default select for this ADC) */ 3120 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02}, 3121 /* unmute Line-Out mixer amp left and right (volume = 0) */ 3122 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 3123 /* mute pin widget amp left and right (no gain on this amp) */ 3124 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 3125 /* unmute HP mixer amp left and right (volume = 0) */ 3126 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 3127 /* mute pin widget amp left and right (no gain on this amp) */ 3128 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 3129 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */ 3130 /* unmute CD */ 3131 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, 3132 /* unmute Line In */ 3133 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, 3134 /* unmute Mic */ 3135 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3136 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */ 3137 /* Unmute Front out path */ 3138 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3139 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3140 /* Unmute Headphone out path */ 3141 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3142 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3143 /* Unmute Mono out path */ 3144 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3145 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3146 {0} 3126 3147 }; 3127 3148 … … 3130 3151 */ 3131 3152 static struct hda_verb alc260_fujitsu_init_verbs[] = { 3132 /* Disable all GPIOs */3133 {0x01, AC_VERB_SET_GPIO_MASK, 0},3134 /* Internal speaker is connected to headphone pin */3135 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},3136 /* Headphone/Line-out jack connects to Line1 pin; make it an output */3137 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},3138 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */3139 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},3140 /* Ensure all other unused pins are disabled and muted. */3141 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},3142 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},3143 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},3144 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},3145 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},3146 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},3147 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},3148 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},3149 3150 /* Disable digital (SPDIF) pins */3151 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},3152 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},3153 3154 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus3155 * when acting as an output.3156 */3157 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},3158 3159 /* Start with output sum widgets muted and their output gains at min */3160 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},3161 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},3162 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},3163 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},3164 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},3165 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},3166 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},3167 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},3168 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},3169 3170 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */3171 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},3172 /* Unmute Line1 pin widget output buffer since it starts as an output.3173 * If the pin mode is changed by the user the pin mode control will3174 * take care of enabling the pin's input/output buffers as needed.3175 * Therefore there's no need to enable the input buffer at this3176 * stage.3177 */3178 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},3179 /* Unmute input buffer of pin widget used for Line-in (no equiv3180 * mixer ctrl)3181 */3182 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},3183 3184 /* Mute capture amp left and right */3185 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},3186 /* Set ADC connection select to match default mixer setting - line3187 * in (on mic1 pin)3188 */3189 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},3190 3191 /* Do the same for the second ADC: mute capture input amp and3192 * set ADC connection to line in (on mic1 pin)3193 */3194 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},3195 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},3196 3197 /* Mute all inputs to mixer widget (even unconnected ones) */3198 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */3199 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */3200 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */3201 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */3202 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */3203 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */3204 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */3205 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */3206 3207 {0}3153 /* Disable all GPIOs */ 3154 {0x01, AC_VERB_SET_GPIO_MASK, 0}, 3155 /* Internal speaker is connected to headphone pin */ 3156 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3157 /* Headphone/Line-out jack connects to Line1 pin; make it an output */ 3158 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3159 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */ 3160 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3161 /* Ensure all other unused pins are disabled and muted. */ 3162 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 3163 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3164 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 3165 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3166 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 3167 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3168 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 3169 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3170 3171 /* Disable digital (SPDIF) pins */ 3172 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, 3173 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, 3174 3175 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus 3176 * when acting as an output. 3177 */ 3178 {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, 3179 3180 /* Start with output sum widgets muted and their output gains at min */ 3181 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3182 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3183 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3184 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3185 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3186 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3187 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3188 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3189 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3190 3191 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */ 3192 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3193 /* Unmute Line1 pin widget output buffer since it starts as an output. 3194 * If the pin mode is changed by the user the pin mode control will 3195 * take care of enabling the pin's input/output buffers as needed. 3196 * Therefore there's no need to enable the input buffer at this 3197 * stage. 3198 */ 3199 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3200 /* Unmute input buffer of pin widget used for Line-in (no equiv 3201 * mixer ctrl) 3202 */ 3203 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3204 3205 /* Mute capture amp left and right */ 3206 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3207 /* Set ADC connection select to match default mixer setting - line 3208 * in (on mic1 pin) 3209 */ 3210 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 3211 3212 /* Do the same for the second ADC: mute capture input amp and 3213 * set ADC connection to line in (on mic1 pin) 3214 */ 3215 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3216 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 3217 3218 /* Mute all inputs to mixer widget (even unconnected ones) */ 3219 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ 3220 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ 3221 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ 3222 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ 3223 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ 3224 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ 3225 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ 3226 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ 3227 3228 {0} 3208 3229 }; 3209 3230 … … 3212 3233 */ 3213 3234 static struct hda_verb alc260_acer_init_verbs[] = { 3214 /* On TravelMate laptops, GPIO 0 enables the internal speaker and3215 * the headphone jack. Turn this on and rely on the standard mute3216 * methods whenever the user wants to turn these outputs off.3217 */3218 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},3219 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},3220 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},3221 /* Internal speaker/Headphone jack is connected to Line-out pin */3222 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},3223 /* Internal microphone/Mic jack is connected to Mic1 pin */3224 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},3225 /* Line In jack is connected to Line1 pin */3226 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},3227 /* Ensure all other unused pins are disabled and muted. */3228 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},3229 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},3230 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},3231 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},3232 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},3233 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},3234 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},3235 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},3236 /* Disable digital (SPDIF) pins */3237 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},3238 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},3239 3240 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum3241 * bus when acting as outputs.3242 */3243 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},3244 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},3245 3246 /* Start with output sum widgets muted and their output gains at min */3247 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},3248 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},3249 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},3250 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},3251 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},3252 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},3253 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},3254 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},3255 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},3256 3257 /* Unmute Line-out pin widget amp left and right (no equiv mixer ctrl) */3258 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},3259 /* Unmute Mic1 and Line1 pin widget input buffers since they start as3260 * inputs. If the pin mode is changed by the user the pin mode control3261 * will take care of enabling the pin's input/output buffers as needed.3262 * Therefore there's no need to enable the input buffer at this3263 * stage.3264 */3265 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},3266 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},3267 3268 /* Mute capture amp left and right */3269 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},3270 /* Set ADC connection select to match default mixer setting - mic3271 * (on mic1 pin)3272 */3273 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},3274 3275 /* Do similar with the second ADC: mute capture input amp and3276 * set ADC connection to line (on line1 pin)3277 */3278 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},3279 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},3280 3281 /* Mute all inputs to mixer widget (even unconnected ones) */3282 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */3283 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */3284 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */3285 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */3286 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */3287 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */3288 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */3289 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */3290 3291 {0}3235 /* On TravelMate laptops, GPIO 0 enables the internal speaker and 3236 * the headphone jack. Turn this on and rely on the standard mute 3237 * methods whenever the user wants to turn these outputs off. 3238 */ 3239 {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, 3240 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 3241 {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, 3242 /* Internal speaker/Headphone jack is connected to Line-out pin */ 3243 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3244 /* Internal microphone/Mic jack is connected to Mic1 pin */ 3245 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 3246 /* Line In jack is connected to Line1 pin */ 3247 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3248 /* Ensure all other unused pins are disabled and muted. */ 3249 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 3250 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3251 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 3252 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3253 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 3254 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3255 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 3256 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3257 /* Disable digital (SPDIF) pins */ 3258 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, 3259 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, 3260 3261 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum 3262 * bus when acting as outputs. 3263 */ 3264 {0x0b, AC_VERB_SET_CONNECT_SEL, 0}, 3265 {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, 3266 3267 /* Start with output sum widgets muted and their output gains at min */ 3268 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3269 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3270 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3271 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3272 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3273 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3274 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3275 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3276 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3277 3278 /* Unmute Line-out pin widget amp left and right (no equiv mixer ctrl) */ 3279 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3280 /* Unmute Mic1 and Line1 pin widget input buffers since they start as 3281 * inputs. If the pin mode is changed by the user the pin mode control 3282 * will take care of enabling the pin's input/output buffers as needed. 3283 * Therefore there's no need to enable the input buffer at this 3284 * stage. 3285 */ 3286 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3287 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3288 3289 /* Mute capture amp left and right */ 3290 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3291 /* Set ADC connection select to match default mixer setting - mic 3292 * (on mic1 pin) 3293 */ 3294 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 3295 3296 /* Do similar with the second ADC: mute capture input amp and 3297 * set ADC connection to line (on line1 pin) 3298 */ 3299 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3300 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02}, 3301 3302 /* Mute all inputs to mixer widget (even unconnected ones) */ 3303 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ 3304 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ 3305 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ 3306 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ 3307 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ 3308 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ 3309 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ 3310 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ 3311 3312 {0} 3292 3313 }; 3293 3314 … … 3297 3318 #ifdef CONFIG_SND_DEBUG 3298 3319 static hda_nid_t alc260_test_dac_nids[1] = { 3299 0x02,3320 0x02, 3300 3321 }; 3301 3322 static hda_nid_t alc260_test_adc_nids[2] = { 3302 0x04, 0x05,3323 0x04, 0x05, 3303 3324 }; 3304 3325 /* This is a bit messy since the two input muxes in the ALC260 have slight … … 3312 3333 */ 3313 3334 static struct hda_input_mux alc260_test_capture_source = { 3314 .num_items = 8,3315 .items = {3316 { "MIC1 pin", 0x0 },3317 { "MIC2 pin", 0x1 },3318 { "LINE1 pin", 0x2 },3319 { "LINE2 pin", 0x3 },3320 { "CD pin", 0x4 },3321 { "LINE-OUT pin (cap1), Mixer (cap2)", 0x5 },3322 { "HP-OUT pin (cap1), LINE-OUT pin (cap2)", 0x6 },3323 { "HP-OUT pin (cap2 only)", 0x7 },3324 },3335 .num_items = 8, 3336 .items = { 3337 { "MIC1 pin", 0x0 }, 3338 { "MIC2 pin", 0x1 }, 3339 { "LINE1 pin", 0x2 }, 3340 { "LINE2 pin", 0x3 }, 3341 { "CD pin", 0x4 }, 3342 { "LINE-OUT pin (cap1), Mixer (cap2)", 0x5 }, 3343 { "HP-OUT pin (cap1), LINE-OUT pin (cap2)", 0x6 }, 3344 { "HP-OUT pin (cap2 only)", 0x7 }, 3345 }, 3325 3346 }; 3326 3347 static struct snd_kcontrol_new alc260_test_mixer[] = { 3327 /* Output driver widgets */3328 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),3329 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),3330 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),3331 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),3332 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),3333 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),3334 3335 /* Modes for retasking pin widgets */3336 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),3337 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),3338 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),3339 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),3340 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),3341 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),3342 3343 /* Loopback mixer controls */3344 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),3345 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),3346 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),3347 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),3348 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),3349 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),3350 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),3351 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),3352 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),3353 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),3354 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),3355 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),3356 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),3357 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),3358 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),3359 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),3360 3361 /* Controls for GPIO pins, assuming they are configured as outputs */3362 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),3363 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),3364 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),3365 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),3366 3367 /* Switches to allow the digital IO pins to be enabled. The datasheet3368 * is ambigious as to which NID is which; testing on laptops which3369 * make this output available should provide clarification.3370 */3371 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),3372 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),3373 3374 {0} /* end */3348 /* Output driver widgets */ 3349 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), 3350 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT), 3351 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT), 3352 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT), 3353 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT), 3354 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT), 3355 3356 /* Modes for retasking pin widgets */ 3357 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT), 3358 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT), 3359 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT), 3360 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT), 3361 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT), 3362 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT), 3363 3364 /* Loopback mixer controls */ 3365 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT), 3366 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT), 3367 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT), 3368 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT), 3369 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT), 3370 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT), 3371 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT), 3372 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT), 3373 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 3374 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 3375 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT), 3376 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT), 3377 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT), 3378 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT), 3379 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT), 3380 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT), 3381 3382 /* Controls for GPIO pins, assuming they are configured as outputs */ 3383 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01), 3384 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02), 3385 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04), 3386 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08), 3387 3388 /* Switches to allow the digital IO pins to be enabled. The datasheet 3389 * is ambigious as to which NID is which; testing on laptops which 3390 * make this output available should provide clarification. 3391 */ 3392 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01), 3393 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01), 3394 3395 {0} /* end */ 3375 3396 }; 3376 3397 static struct hda_verb alc260_test_init_verbs[] = { 3377 /* Enable all GPIOs as outputs with an initial value of 0 */3378 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},3379 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},3380 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},3381 3382 /* Enable retasking pins as output, initially without power amp */3383 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},3384 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},3385 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},3386 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},3387 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},3388 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},3389 3390 /* Disable digital (SPDIF) pins initially, but users can enable3391 * them via a mixer switch. In the case of SPDIF-out, this initverb3392 * payload also sets the generation to 0, output to be in "consumer"3393 * PCM format, copyright asserted, no pre-emphasis and no validity3394 * control.3395 */3396 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},3397 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},3398 3399 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the3400 * OUT1 sum bus when acting as an output.3401 */3402 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},3403 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},3404 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},3405 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},3406 3407 /* Start with output sum widgets muted and their output gains at min */3408 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},3409 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},3410 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},3411 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},3412 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},3413 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},3414 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},3415 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},3416 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},3417 3418 /* Unmute retasking pin widget output buffers since the default3419 * state appears to be output. As the pin mode is changed by the3420 * user the pin mode control will take care of enabling the pin's3421 * input/output buffers as needed.3422 */3423 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},3424 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},3425 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},3426 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},3427 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},3428 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},3429 /* Also unmute the mono-out pin widget */3430 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},3431 3432 /* Mute capture amp left and right */3433 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},3434 /* Set ADC connection select to match default mixer setting (mic13435 * pin)3436 */3437 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},3438 3439 /* Do the same for the second ADC: mute capture input amp and3440 * set ADC connection to mic1 pin3441 */3442 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},3443 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},3444 3445 /* Mute all inputs to mixer widget (even unconnected ones) */3446 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */3447 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */3448 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */3449 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */3450 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */3451 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */3452 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */3453 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */3454 3455 {0}3398 /* Enable all GPIOs as outputs with an initial value of 0 */ 3399 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f}, 3400 {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, 3401 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f}, 3402 3403 /* Enable retasking pins as output, initially without power amp */ 3404 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3405 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3406 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3407 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3408 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3409 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3410 3411 /* Disable digital (SPDIF) pins initially, but users can enable 3412 * them via a mixer switch. In the case of SPDIF-out, this initverb 3413 * payload also sets the generation to 0, output to be in "consumer" 3414 * PCM format, copyright asserted, no pre-emphasis and no validity 3415 * control. 3416 */ 3417 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, 3418 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, 3419 3420 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the 3421 * OUT1 sum bus when acting as an output. 3422 */ 3423 {0x0b, AC_VERB_SET_CONNECT_SEL, 0}, 3424 {0x0c, AC_VERB_SET_CONNECT_SEL, 0}, 3425 {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, 3426 {0x0e, AC_VERB_SET_CONNECT_SEL, 0}, 3427 3428 /* Start with output sum widgets muted and their output gains at min */ 3429 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3430 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3431 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3432 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3433 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3434 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3435 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3436 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3437 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3438 3439 /* Unmute retasking pin widget output buffers since the default 3440 * state appears to be output. As the pin mode is changed by the 3441 * user the pin mode control will take care of enabling the pin's 3442 * input/output buffers as needed. 3443 */ 3444 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3445 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3446 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3447 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3448 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3449 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3450 /* Also unmute the mono-out pin widget */ 3451 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3452 3453 /* Mute capture amp left and right */ 3454 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3455 /* Set ADC connection select to match default mixer setting (mic1 3456 * pin) 3457 */ 3458 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 3459 3460 /* Do the same for the second ADC: mute capture input amp and 3461 * set ADC connection to mic1 pin 3462 */ 3463 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3464 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 3465 3466 /* Mute all inputs to mixer widget (even unconnected ones) */ 3467 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ 3468 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ 3469 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ 3470 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ 3471 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ 3472 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ 3473 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ 3474 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ 3475 3476 {0} 3456 3477 }; 3457 3478 #endif 3458 3479 3459 3480 static struct hda_pcm_stream alc260_pcm_analog_playback = { 3460 .substreams = 1,3461 .channels_min = 2,3462 .channels_max = 2,3481 .substreams = 1, 3482 .channels_min = 2, 3483 .channels_max = 2, 3463 3484 }; 3464 3485 3465 3486 static struct hda_pcm_stream alc260_pcm_analog_capture = { 3466 .substreams = 1,3467 .channels_min = 2,3468 .channels_max = 2,3487 .substreams = 1, 3488 .channels_min = 2, 3489 .channels_max = 2, 3469 3490 }; 3470 3491 … … 3477 3498 3478 3499 static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid, 3479 const char *pfx)3480 { 3481 hda_nid_t nid_vol;3482 unsigned long vol_val, sw_val;3483 char name[32];3484 int err;3485 3486 if (nid >= 0x0f && nid < 0x11) {3487 nid_vol = nid - 0x7;3488 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);3489 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);3490 } else if (nid == 0x11) {3491 nid_vol = nid - 0x7;3492 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);3493 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);3494 } else if (nid >= 0x12 && nid <= 0x15) {3495 nid_vol = 0x08;3496 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);3497 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);3498 } else3499 return 0; /* N/A */3500 3501 sprintf(name, /*sizeof(name), */"%s Playback Volume", pfx);3502 if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val)) < 0)3503 return err;3504 sprintf(name, /*sizeof(name), */"%s Playback Switch", pfx);3505 if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val)) < 0)3506 return err;3507 return 1;3500 const char *pfx) 3501 { 3502 hda_nid_t nid_vol; 3503 unsigned long vol_val, sw_val; 3504 char name[32]; 3505 int err; 3506 3507 if (nid >= 0x0f && nid < 0x11) { 3508 nid_vol = nid - 0x7; 3509 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT); 3510 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); 3511 } else if (nid == 0x11) { 3512 nid_vol = nid - 0x7; 3513 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT); 3514 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT); 3515 } else if (nid >= 0x12 && nid <= 0x15) { 3516 nid_vol = 0x08; 3517 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT); 3518 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); 3519 } else 3520 return 0; /* N/A */ 3521 3522 sprintf(name, /*sizeof(name), */"%s Playback Volume", pfx); 3523 if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val)) < 0) 3524 return err; 3525 sprintf(name, /*sizeof(name), */"%s Playback Switch", pfx); 3526 if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val)) < 0) 3527 return err; 3528 return 1; 3508 3529 } 3509 3530 3510 3531 /* add playback controls from the parsed DAC table */ 3511 3532 static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec, 3512 const struct auto_pin_cfg *cfg)3513 { 3514 hda_nid_t nid;3515 int err;3516 3517 spec->multiout.num_dacs = 1;3518 spec->multiout.dac_nids = spec->private_dac_nids;3519 spec->multiout.dac_nids[0] = 0x02;3520 3521 nid = cfg->line_out_pins[0];3522 if (nid) {3523 err = alc260_add_playback_controls(spec, nid, "Front");3524 if (err < 0)3525 return err;3526 }3527 3528 nid = cfg->speaker_pins[0];3529 if (nid) {3530 err = alc260_add_playback_controls(spec, nid, "Speaker");3531 if (err < 0)3532 return err;3533 }3534 3535 nid = cfg->hp_pin;3536 if (nid) {3537 err = alc260_add_playback_controls(spec, nid, "Headphone");3538 if (err < 0)3539 return err;3540 }3541 return 0;3533 const struct auto_pin_cfg *cfg) 3534 { 3535 hda_nid_t nid; 3536 int err; 3537 3538 spec->multiout.num_dacs = 1; 3539 spec->multiout.dac_nids = spec->private_dac_nids; 3540 spec->multiout.dac_nids[0] = 0x02; 3541 3542 nid = cfg->line_out_pins[0]; 3543 if (nid) { 3544 err = alc260_add_playback_controls(spec, nid, "Front"); 3545 if (err < 0) 3546 return err; 3547 } 3548 3549 nid = cfg->speaker_pins[0]; 3550 if (nid) { 3551 err = alc260_add_playback_controls(spec, nid, "Speaker"); 3552 if (err < 0) 3553 return err; 3554 } 3555 3556 nid = cfg->hp_pin; 3557 if (nid) { 3558 err = alc260_add_playback_controls(spec, nid, "Headphone"); 3559 if (err < 0) 3560 return err; 3561 } 3562 return 0; 3542 3563 } 3543 3564 3544 3565 /* create playback/capture controls for input pins */ 3545 3566 static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec, 3546 const struct auto_pin_cfg *cfg)3547 { 3548 struct hda_input_mux *imux = &spec->private_imux;3549 int i, err, idx;3550 3551 for (i = 0; i < AUTO_PIN_LAST; i++) {3552 if (cfg->input_pins[i] >= 0x12) {3553 idx = cfg->input_pins[i] - 0x12;3554 err = new_analog_input(spec, cfg->input_pins[i],3555 auto_pin_cfg_labels[i], idx, 0x07);3556 if (err < 0)3557 return err;3558 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];3559 imux->items[imux->num_items].index = idx;3560 imux->num_items++;3561 }3562 if ((cfg->input_pins[i] >= 0x0f) && (cfg->input_pins[i] <= 0x10)){3563 idx = cfg->input_pins[i] - 0x09;3564 err = new_analog_input(spec, cfg->input_pins[i],3565 auto_pin_cfg_labels[i], idx, 0x07);3566 if (err < 0)3567 return err;3568 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];3569 imux->items[imux->num_items].index = idx;3570 imux->num_items++;3571 }3572 }3573 return 0;3567 const struct auto_pin_cfg *cfg) 3568 { 3569 struct hda_input_mux *imux = &spec->private_imux; 3570 int i, err, idx; 3571 3572 for (i = 0; i < AUTO_PIN_LAST; i++) { 3573 if (cfg->input_pins[i] >= 0x12) { 3574 idx = cfg->input_pins[i] - 0x12; 3575 err = new_analog_input(spec, cfg->input_pins[i], 3576 auto_pin_cfg_labels[i], idx, 0x07); 3577 if (err < 0) 3578 return err; 3579 imux->items[imux->num_items].label = auto_pin_cfg_labels[i]; 3580 imux->items[imux->num_items].index = idx; 3581 imux->num_items++; 3582 } 3583 if ((cfg->input_pins[i] >= 0x0f) && (cfg->input_pins[i] <= 0x10)){ 3584 idx = cfg->input_pins[i] - 0x09; 3585 err = new_analog_input(spec, cfg->input_pins[i], 3586 auto_pin_cfg_labels[i], idx, 0x07); 3587 if (err < 0) 3588 return err; 3589 imux->items[imux->num_items].label = auto_pin_cfg_labels[i]; 3590 imux->items[imux->num_items].index = idx; 3591 imux->num_items++; 3592 } 3593 } 3594 return 0; 3574 3595 } 3575 3596 3576 3597 static void alc260_auto_set_output_and_unmute(struct hda_codec *codec, 3577 hda_nid_t nid, int pin_type,3578 int sel_idx)3579 { 3580 /* set as output */3581 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);3582 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);3583 /* need the manual connection? */3584 if (nid >= 0x12) {3585 int idx = nid - 0x12;3586 snd_hda_codec_write(codec, idx + 0x0b, 0,3587 AC_VERB_SET_CONNECT_SEL, sel_idx);3588 3589 }3598 hda_nid_t nid, int pin_type, 3599 int sel_idx) 3600 { 3601 /* set as output */ 3602 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type); 3603 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); 3604 /* need the manual connection? */ 3605 if (nid >= 0x12) { 3606 int idx = nid - 0x12; 3607 snd_hda_codec_write(codec, idx + 0x0b, 0, 3608 AC_VERB_SET_CONNECT_SEL, sel_idx); 3609 3610 } 3590 3611 } 3591 3612 3592 3613 static void alc260_auto_init_multi_out(struct hda_codec *codec) 3593 3614 { 3594 struct alc_spec *spec = codec->spec;3595 hda_nid_t nid;3596 3597 nid = spec->autocfg.line_out_pins[0];3598 if (nid)3599 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);3600 3601 nid = spec->autocfg.speaker_pins[0];3602 if (nid)3603 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);3604 3605 nid = spec->autocfg.hp_pin;3606 if (nid)3607 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);3615 struct alc_spec *spec = codec->spec; 3616 hda_nid_t nid; 3617 3618 nid = spec->autocfg.line_out_pins[0]; 3619 if (nid) 3620 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0); 3621 3622 nid = spec->autocfg.speaker_pins[0]; 3623 if (nid) 3624 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0); 3625 3626 nid = spec->autocfg.hp_pin; 3627 if (nid) 3628 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0); 3608 3629 } 3609 3630 … … 3611 3632 static void alc260_auto_init_analog_input(struct hda_codec *codec) 3612 3633 { 3613 struct alc_spec *spec = codec->spec;3614 int i;3615 3616 for (i = 0; i < AUTO_PIN_LAST; i++) {3617 hda_nid_t nid = spec->autocfg.input_pins[i];3618 if (nid >= 0x12) {3619 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,3620 i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN);3621 if (nid != ALC260_PIN_CD_NID)3622 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,3623 AMP_OUT_MUTE);3624 }3625 }3634 struct alc_spec *spec = codec->spec; 3635 int i; 3636 3637 for (i = 0; i < AUTO_PIN_LAST; i++) { 3638 hda_nid_t nid = spec->autocfg.input_pins[i]; 3639 if (nid >= 0x12) { 3640 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 3641 i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN); 3642 if (nid != ALC260_PIN_CD_NID) 3643 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 3644 AMP_OUT_MUTE); 3645 } 3646 } 3626 3647 } 3627 3648 … … 3630 3651 */ 3631 3652 static struct hda_verb alc260_volume_init_verbs[] = { 3632 /*3633 * Unmute ADC0-1 and set the default input to mic-in3634 */3635 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},3636 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},3637 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},3638 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},3639 3640 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback3641 * mixer widget3642 * Note: PASD motherboards uses the Line In 2 as the input for front panel3643 * mic (mic 2)3644 */3645 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */3646 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},3647 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},3648 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},3649 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},3650 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},3651 3652 /*3653 * Set up output mixers (0x08 - 0x0a)3654 */3655 /* set vol=0 to output mixers */3656 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},3657 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},3658 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},3659 /* set up input amps for analog loopback */3660 /* Amp Indices: DAC = 0, mixer = 1 */3661 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},3662 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},3663 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},3664 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},3665 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},3666 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},3667 3668 {0}3653 /* 3654 * Unmute ADC0-1 and set the default input to mic-in 3655 */ 3656 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 3657 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3658 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 3659 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3660 3661 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 3662 * mixer widget 3663 * Note: PASD motherboards uses the Line In 2 as the input for front panel 3664 * mic (mic 2) 3665 */ 3666 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 3667 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3668 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 3669 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 3670 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 3671 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 3672 3673 /* 3674 * Set up output mixers (0x08 - 0x0a) 3675 */ 3676 /* set vol=0 to output mixers */ 3677 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3678 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3679 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3680 /* set up input amps for analog loopback */ 3681 /* Amp Indices: DAC = 0, mixer = 1 */ 3682 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3683 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 3684 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3685 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 3686 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3687 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 3688 3689 {0} 3669 3690 }; 3670 3691 3671 3692 static int alc260_parse_auto_config(struct hda_codec *codec) 3672 3693 { 3673 struct alc_spec *spec = codec->spec;3674 unsigned int wcap;3675 int err;3676 static hda_nid_t alc260_ignore[] = { 0x17, 0 };3677 3678 if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,3679 alc260_ignore)) < 0)3680 return err;3681 if ((err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0)3682 return err;3683 if (! spec->kctl_alloc)3684 return 0; /* can't find valid BIOS pin config */3685 if ((err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0)3686 return err;3687 3688 spec->multiout.max_channels = 2;3689 3690 if (spec->autocfg.dig_out_pin)3691 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;3692 if (spec->kctl_alloc)3693 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;3694 3695 spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs;3696 3697 spec->input_mux = &spec->private_imux;3698 3699 /* check whether NID 0x04 is valid */3700 wcap = get_wcaps(codec, 0x04);3701 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */3702 if (wcap != AC_WID_AUD_IN) {3703 spec->adc_nids = alc260_adc_nids_alt;3704 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);3705 spec->mixers[spec->num_mixers] = alc260_capture_alt_mixer;3706 } else {3707 spec->adc_nids = alc260_adc_nids;3708 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);3709 spec->mixers[spec->num_mixers] = alc260_capture_mixer;3710 }3711 spec->num_mixers++;3712 3713 return 1;3694 struct alc_spec *spec = codec->spec; 3695 unsigned int wcap; 3696 int err; 3697 static hda_nid_t alc260_ignore[] = { 0x17, 0 }; 3698 3699 if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 3700 alc260_ignore)) < 0) 3701 return err; 3702 if ((err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0) 3703 return err; 3704 if (! spec->kctl_alloc) 3705 return 0; /* can't find valid BIOS pin config */ 3706 if ((err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0) 3707 return err; 3708 3709 spec->multiout.max_channels = 2; 3710 3711 if (spec->autocfg.dig_out_pin) 3712 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID; 3713 if (spec->kctl_alloc) 3714 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 3715 3716 spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs; 3717 3718 spec->input_mux = &spec->private_imux; 3719 3720 /* check whether NID 0x04 is valid */ 3721 wcap = get_wcaps(codec, 0x04); 3722 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */ 3723 if (wcap != AC_WID_AUD_IN) { 3724 spec->adc_nids = alc260_adc_nids_alt; 3725 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt); 3726 spec->mixers[spec->num_mixers] = alc260_capture_alt_mixer; 3727 } else { 3728 spec->adc_nids = alc260_adc_nids; 3729 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids); 3730 spec->mixers[spec->num_mixers] = alc260_capture_mixer; 3731 } 3732 spec->num_mixers++; 3733 3734 return 1; 3714 3735 } 3715 3736 … … 3725 3746 */ 3726 3747 static struct hda_board_config alc260_cfg_tbl[] = { 3727 { .modelname = "basic", .config = ALC260_BASIC }, 3728 { .pci_subvendor = 0x104d, .pci_subdevice = 0x81bb, 3729 .config = ALC260_BASIC }, /* Sony VAIO */ 3730 { .pci_subvendor = 0x152d, .pci_subdevice = 0x0729, 3731 .config = ALC260_BASIC }, /* CTL Travel Master U553W */ 3732 { .modelname = "hp", .config = ALC260_HP }, 3733 { .pci_subvendor = 0x103c, .pci_subdevice = 0x3010, .config = ALC260_HP }, 3734 { .pci_subvendor = 0x103c, .pci_subdevice = 0x3011, .config = ALC260_HP }, 3735 { .pci_subvendor = 0x103c, .pci_subdevice = 0x3012, .config = ALC260_HP }, 3736 { .pci_subvendor = 0x103c, .pci_subdevice = 0x3013, .config = ALC260_HP_3013 }, 3737 { .pci_subvendor = 0x103c, .pci_subdevice = 0x3014, .config = ALC260_HP }, 3738 { .pci_subvendor = 0x103c, .pci_subdevice = 0x3015, .config = ALC260_HP }, 3739 { .pci_subvendor = 0x103c, .pci_subdevice = 0x3016, .config = ALC260_HP }, 3740 { .modelname = "fujitsu", .config = ALC260_FUJITSU_S702X }, 3741 { .pci_subvendor = 0x10cf, .pci_subdevice = 0x1326, .config = ALC260_FUJITSU_S702X }, 3742 { .modelname = "acer", .config = ALC260_ACER }, 3743 { .pci_subvendor = 0x1025, .pci_subdevice = 0x008f, .config = ALC260_ACER }, 3748 { .modelname = "basic", .config = ALC260_BASIC }, 3749 { .pci_subvendor = 0x104d, .pci_subdevice = 0x81bb, 3750 .config = ALC260_BASIC }, /* Sony VAIO */ 3751 { .pci_subvendor = 0x104d, .pci_subdevice = 0x81cc, 3752 .config = ALC260_BASIC }, /* Sony VAIO VGN-S3HP */ 3753 { .pci_subvendor = 0x104d, .pci_subdevice = 0x81cd, 3754 .config = ALC260_BASIC }, /* Sony VAIO */ 3755 { .pci_subvendor = 0x152d, .pci_subdevice = 0x0729, 3756 .config = ALC260_BASIC }, /* CTL Travel Master U553W */ 3757 { .modelname = "hp", .config = ALC260_HP }, 3758 { .pci_subvendor = 0x103c, .pci_subdevice = 0x3010, .config = ALC260_HP }, 3759 { .pci_subvendor = 0x103c, .pci_subdevice = 0x3011, .config = ALC260_HP }, 3760 { .pci_subvendor = 0x103c, .pci_subdevice = 0x3012, .config = ALC260_HP_3013 }, 3761 { .pci_subvendor = 0x103c, .pci_subdevice = 0x3013, .config = ALC260_HP_3013 }, 3762 { .pci_subvendor = 0x103c, .pci_subdevice = 0x3014, .config = ALC260_HP }, 3763 { .pci_subvendor = 0x103c, .pci_subdevice = 0x3015, .config = ALC260_HP }, 3764 { .pci_subvendor = 0x103c, .pci_subdevice = 0x3016, .config = ALC260_HP }, 3765 { .modelname = "fujitsu", .config = ALC260_FUJITSU_S702X }, 3766 { .pci_subvendor = 0x10cf, .pci_subdevice = 0x1326, .config = ALC260_FUJITSU_S702X }, 3767 { .modelname = "acer", .config = ALC260_ACER }, 3768 { .pci_subvendor = 0x1025, .pci_subdevice = 0x008f, .config = ALC260_ACER }, 3744 3769 #ifdef CONFIG_SND_DEBUG 3745 { .modelname = "test", .config = ALC260_TEST },3770 { .modelname = "test", .config = ALC260_TEST }, 3746 3771 #endif 3747 { .modelname = "auto", .config = ALC260_AUTO },3748 {0}3772 { .modelname = "auto", .config = ALC260_AUTO }, 3773 {0} 3749 3774 }; 3750 3775 3751 3776 static struct alc_config_preset alc260_presets[] = { 3752 [ALC260_BASIC] = {3753 .mixers = { alc260_base_output_mixer,3754 alc260_input_mixer,3755 alc260_pc_beep_mixer,3756 alc260_capture_mixer },3757 .init_verbs = { alc260_init_verbs },3758 .num_dacs = ARRAY_SIZE(alc260_dac_nids),3759 .dac_nids = alc260_dac_nids,3760 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),3761 .adc_nids = alc260_adc_nids,3762 .num_channel_mode = ARRAY_SIZE(alc260_modes),3763 .channel_mode = alc260_modes,3764 .input_mux = &alc260_capture_source,3765 },3766 [ALC260_HP] = {3767 .mixers = { alc260_base_output_mixer,3768 alc260_input_mixer,3769 alc260_capture_alt_mixer },3770 .init_verbs = { alc260_hp_init_verbs },3771 .num_dacs = ARRAY_SIZE(alc260_dac_nids),3772 .dac_nids = alc260_dac_nids,3773 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),3774 .adc_nids = alc260_hp_adc_nids,3775 .num_channel_mode = ARRAY_SIZE(alc260_modes),3776 .channel_mode = alc260_modes,3777 .input_mux = &alc260_capture_source,3778 },3779 [ALC260_HP_3013] = {3780 .mixers = { alc260_hp_3013_mixer,3781 alc260_input_mixer,3782 alc260_capture_alt_mixer },3783 .init_verbs = { alc260_hp_3013_init_verbs },3784 .num_dacs = ARRAY_SIZE(alc260_dac_nids),3785 .dac_nids = alc260_dac_nids,3786 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),3787 .adc_nids = alc260_hp_adc_nids,3788 .num_channel_mode = ARRAY_SIZE(alc260_modes),3789 .channel_mode = alc260_modes,3790 .input_mux = &alc260_capture_source,3791 },3792 [ALC260_FUJITSU_S702X] = {3793 .mixers = { alc260_fujitsu_mixer,3794 alc260_capture_mixer },3795 .init_verbs = { alc260_fujitsu_init_verbs },3796 .num_dacs = ARRAY_SIZE(alc260_dac_nids),3797 .dac_nids = alc260_dac_nids,3798 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),3799 .adc_nids = alc260_dual_adc_nids,3800 .num_channel_mode = ARRAY_SIZE(alc260_modes),3801 .channel_mode = alc260_modes,3802 .input_mux = &alc260_fujitsu_capture_source,3803 },3804 [ALC260_ACER] = {3805 .mixers = { alc260_acer_mixer,3806 alc260_capture_mixer },3807 .init_verbs = { alc260_acer_init_verbs },3808 .num_dacs = ARRAY_SIZE(alc260_dac_nids),3809 .dac_nids = alc260_dac_nids,3810 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),3811 .adc_nids = alc260_dual_adc_nids,3812 .num_channel_mode = ARRAY_SIZE(alc260_modes),3813 .channel_mode = alc260_modes,3814 .input_mux = &alc260_acer_capture_source,3815 },3777 [ALC260_BASIC] = { 3778 .mixers = { alc260_base_output_mixer, 3779 alc260_input_mixer, 3780 alc260_pc_beep_mixer, 3781 alc260_capture_mixer }, 3782 .init_verbs = { alc260_init_verbs }, 3783 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 3784 .dac_nids = alc260_dac_nids, 3785 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids), 3786 .adc_nids = alc260_adc_nids, 3787 .num_channel_mode = ARRAY_SIZE(alc260_modes), 3788 .channel_mode = alc260_modes, 3789 .input_mux = &alc260_capture_source, 3790 }, 3791 [ALC260_HP] = { 3792 .mixers = { alc260_base_output_mixer, 3793 alc260_input_mixer, 3794 alc260_capture_alt_mixer }, 3795 .init_verbs = { alc260_init_verbs }, 3796 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 3797 .dac_nids = alc260_dac_nids, 3798 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids), 3799 .adc_nids = alc260_hp_adc_nids, 3800 .num_channel_mode = ARRAY_SIZE(alc260_modes), 3801 .channel_mode = alc260_modes, 3802 .input_mux = &alc260_capture_source, 3803 }, 3804 [ALC260_HP_3013] = { 3805 .mixers = { alc260_hp_3013_mixer, 3806 alc260_input_mixer, 3807 alc260_capture_alt_mixer }, 3808 .init_verbs = { alc260_hp_3013_init_verbs }, 3809 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 3810 .dac_nids = alc260_dac_nids, 3811 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids), 3812 .adc_nids = alc260_hp_adc_nids, 3813 .num_channel_mode = ARRAY_SIZE(alc260_modes), 3814 .channel_mode = alc260_modes, 3815 .input_mux = &alc260_capture_source, 3816 }, 3817 [ALC260_FUJITSU_S702X] = { 3818 .mixers = { alc260_fujitsu_mixer, 3819 alc260_capture_mixer }, 3820 .init_verbs = { alc260_fujitsu_init_verbs }, 3821 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 3822 .dac_nids = alc260_dac_nids, 3823 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids), 3824 .adc_nids = alc260_dual_adc_nids, 3825 .num_channel_mode = ARRAY_SIZE(alc260_modes), 3826 .channel_mode = alc260_modes, 3827 .input_mux = &alc260_fujitsu_capture_source, 3828 }, 3829 [ALC260_ACER] = { 3830 .mixers = { alc260_acer_mixer, 3831 alc260_capture_mixer }, 3832 .init_verbs = { alc260_acer_init_verbs }, 3833 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 3834 .dac_nids = alc260_dac_nids, 3835 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids), 3836 .adc_nids = alc260_dual_adc_nids, 3837 .num_channel_mode = ARRAY_SIZE(alc260_modes), 3838 .channel_mode = alc260_modes, 3839 .input_mux = &alc260_acer_capture_source, 3840 }, 3816 3841 #ifdef CONFIG_SND_DEBUG 3817 [ALC260_TEST] = {3818 .mixers = { alc260_test_mixer,3819 alc260_capture_mixer },3820 .init_verbs = { alc260_test_init_verbs },3821 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),3822 .dac_nids = alc260_test_dac_nids,3823 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),3824 .adc_nids = alc260_test_adc_nids,3825 .num_channel_mode = ARRAY_SIZE(alc260_modes),3826 .channel_mode = alc260_modes,3827 .input_mux = &alc260_test_capture_source,3828 },3842 [ALC260_TEST] = { 3843 .mixers = { alc260_test_mixer, 3844 alc260_capture_mixer }, 3845 .init_verbs = { alc260_test_init_verbs }, 3846 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids), 3847 .dac_nids = alc260_test_dac_nids, 3848 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids), 3849 .adc_nids = alc260_test_adc_nids, 3850 .num_channel_mode = ARRAY_SIZE(alc260_modes), 3851 .channel_mode = alc260_modes, 3852 .input_mux = &alc260_test_capture_source, 3853 }, 3829 3854 #endif 3830 3855 }; … … 3832 3857 static int patch_alc260(struct hda_codec *codec) 3833 3858 { 3834 struct alc_spec *spec;3835 int err, board_config;3836 3837 spec = kzalloc(sizeof(*spec), GFP_KERNEL);3838 if (spec == NULL)3839 return -ENOMEM;3840 3841 codec->spec = spec;3842 3843 board_config = snd_hda_check_board_config(codec, alc260_cfg_tbl);3844 if (board_config < 0 || board_config >= ALC260_MODEL_LAST) {3845 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260\n");3846 board_config = ALC260_AUTO;3847 }3848 3849 if (board_config == ALC260_AUTO) {3850 /* automatic parse from the BIOS config */3851 err = alc260_parse_auto_config(codec);3852 if (err < 0) {3853 alc_free(codec);3854 return err;3855 } else if (! err) {3856 printk(KERN_INFO "hda_codec: Cannot set up configuration from BIOS. Using base mode...\n");3857 board_config = ALC260_BASIC;3858 }3859 }3860 3861 if (board_config != ALC260_AUTO)3862 setup_preset(spec, &alc260_presets[board_config]);3863 3864 spec->stream_name_analog = "ALC260 Analog";3865 spec->stream_analog_playback = &alc260_pcm_analog_playback;3866 spec->stream_analog_capture = &alc260_pcm_analog_capture;3867 3868 spec->stream_name_digital = "ALC260 Digital";3869 spec->stream_digital_playback = &alc260_pcm_digital_playback;3870 spec->stream_digital_capture = &alc260_pcm_digital_capture;3871 3872 codec->patch_ops = alc_patch_ops;3873 if (board_config == ALC260_AUTO)3874 spec->init_hook = alc260_auto_init;3875 3876 return 0;3859 struct alc_spec *spec; 3860 int err, board_config; 3861 3862 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 3863 if (spec == NULL) 3864 return -ENOMEM; 3865 3866 codec->spec = spec; 3867 3868 board_config = snd_hda_check_board_config(codec, alc260_cfg_tbl); 3869 if (board_config < 0 || board_config >= ALC260_MODEL_LAST) { 3870 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260\n"); 3871 board_config = ALC260_AUTO; 3872 } 3873 3874 if (board_config == ALC260_AUTO) { 3875 /* automatic parse from the BIOS config */ 3876 err = alc260_parse_auto_config(codec); 3877 if (err < 0) { 3878 alc_free(codec); 3879 return err; 3880 } else if (! err) { 3881 printk(KERN_INFO "hda_codec: Cannot set up configuration from BIOS. Using base mode...\n"); 3882 board_config = ALC260_BASIC; 3883 } 3884 } 3885 3886 if (board_config != ALC260_AUTO) 3887 setup_preset(spec, &alc260_presets[board_config]); 3888 3889 spec->stream_name_analog = "ALC260 Analog"; 3890 spec->stream_analog_playback = &alc260_pcm_analog_playback; 3891 spec->stream_analog_capture = &alc260_pcm_analog_capture; 3892 3893 spec->stream_name_digital = "ALC260 Digital"; 3894 spec->stream_digital_playback = &alc260_pcm_digital_playback; 3895 spec->stream_digital_capture = &alc260_pcm_digital_capture; 3896 3897 codec->patch_ops = alc_patch_ops; 3898 if (board_config == ALC260_AUTO) 3899 spec->init_hook = alc260_auto_init; 3900 3901 return 0; 3877 3902 } 3878 3903 … … 3893 3918 3894 3919 static struct hda_channel_mode alc882_ch_modes[1] = { 3895 { 8, NULL }3920 { 8, NULL } 3896 3921 }; 3897 3922 3898 3923 static hda_nid_t alc882_dac_nids[4] = { 3899 /* front, rear, clfe, rear_surr */3900 0x02, 0x03, 0x04, 0x053924 /* front, rear, clfe, rear_surr */ 3925 0x02, 0x03, 0x04, 0x05 3901 3926 }; 3902 3927 … … 3909 3934 3910 3935 static struct hda_input_mux alc882_capture_source = { 3911 .num_items = 4,3912 .items = {3913 { "Mic", 0x0 },3914 { "Front Mic", 0x1 },3915 { "Line", 0x2 },3916 { "CD", 0x4 },3917 },3936 .num_items = 4, 3937 .items = { 3938 { "Mic", 0x0 }, 3939 { "Front Mic", 0x1 }, 3940 { "Line", 0x2 }, 3941 { "CD", 0x4 }, 3942 }, 3918 3943 }; 3919 3944 … … 3923 3948 static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 3924 3949 { 3925 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);3926 struct alc_spec *spec = codec->spec;3927 const struct hda_input_mux *imux = spec->input_mux;3928 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);3929 static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };3930 hda_nid_t nid = capture_mixers[adc_idx];3931 unsigned int *cur_val = &spec->cur_mux[adc_idx];3932 unsigned int i, idx;3933 3934 idx = ucontrol->value.enumerated.item[0];3935 if (idx >= imux->num_items)3936 idx = imux->num_items - 1;3937 if (*cur_val == idx && ! codec->in_resume)3938 return 0;3939 for (i = 0; i < imux->num_items; i++) {3940 unsigned int v = (i == idx) ? 0x7000 : 0x7080;3941 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,3942 v | (imux->items[i].index << 8));3943 }3944 *cur_val = idx;3945 return 1;3950 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 3951 struct alc_spec *spec = codec->spec; 3952 const struct hda_input_mux *imux = spec->input_mux; 3953 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 3954 static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 }; 3955 hda_nid_t nid = capture_mixers[adc_idx]; 3956 unsigned int *cur_val = &spec->cur_mux[adc_idx]; 3957 unsigned int i, idx; 3958 3959 idx = ucontrol->value.enumerated.item[0]; 3960 if (idx >= imux->num_items) 3961 idx = imux->num_items - 1; 3962 if (*cur_val == idx && ! codec->in_resume) 3963 return 0; 3964 for (i = 0; i < imux->num_items; i++) { 3965 unsigned int v = (i == idx) ? 0x7000 : 0x7080; 3966 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 3967 v | (imux->items[i].index << 8)); 3968 } 3969 *cur_val = idx; 3970 return 1; 3946 3971 } 3947 3972 … … 3950 3975 */ 3951 3976 static struct hda_verb alc882_sixstack_ch6_init[] = { 3952 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },3953 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },3954 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },3955 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },3956 {0} /* end */3977 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 3978 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 3979 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 3980 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 3981 {0} /* end */ 3957 3982 }; 3958 3983 … … 3961 3986 */ 3962 3987 static struct hda_verb alc882_sixstack_ch8_init[] = { 3963 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },3964 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },3965 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },3966 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },3967 {0} /* end */3988 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 3989 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 3990 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 3991 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 3992 {0} /* end */ 3968 3993 }; 3969 3994 3970 3995 static struct hda_channel_mode alc882_sixstack_modes[2] = { 3971 { 6, alc882_sixstack_ch6_init },3972 { 8, alc882_sixstack_ch8_init },3996 { 6, alc882_sixstack_ch6_init }, 3997 { 8, alc882_sixstack_ch8_init }, 3973 3998 }; 3974 3999 … … 3977 4002 */ 3978 4003 static struct snd_kcontrol_new alc882_base_mixer[] = { 3979 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 3980 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 3981 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 3982 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 3983 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 3984 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 3985 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 3986 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 3987 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 3988 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 3989 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 3990 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 3991 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 3992 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 3993 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 3994 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 3995 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 3996 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 3997 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 3998 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 3999 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 4000 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT), 4001 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT), 4002 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT), 4003 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT), 4004 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT), 4005 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT), 4006 { 4007 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 4008 /* .name = "Capture Source", */ 4009 .name = "Input Source", 4010 .count = 3, 4011 .info = alc882_mux_enum_info, 4012 .get = alc882_mux_enum_get, 4013 .put = alc882_mux_enum_put, 4014 }, 4015 {0} /* end */ 4004 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 4005 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 4006 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 4007 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 4008 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 4009 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 4010 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 4011 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 4012 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 4013 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 4014 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 4015 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 4016 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 4017 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 4018 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 4019 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 4020 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 4021 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 4022 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 4023 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 4024 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 4025 {0} /* end */ 4016 4026 }; 4017 4027 4018 4028 static struct snd_kcontrol_new alc882_chmode_mixer[] = { 4019 {4020 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,4021 .name = "Channel Mode",4022 .info = alc_ch_mode_info,4023 .get = alc_ch_mode_get,4024 .put = alc_ch_mode_put,4025 },4026 {0} /* end */4029 { 4030 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 4031 .name = "Channel Mode", 4032 .info = alc_ch_mode_info, 4033 .get = alc_ch_mode_get, 4034 .put = alc_ch_mode_put, 4035 }, 4036 {0} /* end */ 4027 4037 }; 4028 4038 4029 4039 static struct hda_verb alc882_init_verbs[] = { 4030 /* Front mixer: unmute input/output amp left and right (volume = 0) */4031 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},4032 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},4033 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},4034 /* Rear mixer */4035 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},4036 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},4037 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},4038 /* CLFE mixer */4039 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},4040 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},4041 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},4042 /* Side mixer */4043 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},4044 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},4045 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},4046 4047 /* Front Pin: output 0 (0x0c) */4048 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},4049 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},4050 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},4051 /* Rear Pin: output 1 (0x0d) */4052 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},4053 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},4054 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},4055 /* CLFE Pin: output 2 (0x0e) */4056 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},4057 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},4058 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},4059 /* Side Pin: output 3 (0x0f) */4060 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},4061 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},4062 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},4063 /* Mic (rear) pin: input vref at 80% */4064 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},4065 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},4066 /* Front Mic pin: input vref at 80% */4067 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},4068 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},4069 /* Line In pin: input */4070 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},4071 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},4072 /* Line-2 In: Headphone output (output 0 - 0x0c) */4073 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},4074 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},4075 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},4076 /* CD pin widget for input */4077 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},4078 4079 /* FIXME: use matrix-type input source selection */4080 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */4081 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */4082 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},4083 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},4084 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},4085 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},4086 /* Input mixer2 */4087 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},4088 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},4089 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},4090 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},4091 /* Input mixer3 */4092 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},4093 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},4094 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},4095 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},4096 /* ADC1: mute amp left and right */4097 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},4098 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},4099 /* ADC2: mute amp left and right */4100 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},4101 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},4102 /* ADC3: mute amp left and right */4103 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},4104 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},4105 4106 {0}4040 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 4041 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4042 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4043 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4044 /* Rear mixer */ 4045 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4046 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4047 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4048 /* CLFE mixer */ 4049 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4050 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4051 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4052 /* Side mixer */ 4053 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4054 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4055 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4056 4057 /* Front Pin: output 0 (0x0c) */ 4058 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4059 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4060 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 4061 /* Rear Pin: output 1 (0x0d) */ 4062 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4063 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4064 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 4065 /* CLFE Pin: output 2 (0x0e) */ 4066 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4067 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4068 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, 4069 /* Side Pin: output 3 (0x0f) */ 4070 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4071 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4072 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 4073 /* Mic (rear) pin: input vref at 80% */ 4074 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 4075 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 4076 /* Front Mic pin: input vref at 80% */ 4077 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 4078 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 4079 /* Line In pin: input */ 4080 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 4081 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 4082 /* Line-2 In: Headphone output (output 0 - 0x0c) */ 4083 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 4084 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4085 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 4086 /* CD pin widget for input */ 4087 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 4088 4089 /* FIXME: use matrix-type input source selection */ 4090 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 4091 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 4092 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4093 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 4094 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 4095 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 4096 /* Input mixer2 */ 4097 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4098 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 4099 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 4100 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 4101 /* Input mixer3 */ 4102 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4103 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 4104 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 4105 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 4106 /* ADC1: mute amp left and right */ 4107 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4108 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 4109 /* ADC2: mute amp left and right */ 4110 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4111 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 4112 /* ADC3: mute amp left and right */ 4113 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4114 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 4115 4116 {0} 4107 4117 }; 4108 4118 … … 4111 4121 */ 4112 4122 static struct hda_verb alc882_auto_init_verbs[] = { 4113 /*4114 * Unmute ADC0-2 and set the default input to mic-in4115 */4116 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},4117 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},4118 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},4119 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},4120 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},4121 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},4122 4123 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback4124 * mixer widget4125 * Note: PASD motherboards uses the Line In 2 as the input for front panel4126 * mic (mic 2)4127 */4128 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */4129 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},4130 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},4131 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},4132 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},4133 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},4134 4135 /*4136 * Set up output mixers (0x0c - 0x0f)4137 */4138 /* set vol=0 to output mixers */4139 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},4140 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},4141 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},4142 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},4143 /* set up input amps for analog loopback */4144 /* Amp Indices: DAC = 0, mixer = 1 */4145 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},4146 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},4147 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},4148 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},4149 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},4150 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},4151 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},4152 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},4153 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},4154 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},4155 4156 /* FIXME: use matrix-type input source selection */4157 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */4158 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */4159 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},4160 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},4161 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},4162 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},4163 /* Input mixer2 */4164 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},4165 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},4166 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},4167 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},4168 /* Input mixer3 */4169 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},4170 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},4171 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},4172 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},4173 4174 {0}4123 /* 4124 * Unmute ADC0-2 and set the default input to mic-in 4125 */ 4126 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 4127 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4128 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 4129 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4130 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 4131 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4132 4133 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 4134 * mixer widget 4135 * Note: PASD motherboards uses the Line In 2 as the input for front panel 4136 * mic (mic 2) 4137 */ 4138 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 4139 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4140 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4141 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 4142 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 4143 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 4144 4145 /* 4146 * Set up output mixers (0x0c - 0x0f) 4147 */ 4148 /* set vol=0 to output mixers */ 4149 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4150 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4151 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4152 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4153 /* set up input amps for analog loopback */ 4154 /* Amp Indices: DAC = 0, mixer = 1 */ 4155 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4156 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4157 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4158 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4159 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4160 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4161 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4162 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4163 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4164 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4165 4166 /* FIXME: use matrix-type input source selection */ 4167 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 4168 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 4169 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 4170 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 4171 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 4172 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 4173 /* Input mixer2 */ 4174 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 4175 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 4176 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 4177 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 4178 /* Input mixer3 */ 4179 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 4180 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 4181 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 4182 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 4183 4184 {0} 4175 4185 }; 4176 4186 4177 4187 /* capture mixer elements */ 4178 4188 static struct snd_kcontrol_new alc882_capture_alt_mixer[] = { 4179 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),4180 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),4181 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),4182 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),4183 {4184 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,4185 /* The multiple "Capture Source" controls confuse alsamixer4186 * So call somewhat different..4187 * FIXME: the controls appear in the "playback" view!4188 */4189 /* .name = "Capture Source", */4190 .name = "Input Source",4191 .count = 2,4192 .info = alc882_mux_enum_info,4193 .get = alc882_mux_enum_get,4194 .put = alc882_mux_enum_put,4195 },4196 {0} /* end */4189 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 4190 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 4191 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), 4192 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), 4193 { 4194 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 4195 /* The multiple "Capture Source" controls confuse alsamixer 4196 * So call somewhat different.. 4197 * FIXME: the controls appear in the "playback" view! 4198 */ 4199 /* .name = "Capture Source", */ 4200 .name = "Input Source", 4201 .count = 2, 4202 .info = alc882_mux_enum_info, 4203 .get = alc882_mux_enum_get, 4204 .put = alc882_mux_enum_put, 4205 }, 4206 {0} /* end */ 4197 4207 }; 4198 4208 4199 4209 static struct snd_kcontrol_new alc882_capture_mixer[] = { 4200 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),4201 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),4202 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),4203 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),4204 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),4205 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),4206 {4207 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,4208 /* The multiple "Capture Source" controls confuse alsamixer4209 * So call somewhat different..4210 * FIXME: the controls appear in the "playback" view!4211 */4212 /* .name = "Capture Source", */4213 .name = "Input Source",4214 .count = 3,4215 .info = alc882_mux_enum_info,4216 .get = alc882_mux_enum_get,4217 .put = alc882_mux_enum_put,4218 },4219 {0} /* end */4210 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT), 4211 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT), 4212 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT), 4213 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT), 4214 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT), 4215 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT), 4216 { 4217 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 4218 /* The multiple "Capture Source" controls confuse alsamixer 4219 * So call somewhat different.. 4220 * FIXME: the controls appear in the "playback" view! 4221 */ 4222 /* .name = "Capture Source", */ 4223 .name = "Input Source", 4224 .count = 3, 4225 .info = alc882_mux_enum_info, 4226 .get = alc882_mux_enum_get, 4227 .put = alc882_mux_enum_put, 4228 }, 4229 {0} /* end */ 4220 4230 }; 4221 4231 … … 4230 4240 */ 4231 4241 static struct hda_board_config alc882_cfg_tbl[] = { 4232 { .modelname = "3stack-dig", .config = ALC882_3ST_DIG },4233 { .modelname = "6stack-dig", .config = ALC882_6ST_DIG },4234 { .pci_subvendor = 0x1462, .pci_subdevice = 0x6668, .config = ALC882_6ST_DIG }, /* MSI */4235 { .pci_subvendor = 0x105b, .pci_subdevice = 0x6668, .config = ALC882_6ST_DIG }, /* Foxconn */4236 { .pci_subvendor = 0x1019, .pci_subdevice = 0x6668, .config = ALC882_6ST_DIG }, /* ECS */4237 { .modelname = "auto", .config = ALC882_AUTO },4238 {0}4242 { .modelname = "3stack-dig", .config = ALC882_3ST_DIG }, 4243 { .modelname = "6stack-dig", .config = ALC882_6ST_DIG }, 4244 { .pci_subvendor = 0x1462, .pci_subdevice = 0x6668, .config = ALC882_6ST_DIG }, /* MSI */ 4245 { .pci_subvendor = 0x105b, .pci_subdevice = 0x6668, .config = ALC882_6ST_DIG }, /* Foxconn */ 4246 { .pci_subvendor = 0x1019, .pci_subdevice = 0x6668, .config = ALC882_6ST_DIG }, /* ECS */ 4247 { .modelname = "auto", .config = ALC882_AUTO }, 4248 {0} 4239 4249 }; 4240 4250 4241 4251 static struct alc_config_preset alc882_presets[] = { 4242 [ALC882_3ST_DIG] = { 4243 .mixers = { alc882_base_mixer }, 4244 .init_verbs = { alc882_init_verbs }, 4245 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 4246 .dac_nids = alc882_dac_nids, 4247 .dig_out_nid = ALC882_DIGOUT_NID, 4248 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids), 4249 .adc_nids = alc882_adc_nids, 4250 .dig_in_nid = ALC882_DIGIN_NID, 4251 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), 4252 .channel_mode = alc882_ch_modes, 4253 .input_mux = &alc882_capture_source, 4254 }, 4255 [ALC882_6ST_DIG] = { 4256 .mixers = { alc882_base_mixer, alc882_chmode_mixer }, 4257 .init_verbs = { alc882_init_verbs }, 4258 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 4259 .dac_nids = alc882_dac_nids, 4260 .dig_out_nid = ALC882_DIGOUT_NID, 4261 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids), 4262 .adc_nids = alc882_adc_nids, 4263 .dig_in_nid = ALC882_DIGIN_NID, 4264 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes), 4265 .channel_mode = alc882_sixstack_modes, 4266 .input_mux = &alc882_capture_source, 4267 }, 4252 [ALC882_3ST_DIG] = { 4253 .mixers = { alc882_base_mixer }, 4254 .init_verbs = { alc882_init_verbs }, 4255 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 4256 .dac_nids = alc882_dac_nids, 4257 .dig_out_nid = ALC882_DIGOUT_NID, 4258 .dig_in_nid = ALC882_DIGIN_NID, 4259 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), 4260 .channel_mode = alc882_ch_modes, 4261 .input_mux = &alc882_capture_source, 4262 }, 4263 [ALC882_6ST_DIG] = { 4264 .mixers = { alc882_base_mixer, alc882_chmode_mixer }, 4265 .init_verbs = { alc882_init_verbs }, 4266 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 4267 .dac_nids = alc882_dac_nids, 4268 .dig_out_nid = ALC882_DIGOUT_NID, 4269 .dig_in_nid = ALC882_DIGIN_NID, 4270 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes), 4271 .channel_mode = alc882_sixstack_modes, 4272 .input_mux = &alc882_capture_source, 4273 }, 4268 4274 }; 4269 4275 … … 4273 4279 */ 4274 4280 static void alc882_auto_set_output_and_unmute(struct hda_codec *codec, 4275 hda_nid_t nid, int pin_type,4276 int dac_idx)4277 { 4278 /* set as output */4279 struct alc_spec *spec = codec->spec;4280 int idx;4281 4282 if (spec->multiout.dac_nids[dac_idx] == 0x25)4283 idx = 4;4284 else4285 idx = spec->multiout.dac_nids[dac_idx] - 2;4286 4287 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);4288 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);4289 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);4281 hda_nid_t nid, int pin_type, 4282 int dac_idx) 4283 { 4284 /* set as output */ 4285 struct alc_spec *spec = codec->spec; 4286 int idx; 4287 4288 if (spec->multiout.dac_nids[dac_idx] == 0x25) 4289 idx = 4; 4290 else 4291 idx = spec->multiout.dac_nids[dac_idx] - 2; 4292 4293 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type); 4294 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); 4295 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx); 4290 4296 4291 4297 } … … 4293 4299 static void alc882_auto_init_multi_out(struct hda_codec *codec) 4294 4300 { 4295 struct alc_spec *spec = codec->spec;4296 int i;4297 4298 for (i = 0; i <= HDA_SIDE; i++) {4299 hda_nid_t nid = spec->autocfg.line_out_pins[i];4300 if (nid)4301 alc882_auto_set_output_and_unmute(codec, nid, PIN_OUT, i);4302 }4301 struct alc_spec *spec = codec->spec; 4302 int i; 4303 4304 for (i = 0; i <= HDA_SIDE; i++) { 4305 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 4306 if (nid) 4307 alc882_auto_set_output_and_unmute(codec, nid, PIN_OUT, i); 4308 } 4303 4309 } 4304 4310 4305 4311 static void alc882_auto_init_hp_out(struct hda_codec *codec) 4306 4312 { 4307 struct alc_spec *spec = codec->spec;4308 hda_nid_t pin;4309 4310 pin = spec->autocfg.hp_pin;4311 if (pin) /* connect to front */4312 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); /* use dac 0 */4313 struct alc_spec *spec = codec->spec; 4314 hda_nid_t pin; 4315 4316 pin = spec->autocfg.hp_pin; 4317 if (pin) /* connect to front */ 4318 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); /* use dac 0 */ 4313 4319 } 4314 4320 … … 4318 4324 static void alc882_auto_init_analog_input(struct hda_codec *codec) 4319 4325 { 4320 struct alc_spec *spec = codec->spec;4321 int i;4322 4323 for (i = 0; i < AUTO_PIN_LAST; i++) {4324 hda_nid_t nid = spec->autocfg.input_pins[i];4325 if (alc882_is_input_pin(nid)) {4326 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,4327 i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN);4328 if (nid != ALC882_PIN_CD_NID)4329 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,4330 AMP_OUT_MUTE);4331 }4332 }4326 struct alc_spec *spec = codec->spec; 4327 int i; 4328 4329 for (i = 0; i < AUTO_PIN_LAST; i++) { 4330 hda_nid_t nid = spec->autocfg.input_pins[i]; 4331 if (alc882_is_input_pin(nid)) { 4332 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 4333 i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN); 4334 if (nid != ALC882_PIN_CD_NID) 4335 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 4336 AMP_OUT_MUTE); 4337 } 4338 } 4333 4339 } 4334 4340 … … 4336 4342 static int alc882_parse_auto_config(struct hda_codec *codec) 4337 4343 { 4338 struct alc_spec *spec = codec->spec;4339 int err = alc880_parse_auto_config(codec);4340 4341 if (err < 0)4342 return err;4343 else if (err > 0)4344 /* hack - override the init verbs */4345 spec->init_verbs[0] = alc882_auto_init_verbs;4346 return err;4344 struct alc_spec *spec = codec->spec; 4345 int err = alc880_parse_auto_config(codec); 4346 4347 if (err < 0) 4348 return err; 4349 else if (err > 0) 4350 /* hack - override the init verbs */ 4351 spec->init_verbs[0] = alc882_auto_init_verbs; 4352 return err; 4347 4353 } 4348 4354 … … 4355 4361 } 4356 4362 4357 /*4358 * ALC882 Headphone poll in 3.5.1a or 3.5.24359 */4360 4361 4363 static int patch_alc882(struct hda_codec *codec) 4362 4364 { 4363 struct alc_spec *spec; 4364 int err, board_config; 4365 4366 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 4367 if (spec == NULL) 4368 return -ENOMEM; 4369 4370 codec->spec = spec; 4371 4372 board_config = snd_hda_check_board_config(codec, alc882_cfg_tbl); 4373 4374 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) { 4375 printk(KERN_INFO "hda_codec: Unknown model for ALC882, trying auto-probe from BIOS...\n"); 4376 board_config = ALC882_AUTO; 4377 } 4378 4379 if (board_config == ALC882_AUTO) { 4380 /* automatic parse from the BIOS config */ 4381 err = alc882_parse_auto_config(codec); 4382 if (err < 0) { 4383 alc_free(codec); 4384 return err; 4385 } else if (! err) { 4386 printk(KERN_INFO "hda_codec: Cannot set up configuration from BIOS. Using base mode...\n"); 4387 board_config = ALC882_3ST_DIG; 4388 } 4389 } 4390 4391 if (board_config != ALC882_AUTO) 4392 setup_preset(spec, &alc882_presets[board_config]); 4393 4394 spec->stream_name_analog = "ALC882 Analog"; 4395 spec->stream_analog_playback = &alc882_pcm_analog_playback; 4396 spec->stream_analog_capture = &alc882_pcm_analog_capture; 4397 4398 spec->stream_name_digital = "ALC882 Digital"; 4399 spec->stream_digital_playback = &alc882_pcm_digital_playback; 4400 spec->stream_digital_capture = &alc882_pcm_digital_capture; 4401 4402 if (! spec->adc_nids && spec->input_mux) { 4403 /* check whether NID 0x07 is valid */ 4404 unsigned int wcap = get_wcaps(codec, 0x07); 4405 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */ 4406 if (wcap != AC_WID_AUD_IN) { 4407 spec->adc_nids = alc882_adc_nids_alt; 4408 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt); 4409 spec->mixers[spec->num_mixers] = alc882_capture_alt_mixer; 4410 spec->num_mixers++; 4411 } else { 4412 spec->adc_nids = alc882_adc_nids; 4413 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids); 4414 spec->mixers[spec->num_mixers] = alc882_capture_mixer; 4415 spec->num_mixers++; 4416 } 4417 } 4418 4419 codec->patch_ops = alc_patch_ops; 4420 if (board_config == ALC882_AUTO) 4421 spec->init_hook = alc882_auto_init; 4422 4423 return 0; 4365 struct alc_spec *spec; 4366 int err, board_config; 4367 4368 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 4369 if (spec == NULL) 4370 return -ENOMEM; 4371 4372 codec->spec = spec; 4373 4374 board_config = snd_hda_check_board_config(codec, alc882_cfg_tbl); 4375 4376 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) { 4377 printk(KERN_INFO "hda_codec: Unknown model for ALC882, trying auto-probe from BIOS...\n"); 4378 board_config = ALC882_AUTO; 4379 } 4380 4381 if (board_config == ALC882_AUTO) { 4382 /* automatic parse from the BIOS config */ 4383 err = alc882_parse_auto_config(codec); 4384 if (err < 0) { 4385 alc_free(codec); 4386 return err; 4387 } else if (! err) { 4388 printk(KERN_INFO "hda_codec: Cannot set up configuration from BIOS. Using base mode...\n"); 4389 board_config = ALC882_3ST_DIG; 4390 } 4391 } 4392 4393 if (board_config != ALC882_AUTO) 4394 setup_preset(spec, &alc882_presets[board_config]); 4395 4396 spec->stream_name_analog = "ALC882 Analog"; 4397 spec->stream_analog_playback = &alc882_pcm_analog_playback; 4398 spec->stream_analog_capture = &alc882_pcm_analog_capture; 4399 4400 spec->stream_name_digital = "ALC882 Digital"; 4401 spec->stream_digital_playback = &alc882_pcm_digital_playback; 4402 spec->stream_digital_capture = &alc882_pcm_digital_capture; 4403 4404 if (! spec->adc_nids && spec->input_mux) { 4405 /* check whether NID 0x07 is valid */ 4406 unsigned int wcap = get_wcaps(codec, 0x07); 4407 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */ 4408 if (wcap != AC_WID_AUD_IN) { 4409 spec->adc_nids = alc882_adc_nids_alt; 4410 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt); 4411 spec->mixers[spec->num_mixers] = alc882_capture_alt_mixer; 4412 spec->num_mixers++; 4413 } else { 4414 spec->adc_nids = alc882_adc_nids; 4415 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids); 4416 spec->mixers[spec->num_mixers] = alc882_capture_mixer; 4417 spec->num_mixers++; 4418 } 4419 } 4420 4421 codec->patch_ops = alc_patch_ops; 4422 if (board_config == ALC882_AUTO) 4423 spec->init_hook = alc882_auto_init; 4424 4425 return 0; 4426 } 4427 4428 /* 4429 * ALC883 support 4430 * 4431 * ALC883 is almost identical with ALC880 but has cleaner and more flexible 4432 * configuration. Each pin widget can choose any input DACs and a mixer. 4433 * Each ADC is connected from a mixer of all inputs. This makes possible 4434 * 6-channel independent captures. 4435 * 4436 * In addition, an independent DAC for the multi-playback (not used in this 4437 * driver yet). 4438 */ 4439 #define ALC883_DIGOUT_NID 0x06 4440 #define ALC883_DIGIN_NID 0x0a 4441 4442 static hda_nid_t alc883_dac_nids[4] = { 4443 /* front, rear, clfe, rear_surr */ 4444 0x02, 0x04, 0x03, 0x05 4445 }; 4446 4447 static hda_nid_t alc883_adc_nids[2] = { 4448 /* ADC1-2 */ 4449 0x08, 0x09, 4450 }; 4451 /* input MUX */ 4452 /* FIXME: should be a matrix-type input source selection */ 4453 4454 static struct hda_input_mux alc883_capture_source = { 4455 .num_items = 4, 4456 .items = { 4457 { "Mic", 0x0 }, 4458 { "Front Mic", 0x1 }, 4459 { "Line", 0x2 }, 4460 { "CD", 0x4 }, 4461 }, 4462 }; 4463 #define alc883_mux_enum_info alc_mux_enum_info 4464 #define alc883_mux_enum_get alc_mux_enum_get 4465 4466 static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol, 4467 struct snd_ctl_elem_value *ucontrol) 4468 { 4469 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 4470 struct alc_spec *spec = codec->spec; 4471 const struct hda_input_mux *imux = spec->input_mux; 4472 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 4473 static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 }; 4474 hda_nid_t nid = capture_mixers[adc_idx]; 4475 unsigned int *cur_val = &spec->cur_mux[adc_idx]; 4476 unsigned int i, idx; 4477 4478 idx = ucontrol->value.enumerated.item[0]; 4479 if (idx >= imux->num_items) 4480 idx = imux->num_items - 1; 4481 if (*cur_val == idx && ! codec->in_resume) 4482 return 0; 4483 for (i = 0; i < imux->num_items; i++) { 4484 unsigned int v = (i == idx) ? 0x7000 : 0x7080; 4485 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 4486 v | (imux->items[i].index << 8)); 4487 } 4488 *cur_val = idx; 4489 return 1; 4490 } 4491 /* 4492 * 2ch mode 4493 */ 4494 static struct hda_channel_mode alc883_3ST_2ch_modes[1] = { 4495 { 2, NULL } 4496 }; 4497 4498 /* 4499 * 2ch mode 4500 */ 4501 static struct hda_verb alc883_3ST_ch2_init[] = { 4502 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 4503 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 4504 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 4505 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 4506 {0} /* end */ 4507 }; 4508 4509 /* 4510 * 6ch mode 4511 */ 4512 static struct hda_verb alc883_3ST_ch6_init[] = { 4513 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 4514 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 4515 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 4516 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 4517 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 4518 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 4519 {0} /* end */ 4520 }; 4521 4522 static struct hda_channel_mode alc883_3ST_6ch_modes[2] = { 4523 { 2, alc883_3ST_ch2_init }, 4524 { 6, alc883_3ST_ch6_init }, 4525 }; 4526 4527 /* 4528 * 6ch mode 4529 */ 4530 static struct hda_verb alc883_sixstack_ch6_init[] = { 4531 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 4532 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 4533 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 4534 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 4535 {0} /* end */ 4536 }; 4537 4538 /* 4539 * 8ch mode 4540 */ 4541 static struct hda_verb alc883_sixstack_ch8_init[] = { 4542 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 4543 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 4544 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 4545 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 4546 {0} /* end */ 4547 }; 4548 4549 static struct hda_channel_mode alc883_sixstack_modes[2] = { 4550 { 6, alc883_sixstack_ch6_init }, 4551 { 8, alc883_sixstack_ch8_init }, 4552 }; 4553 4554 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 4555 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b 4556 */ 4557 4558 static struct snd_kcontrol_new alc883_base_mixer[] = { 4559 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 4560 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 4561 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 4562 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 4563 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 4564 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 4565 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 4566 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 4567 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 4568 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 4569 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 4570 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 4571 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 4572 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 4573 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 4574 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 4575 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 4576 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 4577 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 4578 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 4579 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 4580 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 4581 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 4582 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), 4583 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), 4584 { 4585 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 4586 /* .name = "Capture Source", */ 4587 .name = "Input Source", 4588 .count = 2, 4589 .info = alc883_mux_enum_info, 4590 .get = alc883_mux_enum_get, 4591 .put = alc883_mux_enum_put, 4592 }, 4593 {0} /* end */ 4594 }; 4595 4596 static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = { 4597 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 4598 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 4599 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 4600 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 4601 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 4602 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 4603 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 4604 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 4605 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 4606 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 4607 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 4608 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 4609 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 4610 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 4611 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 4612 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), 4613 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), 4614 { 4615 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 4616 /* .name = "Capture Source", */ 4617 .name = "Input Source", 4618 .count = 2, 4619 .info = alc883_mux_enum_info, 4620 .get = alc883_mux_enum_get, 4621 .put = alc883_mux_enum_put, 4622 }, 4623 {0} /* end */ 4624 }; 4625 4626 static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = { 4627 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 4628 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 4629 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 4630 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 4631 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 4632 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 4633 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 4634 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 4635 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 4636 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 4637 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 4638 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 4639 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 4640 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 4641 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 4642 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 4643 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 4644 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 4645 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 4646 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 4647 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 4648 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), 4649 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), 4650 { 4651 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 4652 /* .name = "Capture Source", */ 4653 .name = "Input Source", 4654 .count = 2, 4655 .info = alc883_mux_enum_info, 4656 .get = alc883_mux_enum_get, 4657 .put = alc883_mux_enum_put, 4658 }, 4659 {0} /* end */ 4660 }; 4661 4662 static struct snd_kcontrol_new alc883_chmode_mixer[] = { 4663 { 4664 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 4665 .name = "Channel Mode", 4666 .info = alc_ch_mode_info, 4667 .get = alc_ch_mode_get, 4668 .put = alc_ch_mode_put, 4669 }, 4670 {0} /* end */ 4671 }; 4672 4673 static struct hda_verb alc883_init_verbs[] = { 4674 /* ADC1: mute amp left and right */ 4675 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4676 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 4677 /* ADC2: mute amp left and right */ 4678 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4679 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 4680 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 4681 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4682 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4683 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4684 /* Rear mixer */ 4685 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4686 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4687 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4688 /* CLFE mixer */ 4689 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4690 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4691 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4692 /* Side mixer */ 4693 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4694 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4695 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4696 4697 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4698 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4699 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 4700 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 4701 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 4702 4703 /* Front Pin: output 0 (0x0c) */ 4704 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4705 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4706 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 4707 /* Rear Pin: output 1 (0x0d) */ 4708 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4709 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4710 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 4711 /* CLFE Pin: output 2 (0x0e) */ 4712 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4713 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4714 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, 4715 /* Side Pin: output 3 (0x0f) */ 4716 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4717 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4718 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 4719 /* Mic (rear) pin: input vref at 80% */ 4720 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 4721 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 4722 /* Front Mic pin: input vref at 80% */ 4723 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 4724 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 4725 /* Line In pin: input */ 4726 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 4727 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 4728 /* Line-2 In: Headphone output (output 0 - 0x0c) */ 4729 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 4730 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4731 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 4732 /* CD pin widget for input */ 4733 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 4734 4735 /* FIXME: use matrix-type input source selection */ 4736 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 4737 /* Input mixer2 */ 4738 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4739 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4740 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 4741 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 4742 /* Input mixer3 */ 4743 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4744 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4745 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 4746 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 4747 {0} 4748 }; 4749 4750 /* 4751 * generic initialization of ADC, input mixers and output mixers 4752 */ 4753 static struct hda_verb alc883_auto_init_verbs[] = { 4754 /* 4755 * Unmute ADC0-2 and set the default input to mic-in 4756 */ 4757 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 4758 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4759 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 4760 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4761 4762 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 4763 * mixer widget 4764 * Note: PASD motherboards uses the Line In 2 as the input for front panel 4765 * mic (mic 2) 4766 */ 4767 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 4768 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4769 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4770 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 4771 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 4772 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 4773 4774 /* 4775 * Set up output mixers (0x0c - 0x0f) 4776 */ 4777 /* set vol=0 to output mixers */ 4778 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4779 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4780 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4781 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4782 /* set up input amps for analog loopback */ 4783 /* Amp Indices: DAC = 0, mixer = 1 */ 4784 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4785 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4786 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4787 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4788 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4789 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4790 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4791 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4792 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4793 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4794 4795 /* FIXME: use matrix-type input source selection */ 4796 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 4797 /* Input mixer1 */ 4798 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4799 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4800 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 4801 //{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 4802 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 4803 /* Input mixer2 */ 4804 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4805 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4806 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 4807 //{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 4808 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 4809 4810 {0} 4811 }; 4812 4813 /* capture mixer elements */ 4814 static struct snd_kcontrol_new alc883_capture_mixer[] = { 4815 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 4816 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 4817 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), 4818 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), 4819 { 4820 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 4821 /* The multiple "Capture Source" controls confuse alsamixer 4822 * So call somewhat different.. 4823 * FIXME: the controls appear in the "playback" view! 4824 */ 4825 /* .name = "Capture Source", */ 4826 .name = "Input Source", 4827 .count = 2, 4828 .info = alc882_mux_enum_info, 4829 .get = alc882_mux_enum_get, 4830 .put = alc882_mux_enum_put, 4831 }, 4832 {0} /* end */ 4833 }; 4834 4835 /* pcm configuration: identiacal with ALC880 */ 4836 #define alc883_pcm_analog_playback alc880_pcm_analog_playback 4837 #define alc883_pcm_analog_capture alc880_pcm_analog_capture 4838 #define alc883_pcm_digital_playback alc880_pcm_digital_playback 4839 #define alc883_pcm_digital_capture alc880_pcm_digital_capture 4840 4841 /* 4842 * configuration and preset 4843 */ 4844 static struct hda_board_config alc883_cfg_tbl[] = { 4845 { .modelname = "3stack-dig", .config = ALC883_3ST_2ch_DIG }, 4846 { .modelname = "6stack-dig", .config = ALC883_6ST_DIG }, 4847 { .modelname = "6stack-dig-demo", .config = ALC888_DEMO_BOARD }, 4848 { .pci_subvendor = 0x1462, .pci_subdevice = 0x6668, 4849 .config = ALC883_6ST_DIG }, /* MSI */ 4850 { .pci_subvendor = 0x105b, .pci_subdevice = 0x6668, 4851 .config = ALC883_6ST_DIG }, /* Foxconn */ 4852 { .pci_subvendor = 0x1019, .pci_subdevice = 0x6668, 4853 .config = ALC883_3ST_6ch_DIG }, /* ECS to Intel*/ 4854 { .pci_subvendor = 0x108e, .pci_subdevice = 0x534d, 4855 .config = ALC883_3ST_6ch }, 4856 { .modelname = "auto", .config = ALC883_AUTO }, 4857 {0} 4858 }; 4859 4860 static struct alc_config_preset alc883_presets[] = { 4861 [ALC883_3ST_2ch_DIG] = { 4862 .mixers = { alc883_3ST_2ch_mixer }, 4863 .init_verbs = { alc883_init_verbs }, 4864 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 4865 .dac_nids = alc883_dac_nids, 4866 .dig_out_nid = ALC883_DIGOUT_NID, 4867 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 4868 .adc_nids = alc883_adc_nids, 4869 .dig_in_nid = ALC883_DIGIN_NID, 4870 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 4871 .channel_mode = alc883_3ST_2ch_modes, 4872 .input_mux = &alc883_capture_source, 4873 }, 4874 [ALC883_3ST_6ch_DIG] = { 4875 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 4876 .init_verbs = { alc883_init_verbs }, 4877 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 4878 .dac_nids = alc883_dac_nids, 4879 .dig_out_nid = ALC883_DIGOUT_NID, 4880 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 4881 .adc_nids = alc883_adc_nids, 4882 .dig_in_nid = ALC883_DIGIN_NID, 4883 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 4884 .channel_mode = alc883_3ST_6ch_modes, 4885 .input_mux = &alc883_capture_source, 4886 }, 4887 [ALC883_3ST_6ch] = { 4888 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 4889 .init_verbs = { alc883_init_verbs }, 4890 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 4891 .dac_nids = alc883_dac_nids, 4892 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 4893 .adc_nids = alc883_adc_nids, 4894 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 4895 .channel_mode = alc883_3ST_6ch_modes, 4896 .input_mux = &alc883_capture_source, 4897 }, 4898 [ALC883_6ST_DIG] = { 4899 .mixers = { alc883_base_mixer, alc883_chmode_mixer }, 4900 .init_verbs = { alc883_init_verbs }, 4901 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 4902 .dac_nids = alc883_dac_nids, 4903 .dig_out_nid = ALC883_DIGOUT_NID, 4904 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 4905 .adc_nids = alc883_adc_nids, 4906 .dig_in_nid = ALC883_DIGIN_NID, 4907 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 4908 .channel_mode = alc883_sixstack_modes, 4909 .input_mux = &alc883_capture_source, 4910 }, 4911 [ALC888_DEMO_BOARD] = { 4912 .mixers = { alc883_base_mixer, alc883_chmode_mixer }, 4913 .init_verbs = { alc883_init_verbs }, 4914 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 4915 .dac_nids = alc883_dac_nids, 4916 .dig_out_nid = ALC883_DIGOUT_NID, 4917 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 4918 .adc_nids = alc883_adc_nids, 4919 .dig_in_nid = ALC883_DIGIN_NID, 4920 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 4921 .channel_mode = alc883_sixstack_modes, 4922 .input_mux = &alc883_capture_source, 4923 }, 4924 }; 4925 4926 4927 /* 4928 * BIOS auto configuration 4929 */ 4930 static void alc883_auto_set_output_and_unmute(struct hda_codec *codec, 4931 hda_nid_t nid, int pin_type, 4932 int dac_idx) 4933 { 4934 /* set as output */ 4935 struct alc_spec *spec = codec->spec; 4936 int idx; 4937 4938 if (spec->multiout.dac_nids[dac_idx] == 0x25) 4939 idx = 4; 4940 else 4941 idx = spec->multiout.dac_nids[dac_idx] - 2; 4942 4943 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 4944 pin_type); 4945 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 4946 AMP_OUT_UNMUTE); 4947 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx); 4948 4949 } 4950 4951 static void alc883_auto_init_multi_out(struct hda_codec *codec) 4952 { 4953 struct alc_spec *spec = codec->spec; 4954 int i; 4955 4956 for (i = 0; i <= HDA_SIDE; i++) { 4957 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 4958 if (nid) 4959 alc883_auto_set_output_and_unmute(codec, nid, PIN_OUT, i); 4960 } 4961 } 4962 4963 static void alc883_auto_init_hp_out(struct hda_codec *codec) 4964 { 4965 struct alc_spec *spec = codec->spec; 4966 hda_nid_t pin; 4967 4968 pin = spec->autocfg.hp_pin; 4969 if (pin) /* connect to front */ 4970 /* use dac 0 */ 4971 alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 4972 } 4973 4974 #define alc883_is_input_pin(nid) alc880_is_input_pin(nid) 4975 #define ALC883_PIN_CD_NID ALC880_PIN_CD_NID 4976 4977 static void alc883_auto_init_analog_input(struct hda_codec *codec) 4978 { 4979 struct alc_spec *spec = codec->spec; 4980 int i; 4981 4982 for (i = 0; i < AUTO_PIN_LAST; i++) { 4983 hda_nid_t nid = spec->autocfg.input_pins[i]; 4984 if (alc883_is_input_pin(nid)) { 4985 snd_hda_codec_write(codec, nid, 0, 4986 AC_VERB_SET_PIN_WIDGET_CONTROL, 4987 (i <= AUTO_PIN_FRONT_MIC ? 4988 PIN_VREF80 : PIN_IN)); 4989 if (nid != ALC883_PIN_CD_NID) 4990 snd_hda_codec_write(codec, nid, 0, 4991 AC_VERB_SET_AMP_GAIN_MUTE, 4992 AMP_OUT_MUTE); 4993 } 4994 } 4995 } 4996 4997 /* almost identical with ALC880 parser... */ 4998 static int alc883_parse_auto_config(struct hda_codec *codec) 4999 { 5000 struct alc_spec *spec = codec->spec; 5001 int err = alc880_parse_auto_config(codec); 5002 5003 if (err < 0) 5004 return err; 5005 else if (err > 0) 5006 /* hack - override the init verbs */ 5007 spec->init_verbs[0] = alc883_auto_init_verbs; 5008 spec->mixers[spec->num_mixers] = alc883_capture_mixer; 5009 spec->num_mixers++; 5010 return err; 5011 } 5012 5013 /* additional initialization for auto-configuration model */ 5014 static void alc883_auto_init(struct hda_codec *codec) 5015 { 5016 alc883_auto_init_multi_out(codec); 5017 alc883_auto_init_hp_out(codec); 5018 alc883_auto_init_analog_input(codec); 5019 } 5020 5021 static int patch_alc883(struct hda_codec *codec) 5022 { 5023 struct alc_spec *spec; 5024 int err, board_config; 5025 5026 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 5027 if (spec == NULL) 5028 return -ENOMEM; 5029 5030 codec->spec = spec; 5031 5032 board_config = snd_hda_check_board_config(codec, alc883_cfg_tbl); 5033 if (board_config < 0 || board_config >= ALC883_MODEL_LAST) { 5034 printk(KERN_INFO "hda_codec: Unknown model for ALC883, " 5035 "trying auto-probe from BIOS...\n"); 5036 board_config = ALC883_AUTO; 5037 } 5038 5039 if (board_config == ALC883_AUTO) { 5040 /* automatic parse from the BIOS config */ 5041 err = alc883_parse_auto_config(codec); 5042 if (err < 0) { 5043 alc_free(codec); 5044 return err; 5045 } else if (! err) { 5046 printk(KERN_INFO 5047 "hda_codec: Cannot set up configuration " 5048 "from BIOS. Using base mode...\n"); 5049 board_config = ALC883_3ST_2ch_DIG; 5050 } 5051 } 5052 5053 if (board_config != ALC883_AUTO) 5054 setup_preset(spec, &alc883_presets[board_config]); 5055 5056 spec->stream_name_analog = "ALC883 Analog"; 5057 spec->stream_analog_playback = &alc883_pcm_analog_playback; 5058 spec->stream_analog_capture = &alc883_pcm_analog_capture; 5059 5060 spec->stream_name_digital = "ALC883 Digital"; 5061 spec->stream_digital_playback = &alc883_pcm_digital_playback; 5062 spec->stream_digital_capture = &alc883_pcm_digital_capture; 5063 5064 spec->adc_nids = alc883_adc_nids; 5065 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids); 5066 5067 codec->patch_ops = alc_patch_ops; 5068 if (board_config == ALC883_AUTO) 5069 spec->init_hook = alc883_auto_init; 5070 return 0; 4424 5071 } 4425 5072 … … 4439 5086 4440 5087 static struct snd_kcontrol_new alc262_base_mixer[] = { 4441 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 4442 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 4443 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 4444 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 4445 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 4446 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 4447 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 4448 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 4449 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 4450 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 4451 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT), 4452 HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */ 4453 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT), 4454 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 4455 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 4456 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT), 4457 {0} /* end */ 5088 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 5089 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 5090 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 5091 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 5092 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 5093 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 5094 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 5095 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 5096 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 5097 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 5098 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT), 5099 HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */ 5100 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT), 5101 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 5102 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 5103 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT), 5104 {0} /* end */ 5105 }; 5106 5107 static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = { 5108 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 5109 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT), 5110 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 5111 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 5112 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT), 5113 5114 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 5115 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 5116 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 5117 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 5118 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 5119 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 5120 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 5121 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 5122 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT), 5123 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), 5124 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT), 5125 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT), 5126 {0} /* end */ 4458 5127 }; 4459 5128 … … 4465 5134 */ 4466 5135 static struct hda_verb alc262_init_verbs[] = { 4467 /*4468 * Unmute ADC0-2 and set the default input to mic-in4469 */4470 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},4471 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},4472 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},4473 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},4474 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},4475 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},4476 4477 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback4478 * mixer widget4479 * Note: PASD motherboards uses the Line In 2 as the input for front panel4480 * mic (mic 2)4481 */4482 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */4483 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},4484 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},4485 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},4486 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},4487 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},4488 4489 /*4490 * Set up output mixers (0x0c - 0x0e)4491 */4492 /* set vol=0 to output mixers */4493 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},4494 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},4495 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},4496 /* set up input amps for analog loopback */4497 /* Amp Indices: DAC = 0, mixer = 1 */4498 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},4499 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},4500 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},4501 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},4502 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},4503 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},4504 4505 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},4506 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},4507 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},4508 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},4509 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},4510 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},4511 4512 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},4513 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},4514 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},4515 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},4516 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},4517 4518 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},4519 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},4520 4521 /* FIXME: use matrix-type input source selection */4522 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */4523 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */4524 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},4525 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},4526 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},4527 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},4528 /* Input mixer2 */4529 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},4530 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},4531 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},4532 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},4533 /* Input mixer3 */4534 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},4535 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},4536 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},4537 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},4538 4539 {0}5136 /* 5137 * Unmute ADC0-2 and set the default input to mic-in 5138 */ 5139 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 5140 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5141 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 5142 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5143 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 5144 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5145 5146 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 5147 * mixer widget 5148 * Note: PASD motherboards uses the Line In 2 as the input for front panel 5149 * mic (mic 2) 5150 */ 5151 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 5152 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5153 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5154 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 5155 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 5156 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 5157 5158 /* 5159 * Set up output mixers (0x0c - 0x0e) 5160 */ 5161 /* set vol=0 to output mixers */ 5162 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5163 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5164 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5165 /* set up input amps for analog loopback */ 5166 /* Amp Indices: DAC = 0, mixer = 1 */ 5167 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5168 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5169 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5170 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5171 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5172 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5173 5174 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 5175 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 5176 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 5177 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 5178 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 5179 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 5180 5181 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 5182 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 5183 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 5184 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 5185 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 5186 5187 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 5188 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 5189 5190 /* FIXME: use matrix-type input source selection */ 5191 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 5192 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 5193 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 5194 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 5195 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 5196 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 5197 /* Input mixer2 */ 5198 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 5199 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 5200 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 5201 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 5202 /* Input mixer3 */ 5203 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 5204 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 5205 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 5206 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 5207 5208 {0} 4540 5209 }; 4541 5210 … … 4548 5217 4549 5218 static struct hda_verb alc262_fujitsu_unsol_verbs[] = { 4550 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},4551 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},4552 {0}5219 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, 5220 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 5221 {0} 4553 5222 }; 4554 5223 4555 5224 static struct hda_input_mux alc262_fujitsu_capture_source = { 4556 .num_items = 2, 4557 .items = { 4558 { "Mic", 0x0 }, 4559 { "CD", 0x4 }, 4560 }, 5225 .num_items = 2, 5226 .items = { 5227 { "Mic", 0x0 }, 5228 { "CD", 0x4 }, 5229 }, 5230 }; 5231 5232 static struct hda_input_mux alc262_HP_capture_source = { 5233 .num_items = 5, 5234 .items = { 5235 { "Mic", 0x0 }, 5236 { "Front Mic", 0x3 }, 5237 { "Line", 0x2 }, 5238 { "CD", 0x4 }, 5239 { "AUX IN", 0x6 }, 5240 }, 4561 5241 }; 4562 5242 … … 4564 5244 static void alc262_fujitsu_automute(struct hda_codec *codec, int force) 4565 5245 { 4566 struct alc_spec *spec = codec->spec;4567 unsigned int mute;4568 4569 if (force || ! spec->sense_updated) {4570 unsigned int present;4571 /* need to execute and sync at first */4572 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);4573 present = snd_hda_codec_read(codec, 0x14, 0,4574 AC_VERB_GET_PIN_SENSE, 0);4575 spec->jack_present = (present & 0x80000000) != 0;4576 spec->sense_updated = 1;4577 }4578 if (spec->jack_present) {4579 /* mute internal speaker */4580 snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,4581 0x80, 0x80);4582 snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,4583 0x80, 0x80);4584 } else {4585 /* unmute internal speaker if necessary */4586 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);4587 snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,4588 0x80, mute & 0x80);4589 mute = snd_hda_codec_amp_read(codec, 0x14, 1, HDA_OUTPUT, 0);4590 snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,4591 0x80, mute & 0x80);4592 }5246 struct alc_spec *spec = codec->spec; 5247 unsigned int mute; 5248 5249 if (force || ! spec->sense_updated) { 5250 unsigned int present; 5251 /* need to execute and sync at first */ 5252 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0); 5253 present = snd_hda_codec_read(codec, 0x14, 0, 5254 AC_VERB_GET_PIN_SENSE, 0); 5255 spec->jack_present = (present & 0x80000000) != 0; 5256 spec->sense_updated = 1; 5257 } 5258 if (spec->jack_present) { 5259 /* mute internal speaker */ 5260 snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0, 5261 0x80, 0x80); 5262 snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0, 5263 0x80, 0x80); 5264 } else { 5265 /* unmute internal speaker if necessary */ 5266 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0); 5267 snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0, 5268 0x80, mute & 0x80); 5269 mute = snd_hda_codec_amp_read(codec, 0x14, 1, HDA_OUTPUT, 0); 5270 snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0, 5271 0x80, mute & 0x80); 5272 } 4593 5273 } 4594 5274 4595 5275 /* unsolicited event for HP jack sensing */ 4596 5276 static void alc262_fujitsu_unsol_event(struct hda_codec *codec, 4597 unsigned int res)4598 { 4599 if ((res >> 26) != ALC_HP_EVENT)4600 return;4601 alc262_fujitsu_automute(codec, 1);5277 unsigned int res) 5278 { 5279 if ((res >> 26) != ALC_HP_EVENT) 5280 return; 5281 alc262_fujitsu_automute(codec, 1); 4602 5282 } 4603 5283 4604 5284 /* bind volumes of both NID 0x0c and 0x0d */ 4605 5285 static int alc262_fujitsu_master_vol_put(struct snd_kcontrol *kcontrol, 4606 struct snd_ctl_elem_value *ucontrol)4607 { 4608 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);4609 long *valp = ucontrol->value.integer.value;4610 int change;4611 4612 change = snd_hda_codec_amp_update(codec, 0x0c, 0, HDA_OUTPUT, 0,4613 0x7f, valp[0] & 0x7f);4614 change |= snd_hda_codec_amp_update(codec, 0x0c, 1, HDA_OUTPUT, 0,4615 0x7f, valp[1] & 0x7f);4616 snd_hda_codec_amp_update(codec, 0x0d, 0, HDA_OUTPUT, 0,4617 0x7f, valp[0] & 0x7f);4618 snd_hda_codec_amp_update(codec, 0x0d, 1, HDA_OUTPUT, 0,4619 0x7f, valp[1] & 0x7f);4620 return change;5286 struct snd_ctl_elem_value *ucontrol) 5287 { 5288 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 5289 long *valp = ucontrol->value.integer.value; 5290 int change; 5291 5292 change = snd_hda_codec_amp_update(codec, 0x0c, 0, HDA_OUTPUT, 0, 5293 0x7f, valp[0] & 0x7f); 5294 change |= snd_hda_codec_amp_update(codec, 0x0c, 1, HDA_OUTPUT, 0, 5295 0x7f, valp[1] & 0x7f); 5296 snd_hda_codec_amp_update(codec, 0x0d, 0, HDA_OUTPUT, 0, 5297 0x7f, valp[0] & 0x7f); 5298 snd_hda_codec_amp_update(codec, 0x0d, 1, HDA_OUTPUT, 0, 5299 0x7f, valp[1] & 0x7f); 5300 return change; 4621 5301 } 4622 5302 4623 5303 /* bind hp and internal speaker mute (with plug check) */ 4624 5304 static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol, 4625 struct snd_ctl_elem_value *ucontrol)4626 { 4627 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);4628 long *valp = ucontrol->value.integer.value;4629 int change;4630 4631 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,4632 0x80, valp[0] ? 0 : 0x80);4633 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,4634 0x80, valp[1] ? 0 : 0x80);4635 if (change || codec->in_resume)4636 alc262_fujitsu_automute(codec, codec->in_resume);4637 return change;5305 struct snd_ctl_elem_value *ucontrol) 5306 { 5307 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 5308 long *valp = ucontrol->value.integer.value; 5309 int change; 5310 5311 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0, 5312 0x80, valp[0] ? 0 : 0x80); 5313 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0, 5314 0x80, valp[1] ? 0 : 0x80); 5315 if (change || codec->in_resume) 5316 alc262_fujitsu_automute(codec, codec->in_resume); 5317 return change; 4638 5318 } 4639 5319 4640 5320 static struct snd_kcontrol_new alc262_fujitsu_mixer[] = { 4641 {4642 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,4643 .name = "Master Playback Volume",4644 .info = snd_hda_mixer_amp_volume_info,4645 .get = snd_hda_mixer_amp_volume_get,4646 .put = alc262_fujitsu_master_vol_put,4647 .private_value = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),4648 },4649 {4650 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,4651 .name = "Master Playback Switch",4652 .info = snd_hda_mixer_amp_switch_info,4653 .get = snd_hda_mixer_amp_switch_get,4654 .put = alc262_fujitsu_master_sw_put,4655 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),4656 },4657 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),4658 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),4659 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),4660 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),4661 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),4662 {0} /* end */5321 { 5322 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 5323 .name = "Master Playback Volume", 5324 .info = snd_hda_mixer_amp_volume_info, 5325 .get = snd_hda_mixer_amp_volume_get, 5326 .put = alc262_fujitsu_master_vol_put, 5327 .private_value = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT), 5328 }, 5329 { 5330 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 5331 .name = "Master Playback Switch", 5332 .info = snd_hda_mixer_amp_switch_info, 5333 .get = snd_hda_mixer_amp_switch_get, 5334 .put = alc262_fujitsu_master_sw_put, 5335 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 5336 }, 5337 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 5338 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 5339 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 5340 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 5341 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 5342 {0} /* end */ 4663 5343 }; 4664 5344 … … 4666 5346 static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, const struct auto_pin_cfg *cfg) 4667 5347 { 4668 hda_nid_t nid;4669 int err;4670 4671 spec->multiout.num_dacs = 1; /* only use one dac */4672 spec->multiout.dac_nids = spec->private_dac_nids;4673 spec->multiout.dac_nids[0] = 2;4674 4675 nid = cfg->line_out_pins[0];4676 if (nid) {4677 if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Front Playback Volume",4678 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT))) < 0)4679 return err;4680 if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Front Playback Switch",4681 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)4682 return err;4683 }4684 4685 nid = cfg->speaker_pins[0];4686 if (nid) {4687 if (nid == 0x16) {4688 if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Speaker Playback Switch",4689 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0)4690 return err;4691 } else {4692 if (! cfg->line_out_pins[0])4693 if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Speaker Playback Volume",4694 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT))) < 0)4695 return err;4696 if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Speaker Playback Switch",4697 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)4698 return err;4699 }4700 }4701 nid = cfg->hp_pin;4702 if (nid) {4703 /* spec->multiout.hp_nid = 2; */4704 if (nid == 0x16) {4705 if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Headphone Playback Volume",4706 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT))) < 0)4707 return err;4708 if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Headphone Playback Switch",4709 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0)4710 return err;4711 } else {4712 if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Headphone Playback Switch",4713 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)4714 return err;4715 }4716 }4717 return 0;5348 hda_nid_t nid; 5349 int err; 5350 5351 spec->multiout.num_dacs = 1; /* only use one dac */ 5352 spec->multiout.dac_nids = spec->private_dac_nids; 5353 spec->multiout.dac_nids[0] = 2; 5354 5355 nid = cfg->line_out_pins[0]; 5356 if (nid) { 5357 if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Front Playback Volume", 5358 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT))) < 0) 5359 return err; 5360 if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Front Playback Switch", 5361 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) 5362 return err; 5363 } 5364 5365 nid = cfg->speaker_pins[0]; 5366 if (nid) { 5367 if (nid == 0x16) { 5368 if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Speaker Playback Switch", 5369 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0) 5370 return err; 5371 } else { 5372 if (! cfg->line_out_pins[0]) 5373 if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Speaker Playback Volume", 5374 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT))) < 0) 5375 return err; 5376 if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Speaker Playback Switch", 5377 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) 5378 return err; 5379 } 5380 } 5381 nid = cfg->hp_pin; 5382 if (nid) { 5383 /* spec->multiout.hp_nid = 2; */ 5384 if (nid == 0x16) { 5385 if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Headphone Playback Volume", 5386 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT))) < 0) 5387 return err; 5388 if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Headphone Playback Switch", 5389 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0) 5390 return err; 5391 } else { 5392 if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Headphone Playback Switch", 5393 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) 5394 return err; 5395 } 5396 } 5397 return 0; 4718 5398 } 4719 5399 … … 4725 5405 */ 4726 5406 static struct hda_verb alc262_volume_init_verbs[] = { 4727 /* 4728 * Unmute ADC0-2 and set the default input to mic-in 4729 */ 4730 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 4731 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4732 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 4733 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4734 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 4735 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4736 4737 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 4738 * mixer widget 4739 * Note: PASD motherboards uses the Line In 2 as the input for front panel 4740 * mic (mic 2) 4741 */ 4742 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 4743 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4744 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4745 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 4746 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 4747 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 4748 4749 /* 4750 * Set up output mixers (0x0c - 0x0f) 4751 */ 4752 /* set vol=0 to output mixers */ 4753 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4754 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4755 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4756 4757 /* set up input amps for analog loopback */ 4758 /* Amp Indices: DAC = 0, mixer = 1 */ 4759 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4760 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4761 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4762 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4763 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4764 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4765 4766 /* FIXME: use matrix-type input source selection */ 4767 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 4768 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 4769 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 4770 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 4771 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 4772 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 4773 /* Input mixer2 */ 4774 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 4775 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 4776 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 4777 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 4778 /* Input mixer3 */ 4779 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 4780 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 4781 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 4782 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 4783 4784 {0} 5407 /* 5408 * Unmute ADC0-2 and set the default input to mic-in 5409 */ 5410 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 5411 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5412 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 5413 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5414 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 5415 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5416 5417 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 5418 * mixer widget 5419 * Note: PASD motherboards uses the Line In 2 as the input for front panel 5420 * mic (mic 2) 5421 */ 5422 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 5423 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5424 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5425 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 5426 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 5427 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 5428 5429 /* 5430 * Set up output mixers (0x0c - 0x0f) 5431 */ 5432 /* set vol=0 to output mixers */ 5433 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5434 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5435 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5436 5437 /* set up input amps for analog loopback */ 5438 /* Amp Indices: DAC = 0, mixer = 1 */ 5439 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5440 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5441 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5442 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5443 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5444 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5445 5446 /* FIXME: use matrix-type input source selection */ 5447 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 5448 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 5449 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 5450 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 5451 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 5452 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 5453 /* Input mixer2 */ 5454 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 5455 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 5456 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 5457 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 5458 /* Input mixer3 */ 5459 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 5460 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 5461 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 5462 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 5463 5464 {0} 5465 }; 5466 5467 static struct hda_verb alc262_HP_BPC_init_verbs[] = { 5468 /* 5469 * Unmute ADC0-2 and set the default input to mic-in 5470 */ 5471 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 5472 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5473 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 5474 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5475 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 5476 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5477 5478 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 5479 * mixer widget 5480 * Note: PASD motherboards uses the Line In 2 as the input for front panel 5481 * mic (mic 2) 5482 */ 5483 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 5484 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5485 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5486 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 5487 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 5488 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 5489 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)}, 5490 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(6)}, 5491 5492 /* 5493 * Set up output mixers (0x0c - 0x0e) 5494 */ 5495 /* set vol=0 to output mixers */ 5496 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5497 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5498 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5499 5500 /* set up input amps for analog loopback */ 5501 /* Amp Indices: DAC = 0, mixer = 1 */ 5502 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5503 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5504 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5505 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5506 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5507 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5508 5509 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 5510 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 5511 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 5512 5513 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 5514 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 5515 5516 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 5517 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 5518 5519 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 5520 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 5521 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 5522 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 5523 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 5524 5525 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, 5526 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 5527 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 5528 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, 5529 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 5530 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 5531 5532 5533 /* FIXME: use matrix-type input source selection */ 5534 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 5535 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 5536 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 5537 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, 5538 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, 5539 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, 5540 /* Input mixer2 */ 5541 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 5542 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, 5543 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, 5544 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, 5545 /* Input mixer3 */ 5546 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 5547 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, 5548 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, 5549 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, 5550 5551 {0} 4785 5552 }; 4786 5553 … … 4796 5563 static int alc262_parse_auto_config(struct hda_codec *codec) 4797 5564 { 4798 struct alc_spec *spec = codec->spec;4799 int err;4800 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };4801 4802 if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,4803 alc262_ignore)) < 0)4804 return err;4805 if (! spec->autocfg.line_outs)4806 return 0; /* can't find valid BIOS pin config */4807 if ((err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 ||4808 (err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0)4809 return err;4810 4811 spec->multiout.max_channels = spec->multiout.num_dacs * 2;4812 4813 if (spec->autocfg.dig_out_pin)4814 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;4815 if (spec->autocfg.dig_in_pin)4816 spec->dig_in_nid = ALC262_DIGIN_NID;4817 4818 if (spec->kctl_alloc)4819 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;4820 4821 spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs;4822 spec->input_mux = &spec->private_imux;4823 4824 return 1;5565 struct alc_spec *spec = codec->spec; 5566 int err; 5567 static hda_nid_t alc262_ignore[] = { 0x1d, 0 }; 5568 5569 if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 5570 alc262_ignore)) < 0) 5571 return err; 5572 if (! spec->autocfg.line_outs) 5573 return 0; /* can't find valid BIOS pin config */ 5574 if ((err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 || 5575 (err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0) 5576 return err; 5577 5578 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 5579 5580 if (spec->autocfg.dig_out_pin) 5581 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID; 5582 if (spec->autocfg.dig_in_pin) 5583 spec->dig_in_nid = ALC262_DIGIN_NID; 5584 5585 if (spec->kctl_alloc) 5586 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 5587 5588 spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs; 5589 spec->input_mux = &spec->private_imux; 5590 5591 return 1; 4825 5592 } 4826 5593 … … 4842 5609 */ 4843 5610 static struct hda_board_config alc262_cfg_tbl[] = { 4844 { .modelname = "basic", .config = ALC262_BASIC }, 4845 { .modelname = "fujitsu", .config = ALC262_FUJITSU }, 4846 { .pci_subvendor = 0x10cf, .pci_subdevice = 0x1397, .config = ALC262_FUJITSU }, 4847 { .modelname = "auto", .config = ALC262_AUTO }, 4848 {0} 5611 { .modelname = "basic", .config = ALC262_BASIC }, 5612 { .modelname = "fujitsu", .config = ALC262_FUJITSU }, 5613 { .pci_subvendor = 0x10cf, .pci_subdevice = 0x1397, 5614 .config = ALC262_FUJITSU }, 5615 { .pci_subvendor = 0x103c, .pci_subdevice = 0x208c, 5616 .config = ALC262_HP_BPC }, /* xw4400 */ 5617 { .pci_subvendor = 0x103c, .pci_subdevice = 0x3014, 5618 .config = ALC262_HP_BPC }, /* xw6400 */ 5619 { .pci_subvendor = 0x103c, .pci_subdevice = 0x3015, 5620 .config = ALC262_HP_BPC }, /* xw8400 */ 5621 { .pci_subvendor = 0x103c, .pci_subdevice = 0x12fe, 5622 .config = ALC262_HP_BPC }, /* xw9400 */ 5623 { .modelname = "auto", .config = ALC262_AUTO }, 5624 {0} 4849 5625 }; 4850 5626 4851 5627 static struct alc_config_preset alc262_presets[] = { 4852 [ALC262_BASIC] = { 4853 .mixers = { alc262_base_mixer }, 4854 .init_verbs = { alc262_init_verbs }, 4855 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 4856 .dac_nids = alc262_dac_nids, 4857 .hp_nid = 0x03, 4858 .num_channel_mode = ARRAY_SIZE(alc262_modes), 4859 .channel_mode = alc262_modes, 4860 .input_mux = &alc262_capture_source, 4861 }, 4862 [ALC262_FUJITSU] = { 4863 .mixers = { alc262_fujitsu_mixer }, 4864 .init_verbs = { alc262_init_verbs, alc262_fujitsu_unsol_verbs }, 4865 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 4866 .dac_nids = alc262_dac_nids, 4867 .hp_nid = 0x03, 4868 .dig_out_nid = ALC262_DIGOUT_NID, 4869 .num_channel_mode = ARRAY_SIZE(alc262_modes), 4870 .channel_mode = alc262_modes, 4871 .input_mux = &alc262_fujitsu_capture_source, 4872 .unsol_event = alc262_fujitsu_unsol_event, 4873 }, 5628 [ALC262_BASIC] = { 5629 .mixers = { alc262_base_mixer }, 5630 .init_verbs = { alc262_init_verbs }, 5631 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 5632 .dac_nids = alc262_dac_nids, 5633 .hp_nid = 0x03, 5634 .num_channel_mode = ARRAY_SIZE(alc262_modes), 5635 .channel_mode = alc262_modes, 5636 .input_mux = &alc262_capture_source, 5637 }, 5638 [ALC262_FUJITSU] = { 5639 .mixers = { alc262_fujitsu_mixer }, 5640 .init_verbs = { alc262_init_verbs, alc262_fujitsu_unsol_verbs }, 5641 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 5642 .dac_nids = alc262_dac_nids, 5643 .hp_nid = 0x03, 5644 .dig_out_nid = ALC262_DIGOUT_NID, 5645 .num_channel_mode = ARRAY_SIZE(alc262_modes), 5646 .channel_mode = alc262_modes, 5647 .input_mux = &alc262_fujitsu_capture_source, 5648 .unsol_event = alc262_fujitsu_unsol_event, 5649 }, 5650 [ALC262_HP_BPC] = { 5651 .mixers = { alc262_HP_BPC_mixer }, 5652 .init_verbs = { alc262_HP_BPC_init_verbs }, 5653 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 5654 .dac_nids = alc262_dac_nids, 5655 .hp_nid = 0x03, 5656 .num_channel_mode = ARRAY_SIZE(alc262_modes), 5657 .channel_mode = alc262_modes, 5658 .input_mux = &alc262_HP_capture_source, 5659 }, 4874 5660 }; 4875 5661 4876 5662 static int patch_alc262(struct hda_codec *codec) 4877 5663 { 4878 struct alc_spec *spec;4879 int board_config;4880 int err;4881 4882 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);4883 if (spec == NULL)4884 return -ENOMEM;4885 4886 codec->spec = spec;5664 struct alc_spec *spec; 5665 int board_config; 5666 int err; 5667 5668 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); 5669 if (spec == NULL) 5670 return -ENOMEM; 5671 5672 codec->spec = spec; 4887 5673 #if 0 4888 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is under-run */4889 {4890 int tmp;4891 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);4892 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);4893 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);4894 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);4895 }5674 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is under-run */ 5675 { 5676 int tmp; 5677 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7); 5678 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); 5679 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7); 5680 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80); 5681 } 4896 5682 #endif 4897 5683 4898 board_config = snd_hda_check_board_config(codec, alc262_cfg_tbl); 4899 if (board_config < 0 || board_config >= ALC262_MODEL_LAST) { 4900 printk(KERN_INFO "hda_codec: Unknown model for ALC262, trying auto-probe from BIOS...\n"); 4901 board_config = ALC262_AUTO; 4902 } 4903 4904 if (board_config == ALC262_AUTO) { 4905 /* automatic parse from the BIOS config */ 4906 err = alc262_parse_auto_config(codec); 4907 if (err < 0) { 4908 alc_free(codec); 4909 return err; 4910 } else if (! err) { 4911 printk(KERN_INFO "hda_codec: Cannot set up configuration from BIOS. Using base mode...\n"); 4912 board_config = ALC262_BASIC; 4913 } 4914 } 4915 4916 if (board_config != ALC262_AUTO) 4917 setup_preset(spec, &alc262_presets[board_config]); 4918 4919 spec->stream_name_analog = "ALC262 Analog"; 4920 spec->stream_analog_playback = &alc262_pcm_analog_playback; 4921 spec->stream_analog_capture = &alc262_pcm_analog_capture; 4922 4923 spec->stream_name_digital = "ALC262 Digital"; 4924 spec->stream_digital_playback = &alc262_pcm_digital_playback; 4925 spec->stream_digital_capture = &alc262_pcm_digital_capture; 4926 4927 if (! spec->adc_nids && spec->input_mux) { 4928 /* check whether NID 0x07 is valid */ 4929 unsigned int wcap = get_wcaps(codec, 0x07); 4930 4931 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */ 4932 if (wcap != AC_WID_AUD_IN) { 4933 spec->adc_nids = alc262_adc_nids_alt; 4934 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt); 4935 spec->mixers[spec->num_mixers] = alc262_capture_alt_mixer; 4936 spec->num_mixers++; 4937 } else { 4938 spec->adc_nids = alc262_adc_nids; 4939 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids); 4940 spec->mixers[spec->num_mixers] = alc262_capture_mixer; 4941 spec->num_mixers++; 4942 } 4943 } 4944 4945 codec->patch_ops = alc_patch_ops; 4946 if (board_config == ALC262_AUTO) 4947 spec->init_hook = alc262_auto_init; 4948 4949 return 0; 5684 board_config = snd_hda_check_board_config(codec, alc262_cfg_tbl); 5685 5686 if (board_config < 0 || board_config >= ALC262_MODEL_LAST) { 5687 printk(KERN_INFO "hda_codec: Unknown model for ALC262, trying auto-probe from BIOS...\n"); 5688 board_config = ALC262_AUTO; 5689 } 5690 5691 if (board_config == ALC262_AUTO) { 5692 /* automatic parse from the BIOS config */ 5693 err = alc262_parse_auto_config(codec); 5694 if (err < 0) { 5695 alc_free(codec); 5696 return err; 5697 } else if (! err) { 5698 printk(KERN_INFO "hda_codec: Cannot set up configuration from BIOS. Using base mode...\n"); 5699 board_config = ALC262_BASIC; 5700 } 5701 } 5702 5703 if (board_config != ALC262_AUTO) 5704 setup_preset(spec, &alc262_presets[board_config]); 5705 5706 spec->stream_name_analog = "ALC262 Analog"; 5707 spec->stream_analog_playback = &alc262_pcm_analog_playback; 5708 spec->stream_analog_capture = &alc262_pcm_analog_capture; 5709 5710 spec->stream_name_digital = "ALC262 Digital"; 5711 spec->stream_digital_playback = &alc262_pcm_digital_playback; 5712 spec->stream_digital_capture = &alc262_pcm_digital_capture; 5713 5714 if (! spec->adc_nids && spec->input_mux) { 5715 /* check whether NID 0x07 is valid */ 5716 unsigned int wcap = get_wcaps(codec, 0x07); 5717 5718 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */ 5719 if (wcap != AC_WID_AUD_IN) { 5720 spec->adc_nids = alc262_adc_nids_alt; 5721 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt); 5722 spec->mixers[spec->num_mixers] = alc262_capture_alt_mixer; 5723 spec->num_mixers++; 5724 } else { 5725 spec->adc_nids = alc262_adc_nids; 5726 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids); 5727 spec->mixers[spec->num_mixers] = alc262_capture_mixer; 5728 spec->num_mixers++; 5729 } 5730 } 5731 5732 codec->patch_ops = alc_patch_ops; 5733 if (board_config == ALC262_AUTO) 5734 spec->init_hook = alc262_auto_init; 5735 5736 return 0; 4950 5737 } 4951 5738 … … 4960 5747 */ 4961 5748 static struct hda_verb alc861_threestack_ch2_init[] = { 4962 /* set pin widget 1Ah (line in) for input */ 4963 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 4964 /* set pin widget 18h (mic1/2) for input, for mic also enable the vref */ 4965 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 4966 4967 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, 4968 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, //mic 4969 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, //line in 4970 {0} /* end */ 5749 /* set pin widget 1Ah (line in) for input */ 5750 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 5751 /* set pin widget 18h (mic1/2) for input, for mic also enable the vref */ 5752 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 5753 5754 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, 5755 #if 0 5756 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/ 5757 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/ 5758 #endif 5759 {0} /* end */ 4971 5760 }; 4972 5761 /* … … 4975 5764 */ 4976 5765 static struct hda_verb alc861_threestack_ch6_init[] = { 4977 /* set pin widget 1Ah (line in) for output (Back Surround)*/ 4978 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 4979 /* set pin widget 18h (mic1) for output (CLFE)*/ 4980 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 4981 4982 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 }, 4983 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 }, 4984 4985 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 }, 4986 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, //mic 4987 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, //line in 4988 {0} /* end */ 5766 /* set pin widget 1Ah (line in) for output (Back Surround)*/ 5767 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 5768 /* set pin widget 18h (mic1) for output (CLFE)*/ 5769 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 5770 5771 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 }, 5772 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 }, 5773 5774 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 }, 5775 #if 0 5776 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/ 5777 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/ 5778 #endif 5779 {0} /* end */ 4989 5780 }; 4990 5781 4991 5782 static struct hda_channel_mode alc861_threestack_modes[2] = { 4992 { 2, alc861_threestack_ch2_init },4993 { 6, alc861_threestack_ch6_init },5783 { 2, alc861_threestack_ch2_init }, 5784 { 6, alc861_threestack_ch6_init }, 4994 5785 }; 4995 5786 … … 4997 5788 4998 5789 static struct snd_kcontrol_new alc861_base_mixer[] = { 4999 /* output mixer control */5000 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),5001 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),5002 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),5003 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),5004 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),5005 5006 /*Input mixer control */5007 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),5008 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */5009 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),5010 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),5011 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),5012 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),5013 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),5014 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),5015 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),5016 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),5017 5018 /* Capture mixer control */5019 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),5020 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),5021 {5022 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,5023 .name = "Capture Source",5024 .count = 1,5025 .info = alc_mux_enum_info,5026 .get = alc_mux_enum_get,5027 .put = alc_mux_enum_put,5028 },5029 {0} /* end */5790 /* output mixer control */ 5791 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), 5792 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), 5793 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT), 5794 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT), 5795 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), 5796 5797 /*Input mixer control */ 5798 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT), 5799 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */ 5800 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 5801 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 5802 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT), 5803 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT), 5804 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 5805 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 5806 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), 5807 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), 5808 5809 /* Capture mixer control */ 5810 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 5811 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 5812 { 5813 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 5814 .name = "Capture Source", 5815 .count = 1, 5816 .info = alc_mux_enum_info, 5817 .get = alc_mux_enum_get, 5818 .put = alc_mux_enum_put, 5819 }, 5820 {0} /* end */ 5030 5821 }; 5031 5822 5032 5823 static struct snd_kcontrol_new alc861_3ST_mixer[] = { 5033 /* output mixer control */5034 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),5035 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),5036 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),5037 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),5038 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */5039 5040 /* Input mixer control */5041 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),5042 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */5043 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),5044 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),5045 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),5046 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),5047 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),5048 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),5049 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),5050 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),5051 5052 /* Capture mixer control */5053 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),5054 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),5055 {5056 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,5057 .name = "Capture Source",5058 .count = 1,5059 .info = alc_mux_enum_info,5060 .get = alc_mux_enum_get,5061 .put = alc_mux_enum_put,5062 },5063 {5064 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,5065 .name = "Channel Mode",5066 .info = alc_ch_mode_info,5067 .get = alc_ch_mode_get,5068 .put = alc_ch_mode_put,5069 .private_value = ARRAY_SIZE(alc861_threestack_modes),5070 },5071 {0} /* end */5824 /* output mixer control */ 5825 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), 5826 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), 5827 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT), 5828 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT), 5829 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */ 5830 5831 /* Input mixer control */ 5832 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT), 5833 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */ 5834 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 5835 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 5836 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT), 5837 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT), 5838 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 5839 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 5840 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), 5841 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), 5842 5843 /* Capture mixer control */ 5844 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 5845 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 5846 { 5847 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 5848 .name = "Capture Source", 5849 .count = 1, 5850 .info = alc_mux_enum_info, 5851 .get = alc_mux_enum_get, 5852 .put = alc_mux_enum_put, 5853 }, 5854 { 5855 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 5856 .name = "Channel Mode", 5857 .info = alc_ch_mode_info, 5858 .get = alc_ch_mode_get, 5859 .put = alc_ch_mode_put, 5860 .private_value = ARRAY_SIZE(alc861_threestack_modes), 5861 }, 5862 {0} /* end */ 5072 5863 }; 5073 5864 … … 5076 5867 */ 5077 5868 static struct hda_verb alc861_base_init_verbs[] = { 5078 /*5079 * Unmute ADC0 and set the default input to mic-in5080 */5081 /* port-A for surround (rear panel) */5082 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },5083 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },5084 /* port-B for mic-in (rear panel) with vref */5085 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },5086 /* port-C for line-in (rear panel) */5087 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },5088 /* port-D for Front */5089 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },5090 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },5091 /* port-E for HP out (front panel) */5092 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },5093 /* route front PCM to HP */5094 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x01 },5095 /* port-F for mic-in (front panel) with vref */5096 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },5097 /* port-G for CLFE (rear panel) */5098 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },5099 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },5100 /* port-H for side (rear panel) */5101 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },5102 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },5103 /* CD-in */5104 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },5105 /* route front mic to ADC1*/5106 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},5107 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},5108 5109 /* Unmute DAC0~3 & spdif out*/5110 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},5111 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},5112 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},5113 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},5114 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},5115 5116 /* Unmute Mixer 14 (mic) 1c (Line in)*/5117 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},5118 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},5119 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},5120 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},5121 5122 /* Unmute Stereo Mixer 15 */5123 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},5124 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},5125 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},5126 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, //Output 0~12 step5127 5128 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},5129 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},5130 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},5131 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},5132 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},5133 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},5134 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},5135 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},5136 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, // hp used DAC 3 (Front)5137 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},5138 5139 {0}5869 /* 5870 * Unmute ADC0 and set the default input to mic-in 5871 */ 5872 /* port-A for surround (rear panel) */ 5873 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 5874 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 }, 5875 /* port-B for mic-in (rear panel) with vref */ 5876 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 5877 /* port-C for line-in (rear panel) */ 5878 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 5879 /* port-D for Front */ 5880 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 5881 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, 5882 /* port-E for HP out (front panel) */ 5883 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, 5884 /* route front PCM to HP */ 5885 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x01 }, 5886 /* port-F for mic-in (front panel) with vref */ 5887 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 5888 /* port-G for CLFE (rear panel) */ 5889 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 5890 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 5891 /* port-H for side (rear panel) */ 5892 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 5893 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 }, 5894 /* CD-in */ 5895 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 5896 /* route front mic to ADC1*/ 5897 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 5898 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5899 5900 /* Unmute DAC0~3 & spdif out*/ 5901 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5902 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5903 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5904 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5905 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5906 5907 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 5908 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5909 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5910 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5911 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5912 5913 /* Unmute Stereo Mixer 15 */ 5914 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5915 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5916 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 5917 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, //Output 0~12 step 5918 5919 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5920 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5921 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5922 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5923 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5924 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5925 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5926 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5927 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, // hp used DAC 3 (Front) 5928 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 5929 5930 {0} 5140 5931 }; 5141 5932 5142 5933 static struct hda_verb alc861_threestack_init_verbs[] = { 5143 /*5144 * Unmute ADC0 and set the default input to mic-in5145 */5146 /* port-A for surround (rear panel) */5147 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },5148 /* port-B for mic-in (rear panel) with vref */5149 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },5150 /* port-C for line-in (rear panel) */5151 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },5152 /* port-D for Front */5153 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },5154 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },5155 /* port-E for HP out (front panel) */5156 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },5157 /* route front PCM to HP */5158 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x01 },5159 /* port-F for mic-in (front panel) with vref */5160 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },5161 /* port-G for CLFE (rear panel) */5162 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },5163 /* port-H for side (rear panel) */5164 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },5165 /* CD-in */5166 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },5167 /* route front mic to ADC1*/5168 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},5169 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},5170 /* Unmute DAC0~3 & spdif out*/5171 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},5172 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},5173 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},5174 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},5175 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},5176 5177 /* Unmute Mixer 14 (mic) 1c (Line in)*/5178 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},5179 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},5180 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},5181 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},5182 5183 /* Unmute Stereo Mixer 15 */5184 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},5185 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},5186 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},5187 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, //Output 0~12 step5188 5189 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},5190 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},5191 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},5192 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},5193 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},5194 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},5195 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},5196 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},5197 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, // hp used DAC 3 (Front)5198 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},5199 {0}5934 /* 5935 * Unmute ADC0 and set the default input to mic-in 5936 */ 5937 /* port-A for surround (rear panel) */ 5938 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 5939 /* port-B for mic-in (rear panel) with vref */ 5940 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 5941 /* port-C for line-in (rear panel) */ 5942 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 5943 /* port-D for Front */ 5944 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 5945 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, 5946 /* port-E for HP out (front panel) */ 5947 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, 5948 /* route front PCM to HP */ 5949 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x01 }, 5950 /* port-F for mic-in (front panel) with vref */ 5951 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 5952 /* port-G for CLFE (rear panel) */ 5953 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 5954 /* port-H for side (rear panel) */ 5955 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 5956 /* CD-in */ 5957 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 5958 /* route front mic to ADC1*/ 5959 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 5960 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5961 /* Unmute DAC0~3 & spdif out*/ 5962 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5963 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5964 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5965 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5966 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5967 5968 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 5969 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5970 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5971 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5972 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5973 5974 /* Unmute Stereo Mixer 15 */ 5975 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5976 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5977 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 5978 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, //Output 0~12 step 5979 5980 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5981 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5982 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5983 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5984 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5985 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5986 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5987 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5988 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, // hp used DAC 3 (Front) 5989 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 5990 {0} 5200 5991 }; 5201 5992 /* … … 5203 5994 */ 5204 5995 static struct hda_verb alc861_auto_init_verbs[] = { 5205 /*5206 * Unmute ADC0 and set the default input to mic-in5207 */5208 // {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},5209 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},5210 5211 /* Unmute DAC0~3 & spdif out*/5212 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},5213 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},5214 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},5215 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},5216 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},5217 5218 /* Unmute Mixer 14 (mic) 1c (Line in)*/5219 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},5220 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},5221 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},5222 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},5223 5224 /* Unmute Stereo Mixer 15 */5225 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},5226 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},5227 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},5228 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},5229 5230 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},5231 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},5232 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},5233 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},5234 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},5235 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},5236 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},5237 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},5238 5239 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},5240 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},5241 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},5242 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},5243 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},5244 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},5245 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},5246 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},5247 5248 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, // set Mic 15249 5250 {0}5996 /* 5997 * Unmute ADC0 and set the default input to mic-in 5998 */ 5999 // {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 6000 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6001 6002 /* Unmute DAC0~3 & spdif out*/ 6003 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 6004 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 6005 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 6006 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 6007 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6008 6009 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 6010 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6011 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6012 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6013 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6014 6015 /* Unmute Stereo Mixer 15 */ 6016 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6017 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6018 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 6019 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, 6020 6021 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6022 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6023 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6024 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6025 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6026 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6027 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6028 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6029 6030 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6031 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6032 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 6033 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 6034 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6035 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6036 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 6037 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 6038 6039 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, // set Mic 1 6040 6041 {0} 5251 6042 }; 5252 6043 … … 5261 6052 5262 6053 static struct hda_channel_mode alc861_8ch_modes[1] = { 5263 { 8, NULL }6054 { 8, NULL } 5264 6055 }; 5265 6056 5266 6057 static hda_nid_t alc861_dac_nids[4] = { 5267 /* front, surround, clfe, side */ 5268 0x03, 0x06, 0x05, 0x04 6058 /* front, surround, clfe, side */ 6059 0x03, 0x06, 0x05, 0x04 6060 }; 6061 6062 static hda_nid_t alc660_dac_nids[3] = { 6063 /* front, clfe, surround */ 6064 0x03, 0x05, 0x06 5269 6065 }; 5270 6066 5271 6067 static hda_nid_t alc861_adc_nids[1] = { 5272 /* ADC0-2 */5273 0x08,6068 /* ADC0-2 */ 6069 0x08, 5274 6070 }; 5275 6071 5276 6072 static struct hda_input_mux alc861_capture_source = { 5277 .num_items = 5,5278 .items = {5279 { "Mic", 0x0 },5280 { "Front Mic", 0x3 },5281 { "Line", 0x1 },5282 { "CD", 0x4 },5283 { "Mixer", 0x5 },5284 },6073 .num_items = 5, 6074 .items = { 6075 { "Mic", 0x0 }, 6076 { "Front Mic", 0x3 }, 6077 { "Line", 0x1 }, 6078 { "CD", 0x4 }, 6079 { "Mixer", 0x5 }, 6080 }, 5285 6081 }; 5286 6082 … … 5288 6084 static int alc861_auto_fill_dac_nids(struct alc_spec *spec, const struct auto_pin_cfg *cfg) 5289 6085 { 5290 int i;5291 hda_nid_t nid;5292 5293 spec->multiout.dac_nids = spec->private_dac_nids;5294 for (i = 0; i < cfg->line_outs; i++) {5295 nid = cfg->line_out_pins[i];5296 if (nid) {5297 if (i >= ARRAY_SIZE(alc861_dac_nids))5298 continue;5299 spec->multiout.dac_nids[i] = alc861_dac_nids[i];5300 }5301 }5302 spec->multiout.num_dacs = cfg->line_outs;5303 return 0;6086 int i; 6087 hda_nid_t nid; 6088 6089 spec->multiout.dac_nids = spec->private_dac_nids; 6090 for (i = 0; i < cfg->line_outs; i++) { 6091 nid = cfg->line_out_pins[i]; 6092 if (nid) { 6093 if (i >= ARRAY_SIZE(alc861_dac_nids)) 6094 continue; 6095 spec->multiout.dac_nids[i] = alc861_dac_nids[i]; 6096 } 6097 } 6098 spec->multiout.num_dacs = cfg->line_outs; 6099 return 0; 5304 6100 } 5305 6101 5306 6102 /* add playback controls from the parsed DAC table */ 5307 6103 static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec, 5308 const struct auto_pin_cfg *cfg)5309 { 5310 char name[32];5311 static const char *chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" };5312 hda_nid_t nid;5313 int i, idx, err;5314 5315 for (i = 0; i < cfg->line_outs; i++) {5316 nid = spec->multiout.dac_nids[i];5317 if (! nid)5318 continue;5319 if (nid == 0x05) {5320 /* Center/LFE */5321 if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "Center Playback Switch",5322 HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT))) < 0)5323 return err;5324 if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "LFE Playback Switch",5325 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0)5326 return err;5327 } else {5328 for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1; idx++)5329 if (nid == alc861_dac_nids[idx])5330 break;5331 sprintf(name, "%s Playback Switch", chname[idx]);5332 if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name,5333 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)5334 return err;5335 }5336 }5337 return 0;6104 const struct auto_pin_cfg *cfg) 6105 { 6106 char name[32]; 6107 static const char *chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" }; 6108 hda_nid_t nid; 6109 int i, idx, err; 6110 6111 for (i = 0; i < cfg->line_outs; i++) { 6112 nid = spec->multiout.dac_nids[i]; 6113 if (! nid) 6114 continue; 6115 if (nid == 0x05) { 6116 /* Center/LFE */ 6117 if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "Center Playback Switch", 6118 HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT))) < 0) 6119 return err; 6120 if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "LFE Playback Switch", 6121 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0) 6122 return err; 6123 } else { 6124 for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1; idx++) 6125 if (nid == alc861_dac_nids[idx]) 6126 break; 6127 sprintf(name, "%s Playback Switch", chname[idx]); 6128 if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name, 6129 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) 6130 return err; 6131 } 6132 } 6133 return 0; 5338 6134 } 5339 6135 5340 6136 static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin) 5341 6137 { 5342 int err;5343 hda_nid_t nid;5344 5345 if (! pin)5346 return 0;5347 5348 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {5349 nid = 0x03;5350 if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Headphone Playback Switch",5351 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)5352 return err;5353 spec->multiout.hp_nid = nid;5354 }5355 return 0;6138 int err; 6139 hda_nid_t nid; 6140 6141 if (! pin) 6142 return 0; 6143 6144 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) { 6145 nid = 0x03; 6146 if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Headphone Playback Switch", 6147 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) 6148 return err; 6149 spec->multiout.hp_nid = nid; 6150 } 6151 return 0; 5356 6152 } 5357 6153 … … 5359 6155 static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec, const struct auto_pin_cfg *cfg) 5360 6156 { 5361 struct hda_input_mux *imux = &spec->private_imux;5362 int i, err, idx, idx1;5363 5364 for (i = 0; i < AUTO_PIN_LAST; i++) {5365 switch(cfg->input_pins[i]) {5366 case 0x0c:5367 idx1 = 1;5368 idx = 2; // Line In5369 break;5370 case 0x0f:5371 idx1 = 2;5372 idx = 2; // Line In5373 break;5374 case 0x0d:5375 idx1 = 0;5376 idx = 1; // Mic In5377 break;5378 case 0x10:5379 idx1 = 3;5380 idx = 1; // Mic In5381 break;5382 case 0x11:5383 idx1 = 4;5384 idx = 0; // CD5385 break;5386 default:5387 continue;5388 }5389 5390 err = new_analog_input(spec, cfg->input_pins[i],5391 auto_pin_cfg_labels[i], idx, 0x15);5392 if (err < 0)5393 return err;5394 5395 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];5396 imux->items[imux->num_items].index = idx1;5397 imux->num_items++;5398 }5399 return 0;6157 struct hda_input_mux *imux = &spec->private_imux; 6158 int i, err, idx, idx1; 6159 6160 for (i = 0; i < AUTO_PIN_LAST; i++) { 6161 switch(cfg->input_pins[i]) { 6162 case 0x0c: 6163 idx1 = 1; 6164 idx = 2; // Line In 6165 break; 6166 case 0x0f: 6167 idx1 = 2; 6168 idx = 2; // Line In 6169 break; 6170 case 0x0d: 6171 idx1 = 0; 6172 idx = 1; // Mic In 6173 break; 6174 case 0x10: 6175 idx1 = 3; 6176 idx = 1; // Mic In 6177 break; 6178 case 0x11: 6179 idx1 = 4; 6180 idx = 0; // CD 6181 break; 6182 default: 6183 continue; 6184 } 6185 6186 err = new_analog_input(spec, cfg->input_pins[i], 6187 auto_pin_cfg_labels[i], idx, 0x15); 6188 if (err < 0) 6189 return err; 6190 6191 imux->items[imux->num_items].label = auto_pin_cfg_labels[i]; 6192 imux->items[imux->num_items].index = idx1; 6193 imux->num_items++; 6194 } 6195 return 0; 5400 6196 } 5401 6197 5402 6198 static struct snd_kcontrol_new alc861_capture_mixer[] = { 5403 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),5404 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),5405 5406 {5407 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,5408 /* The multiple "Capture Source" controls confuse alsamixer5409 * So call somewhat different..5410 *FIXME: the controls appear in the "playback" view!5411 */5412 /* .name = "Capture Source", */5413 .name = "Input Source",5414 .count = 1,5415 .info = alc_mux_enum_info,5416 .get = alc_mux_enum_get,5417 .put = alc_mux_enum_put,5418 },5419 {0} /* end */6199 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 6200 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 6201 6202 { 6203 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6204 /* The multiple "Capture Source" controls confuse alsamixer 6205 * So call somewhat different.. 6206 *FIXME: the controls appear in the "playback" view! 6207 */ 6208 /* .name = "Capture Source", */ 6209 .name = "Input Source", 6210 .count = 1, 6211 .info = alc_mux_enum_info, 6212 .get = alc_mux_enum_get, 6213 .put = alc_mux_enum_put, 6214 }, 6215 {0} /* end */ 5420 6216 }; 5421 6217 5422 6218 static void alc861_auto_set_output_and_unmute(struct hda_codec *codec, hda_nid_t nid, 5423 int pin_type, int dac_idx)5424 { 5425 /* set as output */5426 5427 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);5428 snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);6219 int pin_type, int dac_idx) 6220 { 6221 /* set as output */ 6222 6223 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type); 6224 snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); 5429 6225 5430 6226 } … … 5432 6228 static void alc861_auto_init_multi_out(struct hda_codec *codec) 5433 6229 { 5434 struct alc_spec *spec = codec->spec;5435 int i;5436 5437 for (i = 0; i < spec->autocfg.line_outs; i++) {5438 hda_nid_t nid = spec->autocfg.line_out_pins[i];5439 if (nid)5440 alc861_auto_set_output_and_unmute(codec, nid, PIN_OUT, spec->multiout.dac_nids[i]);5441 }6230 struct alc_spec *spec = codec->spec; 6231 int i; 6232 6233 for (i = 0; i < spec->autocfg.line_outs; i++) { 6234 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 6235 if (nid) 6236 alc861_auto_set_output_and_unmute(codec, nid, PIN_OUT, spec->multiout.dac_nids[i]); 6237 } 5442 6238 } 5443 6239 5444 6240 static void alc861_auto_init_hp_out(struct hda_codec *codec) 5445 6241 { 5446 struct alc_spec *spec = codec->spec;5447 hda_nid_t pin;5448 5449 pin = spec->autocfg.hp_pin;5450 if (pin) /* connect to front */5451 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP, spec->multiout.dac_nids[0]);6242 struct alc_spec *spec = codec->spec; 6243 hda_nid_t pin; 6244 6245 pin = spec->autocfg.hp_pin; 6246 if (pin) /* connect to front */ 6247 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP, spec->multiout.dac_nids[0]); 5452 6248 } 5453 6249 5454 6250 static void alc861_auto_init_analog_input(struct hda_codec *codec) 5455 6251 { 5456 struct alc_spec *spec = codec->spec;5457 int i;5458 5459 for (i = 0; i < AUTO_PIN_LAST; i++) {5460 hda_nid_t nid = spec->autocfg.input_pins[i];5461 if ((nid>=0x0c) && (nid <=0x11)) {5462 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,5463 i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN);5464 }5465 }6252 struct alc_spec *spec = codec->spec; 6253 int i; 6254 6255 for (i = 0; i < AUTO_PIN_LAST; i++) { 6256 hda_nid_t nid = spec->autocfg.input_pins[i]; 6257 if ((nid>=0x0c) && (nid <=0x11)) { 6258 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 6259 i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN); 6260 } 6261 } 5466 6262 } 5467 6263 … … 5470 6266 static int alc861_parse_auto_config(struct hda_codec *codec) 5471 6267 { 5472 struct alc_spec *spec = codec->spec;5473 int err;5474 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };5475 5476 if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,5477 alc861_ignore)) < 0)5478 return err;5479 if (! spec->autocfg.line_outs)5480 return 0; /* can't find valid BIOS pin config */5481 5482 if ((err = alc861_auto_fill_dac_nids(spec, &spec->autocfg)) < 0 ||5483 (err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 ||5484 (err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pin)) < 0 ||5485 (err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0)5486 return err;5487 5488 spec->multiout.max_channels = spec->multiout.num_dacs * 2;5489 5490 if (spec->autocfg.dig_out_pin)5491 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;5492 5493 if (spec->kctl_alloc)5494 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;5495 5496 spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs;5497 5498 spec->input_mux = &spec->private_imux;5499 5500 spec->adc_nids = alc861_adc_nids;5501 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);5502 spec->mixers[spec->num_mixers] = alc861_capture_mixer;5503 spec->num_mixers++;5504 5505 return 1;6268 struct alc_spec *spec = codec->spec; 6269 int err; 6270 static hda_nid_t alc861_ignore[] = { 0x1d, 0 }; 6271 6272 if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 6273 alc861_ignore)) < 0) 6274 return err; 6275 if (! spec->autocfg.line_outs) 6276 return 0; /* can't find valid BIOS pin config */ 6277 6278 if ((err = alc861_auto_fill_dac_nids(spec, &spec->autocfg)) < 0 || 6279 (err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 || 6280 (err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pin)) < 0 || 6281 (err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0) 6282 return err; 6283 6284 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 6285 6286 if (spec->autocfg.dig_out_pin) 6287 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID; 6288 6289 if (spec->kctl_alloc) 6290 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 6291 6292 spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs; 6293 6294 spec->input_mux = &spec->private_imux; 6295 6296 spec->adc_nids = alc861_adc_nids; 6297 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids); 6298 spec->mixers[spec->num_mixers] = alc861_capture_mixer; 6299 spec->num_mixers++; 6300 6301 return 1; 5506 6302 } 5507 6303 … … 5520 6316 */ 5521 6317 static struct hda_board_config alc861_cfg_tbl[] = { 5522 { .modelname = "3stack", .config = ALC861_3ST }, 5523 { .pci_subvendor = 0x8086, .pci_subdevice = 0xd600, .config = ALC861_3ST }, 5524 { .modelname = "3stack-dig", .config = ALC861_3ST_DIG }, 5525 { .modelname = "6stack-dig", .config = ALC861_6ST_DIG }, 5526 { .modelname = "auto", .config = ALC861_AUTO }, 5527 {0} 6318 { .modelname = "3stack", .config = ALC861_3ST }, 6319 { .pci_subvendor = 0x8086, .pci_subdevice = 0xd600, 6320 .config = ALC861_3ST }, 6321 { .pci_subvendor = 0x1043, .pci_subdevice = 0x81e7, 6322 .config = ALC660_3ST }, 6323 { .modelname = "3stack-dig", .config = ALC861_3ST_DIG }, 6324 { .modelname = "6stack-dig", .config = ALC861_6ST_DIG }, 6325 { .modelname = "auto", .config = ALC861_AUTO }, 6326 {0} 5528 6327 }; 5529 6328 5530 6329 static struct alc_config_preset alc861_presets[] = { 5531 [ALC861_3ST] = { 5532 .mixers = { alc861_3ST_mixer }, 5533 .init_verbs = { alc861_threestack_init_verbs }, 5534 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 5535 .dac_nids = alc861_dac_nids, 5536 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes), 5537 .channel_mode = alc861_threestack_modes, 5538 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 5539 .adc_nids = alc861_adc_nids, 5540 .input_mux = &alc861_capture_source, 5541 }, 5542 [ALC861_3ST_DIG] = { 5543 .mixers = { alc861_base_mixer }, 5544 .init_verbs = { alc861_threestack_init_verbs }, 5545 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 5546 .dac_nids = alc861_dac_nids, 5547 .dig_out_nid = ALC861_DIGOUT_NID, 5548 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes), 5549 .channel_mode = alc861_threestack_modes, 5550 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 5551 .adc_nids = alc861_adc_nids, 5552 .input_mux = &alc861_capture_source, 5553 }, 5554 [ALC861_6ST_DIG] = { 5555 .mixers = { alc861_base_mixer }, 5556 .init_verbs = { alc861_base_init_verbs }, 5557 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 5558 .dac_nids = alc861_dac_nids, 5559 .dig_out_nid = ALC861_DIGOUT_NID, 5560 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes), 5561 .channel_mode = alc861_8ch_modes, 5562 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 5563 .adc_nids = alc861_adc_nids, 5564 .input_mux = &alc861_capture_source, 5565 }, 6330 [ALC861_3ST] = { 6331 .mixers = { alc861_3ST_mixer }, 6332 .init_verbs = { alc861_threestack_init_verbs }, 6333 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 6334 .dac_nids = alc861_dac_nids, 6335 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes), 6336 .channel_mode = alc861_threestack_modes, 6337 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 6338 .adc_nids = alc861_adc_nids, 6339 .input_mux = &alc861_capture_source, 6340 }, 6341 [ALC861_3ST_DIG] = { 6342 .mixers = { alc861_base_mixer }, 6343 .init_verbs = { alc861_threestack_init_verbs }, 6344 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 6345 .dac_nids = alc861_dac_nids, 6346 .dig_out_nid = ALC861_DIGOUT_NID, 6347 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes), 6348 .channel_mode = alc861_threestack_modes, 6349 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 6350 .adc_nids = alc861_adc_nids, 6351 .input_mux = &alc861_capture_source, 6352 }, 6353 [ALC861_6ST_DIG] = { 6354 .mixers = { alc861_base_mixer }, 6355 .init_verbs = { alc861_base_init_verbs }, 6356 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 6357 .dac_nids = alc861_dac_nids, 6358 .dig_out_nid = ALC861_DIGOUT_NID, 6359 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes), 6360 .channel_mode = alc861_8ch_modes, 6361 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 6362 .adc_nids = alc861_adc_nids, 6363 .input_mux = &alc861_capture_source, 6364 }, 6365 [ALC660_3ST] = { 6366 .mixers = { alc861_3ST_mixer }, 6367 .init_verbs = { alc861_threestack_init_verbs }, 6368 .num_dacs = ARRAY_SIZE(alc660_dac_nids), 6369 .dac_nids = alc660_dac_nids, 6370 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes), 6371 .channel_mode = alc861_threestack_modes, 6372 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 6373 .adc_nids = alc861_adc_nids, 6374 .input_mux = &alc861_capture_source, 6375 }, 5566 6376 }; 5567 6377 … … 5569 6379 static int patch_alc861(struct hda_codec *codec) 5570 6380 { 5571 struct alc_spec *spec;5572 int board_config;5573 int err;5574 5575 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);5576 if (spec == NULL)5577 return -ENOMEM;5578 5579 codec->spec = spec;5580 5581 board_config = snd_hda_check_board_config(codec, alc861_cfg_tbl);5582 if (board_config < 0 || board_config >= ALC861_MODEL_LAST) {5583 printk(KERN_INFO "hda_codec: Unknown model for ALC861, trying auto-probe from BIOS...\n");5584 board_config = ALC861_AUTO;5585 }5586 5587 if (board_config == ALC861_AUTO) {5588 /* automatic parse from the BIOS config */5589 err = alc861_parse_auto_config(codec);5590 if (err < 0) {5591 alc_free(codec);5592 return err;5593 } else if (! err) {5594 printk(KERN_INFO "hda_codec: Cannot set up configuration from BIOS. Using base mode...\n");5595 board_config = ALC861_3ST_DIG;5596 }5597 }5598 5599 if (board_config != ALC861_AUTO)5600 setup_preset(spec, &alc861_presets[board_config]);5601 5602 spec->stream_name_analog = "ALC861 Analog";5603 spec->stream_analog_playback = &alc861_pcm_analog_playback;5604 spec->stream_analog_capture = &alc861_pcm_analog_capture;5605 5606 spec->stream_name_digital = "ALC861 Digital";5607 spec->stream_digital_playback = &alc861_pcm_digital_playback;5608 spec->stream_digital_capture = &alc861_pcm_digital_capture;5609 5610 codec->patch_ops = alc_patch_ops;5611 if (board_config == ALC861_AUTO)5612 spec->init_hook = alc861_auto_init;5613 5614 return 0;6381 struct alc_spec *spec; 6382 int board_config; 6383 int err; 6384 6385 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); 6386 if (spec == NULL) 6387 return -ENOMEM; 6388 6389 codec->spec = spec; 6390 6391 board_config = snd_hda_check_board_config(codec, alc861_cfg_tbl); 6392 if (board_config < 0 || board_config >= ALC861_MODEL_LAST) { 6393 printk(KERN_INFO "hda_codec: Unknown model for ALC861, trying auto-probe from BIOS...\n"); 6394 board_config = ALC861_AUTO; 6395 } 6396 6397 if (board_config == ALC861_AUTO) { 6398 /* automatic parse from the BIOS config */ 6399 err = alc861_parse_auto_config(codec); 6400 if (err < 0) { 6401 alc_free(codec); 6402 return err; 6403 } else if (! err) { 6404 printk(KERN_INFO "hda_codec: Cannot set up configuration from BIOS. Using base mode...\n"); 6405 board_config = ALC861_3ST_DIG; 6406 } 6407 } 6408 6409 if (board_config != ALC861_AUTO) 6410 setup_preset(spec, &alc861_presets[board_config]); 6411 6412 spec->stream_name_analog = "ALC861 Analog"; 6413 spec->stream_analog_playback = &alc861_pcm_analog_playback; 6414 spec->stream_analog_capture = &alc861_pcm_analog_capture; 6415 6416 spec->stream_name_digital = "ALC861 Digital"; 6417 spec->stream_digital_playback = &alc861_pcm_digital_playback; 6418 spec->stream_digital_capture = &alc861_pcm_digital_capture; 6419 6420 codec->patch_ops = alc_patch_ops; 6421 if (board_config == ALC861_AUTO) 6422 spec->init_hook = alc861_auto_init; 6423 6424 return 0; 5615 6425 } 5616 6426 … … 5619 6429 */ 5620 6430 struct hda_codec_preset snd_hda_preset_realtek[] = { 5621 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 }, 5622 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 }, 5623 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, 5624 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, 5625 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 }, 5626 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 }, 5627 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 }, 5628 {0} /* terminator */ 5629 }; 6431 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 }, 6432 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 }, 6433 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, 6434 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, 6435 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 }, 6436 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 }, 6437 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 }, 6438 { .id = 0x10ec0861, .rev = 0x100300, .name = "ALC861", 6439 .patch = patch_alc861 }, 6440 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", 6441 .patch = patch_alc861 }, 6442 {0} /* terminator */ 6443 }; -
GPL/trunk/alsa-kernel/pci/hda/patch_sigmatel.c
r76 r77 42 42 #define STAC_D945GTP3 1 43 43 #define STAC_D945GTP5 2 44 #define STAC_MACMINI 3 45 #define STAC_D965_2112 4 46 #define STAC_D965_284B 5 47 #define STAC_922X_MODELS 6 /* number of 922x models */ 44 48 45 49 struct sigmatel_spec { … … 53 57 unsigned int alt_switch: 1; 54 58 unsigned int hp_detect: 1; 59 unsigned int gpio_mute: 1; 55 60 56 61 /* playback */ … … 106 111 }; 107 112 113 static hda_nid_t stac9227_adc_nids[2] = { 114 0x07, 0x08, 115 }; 116 117 #if 0 118 static hda_nid_t d965_2112_dac_nids[3] = { 119 0x02, 0x03, 0x05, 120 }; 121 #endif 122 108 123 static hda_nid_t stac922x_mux_nids[2] = { 109 0x12, 0x13, 124 0x12, 0x13, 125 }; 126 127 static hda_nid_t stac9227_mux_nids[2] = { 128 0x15, 0x16, 110 129 }; 111 130 … … 168 187 static struct hda_verb stac922x_core_init[] = { 169 188 /* set master volume and direct control */ 189 { 0x16, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, 190 {0} 191 }; 192 193 static struct hda_verb stac9227_core_init[] = { 194 /* set master volume and direct control */ 170 195 { 0x16, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, 196 /* unmute node 0x1b */ 197 { 0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 198 {0} 199 }; 200 201 static struct hda_verb d965_2112_core_init[] = { 202 /* set master volume and direct control */ 203 { 0x16, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, 204 /* unmute node 0x1b */ 205 { 0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 206 /* select node 0x03 as DAC */ 207 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x01}, 171 208 {0} 172 209 }; … … 211 248 }; 212 249 250 /* This needs to be generated dynamically based on sequence */ 251 static struct snd_kcontrol_new stac9227_mixer[] = { 252 { 253 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 254 .name = "Input Source", 255 .count = 1, 256 .info = stac92xx_mux_enum_info, 257 .get = stac92xx_mux_enum_get, 258 .put = stac92xx_mux_enum_put, 259 }, 260 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT), 261 HDA_CODEC_MUTE("Capture Switch", 0x1b, 0x0, HDA_OUTPUT), 262 {0} /* end */ 263 }; 264 213 265 static snd_kcontrol_new_t stac927x_mixer[] = { 214 266 { … … 290 342 }; 291 343 292 static unsigned int *stac922x_brd_tbl[] = { 293 ref922x_pin_configs, 294 d945gtp3_pin_configs, 295 d945gtp5_pin_configs, 344 static unsigned int d965_2112_pin_configs[10] = { 345 0x0221401f, 0x40000100, 0x40000100, 0x01014011, 346 0x01a19021, 0x01813024, 0x01452130, 0x40000100, 347 0x02a19320, 0x40000100, 348 }; 349 350 static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = { 351 [STAC_REF] = ref922x_pin_configs, 352 [STAC_D945GTP3] = d945gtp3_pin_configs, 353 [STAC_D945GTP5] = d945gtp5_pin_configs, 354 [STAC_D965_2112] = d965_2112_pin_configs, 296 355 }; 297 356 … … 322 381 .pci_subdevice = 0x0417, 323 382 .config = STAC_D945GTP5 }, /* Intel D975XBK - 5 Stack */ 383 { .pci_subvendor = 0x8384, 384 .pci_subdevice = 0x7680, 385 .config = STAC_MACMINI }, /* Apple Mac Mini (early 2006) */ 386 { .pci_subvendor = PCI_VENDOR_ID_INTEL, 387 .pci_subdevice = 0x2112, 388 .config = STAC_D965_2112 }, 389 { .pci_subvendor = PCI_VENDOR_ID_INTEL, 390 .pci_subdevice = 0x284b, 391 .config = STAC_D965_284B }, 324 392 {0} /* terminator */ 325 393 }; … … 842 910 imux->num_items++; 843 911 } 844 } 912 } 913 if (imux->num_items == 1) { 914 /* 915 * Set the current input for the muxes. 916 * The STAC9221 has two input muxes with identical source 917 * NID lists. Hopefully this won't get confused. 918 */ 919 for (i = 0; i < spec->num_muxes; i++) { 920 snd_hda_codec_write(codec, spec->mux_nids[i], 0, 921 AC_VERB_SET_CONNECT_SEL, 922 imux->items[0].index); 923 } 924 } 845 925 846 926 return 0; … … 877 957 if (! spec->autocfg.line_outs) 878 958 return 0; /* can't find valid pin config */ 879 if ((err = stac92xx_add_dyn_out_pins(codec, &spec->autocfg)) < 0) 880 return err; 881 if ((err = stac92xx_auto_fill_dac_nids(codec, &spec->autocfg)) < 0) 882 return err; 959 960 if ((err = stac92xx_add_dyn_out_pins(codec, &spec->autocfg)) < 0) 961 return err; 962 963 if (spec->multiout.num_dacs == 0) 964 if ((err = stac92xx_auto_fill_dac_nids(codec, &spec->autocfg)) < 0) 965 return err; 883 966 884 967 if ((err = stac92xx_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 || … … 951 1034 spec->input_mux = &spec->private_imux; 952 1035 953 return 1; 1036 return 1; 1037 } 1038 1039 /* 1040 * Early 2006 Intel Macintoshes with STAC9220X5 codecs seem to have a 1041 * funky external mute control using GPIO pins. 1042 */ 1043 1044 static void stac922x_gpio_mute(struct hda_codec *codec, int pin, int muted) 1045 { 1046 unsigned int gpiostate, gpiomask, gpiodir; 1047 1048 gpiostate = snd_hda_codec_read(codec, codec->afg, 0, 1049 AC_VERB_GET_GPIO_DATA, 0); 1050 1051 if (!muted) 1052 gpiostate |= (1 << pin); 1053 else 1054 gpiostate &= ~(1 << pin); 1055 1056 gpiomask = snd_hda_codec_read(codec, codec->afg, 0, 1057 AC_VERB_GET_GPIO_MASK, 0); 1058 gpiomask |= (1 << pin); 1059 1060 gpiodir = snd_hda_codec_read(codec, codec->afg, 0, 1061 AC_VERB_GET_GPIO_DIRECTION, 0); 1062 gpiodir |= (1 << pin); 1063 1064 /* AppleHDA seems to do this -- WTF is this verb?? */ 1065 snd_hda_codec_write(codec, codec->afg, 0, 0x7e7, 0); 1066 1067 snd_hda_codec_write(codec, codec->afg, 0, 1068 AC_VERB_SET_GPIO_MASK, gpiomask); 1069 snd_hda_codec_write(codec, codec->afg, 0, 1070 AC_VERB_SET_GPIO_DIRECTION, gpiodir); 1071 1072 msleep(1); 1073 1074 snd_hda_codec_write(codec, codec->afg, 0, 1075 AC_VERB_SET_GPIO_DATA, gpiostate); 954 1076 } 955 1077 … … 985 1107 stac92xx_auto_set_pinctl(codec, cfg->dig_in_pin, 986 1108 AC_PINCTL_IN_EN); 1109 if (spec->gpio_mute) { 1110 stac922x_gpio_mute(codec, 0, 0); 1111 stac922x_gpio_mute(codec, 1, 0); 1112 } 987 1113 988 1114 return 0; … … 1135 1261 spec->board_config = snd_hda_check_board_config(codec, stac922x_cfg_tbl); 1136 1262 if (spec->board_config < 0) 1137 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC922x, using BIOS defaults\n");1138 else{1263 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC922x, using BIOS defaults\n"); 1264 else if (stac922x_brd_tbl[spec->board_config] != NULL) { 1139 1265 spec->num_pins = 10; 1140 1266 spec->pin_nids = stac922x_pin_nids; … … 1152 1278 spec->multiout.dac_nids = spec->dac_nids; 1153 1279 1280 switch (spec->board_config) { 1281 case STAC_D965_2112: 1282 spec->adc_nids = stac9227_adc_nids; 1283 spec->mux_nids = stac9227_mux_nids; 1284 #if 0 1285 spec->multiout.dac_nids = d965_2112_dac_nids; 1286 spec->multiout.num_dacs = ARRAY_SIZE(d965_2112_dac_nids); 1287 #endif 1288 spec->init = d965_2112_core_init; 1289 spec->mixer = stac9227_mixer; 1290 break; 1291 case STAC_D965_284B: 1292 spec->adc_nids = stac9227_adc_nids; 1293 spec->mux_nids = stac9227_mux_nids; 1294 spec->init = stac9227_core_init; 1295 spec->mixer = stac9227_mixer; 1296 break; 1297 } 1154 1298 err = stac92xx_parse_auto_config(codec, 0x08, 0x09); 1155 1299 if (err < 0) { … … 1158 1302 } 1159 1303 1304 if (spec->board_config == STAC_MACMINI) 1305 spec->gpio_mute = 1; 1160 1306 codec->patch_ops = stac92xx_patch_ops; 1161 1307 … … 1216 1362 .num_items = 2, 1217 1363 .items = { 1218 /* { "HP", 0x0 }, 1219 { "Unknown", 0x1 }, */1364 /* { "HP", 0x0 }, */ 1365 { "Line", 0x1 }, 1220 1366 { "Mic", 0x2 }, 1221 1367 { "PCM", 0x3 }, … … 1266 1412 1267 1413 change = snd_hda_codec_amp_update(codec, 0x02, 0, HDA_OUTPUT, 0, 1268 0x80, valp[0] & 0x80);1414 0x80, (valp[0] ? 0 : 0x80)); 1269 1415 change |= snd_hda_codec_amp_update(codec, 0x02, 1, HDA_OUTPUT, 0, 1270 0x80, valp[1] & 0x80);1416 0x80, (valp[1] ? 0 : 0x80)); 1271 1417 snd_hda_codec_amp_update(codec, 0x05, 0, HDA_OUTPUT, 0, 1272 0x80, valp[0] & 0x80);1418 0x80, (valp[0] ? 0 : 0x80)); 1273 1419 snd_hda_codec_amp_update(codec, 0x05, 1, HDA_OUTPUT, 0, 1274 0x80, valp[1] & 0x80);1420 0x80, (valp[1] ? 0 : 0x80)); 1275 1421 return change; 1276 1422 } … … 1369 1515 { .id = 0x83847690, .name = "STAC9200", .patch = patch_stac9200 }, 1370 1516 { .id = 0x83847882, .name = "STAC9220 A1", .patch = patch_stac922x }, 1371 { .id = 0x83847680, .name = "STAC9221 A1", .patch = patch_stac922x }, 1517 { .id = 0x83847680, .name = "STAC9221 A1", .patch = patch_stac922x }, 1518 { .id = 0x83847618, .name = "STAC9227", .patch = patch_stac922x }, 1519 { .id = 0x83847619, .name = "STAC9227", .patch = patch_stac922x }, 1520 { .id = 0x83847616, .name = "STAC9228", .patch = patch_stac922x }, 1521 { .id = 0x83847617, .name = "STAC9228", .patch = patch_stac922x }, 1522 { .id = 0x83847614, .name = "STAC9229", .patch = patch_stac922x }, 1523 { .id = 0x83847615, .name = "STAC9229", .patch = patch_stac922x }, 1372 1524 { .id = 0x83847880, .name = "STAC9220 A2", .patch = patch_stac922x }, 1373 1525 { .id = 0x83847681, .name = "STAC9220D/9223D A2", .patch = patch_stac922x }, -
GPL/trunk/alsa-kernel/pci/intel8x0.c
r76 r77 1840 1840 { 1841 1841 .subvendor = 0x1028, 1842 .subdevice = 0x014e, 1843 .name = "Dell D800", /* STAC9750/51 */ 1844 .type = AC97_TUNE_HP_ONLY 1845 }, 1846 { 1847 .subvendor = 0x1028, 1842 1848 .subdevice = 0x0163, 1843 1849 .name = "Dell Unknown", /* STAC9750/51 */ … … 1982 1988 .type = AC97_TUNE_HP_ONLY 1983 1989 }, 1990 { 1991 .subvendor = 0x10f1, 1992 .subdevice = 0x2895, 1993 .name = "Tyan Thunder K8WE", 1994 .type = AC97_TUNE_HP_ONLY 1995 }, 1984 1996 { 1985 1997 .subvendor = 0x110a, … … 2296 2308 // cnt &= ~ICH_ACLINK; 2297 2309 cnt &= ~(ICH_ACLINK | ICH_PCM_246_MASK); 2310 #ifdef CONFIG_SND_AC97_POWER_SAVE 2311 /* do cold reset - the full ac97 powerdown may leave the controller 2312 * in a warm state but actually it cannot communicate with the codec. 2313 */ 2314 iputdword(chip, ICHREG(GLOB_CNT), cnt & ~ICH_AC97COLD); 2315 cnt = igetdword(chip, ICHREG(GLOB_CNT)); 2316 udelay(10); 2317 iputdword(chip, ICHREG(GLOB_CNT), cnt | ICH_AC97COLD); 2318 msleep(1); 2319 #else 2298 2320 cnt |= (cnt & ICH_AC97COLD) == 0 ? ICH_AC97COLD : ICH_AC97WARM; 2299 2321 … … 2321 2343 return -EIO; 2322 2344 __ok: 2345 #endif /* CONFIG_SND_AC97_POWER_SAVE */ 2323 2346 #ifdef DEBUG 2324 2347 dprintf(("ICH chip init ACLink ON")); … … 2542 2565 chip->irq = pci->irq; 2543 2566 synchronize_irq(chip->irq); 2544 snd_intel8x0_chip_init(chip, 1);2567 snd_intel8x0_chip_init(chip, 0); 2545 2568 /* re-initialize mixer stuff */ 2546 2569 if (chip->device_type == DEVICE_INTEL_ICH4 || … … 2658 2681 chip->ac97_bus->clock = (chip->ac97_bus->clock * 48000) / pos; 2659 2682 printk(KERN_INFO "intel8x0: clocking to %d\n", chip->ac97_bus->clock); 2683 snd_ac97_update_power(chip->ac97[0], AC97_PCM_FRONT_DAC_RATE, 0); 2660 2684 } 2661 2685 -
GPL/trunk/alsa-kernel/pci/maestro3.c
r76 r77 2889 2889 /* TODO enable MIDI IRQ and I/O */ 2890 2890 err = snd_mpu401_uart_new(chip->card, 0, MPU401_HW_MPU401, 2891 chip->iobase + MPU401_DATA_PORT, 1, 2891 chip->iobase + MPU401_DATA_PORT, 2892 MPU401_INFO_INTEGRATED, 2892 2893 chip->irq, 0, &chip->rmidi); 2893 2894 if (err < 0) -
GPL/trunk/alsa-kernel/pci/sonicvibes.c
r32 r77 1578 1578 return err; 1579 1579 } 1580 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_SONICVIBES,1581 sonic->midi_port, 1,1580 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_SONICVIBES, 1581 sonic->midi_port, MPU401_INFO_INTEGRATED, 1582 1582 sonic->irq, 0, 1583 1583 &midi_uart)) < 0) { -
GPL/trunk/alsa-kernel/pci/trident/trident.c
r34 r77 149 149 } 150 150 } 151 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_TRID4DWAVE, 152 trident->midi_port, 1, 151 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_TRID4DWAVE, 152 trident->midi_port, 153 MPU401_INFO_INTEGRATED, 153 154 trident->irq, 0, &trident->rmidi)) < 0) { 154 155 snd_card_free(card); -
GPL/trunk/alsa-kernel/pci/via82xx.c
r76 r77 1275 1275 if (! ratep->used) 1276 1276 ratep->rate = 0; 1277 spin_unlock_irq(&ratep->lock); 1278 1277 spin_unlock_irq(&ratep->lock); 1278 1279 if (! ratep->rate) { 1280 if (! viadev->direction) { 1281 snd_ac97_update_power(chip->ac97, 1282 AC97_PCM_FRONT_DAC_RATE, 0); 1283 snd_ac97_update_power(chip->ac97, 1284 AC97_PCM_SURR_DAC_RATE, 0); 1285 snd_ac97_update_power(chip->ac97, 1286 AC97_PCM_LFE_DAC_RATE, 0); 1287 } else 1288 snd_ac97_update_power(chip->ac97, 1289 AC97_PCM_LR_ADC_RATE, 0); 1290 } 1279 1291 viadev->substream = NULL; 1280 1292 return 0; … … 1772 1784 .subdevice = 0x2032, 1773 1785 .name = "Targa Traveller 811", 1774 .type = AC97_TUNE_HP_ONLY, 1786 .type = AC97_TUNE_HP_ONLY, 1787 }, 1788 { 1789 .subvendor = 0x161f, 1790 .subdevice = 0x2032, 1791 .name = "m680x", 1792 .type = AC97_TUNE_HP_ONLY, /* http://launchpad.net/bugs/38546 */ 1775 1793 }, 1776 1794 {0} /* terminator */ … … 1971 1989 pci_write_config_byte(chip->pci, VIA_PNP_CONTROL, legacy_cfg); 1972 1990 if (chip->mpu_res) { 1973 if (snd_mpu401_uart_new(chip->card, 0, MPU401_HW_VIA686A,1974 mpu_port, 1,1975 chip->irq, 0, &chip->rmidi) < 0) {1991 if (snd_mpu401_uart_new(chip->card, 0, MPU401_HW_VIA686A, 1992 mpu_port, MPU401_INFO_INTEGRATED, 1993 chip->irq, 0, &chip->rmidi) < 0) { 1976 1994 printk(KERN_WARNING "unable to initialize MPU-401" 1977 1995 " at 0x%lx, skipping\n", mpu_port); … … 2330 2348 }; 2331 2349 2332 static int __devinit check_dxs_list(struct pci_dev *pci )2350 static int __devinit check_dxs_list(struct pci_dev *pci, int revision) 2333 2351 { 2334 2352 static struct dxs_whitelist whitelist[] = { … … 2360 2378 { .subvendor = 0x1462, .subdevice = 0x0470, .action = VIA_DXS_SRC }, /* MSI KT880 Delta-FSR */ 2361 2379 { .subvendor = 0x1462, .subdevice = 0x3800, .action = VIA_DXS_ENABLE }, /* MSI KT266 */ 2362 { .subvendor = 0x1462, .subdevice = 0x5901, .action = VIA_DXS_NO_VRA }, /* MSI KT6 Delta-SR */2363 { .subvendor = 0x1462, .subdevice = 0x7023, .action = VIA_DXS_NO_VRA}, /* MSI K8T Neo2-FI */2380 { .subvendor = 0x1462, .subdevice = 0x5901, .action = VIA_DXS_NO_VRA }, /* MSI KT6 Delta-SR */ 2381 { .subvendor = 0x1462, .subdevice = 0x7023, .action = VIA_DXS_SRC }, /* MSI K8T Neo2-FI */ 2364 2382 { .subvendor = 0x1462, .subdevice = 0x7120, .action = VIA_DXS_ENABLE }, /* MSI KT4V */ 2365 2383 { .subvendor = 0x1462, .subdevice = 0x7142, .action = VIA_DXS_ENABLE }, /* MSI K8MM-V */ … … 2406 2424 return w->action; 2407 2425 } 2408 } 2409 2426 } 2427 /* for newer revision, default to DXS_SRC */ 2428 if (revision >= VIA_REV_8235) 2429 return VIA_DXS_SRC; 2410 2430 /* 2411 2431 * not detected, try 48k rate only to be sure. … … 2451 2471 } 2452 2472 if (chip_type != TYPE_VIA8233A) { 2453 if (dxs_support == VIA_DXS_AUTO)2454 dxs_support = check_dxs_list(pci);2473 if (dxs_support == VIA_DXS_AUTO) 2474 dxs_support = check_dxs_list(pci, revision); 2455 2475 /* force to use VIA8233 or 8233A model according to 2456 2476 * dxs_support module option -
GPL/trunk/alsa-kernel/pci/ymfpci/ymfpci.c
r35 r77 226 226 #if 1 227 227 if (chip->mpu_res) { 228 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_YMFPCI, 229 mpu_port[dev], 1, 230 pci->irq, 0, &chip->rawmidi)) < 0) { 228 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_YMFPCI, 229 mpu_port[dev], 230 MPU401_INFO_INTEGRATED, 231 pci->irq, 0, &chip->rawmidi)) < 0) { 231 232 printk(KERN_WARNING "ymfpci: cannot initialize MPU401 at 0x%lx, skipping...\n", mpu_port[dev]); 232 233 legacy_ctrl &= ~YMFPCI_LEGACY_MIEN; /* disable MPU401 irq */ -
GPL/trunk/alsa-kernel/synth/emux/soundfont.c
r34 r77 195 195 break; 196 196 case SNDRV_SFNT_REMOVE_INFO: 197 /* patch must be opened */198 if (sflist->currsf) {199 snd_printk("soundfont: remove_info: patch not opened\n");200 rc = -EINVAL;201 } else {202 int bank, instr;203 bank = ((unsigned short)patch.optarg >> 8) & 0xff;204 instr = (unsigned short)patch.optarg & 0xff;205 if (! remove_info(sflist, sflist->currsf, bank, instr))206 rc = -EINVAL;207 else208 rc = 0;209 }210 break;197 /* patch must be opened */ 198 if (!sflist->currsf) { 199 snd_printk("soundfont: remove_info: patch not opened\n"); 200 rc = -EINVAL; 201 } else { 202 int bank, instr; 203 bank = ((unsigned short)patch.optarg >> 8) & 0xff; 204 instr = (unsigned short)patch.optarg & 0xff; 205 if (! remove_info(sflist, sflist->currsf, bank, instr)) 206 rc = -EINVAL; 207 else 208 rc = 0; 209 } 210 break; 211 211 } 212 212 unlock_preset(sflist); -
GPL/trunk/include/version.mak
r76 r77 11 11 BLDLVL_REVISION = 1.1 12 12 BLDLVL_FILEVER = 4 13 BLDLVL_DATETIME = 31.03.2006 01:05:3413 BLDLVL_DATETIME = 09.07.2006 21:27:17 14 14 BLDLVL_MACHINE = VLAD -
GPL/trunk/lib32/ioctl.c
r76 r77 333 333 pHandle->file.f_flags = O_NONBLOCK; 334 334 335 printk("GetUniaudPcmCaps: cp1. phandle %x\n", pHandle); 335 336 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_INFO, (ULONG)pcminfo); 336 337 if(ret != 0) { … … 350 351 pWaveCaps->nrStreams = pcminfo->subdevices_count; 351 352 353 printk("GetUniaudPcmCaps: cp2. nr of streams: %i\n", pWaveCaps->nrStreams); 352 354 //get all hardware parameters 353 355 _snd_pcm_hw_params_any(params); … … 359 361 continue; 360 362 } 363 printk("GetUniaudPcmCaps: cp3\n"); 361 364 362 365 pWaveCaps->ulMinChannels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS)->min; -
GPL/trunk/lib32/sound.c
r76 r77 532 532 } 533 533 534 printk("OSS32_WaveOpen: cp1\n"); 534 535 ret = alsa_fops->open(&pHandle->inode, &pHandle->file); 536 printk("OSS32_WaveOpen: cp2\n"); 535 537 /* check if PCM already opened (stupid uniaud16.sys doesnt closes it) */ 536 538 if (ret == -16) … … 549 551 } 550 552 } 553 printk("OSS32_WaveOpen: cp3\n"); 551 554 552 555 if(ret) { … … 557 560 } 558 561 pHandle->magic = MAGIC_WAVE_ALSA32; 562 printk("OSS32_WaveOpen: cp4\n"); 559 563 560 564 if (pStreamId)
Note:
See TracChangeset
for help on using the changeset viewer.
