[ALSA] hda: Added new IDT codec family
authorMatthew Ranostay <mranostay@embeddedalley.com>
Tue, 6 Nov 2007 10:53:55 +0000 (11:53 +0100)
committerJaroslav Kysela <perex@perex.cz>
Thu, 31 Jan 2008 16:29:16 +0000 (17:29 +0100)
Added initial support for the STAC92HD71BXX family of codecs.

Signed-off-by: Matthew Ranostay <mranostay@embeddedalley.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
sound/pci/hda/patch_sigmatel.c

index 4dc09ef899bf8aabc915b489be984af16f08cecc..f6e00c4ff32506894e7fbd97b0f9635e2737089a 100644 (file)
@@ -61,6 +61,11 @@ enum {
        STAC_9205_MODELS
 };
 
+enum {
+       STAC_92HD71BXX_REF,
+       STAC_92HD71BXX_MODELS
+};
+
 enum {
        STAC_925x_REF,
        STAC_M2_2,
@@ -171,6 +176,23 @@ static hda_nid_t stac9200_dac_nids[1] = {
         0x02,
 };
 
+static hda_nid_t stac92hd71bxx_adc_nids[2] = {
+       0x12, 0x13,
+};
+
+static hda_nid_t stac92hd71bxx_mux_nids[2] = {
+       0x1a, 0x1b
+};
+
+static hda_nid_t stac92hd71bxx_dac_nids[2] = {
+       0x10, /*0x11, */
+};
+
+#define STAC92HD71BXX_NUM_DMICS        2
+static hda_nid_t stac92hd71bxx_dmic_nids[STAC92HD71BXX_NUM_DMICS + 1] = {
+       0x18, 0x19, 0
+};
+
 static hda_nid_t stac925x_adc_nids[1] = {
         0x03,
 };
@@ -237,6 +259,11 @@ static hda_nid_t stac922x_pin_nids[10] = {
        0x0f, 0x10, 0x11, 0x15, 0x1b,
 };
 
+static hda_nid_t stac92hd71bxx_pin_nids[10] = {
+       0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
+       0x0f, 0x14, 0x18, 0x19, 0x1e,
+};
+
 static hda_nid_t stac927x_pin_nids[14] = {
        0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
        0x0f, 0x10, 0x11, 0x12, 0x13,
@@ -359,6 +386,20 @@ static struct hda_verb stac9200_eapd_init[] = {
        {}
 };
 
+static struct hda_verb stac92hd71bxx_core_init[] = {
+       /* set master volume and direct control */
+       { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
+       /* connect headphone jack to dac1 */
+       { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01},
+       /* unmute right and left channels for nodes 0x0a, 0xd, 0x0f */
+       { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+       { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+       { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+       /* unmute mono out node */
+       { 0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+       {}
+};
+
 static struct hda_verb stac925x_core_init[] = {
        /* set dac0mux for dac converter */
        { 0x06, AC_VERB_SET_CONNECT_SEL, 0x00},
@@ -434,6 +475,21 @@ static struct snd_kcontrol_new stac9200_mixer[] = {
        { } /* end */
 };
 
+static struct snd_kcontrol_new stac92hd71bxx_mixer[] = {
+       STAC_DIGITAL_INPUT_SOURCE(1),
+       STAC_INPUT_SOURCE(2),
+       STAC_VOLKNOB(0x28),
+
+       /* hardware gain controls */
+       HDA_CODEC_VOLUME("Digital Mic 1 Volume", 0x18, 0, HDA_OUTPUT),
+       HDA_CODEC_VOLUME("Digital Mic 2 Volume", 0x19, 0, HDA_OUTPUT),
+
+       HDA_CODEC_VOLUME("Capture Volume", 0x1c, 0, HDA_OUTPUT),
+       HDA_CODEC_MUTE("Capture Switch", 0x1c, 0, HDA_OUTPUT),
+       HDA_CODEC_VOLUME("Capture Mux Volume", 0x1a, 0, HDA_OUTPUT),
+       { } /* end */
+};
+
 static struct snd_kcontrol_new stac925x_mixer[] = {
        STAC_INPUT_SOURCE(1),
        HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_OUTPUT),
@@ -786,6 +842,27 @@ static struct snd_pci_quirk stac925x_cfg_tbl[] = {
        {} /* terminator */
 };
 
+static unsigned int ref92hd71bxx_pin_configs[10] = {
+       0x02214030, 0x02a19040, 0x01a19020, 0x01014010,
+       0x0181302e, 0x01114010, 0x01a19020, 0x90a000f0,
+       0x90a000f0, 0x01452050,
+};
+
+static unsigned int *stac92hd71bxx_brd_tbl[STAC_92HD71BXX_MODELS] = {
+       [STAC_92HD71BXX_REF] = ref92hd71bxx_pin_configs,
+};
+
+static const char *stac92hd71bxx_models[STAC_92HD71BXX_MODELS] = {
+       [STAC_92HD71BXX_REF] = "ref",
+};
+
+static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = {
+       /* SigmaTel reference board */
+       SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
+                     "DFI LanParty", STAC_92HD71BXX_REF),
+       {} /* terminator */
+};
+
 static unsigned int ref922x_pin_configs[10] = {
        0x01014010, 0x01016011, 0x01012012, 0x0221401f,
        0x01813122, 0x01011014, 0x01441030, 0x01c41030,
@@ -2560,6 +2637,77 @@ static int patch_stac925x(struct hda_codec *codec)
        return 0;
 }
 
+static int patch_stac92hd71bxx(struct hda_codec *codec)
+{
+       struct sigmatel_spec *spec;
+       int err = 0;
+
+       spec  = kzalloc(sizeof(*spec), GFP_KERNEL);
+       if (spec == NULL)
+               return -ENOMEM;
+
+       codec->spec = spec;
+       spec->num_pins = ARRAY_SIZE(stac92hd71bxx_pin_nids);
+       spec->pin_nids = stac92hd71bxx_pin_nids;
+       spec->board_config = snd_hda_check_board_config(codec,
+                                                       STAC_92HD71BXX_MODELS,
+                                                       stac92hd71bxx_models,
+                                                       stac92hd71bxx_cfg_tbl);
+again:
+       if (spec->board_config < 0) {
+               snd_printdd(KERN_INFO "hda_codec: Unknown model for"
+                       " STAC92HD71BXX, using BIOS defaults\n");
+               err = stac92xx_save_bios_config_regs(codec);
+               if (err < 0) {
+                       stac92xx_free(codec);
+                       return err;
+               }
+               spec->pin_configs = spec->bios_pin_configs;
+       } else {
+               spec->pin_configs = stac92hd71bxx_brd_tbl[spec->board_config];
+               stac92xx_set_config_regs(codec);
+       }
+
+       spec->gpio_mask = spec->gpio_data = 0x00000001; /* GPIO0 High = EAPD */
+       stac92xx_enable_gpio_mask(codec);
+
+       spec->init = stac92hd71bxx_core_init;
+       spec->mixer = stac92hd71bxx_mixer;
+
+       spec->mux_nids = stac92hd71bxx_mux_nids;
+       spec->adc_nids = stac92hd71bxx_adc_nids;
+       spec->dmic_nids = stac92hd71bxx_dmic_nids;
+       spec->dmux_nid = 0x1c;
+
+       spec->num_muxes = ARRAY_SIZE(stac92hd71bxx_mux_nids);
+       spec->num_adcs = ARRAY_SIZE(stac92hd71bxx_adc_nids);
+       spec->num_dmics = STAC92HD71BXX_NUM_DMICS;
+
+       spec->multiout.num_dacs = 2;
+       spec->multiout.hp_nid = 0x11;
+       spec->multiout.dac_nids = stac92hd71bxx_dac_nids;
+
+       err = stac92xx_parse_auto_config(codec, 0x21, 0x23);
+       if (!err) {
+               if (spec->board_config < 0) {
+                       printk(KERN_WARNING "hda_codec: No auto-config is "
+                              "available, default to model=ref\n");
+                       spec->board_config = STAC_92HD71BXX_REF;
+                       goto again;
+               }
+               err = -EINVAL;
+       }
+
+       if (err < 0) {
+               stac92xx_free(codec);
+               return err;
+       }
+
+       codec->patch_ops = stac92xx_patch_ops;
+
+       return 0;
+};
+
 static int patch_stac922x(struct hda_codec *codec)
 {
        struct sigmatel_spec *spec;
@@ -3128,5 +3276,6 @@ struct hda_codec_preset snd_hda_preset_sigmatel[] = {
        { .id = 0x838476a5, .name = "STAC9255D", .patch = patch_stac9205 },
        { .id = 0x838476a6, .name = "STAC9254", .patch = patch_stac9205 },
        { .id = 0x838476a7, .name = "STAC9254D", .patch = patch_stac9205 },
+       { .id = 0x111d76b0, .name = "92HD71BXX", .patch = patch_stac92hd71bxx },
        {} /* terminator */
 };