Commit e035b841 authored by Matthew Ranostay's avatar Matthew Ranostay Committed by Jaroslav Kysela

[ALSA] hda: Added new IDT codec family

Added initial support for the STAC92HD71BXX family of codecs.
Signed-off-by: default avatarMatthew Ranostay <mranostay@embeddedalley.com>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
Signed-off-by: default avatarJaroslav Kysela <perex@perex.cz>
parent 2797f724
...@@ -61,6 +61,11 @@ enum { ...@@ -61,6 +61,11 @@ enum {
STAC_9205_MODELS STAC_9205_MODELS
}; };
enum {
STAC_92HD71BXX_REF,
STAC_92HD71BXX_MODELS
};
enum { enum {
STAC_925x_REF, STAC_925x_REF,
STAC_M2_2, STAC_M2_2,
...@@ -171,6 +176,23 @@ static hda_nid_t stac9200_dac_nids[1] = { ...@@ -171,6 +176,23 @@ static hda_nid_t stac9200_dac_nids[1] = {
0x02, 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] = { static hda_nid_t stac925x_adc_nids[1] = {
0x03, 0x03,
}; };
...@@ -237,6 +259,11 @@ static hda_nid_t stac922x_pin_nids[10] = { ...@@ -237,6 +259,11 @@ static hda_nid_t stac922x_pin_nids[10] = {
0x0f, 0x10, 0x11, 0x15, 0x1b, 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] = { static hda_nid_t stac927x_pin_nids[14] = {
0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
0x0f, 0x10, 0x11, 0x12, 0x13, 0x0f, 0x10, 0x11, 0x12, 0x13,
...@@ -359,6 +386,20 @@ static struct hda_verb stac9200_eapd_init[] = { ...@@ -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[] = { static struct hda_verb stac925x_core_init[] = {
/* set dac0mux for dac converter */ /* set dac0mux for dac converter */
{ 0x06, AC_VERB_SET_CONNECT_SEL, 0x00}, { 0x06, AC_VERB_SET_CONNECT_SEL, 0x00},
...@@ -434,6 +475,21 @@ static struct snd_kcontrol_new stac9200_mixer[] = { ...@@ -434,6 +475,21 @@ static struct snd_kcontrol_new stac9200_mixer[] = {
{ } /* end */ { } /* 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[] = { static struct snd_kcontrol_new stac925x_mixer[] = {
STAC_INPUT_SOURCE(1), STAC_INPUT_SOURCE(1),
HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_OUTPUT), HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_OUTPUT),
...@@ -786,6 +842,27 @@ static struct snd_pci_quirk stac925x_cfg_tbl[] = { ...@@ -786,6 +842,27 @@ static struct snd_pci_quirk stac925x_cfg_tbl[] = {
{} /* terminator */ {} /* 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] = { static unsigned int ref922x_pin_configs[10] = {
0x01014010, 0x01016011, 0x01012012, 0x0221401f, 0x01014010, 0x01016011, 0x01012012, 0x0221401f,
0x01813122, 0x01011014, 0x01441030, 0x01c41030, 0x01813122, 0x01011014, 0x01441030, 0x01c41030,
...@@ -2560,6 +2637,77 @@ static int patch_stac925x(struct hda_codec *codec) ...@@ -2560,6 +2637,77 @@ static int patch_stac925x(struct hda_codec *codec)
return 0; 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) static int patch_stac922x(struct hda_codec *codec)
{ {
struct sigmatel_spec *spec; struct sigmatel_spec *spec;
...@@ -3128,5 +3276,6 @@ struct hda_codec_preset snd_hda_preset_sigmatel[] = { ...@@ -3128,5 +3276,6 @@ struct hda_codec_preset snd_hda_preset_sigmatel[] = {
{ .id = 0x838476a5, .name = "STAC9255D", .patch = patch_stac9205 }, { .id = 0x838476a5, .name = "STAC9255D", .patch = patch_stac9205 },
{ .id = 0x838476a6, .name = "STAC9254", .patch = patch_stac9205 }, { .id = 0x838476a6, .name = "STAC9254", .patch = patch_stac9205 },
{ .id = 0x838476a7, .name = "STAC9254D", .patch = patch_stac9205 }, { .id = 0x838476a7, .name = "STAC9254D", .patch = patch_stac9205 },
{ .id = 0x111d76b0, .name = "92HD71BXX", .patch = patch_stac92hd71bxx },
{} /* terminator */ {} /* terminator */
}; };
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment