ALSA: hda - Give more unique names by snd_hda_get_pin_label()

The function now gives more unique names for the output pins by adding
some prefix and suffix for the location and the channels.  Otherwise, it
can pass the index number.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
Takashi Iwai 2011-11-16 15:33:26 +01:00
Родитель bf815bf0a3
Коммит 201e06ffa9
6 изменённых файлов: 135 добавлений и 54 удалений

Просмотреть файл

@ -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";
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)
return hda_get_autocfg_input_label(codec, cfg, i);
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;
}
return hda_get_input_pin_label(codec, nid, true);
}
if (!name)
name = hda_get_input_pin_label(codec, nid, true);
break;
}
if (!name)
return 0;
strlcpy(label, name, maxlen);
return 1;
}
EXPORT_SYMBOL_HDA(snd_hda_get_pin_label);

Просмотреть файл

@ -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;

Просмотреть файл

@ -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);

Просмотреть файл

@ -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++;
}

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -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);