/*! * pcd_bwkup_int_hndlr() - wakeup interrupt * @param irq * @param dev_id * @param regs */ static irqreturn_t pcd_bwkup_int_hndlr(int irq, void *dev_id) { u32 sys_ctrl = fs_rl(OTG_SYS_CTRL); //static int bwkup_count = 0; //TRACE_MSG2(otg->ocd->TAG, "SYS_CTRL: %08x CORE_CLK: %08x", sys_ctrl, fs_rl(OTG_CORE_CLK_CTRL)); //printk(KERN_INFO"%s: %08x CORE_CLK: %08x\n", __FUNCTION__, sys_ctrl, fs_rl(OTG_CORE_CLK_CTRL)); //fs_wl(OTG_SYS_CTRL, sys_ctrl & ~0x0F000000); mxc_main_clock_on(); // turn on Main Clock mxc_func_clock_on(); // turn on Function Clock //if (bwkup_count++ > 10) // fs_wl(OTG_SYS_CTRL, 0); return IRQ_HANDLED; }
/*! * ocd_ctrl_int_hndlr - Control and I2C interrupt * Process USBOTG related interrupts. * @param irq * @param dev_id * @param regs */ static irqreturn_t ocd_ctrl_int_hndlr(int irq, void *dev_id) { u32 sys_ctrl = fs_rl(OTG_SYS_CTRL); // C.f. 23.8 USB Control Register u32 cint_stat = fs_rl(OTG_CORE_CINT_STAT); // C.f. 23.9.2 USBOTG Module Interrupt Status Register u32 hint_stat = fs_rl(OTG_CORE_HINT_STAT); // C.f. 23.9.12 HNP Interrupt Status Register u32 hnp_cstat = fs_rl(OTG_CORE_HNP_CSTAT); static u32 ocd_interrupts = 0; /* N.B. OTG_CORE_CINT_STAT interrupts are self clearing when interrupt * sources have been cleared. */ RETURN_IRQ_HANDLED_UNLESS(cint_stat || hint_stat); //if (sys_ctrl & (SYS_CTRL_HOST_WU_INT_STAT | SYS_CTRL_FNT_WU_INT_STAT)) // TRACE_MSG1(OCD, "SYS_CTRL: HOST/FUNC %08x", sys_ctrl); //TRACE_MSG4(OCD, "CLK: %08x sys: %08x cint: %08x hint: %08x", fs_rl(OTG_CORE_CLK_CTRL), sys_ctrl, cint_stat, hint_stat); if (hint_stat) { //if (hint_stat & HNP_I2COTGINT) // TRACE_MSG1(OCD, "OTG_CORE_HINT_STAT HNP_I2COTGINT %08x ignored (periodic?)", hint_stat); fs_wl(OTG_CORE_HINT_STAT, hint_stat); printk(KERN_INFO"%s: HINT_STAT: %08x HNP_CSTAT: %08x\n", __FUNCTION__, hint_stat, hnp_cstat); } if (cint_stat & MODULE_ASHNPINT) { // asynchronous HNP interrupt, enable Main clock u32 hnp_cstat = fs_rl(OTG_CORE_HNP_CSTAT); u32 hint_stat = fs_rl(OTG_CORE_HINT_STAT); //TRACE_MSG1(OCD, "MODULE_ASHNPINT %08x", hint_stat); mxc_main_clock_on(); // turn on Main Clock //if (hnp_cstat & MODULE_ISBDEV) // TRACE_MSG0(OCD, "ISBDEV"); //if (hnp_cstat & MODULE_ISADEV) // TRACE_MSG0(OCD, "ISADEV"); //fs_wl_set(OCD, OTG_CORE_HINT_STAT, hint_stat); fs_wl(OTG_CORE_HINT_STAT, hint_stat); ocd_hnp_int_hndlr(irq, dev_id); } if (cint_stat & MODULE_ASFCINT) { // Asynchronous Function interrupt, enable Func clock //TRACE_MSG1(OCD, "MODULE_ASFCINT %08x", cint_stat); // XXX otg_queue_event(ocd_instance->otg, B_SESS_VLD | A_SESS_VLD, PCD, "MX2ADS ASFCINT"); mxc_func_clock_on(); // turn on Function Clock } if (cint_stat & MODULE_ASHCINT) { // Asynchronous Host interrupt, enable Host clock //TRACE_MSG1(OCD, "MODULE_ASHCINT %08x", cint_stat); mxc_host_clock_on(); // turn on Host Clock } if ((cint_stat & MODULE_HNPINT) || hint_stat) // HNP interrupt ocd_hnp_int_hndlr(irq, dev_id); if (cint_stat & MODULE_FCINT) mxc_pcd_int_hndlr(); if (cint_stat & MODULE_HCINT) { //TRACE_MSG1(OCD, "MODULE_HCINT %08x", cint_stat); mxc_hcd_hw_int_hndlr(irq, NULL); } return IRQ_HANDLED; }
/*! * zasevb_tcd_mod_init() - initial tcd setup * This performs the platform specific hardware setup for the MX2ADS. */ int zasevb_tcd_mod_init (void) { int i2c = 1; int gpio = 1; /* ------------------------------------------------------------------------ */ #ifdef CONFIG_OTG_ZASEVB_DIFFERENTIAL_UNIDIRECTIONAL int hwmode = XCVR_D_SE0_NEW; int newmode = XCVR_D_D; isp1301_tx_mode_t tx_mode = vp_vm_unidirectional; // MXC91231 ok printk (KERN_INFO"Current setting is DIFFERENTIAL UNIDIRECTIONAL\n"); /* ------------------------------------------------------------------------ */ #elif CONFIG_OTG_ZASEVB_SINGLE_ENDED_UNIDIRECTIONAL int hwmode = XCVR_SE0_D_NEW; int newmode = XCVR_SE0_D_NEW; isp1301_tx_mode_t tx_mode = dat_se0_unidirectional; // MXC91331 ok printk (KERN_INFO"Current setting is SINGLE ENDED UNIDIRECTIONAL\n"); /* ------------------------------------------------------------------------ */ #elif CONFIG_OTG_ZASEVB_DIFFERENTIAL_BIDIRECTIONAL int hwmode = XCVR_D_D; int newmode = XCVR_D_D; isp1301_tx_mode_t tx_mode = vp_vm_bidirectional; // MXC91331 ok printk (KERN_INFO"Current setting is DIFFERENTIAL BIDIRECTIONAL\n"); /* ------------------------------------------------------------------------ */ #elif CONFIG_OTG_ZASEVB_SINGLE_ENDED_BIDIRECTIONAL int hwmode = XCVR_SE0_SE0; int newmode = XCVR_SE0_SE0; isp1301_tx_mode_t tx_mode = dat_se0_bidirectional; //MXC91231 ok printk (KERN_INFO"Current setting is SINGLE ENDED BIDIRECTIONAL\n"); /* ------------------------------------------------------------------------ */ #else #error Please Configure Transceiver Mode #endif /* CONFIG_OTG_ZASEVB_.... */ /* ------------------------------------------------------------------------ */ TRACE_MSG0(TCD, "1. I2C setup"); THROW_IF ((i2c = i2c_configure(ADAPTER_NAME, ISP1301_I2C_ADDR_HIGH)), error); TRACE_MSG0(TCD, "2. ISP1301 module setup"); // isp1301_mod_init(&zasevb_isp1301_bh); TRACE_MSG0(TCD, "3. SET TCD OPS"); THROW_UNLESS(zasevb_tcd_instance = otg_set_tcd_ops(&tcd_ops), error); TRACE_MSG0(TCD, "4. ISP1301 device setup"); mxc_iomux_gpio_isp1301_set (hwmode); #ifdef CONFIG_ARCH_MXC91131 writel (0x00000051, PLL2_DP_HFSOP); writel (0x00000051, PLL2_DP_OP); #endif /* CONFIG_ARCH_MXC91131 */ /* ------------------------------------------------------------------------ */ TRACE_MSG0(TCD, "7. SET HWMODE"); isp1301_configure(tx_mode, spd_susp_reg); mxc_main_clock_on(); //mxc_host_clock_on(); //mxc_func_clock_on(); mxc_set_transceiver_mode(newmode); /* Success! */ TRACE_MSG0(TCD, "8. Success!"); CATCH(error) { printk(KERN_INFO"%s: failed\n", __FUNCTION__); UNLESS (i2c) i2c_close(); // UNLESS (gpio) gpio_free_irq (ZGPIO_PORT, ZGPIO_PIN, GPIO_HIGH_PRIO); return -EINVAL; } TRACE_MSG0(TCD, "MX2_MOD_TCD_INIT FINISHED"); return 0; }