added brooktree (BT) and conexant (CX) TV encoder recognition, as far as was supported in BeTVOut (BT868/869, CX25870/25871). Tested OK on TNT1 with BT869 on secondary adres, primary bus.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@14252 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Rudolf Cornelissen 2005-09-27 14:18:46 +00:00
parent 170a41cdcb
commit 12566cbd0d
5 changed files with 198 additions and 81 deletions

View File

@ -1,14 +1,166 @@
/* Authors:
Mark Watson 2000,
Rudolf Cornelissen 1/2003-12/2003
Thanx to Petr Vandrovec for writing matroxfb.
/*
Author:
Rudolf Cornelissen 4/2002-9/2005
*/
#define MODULE_BIT 0x00100000
#include "nv_std.h"
#define PRADR 0x88
#define SCADR 0x8a
#define WR 0x00
#define RD 0x01
/*
see if a (possible) BT/CX chip resides at the given adress.
Return zero if no errors occurred.
*/
static uint8 BT_check (uint8 bus, uint8 adress)
{
/* reset status */
i2c_flag_error (-1);
/* do check */
i2c_bstart(bus);
i2c_writebyte(bus, adress + WR);
/* set ESTATUS at b'00'; and enable bt chip-outputs
* WARNING:
* If bit0 = 0 is issued below (EN_OUT = disabled), the BT will lock SDA
* after writing adress $A0 (setting EN_XCLK)!!!
* Until a reboot the corresponding IIC bus will be inacessable then!!! */
i2c_writebyte(bus, 0xc4);
/* fixme: if testimage 'was' active txbuffer[3] should become 0x05...
* (currently this cannot be detected in a 'foolproof' way so don't touch...) */
/* (ESTATUS b'0x' means: RX ID and VERSION info later..) */
i2c_writebyte(bus, 0x01);
i2c_bstop(bus);
return i2c_flag_error(0);
}
/* identify chiptype */
static uint8 BT_read_type (void)
{
uint8 id, stat;
/* reset status */
i2c_flag_error (-1);
//fixme: setup higher level static I2C routines in this file.
/* Make sure a CX (Conexant) chip (if this turns out to be there) is set to
* BT-compatibility mode! (This command will do nothing on a BT chip...) */
i2c_bstart(si->ps.tv_encoder.bus);
i2c_writebyte(si->ps.tv_encoder.bus, si->ps.tv_encoder.adress + WR);
/* select CX reg. for BT-compatible readback, video still off */
i2c_writebyte(si->ps.tv_encoder.bus, 0x6c);
/* set it up */
i2c_writebyte(si->ps.tv_encoder.bus, 0x02);
i2c_bstop(si->ps.tv_encoder.bus);
/* abort on errors */
stat = i2c_flag_error(0);
if (stat) return stat;
/* Do actual readtype command */
i2c_bstart(si->ps.tv_encoder.bus);
/* issue IIC read command */
i2c_writebyte(si->ps.tv_encoder.bus, si->ps.tv_encoder.adress + RD);
/* receive 1 byte;
* ACK level to TX after last byte to RX should be 1 (= NACK) (see IIC spec). */
/* note:
* While the BT's don't care, CX chips will block the SDA line if
* an ACK gets sent! */
id = i2c_readbyte(si->ps.tv_encoder.bus, true);
i2c_bstop(si->ps.tv_encoder.bus);
/* abort on errors */
stat = i2c_flag_error(0);
if (stat) return stat;
/* inform driver about TV encoder found */
si->ps.tvout = true;
si->ps.tv_encoder.type = BT868 + ((id & 0xe0) >> 5);
si->ps.tv_encoder.version = id & 0x1f;
return stat;
}
bool BT_probe()
{
bool btfound = false;
LOG(4,("Brooktree: Checking IIC bus(ses) for first possible TV encoder...\n"));
if (si->ps.i2c_bus0)
{
/* try primary adress on bus 0 */
if (!BT_check(0, PRADR))
{
btfound = true;
si->ps.tv_encoder.adress = PRADR;
si->ps.tv_encoder.bus = 0;
}
else
{
/* try secondary adress on bus 0 */
if (!BT_check(0, SCADR))
{
btfound = true;
si->ps.tv_encoder.adress = SCADR;
si->ps.tv_encoder.bus = 0;
}
}
}
if (si->ps.i2c_bus1 && !btfound)
{
/* try primary adress on bus 1 */
if (!BT_check(1, PRADR))
{
btfound = true;
si->ps.tv_encoder.adress = PRADR;
si->ps.tv_encoder.bus = 1;
}
else
{
/* try secondary adress on bus 1 */
if (!BT_check(1, SCADR))
{
btfound = true;
si->ps.tv_encoder.adress = SCADR;
si->ps.tv_encoder.bus = 1;
}
}
}
/* identify exact TV encoder type */
if (btfound)
{
/* if errors are found, retry */
/* note:
* NACK: occurs on some ASUS V7700 GeForce cards!
* (apparantly the video-in chip or another chip resides at 'BT' adresses
* there..) */
uint8 stat;
uint8 cnt = 0;
while ((stat = BT_read_type()) && (cnt < 3))
{
cnt++;
}
if (stat)
{
LOG(4,("Brooktree: too much errors occurred, aborting.\n"));
btfound = 0;
}
}
if (btfound)
LOG(4,("Brooktree: Found TV encoder on bus %d, adress $%02x\n",
si->ps.tv_encoder.bus, si->ps.tv_encoder.adress));
else
LOG(4,("Brooktree: No TV encoder Found\n"));
return btfound;
}
//matrox old stuff..
typedef struct {
uint32 h_total;
uint32 h_display;

View File

@ -1107,7 +1107,8 @@ static status_t nvxx_general_powerup()
unlock_card();
/* get RAM size and fake panel startup (panel init code is still missing) */
/* get RAM size, detect TV encoder and do fake panel startup (panel init code
* is still missing). */
fake_panel_start();
/* log the final card specifications */

View File

@ -38,8 +38,9 @@ status_t i2c_sec_tv_adapter()
return result;
}
static char FlagIICError (char ErrNo)
char i2c_flag_error (char ErrNo)
//error code list:
//0 - OK status
//1 - SCL locked low by device (bus is still busy)
//2 - SDA locked low by device (bus is still busy)
//3 - No Acknowledge from device (no handshake)
@ -131,7 +132,7 @@ static void TXBit (uint8 BusNR, bool Bit)
{
OutSDA(BusNR, true);
snooze(3);
if (!InSDA(BusNR)) FlagIICError (2);
if (!InSDA(BusNR)) i2c_flag_error (2);
}
else
{
@ -141,7 +142,7 @@ static void TXBit (uint8 BusNR, bool Bit)
snooze(6);
OutSCL(BusNR, true);
snooze(3);
if (!InSCL(BusNR)) FlagIICError (1);
if (!InSCL(BusNR)) i2c_flag_error (1);
snooze(6);
OutSCL(BusNR, false);
snooze(6);
@ -157,7 +158,7 @@ static uint8 RXBit (uint8 BusNR)
snooze(6);
OutSCL(BusNR, true);
snooze(3);
if (!InSCL(BusNR)) FlagIICError (1);
if (!InSCL(BusNR)) i2c_flag_error (1);
snooze(3);
/* read databit */
if (InSDA(BusNR)) Bit = 1;
@ -168,14 +169,14 @@ static uint8 RXBit (uint8 BusNR)
return Bit;
}
static void bstart (uint8 BusNR)
void i2c_bstart (uint8 BusNR)
{
/* make sure SDA is high */
OutSDA(BusNR, true);
snooze(3);
OutSCL(BusNR, true);
snooze(3);
if (!InSCL(BusNR)) FlagIICError (1);
if (!InSCL(BusNR)) i2c_flag_error (1);
snooze(6);
/* clear SDA while SCL set (bus-start condition) */
OutSDA(BusNR, false);
@ -184,29 +185,29 @@ static void bstart (uint8 BusNR)
snooze(6);
LOG(4,("I2C: START condition generated on bus %d; status is %d\n",
BusNR, FlagIICError (0)));
BusNR, i2c_flag_error (0)));
}
static void bstop (uint8 BusNR)
void i2c_bstop (uint8 BusNR)
{
/* make sure SDA is low */
OutSDA(BusNR, false);
snooze(3);
OutSCL(BusNR, true);
snooze(3);
if (!InSCL(BusNR)) FlagIICError (1);
if (!InSCL(BusNR)) i2c_flag_error (1);
snooze(6);
/* set SDA while SCL set (bus-stop condition) */
OutSDA(BusNR, true);
snooze(3);
if (!InSDA(BusNR)) FlagIICError (4);
if (!InSDA(BusNR)) i2c_flag_error (4);
snooze(3);
LOG(4,("I2C: STOP condition generated on bus %d; status is %d\n",
BusNR, FlagIICError (0)));
BusNR, i2c_flag_error (0)));
}
static uint8 i2c_readbyte(uint8 BusNR, bool Ack)
uint8 i2c_readbyte(uint8 BusNR, bool Ack)
{
uint8 cnt, bit, byte = 0;
@ -224,15 +225,16 @@ static uint8 i2c_readbyte(uint8 BusNR, bool Ack)
TXBit (BusNR, Ack);
LOG(4,("I2C: read byte ($%02x) from bus #%d; status is %d\n",
byte, BusNR, FlagIICError(0)));
byte, BusNR, i2c_flag_error(0)));
return byte;
}
static bool i2c_writebyte (uint8 BusNR, uint8 byte)
bool i2c_writebyte (uint8 BusNR, uint8 byte)
{
uint8 cnt;
bool bit;
uint8 tmp = byte;
/* enable access to primary head */
set_crtc_owner(0);
@ -240,55 +242,19 @@ static bool i2c_writebyte (uint8 BusNR, uint8 byte)
/* write data */
for (cnt = 8; cnt > 0; cnt--)
{
bit = (byte & 0x80);
bit = (tmp & 0x80);
TXBit (BusNR, bit);
byte <<= 1;
tmp <<= 1;
}
/* read acknowledge */
bit = RXBit (BusNR);
if (bit) FlagIICError (3);
if (bit) i2c_flag_error (3);
LOG(4,("I2C: written byte ($%02x) to bus #%d; status is %d\n",
byte, BusNR, FlagIICError(0)));
byte, BusNR, i2c_flag_error(0)));
return bit;
}
//end rud.
/*-------------------------------------------
*PUBLIC functions
*/
int i2c_maven_read(unsigned char address)
{
int error=0;
int data=0;
/*
i2c_start();
{
error+=i2c_sendbyte(MAVEN_READ);
error+=i2c_sendbyte(address);
// data = i2c_readbyte(0);
}
i2c_stop();
*/
if (error>0) LOG(8,("I2C: MAVR ERROR - %x\n",error));
return data;
}
void i2c_maven_write(unsigned char address, unsigned char data)
{
int error=0;
/*
i2c_start();
{
error+=i2c_sendbyte(MAVEN_WRITE);
error+=i2c_sendbyte(address);
error+=i2c_sendbyte(data);
}
i2c_stop();
*/
if (error>0) LOG(8,("I2C: MAVW ERROR - %x\n",error));
}
status_t i2c_init(void)
{
@ -305,10 +271,10 @@ status_t i2c_init(void)
for (bus = 0; bus < 2; bus++)
{
/* reset status */
FlagIICError (-1);
i2c_flag_error (-1);
snooze(6);
/* init and/or stop I2C bus */
bstop(bus);
i2c_bstop(bus);
/* check for hardware coupling of SCL and SDA -out and -in lines */
snooze(6);
OutSCL(bus, false);
@ -323,7 +289,7 @@ status_t i2c_init(void)
i2c_bus[bus] = true;
snooze(3);
/* re-init bus */
bstop(bus);
i2c_bstop(bus);
}
for (bus = 0; bus < 2; bus++)
@ -334,5 +300,6 @@ status_t i2c_init(void)
LOG(4,("I2C: bus #%d wiring check: failed\n", bus));
}
if (!si->ps.i2c_bus0 && !si->ps.i2c_bus1) return B_ERROR;
return B_OK;
}

