aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/hda')
-rw-r--r--sound/pci/hda/hda_codec.c141
-rw-r--r--sound/pci/hda/hda_jack.c24
-rw-r--r--sound/pci/hda/hda_local.h5
-rw-r--r--sound/pci/hda/patch_ca0110.c6
-rw-r--r--sound/pci/hda/patch_cirrus.c5
-rw-r--r--sound/pci/hda/patch_sigmatel.c8
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}
5067EXPORT_SYMBOL_HDA(hda_get_autocfg_input_label); 5067EXPORT_SYMBOL_HDA(hda_get_autocfg_input_label);
5068 5068
5069/* get a unique suffix or an index number */
5070static 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
5093static 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 */
5076const char *snd_hda_get_pin_label(struct hda_codec *codec, hda_nid_t nid, 5144int 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}
5125EXPORT_SYMBOL_HDA(snd_hda_get_pin_label); 5200EXPORT_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}
233EXPORT_SYMBOL_HDA(snd_hda_jack_add_kctl); 233EXPORT_SYMBOL_HDA(snd_hda_jack_add_kctl);
234 234
235static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid, int idx, 235static 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;
397const char *hda_get_autocfg_input_label(struct hda_codec *codec, 397const 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);
400const char *snd_hda_get_pin_label(struct hda_codec *codec, hda_nid_t nid, 400int 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);
402int snd_hda_add_imux_item(struct hda_input_mux *imux, const char *label, 403int 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);