diff options
Diffstat (limited to 'sound')
-rw-r--r-- | sound/pci/hda/hda_beep.c | 11 | ||||
-rw-r--r-- | sound/pci/hda/hda_codec.c | 71 | ||||
-rw-r--r-- | sound/pci/hda/hda_eld.c | 4 | ||||
-rw-r--r-- | sound/pci/hda/hda_generic.c | 18 | ||||
-rw-r--r-- | sound/pci/hda/hda_intel.c | 35 | ||||
-rw-r--r-- | sound/pci/hda/hda_local.h | 3 | ||||
-rw-r--r-- | sound/pci/hda/hda_proc.c | 3 | ||||
-rw-r--r-- | sound/pci/hda/patch_analog.c | 30 | ||||
-rw-r--r-- | sound/pci/hda/patch_ca0110.c | 3 | ||||
-rw-r--r-- | sound/pci/hda/patch_cmedia.c | 3 | ||||
-rw-r--r-- | sound/pci/hda/patch_conexant.c | 479 | ||||
-rw-r--r-- | sound/pci/hda/patch_intelhdmi.c | 2 | ||||
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 656 | ||||
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 655 | ||||
-rw-r--r-- | sound/pci/hda/patch_via.c | 88 |
15 files changed, 1600 insertions, 461 deletions
diff --git a/sound/pci/hda/hda_beep.c b/sound/pci/hda/hda_beep.c index 08fe6592ad44..3f51a981e604 100644 --- a/sound/pci/hda/hda_beep.c +++ b/sound/pci/hda/hda_beep.c | |||
@@ -51,19 +51,22 @@ static void snd_hda_generate_beep(struct work_struct *work) | |||
51 | * The tone frequency of beep generator on IDT/STAC codecs is | 51 | * The tone frequency of beep generator on IDT/STAC codecs is |
52 | * defined from the 8bit tone parameter, in Hz, | 52 | * defined from the 8bit tone parameter, in Hz, |
53 | * freq = 48000 * (257 - tone) / 1024 | 53 | * freq = 48000 * (257 - tone) / 1024 |
54 | * that is from 12kHz to 93.75kHz in step of 46.875 hz | 54 | * that is from 12kHz to 93.75Hz in steps of 46.875 Hz |
55 | */ | 55 | */ |
56 | static int beep_linear_tone(struct hda_beep *beep, int hz) | 56 | static int beep_linear_tone(struct hda_beep *beep, int hz) |
57 | { | 57 | { |
58 | if (hz <= 0) | ||
59 | return 0; | ||
58 | hz *= 1000; /* fixed point */ | 60 | hz *= 1000; /* fixed point */ |
59 | hz = hz - DIGBEEP_HZ_MIN; | 61 | hz = hz - DIGBEEP_HZ_MIN |
62 | + DIGBEEP_HZ_STEP / 2; /* round to nearest step */ | ||
60 | if (hz < 0) | 63 | if (hz < 0) |
61 | hz = 0; /* turn off PC beep*/ | 64 | hz = 0; /* turn off PC beep*/ |
62 | else if (hz >= (DIGBEEP_HZ_MAX - DIGBEEP_HZ_MIN)) | 65 | else if (hz >= (DIGBEEP_HZ_MAX - DIGBEEP_HZ_MIN)) |
63 | hz = 0xff; | 66 | hz = 1; /* max frequency */ |
64 | else { | 67 | else { |
65 | hz /= DIGBEEP_HZ_STEP; | 68 | hz /= DIGBEEP_HZ_STEP; |
66 | hz++; | 69 | hz = 255 - hz; |
67 | } | 70 | } |
68 | return hz; | 71 | return hz; |
69 | } | 72 | } |
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index eea91c3bd420..a23c27d2fb2f 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -151,7 +151,14 @@ make_codec_cmd(struct hda_codec *codec, hda_nid_t nid, int direct, | |||
151 | { | 151 | { |
152 | u32 val; | 152 | u32 val; |
153 | 153 | ||
154 | val = (u32)(codec->addr & 0x0f) << 28; | 154 | if ((codec->addr & ~0xf) || (direct & ~1) || (nid & ~0x7f) || |
155 | (verb & ~0xfff) || (parm & ~0xffff)) { | ||
156 | printk(KERN_ERR "hda-codec: out of range cmd %x:%x:%x:%x:%x\n", | ||
157 | codec->addr, direct, nid, verb, parm); | ||
158 | return ~0; | ||
159 | } | ||
160 | |||
161 | val = (u32)codec->addr << 28; | ||
155 | val |= (u32)direct << 27; | 162 | val |= (u32)direct << 27; |
156 | val |= (u32)nid << 20; | 163 | val |= (u32)nid << 20; |
157 | val |= verb << 8; | 164 | val |= verb << 8; |
@@ -168,6 +175,9 @@ static int codec_exec_verb(struct hda_codec *codec, unsigned int cmd, | |||
168 | struct hda_bus *bus = codec->bus; | 175 | struct hda_bus *bus = codec->bus; |
169 | int err; | 176 | int err; |
170 | 177 | ||
178 | if (cmd == ~0) | ||
179 | return -1; | ||
180 | |||
171 | if (res) | 181 | if (res) |
172 | *res = -1; | 182 | *res = -1; |
173 | again: | 183 | again: |
@@ -292,11 +302,20 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, | |||
292 | unsigned int parm; | 302 | unsigned int parm; |
293 | int i, conn_len, conns; | 303 | int i, conn_len, conns; |
294 | unsigned int shift, num_elems, mask; | 304 | unsigned int shift, num_elems, mask; |
305 | unsigned int wcaps; | ||
295 | hda_nid_t prev_nid; | 306 | hda_nid_t prev_nid; |
296 | 307 | ||
297 | if (snd_BUG_ON(!conn_list || max_conns <= 0)) | 308 | if (snd_BUG_ON(!conn_list || max_conns <= 0)) |
298 | return -EINVAL; | 309 | return -EINVAL; |
299 | 310 | ||
311 | wcaps = get_wcaps(codec, nid); | ||
312 | if (!(wcaps & AC_WCAP_CONN_LIST) && | ||
313 | get_wcaps_type(wcaps) != AC_WID_VOL_KNB) { | ||
314 | snd_printk(KERN_WARNING "hda_codec: " | ||
315 | "connection list not available for 0x%x\n", nid); | ||
316 | return -EINVAL; | ||
317 | } | ||
318 | |||
300 | parm = snd_hda_param_read(codec, nid, AC_PAR_CONNLIST_LEN); | 319 | parm = snd_hda_param_read(codec, nid, AC_PAR_CONNLIST_LEN); |
301 | if (parm & AC_CLIST_LONG) { | 320 | if (parm & AC_CLIST_LONG) { |
302 | /* long form */ | 321 | /* long form */ |
@@ -317,6 +336,8 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, | |||
317 | /* single connection */ | 336 | /* single connection */ |
318 | parm = snd_hda_codec_read(codec, nid, 0, | 337 | parm = snd_hda_codec_read(codec, nid, 0, |
319 | AC_VERB_GET_CONNECT_LIST, 0); | 338 | AC_VERB_GET_CONNECT_LIST, 0); |
339 | if (parm == -1 && codec->bus->rirb_error) | ||
340 | return -EIO; | ||
320 | conn_list[0] = parm & mask; | 341 | conn_list[0] = parm & mask; |
321 | return 1; | 342 | return 1; |
322 | } | 343 | } |
@@ -328,11 +349,20 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, | |||
328 | int range_val; | 349 | int range_val; |
329 | hda_nid_t val, n; | 350 | hda_nid_t val, n; |
330 | 351 | ||
331 | if (i % num_elems == 0) | 352 | if (i % num_elems == 0) { |
332 | parm = snd_hda_codec_read(codec, nid, 0, | 353 | parm = snd_hda_codec_read(codec, nid, 0, |
333 | AC_VERB_GET_CONNECT_LIST, i); | 354 | AC_VERB_GET_CONNECT_LIST, i); |
355 | if (parm == -1 && codec->bus->rirb_error) | ||
356 | return -EIO; | ||
357 | } | ||
334 | range_val = !!(parm & (1 << (shift-1))); /* ranges */ | 358 | range_val = !!(parm & (1 << (shift-1))); /* ranges */ |
335 | val = parm & mask; | 359 | val = parm & mask; |
360 | if (val == 0) { | ||
361 | snd_printk(KERN_WARNING "hda_codec: " | ||
362 | "invalid CONNECT_LIST verb %x[%i]:%x\n", | ||
363 | nid, i, parm); | ||
364 | return 0; | ||
365 | } | ||
336 | parm >>= shift; | 366 | parm >>= shift; |
337 | if (range_val) { | 367 | if (range_val) { |
338 | /* ranges between the previous and this one */ | 368 | /* ranges between the previous and this one */ |
@@ -722,8 +752,7 @@ static int read_pin_defaults(struct hda_codec *codec) | |||
722 | for (i = 0; i < codec->num_nodes; i++, nid++) { | 752 | for (i = 0; i < codec->num_nodes; i++, nid++) { |
723 | struct hda_pincfg *pin; | 753 | struct hda_pincfg *pin; |
724 | unsigned int wcaps = get_wcaps(codec, nid); | 754 | unsigned int wcaps = get_wcaps(codec, nid); |
725 | unsigned int wid_type = (wcaps & AC_WCAP_TYPE) >> | 755 | unsigned int wid_type = get_wcaps_type(wcaps); |
726 | AC_WCAP_TYPE_SHIFT; | ||
727 | if (wid_type != AC_WID_PIN) | 756 | if (wid_type != AC_WID_PIN) |
728 | continue; | 757 | continue; |
729 | pin = snd_array_new(&codec->init_pins); | 758 | pin = snd_array_new(&codec->init_pins); |
@@ -2347,16 +2376,20 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg, | |||
2347 | hda_nid_t nid; | 2376 | hda_nid_t nid; |
2348 | int i; | 2377 | int i; |
2349 | 2378 | ||
2350 | snd_hda_codec_write(codec, fg, 0, AC_VERB_SET_POWER_STATE, | 2379 | /* this delay seems necessary to avoid click noise at power-down */ |
2380 | if (power_state == AC_PWRST_D3) | ||
2381 | msleep(100); | ||
2382 | snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE, | ||
2351 | power_state); | 2383 | power_state); |
2352 | msleep(10); /* partial workaround for "azx_get_response timeout" */ | 2384 | /* partial workaround for "azx_get_response timeout" */ |
2385 | if (power_state == AC_PWRST_D0) | ||
2386 | msleep(10); | ||
2353 | 2387 | ||
2354 | nid = codec->start_nid; | 2388 | nid = codec->start_nid; |
2355 | for (i = 0; i < codec->num_nodes; i++, nid++) { | 2389 | for (i = 0; i < codec->num_nodes; i++, nid++) { |
2356 | unsigned int wcaps = get_wcaps(codec, nid); | 2390 | unsigned int wcaps = get_wcaps(codec, nid); |
2357 | if (wcaps & AC_WCAP_POWER) { | 2391 | if (wcaps & AC_WCAP_POWER) { |
2358 | unsigned int wid_type = (wcaps & AC_WCAP_TYPE) >> | 2392 | unsigned int wid_type = get_wcaps_type(wcaps); |
2359 | AC_WCAP_TYPE_SHIFT; | ||
2360 | if (power_state == AC_PWRST_D3 && | 2393 | if (power_state == AC_PWRST_D3 && |
2361 | wid_type == AC_WID_PIN) { | 2394 | wid_type == AC_WID_PIN) { |
2362 | unsigned int pincap; | 2395 | unsigned int pincap; |
@@ -2564,7 +2597,7 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate, | |||
2564 | case 20: | 2597 | case 20: |
2565 | case 24: | 2598 | case 24: |
2566 | case 32: | 2599 | case 32: |
2567 | if (maxbps >= 32) | 2600 | if (maxbps >= 32 || format == SNDRV_PCM_FORMAT_FLOAT_LE) |
2568 | val |= 0x40; | 2601 | val |= 0x40; |
2569 | else if (maxbps >= 24) | 2602 | else if (maxbps >= 24) |
2570 | val |= 0x30; | 2603 | val |= 0x30; |
@@ -2693,7 +2726,8 @@ static int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, | |||
2693 | } | 2726 | } |
2694 | if (streams & AC_SUPFMT_FLOAT32) { | 2727 | if (streams & AC_SUPFMT_FLOAT32) { |
2695 | formats |= SNDRV_PCM_FMTBIT_FLOAT_LE; | 2728 | formats |= SNDRV_PCM_FMTBIT_FLOAT_LE; |
2696 | bps = 32; | 2729 | if (!bps) |
2730 | bps = 32; | ||
2697 | } | 2731 | } |
2698 | if (streams == AC_SUPFMT_AC3) { | 2732 | if (streams == AC_SUPFMT_AC3) { |
2699 | /* should be exclusive */ | 2733 | /* should be exclusive */ |
@@ -3467,10 +3501,16 @@ int snd_hda_multi_out_analog_open(struct hda_codec *codec, | |||
3467 | } | 3501 | } |
3468 | mutex_lock(&codec->spdif_mutex); | 3502 | mutex_lock(&codec->spdif_mutex); |
3469 | if (mout->share_spdif) { | 3503 | if (mout->share_spdif) { |
3470 | runtime->hw.rates &= mout->spdif_rates; | 3504 | if ((runtime->hw.rates & mout->spdif_rates) && |
3471 | runtime->hw.formats &= mout->spdif_formats; | 3505 | (runtime->hw.formats & mout->spdif_formats)) { |
3472 | if (mout->spdif_maxbps < hinfo->maxbps) | 3506 | runtime->hw.rates &= mout->spdif_rates; |
3473 | hinfo->maxbps = mout->spdif_maxbps; | 3507 | runtime->hw.formats &= mout->spdif_formats; |
3508 | if (mout->spdif_maxbps < hinfo->maxbps) | ||
3509 | hinfo->maxbps = mout->spdif_maxbps; | ||
3510 | } else { | ||
3511 | mout->share_spdif = 0; | ||
3512 | /* FIXME: need notify? */ | ||
3513 | } | ||
3474 | } | 3514 | } |
3475 | mutex_unlock(&codec->spdif_mutex); | 3515 | mutex_unlock(&codec->spdif_mutex); |
3476 | } | 3516 | } |
@@ -3640,8 +3680,7 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, | |||
3640 | end_nid = codec->start_nid + codec->num_nodes; | 3680 | end_nid = codec->start_nid + codec->num_nodes; |
3641 | for (nid = codec->start_nid; nid < end_nid; nid++) { | 3681 | for (nid = codec->start_nid; nid < end_nid; nid++) { |
3642 | unsigned int wid_caps = get_wcaps(codec, nid); | 3682 | unsigned int wid_caps = get_wcaps(codec, nid); |
3643 | unsigned int wid_type = | 3683 | unsigned int wid_type = get_wcaps_type(wid_caps); |
3644 | (wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; | ||
3645 | unsigned int def_conf; | 3684 | unsigned int def_conf; |
3646 | short assoc, loc; | 3685 | short assoc, loc; |
3647 | 3686 | ||
diff --git a/sound/pci/hda/hda_eld.c b/sound/pci/hda/hda_eld.c index fcad5ec31773..9446a5abea13 100644 --- a/sound/pci/hda/hda_eld.c +++ b/sound/pci/hda/hda_eld.c | |||
@@ -508,7 +508,7 @@ static void hdmi_write_eld_info(struct snd_info_entry *entry, | |||
508 | char name[64]; | 508 | char name[64]; |
509 | char *sname; | 509 | char *sname; |
510 | long long val; | 510 | long long val; |
511 | int n; | 511 | unsigned int n; |
512 | 512 | ||
513 | while (!snd_info_get_line(buffer, line, sizeof(line))) { | 513 | while (!snd_info_get_line(buffer, line, sizeof(line))) { |
514 | if (sscanf(line, "%s %llx", name, &val) != 2) | 514 | if (sscanf(line, "%s %llx", name, &val) != 2) |
@@ -539,7 +539,7 @@ static void hdmi_write_eld_info(struct snd_info_entry *entry, | |||
539 | sname++; | 539 | sname++; |
540 | n = 10 * n + name[4] - '0'; | 540 | n = 10 * n + name[4] - '0'; |
541 | } | 541 | } |
542 | if (n < 0 || n > 31) /* double the CEA limit */ | 542 | if (n >= ELD_MAX_SAD) |
543 | continue; | 543 | continue; |
544 | if (!strcmp(sname, "_coding_type")) | 544 | if (!strcmp(sname, "_coding_type")) |
545 | e->sad[n].format = val; | 545 | e->sad[n].format = val; |
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index 1d5797a96682..b36f6c5a92df 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c | |||
@@ -121,11 +121,17 @@ static int add_new_node(struct hda_codec *codec, struct hda_gspec *spec, hda_nid | |||
121 | if (node == NULL) | 121 | if (node == NULL) |
122 | return -ENOMEM; | 122 | return -ENOMEM; |
123 | node->nid = nid; | 123 | node->nid = nid; |
124 | nconns = snd_hda_get_connections(codec, nid, conn_list, | 124 | node->wid_caps = get_wcaps(codec, nid); |
125 | HDA_MAX_CONNECTIONS); | 125 | node->type = get_wcaps_type(node->wid_caps); |
126 | if (nconns < 0) { | 126 | if (node->wid_caps & AC_WCAP_CONN_LIST) { |
127 | kfree(node); | 127 | nconns = snd_hda_get_connections(codec, nid, conn_list, |
128 | return nconns; | 128 | HDA_MAX_CONNECTIONS); |
129 | if (nconns < 0) { | ||
130 | kfree(node); | ||
131 | return nconns; | ||
132 | } | ||
133 | } else { | ||
134 | nconns = 0; | ||
129 | } | 135 | } |
130 | if (nconns <= ARRAY_SIZE(node->slist)) | 136 | if (nconns <= ARRAY_SIZE(node->slist)) |
131 | node->conn_list = node->slist; | 137 | node->conn_list = node->slist; |
@@ -140,8 +146,6 @@ static int add_new_node(struct hda_codec *codec, struct hda_gspec *spec, hda_nid | |||
140 | } | 146 | } |
141 | memcpy(node->conn_list, conn_list, nconns * sizeof(hda_nid_t)); | 147 | memcpy(node->conn_list, conn_list, nconns * sizeof(hda_nid_t)); |
142 | node->nconns = nconns; | 148 | node->nconns = nconns; |
143 | node->wid_caps = get_wcaps(codec, nid); | ||
144 | node->type = (node->wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; | ||
145 | 149 | ||
146 | if (node->type == AC_WID_PIN) { | 150 | if (node->type == AC_WID_PIN) { |
147 | node->pin_caps = snd_hda_query_pin_caps(codec, node->nid); | 151 | node->pin_caps = snd_hda_query_pin_caps(codec, node->nid); |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index a2f4a116f872..4db854b43e6b 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -1469,6 +1469,18 @@ static int azx_pcm_open(struct snd_pcm_substream *substream) | |||
1469 | mutex_unlock(&chip->open_mutex); | 1469 | mutex_unlock(&chip->open_mutex); |
1470 | return err; | 1470 | return err; |
1471 | } | 1471 | } |
1472 | snd_pcm_limit_hw_rates(runtime); | ||
1473 | /* sanity check */ | ||
1474 | if (snd_BUG_ON(!runtime->hw.channels_min) || | ||
1475 | snd_BUG_ON(!runtime->hw.channels_max) || | ||
1476 | snd_BUG_ON(!runtime->hw.formats) || | ||
1477 | snd_BUG_ON(!runtime->hw.rates)) { | ||
1478 | azx_release_device(azx_dev); | ||
1479 | hinfo->ops.close(hinfo, apcm->codec, substream); | ||
1480 | snd_hda_power_down(apcm->codec); | ||
1481 | mutex_unlock(&chip->open_mutex); | ||
1482 | return -EINVAL; | ||
1483 | } | ||
1472 | spin_lock_irqsave(&chip->reg_lock, flags); | 1484 | spin_lock_irqsave(&chip->reg_lock, flags); |
1473 | azx_dev->substream = substream; | 1485 | azx_dev->substream = substream; |
1474 | azx_dev->running = 0; | 1486 | azx_dev->running = 0; |
@@ -1477,7 +1489,6 @@ static int azx_pcm_open(struct snd_pcm_substream *substream) | |||
1477 | runtime->private_data = azx_dev; | 1489 | runtime->private_data = azx_dev; |
1478 | snd_pcm_set_sync(substream); | 1490 | snd_pcm_set_sync(substream); |
1479 | mutex_unlock(&chip->open_mutex); | 1491 | mutex_unlock(&chip->open_mutex); |
1480 | |||
1481 | return 0; | 1492 | return 0; |
1482 | } | 1493 | } |
1483 | 1494 | ||
@@ -2337,9 +2348,19 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, | |||
2337 | gcap = azx_readw(chip, GCAP); | 2348 | gcap = azx_readw(chip, GCAP); |
2338 | snd_printdd(SFX "chipset global capabilities = 0x%x\n", gcap); | 2349 | snd_printdd(SFX "chipset global capabilities = 0x%x\n", gcap); |
2339 | 2350 | ||
2340 | /* ATI chips seems buggy about 64bit DMA addresses */ | 2351 | /* disable SB600 64bit support for safety */ |
2341 | if (chip->driver_type == AZX_DRIVER_ATI) | 2352 | if ((chip->driver_type == AZX_DRIVER_ATI) || |
2342 | gcap &= ~ICH6_GCAP_64OK; | 2353 | (chip->driver_type == AZX_DRIVER_ATIHDMI)) { |
2354 | struct pci_dev *p_smbus; | ||
2355 | p_smbus = pci_get_device(PCI_VENDOR_ID_ATI, | ||
2356 | PCI_DEVICE_ID_ATI_SBX00_SMBUS, | ||
2357 | NULL); | ||
2358 | if (p_smbus) { | ||
2359 | if (p_smbus->revision < 0x30) | ||
2360 | gcap &= ~ICH6_GCAP_64OK; | ||
2361 | pci_dev_put(p_smbus); | ||
2362 | } | ||
2363 | } | ||
2343 | 2364 | ||
2344 | /* allow 64bit DMA address if supported by H/W */ | 2365 | /* allow 64bit DMA address if supported by H/W */ |
2345 | if ((gcap & ICH6_GCAP_64OK) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64))) | 2366 | if ((gcap & ICH6_GCAP_64OK) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64))) |
@@ -2613,11 +2634,15 @@ static struct pci_device_id azx_ids[] = { | |||
2613 | /* this entry seems still valid -- i.e. without emu20kx chip */ | 2634 | /* this entry seems still valid -- i.e. without emu20kx chip */ |
2614 | { PCI_DEVICE(0x1102, 0x0009), .driver_data = AZX_DRIVER_GENERIC }, | 2635 | { PCI_DEVICE(0x1102, 0x0009), .driver_data = AZX_DRIVER_GENERIC }, |
2615 | #endif | 2636 | #endif |
2616 | /* AMD Generic, PCI class code and Vendor ID for HD Audio */ | 2637 | /* AMD/ATI Generic, PCI class code and Vendor ID for HD Audio */ |
2617 | { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_ANY_ID), | 2638 | { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_ANY_ID), |
2618 | .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, | 2639 | .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, |
2619 | .class_mask = 0xffffff, | 2640 | .class_mask = 0xffffff, |
2620 | .driver_data = AZX_DRIVER_GENERIC }, | 2641 | .driver_data = AZX_DRIVER_GENERIC }, |
2642 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_ANY_ID), | ||
2643 | .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, | ||
2644 | .class_mask = 0xffffff, | ||
2645 | .driver_data = AZX_DRIVER_GENERIC }, | ||
2621 | { 0, } | 2646 | { 0, } |
2622 | }; | 2647 | }; |
2623 | MODULE_DEVICE_TABLE(pci, azx_ids); | 2648 | MODULE_DEVICE_TABLE(pci, azx_ids); |
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index 75aa3785212f..fa57cb93b443 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h | |||
@@ -407,6 +407,9 @@ static inline u32 get_wcaps(struct hda_codec *codec, hda_nid_t nid) | |||
407 | return codec->wcaps[nid - codec->start_nid]; | 407 | return codec->wcaps[nid - codec->start_nid]; |
408 | } | 408 | } |
409 | 409 | ||
410 | /* get the widget type from widget capability bits */ | ||
411 | #define get_wcaps_type(wcaps) (((wcaps) & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT) | ||
412 | |||
410 | u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction); | 413 | u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction); |
411 | int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir, | 414 | int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir, |
412 | unsigned int caps); | 415 | unsigned int caps); |
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c index 418c5d1badaa..a721eb08a290 100644 --- a/sound/pci/hda/hda_proc.c +++ b/sound/pci/hda/hda_proc.c | |||
@@ -508,8 +508,7 @@ static void print_codec_info(struct snd_info_entry *entry, | |||
508 | unsigned int wid_caps = | 508 | unsigned int wid_caps = |
509 | snd_hda_param_read(codec, nid, | 509 | snd_hda_param_read(codec, nid, |
510 | AC_PAR_AUDIO_WIDGET_CAP); | 510 | AC_PAR_AUDIO_WIDGET_CAP); |
511 | unsigned int wid_type = | 511 | unsigned int wid_type = get_wcaps_type(wid_caps); |
512 | (wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; | ||
513 | hda_nid_t conn[HDA_MAX_CONNECTIONS]; | 512 | hda_nid_t conn[HDA_MAX_CONNECTIONS]; |
514 | int conn_len = 0; | 513 | int conn_len = 0; |
515 | 514 | ||
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index ad700761a561..ab3bcb78ace9 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c | |||
@@ -2982,7 +2982,8 @@ static int patch_ad1988(struct hda_codec *codec) | |||
2982 | board_config = snd_hda_check_board_config(codec, AD1988_MODEL_LAST, | 2982 | board_config = snd_hda_check_board_config(codec, AD1988_MODEL_LAST, |
2983 | ad1988_models, ad1988_cfg_tbl); | 2983 | ad1988_models, ad1988_cfg_tbl); |
2984 | if (board_config < 0) { | 2984 | if (board_config < 0) { |
2985 | printk(KERN_INFO "hda_codec: Unknown model for AD1988, trying auto-probe from BIOS...\n"); | 2985 | printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", |
2986 | codec->chip_name); | ||
2986 | board_config = AD1988_AUTO; | 2987 | board_config = AD1988_AUTO; |
2987 | } | 2988 | } |
2988 | 2989 | ||
@@ -3746,9 +3747,30 @@ static struct snd_kcontrol_new ad1884a_laptop_mixers[] = { | |||
3746 | { } /* end */ | 3747 | { } /* end */ |
3747 | }; | 3748 | }; |
3748 | 3749 | ||
3750 | static int ad1884a_mobile_master_sw_put(struct snd_kcontrol *kcontrol, | ||
3751 | struct snd_ctl_elem_value *ucontrol) | ||
3752 | { | ||
3753 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
3754 | int ret = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol); | ||
3755 | int mute = (!ucontrol->value.integer.value[0] && | ||
3756 | !ucontrol->value.integer.value[1]); | ||
3757 | /* toggle GPIO1 according to the mute state */ | ||
3758 | snd_hda_codec_write_cache(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, | ||
3759 | mute ? 0x02 : 0x0); | ||
3760 | return ret; | ||
3761 | } | ||
3762 | |||
3749 | static struct snd_kcontrol_new ad1884a_mobile_mixers[] = { | 3763 | static struct snd_kcontrol_new ad1884a_mobile_mixers[] = { |
3750 | HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT), | 3764 | HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT), |
3751 | HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT), | 3765 | /*HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/ |
3766 | { | ||
3767 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
3768 | .name = "Master Playback Switch", | ||
3769 | .info = snd_hda_mixer_amp_switch_info, | ||
3770 | .get = snd_hda_mixer_amp_switch_get, | ||
3771 | .put = ad1884a_mobile_master_sw_put, | ||
3772 | .private_value = HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT), | ||
3773 | }, | ||
3752 | HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT), | 3774 | HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT), |
3753 | HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT), | 3775 | HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT), |
3754 | HDA_CODEC_VOLUME("Mic Capture Volume", 0x14, 0x0, HDA_INPUT), | 3776 | HDA_CODEC_VOLUME("Mic Capture Volume", 0x14, 0x0, HDA_INPUT), |
@@ -3869,6 +3891,10 @@ static struct hda_verb ad1884a_mobile_verbs[] = { | |||
3869 | /* unsolicited event for pin-sense */ | 3891 | /* unsolicited event for pin-sense */ |
3870 | {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT}, | 3892 | {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT}, |
3871 | {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT}, | 3893 | {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT}, |
3894 | /* allow to touch GPIO1 (for mute control) */ | ||
3895 | {0x01, AC_VERB_SET_GPIO_MASK, 0x02}, | ||
3896 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02}, | ||
3897 | {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, /* first muted */ | ||
3872 | { } /* end */ | 3898 | { } /* end */ |
3873 | }; | 3899 | }; |
3874 | 3900 | ||
diff --git a/sound/pci/hda/patch_ca0110.c b/sound/pci/hda/patch_ca0110.c index 019ca7cb56d7..d08353d3bb7f 100644 --- a/sound/pci/hda/patch_ca0110.c +++ b/sound/pci/hda/patch_ca0110.c | |||
@@ -459,8 +459,7 @@ static void parse_input(struct hda_codec *codec) | |||
459 | nid = codec->start_nid; | 459 | nid = codec->start_nid; |
460 | for (i = 0; i < codec->num_nodes; i++, nid++) { | 460 | for (i = 0; i < codec->num_nodes; i++, nid++) { |
461 | unsigned int wcaps = get_wcaps(codec, nid); | 461 | unsigned int wcaps = get_wcaps(codec, nid); |
462 | unsigned int type = (wcaps & AC_WCAP_TYPE) >> | 462 | unsigned int type = get_wcaps_type(wcaps); |
463 | AC_WCAP_TYPE_SHIFT; | ||
464 | if (type != AC_WID_AUD_IN) | 463 | if (type != AC_WID_AUD_IN) |
465 | continue; | 464 | continue; |
466 | if (snd_hda_get_connections(codec, nid, &pin, 1) != 1) | 465 | if (snd_hda_get_connections(codec, nid, &pin, 1) != 1) |
diff --git a/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c index c921264bbd71..780e1a72114a 100644 --- a/sound/pci/hda/patch_cmedia.c +++ b/sound/pci/hda/patch_cmedia.c | |||
@@ -635,7 +635,8 @@ static int patch_cmi9880(struct hda_codec *codec) | |||
635 | cmi9880_models, | 635 | cmi9880_models, |
636 | cmi9880_cfg_tbl); | 636 | cmi9880_cfg_tbl); |
637 | if (spec->board_config < 0) { | 637 | if (spec->board_config < 0) { |
638 | snd_printdd(KERN_INFO "hda_codec: Unknown model for CMI9880\n"); | 638 | snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", |
639 | codec->chip_name); | ||
639 | spec->board_config = CMI_AUTO; /* try everything */ | 640 | spec->board_config = CMI_AUTO; /* try everything */ |
640 | } | 641 | } |
641 | 642 | ||
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index ac868c59f9e3..9d899eda44d7 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c | |||
@@ -108,6 +108,8 @@ struct conexant_spec { | |||
108 | struct hda_input_mux private_imux; | 108 | struct hda_input_mux private_imux; |
109 | hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; | 109 | hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; |
110 | 110 | ||
111 | unsigned int dell_automute; | ||
112 | unsigned int port_d_mode; | ||
111 | }; | 113 | }; |
112 | 114 | ||
113 | static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo, | 115 | static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo, |
@@ -1908,6 +1910,480 @@ static int patch_cxt5051(struct hda_codec *codec) | |||
1908 | return 0; | 1910 | return 0; |
1909 | } | 1911 | } |
1910 | 1912 | ||
1913 | /* Conexant 5066 specific */ | ||
1914 | |||
1915 | static hda_nid_t cxt5066_dac_nids[1] = { 0x10 }; | ||
1916 | static hda_nid_t cxt5066_adc_nids[3] = { 0x14, 0x15, 0x16 }; | ||
1917 | static hda_nid_t cxt5066_capsrc_nids[1] = { 0x17 }; | ||
1918 | #define CXT5066_SPDIF_OUT 0x21 | ||
1919 | |||
1920 | static struct hda_channel_mode cxt5066_modes[1] = { | ||
1921 | { 2, NULL }, | ||
1922 | }; | ||
1923 | |||
1924 | static void cxt5066_update_speaker(struct hda_codec *codec) | ||
1925 | { | ||
1926 | struct conexant_spec *spec = codec->spec; | ||
1927 | unsigned int pinctl; | ||
1928 | |||
1929 | snd_printdd("CXT5066: update speaker, hp_present=%d\n", | ||
1930 | spec->hp_present); | ||
1931 | |||
1932 | /* Port A (HP) */ | ||
1933 | pinctl = ((spec->hp_present & 1) && spec->cur_eapd) ? PIN_HP : 0; | ||
1934 | snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
1935 | pinctl); | ||
1936 | |||
1937 | /* Port D (HP/LO) */ | ||
1938 | pinctl = ((spec->hp_present & 2) && spec->cur_eapd) | ||
1939 | ? spec->port_d_mode : 0; | ||
1940 | snd_hda_codec_write(codec, 0x1c, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
1941 | pinctl); | ||
1942 | |||
1943 | /* CLASS_D AMP */ | ||
1944 | pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0; | ||
1945 | snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
1946 | pinctl); | ||
1947 | |||
1948 | if (spec->dell_automute) { | ||
1949 | /* DELL AIO Port Rule: PortA > PortD > IntSpk */ | ||
1950 | pinctl = (!(spec->hp_present & 1) && spec->cur_eapd) | ||
1951 | ? PIN_OUT : 0; | ||
1952 | snd_hda_codec_write(codec, 0x1c, 0, | ||
1953 | AC_VERB_SET_PIN_WIDGET_CONTROL, pinctl); | ||
1954 | } | ||
1955 | } | ||
1956 | |||
1957 | /* turn on/off EAPD (+ mute HP) as a master switch */ | ||
1958 | static int cxt5066_hp_master_sw_put(struct snd_kcontrol *kcontrol, | ||
1959 | struct snd_ctl_elem_value *ucontrol) | ||
1960 | { | ||
1961 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
1962 | |||
1963 | if (!cxt_eapd_put(kcontrol, ucontrol)) | ||
1964 | return 0; | ||
1965 | |||
1966 | cxt5066_update_speaker(codec); | ||
1967 | return 1; | ||
1968 | } | ||
1969 | |||
1970 | /* toggle input of built-in and mic jack appropriately */ | ||
1971 | static void cxt5066_automic(struct hda_codec *codec) | ||
1972 | { | ||
1973 | static struct hda_verb ext_mic_present[] = { | ||
1974 | /* enable external mic, port B */ | ||
1975 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
1976 | |||
1977 | /* switch to external mic input */ | ||
1978 | {0x17, AC_VERB_SET_CONNECT_SEL, 0}, | ||
1979 | |||
1980 | /* disable internal mic, port C */ | ||
1981 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
1982 | {} | ||
1983 | }; | ||
1984 | static struct hda_verb ext_mic_absent[] = { | ||
1985 | /* enable internal mic, port C */ | ||
1986 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
1987 | |||
1988 | /* switch to internal mic input */ | ||
1989 | {0x17, AC_VERB_SET_CONNECT_SEL, 1}, | ||
1990 | |||
1991 | /* disable external mic, port B */ | ||
1992 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
1993 | {} | ||
1994 | }; | ||
1995 | unsigned int present; | ||
1996 | |||
1997 | present = snd_hda_codec_read(codec, 0x1a, 0, | ||
1998 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
1999 | if (present) { | ||
2000 | snd_printdd("CXT5066: external microphone detected\n"); | ||
2001 | snd_hda_sequence_write(codec, ext_mic_present); | ||
2002 | } else { | ||
2003 | snd_printdd("CXT5066: external microphone absent\n"); | ||
2004 | snd_hda_sequence_write(codec, ext_mic_absent); | ||
2005 | } | ||
2006 | } | ||
2007 | |||
2008 | /* mute internal speaker if HP is plugged */ | ||
2009 | static void cxt5066_hp_automute(struct hda_codec *codec) | ||
2010 | { | ||
2011 | struct conexant_spec *spec = codec->spec; | ||
2012 | unsigned int portA, portD; | ||
2013 | |||
2014 | /* Port A */ | ||
2015 | portA = snd_hda_codec_read(codec, 0x19, 0, AC_VERB_GET_PIN_SENSE, 0) | ||
2016 | & AC_PINSENSE_PRESENCE; | ||
2017 | |||
2018 | /* Port D */ | ||
2019 | portD = (snd_hda_codec_read(codec, 0x1c, 0, AC_VERB_GET_PIN_SENSE, 0) | ||
2020 | & AC_PINSENSE_PRESENCE) << 1; | ||
2021 | |||
2022 | spec->hp_present = !!(portA | portD); | ||
2023 | snd_printdd("CXT5066: hp automute portA=%x portD=%x present=%d\n", | ||
2024 | portA, portD, spec->hp_present); | ||
2025 | cxt5066_update_speaker(codec); | ||
2026 | } | ||
2027 | |||
2028 | /* unsolicited event for jack sensing */ | ||
2029 | static void cxt5066_unsol_event(struct hda_codec *codec, unsigned int res) | ||
2030 | { | ||
2031 | snd_printdd("CXT5066: unsol event %x (%x)\n", res, res >> 26); | ||
2032 | switch (res >> 26) { | ||
2033 | case CONEXANT_HP_EVENT: | ||
2034 | cxt5066_hp_automute(codec); | ||
2035 | break; | ||
2036 | case CONEXANT_MIC_EVENT: | ||
2037 | cxt5066_automic(codec); | ||
2038 | break; | ||
2039 | } | ||
2040 | } | ||
2041 | |||
2042 | static const struct hda_input_mux cxt5066_analog_mic_boost = { | ||
2043 | .num_items = 5, | ||
2044 | .items = { | ||
2045 | { "0dB", 0 }, | ||
2046 | { "10dB", 1 }, | ||
2047 | { "20dB", 2 }, | ||
2048 | { "30dB", 3 }, | ||
2049 | { "40dB", 4 }, | ||
2050 | }, | ||
2051 | }; | ||
2052 | |||
2053 | static int cxt5066_mic_boost_mux_enum_info(struct snd_kcontrol *kcontrol, | ||
2054 | struct snd_ctl_elem_info *uinfo) | ||
2055 | { | ||
2056 | return snd_hda_input_mux_info(&cxt5066_analog_mic_boost, uinfo); | ||
2057 | } | ||
2058 | |||
2059 | static int cxt5066_mic_boost_mux_enum_get(struct snd_kcontrol *kcontrol, | ||
2060 | struct snd_ctl_elem_value *ucontrol) | ||
2061 | { | ||
2062 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
2063 | int val; | ||
2064 | |||
2065 | val = snd_hda_codec_read(codec, 0x17, 0, | ||
2066 | AC_VERB_GET_AMP_GAIN_MUTE, AC_AMP_GET_OUTPUT); | ||
2067 | |||
2068 | ucontrol->value.enumerated.item[0] = val & AC_AMP_GAIN; | ||
2069 | return 0; | ||
2070 | } | ||
2071 | |||
2072 | static int cxt5066_mic_boost_mux_enum_put(struct snd_kcontrol *kcontrol, | ||
2073 | struct snd_ctl_elem_value *ucontrol) | ||
2074 | { | ||
2075 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
2076 | const struct hda_input_mux *imux = &cxt5066_analog_mic_boost; | ||
2077 | unsigned int idx; | ||
2078 | |||
2079 | if (!imux->num_items) | ||
2080 | return 0; | ||
2081 | idx = ucontrol->value.enumerated.item[0]; | ||
2082 | if (idx >= imux->num_items) | ||
2083 | idx = imux->num_items - 1; | ||
2084 | |||
2085 | snd_hda_codec_write_cache(codec, 0x17, 0, | ||
2086 | AC_VERB_SET_AMP_GAIN_MUTE, | ||
2087 | AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | AC_AMP_SET_OUTPUT | | ||
2088 | imux->items[idx].index); | ||
2089 | |||
2090 | return 1; | ||
2091 | } | ||
2092 | |||
2093 | static struct hda_input_mux cxt5066_capture_source = { | ||
2094 | .num_items = 4, | ||
2095 | .items = { | ||
2096 | { "Mic B", 0 }, | ||
2097 | { "Mic C", 1 }, | ||
2098 | { "Mic E", 2 }, | ||
2099 | { "Mic F", 3 }, | ||
2100 | }, | ||
2101 | }; | ||
2102 | |||
2103 | static struct hda_bind_ctls cxt5066_bind_capture_vol_others = { | ||
2104 | .ops = &snd_hda_bind_vol, | ||
2105 | .values = { | ||
2106 | HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_INPUT), | ||
2107 | HDA_COMPOSE_AMP_VAL(0x14, 3, 2, HDA_INPUT), | ||
2108 | 0 | ||
2109 | }, | ||
2110 | }; | ||
2111 | |||
2112 | static struct hda_bind_ctls cxt5066_bind_capture_sw_others = { | ||
2113 | .ops = &snd_hda_bind_sw, | ||
2114 | .values = { | ||
2115 | HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_INPUT), | ||
2116 | HDA_COMPOSE_AMP_VAL(0x14, 3, 2, HDA_INPUT), | ||
2117 | 0 | ||
2118 | }, | ||
2119 | }; | ||
2120 | |||
2121 | static struct snd_kcontrol_new cxt5066_mixer_master[] = { | ||
2122 | HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT), | ||
2123 | {} | ||
2124 | }; | ||
2125 | |||
2126 | static struct snd_kcontrol_new cxt5066_mixer_master_olpc[] = { | ||
2127 | { | ||
2128 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
2129 | .name = "Master Playback Volume", | ||
2130 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | | ||
2131 | SNDRV_CTL_ELEM_ACCESS_TLV_READ | | ||
2132 | SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK, | ||
2133 | .info = snd_hda_mixer_amp_volume_info, | ||
2134 | .get = snd_hda_mixer_amp_volume_get, | ||
2135 | .put = snd_hda_mixer_amp_volume_put, | ||
2136 | .tlv = { .c = snd_hda_mixer_amp_tlv }, | ||
2137 | /* offset by 28 volume steps to limit minimum gain to -46dB */ | ||
2138 | .private_value = | ||
2139 | HDA_COMPOSE_AMP_VAL_OFS(0x10, 3, 0, HDA_OUTPUT, 28), | ||
2140 | }, | ||
2141 | {} | ||
2142 | }; | ||
2143 | |||
2144 | static struct snd_kcontrol_new cxt5066_mixers[] = { | ||
2145 | { | ||
2146 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
2147 | .name = "Master Playback Switch", | ||
2148 | .info = cxt_eapd_info, | ||
2149 | .get = cxt_eapd_get, | ||
2150 | .put = cxt5066_hp_master_sw_put, | ||
2151 | .private_value = 0x1d, | ||
2152 | }, | ||
2153 | |||
2154 | { | ||
2155 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
2156 | .name = "Analog Mic Boost Capture Enum", | ||
2157 | .info = cxt5066_mic_boost_mux_enum_info, | ||
2158 | .get = cxt5066_mic_boost_mux_enum_get, | ||
2159 | .put = cxt5066_mic_boost_mux_enum_put, | ||
2160 | }, | ||
2161 | |||
2162 | HDA_BIND_VOL("Capture Volume", &cxt5066_bind_capture_vol_others), | ||
2163 | HDA_BIND_SW("Capture Switch", &cxt5066_bind_capture_sw_others), | ||
2164 | {} | ||
2165 | }; | ||
2166 | |||
2167 | static struct hda_verb cxt5066_init_verbs[] = { | ||
2168 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port B */ | ||
2169 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port C */ | ||
2170 | {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port F */ | ||
2171 | {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port E */ | ||
2172 | |||
2173 | /* Speakers */ | ||
2174 | {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
2175 | {0x1f, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */ | ||
2176 | |||
2177 | /* HP, Amp */ | ||
2178 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
2179 | {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */ | ||
2180 | |||
2181 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
2182 | {0x1c, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */ | ||
2183 | |||
2184 | /* DAC1 */ | ||
2185 | {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
2186 | |||
2187 | /* Node 14 connections: 0x17 0x18 0x23 0x24 0x27 */ | ||
2188 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x50}, | ||
2189 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
2190 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2) | 0x50}, | ||
2191 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | ||
2192 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, | ||
2193 | |||
2194 | /* no digital microphone support yet */ | ||
2195 | {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
2196 | |||
2197 | /* Audio input selector */ | ||
2198 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x3}, | ||
2199 | |||
2200 | /* SPDIF route: PCM */ | ||
2201 | {0x20, AC_VERB_SET_CONNECT_SEL, 0x0}, | ||
2202 | {0x22, AC_VERB_SET_CONNECT_SEL, 0x0}, | ||
2203 | |||
2204 | {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
2205 | {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
2206 | |||
2207 | /* EAPD */ | ||
2208 | {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ | ||
2209 | |||
2210 | /* not handling these yet */ | ||
2211 | {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, 0}, | ||
2212 | {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, 0}, | ||
2213 | {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, 0}, | ||
2214 | {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, 0}, | ||
2215 | {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE, 0}, | ||
2216 | {0x1e, AC_VERB_SET_UNSOLICITED_ENABLE, 0}, | ||
2217 | {0x20, AC_VERB_SET_UNSOLICITED_ENABLE, 0}, | ||
2218 | {0x22, AC_VERB_SET_UNSOLICITED_ENABLE, 0}, | ||
2219 | { } /* end */ | ||
2220 | }; | ||
2221 | |||
2222 | static struct hda_verb cxt5066_init_verbs_olpc[] = { | ||
2223 | /* Port A: headphones */ | ||
2224 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
2225 | {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */ | ||
2226 | |||
2227 | /* Port B: external microphone */ | ||
2228 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
2229 | |||
2230 | /* Port C: internal microphone */ | ||
2231 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
2232 | |||
2233 | /* Port D: unused */ | ||
2234 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
2235 | |||
2236 | /* Port E: unused, but has primary EAPD */ | ||
2237 | {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
2238 | {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ | ||
2239 | |||
2240 | /* Port F: unused */ | ||
2241 | {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
2242 | |||
2243 | /* Port G: internal speakers */ | ||
2244 | {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
2245 | {0x1f, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */ | ||
2246 | |||
2247 | /* DAC1 */ | ||
2248 | {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
2249 | |||
2250 | /* DAC2: unused */ | ||
2251 | {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
2252 | |||
2253 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x50}, | ||
2254 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
2255 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | ||
2256 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | ||
2257 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
2258 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
2259 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | ||
2260 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | ||
2261 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
2262 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
2263 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | ||
2264 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | ||
2265 | |||
2266 | /* Disable digital microphone port */ | ||
2267 | {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
2268 | |||
2269 | /* Audio input selectors */ | ||
2270 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x3}, | ||
2271 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, | ||
2272 | |||
2273 | /* Disable SPDIF */ | ||
2274 | {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
2275 | {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
2276 | |||
2277 | /* enable unsolicited events for Port A and B */ | ||
2278 | {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT}, | ||
2279 | {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT}, | ||
2280 | { } /* end */ | ||
2281 | }; | ||
2282 | |||
2283 | static struct hda_verb cxt5066_init_verbs_portd_lo[] = { | ||
2284 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
2285 | { } /* end */ | ||
2286 | }; | ||
2287 | |||
2288 | /* initialize jack-sensing, too */ | ||
2289 | static int cxt5066_init(struct hda_codec *codec) | ||
2290 | { | ||
2291 | snd_printdd("CXT5066: init\n"); | ||
2292 | conexant_init(codec); | ||
2293 | if (codec->patch_ops.unsol_event) { | ||
2294 | cxt5066_hp_automute(codec); | ||
2295 | cxt5066_automic(codec); | ||
2296 | } | ||
2297 | return 0; | ||
2298 | } | ||
2299 | |||
2300 | enum { | ||
2301 | CXT5066_LAPTOP, /* Laptops w/ EAPD support */ | ||
2302 | CXT5066_DELL_LAPTOP, /* Dell Laptop */ | ||
2303 | CXT5066_OLPC_XO_1_5, /* OLPC XO 1.5 */ | ||
2304 | CXT5066_MODELS | ||
2305 | }; | ||
2306 | |||
2307 | static const char *cxt5066_models[CXT5066_MODELS] = { | ||
2308 | [CXT5066_LAPTOP] = "laptop", | ||
2309 | [CXT5066_DELL_LAPTOP] = "dell-laptop", | ||
2310 | [CXT5066_OLPC_XO_1_5] = "olpc-xo-1_5", | ||
2311 | }; | ||
2312 | |||
2313 | static struct snd_pci_quirk cxt5066_cfg_tbl[] = { | ||
2314 | SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board", | ||
2315 | CXT5066_LAPTOP), | ||
2316 | SND_PCI_QUIRK(0x1028, 0x02f5, "Dell", | ||
2317 | CXT5066_DELL_LAPTOP), | ||
2318 | {} | ||
2319 | }; | ||
2320 | |||
2321 | static int patch_cxt5066(struct hda_codec *codec) | ||
2322 | { | ||
2323 | struct conexant_spec *spec; | ||
2324 | int board_config; | ||
2325 | |||
2326 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | ||
2327 | if (!spec) | ||
2328 | return -ENOMEM; | ||
2329 | codec->spec = spec; | ||
2330 | |||
2331 | codec->patch_ops = conexant_patch_ops; | ||
2332 | codec->patch_ops.init = cxt5066_init; | ||
2333 | |||
2334 | spec->dell_automute = 0; | ||
2335 | spec->multiout.max_channels = 2; | ||
2336 | spec->multiout.num_dacs = ARRAY_SIZE(cxt5066_dac_nids); | ||
2337 | spec->multiout.dac_nids = cxt5066_dac_nids; | ||
2338 | spec->multiout.dig_out_nid = CXT5066_SPDIF_OUT; | ||
2339 | spec->num_adc_nids = 1; | ||
2340 | spec->adc_nids = cxt5066_adc_nids; | ||
2341 | spec->capsrc_nids = cxt5066_capsrc_nids; | ||
2342 | spec->input_mux = &cxt5066_capture_source; | ||
2343 | |||
2344 | spec->port_d_mode = PIN_HP; | ||
2345 | |||
2346 | spec->num_init_verbs = 1; | ||
2347 | spec->init_verbs[0] = cxt5066_init_verbs; | ||
2348 | spec->num_channel_mode = ARRAY_SIZE(cxt5066_modes); | ||
2349 | spec->channel_mode = cxt5066_modes; | ||
2350 | spec->cur_adc = 0; | ||
2351 | spec->cur_adc_idx = 0; | ||
2352 | |||
2353 | board_config = snd_hda_check_board_config(codec, CXT5066_MODELS, | ||
2354 | cxt5066_models, cxt5066_cfg_tbl); | ||
2355 | switch (board_config) { | ||
2356 | default: | ||
2357 | case CXT5066_LAPTOP: | ||
2358 | spec->mixers[spec->num_mixers++] = cxt5066_mixer_master; | ||
2359 | spec->mixers[spec->num_mixers++] = cxt5066_mixers; | ||
2360 | break; | ||
2361 | case CXT5066_DELL_LAPTOP: | ||
2362 | spec->mixers[spec->num_mixers++] = cxt5066_mixer_master; | ||
2363 | spec->mixers[spec->num_mixers++] = cxt5066_mixers; | ||
2364 | |||
2365 | spec->port_d_mode = PIN_OUT; | ||
2366 | spec->init_verbs[spec->num_init_verbs] = cxt5066_init_verbs_portd_lo; | ||
2367 | spec->num_init_verbs++; | ||
2368 | spec->dell_automute = 1; | ||
2369 | break; | ||
2370 | case CXT5066_OLPC_XO_1_5: | ||
2371 | codec->patch_ops.unsol_event = cxt5066_unsol_event; | ||
2372 | spec->init_verbs[0] = cxt5066_init_verbs_olpc; | ||
2373 | spec->mixers[spec->num_mixers++] = cxt5066_mixer_master_olpc; | ||
2374 | spec->mixers[spec->num_mixers++] = cxt5066_mixers; | ||
2375 | spec->port_d_mode = 0; | ||
2376 | |||
2377 | /* no S/PDIF out */ | ||
2378 | spec->multiout.dig_out_nid = 0; | ||
2379 | |||
2380 | /* input source automatically selected */ | ||
2381 | spec->input_mux = NULL; | ||
2382 | break; | ||
2383 | } | ||
2384 | |||
2385 | return 0; | ||
2386 | } | ||
1911 | 2387 | ||
1912 | /* | 2388 | /* |
1913 | */ | 2389 | */ |
@@ -1919,12 +2395,15 @@ static struct hda_codec_preset snd_hda_preset_conexant[] = { | |||
1919 | .patch = patch_cxt5047 }, | 2395 | .patch = patch_cxt5047 }, |
1920 | { .id = 0x14f15051, .name = "CX20561 (Hermosa)", | 2396 | { .id = 0x14f15051, .name = "CX20561 (Hermosa)", |
1921 | .patch = patch_cxt5051 }, | 2397 | .patch = patch_cxt5051 }, |
2398 | { .id = 0x14f15066, .name = "CX20582 (Pebble)", | ||
2399 | .patch = patch_cxt5066 }, | ||
1922 | {} /* terminator */ | 2400 | {} /* terminator */ |
1923 | }; | 2401 | }; |
1924 | 2402 | ||
1925 | MODULE_ALIAS("snd-hda-codec-id:14f15045"); | 2403 | MODULE_ALIAS("snd-hda-codec-id:14f15045"); |
1926 | MODULE_ALIAS("snd-hda-codec-id:14f15047"); | 2404 | MODULE_ALIAS("snd-hda-codec-id:14f15047"); |
1927 | MODULE_ALIAS("snd-hda-codec-id:14f15051"); | 2405 | MODULE_ALIAS("snd-hda-codec-id:14f15051"); |
2406 | MODULE_ALIAS("snd-hda-codec-id:14f15066"); | ||
1928 | 2407 | ||
1929 | MODULE_LICENSE("GPL"); | 2408 | MODULE_LICENSE("GPL"); |
1930 | MODULE_DESCRIPTION("Conexant HD-audio codec"); | 2409 | MODULE_DESCRIPTION("Conexant HD-audio codec"); |
diff --git a/sound/pci/hda/patch_intelhdmi.c b/sound/pci/hda/patch_intelhdmi.c index fcc77fec4487..032850eba369 100644 --- a/sound/pci/hda/patch_intelhdmi.c +++ b/sound/pci/hda/patch_intelhdmi.c | |||
@@ -685,6 +685,7 @@ static struct hda_codec_preset snd_hda_preset_intelhdmi[] = { | |||
685 | { .id = 0x80862802, .name = "G45 DEVCTG", .patch = patch_intel_hdmi }, | 685 | { .id = 0x80862802, .name = "G45 DEVCTG", .patch = patch_intel_hdmi }, |
686 | { .id = 0x80862803, .name = "G45 DEVELK", .patch = patch_intel_hdmi }, | 686 | { .id = 0x80862803, .name = "G45 DEVELK", .patch = patch_intel_hdmi }, |
687 | { .id = 0x80862804, .name = "G45 DEVIBX", .patch = patch_intel_hdmi }, | 687 | { .id = 0x80862804, .name = "G45 DEVIBX", .patch = patch_intel_hdmi }, |
688 | { .id = 0x80860054, .name = "G45 DEVIBX", .patch = patch_intel_hdmi }, | ||
688 | { .id = 0x10951392, .name = "SiI1392 HDMI", .patch = patch_intel_hdmi }, | 689 | { .id = 0x10951392, .name = "SiI1392 HDMI", .patch = patch_intel_hdmi }, |
689 | {} /* terminator */ | 690 | {} /* terminator */ |
690 | }; | 691 | }; |
@@ -694,6 +695,7 @@ MODULE_ALIAS("snd-hda-codec-id:80862801"); | |||
694 | MODULE_ALIAS("snd-hda-codec-id:80862802"); | 695 | MODULE_ALIAS("snd-hda-codec-id:80862802"); |
695 | MODULE_ALIAS("snd-hda-codec-id:80862803"); | 696 | MODULE_ALIAS("snd-hda-codec-id:80862803"); |
696 | MODULE_ALIAS("snd-hda-codec-id:80862804"); | 697 | MODULE_ALIAS("snd-hda-codec-id:80862804"); |
698 | MODULE_ALIAS("snd-hda-codec-id:80860054"); | ||
697 | MODULE_ALIAS("snd-hda-codec-id:10951392"); | 699 | MODULE_ALIAS("snd-hda-codec-id:10951392"); |
698 | 700 | ||
699 | MODULE_LICENSE("GPL"); | 701 | MODULE_LICENSE("GPL"); |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 0f6b6a6f72e3..587d94f869be 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -235,6 +235,8 @@ enum { | |||
235 | ALC883_FUJITSU_PI2515, | 235 | ALC883_FUJITSU_PI2515, |
236 | ALC888_FUJITSU_XA3530, | 236 | ALC888_FUJITSU_XA3530, |
237 | ALC883_3ST_6ch_INTEL, | 237 | ALC883_3ST_6ch_INTEL, |
238 | ALC889A_INTEL, | ||
239 | ALC889_INTEL, | ||
238 | ALC888_ASUS_M90V, | 240 | ALC888_ASUS_M90V, |
239 | ALC888_ASUS_EEE1601, | 241 | ALC888_ASUS_EEE1601, |
240 | ALC889A_MB31, | 242 | ALC889A_MB31, |
@@ -413,7 +415,7 @@ static int alc_mux_enum_put(struct snd_kcontrol *kcontrol, | |||
413 | mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx; | 415 | mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx; |
414 | imux = &spec->input_mux[mux_idx]; | 416 | imux = &spec->input_mux[mux_idx]; |
415 | 417 | ||
416 | type = (get_wcaps(codec, nid) & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; | 418 | type = get_wcaps_type(get_wcaps(codec, nid)); |
417 | if (type == AC_WID_AUD_MIX) { | 419 | if (type == AC_WID_AUD_MIX) { |
418 | /* Matrix-mixer style (e.g. ALC882) */ | 420 | /* Matrix-mixer style (e.g. ALC882) */ |
419 | unsigned int *cur_val = &spec->cur_mux[adc_idx]; | 421 | unsigned int *cur_val = &spec->cur_mux[adc_idx]; |
@@ -1027,6 +1029,16 @@ static void alc888_coef_init(struct hda_codec *codec) | |||
1027 | AC_VERB_SET_PROC_COEF, 0x3030); | 1029 | AC_VERB_SET_PROC_COEF, 0x3030); |
1028 | } | 1030 | } |
1029 | 1031 | ||
1032 | static void alc889_coef_init(struct hda_codec *codec) | ||
1033 | { | ||
1034 | unsigned int tmp; | ||
1035 | |||
1036 | snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7); | ||
1037 | tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); | ||
1038 | snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7); | ||
1039 | snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010); | ||
1040 | } | ||
1041 | |||
1030 | static void alc_auto_init_amp(struct hda_codec *codec, int type) | 1042 | static void alc_auto_init_amp(struct hda_codec *codec, int type) |
1031 | { | 1043 | { |
1032 | unsigned int tmp; | 1044 | unsigned int tmp; |
@@ -1084,15 +1096,7 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type) | |||
1084 | case 0x10ec0885: | 1096 | case 0x10ec0885: |
1085 | case 0x10ec0887: | 1097 | case 0x10ec0887: |
1086 | case 0x10ec0889: | 1098 | case 0x10ec0889: |
1087 | snd_hda_codec_write(codec, 0x20, 0, | 1099 | alc889_coef_init(codec); |
1088 | AC_VERB_SET_COEF_INDEX, 7); | ||
1089 | tmp = snd_hda_codec_read(codec, 0x20, 0, | ||
1090 | AC_VERB_GET_PROC_COEF, 0); | ||
1091 | snd_hda_codec_write(codec, 0x20, 0, | ||
1092 | AC_VERB_SET_COEF_INDEX, 7); | ||
1093 | snd_hda_codec_write(codec, 0x20, 0, | ||
1094 | AC_VERB_SET_PROC_COEF, | ||
1095 | tmp | 0x2010); | ||
1096 | break; | 1100 | break; |
1097 | case 0x10ec0888: | 1101 | case 0x10ec0888: |
1098 | alc888_coef_init(codec); | 1102 | alc888_coef_init(codec); |
@@ -1432,6 +1436,25 @@ static void alc_automute_amp_unsol_event(struct hda_codec *codec, | |||
1432 | alc_automute_amp(codec); | 1436 | alc_automute_amp(codec); |
1433 | } | 1437 | } |
1434 | 1438 | ||
1439 | static void alc889_automute_init(struct hda_codec *codec) | ||
1440 | { | ||
1441 | struct alc_spec *spec = codec->spec; | ||
1442 | |||
1443 | spec->autocfg.hp_pins[0] = 0x15; | ||
1444 | spec->autocfg.speaker_pins[0] = 0x14; | ||
1445 | spec->autocfg.speaker_pins[1] = 0x16; | ||
1446 | spec->autocfg.speaker_pins[2] = 0x17; | ||
1447 | spec->autocfg.speaker_pins[3] = 0x19; | ||
1448 | spec->autocfg.speaker_pins[4] = 0x1a; | ||
1449 | alc_automute_amp(codec); | ||
1450 | } | ||
1451 | |||
1452 | static void alc889_intel_init_hook(struct hda_codec *codec) | ||
1453 | { | ||
1454 | alc889_coef_init(codec); | ||
1455 | alc889_automute_init(codec); | ||
1456 | } | ||
1457 | |||
1435 | static void alc888_fujitsu_xa3530_init_hook(struct hda_codec *codec) | 1458 | static void alc888_fujitsu_xa3530_init_hook(struct hda_codec *codec) |
1436 | { | 1459 | { |
1437 | struct alc_spec *spec = codec->spec; | 1460 | struct alc_spec *spec = codec->spec; |
@@ -4580,8 +4603,8 @@ static int patch_alc880(struct hda_codec *codec) | |||
4580 | alc880_models, | 4603 | alc880_models, |
4581 | alc880_cfg_tbl); | 4604 | alc880_cfg_tbl); |
4582 | if (board_config < 0) { | 4605 | if (board_config < 0) { |
4583 | printk(KERN_INFO "hda_codec: Unknown model for %s, " | 4606 | printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", |
4584 | "trying auto-probe from BIOS...\n", codec->chip_name); | 4607 | codec->chip_name); |
4585 | board_config = ALC880_AUTO; | 4608 | board_config = ALC880_AUTO; |
4586 | } | 4609 | } |
4587 | 4610 | ||
@@ -4619,7 +4642,7 @@ static int patch_alc880(struct hda_codec *codec) | |||
4619 | /* check whether NID 0x07 is valid */ | 4642 | /* check whether NID 0x07 is valid */ |
4620 | unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]); | 4643 | unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]); |
4621 | /* get type */ | 4644 | /* get type */ |
4622 | wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; | 4645 | wcap = get_wcaps_type(wcap); |
4623 | if (wcap != AC_WID_AUD_IN) { | 4646 | if (wcap != AC_WID_AUD_IN) { |
4624 | spec->adc_nids = alc880_adc_nids_alt; | 4647 | spec->adc_nids = alc880_adc_nids_alt; |
4625 | spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt); | 4648 | spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt); |
@@ -6224,8 +6247,7 @@ static int patch_alc260(struct hda_codec *codec) | |||
6224 | alc260_models, | 6247 | alc260_models, |
6225 | alc260_cfg_tbl); | 6248 | alc260_cfg_tbl); |
6226 | if (board_config < 0) { | 6249 | if (board_config < 0) { |
6227 | snd_printd(KERN_INFO "hda_codec: Unknown model for %s, " | 6250 | snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", |
6228 | "trying auto-probe from BIOS...\n", | ||
6229 | codec->chip_name); | 6251 | codec->chip_name); |
6230 | board_config = ALC260_AUTO; | 6252 | board_config = ALC260_AUTO; |
6231 | } | 6253 | } |
@@ -6262,7 +6284,7 @@ static int patch_alc260(struct hda_codec *codec) | |||
6262 | if (!spec->adc_nids && spec->input_mux) { | 6284 | if (!spec->adc_nids && spec->input_mux) { |
6263 | /* check whether NID 0x04 is valid */ | 6285 | /* check whether NID 0x04 is valid */ |
6264 | unsigned int wcap = get_wcaps(codec, 0x04); | 6286 | unsigned int wcap = get_wcaps(codec, 0x04); |
6265 | wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; | 6287 | wcap = get_wcaps_type(wcap); |
6266 | /* get type */ | 6288 | /* get type */ |
6267 | if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) { | 6289 | if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) { |
6268 | spec->adc_nids = alc260_adc_nids_alt; | 6290 | spec->adc_nids = alc260_adc_nids_alt; |
@@ -6348,6 +6370,15 @@ static struct hda_input_mux alc882_capture_source = { | |||
6348 | 6370 | ||
6349 | #define alc883_capture_source alc882_capture_source | 6371 | #define alc883_capture_source alc882_capture_source |
6350 | 6372 | ||
6373 | static struct hda_input_mux alc889_capture_source = { | ||
6374 | .num_items = 3, | ||
6375 | .items = { | ||
6376 | { "Front Mic", 0x0 }, | ||
6377 | { "Mic", 0x3 }, | ||
6378 | { "Line", 0x2 }, | ||
6379 | }, | ||
6380 | }; | ||
6381 | |||
6351 | static struct hda_input_mux mb5_capture_source = { | 6382 | static struct hda_input_mux mb5_capture_source = { |
6352 | .num_items = 3, | 6383 | .num_items = 3, |
6353 | .items = { | 6384 | .items = { |
@@ -6669,6 +6700,52 @@ static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = { | |||
6669 | }; | 6700 | }; |
6670 | 6701 | ||
6671 | /* | 6702 | /* |
6703 | * 2ch mode | ||
6704 | */ | ||
6705 | static struct hda_verb alc889_ch2_intel_init[] = { | ||
6706 | { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 }, | ||
6707 | { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 }, | ||
6708 | { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 }, | ||
6709 | { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 }, | ||
6710 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, | ||
6711 | { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, | ||
6712 | { } /* end */ | ||
6713 | }; | ||
6714 | |||
6715 | /* | ||
6716 | * 6ch mode | ||
6717 | */ | ||
6718 | static struct hda_verb alc889_ch6_intel_init[] = { | ||
6719 | { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 }, | ||
6720 | { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 }, | ||
6721 | { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 }, | ||
6722 | { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 }, | ||
6723 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, | ||
6724 | { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, | ||
6725 | { } /* end */ | ||
6726 | }; | ||
6727 | |||
6728 | /* | ||
6729 | * 8ch mode | ||
6730 | */ | ||
6731 | static struct hda_verb alc889_ch8_intel_init[] = { | ||
6732 | { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 }, | ||
6733 | { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 }, | ||
6734 | { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 }, | ||
6735 | { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 }, | ||
6736 | { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 }, | ||
6737 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
6738 | { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | ||
6739 | { } /* end */ | ||
6740 | }; | ||
6741 | |||
6742 | static struct hda_channel_mode alc889_8ch_intel_modes[3] = { | ||
6743 | { 2, alc889_ch2_intel_init }, | ||
6744 | { 6, alc889_ch6_intel_init }, | ||
6745 | { 8, alc889_ch8_intel_init }, | ||
6746 | }; | ||
6747 | |||
6748 | /* | ||
6672 | * 6ch mode | 6749 | * 6ch mode |
6673 | */ | 6750 | */ |
6674 | static struct hda_verb alc883_sixstack_ch6_init[] = { | 6751 | static struct hda_verb alc883_sixstack_ch6_init[] = { |
@@ -6849,6 +6926,13 @@ static struct hda_verb alc882_base_init_verbs[] = { | |||
6849 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | 6926 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, |
6850 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | 6927 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, |
6851 | 6928 | ||
6929 | /* mute analog input loopbacks */ | ||
6930 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
6931 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
6932 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | ||
6933 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | ||
6934 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, | ||
6935 | |||
6852 | /* Front Pin: output 0 (0x0c) */ | 6936 | /* Front Pin: output 0 (0x0c) */ |
6853 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | 6937 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, |
6854 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 6938 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
@@ -6915,9 +6999,6 @@ static struct hda_verb alc882_adc1_init_verbs[] = { | |||
6915 | { } | 6999 | { } |
6916 | }; | 7000 | }; |
6917 | 7001 | ||
6918 | /* HACK - expand to two elements */ | ||
6919 | #define alc882_init_verbs alc882_base_init_verbs, alc882_adc1_init_verbs | ||
6920 | |||
6921 | static struct hda_verb alc882_eapd_verbs[] = { | 7002 | static struct hda_verb alc882_eapd_verbs[] = { |
6922 | /* change to EAPD mode */ | 7003 | /* change to EAPD mode */ |
6923 | {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, | 7004 | {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, |
@@ -6925,6 +7006,108 @@ static struct hda_verb alc882_eapd_verbs[] = { | |||
6925 | { } | 7006 | { } |
6926 | }; | 7007 | }; |
6927 | 7008 | ||
7009 | static struct hda_verb alc889_eapd_verbs[] = { | ||
7010 | {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, | ||
7011 | {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, | ||
7012 | { } | ||
7013 | }; | ||
7014 | |||
7015 | static struct hda_verb alc_hp15_unsol_verbs[] = { | ||
7016 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, | ||
7017 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
7018 | {} | ||
7019 | }; | ||
7020 | |||
7021 | static struct hda_verb alc885_init_verbs[] = { | ||
7022 | /* Front mixer: unmute input/output amp left and right (volume = 0) */ | ||
7023 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
7024 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
7025 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
7026 | /* Rear mixer */ | ||
7027 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
7028 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
7029 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
7030 | /* CLFE mixer */ | ||
7031 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
7032 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
7033 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
7034 | /* Side mixer */ | ||
7035 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
7036 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
7037 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
7038 | |||
7039 | /* mute analog input loopbacks */ | ||
7040 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
7041 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | ||
7042 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | ||
7043 | |||
7044 | /* Front HP Pin: output 0 (0x0c) */ | ||
7045 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
7046 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
7047 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
7048 | /* Front Pin: output 0 (0x0c) */ | ||
7049 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
7050 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
7051 | {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
7052 | /* Rear Pin: output 1 (0x0d) */ | ||
7053 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
7054 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
7055 | {0x19, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
7056 | /* CLFE Pin: output 2 (0x0e) */ | ||
7057 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
7058 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
7059 | {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, | ||
7060 | /* Side Pin: output 3 (0x0f) */ | ||
7061 | {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
7062 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
7063 | {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, | ||
7064 | /* Mic (rear) pin: input vref at 80% */ | ||
7065 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
7066 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
7067 | /* Front Mic pin: input vref at 80% */ | ||
7068 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
7069 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
7070 | /* Line In pin: input */ | ||
7071 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
7072 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
7073 | |||
7074 | /* Mixer elements: 0x18, , 0x1a, 0x1b */ | ||
7075 | /* Input mixer1 */ | ||
7076 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, | ||
7077 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
7078 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | ||
7079 | /* Input mixer2 */ | ||
7080 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
7081 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | ||
7082 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | ||
7083 | /* Input mixer3 */ | ||
7084 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | ||
7085 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
7086 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | ||
7087 | /* ADC2: mute amp left and right */ | ||
7088 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
7089 | /* ADC3: mute amp left and right */ | ||
7090 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
7091 | |||
7092 | { } | ||
7093 | }; | ||
7094 | |||
7095 | static struct hda_verb alc885_init_input_verbs[] = { | ||
7096 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
7097 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | ||
7098 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, | ||
7099 | { } | ||
7100 | }; | ||
7101 | |||
7102 | |||
7103 | /* Unmute Selector 24h and set the default input to front mic */ | ||
7104 | static struct hda_verb alc889_init_input_verbs[] = { | ||
7105 | {0x24, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
7106 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
7107 | { } | ||
7108 | }; | ||
7109 | |||
7110 | |||
6928 | #define alc883_init_verbs alc882_base_init_verbs | 7111 | #define alc883_init_verbs alc882_base_init_verbs |
6929 | 7112 | ||
6930 | /* Mac Pro test */ | 7113 | /* Mac Pro test */ |
@@ -7162,9 +7345,6 @@ static struct hda_verb alc882_targa_verbs[] = { | |||
7162 | {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ | 7345 | {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ |
7163 | 7346 | ||
7164 | {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, | 7347 | {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, |
7165 | {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, | ||
7166 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03}, | ||
7167 | {0x01, AC_VERB_SET_GPIO_DATA, 0x03}, | ||
7168 | { } /* end */ | 7348 | { } /* end */ |
7169 | }; | 7349 | }; |
7170 | 7350 | ||
@@ -7496,6 +7676,30 @@ static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = { | |||
7496 | { } /* end */ | 7676 | { } /* end */ |
7497 | }; | 7677 | }; |
7498 | 7678 | ||
7679 | static struct snd_kcontrol_new alc885_8ch_intel_mixer[] = { | ||
7680 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
7681 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | ||
7682 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | ||
7683 | HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), | ||
7684 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, | ||
7685 | HDA_OUTPUT), | ||
7686 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), | ||
7687 | HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), | ||
7688 | HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), | ||
7689 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT), | ||
7690 | HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT), | ||
7691 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), | ||
7692 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
7693 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
7694 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT), | ||
7695 | HDA_CODEC_VOLUME("Mic Boost", 0x1b, 0, HDA_INPUT), | ||
7696 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT), | ||
7697 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
7698 | HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT), | ||
7699 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
7700 | { } /* end */ | ||
7701 | }; | ||
7702 | |||
7499 | static struct snd_kcontrol_new alc883_fivestack_mixer[] = { | 7703 | static struct snd_kcontrol_new alc883_fivestack_mixer[] = { |
7500 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 7704 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
7501 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | 7705 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), |
@@ -8339,6 +8543,8 @@ static const char *alc882_models[ALC882_MODEL_LAST] = { | |||
8339 | [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515", | 8543 | [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515", |
8340 | [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530", | 8544 | [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530", |
8341 | [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel", | 8545 | [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel", |
8546 | [ALC889A_INTEL] = "intel-alc889a", | ||
8547 | [ALC889_INTEL] = "intel-x58", | ||
8342 | [ALC1200_ASUS_P5Q] = "asus-p5q", | 8548 | [ALC1200_ASUS_P5Q] = "asus-p5q", |
8343 | [ALC889A_MB31] = "mb31", | 8549 | [ALC889A_MB31] = "mb31", |
8344 | [ALC883_SONY_VAIO_TT] = "sony-vaio-tt", | 8550 | [ALC883_SONY_VAIO_TT] = "sony-vaio-tt", |
@@ -8418,6 +8624,7 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = { | |||
8418 | SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG), | 8624 | SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG), |
8419 | SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG), | 8625 | SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG), |
8420 | SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG), | 8626 | SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG), |
8627 | SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG), | ||
8421 | SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG), | 8628 | SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG), |
8422 | SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG), | 8629 | SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG), |
8423 | SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG), | 8630 | SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG), |
@@ -8431,6 +8638,7 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = { | |||
8431 | SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG), | 8638 | SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG), |
8432 | SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG), | 8639 | SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG), |
8433 | SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG), | 8640 | SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG), |
8641 | SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG), | ||
8434 | 8642 | ||
8435 | SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG), | 8643 | SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG), |
8436 | SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720), | 8644 | SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720), |
@@ -8456,7 +8664,9 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = { | |||
8456 | SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL), | 8664 | SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL), |
8457 | SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL), | 8665 | SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL), |
8458 | SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC), | 8666 | SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC), |
8459 | SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC883_3ST_6ch_INTEL), | 8667 | SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL), |
8668 | SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL), | ||
8669 | SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL), | ||
8460 | SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch), | 8670 | SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch), |
8461 | 8671 | ||
8462 | {} | 8672 | {} |
@@ -8485,7 +8695,8 @@ static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = { | |||
8485 | static struct alc_config_preset alc882_presets[] = { | 8695 | static struct alc_config_preset alc882_presets[] = { |
8486 | [ALC882_3ST_DIG] = { | 8696 | [ALC882_3ST_DIG] = { |
8487 | .mixers = { alc882_base_mixer }, | 8697 | .mixers = { alc882_base_mixer }, |
8488 | .init_verbs = { alc882_init_verbs }, | 8698 | .init_verbs = { alc882_base_init_verbs, |
8699 | alc882_adc1_init_verbs }, | ||
8489 | .num_dacs = ARRAY_SIZE(alc882_dac_nids), | 8700 | .num_dacs = ARRAY_SIZE(alc882_dac_nids), |
8490 | .dac_nids = alc882_dac_nids, | 8701 | .dac_nids = alc882_dac_nids, |
8491 | .dig_out_nid = ALC882_DIGOUT_NID, | 8702 | .dig_out_nid = ALC882_DIGOUT_NID, |
@@ -8497,7 +8708,8 @@ static struct alc_config_preset alc882_presets[] = { | |||
8497 | }, | 8708 | }, |
8498 | [ALC882_6ST_DIG] = { | 8709 | [ALC882_6ST_DIG] = { |
8499 | .mixers = { alc882_base_mixer, alc882_chmode_mixer }, | 8710 | .mixers = { alc882_base_mixer, alc882_chmode_mixer }, |
8500 | .init_verbs = { alc882_init_verbs }, | 8711 | .init_verbs = { alc882_base_init_verbs, |
8712 | alc882_adc1_init_verbs }, | ||
8501 | .num_dacs = ARRAY_SIZE(alc882_dac_nids), | 8713 | .num_dacs = ARRAY_SIZE(alc882_dac_nids), |
8502 | .dac_nids = alc882_dac_nids, | 8714 | .dac_nids = alc882_dac_nids, |
8503 | .dig_out_nid = ALC882_DIGOUT_NID, | 8715 | .dig_out_nid = ALC882_DIGOUT_NID, |
@@ -8508,7 +8720,8 @@ static struct alc_config_preset alc882_presets[] = { | |||
8508 | }, | 8720 | }, |
8509 | [ALC882_ARIMA] = { | 8721 | [ALC882_ARIMA] = { |
8510 | .mixers = { alc882_base_mixer, alc882_chmode_mixer }, | 8722 | .mixers = { alc882_base_mixer, alc882_chmode_mixer }, |
8511 | .init_verbs = { alc882_init_verbs, alc882_eapd_verbs }, | 8723 | .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs, |
8724 | alc882_eapd_verbs }, | ||
8512 | .num_dacs = ARRAY_SIZE(alc882_dac_nids), | 8725 | .num_dacs = ARRAY_SIZE(alc882_dac_nids), |
8513 | .dac_nids = alc882_dac_nids, | 8726 | .dac_nids = alc882_dac_nids, |
8514 | .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes), | 8727 | .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes), |
@@ -8517,8 +8730,8 @@ static struct alc_config_preset alc882_presets[] = { | |||
8517 | }, | 8730 | }, |
8518 | [ALC882_W2JC] = { | 8731 | [ALC882_W2JC] = { |
8519 | .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer }, | 8732 | .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer }, |
8520 | .init_verbs = { alc882_init_verbs, alc882_eapd_verbs, | 8733 | .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs, |
8521 | alc880_gpio1_init_verbs }, | 8734 | alc882_eapd_verbs, alc880_gpio1_init_verbs }, |
8522 | .num_dacs = ARRAY_SIZE(alc882_dac_nids), | 8735 | .num_dacs = ARRAY_SIZE(alc882_dac_nids), |
8523 | .dac_nids = alc882_dac_nids, | 8736 | .dac_nids = alc882_dac_nids, |
8524 | .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), | 8737 | .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), |
@@ -8580,7 +8793,8 @@ static struct alc_config_preset alc882_presets[] = { | |||
8580 | }, | 8793 | }, |
8581 | [ALC882_TARGA] = { | 8794 | [ALC882_TARGA] = { |
8582 | .mixers = { alc882_targa_mixer, alc882_chmode_mixer }, | 8795 | .mixers = { alc882_targa_mixer, alc882_chmode_mixer }, |
8583 | .init_verbs = { alc882_init_verbs, alc882_targa_verbs}, | 8796 | .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs, |
8797 | alc880_gpio3_init_verbs, alc882_targa_verbs}, | ||
8584 | .num_dacs = ARRAY_SIZE(alc882_dac_nids), | 8798 | .num_dacs = ARRAY_SIZE(alc882_dac_nids), |
8585 | .dac_nids = alc882_dac_nids, | 8799 | .dac_nids = alc882_dac_nids, |
8586 | .dig_out_nid = ALC882_DIGOUT_NID, | 8800 | .dig_out_nid = ALC882_DIGOUT_NID, |
@@ -8596,7 +8810,8 @@ static struct alc_config_preset alc882_presets[] = { | |||
8596 | }, | 8810 | }, |
8597 | [ALC882_ASUS_A7J] = { | 8811 | [ALC882_ASUS_A7J] = { |
8598 | .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer }, | 8812 | .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer }, |
8599 | .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs}, | 8813 | .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs, |
8814 | alc882_asus_a7j_verbs}, | ||
8600 | .num_dacs = ARRAY_SIZE(alc882_dac_nids), | 8815 | .num_dacs = ARRAY_SIZE(alc882_dac_nids), |
8601 | .dac_nids = alc882_dac_nids, | 8816 | .dac_nids = alc882_dac_nids, |
8602 | .dig_out_nid = ALC882_DIGOUT_NID, | 8817 | .dig_out_nid = ALC882_DIGOUT_NID, |
@@ -8610,8 +8825,8 @@ static struct alc_config_preset alc882_presets[] = { | |||
8610 | }, | 8825 | }, |
8611 | [ALC882_ASUS_A7M] = { | 8826 | [ALC882_ASUS_A7M] = { |
8612 | .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer }, | 8827 | .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer }, |
8613 | .init_verbs = { alc882_init_verbs, alc882_eapd_verbs, | 8828 | .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs, |
8614 | alc880_gpio1_init_verbs, | 8829 | alc882_eapd_verbs, alc880_gpio1_init_verbs, |
8615 | alc882_asus_a7m_verbs }, | 8830 | alc882_asus_a7m_verbs }, |
8616 | .num_dacs = ARRAY_SIZE(alc882_dac_nids), | 8831 | .num_dacs = ARRAY_SIZE(alc882_dac_nids), |
8617 | .dac_nids = alc882_dac_nids, | 8832 | .dac_nids = alc882_dac_nids, |
@@ -8667,6 +8882,44 @@ static struct alc_config_preset alc882_presets[] = { | |||
8667 | .need_dac_fix = 1, | 8882 | .need_dac_fix = 1, |
8668 | .input_mux = &alc883_3stack_6ch_intel, | 8883 | .input_mux = &alc883_3stack_6ch_intel, |
8669 | }, | 8884 | }, |
8885 | [ALC889A_INTEL] = { | ||
8886 | .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer }, | ||
8887 | .init_verbs = { alc885_init_verbs, alc885_init_input_verbs, | ||
8888 | alc_hp15_unsol_verbs }, | ||
8889 | .num_dacs = ARRAY_SIZE(alc883_dac_nids), | ||
8890 | .dac_nids = alc883_dac_nids, | ||
8891 | .num_adc_nids = ARRAY_SIZE(alc889_adc_nids), | ||
8892 | .adc_nids = alc889_adc_nids, | ||
8893 | .dig_out_nid = ALC883_DIGOUT_NID, | ||
8894 | .dig_in_nid = ALC883_DIGIN_NID, | ||
8895 | .slave_dig_outs = alc883_slave_dig_outs, | ||
8896 | .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes), | ||
8897 | .channel_mode = alc889_8ch_intel_modes, | ||
8898 | .capsrc_nids = alc889_capsrc_nids, | ||
8899 | .input_mux = &alc889_capture_source, | ||
8900 | .init_hook = alc889_automute_init, | ||
8901 | .unsol_event = alc_automute_amp_unsol_event, | ||
8902 | .need_dac_fix = 1, | ||
8903 | }, | ||
8904 | [ALC889_INTEL] = { | ||
8905 | .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer }, | ||
8906 | .init_verbs = { alc885_init_verbs, alc889_init_input_verbs, | ||
8907 | alc889_eapd_verbs, alc_hp15_unsol_verbs}, | ||
8908 | .num_dacs = ARRAY_SIZE(alc883_dac_nids), | ||
8909 | .dac_nids = alc883_dac_nids, | ||
8910 | .num_adc_nids = ARRAY_SIZE(alc889_adc_nids), | ||
8911 | .adc_nids = alc889_adc_nids, | ||
8912 | .dig_out_nid = ALC883_DIGOUT_NID, | ||
8913 | .dig_in_nid = ALC883_DIGIN_NID, | ||
8914 | .slave_dig_outs = alc883_slave_dig_outs, | ||
8915 | .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes), | ||
8916 | .channel_mode = alc889_8ch_intel_modes, | ||
8917 | .capsrc_nids = alc889_capsrc_nids, | ||
8918 | .input_mux = &alc889_capture_source, | ||
8919 | .init_hook = alc889_intel_init_hook, | ||
8920 | .unsol_event = alc_automute_amp_unsol_event, | ||
8921 | .need_dac_fix = 1, | ||
8922 | }, | ||
8670 | [ALC883_6ST_DIG] = { | 8923 | [ALC883_6ST_DIG] = { |
8671 | .mixers = { alc883_base_mixer, alc883_chmode_mixer }, | 8924 | .mixers = { alc883_base_mixer, alc883_chmode_mixer }, |
8672 | .init_verbs = { alc883_init_verbs }, | 8925 | .init_verbs = { alc883_init_verbs }, |
@@ -8680,7 +8933,8 @@ static struct alc_config_preset alc882_presets[] = { | |||
8680 | }, | 8933 | }, |
8681 | [ALC883_TARGA_DIG] = { | 8934 | [ALC883_TARGA_DIG] = { |
8682 | .mixers = { alc883_targa_mixer, alc883_chmode_mixer }, | 8935 | .mixers = { alc883_targa_mixer, alc883_chmode_mixer }, |
8683 | .init_verbs = { alc883_init_verbs, alc883_targa_verbs}, | 8936 | .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs, |
8937 | alc883_targa_verbs}, | ||
8684 | .num_dacs = ARRAY_SIZE(alc883_dac_nids), | 8938 | .num_dacs = ARRAY_SIZE(alc883_dac_nids), |
8685 | .dac_nids = alc883_dac_nids, | 8939 | .dac_nids = alc883_dac_nids, |
8686 | .dig_out_nid = ALC883_DIGOUT_NID, | 8940 | .dig_out_nid = ALC883_DIGOUT_NID, |
@@ -8693,7 +8947,8 @@ static struct alc_config_preset alc882_presets[] = { | |||
8693 | }, | 8947 | }, |
8694 | [ALC883_TARGA_2ch_DIG] = { | 8948 | [ALC883_TARGA_2ch_DIG] = { |
8695 | .mixers = { alc883_targa_2ch_mixer}, | 8949 | .mixers = { alc883_targa_2ch_mixer}, |
8696 | .init_verbs = { alc883_init_verbs, alc883_targa_verbs}, | 8950 | .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs, |
8951 | alc883_targa_verbs}, | ||
8697 | .num_dacs = ARRAY_SIZE(alc883_dac_nids), | 8952 | .num_dacs = ARRAY_SIZE(alc883_dac_nids), |
8698 | .dac_nids = alc883_dac_nids, | 8953 | .dac_nids = alc883_dac_nids, |
8699 | .adc_nids = alc883_adc_nids_alt, | 8954 | .adc_nids = alc883_adc_nids_alt, |
@@ -9238,7 +9493,7 @@ static int alc882_parse_auto_config(struct hda_codec *codec) | |||
9238 | spec->init_verbs[0] = alc883_auto_init_verbs; | 9493 | spec->init_verbs[0] = alc883_auto_init_verbs; |
9239 | /* if ADC 0x07 is available, initialize it, too */ | 9494 | /* if ADC 0x07 is available, initialize it, too */ |
9240 | wcap = get_wcaps(codec, 0x07); | 9495 | wcap = get_wcaps(codec, 0x07); |
9241 | wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; | 9496 | wcap = get_wcaps_type(wcap); |
9242 | if (wcap == AC_WID_AUD_IN) | 9497 | if (wcap == AC_WID_AUD_IN) |
9243 | add_verb(spec, alc882_adc1_init_verbs); | 9498 | add_verb(spec, alc882_adc1_init_verbs); |
9244 | 9499 | ||
@@ -9304,8 +9559,7 @@ static int patch_alc882(struct hda_codec *codec) | |||
9304 | ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl); | 9559 | ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl); |
9305 | 9560 | ||
9306 | if (board_config < 0 || board_config >= ALC882_MODEL_LAST) { | 9561 | if (board_config < 0 || board_config >= ALC882_MODEL_LAST) { |
9307 | printk(KERN_INFO "hda_codec: Unknown model for %s, " | 9562 | printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", |
9308 | "trying auto-probe from BIOS...\n", | ||
9309 | codec->chip_name); | 9563 | codec->chip_name); |
9310 | board_config = ALC882_AUTO; | 9564 | board_config = ALC882_AUTO; |
9311 | } | 9565 | } |
@@ -9355,7 +9609,7 @@ static int patch_alc882(struct hda_codec *codec) | |||
9355 | hda_nid_t nid = alc882_adc_nids[i]; | 9609 | hda_nid_t nid = alc882_adc_nids[i]; |
9356 | unsigned int wcap = get_wcaps(codec, nid); | 9610 | unsigned int wcap = get_wcaps(codec, nid); |
9357 | /* get type */ | 9611 | /* get type */ |
9358 | wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; | 9612 | wcap = get_wcaps_type(wcap); |
9359 | if (wcap != AC_WID_AUD_IN) | 9613 | if (wcap != AC_WID_AUD_IN) |
9360 | continue; | 9614 | continue; |
9361 | spec->private_adc_nids[spec->num_adc_nids] = nid; | 9615 | spec->private_adc_nids[spec->num_adc_nids] = nid; |
@@ -9895,12 +10149,6 @@ static struct hda_verb alc262_eapd_verbs[] = { | |||
9895 | { } | 10149 | { } |
9896 | }; | 10150 | }; |
9897 | 10151 | ||
9898 | static struct hda_verb alc262_hippo_unsol_verbs[] = { | ||
9899 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, | ||
9900 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
9901 | {} | ||
9902 | }; | ||
9903 | |||
9904 | static struct hda_verb alc262_hippo1_unsol_verbs[] = { | 10152 | static struct hda_verb alc262_hippo1_unsol_verbs[] = { |
9905 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, | 10153 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, |
9906 | {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, | 10154 | {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, |
@@ -10167,6 +10415,18 @@ static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec, | |||
10167 | alc262_lenovo_3000_automute(codec, 1); | 10415 | alc262_lenovo_3000_automute(codec, 1); |
10168 | } | 10416 | } |
10169 | 10417 | ||
10418 | static int amp_stereo_mute_update(struct hda_codec *codec, hda_nid_t nid, | ||
10419 | int dir, int idx, long *valp) | ||
10420 | { | ||
10421 | int i, change = 0; | ||
10422 | |||
10423 | for (i = 0; i < 2; i++, valp++) | ||
10424 | change |= snd_hda_codec_amp_update(codec, nid, i, dir, idx, | ||
10425 | HDA_AMP_MUTE, | ||
10426 | *valp ? 0 : HDA_AMP_MUTE); | ||
10427 | return change; | ||
10428 | } | ||
10429 | |||
10170 | /* bind hp and internal speaker mute (with plug check) */ | 10430 | /* bind hp and internal speaker mute (with plug check) */ |
10171 | static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol, | 10431 | static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol, |
10172 | struct snd_ctl_elem_value *ucontrol) | 10432 | struct snd_ctl_elem_value *ucontrol) |
@@ -10175,13 +10435,8 @@ static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol, | |||
10175 | long *valp = ucontrol->value.integer.value; | 10435 | long *valp = ucontrol->value.integer.value; |
10176 | int change; | 10436 | int change; |
10177 | 10437 | ||
10178 | change = snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, | 10438 | change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp); |
10179 | HDA_AMP_MUTE, | 10439 | change |= amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp); |
10180 | valp ? 0 : HDA_AMP_MUTE); | ||
10181 | change |= snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0, | ||
10182 | HDA_AMP_MUTE, | ||
10183 | valp ? 0 : HDA_AMP_MUTE); | ||
10184 | |||
10185 | if (change) | 10440 | if (change) |
10186 | alc262_fujitsu_automute(codec, 0); | 10441 | alc262_fujitsu_automute(codec, 0); |
10187 | return change; | 10442 | return change; |
@@ -10216,10 +10471,7 @@ static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol, | |||
10216 | long *valp = ucontrol->value.integer.value; | 10471 | long *valp = ucontrol->value.integer.value; |
10217 | int change; | 10472 | int change; |
10218 | 10473 | ||
10219 | change = snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0, | 10474 | change = amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp); |
10220 | HDA_AMP_MUTE, | ||
10221 | valp ? 0 : HDA_AMP_MUTE); | ||
10222 | |||
10223 | if (change) | 10475 | if (change) |
10224 | alc262_lenovo_3000_automute(codec, 0); | 10476 | alc262_lenovo_3000_automute(codec, 0); |
10225 | return change; | 10477 | return change; |
@@ -10938,7 +11190,7 @@ static struct alc_config_preset alc262_presets[] = { | |||
10938 | }, | 11190 | }, |
10939 | [ALC262_HIPPO] = { | 11191 | [ALC262_HIPPO] = { |
10940 | .mixers = { alc262_hippo_mixer }, | 11192 | .mixers = { alc262_hippo_mixer }, |
10941 | .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs}, | 11193 | .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs}, |
10942 | .num_dacs = ARRAY_SIZE(alc262_dac_nids), | 11194 | .num_dacs = ARRAY_SIZE(alc262_dac_nids), |
10943 | .dac_nids = alc262_dac_nids, | 11195 | .dac_nids = alc262_dac_nids, |
10944 | .hp_nid = 0x03, | 11196 | .hp_nid = 0x03, |
@@ -11058,7 +11310,8 @@ static struct alc_config_preset alc262_presets[] = { | |||
11058 | }, | 11310 | }, |
11059 | [ALC262_BENQ_T31] = { | 11311 | [ALC262_BENQ_T31] = { |
11060 | .mixers = { alc262_benq_t31_mixer }, | 11312 | .mixers = { alc262_benq_t31_mixer }, |
11061 | .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs }, | 11313 | .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, |
11314 | alc_hp15_unsol_verbs }, | ||
11062 | .num_dacs = ARRAY_SIZE(alc262_dac_nids), | 11315 | .num_dacs = ARRAY_SIZE(alc262_dac_nids), |
11063 | .dac_nids = alc262_dac_nids, | 11316 | .dac_nids = alc262_dac_nids, |
11064 | .hp_nid = 0x03, | 11317 | .hp_nid = 0x03, |
@@ -11180,8 +11433,8 @@ static int patch_alc262(struct hda_codec *codec) | |||
11180 | alc262_cfg_tbl); | 11433 | alc262_cfg_tbl); |
11181 | 11434 | ||
11182 | if (board_config < 0) { | 11435 | if (board_config < 0) { |
11183 | printk(KERN_INFO "hda_codec: Unknown model for %s, " | 11436 | printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", |
11184 | "trying auto-probe from BIOS...\n", codec->chip_name); | 11437 | codec->chip_name); |
11185 | board_config = ALC262_AUTO; | 11438 | board_config = ALC262_AUTO; |
11186 | } | 11439 | } |
11187 | 11440 | ||
@@ -11234,7 +11487,7 @@ static int patch_alc262(struct hda_codec *codec) | |||
11234 | unsigned int wcap = get_wcaps(codec, 0x07); | 11487 | unsigned int wcap = get_wcaps(codec, 0x07); |
11235 | 11488 | ||
11236 | /* get type */ | 11489 | /* get type */ |
11237 | wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; | 11490 | wcap = get_wcaps_type(wcap); |
11238 | if (wcap != AC_WID_AUD_IN) { | 11491 | if (wcap != AC_WID_AUD_IN) { |
11239 | spec->adc_nids = alc262_adc_nids_alt; | 11492 | spec->adc_nids = alc262_adc_nids_alt; |
11240 | spec->num_adc_nids = | 11493 | spec->num_adc_nids = |
@@ -11390,12 +11643,7 @@ static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol, | |||
11390 | long *valp = ucontrol->value.integer.value; | 11643 | long *valp = ucontrol->value.integer.value; |
11391 | int change; | 11644 | int change; |
11392 | 11645 | ||
11393 | change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0, | 11646 | change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp); |
11394 | HDA_AMP_MUTE, | ||
11395 | valp[0] ? 0 : HDA_AMP_MUTE); | ||
11396 | change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0, | ||
11397 | HDA_AMP_MUTE, | ||
11398 | valp[1] ? 0 : HDA_AMP_MUTE); | ||
11399 | if (change) | 11647 | if (change) |
11400 | alc268_acer_automute(codec, 0); | 11648 | alc268_acer_automute(codec, 0); |
11401 | return change; | 11649 | return change; |
@@ -11806,26 +12054,38 @@ static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid, | |||
11806 | const char *ctlname, int idx) | 12054 | const char *ctlname, int idx) |
11807 | { | 12055 | { |
11808 | char name[32]; | 12056 | char name[32]; |
12057 | hda_nid_t dac; | ||
11809 | int err; | 12058 | int err; |
11810 | 12059 | ||
11811 | sprintf(name, "%s Playback Volume", ctlname); | 12060 | sprintf(name, "%s Playback Volume", ctlname); |
11812 | if (nid == 0x14) { | 12061 | switch (nid) { |
11813 | err = add_control(spec, ALC_CTL_WIDGET_VOL, name, | 12062 | case 0x14: |
11814 | HDA_COMPOSE_AMP_VAL(0x02, 3, idx, | 12063 | case 0x16: |
11815 | HDA_OUTPUT)); | 12064 | dac = 0x02; |
11816 | if (err < 0) | 12065 | break; |
11817 | return err; | 12066 | case 0x15: |
11818 | } else if (nid == 0x15) { | 12067 | dac = 0x03; |
12068 | break; | ||
12069 | default: | ||
12070 | return 0; | ||
12071 | } | ||
12072 | if (spec->multiout.dac_nids[0] != dac && | ||
12073 | spec->multiout.dac_nids[1] != dac) { | ||
11819 | err = add_control(spec, ALC_CTL_WIDGET_VOL, name, | 12074 | err = add_control(spec, ALC_CTL_WIDGET_VOL, name, |
11820 | HDA_COMPOSE_AMP_VAL(0x03, 3, idx, | 12075 | HDA_COMPOSE_AMP_VAL(dac, 3, idx, |
11821 | HDA_OUTPUT)); | 12076 | HDA_OUTPUT)); |
11822 | if (err < 0) | 12077 | if (err < 0) |
11823 | return err; | 12078 | return err; |
11824 | } else | 12079 | spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac; |
11825 | return -1; | 12080 | } |
12081 | |||
11826 | sprintf(name, "%s Playback Switch", ctlname); | 12082 | sprintf(name, "%s Playback Switch", ctlname); |
11827 | err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, | 12083 | if (nid != 0x16) |
12084 | err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, | ||
11828 | HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT)); | 12085 | HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT)); |
12086 | else /* mono */ | ||
12087 | err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, | ||
12088 | HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT)); | ||
11829 | if (err < 0) | 12089 | if (err < 0) |
11830 | return err; | 12090 | return err; |
11831 | return 0; | 12091 | return 0; |
@@ -11838,14 +12098,19 @@ static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec, | |||
11838 | hda_nid_t nid; | 12098 | hda_nid_t nid; |
11839 | int err; | 12099 | int err; |
11840 | 12100 | ||
11841 | spec->multiout.num_dacs = 2; /* only use one dac */ | ||
11842 | spec->multiout.dac_nids = spec->private_dac_nids; | 12101 | spec->multiout.dac_nids = spec->private_dac_nids; |
11843 | spec->multiout.dac_nids[0] = 2; | ||
11844 | spec->multiout.dac_nids[1] = 3; | ||
11845 | 12102 | ||
11846 | nid = cfg->line_out_pins[0]; | 12103 | nid = cfg->line_out_pins[0]; |
11847 | if (nid) | 12104 | if (nid) { |
11848 | alc268_new_analog_output(spec, nid, "Front", 0); | 12105 | const char *name; |
12106 | if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) | ||
12107 | name = "Speaker"; | ||
12108 | else | ||
12109 | name = "Front"; | ||
12110 | err = alc268_new_analog_output(spec, nid, name, 0); | ||
12111 | if (err < 0) | ||
12112 | return err; | ||
12113 | } | ||
11849 | 12114 | ||
11850 | nid = cfg->speaker_pins[0]; | 12115 | nid = cfg->speaker_pins[0]; |
11851 | if (nid == 0x1d) { | 12116 | if (nid == 0x1d) { |
@@ -11854,16 +12119,23 @@ static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec, | |||
11854 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); | 12119 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); |
11855 | if (err < 0) | 12120 | if (err < 0) |
11856 | return err; | 12121 | return err; |
12122 | } else { | ||
12123 | err = alc268_new_analog_output(spec, nid, "Speaker", 0); | ||
12124 | if (err < 0) | ||
12125 | return err; | ||
11857 | } | 12126 | } |
11858 | nid = cfg->hp_pins[0]; | 12127 | nid = cfg->hp_pins[0]; |
11859 | if (nid) | 12128 | if (nid) { |
11860 | alc268_new_analog_output(spec, nid, "Headphone", 0); | 12129 | err = alc268_new_analog_output(spec, nid, "Headphone", 0); |
12130 | if (err < 0) | ||
12131 | return err; | ||
12132 | } | ||
11861 | 12133 | ||
11862 | nid = cfg->line_out_pins[1] | cfg->line_out_pins[2]; | 12134 | nid = cfg->line_out_pins[1] | cfg->line_out_pins[2]; |
11863 | if (nid == 0x16) { | 12135 | if (nid == 0x16) { |
11864 | err = add_control(spec, ALC_CTL_WIDGET_MUTE, | 12136 | err = add_control(spec, ALC_CTL_WIDGET_MUTE, |
11865 | "Mono Playback Switch", | 12137 | "Mono Playback Switch", |
11866 | HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT)); | 12138 | HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT)); |
11867 | if (err < 0) | 12139 | if (err < 0) |
11868 | return err; | 12140 | return err; |
11869 | } | 12141 | } |
@@ -12234,8 +12506,8 @@ static int patch_alc268(struct hda_codec *codec) | |||
12234 | alc268_cfg_tbl); | 12506 | alc268_cfg_tbl); |
12235 | 12507 | ||
12236 | if (board_config < 0 || board_config >= ALC268_MODEL_LAST) { | 12508 | if (board_config < 0 || board_config >= ALC268_MODEL_LAST) { |
12237 | printk(KERN_INFO "hda_codec: Unknown model for %s, " | 12509 | printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", |
12238 | "trying auto-probe from BIOS...\n", codec->chip_name); | 12510 | codec->chip_name); |
12239 | board_config = ALC268_AUTO; | 12511 | board_config = ALC268_AUTO; |
12240 | } | 12512 | } |
12241 | 12513 | ||
@@ -12291,7 +12563,7 @@ static int patch_alc268(struct hda_codec *codec) | |||
12291 | int i; | 12563 | int i; |
12292 | 12564 | ||
12293 | /* get type */ | 12565 | /* get type */ |
12294 | wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; | 12566 | wcap = get_wcaps_type(wcap); |
12295 | if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) { | 12567 | if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) { |
12296 | spec->adc_nids = alc268_adc_nids_alt; | 12568 | spec->adc_nids = alc268_adc_nids_alt; |
12297 | spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt); | 12569 | spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt); |
@@ -12418,20 +12690,11 @@ static struct snd_kcontrol_new alc269_lifebook_mixer[] = { | |||
12418 | { } | 12690 | { } |
12419 | }; | 12691 | }; |
12420 | 12692 | ||
12421 | /* bind volumes of both NID 0x0c and 0x0d */ | ||
12422 | static struct hda_bind_ctls alc269_epc_bind_vol = { | ||
12423 | .ops = &snd_hda_bind_vol, | ||
12424 | .values = { | ||
12425 | HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), | ||
12426 | HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT), | ||
12427 | 0 | ||
12428 | }, | ||
12429 | }; | ||
12430 | |||
12431 | static struct snd_kcontrol_new alc269_eeepc_mixer[] = { | 12693 | static struct snd_kcontrol_new alc269_eeepc_mixer[] = { |
12432 | HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), | 12694 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), |
12433 | HDA_BIND_VOL("LineOut Playback Volume", &alc269_epc_bind_vol), | 12695 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), |
12434 | HDA_CODEC_MUTE("LineOut Playback Switch", 0x15, 0x0, HDA_OUTPUT), | 12696 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), |
12697 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), | ||
12435 | { } /* end */ | 12698 | { } /* end */ |
12436 | }; | 12699 | }; |
12437 | 12700 | ||
@@ -12444,12 +12707,7 @@ static struct snd_kcontrol_new alc269_epc_capture_mixer[] = { | |||
12444 | }; | 12707 | }; |
12445 | 12708 | ||
12446 | /* FSC amilo */ | 12709 | /* FSC amilo */ |
12447 | static struct snd_kcontrol_new alc269_fujitsu_mixer[] = { | 12710 | #define alc269_fujitsu_mixer alc269_eeepc_mixer |
12448 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), | ||
12449 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), | ||
12450 | HDA_BIND_VOL("PCM Playback Volume", &alc269_epc_bind_vol), | ||
12451 | { } /* end */ | ||
12452 | }; | ||
12453 | 12711 | ||
12454 | static struct hda_verb alc269_quanta_fl1_verbs[] = { | 12712 | static struct hda_verb alc269_quanta_fl1_verbs[] = { |
12455 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, | 12713 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, |
@@ -13066,8 +13324,8 @@ static int patch_alc269(struct hda_codec *codec) | |||
13066 | alc269_cfg_tbl); | 13324 | alc269_cfg_tbl); |
13067 | 13325 | ||
13068 | if (board_config < 0) { | 13326 | if (board_config < 0) { |
13069 | printk(KERN_INFO "hda_codec: Unknown model for %s, " | 13327 | printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", |
13070 | "trying auto-probe from BIOS...\n", codec->chip_name); | 13328 | codec->chip_name); |
13071 | board_config = ALC269_AUTO; | 13329 | board_config = ALC269_AUTO; |
13072 | } | 13330 | } |
13073 | 13331 | ||
@@ -13659,23 +13917,23 @@ static struct hda_verb alc861_auto_init_verbs[] = { | |||
13659 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | 13917 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, |
13660 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, | 13918 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, |
13661 | 13919 | ||
13662 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 13920 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, |
13663 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 13921 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, |
13664 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 13922 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, |
13665 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 13923 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, |
13666 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 13924 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, |
13667 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 13925 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, |
13668 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 13926 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, |
13669 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 13927 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, |
13670 | 13928 | ||
13671 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | 13929 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, |
13672 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | 13930 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, |
13673 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | 13931 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, |
13674 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, | 13932 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, |
13675 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | 13933 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, |
13676 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | 13934 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, |
13677 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | 13935 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, |
13678 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, | 13936 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, |
13679 | 13937 | ||
13680 | {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */ | 13938 | {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */ |
13681 | 13939 | ||
@@ -13747,64 +14005,96 @@ static struct hda_input_mux alc861_capture_source = { | |||
13747 | }, | 14005 | }, |
13748 | }; | 14006 | }; |
13749 | 14007 | ||
14008 | static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin) | ||
14009 | { | ||
14010 | struct alc_spec *spec = codec->spec; | ||
14011 | hda_nid_t mix, srcs[5]; | ||
14012 | int i, j, num; | ||
14013 | |||
14014 | if (snd_hda_get_connections(codec, pin, &mix, 1) != 1) | ||
14015 | return 0; | ||
14016 | num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs)); | ||
14017 | if (num < 0) | ||
14018 | return 0; | ||
14019 | for (i = 0; i < num; i++) { | ||
14020 | unsigned int type; | ||
14021 | type = get_wcaps_type(get_wcaps(codec, srcs[i])); | ||
14022 | if (type != AC_WID_AUD_OUT) | ||
14023 | continue; | ||
14024 | for (j = 0; j < spec->multiout.num_dacs; j++) | ||
14025 | if (spec->multiout.dac_nids[j] == srcs[i]) | ||
14026 | break; | ||
14027 | if (j >= spec->multiout.num_dacs) | ||
14028 | return srcs[i]; | ||
14029 | } | ||
14030 | return 0; | ||
14031 | } | ||
14032 | |||
13750 | /* fill in the dac_nids table from the parsed pin configuration */ | 14033 | /* fill in the dac_nids table from the parsed pin configuration */ |
13751 | static int alc861_auto_fill_dac_nids(struct alc_spec *spec, | 14034 | static int alc861_auto_fill_dac_nids(struct hda_codec *codec, |
13752 | const struct auto_pin_cfg *cfg) | 14035 | const struct auto_pin_cfg *cfg) |
13753 | { | 14036 | { |
14037 | struct alc_spec *spec = codec->spec; | ||
13754 | int i; | 14038 | int i; |
13755 | hda_nid_t nid; | 14039 | hda_nid_t nid, dac; |
13756 | 14040 | ||
13757 | spec->multiout.dac_nids = spec->private_dac_nids; | 14041 | spec->multiout.dac_nids = spec->private_dac_nids; |
13758 | for (i = 0; i < cfg->line_outs; i++) { | 14042 | for (i = 0; i < cfg->line_outs; i++) { |
13759 | nid = cfg->line_out_pins[i]; | 14043 | nid = cfg->line_out_pins[i]; |
13760 | if (nid) { | 14044 | dac = alc861_look_for_dac(codec, nid); |
13761 | if (i >= ARRAY_SIZE(alc861_dac_nids)) | 14045 | if (!dac) |
13762 | continue; | 14046 | continue; |
13763 | spec->multiout.dac_nids[i] = alc861_dac_nids[i]; | 14047 | spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac; |
13764 | } | ||
13765 | } | 14048 | } |
13766 | spec->multiout.num_dacs = cfg->line_outs; | ||
13767 | return 0; | 14049 | return 0; |
13768 | } | 14050 | } |
13769 | 14051 | ||
14052 | static int alc861_create_out_sw(struct hda_codec *codec, const char *pfx, | ||
14053 | hda_nid_t nid, unsigned int chs) | ||
14054 | { | ||
14055 | char name[32]; | ||
14056 | snprintf(name, sizeof(name), "%s Playback Switch", pfx); | ||
14057 | return add_control(codec->spec, ALC_CTL_WIDGET_MUTE, name, | ||
14058 | HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT)); | ||
14059 | } | ||
14060 | |||
13770 | /* add playback controls from the parsed DAC table */ | 14061 | /* add playback controls from the parsed DAC table */ |
13771 | static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec, | 14062 | static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec, |
13772 | const struct auto_pin_cfg *cfg) | 14063 | const struct auto_pin_cfg *cfg) |
13773 | { | 14064 | { |
13774 | char name[32]; | 14065 | struct alc_spec *spec = codec->spec; |
13775 | static const char *chname[4] = { | 14066 | static const char *chname[4] = { |
13776 | "Front", "Surround", NULL /*CLFE*/, "Side" | 14067 | "Front", "Surround", NULL /*CLFE*/, "Side" |
13777 | }; | 14068 | }; |
13778 | hda_nid_t nid; | 14069 | hda_nid_t nid; |
13779 | int i, idx, err; | 14070 | int i, err; |
14071 | |||
14072 | if (cfg->line_outs == 1) { | ||
14073 | const char *pfx = NULL; | ||
14074 | if (!cfg->hp_outs) | ||
14075 | pfx = "Master"; | ||
14076 | else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) | ||
14077 | pfx = "Speaker"; | ||
14078 | if (pfx) { | ||
14079 | nid = spec->multiout.dac_nids[0]; | ||
14080 | return alc861_create_out_sw(codec, pfx, nid, 3); | ||
14081 | } | ||
14082 | } | ||
13780 | 14083 | ||
13781 | for (i = 0; i < cfg->line_outs; i++) { | 14084 | for (i = 0; i < cfg->line_outs; i++) { |
13782 | nid = spec->multiout.dac_nids[i]; | 14085 | nid = spec->multiout.dac_nids[i]; |
13783 | if (!nid) | 14086 | if (!nid) |
13784 | continue; | 14087 | continue; |
13785 | if (nid == 0x05) { | 14088 | if (i == 2) { |
13786 | /* Center/LFE */ | 14089 | /* Center/LFE */ |
13787 | err = add_control(spec, ALC_CTL_BIND_MUTE, | 14090 | err = alc861_create_out_sw(codec, "Center", nid, 1); |
13788 | "Center Playback Switch", | ||
13789 | HDA_COMPOSE_AMP_VAL(nid, 1, 0, | ||
13790 | HDA_OUTPUT)); | ||
13791 | if (err < 0) | 14091 | if (err < 0) |
13792 | return err; | 14092 | return err; |
13793 | err = add_control(spec, ALC_CTL_BIND_MUTE, | 14093 | err = alc861_create_out_sw(codec, "LFE", nid, 2); |
13794 | "LFE Playback Switch", | ||
13795 | HDA_COMPOSE_AMP_VAL(nid, 2, 0, | ||
13796 | HDA_OUTPUT)); | ||
13797 | if (err < 0) | 14094 | if (err < 0) |
13798 | return err; | 14095 | return err; |
13799 | } else { | 14096 | } else { |
13800 | for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1; | 14097 | err = alc861_create_out_sw(codec, chname[i], nid, 3); |
13801 | idx++) | ||
13802 | if (nid == alc861_dac_nids[idx]) | ||
13803 | break; | ||
13804 | sprintf(name, "%s Playback Switch", chname[idx]); | ||
13805 | err = add_control(spec, ALC_CTL_BIND_MUTE, name, | ||
13806 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, | ||
13807 | HDA_OUTPUT)); | ||
13808 | if (err < 0) | 14098 | if (err < 0) |
13809 | return err; | 14099 | return err; |
13810 | } | 14100 | } |
@@ -13812,8 +14102,9 @@ static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec, | |||
13812 | return 0; | 14102 | return 0; |
13813 | } | 14103 | } |
13814 | 14104 | ||
13815 | static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin) | 14105 | static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin) |
13816 | { | 14106 | { |
14107 | struct alc_spec *spec = codec->spec; | ||
13817 | int err; | 14108 | int err; |
13818 | hda_nid_t nid; | 14109 | hda_nid_t nid; |
13819 | 14110 | ||
@@ -13821,21 +14112,22 @@ static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin) | |||
13821 | return 0; | 14112 | return 0; |
13822 | 14113 | ||
13823 | if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) { | 14114 | if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) { |
13824 | nid = 0x03; | 14115 | nid = alc861_look_for_dac(codec, pin); |
13825 | err = add_control(spec, ALC_CTL_WIDGET_MUTE, | 14116 | if (nid) { |
13826 | "Headphone Playback Switch", | 14117 | err = alc861_create_out_sw(codec, "Headphone", nid, 3); |
13827 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); | 14118 | if (err < 0) |
13828 | if (err < 0) | 14119 | return err; |
13829 | return err; | 14120 | spec->multiout.hp_nid = nid; |
13830 | spec->multiout.hp_nid = nid; | 14121 | } |
13831 | } | 14122 | } |
13832 | return 0; | 14123 | return 0; |
13833 | } | 14124 | } |
13834 | 14125 | ||
13835 | /* create playback/capture controls for input pins */ | 14126 | /* create playback/capture controls for input pins */ |
13836 | static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec, | 14127 | static int alc861_auto_create_analog_input_ctls(struct hda_codec *codec, |
13837 | const struct auto_pin_cfg *cfg) | 14128 | const struct auto_pin_cfg *cfg) |
13838 | { | 14129 | { |
14130 | struct alc_spec *spec = codec->spec; | ||
13839 | struct hda_input_mux *imux = &spec->private_imux[0]; | 14131 | struct hda_input_mux *imux = &spec->private_imux[0]; |
13840 | int i, err, idx, idx1; | 14132 | int i, err, idx, idx1; |
13841 | 14133 | ||
@@ -13879,12 +14171,29 @@ static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec, | |||
13879 | 14171 | ||
13880 | static void alc861_auto_set_output_and_unmute(struct hda_codec *codec, | 14172 | static void alc861_auto_set_output_and_unmute(struct hda_codec *codec, |
13881 | hda_nid_t nid, | 14173 | hda_nid_t nid, |
13882 | int pin_type, int dac_idx) | 14174 | int pin_type, hda_nid_t dac) |
13883 | { | 14175 | { |
14176 | hda_nid_t mix, srcs[5]; | ||
14177 | int i, num; | ||
14178 | |||
13884 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | 14179 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, |
13885 | pin_type); | 14180 | pin_type); |
13886 | snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE, | 14181 | snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE, |
13887 | AMP_OUT_UNMUTE); | 14182 | AMP_OUT_UNMUTE); |
14183 | if (snd_hda_get_connections(codec, nid, &mix, 1) != 1) | ||
14184 | return; | ||
14185 | num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs)); | ||
14186 | if (num < 0) | ||
14187 | return; | ||
14188 | for (i = 0; i < num; i++) { | ||
14189 | unsigned int mute; | ||
14190 | if (srcs[i] == dac || srcs[i] == 0x15) | ||
14191 | mute = AMP_IN_UNMUTE(i); | ||
14192 | else | ||
14193 | mute = AMP_IN_MUTE(i); | ||
14194 | snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
14195 | mute); | ||
14196 | } | ||
13888 | } | 14197 | } |
13889 | 14198 | ||
13890 | static void alc861_auto_init_multi_out(struct hda_codec *codec) | 14199 | static void alc861_auto_init_multi_out(struct hda_codec *codec) |
@@ -13907,12 +14216,13 @@ static void alc861_auto_init_hp_out(struct hda_codec *codec) | |||
13907 | hda_nid_t pin; | 14216 | hda_nid_t pin; |
13908 | 14217 | ||
13909 | pin = spec->autocfg.hp_pins[0]; | 14218 | pin = spec->autocfg.hp_pins[0]; |
13910 | if (pin) /* connect to front */ | 14219 | if (pin) |
13911 | alc861_auto_set_output_and_unmute(codec, pin, PIN_HP, | 14220 | alc861_auto_set_output_and_unmute(codec, pin, PIN_HP, |
13912 | spec->multiout.dac_nids[0]); | 14221 | spec->multiout.hp_nid); |
13913 | pin = spec->autocfg.speaker_pins[0]; | 14222 | pin = spec->autocfg.speaker_pins[0]; |
13914 | if (pin) | 14223 | if (pin) |
13915 | alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); | 14224 | alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT, |
14225 | spec->multiout.dac_nids[0]); | ||
13916 | } | 14226 | } |
13917 | 14227 | ||
13918 | static void alc861_auto_init_analog_input(struct hda_codec *codec) | 14228 | static void alc861_auto_init_analog_input(struct hda_codec *codec) |
@@ -13944,16 +14254,16 @@ static int alc861_parse_auto_config(struct hda_codec *codec) | |||
13944 | if (!spec->autocfg.line_outs) | 14254 | if (!spec->autocfg.line_outs) |
13945 | return 0; /* can't find valid BIOS pin config */ | 14255 | return 0; /* can't find valid BIOS pin config */ |
13946 | 14256 | ||
13947 | err = alc861_auto_fill_dac_nids(spec, &spec->autocfg); | 14257 | err = alc861_auto_fill_dac_nids(codec, &spec->autocfg); |
13948 | if (err < 0) | 14258 | if (err < 0) |
13949 | return err; | 14259 | return err; |
13950 | err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg); | 14260 | err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg); |
13951 | if (err < 0) | 14261 | if (err < 0) |
13952 | return err; | 14262 | return err; |
13953 | err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]); | 14263 | err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]); |
13954 | if (err < 0) | 14264 | if (err < 0) |
13955 | return err; | 14265 | return err; |
13956 | err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg); | 14266 | err = alc861_auto_create_analog_input_ctls(codec, &spec->autocfg); |
13957 | if (err < 0) | 14267 | if (err < 0) |
13958 | return err; | 14268 | return err; |
13959 | 14269 | ||
@@ -14165,8 +14475,8 @@ static int patch_alc861(struct hda_codec *codec) | |||
14165 | alc861_cfg_tbl); | 14475 | alc861_cfg_tbl); |
14166 | 14476 | ||
14167 | if (board_config < 0) { | 14477 | if (board_config < 0) { |
14168 | printk(KERN_INFO "hda_codec: Unknown model for %s, " | 14478 | printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", |
14169 | "trying auto-probe from BIOS...\n", codec->chip_name); | 14479 | codec->chip_name); |
14170 | board_config = ALC861_AUTO; | 14480 | board_config = ALC861_AUTO; |
14171 | } | 14481 | } |
14172 | 14482 | ||
@@ -15089,8 +15399,8 @@ static int patch_alc861vd(struct hda_codec *codec) | |||
15089 | alc861vd_cfg_tbl); | 15399 | alc861vd_cfg_tbl); |
15090 | 15400 | ||
15091 | if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) { | 15401 | if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) { |
15092 | printk(KERN_INFO "hda_codec: Unknown model for %s, " | 15402 | printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", |
15093 | "trying auto-probe from BIOS...\n", codec->chip_name); | 15403 | codec->chip_name); |
15094 | board_config = ALC861VD_AUTO; | 15404 | board_config = ALC861VD_AUTO; |
15095 | } | 15405 | } |
15096 | 15406 | ||
@@ -17013,8 +17323,8 @@ static int patch_alc662(struct hda_codec *codec) | |||
17013 | alc662_models, | 17323 | alc662_models, |
17014 | alc662_cfg_tbl); | 17324 | alc662_cfg_tbl); |
17015 | if (board_config < 0) { | 17325 | if (board_config < 0) { |
17016 | printk(KERN_INFO "hda_codec: Unknown model for %s, " | 17326 | printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", |
17017 | "trying auto-probe from BIOS...\n", codec->chip_name); | 17327 | codec->chip_name); |
17018 | board_config = ALC662_AUTO; | 17328 | board_config = ALC662_AUTO; |
17019 | } | 17329 | } |
17020 | 17330 | ||
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 14f3c3e0f62d..e5fbec37ffdd 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -40,6 +40,8 @@ enum { | |||
40 | STAC_INSERT_EVENT, | 40 | STAC_INSERT_EVENT, |
41 | STAC_PWR_EVENT, | 41 | STAC_PWR_EVENT, |
42 | STAC_HP_EVENT, | 42 | STAC_HP_EVENT, |
43 | STAC_LO_EVENT, | ||
44 | STAC_MIC_EVENT, | ||
43 | }; | 45 | }; |
44 | 46 | ||
45 | enum { | 47 | enum { |
@@ -176,6 +178,12 @@ struct sigmatel_jack { | |||
176 | struct snd_jack *jack; | 178 | struct snd_jack *jack; |
177 | }; | 179 | }; |
178 | 180 | ||
181 | struct sigmatel_mic_route { | ||
182 | hda_nid_t pin; | ||
183 | unsigned char mux_idx; | ||
184 | unsigned char dmux_idx; | ||
185 | }; | ||
186 | |||
179 | struct sigmatel_spec { | 187 | struct sigmatel_spec { |
180 | struct snd_kcontrol_new *mixers[4]; | 188 | struct snd_kcontrol_new *mixers[4]; |
181 | unsigned int num_mixers; | 189 | unsigned int num_mixers; |
@@ -187,6 +195,7 @@ struct sigmatel_spec { | |||
187 | unsigned int hp_detect: 1; | 195 | unsigned int hp_detect: 1; |
188 | unsigned int spdif_mute: 1; | 196 | unsigned int spdif_mute: 1; |
189 | unsigned int check_volume_offset:1; | 197 | unsigned int check_volume_offset:1; |
198 | unsigned int auto_mic:1; | ||
190 | 199 | ||
191 | /* gpio lines */ | 200 | /* gpio lines */ |
192 | unsigned int eapd_mask; | 201 | unsigned int eapd_mask; |
@@ -238,6 +247,14 @@ struct sigmatel_spec { | |||
238 | unsigned int num_dmuxes; | 247 | unsigned int num_dmuxes; |
239 | hda_nid_t *smux_nids; | 248 | hda_nid_t *smux_nids; |
240 | unsigned int num_smuxes; | 249 | unsigned int num_smuxes; |
250 | |||
251 | unsigned long *capvols; /* amp-volume attr: HDA_COMPOSE_AMP_VAL() */ | ||
252 | unsigned long *capsws; /* amp-mute attr: HDA_COMPOSE_AMP_VAL() */ | ||
253 | unsigned int num_caps; /* number of capture volume/switch elements */ | ||
254 | |||
255 | struct sigmatel_mic_route ext_mic; | ||
256 | struct sigmatel_mic_route int_mic; | ||
257 | |||
241 | const char **spdif_labels; | 258 | const char **spdif_labels; |
242 | 259 | ||
243 | hda_nid_t dig_in_nid; | 260 | hda_nid_t dig_in_nid; |
@@ -334,6 +351,13 @@ static hda_nid_t stac92hd73xx_smux_nids[2] = { | |||
334 | 0x22, 0x23, | 351 | 0x22, 0x23, |
335 | }; | 352 | }; |
336 | 353 | ||
354 | #define STAC92HD73XX_NUM_CAPS 2 | ||
355 | static unsigned long stac92hd73xx_capvols[] = { | ||
356 | HDA_COMPOSE_AMP_VAL(0x20, 3, 0, HDA_OUTPUT), | ||
357 | HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT), | ||
358 | }; | ||
359 | #define stac92hd73xx_capsws stac92hd73xx_capvols | ||
360 | |||
337 | #define STAC92HD83XXX_NUM_DMICS 2 | 361 | #define STAC92HD83XXX_NUM_DMICS 2 |
338 | static hda_nid_t stac92hd83xxx_dmic_nids[STAC92HD83XXX_NUM_DMICS + 1] = { | 362 | static hda_nid_t stac92hd83xxx_dmic_nids[STAC92HD83XXX_NUM_DMICS + 1] = { |
339 | 0x11, 0x12, 0 | 363 | 0x11, 0x12, 0 |
@@ -365,6 +389,13 @@ static hda_nid_t stac92hd83xxx_amp_nids[1] = { | |||
365 | 0xc, | 389 | 0xc, |
366 | }; | 390 | }; |
367 | 391 | ||
392 | #define STAC92HD83XXX_NUM_CAPS 2 | ||
393 | static unsigned long stac92hd83xxx_capvols[] = { | ||
394 | HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT), | ||
395 | HDA_COMPOSE_AMP_VAL(0x18, 3, 0, HDA_OUTPUT), | ||
396 | }; | ||
397 | #define stac92hd83xxx_capsws stac92hd83xxx_capvols | ||
398 | |||
368 | static hda_nid_t stac92hd71bxx_pwr_nids[3] = { | 399 | static hda_nid_t stac92hd71bxx_pwr_nids[3] = { |
369 | 0x0a, 0x0d, 0x0f | 400 | 0x0a, 0x0d, 0x0f |
370 | }; | 401 | }; |
@@ -394,6 +425,13 @@ static hda_nid_t stac92hd71bxx_slave_dig_outs[2] = { | |||
394 | 0x22, 0 | 425 | 0x22, 0 |
395 | }; | 426 | }; |
396 | 427 | ||
428 | #define STAC92HD71BXX_NUM_CAPS 2 | ||
429 | static unsigned long stac92hd71bxx_capvols[] = { | ||
430 | HDA_COMPOSE_AMP_VAL(0x1c, 3, 0, HDA_OUTPUT), | ||
431 | HDA_COMPOSE_AMP_VAL(0x1d, 3, 0, HDA_OUTPUT), | ||
432 | }; | ||
433 | #define stac92hd71bxx_capsws stac92hd71bxx_capvols | ||
434 | |||
397 | static hda_nid_t stac925x_adc_nids[1] = { | 435 | static hda_nid_t stac925x_adc_nids[1] = { |
398 | 0x03, | 436 | 0x03, |
399 | }; | 437 | }; |
@@ -415,6 +453,13 @@ static hda_nid_t stac925x_dmux_nids[1] = { | |||
415 | 0x14, | 453 | 0x14, |
416 | }; | 454 | }; |
417 | 455 | ||
456 | static unsigned long stac925x_capvols[] = { | ||
457 | HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT), | ||
458 | }; | ||
459 | static unsigned long stac925x_capsws[] = { | ||
460 | HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), | ||
461 | }; | ||
462 | |||
418 | static hda_nid_t stac922x_adc_nids[2] = { | 463 | static hda_nid_t stac922x_adc_nids[2] = { |
419 | 0x06, 0x07, | 464 | 0x06, 0x07, |
420 | }; | 465 | }; |
@@ -423,6 +468,13 @@ static hda_nid_t stac922x_mux_nids[2] = { | |||
423 | 0x12, 0x13, | 468 | 0x12, 0x13, |
424 | }; | 469 | }; |
425 | 470 | ||
471 | #define STAC922X_NUM_CAPS 2 | ||
472 | static unsigned long stac922x_capvols[] = { | ||
473 | HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_INPUT), | ||
474 | HDA_COMPOSE_AMP_VAL(0x18, 3, 0, HDA_INPUT), | ||
475 | }; | ||
476 | #define stac922x_capsws stac922x_capvols | ||
477 | |||
426 | static hda_nid_t stac927x_slave_dig_outs[2] = { | 478 | static hda_nid_t stac927x_slave_dig_outs[2] = { |
427 | 0x1f, 0, | 479 | 0x1f, 0, |
428 | }; | 480 | }; |
@@ -452,6 +504,18 @@ static hda_nid_t stac927x_dmic_nids[STAC927X_NUM_DMICS + 1] = { | |||
452 | 0x13, 0x14, 0 | 504 | 0x13, 0x14, 0 |
453 | }; | 505 | }; |
454 | 506 | ||
507 | #define STAC927X_NUM_CAPS 3 | ||
508 | static unsigned long stac927x_capvols[] = { | ||
509 | HDA_COMPOSE_AMP_VAL(0x18, 3, 0, HDA_INPUT), | ||
510 | HDA_COMPOSE_AMP_VAL(0x19, 3, 0, HDA_INPUT), | ||
511 | HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_INPUT), | ||
512 | }; | ||
513 | static unsigned long stac927x_capsws[] = { | ||
514 | HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT), | ||
515 | HDA_COMPOSE_AMP_VAL(0x1c, 3, 0, HDA_OUTPUT), | ||
516 | HDA_COMPOSE_AMP_VAL(0x1d, 3, 0, HDA_OUTPUT), | ||
517 | }; | ||
518 | |||
455 | static const char *stac927x_spdif_labels[5] = { | 519 | static const char *stac927x_spdif_labels[5] = { |
456 | "Digital Playback", "ADAT", "Analog Mux 1", | 520 | "Digital Playback", "ADAT", "Analog Mux 1", |
457 | "Analog Mux 2", "Analog Mux 3" | 521 | "Analog Mux 2", "Analog Mux 3" |
@@ -478,6 +542,16 @@ static hda_nid_t stac9205_dmic_nids[STAC9205_NUM_DMICS + 1] = { | |||
478 | 0x17, 0x18, 0 | 542 | 0x17, 0x18, 0 |
479 | }; | 543 | }; |
480 | 544 | ||
545 | #define STAC9205_NUM_CAPS 2 | ||
546 | static unsigned long stac9205_capvols[] = { | ||
547 | HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_INPUT), | ||
548 | HDA_COMPOSE_AMP_VAL(0x1c, 3, 0, HDA_INPUT), | ||
549 | }; | ||
550 | static unsigned long stac9205_capsws[] = { | ||
551 | HDA_COMPOSE_AMP_VAL(0x1d, 3, 0, HDA_OUTPUT), | ||
552 | HDA_COMPOSE_AMP_VAL(0x1e, 3, 0, HDA_OUTPUT), | ||
553 | }; | ||
554 | |||
481 | static hda_nid_t stac9200_pin_nids[8] = { | 555 | static hda_nid_t stac9200_pin_nids[8] = { |
482 | 0x08, 0x09, 0x0d, 0x0e, | 556 | 0x08, 0x09, 0x0d, 0x0e, |
483 | 0x0f, 0x10, 0x11, 0x12, | 557 | 0x0f, 0x10, 0x11, 0x12, |
@@ -924,19 +998,6 @@ static struct hda_verb stac92hd71bxx_core_init[] = { | |||
924 | {} | 998 | {} |
925 | }; | 999 | }; |
926 | 1000 | ||
927 | #define HD_DISABLE_PORTF 1 | ||
928 | static struct hda_verb stac92hd71bxx_analog_core_init[] = { | ||
929 | /* start of config #1 */ | ||
930 | |||
931 | /* connect port 0f to audio mixer */ | ||
932 | { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x2}, | ||
933 | /* start of config #2 */ | ||
934 | |||
935 | /* set master volume and direct control */ | ||
936 | { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, | ||
937 | {} | ||
938 | }; | ||
939 | |||
940 | static struct hda_verb stac92hd71bxx_unmute_core_init[] = { | 1001 | static struct hda_verb stac92hd71bxx_unmute_core_init[] = { |
941 | /* unmute right and left channels for nodes 0x0f, 0xa, 0x0d */ | 1002 | /* unmute right and left channels for nodes 0x0f, 0xa, 0x0d */ |
942 | { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 1003 | { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
@@ -1069,12 +1130,6 @@ static struct snd_kcontrol_new stac92hd73xx_6ch_mixer[] = { | |||
1069 | HDA_CODEC_VOLUME("DAC Mixer Capture Volume", 0x1d, 0x3, HDA_INPUT), | 1130 | HDA_CODEC_VOLUME("DAC Mixer Capture Volume", 0x1d, 0x3, HDA_INPUT), |
1070 | HDA_CODEC_MUTE("DAC Mixer Capture Switch", 0x1d, 0x3, HDA_INPUT), | 1131 | HDA_CODEC_MUTE("DAC Mixer Capture Switch", 0x1d, 0x3, HDA_INPUT), |
1071 | 1132 | ||
1072 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x20, 0x0, HDA_OUTPUT), | ||
1073 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x20, 0x0, HDA_OUTPUT), | ||
1074 | |||
1075 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x21, 0x0, HDA_OUTPUT), | ||
1076 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x21, 0x0, HDA_OUTPUT), | ||
1077 | |||
1078 | { } /* end */ | 1133 | { } /* end */ |
1079 | }; | 1134 | }; |
1080 | 1135 | ||
@@ -1094,12 +1149,6 @@ static struct snd_kcontrol_new stac92hd73xx_10ch_loopback[] = { | |||
1094 | }; | 1149 | }; |
1095 | 1150 | ||
1096 | static struct snd_kcontrol_new stac92hd73xx_8ch_mixer[] = { | 1151 | static struct snd_kcontrol_new stac92hd73xx_8ch_mixer[] = { |
1097 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x20, 0x0, HDA_OUTPUT), | ||
1098 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x20, 0x0, HDA_OUTPUT), | ||
1099 | |||
1100 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x21, 0x0, HDA_OUTPUT), | ||
1101 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x21, 0x0, HDA_OUTPUT), | ||
1102 | |||
1103 | HDA_CODEC_VOLUME("Front Mic Mixer Capture Volume", 0x1d, 0, HDA_INPUT), | 1152 | HDA_CODEC_VOLUME("Front Mic Mixer Capture Volume", 0x1d, 0, HDA_INPUT), |
1104 | HDA_CODEC_MUTE("Front Mic Mixer Capture Switch", 0x1d, 0, HDA_INPUT), | 1153 | HDA_CODEC_MUTE("Front Mic Mixer Capture Switch", 0x1d, 0, HDA_INPUT), |
1105 | 1154 | ||
@@ -1118,12 +1167,6 @@ static struct snd_kcontrol_new stac92hd73xx_8ch_mixer[] = { | |||
1118 | }; | 1167 | }; |
1119 | 1168 | ||
1120 | static struct snd_kcontrol_new stac92hd73xx_10ch_mixer[] = { | 1169 | static struct snd_kcontrol_new stac92hd73xx_10ch_mixer[] = { |
1121 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x20, 0x0, HDA_OUTPUT), | ||
1122 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x20, 0x0, HDA_OUTPUT), | ||
1123 | |||
1124 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x21, 0x0, HDA_OUTPUT), | ||
1125 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x21, 0x0, HDA_OUTPUT), | ||
1126 | |||
1127 | HDA_CODEC_VOLUME("Front Mic Mixer Capture Volume", 0x1d, 0, HDA_INPUT), | 1170 | HDA_CODEC_VOLUME("Front Mic Mixer Capture Volume", 0x1d, 0, HDA_INPUT), |
1128 | HDA_CODEC_MUTE("Front Mic Mixer Capture Switch", 0x1d, 0, HDA_INPUT), | 1171 | HDA_CODEC_MUTE("Front Mic Mixer Capture Switch", 0x1d, 0, HDA_INPUT), |
1129 | 1172 | ||
@@ -1143,12 +1186,6 @@ static struct snd_kcontrol_new stac92hd73xx_10ch_mixer[] = { | |||
1143 | 1186 | ||
1144 | 1187 | ||
1145 | static struct snd_kcontrol_new stac92hd83xxx_mixer[] = { | 1188 | static struct snd_kcontrol_new stac92hd83xxx_mixer[] = { |
1146 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x17, 0x0, HDA_OUTPUT), | ||
1147 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x17, 0x0, HDA_OUTPUT), | ||
1148 | |||
1149 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x18, 0x0, HDA_OUTPUT), | ||
1150 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x18, 0x0, HDA_OUTPUT), | ||
1151 | |||
1152 | HDA_CODEC_VOLUME("DAC0 Capture Volume", 0x1b, 0x3, HDA_INPUT), | 1189 | HDA_CODEC_VOLUME("DAC0 Capture Volume", 0x1b, 0x3, HDA_INPUT), |
1153 | HDA_CODEC_MUTE("DAC0 Capture Switch", 0x1b, 0x3, HDA_INPUT), | 1190 | HDA_CODEC_MUTE("DAC0 Capture Switch", 0x1b, 0x3, HDA_INPUT), |
1154 | 1191 | ||
@@ -1169,17 +1206,6 @@ static struct snd_kcontrol_new stac92hd83xxx_mixer[] = { | |||
1169 | }; | 1206 | }; |
1170 | 1207 | ||
1171 | static struct snd_kcontrol_new stac92hd71bxx_analog_mixer[] = { | 1208 | static struct snd_kcontrol_new stac92hd71bxx_analog_mixer[] = { |
1172 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1c, 0x0, HDA_OUTPUT), | ||
1173 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1c, 0x0, HDA_OUTPUT), | ||
1174 | |||
1175 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x1d, 0x0, HDA_OUTPUT), | ||
1176 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1d, 0x0, HDA_OUTPUT), | ||
1177 | /* analog pc-beep replaced with digital beep support */ | ||
1178 | /* | ||
1179 | HDA_CODEC_VOLUME("PC Beep Volume", 0x17, 0x2, HDA_INPUT), | ||
1180 | HDA_CODEC_MUTE("PC Beep Switch", 0x17, 0x2, HDA_INPUT), | ||
1181 | */ | ||
1182 | |||
1183 | HDA_CODEC_MUTE("Import0 Mux Capture Switch", 0x17, 0x0, HDA_INPUT), | 1209 | HDA_CODEC_MUTE("Import0 Mux Capture Switch", 0x17, 0x0, HDA_INPUT), |
1184 | HDA_CODEC_VOLUME("Import0 Mux Capture Volume", 0x17, 0x0, HDA_INPUT), | 1210 | HDA_CODEC_VOLUME("Import0 Mux Capture Volume", 0x17, 0x0, HDA_INPUT), |
1185 | 1211 | ||
@@ -1198,29 +1224,9 @@ static struct snd_kcontrol_new stac92hd71bxx_loopback[] = { | |||
1198 | STAC_ANALOG_LOOPBACK(0xFA0, 0x7A0, 2) | 1224 | STAC_ANALOG_LOOPBACK(0xFA0, 0x7A0, 2) |
1199 | }; | 1225 | }; |
1200 | 1226 | ||
1201 | static struct snd_kcontrol_new stac92hd71bxx_mixer[] = { | ||
1202 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1c, 0x0, HDA_OUTPUT), | ||
1203 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1c, 0x0, HDA_OUTPUT), | ||
1204 | |||
1205 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x1d, 0x0, HDA_OUTPUT), | ||
1206 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1d, 0x0, HDA_OUTPUT), | ||
1207 | { } /* end */ | ||
1208 | }; | ||
1209 | |||
1210 | static struct snd_kcontrol_new stac925x_mixer[] = { | 1227 | static struct snd_kcontrol_new stac925x_mixer[] = { |
1211 | HDA_CODEC_VOLUME("Master Playback Volume", 0x0e, 0, HDA_OUTPUT), | 1228 | HDA_CODEC_VOLUME("Master Playback Volume", 0x0e, 0, HDA_OUTPUT), |
1212 | HDA_CODEC_MUTE("Master Playback Switch", 0x0e, 0, HDA_OUTPUT), | 1229 | HDA_CODEC_MUTE("Master Playback Switch", 0x0e, 0, HDA_OUTPUT), |
1213 | HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_OUTPUT), | ||
1214 | HDA_CODEC_MUTE("Capture Switch", 0x14, 0, HDA_OUTPUT), | ||
1215 | { } /* end */ | ||
1216 | }; | ||
1217 | |||
1218 | static struct snd_kcontrol_new stac9205_mixer[] = { | ||
1219 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1b, 0x0, HDA_INPUT), | ||
1220 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1d, 0x0, HDA_OUTPUT), | ||
1221 | |||
1222 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x1c, 0x0, HDA_INPUT), | ||
1223 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1e, 0x0, HDA_OUTPUT), | ||
1224 | { } /* end */ | 1230 | { } /* end */ |
1225 | }; | 1231 | }; |
1226 | 1232 | ||
@@ -1229,29 +1235,6 @@ static struct snd_kcontrol_new stac9205_loopback[] = { | |||
1229 | {} | 1235 | {} |
1230 | }; | 1236 | }; |
1231 | 1237 | ||
1232 | /* This needs to be generated dynamically based on sequence */ | ||
1233 | static struct snd_kcontrol_new stac922x_mixer[] = { | ||
1234 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x17, 0x0, HDA_INPUT), | ||
1235 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x17, 0x0, HDA_INPUT), | ||
1236 | |||
1237 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x18, 0x0, HDA_INPUT), | ||
1238 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x18, 0x0, HDA_INPUT), | ||
1239 | { } /* end */ | ||
1240 | }; | ||
1241 | |||
1242 | |||
1243 | static struct snd_kcontrol_new stac927x_mixer[] = { | ||
1244 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x18, 0x0, HDA_INPUT), | ||
1245 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1b, 0x0, HDA_OUTPUT), | ||
1246 | |||
1247 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x19, 0x0, HDA_INPUT), | ||
1248 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1c, 0x0, HDA_OUTPUT), | ||
1249 | |||
1250 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x2, 0x1A, 0x0, HDA_INPUT), | ||
1251 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x2, 0x1d, 0x0, HDA_OUTPUT), | ||
1252 | { } /* end */ | ||
1253 | }; | ||
1254 | |||
1255 | static struct snd_kcontrol_new stac927x_loopback[] = { | 1238 | static struct snd_kcontrol_new stac927x_loopback[] = { |
1256 | STAC_ANALOG_LOOPBACK(0xFEB, 0x7EB, 1), | 1239 | STAC_ANALOG_LOOPBACK(0xFEB, 0x7EB, 1), |
1257 | {} | 1240 | {} |
@@ -1309,16 +1292,18 @@ static int stac92xx_build_controls(struct hda_codec *codec) | |||
1309 | int err; | 1292 | int err; |
1310 | int i; | 1293 | int i; |
1311 | 1294 | ||
1312 | err = snd_hda_add_new_ctls(codec, spec->mixer); | 1295 | if (spec->mixer) { |
1313 | if (err < 0) | 1296 | err = snd_hda_add_new_ctls(codec, spec->mixer); |
1314 | return err; | 1297 | if (err < 0) |
1298 | return err; | ||
1299 | } | ||
1315 | 1300 | ||
1316 | for (i = 0; i < spec->num_mixers; i++) { | 1301 | for (i = 0; i < spec->num_mixers; i++) { |
1317 | err = snd_hda_add_new_ctls(codec, spec->mixers[i]); | 1302 | err = snd_hda_add_new_ctls(codec, spec->mixers[i]); |
1318 | if (err < 0) | 1303 | if (err < 0) |
1319 | return err; | 1304 | return err; |
1320 | } | 1305 | } |
1321 | if (spec->num_dmuxes > 0) { | 1306 | if (!spec->auto_mic && spec->num_dmuxes > 0) { |
1322 | stac_dmux_mixer.count = spec->num_dmuxes; | 1307 | stac_dmux_mixer.count = spec->num_dmuxes; |
1323 | err = snd_hda_ctl_add(codec, | 1308 | err = snd_hda_ctl_add(codec, |
1324 | snd_ctl_new1(&stac_dmux_mixer, codec)); | 1309 | snd_ctl_new1(&stac_dmux_mixer, codec)); |
@@ -1590,8 +1575,6 @@ static struct snd_pci_quirk stac9200_cfg_tbl[] = { | |||
1590 | /* SigmaTel reference board */ | 1575 | /* SigmaTel reference board */ |
1591 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, | 1576 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, |
1592 | "DFI LanParty", STAC_REF), | 1577 | "DFI LanParty", STAC_REF), |
1593 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0xfb30, | ||
1594 | "SigmaTel",STAC_9205_REF), | ||
1595 | SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, | 1578 | SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, |
1596 | "DFI LanParty", STAC_REF), | 1579 | "DFI LanParty", STAC_REF), |
1597 | /* Dell laptops have BIOS problem */ | 1580 | /* Dell laptops have BIOS problem */ |
@@ -1811,6 +1794,8 @@ static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = { | |||
1811 | "Dell Studio 1537", STAC_DELL_M6_DMIC), | 1794 | "Dell Studio 1537", STAC_DELL_M6_DMIC), |
1812 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02a0, | 1795 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02a0, |
1813 | "Dell Studio 17", STAC_DELL_M6_DMIC), | 1796 | "Dell Studio 17", STAC_DELL_M6_DMIC), |
1797 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02be, | ||
1798 | "Dell Studio 1555", STAC_DELL_M6_DMIC), | ||
1814 | {} /* terminator */ | 1799 | {} /* terminator */ |
1815 | }; | 1800 | }; |
1816 | 1801 | ||
@@ -2344,6 +2329,8 @@ static struct snd_pci_quirk stac9205_cfg_tbl[] = { | |||
2344 | /* SigmaTel reference board */ | 2329 | /* SigmaTel reference board */ |
2345 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, | 2330 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, |
2346 | "DFI LanParty", STAC_9205_REF), | 2331 | "DFI LanParty", STAC_9205_REF), |
2332 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0xfb30, | ||
2333 | "SigmaTel", STAC_9205_REF), | ||
2347 | SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, | 2334 | SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, |
2348 | "DFI LanParty", STAC_9205_REF), | 2335 | "DFI LanParty", STAC_9205_REF), |
2349 | /* Dell */ | 2336 | /* Dell */ |
@@ -2378,6 +2365,7 @@ static struct snd_pci_quirk stac9205_cfg_tbl[] = { | |||
2378 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0228, | 2365 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0228, |
2379 | "Dell Vostro 1500", STAC_9205_DELL_M42), | 2366 | "Dell Vostro 1500", STAC_9205_DELL_M42), |
2380 | /* Gateway */ | 2367 | /* Gateway */ |
2368 | SND_PCI_QUIRK(0x107b, 0x0560, "Gateway T6834c", STAC_9205_EAPD), | ||
2381 | SND_PCI_QUIRK(0x107b, 0x0565, "Gateway T1616", STAC_9205_EAPD), | 2369 | SND_PCI_QUIRK(0x107b, 0x0565, "Gateway T1616", STAC_9205_EAPD), |
2382 | {} /* terminator */ | 2370 | {} /* terminator */ |
2383 | }; | 2371 | }; |
@@ -2633,8 +2621,7 @@ static int stac92xx_hp_switch_get(struct snd_kcontrol *kcontrol, | |||
2633 | return 0; | 2621 | return 0; |
2634 | } | 2622 | } |
2635 | 2623 | ||
2636 | static void stac_issue_unsol_event(struct hda_codec *codec, hda_nid_t nid, | 2624 | static void stac_issue_unsol_event(struct hda_codec *codec, hda_nid_t nid); |
2637 | unsigned char type); | ||
2638 | 2625 | ||
2639 | static int stac92xx_hp_switch_put(struct snd_kcontrol *kcontrol, | 2626 | static int stac92xx_hp_switch_put(struct snd_kcontrol *kcontrol, |
2640 | struct snd_ctl_elem_value *ucontrol) | 2627 | struct snd_ctl_elem_value *ucontrol) |
@@ -2648,7 +2635,7 @@ static int stac92xx_hp_switch_put(struct snd_kcontrol *kcontrol, | |||
2648 | /* check to be sure that the ports are upto date with | 2635 | /* check to be sure that the ports are upto date with |
2649 | * switch changes | 2636 | * switch changes |
2650 | */ | 2637 | */ |
2651 | stac_issue_unsol_event(codec, nid, STAC_HP_EVENT); | 2638 | stac_issue_unsol_event(codec, nid); |
2652 | 2639 | ||
2653 | return 1; | 2640 | return 1; |
2654 | } | 2641 | } |
@@ -2781,7 +2768,7 @@ static int stac92xx_io_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ | |||
2781 | * appropriately according to the pin direction | 2768 | * appropriately according to the pin direction |
2782 | */ | 2769 | */ |
2783 | if (spec->hp_detect) | 2770 | if (spec->hp_detect) |
2784 | stac_issue_unsol_event(codec, nid, STAC_HP_EVENT); | 2771 | stac_issue_unsol_event(codec, nid); |
2785 | 2772 | ||
2786 | return 1; | 2773 | return 1; |
2787 | } | 2774 | } |
@@ -2964,6 +2951,8 @@ static int stac92xx_add_input_source(struct sigmatel_spec *spec) | |||
2964 | struct snd_kcontrol_new *knew; | 2951 | struct snd_kcontrol_new *knew; |
2965 | struct hda_input_mux *imux = &spec->private_imux; | 2952 | struct hda_input_mux *imux = &spec->private_imux; |
2966 | 2953 | ||
2954 | if (spec->auto_mic) | ||
2955 | return 0; /* no need for input source */ | ||
2967 | if (!spec->num_adcs || imux->num_items <= 1) | 2956 | if (!spec->num_adcs || imux->num_items <= 1) |
2968 | return 0; /* no need for input source control */ | 2957 | return 0; /* no need for input source control */ |
2969 | knew = stac_control_new(spec, &stac_input_src_temp, | 2958 | knew = stac_control_new(spec, &stac_input_src_temp, |
@@ -3057,7 +3046,7 @@ static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t nid) | |||
3057 | HDA_MAX_CONNECTIONS); | 3046 | HDA_MAX_CONNECTIONS); |
3058 | for (j = 0; j < conn_len; j++) { | 3047 | for (j = 0; j < conn_len; j++) { |
3059 | wcaps = get_wcaps(codec, conn[j]); | 3048 | wcaps = get_wcaps(codec, conn[j]); |
3060 | wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; | 3049 | wtype = get_wcaps_type(wcaps); |
3061 | /* we check only analog outputs */ | 3050 | /* we check only analog outputs */ |
3062 | if (wtype != AC_WID_AUD_OUT || (wcaps & AC_WCAP_DIGITAL)) | 3051 | if (wtype != AC_WID_AUD_OUT || (wcaps & AC_WCAP_DIGITAL)) |
3063 | continue; | 3052 | continue; |
@@ -3316,6 +3305,21 @@ static int create_multi_out_ctls(struct hda_codec *codec, int num_outs, | |||
3316 | return 0; | 3305 | return 0; |
3317 | } | 3306 | } |
3318 | 3307 | ||
3308 | static int stac92xx_add_capvol_ctls(struct hda_codec *codec, unsigned long vol, | ||
3309 | unsigned long sw, int idx) | ||
3310 | { | ||
3311 | int err; | ||
3312 | err = stac92xx_add_control_idx(codec->spec, STAC_CTL_WIDGET_VOL, idx, | ||
3313 | "Capture Volume", vol); | ||
3314 | if (err < 0) | ||
3315 | return err; | ||
3316 | err = stac92xx_add_control_idx(codec->spec, STAC_CTL_WIDGET_MUTE, idx, | ||
3317 | "Capture Switch", sw); | ||
3318 | if (err < 0) | ||
3319 | return err; | ||
3320 | return 0; | ||
3321 | } | ||
3322 | |||
3319 | /* add playback controls from the parsed DAC table */ | 3323 | /* add playback controls from the parsed DAC table */ |
3320 | static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec, | 3324 | static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec, |
3321 | const struct auto_pin_cfg *cfg) | 3325 | const struct auto_pin_cfg *cfg) |
@@ -3389,7 +3393,7 @@ static int stac92xx_auto_create_mono_output_ctls(struct hda_codec *codec) | |||
3389 | spec->mono_nid, | 3393 | spec->mono_nid, |
3390 | con_lst, | 3394 | con_lst, |
3391 | HDA_MAX_NUM_INPUTS); | 3395 | HDA_MAX_NUM_INPUTS); |
3392 | if (!num_cons || num_cons > ARRAY_SIZE(stac92xx_mono_labels)) | 3396 | if (num_cons <= 0 || num_cons > ARRAY_SIZE(stac92xx_mono_labels)) |
3393 | return -EINVAL; | 3397 | return -EINVAL; |
3394 | 3398 | ||
3395 | for (i = 0; i < num_cons; i++) { | 3399 | for (i = 0; i < num_cons; i++) { |
@@ -3535,7 +3539,7 @@ static int stac92xx_auto_create_spdif_mux_ctls(struct hda_codec *codec) | |||
3535 | spec->smux_nids[0], | 3539 | spec->smux_nids[0], |
3536 | con_lst, | 3540 | con_lst, |
3537 | HDA_MAX_NUM_INPUTS); | 3541 | HDA_MAX_NUM_INPUTS); |
3538 | if (!num_cons) | 3542 | if (num_cons <= 0) |
3539 | return -EINVAL; | 3543 | return -EINVAL; |
3540 | 3544 | ||
3541 | if (!labels) | 3545 | if (!labels) |
@@ -3556,14 +3560,26 @@ static const char *stac92xx_dmic_labels[5] = { | |||
3556 | "Digital Mic 3", "Digital Mic 4" | 3560 | "Digital Mic 3", "Digital Mic 4" |
3557 | }; | 3561 | }; |
3558 | 3562 | ||
3563 | static int get_connection_index(struct hda_codec *codec, hda_nid_t mux, | ||
3564 | hda_nid_t nid) | ||
3565 | { | ||
3566 | hda_nid_t conn[HDA_MAX_NUM_INPUTS]; | ||
3567 | int i, nums; | ||
3568 | |||
3569 | nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn)); | ||
3570 | for (i = 0; i < nums; i++) | ||
3571 | if (conn[i] == nid) | ||
3572 | return i; | ||
3573 | return -1; | ||
3574 | } | ||
3575 | |||
3559 | /* create playback/capture controls for input pins on dmic capable codecs */ | 3576 | /* create playback/capture controls for input pins on dmic capable codecs */ |
3560 | static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec, | 3577 | static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec, |
3561 | const struct auto_pin_cfg *cfg) | 3578 | const struct auto_pin_cfg *cfg) |
3562 | { | 3579 | { |
3563 | struct sigmatel_spec *spec = codec->spec; | 3580 | struct sigmatel_spec *spec = codec->spec; |
3564 | struct hda_input_mux *dimux = &spec->private_dimux; | 3581 | struct hda_input_mux *dimux = &spec->private_dimux; |
3565 | hda_nid_t con_lst[HDA_MAX_NUM_INPUTS]; | 3582 | int err, i; |
3566 | int err, i, j; | ||
3567 | char name[32]; | 3583 | char name[32]; |
3568 | 3584 | ||
3569 | dimux->items[dimux->num_items].label = stac92xx_dmic_labels[0]; | 3585 | dimux->items[dimux->num_items].label = stac92xx_dmic_labels[0]; |
@@ -3573,7 +3589,6 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec, | |||
3573 | for (i = 0; i < spec->num_dmics; i++) { | 3589 | for (i = 0; i < spec->num_dmics; i++) { |
3574 | hda_nid_t nid; | 3590 | hda_nid_t nid; |
3575 | int index; | 3591 | int index; |
3576 | int num_cons; | ||
3577 | unsigned int wcaps; | 3592 | unsigned int wcaps; |
3578 | unsigned int def_conf; | 3593 | unsigned int def_conf; |
3579 | 3594 | ||
@@ -3582,17 +3597,10 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec, | |||
3582 | continue; | 3597 | continue; |
3583 | 3598 | ||
3584 | nid = spec->dmic_nids[i]; | 3599 | nid = spec->dmic_nids[i]; |
3585 | num_cons = snd_hda_get_connections(codec, | 3600 | index = get_connection_index(codec, spec->dmux_nids[0], nid); |
3586 | spec->dmux_nids[0], | 3601 | if (index < 0) |
3587 | con_lst, | 3602 | continue; |
3588 | HDA_MAX_NUM_INPUTS); | 3603 | |
3589 | for (j = 0; j < num_cons; j++) | ||
3590 | if (con_lst[j] == nid) { | ||
3591 | index = j; | ||
3592 | goto found; | ||
3593 | } | ||
3594 | continue; | ||
3595 | found: | ||
3596 | wcaps = get_wcaps(codec, nid) & | 3604 | wcaps = get_wcaps(codec, nid) & |
3597 | (AC_WCAP_OUT_AMP | AC_WCAP_IN_AMP); | 3605 | (AC_WCAP_OUT_AMP | AC_WCAP_IN_AMP); |
3598 | 3606 | ||
@@ -3619,6 +3627,88 @@ found: | |||
3619 | return 0; | 3627 | return 0; |
3620 | } | 3628 | } |
3621 | 3629 | ||
3630 | static int check_mic_pin(struct hda_codec *codec, hda_nid_t nid, | ||
3631 | hda_nid_t *fixed, hda_nid_t *ext) | ||
3632 | { | ||
3633 | unsigned int cfg; | ||
3634 | |||
3635 | if (!nid) | ||
3636 | return 0; | ||
3637 | cfg = snd_hda_codec_get_pincfg(codec, nid); | ||
3638 | switch (get_defcfg_connect(cfg)) { | ||
3639 | case AC_JACK_PORT_FIXED: | ||
3640 | if (*fixed) | ||
3641 | return 1; /* already occupied */ | ||
3642 | *fixed = nid; | ||
3643 | break; | ||
3644 | case AC_JACK_PORT_COMPLEX: | ||
3645 | if (*ext) | ||
3646 | return 1; /* already occupied */ | ||
3647 | *ext = nid; | ||
3648 | break; | ||
3649 | } | ||
3650 | return 0; | ||
3651 | } | ||
3652 | |||
3653 | static int set_mic_route(struct hda_codec *codec, | ||
3654 | struct sigmatel_mic_route *mic, | ||
3655 | hda_nid_t pin) | ||
3656 | { | ||
3657 | struct sigmatel_spec *spec = codec->spec; | ||
3658 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
3659 | int i; | ||
3660 | |||
3661 | mic->pin = pin; | ||
3662 | for (i = AUTO_PIN_MIC; i <= AUTO_PIN_FRONT_MIC; i++) | ||
3663 | if (pin == cfg->input_pins[i]) | ||
3664 | break; | ||
3665 | if (i <= AUTO_PIN_FRONT_MIC) { | ||
3666 | /* analog pin */ | ||
3667 | mic->dmux_idx = 0; | ||
3668 | i = get_connection_index(codec, spec->mux_nids[0], pin); | ||
3669 | if (i < 0) | ||
3670 | return -1; | ||
3671 | mic->mux_idx = i; | ||
3672 | } else { | ||
3673 | /* digital pin */ | ||
3674 | mic->mux_idx = 0; | ||
3675 | i = get_connection_index(codec, spec->dmux_nids[0], pin); | ||
3676 | if (i < 0) | ||
3677 | return -1; | ||
3678 | mic->dmux_idx = i; | ||
3679 | } | ||
3680 | return 0; | ||
3681 | } | ||
3682 | |||
3683 | /* return non-zero if the device is for automatic mic switch */ | ||
3684 | static int stac_check_auto_mic(struct hda_codec *codec) | ||
3685 | { | ||
3686 | struct sigmatel_spec *spec = codec->spec; | ||
3687 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
3688 | hda_nid_t fixed, ext; | ||
3689 | int i; | ||
3690 | |||
3691 | for (i = AUTO_PIN_LINE; i < AUTO_PIN_LAST; i++) { | ||
3692 | if (cfg->input_pins[i]) | ||
3693 | return 0; /* must be exclusively mics */ | ||
3694 | } | ||
3695 | fixed = ext = 0; | ||
3696 | for (i = AUTO_PIN_MIC; i <= AUTO_PIN_FRONT_MIC; i++) | ||
3697 | if (check_mic_pin(codec, cfg->input_pins[i], &fixed, &ext)) | ||
3698 | return 0; | ||
3699 | for (i = 0; i < spec->num_dmics; i++) | ||
3700 | if (check_mic_pin(codec, spec->dmic_nids[i], &fixed, &ext)) | ||
3701 | return 0; | ||
3702 | if (!fixed || !ext) | ||
3703 | return 0; | ||
3704 | if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP)) | ||
3705 | return 0; /* no unsol support */ | ||
3706 | if (set_mic_route(codec, &spec->ext_mic, ext) || | ||
3707 | set_mic_route(codec, &spec->int_mic, fixed)) | ||
3708 | return 0; /* something is wrong */ | ||
3709 | return 1; | ||
3710 | } | ||
3711 | |||
3622 | /* create playback/capture controls for input pins */ | 3712 | /* create playback/capture controls for input pins */ |
3623 | static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg) | 3713 | static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg) |
3624 | { | 3714 | { |
@@ -3702,7 +3792,7 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out | |||
3702 | { | 3792 | { |
3703 | struct sigmatel_spec *spec = codec->spec; | 3793 | struct sigmatel_spec *spec = codec->spec; |
3704 | int hp_swap = 0; | 3794 | int hp_swap = 0; |
3705 | int err; | 3795 | int i, err; |
3706 | 3796 | ||
3707 | if ((err = snd_hda_parse_pin_def_config(codec, | 3797 | if ((err = snd_hda_parse_pin_def_config(codec, |
3708 | &spec->autocfg, | 3798 | &spec->autocfg, |
@@ -3742,11 +3832,10 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out | |||
3742 | if (snd_hda_get_connections(codec, | 3832 | if (snd_hda_get_connections(codec, |
3743 | spec->autocfg.mono_out_pin, conn_list, 1) && | 3833 | spec->autocfg.mono_out_pin, conn_list, 1) && |
3744 | snd_hda_get_connections(codec, conn_list[0], | 3834 | snd_hda_get_connections(codec, conn_list[0], |
3745 | conn_list, 1)) { | 3835 | conn_list, 1) > 0) { |
3746 | 3836 | ||
3747 | int wcaps = get_wcaps(codec, conn_list[0]); | 3837 | int wcaps = get_wcaps(codec, conn_list[0]); |
3748 | int wid_type = (wcaps & AC_WCAP_TYPE) | 3838 | int wid_type = get_wcaps_type(wcaps); |
3749 | >> AC_WCAP_TYPE_SHIFT; | ||
3750 | /* LR swap check, some stac925x have a mux that | 3839 | /* LR swap check, some stac925x have a mux that |
3751 | * changes the DACs output path instead of the | 3840 | * changes the DACs output path instead of the |
3752 | * mono-mux path. | 3841 | * mono-mux path. |
@@ -3837,6 +3926,21 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out | |||
3837 | spec->autocfg.line_outs = 0; | 3926 | spec->autocfg.line_outs = 0; |
3838 | } | 3927 | } |
3839 | 3928 | ||
3929 | if (stac_check_auto_mic(codec)) { | ||
3930 | spec->auto_mic = 1; | ||
3931 | /* only one capture for auto-mic */ | ||
3932 | spec->num_adcs = 1; | ||
3933 | spec->num_caps = 1; | ||
3934 | spec->num_muxes = 1; | ||
3935 | } | ||
3936 | |||
3937 | for (i = 0; i < spec->num_caps; i++) { | ||
3938 | err = stac92xx_add_capvol_ctls(codec, spec->capvols[i], | ||
3939 | spec->capsws[i], i); | ||
3940 | if (err < 0) | ||
3941 | return err; | ||
3942 | } | ||
3943 | |||
3840 | err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg); | 3944 | err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg); |
3841 | if (err < 0) | 3945 | if (err < 0) |
3842 | return err; | 3946 | return err; |
@@ -4065,7 +4169,7 @@ static int stac92xx_add_jack(struct hda_codec *codec, | |||
4065 | jack->nid = nid; | 4169 | jack->nid = nid; |
4066 | jack->type = type; | 4170 | jack->type = type; |
4067 | 4171 | ||
4068 | sprintf(name, "%s at %s %s Jack", | 4172 | snprintf(name, sizeof(name), "%s at %s %s Jack", |
4069 | snd_hda_get_jack_type(def_conf), | 4173 | snd_hda_get_jack_type(def_conf), |
4070 | snd_hda_get_jack_connectivity(def_conf), | 4174 | snd_hda_get_jack_connectivity(def_conf), |
4071 | snd_hda_get_jack_location(def_conf)); | 4175 | snd_hda_get_jack_location(def_conf)); |
@@ -4099,14 +4203,14 @@ static int stac_add_event(struct sigmatel_spec *spec, hda_nid_t nid, | |||
4099 | } | 4203 | } |
4100 | 4204 | ||
4101 | static struct sigmatel_event *stac_get_event(struct hda_codec *codec, | 4205 | static struct sigmatel_event *stac_get_event(struct hda_codec *codec, |
4102 | hda_nid_t nid, unsigned char type) | 4206 | hda_nid_t nid) |
4103 | { | 4207 | { |
4104 | struct sigmatel_spec *spec = codec->spec; | 4208 | struct sigmatel_spec *spec = codec->spec; |
4105 | struct sigmatel_event *event = spec->events.list; | 4209 | struct sigmatel_event *event = spec->events.list; |
4106 | int i; | 4210 | int i; |
4107 | 4211 | ||
4108 | for (i = 0; i < spec->events.used; i++, event++) { | 4212 | for (i = 0; i < spec->events.used; i++, event++) { |
4109 | if (event->nid == nid && event->type == type) | 4213 | if (event->nid == nid) |
4110 | return event; | 4214 | return event; |
4111 | } | 4215 | } |
4112 | return NULL; | 4216 | return NULL; |
@@ -4126,24 +4230,32 @@ static struct sigmatel_event *stac_get_event_from_tag(struct hda_codec *codec, | |||
4126 | return NULL; | 4230 | return NULL; |
4127 | } | 4231 | } |
4128 | 4232 | ||
4129 | static void enable_pin_detect(struct hda_codec *codec, hda_nid_t nid, | 4233 | /* check if given nid is a valid pin and no other events are assigned |
4130 | unsigned int type) | 4234 | * to it. If OK, assign the event, set the unsol flag, and returns 1. |
4235 | * Otherwise, returns zero. | ||
4236 | */ | ||
4237 | static int enable_pin_detect(struct hda_codec *codec, hda_nid_t nid, | ||
4238 | unsigned int type) | ||
4131 | { | 4239 | { |
4132 | struct sigmatel_event *event; | 4240 | struct sigmatel_event *event; |
4133 | int tag; | 4241 | int tag; |
4134 | 4242 | ||
4135 | if (!(get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP)) | 4243 | if (!(get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP)) |
4136 | return; | 4244 | return 0; |
4137 | event = stac_get_event(codec, nid, type); | 4245 | event = stac_get_event(codec, nid); |
4138 | if (event) | 4246 | if (event) { |
4247 | if (event->type != type) | ||
4248 | return 0; | ||
4139 | tag = event->tag; | 4249 | tag = event->tag; |
4140 | else | 4250 | } else { |
4141 | tag = stac_add_event(codec->spec, nid, type, 0); | 4251 | tag = stac_add_event(codec->spec, nid, type, 0); |
4142 | if (tag < 0) | 4252 | if (tag < 0) |
4143 | return; | 4253 | return 0; |
4254 | } | ||
4144 | snd_hda_codec_write_cache(codec, nid, 0, | 4255 | snd_hda_codec_write_cache(codec, nid, 0, |
4145 | AC_VERB_SET_UNSOLICITED_ENABLE, | 4256 | AC_VERB_SET_UNSOLICITED_ENABLE, |
4146 | AC_USRSP_EN | tag); | 4257 | AC_USRSP_EN | tag); |
4258 | return 1; | ||
4147 | } | 4259 | } |
4148 | 4260 | ||
4149 | static int is_nid_hp_pin(struct auto_pin_cfg *cfg, hda_nid_t nid) | 4261 | static int is_nid_hp_pin(struct auto_pin_cfg *cfg, hda_nid_t nid) |
@@ -4236,20 +4348,34 @@ static int stac92xx_init(struct hda_codec *codec) | |||
4236 | hda_nid_t nid = cfg->hp_pins[i]; | 4348 | hda_nid_t nid = cfg->hp_pins[i]; |
4237 | enable_pin_detect(codec, nid, STAC_HP_EVENT); | 4349 | enable_pin_detect(codec, nid, STAC_HP_EVENT); |
4238 | } | 4350 | } |
4351 | if (cfg->line_out_type == AUTO_PIN_LINE_OUT) { | ||
4352 | /* enable pin-detect for line-outs as well */ | ||
4353 | for (i = 0; i < cfg->hp_outs; i++) { | ||
4354 | hda_nid_t nid = cfg->hp_pins[i]; | ||
4355 | enable_pin_detect(codec, nid, STAC_LO_EVENT); | ||
4356 | } | ||
4357 | } | ||
4358 | |||
4239 | /* force to enable the first line-out; the others are set up | 4359 | /* force to enable the first line-out; the others are set up |
4240 | * in unsol_event | 4360 | * in unsol_event |
4241 | */ | 4361 | */ |
4242 | stac92xx_auto_set_pinctl(codec, spec->autocfg.line_out_pins[0], | 4362 | stac92xx_auto_set_pinctl(codec, spec->autocfg.line_out_pins[0], |
4243 | AC_PINCTL_OUT_EN); | 4363 | AC_PINCTL_OUT_EN); |
4244 | /* fake event to set up pins */ | 4364 | /* fake event to set up pins */ |
4245 | stac_issue_unsol_event(codec, spec->autocfg.hp_pins[0], | 4365 | stac_issue_unsol_event(codec, spec->autocfg.hp_pins[0]); |
4246 | STAC_HP_EVENT); | ||
4247 | } else { | 4366 | } else { |
4248 | stac92xx_auto_init_multi_out(codec); | 4367 | stac92xx_auto_init_multi_out(codec); |
4249 | stac92xx_auto_init_hp_out(codec); | 4368 | stac92xx_auto_init_hp_out(codec); |
4250 | for (i = 0; i < cfg->hp_outs; i++) | 4369 | for (i = 0; i < cfg->hp_outs; i++) |
4251 | stac_toggle_power_map(codec, cfg->hp_pins[i], 1); | 4370 | stac_toggle_power_map(codec, cfg->hp_pins[i], 1); |
4252 | } | 4371 | } |
4372 | if (spec->auto_mic) { | ||
4373 | /* initialize connection to analog input */ | ||
4374 | snd_hda_codec_write_cache(codec, spec->dmux_nids[0], 0, | ||
4375 | AC_VERB_SET_CONNECT_SEL, 0); | ||
4376 | if (enable_pin_detect(codec, spec->ext_mic.pin, STAC_MIC_EVENT)) | ||
4377 | stac_issue_unsol_event(codec, spec->ext_mic.pin); | ||
4378 | } | ||
4253 | for (i = 0; i < AUTO_PIN_LAST; i++) { | 4379 | for (i = 0; i < AUTO_PIN_LAST; i++) { |
4254 | hda_nid_t nid = cfg->input_pins[i]; | 4380 | hda_nid_t nid = cfg->input_pins[i]; |
4255 | if (nid) { | 4381 | if (nid) { |
@@ -4276,10 +4402,9 @@ static int stac92xx_init(struct hda_codec *codec) | |||
4276 | } | 4402 | } |
4277 | conf = snd_hda_codec_get_pincfg(codec, nid); | 4403 | conf = snd_hda_codec_get_pincfg(codec, nid); |
4278 | if (get_defcfg_connect(conf) != AC_JACK_PORT_FIXED) { | 4404 | if (get_defcfg_connect(conf) != AC_JACK_PORT_FIXED) { |
4279 | enable_pin_detect(codec, nid, | 4405 | if (enable_pin_detect(codec, nid, |
4280 | STAC_INSERT_EVENT); | 4406 | STAC_INSERT_EVENT)) |
4281 | stac_issue_unsol_event(codec, nid, | 4407 | stac_issue_unsol_event(codec, nid); |
4282 | STAC_INSERT_EVENT); | ||
4283 | } | 4408 | } |
4284 | } | 4409 | } |
4285 | } | 4410 | } |
@@ -4324,10 +4449,8 @@ static int stac92xx_init(struct hda_codec *codec) | |||
4324 | stac_toggle_power_map(codec, nid, 1); | 4449 | stac_toggle_power_map(codec, nid, 1); |
4325 | continue; | 4450 | continue; |
4326 | } | 4451 | } |
4327 | if (!stac_get_event(codec, nid, STAC_INSERT_EVENT)) { | 4452 | if (enable_pin_detect(codec, nid, STAC_PWR_EVENT)) |
4328 | enable_pin_detect(codec, nid, STAC_PWR_EVENT); | 4453 | stac_issue_unsol_event(codec, nid); |
4329 | stac_issue_unsol_event(codec, nid, STAC_PWR_EVENT); | ||
4330 | } | ||
4331 | } | 4454 | } |
4332 | if (spec->dac_list) | 4455 | if (spec->dac_list) |
4333 | stac92xx_power_down(codec); | 4456 | stac92xx_power_down(codec); |
@@ -4431,6 +4554,48 @@ static int get_pin_presence(struct hda_codec *codec, hda_nid_t nid) | |||
4431 | return 0; | 4554 | return 0; |
4432 | } | 4555 | } |
4433 | 4556 | ||
4557 | static void stac92xx_line_out_detect(struct hda_codec *codec, | ||
4558 | int presence) | ||
4559 | { | ||
4560 | struct sigmatel_spec *spec = codec->spec; | ||
4561 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
4562 | int i; | ||
4563 | |||
4564 | for (i = 0; i < cfg->line_outs; i++) { | ||
4565 | if (presence) | ||
4566 | break; | ||
4567 | presence = get_pin_presence(codec, cfg->line_out_pins[i]); | ||
4568 | if (presence) { | ||
4569 | unsigned int pinctl; | ||
4570 | pinctl = snd_hda_codec_read(codec, | ||
4571 | cfg->line_out_pins[i], 0, | ||
4572 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | ||
4573 | if (pinctl & AC_PINCTL_IN_EN) | ||
4574 | presence = 0; /* mic- or line-input */ | ||
4575 | } | ||
4576 | } | ||
4577 | |||
4578 | if (presence) { | ||
4579 | /* disable speakers */ | ||
4580 | for (i = 0; i < cfg->speaker_outs; i++) | ||
4581 | stac92xx_reset_pinctl(codec, cfg->speaker_pins[i], | ||
4582 | AC_PINCTL_OUT_EN); | ||
4583 | if (spec->eapd_mask && spec->eapd_switch) | ||
4584 | stac_gpio_set(codec, spec->gpio_mask, | ||
4585 | spec->gpio_dir, spec->gpio_data & | ||
4586 | ~spec->eapd_mask); | ||
4587 | } else { | ||
4588 | /* enable speakers */ | ||
4589 | for (i = 0; i < cfg->speaker_outs; i++) | ||
4590 | stac92xx_set_pinctl(codec, cfg->speaker_pins[i], | ||
4591 | AC_PINCTL_OUT_EN); | ||
4592 | if (spec->eapd_mask && spec->eapd_switch) | ||
4593 | stac_gpio_set(codec, spec->gpio_mask, | ||
4594 | spec->gpio_dir, spec->gpio_data | | ||
4595 | spec->eapd_mask); | ||
4596 | } | ||
4597 | } | ||
4598 | |||
4434 | /* return non-zero if the hp-pin of the given array index isn't | 4599 | /* return non-zero if the hp-pin of the given array index isn't |
4435 | * a jack-detection target | 4600 | * a jack-detection target |
4436 | */ | 4601 | */ |
@@ -4483,13 +4648,6 @@ static void stac92xx_hp_detect(struct hda_codec *codec) | |||
4483 | for (i = 0; i < cfg->line_outs; i++) | 4648 | for (i = 0; i < cfg->line_outs; i++) |
4484 | stac92xx_reset_pinctl(codec, cfg->line_out_pins[i], | 4649 | stac92xx_reset_pinctl(codec, cfg->line_out_pins[i], |
4485 | AC_PINCTL_OUT_EN); | 4650 | AC_PINCTL_OUT_EN); |
4486 | for (i = 0; i < cfg->speaker_outs; i++) | ||
4487 | stac92xx_reset_pinctl(codec, cfg->speaker_pins[i], | ||
4488 | AC_PINCTL_OUT_EN); | ||
4489 | if (spec->eapd_mask && spec->eapd_switch) | ||
4490 | stac_gpio_set(codec, spec->gpio_mask, | ||
4491 | spec->gpio_dir, spec->gpio_data & | ||
4492 | ~spec->eapd_mask); | ||
4493 | } else { | 4651 | } else { |
4494 | /* enable lineouts */ | 4652 | /* enable lineouts */ |
4495 | if (spec->hp_switch) | 4653 | if (spec->hp_switch) |
@@ -4498,14 +4656,8 @@ static void stac92xx_hp_detect(struct hda_codec *codec) | |||
4498 | for (i = 0; i < cfg->line_outs; i++) | 4656 | for (i = 0; i < cfg->line_outs; i++) |
4499 | stac92xx_set_pinctl(codec, cfg->line_out_pins[i], | 4657 | stac92xx_set_pinctl(codec, cfg->line_out_pins[i], |
4500 | AC_PINCTL_OUT_EN); | 4658 | AC_PINCTL_OUT_EN); |
4501 | for (i = 0; i < cfg->speaker_outs; i++) | ||
4502 | stac92xx_set_pinctl(codec, cfg->speaker_pins[i], | ||
4503 | AC_PINCTL_OUT_EN); | ||
4504 | if (spec->eapd_mask && spec->eapd_switch) | ||
4505 | stac_gpio_set(codec, spec->gpio_mask, | ||
4506 | spec->gpio_dir, spec->gpio_data | | ||
4507 | spec->eapd_mask); | ||
4508 | } | 4659 | } |
4660 | stac92xx_line_out_detect(codec, presence); | ||
4509 | /* toggle hp outs */ | 4661 | /* toggle hp outs */ |
4510 | for (i = 0; i < cfg->hp_outs; i++) { | 4662 | for (i = 0; i < cfg->hp_outs; i++) { |
4511 | unsigned int val = AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN; | 4663 | unsigned int val = AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN; |
@@ -4590,10 +4742,28 @@ static void stac92xx_report_jack(struct hda_codec *codec, hda_nid_t nid) | |||
4590 | } | 4742 | } |
4591 | } | 4743 | } |
4592 | 4744 | ||
4593 | static void stac_issue_unsol_event(struct hda_codec *codec, hda_nid_t nid, | 4745 | static void stac92xx_mic_detect(struct hda_codec *codec) |
4594 | unsigned char type) | ||
4595 | { | 4746 | { |
4596 | struct sigmatel_event *event = stac_get_event(codec, nid, type); | 4747 | struct sigmatel_spec *spec = codec->spec; |
4748 | struct sigmatel_mic_route *mic; | ||
4749 | |||
4750 | if (get_pin_presence(codec, spec->ext_mic.pin)) | ||
4751 | mic = &spec->ext_mic; | ||
4752 | else | ||
4753 | mic = &spec->int_mic; | ||
4754 | if (mic->dmux_idx) | ||
4755 | snd_hda_codec_write_cache(codec, spec->dmux_nids[0], 0, | ||
4756 | AC_VERB_SET_CONNECT_SEL, | ||
4757 | mic->dmux_idx); | ||
4758 | else | ||
4759 | snd_hda_codec_write_cache(codec, spec->mux_nids[0], 0, | ||
4760 | AC_VERB_SET_CONNECT_SEL, | ||
4761 | mic->mux_idx); | ||
4762 | } | ||
4763 | |||
4764 | static void stac_issue_unsol_event(struct hda_codec *codec, hda_nid_t nid) | ||
4765 | { | ||
4766 | struct sigmatel_event *event = stac_get_event(codec, nid); | ||
4597 | if (!event) | 4767 | if (!event) |
4598 | return; | 4768 | return; |
4599 | codec->patch_ops.unsol_event(codec, (unsigned)event->tag << 26); | 4769 | codec->patch_ops.unsol_event(codec, (unsigned)event->tag << 26); |
@@ -4613,7 +4783,19 @@ static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res) | |||
4613 | switch (event->type) { | 4783 | switch (event->type) { |
4614 | case STAC_HP_EVENT: | 4784 | case STAC_HP_EVENT: |
4615 | stac92xx_hp_detect(codec); | 4785 | stac92xx_hp_detect(codec); |
4616 | /* fallthru */ | 4786 | break; |
4787 | case STAC_LO_EVENT: | ||
4788 | stac92xx_line_out_detect(codec, 0); | ||
4789 | break; | ||
4790 | case STAC_MIC_EVENT: | ||
4791 | stac92xx_mic_detect(codec); | ||
4792 | break; | ||
4793 | } | ||
4794 | |||
4795 | switch (event->type) { | ||
4796 | case STAC_HP_EVENT: | ||
4797 | case STAC_LO_EVENT: | ||
4798 | case STAC_MIC_EVENT: | ||
4617 | case STAC_INSERT_EVENT: | 4799 | case STAC_INSERT_EVENT: |
4618 | case STAC_PWR_EVENT: | 4800 | case STAC_PWR_EVENT: |
4619 | if (spec->num_pwrs > 0) | 4801 | if (spec->num_pwrs > 0) |
@@ -4704,8 +4886,7 @@ static int stac92xx_resume(struct hda_codec *codec) | |||
4704 | snd_hda_codec_resume_cache(codec); | 4886 | snd_hda_codec_resume_cache(codec); |
4705 | /* fake event to set up pins again to override cached values */ | 4887 | /* fake event to set up pins again to override cached values */ |
4706 | if (spec->hp_detect) | 4888 | if (spec->hp_detect) |
4707 | stac_issue_unsol_event(codec, spec->autocfg.hp_pins[0], | 4889 | stac_issue_unsol_event(codec, spec->autocfg.hp_pins[0]); |
4708 | STAC_HP_EVENT); | ||
4709 | return 0; | 4890 | return 0; |
4710 | } | 4891 | } |
4711 | 4892 | ||
@@ -4745,6 +4926,19 @@ static int stac92xx_hp_check_power_status(struct hda_codec *codec, | |||
4745 | static int stac92xx_suspend(struct hda_codec *codec, pm_message_t state) | 4926 | static int stac92xx_suspend(struct hda_codec *codec, pm_message_t state) |
4746 | { | 4927 | { |
4747 | struct sigmatel_spec *spec = codec->spec; | 4928 | struct sigmatel_spec *spec = codec->spec; |
4929 | int i; | ||
4930 | hda_nid_t nid; | ||
4931 | |||
4932 | /* reset each pin before powering down DAC/ADC to avoid click noise */ | ||
4933 | nid = codec->start_nid; | ||
4934 | for (i = 0; i < codec->num_nodes; i++, nid++) { | ||
4935 | unsigned int wcaps = get_wcaps(codec, nid); | ||
4936 | unsigned int wid_type = get_wcaps_type(wcaps); | ||
4937 | if (wid_type == AC_WID_PIN) | ||
4938 | snd_hda_codec_read(codec, nid, 0, | ||
4939 | AC_VERB_SET_PIN_WIDGET_CONTROL, 0); | ||
4940 | } | ||
4941 | |||
4748 | if (spec->eapd_mask) | 4942 | if (spec->eapd_mask) |
4749 | stac_gpio_set(codec, spec->gpio_mask, | 4943 | stac_gpio_set(codec, spec->gpio_mask, |
4750 | spec->gpio_dir, spec->gpio_data & | 4944 | spec->gpio_dir, spec->gpio_data & |
@@ -4781,7 +4975,8 @@ static int patch_stac9200(struct hda_codec *codec) | |||
4781 | stac9200_models, | 4975 | stac9200_models, |
4782 | stac9200_cfg_tbl); | 4976 | stac9200_cfg_tbl); |
4783 | if (spec->board_config < 0) | 4977 | if (spec->board_config < 0) |
4784 | snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9200, using BIOS defaults\n"); | 4978 | snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", |
4979 | codec->chip_name); | ||
4785 | else | 4980 | else |
4786 | stac92xx_set_config_regs(codec, | 4981 | stac92xx_set_config_regs(codec, |
4787 | stac9200_brd_tbl[spec->board_config]); | 4982 | stac9200_brd_tbl[spec->board_config]); |
@@ -4853,8 +5048,8 @@ static int patch_stac925x(struct hda_codec *codec) | |||
4853 | stac925x_cfg_tbl); | 5048 | stac925x_cfg_tbl); |
4854 | again: | 5049 | again: |
4855 | if (spec->board_config < 0) | 5050 | if (spec->board_config < 0) |
4856 | snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC925x," | 5051 | snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", |
4857 | "using BIOS defaults\n"); | 5052 | codec->chip_name); |
4858 | else | 5053 | else |
4859 | stac92xx_set_config_regs(codec, | 5054 | stac92xx_set_config_regs(codec, |
4860 | stac925x_brd_tbl[spec->board_config]); | 5055 | stac925x_brd_tbl[spec->board_config]); |
@@ -4884,6 +5079,9 @@ static int patch_stac925x(struct hda_codec *codec) | |||
4884 | 5079 | ||
4885 | spec->init = stac925x_core_init; | 5080 | spec->init = stac925x_core_init; |
4886 | spec->mixer = stac925x_mixer; | 5081 | spec->mixer = stac925x_mixer; |
5082 | spec->num_caps = 1; | ||
5083 | spec->capvols = stac925x_capvols; | ||
5084 | spec->capsws = stac925x_capsws; | ||
4887 | 5085 | ||
4888 | err = stac92xx_parse_auto_config(codec, 0x8, 0x7); | 5086 | err = stac92xx_parse_auto_config(codec, 0x8, 0x7); |
4889 | if (!err) { | 5087 | if (!err) { |
@@ -4936,8 +5134,8 @@ static int patch_stac92hd73xx(struct hda_codec *codec) | |||
4936 | stac92hd73xx_cfg_tbl); | 5134 | stac92hd73xx_cfg_tbl); |
4937 | again: | 5135 | again: |
4938 | if (spec->board_config < 0) | 5136 | if (spec->board_config < 0) |
4939 | snd_printdd(KERN_INFO "hda_codec: Unknown model for" | 5137 | snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", |
4940 | " STAC92HD73XX, using BIOS defaults\n"); | 5138 | codec->chip_name); |
4941 | else | 5139 | else |
4942 | stac92xx_set_config_regs(codec, | 5140 | stac92xx_set_config_regs(codec, |
4943 | stac92hd73xx_brd_tbl[spec->board_config]); | 5141 | stac92hd73xx_brd_tbl[spec->board_config]); |
@@ -4987,6 +5185,10 @@ again: | |||
4987 | memcpy(&spec->private_dimux, &stac92hd73xx_dmux, | 5185 | memcpy(&spec->private_dimux, &stac92hd73xx_dmux, |
4988 | sizeof(stac92hd73xx_dmux)); | 5186 | sizeof(stac92hd73xx_dmux)); |
4989 | 5187 | ||
5188 | spec->num_caps = STAC92HD73XX_NUM_CAPS; | ||
5189 | spec->capvols = stac92hd73xx_capvols; | ||
5190 | spec->capsws = stac92hd73xx_capsws; | ||
5191 | |||
4990 | switch (spec->board_config) { | 5192 | switch (spec->board_config) { |
4991 | case STAC_DELL_EQ: | 5193 | case STAC_DELL_EQ: |
4992 | spec->init = dell_eq_core_init; | 5194 | spec->init = dell_eq_core_init; |
@@ -5106,14 +5308,18 @@ static int patch_stac92hd83xxx(struct hda_codec *codec) | |||
5106 | spec->num_dmics = STAC92HD83XXX_NUM_DMICS; | 5308 | spec->num_dmics = STAC92HD83XXX_NUM_DMICS; |
5107 | spec->dinput_mux = &stac92hd83xxx_dmux; | 5309 | spec->dinput_mux = &stac92hd83xxx_dmux; |
5108 | spec->pin_nids = stac92hd83xxx_pin_nids; | 5310 | spec->pin_nids = stac92hd83xxx_pin_nids; |
5311 | spec->num_caps = STAC92HD83XXX_NUM_CAPS; | ||
5312 | spec->capvols = stac92hd83xxx_capvols; | ||
5313 | spec->capsws = stac92hd83xxx_capsws; | ||
5314 | |||
5109 | spec->board_config = snd_hda_check_board_config(codec, | 5315 | spec->board_config = snd_hda_check_board_config(codec, |
5110 | STAC_92HD83XXX_MODELS, | 5316 | STAC_92HD83XXX_MODELS, |
5111 | stac92hd83xxx_models, | 5317 | stac92hd83xxx_models, |
5112 | stac92hd83xxx_cfg_tbl); | 5318 | stac92hd83xxx_cfg_tbl); |
5113 | again: | 5319 | again: |
5114 | if (spec->board_config < 0) | 5320 | if (spec->board_config < 0) |
5115 | snd_printdd(KERN_INFO "hda_codec: Unknown model for" | 5321 | snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", |
5116 | " STAC92HD83XXX, using BIOS defaults\n"); | 5322 | codec->chip_name); |
5117 | else | 5323 | else |
5118 | stac92xx_set_config_regs(codec, | 5324 | stac92xx_set_config_regs(codec, |
5119 | stac92hd83xxx_brd_tbl[spec->board_config]); | 5325 | stac92hd83xxx_brd_tbl[spec->board_config]); |
@@ -5155,6 +5361,8 @@ again: | |||
5155 | 5361 | ||
5156 | num_dacs = snd_hda_get_connections(codec, nid, | 5362 | num_dacs = snd_hda_get_connections(codec, nid, |
5157 | conn, STAC92HD83_DAC_COUNT + 1) - 1; | 5363 | conn, STAC92HD83_DAC_COUNT + 1) - 1; |
5364 | if (num_dacs < 0) | ||
5365 | num_dacs = STAC92HD83_DAC_COUNT; | ||
5158 | 5366 | ||
5159 | /* set port X to select the last DAC | 5367 | /* set port X to select the last DAC |
5160 | */ | 5368 | */ |
@@ -5276,8 +5484,8 @@ static int patch_stac92hd71bxx(struct hda_codec *codec) | |||
5276 | stac92hd71bxx_cfg_tbl); | 5484 | stac92hd71bxx_cfg_tbl); |
5277 | again: | 5485 | again: |
5278 | if (spec->board_config < 0) | 5486 | if (spec->board_config < 0) |
5279 | snd_printdd(KERN_INFO "hda_codec: Unknown model for" | 5487 | snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", |
5280 | " STAC92HD71BXX, using BIOS defaults\n"); | 5488 | codec->chip_name); |
5281 | else | 5489 | else |
5282 | stac92xx_set_config_regs(codec, | 5490 | stac92xx_set_config_regs(codec, |
5283 | stac92hd71bxx_brd_tbl[spec->board_config]); | 5491 | stac92hd71bxx_brd_tbl[spec->board_config]); |
@@ -5292,6 +5500,10 @@ again: | |||
5292 | spec->dmic_nids = stac92hd71bxx_dmic_nids; | 5500 | spec->dmic_nids = stac92hd71bxx_dmic_nids; |
5293 | spec->dmux_nids = stac92hd71bxx_dmux_nids; | 5501 | spec->dmux_nids = stac92hd71bxx_dmux_nids; |
5294 | 5502 | ||
5503 | spec->num_caps = STAC92HD71BXX_NUM_CAPS; | ||
5504 | spec->capvols = stac92hd71bxx_capvols; | ||
5505 | spec->capsws = stac92hd71bxx_capsws; | ||
5506 | |||
5295 | switch (codec->vendor_id) { | 5507 | switch (codec->vendor_id) { |
5296 | case 0x111d76b6: /* 4 Port without Analog Mixer */ | 5508 | case 0x111d76b6: /* 4 Port without Analog Mixer */ |
5297 | case 0x111d76b7: | 5509 | case 0x111d76b7: |
@@ -5301,7 +5513,6 @@ again: | |||
5301 | case 0x111d76b5: | 5513 | case 0x111d76b5: |
5302 | memcpy(&spec->private_dimux, &stac92hd71bxx_dmux_nomixer, | 5514 | memcpy(&spec->private_dimux, &stac92hd71bxx_dmux_nomixer, |
5303 | sizeof(stac92hd71bxx_dmux_nomixer)); | 5515 | sizeof(stac92hd71bxx_dmux_nomixer)); |
5304 | spec->mixer = stac92hd71bxx_mixer; | ||
5305 | spec->init = stac92hd71bxx_core_init; | 5516 | spec->init = stac92hd71bxx_core_init; |
5306 | codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs; | 5517 | codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs; |
5307 | spec->num_dmics = stac92hd71bxx_connected_ports(codec, | 5518 | spec->num_dmics = stac92hd71bxx_connected_ports(codec, |
@@ -5314,8 +5525,6 @@ again: | |||
5314 | } | 5525 | } |
5315 | break; | 5526 | break; |
5316 | case 0x111d7608: /* 5 Port with Analog Mixer */ | 5527 | case 0x111d7608: /* 5 Port with Analog Mixer */ |
5317 | memcpy(&spec->private_dimux, &stac92hd71bxx_dmux_amixer, | ||
5318 | sizeof(stac92hd71bxx_dmux_amixer)); | ||
5319 | spec->private_dimux.num_items--; | 5528 | spec->private_dimux.num_items--; |
5320 | switch (spec->board_config) { | 5529 | switch (spec->board_config) { |
5321 | case STAC_HP_M4: | 5530 | case STAC_HP_M4: |
@@ -5338,11 +5547,17 @@ again: | |||
5338 | 5547 | ||
5339 | /* no output amps */ | 5548 | /* no output amps */ |
5340 | spec->num_pwrs = 0; | 5549 | spec->num_pwrs = 0; |
5341 | spec->mixer = stac92hd71bxx_analog_mixer; | 5550 | if (snd_hda_get_bool_hint(codec, "analog_mixer") == 1) { |
5342 | spec->dinput_mux = &spec->private_dimux; | 5551 | spec->mixer = stac92hd71bxx_analog_mixer; |
5343 | 5552 | memcpy(&spec->private_dimux, &stac92hd71bxx_dmux_amixer, | |
5553 | sizeof(stac92hd71bxx_dmux_amixer)); | ||
5554 | } else { | ||
5555 | memcpy(&spec->private_dimux, | ||
5556 | &stac92hd71bxx_dmux_nomixer, | ||
5557 | sizeof(stac92hd71bxx_dmux_nomixer)); | ||
5558 | } | ||
5344 | /* disable VSW */ | 5559 | /* disable VSW */ |
5345 | spec->init = &stac92hd71bxx_analog_core_init[HD_DISABLE_PORTF]; | 5560 | spec->init = stac92hd71bxx_core_init; |
5346 | unmute_init++; | 5561 | unmute_init++; |
5347 | snd_hda_codec_set_pincfg(codec, 0x0f, 0x40f000f0); | 5562 | snd_hda_codec_set_pincfg(codec, 0x0f, 0x40f000f0); |
5348 | snd_hda_codec_set_pincfg(codec, 0x19, 0x40f000f3); | 5563 | snd_hda_codec_set_pincfg(codec, 0x19, 0x40f000f3); |
@@ -5350,8 +5565,11 @@ again: | |||
5350 | spec->num_dmics = stac92hd71bxx_connected_ports(codec, | 5565 | spec->num_dmics = stac92hd71bxx_connected_ports(codec, |
5351 | stac92hd71bxx_dmic_nids, | 5566 | stac92hd71bxx_dmic_nids, |
5352 | STAC92HD71BXX_NUM_DMICS - 1); | 5567 | STAC92HD71BXX_NUM_DMICS - 1); |
5353 | spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids); | 5568 | if (spec->num_dmics) { |
5354 | ndmic_nids = ARRAY_SIZE(stac92hd71bxx_dmic_nids) - 2; | 5569 | spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids); |
5570 | spec->dinput_mux = &spec->private_dimux; | ||
5571 | ndmic_nids = ARRAY_SIZE(stac92hd71bxx_dmic_nids) - 2; | ||
5572 | } | ||
5355 | break; | 5573 | break; |
5356 | case 0x111d7603: /* 6 Port with Analog Mixer */ | 5574 | case 0x111d7603: /* 6 Port with Analog Mixer */ |
5357 | if ((codec->revision_id & 0xf) == 1) | 5575 | if ((codec->revision_id & 0xf) == 1) |
@@ -5361,17 +5579,25 @@ again: | |||
5361 | spec->num_pwrs = 0; | 5579 | spec->num_pwrs = 0; |
5362 | /* fallthru */ | 5580 | /* fallthru */ |
5363 | default: | 5581 | default: |
5364 | memcpy(&spec->private_dimux, &stac92hd71bxx_dmux_amixer, | 5582 | if (snd_hda_get_bool_hint(codec, "analog_mixer") == 1) { |
5365 | sizeof(stac92hd71bxx_dmux_amixer)); | 5583 | spec->mixer = stac92hd71bxx_analog_mixer; |
5366 | spec->dinput_mux = &spec->private_dimux; | 5584 | memcpy(&spec->private_dimux, &stac92hd71bxx_dmux_amixer, |
5367 | spec->mixer = stac92hd71bxx_analog_mixer; | 5585 | sizeof(stac92hd71bxx_dmux_amixer)); |
5368 | spec->init = stac92hd71bxx_analog_core_init; | 5586 | } else { |
5587 | memcpy(&spec->private_dimux, | ||
5588 | &stac92hd71bxx_dmux_nomixer, | ||
5589 | sizeof(stac92hd71bxx_dmux_nomixer)); | ||
5590 | } | ||
5591 | spec->init = stac92hd71bxx_core_init; | ||
5369 | codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs; | 5592 | codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs; |
5370 | spec->num_dmics = stac92hd71bxx_connected_ports(codec, | 5593 | spec->num_dmics = stac92hd71bxx_connected_ports(codec, |
5371 | stac92hd71bxx_dmic_nids, | 5594 | stac92hd71bxx_dmic_nids, |
5372 | STAC92HD71BXX_NUM_DMICS); | 5595 | STAC92HD71BXX_NUM_DMICS); |
5373 | spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids); | 5596 | if (spec->num_dmics) { |
5374 | ndmic_nids = ARRAY_SIZE(stac92hd71bxx_dmic_nids) - 1; | 5597 | spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids); |
5598 | spec->dinput_mux = &spec->private_dimux; | ||
5599 | ndmic_nids = ARRAY_SIZE(stac92hd71bxx_dmic_nids) - 1; | ||
5600 | } | ||
5375 | } | 5601 | } |
5376 | 5602 | ||
5377 | if (get_wcaps(codec, 0xa) & AC_WCAP_IN_AMP) | 5603 | if (get_wcaps(codec, 0xa) & AC_WCAP_IN_AMP) |
@@ -5532,8 +5758,8 @@ static int patch_stac922x(struct hda_codec *codec) | |||
5532 | 5758 | ||
5533 | again: | 5759 | again: |
5534 | if (spec->board_config < 0) | 5760 | if (spec->board_config < 0) |
5535 | snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC922x, " | 5761 | snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", |
5536 | "using BIOS defaults\n"); | 5762 | codec->chip_name); |
5537 | else | 5763 | else |
5538 | stac92xx_set_config_regs(codec, | 5764 | stac92xx_set_config_regs(codec, |
5539 | stac922x_brd_tbl[spec->board_config]); | 5765 | stac922x_brd_tbl[spec->board_config]); |
@@ -5546,7 +5772,10 @@ static int patch_stac922x(struct hda_codec *codec) | |||
5546 | spec->num_pwrs = 0; | 5772 | spec->num_pwrs = 0; |
5547 | 5773 | ||
5548 | spec->init = stac922x_core_init; | 5774 | spec->init = stac922x_core_init; |
5549 | spec->mixer = stac922x_mixer; | 5775 | |
5776 | spec->num_caps = STAC922X_NUM_CAPS; | ||
5777 | spec->capvols = stac922x_capvols; | ||
5778 | spec->capsws = stac922x_capsws; | ||
5550 | 5779 | ||
5551 | spec->multiout.dac_nids = spec->dac_nids; | 5780 | spec->multiout.dac_nids = spec->dac_nids; |
5552 | 5781 | ||
@@ -5595,8 +5824,8 @@ static int patch_stac927x(struct hda_codec *codec) | |||
5595 | stac927x_cfg_tbl); | 5824 | stac927x_cfg_tbl); |
5596 | again: | 5825 | again: |
5597 | if (spec->board_config < 0) | 5826 | if (spec->board_config < 0) |
5598 | snd_printdd(KERN_INFO "hda_codec: Unknown model for" | 5827 | snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", |
5599 | "STAC927x, using BIOS defaults\n"); | 5828 | codec->chip_name); |
5600 | else | 5829 | else |
5601 | stac92xx_set_config_regs(codec, | 5830 | stac92xx_set_config_regs(codec, |
5602 | stac927x_brd_tbl[spec->board_config]); | 5831 | stac927x_brd_tbl[spec->board_config]); |
@@ -5621,7 +5850,6 @@ static int patch_stac927x(struct hda_codec *codec) | |||
5621 | spec->num_dmics = 0; | 5850 | spec->num_dmics = 0; |
5622 | 5851 | ||
5623 | spec->init = d965_core_init; | 5852 | spec->init = d965_core_init; |
5624 | spec->mixer = stac927x_mixer; | ||
5625 | break; | 5853 | break; |
5626 | case STAC_DELL_BIOS: | 5854 | case STAC_DELL_BIOS: |
5627 | switch (codec->subsystem_id) { | 5855 | switch (codec->subsystem_id) { |
@@ -5646,7 +5874,6 @@ static int patch_stac927x(struct hda_codec *codec) | |||
5646 | spec->num_dmics = STAC927X_NUM_DMICS; | 5874 | spec->num_dmics = STAC927X_NUM_DMICS; |
5647 | 5875 | ||
5648 | spec->init = d965_core_init; | 5876 | spec->init = d965_core_init; |
5649 | spec->mixer = stac927x_mixer; | ||
5650 | spec->dmux_nids = stac927x_dmux_nids; | 5877 | spec->dmux_nids = stac927x_dmux_nids; |
5651 | spec->num_dmuxes = ARRAY_SIZE(stac927x_dmux_nids); | 5878 | spec->num_dmuxes = ARRAY_SIZE(stac927x_dmux_nids); |
5652 | break; | 5879 | break; |
@@ -5659,9 +5886,12 @@ static int patch_stac927x(struct hda_codec *codec) | |||
5659 | spec->num_dmics = 0; | 5886 | spec->num_dmics = 0; |
5660 | 5887 | ||
5661 | spec->init = stac927x_core_init; | 5888 | spec->init = stac927x_core_init; |
5662 | spec->mixer = stac927x_mixer; | ||
5663 | } | 5889 | } |
5664 | 5890 | ||
5891 | spec->num_caps = STAC927X_NUM_CAPS; | ||
5892 | spec->capvols = stac927x_capvols; | ||
5893 | spec->capsws = stac927x_capsws; | ||
5894 | |||
5665 | spec->num_pwrs = 0; | 5895 | spec->num_pwrs = 0; |
5666 | spec->aloopback_ctl = stac927x_loopback; | 5896 | spec->aloopback_ctl = stac927x_loopback; |
5667 | spec->aloopback_mask = 0x40; | 5897 | spec->aloopback_mask = 0x40; |
@@ -5723,7 +5953,8 @@ static int patch_stac9205(struct hda_codec *codec) | |||
5723 | stac9205_cfg_tbl); | 5953 | stac9205_cfg_tbl); |
5724 | again: | 5954 | again: |
5725 | if (spec->board_config < 0) | 5955 | if (spec->board_config < 0) |
5726 | snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9205, using BIOS defaults\n"); | 5956 | snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", |
5957 | codec->chip_name); | ||
5727 | else | 5958 | else |
5728 | stac92xx_set_config_regs(codec, | 5959 | stac92xx_set_config_regs(codec, |
5729 | stac9205_brd_tbl[spec->board_config]); | 5960 | stac9205_brd_tbl[spec->board_config]); |
@@ -5742,9 +5973,12 @@ static int patch_stac9205(struct hda_codec *codec) | |||
5742 | spec->num_pwrs = 0; | 5973 | spec->num_pwrs = 0; |
5743 | 5974 | ||
5744 | spec->init = stac9205_core_init; | 5975 | spec->init = stac9205_core_init; |
5745 | spec->mixer = stac9205_mixer; | ||
5746 | spec->aloopback_ctl = stac9205_loopback; | 5976 | spec->aloopback_ctl = stac9205_loopback; |
5747 | 5977 | ||
5978 | spec->num_caps = STAC9205_NUM_CAPS; | ||
5979 | spec->capvols = stac9205_capvols; | ||
5980 | spec->capsws = stac9205_capsws; | ||
5981 | |||
5748 | spec->aloopback_mask = 0x40; | 5982 | spec->aloopback_mask = 0x40; |
5749 | spec->aloopback_shift = 0; | 5983 | spec->aloopback_shift = 0; |
5750 | /* Turn on/off EAPD per HP plugging */ | 5984 | /* Turn on/off EAPD per HP plugging */ |
@@ -5819,12 +6053,6 @@ static struct hda_verb stac9872_core_init[] = { | |||
5819 | {} | 6053 | {} |
5820 | }; | 6054 | }; |
5821 | 6055 | ||
5822 | static struct snd_kcontrol_new stac9872_mixer[] = { | ||
5823 | HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT), | ||
5824 | HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT), | ||
5825 | { } /* end */ | ||
5826 | }; | ||
5827 | |||
5828 | static hda_nid_t stac9872_pin_nids[] = { | 6056 | static hda_nid_t stac9872_pin_nids[] = { |
5829 | 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, | 6057 | 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, |
5830 | 0x11, 0x13, 0x14, | 6058 | 0x11, 0x13, 0x14, |
@@ -5838,6 +6066,11 @@ static hda_nid_t stac9872_mux_nids[] = { | |||
5838 | 0x15 | 6066 | 0x15 |
5839 | }; | 6067 | }; |
5840 | 6068 | ||
6069 | static unsigned long stac9872_capvols[] = { | ||
6070 | HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT), | ||
6071 | }; | ||
6072 | #define stac9872_capsws stac9872_capvols | ||
6073 | |||
5841 | static unsigned int stac9872_vaio_pin_configs[9] = { | 6074 | static unsigned int stac9872_vaio_pin_configs[9] = { |
5842 | 0x03211020, 0x411111f0, 0x411111f0, 0x03a15030, | 6075 | 0x03211020, 0x411111f0, 0x411111f0, 0x03a15030, |
5843 | 0x411111f0, 0x90170110, 0x411111f0, 0x411111f0, | 6076 | 0x411111f0, 0x90170110, 0x411111f0, 0x411111f0, |
@@ -5854,6 +6087,8 @@ static unsigned int *stac9872_brd_tbl[STAC_9872_MODELS] = { | |||
5854 | }; | 6087 | }; |
5855 | 6088 | ||
5856 | static struct snd_pci_quirk stac9872_cfg_tbl[] = { | 6089 | static struct snd_pci_quirk stac9872_cfg_tbl[] = { |
6090 | SND_PCI_QUIRK_MASK(0x104d, 0xfff0, 0x81e0, | ||
6091 | "Sony VAIO F/S", STAC_9872_VAIO), | ||
5857 | {} /* terminator */ | 6092 | {} /* terminator */ |
5858 | }; | 6093 | }; |
5859 | 6094 | ||
@@ -5866,26 +6101,28 @@ static int patch_stac9872(struct hda_codec *codec) | |||
5866 | if (spec == NULL) | 6101 | if (spec == NULL) |
5867 | return -ENOMEM; | 6102 | return -ENOMEM; |
5868 | codec->spec = spec; | 6103 | codec->spec = spec; |
6104 | spec->num_pins = ARRAY_SIZE(stac9872_pin_nids); | ||
6105 | spec->pin_nids = stac9872_pin_nids; | ||
5869 | 6106 | ||
5870 | spec->board_config = snd_hda_check_board_config(codec, STAC_9872_MODELS, | 6107 | spec->board_config = snd_hda_check_board_config(codec, STAC_9872_MODELS, |
5871 | stac9872_models, | 6108 | stac9872_models, |
5872 | stac9872_cfg_tbl); | 6109 | stac9872_cfg_tbl); |
5873 | if (spec->board_config < 0) | 6110 | if (spec->board_config < 0) |
5874 | snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9872, " | 6111 | snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", |
5875 | "using BIOS defaults\n"); | 6112 | codec->chip_name); |
5876 | else | 6113 | else |
5877 | stac92xx_set_config_regs(codec, | 6114 | stac92xx_set_config_regs(codec, |
5878 | stac9872_brd_tbl[spec->board_config]); | 6115 | stac9872_brd_tbl[spec->board_config]); |
5879 | 6116 | ||
5880 | spec->num_pins = ARRAY_SIZE(stac9872_pin_nids); | ||
5881 | spec->pin_nids = stac9872_pin_nids; | ||
5882 | spec->multiout.dac_nids = spec->dac_nids; | 6117 | spec->multiout.dac_nids = spec->dac_nids; |
5883 | spec->num_adcs = ARRAY_SIZE(stac9872_adc_nids); | 6118 | spec->num_adcs = ARRAY_SIZE(stac9872_adc_nids); |
5884 | spec->adc_nids = stac9872_adc_nids; | 6119 | spec->adc_nids = stac9872_adc_nids; |
5885 | spec->num_muxes = ARRAY_SIZE(stac9872_mux_nids); | 6120 | spec->num_muxes = ARRAY_SIZE(stac9872_mux_nids); |
5886 | spec->mux_nids = stac9872_mux_nids; | 6121 | spec->mux_nids = stac9872_mux_nids; |
5887 | spec->mixer = stac9872_mixer; | ||
5888 | spec->init = stac9872_core_init; | 6122 | spec->init = stac9872_core_init; |
6123 | spec->num_caps = 1; | ||
6124 | spec->capvols = stac9872_capvols; | ||
6125 | spec->capsws = stac9872_capsws; | ||
5889 | 6126 | ||
5890 | err = stac92xx_parse_auto_config(codec, 0x10, 0x12); | 6127 | err = stac92xx_parse_auto_config(codec, 0x10, 0x12); |
5891 | if (err < 0) { | 6128 | if (err < 0) { |
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index 8e004fb6961a..ab90abb04ccd 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c | |||
@@ -210,7 +210,9 @@ struct via_spec { | |||
210 | /* capture */ | 210 | /* capture */ |
211 | unsigned int num_adc_nids; | 211 | unsigned int num_adc_nids; |
212 | hda_nid_t *adc_nids; | 212 | hda_nid_t *adc_nids; |
213 | hda_nid_t mux_nids[3]; | ||
213 | hda_nid_t dig_in_nid; | 214 | hda_nid_t dig_in_nid; |
215 | hda_nid_t dig_in_pin; | ||
214 | 216 | ||
215 | /* capture source */ | 217 | /* capture source */ |
216 | const struct hda_input_mux *input_mux; | 218 | const struct hda_input_mux *input_mux; |
@@ -319,6 +321,9 @@ static void via_auto_set_output_and_unmute(struct hda_codec *codec, | |||
319 | pin_type); | 321 | pin_type); |
320 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, | 322 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, |
321 | AMP_OUT_UNMUTE); | 323 | AMP_OUT_UNMUTE); |
324 | if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD) | ||
325 | snd_hda_codec_write(codec, nid, 0, | ||
326 | AC_VERB_SET_EAPD_BTLENABLE, 0x02); | ||
322 | } | 327 | } |
323 | 328 | ||
324 | 329 | ||
@@ -387,27 +392,12 @@ static int via_mux_enum_put(struct snd_kcontrol *kcontrol, | |||
387 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 392 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
388 | struct via_spec *spec = codec->spec; | 393 | struct via_spec *spec = codec->spec; |
389 | unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); | 394 | unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); |
390 | unsigned int vendor_id = codec->vendor_id; | 395 | |
391 | 396 | if (!spec->mux_nids[adc_idx]) | |
392 | /* AIW0 lydia 060801 add for correct sw0 input select */ | 397 | return -EINVAL; |
393 | if (IS_VT1708_VENDORID(vendor_id) && (adc_idx == 0)) | 398 | return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, |
394 | return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, | 399 | spec->mux_nids[adc_idx], |
395 | 0x18, &spec->cur_mux[adc_idx]); | 400 | &spec->cur_mux[adc_idx]); |
396 | else if ((IS_VT1709_10CH_VENDORID(vendor_id) || | ||
397 | IS_VT1709_6CH_VENDORID(vendor_id)) && (adc_idx == 0)) | ||
398 | return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, | ||
399 | 0x19, &spec->cur_mux[adc_idx]); | ||
400 | else if ((IS_VT1708B_8CH_VENDORID(vendor_id) || | ||
401 | IS_VT1708B_4CH_VENDORID(vendor_id)) && (adc_idx == 0)) | ||
402 | return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, | ||
403 | 0x17, &spec->cur_mux[adc_idx]); | ||
404 | else if (IS_VT1702_VENDORID(vendor_id) && (adc_idx == 0)) | ||
405 | return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, | ||
406 | 0x13, &spec->cur_mux[adc_idx]); | ||
407 | else | ||
408 | return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, | ||
409 | spec->adc_nids[adc_idx], | ||
410 | &spec->cur_mux[adc_idx]); | ||
411 | } | 401 | } |
412 | 402 | ||
413 | static int via_independent_hp_info(struct snd_kcontrol *kcontrol, | 403 | static int via_independent_hp_info(struct snd_kcontrol *kcontrol, |
@@ -998,25 +988,11 @@ static int via_init(struct hda_codec *codec) | |||
998 | 988 | ||
999 | /* Lydia Add for EAPD enable */ | 989 | /* Lydia Add for EAPD enable */ |
1000 | if (!spec->dig_in_nid) { /* No Digital In connection */ | 990 | if (!spec->dig_in_nid) { /* No Digital In connection */ |
1001 | if (IS_VT1708_VENDORID(codec->vendor_id)) { | 991 | if (spec->dig_in_pin) { |
1002 | snd_hda_codec_write(codec, VT1708_DIGIN_PIN, 0, | 992 | snd_hda_codec_write(codec, spec->dig_in_pin, 0, |
1003 | AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
1004 | PIN_OUT); | ||
1005 | snd_hda_codec_write(codec, VT1708_DIGIN_PIN, 0, | ||
1006 | AC_VERB_SET_EAPD_BTLENABLE, 0x02); | ||
1007 | } else if (IS_VT1709_10CH_VENDORID(codec->vendor_id) || | ||
1008 | IS_VT1709_6CH_VENDORID(codec->vendor_id)) { | ||
1009 | snd_hda_codec_write(codec, VT1709_DIGIN_PIN, 0, | ||
1010 | AC_VERB_SET_PIN_WIDGET_CONTROL, | 993 | AC_VERB_SET_PIN_WIDGET_CONTROL, |
1011 | PIN_OUT); | 994 | PIN_OUT); |
1012 | snd_hda_codec_write(codec, VT1709_DIGIN_PIN, 0, | 995 | snd_hda_codec_write(codec, spec->dig_in_pin, 0, |
1013 | AC_VERB_SET_EAPD_BTLENABLE, 0x02); | ||
1014 | } else if (IS_VT1708B_8CH_VENDORID(codec->vendor_id) || | ||
1015 | IS_VT1708B_4CH_VENDORID(codec->vendor_id)) { | ||
1016 | snd_hda_codec_write(codec, VT1708B_DIGIN_PIN, 0, | ||
1017 | AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
1018 | PIN_OUT); | ||
1019 | snd_hda_codec_write(codec, VT1708B_DIGIN_PIN, 0, | ||
1020 | AC_VERB_SET_EAPD_BTLENABLE, 0x02); | 996 | AC_VERB_SET_EAPD_BTLENABLE, 0x02); |
1021 | } | 997 | } |
1022 | } else /* enable SPDIF-input pin */ | 998 | } else /* enable SPDIF-input pin */ |
@@ -1326,6 +1302,7 @@ static int vt1708_parse_auto_config(struct hda_codec *codec) | |||
1326 | 1302 | ||
1327 | if (spec->autocfg.dig_outs) | 1303 | if (spec->autocfg.dig_outs) |
1328 | spec->multiout.dig_out_nid = VT1708_DIGOUT_NID; | 1304 | spec->multiout.dig_out_nid = VT1708_DIGOUT_NID; |
1305 | spec->dig_in_pin = VT1708_DIGIN_PIN; | ||
1329 | if (spec->autocfg.dig_in_pin) | 1306 | if (spec->autocfg.dig_in_pin) |
1330 | spec->dig_in_nid = VT1708_DIGIN_NID; | 1307 | spec->dig_in_nid = VT1708_DIGIN_NID; |
1331 | 1308 | ||
@@ -1352,6 +1329,33 @@ static int via_auto_init(struct hda_codec *codec) | |||
1352 | return 0; | 1329 | return 0; |
1353 | } | 1330 | } |
1354 | 1331 | ||
1332 | static int get_mux_nids(struct hda_codec *codec) | ||
1333 | { | ||
1334 | struct via_spec *spec = codec->spec; | ||
1335 | hda_nid_t nid, conn[8]; | ||
1336 | unsigned int type; | ||
1337 | int i, n; | ||
1338 | |||
1339 | for (i = 0; i < spec->num_adc_nids; i++) { | ||
1340 | nid = spec->adc_nids[i]; | ||
1341 | while (nid) { | ||
1342 | type = get_wcaps_type(get_wcaps(codec, nid)); | ||
1343 | if (type == AC_WID_PIN) | ||
1344 | break; | ||
1345 | n = snd_hda_get_connections(codec, nid, conn, | ||
1346 | ARRAY_SIZE(conn)); | ||
1347 | if (n <= 0) | ||
1348 | break; | ||
1349 | if (n > 1) { | ||
1350 | spec->mux_nids[i] = nid; | ||
1351 | break; | ||
1352 | } | ||
1353 | nid = conn[0]; | ||
1354 | } | ||
1355 | } | ||
1356 | return 0; | ||
1357 | } | ||
1358 | |||
1355 | static int patch_vt1708(struct hda_codec *codec) | 1359 | static int patch_vt1708(struct hda_codec *codec) |
1356 | { | 1360 | { |
1357 | struct via_spec *spec; | 1361 | struct via_spec *spec; |
@@ -1799,6 +1803,7 @@ static int vt1709_parse_auto_config(struct hda_codec *codec) | |||
1799 | 1803 | ||
1800 | if (spec->autocfg.dig_outs) | 1804 | if (spec->autocfg.dig_outs) |
1801 | spec->multiout.dig_out_nid = VT1709_DIGOUT_NID; | 1805 | spec->multiout.dig_out_nid = VT1709_DIGOUT_NID; |
1806 | spec->dig_in_pin = VT1709_DIGIN_PIN; | ||
1802 | if (spec->autocfg.dig_in_pin) | 1807 | if (spec->autocfg.dig_in_pin) |
1803 | spec->dig_in_nid = VT1709_DIGIN_NID; | 1808 | spec->dig_in_nid = VT1709_DIGIN_NID; |
1804 | 1809 | ||
@@ -1859,6 +1864,7 @@ static int patch_vt1709_10ch(struct hda_codec *codec) | |||
1859 | if (!spec->adc_nids && spec->input_mux) { | 1864 | if (!spec->adc_nids && spec->input_mux) { |
1860 | spec->adc_nids = vt1709_adc_nids; | 1865 | spec->adc_nids = vt1709_adc_nids; |
1861 | spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids); | 1866 | spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids); |
1867 | get_mux_nids(codec); | ||
1862 | spec->mixers[spec->num_mixers] = vt1709_capture_mixer; | 1868 | spec->mixers[spec->num_mixers] = vt1709_capture_mixer; |
1863 | spec->num_mixers++; | 1869 | spec->num_mixers++; |
1864 | } | 1870 | } |
@@ -1952,6 +1958,7 @@ static int patch_vt1709_6ch(struct hda_codec *codec) | |||
1952 | if (!spec->adc_nids && spec->input_mux) { | 1958 | if (!spec->adc_nids && spec->input_mux) { |
1953 | spec->adc_nids = vt1709_adc_nids; | 1959 | spec->adc_nids = vt1709_adc_nids; |
1954 | spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids); | 1960 | spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids); |
1961 | get_mux_nids(codec); | ||
1955 | spec->mixers[spec->num_mixers] = vt1709_capture_mixer; | 1962 | spec->mixers[spec->num_mixers] = vt1709_capture_mixer; |
1956 | spec->num_mixers++; | 1963 | spec->num_mixers++; |
1957 | } | 1964 | } |
@@ -2344,6 +2351,7 @@ static int vt1708B_parse_auto_config(struct hda_codec *codec) | |||
2344 | 2351 | ||
2345 | if (spec->autocfg.dig_outs) | 2352 | if (spec->autocfg.dig_outs) |
2346 | spec->multiout.dig_out_nid = VT1708B_DIGOUT_NID; | 2353 | spec->multiout.dig_out_nid = VT1708B_DIGOUT_NID; |
2354 | spec->dig_in_pin = VT1708B_DIGIN_PIN; | ||
2347 | if (spec->autocfg.dig_in_pin) | 2355 | if (spec->autocfg.dig_in_pin) |
2348 | spec->dig_in_nid = VT1708B_DIGIN_NID; | 2356 | spec->dig_in_nid = VT1708B_DIGIN_NID; |
2349 | 2357 | ||
@@ -2404,6 +2412,7 @@ static int patch_vt1708B_8ch(struct hda_codec *codec) | |||
2404 | if (!spec->adc_nids && spec->input_mux) { | 2412 | if (!spec->adc_nids && spec->input_mux) { |
2405 | spec->adc_nids = vt1708B_adc_nids; | 2413 | spec->adc_nids = vt1708B_adc_nids; |
2406 | spec->num_adc_nids = ARRAY_SIZE(vt1708B_adc_nids); | 2414 | spec->num_adc_nids = ARRAY_SIZE(vt1708B_adc_nids); |
2415 | get_mux_nids(codec); | ||
2407 | spec->mixers[spec->num_mixers] = vt1708B_capture_mixer; | 2416 | spec->mixers[spec->num_mixers] = vt1708B_capture_mixer; |
2408 | spec->num_mixers++; | 2417 | spec->num_mixers++; |
2409 | } | 2418 | } |
@@ -2455,6 +2464,7 @@ static int patch_vt1708B_4ch(struct hda_codec *codec) | |||
2455 | if (!spec->adc_nids && spec->input_mux) { | 2464 | if (!spec->adc_nids && spec->input_mux) { |
2456 | spec->adc_nids = vt1708B_adc_nids; | 2465 | spec->adc_nids = vt1708B_adc_nids; |
2457 | spec->num_adc_nids = ARRAY_SIZE(vt1708B_adc_nids); | 2466 | spec->num_adc_nids = ARRAY_SIZE(vt1708B_adc_nids); |
2467 | get_mux_nids(codec); | ||
2458 | spec->mixers[spec->num_mixers] = vt1708B_capture_mixer; | 2468 | spec->mixers[spec->num_mixers] = vt1708B_capture_mixer; |
2459 | spec->num_mixers++; | 2469 | spec->num_mixers++; |
2460 | } | 2470 | } |
@@ -2889,6 +2899,7 @@ static int patch_vt1708S(struct hda_codec *codec) | |||
2889 | if (!spec->adc_nids && spec->input_mux) { | 2899 | if (!spec->adc_nids && spec->input_mux) { |
2890 | spec->adc_nids = vt1708S_adc_nids; | 2900 | spec->adc_nids = vt1708S_adc_nids; |
2891 | spec->num_adc_nids = ARRAY_SIZE(vt1708S_adc_nids); | 2901 | spec->num_adc_nids = ARRAY_SIZE(vt1708S_adc_nids); |
2902 | get_mux_nids(codec); | ||
2892 | spec->mixers[spec->num_mixers] = vt1708S_capture_mixer; | 2903 | spec->mixers[spec->num_mixers] = vt1708S_capture_mixer; |
2893 | spec->num_mixers++; | 2904 | spec->num_mixers++; |
2894 | } | 2905 | } |
@@ -3206,6 +3217,7 @@ static int patch_vt1702(struct hda_codec *codec) | |||
3206 | if (!spec->adc_nids && spec->input_mux) { | 3217 | if (!spec->adc_nids && spec->input_mux) { |
3207 | spec->adc_nids = vt1702_adc_nids; | 3218 | spec->adc_nids = vt1702_adc_nids; |
3208 | spec->num_adc_nids = ARRAY_SIZE(vt1702_adc_nids); | 3219 | spec->num_adc_nids = ARRAY_SIZE(vt1702_adc_nids); |
3220 | get_mux_nids(codec); | ||
3209 | spec->mixers[spec->num_mixers] = vt1702_capture_mixer; | 3221 | spec->mixers[spec->num_mixers] = vt1702_capture_mixer; |
3210 | spec->num_mixers++; | 3222 | spec->num_mixers++; |
3211 | } | 3223 | } |