[Bugfix][R306BR][bug-view-1474][USB] use usb detect pin for R306BR, to fix out of skbuff after usb plugin/plugout; old files

Change-Id: I57a61157f14ba706ff1f341b87260e29b355725b
diff --git a/lynq/R306BR/ap/os/linux/linux-3.4.x/drivers/usb/dwc_otg/dwc_otg_chg_identify.c b/lynq/R306BR/ap/os/linux/linux-3.4.x/drivers/usb/dwc_otg/dwc_otg_chg_identify.c
new file mode 100644
index 0000000..6d887bf
--- /dev/null
+++ b/lynq/R306BR/ap/os/linux/linux-3.4.x/drivers/usb/dwc_otg/dwc_otg_chg_identify.c
@@ -0,0 +1,1204 @@
+/* ==========================================================================
+ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_driver.c $
+ * $Revision: #92 $
+ * $Date: 2012/08/10 $
+ * $Change: 2047372 $
+ *
+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
+ * otherwise expressly agreed to in writing between Synopsys and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product under
+ * any End User Software License Agreement or Agreement for Licensed Product
+ * with Synopsys or any supplement thereto. You are permitted to use and
+ * redistribute this Software in source and binary forms, with or without
+ * modification, provided that redistributions of source code must retain this
+ * notice. You may not view, use, disclose, copy or distribute this file or
+ * any information contained herein except pursuant to this license grant from
+ * Synopsys. If you do not agree with this notice, including the disclaimer
+ * below, then you are not authorized to use the Software.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * ========================================================================== */
+
+/** @file
+ * The dwc_otg_driver module provides the initialization and cleanup entry
+ * points for the DWC_otg driver. This module will be dynamically installed
+ * after Linux is booted using the insmod command. When the module is
+ * installed, the dwc_otg_driver_init function is called. When the module is
+ * removed (using rmmod), the dwc_otg_driver_cleanup function is called.
+ *
+ * This module also defines a data structure for the dwc_otg_driver, which is
+ * used in conjunction with the standard ARM lm_device structure. These
+ * structures allow the OTG driver to comply with the standard Linux driver
+ * model in which devices and drivers are registered with a bus driver. This
+ * has the benefit that Linux can expose attributes of the driver and device
+ * in its special sysfs file system. Users can then read or write files in
+ * this file system to perform diagnostics on the driver components or the
+ * device.
+ */
+
+#include "dwc_otg_os_dep.h"
+#include "dwc_os.h"
+#include "dwc_otg_dbg.h"
+#include "dwc_otg_driver.h"
+#include "dwc_otg_attr.h"
+#include "dwc_otg_cil.h"
+#include "dwc_otg_core_if.h"
+#include "dwc_otg_pcd_if.h"
+#include "dwc_otg_hcd_if.h"
+#include "dwc_otg_pcd.h"
+#include <mach/zx29_usb.h>
+#include <linux/android_notify.h>
+#include <mach/highspeed_debug.h>
+#include <linux/wakelock.h>
+#include <linux/clockchips.h>
+#include <linux/clk.h>
+#include <mach/gpio.h> 
+#include <linux/gpio.h>
+#include <mach/pcu.h>
+
+#ifdef USB_CHG_DEV
+#define DWC_DRIVER_VERSION	"3.00a 10-AUG-2012"
+#define DWC_DRIVER_DESC		"HS OTG USB Controller driver"
+static const char dwc_chg_name[] = "zx297520V3_hsotg";
+#endif
+#define DWC_WRITE_REG32(a,v)    ((*(volatile u32 *)(a)) = v)
+#define DWC_READ_REG32(a)     	(*(volatile u32 *)(a))
+
+#define USE_ASIC 1
+#define DMA_ENABLE 0
+
+extern void usb_notify_up(usb_notify_event notify_type, void* puf);
+//extern void usb_detect_callback(void *buf, unsigned int len);
+//extern void zx297510_usbdev_init(void);
+extern void dwc_chg_udelay(uint32_t usecs);
+extern void dwc_chg_mdelay(uint32_t usecs);
+//extern struct wake_lock dwc_otg_wake_lock;
+
+extern void dwc_otg_hal_init(void);
+extern void dwc_otg_hal_exit(void);
+
+/*-------------------------------------------------------------------------*/
+/* Encapsulate the module parameter settings */
+
+struct dwc_otg_driver_module_params {
+	int32_t opt;
+	int32_t otg_cap;
+	int32_t dma_enable;
+	int32_t dma_desc_enable;
+	int32_t dma_burst_size;
+	int32_t speed;
+	int32_t host_support_fs_ls_low_power;
+	int32_t host_ls_low_power_phy_clk;
+	int32_t enable_dynamic_fifo;
+	int32_t data_fifo_size;
+	int32_t dev_rx_fifo_size;
+	int32_t dev_nperio_tx_fifo_size;
+	uint32_t dev_perio_tx_fifo_size[MAX_PERIO_FIFOS];
+	int32_t host_rx_fifo_size;
+	int32_t host_nperio_tx_fifo_size;
+	int32_t host_perio_tx_fifo_size;
+	int32_t max_transfer_size;
+	int32_t max_packet_count;
+	int32_t host_channels;
+	int32_t dev_endpoints;
+	int32_t phy_type;
+	int32_t phy_utmi_width;
+	int32_t phy_ulpi_ddr;
+	int32_t phy_ulpi_ext_vbus;
+	int32_t i2c_enable;
+	int32_t ulpi_fs_ls;
+	int32_t ts_dline;
+	int32_t en_multiple_tx_fifo;
+	uint32_t dev_tx_fifo_size[MAX_TX_FIFOS];
+	uint32_t thr_ctl;
+	uint32_t tx_thr_length;
+	uint32_t rx_thr_length;
+	int32_t pti_enable;
+	int32_t mpi_enable;
+	int32_t lpm_enable;
+	int32_t ic_usb_cap;
+	int32_t ahb_thr_ratio;
+	int32_t power_down;
+	int32_t reload_ctl;
+	int32_t dev_out_nak;
+	int32_t cont_on_bna;
+	int32_t ahb_single;
+	int32_t otg_ver;
+	int32_t adp_enable;
+};
+
+struct g_data
+{
+	dwc_otg_device_t 		g_dwc_otg_dev_t;
+	u32						dwRxQuit;
+	u32						dwTxQuit;
+	u32						g_Connet;
+	u32						g_USB_MODE;
+	u32						g_USB_TIMEOUT;
+	u16						g_status_buf;
+	int						g_State;
+	int 					g_bootfinish;
+	int						g_bootaddr;
+	int						g_bootsize;
+
+	dwc_otg_core_if_t 		core_if_t;
+	dwc_otg_dev_if_t 		dev_if_t;
+	dwc_otg_core_params_t 	g_core_params;
+
+	u32						g_in_pPara[3];
+	u32						g_out_pPara[3];
+//	u_setup_pkt 			g_u_setup_pkt[sizeof(u_setup_pkt)*5];
+	dwc_otg_pcd_t 			g_dwc_otg_pcd_tp;
+//	T_USB_ENUM                    g_enum;
+	//add by 10136329 for charger or PC
+
+};
+#ifdef 	CONFIG_DWC_DEVICE_GPIO_CHARGER
+	int usb_detect_irq;
+	int usb_plugin;
+#endif
+	T_TYPE_USB_DETECT     g_plug_in = TYPE_UNKNOWN;
+	usb_detect_callback	detect_fn = NULL;
+struct g_data	  	*g_chg_usb_global = NULL;
+
+void dwc_chg_Regcallback(usb_detect_callback	fn)
+{
+	USBHAL_DBG("dwc_chg_Regcallback");
+	detect_fn = fn;
+}
+int detected_charger(void)
+{
+#ifdef CONFIG_DWC_DEVICE_GPIO_CHARGER
+	return 1;
+#endif
+	if(detect_fn == NULL)
+		return 1;
+	else return 0;
+}
+
+
+static void dwc_chg_modify_reg32(uint32_t volatile *reg, uint32_t clear_mask, uint32_t set_mask)
+{
+    DWC_WRITE_REG32(reg,(DWC_READ_REG32(reg) & ~clear_mask) | set_mask);
+}
+
+
+static int dwc_otg_chg_setup_params(dwc_otg_core_if_t * core_if)
+{
+    int i;
+    core_if->core_params = &(g_chg_usb_global->g_core_params);
+    core_if->core_params->otg_cap = DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE;
+    core_if->core_params->phy_type = DWC_PHY_TYPE_PARAM_UTMI;
+    core_if->core_params->speed = DWC_SPEED_PARAM_HIGH;//DWC_SPEED_PARAM_FULL
+    core_if->core_params->phy_ulpi_ddr = dwc_param_phy_ulpi_ddr_default;
+    core_if->core_params->phy_ulpi_ext_vbus = dwc_param_phy_ulpi_ext_vbus_default;
+    core_if->core_params->phy_utmi_width = 8;
+    core_if->core_params->ts_dline = dwc_param_ts_dline_default;
+    core_if->core_params->ulpi_fs_ls = dwc_param_ulpi_fs_ls_default;
+    core_if->core_params->en_multiple_tx_fifo = dwc_param_en_multiple_tx_fifo_default;
+
+    core_if->core_params->dma_enable = dwc_param_dma_enable_default;
+    core_if->core_params->dma_desc_enable = dwc_param_dma_desc_enable_default;
+    core_if->core_params->max_transfer_size = dwc_param_max_transfer_size_default;
+    core_if->core_params->dma_burst_size = dwc_param_dma_burst_size_default;
+
+    for (i = 0; i < 15; i++)
+    {
+       core_if->core_params->dev_tx_fifo_size[i] = dwc_param_dev_tx_fifo_size_default;
+    }
+    core_if->core_params->otg_ver = 1;
+    return 0;
+}
+
+dwc_otg_core_if_t *dwc_otg_chg_cil_init(const uint32_t * reg_base_addr)
+{
+    dwc_otg_core_if_t *core_if = &(g_chg_usb_global->core_if_t);
+    dwc_otg_dev_if_t *dev_if = &(g_chg_usb_global->dev_if_t);
+    uint8_t *pt_core_if = ( uint8_t *)&(g_chg_usb_global->core_if_t);
+    uint8_t *pt_dev_if = ( uint8_t *)&(g_chg_usb_global->dev_if_t);
+    uint8_t *reg_base = (uint8_t *) reg_base_addr;
+    int i = 0;
+    for(i= 0;i<sizeof(g_chg_usb_global->core_if_t);i++)
+    {
+        pt_core_if[i] = 0;
+    }
+    core_if->core_global_regs = (dwc_otg_core_global_regs_t *) reg_base;
+
+    for(i= 0;i<sizeof(g_chg_usb_global->dev_if_t);i++)
+    {
+        pt_dev_if[i] = 0;
+    }
+
+    dev_if->dev_global_regs = (dwc_otg_device_global_regs_t *) (reg_base +DWC_DEV_GLOBAL_REG_OFFSET);
+
+    for (i = 0; i < MAX_EPS_CHANNELS; i++)
+    {
+        dev_if->in_ep_regs[i] = (dwc_otg_dev_in_ep_regs_t *)
+                                (reg_base + DWC_DEV_IN_EP_REG_OFFSET +
+                                 (i * DWC_EP_REG_OFFSET));
+
+        dev_if->out_ep_regs[i] = (dwc_otg_dev_out_ep_regs_t *)
+                                 (reg_base + DWC_DEV_OUT_EP_REG_OFFSET +
+                                  (i * DWC_EP_REG_OFFSET));
+
+        core_if->data_fifo[i] =(uint32_t *) (reg_base + DWC_OTG_DATA_FIFO_OFFSET +(i * DWC_OTG_DATA_FIFO_SIZE));
+    }
+
+    dev_if->speed = 0;	
+
+    core_if->dev_if = dev_if;
+
+    core_if->pcgcctl = (uint32_t *) (reg_base + DWC_OTG_PCGCCTL_OFFSET);
+
+    core_if->hwcfg1.d32 =DWC_READ_REG32(&core_if->core_global_regs->ghwcfg1);
+    core_if->hwcfg2.d32 =DWC_READ_REG32(&core_if->core_global_regs->ghwcfg2);
+    core_if->hwcfg3.d32 =DWC_READ_REG32(&core_if->core_global_regs->ghwcfg3);
+    core_if->hwcfg4.d32 =DWC_READ_REG32(&core_if->core_global_regs->ghwcfg4);
+
+    core_if->dcfg.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dcfg);
+
+    core_if->snpsid = DWC_READ_REG32(&core_if->core_global_regs->gsnpsid);
+	
+    dwc_otg_chg_setup_params(core_if);
+
+
+    return core_if;
+}
+
+/**
+ * Initializes the DevSpd field of the DCFG register depending on the PHY type
+ * and the enumeration speed of the device.
+ */
+	/**
+	 * Initializes the DevSpd field of the DCFG register depending on the PHY type
+	 * and the enumeration speed of the device.
+	 */
+static void init_chg_devspd(dwc_otg_core_if_t * core_if,uint8_t speed)
+{
+	uint32_t val;
+	dcfg_data_t dcfg;
+
+	val = speed;
+	dcfg.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dcfg);
+	dcfg.b.devspd = val;
+	DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dcfg, dcfg.d32);
+}
+
+/**
+ * Flush a Tx FIFO.
+ *
+ * @param core_if Programming view of DWC_otg controller.
+ * @param num Tx FIFO to flush.
+ */
+void dwc_otg_chg_flush_tx_fifo(dwc_otg_core_if_t * core_if, const int num)
+{
+    dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
+    volatile grstctl_t greset;
+    int count = 0;
+    greset.d32 = 0;
+
+    greset.b.txfflsh = 1;
+    greset.b.txfnum = num;
+
+{
+    DWC_WRITE_REG32(&global_regs->grstctl, greset.d32);
+
+    do
+    {
+        greset.d32 = DWC_READ_REG32(&global_regs->grstctl);
+        if (++count > 10000)
+        {
+            break;
+        }
+        dwc_chg_udelay(10);
+    }
+    while (greset.b.txfflsh == 1);
+
+    /* Wait for 3 PHY Clocks */
+    dwc_chg_udelay(10);
+}
+
+}
+
+/**
+ * Flush Rx FIFO.
+ *
+ * @param core_if Programming view of DWC_otg controller.
+ */
+void dwc_otg_chg_flush_rx_fifo(dwc_otg_core_if_t * core_if)
+{
+    dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
+    volatile grstctl_t greset;
+    int count = 0;
+    greset.d32 = 0;
+    greset.b.rxfflsh = 1;
+
+{
+    DWC_WRITE_REG32(&global_regs->grstctl, greset.d32);
+
+    do
+    {
+        greset.d32 = DWC_READ_REG32(&global_regs->grstctl);
+        if (++count > 10000)
+        {
+            break;
+        }
+        dwc_chg_udelay(10);   
+     }
+    while (greset.b.rxfflsh == 1);
+
+    /* Wait for 3 PHY Clocks */
+
+    dwc_chg_udelay(10);
+}
+}
+
+/**
+ * This function initializes the DWC_otg controller registers for
+ * device mode.
+ *
+ * @param core_if Programming view of DWC_otg controller
+ *
+ */
+void dwc_otg_chg_core_dev_init(dwc_otg_core_if_t * core_if)
+{
+    int i;
+//	T_TYPE_USB_DETECT chgtype;
+    dwc_otg_dev_if_t *dev_if = core_if->dev_if;
+    dcfg_data_t dcfg;
+    grstctl_t resetctl;
+    dctl_data_t dctl;
+    diepmsk_data_t msk;
+    dcfg.d32 = 0;
+    resetctl.d32 = 0;
+    dctl.d32 = 0;
+    msk.d32 = 0;
+    /* Restart the Phy Clock */
+    DWC_WRITE_REG32(core_if->pcgcctl, 0);
+
+    /* Device configuration register */
+    init_chg_devspd(core_if,0);//ĬÈÏÅäÖóɸßËÙ
+    dcfg.d32 = DWC_READ_REG32(&dev_if->dev_global_regs->dcfg);
+    dcfg.b.descdma = 0;
+    dcfg.b.perfrint = DWC_DCFG_FRAME_INTERVAL_80;
+
+    DWC_WRITE_REG32(&dev_if->dev_global_regs->dcfg, dcfg.d32);
+
+    /* Flush the FIFOs */
+    dwc_otg_chg_flush_tx_fifo(core_if, 0x10);	/* all Tx FIFOs */
+    dwc_otg_chg_flush_rx_fifo(core_if);
+
+    /* Flush the Learning Queue. */
+    resetctl.b.intknqflsh = 1;
+    DWC_WRITE_REG32(&core_if->core_global_regs->grstctl, resetctl.d32);
+    /* Clear all pending Device Interrupts */
+    /** @todo - if the condition needed to be checked
+     *  or in any case all pending interrutps should be cleared?
+     */
+    DWC_WRITE_REG32(&dev_if->dev_global_regs->diepmsk, 0);
+    DWC_WRITE_REG32(&dev_if->dev_global_regs->doepmsk, 0);
+    DWC_WRITE_REG32(&dev_if->dev_global_regs->daint, 0xFFFFFFFF);
+    DWC_WRITE_REG32(&dev_if->dev_global_regs->daintmsk, 0);
+    
+    for (i = 0; i <= dev_if->num_in_eps; i++)
+    {
+        DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->diepctl,0);
+
+        DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->dieptsiz, 0);
+        DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->diepdma, 0);
+        DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->diepint, 0xFF);
+
+        DWC_WRITE_REG32(&dev_if->out_ep_regs[i]->doepctl,0);
+
+        DWC_WRITE_REG32(&dev_if->out_ep_regs[i]->doeptsiz, 0);
+        DWC_WRITE_REG32(&dev_if->out_ep_regs[i]->doepdma, 0);
+		USBHAL_DBG("%s, %u doepdmadbg i:%d", __func__, __LINE__, i);
+        DWC_WRITE_REG32(&dev_if->out_ep_regs[i]->doepint, 0xFF);
+    }
+    msk.b.txfifoundrn = 1;
+    dwc_chg_modify_reg32(&dev_if->dev_global_regs->diepmsk,msk.d32, msk.d32);
+    dctl.d32 = DWC_READ_REG32(&dev_if->dev_global_regs->dctl);
+    dctl.b.sftdiscon = 0;
+    DWC_WRITE_REG32(&dev_if->dev_global_regs->dctl, dctl.d32);
+
+    #if 1
+    for(i = 0;i<3;i++)
+    {
+        dwc_chg_mdelay(30);
+    	if((((DWC_READ_REG32(&dev_if->dev_global_regs->dsts))>>22)&0x3) ==3)
+       {
+          	g_plug_in = TYPE_ADAPTER;
+       }
+		else
+       {
+         	g_plug_in = TYPE_COMPUTER;
+					break;
+       }
+    }
+  //  if(g_plug_in == TYPE_ADAPTER)
+	//	WARN_ON(1);
+    #else
+    dwc_chg_mdelay(100);
+    if((((DWC_READ_REG32(&dev_if->dev_global_regs->dsts))>>22)&0x3) ==3)
+    {
+         g_plug_in = TYPE_ADAPTER;
+		USBHAL_DBG("usb-dwc deteck TYPE_ADAPTER");
+		 
+//		 chgtype = TYPE_ADAPTER;
+//		 usb_detect_callback(&chgtype, 0);
+    }else
+    {
+         g_plug_in = TYPE_COMPUTER;
+		USBHAL_DBG("usb-dwc deteck TYPE_COMPUTER");
+//		 chgtype = TYPE_COMPUTER;
+//		 usb_detect_callback(&chgtype, 0);
+    }
+    #endif
+
+	if(detect_fn)
+	{
+		USBHAL_DBG("usb-dwc callback");
+		detect_fn(g_plug_in);
+	}
+
+	dctl.d32 = DWC_READ_REG32(&dev_if->dev_global_regs->dctl);
+	dctl.b.sftdiscon = 1;
+	DWC_WRITE_REG32(&dev_if->dev_global_regs->dctl, dctl.d32);
+}
+
+/**
+ * Do core a soft reset of the core.  Be careful with this because it
+ * resets all the internal state machines of the core.
+ */
+void dwc_otg_chg_core_reset(dwc_otg_core_if_t * core_if)
+{
+    dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
+    volatile grstctl_t greset;
+    int count = 0;
+    greset.d32 =0;
+    /* Wait for AHB master IDLE state. */
+    do
+    {
+        dwc_chg_udelay(10);
+        greset.d32 = DWC_READ_REG32(&global_regs->grstctl);
+        if (++count > 100000)
+        {
+            return;
+        }
+    }
+    while (greset.b.ahbidle == 0);
+
+    /* Core Soft Reset */
+    count = 0;
+    greset.b.csftrst = 1;
+    DWC_WRITE_REG32(&global_regs->grstctl, greset.d32);
+    do
+    {
+        greset.d32 = DWC_READ_REG32(&global_regs->grstctl);
+        if (++count > 10000)
+        {
+            break;
+        }
+        dwc_chg_udelay(10);
+    }
+    while (greset.b.csftrst == 1);
+/* Wait for 3 PHY Clocks */
+    dwc_chg_udelay(10);
+}
+
+/**
+ * This function initializes the DWC_otg controller registers and
+ * prepares the core for device mode or host mode operation.
+ *
+ * @param core_if Programming view of the DWC_otg controller
+ *
+ */
+void dwc_otg_chg_core_init(dwc_otg_core_if_t * core_if)
+{
+    dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
+    dwc_otg_dev_if_t *dev_if = core_if->dev_if;
+    gahbcfg_data_t ahbcfg;
+    gotgctl_data_t gotgctl;
+
+    gusbcfg_data_t usbcfg;
+    ahbcfg.d32 = 0;
+    usbcfg.d32 = 0;
+    gotgctl.d32 = 0;
+
+
+    usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
+
+{
+
+#if !USE_ASIC
+    usbcfg.b.ulpi_ext_vbus_drv =(core_if->core_params->phy_ulpi_ext_vbus == DWC_PHY_ULPI_EXTERNAL_VBUS) ? 1 : 0;
+
+    usbcfg.b.term_sel_dl_pulse = (core_if->core_params->ts_dline == 1) ? 1 : 0;
+
+
+    DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
+#endif
+    dwc_otg_chg_core_reset(core_if);
+	}
+
+
+    dev_if->num_in_eps =  2;//calc_num_in_eps(core_if);
+    dev_if->num_out_eps = 2;//calc_num_out_eps(core_if);
+
+    core_if->total_fifo_size = core_if->hwcfg3.b.dfifo_depth;
+    core_if->rx_fifo_size = DWC_READ_REG32(&global_regs->grxfsiz);
+    core_if->nperio_tx_fifo_size = DWC_READ_REG32(&global_regs->gnptxfsiz) >> 16;
+    {
+        /* High speed PHY. */
+        if (!core_if->phy_init_done)
+        {
+            core_if->phy_init_done = 1;
+            /* HS PHY parameters.  These parameters are preserved
+             * during soft reset so only program the first time.  Do
+             * a soft reset immediately after setting phyif.  */
+         #if !USE_ASIC
+            if (core_if->core_params->phy_type == 2)
+            {
+                /* ULPI interface */
+                usbcfg.b.ulpi_utmi_sel = 1;
+                usbcfg.b.phyif = 0;
+                usbcfg.b.ddrsel = core_if->core_params->phy_ulpi_ddr;
+            }
+          #else
+            if (core_if->core_params->phy_type == 1)
+            {
+                /* UTMI+ interface */
+                usbcfg.b.ulpi_utmi_sel = 0;
+                if (core_if->core_params->phy_utmi_width == 16)
+                {
+                    usbcfg.b.phyif = 1;
+
+                }
+                else
+                {
+                    usbcfg.b.phyif = 0;
+                }
+            }
+            #endif
+
+	{
+            DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
+            /* Reset after setting the PHY parameters */
+            dwc_otg_chg_core_reset(core_if);
+	}
+        }
+    }
+
+		{
+#if !USE_ASIC
+    if ((core_if->hwcfg2.b.hs_phy_type == 2) &&(core_if->hwcfg2.b.fs_phy_type == 1) &&(core_if->core_params->ulpi_fs_ls))
+    {
+        usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
+        usbcfg.b.ulpi_fsls = 1;
+        usbcfg.b.ulpi_clk_sus_m = 1;
+        DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
+    }
+    else
+    {
+        usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
+        usbcfg.b.ulpi_fsls = 0;
+        usbcfg.b.ulpi_clk_sus_m = 0;
+        DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
+    }
+#endif
+		}
+#if DMA_ENABLE
+        /* Program the GAHBCFG Register. */
+	switch (core_if->hwcfg2.b.architecture) 
+    {
+        case DWC_SLAVE_ONLY_ARCH:
+            
+    		//ahbcfg.b.nptxfemplvl_txfemplvl = DWC_GAHBCFG_TXFEMPTYLVL_HALFEMPTY;
+            //  ÅäÖÃÈ«¿ÕFIFO²úÉúÖжÏ
+            ahbcfg.b.nptxfemplvl_txfemplvl = DWC_GAHBCFG_TXFEMPTYLVL_EMPTY ;
+    		ahbcfg.b.ptxfemplvl = DWC_GAHBCFG_TXFEMPTYLVL_HALFEMPTY;
+    		core_if->dma_enable = 0;
+    		core_if->dma_desc_enable = 0;
+    		break;
+
+        case DWC_EXT_DMA_ARCH:
+    		{
+    			uint8_t brst_sz = core_if->core_params->dma_burst_size;
+    			ahbcfg.b.hburstlen = 0;
+    			while (brst_sz > 1) 
+                {
+    				ahbcfg.b.hburstlen++;
+    				brst_sz >>= 1;
+    			}
+    		}
+    		core_if->dma_enable = (core_if->core_params->dma_enable != 0);
+    		core_if->dma_desc_enable = (core_if->core_params->dma_desc_enable != 0);
+    		break;
+
+        case DWC_INT_DMA_ARCH:
+    		/* Old value was DWC_GAHBCFG_INT_DMA_BURST_INCR - done for 
+    		   Host mode ISOC in issue fix - vahrama */
+    		ahbcfg.b.hburstlen = DWC_GAHBCFG_INT_DMA_BURST_INCR4;
+    		core_if->dma_enable = (core_if->core_params->dma_enable != 0);
+    		core_if->dma_desc_enable = (core_if->core_params->dma_desc_enable != 0);
+    		break;
+
+    }
+	 if (core_if->dma_enable)
+    {
+        if (core_if->dma_desc_enable) 
+        {
+			printf("Using Descriptor DMA mode\n");
+		} 
+        else 
+       {
+			printf("using buffer dma mode\n");
+
+        }
+    }
+	 else 
+	{
+		printf("Using Slave mode\n");
+
+		core_if->dma_desc_enable = 0;
+	}
+	 ahbcfg.b.dmaenable = core_if->dma_enable;
+ #else
+    ahbcfg.b.nptxfemplvl_txfemplvl = DWC_GAHBCFG_TXFEMPTYLVL_HALFEMPTY;
+    ahbcfg.b.ptxfemplvl = DWC_GAHBCFG_TXFEMPTYLVL_HALFEMPTY;
+
+
+    ahbcfg.b.dmaenable = 0;
+//  ÅäÖÃÈ«¿ÕFIFO²úÉúÖжÏ
+    ahbcfg.b.nptxfemplvl_txfemplvl = DWC_GAHBCFG_TXFEMPTYLVL_EMPTY ;
+#endif
+
+    DWC_WRITE_REG32(&global_regs->gahbcfg, ahbcfg.d32);
+
+    core_if->en_multiple_tx_fifo = core_if->hwcfg4.b.ded_fifo_en;
+
+    core_if->pti_enh_enable = core_if->core_params->pti_enable != 0;
+    core_if->multiproc_int_enable = dwc_param_mpi_enable_default;//core_if->core_params->mpi_enable;
+    /*
+     * Program the GUSBCFG register.
+     */
+    usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
+    usbcfg.b.hnpcap = 0;
+    usbcfg.b.srpcap = 0;
+
+    	DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
+
+        gotgctl.b.otgver = core_if->core_params->otg_ver;
+
+        	dwc_chg_modify_reg32(&core_if->core_global_regs->gotgctl, 0, gotgctl.d32);
+
+        /* Set OTG version supported */
+    core_if->otg_ver = core_if->core_params->otg_ver;
+
+   dwc_otg_chg_core_dev_init(core_if);
+}
+
+struct platform_device *zx297510_platform_chg_usb_dev;
+
+#ifdef USB_CHG_DEV
+static int dwc_otg_chg_driver_probe(struct platform_device *_dev)
+{
+    zx297510_platform_chg_usb_dev = _dev;
+	return 0;
+}
+
+static void dwc_otg_chg_driver_remove( struct platform_device *_dev)
+{
+}
+
+static struct platform_driver dwc_otg_chg_driver = {
+	.driver = {
+	.name    = (char *)dwc_chg_name,
+       .bus       = &platform_bus_type,
+       .owner   = THIS_MODULE,
+       //.pm       =  DWC_OTG_PM_OPS,
+	},
+	.probe    = dwc_otg_chg_driver_probe,
+	.remove  = __exit_p(dwc_otg_chg_driver_remove),
+};
+#endif
+uint32_t dwc_otg_chg_get_gsnpsid(dwc_otg_core_if_t * core_if)
+{
+	return core_if->snpsid;
+}
+
+/**
+ * This function is called when an lm_device is bound to a
+ * dwc_otg_driver. It creates the driver components required to
+ * control the device (CIL, HCD, and PCD) and it initializes the
+ * device. The driver components are stored in a dwc_otg_device
+ * structure. A reference to the dwc_otg_device is saved in the
+ * lm_device. This allows the driver to access the dwc_otg_device
+ * structure on subsequent calls to driver methods for this device.
+ *
+ * @param _dev Bus device
+ */
+//extern int dwc_otg_open_power(void);
+//extern int dwc_otg_close_power(void);
+#ifdef USB_CHG_DEV
+int dwc_otg_usb_chg_detect(struct platform_device *_dev)
+{
+	int retval = 0;
+    struct clk* wclk;
+	struct clk* pclk;
+    struct resource *iomem;
+
+	dwc_otg_device_t *dwc_otg_device = (g_chg_usb_global->g_dwc_otg_dev_t);
+	
+	iomem = platform_get_resource(_dev, IORESOURCE_MEM,0);
+  
+    dev_dbg(&_dev->dev, "start=0x%08x\n", (unsigned)iomem->start);
+
+	memset(dwc_otg_device, 0, sizeof(dwc_otg_device_t));
+	dwc_otg_device->os_dep.reg_offset = 0xFFFFFFFF;
+
+	dwc_otg_device->os_dep.regs_res = request_mem_region(iomem->start, resource_size(iomem),
+										dev_name(_dev));
+	dwc_otg_device->os_dep.base= ioremap(iomem->start, resource_size(iomem));
+ 
+	if (!dwc_otg_device->os_dep.base) {
+		dev_err(&_dev->dev, "ioremap() failed\n");
+		return -ENOMEM;
+	}
+
+	/*
+	 * Initialize driver data to point to the global DWC_otg
+	 * Device structure.
+	 */
+	platform_set_drvdata(_dev, dwc_otg_device);
+
+	dev_dbg(&_dev->dev, "dwc_otg_device=0x%p\n", dwc_otg_device);
+
+/*
+       Please ensure power on the USB controller and Phy
+*/
+#if 0
+    zx29_usbdev_init(); //
+    retval = dwc_otg_open_power();
+#endif
+
+	pclk = clk_get(&_dev->dev, "ahb_clk");
+    if(IS_ERR(pclk)	){
+		return -EIO;
+    }
+
+	wclk = clk_get(&_dev->dev, "work_clk");
+	
+    if(IS_ERR(pclk)	){
+		return -EIO;
+    }
+
+	clk_enable(pclk);
+	clk_enable(wclk);
+
+#if 1
+    zx29_usbdev_init();
+    retval = dwc_otg_open_power();
+#endif
+
+	dwc_otg_device->core_if = dwc_otg_chg_cil_init(dwc_otg_device->os_dep.base);
+	if (!dwc_otg_device->core_if) {
+		dev_err(&_dev->dev, "CIL initialization failed!\n");
+		retval = -ENOMEM;
+		goto fail;
+	}
+	if (((dwc_otg_chg_get_gsnpsid(dwc_otg_device->core_if) & 0xFFFFF000) !=	0x4F542000) &&
+		((dwc_otg_chg_get_gsnpsid(dwc_otg_device->core_if) & 0xFFFFF000) != 0x4F543000)) {
+		dev_err(&_dev->dev, "%s, Bad value for SNPSID: 0x%08x\n",__func__,
+			dwc_otg_chg_get_gsnpsid(dwc_otg_device->core_if));
+		retval = -EINVAL;
+		goto fail;
+	}
+
+    dwc_otg_chg_core_init(dwc_otg_device->core_if);
+
+   clk_disable(wclk);
+   clk_disable(pclk);
+   clk_put(wclk);
+   clk_put(pclk);
+
+    retval = dwc_otg_close_power();
+    
+     /*
+      * Return the memory.
+      */
+     
+     if(dwc_otg_device->os_dep.regs_res){
+     	release_resource(dwc_otg_device->os_dep.regs_res);
+     	kfree(dwc_otg_device->os_dep.regs_res);
+     }
+     if (dwc_otg_device->os_dep.base) {
+     	iounmap(dwc_otg_device->os_dep.base);
+     }
+    
+     /*
+      * Clear the drvdata pointer.
+      */
+     platform_set_drvdata(_dev, 0);
+
+	 platform_driver_unregister(&dwc_otg_chg_driver);
+
+	 if (g_plug_in == TYPE_ADAPTER)
+	 {
+	     usb_notify_up(USB_CHARGER_PLUGIN, NULL);
+	 }
+	 else
+	 {
+	     usb_notify_up(USB_DEVICE_PLUGIN, NULL);
+	 }
+	 usb_printk("%s, detect done plunin:%d\n", __func__, g_plug_in);
+fail:
+	return 0;
+
+}
+EXPORT_SYMBOL_GPL(dwc_otg_usb_chg_detect);
+#else
+
+
+
+int dwc_otg_usb_chg_detect(void)
+{
+	int retval = 0;
+    struct clk* wclk;
+	struct clk* pclk;
+    struct resource iomem;
+    unsigned int value;
+	g_chg_usb_global = (struct g_data *)kmalloc(sizeof(struct g_data), GFP_KERNEL);
+	if(g_chg_usb_global == NULL){	
+		g_chg_usb_global = (struct g_data *)kmalloc(sizeof(struct g_data), GFP_KERNEL);
+		if(g_chg_usb_global == NULL){
+			printk("fetal error alloc g_chg_usb_global fail\n");
+			WARN_ON(1);
+			return -1;
+		}
+	}
+
+	memset(g_chg_usb_global, 0, sizeof(struct g_data));		
+	
+	dwc_otg_device_t *dwc_otg_device = &(g_chg_usb_global->g_dwc_otg_dev_t);
+
+	memset(dwc_otg_device, 0, sizeof(dwc_otg_device_t));
+	dwc_otg_device->os_dep.reg_offset = 0xFFFFFFFF;
+    iomem.start = ZX29_USB_PHYS;// change by gsn
+	iomem.end = ZX29_USB_PHYS+SZ_256K-1;// change by gsn
+#if 1
+    dwc_otg_device->os_dep.base= ioremap(iomem.start, resource_size(&iomem));
+#else
+    dwc_otg_device->os_dep.base = ZX29_USB1_CFG_BASE_VA;
+#endif
+    if(!dwc_otg_device->os_dep.base)
+	{
+		retval = -ENOMEM;
+		goto fail;
+	}
+/*
+       Please ensure power on the USB controller and Phy
+*/
+	dwc_otg_hal_init();
+
+    dwc_chg_udelay(10);
+
+	dwc_otg_device->core_if = dwc_otg_chg_cil_init(dwc_otg_device->os_dep.base);
+	if (!dwc_otg_device->core_if) {
+		printk(KERN_ERR "%s, CIL initialization failed!\n", __func__);
+		retval = -ENOMEM;
+		goto fail;
+	}
+	if (((dwc_otg_chg_get_gsnpsid(dwc_otg_device->core_if) & 0xFFFFF000) !=	0x4F542000) &&
+		((dwc_otg_chg_get_gsnpsid(dwc_otg_device->core_if) & 0xFFFFF000) != 0x4F543000)) {
+		printk(KERN_ERR "%s, Bad value for SNPSID: 0x%08x\n",__func__,
+			dwc_otg_chg_get_gsnpsid(dwc_otg_device->core_if));
+		retval = -EINVAL;
+		goto fail;
+	}
+
+    dwc_otg_chg_core_init(dwc_otg_device->core_if);
+
+	dwc_otg_hal_exit();
+	printk("dwc_otg_usb_chg_detect, g_plug_in:%d, type:%s\n", g_plug_in, (g_plug_in == 1 ? "pc" : "adapter"));
+    if (g_plug_in == TYPE_ADAPTER)
+    {
+        usb_notify_up(USB_CHARGER_PLUGIN, NULL);
+    }
+    else
+    {
+        usb_notify_up(USB_DEVICE_PLUGIN, NULL);
+//		wake_lock(&dwc_otg_wake_lock);
+        dwc_otg_wakelock(1,1);
+    }
+
+fail:
+    if (dwc_otg_device->os_dep.base) 
+    {
+#if 1
+        iounmap(dwc_otg_device->os_dep.base);
+#endif
+    }
+    kfree(g_chg_usb_global);
+    g_chg_usb_global = NULL;
+    
+	return 0;
+
+}
+EXPORT_SYMBOL_GPL(dwc_otg_usb_chg_detect);
+
+#endif
+int dwc_otg_usb_chg_remove(void)
+{
+    if (g_plug_in == TYPE_ADAPTER)
+    {
+    	usb_notify_up(USB_CHARGER_PLUGOUT, NULL);
+    }
+    else
+    {
+    	usb_notify_up(USB_DEVICE_PLUGOUT, NULL);
+//		wake_unlock(&dwc_otg_wake_lock);
+        //dwc_otg_wakelock(0,0);
+    }
+    g_plug_in = TYPE_UNKNOWN;
+    return 0;
+}
+EXPORT_SYMBOL_GPL(dwc_otg_usb_chg_remove);
+
+
+void dwc_otg_chg_inform(int inform)
+{
+	if(inform == 0)
+		dwc_otg_usb_chg_detect();
+	else if(inform == 1)
+		dwc_otg_usb_chg_remove();
+	else
+		USBHAL_DBG("dwc_otg_chg_inform %d", inform);
+}
+EXPORT_SYMBOL_GPL(dwc_otg_chg_inform);
+
+int dwc_otg_chg_inform_type(int inform)
+{
+	int chg_type = 0;
+	if(inform == 0){
+		dwc_otg_usb_chg_detect();
+		if (g_plug_in == TYPE_ADAPTER){
+			chg_type = 0;
+		}else{
+			chg_type = 1;
+		}
+	}
+	else if(inform == 1)
+		dwc_otg_usb_chg_remove();
+	else
+		USBHAL_DBG("dwc_otg_chg_inform %d", inform);
+	return chg_type;
+}
+EXPORT_SYMBOL_GPL(dwc_otg_chg_inform_type);
+#ifdef USB_CHG_DEV
+
+struct platform_device *get_chg_usb_platform_device(void)
+{
+    usb_printk("%s, dev:%p, name:%s\n", __func__, zx297510_platform_chg_usb_dev, zx297510_platform_chg_usb_dev->name);
+    return zx297510_platform_chg_usb_dev;
+}
+EXPORT_SYMBOL_GPL(get_chg_usb_platform_device);
+
+static int __init dwc_otg_chg_init(void)
+{
+	int retval = 0;
+	int error;
+
+	usb_printk("%s, %s: version %s\n", __func__, dwc_chg_name,
+	       DWC_DRIVER_VERSION);
+	
+	retval = platform_driver_register(&dwc_otg_chg_driver);
+
+
+	if (retval < 0) {
+		printk(KERN_ERR "%s retval=%d\n", __func__, retval);
+		return retval;
+	}
+	return retval;
+}
+
+module_init(dwc_otg_chg_init);
+#endif
+#ifdef CONFIG_DWC_DEVICE_GPIO_CHARGER
+extern unsigned int get_usb_gpio_detect_flag(void);
+//wangzhen
+extern int dwc_otg_disconnect(void);
+/*GPIOºÍÍⲿÖжϺŸù¾ÝÏîĿʵ¼ÊÇé¿öÐÞ¸Ä
+ *´Ë´¦Îª²Î¿¼´úÂë
+ */
+#define USB_GPIO ZX29_GPIO_52
+#define USB_GPIO_FUNC_GPIO GPIO52_GPIO52
+#define USB_GPIO_FUNC_EXT_INT GPIO52_EXT_INT5
+#define USB_DT_INT  PCU_EX5_INT
+
+int Usb_Detect_Val(void)
+{
+    int value;
+    
+    value = gpio_get_value(USB_GPIO);
+
+	return value;
+}
+EXPORT_SYMBOL_GPL(Usb_Detect_Val);
+
+irqreturn_t Usb_Detect_Irq_Handler(int irq, struct platform_device *_dev)
+{
+	printk(KERN_INFO"%s,end\n", __func__);
+	pcu_int_clear(USB_DT_INT);
+	//dwc_otg_wakelock(1,0);
+	return IRQ_WAKE_THREAD;
+}
+
+irqreturn_t  Usb_Detect_Irq_Thread(int irq, struct platform_device *_dev)
+{
+    int ret = -1;
+    int irq_num;
+    int retval;
+	int value;
+	unsigned int gpio_enable = 0;
+	struct sched_param param = { .sched_priority = 2 };
+	param.sched_priority= 33;
+	sched_setscheduler(current, SCHED_FIFO, &param);
+	gpio_enable = get_usb_gpio_detect_flag();
+	printk("Usb_Detect_Irq_Thread, gpio_enable:%d\n", gpio_enable);
+	if(gpio_enable == 0)	
+		return IRQ_HANDLED;
+	
+	  dwc_otg_wakelock(1,0);
+	//5.23
+	zx29_gpio_config(USB_GPIO,USB_GPIO_FUNC_GPIO);
+	gpio_direction_input(USB_GPIO);
+	msleep(5);
+	value = gpio_get_value(USB_GPIO);
+	printk("%s,value:%d\n", __func__,value);
+	zx29_gpio_config(USB_GPIO,USB_GPIO_FUNC_EXT_INT);
+	
+	if(value == 1)
+	{
+	  zx29_gpio_set_inttype(USB_GPIO,IRQ_TYPE_EDGE_FALLING);
+	  pcu_int_clear(USB_DT_INT);
+	  if(usb_plugin == 1){
+	 	 dwc_otg_disconnect();
+	  	dwc_otg_usb_chg_remove(); //not plug in;
+	  	usb_plugin = 0;
+	  }
+	}
+	else
+	{
+	  zx29_gpio_set_inttype(USB_GPIO,IRQ_TYPE_EDGE_RISING);
+	  pcu_int_clear(USB_DT_INT); 
+	  if(usb_plugin == 0){
+	  	dwc_otg_usb_chg_detect(); //plug in;
+	  	usb_plugin = 1;
+	  }
+	}
+	printk(KERN_INFO"%s,value:%d,end\n", __func__,value);
+    USBSTACK_DBG("%s,value:%d", __func__,value);
+	return IRQ_HANDLED;
+}
+
+static void usb_detect_typedet(T_TYPE_USB_DETECT chg_type)
+{
+	printk("register usb_detect_typedet for charger\n");	
+}
+
+int Usb_Detect_Irq_probe(struct platform_device *_dev)
+{
+    USBSTACK_DBG("%s", __func__);
+    int ret = -1;
+	int value;
+	int value2 = 0;
+	
+	printk("-----------Usb_Detect_Irq_probe\n");
+	dwc_chg_Regcallback(usb_detect_typedet);
+
+	ret = gpio_request(USB_GPIO, "usb");
+	zx29_gpio_config(USB_GPIO,USB_GPIO_FUNC_GPIO);
+	gpio_direction_input(USB_GPIO);
+	zx29_gpio_pd_pu_set(USB_GPIO,IO_CFG_PULL_DISABLE);
+	gpio_export(USB_GPIO, 1);
+	mdelay(5);
+	value = gpio_get_value(USB_GPIO);
+	USBSTACK_DBG("%s,value:%d", __func__,value);
+    usb_detect_irq= gpio_to_irq(USB_GPIO);
+	printk(KERN_INFO "%s,value:%d, irq_num:%d\n",__func__,value, usb_detect_irq);
+	
+    zx29_gpio_config(USB_GPIO,USB_GPIO_FUNC_EXT_INT);
+#if 1	
+	if(value == 1)
+	{
+	  usb_plugin = 0;
+	  zx29_gpio_set_inttype(USB_GPIO,IRQ_TYPE_EDGE_FALLING);
+	}
+	else
+	{
+	  dwc_otg_usb_chg_detect(); //plug in;
+	  usb_plugin = 1;
+	  zx29_gpio_set_inttype(USB_GPIO,IRQ_TYPE_EDGE_RISING);
+	}
+#endif	
+    pcu_int_clear(USB_DT_INT);
+	ret = request_threaded_irq(usb_detect_irq, Usb_Detect_Irq_Handler,Usb_Detect_Irq_Thread,IRQF_ONESHOT,
+                "usb", _dev);
+
+	printk(KERN_INFO "%s,ret:%d\n",__func__,ret);
+   	if (ret)
+    {   
+	   printk(KERN_INFO"cannot request Usb_Detect_Irq\n");
+	   return ret;
+    }
+	
+	irq_set_irq_wake(usb_detect_irq, 1);
+	
+	return 0;
+	
+}
+
+static int usb_detect_suspend(void)
+{
+	disable_irq(usb_detect_irq);
+	return 0;
+}
+
+static int usb_detect_resume(void)
+{
+	enable_irq(usb_detect_irq);
+	return 0;
+}
+
+static struct platform_driver usb_detect_platform_driver = {
+	.probe		= Usb_Detect_Irq_probe,
+	.driver		= {
+		.name	= "usb_detect",
+		.owner	= THIS_MODULE,
+	},
+	.suspend = usb_detect_suspend,
+	.resume = usb_detect_resume,
+};
+
+static int __init usb_detect_init(void)
+{
+	printk("-----------usb_detect_init\n");
+	return platform_driver_register(&usb_detect_platform_driver);
+}
+
+module_init(usb_detect_init);
+
+#endif
\ No newline at end of file
diff --git a/lynq/R306BR/ap/os/linux/linux-3.4.x/drivers/usb/gadget/usb_netlink.c b/lynq/R306BR/ap/os/linux/linux-3.4.x/drivers/usb/gadget/usb_netlink.c
new file mode 100755
index 0000000..649d5ec
--- /dev/null
+++ b/lynq/R306BR/ap/os/linux/linux-3.4.x/drivers/usb/gadget/usb_netlink.c
@@ -0,0 +1,857 @@
+

