Patch by Euan Kirkhope:

* Initial support for Rage Theatre 200.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20338 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2007-03-05 21:16:15 +00:00
parent 0dd99544d0
commit 863634b83f
20 changed files with 3393 additions and 1577 deletions
@@ -20,6 +20,7 @@
#include "ddc.h" #include "ddc.h"
// magic code for ioctls // magic code for ioctls
// changed from TKRA to TKR1 for RADEON_WAITFORFIFO ioctl
// changed from TKRA to TKR2 for VIP FIFO ioctls // changed from TKRA to TKR2 for VIP FIFO ioctls
#define RADEON_PRIVATE_DATA_MAGIC 'TKR2' #define RADEON_PRIVATE_DATA_MAGIC 'TKR2'
@@ -15,15 +15,25 @@ CI2CPort::CI2CPort(CRadeon & radeon, int rate)
: fRadeon(radeon), : fRadeon(radeon),
fNfactor(0), fNfactor(0),
fMfactor(0), fMfactor(0),
fTimeLimit(0) fTimeLimit(0),
si(NULL)
{ {
PRINT(("CI2CPort::CI2CPort()\n")); PRINT(("CI2CPort::CI2CPort()\n"));
if( fRadeon.InitCheck() == B_OK ) { if( fRadeon.InitCheck() == B_OK ) {
int refFreq, refDiv, minFreq, maxFreq, xclock; int refFreq, refDiv, minFreq, maxFreq, xclock;
double n;
fRadeon.GetPLLParameters(refFreq, refDiv, minFreq, maxFreq, xclock); fRadeon.GetPLLParameters(refFreq, refDiv, minFreq, maxFreq, xclock);
si = fRadeon.GetSharedInfo();
double n = (xclock * 10000.0) / (4.0 * rate);
if ( si->asic == rt_rv200 ) {
n = (xclock * 40000.0) / (1.0 * rate);
} else {
n = (xclock * 10000.0) / (4.0 * rate);
}
for (fNfactor = 1; fNfactor < 255; fNfactor++) { for (fNfactor = 1; fNfactor < 255; fNfactor++) {
if (fNfactor * (fNfactor - 1) > n) if (fNfactor * (fNfactor - 1) > n)
break; break;
@@ -62,7 +72,17 @@ CI2CPort::~CI2CPort()
status_t CI2CPort::InitCheck() const status_t CI2CPort::InitCheck() const
{ {
return fRadeon.InitCheck(); if (fRadeon.InitCheck() != B_OK)
return B_ERROR;
if ( si == NULL )
return B_ERROR;
if ( si->has_no_i2c ) {
PRINT(("This Chips I2C is BLACKLISTED!"));
return B_ERROR;
}
return B_OK;
} }
CRadeon & CI2CPort::Radeon() const CRadeon & CI2CPort::Radeon() const
@@ -132,16 +152,22 @@ int CI2CPort::Send(int address, const char * buffer, int length, bool start, boo
C_RADEON_I2C_HALT | C_RADEON_I2C_SOFT_RST); C_RADEON_I2C_HALT | C_RADEON_I2C_SOFT_RST);
// write address // write address
fRadeon.SetRegister(C_RADEON_I2C_DATA, address & 0xfffffffe); fRadeon.SetRegister(C_RADEON_I2C_DATA, address & ~(1));
// write data // write data
for (int offset = 0; offset < length; offset++) for (int offset = 0; offset < length; offset++)
fRadeon.SetRegister(C_RADEON_I2C_DATA, buffer[offset]); fRadeon.SetRegister(C_RADEON_I2C_DATA, buffer[offset]);
// //
fRadeon.SetRegister(C_RADEON_I2C_CNTL_1, if (si->asic >= rt_r200) {
(fTimeLimit << 24) | length | fRadeon.SetRegister(C_RADEON_I2C_CNTL_1,
C_RADEON_I2C_EN | C_RADEON_I2C_SEL | 0x100); (fTimeLimit << 24) | length |
C_RADEON_I2C_EN | C_RADEON_I2C_SEL | 0x010);
} else {
fRadeon.SetRegister(C_RADEON_I2C_CNTL_1,
(fTimeLimit << 24) | length |
C_RADEON_I2C_EN | C_RADEON_I2C_SEL | 0x100);
}
fRadeon.SetRegister(C_RADEON_I2C_CNTL_0, fRadeon.SetRegister(C_RADEON_I2C_CNTL_0,
(fNfactor << 24) | (fMfactor << 16) | (fNfactor << 24) | (fMfactor << 16) |
@@ -171,9 +197,15 @@ int CI2CPort::Receive(int address, char * buffer, int length, bool start, bool s
fRadeon.SetRegister(C_RADEON_I2C_DATA, address | 0x00000001); fRadeon.SetRegister(C_RADEON_I2C_DATA, address | 0x00000001);
fRadeon.SetRegister(C_RADEON_I2C_CNTL_1, if (si->asic >= rt_r200) {
(fTimeLimit << 24) | C_RADEON_I2C_EN | //C_RADEON_I2C_SEL | fRadeon.SetRegister(C_RADEON_I2C_CNTL_1,
length | 0x100); (fTimeLimit << 24) | C_RADEON_I2C_EN | C_RADEON_I2C_SEL |
length | 0x010);
} else {
fRadeon.SetRegister(C_RADEON_I2C_CNTL_1,
(fTimeLimit << 24) | C_RADEON_I2C_EN | C_RADEON_I2C_SEL |
length | 0x100);
}
fRadeon.SetRegister(C_RADEON_I2C_CNTL_0, fRadeon.SetRegister(C_RADEON_I2C_CNTL_0,
(fNfactor << 24) | (fMfactor << 16) | C_RADEON_I2C_GO | (fNfactor << 24) | (fMfactor << 16) | C_RADEON_I2C_GO |
@@ -222,7 +254,7 @@ void CI2CPort::Stop()
C_RADEON_I2C_DONE | C_RADEON_I2C_NACK | C_RADEON_I2C_HALT, 0); C_RADEON_I2C_DONE | C_RADEON_I2C_NACK | C_RADEON_I2C_HALT, 0);
// issue abort call // issue abort call
fRadeon.SetRegister(C_RADEON_I2C_CNTL_0, fRadeon.SetRegister(C_RADEON_I2C_CNTL_0_PLUS1,
C_RADEON_I2C_ABORT | C_RADEON_I2C_GO, C_RADEON_I2C_ABORT | C_RADEON_I2C_GO); C_RADEON_I2C_ABORT | C_RADEON_I2C_GO, C_RADEON_I2C_ABORT | C_RADEON_I2C_GO);
// wait GO bit to go low // wait GO bit to go low
@@ -57,6 +57,7 @@ private:
int fNfactor; int fNfactor;
int fMfactor; int fMfactor;
int fTimeLimit; int fTimeLimit;
shared_info* si;
}; };
@@ -16,6 +16,8 @@ Addon radeon.media_addon : media :
Tuner.cpp Tuner.cpp
VIPPort.cpp VIPPort.cpp
VideoIn.cpp VideoIn.cpp
Theater100.cpp
Theater200.cpp
; ;
LinkAgainst radeon.media_addon : be media ; LinkAgainst radeon.media_addon : be media ;
@@ -14,6 +14,7 @@
#include <string.h> #include <string.h>
//#include "Driver.h" //#include "Driver.h"
#include "Radeon.h" #include "Radeon.h"
#include "OS.h"
static const char * const C_RADEON_REGISTER_AREA_NAME = "RadeonRegisters"; static const char * const C_RADEON_REGISTER_AREA_NAME = "RadeonRegisters";
static const char * const C_RADEON_MEMORY_AREA_NAME = "RadeonMemory"; static const char * const C_RADEON_MEMORY_AREA_NAME = "RadeonMemory";
@@ -119,7 +120,8 @@ CRadeon::CRadeon( const char *dev_name )
fRegisterArea(0), fRegisterArea(0),
fROMArea(0), fROMArea(0),
fVirtualCardArea(0), fVirtualCardArea(0),
fSharedInfoArea(0) fSharedInfoArea(0),
caps_video_in(0)
{ {
PRINT(("CRadeon::CRadeon()\n")); PRINT(("CRadeon::CRadeon()\n"));
@@ -227,6 +229,7 @@ int CRadeon::VIPRegister(int device, int address)
vr.magic = RADEON_PRIVATE_DATA_MAGIC; vr.magic = RADEON_PRIVATE_DATA_MAGIC;
vr.channel = device; vr.channel = device;
vr.address = address; vr.address = address;
vr.lock = true;
res = ioctl( fHandle, RADEON_VIPREAD, &vr, sizeof( vr )); res = ioctl( fHandle, RADEON_VIPREAD, &vr, sizeof( vr ));
@@ -244,10 +247,53 @@ void CRadeon::SetVIPRegister(int device, int address, int value)
vw.channel = device; vw.channel = device;
vw.address = address; vw.address = address;
vw.data = value; vw.data = value;
vw.lock = true;
ioctl( fHandle, RADEON_VIPWRITE, &vw, sizeof( vw )); ioctl( fHandle, RADEON_VIPWRITE, &vw, sizeof( vw ));
} }
int CRadeon::VIPReadFifo(int device, uint32 address, uint32 count, uint8 *buffer)
{
radeon_vip_fifo_read vr;
status_t res;
vr.magic = RADEON_PRIVATE_DATA_MAGIC;
vr.channel = device;
vr.address = address;
vr.count = count;
vr.data = buffer;
vr.lock = true;
res = ioctl( fHandle, RADEON_VIPFIFOREAD, &vr, sizeof( vr ));
if( res == B_OK )
return TRUE;
else
return FALSE;
}
int CRadeon::VIPWriteFifo(int device, uint32 address, uint32 count, uint8 *buffer)
{
radeon_vip_fifo_write vw;
status_t res;
vw.magic = RADEON_PRIVATE_DATA_MAGIC;
vw.channel = device;
vw.address = address;
vw.count = count;
vw.data = buffer;
vw.lock = true;
res = ioctl( fHandle, RADEON_VIPFIFOWRITE, &vw, sizeof( vw ));
if( res == B_OK )
return TRUE;
else
return FALSE;
}
int CRadeon::FindVIPDevice( uint32 device_id ) int CRadeon::FindVIPDevice( uint32 device_id )
{ {
radeon_find_vip_device fvd; radeon_find_vip_device fvd;
@@ -264,6 +310,11 @@ int CRadeon::FindVIPDevice( uint32 device_id )
return -1; return -1;
} }
shared_info* CRadeon::GetSharedInfo()
{
return fSharedInfo;
}
void CRadeon::GetPLLParameters(int & refFreq, int & refDiv, int & minFreq, int & maxFreq, int & xclock) void CRadeon::GetPLLParameters(int & refFreq, int & refDiv, int & minFreq, int & maxFreq, int & xclock)
{ {
refFreq = fSharedInfo->pll.ref_freq; refFreq = fSharedInfo->pll.ref_freq;
@@ -280,12 +331,77 @@ void CRadeon::GetMMParameters(radeon_video_tuner & tuner,
int & compositePort, int & compositePort,
int & svideoPort) int & svideoPort)
{ {
unsigned char *fVideoBIOS = fROM + fROM[0x48] + (fROM[0x49] << 8);
unsigned char * fMMTable = fROM + fVideoBIOS[0x38] + (fVideoBIOS[0x39] << 8);
unsigned char * fMMTable = NULL;
PRINT(("CRadeon::GetMMParameters()\n"));
if (fSharedInfo->is_atombios) {
uint16 hdr = fROM[0x48] + (fROM[0x49] << 8);
uint16 PCIR = hdr + fROM[hdr] + (fROM[hdr + 1] << 8);
uint16 hdr2 = fROM[PCIR - 4] + (fROM[PCIR - 3] << 8);
uint16 hmMedia = fROM[hdr2 + 8] + (fROM[hdr2 + 9] << 8);
if(fROM[hmMedia ] == 0x14
&& fROM[hmMedia + 1] == 0x00
&& fROM[hmMedia + 2] == 0x01
&& fROM[hmMedia + 3] == 0x01
&& fROM[hmMedia + 4] == '$'
&& fROM[hmMedia + 5] == 'M'
&& fROM[hmMedia + 6] == 'M'
&& fROM[hmMedia + 7] == 'T') {
fMMTable = &fROM[hmMedia + 8];
PRINT(("ATOMBIOS MM Table Signiture found\n"));
} else {
PRINT(("ATOMBIOS MM Table Not Found\n"));
return;
}
} else {
unsigned char *fVideoBIOS = fROM + fROM[0x48] + (fROM[0x49] << 8);
fMMTable = fROM + fVideoBIOS[0x38] + (fVideoBIOS[0x39] << 8) - 2;
if (fMMTable[0] != 0x0c)
{
PRINT(("MM_TABLE invalid size\n"));
return;
}
else
{
PRINT(("MM Table Found (non ATOM) \n"));
PRINT(("Revision %02x\n", fMMTable[0]));
PRINT(("Size %02x\n", fMMTable[2]));
fMMTable += 2;
}
}
// check table:
PRINT(( "MM_TABLE:\n"));
const char* names[] = {
"Tuner Type %02x\n",
"Audio Chip %02x\n",
"Product ID %02x\n",
"Tuner misc %02x\n",
"I2C Config %02x\n",
"Vid Decoder %02x\n",
"..Host config %02x\n",
"input 0 %02x\n",
"input 1 %02x\n",
"input 2 %02x\n",
"input 3 %02x\n",
"input 4 %02x\n",
0
};
int i = 0;
while(names[i]) {
PRINT((names[i], fMMTable[i]));
i++;
}
switch (fMMTable[0] & 0x1f) { switch (fMMTable[0] & 0x1f) {
case 0x00: case 0x00:
tuner = C_RADEON_NO_TUNER; tuner = C_RADEON_NO_TUNER;
PRINT(("CRadeon::GetMMParameters() No Tuner\n"));
break; break;
case 0x01: case 0x01:
tuner = C_RADEON_FI1236_MK1_NTSC; tuner = C_RADEON_FI1236_MK1_NTSC;
@@ -328,12 +444,14 @@ void CRadeon::GetMMParameters(radeon_video_tuner & tuner,
break; break;
default: default:
tuner = C_RADEON_NO_TUNER; tuner = C_RADEON_NO_TUNER;
PRINT(("CRadeon::GetMMParameters() No Tuner\n"));
break; break;
} }
switch (fMMTable[5] & 0x0f) { switch (fMMTable[5] & 0x0f) {
case 0x00: case 0x00:
video = C_RADEON_NO_VIDEO; video = C_RADEON_NO_VIDEO;
PRINT(("CRadeon::GetMMParameters() No Video\n"));
break; break;
case 0x01: case 0x01:
video = C_RADEON_BT819; video = C_RADEON_BT819;
@@ -352,9 +470,11 @@ void CRadeon::GetMMParameters(radeon_video_tuner & tuner,
break; break;
case 0x06: case 0x06:
video = C_RADEON_RAGE_THEATER; video = C_RADEON_RAGE_THEATER;
PRINT(("CRadeon::GetMMParameters() Rage Theater\n"));
break; break;
default: default:
video = C_RADEON_NO_VIDEO; video = C_RADEON_NO_VIDEO;
PRINT(("CRadeon::GetMMParameters() No Video\n"));
break; break;
} }
@@ -364,6 +484,7 @@ void CRadeon::GetMMParameters(radeon_video_tuner & tuner,
case 0x20: case 0x20:
case 0x30: case 0x30:
clock = C_RADEON_NO_VIDEO_CLOCK; clock = C_RADEON_NO_VIDEO_CLOCK;
PRINT(("CRadeon::GetMMParameters() Video No Clock\n"));
break; break;
case 0x40: case 0x40:
clock = C_RADEON_VIDEO_CLOCK_28_63636_MHZ; clock = C_RADEON_VIDEO_CLOCK_28_63636_MHZ;
@@ -379,24 +500,29 @@ void CRadeon::GetMMParameters(radeon_video_tuner & tuner,
break; break;
default: default:
clock = C_RADEON_NO_VIDEO_CLOCK; clock = C_RADEON_NO_VIDEO_CLOCK;
PRINT(("CRadeon::GetMMParameters() Video No Clock\n"));
break; break;
} }
for (int port = 0; port < 4; port++) { for (int port = 0; port < 5; port++) {
switch (fMMTable[7 + port] & 0x03) { switch (fMMTable[7 + port] & 0x03) {
case 0x00: case 0x00:
// Unused or Invalid // Unused or Invalid
PRINT(("CRadeon::GetMMParameters() Invalid Port\n"));
break; break;
case 0x01: case 0x01:
// Tuner Input // Tuner Input
PRINT(("CRadeon::GetMMParameters() Tuner Port\n"));
tunerPort = 0; tunerPort = 0;
break; break;
case 0x02: case 0x02:
// Front/Rear Composite Input // Front/Rear Composite Input
PRINT(("CRadeon::GetMMParameters() Composite Port\n"));
compositePort = (fMMTable[7 + port] & 0x04 ? 2 : 1); compositePort = (fMMTable[7 + port] & 0x04 ? 2 : 1);
break; break;
case 0x03: case 0x03:
// Front/Rear SVideo Input // Front/Rear SVideo Input
PRINT(("CRadeon::GetMMParameters() SVideo Port\n"));
svideoPort = (fMMTable[7 + port] & 0x04 ? 6 : 5); svideoPort = (fMMTable[7 + port] & 0x04 ? 6 : 5);
break; break;
} }
@@ -46,7 +46,6 @@ enum radeon_video_decoder {
C_RADEON_RAGE_THEATER = 6 C_RADEON_RAGE_THEATER = 6
}; };
enum radeon_register { enum radeon_register {
C_RADEON_VIDEOMUX_CNTL = 0x0190, C_RADEON_VIDEOMUX_CNTL = 0x0190,
C_RADEON_VIPH_INT_SEL = BITS(0:0), C_RADEON_VIPH_INT_SEL = BITS(0:0),
@@ -56,6 +55,7 @@ enum radeon_register {
// I2C // I2C
C_RADEON_I2C_CNTL_0 = 0x0090, C_RADEON_I2C_CNTL_0 = 0x0090,
C_RADEON_I2C_CNTL_0_PLUS1 = 0x0091,
C_RADEON_I2C_DONE = BITS(0:0), C_RADEON_I2C_DONE = BITS(0:0),
C_RADEON_I2C_NACK = BITS(1:1), C_RADEON_I2C_NACK = BITS(1:1),
C_RADEON_I2C_HALT = BITS(2:2), C_RADEON_I2C_HALT = BITS(2:2),
@@ -352,6 +352,10 @@ public:
void SetVIPRegister(int device, int address, int value); void SetVIPRegister(int device, int address, int value);
int VIPReadFifo(int device, uint32 address, uint32 count, uint8 *buffer);
int VIPWriteFifo(int device, uint32 address, uint32 count, uint8 *buffer);
int FindVIPDevice( uint32 device_id ); int FindVIPDevice( uint32 device_id );
public: public:
@@ -383,6 +387,7 @@ public:
status_t CloneArea(const char * name, area_id src_area, status_t CloneArea(const char * name, area_id src_area,
area_id *cloned_area, void ** map); area_id *cloned_area, void ** map);
shared_info* GetSharedInfo();
private: private:
int fHandle; int fHandle;
unsigned int * fRegister; unsigned int * fRegister;
@@ -394,6 +399,8 @@ private:
area_id fROMArea; area_id fROMArea;
area_id fVirtualCardArea; area_id fVirtualCardArea;
area_id fSharedInfoArea; area_id fSharedInfoArea;
uint32 caps_video_in;
}; };
template <typename T> template <typename T>
@@ -412,9 +412,8 @@ CRadeonAddOn::RecursiveScan(const char* rootPath, BEntry *rootEntry = NULL)
// if there is a Rage Theatre, then there should be Video-In // if there is a Rage Theatre, then there should be Video-In
if( vip_port.InitCheck() == B_OK && if( vip_port.InitCheck() == B_OK &&
vip_port.FindVIPDevice( ((vip_port.FindVIPDevice( C_THEATER100_VIP_DEVICE_ID ) >= 0)
(C_THEATER_VIP_VENDOR_ID << 0) | || (vip_port.FindVIPDevice( C_THEATER200_VIP_DEVICE_ID ) >= 0)))
(C_THEATER_VIP_DEVICE_ID << 16)) >= 0 )
{ {
fDevices.AddItem( new CRadeonPlug( this, path, cur_id++ )); fDevices.AddItem( new CRadeonPlug( this, path, cur_id++ ));
} }
@@ -28,6 +28,7 @@
#include <app/Message.h> #include <app/Message.h>
#include "RadeonAddOn.h" #include "RadeonAddOn.h"
#include "VideoIn.h"
#define DPRINT(args) { PRINT(("\x1b[0;30;35m")); PRINT(args); PRINT(("\x1b[0;30;47m")); } #define DPRINT(args) { PRINT(("\x1b[0;30;35m")); PRINT(args); PRINT(("\x1b[0;30;47m")); }
@@ -50,6 +51,8 @@
// functions to convert to scattered Be-code to the compact video-in-code // functions to convert to scattered Be-code to the compact video-in-code
video_in_standard BeToVideoInStandard( int32 be_standard ) video_in_standard BeToVideoInStandard( int32 be_standard )
{ {
DPRINT(("BeToVideoInStandard %d \n", be_standard));
switch( be_standard ) { switch( be_standard ) {
case 1: return C_VIDEO_IN_NTSC; case 1: return C_VIDEO_IN_NTSC;
case 2: return C_VIDEO_IN_NTSC_JAPAN; case 2: return C_VIDEO_IN_NTSC_JAPAN;
@@ -66,14 +69,19 @@ video_in_standard BeToVideoInStandard( int32 be_standard )
int32 VideoInStandardToBe( video_in_standard standard ) int32 VideoInStandardToBe( video_in_standard standard )
{ {
int32 be_standard[] = { DPRINT(("VideoInStandardToBe %d \n", standard));
1, 2, 101, 4, 3, 5, 102, 103, 6 switch( standard ) {
}; case C_VIDEO_IN_NTSC: return 1;
case C_VIDEO_IN_NTSC_JAPAN: return 2;
if( (uint)standard < sizeof( be_standard ) / sizeof( be_standard[0] ) ) case C_VIDEO_IN_PAL_BDGHI: return 3;
return be_standard[(int)standard]; case C_VIDEO_IN_PAL_M: return 4;
else case C_VIDEO_IN_PAL_N: return 5;
return 1; case C_VIDEO_IN_SECAM: return 6;
case C_VIDEO_IN_NTSC_443: return 101;
case C_VIDEO_IN_PAL_60: return 102;
case C_VIDEO_IN_PAL_NC: return 103;
default: return 1;
}
} }
status_t CRadeonProducer::FindInt32( status_t CRadeonProducer::FindInt32(
@@ -130,7 +138,7 @@ CRadeonProducer::CRadeonProducer(
fInitStatus = B_OK; fInitStatus = B_OK;
fSource = ((fVideoIn.Capabilities() & C_VIDEO_IN_HAS_TUNER) != 0 ? C_VIDEO_IN_TUNER : C_VIDEO_IN_COMPOSITE); fSource = ((fVideoIn.Capabilities() & C_VIDEO_IN_HAS_TUNER) != 0 ? C_VIDEO_IN_TUNER : C_VIDEO_IN_COMPOSITE);
fStandard = 1; fStandard = C_VIDEO_IN_NTSC;
fMode = C_VIDEO_IN_WEAVE; fMode = C_VIDEO_IN_WEAVE;
fFormat = B_RGB32; fFormat = B_RGB32;
fResolution = 4; fResolution = 4;
@@ -174,6 +182,7 @@ CRadeonProducer::CRadeonProducer(
// standard is stored as internal code (which has no "holes" in its numbering); // standard is stored as internal code (which has no "holes" in its numbering);
// time to convert it // time to convert it
// if this value comes from our setup web is it not already linear?
fStandard = VideoInStandardToBe( (video_in_standard)standard ); fStandard = VideoInStandardToBe( (video_in_standard)standard );
// if there is no tuner, force composite input // if there is no tuner, force composite input
@@ -266,11 +275,11 @@ void CRadeonProducer::setupWeb()
P_AUDIO_SOURCE, B_MEDIA_RAW_VIDEO, "Audio Input:", "Audio Input:"); P_AUDIO_SOURCE, B_MEDIA_RAW_VIDEO, "Audio Input:", "Audio Input:");
if ((fVideoIn.Capabilities() & C_VIDEO_IN_HAS_TUNER) != 0) if ((fVideoIn.Capabilities() & C_VIDEO_IN_HAS_TUNER) != 0)
source2->AddItem(C_VIDEO_IN_TUNER, "Tuner"); source2->AddItem(C_VIDEO_IN_TUNER, "Tuner");
if ((fVideoIn.Capabilities() & C_VIDEO_IN_HAS_COMPOSITE) != 0) /* if ((fVideoIn.Capabilities() & C_VIDEO_IN_HAS_COMPOSITE) != 0)
source2->AddItem(C_VIDEO_IN_COMPOSITE, "Composite"); source2->AddItem(C_VIDEO_IN_COMPOSITE, "Composite");
if ((fVideoIn.Capabilities() & C_VIDEO_IN_HAS_SVIDEO) != 0) if ((fVideoIn.Capabilities() & C_VIDEO_IN_HAS_SVIDEO) != 0)
source2->AddItem(C_VIDEO_IN_SVIDEO, "SVideo"); source2->AddItem(C_VIDEO_IN_SVIDEO, "SVideo");
*/
// Controls.Brightness/Contrast/Saturation/Hue // Controls.Brightness/Contrast/Saturation/Hue
controls2->MakeContinuousParameter(P_BRIGHTNESS, B_MEDIA_RAW_VIDEO,"Brightness", "BRIGHTNESS", "", -100, 100, 1); controls2->MakeContinuousParameter(P_BRIGHTNESS, B_MEDIA_RAW_VIDEO,"Brightness", "BRIGHTNESS", "", -100, 100, 1);
@@ -877,11 +886,13 @@ CRadeonProducer::verifySetSize(
// our format converters do up to 8 pixels at a time (grey8); // our format converters do up to 8 pixels at a time (grey8);
// to be absolutely sure we don't get trouble there, refuse // to be absolutely sure we don't get trouble there, refuse
// any width that is not a multiple of 8 // any width that is not a multiple of 8
if( (format->u.raw_video.display.line_width & 7) != 0 ) { if( (format->u.raw_video.display.line_width & 7) != 0 ) {
DPRINT(( "Request image width is not multiple of 8 (%d)\n", DPRINT(( "Request image width is not multiple of 8 (%d)\n",
format->u.raw_video.display.line_width )); format->u.raw_video.display.line_width ));
return B_MEDIA_BAD_FORMAT; return B_MEDIA_BAD_FORMAT;
} }
} else { } else {
switch (fResolution) { switch (fResolution) {
case 0: case 0:
@@ -1081,8 +1092,7 @@ CRadeonProducer::finalizeFormat( media_format *format )
return res; return res;
setFormatFlags( format ); setFormatFlags( format );
return res;
return B_OK;
} }
@@ -1118,7 +1128,7 @@ CRadeonProducer::FormatSuggestionRequested(
First, the application defines a format with many wildcards in it; First, the application defines a format with many wildcards in it;
this format is passed to us, so we can restrict it if necessary; this format is passed to us, so we can restrict it if necessary;
we should leave as many wildcards as possible, because in the next we should leave as many wildcards as possible, because in the next
step the consumer is asked, and he will not be happy if he has to choise left . step the consumer is asked, and he will not be happy if he has no choice left .
*/ */
status_t status_t
CRadeonProducer::FormatProposal(const media_source &output, media_format *format) CRadeonProducer::FormatProposal(const media_source &output, media_format *format)
@@ -1373,7 +1383,7 @@ CRadeonProducer::startCapturing()
fOutput.destination == media_destination::null ) fOutput.destination == media_destination::null )
return; return;
fVideoIn.SetChannel(fTuner, C_VIDEO_IN_NTSC); fVideoIn.SetChannel(fTuner, C_VIDEO_IN_NTSC); // was hardcoded to NTSC
fVideoIn.SetBrightness(fBrightness); fVideoIn.SetBrightness(fBrightness);
fVideoIn.SetContrast(fContrast); fVideoIn.SetContrast(fContrast);
fVideoIn.SetSaturation(fSaturation); fVideoIn.SetSaturation(fSaturation);
@@ -1696,11 +1706,20 @@ CRadeonProducer::SetParameterValue(
return; return;
fSource = *((const uint32 *) value); fSource = *((const uint32 *) value);
fSourceLastChange = when; fSourceLastChange = when;
// if there is no tuner, force composite input
// (eXposer sets source manually to tuner, even if there is none)
// if there is no tuner, it isn't in the list and can't be picked!
//if( (fVideoIn.Capabilities() & C_VIDEO_IN_HAS_TUNER) == 0 )
// fSource = C_VIDEO_IN_COMPOSITE;
break; break;
case P_STANDARD: { case P_STANDARD: {
if (*((const int32 *) value) == fStandard) if (*((const int32 *) value) == fStandard)
return; return;
fStandard = *((const uint32 *) value);
fStandard = BeToVideoInStandard( *((const int32 *) value) );
fStandardLastChange = when; fStandardLastChange = when;
media_format new_format = fOutput.format; media_format new_format = fOutput.format;
@@ -1756,7 +1775,7 @@ CRadeonProducer::SetParameterValue(
return; return;
fTuner = *((const uint32 *) value); fTuner = *((const uint32 *) value);
fTunerLastChange = when; fTunerLastChange = when;
fVideoIn.SetChannel(fTuner, C_VIDEO_IN_NTSC); fVideoIn.SetChannel(fTuner, C_VIDEO_IN_NTSC); // was hardcoded to NTSC
break; break;
case P_BRIGHTNESS: case P_BRIGHTNESS:
if (*((const float *) value) == fBrightness) if (*((const float *) value) == fBrightness)
@@ -28,191 +28,190 @@ class CRadeonProducer :
public virtual BControllable public virtual BControllable
{ {
public: public:
CRadeonProducer( CRadeonProducer(CRadeonAddOn *addon, const char *name, const char *device_name,
CRadeonAddOn *addon, const char *name, const char *device_name, int32 internal_id, BMessage *config );
int32 internal_id, BMessage *config ); virtual ~CRadeonProducer();
virtual ~CRadeonProducer();
void setupWeb(); void setupWeb();
virtual status_t InitCheck() const { return fInitStatus; } virtual status_t InitCheck() const { return fInitStatus; }
/* BMediaNode */ /* BMediaNode */
public: public:
virtual port_id ControlPort() const; virtual port_id ControlPort() const;
virtual BMediaAddOn *AddOn(int32 * internal_id) const; virtual BMediaAddOn *AddOn(int32 * internal_id) const;
virtual status_t HandleMessage(int32 message, const void *data, virtual status_t HandleMessage(int32 message, const void *data,
size_t size); size_t size);
protected: protected:
virtual void Preroll(); virtual void Preroll();
virtual void SetTimeSource(BTimeSource * time_source); virtual void SetTimeSource(BTimeSource * time_source);
virtual status_t RequestCompleted(const media_request_info & info); virtual status_t RequestCompleted(const media_request_info & info);
/* BMediaEventLooper */ /* BMediaEventLooper */
protected: protected:
virtual void NodeRegistered(); virtual void NodeRegistered();
virtual void Start(bigtime_t performance_time); virtual void Start(bigtime_t performance_time);
virtual void Stop(bigtime_t performance_time, bool immediate); virtual void Stop(bigtime_t performance_time, bool immediate);
virtual void Seek(bigtime_t media_time, bigtime_t performance_time); virtual void Seek(bigtime_t media_time, bigtime_t performance_time);
virtual void TimeWarp(bigtime_t at_real_time, virtual void TimeWarp(bigtime_t at_real_time,
bigtime_t to_performance_time); bigtime_t to_performance_time);
virtual status_t AddTimer(bigtime_t at_performance_time, int32 cookie); virtual status_t AddTimer(bigtime_t at_performance_time, int32 cookie);
virtual void SetRunMode(run_mode mode); virtual void SetRunMode(run_mode mode);
virtual void HandleEvent(const media_timed_event *event, virtual void HandleEvent(const media_timed_event *event,
bigtime_t lateness, bool realTimeEvent = false); bigtime_t lateness, bool realTimeEvent = false);
virtual void CleanUpEvent(const media_timed_event *event); virtual void CleanUpEvent(const media_timed_event *event);
virtual bigtime_t OfflineTime(); virtual bigtime_t OfflineTime();
virtual void ControlLoop(); virtual void ControlLoop();
virtual status_t DeleteHook(BMediaNode * node); virtual status_t DeleteHook(BMediaNode * node);
/* BBufferProducer */ /* BBufferProducer */
protected: protected:
virtual status_t FormatSuggestionRequested(media_type type, int32 quality, virtual status_t FormatSuggestionRequested(media_type type, int32 quality,
media_format * format); media_format * format);
virtual status_t FormatProposal(const media_source &output, virtual status_t FormatProposal(const media_source &output,
media_format *format); media_format *format);
virtual status_t FormatChangeRequested(const media_source &source, virtual status_t FormatChangeRequested(const media_source &source,
const media_destination &destination, const media_destination &destination,
media_format *io_format, int32 *_deprecated_); media_format *io_format, int32 *_deprecated_);
virtual status_t GetNextOutput(int32 * cookie, media_output * out_output); virtual status_t GetNextOutput(int32 * cookie, media_output * out_output);
virtual status_t DisposeOutputCookie(int32 cookie); virtual status_t DisposeOutputCookie(int32 cookie);
virtual status_t SetBufferGroup(const media_source &for_source, virtual status_t SetBufferGroup(const media_source &for_source,
BBufferGroup * group); BBufferGroup * group);
virtual status_t VideoClippingChanged(const media_source &for_source, virtual status_t VideoClippingChanged(const media_source &for_source,
int16 num_shorts, int16 *clip_data, int16 num_shorts, int16 *clip_data,
const media_video_display_info &display, const media_video_display_info &display,
int32 * _deprecated_); int32 * _deprecated_);
virtual status_t GetLatency(bigtime_t * out_latency); virtual status_t GetLatency(bigtime_t * out_latency);
virtual status_t PrepareToConnect(const media_source &what, virtual status_t PrepareToConnect(const media_source &what,
const media_destination &where, const media_destination &where,
media_format *format, media_format *format,
media_source *out_source, char *out_name); media_source *out_source, char *out_name);
virtual void Connect(status_t error, const media_source &source, virtual void Connect(status_t error, const media_source &source,
const media_destination &destination, const media_destination &destination,
const media_format & format, char *io_name); const media_format & format, char *io_name);
virtual void Disconnect(const media_source & what, virtual void Disconnect(const media_source & what,
const media_destination & where); const media_destination & where);
virtual void LateNoticeReceived(const media_source & what, virtual void LateNoticeReceived(const media_source & what,
bigtime_t how_much, bigtime_t performance_time); bigtime_t how_much, bigtime_t performance_time);
virtual void EnableOutput(const media_source & what, bool enabled, virtual void EnableOutput(const media_source & what, bool enabled,
int32 * _deprecated_); int32 * _deprecated_);
virtual status_t SetPlayRate(int32 numer,int32 denom); virtual status_t SetPlayRate(int32 numer,int32 denom);
virtual void AdditionalBufferRequested(const media_source & source, virtual void AdditionalBufferRequested(const media_source & source,
media_buffer_id prev_buffer, bigtime_t prev_time, media_buffer_id prev_buffer, bigtime_t prev_time,
const media_seek_tag * prev_tag); const media_seek_tag * prev_tag);
virtual void LatencyChanged(const media_source & source, virtual void LatencyChanged(const media_source & source,
const media_destination & destination, const media_destination & destination,
bigtime_t new_latency, uint32 flags); bigtime_t new_latency, uint32 flags);
/* BControllable */ /* BControllable */
protected: protected:
virtual status_t GetParameterValue(int32 id, bigtime_t *last_change, virtual status_t GetParameterValue(int32 id, bigtime_t *last_change,
void *value, size_t *size); void *value, size_t *size);
virtual void SetParameterValue(int32 id, bigtime_t when, virtual void SetParameterValue(int32 id, bigtime_t when,
const void *value, size_t size); const void *value, size_t size);
virtual status_t StartControlPanel(BMessenger *out_messenger); virtual status_t StartControlPanel(BMessenger *out_messenger);
public: public:
enum { enum {
C_GET_CONFIGURATION = BTimedEventQueue::B_USER_EVENT, C_GET_CONFIGURATION = BTimedEventQueue::B_USER_EVENT,
C_GET_CONFIGURATION_REPLY C_GET_CONFIGURATION_REPLY
}; };
struct configuration_msg { struct configuration_msg {
port_id reply_port; port_id reply_port;
}; };
struct configuration_msg_reply { struct configuration_msg_reply {
status_t res; status_t res;
size_t config_size; size_t config_size;
char config; char config;
}; };
/* state */ /* state */
private: private:
void HandleStart(bigtime_t performance_time); void HandleStart(bigtime_t performance_time);
void HandleStop(); void HandleStop();
void HandleTimeWarp(bigtime_t performance_time); void HandleTimeWarp(bigtime_t performance_time);
void HandleSeek(bigtime_t performance_time); void HandleSeek(bigtime_t performance_time);
void HandleHardware(); void HandleHardware();
// home-brewed extension // home-brewed extension
status_t GetConfiguration( BMessage *out ); status_t GetConfiguration( BMessage *out );
CVideoIn fVideoIn; CVideoIn fVideoIn;
status_t fInitStatus; status_t fInitStatus;
int32 fInternalID; int32 fInternalID;
CRadeonAddOn *fAddOn; CRadeonAddOn *fAddOn;
BBufferGroup *fBufferGroup; BBufferGroup *fBufferGroup;
//BBufferGroup *fUsedBufferGroup; //BBufferGroup *fUsedBufferGroup;
static int32 _frame_generator_(void *data); static int32 _frame_generator_(void *data);
int32 FrameGenerator(); int32 FrameGenerator();
/* The remaining variables should be declared volatile, but they /* The remaining variables should be declared volatile, but they
* are not here to improve the legibility of the sample code. */ * are not here to improve the legibility of the sample code. */
//uint32 fFrame; //uint32 fFrame;
uint32 fFieldSequenceBase; uint32 fFieldSequenceBase;
//bigtime_t fPerformanceTimeBase; //bigtime_t fPerformanceTimeBase;
bigtime_t fProcessingLatency; bigtime_t fProcessingLatency;
media_output fOutput; media_output fOutput;
//media_raw_video_format fConnectedFormat; //media_raw_video_format fConnectedFormat;
//bool fConnected; //bool fConnected;
bool fEnabled; bool fEnabled;
// use fixed names as they are used in settings file // use fixed names as they are used in settings file
enum EOptions { enum EOptions {
P_SOURCE = 'VSRC', P_SOURCE = 'VSRC',
P_AUDIO_SOURCE = 'ASRC', P_AUDIO_SOURCE = 'ASRC',
P_AUDIO_FORMAT = 'AFMT', P_AUDIO_FORMAT = 'AFMT',
P_VOLUME = 'VOL ', P_VOLUME = 'VOL ',
P_STANDARD = 'TVST', P_STANDARD = 'TVST',
P_MODE = 'CMOD', P_MODE = 'CMOD',
P_FORMAT = 'VFMT', P_FORMAT = 'VFMT',
P_RESOLUTION = 'RES ', P_RESOLUTION = 'RES ',
P_TUNER = 'TUNR', P_TUNER = 'TUNR',
P_BRIGHTNESS = 'BRGT', P_BRIGHTNESS = 'BRGT',
P_CONTRAST = 'CONT', P_CONTRAST = 'CONT',
P_SATURATION = 'SATU', P_SATURATION = 'SATU',
P_HUE = 'HUE ', P_HUE = 'HUE ',
P_SHARPNESS = 'SHRP' P_SHARPNESS = 'SHRP'
}; };
enum { C_RESOLUTION_MAX = 6 };
enum { C_CHANNEL_MAX = 125 };
int32 fSource;
int32 fStandard;
int32 fMode;
int32 fCurMode; // mode, overwritten by application
int32 fFormat;
int32 fResolution;
int32 fTuner;
int32 fBrightness;
int32 fContrast;
int32 fSaturation;
int32 fHue;
int32 fSharpness;
bigtime_t fSourceLastChange;
bigtime_t fStandardLastChange;
bigtime_t fModeLastChange;
bigtime_t fFormatLastChange;
bigtime_t fResolutionLastChange;
bigtime_t fTunerLastChange;
bigtime_t fBrightnessLastChange;
bigtime_t fContrastLastChange;
bigtime_t fSaturationLastChange;
bigtime_t fHueLastChange;
bigtime_t fSharpnessLastChange;
status_t AddInt32(
BMessage *msg, EOptions option, int32 value );
enum { C_RESOLUTION_MAX = 6 }; status_t FindInt32(
enum { C_CHANNEL_MAX = 125 }; BMessage *config, EOptions option, int32 min_value, int32 max_value,
int32 default_value, int32 *value );
int32 fSource;
int32 fStandard;
int32 fMode;
int32 fCurMode; // mode, overwritten by application
int32 fFormat;
int32 fResolution;
int32 fTuner;
int32 fBrightness;
int32 fContrast;
int32 fSaturation;
int32 fHue;
int32 fSharpness;
bigtime_t fSourceLastChange;
bigtime_t fStandardLastChange;
bigtime_t fModeLastChange;
bigtime_t fFormatLastChange;
bigtime_t fResolutionLastChange;
bigtime_t fTunerLastChange;
bigtime_t fBrightnessLastChange;
bigtime_t fContrastLastChange;
bigtime_t fSaturationLastChange;
bigtime_t fHueLastChange;
bigtime_t fSharpnessLastChange;
status_t AddInt32(
BMessage *msg, EOptions option, int32 value );
status_t FindInt32(
BMessage *config, EOptions option, int32 min_value, int32 max_value,
int32 default_value, int32 *value );
// format negotiation helpers // format negotiation helpers
status_t verifySetMode( media_format *format ); status_t verifySetMode( media_format *format );
File diff suppressed because it is too large Load Diff
@@ -7,7 +7,6 @@
/ Copyright 2001, Carlos Hasan / Copyright 2001, Carlos Hasan
/ /
*******************************************************************************/ *******************************************************************************/
#ifndef __THEATER_H__ #ifndef __THEATER_H__
#define __THEATER_H__ #define __THEATER_H__
@@ -15,8 +14,9 @@
#include "VIPPort.h" #include "VIPPort.h"
enum theater_identifier { enum theater_identifier {
C_THEATER_VIP_VENDOR_ID = 0x1002, // C_THEATER_VIP_VENDOR_ID = 0x1002,
C_THEATER_VIP_DEVICE_ID = 0x4d54 C_THEATER100_VIP_DEVICE_ID = 0x4D541002,
C_THEATER200_VIP_DEVICE_ID = 0x4d4a1002
}; };
@@ -39,71 +39,43 @@ enum theater_source {
C_THEATER_SVIDEO = 2 C_THEATER_SVIDEO = 2
}; };
class CTheater { class CTheater {
public: public:
CTheater(CRadeon & radeon); CTheater(CRadeon & radeon, int device);
~CTheater(); virtual ~CTheater();
status_t InitCheck() const; virtual status_t InitCheck() const = 0;
void Reset(); virtual void Reset() = 0;
void SetEnable(bool enable, bool vbi); virtual void SetEnable(bool enable, bool vbi) = 0;
void SetStandard(theater_standard standard, theater_source source); virtual void SetStandard(theater_standard standard, theater_source source) = 0;
void SetSize(int hactive, int vactive); virtual void SetSize(int hactive, int vactive) = 0;
void SetDeinterlace(bool deinterlace); virtual void SetDeinterlace(bool deinterlace) = 0;
void SetSharpness(int sharpness); virtual void SetSharpness(int sharpness) = 0;
void SetBrightness(int brightness); virtual void SetBrightness(int brightness) = 0;
void SetContrast(int contrast); virtual void SetContrast(int contrast) = 0;
void SetSaturation(int saturation); virtual void SetSaturation(int saturation) = 0;
void SetHue(int hue); virtual void SetHue(int hue) = 0;
int CurrentLine(); virtual int CurrentLine() = 0;
void getActiveRange( theater_standard standard, CRadeonRect &rect ); virtual void getActiveRange( theater_standard standard, CRadeonRect &rect ) = 0;
void getVBIRange( theater_standard standard, CRadeonRect &rect ); virtual void getVBIRange( theater_standard standard, CRadeonRect &rect ) = 0;
void PrintToStream(); virtual void PrintToStream() = 0;
private: uint32 Capabilities() const;
void SetClock(theater_standard standard, radeon_video_clock clock);
void SetADC(theater_standard standard, theater_source source);
void SetHSYNC(theater_standard standard);
void WaitHSYNC();
void SetVSYNC(theater_standard standard);
void WaitVSYNC();
void SetSyncGenerator(theater_standard standard);
void SetCombFilter(theater_standard standard, theater_source source);
void SetLuminanceProcessor(theater_standard standard);
void SetLuminanceLevels(theater_standard standard, int brightness, int contrast);
void SetChromaProcessor(theater_standard standard);
void SetChromaLevels(theater_standard standard, int saturation, int hue);
void SetClipWindow(theater_standard standard, bool vbi);
void SetScaler(theater_standard standard, int hactive, int vactive, bool deinterlace);
public: public:
int Register(int index); int Register(int index);
@@ -114,7 +86,7 @@ public:
void SetRegister(int index, int mask, int value); void SetRegister(int index, int mask, int value);
private: protected:
CVIPPort fPort; CVIPPort fPort;
int fDevice; int fDevice;
radeon_video_clock fClock; radeon_video_clock fClock;
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,86 @@
/******************************************************************************
/
/ File: Theater.h
/
/ Description: ATI Rage Theater Video Decoder interface.
/
/ Copyright 2001, Carlos Hasan
/
*******************************************************************************/
#ifndef __THEATER100_H__
#define __THEATER100_H__
#include "Theater.h"
#include "Radeon.h"
#include "VIPPort.h"
class CTheater100 : public CTheater
{
public:
CTheater100(CRadeon & radeon, int device);
~CTheater100();
status_t InitCheck() const;
void Reset();
void SetEnable(bool enable, bool vbi);
void SetStandard(theater_standard standard, theater_source source);
void SetSize(int hactive, int vactive);
void SetDeinterlace(bool deinterlace);
void SetSharpness(int sharpness);
void SetBrightness(int brightness);
void SetContrast(int contrast);
void SetSaturation(int saturation);
void SetHue(int hue);
int CurrentLine();
void getActiveRange( theater_standard standard, CRadeonRect &rect );
void getVBIRange( theater_standard standard, CRadeonRect &rect );
void PrintToStream();
private:
void SetClock(theater_standard standard, radeon_video_clock clock);
void SetADC(theater_standard standard, theater_source source);
void SetHSYNC(theater_standard standard);
void WaitHSYNC();
void SetVSYNC(theater_standard standard);
void WaitVSYNC();
void SetSyncGenerator(theater_standard standard);
void SetCombFilter(theater_standard standard, theater_source source);
void SetLuminanceProcessor(theater_standard standard);
void SetLuminanceLevels(theater_standard standard, int brightness, int contrast);
void SetChromaProcessor(theater_standard standard);
void SetChromaLevels(theater_standard standard, int saturation, int hue);
void SetClipWindow(theater_standard standard, bool vbi);
void SetScaler(theater_standard standard, int hactive, int vactive, bool deinterlace);
};
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,147 @@
/******************************************************************************
/
/ File: Theater200.h
/
/ Description: ATI Rage Theater Video Decoder interface.
/
/ Based on code from X.org
/
*******************************************************************************/
#ifndef __THEATER200_H__
#define __THEATER200_H__
#include "Theater.h"
#include "Radeon.h"
#include "VIPPort.h"
enum theater200_state
{
MODE_UNINITIALIZED,
MODE_INITIALIZATION_IN_PROGRESS,
MODE_INITIALIZED_FOR_TV_IN
};
class CTheater200 : public CTheater {
public:
CTheater200(CRadeon & radeon, int device);
~CTheater200();
status_t InitCheck() const;
void Reset();
void SetEnable(bool enable, bool vbi);
void SetStandard(theater_standard standard, theater_source source);
void SetSize(int hactive, int vactive);
void SetDeinterlace(bool deinterlace);
void SetSharpness(int sharpness);
void SetBrightness(int brightness);
void SetContrast(int contrast);
void SetSaturation(int saturation);
void SetHue(int hue);
int CurrentLine();
// help no idea
void getActiveRange( theater_standard standard, CRadeonRect &rect );
// help no idea.
void getVBIRange( theater_standard standard, CRadeonRect &rect );
void PrintToStream();
private:
status_t DspInit();
status_t DspLoad( struct rt200_microc_data* microc_datap );
status_t DspGetMicrocode( char* micro_path,
char* micro_type,
struct rt200_microc_data* microc_datap );
status_t DSPLoadMicrocode( char* micro_path,
char* micro_type,
struct rt200_microc_data* microc_datap );
void DSPCleanMicrocode(struct rt200_microc_data* microc_datap);
status_t DspSendCommand( uint32 fb_scratch1, uint32 fb_scratch0 );
void InitTheatre();
int DSPDownloadMicrocode();
void ShutdownTheatre();
// in accelerant?
void ResetTheatreRegsForNoTVout();
void ResetTheatreRegsForTVout();
int32 DspSetVideostreamformat(int32 format);
int32 DspGetSignalLockStatus();
int32 DspAudioMute(int8 left, int8 right);
int32 DspSetAudioVolume(int8 left, int8 right, int8 auto_mute);
int32 DspConfigureI2SPort(int8 tx_mode, int8 rx_mode, int8 clk_mode);
int32 DspConfigureSpdifPort(int8 state);
// does nothing now
void SetClock(theater_standard standard, radeon_video_clock clock){;};
// source not correct values for PAL NTSC etc...
void SetADC(theater_standard standard, theater_source source);
// does nothing now
void SetHSYNC(theater_standard standard){;};
void WaitHSYNC();
// does nothing now
void SetVSYNC(theater_standard standard){;};
void WaitVSYNC();
// does nothing now
void SetSyncGenerator(theater_standard standard){;};
// does nothing now
void SetCombFilter(theater_standard standard, theater_source source){;};
// does nothing now
void SetLuminanceProcessor(theater_standard standard){;};
void SetLuminanceLevels(theater_standard standard, int brightness, int contrast);
// does nothing now
void SetChromaProcessor(theater_standard standard);
void SetChromaLevels(theater_standard standard, int saturation, int hue);
// does nothing now
void SetClipWindow(theater_standard standard, bool vbi);
// um, help
void SetScaler(theater_standard standard, int hactive, int vactive, bool deinterlace);
public:
int ReadFifo(uint32 address, uint8 *buffer);
int WriteFifo(uint32 address, uint32 count, uint8 *buffer);
private:
theater200_state fMode;
char* microcode_path;
char* microcode_type;
};
#endif
@@ -1229,7 +1229,132 @@ enum theater_register {
VIP_CRT_DTO_INCREMENTS = 0x0394, VIP_CRT_DTO_INCREMENTS = 0x0394,
VIP_VSYNC_DIFF_CNTL = 0x03a0, VIP_VSYNC_DIFF_CNTL = 0x03a0,
VIP_VSYNC_DIFF_LIMITS = 0x03a4, VIP_VSYNC_DIFF_LIMITS = 0x03a4,
VIP_VSYNC_DIFF_RD_DATA = 0x03a8 VIP_VSYNC_DIFF_RD_DATA = 0x03a8,
DSP_OK = 0x21,
DSP_INVALID_PARAMETER = 0x22,
DSP_MISSING_PARAMETER = 0x23,
DSP_UNKNOWN_COMMAND = 0x24,
DSP_UNSUCCESS = 0x25,
DSP_BUSY = 0x26,
DSP_RESET_REQUIRED = 0x27,
DSP_UNKNOWN_RESULT = 0x28,
DSP_CRC_ERROR = 0x29,
DSP_AUDIO_GAIN_ADJ_FAIL = 0x2a,
DSP_AUDIO_GAIN_CHK_ERROR = 0x2b,
DSP_WARNING = 0x2c,
DSP_POWERDOWN_MODE = 0x2d,
RT200_NTSC_M = 0x01,
RT200_NTSC_433 = 0x03,
RT200_NTSC_J = 0x04,
RT200_PAL_B = 0x05,
RT200_PAL_D = 0x06,
RT200_PAL_G = 0x07,
RT200_PAL_H = 0x08,
RT200_PAL_I = 0x09,
RT200_PAL_N = 0x0a,
RT200_PAL_Ncomb = 0x0b,
RT200_PAL_M = 0x0c,
RT200_PAL_60 = 0x0d,
RT200_SECAM = 0x0e,
RT200_SECAM_B = 0x0f,
RT200_SECAM_D = 0x10,
RT200_SECAM_G = 0x11,
RT200_SECAM_H = 0x12,
RT200_SECAM_K = 0x13,
RT200_SECAM_K1 = 0x14,
RT200_SECAM_L = 0x15,
RT200_SECAM_L1 = 0x16,
RT200_480i = 0x17,
RT200_480p = 0x18,
RT200_576i = 0x19,
RT200_720p = 0x1a,
RT200_1080i = 0x1b
};
/* RT200 stuff there's no way I'm converting these to enums...*/
/* RT200 */
#define VIP_INT_CNTL__FB_INT0 0x02000000
#define VIP_INT_CNTL__FB_INT0_CLR 0x02000000
#define VIP_GPIO_INOUT 0x0030
#define VIP_GPIO_CNTL 0x0034
#define VIP_CLKOUT_GPIO_CNTL 0x0038
#define VIP_RIPINTF_PORT_CNTL 0x003c
/* RT200 */
#define VIP_GPIO_INOUT 0x0030
#define VIP_GPIO_CNTL 0x0034
#define VIP_HOSTINTF_PORT_CNTL 0x003c
#define VIP_HOSTINTF_PORT_CNTL__HAD_HCTL_SDA_SN 0x00000008
#define VIP_HOSTINTF_PORT_CNTL__HAD_HCTL_SDA_SP 0x00000080
#define VIP_HOSTINTF_PORT_CNTL__HAD_HCTL_SDA_SR 0x00000100
#define VIP_HOSTINTF_PORT_CNTL__SUB_SYS_ID_EN 0x00010000
#define VIP_HOSTINTF_PORT_CNTL__FIFO_RW_MODE 0x00300000
#define VIP_HOSTINTF_PORT_CNTL__FIFOA_ENDIAN_SWAP 0x00c00000
#define VIP_HOSTINTF_PORT_CNTL__FIFOB_ENDIAN_SWAP 0x03000000
#define VIP_HOSTINTF_PORT_CNTL__FIFOC_ENDIAN_SWAP 0x0c000000
#define VIP_HOSTINTF_PORT_CNTL__FIFOD_ENDIAN_SWAP 0x30000000
#define VIP_HOSTINTF_PORT_CNTL__FIFOE_ENDIAN_SWAP 0xc0000000
/* RT200 */
#define VIP_DSP_PLL_CNTL 0x0bc
/* RT200 */
#define VIP_TC_SOURCE 0x300
#define VIP_TC_DESTINATION 0x304
#define VIP_TC_COMMAND 0x308
/* RT200 */
#define VIP_TC_STATUS 0x030c
#define VIP_TC_STATUS__TC_CHAN_BUSY 0x00007fff
#define VIP_TC_STATUS__TC_WRITE_PENDING 0x00008000
#define VIP_TC_STATUS__TC_FIFO_4_EMPTY 0x00040000
#define VIP_TC_STATUS__TC_FIFO_6_EMPTY 0x00080000
#define VIP_TC_STATUS__TC_FIFO_8_EMPTY 0x00100000
#define VIP_TC_STATUS__TC_FIFO_10_EMPTY 0x00200000
#define VIP_TC_STATUS__TC_FIFO_4_FULL 0x04000000
#define VIP_TC_STATUS__TC_FIFO_6_FULL 0x08080000
#define VIP_TC_STATUS__TC_FIFO_8_FULL 0x10080000
#define VIP_TC_STATUS__TC_FIFO_10_FULL 0x20080000
#define VIP_TC_STATUS__DSP_ILLEGAL_OP 0x80080000
/* RT200 */
#define VIP_TC_DOWNLOAD 0x0310
#define VIP_TC_DOWNLOAD__TC_DONE_MASK 0x00003fff
#define VIP_TC_DOWNLOAD__TC_RESET_MODE 0x00060000
/* RT200 */
#define VIP_FB_INT 0x0314
#define VIP_FB_INT__INT_7 0x00000080
#define VIP_FB_SCRATCH0 0x0318
#define VIP_FB_SCRATCH1 0x031c
struct rt200_microc_head
{
unsigned int device_id;
unsigned int vendor_id;
unsigned int revision_id;
unsigned int num_seg;
};
struct rt200_microc_seg
{
unsigned int num_bytes;
unsigned int download_dst;
unsigned int crc_val;
unsigned char* data;
struct rt200_microc_seg* next;
};
struct rt200_microc_data
{
struct rt200_microc_head microc_head;
struct rt200_microc_seg* microc_seg_list;
}; };
#endif #endif
@@ -58,6 +58,14 @@ public:
fRadeon.SetVIPRegister( device, address, value ); fRadeon.SetVIPRegister( device, address, value );
} }
int ReadFifo(int device, uint32 address, uint32 count, uint8 *buffer) {
return fRadeon.VIPReadFifo( device, address, count, buffer );
}
int WriteFifo(int device, uint32 address, uint32 count, uint8 *buffer) {
return fRadeon.VIPWriteFifo( device, address, count, buffer );
}
int FindVIPDevice( uint32 device_id ) { int FindVIPDevice( uint32 device_id ) {
return fRadeon.FindVIPDevice( device_id ); return fRadeon.FindVIPDevice( device_id );
} }
@@ -64,13 +64,14 @@ static const struct {
{ { 910, 525 }, { 112, 37, 755, 480 }, { 73, 13, 798, 22 } } // NTSC-Raw { { 910, 525 }, { 112, 37, 755, 480 }, { 73, 13, 798, 22 } } // NTSC-Raw
}; };
class CTheater100;
class CTheater200;
CVideoIn::CVideoIn( const char *dev_name ) CVideoIn::CVideoIn( const char *dev_name )
: fRadeon( dev_name ), : fRadeon( dev_name ),
fCapture(fRadeon), fCapture(fRadeon),
fI2CPort(fRadeon), fI2CPort(fRadeon),
fTheater(fRadeon), fTheater(NULL),
fTuner(fI2CPort), fTuner(fI2CPort),
fSound(fI2CPort), fSound(fI2CPort),
fBuffer0(0), fBuffer0(0),
@@ -84,7 +85,9 @@ CVideoIn::CVideoIn( const char *dev_name )
fBufferPeriod(0), fBufferPeriod(0),
started( false ) started( false )
{ {
Trace("CVideoIn::CVideoIn()"); Trace("CVideoIn::CVideoIn()");
} }
CVideoIn::~CVideoIn() CVideoIn::~CVideoIn()
@@ -94,12 +97,12 @@ CVideoIn::~CVideoIn()
FreeBuffers(); FreeBuffers();
} }
status_t CVideoIn::InitCheck() const status_t CVideoIn::InitCheck()
{ {
status_t res; status_t res;
int device;
Trace("CVideoIn::InitCheck()"); Trace("CVideoIn::InitCheck()");
if( (res = fRadeon.InitCheck()) != B_OK ) if( (res = fRadeon.InitCheck()) != B_OK )
return res; return res;
@@ -109,12 +112,35 @@ status_t CVideoIn::InitCheck() const
if( (res = fI2CPort.InitCheck()) != B_OK ) if( (res = fI2CPort.InitCheck()) != B_OK )
return res; return res;
return fTheater.InitCheck(); //debugger("init");
// detect type of theatre and initialise specific theater class
if ((device = fRadeon.FindVIPDevice( C_THEATER100_VIP_DEVICE_ID )) != -1)
{
Trace("CVideoIn::Found Rage Theater 100");
fTheater = new CTheater100(fRadeon, device);
}
else if ((device = fRadeon.FindVIPDevice( C_THEATER200_VIP_DEVICE_ID )) != -1)
{
Trace("CVideoIn::Found Rage Theater 200");
fTheater = new CTheater200(fRadeon, device);
}
if (fTheater)
{
res = fTheater->InitCheck();
}
else
{
res = B_ERROR;
}
return res;
} }
int CVideoIn::Capabilities() const int CVideoIn::Capabilities() const
{ {
return (fTuner.InitCheck() == B_OK ? C_VIDEO_IN_HAS_TUNER + C_VIDEO_IN_HAS_COMPOSITE + C_VIDEO_IN_HAS_SVIDEO : 0) + return fTheater->Capabilities() +
(fTuner.InitCheck() == B_OK ? C_VIDEO_IN_HAS_TUNER : 0) +
(fSound.InitCheck() == B_OK ? C_VIDEO_IN_HAS_SOUND : 0); (fSound.InitCheck() == B_OK ? C_VIDEO_IN_HAS_SOUND : 0);
} }
@@ -166,13 +192,13 @@ void CVideoIn::Start(video_in_source source, video_in_standard standard,
if( mode == C_VIDEO_IN_BOB ) if( mode == C_VIDEO_IN_BOB )
fBufferPeriod >>= 1; fBufferPeriod >>= 1;
fTheater.SetStandard(kStandard[standard], kSource[source]); fTheater->SetStandard(kStandard[standard], kSource[source]);
fTheater.SetSize(width, (mode != C_VIDEO_IN_WEAVE ? 2 * height : height)); fTheater->SetSize(width, (mode != C_VIDEO_IN_WEAVE ? 2 * height : height));
fCapture.SetBuffer(C_RADEON_CAPTURE_CCIR656, kMode[mode], fBuffer0, fBuffer1, fBufferLength, fBufferBytesPerRow >> 1); fCapture.SetBuffer(C_RADEON_CAPTURE_CCIR656, kMode[mode], fBuffer0, fBuffer1, fBufferLength, fBufferBytesPerRow >> 1);
fCapture.SetClip(0, kTiming[standard].vbi.height, width - 1, kTiming[standard].vbi.height + (mode != C_VIDEO_IN_WEAVE ? height : height >> 1) - 1); fCapture.SetClip(0, kTiming[standard].vbi.height, width - 1, kTiming[standard].vbi.height + (mode != C_VIDEO_IN_WEAVE ? height : height >> 1) - 1);
fTheater.SetEnable(true, false); fTheater->SetEnable(true, false);
if( fSound.InitCheck() == B_OK ) if( fSound.InitCheck() == B_OK )
fSound.SetEnable(true); fSound.SetEnable(true);
fCapture.SetInterrupts(true); fCapture.SetInterrupts(true);
@@ -190,7 +216,7 @@ void CVideoIn::Stop()
fCapture.SetInterrupts(false); fCapture.SetInterrupts(false);
if( fSound.InitCheck() == B_OK ) if( fSound.InitCheck() == B_OK )
fSound.SetEnable(false); fSound.SetEnable(false);
fTheater.SetEnable(false, false); fTheater->SetEnable(false, false);
FreeBuffers(); FreeBuffers();
} }
@@ -217,35 +243,35 @@ void CVideoIn::SetBrightness(int brightness)
{ {
Trace("CVideoIn::SetBrightness()"); Trace("CVideoIn::SetBrightness()");
fTheater.SetBrightness(brightness); fTheater->SetBrightness(brightness);
} }
void CVideoIn::SetContrast(int contrast) void CVideoIn::SetContrast(int contrast)
{ {
Trace("CVideoIn::SetContrast()"); Trace("CVideoIn::SetContrast()");
fTheater.SetContrast(contrast); fTheater->SetContrast(contrast);
} }
void CVideoIn::SetSaturation(int saturation) void CVideoIn::SetSaturation(int saturation)
{ {
Trace("CVideoIn::SetSaturation()"); Trace("CVideoIn::SetSaturation()");
fTheater.SetSaturation(saturation); fTheater->SetSaturation(saturation);
} }
void CVideoIn::SetHue(int hue) void CVideoIn::SetHue(int hue)
{ {
Trace("CVideoIn::SetHue()"); Trace("CVideoIn::SetHue()");
fTheater.SetHue(hue); fTheater->SetHue(hue);
} }
void CVideoIn::SetSharpness(int sharpness) void CVideoIn::SetSharpness(int sharpness)
{ {
Trace("CVideoIn::SetSharpness()"); Trace("CVideoIn::SetSharpness()");
fTheater.SetSharpness(sharpness); fTheater->SetSharpness(sharpness);
} }
void CVideoIn::SetFrequency(float frequency, float picture) void CVideoIn::SetFrequency(float frequency, float picture)
@@ -360,12 +386,10 @@ int CVideoIn::Capture(color_space colorSpace, void * bits, int bitsLength,
// always copy into main memory first, even if it must be converted by CPU - // always copy into main memory first, even if it must be converted by CPU -
// reading from graphics mem is incredibly slow // reading from graphics mem is incredibly slow
if (colorSpace == B_YCbCr422 && bitsLength <= fBufferLength && bytesPerRow == fBufferBytesPerRow) { if (colorSpace == B_YCbCr422 && bitsLength <= fBufferLength && bytesPerRow == fBufferBytesPerRow) {
PRINT(("%d, %p\n", captured_buffer, bits));
fRadeon.DMACopy( captured_buffer, bits, bitsLength, true, false ); fRadeon.DMACopy( captured_buffer, bits, bitsLength, true, false );
} }
else if (colorSpace == B_RGB32 && bitsLength <= 2 * fBufferLength && bytesPerRow == 2 * fBufferBytesPerRow) {
else if (colorSpace == B_RGB32 && bitsLength <= 2 * fBufferLength && bytesPerRow == 2 * fBufferBytesPerRow) {
fRadeon.DMACopy( captured_buffer, convert_buffer, fBufferLength, true, false ); fRadeon.DMACopy( captured_buffer, convert_buffer, fBufferLength, true, false );
#define RGB32 #define RGB32
@@ -373,6 +397,7 @@ int CVideoIn::Capture(color_space colorSpace, void * bits, int bitsLength,
#undef RGB32 #undef RGB32
} }
else if (colorSpace == B_RGB16 && bitsLength <= fBufferLength && bytesPerRow == fBufferBytesPerRow) { else if (colorSpace == B_RGB16 && bitsLength <= fBufferLength && bytesPerRow == fBufferBytesPerRow) {
fRadeon.DMACopy( captured_buffer, convert_buffer, fBufferLength, true, false ); fRadeon.DMACopy( captured_buffer, convert_buffer, fBufferLength, true, false );
@@ -381,6 +406,7 @@ int CVideoIn::Capture(color_space colorSpace, void * bits, int bitsLength,
#undef RGB16 #undef RGB16
} }
else if (colorSpace == B_RGB15 && bitsLength <= fBufferLength && bytesPerRow == fBufferBytesPerRow) { else if (colorSpace == B_RGB15 && bitsLength <= fBufferLength && bytesPerRow == fBufferBytesPerRow) {
fRadeon.DMACopy( captured_buffer, convert_buffer, fBufferLength, true, false ); fRadeon.DMACopy( captured_buffer, convert_buffer, fBufferLength, true, false );
@@ -19,6 +19,8 @@
#include "Tuner.h" #include "Tuner.h"
#include "MSP3430.h" #include "MSP3430.h"
#include "Theater.h" #include "Theater.h"
#include "Theater100.h"
#include "Theater200.h"
enum video_in_source { enum video_in_source {
C_VIDEO_IN_TUNER, C_VIDEO_IN_TUNER,
@@ -83,7 +85,7 @@ public:
~CVideoIn(); ~CVideoIn();
status_t InitCheck() const; status_t InitCheck();
int Capabilities() const; int Capabilities() const;
@@ -126,7 +128,7 @@ private:
CRadeon fRadeon; CRadeon fRadeon;
CCapture fCapture; CCapture fCapture;
CI2CPort fI2CPort; CI2CPort fI2CPort;
CTheater fTheater; CTheater* fTheater;
CTuner fTuner; CTuner fTuner;
CMSP3430 fSound; CMSP3430 fSound;
int32 fBuffer0; int32 fBuffer0;
@@ -172,6 +172,6 @@
"jg 2b\n" "jg 2b\n"
"emms\n" "emms\n"
: :
: "a" (convert_buffer), "d" (bits), : "a" (convert_buffer), "d" (bits),
"g" (c_offs), "g" (y_offs), "g" (masks), "g" (scale), "g" (masks_8bit), "g" (c_offs), "g" (y_offs), "g" (masks), "g" (scale), "g" (masks_8bit),
"c" (bytesPerRow), "S" (bitsLength), "D" (bytesPerRow)); "c" (bytesPerRow), "S" (bitsLength), "D" (bytesPerRow));