From 7249b927286bdb3007eab438c9b49cbee76283cd Mon Sep 17 00:00:00 2001 From: yangkai Date: Thu, 30 Aug 2012 11:45:58 +0800 Subject: [PATCH] usb driver restructure --- arch/arm/mach-rk30/devices.c | 53 -- drivers/usb/dwc_otg/Makefile | 2 +- drivers/usb/dwc_otg/dwc_otg_attr.c | 52 +- drivers/usb/dwc_otg/dwc_otg_cil_intr.c | 5 - drivers/usb/dwc_otg/dwc_otg_driver.c | 766 +++---------------------- drivers/usb/dwc_otg/dwc_otg_driver.h | 7 +- drivers/usb/dwc_otg/dwc_otg_hcd.c | 81 ++- drivers/usb/dwc_otg/dwc_otg_pcd.c | 354 +----------- drivers/usb/dwc_otg/usbdev_rk.h | 22 + drivers/usb/dwc_otg/usbdev_rk30.c | 279 +++++++++ 10 files changed, 464 insertions(+), 1157 deletions(-) create mode 100755 drivers/usb/dwc_otg/usbdev_rk.h create mode 100755 drivers/usb/dwc_otg/usbdev_rk30.c diff --git a/arch/arm/mach-rk30/devices.c b/arch/arm/mach-rk30/devices.c index 41a02d479b61..5246391f26a6 100755 --- a/arch/arm/mach-rk30/devices.c +++ b/arch/arm/mach-rk30/devices.c @@ -16,9 +16,6 @@ #include #include #include -#ifdef CONFIG_USB_ANDROID -#include -#endif #include #include #include @@ -1182,51 +1179,7 @@ static void __init rk30_init_i2s(void) platform_device_register(&device_pcm); } -#ifdef CONFIG_USB20_OTG -/*DWC_OTG*/ -static struct resource usb20_otg_resource[] = { - { - .start = IRQ_USB_OTG, - .end = IRQ_USB_OTG, - .flags = IORESOURCE_IRQ, - }, - { - .start = RK30_USBOTG20_PHYS, - .end = RK30_USBOTG20_PHYS + RK30_USBOTG20_SIZE - 1, - .flags = IORESOURCE_MEM, - }, - -}; - -struct platform_device device_usb20_otg = { - .name = "usb20_otg", - .id = -1, - .num_resources = ARRAY_SIZE(usb20_otg_resource), - .resource = usb20_otg_resource, -}; -#endif -#ifdef CONFIG_USB20_HOST -static struct resource usb20_host_resource[] = { - { - .start = IRQ_USB_HOST, - .end = IRQ_USB_HOST, - .flags = IORESOURCE_IRQ, - }, - { - .start = RK30_USBHOST20_PHYS, - .end = RK30_USBHOST20_PHYS + RK30_USBHOST20_SIZE - 1, - .flags = IORESOURCE_MEM, - }, - -}; -struct platform_device device_usb20_host = { - .name = "usb20_host", - .id = -1, - .num_resources = ARRAY_SIZE(usb20_host_resource), - .resource = usb20_host_resource, -}; -#endif #ifdef CONFIG_KEYS_RK29 extern struct rk29_keys_platform_data rk29_keys_pdata; @@ -1361,12 +1314,6 @@ static int __init rk30_init_devices(void) #ifdef CONFIG_KEYS_RK29 platform_device_register(&device_keys); #endif -#ifdef CONFIG_USB20_OTG - platform_device_register(&device_usb20_otg); -#endif -#ifdef CONFIG_USB20_HOST - platform_device_register(&device_usb20_host); -#endif #ifdef CONFIG_RGA_RK30 platform_device_register(&device_rga); #endif diff --git a/drivers/usb/dwc_otg/Makefile b/drivers/usb/dwc_otg/Makefile index 6da2668e6b2a..3fa026561bfb 100755 --- a/drivers/usb/dwc_otg/Makefile +++ b/drivers/usb/dwc_otg/Makefile @@ -25,7 +25,7 @@ EXTRA_CFLAGS += -DDWC_BOTH_HOST_SLAVE endif #EXTRA_CFLAGS += -Dlinux -DDWC_HS_ELECT_TST -dwc_otg-objs := dwc_otg_driver.o dwc_otg_attr.o +dwc_otg-objs := dwc_otg_driver.o dwc_otg_attr.o usbdev_rk30.o dwc_otg-objs += dwc_otg_cil.o dwc_otg_cil_intr.o dwc_otg-objs += dwc_otg_pcd.o dwc_otg_pcd_intr.o dwc_otg-objs += dwc_otg_hcd.o dwc_otg_hcd_intr.o dwc_otg_hcd_queue.o diff --git a/drivers/usb/dwc_otg/dwc_otg_attr.c b/drivers/usb/dwc_otg/dwc_otg_attr.c index 01d5a74f57e1..9b7a5d3355aa 100755 --- a/drivers/usb/dwc_otg/dwc_otg_attr.c +++ b/drivers/usb/dwc_otg/dwc_otg_attr.c @@ -270,7 +270,7 @@ #define DWC_OTG_DEVICE_ATTR_BITFIELD_SHOW(_otg_attr_name_,_addr_,_mask_,_shift_,_string_) \ static ssize_t _otg_attr_name_##_show (struct device *_dev, struct device_attribute *attr, char *buf) \ { \ - dwc_otg_device_t *otg_dev = _dev->platform_data;\ + dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)_dev->platform_data));\ uint32_t val; \ val = dwc_read_reg32 (_addr_); \ val = (val & (_mask_)) >> _shift_; \ @@ -279,7 +279,7 @@ static ssize_t _otg_attr_name_##_show (struct device *_dev, struct device_attrib #define DWC_OTG_DEVICE_ATTR_BITFIELD_STORE(_otg_attr_name_,_addr_,_mask_,_shift_,_string_) \ static ssize_t _otg_attr_name_##_store (struct device *_dev, struct device_attribute *attr, const char *buf, size_t count) \ { \ - dwc_otg_device_t *otg_dev = _dev->platform_data;\ + dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)_dev->platform_data));\ uint32_t set = simple_strtoul(buf, NULL, 16); \ uint32_t clear = set; \ clear = ((~clear) << _shift_) & _mask_; \ @@ -304,7 +304,7 @@ DEVICE_ATTR(_otg_attr_name_,0444,_otg_attr_name_##_show,NULL); #define DWC_OTG_DEVICE_ATTR_REG_SHOW(_otg_attr_name_,_addr_,_string_) \ static ssize_t _otg_attr_name_##_show (struct device *_dev, struct device_attribute *attr, char *buf) \ { \ - dwc_otg_device_t *otg_dev = _dev->platform_data;\ + dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)_dev->platform_data));\ uint32_t val; \ val = dwc_read_reg32 (_addr_); \ return sprintf (buf, "%s = 0x%08x\n", _string_, val); \ @@ -312,7 +312,7 @@ static ssize_t _otg_attr_name_##_show (struct device *_dev, struct device_attrib #define DWC_OTG_DEVICE_ATTR_REG_STORE(_otg_attr_name_,_addr_,_string_) \ static ssize_t _otg_attr_name_##_store (struct device *_dev, struct device_attribute *attr, const char *buf, size_t count) \ { \ - dwc_otg_device_t *otg_dev = _dev->platform_data;\ + dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)_dev->platform_data));\ uint32_t val = simple_strtoul(buf, NULL, 16); \ dev_dbg(_dev, "Storing Address=0x%08x Val=0x%08x\n", (uint32_t)_addr_, val); \ dwc_write_reg32(_addr_, val); \ @@ -338,7 +338,7 @@ DEVICE_ATTR(_otg_attr_name_,0444,_otg_attr_name_##_show,NULL); static ssize_t regoffset_show( struct device *_dev, struct device_attribute *attr, char *buf) { - dwc_otg_device_t *otg_dev = _dev->platform_data; + dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)_dev->platform_data)); return snprintf(buf, sizeof("0xFFFFFFFF\n")+1,"0x%08x\n", otg_dev->reg_offset); } @@ -349,7 +349,7 @@ static ssize_t regoffset_show( struct device *_dev, static ssize_t regoffset_store( struct device *_dev, struct device_attribute *attr, const char *buf, size_t count ) { - dwc_otg_device_t *otg_dev = _dev->platform_data; + dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)_dev->platform_data)); uint32_t offset = simple_strtoul(buf, NULL, 16); //dev_dbg(_dev, "Offset=0x%08x\n", offset); if (offset < SZ_256K ) { @@ -371,7 +371,7 @@ DEVICE_ATTR(regoffset, S_IRUGO|S_IWUSR, regoffset_show, regoffset_store); static ssize_t regvalue_show( struct device *_dev, struct device_attribute *attr, char *buf) { - dwc_otg_device_t *otg_dev = _dev->platform_data; + dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)_dev->platform_data)); uint32_t val; volatile uint32_t *addr; @@ -402,7 +402,7 @@ static ssize_t regvalue_store( struct device *_dev, struct device_attribute *attr, const char *buf, size_t count ) { - dwc_otg_device_t *otg_dev = _dev->platform_data; + dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)_dev->platform_data)); volatile uint32_t * addr; uint32_t val = simple_strtoul(buf, NULL, 16); //dev_dbg(_dev, "Offset=0x%08x Val=0x%08x\n", otg_dev->reg_offset, val); @@ -456,7 +456,7 @@ DWC_OTG_DEVICE_ATTR_REG32_RW(hprt0,otg_dev->core_if->host_if->hprt0,"HPRT0"); static ssize_t hnp_show( struct device *_dev, struct device_attribute *attr, char *buf) { - dwc_otg_device_t *otg_dev = _dev->platform_data; + dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)_dev->platform_data)); gotgctl_data_t val; val.d32 = dwc_read_reg32 (&(otg_dev->core_if->core_global_regs->gotgctl)); return sprintf (buf, "HstNegScs = 0x%x\n", val.b.hstnegscs); @@ -469,7 +469,7 @@ static ssize_t hnp_store( struct device *_dev, struct device_attribute *attr, const char *buf, size_t count ) { - dwc_otg_device_t *otg_dev = _dev->platform_data; + dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)_dev->platform_data)); uint32_t in = simple_strtoul(buf, NULL, 16); uint32_t *addr = (uint32_t *)&(otg_dev->core_if->core_global_regs->gotgctl); gotgctl_data_t mem; @@ -491,7 +491,7 @@ static ssize_t srp_show( struct device *_dev, struct device_attribute *attr, char *buf) { #ifndef DWC_HOST_ONLY - dwc_otg_device_t *otg_dev = _dev->platform_data; + dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)_dev->platform_data)); gotgctl_data_t val; val.d32 = dwc_read_reg32 (&(otg_dev->core_if->core_global_regs->gotgctl)); return sprintf (buf, "SesReqScs = 0x%x\n", val.b.sesreqscs); @@ -510,7 +510,7 @@ static ssize_t srp_store( struct device *_dev, const char *buf, size_t count ) { #ifndef DWC_HOST_ONLY - dwc_otg_device_t *otg_dev = _dev->platform_data; + dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)_dev->platform_data)); dwc_otg_pcd_initiate_srp(otg_dev->pcd); #endif return count; @@ -526,7 +526,7 @@ DEVICE_ATTR(srp, 0644, srp_show, srp_store); static ssize_t buspower_show( struct device *_dev, struct device_attribute *attr, char *buf) { - dwc_otg_device_t *otg_dev = _dev->platform_data; + dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)_dev->platform_data)); hprt0_data_t val; val.d32 = dwc_read_reg32 (otg_dev->core_if->host_if->hprt0); return sprintf (buf, "Bus Power = 0x%x\n", val.b.prtpwr); @@ -540,7 +540,7 @@ static ssize_t buspower_store( struct device *_dev, struct device_attribute *attr, const char *buf, size_t count ) { - dwc_otg_device_t *otg_dev = _dev->platform_data; + dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)_dev->platform_data)); uint32_t on = simple_strtoul(buf, NULL, 16); uint32_t *addr = (uint32_t *)otg_dev->core_if->host_if->hprt0; hprt0_data_t mem; @@ -564,7 +564,7 @@ DEVICE_ATTR(buspower, 0644, buspower_show, buspower_store); static ssize_t bussuspend_show( struct device *_dev, struct device_attribute *attr, char *buf) { - dwc_otg_device_t *otg_dev = _dev->platform_data; + dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)_dev->platform_data)); hprt0_data_t val; val.d32 = dwc_read_reg32 (otg_dev->core_if->host_if->hprt0); return sprintf (buf, "Bus Suspend = 0x%x\n", val.b.prtsusp); @@ -577,7 +577,7 @@ static ssize_t bussuspend_store( struct device *_dev, struct device_attribute *attr, const char *buf, size_t count ) { - dwc_otg_device_t *otg_dev = _dev->platform_data; + dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)_dev->platform_data)); uint32_t in = simple_strtoul(buf, NULL, 16); uint32_t *addr = (uint32_t *)otg_dev->core_if->host_if->hprt0; hprt0_data_t mem; @@ -596,7 +596,7 @@ static ssize_t remote_wakeup_show( struct device *_dev, struct device_attribute *attr,char *buf) { #ifndef DWC_HOST_ONLY - dwc_otg_device_t *otg_dev = _dev->platform_data; + dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)_dev->platform_data)); dctl_data_t val; val.d32 = dwc_read_reg32( &otg_dev->core_if->dev_if->dev_global_regs->dctl); @@ -617,8 +617,8 @@ static ssize_t remote_wakeup_store( struct device *_dev, const char *buf, size_t count ) { #ifndef DWC_HOST_ONLY - uint32_t val = simple_strtoul(buf, NULL, 16); - dwc_otg_device_t *otg_dev = _dev->platform_data; + uint32_t val = simple_strtoul(buf, NULL, 16); + dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)_dev->platform_data)); if (val&1) { dwc_otg_pcd_remote_wakeup(otg_dev->pcd, 1); } @@ -638,7 +638,7 @@ static DEVICE_ATTR(remote_wakeup, S_IRUGO|S_IWUSR, remote_wakeup_show, static ssize_t regdump_show( struct device *_dev, struct device_attribute *attr, char *buf) { - dwc_otg_device_t *otg_dev = _dev->platform_data; + dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)_dev->platform_data)); dwc_otg_dump_global_registers( otg_dev->core_if); if (dwc_otg_is_host_mode(otg_dev->core_if)) { dwc_otg_dump_host_registers( otg_dev->core_if); @@ -657,7 +657,7 @@ static ssize_t hcddump_show( struct device *_dev, struct device_attribute *attr, char *buf) { #ifndef DWC_DEVICE_ONLY - dwc_otg_device_t *otg_dev = _dev->platform_data; + dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)_dev->platform_data)); dwc_otg_hcd_dump_state(otg_dev->hcd); #endif return sprintf( buf, "HCD Dump\n" ); @@ -674,7 +674,7 @@ static ssize_t hcd_frrem_show( struct device *_dev, struct device_attribute *attr, char *buf) { #ifndef DWC_DEVICE_ONLY - dwc_otg_device_t *otg_dev = _dev->platform_data; + dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)_dev->platform_data)); dwc_otg_hcd_dump_frrem(otg_dev->hcd); #endif return sprintf( buf, "HCD Dump Frame Remaining\n" ); @@ -694,7 +694,7 @@ static ssize_t rd_reg_test_show( struct device *_dev, int i; int time; int start_jiffies; - dwc_otg_device_t *otg_dev = _dev->platform_data; + dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)_dev->platform_data)); DWC_PRINT("HZ %d, MSEC_PER_JIFFIE %d, loops_per_jiffy %lu\n", HZ, MSEC_PER_JIFFIE, loops_per_jiffy); @@ -719,7 +719,7 @@ static ssize_t wr_reg_test_show( struct device *_dev, int i; int time; int start_jiffies; - dwc_otg_device_t *otg_dev = _dev->platform_data; + dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)_dev->platform_data)); uint32_t reg_val; DWC_PRINT("HZ %d, MSEC_PER_JIFFIE %d, loops_per_jiffy %lu\n", @@ -740,7 +740,7 @@ extern int dwc_debug(dwc_otg_core_if_t *core_if, int flag); static ssize_t debug_show( struct device *_dev, struct device_attribute *attr, char *buf) { - dwc_otg_device_t *otg_dev = _dev->platform_data; + dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)_dev->platform_data)); dwc_otg_dump_global_registers( otg_dev->core_if); if (dwc_otg_is_host_mode(otg_dev->core_if)) { dwc_otg_dump_host_registers( otg_dev->core_if); @@ -754,7 +754,7 @@ static ssize_t debug_store( struct device *_dev, const char *buf, size_t count ) { uint32_t val = simple_strtoul(buf, NULL, 16); - dwc_otg_device_t *otg_dev = _dev->platform_data; + dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)_dev->platform_data)); dwc_otg_dump_global_registers( otg_dev->core_if); dwc_debug(otg_dev->core_if,val); return count; diff --git a/drivers/usb/dwc_otg/dwc_otg_cil_intr.c b/drivers/usb/dwc_otg/dwc_otg_cil_intr.c index ec8b88875ce1..fcfced9c0f24 100755 --- a/drivers/usb/dwc_otg/dwc_otg_cil_intr.c +++ b/drivers/usb/dwc_otg/dwc_otg_cil_intr.c @@ -341,7 +341,6 @@ int32_t dwc_otg_handle_otg_intr(dwc_otg_core_if_t *_core_if) #ifdef DWC_BOTH_HOST_SLAVE extern void dwc_otg_force_device(dwc_otg_core_if_t *core_if); extern void dwc_otg_force_host(dwc_otg_core_if_t *core_if); -extern int dwc_otg20phy_suspend( int exitsuspend ); #endif int32_t dwc_otg_handle_conn_id_status_change_intr(dwc_otg_core_if_t *_core_if) @@ -352,10 +351,6 @@ int32_t dwc_otg_handle_conn_id_status_change_intr(dwc_otg_core_if_t *_core_if) dwc_otg_pcd_t *pcd = _core_if->otg_dev->pcd; gintmsk_data_t gintmsk = { .d32 = 0 }; gotgctl_data_t gotgctl = { .d32 = 0 }; - if(pcd &&(pcd->phy_suspend == 1)) - { - dwc_otg20phy_suspend( 1 ); - } /* * yangkai@rk, 20100331 diff --git a/drivers/usb/dwc_otg/dwc_otg_driver.c b/drivers/usb/dwc_otg/dwc_otg_driver.c index e4d212900266..754f8f62aa12 100755 --- a/drivers/usb/dwc_otg/dwc_otg_driver.c +++ b/drivers/usb/dwc_otg/dwc_otg_driver.c @@ -48,7 +48,6 @@ * device. */ -#include #include #include #include @@ -61,12 +60,6 @@ #include #include -#ifdef CONFIG_MACH_RK30_DS1001B -#include -#include -#include -#endif - #include "linux/dwc_otg_plat.h" #include #include "dwc_otg_attr.h" @@ -74,7 +67,8 @@ #include "dwc_otg_cil.h" #include "dwc_otg_pcd.h" #include "dwc_otg_hcd.h" -#include + +#include "usbdev_rk.h" //#define DWC_DRIVER_VERSION "2.60a 22-NOV-2006" //#define DWC_DRIVER_VERSION "2.70 2009-12-31" #define DWC_DRIVER_VERSION "3.00 2010-12-12 rockchip" @@ -342,46 +336,28 @@ extern struct usb_hub *g_root_hub20; #ifdef DWC_BOTH_HOST_SLAVE extern void hcd_start( dwc_otg_core_if_t *_core_if ); -extern int dwc_otg20phy_suspend( int exitsuspend ); extern void hub_disconnect_device(struct usb_hub *hub); static ssize_t force_usb_mode_show(struct device_driver *_drv, char *_buf) { dwc_otg_device_t *otg_dev = g_otgdev; dwc_otg_core_if_t *core_if = otg_dev->core_if; -#if 1 + return sprintf (_buf, "%d\n", core_if->usb_mode); -#else - dwc_otg_device_t *otg_dev = lm_get_drvdata(g_lmdev); - dwc_otg_core_if_t *core_if = otg_dev->core_if; - gotgctl_data_t gctrl; - gctrl.d32 = dwc_read_reg32( &core_if->core_global_regs->gotgctl ); - printk("OTGCTL=0x%08X\n", gctrl.d32); - - if(g_usb_mode == USB_NORMAL_MODE) - return sprintf (_buf, "Current usb mode: Normal Mode\n"); - else if(g_usb_mode == FORCE_HOST_MODE) - return sprintf (_buf, "Current usb mode: Force Host\n"); - else if(g_usb_mode == FORCE_DEVICE_MODE) - return sprintf (_buf, "Current usb mode: Force Device\n"); - else - return sprintf (_buf, "Current usb mode: Unknown\n"); -#endif } void dwc_otg_force_host(dwc_otg_core_if_t *core_if) { dwc_otg_device_t *otg_dev = g_otgdev; dctl_data_t dctl = {.d32=0}; + struct dwc_otg_platform_data *pldata = otg_dev->pldata; if(core_if->op_state == A_HOST) { printk("dwc_otg_force_host,already in A_HOST mode,everest\n"); return; } - if((otg_dev->pcd)&&(otg_dev->pcd->phy_suspend == 1)) - { - dwc_otg20phy_suspend( 1 ); - } + if(pldata->phy_suspend) + pldata->phy_suspend(pldata,USB_PHY_ENABLED); del_timer(&otg_dev->pcd->check_vbus_timer); // force disconnect /* soft disconnect */ @@ -452,6 +428,7 @@ static ssize_t force_usb_mode_store(struct device_driver *_drv, const char *_buf int new_mode = simple_strtoul(_buf, NULL, 16); dwc_otg_device_t *otg_dev = g_otgdev; dwc_otg_core_if_t *core_if = otg_dev->core_if; + struct dwc_otg_platform_data *pldata = otg_dev->pldata; DWC_PRINT("%s %d->%d\n",__func__, core_if->usb_mode, new_mode); if(core_if->usb_mode == new_mode) { @@ -505,10 +482,8 @@ static ssize_t force_usb_mode_store(struct device_driver *_drv, const char *_buf if(USB_MODE_FORCE_DEVICE == core_if->usb_mode) { core_if->usb_mode = new_mode; - if((otg_dev->pcd)&&(otg_dev->pcd->phy_suspend == 1)) - { - dwc_otg20phy_suspend( 1 ); - } + if(pldata->phy_suspend) + pldata->phy_suspend(pldata,USB_PHY_ENABLED); del_timer(&otg_dev->pcd->check_vbus_timer); dwc_otg_set_gusbcfg(core_if, new_mode); msleep(50); @@ -527,10 +502,8 @@ static ssize_t force_usb_mode_store(struct device_driver *_drv, const char *_buf } else if(USB_MODE_FORCE_HOST == core_if->usb_mode) { - if((otg_dev->pcd)&&(otg_dev->pcd->phy_suspend == 1)) - { - dwc_otg20phy_suspend( 1 ); - } + if(pldata->phy_suspend) + pldata->phy_suspend(pldata,USB_PHY_ENABLED); core_if->usb_mode = new_mode; dwc_otg_set_gusbcfg(core_if, new_mode); msleep(100); @@ -555,7 +528,7 @@ static DRIVER_ATTR(force_usb_mode, 0666/*S_IRUGO|S_IWUSR*/, force_usb_mode_show, static ssize_t dwc_otg_enable_show( struct device *_dev, struct device_attribute *attr, char *buf) { - dwc_otg_device_t *otg_dev = _dev->platform_data; + dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)_dev->platform_data)); return sprintf (buf, "%d\n", otg_dev->hcd->host_enabled); } @@ -563,10 +536,11 @@ static ssize_t dwc_otg_enable_store( struct device *_dev, struct device_attribute *attr, const char *buf, size_t count ) { - dwc_otg_device_t *otg_dev = _dev->platform_data; + dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)_dev->platform_data)); dwc_otg_core_if_t *_core_if = otg_dev->core_if; struct platform_device *pdev = to_platform_device(_dev); uint32_t val = simple_strtoul(buf, NULL, 16); + struct dwc_otg_platform_data *pldata = _dev->platform_data; if(otg_dev->hcd->host_enabled == val) return count; @@ -582,21 +556,16 @@ static ssize_t dwc_otg_enable_store( struct device *_dev, if (_core_if->hcd_cb && _core_if->hcd_cb->stop) { _core_if->hcd_cb->stop( _core_if->hcd_cb->p ); } - if (_core_if->hcd_cb && _core_if->hcd_cb->suspend) { - _core_if->hcd_cb->suspend( _core_if->hcd_cb->p, val); - } + if(pldata->phy_suspend) + pldata->phy_suspend(pldata,USB_PHY_SUSPEND); udelay(3); - clk_disable(otg_dev->phyclk); - clk_disable(otg_dev->ahbclk); + pldata->clock_enable(pldata, 0); } else if(val == 1) { DWC_PRINT("enable host controller:%s\n",pdev->name); - clk_enable(otg_dev->phyclk); - clk_enable(otg_dev->ahbclk); - if (_core_if->hcd_cb && _core_if->hcd_cb->suspend) { - _core_if->hcd_cb->suspend( _core_if->hcd_cb->p, val); - } + pldata->clock_enable(pldata, 1); + pldata->phy_suspend(pldata,USB_PHY_ENABLED); mdelay(5); if (_core_if->hcd_cb && _core_if->hcd_cb->start) { _core_if->hcd_cb->start( _core_if->hcd_cb->p ); @@ -1105,7 +1074,7 @@ static irqreturn_t dwc_otg_common_irq(int _irq, void *_dev) static int dwc_otg_driver_remove(struct platform_device *pdev) { struct device *dev = &pdev->dev; - dwc_otg_device_t *otg_dev = dev->platform_data; + dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)dev->platform_data)); DWC_DEBUGPL(DBG_ANY, "%s(%p)\n", __func__, pdev); if (otg_dev == NULL) @@ -1152,20 +1121,12 @@ static int dwc_otg_driver_remove(struct platform_device *pdev) { iounmap(otg_dev->base); } - clk_put(otg_dev->phyclk); - clk_disable(otg_dev->phyclk); - clk_put(otg_dev->ahbclk); - clk_disable(otg_dev->ahbclk); -#ifdef CONFIG_ARCH_RK29 - clk_put(otg_dev->busclk); - clk_disable(otg_dev->busclk); -#endif kfree(otg_dev); /* * Clear the drvdata pointer. */ - dev->platform_data = 0; +// dev->platform_data = 0; #ifdef DWC_BOTH_HOST_SLAVE dwc_otg_module_params.host_rx_fifo_size = -1; @@ -1195,134 +1156,22 @@ static __devinit int dwc_otg_driver_probe(struct platform_device *pdev) dwc_otg_device_t *dwc_otg_device; int32_t snpsid; int irq; - int32_t regval; - struct clk *ahbclk,*phyclk,*busclk; -#ifdef CONFIG_ARCH_RK29 - unsigned int * otg_phy_con1 = (unsigned int*)(USB_GRF_CON); -#endif -#ifdef CONFIG_ARCH_RK30 - unsigned int * otg_phy_con = (unsigned int*)(USBGRF_UOC0_CON2); -#endif -#ifdef CONFIG_ARCH_RK2928 - unsigned int * otg_phy_con = (unsigned int*)(USBGRF_UOC0_CON5); -#endif - -#ifdef CONFIG_ARCH_RK29 - regval = * otg_phy_con1; -#ifndef CONFIG_USB11_HOST - /* - * disable usb host 1.1 controller if not support - */ - phyclk = clk_get(NULL, "uhost"); - if (IS_ERR(phyclk)) { - retval = PTR_ERR(phyclk); - DWC_ERROR("can't get UHOST clock\n"); - goto fail; - } - clk_enable(phyclk); - - ahbclk = clk_get(NULL, "hclk_uhost"); - if (IS_ERR(ahbclk)) { - retval = PTR_ERR(ahbclk); - DWC_ERROR("can't get UHOST ahb bus clock\n"); - goto fail; - } - clk_enable(ahbclk); - - regval |= (0x01<<28); - - *otg_phy_con1 = regval; - - udelay(3); - clk_disable(phyclk); - clk_disable(ahbclk); -#endif -#ifndef CONFIG_USB20_HOST - /* - * disable usb host 2.0 phy if not support - */ - phyclk = clk_get(NULL, "otgphy1"); - if (IS_ERR(phyclk)) { - retval = PTR_ERR(phyclk); - DWC_ERROR("can't get USBPHY1 clock\n"); - goto fail; - } - clk_enable(phyclk); - - ahbclk = clk_get(NULL, "usbotg1"); - if (IS_ERR(ahbclk)) { - retval = PTR_ERR(ahbclk); - DWC_ERROR("can't get USBOTG1 ahb bus clock\n"); - goto fail; - } - clk_enable(ahbclk); + struct dwc_otg_platform_data *pldata = dev->platform_data; + + // clock and hw init + if(pldata->soft_reset) + pldata->soft_reset(); - regval &= ~(0x01<<14); // enter suspend. - regval |= (0x01<<13); // software control enable. + if(pldata->clock_init){ + pldata->clock_init(pldata); + pldata->clock_enable(pldata, 1); + } - *otg_phy_con1 = regval; - udelay(3); - clk_disable(phyclk); - clk_disable(ahbclk); -#endif -#endif + if(pldata->hw_init) + pldata->hw_init(); + if(pldata->phy_suspend) + pldata->phy_suspend(pldata, USB_PHY_ENABLED); -#ifdef CONFIG_ARCH_RK30 -#ifndef CONFIG_USB20_HOST - otg_phy_con = (unsigned int*)(USBGRF_UOC1_CON2); - /* - * disable usb host 2.0 phy if not support - */ - phyclk = clk_get(NULL, "otgphy1"); - if (IS_ERR(phyclk)) { - retval = PTR_ERR(phyclk); - DWC_ERROR("can't get USBPHY1 clock\n"); - goto fail; - } - clk_enable(phyclk); - - ahbclk = clk_get(NULL, "hclk_otg1"); - if (IS_ERR(ahbclk)) { - retval = PTR_ERR(ahbclk); - DWC_ERROR("can't get USBOTG1 ahb bus clock\n"); - goto fail; - } - clk_enable(ahbclk); - - *otg_phy_con = ((0x01<<2)|(0x00<<3)|(0x05<<6))|(((0x01<<2)|(0x01<<3)|(0x07<<6))<<16); // enter suspend. - udelay(3); - clk_disable(phyclk); - clk_disable(ahbclk); -#endif -#endif -#ifdef CONFIG_ARCH_RK2928 -#ifndef CONFIG_USB20_HOST - otg_phy_con = (unsigned int*)(USBGRF_UOC1_CON5); - /* - * disable usb host 2.0 phy if not support - */ - phyclk = clk_get(NULL, "otgphy1"); - if (IS_ERR(phyclk)) { - retval = PTR_ERR(phyclk); - DWC_ERROR("can't get USBPHY1 clock\n"); - goto fail; - } - clk_enable(phyclk); - - ahbclk = clk_get(NULL, "hclk_otg1"); - if (IS_ERR(ahbclk)) { - retval = PTR_ERR(ahbclk); - DWC_ERROR("can't get USBOTG1 ahb bus clock\n"); - goto fail; - } - clk_enable(ahbclk); - - *otg_phy_con = ((0x01<<0)|(0x00<<1)|(0x05<<4))|(((0x01<<0)|(0x01<<1)|(0x07<<4))<<16); // enter suspend. - udelay(3); - clk_disable(phyclk); - clk_disable(ahbclk); -#endif -#endif dwc_otg_device = kmalloc(sizeof(dwc_otg_device_t), GFP_KERNEL); if (dwc_otg_device == 0) @@ -1335,122 +1184,6 @@ static __devinit int dwc_otg_driver_probe(struct platform_device *pdev) memset(dwc_otg_device, 0, sizeof(*dwc_otg_device)); dwc_otg_device->reg_offset = 0xFFFFFFFF; -#ifdef CONFIG_ARCH_RK29 - cru_set_soft_reset(SOFT_RST_USB_OTG_2_0_AHB_BUS, true); - cru_set_soft_reset(SOFT_RST_USB_OTG_2_0_PHY, true); - cru_set_soft_reset(SOFT_RST_USB_OTG_2_0_CONTROLLER, true); - udelay(1); - - cru_set_soft_reset(SOFT_RST_USB_OTG_2_0_AHB_BUS, false); - cru_set_soft_reset(SOFT_RST_USB_OTG_2_0_PHY, false); - cru_set_soft_reset(SOFT_RST_USB_OTG_2_0_CONTROLLER, false); - busclk = clk_get(NULL, "hclk_usb_peri"); - if (IS_ERR(busclk)) { - retval = PTR_ERR(busclk); - DWC_ERROR("can't get USB PERIPH AHB bus clock\n"); - goto fail; - } - clk_enable(busclk); - - phyclk = clk_get(NULL, "otgphy0"); - if (IS_ERR(phyclk)) { - retval = PTR_ERR(phyclk); - DWC_ERROR("can't get USBPHY0 clock\n"); - goto fail; - } - clk_enable(phyclk); - - ahbclk = clk_get(NULL, "usbotg0"); - if (IS_ERR(ahbclk)) { - retval = PTR_ERR(ahbclk); - DWC_ERROR("can't get USB otg0 ahb bus clock\n"); - goto fail; - } - clk_enable(ahbclk); - - /* - * Enable usb phy 0 - */ - regval = * otg_phy_con1; - regval |= (0x01<<2); - regval |= (0x01<<3); // exit suspend. - regval &= ~(0x01<<2); - *otg_phy_con1 = regval; - - dwc_otg_device->phyclk = phyclk; - dwc_otg_device->ahbclk = ahbclk; - dwc_otg_device->busclk = busclk; -#endif -#ifdef CONFIG_ARCH_RK30 - otg_phy_con = (unsigned int*)(USBGRF_UOC0_CON2); - cru_set_soft_reset(SOFT_RST_USBPHY0, true); - cru_set_soft_reset(SOFT_RST_OTGC0, true); - cru_set_soft_reset(SOFT_RST_USBOTG0, true); - udelay(1); - - cru_set_soft_reset(SOFT_RST_USBOTG0, false); - cru_set_soft_reset(SOFT_RST_OTGC0, false); - cru_set_soft_reset(SOFT_RST_USBPHY0, false); - - phyclk = clk_get(NULL, "otgphy0"); - if (IS_ERR(phyclk)) { - retval = PTR_ERR(phyclk); - DWC_ERROR("can't get USBPHY0 clock\n"); - goto fail; - } - clk_enable(phyclk); - - ahbclk = clk_get(NULL, "hclk_otg0"); - if (IS_ERR(ahbclk)) { - retval = PTR_ERR(ahbclk); - DWC_ERROR("can't get USB otg0 ahb bus clock\n"); - goto fail; - } - clk_enable(ahbclk); - - /* - * Enable usb phy 0 - */ - *otg_phy_con = ((0x01<<2)<<16); - - dwc_otg_device->phyclk = phyclk; - dwc_otg_device->ahbclk = ahbclk; -#endif -#ifdef CONFIG_ARCH_RK2928 - otg_phy_con = (unsigned int*)(USBGRF_UOC0_CON5); - cru_set_soft_reset(SOFT_RST_USBPHY0, true); - cru_set_soft_reset(SOFT_RST_OTGC0, true); - cru_set_soft_reset(SOFT_RST_USBOTG0, true); - udelay(1); - - cru_set_soft_reset(SOFT_RST_USBOTG0, false); - cru_set_soft_reset(SOFT_RST_OTGC0, false); - cru_set_soft_reset(SOFT_RST_USBPHY0, false); - - phyclk = clk_get(NULL, "otgphy0"); - if (IS_ERR(phyclk)) { - retval = PTR_ERR(phyclk); - DWC_ERROR("can't get USBPHY0 clock\n"); - goto fail; - } - clk_enable(phyclk); - - ahbclk = clk_get(NULL, "hclk_otg0"); - if (IS_ERR(ahbclk)) { - retval = PTR_ERR(ahbclk); - DWC_ERROR("can't get USB otg0 ahb bus clock\n"); - goto fail; - } - clk_enable(ahbclk); - - /* - * Enable usb phy 0 - */ - *otg_phy_con = (0x01<<16); - - dwc_otg_device->phyclk = phyclk; - dwc_otg_device->ahbclk = ahbclk; -#endif /* * Map the DWC_otg Core memory into virtual address space. */ @@ -1494,8 +1227,12 @@ static __devinit int dwc_otg_driver_probe(struct platform_device *pdev) * Initialize driver data to point to the global DWC_otg * Device structure. */ - dev->platform_data = dwc_otg_device; + //dev->platform_data = dwc_otg_device; + pldata->privdata = dwc_otg_device; + dwc_otg_device->pldata = (void *)pldata; + dev_dbg(dev, "dwc_otg_device=0x%p\n", dwc_otg_device); + g_otgdev = dwc_otg_device; dwc_otg_device->core_if = dwc_otg_cil_init( dwc_otg_device->base, @@ -1580,17 +1317,6 @@ static __devinit int dwc_otg_driver_probe(struct platform_device *pdev) /* Initialize the bus state. If the core is in Device Mode * HALT the USB bus and return. */ #ifndef CONFIG_DWC_OTG_DEVICE_ONLY -#ifdef CONFIG_ARCH_RK29 - USB_IOMUX_INIT(GPIO4A5_OTG0DRVVBUS_NAME, GPIO4L_OTG0_DRV_VBUS); -#endif -#if defined(CONFIG_ARCH_RK3066B) - USB_IOMUX_INIT(GPIO3D5_PWM2_JTAGTCK_OTGDRVVBUS_NAME, GPIO3D_OTGDRVVBUS); -#elif defined(CONFIG_ARCH_RK30) - USB_IOMUX_INIT(GPIO0A5_OTGDRVVBUS_NAME, GPIO0A_OTG_DRV_VBUS); -#endif -#ifdef CONFIG_ARCH_RK2928 - USB_IOMUX_INIT(GPIO3C1_OTG_DRVVBUS_NAME, GPIO3C_OTG_DRVVBUS); -#endif /* * Initialize the HCD */ @@ -1629,12 +1355,12 @@ static __devinit int dwc_otg_driver_probe(struct platform_device *pdev) } #ifndef CONFIG_DWC_OTG_HOST_ONLY -extern int dwc_otg20phy_suspend( int exitsuspend ); static int dwc_otg_driver_suspend(struct platform_device *_dev , pm_message_t state ) { struct device *dev = &_dev->dev; - dwc_otg_device_t *otg_dev = dev->platform_data; + dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)dev->platform_data)); dwc_otg_core_if_t *core_if = otg_dev->core_if; + struct dwc_otg_platform_data *pldata = dev->platform_data; if(core_if->op_state == A_HOST) { DWC_PRINT("%s,A_HOST mode\n", __func__); @@ -1643,7 +1369,7 @@ static int dwc_otg_driver_suspend(struct platform_device *_dev , pm_message_t st /* Clear any pending interrupts */ dwc_write_reg32( &core_if->core_global_regs->gintsts, 0xFFFFFFFF); dwc_otg_disable_global_interrupts(core_if); - dwc_otg20phy_suspend(0); + pldata->phy_suspend(pldata,USB_PHY_SUSPEND); del_timer(&otg_dev->pcd->check_vbus_timer); return 0; @@ -1658,9 +1384,10 @@ static int dwc_otg_driver_suspend(struct platform_device *_dev , pm_message_t st static int dwc_otg_driver_resume(struct platform_device *_dev ) { struct device *dev = &_dev->dev; - dwc_otg_device_t *otg_dev = dev->platform_data; + dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)dev->platform_data)); dwc_otg_core_if_t *core_if = otg_dev->core_if; dctl_data_t dctl = {.d32=0}; + struct dwc_otg_platform_data *pldata = dev->platform_data; dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs; @@ -1671,7 +1398,7 @@ static int dwc_otg_driver_resume(struct platform_device *_dev ) } #ifndef CONFIG_DWC_OTG_HOST_ONLY - dwc_otg20phy_suspend(1); + pldata->phy_suspend(pldata,USB_PHY_ENABLED); /* soft disconnect */ /* 20100226,HSL@RK,if not disconnect,when usb cable in,will auto reconnect @@ -1701,7 +1428,7 @@ static int dwc_otg_driver_resume(struct platform_device *_dev ) static void dwc_otg_driver_shutdown(struct platform_device *_dev ) { struct device *dev = &_dev->dev; - dwc_otg_device_t *otg_dev = dev->platform_data; + dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)dev->platform_data)); dwc_otg_core_if_t *core_if = otg_dev->core_if; dctl_data_t dctl = {.d32=0}; @@ -1738,286 +1465,6 @@ static struct platform_driver dwc_otg_driver = { .owner = THIS_MODULE}, }; -#ifdef CONFIG_USB11_HOST -extern void dwc_otg_hcd_remove(struct device *dev); -extern int __devinit host11_hcd_init(struct device *dev); - -static int host11_driver_remove(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - dwc_otg_device_t *otg_dev = dev->platform_data; - DWC_DEBUGPL(DBG_ANY, "%s(%p)\n", __func__, pdev); - - if (otg_dev == NULL) - { - /* Memory allocation for the dwc_otg_device failed. */ - return 0; - } - - /* - * Free the IRQ - */ - if (otg_dev->common_irq_installed) - { - free_irq( platform_get_irq(to_platform_device(dev),0), otg_dev ); - } - - if (otg_dev->hcd != NULL) - { - dwc_otg_hcd_remove(dev); - } - - if (otg_dev->core_if != NULL) - { - dwc_otg_cil_remove( otg_dev->core_if ); - } - - /* - * Remove the device attributes - */ - //dwc_otg_attr_remove(dev); - - /* - * Return the memory. - */ - if (otg_dev->base != NULL) - { - iounmap(otg_dev->base); - } - clk_put(otg_dev->phyclk); - clk_disable(otg_dev->phyclk); - clk_put(otg_dev->ahbclk); - clk_disable(otg_dev->ahbclk); - kfree(otg_dev); - - /* - * Clear the drvdata pointer. - */ - dev->platform_data = 0; - - return 0; -} - -/** - * 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[in] pdev platform_device definition - */ -static __devinit int host11_driver_probe(struct platform_device *pdev) -{ - struct resource *res_base; - int retval = 0; - struct device *dev = &pdev->dev; - dwc_otg_device_t *dwc_otg_device; - int32_t snpsid; - int irq; - struct clk* ahbclk,*phyclk; - /* - *Enable usb phy - */ - unsigned int * otg_phy_con1 = (unsigned int*)(USB_GRF_CON); - - *otg_phy_con1 &= ~(0x01<<28); // exit suspend. - #if 0 - *otg_phy_con1 |= (0x01<<2); - *otg_phy_con1 |= (0x01<<3); // exit suspend. - *otg_phy_con1 &= ~(0x01<<2); - otgreg = ioremap(RK2818_USBOTG_PHYS,RK2818_USBOTG_SIZE); - DWC_PRINT("%s otg2.0 reg addr: 0x%x",__func__,otgreg); - dwc_modify_reg32((uint32_t *)(otgreg+0xc),0x20000000,0x20000000); - dwc_write_reg32((uint32_t *)(otgreg+0x440), 0x1000); - #endif - - dwc_otg_device = kmalloc(sizeof(dwc_otg_device_t), GFP_KERNEL); - - if (dwc_otg_device == 0) - { - dev_err(dev, "kmalloc of dwc_otg_device failed\n"); - retval = -ENOMEM; - goto fail; - } - - memset(dwc_otg_device, 0, sizeof(*dwc_otg_device)); - dwc_otg_device->reg_offset = 0xFFFFFFFF; - - cru_set_soft_reset(SOFT_RST_UHOST, true); - udelay(1); - - cru_set_soft_reset(SOFT_RST_UHOST, false); - - phyclk = clk_get(NULL, "uhost"); - if (IS_ERR(phyclk)) { - retval = PTR_ERR(phyclk); - DWC_ERROR("can't get UHOST clock\n"); - goto fail; - } - clk_enable(phyclk); - - ahbclk = clk_get(NULL, "hclk_uhost"); - if (IS_ERR(ahbclk)) { - retval = PTR_ERR(ahbclk); - DWC_ERROR("can't get UHOST ahb bus clock\n"); - goto fail1; - } - clk_enable(ahbclk); - - if (clk_get_rate(phyclk) != 48000000) { - DWC_PRINT("Bad USB clock (%d Hz), changing to 48000000 Hz\n", - (int)clk_get_rate(phyclk)); - if (clk_set_rate(phyclk, 48000000)) { - DWC_ERROR("Unable to set correct USB clock (48MHz)\n"); - retval = -EIO; - goto fail2; - } - } - dwc_otg_device->ahbclk = ahbclk; - dwc_otg_device->phyclk = phyclk; - - /* - * Map the DWC_otg Core memory into virtual address space. - */ - - res_base = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res_base) - goto fail; - - dwc_otg_device->base = - ioremap(res_base->start,USBOTG_SIZE); - DWC_PRINT("%s host1.1 reg addr: 0x%x remap:0x%x\n",__func__, - (unsigned)res_base->start, (unsigned)dwc_otg_device->base); - if (dwc_otg_device->base == NULL) - { - DWC_ERROR("ioremap() failed\n"); - retval = -ENOMEM; - goto fail; - } - DWC_DEBUGPL( DBG_CIL, "base addr for rk29 host11:0x%x\n", (unsigned)dwc_otg_device->base); - /* - * Attempt to ensure this device is really a DWC_otg Controller. - * Read and verify the SNPSID register contents. The value should be - * 0x45F42XXX, which corresponds to "OT2", as in "OTG version 2.XX". - */ - snpsid = dwc_read_reg32((uint32_t *)((uint8_t *)dwc_otg_device->base + 0x40)); - if ((snpsid & 0xFFFFF000) != 0x4F542000) - { - DWC_PRINT("%s::snpsid=0x%x,want 0x%x" , __func__ , snpsid , 0x4F542000 ); - dev_err(dev, "Bad value for SNPSID: 0x%08x\n", snpsid); - retval = -EINVAL; - goto fail; - } - - /* - * Initialize driver data to point to the global DWC_otg - * Device structure. - */ - dev->platform_data = dwc_otg_device; - DWC_DEBUGPL(DBG_CIL, "dwc_otg_device=0x%p\n", dwc_otg_device); - g_host11 = dwc_otg_device; - - dwc_otg_device->core_if = dwc_otg_cil_init( dwc_otg_device->base, - &host11_module_params); - if (dwc_otg_device->core_if == 0) - { - dev_err(dev, "CIL initialization failed!\n"); - retval = -ENOMEM; - goto fail; - } - - dwc_otg_device->core_if->otg_dev = dwc_otg_device; - /* - * Validate parameter values. - */ - if (check_parameters(dwc_otg_device->core_if) != 0) - { - retval = -EINVAL; - goto fail; - } - - /* - * Create Device Attributes in sysfs - */ - dwc_otg_attr_create(dev); - retval |= device_create_file(dev, &dev_attr_enable); - - /* - * Disable the global interrupt until all the interrupt - * handlers are installed. - */ - dwc_otg_disable_global_interrupts( dwc_otg_device->core_if ); - /* - * Install the interrupt handler for the common interrupts before - * enabling common interrupts in core_init below. - */ - irq = platform_get_irq(to_platform_device(dev),0); - DWC_DEBUGPL( DBG_CIL, "registering (common) handler for irq%d\n", - irq); - retval = request_irq(irq, dwc_otg_common_irq, - IRQF_SHARED, "dwc_otg", dwc_otg_device ); - if (retval != 0) - { - DWC_ERROR("request of irq%d failed\n", irq); - retval = -EBUSY; - goto fail; - } - else - { - dwc_otg_device->common_irq_installed = 1; - } - - /* - * Initialize the DWC_otg core. - */ - dwc_otg_core_init( dwc_otg_device->core_if ); - - /* - * Initialize the HCD - */ - retval = host11_hcd_init(dev); - if (retval != 0) - { - DWC_ERROR("host11_hcd_init failed\n"); - dwc_otg_device->hcd = NULL; - goto fail; - } - /* - * Enable the global interrupt after all the interrupt - * handlers are installed. - */ - dwc_otg_enable_global_interrupts( dwc_otg_device->core_if ); -#ifndef CONFIG_USB11_HOST_EN - *otg_phy_con1 |= (0x01<<28); // enter suspend. - clk_disable(phyclk); - clk_disable(ahbclk); -#endif - return 0; - -fail2: - clk_put(ahbclk); - clk_disable(ahbclk); -fail1: - clk_put(phyclk); - clk_disable(phyclk); - - fail: - devm_kfree(&pdev->dev, dwc_otg_device); - DWC_PRINT("host11_driver_probe fail,everest\n"); - return retval; -} - -static struct platform_driver host11_driver = { - .probe = host11_driver_probe, - .remove = host11_driver_remove, - .driver = { - .name = "usb11_host", - .owner = THIS_MODULE}, -}; -#endif #ifdef CONFIG_USB20_HOST extern void dwc_otg_hcd_remove(struct device *dev); @@ -2027,7 +1474,7 @@ extern int __devinit host20_hcd_init(struct device *_dev); static int host20_driver_remove(struct platform_device *pdev) { struct device *dev = &pdev->dev; - dwc_otg_device_t *otg_dev = dev->platform_data; + dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)dev->platform_data)); DWC_DEBUGPL(DBG_ANY, "%s(%p)\n", __func__, pdev); if (otg_dev == NULL) @@ -2066,16 +1513,12 @@ static int host20_driver_remove(struct platform_device *pdev) { iounmap(otg_dev->base); } - clk_put(otg_dev->phyclk); - clk_disable(otg_dev->phyclk); - clk_put(otg_dev->ahbclk); - clk_disable(otg_dev->ahbclk); kfree(otg_dev); /* * Clear the drvdata pointer. */ - dev->platform_data = 0; +// dev->platform_data = 0; return 0; @@ -2100,58 +1543,27 @@ static __devinit int host20_driver_probe(struct platform_device *pdev) dwc_otg_device_t *dwc_otg_device; int32_t snpsid; int irq; - uint32_t otgreg; - struct clk* ahbclk,*phyclk; + struct dwc_otg_platform_data *pldata = dev->platform_data; + + // clock and hw init + if(pldata->soft_reset) + pldata->soft_reset(); + + if(pldata->clock_init){ + pldata->clock_init(pldata); + pldata->clock_enable(pldata, 1); + } + + if(pldata->hw_init) + pldata->hw_init(); + if(pldata->phy_suspend) + pldata->phy_suspend(pldata, USB_PHY_ENABLED); /* *Enable usb phy */ -#ifdef CONFIG_ARCH_RK29 - unsigned int * otg_phy_con1 = (unsigned int*)(USB_GRF_CON); - otgreg = * otg_phy_con1; - otgreg |= (0x01<<13); // software control enable - otgreg |= (0x01<<14); // exit suspend. - otgreg &= ~(0x01<<13); // software control disable - *otg_phy_con1 = otgreg; -#endif -#ifdef CONFIG_ARCH_RK30 - unsigned int * otg_phy_con1 = (unsigned int*)(USBGRF_UOC1_CON2); - *otg_phy_con1 = ((0x01<<2)<<16); // exit suspend. -#endif -#ifdef CONFIG_ARCH_RK2928 - unsigned int * otg_phy_con1 = (unsigned int*)(USBGRF_UOC1_CON5); - *otg_phy_con1 = (0x01<<16); // exit suspend. - // inno phy config - *(unsigned int *)(USBGRF_UOC0_CON5+4) = 0x07e00350; -#endif - #if 0 - *otg_phy_con1 |= (0x01<<2); - *otg_phy_con1 |= (0x01<<3); // exit suspend. - *otg_phy_con1 &= ~(0x01<<2); - otgreg = ioremap(RK2818_USBOTG_PHYS,RK2818_USBOTG_SIZE); - DWC_PRINT("%s otg2.0 reg addr: 0x%x",__func__,otgreg); - dwc_modify_reg32((uint32_t *)(otgreg+0xc),0x20000000,0x20000000); - dwc_write_reg32((uint32_t *)(otgreg+0x440), 0x1000); - #endif dwc_otg_device = kmalloc(sizeof(dwc_otg_device_t), GFP_KERNEL); -#ifdef CONFIG_ARCH_RK29 - cru_set_soft_reset(SOFT_RST_USB_HOST_2_0_AHB_BUS, true); - cru_set_soft_reset(SOFT_RST_USB_HOST_2_0_PHY, true); - cru_set_soft_reset(SOFT_RST_USB_HOST_2_0_CONTROLLER, true); - - udelay(1); - - cru_set_soft_reset(SOFT_RST_USB_HOST_2_0_AHB_BUS, false); - cru_set_soft_reset(SOFT_RST_USB_HOST_2_0_PHY, false); - cru_set_soft_reset(SOFT_RST_USB_HOST_2_0_CONTROLLER, false); -#endif -#ifdef CONFIG_ARCH_RK30 - *(unsigned int*)(USBGRF_UOC1_CON2+4) = ((1<<5)|((1<<5)<<16)); -#endif -#ifdef CONFIG_ARCH_RK2928 - *(unsigned int*)(USBGRF_UOC1_CON5-4) = ((1<<5)|((1<<5)<<16)); -#endif if (dwc_otg_device == 0) { dev_err(dev, "kmalloc of dwc_otg_device failed\n"); @@ -2162,32 +1574,6 @@ static __devinit int host20_driver_probe(struct platform_device *pdev) memset(dwc_otg_device, 0, sizeof(*dwc_otg_device)); dwc_otg_device->reg_offset = 0xFFFFFFFF; - phyclk = clk_get(NULL, "otgphy1"); - if (IS_ERR(phyclk)) { - retval = PTR_ERR(phyclk); - DWC_ERROR("can't get USBPHY1 clock\n"); - goto fail; - } - clk_enable(phyclk); - -#ifdef CONFIG_ARCH_RK29 - ahbclk = clk_get(NULL, "usbotg1"); -#endif -#if defined(CONFIG_ARCH_RK30) || defined(CONFIG_ARCH_RK3066B) - ahbclk = clk_get(NULL, "hclk_otg1"); -#endif -#ifdef CONFIG_ARCH_RK2928 - ahbclk = clk_get(NULL, "hclk_otg1"); -#endif - if (IS_ERR(ahbclk)) { - retval = PTR_ERR(ahbclk); - DWC_ERROR("can't get USBOTG1 ahb bus clock\n"); - goto fail; - } - clk_enable(ahbclk); - dwc_otg_device->phyclk = phyclk; - dwc_otg_device->ahbclk = ahbclk; - /* * Map the DWC_otg Core memory into virtual address space. */ @@ -2225,7 +1611,9 @@ static __devinit int host20_driver_probe(struct platform_device *pdev) * Initialize driver data to point to the global DWC_otg * Device structure. */ - dev->platform_data = dwc_otg_device; + pldata->privdata = dwc_otg_device; + dwc_otg_device->pldata = (void *)pldata; + DWC_DEBUGPL(DBG_CIL, "dwc_otg_device=0x%p\n", dwc_otg_device); g_host20 = dwc_otg_device; @@ -2279,14 +1667,6 @@ static __devinit int host20_driver_probe(struct platform_device *pdev) dwc_otg_device->common_irq_installed = 1; } -#ifdef CONFIG_ARCH_RK29 - USB_IOMUX_INIT(GPIO4A6_OTG1DRVVBUS_NAME, GPIO4L_OTG1_DRV_VBUS); -#endif -#if defined(CONFIG_ARCH_RK3066B) - USB_IOMUX_INIT(GPIO3D6_PWM3_JTAGTMS_HOSTDRVVBUS_NAME, GPIO3D_HOSTDRVVBUS); -#elif defined(CONFIG_ARCH_RK30) - USB_IOMUX_INIT(GPIO0A6_HOSTDRVVBUS_NAME, GPIO0A_HOST_DRV_VBUS); -#endif /* * Initialize the DWC_otg core. */ @@ -2307,19 +1687,7 @@ static __devinit int host20_driver_probe(struct platform_device *pdev) * handlers are installed. */ dwc_otg_enable_global_interrupts( dwc_otg_device->core_if ); -#ifndef CONFIG_USB20_HOST_EN - clk_disable(phyclk); - clk_disable(ahbclk); -#if defined(CONFIG_ARCH_RK29) - otgreg &= ~(0x01<<14); // suspend. - otgreg |= (0x01<<13); // software control enable - *otg_phy_con1 = otgreg; -#elif defined(CONFIG_ARCH_RK30) - *otg_phy_con1 = ((0x01<<2)|(0x00<<3)|(0x05<<6))|(((0x01<<2)|(0x01<<3)|(0x07<<6))<<16); // enter suspend. -#elif defined(CONFIG_ARCH_RK2928) - *otg_phy_con1 = ((0x01<<0)|(0x00<<1)|(0x05<<4))|(((0x01<<0)|(0x01<<1)|(0x07<<4))<<16); // enter suspend. -#endif -#endif + return 0; fail: diff --git a/drivers/usb/dwc_otg/dwc_otg_driver.h b/drivers/usb/dwc_otg/dwc_otg_driver.h index 3e334d0201e9..b7e58063ccea 100755 --- a/drivers/usb/dwc_otg/dwc_otg_driver.h +++ b/drivers/usb/dwc_otg/dwc_otg_driver.h @@ -64,10 +64,9 @@ typedef struct dwc_otg_device /** Pointer to the HCD structure. */ struct dwc_otg_hcd *hcd; - struct clk* phyclk; - struct clk* ahbclk; - struct clk* busclk; - + /** Pointer to platform device structure. */ + void *pldata; + /** Flag to indicate whether the common IRQ handler is installed. */ uint8_t common_irq_installed; diff --git a/drivers/usb/dwc_otg/dwc_otg_hcd.c b/drivers/usb/dwc_otg/dwc_otg_hcd.c index 96d7508d9860..ebb3a938cfcd 100755 --- a/drivers/usb/dwc_otg/dwc_otg_hcd.c +++ b/drivers/usb/dwc_otg/dwc_otg_hcd.c @@ -38,7 +38,6 @@ * This file contains the implementation of the HCD. In Linux, the HCD * implements the hc_driver API. */ -#include #include #include #include @@ -51,6 +50,7 @@ #include #include #include +#include "usbdev_rk.h" #include "dwc_otg_driver.h" #include "dwc_otg_hcd.h" @@ -62,6 +62,8 @@ static int dwc_otg_hcd_suspend(struct usb_hcd *hcd) dwc_otg_core_if_t *core_if = dwc_otg_hcd->core_if; hprt0_data_t hprt0; pcgcctl_data_t pcgcctl; + struct dwc_otg_platform_data *pldata; + pldata = core_if->otg_dev->pldata; if(core_if->op_state == B_PERIPHERAL) { @@ -104,15 +106,14 @@ static int dwc_otg_hcd_suspend(struct usb_hcd *hcd) } else //no device connect { - if (core_if->hcd_cb && core_if->hcd_cb->suspend) { - core_if->hcd_cb->suspend( core_if->hcd_cb->p, 0); - } + if(pldata->phy_suspend) + pldata->phy_suspend( pldata, USB_PHY_SUSPEND); } udelay(3); - #ifndef CONFIG_DWC_REMOTE_WAKEUP - clk_disable(core_if->otg_dev->phyclk); - clk_disable(core_if->otg_dev->ahbclk); - #endif +#ifndef CONFIG_DWC_REMOTE_WAKEUP + if (pldata->clock_enable) + pldata->clock_enable( pldata, 0); +#endif //power off return 0; } @@ -124,6 +125,8 @@ static int dwc_otg_hcd_resume(struct usb_hcd *hcd) hprt0_data_t hprt0; pcgcctl_data_t pcgcctl; gintmsk_data_t gintmsk; + struct dwc_otg_platform_data *pldata; + pldata = core_if->otg_dev->pldata; if(core_if->op_state == B_PERIPHERAL) { @@ -134,10 +137,10 @@ static int dwc_otg_hcd_resume(struct usb_hcd *hcd) if(!dwc_otg_hcd->host_enabled) return 0; #endif - #ifndef CONFIG_DWC_REMOTE_WAKEUP - clk_enable(core_if->otg_dev->phyclk); - clk_enable(core_if->otg_dev->ahbclk); - #endif +#ifndef CONFIG_DWC_REMOTE_WAKEUP + if (pldata->clock_enable) + pldata->clock_enable( pldata, 1); +#endif //partial power-down //power on pcgcctl.d32 = dwc_read_reg32(core_if->pcgcctl);; @@ -185,11 +188,9 @@ static int dwc_otg_hcd_resume(struct usb_hcd *hcd) mdelay(10); } - else - { - if (core_if->hcd_cb && core_if->hcd_cb->suspend) { - core_if->hcd_cb->suspend( core_if->hcd_cb->p, 1); - } + else{ + if(pldata->phy_suspend) + pldata->phy_suspend( pldata, USB_PHY_ENABLED); } gintmsk.b.portintr = 1; dwc_write_reg32(&core_if->core_global_regs->gintmsk, gintmsk.d32); @@ -583,7 +584,7 @@ static void dwc_otg_hcd_start_connect_timer( dwc_otg_hcd_t *_hcd) */ static int32_t dwc_otg_hcd_session_start_cb( void *_p ) { - dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd (_p); +// dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd (_p); DWC_DEBUGPL(DBG_HCDV, "%s(%p)\n", __func__, _p); // dwc_otg_hcd_start_connect_timer( dwc_otg_hcd ); return 1; @@ -681,14 +682,16 @@ static struct tasklet_struct reset_tasklet = { .func = reset_tasklet_func, .data = 0, }; -#if defined(CONFIG_ARCH_RK30) || defined(CONFIG_ARCH_RK2928) +#ifndef CONFIG_ARCH_RK29 static void dwc_otg_hcd_enable(struct work_struct *work) { dwc_otg_hcd_t *dwc_otg_hcd; dwc_otg_core_if_t *_core_if; + struct dwc_otg_platform_data *pldata; dwc_otg_hcd = container_of(work, dwc_otg_hcd_t, host_enable_work.work); _core_if = dwc_otg_hcd->core_if; + pldata = _core_if->otg_dev->pldata; if(dwc_otg_hcd->host_enabled == dwc_otg_hcd->host_setenable){ // DWC_PRINT("%s, enable flag %d\n", __func__, dwc_otg_hcd->host_setenable); @@ -707,21 +710,17 @@ static void dwc_otg_hcd_enable(struct work_struct *work) if (_core_if->hcd_cb && _core_if->hcd_cb->stop) { _core_if->hcd_cb->stop( _core_if->hcd_cb->p ); } - if (_core_if->hcd_cb && _core_if->hcd_cb->suspend) { - _core_if->hcd_cb->suspend( _core_if->hcd_cb->p, 0); - } + if(pldata->phy_suspend) + pldata->phy_suspend( pldata, USB_PHY_SUSPEND); udelay(3); -// clk_disable(otg_dev->phyclk); -// clk_disable(otg_dev->ahbclk); + pldata->clock_enable( pldata, 0); } else if(dwc_otg_hcd->host_setenable == 1) { DWC_PRINT("%s, enable host controller\n", __func__); -// clk_enable(otg_dev->phyclk); -// clk_enable(otg_dev->ahbclk); - if (_core_if->hcd_cb && _core_if->hcd_cb->suspend) { - _core_if->hcd_cb->suspend( _core_if->hcd_cb->p, 1); - } + pldata->clock_enable( pldata, 1); + if(pldata->phy_suspend) + pldata->phy_suspend( pldata, USB_PHY_ENABLED); mdelay(5); if (_core_if->hcd_cb && _core_if->hcd_cb->start) { _core_if->hcd_cb->start( _core_if->hcd_cb->p ); @@ -733,17 +732,14 @@ static void dwc_otg_hcd_connect_detect(unsigned long pdata) { dwc_otg_hcd_t *dwc_otg_hcd = (dwc_otg_hcd_t *)pdata; dwc_otg_core_if_t *core_if = dwc_otg_hcd->core_if; - unsigned int usbgrf_status = *(unsigned int*)(USBGRF_SOC_STATUS0); unsigned long flags; + struct dwc_otg_platform_data *pldata; + pldata = core_if->otg_dev->pldata; local_irq_save(flags); // DWC_PRINT("%s hprt %x, grfstatus 0x%x\n", __func__, dwc_read_reg32(core_if->host_if->hprt0), usbgrf_status& (7<<22)); -#ifdef CONFIG_ARCH_RK30 - if(usbgrf_status & (7<<22)){ -#else //CONFIG_ARCH_RK2928 - if(usbgrf_status & (7<<12)){ -#endif + if(pldata->get_status(USB_STATUS_DPDM)){ // usb device connected dwc_otg_hcd->host_setenable = 1; } @@ -754,11 +750,6 @@ static void dwc_otg_hcd_connect_detect(unsigned long pdata) } if(dwc_otg_hcd->host_setenable != dwc_otg_hcd->host_enabled){ -#ifdef CONFIG_ARCH_RK30 - DWC_PRINT("%s schedule delaywork, hprt 0x%08x, grfstatus 0x%08x\n", __func__, dwc_read_reg32(core_if->host_if->hprt0), usbgrf_status& (7<<22)); -#else //CONFIG_ARCH_RK2928 - DWC_PRINT("%s schedule delaywork, hprt 0x%08x, grfstatus 0x%08x\n", __func__, dwc_read_reg32(core_if->host_if->hprt0), usbgrf_status& (7<<12)); -#endif schedule_delayed_work(&dwc_otg_hcd->host_enable_work, 8); } // dwc_otg_hcd->connect_detect_timer.expires = jiffies + (HZ<<1); /* 1 s */ @@ -778,7 +769,7 @@ int __devinit dwc_otg_hcd_init(struct device *dev) { struct usb_hcd *hcd = NULL; dwc_otg_hcd_t *dwc_otg_hcd = NULL; - dwc_otg_device_t *otg_dev = dev->platform_data; + dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)dev->platform_data)); int num_channels; int i; @@ -959,7 +950,7 @@ int __devinit host11_hcd_init(struct device *dev) { struct usb_hcd *hcd = NULL; dwc_otg_hcd_t *dwc_otg_hcd = NULL; - dwc_otg_device_t *otg_dev = dev->platform_data; + dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)dev->platform_data)); int num_channels; int i; @@ -1179,7 +1170,7 @@ int __devinit host20_hcd_init(struct device *dev) { struct usb_hcd *hcd = NULL; dwc_otg_hcd_t *dwc_otg_hcd = NULL; - dwc_otg_device_t *otg_dev = dev->platform_data; + dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)dev->platform_data)); int num_channels; int i; @@ -1304,7 +1295,7 @@ int __devinit host20_hcd_init(struct device *dev) goto error3; } -#if defined(CONFIG_ARCH_RK30) || defined(CONFIG_ARCH_RK2928) +#ifndef CONFIG_ARCH_RK29 dwc_otg_hcd->host_setenable = 1; dwc_otg_hcd->connect_detect_timer.function = dwc_otg_hcd_connect_detect; dwc_otg_hcd->connect_detect_timer.data = (unsigned long)(dwc_otg_hcd); @@ -1335,7 +1326,7 @@ int __devinit host20_hcd_init(struct device *dev) */ void dwc_otg_hcd_remove(struct device *dev) { - dwc_otg_device_t *otg_dev = dev->platform_data; + dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)dev->platform_data)); dwc_otg_hcd_t *dwc_otg_hcd = otg_dev->hcd; struct usb_hcd *hcd = dwc_otg_hcd_to_hcd(dwc_otg_hcd); diff --git a/drivers/usb/dwc_otg/dwc_otg_pcd.c b/drivers/usb/dwc_otg/dwc_otg_pcd.c index 9faaad28acd2..8106e57a1307 100755 --- a/drivers/usb/dwc_otg/dwc_otg_pcd.c +++ b/drivers/usb/dwc_otg/dwc_otg_pcd.c @@ -61,7 +61,6 @@ * */ -#include #include #include #include @@ -74,20 +73,19 @@ #include #include #include +#include #include #include #include +#include + #include "dwc_otg_driver.h" #include "dwc_otg_pcd.h" #include "dwc_otg_regs.h" -#include -#ifdef CONFIG_ARCH_RK29 -#include -#endif -#include +#include "usbdev_rk.h" /** * Static PCD pointer for use in usb_gadget_register_driver and * usb_gadget_unregister_driver. Initialized in dwc_otg_pcd_init. @@ -190,7 +188,7 @@ void request_nuke( dwc_otg_pcd_ep_t *_ep ) * This function assigns periodic Tx FIFO to an periodic EP * in shared Tx FIFO mode */ - #if defined(CONFIG_ARCH_RK30)||defined(CONFIG_ARCH_RK2928) //@lyz +#ifndef CONFIG_ARCH_RK29 static uint32_t assign_perio_tx_fifo(dwc_otg_core_if_t *core_if) { uint32_t PerTxMsk = 1; @@ -219,7 +217,7 @@ static void release_perio_tx_fifo(dwc_otg_core_if_t *core_if, uint32_t fifo_num) * This function assigns periodic Tx FIFO to an periodic EP * in Dedicated FIFOs mode */ -#if defined(CONFIG_ARCH_RK30)||defined(CONFIG_ARCH_RK2928) //@lyz +#ifndef CONFIG_ARCH_RK29 static uint32_t assign_tx_fifo(dwc_otg_core_if_t *core_if) { uint32_t TxMsk = 1; @@ -305,7 +303,7 @@ static int dwc_otg_pcd_ep_enable(struct usb_ep *_ep, if(ep->dwc_ep.is_in) { -#if defined(CONFIG_ARCH_RK30)||defined(CONFIG_ARCH_RK2928) //@lyz +#ifndef CONFIG_ARCH_RK29 if(!pcd->otg_dev->core_if->en_multiple_tx_fifo) { ep->dwc_ep.tx_fifo_num = 0; @@ -1497,11 +1495,7 @@ void dwc_otg_pcd_reinit(dwc_otg_pcd_t *_pcd) * @yk@rk 20120329 * EP8&EP9 of rk30 are IN&OUT ep, we use ep8 as OUT EP default */ - #ifdef CONFIG_ARCH_RK30 - if(i == 8) - continue; - #endif - #ifdef CONFIG_ARCH_RK2928 //@lyz the same with rk30 + #ifndef CONFIG_ARCH_RK29 if(i == 8) continue; #endif @@ -1562,11 +1556,7 @@ void dwc_otg_pcd_reinit(dwc_otg_pcd_t *_pcd) * @yk@rk 20120329 * EP8&EP9 of rk30 are IN&OUT ep, we use ep9 as IN EP default */ - #ifdef CONFIG_ARCH_RK30 - if(i == 9) - continue; - #endif - #ifdef CONFIG_ARCH_RK2928 //@lyz the same with rk30 + #ifndef CONFIG_ARCH_RK29 if(i == 9) continue; #endif @@ -1620,79 +1610,7 @@ int dwc_pcd_reset(dwc_otg_pcd_t *pcd) return 0; } -/* - * close usb phy , about 7ma--2.5v - * 20090925,add vbus test code.500ms ¼ä¸ô. - * 20100122,HSL@RK,hard reset usb controller and phy. -*/ -int dwc_otg20phy_suspend( int exitsuspend ) -{ - dwc_otg_pcd_t *pcd = s_pcd; -#ifdef CONFIG_ARCH_RK29 - unsigned int * otg_phy_con1 = (unsigned int*)(USB_GRF_CON); - if(exitsuspend && (pcd->phy_suspend == 1)) { - clk_enable(pcd->otg_dev->ahbclk); - clk_enable(pcd->otg_dev->phyclk); - pcd->phy_suspend = 0; - *otg_phy_con1 |= (0x01<<2); - *otg_phy_con1 |= (0x01<<3); // exit suspend. - *otg_phy_con1 &= ~(0x01<<2); - - /* 20091011,reenable usb phy ,will raise reset intr */ - //debug_print("enable usb phy\n"); - DWC_DEBUGPL(DBG_PCDV, "enable usb phy\n"); - } - if( !exitsuspend && (pcd->phy_suspend == 0)) { - pcd->phy_suspend = 1; - *otg_phy_con1 |= ((0x01<<2)|(0x05<<6)); - *otg_phy_con1 &= ~(0x01<<3); // enter suspend. - udelay(3); - clk_disable(pcd->otg_dev->phyclk); - clk_disable(pcd->otg_dev->ahbclk); - //*otg_phy_con1 &= ~(0x01<<2); - //debug_print("disable usb phy\n"); - DWC_DEBUGPL(DBG_PCDV, "disable usb phy\n"); - } -#endif -#ifdef CONFIG_ARCH_RK30 - unsigned int * otg_phy_con1 = (unsigned int*)(USBGRF_UOC0_CON2); - if(exitsuspend && (pcd->phy_suspend == 1)) { - clk_enable(pcd->otg_dev->ahbclk); - clk_enable(pcd->otg_dev->phyclk); - pcd->phy_suspend = 0; - *otg_phy_con1 = ((0x01<<2)<<16); // exit suspend. - DWC_DEBUGPL(DBG_PCDV, "enable usb phy\n"); - } - if( !exitsuspend && (pcd->phy_suspend == 0)) { - pcd->phy_suspend = 1; - *otg_phy_con1 = 0x554|(0xfff<<16); // enter suspend. - udelay(3); - clk_disable(pcd->otg_dev->phyclk); - clk_disable(pcd->otg_dev->ahbclk); - DWC_DEBUGPL(DBG_PCDV, "disable usb phy\n"); - } -#endif -#ifdef CONFIG_ARCH_RK2928 - unsigned int * otg_phy_con1 = (unsigned int*)(USBGRF_UOC0_CON5); - if(exitsuspend && (pcd->phy_suspend == 1)) { - clk_enable(pcd->otg_dev->ahbclk); - clk_enable(pcd->otg_dev->phyclk); - pcd->phy_suspend = 0; - *otg_phy_con1 = (0x01<<16); // exit suspend. - DWC_DEBUGPL(DBG_PCDV, "enable usb phy\n"); - } - if( !exitsuspend && (pcd->phy_suspend == 0)) { - pcd->phy_suspend = 1; - *otg_phy_con1 = 0x1D5 |(0x1ff<<16); // enter suspend. enable dm,dp Pull-Down Resistor wlf @2012.8.10 - udelay(3); -// otg/host20 use the same phyclk, so can't disable phyclk in case host20 is used. wlf @2012.8.16 -// clk_disable(pcd->otg_dev->phyclk); - clk_disable(pcd->otg_dev->ahbclk); - DWC_DEBUGPL(DBG_PCDV, "disable usb phy\n"); - } -#endif - return pcd->phy_suspend; -} + int dwc_otg_reset( void ) { @@ -1746,109 +1664,22 @@ static void dwc_phy_reconnect(struct work_struct *work) DWC_PRINT("********soft connect!!!*****************************************\n"); } } -#ifdef CONFIG_ARCH_RK29 -static void dwc_otg_pcd_check_vbus_timer( unsigned long pdata ) -{ - dwc_otg_pcd_t * _pcd = (dwc_otg_pcd_t *)pdata; - dwc_otg_core_if_t *core_if = GET_CORE_IF(_pcd); - gotgctl_data_t gctrl; - dctl_data_t dctl = {.d32=0}; - //dsts_data_t gsts; - unsigned long flags; - local_irq_save(flags); - gctrl.d32 = dwc_read_reg32( &core_if->core_global_regs->gotgctl ); - //gsts.d32 = dwc_read_reg32( &core_if->dev_if->dev_global_regs->dsts); - - _pcd->check_vbus_timer.expires = jiffies + (HZ); /* 1 s */ - if( gctrl.b.bsesvld ) { - /* if usb not connect before ,then start connect */ - if( _pcd->vbus_status == 0 ) { - dwc_otg_msc_lock(_pcd); - DWC_PRINT("********vbus detect*********************************************\n"); - _pcd->vbus_status = 1; - /* soft disconnect */ - dctl.d32 = dwc_read_reg32( &core_if->dev_if->dev_global_regs->dctl ); - dctl.b.sftdiscon = 1; - dwc_write_reg32( &core_if->dev_if->dev_global_regs->dctl, dctl.d32 ); - /* Clear any pending interrupts */ - dwc_write_reg32( &core_if->core_global_regs->gintsts, 0xFFFFFFFF); - if(_pcd->conn_en) - { - schedule_delayed_work( &_pcd->reconnect , 8 ); /* delay 1 jiffies */ - _pcd->check_vbus_timer.expires = jiffies + (HZ<<1); /* 1 s */ - } - - } else if((_pcd->conn_status>0)&&(_pcd->conn_status <3)) { - //dwc_otg_msc_unlock(_pcd); - DWC_PRINT("********soft reconnect******************************************\n"); - //_pcd->vbus_status =0; - - /* soft disconnect */ - dctl.d32 = dwc_read_reg32( &core_if->dev_if->dev_global_regs->dctl ); - dctl.b.sftdiscon = 1; - dwc_write_reg32( &core_if->dev_if->dev_global_regs->dctl, dctl.d32 ); - /* Clear any pending interrupts */ - dwc_write_reg32( &core_if->core_global_regs->gintsts, 0xFFFFFFFF); - if(_pcd->conn_en) - { - schedule_delayed_work( &_pcd->reconnect , 8 ); /* delay 1 jiffies */ - _pcd->check_vbus_timer.expires = jiffies + (HZ<<1); /* 1 s */ - } - } - else if((_pcd->conn_en)&&(_pcd->conn_status == 0)) - { - - schedule_delayed_work( &_pcd->reconnect , 8 ); /* delay 1 jiffies */ - _pcd->check_vbus_timer.expires = jiffies + (HZ<<1); /* 1 s */ - } - else if(_pcd->conn_status ==3) - { - //*Á¬½Ó²»ÉÏʱÊÍ·ÅËø£¬ÔÊÐíϵͳ½øÈë¶þ¼¶Ë¯Ãߣ¬yk@rk,20100331*// - dwc_otg_msc_unlock(_pcd); - _pcd->conn_status++; - if((dwc_read_reg32((uint32_t*)((uint8_t *)_pcd->otg_dev->base + DWC_OTG_HOST_PORT_REGS_OFFSET))&0xc00) == 0xc00) - _pcd->vbus_status = 2; - } - } else { - //DWC_PRINT("new vbus=%d,old vbus=%d\n" , gctrl.b.bsesvld , _pcd->vbus_status ); - _pcd->vbus_status = 0; - if(_pcd->conn_status) - { - _pcd->conn_status = 0; - dwc_otg_msc_unlock(_pcd); - } - /* every 500 ms open usb phy power and start 1 jiffies timer to get vbus */ - if( _pcd->phy_suspend == 0 ) { - /* no vbus detect here , close usb phy for 500ms */ - dwc_otg20phy_suspend( 0 ); - _pcd->check_vbus_timer.expires = jiffies + (HZ/2); /* 500 ms */ - } else if( _pcd->phy_suspend == 1 ) { - dwc_otg20phy_suspend( 1 ); - /*20100325 yk@rk,delay 2-->8,for host connect id detect*/ - _pcd->check_vbus_timer.expires = jiffies + 8; /* 20091127,HSL@RK,1-->2 */ - - } - } - //DWC_PRINT("%s:restart check vbus timer\n" , __func__ ); - add_timer(&_pcd->check_vbus_timer); - local_irq_restore(flags); -} -#endif -#ifdef CONFIG_ARCH_RK30 -static void dwc_otg_pcd_check_vbus_timer( unsigned long pdata ) +static void dwc_otg_pcd_check_vbus_timer( unsigned long data ) { - dwc_otg_pcd_t * _pcd = (dwc_otg_pcd_t *)pdata; - unsigned long flags; - unsigned int usbgrf_status = *(unsigned int*)(USBGRF_SOC_STATUS0); + struct device *_dev = (struct device *)data; + struct dwc_otg_platform_data *pldata = _dev->platform_data; + dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)_dev->platform_data)); + dwc_otg_pcd_t * _pcd = otg_dev->pcd; + unsigned long flags; local_irq_save(flags); _pcd->check_vbus_timer.expires = jiffies + (HZ); /* 1 s */ - if((usbgrf_status &(1<<20)) == 0){ // id low + if(!pldata->get_status(USB_STATUS_ID)){ // id low - if( _pcd->phy_suspend) - dwc_otg20phy_suspend( 1 ); + if( pldata->phy_status) + pldata->phy_suspend(pldata, USB_PHY_ENABLED); } - else if(usbgrf_status &0x20000){ // bvalid + else if(pldata->get_status(USB_STATUS_BVABLID)){ // bvalid /* if usb not connect before ,then start connect */ if( _pcd->vbus_status == 0 ) { DWC_PRINT("********vbus detect*********************************************\n"); @@ -1857,7 +1688,7 @@ static void dwc_otg_pcd_check_vbus_timer( unsigned long pdata ) goto connect; else // not connect, suspend phy - dwc_otg20phy_suspend(0); + pldata->phy_suspend(pldata, USB_PHY_SUSPEND); } else if((_pcd->conn_en)&&(_pcd->conn_status>=0)&&(_pcd->conn_status <3)){ DWC_PRINT("********soft reconnect******************************************\n"); @@ -1871,83 +1702,18 @@ static void dwc_otg_pcd_check_vbus_timer( unsigned long pdata ) _pcd->vbus_status = 2; // not connect, suspend phy - dwc_otg20phy_suspend(0); - } - }else { - _pcd->vbus_status = 0; - if(_pcd->conn_status){ - _pcd->conn_status = 0; - dwc_otg_msc_unlock(_pcd); - } - /* every 500 ms open usb phy power and start 1 jiffies timer to get vbus */ - else if( _pcd->phy_suspend == 0 ) - /* no vbus detect here , close usb phy */ - dwc_otg20phy_suspend( 0 ); - } - add_timer(&_pcd->check_vbus_timer); - local_irq_restore(flags); - return; - -connect: - if(_pcd->conn_status==0) - dwc_otg_msc_lock(_pcd); - if( _pcd->phy_suspend == 1 ) - dwc_otg20phy_suspend( 1 ); - schedule_delayed_work( &_pcd->reconnect , 8 ); /* delay 1 jiffies */ - _pcd->check_vbus_timer.expires = jiffies + (HZ<<1); /* 1 s */ - add_timer(&_pcd->check_vbus_timer); - local_irq_restore(flags); - return; -} - -#endif -#ifdef CONFIG_ARCH_RK2928 -static void dwc_otg_pcd_check_vbus_timer( unsigned long pdata ) -{ - dwc_otg_pcd_t * _pcd = (dwc_otg_pcd_t *)pdata; - unsigned long flags; - unsigned int usbgrf_status = *(unsigned int*)(USBGRF_SOC_STATUS0);//@lyz USBGRF_SOC_STATUS0½á¹¹Óбä - - local_irq_save(flags); - _pcd->check_vbus_timer.expires = jiffies + (HZ); /* 1 s */ - if((usbgrf_status &(1<<10)) == 0){ // id low //@lyz SOC_STATUS0[10] represents id_dig - - if( _pcd->phy_suspend) - dwc_otg20phy_suspend( 1 ); - } - else if(usbgrf_status & (1<<7)){ //@lyz SOC_STATUS0[7] represents bvalid - /* if usb not connect before ,then start connect */ - if( _pcd->vbus_status == 0 ) { - DWC_PRINT("********vbus detect*********************************************\n"); - _pcd->vbus_status = 1; - if(_pcd->conn_en) - goto connect; - else - dwc_otg20phy_suspend( 0 ); - } - else if((_pcd->conn_en)&&(_pcd->conn_status>=0)&&(_pcd->conn_status <3)){ - DWC_PRINT("********soft reconnect******************************************\n"); - goto connect; - } - else if(_pcd->conn_status ==3){ - //*Á¬½Ó²»ÉÏʱÊÍ·ÅËø£¬ÔÊÐíϵͳ½øÈë¶þ¼¶Ë¯Ãߣ¬yk@rk,20100331*// - dwc_otg_msc_unlock(_pcd); - _pcd->conn_status++; - if((dwc_read_reg32((uint32_t*)((uint8_t *)_pcd->otg_dev->base + DWC_OTG_HOST_PORT_REGS_OFFSET))&0xc00) == 0xc00) - _pcd->vbus_status = 2; - dwc_otg20phy_suspend(0); + pldata->phy_suspend(pldata, USB_PHY_SUSPEND); } }else { _pcd->vbus_status = 0; if(_pcd->conn_status){ _pcd->conn_status = 0; dwc_otg_msc_unlock(_pcd); - rk28_send_wakeup_key(); } /* every 500 ms open usb phy power and start 1 jiffies timer to get vbus */ - else if( _pcd->phy_suspend == 0 ) - /* no vbus detect here , close usb phy */ - dwc_otg20phy_suspend( 0 ); + else if( pldata->phy_status == 0 ) + /* no vbus detect here , close usb phy */ + pldata->phy_suspend(pldata, USB_PHY_SUSPEND); } add_timer(&_pcd->check_vbus_timer); local_irq_restore(flags); @@ -1956,74 +1722,14 @@ static void dwc_otg_pcd_check_vbus_timer( unsigned long pdata ) connect: if(_pcd->conn_status==0) dwc_otg_msc_lock(_pcd); - if( _pcd->phy_suspend == 1 ) - dwc_otg20phy_suspend( 1 ); + pldata->phy_suspend(pldata, USB_PHY_ENABLED); schedule_delayed_work( &_pcd->reconnect , 8 ); /* delay 1 jiffies */ - _pcd->check_vbus_timer.expires = jiffies + (HZ<<1); /* 1 s */ + _pcd->check_vbus_timer.expires = jiffies + (HZ<<1); /* 1 s */ add_timer(&_pcd->check_vbus_timer); local_irq_restore(flags); return; } -#endif -#ifdef CONFIG_ARCH_RK29 -/* - * This function can be only called in charge mode. - * return value: - * -1: ioremap fail; - * 0: vbus not connected; - * 1: vbus connected, dp,dm not in both high status; - * 2: vbus connected and both dp,dm in high level.(standard USB charger) - */ -int dwc_otg_check_dpdm(void) -{ - static uint8_t * reg_base = 0; - volatile unsigned int * otg_phy_con1 = (unsigned int*)(USB_GRF_CON); - volatile unsigned int * otg_clkgate = (unsigned int*)(USB_CLKGATE_CON); - volatile unsigned int * otg_clkreset = (unsigned int*)(RK29_CRU_BASE+0x70); - volatile unsigned int * otg_dctl; - volatile unsigned int * otg_gotgctl; - volatile unsigned int * otg_hprt0; - int bus_status = 0; - - - // softreset & clockgate - *otg_clkreset |= (7<<16); - udelay(3); - *otg_clkreset &= ~(7<<16); - *otg_clkgate &= ~((1<<4)|(3<<25)); - - // exit phy suspend - *otg_phy_con1 |= (0x01<<2); - *otg_phy_con1 |= (0x01<<3); // exit suspend. - *otg_phy_con1 &= ~(0x01<<2); - - // soft connect - if(reg_base == 0){ - reg_base = ioremap(RK29_USBOTG0_PHYS,USBOTG_SIZE); - if(!reg_base){ - bus_status = -1; - goto out; - } - } - mdelay(105); - printk("regbase %p 0x%x, otg_phy_con%p, 0x%x, otg_clkgate %p,0x%x\n", - reg_base, *(reg_base), otg_phy_con1, *otg_phy_con1, otg_clkgate, *otg_clkgate); - otg_dctl = (unsigned int * )(reg_base+0x804); - otg_gotgctl = (unsigned int * )(reg_base); - otg_hprt0 = (unsigned int * )(reg_base + DWC_OTG_HOST_PORT_REGS_OFFSET); - if(*otg_gotgctl &(1<<19)){ - bus_status = 1; - *otg_dctl &= ~2; - mdelay(50); // delay about 10ms - // check dp,dm - if((*otg_hprt0 & 0xc00)==0xc00) - bus_status = 2; - } -out: - return bus_status; -} -#endif #ifdef CONFIG_ARCH_RK30 int dwc_otg_check_dpdm(void) { @@ -2162,7 +1868,7 @@ int dwc_otg_pcd_init(struct device *dev) { static char pcd_name[] = "dwc_otg_pcd"; dwc_otg_pcd_t *pcd; - dwc_otg_device_t *otg_dev = dev->platform_data; + dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)dev->platform_data)); dwc_otg_core_if_t *core_if = otg_dev->core_if; int retval = 0; int irq; @@ -2256,7 +1962,7 @@ int dwc_otg_pcd_init(struct device *dev) init_timer( &pcd->check_vbus_timer ); pcd->check_vbus_timer.function = dwc_otg_pcd_check_vbus_timer; - pcd->check_vbus_timer.data = (unsigned long)(pcd); + pcd->check_vbus_timer.data = (unsigned long)(dev); INIT_DELAYED_WORK(&pcd->reconnect , dwc_phy_reconnect); pcd->vbus_status = 0; @@ -2270,7 +1976,7 @@ int dwc_otg_pcd_init(struct device *dev) */ void dwc_otg_pcd_remove( struct device *dev ) { - dwc_otg_device_t *otg_dev = dev->platform_data; + dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)dev->platform_data)); dwc_otg_pcd_t *pcd = otg_dev->pcd; DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, dev); diff --git a/drivers/usb/dwc_otg/usbdev_rk.h b/drivers/usb/dwc_otg/usbdev_rk.h new file mode 100755 index 000000000000..fb5a774258aa --- /dev/null +++ b/drivers/usb/dwc_otg/usbdev_rk.h @@ -0,0 +1,22 @@ + +#define USB_PHY_ENABLED 0 +#define USB_PHY_SUSPEND 1 + +#define USB_STATUS_BVABLID 1 +#define USB_STATUS_DPDM 2 +#define USB_STATUS_ID 3 + +struct dwc_otg_platform_data { + void *privdata; + struct clk* phyclk; + struct clk* ahbclk; + struct clk* busclk; + int phy_status; + void (*hw_init)(void); + void (*phy_suspend)(void* pdata, int suspend); + void (*soft_reset)(void); + void (*clock_init)(void* pdata); + void (*clock_enable)(void* pdata, int enable); + void (*power_enable)(int enable); + int (*get_status)(int id); +}; \ No newline at end of file diff --git a/drivers/usb/dwc_otg/usbdev_rk30.c b/drivers/usb/dwc_otg/usbdev_rk30.c new file mode 100755 index 000000000000..78766ca76460 --- /dev/null +++ b/drivers/usb/dwc_otg/usbdev_rk30.c @@ -0,0 +1,279 @@ +#include +#include +#include +#ifdef CONFIG_ARCH_RK30 +#include +#include + +#include +#include +#include +#include + +#include "usbdev_rk.h" + +#define GRF_REG_BASE RK30_GRF_BASE +#define USBOTG_SIZE RK30_USBOTG20_SIZE +#define USBGRF_SOC_STATUS0 (GRF_REG_BASE+0x15c) +#define USBGRF_UOC0_CON2 (GRF_REG_BASE+0x184) +#define USBGRF_UOC1_CON2 (GRF_REG_BASE+0x190) +//#define USB_IOMUX_INIT(a,b) rk30_mux_api_set(a,b) + +#ifdef CONFIG_USB20_OTG +/*DWC_OTG*/ +static struct resource usb20_otg_resource[] = { + { + .start = IRQ_USB_OTG, + .end = IRQ_USB_OTG, + .flags = IORESOURCE_IRQ, + }, + { + .start = RK30_USBOTG20_PHYS, + .end = RK30_USBOTG20_PHYS + RK30_USBOTG20_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + +}; + +void usb20otg_hw_init(void) +{ +#ifndef CONFIG_USB20_HOST + // close USB 2.0 HOST phy and clock + unsigned int * otg_phy_con1 = (unsigned int*)(USBGRF_UOC1_CON2); + *otg_phy_con1 = 0x554|(0xfff<<16); // enter suspend. +#endif + // usb phy config init + + // other haredware init + rk30_mux_api_set(GPIO0A5_OTGDRVVBUS_NAME, GPIO0A_OTG_DRV_VBUS); +} +void usb20otg_phy_suspend(void* pdata, int suspend) +{ + struct dwc_otg_platform_data *usbpdata=pdata; + unsigned int * otg_phy_con1 = (unsigned int*)(USBGRF_UOC0_CON2); + if(suspend){ + *otg_phy_con1 = 0x554|(0xfff<<16); // enter suspend. + usbpdata->phy_status = 1; + } + else{ + *otg_phy_con1 = ((0x01<<2)<<16); // exit suspend. + usbpdata->phy_status = 0; + } +} +void usb20otg_soft_reset(void) +{ +#if 1 + cru_set_soft_reset(SOFT_RST_USBOTG0, true); + cru_set_soft_reset(SOFT_RST_USBPHY0, true); + cru_set_soft_reset(SOFT_RST_OTGC0, true); + udelay(1); + + cru_set_soft_reset(SOFT_RST_USBOTG0, false); + cru_set_soft_reset(SOFT_RST_USBPHY0, false); + cru_set_soft_reset(SOFT_RST_OTGC0, false); + mdelay(1); +#endif +} +void usb20otg_clock_init(void* pdata) +{ + struct dwc_otg_platform_data *usbpdata=pdata; + struct clk* ahbclk,*phyclk; + ahbclk = clk_get(NULL, "hclk_otg0"); + phyclk = clk_get(NULL, "otgphy0"); + usbpdata->phyclk = phyclk; + usbpdata->ahbclk = ahbclk; +} +void usb20otg_clock_enable(void* pdata, int enable) +{ + struct dwc_otg_platform_data *usbpdata=pdata; + #if 1 + if(enable){ + clk_enable(usbpdata->ahbclk); + clk_enable(usbpdata->phyclk); + } + else{ + clk_disable(usbpdata->phyclk); + clk_disable(usbpdata->ahbclk); + } + #endif +} +int usb20otg_get_status(int id) +{ + int ret = -1; + unsigned int usbgrf_status = *(unsigned int*)(USBGRF_SOC_STATUS0); + switch(id) + { + case 0x01: + // bvalid in grf + ret = (usbgrf_status &0x20000); + break; + case 0x02: + // dpdm in grf + ret = (usbgrf_status &(3<<18)); + break; + case 0x03: + // id in grf + ret = (usbgrf_status &(1<<20)); + break; + default: + break; + } + return ret; +} +void usb20otg_power_enable(int enable) +{ +} +struct dwc_otg_platform_data usb20otg_pdata = { + .phyclk = NULL, + .ahbclk = NULL, + .busclk = NULL, + .phy_status = 0, + .hw_init=usb20otg_hw_init, + .phy_suspend=usb20otg_phy_suspend, + .soft_reset=usb20otg_soft_reset, + .clock_init=usb20otg_clock_init, + .clock_enable=usb20otg_clock_enable, + .get_status=usb20otg_get_status, +}; + +struct platform_device device_usb20_otg = { + .name = "usb20_otg", + .id = -1, + .num_resources = ARRAY_SIZE(usb20_otg_resource), + .resource = usb20_otg_resource, + .dev = { + .platform_data = &usb20otg_pdata, + }, +}; +#endif +#ifdef CONFIG_USB20_HOST +static struct resource usb20_host_resource[] = { + { + .start = IRQ_USB_HOST, + .end = IRQ_USB_HOST, + .flags = IORESOURCE_IRQ, + }, + { + .start = RK30_USBHOST20_PHYS, + .end = RK30_USBHOST20_PHYS + RK30_USBHOST20_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + +}; +void usb20host_hw_init(void) +{ + // usb phy config init + + // other haredware init + rk30_mux_api_set(GPIO0A6_HOSTDRVVBUS_NAME, GPIO0A_HOST_DRV_VBUS); +} +void usb20host_phy_suspend(void* pdata, int suspend) +{ + struct dwc_otg_platform_data *usbpdata=pdata; + unsigned int * otg_phy_con1 = (unsigned int*)(USBGRF_UOC1_CON2); + if(suspend){ + *otg_phy_con1 = 0x554|(0xfff<<16); // enter suspend. + usbpdata->phy_status = 0; + } + else{ + *otg_phy_con1 = ((0x01<<2)<<16); // exit suspend. + usbpdata->phy_status = 1; + } +} +void usb20host_soft_reset(void) +{ +#if 1 + cru_set_soft_reset(SOFT_RST_USBOTG1, true); + cru_set_soft_reset(SOFT_RST_USBPHY1, true); + cru_set_soft_reset(SOFT_RST_OTGC1, true); + udelay(1); + + cru_set_soft_reset(SOFT_RST_USBOTG1, false); + cru_set_soft_reset(SOFT_RST_USBPHY1, false); + cru_set_soft_reset(SOFT_RST_OTGC1, false); + mdelay(1); +#endif +} +void usb20host_clock_init(void* pdata) +{ + struct dwc_otg_platform_data *usbpdata=pdata; + struct clk* ahbclk,*phyclk; + ahbclk = clk_get(NULL, "hclk_otg1"); + phyclk = clk_get(NULL, "otgphy1"); + usbpdata->phyclk = phyclk; + usbpdata->ahbclk = ahbclk; +} +void usb20host_clock_enable(void* pdata, int enable) +{ + struct dwc_otg_platform_data *usbpdata=pdata; + #if 1 + if(enable){ + clk_enable(usbpdata->ahbclk); + clk_enable(usbpdata->phyclk); + } + else{ + clk_disable(usbpdata->phyclk); + clk_disable(usbpdata->ahbclk); + } + #endif +} +int usb20host_get_status(int id) +{ + int ret = -1; + unsigned int usbgrf_status = *(unsigned int*)(USBGRF_SOC_STATUS0); + switch(id) + { + case USB_STATUS_BVABLID: + // bvalid in grf + ret = (usbgrf_status &(1<<22)); + break; + case USB_STATUS_DPDM: + // dpdm in grf + ret = (usbgrf_status &(3<<23)); + break; + case USB_STATUS_ID: + // id in grf + ret = 0; + break; + default: + break; + } + return ret; +} +void usb20host_power_enable(int enable) +{ +} +struct dwc_otg_platform_data usb20host_pdata = { + .phyclk = NULL, + .ahbclk = NULL, + .busclk = NULL, + .phy_status = 0, + .hw_init=usb20host_hw_init, + .phy_suspend=usb20host_phy_suspend, + .soft_reset=usb20host_soft_reset, + .clock_init=usb20host_clock_init, + .clock_enable=usb20host_clock_enable, + .get_status=usb20host_get_status, +}; + +struct platform_device device_usb20_host = { + .name = "usb20_host", + .id = -1, + .num_resources = ARRAY_SIZE(usb20_host_resource), + .resource = usb20_host_resource, + .dev = { + .platform_data = &usb20host_pdata, + }, +}; +#endif +static int __init usbdev_init_devices(void) +{ +#ifdef CONFIG_USB20_OTG + platform_device_register(&device_usb20_otg); +#endif +#ifdef CONFIG_USB20_HOST + platform_device_register(&device_usb20_host); +#endif +} +arch_initcall(usbdev_init_devices); +#endif \ No newline at end of file -- 2.34.1