Commit f1a63a38d2a885cc7e38c67b699171a7c5666d88

Authored by Takashi Iwai
Committed by Jaroslav Kysela
1 parent 7cdbff945e

[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>

Showing 8 changed files with 28 additions and 27 deletions Side-by-side Diff

include/sound/ac97_codec.h
... ... @@ -375,6 +375,7 @@
375 375 #define AC97_SCAP_DETECT_BY_VENDOR (1<<8) /* use vendor registers for read tests */
376 376 #define AC97_SCAP_NO_SPDIF (1<<9) /* don't build SPDIF controls */
377 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 380 /* ac97->flags */
380 381 #define AC97_HAS_PC_BEEP (1<<0) /* force PC Speaker usage */
... ... @@ -511,7 +512,6 @@
511 512  
512 513 #ifdef CONFIG_SND_AC97_POWER_SAVE
513 514 unsigned int power_up; /* power states */
514   - struct workqueue_struct *power_workq;
515 515 struct delayed_work power_work;
516 516 #endif
517 517 struct device dev;
sound/pci/ac97/ac97_codec.c
... ... @@ -194,7 +194,14 @@
194 194  
195 195  
196 196 static 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
197 203  
  204 +
198 205 /*
199 206 * I/O routines
200 207 */
... ... @@ -982,8 +989,7 @@
982 989 {
983 990 if (ac97) {
984 991 #ifdef CONFIG_SND_AC97_POWER_SAVE
985   - if (ac97->power_workq)
986   - destroy_workqueue(ac97->power_workq);
  992 + cancel_delayed_work(&ac97->power_work);
987 993 #endif
988 994 snd_ac97_proc_done(ac97);
989 995 if (ac97->bus)
... ... @@ -1989,7 +1995,6 @@
1989 1995 mutex_init(&ac97->reg_mutex);
1990 1996 mutex_init(&ac97->page_mutex);
1991 1997 #ifdef CONFIG_SND_AC97_POWER_SAVE
1992   - ac97->power_workq = create_workqueue("ac97");
1993 1998 INIT_DELAYED_WORK(&ac97->power_work, do_update_power);
1994 1999 #endif
1995 2000  
1996 2001  
... ... @@ -2275,15 +2280,13 @@
2275 2280 udelay(100);
2276 2281 power |= AC97_PD_PR2 | AC97_PD_PR3; /* Analog Mixer powerdown */
2277 2282 snd_ac97_write(ac97, AC97_POWERDOWN, power);
2278   -#ifdef CONFIG_SND_AC97_POWER_SAVE
2279   - if (power_save) {
  2283 + if (ac97_is_power_save_mode(ac97)) {
2280 2284 udelay(100);
2281 2285 /* AC-link powerdown, internal Clk disable */
2282 2286 /* FIXME: this may cause click noises on some boards */
2283 2287 power |= AC97_PD_PR4 | AC97_PD_PR5;
2284 2288 snd_ac97_write(ac97, AC97_POWERDOWN, power);
2285 2289 }
2286   -#endif
2287 2290 }
2288 2291  
2289 2292  
2290 2293  
2291 2294  
... ... @@ -2337,14 +2340,16 @@
2337 2340 }
2338 2341 }
2339 2342  
2340   - if (power_save && !powerup && ac97->power_workq)
  2343 + if (ac97_is_power_save_mode(ac97) && !powerup)
2341 2344 /* adjust power-down bits after two seconds delay
2342 2345 * (for avoiding loud click noises for many (OSS) apps
2343 2346 * that open/close frequently)
2344 2347 */
2345   - queue_delayed_work(ac97->power_workq, &ac97->power_work, HZ*2);
2346   - else
  2348 + schedule_delayed_work(&ac97->power_work, HZ*2);
  2349 + else {
  2350 + cancel_delayed_work(&ac97->power_work);
2347 2351 update_power_regs(ac97);
  2352 + }
2348 2353  
2349 2354 return 0;
2350 2355 }
2351 2356  
2352 2357  
... ... @@ -2357,19 +2362,15 @@
2357 2362 unsigned int power_up, bits;
2358 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 2371 #ifdef CONFIG_SND_AC97_POWER_SAVE
2361   - if (power_save)
  2372 + if (ac97_is_power_save_mode(ac97))
2362 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 2374 #endif
2374 2375 if (power_up) {
2375 2376 if (ac97->regs[AC97_POWERDOWN] & AC97_PD_PR2) {
... ... @@ -1396,7 +1396,7 @@
1396 1396 ac97.private_data = chip;
1397 1397 ac97.pci = chip->pci;
1398 1398 ac97.num = i;
1399   - ac97.scaps = AC97_SCAP_SKIP_MODEM;
  1399 + ac97.scaps = AC97_SCAP_SKIP_MODEM | AC97_SCAP_POWER_SAVE;
1400 1400 if (! chip->spdif_over_aclink)
1401 1401 ac97.scaps |= AC97_SCAP_NO_SPDIF;
1402 1402 if ((err = snd_ac97_mixer(pbus, &ac97, &chip->ac97[i])) < 0) {
sound/pci/atiixp_modem.c
... ... @@ -1090,7 +1090,7 @@
1090 1090 ac97.private_data = chip;
1091 1091 ac97.pci = chip->pci;
1092 1092 ac97.num = i;
1093   - ac97.scaps = AC97_SCAP_SKIP_AUDIO;
  1093 + ac97.scaps = AC97_SCAP_SKIP_AUDIO | AC97_SCAP_POWER_SAVE;
1094 1094 if ((err = snd_ac97_mixer(pbus, &ac97, &chip->ac97[i])) < 0) {
1095 1095 chip->ac97[i] = NULL; /* to be sure */
1096 1096 snd_printdd("atiixp-modem: codec %d not available for modem\n", i);
sound/pci/intel8x0.c
... ... @@ -2057,7 +2057,7 @@
2057 2057 memset(&ac97, 0, sizeof(ac97));
2058 2058 ac97.private_data = chip;
2059 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 2061 if (chip->xbox)
2062 2062 ac97.scaps |= AC97_SCAP_DETECT_BY_VENDOR;
2063 2063 if (chip->device_type != DEVICE_ALI) {
sound/pci/intel8x0m.c
... ... @@ -830,7 +830,7 @@
830 830 memset(&ac97, 0, sizeof(ac97));
831 831 ac97.private_data = chip;
832 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 835 glob_sta = igetdword(chip, ICHREG(GLOB_STA));
836 836  
... ... @@ -1823,7 +1823,7 @@
1823 1823 ac97.private_data = chip;
1824 1824 ac97.private_free = snd_via82xx_mixer_free_ac97;
1825 1825 ac97.pci = chip->pci;
1826   - ac97.scaps = AC97_SCAP_SKIP_MODEM;
  1826 + ac97.scaps = AC97_SCAP_SKIP_MODEM | AC97_SCAP_POWER_SAVE;
1827 1827 if ((err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97)) < 0)
1828 1828 return err;
1829 1829  
sound/pci/via82xx_modem.c
... ... @@ -900,7 +900,7 @@
900 900 ac97.private_data = chip;
901 901 ac97.private_free = snd_via82xx_mixer_free_ac97;
902 902 ac97.pci = chip->pci;
903   - ac97.scaps = AC97_SCAP_SKIP_AUDIO;
  903 + ac97.scaps = AC97_SCAP_SKIP_AUDIO | AC97_SCAP_POWER_SAVE;
904 904 ac97.num = chip->ac97_secondary;
905 905  
906 906 if ((err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97)) < 0)