Beispiel #1
0
void cbus_display_registers(int startfrom, int howmany)

{

	int	regnum, regval, i;

	int end_at;



	end_at = startfrom + howmany;



	for(regnum = startfrom; regnum <= end_at;)

	{

		for (i = 0 ; i <= 7; i++, regnum++)

		{

			regval = SiIRegioCbusRead(regnum, 0);

		}

	}

}
Beispiel #2
0
Bool SI_CbusUpdateBusStatus ( byte channel )

{

    byte busStatus;



    busStatus = SiIRegioCbusRead( REG_CBUS_BUS_STATUS, channel );



    printk("CBUS status:%x \n",(int)busStatus);

    

    l_cbus[ channel].connected = (busStatus & BIT_BUS_CONNECTED) != 0;



    printk("CBUS connected:%x \n",(int)l_cbus[ channel].connected);

    /* Clear the interrupt register bits.   */



    SiIRegioCbusWrite( REG_CBUS_BUS_STATUS, channel, busStatus );



    return( l_cbus[ channel].connected );

}
Beispiel #3
0
void SI_CbusHeartBeat ( byte channel, byte enable)

{

	byte  value;

    value = SiIRegioCbusRead( REG_MSC_HEARTBEAT_CONTROL, channel);

    SiIRegioCbusWrite( REG_MSC_HEARTBEAT_CONTROL, channel, enable ? (value | MSC_HEARTBEAT_ENABLE) : ( value & 0x7F) );

}
Bool SI_CbusInitialize ( void )
{
	byte     channel;
	int	result = STATUS_SUCCESS;
	int	port = 0;
	word	devcap_reg;
	int 		regval;

	memset( &l_cbus, 0, sizeof( l_cbus ));
	dev_cap_regs_ready_bit = FALSE;

	/* Determine the Port Switch input ports that are selected for MHD  */
	/* operation and initialize the port to channel decode array.       */

	channel = 0;

	//
	// Setup local DEVCAP registers for read by the peer
	//
	devcap_reg = REG_CBUS_DEVICE_CAP_0;
	SiIRegioCbusWrite(devcap_reg++, channel, MHD_DEV_ACTIVE);
	SiIRegioCbusWrite(devcap_reg++, channel, MHD_VERSION);
	SiIRegioCbusWrite(devcap_reg++, channel, MHD_DEVICE_CATEGORY);
	SiIRegioCbusWrite(devcap_reg++, channel, 0);
	SiIRegioCbusWrite(devcap_reg++, channel, 0);
	SiIRegioCbusWrite(devcap_reg++, channel, MHD_DEV_VID_LINK_SUPPRGB444);
	SiIRegioCbusWrite(devcap_reg++, channel, MHD_DEV_AUD_LINK_2CH);
	SiIRegioCbusWrite(devcap_reg++, channel, 0);										// not for source
	SiIRegioCbusWrite(devcap_reg++, channel, MHD_LOGICAL_DEVICE_MAP);
	SiIRegioCbusWrite(devcap_reg++, channel, 0);										// not for source
	SiIRegioCbusWrite(devcap_reg++, channel, MHD_RCP_SUPPORT | MHD_RAP_SUPPORT);		// feature flag
	SiIRegioCbusWrite(devcap_reg++, channel, 0);
	SiIRegioCbusWrite(devcap_reg++, channel, 0);										// reserved
	SiIRegioCbusWrite(devcap_reg++, channel, MHD_SCRATCHPAD_SIZE);
	SiIRegioCbusWrite(devcap_reg++, channel, MHD_INTERRUPT_SIZE);
	SiIRegioCbusWrite(devcap_reg++, channel, 0);										//reserved

	if(SiIRegioCbusRead(REG_CBUS_SUPPORT, channel) == 0xff)
	{
		// Display all registers for debugging. Only at initialization.
		printk( "cbus initialization failed\n");
		cbus_display_registers(0, 0x30);
		return ERROR_INIT;
	}

	SiIRegioCbusWrite(REG_CBUS_INTR_ENABLE, channel, (BIT_CONNECT_CHG | BIT_MSC_MSG_RCV | BIT_MSC_XFR_DONE	| BIT_MSC_XFR_ABORT | BIT_MSC_ABORT | BIT_HEARTBEAT_TIMEOUT ));
	regval = SiIRegioCbusRead(REG_CBUS_LINK_CONTROL_2, channel);
	regval = (regval | 0x0C);
	SiIRegioCbusWrite(REG_CBUS_LINK_CONTROL_2, channel, regval);

	// Clear legacy bit on Wolverine TX.
	regval = SiIRegioCbusRead( REG_MSC_TIMEOUT_LIMIT, channel );
	SiIRegioCbusWrite( REG_MSC_TIMEOUT_LIMIT, channel, (regval & MSC_TIMEOUT_LIMIT_MSB_MASK));

	// Set NMax to 1
	SiIRegioCbusWrite( REG_CBUS_LINK_CONTROL_1, channel, 0x01);

	printk( "cbus_initialize. Poll interval = %d ms. CBUS Connected = %d\n", (int)CBUS_FW_INTR_POLL_MILLISECS, (int)SI_CbusChannelConnected(channel));

	return result;
}
static byte CBusCheckInterruptStatus ( byte channel )
{
	byte 	intStatus, result;
	byte     vs_cmd, vs_data;
	byte 	writeBurstLen 	= 0;

	/* Read CBUS interrupt status.  */
	intStatus = SiIRegioCbusRead( REG_CBUS_INTR_STATUS, channel );
	if( intStatus & BIT_MSC_MSG_RCV )
	{
		printk("( intStatus & BIT_MSC_MSG_RCV )\n");
		vs_cmd  = SiIRegioCbusRead( REG_CBUS_PRI_VS_CMD, channel );
		vs_data = SiIRegioCbusRead( REG_CBUS_PRI_VS_DATA, channel );
	}
	SiIRegioCbusWrite( REG_CBUS_INTR_STATUS, channel, intStatus );

	/* Check for interrupts.  */

	result = STATUS_SUCCESS;
	intStatus &= (~BIT_HEARTBEAT_TIMEOUT);	 //don't check heartbeat
	if( intStatus != 0 )
	{
		if( intStatus & BIT_CONNECT_CHG )
		{
			printk("( intStatus & BIT_CONNECT_CHG )\n");
			/* The connection change interrupt has been received.   */
			result = CBusProcessConnectionChange( channel );
			SiIRegioCbusWrite( REG_CBUS_BUS_STATUS, channel, BIT_CONNECT_CHG );
		}

		if( intStatus & BIT_MSC_XFR_DONE )
		{
			printk("( intStatus & BIT_MSC_XFR_DONE )\n");
			/* A previous MSC sub-command has been acknowledged by the responder.   */
			/* Does not include MSC MSG commands.                                   */

			l_cbus[ channel].state = CBUS_XFR_DONE;

			/* Save any response data in the channel request structure to be returned    */
			/* to the upper level.                                                      */

			msc_return_cmd = l_cbus[ channel].request[ l_cbus[ channel].activeIndex ].msgData[0] =
				SiIRegioCbusRead( REG_CBUS_PRI_RD_DATA_1ST, channel );
			msc_return_value = l_cbus[ channel].request[ l_cbus[ channel].activeIndex ].msgData[1] =
				SiIRegioCbusRead( REG_CBUS_PRI_RD_DATA_2ND, channel );

			printk ( "\nCBUS:: Transfer Done \n" );
			printk ("Response data Received:: %02X\n\n", (int)l_cbus[ channel].request[l_cbus[channel].activeIndex].msgData[0]);

			result = STATUS_SUCCESS;

			// Check if we received NACK from Peer
			writeBurstLen = SiIRegioCbusRead( REG_MSC_WRITE_BURST_LEN, channel );
			if( writeBurstLen & MSC_REQUESTOR_DONE_NACK )
			{
				result = ERROR_NACK_FROM_PEER;
				printk( "NACK received!!! :: %02X\n", (int)writeBurstLen) ;
			}
			result = CBusProcessFailureInterrupts( channel, intStatus, result );
		}

		if( intStatus & BIT_MSC_MSG_RCV )
		{
			printk("( intStatus & BIT_MSC_MSG_RCV )\n");
			/* Receiving a sub-command, either an actual command or */
			/* the response to a command we sent.                   */
			result = CBusProcessSubCommand( channel, vs_cmd, vs_data );
		}
	}
	return( result );
}
static byte CBusProcessSubCommand ( int channel, byte vs_cmd, byte vs_data )
{
	/* Save RCP message data in the channel request structure to be returned    */
	/* to the upper level.                                                      */

	l_cbus[channel].request[l_cbus[channel].activeIndex].command = vs_cmd;
	l_cbus[channel].request[l_cbus[channel].activeIndex].offsetData = vs_data;

	/* Parse it a little before telling the upper level about it.   */

	switch (vs_cmd) {
	case MHD_MSC_MSG_RCP:
	/* Received a Remote Control Protocol message.  Signal that */
	/* it has been received if we are in the right state,       */
	/* otherwise, it is a bogus message.  Don't send RCPK now   */
	/* because the upper layer must validate the command.       */
		printk ("CBUS:: Received <-- MHD_MSC_MSG_RCP::"
				" cbus state = %02X\n",
				(int)(l_cbus[ channel].state));
		switch (l_cbus[channel].state) {
		case CBUS_IDLE:
		case CBUS_SENT:
			l_cbus[channel].request[l_cbus[channel].activeIndex ].reqStatus = CBUS_REQ_RECEIVED;
			l_cbus[ channel].state = CBUS_RECEIVED;
			break;
		default:
			l_cbus[ channel].state = CBUS_IDLE;
			break;
		}

		break;
	case MHD_MSC_MSG_RCPK:
		printk ("CBUS:: Received <-- MHD_MSC_MSG_RCPK\n");
		break;
	case MHD_MSC_MSG_RCPE:
		printk ("CBUS:: Received <-- MHD_MSC_MSG_RCPE\n");
		break;
	case MHD_MSC_MSG_RAP:
		printk ("CBUS:: Received <-- MHD_MSC_MSG_RAP::"
			" cbus state = %02X\n",
			(int)(l_cbus[ channel].state));

		switch ( l_cbus[ channel].state ) {
		case CBUS_IDLE:
		case CBUS_SENT:
			l_cbus[ channel].request[ l_cbus[ channel].activeIndex ].reqStatus = CBUS_REQ_RECEIVED;
			l_cbus[ channel].state = CBUS_RECEIVED;
			break;
		default:
			l_cbus[ channel].state = CBUS_IDLE;
			break;
		}
		break;
	case MHD_MSC_MSG_RAPK:
		printk ("CBUS:: Received <-- MHD_MSC_MSG_RAPK\n");
		break;

#if MSC_TESTER
	case MHD_MSC_MSG_NEW_TESTER:
		SI_CbusMscMsgSubCmdSend(channel, MHD_MSC_MSG_NEW_TESTER_REPLY, 0x00);
		break;
	case MHD_MSC_MSG_NEW_TESTER_REPLY:
		msc_return_cmd = vs_cmd;
		break;
	case MHD_MSC_MSG_STATE_CHANGE:
		SiIRegioCbusWrite( REG_CBUS_DEVICE_CAP_0, channel, vs_data );
		SI_CbusMscMsgSubCmdSend(channel, MHD_MSC_MSG_STATE_CHANGE_REPLY, 0x00);
		break;
	case MHD_MSC_MSG_DEVCAP0_CHANGE:
		SiIRegioCbusWrite( REG_CBUS_DEVICE_CAP_0, channel, vs_data );
		SI_CbusMscMsgSubCmdSend(channel, MHD_MSC_MSG_DEVCAP_CHANGE_REPLY, SiIRegioCbusRead( REG_CBUS_DEVICE_CAP_0, channel);
		break;
	case MHD_MSC_MSG_DEVCAP1_CHANGE:
		SiIRegioCbusWrite( REG_CBUS_DEVICE_CAP_1, channel, vs_data );
		SI_CbusMscMsgSubCmdSend(channel, MHD_MSC_MSG_DEVCAP_CHANGE_REPLY, SiIRegioCbusRead( REG_CBUS_DEVICE_CAP_1, channel);
		break;
	case MHD_MSC_MSG_DEVCAP2_CHANGE:
		SiIRegioCbusWrite( REG_CBUS_DEVICE_CAP_2, channel, vs_data );
		SI_CbusMscMsgSubCmdSend(channel, MHD_MSC_MSG_DEVCAP_CHANGE_REPLY, SiIRegioCbusRead( REG_CBUS_DEVICE_CAP_2, channel);
		break;
	case MHD_MSC_MSG_DEVCAP3_CHANGE:
		SiIRegioCbusWrite( REG_CBUS_DEVICE_CAP_3, channel, vs_data );
		SI_CbusMscMsgSubCmdSend(channel, MHD_MSC_MSG_DEVCAP_CHANGE_REPLY, SiIRegioCbusRead( REG_CBUS_DEVICE_CAP_3, channel);
		break;
	case MHD_MSC_MSG_DEVCAP4_CHANGE:
		SiIRegioCbusWrite( REG_CBUS_DEVICE_CAP_4, channel, vs_data );
		SI_CbusMscMsgSubCmdSend(channel, MHD_MSC_MSG_DEVCAP_CHANGE_REPLY, SiIRegioCbusRead( REG_CBUS_DEVICE_CAP_4, channel);
		break;
	case MHD_MSC_MSG_DEVCAP5_CHANGE:
		SiIRegioCbusWrite( REG_CBUS_DEVICE_CAP_5, channel, vs_data );
		SI_CbusMscMsgSubCmdSend(channel, MHD_MSC_MSG_DEVCAP_CHANGE_REPLY, SiIRegioCbusRead( REG_CBUS_DEVICE_CAP_5, channel);
		break;
	case MHD_MSC_MSG_DEVCAP6_CHANGE:
		SiIRegioCbusWrite( REG_CBUS_DEVICE_CAP_6, channel, vs_data );
		SI_CbusMscMsgSubCmdSend(channel, MHD_MSC_MSG_DEVCAP_CHANGE_REPLY, SiIRegioCbusRead( REG_CBUS_DEVICE_CAP_6, channel);
		break;

	case MHD_MSC_MSG_DEVCAP7_CHANGE:
		SiIRegioCbusWrite( REG_CBUS_DEVICE_CAP_7, channel, vs_data );
		SI_CbusMscMsgSubCmdSend(channel, MHD_MSC_MSG_DEVCAP_CHANGE_REPLY, SiIRegioCbusRead( REG_CBUS_DEVICE_CAP_7, channel);
		break;
	case MHD_MSC_MSG_DEVCAP8_CHANGE:
		SiIRegioCbusWrite( REG_CBUS_DEVICE_CAP_8, channel, vs_data );
		SI_CbusMscMsgSubCmdSend(channel, MHD_MSC_MSG_DEVCAP_CHANGE_REPLY, SiIRegioCbusRead( REG_CBUS_DEVICE_CAP_8, channel);
		break;
	case MHD_MSC_MSG_DEVCAP9_CHANGE:
		SiIRegioCbusWrite( REG_CBUS_DEVICE_CAP_9, channel, vs_data );
		SI_CbusMscMsgSubCmdSend(channel, MHD_MSC_MSG_DEVCAP_CHANGE_REPLY, SiIRegioCbusRead( REG_CBUS_DEVICE_CAP_9, channel);
		break;
	case MHD_MSC_MSG_DEVCAP10_CHANGE:
		SiIRegioCbusWrite( REG_CBUS_DEVICE_CAP_A, channel, vs_data );
		SI_CbusMscMsgSubCmdSend(channel, MHD_MSC_MSG_DEVCAP_CHANGE_REPLY, SiIRegioCbusRead( REG_CBUS_DEVICE_CAP_A, channel);
		break;
	case MHD_MSC_MSG_DEVCAP11_CHANGE:
		SiIRegioCbusWrite( REG_CBUS_DEVICE_CAP_B, channel, vs_data );
		SI_CbusMscMsgSubCmdSend(channel, MHD_MSC_MSG_DEVCAP_CHANGE_REPLY, SiIRegioCbusRead( REG_CBUS_DEVICE_CAP_B, channel);
		break;
	case MHD_MSC_MSG_DEVCAP12_CHANGE:
		SiIRegioCbusWrite( REG_CBUS_DEVICE_CAP_C, channel, vs_data );
		SI_CbusMscMsgSubCmdSend(channel, MHD_MSC_MSG_DEVCAP_CHANGE_REPLY, SiIRegioCbusRead( REG_CBUS_DEVICE_CAP_C, channel);
		break;
	case MHD_MSC_MSG_DEVCAP13_CHANGE:
		SiIRegioCbusWrite( REG_CBUS_DEVICE_CAP_D, channel, vs_data );
		SI_CbusMscMsgSubCmdSend(channel, MHD_MSC_MSG_DEVCAP_CHANGE_REPLY, SiIRegioCbusRead( REG_CBUS_DEVICE_CAP_D, channel);
		break;
	case MHD_MSC_MSG_DEVCAP14_CHANGE:
		SiIRegioCbusWrite( REG_CBUS_DEVICE_CAP_E, channel, vs_data );
		SI_CbusMscMsgSubCmdSend(channel, MHD_MSC_MSG_DEVCAP_CHANGE_REPLY, SiIRegioCbusRead( REG_CBUS_DEVICE_CAP_E, channel);
		break;
	case MHD_MSC_MSG_DEVCAP15_CHANGE:
		SiIRegioCbusWrite( REG_CBUS_DEVICE_CAP_F, channel, vs_data );
		SI_CbusMscMsgSubCmdSend(channel, MHD_MSC_MSG_DEVCAP_CHANGE_REPLY, SiIRegioCbusRead( REG_CBUS_DEVICE_CAP_F, channel);
		break;
	case MHD_MSC_MSG_SET_INT0_CHECK:
		SI_CbusMscMsgSubCmdSend(channel, MHD_MSC_MSG_SET_INT_REPLY, SiIRegioCbusRead( REG_CBUS_SET_INT_0, channel );
		break;
	case MHD_MSC_MSG_SET_INT1_CHECK:
		SI_CbusMscMsgSubCmdSend(channel, MHD_MSC_MSG_SET_INT_REPLY, SiIRegioCbusRead( REG_CBUS_SET_INT_1, channel );
		break;
	case MHD_MSC_MSG_SET_INT2_CHECK:
		SI_CbusMscMsgSubCmdSend(channel, MHD_MSC_MSG_SET_INT_REPLY, SiIRegioCbusRead( REG_CBUS_SET_INT_2, channel );
		break;
	case MHD_MSC_MSG_SET_INT3_CHECK:
		SI_CbusMscMsgSubCmdSend(channel, MHD_MSC_MSG_SET_INT_REPLY, SiIRegioCbusRead( REG_CBUS_SET_INT_3, channel );
		break;
	case MHD_MSC_MSG_WRITE_STAT0_CHECK:
		SI_CbusMscMsgSubCmdSend(channel, MHD_MSC_MSG_WRITE_STAT_REPLY, SiIRegioCbusRead( REG_CBUS_WRITE_STAT_0, channel );
		break;
	case MHD_MSC_MSG_WRITE_STAT1_CHECK:
		SI_CbusMscMsgSubCmdSend(channel, MHD_MSC_MSG_WRITE_STAT_REPLY, SiIRegioCbusRead( REG_CBUS_WRITE_STAT_1, channel );
		break;
	case MHD_MSC_MSG_WRITE_STAT2_CHECK:
		SI_CbusMscMsgSubCmdSend(channel, MHD_MSC_MSG_WRITE_STAT_REPLY, SiIRegioCbusRead( REG_CBUS_WRITE_STAT_2, channel );
		break;
	case MHD_MSC_MSG_WRITE_STAT3_CHECK:
		SI_CbusMscMsgSubCmdSend(channel, MHD_MSC_MSG_WRITE_STAT_REPLY, SiIRegioCbusRead( REG_CBUS_WRITE_STAT_3, channel );
		break;
	case MHD_MSC_MSG_STATE_CHANGE_REPLY:
		msc_return_cmd = vs_cmd;
		break;
	case MHD_MSC_MSG_DEVCAP_CHANGE_REPLY:
		msc_return_cmd = vs_cmd;
		break;
	case MHD_MSC_MSG_SET_INT_REPLY:
		msc_return_value = vs_data;
		msc_return_cmd = vs_cmd;
		break;
	case MHD_MSC_MSG_WRITE_STAT_REPLY:
		msc_return_value = vs_data;
		msc_return_cmd = vs_cmd;
		break;
#endif
	default:
		break;
	}

	printk ("CBUS:: MSG_MSC CMD:  0x%02X\n", (int)vs_cmd );
	printk ("CBUS:: MSG_MSC Data: 0x%02X\n\n", (int)vs_data );

	return( STATUS_SUCCESS );
}
static byte CBusProcessFailureInterrupts ( byte channel, byte intStatus, byte inResult )
{

	byte result          = inResult;
	byte mscAbortReason  = STATUS_SUCCESS;
	byte ddcAbortReason  = STATUS_SUCCESS;

	/* At this point, we only need to look at the abort interrupts. */

	intStatus &=  /*BIT_DDC_ABORT |*/ BIT_MSC_ABORT | BIT_MSC_XFR_ABORT;

	if ( intStatus )
	{
		result = ERROR_CBUS_ABORT;		// No Retry will help

		/* If transfer abort or MSC abort, clear the abort reason register. */

		if( intStatus & BIT_CONNECT_CHG )
		{
			printk("CBUS Connection Change Detected\n");
		}
		if( intStatus & BIT_DDC_ABORT )
		{
			ddcAbortReason = SiIRegioCbusRead( REG_DDC_ABORT_REASON, channel );
			printk("CBUS DDC ABORT happened, reason:: %02X\n", (int)(ddcAbortReason));
		}

		if ( intStatus & BIT_MSC_XFR_ABORT )
		{
			mscAbortReason = SiIRegioCbusRead( REG_PRI_XFR_ABORT_REASON, channel );

			printk( "CBUS:: MSC Transfer ABORTED. Clearing 0x0D\n");
			SiIRegioCbusWrite( REG_PRI_XFR_ABORT_REASON, channel, 0xFF );
		}
		if ( intStatus & BIT_MSC_ABORT )
		{
			printk( "CBUS:: MSC Peer sent an ABORT. Clearing 0x0E\n");
			SiIRegioCbusWrite( REG_CBUS_PRI_FWR_ABORT_REASON, channel, 0xFF );
		}

		// Now display the abort reason.

		if ( mscAbortReason != 0 )
		{
			printk( "CBUS:: Reason for ABORT is ....0x%02X = ", (int)mscAbortReason );

			if ( mscAbortReason & CBUSABORT_BIT_REQ_MAXFAIL)
			{
				printk("Requestor MAXFAIL - retry threshold exceeded\n");
			}
			if ( mscAbortReason & CBUSABORT_BIT_PROTOCOL_ERROR)
			{
				printk ("Protocol Error\n");
			}
			if ( mscAbortReason & CBUSABORT_BIT_REQ_TIMEOUT)
			{
				printk ("Requestor translation layer timeout\n");
			}
			if ( mscAbortReason & CBUSABORT_BIT_PEER_ABORTED)
			{
				printk ("Peer sent an abort\n");
			}
			if ( mscAbortReason & CBUSABORT_BIT_UNDEFINED_OPCODE)
			{
				printk ("Undefined opcode\n");
			}
		}
	}

	/* Clear any failure interrupt that we received.    */
	SiIRegioCbusWrite( REG_CBUS_INTR_STATUS, channel, intStatus );

	return( result );
}