提交 87d48363 编写于 作者: M Matthew Ranostay 提交者: Jaroslav Kysela

[ALSA] hda: Enable SPDIF in/out on some stac9205 boards

Added support for some boards with SPDIF in/out, and cleaned up the GPIO
enable function.
Signed-off-by: NMatthew Ranostay <mranostay@embeddedalley.com>
Signed-off-by: NTakashi Iwai <tiwai@suse.de>
Signed-off-by: NJaroslav Kysela <perex@suse.cz>
上级 7c64ec34
...@@ -44,6 +44,7 @@ enum { ...@@ -44,6 +44,7 @@ enum {
enum { enum {
STAC_9205_REF, STAC_9205_REF,
STAC_M43xx,
STAC_9205_MODELS STAC_9205_MODELS
}; };
...@@ -218,7 +219,6 @@ static hda_nid_t stac9205_pin_nids[12] = { ...@@ -218,7 +219,6 @@ static hda_nid_t stac9205_pin_nids[12] = {
0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
0x0f, 0x14, 0x16, 0x17, 0x18, 0x0f, 0x14, 0x16, 0x17, 0x18,
0x21, 0x22, 0x21, 0x22,
}; };
static int stac92xx_dmux_enum_info(struct snd_kcontrol *kcontrol, static int stac92xx_dmux_enum_info(struct snd_kcontrol *kcontrol,
...@@ -773,7 +773,8 @@ static unsigned int ref9205_pin_configs[12] = { ...@@ -773,7 +773,8 @@ static unsigned int ref9205_pin_configs[12] = {
}; };
static unsigned int *stac9205_brd_tbl[STAC_9205_MODELS] = { 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] = { static const char *stac9205_models[STAC_9205_MODELS] = {
...@@ -784,6 +785,10 @@ static struct snd_pci_quirk stac9205_cfg_tbl[] = { ...@@ -784,6 +785,10 @@ static struct snd_pci_quirk stac9205_cfg_tbl[] = {
/* SigmaTel reference board */ /* SigmaTel reference board */
SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
"DFI LanParty", STAC_9205_REF), "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 */ {} /* terminator */
}; };
...@@ -813,48 +818,56 @@ static int stac92xx_save_bios_config_regs(struct hda_codec *codec) ...@@ -813,48 +818,56 @@ static int stac92xx_save_bios_config_regs(struct hda_codec *codec)
return 0; 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) static void stac92xx_set_config_regs(struct hda_codec *codec)
{ {
int i; int i;
struct sigmatel_spec *spec = codec->spec; struct sigmatel_spec *spec = codec->spec;
unsigned int pin_cfg;
if (! spec->pin_nids || ! spec->pin_configs) if (!spec->pin_configs)
return; return;
for (i = 0; i < spec->num_pins; i++) { for (i = 0; i < spec->num_pins; i++)
snd_hda_codec_write(codec, spec->pin_nids[i], 0, stac92xx_set_config_reg(codec, spec->pin_nids[i],
AC_VERB_SET_CONFIG_DEFAULT_BYTES_0, spec->pin_configs[i]);
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);
}
} }
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, snd_hda_codec_write(codec, codec->afg, 0,
AC_VERB_SET_GPIO_DIRECTION, 0x00000001); AC_VERB_SET_GPIO_DIRECTION, gpio_mask);
/* Configure GPIO0 as CMOS */ /* Configure GPIOx as CMOS */
snd_hda_codec_write(codec, codec->afg, 0, 0x7e7, 0x00000000); snd_hda_codec_write(codec, codec->afg, 0, 0x7e7, 0x00000000);
/* Assert GPIO0 high */ /* Assert GPIOx */
snd_hda_codec_write(codec, codec->afg, 0, snd_hda_codec_write(codec, codec->afg, 0,
AC_VERB_SET_GPIO_DATA, 0x00000001); AC_VERB_SET_GPIO_DATA, gpio_data);
/* Enable GPIO0 */ /* Enable GPIOx */
snd_hda_codec_write(codec, codec->afg, 0, 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) ...@@ -2233,7 +2246,8 @@ static int patch_stac927x(struct hda_codec *codec)
} }
spec->multiout.dac_nids = spec->dac_nids; 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); err = stac92xx_parse_auto_config(codec, 0x1e, 0x20);
if (!err) { if (!err) {
...@@ -2265,7 +2279,7 @@ static int patch_stac927x(struct hda_codec *codec) ...@@ -2265,7 +2279,7 @@ static int patch_stac927x(struct hda_codec *codec)
static int patch_stac9205(struct hda_codec *codec) static int patch_stac9205(struct hda_codec *codec)
{ {
struct sigmatel_spec *spec; struct sigmatel_spec *spec;
int err; int err, gpio_mask, gpio_data;
spec = kzalloc(sizeof(*spec), GFP_KERNEL); spec = kzalloc(sizeof(*spec), GFP_KERNEL);
if (spec == NULL) if (spec == NULL)
...@@ -2302,8 +2316,21 @@ static int patch_stac9205(struct hda_codec *codec) ...@@ -2302,8 +2316,21 @@ static int patch_stac9205(struct hda_codec *codec)
spec->mixer = stac9205_mixer; spec->mixer = stac9205_mixer;
spec->multiout.dac_nids = spec->dac_nids; 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); err = stac92xx_parse_auto_config(codec, 0x1f, 0x20);
if (!err) { if (!err) {
if (spec->board_config < 0) { if (spec->board_config < 0) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册