From 22a27c7f8d0752b38b315d6a192c338d45ea28d5 Mon Sep 17 00:00:00 2001 From: Matt Porter Date: Thu, 6 Jul 2006 18:49:10 +0200 Subject: [ALSA] hda: fix sigmatel 9227/8/9 codec support SigmaTel 9227/8/9 IDs must use the 927x patch. Signed-off-by: Matt Porter Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_sigmatel.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'sound/pci/hda/patch_sigmatel.c') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index ea99083a102..ac96336f348 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -1525,12 +1525,12 @@ struct hda_codec_preset snd_hda_preset_sigmatel[] = { { .id = 0x83847681, .name = "STAC9220D/9223D A2", .patch = patch_stac922x }, { .id = 0x83847682, .name = "STAC9221 A2", .patch = patch_stac922x }, { .id = 0x83847683, .name = "STAC9221D A2", .patch = patch_stac922x }, - { .id = 0x83847618, .name = "STAC9227", .patch = patch_stac922x }, - { .id = 0x83847619, .name = "STAC9227", .patch = patch_stac922x }, - { .id = 0x83847616, .name = "STAC9228", .patch = patch_stac922x }, - { .id = 0x83847617, .name = "STAC9228", .patch = patch_stac922x }, - { .id = 0x83847614, .name = "STAC9229", .patch = patch_stac922x }, - { .id = 0x83847615, .name = "STAC9229", .patch = patch_stac922x }, + { .id = 0x83847618, .name = "STAC9227", .patch = patch_stac927x }, + { .id = 0x83847619, .name = "STAC9227", .patch = patch_stac927x }, + { .id = 0x83847616, .name = "STAC9228", .patch = patch_stac927x }, + { .id = 0x83847617, .name = "STAC9228", .patch = patch_stac927x }, + { .id = 0x83847614, .name = "STAC9229", .patch = patch_stac927x }, + { .id = 0x83847615, .name = "STAC9229", .patch = patch_stac927x }, { .id = 0x83847620, .name = "STAC9274", .patch = patch_stac927x }, { .id = 0x83847621, .name = "STAC9274D", .patch = patch_stac927x }, { .id = 0x83847622, .name = "STAC9273X", .patch = patch_stac927x }, -- cgit v1.2.3 From f3302a59cf6961712658db63b66ea5902c17d5e1 Mon Sep 17 00:00:00 2001 From: Matt Porter Date: Mon, 31 Jul 2006 12:49:34 +0200 Subject: [ALSA] hda: sigmatel 9205 family support Adds support for the '9205 family' which includes some other part numbers but 9205 is the first one. These are 4 channel codecs, some have digital mic capability. Support for the digital mic feature will come later. Signed-off-by: Matt Porter Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_sigmatel.c | 102 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) (limited to 'sound/pci/hda/patch_sigmatel.c') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index ac96336f348..d572f030c3e 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -136,6 +136,14 @@ static hda_nid_t stac927x_mux_nids[3] = { 0x15, 0x16, 0x17 }; +static hda_nid_t stac9205_adc_nids[2] = { + 0x12, 0x13 +}; + +static hda_nid_t stac9205_mux_nids[2] = { + 0x19, 0x1a +}; + static hda_nid_t stac9200_pin_nids[8] = { 0x08, 0x09, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, }; @@ -151,6 +159,13 @@ static hda_nid_t stac927x_pin_nids[14] = { 0x14, 0x21, 0x22, 0x23, }; +static hda_nid_t stac9205_pin_nids[12] = { + 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, + 0x0f, 0x14, 0x16, 0x17, 0x18, + 0x21, 0x22, + +}; + static int stac92xx_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); @@ -214,6 +229,12 @@ static struct hda_verb stac927x_core_init[] = { {} }; +static struct hda_verb stac9205_core_init[] = { + /* set master volume and direct control */ + { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, + {} +}; + static struct snd_kcontrol_new stac9200_mixer[] = { HDA_CODEC_VOLUME("Master Playback Volume", 0xb, 0, HDA_OUTPUT), HDA_CODEC_MUTE("Master Playback Switch", 0xb, 0, HDA_OUTPUT), @@ -277,6 +298,21 @@ static snd_kcontrol_new_t stac927x_mixer[] = { { } /* end */ }; +static snd_kcontrol_new_t stac9205_mixer[] = { + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Input Source", + .count = 1, + .info = stac92xx_mux_enum_info, + .get = stac92xx_mux_enum_get, + .put = stac92xx_mux_enum_put, + }, + HDA_CODEC_VOLUME("InMux Capture Volume", 0x19, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("InVol Capture Volume", 0x1b, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("ADCMux Capture Switch", 0x1d, 0x0, HDA_OUTPUT), + { } /* end */ +}; + static int stac92xx_build_controls(struct hda_codec *codec) { struct sigmatel_spec *spec = codec->spec; @@ -415,6 +451,24 @@ static struct hda_board_config stac927x_cfg_tbl[] = { {} /* terminator */ }; +static unsigned int ref9205_pin_configs[12] = { + 0x40000100, 0x40000100, 0x01016011, 0x01014010, + 0x01813122, 0x01a19021, 0x40000100, 0x40000100, + 0x40000100, 0x40000100, 0x01441030, 0x01c41030 +}; + +static unsigned int *stac9205_brd_tbl[] = { + ref9205_pin_configs, +}; + +static struct hda_board_config stac9205_cfg_tbl[] = { + { .modelname = "ref", + .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2668, /* DFI LanParty */ + .config = STAC_REF }, /* SigmaTel reference board */ + {} /* terminator */ +}; + static void stac92xx_set_config_regs(struct hda_codec *codec) { int i; @@ -1354,6 +1408,46 @@ static int patch_stac927x(struct hda_codec *codec) return 0; } +static int patch_stac9205(struct hda_codec *codec) +{ + struct sigmatel_spec *spec; + int err; + + spec = kzalloc(sizeof(*spec), GFP_KERNEL); + if (spec == NULL) + return -ENOMEM; + + codec->spec = spec; + spec->board_config = snd_hda_check_board_config(codec, stac9205_cfg_tbl); + if (spec->board_config < 0) + snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9205, using BIOS defaults\n"); + else { + spec->num_pins = 14; + spec->pin_nids = stac9205_pin_nids; + spec->pin_configs = stac9205_brd_tbl[spec->board_config]; + stac92xx_set_config_regs(codec); + } + + spec->adc_nids = stac9205_adc_nids; + spec->mux_nids = stac9205_mux_nids; + spec->num_muxes = 3; + + spec->init = stac9205_core_init; + spec->mixer = stac9205_mixer; + + spec->multiout.dac_nids = spec->dac_nids; + + err = stac92xx_parse_auto_config(codec, 0x1f, 0x20); + if (err < 0) { + stac92xx_free(codec); + return err; + } + + codec->patch_ops = stac92xx_patch_ops; + + return 0; +} + /* * STAC 7661(?) hack */ @@ -1542,5 +1636,13 @@ struct hda_codec_preset snd_hda_preset_sigmatel[] = { { .id = 0x83847628, .name = "STAC9274X5NH", .patch = patch_stac927x }, { .id = 0x83847629, .name = "STAC9274D5NH", .patch = patch_stac927x }, { .id = 0x83847661, .name = "STAC7661", .patch = patch_stac7661 }, + { .id = 0x838476a0, .name = "STAC9205", .patch = patch_stac9205 }, + { .id = 0x838476a1, .name = "STAC9205D", .patch = patch_stac9205 }, + { .id = 0x838476a2, .name = "STAC9204", .patch = patch_stac9205 }, + { .id = 0x838476a3, .name = "STAC9204D", .patch = patch_stac9205 }, + { .id = 0x838476a4, .name = "STAC9255", .patch = patch_stac9205 }, + { .id = 0x838476a5, .name = "STAC9255D", .patch = patch_stac9205 }, + { .id = 0x838476a6, .name = "STAC9254", .patch = patch_stac9205 }, + { .id = 0x838476a7, .name = "STAC9254D", .patch = patch_stac9205 }, {} /* terminator */ }; -- cgit v1.2.3 From 99ccc560b73ff7381153dc1391d18391373931d3 Mon Sep 17 00:00:00 2001 From: Guillaume Munch Date: Wed, 16 Aug 2006 19:35:12 +0200 Subject: [ALSA] Add support for Sony Vaio AR 11B This patch adds automatic detection for Sigmatel ID 7664, the sound chip in Sony Vaio AR 11B (european name). - patch_stac7661 becomes patch_stac766x - .id = 0x83847664 is added Signed-off-by: Guillaume Munch Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_sigmatel.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) (limited to 'sound/pci/hda/patch_sigmatel.c') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index d572f030c3e..7eaf755b014 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -1449,10 +1449,10 @@ static int patch_stac9205(struct hda_codec *codec) } /* - * STAC 7661(?) hack + * STAC 7661(?) and 7664 hack */ -/* static config for Sony VAIO FE550G */ +/* static config for Sony VAIO FE550G and Sony VAIO AR */ static hda_nid_t vaio_dacs[] = { 0x2 }; #define VAIO_HP_DAC 0x5 static hda_nid_t vaio_adcs[] = { 0x8 /*,0x6*/ }; @@ -1552,7 +1552,7 @@ static struct snd_kcontrol_new vaio_mixer[] = { {} }; -static struct hda_codec_ops stac7661_patch_ops = { +static struct hda_codec_ops stac766x_patch_ops = { .build_controls = stac92xx_build_controls, .build_pcms = stac92xx_build_pcms, .init = stac92xx_init, @@ -1562,23 +1562,25 @@ static struct hda_codec_ops stac7661_patch_ops = { #endif }; -enum { STAC7661_VAIO }; +enum { STAC766x_VAIO }; -static struct hda_board_config stac7661_cfg_tbl[] = { - { .modelname = "vaio", .config = STAC7661_VAIO }, +static struct hda_board_config stac766x_cfg_tbl[] = { + { .modelname = "vaio", .config = STAC766x_VAIO }, { .pci_subvendor = 0x104d, .pci_subdevice = 0x81e6, - .config = STAC7661_VAIO }, + .config = STAC766x_VAIO }, { .pci_subvendor = 0x104d, .pci_subdevice = 0x81ef, - .config = STAC7661_VAIO }, + .config = STAC766x_VAIO }, + { .pci_subvendor = 0x104d, .pci_subdevice = 0x81fd, + .config = STAC766x_VAIO }, {} }; -static int patch_stac7661(struct hda_codec *codec) +static int patch_stac766x(struct hda_codec *codec) { struct sigmatel_spec *spec; int board_config; - board_config = snd_hda_check_board_config(codec, stac7661_cfg_tbl); + board_config = snd_hda_check_board_config(codec, stac766x_cfg_tbl); if (board_config < 0) /* unknown config, let generic-parser do its job... */ return snd_hda_parse_generic_codec(codec); @@ -1589,7 +1591,7 @@ static int patch_stac7661(struct hda_codec *codec) codec->spec = spec; switch (board_config) { - case STAC7661_VAIO: + case STAC766x_VAIO: spec->mixer = vaio_mixer; spec->init = vaio_init; spec->multiout.max_channels = 2; @@ -1603,7 +1605,7 @@ static int patch_stac7661(struct hda_codec *codec) break; } - codec->patch_ops = stac7661_patch_ops; + codec->patch_ops = stac766x_patch_ops; return 0; } @@ -1635,7 +1637,7 @@ struct hda_codec_preset snd_hda_preset_sigmatel[] = { { .id = 0x83847627, .name = "STAC9271D", .patch = patch_stac927x }, { .id = 0x83847628, .name = "STAC9274X5NH", .patch = patch_stac927x }, { .id = 0x83847629, .name = "STAC9274D5NH", .patch = patch_stac927x }, - { .id = 0x83847661, .name = "STAC7661", .patch = patch_stac7661 }, + { .id = 0x83847661, .name = "STAC7661", .patch = patch_stac766x }, { .id = 0x838476a0, .name = "STAC9205", .patch = patch_stac9205 }, { .id = 0x838476a1, .name = "STAC9205D", .patch = patch_stac9205 }, { .id = 0x838476a2, .name = "STAC9204", .patch = patch_stac9205 }, @@ -1644,5 +1646,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 = 0x83847664, .name = "STAC7664", .patch = patch_stac766x }, {} /* terminator */ }; -- cgit v1.2.3 From c256652466127872f1b2e510431dc25524ba40ba Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 17 Aug 2006 18:21:36 +0200 Subject: [ALSA] Add missing TLV callbacks for HD-audio codecs Added missing TLV callbacks for HD-audio codec supports. Also cleaned up the tlv callback for ad1986a (no mutex is needed there). Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_sigmatel.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound/pci/hda/patch_sigmatel.c') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 7eaf755b014..887b52e96ec 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -1528,6 +1528,7 @@ static struct snd_kcontrol_new vaio_mixer[] = { .info = snd_hda_mixer_amp_volume_info, .get = snd_hda_mixer_amp_volume_get, .put = vaio_master_vol_put, + .tlv = { .c = snd_hda_mixer_amp_tlv }, .private_value = HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), }, { -- cgit v1.2.3 From 68a6abd97f8b9aa072e36b1901531e7bb69b6efc Mon Sep 17 00:00:00 2001 From: Tobin Davis Date: Mon, 21 Aug 2006 19:02:10 +0200 Subject: [ALSA] hda-codec - Fix headphone output for some Intel 945 systems This patch enables headphone output at initialization for Intel 945 based systems that don't have proper detection circuitry. Signed-off-by: Tobin Davis Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_sigmatel.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'sound/pci/hda/patch_sigmatel.c') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 887b52e96ec..d709389c4f6 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -1143,6 +1143,8 @@ static int stac92xx_init(struct hda_codec *codec) STAC_UNSOL_ENABLE); /* fake event to set up pins */ codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26); + /* enable the headphones by default. If/when unsol_event detection works, this will be ignored */ + stac92xx_auto_init_hp_out(codec); } else { stac92xx_auto_init_multi_out(codec); stac92xx_auto_init_hp_out(codec); -- cgit v1.2.3 From 948a4db217235ba51c41d8e7c2ffcf9432e57274 Mon Sep 17 00:00:00 2001 From: Tobin Davis Date: Tue, 22 Aug 2006 19:43:46 +0200 Subject: [ALSA] hda-codec - add missing device ids for Intel 945 boards This patch adds missing device ids for Intel 945 motherboards. Signed-off-by: Tobin Davis Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_sigmatel.c | 66 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 60 insertions(+), 6 deletions(-) (limited to 'sound/pci/hda/patch_sigmatel.c') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index d709389c4f6..7b29288690c 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -396,19 +396,53 @@ static struct hda_board_config stac922x_cfg_tbl[] = { .pci_subvendor = PCI_VENDOR_ID_INTEL, .pci_subdevice = 0x2668, /* DFI LanParty */ .config = STAC_REF }, /* SigmaTel reference board */ + /* Intel 945G based systems */ { .pci_subvendor = PCI_VENDOR_ID_INTEL, .pci_subdevice = 0x0101, .config = STAC_D945GTP3 }, /* Intel D945GTP - 3 Stack */ { .pci_subvendor = PCI_VENDOR_ID_INTEL, .pci_subdevice = 0x0202, - .config = STAC_D945GTP3 }, /* Intel D945GNT - 3 Stack, 9221 A1 */ + .config = STAC_D945GTP3 }, /* Intel D945GNT - 3 Stack */ { .pci_subvendor = PCI_VENDOR_ID_INTEL, - .pci_subdevice = 0x0b0b, - .config = STAC_D945GTP3 }, /* Intel D945PSN - 3 Stack, 9221 A1 */ + .pci_subdevice = 0x0606, + .config = STAC_D945GTP3 }, /* Intel D945GTP - 3 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x0601, + .config = STAC_D945GTP3 }, /* Intel D945GTP - 3 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x0111, + .config = STAC_D945GTP3 }, /* Intel D945GZP - 3 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x1115, + .config = STAC_D945GTP3 }, /* Intel D945GPM - 3 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x1116, + .config = STAC_D945GTP3 }, /* Intel D945GBO - 3 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x1117, + .config = STAC_D945GTP3 }, /* Intel D945GPM - 3 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x1118, + .config = STAC_D945GTP3 }, /* Intel D945GPM - 3 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x1119, + .config = STAC_D945GTP3 }, /* Intel D945GPM - 3 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x8826, + .config = STAC_D945GTP3 }, /* Intel D945GPM - 3 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x5049, + .config = STAC_D945GTP3 }, /* Intel D945GCZ - 3 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x5055, + .config = STAC_D945GTP3 }, /* Intel D945GCZ - 3 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x5048, + .config = STAC_D945GTP3 }, /* Intel D945GPB - 3 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x0110, + .config = STAC_D945GTP3 }, /* Intel D945GLR - 3 Stack */ { .pci_subvendor = PCI_VENDOR_ID_INTEL, - .pci_subdevice = 0x0707, - .config = STAC_D945GTP5 }, /* Intel D945PSV - 5 Stack */ - { .pci_subvendor = PCI_VENDOR_ID_INTEL, .pci_subdevice = 0x0404, .config = STAC_D945GTP5 }, /* Intel D945GTP - 5 Stack */ { .pci_subvendor = PCI_VENDOR_ID_INTEL, @@ -420,6 +454,26 @@ static struct hda_board_config stac922x_cfg_tbl[] = { { .pci_subvendor = PCI_VENDOR_ID_INTEL, .pci_subdevice = 0x0417, .config = STAC_D945GTP5 }, /* Intel D975XBK - 5 Stack */ + /* Intel 945P based systems */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x0b0b, + .config = STAC_D945GTP3 }, /* Intel D945PSN - 3 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x0112, + .config = STAC_D945GTP3 }, /* Intel D945PLN - 3 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x0d0d, + .config = STAC_D945GTP3 }, /* Intel D945PLM - 3 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x0909, + .config = STAC_D945GTP3 }, /* Intel D945PAW - 3 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x0505, + .config = STAC_D945GTP3 }, /* Intel D945PLM - 3 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x0707, + .config = STAC_D945GTP5 }, /* Intel D945PSV - 5 Stack */ + /* other systems */ { .pci_subvendor = 0x8384, .pci_subdevice = 0x7680, .config = STAC_MACMINI }, /* Apple Mac Mini (early 2006) */ -- cgit v1.2.3 From 81d3dbde76eedcd3ede8a73eb72790d67fa254a9 Mon Sep 17 00:00:00 2001 From: Tobin Davis Date: Tue, 22 Aug 2006 19:44:45 +0200 Subject: [ALSA] hda-codec - Add support for new Intel boards with Stac9227 codec This patch adds full 5.1 audio support for Intel boards with the SigmaTel 9227 codec chip (946, 963, 965 series). Signed-off-by: Tobin Davis Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_sigmatel.c | 126 ++++++++++++++++++++++++++++++----------- 1 file changed, 92 insertions(+), 34 deletions(-) (limited to 'sound/pci/hda/patch_sigmatel.c') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 7b29288690c..73ca566e9eb 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -377,18 +377,11 @@ static unsigned int d945gtp5_pin_configs[10] = { 0x02a19320, 0x40000100, }; -static unsigned int d965_2112_pin_configs[10] = { - 0x0221401f, 0x40000100, 0x40000100, 0x01014011, - 0x01a19021, 0x01813024, 0x01452130, 0x40000100, - 0x02a19320, 0x40000100, -}; - static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = { [STAC_REF] = ref922x_pin_configs, [STAC_D945GTP3] = d945gtp3_pin_configs, [STAC_D945GTP5] = d945gtp5_pin_configs, [STAC_MACMINI] = d945gtp5_pin_configs, - [STAC_D965_2112] = d965_2112_pin_configs, }; static struct hda_board_config stac922x_cfg_tbl[] = { @@ -493,8 +486,16 @@ static unsigned int ref927x_pin_configs[14] = { 0x01c41030, 0x40000100, }; +static unsigned int d965_2112_pin_configs[14] = { + 0x0221401f, 0x02a19120, 0x40000100, 0x01014011, + 0x01a19021, 0x01813024, 0x40000100, 0x40000100, + 0x40000100, 0x40000100, 0x40000100, 0x40000100, + 0x40000100, 0x40000100 +}; + static unsigned int *stac927x_brd_tbl[] = { - ref927x_pin_configs, + [STAC_REF] = ref927x_pin_configs, + [STAC_D965_2112] = d965_2112_pin_configs, }; static struct hda_board_config stac927x_cfg_tbl[] = { @@ -502,6 +503,66 @@ static struct hda_board_config stac927x_cfg_tbl[] = { .pci_subvendor = PCI_VENDOR_ID_INTEL, .pci_subdevice = 0x2668, /* DFI LanParty */ .config = STAC_REF }, /* SigmaTel reference board */ + /* SigmaTel 9227 reference board */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x284b, + .config = STAC_D965_284B }, + /* Intel 946 based systems */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x3d01, + .config = STAC_D965_2112 }, /* D946 configuration */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0xa301, + .config = STAC_D965_2112 }, /* Intel D946GZT - 3 stack */ + /* 965 based systems */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2116, + .config = STAC_D965_2112 }, /* Intel D965 3Stack config */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2115, + .config = STAC_D965_2112 }, /* Intel DQ965WC - 3 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2114, + .config = STAC_D965_2112 }, /* Intel D965 3Stack config */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2113, + .config = STAC_D965_2112 }, /* Intel D965 3Stack config */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2112, + .config = STAC_D965_2112 }, /* Intel DG965MS - 3 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2111, + .config = STAC_D965_2112 }, /* Intel D965 3Stack config */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2110, + .config = STAC_D965_2112 }, /* Intel D965 3Stack config */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2009, + .config = STAC_D965_2112 }, /* Intel D965 3Stack config */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2008, + .config = STAC_D965_2112 }, /* Intel DQ965GF - 3 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2007, + .config = STAC_D965_2112 }, /* Intel D965 3Stack config */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2006, + .config = STAC_D965_2112 }, /* Intel D965 3Stack config */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2005, + .config = STAC_D965_2112 }, /* Intel D965 3Stack config */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2004, + .config = STAC_D965_2112 }, /* Intel D965 3Stack config */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2003, + .config = STAC_D965_2112 }, /* Intel D965 3Stack config */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2002, + .config = STAC_D965_2112 }, /* Intel D965 3Stack config */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2001, + .config = STAC_D965_2112 }, /* Intel DQ965GF - 3 Stackg */ {} /* terminator */ }; @@ -1391,25 +1452,6 @@ static int patch_stac922x(struct hda_codec *codec) spec->multiout.dac_nids = spec->dac_nids; - switch (spec->board_config) { - case STAC_D965_2112: - spec->adc_nids = stac9227_adc_nids; - spec->mux_nids = stac9227_mux_nids; -#if 0 - spec->multiout.dac_nids = d965_2112_dac_nids; - spec->multiout.num_dacs = ARRAY_SIZE(d965_2112_dac_nids); -#endif - spec->init = d965_2112_core_init; - spec->mixer = stac9227_mixer; - break; - case STAC_D965_284B: - spec->adc_nids = stac9227_adc_nids; - spec->mux_nids = stac9227_mux_nids; - spec->init = stac9227_core_init; - spec->mixer = stac9227_mixer; - break; - } - err = stac92xx_parse_auto_config(codec, 0x08, 0x09); if (err < 0) { stac92xx_free(codec); @@ -1437,19 +1479,35 @@ static int patch_stac927x(struct hda_codec *codec) spec->board_config = snd_hda_check_board_config(codec, stac927x_cfg_tbl); if (spec->board_config < 0) snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC927x, using BIOS defaults\n"); - else { + else if (stac927x_brd_tbl[spec->board_config] != NULL) { spec->num_pins = 14; spec->pin_nids = stac927x_pin_nids; spec->pin_configs = stac927x_brd_tbl[spec->board_config]; stac92xx_set_config_regs(codec); } - spec->adc_nids = stac927x_adc_nids; - spec->mux_nids = stac927x_mux_nids; - spec->num_muxes = 3; - - spec->init = stac927x_core_init; - spec->mixer = stac927x_mixer; + switch (spec->board_config) { + case STAC_D965_2112: + spec->adc_nids = stac927x_adc_nids; + spec->mux_nids = stac927x_mux_nids; + spec->num_muxes = 3; + spec->init = d965_2112_core_init; + spec->mixer = stac9227_mixer; + break; + case STAC_D965_284B: + spec->adc_nids = stac9227_adc_nids; + spec->mux_nids = stac9227_mux_nids; + spec->num_muxes = 2; + spec->init = stac9227_core_init; + spec->mixer = stac9227_mixer; + break; + default: + spec->adc_nids = stac927x_adc_nids; + spec->mux_nids = stac927x_mux_nids; + spec->num_muxes = 3; + spec->init = stac927x_core_init; + spec->mixer = stac927x_mixer; + } spec->multiout.dac_nids = spec->dac_nids; -- cgit v1.2.3 From 6d8590650eb81d2c869c7adf4b469071cec11eee Mon Sep 17 00:00:00 2001 From: Guillaume Munch Date: Tue, 22 Aug 2006 17:15:47 +0200 Subject: [ALSA] hda-codec - Support for SigmaTel 9872 - AR11M and AR11S uses the same chip hence we claim to support the AR Series. - Added commentary about STAC9225s which shares the same id as CXD9872RD. - Added entry for 7662 but won't work automatically until pci_subdevice is known. - 'vaio' model now corresponds to CXD9872RD_VAIO for backward compat. - Replaced STAC766x_VAIO with CXD9872RD_VAIO, STAC9872AK_VAIO, STAC9872K_VAIO and CXD9872AKD_VAIO - Added 'vaio-ar' model for potential future modifications. Signed-off-by: Guillaume Munch Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_sigmatel.c | 109 +++++++++++++++++++++++++++++++++++------ 1 file changed, 94 insertions(+), 15 deletions(-) (limited to 'sound/pci/hda/patch_sigmatel.c') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 73ca566e9eb..139d73e18a3 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -1563,7 +1563,7 @@ static int patch_stac9205(struct hda_codec *codec) } /* - * STAC 7661(?) and 7664 hack + * STAC9872 hack */ /* static config for Sony VAIO FE550G and Sony VAIO AR */ @@ -1597,6 +1597,23 @@ static struct hda_verb vaio_init[] = { {} }; +static struct hda_verb vaio_ar_init[] = { + {0x0a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP <- 0x2 */ + {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Speaker <- 0x5 */ + {0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? (<- 0x2) */ + {0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD */ +/* {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },*/ /* Optical Out */ + {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? */ + {0x15, AC_VERB_SET_CONNECT_SEL, 0x2}, /* mic-sel: 0a,0d,14,02 */ + {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* HP */ + {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Speaker */ +/* {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},*/ /* Optical Out */ + {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* capture sw/vol -> 0x8 */ + {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, /* CD-in -> 0x6 */ + {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */ + {} +}; + /* bind volumes of both NID 0x02 and 0x05 */ static int vaio_master_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -1667,7 +1684,40 @@ static struct snd_kcontrol_new vaio_mixer[] = { {} }; -static struct hda_codec_ops stac766x_patch_ops = { +static struct snd_kcontrol_new vaio_ar_mixer[] = { + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Master Playback Volume", + .info = snd_hda_mixer_amp_volume_info, + .get = snd_hda_mixer_amp_volume_get, + .put = vaio_master_vol_put, + .private_value = HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Master Playback Switch", + .info = snd_hda_mixer_amp_switch_info, + .get = snd_hda_mixer_amp_switch_get, + .put = vaio_master_sw_put, + .private_value = HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), + }, + /* HDA_CODEC_VOLUME("CD Capture Volume", 0x07, 0, HDA_INPUT), */ + HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT), + HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT), + /*HDA_CODEC_MUTE("Optical Out Switch", 0x10, 0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Optical Out Volume", 0x10, 0, HDA_OUTPUT),*/ + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Capture Source", + .count = 1, + .info = stac92xx_mux_enum_info, + .get = stac92xx_mux_enum_get, + .put = stac92xx_mux_enum_put, + }, + {} +}; + +static struct hda_codec_ops stac9872_patch_ops = { .build_controls = stac92xx_build_controls, .build_pcms = stac92xx_build_pcms, .init = stac92xx_init, @@ -1677,25 +1727,34 @@ static struct hda_codec_ops stac766x_patch_ops = { #endif }; -enum { STAC766x_VAIO }; - -static struct hda_board_config stac766x_cfg_tbl[] = { - { .modelname = "vaio", .config = STAC766x_VAIO }, +enum { /* FE and SZ series. id=0x83847661 and subsys=0x104D0700 or 104D1000. */ + CXD9872RD_VAIO, + /* Unknown. id=0x83847662 and subsys=0x104D1200 or 104D1000. */ + STAC9872AK_VAIO, + /* Unknown. id=0x83847661 and subsys=0x104D1200. */ + STAC9872K_VAIO, + /* AR Series. id=0x83847664 and subsys=104D1300 */ + CXD9872AKD_VAIO + }; + +static struct hda_board_config stac9872_cfg_tbl[] = { + { .modelname = "vaio", .config = CXD9872RD_VAIO }, + { .modelname = "vaio-ar", .config = CXD9872AKD_VAIO }, { .pci_subvendor = 0x104d, .pci_subdevice = 0x81e6, - .config = STAC766x_VAIO }, + .config = CXD9872RD_VAIO }, { .pci_subvendor = 0x104d, .pci_subdevice = 0x81ef, - .config = STAC766x_VAIO }, + .config = CXD9872RD_VAIO }, { .pci_subvendor = 0x104d, .pci_subdevice = 0x81fd, - .config = STAC766x_VAIO }, + .config = CXD9872AKD_VAIO }, {} }; -static int patch_stac766x(struct hda_codec *codec) +static int patch_stac9872(struct hda_codec *codec) { struct sigmatel_spec *spec; int board_config; - board_config = snd_hda_check_board_config(codec, stac766x_cfg_tbl); + board_config = snd_hda_check_board_config(codec, stac9872_cfg_tbl); if (board_config < 0) /* unknown config, let generic-parser do its job... */ return snd_hda_parse_generic_codec(codec); @@ -1706,7 +1765,9 @@ static int patch_stac766x(struct hda_codec *codec) codec->spec = spec; switch (board_config) { - case STAC766x_VAIO: + case CXD9872RD_VAIO: + case STAC9872AK_VAIO: + case STAC9872K_VAIO: spec->mixer = vaio_mixer; spec->init = vaio_init; spec->multiout.max_channels = 2; @@ -1718,9 +1779,22 @@ static int patch_stac766x(struct hda_codec *codec) spec->input_mux = &vaio_mux; spec->mux_nids = vaio_mux_nids; break; + + case CXD9872AKD_VAIO: + spec->mixer = vaio_ar_mixer; + spec->init = vaio_ar_init; + spec->multiout.max_channels = 2; + spec->multiout.num_dacs = ARRAY_SIZE(vaio_dacs); + spec->multiout.dac_nids = vaio_dacs; + spec->multiout.hp_nid = VAIO_HP_DAC; + spec->num_adcs = ARRAY_SIZE(vaio_adcs); + spec->adc_nids = vaio_adcs; + spec->input_mux = &vaio_mux; + spec->mux_nids = vaio_mux_nids; + break; } - codec->patch_ops = stac766x_patch_ops; + codec->patch_ops = stac9872_patch_ops; return 0; } @@ -1752,7 +1826,13 @@ struct hda_codec_preset snd_hda_preset_sigmatel[] = { { .id = 0x83847627, .name = "STAC9271D", .patch = patch_stac927x }, { .id = 0x83847628, .name = "STAC9274X5NH", .patch = patch_stac927x }, { .id = 0x83847629, .name = "STAC9274D5NH", .patch = patch_stac927x }, - { .id = 0x83847661, .name = "STAC7661", .patch = patch_stac766x }, + /* The following does not take into account .id=0x83847661 when subsys = + * 104D0C00 which is STAC9225s. Because of this, some SZ Notebooks are + * currently not fully supported. + */ + { .id = 0x83847661, .name = "CXD9872RD/K", .patch = patch_stac9872 }, + { .id = 0x83847662, .name = "STAC9872AK", .patch = patch_stac9872 }, + { .id = 0x83847664, .name = "CXD9872AKD", .patch = patch_stac9872 }, { .id = 0x838476a0, .name = "STAC9205", .patch = patch_stac9205 }, { .id = 0x838476a1, .name = "STAC9205D", .patch = patch_stac9205 }, { .id = 0x838476a2, .name = "STAC9204", .patch = patch_stac9205 }, @@ -1761,6 +1841,5 @@ 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 = 0x83847664, .name = "STAC7664", .patch = patch_stac766x }, {} /* terminator */ }; -- cgit v1.2.3 From 11b44bbde52b6c50ed8c9ba579d7ee9ff5b48cd8 Mon Sep 17 00:00:00 2001 From: Richard Fish Date: Wed, 23 Aug 2006 18:31:34 +0200 Subject: [ALSA] hda-codec - restore HDA sigmatel pin configs on resume This patch restores the Intel HDA Sigmatel codec pin configuration on resume. Most of it is dedicated to saving the BIOS pin configuration if necessary, so that even unrecognized chips can be resumed correctly. Signed-off-by: Richard Fish Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_sigmatel.c | 100 ++++++++++++++++++++++++++++++++--------- 1 file changed, 79 insertions(+), 21 deletions(-) (limited to 'sound/pci/hda/patch_sigmatel.c') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 139d73e18a3..239ae3fad05 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -73,6 +73,7 @@ struct sigmatel_spec { hda_nid_t *pin_nids; unsigned int num_pins; unsigned int *pin_configs; + unsigned int *bios_pin_configs; /* codec specific stuff */ struct hda_verb *init; @@ -584,13 +585,42 @@ static struct hda_board_config stac9205_cfg_tbl[] = { {} /* terminator */ }; +static int stac92xx_save_bios_config_regs(struct hda_codec *codec) +{ + int i; + struct sigmatel_spec *spec = codec->spec; + + if (! spec->bios_pin_configs) { + spec->bios_pin_configs = kcalloc(spec->num_pins, + sizeof(*spec->bios_pin_configs), GFP_KERNEL); + if (! spec->bios_pin_configs) + return -ENOMEM; + } + + for (i = 0; i < spec->num_pins; i++) { + hda_nid_t nid = spec->pin_nids[i]; + unsigned int pin_cfg; + + pin_cfg = snd_hda_codec_read(codec, nid, 0, + AC_VERB_GET_CONFIG_DEFAULT, 0x00); + snd_printdd(KERN_INFO "hda_codec: pin nid %2.2x bios pin config %8.8x\n", + nid, pin_cfg); + spec->bios_pin_configs[i] = pin_cfg; + } + + return 0; +} + static void stac92xx_set_config_regs(struct hda_codec *codec) { int i; struct sigmatel_spec *spec = codec->spec; unsigned int pin_cfg; - for (i=0; i < spec->num_pins; i++) { + if (! spec->pin_nids || ! 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); @@ -1302,6 +1332,9 @@ static void stac92xx_free(struct hda_codec *codec) kfree(spec->kctl_alloc); } + if (spec->bios_pin_configs) + kfree(spec->bios_pin_configs); + kfree(spec); } @@ -1359,6 +1392,7 @@ static int stac92xx_resume(struct hda_codec *codec) int i; stac92xx_init(codec); + stac92xx_set_config_regs(codec); for (i = 0; i < spec->num_mixers; i++) snd_hda_resume_ctls(codec, spec->mixers[i]); if (spec->multiout.dig_out_nid) @@ -1391,12 +1425,18 @@ static int patch_stac9200(struct hda_codec *codec) return -ENOMEM; codec->spec = spec; + spec->num_pins = 8; + spec->pin_nids = stac9200_pin_nids; spec->board_config = snd_hda_check_board_config(codec, stac9200_cfg_tbl); - if (spec->board_config < 0) - snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9200, using BIOS defaults\n"); - else { - spec->num_pins = 8; - spec->pin_nids = stac9200_pin_nids; + if (spec->board_config < 0) { + snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9200, 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 = stac9200_brd_tbl[spec->board_config]; stac92xx_set_config_regs(codec); } @@ -1432,13 +1472,19 @@ static int patch_stac922x(struct hda_codec *codec) return -ENOMEM; codec->spec = spec; + spec->num_pins = 10; + spec->pin_nids = stac922x_pin_nids; spec->board_config = snd_hda_check_board_config(codec, stac922x_cfg_tbl); - if (spec->board_config < 0) - snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC922x, " - "using BIOS defaults\n"); - else if (stac922x_brd_tbl[spec->board_config] != NULL) { - spec->num_pins = 10; - spec->pin_nids = stac922x_pin_nids; + if (spec->board_config < 0) { + snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC922x, " + "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 if (stac922x_brd_tbl[spec->board_config] != NULL) { spec->pin_configs = stac922x_brd_tbl[spec->board_config]; stac92xx_set_config_regs(codec); } @@ -1476,12 +1522,18 @@ static int patch_stac927x(struct hda_codec *codec) return -ENOMEM; codec->spec = spec; + spec->num_pins = 14; + spec->pin_nids = stac927x_pin_nids; spec->board_config = snd_hda_check_board_config(codec, stac927x_cfg_tbl); - if (spec->board_config < 0) + if (spec->board_config < 0) { snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC927x, using BIOS defaults\n"); - else if (stac927x_brd_tbl[spec->board_config] != NULL) { - spec->num_pins = 14; - spec->pin_nids = stac927x_pin_nids; + err = stac92xx_save_bios_config_regs(codec); + if (err < 0) { + stac92xx_free(codec); + return err; + } + spec->pin_configs = spec->bios_pin_configs; + } else if (stac927x_brd_tbl[spec->board_config] != NULL) { spec->pin_configs = stac927x_brd_tbl[spec->board_config]; stac92xx_set_config_regs(codec); } @@ -1532,12 +1584,18 @@ static int patch_stac9205(struct hda_codec *codec) return -ENOMEM; codec->spec = spec; + spec->num_pins = 14; + spec->pin_nids = stac9205_pin_nids; spec->board_config = snd_hda_check_board_config(codec, stac9205_cfg_tbl); - if (spec->board_config < 0) - snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9205, using BIOS defaults\n"); - else { - spec->num_pins = 14; - spec->pin_nids = stac9205_pin_nids; + if (spec->board_config < 0) { + snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9205, 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 = stac9205_brd_tbl[spec->board_config]; stac92xx_set_config_regs(codec); } -- cgit v1.2.3 From 2c7782b420ee137057eeec7c24a565ac85fc1988 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 25 Aug 2006 13:11:26 +0200 Subject: [ALSA] hda-codec - Use model=ref for some Dell laptops Force to choose model=ref for some Dell laptops with STAC9200 codec chip for fixing the silent mic recording problem (possibly due to a BIOS bug). Reference: ALSA bug#2038 So far, applied to Inspiron 630m, Latitude D620 and 120L. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_sigmatel.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'sound/pci/hda/patch_sigmatel.c') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 239ae3fad05..8d5ad7c0db0 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -582,6 +582,13 @@ static struct hda_board_config stac9205_cfg_tbl[] = { .pci_subvendor = PCI_VENDOR_ID_INTEL, .pci_subdevice = 0x2668, /* DFI LanParty */ .config = STAC_REF }, /* SigmaTel reference board */ + /* Dell laptops have BIOS problem */ + { .pci_subvendor = PCI_VENDOR_ID_DELL, .pci_subdevice = 0x01b5, + .config = STAC_REF }, /* Dell Inspiron 630m */ + { .pci_subvendor = PCI_VENDOR_ID_DELL, .pci_subdevice = 0x01c2, + .config = STAC_REF }, /* Dell Latitude D620 */ + { .pci_subvendor = PCI_VENDOR_ID_DELL, .pci_subdevice = 0x01cb, + .config = STAC_REF }, /* Dell Latitude 120L */ {} /* terminator */ }; -- cgit v1.2.3 From 93ed150375187ae7917ed1e3b9b830b9d4065bad Mon Sep 17 00:00:00 2001 From: Tobin Davis Date: Fri, 1 Sep 2006 21:03:12 +0200 Subject: [ALSA] hda-codec - Add 5 stack audio support for Intel 965 systems This patch renames the 965_2112 function ids to 965_3ST, and adds functional support for 965_5ST (5 stack 7.1 surround). Signed-off-by: Tobin Davis Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_sigmatel.c | 152 ++++++++++++++++++++++------------------- 1 file changed, 81 insertions(+), 71 deletions(-) (limited to 'sound/pci/hda/patch_sigmatel.c') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 8d5ad7c0db0..87169032be1 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -42,9 +42,10 @@ #define STAC_D945GTP3 1 #define STAC_D945GTP5 2 #define STAC_MACMINI 3 -#define STAC_D965_2112 4 -#define STAC_D965_284B 5 -#define STAC_922X_MODELS 6 /* number of 922x models */ +#define STAC_922X_MODELS 4 /* number of 922x models */ +#define STAC_D965_3ST 4 +#define STAC_D965_5ST 5 +#define STAC_927X_MODELS 6 /* number of 922x models */ struct sigmatel_spec { struct snd_kcontrol_new *mixers[4]; @@ -111,24 +112,10 @@ static hda_nid_t stac922x_adc_nids[2] = { 0x06, 0x07, }; -static hda_nid_t stac9227_adc_nids[2] = { - 0x07, 0x08, -}; - -#if 0 -static hda_nid_t d965_2112_dac_nids[3] = { - 0x02, 0x03, 0x05, -}; -#endif - static hda_nid_t stac922x_mux_nids[2] = { 0x12, 0x13, }; -static hda_nid_t stac9227_mux_nids[2] = { - 0x15, 0x16, -}; - static hda_nid_t stac927x_adc_nids[3] = { 0x07, 0x08, 0x09 }; @@ -146,7 +133,8 @@ static hda_nid_t stac9205_mux_nids[2] = { }; static hda_nid_t stac9200_pin_nids[8] = { - 0x08, 0x09, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, + 0x08, 0x09, 0x0d, 0x0e, + 0x0f, 0x10, 0x11, 0x12, }; static hda_nid_t stac922x_pin_nids[10] = { @@ -206,17 +194,9 @@ static struct hda_verb stac922x_core_init[] = { {} }; -static struct hda_verb stac9227_core_init[] = { - /* set master volume and direct control */ - { 0x16, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, - /* unmute node 0x1b */ - { 0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, - {} -}; - -static struct hda_verb d965_2112_core_init[] = { +static struct hda_verb d965_core_init[] = { /* set master volume and direct control */ - { 0x16, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, + { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, /* unmute node 0x1b */ { 0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, /* select node 0x03 as DAC */ @@ -386,6 +366,8 @@ static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = { }; static struct hda_board_config stac922x_cfg_tbl[] = { + { .modelname = "5stack", .config = STAC_D945GTP5 }, + { .modelname = "3stack", .config = STAC_D945GTP3 }, { .modelname = "ref", .pci_subvendor = PCI_VENDOR_ID_INTEL, .pci_subdevice = 0x2668, /* DFI LanParty */ @@ -471,99 +453,127 @@ static struct hda_board_config stac922x_cfg_tbl[] = { { .pci_subvendor = 0x8384, .pci_subdevice = 0x7680, .config = STAC_MACMINI }, /* Apple Mac Mini (early 2006) */ - { .pci_subvendor = PCI_VENDOR_ID_INTEL, - .pci_subdevice = 0x2112, - .config = STAC_D965_2112 }, - { .pci_subvendor = PCI_VENDOR_ID_INTEL, - .pci_subdevice = 0x284b, - .config = STAC_D965_284B }, {} /* terminator */ }; static unsigned int ref927x_pin_configs[14] = { - 0x01813122, 0x01a19021, 0x01014010, 0x01016011, - 0x01012012, 0x01011014, 0x40000100, 0x40000100, - 0x40000100, 0x40000100, 0x40000100, 0x01441030, - 0x01c41030, 0x40000100, + 0x02214020, 0x02a19080, 0x0181304e, 0x01014010, + 0x01a19040, 0x01011012, 0x01016011, 0x0101201f, + 0x183301f0, 0x18a001f0, 0x18a001f0, 0x01442070, + 0x01c42190, 0x40000100, }; -static unsigned int d965_2112_pin_configs[14] = { +static unsigned int d965_3st_pin_configs[14] = { 0x0221401f, 0x02a19120, 0x40000100, 0x01014011, 0x01a19021, 0x01813024, 0x40000100, 0x40000100, 0x40000100, 0x40000100, 0x40000100, 0x40000100, 0x40000100, 0x40000100 }; -static unsigned int *stac927x_brd_tbl[] = { +static unsigned int d965_5st_pin_configs[14] = { + 0x02214020, 0x02a19080, 0x0181304e, 0x01014010, + 0x01a19040, 0x01011012, 0x01016011, 0x40000100, + 0x40000100, 0x40000100, 0x40000100, 0x01442070, + 0x40000100, 0x40000100 +}; + +static unsigned int *stac927x_brd_tbl[STAC_927X_MODELS] = { [STAC_REF] = ref927x_pin_configs, - [STAC_D965_2112] = d965_2112_pin_configs, + [STAC_D965_3ST] = d965_3st_pin_configs, + [STAC_D965_5ST] = d965_5st_pin_configs, }; static struct hda_board_config stac927x_cfg_tbl[] = { + { .modelname = "5stack", .config = STAC_D965_5ST }, + { .modelname = "3stack", .config = STAC_D965_3ST }, { .modelname = "ref", .pci_subvendor = PCI_VENDOR_ID_INTEL, .pci_subdevice = 0x2668, /* DFI LanParty */ .config = STAC_REF }, /* SigmaTel reference board */ - /* SigmaTel 9227 reference board */ - { .pci_subvendor = PCI_VENDOR_ID_INTEL, - .pci_subdevice = 0x284b, - .config = STAC_D965_284B }, /* Intel 946 based systems */ { .pci_subvendor = PCI_VENDOR_ID_INTEL, .pci_subdevice = 0x3d01, - .config = STAC_D965_2112 }, /* D946 configuration */ + .config = STAC_D965_3ST }, /* D946 configuration */ { .pci_subvendor = PCI_VENDOR_ID_INTEL, .pci_subdevice = 0xa301, - .config = STAC_D965_2112 }, /* Intel D946GZT - 3 stack */ - /* 965 based systems */ + .config = STAC_D965_3ST }, /* Intel D946GZT - 3 stack */ + /* 965 based 3 stack systems */ { .pci_subvendor = PCI_VENDOR_ID_INTEL, .pci_subdevice = 0x2116, - .config = STAC_D965_2112 }, /* Intel D965 3Stack config */ + .config = STAC_D965_3ST }, /* Intel D965 3Stack config */ { .pci_subvendor = PCI_VENDOR_ID_INTEL, .pci_subdevice = 0x2115, - .config = STAC_D965_2112 }, /* Intel DQ965WC - 3 Stack */ + .config = STAC_D965_3ST }, /* Intel DQ965WC - 3 Stack */ { .pci_subvendor = PCI_VENDOR_ID_INTEL, .pci_subdevice = 0x2114, - .config = STAC_D965_2112 }, /* Intel D965 3Stack config */ + .config = STAC_D965_3ST }, /* Intel D965 3Stack config */ { .pci_subvendor = PCI_VENDOR_ID_INTEL, .pci_subdevice = 0x2113, - .config = STAC_D965_2112 }, /* Intel D965 3Stack config */ + .config = STAC_D965_3ST }, /* Intel D965 3Stack config */ { .pci_subvendor = PCI_VENDOR_ID_INTEL, .pci_subdevice = 0x2112, - .config = STAC_D965_2112 }, /* Intel DG965MS - 3 Stack */ + .config = STAC_D965_3ST }, /* Intel DG965MS - 3 Stack */ { .pci_subvendor = PCI_VENDOR_ID_INTEL, .pci_subdevice = 0x2111, - .config = STAC_D965_2112 }, /* Intel D965 3Stack config */ + .config = STAC_D965_3ST }, /* Intel D965 3Stack config */ { .pci_subvendor = PCI_VENDOR_ID_INTEL, .pci_subdevice = 0x2110, - .config = STAC_D965_2112 }, /* Intel D965 3Stack config */ + .config = STAC_D965_3ST }, /* Intel D965 3Stack config */ { .pci_subvendor = PCI_VENDOR_ID_INTEL, .pci_subdevice = 0x2009, - .config = STAC_D965_2112 }, /* Intel D965 3Stack config */ + .config = STAC_D965_3ST }, /* Intel D965 3Stack config */ { .pci_subvendor = PCI_VENDOR_ID_INTEL, .pci_subdevice = 0x2008, - .config = STAC_D965_2112 }, /* Intel DQ965GF - 3 Stack */ + .config = STAC_D965_3ST }, /* Intel DQ965GF - 3 Stack */ { .pci_subvendor = PCI_VENDOR_ID_INTEL, .pci_subdevice = 0x2007, - .config = STAC_D965_2112 }, /* Intel D965 3Stack config */ + .config = STAC_D965_3ST }, /* Intel D965 3Stack config */ { .pci_subvendor = PCI_VENDOR_ID_INTEL, .pci_subdevice = 0x2006, - .config = STAC_D965_2112 }, /* Intel D965 3Stack config */ + .config = STAC_D965_3ST }, /* Intel D965 3Stack config */ { .pci_subvendor = PCI_VENDOR_ID_INTEL, .pci_subdevice = 0x2005, - .config = STAC_D965_2112 }, /* Intel D965 3Stack config */ + .config = STAC_D965_3ST }, /* Intel D965 3Stack config */ { .pci_subvendor = PCI_VENDOR_ID_INTEL, .pci_subdevice = 0x2004, - .config = STAC_D965_2112 }, /* Intel D965 3Stack config */ + .config = STAC_D965_3ST }, /* Intel D965 3Stack config */ { .pci_subvendor = PCI_VENDOR_ID_INTEL, .pci_subdevice = 0x2003, - .config = STAC_D965_2112 }, /* Intel D965 3Stack config */ + .config = STAC_D965_3ST }, /* Intel D965 3Stack config */ { .pci_subvendor = PCI_VENDOR_ID_INTEL, .pci_subdevice = 0x2002, - .config = STAC_D965_2112 }, /* Intel D965 3Stack config */ + .config = STAC_D965_3ST }, /* Intel D965 3Stack config */ { .pci_subvendor = PCI_VENDOR_ID_INTEL, .pci_subdevice = 0x2001, - .config = STAC_D965_2112 }, /* Intel DQ965GF - 3 Stackg */ + .config = STAC_D965_3ST }, /* Intel DQ965GF - 3 Stack */ + /* 965 based 5 stack systems */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2301, + .config = STAC_D965_5ST }, /* Intel DG965 - 5 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2302, + .config = STAC_D965_5ST }, /* Intel DG965 - 5 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2303, + .config = STAC_D965_5ST }, /* Intel DG965 - 5 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2304, + .config = STAC_D965_5ST }, /* Intel DG965 - 5 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2305, + .config = STAC_D965_5ST }, /* Intel DG965 - 5 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2501, + .config = STAC_D965_5ST }, /* Intel DG965MQ - 5 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2502, + .config = STAC_D965_5ST }, /* Intel DG965 - 5 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2503, + .config = STAC_D965_5ST }, /* Intel DG965 - 5 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2504, + .config = STAC_D965_5ST }, /* Intel DQ965GF - 5 Stack */ {} /* terminator */ }; @@ -1546,18 +1556,18 @@ static int patch_stac927x(struct hda_codec *codec) } switch (spec->board_config) { - case STAC_D965_2112: + case STAC_D965_3ST: spec->adc_nids = stac927x_adc_nids; spec->mux_nids = stac927x_mux_nids; spec->num_muxes = 3; - spec->init = d965_2112_core_init; + spec->init = d965_core_init; spec->mixer = stac9227_mixer; break; - case STAC_D965_284B: - spec->adc_nids = stac9227_adc_nids; - spec->mux_nids = stac9227_mux_nids; - spec->num_muxes = 2; - spec->init = stac9227_core_init; + case STAC_D965_5ST: + spec->adc_nids = stac927x_adc_nids; + spec->mux_nids = stac927x_mux_nids; + spec->num_muxes = 3; + spec->init = d965_core_init; spec->mixer = stac9227_mixer; break; default: -- cgit v1.2.3 From 160ea0dc6b86e2c0c4d325c06bf402bfdde7c1c7 Mon Sep 17 00:00:00 2001 From: Richard Fish Date: Wed, 6 Sep 2006 13:58:25 +0200 Subject: [ALSA] [snd-intel-hda] enable center/LFE speaker on some laptops This patch adds LFE mixer controls for laptops with a stac9200 and a mono speaker pin with amplifier. Signed-off-by: Richard Fish Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_sigmatel.c | 63 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) (limited to 'sound/pci/hda/patch_sigmatel.c') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 87169032be1..bcbbe111ab9 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -1223,6 +1223,66 @@ static int stac9200_auto_create_hp_ctls(struct hda_codec *codec, return 0; } +/* add playback controls for LFE output */ +static int stac9200_auto_create_lfe_ctls(struct hda_codec *codec, + struct auto_pin_cfg *cfg) +{ + struct sigmatel_spec *spec = codec->spec; + int err; + hda_nid_t lfe_pin = 0x0; + int i; + + /* + * search speaker outs and line outs for a mono speaker pin + * with an amp. If one is found, add LFE controls + * for it. + */ + for (i = 0; i < spec->autocfg.speaker_outs && lfe_pin == 0x0; i++) { + hda_nid_t pin = spec->autocfg.speaker_pins[i]; + unsigned long wcaps = get_wcaps(codec, pin); + wcaps &= (AC_WCAP_STEREO | AC_WCAP_OUT_AMP); + if (wcaps == AC_WCAP_OUT_AMP) + /* found a mono speaker with an amp, must be lfe */ + lfe_pin = pin; + } + + /* if speaker_outs is 0, then speakers may be in line_outs */ + if (lfe_pin == 0 && spec->autocfg.speaker_outs == 0) { + for (i = 0; i < spec->autocfg.line_outs && lfe_pin == 0x0; i++) { + hda_nid_t pin = spec->autocfg.line_out_pins[i]; + unsigned long cfg; + cfg = snd_hda_codec_read(codec, pin, 0, + AC_VERB_GET_CONFIG_DEFAULT, + 0x00); + if (get_defcfg_device(cfg) == AC_JACK_SPEAKER) { + unsigned long wcaps = get_wcaps(codec, pin); + wcaps &= (AC_WCAP_STEREO | AC_WCAP_OUT_AMP); + if (wcaps == AC_WCAP_OUT_AMP) + /* found a mono speaker with an amp, + must be lfe */ + lfe_pin = pin; + } + } + } + + if (lfe_pin) { + err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL, + "LFE Playback Volume", + HDA_COMPOSE_AMP_VAL(lfe_pin, 1, 0, + HDA_OUTPUT)); + if (err < 0) + return err; + err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE, + "LFE Playback Switch", + HDA_COMPOSE_AMP_VAL(lfe_pin, 1, 0, + HDA_OUTPUT)); + if (err < 0) + return err; + } + + return 0; +} + static int stac9200_parse_auto_config(struct hda_codec *codec) { struct sigmatel_spec *spec = codec->spec; @@ -1237,6 +1297,9 @@ static int stac9200_parse_auto_config(struct hda_codec *codec) if ((err = stac9200_auto_create_hp_ctls(codec, &spec->autocfg)) < 0) return err; + if ((err = stac9200_auto_create_lfe_ctls(codec, &spec->autocfg)) < 0) + return err; + if (spec->autocfg.dig_out_pin) spec->multiout.dig_out_nid = 0x05; if (spec->autocfg.dig_in_pin) -- cgit v1.2.3 From eb06ed8f4c2440558ebf465e8baeac6367d90201 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 20 Sep 2006 17:10:27 +0200 Subject: [ALSA] hda-codec - Support multiple headphone pins Some machines have multiple headpohne pins (usually on the lpatop and on the docking station) while the current hda-codec driver assumes a single headphone pin. Now it supports multiple hp pins (at least for detection). The sigmatel 92xx code supports this new multiple hp pins. It detects all hp pins for auto-muting, too. Also, the driver checks speaker pins in addition. In some cases, all line-out, speaker and hp-pins coexist. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_sigmatel.c | 202 +++++++++++++++++++++++++++-------------- 1 file changed, 136 insertions(+), 66 deletions(-) (limited to 'sound/pci/hda/patch_sigmatel.c') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index bcbbe111ab9..7cc06426520 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -1011,11 +1011,29 @@ static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec, return 0; } +/* create volume control/switch for the given prefx type */ +static int create_controls(struct sigmatel_spec *spec, const char *pfx, hda_nid_t nid, int chs) +{ + char name[32]; + int err; + + sprintf(name, "%s Playback Volume", pfx); + err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL, name, + HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT)); + if (err < 0) + return err; + sprintf(name, "%s Playback Switch", pfx); + err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE, name, + HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT)); + if (err < 0) + return err; + return 0; +} + /* add playback controls from the parsed DAC table */ static int stac92xx_auto_create_multi_out_ctls(struct sigmatel_spec *spec, const struct auto_pin_cfg *cfg) { - char name[32]; static const char *chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" }; @@ -1030,26 +1048,15 @@ static int stac92xx_auto_create_multi_out_ctls(struct sigmatel_spec *spec, if (i == 2) { /* Center/LFE */ - if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL, "Center Playback Volume", - HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT))) < 0) + err = create_controls(spec, "Center", nid, 1); + if (err < 0) return err; - if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL, "LFE Playback Volume", - HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0) - return err; - if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE, "Center Playback Switch", - HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT))) < 0) - return err; - if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE, "LFE Playback Switch", - HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0) + err = create_controls(spec, "LFE", nid, 2); + if (err < 0) return err; } else { - sprintf(name, "%s Playback Volume", chname[i]); - if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL, name, - HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) - return err; - sprintf(name, "%s Playback Switch", chname[i]); - if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE, name, - HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) + err = create_controls(spec, chname[i], nid, 3); + if (err < 0) return err; } } @@ -1065,39 +1072,85 @@ static int stac92xx_auto_create_multi_out_ctls(struct sigmatel_spec *spec, return 0; } -/* add playback controls for HP output */ -static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec, struct auto_pin_cfg *cfg) +static int check_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid) { - struct sigmatel_spec *spec = codec->spec; - hda_nid_t pin = cfg->hp_pin; - hda_nid_t nid; - int i, err; - unsigned int wid_caps; + int i; - if (! pin) - return 0; + for (i = 0; i < spec->multiout.num_dacs; i++) { + if (spec->multiout.dac_nids[i] == nid) + return 1; + } + if (spec->multiout.hp_nid == nid) + return 1; + return 0; +} - wid_caps = get_wcaps(codec, pin); - if (wid_caps & AC_WCAP_UNSOL_CAP) - spec->hp_detect = 1; +static int add_spec_dacs(struct sigmatel_spec *spec, hda_nid_t nid) +{ + if (!spec->multiout.hp_nid) + spec->multiout.hp_nid = nid; + else if (spec->multiout.num_dacs > 4) { + printk(KERN_WARNING "stac92xx: No space for DAC 0x%x\n", nid); + return 1; + } else { + spec->multiout.dac_nids[spec->multiout.num_dacs] = nid; + spec->multiout.num_dacs++; + } + return 0; +} - nid = snd_hda_codec_read(codec, pin, 0, AC_VERB_GET_CONNECT_LIST, 0) & 0xff; - for (i = 0; i < cfg->line_outs; i++) { - if (! spec->multiout.dac_nids[i]) +/* add playback controls for Speaker and HP outputs */ +static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec, + struct auto_pin_cfg *cfg) +{ + struct sigmatel_spec *spec = codec->spec; + hda_nid_t nid; + int i, old_num_dacs, err; + + old_num_dacs = spec->multiout.num_dacs; + for (i = 0; i < cfg->hp_outs; i++) { + unsigned int wid_caps = get_wcaps(codec, cfg->hp_pins[i]); + if (wid_caps & AC_WCAP_UNSOL_CAP) + spec->hp_detect = 1; + nid = snd_hda_codec_read(codec, cfg->hp_pins[i], 0, + AC_VERB_GET_CONNECT_LIST, 0) & 0xff; + if (check_in_dac_nids(spec, nid)) + nid = 0; + if (! nid) continue; - if (spec->multiout.dac_nids[i] == nid) - return 0; + add_spec_dacs(spec, nid); + } + for (i = 0; i < cfg->speaker_outs; i++) { + nid = snd_hda_codec_read(codec, cfg->speaker_pins[0], 0, + AC_VERB_GET_CONNECT_LIST, 0) & 0xff; + if (check_in_dac_nids(spec, nid)) + nid = 0; + if (check_in_dac_nids(spec, nid)) + nid = 0; + if (! nid) + continue; + add_spec_dacs(spec, nid); } - spec->multiout.hp_nid = nid; - - /* control HP volume/switch on the output mixer amp */ - if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL, "Headphone Playback Volume", - HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) - return err; - if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE, "Headphone Playback Switch", - HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) - return err; + for (i = old_num_dacs; i < spec->multiout.num_dacs; i++) { + static const char *pfxs[] = { + "Speaker", "External Speaker", "Speaker2", + }; + err = create_controls(spec, pfxs[i - old_num_dacs], + spec->multiout.dac_nids[i], 3); + if (err < 0) + return err; + } + if (spec->multiout.hp_nid) { + const char *pfx; + if (old_num_dacs == spec->multiout.num_dacs) + pfx = "Master"; + else + pfx = "Headphone"; + err = create_controls(spec, pfx, spec->multiout.hp_nid, 3); + if (err < 0) + return err; + } return 0; } @@ -1160,11 +1213,20 @@ static void stac92xx_auto_init_multi_out(struct hda_codec *codec) static void stac92xx_auto_init_hp_out(struct hda_codec *codec) { struct sigmatel_spec *spec = codec->spec; - hda_nid_t pin; + int i; - pin = spec->autocfg.hp_pin; - if (pin) /* connect to front */ - stac92xx_auto_set_pinctl(codec, pin, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN); + for (i = 0; i < spec->autocfg.hp_outs; i++) { + hda_nid_t pin; + pin = spec->autocfg.hp_pins[i]; + if (pin) /* connect to front */ + stac92xx_auto_set_pinctl(codec, pin, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN); + } + for (i = 0; i < spec->autocfg.speaker_outs; i++) { + hda_nid_t pin; + pin = spec->autocfg.speaker_pins[i]; + if (pin) /* connect to front */ + stac92xx_auto_set_pinctl(codec, pin, AC_PINCTL_OUT_EN); + } } static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out, hda_nid_t dig_in) @@ -1210,7 +1272,7 @@ static int stac9200_auto_create_hp_ctls(struct hda_codec *codec, struct auto_pin_cfg *cfg) { struct sigmatel_spec *spec = codec->spec; - hda_nid_t pin = cfg->hp_pin; + hda_nid_t pin = cfg->hp_pins[0]; unsigned int wid_caps; if (! pin) @@ -1266,16 +1328,7 @@ static int stac9200_auto_create_lfe_ctls(struct hda_codec *codec, } if (lfe_pin) { - err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL, - "LFE Playback Volume", - HDA_COMPOSE_AMP_VAL(lfe_pin, 1, 0, - HDA_OUTPUT)); - if (err < 0) - return err; - err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE, - "LFE Playback Switch", - HDA_COMPOSE_AMP_VAL(lfe_pin, 1, 0, - HDA_OUTPUT)); + err = create_controls(spec, "LFE", lfe_pin, 1); if (err < 0) return err; } @@ -1363,9 +1416,11 @@ static int stac92xx_init(struct hda_codec *codec) /* set up pins */ if (spec->hp_detect) { /* Enable unsolicited responses on the HP widget */ - snd_hda_codec_write(codec, cfg->hp_pin, 0, - AC_VERB_SET_UNSOLICITED_ENABLE, - STAC_UNSOL_ENABLE); + for (i = 0; i < cfg->hp_outs; i++) + if (get_wcaps(codec, cfg->hp_pins[i]) & AC_WCAP_UNSOL_CAP) + snd_hda_codec_write(codec, cfg->hp_pins[i], 0, + AC_VERB_SET_UNSOLICITED_ENABLE, + STAC_UNSOL_ENABLE); /* fake event to set up pins */ codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26); /* enable the headphones by default. If/when unsol_event detection works, this will be ignored */ @@ -1447,21 +1502,36 @@ static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res) if ((res >> 26) != STAC_HP_EVENT) return; - presence = snd_hda_codec_read(codec, cfg->hp_pin, 0, - AC_VERB_GET_PIN_SENSE, 0x00) >> 31; + presence = 0; + for (i = 0; i < cfg->hp_outs; i++) { + int p = snd_hda_codec_read(codec, cfg->hp_pins[i], 0, + AC_VERB_GET_PIN_SENSE, 0x00); + if (p & (1 << 31)) + presence++; + } if (presence) { /* disable lineouts, enable hp */ for (i = 0; i < cfg->line_outs; i++) stac92xx_reset_pinctl(codec, cfg->line_out_pins[i], AC_PINCTL_OUT_EN); - stac92xx_set_pinctl(codec, cfg->hp_pin, AC_PINCTL_OUT_EN); + for (i = 0; i < cfg->speaker_outs; i++) + stac92xx_reset_pinctl(codec, cfg->speaker_pins[i], + AC_PINCTL_OUT_EN); + for (i = 0; i < cfg->hp_outs; i++) + stac92xx_set_pinctl(codec, cfg->hp_pins[i], + AC_PINCTL_OUT_EN); } else { /* enable lineouts, disable hp */ for (i = 0; i < cfg->line_outs; i++) stac92xx_set_pinctl(codec, cfg->line_out_pins[i], AC_PINCTL_OUT_EN); - stac92xx_reset_pinctl(codec, cfg->hp_pin, AC_PINCTL_OUT_EN); + for (i = 0; i < cfg->speaker_outs; i++) + stac92xx_set_pinctl(codec, cfg->speaker_pins[i], + AC_PINCTL_OUT_EN); + for (i = 0; i < cfg->hp_outs; i++) + stac92xx_reset_pinctl(codec, cfg->hp_pins[i], + AC_PINCTL_OUT_EN); } } -- cgit v1.2.3 From 314634bc81325dcfeb31ed138647d428b1f26cbf Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 21 Sep 2006 11:56:18 +0200 Subject: [ALSA] hda-codec - Fix mic input with STAC92xx codecs Fixed mic input with STAC92xx codecs. The mic pin was sometimes set to OUTPUT by the headphone jack detection. Also, try to assign a secondary mic as front-mic (or vice versa) in the auto-detection if possible. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_sigmatel.c | 90 ++++++++++++++++++++++++++++-------------- 1 file changed, 60 insertions(+), 30 deletions(-) (limited to 'sound/pci/hda/patch_sigmatel.c') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 7cc06426520..92f48a72585 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -36,7 +36,6 @@ #define NUM_CONTROL_ALLOC 32 #define STAC_HP_EVENT 0x37 -#define STAC_UNSOL_ENABLE (AC_USRSP_EN | STAC_HP_EVENT) #define STAC_REF 0 #define STAC_D945GTP3 1 @@ -1164,23 +1163,28 @@ static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const int i, j, k; for (i = 0; i < AUTO_PIN_LAST; i++) { - int index = -1; - if (cfg->input_pins[i]) { - imux->items[imux->num_items].label = auto_pin_cfg_labels[i]; - - for (j=0; jnum_muxes; j++) { - int num_cons = snd_hda_get_connections(codec, spec->mux_nids[j], con_lst, HDA_MAX_NUM_INPUTS); - for (k=0; kinput_pins[i]) { - index = k; - break; - } - if (index >= 0) - break; - } - imux->items[imux->num_items].index = index; - imux->num_items++; + int index; + + if (!cfg->input_pins[i]) + continue; + index = -1; + for (j = 0; j < spec->num_muxes; j++) { + int num_cons; + num_cons = snd_hda_get_connections(codec, + spec->mux_nids[j], + con_lst, + HDA_MAX_NUM_INPUTS); + for (k = 0; k < num_cons; k++) + if (con_lst[k] == cfg->input_pins[i]) { + index = k; + goto found; + } } + continue; + found: + imux->items[imux->num_items].label = auto_pin_cfg_labels[i]; + imux->items[imux->num_items].index = index; + imux->num_items++; } if (imux->num_items == 1) { @@ -1405,6 +1409,15 @@ static void stac922x_gpio_mute(struct hda_codec *codec, int pin, int muted) AC_VERB_SET_GPIO_DATA, gpiostate); } +static void enable_pin_detect(struct hda_codec *codec, hda_nid_t nid, + unsigned int event) +{ + if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) + snd_hda_codec_write(codec, nid, 0, + AC_VERB_SET_UNSOLICITED_ENABLE, + (AC_USRSP_EN | event)); +} + static int stac92xx_init(struct hda_codec *codec) { struct sigmatel_spec *spec = codec->spec; @@ -1417,13 +1430,13 @@ static int stac92xx_init(struct hda_codec *codec) if (spec->hp_detect) { /* Enable unsolicited responses on the HP widget */ for (i = 0; i < cfg->hp_outs; i++) - if (get_wcaps(codec, cfg->hp_pins[i]) & AC_WCAP_UNSOL_CAP) - snd_hda_codec_write(codec, cfg->hp_pins[i], 0, - AC_VERB_SET_UNSOLICITED_ENABLE, - STAC_UNSOL_ENABLE); + enable_pin_detect(codec, cfg->hp_pins[i], + STAC_HP_EVENT); /* fake event to set up pins */ codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26); - /* enable the headphones by default. If/when unsol_event detection works, this will be ignored */ + /* enable the headphones by default. + * If/when unsol_event detection works, this will be ignored + */ stac92xx_auto_init_hp_out(codec); } else { stac92xx_auto_init_multi_out(codec); @@ -1478,6 +1491,8 @@ static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid, { unsigned int pin_ctl = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00); + if (flag == AC_PINCTL_OUT_EN && (pin_ctl & AC_PINCTL_IN_EN)) + return; snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_ctl | flag); @@ -1493,21 +1508,27 @@ static void stac92xx_reset_pinctl(struct hda_codec *codec, hda_nid_t nid, pin_ctl & ~flag); } -static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res) +static int get_pin_presence(struct hda_codec *codec, hda_nid_t nid) +{ + if (!nid) + return 0; + if (snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_SENSE, 0x00) + & (1 << 31)) + return 1; + return 0; +} + +static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res) { struct sigmatel_spec *spec = codec->spec; struct auto_pin_cfg *cfg = &spec->autocfg; int i, presence; - if ((res >> 26) != STAC_HP_EVENT) - return; - presence = 0; for (i = 0; i < cfg->hp_outs; i++) { - int p = snd_hda_codec_read(codec, cfg->hp_pins[i], 0, - AC_VERB_GET_PIN_SENSE, 0x00); - if (p & (1 << 31)) - presence++; + presence = get_pin_presence(codec, cfg->hp_pins[i]); + if (presence) + break; } if (presence) { @@ -1535,6 +1556,15 @@ static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res) } } +static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res) +{ + switch (res >> 26) { + case STAC_HP_EVENT: + stac92xx_hp_detect(codec, res); + break; + } +} + #ifdef CONFIG_PM static int stac92xx_resume(struct hda_codec *codec) { -- cgit v1.2.3 From eb995a8c82dba4a8e027c99ac5001fbc287a115c Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 21 Sep 2006 14:28:21 +0200 Subject: [ALSA] hda-codec - Fix headphone auto-toggle on sigmatel codec Fix/optimize the headphone auto-toggle function on sigmatel codecs. The headphone pins are kept as output. When headhpones are unplugged, you cannot hear anyway ;) Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_sigmatel.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) (limited to 'sound/pci/hda/patch_sigmatel.c') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 92f48a72585..731b7b97ee7 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -1432,12 +1432,9 @@ static int stac92xx_init(struct hda_codec *codec) for (i = 0; i < cfg->hp_outs; i++) enable_pin_detect(codec, cfg->hp_pins[i], STAC_HP_EVENT); + stac92xx_auto_init_hp_out(codec); /* fake event to set up pins */ codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26); - /* enable the headphones by default. - * If/when unsol_event detection works, this will be ignored - */ - stac92xx_auto_init_hp_out(codec); } else { stac92xx_auto_init_multi_out(codec); stac92xx_auto_init_hp_out(codec); @@ -1539,9 +1536,6 @@ static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res) for (i = 0; i < cfg->speaker_outs; i++) stac92xx_reset_pinctl(codec, cfg->speaker_pins[i], AC_PINCTL_OUT_EN); - for (i = 0; i < cfg->hp_outs; i++) - stac92xx_set_pinctl(codec, cfg->hp_pins[i], - AC_PINCTL_OUT_EN); } else { /* enable lineouts, disable hp */ for (i = 0; i < cfg->line_outs; i++) @@ -1550,9 +1544,6 @@ static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res) for (i = 0; i < cfg->speaker_outs; i++) stac92xx_set_pinctl(codec, cfg->speaker_pins[i], AC_PINCTL_OUT_EN); - for (i = 0; i < cfg->hp_outs; i++) - stac92xx_reset_pinctl(codec, cfg->hp_pins[i], - AC_PINCTL_OUT_EN); } } -- cgit v1.2.3