+/*

+|| sanchips add: xjy@20150312 for usbconfig-hotplug

+*/

+

+#include <linux/device.h>

+#include <linux/module.h>

+#include <linux/kernel.h>

+

+#include <linux/init.h>

+

+#include <linux/string.h>

+

+#include <linux/sysfs.h>

+

+#include <linux/stat.h>

+#include <linux/slab.h>

+#include <linux/kobject.h>

+#include <linux/android_notify.h>

+#include <mach/highspeed_debug.h>

+#include <mach/iomap.h>

+

+extern int detected_charger(void);

+static unsigned int charger_plug = 0;

+static unsigned int usb_plug = 0;

+//static unsigned int sys_id = 1;//0 is windows, other value not windows(mac or linux)

+static unsigned int en_mods = 0;//enable mods

+//static unsigned int auto_eject_ms = 0;

+unsigned int hotplug_flag = 1;

+unsigned int usb_printk_en = 1;

+EXPORT_SYMBOL_GPL(usb_printk_en);

+unsigned int mmc_printk_en = 1;

+unsigned int gmac_printk_en = 1;

+

+unsigned int force_net = 0;

+unsigned int set_panic = 0;

+//for auto test,mdl dev with gpio detect usb plug in/out

+unsigned int usb_gpio_detect_enable = 0;

