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

📄 cem85xx.c

📁 这是一个SIGMA方案的PMP播放器的UCLINUX程序,可播放DVD,VCD,CD MP3...有很好的参考价值.
💻 C
字号:
/********************************************************************************************//*  cem85xx.c : Implementation of the EM85xx interface*  REALmagic Quasar Hardware Library*  Created by Aurelia Popa-Radu*  Copyright Sigma Designs Inc*  Sigma Designs Proprietary and confidential*  Created on 05/17/02*  Description:/********************************************************************************************/#include "pch.h"#if defined EM85XX_OBJECT// specific code for Jasper#include "cquasar.h"#include "em847x.h"#include "regs847x.h"#define CHIP_REVISION_REG	0x500008#define PIO_0F_INT_REG		0x500600#define PIO_0F_DATA_REG		0x500604#define PIO_0F_DIR_REG		0x500608#define PIO_0F_POL_REG		0x50060C#define PIO_0F_INT_EN_REG	0x500610#define PIO_101F_INT_REG	0x500A00#define PIO_101F_DATA_REG	0x500A04#define PIO_101F_DIR_REG	0x500A08#define PIO_101F_POL_REG	0x500A0C#define PIO_101F_INT_EN_REG	0x500A10QRESULT CEM85XX__SetPIODir(IDecoder* pIDecoder, DWORD PIONumber, DWORD Dir){	if(PIONumber < 16)	{		OSWritePciDword((DWORD *)PIO_0F_DIR_REG, ((Dir ? 0x00010001:0x00010000) << PIONumber));	}	else	{		OSWritePciDword((DWORD *)PIO_101F_DIR_REG, ((Dir ? 0x00010001:0x00010000) << (PIONumber-16)));	}	return Q_OK;}QRESULT CEM85XX__WritePIO(IDecoder* pIDecoder, DWORD PIONumber, DWORD Data){	// don't assume that PIO is output	if(PIONumber < 16)	{		OSWritePciDword((DWORD *)PIO_0F_DATA_REG, ((Data? 0x00010001:0x00010000) << PIONumber));		OSWritePciDword((DWORD *)PIO_0F_DIR_REG, (0x00010001 << PIONumber));	}	else	{		OSWritePciDword((DWORD *)PIO_101F_DATA_REG, ((Data? 0x00010001:0x00010000) << (PIONumber-16)));		OSWritePciDword((DWORD *)PIO_101F_DIR_REG, (0x00010001 << (PIONumber-16)));	}	return Q_OK;}QRESULT CEM85XX__ReadPIO(IDecoder* pIDecoder, DWORD PIONumber, DWORD* pData){	// don't assume that PIO is input	if(PIONumber < 16)	{		OSWritePciDword((DWORD *)PIO_0F_DIR_REG, (0x00010000 << PIONumber) );		*pData = (OSReadPciDword((DWORD *)PIO_0F_DATA_REG) & (0x00000001 << PIONumber)) ? 1:0;	}	else	{		OSWritePciDword((DWORD *)PIO_101F_DIR_REG, (0x00010000 << (PIONumber-16)) );		*pData = (OSReadPciDword((DWORD *)PIO_101F_DATA_REG) & (0x00000001 << (PIONumber-16))) ? 1:0;	}	return Q_OK;}void CEM85XX__SetI2C_params(ISetI2CpIO* pISetI2CpIO, BYTE Data, BYTE Clock){	CQuasar* this = GET_CQUASAR_FROM_ISETI2CPIO (pISetI2CpIO);	this->PIO_I2C_Data = Data;	this->PIO_I2C_Clk = Clock;	this->m_I2Cparams.m_dwData0		= 0x00010000 << Data;	this->m_I2Cparams.m_dwData1		= 0x00010001 << Data;	this->m_I2Cparams.m_dwDataIN	= 0x00010000 << Data;	this->m_I2Cparams.m_dwDataOUT	= 0x00010001 << Data;	this->m_I2Cparams.m_dwClock0	= 0x00010000 << Clock;	this->m_I2Cparams.m_dwClock1	= 0x00010001 << Clock;	this->m_I2Cparams.m_dwClkIN		= 0x00010000 << Clock;	this->m_I2Cparams.m_dwClkOUT	= 0x00010001 << Clock;}void CEM85XX__SetClockDir(ISetI2CpIO* pISetI2CpIO, DWORD dir){	CQuasar* this = GET_CQUASAR_FROM_ISETI2CPIO (pISetI2CpIO);	OSWritePciDword((DWORD *)PIO_0F_DIR_REG, dir);}void CEM85XX__SetDataDir(ISetI2CpIO* pISetI2CpIO, DWORD dir){	CQuasar* this = GET_CQUASAR_FROM_ISETI2CPIO (pISetI2CpIO);	OSWritePciDword((DWORD *)PIO_0F_DIR_REG, dir);}void CEM85XX__WrClock(ISetI2CpIO* pISetI2CpIO, DWORD clock){	CQuasar* this = GET_CQUASAR_FROM_ISETI2CPIO (pISetI2CpIO);	OSWritePciDword((DWORD *)PIO_0F_DATA_REG, clock);}void CEM85XX__WrData(ISetI2CpIO* ISetI2CpIO, DWORD data){	CQuasar* this = GET_CQUASAR_FROM_ISETI2CPIO (ISetI2CpIO);	OSWritePciDword((DWORD *)PIO_0F_DATA_REG, data);}DWORD CEM85XX__RdData( ISetI2CpIO* ISetI2CpIO, DWORD Mask ){	CQuasar* this = GET_CQUASAR_FROM_ISETI2CPIO (ISetI2CpIO);	DWORD Data = OSReadPciDword((DWORD *)PIO_0F_DATA_REG);	if(Data & Mask)		return 1;	else		return 0;}BOOL CEM85XX__WriteDramSlave(IDecoder* pIDecoder, IN DWORD addr, IN DWORD* pData, IN DWORD nBytes){	DWORD i, timeout;	UCHAR* pBytes = (UCHAR*)pData;	CheckTransferSize(nBytes, TEXT("WriteDramSlave"))	CheckDramChannel(HOST_DRAM, TEXT("WriteDramSlave start timeout !"))	ProgramDramChannel(HOST_DRAM, addr, nBytes)	for(i=0; i<nBytes/4; i++)	{		OSWritePciDword((DWORD *)0x50150c, OSGetDword(pBytes) );		pBytes += 4;	}		switch(nBytes % 4)	// write bytes that are not multiple of 4	{	case 3:		OSWritePciDword((DWORD *)0x501508,OSGetDword(pBytes));		break;	case 2:		OSWritePciDword((DWORD *)0x501504,OSGetDword(pBytes));		break;	case 1:		OSWritePciDword((DWORD *)0x501500,OSGetDword(pBytes));	default:		break;	}	CheckDramChannel(HOST_DRAM, TEXT("WriteDramSlave end timeout !"))	return TRUE;}BOOL CEM85XX__FillDramSlave(IDecoder* pIDecoder, IN DWORD addr,IN DWORD nBytes, DWORD value){	DWORD i,timeout;	CheckTransferSize(nBytes, TEXT("FillDramSlave"))	CheckDramChannel(HOST_DRAM, TEXT("FillDramSlave start timeout !"))	ProgramDramChannel(HOST_DRAM, addr, nBytes)	for(i=0; i<nBytes/4; i++)		OSWritePciDword((DWORD *)0x50150c, value );	switch(nBytes % 4)	{	case 3:		OSWritePciDword((DWORD *)0x501508, value);		break;	case 2:		OSWritePciDword((DWORD *)0x501504, value);		break;	case 1:		OSWritePciDword((DWORD *)0x501500, value);	default:		break;	}	CheckDramChannel(HOST_DRAM, TEXT("FillDramSlave end timeout !"))	return TRUE;}BOOL CEM85XX__ReadSlaveDramToHost(IDecoder* pIDecoder, IN DWORD addr, OUT DWORD* pData, IN DWORD nBytes){	UCHAR* pBytes = (UCHAR*)pData;	DWORD i, timeout;	volatile DWORD tmp;	// BUGFIX: Hack to fix a bug in EM8500 - Consecutive read access to slave channel	// will fails, so we read a register in another block before reading the slave	// data register.(see BUGFIX lines below)	// Beware of compiler optimizations (gcc is happy with volatile declaration) 	// (Ask sammy for details..)  --  Fabrice 06/25/02	CheckTransferSize(nBytes, TEXT("ReadDramSlave"))	CheckDramChannel(DRAM_HOST, TEXT("ReadDramSlave start timeout !"))	// select Port1 for Slave Write to Host	CQuasar__WriteReg(pIDecoder, QPM_to_host_master_ena, Port1_to_SlaveWriteToHost);	ProgramDramChannel(DRAM_HOST, addr, nBytes)	for(i=0; i<nBytes/4; i++)	{		tmp = OSReadPciDword((DWORD *)0x500000); // BUGFIX		OSPutDword(OSReadPciDword((DWORD *)0x50150c), pBytes);		pBytes += 4;	}	switch(nBytes % 4)	{	case 3:		tmp = OSReadPciDword((DWORD *)0x500000); // BUGFIX		OSPutDword(OSReadPciDword((DWORD *)0x501508), pBytes);		break;	case 2:		tmp = OSReadPciDword((DWORD *)0x500000); // BUGFIX		OSPutDword(OSReadPciDword((DWORD *)0x501504), pBytes);		break;	case 1:		tmp = OSReadPciDword((DWORD *)0x500000); // BUGFIX		OSPutDword(OSReadPciDword((DWORD *)0x501500), pBytes);	default:		break;	}	CheckDramChannel(DRAM_HOST, TEXT("ReadDramSlave end timeout !"))	return TRUE;}///////////////////////////////////////////////////////////////////////////// start I2C specific implementation#include "ci2c.h"static void EM85xx_WriteReg (DWORD Reg, DWORD Data){	*((volatile DWORD *)Reg) = Data;}static DWORD EM85xx_ReadReg (DWORD Reg){	return *((volatile DWORD *)(Reg));}#define I2C_MASTER_BASE_ADDRESS		(0x500800)#define I2C_MASTER_CONFIG			(I2C_MASTER_BASE_ADDRESS + 0x00)#define I2C_MASTER_CLK_DIV			(I2C_MASTER_BASE_ADDRESS + 0x04)#define I2C_MASTER_DEV_ADDR			(I2C_MASTER_BASE_ADDRESS + 0x08)#define I2C_MASTER_ADR				(I2C_MASTER_BASE_ADDRESS + 0x0c)#define I2C_MASTER_DATAOUT			(I2C_MASTER_BASE_ADDRESS + 0x10)#define I2C_MASTER_DATAIN			(I2C_MASTER_BASE_ADDRESS + 0x14)#define I2C_MASTER_STATUS			(I2C_MASTER_BASE_ADDRESS + 0x18)#define I2C_MASTER_STARTXFER		(I2C_MASTER_BASE_ADDRESS + 0x1c)#define I2C_MASTER_BYTE_CNT			(I2C_MASTER_BASE_ADDRESS + 0x20)#define I2C_MASTER_INTEN			(I2C_MASTER_BASE_ADDRESS + 0x24)#define I2C_MASTER_INT				(I2C_MASTER_BASE_ADDRESS + 0x28)void CEM85xxI2C__Init ( II2C* pII2C ){}BOOL CEM85xxI2C__Write( II2C* pII2C, BYTE adr, BYTE* pData, int n ){	CI2C *this = (CI2C*) pII2C ;	int i;	EM85xx_WriteReg (I2C_MASTER_CONFIG, 0xf8);	EM85xx_WriteReg (I2C_MASTER_CLK_DIV, 375);	// assume 150mhz clock	// XXX bug: 0x70 is hardcoded as the device address	EM85xx_WriteReg (I2C_MASTER_DEV_ADDR, this->m_bI2cWriteAddr >> 1);	// ready for a command	// XXX bug: we really should have a timeout here	while ((EM85xx_ReadReg (I2C_MASTER_STATUS) & 1) == 0);	// write	for (i=0; i<n; i++)	{ 		EM85xx_WriteReg (I2C_MASTER_ADR, adr++);		EM85xx_WriteReg (I2C_MASTER_BYTE_CNT, 0);		EM85xx_WriteReg (I2C_MASTER_DATAOUT, *pData++);		EM85xx_WriteReg (I2C_MASTER_STARTXFER, 0);		// XXX bug: we really should have a timeout here		while ((EM85xx_ReadReg (I2C_MASTER_STATUS) & 2) == 0);	}		return TRUE;}BOOL CEM85xxI2C__Read( II2C* pII2C, BYTE adr, BYTE* pData, int n ){	CI2C *this = (CI2C*) pII2C ;	int i;		EM85xx_WriteReg (I2C_MASTER_CLK_DIV, 375);	// assume 150mhz clock 375=750/2	// ready for a command	// XXX bug: we really should have a timeout here	while ((EM85xx_ReadReg (I2C_MASTER_STATUS) & 1) == 0);	for (i=0; i<n; i++)	{		EM85xx_WriteReg (I2C_MASTER_CONFIG, 0xfa);		EM85xx_WriteReg (I2C_MASTER_BYTE_CNT, 0);		// XXX bug: 0x70 is hardcoded as the device address ???		EM85xx_WriteReg (I2C_MASTER_DEV_ADDR, this->m_bI2cReadAddr >> 1);		EM85xx_WriteReg	(I2C_MASTER_DATAOUT, adr++);				EM85xx_WriteReg	(I2C_MASTER_STARTXFER, 0);		// XXX bug: we really should have a timeout here		while ((EM85xx_ReadReg (I2C_MASTER_STATUS) & 2) == 0);		while ((EM85xx_ReadReg (I2C_MASTER_STATUS) & 1) == 0);		EM85xx_WriteReg (I2C_MASTER_CONFIG, 0x00FA);		EM85xx_WriteReg (I2C_MASTER_BYTE_CNT, 0);		// XXX bug: 0x70 is hardcoded as the device address		EM85xx_WriteReg (I2C_MASTER_DEV_ADDR, this->m_bI2cReadAddr >> 1);			EM85xx_WriteReg (I2C_MASTER_STARTXFER, 1);		// XXX bug: we really should have a timeout here		while ((EM85xx_ReadReg (I2C_MASTER_STATUS) & 4) == 0);		while ((EM85xx_ReadReg (I2C_MASTER_STATUS) & 1) == 0);		*pData++ = (BYTE)EM85xx_ReadReg (I2C_MASTER_DATAIN);	}	return TRUE;}BOOL CEM85xxI2C__Write_NoSubAddr( II2C* pII2C, BYTE* pData, int n ){	// XXX bug: implement to use TvTuner	return TRUE;}BOOL CEM85xxI2C__Read_NoSubAddr( II2C* pII2C, BYTE* pData, int n ){	// XXX bug: implement to use TvTuner	return TRUE;}// end I2C specific implementation///////////////////////////////////////////////////////////////////////////#ifdef UCODE_ROM_ADDRESS#warning using external ucodeUCHAR *UCodeJasper;#elseUCHAR UCodeJasper[] =  {	#ifdef MICROCODE_NO_DOLBY		#include "jasper/tst_no_dolby.h"	// doesn't play dolby no matter the bonding of the chip	#else		#include "jasper/tst.h"			// play dolby no matter the bonding of the chip	#endif};#endif/****v* HwLib/J * NAME *	J * DESCRIPTION *	Global array of symbols used to send commands and data to EM847x through microcode./********************************************************************************************/JSymbolTable J;#undef DEFINE_ENTRY#define DEFINE_ENTRY(Symbol) J.Symbol.str = #Symbol;#include "symbols.h"QRESULT InitializeJSymbolsTable( IDecoder* pIDecoder ){	// same symbols like EM847X except VideoIn	SymbolEntry* pSymbolEntry = (SymbolEntry*)&J;	int i;	CommonSymbols	Q4Mpeg4SymbolsTable	Q4AudioNewSymbolsTable	Q4ReverseGOPSymbolsTable	VideoCaptureSymbolTable	JOSDSymbolsTable	for( i=0;i<( sizeof(JSymbolTable)/sizeof(SymbolEntry) );i++ )	{		if( !CQuasar__SearchSymbol(pIDecoder, pSymbolEntry->str, &pSymbolEntry->addr))		{			pSymbolEntry->addr = 0;			OSsprintf(g_InfoError, TEXT("Symbol %s not found"), pSymbolEntry->str );			QDbgLog((QLOG_TRACE, QDebugLevelError,  TEXT("Symbol %s not found"), pSymbolEntry->str));			return E_GET_SYMBOLS_FAILED;		}		pSymbolEntry++;	}	return Q_OK;}QRESULT CEM85XX__SetMicrocode(IDecoder* pIDecoder, DWORD Id){	CQuasar *this = (CQuasar*) pIDecoder;	if(Id == ebiUcode_MpegDecode)	{#ifndef UCODE_ROM_ADDRESS						this->pUCode = (BYTE*)UCodeJasper;		this->UCodeSize = sizeof(UCodeJasper);#else#warning using external ucode				// special uCode in ROM		this->UCodeSize = *(DWORD *)(UCODE_ROM_ADDRESS);		this->pUCode = OSmalloc(this->UCodeSize);		QDbgLog((QLOG_TRACE, QDebugLevelError, TEXT("Setting ucode %p - %08x"), UCODE_ROM_ADDRESS+4,this->UCodeSize));		OSmemcpy(this->pUCode, UCODE_ROM_ADDRESS+4,this->UCodeSize); #endif		this->pQ = (void*)&J;		this->SymbolTableSize = sizeof(J);		return InitializeJSymbolsTable(pIDecoder);	}	else		return E_NOT_SUPPORTED;}void CEM85XX__InitVtable(IDecoder* pIDecoder){	unsigned long int ChipRevision;	CQuasar *this = (CQuasar*) pIDecoder;	ChipRevision = OSReadPciDword ((DWORD *)CHIP_REVISION_REG);	this->VTable.InitPtsFifo				= CEM847X__InitPtsFifo;	this->VTable.PtsFifoEmptiness			= CEM847X__PtsFifoEmptiness;	this->VTable.WritePTS					= CEM847X__WritePTS;	this->VTable.WritePCR					= CEM847X__WritePCR;	this->VTable.SetAudioSampleRate			= CEM847X__SetAudioSampleRate;	// revision 1 and above has an "enhanced" audio clock	if (ChipRevision)		this->VTable.SetAudioSampleRate	= CEM848X__SetAudioSampleRate;	else		this->VTable.SetAudioSampleRate	= CEM847X__SetAudioSampleRate;	this->VTable.InitPropertySet			= CEM847X__InitPropertySet;	this->VTable.SetProperty				= CEM847X__SetProperty;	this->VTable.GetProperty				= CEM847X__GetProperty;	this->VTable.SetDisplayFilter			= CEM847X__SetDisplayFilter;	this->VTable.ProgramVClk				= CEM847X__ProgramVClk;	this->VTable.ReadLbcReg					= CEM847X__ReadLbcReg;	this->VTable.WriteLbcReg				= CEM847X__WriteLbcReg;	this->VTable.WriteDataToLBC				= CEM847X__WriteDataToLBC;	this->VTable.ReadDataFromLBC			= CEM847X__ReadDataFromLBC;	this->VTable.SetMicrocode				= CEM85XX__SetMicrocode;	this->VTable.SetPIODir					= CEM85XX__SetPIODir;	this->VTable.WritePIO					= CEM85XX__WritePIO;	this->VTable.ReadPIO					= CEM85XX__ReadPIO;	this->VTable.WriteDramSlave				= CEM85XX__WriteDramSlave;	this->VTable.FillDramSlave				= CEM85XX__FillDramSlave;	this->VTable.ReadDramSlave				= CEM85XX__ReadSlaveDramToHost;	this->m_ISetI2CpIOVtbl.SetI2C_params	= CEM85XX__SetI2C_params;	this->m_ISetI2CpIOVtbl.SetClockDir		= CEM85XX__SetClockDir;	this->m_ISetI2CpIOVtbl.SetDataDir		= CEM85XX__SetDataDir;	this->m_ISetI2CpIOVtbl.WrClock			= CEM85XX__WrClock;	this->m_ISetI2CpIOVtbl.WrData			= CEM85XX__WrData;	this->m_ISetI2CpIOVtbl.RdData			= CEM85XX__RdData;}void CQuasar__InitVtable(IDecoder* pIDecoder){	CEM85XX__InitVtable(pIDecoder);}void CSigmaTv__InitVtable(ITvEncoder* pITvEncoder){	CEM847X__TvInitVtable(pITvEncoder);}#endif	//	EM85XX_OBJECT

⌨️ 快捷键说明

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