diff options
| -rw-r--r-- | sound/pci/hda/hda_codec.c | 141 | ||||
| -rw-r--r-- | sound/pci/hda/hda_jack.c | 24 | ||||
| -rw-r--r-- | sound/pci/hda/hda_local.h | 5 | ||||
| -rw-r--r-- | sound/pci/hda/patch_ca0110.c | 6 | ||||
| -rw-r--r-- | sound/pci/hda/patch_cirrus.c | 5 | ||||
| -rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 8 | 
6 files changed, 135 insertions, 54 deletions
| diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index e57698f611ab..e050f893bf75 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -5066,61 +5066,136 @@ const char *hda_get_autocfg_input_label(struct hda_codec *codec,  }  EXPORT_SYMBOL_HDA(hda_get_autocfg_input_label); +/* get a unique suffix or an index number */ +static const char *check_output_sfx(hda_nid_t nid, const hda_nid_t *pins, +				    int num_pins, int *indexp) +{ +	static const char * const channel_sfx[] = { +		" Front", " Surrount", " CLFE", " Side" +	}; +	int i; + +	for (i = 0; i < num_pins; i++) { +		if (pins[i] == nid) { +			if (num_pins == 1) +				return ""; +			if (num_pins > ARRAY_SIZE(channel_sfx)) { +				if (indexp) +					*indexp = i; +				return ""; +			} +			return channel_sfx[i]; +		} +	} +	return NULL; +} + +static int fill_audio_out_name(struct hda_codec *codec, hda_nid_t nid, +			       const struct auto_pin_cfg *cfg, +			       const char *name, char *label, int maxlen, +			       int *indexp) +{ +	unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid); +	int attr = snd_hda_get_input_pin_attr(def_conf); +	const char *pfx = "", *sfx = ""; + +	/* handle as a speaker if it's a fixed line-out */ +	if (!strcmp(name, "Line-Out") && attr == INPUT_PIN_ATTR_INT) +		name = "Speaker"; +	/* check the location */ +	switch (attr) { +	case INPUT_PIN_ATTR_DOCK: +		pfx = "Dock "; +		break; +	case INPUT_PIN_ATTR_FRONT: +		pfx = "Front "; +		break; +	} +	if (cfg) { +		/* try to give a unique suffix if needed */ +		sfx = check_output_sfx(nid, cfg->line_out_pins, cfg->line_outs, +				       indexp); +		if (!sfx) +			sfx = check_output_sfx(nid, cfg->hp_pins, cfg->hp_outs, +					       indexp); +		if (!sfx) +			sfx = check_output_sfx(nid, cfg->speaker_pins, cfg->speaker_outs, +					       indexp); +		if (!sfx) +			sfx = ""; +	} +	snprintf(label, maxlen, "%s%s%s", pfx, name, sfx); +	return 1; +} +  /**   * snd_hda_get_pin_label - Get a label for the given I/O pin   *   * Get a label for the given pin.  This function works for both input and   * output pins.  When @cfg is given as non-NULL, the function tries to get   * an optimized label using hda_get_autocfg_input_label(). + * + * This function tries to give a unique label string for the pin as much as + * possible.  For example, when the multiple line-outs are present, it adds + * the channel suffix like "Front", "Surround", etc (only when @cfg is given). + * If no unique name with a suffix is available and @indexp is non-NULL, the + * index number is stored in the pointer.   */ -const char *snd_hda_get_pin_label(struct hda_codec *codec, hda_nid_t nid, -				  const struct auto_pin_cfg *cfg) +int snd_hda_get_pin_label(struct hda_codec *codec, hda_nid_t nid, +			  const struct auto_pin_cfg *cfg, +			  char *label, int maxlen, int *indexp)  {  	unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid); -	int attr; +	const char *name = NULL;  	int i; +	if (indexp) +		*indexp = 0;  	if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE) -		return NULL; +		return 0; -	attr = snd_hda_get_input_pin_attr(def_conf);  	switch (get_defcfg_device(def_conf)) {  	case AC_JACK_LINE_OUT: -		switch (attr) { -		case INPUT_PIN_ATTR_INT: -			return "Speaker"; -		case INPUT_PIN_ATTR_DOCK: -			return "Dock Line-Out"; -		case INPUT_PIN_ATTR_FRONT: -			return "Front Line-Out"; -		default: -			return "Line-Out"; -		} +		return fill_audio_out_name(codec, nid, cfg, "Line-Out", +					   label, maxlen, indexp);  	case AC_JACK_SPEAKER: -		return "Speaker"; +		return fill_audio_out_name(codec, nid, cfg, "Speaker", +					   label, maxlen, indexp);  	case AC_JACK_HP_OUT: -		switch (attr) { -		case INPUT_PIN_ATTR_DOCK: -			return "Dock Headphone"; -		case INPUT_PIN_ATTR_FRONT: -			return "Front Headphone"; -		default: -			return "Headphone"; -		} +		return fill_audio_out_name(codec, nid, cfg, "Headphone", +					   label, maxlen, indexp);  	case AC_JACK_SPDIF_OUT:  	case AC_JACK_DIG_OTHER_OUT:  		if (get_defcfg_location(def_conf) == AC_JACK_LOC_HDMI) -			return "HDMI"; +			name = "HDMI";  		else -			return "SPDIF"; -	} - -	if (cfg) { -		for (i = 0; i < cfg->num_inputs; i++) -			if (cfg->inputs[i].pin == nid) -				return hda_get_autocfg_input_label(codec, cfg, i); +			name = "SPDIF"; +		if (cfg && indexp) { +			for (i = 0; i < cfg->dig_outs; i++) +				if (cfg->dig_out_pins[i] == nid) { +					*indexp = i; +					break; +				} +		} +		break; +	default: +		if (cfg) { +			for (i = 0; i < cfg->num_inputs; i++) { +				if (cfg->inputs[i].pin != nid) +					continue; +				name = hda_get_autocfg_input_label(codec, cfg, i); +				if (name) +					break; +			} +		} +		if (!name) +			name = hda_get_input_pin_label(codec, nid, true); +		break;  	} -	return hda_get_input_pin_label(codec, nid, true); +	if (!name) +		return 0; +	strlcpy(label, name, maxlen); +	return 1;  }  EXPORT_SYMBOL_HDA(snd_hda_get_pin_label); diff --git a/sound/pci/hda/hda_jack.c b/sound/pci/hda/hda_jack.c index 25f756533bec..394901515d9e 100644 --- a/sound/pci/hda/hda_jack.c +++ b/sound/pci/hda/hda_jack.c @@ -232,11 +232,12 @@ int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,  }  EXPORT_SYMBOL_HDA(snd_hda_jack_add_kctl); -static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid, int idx, +static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid,  			 const struct auto_pin_cfg *cfg)  {  	unsigned int def_conf, conn; -	int err; +	char name[44]; +	int idx, err;  	if (!nid)  		return 0; @@ -247,9 +248,8 @@ static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid, int idx,  	if (conn != AC_JACK_PORT_COMPLEX)  		return 0; -	err = snd_hda_jack_add_kctl(codec, nid, -				     snd_hda_get_pin_label(codec, nid, cfg), -				     idx); +	snd_hda_get_pin_label(codec, nid, cfg, name, sizeof(name), &idx); +	err = snd_hda_jack_add_kctl(codec, nid, name, idx);  	if (err < 0)  		return err;  	return snd_hda_jack_detect_enable(codec, nid, 0); @@ -265,38 +265,38 @@ int snd_hda_jack_add_kctls(struct hda_codec *codec,  	int i, err;  	for (i = 0, p = cfg->line_out_pins; i < cfg->line_outs; i++, p++) { -		err = add_jack_kctl(codec, *p, i, cfg); +		err = add_jack_kctl(codec, *p, cfg);  		if (err < 0)  			return err;  	}  	for (i = 0, p = cfg->hp_pins; i < cfg->hp_outs; i++, p++) {  		if (*p == *cfg->line_out_pins) /* might be duplicated */  			break; -		err = add_jack_kctl(codec, *p, i, cfg); +		err = add_jack_kctl(codec, *p, cfg);  		if (err < 0)  			return err;  	}  	for (i = 0, p = cfg->speaker_pins; i < cfg->speaker_outs; i++, p++) {  		if (*p == *cfg->line_out_pins) /* might be duplicated */  			break; -		err = add_jack_kctl(codec, *p, i, cfg); +		err = add_jack_kctl(codec, *p, cfg);  		if (err < 0)  			return err;  	}  	for (i = 0; i < cfg->num_inputs; i++) { -		err = add_jack_kctl(codec, cfg->inputs[i].pin, 0, cfg); +		err = add_jack_kctl(codec, cfg->inputs[i].pin, cfg);  		if (err < 0)  			return err;  	}  	for (i = 0, p = cfg->dig_out_pins; i < cfg->dig_outs; i++, p++) { -		err = add_jack_kctl(codec, *p, i, cfg); +		err = add_jack_kctl(codec, *p, cfg);  		if (err < 0)  			return err;  	} -	err = add_jack_kctl(codec, cfg->dig_in_pin, 0, cfg); +	err = add_jack_kctl(codec, cfg->dig_in_pin, cfg);  	if (err < 0)  		return err; -	err = add_jack_kctl(codec, cfg->mono_out_pin, 0, cfg); +	err = add_jack_kctl(codec, cfg->mono_out_pin, cfg);  	if (err < 0)  		return err;  	return 0; diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index 13f681480a38..ef09716aeb6f 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h @@ -397,8 +397,9 @@ struct auto_pin_cfg;  const char *hda_get_autocfg_input_label(struct hda_codec *codec,  					const struct auto_pin_cfg *cfg,  					int input); -const char *snd_hda_get_pin_label(struct hda_codec *codec, hda_nid_t nid, -				  const struct auto_pin_cfg *cfg); +int snd_hda_get_pin_label(struct hda_codec *codec, hda_nid_t nid, +			  const struct auto_pin_cfg *cfg, +			  char *label, int maxlen, int *indexp);  int snd_hda_add_imux_item(struct hda_input_mux *imux, const char *label,  			  int index, int *type_index_ret); diff --git a/sound/pci/hda/patch_ca0110.c b/sound/pci/hda/patch_ca0110.c index 6bd602bfe0fe..09ccfabb4a17 100644 --- a/sound/pci/hda/patch_ca0110.c +++ b/sound/pci/hda/patch_ca0110.c @@ -41,7 +41,7 @@ struct ca0110_spec {  	hda_nid_t dig_out;  	hda_nid_t dig_in;  	unsigned int num_inputs; -	const char *input_labels[AUTO_PIN_LAST]; +	char input_labels[AUTO_PIN_LAST][32];  	struct hda_pcm pcm_rec[2];	/* PCM information */  }; @@ -476,7 +476,9 @@ static void parse_input(struct hda_codec *codec)  		if (j >= cfg->num_inputs)  			continue;  		spec->input_pins[n] = pin; -		spec->input_labels[n] = snd_hda_get_pin_label(codec, pin, NULL); +		snd_hda_get_pin_label(codec, pin, cfg, +				      spec->input_labels[n], +				      sizeof(spec->input_labels[n]), NULL);  		spec->adcs[n] = nid;  		n++;  	} diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c index 0e34554bc45e..0ba03878c5e0 100644 --- a/sound/pci/hda/patch_cirrus.c +++ b/sound/pci/hda/patch_cirrus.c @@ -711,8 +711,9 @@ static int cs_capture_source_info(struct snd_kcontrol *kcontrol,  	if (uinfo->value.enumerated.item >= spec->num_inputs)  		uinfo->value.enumerated.item = spec->num_inputs - 1;  	idx = spec->input_idx[uinfo->value.enumerated.item]; -	strcpy(uinfo->value.enumerated.name, -	       snd_hda_get_pin_label(codec, cfg->inputs[idx].pin, NULL)); +	snd_hda_get_pin_label(codec, cfg->inputs[idx].pin, cfg, +			      uinfo->value.enumerated.name, +			      sizeof(uinfo->value.enumerated.name), NULL);  	return 0;  } diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 73bf7cd0a6e4..0988dc4890a1 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -2867,7 +2867,8 @@ static inline int stac92xx_add_jack_mode_control(struct hda_codec *codec,  	}  	if (control) { -		strcpy(name, snd_hda_get_pin_label(codec, nid, NULL)); +		snd_hda_get_pin_label(codec, nid, &spec->autocfg, +				      name, sizeof(name), NULL);  		return stac92xx_add_control(codec->spec, control,  					strcat(name, " Jack Mode"), nid);  	} @@ -3545,7 +3546,7 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec,  	for (i = 0; i < spec->num_dmics; i++) {  		hda_nid_t nid;  		int index, type_idx; -		const char *label; +		char label[32];  		nid = spec->dmic_nids[i];  		if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN) @@ -3558,7 +3559,8 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec,  		if (index < 0)  			continue; -		label = snd_hda_get_pin_label(codec, nid, NULL); +		snd_hda_get_pin_label(codec, nid, &spec->autocfg, +				      label, sizeof(label), NULL);  		snd_hda_add_imux_item(dimux, label, index, &type_idx);  		if (snd_hda_get_bool_hint(codec, "separate_dmux") != 1)  			snd_hda_add_imux_item(imux, label, index, &type_idx); | 
