Commit 1327a32b authored by Takashi Iwai's avatar Takashi Iwai

ALSA: hda - Cache pin-cap values

Added snd_hda_query_pin_caps() to read and cache pin-cap values
to avoid too frequently issuing the same verbs.
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 52ca15b7
...@@ -1052,6 +1052,7 @@ EXPORT_SYMBOL_HDA(snd_hda_codec_cleanup_stream); ...@@ -1052,6 +1052,7 @@ EXPORT_SYMBOL_HDA(snd_hda_codec_cleanup_stream);
/* FIXME: more better hash key? */ /* FIXME: more better hash key? */
#define HDA_HASH_KEY(nid,dir,idx) (u32)((nid) + ((idx) << 16) + ((dir) << 24)) #define HDA_HASH_KEY(nid,dir,idx) (u32)((nid) + ((idx) << 16) + ((dir) << 24))
#define HDA_HASH_PINCAP_KEY(nid) (u32)((nid) + (0x02 << 24))
#define INFO_AMP_CAPS (1<<0) #define INFO_AMP_CAPS (1<<0)
#define INFO_AMP_VOL(ch) (1 << (1 + (ch))) #define INFO_AMP_VOL(ch) (1 << (1 + (ch)))
...@@ -1142,6 +1143,21 @@ int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir, ...@@ -1142,6 +1143,21 @@ int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir,
} }
EXPORT_SYMBOL_HDA(snd_hda_override_amp_caps); EXPORT_SYMBOL_HDA(snd_hda_override_amp_caps);
u32 snd_hda_query_pin_caps(struct hda_codec *codec, hda_nid_t nid)
{
struct hda_amp_info *info;
info = get_alloc_amp_hash(codec, HDA_HASH_PINCAP_KEY(nid));
if (!info)
return 0;
if (!info->head.val) {
info->amp_caps = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
info->head.val |= INFO_AMP_CAPS;
}
return info->amp_caps;
}
EXPORT_SYMBOL_HDA(snd_hda_query_pin_caps);
/* /*
* read the current volume to info * read the current volume to info
* if the cache exists, read the cache value. * if the cache exists, read the cache value.
......
...@@ -144,7 +144,7 @@ static int add_new_node(struct hda_codec *codec, struct hda_gspec *spec, hda_nid ...@@ -144,7 +144,7 @@ static int add_new_node(struct hda_codec *codec, struct hda_gspec *spec, hda_nid
node->type = (node->wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; node->type = (node->wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
if (node->type == AC_WID_PIN) { if (node->type == AC_WID_PIN) {
node->pin_caps = snd_hda_param_read(codec, node->nid, AC_PAR_PIN_CAP); node->pin_caps = snd_hda_query_pin_caps(codec, node->nid);
node->pin_ctl = snd_hda_codec_read(codec, node->nid, 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0); node->pin_ctl = snd_hda_codec_read(codec, node->nid, 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
node->def_cfg = snd_hda_codec_get_pincfg(codec, node->nid); node->def_cfg = snd_hda_codec_get_pincfg(codec, node->nid);
} }
......
...@@ -411,6 +411,7 @@ static inline u32 get_wcaps(struct hda_codec *codec, hda_nid_t nid) ...@@ -411,6 +411,7 @@ static inline u32 get_wcaps(struct hda_codec *codec, hda_nid_t nid)
u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction); u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction);
int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir, int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir,
unsigned int caps); unsigned int caps);
u32 snd_hda_query_pin_caps(struct hda_codec *codec, hda_nid_t nid);
int snd_hda_ctl_add(struct hda_codec *codec, struct snd_kcontrol *kctl); int snd_hda_ctl_add(struct hda_codec *codec, struct snd_kcontrol *kctl);
void snd_hda_ctls_clear(struct hda_codec *codec); void snd_hda_ctls_clear(struct hda_codec *codec);
......
...@@ -770,7 +770,7 @@ static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid, ...@@ -770,7 +770,7 @@ static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
if (auto_pin_type <= AUTO_PIN_FRONT_MIC) { if (auto_pin_type <= AUTO_PIN_FRONT_MIC) {
unsigned int pincap; unsigned int pincap;
pincap = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP); pincap = snd_hda_query_pin_caps(codec, nid);
pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT; pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
if (pincap & AC_PINCAP_VREF_80) if (pincap & AC_PINCAP_VREF_80)
val = PIN_VREF80; val = PIN_VREF80;
...@@ -16746,13 +16746,13 @@ static int alc662_input_pin_idx(struct hda_codec *codec, hda_nid_t nid, ...@@ -16746,13 +16746,13 @@ static int alc662_input_pin_idx(struct hda_codec *codec, hda_nid_t nid,
static int alc662_is_input_pin(struct hda_codec *codec, hda_nid_t nid) static int alc662_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
{ {
unsigned int pincap = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP); unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
return (pincap & AC_PINCAP_IN) != 0; return (pincap & AC_PINCAP_IN) != 0;
} }
static int alc662_is_output_pin(struct hda_codec *codec, hda_nid_t nid) static int alc662_is_output_pin(struct hda_codec *codec, hda_nid_t nid)
{ {
unsigned int pincap = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP); unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
return (pincap & AC_PINCAP_OUT) != 0; return (pincap & AC_PINCAP_OUT) != 0;
} }
......
...@@ -2537,8 +2537,7 @@ static int stac92xx_build_pcms(struct hda_codec *codec) ...@@ -2537,8 +2537,7 @@ static int stac92xx_build_pcms(struct hda_codec *codec)
static unsigned int stac92xx_get_vref(struct hda_codec *codec, hda_nid_t nid) static unsigned int stac92xx_get_vref(struct hda_codec *codec, hda_nid_t nid)
{ {
unsigned int pincap = snd_hda_param_read(codec, nid, unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
AC_PAR_PIN_CAP);
pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT; pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
if (pincap & AC_PINCAP_VREF_100) if (pincap & AC_PINCAP_VREF_100)
return AC_PINCTL_VREF_100; return AC_PINCTL_VREF_100;
...@@ -2799,7 +2798,7 @@ static hda_nid_t check_line_out_switch(struct hda_codec *codec) ...@@ -2799,7 +2798,7 @@ static hda_nid_t check_line_out_switch(struct hda_codec *codec)
if (cfg->line_out_type != AUTO_PIN_LINE_OUT) if (cfg->line_out_type != AUTO_PIN_LINE_OUT)
return 0; return 0;
nid = cfg->input_pins[AUTO_PIN_LINE]; nid = cfg->input_pins[AUTO_PIN_LINE];
pincap = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP); pincap = snd_hda_query_pin_caps(codec, nid);
if (pincap & AC_PINCAP_OUT) if (pincap & AC_PINCAP_OUT)
return nid; return nid;
return 0; return 0;
...@@ -2822,7 +2821,7 @@ static hda_nid_t check_mic_out_switch(struct hda_codec *codec) ...@@ -2822,7 +2821,7 @@ static hda_nid_t check_mic_out_switch(struct hda_codec *codec)
/* some laptops have an internal analog microphone /* some laptops have an internal analog microphone
* which can't be used as a output */ * which can't be used as a output */
if (get_defcfg_connect(def_conf) != AC_JACK_PORT_FIXED) { if (get_defcfg_connect(def_conf) != AC_JACK_PORT_FIXED) {
pincap = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP); pincap = snd_hda_query_pin_caps(codec, nid);
if (pincap & AC_PINCAP_OUT) if (pincap & AC_PINCAP_OUT)
return nid; return nid;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment