diff options
| author | Takashi Iwai <tiwai@suse.de> | 2009-01-13 17:50:46 +0100 | 
|---|---|---|
| committer | Takashi Iwai <tiwai@suse.de> | 2009-01-13 17:50:46 +0100 | 
| commit | 14ed74fbe2b917f0ad3e30cf2644203c04a45e89 (patch) | |
| tree | f1c9642a8c1f5c91399a9679faf32adfd213b508 /sound | |
| parent | c107b41c485c43f15b24743e81eaab742b3c0b67 (diff) | |
| parent | 58eec4235d63e07b98544527e031e7ae807e15df (diff) | |
Merge branch 'topic/hda-gateway' into topic/hda
Diffstat (limited to 'sound')
| -rw-r--r-- | sound/pci/hda/hda_codec.c | 61 | ||||
| -rw-r--r-- | sound/pci/hda/hda_local.h | 3 | ||||
| -rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 127 | 
3 files changed, 161 insertions, 30 deletions
| diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index fdad6ae7aad4..b7bba7dc7cf1 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -2724,6 +2724,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   * @knew: the array of struct snd_kcontrol_new diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index 6f2fe0f9fdd8..1dd8716c387f 100644 --- a/sound/pci/hda/hda_local.h +++ b/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); diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 9acf2f0a2df9..0e6fc56fa378 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/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 | 
