diff options
author | Takashi Iwai <tiwai@suse.de> | 2007-08-10 17:21:45 +0200 |
---|---|---|
committer | Jaroslav Kysela <perex@perex.cz> | 2007-10-16 15:58:46 +0200 |
commit | cb53c626e1145edf1d619bc4953f6293d3a77ace (patch) | |
tree | 715c2ef3d56a5ac7c79498800e888f562c1aa961 /sound/pci/hda/hda_codec.h | |
parent | cca3b3718ca96dca51daf1129ac03003bcede751 (diff) | |
download | linux-cb53c626e1145edf1d619bc4953f6293d3a77ace.tar.gz linux-cb53c626e1145edf1d619bc4953f6293d3a77ace.tar.bz2 linux-cb53c626e1145edf1d619bc4953f6293d3a77ace.zip |
[ALSA] hda-intel - Add POWER_SAVE option
Added CONFIG_SND_HDA_POWER_SAVE kconfig. It's an experimental option
to achieve an aggressive power-saving. With this option, the driver
will turn on/off the power of each codec and controller chip dynamically
on demand.
The patch introduces a new module option 'power_save'. It specifies
the second of time-out for automatic power-down. As default, it's
10 seconds. Setting 0 means to suppress the power-saving feature.
The codec may have analog-input loopbacks, which are usually represented
by mixer elements such as 'Mic Playback Switch' or 'CD Playback Switch'.
When these are on, we cannot turn off the mixer and the codec chip has
to be kept on. For bookkeeping these states, a new codec-callback is
introduced.
For the bus-controller side, a new callback pm_notify is introduced,
which can be used to turn on/off the contoller appropriately.
Note that this power-saving might cause slight click-noise at
power-on/off. Also, it might take some time to wake up the codec, and
might even drop some tones at the very beginning. This seems to be the
side-effect of turning off the controller chip.
This turn-off of the controller can be disabled by undefining
HDA_POWER_SAVE_RESET_CONTOLLER in hda_intel.c.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@suse.cz>
Diffstat (limited to 'sound/pci/hda/hda_codec.h')
-rw-r--r-- | sound/pci/hda/hda_codec.h | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 92938d2a52e2..1ffffaa3a30d 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h @@ -26,6 +26,10 @@ #include <sound/pcm.h> #include <sound/hwdep.h> +#if defined(CONFIG_PM) || defined(CONFIG_SND_HDA_POWER_SAVE) +#define SND_HDA_NEEDS_RESUME /* resume control code is required */ +#endif + /* * nodes */ @@ -412,6 +416,10 @@ struct hda_bus_ops { unsigned int (*get_response)(struct hda_codec *codec); /* free the private data */ void (*private_free)(struct hda_bus *); +#ifdef CONFIG_SND_HDA_POWER_SAVE + /* notify power-up/down from codec to contoller */ + void (*pm_notify)(struct hda_codec *codec); +#endif }; /* template to pass to the bus constructor */ @@ -473,10 +481,13 @@ struct hda_codec_ops { int (*init)(struct hda_codec *codec); void (*free)(struct hda_codec *codec); void (*unsol_event)(struct hda_codec *codec, unsigned int res); -#ifdef CONFIG_PM +#ifdef SND_HDA_NEEDS_RESUME int (*suspend)(struct hda_codec *codec, pm_message_t state); int (*resume)(struct hda_codec *codec); #endif +#ifdef CONFIG_SND_HDA_POWER_SAVE + int (*check_power_status)(struct hda_codec *codec, hda_nid_t nid); +#endif }; /* record for amp information cache */ @@ -573,6 +584,12 @@ struct hda_codec { unsigned int spdif_in_enable; /* SPDIF input enable? */ struct snd_hwdep *hwdep; /* assigned hwdep device */ + +#ifdef CONFIG_SND_HDA_POWER_SAVE + int power_on; /* current (global) power-state */ + int power_count; /* current (global) power refcount */ + struct delayed_work power_work; /* delayed task for powerdown */ +#endif }; /* direction */ @@ -617,7 +634,7 @@ void snd_hda_sequence_write(struct hda_codec *codec, int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex); /* cached write */ -#ifdef CONFIG_PM +#ifdef SND_HDA_NEEDS_RESUME int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid, int direct, unsigned int verb, unsigned int parm); void snd_hda_sequence_write_cache(struct hda_codec *codec, @@ -662,4 +679,15 @@ int snd_hda_suspend(struct hda_bus *bus, pm_message_t state); int snd_hda_resume(struct hda_bus *bus); #endif +/* + * power saving + */ +#ifdef CONFIG_SND_HDA_POWER_SAVE +void snd_hda_power_up(struct hda_codec *codec); +void snd_hda_power_down(struct hda_codec *codec); +#else +static inline void snd_hda_power_up(struct hda_codec *codec) {} +static inline void snd_hda_power_down(struct hda_codec *codec) {} +#endif + #endif /* __SOUND_HDA_CODEC_H */ |