added more brooktree/conexant modesetting stuff. still not in use.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@14284 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Rudolf Cornelissen
2005-09-30 18:21:19 +00:00
parent 633dee064e
commit 21f6ecabcb
@@ -12,6 +12,24 @@
#define WR 0x00
#define RD 0x01
//fixme: remove rubbish..
enum
{ // TVoutput mode to set
NOT_USED = 0,
NTSC640_TST,
NTSC640,
NTSC800,
PAL800_TST,
PAL640,
PAL800,
VGA,
EXIT,
NTSC720,
PAL720,
NTSC640_OS,
PAL800_OS
};
/*
see if a (possible) BT/CX chip resides at the given adress.
Return zero if no errors occurred.
@@ -746,6 +764,377 @@ static uint8 BT_init_NTSC640_OS()
return stat;
}//end BT_init_NTSC640_OS.
static uint8 BT_testsignal (void)
{
uint8 stat;
uint8 buffer[3];
buffer[0] = si->ps.tv_encoder.adress + WR;
/* select bt register for enabling colorbars and outputs */
buffer[1] = 0xc4;
/* issue the actual command */
buffer[2] = 0x05;
/* reset status */
i2c_flag_error (-1);
i2c_bstart(si->ps.tv_encoder.bus);
i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
i2c_bstop(si->ps.tv_encoder.bus);
/* log on errors */
stat = i2c_flag_error(0);
if (stat)
LOG(4,("Brooktree: I2C errors occurred while setting up flickerfilter and outputs\n"));
return stat;
}//end BT_testsignal.
static uint8 BT_setup_output(uint8 monstat, uint8 output, uint8 ffilter)
{
uint8 stat;
uint8 buffer[7];
buffer[0] = si->ps.tv_encoder.adress + WR;
/* select first TV config register to write */
buffer[1] = 0xc6;
/* input is 24bit mpx'd RGB, BLANK = out, sync = act. hi */
buffer[2] = 0x98;
/* disable all filters, exept flicker filter */
buffer[3] = 0x98;
if (!ffilter)
{
/* disable flicker filter */
buffer[3] = 0xc0;
}
/* (disable filters) */
buffer[4] = 0xc0;
/* (disable filters) */
buffer[5] = 0xc0;
switch (output)
/* Description of ELSA Erazor III hardware layout:
* (This is the default (recommended) layout by NVIDIA)
* DAC A = CVBS
* DAC B = C (chrominance)
* DAC C = Y (luminance) */
/* Description of Diamond VIPER550:
* DAC A = Not connected
* DAC B = C (chrominance)
* DAC C = Y (luminance)
* To be able to connect to CVBS TV's a special cable is supplied:
* This cable connects the Y (DAC C) output to the TV CVBS input. */
{
case 1: buffer[6] = 0x18; // Y/C and CVBS out if all ports implemented
// in hardware, else only Y/C or CVBS out.
break;
case 2: buffer[6] = 0x00; // put CVBS on all outputs. Used for cards
break; // with only Y/C out and 'translation cable'.
default:switch (monstat) // only 'autodetect' remains...
{
case 1: buffer[6] = 0x00; //only Y connected: must be CVBS!
break;
case 2: buffer[6] = 0x00; //only C connected: must be CVBS!
break; //(though cable is wired wrong...)
case 5: buffer[6] = 0x00; //CVBS and only Y connected: 2x CVBS!
break; //(officially not supported...)
case 6: buffer[6] = 0x00; //CVBS and only C connected: 2x CVBS!
break; //(officially not supported...)
default:buffer[6] = 0x18; //nothing, or
//Y/C only, or
//CVBS only (but on CVBS output), or
//Y/C and CVBS connected:
//So activate recommended signals.
}
}
/* reset status */
i2c_flag_error (-1);
i2c_bstart(si->ps.tv_encoder.bus);
i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
i2c_bstop(si->ps.tv_encoder.bus);
/* log on errors */
stat = i2c_flag_error(0);
if (stat)
LOG(4,("Brooktree: I2C errors occurred while setting up flickerfilter and outputs\n"));
return stat;
}//end BT_setup_output.
static uint8 BT_setup_hphase(uint8 mode)
{
uint8 stat, hoffset;
uint8 buffer[7];
/* CX needs timing reset (advised on BT also), first 1mS delay needed! */
snooze(1000);
/* values below are all tested on TNT1, TNT2 and GeForce2MX */
buffer[0] = si->ps.tv_encoder.adress + WR;
/* select first TV output timing register to write */
buffer[1] = 0x6c;
/* turn on active video & generate timing reset on CX chips! */
buffer[2] = 0x86;
/* (set fail save values...) */
buffer[3] = 0x00; //set default horizontal sync offset
buffer[4] = 0x02; //set default horizontal sync width
buffer[5] = 0x00; //set default vertical sync offset
/* do specific timing setup for all chips and modes: */
hoffset = 8; //TNT2 and TNT2 M64...(8 pixels delayed hpos,
//so picture more to the right)
//fixme: check this out...
// if (ddata->type == 1) hoffset = 0; //TNT1 or GeForce2... (std hpos)
//NOTE: It might be that GeForce needs TNT2 offset:
//for now CX chips get seperate extra offset, until sure.
//(CX is only found AFAIK on GeForce cards, no BT tested
// on GeForce yet. CH was tested on GeForce and seemed to
// indicate TNT1 offset was needed.)
switch (mode)
{
case NTSC640_TST:
case NTSC640:
if (si->ps.tv_encoder.type >= CX25870) hoffset +=8; //if CX shift picture right some more...
buffer[3] = (0x25 + hoffset); //set horizontal sync offset
break;
case NTSC800:
if (si->ps.tv_encoder.type >= CX25870) hoffset +=8; //if CX shift picture right some more...
buffer[3] = (0xe1 + hoffset); //set horizontal sync offset
buffer[4] = 0xc2;
//Vsync offset reg. does not exist on CX: mode is checked and OK.
buffer[5] = 0x40; //set VSync offset (on BT's only)
break;
case PAL640:
if (si->ps.tv_encoder.type >= CX25870) hoffset +=8; //if CX shift picture right some more...
buffer[3] = (0xa8 + hoffset);
break;
case PAL800_TST:
case PAL800:
if (si->ps.tv_encoder.type >= CX25870) hoffset +=8; //if CX shift picture right some more...
buffer[3] = (0x2c + hoffset);
break;
case NTSC720:
if (si->ps.tv_encoder.type >= CX25870)
buffer[3] = (0xb2 + hoffset); //set horizontal sync offset CX
else
buffer[3] = (0xd0 + hoffset); //set horizontal sync offset BT
buffer[4] = 0xff; //hsync width = max:
break; //to prevent vertical image 'shivering'.
case PAL720:
buffer[3] = (0xd4 + hoffset);
buffer[4] = 0xff;
break;
case NTSC640_OS:
buffer[3] = (0xc8 + hoffset);
buffer[4] = 0xff;
break;
case PAL800_OS:
if (si->ps.tv_encoder.type >= CX25870)
buffer[3] = (0x78 + hoffset); //set horizontal sync offset CX
else
buffer[3] = (0xc4 + hoffset); //set horizontal sync offset BT
buffer[4] = 0xff;
break;
default: //nothing to be done here...
break;
}
buffer[6] = 0x01; //set default vertical sync width
/* reset status */
i2c_flag_error (-1);
i2c_bstart(si->ps.tv_encoder.bus);
i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
i2c_bstop(si->ps.tv_encoder.bus);
/* log on errors */
stat = i2c_flag_error(0);
if (stat)
LOG(4,("Brooktree: I2C errors occurred while setting up h_phase\n"));
return stat;
}//end BT_setup_hphase.
static uint8 BT_read_monstat(uint8* monstat)
{
uint8 stat;
uint8 buffer[3];
/* set BT to return connection status in ESTATUS on next read CMD: */
buffer[0] = si->ps.tv_encoder.adress + WR;
/* set ESTATUS at b'01' (return conn.stat.) */
buffer[1] = 0xc4;
/* and leave chip outputs on. */
buffer[2] = 0x41;
/* reset status */
i2c_flag_error (-1);
i2c_bstart(si->ps.tv_encoder.bus);
i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
i2c_bstop(si->ps.tv_encoder.bus);
/* log on errors */
stat = i2c_flag_error(0);
if (stat)
{
LOG(4,("Brooktree: I2C errors occurred while reading connection status (1)\n"));
return stat;
}
/* do actual read connection status: */
buffer[0] = si->ps.tv_encoder.adress + WR;
/* select register with CHECK_STAT CMD */
buffer[1] = 0xba;
/* issue actual command. */
buffer[2] = 0x40;
i2c_bstart(si->ps.tv_encoder.bus);
i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
i2c_bstop(si->ps.tv_encoder.bus);
/* log on errors */
stat = i2c_flag_error(0);
if (stat)
{
LOG(4,("Brooktree: I2C errors occurred while reading connection status (2)\n"));
return stat;
}
/* CX: Wait 600uS for signals to stabilize (see datasheet) */
/* warning, note:
* datasheet is in error! 60mS needed!! */
snooze(60000);
/* read back updated connection status: */
buffer[0] = si->ps.tv_encoder.adress + RD;
/* transmit 1 byte */
i2c_bstart(si->ps.tv_encoder.bus);
i2c_writebuffer(si->ps.tv_encoder.bus, buffer, 1);
/* receive 1 byte */
/* ACK level to TX after last byte to RX should be 1 (= NACK) (see IIC spec)
* While the BT's don't care, CX chips will block the SDA line if an ACK gets sent! */
buffer[0] = 1;
i2c_readbuffer(si->ps.tv_encoder.bus, buffer, 1);
i2c_bstop(si->ps.tv_encoder.bus);
/* log on errors */
stat = i2c_flag_error(0);
if (stat)
{
LOG(4,("Brooktree: I2C errors occurred while reading connection status (3)\n"));
return stat;
}
*monstat = ((buffer[0] & 0xe0) >> 5);
LOG(4,("Brooktree: TV output monitor status = %d\n", *monstat));
/* instruct BT to go back to normal operation: */
buffer[0] = si->ps.tv_encoder.adress + WR;
/* select register with CHECK_STAT CMD */
buffer[1] = 0xba;
/* issue actual command. */
buffer[2] = 0x00;
i2c_bstart(si->ps.tv_encoder.bus);
i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
i2c_bstop(si->ps.tv_encoder.bus);
/* log on errors */
stat = i2c_flag_error(0);
if (stat)
{
LOG(4,("Brooktree: I2C errors occurred while reading connection status (4)\n"));
return stat;
}
return stat;
}//end BT_read_monstat.
static uint8 BT_killclk_blackout(void)
{
uint8 stat;
uint8 buffer[4];
/* reset status */
i2c_flag_error (-1);
if (si->ps.tv_encoder.type <= BT869) //BT...
{
/* Only disable external pixelclock input on BT's.
* CX chips will lock the bus if you do this.
* (It looks like the external pixelclock is always OK as long as a valid
* mode is programmed for the TVout chip. This means that disabling the use
* of this clock is not needed anyway.
* If you do disable this input, this pixelclock will rise to about 60Mhz BTW..) */
/* disable use of external pixelclock source... */
/* (should prevent BT for being 'overclocked' by RIVA in VGA-only mode...) */
buffer[0] = si->ps.tv_encoder.adress + WR;
/* select BT register for setting EN_XCLK */
buffer[1] = 0xa0;
/* clear it */
buffer[2] = 0x00;
i2c_bstart(si->ps.tv_encoder.bus);
i2c_writebuffer(si->ps.tv_encoder.bus, buffer, 3);
i2c_bstop(si->ps.tv_encoder.bus);
/* log on errors */
stat = i2c_flag_error(0);
if (stat)
{
LOG(4,("Brooktree: I2C errors occurred while doing killclk_blackout (1-BT)\n"));
return stat;
}
}
else //CX...
{
/* Disable CX video out (or wild output will be seen on TV..) */
buffer[0] = si->ps.tv_encoder.adress + WR;
/* select register in CX */
buffer[1] = 0x6c;
/* disable active video out. */
buffer[2] = 0x02;
i2c_bstart(si->ps.tv_encoder.bus);
i2c_writebuffer(si->ps.tv_encoder.bus, buffer, 3);
i2c_bstop(si->ps.tv_encoder.bus);
/* log on errors */
stat = i2c_flag_error(0);
if (stat)
{
LOG(4,("Brooktree: I2C errors occurred while doing killclk_blackout (1-CX)\n"));
return stat;
}
}
/* black-out TVout while outputs are enabled... */
buffer[0] = si->ps.tv_encoder.adress + WR;
/* select first TV config register to write */
buffer[1] = 0xc4;
/* disable testimage while outputs remain enabled */
buffer[2] = 0x01;
/* input is 24bit mpx'd RGB, BLANK = in, sync = act. hi */
buffer[3] = 0x18;
i2c_bstart(si->ps.tv_encoder.bus);
i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
i2c_bstop(si->ps.tv_encoder.bus);
/* log on errors */
stat = i2c_flag_error(0);
if (stat)
{
LOG(4,("Brooktree: I2C errors occurred while doing killclk_blackout (2)\n"));
return stat;
}
return stat;
}//end BT_killclk_blackout.
//fixme: resetup for brooktreetv, should cover all supported encoders later on..
int maventv_init(display_mode target)
{