hda_proc.c 27 KB

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