diff options
Diffstat (limited to 'packages/linux/linux-ezx-2.6.24/patches/ezx-bp.patch')
-rw-r--r-- | packages/linux/linux-ezx-2.6.24/patches/ezx-bp.patch | 351 |
1 files changed, 351 insertions, 0 deletions
diff --git a/packages/linux/linux-ezx-2.6.24/patches/ezx-bp.patch b/packages/linux/linux-ezx-2.6.24/patches/ezx-bp.patch new file mode 100644 index 0000000000..e45cb4bd22 --- /dev/null +++ b/packages/linux/linux-ezx-2.6.24/patches/ezx-bp.patch @@ -0,0 +1,351 @@ +This patch adds support for the handshake with the BP (baseband processor) +of the Motorola EZX smartphones. + +Signed-off-by: Daniel Ribeiro <wyrm@openezx.org> + +Index: linux-2.6.24/arch/arm/mach-pxa/ezx.c +=================================================================== +--- linux-2.6.24.orig/arch/arm/mach-pxa/ezx.c ++++ linux-2.6.24/arch/arm/mach-pxa/ezx.c +@@ -19,6 +19,7 @@ + #include <asm/arch/pxa-regs.h> + #include <asm/arch/ohci.h> + #include <asm/arch/ezx.h> ++#include <asm/arch/ezx-bp.h> + + #include "generic.h" + +@@ -86,8 +87,25 @@ + .init = ezx_ohci_init, + }; + ++/* BP */ ++static struct ezxbp_config ezxbp_data = { ++ .gpio_reset = GPIO_BB_RESET, ++ .gpio_wdi = GPIO_BB_WDI, ++ .gpio_wdi2 = GPIO_BB_WDI2, ++ .gpio_rdy = GPIO_BP_RDY, ++ .gpio_mcu_int_sw = GPIO_MCU_INT_SW, ++}; ++ ++static struct platform_device ezxbp_device = { ++ .name = "ezx-bp", ++ .dev = { ++ .platform_data = &ezxbp_data, ++ }, ++ .id = -1, ++}; + + static struct platform_device *devices[] __initdata = { ++ &ezxbp_device, + }; + + static int __init ezx_init(void) +Index: linux-2.6.24/arch/arm/mach-pxa/Kconfig +=================================================================== +--- linux-2.6.24.orig/arch/arm/mach-pxa/Kconfig ++++ linux-2.6.24/arch/arm/mach-pxa/Kconfig +@@ -133,6 +133,12 @@ + + endchoice + ++config EZX_BP ++ bool "Baseband Processor control for EZX platform" ++ help ++ This enables control code for the BP (baseband processor) found in ++ Motorola's EZX smartphone platform. ++ + endif + + endmenu +Index: linux-2.6.24/arch/arm/mach-pxa/ezx-bp.c +=================================================================== +--- /dev/null ++++ linux-2.6.24/arch/arm/mach-pxa/ezx-bp.c +@@ -0,0 +1,261 @@ ++/* ++ * BP handshake code for Motorola EZX phones ++ * ++ * Copyright (c) 2007 Daniel Ribeiro <wyrm@openezx.org> ++ * ++ * 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> ++#include <asm/arch/ezx-bp.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); ++ ++static struct ezxbp_config *bp; ++ ++/* check power down condition */ ++static inline void check_power_off(void) ++{ ++ if (pxa_gpio_get_value(bp->gpio_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. ++ */ ++#if 0 /* some versions of BP firmware doesnt honor this */ ++ pm_power_off(); ++#endif ++ } ++} ++ ++static int step = FIRST_STEP; ++ ++inline int bp_handshake_passed(void) ++{ ++ return (step > LAST_STEP); ++} ++EXPORT_SYMBOL_GPL(bp_handshake_passed); ++ ++static 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(bp->gpio_mcu_int_sw | GPIO_IN); ++ pxa_gpio_mode(bp->gpio_rdy | GPIO_IN); ++ ++ while (timeout--) { ++ if (pxa_gpio_get_value(bp->gpio_mcu_int_sw) == 0 ++ || pxa_gpio_get_value(bp->gpio_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(bp->gpio_rdy) == 0) { ++ /* config MCU_INT_SW as output */ ++ pxa_gpio_mode(bp->gpio_mcu_int_sw | GPIO_OUT); ++ pxa_gpio_set_value(bp->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(bp->gpio_rdy)) { ++ step++; ++ /* FIXME delay_bklight(); */ ++ pxa_gpio_set_value(bp->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(IRQ_GPIO(bp->gpio_wdi2)); ++ ++ /* set bp_rdy handle for usb ipc */ ++ set_irq_type(IRQ_GPIO(bp->gpio_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 *pdev) ++{ ++ int ret; ++ bp = pdev->dev.platform_data; ++ ++// 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(IRQ_GPIO(bp->gpio_wdi), IRQT_FALLING); ++ request_irq(IRQ_GPIO(bp->gpio_wdi), bp_wdi_handler, IRQF_DISABLED, ++ "bp wdi", bp); ++ ++ set_irq_type(IRQ_GPIO(bp->gpio_rdy), IRQT_BOTHEDGE); ++ request_irq(IRQ_GPIO(bp->gpio_rdy), bp_rdy_handler, IRQF_DISABLED, ++ "bp rdy", bp); ++ ++ set_irq_type(IRQ_GPIO(bp->gpio_wdi2), IRQT_FALLING); ++ request_irq(IRQ_GPIO(bp->gpio_wdi2), bp_wdi2_handler, IRQF_DISABLED, ++ "bp wdi2", bp); ++ ++ /* turn on BP */ ++ pxa_gpio_mode(bp->gpio_reset|GPIO_OUT); ++ pxa_gpio_set_value(bp->gpio_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(IRQ_GPIO(bp->gpio_wdi), bp); ++ free_irq(IRQ_GPIO(bp->gpio_wdi2), bp); ++ free_irq(IRQ_GPIO(bp->gpio_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(bp->gpio_mcu_int_sw, 0); */ ++ return 0; ++} ++ ++static int ezxbp_resume(struct platform_device *dev) ++{ ++ DEBUGP("bp resume!\n"); ++/* pxa_gpio_set_value(bp->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 <wyrm@openezx.org>"); ++MODULE_LICENSE("GPL"); ++ +Index: linux-2.6.24/arch/arm/mach-pxa/Makefile +=================================================================== +--- linux-2.6.24.orig/arch/arm/mach-pxa/Makefile ++++ linux-2.6.24/arch/arm/mach-pxa/Makefile +@@ -36,6 +36,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 +Index: linux-2.6.24/include/asm-arm/arch-pxa/ezx-bp.h +=================================================================== +--- /dev/null ++++ linux-2.6.24/include/asm-arm/arch-pxa/ezx-bp.h +@@ -0,0 +1,8 @@ ++struct ezxbp_config { ++ /* gpios for handshake */ ++ int gpio_reset; ++ int gpio_wdi; ++ int gpio_wdi2; ++ int gpio_rdy; ++ int gpio_mcu_int_sw; ++}; |