📄 hcd_1161.c
字号:
sti_hcd();} /* End of fnvIsp1161ItlRead() *//*--------------------------------------------------------------* * 1161 Host Controller Itl Buffer Reading *--------------------------------------------------------------*/void fnvIsp1161ItlWrite(__u8* pbyChar, __u32 uTotalByte){ __u32 uTotalDoubleWord; __u32* puLong; __u32 uIndex; __u32 uData1; __u32 uData2;#ifdef __TRACE_MID_LEVEL__ printk("fnvIsp1161ItlWrite( buff = 0x%p, bytes = %d)\n",pbyChar,uTotalByte);#endif /* __TRACE_MID_LEVEL__ */ outw_hcd(HC_COM, REG_XFER_CNTR | 0x80); outw_hcd(HC_DATA, uTotalByte); /* 2. Pass HCD ITL to ISP1161 internal ITL through the 32-bit ITLBuffer register */ /* Use PIO for the time being. Will use DMA */ uTotalDoubleWord = uTotalByte >> 2; /* Number of double words to move from ISP1161 ATL */ puLong = (__u32*) pbyChar; /* Convert the HCD byte buffer to double-word buffer */ /* Send the command */ outw_hcd(HC_COM,(REG_ITL_BUFF_IO | 0x80)); /* Don't forget to set bit 7 for write*/ cli_hcd(); /* Write data to the data port */ for (uIndex = 0; uIndex < uTotalDoubleWord; uIndex ++) { uData1 = puLong[uIndex] & 0x0000FFFF; /* Take the lower 16-bit of the double word */ uData2 = (puLong[uIndex] & 0xFFFF0000) >> 16; /* Take the higher 16-bit of the double word */ /* Write them to ITL */ outw_hcd(HC_DATA,uData1); /* Write lower 16-bit first */ outw_hcd(HC_DATA,uData2); /* Write higher 16-bit */ } /* for */ sti_hcd();} /* End of fnvIsp1161ItlWrite() */inline void dump_helper_16(char * reg, ULONG address){ ULONG udata; fnvIsp1161HcRead(address, &udata); printk("%s : %x\n",reg,udata);}inline void dump_helper_32(ohci_t * ohci, char * reg, ULONG address){ ULONG udata; fnvIsp1161HcorRead(ohci, address, &udata); printk("%s : %x\n",reg,udata);}void dump_all_registers(ohci_t * ohci){ printk("ISP1161 Registers\n"); dump_helper_32(ohci,"uHcRevision",uHcRevision); dump_helper_32(ohci,"uHcControl",uHcControl); dump_helper_32(ohci,"uHcCommandStatus",uHcCommandStatus); dump_helper_32(ohci,"uHcInterruptStatus",uHcInterruptStatus); dump_helper_32(ohci,"uHcInterruptEnable",uHcInterruptEnable); dump_helper_32(ohci,"uHcInterruptDisable",uHcInterruptDisable); dump_helper_32(ohci,"uHcFmInterval",uHcFmInterval); dump_helper_32(ohci,"uHcFmRemaining",uHcFmRemaining ); dump_helper_32(ohci,"uHcFmNumber",uHcFmNumber ); dump_helper_32(ohci,"uHcLsThreshold",uHcLsThreshold ); dump_helper_32(ohci,"uHcRhDescriptorA",uHcRhDescriptorA ); dump_helper_32(ohci,"uHcRhDescriptorB",uHcRhDescriptorB ); dump_helper_32(ohci,"uHcRhStatus",uHcRhStatus ); dump_helper_32(ohci,"uHcRhPort1Status",uHcRhPort1Status ); dump_helper_32(ohci,"uHcRhPort2Status",uHcRhPort2Status ); dump_helper_16("uHcHardwareConfiguration",REG_HW_MODE ); dump_helper_16("uHcDMAConfiguration",REG_DMA_CNFG ); dump_helper_16("uHcTransferCounter",REG_XFER_CNTR ); dump_helper_16("uHcuPInterrupt",REG_IRQ ); dump_helper_16("uHcuPInterruptEnable",REG_IRQ_MASK ); dump_helper_16("uHcChipID",REG_CHIP_ID ); dump_helper_16("uHcScratch",REG_SCRATCH );// dump_helper_16("uHcSoftwareReset",REG_RESET_DEV ); dump_helper_16("uHcITLBufferLength",REG_ITL_BUFLEN ); dump_helper_16("uHcATLBufferLength",REG_ATL_BUFLEN ); dump_helper_16("uHcBufferStatus",REG_BUFF_STS ); dump_helper_16("uHcReadBackITL0Length",REG_ITL0_LEN ); dump_helper_16("uHcReadBackITL1Length",REG_ITL1_LEN ); dump_helper_16("uHcITLBufferPort",REG_ITL_BUFF_IO ); dump_helper_16("uHcATLBufferPort",REG_ATL_BUFF_IO );} /*--------------------------------------------------------------* * 1161 Initialization functions *--------------------------------------------------------------*//*--------------------------------------------------------------* * 1161 Host Controller Reset *--------------------------------------------------------------*/ULONG fnvIsp1161HostReset(ohci_t *ohci){ULONG uData;ULONG uI;ULONG uRetVal; /* Set the HostController Reset bit in command status register */ fnvIsp1161HcorRead(ohci,uHcCommandStatus,&uData); uData = HC_COMMAND_STATUS_HCR; fnvIsp1161HcorWrite(ohci,uHcCommandStatus, uData); /* wait some time for 1161 to be reset */ for(uI=0;uI<5000;uI++) { fnvIsp1161HcorRead(ohci,uHcCommandStatus,&uData); if((uData & HC_COMMAND_STATUS_HCR) == 0) break; } uRetVal = uData & HC_COMMAND_STATUS_HCR; return uRetVal;} /* End of fnvIsp1161HostReset *//*--------------------------------------------------------------* * 1161 Host Controller detection on ISA bus *--------------------------------------------------------------*/ULONG fnuIsp1161HostDetect(void){ ULONG uDataWrite; ULONG uDataRead; ULONG uChipId; /* Check whether the IO Region is free to use for 1161 Host Controller or not */ if( check_region(HC_IO_BASE, HC_IO_SIZE) < 0 ) { return -EBUSY; } /* Reset the host controller assuming that it will work */ fnvIsp1161HcWrite(REG_RESET_DEV, 0xF6); /* ISP1161 host controller detection */ uDataWrite = 0x55aa; /* Test data */ fnvIsp1161HcWrite(REG_SCRATCH, uDataWrite); /* Write a value to the scratch pad register */ fnvIsp1161HcRead(REG_SCRATCH, &uDataRead); /* Read it back. They should be equal */ if (uDataWrite == uDataRead) { /* Is the host controller there? */ fnvIsp1161HcRead(REG_CHIP_ID, &uChipId); /* Read it back. They should be equal */ printk("ISP116x Chip_id = %x\n",uChipId); return 0; } else return -ENODEV;} /* End of fnuIsp1161Host() *//*--------------------------------------------------------------* * 1161 Host Controller hardware registers initialization *--------------------------------------------------------------*/void fnvHcHardwareConfig(ohci_t *ohci, ULONG uIntLevel){ ULONG uData; UCHAR PicMaskBit[] = {1, 2, 4, 8, 16, 32, 64, 128}; ULONG uIntPort; /* Disable IRQ for ISP1161 */ /* If IRQ is connected to master PIC: IRQ0..IRQ7 */ if (uIntLevel < 8) { uData = (ULONG) inb(PIC1_OCW1); uData |= PicMaskBit[uIntLevel]; outb(PIC1_OCW1, uData); } /* if */ /* if IRQ is connected to slave PIC: IRQ8..IRQ15*/ else { uData = (ULONG) inb(PIC2_OCW1); uData |= PicMaskBit[uIntLevel - 8]; outb(PIC2_OCW1, uData); } /* else */ fnvIsp1161HcRead(REG_HW_MODE, &uData); uData |= (INT_PIN_ENABLE | INT_OUTPUT_POLARITY); /* Global interrupt */ fnvIsp1161HcWrite(REG_HW_MODE, uData); if (uIntLevel < 8) /* IRQ0..IRQ7 */ uIntPort = 0x4d0; else { uIntPort = 0x4d1; uIntLevel -= 8; } uData = (ULONG) inb(uIntPort); uData |= PicMaskBit[uIntLevel]; outb(uIntPort, uData);} /* End of fnvHcHardwareConfig() *//*--------------------------------------------------------------* * 1161 Host Controller hardware Interrupt Initialization *--------------------------------------------------------------*/void fnvHcIntEnable(ohci_t *ohci){ ULONG uData; /* Clear all pending int. source */ uData = 0xFFFFFFFF; fnvIsp1161HcWrite(REG_IRQ, uData); /* Enable int. according settings in host_conf.h */ uData = 0; /* All int. are initially disabled */ /* Should SOF_ITL_INT be enabled? */ uData |= SOF_ITL_INT; /* Should OPR_INT be enabled? */ uData |= OPR_INT; /* Should ATL_INT be enabled? */ if (0) uData |= ATL_INT; /* Should EOT_INT be enabled? */ if (0) uData |= EOT_INT; /* Should HC_SUSPEND_INT be enabled? */ if (0) uData |= HC_SUSPEND_INT; /* Should HC_RESUME_INT be enabled? */ if (0) uData |= HC_RESUME_INT; fnvIsp1161HcWrite(REG_IRQ_MASK, uData);} /* End of fnvHcIntEnable() *//*--------------------------------------------------------------* * 1161 Host Controller Control Register Initialization *--------------------------------------------------------------*/void fnvHcControlInit(ohci_t *ohci){ ULONG uData; ULONG uHostConfigData; uHostConfigData = 0; /* Fill the control register of 1161 */ /* (1) Set the sate to operational */ uData = HC_STATE; uHostConfigData &= (~HC_CONTROL_HCFS); uHostConfigData |= (uData << 6); /* (2) Enable remote wakeup connection if opted */ uData = REMOTE_WAKEUP_CONN; uHostConfigData &= (~HC_CONTROL_RWC); if (uData == YES) uHostConfigData |= HC_CONTROL_RWC; /* (3) Enable remote wakeup if opted */ uData = REMOTE_WAKEUP_ENABLE; uHostConfigData &= (~HC_CONTROL_RWE); if (uData == YES) uHostConfigData |= HC_CONTROL_RWE; fnvIsp1161HcorWrite(ohci,uHcControl, uHostConfigData); /* Configure the HCD transfer control registers uHcHcdControl and uHcHcdCommandStatus */ uHostConfigData = 0; uData = PERIODIC_LIST_ENABLE; /* Periodic list Enable ? */ if (uData == YES) uHostConfigData |= HC_CONTROL_PLE; uData = ISO_ENABLE; /* Isochronous transfer enabled ? */ if (uData == YES) uHostConfigData |= HC_CONTROL_IE; uData = CONTROL_LIST_ENABLE; /* Control trasnfer enabled ? */ if (uData == YES) uHostConfigData |= HC_CONTROL_CLE; uData = BULK_LIST_ENABLE; /* Bulk Transfer Enabled ? */ if (uData == YES) uHostConfigData |= HC_CONTROL_BLE; /* Note: HC_CONTROL_TIP (Transfer In Progress) is alreday set to 0 */ ohci->hc_control = (OHCI_CTRL_CBSR & 0x3) | OHCI_CTRL_PLE | OHCI_USB_OPER ; fnvIsp1161HcorWrite(ohci,uHcHcdControl, uHostConfigData);} /* End of fnvHcControlInit() *//*--------------------------------------------------------------* * 1161 Host Controller Interrupt Register Initialization *--------------------------------------------------------------*/void fnvHcInterruptInit(ohci_t *ohci){ ULONG uHostConfigData; /* First of all, disable all interrupts */ uHostConfigData = HC_INTERRUPT_ALL; fnvIsp1161HcorWrite(ohci,uHcInterruptDisable, uHostConfigData); uHostConfigData = 0; uHostConfigData |= HC_INTERRUPT_MIE; /* Write the configuration to uHcInterruptEnable register */ fnvIsp1161HcorWrite(ohci,uHcInterruptEnable, uHostConfigData);} /* End of fnvHcInterruptInit() *//*--------------------------------------------------------------* * 1161 Host Controller Frame Number interval Initialization *--------------------------------------------------------------*/void fnvHcFmIntervalInit(ohci_t *ohci){ ULONG uHostConfigData; /* Determine the fram interval and the largest data size */ uHostConfigData = FRAME_INTERVAL | (FS_LARGEST_DATA << 16); /* Write the configuration to uHcFmInterval register */ fnvIsp1161HcorWrite(ohci,uHcFmInterval, uHostConfigData);} /* End of fnvHcFmIntervalInit() *//*--------------------------------------------------------------* * 1161 Host Controller Roothub registers Initialization *--------------------------------------------------------------*/void fnvHcRhPower(ohci_t *ohci){ ULONG uData; ULONG uHostConfigData; /* Initialize the configuration data */ uHostConfigData = 0; /* Enable or disable power switching */ uData = PORT_POWER_SWITCHING; if (uData == NO) /* No power switching; ports are always powered on when the HC is powered on */ uHostConfigData |= HC_RH_DESCRIPTORA_NPS; else { /********************************************************/ /* Power switching is enabled */ /* Program root hub in per-port switching mode */ /********************************************************/ uHostConfigData |= HC_RH_DESCRIPTORA_PSM; } /* else */ /* Port over current protection */ uData = OVER_CURRENT_PROTECTION; if (uData == NO) /* No over current protection */ uHostConfigData |= HC_RH_DESCRIPTORA_NOCP; else uData = PER_PORT_OVER_CURRENT_REPORT;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -