ACPI: ibm-acpi: workaround for EC 0x2f initialization bug
[powerpc.git] / sound / pci / hda / patch_realtek.c
index f857e96..84a3eb8 100644 (file)
@@ -111,6 +111,7 @@ enum {
        ALC883_3ST_6ch,
        ALC883_6ST_DIG,
        ALC888_DEMO_BOARD,
+       ALC883_ACER,
        ALC883_AUTO,
        ALC883_MODEL_LAST,
 };
@@ -1795,25 +1796,9 @@ static int alc_build_pcms(struct hda_codec *codec)
                }
        }
 
-       /* If the use of more than one ADC is requested for the current
-        * model, configure a second analog capture-only PCM.
-        */
-       if (spec->num_adc_nids > 1) {
-               codec->num_pcms++;
-               info++;
-               info->name = spec->stream_name_analog;
-               /* No playback stream for second PCM */
-               info->stream[SNDRV_PCM_STREAM_PLAYBACK] = alc_pcm_null_playback;
-               info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
-               if (spec->stream_analog_capture) {
-                       snd_assert(spec->adc_nids, return -EINVAL);
-                       info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
-                       info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[1];
-               }
-       }
-
+       /* SPDIF for stream index #1 */
        if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
-               codec->num_pcms++;
+               codec->num_pcms = 2;
                info++;
                info->name = spec->stream_name_digital;
                if (spec->multiout.dig_out_nid &&
@@ -1828,6 +1813,24 @@ static int alc_build_pcms(struct hda_codec *codec)
                }
        }
 
+       /* If the use of more than one ADC is requested for the current
+        * model, configure a second analog capture-only PCM.
+        */
+       /* Additional Analaog capture for index #2 */
+       if (spec->num_adc_nids > 1 && spec->stream_analog_capture &&
+           spec->adc_nids) {
+               codec->num_pcms = 3;
+               info++;
+               info->name = spec->stream_name_analog;
+               /* No playback stream for second PCM */
+               info->stream[SNDRV_PCM_STREAM_PLAYBACK] = alc_pcm_null_playback;
+               info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
+               if (spec->stream_analog_capture) {
+                       info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
+                       info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[1];
+               }
+       }
+
        return 0;
 }
 
@@ -2143,7 +2146,10 @@ static struct hda_board_config alc880_cfg_tbl[] = {
        { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20f, .config = ALC880_3ST },
        { .pci_subvendor = 0x8086, .pci_subdevice = 0xe210, .config = ALC880_3ST },
        { .pci_subvendor = 0x8086, .pci_subdevice = 0xe211, .config = ALC880_3ST },
+       { .pci_subvendor = 0x8086, .pci_subdevice = 0xe212, .config = ALC880_3ST },
+       { .pci_subvendor = 0x8086, .pci_subdevice = 0xe213, .config = ALC880_3ST },
        { .pci_subvendor = 0x8086, .pci_subdevice = 0xe214, .config = ALC880_3ST },
+       { .pci_subvendor = 0x8086, .pci_subdevice = 0xe234, .config = ALC880_3ST },
        { .pci_subvendor = 0x8086, .pci_subdevice = 0xe302, .config = ALC880_3ST },
        { .pci_subvendor = 0x8086, .pci_subdevice = 0xe303, .config = ALC880_3ST },
        { .pci_subvendor = 0x8086, .pci_subdevice = 0xe304, .config = ALC880_3ST },
@@ -2266,6 +2272,7 @@ static struct hda_board_config alc880_cfg_tbl[] = {
 
        { .modelname = "lg-lw", .config = ALC880_LG_LW },
        { .pci_subvendor = 0x1854, .pci_subdevice = 0x0018, .config = ALC880_LG_LW },
+       { .pci_subvendor = 0x1854, .pci_subdevice = 0x0077, .config = ALC880_LG_LW },
 
 #ifdef CONFIG_SND_DEBUG
        { .modelname = "test", .config = ALC880_TEST },
@@ -2746,7 +2753,7 @@ static void alc880_auto_init_extra_out(struct hda_codec *codec)
        pin = spec->autocfg.speaker_pins[0];
        if (pin) /* connect to front */
                alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
-       pin = spec->autocfg.hp_pin;
+       pin = spec->autocfg.hp_pins[0];
        if (pin) /* connect to front */
                alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
 }
@@ -2787,7 +2794,7 @@ static int alc880_parse_auto_config(struct hda_codec *codec)
            (err = alc880_auto_create_extra_out(spec,
                                                spec->autocfg.speaker_pins[0],
                                                "Speaker")) < 0 ||
-           (err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pin,
+           (err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
                                                "Headphone")) < 0 ||
            (err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0)
                return err;
@@ -3729,7 +3736,7 @@ static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
                        return err;
        }
 
