/*! \brief inlined by ifxusb_driver_probe(), handling device mode probing. */ static inline int ifxusb_driver_probe_d(ifxpcd_pcd_t *_pcd, int _irq, uint32_t _iobase, uint32_t _fifomem, uint32_t _fifodbg ) { int retval = 0; IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ ); #ifdef __DEV_NEW__ ifxusb_power_off (&_pcd->core_if); ifxusb_phy_power_off (&_pcd->core_if); // Test mdelay(500); #endif // __DEV_NEW__ ifxusb_power_on (&_pcd->core_if); mdelay(50); ifxusb_phy_power_on (&_pcd->core_if); // Test mdelay(50); ifxusb_hard_reset(&_pcd->core_if); retval =ifxusb_core_if_init(&_pcd->core_if, _irq, _iobase, _fifomem, _fifodbg); if(retval) return retval; IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ ); ifxusb_dev_core_init(&_pcd->core_if,&ifxusb_module_params); IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ ); ifxusb_disable_global_interrupts( &_pcd->core_if); /* The driver is now initialized and need to be registered into Linux USB Gadget sub-system */ retval = ifxpcd_init(); IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ ); if (retval != 0) { IFX_ERROR("_pcd_init failed\n"); return retval; } //ifxusb_enable_global_interrupts( _pcd->core_if ); // this should be done at gadget bind or start return 0; }
void __exit ifxusb_pcd_driver_cleanup(void) { IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ ); platform_device_unregister(&ifxusb_device); platform_driver_unregister(&ifxusb_driver); IFX_PRINT("%s module removed\n", ifxusb_pcd_driver_name); }
/*! \brief This function is called when a driver is unregistered. This happens when the rmmod command is executed. The device may or may not be electrically present. If it is present, the driver stops device processing. Any resources used on behalf of this device are freed. */ static int ifxusb_driver_remove(struct platform_device *_pdev) { IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ ); #ifdef __IS_HOST__ #if defined(__IS_DUAL__) ifxhcd_remove(&ifxusb_hcd_1); ifxusb_core_if_remove_h(&ifxusb_hcd_1.core_if ); ifxhcd_remove(&ifxusb_hcd_2); ifxusb_core_if_remove_h(&ifxusb_hcd_2.core_if ); #else ifxhcd_remove(&ifxusb_hcd); ifxusb_core_if_remove_h(&ifxusb_hcd.core_if ); #endif #endif #ifdef __IS_DEVICE__ ifxpcd_remove(); ifxusb_core_if_remove_d(&ifxusb_pcd.core_if ); #endif /* Remove the device attributes */ /* #ifdef __IS_HOST__ ifxusb_attr_remove_h(&_pdev->dev); #else ifxusb_attr_remove_d(&_pdev->dev); #endif*/ return 0; }
int __init ifxusb_driver_init(void) { int retval = 0; IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ ); IFX_PRINT("%s: version %s\n", ifxusb_driver_name, IFXUSB_VERSION); retval = ifxusb_driver_probe(); if (retval < 0) { IFX_ERROR("%s retval=%d\n", __func__, retval); return retval; } return retval; }
/*! \brief inlined by ifxusb_driver_probe(), handling host mode probing. Run at each host core. */ static inline int ifxusb_driver_probe_h(ifxhcd_hcd_t *_hcd, int _irq, uint32_t _iobase, uint32_t _fifomem, uint32_t _fifodbg ) { int retval = 0; IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ ); ifxusb_power_on_h (&_hcd->core_if); mdelay(50); ifxusb_phy_power_on_h (&_hcd->core_if); // Test mdelay(50); ifxusb_hard_reset_h(&_hcd->core_if); retval =ifxusb_core_if_init_h(&_hcd->core_if, _irq, _iobase, _fifomem, _fifodbg); if(retval) return retval; ifxusb_host_core_init(&_hcd->core_if,&ifxusb_module_params_h); ifxusb_disable_global_interrupts_h( &_hcd->core_if); /* The driver is now initialized and need to be registered into Linux USB sub-system */ retval = ifxhcd_init(_hcd); // hook the hcd into usb ss if (retval != 0) { IFX_ERROR("_hcd_init failed\n"); return retval; } //ifxusb_enable_global_interrupts_h( _hcd->core_if ); // this should be done at hcd_start , including hcd_interrupt return 0; }
/*! \brief This function completes a request. It call's the request call back. */ static void request_done_ep0(ifxpcd_request_t *_ifxreq, int _status) { IFX_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__,_ifxreq); if(!_ifxreq) { IFX_ERROR("%s() %d invalid _ifxreq\n",__func__,__LINE__); return; } _ifxreq->sysreq.status = _status; list_del_init(&_ifxreq->trq); #ifdef __DO_PCD_UNLOCK__ SPIN_UNLOCK(&ifxusb_pcd.lock); #endif if(_ifxreq->sysreq.complete) _ifxreq->sysreq.complete(&ifxusb_pcd.ifxep[0].sysep, &_ifxreq->sysreq); #ifdef __DO_PCD_UNLOCK__ SPIN_LOCK(&ifxusb_pcd.lock); #endif }
/*! \brief This function is called when a driver is unregistered. This happens when the rmmod command is executed. The device may or may not be electrically present. If it is present, the driver stops device processing. Any resources used on behalf of this device are freed. */ static int ifxusb_driver_remove(struct platform_device *_dev) { IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ ); #ifdef __IS_HOST__ #if defined(__DO_OC_INT__) #if defined(__DO_OC_INT_ENABLE__) ifxusb_oc_int_off(); #endif if(oc_int_installed && oc_int_id) free_irq((unsigned int)IFXUSB_OC_IRQ, oc_int_id ); oc_int_installed=0; oc_int_id=NULL; #endif #if defined(__IS_DUAL__) ifxhcd_remove(&ifxusb_hcd_1); ifxusb_core_if_remove(&ifxusb_hcd_1.core_if ); ifxhcd_remove(&ifxusb_hcd_2); ifxusb_core_if_remove(&ifxusb_hcd_2.core_if ); #else ifxhcd_remove(&ifxusb_hcd); ifxusb_core_if_remove(&ifxusb_hcd.core_if ); #endif #endif #ifdef __IS_DEVICE__ ifxpcd_remove(); ifxusb_core_if_remove(&ifxusb_pcd.core_if ); #endif /* Remove the device attributes */ ifxusb_attr_remove(&_dev->dev); return 0; }
/*! \brief Parsing the parameters taken when module load */ static void parse_parms(void) { IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ ); #ifdef __IS_HOST__ h_dbg_lvl=dbg_lvl; #endif #ifdef __IS_DEVICE__ d_dbg_lvl=dbg_lvl; #endif switch(dma_burst_size) { case 0: case 1: case 4: case 8: case 16: ifxusb_module_params.dma_burst_size=dma_burst_size; break; default: ifxusb_module_params.dma_burst_size=default_param_dma_burst_size; } if(speed==0 || speed==1) ifxusb_module_params.speed=speed; else ifxusb_module_params.speed=default_param_speed; if(max_transfer_size>=2048 && max_transfer_size<=65535) ifxusb_module_params.max_transfer_size=max_transfer_size; else ifxusb_module_params.max_transfer_size=default_param_max_transfer_size; if(max_packet_count>=15 && max_packet_count<=511) ifxusb_module_params.max_packet_count=max_packet_count; else ifxusb_module_params.max_packet_count=default_param_max_packet_count; switch(phy_utmi_width) { case 8: case 16: ifxusb_module_params.phy_utmi_width=phy_utmi_width; break; default: ifxusb_module_params.phy_utmi_width=default_param_phy_utmi_width; } if(turn_around_time_hs>=0 && turn_around_time_hs<=7) ifxusb_module_params.turn_around_time_hs=turn_around_time_hs; else ifxusb_module_params.turn_around_time_hs=default_param_turn_around_time_hs; if(turn_around_time_fs>=0 && turn_around_time_fs<=7) ifxusb_module_params.turn_around_time_fs=turn_around_time_fs; else ifxusb_module_params.turn_around_time_fs=default_param_turn_around_time_fs; if(timeout_cal_hs>=0 && timeout_cal_hs<=7) ifxusb_module_params.timeout_cal_hs=timeout_cal_hs; else ifxusb_module_params.timeout_cal_hs=default_param_timeout_cal_hs; if(timeout_cal_fs>=0 && timeout_cal_fs<=7) ifxusb_module_params.timeout_cal_fs=timeout_cal_fs; else ifxusb_module_params.timeout_cal_fs=default_param_timeout_cal_fs; if(data_fifo_size>=32 && data_fifo_size<=32768) ifxusb_module_params.data_fifo_size=data_fifo_size; else ifxusb_module_params.data_fifo_size=default_param_data_fifo_size; #ifdef __IS_HOST__ if(host_channels>=1 && host_channels<=16) ifxusb_module_params.host_channels=host_channels; else ifxusb_module_params.host_channels=default_param_host_channels; if(rx_fifo_size>=16 && rx_fifo_size<=32768) ifxusb_module_params.rx_fifo_size=rx_fifo_size; else ifxusb_module_params.rx_fifo_size=default_param_rx_fifo_size; if(nperio_tx_fifo_size>=16 && nperio_tx_fifo_size<=32768) ifxusb_module_params.nperio_tx_fifo_size=nperio_tx_fifo_size; else ifxusb_module_params.nperio_tx_fifo_size=default_param_nperio_tx_fifo_size; if(perio_tx_fifo_size>=16 && perio_tx_fifo_size<=32768) ifxusb_module_params.perio_tx_fifo_size=perio_tx_fifo_size; else ifxusb_module_params.perio_tx_fifo_size=default_param_perio_tx_fifo_size; #endif //__IS_HOST__ #ifdef __IS_DEVICE__ if(rx_fifo_size>=16 && rx_fifo_size<=32768) ifxusb_module_params.rx_fifo_size=rx_fifo_size; else ifxusb_module_params.rx_fifo_size=default_param_rx_fifo_size; #ifdef __DED_FIFO__ if(tx_fifo_size_00>=16 && tx_fifo_size_00<=32768) ifxusb_module_params.tx_fifo_size[ 0]=tx_fifo_size_00; else ifxusb_module_params.tx_fifo_size[ 0]=default_param_tx_fifo_size_00; if(tx_fifo_size_01>=0 && tx_fifo_size_01<=32768) ifxusb_module_params.tx_fifo_size[ 1]=tx_fifo_size_01; else ifxusb_module_params.tx_fifo_size[ 1]=default_param_tx_fifo_size_01; if(tx_fifo_size_02>=0 && tx_fifo_size_02<=32768) ifxusb_module_params.tx_fifo_size[ 2]=tx_fifo_size_02; else ifxusb_module_params.tx_fifo_size[ 2]=default_param_tx_fifo_size_02; if(tx_fifo_size_03>=0 && tx_fifo_size_03<=32768) ifxusb_module_params.tx_fifo_size[ 3]=tx_fifo_size_03; else ifxusb_module_params.tx_fifo_size[ 3]=default_param_tx_fifo_size_03; if(tx_fifo_size_04>=0 && tx_fifo_size_04<=32768) ifxusb_module_params.tx_fifo_size[ 4]=tx_fifo_size_04; else ifxusb_module_params.tx_fifo_size[ 4]=default_param_tx_fifo_size_04; if(tx_fifo_size_05>=0 && tx_fifo_size_05<=32768) ifxusb_module_params.tx_fifo_size[ 5]=tx_fifo_size_05; else ifxusb_module_params.tx_fifo_size[ 5]=default_param_tx_fifo_size_05; if(tx_fifo_size_06>=0 && tx_fifo_size_06<=32768) ifxusb_module_params.tx_fifo_size[ 6]=tx_fifo_size_06; else ifxusb_module_params.tx_fifo_size[ 6]=default_param_tx_fifo_size_06; if(tx_fifo_size_07>=0 && tx_fifo_size_07<=32768) ifxusb_module_params.tx_fifo_size[ 7]=tx_fifo_size_07; else ifxusb_module_params.tx_fifo_size[ 7]=default_param_tx_fifo_size_07; if(tx_fifo_size_08>=0 && tx_fifo_size_08<=32768) ifxusb_module_params.tx_fifo_size[ 8]=tx_fifo_size_08; else ifxusb_module_params.tx_fifo_size[ 8]=default_param_tx_fifo_size_08; if(tx_fifo_size_09>=0 && tx_fifo_size_09<=32768) ifxusb_module_params.tx_fifo_size[ 9]=tx_fifo_size_09; else ifxusb_module_params.tx_fifo_size[ 9]=default_param_tx_fifo_size_09; if(tx_fifo_size_10>=0 && tx_fifo_size_10<=32768) ifxusb_module_params.tx_fifo_size[10]=tx_fifo_size_10; else ifxusb_module_params.tx_fifo_size[10]=default_param_tx_fifo_size_10; if(tx_fifo_size_11>=0 && tx_fifo_size_11<=32768) ifxusb_module_params.tx_fifo_size[11]=tx_fifo_size_11; else ifxusb_module_params.tx_fifo_size[11]=default_param_tx_fifo_size_11; if(tx_fifo_size_12>=0 && tx_fifo_size_12<=32768) ifxusb_module_params.tx_fifo_size[12]=tx_fifo_size_12; else ifxusb_module_params.tx_fifo_size[12]=default_param_tx_fifo_size_12; if(tx_fifo_size_13>=0 && tx_fifo_size_13<=32768) ifxusb_module_params.tx_fifo_size[13]=tx_fifo_size_13; else ifxusb_module_params.tx_fifo_size[13]=default_param_tx_fifo_size_13; if(tx_fifo_size_14>=0 && tx_fifo_size_14<=32768) ifxusb_module_params.tx_fifo_size[14]=tx_fifo_size_14; else ifxusb_module_params.tx_fifo_size[14]=default_param_tx_fifo_size_14; if(tx_fifo_size_15>=0 && tx_fifo_size_15<=32768) ifxusb_module_params.tx_fifo_size[15]=tx_fifo_size_15; else ifxusb_module_params.tx_fifo_size[15]=default_param_tx_fifo_size_15; if(thr_ctl==0 || thr_ctl==1) ifxusb_module_params.thr_ctl=thr_ctl; else ifxusb_module_params.thr_ctl=default_param_thr_ctl; if(tx_thr_length>=16 && tx_thr_length<=511) ifxusb_module_params.tx_thr_length=tx_thr_length; else ifxusb_module_params.tx_thr_length=default_param_tx_thr_length; if(rx_thr_length>=16 && rx_thr_length<=511) ifxusb_module_params.rx_thr_length=rx_thr_length; else ifxusb_module_params.rx_thr_length=default_param_rx_thr_length; #else //__DED_FIFO__ if(nperio_tx_fifo_size>=16 && nperio_tx_fifo_size<=32768) ifxusb_module_params.tx_fifo_size[ 0]=nperio_tx_fifo_size; else ifxusb_module_params.tx_fifo_size[ 0]=default_param_nperio_tx_fifo_size; if(perio_tx_fifo_size_01>=0 && perio_tx_fifo_size_01<=32768) ifxusb_module_params.tx_fifo_size[ 1]=perio_tx_fifo_size_01; else ifxusb_module_params.tx_fifo_size[ 1]=default_param_perio_tx_fifo_size_01; if(perio_tx_fifo_size_02>=0 && perio_tx_fifo_size_02<=32768) ifxusb_module_params.tx_fifo_size[ 2]=perio_tx_fifo_size_02; else ifxusb_module_params.tx_fifo_size[ 2]=default_param_perio_tx_fifo_size_02; if(perio_tx_fifo_size_03>=0 && perio_tx_fifo_size_03<=32768) ifxusb_module_params.tx_fifo_size[ 3]=perio_tx_fifo_size_03; else ifxusb_module_params.tx_fifo_size[ 3]=default_param_perio_tx_fifo_size_03; if(perio_tx_fifo_size_04>=0 && perio_tx_fifo_size_04<=32768) ifxusb_module_params.tx_fifo_size[ 4]=perio_tx_fifo_size_04; else ifxusb_module_params.tx_fifo_size[ 4]=default_param_perio_tx_fifo_size_04; if(perio_tx_fifo_size_05>=0 && perio_tx_fifo_size_05<=32768) ifxusb_module_params.tx_fifo_size[ 5]=perio_tx_fifo_size_05; else ifxusb_module_params.tx_fifo_size[ 5]=default_param_perio_tx_fifo_size_05; if(perio_tx_fifo_size_06>=0 && perio_tx_fifo_size_06<=32768) ifxusb_module_params.tx_fifo_size[ 6]=perio_tx_fifo_size_06; else ifxusb_module_params.tx_fifo_size[ 6]=default_param_perio_tx_fifo_size_06; if(perio_tx_fifo_size_07>=0 && perio_tx_fifo_size_07<=32768) ifxusb_module_params.tx_fifo_size[ 7]=perio_tx_fifo_size_07; else ifxusb_module_params.tx_fifo_size[ 7]=default_param_perio_tx_fifo_size_07; if(perio_tx_fifo_size_08>=0 && perio_tx_fifo_size_08<=32768) ifxusb_module_params.tx_fifo_size[ 8]=perio_tx_fifo_size_08; else ifxusb_module_params.tx_fifo_size[ 8]=default_param_perio_tx_fifo_size_08; if(perio_tx_fifo_size_09>=0 && perio_tx_fifo_size_09<=32768) ifxusb_module_params.tx_fifo_size[ 9]=perio_tx_fifo_size_09; else ifxusb_module_params.tx_fifo_size[ 9]=default_param_perio_tx_fifo_size_09; if(perio_tx_fifo_size_10>=0 && perio_tx_fifo_size_10<=32768) ifxusb_module_params.tx_fifo_size[10]=perio_tx_fifo_size_10; else ifxusb_module_params.tx_fifo_size[10]=default_param_perio_tx_fifo_size_10; if(perio_tx_fifo_size_11>=0 && perio_tx_fifo_size_11<=32768) ifxusb_module_params.tx_fifo_size[11]=perio_tx_fifo_size_11; else ifxusb_module_params.tx_fifo_size[11]=default_param_perio_tx_fifo_size_11; if(perio_tx_fifo_size_12>=0 && perio_tx_fifo_size_12<=32768) ifxusb_module_params.tx_fifo_size[12]=perio_tx_fifo_size_12; else ifxusb_module_params.tx_fifo_size[12]=default_param_perio_tx_fifo_size_12; if(perio_tx_fifo_size_13>=0 && perio_tx_fifo_size_13<=32768) ifxusb_module_params.tx_fifo_size[13]=perio_tx_fifo_size_13; else ifxusb_module_params.tx_fifo_size[13]=default_param_perio_tx_fifo_size_13; if(perio_tx_fifo_size_14>=0 && perio_tx_fifo_size_14<=32768) ifxusb_module_params.tx_fifo_size[14]=perio_tx_fifo_size_14; else ifxusb_module_params.tx_fifo_size[14]=default_param_perio_tx_fifo_size_14; if(perio_tx_fifo_size_15>=0 && perio_tx_fifo_size_15<=32768) ifxusb_module_params.tx_fifo_size[15]=perio_tx_fifo_size_15; else ifxusb_module_params.tx_fifo_size[15]=default_param_perio_tx_fifo_size_15; #endif //__DED_FIFO__ #endif //__IS_DEVICE__ }
void __exit ifxusb_driver_cleanup(void) { IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ ); ifxusb_driver_remove(); IFX_PRINT("%s module removed\n", ifxusb_driver_name); }
/*! \brief This function is called by module management in 2.6 kernel or by ifxusb_driver_init with 2.4 kernel It is to probe and setup IFXUSB core(s). */ static int ifxusb_driver_probe(struct platform_device *_dev) { int retval = 0; int *pins = _dev->dev.platform_data; if (ltq_is_vr9()) { gpio_request(6, "id1"); gpio_request(9, "id2"); gpio_direction_input(6); gpio_direction_input(9); } if (pins) { if (pins[0]) { gpio_request(pins[0], "vbus1"); gpio_direction_output(pins[0], 1); } if (pins[1] && ltq_is_vr9()) { gpio_request(pins[1], "vbus2"); gpio_direction_output(pins[1], 1); } } // Parsing and store the parameters IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ ); parse_parms(); #ifdef __IS_HOST__ #if defined(__IS_DUAL__) memset(&ifxusb_hcd_1, 0, sizeof(ifxhcd_hcd_t)); memset(&ifxusb_hcd_2, 0, sizeof(ifxhcd_hcd_t)); ifxusb_hcd_1.core_if.core_no=0; ifxusb_hcd_2.core_if.core_no=1; ifxusb_hcd_1.core_if.core_name=(char *)ifxusb_hcd_name_1; ifxusb_hcd_2.core_if.core_name=(char *)ifxusb_hcd_name_2; ifxusb_hcd_1.dev=&_dev->dev; ifxusb_hcd_2.dev=&_dev->dev; retval = ifxusb_driver_probe_h(&ifxusb_hcd_1, IFX_USB0_IR, IFXUSB1_IOMEM_BASE, IFXUSB1_FIFOMEM_BASE, IFXUSB1_FIFODBG_BASE ); if(retval) goto ifxusb_driver_probe_fail; retval = ifxusb_driver_probe_h(&ifxusb_hcd_2, IFX_USB1_IR, IFXUSB2_IOMEM_BASE, IFXUSB2_FIFOMEM_BASE, IFXUSB2_FIFODBG_BASE ); if(retval) goto ifxusb_driver_probe_fail; #elif defined(__IS_FIRST__) memset(&ifxusb_hcd, 0, sizeof(ifxhcd_hcd_t)); ifxusb_hcd.core_if.core_no=0; ifxusb_hcd.core_if.core_name=(char *)ifxusb_hcd_name; ifxusb_hcd.dev=&_dev->dev; retval = ifxusb_driver_probe_h(&ifxusb_hcd, IFX_USB0_IR, IFXUSB1_IOMEM_BASE, IFXUSB1_FIFOMEM_BASE, IFXUSB1_FIFODBG_BASE ); if(retval) goto ifxusb_driver_probe_fail; #elif defined(__IS_SECOND__) memset(&ifxusb_hcd, 0, sizeof(ifxhcd_hcd_t)); ifxusb_hcd.core_if.core_no=1; ifxusb_hcd.core_if.core_name=(char *)ifxusb_hcd_name; ifxusb_hcd.dev=&_dev->dev; retval = ifxusb_driver_probe_h(&ifxusb_hcd, IFX_USB1_IR, IFXUSB2_IOMEM_BASE, IFXUSB2_FIFOMEM_BASE, IFXUSB2_FIFODBG_BASE ); if(retval) goto ifxusb_driver_probe_fail; #else memset(&ifxusb_hcd, 0, sizeof(ifxhcd_hcd_t)); ifxusb_hcd.core_if.core_no=0; ifxusb_hcd.core_if.core_name=(char *)ifxusb_hcd_name; ifxusb_hcd.dev=&_dev->dev; retval = ifxusb_driver_probe_h(&ifxusb_hcd, IFXUSB_IRQ, IFXUSB_IOMEM_BASE, IFXUSB_FIFOMEM_BASE, IFXUSB_FIFODBG_BASE ); if(retval) goto ifxusb_driver_probe_fail; #endif #if defined(__DO_OC_INT__) IFXUSB_DEBUGPL( DBG_CIL, "registering (overcurrent) handler for irq%d\n", IFXUSB_OC_IRQ); #if defined(__IS_DUAL__) request_irq((unsigned int)IFXUSB_OC_IRQ, &ifx_hcd_oc_irq, // SA_INTERRUPT|SA_SHIRQ, "ifxusb_oc", (void *)&ifxusb_hcd_1); IRQF_DISABLED | IRQF_SHARED, "ifxusb_oc", (void *)&ifxusb_hcd_1); oc_int_id=&ifxusb_hcd_1; #else request_irq((unsigned int)IFXUSB_OC_IRQ, &ifx_hcd_oc_irq, // SA_INTERRUPT|SA_SHIRQ, "ifxusb_oc", (void *)&ifxusb_hcd); IRQF_DISABLED | IRQF_SHARED, "ifxusb_oc", (void *)&ifxusb_hcd); oc_int_id=&ifxusb_hcd; #endif oc_int_installed=1; #if defined(__DO_OC_INT_ENABLE__) ifxusb_oc_int_on(); #endif #endif #endif #ifdef __IS_DEVICE__ memset(&ifxusb_pcd, 0, sizeof(ifxpcd_pcd_t)); ifxusb_pcd.core_if.core_name=(char *)&ifxusb_pcd_name[0]; ifxusb_pcd.dev=&_dev->dev; #if defined(__IS_FIRST__) ifxusb_pcd.core_if.core_no=0; retval = ifxusb_driver_probe_d(&ifxusb_pcd, IFXUSB1_IRQ, IFXUSB1_IOMEM_BASE, IFXUSB1_FIFOMEM_BASE, IFXUSB1_FIFODBG_BASE ); #elif defined(__IS_SECOND__) ifxusb_pcd.core_if.core_no=1; retval = ifxusb_driver_probe_d(&ifxusb_pcd, IFXUSB2_IRQ, IFXUSB2_IOMEM_BASE, IFXUSB2_FIFOMEM_BASE, IFXUSB2_FIFODBG_BASE ); #else ifxusb_pcd.core_if.core_no=0; retval = ifxusb_driver_probe_d(&ifxusb_pcd, IFXUSB_IRQ, IFXUSB_IOMEM_BASE, IFXUSB_FIFOMEM_BASE, IFXUSB_FIFODBG_BASE ); #endif if(retval) goto ifxusb_driver_probe_fail; #endif ifxusb_attr_create(&_dev->dev); return 0; ifxusb_driver_probe_fail: ifxusb_driver_remove(_dev); return retval; }
/*! \brief Parsing the parameters taken when module load */ static void parse_parms(void) { ifxusb_params_t *params; IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ ); #ifdef __IS_HOST__ h_dbg_lvl=dbg_lvl; params=&ifxusb_module_params_h; #endif #ifdef __IS_DEVICE__ d_dbg_lvl=dbg_lvl; params=&ifxusb_module_params_d; #endif switch(dma_burst_size) { case 0: case 1: case 4: case 8: case 16: params->dma_burst_size=dma_burst_size; break; default: #if defined(__IS_VR9__) { unsigned int chipid; unsigned int partnum; chipid=*((volatile uint32_t *)IFX_MPS_CHIPID); partnum=(chipid&0x0FFFF000)>>12; switch(partnum) { case 0x000B: //VRX288_A2x case 0x000E: //VRX282_A2x case 0x000C: //VRX268_A2x case 0x000D: //GRX288_A2x params->dma_burst_size=default_param_dma_burst_size_n; break; default: params->dma_burst_size=default_param_dma_burst_size; } printk(KERN_INFO "Chip Version :%04x BurstSize=%d\n",partnum,params->dma_burst_size); } #else params->dma_burst_size=default_param_dma_burst_size; #endif } if(speed==0 || speed==1) params->speed=speed; else params->speed=default_param_speed; if(max_transfer_size>=2048 && max_transfer_size<=65535) params->max_transfer_size=max_transfer_size; else params->max_transfer_size=default_param_max_transfer_size; if(max_packet_count>=15 && max_packet_count<=511) params->max_packet_count=max_packet_count; else params->max_packet_count=default_param_max_packet_count; switch(phy_utmi_width) { case 8: case 16: params->phy_utmi_width=phy_utmi_width; break; default: params->phy_utmi_width=default_param_phy_utmi_width; } if(turn_around_time_hs>=0 && turn_around_time_hs<=7) params->turn_around_time_hs=turn_around_time_hs; else params->turn_around_time_hs=default_param_turn_around_time_hs; if(turn_around_time_fs>=0 && turn_around_time_fs<=7) params->turn_around_time_fs=turn_around_time_fs; else params->turn_around_time_fs=default_param_turn_around_time_fs; if(timeout_cal_hs>=0 && timeout_cal_hs<=7) params->timeout_cal_hs=timeout_cal_hs; else params->timeout_cal_hs=default_param_timeout_cal_hs; if(timeout_cal_fs>=0 && timeout_cal_fs<=7) params->timeout_cal_fs=timeout_cal_fs; else params->timeout_cal_fs=default_param_timeout_cal_fs; if(data_fifo_size>=32 && data_fifo_size<=32768) params->data_fifo_size=data_fifo_size; else params->data_fifo_size=default_param_data_fifo_size; #ifdef __IS_HOST__ if(host_channels>=1 && host_channels<=16) params->host_channels=host_channels; else params->host_channels=default_param_host_channels; if(rx_fifo_size>=16 && rx_fifo_size<=32768) params->rx_fifo_size=rx_fifo_size; else params->rx_fifo_size=default_param_rx_fifo_size; if(nperio_tx_fifo_size>=16 && nperio_tx_fifo_size<=32768) params->nperio_tx_fifo_size=nperio_tx_fifo_size; else params->nperio_tx_fifo_size=default_param_nperio_tx_fifo_size; if(perio_tx_fifo_size>=16 && perio_tx_fifo_size<=32768) params->perio_tx_fifo_size=perio_tx_fifo_size; else params->perio_tx_fifo_size=default_param_perio_tx_fifo_size; #endif //__IS_HOST__ #ifdef __IS_DEVICE__ if(rx_fifo_size>=16 && rx_fifo_size<=32768) params->rx_fifo_size=rx_fifo_size; else params->rx_fifo_size=default_param_rx_fifo_size; #ifdef __DED_FIFO__ if(tx_fifo_size_00>=16 && tx_fifo_size_00<=32768) params->tx_fifo_size[ 0]=tx_fifo_size_00; else params->tx_fifo_size[ 0]=default_param_tx_fifo_size_00; if(tx_fifo_size_01>=0 && tx_fifo_size_01<=32768) params->tx_fifo_size[ 1]=tx_fifo_size_01; else params->tx_fifo_size[ 1]=default_param_tx_fifo_size_01; if(tx_fifo_size_02>=0 && tx_fifo_size_02<=32768) params->tx_fifo_size[ 2]=tx_fifo_size_02; else params->tx_fifo_size[ 2]=default_param_tx_fifo_size_02; if(tx_fifo_size_03>=0 && tx_fifo_size_03<=32768) params->tx_fifo_size[ 3]=tx_fifo_size_03; else params->tx_fifo_size[ 3]=default_param_tx_fifo_size_03; if(tx_fifo_size_04>=0 && tx_fifo_size_04<=32768) params->tx_fifo_size[ 4]=tx_fifo_size_04; else params->tx_fifo_size[ 4]=default_param_tx_fifo_size_04; if(tx_fifo_size_05>=0 && tx_fifo_size_05<=32768) params->tx_fifo_size[ 5]=tx_fifo_size_05; else params->tx_fifo_size[ 5]=default_param_tx_fifo_size_05; if(tx_fifo_size_06>=0 && tx_fifo_size_06<=32768) params->tx_fifo_size[ 6]=tx_fifo_size_06; else params->tx_fifo_size[ 6]=default_param_tx_fifo_size_06; if(tx_fifo_size_07>=0 && tx_fifo_size_07<=32768) params->tx_fifo_size[ 7]=tx_fifo_size_07; else params->tx_fifo_size[ 7]=default_param_tx_fifo_size_07; if(tx_fifo_size_08>=0 && tx_fifo_size_08<=32768) params->tx_fifo_size[ 8]=tx_fifo_size_08; else params->tx_fifo_size[ 8]=default_param_tx_fifo_size_08; if(tx_fifo_size_09>=0 && tx_fifo_size_09<=32768) params->tx_fifo_size[ 9]=tx_fifo_size_09; else params->tx_fifo_size[ 9]=default_param_tx_fifo_size_09; if(tx_fifo_size_10>=0 && tx_fifo_size_10<=32768) params->tx_fifo_size[10]=tx_fifo_size_10; else params->tx_fifo_size[10]=default_param_tx_fifo_size_10; if(tx_fifo_size_11>=0 && tx_fifo_size_11<=32768) params->tx_fifo_size[11]=tx_fifo_size_11; else params->tx_fifo_size[11]=default_param_tx_fifo_size_11; if(tx_fifo_size_12>=0 && tx_fifo_size_12<=32768) params->tx_fifo_size[12]=tx_fifo_size_12; else params->tx_fifo_size[12]=default_param_tx_fifo_size_12; if(tx_fifo_size_13>=0 && tx_fifo_size_13<=32768) params->tx_fifo_size[13]=tx_fifo_size_13; else params->tx_fifo_size[13]=default_param_tx_fifo_size_13; if(tx_fifo_size_14>=0 && tx_fifo_size_14<=32768) params->tx_fifo_size[14]=tx_fifo_size_14; else params->tx_fifo_size[14]=default_param_tx_fifo_size_14; if(tx_fifo_size_15>=0 && tx_fifo_size_15<=32768) params->tx_fifo_size[15]=tx_fifo_size_15; else params->tx_fifo_size[15]=default_param_tx_fifo_size_15; if(thr_ctl==0 || thr_ctl==1) params->thr_ctl=thr_ctl; else params->thr_ctl=default_param_thr_ctl; if(tx_thr_length>=16 && tx_thr_length<=511) params->tx_thr_length=tx_thr_length; else params->tx_thr_length=default_param_tx_thr_length; if(rx_thr_length>=16 && rx_thr_length<=511) params->rx_thr_length=rx_thr_length; else params->rx_thr_length=default_param_rx_thr_length; #else //__DED_FIFO__ if(nperio_tx_fifo_size>=16 && nperio_tx_fifo_size<=32768) params->tx_fifo_size[ 0]=nperio_tx_fifo_size; else params->tx_fifo_size[ 0]=default_param_nperio_tx_fifo_size; if(perio_tx_fifo_size_01>=0 && perio_tx_fifo_size_01<=32768) params->tx_fifo_size[ 1]=perio_tx_fifo_size_01; else params->tx_fifo_size[ 1]=default_param_perio_tx_fifo_size_01; if(perio_tx_fifo_size_02>=0 && perio_tx_fifo_size_02<=32768) params->tx_fifo_size[ 2]=perio_tx_fifo_size_02; else params->tx_fifo_size[ 2]=default_param_perio_tx_fifo_size_02; if(perio_tx_fifo_size_03>=0 && perio_tx_fifo_size_03<=32768) params->tx_fifo_size[ 3]=perio_tx_fifo_size_03; else params->tx_fifo_size[ 3]=default_param_perio_tx_fifo_size_03; if(perio_tx_fifo_size_04>=0 && perio_tx_fifo_size_04<=32768) params->tx_fifo_size[ 4]=perio_tx_fifo_size_04; else params->tx_fifo_size[ 4]=default_param_perio_tx_fifo_size_04; if(perio_tx_fifo_size_05>=0 && perio_tx_fifo_size_05<=32768) params->tx_fifo_size[ 5]=perio_tx_fifo_size_05; else params->tx_fifo_size[ 5]=default_param_perio_tx_fifo_size_05; if(perio_tx_fifo_size_06>=0 && perio_tx_fifo_size_06<=32768) params->tx_fifo_size[ 6]=perio_tx_fifo_size_06; else params->tx_fifo_size[ 6]=default_param_perio_tx_fifo_size_06; if(perio_tx_fifo_size_07>=0 && perio_tx_fifo_size_07<=32768) params->tx_fifo_size[ 7]=perio_tx_fifo_size_07; else params->tx_fifo_size[ 7]=default_param_perio_tx_fifo_size_07; if(perio_tx_fifo_size_08>=0 && perio_tx_fifo_size_08<=32768) params->tx_fifo_size[ 8]=perio_tx_fifo_size_08; else params->tx_fifo_size[ 8]=default_param_perio_tx_fifo_size_08; if(perio_tx_fifo_size_09>=0 && perio_tx_fifo_size_09<=32768) params->tx_fifo_size[ 9]=perio_tx_fifo_size_09; else params->tx_fifo_size[ 9]=default_param_perio_tx_fifo_size_09; if(perio_tx_fifo_size_10>=0 && perio_tx_fifo_size_10<=32768) params->tx_fifo_size[10]=perio_tx_fifo_size_10; else params->tx_fifo_size[10]=default_param_perio_tx_fifo_size_10; if(perio_tx_fifo_size_11>=0 && perio_tx_fifo_size_11<=32768) params->tx_fifo_size[11]=perio_tx_fifo_size_11; else params->tx_fifo_size[11]=default_param_perio_tx_fifo_size_11; if(perio_tx_fifo_size_12>=0 && perio_tx_fifo_size_12<=32768) params->tx_fifo_size[12]=perio_tx_fifo_size_12; else params->tx_fifo_size[12]=default_param_perio_tx_fifo_size_12; if(perio_tx_fifo_size_13>=0 && perio_tx_fifo_size_13<=32768) params->tx_fifo_size[13]=perio_tx_fifo_size_13; else params->tx_fifo_size[13]=default_param_perio_tx_fifo_size_13; if(perio_tx_fifo_size_14>=0 && perio_tx_fifo_size_14<=32768) params->tx_fifo_size[14]=perio_tx_fifo_size_14; else params->tx_fifo_size[14]=default_param_perio_tx_fifo_size_14; if(perio_tx_fifo_size_15>=0 && perio_tx_fifo_size_15<=32768) params->tx_fifo_size[15]=perio_tx_fifo_size_15; else params->tx_fifo_size[15]=default_param_perio_tx_fifo_size_15; #endif //__DED_FIFO__ #endif //__IS_DEVICE__ }
int __init ifxusb_pcd_driver_init(void) #endif { int retval = 0; IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ ); #if defined(__IS_HOST__) IFX_PRINT("%s: version %s\n", ifxusb_hcd_driver_name, IFXUSB_VERSION); #else IFX_PRINT("%s: version %s\n", ifxusb_pcd_driver_name, IFXUSB_VERSION); #endif #if 0 #if defined(__IS_TWINPASS__) IFX_PRINT(" OPTION: __IS_TWINPASS__\n"); #elif defined(__IS_DANUBE__) IFX_PRINT(" OPTION: __IS_DANUBE__\n"); #elif defined(__IS_AMAZON_SE__) IFX_PRINT(" OPTION: __IS_AMAZON_SE__\n"); #elif defined(__IS_AR9__) IFX_PRINT(" OPTION: __IS_AR9__\n"); #elif defined(__IS_VR9__) IFX_PRINT(" OPTION: __IS_VR9__\n"); #elif defined(__IS_AR10__) IFX_PRINT(" OPTION: __IS_AR10__\n"); #else IFX_PRINT(" OPTION: NO PLATFORM DEFINED\n"); #endif #ifdef __UEIP__ IFX_PRINT(" OPTION: __UEIP__\n"); #endif #ifdef __PHY_LONG_PREEMP__ IFX_PRINT(" OPTION: __PHY_LONG_PREEMP__\n"); #endif #ifdef __FORCE_USB11__ IFX_PRINT(" OPTION: __FORCE_USB11__\n"); #endif #ifdef __UNALIGNED_BUF_ADJ__ IFX_PRINT(" OPTION: __UNALIGNED_BUF_ADJ__\n"); #endif #ifdef __UNALIGNED_BUF_CHK__ IFX_PRINT(" OPTION: __UNALIGNED_BUF_CHK__\n"); #endif #ifdef __UNALIGNED_BUF_BURST__ IFX_PRINT(" OPTION: __UNALIGNED_BUF_BURST__\n"); #endif #ifdef __DEBUG__ IFX_PRINT(" OPTION: __DEBUG__\n"); #endif #ifdef __ENABLE_DUMP__ IFX_PRINT(" OPTION: __ENABLE_DUMP__\n"); #endif #ifdef __IS_HOST__ IFX_PRINT(" OPTION: __IS_HOST__\n"); #ifdef __IS_DUAL__ IFX_PRINT(" __IS_DUAL__\n"); #endif #ifdef __IS_FIRST__ IFX_PRINT(" __IS_FIRST__\n"); #endif #ifdef __IS_SECOND__ IFX_PRINT(" __IS_SECOND__\n"); #endif #ifdef __WITH_HS_ELECT_TST__ IFX_PRINT(" __WITH_HS_ELECT_TST__\n"); #endif #ifdef __EN_ISOC__ IFX_PRINT(" __EN_ISOC__\n"); #endif #ifdef __EN_ISOC_SPLIT__ IFX_PRINT(" __EN_ISOC_SPLIT__\n"); #endif #ifdef __EPQD_DESTROY_TIMEOUT__ IFX_PRINT(" __EPQD_DESTROY_TIMEOUT__\n"); #endif #ifdef __DYN_SOF_INTR__ IFX_PRINT(" __DYN_SOF_INTR__\n"); #endif #else IFX_PRINT(" OPTION: __IS_DEVICE__\n"); #ifdef __DED_INTR__ IFX_PRINT(" __DED_INTR__\n"); #endif #ifdef __DED_FIFO__ IFX_PRINT(" __DED_FIFO__\n"); #endif #ifdef __DESC_DMA__ IFX_PRINT(" __DESC_DMA__\n"); #endif #ifdef __IS_FIRST__ IFX_PRINT(" __IS_FIRST__\n"); #endif #ifdef __IS_SECOND__ IFX_PRINT(" __IS_SECOND__\n"); #endif #ifdef __GADGET_TASKLET_TX__ IFX_PRINT(" __GADGET_TASKLET_TX__\n"); #endif #ifdef __GADGET_TASKLET_RX__ IFX_PRINT(" __GADGET_TASKLET_RX__\n"); #endif #ifdef __GADGET_TASKLET_HIGH__ IFX_PRINT(" __GADGET_TASKLET_HIGH__\n"); #endif #ifdef __DO_PCD_UNLOCK__ IFX_PRINT(" __DO_PCD_UNLOCK__\n"); #endif #ifdef __GADGET_LED__ IFX_PRINT(" __GADGET_LED__\n"); #endif #ifdef __ECM_NO_INTR__ IFX_PRINT(" __ECM_NO_INTR__\n"); #endif #ifdef __NOSWAPINCTRL__ IFX_PRINT(" __NOSWAPINCTRL__\n"); #endif #ifdef __MAC_ECM_FIX__ IFX_PRINT(" __MAC_ECM_FIX__\n"); #endif #ifdef __RETAIN_BUF_TX__ IFX_PRINT(" __RETAIN_BUF_TX__\n"); #endif #ifdef __RETAIN_BUF_RX__ IFX_PRINT(" __RETAIN_BUF_RX__\n"); #endif #ifdef __QUICKNAK__ IFX_PRINT(" __QUICKNAK__\n"); #endif #endif #endif retval = platform_driver_register(&ifxusb_driver); if (retval < 0) { IFX_ERROR("%s retval=%d\n", __func__, retval); return retval; } #ifdef __IS_HOST__ ifxusb_device.name = ifxusb_hcd_driver_name; #else ifxusb_device.name = ifxusb_pcd_driver_name; #endif if (ifxusb_device.dev.parent) retval = -EBUSY; else retval = platform_device_register(&ifxusb_device); if (retval < 0) { IFX_ERROR("%s retval=%d\n", __func__, retval); platform_driver_unregister(&ifxusb_driver); return retval; } return retval; }
/*! \brief This function is called by module management in 2.6 kernel or by ifxusb_driver_init with 2.4 kernel It is to probe and setup IFXUSB core(s). */ static int ifxusb_driver_probe(struct platform_device *_pdev) { int retval = 0; struct device_node *np; int gpio_count; u32 port_mask = 0x1; #ifdef __IS_DANUBE__ np = of_find_compatible_node(NULL, NULL, "lantiq,ifxhcd-danube"); #elif defined __IS_AMAZON_SE__ np = of_find_compatible_node(NULL, NULL, "lantiq,ifxhcd-ase"); #elif defined __IS_AR9__ np = of_find_compatible_node(NULL, NULL, "lantiq,ifxhcd-arx100"); #elif defined __IS_VR9__ np = of_find_compatible_node(NULL, NULL, "lantiq,ifxhcd-xrx200"); #elif defined __IS_AR10__ np = of_find_compatible_node(NULL, NULL, "lantiq,ifxhcd-arx300"); #endif if (!np) { dev_err(&_pdev->dev, "failed to find hcd device node\n"); return -ENODEV; } of_property_read_u32(np, "lantiq,portmask", &port_mask); // Parsing and store the parameters IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ ); parse_parms(); #ifdef __IS_HOST__ #if defined(__DO_OC_INT__) if(!oc_int_id) { #if defined(__IS_DUAL__) oc_int_id=&ifxusb_hcd_1; oc_int_id_1=&ifxusb_hcd_1; oc_int_id_2=&ifxusb_hcd_2; #else oc_int_id=&ifxusb_hcd; #endif } #endif #if defined(__IS_DUAL__) memset(&ifxusb_hcd_1, 0, sizeof(ifxhcd_hcd_t)); memset(&ifxusb_hcd_2, 0, sizeof(ifxhcd_hcd_t)); ifxusb_hcd_1.core_if.core_no=0; ifxusb_hcd_2.core_if.core_no=1; ifxusb_hcd_1.core_if.core_name=(char *)ifxusb_hcd_name_1; ifxusb_hcd_2.core_if.core_name=(char *)ifxusb_hcd_name_2; ifxusb_hcd_1.dev=&_pdev->dev; ifxusb_hcd_2.dev=&_pdev->dev; if (port_mask & 0x1) { retval = ifxusb_driver_probe_h(&ifxusb_hcd_1, IFXUSB1_IRQ, IFXUSB1_IOMEM_BASE, IFXUSB1_FIFOMEM_BASE, IFXUSB1_FIFODBG_BASE ); if(retval) goto ifxusb_driver_probe_fail; } if (port_mask & 0x2) { retval = ifxusb_driver_probe_h(&ifxusb_hcd_2, IFXUSB2_IRQ, IFXUSB2_IOMEM_BASE, IFXUSB2_FIFOMEM_BASE, IFXUSB2_FIFODBG_BASE ); if(retval) goto ifxusb_driver_probe_fail; } #elif defined(__IS_FIRST__) memset(&ifxusb_hcd, 0, sizeof(ifxhcd_hcd_t)); ifxusb_hcd.core_if.core_no=0; ifxusb_hcd.core_if.core_name=(char *)ifxusb_hcd_name; ifxusb_hcd.dev=&_pdev->dev; retval = ifxusb_driver_probe_h(&ifxusb_hcd, IFXUSB1_IRQ, IFXUSB1_IOMEM_BASE, IFXUSB1_FIFOMEM_BASE, IFXUSB1_FIFODBG_BASE ); if(retval) goto ifxusb_driver_probe_fail; #elif defined(__IS_SECOND__) memset(&ifxusb_hcd, 0, sizeof(ifxhcd_hcd_t)); ifxusb_hcd.core_if.core_no=1; ifxusb_hcd.core_if.core_name=(char *)ifxusb_hcd_name; ifxusb_hcd.dev=&_pdev->dev; retval = ifxusb_driver_probe_h(&ifxusb_hcd, IFXUSB2_IRQ, IFXUSB2_IOMEM_BASE, IFXUSB2_FIFOMEM_BASE, IFXUSB2_FIFODBG_BASE ); if(retval) goto ifxusb_driver_probe_fail; #else memset(&ifxusb_hcd, 0, sizeof(ifxhcd_hcd_t)); ifxusb_hcd.core_if.core_no=0; ifxusb_hcd.core_if.core_name=(char *)ifxusb_hcd_name; ifxusb_hcd.dev=&_pdev->dev; retval = ifxusb_driver_probe_h(&ifxusb_hcd, IFXUSB_IRQ, IFXUSB_IOMEM_BASE, IFXUSB_FIFOMEM_BASE, IFXUSB_FIFODBG_BASE ); if(retval) goto ifxusb_driver_probe_fail; #endif #endif #ifdef __IS_DEVICE__ memset(&ifxusb_pcd, 0, sizeof(ifxpcd_pcd_t)); ifxusb_pcd.core_if.core_name=(char *)&ifxusb_pcd_name[0]; ifxusb_pcd.dev=&_pdev->dev; #if defined(__IS_FIRST__) ifxusb_pcd.core_if.core_no=0; retval = ifxusb_driver_probe_d(&ifxusb_pcd, IFXUSB1_IRQ, IFXUSB1_IOMEM_BASE, IFXUSB1_FIFOMEM_BASE, IFXUSB1_FIFODBG_BASE ); #elif defined(__IS_SECOND__) ifxusb_pcd.core_if.core_no=1; retval = ifxusb_driver_probe_d(&ifxusb_pcd, IFXUSB2_IRQ, IFXUSB2_IOMEM_BASE, IFXUSB2_FIFOMEM_BASE, IFXUSB2_FIFODBG_BASE ); #else ifxusb_pcd.core_if.core_no=0; retval = ifxusb_driver_probe_d(&ifxusb_pcd, IFXUSB_IRQ, IFXUSB_IOMEM_BASE, IFXUSB_FIFOMEM_BASE, IFXUSB_FIFODBG_BASE ); #endif if(retval) goto ifxusb_driver_probe_fail; #endif /* #ifdef __IS_HOST__ ifxusb_attr_create_h(&_pdev->dev); #else ifxusb_attr_create_d(&_pdev->dev); #endif*/ gpio_count = of_gpio_count(np); while (gpio_count > 0) { enum of_gpio_flags flags; int gpio = of_get_gpio_flags(np, --gpio_count, &flags); if (gpio_request(gpio, "usb")) continue; dev_info(&_pdev->dev, "requested GPIO %d\n", gpio); gpio_direction_output(gpio, (flags & OF_GPIO_ACTIVE_LOW) ? (0) : (1)); } return 0; ifxusb_driver_probe_fail: ifxusb_driver_remove(_pdev); return retval; }
void request_done(ifxpcd_ep_t *_ifxep, ifxpcd_request_t *_ifxreq, int _status) { IFX_DEBUGPL(DBG_PCDV, "%s(%p,%p)\n", __func__, _ifxep,_ifxreq); if(!_ifxep) { IFX_ERROR("%s() %d invalid _ifxep\n",__func__,__LINE__); return; } if(!_ifxreq) { IFX_ERROR("%s() %d invalid _ifxreq\n",__func__,__LINE__); return; } if(_ifxep->num==0) { request_done_ep0(_ifxreq, _status); return; } _ifxreq->sysreq.status = _status; if(_ifxep->type==IFXUSB_EP_TYPE_INTR) { list_del_init(&_ifxreq->trq); if(_ifxreq->sysreq.complete) { #ifdef __DO_PCD_UNLOCK__ SPIN_UNLOCK(&ifxusb_pcd.lock); #endif _ifxreq->sysreq.complete(&_ifxep->sysep, &_ifxreq->sysreq); #ifdef __DO_PCD_UNLOCK__ SPIN_LOCK(&ifxusb_pcd.lock); #endif } } else if(_ifxep->is_in) // Tx { #if defined(__GADGET_TASKLET_TX__) list_del_init(&_ifxreq->trq); list_add_tail(&_ifxreq->trq, &_ifxep->queue_cmpt); if(!_ifxreq->sysreq.no_interrupt && !_ifxep->cmpt_tasklet_in_process) { #ifdef __GADGET_TASKLET_HIGH__ tasklet_hi_schedule(&_ifxep->cmpt_tasklet); #else tasklet_schedule(&_ifxep->cmpt_tasklet); #endif } #else list_del_init(&_ifxreq->trq); if(!_ifxreq->sysreq.no_interrupt) { while (!list_empty(&_ifxep->queue_cmpt)) { ifxpcd_request_t *req; req = list_entry(_ifxep->queue_cmpt.next, ifxpcd_request_t,trq); list_del_init(&req->trq); if(req->sysreq.complete) { #ifdef __DO_PCD_UNLOCK__ SPIN_UNLOCK(&ifxusb_pcd.lock); #endif req->sysreq.complete(&_ifxep->sysep, &req->sysreq); #ifdef __DO_PCD_UNLOCK__ SPIN_LOCK(&ifxusb_pcd.lock); #endif } else { #ifdef __req_num_dbg__ IFX_ERROR("%s() no complete EP%d Req%d\n",__func__,_ifxep->num, req->reqid); #else IFX_ERROR("%s() no complete EP%d Req %p\n",__func__,_ifxep->num, req); #endif } } if(_ifxreq->sysreq.complete) { #ifdef __DO_PCD_UNLOCK__ SPIN_UNLOCK(&ifxusb_pcd.lock); #endif _ifxreq->sysreq.complete(&_ifxep->sysep, &_ifxreq->sysreq); #ifdef __DO_PCD_UNLOCK__ SPIN_LOCK(&ifxusb_pcd.lock); #endif } else { #ifdef __req_num_dbg__ IFX_ERROR("%s() no complete EP%d Req%d\n",__func__,_ifxep->num, _ifxreq->reqid); #else IFX_ERROR("%s() no complete EP%d Req %p\n",__func__,_ifxep->num, _ifxreq); #endif } } else list_add_tail(&_ifxreq->trq, &_ifxep->queue_cmpt); #endif } else // Rx { #if defined(__GADGET_TASKLET_RX__) if(list_empty(&_ifxep->queue)) // Rx Empty, Reuse { _ifxreq->sysreq.actual=0; _ifxreq->sysreq.status=0; } else if(!_ifxreq->sysreq.no_interrupt && !_ifxep->cmpt_tasklet_in_process) { _ifxep->cmpt_tasklet_in_process=1; list_move_tail(&_ifxreq->trq, &_ifxep->queue_cmpt); #ifdef __GADGET_TASKLET_HIGH__ tasklet_hi_schedule(&_ifxep->cmpt_tasklet); #else tasklet_schedule(&_ifxep->cmpt_tasklet); #endif } else list_move_tail(&_ifxreq->trq, &_ifxep->queue_cmpt); #else if(!_ifxreq->sysreq.no_interrupt) { ifxpcd_request_t *req2; while (!list_empty(&_ifxep->queue_cmpt)) { req = list_entry(_ifxep->queue_cmpt.next, ifxpcd_request_t,trq); list_del_init(&req->trq); if(req->sysreq.complete) { #ifdef __DO_PCD_UNLOCK__ SPIN_UNLOCK(&ifxusb_pcd.lock); #endif req->sysreq.complete(&_ifxep->sysep, &req->sysreq); #ifdef __DO_PCD_UNLOCK__ SPIN_LOCK(&ifxusb_pcd.lock); #endif } else { #ifdef __req_num_dbg__ IFX_ERROR("%s() no complete EP%d Req%d\n",__func__,_ifxep->num, req->reqid); #else IFX_ERROR("%s() no complete EP%d Req %p\n",__func__,_ifxep->num, req); #endif } } if(list_empty(&_ifxep->queue) // Rx Empty, Reuse { _ifxreq->sysreq.actual=0; _ifxreq->sysreq.status=0; list_add_tail(&_ifxreq->trq, &_ifxep->queue); } else { if(_ifxreq->sysreq.complete) { #ifdef __DO_PCD_UNLOCK__ SPIN_UNLOCK(&ifxusb_pcd.lock); #endif _ifxreq->sysreq.complete(&_ifxep->sysep, &_ifxreq->sysreq); #ifdef __DO_PCD_UNLOCK__ SPIN_LOCK(&ifxusb_pcd.lock); #endif } else { #ifdef __req_num_dbg__ IFX_ERROR("%s() no complete EP%d Req%d\n",__func__,_ifxep->num, req->reqid); #else IFX_ERROR("%s() no complete EP%d Req %p\n",__func__,_ifxep->num, req); #endif } } }
/*! \brief This function is called to initialize the IFXUSB CSR data structures. The register addresses in the device and host structures are initialized from the base address supplied by the caller. The calling function must make the OS calls to get the base address of the IFXUSB controller registers. \param _core_if Pointer of core_if structure \param _irq irq number \param _reg_base_addr Base address of IFXUSB core registers \param _fifo_base_addr Fifo base address \param _fifo_dbg_addr Fifo debug address \return 0: success; */ int ifxusb_core_if_init(ifxusb_core_if_t *_core_if, int _irq, uint32_t _reg_base_addr, uint32_t _fifo_base_addr, uint32_t _fifo_dbg_addr) { int retval = 0; uint32_t *reg_base =NULL; uint32_t *fifo_base =NULL; uint32_t *fifo_dbg =NULL; int i; IFX_DEBUGPL(DBG_CILV, "%s(%p,%d,0x%08X,0x%08X,0x%08X)\n", __func__, _core_if, _irq, _reg_base_addr, _fifo_base_addr, _fifo_dbg_addr); if( _core_if == NULL) { IFX_ERROR("%s() invalid _core_if\n", __func__); retval = -ENOMEM; goto fail; } //memset(_core_if, 0, sizeof(ifxusb_core_if_t)); _core_if->irq=_irq; reg_base =ioremap_nocache(_reg_base_addr , IFXUSB_IOMEM_SIZE ); fifo_base =ioremap_nocache(_fifo_base_addr, IFXUSB_FIFOMEM_SIZE); fifo_dbg =ioremap_nocache(_fifo_dbg_addr , IFXUSB_FIFODBG_SIZE); if( reg_base == NULL || fifo_base == NULL || fifo_dbg == NULL) { IFX_ERROR("%s() usb ioremap() failed\n", __func__); retval = -ENOMEM; goto fail; } _core_if->core_global_regs = (ifxusb_core_global_regs_t *)reg_base; /* * Attempt to ensure this device is really a IFXUSB Controller. * Read and verify the SNPSID register contents. The value should be * 0x45F42XXX */ { int32_t snpsid; snpsid = ifxusb_rreg(&_core_if->core_global_regs->gsnpsid); if ((snpsid & 0xFFFFF000) != 0x4F542000) { IFX_ERROR("%s() snpsid error(0x%08x) failed\n", __func__,snpsid); retval = -EINVAL; goto fail; } _core_if->snpsid=snpsid; } #ifdef __IS_HOST__ _core_if->host_global_regs = (ifxusb_host_global_regs_t *) ((uint32_t)reg_base + IFXUSB_HOST_GLOBAL_REG_OFFSET); _core_if->hprt0 = (uint32_t*)((uint32_t)reg_base + IFXUSB_HOST_PORT_REGS_OFFSET); for (i=0; i<MAX_EPS_CHANNELS; i++) { _core_if->hc_regs[i] = (ifxusb_hc_regs_t *) ((uint32_t)reg_base + IFXUSB_HOST_CHAN_REGS_OFFSET + (i * IFXUSB_CHAN_REGS_OFFSET)); IFX_DEBUGPL(DBG_CILV, "hc_reg[%d]->hcchar=%p\n", i, &_core_if->hc_regs[i]->hcchar); } #endif //__IS_HOST__ #ifdef __IS_DEVICE__ _core_if->dev_global_regs = (ifxusb_device_global_regs_t *)((uint32_t)reg_base + IFXUSB_DEV_GLOBAL_REG_OFFSET); for (i=0; i<MAX_EPS_CHANNELS; i++) { _core_if->in_ep_regs[i] = (ifxusb_dev_in_ep_regs_t *) ((uint32_t)reg_base + IFXUSB_DEV_IN_EP_REG_OFFSET + (i * IFXUSB_EP_REG_OFFSET)); _core_if->out_ep_regs[i] = (ifxusb_dev_out_ep_regs_t *) ((uint32_t)reg_base + IFXUSB_DEV_OUT_EP_REG_OFFSET + (i * IFXUSB_EP_REG_OFFSET)); IFX_DEBUGPL(DBG_CILV, "in_ep_regs[%d]->diepctl=%p/%p %p/0x%08X/0x%08X\n", i, &_core_if->in_ep_regs[i]->diepctl, _core_if->in_ep_regs[i], reg_base,IFXUSB_DEV_IN_EP_REG_OFFSET,(i * IFXUSB_EP_REG_OFFSET) ); IFX_DEBUGPL(DBG_CILV, "out_ep_regs[%d]->doepctl=%p/%p %p/0x%08X/0x%08X\n", i, &_core_if->out_ep_regs[i]->doepctl, _core_if->out_ep_regs[i], reg_base,IFXUSB_DEV_OUT_EP_REG_OFFSET,(i * IFXUSB_EP_REG_OFFSET) ); } #endif //__IS_DEVICE__ /* Setting the FIFO and other Address. */ for (i=0; i<MAX_EPS_CHANNELS; i++) { _core_if->data_fifo[i] = fifo_base + (i * IFXUSB_DATA_FIFO_SIZE); IFX_DEBUGPL(DBG_CILV, "data_fifo[%d]=0x%08x\n", i, (unsigned)_core_if->data_fifo[i]); } _core_if->data_fifo_dbg = fifo_dbg; _core_if->pcgcctl = (uint32_t*)(((uint32_t)reg_base) + IFXUSB_PCGCCTL_OFFSET); /* * Store the contents of the hardware configuration registers here for * easy access later. */ _core_if->hwcfg1.d32 = ifxusb_rreg(&_core_if->core_global_regs->ghwcfg1); _core_if->hwcfg2.d32 = ifxusb_rreg(&_core_if->core_global_regs->ghwcfg2); _core_if->hwcfg3.d32 = ifxusb_rreg(&_core_if->core_global_regs->ghwcfg3); _core_if->hwcfg4.d32 = ifxusb_rreg(&_core_if->core_global_regs->ghwcfg4); IFX_DEBUGPL(DBG_CILV,"hwcfg1=%08x\n",_core_if->hwcfg1.d32); IFX_DEBUGPL(DBG_CILV,"hwcfg2=%08x\n",_core_if->hwcfg2.d32); IFX_DEBUGPL(DBG_CILV,"hwcfg3=%08x\n",_core_if->hwcfg3.d32); IFX_DEBUGPL(DBG_CILV,"hwcfg4=%08x\n",_core_if->hwcfg4.d32); #ifdef __DED_FIFO__ IFX_PRINT("Waiting for PHY Clock Lock!\n"); while(!( ifxusb_rreg(&_core_if->core_global_regs->grxfsiz) & (1<<9))) { } IFX_PRINT("PHY Clock Locked!\n"); //ifxusb_clean_spram(_core_if,128*1024/4); #endif /* Create new workqueue and init works */ #if 0 _core_if->wq_usb = create_singlethread_workqueue(_core_if->core_name); if(_core_if->wq_usb == 0) { IFX_DEBUGPL(DBG_CIL, "Creation of wq_usb failed\n"); retval = -EINVAL; goto fail; } #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) INIT_WORK(&core_if->w_conn_id, w_conn_id_status_change, core_if); INIT_WORK(&core_if->w_wkp, w_wakeup_detected, core_if); #else INIT_WORK(&core_if->w_conn_id, w_conn_id_status_change); INIT_DELAYED_WORK(&core_if->w_wkp, w_wakeup_detected); #endif #endif return 0; fail: if( reg_base != NULL) iounmap(reg_base ); if( fifo_base != NULL) iounmap(fifo_base); if( fifo_dbg != NULL) iounmap(fifo_dbg ); return retval; }