mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-05 10:29:37 +00:00
[ALSA] hda_proc - Add a number of new settings to proc codec output
This patch adds additional output to the /proc codec#X info. The following pieces of information are added to the output: - Balanced, L/R swap, trigger, impedance sense pin capabilities - Vref pin capabilities - Current Vref pin widget control setting - Default configuration association, sequence, and misc bit test - EAPD/BTL bits conveying balanced mode, EAPD, and L/R swap - Power state modified to show state name as well as setting vs actual value - GPIO parameter output on Audio Function Group, including enumeration of IO pins which are indicated present (Any I and O pins are not output at this time) - Stripe and L/R swap widget capabilities - All digital converter bits: enable, validity, validity config, preemphasis, copyright, non-audio, professional, generation level, and content category - Converter stream and channel values for in/out widgets - SDI select value for in widgets - Unsolicited response widget capability tag and enabled bit - Delay widget capability value - Processing widget capability benign bit and number of coefficients - Realtek Define Registers: processing coefficient, coefficient index [Also, fixed space/tab issues and make codes a bit more readable -- Takashi] Signed-off-by: Andrew Paprocki <andrew@ishiboo.com> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Jaroslav Kysela <perex@perex.cz>
This commit is contained in:
parent
e005954934
commit
797760ab14
2 changed files with 343 additions and 50 deletions
|
@ -84,7 +84,9 @@ enum {
|
|||
#define AC_VERB_GET_GPIO_DATA 0x0f15
|
||||
#define AC_VERB_GET_GPIO_MASK 0x0f16
|
||||
#define AC_VERB_GET_GPIO_DIRECTION 0x0f17
|
||||
#define AC_VERB_GET_GPIO_WAKE_MASK 0x0f18
|
||||
#define AC_VERB_GET_GPIO_UNSOLICITED_RSP_MASK 0x0f19
|
||||
#define AC_VERB_GET_GPIO_STICKY_MASK 0x0f1a
|
||||
#define AC_VERB_GET_CONFIG_DEFAULT 0x0f1c
|
||||
/* f20: AFG/MFG */
|
||||
#define AC_VERB_GET_SUBSYSTEM_ID 0x0f20
|
||||
|
@ -112,7 +114,9 @@ enum {
|
|||
#define AC_VERB_SET_GPIO_DATA 0x715
|
||||
#define AC_VERB_SET_GPIO_MASK 0x716
|
||||
#define AC_VERB_SET_GPIO_DIRECTION 0x717
|
||||
#define AC_VERB_SET_GPIO_WAKE_MASK 0x718
|
||||
#define AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK 0x719
|
||||
#define AC_VERB_SET_GPIO_STICKY_MASK 0x71a
|
||||
#define AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 0x71c
|
||||
#define AC_VERB_SET_CONFIG_DEFAULT_BYTES_1 0x71d
|
||||
#define AC_VERB_SET_CONFIG_DEFAULT_BYTES_2 0x71e
|
||||
|
@ -185,6 +189,27 @@ enum {
|
|||
#define AC_SUPFMT_FLOAT32 (1<<1)
|
||||
#define AC_SUPFMT_AC3 (1<<2)
|
||||
|
||||
/* GP I/O count */
|
||||
#define AC_GPIO_IO_COUNT (0xff<<0)
|
||||
#define AC_GPIO_O_COUNT (0xff<<8)
|
||||
#define AC_GPIO_O_COUNT_SHIFT 8
|
||||
#define AC_GPIO_I_COUNT (0xff<<16)
|
||||
#define AC_GPIO_I_COUNT_SHIFT 16
|
||||
#define AC_GPIO_UNSOLICITED (1<<30)
|
||||
#define AC_GPIO_WAKE (1<<31)
|
||||
|
||||
/* Converter stream, channel */
|
||||
#define AC_CONV_CHANNEL (0xf<<0)
|
||||
#define AC_CONV_STREAM (0xf<<4)
|
||||
#define AC_CONV_STREAM_SHIFT 4
|
||||
|
||||
/* Input converter SDI select */
|
||||
#define AC_SDI_SELECT (0xf<<0)
|
||||
|
||||
/* Unsolicited response */
|
||||
#define AC_UNSOL_TAG (0x3f<<0)
|
||||
#define AC_UNSOL_ENABLED (1<<7)
|
||||
|
||||
/* Pin widget capabilies */
|
||||
#define AC_PINCAP_IMP_SENSE (1<<0) /* impedance sense capable */
|
||||
#define AC_PINCAP_TRIG_REQ (1<<1) /* trigger required */
|
||||
|
@ -230,6 +255,9 @@ enum {
|
|||
#define AC_PWRST_D3SUP (1<<3)
|
||||
|
||||
/* Power state values */
|
||||
#define AC_PWRST_SETTING (0xf<<0)
|
||||
#define AC_PWRST_ACTUAL (0xf<<4)
|
||||
#define AC_PWRST_ACTUAL_SHIFT 4
|
||||
#define AC_PWRST_D0 0x00
|
||||
#define AC_PWRST_D1 0x01
|
||||
#define AC_PWRST_D2 0x02
|
||||
|
@ -238,6 +266,7 @@ enum {
|
|||
/* Processing capabilies */
|
||||
#define AC_PCAP_BENIGN (1<<0)
|
||||
#define AC_PCAP_NUM_COEF (0xff<<8)
|
||||
#define AC_PCAP_NUM_COEF_SHIFT 8
|
||||
|
||||
/* Volume knobs capabilities */
|
||||
#define AC_KNBCAP_NUM_STEPS (0x7f<<0)
|
||||
|
@ -274,6 +303,9 @@ enum {
|
|||
#define AC_DIG1_PROFESSIONAL (1<<6)
|
||||
#define AC_DIG1_LEVEL (1<<7)
|
||||
|
||||
/* DIGITAL2 bits */
|
||||
#define AC_DIG2_CC (0x7f<<0)
|
||||
|
||||
/* Pin widget control - 8bit */
|
||||
#define AC_PINCTL_VREFEN (0x7<<0)
|
||||
#define AC_PINCTL_VREF_HIZ 0 /* Hi-Z */
|
||||
|
@ -288,12 +320,22 @@ enum {
|
|||
/* Unsolicited response - 8bit */
|
||||
#define AC_USRSP_EN (1<<7)
|
||||
|
||||
/* Pin sense - 32bit */
|
||||
#define AC_PINSENSE_IMPEDANCE_MASK (0x7fffffff)
|
||||
#define AC_PINSENSE_PRESENCE (1<<31)
|
||||
|
||||
/* EAPD/BTL enable - 32bit */
|
||||
#define AC_EAPDBTL_BALANCED (1<<0)
|
||||
#define AC_EAPDBTL_EAPD (1<<1)
|
||||
#define AC_EAPDBTL_LR_SWAP (1<<2)
|
||||
|
||||
/* configuration default - 32bit */
|
||||
#define AC_DEFCFG_SEQUENCE (0xf<<0)
|
||||
#define AC_DEFCFG_DEF_ASSOC (0xf<<4)
|
||||
#define AC_DEFCFG_ASSOC_SHIFT 4
|
||||
#define AC_DEFCFG_MISC (0xf<<8)
|
||||
#define AC_DEFCFG_MISC_SHIFT 8
|
||||
#define AC_DEFCFG_MISC_NO_PRESENCE (1<<0)
|
||||
#define AC_DEFCFG_COLOR (0xf<<12)
|
||||
#define AC_DEFCFG_COLOR_SHIFT 12
|
||||
#define AC_DEFCFG_CONN_TYPE (0xf<<16)
|
||||
|
|
|
@ -202,7 +202,8 @@ static const char *get_jack_color(u32 cfg)
|
|||
}
|
||||
|
||||
static void print_pin_caps(struct snd_info_buffer *buffer,
|
||||
struct hda_codec *codec, hda_nid_t nid)
|
||||
struct hda_codec *codec, hda_nid_t nid,
|
||||
int *supports_vref)
|
||||
{
|
||||
static char *jack_conns[4] = { "Jack", "N/A", "Fixed", "Both" };
|
||||
static char *jack_types[16] = {
|
||||
|
@ -226,7 +227,45 @@ static void print_pin_caps(struct snd_info_buffer *buffer,
|
|||
snd_iprintf(buffer, " EAPD");
|
||||
if (caps & AC_PINCAP_PRES_DETECT)
|
||||
snd_iprintf(buffer, " Detect");
|
||||
if (caps & AC_PINCAP_BALANCE)
|
||||
snd_iprintf(buffer, " Balanced");
|
||||
if (caps & AC_PINCAP_LR_SWAP)
|
||||
snd_iprintf(buffer, " R/L");
|
||||
if (caps & AC_PINCAP_TRIG_REQ)
|
||||
snd_iprintf(buffer, " Trigger");
|
||||
if (caps & AC_PINCAP_IMP_SENSE)
|
||||
snd_iprintf(buffer, " ImpSense");
|
||||
snd_iprintf(buffer, "\n");
|
||||
if (caps & AC_PINCAP_VREF) {
|
||||
unsigned int vref =
|
||||
(caps & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
|
||||
snd_iprintf(buffer, " Vref caps:");
|
||||
if (vref & AC_PINCAP_VREF_HIZ)
|
||||
snd_iprintf(buffer, " HIZ");
|
||||
if (vref & AC_PINCAP_VREF_50)
|
||||
snd_iprintf(buffer, " 50");
|
||||
if (vref & AC_PINCAP_VREF_GRD)
|
||||
snd_iprintf(buffer, " GRD");
|
||||
if (vref & AC_PINCAP_VREF_80)
|
||||
snd_iprintf(buffer, " 80");
|
||||
if (vref & AC_PINCAP_VREF_100)
|
||||
snd_iprintf(buffer, " 100");
|
||||
snd_iprintf(buffer, "\n");
|
||||
*supports_vref = 1;
|
||||
} else
|
||||
*supports_vref = 0;
|
||||
if (caps & AC_PINCAP_EAPD) {
|
||||
val = snd_hda_codec_read(codec, nid, 0,
|
||||
AC_VERB_GET_EAPD_BTLENABLE, 0);
|
||||
snd_iprintf(buffer, " EAPD 0x%x:", val);
|
||||
if (val & AC_EAPDBTL_BALANCED)
|
||||
snd_iprintf(buffer, " BALANCED");
|
||||
if (val & AC_EAPDBTL_EAPD)
|
||||
snd_iprintf(buffer, " EAPD");
|
||||
if (val & AC_EAPDBTL_LR_SWAP)
|
||||
snd_iprintf(buffer, " R/L");
|
||||
snd_iprintf(buffer, "\n");
|
||||
}
|
||||
caps = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONFIG_DEFAULT, 0);
|
||||
snd_iprintf(buffer, " Pin Default 0x%08x: [%s] %s at %s %s\n", caps,
|
||||
jack_conns[(caps & AC_DEFCFG_PORT_CONN) >> AC_DEFCFG_PORT_CONN_SHIFT],
|
||||
|
@ -236,13 +275,233 @@ static void print_pin_caps(struct snd_info_buffer *buffer,
|
|||
snd_iprintf(buffer, " Conn = %s, Color = %s\n",
|
||||
get_jack_connection(caps),
|
||||
get_jack_color(caps));
|
||||
if (caps & AC_PINCAP_EAPD) {
|
||||
val = snd_hda_codec_read(codec, nid, 0,
|
||||
AC_VERB_GET_EAPD_BTLENABLE, 0);
|
||||
snd_iprintf(buffer, " EAPD: 0x%x\n", val);
|
||||
/* Default association and sequence values refer to default grouping
|
||||
* of pin complexes and their sequence within the group. This is used
|
||||
* for priority and resource allocation.
|
||||
*/
|
||||
snd_iprintf(buffer, " DefAssociation = 0x%x, Sequence = 0x%x\n",
|
||||
(caps & AC_DEFCFG_DEF_ASSOC) >> AC_DEFCFG_ASSOC_SHIFT,
|
||||
caps & AC_DEFCFG_SEQUENCE);
|
||||
if (((caps & AC_DEFCFG_MISC) >> AC_DEFCFG_MISC_SHIFT) &
|
||||
AC_DEFCFG_MISC_NO_PRESENCE) {
|
||||
/* Miscellaneous bit indicates external hardware does not
|
||||
* support presence detection even if the pin complex
|
||||
* indicates it is supported.
|
||||
*/
|
||||
snd_iprintf(buffer, " Misc = NO_PRESENCE\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void print_pin_ctls(struct snd_info_buffer *buffer,
|
||||
struct hda_codec *codec, hda_nid_t nid,
|
||||
int supports_vref)
|
||||
{
|
||||
unsigned int pinctls;
|
||||
|
||||
pinctls = snd_hda_codec_read(codec, nid, 0,
|
||||
AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
|
||||
snd_iprintf(buffer, " Pin-ctls: 0x%02x:", pinctls);
|
||||
if (pinctls & AC_PINCTL_IN_EN)
|
||||
snd_iprintf(buffer, " IN");
|
||||
if (pinctls & AC_PINCTL_OUT_EN)
|
||||
snd_iprintf(buffer, " OUT");
|
||||
if (pinctls & AC_PINCTL_HP_EN)
|
||||
snd_iprintf(buffer, " HP");
|
||||
if (supports_vref) {
|
||||
int vref = pinctls & AC_PINCTL_VREFEN;
|
||||
switch (vref) {
|
||||
case AC_PINCTL_VREF_HIZ:
|
||||
snd_iprintf(buffer, " VREF_HIZ");
|
||||
break;
|
||||
case AC_PINCTL_VREF_50:
|
||||
snd_iprintf(buffer, " VREF_50");
|
||||
break;
|
||||
case AC_PINCTL_VREF_GRD:
|
||||
snd_iprintf(buffer, " VREF_GRD");
|
||||
break;
|
||||
case AC_PINCTL_VREF_80:
|
||||
snd_iprintf(buffer, " VREF_80");
|
||||
break;
|
||||
case AC_PINCTL_VREF_100:
|
||||
snd_iprintf(buffer, " VREF_100");
|
||||
break;
|
||||
}
|
||||
}
|
||||
snd_iprintf(buffer, "\n");
|
||||
}
|
||||
|
||||
static void print_vol_knob(struct snd_info_buffer *buffer,
|
||||
struct hda_codec *codec, hda_nid_t nid)
|
||||
{
|
||||
unsigned int cap = snd_hda_param_read(codec, nid,
|
||||
AC_PAR_VOL_KNB_CAP);
|
||||
snd_iprintf(buffer, " Volume-Knob: delta=%d, steps=%d, ",
|
||||
(cap >> 7) & 1, cap & 0x7f);
|
||||
cap = snd_hda_codec_read(codec, nid, 0,
|
||||
AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
|
||||
snd_iprintf(buffer, "direct=%d, val=%d\n",
|
||||
(cap >> 7) & 1, cap & 0x7f);
|
||||
}
|
||||
|
||||
static void print_audio_io(struct snd_info_buffer *buffer,
|
||||
struct hda_codec *codec, hda_nid_t nid,
|
||||
unsigned int wid_type)
|
||||
{
|
||||
int conv = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0);
|
||||
snd_iprintf(buffer,
|
||||
" Converter: stream=%d, channel=%d\n",
|
||||
(conv & AC_CONV_STREAM) >> AC_CONV_STREAM_SHIFT,
|
||||
conv & AC_CONV_CHANNEL);
|
||||
|
||||
if (wid_type == AC_WID_AUD_IN && (conv & AC_CONV_CHANNEL) == 0) {
|
||||
int sdi = snd_hda_codec_read(codec, nid, 0,
|
||||
AC_VERB_GET_SDI_SELECT, 0);
|
||||
snd_iprintf(buffer, " SDI-Select: %d\n",
|
||||
sdi & AC_SDI_SELECT);
|
||||
}
|
||||
}
|
||||
|
||||
static void print_digital_conv(struct snd_info_buffer *buffer,
|
||||
struct hda_codec *codec, hda_nid_t nid)
|
||||
{
|
||||
unsigned int digi1 = snd_hda_codec_read(codec, nid, 0,
|
||||
AC_VERB_GET_DIGI_CONVERT_1, 0);
|
||||
unsigned int digi2 = snd_hda_codec_read(codec, nid, 0,
|
||||
AC_VERB_GET_DIGI_CONVERT_2, 0);
|
||||
snd_iprintf(buffer, " Digital:");
|
||||
if (digi1 & AC_DIG1_ENABLE)
|
||||
snd_iprintf(buffer, " Enabled");
|
||||
if (digi1 & AC_DIG1_V)
|
||||
snd_iprintf(buffer, " Validity");
|
||||
if (digi1 & AC_DIG1_VCFG)
|
||||
snd_iprintf(buffer, " ValidityCfg");
|
||||
if (digi1 & AC_DIG1_EMPHASIS)
|
||||
snd_iprintf(buffer, " Preemphasis");
|
||||
if (digi1 & AC_DIG1_COPYRIGHT)
|
||||
snd_iprintf(buffer, " Copyright");
|
||||
if (digi1 & AC_DIG1_NONAUDIO)
|
||||
snd_iprintf(buffer, " Non-Audio");
|
||||
if (digi1 & AC_DIG1_PROFESSIONAL)
|
||||
snd_iprintf(buffer, " Pro");
|
||||
if (digi1 & AC_DIG1_LEVEL)
|
||||
snd_iprintf(buffer, " GenLevel");
|
||||
snd_iprintf(buffer, "\n");
|
||||
snd_iprintf(buffer, " Digital category: 0x%x\n", digi2 & AC_DIG2_CC);
|
||||
}
|
||||
|
||||
static const char *get_pwr_state(u32 state)
|
||||
{
|
||||
static const char *buf[4] = {
|
||||
"D0", "D1", "D2", "D3"
|
||||
};
|
||||
if (state < 4)
|
||||
return buf[state];
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
||||
static void print_power_state(struct snd_info_buffer *buffer,
|
||||
struct hda_codec *codec, hda_nid_t nid)
|
||||
{
|
||||
int pwr = snd_hda_codec_read(codec, nid, 0,
|
||||
AC_VERB_GET_POWER_STATE, 0);
|
||||
snd_iprintf(buffer, " Power: setting=%s, actual=%s\n",
|
||||
get_pwr_state(pwr & AC_PWRST_SETTING),
|
||||
get_pwr_state((pwr & AC_PWRST_ACTUAL) >>
|
||||
AC_PWRST_ACTUAL_SHIFT));
|
||||
}
|
||||
|
||||
static void print_unsol_cap(struct snd_info_buffer *buffer,
|
||||
struct hda_codec *codec, hda_nid_t nid)
|
||||
{
|
||||
int unsol = snd_hda_codec_read(codec, nid, 0,
|
||||
AC_VERB_GET_UNSOLICITED_RESPONSE, 0);
|
||||
snd_iprintf(buffer,
|
||||
" Unsolicited: tag=%02x, enabled=%d\n",
|
||||
unsol & AC_UNSOL_TAG,
|
||||
(unsol & AC_UNSOL_ENABLED) ? 1 : 0);
|
||||
}
|
||||
|
||||
static void print_proc_caps(struct snd_info_buffer *buffer,
|
||||
struct hda_codec *codec, hda_nid_t nid)
|
||||
{
|
||||
unsigned int proc_caps = snd_hda_param_read(codec, nid,
|
||||
AC_PAR_PROC_CAP);
|
||||
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);
|
||||
}
|
||||
|
||||
static void print_conn_list(struct snd_info_buffer *buffer,
|
||||
struct hda_codec *codec, hda_nid_t nid,
|
||||
unsigned int wid_type, hda_nid_t *conn,
|
||||
int conn_len)
|
||||
{
|
||||
int c, curr = -1;
|
||||
|
||||
if (conn_len > 1 && wid_type != AC_WID_AUD_MIX)
|
||||
curr = snd_hda_codec_read(codec, nid, 0,
|
||||
AC_VERB_GET_CONNECT_SEL, 0);
|
||||
snd_iprintf(buffer, " Connection: %d\n", conn_len);
|
||||
if (conn_len > 0) {
|
||||
snd_iprintf(buffer, " ");
|
||||
for (c = 0; c < conn_len; c++) {
|
||||
snd_iprintf(buffer, " 0x%02x", conn[c]);
|
||||
if (c == curr)
|
||||
snd_iprintf(buffer, "*");
|
||||
}
|
||||
snd_iprintf(buffer, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void print_realtek_coef(struct snd_info_buffer *buffer,
|
||||
struct hda_codec *codec, hda_nid_t nid)
|
||||
{
|
||||
int coeff = snd_hda_codec_read(codec, nid, 0,
|
||||
AC_VERB_GET_PROC_COEF, 0);
|
||||
snd_iprintf(buffer, " Processing Coefficient: 0x%02x\n", coeff);
|
||||
coeff = snd_hda_codec_read(codec, nid, 0,
|
||||
AC_VERB_GET_COEF_INDEX, 0);
|
||||
snd_iprintf(buffer, " Coefficient Index: 0x%02x\n", coeff);
|
||||
}
|
||||
|
||||
static void print_gpio(struct snd_info_buffer *buffer,
|
||||
struct hda_codec *codec, hda_nid_t nid)
|
||||
{
|
||||
unsigned int gpio =
|
||||
snd_hda_param_read(codec, codec->afg, AC_PAR_GPIO_CAP);
|
||||
unsigned int enable, direction, wake, unsol, sticky, data;
|
||||
int i, max;
|
||||
snd_iprintf(buffer, "GPIO: io=%d, o=%d, i=%d, "
|
||||
"unsolicited=%d, wake=%d\n",
|
||||
gpio & AC_GPIO_IO_COUNT,
|
||||
(gpio & AC_GPIO_O_COUNT) >> AC_GPIO_O_COUNT_SHIFT,
|
||||
(gpio & AC_GPIO_I_COUNT) >> AC_GPIO_I_COUNT_SHIFT,
|
||||
(gpio & AC_GPIO_UNSOLICITED) ? 1 : 0,
|
||||
(gpio & AC_GPIO_WAKE) ? 1 : 0);
|
||||
max = gpio & AC_GPIO_IO_COUNT;
|
||||
enable = snd_hda_codec_read(codec, nid, 0,
|
||||
AC_VERB_GET_GPIO_MASK, 0);
|
||||
direction = snd_hda_codec_read(codec, nid, 0,
|
||||
AC_VERB_GET_GPIO_DIRECTION, 0);
|
||||
wake = snd_hda_codec_read(codec, nid, 0,
|
||||
AC_VERB_GET_GPIO_WAKE_MASK, 0);
|
||||
unsol = snd_hda_codec_read(codec, nid, 0,
|
||||
AC_VERB_GET_GPIO_UNSOLICITED_RSP_MASK, 0);
|
||||
sticky = snd_hda_codec_read(codec, nid, 0,
|
||||
AC_VERB_GET_GPIO_STICKY_MASK, 0);
|
||||
data = snd_hda_codec_read(codec, nid, 0,
|
||||
AC_VERB_GET_GPIO_DATA, 0);
|
||||
for (i = 0; i < max; ++i)
|
||||
snd_iprintf(buffer,
|
||||
" IO[%d]: enable=%d, dir=%d, wake=%d, "
|
||||
"sticky=%d, data=%d\n", i,
|
||||
(enable & (1<<i)) ? 1 : 0,
|
||||
(direction & (1<<i)) ? 1 : 0,
|
||||
(wake & (1<<i)) ? 1 : 0,
|
||||
(sticky & (1<<i)) ? 1 : 0,
|
||||
(data & (1<<i)) ? 1 : 0);
|
||||
/* FIXME: add GPO and GPI pin information */
|
||||
}
|
||||
|
||||
static void print_codec_info(struct snd_info_entry *entry,
|
||||
struct snd_info_buffer *buffer)
|
||||
|
@ -280,15 +539,17 @@ static void print_codec_info(struct snd_info_entry *entry,
|
|||
snd_hda_power_down(codec);
|
||||
return;
|
||||
}
|
||||
|
||||
print_gpio(buffer, codec, codec->afg);
|
||||
|
||||
for (i = 0; i < nodes; i++, nid++) {
|
||||
unsigned int wid_caps =
|
||||
snd_hda_param_read(codec, nid,
|
||||
AC_PAR_AUDIO_WIDGET_CAP);
|
||||
unsigned int wid_type =
|
||||
(wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
|
||||
int conn_len = 0;
|
||||
hda_nid_t conn[HDA_MAX_CONNECTIONS];
|
||||
unsigned int pinctls;
|
||||
int conn_len = 0;
|
||||
|
||||
snd_iprintf(buffer, "Node 0x%02x [%s] wcaps 0x%x:", nid,
|
||||
get_wid_type_name(wid_type), wid_caps);
|
||||
|
@ -302,6 +563,10 @@ static void print_codec_info(struct snd_info_entry *entry,
|
|||
snd_iprintf(buffer, " Amp-In");
|
||||
if (wid_caps & AC_WCAP_OUT_AMP)
|
||||
snd_iprintf(buffer, " Amp-Out");
|
||||
if (wid_caps & AC_WCAP_STRIPE)
|
||||
snd_iprintf(buffer, " Stripe");
|
||||
if (wid_caps & AC_WCAP_LR_SWAP)
|
||||
snd_iprintf(buffer, " R/L");
|
||||
snd_iprintf(buffer, "\n");
|
||||
|
||||
/* volume knob is a special widget that always have connection
|
||||
|
@ -330,33 +595,20 @@ static void print_codec_info(struct snd_info_entry *entry,
|
|||
}
|
||||
|
||||
switch (wid_type) {
|
||||
case AC_WID_PIN:
|
||||
print_pin_caps(buffer, codec, nid);
|
||||
pinctls = snd_hda_codec_read(codec, nid, 0,
|
||||
AC_VERB_GET_PIN_WIDGET_CONTROL,
|
||||
0);
|
||||
snd_iprintf(buffer, " Pin-ctls: 0x%02x:", pinctls);
|
||||
if (pinctls & AC_PINCTL_IN_EN)
|
||||
snd_iprintf(buffer, " IN");
|
||||
if (pinctls & AC_PINCTL_OUT_EN)
|
||||
snd_iprintf(buffer, " OUT");
|
||||
if (pinctls & AC_PINCTL_HP_EN)
|
||||
snd_iprintf(buffer, " HP");
|
||||
snd_iprintf(buffer, "\n");
|
||||
case AC_WID_PIN: {
|
||||
int supports_vref;
|
||||
print_pin_caps(buffer, codec, nid, &supports_vref);
|
||||
print_pin_ctls(buffer, codec, nid, supports_vref);
|
||||
break;
|
||||
}
|
||||
case AC_WID_VOL_KNB:
|
||||
pinctls = snd_hda_param_read(codec, nid,
|
||||
AC_PAR_VOL_KNB_CAP);
|
||||
snd_iprintf(buffer, " Volume-Knob: delta=%d, "
|
||||
"steps=%d, ",
|
||||
(pinctls >> 7) & 1, pinctls & 0x7f);
|
||||
pinctls = snd_hda_codec_read(codec, nid, 0,
|
||||
AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
|
||||
snd_iprintf(buffer, "direct=%d, val=%d\n",
|
||||
(pinctls >> 7) & 1, pinctls & 0x7f);
|
||||
print_vol_knob(buffer, codec, nid);
|
||||
break;
|
||||
case AC_WID_AUD_OUT:
|
||||
case AC_WID_AUD_IN:
|
||||
print_audio_io(buffer, codec, nid, wid_type);
|
||||
if (wid_caps & AC_WCAP_DIGITAL)
|
||||
print_digital_conv(buffer, codec, nid);
|
||||
if (wid_caps & AC_WCAP_FORMAT_OVRD) {
|
||||
snd_iprintf(buffer, " PCM:\n");
|
||||
print_pcm_caps(buffer, codec, nid);
|
||||
|
@ -364,28 +616,27 @@ static void print_codec_info(struct snd_info_entry *entry,
|
|||
break;
|
||||
}
|
||||
|
||||
if (wid_caps & AC_WCAP_POWER)
|
||||
snd_iprintf(buffer, " Power: 0x%x\n",
|
||||
snd_hda_codec_read(codec, nid, 0,
|
||||
AC_VERB_GET_POWER_STATE,
|
||||
0));
|
||||
if (wid_caps & AC_WCAP_UNSOL_CAP)
|
||||
print_unsol_cap(buffer, codec, nid);
|
||||
|
||||
if (wid_caps & AC_WCAP_CONN_LIST) {
|
||||
int c, curr = -1;
|
||||
if (conn_len > 1 && wid_type != AC_WID_AUD_MIX)
|
||||
curr = snd_hda_codec_read(codec, nid, 0,
|
||||
AC_VERB_GET_CONNECT_SEL, 0);
|
||||
snd_iprintf(buffer, " Connection: %d\n", conn_len);
|
||||
if (conn_len > 0) {
|
||||
snd_iprintf(buffer, " ");
|
||||
for (c = 0; c < conn_len; c++) {
|
||||
snd_iprintf(buffer, " 0x%02x", conn[c]);
|
||||
if (c == curr)
|
||||
snd_iprintf(buffer, "*");
|
||||
}
|
||||
snd_iprintf(buffer, "\n");
|
||||
}
|
||||
}
|
||||
if (wid_caps & AC_WCAP_POWER)
|
||||
print_power_state(buffer, codec, nid);
|
||||
|
||||
if (wid_caps & AC_WCAP_DELAY)
|
||||
snd_iprintf(buffer, " Delay: %d samples\n",
|
||||
(wid_caps & AC_WCAP_DELAY) >>
|
||||
AC_WCAP_DELAY_SHIFT);
|
||||
|
||||
if (wid_caps & AC_WCAP_CONN_LIST)
|
||||
print_conn_list(buffer, codec, nid, wid_type,
|
||||
conn, conn_len);
|
||||
|
||||
if (wid_caps & AC_WCAP_PROC_WID)
|
||||
print_proc_caps(buffer, codec, nid);
|
||||
|
||||
/* NID 0x20 == Realtek Define Registers */
|
||||
if (codec->vendor_id == 0x10ec && nid == 0x20)
|
||||
print_realtek_coef(buffer, codec, nid);
|
||||
}
|
||||
snd_hda_power_down(codec);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue