diff options
Diffstat (limited to 'sound/pci/hda')
-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, | |||
5066 | } | 5066 | } |
5067 | EXPORT_SYMBOL_HDA(hda_get_autocfg_input_label); | 5067 | EXPORT_SYMBOL_HDA(hda_get_autocfg_input_label); |
5068 | 5068 | ||
5069 | /* get a unique suffix or an index number */ | ||
5070 | static const char *check_output_sfx(hda_nid_t nid, const hda_nid_t *pins, | ||
5071 | int num_pins, int *indexp) | ||
5072 | { | ||
5073 | static const char * const channel_sfx[] = { | ||
5074 | " Front", " Surrount", " CLFE", " Side" | ||
5075 | }; | ||
5076 | int i; | ||
5077 | |||
5078 | for (i = 0; i < num_pins; i++) { | ||
5079 | if (pins[i] == nid) { | ||
5080 | if (num_pins == 1) | ||
5081 | return ""; | ||
5082 | if (num_pins > ARRAY_SIZE(channel_sfx)) { | ||
5083 | if (indexp) | ||
5084 | *indexp = i; | ||
5085 | return ""; | ||
5086 | } | ||
5087 | return channel_sfx[i]; | ||
5088 | } | ||
5089 | } | ||
5090 | return NULL; | ||
5091 | } | ||
5092 | |||
5093 | static int fill_audio_out_name(struct hda_codec *codec, hda_nid_t nid, | ||
5094 | const struct auto_pin_cfg *cfg, | ||
5095 | const char *name, char *label, int maxlen, | ||
5096 | int *indexp) | ||
5097 | { | ||
5098 | unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid); | ||
5099 | int attr = snd_hda_get_input_pin_attr(def_conf); | ||
5100 | const char *pfx = "", *sfx = ""; | ||
5101 | |||
5102 | /* handle as a speaker if it's a fixed line-out */ | ||
5103 | if (!strcmp(name, "Line-Out") && attr == INPUT_PIN_ATTR_INT) | ||
5104 | name = "Speaker"; | ||
5105 | /* check the location */ | ||
5106 | switch (attr) { | ||
5107 | case INPUT_PIN_ATTR_DOCK: | ||
5108 | pfx = "Dock "; | ||
5109 | break; | ||
5110 | case INPUT_PIN_ATTR_FRONT: | ||
5111 | pfx = "Front "; | ||
5112 | break; | ||
5113 | } | ||
5114 | if (cfg) { | ||
5115 | /* try to give a unique suffix if needed */ | ||
5116 | sfx = check_output_sfx(nid, cfg->line_out_pins, cfg->line_outs, | ||
5117 | indexp); | ||
5118 | if (!sfx) | ||
5119 | sfx = check_output_sfx(nid, cfg->hp_pins, cfg->hp_outs, | ||
5120 | indexp); | ||
5121 | if (!sfx) | ||
5122 | sfx = check_output_sfx(nid, cfg->speaker_pins, cfg->speaker_outs, | ||
5123 | indexp); | ||
5124 | if (!sfx) | ||
5125 | sfx = ""; | ||
5126 | } | ||
5127 | snprintf(label, maxlen, "%s%s%s", pfx, name, sfx); | ||
5128 | return 1; | ||
5129 | } | ||
5130 | |||
5069 | /** | 5131 | /** |
5070 | * snd_hda_get_pin_label - Get a label for the given I/O pin | 5132 | * snd_hda_get_pin_label - Get a label for the given I/O pin |
5071 | * | 5133 | * |
5072 | * Get a label for the given pin. This function works for both input and | 5134 | * Get a label for the given pin. This function works for both input and |
5073 | * output pins. When @cfg is given as non-NULL, the function tries to get | 5135 | * output pins. When @cfg is given as non-NULL, the function tries to get |
5074 | * an optimized label using hda_get_autocfg_input_label(). | 5136 | * an optimized label using hda_get_autocfg_input_label(). |
5137 | * | ||
5138 | * This function tries to give a unique label string for the pin as much as | ||
5139 | * possible. For example, when the multiple line-outs are present, it adds | ||
5140 | * the channel suffix like "Front", "Surround", etc (only when @cfg is given). | ||
5141 | * If no unique name with a suffix is available and @indexp is non-NULL, the | ||
5142 | * index number is stored in the pointer. | ||
5075 | */ | 5143 | */ |
5076 | const char *snd_hda_get_pin_label(struct hda_codec *codec, hda_nid_t nid, | 5144 | int snd_hda_get_pin_label(struct hda_codec *codec, hda_nid_t nid, |
5077 | const struct auto_pin_cfg *cfg) | 5145 | const struct auto_pin_cfg *cfg, |
5146 | char *label, int maxlen, int *indexp) | ||
5078 | { | 5147 | { |
5079 | unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid); | 5148 | unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid); |
5080 | int attr; | 5149 | const char *name = NULL; |
5081 | int i; | 5150 | int i; |
5082 | 5151 | ||
5152 | if (indexp) | ||
5153 | *indexp = 0; | ||
5083 | if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE) | 5154 | if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE) |
5084 | return NULL; | 5155 | return 0; |
5085 | 5156 | ||
5086 | attr = snd_hda_get_input_pin_attr(def_conf); | ||
5087 | switch (get_defcfg_device(def_conf)) { | 5157 | switch (get_defcfg_device(def_conf)) { |
5088 | case AC_JACK_LINE_OUT: | 5158 | case AC_JACK_LINE_OUT: |
5089 | switch (attr) { | 5159 | return fill_audio_out_name(codec, nid, cfg, "Line-Out", |
5090 | case INPUT_PIN_ATTR_INT: | 5160 | label, maxlen, indexp); |
5091 | return "Speaker"; | ||
5092 | case INPUT_PIN_ATTR_DOCK: | ||
5093 | return "Dock Line-Out"; | ||
5094 | case INPUT_PIN_ATTR_FRONT: | ||
5095 | return "Front Line-Out"; | ||
5096 | default: | ||
5097 | return "Line-Out"; | ||
5098 | } | ||
5099 | case AC_JACK_SPEAKER: | 5161 | case AC_JACK_SPEAKER: |
5100 | return "Speaker"; | 5162 | return fill_audio_out_name(codec, nid, cfg, "Speaker", |
5163 | label, maxlen, indexp); | ||
5101 | case AC_JACK_HP_OUT: | 5164 | case AC_JACK_HP_OUT: |
5102 | switch (attr) { | 5165 | return fill_audio_out_name(codec, nid, cfg, "Headphone", |
5103 | case INPUT_PIN_ATTR_DOCK: | 5166 | label, maxlen, indexp); |
5104 | return "Dock Headphone"; | ||
5105 | case INPUT_PIN_ATTR_FRONT: | ||
5106 | return "Front Headphone"; | ||
5107 | default: | ||
5108 | return "Headphone"; | ||
5109 | } | ||
5110 | case AC_JACK_SPDIF_OUT: | 5167 | case AC_JACK_SPDIF_OUT: |
5111 | case AC_JACK_DIG_OTHER_OUT: | 5168 | case AC_JACK_DIG_OTHER_OUT: |
5112 | if (get_defcfg_location(def_conf) == AC_JACK_LOC_HDMI) | 5169 | if (get_defcfg_location(def_conf) == AC_JACK_LOC_HDMI) |
5113 | return "HDMI"; | 5170 | name = "HDMI"; |
5114 | else | 5171 | else |
5115 | return "SPDIF"; | 5172 | name = "SPDIF"; |
5116 | } | 5173 | if (cfg && indexp) { |
5117 | 5174 | for (i = 0; i < cfg->dig_outs; i++) | |
5118 | if (cfg) { | 5175 | if (cfg->dig_out_pins[i] == nid) { |
5119 | for (i = 0; i < cfg->num_inputs; i++) | 5176 | *indexp = i; |
5120 | if (cfg->inputs[i].pin == nid) | 5177 | break; |
5121 | return hda_get_autocfg_input_label(codec, cfg, i); | 5178 | } |
5179 | } | ||
5180 | break; | ||
5181 | default: | ||
5182 | if (cfg) { | ||
5183 | for (i = 0; i < cfg->num_inputs; i++) { | ||
5184 | if (cfg->inputs[i].pin != nid) | ||
5185 | continue; | ||
5186 | name = hda_get_autocfg_input_label(codec, cfg, i); | ||
5187 | if (name) | ||
5188 | break; | ||
5189 | } | ||
5190 | } | ||
5191 | if (!name) | ||
5192 | name = hda_get_input_pin_label(codec, nid, true); | ||
5193 | break; | ||
5122 | } | 5194 | } |
5123 | return hda_get_input_pin_label(codec, nid, true); | 5195 | if (!name) |
5196 | return 0; | ||
5197 | strlcpy(label, name, maxlen); | ||
5198 | return 1; | ||
5124 | } | 5199 | } |
5125 | EXPORT_SYMBOL_HDA(snd_hda_get_pin_label); | 5200 | EXPORT_SYMBOL_HDA(snd_hda_get_pin_label); |
5126 | 5201 | ||
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, | |||
232 | } | 232 | } |
233 | EXPORT_SYMBOL_HDA(snd_hda_jack_add_kctl); | 233 | EXPORT_SYMBOL_HDA(snd_hda_jack_add_kctl); |
234 | 234 | ||
235 | static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid, int idx, | 235 | static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid, |
236 | const struct auto_pin_cfg *cfg) | 236 | const struct auto_pin_cfg *cfg) |
237 | { | 237 | { |
238 | unsigned int def_conf, conn; | 238 | unsigned int def_conf, conn; |
239 | int err; | 239 | char name[44]; |
240 | int idx, err; | ||
240 | 241 | ||
241 | if (!nid) | 242 | if (!nid) |
242 | return 0; | 243 | return 0; |
@@ -247,9 +248,8 @@ static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid, int idx, | |||
247 | if (conn != AC_JACK_PORT_COMPLEX) | 248 | if (conn != AC_JACK_PORT_COMPLEX) |
248 | return 0; | 249 | return 0; |
249 | 250 | ||
250 | err = snd_hda_jack_add_kctl(codec, nid, | 251 | snd_hda_get_pin_label(codec, nid, cfg, name, sizeof(name), &idx); |
251 | snd_hda_get_pin_label(codec, nid, cfg), | 252 | err = snd_hda_jack_add_kctl(codec, nid, name, idx); |
252 | idx); | ||
253 | if (err < 0) | 253 | if (err < 0) |
254 | return err; | 254 | return err; |
255 | return snd_hda_jack_detect_enable(codec, nid, 0); | 255 | return snd_hda_jack_detect_enable(codec, nid, 0); |
@@ -265,38 +265,38 @@ int snd_hda_jack_add_kctls(struct hda_codec *codec, | |||
265 | int i, err; | 265 | int i, err; |
266 | 266 | ||
267 | for (i = 0, p = cfg->line_out_pins; i < cfg->line_outs; i++, p++) { | 267 | for (i = 0, p = cfg->line_out_pins; i < cfg->line_outs; i++, p++) { |
268 | err = add_jack_kctl(codec, *p, i, cfg); | 268 | err = add_jack_kctl(codec, *p, cfg); |
269 | if (err < 0) | 269 | if (err < 0) |
270 | return err; | 270 | return err; |
271 | } | 271 | } |
272 | for (i = 0, p = cfg->hp_pins; i < cfg->hp_outs; i++, p++) { | 272 | for (i = 0, p = cfg->hp_pins; i < cfg->hp_outs; i++, p++) { |
273 | if (*p == *cfg->line_out_pins) /* might be duplicated */ | 273 | if (*p == *cfg->line_out_pins) /* might be duplicated */ |
274 | break; | 274 | break; |
275 | err = add_jack_kctl(codec, *p, i, cfg); | 275 | err = add_jack_kctl(codec, *p, cfg); |
276 | if (err < 0) | 276 | if (err < 0) |
277 | return err; | 277 | return err; |
278 | } | 278 | } |
279 | for (i = 0, p = cfg->speaker_pins; i < cfg->speaker_outs; i++, p++) { | 279 | for (i = 0, p = cfg->speaker_pins; i < cfg->speaker_outs; i++, p++) { |
280 | if (*p == *cfg->line_out_pins) /* might be duplicated */ | 280 | if (*p == *cfg->line_out_pins) /* might be duplicated */ |
281 | break; | 281 | break; |
282 | err = add_jack_kctl(codec, *p, i, cfg); | 282 | err = add_jack_kctl(codec, *p, cfg); |
283 | if (err < 0) | 283 | if (err < 0) |
284 | return err; | 284 | return err; |
285 | } | 285 | } |
286 | for (i = 0; i < cfg->num_inputs; i++) { | 286 | for (i = 0; i < cfg->num_inputs; i++) { |
287 | err = add_jack_kctl(codec, cfg->inputs[i].pin, 0, cfg); | 287 | err = add_jack_kctl(codec, cfg->inputs[i].pin, cfg); |
288 | if (err < 0) | 288 | if (err < 0) |
289 | return err; | 289 | return err; |
290 | } | 290 | } |
291 | for (i = 0, p = cfg->dig_out_pins; i < cfg->dig_outs; i++, p++) { | 291 | for (i = 0, p = cfg->dig_out_pins; i < cfg->dig_outs; i++, p++) { |
292 | err = add_jack_kctl(codec, *p, i, cfg); | 292 | err = add_jack_kctl(codec, *p, cfg); |
293 | if (err < 0) | 293 | if (err < 0) |
294 | return err; | 294 | return err; |
295 | } | 295 | } |
296 | err = add_jack_kctl(codec, cfg->dig_in_pin, 0, cfg); | 296 | err = add_jack_kctl(codec, cfg->dig_in_pin, cfg); |
297 | if (err < 0) | 297 | if (err < 0) |
298 | return err; | 298 | return err; |
299 | err = add_jack_kctl(codec, cfg->mono_out_pin, 0, cfg); | 299 | err = add_jack_kctl(codec, cfg->mono_out_pin, cfg); |
300 | if (err < 0) | 300 | if (err < 0) |
301 | return err; | 301 | return err; |
302 | return 0; | 302 | 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; | |||
397 | const char *hda_get_autocfg_input_label(struct hda_codec *codec, | 397 | const char *hda_get_autocfg_input_label(struct hda_codec *codec, |
398 | const struct auto_pin_cfg *cfg, | 398 | const struct auto_pin_cfg *cfg, |
399 | int input); | 399 | int input); |
400 | const char *snd_hda_get_pin_label(struct hda_codec *codec, hda_nid_t nid, | 400 | int snd_hda_get_pin_label(struct hda_codec *codec, hda_nid_t nid, |
401 | const struct auto_pin_cfg *cfg); | 401 | const struct auto_pin_cfg *cfg, |
402 | char *label, int maxlen, int *indexp); | ||
402 | int snd_hda_add_imux_item(struct hda_input_mux *imux, const char *label, | 403 | int snd_hda_add_imux_item(struct hda_input_mux *imux, const char *label, |
403 | int index, int *type_index_ret); | 404 | int index, int *type_index_ret); |
404 | 405 | ||
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 { | |||
41 | hda_nid_t dig_out; | 41 | hda_nid_t dig_out; |
42 | hda_nid_t dig_in; | 42 | hda_nid_t dig_in; |
43 | unsigned int num_inputs; | 43 | unsigned int num_inputs; |
44 | const char *input_labels[AUTO_PIN_LAST]; | 44 | char input_labels[AUTO_PIN_LAST][32]; |
45 | struct hda_pcm pcm_rec[2]; /* PCM information */ | 45 | struct hda_pcm pcm_rec[2]; /* PCM information */ |
46 | }; | 46 | }; |
47 | 47 | ||
@@ -476,7 +476,9 @@ static void parse_input(struct hda_codec *codec) | |||
476 | if (j >= cfg->num_inputs) | 476 | if (j >= cfg->num_inputs) |
477 | continue; | 477 | continue; |
478 | spec->input_pins[n] = pin; | 478 | spec->input_pins[n] = pin; |
479 | spec->input_labels[n] = snd_hda_get_pin_label(codec, pin, NULL); | 479 | snd_hda_get_pin_label(codec, pin, cfg, |
480 | spec->input_labels[n], | ||
481 | sizeof(spec->input_labels[n]), NULL); | ||
480 | spec->adcs[n] = nid; | 482 | spec->adcs[n] = nid; |
481 | n++; | 483 | n++; |
482 | } | 484 | } |
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, | |||
711 | if (uinfo->value.enumerated.item >= spec->num_inputs) | 711 | if (uinfo->value.enumerated.item >= spec->num_inputs) |
712 | uinfo->value.enumerated.item = spec->num_inputs - 1; | 712 | uinfo->value.enumerated.item = spec->num_inputs - 1; |
713 | idx = spec->input_idx[uinfo->value.enumerated.item]; | 713 | idx = spec->input_idx[uinfo->value.enumerated.item]; |
714 | strcpy(uinfo->value.enumerated.name, | 714 | snd_hda_get_pin_label(codec, cfg->inputs[idx].pin, cfg, |
715 | snd_hda_get_pin_label(codec, cfg->inputs[idx].pin, NULL)); | 715 | uinfo->value.enumerated.name, |
716 | sizeof(uinfo->value.enumerated.name), NULL); | ||
716 | return 0; | 717 | return 0; |
717 | } | 718 | } |
718 | 719 | ||
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, | |||
2867 | } | 2867 | } |
2868 | 2868 | ||
2869 | if (control) { | 2869 | if (control) { |
2870 | strcpy(name, snd_hda_get_pin_label(codec, nid, NULL)); | 2870 | snd_hda_get_pin_label(codec, nid, &spec->autocfg, |
2871 | name, sizeof(name), NULL); | ||
2871 | return stac92xx_add_control(codec->spec, control, | 2872 | return stac92xx_add_control(codec->spec, control, |
2872 | strcat(name, " Jack Mode"), nid); | 2873 | strcat(name, " Jack Mode"), nid); |
2873 | } | 2874 | } |
@@ -3545,7 +3546,7 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec, | |||
3545 | for (i = 0; i < spec->num_dmics; i++) { | 3546 | for (i = 0; i < spec->num_dmics; i++) { |
3546 | hda_nid_t nid; | 3547 | hda_nid_t nid; |
3547 | int index, type_idx; | 3548 | int index, type_idx; |
3548 | const char *label; | 3549 | char label[32]; |
3549 | 3550 | ||
3550 | nid = spec->dmic_nids[i]; | 3551 | nid = spec->dmic_nids[i]; |
3551 | if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN) | 3552 | 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, | |||
3558 | if (index < 0) | 3559 | if (index < 0) |
3559 | continue; | 3560 | continue; |
3560 | 3561 | ||
3561 | label = snd_hda_get_pin_label(codec, nid, NULL); | 3562 | snd_hda_get_pin_label(codec, nid, &spec->autocfg, |
3563 | label, sizeof(label), NULL); | ||
3562 | snd_hda_add_imux_item(dimux, label, index, &type_idx); | 3564 | snd_hda_add_imux_item(dimux, label, index, &type_idx); |
3563 | if (snd_hda_get_bool_hint(codec, "separate_dmux") != 1) | 3565 | if (snd_hda_get_bool_hint(codec, "separate_dmux") != 1) |
3564 | snd_hda_add_imux_item(imux, label, index, &type_idx); | 3566 | snd_hda_add_imux_item(imux, label, index, &type_idx); |