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
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
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)
{
#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
}
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;
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