mirror of
https://review.haiku-os.org/haiku
synced 2025-01-21 05:53:46 +01:00
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:
parent
170a41cdcb
commit
12566cbd0d
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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: "));
|
||||
|
@ -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};
|
||||
|
Loading…
x
Reference in New Issue
Block a user