+//add by gsn, to avoid usb in vincPkt_list backlogged many Skb, set a limit

+unsigned int rndis_vplist_max = 800;

+

+static unsigned int ramdump_flag = 0;

+#define RNDIS_NUM    4

+unsigned int usblan[RNDIS_NUM] = {0,0,0,0};

+

+#define CHARGER_PLUG_NAME	"chargerPlug"

+#define USB_PLUG_NAME		"usbPlug"

+#define SYS_ID_NAME			"sysId"

+#define ENABLE_MODS		"enMods"

+#define NET_NAME           "netname"

+#define NET0_STATE           "usblan0"

+#define NET1_STATE           "usblan1"

+#define NET2_STATE           "usblan2"

+#define NET3_STATE           "usblan3"

+#define HOT_PLUG           "hotplug"

+#define USB_PRINTK_EN           "usb"

+#define MMC_PRINTK_EN           "mmc"

+#define GMAC_PRINTK_EN           "gmac"

+

+#define FORCE_NET          "forcenet"

+#define SET_PANIC			"set_panic"

+#define RAMDUMP_FLAG		"ramdumpFlag"

+#define RNDIS_VPLST_MAX     "lstmax"

+#define USB_GPIO_DETECT_ENABLE "gpio_detect"

+

+#define USB_LOG_MEM_SIZE	(15*1000)

