diff options
Diffstat (limited to 'sound/pci/hda/hda_proc.c')
| -rw-r--r-- | sound/pci/hda/hda_proc.c | 67 |
1 files changed, 65 insertions, 2 deletions
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c index 9760f001916..ce5a6da8341 100644 --- a/sound/pci/hda/hda_proc.c +++ b/sound/pci/hda/hda_proc.c @@ -24,9 +24,14 @@ #include <linux/init.h> #include <linux/slab.h> #include <sound/core.h> +#include <linux/module.h> #include "hda_codec.h" #include "hda_local.h" +static int dump_coef = -1; +module_param(dump_coef, int, 0644); +MODULE_PARM_DESC(dump_coef, "Dump processing coefficients in codec proc file (-1=auto, 0=disable, 1=enable)"); + static char *bits_names(unsigned int bits, char *names[], int size) { int i, n; @@ -488,14 +493,39 @@ static void print_unsol_cap(struct snd_info_buffer *buffer, (unsol & AC_UNSOL_ENABLED) ? 1 : 0); } +static inline bool can_dump_coef(struct hda_codec *codec) +{ + switch (dump_coef) { + case 0: return false; + case 1: return true; + default: return codec->dump_coef; + } +} + static void print_proc_caps(struct snd_info_buffer *buffer, struct hda_codec *codec, hda_nid_t nid) { + unsigned int i, ncoeff, oldindex; unsigned int proc_caps = snd_hda_param_read(codec, nid, AC_PAR_PROC_CAP); + ncoeff = (proc_caps & AC_PCAP_NUM_COEF) >> AC_PCAP_NUM_COEF_SHIFT; snd_iprintf(buffer, " Processing caps: benign=%d, ncoeff=%d\n", - proc_caps & AC_PCAP_BENIGN, - (proc_caps & AC_PCAP_NUM_COEF) >> AC_PCAP_NUM_COEF_SHIFT); + proc_caps & AC_PCAP_BENIGN, ncoeff); + + if (!can_dump_coef(codec)) + return; + + /* Note: This is racy - another process could run in parallel and change + the coef index too. */ + oldindex = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_COEF_INDEX, 0); + for (i = 0; i < ncoeff; i++) { + unsigned int val; + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, i); + val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PROC_COEF, + 0); + snd_iprintf(buffer, " Coeff 0x%02x: 0x%04x\n", i, val); + } + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, oldindex); } static void print_conn_list(struct snd_info_buffer *buffer, @@ -582,6 +612,36 @@ static void print_gpio(struct snd_info_buffer *buffer, print_nid_array(buffer, codec, nid, &codec->nids); } +static void print_device_list(struct snd_info_buffer *buffer, + struct hda_codec *codec, hda_nid_t nid) +{ + int i, curr = -1; + u8 dev_list[AC_MAX_DEV_LIST_LEN]; + int devlist_len; + + devlist_len = snd_hda_get_devices(codec, nid, dev_list, + AC_MAX_DEV_LIST_LEN); + snd_iprintf(buffer, " Devices: %d\n", devlist_len); + if (devlist_len <= 0) + return; + + curr = snd_hda_codec_read(codec, nid, 0, + AC_VERB_GET_DEVICE_SEL, 0); + + for (i = 0; i < devlist_len; i++) { + if (i == curr) + snd_iprintf(buffer, " *"); + else + snd_iprintf(buffer, " "); + + snd_iprintf(buffer, + "Dev %02d: PD = %d, ELDV = %d, IA = %d\n", i, + !!(dev_list[i] & AC_DE_PD), + !!(dev_list[i] & AC_DE_ELDV), + !!(dev_list[i] & AC_DE_IA)); + } +} + static void print_codec_info(struct snd_info_entry *entry, struct snd_info_buffer *buffer) { @@ -751,6 +811,9 @@ static void print_codec_info(struct snd_info_entry *entry, (wid_caps & AC_WCAP_DELAY) >> AC_WCAP_DELAY_SHIFT); + if (wid_type == AC_WID_PIN && codec->dp_mst) + print_device_list(buffer, codec, nid); + if (wid_caps & AC_WCAP_CONN_LIST) print_conn_list(buffer, codec, nid, wid_type, conn, conn_len); |
