diff options
author | Takashi Iwai <tiwai@suse.de> | 2009-03-20 07:52:47 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2009-03-20 07:52:47 -0400 |
commit | 2d864c499a77129dc6aa4f7552ddf2885e4a9c47 (patch) | |
tree | 46c73aad233f3105972a0138b96a4674c88aaf7f /sound/pci | |
parent | 07a1e81355245ca65ab16c7b4ae2332e52ed7acd (diff) |
ALSA: hda - Detect digital-mic inputs on ALC663 / ALC272
Fix the detection of digital-mic inputs on ALC663 / ALC272 codecs
in the auto-detection mode. The automatic mic switch via plugging
isn't implemented yet, though.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci')
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 63 |
1 files changed, 47 insertions, 16 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 5ad0f8d72ddb..b69d9864f6f3 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -16725,26 +16725,58 @@ static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin, | |||
16725 | return 0; | 16725 | return 0; |
16726 | } | 16726 | } |
16727 | 16727 | ||
16728 | /* return the index of the src widget from the connection list of the nid. | ||
16729 | * return -1 if not found | ||
16730 | */ | ||
16731 | static int alc662_input_pin_idx(struct hda_codec *codec, hda_nid_t nid, | ||
16732 | hda_nid_t src) | ||
16733 | { | ||
16734 | hda_nid_t conn_list[HDA_MAX_CONNECTIONS]; | ||
16735 | int i, conns; | ||
16736 | |||
16737 | conns = snd_hda_get_connections(codec, nid, conn_list, | ||
16738 | ARRAY_SIZE(conn_list)); | ||
16739 | if (conns < 0) | ||
16740 | return -1; | ||
16741 | for (i = 0; i < conns; i++) | ||
16742 | if (conn_list[i] == src) | ||
16743 | return i; | ||
16744 | return -1; | ||
16745 | } | ||
16746 | |||
16747 | static int alc662_is_input_pin(struct hda_codec *codec, hda_nid_t nid) | ||
16748 | { | ||
16749 | unsigned int pincap = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP); | ||
16750 | return (pincap & AC_PINCAP_IN) != 0; | ||
16751 | } | ||
16752 | |||
16728 | /* create playback/capture controls for input pins */ | 16753 | /* create playback/capture controls for input pins */ |
16729 | static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec, | 16754 | static int alc662_auto_create_analog_input_ctls(struct hda_codec *codec, |
16730 | const struct auto_pin_cfg *cfg) | 16755 | const struct auto_pin_cfg *cfg) |
16731 | { | 16756 | { |
16757 | struct alc_spec *spec = codec->spec; | ||
16732 | struct hda_input_mux *imux = &spec->private_imux[0]; | 16758 | struct hda_input_mux *imux = &spec->private_imux[0]; |
16733 | int i, err, idx; | 16759 | int i, err, idx; |
16734 | 16760 | ||
16735 | for (i = 0; i < AUTO_PIN_LAST; i++) { | 16761 | for (i = 0; i < AUTO_PIN_LAST; i++) { |
16736 | if (alc880_is_input_pin(cfg->input_pins[i])) { | 16762 | if (alc662_is_input_pin(codec, cfg->input_pins[i])) { |
16737 | idx = alc880_input_pin_idx(cfg->input_pins[i]); | 16763 | idx = alc662_input_pin_idx(codec, 0x0b, |
16738 | err = new_analog_input(spec, cfg->input_pins[i], | 16764 | cfg->input_pins[i]); |
16739 | auto_pin_cfg_labels[i], | 16765 | if (idx >= 0) { |
16740 | idx, 0x0b); | 16766 | err = new_analog_input(spec, cfg->input_pins[i], |
16741 | if (err < 0) | 16767 | auto_pin_cfg_labels[i], |
16742 | return err; | 16768 | idx, 0x0b); |
16743 | imux->items[imux->num_items].label = | 16769 | if (err < 0) |
16744 | auto_pin_cfg_labels[i]; | 16770 | return err; |
16745 | imux->items[imux->num_items].index = | 16771 | } |
16746 | alc880_input_pin_idx(cfg->input_pins[i]); | 16772 | idx = alc662_input_pin_idx(codec, 0x22, |
16747 | imux->num_items++; | 16773 | cfg->input_pins[i]); |
16774 | if (idx >= 0) { | ||
16775 | imux->items[imux->num_items].label = | ||
16776 | auto_pin_cfg_labels[i]; | ||
16777 | imux->items[imux->num_items].index = idx; | ||
16778 | imux->num_items++; | ||
16779 | } | ||
16748 | } | 16780 | } |
16749 | } | 16781 | } |
16750 | return 0; | 16782 | return 0; |
@@ -16794,7 +16826,6 @@ static void alc662_auto_init_hp_out(struct hda_codec *codec) | |||
16794 | alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); | 16826 | alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); |
16795 | } | 16827 | } |
16796 | 16828 | ||
16797 | #define alc662_is_input_pin(nid) alc880_is_input_pin(nid) | ||
16798 | #define ALC662_PIN_CD_NID ALC880_PIN_CD_NID | 16829 | #define ALC662_PIN_CD_NID ALC880_PIN_CD_NID |
16799 | 16830 | ||
16800 | static void alc662_auto_init_analog_input(struct hda_codec *codec) | 16831 | static void alc662_auto_init_analog_input(struct hda_codec *codec) |
@@ -16804,7 +16835,7 @@ static void alc662_auto_init_analog_input(struct hda_codec *codec) | |||
16804 | 16835 | ||
16805 | for (i = 0; i < AUTO_PIN_LAST; i++) { | 16836 | for (i = 0; i < AUTO_PIN_LAST; i++) { |
16806 | hda_nid_t nid = spec->autocfg.input_pins[i]; | 16837 | hda_nid_t nid = spec->autocfg.input_pins[i]; |
16807 | if (alc662_is_input_pin(nid)) { | 16838 | if (alc662_is_input_pin(codec, nid)) { |
16808 | alc_set_input_pin(codec, nid, i); | 16839 | alc_set_input_pin(codec, nid, i); |
16809 | if (nid != ALC662_PIN_CD_NID) | 16840 | if (nid != ALC662_PIN_CD_NID) |
16810 | snd_hda_codec_write(codec, nid, 0, | 16841 | snd_hda_codec_write(codec, nid, 0, |
@@ -16844,7 +16875,7 @@ static int alc662_parse_auto_config(struct hda_codec *codec) | |||
16844 | "Headphone"); | 16875 | "Headphone"); |
16845 | if (err < 0) | 16876 | if (err < 0) |
16846 | return err; | 16877 | return err; |
16847 | err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg); | 16878 | err = alc662_auto_create_analog_input_ctls(codec, &spec->autocfg); |
16848 | if (err < 0) | 16879 | if (err < 0) |
16849 | return err; | 16880 | return err; |
16850 | 16881 | ||