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

📄 hostctrl.c

📁 Usb Host/Periphel Control TD1120 codes
💻 C
📖 第 1 页 / 共 5 页
字号:
            }
         else
            {
            if (val & OHCI_HC_RH_DESCRIPTOR_A_NPS)
               {
               val &= ~OHCI_HC_RH_DESCRIPTOR_A_NPS;
               val |= OHCI_HC_RH_DESCRIPTOR_A_PSM;
               }
            }
         break;
      case OHCI_HC_RH_DESCRIPTOR_B:
         val = OTG242HC_ReadReg(hc, OTG242HC_RH_DESCRIPTOR_B);
         break;
      case OHCI_HC_RH_STATUS:
         val = OTG242HC_ReadReg(hc, OTG242HC_RH_STATUS);
         break;
      case OHCI_HC_RH_PORT_STATUS(1):
         val = OTG242HC_ReadReg(hc, OTG242HC_RH_PORT_STATUS(1));
#if OTG242HC_PORTCHANGE_FIX
         val |= OTG242HC_PortCSC[0] & OTG242HC_RH_PORT_STATUS_CSC; 
#endif         
         break;
      case OHCI_HC_RH_PORT_STATUS(2):
         val = OTG242HC_ReadReg(hc, OTG242HC_RH_PORT_STATUS(2));
#if OTG242HC_PORTCHANGE_FIX
         val |= OTG242HC_PortCSC[1] & OTG242HC_RH_PORT_STATUS_CSC; 
#endif         
         break;
      case OHCI_HC_RH_PORT_STATUS(3):
         val = 0;
         break;

     case 0x60:
        val = OTG242HC_ReadReg(hc, OTG242_CLOCK_CONTROL);
        break;
     case 0x64:
        val = OTG242HC_ReadReg(hc, OTG242_RESET_CONTROL);
        break;

      default:
         OS_DEBUG_MSG2(OS_ZONE_ERR, "Unknown OHCI register 0x%0x\r\n", index);
         break;
      }
   return val;
   }

