/***************************************************************************** ** FILE NAME : ifxusb_cif_h.c ** PROJECT : IFX USB sub-system V3 ** MODULES : IFX USB sub-system Host and Device driver ** SRC VERSION : 3.2 ** DATE : 1/Jan/2011 ** AUTHOR : Chen, Howard ** DESCRIPTION : The Core Interface provides basic services for accessing and ** managing the IFX USB hardware. These services are used by the ** Host Controller Driver only. ** FUNCTIONS : ** COMPILER : gcc ** REFERENCE : Synopsys DWC-OTG Driver 2.7 ** COPYRIGHT : Copyright (c) 2010 ** LANTIQ DEUTSCHLAND GMBH, ** Am Campeon 3, 85579 Neubiberg, Germany ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** Version Control Section ** ** $Author$ ** $Date$ ** $Revisions$ ** $Log$ Revision history *****************************************************************************/ /* * This file contains code fragments from Synopsys HS OTG Linux Software Driver. * For this code the following notice is applicable: * * ========================================================================== * * Synopsys HS OTG Linux Software Driver and documentation (hereinafter, * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless * otherwise expressly agreed to in writing between Synopsys and you. * * The Software IS NOT an item of Licensed Software or Licensed Product under * any End User Software License Agreement or Agreement for Licensed Product * with Synopsys or any supplement thereto. You are permitted to use and * redistribute this Software in source and binary forms, with or without * modification, provided that redistributions of source code must retain this * notice. You may not view, use, disclose, copy or distribute this file or * any information contained herein except pursuant to this license grant from * Synopsys. If you do not agree with this notice, including the disclaimer * below, then you are not authorized to use the Software. * * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. * ========================================================================== */ /*! \file ifxusb_cif_h.c \ingroup IFXUSB_DRIVER_V3 \brief This file contains the interface to the IFX USB Core. */ #include #include "ifxusb_version.h" #include #include #ifdef __DEBUG__ #include #endif #include #include #include #include "ifxusb_plat.h" #include "ifxusb_regs.h" #include "ifxusb_cif.h" #include "ifxhcd.h" #if !defined(__UEIP__) #undef __USING_LED_AS_GPIO__ #endif /*! \brief This function enables the Host mode interrupts. \param _core_if Pointer of core_if structure */ void ifxusb_host_enable_interrupts(ifxusb_core_if_t *_core_if) { gint_data_t intr_mask ={ .d32 = 0}; ifxusb_core_global_regs_t *global_regs = _core_if->core_global_regs; IFX_DEBUGPL(DBG_CIL, "%s()\n", __func__); /* Clear any pending OTG Interrupts */ ifxusb_wreg( &global_regs->gotgint, 0xFFFFFFFF); /* Clear any pending interrupts */ ifxusb_wreg( &global_regs->gintsts, 0xFFFFFFFF); /* Enable the interrupts in the GINTMSK.*/ /* Common interrupts */ intr_mask.b.modemismatch = 1; intr_mask.b.conidstschng = 1; intr_mask.b.wkupintr = 1; intr_mask.b.disconnect = 1; intr_mask.b.usbsuspend = 1; /* Host interrupts */ intr_mask.b.sofintr = 1; intr_mask.b.portintr = 1; intr_mask.b.hcintr = 1; ifxusb_mreg( &global_regs->gintmsk, intr_mask.d32, intr_mask.d32); IFX_DEBUGPL(DBG_CIL, "%s() gintmsk=%0x\n", __func__, ifxusb_rreg( &global_regs->gintmsk)); } /*! \brief This function disables the Host mode interrupts. \param _core_if Pointer of core_if structure */ void ifxusb_host_disable_interrupts(ifxusb_core_if_t *_core_if) { ifxusb_core_global_regs_t *global_regs = _core_if->core_global_regs; IFX_DEBUGPL(DBG_CILV, "%s()\n", __func__); #if 1 ifxusb_wreg( &global_regs->gintmsk, 0); #else /* Common interrupts */ { gint_data_t intr_mask ={.d32 = 0}; intr_mask.b.modemismatch = 1; intr_mask.b.rxstsqlvl = 1; intr_mask.b.conidstschng = 1; intr_mask.b.wkupintr = 1; intr_mask.b.disconnect = 1; intr_mask.b.usbsuspend = 1; /* Host interrupts */ intr_mask.b.sofintr = 1; intr_mask.b.portintr = 1; intr_mask.b.hcintr = 1; intr_mask.b.ptxfempty = 1; intr_mask.b.nptxfempty = 1; ifxusb_mreg(&global_regs->gintmsk, intr_mask.d32, 0); } #endif } /*! \brief This function initializes the IFXUSB controller registers for Host mode. This function flushes the Tx and Rx FIFOs and it flushes any entries in the request queues. \param _core_if Pointer of core_if structure \param _params parameters to be set */ void ifxusb_host_core_init(ifxusb_core_if_t *_core_if, ifxusb_params_t *_params) { ifxusb_core_global_regs_t *global_regs = _core_if->core_global_regs; gusbcfg_data_t usbcfg ={.d32 = 0}; gahbcfg_data_t ahbcfg ={.d32 = 0}; gotgctl_data_t gotgctl ={.d32 = 0}; int i; IFX_DEBUGPL(DBG_CILV, "%s(%p)\n",__func__,_core_if); /* Copy Params */ _core_if->params.dma_burst_size = _params->dma_burst_size; _core_if->params.speed = _params->speed; if(_params->max_transfer_size < 2048 || _params->max_transfer_size > ((1 << (_core_if->hwcfg3.b.xfer_size_cntr_width + 11)) - 1) ) _core_if->params.max_transfer_size = ((1 << (_core_if->hwcfg3.b.xfer_size_cntr_width + 11)) - 1); else _core_if->params.max_transfer_size = _params->max_transfer_size; if(_params->max_packet_count < 16 || _params->max_packet_count > ((1 << (_core_if->hwcfg3.b.packet_size_cntr_width + 4)) - 1) ) _core_if->params.max_packet_count= ((1 << (_core_if->hwcfg3.b.packet_size_cntr_width + 4)) - 1); else _core_if->params.max_packet_count= _params->max_packet_count; _core_if->params.phy_utmi_width = _params->phy_utmi_width; _core_if->params.turn_around_time_hs = _params->turn_around_time_hs; _core_if->params.turn_around_time_fs = _params->turn_around_time_fs; _core_if->params.timeout_cal_hs = _params->timeout_cal_hs; _core_if->params.timeout_cal_fs = _params->timeout_cal_fs; usbcfg.d32 = ifxusb_rreg(&global_regs->gusbcfg); // usbcfg.b.ulpi_ext_vbus_drv = 1; usbcfg.b.term_sel_dl_pulse = 0; usbcfg.b.ForceDevMode = 0; usbcfg.b.ForceHstMode = 1; ifxusb_wreg (&global_regs->gusbcfg, usbcfg.d32); /* Reset the Controller */ do { while(ifxusb_core_soft_reset_h( _core_if )) ifxusb_hard_reset_h(_core_if); } while (ifxusb_is_device_mode(_core_if)); usbcfg.d32 = ifxusb_rreg(&global_regs->gusbcfg); // usbcfg.b.ulpi_ext_vbus_drv = 1; usbcfg.b.term_sel_dl_pulse = 0; ifxusb_wreg (&global_regs->gusbcfg, usbcfg.d32); /* This programming sequence needs to happen in FS mode before any other * programming occurs */ /* High speed PHY. */ if (!_core_if->phy_init_done) { _core_if->phy_init_done = 1; /* HS PHY parameters. These parameters are preserved * during soft reset so only program the first time. Do * a soft reset immediately after setting phyif. */ usbcfg.b.ulpi_utmi_sel = 0; //UTMI+ usbcfg.b.phyif = ( _core_if->params.phy_utmi_width == 16)?1:0; ifxusb_wreg( &global_regs->gusbcfg, usbcfg.d32); /* Reset after setting the PHY parameters */ ifxusb_core_soft_reset_h( _core_if ); } usbcfg.d32 = ifxusb_rreg(&global_regs->gusbcfg); // usbcfg.b.ulpi_fsls = 0; // usbcfg.b.ulpi_clk_sus_m = 0; usbcfg.b.term_sel_dl_pulse = 0; usbcfg.b.ForceDevMode = 0; usbcfg.b.ForceHstMode = 1; ifxusb_wreg(&global_regs->gusbcfg, usbcfg.d32); /* Program the GAHBCFG Register.*/ switch (_core_if->params.dma_burst_size) { case 0 : ahbcfg.b.hburstlen = IFXUSB_GAHBCFG_INT_DMA_BURST_SINGLE; break; case 1 : ahbcfg.b.hburstlen = IFXUSB_GAHBCFG_INT_DMA_BURST_INCR; break; case 4 : ahbcfg.b.hburstlen = IFXUSB_GAHBCFG_INT_DMA_BURST_INCR4; break; case 8 : ahbcfg.b.hburstlen = IFXUSB_GAHBCFG_INT_DMA_BURST_INCR8; break; case 16: ahbcfg.b.hburstlen = IFXUSB_GAHBCFG_INT_DMA_BURST_INCR16; break; } #if defined(__UNALIGNED_BUF_ADJ__) || defined(__UNALIGNED_BUF_CHK__) _core_if->unaligned_mask=3; #if defined(__UNALIGNED_BUF_BURST__) switch(_core_if->params.dma_burst_size) { case 4 : _core_if->unaligned_mask=15; break; case 8 : _core_if->unaligned_mask=31; break; case 16: _core_if->unaligned_mask=63; break; case 0 : case 1 : break; default: break; } #endif //defined(__UNALIGNED_BUF_BURST__) #endif //defined(__UNALIGNED_BUF_ADJ__) || defined(__UNALIGNED_BUF_CHK__) ahbcfg.b.dmaenable = 1; ifxusb_wreg(&global_regs->gahbcfg, ahbcfg.d32); /* Program the GUSBCFG register. */ usbcfg.d32 = ifxusb_rreg( &global_regs->gusbcfg ); usbcfg.b.hnpcap = 0; usbcfg.b.srpcap = 0; ifxusb_wreg( &global_regs->gusbcfg, usbcfg.d32); /* Restart the Phy Clock */ ifxusb_wreg(_core_if->pcgcctl, 0); /* Initialize Host Configuration Register */ { hcfg_data_t hcfg; hcfg.d32 = ifxusb_rreg(&_core_if->host_global_regs->hcfg); hcfg.b.fslspclksel = IFXUSB_HCFG_30_60_MHZ; if (_params->speed == IFXUSB_PARAM_SPEED_FULL) hcfg.b.fslssupp = 1; ifxusb_wreg(&_core_if->host_global_regs->hcfg, hcfg.d32); } _core_if->params.host_channels=(_core_if->hwcfg2.b.num_host_chan + 1); if(_params->host_channels>0 && _params->host_channels < _core_if->params.host_channels) _core_if->params.host_channels = _params->host_channels; /* Configure data FIFO sizes */ _core_if->params.data_fifo_size = _core_if->hwcfg3.b.dfifo_depth; _core_if->params.rx_fifo_size = ifxusb_rreg(&global_regs->grxfsiz); _core_if->params.nperio_tx_fifo_size= ifxusb_rreg(&global_regs->gnptxfsiz) >> 16; _core_if->params.perio_tx_fifo_size = ifxusb_rreg(&global_regs->hptxfsiz) >> 16; IFX_DEBUGPL(DBG_CIL, "Initial: FIFO Size=0x%06X\n" , _core_if->params.data_fifo_size); IFX_DEBUGPL(DBG_CIL, " Rx FIFO Size=0x%06X\n", _core_if->params.rx_fifo_size); IFX_DEBUGPL(DBG_CIL, " NPTx FIFO Size=0x%06X\n", _core_if->params.nperio_tx_fifo_size); IFX_DEBUGPL(DBG_CIL, " PTx FIFO Size=0x%06X\n", _core_if->params.perio_tx_fifo_size); { fifosize_data_t txfifosize; if(_params->data_fifo_size >=0 && _params->data_fifo_size < _core_if->params.data_fifo_size) _core_if->params.data_fifo_size = _params->data_fifo_size; if( _params->rx_fifo_size >= 0 && _params->rx_fifo_size < _core_if->params.rx_fifo_size) _core_if->params.rx_fifo_size = _params->rx_fifo_size; if( _params->nperio_tx_fifo_size >=0 && _params->nperio_tx_fifo_size < _core_if->params.nperio_tx_fifo_size) _core_if->params.nperio_tx_fifo_size = _params->nperio_tx_fifo_size; if( _params->perio_tx_fifo_size >=0 && _params->perio_tx_fifo_size < _core_if->params.perio_tx_fifo_size) _core_if->params.perio_tx_fifo_size = _params->perio_tx_fifo_size; if(_core_if->params.data_fifo_size < _core_if->params.rx_fifo_size) _core_if->params.rx_fifo_size = _core_if->params.data_fifo_size; ifxusb_wreg( &global_regs->grxfsiz, _core_if->params.rx_fifo_size); txfifosize.b.startaddr = _core_if->params.rx_fifo_size; if(txfifosize.b.startaddr + _core_if->params.nperio_tx_fifo_size > _core_if->params.data_fifo_size) _core_if->params.nperio_tx_fifo_size = _core_if->params.data_fifo_size - txfifosize.b.startaddr; txfifosize.b.depth=_core_if->params.nperio_tx_fifo_size; ifxusb_wreg( &global_regs->gnptxfsiz, txfifosize.d32); txfifosize.b.startaddr += _core_if->params.nperio_tx_fifo_size; if(txfifosize.b.startaddr + _core_if->params.perio_tx_fifo_size > _core_if->params.data_fifo_size) _core_if->params.perio_tx_fifo_size = _core_if->params.data_fifo_size - txfifosize.b.startaddr; txfifosize.b.depth=_core_if->params.perio_tx_fifo_size; ifxusb_wreg( &global_regs->hptxfsiz, txfifosize.d32); txfifosize.b.startaddr += _core_if->params.perio_tx_fifo_size; } #ifdef __DEBUG__ { fifosize_data_t fifosize; IFX_DEBUGPL(DBG_CIL, "Result : FIFO Size=0x%06X\n" , _core_if->params.data_fifo_size); fifosize.d32=ifxusb_rreg(&global_regs->grxfsiz); IFX_DEBUGPL(DBG_CIL, " Rx FIFO =0x%06X 0x%06X\n", fifosize.b.startaddr,fifosize.b.depth); fifosize.d32=ifxusb_rreg(&global_regs->gnptxfsiz); IFX_DEBUGPL(DBG_CIL, " NPTx FIFO =0x%06X 0x%06X\n", fifosize.b.startaddr,fifosize.b.depth); fifosize.d32=ifxusb_rreg(&global_regs->hptxfsiz); IFX_DEBUGPL(DBG_CIL, " PTx FIFO =0x%06X 0x%06X\n", fifosize.b.startaddr,fifosize.b.depth); } #endif /* Clear Host Set HNP Enable in the OTG Control Register */ gotgctl.b.hstsethnpen = 1; ifxusb_mreg( &global_regs->gotgctl, gotgctl.d32, 0); /* Flush the FIFOs */ ifxusb_flush_tx_fifo_h(_core_if, 0x10); /* all Tx FIFOs */ ifxusb_flush_rx_fifo_h(_core_if); for (i = 0; i < _core_if->hwcfg2.b.num_host_chan + 1; i++) { hcchar_data_t hcchar; hcchar.d32 = ifxusb_rreg(&_core_if->hc_regs[i]->hcchar); hcchar.b.chen = 0; hcchar.b.chdis = 1; hcchar.b.epdir = 0; ifxusb_wreg(&_core_if->hc_regs[i]->hcchar, hcchar.d32); } /* Halt all channels to put them into a known state. */ for (i = 0; i < _core_if->hwcfg2.b.num_host_chan + 1; i++) { hcchar_data_t hcchar; int count = 0; hcchar.d32 = ifxusb_rreg(&_core_if->hc_regs[i]->hcchar); hcchar.b.chen = 1; hcchar.b.chdis = 1; hcchar.b.epdir = 0; ifxusb_wreg(&_core_if->hc_regs[i]->hcchar, hcchar.d32); IFX_DEBUGPL(DBG_HCDV, "%s: Halt channel %d\n", __func__, i); do{ hcchar.d32 = ifxusb_rreg(&_core_if->hc_regs[i]->hcchar); if (++count > 1000) { IFX_ERROR("%s: Unable to clear halt on channel %d\n", __func__, i); break; } } while (hcchar.b.chen); } } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #if defined(__UEIP__) #if defined(IFX_GPIO_USB_VBUS) || defined(IFX_LEDGPIO_USB_VBUS) || defined(IFX_LEDLED_USB_VBUS) int ifxusb_vbus_status =-1; #endif #if defined(IFX_GPIO_USB_VBUS1) || defined(IFX_LEDGPIO_USB_VBUS1) || defined(IFX_LEDLED_USB_VBUS1) int ifxusb_vbus1_status =-1; #endif #if defined(IFX_GPIO_USB_VBUS2) || defined(IFX_LEDGPIO_USB_VBUS2) || defined(IFX_LEDLED_USB_VBUS2) int ifxusb_vbus2_status =-1; #endif #if defined(IFX_LEDGPIO_USB_VBUS) || defined(IFX_LEDLED_USB_VBUS) static void *g_usb_vbus_trigger = NULL; #endif #if defined(IFX_LEDGPIO_USB_VBUS1) || defined(IFX_LEDLED_USB_VBUS1) static void *g_usb_vbus1_trigger = NULL; #endif #if defined(IFX_LEDGPIO_USB_VBUS2) || defined(IFX_LEDLED_USB_VBUS2) static void *g_usb_vbus2_trigger = NULL; #endif #if defined(IFX_GPIO_USB_VBUS) || defined(IFX_GPIO_USB_VBUS1) || defined(IFX_GPIO_USB_VBUS2) int ifxusb_vbus_gpio_inited=0; #endif #else //defined(__UEIP__) int ifxusb_vbus_status =-1; int ifxusb_vbus1_status =-1; int ifxusb_vbus2_status =-1; int ifxusb_vbus_gpio_inited=0; #endif ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /*! \fn void ifxusb_vbus_init(ifxusb_core_if_t *_core_if) \brief This function init the VBUS control. \param _core_if Pointer of core_if structure \ingroup IFXUSB_CIF */ void ifxusb_vbus_init(ifxusb_core_if_t *_core_if) { #if defined(__UEIP__) #if defined(IFX_LEDGPIO_USB_VBUS) || defined(IFX_LEDLED_USB_VBUS) if ( !g_usb_vbus_trigger ) { ifx_led_trigger_register("USB_VBUS", &g_usb_vbus_trigger); if ( g_usb_vbus_trigger != NULL ) { struct ifx_led_trigger_attrib attrib = {0}; attrib.delay_on = 0; attrib.delay_off = 0; attrib.timeout = 0; attrib.def_value = 0; attrib.flags = IFX_LED_TRIGGER_ATTRIB_DELAY_ON | IFX_LED_TRIGGER_ATTRIB_DELAY_OFF | IFX_LED_TRIGGER_ATTRIB_TIMEOUT | IFX_LED_TRIGGER_ATTRIB_DEF_VALUE; IFX_DEBUGP("Reg USB power!!\n"); ifx_led_trigger_set_attrib(g_usb_vbus_trigger, &attrib); ifxusb_vbus_status =0; } } #endif #if defined(IFX_LEDGPIO_USB_VBUS1) || defined(IFX_LEDLED_USB_VBUS1) if(_core_if->core_no==0 && !g_usb_vbus1_trigger ) { ifx_led_trigger_register("USB_VBUS1", &g_usb_vbus1_trigger); if ( g_usb_vbus1_trigger != NULL ) { struct ifx_led_trigger_attrib attrib = {0}; attrib.delay_on = 0; attrib.delay_off = 0; attrib.timeout = 0; attrib.def_value = 0; attrib.flags = IFX_LED_TRIGGER_ATTRIB_DELAY_ON | IFX_LED_TRIGGER_ATTRIB_DELAY_OFF | IFX_LED_TRIGGER_ATTRIB_TIMEOUT | IFX_LED_TRIGGER_ATTRIB_DEF_VALUE; IFX_DEBUGP("Reg USB1 power!!\n"); ifx_led_trigger_set_attrib(g_usb_vbus1_trigger, &attrib); ifxusb_vbus1_status =0; } } #endif #if defined(IFX_LEDGPIO_USB_VBUS2) || defined(IFX_LEDLED_USB_VBUS2) if(_core_if->core_no==1 && !g_usb_vbus2_trigger ) { ifx_led_trigger_register("USB_VBUS2", &g_usb_vbus2_trigger); if ( g_usb_vbus2_trigger != NULL ) { struct ifx_led_trigger_attrib attrib = {0}; attrib.delay_on = 0; attrib.delay_off = 0; attrib.timeout = 0; attrib.def_value = 0; attrib.flags = IFX_LED_TRIGGER_ATTRIB_DELAY_ON | IFX_LED_TRIGGER_ATTRIB_DELAY_OFF | IFX_LED_TRIGGER_ATTRIB_TIMEOUT | IFX_LED_TRIGGER_ATTRIB_DEF_VALUE; IFX_DEBUGP("Reg USB2 power!!\n"); ifx_led_trigger_set_attrib(g_usb_vbus2_trigger, &attrib); ifxusb_vbus2_status =0; } } #endif #if defined(IFX_GPIO_USB_VBUS) || defined(IFX_GPIO_USB_VBUS1) || defined(IFX_GPIO_USB_VBUS2) if(!ifxusb_vbus_gpio_inited) { if(!ifx_gpio_register(IFX_GPIO_MODULE_USB)) { IFX_DEBUGP("Register USB VBus through GPIO OK!!\n"); #ifdef IFX_GPIO_USB_VBUS ifxusb_vbus_status =0; #endif //IFX_GPIO_USB_VBUS #ifdef IFX_GPIO_USB_VBUS1 ifxusb_vbus1_status=0; #endif //IFX_GPIO_USB_VBUS1 #ifdef IFX_GPIO_USB_VBUS2 ifxusb_vbus2_status=0; #endif //IFX_GPIO_USB_VBUS2 } else IFX_PRINT("Register USB VBus Failed!!\n"); ifxusb_vbus_gpio_inited=1; } #endif //defined(IFX_GPIO_USB_VBUS) || defined(IFX_GPIO_USB_VBUS1) || defined(IFX_GPIO_USB_VBUS2) #endif //defined(__UEIP__) } /*! \fn void ifxusb_vbus_free(ifxusb_core_if_t *_core_if) \brief This function free the VBUS control. \param _core_if Pointer of core_if structure \ingroup IFXUSB_CIF */ void ifxusb_vbus_free(ifxusb_core_if_t *_core_if) { #if defined(__UEIP__) #if defined(IFX_LEDGPIO_USB_VBUS) || defined(IFX_LEDLED_USB_VBUS) if ( g_usb_vbus_trigger ) { ifx_led_trigger_deregister(g_usb_vbus_trigger); g_usb_vbus_trigger = NULL; ifxusb_vbus_status =-1; } #endif #if defined(IFX_LEDGPIO_USB_VBUS1) || defined(IFX_LEDLED_USB_VBUS1) if(_core_if->core_no==0 && g_usb_vbus1_trigger ) { ifx_led_trigger_deregister(g_usb_vbus1_trigger); g_usb_vbus1_trigger = NULL; ifxusb_vbus1_status =-1; } #endif #if defined(IFX_LEDGPIO_USB_VBUS2) || defined(IFX_LEDLED_USB_VBUS2) if(_core_if->core_no==1 && g_usb_vbus2_trigger ) { ifx_led_trigger_deregister(g_usb_vbus2_trigger); g_usb_vbus2_trigger = NULL; ifxusb_vbus2_status =-1; } #endif #if defined(IFX_GPIO_USB_VBUS) || defined(IFX_GPIO_USB_VBUS1) || defined(IFX_GPIO_USB_VBUS2) if(ifxusb_vbus_gpio_inited) { ifx_gpio_deregister(IFX_GPIO_MODULE_USB); #ifdef IFX_GPIO_USB_VBUS ifxusb_vbus_status =-1; #endif //IFX_GPIO_USB_VBUS #ifdef IFX_GPIO_USB_VBUS1 ifxusb_vbus1_status=-1; #endif //IFX_GPIO_USB_VBUS1 #ifdef IFX_GPIO_USB_VBUS2 ifxusb_vbus2_status=-1; #endif //IFX_GPIO_USB_VBUS2 ifxusb_vbus_gpio_inited=0; } #endif //defined(IFX_GPIO_USB_VBUS) || defined(IFX_GPIO_USB_VBUS1) || defined(IFX_GPIO_USB_VBUS2) #endif //defined(__UEIP__) } #if defined(__DO_OC_INT__) #define OC_Timer_Stable 3 #define OC_Timer_Sleep 200 #define OC_Timer_Max 3 #if defined(__IS_AR10__) #if defined(__IS_DUAL__) unsigned int oc1_int_installed=0; unsigned int oc2_int_installed=0; unsigned int oc1_int_count=0; unsigned int oc2_int_count=0; extern ifxhcd_hcd_t *oc1_int_id; extern ifxhcd_hcd_t *oc2_int_id; /*! \brief Handles host mode Over Current Interrupt */ struct timer_list oc1_retry_timer; struct timer_list oc2_retry_timer; void oc_retry_timer_func(unsigned long arg) { if(arg==1) { if(oc1_int_installed==0) //not installed { } else if(oc1_int_installed==1) //disabled { } else if(oc1_int_installed==2) //stablizing { oc1_int_installed=4; oc1_int_count=0; } else if(oc1_int_installed==3) // sleeping { mod_timer(&oc1_retry_timer,jiffies + HZ*OC_Timer_Stable); oc1_int_installed=2; enable_irq(IFXUSB1_OC_IRQ); } else if(oc1_int_installed==4) // { oc1_int_count=0; } else if(oc1_int_installed==5) // Stable sleeping { mod_timer(&oc1_retry_timer,jiffies + HZ*OC_Timer_Stable); oc1_int_installed=4; enable_irq(IFXUSB1_OC_IRQ); } else { } } else { if(oc2_int_installed==0) //not installed { } else if(oc2_int_installed==1) //disabled { } else if(oc2_int_installed==2) //stablizing { oc2_int_installed=4; oc2_int_count=0; } else if(oc2_int_installed==3) // sleeping { mod_timer(&oc2_retry_timer,jiffies + HZ*OC_Timer_Stable); oc2_int_installed=2; enable_irq(IFXUSB2_OC_IRQ); } else if(oc2_int_installed==4) // { oc2_int_count=0; } else if(oc2_int_installed==5) // Stable sleeping { mod_timer(&oc2_retry_timer,jiffies + HZ*OC_Timer_Stable); oc2_int_installed=4; enable_irq(IFXUSB2_OC_IRQ); } else { } } } irqreturn_t ifxhcd_oc_irq(int _irq , void *_dev) { //ifxhcd_hcd_t *ifxhcd= _dev; int32_t retval=1; if(_irq==IFXUSB1_OC_IRQ) { if(oc1_int_installed==0) //not installed { } else if(oc1_int_installed==1) //disabled { } else if(oc1_int_installed==2) //stablizing { disable_irq_nosync(IFXUSB1_OC_IRQ); mod_timer(&oc1_retry_timer,jiffies + HZ/OC_Timer_Sleep); oc1_int_installed=3; } else if(oc1_int_installed==3) // sleeping { } else if(oc1_int_installed==4) // { oc1_int_count++; if(oc1_int_count>=OC_Timer_Max) { IFX_DEBUGP("OC INTERRUPT port #1\n"); oc1_int_id->flags.b.port_over_current_change = 1; ifxusb_vbus_off(&oc1_int_id->core_if); IFX_DEBUGP("Turning off port #1\n"); } else { disable_irq_nosync(IFXUSB1_OC_IRQ); mod_timer(&oc1_retry_timer,jiffies + HZ/OC_Timer_Sleep); oc1_int_installed=5; } } else if(oc1_int_installed==5) // Stable sleeping { } } else { if(oc2_int_installed==0) //not installed { } else if(oc2_int_installed==1) //disabled { } else if(oc2_int_installed==2) //stablizing { disable_irq_nosync(IFXUSB2_OC_IRQ); mod_timer(&oc2_retry_timer,jiffies + HZ/OC_Timer_Sleep); oc2_int_installed=3; } else if(oc2_int_installed==3) // sleeping { } else if(oc2_int_installed==4) // { oc2_int_count++; if(oc2_int_count>=OC_Timer_Max) { IFX_DEBUGP("OC INTERRUPT port #2\n"); oc2_int_id->flags.b.port_over_current_change = 1; ifxusb_vbus_off(&oc2_int_id->core_if); IFX_DEBUGP("Turning off port #2\n"); } else { disable_irq_nosync(IFXUSB2_OC_IRQ); mod_timer(&oc2_retry_timer,jiffies + HZ/OC_Timer_Sleep); oc2_int_installed=5; } } else if(oc2_int_installed==5) // Stable sleeping { } } return IRQ_RETVAL(retval); } void ifxusb_oc_int_on(int port) { if(port==1) IFX_DEBUGPL( DBG_CIL, "registering (overcurrent) handler for port #1 irq%d\n", IFXUSB1_OC_IRQ); else IFX_DEBUGPL( DBG_CIL, "registering (overcurrent) handler for port #2 irq%d\n", IFXUSB2_OC_IRQ); if((port==1&&oc1_int_id) || (port==2&&oc2_int_id) { if((port==1&&oc1_int_installed==0)||(port==2&&oc2_int_installed==0)) { if(port==1) { oc1_int_installed=2; init_timer(&oc1_retry_timer); oc1_retry_timer.function = oc_retry_timer_func; oc1_retry_timer.data=1; if(request_irq((unsigned int)IFXUSB1_OC_IRQ, &ifxhcd_oc_irq, IRQF_TRIGGER_NONE // | IRQF_TRIGGER_RISING // | IRQF_TRIGGER_FALLING // | IRQF_TRIGGER_HIGH // | IRQF_TRIGGER_LOW // | IRQF_TRIGGER_PROBE // | IRQF_SAMPLE_RANDOM // | IRQF_SHARED | IRQF_PROBE_SHARED // | IRQF_TIMER // | IRQF_PERCPU // | IRQF_NOBALANCING // | IRQF_IRQPOLL // | IRQF_ONESHOT , "ifxusb1_oc", (void *)oc1_int_id)) oc1_int_installed=0; else mod_timer(&oc1_retry_timer,jiffies + HZ*OC_Timer_Stable); } else { oc2_int_installed=2; init_timer(&oc2_retry_timer); oc2_retry_timer.function = oc_retry_timer_func; oc2_retry_timer.data=2; if(request_irq((unsigned int)IFXUSB2_OC_IRQ, &ifxhcd_oc_irq, IRQF_TRIGGER_NONE // | IRQF_TRIGGER_RISING // | IRQF_TRIGGER_FALLING // | IRQF_TRIGGER_HIGH // | IRQF_TRIGGER_LOW // | IRQF_TRIGGER_PROBE // | IRQF_SAMPLE_RANDOM // | IRQF_SHARED | IRQF_PROBE_SHARED // | IRQF_TIMER // | IRQF_PERCPU // | IRQF_NOBALANCING // | IRQF_IRQPOLL // | IRQF_ONESHOT , "ifxusb2_oc", (void *)oc2_int_id)) oc2_int_installed=0; else mod_timer(&oc2_retry_timer,jiffies + HZ*OC_Timer_Stable); } /* Poll the event ring */ } else if(port==1 && oc1_int_installed!=2 && oc1_int_installed!=4 ) { oc1_int_installed=2; enable_irq(IFXUSB1_OC_IRQ); mod_timer(&oc1_retry_timer,jiffies + HZ*OC_Timer_Stable); } else if(port==2 && oc2_int_installed!=2 && oc2_int_installed!=4 ) { oc2_int_installed=2; enable_irq(IFXUSB2_OC_IRQ); mod_timer(&oc2_retry_timer,jiffies + HZ*OC_Timer_Stable); } } } void ifxusb_oc_int_off(int port) { if(port==1) { disable_irq_nosync(IFXUSB1_OC_IRQ); if(oc1_int_installed) oc1_int_installed=1; } else { disable_irq_nosync(IFXUSB2_OC_IRQ); if(oc2_int_installed) oc2_int_installed=1; } } void ifxusb_oc_int_free(int port) { if(port==1) { del_timer(&oc1_retry_timer); disable_irq_nosync(IFXUSB1_OC_IRQ); free_irq(IFXUSB1_OC_IRQ, (void *)oc1_int_id); oc1_int_installed=0; } else { del_timer(&oc1_retry_timer); disable_irq_nosync(IFXUSB1_OC_IRQ); free_irq(IFXUSB2_OC_IRQ, (void *)oc2_int_id); oc2_int_installed=0; } } #elif defined(__IS_FIRST__) || defined(__IS_SECOND__) unsigned int oc_int_installed=0; unsigned int oc_int_count=0; extern ifxhcd_hcd_t *oc_int_id; /*! \brief Handles host mode Over Current Interrupt */ struct timer_list oc_retry_timer; void oc_retry_timer_func(void) { if(oc_int_installed==0) //not installed { } else if(oc_int_installed==1) //disabled { } else if(oc_int_installed==2) //stablizing { oc_int_installed=4; oc_int_count=0; } else if(oc_int_installed==3) // sleeping { mod_timer(&oc_retry_timer,jiffies + HZ*OC_Timer_Stable); oc_int_installed=2; #if defined(__IS_FIRST__) enable_irq(IFXUSB1_OC_IRQ); #else enable_irq(IFXUSB2_OC_IRQ); #endif } else if(oc_int_installed==4) // { oc_int_count=0; } else if(oc_int_installed==5) // Stable sleeping { mod_timer(&oc_retry_timer,jiffies + HZ*OC_Timer_Stable); oc_int_installed=4; #if defined(__IS_FIRST__) enable_irq(IFXUSB1_OC_IRQ); #else enable_irq(IFXUSB2_OC_IRQ); #endif } else { } } irqreturn_t ifxhcd_oc_irq(int _irq , void *_dev) { //ifxhcd_hcd_t *ifxhcd= _dev; int32_t retval=1; if(oc_int_installed==0) //not installed { } else if(oc_int_installed==1) //disabled { } else if(oc_int_installed==2) //stablizing { #if defined(__IS_FIRST__) disable_irq_nosync(IFXUSB1_OC_IRQ); #else disable_irq_nosync(IFXUSB2_OC_IRQ); #endif mod_timer(&oc_retry_timer,jiffies + HZ/OC_Timer_Sleep); oc_int_installed=3; } else if(oc_int_installed==3) // sleeping { } else if(oc_int_installed==4) // { oc_int_count++; if(oc_int_count>=OC_Timer_Max) { #if defined(__IS_FIRST__) IFX_DEBUGP("OC INTERRUPT port #1\n"); #else IFX_DEBUGP("OC INTERRUPT port #2\n"); #endif oc_int_id->flags.b.port_over_current_change = 1; ifxusb_vbus_off(&oc_int_id->core_if); #if defined(__IS_FIRST__) IFX_DEBUGP("Turning off port #1\n"); #else IFX_DEBUGP("Turning off port #2\n"); #endif } else { #if defined(__IS_FIRST__) disable_irq_nosync(IFXUSB1_OC_IRQ); #else disable_irq_nosync(IFXUSB2_OC_IRQ); #endif mod_timer(&oc_retry_timer,jiffies + HZ/OC_Timer_Sleep); oc_int_installed=5; } } else if(oc_int_installed==5) // Stable sleeping { } return IRQ_RETVAL(retval); } void ifxusb_oc_int_on(void) { #if defined(__IS_FIRST__) IFX_DEBUGPL( DBG_CIL, "registering (overcurrent) handler for port #1 irq%d\n", IFXUSB1_OC_IRQ); #else IFX_DEBUGPL( DBG_CIL, "registering (overcurrent) handler for port #2 irq%d\n", IFXUSB2_OC_IRQ); #endif if(oc_int_id) { if(oc_int_installed==0) { oc_int_installed=2; init_timer(&oc_retry_timer); oc_retry_timer.function = oc_retry_timer_func; oc_retry_timer.data=1; #if defined(__IS_FIRST__) if(request_irq((unsigned int)IFXUSB1_OC_IRQ, &ifxhcd_oc_irq, #else if(request_irq((unsigned int)IFXUSB2_OC_IRQ, &ifxhcd_oc_irq, #endif IRQF_TRIGGER_NONE // | IRQF_TRIGGER_RISING // | IRQF_TRIGGER_FALLING // | IRQF_TRIGGER_HIGH // | IRQF_TRIGGER_LOW // | IRQF_TRIGGER_PROBE // | IRQF_SAMPLE_RANDOM // | IRQF_SHARED | IRQF_PROBE_SHARED // | IRQF_TIMER // | IRQF_PERCPU // | IRQF_NOBALANCING // | IRQF_IRQPOLL // | IRQF_ONESHOT , "ifxusb_oc", (void *)oc_int_id)) oc_int_installed=0; else mod_timer(&oc1_retry_timer,jiffies + HZ*OC_Timer_Stable); } else if(oc_int_installed!=2 && oc_int_installed!=4 ) { oc_int_installed=2; #if defined(__IS_FIRST__) enable_irq(IFXUSB1_OC_IRQ); #else enable_irq(IFXUSB2_OC_IRQ); #endif mod_timer(&oc_retry_timer,jiffies + HZ*OC_Timer_Stable); } } } void ifxusb_oc_int_off(int port) { #if defined(__IS_FIRST__) disable_irq_nosync(IFXUSB1_OC_IRQ); #else disable_irq_nosync(IFXUSB2_OC_IRQ); #endif } void ifxusb_oc_int_free(int port) { #if defined(__IS_FIRST__) free_irq(IFXUSB1_OC_IRQ, (void *)oc_int_id); #else free_irq(IFXUSB2_OC_IRQ, (void *)oc_int_id); #endif } #endif #else //!defined(__IS_AR10__) unsigned int oc_int_installed=0; unsigned int oc_int_count=0; extern ifxhcd_hcd_t *oc_int_id; #ifdef __IS_DUAL__ extern ifxhcd_hcd_t *oc_int_id_1; extern ifxhcd_hcd_t *oc_int_id_2; #endif /*! \brief Handles host mode Over Current Interrupt */ struct timer_list oc_retry_timer; void oc_retry_timer_func(unsigned long arg) { if(oc_int_installed==0) //not installed { } else if(oc_int_installed==1) //disabled { } else if(oc_int_installed==2) //stablizing { oc_int_installed=4; oc_int_count=0; } else if(oc_int_installed==3) // sleeping { mod_timer(&oc_retry_timer,jiffies + HZ*OC_Timer_Stable); oc_int_installed=2; enable_irq(IFXUSB_OC_IRQ); } else if(oc_int_installed==4) // { oc_int_count=0; } else if(oc_int_installed==5) // Stable sleeping { mod_timer(&oc_retry_timer,jiffies + HZ*OC_Timer_Stable); oc_int_installed=4; enable_irq(IFXUSB_OC_IRQ); } else { } } irqreturn_t ifxhcd_oc_irq(int _irq , void *_dev) { //ifxhcd_hcd_t *ifxhcd= _dev; int32_t retval=1; if(oc_int_installed==0) //not installed { } else if(oc_int_installed==1) //disabled { } else if(oc_int_installed==2) //stablizing { disable_irq_nosync(IFXUSB_OC_IRQ); mod_timer(&oc_retry_timer,jiffies + HZ/OC_Timer_Sleep); oc_int_installed=3; } else if(oc_int_installed==3) // sleeping { } else if(oc_int_installed==4) // { oc_int_count++; if(oc_int_count>=OC_Timer_Max) { IFX_DEBUGP("OC INTERRUPT port #%d\n",oc_int_id->core_if.core_no); #ifdef __IS_DUAL__ oc_int_id_1->flags.b.port_over_current_change = 1; oc_int_id_2->flags.b.port_over_current_change = 1; ifxusb_vbus_off(&oc_int_id_1->core_if); IFX_DEBUGP("Turning off port #%d\n",oc_int_id_1->core_if.core_no); ifxusb_vbus_off(&oc_int_id_2->core_if); IFX_DEBUGP("Turning off port #%d\n",oc_int_id_2->core_if.core_no); #else oc_int_id->flags.b.port_over_current_change = 1; ifxusb_vbus_off(&oc_int_id->core_if); IFX_DEBUGP("Turning off port #%d\n",oc_int_id->core_if.core_no); #endif } else { disable_irq_nosync(IFXUSB_OC_IRQ); mod_timer(&oc_retry_timer,jiffies + HZ/OC_Timer_Sleep); oc_int_installed=5; } } else if(oc_int_installed==5) // Stable sleeping { } return IRQ_RETVAL(retval); } void ifxusb_oc_int_on(void) { IFX_DEBUGPL( DBG_CIL, "registering (overcurrent) handler for irq%d\n", IFXUSB_OC_IRQ); if(oc_int_id) { if(oc_int_installed==0) { oc_int_installed=2; init_timer(&oc_retry_timer); oc_retry_timer.function = oc_retry_timer_func; /* Poll the event ring */ if(request_irq((unsigned int)IFXUSB_OC_IRQ, &ifxhcd_oc_irq, IRQF_TRIGGER_NONE // | IRQF_TRIGGER_RISING // | IRQF_TRIGGER_FALLING // | IRQF_TRIGGER_HIGH // | IRQF_TRIGGER_LOW // | IRQF_TRIGGER_PROBE // | IRQF_SAMPLE_RANDOM // | IRQF_SHARED // | IRQF_PROBE_SHARED // | IRQF_TIMER // | IRQF_PERCPU // | IRQF_NOBALANCING // | IRQF_IRQPOLL // | IRQF_ONESHOT , "ifxusb_oc", (void *)oc_int_id)) oc_int_installed=0; else mod_timer(&oc_retry_timer,jiffies + HZ*OC_Timer_Stable); } else if(oc_int_installed!=2 && oc_int_installed!=4 ) { oc_int_installed=2; enable_irq(IFXUSB_OC_IRQ); mod_timer(&oc_retry_timer,jiffies + HZ*OC_Timer_Stable); } } } void ifxusb_oc_int_off(void) { disable_irq_nosync(IFXUSB_OC_IRQ); if(oc_int_installed) oc_int_installed=1; } void ifxusb_oc_int_free(void) { del_timer(&oc_retry_timer); disable_irq_nosync(IFXUSB_OC_IRQ); if(oc_int_installed) free_irq(IFXUSB_OC_IRQ, (void *)oc_int_id); oc_int_installed=0; } #endif #endif /*! \fn void ifxusb_vbus_on(ifxusb_core_if_t *_core_if) \brief Turn on the USB 5V VBus Power \param _core_if Pointer of core_if structure \ingroup IFXUSB_CIF */ void ifxusb_vbus_on(ifxusb_core_if_t *_core_if) { IFX_DEBUGP("SENDING VBus POWER UP\n"); #if defined(__UEIP__) #if defined(IFX_LEDGPIO_USB_VBUS) || defined(IFX_LEDLED_USB_VBUS) if ( g_usb_vbus_trigger && ifxusb_vbus_status==0) { ifx_led_trigger_activate(g_usb_vbus_trigger); IFX_DEBUGP("Enable USB power!!\n"); ifxusb_vbus_status=1; } #endif #if defined(IFX_LEDGPIO_USB_VBUS1) || defined(IFX_LEDLED_USB_VBUS1) if(_core_if->core_no==0 && g_usb_vbus1_trigger && ifxusb_vbus1_status==0) { ifx_led_trigger_activate(g_usb_vbus1_trigger); IFX_DEBUGP("Enable USB1 power!!\n"); ifxusb_vbus1_status=1; } #endif #if defined(IFX_LEDGPIO_USB_VBUS2) || defined(IFX_LEDLED_USB_VBUS2) if(_core_if->core_no==1 && g_usb_vbus2_trigger && ifxusb_vbus2_status==0) { ifx_led_trigger_activate(g_usb_vbus2_trigger); IFX_DEBUGP("Enable USB2 power!!\n"); ifxusb_vbus2_status=1; } #endif #if defined(IFX_GPIO_USB_VBUS) || defined(IFX_GPIO_USB_VBUS1) || defined(IFX_GPIO_USB_VBUS2) if(ifxusb_vbus_gpio_inited) { #if defined(IFX_GPIO_USB_VBUS) if(ifxusb_vbus_status==0) { ifx_gpio_output_set(IFX_GPIO_USB_VBUS,IFX_GPIO_MODULE_USB); ifxusb_vbus_status=1; } #endif #if defined(IFX_GPIO_USB_VBUS1) if(_core_if->core_no==0 && ifxusb_vbus1_status==0) { ifx_gpio_output_set(IFX_GPIO_USB_VBUS1,IFX_GPIO_MODULE_USB); ifxusb_vbus1_status=1; } #endif #if defined(IFX_GPIO_USB_VBUS2) if(_core_if->core_no==1 && ifxusb_vbus2_status==0) { ifx_gpio_output_set(IFX_GPIO_USB_VBUS2,IFX_GPIO_MODULE_USB); ifxusb_vbus2_status=1; } #endif } #endif //defined(IFX_GPIO_USB_VBUS) || defined(IFX_GPIO_USB_VBUS1) || defined(IFX_GPIO_USB_VBUS2) #else #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) ifxusb_vbus_status=1; //usb_set_vbus_on(); #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) #if defined(__IS_AMAZON_SE__) set_bit (4, (volatile unsigned long *)AMAZON_SE_GPIO_P0_OUT); ifxusb_vbus_status=1; #endif //defined(__IS_AMAZON_SE__) #if defined(__IS_AR9__) if(_core_if->core_no==0) { if (bsp_port_reserve_pin(1, 13, PORT_MODULE_USB) != 0) { IFX_PRINT("Can't enable USB1 5.5V power!!\n"); return; } bsp_port_clear_altsel0(1, 13, PORT_MODULE_USB); bsp_port_clear_altsel1(1, 13, PORT_MODULE_USB); bsp_port_set_dir_out(1, 13, PORT_MODULE_USB); bsp_port_set_pudsel(1, 13, PORT_MODULE_USB); bsp_port_set_puden(1, 13, PORT_MODULE_USB); bsp_port_set_output(1, 13, PORT_MODULE_USB); IFX_DEBUGP("Enable USB1 power!!\n"); ifxusb_vbus1_status=1; } else { if (bsp_port_reserve_pin(3, 4, PORT_MODULE_USB) != 0) { IFX_PRINT("Can't enable USB2 5.5V power!!\n"); return; } bsp_port_clear_altsel0(3, 4, PORT_MODULE_USB); bsp_port_clear_altsel1(3, 4, PORT_MODULE_USB); bsp_port_set_dir_out(3, 4, PORT_MODULE_USB); bsp_port_set_pudsel(3, 4, PORT_MODULE_USB); bsp_port_set_puden(3, 4, PORT_MODULE_USB); bsp_port_set_output(3, 4, PORT_MODULE_USB); IFX_DEBUGP("Enable USB2 power!!\n"); ifxusb_vbus2_status=1; } #endif //defined(__IS_AR9__) #if defined(__IS_VR9__) if(_core_if->core_no==0) { ifxusb_vbus1_status=1; } else { ifxusb_vbus2_status=1; } #endif //defined(__IS_VR9__) #endif //defined(__UEIP__) #if defined(__DO_OC_INT__) #if defined(__IS_AR10__) && defined(__IS_DUAL__) if(_core_if->core_no==0) ifxusb_oc_int_on(1); else ifxusb_oc_int_on(2); #else ifxusb_oc_int_on(); #endif #endif } /*! \fn void ifxusb_vbus_off(ifxusb_core_if_t *_core_if) \brief Turn off the USB 5V VBus Power \param _core_if Pointer of core_if structure \ingroup IFXUSB_CIF */ void ifxusb_vbus_off(ifxusb_core_if_t *_core_if) { IFX_DEBUGP("SENDING VBus POWER OFF\n"); #if defined(__UEIP__) #if defined(IFX_LEDGPIO_USB_VBUS) || defined(IFX_LEDLED_USB_VBUS) if ( g_usb_vbus_trigger && ifxusb_vbus_status==1) { ifx_led_trigger_deactivate(g_usb_vbus_trigger); IFX_DEBUGP("Disable USB power!!\n"); ifxusb_vbus_status=0; } #endif #if defined(IFX_LEDGPIO_USB_VBUS1) || defined(IFX_LEDLED_USB_VBUS1) if(_core_if->core_no==0 && g_usb_vbus1_trigger && ifxusb_vbus1_status==1) { ifx_led_trigger_deactivate(g_usb_vbus1_trigger); IFX_DEBUGP("Disable USB1 power!!\n"); ifxusb_vbus1_status=0; } #endif #if defined(IFX_LEDGPIO_USB_VBUS2) || defined(IFX_LEDLED_USB_VBUS2) if(_core_if->core_no==1 && g_usb_vbus2_trigger && ifxusb_vbus2_status==1) { ifx_led_trigger_deactivate(g_usb_vbus2_trigger); IFX_DEBUGP("Disable USB2 power!!\n"); ifxusb_vbus2_status=0; } #endif #if defined(IFX_GPIO_USB_VBUS) || defined(IFX_GPIO_USB_VBUS1) || defined(IFX_GPIO_USB_VBUS2) if(ifxusb_vbus_gpio_inited) { #if defined(IFX_GPIO_USB_VBUS) if(ifxusb_vbus_status==1) { ifx_gpio_output_clear(IFX_GPIO_USB_VBUS,IFX_GPIO_MODULE_USB); ifxusb_vbus_status=0; } #endif #if defined(IFX_GPIO_USB_VBUS1) if(_core_if->core_no==0 && ifxusb_vbus1_status==1) { ifx_gpio_output_clear(IFX_GPIO_USB_VBUS1,IFX_GPIO_MODULE_USB); ifxusb_vbus1_status=0; } #endif #if defined(IFX_GPIO_USB_VBUS2) if(_core_if->core_no==1 && ifxusb_vbus2_status==1) { ifx_gpio_output_clear(IFX_GPIO_USB_VBUS2,IFX_GPIO_MODULE_USB); ifxusb_vbus2_status=0; } #endif } #endif //defined(IFX_GPIO_USB_VBUS) || defined(IFX_GPIO_USB_VBUS1) || defined(IFX_GPIO_USB_VBUS2) #else #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) ifxusb_vbus_status=0; //usb_set_vbus_on(); #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) #if defined(__IS_AMAZON_SE__) clear_bit (4, (volatile unsigned long *)AMAZON_SE_GPIO_P0_OUT); ifxusb_vbus_status=0; #endif //defined(__IS_AMAZON_SE__) #if defined(__IS_AR9__) if(_core_if->core_no==0) { if (bsp_port_reserve_pin(1, 13, PORT_MODULE_USB) != 0) { IFX_PRINT("Can't Disable USB1 5.5V power!!\n"); return; } bsp_port_clear_altsel0(1, 13, PORT_MODULE_USB); bsp_port_clear_altsel1(1, 13, PORT_MODULE_USB); bsp_port_set_dir_out(1, 13, PORT_MODULE_USB); bsp_port_set_pudsel(1, 13, PORT_MODULE_USB); bsp_port_set_puden(1, 13, PORT_MODULE_USB); bsp_port_clear_output(1, 13, PORT_MODULE_USB); IFX_DEBUGP("Disable USB1 power!!\n"); ifxusb_vbus1_status=0; } else { if (bsp_port_reserve_pin(3, 4, PORT_MODULE_USB) != 0) { IFX_PRINT("Can't Disable USB2 5.5V power!!\n"); return; } bsp_port_clear_altsel0(3, 4, PORT_MODULE_USB); bsp_port_clear_altsel1(3, 4, PORT_MODULE_USB); bsp_port_set_dir_out(3, 4, PORT_MODULE_USB); bsp_port_set_pudsel(3, 4, PORT_MODULE_USB); bsp_port_set_puden(3, 4, PORT_MODULE_USB); bsp_port_clear_output(3, 4, PORT_MODULE_USB); IFX_DEBUGP("Disable USB2 power!!\n"); ifxusb_vbus2_status=0; } #endif //defined(__IS_AR9__) #if defined(__IS_VR9__) if(_core_if->core_no==0) { ifxusb_vbus1_status=0; } else { ifxusb_vbus2_status=0; } #endif //defined(__IS_VR9__) #endif //defined(__UEIP__) #if defined(__DO_OC_INT__) #if defined(__IS_AR10__) && defined(__IS_DUAL__) if(_core_if->core_no==0) ifxusb_oc_int_off(1); else ifxusb_oc_int_off(2); #else ifxusb_oc_int_off(); #endif #endif } /*! \fn int ifxusb_vbus(ifxusb_core_if_t *_core_if) \brief Read Current VBus status \param _core_if Pointer of core_if structure \ingroup IFXUSB_CIF */ int ifxusb_vbus(ifxusb_core_if_t *_core_if) { #if defined(__UEIP__) #if defined(IFX_GPIO_USB_VBUS) || defined(IFX_LEDGPIO_USB_VBUS) || defined(IFX_LEDLED_USB_VBUS) return (ifxusb_vbus_status); #endif #if defined(IFX_GPIO_USB_VBUS1) || defined(IFX_LEDGPIO_USB_VBUS1) || defined(IFX_LEDLED_USB_VBUS1) if(_core_if->core_no==0) return (ifxusb_vbus1_status); #endif #if defined(IFX_GPIO_USB_VBUS2) || defined(IFX_LEDGPIO_USB_VBUS2) || defined(IFX_LEDLED_USB_VBUS2) if(_core_if->core_no==1) return (ifxusb_vbus2_status); #endif #else //defined(__UEIP__) #endif return -1; } #if defined(__UEIP__) #else #if defined(__IS_TWINPASS__) #define ADSL_BASE 0x20000 #define CRI_BASE 0x31F00 #define CRI_CCR0 CRI_BASE + 0x00 #define CRI_CCR1 CRI_BASE + 0x01*4 #define CRI_CDC0 CRI_BASE + 0x02*4 #define CRI_CDC1 CRI_BASE + 0x03*4 #define CRI_RST CRI_BASE + 0x04*4 #define CRI_MASK0 CRI_BASE + 0x05*4 #define CRI_MASK1 CRI_BASE + 0x06*4 #define CRI_MASK2 CRI_BASE + 0x07*4 #define CRI_STATUS0 CRI_BASE + 0x08*4 #define CRI_STATUS1 CRI_BASE + 0x09*4 #define CRI_STATUS2 CRI_BASE + 0x0A*4 #define CRI_AMASK0 CRI_BASE + 0x0B*4 #define CRI_AMASK1 CRI_BASE + 0x0C*4 #define CRI_UPDCTL CRI_BASE + 0x0D*4 #define CRI_MADST CRI_BASE + 0x0E*4 // 0x0f is missing #define CRI_EVENT0 CRI_BASE + 0x10*4 #define CRI_EVENT1 CRI_BASE + 0x11*4 #define CRI_EVENT2 CRI_BASE + 0x12*4 #define IRI_I_ENABLE 0x32000 #define STY_SMODE 0x3c004 #define AFE_TCR_0 0x3c0dc #define AFE_ADDR_ADDR 0x3c0e8 #define AFE_RDATA_ADDR 0x3c0ec #define AFE_WDATA_ADDR 0x3c0f0 #define AFE_CONFIG 0x3c0f4 #define AFE_SERIAL_CFG 0x3c0fc #define DFE_BASE_ADDR 0xBE116000 //#define DFE_BASE_ADDR 0x9E116000 #define MEI_FR_ARCINT_C (DFE_BASE_ADDR + 0x0000001C) #define MEI_DBG_WADDR_C (DFE_BASE_ADDR + 0x00000024) #define MEI_DBG_RADDR_C (DFE_BASE_ADDR + 0x00000028) #define MEI_DBG_DATA_C (DFE_BASE_ADDR + 0x0000002C) #define MEI_DBG_DECO_C (DFE_BASE_ADDR + 0x00000030) #define MEI_DBG_MASTER_C (DFE_BASE_ADDR + 0x0000003C) static void WriteARCmem(uint32_t addr, uint32_t data) { writel(1 ,(volatile uint32_t *)MEI_DBG_MASTER_C); writel(1 ,(volatile uint32_t *)MEI_DBG_DECO_C ); writel(addr ,(volatile uint32_t *)MEI_DBG_WADDR_C ); writel(data ,(volatile uint32_t *)MEI_DBG_DATA_C ); while( (ifxusb_rreg((volatile uint32_t *)MEI_FR_ARCINT_C) & 0x20) != 0x20 ){}; writel(0 ,(volatile uint32_t *)MEI_DBG_MASTER_C); IFX_DEBUGP("WriteARCmem %08x %08x\n",addr,data); }; static uint32_t ReadARCmem(uint32_t addr) { u32 data; writel(1 ,(volatile uint32_t *)MEI_DBG_MASTER_C); writel(1 ,(volatile uint32_t *)MEI_DBG_DECO_C ); writel(addr ,(volatile uint32_t *)MEI_DBG_RADDR_C ); while( (ifxusb_rreg((volatile uint32_t *)MEI_FR_ARCINT_C) & 0x20) != 0x20 ){}; data = ifxusb_rreg((volatile uint32_t *)MEI_DBG_DATA_C ); writel(0 ,(volatile uint32_t *)MEI_DBG_MASTER_C); IFX_DEBUGP("ReadARCmem %08x %08x\n",addr,data); return data; }; void ifxusb_enable_afe_oc(void) { /* Start the clock */ WriteARCmem(CRI_UPDCTL ,0x00000008); WriteARCmem(CRI_CCR0 ,0x00000014); WriteARCmem(CRI_CCR1 ,0x00000500); WriteARCmem(AFE_CONFIG ,0x000001c8); WriteARCmem(AFE_SERIAL_CFG,0x00000016); // (DANUBE_PCI_CFG_BASE+(1<