aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2006-10-24 12:25:29 -0400
committerJaroslav Kysela <perex@suse.cz>2007-02-09 03:01:09 -0500
commitf1a63a38d2a885cc7e38c67b699171a7c5666d88 (patch)
tree9425150713ffa2af52f8b28bdadf453cf62b2afc
parent7cdbff945e9e3bb592dee2f66afbcc2255747f8f (diff)
[ALSA] ac97 - Suppress power-saving mode on non-supporting drivers
Don't enable power-saving mode on drivers that don't support it. The supporting drivers set AC97_SCAP_POWER_SAVE to scaps at creation of ac97 instance. Currently enable on the following drivers: intel8x0, intel8x0m, atiixp, atiixp-modem, via82xx and via82xx-modem. Also, a bit clean up of power-saving stuff: - Don't create an own workq - Remove superfluous ifdefs Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Jaroslav Kysela <perex@suse.cz>
-rw-r--r--include/sound/ac97_codec.h2
-rw-r--r--sound/pci/ac97/ac97_codec.c41
-rw-r--r--sound/pci/atiixp.c2
-rw-r--r--sound/pci/atiixp_modem.c2
-rw-r--r--sound/pci/intel8x0.c2
-rw-r--r--sound/pci/intel8x0m.c2
-rw-r--r--sound/pci/via82xx.c2
-rw-r--r--sound/pci/via82xx_modem.c2
8 files changed, 28 insertions, 27 deletions
diff --git a/include/sound/ac97_codec.h b/include/sound/ac97_codec.h
index 5f7c78d9e379..5d3f0d8c0e61 100644
--- a/include/sound/ac97_codec.h
+++ b/include/sound/ac97_codec.h
@@ -375,6 +375,7 @@
375#define AC97_SCAP_DETECT_BY_VENDOR (1<<8) /* use vendor registers for read tests */ 375#define AC97_SCAP_DETECT_BY_VENDOR (1<<8) /* use vendor registers for read tests */
376#define AC97_SCAP_NO_SPDIF (1<<9) /* don't build SPDIF controls */ 376#define AC97_SCAP_NO_SPDIF (1<<9) /* don't build SPDIF controls */
377#define AC97_SCAP_EAPD_LED (1<<10) /* EAPD as mute LED */ 377#define AC97_SCAP_EAPD_LED (1<<10) /* EAPD as mute LED */
378#define AC97_SCAP_POWER_SAVE (1<<11) /* capable for aggresive power-saving */
378 379
379/* ac97->flags */ 380/* ac97->flags */
380#define AC97_HAS_PC_BEEP (1<<0) /* force PC Speaker usage */ 381#define AC97_HAS_PC_BEEP (1<<0) /* force PC Speaker usage */
@@ -511,7 +512,6 @@ struct snd_ac97 {
511 512
512#ifdef CONFIG_SND_AC97_POWER_SAVE 513#ifdef CONFIG_SND_AC97_POWER_SAVE
513 unsigned int power_up; /* power states */ 514 unsigned int power_up; /* power states */
514 struct workqueue_struct *power_workq;
515 struct delayed_work power_work; 515 struct delayed_work power_work;
516#endif 516#endif
517 struct device dev; 517 struct device dev;
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c
index d2994cb4c8c9..9da4977c0a0c 100644
--- a/sound/pci/ac97/ac97_codec.c
+++ b/sound/pci/ac97/ac97_codec.c
@@ -194,6 +194,13 @@ static const struct ac97_codec_id snd_ac97_codec_ids[] = {
194 194
195 195
196static void update_power_regs(struct snd_ac97 *ac97); 196static void update_power_regs(struct snd_ac97 *ac97);
197#ifdef CONFIG_SND_AC97_POWER_SAVE
198#define ac97_is_power_save_mode(ac97) \
199 ((ac97->scaps & AC97_SCAP_POWER_SAVE) && power_save)
200#else
201#define ac97_is_power_save_mode(ac97) 0
202#endif
203
197 204
198/* 205/*
199 * I/O routines 206 * I/O routines
@@ -982,8 +989,7 @@ static int snd_ac97_free(struct snd_ac97 *ac97)
982{ 989{
983 if (ac97) { 990 if (ac97) {
984#ifdef CONFIG_SND_AC97_POWER_SAVE 991#ifdef CONFIG_SND_AC97_POWER_SAVE
985 if (ac97->power_workq) 992 cancel_delayed_work(&ac97->power_work);
986 destroy_workqueue(ac97->power_workq);
987#endif 993#endif
988 snd_ac97_proc_done(ac97); 994 snd_ac97_proc_done(ac97);
989 if (ac97->bus) 995 if (ac97->bus)
@@ -1989,7 +1995,6 @@ int snd_ac97_mixer(struct snd_ac97_bus *bus, struct snd_ac97_template *template,
1989 mutex_init(&ac97->reg_mutex); 1995 mutex_init(&ac97->reg_mutex);
1990 mutex_init(&ac97->page_mutex); 1996 mutex_init(&ac97->page_mutex);
1991#ifdef CONFIG_SND_AC97_POWER_SAVE 1997#ifdef CONFIG_SND_AC97_POWER_SAVE
1992 ac97->power_workq = create_workqueue("ac97");
1993 INIT_DELAYED_WORK(&ac97->power_work, do_update_power); 1998 INIT_DELAYED_WORK(&ac97->power_work, do_update_power);
1994#endif 1999#endif
1995 2000
@@ -2275,15 +2280,13 @@ static void snd_ac97_powerdown(struct snd_ac97 *ac97)
2275 udelay(100); 2280 udelay(100);
2276 power |= AC97_PD_PR2 | AC97_PD_PR3; /* Analog Mixer powerdown */ 2281 power |= AC97_PD_PR2 | AC97_PD_PR3; /* Analog Mixer powerdown */
2277 snd_ac97_write(ac97, AC97_POWERDOWN, power); 2282 snd_ac97_write(ac97, AC97_POWERDOWN, power);
2278#ifdef CONFIG_SND_AC97_POWER_SAVE 2283 if (ac97_is_power_save_mode(ac97)) {
2279 if (power_save) {
2280 udelay(100); 2284 udelay(100);
2281 /* AC-link powerdown, internal Clk disable */ 2285 /* AC-link powerdown, internal Clk disable */
2282 /* FIXME: this may cause click noises on some boards */ 2286 /* FIXME: this may cause click noises on some boards */
2283 power |= AC97_PD_PR4 | AC97_PD_PR5; 2287 power |= AC97_PD_PR4 | AC97_PD_PR5;
2284 snd_ac97_write(ac97, AC97_POWERDOWN, power); 2288 snd_ac97_write(ac97, AC97_POWERDOWN, power);
2285 } 2289 }
2286#endif
2287} 2290}
2288 2291
2289 2292
@@ -2337,14 +2340,16 @@ int snd_ac97_update_power(struct snd_ac97 *ac97, int reg, int powerup)
2337 } 2340 }
2338 } 2341 }
2339 2342
2340 if (power_save && !powerup && ac97->power_workq) 2343 if (ac97_is_power_save_mode(ac97) && !powerup)
2341 /* adjust power-down bits after two seconds delay 2344 /* adjust power-down bits after two seconds delay
2342 * (for avoiding loud click noises for many (OSS) apps 2345 * (for avoiding loud click noises for many (OSS) apps
2343 * that open/close frequently) 2346 * that open/close frequently)
2344 */ 2347 */
2345 queue_delayed_work(ac97->power_workq, &ac97->power_work, HZ*2); 2348 schedule_delayed_work(&ac97->power_work, HZ*2);
2346 else 2349 else {
2350 cancel_delayed_work(&ac97->power_work);
2347 update_power_regs(ac97); 2351 update_power_regs(ac97);
2352 }
2348 2353
2349 return 0; 2354 return 0;
2350} 2355}
@@ -2357,19 +2362,15 @@ static void update_power_regs(struct snd_ac97 *ac97)
2357 unsigned int power_up, bits; 2362 unsigned int power_up, bits;
2358 int i; 2363 int i;
2359 2364
2365 power_up = (1 << PWIDX_FRONT) | (1 << PWIDX_ADC);
2366 power_up |= (1 << PWIDX_MIC);
2367 if (ac97->scaps & AC97_SCAP_SURROUND_DAC)
2368 power_up |= (1 << PWIDX_SURR);
2369 if (ac97->scaps & AC97_SCAP_CENTER_LFE_DAC)
2370 power_up |= (1 << PWIDX_CLFE);
2360#ifdef CONFIG_SND_AC97_POWER_SAVE 2371#ifdef CONFIG_SND_AC97_POWER_SAVE
2361 if (power_save) 2372 if (ac97_is_power_save_mode(ac97))
2362 power_up = ac97->power_up; 2373 power_up = ac97->power_up;
2363 else {
2364#endif
2365 power_up = (1 << PWIDX_FRONT) | (1 << PWIDX_ADC);
2366 power_up |= (1 << PWIDX_MIC);
2367 if (ac97->scaps & AC97_SCAP_SURROUND_DAC)
2368 power_up |= (1 << PWIDX_SURR);
2369 if (ac97->scaps & AC97_SCAP_CENTER_LFE_DAC)
2370 power_up |= (1 << PWIDX_CLFE);
2371#ifdef CONFIG_SND_AC97_POWER_SAVE
2372 }
2373#endif 2374#endif
2374 if (power_up) { 2375 if (power_up) {
2375 if (ac97->regs[AC97_POWERDOWN] & AC97_PD_PR2) { 2376 if (ac97->regs[AC97_POWERDOWN] & AC97_PD_PR2) {
diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c
index 476c3433073e..86710df71a8e 100644
--- a/sound/pci/atiixp.c
+++ b/sound/pci/atiixp.c
@@ -1396,7 +1396,7 @@ static int __devinit snd_atiixp_mixer_new(struct atiixp *chip, int clock,
1396 ac97.private_data = chip; 1396 ac97.private_data = chip;
1397 ac97.pci = chip->pci; 1397 ac97.pci = chip->pci;
1398 ac97.num = i; 1398 ac97.num = i;
1399 ac97.scaps = AC97_SCAP_SKIP_MODEM; 1399 ac97.scaps = AC97_SCAP_SKIP_MODEM | AC97_SCAP_POWER_SAVE;
1400 if (! chip->spdif_over_aclink) 1400 if (! chip->spdif_over_aclink)
1401 ac97.scaps |= AC97_SCAP_NO_SPDIF; 1401 ac97.scaps |= AC97_SCAP_NO_SPDIF;
1402 if ((err = snd_ac97_mixer(pbus, &ac97, &chip->ac97[i])) < 0) { 1402 if ((err = snd_ac97_mixer(pbus, &ac97, &chip->ac97[i])) < 0) {
diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c
index cc2e6b9d407e..904023fe4f26 100644
--- a/sound/pci/atiixp_modem.c
+++ b/sound/pci/atiixp_modem.c
@@ -1090,7 +1090,7 @@ static int __devinit snd_atiixp_mixer_new(struct atiixp_modem *chip, int clock)
1090 ac97.private_data = chip; 1090 ac97.private_data = chip;
1091 ac97.pci = chip->pci; 1091 ac97.pci = chip->pci;
1092 ac97.num = i; 1092 ac97.num = i;
1093 ac97.scaps = AC97_SCAP_SKIP_AUDIO; 1093 ac97.scaps = AC97_SCAP_SKIP_AUDIO | AC97_SCAP_POWER_SAVE;
1094 if ((err = snd_ac97_mixer(pbus, &ac97, &chip->ac97[i])) < 0) { 1094 if ((err = snd_ac97_mixer(pbus, &ac97, &chip->ac97[i])) < 0) {
1095 chip->ac97[i] = NULL; /* to be sure */ 1095 chip->ac97[i] = NULL; /* to be sure */
1096 snd_printdd("atiixp-modem: codec %d not available for modem\n", i); 1096 snd_printdd("atiixp-modem: codec %d not available for modem\n", i);
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index 28d5d9deb892..f8aef131be7a 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -2057,7 +2057,7 @@ static int __devinit snd_intel8x0_mixer(struct intel8x0 *chip, int ac97_clock,
2057 memset(&ac97, 0, sizeof(ac97)); 2057 memset(&ac97, 0, sizeof(ac97));
2058 ac97.private_data = chip; 2058 ac97.private_data = chip;
2059 ac97.private_free = snd_intel8x0_mixer_free_ac97; 2059 ac97.private_free = snd_intel8x0_mixer_free_ac97;
2060 ac97.scaps = AC97_SCAP_SKIP_MODEM; 2060 ac97.scaps = AC97_SCAP_SKIP_MODEM | AC97_SCAP_POWER_SAVE;
2061 if (chip->xbox) 2061 if (chip->xbox)
2062 ac97.scaps |= AC97_SCAP_DETECT_BY_VENDOR; 2062 ac97.scaps |= AC97_SCAP_DETECT_BY_VENDOR;
2063 if (chip->device_type != DEVICE_ALI) { 2063 if (chip->device_type != DEVICE_ALI) {
diff --git a/sound/pci/intel8x0m.c b/sound/pci/intel8x0m.c
index 936c3cf16936..c155e1f3a0e5 100644
--- a/sound/pci/intel8x0m.c
+++ b/sound/pci/intel8x0m.c
@@ -830,7 +830,7 @@ static int __devinit snd_intel8x0_mixer(struct intel8x0m *chip, int ac97_clock)
830 memset(&ac97, 0, sizeof(ac97)); 830 memset(&ac97, 0, sizeof(ac97));
831 ac97.private_data = chip; 831 ac97.private_data = chip;
832 ac97.private_free = snd_intel8x0_mixer_free_ac97; 832 ac97.private_free = snd_intel8x0_mixer_free_ac97;
833 ac97.scaps = AC97_SCAP_SKIP_AUDIO; 833 ac97.scaps = AC97_SCAP_SKIP_AUDIO | AC97_SCAP_POWER_SAVE;
834 834
835 glob_sta = igetdword(chip, ICHREG(GLOB_STA)); 835 glob_sta = igetdword(chip, ICHREG(GLOB_STA));
836 836
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c
index a572b018807f..0440df7de37d 100644
--- a/sound/pci/via82xx.c
+++ b/sound/pci/via82xx.c
@@ -1823,7 +1823,7 @@ static int __devinit snd_via82xx_mixer_new(struct via82xx *chip, const char *qui
1823 ac97.private_data = chip; 1823 ac97.private_data = chip;
1824 ac97.private_free = snd_via82xx_mixer_free_ac97; 1824 ac97.private_free = snd_via82xx_mixer_free_ac97;
1825 ac97.pci = chip->pci; 1825 ac97.pci = chip->pci;
1826 ac97.scaps = AC97_SCAP_SKIP_MODEM; 1826 ac97.scaps = AC97_SCAP_SKIP_MODEM | AC97_SCAP_POWER_SAVE;
1827 if ((err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97)) < 0) 1827 if ((err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97)) < 0)
1828 return err; 1828 return err;
1829 1829
diff --git a/sound/pci/via82xx_modem.c b/sound/pci/via82xx_modem.c
index 17d6b847585f..b338e15db0d9 100644
--- a/sound/pci/via82xx_modem.c
+++ b/sound/pci/via82xx_modem.c
@@ -900,7 +900,7 @@ static int __devinit snd_via82xx_mixer_new(struct via82xx_modem *chip)
900 ac97.private_data = chip; 900 ac97.private_data = chip;
901 ac97.private_free = snd_via82xx_mixer_free_ac97; 901 ac97.private_free = snd_via82xx_mixer_free_ac97;
902 ac97.pci = chip->pci; 902 ac97.pci = chip->pci;
903 ac97.scaps = AC97_SCAP_SKIP_AUDIO; 903 ac97.scaps = AC97_SCAP_SKIP_AUDIO | AC97_SCAP_POWER_SAVE;
904 ac97.num = chip->ac97_secondary; 904 ac97.num = chip->ac97_secondary;
905 905
906 if ((err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97)) < 0) 906 if ((err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97)) < 0)