diff options
Diffstat (limited to 'sound/pci/hda')
-rw-r--r-- | sound/pci/hda/hda_codec.c | 2 | ||||
-rw-r--r-- | sound/pci/hda/hda_codec.h | 2 | ||||
-rw-r--r-- | sound/pci/hda/hda_hwdep.c | 2 | ||||
-rw-r--r-- | sound/pci/hda/hda_intel.c | 306 | ||||
-rw-r--r-- | sound/pci/hda/hda_proc.c | 5 | ||||
-rw-r--r-- | sound/pci/hda/patch_analog.c | 38 | ||||
-rw-r--r-- | sound/pci/hda/patch_conexant.c | 33 | ||||
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 548 | ||||
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 71 |
9 files changed, 854 insertions, 153 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index a6be6e3e8716..d2e1093f8e97 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -2335,7 +2335,7 @@ int snd_hda_check_board_config(struct hda_codec *codec, | |||
2335 | if (!tbl) | 2335 | if (!tbl) |
2336 | return -1; | 2336 | return -1; |
2337 | if (tbl->value >= 0 && tbl->value < num_configs) { | 2337 | if (tbl->value >= 0 && tbl->value < num_configs) { |
2338 | #ifdef CONFIG_SND_DEBUG_DETECT | 2338 | #ifdef CONFIG_SND_DEBUG_VERBOSE |
2339 | char tmp[10]; | 2339 | char tmp[10]; |
2340 | const char *model = NULL; | 2340 | const char *model = NULL; |
2341 | if (models) | 2341 | if (models) |
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index dcd390b2bbaa..efc682888b31 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h | |||
@@ -78,7 +78,7 @@ enum { | |||
78 | #define AC_VERB_GET_BEEP_CONTROL 0x0f0a | 78 | #define AC_VERB_GET_BEEP_CONTROL 0x0f0a |
79 | #define AC_VERB_GET_EAPD_BTLENABLE 0x0f0c | 79 | #define AC_VERB_GET_EAPD_BTLENABLE 0x0f0c |
80 | #define AC_VERB_GET_DIGI_CONVERT_1 0x0f0d | 80 | #define AC_VERB_GET_DIGI_CONVERT_1 0x0f0d |
81 | #define AC_VERB_GET_DIGI_CONVERT_2 0x0f0e | 81 | #define AC_VERB_GET_DIGI_CONVERT_2 0x0f0e /* unused */ |
82 | #define AC_VERB_GET_VOLUME_KNOB_CONTROL 0x0f0f | 82 | #define AC_VERB_GET_VOLUME_KNOB_CONTROL 0x0f0f |
83 | /* f10-f1a: GPIO */ | 83 | /* f10-f1a: GPIO */ |
84 | #define AC_VERB_GET_GPIO_DATA 0x0f15 | 84 | #define AC_VERB_GET_GPIO_DATA 0x0f15 |
diff --git a/sound/pci/hda/hda_hwdep.c b/sound/pci/hda/hda_hwdep.c index 2177d9af5334..6e18a422d993 100644 --- a/sound/pci/hda/hda_hwdep.c +++ b/sound/pci/hda/hda_hwdep.c | |||
@@ -88,7 +88,7 @@ static int hda_hwdep_ioctl_compat(struct snd_hwdep *hw, struct file *file, | |||
88 | 88 | ||
89 | static int hda_hwdep_open(struct snd_hwdep *hw, struct file *file) | 89 | static int hda_hwdep_open(struct snd_hwdep *hw, struct file *file) |
90 | { | 90 | { |
91 | #ifndef CONFIG_SND_DEBUG_DETECT | 91 | #ifndef CONFIG_SND_DEBUG_VERBOSE |
92 | if (!capable(CAP_SYS_RAWIO)) | 92 | if (!capable(CAP_SYS_RAWIO)) |
93 | return -EACCES; | 93 | return -EACCES; |
94 | #endif | 94 | #endif |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index b3a618eb42cd..16715a68ba5e 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -55,6 +55,7 @@ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; | |||
55 | static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; | 55 | static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; |
56 | static char *model[SNDRV_CARDS]; | 56 | static char *model[SNDRV_CARDS]; |
57 | static int position_fix[SNDRV_CARDS]; | 57 | static int position_fix[SNDRV_CARDS]; |
58 | static int bdl_pos_adj[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1}; | ||
58 | static int probe_mask[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1}; | 59 | static int probe_mask[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1}; |
59 | static int single_cmd; | 60 | static int single_cmd; |
60 | static int enable_msi; | 61 | static int enable_msi; |
@@ -69,7 +70,9 @@ module_param_array(model, charp, NULL, 0444); | |||
69 | MODULE_PARM_DESC(model, "Use the given board model."); | 70 | MODULE_PARM_DESC(model, "Use the given board model."); |
70 | module_param_array(position_fix, int, NULL, 0444); | 71 | module_param_array(position_fix, int, NULL, 0444); |
71 | MODULE_PARM_DESC(position_fix, "Fix DMA pointer " | 72 | MODULE_PARM_DESC(position_fix, "Fix DMA pointer " |
72 | "(0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size)."); | 73 | "(0 = auto, 1 = none, 2 = POSBUF)."); |
74 | module_param_array(bdl_pos_adj, int, NULL, 0644); | ||
75 | MODULE_PARM_DESC(bdl_pos_adj, "BDL position adjustment offset."); | ||
73 | module_param_array(probe_mask, int, NULL, 0444); | 76 | module_param_array(probe_mask, int, NULL, 0444); |
74 | MODULE_PARM_DESC(probe_mask, "Bitmask to probe codecs (default = -1)."); | 77 | MODULE_PARM_DESC(probe_mask, "Bitmask to probe codecs (default = -1)."); |
75 | module_param(single_cmd, bool, 0444); | 78 | module_param(single_cmd, bool, 0444); |
@@ -197,6 +200,10 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 }; | |||
197 | #define ATIHDMI_NUM_CAPTURE 0 | 200 | #define ATIHDMI_NUM_CAPTURE 0 |
198 | #define ATIHDMI_NUM_PLAYBACK 1 | 201 | #define ATIHDMI_NUM_PLAYBACK 1 |
199 | 202 | ||
203 | /* TERA has 4 playback and 3 capture */ | ||
204 | #define TERA_NUM_CAPTURE 3 | ||
205 | #define TERA_NUM_PLAYBACK 4 | ||
206 | |||
200 | /* this number is statically defined for simplicity */ | 207 | /* this number is statically defined for simplicity */ |
201 | #define MAX_AZX_DEV 16 | 208 | #define MAX_AZX_DEV 16 |
202 | 209 | ||
@@ -259,9 +266,8 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 }; | |||
259 | /* position fix mode */ | 266 | /* position fix mode */ |
260 | enum { | 267 | enum { |
261 | POS_FIX_AUTO, | 268 | POS_FIX_AUTO, |
262 | POS_FIX_NONE, | 269 | POS_FIX_LPIB, |
263 | POS_FIX_POSBUF, | 270 | POS_FIX_POSBUF, |
264 | POS_FIX_FIFO, | ||
265 | }; | 271 | }; |
266 | 272 | ||
267 | /* Defines for ATI HD Audio support in SB450 south bridge */ | 273 | /* Defines for ATI HD Audio support in SB450 south bridge */ |
@@ -285,6 +291,7 @@ struct azx_dev { | |||
285 | u32 *posbuf; /* position buffer pointer */ | 291 | u32 *posbuf; /* position buffer pointer */ |
286 | 292 | ||
287 | unsigned int bufsize; /* size of the play buffer in bytes */ | 293 | unsigned int bufsize; /* size of the play buffer in bytes */ |
294 | unsigned int period_bytes; /* size of the period in bytes */ | ||
288 | unsigned int frags; /* number for period in the play buffer */ | 295 | unsigned int frags; /* number for period in the play buffer */ |
289 | unsigned int fifo_size; /* FIFO size */ | 296 | unsigned int fifo_size; /* FIFO size */ |
290 | 297 | ||
@@ -301,11 +308,11 @@ struct azx_dev { | |||
301 | */ | 308 | */ |
302 | unsigned char stream_tag; /* assigned stream */ | 309 | unsigned char stream_tag; /* assigned stream */ |
303 | unsigned char index; /* stream index */ | 310 | unsigned char index; /* stream index */ |
304 | /* for sanity check of position buffer */ | ||
305 | unsigned int period_intr; | ||
306 | 311 | ||
307 | unsigned int opened :1; | 312 | unsigned int opened :1; |
308 | unsigned int running :1; | 313 | unsigned int running :1; |
314 | unsigned int irq_pending :1; | ||
315 | unsigned int irq_ignore :1; | ||
309 | }; | 316 | }; |
310 | 317 | ||
311 | /* CORB/RIRB */ | 318 | /* CORB/RIRB */ |
@@ -323,6 +330,7 @@ struct azx_rb { | |||
323 | struct azx { | 330 | struct azx { |
324 | struct snd_card *card; | 331 | struct snd_card *card; |
325 | struct pci_dev *pci; | 332 | struct pci_dev *pci; |
333 | int dev_index; | ||
326 | 334 | ||
327 | /* chip type specific */ | 335 | /* chip type specific */ |
328 | int driver_type; | 336 | int driver_type; |
@@ -366,9 +374,13 @@ struct azx { | |||
366 | unsigned int single_cmd :1; | 374 | unsigned int single_cmd :1; |
367 | unsigned int polling_mode :1; | 375 | unsigned int polling_mode :1; |
368 | unsigned int msi :1; | 376 | unsigned int msi :1; |
377 | unsigned int irq_pending_warned :1; | ||
369 | 378 | ||
370 | /* for debugging */ | 379 | /* for debugging */ |
371 | unsigned int last_cmd; /* last issued command (to sync) */ | 380 | unsigned int last_cmd; /* last issued command (to sync) */ |
381 | |||
382 | /* for pending irqs */ | ||
383 | struct work_struct irq_pending_work; | ||
372 | }; | 384 | }; |
373 | 385 | ||
374 | /* driver types */ | 386 | /* driver types */ |
@@ -381,6 +393,7 @@ enum { | |||
381 | AZX_DRIVER_SIS, | 393 | AZX_DRIVER_SIS, |
382 | AZX_DRIVER_ULI, | 394 | AZX_DRIVER_ULI, |
383 | AZX_DRIVER_NVIDIA, | 395 | AZX_DRIVER_NVIDIA, |
396 | AZX_DRIVER_TERA, | ||
384 | }; | 397 | }; |
385 | 398 | ||
386 | static char *driver_short_names[] __devinitdata = { | 399 | static char *driver_short_names[] __devinitdata = { |
@@ -392,6 +405,7 @@ static char *driver_short_names[] __devinitdata = { | |||
392 | [AZX_DRIVER_SIS] = "HDA SIS966", | 405 | [AZX_DRIVER_SIS] = "HDA SIS966", |
393 | [AZX_DRIVER_ULI] = "HDA ULI M5461", | 406 | [AZX_DRIVER_ULI] = "HDA ULI M5461", |
394 | [AZX_DRIVER_NVIDIA] = "HDA NVidia", | 407 | [AZX_DRIVER_NVIDIA] = "HDA NVidia", |
408 | [AZX_DRIVER_TERA] = "HDA Teradici", | ||
395 | }; | 409 | }; |
396 | 410 | ||
397 | /* | 411 | /* |
@@ -426,11 +440,6 @@ static char *driver_short_names[] __devinitdata = { | |||
426 | /* for pcm support */ | 440 | /* for pcm support */ |
427 | #define get_azx_dev(substream) (substream->runtime->private_data) | 441 | #define get_azx_dev(substream) (substream->runtime->private_data) |
428 | 442 | ||
429 | /* Get the upper 32bit of the given dma_addr_t | ||
430 | * Compiler should optimize and eliminate the code if dma_addr_t is 32bit | ||
431 | */ | ||
432 | #define upper_32bit(addr) (sizeof(addr) > 4 ? (u32)((addr) >> 32) : (u32)0) | ||
433 | |||
434 | static int azx_acquire_irq(struct azx *chip, int do_disconnect); | 443 | static int azx_acquire_irq(struct azx *chip, int do_disconnect); |
435 | 444 | ||
436 | /* | 445 | /* |
@@ -461,7 +470,7 @@ static void azx_init_cmd_io(struct azx *chip) | |||
461 | chip->corb.addr = chip->rb.addr; | 470 | chip->corb.addr = chip->rb.addr; |
462 | chip->corb.buf = (u32 *)chip->rb.area; | 471 | chip->corb.buf = (u32 *)chip->rb.area; |
463 | azx_writel(chip, CORBLBASE, (u32)chip->corb.addr); | 472 | azx_writel(chip, CORBLBASE, (u32)chip->corb.addr); |
464 | azx_writel(chip, CORBUBASE, upper_32bit(chip->corb.addr)); | 473 | azx_writel(chip, CORBUBASE, upper_32_bits(chip->corb.addr)); |
465 | 474 | ||
466 | /* set the corb size to 256 entries (ULI requires explicitly) */ | 475 | /* set the corb size to 256 entries (ULI requires explicitly) */ |
467 | azx_writeb(chip, CORBSIZE, 0x02); | 476 | azx_writeb(chip, CORBSIZE, 0x02); |
@@ -476,7 +485,7 @@ static void azx_init_cmd_io(struct azx *chip) | |||
476 | chip->rirb.addr = chip->rb.addr + 2048; | 485 | chip->rirb.addr = chip->rb.addr + 2048; |
477 | chip->rirb.buf = (u32 *)(chip->rb.area + 2048); | 486 | chip->rirb.buf = (u32 *)(chip->rb.area + 2048); |
478 | azx_writel(chip, RIRBLBASE, (u32)chip->rirb.addr); | 487 | azx_writel(chip, RIRBLBASE, (u32)chip->rirb.addr); |
479 | azx_writel(chip, RIRBUBASE, upper_32bit(chip->rirb.addr)); | 488 | azx_writel(chip, RIRBUBASE, upper_32_bits(chip->rirb.addr)); |
480 | 489 | ||
481 | /* set the rirb size to 256 entries (ULI requires explicitly) */ | 490 | /* set the rirb size to 256 entries (ULI requires explicitly) */ |
482 | azx_writeb(chip, RIRBSIZE, 0x02); | 491 | azx_writeb(chip, RIRBSIZE, 0x02); |
@@ -847,7 +856,7 @@ static void azx_init_chip(struct azx *chip) | |||
847 | 856 | ||
848 | /* program the position buffer */ | 857 | /* program the position buffer */ |
849 | azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr); | 858 | azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr); |
850 | azx_writel(chip, DPUBASE, upper_32bit(chip->posbuf.addr)); | 859 | azx_writel(chip, DPUBASE, upper_32_bits(chip->posbuf.addr)); |
851 | 860 | ||
852 | chip->initialized = 1; | 861 | chip->initialized = 1; |
853 | } | 862 | } |
@@ -908,6 +917,8 @@ static void azx_init_pci(struct azx *chip) | |||
908 | } | 917 | } |
909 | 918 | ||
910 | 919 | ||
920 | static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev); | ||
921 | |||
911 | /* | 922 | /* |
912 | * interrupt handler | 923 | * interrupt handler |
913 | */ | 924 | */ |
@@ -930,11 +941,23 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id) | |||
930 | azx_dev = &chip->azx_dev[i]; | 941 | azx_dev = &chip->azx_dev[i]; |
931 | if (status & azx_dev->sd_int_sta_mask) { | 942 | if (status & azx_dev->sd_int_sta_mask) { |
932 | azx_sd_writeb(azx_dev, SD_STS, SD_INT_MASK); | 943 | azx_sd_writeb(azx_dev, SD_STS, SD_INT_MASK); |
933 | if (azx_dev->substream && azx_dev->running) { | 944 | if (!azx_dev->substream || !azx_dev->running) |
934 | azx_dev->period_intr++; | 945 | continue; |
946 | /* ignore the first dummy IRQ (due to pos_adj) */ | ||
947 | if (azx_dev->irq_ignore) { | ||
948 | azx_dev->irq_ignore = 0; | ||
949 | continue; | ||
950 | } | ||
951 | /* check whether this IRQ is really acceptable */ | ||
952 | if (azx_position_ok(chip, azx_dev)) { | ||
953 | azx_dev->irq_pending = 0; | ||
935 | spin_unlock(&chip->reg_lock); | 954 | spin_unlock(&chip->reg_lock); |
936 | snd_pcm_period_elapsed(azx_dev->substream); | 955 | snd_pcm_period_elapsed(azx_dev->substream); |
937 | spin_lock(&chip->reg_lock); | 956 | spin_lock(&chip->reg_lock); |
957 | } else { | ||
958 | /* bogus IRQ, process it later */ | ||
959 | azx_dev->irq_pending = 1; | ||
960 | schedule_work(&chip->irq_pending_work); | ||
938 | } | 961 | } |
939 | } | 962 | } |
940 | } | 963 | } |
@@ -959,59 +982,107 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id) | |||
959 | 982 | ||
960 | 983 | ||
961 | /* | 984 | /* |
985 | * set up a BDL entry | ||
986 | */ | ||
987 | static int setup_bdle(struct snd_pcm_substream *substream, | ||
988 | struct azx_dev *azx_dev, u32 **bdlp, | ||
989 | int ofs, int size, int with_ioc) | ||
990 | { | ||
991 | struct snd_sg_buf *sgbuf = snd_pcm_substream_sgbuf(substream); | ||
992 | u32 *bdl = *bdlp; | ||
993 | |||
994 | while (size > 0) { | ||
995 | dma_addr_t addr; | ||
996 | int chunk; | ||
997 | |||
998 | if (azx_dev->frags >= AZX_MAX_BDL_ENTRIES) | ||
999 | return -EINVAL; | ||
1000 | |||
1001 | addr = snd_pcm_sgbuf_get_addr(sgbuf, ofs); | ||
1002 | /* program the address field of the BDL entry */ | ||
1003 | bdl[0] = cpu_to_le32((u32)addr); | ||
1004 | bdl[1] = cpu_to_le32(upper_32_bits(addr)); | ||
1005 | /* program the size field of the BDL entry */ | ||
1006 | chunk = PAGE_SIZE - (ofs % PAGE_SIZE); | ||
1007 | if (size < chunk) | ||
1008 | chunk = size; | ||
1009 | bdl[2] = cpu_to_le32(chunk); | ||
1010 | /* program the IOC to enable interrupt | ||
1011 | * only when the whole fragment is processed | ||
1012 | */ | ||
1013 | size -= chunk; | ||
1014 | bdl[3] = (size || !with_ioc) ? 0 : cpu_to_le32(0x01); | ||
1015 | bdl += 4; | ||
1016 | azx_dev->frags++; | ||
1017 | ofs += chunk; | ||
1018 | } | ||
1019 | *bdlp = bdl; | ||
1020 | return ofs; | ||
1021 | } | ||
1022 | |||
1023 | /* | ||
962 | * set up BDL entries | 1024 | * set up BDL entries |
963 | */ | 1025 | */ |
964 | static int azx_setup_periods(struct snd_pcm_substream *substream, | 1026 | static int azx_setup_periods(struct azx *chip, |
1027 | struct snd_pcm_substream *substream, | ||
965 | struct azx_dev *azx_dev) | 1028 | struct azx_dev *azx_dev) |
966 | { | 1029 | { |
967 | struct snd_sg_buf *sgbuf = snd_pcm_substream_sgbuf(substream); | ||
968 | u32 *bdl; | 1030 | u32 *bdl; |
969 | int i, ofs, periods, period_bytes; | 1031 | int i, ofs, periods, period_bytes; |
1032 | int pos_adj; | ||
970 | 1033 | ||
971 | /* reset BDL address */ | 1034 | /* reset BDL address */ |
972 | azx_sd_writel(azx_dev, SD_BDLPL, 0); | 1035 | azx_sd_writel(azx_dev, SD_BDLPL, 0); |
973 | azx_sd_writel(azx_dev, SD_BDLPU, 0); | 1036 | azx_sd_writel(azx_dev, SD_BDLPU, 0); |
974 | 1037 | ||
975 | period_bytes = snd_pcm_lib_period_bytes(substream); | 1038 | period_bytes = snd_pcm_lib_period_bytes(substream); |
1039 | azx_dev->period_bytes = period_bytes; | ||
976 | periods = azx_dev->bufsize / period_bytes; | 1040 | periods = azx_dev->bufsize / period_bytes; |
977 | 1041 | ||
978 | /* program the initial BDL entries */ | 1042 | /* program the initial BDL entries */ |
979 | bdl = (u32 *)azx_dev->bdl.area; | 1043 | bdl = (u32 *)azx_dev->bdl.area; |
980 | ofs = 0; | 1044 | ofs = 0; |
981 | azx_dev->frags = 0; | 1045 | azx_dev->frags = 0; |
982 | for (i = 0; i < periods; i++) { | 1046 | azx_dev->irq_ignore = 0; |
983 | int size, rest; | 1047 | pos_adj = bdl_pos_adj[chip->dev_index]; |
984 | if (i >= AZX_MAX_BDL_ENTRIES) { | 1048 | if (pos_adj > 0) { |
985 | snd_printk(KERN_ERR "Too many BDL entries: " | 1049 | struct snd_pcm_runtime *runtime = substream->runtime; |
986 | "buffer=%d, period=%d\n", | 1050 | pos_adj = (pos_adj * runtime->rate + 47999) / 48000; |
987 | azx_dev->bufsize, period_bytes); | 1051 | if (!pos_adj) |
988 | /* reset */ | 1052 | pos_adj = 1; |
989 | azx_sd_writel(azx_dev, SD_BDLPL, 0); | 1053 | pos_adj = frames_to_bytes(runtime, pos_adj); |
990 | azx_sd_writel(azx_dev, SD_BDLPU, 0); | 1054 | if (pos_adj >= period_bytes) { |
991 | return -EINVAL; | 1055 | snd_printk(KERN_WARNING "Too big adjustment %d\n", |
1056 | bdl_pos_adj[chip->dev_index]); | ||
1057 | pos_adj = 0; | ||
1058 | } else { | ||
1059 | ofs = setup_bdle(substream, azx_dev, | ||
1060 | &bdl, ofs, pos_adj, 1); | ||
1061 | if (ofs < 0) | ||
1062 | goto error; | ||
1063 | azx_dev->irq_ignore = 1; | ||
992 | } | 1064 | } |
993 | rest = period_bytes; | 1065 | } else |
994 | do { | 1066 | pos_adj = 0; |
995 | dma_addr_t addr = snd_pcm_sgbuf_get_addr(sgbuf, ofs); | 1067 | for (i = 0; i < periods; i++) { |
996 | /* program the address field of the BDL entry */ | 1068 | if (i == periods - 1 && pos_adj) |
997 | bdl[0] = cpu_to_le32((u32)addr); | 1069 | ofs = setup_bdle(substream, azx_dev, &bdl, ofs, |
998 | bdl[1] = cpu_to_le32(upper_32bit(addr)); | 1070 | period_bytes - pos_adj, 0); |
999 | /* program the size field of the BDL entry */ | 1071 | else |
1000 | size = PAGE_SIZE - (ofs % PAGE_SIZE); | 1072 | ofs = setup_bdle(substream, azx_dev, &bdl, ofs, |
1001 | if (rest < size) | 1073 | period_bytes, 1); |
1002 | size = rest; | 1074 | if (ofs < 0) |
1003 | bdl[2] = cpu_to_le32(size); | 1075 | goto error; |
1004 | /* program the IOC to enable interrupt | ||
1005 | * only when the whole fragment is processed | ||
1006 | */ | ||
1007 | rest -= size; | ||
1008 | bdl[3] = rest ? 0 : cpu_to_le32(0x01); | ||
1009 | bdl += 4; | ||
1010 | azx_dev->frags++; | ||
1011 | ofs += size; | ||
1012 | } while (rest > 0); | ||
1013 | } | 1076 | } |
1014 | return 0; | 1077 | return 0; |
1078 | |||
1079 | error: | ||
1080 | snd_printk(KERN_ERR "Too many BDL entries: buffer=%d, period=%d\n", | ||
1081 | azx_dev->bufsize, period_bytes); | ||
1082 | /* reset */ | ||
1083 | azx_sd_writel(azx_dev, SD_BDLPL, 0); | ||
1084 | azx_sd_writel(azx_dev, SD_BDLPU, 0); | ||
1085 | return -EINVAL; | ||
1015 | } | 1086 | } |
1016 | 1087 | ||
1017 | /* | 1088 | /* |
@@ -1062,7 +1133,7 @@ static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev) | |||
1062 | /* lower BDL address */ | 1133 | /* lower BDL address */ |
1063 | azx_sd_writel(azx_dev, SD_BDLPL, (u32)azx_dev->bdl.addr); | 1134 | azx_sd_writel(azx_dev, SD_BDLPL, (u32)azx_dev->bdl.addr); |
1064 | /* upper BDL address */ | 1135 | /* upper BDL address */ |
1065 | azx_sd_writel(azx_dev, SD_BDLPU, upper_32bit(azx_dev->bdl.addr)); | 1136 | azx_sd_writel(azx_dev, SD_BDLPU, upper_32_bits(azx_dev->bdl.addr)); |
1066 | 1137 | ||
1067 | /* enable the position buffer */ | 1138 | /* enable the position buffer */ |
1068 | if (chip->position_fix == POS_FIX_POSBUF || | 1139 | if (chip->position_fix == POS_FIX_POSBUF || |
@@ -1085,7 +1156,7 @@ static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev) | |||
1085 | */ | 1156 | */ |
1086 | 1157 | ||
1087 | static unsigned int azx_max_codecs[] __devinitdata = { | 1158 | static unsigned int azx_max_codecs[] __devinitdata = { |
1088 | [AZX_DRIVER_ICH] = 3, | 1159 | [AZX_DRIVER_ICH] = 4, /* Some ICH9 boards use SD3 */ |
1089 | [AZX_DRIVER_SCH] = 3, | 1160 | [AZX_DRIVER_SCH] = 3, |
1090 | [AZX_DRIVER_ATI] = 4, | 1161 | [AZX_DRIVER_ATI] = 4, |
1091 | [AZX_DRIVER_ATIHDMI] = 4, | 1162 | [AZX_DRIVER_ATIHDMI] = 4, |
@@ -1093,6 +1164,7 @@ static unsigned int azx_max_codecs[] __devinitdata = { | |||
1093 | [AZX_DRIVER_SIS] = 3, /* FIXME: correct? */ | 1164 | [AZX_DRIVER_SIS] = 3, /* FIXME: correct? */ |
1094 | [AZX_DRIVER_ULI] = 3, /* FIXME: correct? */ | 1165 | [AZX_DRIVER_ULI] = 3, /* FIXME: correct? */ |
1095 | [AZX_DRIVER_NVIDIA] = 3, /* FIXME: correct? */ | 1166 | [AZX_DRIVER_NVIDIA] = 3, /* FIXME: correct? */ |
1167 | [AZX_DRIVER_TERA] = 1, | ||
1096 | }; | 1168 | }; |
1097 | 1169 | ||
1098 | static int __devinit azx_codec_create(struct azx *chip, const char *model, | 1170 | static int __devinit azx_codec_create(struct azx *chip, const char *model, |
@@ -1316,7 +1388,7 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream) | |||
1316 | 1388 | ||
1317 | snd_printdd("azx_pcm_prepare: bufsize=0x%x, format=0x%x\n", | 1389 | snd_printdd("azx_pcm_prepare: bufsize=0x%x, format=0x%x\n", |
1318 | azx_dev->bufsize, azx_dev->format_val); | 1390 | azx_dev->bufsize, azx_dev->format_val); |
1319 | if (azx_setup_periods(substream, azx_dev) < 0) | 1391 | if (azx_setup_periods(chip, substream, azx_dev) < 0) |
1320 | return -EINVAL; | 1392 | return -EINVAL; |
1321 | azx_setup_controller(chip, azx_dev); | 1393 | azx_setup_controller(chip, azx_dev); |
1322 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 1394 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
@@ -1421,35 +1493,113 @@ static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) | |||
1421 | return 0; | 1493 | return 0; |
1422 | } | 1494 | } |
1423 | 1495 | ||
1424 | static snd_pcm_uframes_t azx_pcm_pointer(struct snd_pcm_substream *substream) | 1496 | static unsigned int azx_get_position(struct azx *chip, |
1497 | struct azx_dev *azx_dev) | ||
1425 | { | 1498 | { |
1426 | struct azx_pcm *apcm = snd_pcm_substream_chip(substream); | ||
1427 | struct azx *chip = apcm->chip; | ||
1428 | struct azx_dev *azx_dev = get_azx_dev(substream); | ||
1429 | unsigned int pos; | 1499 | unsigned int pos; |
1430 | 1500 | ||
1431 | if (chip->position_fix == POS_FIX_POSBUF || | 1501 | if (chip->position_fix == POS_FIX_POSBUF || |
1432 | chip->position_fix == POS_FIX_AUTO) { | 1502 | chip->position_fix == POS_FIX_AUTO) { |
1433 | /* use the position buffer */ | 1503 | /* use the position buffer */ |
1434 | pos = le32_to_cpu(*azx_dev->posbuf); | 1504 | pos = le32_to_cpu(*azx_dev->posbuf); |
1435 | if (chip->position_fix == POS_FIX_AUTO && | ||
1436 | azx_dev->period_intr == 1 && !pos) { | ||
1437 | printk(KERN_WARNING | ||
1438 | "hda-intel: Invalid position buffer, " | ||
1439 | "using LPIB read method instead.\n"); | ||
1440 | chip->position_fix = POS_FIX_NONE; | ||
1441 | goto read_lpib; | ||
1442 | } | ||
1443 | } else { | 1505 | } else { |
1444 | read_lpib: | ||
1445 | /* read LPIB */ | 1506 | /* read LPIB */ |
1446 | pos = azx_sd_readl(azx_dev, SD_LPIB); | 1507 | pos = azx_sd_readl(azx_dev, SD_LPIB); |
1447 | if (chip->position_fix == POS_FIX_FIFO) | ||
1448 | pos += azx_dev->fifo_size; | ||
1449 | } | 1508 | } |
1450 | if (pos >= azx_dev->bufsize) | 1509 | if (pos >= azx_dev->bufsize) |
1451 | pos = 0; | 1510 | pos = 0; |
1452 | return bytes_to_frames(substream->runtime, pos); | 1511 | return pos; |
1512 | } | ||
1513 | |||
1514 | static snd_pcm_uframes_t azx_pcm_pointer(struct snd_pcm_substream *substream) | ||
1515 | { | ||
1516 | struct azx_pcm *apcm = snd_pcm_substream_chip(substream); | ||
1517 | struct azx *chip = apcm->chip; | ||
1518 | struct azx_dev *azx_dev = get_azx_dev(substream); | ||
1519 | return bytes_to_frames(substream->runtime, | ||
1520 | azx_get_position(chip, azx_dev)); | ||
1521 | } | ||
1522 | |||
1523 | /* | ||
1524 | * Check whether the current DMA position is acceptable for updating | ||
1525 | * periods. Returns non-zero if it's OK. | ||
1526 | * | ||
1527 | * Many HD-audio controllers appear pretty inaccurate about | ||
1528 | * the update-IRQ timing. The IRQ is issued before actually the | ||
1529 | * data is processed. So, we need to process it afterwords in a | ||
1530 | * workqueue. | ||
1531 | */ | ||
1532 | static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev) | ||
1533 | { | ||
1534 | unsigned int pos; | ||
1535 | |||
1536 | pos = azx_get_position(chip, azx_dev); | ||
1537 | if (chip->position_fix == POS_FIX_AUTO) { | ||
1538 | if (!pos) { | ||
1539 | printk(KERN_WARNING | ||
1540 | "hda-intel: Invalid position buffer, " | ||
1541 | "using LPIB read method instead.\n"); | ||
1542 | chip->position_fix = POS_FIX_LPIB; | ||
1543 | pos = azx_get_position(chip, azx_dev); | ||
1544 | } else | ||
1545 | chip->position_fix = POS_FIX_POSBUF; | ||
1546 | } | ||
1547 | |||
1548 | if (pos % azx_dev->period_bytes > azx_dev->period_bytes / 2) | ||
1549 | return 0; /* NG - it's below the period boundary */ | ||
1550 | return 1; /* OK, it's fine */ | ||
1551 | } | ||
1552 | |||
1553 | /* | ||
1554 | * The work for pending PCM period updates. | ||
1555 | */ | ||
1556 | static void azx_irq_pending_work(struct work_struct *work) | ||
1557 | { | ||
1558 | struct azx *chip = container_of(work, struct azx, irq_pending_work); | ||
1559 | int i, pending; | ||
1560 | |||
1561 | if (!chip->irq_pending_warned) { | ||
1562 | printk(KERN_WARNING | ||
1563 | "hda-intel: IRQ timing workaround is activated " | ||
1564 | "for card #%d. Suggest a bigger bdl_pos_adj.\n", | ||
1565 | chip->card->number); | ||
1566 | chip->irq_pending_warned = 1; | ||
1567 | } | ||
1568 | |||
1569 | for (;;) { | ||
1570 | pending = 0; | ||
1571 | spin_lock_irq(&chip->reg_lock); | ||
1572 | for (i = 0; i < chip->num_streams; i++) { | ||
1573 | struct azx_dev *azx_dev = &chip->azx_dev[i]; | ||
1574 | if (!azx_dev->irq_pending || | ||
1575 | !azx_dev->substream || | ||
1576 | !azx_dev->running) | ||
1577 | continue; | ||
1578 | if (azx_position_ok(chip, azx_dev)) { | ||
1579 | azx_dev->irq_pending = 0; | ||
1580 | spin_unlock(&chip->reg_lock); | ||
1581 | snd_pcm_period_elapsed(azx_dev->substream); | ||
1582 | spin_lock(&chip->reg_lock); | ||
1583 | } else | ||
1584 | pending++; | ||
1585 | } | ||
1586 | spin_unlock_irq(&chip->reg_lock); | ||
1587 | if (!pending) | ||
1588 | return; | ||
1589 | cond_resched(); | ||
1590 | } | ||
1591 | } | ||
1592 | |||
1593 | /* clear irq_pending flags and assure no on-going workq */ | ||
1594 | static void azx_clear_irq_pending(struct azx *chip) | ||
1595 | { | ||
1596 | int i; | ||
1597 | |||
1598 | spin_lock_irq(&chip->reg_lock); | ||
1599 | for (i = 0; i < chip->num_streams; i++) | ||
1600 | chip->azx_dev[i].irq_pending = 0; | ||
1601 | spin_unlock_irq(&chip->reg_lock); | ||
1602 | flush_scheduled_work(); | ||
1453 | } | 1603 | } |
1454 | 1604 | ||
1455 | static struct snd_pcm_ops azx_pcm_ops = { | 1605 | static struct snd_pcm_ops azx_pcm_ops = { |
@@ -1676,6 +1826,7 @@ static int azx_suspend(struct pci_dev *pci, pm_message_t state) | |||
1676 | int i; | 1826 | int i; |
1677 | 1827 | ||
1678 | snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); | 1828 | snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); |
1829 | azx_clear_irq_pending(chip); | ||
1679 | for (i = 0; i < AZX_MAX_PCMS; i++) | 1830 | for (i = 0; i < AZX_MAX_PCMS; i++) |
1680 | snd_pcm_suspend_all(chip->pcm[i]); | 1831 | snd_pcm_suspend_all(chip->pcm[i]); |
1681 | if (chip->initialized) | 1832 | if (chip->initialized) |
@@ -1732,6 +1883,7 @@ static int azx_free(struct azx *chip) | |||
1732 | int i; | 1883 | int i; |
1733 | 1884 | ||
1734 | if (chip->initialized) { | 1885 | if (chip->initialized) { |
1886 | azx_clear_irq_pending(chip); | ||
1735 | for (i = 0; i < chip->num_streams; i++) | 1887 | for (i = 0; i < chip->num_streams; i++) |
1736 | azx_stream_stop(chip, &chip->azx_dev[i]); | 1888 | azx_stream_stop(chip, &chip->azx_dev[i]); |
1737 | azx_stop_chip(chip); | 1889 | azx_stop_chip(chip); |
@@ -1770,9 +1922,9 @@ static int azx_dev_free(struct snd_device *device) | |||
1770 | * white/black-listing for position_fix | 1922 | * white/black-listing for position_fix |
1771 | */ | 1923 | */ |
1772 | static struct snd_pci_quirk position_fix_list[] __devinitdata = { | 1924 | static struct snd_pci_quirk position_fix_list[] __devinitdata = { |
1773 | SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_NONE), | 1925 | SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB), |
1774 | SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_NONE), | 1926 | SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB), |
1775 | SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_NONE), | 1927 | SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB), |
1776 | {} | 1928 | {} |
1777 | }; | 1929 | }; |
1778 | 1930 | ||
@@ -1857,12 +2009,25 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, | |||
1857 | chip->irq = -1; | 2009 | chip->irq = -1; |
1858 | chip->driver_type = driver_type; | 2010 | chip->driver_type = driver_type; |
1859 | chip->msi = enable_msi; | 2011 | chip->msi = enable_msi; |
2012 | chip->dev_index = dev; | ||
2013 | INIT_WORK(&chip->irq_pending_work, azx_irq_pending_work); | ||
1860 | 2014 | ||
1861 | chip->position_fix = check_position_fix(chip, position_fix[dev]); | 2015 | chip->position_fix = check_position_fix(chip, position_fix[dev]); |
1862 | check_probe_mask(chip, dev); | 2016 | check_probe_mask(chip, dev); |
1863 | 2017 | ||
1864 | chip->single_cmd = single_cmd; | 2018 | chip->single_cmd = single_cmd; |
1865 | 2019 | ||
2020 | if (bdl_pos_adj[dev] < 0) { | ||
2021 | switch (chip->driver_type) { | ||
2022 | case AZX_DRIVER_ICH: | ||
2023 | bdl_pos_adj[dev] = 1; | ||
2024 | break; | ||
2025 | default: | ||
2026 | bdl_pos_adj[dev] = 32; | ||
2027 | break; | ||
2028 | } | ||
2029 | } | ||
2030 | |||
1866 | #if BITS_PER_LONG != 64 | 2031 | #if BITS_PER_LONG != 64 |
1867 | /* Fix up base address on ULI M5461 */ | 2032 | /* Fix up base address on ULI M5461 */ |
1868 | if (chip->driver_type == AZX_DRIVER_ULI) { | 2033 | if (chip->driver_type == AZX_DRIVER_ULI) { |
@@ -2089,6 +2254,7 @@ static struct pci_device_id azx_ids[] = { | |||
2089 | { PCI_DEVICE(0x8086, 0x27d8), .driver_data = AZX_DRIVER_ICH }, | 2254 | { PCI_DEVICE(0x8086, 0x27d8), .driver_data = AZX_DRIVER_ICH }, |
2090 | { PCI_DEVICE(0x8086, 0x269a), .driver_data = AZX_DRIVER_ICH }, | 2255 | { PCI_DEVICE(0x8086, 0x269a), .driver_data = AZX_DRIVER_ICH }, |
2091 | { PCI_DEVICE(0x8086, 0x284b), .driver_data = AZX_DRIVER_ICH }, | 2256 | { PCI_DEVICE(0x8086, 0x284b), .driver_data = AZX_DRIVER_ICH }, |
2257 | { PCI_DEVICE(0x8086, 0x2911), .driver_data = AZX_DRIVER_ICH }, | ||
2092 | { PCI_DEVICE(0x8086, 0x293e), .driver_data = AZX_DRIVER_ICH }, | 2258 | { PCI_DEVICE(0x8086, 0x293e), .driver_data = AZX_DRIVER_ICH }, |
2093 | { PCI_DEVICE(0x8086, 0x293f), .driver_data = AZX_DRIVER_ICH }, | 2259 | { PCI_DEVICE(0x8086, 0x293f), .driver_data = AZX_DRIVER_ICH }, |
2094 | { PCI_DEVICE(0x8086, 0x3a3e), .driver_data = AZX_DRIVER_ICH }, | 2260 | { PCI_DEVICE(0x8086, 0x3a3e), .driver_data = AZX_DRIVER_ICH }, |
@@ -2141,6 +2307,8 @@ static struct pci_device_id azx_ids[] = { | |||
2141 | { PCI_DEVICE(0x10de, 0x0bd5), .driver_data = AZX_DRIVER_NVIDIA }, | 2307 | { PCI_DEVICE(0x10de, 0x0bd5), .driver_data = AZX_DRIVER_NVIDIA }, |
2142 | { PCI_DEVICE(0x10de, 0x0bd6), .driver_data = AZX_DRIVER_NVIDIA }, | 2308 | { PCI_DEVICE(0x10de, 0x0bd6), .driver_data = AZX_DRIVER_NVIDIA }, |
2143 | { PCI_DEVICE(0x10de, 0x0bd7), .driver_data = AZX_DRIVER_NVIDIA }, | 2309 | { PCI_DEVICE(0x10de, 0x0bd7), .driver_data = AZX_DRIVER_NVIDIA }, |
2310 | /* Teradici */ | ||
2311 | { PCI_DEVICE(0x6549, 0x1200), .driver_data = AZX_DRIVER_TERA }, | ||
2144 | { 0, } | 2312 | { 0, } |
2145 | }; | 2313 | }; |
2146 | MODULE_DEVICE_TABLE(pci, azx_ids); | 2314 | MODULE_DEVICE_TABLE(pci, azx_ids); |
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c index 5633f77f8f3b..1e5aff5c48d1 100644 --- a/sound/pci/hda/hda_proc.c +++ b/sound/pci/hda/hda_proc.c | |||
@@ -366,8 +366,6 @@ static void print_digital_conv(struct snd_info_buffer *buffer, | |||
366 | { | 366 | { |
367 | unsigned int digi1 = snd_hda_codec_read(codec, nid, 0, | 367 | unsigned int digi1 = snd_hda_codec_read(codec, nid, 0, |
368 | AC_VERB_GET_DIGI_CONVERT_1, 0); | 368 | AC_VERB_GET_DIGI_CONVERT_1, 0); |
369 | unsigned int digi2 = snd_hda_codec_read(codec, nid, 0, | ||
370 | AC_VERB_GET_DIGI_CONVERT_2, 0); | ||
371 | snd_iprintf(buffer, " Digital:"); | 369 | snd_iprintf(buffer, " Digital:"); |
372 | if (digi1 & AC_DIG1_ENABLE) | 370 | if (digi1 & AC_DIG1_ENABLE) |
373 | snd_iprintf(buffer, " Enabled"); | 371 | snd_iprintf(buffer, " Enabled"); |
@@ -386,7 +384,8 @@ static void print_digital_conv(struct snd_info_buffer *buffer, | |||
386 | if (digi1 & AC_DIG1_LEVEL) | 384 | if (digi1 & AC_DIG1_LEVEL) |
387 | snd_iprintf(buffer, " GenLevel"); | 385 | snd_iprintf(buffer, " GenLevel"); |
388 | snd_iprintf(buffer, "\n"); | 386 | snd_iprintf(buffer, "\n"); |
389 | snd_iprintf(buffer, " Digital category: 0x%x\n", digi2 & AC_DIG2_CC); | 387 | snd_iprintf(buffer, " Digital category: 0x%x\n", |
388 | (digi1 >> 8) & AC_DIG2_CC); | ||
390 | } | 389 | } |
391 | 390 | ||
392 | static const char *get_pwr_state(u32 state) | 391 | static const char *get_pwr_state(u32 state) |
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index a99e86d74278..e8003d99f0bf 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #include <linux/delay.h> | 23 | #include <linux/delay.h> |
24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
25 | #include <linux/pci.h> | 25 | #include <linux/pci.h> |
26 | #include <linux/mutex.h> | ||
27 | 26 | ||
28 | #include <sound/core.h> | 27 | #include <sound/core.h> |
29 | #include "hda_codec.h" | 28 | #include "hda_codec.h" |
@@ -64,7 +63,6 @@ struct ad198x_spec { | |||
64 | /* PCM information */ | 63 | /* PCM information */ |
65 | struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */ | 64 | struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */ |
66 | 65 | ||
67 | struct mutex amp_mutex; /* PCM volume/mute control mutex */ | ||
68 | unsigned int spdif_route; | 66 | unsigned int spdif_route; |
69 | 67 | ||
70 | /* dynamic controls, init_verbs and input_mux */ | 68 | /* dynamic controls, init_verbs and input_mux */ |
@@ -1618,6 +1616,7 @@ static const char *ad1981_models[AD1981_MODELS] = { | |||
1618 | 1616 | ||
1619 | static struct snd_pci_quirk ad1981_cfg_tbl[] = { | 1617 | static struct snd_pci_quirk ad1981_cfg_tbl[] = { |
1620 | SND_PCI_QUIRK(0x1014, 0x0597, "Lenovo Z60", AD1981_THINKPAD), | 1618 | SND_PCI_QUIRK(0x1014, 0x0597, "Lenovo Z60", AD1981_THINKPAD), |
1619 | SND_PCI_QUIRK(0x1014, 0x05b7, "Lenovo Z60m", AD1981_THINKPAD), | ||
1621 | /* All HP models */ | 1620 | /* All HP models */ |
1622 | SND_PCI_QUIRK(0x103c, 0, "HP nx", AD1981_HP), | 1621 | SND_PCI_QUIRK(0x103c, 0, "HP nx", AD1981_HP), |
1623 | SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba U205", AD1981_TOSHIBA), | 1622 | SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba U205", AD1981_TOSHIBA), |
@@ -2623,7 +2622,7 @@ static int ad1988_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin, | |||
2623 | { | 2622 | { |
2624 | struct ad198x_spec *spec = codec->spec; | 2623 | struct ad198x_spec *spec = codec->spec; |
2625 | hda_nid_t nid; | 2624 | hda_nid_t nid; |
2626 | int idx, err; | 2625 | int i, idx, err; |
2627 | char name[32]; | 2626 | char name[32]; |
2628 | 2627 | ||
2629 | if (! pin) | 2628 | if (! pin) |
@@ -2631,16 +2630,26 @@ static int ad1988_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin, | |||
2631 | 2630 | ||
2632 | idx = ad1988_pin_idx(pin); | 2631 | idx = ad1988_pin_idx(pin); |
2633 | nid = ad1988_idx_to_dac(codec, idx); | 2632 | nid = ad1988_idx_to_dac(codec, idx); |
2634 | /* specify the DAC as the extra output */ | 2633 | /* check whether the corresponding DAC was already taken */ |
2635 | if (! spec->multiout.hp_nid) | 2634 | for (i = 0; i < spec->autocfg.line_outs; i++) { |
2636 | spec->multiout.hp_nid = nid; | 2635 | hda_nid_t pin = spec->autocfg.line_out_pins[i]; |
2637 | else | 2636 | hda_nid_t dac = ad1988_idx_to_dac(codec, ad1988_pin_idx(pin)); |
2638 | spec->multiout.extra_out_nid[0] = nid; | 2637 | if (dac == nid) |
2639 | /* control HP volume/switch on the output mixer amp */ | 2638 | break; |
2640 | sprintf(name, "%s Playback Volume", pfx); | 2639 | } |
2641 | if ((err = add_control(spec, AD_CTL_WIDGET_VOL, name, | 2640 | if (i >= spec->autocfg.line_outs) { |
2642 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) | 2641 | /* specify the DAC as the extra output */ |
2643 | return err; | 2642 | if (!spec->multiout.hp_nid) |
2643 | spec->multiout.hp_nid = nid; | ||
2644 | else | ||
2645 | spec->multiout.extra_out_nid[0] = nid; | ||
2646 | /* control HP volume/switch on the output mixer amp */ | ||
2647 | sprintf(name, "%s Playback Volume", pfx); | ||
2648 | err = add_control(spec, AD_CTL_WIDGET_VOL, name, | ||
2649 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); | ||
2650 | if (err < 0) | ||
2651 | return err; | ||
2652 | } | ||
2644 | nid = ad1988_mixer_nids[idx]; | 2653 | nid = ad1988_mixer_nids[idx]; |
2645 | sprintf(name, "%s Playback Switch", pfx); | 2654 | sprintf(name, "%s Playback Switch", pfx); |
2646 | if ((err = add_control(spec, AD_CTL_BIND_MUTE, name, | 2655 | if ((err = add_control(spec, AD_CTL_BIND_MUTE, name, |
@@ -3177,7 +3186,6 @@ static int patch_ad1884(struct hda_codec *codec) | |||
3177 | if (spec == NULL) | 3186 | if (spec == NULL) |
3178 | return -ENOMEM; | 3187 | return -ENOMEM; |
3179 | 3188 | ||
3180 | mutex_init(&spec->amp_mutex); | ||
3181 | codec->spec = spec; | 3189 | codec->spec = spec; |
3182 | 3190 | ||
3183 | spec->multiout.max_channels = 2; | 3191 | spec->multiout.max_channels = 2; |
@@ -3847,7 +3855,6 @@ static int patch_ad1884a(struct hda_codec *codec) | |||
3847 | if (spec == NULL) | 3855 | if (spec == NULL) |
3848 | return -ENOMEM; | 3856 | return -ENOMEM; |
3849 | 3857 | ||
3850 | mutex_init(&spec->amp_mutex); | ||
3851 | codec->spec = spec; | 3858 | codec->spec = spec; |
3852 | 3859 | ||
3853 | spec->multiout.max_channels = 2; | 3860 | spec->multiout.max_channels = 2; |
@@ -4152,7 +4159,6 @@ static int patch_ad1882(struct hda_codec *codec) | |||
4152 | if (spec == NULL) | 4159 | if (spec == NULL) |
4153 | return -ENOMEM; | 4160 | return -ENOMEM; |
4154 | 4161 | ||
4155 | mutex_init(&spec->amp_mutex); | ||
4156 | codec->spec = spec; | 4162 | codec->spec = spec; |
4157 | 4163 | ||
4158 | spec->multiout.max_channels = 6; | 4164 | spec->multiout.max_channels = 6; |
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 36fd85260035..7c1eb23f0cec 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c | |||
@@ -82,7 +82,6 @@ struct conexant_spec { | |||
82 | /* PCM information */ | 82 | /* PCM information */ |
83 | struct hda_pcm pcm_rec[2]; /* used in build_pcms() */ | 83 | struct hda_pcm pcm_rec[2]; /* used in build_pcms() */ |
84 | 84 | ||
85 | struct mutex amp_mutex; /* PCM volume/mute control mutex */ | ||
86 | unsigned int spdif_route; | 85 | unsigned int spdif_route; |
87 | 86 | ||
88 | /* dynamic controls, init_verbs and input_mux */ | 87 | /* dynamic controls, init_verbs and input_mux */ |
@@ -687,7 +686,7 @@ static struct snd_kcontrol_new cxt5045_mixers_hp530[] = { | |||
687 | 686 | ||
688 | static struct hda_verb cxt5045_init_verbs[] = { | 687 | static struct hda_verb cxt5045_init_verbs[] = { |
689 | /* Line in, Mic */ | 688 | /* Line in, Mic */ |
690 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, | 689 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 }, |
691 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 }, | 690 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 }, |
692 | /* HP, Amp */ | 691 | /* HP, Amp */ |
693 | {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | 692 | {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, |
@@ -907,10 +906,12 @@ static struct snd_pci_quirk cxt5045_cfg_tbl[] = { | |||
907 | SND_PCI_QUIRK(0x103c, 0x30cf, "HP DV9533EG", CXT5045_LAPTOP_HPSENSE), | 906 | SND_PCI_QUIRK(0x103c, 0x30cf, "HP DV9533EG", CXT5045_LAPTOP_HPSENSE), |
908 | SND_PCI_QUIRK(0x103c, 0x30d5, "HP 530", CXT5045_LAPTOP_HP530), | 907 | SND_PCI_QUIRK(0x103c, 0x30d5, "HP 530", CXT5045_LAPTOP_HP530), |
909 | SND_PCI_QUIRK(0x103c, 0x30d9, "HP Spartan", CXT5045_LAPTOP_HPSENSE), | 908 | SND_PCI_QUIRK(0x103c, 0x30d9, "HP Spartan", CXT5045_LAPTOP_HPSENSE), |
909 | SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba P105", CXT5045_LAPTOP_MICSENSE), | ||
910 | SND_PCI_QUIRK(0x152d, 0x0753, "Benq R55E", CXT5045_BENQ), | 910 | SND_PCI_QUIRK(0x152d, 0x0753, "Benq R55E", CXT5045_BENQ), |
911 | SND_PCI_QUIRK(0x1734, 0x10ad, "Fujitsu Si1520", CXT5045_LAPTOP_MICSENSE), | 911 | SND_PCI_QUIRK(0x1734, 0x10ad, "Fujitsu Si1520", CXT5045_LAPTOP_MICSENSE), |
912 | SND_PCI_QUIRK(0x1734, 0x10cb, "Fujitsu Si3515", CXT5045_LAPTOP_HPMICSENSE), | 912 | SND_PCI_QUIRK(0x1734, 0x10cb, "Fujitsu Si3515", CXT5045_LAPTOP_HPMICSENSE), |
913 | SND_PCI_QUIRK(0x1734, 0x110e, "Fujitsu V5505", CXT5045_LAPTOP_HPSENSE), | 913 | SND_PCI_QUIRK(0x1734, 0x110e, "Fujitsu V5505", |
914 | CXT5045_LAPTOP_HPMICSENSE), | ||
914 | SND_PCI_QUIRK(0x1509, 0x1e40, "FIC", CXT5045_LAPTOP_HPMICSENSE), | 915 | SND_PCI_QUIRK(0x1509, 0x1e40, "FIC", CXT5045_LAPTOP_HPMICSENSE), |
915 | SND_PCI_QUIRK(0x1509, 0x2f05, "FIC", CXT5045_LAPTOP_HPMICSENSE), | 916 | SND_PCI_QUIRK(0x1509, 0x2f05, "FIC", CXT5045_LAPTOP_HPMICSENSE), |
916 | SND_PCI_QUIRK(0x1509, 0x2f06, "FIC", CXT5045_LAPTOP_HPMICSENSE), | 917 | SND_PCI_QUIRK(0x1509, 0x2f06, "FIC", CXT5045_LAPTOP_HPMICSENSE), |
@@ -928,7 +929,6 @@ static int patch_cxt5045(struct hda_codec *codec) | |||
928 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 929 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); |
929 | if (!spec) | 930 | if (!spec) |
930 | return -ENOMEM; | 931 | return -ENOMEM; |
931 | mutex_init(&spec->amp_mutex); | ||
932 | codec->spec = spec; | 932 | codec->spec = spec; |
933 | 933 | ||
934 | spec->multiout.max_channels = 2; | 934 | spec->multiout.max_channels = 2; |
@@ -963,6 +963,7 @@ static int patch_cxt5045(struct hda_codec *codec) | |||
963 | codec->patch_ops.init = cxt5045_init; | 963 | codec->patch_ops.init = cxt5045_init; |
964 | break; | 964 | break; |
965 | case CXT5045_LAPTOP_MICSENSE: | 965 | case CXT5045_LAPTOP_MICSENSE: |
966 | codec->patch_ops.unsol_event = cxt5045_hp_unsol_event; | ||
966 | spec->input_mux = &cxt5045_capture_source; | 967 | spec->input_mux = &cxt5045_capture_source; |
967 | spec->num_init_verbs = 2; | 968 | spec->num_init_verbs = 2; |
968 | spec->init_verbs[1] = cxt5045_mic_sense_init_verbs; | 969 | spec->init_verbs[1] = cxt5045_mic_sense_init_verbs; |
@@ -1007,15 +1008,19 @@ static int patch_cxt5045(struct hda_codec *codec) | |||
1007 | #endif | 1008 | #endif |
1008 | } | 1009 | } |
1009 | 1010 | ||
1010 | /* | 1011 | switch (codec->subsystem_id >> 16) { |
1011 | * Fix max PCM level to 0 dB | 1012 | case 0x103c: |
1012 | * (originall it has 0x2b steps with 0dB offset 0x14) | 1013 | /* HP laptop has a really bad sound over 0dB on NID 0x17. |
1013 | */ | 1014 | * Fix max PCM level to 0 dB |
1014 | snd_hda_override_amp_caps(codec, 0x17, HDA_INPUT, | 1015 | * (originall it has 0x2b steps with 0dB offset 0x14) |
1015 | (0x14 << AC_AMPCAP_OFFSET_SHIFT) | | 1016 | */ |
1016 | (0x14 << AC_AMPCAP_NUM_STEPS_SHIFT) | | 1017 | snd_hda_override_amp_caps(codec, 0x17, HDA_INPUT, |
1017 | (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) | | 1018 | (0x14 << AC_AMPCAP_OFFSET_SHIFT) | |
1018 | (1 << AC_AMPCAP_MUTE_SHIFT)); | 1019 | (0x14 << AC_AMPCAP_NUM_STEPS_SHIFT) | |
1020 | (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) | | ||
1021 | (1 << AC_AMPCAP_MUTE_SHIFT)); | ||
1022 | break; | ||
1023 | } | ||
1019 | 1024 | ||
1020 | return 0; | 1025 | return 0; |
1021 | } | 1026 | } |
@@ -1477,7 +1482,6 @@ static int patch_cxt5047(struct hda_codec *codec) | |||
1477 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 1482 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); |
1478 | if (!spec) | 1483 | if (!spec) |
1479 | return -ENOMEM; | 1484 | return -ENOMEM; |
1480 | mutex_init(&spec->amp_mutex); | ||
1481 | codec->spec = spec; | 1485 | codec->spec = spec; |
1482 | 1486 | ||
1483 | spec->multiout.max_channels = 2; | 1487 | spec->multiout.max_channels = 2; |
@@ -1736,7 +1740,6 @@ static int patch_cxt5051(struct hda_codec *codec) | |||
1736 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 1740 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); |
1737 | if (!spec) | 1741 | if (!spec) |
1738 | return -ENOMEM; | 1742 | return -ENOMEM; |
1739 | mutex_init(&spec->amp_mutex); | ||
1740 | codec->spec = spec; | 1743 | codec->spec = spec; |
1741 | 1744 | ||
1742 | codec->patch_ops = conexant_patch_ops; | 1745 | codec->patch_ops = conexant_patch_ops; |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index b0a2a262ece2..2807bc840d26 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -163,6 +163,10 @@ enum { | |||
163 | ALC662_LENOVO_101E, | 163 | ALC662_LENOVO_101E, |
164 | ALC662_ASUS_EEEPC_P701, | 164 | ALC662_ASUS_EEEPC_P701, |
165 | ALC662_ASUS_EEEPC_EP20, | 165 | ALC662_ASUS_EEEPC_EP20, |
166 | ALC663_ASUS_M51VA, | ||
167 | ALC663_ASUS_G71V, | ||
168 | ALC663_ASUS_H13, | ||
169 | ALC663_ASUS_G50V, | ||
166 | ALC662_AUTO, | 170 | ALC662_AUTO, |
167 | ALC662_MODEL_LAST, | 171 | ALC662_MODEL_LAST, |
168 | }; | 172 | }; |
@@ -205,6 +209,7 @@ enum { | |||
205 | ALC883_MITAC, | 209 | ALC883_MITAC, |
206 | ALC883_CLEVO_M720, | 210 | ALC883_CLEVO_M720, |
207 | ALC883_FUJITSU_PI2515, | 211 | ALC883_FUJITSU_PI2515, |
212 | ALC883_3ST_6ch_INTEL, | ||
208 | ALC883_AUTO, | 213 | ALC883_AUTO, |
209 | ALC883_MODEL_LAST, | 214 | ALC883_MODEL_LAST, |
210 | }; | 215 | }; |
@@ -280,6 +285,10 @@ struct alc_spec { | |||
280 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 285 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
281 | struct hda_loopback_check loopback; | 286 | struct hda_loopback_check loopback; |
282 | #endif | 287 | #endif |
288 | |||
289 | /* for PLL fix */ | ||
290 | hda_nid_t pll_nid; | ||
291 | unsigned int pll_coef_idx, pll_coef_bit; | ||
283 | }; | 292 | }; |
284 | 293 | ||
285 | /* | 294 | /* |
@@ -747,6 +756,38 @@ static struct hda_verb alc_gpio3_init_verbs[] = { | |||
747 | { } | 756 | { } |
748 | }; | 757 | }; |
749 | 758 | ||
759 | /* | ||
760 | * Fix hardware PLL issue | ||
761 | * On some codecs, the analog PLL gating control must be off while | ||
762 | * the default value is 1. | ||
763 | */ | ||
764 | static void alc_fix_pll(struct hda_codec *codec) | ||
765 | { | ||
766 | struct alc_spec *spec = codec->spec; | ||
767 | unsigned int val; | ||
768 | |||
769 | if (!spec->pll_nid) | ||
770 | return; | ||
771 | snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX, | ||
772 | spec->pll_coef_idx); | ||
773 | val = snd_hda_codec_read(codec, spec->pll_nid, 0, | ||
774 | AC_VERB_GET_PROC_COEF, 0); | ||
775 | snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX, | ||
776 | spec->pll_coef_idx); | ||
777 | snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF, | ||
778 | val & ~(1 << spec->pll_coef_bit)); | ||
779 | } | ||
780 | |||
781 | static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid, | ||
782 | unsigned int coef_idx, unsigned int coef_bit) | ||
783 | { | ||
784 | struct alc_spec *spec = codec->spec; | ||
785 | spec->pll_nid = nid; | ||
786 | spec->pll_coef_idx = coef_idx; | ||
787 | spec->pll_coef_bit = coef_bit; | ||
788 | alc_fix_pll(codec); | ||
789 | } | ||
790 | |||
750 | static void alc_sku_automute(struct hda_codec *codec) | 791 | static void alc_sku_automute(struct hda_codec *codec) |
751 | { | 792 | { |
752 | struct alc_spec *spec = codec->spec; | 793 | struct alc_spec *spec = codec->spec; |
@@ -776,6 +817,24 @@ static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) | |||
776 | alc_sku_automute(codec); | 817 | alc_sku_automute(codec); |
777 | } | 818 | } |
778 | 819 | ||
820 | /* additional initialization for ALC888 variants */ | ||
821 | static void alc888_coef_init(struct hda_codec *codec) | ||
822 | { | ||
823 | unsigned int tmp; | ||
824 | |||
825 | snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0); | ||
826 | tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); | ||
827 | snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7); | ||
828 | if ((tmp & 0xf0) == 2) | ||
829 | /* alc888S-VC */ | ||
830 | snd_hda_codec_read(codec, 0x20, 0, | ||
831 | AC_VERB_SET_PROC_COEF, 0x830); | ||
832 | else | ||
833 | /* alc888-VB */ | ||
834 | snd_hda_codec_read(codec, 0x20, 0, | ||
835 | AC_VERB_SET_PROC_COEF, 0x3030); | ||
836 | } | ||
837 | |||
779 | /* 32-bit subsystem ID for BIOS loading in HD Audio codec. | 838 | /* 32-bit subsystem ID for BIOS loading in HD Audio codec. |
780 | * 31 ~ 16 : Manufacture ID | 839 | * 31 ~ 16 : Manufacture ID |
781 | * 15 ~ 8 : SKU ID | 840 | * 15 ~ 8 : SKU ID |
@@ -851,8 +910,10 @@ do_sku: | |||
851 | case 0x10ec0267: | 910 | case 0x10ec0267: |
852 | case 0x10ec0268: | 911 | case 0x10ec0268: |
853 | case 0x10ec0269: | 912 | case 0x10ec0269: |
913 | case 0x10ec0660: | ||
914 | case 0x10ec0662: | ||
915 | case 0x10ec0663: | ||
854 | case 0x10ec0862: | 916 | case 0x10ec0862: |
855 | case 0x10ec0662: | ||
856 | case 0x10ec0889: | 917 | case 0x10ec0889: |
857 | snd_hda_codec_write(codec, 0x14, 0, | 918 | snd_hda_codec_write(codec, 0x14, 0, |
858 | AC_VERB_SET_EAPD_BTLENABLE, 2); | 919 | AC_VERB_SET_EAPD_BTLENABLE, 2); |
@@ -877,7 +938,6 @@ do_sku: | |||
877 | case 0x10ec0882: | 938 | case 0x10ec0882: |
878 | case 0x10ec0883: | 939 | case 0x10ec0883: |
879 | case 0x10ec0885: | 940 | case 0x10ec0885: |
880 | case 0x10ec0888: | ||
881 | case 0x10ec0889: | 941 | case 0x10ec0889: |
882 | snd_hda_codec_write(codec, 0x20, 0, | 942 | snd_hda_codec_write(codec, 0x20, 0, |
883 | AC_VERB_SET_COEF_INDEX, 7); | 943 | AC_VERB_SET_COEF_INDEX, 7); |
@@ -889,6 +949,9 @@ do_sku: | |||
889 | AC_VERB_SET_PROC_COEF, | 949 | AC_VERB_SET_PROC_COEF, |
890 | tmp | 0x2010); | 950 | tmp | 0x2010); |
891 | break; | 951 | break; |
952 | case 0x10ec0888: | ||
953 | alc888_coef_init(codec); | ||
954 | break; | ||
892 | case 0x10ec0267: | 955 | case 0x10ec0267: |
893 | case 0x10ec0268: | 956 | case 0x10ec0268: |
894 | snd_hda_codec_write(codec, 0x20, 0, | 957 | snd_hda_codec_write(codec, 0x20, 0, |
@@ -2373,6 +2436,8 @@ static int alc_init(struct hda_codec *codec) | |||
2373 | struct alc_spec *spec = codec->spec; | 2436 | struct alc_spec *spec = codec->spec; |
2374 | unsigned int i; | 2437 | unsigned int i; |
2375 | 2438 | ||
2439 | alc_fix_pll(codec); | ||
2440 | |||
2376 | for (i = 0; i < spec->num_init_verbs; i++) | 2441 | for (i = 0; i < spec->num_init_verbs; i++) |
2377 | snd_hda_sequence_write(codec, spec->init_verbs[i]); | 2442 | snd_hda_sequence_write(codec, spec->init_verbs[i]); |
2378 | 2443 | ||
@@ -3009,6 +3074,7 @@ static struct snd_pci_quirk alc880_cfg_tbl[] = { | |||
3009 | SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG), | 3074 | SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG), |
3010 | SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG), | 3075 | SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG), |
3011 | SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734), | 3076 | SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734), |
3077 | SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU), | ||
3012 | SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL), | 3078 | SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL), |
3013 | SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU), | 3079 | SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU), |
3014 | SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW), | 3080 | SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW), |
@@ -5101,7 +5167,7 @@ static struct snd_pci_quirk alc260_cfg_tbl[] = { | |||
5101 | SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013), | 5167 | SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013), |
5102 | SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013), | 5168 | SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013), |
5103 | SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013), | 5169 | SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013), |
5104 | SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP), | 5170 | SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013), |
5105 | SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_3013), | 5171 | SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_3013), |
5106 | SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013), | 5172 | SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013), |
5107 | SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP), | 5173 | SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP), |
@@ -6127,6 +6193,7 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = { | |||
6127 | SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG), | 6193 | SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG), |
6128 | SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG), | 6194 | SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG), |
6129 | SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG), | 6195 | SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG), |
6196 | SND_PCI_QUIRK(0x106b, 0x00a0, "Apple iMac 24''", ALC885_IMAC24), | ||
6130 | SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG), | 6197 | SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG), |
6131 | SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */ | 6198 | SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */ |
6132 | SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG), | 6199 | SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG), |
@@ -6353,7 +6420,9 @@ static void alc882_auto_init_analog_input(struct hda_codec *codec) | |||
6353 | continue; | 6420 | continue; |
6354 | vref = PIN_IN; | 6421 | vref = PIN_IN; |
6355 | if (1 /*i <= AUTO_PIN_FRONT_MIC*/) { | 6422 | if (1 /*i <= AUTO_PIN_FRONT_MIC*/) { |
6356 | if (snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP) & | 6423 | unsigned int pincap; |
6424 | pincap = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP); | ||
6425 | if ((pincap >> AC_PINCAP_VREF_SHIFT) & | ||
6357 | AC_PINCAP_VREF_80) | 6426 | AC_PINCAP_VREF_80) |
6358 | vref = PIN_VREF80; | 6427 | vref = PIN_VREF80; |
6359 | } | 6428 | } |
@@ -6450,8 +6519,9 @@ static int patch_alc882(struct hda_codec *codec) | |||
6450 | case 0x106b1000: /* iMac 24 */ | 6519 | case 0x106b1000: /* iMac 24 */ |
6451 | board_config = ALC885_IMAC24; | 6520 | board_config = ALC885_IMAC24; |
6452 | break; | 6521 | break; |
6453 | case 0x106b00a1: /* Macbook */ | 6522 | case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */ |
6454 | case 0x106b2c00: /* Macbook Pro rev3 */ | 6523 | case 0x106b2c00: /* Macbook Pro rev3 */ |
6524 | case 0x106b3600: /* Macbook 3.1 */ | ||
6455 | board_config = ALC885_MBP3; | 6525 | board_config = ALC885_MBP3; |
6456 | break; | 6526 | break; |
6457 | default: | 6527 | default: |
@@ -6485,14 +6555,20 @@ static int patch_alc882(struct hda_codec *codec) | |||
6485 | if (board_config != ALC882_AUTO) | 6555 | if (board_config != ALC882_AUTO) |
6486 | setup_preset(spec, &alc882_presets[board_config]); | 6556 | setup_preset(spec, &alc882_presets[board_config]); |
6487 | 6557 | ||
6488 | spec->stream_name_analog = "ALC882 Analog"; | 6558 | if (codec->vendor_id == 0x10ec0885) { |
6559 | spec->stream_name_analog = "ALC885 Analog"; | ||
6560 | spec->stream_name_digital = "ALC885 Digital"; | ||
6561 | } else { | ||
6562 | spec->stream_name_analog = "ALC882 Analog"; | ||
6563 | spec->stream_name_digital = "ALC882 Digital"; | ||
6564 | } | ||
6565 | |||
6489 | spec->stream_analog_playback = &alc882_pcm_analog_playback; | 6566 | spec->stream_analog_playback = &alc882_pcm_analog_playback; |
6490 | spec->stream_analog_capture = &alc882_pcm_analog_capture; | 6567 | spec->stream_analog_capture = &alc882_pcm_analog_capture; |
6491 | /* FIXME: setup DAC5 */ | 6568 | /* FIXME: setup DAC5 */ |
6492 | /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/ | 6569 | /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/ |
6493 | spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture; | 6570 | spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture; |
6494 | 6571 | ||
6495 | spec->stream_name_digital = "ALC882 Digital"; | ||
6496 | spec->stream_digital_playback = &alc882_pcm_digital_playback; | 6572 | spec->stream_digital_playback = &alc882_pcm_digital_playback; |
6497 | spec->stream_digital_capture = &alc882_pcm_digital_capture; | 6573 | spec->stream_digital_capture = &alc882_pcm_digital_capture; |
6498 | 6574 | ||
@@ -6569,6 +6645,16 @@ static struct hda_input_mux alc883_capture_source = { | |||
6569 | }, | 6645 | }, |
6570 | }; | 6646 | }; |
6571 | 6647 | ||
6648 | static struct hda_input_mux alc883_3stack_6ch_intel = { | ||
6649 | .num_items = 4, | ||
6650 | .items = { | ||
6651 | { "Mic", 0x1 }, | ||
6652 | { "Front Mic", 0x0 }, | ||
6653 | { "Line", 0x2 }, | ||
6654 | { "CD", 0x4 }, | ||
6655 | }, | ||
6656 | }; | ||
6657 | |||
6572 | static struct hda_input_mux alc883_lenovo_101e_capture_source = { | 6658 | static struct hda_input_mux alc883_lenovo_101e_capture_source = { |
6573 | .num_items = 2, | 6659 | .num_items = 2, |
6574 | .items = { | 6660 | .items = { |
@@ -6650,6 +6736,48 @@ static struct hda_channel_mode alc883_3ST_6ch_modes[3] = { | |||
6650 | }; | 6736 | }; |
6651 | 6737 | ||
6652 | /* | 6738 | /* |
6739 | * 2ch mode | ||
6740 | */ | ||
6741 | static struct hda_verb alc883_3ST_ch2_intel_init[] = { | ||
6742 | { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, | ||
6743 | { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, | ||
6744 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, | ||
6745 | { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, | ||
6746 | { } /* end */ | ||
6747 | }; | ||
6748 | |||
6749 | /* | ||
6750 | * 4ch mode | ||
6751 | */ | ||
6752 | static struct hda_verb alc883_3ST_ch4_intel_init[] = { | ||
6753 | { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, | ||
6754 | { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, | ||
6755 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
6756 | { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | ||
6757 | { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, | ||
6758 | { } /* end */ | ||
6759 | }; | ||
6760 | |||
6761 | /* | ||
6762 | * 6ch mode | ||
6763 | */ | ||
6764 | static struct hda_verb alc883_3ST_ch6_intel_init[] = { | ||
6765 | { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
6766 | { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | ||
6767 | { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 }, | ||
6768 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
6769 | { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | ||
6770 | { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, | ||
6771 | { } /* end */ | ||
6772 | }; | ||
6773 | |||
6774 | static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = { | ||
6775 | { 2, alc883_3ST_ch2_intel_init }, | ||
6776 | { 4, alc883_3ST_ch4_intel_init }, | ||
6777 | { 6, alc883_3ST_ch6_intel_init }, | ||
6778 | }; | ||
6779 | |||
6780 | /* | ||
6653 | * 6ch mode | 6781 | * 6ch mode |
6654 | */ | 6782 | */ |
6655 | static struct hda_verb alc883_sixstack_ch6_init[] = { | 6783 | static struct hda_verb alc883_sixstack_ch6_init[] = { |
@@ -6881,15 +7009,54 @@ static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = { | |||
6881 | { } /* end */ | 7009 | { } /* end */ |
6882 | }; | 7010 | }; |
6883 | 7011 | ||
7012 | static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = { | ||
7013 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
7014 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | ||
7015 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | ||
7016 | HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), | ||
7017 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, | ||
7018 | HDA_OUTPUT), | ||
7019 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), | ||
7020 | HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), | ||
7021 | HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), | ||
7022 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), | ||
7023 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | ||
7024 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | ||
7025 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
7026 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
7027 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | ||
7028 | HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT), | ||
7029 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | ||
7030 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
7031 | HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT), | ||
7032 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
7033 | HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), | ||
7034 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), | ||
7035 | HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), | ||
7036 | HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), | ||
7037 | HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), | ||
7038 | HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), | ||
7039 | { | ||
7040 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
7041 | /* .name = "Capture Source", */ | ||
7042 | .name = "Input Source", | ||
7043 | .count = 2, | ||
7044 | .info = alc883_mux_enum_info, | ||
7045 | .get = alc883_mux_enum_get, | ||
7046 | .put = alc883_mux_enum_put, | ||
7047 | }, | ||
7048 | { } /* end */ | ||
7049 | }; | ||
7050 | |||
6884 | static struct snd_kcontrol_new alc883_fivestack_mixer[] = { | 7051 | static struct snd_kcontrol_new alc883_fivestack_mixer[] = { |
6885 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 7052 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
6886 | HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), | 7053 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), |
6887 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | 7054 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), |
6888 | HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT), | 7055 | HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), |
6889 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), | 7056 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), |
6890 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), | 7057 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), |
6891 | HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT), | 7058 | HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), |
6892 | HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT), | 7059 | HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), |
6893 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | 7060 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), |
6894 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | 7061 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), |
6895 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | 7062 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), |
@@ -7729,6 +7896,7 @@ static const char *alc883_models[ALC883_MODEL_LAST] = { | |||
7729 | [ALC883_MITAC] = "mitac", | 7896 | [ALC883_MITAC] = "mitac", |
7730 | [ALC883_CLEVO_M720] = "clevo-m720", | 7897 | [ALC883_CLEVO_M720] = "clevo-m720", |
7731 | [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515", | 7898 | [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515", |
7899 | [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel", | ||
7732 | [ALC883_AUTO] = "auto", | 7900 | [ALC883_AUTO] = "auto", |
7733 | }; | 7901 | }; |
7734 | 7902 | ||
@@ -7786,6 +7954,8 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { | |||
7786 | SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2), | 7954 | SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2), |
7787 | SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG), | 7955 | SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG), |
7788 | SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66), | 7956 | SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66), |
7957 | SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL), | ||
7958 | SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL), | ||
7789 | SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch), | 7959 | SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch), |
7790 | {} | 7960 | {} |
7791 | }; | 7961 | }; |
@@ -7824,6 +7994,18 @@ static struct alc_config_preset alc883_presets[] = { | |||
7824 | .need_dac_fix = 1, | 7994 | .need_dac_fix = 1, |
7825 | .input_mux = &alc883_capture_source, | 7995 | .input_mux = &alc883_capture_source, |
7826 | }, | 7996 | }, |
7997 | [ALC883_3ST_6ch_INTEL] = { | ||
7998 | .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer }, | ||
7999 | .init_verbs = { alc883_init_verbs }, | ||
8000 | .num_dacs = ARRAY_SIZE(alc883_dac_nids), | ||
8001 | .dac_nids = alc883_dac_nids, | ||
8002 | .dig_out_nid = ALC883_DIGOUT_NID, | ||
8003 | .dig_in_nid = ALC883_DIGIN_NID, | ||
8004 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes), | ||
8005 | .channel_mode = alc883_3ST_6ch_intel_modes, | ||
8006 | .need_dac_fix = 1, | ||
8007 | .input_mux = &alc883_3stack_6ch_intel, | ||
8008 | }, | ||
7827 | [ALC883_6ST_DIG] = { | 8009 | [ALC883_6ST_DIG] = { |
7828 | .mixers = { alc883_base_mixer, alc883_chmode_mixer }, | 8010 | .mixers = { alc883_base_mixer, alc883_chmode_mixer }, |
7829 | .init_verbs = { alc883_init_verbs }, | 8011 | .init_verbs = { alc883_init_verbs }, |
@@ -8145,6 +8327,8 @@ static int patch_alc883(struct hda_codec *codec) | |||
8145 | 8327 | ||
8146 | codec->spec = spec; | 8328 | codec->spec = spec; |
8147 | 8329 | ||
8330 | alc_fix_pll_init(codec, 0x20, 0x0a, 10); | ||
8331 | |||
8148 | board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST, | 8332 | board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST, |
8149 | alc883_models, | 8333 | alc883_models, |
8150 | alc883_cfg_tbl); | 8334 | alc883_cfg_tbl); |
@@ -8171,12 +8355,25 @@ static int patch_alc883(struct hda_codec *codec) | |||
8171 | if (board_config != ALC883_AUTO) | 8355 | if (board_config != ALC883_AUTO) |
8172 | setup_preset(spec, &alc883_presets[board_config]); | 8356 | setup_preset(spec, &alc883_presets[board_config]); |
8173 | 8357 | ||
8174 | spec->stream_name_analog = "ALC883 Analog"; | 8358 | switch (codec->vendor_id) { |
8359 | case 0x10ec0888: | ||
8360 | spec->stream_name_analog = "ALC888 Analog"; | ||
8361 | spec->stream_name_digital = "ALC888 Digital"; | ||
8362 | break; | ||
8363 | case 0x10ec0889: | ||
8364 | spec->stream_name_analog = "ALC889 Analog"; | ||
8365 | spec->stream_name_digital = "ALC889 Digital"; | ||
8366 | break; | ||
8367 | default: | ||
8368 | spec->stream_name_analog = "ALC883 Analog"; | ||
8369 | spec->stream_name_digital = "ALC883 Digital"; | ||
8370 | break; | ||
8371 | } | ||
8372 | |||
8175 | spec->stream_analog_playback = &alc883_pcm_analog_playback; | 8373 | spec->stream_analog_playback = &alc883_pcm_analog_playback; |
8176 | spec->stream_analog_capture = &alc883_pcm_analog_capture; | 8374 | spec->stream_analog_capture = &alc883_pcm_analog_capture; |
8177 | spec->stream_analog_alt_capture = &alc883_pcm_analog_alt_capture; | 8375 | spec->stream_analog_alt_capture = &alc883_pcm_analog_alt_capture; |
8178 | 8376 | ||
8179 | spec->stream_name_digital = "ALC883 Digital"; | ||
8180 | spec->stream_digital_playback = &alc883_pcm_digital_playback; | 8377 | spec->stream_digital_playback = &alc883_pcm_digital_playback; |
8181 | spec->stream_digital_capture = &alc883_pcm_digital_capture; | 8378 | spec->stream_digital_capture = &alc883_pcm_digital_capture; |
8182 | 8379 | ||
@@ -8189,6 +8386,9 @@ static int patch_alc883(struct hda_codec *codec) | |||
8189 | codec->patch_ops = alc_patch_ops; | 8386 | codec->patch_ops = alc_patch_ops; |
8190 | if (board_config == ALC883_AUTO) | 8387 | if (board_config == ALC883_AUTO) |
8191 | spec->init_hook = alc883_auto_init; | 8388 | spec->init_hook = alc883_auto_init; |
8389 | else if (codec->vendor_id == 0x10ec0888) | ||
8390 | spec->init_hook = alc888_coef_init; | ||
8391 | |||
8192 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 8392 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
8193 | if (!spec->loopback.amplist) | 8393 | if (!spec->loopback.amplist) |
8194 | spec->loopback.amplist = alc883_loopbacks; | 8394 | spec->loopback.amplist = alc883_loopbacks; |
@@ -9522,6 +9722,8 @@ static struct snd_pci_quirk alc262_cfg_tbl[] = { | |||
9522 | SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD), | 9722 | SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD), |
9523 | SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD), | 9723 | SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD), |
9524 | SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD), | 9724 | SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD), |
9725 | SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1", | ||
9726 | ALC262_SONY_ASSAMD), | ||
9525 | SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU), | 9727 | SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU), |
9526 | SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU), | 9728 | SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU), |
9527 | SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA), | 9729 | SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA), |
@@ -9729,6 +9931,8 @@ static int patch_alc262(struct hda_codec *codec) | |||
9729 | } | 9931 | } |
9730 | #endif | 9932 | #endif |
9731 | 9933 | ||
9934 | alc_fix_pll_init(codec, 0x20, 0x0a, 10); | ||
9935 | |||
9732 | board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST, | 9936 | board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST, |
9733 | alc262_models, | 9937 | alc262_models, |
9734 | alc262_cfg_tbl); | 9938 | alc262_cfg_tbl); |
@@ -10674,12 +10878,18 @@ static int patch_alc268(struct hda_codec *codec) | |||
10674 | if (board_config != ALC268_AUTO) | 10878 | if (board_config != ALC268_AUTO) |
10675 | setup_preset(spec, &alc268_presets[board_config]); | 10879 | setup_preset(spec, &alc268_presets[board_config]); |
10676 | 10880 | ||
10677 | spec->stream_name_analog = "ALC268 Analog"; | 10881 | if (codec->vendor_id == 0x10ec0267) { |
10882 | spec->stream_name_analog = "ALC267 Analog"; | ||
10883 | spec->stream_name_digital = "ALC267 Digital"; | ||
10884 | } else { | ||
10885 | spec->stream_name_analog = "ALC268 Analog"; | ||
10886 | spec->stream_name_digital = "ALC268 Digital"; | ||
10887 | } | ||
10888 | |||
10678 | spec->stream_analog_playback = &alc268_pcm_analog_playback; | 10889 | spec->stream_analog_playback = &alc268_pcm_analog_playback; |
10679 | spec->stream_analog_capture = &alc268_pcm_analog_capture; | 10890 | spec->stream_analog_capture = &alc268_pcm_analog_capture; |
10680 | spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture; | 10891 | spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture; |
10681 | 10892 | ||
10682 | spec->stream_name_digital = "ALC268 Digital"; | ||
10683 | spec->stream_digital_playback = &alc268_pcm_digital_playback; | 10893 | spec->stream_digital_playback = &alc268_pcm_digital_playback; |
10684 | 10894 | ||
10685 | if (!query_amp_caps(codec, 0x1d, HDA_INPUT)) | 10895 | if (!query_amp_caps(codec, 0x1d, HDA_INPUT)) |
@@ -11033,6 +11243,8 @@ static int patch_alc269(struct hda_codec *codec) | |||
11033 | 11243 | ||
11034 | codec->spec = spec; | 11244 | codec->spec = spec; |
11035 | 11245 | ||
11246 | alc_fix_pll_init(codec, 0x20, 0x04, 15); | ||
11247 | |||
11036 | board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST, | 11248 | board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST, |
11037 | alc269_models, | 11249 | alc269_models, |
11038 | alc269_cfg_tbl); | 11250 | alc269_cfg_tbl); |
@@ -12631,6 +12843,12 @@ static struct hda_verb alc861vd_eapd_verbs[] = { | |||
12631 | { } | 12843 | { } |
12632 | }; | 12844 | }; |
12633 | 12845 | ||
12846 | static struct hda_verb alc660vd_eapd_verbs[] = { | ||
12847 | {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, | ||
12848 | {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, | ||
12849 | { } | ||
12850 | }; | ||
12851 | |||
12634 | static struct hda_verb alc861vd_lenovo_unsol_verbs[] = { | 12852 | static struct hda_verb alc861vd_lenovo_unsol_verbs[] = { |
12635 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 12853 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
12636 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 12854 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, |
@@ -12786,6 +13004,7 @@ static struct snd_pci_quirk alc861vd_cfg_tbl[] = { | |||
12786 | SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG), | 13004 | SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG), |
12787 | SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO), | 13005 | SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO), |
12788 | SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO), | 13006 | SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO), |
13007 | SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 N200", ALC861VD_LENOVO), | ||
12789 | SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG), | 13008 | SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG), |
12790 | {} | 13009 | {} |
12791 | }; | 13010 | }; |
@@ -13168,11 +13387,19 @@ static int patch_alc861vd(struct hda_codec *codec) | |||
13168 | if (board_config != ALC861VD_AUTO) | 13387 | if (board_config != ALC861VD_AUTO) |
13169 | setup_preset(spec, &alc861vd_presets[board_config]); | 13388 | setup_preset(spec, &alc861vd_presets[board_config]); |
13170 | 13389 | ||
13171 | spec->stream_name_analog = "ALC861VD Analog"; | 13390 | if (codec->vendor_id == 0x10ec0660) { |
13391 | spec->stream_name_analog = "ALC660-VD Analog"; | ||
13392 | spec->stream_name_digital = "ALC660-VD Digital"; | ||
13393 | /* always turn on EAPD */ | ||
13394 | spec->init_verbs[spec->num_init_verbs++] = alc660vd_eapd_verbs; | ||
13395 | } else { | ||
13396 | spec->stream_name_analog = "ALC861VD Analog"; | ||
13397 | spec->stream_name_digital = "ALC861VD Digital"; | ||
13398 | } | ||
13399 | |||
13172 | spec->stream_analog_playback = &alc861vd_pcm_analog_playback; | 13400 | spec->stream_analog_playback = &alc861vd_pcm_analog_playback; |
13173 | spec->stream_analog_capture = &alc861vd_pcm_analog_capture; | 13401 | spec->stream_analog_capture = &alc861vd_pcm_analog_capture; |
13174 | 13402 | ||
13175 | spec->stream_name_digital = "ALC861VD Digital"; | ||
13176 | spec->stream_digital_playback = &alc861vd_pcm_digital_playback; | 13403 | spec->stream_digital_playback = &alc861vd_pcm_digital_playback; |
13177 | spec->stream_digital_capture = &alc861vd_pcm_digital_capture; | 13404 | spec->stream_digital_capture = &alc861vd_pcm_digital_capture; |
13178 | 13405 | ||
@@ -13251,6 +13478,23 @@ static struct hda_input_mux alc662_eeepc_capture_source = { | |||
13251 | }, | 13478 | }, |
13252 | }; | 13479 | }; |
13253 | 13480 | ||
13481 | static struct hda_input_mux alc663_capture_source = { | ||
13482 | .num_items = 3, | ||
13483 | .items = { | ||
13484 | { "Mic", 0x0 }, | ||
13485 | { "Front Mic", 0x1 }, | ||
13486 | { "Line", 0x2 }, | ||
13487 | }, | ||
13488 | }; | ||
13489 | |||
13490 | static struct hda_input_mux alc663_m51va_capture_source = { | ||
13491 | .num_items = 2, | ||
13492 | .items = { | ||
13493 | { "Ext-Mic", 0x0 }, | ||
13494 | { "D-Mic", 0x9 }, | ||
13495 | }, | ||
13496 | }; | ||
13497 | |||
13254 | #define alc662_mux_enum_info alc_mux_enum_info | 13498 | #define alc662_mux_enum_info alc_mux_enum_info |
13255 | #define alc662_mux_enum_get alc_mux_enum_get | 13499 | #define alc662_mux_enum_get alc_mux_enum_get |
13256 | #define alc662_mux_enum_put alc882_mux_enum_put | 13500 | #define alc662_mux_enum_put alc882_mux_enum_put |
@@ -13431,6 +13675,44 @@ static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = { | |||
13431 | { } /* end */ | 13675 | { } /* end */ |
13432 | }; | 13676 | }; |
13433 | 13677 | ||
13678 | static struct snd_kcontrol_new alc663_m51va_mixer[] = { | ||
13679 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), | ||
13680 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), | ||
13681 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), | ||
13682 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
13683 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
13684 | HDA_CODEC_MUTE("DMic Playback Switch", 0x23, 0x9, HDA_INPUT), | ||
13685 | { } /* end */ | ||
13686 | }; | ||
13687 | |||
13688 | static struct snd_kcontrol_new alc663_g71v_mixer[] = { | ||
13689 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), | ||
13690 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), | ||
13691 | HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT), | ||
13692 | HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT), | ||
13693 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), | ||
13694 | |||
13695 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
13696 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
13697 | HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | ||
13698 | HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | ||
13699 | { } /* end */ | ||
13700 | }; | ||
13701 | |||
13702 | static struct snd_kcontrol_new alc663_g50v_mixer[] = { | ||
13703 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), | ||
13704 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), | ||
13705 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), | ||
13706 | |||
13707 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
13708 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
13709 | HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | ||
13710 | HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | ||
13711 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
13712 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
13713 | { } /* end */ | ||
13714 | }; | ||
13715 | |||
13434 | static struct snd_kcontrol_new alc662_chmode_mixer[] = { | 13716 | static struct snd_kcontrol_new alc662_chmode_mixer[] = { |
13435 | { | 13717 | { |
13436 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 13718 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
@@ -13501,6 +13783,11 @@ static struct hda_verb alc662_init_verbs[] = { | |||
13501 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 13783 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, |
13502 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | 13784 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, |
13503 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, | 13785 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, |
13786 | |||
13787 | /* always trun on EAPD */ | ||
13788 | {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, | ||
13789 | {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, | ||
13790 | |||
13504 | { } | 13791 | { } |
13505 | }; | 13792 | }; |
13506 | 13793 | ||
@@ -13571,6 +13858,43 @@ static struct hda_verb alc662_auto_init_verbs[] = { | |||
13571 | { } | 13858 | { } |
13572 | }; | 13859 | }; |
13573 | 13860 | ||
13861 | static struct hda_verb alc663_m51va_init_verbs[] = { | ||
13862 | {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
13863 | {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
13864 | {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */ | ||
13865 | |||
13866 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)}, | ||
13867 | |||
13868 | {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, | ||
13869 | {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, | ||
13870 | {} | ||
13871 | }; | ||
13872 | |||
13873 | static struct hda_verb alc663_g71v_init_verbs[] = { | ||
13874 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
13875 | /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */ | ||
13876 | /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */ | ||
13877 | |||
13878 | {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
13879 | {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
13880 | {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */ | ||
13881 | |||
13882 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT}, | ||
13883 | {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT}, | ||
13884 | {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT}, | ||
13885 | {} | ||
13886 | }; | ||
13887 | |||
13888 | static struct hda_verb alc663_g50v_init_verbs[] = { | ||
13889 | {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
13890 | {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
13891 | {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */ | ||
13892 | |||
13893 | {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, | ||
13894 | {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, | ||
13895 | {} | ||
13896 | }; | ||
13897 | |||
13574 | /* capture mixer elements */ | 13898 | /* capture mixer elements */ |
13575 | static struct snd_kcontrol_new alc662_capture_mixer[] = { | 13899 | static struct snd_kcontrol_new alc662_capture_mixer[] = { |
13576 | HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), | 13900 | HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), |
@@ -13692,6 +14016,125 @@ static void alc662_eeepc_ep20_inithook(struct hda_codec *codec) | |||
13692 | alc662_eeepc_ep20_automute(codec); | 14016 | alc662_eeepc_ep20_automute(codec); |
13693 | } | 14017 | } |
13694 | 14018 | ||
14019 | static void alc663_m51va_speaker_automute(struct hda_codec *codec) | ||
14020 | { | ||
14021 | unsigned int present; | ||
14022 | unsigned char bits; | ||
14023 | |||
14024 | present = snd_hda_codec_read(codec, 0x21, 0, | ||
14025 | AC_VERB_GET_PIN_SENSE, 0) | ||
14026 | & AC_PINSENSE_PRESENCE; | ||
14027 | bits = present ? HDA_AMP_MUTE : 0; | ||
14028 | snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, | ||
14029 | HDA_AMP_MUTE, bits); | ||
14030 | } | ||
14031 | |||
14032 | static void alc663_m51va_mic_automute(struct hda_codec *codec) | ||
14033 | { | ||
14034 | unsigned int present; | ||
14035 | |||
14036 | present = snd_hda_codec_read(codec, 0x18, 0, | ||
14037 | AC_VERB_GET_PIN_SENSE, 0) | ||
14038 | & AC_PINSENSE_PRESENCE; | ||
14039 | snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
14040 | 0x7000 | (0x00 << 8) | (present ? 0 : 0x80)); | ||
14041 | snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
14042 | 0x7000 | (0x00 << 8) | (present ? 0 : 0x80)); | ||
14043 | snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
14044 | 0x7000 | (0x09 << 8) | (present ? 0x80 : 0)); | ||
14045 | snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
14046 | 0x7000 | (0x09 << 8) | (present ? 0x80 : 0)); | ||
14047 | } | ||
14048 | |||
14049 | static void alc663_m51va_unsol_event(struct hda_codec *codec, | ||
14050 | unsigned int res) | ||
14051 | { | ||
14052 | switch (res >> 26) { | ||
14053 | case ALC880_HP_EVENT: | ||
14054 | alc663_m51va_speaker_automute(codec); | ||
14055 | break; | ||
14056 | case ALC880_MIC_EVENT: | ||
14057 | alc663_m51va_mic_automute(codec); | ||
14058 | break; | ||
14059 | } | ||
14060 | } | ||
14061 | |||
14062 | static void alc663_m51va_inithook(struct hda_codec *codec) | ||
14063 | { | ||
14064 | alc663_m51va_speaker_automute(codec); | ||
14065 | alc663_m51va_mic_automute(codec); | ||
14066 | } | ||
14067 | |||
14068 | static void alc663_g71v_hp_automute(struct hda_codec *codec) | ||
14069 | { | ||
14070 | unsigned int present; | ||
14071 | unsigned char bits; | ||
14072 | |||
14073 | present = snd_hda_codec_read(codec, 0x21, 0, | ||
14074 | AC_VERB_GET_PIN_SENSE, 0) | ||
14075 | & AC_PINSENSE_PRESENCE; | ||
14076 | bits = present ? HDA_AMP_MUTE : 0; | ||
14077 | snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, | ||
14078 | HDA_AMP_MUTE, bits); | ||
14079 | snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, | ||
14080 | HDA_AMP_MUTE, bits); | ||
14081 | } | ||
14082 | |||
14083 | static void alc663_g71v_front_automute(struct hda_codec *codec) | ||
14084 | { | ||
14085 | unsigned int present; | ||
14086 | unsigned char bits; | ||
14087 | |||
14088 | present = snd_hda_codec_read(codec, 0x15, 0, | ||
14089 | AC_VERB_GET_PIN_SENSE, 0) | ||
14090 | & AC_PINSENSE_PRESENCE; | ||
14091 | bits = present ? HDA_AMP_MUTE : 0; | ||
14092 | snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, | ||
14093 | HDA_AMP_MUTE, bits); | ||
14094 | } | ||
14095 | |||
14096 | static void alc663_g71v_unsol_event(struct hda_codec *codec, | ||
14097 | unsigned int res) | ||
14098 | { | ||
14099 | switch (res >> 26) { | ||
14100 | case ALC880_HP_EVENT: | ||
14101 | alc663_g71v_hp_automute(codec); | ||
14102 | break; | ||
14103 | case ALC880_FRONT_EVENT: | ||
14104 | alc663_g71v_front_automute(codec); | ||
14105 | break; | ||
14106 | case ALC880_MIC_EVENT: | ||
14107 | alc662_eeepc_mic_automute(codec); | ||
14108 | break; | ||
14109 | } | ||
14110 | } | ||
14111 | |||
14112 | static void alc663_g71v_inithook(struct hda_codec *codec) | ||
14113 | { | ||
14114 | alc663_g71v_front_automute(codec); | ||
14115 | alc663_g71v_hp_automute(codec); | ||
14116 | alc662_eeepc_mic_automute(codec); | ||
14117 | } | ||
14118 | |||
14119 | static void alc663_g50v_unsol_event(struct hda_codec *codec, | ||
14120 | unsigned int res) | ||
14121 | { | ||
14122 | switch (res >> 26) { | ||
14123 | case ALC880_HP_EVENT: | ||
14124 | alc663_m51va_speaker_automute(codec); | ||
14125 | break; | ||
14126 | case ALC880_MIC_EVENT: | ||
14127 | alc662_eeepc_mic_automute(codec); | ||
14128 | break; | ||
14129 | } | ||
14130 | } | ||
14131 | |||
14132 | static void alc663_g50v_inithook(struct hda_codec *codec) | ||
14133 | { | ||
14134 | alc663_m51va_speaker_automute(codec); | ||
14135 | alc662_eeepc_mic_automute(codec); | ||
14136 | } | ||
14137 | |||
13695 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 14138 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
13696 | #define alc662_loopbacks alc880_loopbacks | 14139 | #define alc662_loopbacks alc880_loopbacks |
13697 | #endif | 14140 | #endif |
@@ -13714,14 +14157,24 @@ static const char *alc662_models[ALC662_MODEL_LAST] = { | |||
13714 | [ALC662_LENOVO_101E] = "lenovo-101e", | 14157 | [ALC662_LENOVO_101E] = "lenovo-101e", |
13715 | [ALC662_ASUS_EEEPC_P701] = "eeepc-p701", | 14158 | [ALC662_ASUS_EEEPC_P701] = "eeepc-p701", |
13716 | [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20", | 14159 | [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20", |
14160 | [ALC663_ASUS_M51VA] = "m51va", | ||
14161 | [ALC663_ASUS_G71V] = "g71v", | ||
14162 | [ALC663_ASUS_H13] = "h13", | ||
14163 | [ALC663_ASUS_G50V] = "g50v", | ||
13717 | [ALC662_AUTO] = "auto", | 14164 | [ALC662_AUTO] = "auto", |
13718 | }; | 14165 | }; |
13719 | 14166 | ||
13720 | static struct snd_pci_quirk alc662_cfg_tbl[] = { | 14167 | static struct snd_pci_quirk alc662_cfg_tbl[] = { |
14168 | SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS G71V", ALC663_ASUS_G71V), | ||
14169 | SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA), | ||
14170 | SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS M51VA", ALC663_ASUS_G50V), | ||
13721 | SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG), | 14171 | SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG), |
13722 | SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701), | 14172 | SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701), |
13723 | SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20), | 14173 | SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20), |
13724 | SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E), | 14174 | SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E), |
14175 | SND_PCI_QUIRK(0x1854, 0x2000, "ASUS H13-2000", ALC663_ASUS_H13), | ||
14176 | SND_PCI_QUIRK(0x1854, 0x2001, "ASUS H13-2001", ALC663_ASUS_H13), | ||
14177 | SND_PCI_QUIRK(0x1854, 0x2002, "ASUS H13-2002", ALC663_ASUS_H13), | ||
13725 | {} | 14178 | {} |
13726 | }; | 14179 | }; |
13727 | 14180 | ||
@@ -13809,7 +14262,53 @@ static struct alc_config_preset alc662_presets[] = { | |||
13809 | .unsol_event = alc662_eeepc_ep20_unsol_event, | 14262 | .unsol_event = alc662_eeepc_ep20_unsol_event, |
13810 | .init_hook = alc662_eeepc_ep20_inithook, | 14263 | .init_hook = alc662_eeepc_ep20_inithook, |
13811 | }, | 14264 | }, |
13812 | 14265 | [ALC663_ASUS_M51VA] = { | |
14266 | .mixers = { alc663_m51va_mixer, alc662_capture_mixer}, | ||
14267 | .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs }, | ||
14268 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), | ||
14269 | .dac_nids = alc662_dac_nids, | ||
14270 | .dig_out_nid = ALC662_DIGOUT_NID, | ||
14271 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | ||
14272 | .channel_mode = alc662_3ST_2ch_modes, | ||
14273 | .input_mux = &alc663_m51va_capture_source, | ||
14274 | .unsol_event = alc663_m51va_unsol_event, | ||
14275 | .init_hook = alc663_m51va_inithook, | ||
14276 | }, | ||
14277 | [ALC663_ASUS_G71V] = { | ||
14278 | .mixers = { alc663_g71v_mixer, alc662_capture_mixer}, | ||
14279 | .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs }, | ||
14280 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), | ||
14281 | .dac_nids = alc662_dac_nids, | ||
14282 | .dig_out_nid = ALC662_DIGOUT_NID, | ||
14283 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | ||
14284 | .channel_mode = alc662_3ST_2ch_modes, | ||
14285 | .input_mux = &alc662_eeepc_capture_source, | ||
14286 | .unsol_event = alc663_g71v_unsol_event, | ||
14287 | .init_hook = alc663_g71v_inithook, | ||
14288 | }, | ||
14289 | [ALC663_ASUS_H13] = { | ||
14290 | .mixers = { alc663_m51va_mixer, alc662_capture_mixer}, | ||
14291 | .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs }, | ||
14292 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), | ||
14293 | .dac_nids = alc662_dac_nids, | ||
14294 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | ||
14295 | .channel_mode = alc662_3ST_2ch_modes, | ||
14296 | .input_mux = &alc663_m51va_capture_source, | ||
14297 | .unsol_event = alc663_m51va_unsol_event, | ||
14298 | .init_hook = alc663_m51va_inithook, | ||
14299 | }, | ||
14300 | [ALC663_ASUS_G50V] = { | ||
14301 | .mixers = { alc663_g50v_mixer, alc662_capture_mixer}, | ||
14302 | .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs }, | ||
14303 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), | ||
14304 | .dac_nids = alc662_dac_nids, | ||
14305 | .dig_out_nid = ALC662_DIGOUT_NID, | ||
14306 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), | ||
14307 | .channel_mode = alc662_3ST_6ch_modes, | ||
14308 | .input_mux = &alc663_capture_source, | ||
14309 | .unsol_event = alc663_g50v_unsol_event, | ||
14310 | .init_hook = alc663_g50v_inithook, | ||
14311 | }, | ||
13813 | }; | 14312 | }; |
13814 | 14313 | ||
13815 | 14314 | ||
@@ -14082,6 +14581,8 @@ static int patch_alc662(struct hda_codec *codec) | |||
14082 | 14581 | ||
14083 | codec->spec = spec; | 14582 | codec->spec = spec; |
14084 | 14583 | ||
14584 | alc_fix_pll_init(codec, 0x20, 0x04, 15); | ||
14585 | |||
14085 | board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST, | 14586 | board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST, |
14086 | alc662_models, | 14587 | alc662_models, |
14087 | alc662_cfg_tbl); | 14588 | alc662_cfg_tbl); |
@@ -14108,11 +14609,17 @@ static int patch_alc662(struct hda_codec *codec) | |||
14108 | if (board_config != ALC662_AUTO) | 14609 | if (board_config != ALC662_AUTO) |
14109 | setup_preset(spec, &alc662_presets[board_config]); | 14610 | setup_preset(spec, &alc662_presets[board_config]); |
14110 | 14611 | ||
14111 | spec->stream_name_analog = "ALC662 Analog"; | 14612 | if (codec->vendor_id == 0x10ec0663) { |
14613 | spec->stream_name_analog = "ALC663 Analog"; | ||
14614 | spec->stream_name_digital = "ALC663 Digital"; | ||
14615 | } else { | ||
14616 | spec->stream_name_analog = "ALC662 Analog"; | ||
14617 | spec->stream_name_digital = "ALC662 Digital"; | ||
14618 | } | ||
14619 | |||
14112 | spec->stream_analog_playback = &alc662_pcm_analog_playback; | 14620 | spec->stream_analog_playback = &alc662_pcm_analog_playback; |
14113 | spec->stream_analog_capture = &alc662_pcm_analog_capture; | 14621 | spec->stream_analog_capture = &alc662_pcm_analog_capture; |
14114 | 14622 | ||
14115 | spec->stream_name_digital = "ALC662 Digital"; | ||
14116 | spec->stream_digital_playback = &alc662_pcm_digital_playback; | 14623 | spec->stream_digital_playback = &alc662_pcm_digital_playback; |
14117 | spec->stream_digital_capture = &alc662_pcm_digital_capture; | 14624 | spec->stream_digital_capture = &alc662_pcm_digital_capture; |
14118 | 14625 | ||
@@ -14151,6 +14658,7 @@ struct hda_codec_preset snd_hda_preset_realtek[] = { | |||
14151 | .patch = patch_alc883 }, | 14658 | .patch = patch_alc883 }, |
14152 | { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1", | 14659 | { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1", |
14153 | .patch = patch_alc662 }, | 14660 | .patch = patch_alc662 }, |
14661 | { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 }, | ||
14154 | { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, | 14662 | { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, |
14155 | { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, | 14663 | { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, |
14156 | { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 }, | 14664 | { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 }, |
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index a4f44a00bae8..08cb77f51880 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -636,21 +636,28 @@ static struct hda_verb stac92hd71bxx_core_init[] = { | |||
636 | { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 636 | { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
637 | }; | 637 | }; |
638 | 638 | ||
639 | #define HD_DISABLE_PORTF 3 | ||
639 | static struct hda_verb stac92hd71bxx_analog_core_init[] = { | 640 | static struct hda_verb stac92hd71bxx_analog_core_init[] = { |
641 | /* start of config #1 */ | ||
642 | |||
643 | /* connect port 0f to audio mixer */ | ||
644 | { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x2}, | ||
645 | { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Speaker */ | ||
646 | /* unmute right and left channels for node 0x0f */ | ||
647 | { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
648 | /* start of config #2 */ | ||
649 | |||
640 | /* set master volume and direct control */ | 650 | /* set master volume and direct control */ |
641 | { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, | 651 | { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, |
642 | /* connect headphone jack to dac1 */ | 652 | /* connect headphone jack to dac1 */ |
643 | { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01}, | 653 | { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01}, |
644 | /* connect ports 0d and 0f to audio mixer */ | 654 | /* connect port 0d to audio mixer */ |
645 | { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x2}, | 655 | { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x2}, |
646 | { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x2}, | ||
647 | { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Speaker */ | ||
648 | /* unmute dac0 input in audio mixer */ | 656 | /* unmute dac0 input in audio mixer */ |
649 | { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f}, | 657 | { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f}, |
650 | /* unmute right and left channels for nodes 0x0a, 0xd, 0x0f */ | 658 | /* unmute right and left channels for nodes 0x0a, 0xd */ |
651 | { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 659 | { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
652 | { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 660 | { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
653 | { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
654 | {} | 661 | {} |
655 | }; | 662 | }; |
656 | 663 | ||
@@ -818,6 +825,9 @@ static struct snd_kcontrol_new stac92hd71bxx_analog_mixer[] = { | |||
818 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1d, 0x0, HDA_OUTPUT), | 825 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1d, 0x0, HDA_OUTPUT), |
819 | HDA_CODEC_VOLUME_IDX("Capture Mux Volume", 0x1, 0x1b, 0x0, HDA_OUTPUT), | 826 | HDA_CODEC_VOLUME_IDX("Capture Mux Volume", 0x1, 0x1b, 0x0, HDA_OUTPUT), |
820 | 827 | ||
828 | HDA_CODEC_VOLUME("PC Beep Volume", 0x17, 0x2, HDA_INPUT), | ||
829 | HDA_CODEC_MUTE("PC Beep Switch", 0x17, 0x2, HDA_INPUT), | ||
830 | |||
821 | HDA_CODEC_MUTE("Analog Loopback 1", 0x17, 0x3, HDA_INPUT), | 831 | HDA_CODEC_MUTE("Analog Loopback 1", 0x17, 0x3, HDA_INPUT), |
822 | HDA_CODEC_MUTE("Analog Loopback 2", 0x17, 0x4, HDA_INPUT), | 832 | HDA_CODEC_MUTE("Analog Loopback 2", 0x17, 0x4, HDA_INPUT), |
823 | { } /* end */ | 833 | { } /* end */ |
@@ -1317,13 +1327,13 @@ static unsigned int ref92hd71bxx_pin_configs[10] = { | |||
1317 | 0x90a000f0, 0x01452050, | 1327 | 0x90a000f0, 0x01452050, |
1318 | }; | 1328 | }; |
1319 | 1329 | ||
1320 | static unsigned int dell_m4_1_pin_configs[13] = { | 1330 | static unsigned int dell_m4_1_pin_configs[10] = { |
1321 | 0x0421101f, 0x04a11221, 0x40f000f0, 0x90170110, | 1331 | 0x0421101f, 0x04a11221, 0x40f000f0, 0x90170110, |
1322 | 0x23a1902e, 0x23014250, 0x40f000f0, 0x90a000f0, | 1332 | 0x23a1902e, 0x23014250, 0x40f000f0, 0x90a000f0, |
1323 | 0x40f000f0, 0x4f0000f0, | 1333 | 0x40f000f0, 0x4f0000f0, |
1324 | }; | 1334 | }; |
1325 | 1335 | ||
1326 | static unsigned int dell_m4_2_pin_configs[13] = { | 1336 | static unsigned int dell_m4_2_pin_configs[10] = { |
1327 | 0x0421101f, 0x04a11221, 0x90a70330, 0x90170110, | 1337 | 0x0421101f, 0x04a11221, 0x90a70330, 0x90170110, |
1328 | 0x23a1902e, 0x23014250, 0x40f000f0, 0x40f000f0, | 1338 | 0x23a1902e, 0x23014250, 0x40f000f0, 0x40f000f0, |
1329 | 0x40f000f0, 0x044413b0, | 1339 | 0x40f000f0, 0x044413b0, |
@@ -1754,12 +1764,8 @@ static struct snd_pci_quirk stac9205_cfg_tbl[] = { | |||
1754 | "unknown Dell", STAC_9205_DELL_M42), | 1764 | "unknown Dell", STAC_9205_DELL_M42), |
1755 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f8, | 1765 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f8, |
1756 | "Dell Precision", STAC_9205_DELL_M43), | 1766 | "Dell Precision", STAC_9205_DELL_M43), |
1757 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021c, | ||
1758 | "Dell Precision", STAC_9205_DELL_M43), | ||
1759 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f9, | 1767 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f9, |
1760 | "Dell Precision", STAC_9205_DELL_M43), | 1768 | "Dell Precision", STAC_9205_DELL_M43), |
1761 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021b, | ||
1762 | "Dell Precision", STAC_9205_DELL_M43), | ||
1763 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fa, | 1769 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fa, |
1764 | "Dell Precision", STAC_9205_DELL_M43), | 1770 | "Dell Precision", STAC_9205_DELL_M43), |
1765 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fc, | 1771 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fc, |
@@ -1770,18 +1776,14 @@ static struct snd_pci_quirk stac9205_cfg_tbl[] = { | |||
1770 | "Dell Precision", STAC_9205_DELL_M43), | 1776 | "Dell Precision", STAC_9205_DELL_M43), |
1771 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ff, | 1777 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ff, |
1772 | "Dell Precision M4300", STAC_9205_DELL_M43), | 1778 | "Dell Precision M4300", STAC_9205_DELL_M43), |
1773 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0206, | ||
1774 | "Dell Precision", STAC_9205_DELL_M43), | ||
1775 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f1, | ||
1776 | "Dell Inspiron", STAC_9205_DELL_M44), | ||
1777 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f2, | ||
1778 | "Dell Inspiron", STAC_9205_DELL_M44), | ||
1779 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fc, | ||
1780 | "Dell Inspiron", STAC_9205_DELL_M44), | ||
1781 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fd, | ||
1782 | "Dell Inspiron", STAC_9205_DELL_M44), | ||
1783 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0204, | 1779 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0204, |
1784 | "unknown Dell", STAC_9205_DELL_M42), | 1780 | "unknown Dell", STAC_9205_DELL_M42), |
1781 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0206, | ||
1782 | "Dell Precision", STAC_9205_DELL_M43), | ||
1783 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021b, | ||
1784 | "Dell Precision", STAC_9205_DELL_M43), | ||
1785 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021c, | ||
1786 | "Dell Precision", STAC_9205_DELL_M43), | ||
1785 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021f, | 1787 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021f, |
1786 | "Dell Inspiron", STAC_9205_DELL_M44), | 1788 | "Dell Inspiron", STAC_9205_DELL_M44), |
1787 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0228, | 1789 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0228, |
@@ -3103,13 +3105,16 @@ static int stac92xx_init(struct hda_codec *codec) | |||
3103 | 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | 3105 | 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0); |
3104 | int def_conf = snd_hda_codec_read(codec, spec->pwr_nids[i], | 3106 | int def_conf = snd_hda_codec_read(codec, spec->pwr_nids[i], |
3105 | 0, AC_VERB_GET_CONFIG_DEFAULT, 0); | 3107 | 0, AC_VERB_GET_CONFIG_DEFAULT, 0); |
3108 | def_conf = get_defcfg_connect(def_conf); | ||
3106 | /* outputs are only ports capable of power management | 3109 | /* outputs are only ports capable of power management |
3107 | * any attempts on powering down a input port cause the | 3110 | * any attempts on powering down a input port cause the |
3108 | * referenced VREF to act quirky. | 3111 | * referenced VREF to act quirky. |
3109 | */ | 3112 | */ |
3110 | if (pinctl & AC_PINCTL_IN_EN) | 3113 | if (pinctl & AC_PINCTL_IN_EN) |
3111 | continue; | 3114 | continue; |
3112 | if (get_defcfg_connect(def_conf) != AC_JACK_PORT_FIXED) | 3115 | /* skip any ports that don't have jacks since presence |
3116 | * detection is useless */ | ||
3117 | if (def_conf && def_conf != AC_JACK_PORT_FIXED) | ||
3113 | continue; | 3118 | continue; |
3114 | enable_pin_detect(codec, spec->pwr_nids[i], event | i); | 3119 | enable_pin_detect(codec, spec->pwr_nids[i], event | i); |
3115 | codec->patch_ops.unsol_event(codec, (event | i) << 26); | 3120 | codec->patch_ops.unsol_event(codec, (event | i) << 26); |
@@ -3614,6 +3619,7 @@ static int patch_stac92hd71bxx(struct hda_codec *codec) | |||
3614 | 3619 | ||
3615 | codec->spec = spec; | 3620 | codec->spec = spec; |
3616 | spec->num_pins = ARRAY_SIZE(stac92hd71bxx_pin_nids); | 3621 | spec->num_pins = ARRAY_SIZE(stac92hd71bxx_pin_nids); |
3622 | spec->num_pwrs = ARRAY_SIZE(stac92hd71bxx_pwr_nids); | ||
3617 | spec->pin_nids = stac92hd71bxx_pin_nids; | 3623 | spec->pin_nids = stac92hd71bxx_pin_nids; |
3618 | spec->board_config = snd_hda_check_board_config(codec, | 3624 | spec->board_config = snd_hda_check_board_config(codec, |
3619 | STAC_92HD71BXX_MODELS, | 3625 | STAC_92HD71BXX_MODELS, |
@@ -3642,6 +3648,19 @@ again: | |||
3642 | spec->mixer = stac92hd71bxx_mixer; | 3648 | spec->mixer = stac92hd71bxx_mixer; |
3643 | spec->init = stac92hd71bxx_core_init; | 3649 | spec->init = stac92hd71bxx_core_init; |
3644 | break; | 3650 | break; |
3651 | case 0x111d7608: /* 5 Port with Analog Mixer */ | ||
3652 | /* no output amps */ | ||
3653 | spec->num_pwrs = 0; | ||
3654 | spec->mixer = stac92hd71bxx_analog_mixer; | ||
3655 | |||
3656 | /* disable VSW */ | ||
3657 | spec->init = &stac92hd71bxx_analog_core_init[HD_DISABLE_PORTF]; | ||
3658 | stac92xx_set_config_reg(codec, 0xf, 0x40f000f0); | ||
3659 | break; | ||
3660 | case 0x111d7603: /* 6 Port with Analog Mixer */ | ||
3661 | /* no output amps */ | ||
3662 | spec->num_pwrs = 0; | ||
3663 | /* fallthru */ | ||
3645 | default: | 3664 | default: |
3646 | spec->mixer = stac92hd71bxx_analog_mixer; | 3665 | spec->mixer = stac92hd71bxx_analog_mixer; |
3647 | spec->init = stac92hd71bxx_analog_core_init; | 3666 | spec->init = stac92hd71bxx_analog_core_init; |
@@ -3653,22 +3672,19 @@ again: | |||
3653 | /* GPIO0 High = EAPD */ | 3672 | /* GPIO0 High = EAPD */ |
3654 | spec->gpio_mask = 0x01; | 3673 | spec->gpio_mask = 0x01; |
3655 | spec->gpio_dir = 0x01; | 3674 | spec->gpio_dir = 0x01; |
3656 | spec->gpio_mask = 0x01; | ||
3657 | spec->gpio_data = 0x01; | 3675 | spec->gpio_data = 0x01; |
3658 | 3676 | ||
3659 | spec->mux_nids = stac92hd71bxx_mux_nids; | 3677 | spec->mux_nids = stac92hd71bxx_mux_nids; |
3660 | spec->adc_nids = stac92hd71bxx_adc_nids; | 3678 | spec->adc_nids = stac92hd71bxx_adc_nids; |
3661 | spec->dmic_nids = stac92hd71bxx_dmic_nids; | 3679 | spec->dmic_nids = stac92hd71bxx_dmic_nids; |
3662 | spec->dmux_nids = stac92hd71bxx_dmux_nids; | 3680 | spec->dmux_nids = stac92hd71bxx_dmux_nids; |
3681 | spec->pwr_nids = stac92hd71bxx_pwr_nids; | ||
3663 | 3682 | ||
3664 | spec->num_muxes = ARRAY_SIZE(stac92hd71bxx_mux_nids); | 3683 | spec->num_muxes = ARRAY_SIZE(stac92hd71bxx_mux_nids); |
3665 | spec->num_adcs = ARRAY_SIZE(stac92hd71bxx_adc_nids); | 3684 | spec->num_adcs = ARRAY_SIZE(stac92hd71bxx_adc_nids); |
3666 | spec->num_dmics = STAC92HD71BXX_NUM_DMICS; | 3685 | spec->num_dmics = STAC92HD71BXX_NUM_DMICS; |
3667 | spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids); | 3686 | spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids); |
3668 | 3687 | ||
3669 | spec->num_pwrs = ARRAY_SIZE(stac92hd71bxx_pwr_nids); | ||
3670 | spec->pwr_nids = stac92hd71bxx_pwr_nids; | ||
3671 | |||
3672 | spec->multiout.num_dacs = 1; | 3688 | spec->multiout.num_dacs = 1; |
3673 | spec->multiout.hp_nid = 0x11; | 3689 | spec->multiout.hp_nid = 0x11; |
3674 | spec->multiout.dac_nids = stac92hd71bxx_dac_nids; | 3690 | spec->multiout.dac_nids = stac92hd71bxx_dac_nids; |
@@ -4306,10 +4322,11 @@ struct hda_codec_preset snd_hda_preset_sigmatel[] = { | |||
4306 | { .id = 0x838476a5, .name = "STAC9255D", .patch = patch_stac9205 }, | 4322 | { .id = 0x838476a5, .name = "STAC9255D", .patch = patch_stac9205 }, |
4307 | { .id = 0x838476a6, .name = "STAC9254", .patch = patch_stac9205 }, | 4323 | { .id = 0x838476a6, .name = "STAC9254", .patch = patch_stac9205 }, |
4308 | { .id = 0x838476a7, .name = "STAC9254D", .patch = patch_stac9205 }, | 4324 | { .id = 0x838476a7, .name = "STAC9254D", .patch = patch_stac9205 }, |
4325 | { .id = 0x111d7603, .name = "92HD75B3X5", .patch = patch_stac92hd71bxx}, | ||
4326 | { .id = 0x111d7608, .name = "92HD75B2X5", .patch = patch_stac92hd71bxx}, | ||
4309 | { .id = 0x111d7674, .name = "92HD73D1X5", .patch = patch_stac92hd73xx }, | 4327 | { .id = 0x111d7674, .name = "92HD73D1X5", .patch = patch_stac92hd73xx }, |
4310 | { .id = 0x111d7675, .name = "92HD73C1X5", .patch = patch_stac92hd73xx }, | 4328 | { .id = 0x111d7675, .name = "92HD73C1X5", .patch = patch_stac92hd73xx }, |
4311 | { .id = 0x111d7676, .name = "92HD73E1X5", .patch = patch_stac92hd73xx }, | 4329 | { .id = 0x111d7676, .name = "92HD73E1X5", .patch = patch_stac92hd73xx }, |
4312 | { .id = 0x111d7608, .name = "92HD71BXX", .patch = patch_stac92hd71bxx }, | ||
4313 | { .id = 0x111d76b0, .name = "92HD71B8X", .patch = patch_stac92hd71bxx }, | 4330 | { .id = 0x111d76b0, .name = "92HD71B8X", .patch = patch_stac92hd71bxx }, |
4314 | { .id = 0x111d76b1, .name = "92HD71B8X", .patch = patch_stac92hd71bxx }, | 4331 | { .id = 0x111d76b1, .name = "92HD71B8X", .patch = patch_stac92hd71bxx }, |
4315 | { .id = 0x111d76b2, .name = "92HD71B7X", .patch = patch_stac92hd71bxx }, | 4332 | { .id = 0x111d76b2, .name = "92HD71B7X", .patch = patch_stac92hd71bxx }, |