aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/patch_sigmatel.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/hda/patch_sigmatel.c')
-rw-r--r--sound/pci/hda/patch_sigmatel.c379
1 files changed, 192 insertions, 187 deletions
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index c16c5ba0fda0..82ebeb9544fe 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -32,6 +32,7 @@
32#include <sound/core.h> 32#include <sound/core.h>
33#include <sound/asoundef.h> 33#include <sound/asoundef.h>
34#include <sound/jack.h> 34#include <sound/jack.h>
35#include <sound/tlv.h>
35#include "hda_codec.h" 36#include "hda_codec.h"
36#include "hda_local.h" 37#include "hda_local.h"
37#include "hda_beep.h" 38#include "hda_beep.h"
@@ -263,6 +264,7 @@ struct sigmatel_spec {
263 264
264 struct sigmatel_mic_route ext_mic; 265 struct sigmatel_mic_route ext_mic;
265 struct sigmatel_mic_route int_mic; 266 struct sigmatel_mic_route int_mic;
267 struct sigmatel_mic_route dock_mic;
266 268
267 const char **spdif_labels; 269 const char **spdif_labels;
268 270
@@ -382,6 +384,11 @@ static unsigned int stac92hd83xxx_pwr_mapping[4] = {
382 0x03, 0x0c, 0x20, 0x40, 384 0x03, 0x0c, 0x20, 0x40,
383}; 385};
384 386
387#define STAC92HD83XXX_NUM_DMICS 2
388static hda_nid_t stac92hd83xxx_dmic_nids[STAC92HD83XXX_NUM_DMICS + 1] = {
389 0x11, 0x20, 0
390};
391
385#define STAC92HD83XXX_NUM_CAPS 2 392#define STAC92HD83XXX_NUM_CAPS 2
386static unsigned long stac92hd83xxx_capvols[] = { 393static unsigned long stac92hd83xxx_capvols[] = {
387 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT), 394 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
@@ -986,7 +993,7 @@ static struct hda_verb stac9205_core_init[] = {
986 } 993 }
987 994
988static struct snd_kcontrol_new stac9200_mixer[] = { 995static struct snd_kcontrol_new stac9200_mixer[] = {
989 HDA_CODEC_VOLUME("Master Playback Volume", 0xb, 0, HDA_OUTPUT), 996 HDA_CODEC_VOLUME_MIN_MUTE("Master Playback Volume", 0xb, 0, HDA_OUTPUT),
990 HDA_CODEC_MUTE("Master Playback Switch", 0xb, 0, HDA_OUTPUT), 997 HDA_CODEC_MUTE("Master Playback Switch", 0xb, 0, HDA_OUTPUT),
991 HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT), 998 HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT),
992 HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT), 999 HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT),
@@ -1014,7 +1021,7 @@ static struct snd_kcontrol_new stac92hd71bxx_loopback[] = {
1014}; 1021};
1015 1022
1016static struct snd_kcontrol_new stac925x_mixer[] = { 1023static struct snd_kcontrol_new stac925x_mixer[] = {
1017 HDA_CODEC_VOLUME("Master Playback Volume", 0x0e, 0, HDA_OUTPUT), 1024 HDA_CODEC_VOLUME_MIN_MUTE("Master Playback Volume", 0xe, 0, HDA_OUTPUT),
1018 HDA_CODEC_MUTE("Master Playback Switch", 0x0e, 0, HDA_OUTPUT), 1025 HDA_CODEC_MUTE("Master Playback Switch", 0x0e, 0, HDA_OUTPUT),
1019 { } /* end */ 1026 { } /* end */
1020}; 1027};
@@ -1105,9 +1112,7 @@ static int stac92xx_build_controls(struct hda_codec *codec)
1105 struct hda_input_mux *smux = &spec->private_smux; 1112 struct hda_input_mux *smux = &spec->private_smux;
1106 /* check for mute support on SPDIF out */ 1113 /* check for mute support on SPDIF out */
1107 if (wcaps & AC_WCAP_OUT_AMP) { 1114 if (wcaps & AC_WCAP_OUT_AMP) {
1108 smux->items[smux->num_items].label = "Off"; 1115 snd_hda_add_imux_item(smux, "Off", 0, NULL);
1109 smux->items[smux->num_items].index = 0;
1110 smux->num_items++;
1111 spec->spdif_mute = 1; 1116 spec->spdif_mute = 1;
1112 } 1117 }
1113 stac_smux_mixer.count = spec->num_smuxes; 1118 stac_smux_mixer.count = spec->num_smuxes;
@@ -1140,6 +1145,8 @@ static int stac92xx_build_controls(struct hda_codec *codec)
1140 HDA_OUTPUT, vmaster_tlv); 1145 HDA_OUTPUT, vmaster_tlv);
1141 /* correct volume offset */ 1146 /* correct volume offset */
1142 vmaster_tlv[2] += vmaster_tlv[3] * spec->volume_offset; 1147 vmaster_tlv[2] += vmaster_tlv[3] * spec->volume_offset;
1148 /* minimum value is actually mute */
1149 vmaster_tlv[3] |= TLV_DB_SCALE_MUTE;
1143 err = snd_hda_add_vmaster(codec, "Master Playback Volume", 1150 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1144 vmaster_tlv, slave_vols); 1151 vmaster_tlv, slave_vols);
1145 if (err < 0) 1152 if (err < 0)
@@ -1180,14 +1187,11 @@ static int stac92xx_build_controls(struct hda_codec *codec)
1180 if (err < 0) 1187 if (err < 0)
1181 return err; 1188 return err;
1182 } 1189 }
1183 for (i = 0; i < AUTO_PIN_LAST; i++) { 1190 for (i = 0; i < cfg->num_inputs; i++) {
1184 nid = cfg->input_pins[i]; 1191 nid = cfg->inputs[i].pin;
1185 if (nid) { 1192 err = stac92xx_add_jack(codec, nid, SND_JACK_MICROPHONE);
1186 err = stac92xx_add_jack(codec, nid, 1193 if (err < 0)
1187 SND_JACK_MICROPHONE); 1194 return err;
1188 if (err < 0)
1189 return err;
1190 }
1191 } 1195 }
1192 1196
1193 return 0; 1197 return 0;
@@ -2779,7 +2783,7 @@ static inline int stac92xx_add_jack_mode_control(struct hda_codec *codec,
2779 struct sigmatel_spec *spec = codec->spec; 2783 struct sigmatel_spec *spec = codec->spec;
2780 char name[22]; 2784 char name[22];
2781 2785
2782 if (!((get_defcfg_connect(def_conf)) & AC_JACK_PORT_FIXED)) { 2786 if (snd_hda_get_input_pin_attr(def_conf) != INPUT_PIN_ATTR_INT) {
2783 if (stac92xx_get_default_vref(codec, nid) == AC_PINCTL_VREF_GRD 2787 if (stac92xx_get_default_vref(codec, nid) == AC_PINCTL_VREF_GRD
2784 && nid == spec->line_switch) 2788 && nid == spec->line_switch)
2785 control = STAC_CTL_WIDGET_IO_SWITCH; 2789 control = STAC_CTL_WIDGET_IO_SWITCH;
@@ -2791,7 +2795,7 @@ static inline int stac92xx_add_jack_mode_control(struct hda_codec *codec,
2791 } 2795 }
2792 2796
2793 if (control) { 2797 if (control) {
2794 strcpy(name, auto_pin_cfg_labels[idx]); 2798 strcpy(name, hda_get_input_pin_label(codec, nid, 1));
2795 return stac92xx_add_control(codec->spec, control, 2799 return stac92xx_add_control(codec->spec, control,
2796 strcat(name, " Jack Mode"), nid); 2800 strcat(name, " Jack Mode"), nid);
2797 } 2801 }
@@ -2823,41 +2827,49 @@ static hda_nid_t check_line_out_switch(struct hda_codec *codec)
2823 struct auto_pin_cfg *cfg = &spec->autocfg; 2827 struct auto_pin_cfg *cfg = &spec->autocfg;
2824 hda_nid_t nid; 2828 hda_nid_t nid;
2825 unsigned int pincap; 2829 unsigned int pincap;
2830 int i;
2826 2831
2827 if (cfg->line_out_type != AUTO_PIN_LINE_OUT) 2832 if (cfg->line_out_type != AUTO_PIN_LINE_OUT)
2828 return 0; 2833 return 0;
2829 nid = cfg->input_pins[AUTO_PIN_LINE]; 2834 for (i = 0; i < cfg->num_inputs; i++) {
2830 pincap = snd_hda_query_pin_caps(codec, nid); 2835 if (cfg->inputs[i].type == AUTO_PIN_LINE_IN) {
2831 if (pincap & AC_PINCAP_OUT) 2836 nid = cfg->inputs[i].pin;
2832 return nid; 2837 pincap = snd_hda_query_pin_caps(codec, nid);
2838 if (pincap & AC_PINCAP_OUT)
2839 return nid;
2840 }
2841 }
2833 return 0; 2842 return 0;
2834} 2843}
2835 2844
2845static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t nid);
2846
2836/* check whether the mic-input can be used as line-out */ 2847/* check whether the mic-input can be used as line-out */
2837static hda_nid_t check_mic_out_switch(struct hda_codec *codec) 2848static hda_nid_t check_mic_out_switch(struct hda_codec *codec, hda_nid_t *dac)
2838{ 2849{
2839 struct sigmatel_spec *spec = codec->spec; 2850 struct sigmatel_spec *spec = codec->spec;
2840 struct auto_pin_cfg *cfg = &spec->autocfg; 2851 struct auto_pin_cfg *cfg = &spec->autocfg;
2841 unsigned int def_conf, pincap; 2852 unsigned int def_conf, pincap;
2842 unsigned int mic_pin; 2853 int i;
2843 2854
2855 *dac = 0;
2844 if (cfg->line_out_type != AUTO_PIN_LINE_OUT) 2856 if (cfg->line_out_type != AUTO_PIN_LINE_OUT)
2845 return 0; 2857 return 0;
2846 mic_pin = AUTO_PIN_MIC; 2858 for (i = 0; i < cfg->num_inputs; i++) {
2847 for (;;) { 2859 hda_nid_t nid = cfg->inputs[i].pin;
2848 hda_nid_t nid = cfg->input_pins[mic_pin]; 2860 if (cfg->inputs[i].type != AUTO_PIN_MIC)
2861 continue;
2849 def_conf = snd_hda_codec_get_pincfg(codec, nid); 2862 def_conf = snd_hda_codec_get_pincfg(codec, nid);
2850 /* some laptops have an internal analog microphone 2863 /* some laptops have an internal analog microphone
2851 * which can't be used as a output */ 2864 * which can't be used as a output */
2852 if (get_defcfg_connect(def_conf) != AC_JACK_PORT_FIXED) { 2865 if (snd_hda_get_input_pin_attr(def_conf) != INPUT_PIN_ATTR_INT) {
2853 pincap = snd_hda_query_pin_caps(codec, nid); 2866 pincap = snd_hda_query_pin_caps(codec, nid);
2854 if (pincap & AC_PINCAP_OUT) 2867 if (pincap & AC_PINCAP_OUT) {
2855 return nid; 2868 *dac = get_unassigned_dac(codec, nid);
2869 if (*dac)
2870 return nid;
2871 }
2856 } 2872 }
2857 if (mic_pin == AUTO_PIN_MIC)
2858 mic_pin = AUTO_PIN_FRONT_MIC;
2859 else
2860 break;
2861 } 2873 }
2862 return 0; 2874 return 0;
2863} 2875}
@@ -3004,17 +3016,14 @@ static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec)
3004 } 3016 }
3005 } 3017 }
3006 /* add mic as output */ 3018 /* add mic as output */
3007 nid = check_mic_out_switch(codec); 3019 nid = check_mic_out_switch(codec, &dac);
3008 if (nid) { 3020 if (nid && dac) {
3009 dac = get_unassigned_dac(codec, nid); 3021 snd_printdd("STAC: Add mic-in 0x%x as output %d\n",
3010 if (dac) { 3022 nid, cfg->line_outs);
3011 snd_printdd("STAC: Add mic-in 0x%x as output %d\n", 3023 cfg->line_out_pins[cfg->line_outs] = nid;
3012 nid, cfg->line_outs); 3024 cfg->line_outs++;
3013 cfg->line_out_pins[cfg->line_outs] = nid; 3025 spec->mic_switch = nid;
3014 cfg->line_outs++; 3026 add_spec_dacs(spec, dac);
3015 spec->mic_switch = nid;
3016 add_spec_dacs(spec, dac);
3017 }
3018 } 3027 }
3019 3028
3020 snd_printd("stac92xx: dac_nids=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n", 3029 snd_printd("stac92xx: dac_nids=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n",
@@ -3204,13 +3213,13 @@ static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec,
3204 return err; 3213 return err;
3205 } 3214 }
3206 3215
3207 for (idx = AUTO_PIN_MIC; idx <= AUTO_PIN_FRONT_LINE; idx++) { 3216 for (idx = 0; idx < cfg->num_inputs; idx++) {
3208 nid = cfg->input_pins[idx]; 3217 if (cfg->inputs[idx].type > AUTO_PIN_LINE_IN)
3209 if (nid) { 3218 break;
3210 err = stac92xx_add_jack_mode_control(codec, nid, idx); 3219 nid = cfg->inputs[idx].pin;
3211 if (err < 0) 3220 err = stac92xx_add_jack_mode_control(codec, nid, idx);
3212 return err; 3221 if (err < 0)
3213 } 3222 return err;
3214 } 3223 }
3215 3224
3216 return 0; 3225 return 0;
@@ -3256,12 +3265,9 @@ static int stac92xx_auto_create_mono_output_ctls(struct hda_codec *codec)
3256 if (num_cons <= 0 || num_cons > ARRAY_SIZE(stac92xx_mono_labels)) 3265 if (num_cons <= 0 || num_cons > ARRAY_SIZE(stac92xx_mono_labels))
3257 return -EINVAL; 3266 return -EINVAL;
3258 3267
3259 for (i = 0; i < num_cons; i++) { 3268 for (i = 0; i < num_cons; i++)
3260 mono_mux->items[mono_mux->num_items].label = 3269 snd_hda_add_imux_item(mono_mux, stac92xx_mono_labels[i], i,
3261 stac92xx_mono_labels[i]; 3270 NULL);
3262 mono_mux->items[mono_mux->num_items].index = i;
3263 mono_mux->num_items++;
3264 }
3265 3271
3266 return stac92xx_add_control(spec, STAC_CTL_WIDGET_MONO_MUX, 3272 return stac92xx_add_control(spec, STAC_CTL_WIDGET_MONO_MUX,
3267 "Mono Mux", spec->mono_nid); 3273 "Mono Mux", spec->mono_nid);
@@ -3386,11 +3392,8 @@ static int stac92xx_auto_create_spdif_mux_ctls(struct hda_codec *codec)
3386 if (!labels) 3392 if (!labels)
3387 labels = stac92xx_spdif_labels; 3393 labels = stac92xx_spdif_labels;
3388 3394
3389 for (i = 0; i < num_cons; i++) { 3395 for (i = 0; i < num_cons; i++)
3390 spdif_mux->items[spdif_mux->num_items].label = labels[i]; 3396 snd_hda_add_imux_item(spdif_mux, labels[i], i, NULL);
3391 spdif_mux->items[spdif_mux->num_items].index = i;
3392 spdif_mux->num_items++;
3393 }
3394 3397
3395 return 0; 3398 return 0;
3396} 3399}
@@ -3417,7 +3420,7 @@ static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
3417/* create a volume assigned to the given pin (only if supported) */ 3420/* create a volume assigned to the given pin (only if supported) */
3418/* return 1 if the volume control is created */ 3421/* return 1 if the volume control is created */
3419static int create_elem_capture_vol(struct hda_codec *codec, hda_nid_t nid, 3422static int create_elem_capture_vol(struct hda_codec *codec, hda_nid_t nid,
3420 const char *label, int direction) 3423 const char *label, int idx, int direction)
3421{ 3424{
3422 unsigned int caps, nums; 3425 unsigned int caps, nums;
3423 char name[32]; 3426 char name[32];
@@ -3434,8 +3437,8 @@ static int create_elem_capture_vol(struct hda_codec *codec, hda_nid_t nid,
3434 if (!nums) 3437 if (!nums)
3435 return 0; 3438 return 0;
3436 snprintf(name, sizeof(name), "%s Capture Volume", label); 3439 snprintf(name, sizeof(name), "%s Capture Volume", label);
3437 err = stac92xx_add_control(codec->spec, STAC_CTL_WIDGET_VOL, name, 3440 err = stac92xx_add_control_idx(codec->spec, STAC_CTL_WIDGET_VOL, idx, name,
3438 HDA_COMPOSE_AMP_VAL(nid, 3, 0, direction)); 3441 HDA_COMPOSE_AMP_VAL(nid, 3, 0, direction));
3439 if (err < 0) 3442 if (err < 0)
3440 return err; 3443 return err;
3441 return 1; 3444 return 1;
@@ -3448,27 +3451,14 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec,
3448 struct sigmatel_spec *spec = codec->spec; 3451 struct sigmatel_spec *spec = codec->spec;
3449 struct hda_input_mux *imux = &spec->private_imux; 3452 struct hda_input_mux *imux = &spec->private_imux;
3450 struct hda_input_mux *dimux = &spec->private_dimux; 3453 struct hda_input_mux *dimux = &spec->private_dimux;
3451 int err, i, active_mics; 3454 int err, i;
3452 unsigned int def_conf; 3455 unsigned int def_conf;
3453 3456
3454 dimux->items[dimux->num_items].label = stac92xx_dmic_labels[0]; 3457 snd_hda_add_imux_item(dimux, stac92xx_dmic_labels[0], 0, NULL);
3455 dimux->items[dimux->num_items].index = 0;
3456 dimux->num_items++;
3457
3458 active_mics = 0;
3459 for (i = 0; i < spec->num_dmics; i++) {
3460 /* check the validity: sometimes it's a dead vendor-spec node */
3461 if (get_wcaps_type(get_wcaps(codec, spec->dmic_nids[i]))
3462 != AC_WID_PIN)
3463 continue;
3464 def_conf = snd_hda_codec_get_pincfg(codec, spec->dmic_nids[i]);
3465 if (get_defcfg_connect(def_conf) != AC_JACK_PORT_NONE)
3466 active_mics++;
3467 }
3468 3458
3469 for (i = 0; i < spec->num_dmics; i++) { 3459 for (i = 0; i < spec->num_dmics; i++) {
3470 hda_nid_t nid; 3460 hda_nid_t nid;
3471 int index; 3461 int index, type_idx;
3472 const char *label; 3462 const char *label;
3473 3463
3474 nid = spec->dmic_nids[i]; 3464 nid = spec->dmic_nids[i];
@@ -3482,28 +3472,23 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec,
3482 if (index < 0) 3472 if (index < 0)
3483 continue; 3473 continue;
3484 3474
3485 if (active_mics == 1) 3475 label = hda_get_input_pin_label(codec, nid, 1);
3486 label = "Digital Mic"; 3476 snd_hda_add_imux_item(dimux, label, index, &type_idx);
3487 else
3488 label = stac92xx_dmic_labels[dimux->num_items];
3489 3477
3490 err = create_elem_capture_vol(codec, nid, label, HDA_INPUT); 3478 err = create_elem_capture_vol(codec, nid, label, type_idx,
3479 HDA_INPUT);
3491 if (err < 0) 3480 if (err < 0)
3492 return err; 3481 return err;
3493 if (!err) { 3482 if (!err) {
3494 err = create_elem_capture_vol(codec, nid, label, 3483 err = create_elem_capture_vol(codec, nid, label,
3495 HDA_OUTPUT); 3484 type_idx, HDA_OUTPUT);
3496 if (err < 0) 3485 if (err < 0)
3497 return err; 3486 return err;
3498 } 3487 }
3499 3488
3500 dimux->items[dimux->num_items].label = label;
3501 dimux->items[dimux->num_items].index = index;
3502 dimux->num_items++;
3503 if (snd_hda_get_bool_hint(codec, "separate_dmux") != 1) { 3489 if (snd_hda_get_bool_hint(codec, "separate_dmux") != 1) {
3504 imux->items[imux->num_items].label = label; 3490 snd_hda_add_imux_item(imux, label, index, NULL);
3505 imux->items[imux->num_items].index = index; 3491 spec->num_analog_muxes++;
3506 imux->num_items++;
3507 } 3492 }
3508 } 3493 }
3509 3494
@@ -3511,20 +3496,27 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec,
3511} 3496}
3512 3497
3513static int check_mic_pin(struct hda_codec *codec, hda_nid_t nid, 3498static int check_mic_pin(struct hda_codec *codec, hda_nid_t nid,
3514 hda_nid_t *fixed, hda_nid_t *ext) 3499 hda_nid_t *fixed, hda_nid_t *ext, hda_nid_t *dock)
3515{ 3500{
3516 unsigned int cfg; 3501 unsigned int cfg;
3517 3502
3518 if (!nid) 3503 if (!nid)
3519 return 0; 3504 return 0;
3520 cfg = snd_hda_codec_get_pincfg(codec, nid); 3505 cfg = snd_hda_codec_get_pincfg(codec, nid);
3521 switch (get_defcfg_connect(cfg)) { 3506 switch (snd_hda_get_input_pin_attr(cfg)) {
3522 case AC_JACK_PORT_FIXED: 3507 case INPUT_PIN_ATTR_INT:
3523 if (*fixed) 3508 if (*fixed)
3524 return 1; /* already occupied */ 3509 return 1; /* already occupied */
3525 *fixed = nid; 3510 *fixed = nid;
3526 break; 3511 break;
3527 case AC_JACK_PORT_COMPLEX: 3512 case INPUT_PIN_ATTR_UNUSED:
3513 break;
3514 case INPUT_PIN_ATTR_DOCK:
3515 if (*dock)
3516 return 1; /* already occupied */
3517 *dock = nid;
3518 break;
3519 default:
3528 if (*ext) 3520 if (*ext)
3529 return 1; /* already occupied */ 3521 return 1; /* already occupied */
3530 *ext = nid; 3522 *ext = nid;
@@ -3542,10 +3534,13 @@ static int set_mic_route(struct hda_codec *codec,
3542 int i; 3534 int i;
3543 3535
3544 mic->pin = pin; 3536 mic->pin = pin;
3545 for (i = AUTO_PIN_MIC; i <= AUTO_PIN_FRONT_MIC; i++) 3537 if (pin == 0)
3546 if (pin == cfg->input_pins[i]) 3538 return 0;
3539 for (i = 0; i < cfg->num_inputs; i++) {
3540 if (pin == cfg->inputs[i].pin)
3547 break; 3541 break;
3548 if (i <= AUTO_PIN_FRONT_MIC) { 3542 }
3543 if (i < cfg->num_inputs && cfg->inputs[i].type == AUTO_PIN_MIC) {
3549 /* analog pin */ 3544 /* analog pin */
3550 i = get_connection_index(codec, spec->mux_nids[0], pin); 3545 i = get_connection_index(codec, spec->mux_nids[0], pin);
3551 if (i < 0) 3546 if (i < 0)
@@ -3576,26 +3571,29 @@ static int stac_check_auto_mic(struct hda_codec *codec)
3576{ 3571{
3577 struct sigmatel_spec *spec = codec->spec; 3572 struct sigmatel_spec *spec = codec->spec;
3578 struct auto_pin_cfg *cfg = &spec->autocfg; 3573 struct auto_pin_cfg *cfg = &spec->autocfg;
3579 hda_nid_t fixed, ext; 3574 hda_nid_t fixed, ext, dock;
3580 int i; 3575 int i;
3581 3576
3582 for (i = AUTO_PIN_LINE; i < AUTO_PIN_LAST; i++) { 3577 for (i = 0; i < cfg->num_inputs; i++) {
3583 if (cfg->input_pins[i]) 3578 if (cfg->inputs[i].type >= AUTO_PIN_LINE_IN)
3584 return 0; /* must be exclusively mics */ 3579 return 0; /* must be exclusively mics */
3585 } 3580 }
3586 fixed = ext = 0; 3581 fixed = ext = dock = 0;
3587 for (i = AUTO_PIN_MIC; i <= AUTO_PIN_FRONT_MIC; i++) 3582 for (i = 0; i < cfg->num_inputs; i++)
3588 if (check_mic_pin(codec, cfg->input_pins[i], &fixed, &ext)) 3583 if (check_mic_pin(codec, cfg->inputs[i].pin,
3584 &fixed, &ext, &dock))
3589 return 0; 3585 return 0;
3590 for (i = 0; i < spec->num_dmics; i++) 3586 for (i = 0; i < spec->num_dmics; i++)
3591 if (check_mic_pin(codec, spec->dmic_nids[i], &fixed, &ext)) 3587 if (check_mic_pin(codec, spec->dmic_nids[i],
3588 &fixed, &ext, &dock))
3592 return 0; 3589 return 0;
3593 if (!fixed || !ext) 3590 if (!fixed && !ext && !dock)
3594 return 0; 3591 return 0; /* no input to switch */
3595 if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP)) 3592 if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP))
3596 return 0; /* no unsol support */ 3593 return 0; /* no unsol support */
3597 if (set_mic_route(codec, &spec->ext_mic, ext) || 3594 if (set_mic_route(codec, &spec->ext_mic, ext) ||
3598 set_mic_route(codec, &spec->int_mic, fixed)) 3595 set_mic_route(codec, &spec->int_mic, fixed) ||
3596 set_mic_route(codec, &spec->dock_mic, dock))
3599 return 0; /* something is wrong */ 3597 return 0; /* something is wrong */
3600 return 1; 3598 return 1;
3601} 3599}
@@ -3606,13 +3604,12 @@ static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const
3606 struct sigmatel_spec *spec = codec->spec; 3604 struct sigmatel_spec *spec = codec->spec;
3607 struct hda_input_mux *imux = &spec->private_imux; 3605 struct hda_input_mux *imux = &spec->private_imux;
3608 int i, j; 3606 int i, j;
3607 const char *label;
3609 3608
3610 for (i = 0; i < AUTO_PIN_LAST; i++) { 3609 for (i = 0; i < cfg->num_inputs; i++) {
3611 hda_nid_t nid = cfg->input_pins[i]; 3610 hda_nid_t nid = cfg->inputs[i].pin;
3612 int index, err; 3611 int index, err, type_idx;
3613 3612
3614 if (!nid)
3615 continue;
3616 index = -1; 3613 index = -1;
3617 for (j = 0; j < spec->num_muxes; j++) { 3614 for (j = 0; j < spec->num_muxes; j++) {
3618 index = get_connection_index(codec, spec->mux_nids[j], 3615 index = get_connection_index(codec, spec->mux_nids[j],
@@ -3623,15 +3620,14 @@ static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const
3623 if (index < 0) 3620 if (index < 0)
3624 continue; 3621 continue;
3625 3622
3623 label = hda_get_autocfg_input_label(codec, cfg, i);
3624 snd_hda_add_imux_item(imux, label, index, &type_idx);
3625
3626 err = create_elem_capture_vol(codec, nid, 3626 err = create_elem_capture_vol(codec, nid,
3627 auto_pin_cfg_labels[i], 3627 label, type_idx,
3628 HDA_INPUT); 3628 HDA_INPUT);
3629 if (err < 0) 3629 if (err < 0)
3630 return err; 3630 return err;
3631
3632 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
3633 imux->items[imux->num_items].index = index;
3634 imux->num_items++;
3635 } 3631 }
3636 spec->num_analog_muxes = imux->num_items; 3632 spec->num_analog_muxes = imux->num_items;
3637 3633
@@ -4305,38 +4301,38 @@ static int stac92xx_init(struct hda_codec *codec)
4305 AC_VERB_SET_CONNECT_SEL, 0); 4301 AC_VERB_SET_CONNECT_SEL, 0);
4306 if (enable_pin_detect(codec, spec->ext_mic.pin, STAC_MIC_EVENT)) 4302 if (enable_pin_detect(codec, spec->ext_mic.pin, STAC_MIC_EVENT))
4307 stac_issue_unsol_event(codec, spec->ext_mic.pin); 4303 stac_issue_unsol_event(codec, spec->ext_mic.pin);
4308 } 4304 if (enable_pin_detect(codec, spec->dock_mic.pin,
4309 for (i = 0; i < AUTO_PIN_LAST; i++) { 4305 STAC_MIC_EVENT))
4310 hda_nid_t nid = cfg->input_pins[i]; 4306 stac_issue_unsol_event(codec, spec->dock_mic.pin);
4311 if (nid) { 4307 }
4312 unsigned int pinctl, conf; 4308 for (i = 0; i < cfg->num_inputs; i++) {
4313 if (i == AUTO_PIN_MIC || i == AUTO_PIN_FRONT_MIC) { 4309 hda_nid_t nid = cfg->inputs[i].pin;
4314 /* for mic pins, force to initialize */ 4310 int type = cfg->inputs[i].type;
4315 pinctl = stac92xx_get_default_vref(codec, nid); 4311 unsigned int pinctl, conf;
4312 if (type == AUTO_PIN_MIC) {
4313 /* for mic pins, force to initialize */
4314 pinctl = stac92xx_get_default_vref(codec, nid);
4315 pinctl |= AC_PINCTL_IN_EN;
4316 stac92xx_auto_set_pinctl(codec, nid, pinctl);
4317 } else {
4318 pinctl = snd_hda_codec_read(codec, nid, 0,
4319 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4320 /* if PINCTL already set then skip */
4321 /* Also, if both INPUT and OUTPUT are set,
4322 * it must be a BIOS bug; need to override, too
4323 */
4324 if (!(pinctl & AC_PINCTL_IN_EN) ||
4325 (pinctl & AC_PINCTL_OUT_EN)) {
4326 pinctl &= ~AC_PINCTL_OUT_EN;
4316 pinctl |= AC_PINCTL_IN_EN; 4327 pinctl |= AC_PINCTL_IN_EN;
4317 stac92xx_auto_set_pinctl(codec, nid, pinctl); 4328 stac92xx_auto_set_pinctl(codec, nid, pinctl);
4318 } else {
4319 pinctl = snd_hda_codec_read(codec, nid, 0,
4320 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4321 /* if PINCTL already set then skip */
4322 /* Also, if both INPUT and OUTPUT are set,
4323 * it must be a BIOS bug; need to override, too
4324 */
4325 if (!(pinctl & AC_PINCTL_IN_EN) ||
4326 (pinctl & AC_PINCTL_OUT_EN)) {
4327 pinctl &= ~AC_PINCTL_OUT_EN;
4328 pinctl |= AC_PINCTL_IN_EN;
4329 stac92xx_auto_set_pinctl(codec, nid,
4330 pinctl);
4331 }
4332 }
4333 conf = snd_hda_codec_get_pincfg(codec, nid);
4334 if (get_defcfg_connect(conf) != AC_JACK_PORT_FIXED) {
4335 if (enable_pin_detect(codec, nid,
4336 STAC_INSERT_EVENT))
4337 stac_issue_unsol_event(codec, nid);
4338 } 4329 }
4339 } 4330 }
4331 conf = snd_hda_codec_get_pincfg(codec, nid);
4332 if (get_defcfg_connect(conf) != AC_JACK_PORT_FIXED) {
4333 if (enable_pin_detect(codec, nid, STAC_INSERT_EVENT))
4334 stac_issue_unsol_event(codec, nid);
4335 }
4340 } 4336 }
4341 for (i = 0; i < spec->num_dmics; i++) 4337 for (i = 0; i < spec->num_dmics; i++)
4342 stac92xx_auto_set_pinctl(codec, spec->dmic_nids[i], 4338 stac92xx_auto_set_pinctl(codec, spec->dmic_nids[i],
@@ -4383,11 +4379,9 @@ static int stac92xx_init(struct hda_codec *codec)
4383 stac_issue_unsol_event(codec, nid); 4379 stac_issue_unsol_event(codec, nid);
4384 } 4380 }
4385 4381
4386#ifdef CONFIG_SND_HDA_POWER_SAVE
4387 /* sync mute LED */ 4382 /* sync mute LED */
4388 if (spec->gpio_led && codec->patch_ops.check_power_status) 4383 if (spec->gpio_led)
4389 codec->patch_ops.check_power_status(codec, 0x01); 4384 hda_call_check_power_status(codec, 0x01);
4390#endif
4391 if (spec->dac_list) 4385 if (spec->dac_list)
4392 stac92xx_power_down(codec); 4386 stac92xx_power_down(codec);
4393 return 0; 4387 return 0;
@@ -4688,6 +4682,36 @@ static void stac92xx_report_jack(struct hda_codec *codec, hda_nid_t nid)
4688 } 4682 }
4689} 4683}
4690 4684
4685/* get the pin connection (fixed, none, etc) */
4686static unsigned int stac_get_defcfg_connect(struct hda_codec *codec, int idx)
4687{
4688 struct sigmatel_spec *spec = codec->spec;
4689 unsigned int cfg;
4690
4691 cfg = snd_hda_codec_get_pincfg(codec, spec->pin_nids[idx]);
4692 return get_defcfg_connect(cfg);
4693}
4694
4695static int stac92xx_connected_ports(struct hda_codec *codec,
4696 hda_nid_t *nids, int num_nids)
4697{
4698 struct sigmatel_spec *spec = codec->spec;
4699 int idx, num;
4700 unsigned int def_conf;
4701
4702 for (num = 0; num < num_nids; num++) {
4703 for (idx = 0; idx < spec->num_pins; idx++)
4704 if (spec->pin_nids[idx] == nids[num])
4705 break;
4706 if (idx >= spec->num_pins)
4707 break;
4708 def_conf = stac_get_defcfg_connect(codec, idx);
4709 if (def_conf == AC_JACK_PORT_NONE)
4710 break;
4711 }
4712 return num;
4713}
4714
4691static void stac92xx_mic_detect(struct hda_codec *codec) 4715static void stac92xx_mic_detect(struct hda_codec *codec)
4692{ 4716{
4693 struct sigmatel_spec *spec = codec->spec; 4717 struct sigmatel_spec *spec = codec->spec;
@@ -4695,6 +4719,8 @@ static void stac92xx_mic_detect(struct hda_codec *codec)
4695 4719
4696 if (get_pin_presence(codec, spec->ext_mic.pin)) 4720 if (get_pin_presence(codec, spec->ext_mic.pin))
4697 mic = &spec->ext_mic; 4721 mic = &spec->ext_mic;
4722 else if (get_pin_presence(codec, spec->dock_mic.pin))
4723 mic = &spec->dock_mic;
4698 else 4724 else
4699 mic = &spec->int_mic; 4725 mic = &spec->int_mic;
4700 if (mic->dmux_idx >= 0) 4726 if (mic->dmux_idx >= 0)
@@ -4937,11 +4963,9 @@ static int stac92xx_resume(struct hda_codec *codec)
4937 stac_issue_unsol_event(codec, 4963 stac_issue_unsol_event(codec,
4938 spec->autocfg.line_out_pins[0]); 4964 spec->autocfg.line_out_pins[0]);
4939 } 4965 }
4940#ifdef CONFIG_SND_HDA_POWER_SAVE
4941 /* sync mute LED */ 4966 /* sync mute LED */
4942 if (spec->gpio_led && codec->patch_ops.check_power_status) 4967 if (spec->gpio_led)
4943 codec->patch_ops.check_power_status(codec, 0x01); 4968 hda_call_check_power_status(codec, 0x01);
4944#endif
4945 return 0; 4969 return 0;
4946} 4970}
4947 4971
@@ -5313,11 +5337,16 @@ static int patch_stac92hd83xxx(struct hda_codec *codec)
5313 if (spec == NULL) 5337 if (spec == NULL)
5314 return -ENOMEM; 5338 return -ENOMEM;
5315 5339
5340 /* reset pin power-down; Windows may leave these bits after reboot */
5341 snd_hda_codec_write_cache(codec, codec->afg, 0, 0x7EC, 0);
5342 snd_hda_codec_write_cache(codec, codec->afg, 0, 0x7ED, 0);
5316 codec->no_trigger_sense = 1; 5343 codec->no_trigger_sense = 1;
5317 codec->spec = spec; 5344 codec->spec = spec;
5318 spec->linear_tone_beep = 1; 5345 spec->linear_tone_beep = 1;
5319 codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs; 5346 codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs;
5320 spec->digbeep_nid = 0x21; 5347 spec->digbeep_nid = 0x21;
5348 spec->dmic_nids = stac92hd83xxx_dmic_nids;
5349 spec->dmux_nids = stac92hd83xxx_mux_nids;
5321 spec->mux_nids = stac92hd83xxx_mux_nids; 5350 spec->mux_nids = stac92hd83xxx_mux_nids;
5322 spec->num_muxes = ARRAY_SIZE(stac92hd83xxx_mux_nids); 5351 spec->num_muxes = ARRAY_SIZE(stac92hd83xxx_mux_nids);
5323 spec->adc_nids = stac92hd83xxx_adc_nids; 5352 spec->adc_nids = stac92hd83xxx_adc_nids;
@@ -5363,9 +5392,13 @@ again:
5363 case 0x111d76d4: 5392 case 0x111d76d4:
5364 case 0x111d7605: 5393 case 0x111d7605:
5365 case 0x111d76d5: 5394 case 0x111d76d5:
5395 case 0x111d76e7:
5366 if (spec->board_config == STAC_92HD83XXX_PWR_REF) 5396 if (spec->board_config == STAC_92HD83XXX_PWR_REF)
5367 break; 5397 break;
5368 spec->num_pwrs = 0; 5398 spec->num_pwrs = 0;
5399 spec->num_dmics = stac92xx_connected_ports(codec,
5400 stac92hd83xxx_dmic_nids,
5401 STAC92HD83XXX_NUM_DMICS);
5369 break; 5402 break;
5370 } 5403 }
5371 5404
@@ -5424,36 +5457,6 @@ again:
5424 return 0; 5457 return 0;
5425} 5458}
5426 5459
5427/* get the pin connection (fixed, none, etc) */
5428static unsigned int stac_get_defcfg_connect(struct hda_codec *codec, int idx)
5429{
5430 struct sigmatel_spec *spec = codec->spec;
5431 unsigned int cfg;
5432
5433 cfg = snd_hda_codec_get_pincfg(codec, spec->pin_nids[idx]);
5434 return get_defcfg_connect(cfg);
5435}
5436
5437static int stac92hd71bxx_connected_ports(struct hda_codec *codec,
5438 hda_nid_t *nids, int num_nids)
5439{
5440 struct sigmatel_spec *spec = codec->spec;
5441 int idx, num;
5442 unsigned int def_conf;
5443
5444 for (num = 0; num < num_nids; num++) {
5445 for (idx = 0; idx < spec->num_pins; idx++)
5446 if (spec->pin_nids[idx] == nids[num])
5447 break;
5448 if (idx >= spec->num_pins)
5449 break;
5450 def_conf = stac_get_defcfg_connect(codec, idx);
5451 if (def_conf == AC_JACK_PORT_NONE)
5452 break;
5453 }
5454 return num;
5455}
5456
5457static int stac92hd71bxx_connected_smuxes(struct hda_codec *codec, 5460static int stac92hd71bxx_connected_smuxes(struct hda_codec *codec,
5458 hda_nid_t dig0pin) 5461 hda_nid_t dig0pin)
5459{ 5462{
@@ -5592,7 +5595,7 @@ again:
5592 case 0x111d76b5: 5595 case 0x111d76b5:
5593 spec->init = stac92hd71bxx_core_init; 5596 spec->init = stac92hd71bxx_core_init;
5594 codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs; 5597 codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs;
5595 spec->num_dmics = stac92hd71bxx_connected_ports(codec, 5598 spec->num_dmics = stac92xx_connected_ports(codec,
5596 stac92hd71bxx_dmic_nids, 5599 stac92hd71bxx_dmic_nids,
5597 STAC92HD71BXX_NUM_DMICS); 5600 STAC92HD71BXX_NUM_DMICS);
5598 break; 5601 break;
@@ -5624,7 +5627,7 @@ again:
5624 snd_hda_codec_set_pincfg(codec, 0x0f, 0x40f000f0); 5627 snd_hda_codec_set_pincfg(codec, 0x0f, 0x40f000f0);
5625 snd_hda_codec_set_pincfg(codec, 0x19, 0x40f000f3); 5628 snd_hda_codec_set_pincfg(codec, 0x19, 0x40f000f3);
5626 stac92hd71bxx_dmic_nids[STAC92HD71BXX_NUM_DMICS - 1] = 0; 5629 stac92hd71bxx_dmic_nids[STAC92HD71BXX_NUM_DMICS - 1] = 0;
5627 spec->num_dmics = stac92hd71bxx_connected_ports(codec, 5630 spec->num_dmics = stac92xx_connected_ports(codec,
5628 stac92hd71bxx_dmic_nids, 5631 stac92hd71bxx_dmic_nids,
5629 STAC92HD71BXX_NUM_DMICS - 1); 5632 STAC92HD71BXX_NUM_DMICS - 1);
5630 break; 5633 break;
@@ -5638,7 +5641,7 @@ again:
5638 default: 5641 default:
5639 spec->init = stac92hd71bxx_core_init; 5642 spec->init = stac92hd71bxx_core_init;
5640 codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs; 5643 codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs;
5641 spec->num_dmics = stac92hd71bxx_connected_ports(codec, 5644 spec->num_dmics = stac92xx_connected_ports(codec,
5642 stac92hd71bxx_dmic_nids, 5645 stac92hd71bxx_dmic_nids,
5643 STAC92HD71BXX_NUM_DMICS); 5646 STAC92HD71BXX_NUM_DMICS);
5644 break; 5647 break;
@@ -6320,6 +6323,8 @@ static struct hda_codec_preset snd_hda_preset_sigmatel[] = {
6320 { .id = 0x111d76cc, .name = "92HD89F3", .patch = patch_stac92hd73xx }, 6323 { .id = 0x111d76cc, .name = "92HD89F3", .patch = patch_stac92hd73xx },
6321 { .id = 0x111d76cd, .name = "92HD89F2", .patch = patch_stac92hd73xx }, 6324 { .id = 0x111d76cd, .name = "92HD89F2", .patch = patch_stac92hd73xx },
6322 { .id = 0x111d76ce, .name = "92HD89F1", .patch = patch_stac92hd73xx }, 6325 { .id = 0x111d76ce, .name = "92HD89F1", .patch = patch_stac92hd73xx },
6326 { .id = 0x111d76e0, .name = "92HD91BXX", .patch = patch_stac92hd83xxx},
6327 { .id = 0x111d76e7, .name = "92HD90BXX", .patch = patch_stac92hd83xxx},
6323 {} /* terminator */ 6328 {} /* terminator */
6324}; 6329};
6325 6330