提交 797760ab 编写于 作者: A Andrew Paprocki 提交者: Jaroslav Kysela

[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: NAndrew Paprocki <andrew@ishiboo.com>
Signed-off-by: NTakashi Iwai <tiwai@suse.de>
Signed-off-by: NJaroslav Kysela <perex@perex.cz>
上级 e0059549
......@@ -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_UNSOL_CAP)
print_unsol_cap(buffer, codec, nid);
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_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");
}
}
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);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册