From f52caf4b4eb7b3e995f05e526b44f2a38a19fe46 Mon Sep 17 00:00:00 2001 From: yangkai Date: Fri, 17 Dec 2010 11:12:42 +0800 Subject: [PATCH] usb2.0 host & usb1.1 host support --- arch/arm/mach-rk29/board-rk29sdk.c | 17 +- arch/arm/mach-rk29/devices.c | 74 +- arch/arm/mach-rk29/devices.h | 4 +- drivers/usb/core/hub.c | 30 - drivers/usb/dwc_otg/Kconfig | 82 +-- drivers/usb/dwc_otg/Makefile | 17 +- drivers/usb/dwc_otg/dwc_otg_attr.c | 10 +- drivers/usb/dwc_otg/dwc_otg_cil.c | 126 ++-- drivers/usb/dwc_otg/dwc_otg_cil_intr.c | 112 +-- drivers/usb/dwc_otg/dwc_otg_driver.c | 858 ++++++++++++----------- drivers/usb/dwc_otg/dwc_otg_hcd.c | 300 ++++++-- drivers/usb/dwc_otg/dwc_otg_hcd_intr.c | 50 +- drivers/usb/dwc_otg/dwc_otg_hcd_queue.c | 9 +- drivers/usb/dwc_otg/dwc_otg_pcd.c | 66 +- drivers/usb/dwc_otg/dwc_otg_pcd.h | 5 +- drivers/usb/dwc_otg/dwc_otg_pcd_intr.c | 4 +- drivers/usb/dwc_otg/linux/dwc_otg_plat.h | 14 +- drivers/usb/gadget/f_mass_storage.c | 69 +- drivers/usb/storage/usb.c | 2 +- 19 files changed, 1007 insertions(+), 842 deletions(-) mode change 100644 => 100755 arch/arm/mach-rk29/board-rk29sdk.c mode change 100644 => 100755 arch/arm/mach-rk29/devices.c mode change 100644 => 100755 drivers/usb/core/hub.c mode change 100644 => 100755 drivers/usb/gadget/f_mass_storage.c mode change 100644 => 100755 drivers/usb/storage/usb.c diff --git a/arch/arm/mach-rk29/board-rk29sdk.c b/arch/arm/mach-rk29/board-rk29sdk.c old mode 100644 new mode 100755 index c9d178610e59..486e9c028d3a --- a/arch/arm/mach-rk29/board-rk29sdk.c +++ b/arch/arm/mach-rk29/board-rk29sdk.c @@ -1034,13 +1034,6 @@ static struct platform_device rk29_device_keys = { }, }; #endif -/********************usb*********************/ -struct usb_mass_storage_platform_data mass_storage_pdata = { - .nluns = 1, - .vendor = "RockChip", - .product = "rk9 sdk", - .release = 0x0100, -}; static void __init rk29_board_iomux_init(void) { @@ -1173,8 +1166,14 @@ static struct platform_device *devices[] __initdata = { #endif &android_pmem_device, &rk29_vpu_mem_device, -#ifdef CONFIG_DWC_OTG - &rk29_device_dwc_otg, +#ifdef CONFIG_USB20_OTG + &rk29_device_usb20_otg, +#endif +#ifdef CONFIG_USB20_HOST + &rk29_device_usb20_host, +#endif +#ifdef CONFIG_USB11_HOST + &rk29_device_usb11_host, #endif #ifdef CONFIG_USB_ANDROID &android_usb_device, diff --git a/arch/arm/mach-rk29/devices.c b/arch/arm/mach-rk29/devices.c old mode 100644 new mode 100755 index f9a7778c22cd..b66ea3a37279 --- a/arch/arm/mach-rk29/devices.c +++ b/arch/arm/mach-rk29/devices.c @@ -533,9 +533,9 @@ struct platform_device rk29_device_ipp = { }; #endif -#ifdef CONFIG_DWC_OTG +#ifdef CONFIG_USB20_OTG /*DWC_OTG*/ -static struct resource dwc_otg_resource[] = { +static struct resource usb20_otg_resource[] = { { .start = IRQ_USB_OTG0, .end = IRQ_USB_OTG0, @@ -549,12 +549,14 @@ static struct resource dwc_otg_resource[] = { }; -struct platform_device rk29_device_dwc_otg = { - .name = "dwc_otg", +struct platform_device rk29_device_usb20_otg = { + .name = "usb20_otg", .id = -1, - .num_resources = ARRAY_SIZE(dwc_otg_resource), - .resource = dwc_otg_resource, + .num_resources = ARRAY_SIZE(usb20_otg_resource), + .resource = usb20_otg_resource, }; +#endif +#ifdef CONFIG_USB_ANDROID static char *usb_functions_rockchip[] = { "usb_mass_storage", @@ -607,7 +609,7 @@ static struct android_usb_product usb_products[] = { .functions = usb_functions_rockchip, }, { - .product_id = 0x4e12, + .product_id = 0x2810,//0x0c02,//0x4e12, .num_functions = ARRAY_SIZE(usb_functions_rockchip_adb), .functions = usb_functions_rockchip_adb, }, @@ -629,7 +631,10 @@ static struct android_usb_product usb_products[] = { }, #endif }; - +/* + * if anyone want to use adb driver of HTC G1, + * please change vendor_id to 0x0bb4 and product_id to 0x0c02. + */ static struct android_usb_platform_data android_usb_pdata = { .vendor_id = 0x2207,//0x0bb4,//0x18d1, .product_id = 0x2810,//0x4e11, @@ -651,6 +656,14 @@ struct platform_device android_usb_device = { }, }; +/********************usb*********************/ +struct usb_mass_storage_platform_data mass_storage_pdata = { + .nluns = 1, + .vendor = "RockChip", + .product = "rk29 sdk", + .release = 0x0100, +}; + //static struct platform_device usb_mass_storage_device = { .name = "usb_mass_storage", @@ -660,3 +673,48 @@ struct platform_device usb_mass_storage_device = { }, }; #endif +#ifdef CONFIG_USB11_HOST +static struct resource usb11_host_resource[] = { + { + .start = IRQ_USB_HOST, + .end = IRQ_USB_HOST, + .flags = IORESOURCE_IRQ, + }, + { + .start = RK29_USBHOST_PHYS, + .end = RK29_USBHOST_PHYS + RK29_USBHOST_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + +}; + +struct platform_device rk29_device_usb11_host = { + .name = "usb11_host", + .id = -1, + .num_resources = ARRAY_SIZE(usb11_host_resource), + .resource = usb11_host_resource, +}; +#endif +#ifdef CONFIG_USB20_HOST +static struct resource usb20_host_resource[] = { + { + .start = IRQ_USB_OTG1, + .end = IRQ_USB_OTG1, + .flags = IORESOURCE_IRQ, + }, + { + .start = RK29_USBOTG1_PHYS, + .end = RK29_USBOTG1_PHYS + RK29_USBOTG1_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + +}; + +struct platform_device rk29_device_usb20_host = { + .name = "usb20_host", + .id = -1, + .num_resources = ARRAY_SIZE(usb20_host_resource), + .resource = usb20_host_resource, +}; +#endif + diff --git a/arch/arm/mach-rk29/devices.h b/arch/arm/mach-rk29/devices.h index ed885aa0ce89..b80198fa8325 100755 --- a/arch/arm/mach-rk29/devices.h +++ b/arch/arm/mach-rk29/devices.h @@ -50,7 +50,9 @@ extern struct platform_device rk29_device_adc; extern struct platform_device rk29_device_vmac; extern struct rk29_bl_info rk29_bl_info; extern struct platform_device rk29_device_backlight; -extern struct platform_device rk29_device_dwc_otg; +extern struct platform_device rk29_device_usb20_otg; +extern struct platform_device rk29_device_usb20_host; +extern struct platform_device rk29_device_usb11_host; extern struct platform_device android_usb_device; extern struct usb_mass_storage_platform_data mass_storage_pdata; extern struct platform_device usb_mass_storage_device; diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c old mode 100644 new mode 100755 index 49ec81d5984f..9478cf70509b --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -38,9 +38,6 @@ #endif #endif -// cmy@091222: ¼Ç¼Host¶Ë¿ÚËùÁ¬½ÓµÄÉ豸 -static struct usb_device *g_usb_device = 0; - struct usb_hub { struct device *intfdev; /* the "interface" device */ struct usb_device *hdev; @@ -1171,8 +1168,6 @@ static void hub_disconnect(struct usb_interface *intf) kref_put(&hub->kref, hub_release); } -struct usb_hub *g_root_hub20 = NULL; -struct usb_hub *g_root_hub11 = NULL; static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_host_interface *desc; @@ -1223,13 +1218,6 @@ descriptor_error: dev_dbg (&intf->dev, "couldn't kmalloc hub struct\n"); return -ENOMEM; } - if(hdev->parent == NULL) - { - if(!g_root_hub20) - g_root_hub20 = hub; - else if(!g_root_hub11) - g_root_hub11 = hub; - } kref_init(&hub->kref); INIT_LIST_HEAD(&hub->event_list); hub->intfdev = &intf->dev; @@ -1598,16 +1586,6 @@ void usb_disconnect(struct usb_device **pdev) usb_stop_pm(udev); - // cmy: ²»´¦ÀíhubÉ豸 - if(USB_CLASS_HUB != udev->descriptor.bDeviceClass) - { - if(udev == g_usb_device) - g_usb_device = 0; - -#ifdef CONFIG_ANDROID_POWER - android_unlock_suspend(&hub_suspend_lock); -#endif - } hub_free_dev(udev); @@ -1812,14 +1790,6 @@ int usb_new_device(struct usb_device *udev) dev_err(&udev->dev, "can't device_add, error %d\n", err); goto fail; } - // cmy: ÔÚÆô¶¯Ê±×Ô¶¯»áÌí¼Ólm0µÄhubÉ豸£¬²»Ðè¼Ç¼£¬²»ÐèÉÏËø - if(USB_CLASS_HUB != udev->descriptor.bDeviceClass) - { - g_usb_device = udev; -#ifdef CONFIG_ANDROID_POWER - android_lock_suspend(&hub_suspend_lock); -#endif - } (void) usb_create_ep_devs(&udev->dev, &udev->ep0, udev); return err; diff --git a/drivers/usb/dwc_otg/Kconfig b/drivers/usb/dwc_otg/Kconfig index 6f70c019c3da..480ae0545356 100755 --- a/drivers/usb/dwc_otg/Kconfig +++ b/drivers/usb/dwc_otg/Kconfig @@ -1,55 +1,57 @@ -config RK2818_HOST11 - tristate "RockChip USB Host 1.1 support" +config USB11_HOST + tristate "RockChip USB 1.1 host controller" ---help--- - This driver supports Rockchip USB HOST 1.1 - controller in RK281X. + This driver supports Rockchip USB 1.1 HOST + controller. -config DWC_OTG - tristate "RockChip USB OTG 2.0 support" - ---help--- - This driver supports Rockchip DWC_OTG - -config DWC_OTG_DEBUG - bool "enable debug mode" - depends on DWC_OTG +config USB20_HOST + tristate "Rockchip USB 2.0 host controller" + ---help--- + This driver supports Rockchip USB2.0 host + controller. +config USB20_OTG + tristate "RockChip USB 2.0 OTG controller" + ---help--- + This driver supports Rockchip USB2.0 DWC_OTG + controller. choice - tristate "DWC_OTG OPMODE" - default DWC_OTG_BOTH_HOST_SLAVE - depends on DWC_OTG + bool "USB2.0 OTG controller mode" + depends on USB20_OTG + default DWC_OTG_DEVICE_ONLY help RockChip DWC_OTG Controller can only work - one of following mode + in one of following mode config DWC_OTG_HOST_ONLY - bool "HOST ONLY MODE" - depends on DWC_OTG && USB + boolean "HOST ONLY MODE" + depends on USB20_OTG && USB + help + USB2.0 OTG controller worked in host mode + and device can support other gadgets. config DWC_OTG_DEVICE_ONLY - bool "DEVICE ONLY MODE" - depends on DWC_OTG && USB_GADGET + boolean "DEVICE ONLY MODE" + depends on USB20_OTG && USB_GADGET + help + USB2.0 OTG controller worked in device mode + and device can connect to PC via USB cable. -config DWC_OTG_BOTH_HOST_SLAVE - bool "BOTH HOST AND SLAVE" - depends on DWC_OTG && USB_GADGET && USB endchoice -choice - bool "USB controller mode" - depends on DWC_OTG - default DWC_OTG_NORMAL_PREFRENCE - help - Rockchip dwc_otg controller - -config DWC_OTG_NORMAL_PREFERENCE - bool "NORMAL MODE" - depends on DWC_OTG_BOTH_HOST_SLAVE -config DWC_OTG_HOST_PREFERENCE - bool "HOST PREFERENCE MODE" - depends on DWC_OTG_HOST_ONLY || DWC_OTG_BOTH_HOST_SLAVE +config DWC_CONN_EN + bool "connect to PC when vbus detect" + default y + depends on DWC_OTG_DEVICE_ONLY + help + USB2.0 OTG controller always polling the USB vbus + + if selected, device will connect to PC automatic -config DWC_OTG_DEVICE_PREFERENCE - bool "DEVICE PREFERENCE MODE" - depends on DWC_OTG_DEVICE_ONLY || DWC_OTG_BOTH_HOST_SLAVE +config DWC_OTG_DEBUG + bool "DWC_OTG debug messages" + depends on USB11_HOST || USB20_HOST || USB20_OTG -endchoice +config DWC_OTG + tristate + default y if USB11_HOST || USB20_HOST || USB20_OTG diff --git a/drivers/usb/dwc_otg/Makefile b/drivers/usb/dwc_otg/Makefile index d119d99ad02d..0801026dea2d 100755 --- a/drivers/usb/dwc_otg/Makefile +++ b/drivers/usb/dwc_otg/Makefile @@ -9,17 +9,14 @@ endif # Use one of the following flags to compile the software in host-only or # device-only mode. -ifeq ($(CONFIG_DWC_OTG_HOST_ONLY),y) -EXTRA_CFLAGS += -DDWC_HOST_ONLY -endif +#ifeq ($(CONFIG_DWC_OTG_HOST_ONLY),y) +#EXTRA_CFLAGS += -DDWC_HOST_ONLY +#endif -ifeq ($(CONFIG_DWC_OTG_DEVICE_ONLY),y) -EXTRA_CFLAGS += -DDWC_DEVICE_ONLY -endif +#ifeq ($(CONFIG_DWC_OTG_DEVICE_ONLY),y) +#EXTRA_CFLAGS += -DDWC_DEVICE_ONLY +#endif -ifeq ($(CONFIG_DWC_OTG_BOTH_HOST_SLAVE),y) -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 @@ -27,4 +24,4 @@ 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 -obj-$(CONFIG_DWC_OTG) := dwc_otg.o gadget_supplement.o +obj-$(CONFIG_DWC_OTG) := dwc_otg.o diff --git a/drivers/usb/dwc_otg/dwc_otg_attr.c b/drivers/usb/dwc_otg/dwc_otg_attr.c index c710d037eb7e..9fb2024a5888 100755 --- a/drivers/usb/dwc_otg/dwc_otg_attr.c +++ b/drivers/usb/dwc_otg/dwc_otg_attr.c @@ -696,7 +696,7 @@ static ssize_t rd_reg_test_show( struct device *_dev, int start_jiffies; dwc_otg_device_t *otg_dev = _dev->platform_data; - printk("HZ %d, MSEC_PER_JIFFIE %d, loops_per_jiffy %lu\n", + DWC_PRINT("HZ %d, MSEC_PER_JIFFIE %d, loops_per_jiffy %lu\n", HZ, MSEC_PER_JIFFIE, loops_per_jiffy); start_jiffies = jiffies; for (i = 0; i < RW_REG_COUNT; i++) { @@ -722,7 +722,7 @@ static ssize_t wr_reg_test_show( struct device *_dev, dwc_otg_device_t *otg_dev = _dev->platform_data; uint32_t reg_val; - printk("HZ %d, MSEC_PER_JIFFIE %d, loops_per_jiffy %lu\n", + DWC_PRINT("HZ %d, MSEC_PER_JIFFIE %d, loops_per_jiffy %lu\n", HZ, MSEC_PER_JIFFIE, loops_per_jiffy); reg_val = dwc_read_reg32(&otg_dev->core_if->core_global_regs->gnptxfsiz); start_jiffies = jiffies; @@ -757,7 +757,7 @@ static ssize_t debug_store( struct device *_dev, return count; } -DEVICE_ATTR(step, S_IRUGO|S_IWUSR, debug_show, debug_store); +DEVICE_ATTR(debug, S_IRUGO|S_IWUSR, debug_show, debug_store); /**@}*/ /** @@ -794,7 +794,7 @@ void dwc_otg_attr_create (struct device *dev) error |= device_create_file(dev, &dev_attr_hcd_frrem); error |= device_create_file(dev, &dev_attr_rd_reg_test); error |= device_create_file(dev, &dev_attr_wr_reg_test); - error |= device_create_file(dev, &dev_attr_step); + error |= device_create_file(dev, &dev_attr_debug); if (error) pr_err("DWC_OTG: Creating some device files failed\n"); } @@ -832,5 +832,5 @@ void dwc_otg_attr_remove (struct device *dev) device_remove_file(dev, &dev_attr_hcd_frrem); device_remove_file(dev, &dev_attr_rd_reg_test); device_remove_file(dev, &dev_attr_wr_reg_test); - device_remove_file(dev, &dev_attr_step); + device_remove_file(dev, &dev_attr_debug); } diff --git a/drivers/usb/dwc_otg/dwc_otg_cil.c b/drivers/usb/dwc_otg/dwc_otg_cil.c index 089e1ae5687d..a5f2c07dda45 100755 --- a/drivers/usb/dwc_otg/dwc_otg_cil.c +++ b/drivers/usb/dwc_otg/dwc_otg_cil.c @@ -210,7 +210,7 @@ dwc_otg_core_if_t *dwc_otg_cil_init(const uint32_t *_reg_base_addr, core_if->srp_timer_started = 0; core_if->usb_wakeup = 0; - if(dwc_core_if == NULL) +// if(dwc_core_if == NULL) dwc_core_if = core_if; return core_if; } @@ -243,7 +243,7 @@ void dwc_otg_cil_remove( dwc_otg_core_if_t *_core_if ) * * @param[in] _core_if Programming view of DWC_otg controller. */ -extern void dwc_otg_enable_global_interrupts( dwc_otg_core_if_t *_core_if ) +void dwc_otg_enable_global_interrupts( dwc_otg_core_if_t *_core_if ) { gahbcfg_data_t ahbcfg = { .d32 = 0}; ahbcfg.b.glblintrmsk = 1; /* Enable interrupts */ @@ -442,9 +442,7 @@ void dwc_otg_core_init(dwc_otg_core_if_t *_core_if) /* Common Initialization */ usbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg); - //printk("%s:::::::::::::gusbcfg is %x\n",__func__,usbcfg.d32); regvalue = dwc_read_reg32(&global_regs->gintsts); - //printk("%s:::::::::::::gusbcfg is %x\n",__func__,regvalue); /* Program the ULPI External VBUS bit if needed */ usbcfg.b.ulpi_ext_vbus_drv = (_core_if->core_params->phy_ulpi_ext_vbus == DWC_PHY_ULPI_EXTERNAL_VBUS) ? 1 : 0; @@ -485,8 +483,6 @@ void dwc_otg_core_init(dwc_otg_core_if_t *_core_if) _core_if->nperio_tx_fifo_size = dwc_read_reg32( &global_regs->gnptxfsiz) >> 16; - //printk( "%s::Total FIFO SZ=%d, Rx FIFO SZ=%d,NP Tx FIFO SZ=%d\n",__func__, _core_if->total_fifo_size, - // _core_if->rx_fifo_size, _core_if->nperio_tx_fifo_size); DWC_DEBUGPL(DBG_CIL, "Total FIFO SZ=%d\n", _core_if->total_fifo_size); DWC_DEBUGPL(DBG_CIL, "Rx FIFO SZ=%d\n", _core_if->rx_fifo_size); DWC_DEBUGPL(DBG_CIL, "NP Tx FIFO SZ=%d\n", _core_if->nperio_tx_fifo_size); @@ -1050,16 +1046,6 @@ void dwc_otg_hc_init(dwc_otg_core_if_t *_core_if, dwc_hc_t *_hc) } } } -#if 1 - //yk@rk 20100714 - if((_core_if->core_params->host_channels <= 2)&& - _hc->ep_is_in && - _hc->ep_type == DWC_OTG_EP_TYPE_BULK) - { - //DWC_PRINT("%s bulk in\n",__func__); - hc_intr_mask.b.nak = 1; - } -#endif } else { @@ -1236,7 +1222,11 @@ void dwc_otg_hc_halt(dwc_otg_core_if_t *_core_if, dwc_otg_hc_regs_t *hc_regs; dwc_otg_core_global_regs_t *global_regs; dwc_otg_host_global_regs_t *host_global_regs; - + if((!_core_if)||(!_hc)) + { + DWC_PRINT("%s parm error _core_if:0x%x, _hc:0x%x\n",__func__,(uint32_t)_core_if,(uint32_t)_hc); + return; + } hc_regs = _core_if->host_if->hc_regs[_hc->hc_num]; global_regs = _core_if->core_global_regs; host_global_regs = _core_if->host_if->host_global_regs; @@ -2999,22 +2989,6 @@ extern void dwc_otg_cil_register_pcd_callbacks( dwc_otg_core_if_t *_core_if, _cb->p = _p; } -void rk28_usb_force_disconnect( dwc_otg_core_if_t *core_if ) -{ - gotgctl_data_t gctrl; - dctl_data_t dctl = {.d32=0}; - - gctrl.d32 = dwc_read_reg32( &core_if->core_global_regs->gotgctl ); - if( !gctrl.b.bsesvld ) - return ; - - printk("%s\n" , __func__); - /* 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 ); -} - /** * This functions reads the device registers and prints them * @@ -3279,40 +3253,87 @@ void dwc_otg_dump_global_registers(dwc_otg_core_if_t *_core_if) void dump_scu_regs(void) { int regvalue; - printk("_______________________System Regs________________________________\n"); + DWC_PRINT("_______________________System Regs________________________________\n"); regvalue = dwc_read_reg32((uint32_t *)(SCU_BASE_ADDR_VA+0x00)); - printk("SCU_APLL_CON: 0x%08x\n",regvalue); + DWC_PRINT("CRU_APLL_CON: 0x%08x\n",regvalue); regvalue = dwc_read_reg32((uint32_t *)(SCU_BASE_ADDR_VA+0x04)); - printk("SCU_DPLL_CON: 0x%08x\n",regvalue); + DWC_PRINT("CRU_DPLL_CON: 0x%08x\n",regvalue); regvalue = dwc_read_reg32((uint32_t *)(SCU_BASE_ADDR_VA+0x08)); - printk("SCU_CPLL_CON: 0x%08x\n",regvalue); + DWC_PRINT("CRU_CPLL_CON: 0x%08x\n",regvalue); regvalue = dwc_read_reg32((uint32_t *)(SCU_BASE_ADDR_VA+0x0c)); - printk("SCU_MODE_CON: 0x%08x\n",regvalue); + DWC_PRINT("CRU_PPLL_CON: 0x%08x\n",regvalue); regvalue = dwc_read_reg32((uint32_t *)(SCU_BASE_ADDR_VA+0x10)); - printk("SCU_PMU_MODE: 0x%08x\n",regvalue); + DWC_PRINT("CRU_MODE_CON: 0x%08x\n",regvalue); + + /////////////////////////////////////////////////////////////// regvalue = dwc_read_reg32((uint32_t *)(SCU_BASE_ADDR_VA+0x14)); - printk("SCU_CLKSEL0_CON: 0x%08x\n",regvalue); + DWC_PRINT("CRU_CLKSEL0_CON: 0x%08x\n",regvalue); regvalue = dwc_read_reg32((uint32_t *)(SCU_BASE_ADDR_VA+0x18)); - printk("SCU_CLKSEL1_CON: 0x%08x\n",regvalue); - regvalue = dwc_read_reg32((uint32_t *)(SCU_BASE_ADDR_VA+0x1c)); - printk("SCU_CLKGATE0_CON: 0x%08x\n",regvalue); + DWC_PRINT("CRU_CLKSEL1_CON: 0x%08x\n",regvalue); + regvalue = dwc_read_reg32((uint32_t *)(SCU_BASE_ADDR_VA+0x1C)); + DWC_PRINT("CRU_CLKSEL2_CON: 0x%08x\n",regvalue); regvalue = dwc_read_reg32((uint32_t *)(SCU_BASE_ADDR_VA+0x20)); - printk("SCU_CLKGATE1_CON: 0x%08x\n",regvalue); + DWC_PRINT("CRU_CLKSEL3_CON: 0x%08x\n",regvalue); regvalue = dwc_read_reg32((uint32_t *)(SCU_BASE_ADDR_VA+0x24)); - printk("SCU_CLKGATE2_CON: 0x%08x\n",regvalue); + DWC_PRINT("CRU_CLKSEL4_CON: 0x%08x\n",regvalue); regvalue = dwc_read_reg32((uint32_t *)(SCU_BASE_ADDR_VA+0x28)); - printk("SCU_SOFTRST_CON: 0x%08x\n",regvalue); + DWC_PRINT("CRU_CLKSEL5_CON: 0x%08x\n",regvalue); + regvalue = dwc_read_reg32((uint32_t *)(SCU_BASE_ADDR_VA+0x2C)); + DWC_PRINT("CRU_CLKSEL6_CON: 0x%08x\n",regvalue); + regvalue = dwc_read_reg32((uint32_t *)(SCU_BASE_ADDR_VA+0x30)); + DWC_PRINT("CRU_CLKSEL7_CON: 0x%08x\n",regvalue); + regvalue = dwc_read_reg32((uint32_t *)(SCU_BASE_ADDR_VA+0x34)); + DWC_PRINT("CRU_CLKSEL8_CON: 0x%08x\n",regvalue); + regvalue = dwc_read_reg32((uint32_t *)(SCU_BASE_ADDR_VA+0x38)); + DWC_PRINT("CRU_CLKSEL9_CON: 0x%08x\n",regvalue); + regvalue = dwc_read_reg32((uint32_t *)(SCU_BASE_ADDR_VA+0x3C)); + DWC_PRINT("CRU_CLKSEL10_CON: 0x%08x\n",regvalue); + regvalue = dwc_read_reg32((uint32_t *)(SCU_BASE_ADDR_VA+0x40)); + DWC_PRINT("CRU_CLKSEL11_CON: 0x%08x\n",regvalue); + regvalue = dwc_read_reg32((uint32_t *)(SCU_BASE_ADDR_VA+0x44)); + DWC_PRINT("CRU_CLKSEL12_CON: 0x%08x\n",regvalue); + regvalue = dwc_read_reg32((uint32_t *)(SCU_BASE_ADDR_VA+0x48)); + DWC_PRINT("CRU_CLKSEL12_CON: 0x%08x\n",regvalue); + regvalue = dwc_read_reg32((uint32_t *)(SCU_BASE_ADDR_VA+0x4C)); + DWC_PRINT("CRU_CLKSEL14_CON: 0x%08x\n",regvalue); + regvalue = dwc_read_reg32((uint32_t *)(SCU_BASE_ADDR_VA+0x50)); + DWC_PRINT("CRU_CLKSEL15_CON: 0x%08x\n",regvalue); + regvalue = dwc_read_reg32((uint32_t *)(SCU_BASE_ADDR_VA+0x54)); + DWC_PRINT("CRU_CLKSEL16_CON: 0x%08x\n",regvalue); + regvalue = dwc_read_reg32((uint32_t *)(SCU_BASE_ADDR_VA+0x58)); + DWC_PRINT("CRU_CLKSEL17_CON: 0x%08x\n",regvalue); + + /////////////////////////////////////////////////////////////// + regvalue = dwc_read_reg32((uint32_t *)(SCU_BASE_ADDR_VA+0x5c)); + DWC_PRINT("CRU_CLKGATE0_CON: 0x%08x\n",regvalue); + regvalue = dwc_read_reg32((uint32_t *)(SCU_BASE_ADDR_VA+0x60)); + DWC_PRINT("CRU_CLKGATE1_CON: 0x%08x\n",regvalue); + regvalue = dwc_read_reg32((uint32_t *)(SCU_BASE_ADDR_VA+0x64)); + DWC_PRINT("CRU_CLKGATE2_CON: 0x%08x\n",regvalue); + regvalue = dwc_read_reg32((uint32_t *)(SCU_BASE_ADDR_VA+0x68)); + DWC_PRINT("CRU_CLKGATE3_CON: 0x%08x\n",regvalue); + + /////////////////////////////////////////////////////////////// + regvalue = dwc_read_reg32((uint32_t *)(SCU_BASE_ADDR_VA+0x6C)); + DWC_PRINT("CRU_SOFTRST0_CON: 0x%08x\n",regvalue); + regvalue = dwc_read_reg32((uint32_t *)(SCU_BASE_ADDR_VA+0x70)); + DWC_PRINT("CRU_SOFTRST1_CON: 0x%08x\n",regvalue); + regvalue = dwc_read_reg32((uint32_t *)(SCU_BASE_ADDR_VA+0x74)); + DWC_PRINT("CRU_SOFTRST2_CON: 0x%08x\n",regvalue); + + ///////////////////////////////////////////////////////////// regvalue = dwc_read_reg32((uint32_t *)(USB_GRF_CON)); - printk("USB_PHY_CON1: 0x%08x\n",regvalue); + DWC_PRINT("USB_PHY_CON1: 0x%08x\n",regvalue); + regvalue = dwc_read_reg32((uint32_t *)(USB_GRF_IOMUX)); + DWC_PRINT("GRF_GPIO4L_IOMUX: 0x%08x\n",regvalue); } void dwc_otg_dump_flags(dwc_otg_core_if_t *_core_if) { - printk("_______________________dwc_otg flags_______________________________\n"); - printk("core_if->op_state = %x\n",_core_if->op_state); - printk("core_if->usb_mode = %x\n",_core_if->usb_mode); - printk("core_if->usb_wakeup = %x\n",_core_if->usb_wakeup); + DWC_PRINT("_______________________dwc_otg flags_______________________________\n"); + DWC_PRINT("core_if->op_state = %x\n",_core_if->op_state); + DWC_PRINT("core_if->usb_mode = %x\n",_core_if->usb_mode); + DWC_PRINT("core_if->usb_wakeup = %x\n",_core_if->usb_wakeup); } -int dwc_step = 0; int dwc_debug(int flag) { dwc_otg_core_if_t *core_if = dwc_core_if; @@ -3342,7 +3363,6 @@ int dwc_debug(int flag) dwc_otg_dump_flags(core_if); break; case 8: - dwc_step = 0; break; case 9: dwc_otg_dump_flags(core_if); diff --git a/drivers/usb/dwc_otg/dwc_otg_cil_intr.c b/drivers/usb/dwc_otg/dwc_otg_cil_intr.c index 783a48a1e323..06ef87b33889 100755 --- a/drivers/usb/dwc_otg/dwc_otg_cil_intr.c +++ b/drivers/usb/dwc_otg/dwc_otg_cil_intr.c @@ -193,7 +193,7 @@ int32_t dwc_otg_handle_otg_intr(dwc_otg_core_if_t *_core_if) 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 ); - printk("********session end intr,soft disconnect************************\n"); + DWC_PRINT("********session end intr,soft disconnect************************\n"); } _core_if->otg_dev->pcd->vbus_status = 0; /////////////////////////////// @@ -337,93 +337,11 @@ int32_t dwc_otg_handle_otg_intr(dwc_otg_core_if_t *_core_if) * * @param _core_if Programming view of DWC_otg controller. */ -#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 rk28_usb_suspend( int exitsuspend ); -#endif int32_t dwc_otg_handle_conn_id_status_change_intr(dwc_otg_core_if_t *_core_if) { gintsts_data_t gintsts = { .d32 = 0 }; - #ifdef DWC_BOTH_HOST_SLAVE - uint32_t count = 0; - volatile gotgctl_data_t gctrl; - 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)) - { - rk28_usb_suspend( 1 ); - } - - /* - * yangkai@rk, 20100331 - * ³äµçÆ÷½ÓÈëʱÓпÉÄÜUSB IDΪµÍ, hostÉ豸Èç¹û¿ìËٰβ壬»áµ±³É³äµçÆ÷´¦Àí - */ - gctrl.d32 = dwc_read_reg32( &_core_if->core_global_regs->gotgctl ); - #if 0 - if( gctrl.b.bsesvld ) - { - if(pcd &&(pcd->vbus_status == 0)) - pcd->vbus_status = 1; - gintsts.b.conidstschng = 1; - dwc_write_reg32 (&_core_if->core_global_regs->gintsts, gintsts.d32); - return 1; - } - #endif -// cmy: Ö»Óе±usb´¦ÓÚÕý³£Ä£Ê½Ê±£¬²Å´¦Àí¸ÃÖжϽøÐÐÇл» - if(_core_if->usb_mode != USB_MODE_NORMAL) - { - DWC_PRINT("_core_if->usb_mode=%d\n", _core_if->usb_mode); - gintsts.b.conidstschng = 1; - dwc_write_reg32 (&_core_if->core_global_regs->gintsts, gintsts.d32); - return 1; - } - DWC_DEBUGPL(DBG_CIL, "switch\n"); - - /* - * Need to disable SOF interrupt immediately. If switching from device - * to host, the PCD interrupt handler won't handle the interrupt if - * host mode is already set. The HCD interrupt handler won't get - * called if the HCD state is HALT. This means that the interrupt does - * not get handled and Linux complains loudly. - */ - gintmsk.b.sofintr = 1; - dwc_modify_reg32(&_core_if->core_global_regs->gintmsk, gintmsk.d32, 0); - - DWC_DEBUGPL(DBG_CIL, " ++Connector ID Status Change Interrupt++ (%s)\n", - (dwc_otg_is_host_mode(_core_if)?"Host":"Device")); - gotgctl.d32 = dwc_read_reg32(&_core_if->core_global_regs->gotgctl); - DWC_DEBUGPL(DBG_CIL, "gotgctl=%0x\n", gotgctl.d32); - DWC_DEBUGPL(DBG_CIL, "gotgctl.b.conidsts=%d\n", gotgctl.b.conidsts); - - /* B-Device connector (Device Mode) */ - if (gotgctl.b.conidsts) { - /* Wait for switch to device mode. */ - while (!dwc_otg_is_device_mode(_core_if) ){ - DWC_PRINT("Waiting for Peripheral Mode, Mode=%s\n", - (dwc_otg_is_host_mode(_core_if)?"Host":"Peripheral")); - MDELAY(100); - if (++count > 10000) *(uint32_t*)NULL=0; - } - hcd_stop(_core_if); - _core_if->op_state = B_PERIPHERAL; - pcd->phy_suspend = 1; - pcd->vbus_status = 0; - dwc_otg_pcd_start_vbus_timer( pcd ); - } else { - /* A-Device connector (Host Mode) */ - while (!dwc_otg_is_host_mode(_core_if) ) { - DWC_PRINT("Waiting for Host Mode, Mode=%s\n", - (dwc_otg_is_host_mode(_core_if)?"Host":"Peripheral")); - MDELAY(100); - if (++count > 10000) *(uint32_t*)NULL=0; - } - dwc_otg_force_host(_core_if); - } - #endif /* Set flag and clear interrupt */ gintsts.b.conidstschng = 1; dwc_write_reg32 (&_core_if->core_global_regs->gintsts, gintsts.d32); @@ -450,27 +368,7 @@ int32_t dwc_otg_handle_session_req_intr( dwc_otg_core_if_t *_core_if ) DWC_PRINT("SRP: Device mode\n"); } else { DWC_PRINT("SRP: Host mode\n"); -/* - int regvalue; - printk("__________________________________________________________________\n"); - regvalue = dwc_read_reg32(&_core_if->core_global_regs->gotgctl); - printk("gotgctl is %08x\n",regvalue); - regvalue = dwc_read_reg32(&_core_if->core_global_regs->gotgint); - printk("gotgint is %08x\n",regvalue); - regvalue = dwc_read_reg32(&_core_if->core_global_regs->gahbcfg); - printk("gahbcfg is %08x\n",regvalue); - regvalue = dwc_read_reg32(&_core_if->core_global_regs->gusbcfg); - printk("gusbcfg is %08x\n",regvalue); - regvalue = dwc_read_reg32(&_core_if->core_global_regs->grstctl); - printk("grstctl is %08x\n",regvalue); - regvalue = dwc_read_reg32(&_core_if->core_global_regs->gintsts); - printk("gintsts is %08x\n",regvalue); - regvalue = dwc_read_reg32(&_core_if->core_global_regs->gintmsk); - printk("gintmsk is %08x\n",regvalue); - regvalue = dwc_read_reg32(&_core_if->core_global_regs->gotgctl); - printk("gotgctl is %08x\n",regvalue); - printk("__________________________________________________________________\n"); -*/ + // dump_coreif(_core_if); // dump_hostif(_core_if); dwc_otg_dump_global_registers(_core_if); @@ -578,7 +476,6 @@ int32_t dwc_otg_handle_disconnect_intr( dwc_otg_core_if_t *_core_if) op_state_str(_core_if)); /** @todo Consolidate this if statement. */ -#ifndef DWC_BOTH_HOST_SLAVE #ifndef DWC_HOST_ONLY if (_core_if->op_state == B_HOST) { /* If in device mode Disconnect and stop the HCD, then @@ -609,7 +506,6 @@ int32_t dwc_otg_handle_disconnect_intr( dwc_otg_core_if_t *_core_if) hcd_disconnect( _core_if ); } } -#endif #endif gintsts.d32 = 0; gintsts.b.disconnect = 1; @@ -632,7 +528,7 @@ int32_t dwc_otg_handle_usb_suspend_intr(dwc_otg_core_if_t *_core_if ) gintsts_data_t gintsts; DWC_DEBUGPL(DBG_ANY,"USB SUSPEND\n"); - printk("USB SUSPEND\n"); + DWC_PRINT("USB SUSPEND\n"); if (dwc_otg_is_device_mode( _core_if ) ) { /* Check the Device status register to determine if the Suspend @@ -648,7 +544,7 @@ int32_t dwc_otg_handle_usb_suspend_intr(dwc_otg_core_if_t *_core_if ) /** @todo Add a module parameter for power management. */ if (dsts.b.suspsts && _core_if->hwcfg4.b.power_optimiz) { - printk("suspend power_optimiz\n"); + DWC_PRINT("suspend power_optimiz\n"); #if 0 pcgcctl_data_t power = {.d32=0}; DWC_DEBUGPL(DBG_CIL, "suspend\n"); diff --git a/drivers/usb/dwc_otg/dwc_otg_driver.c b/drivers/usb/dwc_otg/dwc_otg_driver.c index 735d7fa57c75..6b6361d59673 100755 --- a/drivers/usb/dwc_otg/dwc_otg_driver.c +++ b/drivers/usb/dwc_otg/dwc_otg_driver.c @@ -69,10 +69,12 @@ #include "dwc_otg_hcd.h" //#define DWC_DRIVER_VERSION "2.60a 22-NOV-2006" -#define DWC_DRIVER_VERSION "2.70 2009-12-31" +//#define DWC_DRIVER_VERSION "2.70 2009-12-31" +#define DWC_DRIVER_VERSION "3.00 2010-12-12 rockchip" + #define DWC_DRIVER_DESC "HS OTG USB Controller driver" -static const char dwc_driver_name[] = "dwc_otg"; +static const char dwc_driver_name[] = "usb20_otg"; dwc_otg_device_t* g_otgdev = NULL; @@ -148,11 +150,11 @@ static dwc_otg_core_params_t dwc_otg_module_params = { .rx_thr_length = -1, }; -#ifdef CONFIG_RK2818_HOST11 +#ifdef CONFIG_USB11_HOST dwc_otg_device_t* g_host11 = NULL; -static dwc_otg_core_params_t rk28_host11_module_params = { +static dwc_otg_core_params_t host11_module_params = { .opt = -1, .otg_cap = -1, .dma_enable = -1, @@ -221,6 +223,80 @@ static dwc_otg_core_params_t rk28_host11_module_params = { .rx_thr_length = -1, }; #endif + +#ifdef CONFIG_USB20_HOST +dwc_otg_device_t* g_host20 = NULL; + +static dwc_otg_core_params_t host20_module_params = { + .opt = -1, + .otg_cap = -1, + .dma_enable = -1, + .dma_burst_size = -1, + .speed = -1, + .host_support_fs_ls_low_power = -1, + .host_ls_low_power_phy_clk = -1, + .enable_dynamic_fifo = -1, + .data_fifo_size = -1, + .dev_rx_fifo_size = -1, + .dev_nperio_tx_fifo_size = -1, + .dev_perio_tx_fifo_size = + { /* dev_perio_tx_fifo_size_1 */ + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1 + }, /* 15 */ + .host_rx_fifo_size = -1, + .host_nperio_tx_fifo_size = -1, + //.host_perio_tx_fifo_size = 512, + .host_perio_tx_fifo_size = -1, + .max_transfer_size = -1, + .max_packet_count = -1, + .host_channels = -1, + .dev_endpoints = -1, + .phy_type = -1, + .phy_utmi_width = -1, + .phy_ulpi_ddr = -1, + .phy_ulpi_ext_vbus = -1, + .i2c_enable = -1, + .ulpi_fs_ls = -1, + .ts_dline = -1, + .en_multiple_tx_fifo = -1, + .dev_tx_fifo_size = + { /* dev_tx_fifo_size */ + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1 + }, /* 15 */ + .thr_ctl = -1, + .tx_thr_length = -1, + .rx_thr_length = -1, +}; +#endif + /** * This function shows the Driver Version. */ @@ -254,273 +330,34 @@ static ssize_t dbg_level_store(struct device_driver *_drv, const char *_buf, } static DRIVER_ATTR(debuglevel, S_IRUGO|S_IWUSR, dbg_level_show, dbg_level_store); -extern struct usb_hub *g_root_hub20; -extern struct usb_hub *g_root_hub11; -#ifdef DWC_BOTH_HOST_SLAVE -extern void hcd_start( dwc_otg_core_if_t *_core_if ); - -extern int rk28_usb_suspend( int exitsuspend ); -extern void hub_disconnect_device(struct usb_hub *hub); -extern void rk28_usb_force_disconnect( dwc_otg_core_if_t *core_if ); - -static ssize_t force_usb_mode_show(struct device_driver *_drv, char *_buf) +#ifdef CONFIG_DWC_OTG_DEVICE_ONLY +static ssize_t dwc_otg_conn_en_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 + dwc_otg_pcd_t *_pcd = otg_dev->pcd; + return sprintf (_buf, "%d\n", _pcd->conn_en); } -void dwc_otg_force_host(dwc_otg_core_if_t *core_if) +static ssize_t dwc_otg_conn_en_store(struct device_driver *_drv, const char *_buf, + size_t _count) { + int enable = simple_strtoul(_buf, NULL, 10); dwc_otg_device_t *otg_dev = g_otgdev; - 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)) - { - rk28_usb_suspend( 1 ); - } - del_timer(&otg_dev->pcd->check_vbus_timer); - rk28_usb_force_disconnect(core_if); - if (core_if->pcd_cb && core_if->pcd_cb->stop ) { - core_if->pcd_cb->stop( core_if->pcd_cb->p ); - } - - //core_if->op_state = A_HOST; - /* - * Initialize the Core for Host mode. - */ - dwc_otg_core_init(core_if); - dwc_otg_enable_global_interrupts(core_if); - hcd_start( core_if ); + dwc_otg_pcd_t *_pcd = otg_dev->pcd; + DWC_PRINT("%s %d->%d\n",__func__, _pcd->conn_en, enable); + _pcd->conn_en = enable; + return _count; } -void dwc_otg_force_device(dwc_otg_core_if_t *core_if) -{ - dwc_otg_device_t *otg_dev = g_otgdev; - dwc_otg_disable_global_interrupts( core_if ); - hub_disconnect_device(g_root_hub20); - if (core_if->hcd_cb && core_if->hcd_cb->stop) { - core_if->hcd_cb->stop( core_if->hcd_cb->p ); - } - if(core_if->op_state == B_PERIPHERAL) - { - printk("dwc_otg_force_device,already in B_PERIPHERAL,everest\n"); - return; - } - otg_dev->core_if->op_state = B_PERIPHERAL; - /* Reset the Controller */ - dwc_otg_core_reset( core_if ); - otg_dev->pcd->phy_suspend = 1; - otg_dev->pcd->vbus_status = 0; - dwc_otg_pcd_start_vbus_timer( otg_dev->pcd ); - -} -static void dwc_otg_set_gusbcfg(dwc_otg_core_if_t *core_if, int mode) -{ - gusbcfg_data_t usbcfg = { .d32 = 0 }; - - usbcfg.d32 = dwc_read_reg32( &core_if->core_global_regs->gusbcfg); - switch(mode) - { - case USB_MODE_FORCE_HOST: - usbcfg.b.force_hst_mode = 1; - usbcfg.b.force_dev_mode = 0; - break; - case USB_MODE_FORCE_DEVICE: - usbcfg.b.force_hst_mode = 0; - usbcfg.b.force_dev_mode = 1; - break; - case USB_MODE_NORMAL: - usbcfg.b.force_hst_mode = 0; - usbcfg.b.force_dev_mode = 0; - break; - } - dwc_write_reg32( &core_if->core_global_regs->gusbcfg, usbcfg.d32 ); -} - -static ssize_t force_usb_mode_store(struct device_driver *_drv, const char *_buf, - size_t _count ) -{ - 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; - DWC_PRINT("%s %d->%d\n",__func__, core_if->usb_mode, new_mode); - if(core_if->usb_mode == new_mode) - { - return _count; - } - - switch(new_mode) - { - case USB_MODE_FORCE_HOST: - if(USB_MODE_FORCE_DEVICE == core_if->usb_mode) - {/* device-->host */ - core_if->usb_mode = new_mode; - dwc_otg_force_host(core_if); - } - else if(USB_MODE_NORMAL == core_if->usb_mode) - { - core_if->usb_mode = new_mode; - if(dwc_otg_is_host_mode(core_if)) - { - dwc_otg_set_gusbcfg(core_if, new_mode); - } - else - { - dwc_otg_force_host(core_if); - } - } - break; - case USB_MODE_FORCE_DEVICE: - if(USB_MODE_FORCE_HOST == core_if->usb_mode) - { - core_if->usb_mode = new_mode; - dwc_otg_force_device(core_if); - } - else if(USB_MODE_NORMAL == core_if->usb_mode) - { - core_if->usb_mode = new_mode; - if(dwc_otg_is_device_mode(core_if)) - { - dwc_otg_set_gusbcfg(core_if, new_mode); - } - else - { - dwc_otg_force_device(core_if); - } - } - break; - case USB_MODE_NORMAL: - #if 1 - 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)) - { - rk28_usb_suspend( 1 ); - } - del_timer(&otg_dev->pcd->check_vbus_timer); - dwc_otg_set_gusbcfg(core_if, new_mode); - msleep(50); - if(dwc_otg_is_host_mode(core_if)) - { - dwc_otg_force_host(core_if); - } - else - { - dwc_otg_pcd_start_vbus_timer( otg_dev->pcd ); - } - //mdelay(10); - //core_if->usb_mode = new_mode; - //if(!dwc_otg_connid(core_if)) - // dwc_otg_force_host(core_if); - } - else if(USB_MODE_FORCE_HOST == core_if->usb_mode) - { - if((otg_dev->pcd)&&(otg_dev->pcd->phy_suspend == 1)) - { - rk28_usb_suspend( 1 ); - } - core_if->usb_mode = new_mode; - dwc_otg_set_gusbcfg(core_if, new_mode); - msleep(40); - if(dwc_otg_is_device_mode(core_if)) - { - dwc_otg_force_device(core_if); - } - //if(dwc_otg_connid(core_if)) - // hub_disconnect_device(); - //core_if->usb_mode = new_mode; - // dwc_otg_force_device(core_if); - } - #endif - break; - default: - break; - } - return _count; -} -int otg_debug( int action ) +static DRIVER_ATTR(dwc_otg_conn_en, S_IRUGO|S_IWUSR, dwc_otg_conn_en_show, dwc_otg_conn_en_store); +static ssize_t vbus_status_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; - switch(action) - { - case 0: - dwc_otg_set_gusbcfg(core_if, USB_MODE_FORCE_HOST); - break; - case 1: - dwc_otg_set_gusbcfg(core_if, USB_MODE_FORCE_DEVICE); - break; - case 2: - dwc_otg_set_gusbcfg(core_if, USB_MODE_NORMAL); - break; - default: - break; - } - return 0; -} - -static DRIVER_ATTR(force_usb_mode, 0666/*S_IRUGO|S_IWUSR*/, force_usb_mode_show, force_usb_mode_store); -#endif - -int rk28_usb_check_connectid_change(void) -{ -#ifdef DWC_BOTH_HOST_SLAVE - dwc_otg_device_t *otg_dev = g_otgdev; - dwc_otg_core_if_t *core_if = otg_dev->core_if; - gintsts_data_t gintsts; - - __udelay(1000);//40ms - - gintsts.d32 = dwc_read_reg32(&core_if->core_global_regs->gintsts); - if(gintsts.b.conidstschng) - { - //debug_print("rk28 connect id change %d \n",change); - core_if->usb_wakeup = 1; - return 1; - } -#endif - return 0; + dwc_otg_pcd_t *_pcd = otg_dev->pcd; + return sprintf (_buf, "%d\n", _pcd->vbus_status); } - -int rk28_usb_check_vbus_change( void ) -{ -#ifndef DWC_HOST_ONLY - dwc_otg_device_t *otg_dev = g_otgdev; - 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); - if(gctrl.b.bsesvld != otg_dev->pcd->vbus_status) - { - /* 20091104,HSL@RK,plug and unplg quickly, timer will not know,so let timer connect again */ - otg_dev->pcd->vbus_status = 0; - core_if->usb_wakeup = 1; - return 1; - } +static DRIVER_ATTR(vbus_status, S_IRUGO|S_IWUSR, vbus_status_show, NULL); #endif - return 0; -} /** * This function is called during module intialization to verify that @@ -772,11 +609,10 @@ static int check_parameters(dwc_otg_core_if_t *core_if) (core_params->max_packet_count < (1 << (core_if->hwcfg3.b.packet_size_cntr_width + 4))), ((1 << (core_if->hwcfg3.b.packet_size_cntr_width + 4)) - 1)); -// yk@rk use 1 channel in host 1.1 retval += DWC_OTG_PARAM_CHECK_VALID(host_channels, "host_channels", (core_params->host_channels <= (core_if->hwcfg2.b.num_host_chan + 1)), - (core_if->hwcfg2.b.num_host_chan));// + 1 + (core_if->hwcfg2.b.num_host_chan + 1)); retval += DWC_OTG_PARAM_CHECK_VALID(dev_endpoints, "dev_endpoints", @@ -958,14 +794,14 @@ static int dwc_otg_driver_remove(struct platform_device *pdev) free_irq( platform_get_irq(to_platform_device(dev),0), otg_dev ); } -#ifndef DWC_DEVICE_ONLY +#ifdef CONFIG_DWC_OTG_HOST_ONLY if (otg_dev->hcd != NULL) { dwc_otg_hcd_remove(dev); } #endif -#ifndef DWC_HOST_ONLY +#ifdef CONFIG_DWC_OTG_DEVICE_ONLY if (otg_dev->pcd != NULL) { dwc_otg_pcd_remove(dev); @@ -1023,24 +859,31 @@ 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; /* *Enable usb phy */ unsigned int * otg_phy_con1 = (unsigned int*)(USB_GRF_CON); - *otg_phy_con1 |= (0x01<<2); - *otg_phy_con1 |= (0x01<<3); // exit suspend. - *otg_phy_con1 &= ~(0x01<<2); -#ifndef CONFIG_RK2818_HOST11 - *otg_phy_con1 |= (0x01<<31); + regval = * otg_phy_con1; + regval |= (0x01<<2); + regval |= (0x01<<3); // exit suspend. + regval &= ~(0x01<<2); +#ifndef CONFIG_USB11_HOST + regval |= (0x01<<28); #endif +#ifndef CONFIG_USB20_HOST + regval &= ~(0x01<<14); // exit suspend. + regval |= (0x01<<13); // software control +#endif + *otg_phy_con1 = regval; #if 0 otgreg = ioremap(RK2818_USBOTG_PHYS,RK2818_USBOTG_SIZE); - printk("otgreg 0x%x",otgreg); + DWC_PRINT("otgreg 0x%x",otgreg); dwc_modify_reg32((uint32_t *)(otgreg+0xc),0x20000000,0x20000000); dwc_write_reg32((uint32_t *)(otgreg+0x440), 0x1000); #endif - printk("dwc_otg_driver_probe,everest\n"); + DWC_PRINT("dwc_otg_driver_probe,everest\n"); dwc_otg_device = kmalloc(sizeof(dwc_otg_device_t), GFP_KERNEL); @@ -1069,7 +912,7 @@ static __devinit int dwc_otg_driver_probe(struct platform_device *pdev) retval = -ENOMEM; goto fail; } - printk("%s otg2.0 reg addr: 0x%x remap:0x%x\n",__func__, + DWC_PRINT("%s otg2.0 reg addr: 0x%x remap:0x%x\n",__func__, (unsigned)res_base->start, (unsigned)dwc_otg_device->base); #if 0 dwc_otg_device->base = (void*)(USB_OTG_BASE_ADDR_VA); @@ -1090,7 +933,7 @@ static __devinit int dwc_otg_driver_probe(struct platform_device *pdev) snpsid = dwc_read_reg32((uint32_t *)((uint8_t *)dwc_otg_device->base + 0x40)); if ((snpsid & 0xFFFFF000) != 0x4F542000) { - printk("%s::snpsid=0x%x,want 0x%x" , __func__ , snpsid , 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; @@ -1156,14 +999,10 @@ static __devinit int dwc_otg_driver_probe(struct platform_device *pdev) set_irq_type(irq, IRQT_LOW); #endif -#ifdef CONFIG_DWC_OTG_HOST_PREFERENCE - dwc_otg_device->core_if->usb_mode = USB_MODE_FORCE_HOST; -#else -#ifdef CONFIG_DWC_OTG_DEVICE_PREFERENCE +#ifdef CONFIG_DWC_OTG_DEVICE_ONLY dwc_otg_device->core_if->usb_mode = USB_MODE_FORCE_DEVICE; #else - dwc_otg_device->core_if->usb_mode = USB_MODE_NORMAL; -#endif + dwc_otg_device->core_if->usb_mode = USB_MODE_FORCE_HOST; #endif /* @@ -1173,7 +1012,8 @@ 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 DWC_DEVICE_ONLY +#ifdef CONFIG_DWC_OTG_HOST_ONLY + USB_IOMUX_INIT(GPIO4A5_OTG0DRVVBUS_NAME, GPIO4L_OTG0_DRV_VBUS); /* * Initialize the HCD */ @@ -1185,7 +1025,7 @@ static __devinit int dwc_otg_driver_probe(struct platform_device *pdev) goto fail; } #endif -#ifndef DWC_HOST_ONLY +#ifdef CONFIG_DWC_OTG_DEVICE_ONLY /* * Initialize the PCD */ @@ -1197,17 +1037,19 @@ static __devinit int dwc_otg_driver_probe(struct platform_device *pdev) goto fail; } #endif + + /* * Enable the global interrupt after all the interrupt * handlers are installed. */ dwc_otg_enable_global_interrupts( dwc_otg_device->core_if ); - printk("dwc_otg_driver_probe end, everest\n"); + DWC_PRINT("dwc_otg_driver_probe end, everest\n"); return 0; fail: devm_kfree(&pdev->dev, dwc_otg_device); - printk("dwc_otg_driver_probe fail,everest\n"); + DWC_PRINT("dwc_otg_driver_probe fail,everest\n"); return retval; } @@ -1218,14 +1060,9 @@ static int dwc_otg_driver_suspend(struct platform_device *_dev , pm_message_t st dwc_otg_core_if_t *core_if = otg_dev->core_if; if(core_if->op_state == A_HOST) { - printk("%s,A_HOST mode\n", __func__); + DWC_PRINT("%s,A_HOST mode\n", __func__); return 0; } - //gotgctl_data_t gctrl; -#if 0 - if( __rkusb_debug_mod() ) - return 0; -#endif /* Clear any pending interrupts */ dwc_write_reg32( &core_if->core_global_regs->gintsts, 0xFFFFFFFF); dwc_otg_disable_global_interrupts(core_if); @@ -1243,13 +1080,10 @@ static int dwc_otg_driver_resume(struct platform_device *_dev ) core_if->core_global_regs; if(core_if->op_state == A_HOST) { - printk("%s,A_HOST mode\n", __func__); + DWC_PRINT("%s,A_HOST mode\n", __func__); return 0; } -#if 0 - if( __rkusb_debug_mod() ) - goto sendwakeup; -#endif + /* soft disconnect */ /* 20100226,HSL@RK,if not disconnect,when usb cable in,will auto reconnect * besause now USB PHY is enable,and get USB RESET irq. @@ -1278,7 +1112,7 @@ static void dwc_otg_driver_shutdown(struct platform_device *_dev ) dwc_otg_core_if_t *core_if = otg_dev->core_if; dctl_data_t dctl = {.d32=0}; - printk("%s:: disconnect USB\n" , __func__ ); + DWC_PRINT("%s:: disconnect USB\n" , __func__ ); /* soft disconnect */ dctl.d32 = dwc_read_reg32( &core_if->dev_if->dev_global_regs->dctl ); dctl.b.sftdiscon = 1; @@ -1287,8 +1121,6 @@ static void dwc_otg_driver_shutdown(struct platform_device *_dev ) /* Clear any pending interrupts */ dwc_write_reg32( &core_if->core_global_regs->gintsts, 0xFFFFFFFF); - /* suspend phy. */ - //rk28_usb_suspend(0); } /** @@ -1313,118 +1145,259 @@ static struct platform_driver dwc_otg_driver = { .owner = THIS_MODULE}, }; -#ifdef CONFIG_RK2818_HOST11 +#ifdef CONFIG_USB11_HOST +extern void dwc_otg_hcd_remove(struct device *dev); +extern int __devinit host11_hcd_init(struct device *dev); -void rk28_host11_driver_enable(dwc_otg_core_if_t *core_if) +static int host11_driver_remove(struct platform_device *pdev) { - unsigned int * otg_phy_con1 = (unsigned int*)(USB_GRF_CON); - unsigned int * scu_clkgate1_con = (unsigned int*)(USB_CLKGATE_CON); + 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; + } + /* - * enable usb phy & clockgate host controller + * Free the IRQ */ - core_if->usb_mode == USB_MODE_FORCE_HOST; - core_if->op_state = A_HOST; - dwc_modify_reg32(scu_clkgate1_con,0x80000000,0); //clock gate enable - udelay(10); - dwc_modify_reg32(otg_phy_con1,0x80000000,0);// exit suspend. - mdelay(10); + if (otg_dev->common_irq_installed) + { + free_irq( platform_get_irq(to_platform_device(dev),0), otg_dev ); + } - /* - * Initialize the Core for Host mode. - */ - dwc_otg_core_init(core_if); - dwc_otg_enable_global_interrupts(core_if); - hcd_start( core_if ); + 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); + } + kfree(otg_dev); + + /* + * Clear the drvdata pointer. + */ + dev->platform_data = 0; + + return 0; } -void rk28_host11_driver_disable(dwc_otg_core_if_t *core_if) +/** + * 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; + /* + *Enable usb phy + */ unsigned int * otg_phy_con1 = (unsigned int*)(USB_GRF_CON); - unsigned int * scu_clkgate1_con = (unsigned int*)(USB_CLKGATE_CON); - dwc_otg_disable_global_interrupts( core_if ); - hub_disconnect_device(g_root_hub11); - if (core_if->hcd_cb && core_if->hcd_cb->stop) { - core_if->hcd_cb->stop( core_if->hcd_cb->p ); - } + *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; /* - *disable usb phy & clockgate host controller + * Map the DWC_otg Core memory into virtual address space. */ - dwc_modify_reg32(otg_phy_con1,0x80000000,0x80000000);// exit suspend. - mdelay(10); - dwc_modify_reg32(scu_clkgate1_con,0x80000000,0x80000000); //clock gate enable -} -extern void dwc_otg_hcd_remove(struct device *_dev); -extern int __devinit rk28_host11_hcd_init(struct device *_dev); + + res_base = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res_base) + goto fail; -static int s_host11_enable = 0; + 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 rk28 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; + } -static ssize_t enable_usb11_show(struct device_driver *_drv, char *_buf) + 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); + + /* + * 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 ); + DWC_PRINT("host11_driver_probe end, everest\n"); + return 0; + + fail: + devm_kfree(&pdev->dev, dwc_otg_device); + DWC_PRINT("host11_driver_probe fail,everest\n"); + return retval; +} + +static int host11_driver_suspend(struct platform_device *_dev , pm_message_t state ) { - return sprintf(_buf, "%d\n", s_host11_enable); + //struct device *dev = &_dev->dev; + //dwc_otg_device_t *otg_dev = dev->platform_data; + //dwc_otg_core_if_t *core_if = otg_dev->core_if; + return 0; } -static ssize_t enable_usb11_store(struct device_driver *_drv, const char *_buf, - size_t _count ) +static int host11_driver_resume(struct platform_device *_dev ) { - int enabled = simple_strtoul(_buf, NULL, 16); - dwc_otg_device_t *otg_dev = g_host11; - dwc_otg_core_if_t *core_if = otg_dev->core_if; - printk("enable usb11: %d\n", enabled); - - if(enabled) - {// enable usb1.1 - printk("BEGIN enable\n"); - if(s_host11_enable){ - printk("HOST1.1 already enable\n"); - return _count; - } - rk28_host11_driver_enable(core_if); -#if 0 - GPIOSetPinDirection(GPIOPortG_Pin1, GPIO_OUT); - GPIOSetPinLevel(GPIOPortG_Pin1, GPIO_LOW); - msleep(10); - - GPIOSetPinDirection(GPIOPortB_Pin0, GPIO_OUT); - GPIOSetPinLevel(GPIOPortB_Pin0, GPIO_HIGH); - msleep(10); - - GPIOSetPinDirection(GPIOPortG_Pin0, GPIO_OUT); - GPIOSetPinLevel(GPIOPortG_Pin0, GPIO_HIGH); - msleep(10); - - GPIOSetPinDirection(GPIOPortG_Pin1, GPIO_OUT); - GPIOSetPinLevel(GPIOPortG_Pin1, GPIO_HIGH); -#endif - s_host11_enable = 1; - printk("END\n"); - } - else - {// disable usb1.1 -// cmy: - printk("BEGIN disable\n"); - rk28_host11_driver_disable(core_if); -#if 0 - GPIOSetPinDirection(GPIOPortB_Pin0, GPIO_OUT); - GPIOSetPinLevel(GPIOPortB_Pin0, GPIO_LOW); - msleep(10); - - GPIOSetPinDirection(GPIOPortG_Pin0, GPIO_OUT); - GPIOSetPinLevel(GPIOPortG_Pin0, GPIO_LOW); - msleep(10); - - GPIOSetPinDirection(GPIOPortG_Pin1, GPIO_OUT); - GPIOSetPinLevel(GPIOPortG_Pin1, GPIO_LOW); + //struct device *dev = &_dev->dev; + //dwc_otg_device_t *otg_dev = dev->platform_data; + //dwc_otg_core_if_t *core_if = otg_dev->core_if; + return 0; +} + +static struct platform_driver host11_driver = { + .probe = host11_driver_probe, + .remove = host11_driver_remove, + .suspend = host11_driver_suspend, + .resume = host11_driver_resume, + .driver = { + .name = "usb11_host", + .owner = THIS_MODULE}, +}; #endif - s_host11_enable = 0; - printk("END\n"); - } - return _count; -} +#ifdef CONFIG_USB20_HOST +extern void dwc_otg_hcd_remove(struct device *dev); +extern int __devinit host20_hcd_init(struct device *_dev); -static DRIVER_ATTR(enable_usb11, 0666/*S_IRUGO|S_IWUSR*/, enable_usb11_show, enable_usb11_store); -static int rk28_host11_driver_remove(struct platform_device *pdev) +static int host20_driver_remove(struct platform_device *pdev) { struct device *dev = &pdev->dev; dwc_otg_device_t *otg_dev = dev->platform_data; @@ -1487,7 +1460,7 @@ static int rk28_host11_driver_remove(struct platform_device *pdev) * * @param[in] pdev platform_device definition */ -static __devinit int rk28_host11_driver_probe(struct platform_device *pdev) +static __devinit int host20_driver_probe(struct platform_device *pdev) { struct resource *res_base; int retval = 0; @@ -1500,17 +1473,20 @@ static __devinit int rk28_host11_driver_probe(struct platform_device *pdev) *Enable usb phy */ unsigned int * otg_phy_con1 = (unsigned int*)(USB_GRF_CON); - *otg_phy_con1 &= ~(0x01<<31); // exit suspend. + otgreg = * otg_phy_con1; + otgreg |= (0x01<<13); // software control + otgreg |= (0x01<<14); // exit suspend. + otgreg &= ~(0x01<<13); // software control + *otg_phy_con1 = otgreg; #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); - printk("%s otg2.0 reg addr: 0x%x",__func__,otgreg); + 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 - printk("%s otg_phy_con1:0x%x,everest\n",__func__,dwc_read_reg32(otg_phy_con1)); dwc_otg_device = kmalloc(sizeof(dwc_otg_device_t), GFP_KERNEL); @@ -1533,7 +1509,7 @@ static __devinit int rk28_host11_driver_probe(struct platform_device *pdev) dwc_otg_device->base = ioremap(res_base->start,USBOTG_SIZE); - printk("%s host1.1 reg addr: 0x%x remap:0x%x\n",__func__, + DWC_PRINT("%s host2.0 reg addr: 0x%x remap:0x%x\n",__func__, (unsigned)res_base->start, (unsigned)dwc_otg_device->base); if (dwc_otg_device->base == NULL) { @@ -1550,7 +1526,7 @@ static __devinit int rk28_host11_driver_probe(struct platform_device *pdev) snpsid = dwc_read_reg32((uint32_t *)((uint8_t *)dwc_otg_device->base + 0x40)); if ((snpsid & 0xFFFFF000) != 0x4F542000) { - printk("%s::snpsid=0x%x,want 0x%x" , __func__ , snpsid , 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; @@ -1562,18 +1538,17 @@ static __devinit int rk28_host11_driver_probe(struct platform_device *pdev) */ dev->platform_data = dwc_otg_device; DWC_DEBUGPL(DBG_CIL, "dwc_otg_device=0x%p\n", dwc_otg_device); - g_host11 = dwc_otg_device; + g_host20 = dwc_otg_device; dwc_otg_device->core_if = dwc_otg_cil_init( dwc_otg_device->base, - &rk28_host11_module_params); + &host20_module_params); if (dwc_otg_device->core_if == 0) { dev_err(dev, "CIL initialization failed!\n"); retval = -ENOMEM; goto fail; } - DWC_DEBUGPL( DBG_CIL, "registering (common) handler for irq%d\n", - irq); + dwc_otg_device->core_if->otg_dev = dwc_otg_device; /* * Validate parameter values. @@ -1587,7 +1562,7 @@ static __devinit int rk28_host11_driver_probe(struct platform_device *pdev) /* * Create Device Attributes in sysfs */ - //dwc_otg_attr_create(dev); + dwc_otg_attr_create(dev); /* * Disable the global interrupt until all the interrupt @@ -1614,6 +1589,7 @@ static __devinit int rk28_host11_driver_probe(struct platform_device *pdev) dwc_otg_device->common_irq_installed = 1; } + USB_IOMUX_INIT(GPIO4A6_OTG1DRVVBUS_NAME, GPIO4L_OTG1_DRV_VBUS); /* * Initialize the DWC_otg core. */ @@ -1622,10 +1598,10 @@ static __devinit int rk28_host11_driver_probe(struct platform_device *pdev) /* * Initialize the HCD */ - retval = rk28_host11_hcd_init(dev); + retval = host20_hcd_init(dev); if (retval != 0) { - DWC_ERROR("rk28_host11_hcd_init failed\n"); + DWC_ERROR("host20_hcd_init failed\n"); dwc_otg_device->hcd = NULL; goto fail; } @@ -1634,16 +1610,16 @@ static __devinit int rk28_host11_driver_probe(struct platform_device *pdev) * handlers are installed. */ dwc_otg_enable_global_interrupts( dwc_otg_device->core_if ); - printk("rk28_host11_driver_probe end, everest\n"); + DWC_PRINT("host20_driver_probe end, everest\n"); return 0; fail: devm_kfree(&pdev->dev, dwc_otg_device); - printk("rk28_host11_driver_probe fail,everest\n"); + DWC_PRINT("host20_driver_probe fail,everest\n"); return retval; } -static int rk28_host11_driver_suspend(struct platform_device *_dev , pm_message_t state ) +static int host20_driver_suspend(struct platform_device *_dev , pm_message_t state ) { //struct device *dev = &_dev->dev; //dwc_otg_device_t *otg_dev = dev->platform_data; @@ -1651,7 +1627,7 @@ static int rk28_host11_driver_suspend(struct platform_device *_dev , pm_message_ return 0; } -static int rk28_host11_driver_resume(struct platform_device *_dev ) +static int host20_driver_resume(struct platform_device *_dev ) { //struct device *dev = &_dev->dev; //dwc_otg_device_t *otg_dev = dev->platform_data; @@ -1659,16 +1635,17 @@ static int rk28_host11_driver_resume(struct platform_device *_dev ) return 0; } -static struct platform_driver rk28_host11_driver = { - .probe = rk28_host11_driver_probe, - .remove = rk28_host11_driver_remove, - .suspend = rk28_host11_driver_suspend, - .resume = rk28_host11_driver_resume, +static struct platform_driver host20_driver = { + .probe = host20_driver_probe, + .remove = host20_driver_remove, + .suspend = host20_driver_suspend, + .resume = host20_driver_resume, .driver = { - .name = "rk2818_host11", + .name = "usb20_host", .owner = THIS_MODULE}, }; #endif + /** * This function is called when the dwc_otg_driver is installed with the * insmod command. It registers the dwc_otg_driver structure with the @@ -1682,31 +1659,51 @@ static struct platform_driver rk28_host11_driver = { static int __init dwc_otg_driver_init(void) { int retval = 0; - - //*(unsigned long *)(0xFF040000+0xE00) = 0x0; //Enable USB Port + /* + * USB2.0 OTG controller + */ retval = platform_driver_register(&dwc_otg_driver); if (retval < 0) { - printk(KERN_ERR "%s retval=%d\n", __func__, retval); + DWC_ERROR("%s retval=%d\n", __func__, retval); return retval; } if (driver_create_file(&dwc_otg_driver.driver, &driver_attr_version)) pr_warning("DWC_OTG: Failed to create driver version file\n"); if (driver_create_file(&dwc_otg_driver.driver, &driver_attr_debuglevel)) pr_warning("DWC_OTG: Failed to create driver debug level file\n"); - -#ifdef DWC_BOTH_HOST_SLAVE - retval = driver_create_file(&dwc_otg_driver.driver, &driver_attr_force_usb_mode); + +#ifdef CONFIG_DWC_OTG_DEVICE_ONLY + if(driver_create_file(&dwc_otg_driver.driver, &driver_attr_dwc_otg_conn_en)) + pr_warning("DWC_OTG: Failed to create driver dwc_otg_conn_en file"); + if(driver_create_file(&dwc_otg_driver.driver, &driver_attr_vbus_status)) + pr_warning("DWC_OTG: Failed to create driver vbus status file"); #endif - -#ifdef CONFIG_RK2818_HOST11 - retval = platform_driver_register(&rk28_host11_driver); + + /* + * USB1.1 host controller + */ + +#ifdef CONFIG_USB11_HOST + retval = platform_driver_register(&host11_driver); if (retval < 0) { - printk(KERN_ERR "%s retval=%d\n", __func__, retval); + DWC_ERROR("%s retval=%d\n", __func__, retval); + return retval; + } +// retval = driver_create_file(&host11_driver.driver, &driver_attr_enable_usb11); +#endif + + /* + * USB1.1 host controller + */ +#ifdef CONFIG_USB20_HOST + retval = platform_driver_register(&host20_driver); + if (retval < 0) + { + DWC_ERROR("%s retval=%d\n", __func__, retval); return retval; } - retval = driver_create_file(&rk28_host11_driver.driver, &driver_attr_enable_usb11); #endif return retval; } @@ -1720,20 +1717,25 @@ module_init(dwc_otg_driver_init); */ static void __exit dwc_otg_driver_cleanup(void) { - printk(KERN_DEBUG "dwc_otg_driver_cleanup()\n"); + DWC_PRINT("dwc_otg_driver_cleanup()\n"); driver_remove_file(&dwc_otg_driver.driver, &driver_attr_version); driver_remove_file(&dwc_otg_driver.driver, &driver_attr_debuglevel); -#ifdef DWC_BOTH_HOST_SLAVE - driver_remove_file(&dwc_otg_driver.driver, &driver_attr_force_usb_mode); + +#ifdef CONFIG_DWC_OTG_DEVICE_ONLY + driver_remove_file(&dwc_otg_driver.driver, &driver_attr_dwc_otg_conn_en); #endif platform_driver_unregister(&dwc_otg_driver); -#ifdef CONFIG_RK2818_HOST11 - platform_driver_unregister(&rk28_host11_driver); + +#ifdef CONFIG_USB11_HOST + platform_driver_unregister(&host11_driver); +#endif + +#ifdef CONFIG_USB20_HOST + platform_driver_unregister(&host20_driver); #endif - //*(unsigned long *)(0xFF040000+0xE00) = 0xF; //Disable USB Port - printk(KERN_INFO "%s module removed\n", dwc_driver_name); + DWC_PRINT("%s module removed\n", dwc_driver_name); } module_exit(dwc_otg_driver_cleanup); diff --git a/drivers/usb/dwc_otg/dwc_otg_hcd.c b/drivers/usb/dwc_otg/dwc_otg_hcd.c index 79502141b6f1..6e1a3ca477a9 100755 --- a/drivers/usb/dwc_otg/dwc_otg_hcd.c +++ b/drivers/usb/dwc_otg/dwc_otg_hcd.c @@ -66,7 +66,7 @@ static int dwc_otg_hcd_suspend(struct usb_hcd *hcd) if(core_if->op_state == B_PERIPHERAL) { - printk("%s, usb device mode\n", __func__); + DWC_PRINT("%s, usb device mode\n", __func__); return 0; } hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0); @@ -115,7 +115,7 @@ static int dwc_otg_hcd_resume(struct usb_hcd *hcd) if(core_if->op_state == B_PERIPHERAL) { - printk("%s, usb device mode\n", __func__); + DWC_PRINT("%s, usb device mode\n", __func__); return 0; } #if 1 @@ -204,10 +204,48 @@ static const struct hc_driver dwc_otg_hc_driver = { //.hub_resume = }; -#ifdef CONFIG_RK2818_HOST11 -static const struct hc_driver rk28_host11_hc_driver = { +#ifdef CONFIG_USB11_HOST +static const struct hc_driver host11_hc_driver = { - .description = "rk28_host11_hcd", + .description = "host11_hcd", + .product_desc = "DWC OTG Controller", + .hcd_priv_size = sizeof(dwc_otg_hcd_t), + + .irq = dwc_otg_hcd_irq, + + .flags = HCD_MEMORY | HCD_USB2, + + //.reset = + .start = dwc_otg_hcd_start, + //.suspend = + //.resume = + + /* yk@rk 20100625 + * core/hcd.c call hcd->driver->bus_suspend + * otherwise system can not be suspended + */ +#ifdef CONFIG_PM + .bus_suspend = dwc_otg_hcd_suspend, + .bus_resume = dwc_otg_hcd_resume, +#endif + .stop = dwc_otg_hcd_stop, + + .urb_enqueue = dwc_otg_hcd_urb_enqueue, + .urb_dequeue = dwc_otg_hcd_urb_dequeue, + .endpoint_disable = dwc_otg_hcd_endpoint_disable, + + .get_frame_number = dwc_otg_hcd_get_frame_number, + + .hub_status_data = dwc_otg_hcd_hub_status_data, + .hub_control = dwc_otg_hcd_hub_control, + //.hub_suspend = + //.hub_resume = +}; +#endif +#ifdef CONFIG_USB20_HOST +static const struct hc_driver host20_hc_driver = { + + .description = "host20_hcd", .product_desc = "DWC OTG Controller", .hcd_priv_size = sizeof(dwc_otg_hcd_t), @@ -247,7 +285,6 @@ static const struct hc_driver rk28_host11_hc_driver = { * Work queue function for starting the HCD when A-Cable is connected. * The dwc_otg_hcd_start() must be called in a process context. */ -// cmy static void hcd_start_func(struct work_struct *work) { dwc_otg_hcd_t *dwc_otg_hcd = container_of(work, dwc_otg_hcd_t, start_work); @@ -381,7 +418,7 @@ static int32_t dwc_otg_hcd_disconnect_cb( void *_p ) /* * Set status flags for the hub driver. */ - printk("dwc_otg_hcd_disconnect_cb"); +// DWC_PRINT("dwc_otg_hcd_disconnect_cb"); dwc_otg_hcd->flags.b.port_connect_status_change = 1; dwc_otg_hcd->flags.b.port_connect_status = 0; @@ -572,20 +609,16 @@ int __devinit dwc_otg_hcd_init(struct device *dev) /* Set device flags indicating whether the HCD supports DMA. */ static u64 usb_dmamask = 0xffffffffUL; if (otg_dev->core_if->dma_enable) { -// DWC_PRINT("Using DMA mode\n"); dev->dma_mask = &usb_dmamask; dev->coherent_dma_mask = ~0; } else { -// DWC_PRINT("Using Slave mode\n"); dev->dma_mask = (void *)0; dev->coherent_dma_mask = 0; } #endif - printk("dwc_otg_hcd_init everest\n"); + DWC_PRINT("dwc_otg_hcd_init everest\n"); // g_dbg_lvl = 0xff; - DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD INIT\n"); - /* * Allocate memory for the base HCD plus the DWC OTG HCD. * Initialize the base HCD. @@ -696,12 +729,172 @@ int __devinit dwc_otg_hcd_init(struct device *dev) usb_put_hcd(hcd); error1: - printk("dwc_otg_hcd_init error,everest\n"); + DWC_PRINT("dwc_otg_hcd_init error,everest\n"); return retval; } -#ifdef CONFIG_RK2818_HOST11 -static dwc_otg_cil_callbacks_t rk28_host11_cil_callbacks = { +#ifdef CONFIG_USB11_HOST +static dwc_otg_cil_callbacks_t host11_cil_callbacks = { + .start = dwc_otg_hcd_start_cb, + .stop = dwc_otg_hcd_stop_cb, + .disconnect = dwc_otg_hcd_disconnect_cb, + .session_start = dwc_otg_hcd_session_start_cb, + .p = 0,//hcd +}; + +static struct tasklet_struct host11_reset_tasklet = { + .next = NULL, + .state = 0, + .count = ATOMIC_INIT(0), + .func = reset_tasklet_func, + .data = 0, +}; + +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; + + int num_channels; + int i; + dwc_hc_t *channel; + + int retval = 0; +#if 1 //kaiker .these code must execute before usb_create_hcd + /* Set device flags indicating whether the HCD supports DMA. */ + static u64 usb_dmamask = 0xffffffffUL; + if (otg_dev->core_if->dma_enable) { +// DWC_PRINT("Using DMA mode\n"); + dev->dma_mask = &usb_dmamask; + dev->coherent_dma_mask = ~0; + } else { +// DWC_PRINT("Using Slave mode\n"); + dev->dma_mask = (void *)0; + dev->coherent_dma_mask = 0; + } +#endif + DWC_PRINT("%s everest\n",__func__); +// g_dbg_lvl = 0xff; + + DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD INIT\n"); + + /* + * Allocate memory for the base HCD plus the DWC OTG HCD. + * Initialize the base HCD. + */ + hcd = usb_create_hcd(&host11_hc_driver, dev, dev_name(dev)); + if (hcd == NULL) { + retval = -ENOMEM; + goto error1; + } + hcd->regs = otg_dev->base; + hcd->self.otg_port = 1; + + /* Initialize the DWC OTG HCD. */ + dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd); + dwc_otg_hcd->core_if = otg_dev->core_if; + otg_dev->hcd = dwc_otg_hcd; + + spin_lock_init(&dwc_otg_hcd->global_lock); + + + /* Register the HCD CIL Callbacks */ + dwc_otg_cil_register_hcd_callbacks(otg_dev->core_if, + &host11_cil_callbacks, hcd); + + /* Initialize the non-periodic schedule. */ + INIT_LIST_HEAD(&dwc_otg_hcd->non_periodic_sched_inactive); + INIT_LIST_HEAD(&dwc_otg_hcd->non_periodic_sched_active); + + /* Initialize the periodic schedule. */ + INIT_LIST_HEAD(&dwc_otg_hcd->periodic_sched_inactive); + INIT_LIST_HEAD(&dwc_otg_hcd->periodic_sched_ready); + INIT_LIST_HEAD(&dwc_otg_hcd->periodic_sched_assigned); + INIT_LIST_HEAD(&dwc_otg_hcd->periodic_sched_queued); + + /* + * Create a host channel descriptor for each host channel implemented + * in the controller. Initialize the channel descriptor array. + */ + INIT_LIST_HEAD(&dwc_otg_hcd->free_hc_list); + num_channels = dwc_otg_hcd->core_if->core_params->host_channels; + for (i = 0; i < num_channels; i++) { + channel = kmalloc(sizeof(dwc_hc_t), GFP_KERNEL); + if (channel == NULL) { + retval = -ENOMEM; + DWC_ERROR("%s: host channel allocation failed\n", __func__); + goto error2; + } + memset(channel, 0, sizeof(dwc_hc_t)); + channel->hc_num = i; + dwc_otg_hcd->hc_ptr_array[i] = channel; +#ifdef DEBUG + init_timer(&dwc_otg_hcd->core_if->hc_xfer_timer[i]); +#endif + + DWC_DEBUGPL(DBG_HCDV, "HCD Added channel #%d, hc=%p\n", i, channel); + } + + /* Initialize the Connection timeout timer. */ + init_timer( &dwc_otg_hcd->conn_timer ); + + /* Initialize reset tasklet. */ + host11_reset_tasklet.data = (unsigned long) dwc_otg_hcd; + dwc_otg_hcd->reset_tasklet = &host11_reset_tasklet; + /* + * Finish generic HCD initialization and start the HCD. This function + * allocates the DMA buffer pool, registers the USB bus, requests the + * IRQ line, and calls dwc_otg_hcd_start method. + */ + retval = usb_add_hcd(hcd, platform_get_irq(to_platform_device(dev), 0), + IRQF_SHARED); + if (retval < 0) { + DWC_ERROR("usb_add_hcd fail,everest\n"); + goto error2; + } + /* + * Allocate space for storing data on status transactions. Normally no + * data is sent, but this space acts as a bit bucket. This must be + * done after usb_add_hcd since that function allocates the DMA buffer + * pool. + */ + if (otg_dev->core_if->dma_enable) { + dwc_otg_hcd->status_buf = + dma_alloc_coherent(dev, + DWC_OTG_HCD_STATUS_BUF_SIZE, + &dwc_otg_hcd->status_buf_dma, + GFP_KERNEL | GFP_DMA); + } else { + dwc_otg_hcd->status_buf = kmalloc(DWC_OTG_HCD_STATUS_BUF_SIZE, + GFP_KERNEL); + } + if (dwc_otg_hcd->status_buf == NULL) { + retval = -ENOMEM; + DWC_ERROR("%s: status_buf allocation failed\n", __func__); + goto error3; + } + + DWC_PRINT("%s end,everest\n",__func__); +// DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD Initialized HCD, bus=%s, usbbus=%d\n", +// dev->bus_id, hcd->self.busnum); + + return 0; + + /* Error conditions */ + error3: + usb_remove_hcd(hcd); + error2: + dwc_otg_hcd_free(hcd); + usb_put_hcd(hcd); + + error1: + DWC_PRINT("dwc_otg_hcd_init error,everest\n"); + return retval; +} +#endif +#ifdef CONFIG_USB20_HOST +static dwc_otg_cil_callbacks_t host20_cil_callbacks = { .start = dwc_otg_hcd_start_cb, .stop = dwc_otg_hcd_stop_cb, .disconnect = dwc_otg_hcd_disconnect_cb, @@ -709,7 +902,7 @@ static dwc_otg_cil_callbacks_t rk28_host11_cil_callbacks = { .p = 0,//hcd }; -static struct tasklet_struct rk28_host11_reset_tasklet = { +static struct tasklet_struct host20_reset_tasklet = { .next = NULL, .state = 0, .count = ATOMIC_INIT(0), @@ -717,7 +910,7 @@ static struct tasklet_struct rk28_host11_reset_tasklet = { .data = 0, }; -int __devinit rk28_host11_hcd_init(struct device *dev) +int __devinit host20_hcd_init(struct device *dev) { struct usb_hcd *hcd = NULL; dwc_otg_hcd_t *dwc_otg_hcd = NULL; @@ -741,7 +934,7 @@ int __devinit rk28_host11_hcd_init(struct device *dev) dev->coherent_dma_mask = 0; } #endif - printk("%s everest\n",__func__); + DWC_PRINT("%s everest\n",__func__); // g_dbg_lvl = 0xff; DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD INIT\n"); @@ -750,7 +943,7 @@ int __devinit rk28_host11_hcd_init(struct device *dev) * Allocate memory for the base HCD plus the DWC OTG HCD. * Initialize the base HCD. */ - hcd = usb_create_hcd(&rk28_host11_hc_driver, dev, dev_name(dev)); + hcd = usb_create_hcd(&host20_hc_driver, dev, dev_name(dev)); if (hcd == NULL) { retval = -ENOMEM; goto error1; @@ -768,7 +961,7 @@ int __devinit rk28_host11_hcd_init(struct device *dev) /* Register the HCD CIL Callbacks */ dwc_otg_cil_register_hcd_callbacks(otg_dev->core_if, - &rk28_host11_cil_callbacks, hcd); + &host20_cil_callbacks, hcd); /* Initialize the non-periodic schedule. */ INIT_LIST_HEAD(&dwc_otg_hcd->non_periodic_sched_inactive); @@ -807,8 +1000,8 @@ int __devinit rk28_host11_hcd_init(struct device *dev) init_timer( &dwc_otg_hcd->conn_timer ); /* Initialize reset tasklet. */ - rk28_host11_reset_tasklet.data = (unsigned long) dwc_otg_hcd; - dwc_otg_hcd->reset_tasklet = &rk28_host11_reset_tasklet; + host20_reset_tasklet.data = (unsigned long) dwc_otg_hcd; + dwc_otg_hcd->reset_tasklet = &host20_reset_tasklet; /* * Finish generic HCD initialization and start the HCD. This function * allocates the DMA buffer pool, registers the USB bus, requests the @@ -856,10 +1049,11 @@ int __devinit rk28_host11_hcd_init(struct device *dev) usb_put_hcd(hcd); error1: - printk("dwc_otg_hcd_init error,everest\n"); + DWC_PRINT("dwc_otg_hcd_init error,everest\n"); return retval; } #endif + /** * Removes the HCD. * Frees memory and resources associated with the HCD and deregisters the bus. @@ -934,32 +1128,11 @@ int dwc_otg_hcd_start(struct usb_hcd *_hcd) dwc_otg_core_if_t *core_if = dwc_otg_hcd->core_if; unsigned long flags; - struct usb_device *udev; struct usb_bus *bus; DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD START\n"); spin_lock_irqsave(&dwc_otg_hcd->global_lock, flags); -#if 0 - unsigned int regvalue; - printk("__________________________________________________________________\n"); - regvalue = dwc_read_reg32(&dwc_otg_hcd->core_if->core_global_regs->gotgctl); - printk("gotgctl is %08x\n",regvalue); - regvalue = dwc_read_reg32(&dwc_otg_hcd->core_if->core_global_regs->gotgint); - printk("gotgint is %08x\n",regvalue); - regvalue = dwc_read_reg32(&dwc_otg_hcd->core_if->core_global_regs->gahbcfg); - printk("gahbcfg is %08x\n",regvalue); - regvalue = dwc_read_reg32(&dwc_otg_hcd->core_if->core_global_regs->gusbcfg); - printk("gusbcfg is %08x\n",regvalue); - regvalue = dwc_read_reg32(&dwc_otg_hcd->core_if->core_global_regs->grstctl); - printk("grstctl is %08x\n",regvalue); - regvalue = dwc_read_reg32(&dwc_otg_hcd->core_if->core_global_regs->gintsts); - printk("gintsts is %08x\n",regvalue); - regvalue = dwc_read_reg32(&dwc_otg_hcd->core_if->core_global_regs->gintmsk); - printk("gintmsk is %08x\n",regvalue); - regvalue = dwc_read_reg32(&dwc_otg_hcd->core_if->core_global_regs->gotgctl); - printk("gotgctl is %08x\n",regvalue); - printk("__________________________________________________________________\n"); -#endif + DWC_PRINT("dwc_otg_hcd_start! everest\n"); bus = hcd_to_bus(_hcd); _hcd->state = HC_STATE_RUNNING; @@ -971,13 +1144,17 @@ int dwc_otg_hcd_start(struct usb_hcd *_hcd) usb_hcd_resume_root_hub(_hcd); } else { + /* + * no use + * yk@rk 2010121 + struct usb_device *udev;6 udev = usb_alloc_dev(NULL, bus, 0); udev->speed = USB_SPEED_HIGH; if (!udev) { DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD Error udev alloc\n"); return -ENODEV; } - + */ /* Not needed - VJ if ((retval = usb_hcd_register_root_hub(udev, _hcd)) != 0) { DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD Error registering %d\n", retval); @@ -988,7 +1165,7 @@ int dwc_otg_hcd_start(struct usb_hcd *_hcd) /* Initialize the bus state. If the core is in Device Mode * HALT the USB bus and return. */ if (dwc_otg_is_device_mode (core_if)) { - printk("dwc_otg_hcd_start controller in device mode,everest\n"); + DWC_PRINT("dwc_otg_hcd_start controller in device mode,everest\n"); //_hcd->state = HC_STATE_HALT; goto out; } @@ -1110,7 +1287,6 @@ void dwc_otg_hcd_free(struct usb_hcd *_hcd) #ifdef DEBUG static void dump_urb_info(struct urb *_urb, char* _fn_name) { - DWC_PRINT("%s, urb %p,%x\n", _fn_name, _urb,_urb); DWC_PRINT(" Device address: %d\n", usb_pipedevice(_urb->pipe)); DWC_PRINT(" Endpoint: %d, %s\n", usb_pipeendpoint(_urb->pipe), (usb_pipein(_urb->pipe) ? "IN" : "OUT")); @@ -1219,7 +1395,7 @@ int dwc_otg_hcd_urb_enqueue(struct usb_hcd *_hcd, retval = usb_hcd_link_urb_to_ep(_hcd, _urb); if (retval) { - printk("%s, usb_hcd_link_urb_to_ep error\n", __func__); + DWC_PRINT("%s, usb_hcd_link_urb_to_ep error\n", __func__); return retval; } spin_lock_irqsave(&dwc_otg_hcd->global_lock, flags); @@ -1277,8 +1453,8 @@ int dwc_otg_hcd_urb_dequeue(struct usb_hcd *_hcd, struct urb *_urb, int _status) urb_qtd = (dwc_otg_qtd_t *) _urb->hcpriv; if(_ep==NULL) { - printk("%s=====================================================\n",__func__); - printk("urb->ep is null\n"); + DWC_PRINT("%s=====================================================\n",__func__); + DWC_PRINT("urb->ep is null\n"); return -1; } qh = (dwc_otg_qh_t *) _ep->hcpriv; @@ -1288,7 +1464,11 @@ int dwc_otg_hcd_urb_dequeue(struct usb_hcd *_hcd, struct urb *_urb, int _status) spin_unlock_irqrestore(&dwc_otg_hcd->global_lock, flags); return retval; } - + if(urb_qtd == NULL) + { + DWC_PRINT("%s,urb_qtd is null\n",__func__); + //return -1; + } dwc_otg_hcd = hcd_to_dwc_otg_hcd(_hcd); #ifdef DEBUG @@ -2389,8 +2569,18 @@ static void assign_and_init_hc(dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh) if (urb->dev->speed == USB_SPEED_LOW) { hc->speed = DWC_OTG_EP_SPEED_LOW; + /* + * yk@rk 20101216 fix bandwidth check error when full/low speed + * device connected. + */ + _hcd->core_if->core_params->speed = DWC_SPEED_PARAM_FULL; } else if (urb->dev->speed == USB_SPEED_FULL) { hc->speed = DWC_OTG_EP_SPEED_FULL; + /* + * yk@rk 20101216 fix bandwidth check error when full/low speed + * device connected. warning: only support 1 device at root hub. + */ + _hcd->core_if->core_params->speed = DWC_SPEED_PARAM_FULL; } else { hc->speed = DWC_OTG_EP_SPEED_HIGH; } @@ -2569,15 +2759,9 @@ dwc_otg_transaction_type_e dwc_otg_hcd_select_transactions(dwc_otg_hcd_t *_hcd) qh_ptr = _hcd->non_periodic_sched_inactive.next; num_channels = _hcd->core_if->core_params->host_channels; while (qh_ptr != &_hcd->non_periodic_sched_inactive && - /*yk@rk 20100714 (_hcd->non_periodic_channels < num_channels - _hcd->periodic_channels) && - */ !list_empty(&_hcd->free_hc_list)) { - - if((num_channels > 2)&&(_hcd->non_periodic_channels >= - num_channels - _hcd->periodic_channels)) - break; qh = list_entry(qh_ptr, dwc_otg_qh_t, qh_list_entry); assign_and_init_hc(_hcd, qh); diff --git a/drivers/usb/dwc_otg/dwc_otg_hcd_intr.c b/drivers/usb/dwc_otg/dwc_otg_hcd_intr.c index 8e24b6173e05..9872a1c75e9d 100755 --- a/drivers/usb/dwc_otg/dwc_otg_hcd_intr.c +++ b/drivers/usb/dwc_otg/dwc_otg_hcd_intr.c @@ -35,7 +35,7 @@ #include "dwc_otg_driver.h" #include "dwc_otg_hcd.h" #include "dwc_otg_regs.h" - +int csplit_nak = 0; /** @file * This file contains the implementation of the HCD Interrupt handlers. */ @@ -55,7 +55,7 @@ int32_t dwc_otg_hcd_handle_intr (dwc_otg_hcd_t *_dwc_otg_hcd) if (dwc_otg_is_host_mode(core_if)) { gintsts.d32 = dwc_otg_read_core_intr(core_if); if (!gintsts.d32) { - DWC_PRINT("%s,GINTSTS = 0\n",__func__); +// DWC_PRINT("%s,GINTSTS = 0\n",__func__); return 0; } @@ -196,7 +196,7 @@ int32_t dwc_otg_hcd_handle_sof_intr (dwc_otg_hcd_t *_hcd) * fix bug for alcro hub * do not send csplit after start_split_frame+4 */ - if(dwc_frame_num_gt(_hcd->frame_number, + if((qh->do_split)&&dwc_frame_num_gt(_hcd->frame_number, dwc_frame_num_inc(qh->start_split_frame, 4))) { qtd = list_entry(qh->qtd_list.next, dwc_otg_qtd_t, qtd_list_entry); @@ -792,19 +792,10 @@ static void release_channel(dwc_otg_hcd_t *_hcd, dwc_otg_transaction_type_e tr_type; int free_qtd; - int continue_trans = 0; + int continue_trans = 1; DWC_DEBUGPL(DBG_HCDV, " %s: channel %d, halt_status %d\n", __func__, _hc->hc_num, _halt_status); - if((!_hc->halt_pending)|| -// (!list_empty(&_hcd->non_periodic_sched_inactive)) - (_hcd->core_if->core_params->host_channels > 2)|| - (!_hc->ep_is_in)|| - (_hc->ep_type != DWC_OTG_EP_TYPE_BULK) - ) - { - continue_trans = 1; - } switch (_halt_status) { case DWC_OTG_HC_XFER_URB_COMPLETE: free_qtd = 1; @@ -839,7 +830,11 @@ static void release_channel(dwc_otg_hcd_t *_hcd, free_qtd = 0; break; } - + if(csplit_nak) + { + continue_trans = 0; + csplit_nak = 0; + } deactivate_qh(_hcd, _hc->qh, free_qtd); @@ -1214,6 +1209,7 @@ static int32_t handle_hc_nak_intr(dwc_otg_hcd_t *_hcd, if (_hc->complete_split) { _qtd->error_count = 0; } + csplit_nak = 1; _qtd->complete_split = 0; halt_channel(_hcd, _hc, _qtd, DWC_OTG_HC_XFER_NAK); goto handle_nak_done; @@ -1230,12 +1226,6 @@ static int32_t handle_hc_nak_intr(dwc_otg_hcd_t *_hcd, * occurs. The core will continue transferring data. */ _qtd->error_count = 0; - //yk@rk 20100714 - #if 1 - if((_hcd->core_if->core_params->host_channels <= 2) - &&(!_hc->halt_pending)) - dwc_otg_hc_halt(_hcd->core_if, _hc, DWC_OTG_HC_XFER_NAK); - #endif goto handle_nak_done; } @@ -1274,7 +1264,6 @@ static int32_t handle_hc_nak_intr(dwc_otg_hcd_t *_hcd, handle_nak_done: clear_hc_int(_hc_regs,nak); - if(_hcd->core_if->core_params->host_channels > 2) disable_hc_int(_hc_regs,nak); return 1; @@ -1734,23 +1723,6 @@ static void handle_hc_chhltd_intr_dma(dwc_otg_hcd_t *_hcd, hcint.d32 = dwc_read_reg32(&_hc_regs->hcint); hcintmsk.d32 = dwc_read_reg32(&_hc_regs->hcintmsk); - if((!hcint.b.xfercomp)&& - (_hcd->core_if->core_params->host_channels <= 2)&& - (_hc->halt_pending)&& - (_hc->ep_is_in)&& - (_hc->ep_type == DWC_OTG_EP_TYPE_BULK)) - { - if(hcint.b.ack && !hcintmsk.b.ack) - { - //DWC_PRINT("Halt pending, ack!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); - handle_hc_xfercomp_intr(_hcd, _hc, _hc_regs, _qtd); - return; - } - release_channel(_hcd, _hc, _qtd, DWC_OTG_HC_XFER_NAK); - clear_hc_int(_hc_regs,chhltd); - return; - } - if (hcint.b.xfercomp) { /** @todo This is here because of a possible hardware bug. Spec * says that on SPLIT-ISOC OUT transfers in DMA mode that a HALT @@ -1800,7 +1772,7 @@ static void handle_hc_chhltd_intr_dma(dwc_otg_hcd_t *_hcd, */ handle_hc_ack_intr(_hcd, _hc, _hc_regs, _qtd); } else if(hcint.b.datatglerr){ - DWC_PRINT("%s, DATA toggle error\n"); + DWC_PRINT("%s, DATA toggle error, Channel %d\n",__func__, _hc->hc_num); dwc_debug(1); clear_hc_int(_hc_regs,chhltd); } else { diff --git a/drivers/usb/dwc_otg/dwc_otg_hcd_queue.c b/drivers/usb/dwc_otg/dwc_otg_hcd_queue.c index 120080356f65..59abc4130ef7 100755 --- a/drivers/usb/dwc_otg/dwc_otg_hcd_queue.c +++ b/drivers/usb/dwc_otg/dwc_otg_hcd_queue.c @@ -143,7 +143,7 @@ void dwc_otg_hcd_qh_init(dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh, struct urb *_ur * _urb->dev->tt->hub may be null */ if((_urb->dev->tt)&&(!_urb->dev->tt->hub)) - printk("%s tt->hub null!\n",__func__); + DWC_PRINT("%s tt->hub null!\n",__func__); if (((_urb->dev->speed == USB_SPEED_LOW) || (_urb->dev->speed == USB_SPEED_FULL)) && (_urb->dev->tt) && (_urb->dev->tt->hub)&& @@ -241,9 +241,8 @@ static int periodic_channel_available(dwc_otg_hcd_t *_hcd) * non-periodic transactions. */ int status; -/*yk@rk modified for usb host 1.1*/ -#if 0 int num_channels; + num_channels = _hcd->core_if->core_params->host_channels; if ((_hcd->periodic_channels + _hcd->non_periodic_channels < num_channels) && (_hcd->periodic_channels < num_channels - 1)) { @@ -255,9 +254,7 @@ static int periodic_channel_available(dwc_otg_hcd_t *_hcd) _hcd->non_periodic_channels); status = -ENOSPC; } -#else - status = 0; -#endif + return status; } diff --git a/drivers/usb/dwc_otg/dwc_otg_pcd.c b/drivers/usb/dwc_otg/dwc_otg_pcd.c index 20ee3409bd06..c1fe4382d428 100755 --- a/drivers/usb/dwc_otg/dwc_otg_pcd.c +++ b/drivers/usb/dwc_otg/dwc_otg_pcd.c @@ -568,7 +568,7 @@ static int dwc_otg_pcd_ep_queue(struct usb_ep *_ep, /* 20091226,HSL@RK */ if ( !list_empty(&req->queue) ) { - printk("%s::ep %s req not empty,done it error!\n" , __func__, _ep->name); + DWC_PRINT("%s::ep %s req not empty,done it error!\n" , __func__, _ep->name); return -EINVAL; while(!list_empty(&req->queue) ) { ep = container_of(_ep, dwc_otg_pcd_ep_t, ep); @@ -1526,7 +1526,7 @@ int dwc_pcd_reset(dwc_otg_pcd_t *pcd) //rockchip_scu_reset_unit(12); dwc_otg_pcd_reinit( pcd ); dwc_otg_core_dev_init(core_if); - //printk("%s\n" , __func__ ); + //DWC_PRINT("%s\n" , __func__ ); dwc_otg_enable_global_interrupts( core_if ); return 0; } @@ -1589,7 +1589,7 @@ int dwc_otg_reset( void ) 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 ); - //printk("%s::otg reset connect!!!\n" , __func__ ); + //DWC_PRINT("%s::otg reset connect!!!\n" , __func__ ); return 0; } void dwc_otg_msc_lock(void) @@ -1605,7 +1605,6 @@ void dwc_otg_msc_unlock(void) android_unlock_suspend(&usb_msc_lock); #endif } -extern int dwc_step; static void dwc_phy_reconnect(struct work_struct *work) { dwc_otg_pcd_t *pcd; @@ -1618,23 +1617,17 @@ static void dwc_phy_reconnect(struct work_struct *work) gctrl.d32 = dwc_read_reg32( &core_if->core_global_regs->gotgctl ); if( gctrl.b.bsesvld ) { dwc_otg_msc_lock(); - pcd->vbus_status = 1; /* set after softconnect */ +// pcd->vbus_status = 1; /* set after softconnect */ pcd->conn_status++; dwc_pcd_reset(pcd); /* * Enable the global interrupt after all the interrupt * handlers are installed. */ - #if 0 - printk("debug while 1, please enter command to continue!\n"); - dwc_step = 1; - while(dwc_step) - mdelay(5); - #endif dctl.d32 = dwc_read_reg32( &core_if->dev_if->dev_global_regs->dctl ); dctl.b.sftdiscon = 0; dwc_write_reg32( &core_if->dev_if->dev_global_regs->dctl, dctl.d32 ); - printk("********soft connect!!!*****************************************\n"); + DWC_PRINT("********soft connect!!!*****************************************\n"); } } @@ -1654,19 +1647,24 @@ static void dwc_otg_pcd_check_vbus_timer( unsigned long pdata ) if( gctrl.b.bsesvld ) { /* if usb not connect before ,then start connect */ if( _pcd->vbus_status == 0 ) { - printk("********soft disconnect*****************************************\n"); + DWC_PRINT("********vbus detect*********************************************\n"); +// _pcd->conn_status = + _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); - schedule_delayed_work( &_pcd->reconnect , 8 ); /* delay 1 jiffies */ + 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(); - printk("********soft reconnect******************************************\n"); + DWC_PRINT("********soft reconnect******************************************\n"); _pcd->vbus_status =0; /* soft disconnect */ @@ -1676,6 +1674,12 @@ static void dwc_otg_pcd_check_vbus_timer( unsigned long pdata ) /* Clear any pending interrupts */ dwc_write_reg32( &core_if->core_global_regs->gintsts, 0xFFFFFFFF); } + 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*// @@ -1683,7 +1687,7 @@ static void dwc_otg_pcd_check_vbus_timer( unsigned long pdata ) _pcd->conn_status++; } } else { - //printk("new vbus=%d,old vbus=%d\n" , gctrl.b.bsesvld , _pcd->vbus_status ); + //DWC_PRINT("new vbus=%d,old vbus=%d\n" , gctrl.b.bsesvld , _pcd->vbus_status ); _pcd->vbus_status = 0; if(_pcd->conn_status) { @@ -1702,7 +1706,7 @@ static void dwc_otg_pcd_check_vbus_timer( unsigned long pdata ) } } - //printk("%s:restart check vbus timer\n" , __func__ ); + //DWC_PRINT("%s:restart check vbus timer\n" , __func__ ); add_timer(&_pcd->check_vbus_timer); local_irq_restore(flags); } @@ -1726,6 +1730,8 @@ int dwc_vbus_status( void ) dwc_otg_pcd_t *pcd = s_pcd; return pcd->vbus_status ; } +EXPORT_SYMBOL(dwc_vbus_status); + int dwc_otg_set_phy_status(uint8_t status) { dwc_otg_pcd_t *pcd = s_pcd; @@ -1744,7 +1750,7 @@ int dwc_otg_pcd_init(struct device *dev) dwc_otg_core_if_t *core_if = otg_dev->core_if; int retval = 0; int irq; - printk("dwc_otg_pcd_init,everest\n"); + DWC_PRINT("dwc_otg_pcd_init,everest\n"); /* * Allocate PCD structure */ @@ -1772,7 +1778,11 @@ int dwc_otg_pcd_init(struct device *dev) pcd->gadget.is_dualspeed = 0; pcd->gadget.is_otg = 0; pcd->driver = 0; - +#ifdef CONFIG_DWC_CONN_EN + pcd->conn_en = 1; +#else + pcd->conn_en = 0; +#endif /* Register the gadget device */ retval = device_register( &pcd->gadget.dev ); if(retval != 0) @@ -1825,7 +1835,7 @@ int dwc_otg_pcd_init(struct device *dev) if (pcd->setup_pkt == 0) { - printk("pcd->setup_pkt alloc fail,everest\n"); + DWC_PRINT("pcd->setup_pkt alloc fail,everest\n"); kfree (pcd); return -ENOMEM; } @@ -1951,7 +1961,7 @@ EXPORT_SYMBOL(usb_gadget_register_driver); */ int usb_gadget_unregister_driver(struct usb_gadget_driver *_driver) { - //DWC_DEBUGPL(DBG_PCDV,"%s(%p)\n", __func__, _driver); + DWC_DEBUGPL(DBG_PCDV,"%s(%p)\n", __func__, _driver); if (s_pcd == 0) { @@ -1974,18 +1984,4 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *_driver) return 0; } EXPORT_SYMBOL(usb_gadget_unregister_driver); -#else -int rk28_usb_suspend( int exitsuspend ) -{ - return 0; -} -int dwc_vbus_status( void ) -{ - return 0; -} -int get_msc_connect_flag( void ) -{ - return 0; -} - #endif /* DWC_HOST_ONLY */ diff --git a/drivers/usb/dwc_otg/dwc_otg_pcd.h b/drivers/usb/dwc_otg/dwc_otg_pcd.h index ec8f2f5790a0..7d44d18e391a 100755 --- a/drivers/usb/dwc_otg/dwc_otg_pcd.h +++ b/drivers/usb/dwc_otg/dwc_otg_pcd.h @@ -192,8 +192,11 @@ typedef struct dwc_otg_pcd /** vbus status in device mode */ uint8_t vbus_status; + /** enable connect to PC in device mode */ + uint8_t conn_en; + /** connect status used during enumeration */ - int16_t conn_status; + int8_t conn_status; /** Timer for check vbus at usb suspend. * every 500 ms. */ struct timer_list check_vbus_timer; diff --git a/drivers/usb/dwc_otg/dwc_otg_pcd_intr.c b/drivers/usb/dwc_otg/dwc_otg_pcd_intr.c index ed21e70295a5..ac3f936c8d47 100755 --- a/drivers/usb/dwc_otg/dwc_otg_pcd_intr.c +++ b/drivers/usb/dwc_otg/dwc_otg_pcd_intr.c @@ -1630,7 +1630,7 @@ static int32_t ep0_complete_request( dwc_otg_pcd_ep_t *_ep ) /* else if (req->req.zero) { - printk("%s--------------------------------------------------\n",__func__); + DWC_PRINT("%s--------------------------------------------------\n",__func__); req->req.actual = _ep->dwc_ep.xfer_count; //do_setup_in_status_phase (pcd); req->req.zero = 0; @@ -1777,7 +1777,7 @@ static void complete_ep( dwc_otg_pcd_ep_t *_ep ) } request_done(_ep, req, 0); } else { - printk("\n++++++FIND NULL req,ep=%s++++++++++\n" , _ep->ep.name ); + DWC_PRINT("\n++++++FIND NULL req,ep=%s++++++++++\n" , _ep->ep.name ); _ep->pcd->request_pending = 0; } _ep->dwc_ep.start_xfer_buff = 0; diff --git a/drivers/usb/dwc_otg/linux/dwc_otg_plat.h b/drivers/usb/dwc_otg/linux/dwc_otg_plat.h index 74008b6a5728..5bc5f78f8aab 100755 --- a/drivers/usb/dwc_otg/linux/dwc_otg_plat.h +++ b/drivers/usb/dwc_otg/linux/dwc_otg_plat.h @@ -41,16 +41,20 @@ #include #include +#include #define GRF_REG_BASE RK29_GRF_BASE #define USB20_OTG0_BASE RK29_USBOTG0_PHYS #define USB20_OTG1_BASE RK29_USBOTG1_PHYS #define USB11_HOST_BASE RK29_USBHOST_PHYS #define USBOTG_SIZE RK29_USBOTG0_SIZE -#define USB_GRF_CON (GRF_REG_BASE+0X9C) -#define USB_CLKGATE_CON (RK29_CRU_BASE+0X60) +#define USB_GRF_CON (GRF_REG_BASE+0x9C) +#define USB_GRF_IOMUX (GRF_REG_BASE+0x68) +#define USB_CLKGATE_CON (RK29_CRU_BASE+0x60) +#define USB_CLKSEL_CON (RK29_CRU_BASE+0x18) #ifndef SCU_BASE_ADDR_VA #define SCU_BASE_ADDR_VA RK29_CRU_BASE #endif +#define USB_IOMUX_INIT(a,b) rk29_mux_api_set(a,b) /** * @file * @@ -220,7 +224,7 @@ static inline uint32_t SET_DEBUG_LEVEL( const uint32_t _new ) #define DBG_OFF 0 /** Prefix string for DWC_DEBUG print macros. */ -#define USB_DWC "DWC_otg: " +#define USB_DWC "DWC_OTG: " /** * Print a debug message when the Global debug level variable contains @@ -240,8 +244,8 @@ static inline uint32_t SET_DEBUG_LEVEL( const uint32_t _new ) * */ #ifdef DEBUG -//# define DWC_DEBUGPL(lvl, x...) do{ if ((lvl)&g_dbg_lvl)printk( KERN_DEBUG USB_DWC x ); }while(0) -# define DWC_DEBUGPL(lvl, x...) printk( ">>> " x ) +# define DWC_DEBUGPL(lvl, x...) do{ if ((lvl)&g_dbg_lvl)printk( KERN_DEBUG USB_DWC x ); }while(0) +//# define DWC_DEBUGPL(lvl, x...) printk( ">>> " x ) # define DWC_DEBUGP(x...) DWC_DEBUGPL(DBG_ANY, x ) # define CHK_DEBUG_LEVEL(level) ((level) & g_dbg_lvl) diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c old mode 100644 new mode 100755 index dbc394ae33c9..8bdf100be5dc --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -68,6 +68,7 @@ #include #include #include +#include #include #include @@ -468,8 +469,7 @@ static void put_be32(u8 *buf, u32 val) static void set_msc_connect_flag( int connected ) { - //GPIOSetPinLevel(CHARGE_OK_PIN,GPIO_LOW); - printk("set usb_msc_connect status = %d 20100520\n" , connected); + printk("%s status = %d 20101216\n" , __func__, connected); if( usb_msc_connected == connected ) return; usb_msc_connected = connected;//usb mass storage is ok @@ -479,6 +479,7 @@ int get_msc_connect_flag( void ) { return usb_msc_connected; } +EXPORT_SYMBOL(get_msc_connect_flag); /*-------------------------------------------------------------------------*/ @@ -2936,10 +2937,63 @@ static void fsg_function_disable(struct usb_function *f) set_msc_connect_flag(0); } +static enum power_supply_property usb_props[] = { +// POWER_SUPPLY_PROP_STATUS, + POWER_SUPPLY_PROP_ONLINE, +}; + +static int usb_get_property(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + int ret = 0; + + switch (psp) { + case POWER_SUPPLY_PROP_ONLINE: + #ifdef CONFIG_DWC_OTG_DEVICE_ONLY + val->intval = get_msc_connect_flag(); + #else + val->intval = 0; + #endif + break; + default: + return -EINVAL; + } + + return ret; +} + +int usb_power_supply_register(struct device* parent) +{ + struct power_supply *ps; + int retval = 0; + + ps = kzalloc(sizeof(*ps), GFP_KERNEL); + if (!ps) { + dev_err(parent, "failed to allocate power supply data\n"); + retval = -ENOMEM; + goto out; + } + ps->name = "usb"; + ps->type = POWER_SUPPLY_TYPE_USB; + ps->properties = usb_props; + ps->num_properties = ARRAY_SIZE(usb_props); + ps->get_property = usb_get_property; + ps->external_power_changed = NULL; + retval = power_supply_register(parent, ps); + if (retval) { + dev_err(parent, "failed to register battery\n"); + goto out; + } +out: + return retval; +} + static int __init fsg_probe(struct platform_device *pdev) { struct usb_mass_storage_platform_data *pdata = pdev->dev.platform_data; struct fsg_dev *fsg = the_fsg; + int retval = 0; fsg->pdev = pdev; printk(KERN_INFO "fsg_probe pdata: %p\n", pdata); @@ -2956,7 +3010,16 @@ static int __init fsg_probe(struct platform_device *pdev) fsg->nluns = pdata->nluns; } - return 0; + /* + * Initialize usb power supply + */ + retval = usb_power_supply_register(&pdev->dev); + if (retval != 0) + { + dev_err(&pdev->dev, "usb_power_supply_register failed\n"); + } + + return retval; } static struct platform_driver fsg_platform_driver = { diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c old mode 100644 new mode 100755 index 7c8f64d842f2..33197fa22715 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c @@ -74,7 +74,7 @@ MODULE_AUTHOR("Matthew Dharm "); MODULE_DESCRIPTION("USB Mass Storage driver for Linux"); MODULE_LICENSE("GPL"); -static unsigned int delay_use = 1; +static unsigned int delay_use = 5; module_param(delay_use, uint, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(delay_use, "seconds to delay before using a new device"); -- 2.34.1