示例#1
0
文件: ohci.cpp 项目: mmanley/Antares
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;
}
示例#2
0
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)));
}
示例#3
0
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);
	}
}
示例#4
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, &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;
}
示例#5
0
文件: ohci.cpp 项目: mmanley/Antares
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;
}
示例#6
0
文件: ohci.cpp 项目: mmanley/Antares
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;
}
示例#7
0
// 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);
}
示例#8
0
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;
}
示例#9
0
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;
}
示例#10
0
void Hiopl::SetKsl(int ch, int osc, int level) {
	int offset = this->_GetOffset(ch, osc);
	_WriteReg(0x40+offset, (Bit8u)(level<<6), 0xc0);
}
示例#11
0
void Hiopl::SetAttenuation(int ch, int osc, int level) {
	int offset = this->_GetOffset(ch, osc);
	_WriteReg(0x40+offset, (Bit8u)level, 0x3f);
}
示例#12
0
void Hiopl::SetWaveform(int ch, int osc, Waveform wave) {
	int offset = this->_GetOffset(ch, osc);
	_WriteReg(0xe0+offset, (Bit8u)wave, 0x7);
}
示例#13
0
void Hiopl::EnableWaveformControl() {
	_WriteReg(0x01, 0x20);
}
示例#14
0
void Hiopl::_ClearRegBits(Bit32u reg, Bit8u mask) {
	_WriteReg(reg, regCache[reg] & ~mask);
}
示例#15
0
文件: ohci.cpp 项目: mmanley/Antares
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;
}
示例#16
0
void Hiopl::SetEnvelopeAttack(int ch, int osc, int t) {
	int offset = this->_GetOffset(ch, osc);
	_WriteReg(0x60+offset, (Bit8u)t<<4, 0xf0);
}
示例#17
0
void Hiopl::SetModulatorFeedback(int ch, int level) {
	int offset = this->_GetOffset(ch);
	_WriteReg(0xc0+offset, (Bit8u)level, 0x0e);
}
示例#18
0
void Hiopl::EnableAdditiveSynthesis(int ch, bool enable) {
	int offset = this->_GetOffset(ch);
	_WriteReg(0xc0+offset, enable ? 0x1 : 0x0, 0x1);
}
示例#19
0
void Hiopl::TremoloDepth(bool high) {
	_WriteReg(0xbd, high ? 0x80 : 0x0, 0x80);
}
示例#20
0
void Hiopl::SetEnvelopeRelease(int ch, int osc, int t) {
	int offset = this->_GetOffset(ch, osc);
	_WriteReg(0x80+offset, (Bit8u)t, 0x0f);
}
示例#21
0
void Hiopl::SetEnvelopeSustain(int ch, int osc, int level) {
	int offset = this->_GetOffset(ch, osc);
	_WriteReg(0x80+offset, (Bit8u)level<<4, 0xf0);
}
示例#22
0
void Hiopl::SetFrequencyMultiple(int ch, int osc, FreqMultiple mult) {
	int offset = this->_GetOffset(ch, osc);
	_WriteReg(0x20+offset, (Bit8u)mult, 0xf);
}
示例#23
0
文件: ohci.cpp 项目: mmanley/Antares
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;
}
示例#24
0
void Hiopl::VibratoDepth(bool high) {
	_WriteReg(0xbd, high ? 0x40 : 0x0, 0x40);
}
示例#25
0
文件: ohci.cpp 项目: mmanley/Antares
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;
}
示例#26
0
/*********************************************************************
*
*       _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
}
示例#27
0
void Hiopl::EnableKsr(int ch, int osc, bool enable) {
	int offset = this->_GetOffset(ch, osc);
	_WriteReg(0x20+offset, enable ? 0x10 : 0x0, 0x10);
}