ソースを参照

Merge branch 'topic/hda-gateway' into topic/hda

Takashi Iwai 16 年 前
コミット
14ed74fbe2
3 ファイル変更161 行追加30 行削除
  1. 61 0
      sound/pci/hda/hda_codec.c
  2. 3 0
      sound/pci/hda/hda_local.h
  3. 97 30
      sound/pci/hda/patch_sigmatel.c

+ 61 - 0
sound/pci/hda/hda_codec.c

@@ -2723,6 +2723,67 @@ int snd_hda_check_board_config(struct hda_codec *codec,
 }
 EXPORT_SYMBOL_HDA(snd_hda_check_board_config);
 
+/**
+ * snd_hda_check_board_codec_sid_config - compare the current codec
+				          subsystem ID with the
+					  config table
+
+	   This is important for Gateway notebooks with SB450 HDA Audio
+	   where the vendor ID of the PCI device is:
+		ATI Technologies Inc SB450 HDA Audio [1002:437b]
+	   and the vendor/subvendor are found only at the codec.
+
+ * @codec: the HDA codec
+ * @num_configs: number of config enums
+ * @models: array of model name strings
+ * @tbl: configuration table, terminated by null entries
+ *
+ * Compares the modelname or PCI subsystem id of the current codec with the
+ * given configuration table.  If a matching entry is found, returns its
+ * config value (supposed to be 0 or positive).
+ *
+ * If no entries are matching, the function returns a negative value.
+ */
+int snd_hda_check_board_codec_sid_config(struct hda_codec *codec,
+			       int num_configs, const char **models,
+			       const struct snd_pci_quirk *tbl)
+{
+	const struct snd_pci_quirk *q;
+
+	/* Search for codec ID */
+	for (q = tbl; q->subvendor; q++) {
+		unsigned long vendorid = (q->subdevice) | (q->subvendor << 16);
+
+		if (vendorid == codec->subsystem_id)
+			break;
+	}
+
+	if (!q->subvendor)
+		return -1;
+
+	tbl = q;
+
+	if (tbl->value >= 0 && tbl->value < num_configs) {
+#ifdef CONFIG_SND_DEBUG_DETECT
+		char tmp[10];
+		const char *model = NULL;
+		if (models)
+			model = models[tbl->value];
+		if (!model) {
+			sprintf(tmp, "#%d", tbl->value);
+			model = tmp;
+		}
+		snd_printdd(KERN_INFO "hda_codec: model '%s' is selected "
+			    "for config %x:%x (%s)\n",
+			    model, tbl->subvendor, tbl->subdevice,
+			    (tbl->name ? tbl->name : "Unknown device"));
+#endif
+		return tbl->value;
+	}
+	return -1;
+}
+EXPORT_SYMBOL_HDA(snd_hda_check_board_codec_sid_config);
+
 /**
  * snd_hda_add_new_ctls - create controls from the array
  * @codec: the HDA codec

+ 3 - 0
sound/pci/hda/hda_local.h

@@ -296,6 +296,9 @@ void snd_print_pcm_bits(int pcm, char *buf, int buflen);
 int snd_hda_check_board_config(struct hda_codec *codec, int num_configs,
 			       const char **modelnames,
 			       const struct snd_pci_quirk *pci_list);
+int snd_hda_check_board_codec_sid_config(struct hda_codec *codec,
+                               int num_configs, const char **models,
+                               const struct snd_pci_quirk *tbl);
 int snd_hda_add_new_ctls(struct hda_codec *codec,
 			 struct snd_kcontrol_new *knew);
 

+ 97 - 30
sound/pci/hda/patch_sigmatel.c

@@ -55,7 +55,8 @@ enum {
 	STAC_9200_DELL_M25,
 	STAC_9200_DELL_M26,
 	STAC_9200_DELL_M27,
-	STAC_9200_GATEWAY,
+	STAC_9200_M4,
+	STAC_9200_M4_2,
 	STAC_9200_PANASONIC,
 	STAC_9200_MODELS
 };
@@ -94,9 +95,13 @@ enum {
 
 enum {
 	STAC_925x_REF,
+	STAC_M1,
+	STAC_M1_2,
+	STAC_M2,
 	STAC_M2_2,
-	STAC_MA6,
-	STAC_PA6,
+	STAC_M3,
+	STAC_M5,
+	STAC_M6,
 	STAC_925x_MODELS
 };
 
@@ -1334,7 +1339,16 @@ static unsigned int ref9200_pin_configs[8] = {
 	0x02a19020, 0x01a19021, 0x90100140, 0x01813122,
 };
 
-/* 
+static unsigned int gateway9200_m4_pin_configs[8] = {
+	0x400000fe, 0x404500f4, 0x400100f0, 0x90110010,
+	0x400100f1, 0x02a1902e, 0x500000f2, 0x500000f3,
+};
+static unsigned int gateway9200_m4_2_pin_configs[8] = {
+	0x400000fe, 0x404500f4, 0x400100f0, 0x90110010,
+	0x400100f1, 0x02a1902e, 0x500000f2, 0x500000f3,
+};
+
+/*
     STAC 9200 pin configs for
     102801A8
     102801DE
@@ -1464,6 +1478,8 @@ static unsigned int *stac9200_brd_tbl[STAC_9200_MODELS] = {
 	[STAC_9200_DELL_M25] = dell9200_m25_pin_configs,
 	[STAC_9200_DELL_M26] = dell9200_m26_pin_configs,
 	[STAC_9200_DELL_M27] = dell9200_m27_pin_configs,
+	[STAC_9200_M4] = gateway9200_m4_pin_configs,
+	[STAC_9200_M4_2] = gateway9200_m4_2_pin_configs,
 	[STAC_9200_PANASONIC] = ref9200_pin_configs,
 };
 
@@ -1480,7 +1496,8 @@ static const char *stac9200_models[STAC_9200_MODELS] = {
 	[STAC_9200_DELL_M25] = "dell-m25",
 	[STAC_9200_DELL_M26] = "dell-m26",
 	[STAC_9200_DELL_M27] = "dell-m27",
-	[STAC_9200_GATEWAY] = "gateway",
+	[STAC_9200_M4] = "gateway-m4",
+	[STAC_9200_M4_2] = "gateway-m4-2",
 	[STAC_9200_PANASONIC] = "panasonic",
 };
 
@@ -1550,11 +1567,9 @@ static struct snd_pci_quirk stac9200_cfg_tbl[] = {
 	/* Panasonic */
 	SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-74", STAC_9200_PANASONIC),
 	/* Gateway machines needs EAPD to be set on resume */
