From: <z7...@us...> - 2007-03-28 11:04:15
|
Revision: 936 http://svn.sourceforge.net/hackndev/?rev=936&view=rev Author: z72ka Date: 2007-03-28 04:04:10 -0700 (Wed, 28 Mar 2007) Log Message: ----------- palmtx: Added: Battery monitoring support, power management support (developing stage), removed old machine dependent drivers and used new universal drivers for: touchscreen, sound and backlight Modified Paths: -------------- linux4palm/linux/trunk/arch/arm/mach-pxa/palmtx/Kconfig linux4palm/linux/trunk/arch/arm/mach-pxa/palmtx/Makefile linux4palm/linux/trunk/arch/arm/mach-pxa/palmtx/palmtx.c Added Paths: ----------- linux4palm/linux/trunk/arch/arm/mach-pxa/palmtx/palmtx_battery.c linux4palm/linux/trunk/arch/arm/mach-pxa/palmtx/palmtx_pm.c Modified: linux4palm/linux/trunk/arch/arm/mach-pxa/palmtx/Kconfig =================================================================== --- linux4palm/linux/trunk/arch/arm/mach-pxa/palmtx/Kconfig 2007-03-25 01:00:02 UTC (rev 935) +++ linux4palm/linux/trunk/arch/arm/mach-pxa/palmtx/Kconfig 2007-03-28 11:04:10 UTC (rev 936) @@ -3,26 +3,7 @@ select PXA27x help This enables support for Palm TX handheld. - Note: this is in a very early stage. -config PALMTX_AC97 - tristate "Palm TX AC97 driver" - depends on MACH_XSCALE_PALMTX - default y if MACH_XSCALE_PALMTX - help - AC97 codec for Palm TX. - Enable support for WM9712 touchscreen and battery for - the Palm TX PDA - -config PALMTX_LCD - tristate "Palm TX LCD driver" - select LCD_CLASS_DEVICE - depends on MACH_XSCALE_PALMTX - default y if MACH_XSCALE_PALMTX - help - LCD driver for Palm TX. - Enable support for switching the Palm TX LCD on/off - config PALMTX_PCMCIA tristate "Palm TX PCMCIA driver" depends on MACH_XSCALE_PALMTX @@ -36,4 +17,20 @@ default n help Enable core debug output for Palm TX modules. + +config PALMTX_BATTERY + tristate "Palm TX Battery support" + select TOUCHSCREEN_WM97XX + depends on MACH_XSCALE_PALMTX + default m + help + Enable support for Palm TX battery to APM. + ATM use it only as module, otherwise it hangs. + +config PALMTX_PM + tristate "Palm TX Power Management support" + depends on MACH_XSCALE_PALMTX + default y if MACH_PALMTX + help + Enable support for suspend/resume the Palm TX PDA. Modified: linux4palm/linux/trunk/arch/arm/mach-pxa/palmtx/Makefile =================================================================== --- linux4palm/linux/trunk/arch/arm/mach-pxa/palmtx/Makefile 2007-03-25 01:00:02 UTC (rev 935) +++ linux4palm/linux/trunk/arch/arm/mach-pxa/palmtx/Makefile 2007-03-28 11:04:10 UTC (rev 936) @@ -2,8 +2,7 @@ ## Palm TX Linux kernel Makefile # # -obj-$(CONFIG_MACH_XSCALE_PALMTX) += palmtx.o -obj-$(CONFIG_PALMTX_AC97) += palmld_ac97.o -obj-$(CONFIG_PALMTX_LCD) += palmtx_lcd.o -obj-$(CONFIG_PM) += palmtx_pm.o -#obj-$(CONFIG_PALMTX_PCMCIA) += palmtx_pcmcia.o +obj-$(CONFIG_MACH_XSCALE_PALMTX) += palmtx.o +obj-$(CONFIG_PALMTX_BATTERY) += palmtx_battery.o +obj-$(CONFIG_PM) += palmtx_pm.o +obj-$(CONFIG_PALMTX_PCMCIA) += palmtx_pcmcia.o Modified: linux4palm/linux/trunk/arch/arm/mach-pxa/palmtx/palmtx.c =================================================================== --- linux4palm/linux/trunk/arch/arm/mach-pxa/palmtx/palmtx.c 2007-03-25 01:00:02 UTC (rev 935) +++ linux4palm/linux/trunk/arch/arm/mach-pxa/palmtx/palmtx.c 2007-03-28 11:04:10 UTC (rev 936) @@ -7,8 +7,8 @@ * * Authors: Alex Osborne <bob...@gm...> * Cristiano P. <cristianop AT users DOT sourceforge DOT net> (adapted for Palm TX) + * Jan Herman <2h...@se...> * - * * 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. @@ -151,16 +151,12 @@ // backlight static void palmtx_bl_on(void){ - //printk("palmtx: turning backlight on\n"); SET_GPIO(GPIO_NR_PALMTX_BL_POWER, 1); - //printk("GPIO_NR_PALMTX_BL_POWER: %d\n",GET_GPIO(GPIO_NR_PALMTX_BL_POWER)); mdelay(50); } static void palmtx_bl_off(void){ - //printk("palmtx: turning backlight off\n"); SET_GPIO(GPIO_NR_PALMTX_BL_POWER, 0); - //printk("GPIO_NR_PALMTX_BL_POWER: %d\n",GET_GPIO(GPIO_NR_PALMTX_BL_POWER)); mdelay(50); } @@ -182,15 +178,7 @@ }, }; -// LCD -static struct platform_device palmtx_lcd = { - .name = "palmtx-lcd", -}; - - - - // IRDA static void palmtx_irda_transceiver_mode(struct device *dev, int mode) @@ -289,11 +277,23 @@ .dev = { .platform_data = &palmtx_audio_ops }, }; +/******************** + * Power Management * + ********************/ + +struct platform_device palmtx_pm = { + .name = "palmtx-pm", + .id = -1, + .dev = { + .platform_data = NULL, + }, +}; + static struct platform_device *devices[] __initdata = { &palmtx_keypad, &palmtx_ac97, + &palmtx_pm, &palmtx_backlight, - &palmtx_lcd, }; @@ -323,7 +323,6 @@ .hsync_len = 4, // HSW + 1 (HSW=3) .vsync_len = 1, // VSW + 1 (VSW=0) - // .sync = FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, }, }; @@ -332,8 +331,6 @@ .num_modes = ARRAY_SIZE(palmtx_lcd_modes), .lccr0 = PALMTX_INIT_LCD_LLC0, .lccr3 = PALMTX_INIT_LCD_LLC3, - - //.pxafb_backlight_power = palmtx_backlight_power, .pxafb_backlight_power = NULL, }; @@ -375,8 +372,6 @@ pxa_set_ficp_info ( &palmtx_ficp_platform_data ); platform_add_devices( devices, ARRAY_SIZE(devices) ); - - //stuart_device.dev.platform_data = &palmtx_pxa_irda_funcs; } Added: linux4palm/linux/trunk/arch/arm/mach-pxa/palmtx/palmtx_battery.c =================================================================== --- linux4palm/linux/trunk/arch/arm/mach-pxa/palmtx/palmtx_battery.c (rev 0) +++ linux4palm/linux/trunk/arch/arm/mach-pxa/palmtx/palmtx_battery.c 2007-03-28 11:04:10 UTC (rev 936) @@ -0,0 +1,249 @@ +/************************************************************************ + * linux/arch/arm/mach-pxa/palmztx/palmtx_battery.c * + * Battery driver for Palm TX * + * * + * Author: Jan Herman <2h...@se...> * + * * + * Based on code for Palm Zire 72 by * + * * + * Authors: Jan Herman <2h...@se...> * + * Sergey Lapin <sl...@ha...> * + * * + ************************************************************************/ + + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/moduleparam.h> +#include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/input.h> +#include <linux/device.h> +#include <linux/workqueue.h> +#include <linux/battery.h> + +#include <asm/apm.h> +#include <asm/delay.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/arch/hardware.h> +#include <asm/arch/pxa-regs.h> +#include <asm/arch/irqs.h> + +#include <sound/driver.h> +#include <sound/core.h> +#include <sound/pcm.h> +#include <sound/initval.h> +#include <linux/wm97xx.h> +#include <asm/arch/palmtx-gpio.h> +#include <asm/arch/palmtx-init.h> + + +struct palmtx_battery_dev +{ + struct wm97xx * wm; + int battery_registered; + int current_voltage; + int previous_voltage; + u32 last_battery_update; +}; + +struct palmtx_battery_dev bat; + +#if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE) +/* original APM hook */ +static void (*apm_get_power_status_orig)(struct apm_power_info *info); +#endif + +int palmtx_battery_min_voltage(struct battery *b) +{ + return PALMTX_BAT_MIN_VOLTAGE; +} + + +int palmtx_battery_max_voltage(struct battery *b) +{ + return PALMTX_BAT_MAX_VOLTAGE; /* mV */ +} + +/* + This formula is based on battery life of my battery 1100mAh. Original battery in Zire72 is Li-On 920mAh + V_batt = ADCSEL_BMON * 1,889 + 767,8 [mV] +*/ + +int palmtx_battery_get_voltage(struct battery *b) +{ + if (bat.battery_registered){ + bat.previous_voltage = bat.current_voltage; + bat.current_voltage = wm97xx_read_aux_adc(bat.wm, WM97XX_AUX_ID3); + bat.last_battery_update = jiffies; + return bat.current_voltage * 1889/1000 + 7678/10; + } + else{ + printk("palmtx_battery: cannot get voltage -> battery driver unregistered\n"); + return 0; + } +} + + +int palmtx_battery_get_status(struct battery *b) +{ + int ac_connected = GET_GPIO(GPIO_NR_PALMTX_POWER_DETECT); + int usb_connected = !GET_GPIO(GPIO_NR_PALMTX_USB_DETECT); + + if (bat.current_voltage <= 0) + return BATTERY_STATUS_UNKNOWN; + + if (ac_connected || usb_connected){ + if ( ( bat.current_voltage > bat.previous_voltage ) || (bat.current_voltage <= PALMTX_BAT_MAX_VOLTAGE) ) + return BATTERY_STATUS_CHARGING; + return BATTERY_STATUS_NOT_CHARGING; + } + else + return BATTERY_STATUS_DISCHARGING; +} + +struct battery palmtx_battery = { + .name = "palmtx_battery", + .id = "battery0", + .get_min_voltage = palmtx_battery_min_voltage, + .get_max_voltage = palmtx_battery_max_voltage, + .get_voltage = palmtx_battery_get_voltage, + .get_status = palmtx_battery_get_status, +}; + +static int palmtx_wm97xx_probe(struct device *dev) +{ + struct wm97xx *wm = dev->driver_data; + bat.wm = wm; + return 0; +} + +static int palmtx_wm97xx_remove(struct device *dev) +{ + return 0; +} + +static void +palmtx_wm97xx_shutdown(struct device *dev) +{ +#if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE) + apm_get_power_status = apm_get_power_status_orig; +#endif +} + +static int +palmtx_wm97xx_suspend(struct device *dev, pm_message_t state) +{ + return 0; +} + +static int +palmtx_wm97xx_resume(struct device *dev) +{ + return 0; +} + + +static struct device_driver palmtx_wm97xx_driver = { + .name = "wm97xx-touchscreen", + .bus = &wm97xx_bus_type, + .owner = THIS_MODULE, + .probe = palmtx_wm97xx_probe, + .remove = palmtx_wm97xx_remove, + .suspend = palmtx_wm97xx_suspend, + .resume = palmtx_wm97xx_resume, + .shutdown = palmtx_wm97xx_shutdown +}; + +static int palmtx_ac_is_connected (void){ + /* when charger is plugged in, then status is ONLINE */ + int ret = ((GET_GPIO(GPIO_NR_PALMTX_POWER_DETECT)));; + if (ret) + ret = 1; + else + ret = 0; + + return ret; +} + +#if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE) + +/* APM status query callback implementation */ +static void palmtx_apm_get_power_status(struct apm_power_info *info) +{ + int min, max, curr, percent; + + curr = palmtx_battery_get_voltage(&palmtx_battery); + min = palmtx_battery_min_voltage(&palmtx_battery); + max = palmtx_battery_max_voltage(&palmtx_battery); + + curr = curr - min; + if (curr < 0) curr = 0; + max = max - min; + + percent = curr*100/max; + + info->battery_life = percent; + + info->ac_line_status = palmtx_ac_is_connected() ? APM_AC_ONLINE : APM_AC_OFFLINE; + + if (info->ac_line_status) { + info->battery_status = APM_BATTERY_STATUS_CHARGING; + } else { + if (percent > 50) + info->battery_status = APM_BATTERY_STATUS_HIGH; + else if (percent < 5) + info->battery_status = APM_BATTERY_STATUS_CRITICAL; + else + info->battery_status = APM_BATTERY_STATUS_LOW; + } + + info->time = percent * PALMTX_MAX_LIFE_MINS/100; + info->units = APM_UNITS_MINS; +} +#endif +static int __init palmtx_wm97xx_init(void) +{ +#ifndef MODULE + int ret; +#endif + + /* register battery to APM layer */ + bat.battery_registered = 0; + + if(battery_class_register(&palmtx_battery)) { + printk(KERN_ERR "palmtx_ac97_probe: could not register battery class\n"); + } + else { + bat.battery_registered = 1; + printk("Battery registered\n"); + } +#if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE) + apm_get_power_status_orig = apm_get_power_status; + apm_get_power_status = palmtx_apm_get_power_status; +#endif +#ifndef MODULE + /* If we're in kernel, we could accidentally be run before wm97xx + and thus have panic */ + if((ret = bus_register(&wm97xx_bus_type)) < 0) + return ret; +#endif + return driver_register(&palmtx_wm97xx_driver); +} + +static void __exit palmtx_wm97xx_exit(void) +{ +/* TODO - recover APM callback to original state */ + battery_class_unregister(&palmtx_battery); + driver_unregister(&palmtx_wm97xx_driver); +} + +module_init(palmtx_wm97xx_init); +module_exit(palmtx_wm97xx_exit); + +/* Module information */ +MODULE_AUTHOR("Jan Herman <2h...@se...>"); +MODULE_DESCRIPTION("wm97xx battery driver for Palm TX"); +MODULE_LICENSE("GPL"); Added: linux4palm/linux/trunk/arch/arm/mach-pxa/palmtx/palmtx_pm.c =================================================================== --- linux4palm/linux/trunk/arch/arm/mach-pxa/palmtx/palmtx_pm.c (rev 0) +++ linux4palm/linux/trunk/arch/arm/mach-pxa/palmtx/palmtx_pm.c 2007-03-28 11:04:10 UTC (rev 936) @@ -0,0 +1,136 @@ +/************************************************************************ + * Palm TX suspend/resume support * + * Author: Jan Herman <2h...@se...> * + * * + * Based on code from PalmOne Zire 72 PM by: * + * 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. * + * * + ************************************************************************/ + +#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/palmtx-gpio.h> +#include <asm/arch/pxa27x_keyboard.h> + +#ifdef CONFIG_PM +static int palmtx_suspend(struct device *dev, pm_message_t state) +{ + /* Wake-Up on RTC event, etc. */ + PWER |= PWER_RTC | PWER_WEP1 | PWER_GPIO14 | PWER_GPIO10 | PWER_GPIO13 ; + PRER |= PWER_GPIO14 | PWER_GPIO10 | PWER_GPIO13 ; + + /* Wakeup by keyboard - in progress */ + PKWR = 0xfffff; + + /* Enabled Deep-Sleep mode */ + PCFR |= PCFR_DS; + + /* Low power mode */ + PCFR |= PCFR_OPDE; + + /* 3.6.8.1 */ + while(!(OSCC & OSCC_OOK)) + {} + + /* Turn off LCD power */ + //SET_PALMZ72_GPIO(LCD_POWER,0); + /* Turn screen off */ + //SET_PALMZ72_GPIO(SCREEN,0); + /* Turn off USB power */ + //SET_PALMZ72_GPIO(USB_POWER,0); + + + /* disable GPIO reset - DO NOT REMOVE! */ + PCFR &= PCFR_GPR_EN; + + return 0; +} + +static int palmtx_resume(struct device *dev) +{ + + /* Disabled Deep-Sleep mode ?? */ + PCFR &= PCFR_DS; + + /* Re-enable GPIO reset */ + PCFR |= PCFR_GPR_EN; /* !! DO NOT REMOVE !! THIS IS NECCESARY FOR ENABLE PALM RESET !! */ + + + /* Here are all of special to resume Palm TX */ + + /* Turn on LCD power */ + //SET_PALMZ72_GPIO(LCD_POWER,1); + /* Turn screen on */ + //SET_PALMZ72_GPIO(SCREEN,1); + /* Turn on USB power */ + //SET_PALMZ72_GPIO(USB_POWER,1); + + return 0; +} +#else +#define palmtx_suspend NULL +#define palmtx_resume NULL +#endif + +static void palmtx_pxa_ll_pm_suspend(unsigned long resume_addr) +{ + /* For future */ + return; +} + +static void palmtx_pxa_ll_pm_resume(void) +{ + /* For future */ +} + +struct pxa_ll_pm_ops palmtx_ll_pm_ops = { + .suspend = palmtx_pxa_ll_pm_suspend, + .resume = palmtx_pxa_ll_pm_resume, +}; + +static int palmtx_pm_probe(struct device *dev) +{ + printk(KERN_NOTICE "Palm TX power management driver registered\n"); + return 0; +} + +struct device_driver palmtx_pm_driver = { + .name = "palmtx-pm", + .bus = &platform_bus_type, + .probe = palmtx_pm_probe, + .suspend = palmtx_suspend, + .resume = palmtx_resume, +}; + +static int __init palmtx_pm_init(void) +{ + return driver_register(&palmtx_pm_driver); +} + +static void __exit palmtx_pm_exit(void) +{ + driver_unregister(&palmtx_pm_driver); +} + +module_init(palmtx_pm_init); +module_exit(palmtx_pm_exit); + +MODULE_AUTHOR("Jan Herman <2h...@se...>"); +MODULE_DESCRIPTION("Palm TX power management driver"); +MODULE_LICENSE("GPL"); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |