aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/hda_codec.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/hda/hda_codec.c')
-rw-r--r--sound/pci/hda/hda_codec.c141
1 files changed, 108 insertions, 33 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