⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ftc_fotg2xx.c

📁 WiFi IP-Cam solution. FIC8120 platform VIA VT6656 USB Module driver source code.
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Copyright (c) 2005 by Faraday * * 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. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation, */#include <linux/config.h>#include <linux/kernel.h>#include <linux/module.h>#include <linux/pci.h>#include <linux/delay.h>#include <linux/ioport.h>#include <linux/sched.h>#include <linux/slab.h>#include <linux/smp_lock.h>#include <linux/errno.h>#include <linux/init.h>#include <linux/timer.h>#include <linux/list.h>#include <linux/interrupt.h>#include <linux/proc_fs.h>#include <linux/devfs_fs_kernel.h>//--For USB include#include <linux/usb_ch9.h>#include <linux/usb_gadget.h>#include <linux/usb_otg.h>//--For asm include#include <asm/byteorder.h>#include <asm/io.h>#include <asm/irq.h>#include <asm/pci.h>#include <asm/system.h>#include <asm/unaligned.h>#include <asm/arch/cpe_int.h>//--For OTG include#include "FTC_FOTG2XX.h"#include "../gadget/FTC_FOTG200_udc.h"//--For usb include change between Linux2.4.18-USB and Linux2.6.10-USB#define FOTG2XX_AVOID_REDEFINE  // will used in following usb.h#include <linux/usb.h>//#define FOTG2XX_HOST_ONLY   1 //john20060214 for HOST only usage#define OTG_MAJOR     42    //major device for OTG//--Driver & Module Info#define	DRIVER_DESC		"FOTG2XX USB Controller"#define	DRIVER_VERSION	"14-February 2006"static const char driver_name [] = "FTC_FOTG2XX";static const char driver_desc [] = DRIVER_DESC;MODULE_AUTHOR("bruce-john@faraday-tech.com");MODULE_DESCRIPTION(DRIVER_DESC);MODULE_LICENSE("GPL");//#define  EINDBG(p,args...)  do{if(msglevel>0)printk(p,##args);}while(0)//static int msglevel=1;static struct file_operations otg_fops = {	owner:		THIS_MODULE,	ioctl:		OTGC_AP_ioctl,};//--Global Variable Definitionstatic struct FTC_OTGC_STS    *pFTC_OTG=0;static struct otg_transceiver *xceiv;//-----------------------------------------------------------------------------//-----------------------------------------------------------------------------//---------------------- Group-1:Basic Function -------------------------------//-----------------------------------------------------------------------------//-----------------------------------------------------------------------------static const char *OTGC_state_string(enum usb_otg_state state){	switch (state) {	case OTG_STATE_A_IDLE:		 return "a_idle";	case OTG_STATE_A_WAIT_VRISE: return "a_wait_vrise";	case OTG_STATE_A_WAIT_BCON:	 return "a_wait_bcon";	case OTG_STATE_A_HOST:		 return "a_host";	case OTG_STATE_A_SUSPEND:	 return "a_suspend";	case OTG_STATE_A_PERIPHERAL: return "a_peripheral";	case OTG_STATE_A_WAIT_VFALL: return "a_wait_vfall";	case OTG_STATE_A_VBUS_ERR:	 return "a_vbus_err";	case OTG_STATE_B_IDLE:		 return "b_idle";	case OTG_STATE_B_SRP_INIT:	 return "b_srp_init";	case OTG_STATE_B_PERIPHERAL: return "b_peripheral";	case OTG_STATE_B_WAIT_ACON:	 return "b_wait_acon";	case OTG_STATE_B_HOST:		 return "b_host";	default:			         return "UNDEFINED";	}}//*********************************************************// Name: OTGH_host_quick_Reset// Description://For HNP critical timing//           OTG need the quickly-bus-reset// Input:void// Output:0:OK//*********************************************************static int OTGH_host_quick_Reset(void){   //<1>.Issue Bus reset sequence   mwHost20_PORTSC_PortReset_Set();   //<2>.Delay 55 ms   mdelay(55);   //<3>.terminate Bus reset sequence   mwHost20_PORTSC_PortReset_Clr();   ////John0215 : this is useless code, because bit 0 always 0   ////<4>.Waiting for Reset complete   //while(mwHost20_PORTSC_PortReset_Rd()==1);   //<5>.Issue SOF   mbHost20_USBCMD_RunStop_Set();   DBG_OTG_TRACEC("-OTGH_host_quick_Reset()(0x30=0x%x)\n",mdwFOTGPort(0x30));   return (0);}//*********************************************************// Name: OTGP_Close// Description://         Disable Interrupt for Peripheral// Input:void// Output:void//*********************************************************void OTGP_Close(void){   u32 wTemp;   DBG_OTG_FUNCC("+OTGP_Close()\n");   //<1>.Clear All the Interrupt   mUsbGlobIntDis();  //disable device interrupt   mdwOTGC_GINT_MASK_PERIPHERAL_Set();  // mask device interrupt   //john0215: offset 0x140 is read only   ////<2>.Clear all the Interrupt Status   //wTemp=mUsbIntGroupRegRd();   //mUsbIntGroupRegSet(0);   //Interrupt source group 0(0x144)   wTemp=mUsbIntSrc0Rd();   mUsbIntSrc0Set(0);   //john0215: offset 0x148 is read only   ////Interrupt source group 1(0x148)   //wTemp=mUsbIntSrc1Rd();   //mUsbIntSrc1Set(0);   //Interrupt source group 2(0x14C)   wTemp=mUsbIntSrc2Rd();   mUsbIntSrc2Set(0);   //<3>.Turn off D+   if (mdwOTGC_Control_CROLE_Rd()>0) //For Current Role = Peripheral      mUsbUnPLGSet();  //emulate detached#ifdef CONFIG_USB_GADGET_FOTG2XX   //<4>.Clear the variable   //john0216 if pFTC_OTG->otg.gadget==NULL, and code runto here   //         only happen when OTG syill not boot OK, and device has plugged   //         in such condition, FTC_usb_probe() will clear these variable   if (pFTC_OTG->otg.gadget) {      pFTC_OTG->otg.gadget->b_hnp_enable = 0;      pFTC_OTG->otg.gadget->a_hnp_support = 0;      pFTC_OTG->otg.gadget->a_alt_hnp_support = 0;   }#else   printk("OTG2XX act as HOST only (remove gadget function)\n");#endif}//*********************************************************// Name: OTGH_Close// Description://         Disable Interrupt for Host// Input:void// Output:void//*********************************************************void OTGH_Close(void){   u32 wTemp;   DBG_OTG_FUNCC("+OTGH_Close()(0x30=0x%x)\n",mdwFOTGPort(0x30));   //<1>.Enable Interrupt Mask   mdwOTGC_GINT_MASK_HOST_Set();   //mask host interrupt   //<2>.Clear the Interrupt status   wTemp=mdwHost20_USBINTR_Rd();   wTemp=wTemp&0x0000003F;   mdwHost20_USBSTS_Set(wTemp);}//*********************************************************// Name: OTGP_Open// Description://          open Peripheral Interrupt// Input:void// Output:void//*********************************************************void OTGP_Open(void){   DBG_OTG_FUNCC("+OTGP_Open()\n");   //<1>.Turn On the Interrupt for Peripheral   if (pFTC_OTG->otg.gadget)  //john0217 don't enable interrupt if gadget still not finish initialization      mUsbGlobIntEnSet();  //enable device interrupt   mdwOTGC_GINT_MASK_PERIPHERAL_Clr();  //unmask device interrupt   mUsbUnPLGClr();  //clear detach setting}//*********************************************************// Name: OTGH_Open// Description://          open Host Interrupt// Input:void// Output:void//*********************************************************void OTGH_Open(void){   DBG_OTG_FUNCC("+OTGH_Open()(0x30=0x%x)\n",mdwFOTGPort(0x30));   //<1>.Turn On the Interrupt   mdwOTGC_Control_A_SRP_DET_EN_Clr();   mdwOTGC_GINT_MASK_HOST_Clr();}#define OPEN_PHY_RESET#ifdef OPEN_PHY_RESET//*********************************************************// Name: OTGC_A_PHY_Reset// Description://          Phy Reset// Input:void// Output:void//*********************************************************void OTGC_A_PHY_Reset(void){   //DBG_OTG_FUNCC("+OTGC_A_PHY_Reset()\n");   printk("+OTGC_A_PHY_Reset()\n");   do {  //wait until B-device VBUS voltage dropped      mdelay(10);   }while(mdwOTGC_Control_B_SESS_END_Rd()==0);   mdwOTG20_Control_Phy_Reset_Set();   mdelay(5);   mdwOTG20_Control_Phy_Reset_Clr();   printk("OTG Controller Reset...()\n");   mdwOTG20_Control_OTG_Reset_Set();   mdelay(5);   mdwOTG20_Control_OTG_Reset_Clr();}#endif//*********************************************************// Name: OTGC_Waiting_VBUS_On// Description://           Waiting for A-device VBUS On// Input:bmsec => wait bmsec time// Output: 0 => ok//*********************************************************int OTGC_Waiting_VBUS_On(u32 bmsec){   u8 bExitFlag=0;   u32 wTimer_ms=0;   DBG_OTG_FUNCC("+OTGC_Waiting_VBUS_On()\n");   do {      if (mdwOTGC_Control_A_VBUS_VLD_Rd()>0)         bExitFlag=1;      mdelay(1);//delay 1ms      wTimer_ms++;      if (wTimer_ms>bmsec) {    	 bExitFlag=2;    	 ERROR(pFTC_OTG,"??? Time out for waiting for VBUS On...\n");    	 return(1);//Time out	  }   } while(bExitFlag==0);   return(0);}//*********************************************************// Name: OTGC_Waiting_VBUS_Off// Description://           Waiting for A-device VBUS OFF// Input:bmsec => wait bmsec time// Output: 0 => ok//*********************************************************int OTGC_Waiting_VBUS_Off(u32 bmsec){   u8 bExitFlag=0;   u32 wTimer_ms=0;   DBG_OTG_FUNCC("+OTGC_Waiting_VBUS_Off()\n");   do {      if (mdwOTGC_Control_A_VBUS_VLD_Rd()==0)          bExitFlag=1;      mdelay(1);//delay 1ms      wTimer_ms++;      if (wTimer_ms>bmsec) {    	 bExitFlag=2;    	 ERROR(pFTC_OTG,"??? Time out for waiting for VBUS Off...\n");    	 return(1);//Time out	  }   } while(bExitFlag==0);   return(0);}//*********************************************************// Name: OTGC_enable_vbus_draw// Description://            Drive/Drop VBUS// Input:0=>Drop VBUS//       1=>Drive VBUS// Output: 0 => ok//*********************************************************static void OTGC_enable_vbus_draw(u8 btype){   DBG_OTG_FUNCC("+(OTGC_enable_vbus_draw(btype=%d))\n",btype);   if (btype>0) {//Drive VBUS      if (mdwOTGC_Control_A_BUS_REQ_Rd()>0)  //A-device VBUS has turned on          return;  //Exit when Current Role = Host      mdwOTGC_Control_A_BUS_DROP_Clr(); //clear A-device drop VBUS      mdwOTGC_Control_A_BUS_REQ_Set();  //A-device drive VBUS, generate traffic      OTGC_Waiting_VBUS_On(5000);      INFO(pFTC_OTG,">>> Drive VBUS ok...\n");   }   else {//Drop VBUS      if (mdwOTGC_Control_A_BUS_REQ_Rd()==0)  //A-device VBUS has turned off          return;  //Exit when Current Role = Host      mdwOTGC_Control_A_BUS_REQ_Clr();   // A-device drop driving VBUS and bus traffic      mdwOTGC_Control_A_BUS_DROP_Set();  // Set A-device drop VBUS      OTGC_Waiting_VBUS_Off(5000);      INFO(pFTC_OTG,">>> Drop VBUS ok...\n");   }}//-----------------------------------------------------------------------------//-----------------------------------------------------------------------------//---------------------- Group-2:AP Function ----------------------------------//-----------------------------------------------------------------------------//-----------------------------------------------------------------------------//*********************************************************// Name: OTGC_AP_Get_State// Description: AP will get the OTG State from OTG Driver// Input:void// Output:otg.state//*********************************************************static int OTGC_AP_Get_State(void){   DBG_OTG_FUNCC("+OTGC_AP_Get_State() (pFTC_OTG->otg.state=%d)\n",pFTC_OTG->otg.state);   return((int)(pFTC_OTG->otg.state));}//*********************************************************// Name: OTGC_AP_Set_to_Idle// Description: AP will call this function call to set device to idle// Input:void// Output:0:OK//        others:Fail//*********************************************************static u8 OTGC_AP_Set_to_Idle(void){   DBG_OTG_FUNCC("+OTGC_AP_Set_to_Idle()\n");   pFTC_OTG->otg.host->A_Disable_Set_Feature_HNP=1;   if (mdwOTGC_Control_ID_Rd()==0) { //For A Device      if (pFTC_OTG->otg.state==OTG_STATE_A_HOST) {		 if (pFTC_OTG->otg.host->b_hnp_enable) { 	        //For => A-Host & HNP Enable ==>Then Role change to Peripheral Mode 	        INFO(pFTC_OTG,">>> call otg_start_hnp\n"); 	        FOTG2XX_start_hnp(xceiv); 	        return(0); 	     }     	 else {//For Normale A-Host-Idle     	    Host_Disconnect_for_OTG(pFTC_OTG->otg.host,0);     	    mdwOTGC_Control_A_BUS_REQ_Clr();     //A-device stop driving VBUS and traffic     	    mdwOTGC_Control_A_BUS_DROP_Set();    // A-device want to pwer down VBUS     	    mdwOTGC_Control_A_SRP_DET_EN_Set();  // enable SRP detection            while(mdwOTGC_Control_A_VBUS_VLD_Rd()>0);  //wait until VBUS dropped            pFTC_OTG->otg.state=OTG_STATE_A_IDLE;            return(0);         }	  }      if (pFTC_OTG->otg.state==OTG_STATE_A_IDLE) {         INFO(pFTC_OTG,">>> Device-A is already in Idle mode\n");     	 return(0);      }      else {     	 INFO(pFTC_OTG,">>> Set to Idle Fail...(Current State = %s)\n",OTGC_state_string(pFTC_OTG->otg.state));     	 return(-1);	  }   }   else { //For B Device      if (pFTC_OTG->otg.state==OTG_STATE_B_HOST) { //Change to peripheral==>Host disconnect         //printk("TEMP==> B exit the host mode...\n");     	 Host_Disconnect_for_OTG(pFTC_OTG->otg.host,0);         // pFTC_OTG->otg.state=OTG_STATE_B_IDLE;     	 return(0);	  }      if (mdwOTGC_Control_A_VBUS_VLD_Rd()>0) {     	 ERROR(pFTC_OTG,"??? Can not set Device-B to idle state(When VBUS>0 )...\n");     	 return(-1);	  }      if (pFTC_OTG->otg.state==OTG_STATE_B_IDLE) {     	 INFO(pFTC_OTG,">>> Device-B is already in Idle State... \n");     	 return(0);      }      if (pFTC_OTG->otg.state==OTG_STATE_B_PERIPHERAL) {         OTGP_Close();         mdwOTGC_Control_B_BUS_REQ_Clr();  //B-device stop driving VBUS         mdwOTGC_Control_B_HNP_EN_Clr();   //B-device disable HNP         mdwOTGC_Control_B_DSCHG_VBUS_Clr(); //B-device discharge VBUS         pFTC_OTG->otg.state=OTG_STATE_B_IDLE;     	 return(0);	  }      else {     	 INFO(pFTC_OTG,">>>  Set to Idle Fail...(Current State = %s)\n",OTGC_state_string(pFTC_OTG->otg.state));     	 return(-1);      }   }   return(0);}//*********************************************************// Name: OTGC_AP_Set_to_Host// Description: AP will call this function call to set device to Host// Input:void

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -