aboutsummaryrefslogtreecommitdiffstats
path: root/packages/linux/linux-ezx-2.6.21/patches/ezx-eoc.patch
diff options
context:
space:
mode:
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.patch342
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, &reg_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