Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 353114
b: refs/heads/master
c: 62f3a2f
h: refs/heads/master
v: v3
  • Loading branch information
Takashi Iwai committed Jan 12, 2013
1 parent e161447 commit 65005bb
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 15 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: d7fdc00ae50b3dc02364301b334a6352c58e9e85
refs/heads/master: 62f3a2f718131e6f42746ccd26dbf4eb5eab677a
66 changes: 52 additions & 14 deletions trunk/sound/pci/hda/hda_codec.c
Original file line number Diff line number Diff line change
Expand Up @@ -5275,23 +5275,61 @@ unsigned int snd_hda_get_default_vref(struct hda_codec *codec, hda_nid_t pin)
}
EXPORT_SYMBOL_HDA(snd_hda_get_default_vref);

/* correct the pin ctl value for matching with the pin cap */
unsigned int snd_hda_correct_pin_ctl(struct hda_codec *codec,
hda_nid_t pin, unsigned int val)
{
static unsigned int cap_lists[][2] = {
{ AC_PINCTL_VREF_100, AC_PINCAP_VREF_100 },
{ AC_PINCTL_VREF_80, AC_PINCAP_VREF_80 },
{ AC_PINCTL_VREF_50, AC_PINCAP_VREF_50 },
{ AC_PINCTL_VREF_GRD, AC_PINCAP_VREF_GRD },
};
unsigned int cap;

if (!val)
return 0;
cap = snd_hda_query_pin_caps(codec, pin);
if (!cap)
return val; /* don't know what to do... */

if (val & AC_PINCTL_OUT_EN) {
if (!(cap & AC_PINCAP_OUT))
val &= ~(AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN);
else if ((val & AC_PINCTL_HP_EN) && !(cap & AC_PINCAP_HP_DRV))
val &= ~AC_PINCTL_HP_EN;
}

if (val & AC_PINCTL_IN_EN) {
if (!(cap & AC_PINCAP_IN))
val &= ~(AC_PINCTL_IN_EN | AC_PINCTL_VREFEN);
else {
unsigned int vcap, vref;
int i;
vcap = (cap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
vref = val & AC_PINCTL_VREFEN;
for (i = 0; i < ARRAY_SIZE(cap_lists); i++) {
if (vref == cap_lists[i][0] &&
!(vcap & cap_lists[i][1])) {
if (i == ARRAY_SIZE(cap_lists) - 1)
vref = AC_PINCTL_VREF_HIZ;
else
vref = cap_lists[i + 1][0];
}
}
val &= ~AC_PINCTL_VREFEN;
val |= vref;
}
}

return val;
}
EXPORT_SYMBOL_HDA(snd_hda_correct_pin_ctl);

int _snd_hda_set_pin_ctl(struct hda_codec *codec, hda_nid_t pin,
unsigned int val, bool cached)
{
if (val) {
unsigned int cap = snd_hda_query_pin_caps(codec, pin);
if (cap && (val & AC_PINCTL_OUT_EN)) {
if (!(cap & AC_PINCAP_OUT))
val &= ~(AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN);
else if ((val & AC_PINCTL_HP_EN) &&
!(cap & AC_PINCAP_HP_DRV))
val &= ~AC_PINCTL_HP_EN;
}
if (cap && (val & AC_PINCTL_IN_EN)) {
if (!(cap & AC_PINCAP_IN))
val &= ~(AC_PINCTL_IN_EN | AC_PINCTL_VREFEN);
}
}
val = snd_hda_correct_pin_ctl(codec, pin, val);
snd_hda_codec_set_pin_target(codec, pin, val);
if (cached)
return snd_hda_codec_update_cache(codec, pin, 0,
Expand Down
2 changes: 2 additions & 0 deletions trunk/sound/pci/hda/hda_local.h
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,8 @@ struct hda_bus_unsolicited {
#define PIN_HP_AMP (AC_PINCTL_HP_EN)

unsigned int snd_hda_get_default_vref(struct hda_codec *codec, hda_nid_t pin);
unsigned int snd_hda_correct_pin_ctl(struct hda_codec *codec,
hda_nid_t pin, unsigned int val);
int _snd_hda_set_pin_ctl(struct hda_codec *codec, hda_nid_t pin,
unsigned int val, bool cached);

Expand Down

0 comments on commit 65005bb

Please sign in to comment.