hda_proc.c 27 KB

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