+#define USB_LOG_MAX_SIZE	512

+

+static char	s_usbMemLog[USB_LOG_MEM_SIZE]= {0};

+static char	*s_localStringBuf = NULL;

+static int		s_usbMemLogIndex=0;

+#define SET_ERARLY_SUSPEND_PANIC	     0x00000001

+#define SET_BNA_ERR_PANIC			     0x00000002

+#define SET_TX_REQ_USEUP_PANIC		     0x00000004

+#define SET_RNDIS_RESET_MSG_PANIC		 0x00000008

+

+

+static struct attribute charger_plug_attr =

+{

+        .name = "chargerPlug",

+        .mode = S_IRUGO|S_IWUSR,

+};

+

+static struct attribute usb_plug_attr =

+{

+        .name = "usbPlug",

+        .mode = S_IRUGO|S_IWUSR,

+};

+

+static struct attribute sys_id_attr =

+{

+        .name = "sysId",

+        .mode = S_IRUGO|S_IWUSR,

+};

+

+static struct attribute en_mods_attr =

+{

+        .name = "enMods",

+        .mode = S_IRUGO|S_IWUSR,

+};

+static struct attribute ramdump_flag_attr =

+{

+        .name = "ramdumpFlag",

+        .mode = S_IRUGO|S_IWUSR,

+};