void Ohci_PM_WriteRegister(unsigned long* reg, U32 val)
   {
   U32 index;
   Otg242Hc *hc;
   U32 tmp;

   tmp = (U32)reg;
   index = tmp & 0x7F;
   tmp = (tmp & ~0x7F) + OTG242HC_HC_BASE;
   hc = (Otg242Hc*)(*((U32*)tmp));


   switch (index)
      {
      case OHCI_HC_REVISION:
         break;
      case OHCI_HC_CTRL:
         *reg = val;
         OTG242HC_WriteReg
            (
            hc,
            OTG242HC_CTRL,
            OTG242HC_CTRL_HCFS_FROM_OHCI(val) | OTG242HC_CTRL_RWE_FROM_OHCI(val)
            );

         if ((val & OHCI_HC_CTRL_HCFS) == OHCI_HC_CTRL_HCFS_OPERATIONAL)
            {
            OTG242HC_Operational(hc);
            }
         break;
      case OHCI_HC_CMD_STATUS:
         OTG242HC_CommandStatusWrite(hc, (U32*)reg, val);
         break;
      case OHCI_HC_INTR_STATUS:
         *reg &= ~val;
         break;
      case OHCI_HC_INTR_ENABLE:
         *reg |= val;
         hc->intrEnable |= val & ~(OHCI_HC_INTR_STATUS_OC | OHCI_HC_INTR_STATUS_MIE);
         OTG242HC_WriteReg( hc, OTG242HC_INTR_ENABLE, hc->intrEnable);
         break;
      case OHCI_HC_INTR_DISABLE:
         hc->ohciReg[OHCI_HC_INTR_ENABLE / sizeof(U32)] &= ~val;
         hc->intrEnable &= ~val;
       /* SOF and Port Status Change interrupts should remain on */
         hc->intrEnable |= OTG242HC_INTR_START_OF_FRAME |
            OTG242HC_INTR_ROOT_HUB_STATUS_CHANGE;
         OTG242HC_WriteReg( hc, OTG242HC_INTR_ENABLE, hc->intrEnable);
         break;
      case OHCI_HC_HCCA:
#if HC_MASS_STORAGE_NEW
         hc->hcca = (U32 *)OS_PhysicalToVirtual((void*)val);
#else
         hc->hcca = (U32 *)OS_PhysicalToVirtual(val);
#endif
         *reg = val;
         break;
      case OHCI_HC_PERIOD_CURRENT_ED:
         break;
      case OHCI_HC_CTRL_HEAD_ED:
         *reg = val;
         break;
      case OHCI_HC_CTRL_CURRENT_ED:
         if (!(hc->ohciReg[OHCI_HC_CTRL / sizeof(U32)] & OHCI_HC_CTRL_CLE))
            {
            *reg = val;
            }
         break;
      case OHCI_HC_BULK_HEAD_ED:
         *reg = val;
         break;
      case OHCI_HC_BULK_CURRENT_ED:
         if (!(hc->ohciReg[OHCI_HC_CTRL / sizeof(U32)] & OHCI_HC_CTRL_BLE))
            {
            *reg = val;
            }
         break;
      case OHCI_HC_DONE_HEAD:
         break;
      case OHCI_HC_FM_INTERVAL:
         OTG242HC_WriteReg(hc, OTG242_FRAMEINTERVAL, val);
         break;
      case OHCI_HC_FM_REMAINING:
         break;
      case OHCI_HC_FM_NUMBER:
         break;
      case OHCI_HC_PERIODIC_START:
         *reg = val;
         break;
      case OHCI_HC_LS_THRESHOLD:
         OTG242HC_WriteReg(hc, OTG242HC_LS_THRESHOLD, val);
         break;
      case OHCI_HC_RH_DESCRIPTOR_A:
         if (val & OHCI_HC_RH_DESCRIPTOR_A_PSM)
            {
            if (0 == (val & OHCI_HC_RH_DESCRIPTOR_A_NPS))
               {
               val &= ~OHCI_HC_RH_DESCRIPTOR_A_PSM;
               val |= OHCI_HC_RH_DESCRIPTOR_A_NPS;
               }
            }
         else
            {
            if (val & OHCI_HC_RH_DESCRIPTOR_A_NPS)
               {
               val &= ~OHCI_HC_RH_DESCRIPTOR_A_NPS;
               val |= OHCI_HC_RH_DESCRIPTOR_A_PSM;
               }
            }

         *reg = val;
         OTG242HC_WriteReg(hc, OTG242HC_RH_DESCRIPTOR_A, val);
         break;
      case OHCI_HC_RH_DESCRIPTOR_B:
         *reg = val;
         OTG242HC_WriteReg(hc, OTG242HC_RH_DESCRIPTOR_B, val);
         break;
      case OHCI_HC_RH_STATUS:
         OTG242HC_RhStatusWrite(hc, val);
         break;
      case OHCI_HC_RH_PORT_STATUS(1):
#if OTG242HC_PORTCHANGE_FIX
         val &= ~OTG242HC_RH_PORT_STATUS_CSC; 
         OTG242HC_PortCSC[0] &= ~OTG242HC_RH_PORT_STATUS_CSC; 
#endif         
         OTG242HC_WriteReg(hc, OTG242HC_RH_PORT_STATUS(1), val);
         break;
      case OHCI_HC_RH_PORT_STATUS(2):
#if OTG242HC_PORTCHANGE_FIX
         val &= ~OTG242HC_RH_PORT_STATUS_CSC; 
         OTG242HC_PortCSC[1] &= ~OTG242HC_RH_PORT_STATUS_CSC; 
#endif         
         OTG242HC_WriteReg(hc, OTG242HC_RH_PORT_STATUS(2), val);
         break;
      case OHCI_HC_RH_PORT_STATUS(3):
         break;

      case 0x60:
         {
         /* Write the higher 16 bits first. */
         U16* address = (U16*)((U8*)hc->regBase + OTG242_CLOCK_CONTROL);
         
         U16 lowPart = (U16)(val & 0xFFFF);
         U16 highPart = (U16)((val >> 16) & 0xFFFF);
         
         HW_WriteOtg242Register16((U16*)hc->regBase, (U32)(((U16*)OTG242_CLOCK_CONTROL) + 1), highPart);
         HW_WriteOtg242Register16((U16*)hc->regBase, (U32)OTG242_CLOCK_CONTROL, lowPart);
         }
         break;

      case 0x64:
         OTG242HC_WriteReg(hc, OTG242_RESET_CONTROL, val);
         break;
      
      default:
         OS_DEBUG_MSG3(OS_ZONE_ERR, "Write to Unknown OHCI register 0x%0x with 0x%0x\r\n", index, val);
         break;
      }
   }


