cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

hda_proc.c (27853B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * Universal Interface for Intel High Definition Audio Codec
      4 * 
      5 * Generic proc interface
      6 *
      7 * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
      8 */
      9
     10#include <linux/init.h>
     11#include <linux/slab.h>
     12#include <sound/core.h>
     13#include <linux/module.h>
     14#include <sound/hda_codec.h>
     15#include "hda_local.h"
     16
     17static int dump_coef = -1;
     18module_param(dump_coef, int, 0644);
     19MODULE_PARM_DESC(dump_coef, "Dump processing coefficients in codec proc file (-1=auto, 0=disable, 1=enable)");
     20
     21/* always use noncached version */
     22#define param_read(codec, nid, parm) \
     23	snd_hdac_read_parm_uncached(&(codec)->core, nid, parm)
     24
     25static const char *get_wid_type_name(unsigned int wid_value)
     26{
     27	static const char * const names[16] = {
     28		[AC_WID_AUD_OUT] = "Audio Output",
     29		[AC_WID_AUD_IN] = "Audio Input",
     30		[AC_WID_AUD_MIX] = "Audio Mixer",
     31		[AC_WID_AUD_SEL] = "Audio Selector",
     32		[AC_WID_PIN] = "Pin Complex",
     33		[AC_WID_POWER] = "Power Widget",
     34		[AC_WID_VOL_KNB] = "Volume Knob Widget",
     35		[AC_WID_BEEP] = "Beep Generator Widget",
     36		[AC_WID_VENDOR] = "Vendor Defined Widget",
     37	};
     38	if (wid_value == -1)
     39		return "UNKNOWN Widget";
     40	wid_value &= 0xf;
     41	if (names[wid_value])
     42		return names[wid_value];
     43	else
     44		return "UNKNOWN Widget";
     45}
     46
     47static void print_nid_array(struct snd_info_buffer *buffer,
     48			    struct hda_codec *codec, hda_nid_t nid,
     49			    struct snd_array *array)
     50{
     51	int i;
     52	struct hda_nid_item *items = array->list, *item;
     53	struct snd_kcontrol *kctl;
     54	for (i = 0; i < array->used; i++) {
     55		item = &items[i];
     56		if (item->nid == nid) {
     57			kctl = item->kctl;
     58			snd_iprintf(buffer,
     59			  "  Control: name=\"%s\", index=%i, device=%i\n",
     60			  kctl->id.name, kctl->id.index + item->index,
     61			  kctl->id.device);
     62			if (item->flags & HDA_NID_ITEM_AMP)
     63				snd_iprintf(buffer,
     64				  "    ControlAmp: chs=%lu, dir=%s, "
     65				  "idx=%lu, ofs=%lu\n",
     66				  get_amp_channels(kctl),
     67				  get_amp_direction(kctl) ? "Out" : "In",
     68				  get_amp_index(kctl),
     69				  get_amp_offset(kctl));
     70		}
     71	}
     72}
     73
     74static void print_nid_pcms(struct snd_info_buffer *buffer,
     75			   struct hda_codec *codec, hda_nid_t nid)
     76{
     77	int type;
     78	struct hda_pcm *cpcm;
     79
     80	list_for_each_entry(cpcm, &codec->pcm_list_head, list) {
     81		for (type = 0; type < 2; type++) {
     82			if (cpcm->stream[type].nid != nid || cpcm->pcm == NULL)
     83				continue;
     84			snd_iprintf(buffer, "  Device: name=\"%s\", "
     85				    "type=\"%s\", device=%i\n",
     86				    cpcm->name,
     87				    snd_hda_pcm_type_name[cpcm->pcm_type],
     88				    cpcm->pcm->device);
     89		}
     90	}
     91}
     92
     93static void print_amp_caps(struct snd_info_buffer *buffer,
     94			   struct hda_codec *codec, hda_nid_t nid, int dir)
     95{
     96	unsigned int caps;
     97	caps = param_read(codec, nid, dir == HDA_OUTPUT ?
     98			  AC_PAR_AMP_OUT_CAP : AC_PAR_AMP_IN_CAP);
     99	if (caps == -1 || caps == 0) {
    100		snd_iprintf(buffer, "N/A\n");
    101		return;
    102	}
    103	snd_iprintf(buffer, "ofs=0x%02x, nsteps=0x%02x, stepsize=0x%02x, "
    104		    "mute=%x\n",
    105		    caps & AC_AMPCAP_OFFSET,
    106		    (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT,
    107		    (caps & AC_AMPCAP_STEP_SIZE) >> AC_AMPCAP_STEP_SIZE_SHIFT,
    108		    (caps & AC_AMPCAP_MUTE) >> AC_AMPCAP_MUTE_SHIFT);
    109}
    110
    111/* is this a stereo widget or a stereo-to-mono mix? */
    112static bool is_stereo_amps(struct hda_codec *codec, hda_nid_t nid,
    113			   int dir, unsigned int wcaps, int indices)
    114{
    115	hda_nid_t conn;
    116
    117	if (wcaps & AC_WCAP_STEREO)
    118		return true;
    119	/* check for a stereo-to-mono mix; it must be:
    120	 * only a single connection, only for input, and only a mixer widget
    121	 */
    122	if (indices != 1 || dir != HDA_INPUT ||
    123	    get_wcaps_type(wcaps) != AC_WID_AUD_MIX)
    124		return false;
    125
    126	if (snd_hda_get_raw_connections(codec, nid, &conn, 1) < 0)
    127		return false;
    128	/* the connection source is a stereo? */
    129	wcaps = snd_hda_param_read(codec, conn, AC_PAR_AUDIO_WIDGET_CAP);
    130	return !!(wcaps & AC_WCAP_STEREO);
    131}
    132
    133static void print_amp_vals(struct snd_info_buffer *buffer,
    134			   struct hda_codec *codec, hda_nid_t nid,
    135			   int dir, unsigned int wcaps, int indices)
    136{
    137	unsigned int val;
    138	bool stereo;
    139	int i;
    140
    141	stereo = is_stereo_amps(codec, nid, dir, wcaps, indices);
    142
    143	dir = dir == HDA_OUTPUT ? AC_AMP_GET_OUTPUT : AC_AMP_GET_INPUT;
    144	for (i = 0; i < indices; i++) {
    145		snd_iprintf(buffer, " [");
    146		val = snd_hda_codec_read(codec, nid, 0,
    147					 AC_VERB_GET_AMP_GAIN_MUTE,
    148					 AC_AMP_GET_LEFT | dir | i);
    149		snd_iprintf(buffer, "0x%02x", val);
    150		if (stereo) {
    151			val = snd_hda_codec_read(codec, nid, 0,
    152						 AC_VERB_GET_AMP_GAIN_MUTE,
    153						 AC_AMP_GET_RIGHT | dir | i);
    154			snd_iprintf(buffer, " 0x%02x", val);
    155		}
    156		snd_iprintf(buffer, "]");
    157	}
    158	snd_iprintf(buffer, "\n");
    159}
    160
    161static void print_pcm_rates(struct snd_info_buffer *buffer, unsigned int pcm)
    162{
    163	static const unsigned int rates[] = {
    164		8000, 11025, 16000, 22050, 32000, 44100, 48000, 88200,
    165		96000, 176400, 192000, 384000
    166	};
    167	int i;
    168
    169	pcm &= AC_SUPPCM_RATES;
    170	snd_iprintf(buffer, "    rates [0x%x]:", pcm);
    171	for (i = 0; i < ARRAY_SIZE(rates); i++)
    172		if (pcm & (1 << i))
    173			snd_iprintf(buffer,  " %d", rates[i]);
    174	snd_iprintf(buffer, "\n");
    175}
    176
    177static void print_pcm_bits(struct snd_info_buffer *buffer, unsigned int pcm)
    178{
    179	char buf[SND_PRINT_BITS_ADVISED_BUFSIZE];
    180
    181	snd_iprintf(buffer, "    bits [0x%x]:", (pcm >> 16) & 0xff);
    182	snd_print_pcm_bits(pcm, buf, sizeof(buf));
    183	snd_iprintf(buffer, "%s\n", buf);
    184}
    185
    186static void print_pcm_formats(struct snd_info_buffer *buffer,
    187			      unsigned int streams)
    188{
    189	snd_iprintf(buffer, "    formats [0x%x]:", streams & 0xf);
    190	if (streams & AC_SUPFMT_PCM)
    191		snd_iprintf(buffer, " PCM");
    192	if (streams & AC_SUPFMT_FLOAT32)
    193		snd_iprintf(buffer, " FLOAT");
    194	if (streams & AC_SUPFMT_AC3)
    195		snd_iprintf(buffer, " AC3");
    196	snd_iprintf(buffer, "\n");
    197}
    198
    199static void print_pcm_caps(struct snd_info_buffer *buffer,
    200			   struct hda_codec *codec, hda_nid_t nid)
    201{
    202	unsigned int pcm = param_read(codec, nid, AC_PAR_PCM);
    203	unsigned int stream = param_read(codec, nid, AC_PAR_STREAM);
    204	if (pcm == -1 || stream == -1) {
    205		snd_iprintf(buffer, "N/A\n");
    206		return;
    207	}
    208	print_pcm_rates(buffer, pcm);
    209	print_pcm_bits(buffer, pcm);
    210	print_pcm_formats(buffer, stream);
    211}
    212
    213static const char *get_jack_connection(u32 cfg)
    214{
    215	static const char * const names[16] = {
    216		"Unknown", "1/8", "1/4", "ATAPI",
    217		"RCA", "Optical","Digital", "Analog",
    218		"DIN", "XLR", "RJ11", "Comb",
    219		NULL, NULL, NULL, "Other"
    220	};
    221	cfg = (cfg & AC_DEFCFG_CONN_TYPE) >> AC_DEFCFG_CONN_TYPE_SHIFT;
    222	if (names[cfg])
    223		return names[cfg];
    224	else
    225		return "UNKNOWN";
    226}
    227
    228static const char *get_jack_color(u32 cfg)
    229{
    230	static const char * const names[16] = {
    231		"Unknown", "Black", "Grey", "Blue",
    232		"Green", "Red", "Orange", "Yellow",
    233		"Purple", "Pink", NULL, NULL,
    234		NULL, NULL, "White", "Other",
    235	};
    236	cfg = (cfg & AC_DEFCFG_COLOR) >> AC_DEFCFG_COLOR_SHIFT;
    237	if (names[cfg])
    238		return names[cfg];
    239	else
    240		return "UNKNOWN";
    241}
    242
    243/*
    244 * Parse the pin default config value and returns the string of the
    245 * jack location, e.g. "Rear", "Front", etc.
    246 */
    247static const char *get_jack_location(u32 cfg)
    248{
    249	static const char * const bases[7] = {
    250		"N/A", "Rear", "Front", "Left", "Right", "Top", "Bottom",
    251	};
    252	static const unsigned char specials_idx[] = {
    253		0x07, 0x08,
    254		0x17, 0x18, 0x19,
    255		0x37, 0x38
    256	};
    257	static const char * const specials[] = {
    258		"Rear Panel", "Drive Bar",
    259		"Riser", "HDMI", "ATAPI",
    260		"Mobile-In", "Mobile-Out"
    261	};
    262	int i;
    263
    264	cfg = (cfg & AC_DEFCFG_LOCATION) >> AC_DEFCFG_LOCATION_SHIFT;
    265	if ((cfg & 0x0f) < 7)
    266		return bases[cfg & 0x0f];
    267	for (i = 0; i < ARRAY_SIZE(specials_idx); i++) {
    268		if (cfg == specials_idx[i])
    269			return specials[i];
    270	}
    271	return "UNKNOWN";
    272}
    273
    274/*
    275 * Parse the pin default config value and returns the string of the
    276 * jack connectivity, i.e. external or internal connection.
    277 */
    278static const char *get_jack_connectivity(u32 cfg)
    279{
    280	static const char * const jack_locations[4] = {
    281		"Ext", "Int", "Sep", "Oth"
    282	};
    283
    284	return jack_locations[(cfg >> (AC_DEFCFG_LOCATION_SHIFT + 4)) & 3];
    285}
    286
    287/*
    288 * Parse the pin default config value and returns the string of the
    289 * jack type, i.e. the purpose of the jack, such as Line-Out or CD.
    290 */
    291static const char *get_jack_type(u32 cfg)
    292{
    293	static const char * const jack_types[16] = {
    294		"Line Out", "Speaker", "HP Out", "CD",
    295		"SPDIF Out", "Digital Out", "Modem Line", "Modem Hand",
    296		"Line In", "Aux", "Mic", "Telephony",
    297		"SPDIF In", "Digital In", "Reserved", "Other"
    298	};
    299
    300	return jack_types[(cfg & AC_DEFCFG_DEVICE)
    301				>> AC_DEFCFG_DEVICE_SHIFT];
    302}
    303
    304static void print_pin_caps(struct snd_info_buffer *buffer,
    305			   struct hda_codec *codec, hda_nid_t nid,
    306			   int *supports_vref)
    307{
    308	static const char * const jack_conns[4] = {
    309		"Jack", "N/A", "Fixed", "Both"
    310	};
    311	unsigned int caps, val;
    312
    313	caps = param_read(codec, nid, AC_PAR_PIN_CAP);
    314	snd_iprintf(buffer, "  Pincap 0x%08x:", caps);
    315	if (caps & AC_PINCAP_IN)
    316		snd_iprintf(buffer, " IN");
    317	if (caps & AC_PINCAP_OUT)
    318		snd_iprintf(buffer, " OUT");
    319	if (caps & AC_PINCAP_HP_DRV)
    320		snd_iprintf(buffer, " HP");
    321	if (caps & AC_PINCAP_EAPD)
    322		snd_iprintf(buffer, " EAPD");
    323	if (caps & AC_PINCAP_PRES_DETECT)
    324		snd_iprintf(buffer, " Detect");
    325	if (caps & AC_PINCAP_BALANCE)
    326		snd_iprintf(buffer, " Balanced");
    327	if (caps & AC_PINCAP_HDMI) {
    328		/* Realtek uses this bit as a different meaning */
    329		if ((codec->core.vendor_id >> 16) == 0x10ec)
    330			snd_iprintf(buffer, " R/L");
    331		else {
    332			if (caps & AC_PINCAP_HBR)
    333				snd_iprintf(buffer, " HBR");
    334			snd_iprintf(buffer, " HDMI");
    335		}
    336	}
    337	if (caps & AC_PINCAP_DP)
    338		snd_iprintf(buffer, " DP");
    339	if (caps & AC_PINCAP_TRIG_REQ)
    340		snd_iprintf(buffer, " Trigger");
    341	if (caps & AC_PINCAP_IMP_SENSE)
    342		snd_iprintf(buffer, " ImpSense");
    343	snd_iprintf(buffer, "\n");
    344	if (caps & AC_PINCAP_VREF) {
    345		unsigned int vref =
    346			(caps & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
    347		snd_iprintf(buffer, "    Vref caps:");
    348		if (vref & AC_PINCAP_VREF_HIZ)
    349			snd_iprintf(buffer, " HIZ");
    350		if (vref & AC_PINCAP_VREF_50)
    351			snd_iprintf(buffer, " 50");
    352		if (vref & AC_PINCAP_VREF_GRD)
    353			snd_iprintf(buffer, " GRD");
    354		if (vref & AC_PINCAP_VREF_80)
    355			snd_iprintf(buffer, " 80");
    356		if (vref & AC_PINCAP_VREF_100)
    357			snd_iprintf(buffer, " 100");
    358		snd_iprintf(buffer, "\n");
    359		*supports_vref = 1;
    360	} else
    361		*supports_vref = 0;
    362	if (caps & AC_PINCAP_EAPD) {
    363		val = snd_hda_codec_read(codec, nid, 0,
    364					 AC_VERB_GET_EAPD_BTLENABLE, 0);
    365		snd_iprintf(buffer, "  EAPD 0x%x:", val);
    366		if (val & AC_EAPDBTL_BALANCED)
    367			snd_iprintf(buffer, " BALANCED");
    368		if (val & AC_EAPDBTL_EAPD)
    369			snd_iprintf(buffer, " EAPD");
    370		if (val & AC_EAPDBTL_LR_SWAP)
    371			snd_iprintf(buffer, " R/L");
    372		snd_iprintf(buffer, "\n");
    373	}
    374	caps = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONFIG_DEFAULT, 0);
    375	snd_iprintf(buffer, "  Pin Default 0x%08x: [%s] %s at %s %s\n", caps,
    376		    jack_conns[(caps & AC_DEFCFG_PORT_CONN) >> AC_DEFCFG_PORT_CONN_SHIFT],
    377		    get_jack_type(caps),
    378		    get_jack_connectivity(caps),
    379		    get_jack_location(caps));
    380	snd_iprintf(buffer, "    Conn = %s, Color = %s\n",
    381		    get_jack_connection(caps),
    382		    get_jack_color(caps));
    383	/* Default association and sequence values refer to default grouping
    384	 * of pin complexes and their sequence within the group. This is used
    385	 * for priority and resource allocation.
    386	 */
    387	snd_iprintf(buffer, "    DefAssociation = 0x%x, Sequence = 0x%x\n",
    388		    (caps & AC_DEFCFG_DEF_ASSOC) >> AC_DEFCFG_ASSOC_SHIFT,
    389		    caps & AC_DEFCFG_SEQUENCE);
    390	if (((caps & AC_DEFCFG_MISC) >> AC_DEFCFG_MISC_SHIFT) &
    391	    AC_DEFCFG_MISC_NO_PRESENCE) {
    392		/* Miscellaneous bit indicates external hardware does not
    393		 * support presence detection even if the pin complex
    394		 * indicates it is supported.
    395		 */
    396		snd_iprintf(buffer, "    Misc = NO_PRESENCE\n");
    397	}
    398}
    399
    400static void print_pin_ctls(struct snd_info_buffer *buffer,
    401			   struct hda_codec *codec, hda_nid_t nid,
    402			   int supports_vref)
    403{
    404	unsigned int pinctls;
    405
    406	pinctls = snd_hda_codec_read(codec, nid, 0,
    407				     AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
    408	snd_iprintf(buffer, "  Pin-ctls: 0x%02x:", pinctls);
    409	if (pinctls & AC_PINCTL_IN_EN)
    410		snd_iprintf(buffer, " IN");
    411	if (pinctls & AC_PINCTL_OUT_EN)
    412		snd_iprintf(buffer, " OUT");
    413	if (pinctls & AC_PINCTL_HP_EN)
    414		snd_iprintf(buffer, " HP");
    415	if (supports_vref) {
    416		int vref = pinctls & AC_PINCTL_VREFEN;
    417		switch (vref) {
    418		case AC_PINCTL_VREF_HIZ:
    419			snd_iprintf(buffer, " VREF_HIZ");
    420			break;
    421		case AC_PINCTL_VREF_50:
    422			snd_iprintf(buffer, " VREF_50");
    423			break;
    424		case AC_PINCTL_VREF_GRD:
    425			snd_iprintf(buffer, " VREF_GRD");
    426			break;
    427		case AC_PINCTL_VREF_80:
    428			snd_iprintf(buffer, " VREF_80");
    429			break;
    430		case AC_PINCTL_VREF_100:
    431			snd_iprintf(buffer, " VREF_100");
    432			break;
    433		}
    434	}
    435	snd_iprintf(buffer, "\n");
    436}
    437
    438static void print_vol_knob(struct snd_info_buffer *buffer,
    439			   struct hda_codec *codec, hda_nid_t nid)
    440{
    441	unsigned int cap = param_read(codec, nid, AC_PAR_VOL_KNB_CAP);
    442	snd_iprintf(buffer, "  Volume-Knob: delta=%d, steps=%d, ",
    443		    (cap >> 7) & 1, cap & 0x7f);
    444	cap = snd_hda_codec_read(codec, nid, 0,
    445				 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
    446	snd_iprintf(buffer, "direct=%d, val=%d\n",
    447		    (cap >> 7) & 1, cap & 0x7f);
    448}
    449
    450static void print_audio_io(struct snd_info_buffer *buffer,
    451			   struct hda_codec *codec, hda_nid_t nid,
    452			   unsigned int wid_type)
    453{
    454	int conv = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0);
    455	snd_iprintf(buffer,
    456		    "  Converter: stream=%d, channel=%d\n",
    457		    (conv & AC_CONV_STREAM) >> AC_CONV_STREAM_SHIFT,
    458		    conv & AC_CONV_CHANNEL);
    459
    460	if (wid_type == AC_WID_AUD_IN && (conv & AC_CONV_CHANNEL) == 0) {
    461		int sdi = snd_hda_codec_read(codec, nid, 0,
    462					     AC_VERB_GET_SDI_SELECT, 0);
    463		snd_iprintf(buffer, "  SDI-Select: %d\n",
    464			    sdi & AC_SDI_SELECT);
    465	}
    466}
    467
    468static void print_digital_conv(struct snd_info_buffer *buffer,
    469			       struct hda_codec *codec, hda_nid_t nid)
    470{
    471	unsigned int digi1 = snd_hda_codec_read(codec, nid, 0,
    472						AC_VERB_GET_DIGI_CONVERT_1, 0);
    473	unsigned char digi2 = digi1 >> 8;
    474	unsigned char digi3 = digi1 >> 16;
    475
    476	snd_iprintf(buffer, "  Digital:");
    477	if (digi1 & AC_DIG1_ENABLE)
    478		snd_iprintf(buffer, " Enabled");
    479	if (digi1 & AC_DIG1_V)
    480		snd_iprintf(buffer, " Validity");
    481	if (digi1 & AC_DIG1_VCFG)
    482		snd_iprintf(buffer, " ValidityCfg");
    483	if (digi1 & AC_DIG1_EMPHASIS)
    484		snd_iprintf(buffer, " Preemphasis");
    485	if (digi1 & AC_DIG1_COPYRIGHT)
    486		snd_iprintf(buffer, " Non-Copyright");
    487	if (digi1 & AC_DIG1_NONAUDIO)
    488		snd_iprintf(buffer, " Non-Audio");
    489	if (digi1 & AC_DIG1_PROFESSIONAL)
    490		snd_iprintf(buffer, " Pro");
    491	if (digi1 & AC_DIG1_LEVEL)
    492		snd_iprintf(buffer, " GenLevel");
    493	if (digi3 & AC_DIG3_KAE)
    494		snd_iprintf(buffer, " KAE");
    495	snd_iprintf(buffer, "\n");
    496	snd_iprintf(buffer, "  Digital category: 0x%x\n",
    497		    digi2 & AC_DIG2_CC);
    498	snd_iprintf(buffer, "  IEC Coding Type: 0x%x\n",
    499			digi3 & AC_DIG3_ICT);
    500}
    501
    502static const char *get_pwr_state(u32 state)
    503{
    504	static const char * const buf[] = {
    505		"D0", "D1", "D2", "D3", "D3cold"
    506	};
    507	if (state < ARRAY_SIZE(buf))
    508		return buf[state];
    509	return "UNKNOWN";
    510}
    511
    512static void print_power_state(struct snd_info_buffer *buffer,
    513			      struct hda_codec *codec, hda_nid_t nid)
    514{
    515	static const char * const names[] = {
    516		[ilog2(AC_PWRST_D0SUP)]		= "D0",
    517		[ilog2(AC_PWRST_D1SUP)]		= "D1",
    518		[ilog2(AC_PWRST_D2SUP)]		= "D2",
    519		[ilog2(AC_PWRST_D3SUP)]		= "D3",
    520		[ilog2(AC_PWRST_D3COLDSUP)]	= "D3cold",
    521		[ilog2(AC_PWRST_S3D3COLDSUP)]	= "S3D3cold",
    522		[ilog2(AC_PWRST_CLKSTOP)]	= "CLKSTOP",
    523		[ilog2(AC_PWRST_EPSS)]		= "EPSS",
    524	};
    525
    526	int sup = param_read(codec, nid, AC_PAR_POWER_STATE);
    527	int pwr = snd_hda_codec_read(codec, nid, 0,
    528				     AC_VERB_GET_POWER_STATE, 0);
    529	if (sup != -1) {
    530		int i;
    531
    532		snd_iprintf(buffer, "  Power states: ");
    533		for (i = 0; i < ARRAY_SIZE(names); i++) {
    534			if (sup & (1U << i))
    535				snd_iprintf(buffer, " %s", names[i]);
    536		}
    537		snd_iprintf(buffer, "\n");
    538	}
    539
    540	snd_iprintf(buffer, "  Power: setting=%s, actual=%s",
    541		    get_pwr_state(pwr & AC_PWRST_SETTING),
    542		    get_pwr_state((pwr & AC_PWRST_ACTUAL) >>
    543				  AC_PWRST_ACTUAL_SHIFT));
    544	if (pwr & AC_PWRST_ERROR)
    545		snd_iprintf(buffer, ", Error");
    546	if (pwr & AC_PWRST_CLK_STOP_OK)
    547		snd_iprintf(buffer, ", Clock-stop-OK");
    548	if (pwr & AC_PWRST_SETTING_RESET)
    549		snd_iprintf(buffer, ", Setting-reset");
    550	snd_iprintf(buffer, "\n");
    551}
    552
    553static void print_unsol_cap(struct snd_info_buffer *buffer,
    554			      struct hda_codec *codec, hda_nid_t nid)
    555{
    556	int unsol = snd_hda_codec_read(codec, nid, 0,
    557				       AC_VERB_GET_UNSOLICITED_RESPONSE, 0);
    558	snd_iprintf(buffer,
    559		    "  Unsolicited: tag=%02x, enabled=%d\n",
    560		    unsol & AC_UNSOL_TAG,
    561		    (unsol & AC_UNSOL_ENABLED) ? 1 : 0);
    562}
    563
    564static inline bool can_dump_coef(struct hda_codec *codec)
    565{
    566	switch (dump_coef) {
    567	case 0: return false;
    568	case 1: return true;
    569	default: return codec->dump_coef;
    570	}
    571}
    572
    573static void print_proc_caps(struct snd_info_buffer *buffer,
    574			    struct hda_codec *codec, hda_nid_t nid)
    575{
    576	unsigned int i, ncoeff, oldindex;
    577	unsigned int proc_caps = param_read(codec, nid, AC_PAR_PROC_CAP);
    578	ncoeff = (proc_caps & AC_PCAP_NUM_COEF) >> AC_PCAP_NUM_COEF_SHIFT;
    579	snd_iprintf(buffer, "  Processing caps: benign=%d, ncoeff=%d\n",
    580		    proc_caps & AC_PCAP_BENIGN, ncoeff);
    581
    582	if (!can_dump_coef(codec))
    583		return;
    584
    585	/* Note: This is racy - another process could run in parallel and change
    586	   the coef index too. */
    587	oldindex = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_COEF_INDEX, 0);
    588	for (i = 0; i < ncoeff; i++) {
    589		unsigned int val;
    590		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, i);
    591		val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PROC_COEF,
    592					 0);
    593		snd_iprintf(buffer, "    Coeff 0x%02x: 0x%04x\n", i, val);
    594	}
    595	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, oldindex);
    596}
    597
    598static void print_conn_list(struct snd_info_buffer *buffer,
    599			    struct hda_codec *codec, hda_nid_t nid,
    600			    unsigned int wid_type, hda_nid_t *conn,
    601			    int conn_len)
    602{
    603	int c, curr = -1;
    604	const hda_nid_t *list;
    605	int cache_len;
    606
    607	if (conn_len > 1 &&
    608	    wid_type != AC_WID_AUD_MIX &&
    609	    wid_type != AC_WID_VOL_KNB &&
    610	    wid_type != AC_WID_POWER)
    611		curr = snd_hda_codec_read(codec, nid, 0,
    612					  AC_VERB_GET_CONNECT_SEL, 0);
    613	snd_iprintf(buffer, "  Connection: %d\n", conn_len);
    614	if (conn_len > 0) {
    615		snd_iprintf(buffer, "    ");
    616		for (c = 0; c < conn_len; c++) {
    617			snd_iprintf(buffer, " 0x%02x", conn[c]);
    618			if (c == curr)
    619				snd_iprintf(buffer, "*");
    620		}
    621		snd_iprintf(buffer, "\n");
    622	}
    623
    624	/* Get Cache connections info */
    625	cache_len = snd_hda_get_conn_list(codec, nid, &list);
    626	if (cache_len >= 0 && (cache_len != conn_len ||
    627			      memcmp(list, conn, conn_len) != 0)) {
    628		snd_iprintf(buffer, "  In-driver Connection: %d\n", cache_len);
    629		if (cache_len > 0) {
    630			snd_iprintf(buffer, "    ");
    631			for (c = 0; c < cache_len; c++)
    632				snd_iprintf(buffer, " 0x%02x", list[c]);
    633			snd_iprintf(buffer, "\n");
    634		}
    635	}
    636}
    637
    638static void print_gpio(struct snd_info_buffer *buffer,
    639		       struct hda_codec *codec, hda_nid_t nid)
    640{
    641	unsigned int gpio =
    642		param_read(codec, codec->core.afg, AC_PAR_GPIO_CAP);
    643	unsigned int enable, direction, wake, unsol, sticky, data;
    644	int i, max;
    645	snd_iprintf(buffer, "GPIO: io=%d, o=%d, i=%d, "
    646		    "unsolicited=%d, wake=%d\n",
    647		    gpio & AC_GPIO_IO_COUNT,
    648		    (gpio & AC_GPIO_O_COUNT) >> AC_GPIO_O_COUNT_SHIFT,
    649		    (gpio & AC_GPIO_I_COUNT) >> AC_GPIO_I_COUNT_SHIFT,
    650		    (gpio & AC_GPIO_UNSOLICITED) ? 1 : 0,
    651		    (gpio & AC_GPIO_WAKE) ? 1 : 0);
    652	max = gpio & AC_GPIO_IO_COUNT;
    653	if (!max || max > 8)
    654		return;
    655	enable = snd_hda_codec_read(codec, nid, 0,
    656				    AC_VERB_GET_GPIO_MASK, 0);
    657	direction = snd_hda_codec_read(codec, nid, 0,
    658				       AC_VERB_GET_GPIO_DIRECTION, 0);
    659	wake = snd_hda_codec_read(codec, nid, 0,
    660				  AC_VERB_GET_GPIO_WAKE_MASK, 0);
    661	unsol  = snd_hda_codec_read(codec, nid, 0,
    662				    AC_VERB_GET_GPIO_UNSOLICITED_RSP_MASK, 0);
    663	sticky = snd_hda_codec_read(codec, nid, 0,
    664				    AC_VERB_GET_GPIO_STICKY_MASK, 0);
    665	data = snd_hda_codec_read(codec, nid, 0,
    666				  AC_VERB_GET_GPIO_DATA, 0);
    667	for (i = 0; i < max; ++i)
    668		snd_iprintf(buffer,
    669			    "  IO[%d]: enable=%d, dir=%d, wake=%d, "
    670			    "sticky=%d, data=%d, unsol=%d\n", i,
    671			    (enable & (1<<i)) ? 1 : 0,
    672			    (direction & (1<<i)) ? 1 : 0,
    673			    (wake & (1<<i)) ? 1 : 0,
    674			    (sticky & (1<<i)) ? 1 : 0,
    675			    (data & (1<<i)) ? 1 : 0,
    676			    (unsol & (1<<i)) ? 1 : 0);
    677	/* FIXME: add GPO and GPI pin information */
    678	print_nid_array(buffer, codec, nid, &codec->mixers);
    679	print_nid_array(buffer, codec, nid, &codec->nids);
    680}
    681
    682static void print_dpmst_connections(struct snd_info_buffer *buffer, struct hda_codec *codec,
    683				    hda_nid_t nid, int dev_num)
    684{
    685	int c, conn_len, curr, dev_id_saved;
    686	hda_nid_t *conn;
    687
    688	conn_len = snd_hda_get_num_raw_conns(codec, nid);
    689	if (conn_len <= 0)
    690		return;
    691
    692	conn = kmalloc_array(conn_len, sizeof(hda_nid_t), GFP_KERNEL);
    693	if (!conn)
    694		return;
    695
    696	dev_id_saved = snd_hda_get_dev_select(codec, nid);
    697
    698	snd_hda_set_dev_select(codec, nid, dev_num);
    699	curr = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
    700	if (snd_hda_get_raw_connections(codec, nid, conn, conn_len) < 0)
    701		goto out;
    702
    703	for (c = 0; c < conn_len; c++) {
    704		snd_iprintf(buffer, " 0x%02x", conn[c]);
    705		if (c == curr)
    706			snd_iprintf(buffer, "*");
    707	}
    708
    709out:
    710	kfree(conn);
    711	snd_hda_set_dev_select(codec, nid, dev_id_saved);
    712}
    713
    714static void print_device_list(struct snd_info_buffer *buffer,
    715			    struct hda_codec *codec, hda_nid_t nid)
    716{
    717	int i, curr = -1;
    718	u8 dev_list[AC_MAX_DEV_LIST_LEN];
    719	int devlist_len;
    720
    721	devlist_len = snd_hda_get_devices(codec, nid, dev_list,
    722					AC_MAX_DEV_LIST_LEN);
    723	snd_iprintf(buffer, "  Devices: %d\n", devlist_len);
    724	if (devlist_len <= 0)
    725		return;
    726
    727	curr = snd_hda_codec_read(codec, nid, 0,
    728				AC_VERB_GET_DEVICE_SEL, 0);
    729
    730	for (i = 0; i < devlist_len; i++) {
    731		if (i == curr)
    732			snd_iprintf(buffer, "    *");
    733		else
    734			snd_iprintf(buffer, "     ");
    735
    736		snd_iprintf(buffer,
    737			"Dev %02d: PD = %d, ELDV = %d, IA = %d, Connections [", i,
    738			!!(dev_list[i] & AC_DE_PD),
    739			!!(dev_list[i] & AC_DE_ELDV),
    740			!!(dev_list[i] & AC_DE_IA));
    741
    742		print_dpmst_connections(buffer, codec, nid, i);
    743
    744		snd_iprintf(buffer, " ]\n");
    745	}
    746}
    747
    748static void print_codec_core_info(struct hdac_device *codec,
    749				  struct snd_info_buffer *buffer)
    750{
    751	snd_iprintf(buffer, "Codec: ");
    752	if (codec->vendor_name && codec->chip_name)
    753		snd_iprintf(buffer, "%s %s\n",
    754			    codec->vendor_name, codec->chip_name);
    755	else
    756		snd_iprintf(buffer, "Not Set\n");
    757	snd_iprintf(buffer, "Address: %d\n", codec->addr);
    758	if (codec->afg)
    759		snd_iprintf(buffer, "AFG Function Id: 0x%x (unsol %u)\n",
    760			codec->afg_function_id, codec->afg_unsol);
    761	if (codec->mfg)
    762		snd_iprintf(buffer, "MFG Function Id: 0x%x (unsol %u)\n",
    763			codec->mfg_function_id, codec->mfg_unsol);
    764	snd_iprintf(buffer, "Vendor Id: 0x%08x\n", codec->vendor_id);
    765	snd_iprintf(buffer, "Subsystem Id: 0x%08x\n", codec->subsystem_id);
    766	snd_iprintf(buffer, "Revision Id: 0x%x\n", codec->revision_id);
    767
    768	if (codec->mfg)
    769		snd_iprintf(buffer, "Modem Function Group: 0x%x\n", codec->mfg);
    770	else
    771		snd_iprintf(buffer, "No Modem Function Group found\n");
    772}
    773
    774static void print_codec_info(struct snd_info_entry *entry,
    775			     struct snd_info_buffer *buffer)
    776{
    777	struct hda_codec *codec = entry->private_data;
    778	hda_nid_t nid, fg;
    779	int i, nodes;
    780
    781	print_codec_core_info(&codec->core, buffer);
    782	fg = codec->core.afg;
    783	if (!fg)
    784		return;
    785	snd_hda_power_up(codec);
    786	snd_iprintf(buffer, "Default PCM:\n");
    787	print_pcm_caps(buffer, codec, fg);
    788	snd_iprintf(buffer, "Default Amp-In caps: ");
    789	print_amp_caps(buffer, codec, fg, HDA_INPUT);
    790	snd_iprintf(buffer, "Default Amp-Out caps: ");
    791	print_amp_caps(buffer, codec, fg, HDA_OUTPUT);
    792	snd_iprintf(buffer, "State of AFG node 0x%02x:\n", fg);
    793	print_power_state(buffer, codec, fg);
    794
    795	nodes = snd_hda_get_sub_nodes(codec, fg, &nid);
    796	if (! nid || nodes < 0) {
    797		snd_iprintf(buffer, "Invalid AFG subtree\n");
    798		snd_hda_power_down(codec);
    799		return;
    800	}
    801
    802	print_gpio(buffer, codec, fg);
    803	if (codec->proc_widget_hook)
    804		codec->proc_widget_hook(buffer, codec, fg);
    805
    806	for (i = 0; i < nodes; i++, nid++) {
    807		unsigned int wid_caps =
    808			param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP);
    809		unsigned int wid_type = get_wcaps_type(wid_caps);
    810		hda_nid_t *conn = NULL;
    811		int conn_len = 0;
    812
    813		snd_iprintf(buffer, "Node 0x%02x [%s] wcaps 0x%x:", nid,
    814			    get_wid_type_name(wid_type), wid_caps);
    815		if (wid_caps & AC_WCAP_STEREO) {
    816			unsigned int chans = get_wcaps_channels(wid_caps);
    817			if (chans == 2)
    818				snd_iprintf(buffer, " Stereo");
    819			else
    820				snd_iprintf(buffer, " %d-Channels", chans);
    821		} else
    822			snd_iprintf(buffer, " Mono");
    823		if (wid_caps & AC_WCAP_DIGITAL)
    824			snd_iprintf(buffer, " Digital");
    825		if (wid_caps & AC_WCAP_IN_AMP)
    826			snd_iprintf(buffer, " Amp-In");
    827		if (wid_caps & AC_WCAP_OUT_AMP)
    828			snd_iprintf(buffer, " Amp-Out");
    829		if (wid_caps & AC_WCAP_STRIPE)
    830			snd_iprintf(buffer, " Stripe");
    831		if (wid_caps & AC_WCAP_LR_SWAP)
    832			snd_iprintf(buffer, " R/L");
    833		if (wid_caps & AC_WCAP_CP_CAPS)
    834			snd_iprintf(buffer, " CP");
    835		snd_iprintf(buffer, "\n");
    836
    837		print_nid_array(buffer, codec, nid, &codec->mixers);
    838		print_nid_array(buffer, codec, nid, &codec->nids);
    839		print_nid_pcms(buffer, codec, nid);
    840
    841		/* volume knob is a special widget that always have connection
    842		 * list
    843		 */
    844		if (wid_type == AC_WID_VOL_KNB)
    845			wid_caps |= AC_WCAP_CONN_LIST;
    846
    847		if (wid_caps & AC_WCAP_CONN_LIST) {
    848			conn_len = snd_hda_get_num_raw_conns(codec, nid);
    849			if (conn_len > 0) {
    850				conn = kmalloc_array(conn_len,
    851						     sizeof(hda_nid_t),
    852						     GFP_KERNEL);
    853				if (!conn)
    854					return;
    855				if (snd_hda_get_raw_connections(codec, nid, conn,
    856								conn_len) < 0)
    857					conn_len = 0;
    858			}
    859		}
    860
    861		if (wid_caps & AC_WCAP_IN_AMP) {
    862			snd_iprintf(buffer, "  Amp-In caps: ");
    863			print_amp_caps(buffer, codec, nid, HDA_INPUT);
    864			snd_iprintf(buffer, "  Amp-In vals: ");
    865			if (wid_type == AC_WID_PIN ||
    866			    (codec->single_adc_amp &&
    867			     wid_type == AC_WID_AUD_IN))
    868				print_amp_vals(buffer, codec, nid, HDA_INPUT,
    869					       wid_caps, 1);
    870			else
    871				print_amp_vals(buffer, codec, nid, HDA_INPUT,
    872					       wid_caps, conn_len);
    873		}
    874		if (wid_caps & AC_WCAP_OUT_AMP) {
    875			snd_iprintf(buffer, "  Amp-Out caps: ");
    876			print_amp_caps(buffer, codec, nid, HDA_OUTPUT);
    877			snd_iprintf(buffer, "  Amp-Out vals: ");
    878			if (wid_type == AC_WID_PIN &&
    879			    codec->pin_amp_workaround)
    880				print_amp_vals(buffer, codec, nid, HDA_OUTPUT,
    881					       wid_caps, conn_len);
    882			else
    883				print_amp_vals(buffer, codec, nid, HDA_OUTPUT,
    884					       wid_caps, 1);
    885		}
    886
    887		switch (wid_type) {
    888		case AC_WID_PIN: {
    889			int supports_vref;
    890			print_pin_caps(buffer, codec, nid, &supports_vref);
    891			print_pin_ctls(buffer, codec, nid, supports_vref);
    892			break;
    893		}
    894		case AC_WID_VOL_KNB:
    895			print_vol_knob(buffer, codec, nid);
    896			break;
    897		case AC_WID_AUD_OUT:
    898		case AC_WID_AUD_IN:
    899			print_audio_io(buffer, codec, nid, wid_type);
    900			if (wid_caps & AC_WCAP_DIGITAL)
    901				print_digital_conv(buffer, codec, nid);
    902			if (wid_caps & AC_WCAP_FORMAT_OVRD) {
    903				snd_iprintf(buffer, "  PCM:\n");
    904				print_pcm_caps(buffer, codec, nid);
    905			}
    906			break;
    907		}
    908
    909		if (wid_caps & AC_WCAP_UNSOL_CAP)
    910			print_unsol_cap(buffer, codec, nid);
    911
    912		if (wid_caps & AC_WCAP_POWER)
    913			print_power_state(buffer, codec, nid);
    914
    915		if (wid_caps & AC_WCAP_DELAY)
    916			snd_iprintf(buffer, "  Delay: %d samples\n",
    917				    (wid_caps & AC_WCAP_DELAY) >>
    918				    AC_WCAP_DELAY_SHIFT);
    919
    920		if (wid_type == AC_WID_PIN && codec->dp_mst)
    921			print_device_list(buffer, codec, nid);
    922
    923		if (wid_caps & AC_WCAP_CONN_LIST)
    924			print_conn_list(buffer, codec, nid, wid_type,
    925					conn, conn_len);
    926
    927		if (wid_caps & AC_WCAP_PROC_WID)
    928			print_proc_caps(buffer, codec, nid);
    929
    930		if (codec->proc_widget_hook)
    931			codec->proc_widget_hook(buffer, codec, nid);
    932
    933		kfree(conn);
    934	}
    935	snd_hda_power_down(codec);
    936}
    937
    938/*
    939 * create a proc read
    940 */
    941int snd_hda_codec_proc_new(struct hda_codec *codec)
    942{
    943	char name[32];
    944
    945	snprintf(name, sizeof(name), "codec#%d", codec->core.addr);
    946	return snd_card_ro_proc_new(codec->card, name, codec, print_codec_info);
    947}
    948