status_t OHCI::SetPortFeature(uint8 index, uint16 feature) { TRACE("set port feature index %u feature %u\n", index, feature); if (index > fPortCount) return B_BAD_INDEX; switch (feature) { case PORT_ENABLE: _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PES); return B_OK; case PORT_SUSPEND: _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PSS); return B_OK; case PORT_RESET: _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PRS); return B_OK; case PORT_POWER: _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PPS); return B_OK; } return B_BAD_VALUE; }
void Hiopl::SetFrequency(int ch, float frqHz, bool keyOn) { unsigned int fnum, block; int offset = this->_GetOffset(ch); _milliHertzToFnum((unsigned int)(frqHz * 1000.0), &fnum, &block); _WriteReg(0xa0+offset, fnum % 0x100); uint8 trig = (regCache[0xb0+offset] & 0x20) | (keyOn ? 0x20 : 0x00); _WriteReg(0xb0+offset, trig|((block&0x7)<<2)|(0x3&(fnum/0x100))); }
Hiopl::Hiopl(int buflen) { adlib = new DBOPL::Handler(); Buf32 = new Bit32s[buflen*2]; _op1offset[1] = 0x0; _op1offset[2] = 0x1; _op1offset[3] = 0x2; _op1offset[4] = 0x8; _op1offset[5] = 0x9; _op1offset[6] = 0xa; _op1offset[7] = 0x10; _op1offset[8] = 0x11; _op1offset[9] = 0x12; _op2offset[1] = 0x3; _op2offset[2] = 0x4; _op2offset[3] = 0x5; _op2offset[4] = 0xb; _op2offset[5] = 0xc; _op2offset[6] = 0xd; _op2offset[7] = 0x13; _op2offset[8] = 0x14; _op2offset[9] = 0x15; for (int i = 0; i < 256; i++) { _WriteReg(i, 0); } }
/*FUNCTION**************************************************************** * * Function Name : ModifyReg * Returned Value : MQX error code * Comments : * Modifies value of register. Bits to set to zero are defined by first * mask, bits to be set to one are defined by second mask. * *END*********************************************************************/ _mqx_int I2C_ModifyReg8(unsigned char address, uint_8 reg, uint_8 clr_mask, uint_8 set_mask) { int ret = 0; uint_8 reg_val = 0; /* Init Channel resource bit map */ GET_I2C_SEM; if(i2c_SetAddress(address) != MQX_OK){ printf("set slave address: Error.\n"); ret = -1;// return -1; goto end_modi8; } if (MQX_OK != _ReadReg(reg, ®_val)) { #ifdef I2C_COMMON_DEBUG printf("_ModifyReg: Error - cannot read from SGTL.\n"); #endif ret = -1;// return -1; goto end_modi8; } reg_val &= clr_mask; reg_val |= set_mask; if (MQX_OK != _WriteReg(reg, reg_val)) { #ifdef I2C_COMMON_DEBUG printf("_ModifyReg: Error - cannot write to SGTL.\n"); #endif ret = -2;// return -2; } end_modi8: PUT_I2C_SEM; return ret; }
status_t OHCI::_SubmitTransfer(Transfer *transfer) { Pipe *pipe = transfer->TransferPipe(); bool directionIn = (pipe->Direction() == Pipe::In); ohci_general_td *firstDescriptor = NULL; ohci_general_td *lastDescriptor = NULL; status_t result = _CreateDescriptorChain(&firstDescriptor, &lastDescriptor, directionIn ? OHCI_TD_DIRECTION_PID_IN : OHCI_TD_DIRECTION_PID_OUT, transfer->VectorLength()); if (result < B_OK) return result; // Apply data toggle to the first descriptor (the others will use the carry) firstDescriptor->flags &= ~OHCI_TD_TOGGLE_CARRY; firstDescriptor->flags |= pipe->DataToggle() ? OHCI_TD_TOGGLE_1 : OHCI_TD_TOGGLE_0; // Set the last descriptor to generate an interrupt lastDescriptor->flags &= ~OHCI_TD_INTERRUPT_MASK; lastDescriptor->flags |= OHCI_TD_SET_DELAY_INTERRUPT(OHCI_TD_INTERRUPT_IMMEDIATE); if (!directionIn) { _WriteDescriptorChain(firstDescriptor, transfer->Vector(), transfer->VectorCount()); } // Add to the transfer list ohci_endpoint_descriptor *endpoint = (ohci_endpoint_descriptor *)pipe->ControllerCookie(); MutexLocker endpointLocker(endpoint->lock); result = _AddPendingTransfer(transfer, endpoint, firstDescriptor, firstDescriptor, lastDescriptor, directionIn); if (result < B_OK) { TRACE_ERROR("failed to add pending transfer\n"); _FreeDescriptorChain(firstDescriptor); return result; } // Add the descriptor chain to the endpoint _SwitchEndpointTail(endpoint, firstDescriptor, lastDescriptor); endpointLocker.Unlock(); endpoint->flags &= ~OHCI_ENDPOINT_SKIP; if (pipe->Type() & USB_OBJECT_BULK_PIPE) { // Tell the controller to process the bulk list _WriteReg(OHCI_COMMAND_STATUS, OHCI_BULK_LIST_FILLED); } return B_OK; }
status_t OHCI::ClearPortFeature(uint8 index, uint16 feature) { TRACE("clear port feature index %u feature %u\n", index, feature); if (index > fPortCount) return B_BAD_INDEX; switch (feature) { case PORT_ENABLE: _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_CCS); return B_OK; case PORT_SUSPEND: _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_POCI); return B_OK; case PORT_POWER: _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_LSDA); return B_OK; case C_PORT_CONNECTION: _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_CSC); return B_OK; case C_PORT_ENABLE: _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PESC); return B_OK; case C_PORT_SUSPEND: _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PSSC); return B_OK; case C_PORT_OVER_CURRENT: _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_OCIC); return B_OK; case C_PORT_RESET: _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PRSC); return B_OK; } return B_BAD_VALUE; }
// public functions int FastGpioOmega::SetDirection(int pinNum, int bOutput) { unsigned long int regVal; // read the current input and output settings regVal = _ReadReg(REGISTER_OE_OFFSET); if (verbosityLevel > 0) printf("Direction setting read: 0x%08lx\n", regVal); // set the OE for this pin _SetBit(regVal, pinNum, bOutput); if (verbosityLevel > 0) printf("Direction setting write: 0x%08lx\n", regVal); // write the new register value _WriteReg(REGISTER_OE_OFFSET, regVal); return (EXIT_SUCCESS); }
int I2C_WriteRegister8(unsigned char address ,unsigned char reg, unsigned char reg_val) { // note must add mutex when used audio contrl i2c int ret = 0; GET_I2C_SEM; if(i2c_SetAddress(address) != MQX_OK){ printf("w16 set slave address: Error.\n"); ret = -1; goto end_write8; //return ; } if (MQX_OK != _WriteReg(reg, reg_val)) { //return; ret = -1; printf("WriteRegister 8 failed\n"); } end_write8: PUT_I2C_SEM; return ret; }
int FastGpioOmega::Set(int pinNum, int value) { unsigned long int regAddr; unsigned long int regVal; if (value == 0 ) { // write to the clear register regAddr = REGISTER_CLEAR_OFFSET; } else { // write to the set register regAddr = REGISTER_SET_OFFSET; } // put the desired pin value into the register regVal = (0x1 << pinNum); // write to the register _WriteReg (regAddr, regVal); return EXIT_SUCCESS; }
void Hiopl::SetKsl(int ch, int osc, int level) { int offset = this->_GetOffset(ch, osc); _WriteReg(0x40+offset, (Bit8u)(level<<6), 0xc0); }
void Hiopl::SetAttenuation(int ch, int osc, int level) { int offset = this->_GetOffset(ch, osc); _WriteReg(0x40+offset, (Bit8u)level, 0x3f); }
void Hiopl::SetWaveform(int ch, int osc, Waveform wave) { int offset = this->_GetOffset(ch, osc); _WriteReg(0xe0+offset, (Bit8u)wave, 0x7); }
void Hiopl::EnableWaveformControl() { _WriteReg(0x01, 0x20); }
void Hiopl::_ClearRegBits(Bit32u reg, Bit8u mask) { _WriteReg(reg, regCache[reg] & ~mask); }
status_t OHCI::_SubmitRequest(Transfer *transfer) { usb_request_data *requestData = transfer->RequestData(); bool directionIn = (requestData->RequestType & USB_REQTYPE_DEVICE_IN) != 0; ohci_general_td *setupDescriptor = _CreateGeneralDescriptor(sizeof(usb_request_data)); if (!setupDescriptor) { TRACE_ERROR("failed to allocate setup descriptor\n"); return B_NO_MEMORY; } setupDescriptor->flags = OHCI_TD_DIRECTION_PID_SETUP | OHCI_TD_SET_CONDITION_CODE(OHCI_TD_CONDITION_NOT_ACCESSED) | OHCI_TD_TOGGLE_0 | OHCI_TD_SET_DELAY_INTERRUPT(OHCI_TD_INTERRUPT_NONE); ohci_general_td *statusDescriptor = _CreateGeneralDescriptor(0); if (!statusDescriptor) { TRACE_ERROR("failed to allocate status descriptor\n"); _FreeGeneralDescriptor(setupDescriptor); return B_NO_MEMORY; } statusDescriptor->flags = (directionIn ? OHCI_TD_DIRECTION_PID_OUT : OHCI_TD_DIRECTION_PID_IN) | OHCI_TD_SET_CONDITION_CODE(OHCI_TD_CONDITION_NOT_ACCESSED) | OHCI_TD_TOGGLE_1 | OHCI_TD_SET_DELAY_INTERRUPT(OHCI_TD_INTERRUPT_IMMEDIATE); iovec vector; vector.iov_base = requestData; vector.iov_len = sizeof(usb_request_data); _WriteDescriptorChain(setupDescriptor, &vector, 1); status_t result; ohci_general_td *dataDescriptor = NULL; if (transfer->VectorCount() > 0) { ohci_general_td *lastDescriptor = NULL; result = _CreateDescriptorChain(&dataDescriptor, &lastDescriptor, directionIn ? OHCI_TD_DIRECTION_PID_IN : OHCI_TD_DIRECTION_PID_OUT, transfer->VectorLength()); if (result < B_OK) { _FreeGeneralDescriptor(setupDescriptor); _FreeGeneralDescriptor(statusDescriptor); return result; } if (!directionIn) { _WriteDescriptorChain(dataDescriptor, transfer->Vector(), transfer->VectorCount()); } _LinkDescriptors(setupDescriptor, dataDescriptor); _LinkDescriptors(lastDescriptor, statusDescriptor); } else { _LinkDescriptors(setupDescriptor, statusDescriptor); } // Add to the transfer list ohci_endpoint_descriptor *endpoint = (ohci_endpoint_descriptor *)transfer->TransferPipe()->ControllerCookie(); MutexLocker endpointLocker(endpoint->lock); result = _AddPendingTransfer(transfer, endpoint, setupDescriptor, dataDescriptor, statusDescriptor, directionIn); if (result < B_OK) { TRACE_ERROR("failed to add pending transfer\n"); _FreeDescriptorChain(setupDescriptor); return result; } // Add the descriptor chain to the endpoint _SwitchEndpointTail(endpoint, setupDescriptor, statusDescriptor); endpointLocker.Unlock(); // Tell the controller to process the control list endpoint->flags &= ~OHCI_ENDPOINT_SKIP; _WriteReg(OHCI_COMMAND_STATUS, OHCI_CONTROL_LIST_FILLED); return B_OK; }
void Hiopl::SetEnvelopeAttack(int ch, int osc, int t) { int offset = this->_GetOffset(ch, osc); _WriteReg(0x60+offset, (Bit8u)t<<4, 0xf0); }
void Hiopl::SetModulatorFeedback(int ch, int level) { int offset = this->_GetOffset(ch); _WriteReg(0xc0+offset, (Bit8u)level, 0x0e); }
void Hiopl::EnableAdditiveSynthesis(int ch, bool enable) { int offset = this->_GetOffset(ch); _WriteReg(0xc0+offset, enable ? 0x1 : 0x0, 0x1); }
void Hiopl::TremoloDepth(bool high) { _WriteReg(0xbd, high ? 0x80 : 0x0, 0x80); }
void Hiopl::SetEnvelopeRelease(int ch, int osc, int t) { int offset = this->_GetOffset(ch, osc); _WriteReg(0x80+offset, (Bit8u)t, 0x0f); }
void Hiopl::SetEnvelopeSustain(int ch, int osc, int level) { int offset = this->_GetOffset(ch, osc); _WriteReg(0x80+offset, (Bit8u)level<<4, 0xf0); }
void Hiopl::SetFrequencyMultiple(int ch, int osc, FreqMultiple mult) { int offset = this->_GetOffset(ch, osc); _WriteReg(0x20+offset, (Bit8u)mult, 0xf); }
OHCI::OHCI(pci_info *info, Stack *stack) : BusManager(stack), fPCIInfo(info), fStack(stack), fOperationalRegisters(NULL), fRegisterArea(-1), fHccaArea(-1), fHcca(NULL), fInterruptEndpoints(NULL), fDummyControl(NULL), fDummyBulk(NULL), fDummyIsochronous(NULL), fFirstTransfer(NULL), fLastTransfer(NULL), fFinishTransfersSem(-1), fFinishThread(-1), fStopFinishThread(false), fProcessingPipe(NULL), fRootHub(NULL), fRootHubAddress(0), fPortCount(0) { if (!fInitOK) { TRACE_ERROR("bus manager failed to init\n"); return; } TRACE("constructing new OHCI host controller driver\n"); fInitOK = false; mutex_init(&fEndpointLock, "ohci endpoint lock"); // enable busmaster and memory mapped access uint16 command = sPCIModule->read_pci_config(fPCIInfo->bus, fPCIInfo->device, fPCIInfo->function, PCI_command, 2); command &= ~PCI_command_io; command |= PCI_command_master | PCI_command_memory; sPCIModule->write_pci_config(fPCIInfo->bus, fPCIInfo->device, fPCIInfo->function, PCI_command, 2, command); // map the registers uint32 offset = sPCIModule->read_pci_config(fPCIInfo->bus, fPCIInfo->device, fPCIInfo->function, PCI_base_registers, 4); offset &= PCI_address_memory_32_mask; TRACE_ALWAYS("iospace offset: 0x%lx\n", offset); fRegisterArea = map_physical_memory("OHCI memory mapped registers", (void *)offset, B_PAGE_SIZE, B_ANY_KERNEL_BLOCK_ADDRESS, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA | B_READ_AREA | B_WRITE_AREA, (void **)&fOperationalRegisters); if (fRegisterArea < B_OK) { TRACE_ERROR("failed to map register memory\n"); return; } TRACE("mapped operational registers: %p\n", fOperationalRegisters); // Check the revision of the controller, which should be 10h uint32 revision = _ReadReg(OHCI_REVISION) & 0xff; TRACE("version %ld.%ld%s\n", OHCI_REVISION_HIGH(revision), OHCI_REVISION_LOW(revision), OHCI_REVISION_LEGACY(revision) ? ", legacy support" : ""); if (OHCI_REVISION_HIGH(revision) != 1 || OHCI_REVISION_LOW(revision) != 0) { TRACE_ERROR("unsupported OHCI revision\n"); return; } void *hccaPhysicalAddress; fHccaArea = fStack->AllocateArea((void **)&fHcca, &hccaPhysicalAddress, sizeof(ohci_hcca), "USB OHCI Host Controller Communication Area"); if (fHccaArea < B_OK) { TRACE_ERROR("unable to create the HCCA block area\n"); return; } memset(fHcca, 0, sizeof(ohci_hcca)); // Set Up Host controller // Dummy endpoints fDummyControl = _AllocateEndpoint(); if (!fDummyControl) return; fDummyBulk = _AllocateEndpoint(); if (!fDummyBulk) { _FreeEndpoint(fDummyControl); return; } fDummyIsochronous = _AllocateEndpoint(); if (!fDummyIsochronous) { _FreeEndpoint(fDummyControl); _FreeEndpoint(fDummyBulk); return; } // Static endpoints that get linked in the HCCA fInterruptEndpoints = new(std::nothrow) ohci_endpoint_descriptor *[OHCI_STATIC_ENDPOINT_COUNT]; if (!fInterruptEndpoints) { TRACE_ERROR("failed to allocate memory for interrupt endpoints\n"); _FreeEndpoint(fDummyControl); _FreeEndpoint(fDummyBulk); _FreeEndpoint(fDummyIsochronous); return; } for (int32 i = 0; i < OHCI_STATIC_ENDPOINT_COUNT; i++) { fInterruptEndpoints[i] = _AllocateEndpoint(); if (!fInterruptEndpoints[i]) { TRACE_ERROR("failed to allocate interrupt endpoint %ld", i); while (--i >= 0) _FreeEndpoint(fInterruptEndpoints[i]); _FreeEndpoint(fDummyBulk); _FreeEndpoint(fDummyControl); _FreeEndpoint(fDummyIsochronous); return; } } // build flat tree so that at each of the static interrupt endpoints // fInterruptEndpoints[i] == interrupt endpoint for interval 2^i uint32 interval = OHCI_BIGGEST_INTERVAL; uint32 intervalIndex = OHCI_STATIC_ENDPOINT_COUNT - 1; while (interval > 1) { uint32 insertIndex = interval / 2; while (insertIndex < OHCI_BIGGEST_INTERVAL) { fHcca->interrupt_table[insertIndex] = fInterruptEndpoints[intervalIndex]->physical_address; insertIndex += interval; } intervalIndex--; interval /= 2; } // setup the empty slot in the list and linking of all -> first fHcca->interrupt_table[0] = fInterruptEndpoints[0]->physical_address; for (int32 i = 1; i < OHCI_STATIC_ENDPOINT_COUNT; i++) { fInterruptEndpoints[i]->next_physical_endpoint = fInterruptEndpoints[0]->physical_address; fInterruptEndpoints[i]->next_logical_endpoint = fInterruptEndpoints[0]; } // Now link the first endpoint to the isochronous endpoint fInterruptEndpoints[0]->next_physical_endpoint = fDummyIsochronous->physical_address; // Determine in what context we are running (Kindly copied from FreeBSD) uint32 control = _ReadReg(OHCI_CONTROL); if (control & OHCI_INTERRUPT_ROUTING) { TRACE_ALWAYS("smm is in control of the host controller\n"); uint32 status = _ReadReg(OHCI_COMMAND_STATUS); _WriteReg(OHCI_COMMAND_STATUS, status | OHCI_OWNERSHIP_CHANGE_REQUEST); for (uint32 i = 0; i < 100 && (control & OHCI_INTERRUPT_ROUTING); i++) { snooze(1000); control = _ReadReg(OHCI_CONTROL); } if ((control & OHCI_INTERRUPT_ROUTING) != 0) { TRACE_ERROR("smm does not respond. resetting...\n"); _WriteReg(OHCI_CONTROL, OHCI_HC_FUNCTIONAL_STATE_RESET); snooze(USB_DELAY_BUS_RESET); } else TRACE_ALWAYS("ownership change successful\n"); } else { TRACE("cold started\n"); snooze(USB_DELAY_BUS_RESET); } // This reset should not be necessary according to the OHCI spec, but // without it some controllers do not start. _WriteReg(OHCI_CONTROL, OHCI_HC_FUNCTIONAL_STATE_RESET); snooze(USB_DELAY_BUS_RESET); // We now own the host controller and the bus has been reset uint32 frameInterval = _ReadReg(OHCI_FRAME_INTERVAL); uint32 intervalValue = OHCI_GET_INTERVAL_VALUE(frameInterval); // Disable interrupts right before we reset _WriteReg(OHCI_COMMAND_STATUS, OHCI_HOST_CONTROLLER_RESET); // Nominal time for a reset is 10 us uint32 reset = 0; for (uint32 i = 0; i < 10; i++) { spin(10); reset = _ReadReg(OHCI_COMMAND_STATUS) & OHCI_HOST_CONTROLLER_RESET; if (reset == 0) break; } if (reset) { TRACE_ERROR("error resetting the host controller (timeout)\n"); return; } // The controller is now in SUSPEND state, we have 2ms to go OPERATIONAL. // Interrupts are disabled. // Set up host controller register _WriteReg(OHCI_HCCA, (uint32)hccaPhysicalAddress); _WriteReg(OHCI_CONTROL_HEAD_ED, (uint32)fDummyControl->physical_address); _WriteReg(OHCI_BULK_HEAD_ED, (uint32)fDummyBulk->physical_address); // Disable all interrupts _WriteReg(OHCI_INTERRUPT_DISABLE, OHCI_ALL_INTERRUPTS); // Switch on desired functional features control = _ReadReg(OHCI_CONTROL); control &= ~(OHCI_CONTROL_BULK_SERVICE_RATIO_MASK | OHCI_ENABLE_LIST | OHCI_HC_FUNCTIONAL_STATE_MASK | OHCI_INTERRUPT_ROUTING); control |= OHCI_ENABLE_LIST | OHCI_CONTROL_BULK_RATIO_1_4 | OHCI_HC_FUNCTIONAL_STATE_OPERATIONAL; // And finally start the controller _WriteReg(OHCI_CONTROL, control); // The controller is now OPERATIONAL. frameInterval = (_ReadReg(OHCI_FRAME_INTERVAL) & OHCI_FRAME_INTERVAL_TOGGLE) ^ OHCI_FRAME_INTERVAL_TOGGLE; frameInterval |= OHCI_FSMPS(intervalValue) | intervalValue; _WriteReg(OHCI_FRAME_INTERVAL, frameInterval); // 90% periodic uint32 periodic = OHCI_PERIODIC(intervalValue); _WriteReg(OHCI_PERIODIC_START, periodic); // Fiddle the No Over Current Protection bit to avoid chip bug uint32 desca = _ReadReg(OHCI_RH_DESCRIPTOR_A); _WriteReg(OHCI_RH_DESCRIPTOR_A, desca | OHCI_RH_NO_OVER_CURRENT_PROTECTION); _WriteReg(OHCI_RH_STATUS, OHCI_RH_LOCAL_POWER_STATUS_CHANGE); snooze(OHCI_ENABLE_POWER_DELAY); _WriteReg(OHCI_RH_DESCRIPTOR_A, desca); // The AMD756 requires a delay before re-reading the register, // otherwise it will occasionally report 0 ports. uint32 numberOfPorts = 0; for (uint32 i = 0; i < 10 && numberOfPorts == 0; i++) { snooze(OHCI_READ_DESC_DELAY); uint32 descriptor = _ReadReg(OHCI_RH_DESCRIPTOR_A); numberOfPorts = OHCI_RH_GET_PORT_COUNT(descriptor); } if (numberOfPorts > OHCI_MAX_PORT_COUNT) numberOfPorts = OHCI_MAX_PORT_COUNT; fPortCount = numberOfPorts; TRACE("port count is %d\n", fPortCount); // Create semaphore the finisher thread will wait for fFinishTransfersSem = create_sem(0, "OHCI Finish Transfers"); if (fFinishTransfersSem < B_OK) { TRACE_ERROR("failed to create semaphore\n"); return; } // Create the finisher service thread fFinishThread = spawn_kernel_thread(_FinishThread, "ohci finish thread", B_URGENT_DISPLAY_PRIORITY, (void *)this); resume_thread(fFinishThread); // Install the interrupt handler TRACE("installing interrupt handler\n"); install_io_interrupt_handler(fPCIInfo->u.h0.interrupt_line, _InterruptHandler, (void *)this, 0); // Enable interesting interrupts now that the handler is in place _WriteReg(OHCI_INTERRUPT_ENABLE, OHCI_NORMAL_INTERRUPTS | OHCI_MASTER_INTERRUPT_ENABLE); TRACE("OHCI host controller driver constructed\n"); fInitOK = true; }
void Hiopl::VibratoDepth(bool high) { _WriteReg(0xbd, high ? 0x40 : 0x0, 0x40); }
int32 OHCI::_Interrupt() { static spinlock lock = B_SPINLOCK_INITIALIZER; acquire_spinlock(&lock); uint32 status = 0; uint32 acknowledge = 0; bool finishTransfers = false; int32 result = B_HANDLED_INTERRUPT; // The LSb of done_head is used to inform the HCD that an interrupt // condition exists for both the done list and for another event recorded in // the HcInterruptStatus register. If done_head is 0, then the interrupt // was caused by other than the HccaDoneHead update and the // HcInterruptStatus register needs to be accessed to determine that exact // interrupt cause. If HccDoneHead is nonzero, then a done list update // interrupt is indicated and if the LSb of the Dword is nonzero, then an // additional interrupt event is indicated and HcInterruptStatus should be // checked to determine its cause. uint32 doneHead = fHcca->done_head; if (doneHead != 0) { status = OHCI_WRITEBACK_DONE_HEAD; if (doneHead & OHCI_DONE_INTERRUPTS) status |= _ReadReg(OHCI_INTERRUPT_STATUS) & _ReadReg(OHCI_INTERRUPT_ENABLE); } else { status = _ReadReg(OHCI_INTERRUPT_STATUS) & _ReadReg(OHCI_INTERRUPT_ENABLE) & ~OHCI_WRITEBACK_DONE_HEAD; if (status == 0) { // Nothing to be done (PCI shared interrupt) release_spinlock(&lock); return B_UNHANDLED_INTERRUPT; } } if (status & OHCI_SCHEDULING_OVERRUN) { TRACE_MODULE("scheduling overrun occured\n"); acknowledge |= OHCI_SCHEDULING_OVERRUN; } if (status & OHCI_WRITEBACK_DONE_HEAD) { TRACE_MODULE("transfer descriptors processed\n"); fHcca->done_head = 0; acknowledge |= OHCI_WRITEBACK_DONE_HEAD; result = B_INVOKE_SCHEDULER; finishTransfers = true; } if (status & OHCI_RESUME_DETECTED) { TRACE_MODULE("resume detected\n"); acknowledge |= OHCI_RESUME_DETECTED; } if (status & OHCI_UNRECOVERABLE_ERROR) { TRACE_MODULE_ERROR("unrecoverable error - controller halted\n"); _WriteReg(OHCI_CONTROL, OHCI_HC_FUNCTIONAL_STATE_RESET); // TODO: clear all pending transfers, reset and resetup the controller } if (status & OHCI_ROOT_HUB_STATUS_CHANGE) { TRACE_MODULE("root hub status change\n"); // Disable the interrupt as it will otherwise be retriggered until the // port has been reset and the change is cleared explicitly. // TODO: renable it once we use status changes instead of polling _WriteReg(OHCI_INTERRUPT_DISABLE, OHCI_ROOT_HUB_STATUS_CHANGE); acknowledge |= OHCI_ROOT_HUB_STATUS_CHANGE; } if (acknowledge != 0) _WriteReg(OHCI_INTERRUPT_STATUS, acknowledge); release_spinlock(&lock); if (finishTransfers) release_sem_etc(fFinishTransfersSem, 1, B_DO_NOT_RESCHEDULE); return result; }
/********************************************************************* * * _InitController */ static void _InitController(void) { #ifndef WIN32 _WriteReg(0x060806, 0x0100); /* Software Reset register */ _WriteReg(0x060804, 0x0000); /* Power save configuration register */ _WriteReg(0x060810, 0x0000); /* PLL setting register 0 */ _WriteReg(0x060812, 0x0017); /* PLL setting register 1 */ _WriteReg(0x060814, 0x0035); /* PLL setting register 2 */ _WriteReg(0x060810, 0x0001); /* PLL setting register 0 */ GUI_X_Delay(100); _WriteReg(0x060816, 0x0005); /* Internal clock configuration register */ _WriteReg(0x060804, 0x0002); /* Power save configuraion register */ _WriteReg(0x060820, 0x004D); /* Panel setting miscellaneous register */ _WriteReg(0x060822, 0x0001); /* Display setting register */ _WriteReg(0x060824, XSIZE_PHYS >> 3); /* Horizontal display width register */ _WriteReg(0x060826, 0x0028); /* Horizontal non-display period register */ _WriteReg(0x060828, YSIZE_PHYS); /* Vertical display height register */ _WriteReg(0x06082A, 0x000A); /* Vertical no-displayperiod register */ _WriteReg(0x06082C, 0x0010); /* HS pulse width register */ _WriteReg(0x06082E, 0x0010); /* HS pulse start position register */ _WriteReg(0x060830, 0x0002); /* VS Pulse width register */ _WriteReg(0x060832, 0x0004); /* VS Pulse start position register */ _WriteReg(0x060850, 0x0000); /* PIP layer setting register */ _WriteReg(0x060852, 0x8400); /* PIP layer start address register 0 */ _WriteReg(0x060854, 0x0003); /* PIP layer start address register 1 */ _WriteReg(0x060856, 0x0028); /* PIP layer width register */ _WriteReg(0x060858, 0x0020); /* PIP layer height register */ _WriteReg(0x06085A, 0x0060); /* PIP layer X start position register */ _WriteReg(0x06085C, 0x00D0); /* PIP layer Y start position register */ _WriteReg(0x060862, 0x0040); /* Alpha blending register */ _WriteReg(0x060864, 0x0000); /* Transparency register */ _WriteReg(0x060866, 0x0000); /* Transparency key color register 0 */ _WriteReg(0x060868, 0x0000); /* Transparency key color register 1 */ _WriteReg(0x0608D0, 0x0001); /* GPIO configuration register */ _WriteReg(0x0608D2, 0x0001); /* GPIO status and control regsietr */ _WriteReg(0x0608D4, 0x0000); /* GPIO Pull-down control register */ #endif }
void Hiopl::EnableKsr(int ch, int osc, bool enable) { int offset = this->_GetOffset(ch, osc); _WriteReg(0x20+offset, enable ? 0x10 : 0x0, 0x10); }