void OTG242HC_RhStatusWrite(Otg242Hc *hc, U32 val)
   {
   U32 desc;
   U32 i;
   U32 status;

   OTG242HC_WriteReg(hc, OTG242HC_RH_STATUS, val);
   if (val & (OHCI_HC_RH_STATUS_LPS | OHCI_HC_RH_STATUS_LPSC))
      {
      if (val & OHCI_HC_RH_STATUS_LPS)
         {
         /*  Clear port power, and disable port */
         status = OTG242HC_RH_PORT_STATUS_CCS | OTG242HC_RH_PORT_STATUS_LSDA;
         }
      else
         {
         /*  Set port power and enable port */
         status = OTG242HC_RH_PORT_STATUS_PES | OTG242HC_RH_PORT_STATUS_PPS;
         }

      desc = hc->ohciReg[OHCI_HC_RH_DESCRIPTOR_A / sizeof(U32)];
      if (desc & OHCI_HC_RH_DESCRIPTOR_A_PSM)
         {
         U32 pos;

         pos = OHCI_HC_RH_DESCRIPTOR_B_PPCM0;
         /* Check each port to determine if that port should be set/clear */
         desc = hc->ohciReg[OHCI_HC_RH_DESCRIPTOR_B / sizeof(U32)];
         for (i = 1; i <= OTG242HC_RH_PORT_MAX; i++, pos <<= 1)
            {
            if (!(desc & pos))
               {
               OTG242HC_WriteReg(hc, OTG242HC_RH_PORT_STATUS(i), status);     
               }
            }
         }
      else
         {
         for (i = 1; i <= OTG242HC_RH_PORT_MAX; i++)
            {
            OTG242HC_WriteReg(hc, OTG242HC_RH_PORT_STATUS(i), status);     
            }
         }
      }
   }

void OTG242HC_CommandStatusWrite(Otg242Hc *hc, U32 *reg, U32 val)
   {
   U32 Read;
   if (val & OHCI_HC_CMD_STATUS_HCR)
      {
      Read = OTG242HC_ReadReg(hc, OTG242HC_CTRL);
      OTG242HC_WriteReg(hc, OTG242HC_CTRL, Read | OTG242HC_CMD_STATUS_HCR);
      }

   *reg |= val & ~OHCI_HC_CMD_STATUS_SOC;

   if (val & OHCI_HC_CMD_STATUS_OCR)
      {
      hc->ohciReg[OHCI_HC_INTR_STATUS / sizeof(U32)] |= OHCI_HC_INTR_STATUS_OC;
      }
   }

