|
@@ -44,6 +44,7 @@ enum {
|
|
|
|
|
|
enum {
|
|
|
STAC_9205_REF,
|
|
|
+ STAC_M43xx,
|
|
|
STAC_9205_MODELS
|
|
|
};
|
|
|
|
|
@@ -218,7 +219,6 @@ static hda_nid_t stac9205_pin_nids[12] = {
|
|
|
0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
|
|
|
0x0f, 0x14, 0x16, 0x17, 0x18,
|
|
|
0x21, 0x22,
|
|
|
-
|
|
|
};
|
|
|
|
|
|
static int stac92xx_dmux_enum_info(struct snd_kcontrol *kcontrol,
|
|
@@ -773,7 +773,8 @@ static unsigned int ref9205_pin_configs[12] = {
|
|
|
};
|
|
|
|
|
|
static unsigned int *stac9205_brd_tbl[STAC_9205_MODELS] = {
|
|
|
- ref9205_pin_configs,
|
|
|
+ [STAC_REF] = ref9205_pin_configs,
|
|
|
+ [STAC_M43xx] = NULL,
|
|
|
};
|
|
|
|
|
|
static const char *stac9205_models[STAC_9205_MODELS] = {
|
|
@@ -784,6 +785,10 @@ static struct snd_pci_quirk stac9205_cfg_tbl[] = {
|
|
|
/* SigmaTel reference board */
|
|
|
SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
|
|
|
"DFI LanParty", STAC_9205_REF),
|
|
|
+ SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x01f8,
|
|
|
+ "Dell Precision", STAC_M43xx),
|
|
|
+ SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x01ff,
|
|
|
+ "Dell Precision", STAC_M43xx),
|
|
|
{} /* terminator */
|
|
|
};
|
|
|
|
|
@@ -813,48 +818,56 @@ static int stac92xx_save_bios_config_regs(struct hda_codec *codec)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static void stac92xx_set_config_reg(struct hda_codec *codec,
|
|
|
+ hda_nid_t pin_nid, unsigned int pin_config)
|
|
|
+{
|
|
|
+ int i;
|
|
|
+ snd_hda_codec_write(codec, pin_nid, 0,
|
|
|
+ AC_VERB_SET_CONFIG_DEFAULT_BYTES_0,
|
|
|
+ pin_config & 0x000000ff);
|
|
|
+ snd_hda_codec_write(codec, pin_nid, 0,
|
|
|
+ AC_VERB_SET_CONFIG_DEFAULT_BYTES_1,
|
|
|
+ (pin_config & 0x0000ff00) >> 8);
|
|
|
+ snd_hda_codec_write(codec, pin_nid, 0,
|
|
|
+ AC_VERB_SET_CONFIG_DEFAULT_BYTES_2,
|
|
|
+ (pin_config & 0x00ff0000) >> 16);
|
|
|
+ snd_hda_codec_write(codec, pin_nid, 0,
|
|
|
+ AC_VERB_SET_CONFIG_DEFAULT_BYTES_3,
|
|
|
+ pin_config >> 24);
|
|
|
+ i = snd_hda_codec_read(codec, pin_nid, 0,
|
|
|
+ AC_VERB_GET_CONFIG_DEFAULT,
|
|
|
+ 0x00);
|
|
|
+ snd_printdd(KERN_INFO "hda_codec: pin nid %2.2x pin config %8.8x\n",
|
|
|
+ pin_nid, i);
|
|
|
+}
|
|
|
+
|
|
|
static void stac92xx_set_config_regs(struct hda_codec *codec)
|
|
|
{
|
|
|
int i;
|
|
|
struct sigmatel_spec *spec = codec->spec;
|
|
|
- unsigned int pin_cfg;
|
|
|
|
|
|
- if (! spec->pin_nids || ! spec->pin_configs)
|
|
|
- return;
|
|
|
+ if (!spec->pin_configs)
|
|
|
+ return;
|
|
|
|
|
|
- for (i = 0; i < spec->num_pins; i++) {
|
|
|
- snd_hda_codec_write(codec, spec->pin_nids[i], 0,
|
|
|
- AC_VERB_SET_CONFIG_DEFAULT_BYTES_0,
|
|
|
- spec->pin_configs[i] & 0x000000ff);
|
|
|
- snd_hda_codec_write(codec, spec->pin_nids[i], 0,
|
|
|
- AC_VERB_SET_CONFIG_DEFAULT_BYTES_1,
|
|
|
- (spec->pin_configs[i] & 0x0000ff00) >> 8);
|
|
|
- snd_hda_codec_write(codec, spec->pin_nids[i], 0,
|
|
|
- AC_VERB_SET_CONFIG_DEFAULT_BYTES_2,
|
|
|
- (spec->pin_configs[i] & 0x00ff0000) >> 16);
|
|
|
- snd_hda_codec_write(codec, spec->pin_nids[i], 0,
|
|
|
- AC_VERB_SET_CONFIG_DEFAULT_BYTES_3,
|
|
|
- spec->pin_configs[i] >> 24);
|
|
|
- pin_cfg = snd_hda_codec_read(codec, spec->pin_nids[i], 0,
|
|
|
- AC_VERB_GET_CONFIG_DEFAULT,
|
|
|
- 0x00);
|
|
|
- snd_printdd(KERN_INFO "hda_codec: pin nid %2.2x pin config %8.8x\n", spec->pin_nids[i], pin_cfg);
|
|
|
- }
|
|
|
+ for (i = 0; i < spec->num_pins; i++)
|
|
|
+ stac92xx_set_config_reg(codec, spec->pin_nids[i],
|
|
|
+ spec->pin_configs[i]);
|
|
|
}
|
|
|
|
|
|
-static void stac92xx_enable_eapd(struct hda_codec *codec)
|
|
|
+static void stac92xx_enable_gpio_mask(struct hda_codec *codec,
|
|
|
+ int gpio_mask, int gpio_data)
|
|
|
{
|
|
|
- /* Configure GPIO0 as output */
|
|
|
+ /* Configure GPIOx as output */
|
|
|
snd_hda_codec_write(codec, codec->afg, 0,
|
|
|
- AC_VERB_SET_GPIO_DIRECTION, 0x00000001);
|
|
|
- /* Configure GPIO0 as CMOS */
|
|
|
+ AC_VERB_SET_GPIO_DIRECTION, gpio_mask);
|
|
|
+ /* Configure GPIOx as CMOS */
|
|
|
snd_hda_codec_write(codec, codec->afg, 0, 0x7e7, 0x00000000);
|
|
|
- /* Assert GPIO0 high */
|
|
|
+ /* Assert GPIOx */
|
|
|
snd_hda_codec_write(codec, codec->afg, 0,
|
|
|
- AC_VERB_SET_GPIO_DATA, 0x00000001);
|
|
|
- /* Enable GPIO0 */
|
|
|
+ AC_VERB_SET_GPIO_DATA, gpio_data);
|
|
|
+ /* Enable GPIOx */
|
|
|
snd_hda_codec_write(codec, codec->afg, 0,
|
|
|
- AC_VERB_SET_GPIO_MASK, 0x00000001);
|
|
|
+ AC_VERB_SET_GPIO_MASK, gpio_mask);
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -2233,7 +2246,8 @@ static int patch_stac927x(struct hda_codec *codec)
|
|
|
}
|
|
|
|
|
|
spec->multiout.dac_nids = spec->dac_nids;
|
|
|
- stac92xx_enable_eapd(codec);
|
|
|
+ /* GPIO0 High = Enable EAPD */
|
|
|
+ stac92xx_enable_gpio_mask(codec, 0x00000001, 0x00000001);
|
|
|
|
|
|
err = stac92xx_parse_auto_config(codec, 0x1e, 0x20);
|
|
|
if (!err) {
|
|
@@ -2265,7 +2279,7 @@ static int patch_stac927x(struct hda_codec *codec)
|
|
|
static int patch_stac9205(struct hda_codec *codec)
|
|
|
{
|
|
|
struct sigmatel_spec *spec;
|
|
|
- int err;
|
|
|
+ int err, gpio_mask, gpio_data;
|
|
|
|
|
|
spec = kzalloc(sizeof(*spec), GFP_KERNEL);
|
|
|
if (spec == NULL)
|
|
@@ -2302,8 +2316,21 @@ static int patch_stac9205(struct hda_codec *codec)
|
|
|
spec->mixer = stac9205_mixer;
|
|
|
|
|
|
spec->multiout.dac_nids = spec->dac_nids;
|
|
|
- stac92xx_enable_eapd(codec);
|
|
|
+
|
|
|
+ if (spec->board_config == STAC_M43xx) {
|
|
|
+ /* Enable SPDIF in/out */
|
|
|
+ stac92xx_set_config_reg(codec, 0x1f, 0x01441030);
|
|
|
+ stac92xx_set_config_reg(codec, 0x20, 0x1c410030);
|
|
|
+
|
|
|
+ gpio_mask = 0x00000007; /* GPIO0-2 */
|
|
|
+ /* GPIO0 High = EAPD, GPIO1 Low = DRM,
|
|
|
+ * GPIO2 High = Headphone Mute
|
|
|
+ */
|
|
|
+ gpio_data = 0x00000005;
|
|
|
+ } else
|
|
|
+ gpio_mask = gpio_data = 0x00000001; /* GPIO0 High = EAPD */
|
|
|
|
|
|
+ stac92xx_enable_gpio_mask(codec, gpio_mask, gpio_data);
|
|
|
err = stac92xx_parse_auto_config(codec, 0x1f, 0x20);
|
|
|
if (!err) {
|
|
|
if (spec->board_config < 0) {
|