+static struct attribute net_name_attr =

+{

+        .name = "netname",

+        .mode = S_IRUGO|S_IWUSR,

+};

+static struct attribute net0_state_attr =

+{

+        .name = "usblan0",

+        .mode = S_IRUGO|S_IWUSR,

+};

+static struct attribute net1_state_attr =

+{

+        .name = "usblan1",

+        .mode = S_IRUGO|S_IWUSR,

+};

+static struct attribute net2_state_attr =

+{

+        .name = "usblan2",

+        .mode = S_IRUGO|S_IWUSR,

+};

+static struct attribute net3_state_attr =

+{

+        .name = "usblan3",

+        .mode = S_IRUGO|S_IWUSR,

+};

+

+static struct attribute hotplug_state_attr =

+{

+        .name = "hotplug",

+        .mode = S_IRUGO|S_IWUSR,

+};

+

+static struct attribute force_net_attr =

+{

+        .name = "forcenet",

+        .mode = S_IRUGO|S_IWUSR,

+};

+

+static struct attribute set_panic_attr =

+{

+        .name = "set_panic",

+        .mode = S_IRUGO|S_IWUSR,

+};

+

+

+static struct attribute list_max_attr =

+{

+		.name = "lstmax",

+		.mode = S_IRUGO|S_IWUSR,

+};