#if HC_MASS_STORAGE_NEW
void OTG242HC_CancelEtd(Otg242Hc *hc)
   {
   OhciEd*     ed;
   Otg242EtdBank* etd;
   U32 slot;
   U32 ped;

   for (slot = 0, etd = hc->etdBank; slot < OTG242ETD_MAX; slot++, etd++)
      {
      if (NULL == etd->ed)
         {
         continue;
         }
      
      switch (etd->type)
         {
         case EpTypeIntr:
            for (slot = 0; slot < 0x20; slot++)
               {
               ped = *(hc->hcca + slot);
               if (0 == ped)
                  {
                  continue;
                  }

               for
                  (
                  ed = (OhciEd*)OS_PhysicalToVirtual((void*)ped);
                  ed;
                  ped = ed->nextEd,
                     ed = (OHCIED_IsEof(ped)) ? 0 :
                     (OhciEd*)OS_PhysicalToVirtual((void*)(ped & OHCIED_POINTER))
                  )
                  {
                  if (etd->ed == ed)
                     {
                     break;
                     }
                  }

               if (NULL != ed)
                  {
                  break;
                  }
               }
         break;

         case EpTypeIsoc:
            ped = *(hc->hcca + slot);
            if (0 == ped)
               {
               continue;
               }

            for
               (
               ed = (OhciEd*)OS_PhysicalToVirtual((void*)ped);
               ed;
               ped = ed->nextEd,
                  ed = (OHCIED_IsEof(ped)) ? 0 :
                  (OhciEd*)OS_PhysicalToVirtual((void*)(ped & OHCIED_POINTER))
               )
               {
               if (etd->ed == ed)
                  {
                  break;
                  }
               }
         break;

         case EpTypeCtrl:
            ped = OTG242HC_GetHcControlHeadEd(hc);
            for
               (
               ed = (OhciEd*)OS_PhysicalToVirtual((void*)ped);
               ed;
               ped = ed->nextEd,
                  ed = (OHCIED_IsEof(ped)) ? 0 :
                  (OhciEd*)OS_PhysicalToVirtual((void*)(ped & OHCIED_POINTER))
               )
               {
               if (etd->ed == ed)
                  {
                  break;
                  }
               }
         break;

         case EpTypeBulk:
            ped = OTG242HC_GetHcBulkHeadEd(hc);
            for
               (
               ed = (OhciEd*)OS_PhysicalToVirtual((void*)ped);
               ed;
               ped = ed->nextEd,
                  ed = (OHCIED_IsEof(ped)) ? 0 :
                  (OhciEd*)OS_PhysicalToVirtual((void*)(ped & OHCIED_POINTER))
               )
               {
               if (etd->ed == ed)
                  {
                  break;
                  }
               }
         break;

         default:
            continue;
         }

      if (NULL == ed || (ed->desc & OHCIED_SKIP || ed->headP & OHCIED_HALTED))
         {
         OS_DEBUG_MSG3(OS_ZONE_INTR, "OTG243HC_CancelEtd index=%d ed=%x cancelled\r\n", slot, etd->ed);
         if( OTG242ETD_ReadReg(etd, OTG242HC_ETD_ENABLE) & (1 << slot) ) 
            {
            OTG242ETD_WriteReg( etd, OTG242HC_ETD_ENABLE, (1 << slot));
            }
         OTG242ETD_Free(etd);
         }
      }
   }

#endif

U32 OTG242HC_IntrHandler(Otg242Hc *hc)
   {
   S32 index;
   U32 status;
   U32 val;
   U32 ohciIntStatus;
   U32 doneQueue;
   U32 doneHead;
   U32 oldOhciStatus;

   U32 etdIntrStatusX, etdIntrStatusY;
   U32 pos;
   Otg242EtdBank* etd;
   OhciTd* td;
   U32 Read;


   status = OTG242HC_ReadReg(hc, OTG242HC_INTR_STATUS);

   OTG242HC_WriteReg(hc, OTG242HC_INTR_STATUS, 
      status & ~OTG242HC_INTR_WRITE_DONE_HEAD);

   status &= hc->intrEnable ;

   etdIntrStatusX = OTG242HC_ReadReg(hc, OTG242HC_XBUFFERINTERRUPTSTATUS);
   etdIntrStatusY = OTG242HC_ReadReg(hc, OTG242HC_YBUFFERINTERRUPTSTATUS);
   
   
   etdIntrStatusX &= hc->etdIntrEnable;
   etdIntrStatusY &= hc->etdIntrEnable;

   
   if (etdIntrStatusX || etdIntrStatusY)
      {
      if( etdIntrStatusX )
         {
         OTG242HC_WriteReg(hc, OTG242HC_XBUFFERINTERRUPTSTATUS, etdIntrStatusX);
         }
      if( etdIntrStatusY )
         {
         OTG242HC_WriteReg(hc, OTG242HC_YBUFFERINTERRUPTSTATUS, etdIntrStatusY);
         }
         
      pos = 0x1;
      index = 0;
      while (etdIntrStatusX)
         {
         if (etdIntrStatusX & pos)
            {
            OTG242ETD_NextPacket(&hc->etdBank[index]);
            etdIntrStatusX &= ~pos;
            }

         pos <<= 1;
         index++;
         }

      pos = 0x1;
      index = 0;
      while (etdIntrStatusY)
         {

⌨️ 快捷键说明

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