-	SND_PCI_QUIRK(0x107b, 0x0205, "Gateway S-7110M", STAC_9200_GATEWAY),
-	SND_PCI_QUIRK(0x107b, 0x0317, "Gateway MT3423, MX341*",
-		      STAC_9200_GATEWAY),
-	SND_PCI_QUIRK(0x107b, 0x0318, "Gateway ML3019, MT3707",
-		      STAC_9200_GATEWAY),
+	SND_PCI_QUIRK(0x107b, 0x0205, "Gateway S-7110M", STAC_9200_M4),
+	SND_PCI_QUIRK(0x107b, 0x0317, "Gateway MT3423, MX341*", STAC_9200_M4_2),
+	SND_PCI_QUIRK(0x107b, 0x0318, "Gateway ML3019, MT3707", STAC_9200_M4_2),
 	/* OQO Mobile */
 	SND_PCI_QUIRK(0x1106, 0x3288, "OQO Model 2", STAC_9200_OQO),
 	{} /* terminator */
@@ -1565,44 +1580,85 @@ static unsigned int ref925x_pin_configs[8] = {
 	0x90a70320, 0x02214210, 0x01019020, 0x9033032e,
 };
 
-static unsigned int stac925x_MA6_pin_configs[8] = {
-	0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021,
-	0x90a70320, 0x90100211, 0x400003f1, 0x9033032e,
+static unsigned int stac925xM1_pin_configs[8] = {
+	0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020,
+	0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e,
 };
 
-static unsigned int stac925x_PA6_pin_configs[8] = {
-	0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021,
-	0x50a103f0, 0x90100211, 0x400003f1, 0x9033032e,
+static unsigned int stac925xM1_2_pin_configs[8] = {
+	0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020,
+	0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e,
+};
+
+static unsigned int stac925xM2_pin_configs[8] = {
+	0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020,
+	0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e,
 };
 
 static unsigned int stac925xM2_2_pin_configs[8] = {
-	0x40c003f3, 0x424503f2, 0x04180011, 0x02a19020,
-	0x50a103f0, 0x90100212, 0x400003f1, 0x9033032e,
+	0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020,
+	0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e,
+};
+
+static unsigned int stac925xM3_pin_configs[8] = {
+	0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020,
+	0x40a000f0, 0x90100210, 0x400003f1, 0x503303f3,
+};
+
+static unsigned int stac925xM5_pin_configs[8] = {
+	0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020,
+	0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e,
+};
+
+static unsigned int stac925xM6_pin_configs[8] = {
+	0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020,
+	0x40a000f0, 0x90100210, 0x400003f1, 0x90330320,
 };
 
 static unsigned int *stac925x_brd_tbl[STAC_925x_MODELS] = {
 	[STAC_REF] = ref925x_pin_configs,
+	[STAC_M1] = stac925xM1_pin_configs,
+	[STAC_M1_2] = stac925xM1_2_pin_configs,
+	[STAC_M2] = stac925xM2_pin_configs,
 	[STAC_M2_2] = stac925xM2_2_pin_configs,
-	[STAC_MA6] = stac925x_MA6_pin_configs,
-	[STAC_PA6] = stac925x_PA6_pin_configs,
+	[STAC_M3] = stac925xM3_pin_configs,
+	[STAC_M5] = stac925xM5_pin_configs,
+	[STAC_M6] = stac925xM6_pin_configs,
 };
 
 static const char *stac925x_models[STAC_925x_MODELS] = {
 	[STAC_REF] = "ref",
+	[STAC_M1] = "m1",
+	[STAC_M1_2] = "m1-2",
+	[STAC_M2] = "m2",
 	[STAC_M2_2] = "m2-2",
-	[STAC_MA6] = "m6",
-	[STAC_PA6] = "pa6",
+	[STAC_M3] = "m3",
+	[STAC_M5] = "m5",
+	[STAC_M6] = "m6",
+};
+
+static struct snd_pci_quirk stac925x_codec_id_cfg_tbl[] = {
+	SND_PCI_QUIRK(0x107b, 0x0316, "Gateway M255", STAC_M2),
+	SND_PCI_QUIRK(0x107b, 0x0366, "Gateway MP6954", STAC_M5),
+	SND_PCI_QUIRK(0x107b, 0x0461, "Gateway NX560XL", STAC_M1),
+	SND_PCI_QUIRK(0x107b, 0x0681, "Gateway NX860", STAC_M2),
+	SND_PCI_QUIRK(0x107b, 0x0367, "Gateway MX6453", STAC_M1_2),
+	/* Not sure about the brand name for those */
+	SND_PCI_QUIRK(0x107b, 0x0281, "Gateway mobile", STAC_M1),
+	SND_PCI_QUIRK(0x107b, 0x0507, "Gateway mobile", STAC_M3),
+	SND_PCI_QUIRK(0x107b, 0x0281, "Gateway mobile", STAC_M6),
+	SND_PCI_QUIRK(0x107b, 0x0685, "Gateway mobile", STAC_M2_2),
+	{} /* terminator */
 };
 
 static struct snd_pci_quirk stac925x_cfg_tbl[] = {
 	/* SigmaTel reference board */
 	SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_REF),
 	SND_PCI_QUIRK(0x8384, 0x7632, "Stac9202 Reference Board", STAC_REF),
-	SND_PCI_QUIRK(0x107b, 0x0316, "Gateway M255", STAC_REF),
-	SND_PCI_QUIRK(0x107b, 0x0366, "Gateway MP6954", STAC_REF),
-	SND_PCI_QUIRK(0x107b, 0x0461, "Gateway NX560XL", STAC_MA6),
-	SND_PCI_QUIRK(0x107b, 0x0681, "Gateway NX860", STAC_PA6),
-	SND_PCI_QUIRK(0x1002, 0x437b, "Gateway MX6453", STAC_M2_2),
+
+	/* Default table for unknown ID */
+	SND_PCI_QUIRK(0x1002, 0x437b, "Gateway mobile", STAC_M2_2),
+
 	{} /* terminator */
 };
 
@@ -4392,7 +4448,8 @@ static int patch_stac9200(struct hda_codec *codec)
 	spec->num_adcs = 1;
 	spec->num_pwrs = 0;
 
-	if (spec->board_config == STAC_9200_GATEWAY ||
+	if (spec->board_config == STAC_9200_M4 ||
+	    spec->board_config == STAC_9200_M4_2 ||
 	    spec->board_config == STAC_9200_OQO)
 		spec->init = stac9200_eapd_init;
 	else
@@ -4427,12 +4484,22 @@ static int patch_stac925x(struct hda_codec *codec)
 	codec->spec = spec;
 	spec->num_pins = ARRAY_SIZE(stac925x_pin_nids);
 	spec->pin_nids = stac925x_pin_nids;
-	spec->board_config = snd_hda_check_board_config(codec, STAC_925x_MODELS,
+
+	/* Check first for codec ID */
+	spec->board_config = snd_hda_check_board_codec_sid_config(codec,
+							STAC_925x_MODELS,
+							stac925x_models,
+							stac925x_codec_id_cfg_tbl);
+
+	/* Now checks for PCI ID, if codec ID is not found */
+	if (spec->board_config < 0)
+		spec->board_config = snd_hda_check_board_config(codec,
+							STAC_925x_MODELS,
 							stac925x_models,
 							stac925x_cfg_tbl);
  again:
 	if (spec->board_config < 0) {
-		snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC925x," 
+		snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC925x,"
 				      "using BIOS defaults\n");
 		err = stac92xx_save_bios_config_regs(codec);
 	} else