+

+

+static struct attribute usb_gpio_detect_enable_attr =

+{

+		.name = "gpio_detect",

+		.mode = S_IRUGO|S_IWUSR,

+};

+

+static struct attribute *usb_status_attrs[] =

+{

+	&charger_plug_attr,

+	&usb_plug_attr,

+	&sys_id_attr,

+	&en_mods_attr,

+	&ramdump_flag_attr,

+	&net_name_attr,

+	&net0_state_attr,

+	&net1_state_attr,

+	&net2_state_attr,

+	&net3_state_attr,

+	&hotplug_state_attr,

+	&force_net_attr,

+	&set_panic_attr,

+	&list_max_attr,

+	&usb_gpio_detect_enable_attr,

+       NULL,

+};

+

+

+static struct attribute usbprintk_state_attr =

+{

+        .name = "usb",

+        .mode = S_IRUGO|S_IWUSR,

+};

+

+static struct attribute mmcprintk_state_attr =

+{

+        .name = "mmc",

+        .mode = S_IRUGO|S_IWUSR,

+};

+

+static struct attribute gmacprintk_state_attr =

+{

+        .name = "gmac",

+        .mode = S_IRUGO|S_IWUSR,

+};

+

+static struct attribute *print_status_attrs[] =

+{

+	&usbprintk_state_attr,

+	&mmcprintk_state_attr,

+	&gmacprintk_state_attr,

+       NULL,

+};

+

+

+/***********************************************

+

+				USB MODS 

+				

+************************************************/

+

+struct usb_mods{

+

+	/* µ¥¹âÅ̱êÖ¾ */

+	int only_cdrom;

+

+	/* ÊÖ¶¯µ¯¹âÅÌ ±êÖ¾*/

+	int is_eject_cdrom; 

+

+	/* ×Ô¶¯µ¯¹âÅÌ ±êÖ¾*/

+	int auto_eject_cdrom;

+	int start_timer_flag;

+	struct timer_list	timer;

+	struct work_struct work;

+

+	/* ϵͳʶ±ð±êÖ¾ */

+	int sys_id;	//0 is windows, other value not windows(mac or linux)

+};

+

+static struct usb_mods mods;

+void usb_mods_activate(void);

+

+/* MODSµ¯¹âÅÌÑÓʱһ°ã·¶Î§Îª3~5Ã룬ÔÝÉèΪ3Ãë */

+#define USB_MODS_TIMER_EXPIRES 	3000 

+

+

+int usb_do_reject_cdrom(void)

+{

+	if(mods.only_cdrom){

+		USBSTACK_DBG("usb_do_reject_cdrom!!!! ");

+		mods.is_eject_cdrom = 1;

+	}

+    return 1;

+}

+

+int usb_is_reject_cdrom(void)

+{

+	if(mods.is_eject_cdrom){

+		USBSTACK_DBG("usb_is_reject_cdrom!!!! ");

+		usb_notify_up(USB_CDROM_OBJECT, NULL);

+		return 1;

+	}

+

+	usb_mods_activate();

+	return 0;

+}

+void usb_set_sys_id(int sysId)

+{

+	if(sysId){

+		if(mods.sys_id != sysId)

+			USBSTACK_DBG("sys is mac or linux");

+	}else{

+		if(mods.sys_id != sysId)

+			USBSTACK_DBG("sys is windows");

+	}

+	mods.sys_id = sysId;

+}

+

+void usb_set_ms_auto_reject(int flag)

+{

+	if(mods.auto_eject_cdrom == flag)

+	{

+		//USBSTACK_DBG("already set, set mods-eject-cdrom flag: %d", flag);

+		return;

+	}

+

+	if(en_mods){

+		USBSTACK_DBG("mods enable, set mods-eject-cdrom flag: %d", flag);

+		mods.auto_eject_cdrom = flag;

+	}else{

+		USBSTACK_DBG("mods disable, set mods-eject-cdrom flag: 0");

+		mods.auto_eject_cdrom = 0;

+	}

+}

+//EXPORT_SYMBOL_GPL(usb_set_ms_auto_eject);

+

+

+int usb_get_ms_auto_reject(void)

+{

+	if(en_mods)

+		return mods.auto_eject_cdrom;

+	else

+		return 0;

+}

+//EXPORT_SYMBOL_GPL(usb_get_ms_auto_reject);

+

+

+void usb_mods_activate(void)

+{

+	unsigned long expire;

+	

+	if(mods.auto_eject_cdrom){

+		//mods.beginTime = jiffies;

+		if(mods.start_timer_flag == 0){

+			expire = msecs_to_jiffies(USB_MODS_TIMER_EXPIRES) + jiffies;

+			mods.start_timer_flag = 1;

+			mod_timer(&mods.timer, expire);

+			USBSTACK_DBG("mods timer start");

+		}

+	}

+}

+

+void usb_mods_deactive(void)

+{	

+	mods.start_timer_flag = 0;

+	del_timer_sync(&mods.timer);

+}

+		

+void usb_mods_timer_callback(unsigned long data)

+{

+	USBSTACK_DBG("usb mods timer");

+	schedule_work(&mods.work);

+		}	

+static void usb_mods_work(struct work_struct *data)

+{

+	USBSTACK_DBG("usb mods work");

+	if(usb_plug)

+		usb_notify_up(USB_CDROM_OBJECT, NULL);

+	}

+

+void usb_mods_init(void)

+{

+	USBSTACK_DBG("usb_mods_init");

+	mods.only_cdrom = 1;

+	mods.auto_eject_cdrom =en_mods;

+	mods.sys_id = 1;

+	mods.start_timer_flag = 0;

+	setup_timer(&mods.timer, usb_mods_timer_callback, (unsigned long)(&mods));

+	INIT_WORK(&mods.work, usb_mods_work);

+}

+

+

+void usb_mods_exit(void)

+{

+	USBSTACK_DBG("usb_mods_exit");

+	usb_mods_deactive();

+	//flush_work_sync(&mods.work);

+	mods.only_cdrom =0;

+	mods.auto_eject_cdrom =0;

+	mods.is_eject_cdrom = 0;

+}

+

+/************usb  mods end ****************************/

+unsigned int get_panic_flag(void)

+{

+	return set_panic;

+}

+

+EXPORT_SYMBOL_GPL(get_panic_flag);

+

+unsigned int get_usb_gpio_detect_flag(void)

+{

+	return usb_gpio_detect_enable;

+}

+

+EXPORT_SYMBOL_GPL(get_usb_gpio_detect_flag);

+

+

+int usb_get_rndis_list_max_flag(void)

+{

+	return rndis_vplist_max;

+}

+EXPORT_SYMBOL_GPL(usb_get_rndis_list_max_flag);

+

+

+static void usb_ramdump_config(void)

+{

+	usb_notify_up(USB_RAMDUMP_TRIGGER, NULL);	

+}

+ssize_t kobj_usb_show(struct kobject *kobject,struct attribute *attr,char *buf)

+{

+	int dc=0;

+

+	  if(!strcmp(attr->name, CHARGER_PLUG_NAME)){

+	  		sprintf(buf, "%d\n",charger_plug );

+	  }else if(!strcmp(attr->name, USB_PLUG_NAME)){

+	  		dc = detected_charger();

+	  	  	USBSTACK_DBG("detected charger=%d",dc);

+			if(dc == 1)

+	              	usb_plug = 1;

+	  		sprintf(buf, "%d\n",usb_plug );

+	  }else if(!strcmp(attr->name, SYS_ID_NAME)){

+	  		sprintf(buf, "%d\n",mods.sys_id );

+	  }else if(!strcmp(attr->name, ENABLE_MODS)){

+	  		sprintf(buf, "%d\n",en_mods );

+	  }else if(!strcmp(attr->name, RAMDUMP_FLAG)){

+	  		sprintf(buf, "%d\n",ramdump_flag);

+	  }else if(!strcmp(attr->name, NET_NAME)){

+	  		sprintf(buf,"%s%s%s%s",usblan[0]?"usblan0;":"",usblan[1]?"usblan1;":"",usblan[2]?"usblan2;":"",usblan[3]?"usblan3;":"");

+	  }else if(!strcmp(attr->name, NET0_STATE)){

+	  		sprintf(buf, "%d",usblan[0]);

+	  }else if(!strcmp(attr->name, NET1_STATE)){

+	  		sprintf(buf, "%d",usblan[1]);

+	  }else if(!strcmp(attr->name, NET2_STATE)){

+	  		sprintf(buf, "%d",usblan[2]);

+	  }else if(!strcmp(attr->name, NET3_STATE)){

+	  		sprintf(buf, "%d",usblan[3]);

+	  }else if(!strcmp(attr->name, HOT_PLUG)){

+	  		sprintf(buf, "%d",hotplug_flag);

+	  }else if(!strcmp(attr->name, USB_PRINTK_EN)){

+	  		sprintf(buf, "%d",usb_printk_en);

+	  }else if(!strcmp(attr->name, FORCE_NET)){

+	  		sprintf(buf, "%d",force_net);

+	  }else if(!strcmp(attr->name, SET_PANIC)){

+	  		sprintf(buf, "%u",set_panic);

+	  }else if(!strcmp(attr->name, RNDIS_VPLST_MAX)){

+	  		 sprintf(buf, "%u",rndis_vplist_max);

+	  } else if(!strcmp(attr->name, USB_GPIO_DETECT_ENABLE)){

+	  		 sprintf(buf, "%u",usb_gpio_detect_enable);

+	  } 	  

+

+      return strlen(buf);

+}