View File

@ -2129,16 +2129,11 @@ void fake_panel_start(void)
/* find out if the card has a tvout chip */
si->ps.tvout = false;
si->ps.tvout_chip_type = NONE;
//fixme ;-)
si->ps.tv_encoder.type = NONE;
si->ps.tv_encoder.version = 0;
i2c_init();
/* if (i2c_maven_probe() == B_OK)
{
si->ps.tvout = true;
si->ps.tvout_chip_bus = ???;
si->ps.tvout_chip_type = ???;
}
*/
//fixme: add support for more encoders...
BT_probe();
LOG(8,("INFO: faking panel startup\n"));
@ -3149,7 +3144,7 @@ void dump_pins(void)
LOG(2,("tvout: "));
if (si->ps.tvout) LOG(2,("present\n")); else LOG(2,("absent\n"));
/* setup TVout logmessage text */
switch (si->ps.tvout_chip_type)
switch (si->ps.tv_encoder.type)
{
case NONE:
msg = "No";
@ -3203,7 +3198,8 @@ void dump_pins(void)
msg = "Unknown";
break;
}
LOG(2, ("%s TVout chip detected\n", msg));
LOG(2, ("%s TV encoder detected; silicon revision is $%02x\n",
msg, si->ps.tv_encoder.version));
// LOG(2,("primary_dvi: "));
// if (si->ps.primary_dvi) LOG(2,("present\n")); else LOG(2,("absent\n"));
// LOG(2,("secondary_dvi: "));

