aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/core/pcm_lib.c8
-rw-r--r--sound/pci/hda/hda_codec.c48
-rw-r--r--sound/pci/hda/hda_codec.h1
-rw-r--r--sound/pci/hda/hda_hwdep.c7
-rw-r--r--sound/pci/hda/hda_intel.c51
-rw-r--r--sound/pci/hda/hda_local.h2
-rw-r--r--sound/pci/hda/patch_analog.c71
-rw-r--r--sound/pci/hda/patch_cirrus.c12
-rw-r--r--sound/pci/hda/patch_cmedia.c3
-rw-r--r--sound/pci/hda/patch_conexant.c382
-rw-r--r--sound/pci/hda/patch_realtek.c73
-rw-r--r--sound/pci/hda/patch_sigmatel.c113
-rw-r--r--sound/pci/hda/patch_via.c3
13 files changed, 591 insertions, 183 deletions
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index 0403a7d55f0c..720019560794 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -394,6 +394,7 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream,
394 + HZ/100); 394 + HZ/100);
395 /* move new_hw_ptr according jiffies not pos variable */ 395 /* move new_hw_ptr according jiffies not pos variable */
396 new_hw_ptr = old_hw_ptr; 396 new_hw_ptr = old_hw_ptr;
397 hw_base = delta;
397 /* use loop to avoid checks for delta overflows */ 398 /* use loop to avoid checks for delta overflows */
398 /* the delta value is small or zero in most cases */ 399 /* the delta value is small or zero in most cases */
399 while (delta > 0) { 400 while (delta > 0) {
@@ -403,8 +404,6 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream,
403 delta--; 404 delta--;
404 } 405 }
405 /* align hw_base to buffer_size */ 406 /* align hw_base to buffer_size */
406 hw_base = new_hw_ptr - (new_hw_ptr % runtime->buffer_size);
407 delta = 0;
408 hw_ptr_error(substream, 407 hw_ptr_error(substream,
409 "hw_ptr skipping! %s" 408 "hw_ptr skipping! %s"
410 "(pos=%ld, delta=%ld, period=%ld, " 409 "(pos=%ld, delta=%ld, period=%ld, "
@@ -412,9 +411,12 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream,
412 in_interrupt ? "[Q] " : "", 411 in_interrupt ? "[Q] " : "",
413 (long)pos, (long)hdelta, 412 (long)pos, (long)hdelta,
414 (long)runtime->period_size, jdelta, 413 (long)runtime->period_size, jdelta,
415 ((hdelta * HZ) / runtime->rate), delta, 414 ((hdelta * HZ) / runtime->rate), hw_base,
416 (unsigned long)old_hw_ptr, 415 (unsigned long)old_hw_ptr,
417 (unsigned long)new_hw_ptr); 416 (unsigned long)new_hw_ptr);
417 /* reset values to proper state */
418 delta = 0;
419 hw_base = new_hw_ptr - (new_hw_ptr % runtime->buffer_size);
418 } 420 }
419 no_jiffies_check: 421 no_jiffies_check:
420 if (delta > runtime->period_size + runtime->period_size / 2) { 422 if (delta > runtime->period_size + runtime->period_size / 2) {
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index d2f10b1c3a8a..d02ea8926e7e 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -824,6 +824,9 @@ int snd_hda_add_pincfg(struct hda_codec *codec, struct snd_array *list,
824 struct hda_pincfg *pin; 824 struct hda_pincfg *pin;
825 unsigned int oldcfg; 825 unsigned int oldcfg;
826 826
827 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
828 return -EINVAL;
829
827 oldcfg = snd_hda_codec_get_pincfg(codec, nid); 830 oldcfg = snd_hda_codec_get_pincfg(codec, nid);
828 pin = look_up_pincfg(codec, list, nid); 831 pin = look_up_pincfg(codec, list, nid);
829 if (!pin) { 832 if (!pin) {
@@ -899,6 +902,25 @@ static void restore_pincfgs(struct hda_codec *codec)
899 } 902 }
900} 903}
901 904
905/**
906 * snd_hda_shutup_pins - Shut up all pins
907 * @codec: the HDA codec
908 *
909 * Clear all pin controls to shup up before suspend for avoiding click noise.
910 * The controls aren't cached so that they can be resumed properly.
911 */
912void snd_hda_shutup_pins(struct hda_codec *codec)
913{
914 int i;
915 for (i = 0; i < codec->init_pins.used; i++) {
916 struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i);
917 /* use read here for syncing after issuing each verb */
918 snd_hda_codec_read(codec, pin->nid, 0,
919 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
920 }
921}
922EXPORT_SYMBOL_HDA(snd_hda_shutup_pins);
923
902static void init_hda_cache(struct hda_cache_rec *cache, 924static void init_hda_cache(struct hda_cache_rec *cache,
903 unsigned int record_size); 925 unsigned int record_size);
904static void free_hda_cache(struct hda_cache_rec *cache); 926static void free_hda_cache(struct hda_cache_rec *cache);
@@ -3537,32 +3559,6 @@ int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew)
3537} 3559}
3538EXPORT_SYMBOL_HDA(snd_hda_add_new_ctls); 3560EXPORT_SYMBOL_HDA(snd_hda_add_new_ctls);
3539 3561
3540/**
3541 * snd_hda_add_nids - assign nids to controls from the array
3542 * @codec: the HDA codec
3543 * @kctl: struct snd_kcontrol
3544 * @index: index to kctl
3545 * @nids: the array of hda_nid_t
3546 * @size: count of hda_nid_t items
3547 *
3548 * This helper function assigns NIDs in the given array to a control element.
3549 *
3550 * Returns 0 if successful, or a negative error code.
3551 */
3552int snd_hda_add_nids(struct hda_codec *codec, struct snd_kcontrol *kctl,
3553 unsigned int index, hda_nid_t *nids, unsigned int size)
3554{
3555 int err;
3556
3557 for ( ; size > 0; size--, nids++) {
3558 err = snd_hda_add_nid(codec, kctl, index, *nids);
3559 if (err < 0)
3560 return err;
3561 }
3562 return 0;
3563}
3564EXPORT_SYMBOL_HDA(snd_hda_add_nids);
3565
3566#ifdef CONFIG_SND_HDA_POWER_SAVE 3562#ifdef CONFIG_SND_HDA_POWER_SAVE
3567static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg, 3563static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
3568 unsigned int power_state); 3564 unsigned int power_state);
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index 0d08ad5bd898..11c4aa8ee996 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -898,6 +898,7 @@ int snd_hda_codec_set_pincfg(struct hda_codec *codec, hda_nid_t nid,
898 unsigned int cfg); 898 unsigned int cfg);
899int snd_hda_add_pincfg(struct hda_codec *codec, struct snd_array *list, 899int snd_hda_add_pincfg(struct hda_codec *codec, struct snd_array *list,
900 hda_nid_t nid, unsigned int cfg); /* for hwdep */ 900 hda_nid_t nid, unsigned int cfg); /* for hwdep */
901void snd_hda_shutup_pins(struct hda_codec *codec);
901 902
902/* 903/*
903 * Mixer 904 * Mixer
diff --git a/sound/pci/hda/hda_hwdep.c b/sound/pci/hda/hda_hwdep.c
index 40ccb419b6e9..b36919c0d363 100644
--- a/sound/pci/hda/hda_hwdep.c
+++ b/sound/pci/hda/hda_hwdep.c
@@ -293,8 +293,11 @@ static ssize_t type##_store(struct device *dev, \
293{ \ 293{ \
294 struct snd_hwdep *hwdep = dev_get_drvdata(dev); \ 294 struct snd_hwdep *hwdep = dev_get_drvdata(dev); \
295 struct hda_codec *codec = hwdep->private_data; \ 295 struct hda_codec *codec = hwdep->private_data; \
296 char *after; \ 296 unsigned long val; \
297 codec->type = simple_strtoul(buf, &after, 0); \ 297 int err = strict_strtoul(buf, 0, &val); \
298 if (err < 0) \
299 return err; \
300 codec->type = val; \
298 return count; \ 301 return count; \
299} 302}
300 303
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index ff8ad46cc50e..1f516e668d88 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -356,6 +356,7 @@ struct azx_dev {
356 */ 356 */
357 unsigned char stream_tag; /* assigned stream */ 357 unsigned char stream_tag; /* assigned stream */
358 unsigned char index; /* stream index */ 358 unsigned char index; /* stream index */
359 int device; /* last device number assigned to */
359 360
360 unsigned int opened :1; 361 unsigned int opened :1;
361 unsigned int running :1; 362 unsigned int running :1;
@@ -1441,10 +1442,13 @@ static int __devinit azx_codec_configure(struct azx *chip)
1441 */ 1442 */
1442 1443
1443/* assign a stream for the PCM */ 1444/* assign a stream for the PCM */
1444static inline struct azx_dev *azx_assign_device(struct azx *chip, int stream) 1445static inline struct azx_dev *
1446azx_assign_device(struct azx *chip, struct snd_pcm_substream *substream)
1445{ 1447{
1446 int dev, i, nums; 1448 int dev, i, nums;
1447 if (stream == SNDRV_PCM_STREAM_PLAYBACK) { 1449 struct azx_dev *res = NULL;
1450
1451 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
1448 dev = chip->playback_index_offset; 1452 dev = chip->playback_index_offset;
1449 nums = chip->playback_streams; 1453 nums = chip->playback_streams;
1450 } else { 1454 } else {
@@ -1453,10 +1457,15 @@ static inline struct azx_dev *azx_assign_device(struct azx *chip, int stream)
1453 } 1457 }
1454 for (i = 0; i < nums; i++, dev++) 1458 for (i = 0; i < nums; i++, dev++)
1455 if (!chip->azx_dev[dev].opened) { 1459 if (!chip->azx_dev[dev].opened) {
1456 chip->azx_dev[dev].opened = 1; 1460 res = &chip->azx_dev[dev];
1457 return &chip->azx_dev[dev]; 1461 if (res->device == substream->pcm->device)
1462 break;
1458 } 1463 }
1459 return NULL; 1464 if (res) {
1465 res->opened = 1;
1466 res->device = substream->pcm->device;
1467 }
1468 return res;
1460} 1469}
1461 1470
1462/* release the assigned stream */ 1471/* release the assigned stream */
@@ -1505,7 +1514,7 @@ static int azx_pcm_open(struct snd_pcm_substream *substream)
1505 int err; 1514 int err;
1506 1515
1507 mutex_lock(&chip->open_mutex); 1516 mutex_lock(&chip->open_mutex);
1508 azx_dev = azx_assign_device(chip, substream->stream); 1517 azx_dev = azx_assign_device(chip, substream);
1509 if (azx_dev == NULL) { 1518 if (azx_dev == NULL) {
1510 mutex_unlock(&chip->open_mutex); 1519 mutex_unlock(&chip->open_mutex);
1511 return -EBUSY; 1520 return -EBUSY;
@@ -2695,32 +2704,10 @@ static struct pci_device_id azx_ids[] = {
2695 /* ULI M5461 */ 2704 /* ULI M5461 */
2696 { PCI_DEVICE(0x10b9, 0x5461), .driver_data = AZX_DRIVER_ULI }, 2705 { PCI_DEVICE(0x10b9, 0x5461), .driver_data = AZX_DRIVER_ULI },
2697 /* NVIDIA MCP */ 2706 /* NVIDIA MCP */
2698 { PCI_DEVICE(0x10de, 0x026c), .driver_data = AZX_DRIVER_NVIDIA }, 2707 { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID),
2699 { PCI_DEVICE(0x10de, 0x0371), .driver_data = AZX_DRIVER_NVIDIA }, 2708 .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
2700 { PCI_DEVICE(0x10de, 0x03e4), .driver_data = AZX_DRIVER_NVIDIA }, 2709 .class_mask = 0xffffff,
2701 { PCI_DEVICE(0x10de, 0x03f0), .driver_data = AZX_DRIVER_NVIDIA }, 2710 .driver_data = AZX_DRIVER_NVIDIA },
2702 { PCI_DEVICE(0x10de, 0x044a), .driver_data = AZX_DRIVER_NVIDIA },
2703 { PCI_DEVICE(0x10de, 0x044b), .driver_data = AZX_DRIVER_NVIDIA },
2704 { PCI_DEVICE(0x10de, 0x055c), .driver_data = AZX_DRIVER_NVIDIA },
2705 { PCI_DEVICE(0x10de, 0x055d), .driver_data = AZX_DRIVER_NVIDIA },
2706 { PCI_DEVICE(0x10de, 0x0590), .driver_data = AZX_DRIVER_NVIDIA },
2707 { PCI_DEVICE(0x10de, 0x0774), .driver_data = AZX_DRIVER_NVIDIA },
2708 { PCI_DEVICE(0x10de, 0x0775), .driver_data = AZX_DRIVER_NVIDIA },
2709 { PCI_DEVICE(0x10de, 0x0776), .driver_data = AZX_DRIVER_NVIDIA },
2710 { PCI_DEVICE(0x10de, 0x0777), .driver_data = AZX_DRIVER_NVIDIA },
2711 { PCI_DEVICE(0x10de, 0x07fc), .driver_data = AZX_DRIVER_NVIDIA },
2712 { PCI_DEVICE(0x10de, 0x07fd), .driver_data = AZX_DRIVER_NVIDIA },
2713 { PCI_DEVICE(0x10de, 0x0ac0), .driver_data = AZX_DRIVER_NVIDIA },
2714 { PCI_DEVICE(0x10de, 0x0ac1), .driver_data = AZX_DRIVER_NVIDIA },
2715 { PCI_DEVICE(0x10de, 0x0ac2), .driver_data = AZX_DRIVER_NVIDIA },
2716 { PCI_DEVICE(0x10de, 0x0ac3), .driver_data = AZX_DRIVER_NVIDIA },
2717 { PCI_DEVICE(0x10de, 0x0be2), .driver_data = AZX_DRIVER_NVIDIA },
2718 { PCI_DEVICE(0x10de, 0x0be3), .driver_data = AZX_DRIVER_NVIDIA },
2719 { PCI_DEVICE(0x10de, 0x0be4), .driver_data = AZX_DRIVER_NVIDIA },
2720 { PCI_DEVICE(0x10de, 0x0d94), .driver_data = AZX_DRIVER_NVIDIA },
2721 { PCI_DEVICE(0x10de, 0x0d95), .driver_data = AZX_DRIVER_NVIDIA },
2722 { PCI_DEVICE(0x10de, 0x0d96), .driver_data = AZX_DRIVER_NVIDIA },
2723 { PCI_DEVICE(0x10de, 0x0d97), .driver_data = AZX_DRIVER_NVIDIA },
2724 /* Teradici */ 2711 /* Teradici */
2725 { PCI_DEVICE(0x6549, 0x1200), .driver_data = AZX_DRIVER_TERA }, 2712 { PCI_DEVICE(0x6549, 0x1200), .driver_data = AZX_DRIVER_TERA },
2726 /* Creative X-Fi (CA0110-IBG) */ 2713 /* Creative X-Fi (CA0110-IBG) */
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index d505d052972e..7cee364976ff 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -343,8 +343,6 @@ int snd_hda_check_board_codec_sid_config(struct hda_codec *codec,
343 const struct snd_pci_quirk *tbl); 343 const struct snd_pci_quirk *tbl);
344int snd_hda_add_new_ctls(struct hda_codec *codec, 344int snd_hda_add_new_ctls(struct hda_codec *codec,
345 struct snd_kcontrol_new *knew); 345 struct snd_kcontrol_new *knew);
346int snd_hda_add_nids(struct hda_codec *codec, struct snd_kcontrol *kctl,
347 unsigned int index, hda_nid_t *nids, unsigned int size);
348 346
349/* 347/*
350 * unsolicited event handler 348 * unsolicited event handler
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index 92b72d4f3984..cecd3c108990 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -244,8 +244,7 @@ static int ad198x_build_controls(struct hda_codec *codec)
244 if (!kctl) 244 if (!kctl)
245 kctl = snd_hda_find_mixer_ctl(codec, "Input Source"); 245 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
246 for (i = 0; kctl && i < kctl->count; i++) { 246 for (i = 0; kctl && i < kctl->count; i++) {
247 err = snd_hda_add_nids(codec, kctl, i, spec->capsrc_nids, 247 err = snd_hda_add_nid(codec, kctl, i, spec->capsrc_nids[i]);
248 spec->input_mux->num_items);
249 if (err < 0) 248 if (err < 0)
250 return err; 249 return err;
251 } 250 }
@@ -442,6 +441,11 @@ static int ad198x_build_pcms(struct hda_codec *codec)
442 return 0; 441 return 0;
443} 442}
444 443
444static inline void ad198x_shutup(struct hda_codec *codec)
445{
446 snd_hda_shutup_pins(codec);
447}
448
445static void ad198x_free_kctls(struct hda_codec *codec) 449static void ad198x_free_kctls(struct hda_codec *codec)
446{ 450{
447 struct ad198x_spec *spec = codec->spec; 451 struct ad198x_spec *spec = codec->spec;
@@ -455,6 +459,46 @@ static void ad198x_free_kctls(struct hda_codec *codec)
455 snd_array_free(&spec->kctls); 459 snd_array_free(&spec->kctls);
456} 460}
457 461
462static void ad198x_power_eapd_write(struct hda_codec *codec, hda_nid_t front,
463 hda_nid_t hp)
464{
465 struct ad198x_spec *spec = codec->spec;
466 snd_hda_codec_write(codec, front, 0, AC_VERB_SET_EAPD_BTLENABLE,
467 !spec->inv_eapd ? 0x00 : 0x02);
468 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_EAPD_BTLENABLE,
469 !spec->inv_eapd ? 0x00 : 0x02);
470}
471
472static void ad198x_power_eapd(struct hda_codec *codec)
473{
474 /* We currently only handle front, HP */
475 switch (codec->vendor_id) {
476 case 0x11d41882:
477 case 0x11d4882a:
478 case 0x11d41884:
479 case 0x11d41984:
480 case 0x11d41883:
481 case 0x11d4184a:
482 case 0x11d4194a:
483 case 0x11d4194b:
484 ad198x_power_eapd_write(codec, 0x12, 0x11);
485 break;
486 case 0x11d41981:
487 case 0x11d41983:
488 ad198x_power_eapd_write(codec, 0x05, 0x06);
489 break;
490 case 0x11d41986:
491 ad198x_power_eapd_write(codec, 0x1b, 0x1a);
492 break;
493 case 0x11d41988:
494 case 0x11d4198b:
495 case 0x11d4989a:
496 case 0x11d4989b:
497 ad198x_power_eapd_write(codec, 0x29, 0x22);
498 break;
499 }
500}
501
458static void ad198x_free(struct hda_codec *codec) 502static void ad198x_free(struct hda_codec *codec)
459{ 503{
460 struct ad198x_spec *spec = codec->spec; 504 struct ad198x_spec *spec = codec->spec;
@@ -462,11 +506,29 @@ static void ad198x_free(struct hda_codec *codec)
462 if (!spec) 506 if (!spec)
463 return; 507 return;
464 508
509 ad198x_shutup(codec);
465 ad198x_free_kctls(codec); 510 ad198x_free_kctls(codec);
466 kfree(spec); 511 kfree(spec);
467 snd_hda_detach_beep_device(codec); 512 snd_hda_detach_beep_device(codec);
468} 513}
469 514
515#ifdef SND_HDA_NEEDS_RESUME
516static int ad198x_suspend(struct hda_codec *codec, pm_message_t state)
517{
518 ad198x_shutup(codec);
519 ad198x_power_eapd(codec);
520 return 0;
521}
522
523static int ad198x_resume(struct hda_codec *codec)
524{
525 ad198x_init(codec);
526 snd_hda_codec_resume_amp(codec);
527 snd_hda_codec_resume_cache(codec);
528 return 0;
529}
530#endif
531
470static struct hda_codec_ops ad198x_patch_ops = { 532static struct hda_codec_ops ad198x_patch_ops = {
471 .build_controls = ad198x_build_controls, 533 .build_controls = ad198x_build_controls,
472 .build_pcms = ad198x_build_pcms, 534 .build_pcms = ad198x_build_pcms,
@@ -475,6 +537,11 @@ static struct hda_codec_ops ad198x_patch_ops = {
475#ifdef CONFIG_SND_HDA_POWER_SAVE 537#ifdef CONFIG_SND_HDA_POWER_SAVE
476 .check_power_status = ad198x_check_power_status, 538 .check_power_status = ad198x_check_power_status,
477#endif 539#endif
540#ifdef SND_HDA_NEEDS_RESUME
541 .suspend = ad198x_suspend,
542 .resume = ad198x_resume,
543#endif
544 .reboot_notify = ad198x_shutup,
478}; 545};
479 546
480 547
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c
index 093cfbb55e9e..7de782a5b8f4 100644
--- a/sound/pci/hda/patch_cirrus.c
+++ b/sound/pci/hda/patch_cirrus.c
@@ -753,6 +753,7 @@ static int build_input(struct hda_codec *codec)
753 spec->capture_bind[1] = make_bind_capture(codec, &snd_hda_bind_vol); 753 spec->capture_bind[1] = make_bind_capture(codec, &snd_hda_bind_vol);
754 for (i = 0; i < 2; i++) { 754 for (i = 0; i < 2; i++) {
755 struct snd_kcontrol *kctl; 755 struct snd_kcontrol *kctl;
756 int n;
756 if (!spec->capture_bind[i]) 757 if (!spec->capture_bind[i])
757 return -ENOMEM; 758 return -ENOMEM;
758 kctl = snd_ctl_new1(&cs_capture_ctls[i], codec); 759 kctl = snd_ctl_new1(&cs_capture_ctls[i], codec);
@@ -762,10 +763,13 @@ static int build_input(struct hda_codec *codec)
762 err = snd_hda_ctl_add(codec, 0, kctl); 763 err = snd_hda_ctl_add(codec, 0, kctl);
763 if (err < 0) 764 if (err < 0)
764 return err; 765 return err;
765 err = snd_hda_add_nids(codec, kctl, 0, spec->adc_nid, 766 for (n = 0; n < AUTO_PIN_LAST; n++) {
766 spec->num_inputs); 767 if (!spec->adc_nid[n])
767 if (err < 0) 768 continue;
768 return err; 769 err = snd_hda_add_nid(codec, kctl, 0, spec->adc_nid[i]);
770 if (err < 0)
771 return err;
772 }
769 } 773 }
770 774
771 if (spec->num_inputs > 1 && !spec->mic_detect) { 775 if (spec->num_inputs > 1 && !spec->mic_detect) {
diff --git a/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c
index cc1c22370a60..ff60908f4554 100644
--- a/sound/pci/hda/patch_cmedia.c
+++ b/sound/pci/hda/patch_cmedia.c
@@ -345,8 +345,7 @@ static int cmi9880_build_controls(struct hda_codec *codec)
345 /* assign Capture Source enums to NID */ 345 /* assign Capture Source enums to NID */
346 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source"); 346 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
347 for (i = 0; kctl && i < kctl->count; i++) { 347 for (i = 0; kctl && i < kctl->count; i++) {
348 err = snd_hda_add_nids(codec, kctl, i, spec->adc_nids, 348 err = snd_hda_add_nid(codec, kctl, i, spec->adc_nids[i]);
349 spec->input_mux->num_items);
350 if (err < 0) 349 if (err < 0)
351 return err; 350 return err;
352 } 351 }
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 947785f43b28..685015a53292 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -111,8 +111,22 @@ struct conexant_spec {
111 111
112 unsigned int dell_automute; 112 unsigned int dell_automute;
113 unsigned int port_d_mode; 113 unsigned int port_d_mode;
114 unsigned char ext_mic_bias;
115 unsigned int dell_vostro; 114 unsigned int dell_vostro;
115
116 unsigned int ext_mic_present;
117 unsigned int recording;
118 void (*capture_prepare)(struct hda_codec *codec);
119 void (*capture_cleanup)(struct hda_codec *codec);
120
121 /* OLPC XO-1.5 supports DC input mode (e.g. for use with analog sensors)
122 * through the microphone jack.
123 * When the user enables this through a mixer switch, both internal and
124 * external microphones are disabled. Gain is fixed at 0dB. In this mode,
125 * we also allow the bias to be configured through a separate mixer
126 * control. */
127 unsigned int dc_enable;
128 unsigned int dc_input_bias; /* offset into cxt5066_olpc_dc_bias */
129 unsigned int mic_boost; /* offset into cxt5066_analog_mic_boost */
116}; 130};
117 131
118static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo, 132static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo,
@@ -185,6 +199,8 @@ static int conexant_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
185 struct snd_pcm_substream *substream) 199 struct snd_pcm_substream *substream)
186{ 200{
187 struct conexant_spec *spec = codec->spec; 201 struct conexant_spec *spec = codec->spec;
202 if (spec->capture_prepare)
203 spec->capture_prepare(codec);
188 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], 204 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
189 stream_tag, 0, format); 205 stream_tag, 0, format);
190 return 0; 206 return 0;
@@ -196,6 +212,8 @@ static int conexant_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
196{ 212{
197 struct conexant_spec *spec = codec->spec; 213 struct conexant_spec *spec = codec->spec;
198 snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number]); 214 snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number]);
215 if (spec->capture_cleanup)
216 spec->capture_cleanup(codec);
199 return 0; 217 return 0;
200} 218}
201 219
@@ -1723,6 +1741,22 @@ static struct snd_kcontrol_new cxt5051_hp_dv6736_mixers[] = {
1723 {} 1741 {}
1724}; 1742};
1725 1743
1744static struct snd_kcontrol_new cxt5051_f700_mixers[] = {
1745 HDA_CODEC_VOLUME("Mic Volume", 0x14, 0x01, HDA_INPUT),
1746 HDA_CODEC_MUTE("Mic Switch", 0x14, 0x01, HDA_INPUT),
1747 HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT),
1748 {
1749 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1750 .name = "Master Playback Switch",
1751 .info = cxt_eapd_info,
1752 .get = cxt_eapd_get,
1753 .put = cxt5051_hp_master_sw_put,
1754 .private_value = 0x1a,
1755 },
1756
1757 {}
1758};
1759
1726static struct hda_verb cxt5051_init_verbs[] = { 1760static struct hda_verb cxt5051_init_verbs[] = {
1727 /* Line in, Mic */ 1761 /* Line in, Mic */
1728 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03}, 1762 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
@@ -1813,6 +1847,32 @@ static struct hda_verb cxt5051_lenovo_x200_init_verbs[] = {
1813 { } /* end */ 1847 { } /* end */
1814}; 1848};
1815 1849
1850static struct hda_verb cxt5051_f700_init_verbs[] = {
1851 /* Line in, Mic */
1852 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x03},
1853 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1854 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0},
1855 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0},
1856 /* SPK */
1857 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1858 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
1859 /* HP, Amp */
1860 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1861 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
1862 /* DAC1 */
1863 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1864 /* Record selector: Int mic */
1865 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44},
1866 {0x14, AC_VERB_SET_CONNECT_SEL, 0x1},
1867 /* SPDIF route: PCM */
1868 {0x1c, AC_VERB_SET_CONNECT_SEL, 0x0},
1869 /* EAPD */
1870 {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
1871 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
1872 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CXT5051_PORTB_EVENT},
1873 { } /* end */
1874};
1875
1816/* initialize jack-sensing, too */ 1876/* initialize jack-sensing, too */
1817static int cxt5051_init(struct hda_codec *codec) 1877static int cxt5051_init(struct hda_codec *codec)
1818{ 1878{
@@ -1832,6 +1892,7 @@ enum {
1832 CXT5051_HP, /* no docking */ 1892 CXT5051_HP, /* no docking */
1833 CXT5051_HP_DV6736, /* HP without mic switch */ 1893 CXT5051_HP_DV6736, /* HP without mic switch */
1834 CXT5051_LENOVO_X200, /* Lenovo X200 laptop */ 1894 CXT5051_LENOVO_X200, /* Lenovo X200 laptop */
1895 CXT5051_F700, /* HP Compaq Presario F700 */
1835 CXT5051_MODELS 1896 CXT5051_MODELS
1836}; 1897};
1837 1898
@@ -1840,6 +1901,7 @@ static const char *cxt5051_models[CXT5051_MODELS] = {
1840 [CXT5051_HP] = "hp", 1901 [CXT5051_HP] = "hp",
1841 [CXT5051_HP_DV6736] = "hp-dv6736", 1902 [CXT5051_HP_DV6736] = "hp-dv6736",
1842 [CXT5051_LENOVO_X200] = "lenovo-x200", 1903 [CXT5051_LENOVO_X200] = "lenovo-x200",
1904 [CXT5051_F700] = "hp 700"
1843}; 1905};
1844 1906
1845static struct snd_pci_quirk cxt5051_cfg_tbl[] = { 1907static struct snd_pci_quirk cxt5051_cfg_tbl[] = {
@@ -1849,6 +1911,7 @@ static struct snd_pci_quirk cxt5051_cfg_tbl[] = {
1849 CXT5051_LAPTOP), 1911 CXT5051_LAPTOP),
1850 SND_PCI_QUIRK(0x14f1, 0x5051, "HP Spartan 1.1", CXT5051_HP), 1912 SND_PCI_QUIRK(0x14f1, 0x5051, "HP Spartan 1.1", CXT5051_HP),
1851 SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo X200", CXT5051_LENOVO_X200), 1913 SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo X200", CXT5051_LENOVO_X200),
1914 SND_PCI_QUIRK(0x103c, 0x30ea, "Compaq Presario F700", CXT5051_F700),
1852 {} 1915 {}
1853}; 1916};
1854 1917
@@ -1899,6 +1962,11 @@ static int patch_cxt5051(struct hda_codec *codec)
1899 case CXT5051_LENOVO_X200: 1962 case CXT5051_LENOVO_X200:
1900 spec->init_verbs[0] = cxt5051_lenovo_x200_init_verbs; 1963 spec->init_verbs[0] = cxt5051_lenovo_x200_init_verbs;
1901 break; 1964 break;
1965 case CXT5051_F700:
1966 spec->init_verbs[0] = cxt5051_f700_init_verbs;
1967 spec->mixers[0] = cxt5051_f700_mixers;
1968 spec->no_auto_mic = 1;
1969 break;
1902 } 1970 }
1903 1971
1904 return 0; 1972 return 0;
@@ -1966,53 +2034,97 @@ static int cxt5066_hp_master_sw_put(struct snd_kcontrol *kcontrol,
1966 return 1; 2034 return 1;
1967} 2035}
1968 2036
1969/* toggle input of built-in and mic jack appropriately */ 2037static const struct hda_input_mux cxt5066_olpc_dc_bias = {
1970static void cxt5066_automic(struct hda_codec *codec) 2038 .num_items = 3,
2039 .items = {
2040 { "Off", PIN_IN },
2041 { "50%", PIN_VREF50 },
2042 { "80%", PIN_VREF80 },
2043 },
2044};
2045
2046static int cxt5066_set_olpc_dc_bias(struct hda_codec *codec)
1971{ 2047{
1972 struct conexant_spec *spec = codec->spec; 2048 struct conexant_spec *spec = codec->spec;
1973 struct hda_verb ext_mic_present[] = { 2049 /* Even though port F is the DC input, the bias is controlled on port B.
1974 /* enable external mic, port B */ 2050 * we also leave that port as an active input (but unselected) in DC mode
1975 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, spec->ext_mic_bias}, 2051 * just in case that is necessary to make the bias setting take effect. */
2052 return snd_hda_codec_write_cache(codec, 0x1a, 0,
2053 AC_VERB_SET_PIN_WIDGET_CONTROL,
2054 cxt5066_olpc_dc_bias.items[spec->dc_input_bias].index);
2055}
1976 2056
1977 /* switch to external mic input */ 2057/* OLPC defers mic widget control until when capture is started because the
1978 {0x17, AC_VERB_SET_CONNECT_SEL, 0}, 2058 * microphone LED comes on as soon as these settings are put in place. if we
2059 * did this before recording, it would give the false indication that recording
2060 * is happening when it is not. */
2061static void cxt5066_olpc_select_mic(struct hda_codec *codec)
2062{
2063 struct conexant_spec *spec = codec->spec;
2064 if (!spec->recording)
2065 return;
1979 2066
1980 /* disable internal mic, port C */ 2067 if (spec->dc_enable) {
1981 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2068 /* in DC mode we ignore presence detection and just use the jack
1982 {} 2069 * through our special DC port */
1983 }; 2070 const struct hda_verb enable_dc_mode[] = {
1984 static struct hda_verb ext_mic_absent[] = { 2071 /* disble internal mic, port C */
1985 /* enable internal mic, port C */ 2072 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
1986 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2073
2074 /* enable DC capture, port F */
2075 {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2076 {},
2077 };
2078
2079 snd_hda_sequence_write(codec, enable_dc_mode);
2080 /* port B input disabled (and bias set) through the following call */
2081 cxt5066_set_olpc_dc_bias(codec);
2082 return;
2083 }
1987 2084
1988 /* switch to internal mic input */ 2085 /* disable DC (port F) */
1989 {0x17, AC_VERB_SET_CONNECT_SEL, 1}, 2086 snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
1990 2087
1991 /* disable external mic, port B */ 2088 /* external mic, port B */
1992 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2089 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
1993 {} 2090 spec->ext_mic_present ? CXT5066_OLPC_EXT_MIC_BIAS : 0);
1994 }; 2091
2092 /* internal mic, port C */
2093 snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
2094 spec->ext_mic_present ? 0 : PIN_VREF80);
2095}
2096
2097/* toggle input of built-in and mic jack appropriately */
2098static void cxt5066_olpc_automic(struct hda_codec *codec)
2099{
2100 struct conexant_spec *spec = codec->spec;
1995 unsigned int present; 2101 unsigned int present;
1996 2102
1997 present = snd_hda_jack_detect(codec, 0x1a); 2103 if (spec->dc_enable) /* don't do presence detection in DC mode */
1998 if (present) { 2104 return;
2105
2106 present = snd_hda_codec_read(codec, 0x1a, 0,
2107 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2108 if (present)
1999 snd_printdd("CXT5066: external microphone detected\n"); 2109 snd_printdd("CXT5066: external microphone detected\n");
2000 snd_hda_sequence_write(codec, ext_mic_present); 2110 else
2001 } else {
2002 snd_printdd("CXT5066: external microphone absent\n"); 2111 snd_printdd("CXT5066: external microphone absent\n");
2003 snd_hda_sequence_write(codec, ext_mic_absent); 2112
2004 } 2113 snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_CONNECT_SEL,
2114 present ? 0 : 1);
2115 spec->ext_mic_present = !!present;
2116
2117 cxt5066_olpc_select_mic(codec);
2005} 2118}
2006 2119
2007/* toggle input of built-in digital mic and mic jack appropriately */ 2120/* toggle input of built-in digital mic and mic jack appropriately */
2008static void cxt5066_vostro_automic(struct hda_codec *codec) 2121static void cxt5066_vostro_automic(struct hda_codec *codec)
2009{ 2122{
2010 struct conexant_spec *spec = codec->spec;
2011 unsigned int present; 2123 unsigned int present;
2012 2124
2013 struct hda_verb ext_mic_present[] = { 2125 struct hda_verb ext_mic_present[] = {
2014 /* enable external mic, port B */ 2126 /* enable external mic, port B */
2015 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, spec->ext_mic_bias}, 2127 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2016 2128
2017 /* switch to external mic input */ 2129 /* switch to external mic input */
2018 {0x17, AC_VERB_SET_CONNECT_SEL, 0}, 2130 {0x17, AC_VERB_SET_CONNECT_SEL, 0},
@@ -2063,15 +2175,18 @@ static void cxt5066_hp_automute(struct hda_codec *codec)
2063} 2175}
2064 2176
2065/* unsolicited event for jack sensing */ 2177/* unsolicited event for jack sensing */
2066static void cxt5066_unsol_event(struct hda_codec *codec, unsigned int res) 2178static void cxt5066_olpc_unsol_event(struct hda_codec *codec, unsigned int res)
2067{ 2179{
2180 struct conexant_spec *spec = codec->spec;
2068 snd_printdd("CXT5066: unsol event %x (%x)\n", res, res >> 26); 2181 snd_printdd("CXT5066: unsol event %x (%x)\n", res, res >> 26);
2069 switch (res >> 26) { 2182 switch (res >> 26) {
2070 case CONEXANT_HP_EVENT: 2183 case CONEXANT_HP_EVENT:
2071 cxt5066_hp_automute(codec); 2184 cxt5066_hp_automute(codec);
2072 break; 2185 break;
2073 case CONEXANT_MIC_EVENT: 2186 case CONEXANT_MIC_EVENT:
2074 cxt5066_automic(codec); 2187 /* ignore mic events in DC mode; we're always using the jack */
2188 if (!spec->dc_enable)
2189 cxt5066_olpc_automic(codec);
2075 break; 2190 break;
2076 } 2191 }
2077} 2192}
@@ -2101,6 +2216,15 @@ static const struct hda_input_mux cxt5066_analog_mic_boost = {
2101 }, 2216 },
2102}; 2217};
2103 2218
2219static int cxt5066_set_mic_boost(struct hda_codec *codec)
2220{
2221 struct conexant_spec *spec = codec->spec;
2222 return snd_hda_codec_write_cache(codec, 0x17, 0,
2223 AC_VERB_SET_AMP_GAIN_MUTE,
2224 AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | AC_AMP_SET_OUTPUT |
2225 cxt5066_analog_mic_boost.items[spec->mic_boost].index);
2226}
2227
2104static int cxt5066_mic_boost_mux_enum_info(struct snd_kcontrol *kcontrol, 2228static int cxt5066_mic_boost_mux_enum_info(struct snd_kcontrol *kcontrol,
2105 struct snd_ctl_elem_info *uinfo) 2229 struct snd_ctl_elem_info *uinfo)
2106{ 2230{
@@ -2111,15 +2235,8 @@ static int cxt5066_mic_boost_mux_enum_get(struct snd_kcontrol *kcontrol,
2111 struct snd_ctl_elem_value *ucontrol) 2235 struct snd_ctl_elem_value *ucontrol)
2112{ 2236{
2113 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2237 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2114 int val; 2238 struct conexant_spec *spec = codec->spec;
2115 hda_nid_t nid = kcontrol->private_value & 0xff; 2239 ucontrol->value.enumerated.item[0] = spec->mic_boost;
2116 int inout = (kcontrol->private_value & 0x100) ?
2117 AC_AMP_GET_INPUT : AC_AMP_GET_OUTPUT;
2118
2119 val = snd_hda_codec_read(codec, nid, 0,
2120 AC_VERB_GET_AMP_GAIN_MUTE, inout);
2121
2122 ucontrol->value.enumerated.item[0] = val & AC_AMP_GAIN;
2123 return 0; 2240 return 0;
2124} 2241}
2125 2242
@@ -2127,26 +2244,132 @@ static int cxt5066_mic_boost_mux_enum_put(struct snd_kcontrol *kcontrol,
2127 struct snd_ctl_elem_value *ucontrol) 2244 struct snd_ctl_elem_value *ucontrol)
2128{ 2245{
2129 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2246 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2247 struct conexant_spec *spec = codec->spec;
2130 const struct hda_input_mux *imux = &cxt5066_analog_mic_boost; 2248 const struct hda_input_mux *imux = &cxt5066_analog_mic_boost;
2131 unsigned int idx; 2249 unsigned int idx;
2132 hda_nid_t nid = kcontrol->private_value & 0xff; 2250 idx = ucontrol->value.enumerated.item[0];
2133 int inout = (kcontrol->private_value & 0x100) ? 2251 if (idx >= imux->num_items)
2134 AC_AMP_SET_INPUT : AC_AMP_SET_OUTPUT; 2252 idx = imux->num_items - 1;
2253
2254 spec->mic_boost = idx;
2255 if (!spec->dc_enable)
2256 cxt5066_set_mic_boost(codec);
2257 return 1;
2258}
2259
2260static void cxt5066_enable_dc(struct hda_codec *codec)
2261{
2262 const struct hda_verb enable_dc_mode[] = {
2263 /* disable gain */
2264 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2265
2266 /* switch to DC input */
2267 {0x17, AC_VERB_SET_CONNECT_SEL, 3},
2268 {}
2269 };
2270
2271 /* configure as input source */
2272 snd_hda_sequence_write(codec, enable_dc_mode);
2273 cxt5066_olpc_select_mic(codec); /* also sets configured bias */
2274}
2275
2276static void cxt5066_disable_dc(struct hda_codec *codec)
2277{
2278 /* reconfigure input source */
2279 cxt5066_set_mic_boost(codec);
2280 /* automic also selects the right mic if we're recording */
2281 cxt5066_olpc_automic(codec);
2282}
2283
2284static int cxt5066_olpc_dc_get(struct snd_kcontrol *kcontrol,
2285 struct snd_ctl_elem_value *ucontrol)
2286{
2287 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2288 struct conexant_spec *spec = codec->spec;
2289 ucontrol->value.integer.value[0] = spec->dc_enable;
2290 return 0;
2291}
2292
2293static int cxt5066_olpc_dc_put(struct snd_kcontrol *kcontrol,
2294 struct snd_ctl_elem_value *ucontrol)
2295{
2296 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2297 struct conexant_spec *spec = codec->spec;
2298 int dc_enable = !!ucontrol->value.integer.value[0];
2135 2299
2136 if (!imux->num_items) 2300 if (dc_enable == spec->dc_enable)
2137 return 0; 2301 return 0;
2302
2303 spec->dc_enable = dc_enable;
2304 if (dc_enable)
2305 cxt5066_enable_dc(codec);
2306 else
2307 cxt5066_disable_dc(codec);
2308
2309 return 1;
2310}
2311
2312static int cxt5066_olpc_dc_bias_enum_info(struct snd_kcontrol *kcontrol,
2313 struct snd_ctl_elem_info *uinfo)
2314{
2315 return snd_hda_input_mux_info(&cxt5066_olpc_dc_bias, uinfo);
2316}
2317
2318static int cxt5066_olpc_dc_bias_enum_get(struct snd_kcontrol *kcontrol,
2319 struct snd_ctl_elem_value *ucontrol)
2320{
2321 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2322 struct conexant_spec *spec = codec->spec;
2323 ucontrol->value.enumerated.item[0] = spec->dc_input_bias;
2324 return 0;
2325}
2326
2327static int cxt5066_olpc_dc_bias_enum_put(struct snd_kcontrol *kcontrol,
2328 struct snd_ctl_elem_value *ucontrol)
2329{
2330 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2331 struct conexant_spec *spec = codec->spec;
2332 const struct hda_input_mux *imux = &cxt5066_analog_mic_boost;
2333 unsigned int idx;
2334
2138 idx = ucontrol->value.enumerated.item[0]; 2335 idx = ucontrol->value.enumerated.item[0];
2139 if (idx >= imux->num_items) 2336 if (idx >= imux->num_items)
2140 idx = imux->num_items - 1; 2337 idx = imux->num_items - 1;
2141 2338
2142 snd_hda_codec_write_cache(codec, nid, 0, 2339 spec->dc_input_bias = idx;
2143 AC_VERB_SET_AMP_GAIN_MUTE, 2340 if (spec->dc_enable)
2144 AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | inout | 2341 cxt5066_set_olpc_dc_bias(codec);
2145 imux->items[idx].index);
2146
2147 return 1; 2342 return 1;
2148} 2343}
2149 2344
2345static void cxt5066_olpc_capture_prepare(struct hda_codec *codec)
2346{
2347 struct conexant_spec *spec = codec->spec;
2348 /* mark as recording and configure the microphone widget so that the
2349 * recording LED comes on. */
2350 spec->recording = 1;
2351 cxt5066_olpc_select_mic(codec);
2352}
2353
2354static void cxt5066_olpc_capture_cleanup(struct hda_codec *codec)
2355{
2356 struct conexant_spec *spec = codec->spec;
2357 const struct hda_verb disable_mics[] = {
2358 /* disable external mic, port B */
2359 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2360
2361 /* disble internal mic, port C */
2362 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2363
2364 /* disable DC capture, port F */
2365 {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2366 {},
2367 };
2368
2369 snd_hda_sequence_write(codec, disable_mics);
2370 spec->recording = 0;
2371}
2372
2150static struct hda_input_mux cxt5066_capture_source = { 2373static struct hda_input_mux cxt5066_capture_source = {
2151 .num_items = 4, 2374 .num_items = 4,
2152 .items = { 2375 .items = {
@@ -2199,6 +2422,24 @@ static struct snd_kcontrol_new cxt5066_mixer_master_olpc[] = {
2199 {} 2422 {}
2200}; 2423};
2201 2424
2425static struct snd_kcontrol_new cxt5066_mixer_olpc_dc[] = {
2426 {
2427 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2428 .name = "DC Mode Enable Switch",
2429 .info = snd_ctl_boolean_mono_info,
2430 .get = cxt5066_olpc_dc_get,
2431 .put = cxt5066_olpc_dc_put,
2432 },
2433 {
2434 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2435 .name = "DC Input Bias Enum",
2436 .info = cxt5066_olpc_dc_bias_enum_info,
2437 .get = cxt5066_olpc_dc_bias_enum_get,
2438 .put = cxt5066_olpc_dc_bias_enum_put,
2439 },
2440 {}
2441};
2442
2202static struct snd_kcontrol_new cxt5066_mixers[] = { 2443static struct snd_kcontrol_new cxt5066_mixers[] = {
2203 { 2444 {
2204 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2445 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -2211,11 +2452,10 @@ static struct snd_kcontrol_new cxt5066_mixers[] = {
2211 2452
2212 { 2453 {
2213 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2454 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2214 .name = "Ext Mic Boost Capture Enum", 2455 .name = "Analog Mic Boost Capture Enum",
2215 .info = cxt5066_mic_boost_mux_enum_info, 2456 .info = cxt5066_mic_boost_mux_enum_info,
2216 .get = cxt5066_mic_boost_mux_enum_get, 2457 .get = cxt5066_mic_boost_mux_enum_get,
2217 .put = cxt5066_mic_boost_mux_enum_put, 2458 .put = cxt5066_mic_boost_mux_enum_put,
2218 .private_value = 0x17,
2219 }, 2459 },
2220 2460
2221 HDA_BIND_VOL("Capture Volume", &cxt5066_bind_capture_vol_others), 2461 HDA_BIND_VOL("Capture Volume", &cxt5066_bind_capture_vol_others),
@@ -2297,10 +2537,10 @@ static struct hda_verb cxt5066_init_verbs_olpc[] = {
2297 {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */ 2537 {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2298 2538
2299 /* Port B: external microphone */ 2539 /* Port B: external microphone */
2300 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, CXT5066_OLPC_EXT_MIC_BIAS}, 2540 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2301 2541
2302 /* Port C: internal microphone */ 2542 /* Port C: internal microphone */
2303 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2543 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2304 2544
2305 /* Port D: unused */ 2545 /* Port D: unused */
2306 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2546 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
@@ -2309,7 +2549,7 @@ static struct hda_verb cxt5066_init_verbs_olpc[] = {
2309 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2549 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2310 {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ 2550 {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
2311 2551
2312 /* Port F: unused */ 2552 /* Port F: external DC input through microphone port */
2313 {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2553 {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2314 2554
2315 /* Port G: internal speakers */ 2555 /* Port G: internal speakers */
@@ -2429,8 +2669,22 @@ static int cxt5066_init(struct hda_codec *codec)
2429 cxt5066_hp_automute(codec); 2669 cxt5066_hp_automute(codec);
2430 if (spec->dell_vostro) 2670 if (spec->dell_vostro)
2431 cxt5066_vostro_automic(codec); 2671 cxt5066_vostro_automic(codec);
2432 else 2672 }
2433 cxt5066_automic(codec); 2673 cxt5066_set_mic_boost(codec);
2674 return 0;
2675}
2676
2677static int cxt5066_olpc_init(struct hda_codec *codec)
2678{
2679 struct conexant_spec *spec = codec->spec;
2680 snd_printdd("CXT5066: init\n");
2681 conexant_init(codec);
2682 cxt5066_hp_automute(codec);
2683 if (!spec->dc_enable) {
2684 cxt5066_set_mic_boost(codec);
2685 cxt5066_olpc_automic(codec);
2686 } else {
2687 cxt5066_enable_dc(codec);
2434 } 2688 }
2435 return 0; 2689 return 0;
2436} 2690}
@@ -2471,7 +2725,7 @@ static int patch_cxt5066(struct hda_codec *codec)
2471 codec->spec = spec; 2725 codec->spec = spec;
2472 2726
2473 codec->patch_ops = conexant_patch_ops; 2727 codec->patch_ops = conexant_patch_ops;
2474 codec->patch_ops.init = cxt5066_init; 2728 codec->patch_ops.init = conexant_init;
2475 2729
2476 spec->dell_automute = 0; 2730 spec->dell_automute = 0;
2477 spec->multiout.max_channels = 2; 2731 spec->multiout.max_channels = 2;
@@ -2484,7 +2738,6 @@ static int patch_cxt5066(struct hda_codec *codec)
2484 spec->input_mux = &cxt5066_capture_source; 2738 spec->input_mux = &cxt5066_capture_source;
2485 2739
2486 spec->port_d_mode = PIN_HP; 2740 spec->port_d_mode = PIN_HP;
2487 spec->ext_mic_bias = PIN_VREF80;
2488 2741
2489 spec->num_init_verbs = 1; 2742 spec->num_init_verbs = 1;
2490 spec->init_verbs[0] = cxt5066_init_verbs; 2743 spec->init_verbs[0] = cxt5066_init_verbs;
@@ -2511,20 +2764,28 @@ static int patch_cxt5066(struct hda_codec *codec)
2511 spec->dell_automute = 1; 2764 spec->dell_automute = 1;
2512 break; 2765 break;
2513 case CXT5066_OLPC_XO_1_5: 2766 case CXT5066_OLPC_XO_1_5:
2514 codec->patch_ops.unsol_event = cxt5066_unsol_event; 2767 codec->patch_ops.init = cxt5066_olpc_init;
2768 codec->patch_ops.unsol_event = cxt5066_olpc_unsol_event;
2515 spec->init_verbs[0] = cxt5066_init_verbs_olpc; 2769 spec->init_verbs[0] = cxt5066_init_verbs_olpc;
2516 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master_olpc; 2770 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master_olpc;
2771 spec->mixers[spec->num_mixers++] = cxt5066_mixer_olpc_dc;
2517 spec->mixers[spec->num_mixers++] = cxt5066_mixers; 2772 spec->mixers[spec->num_mixers++] = cxt5066_mixers;
2518 spec->port_d_mode = 0; 2773 spec->port_d_mode = 0;
2519 spec->ext_mic_bias = CXT5066_OLPC_EXT_MIC_BIAS; 2774 spec->mic_boost = 3; /* default 30dB gain */
2520 2775
2521 /* no S/PDIF out */ 2776 /* no S/PDIF out */
2522 spec->multiout.dig_out_nid = 0; 2777 spec->multiout.dig_out_nid = 0;
2523 2778
2524 /* input source automatically selected */ 2779 /* input source automatically selected */
2525 spec->input_mux = NULL; 2780 spec->input_mux = NULL;
2781
2782 /* our capture hooks which allow us to turn on the microphone LED
2783 * at the right time */
2784 spec->capture_prepare = cxt5066_olpc_capture_prepare;
2785 spec->capture_cleanup = cxt5066_olpc_capture_cleanup;
2526 break; 2786 break;
2527 case CXT5066_DELL_VOSTO: 2787 case CXT5066_DELL_VOSTO:
2788 codec->patch_ops.init = cxt5066_init;
2528 codec->patch_ops.unsol_event = cxt5066_vostro_event; 2789 codec->patch_ops.unsol_event = cxt5066_vostro_event;
2529 spec->init_verbs[0] = cxt5066_init_verbs_vostro; 2790 spec->init_verbs[0] = cxt5066_init_verbs_vostro;
2530 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master_olpc; 2791 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master_olpc;
@@ -2532,6 +2793,7 @@ static int patch_cxt5066(struct hda_codec *codec)
2532 spec->mixers[spec->num_mixers++] = cxt5066_vostro_mixers; 2793 spec->mixers[spec->num_mixers++] = cxt5066_vostro_mixers;
2533 spec->port_d_mode = 0; 2794 spec->port_d_mode = 0;
2534 spec->dell_vostro = 1; 2795 spec->dell_vostro = 1;
2796 spec->mic_boost = 3; /* default 30dB gain */
2535 snd_hda_attach_beep_device(codec, 0x13); 2797 snd_hda_attach_beep_device(codec, 0x13);
2536 2798
2537 /* no S/PDIF out */ 2799 /* no S/PDIF out */
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index aeb23ef6afe5..141ff446104a 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -338,7 +338,7 @@ struct alc_spec {
338 void (*init_hook)(struct hda_codec *codec); 338 void (*init_hook)(struct hda_codec *codec);
339 void (*unsol_event)(struct hda_codec *codec, unsigned int res); 339 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
340#ifdef CONFIG_SND_HDA_POWER_SAVE 340#ifdef CONFIG_SND_HDA_POWER_SAVE
341 void (*power_hook)(struct hda_codec *codec, int power); 341 void (*power_hook)(struct hda_codec *codec);
342#endif 342#endif
343 343
344 /* for pin sensing */ 344 /* for pin sensing */
@@ -391,7 +391,7 @@ struct alc_config_preset {
391 void (*init_hook)(struct hda_codec *); 391 void (*init_hook)(struct hda_codec *);
392#ifdef CONFIG_SND_HDA_POWER_SAVE 392#ifdef CONFIG_SND_HDA_POWER_SAVE
393 struct hda_amp_list *loopbacks; 393 struct hda_amp_list *loopbacks;
394 void (*power_hook)(struct hda_codec *codec, int power); 394 void (*power_hook)(struct hda_codec *codec);
395#endif 395#endif
396}; 396};
397 397
@@ -1835,16 +1835,6 @@ static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
1835 spec->autocfg.speaker_pins[2] = 0x1b; 1835 spec->autocfg.speaker_pins[2] = 0x1b;
1836} 1836}
1837 1837
1838#ifdef CONFIG_SND_HDA_POWER_SAVE
1839static void alc889_power_eapd(struct hda_codec *codec, int power)
1840{
1841 snd_hda_codec_write(codec, 0x14, 0,
1842 AC_VERB_SET_EAPD_BTLENABLE, power ? 2 : 0);
1843 snd_hda_codec_write(codec, 0x15, 0,
1844 AC_VERB_SET_EAPD_BTLENABLE, power ? 2 : 0);
1845}
1846#endif
1847
1848/* 1838/*
1849 * ALC880 3-stack model 1839 * ALC880 3-stack model
1850 * 1840 *
@@ -2548,8 +2538,10 @@ static int alc_build_controls(struct hda_codec *codec)
2548 if (!kctl) 2538 if (!kctl)
2549 kctl = snd_hda_find_mixer_ctl(codec, "Input Source"); 2539 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
2550 for (i = 0; kctl && i < kctl->count; i++) { 2540 for (i = 0; kctl && i < kctl->count; i++) {
2551 err = snd_hda_add_nids(codec, kctl, i, spec->capsrc_nids, 2541 hda_nid_t *nids = spec->capsrc_nids;
2552 spec->input_mux->num_items); 2542 if (!nids)
2543 nids = spec->adc_nids;
2544 err = snd_hda_add_nid(codec, kctl, i, nids[i]);
2553 if (err < 0) 2545 if (err < 0)
2554 return err; 2546 return err;
2555 } 2547 }
@@ -3691,6 +3683,11 @@ static int alc_build_pcms(struct hda_codec *codec)
3691 return 0; 3683 return 0;
3692} 3684}
3693 3685
3686static inline void alc_shutup(struct hda_codec *codec)
3687{
3688 snd_hda_shutup_pins(codec);
3689}
3690
3694static void alc_free_kctls(struct hda_codec *codec) 3691static void alc_free_kctls(struct hda_codec *codec)
3695{ 3692{
3696 struct alc_spec *spec = codec->spec; 3693 struct alc_spec *spec = codec->spec;
@@ -3711,17 +3708,47 @@ static void alc_free(struct hda_codec *codec)
3711 if (!spec) 3708 if (!spec)
3712 return; 3709 return;
3713 3710
3711 alc_shutup(codec);
3714 alc_free_kctls(codec); 3712 alc_free_kctls(codec);
3715 kfree(spec); 3713 kfree(spec);
3716 snd_hda_detach_beep_device(codec); 3714 snd_hda_detach_beep_device(codec);
3717} 3715}
3718 3716
3719#ifdef CONFIG_SND_HDA_POWER_SAVE 3717#ifdef CONFIG_SND_HDA_POWER_SAVE
3718static void alc_power_eapd(struct hda_codec *codec)
3719{
3720 /* We currently only handle front, HP */
3721 switch (codec->vendor_id) {
3722 case 0x10ec0260:
3723 snd_hda_codec_write(codec, 0x0f, 0,
3724 AC_VERB_SET_EAPD_BTLENABLE, 0x00);
3725 snd_hda_codec_write(codec, 0x10, 0,
3726 AC_VERB_SET_EAPD_BTLENABLE, 0x00);
3727 break;
3728 case 0x10ec0262:
3729 case 0x10ec0267:
3730 case 0x10ec0268:
3731 case 0x10ec0269:
3732 case 0x10ec0272:
3733 case 0x10ec0660:
3734 case 0x10ec0662:
3735 case 0x10ec0663:
3736 case 0x10ec0862:
3737 case 0x10ec0889:
3738 snd_hda_codec_write(codec, 0x14, 0,
3739 AC_VERB_SET_EAPD_BTLENABLE, 0x00);
3740 snd_hda_codec_write(codec, 0x15, 0,
3741 AC_VERB_SET_EAPD_BTLENABLE, 0x00);
3742 break;
3743 }
3744}
3745
3720static int alc_suspend(struct hda_codec *codec, pm_message_t state) 3746static int alc_suspend(struct hda_codec *codec, pm_message_t state)
3721{ 3747{
3722 struct alc_spec *spec = codec->spec; 3748 struct alc_spec *spec = codec->spec;
3749 alc_shutup(codec);
3723 if (spec && spec->power_hook) 3750 if (spec && spec->power_hook)
3724 spec->power_hook(codec, 0); 3751 spec->power_hook(codec);
3725 return 0; 3752 return 0;
3726} 3753}
3727#endif 3754#endif
@@ -3729,16 +3756,9 @@ static int alc_suspend(struct hda_codec *codec, pm_message_t state)
3729#ifdef SND_HDA_NEEDS_RESUME 3756#ifdef SND_HDA_NEEDS_RESUME
3730static int alc_resume(struct hda_codec *codec) 3757static int alc_resume(struct hda_codec *codec)
3731{ 3758{
3732#ifdef CONFIG_SND_HDA_POWER_SAVE
3733 struct alc_spec *spec = codec->spec;
3734#endif
3735 codec->patch_ops.init(codec); 3759 codec->patch_ops.init(codec);
3736 snd_hda_codec_resume_amp(codec); 3760 snd_hda_codec_resume_amp(codec);
3737 snd_hda_codec_resume_cache(codec); 3761 snd_hda_codec_resume_cache(codec);
3738#ifdef CONFIG_SND_HDA_POWER_SAVE
3739 if (spec && spec->power_hook)
3740 spec->power_hook(codec, 1);
3741#endif
3742 return 0; 3762 return 0;
3743} 3763}
3744#endif 3764#endif
@@ -3758,6 +3778,7 @@ static struct hda_codec_ops alc_patch_ops = {
3758 .suspend = alc_suspend, 3778 .suspend = alc_suspend,
3759 .check_power_status = alc_check_power_status, 3779 .check_power_status = alc_check_power_status,
3760#endif 3780#endif
3781 .reboot_notify = alc_shutup,
3761}; 3782};
3762 3783
3763 3784
@@ -9538,7 +9559,7 @@ static struct alc_config_preset alc882_presets[] = {
9538 .setup = alc889_acer_aspire_8930g_setup, 9559 .setup = alc889_acer_aspire_8930g_setup,
9539 .init_hook = alc_automute_amp, 9560 .init_hook = alc_automute_amp,
9540#ifdef CONFIG_SND_HDA_POWER_SAVE 9561#ifdef CONFIG_SND_HDA_POWER_SAVE
9541 .power_hook = alc889_power_eapd, 9562 .power_hook = alc_power_eapd,
9542#endif 9563#endif
9543 }, 9564 },
9544 [ALC888_ACER_ASPIRE_7730G] = { 9565 [ALC888_ACER_ASPIRE_7730G] = {
@@ -14975,9 +14996,13 @@ static int patch_alc861(struct hda_codec *codec)
14975 spec->vmaster_nid = 0x03; 14996 spec->vmaster_nid = 0x03;
14976 14997
14977 codec->patch_ops = alc_patch_ops; 14998 codec->patch_ops = alc_patch_ops;
14978 if (board_config == ALC861_AUTO) 14999 if (board_config == ALC861_AUTO) {
14979 spec->init_hook = alc861_auto_init; 15000 spec->init_hook = alc861_auto_init;
14980#ifdef CONFIG_SND_HDA_POWER_SAVE 15001#ifdef CONFIG_SND_HDA_POWER_SAVE
15002 spec->power_hook = alc_power_eapd;
15003#endif
15004 }
15005#ifdef CONFIG_SND_HDA_POWER_SAVE
14981 if (!spec->loopback.amplist) 15006 if (!spec->loopback.amplist)
14982 spec->loopback.amplist = alc861_loopbacks; 15007 spec->loopback.amplist = alc861_loopbacks;
14983#endif 15008#endif
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 74d5d333ed6c..e28c810bc00c 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -4159,34 +4159,52 @@ static void stac92xx_power_down(struct hda_codec *codec)
4159static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid, 4159static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid,
4160 int enable); 4160 int enable);
4161 4161
4162static inline int get_int_hint(struct hda_codec *codec, const char *key,
4163 int *valp)
4164{
4165 const char *p;
4166 p = snd_hda_get_hint(codec, key);
4167 if (p) {
4168 unsigned long val;
4169 if (!strict_strtoul(p, 0, &val)) {
4170 *valp = val;
4171 return 1;
4172 }
4173 }
4174 return 0;
4175}
4176
4162/* override some hints from the hwdep entry */ 4177/* override some hints from the hwdep entry */
4163static void stac_store_hints(struct hda_codec *codec) 4178static void stac_store_hints(struct hda_codec *codec)
4164{ 4179{
4165 struct sigmatel_spec *spec = codec->spec; 4180 struct sigmatel_spec *spec = codec->spec;
4166 const char *p;
4167 int val; 4181 int val;
4168 4182
4169 val = snd_hda_get_bool_hint(codec, "hp_detect"); 4183 val = snd_hda_get_bool_hint(codec, "hp_detect");
4170 if (val >= 0) 4184 if (val >= 0)
4171 spec->hp_detect = val; 4185 spec->hp_detect = val;
4172 p = snd_hda_get_hint(codec, "gpio_mask"); 4186 if (get_int_hint(codec, "gpio_mask", &spec->gpio_mask)) {
4173 if (p) {
4174 spec->gpio_mask = simple_strtoul(p, NULL, 0);
4175 spec->eapd_mask = spec->gpio_dir = spec->gpio_data = 4187 spec->eapd_mask = spec->gpio_dir = spec->gpio_data =
4176 spec->gpio_mask; 4188 spec->gpio_mask;
4177 } 4189 }
4178 p = snd_hda_get_hint(codec, "gpio_dir"); 4190 if (get_int_hint(codec, "gpio_dir", &spec->gpio_dir))
4179 if (p) 4191 spec->gpio_mask &= spec->gpio_mask;
4180 spec->gpio_dir = simple_strtoul(p, NULL, 0) & spec->gpio_mask; 4192 if (get_int_hint(codec, "gpio_data", &spec->gpio_data))
4181 p = snd_hda_get_hint(codec, "gpio_data"); 4193 spec->gpio_dir &= spec->gpio_mask;
4182 if (p) 4194 if (get_int_hint(codec, "eapd_mask", &spec->eapd_mask))
4183 spec->gpio_data = simple_strtoul(p, NULL, 0) & spec->gpio_mask; 4195 spec->eapd_mask &= spec->gpio_mask;
4184 p = snd_hda_get_hint(codec, "eapd_mask"); 4196 if (get_int_hint(codec, "gpio_mute", &spec->gpio_mute))
4185 if (p) 4197 spec->gpio_mute &= spec->gpio_mask;
4186 spec->eapd_mask = simple_strtoul(p, NULL, 0) & spec->gpio_mask;
4187 val = snd_hda_get_bool_hint(codec, "eapd_switch"); 4198 val = snd_hda_get_bool_hint(codec, "eapd_switch");
4188 if (val >= 0) 4199 if (val >= 0)
4189 spec->eapd_switch = val; 4200 spec->eapd_switch = val;
4201 get_int_hint(codec, "gpio_led_polarity", &spec->gpio_led_polarity);
4202 if (get_int_hint(codec, "gpio_led", &spec->gpio_led)) {
4203 spec->gpio_mask |= spec->gpio_led;
4204 spec->gpio_dir |= spec->gpio_led;
4205 if (spec->gpio_led_polarity)
4206 spec->gpio_data |= spec->gpio_led;
4207 }
4190} 4208}
4191 4209
4192static int stac92xx_init(struct hda_codec *codec) 4210static int stac92xx_init(struct hda_codec *codec)
@@ -4371,18 +4389,8 @@ static void stac92xx_free_kctls(struct hda_codec *codec)
4371static void stac92xx_shutup(struct hda_codec *codec) 4389static void stac92xx_shutup(struct hda_codec *codec)
4372{ 4390{
4373 struct sigmatel_spec *spec = codec->spec; 4391 struct sigmatel_spec *spec = codec->spec;
4374 int i;
4375 hda_nid_t nid;
4376 4392
4377 /* reset each pin before powering down DAC/ADC to avoid click noise */ 4393 snd_hda_shutup_pins(codec);
4378 nid = codec->start_nid;
4379 for (i = 0; i < codec->num_nodes; i++, nid++) {
4380 unsigned int wcaps = get_wcaps(codec, nid);
4381 unsigned int wid_type = get_wcaps_type(wcaps);
4382 if (wid_type == AC_WID_PIN)
4383 snd_hda_codec_read(codec, nid, 0,
4384 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
4385 }
4386 4394
4387 if (spec->eapd_mask) 4395 if (spec->eapd_mask)
4388 stac_gpio_set(codec, spec->gpio_mask, 4396 stac_gpio_set(codec, spec->gpio_mask,
@@ -5406,6 +5414,54 @@ static int stac92hd71bxx_connected_smuxes(struct hda_codec *codec,
5406 return 0; 5414 return 0;
5407} 5415}
5408 5416
5417/* HP dv7 bass switch - GPIO5 */
5418#define stac_hp_bass_gpio_info snd_ctl_boolean_mono_info
5419static int stac_hp_bass_gpio_get(struct snd_kcontrol *kcontrol,
5420 struct snd_ctl_elem_value *ucontrol)
5421{
5422 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5423 struct sigmatel_spec *spec = codec->spec;
5424 ucontrol->value.integer.value[0] = !!(spec->gpio_data & 0x20);
5425 return 0;
5426}
5427
5428static int stac_hp_bass_gpio_put(struct snd_kcontrol *kcontrol,
5429 struct snd_ctl_elem_value *ucontrol)
5430{
5431 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5432 struct sigmatel_spec *spec = codec->spec;
5433 unsigned int gpio_data;
5434
5435 gpio_data = (spec->gpio_data & ~0x20) |
5436 (ucontrol->value.integer.value[0] ? 0x20 : 0);
5437 if (gpio_data == spec->gpio_data)
5438 return 0;
5439 spec->gpio_data = gpio_data;
5440 stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, spec->gpio_data);
5441 return 1;
5442}
5443
5444static struct snd_kcontrol_new stac_hp_bass_sw_ctrl = {
5445 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5446 .info = stac_hp_bass_gpio_info,
5447 .get = stac_hp_bass_gpio_get,
5448 .put = stac_hp_bass_gpio_put,
5449};
5450
5451static int stac_add_hp_bass_switch(struct hda_codec *codec)
5452{
5453 struct sigmatel_spec *spec = codec->spec;
5454
5455 if (!stac_control_new(spec, &stac_hp_bass_sw_ctrl,
5456 "Bass Speaker Playback Switch", 0))
5457 return -ENOMEM;
5458
5459 spec->gpio_mask |= 0x20;
5460 spec->gpio_dir |= 0x20;
5461 spec->gpio_data |= 0x20;
5462 return 0;
5463}
5464
5409static int patch_stac92hd71bxx(struct hda_codec *codec) 5465static int patch_stac92hd71bxx(struct hda_codec *codec)
5410{ 5466{
5411 struct sigmatel_spec *spec; 5467 struct sigmatel_spec *spec;
@@ -5646,6 +5702,15 @@ again:
5646 return err; 5702 return err;
5647 } 5703 }
5648 5704
5705 /* enable bass on HP dv7 */
5706 if (spec->board_config == STAC_HP_DV5) {
5707 unsigned int cap;
5708 cap = snd_hda_param_read(codec, 0x1, AC_PAR_GPIO_CAP);
5709 cap &= AC_GPIO_IO_COUNT;
5710 if (cap >= 6)
5711 stac_add_hp_bass_switch(codec);
5712 }
5713
5649 codec->proc_widget_hook = stac92hd7x_proc_hook; 5714 codec->proc_widget_hook = stac92hd7x_proc_hook;
5650 5715
5651 return 0; 5716 return 0;
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index de4839e46762..9ddc37300f6b 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -1907,8 +1907,7 @@ static int via_build_controls(struct hda_codec *codec)
1907 /* assign Capture Source enums to NID */ 1907 /* assign Capture Source enums to NID */
1908 kctl = snd_hda_find_mixer_ctl(codec, "Input Source"); 1908 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
1909 for (i = 0; kctl && i < kctl->count; i++) { 1909 for (i = 0; kctl && i < kctl->count; i++) {
1910 err = snd_hda_add_nids(codec, kctl, i, spec->mux_nids, 1910 err = snd_hda_add_nid(codec, kctl, i, spec->mux_nids[i]);
1911 spec->input_mux->num_items);
1912 if (err < 0) 1911 if (err < 0)
1913 return err; 1912 return err;
1914 } 1913 }