+

+//void usbPoll_test(void);

+ssize_t kobj_usb_store(struct kobject *kobject,struct attribute *attr, const char *buf,size_t size)

+{

+	unsigned int value = 0;

+	

+	value = simple_strtoul(buf, NULL, 10);

+	if(!strcmp(attr->name,CHARGER_PLUG_NAME)){

+		charger_plug = value;

+	}else if(!strcmp(attr->name,USB_PLUG_NAME)){

+		//usbPoll_test();

+		usb_plug = value;

+	}else if(!strcmp(attr->name,SYS_ID_NAME)){

+		usb_set_sys_id(value);

+	}else if(!strcmp(attr->name,ENABLE_MODS)){

+		en_mods =value;

+	}else if(!strcmp(attr->name,RAMDUMP_FLAG)){

+		ramdump_flag =value;

+		if(ramdump_flag)

+			usb_ramdump_config();

+	}else if(!strcmp(attr->name,NET0_STATE)){

+		usblan[0] =value;

+	}

+	else if(!strcmp(attr->name,NET1_STATE)){

+		usblan[1] =value;

+	}else if(!strcmp(attr->name,NET2_STATE)){

+		usblan[2] =value;

+	}else if(!strcmp(attr->name,NET3_STATE)){

+		usblan[3] =value;

+	}else if(!strcmp(attr->name,HOT_PLUG)){

+		hotplug_flag =value;

+	}else if(!strcmp(attr->name,USB_PRINTK_EN)){

+		usb_printk_en =value;

+	}else if(!strcmp(attr->name,FORCE_NET)){

+		force_net =value;	

+	}else if(!strcmp(attr->name,SET_PANIC)){

+		set_panic =value;

+	}else if(!strcmp(attr->name,RNDIS_VPLST_MAX)){

+		rndis_vplist_max =value;

+	}else if(!strcmp(attr->name,USB_GPIO_DETECT_ENABLE)){

+		usb_gpio_detect_enable =value;

+	}

+	

+	return size;

+}

+

+static struct sysfs_ops obj_usb_sysops =

+{

+        .show = kobj_usb_show,

+        .store = kobj_usb_store,        

+};

+

+void obj_usb_release(struct kobject *kobject)

+{

+	usb_printk("[kobj_test: release!]\n");

+}

+static struct kobj_type ktype =

+

+{       .release = obj_usb_release,

+        .sysfs_ops = &obj_usb_sysops,

+        .default_attrs = usb_status_attrs,

+};

+

+ssize_t kobj_print_show(struct kobject *kobject,struct attribute *attr,char *buf)

+{

+	  if(!strcmp(attr->name, USB_PRINTK_EN)){

+	  		sprintf(buf, "%d",usb_printk_en);

+	  }else if(!strcmp(attr->name, MMC_PRINTK_EN)){

+	  		sprintf(buf, "%d",mmc_printk_en);

+	  }else if(!strcmp(attr->name, GMAC_PRINTK_EN)){

+	  		sprintf(buf, "%d",gmac_printk_en);

+	  }

+

+      return strlen(buf);

+}

+

+//void usbPoll_test(void);

+ssize_t kobj_print_store(struct kobject *kobject,struct attribute *attr, const char *buf,size_t size)

+{

+	unsigned int value = 0;

+	

+	value = simple_strtoul(buf, NULL, 4);

+	if(!strcmp(attr->name,USB_PRINTK_EN)){

+		usb_printk_en =value;

+	}else if(!strcmp(attr->name,MMC_PRINTK_EN)){

+		mmc_printk_en =value;

+	}else if(!strcmp(attr->name,GMAC_PRINTK_EN)){

+		gmac_printk_en =value;

+	}

+	

+	return size;

+}

+

+static struct sysfs_ops obj_print_sysops =

+{

+        .show = kobj_print_show,

+        .store = kobj_print_store,        

+};

+static struct kobj_type kprinttype =

+

+{       .release = obj_usb_release,

+        .sysfs_ops = &obj_print_sysops,

+        .default_attrs = print_status_attrs,

+};

+

+static int kset_filter(struct kset *kset,struct kobject *kobj)

+{

+//    int ret=0;

+//    struct kobj_type *ktype = get_ktype(kobj); /* µÃµ½ÊôÐÔÀàÐÍ */

+//    ret = (ktype == &ktype_part);

+   usb_printk("Filter: kobj %s.\n",kobj->name);

+     return 1;

+}

+

+static const char *kset_name(struct kset *kset,struct kobject *kobj)

+{    

+    static char buf[20];

+

+/*    struct device *dev = to_dev(kobj);

+   if(dev->bus)

+        return dev->bus->name;

+    else if(dev->class)

+        return dev->class->name;

+    else

+*/    {

+       usb_printk("Name kobj %s.\n",kobj->name);

+       sprintf(buf,"%s","dwc_usb");

+   }

+       return buf;

+}

+

+static int kset_uevent(struct kset *kset,struct kobject *kobj, struct kobj_uevent_env *env)

+{

+   int i = 0;

+    usb_printk("uevent: kobj %s.\n",kobj->name);

+

+   while(i < env->envp_idx)

+    {

+        usb_printk("%s.\n",env->envp[i]);

+       i ++;

+    }

+

+    return 0;

+}

+

+static struct kset_uevent_ops uevent_ops =

+{

+    .filter = kset_filter,

+    .name = kset_name,

+    .uevent = kset_uevent,

+};

+

+struct kset *kset_p;

+struct kset *kset_usb;

+//struct kset kset_c;

+struct kobject *usbkobj = NULL;

+struct kobject *printkobj = NULL;

+static int __init kset_usb_init(void)

+{

+  int ret = 0;

+

+   usb_printk("kset test init!\n");

+   

+   /* ´´½¨²¢×¢²á kset_p */

+   kset_usb = kset_create_and_add("dwc_usb", &uevent_ops, NULL);    

+    

+  // kobject_set_name(&kset_c.kobj,"kset_c");

+ //  kset_c.kobj.kset = kset_p;    /* Ìí¼Ó kset_c µ½ kset_p */

+

+    /* ¶ÔÓÚ½Ïа汾µÄÄںˣ¬ÔÚ×¢²á kset ֮ǰ£¬ÐèÒª 

+        * Ìî³ä kset.kobj µÄ ktype ³ÉÔ±£¬·ñÔò×¢²á²»»á³É¹¦ */

+  // kset_c.kobj.ktype = &ktype;

+   //ret = kset_register(&kset_c);

+

+  // if(ret)

+   //     kset_unregister(kset_p);

+   usbkobj = kzalloc(sizeof(*usbkobj),GFP_KERNEL);

+   if(!usbkobj){

+   		usb_printk(KERN_WARNING "mallock usbkobj failed \n");

+		return 0;

+   }

+   kobject_init(usbkobj, &ktype);

+   kobject_add(usbkobj,&kset_usb->kobj,"%s","usbconfig");

+   usbkobj->kset = kset_usb;

+

+    kset_p = kset_create_and_add("highspeed_print_en", &uevent_ops, NULL);    

+	

+     printkobj = kzalloc(sizeof(*printkobj),GFP_KERNEL);

+   if(!printkobj){

+   		usb_printk(KERN_WARNING "mallock printkobj failed \n");

+		return 0;

+   }

+   kobject_init(printkobj, &kprinttype);

+   kobject_add(printkobj,&kset_p->kobj,"%s","printconfig");

+   printkobj->kset = kset_p;

+

+  // usbkobj = kobject_create_and_add("usbconfig", &kset_p->kobj);

+  // usbkobj->kset = kset_p;

+   //usbkobj->ktype = &ktype;

+    

+   return ret;

+}

+

+

+static void __exit kset_usb_exit(void)

+{

+   usb_printk("kset test exit!\n");

+   

+  // kset_unregister(&kset_c);

+   kset_unregister(kset_usb);

+   kset_unregister(kset_p);

+}

+

+

+void usb_notify_up(usb_notify_event notify_type, void* puf)

