From 28a0dc45bfd1cdd63416d6140df9ec42252af52d Mon Sep 17 00:00:00 2001 From: lyz Date: Fri, 2 Aug 2013 18:50:31 +0800 Subject: [PATCH] rk3026: usb: wake up by otg id & bvalid --- arch/arm/plat-rk/usb_detect.c | 51 +------------ drivers/usb/dwc_otg/dwc_otg_cil.c | 28 ++----- drivers/usb/dwc_otg/usbdev_rk3026.c | 113 +++++++++++++++++++++++++++- 3 files changed, 119 insertions(+), 73 deletions(-) diff --git a/arch/arm/plat-rk/usb_detect.c b/arch/arm/plat-rk/usb_detect.c index 4754d639d66e..1359512f8013 100755 --- a/arch/arm/plat-rk/usb_detect.c +++ b/arch/arm/plat-rk/usb_detect.c @@ -145,57 +145,8 @@ static int __init bvalid_init(void) return 0; } +#if defined(CONFIG_ARCH_RK2928) || defined(CONFIG_ARCH_RK3188) late_initcall(bvalid_init); #endif - -#if 0 -#include -#include - -static irqreturn_t otg_id_irq_handler(int irq, void *dev_id) -{ - unsigned int uoc_con; - /* clear irq */ - uoc_con = readl_relaxed(RK2928_GRF_BASE + GRF_UOC_CON); - - - - if(uoc_con & (1<<1)) //id rise - { - writel_relaxed((0x1 << 16) | 0x1, RK2928_GRF_BASE + GRF_UOC_CON);;//clear id rise irq pandding - } - if(uoc_con & (1<<3))//id fall - { -#ifdef CONFIG_RK_USB_UART - //if(!(readl_relaxed(RK2928_GRF_BASE + 0x014c) & (1<<10))){//id low - writel_relaxed(0x04000000, RK2928_GRF_BASE + GRF_UOC1_CON0); //enter usb phy - } -#endif - writel_relaxed((0x3 << 16) | 0x3, RK2928_GRF_BASE + GRF_UOC_CON);//clear id fall irq pandding - - rk28_send_wakeup_key(); - return IRQ_HANDLED; -} - -static int __init otg_id_irq_init(void) -{ - int ret; - int irq = IRQ_OTG0_ID; - - ret = request_irq(irq, otg_id_irq_handler, 0, "otg_id_change", NULL); - if (ret < 0) { - pr_err("%s: request_irq(%d) failed\n", __func__, irq); - return ret; - } - - /* clear & enable otg change irq */ - /* for rk3026 enable and clear id_fall_irq & id_rise_irq*/ - writel_relaxed((0xf << 16) | 0xf, RK2928_GRF_BASE + GRF_UOC_CON); - - enable_irq_wake(irq); - - return 0; -} -late_initcall(otg_id_irq_init); #endif diff --git a/drivers/usb/dwc_otg/dwc_otg_cil.c b/drivers/usb/dwc_otg/dwc_otg_cil.c index 9f02d63ee66f..f14534394a4c 100755 --- a/drivers/usb/dwc_otg/dwc_otg_cil.c +++ b/drivers/usb/dwc_otg/dwc_otg_cil.c @@ -722,8 +722,12 @@ void dwc_otg_core_dev_init(dwc_otg_core_if_t *_core_if) dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[0], 0x01000220 ); //ep1 tx fifo dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[1], 0x00100320 ); //ep3 tx fifo dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[2], 0x00800330 ); //ep5 tx fifo -#endif -#if defined(CONFIG_ARCH_RK30) || defined(CONFIG_ARCH_RK3188) +#else + +#if !(defined(CONFIG_ARCH_RK30) || defined(CONFIG_ARCH_RK3188) || \ + defined(CONFIG_ARCH_RK2928)|| defined(CONFIG_ARCH_RK3026) ) + DWC_ERROR("Warning!!! Please Check USB Controller FIFO Configuration\n"); +#endif /* Configure data FIFO sizes, RK30 otg has 0x3cc dwords total */ dwc_write_reg32( &global_regs->grxfsiz, 0x00000120 ); dwc_write_reg32( &global_regs->gnptxfsiz, 0x00100120 ); //ep0 tx fifo @@ -733,26 +737,6 @@ void dwc_otg_core_dev_init(dwc_otg_core_if_t *_core_if) dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[3], 0x00800330 ); //ep7 tx fifo dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[4], 0x001003b0 ); //ep9 tx fifo #endif -#ifdef CONFIG_ARCH_RK2928 - /* Configure data FIFO sizes, RK30 otg has 0x3cc dwords total */ - dwc_write_reg32( &global_regs->grxfsiz, 0x00000120 ); - dwc_write_reg32( &global_regs->gnptxfsiz, 0x00100120 ); //ep0 tx fifo - dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[0], 0x01000130 ); //ep1 tx fifo 256*4Byte - dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[1], 0x00800230 ); //ep3 tx fifo 128*4Byte - dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[2], 0x008002b0 ); //ep5 tx fifo 128*4Byte - dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[3], 0x00800330 ); //ep7 tx fifo 128*4Byte - dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[4], 0x001003b0 ); //ep9 tx fifo 16*4Byte -#endif -#ifdef CONFIG_ARCH_RK3026 - /* Configure data FIFO sizes, RK30 otg has 0x3cc dwords total */ - dwc_write_reg32( &global_regs->grxfsiz, 0x00000120 ); - dwc_write_reg32( &global_regs->gnptxfsiz, 0x00100120 ); //ep0 tx fifo - dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[0], 0x01000130 ); //ep1 tx fifo 256*4Byte - dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[1], 0x00800230 ); //ep3 tx fifo 128*4Byte - dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[2], 0x008002b0 ); //ep5 tx fifo 128*4Byte - dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[3], 0x00800330 ); //ep7 tx fifo 128*4Byte - dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[4], 0x001003b0 ); //ep9 tx fifo 16*4Byte -#endif if(_core_if->en_multiple_tx_fifo && _core_if->dma_enable) { diff --git a/drivers/usb/dwc_otg/usbdev_rk3026.c b/drivers/usb/dwc_otg/usbdev_rk3026.c index dd510dfba970..c31496cf03f9 100755 --- a/drivers/usb/dwc_otg/usbdev_rk3026.c +++ b/drivers/usb/dwc_otg/usbdev_rk3026.c @@ -3,11 +3,19 @@ #include #include #include +#include +#include +#include +#include +#include #include #include #include #include +#include + + #ifdef CONFIG_RK_CONFIG #include #endif @@ -124,7 +132,7 @@ void usb20otg_phy_suspend(void* pdata, int suspend) } void usb20otg_soft_reset(void) { -#if 0 //@lyz todo for 3028 phy +#if 1 //@lyz todo for 3028 phy printk("~~~~~~~~~~usb20otg_soft_reset\n"); //phy reset *(unsigned int*)(USBGRF_UOC0_CON0) = 0x00030001; @@ -414,5 +422,108 @@ static int __init usbdev_init_devices(void) return ret; } arch_initcall(usbdev_init_devices); + + +/********************************************************************* + rk3026 usb detect +*********************************************************************/ + +#define WAKE_LOCK_TIMEOUT (HZ * 10) + +static struct wake_lock usb_wakelock; +static struct delayed_work usb_det_wakeup_work; + +inline void do_wakeup(void) +{ + wake_lock_timeout(&usb_wakelock, WAKE_LOCK_TIMEOUT); + rk28_send_wakeup_key(); +} + + +/*********** handler for bvalid irq ***********/ + +static irqreturn_t bvalid_irq_handler(int irq, void *dev_id) +{ + /* clear irq */ + writel_relaxed((1 << 31) | (1 << 15), RK2928_GRF_BASE + GRF_UOC0_CON0); + +#ifdef CONFIG_RK_USB_UART + /* usb otg dp/dm switch to usb phy */ + writel_relaxed((3 << (12 + 16)),RK2928_GRF_BASE + GRF_UOC1_CON4); +#endif + + schedule_delayed_work(&usb_det_wakeup_work, HZ/10); + + return IRQ_HANDLED; +} + +/***** handler for otg id rise and fall edge *****/ + +static irqreturn_t id_irq_handler(int irq, void *dev_id) +{ + unsigned int uoc_con; + + /* clear irq */ + uoc_con = readl_relaxed(RK2928_GRF_BASE + GRF_UOC_CON); + if(uoc_con & (1<<1))//id rise + { + writel_relaxed((0x2 << 16) | 0x2, RK2928_GRF_BASE + GRF_UOC_CON);//clear id rise irq pandding + } + if(uoc_con & (1<<3))//id fall + { + writel_relaxed((0x8 << 16) | 0x8, RK2928_GRF_BASE + GRF_UOC_CON);//clear id fall irq pandding + } + schedule_delayed_work(&usb_det_wakeup_work, HZ/10); + return IRQ_HANDLED; +} + +/***** handler for otg line status change *****/ + +static irqreturn_t line_irq_handler(int irq, void *dev_id) +{ + + /* clear irq */ + writel_relaxed((1 << 29) | (1 << 13), RK2928_GRF_BASE + GRF_UOC0_CON0); + + schedule_delayed_work(&usb_det_wakeup_work, HZ/10); + return IRQ_HANDLED; +} + + +static int __init otg_irq_detect_init(void) +{ + int ret; + int irq = IRQ_OTG_BVALID; + + wake_lock_init(&usb_wakelock, WAKE_LOCK_SUSPEND, "usb_detect"); + INIT_DELAYED_WORK(&usb_det_wakeup_work, do_wakeup); + + ret = request_irq(irq, bvalid_irq_handler, 0, "bvalid", NULL); + if (ret < 0) { + pr_err("%s: request_irq(%d) failed\n", __func__, irq); + return ret; + } + + /* clear & enable bvalid irq */ + writel_relaxed((3 << 30) | (3 << 14), RK2928_GRF_BASE + GRF_UOC0_CON0); + + + irq = IRQ_OTG0_ID; + + ret = request_irq(irq, id_irq_handler, 0, "otg-id", NULL); + if (ret < 0) { + pr_err("%s: request_irq(%d) failed\n", __func__, irq); + return ret; + } + + /* clear & enable otg change irq */ + /* for rk3026 enable and clear id_fall_irq & id_rise_irq*/ + writel_relaxed((0xf << 16) | 0xf, RK2928_GRF_BASE + GRF_UOC_CON); + + enable_irq_wake(irq); + + return 0; +} +late_initcall(otg_irq_detect_init); #endif -- 2.34.1