diff options
Diffstat (limited to 'packages/linux/linux-ezx-2.6.21/patches/ezx-eoc.patch')
-rw-r--r-- | packages/linux/linux-ezx-2.6.21/patches/ezx-eoc.patch | 342 |
1 files changed, 342 insertions, 0 deletions
diff --git a/packages/linux/linux-ezx-2.6.21/patches/ezx-eoc.patch b/packages/linux/linux-ezx-2.6.21/patches/ezx-eoc.patch new file mode 100644 index 0000000000..f21894e904 --- /dev/null +++ b/packages/linux/linux-ezx-2.6.21/patches/ezx-eoc.patch @@ -0,0 +1,342 @@ +Index: linux-2.6.21/arch/arm/mach-pxa/ezx-eoc.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-2.6.21/arch/arm/mach-pxa/ezx-eoc.c 2007-09-09 13:33:19.000000000 -0300 +@@ -0,0 +1,270 @@ ++/* ++ * EZX EOC Driver for Motorola EZX phones ++ * ++ * Copyright (C) 2007 Alex Zhang <celeber2@gmail.com> ++ * ++ * 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/init.h> ++#include <linux/i2c.h> ++#include <linux/platform_device.h> ++ ++#include <asm/arch/hardware.h> ++#include <asm/arch/pxa-regs.h> ++#include <asm/arch/ezx.h> ++ ++#include "ezx-eoc.h" ++ ++#if 1 ++#define EOC_DBG printk ++#else ++#define EOC_DBG(x, args...) ++#endif ++ ++#define EOC_REG_ADDR_SIZE 1 ++#define EOC_REG_DATA_SIZE 3 ++ ++struct ezx_eoc_platform_data *pdata; ++static int eoc_func = EOC_FUNC_USB_NET; ++static const char eoc_i2c_driver_name[] = "ezx-eoc"; ++ ++/* Addresses to scan */ ++static unsigned short normal_i2c[] = { ++ 0x17, /* Address for version 2.0 and above */ ++ // 0x7C, /* Address for versions prior too 2.0 */ ++ I2C_CLIENT_END ++}; ++ ++/* I2C Magic */ ++I2C_CLIENT_INSMOD; ++ ++static int ezx_eoc_attach_adapter(struct i2c_adapter *adapter); ++static int ezx_eoc_detect(struct i2c_adapter *adapter, int address, int kind); ++static int ezx_eoc_detach_client(struct i2c_client *client); ++ ++static struct i2c_client *eoc_i2c_client = NULL; ++ ++static struct i2c_driver eoc_i2c_driver = { ++ .driver = { ++ .name = (char *)eoc_i2c_driver_name, ++ }, ++ .id = I2C_DRIVERID_EEPROM, ++ .attach_adapter = ezx_eoc_attach_adapter, ++ .detach_client = ezx_eoc_detach_client, ++}; ++ ++int eoc_reg_read(int reg, unsigned int *reg_value) ++{ ++ unsigned char reg_num = reg; ++ unsigned char value[EOC_REG_DATA_SIZE]; ++ int retval; ++ ++ struct i2c_msg msgs[2] = ++ { ++ { 0, 0, EOC_REG_ADDR_SIZE, ®_num }, ++ { 0, I2C_M_RD, EOC_REG_DATA_SIZE, value } ++ }; ++ ++ /* check if we have initialized */ /*not necessary --WM ++ if (eoc_i2c_client == NULL) ++ { ++ EOC_DBG("eoc_reg_read: not initialized\n"); ++ return -EINVAL; ++ } ++*/ ++ msgs[0].addr = msgs[1].addr = eoc_i2c_client->addr; ++ ++ /* transfer message to client */ ++ retval = i2c_transfer(eoc_i2c_client->adapter, msgs, 2); ++ if (retval >= 0) ++ { ++ *reg_value = (value[2] << 0); ++ *reg_value |= (value[1] << 8); ++ *reg_value |= (value[0] << 16); ++ } ++ return retval; ++} ++EXPORT_SYMBOL_GPL(eoc_reg_read); ++ ++int eoc_reg_write(int reg, unsigned int reg_value) ++{ ++ unsigned char value[EOC_REG_ADDR_SIZE + EOC_REG_DATA_SIZE]; ++ int retval; ++ ++ /* check if we have initialized */ /*not necessary --WM ++ if (eoc_i2c_client == NULL) ++ { ++ EOC_DBG("eoc_reg_write: not initialized\n"); ++ return -EINVAL; ++ } ++*/ ++ /* Copy the data into a buffer into the correct format */ ++ value[0] = reg; ++ value[1] = (reg_value >> 16) & 0xFF; ++ value[2] = (reg_value >> 8) & 0xFF; ++ value[3] = (reg_value >> 0) & 0xFF; ++ ++ /* Write the data to the EOC */ ++ retval = i2c_master_send (eoc_i2c_client, value, EOC_REG_ADDR_SIZE + EOC_REG_DATA_SIZE); ++ ++ return retval; ++} ++EXPORT_SYMBOL_GPL(eoc_reg_write); ++ ++static void eoc_switch_to_usb(void) ++{ ++ pxa_gpio_mode(GPIO34_USB_P2_2_MD); ++ pxa_gpio_mode(GPIO35_USB_P2_1_MD); ++ pxa_gpio_mode(GPIO36_USB_P2_4_MD); ++ pxa_gpio_mode(GPIO39_USB_P2_6_MD); ++ pxa_gpio_mode(GPIO40_USB_P2_5_MD); ++ pxa_gpio_mode(GPIO53_USB_P2_3_MD); ++ EOC_DBG("ALEX;*********************************************emu_switch_to_usb;\n"); ++} ++ ++static void eoc_switch_to_nothing(void) ++{ ++ pxa_gpio_mode(GPIO34_TXENB | GPIO_OUT); ++ set_GPIO(GPIO34_TXENB); ++ pxa_gpio_mode(GPIO35_XRXD | GPIO_IN); ++ pxa_gpio_mode(GPIO36_VMOUT | GPIO_IN); ++ pxa_gpio_mode(GPIO39_VPOUT | GPIO_IN); ++ pxa_gpio_mode(GPIO40_VPIN | GPIO_IN); ++ pxa_gpio_mode(GPIO53_VMIN | GPIO_IN); ++} ++ ++static void eoc_switch_to_default(void) ++{ ++ switch (eoc_func) { ++ case EOC_FUNC_USB_NET: ++ eoc_switch_to_usb(); ++ break; ++ case EOC_FUNC_NOTHING: ++ eoc_switch_to_nothing(); ++ break; ++ } ++} ++ ++ ++static int ezx_eoc_attach_adapter(struct i2c_adapter *adapter) ++{ ++ return i2c_probe(adapter, &addr_data, ezx_eoc_detect); ++} ++ ++/* This function is called by i2c_probe */ ++static int ezx_eoc_detect(struct i2c_adapter *adapter, int address, int kind) ++{ ++ struct i2c_client *new_client; ++ int err = 0; ++ ++ if (!(new_client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL))) ++ return -ENOMEM; ++ ++ new_client->addr = address; ++ new_client->adapter = adapter; ++ new_client->driver = &eoc_i2c_driver; ++ new_client->flags = 0; ++ strlcpy(new_client->name, eoc_i2c_driver_name, I2C_NAME_SIZE); ++ ++ if ((err = i2c_attach_client(new_client))) { ++ kfree(new_client); ++ return err; ++ } ++ ++ eoc_i2c_client = new_client; ++ ++ if (pdata && pdata->init) { ++ pdata->init(); ++ } ++ else ++ return -EINVAL; ++ ++ eoc_switch_to_default(); ++ ++ return 0; ++} ++ ++static int ezx_eoc_detach_client(struct i2c_client *client) ++{ ++ int err; ++ ++ err = i2c_detach_client(client); ++ if (err) ++ return err; ++ ++ return 0; ++} ++ ++static int __init ezx_eoc_probe(struct platform_device *dev) ++{ ++ int ret; ++ ++ pdata = dev->dev.platform_data; ++ ++ ret = i2c_add_driver(&eoc_i2c_driver); ++ if (ret != 0) ++ return -EINVAL; ++ ++ /* ++ * I think we should save platform_data and call init and eoc_switch ++ * from ezx_eoc_detect, after client is setup. ++ * And there is no need for all the "check if initialised" checks if ++ * you assure that you only call read/write after the client is set. ++ * Probably, this was causing the crash on i2c-core too. ++ * --WM ++ */ ++ ++ /* FIXME: should set udc_info here -WM */ ++ return 0; ++} ++ ++static int ezx_eoc_remove(struct platform_device *dev) ++{ ++ return i2c_del_driver(&eoc_i2c_driver); ++} ++ ++static int ezx_eoc_suspend(struct platform_device *dev, pm_message_t state) ++{ ++ eoc_switch_to_nothing(); ++ return 0; ++} ++ ++static int ezx_eoc_resume(struct platform_device *dev) ++{ ++ eoc_switch_to_default(); ++ return 0; ++} ++ ++static struct platform_driver ezx_eoc_driver = { ++ .probe = ezx_eoc_probe, ++ .remove = ezx_eoc_remove, ++ .suspend = ezx_eoc_suspend, ++ .resume = ezx_eoc_resume, ++ .driver = { ++ .name = "ezx-eoc", ++ .owner = THIS_MODULE, ++ }, ++}; ++ ++int __init ezx_eoc_init(void) ++{ ++ return platform_driver_register(&ezx_eoc_driver); ++} ++ ++void ezx_eoc_exit(void) ++{ ++ return platform_driver_unregister(&ezx_eoc_driver); ++} ++ ++MODULE_AUTHOR("Alex Zhang <celeber2@gmail.com>"); ++MODULE_DESCRIPTION("EZX EOC I2C driver"); ++MODULE_LICENSE("GPL"); ++ ++/* doesnt module_init work?? -WM */ ++/*late_initcall(ezx_eoc_init);*/ ++module_init(ezx_eoc_init); ++module_exit(ezx_eoc_exit); +Index: linux-2.6.21/arch/arm/mach-pxa/ezx-eoc.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-2.6.21/arch/arm/mach-pxa/ezx-eoc.h 2007-09-07 22:15:52.000000000 -0300 +@@ -0,0 +1,33 @@ ++/* ++ * linux/arch/arm/mach-pxa/ezx-eoc.h ++ * ++ * Copyright (C) Alex Zhang <celeber2@gmail.com> ++ * ++ * 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. ++ */ ++ ++#ifndef __EZX_EOC_H__ ++#define __EZX_EOC_H__ ++ ++enum { ++ POWER_IC_REG_EOC_INT_STATUS, ++ POWER_IC_REG_EOC_INT_MASK, ++ POWER_IC_REG_EOC_INT_SENSE, ++ POWER_IC_REG_EOC_POWER_CONTROL_0, ++ POWER_IC_REG_EOC_POWER_CONTROL_1, ++ POWER_IC_REG_EOC_CONN_CONTROL, ++ POWER_IC_REG_EOC_NUM ++}; ++ ++enum { ++ EOC_FUNC_NOTHING, ++ EOC_FUNC_USB_NET, ++}; ++ ++struct ezx_eoc_platform_data { ++ int (*init)(void); ++}; ++ ++#endif /* __EZX_EOC_H__ */ +Index: linux-2.6.21/arch/arm/mach-pxa/Kconfig +=================================================================== +--- linux-2.6.21.orig/arch/arm/mach-pxa/Kconfig 2007-09-07 22:15:52.000000000 -0300 ++++ linux-2.6.21/arch/arm/mach-pxa/Kconfig 2007-09-07 22:15:52.000000000 -0300 +@@ -108,6 +108,12 @@ + config EZX_PCAP + bool "PCAP Support" + ++config EZX_EOC ++ tristate "EOC i2c driver of Motorola EZX phones" ++ depends on I2C && EXPERIMENTAL && PXA_EZX_A1200 ++ help ++ EOC i2c driver of Motorola EZX phones ++ + config EZX_EMU + bool "Motorola Enchanced Mini Usb" + depends on EZX_PCAP +Index: linux-2.6.21/arch/arm/mach-pxa/Makefile +=================================================================== +--- linux-2.6.21.orig/arch/arm/mach-pxa/Makefile 2007-09-07 22:15:52.000000000 -0300 ++++ linux-2.6.21/arch/arm/mach-pxa/Makefile 2007-09-07 22:15:52.000000000 -0300 +@@ -27,6 +27,7 @@ + obj-$(CONFIG_EZX_BP) += ezx-bp.o + obj-$(CONFIG_EZX_PCAP) += ezx-pcap.o + obj-$(CONFIG_EZX_EMU) += ezx-emu.o ++obj-$(CONFIG_EZX_EOC) += ezx-eoc.o + + # Support for blinky lights + led-y := leds.o |