+{

+	unsigned char buf[100];

+	int rtv = -1;

+	enum kobject_action action =KOBJ_MAX;

+	char*envp_ext[] = {NULL,NULL};

+	strcpy(buf, "cdrom-object");

+	switch(notify_type){

+		case USB_CDROM_OBJECT:

+			usb_printk("usb cdrom object \n");

+			USBSTACK_DBG("@CDROM REJECT");

+			strcpy(buf,"USBEVENT=usb_switch");

+			action = KOBJ_CHANGE;

+			break;

+

+		case USB_DEVICE_PLUGIN:

+			usb_printk("usb device plugin \n");

+			USBSTACK_DBG("@USB DEV PLUG IN");

+			strcpy(buf,"USBEVENT=usb_device_in");

+			action = KOBJ_ADD;

+			usb_plug = 1;

+			break;

+

+		case USB_DEVICE_PLUGOUT:

+			usb_printk("usb device plugout \n");

+			USBSTACK_DBG("@USB DEV PLUG OUT");

+			strcpy(buf,"USBEVENT=usb_device_out");

+			action = KOBJ_REMOVE;

+			usb_plug = 0;

+			break;

+		case USB_CHARGER_PLUGIN:

+			usb_printk("usb charger plugin \n");

+			USBSTACK_DBG("@USB CHARGER PLUG IN");

+			strcpy(buf,"USBEVENT=usb_charger_in");

+			action = KOBJ_ADD;

+			charger_plug = 1;

+			break;

+

+		case USB_CHARGER_PLUGOUT:

+			usb_printk("usb charge plugout \n");

+			USBSTACK_DBG("@USB CHARGER PLUG OUT");

+			strcpy(buf,"USBEVENT=usb_charger_out");

+			action = KOBJ_REMOVE;

+			charger_plug = 0;

+			break;

+		case USB_RAMDUMP_TRIGGER:

+			usb_printk("usb ramdump trigger \n");

+			USBSTACK_DBG("@USB RAMDUMP TRIGGERT");

+			 strcpy(buf,"USBEVENT=usb_ramdump");

+			 action = KOBJ_CHANGE;

+             break;

+		case USB_SWITCH_USER:

+			usb_printk("usb switch to user mode \n");

+			USBSTACK_DBG("@USB SWITCH USER");

+			strcpy(buf,"USBEVENT=usb_user");

+			action = KOBJ_CHANGE;

+			break;

+

+		case USB_SWITCH_DEBUG:

+			usb_printk("usb switch to debug mode \n");

+			USBSTACK_DBG("@USB SWITCH DEBUG");

+			strcpy(buf,"USBEVENT=usb_debug");

+			action = KOBJ_CHANGE;

+			break;

+

+		case USB_SWITCH_FACTORY:

+			usb_printk("usb switch to factory mode \n");

+			USBSTACK_DBG("@USB SWITCH FACTORY");

+			strcpy(buf,"USBEVENT=usb_factory");

+			action = KOBJ_CHANGE;

+			break;

+

+		case USB_SWITCH_AMT:

+			usb_printk("usb switch to amt mode \n");

+			USBSTACK_DBG("@USB SWITCH AMT");

+			strcpy(buf,"USBEVENT=usb_amt");

+			action = KOBJ_CHANGE;

+			break;

+

+		case USB_SWITCH_EYE_DIAGRAM:

+			usb_printk("usb switch to EYE_DIAGRAM mode \n");

+			USBSTACK_DBG("@USB SWITCH EYE_DIAGRAM");

+			strcpy(buf,"USBEVENT=usb_eye_diagram");

+			action = KOBJ_CHANGE;

+			break;

+

+		case USB_DEVICE_EXCEPT_RESET:

+			usb_printk("usb catch except reset \n");

+			USBSTACK_DBG("@USB EXCEPT RESET");

+			strcpy(buf,"USBEVENT=usb_except_reset");

+			action = KOBJ_CHANGE;

+			break;

+			 

+		default:

+			usb_printk(KERN_WARNING "UNKWON USB EVENT \n");

+			break;

+	}

+    envp_ext[0] = buf;

+	if(usbkobj && hotplug_flag){

+		rtv = kobject_uevent_env(usbkobj, action,envp_ext);

+	}

+	usb_printk(KERN_WARNING "rtv:%d \n",rtv);

+}

+EXPORT_SYMBOL_GPL(usb_notify_up);

+

+

+

+void usb_dbg_printf(const char *fmt,...)

+{

+    va_list args;

+    int stringCnt = 0;

+

+    if ((USB_LOG_MAX_SIZE +s_usbMemLogIndex)>=USB_LOG_MEM_SIZE)

+    {

+        s_usbMemLogIndex=0;

+    }

+	

+    s_localStringBuf = &s_usbMemLog[s_usbMemLogIndex];

+

+

+    va_start(args, fmt);

+    stringCnt+=vsprintf((char *)s_localStringBuf, fmt, args);

+    va_end(args);

+	

+    s_usbMemLogIndex+=stringCnt;

+}

+EXPORT_SYMBOL_GPL(usb_dbg_printf);

+

+void usb_dbg_showLog(void)

+{

+	int SingleStrLen=0;

+	char logBuf[USB_LOG_MAX_SIZE+1]={0};

+	char *pStart=s_usbMemLog;

+	char *pEnd=NULL;

+

+	logBuf[USB_LOG_MAX_SIZE] = '\n';

+

+	pEnd = (char *)strchr((const char *)pStart, '\n');

+	while((pEnd < (&s_usbMemLog[USB_LOG_MEM_SIZE]))&&(pEnd >=pStart))

+	{

+		SingleStrLen= pEnd-pStart;	

+		memcpy(logBuf,pStart,SingleStrLen);

+		printk("%s\n", logBuf);	

+		

+		do{

+			pStart=pEnd?(pEnd+1):(pStart+1);

+			memset(logBuf,0,USB_LOG_MAX_SIZE);

+			pEnd = (char *)strchr((const char *)pStart, '\n');

+		}while(!pEnd);

+	}

+

+}

+EXPORT_SYMBOL_GPL(usb_dbg_showLog);

+

+void usb_dbg_ep0reg(void)

+{

+#if 0

+    USBREG_DBG("\n GINTSTS:  0x%08x, GINTMASK: 0x%08x, DCFG:     0x%08x, DCTL:     0x%08x,\n DSTS:     0x%08x, DIEPMSK:  0x%08x, DOEPMSK:  0x%08x, DAINT:     0x%08x,\n DAINTMSK: 0x%08x, DIEPCTL0: 0x%08x, DIEPINT0: 0x%08x, DIEPTSIZE0:0x%08x,\n DIEPDMA0: 0x%08x, DIEPDMB0: 0x%08x, DOEPCTL0: 0x%08x, DOEPINT0: 0x%08x,\n DOEPSIZ0: 0x%08x, DOEPDMA0: 0x%08x, unused:   0x%08x, DOEPDMAB0:0x%08x,", 

+    	*(volatile unsigned int *)(ZX_USB_BASE+0x14), //GINTSTS

+    	*(volatile unsigned int *)(ZX_USB_BASE+0x18), //GINTMAK

+    	*(volatile unsigned int *)(ZX_USB_BASE+0x800), //DCFG

+    	*(volatile unsigned int *)(ZX_USB_BASE+0x804), //DCTL  line1 end

+    	*(volatile unsigned int *)(ZX_USB_BASE+0x808), //DSTS

+    	*(volatile unsigned int *)(ZX_USB_BASE+0x810), //DIEPMSK 

+    	*(volatile unsigned int *)(ZX_USB_BASE+0x814), //DOEPMSK

+    	*(volatile unsigned int *)(ZX_USB_BASE+0x818), //DAINT   line2 end

+    	*(volatile unsigned int *)(ZX_USB_BASE+0x81c), //DAINTMSK

+    	*(volatile unsigned int *)(ZX_USB_BASE+0x900), //DIEPCTL0

+    	*(volatile unsigned int *)(ZX_USB_BASE+0x908), //DIEPINT0

+    	*(volatile unsigned int *)(ZX_USB_BASE+0x910), //DIEPTSIZE0  line3 end

+    	*(volatile unsigned int *)(ZX_USB_BASE+0x914), //DIEPDMA0

+        *(volatile unsigned int *)(ZX_USB_BASE+0x91C), //DIEPDMB0

+    	*(volatile unsigned int *)(ZX_USB_BASE+0xB00), //DOEPCTL0

+    	*(volatile unsigned int *)(ZX_USB_BASE+0xB08), //DOEPINT0   line4 end

+    	*(volatile unsigned int *)(ZX_USB_BASE+0xB10), //DOEPSIZ0

+    	*(volatile unsigned int *)(ZX_USB_BASE+0xB14), //DOEPDMA0

+    	*(volatile unsigned int *)(ZX_USB_BASE+0xB18), //unused

+    	*(volatile unsigned int *)(ZX_USB_BASE+0xB1C) //DOEPDMAB0  line5 end

+    	);

+#endif

+}

+EXPORT_SYMBOL_GPL(usb_dbg_ep0reg);

+

+void usb_print_ep0reg(void)

+{

+    USBHAL_DBG("\n GINTSTS:  0x%08x, GINTMASK: 0x%08x, DCFG:     0x%08x, DCTL:     0x%08x,\n DSTS:     0x%08x, DIEPMSK:  0x%08x, DOEPMSK:  0x%08x, DAINT:     0x%08x,\n DAINTMSK: 0x%08x, DIEPCTL0: 0x%08x, DIEPINT0: 0x%08x, DIEPTSIZE0:0x%08x,\n DIEPDMA0: 0x%08x, DIEPDMB0: 0x%08x, DOEPCTL0: 0x%08x, DOEPINT0: 0x%08x,\n DOEPSIZ0: 0x%08x, DOEPDMA0: 0x%08x, unused:   0x%08x, DOEPDMAB0:0x%08x,", 

+    	*(volatile unsigned int *)(ZX_USB_BASE+0x14), //GINTSTS

+    	*(volatile unsigned int *)(ZX_USB_BASE+0x18), //GINTMAK

+    	*(volatile unsigned int *)(ZX_USB_BASE+0x800), //DCFG

+    	*(volatile unsigned int *)(ZX_USB_BASE+0x804), //DCTL  line1 end

+    	*(volatile unsigned int *)(ZX_USB_BASE+0x808), //DSTS

+    	*(volatile unsigned int *)(ZX_USB_BASE+0x810), //DIEPMSK 

+    	*(volatile unsigned int *)(ZX_USB_BASE+0x814), //DOEPMSK

+    	*(volatile unsigned int *)(ZX_USB_BASE+0x818), //DAINT   line2 end

+    	*(volatile unsigned int *)(ZX_USB_BASE+0x81c), //DAINTMSK

+    	*(volatile unsigned int *)(ZX_USB_BASE+0x900), //DIEPCTL0

+    	*(volatile unsigned int *)(ZX_USB_BASE+0x908), //DIEPINT0

+    	*(volatile unsigned int *)(ZX_USB_BASE+0x910), //DIEPTSIZE0  line3 end

+    	*(volatile unsigned int *)(ZX_USB_BASE+0x914), //DIEPDMA0

+        *(volatile unsigned int *)(ZX_USB_BASE+0x91C), //DIEPDMB0

+    	*(volatile unsigned int *)(ZX_USB_BASE+0xB00), //DOEPCTL0

+    	*(volatile unsigned int *)(ZX_USB_BASE+0xB08), //DOEPINT0   line4 end

+    	*(volatile unsigned int *)(ZX_USB_BASE+0xB10), //DOEPSIZ0

+    	*(volatile unsigned int *)(ZX_USB_BASE+0xB14), //DOEPDMA0

+    	*(volatile unsigned int *)(ZX_USB_BASE+0xB18), //unused

+    	*(volatile unsigned int *)(ZX_USB_BASE+0xB1C) //DOEPDMAB0  line5 end

+    	);

+}

+EXPORT_SYMBOL_GPL(usb_print_ep0reg);

+module_init(kset_usb_init);

+

+module_exit(kset_usb_exit);

+

+