diff options
author | Koen Kooi <koen@openembedded.org> | 2007-10-31 13:46:47 +0000 |
---|---|---|
committer | Koen Kooi <koen@openembedded.org> | 2007-10-31 13:46:47 +0000 |
commit | 44cbb9985f111ce87e6990061c89e2e061b6c6ea (patch) | |
tree | f26c7f7df66d468547e5b5cc8ba8dc328c44f08d /packages/linux/linux-ezx-2.6.23/patches/ezx-bp.patch | |
parent | 43b6ecbcb39354a32e0b8dd7c02ec8789be0ab9a (diff) | |
parent | 821528ad116a72c2323d88d21e979614c78f1b41 (diff) |
propagate from branch 'org.openembedded.dev' (head a6b798a43c05aef43ed650ab880f3edd386d0aa3)
to branch 'org.openembedded.dev.avr32' (head 77e1041de2eef682f183f3f5199826818cb9c5b1)
Diffstat (limited to 'packages/linux/linux-ezx-2.6.23/patches/ezx-bp.patch')
-rw-r--r-- | packages/linux/linux-ezx-2.6.23/patches/ezx-bp.patch | 340 |
1 files changed, 340 insertions, 0 deletions
diff --git a/packages/linux/linux-ezx-2.6.23/patches/ezx-bp.patch b/packages/linux/linux-ezx-2.6.23/patches/ezx-bp.patch new file mode 100644 index 0000000000..a20adc464c --- /dev/null +++ b/packages/linux/linux-ezx-2.6.23/patches/ezx-bp.patch @@ -0,0 +1,340 @@ +Index: linux-2.6.23/arch/arm/mach-pxa/ezx.c +=================================================================== +--- linux-2.6.23.orig/arch/arm/mach-pxa/ezx.c 2007-10-23 12:03:55.000000000 +0200 ++++ linux-2.6.23/arch/arm/mach-pxa/ezx.c 2007-10-23 13:21:24.000000000 +0200 +@@ -86,8 +86,40 @@ + .init = ezx_ohci_init, + }; + ++/* BP */ ++static struct resource ezxbp_resources[] = { ++ [0] = { ++ .start = IRQ_GPIO(GPIO_BP_RDY), ++ .end = IRQ_GPIO(GPIO_BP_RDY), ++ .flags = IORESOURCE_IRQ, ++ }, ++ [1] = { ++ .start = IRQ_GPIO(GPIO_BB_WDI2), ++ .end = IRQ_GPIO(GPIO_BB_WDI2), ++ .flags = IORESOURCE_IRQ, ++ }, ++ [2] = { ++ .start = IRQ_GPIO(GPIO_BB_WDI), ++ .end = IRQ_GPIO(GPIO_BB_WDI), ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++static struct platform_device ezxbp_device = { ++ .name = "ezx-bp", ++ .dev = { ++ //.parent = ++ //.platform_data = ++ }, ++ .id = -1, ++ .num_resources = ARRAY_SIZE(ezxbp_resources), ++ .resource = ezxbp_resources, ++}; ++ ++ + + static struct platform_device *devices[] __initdata = { ++ &ezxbp_device, + }; + + static int __init ezx_init(void) +Index: linux-2.6.23/arch/arm/mach-pxa/Kconfig +=================================================================== +--- linux-2.6.23.orig/arch/arm/mach-pxa/Kconfig 2007-10-23 12:03:55.000000000 +0200 ++++ linux-2.6.23/arch/arm/mach-pxa/Kconfig 2007-10-23 13:21:23.000000000 +0200 +@@ -106,6 +106,9 @@ + + endchoice + ++config EZX_BP ++ bool "BP Control code for EZX Platform" ++ + endif + + endmenu +Index: linux-2.6.23/arch/arm/mach-pxa/ezx-bp.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-2.6.23/arch/arm/mach-pxa/ezx-bp.c 2007-10-23 13:22:01.000000000 +0200 +@@ -0,0 +1,264 @@ ++/* ++ * BP handshake code for Motorola EZX phones ++ * ++ * Copyright (c) 2007 Daniel Ribeiro <drwyrm@gmail.com> ++ * ++ * Based on Motorola's a780.c Copyright (c) 2003-2005 Motorola ++ * ++ * 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/interrupt.h> ++#include <linux/module.h> ++#include <linux/platform_device.h> ++ ++#include <asm/mach/irq.h> ++#include <asm/arch/hardware.h> ++#include <asm/arch/pxa-regs.h> ++ ++#include <asm/arch/ezx.h> ++ ++/* BP Handshake */ ++#define FIRST_STEP 2 ++#define LAST_STEP 3 ++#define BP_RDY_TIMEOUT 0x000c0000 ++ ++#if 1 ++#define DEBUGP(x, args ...) printk(x, ##args) ++#else ++#define DEBUGP(x, args ...) ++#endif ++ ++extern void usb_send_readurb(void); ++ ++struct bp { ++ int irq_wdi; ++ int irq_wdi2; ++ int irq_rdy; ++}; ++ ++/* check power down condition */ ++static inline void check_power_off(void) ++{ ++ if (pxa_gpio_get_value(GPIO_BB_WDI2) == 0) { ++ DEBUGP("BP request poweroff!\n"); ++ /* ++ * It is correct to power off here, the following line is ++ * commented out because e680 lowers WDI2 when BP is in ++ * flash mode, otherwise WDI2 is used to detect low ++ * battery. You can safely uncomment this line if you are ++ * using this kernel with BP in normal mode. ++ */ ++#ifndef CONFIG_PXA_EZX_E680 ++ pm_power_off(); ++#endif ++ } ++} ++ ++static int step = FIRST_STEP; ++ ++inline int bp_handshake_passed(void) ++{ ++ return (step > LAST_STEP); ++} ++EXPORT_SYMBOL(bp_handshake_passed); ++ ++void handshake(void) ++{ ++ /* step 1: check MCU_INT_SW or BP_RDY is low (now it is checked in apboot) */ ++ DEBUGP("bp handshake entered!\n"); ++ if (step == 1) { ++ int timeout = BP_RDY_TIMEOUT; ++ ++ /* config MCU_INT_SW, BP_RDY as input */ ++ pxa_gpio_mode(GPIO_MCU_INT_SW | GPIO_IN); ++ pxa_gpio_mode(GPIO_BP_RDY | GPIO_IN); ++ ++ while (timeout--) { ++ if (pxa_gpio_get_value(GPIO_MCU_INT_SW) == 0 ++ || pxa_gpio_get_value(GPIO_BP_RDY) == 0) { ++ step ++; ++ break; ++ } ++ ++ check_power_off(); ++ } ++ DEBUGP("ezx-bp: handshake step 1\n"); ++ } ++ ++ /* step 2: wait BP_RDY is low */ ++ if (step == 2) { ++ if (pxa_gpio_get_value(GPIO_BP_RDY) == 0) { ++ /* config MCU_INT_SW as output */ ++ pxa_gpio_mode(GPIO_MCU_INT_SW | GPIO_OUT); ++ pxa_gpio_set_value(GPIO_MCU_INT_SW, 0); ++ ++ step ++; ++ DEBUGP("ezx-bp: handshake step 2\n"); ++ } ++ } ++ ++ /* step 3: wait BP_RDY is high */ ++ else if (step == 3) { ++ if (pxa_gpio_get_value(GPIO_BP_RDY)) { ++ step ++; ++ //FIXME delay_bklight(); ++ pxa_gpio_set_value(GPIO_MCU_INT_SW, 1); ++ printk(KERN_NOTICE "ezx-bp: handshake passed\n"); ++ } ++ } ++} ++ ++irqreturn_t bp_wdi_handler(int irq, void *dev_id) ++{ ++ DEBUGP("BP Lowered WDI line. This is not good :(\n"); ++ /* ++ * this means that BP is not responsive. ++ * we could try to reset BP and then handshake again ++ * but i doubt its possible to bring it up again. ++ */ ++ return IRQ_HANDLED; ++} ++ ++static irqreturn_t bp_rdy_handler(int irq, void *dev_id) ++{ ++ struct bp *bp = dev_id; ++ DEBUGP("BP rdy irq\n"); ++ if (!bp_handshake_passed()) { ++ handshake(); ++ if (bp_handshake_passed()) { ++ /* FIXME: (test) try to not disable irq_wdi2 and drain battery */ ++ disable_irq(bp->irq_wdi2); ++ ++ /* set bp_rdy handle for usb ipc */ ++ set_irq_type(bp->irq_rdy, IRQT_FALLING); ++ } ++ } ++#ifdef CONFIG_TS0710_MUX_USB ++ else usb_send_readurb(); ++#endif ++ return IRQ_HANDLED; ++} ++ ++/* BP request for poweroff */ ++static irqreturn_t bp_wdi2_handler(int irq, void *dev_id) ++{ ++ DEBUGP("BP request poweroff!\n"); ++ /* same case as check_power_off() */ ++#ifndef CONFIG_PXA_EZX_E680 ++ pm_power_off(); ++#endif ++ return IRQ_HANDLED; ++} ++ ++static int __init ezxbp_probe(struct platform_device *dev) ++{ ++ int ret; ++ struct bp *bp; ++ ++ bp = kzalloc(sizeof(*bp), GFP_KERNEL); ++ if (!bp) ++ return -ENOMEM; ++ ++ bp->irq_rdy = platform_get_irq(dev, 0); ++ if(bp->irq_rdy < 0) { ++ ret = bp->irq_rdy; ++ goto fail; ++ } ++ ++ bp->irq_wdi2 = platform_get_irq(dev, 1); ++ if(bp->irq_wdi2 < 0) { ++ ret = bp->irq_wdi2; ++ goto fail; ++ } ++ ++ bp->irq_wdi = platform_get_irq(dev, 2); ++ if(bp->irq_wdi < 0) { ++ ret = bp->irq_wdi; ++ goto fail; ++ } ++ ++ set_irq_type(bp->irq_wdi, IRQT_FALLING); ++ request_irq(bp->irq_wdi, bp_wdi_handler, IRQF_DISABLED, ++ "bp wdi", bp); ++ ++ set_irq_type(bp->irq_rdy, IRQT_BOTHEDGE); ++ request_irq(bp->irq_rdy, bp_rdy_handler, IRQF_DISABLED, ++ "bp rdy", bp); ++ ++ set_irq_type(bp->irq_wdi2, IRQT_FALLING); ++ request_irq(bp->irq_wdi2, bp_wdi2_handler, IRQF_DISABLED, ++ "bp wdi2", bp); ++ ++ /* turn on BP */ ++ pxa_gpio_mode(GPIO_BB_RESET|GPIO_OUT); ++ pxa_gpio_set_value(GPIO_BB_RESET, 1); ++ ++ check_power_off(); ++ handshake(); ++ ++ return 0; ++fail: ++ kfree(bp); ++ return ret; ++} ++ ++static int ezxbp_remove(struct platform_device *dev) ++{ ++ struct bp *bp = platform_get_drvdata(dev); ++ ++ free_irq(bp->irq_wdi, bp); ++ free_irq(bp->irq_wdi2, bp); ++ free_irq(bp->irq_rdy, bp); ++ kfree(bp); ++ ++ return 0; ++} ++ ++static int ezxbp_suspend(struct platform_device *dev, pm_message_t state) ++{ ++ DEBUGP("bp suspend!\n"); ++// pxa_gpio_set_value(GPIO_MCU_INT_SW, 0); ++ return 0; ++} ++ ++static int ezxbp_resume(struct platform_device *dev) ++{ ++ DEBUGP("bp resume!\n"); ++// pxa_gpio_set_value(GPIO_MCU_INT_SW, 1); ++ return 0; ++} ++static struct platform_driver ezxbp_driver = { ++ .probe = ezxbp_probe, ++ .remove = ezxbp_remove, ++#warning FIXME: missing suspend/resume support ++ .suspend = ezxbp_suspend, ++ .resume = ezxbp_resume, ++ .driver = { ++ .name = "ezx-bp", ++ .owner = THIS_MODULE, ++ }, ++}; ++ ++int __init ezxbp_init(void) ++{ ++ return platform_driver_register(&ezxbp_driver); ++} ++ ++void ezxbp_fini(void) ++{ ++ return platform_driver_unregister(&ezxbp_driver); ++} ++ ++module_init(ezxbp_init); ++module_exit(ezxbp_fini); ++ ++MODULE_DESCRIPTION("Motorola BP Control driver"); ++MODULE_AUTHOR("Daniel Ribeiro <drwyrm@gmail.com>"); ++MODULE_LICENSE("GPL"); ++ +Index: linux-2.6.23/arch/arm/mach-pxa/Makefile +=================================================================== +--- linux-2.6.23.orig/arch/arm/mach-pxa/Makefile 2007-10-23 12:03:55.000000000 +0200 ++++ linux-2.6.23/arch/arm/mach-pxa/Makefile 2007-10-23 13:21:23.000000000 +0200 +@@ -25,6 +25,7 @@ + obj-$(CONFIG_PXA_EZX_E2) += ezx-e2.o + obj-$(CONFIG_PXA_EZX_A1200) += ezx-a1200.o + obj-$(CONFIG_PXA_EZX_E6) += ezx-e6.o ++obj-$(CONFIG_EZX_BP) += ezx-bp.o + + # Support for blinky lights + led-y := leds.o |