From 500dfa4c3d02e3d899b38d29a769830b84bc648e Mon Sep 17 00:00:00 2001 From: yangkai Date: Wed, 29 Dec 2010 11:51:06 +0800 Subject: [PATCH] add usb phy suspend in host mode, modify default usb id --- arch/arm/mach-rk29/devices.c | 8 +-- drivers/usb/dwc_otg/dwc_otg_cil.c | 6 +- drivers/usb/dwc_otg/dwc_otg_cil.h | 2 +- drivers/usb/dwc_otg/dwc_otg_cil_intr.c | 2 +- drivers/usb/dwc_otg/dwc_otg_driver.c | 27 +++++++-- drivers/usb/dwc_otg/dwc_otg_hcd.c | 77 ++++++++++++++++++++++++++ drivers/usb/dwc_otg/dwc_otg_hcd.h | 1 - drivers/usb/dwc_otg/dwc_otg_pcd.c | 2 +- 8 files changed, 110 insertions(+), 15 deletions(-) diff --git a/arch/arm/mach-rk29/devices.c b/arch/arm/mach-rk29/devices.c index 6f5cb47f118b..73008be7b96b 100755 --- a/arch/arm/mach-rk29/devices.c +++ b/arch/arm/mach-rk29/devices.c @@ -604,12 +604,12 @@ static char *usb_functions_all[] = { static struct android_usb_product usb_products[] = { { - .product_id = 0x2810,//0x0c02,//0x4e11, + .product_id = 0x2910,//0x0c02,//0x4e11, .num_functions = ARRAY_SIZE(usb_functions_rockchip), .functions = usb_functions_rockchip, }, { - .product_id = 0x2810,//0x0c02,//0x4e12, + .product_id = 0x0c02,//0x0c02,//0x4e12, .num_functions = ARRAY_SIZE(usb_functions_rockchip_adb), .functions = usb_functions_rockchip_adb, }, @@ -637,9 +637,9 @@ static struct android_usb_product usb_products[] = { */ static struct android_usb_platform_data android_usb_pdata = { .vendor_id = 0x0bb4,//0x2207,//0x0bb4,//0x18d1, - .product_id = 0x4e11,//0x2810,//0x4e11, + .product_id = 0x4e11,//0x2910,//0x4e11, .version = 0x0100, - .product_name = "rk2818 sdk", + .product_name = "rk2918 sdk", .manufacturer_name = "RockChip", .num_products = ARRAY_SIZE(usb_products), .products = usb_products, diff --git a/drivers/usb/dwc_otg/dwc_otg_cil.c b/drivers/usb/dwc_otg/dwc_otg_cil.c index 387d1e4c7126..0d8042b6e16f 100755 --- a/drivers/usb/dwc_otg/dwc_otg_cil.c +++ b/drivers/usb/dwc_otg/dwc_otg_cil.c @@ -3339,8 +3339,10 @@ void dwc_otg_dump_flags(dwc_otg_core_if_t *_core_if) int dwc_debug(dwc_otg_core_if_t *core_if, int flag) { //dwc_otg_core_if_t *core_if = dwc_core_if; + #ifdef CONFIG_DWC_OTG_DEVICE_ONLY + dwc_otg_pcd_t * pcd; + #endif struct dwc_otg_device *otg_dev; - dwc_otg_pcd_t * pcd; switch(flag) { case 1: @@ -3348,9 +3350,11 @@ int dwc_debug(dwc_otg_core_if_t *core_if, int flag) dwc_otg_dump_host_registers(core_if); break; case 2: + #ifdef CONFIG_DWC_OTG_DEVICE_ONLY otg_dev = core_if->otg_dev; pcd = otg_dev->pcd; pcd->vbus_status = 0; + #endif break; case 3: dump_scu_regs(); diff --git a/drivers/usb/dwc_otg/dwc_otg_cil.h b/drivers/usb/dwc_otg/dwc_otg_cil.h index 003c689cfbc4..a385a26a80ae 100755 --- a/drivers/usb/dwc_otg/dwc_otg_cil.h +++ b/drivers/usb/dwc_otg/dwc_otg_cil.h @@ -909,7 +909,7 @@ typedef struct dwc_otg_cil_callbacks /** Resume/Remote wakeup Function */ int (*resume_wakeup) (void *_p); /** Suspend function */ - int (*suspend) (void *_p); + int (*suspend) (void *_p, int suspend); /** Session Start (SRP) */ int (*session_start) (void *_p); /** Pointer passed to start() and stop() */ diff --git a/drivers/usb/dwc_otg/dwc_otg_cil_intr.c b/drivers/usb/dwc_otg/dwc_otg_cil_intr.c index a86169f1241f..d2a78d7971c6 100755 --- a/drivers/usb/dwc_otg/dwc_otg_cil_intr.c +++ b/drivers/usb/dwc_otg/dwc_otg_cil_intr.c @@ -146,7 +146,7 @@ static inline void pcd_stop( dwc_otg_core_if_t *_core_if ) static inline void pcd_suspend( dwc_otg_core_if_t *_core_if ) { if (_core_if->pcd_cb && _core_if->pcd_cb->suspend ) { - _core_if->pcd_cb->suspend( _core_if->pcd_cb->p ); + _core_if->pcd_cb->suspend( _core_if->pcd_cb->p, 0); } } /** Resume the PCD. Helper function for using the PCD callbacks. diff --git a/drivers/usb/dwc_otg/dwc_otg_driver.c b/drivers/usb/dwc_otg/dwc_otg_driver.c index 0f53243432e0..56cefcc65b6d 100755 --- a/drivers/usb/dwc_otg/dwc_otg_driver.c +++ b/drivers/usb/dwc_otg/dwc_otg_driver.c @@ -352,7 +352,7 @@ static ssize_t dwc_otg_enable_store( struct device *_dev, otg_dev->hcd->host_enabled = val; if(val == 0) // enable -> disable { - DWC_PRINT("disable host controller:%s\n",pdev->name); + DWC_PRINT("disable host controller:%s,id:%d\n",pdev->name,pdev->id); #if 1 if (_core_if->hcd_cb && _core_if->hcd_cb->disconnect) { _core_if->hcd_cb->disconnect( _core_if->hcd_cb->p ); @@ -363,12 +363,19 @@ static ssize_t dwc_otg_enable_store( struct device *_dev, } clk_disable(otg_dev->phyclk); clk_disable(otg_dev->ahbclk); + if (_core_if->hcd_cb && _core_if->hcd_cb->suspend) { + _core_if->hcd_cb->suspend( _core_if->hcd_cb->p, val); + } } else if(val == 1) { DWC_PRINT("enable host controller:%s\n",pdev->name); + if (_core_if->hcd_cb && _core_if->hcd_cb->suspend) { + _core_if->hcd_cb->suspend( _core_if->hcd_cb->p, val); + } clk_enable(otg_dev->phyclk); clk_enable(otg_dev->ahbclk); + mdelay(5); if (_core_if->hcd_cb && _core_if->hcd_cb->start) { _core_if->hcd_cb->start( _core_if->hcd_cb->p ); } @@ -384,6 +391,8 @@ static ssize_t dwc_otg_conn_en_show(struct device_driver *_drv, char *_buf) dwc_otg_device_t *otg_dev = g_otgdev; dwc_otg_pcd_t *_pcd = otg_dev->pcd; return sprintf (_buf, "%d\n", _pcd->conn_en); +#else + return sprintf(_buf, "0\n"); #endif } @@ -397,8 +406,8 @@ static ssize_t dwc_otg_conn_en_store(struct device_driver *_drv, const char *_bu DWC_PRINT("%s %d->%d\n",__func__, _pcd->conn_en, enable); _pcd->conn_en = enable; - return _count; #endif + return _count; } static DRIVER_ATTR(dwc_otg_conn_en, S_IRUGO|S_IWUSR, dwc_otg_conn_en_show, dwc_otg_conn_en_store); #ifdef CONFIG_DWC_OTG_DEVICE_ONLY @@ -1135,8 +1144,10 @@ static __devinit int dwc_otg_driver_probe(struct platform_device *pdev) dwc_otg_enable_global_interrupts( dwc_otg_device->core_if ); #ifdef CONFIG_DWC_OTG_HOST_ONLY #ifndef CONFIG_USB20_OTG_EN - clk_disable(otg_dev->phyclk); - clk_disable(otg_dev->ahbclk); + clk_disable(dwc_otg_device->phyclk); + clk_disable(dwc_otg_device->ahbclk); + *otg_phy_con1 |= (0x01<<2); + *otg_phy_con1 &= ~(0x01<<3); // enter suspend. #endif #endif DWC_PRINT("dwc_otg_driver_probe end, everest\n"); @@ -1393,7 +1404,7 @@ static __devinit int host11_driver_probe(struct platform_device *pdev) retval = -ENOMEM; goto fail; } - DWC_DEBUGPL( DBG_CIL, "base addr for rk28 host11:0x%x\n", (unsigned)dwc_otg_device->base); + DWC_DEBUGPL( DBG_CIL, "base addr for rk29 host11:0x%x\n", (unsigned)dwc_otg_device->base); /* * Attempt to ensure this device is really a DWC_otg Controller. * Read and verify the SNPSID register contents. The value should be @@ -1487,6 +1498,7 @@ static __devinit int host11_driver_probe(struct platform_device *pdev) */ dwc_otg_enable_global_interrupts( dwc_otg_device->core_if ); #ifndef CONFIG_USB11_HOST_EN + *otg_phy_con1 |= (0x01<<28); // enter suspend. clk_disable(phyclk); clk_disable(ahbclk); #endif @@ -1684,7 +1696,7 @@ static __devinit int host20_driver_probe(struct platform_device *pdev) retval = -ENOMEM; goto fail; } - DWC_DEBUGPL( DBG_CIL, "base addr for rk28 host11:0x%x\n", (unsigned)dwc_otg_device->base); + DWC_DEBUGPL( DBG_CIL, "base addr for rk29 host20: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 @@ -1781,6 +1793,9 @@ static __devinit int host20_driver_probe(struct platform_device *pdev) #ifndef CONFIG_USB20_HOST_EN clk_disable(phyclk); clk_disable(ahbclk); + otgreg &= ~(0x01<<14); // suspend. + otgreg |= (0x01<<13); // software control + *otg_phy_con1 = otgreg; #endif DWC_PRINT("host20_driver_probe end, everest\n"); return 0; diff --git a/drivers/usb/dwc_otg/dwc_otg_hcd.c b/drivers/usb/dwc_otg/dwc_otg_hcd.c index ff0453726a58..7ff7db6ea73c 100755 --- a/drivers/usb/dwc_otg/dwc_otg_hcd.c +++ b/drivers/usb/dwc_otg/dwc_otg_hcd.c @@ -543,6 +543,31 @@ static int32_t dwc_otg_hcd_session_start_cb( void *_p ) return 1; } +/* + * suspend: 0 usb phy enable + * 1 usb phy suspend + */ +static int32_t dwc_otg_phy_suspend_cb( void *_p, int suspend) +{ + unsigned int * otg_phy_con1 = (unsigned int*)(USB_GRF_CON); + + if(suspend) { + *otg_phy_con1 |= (0x01<<2); + *otg_phy_con1 |= (0x01<<3); // exit suspend. + *otg_phy_con1 &= ~(0x01<<2); + + DWC_DEBUGPL(DBG_PCDV, "enable usb phy\n"); + } + else + { + *otg_phy_con1 |= (0x01<<2); + *otg_phy_con1 &= ~(0x01<<3); // enter suspend. + DWC_DEBUGPL(DBG_PCDV, "disable usb phy\n"); + } + + return suspend; +} + /** * HCD Callback structure for handling mode switching. */ @@ -551,6 +576,7 @@ static dwc_otg_cil_callbacks_t hcd_cil_callbacks = { .stop = dwc_otg_hcd_stop_cb, .disconnect = dwc_otg_hcd_disconnect_cb, .session_start = dwc_otg_hcd_session_start_cb, + .suspend = dwc_otg_phy_suspend_cb, .p = 0,//hcd }; @@ -738,11 +764,32 @@ int __devinit dwc_otg_hcd_init(struct device *dev) } #ifdef CONFIG_USB11_HOST +/* + * suspend: 0 usb phy enable + * 1 usb phy suspend + */ +static int32_t host11_phy_suspend_cb( void *_p, int suspend) +{ + unsigned int * otg_phy_con1 = (unsigned int*)(USB_GRF_CON); + + if(suspend) { + *otg_phy_con1 &= ~(0x01<<28); + DWC_DEBUGPL(DBG_PCDV, "enable usb phy\n"); + } + else + { + *otg_phy_con1 |= (0x01<<28); + DWC_DEBUGPL(DBG_PCDV, "disable usb phy\n"); + } + + return suspend; +} 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, + .suspend = host11_phy_suspend_cb, .p = 0,//hcd }; @@ -904,11 +951,41 @@ int __devinit host11_hcd_init(struct device *dev) } #endif #ifdef CONFIG_USB20_HOST + +/* + * suspend: 0 usb phy enable + * 1 usb phy suspend + */ +static int32_t host20_phy_suspend_cb( void *_p, int suspend) +{ + unsigned int * otg_phy_con1 = (unsigned int*)(USB_GRF_CON); + uint32_t regval; + + regval = *otg_phy_con1; + + if(suspend) { + regval |= (0x01<<14); // exit suspend. + regval &= ~(0x01<<13); + + DWC_DEBUGPL(DBG_PCDV, "enable usb phy\n"); + } + else + { + regval &= ~(0x01<<14); // exit suspend. + regval |= (0x01<<13); // software control + DWC_DEBUGPL(DBG_PCDV, "disable usb phy\n"); + } + *otg_phy_con1 = regval; + + return suspend; +} + 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, .session_start = dwc_otg_hcd_session_start_cb, + .suspend = host20_phy_suspend_cb, .p = 0,//hcd }; diff --git a/drivers/usb/dwc_otg/dwc_otg_hcd.h b/drivers/usb/dwc_otg/dwc_otg_hcd.h index 262f2289dd05..a9253e7dd2da 100755 --- a/drivers/usb/dwc_otg/dwc_otg_hcd.h +++ b/drivers/usb/dwc_otg/dwc_otg_hcd.h @@ -403,7 +403,6 @@ static inline struct usb_hcd *dwc_otg_hcd_to_hcd(dwc_otg_hcd_t *dwc_otg_hcd) /** @{ */ extern int __init dwc_otg_hcd_init(struct device *_dev); extern void dwc_otg_hcd_remove(struct device *_dev); -extern int __init rk28_host11_hcd_init(struct device *_dev); /** @} */ /** @name Linux HC Driver API Functions */ diff --git a/drivers/usb/dwc_otg/dwc_otg_pcd.c b/drivers/usb/dwc_otg/dwc_otg_pcd.c index be70bd083b84..c574339595bd 100755 --- a/drivers/usb/dwc_otg/dwc_otg_pcd.c +++ b/drivers/usb/dwc_otg/dwc_otg_pcd.c @@ -1091,7 +1091,7 @@ static int32_t dwc_otg_pcd_stop_cb( void *_p ) * * @param _p void pointer to the dwc_otg_pcd_t */ -static int32_t dwc_otg_pcd_suspend_cb( void *_p ) +static int32_t dwc_otg_pcd_suspend_cb( void *_p ,int suspend) { dwc_otg_pcd_t *pcd = (dwc_otg_pcd_t *)_p; #ifdef CONFIG_ANDROID_POWER -- 2.34.1