From: <bob...@us...> - 2007-07-20 14:43:08
|
Revision: 1186 http://svn.sourceforge.net/hackndev/?rev=1186&view=rev Author: bobofdoom Date: 2007-07-20 07:43:04 -0700 (Fri, 20 Jul 2007) Log Message: ----------- PalmT650: Rewrote palmt650_pm.c from scratch, fixing many problems: * suspend to ram (sleep) mode now works with original palm bootloader! * palmt650_pm.c is now just compiled in whenever CONFIG_PM is set. * special PM device driver removed, now just use pxa_ll_pm. * can now wake on pressing I, K, M, Alt, Shift or plugging AC. * normal keypad wake-up still not working. Modified Paths: -------------- linux4palm/linux/trunk/arch/arm/mach-pxa/palmt650/Kconfig linux4palm/linux/trunk/arch/arm/mach-pxa/palmt650/Makefile linux4palm/linux/trunk/arch/arm/mach-pxa/palmt650/palmt650.c linux4palm/linux/trunk/arch/arm/mach-pxa/palmt650/palmt650_pm.c Modified: linux4palm/linux/trunk/arch/arm/mach-pxa/palmt650/Kconfig =================================================================== --- linux4palm/linux/trunk/arch/arm/mach-pxa/palmt650/Kconfig 2007-07-20 14:17:00 UTC (rev 1185) +++ linux4palm/linux/trunk/arch/arm/mach-pxa/palmt650/Kconfig 2007-07-20 14:43:04 UTC (rev 1186) @@ -5,10 +5,3 @@ Say Y here if you intend to run this kernel on a Palm Treo 650. Currently there is only basic support for this PDA. - -config MACH_XSCALE_PALMTREO650_PM - tristate "Palm Treo 650 Power Management support" - depends on MACH_XSCALE_PALMTREO650 - default y if MACH_XSCALE_PALMTREO650 - help - Enables support for suspend/resume the PalmOne treo 650. Modified: linux4palm/linux/trunk/arch/arm/mach-pxa/palmt650/Makefile =================================================================== --- linux4palm/linux/trunk/arch/arm/mach-pxa/palmt650/Makefile 2007-07-20 14:17:00 UTC (rev 1185) +++ linux4palm/linux/trunk/arch/arm/mach-pxa/palmt650/Makefile 2007-07-20 14:43:04 UTC (rev 1186) @@ -2,5 +2,4 @@ # Makefile for Palm Treo 650 support # -obj-$(CONFIG_MACH_XSCALE_PALMTREO650) += palmt650.o -obj-$(CONFIG_MACH_XSCALE_PALMTREO650_PM) += palmt650_pm.o +obj-$(CONFIG_MACH_XSCALE_PALMTREO650) += palmt650.o palmt650_pm.o Modified: linux4palm/linux/trunk/arch/arm/mach-pxa/palmt650/palmt650.c =================================================================== --- linux4palm/linux/trunk/arch/arm/mach-pxa/palmt650/palmt650.c 2007-07-20 14:17:00 UTC (rev 1185) +++ linux4palm/linux/trunk/arch/arm/mach-pxa/palmt650/palmt650.c 2007-07-20 14:43:04 UTC (rev 1186) @@ -182,7 +182,7 @@ { case PXA2XX_UDC_CMD_DISCONNECT: printk (KERN_NOTICE "USB cmd disconnect\n"); - SET_PALMT650_GPIO(USB_PULLUP, 1); + SET_PALMT650_GPIO(USB_PULLUP, 0); break; case PXA2XX_UDC_CMD_CONNECT: @@ -357,6 +357,8 @@ iotable_init(palmt650_io_desc, ARRAY_SIZE(palmt650_io_desc)); } +void palmt650_pxa_ll_pm_init(void); + static void __init palmt650_init(void) { /* Disable PRIRDY interrupt to avoid hanging when loading AC97 */ @@ -376,6 +378,10 @@ pxa_set_ficp_info(&palmt650_ficp_platform_data); pxa_set_udc_info( &palmt650_udc_mach_info ); +#ifdef CONFIG_PM + palmt650_pxa_ll_pm_init(); +#endif + platform_add_devices(devices, ARRAY_SIZE(devices)); } Modified: linux4palm/linux/trunk/arch/arm/mach-pxa/palmt650/palmt650_pm.c =================================================================== --- linux4palm/linux/trunk/arch/arm/mach-pxa/palmt650/palmt650_pm.c 2007-07-20 14:17:00 UTC (rev 1185) +++ linux4palm/linux/trunk/arch/arm/mach-pxa/palmt650/palmt650_pm.c 2007-07-20 14:43:04 UTC (rev 1186) @@ -1,100 +1,103 @@ -/************************************************************************ - * PalmOne treo650 suspend/resume support * - * * - * Authors: P3T3, Petr Blaha <pb...@p3...> * - * Jan Herman <2h...@se...> * - * Sergey Lapin <sla...@gm...> * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - ************************************************************************/ +/* + * arch/arm/mach-pxa/palmt650/palmt650_pm.c + * + * Suspend/resume support with unmodified Treo 650 bootloader. + * + * Copyright (C) 2007 Alex Osborne + * + * + * The original bootloader upon waking from sleep mode will + * check PSPR and if it's non-zero it will jump to 0xa0000000. + * + * This code modifies 0xa0000000 just before going to sleep, inserting a jump + * to PSPR which will be holding the address of the Linux resume function. + */ #include <linux/kernel.h> -#include <linux/device.h> -#include <linux/pm.h> -#include <linux/fb.h> -#include <linux/platform_device.h> -#include <asm/mach-types.h> -#include <asm/hardware.h> - -#include <asm/arch/pm.h> #include <asm/arch/pxa-pm_ll.h> #include <asm/arch/hardware.h> #include <asm/arch/pxa-regs.h> - #include <asm/arch/palmt650-gpio.h> #ifdef CONFIG_PM -static int palmt650_suspend(struct device *dev, pm_message_t state) -{ - /* Wake-Up on RTC event, etc. */ - PWER |= PWER_RTC | PWER_WEP1; - PWER |= 2 << 19; /* wake on SD */ - PWER |= 1; - PRER |= 1; - PFER |= 1; +#define RESUME_VECTOR_PHYS 0xa0000000 - /* Wakeup by keyboard :-) */ - PKWR = 0xffffff; - - /* Enabled Deep-Sleep mode */ - PCFR |= PCFR_DS; +static u32 *resume_vector; +static u32 resume_vector_save[3]; - /* Low power mode */ - PCFR |= PCFR_OPDE; - - /* 3.6.8.1 */ - while(!(OSCC & OSCC_OOK)) - {} +static void palmt650_pxa_ll_pm_suspend(unsigned long resume_addr) +{ + resume_vector_save[0] = resume_vector[0]; + resume_vector_save[1] = resume_vector[1]; + resume_vector_save[2] = resume_vector[2]; - /* Turn off LCD power */ - //SET_PALMT650_GPIO(LCD_POWER,0); - /* Turn off USB power */ -/* SET_PALMT650_GPIO(USB_POWER,0); */ + /* write jump to PSPR */ + resume_vector[0] = 0xe3a00121; /* mov r0, #0x40000008 */ + resume_vector[1] = 0xe280060f; /* add r0, r0, #0xf00000 */ + resume_vector[2] = 0xe590f000; /* ldr pc, [r0] */ + /* wake-up enable */ + PWER = PWER_RTC + | PWER_GPIO0 /* AC adapter */ + | PWER_GPIO1 /* reset */ + | (1 << 20); /* SD detect */ - /* disable GPIO reset - DO NOT REMOVE! */ - PCFR = PCFR_GPROD; + /* falling-edge wake */ + PFER = PWER_GPIO0 + | PWER_GPIO1 + | (1 << 20); /* SD detect */ + + /* rising-edge wake */ + PRER = PWER_GPIO0 + | PWER_GPIO1 + | (1 << 20); /* SD detect */ - return 0; -} + /* wake-up by keypad (not working yet) */ + PKWR = 0xffffffff; + KPC &= ~KPC_ASACT; + KPC |= KPC_AS; + KPC &= ~KPC_MIE; /* matrix keypad interrupt disabled */ + PKWR; + PKSR = 0xffffffff; /* clear */ + PSLR |= 0xF08; -static int palmt650_resume(struct device *dev) -{ - - /* Disabled Deep-Sleep mode ?? */ - PCFR &= PCFR_DS; + /* hacky alternate method for keypad wake + * at least allows some way. Press I, K, M, R-Alt or R-Shift to wake + */ + pxa_gpio_mode(GPIO_NR_PALMT650_KP_MKIN7 | GPIO_IN); + PWER |= PWER_GPIO13; + PRER |= PWER_GPIO13; + PFER |= PWER_GPIO13; - /* Re-enable GPIO reset */ - PCFR |= PCFR_GPR_EN; /* !! DO NOT REMOVE !! THIS IS NECCESARY FOR ENABLE PALM RESET !! */ + /* ensure USB connection is broken */ + SET_PALMT650_GPIO(USB_PULLUP, 0); - - /* Here are all of special to resume PalmOne treo 650 */ - - /* Turn on LCD power */ - //SET_PALMT650_GPIO(LCD_POWER,1); - /* Turn on USB power */ -/* SET_PALMT650_GPIO(USB_POWER,1); */ + /* hold current GPIO levels for now + * TODO: find out what we can disable. + */ + PGSR0 = GPLR0; + PGSR1 = GPLR1; + PGSR2 = GPLR2; + PGSR3 = GPLR3; - return 0; -} -#else -#define palmt650_suspend NULL -#define palmt650_resume NULL -#endif + PCFR |= PCFR_OPDE; /* low power: disable oscillator */ -static void palmt650_pxa_ll_pm_suspend(unsigned long resume_addr) -{ - /* For future */ + /* ensure oscillator is stable (see 3.6.8.1) */ + while(!(OSCC & OSCC_OOK)); + + PCFR |= PCFR_GPROD; /* disable gpio reset */ return; } static void palmt650_pxa_ll_pm_resume(void) { - /* For future */ + /* re-enable GPIO reset */ + PCFR |= PCFR_GPR_EN; + + resume_vector[0] = resume_vector_save[0]; + resume_vector[1] = resume_vector_save[1]; + resume_vector[2] = resume_vector_save[2]; } struct pxa_ll_pm_ops palmt650_ll_pm_ops = { @@ -102,33 +105,9 @@ .resume = palmt650_pxa_ll_pm_resume, }; -static int palmt650_pm_probe(struct device *dev) +void palmt650_pxa_ll_pm_init(void) { - printk(KERN_NOTICE "PalmOne Treo 650 power management driver registered\n"); - return 0; + resume_vector = phys_to_virt(0xa0000000); + pxa_pm_set_ll_ops(&palmt650_ll_pm_ops); } - -struct device_driver palmt650_pm_driver = { - .name = "palmt650-pm", - .bus = &platform_bus_type, - .probe = palmt650_pm_probe, - .suspend = palmt650_suspend, - .resume = palmt650_resume, -}; - -static int __init palmt650_pm_init(void) -{ - return driver_register(&palmt650_pm_driver); -} - -static void __exit palmt650_pm_exit(void) -{ - driver_unregister(&palmt650_pm_driver); -} - -module_init(palmt650_pm_init); -module_exit(palmt650_pm_exit); - -MODULE_AUTHOR("P3T3 Petr Blaha <pb...@p3...>, Jan Herman <2h...@se...>, Sergey Lapin <sla...@gm...>"); -MODULE_DESCRIPTION("PalmOne Treo 650 power management driver"); -MODULE_LICENSE("GPL"); +#endif This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |