summaryrefslogtreecommitdiff
path: root/packages/linux/linux-ezx-2.6.24/patches/ezx-bp.patch
diff options
context:
space:
mode:
authorMichael Lauer <mickey@vanille-media.de>2008-01-28 20:43:08 +0000
committerMichael Lauer <mickey@vanille-media.de>2008-01-28 20:43:08 +0000
commitd3422da17dbc0353f7ca8e6c8202201b3ff54af2 (patch)
tree4ebad87462bca8a06ad39538554be5e0fb8b452d /packages/linux/linux-ezx-2.6.24/patches/ezx-bp.patch
parent8314927eacf95b2f0cb38d4a81ce2b0d555e293d (diff)
parentcdd4a5cedce39a419cb8b217770edf5dd7e7f319 (diff)
merge of '1c44ae3b4aae69a8d66c7c068c44f337bc51f559'
and 'd039068c51d6eb51dd6d0bd1dd1306d490e3d527'
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.patch351
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;
++};