File Index
Files and directories
Sign in
FILE

auto_parser.c

File preview with syntax highlighting.

linux-6.19.14/sound/hda/common/auto_parser.c C
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * BIOS auto-parser helper functions for HD-audio
   4 *
   5 * Copyright (c) 2012 Takashi Iwai <tiwai@suse.de>
   6 */
   7
   8#include <linux/slab.h>
   9#include <linux/export.h>
  10#include <linux/sort.h>
  11#include <sound/core.h>
  12#include <sound/hda_codec.h>
  13#include "hda_local.h"
  14#include "hda_auto_parser.h"
  15
  16/*
  17 * Helper for automatic pin configuration
  18 */
  19
  20static int is_in_nid_list(hda_nid_t nid, const hda_nid_t *list)
  21{
  22	for (; *list; list++)
  23		if (*list == nid)
  24			return 1;
  25	return 0;
  26}
  27
  28/* a pair of input pin and its sequence */
  29struct auto_out_pin {
  30	hda_nid_t pin;
  31	short seq;
  32};
  33
  34static int compare_seq(const void *ap, const void *bp)
  35{
  36	const struct auto_out_pin *a = ap;
  37	const struct auto_out_pin *b = bp;
  38	return (int)(a->seq - b->seq);
  39}
  40
  41/*
  42 * Sort an associated group of pins according to their sequence numbers.
  43 * then store it to a pin array.
  44 */
  45static void sort_pins_by_sequence(hda_nid_t *pins, struct auto_out_pin *list,
  46				  int num_pins)
  47{
  48	int i;
  49	sort(list, num_pins, sizeof(list[0]), compare_seq, NULL);
  50	for (i = 0; i < num_pins; i++)
  51		pins[i] = list[i].pin;
  52}
  53
  54
  55/* add the found input-pin to the cfg->inputs[] table */
  56static void add_auto_cfg_input_pin(struct hda_codec *codec, struct auto_pin_cfg *cfg,
  57				   hda_nid_t nid, int type)
  58{
  59	if (cfg->num_inputs < AUTO_CFG_MAX_INS) {
  60		cfg->inputs[cfg->num_inputs].pin = nid;
  61		cfg->inputs[cfg->num_inputs].type = type;
  62		cfg->inputs[cfg->num_inputs].has_boost_on_pin =
  63			nid_has_volume(codec, nid, HDA_INPUT);
  64		cfg->num_inputs++;
  65	}
  66}
  67
  68static int compare_input_type(const void *ap, const void *bp)
  69{
  70	const struct auto_pin_cfg_item *a = ap;
  71	const struct auto_pin_cfg_item *b = bp;
  72	if (a->type != b->type)
  73		return (int)(a->type - b->type);
  74
  75	/* If has both hs_mic and hp_mic, pick the hs_mic ahead of hp_mic. */
  76	if (a->is_headset_mic && b->is_headphone_mic)
  77		return -1; /* don't swap */
  78	else if (a->is_headphone_mic && b->is_headset_mic)
  79		return 1; /* swap */
  80
  81	/* In case one has boost and the other one has not,
  82	   pick the one with boost first. */
  83	if (a->has_boost_on_pin != b->has_boost_on_pin)
  84		return (int)(b->has_boost_on_pin - a->has_boost_on_pin);
  85
  86	/* Keep the original order */
  87	return a->order - b->order;
  88}
  89
  90/* Reorder the surround channels
  91 * ALSA sequence is front/surr/clfe/side
  92 * HDA sequence is:
  93 *    4-ch: front/surr  =>  OK as it is
  94 *    6-ch: front/clfe/surr
  95 *    8-ch: front/clfe/rear/side|fc
  96 */
  97static void reorder_outputs(unsigned int nums, hda_nid_t *pins)
  98{
  99	switch (nums) {
 100	case 3:
 101	case 4:
 102		swap(pins[1], pins[2]);
 103		break;
 104	}
 105}
 106
 107/* check whether the given pin has a proper pin I/O capability bit */
 108static bool check_pincap_validity(struct hda_codec *codec, hda_nid_t pin,
 109				  unsigned int dev)
 110{
 111	unsigned int pincap = snd_hda_query_pin_caps(codec, pin);
 112
 113	/* some old hardware don't return the proper pincaps */
 114	if (!pincap)
 115		return true;
 116
 117	switch (dev) {
 118	case AC_JACK_LINE_OUT:
 119	case AC_JACK_SPEAKER:
 120	case AC_JACK_HP_OUT:
 121	case AC_JACK_SPDIF_OUT:
 122	case AC_JACK_DIG_OTHER_OUT:
 123		return !!(pincap & AC_PINCAP_OUT);
 124	default:
 125		return !!(pincap & AC_PINCAP_IN);
 126	}
 127}
 128
 129static bool can_be_headset_mic(struct hda_codec *codec,
 130			       struct auto_pin_cfg_item *item,
 131			       int seq_number)
 132{
 133	int attr;
 134	unsigned int def_conf;
 135	if (item->type != AUTO_PIN_MIC)
 136		return false;
 137
 138	if (item->is_headset_mic || item->is_headphone_mic)
 139		return false; /* Already assigned */
 140
 141	def_conf = snd_hda_codec_get_pincfg(codec, item->pin);
 142	attr = snd_hda_get_input_pin_attr(def_conf);
 143	if (attr <= INPUT_PIN_ATTR_DOCK)
 144		return false;
 145
 146	if (seq_number >= 0) {
 147		int seq = get_defcfg_sequence(def_conf);
 148		if (seq != seq_number)
 149			return false;
 150	}
 151
 152	return true;
 153}
 154
 155/*
 156 * Parse all pin widgets and store the useful pin nids to cfg
 157 *
 158 * The number of line-outs or any primary output is stored in line_outs,
 159 * and the corresponding output pins are assigned to line_out_pins[],
 160 * in the order of front, rear, CLFE, side, ...
 161 *
 162 * If more extra outputs (speaker and headphone) are found, the pins are
 163 * assisnged to hp_pins[] and speaker_pins[], respectively.  If no line-out jack
 164 * is detected, one of speaker of HP pins is assigned as the primary
 165 * output, i.e. to line_out_pins[0].  So, line_outs is always positive
 166 * if any analog output exists.
 167 *
 168 * The analog input pins are assigned to inputs array.
 169 * The digital input/output pins are assigned to dig_in_pin and dig_out_pin,
 170 * respectively.
 171 */
 172int snd_hda_parse_pin_defcfg(struct hda_codec *codec,
 173			     struct auto_pin_cfg *cfg,
 174			     const hda_nid_t *ignore_nids,
 175			     unsigned int cond_flags)
 176{
 177	hda_nid_t nid;
 178	short seq, assoc_line_out;
 179	struct auto_out_pin line_out[ARRAY_SIZE(cfg->line_out_pins)];
 180	struct auto_out_pin speaker_out[ARRAY_SIZE(cfg->speaker_pins)];
 181	struct auto_out_pin hp_out[ARRAY_SIZE(cfg->hp_pins)];
 182	int i;
 183
 184	if (!snd_hda_get_int_hint(codec, "parser_flags", &i))
 185		cond_flags = i;
 186
 187	memset(cfg, 0, sizeof(*cfg));
 188
 189	memset(line_out, 0, sizeof(line_out));
 190	memset(speaker_out, 0, sizeof(speaker_out));
 191	memset(hp_out, 0, sizeof(hp_out));
 192	assoc_line_out = 0;
 193
 194	for_each_hda_codec_node(nid, codec) {
 195		unsigned int wid_caps = get_wcaps(codec, nid);
 196		unsigned int wid_type = get_wcaps_type(wid_caps);
 197		unsigned int def_conf;
 198		short assoc, loc, conn, dev;
 199
 200		/* read all default configuration for pin complex */
 201		if (wid_type != AC_WID_PIN)
 202			continue;
 203		/* ignore the given nids (e.g. pc-beep returns error) */
 204		if (ignore_nids && is_in_nid_list(nid, ignore_nids))
 205			continue;
 206
 207		def_conf = snd_hda_codec_get_pincfg(codec, nid);
 208		conn = get_defcfg_connect(def_conf);
 209		if (conn == AC_JACK_PORT_NONE)
 210			continue;
 211		loc = get_defcfg_location(def_conf);
 212		dev = get_defcfg_device(def_conf);
 213
 214		/* workaround for buggy BIOS setups */
 215		if (dev == AC_JACK_LINE_OUT) {
 216			if (conn == AC_JACK_PORT_FIXED ||
 217			    conn == AC_JACK_PORT_BOTH)
 218				dev = AC_JACK_SPEAKER;
 219		}
 220
 221		if (!check_pincap_validity(codec, nid, dev))
 222			continue;
 223
 224		switch (dev) {
 225		case AC_JACK_LINE_OUT:
 226			seq = get_defcfg_sequence(def_conf);
 227			assoc = get_defcfg_association(def_conf);
 228
 229			if (!(wid_caps & AC_WCAP_STEREO))
 230				if (!cfg->mono_out_pin)
 231					cfg->mono_out_pin = nid;
 232			if (!assoc)
 233				continue;
 234			if (!assoc_line_out)
 235				assoc_line_out = assoc;
 236			else if (assoc_line_out != assoc) {
 237				codec_info(codec,
 238					   "ignore pin 0x%x with mismatching assoc# 0x%x vs 0x%x\n",
 239					   nid, assoc, assoc_line_out);
 240				continue;
 241			}
 242			if (cfg->line_outs >= ARRAY_SIZE(cfg->line_out_pins)) {
 243				codec_info(codec,
 244					   "ignore pin 0x%x, too many assigned pins\n",
 245					   nid);
 246				continue;
 247			}
 248			line_out[cfg->line_outs].pin = nid;
 249			line_out[cfg->line_outs].seq = seq;
 250			cfg->line_outs++;
 251			break;
 252		case AC_JACK_SPEAKER:
 253			seq = get_defcfg_sequence(def_conf);
 254			assoc = get_defcfg_association(def_conf);
 255			if (cfg->speaker_outs >= ARRAY_SIZE(cfg->speaker_pins)) {
 256				codec_info(codec,
 257					   "ignore pin 0x%x, too many assigned pins\n",
 258					   nid);
 259				continue;
 260			}
 261			speaker_out[cfg->speaker_outs].pin = nid;
 262			speaker_out[cfg->speaker_outs].seq = (assoc << 4) | seq;
 263			cfg->speaker_outs++;
 264			break;
 265		case AC_JACK_HP_OUT:
 266			seq = get_defcfg_sequence(def_conf);
 267			assoc = get_defcfg_association(def_conf);
 268			if (cfg->hp_outs >= ARRAY_SIZE(cfg->hp_pins)) {
 269				codec_info(codec,
 270					   "ignore pin 0x%x, too many assigned pins\n",
 271					   nid);
 272				continue;
 273			}
 274			hp_out[cfg->hp_outs].pin = nid;
 275			hp_out[cfg->hp_outs].seq = (assoc << 4) | seq;
 276			cfg->hp_outs++;
 277			break;
 278		case AC_JACK_MIC_IN:
 279			add_auto_cfg_input_pin(codec, cfg, nid, AUTO_PIN_MIC);
 280			break;
 281		case AC_JACK_LINE_IN:
 282			add_auto_cfg_input_pin(codec, cfg, nid, AUTO_PIN_LINE_IN);
 283			break;
 284		case AC_JACK_CD:
 285			add_auto_cfg_input_pin(codec, cfg, nid, AUTO_PIN_CD);
 286			break;
 287		case AC_JACK_AUX:
 288			add_auto_cfg_input_pin(codec, cfg, nid, AUTO_PIN_AUX);
 289			break;
 290		case AC_JACK_SPDIF_OUT:
 291		case AC_JACK_DIG_OTHER_OUT:
 292			if (cfg->dig_outs >= ARRAY_SIZE(cfg->dig_out_pins)) {
 293				codec_info(codec,
 294					   "ignore pin 0x%x, too many assigned pins\n",
 295					   nid);
 296				continue;
 297			}
 298			cfg->dig_out_pins[cfg->dig_outs] = nid;
 299			cfg->dig_out_type[cfg->dig_outs] =
 300				(loc == AC_JACK_LOC_HDMI) ?
 301				HDA_PCM_TYPE_HDMI : HDA_PCM_TYPE_SPDIF;
 302			cfg->dig_outs++;
 303			break;
 304		case AC_JACK_SPDIF_IN:
 305		case AC_JACK_DIG_OTHER_IN:
 306			cfg->dig_in_pin = nid;
 307			if (loc == AC_JACK_LOC_HDMI)
 308				cfg->dig_in_type = HDA_PCM_TYPE_HDMI;
 309			else
 310				cfg->dig_in_type = HDA_PCM_TYPE_SPDIF;
 311			break;
 312		}
 313	}
 314
 315	/* Find a pin that could be a headset or headphone mic */
 316	if (cond_flags & HDA_PINCFG_HEADSET_MIC || cond_flags & HDA_PINCFG_HEADPHONE_MIC) {
 317		bool hsmic = !!(cond_flags & HDA_PINCFG_HEADSET_MIC);
 318		bool hpmic = !!(cond_flags & HDA_PINCFG_HEADPHONE_MIC);
 319		for (i = 0; (hsmic || hpmic) && (i < cfg->num_inputs); i++)
 320			if (hsmic && can_be_headset_mic(codec, &cfg->inputs[i], 0xc)) {
 321				cfg->inputs[i].is_headset_mic = 1;
 322				hsmic = false;
 323			} else if (hpmic && can_be_headset_mic(codec, &cfg->inputs[i], 0xd)) {
 324				cfg->inputs[i].is_headphone_mic = 1;
 325				hpmic = false;
 326			}
 327
 328		/* If we didn't find our sequence number mark, fall back to any sequence number */
 329		for (i = 0; (hsmic || hpmic) && (i < cfg->num_inputs); i++) {
 330			if (!can_be_headset_mic(codec, &cfg->inputs[i], -1))
 331				continue;
 332			if (hsmic) {
 333				cfg->inputs[i].is_headset_mic = 1;
 334				hsmic = false;
 335			} else if (hpmic) {
 336				cfg->inputs[i].is_headphone_mic = 1;
 337				hpmic = false;
 338			}
 339		}
 340
 341		if (hsmic)
 342			codec_dbg(codec, "Told to look for a headset mic, but didn't find any.\n");
 343		if (hpmic)
 344			codec_dbg(codec, "Told to look for a headphone mic, but didn't find any.\n");
 345	}
 346
 347	/* FIX-UP:
 348	 * If no line-out is defined but multiple HPs are found,
 349	 * some of them might be the real line-outs.
 350	 */
 351	if (!cfg->line_outs && cfg->hp_outs > 1 &&
 352	    !(cond_flags & HDA_PINCFG_NO_HP_FIXUP)) {
 353		i = 0;
 354		while (i < cfg->hp_outs) {
 355			/* The real HPs should have the sequence 0x0f */
 356			if ((hp_out[i].seq & 0x0f) == 0x0f) {
 357				i++;
 358				continue;
 359			}
 360			/* Move it to the line-out table */
 361			line_out[cfg->line_outs++] = hp_out[i];
 362			cfg->hp_outs--;
 363			memmove(hp_out + i, hp_out + i + 1,
 364				sizeof(hp_out[0]) * (cfg->hp_outs - i));
 365		}
 366		memset(hp_out + cfg->hp_outs, 0,
 367		       sizeof(hp_out[0]) * (AUTO_CFG_MAX_OUTS - cfg->hp_outs));
 368		if (!cfg->hp_outs)
 369			cfg->line_out_type = AUTO_PIN_HP_OUT;
 370
 371	}
 372
 373	/* sort by sequence */
 374	sort_pins_by_sequence(cfg->line_out_pins, line_out, cfg->line_outs);
 375	sort_pins_by_sequence(cfg->speaker_pins, speaker_out,
 376			      cfg->speaker_outs);
 377	sort_pins_by_sequence(cfg->hp_pins, hp_out, cfg->hp_outs);
 378
 379	/*
 380	 * FIX-UP: if no line-outs are detected, try to use speaker or HP pin
 381	 * as a primary output
 382	 */
 383	if (!cfg->line_outs &&
 384	    !(cond_flags & HDA_PINCFG_NO_LO_FIXUP)) {
 385		if (cfg->speaker_outs) {
 386			cfg->line_outs = cfg->speaker_outs;
 387			memcpy(cfg->line_out_pins, cfg->speaker_pins,
 388			       sizeof(cfg->speaker_pins));
 389			cfg->speaker_outs = 0;
 390			memset(cfg->speaker_pins, 0, sizeof(cfg->speaker_pins));
 391			cfg->line_out_type = AUTO_PIN_SPEAKER_OUT;
 392		} else if (cfg->hp_outs) {
 393			cfg->line_outs = cfg->hp_outs;
 394			memcpy(cfg->line_out_pins, cfg->hp_pins,
 395			       sizeof(cfg->hp_pins));
 396			cfg->hp_outs = 0;
 397			memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins));
 398			cfg->line_out_type = AUTO_PIN_HP_OUT;
 399		}
 400	}
 401
 402	reorder_outputs(cfg->line_outs, cfg->line_out_pins);
 403	reorder_outputs(cfg->hp_outs, cfg->hp_pins);
 404	reorder_outputs(cfg->speaker_outs, cfg->speaker_pins);
 405
 406	/* sort inputs in the order of AUTO_PIN_* type */
 407	for (i = 0; i < cfg->num_inputs; i++)
 408		cfg->inputs[i].order = i;
 409	sort(cfg->inputs, cfg->num_inputs, sizeof(cfg->inputs[0]),
 410	     compare_input_type, NULL);
 411
 412	/*
 413	 * debug prints of the parsed results
 414	 */
 415	codec_info(codec, "autoconfig for %s: line_outs=%d (0x%x/0x%x/0x%x/0x%x/0x%x) type:%s\n",
 416		   codec->core.chip_name, cfg->line_outs, cfg->line_out_pins[0],
 417		   cfg->line_out_pins[1], cfg->line_out_pins[2],
 418		   cfg->line_out_pins[3], cfg->line_out_pins[4],
 419		   cfg->line_out_type == AUTO_PIN_HP_OUT ? "hp" :
 420		   (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT ?
 421		    "speaker" : "line"));
 422	codec_info(codec, "   speaker_outs=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n",
 423		   cfg->speaker_outs, cfg->speaker_pins[0],
 424		   cfg->speaker_pins[1], cfg->speaker_pins[2],
 425		   cfg->speaker_pins[3], cfg->speaker_pins[4]);
 426	codec_info(codec, "   hp_outs=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n",
 427		   cfg->hp_outs, cfg->hp_pins[0],
 428		   cfg->hp_pins[1], cfg->hp_pins[2],
 429		   cfg->hp_pins[3], cfg->hp_pins[4]);
 430	codec_info(codec, "   mono: mono_out=0x%x\n", cfg->mono_out_pin);
 431	if (cfg->dig_outs)
 432		codec_info(codec, "   dig-out=0x%x/0x%x\n",
 433			   cfg->dig_out_pins[0], cfg->dig_out_pins[1]);
 434	codec_info(codec, "   inputs:\n");
 435	for (i = 0; i < cfg->num_inputs; i++) {
 436		codec_info(codec, "     %s=0x%x\n",
 437			    hda_get_autocfg_input_label(codec, cfg, i),
 438			    cfg->inputs[i].pin);
 439	}
 440	if (cfg->dig_in_pin)
 441		codec_info(codec, "   dig-in=0x%x\n", cfg->dig_in_pin);
 442
 443	return 0;
 444}
 445EXPORT_SYMBOL_GPL(snd_hda_parse_pin_defcfg);
 446
 447/**
 448 * snd_hda_get_input_pin_attr - Get the input pin attribute from pin config
 449 * @def_conf: pin configuration value
 450 *
 451 * Guess the input pin attribute (INPUT_PIN_ATTR_XXX) from the given
 452 * default pin configuration value.
 453 */
 454int snd_hda_get_input_pin_attr(unsigned int def_conf)
 455{
 456	unsigned int loc = get_defcfg_location(def_conf);
 457	unsigned int conn = get_defcfg_connect(def_conf);
 458	if (conn == AC_JACK_PORT_NONE)
 459		return INPUT_PIN_ATTR_UNUSED;
 460	/* Windows may claim the internal mic to be BOTH, too */
 461	if (conn == AC_JACK_PORT_FIXED || conn == AC_JACK_PORT_BOTH)
 462		return INPUT_PIN_ATTR_INT;
 463	if ((loc & 0x30) == AC_JACK_LOC_INTERNAL)
 464		return INPUT_PIN_ATTR_INT;
 465	if ((loc & 0x30) == AC_JACK_LOC_SEPARATE)
 466		return INPUT_PIN_ATTR_DOCK;
 467	if (loc == AC_JACK_LOC_REAR)
 468		return INPUT_PIN_ATTR_REAR;
 469	if (loc == AC_JACK_LOC_FRONT)
 470		return INPUT_PIN_ATTR_FRONT;
 471	return INPUT_PIN_ATTR_NORMAL;
 472}
 473EXPORT_SYMBOL_GPL(snd_hda_get_input_pin_attr);
 474
 475/**
 476 * hda_get_input_pin_label - Give a label for the given input pin
 477 * @codec: the HDA codec
 478 * @item: ping config item to refer
 479 * @pin: the pin NID
 480 * @check_location: flag to add the jack location prefix
 481 *
 482 * When @check_location is true, the function checks the pin location
 483 * for mic and line-in pins, and set an appropriate prefix like "Front",
 484 * "Rear", "Internal".
 485 */
 486static const char *hda_get_input_pin_label(struct hda_codec *codec,
 487					   const struct auto_pin_cfg_item *item,
 488					   hda_nid_t pin, bool check_location)
 489{
 490	unsigned int def_conf;
 491	static const char * const mic_names[] = {
 492		"Internal Mic", "Dock Mic", "Mic", "Rear Mic", "Front Mic"
 493	};
 494	int attr;
 495
 496	def_conf = snd_hda_codec_get_pincfg(codec, pin);
 497
 498	switch (get_defcfg_device(def_conf)) {
 499	case AC_JACK_MIC_IN:
 500		if (item && item->is_headset_mic)
 501			return "Headset Mic";
 502		if (item && item->is_headphone_mic)
 503			return "Headphone Mic";
 504		if (!check_location)
 505			return "Mic";
 506		attr = snd_hda_get_input_pin_attr(def_conf);
 507		if (!attr)
 508			return "None";
 509		return mic_names[attr - 1];
 510	case AC_JACK_LINE_IN:
 511		if (!check_location)
 512			return "Line";
 513		attr = snd_hda_get_input_pin_attr(def_conf);
 514		if (!attr)
 515			return "None";
 516		if (attr == INPUT_PIN_ATTR_DOCK)
 517			return "Dock Line";
 518		return "Line";
 519	case AC_JACK_AUX:
 520		return "Aux";
 521	case AC_JACK_CD:
 522		return "CD";
 523	case AC_JACK_SPDIF_IN:
 524		return "SPDIF In";
 525	case AC_JACK_DIG_OTHER_IN:
 526		return "Digital In";
 527	case AC_JACK_HP_OUT:
 528		return "Headphone Mic";
 529	default:
 530		return "Misc";
 531	}
 532}
 533
 534/* Check whether the location prefix needs to be added to the label.
 535 * If all mic-jacks are in the same location (e.g. rear panel), we don't
 536 * have to put "Front" prefix to each label.  In such a case, returns false.
 537 */
 538static int check_mic_location_need(struct hda_codec *codec,
 539				   const struct auto_pin_cfg *cfg,
 540				   int input)
 541{
 542	unsigned int defc;
 543	int i, attr, attr2;
 544
 545	defc = snd_hda_codec_get_pincfg(codec, cfg->inputs[input].pin);
 546	attr = snd_hda_get_input_pin_attr(defc);
 547	/* for internal or docking mics, we need locations */
 548	if (attr <= INPUT_PIN_ATTR_NORMAL)
 549		return 1;
 550
 551	attr = 0;
 552	for (i = 0; i < cfg->num_inputs; i++) {
 553		defc = snd_hda_codec_get_pincfg(codec, cfg->inputs[i].pin);
 554		attr2 = snd_hda_get_input_pin_attr(defc);
 555		if (attr2 >= INPUT_PIN_ATTR_NORMAL) {
 556			if (attr && attr != attr2)
 557				return 1; /* different locations found */
 558			attr = attr2;
 559		}
 560	}
 561	return 0;
 562}
 563
 564/**
 565 * hda_get_autocfg_input_label - Get a label for the given input
 566 * @codec: the HDA codec
 567 * @cfg: the parsed pin configuration
 568 * @input: the input index number
 569 *
 570 * Get a label for the given input pin defined by the autocfg item.
 571 * Unlike hda_get_input_pin_label(), this function checks all inputs
 572 * defined in autocfg and avoids the redundant mic/line prefix as much as
 573 * possible.
 574 */
 575const char *hda_get_autocfg_input_label(struct hda_codec *codec,
 576					const struct auto_pin_cfg *cfg,
 577					int input)
 578{
 579	int type = cfg->inputs[input].type;
 580	int has_multiple_pins = 0;
 581
 582	if ((input > 0 && cfg->inputs[input - 1].type == type) ||
 583	    (input < cfg->num_inputs - 1 && cfg->inputs[input + 1].type == type))
 584		has_multiple_pins = 1;
 585	if (has_multiple_pins && type == AUTO_PIN_MIC)
 586		has_multiple_pins &= check_mic_location_need(codec, cfg, input);
 587	has_multiple_pins |= codec->force_pin_prefix;
 588	return hda_get_input_pin_label(codec, &cfg->inputs[input],
 589				       cfg->inputs[input].pin,
 590				       has_multiple_pins);
 591}
 592EXPORT_SYMBOL_GPL(hda_get_autocfg_input_label);
 593
 594/* return the position of NID in the list, or -1 if not found */
 595static int find_idx_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
 596{
 597	int i;
 598	for (i = 0; i < nums; i++)
 599		if (list[i] == nid)
 600			return i;
 601	return -1;
 602}
 603
 604/* get a unique suffix or an index number */
 605static const char *check_output_sfx(hda_nid_t nid, const hda_nid_t *pins,
 606				    int num_pins, int *indexp)
 607{
 608	static const char * const channel_sfx[] = {
 609		" Front", " Surround", " CLFE", " Side"
 610	};
 611	int i;
 612
 613	i = find_idx_in_nid_list(nid, pins, num_pins);
 614	if (i < 0)
 615		return NULL;
 616	if (num_pins == 1)
 617		return "";
 618	if (num_pins > ARRAY_SIZE(channel_sfx)) {
 619		if (indexp)
 620			*indexp = i;
 621		return "";
 622	}
 623	return channel_sfx[i];
 624}
 625
 626static const char *check_output_pfx(struct hda_codec *codec, hda_nid_t nid)
 627{
 628	unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid);
 629	int attr = snd_hda_get_input_pin_attr(def_conf);
 630
 631	/* check the location */
 632	switch (attr) {
 633	case INPUT_PIN_ATTR_DOCK:
 634		return "Dock ";
 635	case INPUT_PIN_ATTR_FRONT:
 636		return "Front ";
 637	}
 638	return "";
 639}
 640
 641static int get_hp_label_index(struct hda_codec *codec, hda_nid_t nid,
 642			      const hda_nid_t *pins, int num_pins)
 643{
 644	int i, j, idx = 0;
 645
 646	const char *pfx = check_output_pfx(codec, nid);
 647
 648	i = find_idx_in_nid_list(nid, pins, num_pins);
 649	if (i < 0)
 650		return -1;
 651	for (j = 0; j < i; j++)
 652		if (pfx == check_output_pfx(codec, pins[j]))
 653			idx++;
 654
 655	return idx;
 656}
 657
 658static int fill_audio_out_name(struct hda_codec *codec, hda_nid_t nid,
 659			       const struct auto_pin_cfg *cfg,
 660			       const char *name, char *label, int maxlen,
 661			       int *indexp)
 662{
 663	unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid);
 664	int attr = snd_hda_get_input_pin_attr(def_conf);
 665	const char *pfx, *sfx = "";
 666
 667	/* handle as a speaker if it's a fixed line-out */
 668	if (!strcmp(name, "Line Out") && attr == INPUT_PIN_ATTR_INT)
 669		name = "Speaker";
 670	pfx = check_output_pfx(codec, nid);
 671
 672	if (cfg) {
 673		/* try to give a unique suffix if needed */
 674		sfx = check_output_sfx(nid, cfg->line_out_pins, cfg->line_outs,
 675				       indexp);
 676		if (!sfx)
 677			sfx = check_output_sfx(nid, cfg->speaker_pins, cfg->speaker_outs,
 678					       indexp);
 679		if (!sfx) {
 680			/* don't add channel suffix for Headphone controls */
 681			int idx = get_hp_label_index(codec, nid, cfg->hp_pins,
 682						     cfg->hp_outs);
 683			if (idx >= 0 && indexp)
 684				*indexp = idx;
 685			sfx = "";
 686		}
 687	}
 688	snprintf(label, maxlen, "%s%s%s", pfx, name, sfx);
 689	return 1;
 690}
 691
 692#define is_hdmi_cfg(conf) \
 693	(get_defcfg_location(conf) == AC_JACK_LOC_HDMI)
 694
 695/**
 696 * snd_hda_get_pin_label - Get a label for the given I/O pin
 697 * @codec: the HDA codec
 698 * @nid: pin NID
 699 * @cfg: the parsed pin configuration
 700 * @label: the string buffer to store
 701 * @maxlen: the max length of string buffer (including termination)
 702 * @indexp: the pointer to return the index number (for multiple ctls)
 703 *
 704 * Get a label for the given pin.  This function works for both input and
 705 * output pins.  When @cfg is given as non-NULL, the function tries to get
 706 * an optimized label using hda_get_autocfg_input_label().
 707 *
 708 * This function tries to give a unique label string for the pin as much as
 709 * possible.  For example, when the multiple line-outs are present, it adds
 710 * the channel suffix like "Front", "Surround", etc (only when @cfg is given).
 711 * If no unique name with a suffix is available and @indexp is non-NULL, the
 712 * index number is stored in the pointer.
 713 */
 714int snd_hda_get_pin_label(struct hda_codec *codec, hda_nid_t nid,
 715			  const struct auto_pin_cfg *cfg,
 716			  char *label, int maxlen, int *indexp)
 717{
 718	unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid);
 719	const char *name = NULL;
 720	int i;
 721	bool hdmi;
 722
 723	if (indexp)
 724		*indexp = 0;
 725	if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE)
 726		return 0;
 727
 728	switch (get_defcfg_device(def_conf)) {
 729	case AC_JACK_LINE_OUT:
 730		return fill_audio_out_name(codec, nid, cfg, "Line Out",
 731					   label, maxlen, indexp);
 732	case AC_JACK_SPEAKER:
 733		return fill_audio_out_name(codec, nid, cfg, "Speaker",
 734					   label, maxlen, indexp);
 735	case AC_JACK_HP_OUT:
 736		return fill_audio_out_name(codec, nid, cfg, "Headphone",
 737					   label, maxlen, indexp);
 738	case AC_JACK_SPDIF_OUT:
 739	case AC_JACK_DIG_OTHER_OUT:
 740		hdmi = is_hdmi_cfg(def_conf);
 741		name = hdmi ? "HDMI" : "SPDIF";
 742		if (cfg && indexp)
 743			for (i = 0; i < cfg->dig_outs; i++) {
 744				hda_nid_t pin = cfg->dig_out_pins[i];
 745				unsigned int c;
 746				if (pin == nid)
 747					break;
 748				c = snd_hda_codec_get_pincfg(codec, pin);
 749				if (hdmi == is_hdmi_cfg(c))
 750					(*indexp)++;
 751			}
 752		break;
 753	default:
 754		if (cfg) {
 755			for (i = 0; i < cfg->num_inputs; i++) {
 756				if (cfg->inputs[i].pin != nid)
 757					continue;
 758				name = hda_get_autocfg_input_label(codec, cfg, i);
 759				if (name)
 760					break;
 761			}
 762		}
 763		if (!name)
 764			name = hda_get_input_pin_label(codec, NULL, nid, true);
 765		break;
 766	}
 767	if (!name)
 768		return 0;
 769	strscpy(label, name, maxlen);
 770	return 1;
 771}
 772EXPORT_SYMBOL_GPL(snd_hda_get_pin_label);
 773
 774/**
 775 * snd_hda_add_verbs - Add verbs to the init list
 776 * @codec: the HDA codec
 777 * @list: zero-terminated verb list to add
 778 *
 779 * Append the given verb list to the execution list.  The verbs will be
 780 * performed at init and resume time via snd_hda_apply_verbs().
 781 */
 782int snd_hda_add_verbs(struct hda_codec *codec,
 783		      const struct hda_verb *list)
 784{
 785	const struct hda_verb **v;
 786	v = snd_array_new(&codec->verbs);
 787	if (!v)
 788		return -ENOMEM;
 789	*v = list;
 790	return 0;
 791}
 792EXPORT_SYMBOL_GPL(snd_hda_add_verbs);
 793
 794/**
 795 * snd_hda_apply_verbs - Execute the init verb lists
 796 * @codec: the HDA codec
 797 */
 798void snd_hda_apply_verbs(struct hda_codec *codec)
 799{
 800	const struct hda_verb **v;
 801	int i;
 802
 803	snd_array_for_each(&codec->verbs, i, v)
 804		snd_hda_sequence_write(codec, *v);
 805}
 806EXPORT_SYMBOL_GPL(snd_hda_apply_verbs);
 807
 808/**
 809 * snd_hda_apply_pincfgs - Set each pin config in the given list
 810 * @codec: the HDA codec
 811 * @cfg: NULL-terminated pin config table
 812 */
 813void snd_hda_apply_pincfgs(struct hda_codec *codec,
 814			   const struct hda_pintbl *cfg)
 815{
 816	for (; cfg->nid; cfg++)
 817		snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
 818}
 819EXPORT_SYMBOL_GPL(snd_hda_apply_pincfgs);
 820
 821static void set_pin_targets(struct hda_codec *codec,
 822			    const struct hda_pintbl *cfg)
 823{
 824	for (; cfg->nid; cfg++)
 825		snd_hda_set_pin_ctl_cache(codec, cfg->nid, cfg->val);
 826}
 827
 828void __snd_hda_apply_fixup(struct hda_codec *codec, int id, int action, int depth)
 829{
 830	const char *modelname = codec->fixup_name;
 831
 832	while (id >= 0) {
 833		const struct hda_fixup *fix = codec->fixup_list + id;
 834
 835		if (++depth > 10)
 836			break;
 837		if (fix->chained_before)
 838			__snd_hda_apply_fixup(codec, fix->chain_id, action, depth + 1);
 839
 840		switch (fix->type) {
 841		case HDA_FIXUP_PINS:
 842			if (action != HDA_FIXUP_ACT_PRE_PROBE || !fix->v.pins)
 843				break;
 844			codec_dbg(codec, "%s: Apply pincfg for %s\n",
 845				    codec->core.chip_name, modelname);
 846			snd_hda_apply_pincfgs(codec, fix->v.pins);
 847			break;
 848		case HDA_FIXUP_VERBS:
 849			if (action != HDA_FIXUP_ACT_PROBE || !fix->v.verbs)
 850				break;
 851			codec_dbg(codec, "%s: Apply fix-verbs for %s\n",
 852				    codec->core.chip_name, modelname);
 853			snd_hda_add_verbs(codec, fix->v.verbs);
 854			break;
 855		case HDA_FIXUP_FUNC:
 856			if (!fix->v.func)
 857				break;
 858			codec_dbg(codec, "%s: Apply fix-func for %s\n",
 859				    codec->core.chip_name, modelname);
 860			fix->v.func(codec, fix, action);
 861			break;
 862		case HDA_FIXUP_PINCTLS:
 863			if (action != HDA_FIXUP_ACT_PROBE || !fix->v.pins)
 864				break;
 865			codec_dbg(codec, "%s: Apply pinctl for %s\n",
 866				    codec->core.chip_name, modelname);
 867			set_pin_targets(codec, fix->v.pins);
 868			break;
 869		default:
 870			codec_err(codec, "%s: Invalid fixup type %d\n",
 871				   codec->core.chip_name, fix->type);
 872			break;
 873		}
 874		if (!fix->chained || fix->chained_before)
 875			break;
 876		id = fix->chain_id;
 877	}
 878}
 879EXPORT_SYMBOL_GPL(__snd_hda_apply_fixup);
 880
 881/**
 882 * snd_hda_apply_fixup - Apply the fixup chain with the given action
 883 * @codec: the HDA codec
 884 * @action: fixup action (HDA_FIXUP_ACT_XXX)
 885 */
 886void snd_hda_apply_fixup(struct hda_codec *codec, int action)
 887{
 888	if (codec->fixup_list)
 889		__snd_hda_apply_fixup(codec, codec->fixup_id, action, 0);
 890}
 891EXPORT_SYMBOL_GPL(snd_hda_apply_fixup);
 892
 893#define IGNORE_SEQ_ASSOC (~(AC_DEFCFG_SEQUENCE | AC_DEFCFG_DEF_ASSOC))
 894
 895static bool pin_config_match(struct hda_codec *codec,
 896			     const struct hda_pintbl *pins,
 897			     bool match_all_pins)
 898{
 899	const struct hda_pincfg *pin;
 900	int i;
 901
 902	snd_array_for_each(&codec->init_pins, i, pin) {
 903		hda_nid_t nid = pin->nid;
 904		u32 cfg = pin->cfg;
 905		const struct hda_pintbl *t_pins;
 906		int found;
 907
 908		t_pins = pins;
 909		found = 0;
 910		for (; t_pins->nid; t_pins++) {
 911			if (t_pins->nid == nid) {
 912				found = 1;
 913				if ((t_pins->val & IGNORE_SEQ_ASSOC) == (cfg & IGNORE_SEQ_ASSOC))
 914					break;
 915				else if ((cfg & 0xf0000000) == 0x40000000 && (t_pins->val & 0xf0000000) == 0x40000000)
 916					break;
 917				else
 918					return false;
 919			}
 920		}
 921		if (match_all_pins &&
 922		    !found && (cfg & 0xf0000000) != 0x40000000)
 923			return false;
 924	}
 925
 926	return true;
 927}
 928
 929/**
 930 * snd_hda_pick_pin_fixup - Pick up a fixup matching with the pin quirk list
 931 * @codec: the HDA codec
 932 * @pin_quirk: zero-terminated pin quirk list
 933 * @fixlist: the fixup list
 934 * @match_all_pins: all valid pins must match with the table entries
 935 */
 936void snd_hda_pick_pin_fixup(struct hda_codec *codec,
 937			    const struct snd_hda_pin_quirk *pin_quirk,
 938			    const struct hda_fixup *fixlist,
 939			    bool match_all_pins)
 940{
 941	const struct snd_hda_pin_quirk *pq;
 942	const char *name = NULL;
 943
 944	if (codec->fixup_id != HDA_FIXUP_ID_NOT_SET)
 945		return;
 946
 947	for (pq = pin_quirk; pq->subvendor; pq++) {
 948		if ((codec->core.subsystem_id & 0xffff0000) != (pq->subvendor << 16))
 949			continue;
 950		if (codec->core.vendor_id != pq->codec)
 951			continue;
 952		if (pin_config_match(codec, pq->pins, match_all_pins)) {
 953			codec->fixup_id = pq->value;
 954#ifdef CONFIG_SND_DEBUG_VERBOSE
 955			codec->fixup_name = pq->name;
 956			name = pq->name;
 957#endif
 958			codec_info(codec, "%s: picked fixup %s (pin match)\n",
 959				   codec->core.chip_name, name ? name : "");
 960			codec->fixup_list = fixlist;
 961			return;
 962		}
 963	}
 964}
 965EXPORT_SYMBOL_GPL(snd_hda_pick_pin_fixup);
 966
 967/* check whether the given quirk entry matches with vendor/device pair */
 968static bool hda_quirk_match(u16 vendor, u16 device, const struct hda_quirk *q)
 969{
 970	if (q->subvendor != vendor)
 971		return false;
 972	return !q->subdevice ||
 973		(device & q->subdevice_mask) == q->subdevice;
 974}
 975
 976/* look through the quirk list and return the matching entry */
 977static const struct hda_quirk *
 978hda_quirk_lookup_id(u16 vendor, u16 device, const struct hda_quirk *list)
 979{
 980	const struct hda_quirk *q;
 981
 982	for (q = list; q->subvendor || q->subdevice; q++) {
 983		if (hda_quirk_match(vendor, device, q))
 984			return q;
 985	}
 986	return NULL;
 987}
 988
 989/**
 990 * snd_hda_pick_fixup - Pick up a fixup matching with PCI/codec SSID or model string
 991 * @codec: the HDA codec
 992 * @models: NULL-terminated model string list
 993 * @quirk: zero-terminated PCI/codec SSID quirk list
 994 * @fixlist: the fixup list
 995 *
 996 * Pick up a fixup entry matching with the given model string or SSID.
 997 * If a fixup was already set beforehand, the function doesn't do anything.
 998 * When a special model string "nofixup" is given, also no fixup is applied.
 999 *
1000 * The function tries to find the matching model name at first, if given.
1001 * If the model string contains the SSID alias, try to look up with the given
1002 * alias ID.
1003 * If nothing matched, try to look up the PCI SSID.
1004 * If still nothing matched, try to look up the codec SSID.
1005 */
1006void snd_hda_pick_fixup(struct hda_codec *codec,
1007			const struct hda_model_fixup *models,
1008			const struct hda_quirk *quirk,
1009			const struct hda_fixup *fixlist)
1010{
1011	const struct hda_quirk *q;
1012	int id = HDA_FIXUP_ID_NOT_SET;
1013	const char *name = NULL;
1014	const char *type = NULL;
1015	unsigned int vendor, device;
1016	u16 pci_vendor, pci_device;
1017	u16 codec_vendor, codec_device;
1018
1019	if (codec->fixup_id != HDA_FIXUP_ID_NOT_SET)
1020		return;
1021
1022	/* when model=nofixup is given, don't pick up any fixups */
1023	if (codec->modelname && !strcmp(codec->modelname, "nofixup")) {
1024		id = HDA_FIXUP_ID_NO_FIXUP;
1025		fixlist = NULL;
1026		codec_info(codec, "%s: picked no fixup (nofixup specified)\n",
1027			   codec->core.chip_name);
1028		goto found;
1029	}
1030
1031	/* match with the model name string */
1032	if (codec->modelname && models) {
1033		while (models->name) {
1034			if (!strcmp(codec->modelname, models->name)) {
1035				id = models->id;
1036				name = models->name;
1037				codec_info(codec, "%s: picked fixup %s (model specified)\n",
1038					   codec->core.chip_name, name);
1039				goto found;
1040			}
1041			models++;
1042		}
1043	}
1044
1045	if (!quirk)
1046		return;
1047
1048	if (codec->bus->pci) {
1049		pci_vendor = codec->bus->pci->subsystem_vendor;
1050		pci_device = codec->bus->pci->subsystem_device;
1051	}
1052
1053	codec_vendor = codec->core.subsystem_id >> 16;
1054	codec_device = codec->core.subsystem_id & 0xffff;
1055
1056	/* match with the SSID alias given by the model string "XXXX:YYYY" */
1057	if (codec->modelname &&
1058	    sscanf(codec->modelname, "%04x:%04x", &vendor, &device) == 2) {
1059		q = hda_quirk_lookup_id(vendor, device, quirk);
1060		if (q) {
1061			type = "alias SSID";
1062			goto found_device;
1063		}
1064	}
1065
1066	/* match primarily with the PCI SSID */
1067	for (q = quirk; q->subvendor || q->subdevice; q++) {
1068		/* if the entry is specific to codec SSID, check with it */
1069		if (!codec->bus->pci || q->match_codec_ssid) {
1070			if (hda_quirk_match(codec_vendor, codec_device, q)) {
1071				type = "codec SSID";
1072				goto found_device;
1073			}
1074		} else {
1075			if (hda_quirk_match(pci_vendor, pci_device, q)) {
1076				type = "PCI SSID";
1077				goto found_device;
1078			}
1079		}
1080	}
1081
1082	/* match with the codec SSID */
1083	q = hda_quirk_lookup_id(codec_vendor, codec_device, quirk);
1084	if (q) {
1085		type = "codec SSID";
1086		goto found_device;
1087	}
1088
1089	return; /* no matching */
1090
1091 found_device:
1092	id = q->value;
1093#ifdef CONFIG_SND_DEBUG_VERBOSE
1094	name = q->name;
1095#endif
1096	codec_info(codec, "%s: picked fixup %s for %s %04x:%04x\n",
1097		   codec->core.chip_name, name ? name : "",
1098		   type, q->subvendor, q->subdevice);
1099 found:
1100	codec->fixup_id = id;
1101	codec->fixup_list = fixlist;
1102	codec->fixup_name = name;
1103}
1104EXPORT_SYMBOL_GPL(snd_hda_pick_fixup);
~/ Read-only file preview.