-       nid = cfg->hp_pin;
+       nid = cfg->hp_pins[0];
        if (nid) {
                err = alc260_add_playback_controls(spec, nid, "Headphone");
                if (err < 0)
@@ -3799,7 +3806,7 @@ static void alc260_auto_init_multi_out(struct hda_codec *codec)
        if (nid)
                alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
 
-       nid = spec->autocfg.hp_pin;
+       nid = spec->autocfg.hp_pins[0];
        if (nid)
                alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
 }      
@@ -4519,7 +4526,7 @@ static void alc882_auto_init_hp_out(struct hda_codec *codec)
        struct alc_spec *spec = codec->spec;
        hda_nid_t pin;
 
-       pin = spec->autocfg.hp_pin;
+       pin = spec->autocfg.hp_pins[0];
        if (pin) /* connect to front */
                alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); /* use dac 0 */
 }
@@ -5058,12 +5065,21 @@ static struct hda_board_config alc883_cfg_tbl[] = {
        { .modelname = "3stack-6ch", .config = ALC883_3ST_6ch },
        { .pci_subvendor = 0x108e, .pci_subdevice = 0x534d,
          .config = ALC883_3ST_6ch },
+        { .pci_subvendor = 0x8086, .pci_subdevice = 0xd601,
+          .config = ALC883_3ST_6ch }, /* D102GGC */
        { .modelname = "6stack-dig", .config = ALC883_6ST_DIG },
        { .pci_subvendor = 0x1462, .pci_subdevice = 0x6668,
          .config = ALC883_6ST_DIG }, /* MSI  */
        { .pci_subvendor = 0x105b, .pci_subdevice = 0x6668,
          .config = ALC883_6ST_DIG }, /* Foxconn */
        { .modelname = "6stack-dig-demo", .config = ALC888_DEMO_BOARD },
+       { .modelname = "acer", .config = ALC883_ACER },
+       { .pci_subvendor = 0x1025, .pci_subdevice = 0/*0x0102*/,
+         .config = ALC883_ACER },
+       { .pci_subvendor = 0x1025, .pci_subdevice = 0x0102,
+         .config = ALC883_ACER },
+       { .pci_subvendor = 0x1025, .pci_subdevice = 0x009f,
+         .config = ALC883_ACER },
        { .modelname = "auto", .config = ALC883_AUTO },
        {}
 };
@@ -5134,6 +5150,23 @@ static struct alc_config_preset alc883_presets[] = {
                .channel_mode = alc883_sixstack_modes,
                .input_mux = &alc883_capture_source,
        },
+       [ALC883_ACER] = {
+               .mixers = { alc883_base_mixer,
+                           alc883_chmode_mixer },
+               /* On TravelMate laptops, GPIO 0 enables the internal speaker
+                * and the headphone jack.  Turn this on and rely on the
+                * standard mute methods whenever the user wants to turn
+                * these outputs off.
+                */
+               .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
+               .num_dacs = ARRAY_SIZE(alc883_dac_nids),
+               .dac_nids = alc883_dac_nids,
+               .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
+               .adc_nids = alc883_adc_nids,
+               .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
+               .channel_mode = alc883_3ST_2ch_modes,
+               .input_mux = &alc883_capture_source,
+       },
 };
 
 
@@ -5178,7 +5211,7 @@ static void alc883_auto_init_hp_out(struct hda_codec *codec)
        struct alc_spec *spec = codec->spec;
        hda_nid_t pin;
 
-       pin = spec->autocfg.hp_pin;
+       pin = spec->autocfg.hp_pins[0];
        if (pin) /* connect to front */
                /* use dac 0 */
                alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
@@ -5540,6 +5573,7 @@ static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
                .info = snd_hda_mixer_amp_volume_info,
                .get = snd_hda_mixer_amp_volume_get,
                .put = alc262_fujitsu_master_vol_put,
+               .tlv = { .c = snd_hda_mixer_amp_tlv },
                .private_value = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
        },
        {
@@ -5600,7 +5634,7 @@ static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, const struct
                                return err;
                }
        }
-       nid = cfg->hp_pin;
+       nid = cfg->hp_pins[0];
        if (nid) {
                /* spec->multiout.hp_nid = 2; */
                if (nid == 0x16) {
@@ -6600,7 +6634,7 @@ static void alc861_auto_init_hp_out(struct hda_codec *codec)
        struct alc_spec *spec = codec->spec;
        hda_nid_t pin;
 
-       pin = spec->autocfg.hp_pin;
+       pin = spec->autocfg.hp_pins[0];
        if (pin) /* connect to front */
                alc861_auto_set_output_and_unmute(codec, pin, PIN_HP, spec->multiout.dac_nids[0]);
 }
@@ -6635,7 +6669,7 @@ static int alc861_parse_auto_config(struct hda_codec *codec)
 
        if ((err = alc861_auto_fill_dac_nids(spec, &spec->autocfg)) < 0 ||
            (err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 ||
-           (err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pin)) < 0 ||
+           (err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0])) < 0 ||
            (err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0)
                return err;