View File

@ -26,10 +26,13 @@ void delay(bigtime_t i);
void nv_log(char *format, ...);
/* i2c functions */
int i2c_maven_read(unsigned char address);
void i2c_maven_write(unsigned char address, unsigned char data);
status_t i2c_sec_tv_adapter(void);
char i2c_flag_error (char ErrNo);
void i2c_bstart (uint8 BusNR);
void i2c_bstop (uint8 BusNR);
uint8 i2c_readbyte(uint8 BusNR, bool Ack);
bool i2c_writebyte (uint8 BusNR, uint8 byte);
status_t i2c_init(void);
status_t i2c_maven_probe(void);
/* card info functions */
status_t parse_pins(void);
@ -53,7 +56,8 @@ status_t nv_dac2_palette(uint8*,uint8*,uint8*);
status_t nv_dac2_pix_pll_find(display_mode target,float * result,uint8 *,uint8 *,uint8 *, uint8);
status_t nv_dac2_set_pix_pll(display_mode target);
/*MAVENTV functions*/
/* Brooktree TV functions */
bool BT_probe(void);
status_t g100_g400max_maventv_vid_pll_find(
display_mode target, unsigned int * ht_new, unsigned int * ht_last_line,
uint8 * m_result, uint8 * n_result, uint8 * p_result);
@ -134,9 +138,6 @@ status_t nv_configure_bes
(const overlay_buffer *ob, const overlay_window *ow,const overlay_view *ov, int offset);
status_t nv_release_bes(void);
/* I2C functions */
status_t i2c_sec_tv_adapter(void);
/* driver structures and enums */
enum{BPP8 = 0, BPP15 = 1, BPP16 = 2, BPP24 = 3, BPP32 = 4};
enum{DS_CRTC1DAC_CRTC2MAVEN, DS_CRTC1MAVEN_CRTC2DAC, DS_CRTC1CON1_CRTC2CON2, DS_CRTC1CON2_CRTC2CON1};