rk3026: usb: wake up by otg id & bvalid

This commit is contained in:
lyz
2013-08-02 18:50:31 +08:00
parent ef39e5ccd3
commit 28a0dc45bf
3 changed files with 119 additions and 73 deletions

View File

@@ -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 <linux/io.h>
#include <mach/iomux.h>
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

View File

@@ -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)
{

View File

@@ -3,11 +3,19 @@
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/wakelock.h>
#include <linux/workqueue.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <mach/irqs.h>
#include <mach/gpio.h>
#include <mach/iomux.h>
#include <mach/cru.h>
#include <mach/board.h>
#ifdef CONFIG_RK_CONFIG
#include <mach/config.h>
#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