pmac: Improve sleep code of tumbler driver
PATCH 1/1 pmac: Improve sleep code of tumbler driver
Hi !
This patch (applies on top of my previous one adding support for newer machines) improves the behaviour of the "tumbler/snapper" driver used on newer PowerMacs during sleep. It properly set the HW mutes to shut down amplifiers and does an analog shutdown of the codec. That might improve power consumption during sleep on a number of machines.
sound/ppc/tumbler.c +106 -36
@@ -94,12 +94,17 @@pmac_gpio_t hp_detect;int headphone_irq;unsigned int master_vol[2 ]; +unsigned int save_master_switch[2 ];unsigned int master_switch[2 ];unsigned int mono_vol[VOL_IDX_LAST_MONO ];unsigned int mix_vol[VOL_IDX_LAST_MIX ][2 ];/* stereo volumes for tas3004 */ int drc_range;int drc_enable;int capture_source; +int anded_reset; +int auto_mute_notify; +int reset_on_sleep; +u8 acs; } pmac_tumbler_t;
@@ -654,7 +659,8 @@/* -* mute switches +* mute switches. FIXME: Turn that into software mute when both outputs are muted +* to avoid codec reset on ibook M7 */ enum {TUMBLER_MUTE_HP ,TUMBLER_MUTE_AMP };
@@ -696,8 +702,11 @@ {if (! mix->i2c.client)return -ENODEV ; -return i2c_smbus_write_byte_data (mix->i2c.client,TAS_REG_ACS , - mix->capture_source ?2 :0 ); +if (mix->capture_source) + mix->acs = mix->acs |=2 ; +else + mix->acs &= ~2 ; +return i2c_smbus_write_byte_data (mix->i2c.client,TAS_REG_ACS , mix->acs); }static int snapper_info_capture_source (snd_kcontrol_t *kcontrol,snd_ctl_elem_info_t *uinfo)
@@ -855,8 +864,7 @@static struct work_struct device_change; -static void -device_change_handler (void *self) +static void device_change_handler (void *self) {pmac_t *chip = (pmac_t *) self;pmac_tumbler_t *mix;
@@ -865,6 +873,33 @@return ; mix = chip->mixer_data; +snd_assert (mix, return); + +if (tumbler_detect_headphone (chip)) { +/* mute speaker */ +check_mute (chip, &mix->hp_mute,0 , mix->auto_mute_notify, + chip->master_sw_ctl); +if (mix->anded_reset) +big_mdelay (10 ); +check_mute (chip, &mix->amp_mute,1 , mix->auto_mute_notify, + chip->speaker_sw_ctl); + mix->drc_enable =0 ; + }else { +/* unmute speaker */ +check_mute (chip, &mix->amp_mute,0 , mix->auto_mute_notify, + chip->speaker_sw_ctl); +if (mix->anded_reset) +big_mdelay (10 ); +check_mute (chip, &mix->hp_mute,1 , mix->auto_mute_notify, + chip->master_sw_ctl); + mix->drc_enable =1 ; + } +if (mix->auto_mute_notify) { +snd_ctl_notify (chip->card,SNDRV_CTL_EVENT_MASK_VALUE , + &chip->hp_detect_ctl->id); +snd_ctl_notify (chip->card,SNDRV_CTL_EVENT_MASK_VALUE , + &chip->drc_sw_ctl->id); + }/* first set the DRC so the speaker do not explode -ReneR */ if (chip->model ==PMAC_TUMBLER )
@@ -879,31 +914,11 @@static void tumbler_update_automute (pmac_t *chip,int do_notify) {if (chip->auto_mute) { -pmac_tumbler_t *mix = chip->mixer_data; +pmac_tumbler_t *mix; + mix = chip->mixer_data;snd_assert (mix, return); -if (tumbler_detect_headphone (chip)) { -/* mute speaker */ -check_mute (chip, &mix->amp_mute,1 , do_notify, chip->speaker_sw_ctl); -check_mute (chip, &mix->hp_mute,0 , do_notify, chip->master_sw_ctl); - mix->drc_enable =0 ; - - }else { -/* unmute speaker */ -check_mute (chip, &mix->amp_mute,0 , do_notify, chip->speaker_sw_ctl); -check_mute (chip, &mix->hp_mute,1 , do_notify, chip->master_sw_ctl); - mix->drc_enable =1 ; - } -if (do_notify) { -snd_ctl_notify (chip->card,SNDRV_CTL_EVENT_MASK_VALUE , - &chip->hp_detect_ctl->id); -snd_ctl_notify (chip->card,SNDRV_CTL_EVENT_MASK_VALUE , - &chip->drc_sw_ctl->id); - } - -/* finally we need to schedule an update of the mixer values -(master and DRC are enough for now) -ReneR */ + mix->auto_mute_notify = do_notify;schedule_work (&device_change); - } }#endif /* PMAC_SUPPORT_AUTOMUTE */
@@ -1002,15 +1017,53 @@ {pmac_tumbler_t *mix = chip->mixer_data; -write_audio_gpio (&mix->audio_reset,0 ); -big_mdelay (200 ); -write_audio_gpio (&mix->audio_reset,1 ); -big_mdelay (100 ); -write_audio_gpio (&mix->audio_reset,0 ); -big_mdelay (100 ); +if (mix->anded_reset) { +write_audio_gpio (&mix->hp_mute,0 ); +write_audio_gpio (&mix->amp_mute,0 ); +big_mdelay (200 ); +write_audio_gpio (&mix->hp_mute,1 ); +write_audio_gpio (&mix->amp_mute,1 ); +big_mdelay (100 ); +write_audio_gpio (&mix->hp_mute,0 ); +write_audio_gpio (&mix->amp_mute,0 ); +big_mdelay (100 ); + }else { +write_audio_gpio (&mix->audio_reset,0 ); +big_mdelay (200 ); +write_audio_gpio (&mix->audio_reset,1 ); +big_mdelay (100 ); +write_audio_gpio (&mix->audio_reset,0 ); +big_mdelay (100 ); + } }#ifdef CONFIG_PMAC_PBOOK +/* suspend mixer */ +static void tumbler_suspend (pmac_t *chip) +{ +pmac_tumbler_t *mix = chip->mixer_data; + +if (mix->headphone_irq >=0 ) +disable_irq (mix->headphone_irq); + mix->save_master_switch[0 ] = mix->master_switch[0 ]; + mix->save_master_switch[1 ] = mix->master_switch[1 ]; + mix->master_switch[0 ] = mix->master_switch[1 ] =0 ; +tumbler_set_master_volume (mix); +if (!mix->anded_reset) { +write_audio_gpio (&mix->amp_mute,1 ); +write_audio_gpio (&mix->hp_mute,1 ); + } +if (chip->model ==PMAC_SNAPPER ) { + mix->acs |=1 ; +i2c_smbus_write_byte_data (mix->i2c.client,TAS_REG_ACS , mix->acs); + } +if (mix->anded_reset) { +write_audio_gpio (&mix->amp_mute,1 ); +write_audio_gpio (&mix->hp_mute,1 ); + }else +write_audio_gpio (&mix->audio_reset,1 ); +} +/* resume mixer */ static void tumbler_resume (pmac_t *chip) {
@@ -1018,6 +1071,9 @@snd_assert (mix, return); + mix->acs &= ~1 ; + mix->master_switch[0 ] = mix->save_master_switch[0 ]; + mix->master_switch[1 ] = mix->save_master_switch[1 ];tumbler_reset_audio (chip);if (mix->i2c.client && mix->i2c.init_client) {if (mix->i2c.init_client (&mix->i2c) <0 )
@@ -1041,6 +1097,8 @@tumbler_set_master_volume (mix);if (chip->update_automute) chip->update_automute (chip,0 ); +if (mix->headphone_irq >=0 ) + enable_irq(mix->headphone_irq); }#endif
@@ -1103,9 +1161,9 @@int i, err;pmac_tumbler_t *mix;u32 *paddr; -struct device_node *tas_node; +struct device_node *tas_node, *np;char *chipname; - +#ifdef CONFIG_KMOD if (current->fs->root)request_module ("i2c-keywest" );
@@ -1119,7 +1177,18 @@ chip->mixer_data = mix; chip->mixer_free = tumbler_cleanup; + mix->anded_reset =0 ; + mix->reset_on_sleep =1 ; +for (np = chip->node->child; np; np = np->sibling) { +if (!strcmp (np->name,"sound" )) { +if (get_property (np,"has-anded-reset" ,NULL )) + mix->anded_reset =1 ; +if (get_property (np,"layout-id" ,NULL )) + mix->reset_on_sleep =0 ; +break ; + } + }if ((err =tumbler_init (chip)) <0 )return err;
@@ -1178,6 +1247,7 @@return err;#ifdef CONFIG_PMAC_PBOOK + chip->suspend = tumbler_suspend; chip->resume = tumbler_resume;#endif
Quoted 5 lines · On Mon, 11 Apr 2005 12:00:54 +1000 Benjamin Herrenschmidt…
This patch (applies on top of my previous one adding support for newer machines) improves the behaviour of the "tumbler/snapper" driver used on newer PowerMacs during sleep. It properly set the HW mutes to shut down amplifiers and does an analog shutdown of the codec. That might improve power consumption during sleep on a number of machines.
I suppose it also fixes the occasionnal loud static noise that sometimes at wakeup, for example on iBook G4s. Good :)
Btw, do you know where patches land in this time of SCM change, when it's not in -mm ?
Thanks,
Signature · 1 line
Colin
Quoted 11 lines · Colin Leroy
Quoted 5 lines · On Mon, 11 Apr 2005 12:00:54 +1000 Benjamin Herrenschmidt…
This patch (applies on top of my previous one adding support for newer machines) improves the behaviour of the "tumbler/snapper" driver used on newer PowerMacs during sleep. It properly set the HW mutes to shut down amplifiers and does an analog shutdown of the codec. That might improve power consumption during sleep on a number of machines.
I suppose it also fixes the occasionnal loud static noise that sometimes at wakeup, for example on iBook G4s. Good :)
I don't know, tell me. I didn't know about this problem.
Quoted 2 lines
Btw, do you know where patches land in this time of SCM change, when it's not in -mm ?
-mm :) Linus didn't restart merging things yet.
Ben.
Quoted 11 lines · On Mon, 11 Apr 2005 18:34:34 +1000 Benjamin Herrenschmidt…
Quoted 10 lines · Colin Leroy
Quoted 6 lines · On Mon, 11 Apr 2005 12:00:54 +1000 Benjamin Herrenschmidt…
This patch (applies on top of my previous one adding support for newer machines) improves the behaviour of the "tumbler/snapper" driver used on newer PowerMacs during sleep. It properly set the HW mutes to shut down amplifiers and does an analog shutdown of the codec. That might improve power consumption during sleep on a number of machines.
Quoted 4 lines
Quoted 2 lines
I suppose it also fixes the occasionnal loud static noise that sometimes at wakeup, for example on iBook G4s. Good :)
I don't know, tell me. I didn't know about this problem.
It was reported here:
http://lists.debian.org/debian-powerpc/2005/01/msg00781.html
I didn't personnaly report it because it was hard to track it down; it'd happen about once in twenty resumes (more often when you're in a quiet place with strangers around, evidently, according to Murphy's law), and nothing unusual appeared in dmesg (even with SND_DEBUG, which doesn't debug much on ppc anyway). I just got used to mute the ibook before sending it to sleep.
Quoted 4 lines
Quoted 2 lines
Btw, do you know where patches land in this time of SCM change, when it's not in -mm ?
-mm :) Linus didn't restart merging things yet.
Ok, thanks.
Signature · 1 line
Colin
Quoted 10 lines · Benjamin Herrenschmidt
Quoted 9 lines · Colin Leroy
Quoted 5 lines · On Mon, 11 Apr 2005 12:00:54 +1000 Benjamin Herrenschmidt…
This patch (applies on top of my previous one adding support for newer machines) improves the behaviour of the "tumbler/snapper" driver used on newer PowerMacs during sleep. It properly set the HW mutes to shut down amplifiers and does an analog shutdown of the codec. That might improve power consumption during sleep on a number of machines.
Quoted 4 lines
Quoted 2 lines
I suppose it also fixes the occasionnal loud static noise that sometimes at wakeup, for example on iBook G4s. Good :)
I don't know, tell me. I didn't know about this problem.
Point 3 in
http://lists.debian.org/debian-powerpc/2004/11/msg00383.html
:-)
Anyway, now there is no distortion/noise at sleep/wakeup (linus git tree). Thanks for your great work!
Regards,
wrobell <[email protected]>
Quoted 2 lines · Colin Leroy
I suppose it also fixes the occasionnal loud static noise that sometimes at wakeup, for example on iBook G4s. Good :)
Could this be related to this bug?
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=244467
Signature · 3 lines
Vincent Lefèvre <[email protected]> - Web: <http://www.vinc17.org/> 100% accessible validated (X)HTML - Blog: <http://www.vinc17.org/blog/> Work: CR INRIA - computer arithmetic / SPACES project at LORIA
Quoted 7 lines · Vincent Lefevre
Quoted 2 lines · Colin Leroy
I suppose it also fixes the occasionnal loud static noise that sometimes at wakeup, for example on iBook G4s. Good :)
Could this be related to this bug?
I'm also hearing something like that on iBook G3, but only when setting the input source to the microphone.
Andreas.
Signature · 4 lines
Andreas Schwab, SuSE Labs, [email protected] SuSE Linux Products GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5 "And now for something completely different."
At Mon, 11 Apr 2005 12:00:54 +1000,
Quoted 10 lines · Benjamin Herrenschmidt
Hi !
This patch (applies on top of my previous one adding support for newer machines) improves the behaviour of the "tumbler/snapper" driver used on newer PowerMacs during sleep. It properly set the HW mutes to shut down amplifiers and does an analog shutdown of the codec. That might improve power consumption during sleep on a number of machines.
Signed-off-by Benjamin Herrenschmidt <[email protected]>
Great! I applied to ALSA tree now.
Takashi
Status report for 2.6.12-rc2
In reply to Benjamin HerrenschmidtHi,
I use debian on my Powerbook6,2 and recently upgraded from kernel 2.6.10 with the patch Guido Günther provides at [1] to 2.6.12-rc2 with ben's tumbler/snapper patches applied.
So far I've seen the following issues:
1. I tried the new nvidiafb - just because I'm curious and the help says "This driver supports graphics boards with the nVidia chips, TNT and newer. For very old chipsets, such as the RIVA128, then use the rivafb."
The kernel crashed during boot when it tried to switch to nvidiafb. I could see the messages that appeared before this stage until I switched the computer off. Booting with video=ofonly went well and using the traditional rivafb works fine.
This situation reminds me to crashes I had sometime ago when I was testing Guido's patches for rivafb when he tried to get proper support for NV30 into rivafb.
2. Sometimes the machine crashes on suspend to disk. It only happens when I work in X and it seems to freeze in the process of switching to a virtual terminal. The screen shows a distorted image of the previous screen (as if I had 8Bit colour depth with oversized pixels).
I never had such freezes with 2.6.10 and this is the issue which annoys me most ATM. I don't have a way to clearly reproduce the freeze. It happend in two out of perhaps 20 suspends. It only seems to happen on the first suspend after boot.
The suspend itself is much much faster than with 2.6.10 however.
3. I configured sound to use snd-powermac. Before I used dmasound-{pmac,core} and it works mostly. After a suspend-resume-cycle I have to kill xfce4-panel, which accesses /dev/mixer0, rmmod snd-powermac, wait a second and reinsert the module.
4. Something that is quite annoying but harmless is that after wakeup the machine sometimes suspends again immediately. I had something like this before. On resume the PMU seems to be some kind of irritated and gives wrong information about remaining runtime. If this remaining time is 0 pbbuttonsd suspends the machine again.
Thanks,
Wolfi
1. http://honk.physik.uni-konstanz.de/~agx/linux-ppc/kernel/2.6.11.6-agx0.diff
Re: Status report for 2.6.12-rc2
Quoted 17 lines · Wolfram Quester
Hi,
I use debian on my Powerbook6,2 and recently upgraded from kernel 2.6.10 with the patch Guido Günther provides at [1] to 2.6.12-rc2 with ben's tumbler/snapper patches applied.
So far I've seen the following issues:
1. I tried the new nvidiafb - just because I'm curious and the help says "This driver supports graphics boards with the nVidia chips, TNT and newer. For very old chipsets, such as the RIVA128, then use the rivafb."
The kernel crashed during boot when it tried to switch to nvidiafb. I could see the messages that appeared before this stage until I switched the computer off. Booting with video=ofonly went well and using the traditional rivafb works fine.
This situation reminds me to crashes I had sometime ago when I was testing Guido's patches for rivafb when he tried to get proper support for NV30 into rivafb
You should report that to the linux-fbdev mailing list so the maintainer of this driver can try to figure out what's up.
Quoted 9 lines
2. Sometimes the machine crashes on suspend to disk. It only happens when I work in X and it seems to freeze in the process of switching to a virtual terminal. The screen shows a distorted image of the previous screen (as if I had 8Bit colour depth with oversized pixels).
I never had such freezes with 2.6.10 and this is the issue which annoys me most ATM. I don't have a way to clearly reproduce the freeze. It happend in two out of perhaps 20 suspends. It only seems to happen on the first suspend after boot.
The suspend itself is much much faster than with 2.6.10 however.
It dies at suspend time when switching to VC ? Hrm... looks like it could be X and the framebuffer walking on eachother toes, not sure tho, 2.6.12-rc2 is supposed to have patches fixing such ...
Quoted 5 lines
3. I configured sound to use snd-powermac. Before I used dmasound-{pmac,core} and it works mostly. After a suspend-resume-cycle I have to kill xfce4-panel, which accesses
/dev/mixer0, rmmod snd-powermac, wait a second and reinsert the module.
Yes, the Alsa code isn't doing very well when sleep is triggered while an application is playing. I may try to fix it some day, or you can maybe report that to alsa-devel and have Takashi fix it :)
Quoted 5 lines
4. Something that is quite annoying but harmless is that after wakeup the machine sometimes suspends again immediately. I had something like this before. On resume the PMU seems to be some kind of irritated and gives wrong information about remaining runtime. If this remaining time is 0 pbbuttonsd suspends the machine again.
Possibly, I haven't really checked what's going on with suspend to disk. I suspect we just haven't yet started polling again from the PMU and we expose some crap to userland or something like htat ...
Quoted 10 lines
Thanks,
Wolfi
1. http://honk.physik.uni-konstanz.de/~agx/linux-ppc/kernel/2.6.11.6-agx0.diff
_______________________________________________
Linuxppc-dev mailing list
[email protected]
https://ozlabs.org/mailman/listinfo/linuxppc-dev
Signature · 1 line
Benjamin Herrenschmidt <[email protected]>