Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 353216
b: refs/heads/master
c: 9419ab6
h: refs/heads/master
v: v3
  • Loading branch information
Takashi Iwai committed Jan 24, 2013
1 parent 37b28b2 commit b55a53e
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 19 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: 25368c47aee6d909923001918041f2e94bfa02ef
refs/heads/master: 9419ab6b72325e20789a61004cf68dc9e909a009
39 changes: 25 additions & 14 deletions trunk/sound/pci/hda/hda_codec.c
Original file line number Diff line number Diff line change
Expand Up @@ -1276,6 +1276,8 @@ static bool snd_hda_codec_get_supported_ps(struct hda_codec *codec,

static unsigned int hda_set_power_state(struct hda_codec *codec,
unsigned int power_state);
static unsigned int default_power_filter(struct hda_codec *codec, hda_nid_t nid,
unsigned int power_state);

/**
* snd_hda_codec_new - create a HDA codec
Expand Down Expand Up @@ -1396,6 +1398,7 @@ int snd_hda_codec_new(struct hda_bus *bus,
#endif
codec->epss = snd_hda_codec_get_supported_ps(codec, fg,
AC_PWRST_EPSS);
codec->power_filter = default_power_filter;

/* power-up all before initialization */
hda_set_power_state(codec, AC_PWRST_D0);
Expand Down Expand Up @@ -3649,29 +3652,23 @@ void snd_hda_codec_flush_cache(struct hda_codec *codec)
EXPORT_SYMBOL_HDA(snd_hda_codec_flush_cache);

void snd_hda_codec_set_power_to_all(struct hda_codec *codec, hda_nid_t fg,
unsigned int power_state,
bool eapd_workaround)
unsigned int power_state)
{
hda_nid_t nid = codec->start_nid;
int i;

for (i = 0; i < codec->num_nodes; i++, nid++) {
unsigned int wcaps = get_wcaps(codec, nid);
unsigned int state = power_state;
if (!(wcaps & AC_WCAP_POWER))
continue;
/* don't power down the widget if it controls eapd and
* EAPD_BTLENABLE is set.
*/
if (eapd_workaround && power_state == AC_PWRST_D3 &&
get_wcaps_type(wcaps) == AC_WID_PIN &&
(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)) {
int eapd = snd_hda_codec_read(codec, nid, 0,
AC_VERB_GET_EAPD_BTLENABLE, 0);
if (eapd & 0x02)
if (codec->power_filter) {
state = codec->power_filter(codec, nid, power_state);
if (state != power_state && power_state == AC_PWRST_D3)
continue;
}
snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE,
power_state);
state);
}
}
EXPORT_SYMBOL_HDA(snd_hda_codec_set_power_to_all);
Expand Down Expand Up @@ -3718,6 +3715,21 @@ static unsigned int hda_sync_power_state(struct hda_codec *codec,
return state;
}

/* don't power down the widget if it controls eapd and EAPD_BTLENABLE is set */
static unsigned int default_power_filter(struct hda_codec *codec, hda_nid_t nid,
unsigned int power_state)
{
if (power_state == AC_PWRST_D3 &&
get_wcaps_type(get_wcaps(codec, nid)) == AC_WID_PIN &&
(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)) {
int eapd = snd_hda_codec_read(codec, nid, 0,
AC_VERB_GET_EAPD_BTLENABLE, 0);
if (eapd & 0x02)
return AC_PWRST_D0;
}
return power_state;
}

/*
* set power state of the codec, and return the power state
*/
Expand All @@ -3743,8 +3755,7 @@ static unsigned int hda_set_power_state(struct hda_codec *codec,
snd_hda_codec_read(codec, fg, 0,
AC_VERB_SET_POWER_STATE,
power_state);
snd_hda_codec_set_power_to_all(codec, fg, power_state,
true);
snd_hda_codec_set_power_to_all(codec, fg, power_state);
}
state = hda_sync_power_state(codec, fg, power_state);
if (!(state & AC_PWRST_ERROR))
Expand Down
7 changes: 5 additions & 2 deletions trunk/sound/pci/hda/hda_codec.h
Original file line number Diff line number Diff line change
Expand Up @@ -886,6 +886,10 @@ struct hda_codec {
spinlock_t power_lock;
#endif

/* filter the requested power state per nid */
unsigned int (*power_filter)(struct hda_codec *codec, hda_nid_t nid,
unsigned int power_state);

/* codec-specific additional proc output */
void (*proc_widget_hook)(struct snd_info_buffer *buffer,
struct hda_codec *codec, hda_nid_t nid);
Expand Down Expand Up @@ -1047,8 +1051,7 @@ extern const struct snd_pcm_chmap_elem snd_pcm_2_1_chmaps[];
void snd_hda_get_codec_name(struct hda_codec *codec, char *name, int namelen);
void snd_hda_bus_reboot_notify(struct hda_bus *bus);
void snd_hda_codec_set_power_to_all(struct hda_codec *codec, hda_nid_t fg,
unsigned int power_state,
bool eapd_workaround);
unsigned int power_state);

int snd_hda_lock_devices(struct hda_bus *bus);
void snd_hda_unlock_devices(struct hda_bus *bus);
Expand Down
2 changes: 1 addition & 1 deletion trunk/sound/pci/hda/patch_conexant.c
Original file line number Diff line number Diff line change
Expand Up @@ -435,7 +435,7 @@ static void conexant_set_power(struct hda_codec *codec, hda_nid_t fg,
/* partial workaround for "azx_get_response timeout" */
if (power_state == AC_PWRST_D0)
msleep(10);
snd_hda_codec_set_power_to_all(codec, fg, power_state, true);
snd_hda_codec_set_power_to_all(codec, fg, power_state);
}

static int conexant_init(struct hda_codec *codec)
Expand Down
2 changes: 1 addition & 1 deletion trunk/sound/pci/hda/patch_sigmatel.c
Original file line number Diff line number Diff line change
Expand Up @@ -3724,7 +3724,7 @@ static void stac_set_power_state(struct hda_codec *codec, hda_nid_t fg,
}
snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE,
afg_power_state);
snd_hda_codec_set_power_to_all(codec, fg, power_state, true);
snd_hda_codec_set_power_to_all(codec, fg, power_state);
}
#else
#define stac_suspend NULL
Expand Down

0 comments on commit b55a53e

Please sign in to comment.