At Mon, 07 Jan 2008 11:44:08 -0500, Matthew Ranostay wrote:
[1 <text/plain; ISO-8859-1 (7bit)>] Added support for advanced power management features in new IDT codecs. Inactive ADCs and DACs are changed to D3 mode when not in playback or capture, also inactive line-out/headphone ports are disabled when jack detect does not sense a connection.
Thanks. This is an interesting patch.
Signed-off-by: Matthew Ranostay mranostay@embeddedalley.com [2 stac92hd7xxx_power_save.patch <text/plain (7bit)>] diff -r 5b03c0176aa5 pci/hda/patch_sigmatel.c --- a/pci/hda/patch_sigmatel.c Mon Jan 07 13:33:45 2008 +0100 +++ b/pci/hda/patch_sigmatel.c Mon Jan 07 11:22:56 2008 -0500 @@ -160,6 +160,7 @@ struct sigmatel_spec {
/* i/o switches */ unsigned int io_switch[2];
- unsigned int io_state[2]; unsigned int clfe_swap; unsigned int aloopback;
@@ -438,6 +439,52 @@ static int stac92xx_aloopback_put(struct kcontrol->private_value >> 16, dac_mode);
return 1; +}
+static int is_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid) +{
- int i;
- for (i = 0; i < spec->multiout.num_dacs; i++) {
if (spec->multiout.dac_nids[i] == nid)
return 1;
- }
- return 0;
+}
+static int stac92xx_mixer_amp_switch_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
+{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct sigmatel_spec *spec = codec->spec;
- hda_nid_t nid = kcontrol->private_value & 0xffff;
- int idx = (kcontrol->private_value >> 19) & 0xf;
- int chs = (kcontrol->private_value >> 16) & 0x3;
- long *valp = ucontrol->value.integer.value;
- unsigned int wid_caps, val, change;
- change = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
+#ifdef CONFIG_SND_HDA_POWER_SAVE
- if (!is_in_dac_nids(spec, nid))
nid = spec->adc_nids[idx];
- val = *valp++;
- wid_caps = get_wcaps(codec, nid);
- if (wid_caps & AC_WCAP_POWER) {
if (chs == 3)
val |= *valp;
else { /* Center/LFE mixers workaround */
spec->io_state[--chs] = val;
val |= spec->io_state[chs ? 0 : 1];
}
/* set to power state D3 mode if DAC/ADC isn't being used */
snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE,
val ? 0: AC_PWRST_D3);
- }
+#endif
- return change;
This stuff should go rather to snd_hda_mixer_amp_switch_put(). It's not specific to STAC codecs.
The #ifdef doesn't suffice, BTW. The power-saving is a dynamic switch (via module parameter and/or sysfs), so you need to check whether power-saving mode is active nor not. Also, these calls should be within the snd_hda_power_up/down() block.
@@ -2830,7 +2883,12 @@ static void stac92xx_hp_detect(struct hd for (i = 0; i < cfg->speaker_outs; i++) stac92xx_set_pinctl(codec, cfg->speaker_pins[i], AC_PINCTL_OUT_EN);
- }
for (i = 0; i < cfg->hp_outs; i++)
pwr_state |= 1 << (cfg->hp_pins[i] - 0xa);
- }
- /* power down unused ports */
- snd_hda_codec_write(codec, codec->afg, 0, 0x7ec, pwr_state);
Is this verb available on every STAC codec? I took a look at some specs but they don't show this verb at all.
Takashi