112566cbdSRudolf Cornelissen /* 212566cbdSRudolf Cornelissen Author: 3b2459715SRudolf Cornelissen Rudolf Cornelissen 4/2002-10/2005 4fb6cadf1Sshatty */ 5fb6cadf1Sshatty 6fb6cadf1Sshatty #define MODULE_BIT 0x00100000 7fb6cadf1Sshatty 8fb6cadf1Sshatty #include "nv_std.h" 9fb6cadf1Sshatty 1012566cbdSRudolf Cornelissen #define PRADR 0x88 1112566cbdSRudolf Cornelissen #define SCADR 0x8a 1212566cbdSRudolf Cornelissen #define WR 0x00 1312566cbdSRudolf Cornelissen #define RD 0x01 1412566cbdSRudolf Cornelissen 1521f6ecabSRudolf Cornelissen //fixme: remove rubbish.. 1621f6ecabSRudolf Cornelissen enum 1721f6ecabSRudolf Cornelissen { // TVoutput mode to set 18b2459715SRudolf Cornelissen NOT_SUPPORTED = 0, 1921f6ecabSRudolf Cornelissen NTSC640_TST, 2021f6ecabSRudolf Cornelissen NTSC640, 2121f6ecabSRudolf Cornelissen NTSC800, 2221f6ecabSRudolf Cornelissen PAL800_TST, 2321f6ecabSRudolf Cornelissen PAL640, 2421f6ecabSRudolf Cornelissen PAL800, 2521f6ecabSRudolf Cornelissen VGA, 2621f6ecabSRudolf Cornelissen EXIT, 2721f6ecabSRudolf Cornelissen NTSC720, 2821f6ecabSRudolf Cornelissen PAL720, 2921f6ecabSRudolf Cornelissen NTSC640_OS, 3021f6ecabSRudolf Cornelissen PAL800_OS 3121f6ecabSRudolf Cornelissen }; 3221f6ecabSRudolf Cornelissen 339a7218c5SRudolf Cornelissen /* Dirk Thierbach's Macro setup for registers 0xda-0xfe */ 349a7218c5SRudolf Cornelissen static uint8 BtNtscMacro0 [] = { 359a7218c5SRudolf Cornelissen 0x0f,0xfc,0x20,0xd0,0x6f,0x0f,0x00,0x00,0x0c,0xf3,0x09, 369a7218c5SRudolf Cornelissen 0xbd,0x67,0xb5,0x90,0xb2,0x7d,0x00,0x00}; 379a7218c5SRudolf Cornelissen static uint8 BtNtscMacro1 [] = { 389a7218c5SRudolf Cornelissen 0x0f,0xfc,0x20,0xd0,0x6f,0x0f,0x00,0x00,0x0c,0xf3,0x09, 399a7218c5SRudolf Cornelissen 0xbd,0x67,0xb5,0x90,0xb2,0x7d,0x63,0x00}; 409a7218c5SRudolf Cornelissen static uint8 BtNtscMacro2 [] = { 419a7218c5SRudolf Cornelissen 0x0f,0xfc,0x20,0xd0,0x6f,0x0f,0x00,0x00,0x0c,0xf3,0x09, 429a7218c5SRudolf Cornelissen 0xbd,0x6c,0x31,0x92,0x32,0xdd,0xe3,0x00}; 439a7218c5SRudolf Cornelissen static uint8 BtNtscMacro3 [] = { 449a7218c5SRudolf Cornelissen 0x0f,0xfc,0x20,0xd0,0x6f,0x0f,0x00,0x00,0x0c,0xf3,0x09, 459a7218c5SRudolf Cornelissen 0xbd,0x66,0xb5,0x90,0xb2,0x7d,0xe3,0x00}; 469a7218c5SRudolf Cornelissen 479a7218c5SRudolf Cornelissen static uint8 BtPalMacro0 [] = { 489a7218c5SRudolf Cornelissen 0x05,0x57,0x20,0x40,0x6e,0x7e,0xf4,0x51,0x0f,0xf1,0x05, 499a7218c5SRudolf Cornelissen 0xd3,0x78,0xa2,0x25,0x54,0xa5,0x00,0x00}; 509a7218c5SRudolf Cornelissen static uint8 BtPalMacro1 [] = { 519a7218c5SRudolf Cornelissen 0x05,0x57,0x20,0x40,0x6e,0x7e,0xf4,0x51,0x0f,0xf1,0x05, 529a7218c5SRudolf Cornelissen 0xd3,0x78,0xa2,0x25,0x54,0xa5,0x63,0x00}; 539a7218c5SRudolf Cornelissen 549a7218c5SRudolf Cornelissen static uint8 BT_set_macro (int std, int mode) 559a7218c5SRudolf Cornelissen { 569a7218c5SRudolf Cornelissen uint8 stat; 579a7218c5SRudolf Cornelissen uint8 buffer[21]; 589a7218c5SRudolf Cornelissen 599a7218c5SRudolf Cornelissen LOG(4,("Brooktree: Setting Macro\n")); 609a7218c5SRudolf Cornelissen 619a7218c5SRudolf Cornelissen if ((std < 0) | (std > 1) | (mode < 0) | (mode > 3)) 629a7218c5SRudolf Cornelissen { 639a7218c5SRudolf Cornelissen LOG(4,("Brooktree: Non existing mode or standard selected, aborting.\n")); 649a7218c5SRudolf Cornelissen return 0x80; 659a7218c5SRudolf Cornelissen } 669a7218c5SRudolf Cornelissen 679a7218c5SRudolf Cornelissen switch (std) 689a7218c5SRudolf Cornelissen { 699a7218c5SRudolf Cornelissen case 0: 709a7218c5SRudolf Cornelissen /* NTSC */ 719a7218c5SRudolf Cornelissen switch (mode) 729a7218c5SRudolf Cornelissen { 739a7218c5SRudolf Cornelissen case 0: 749a7218c5SRudolf Cornelissen /* disabled */ 759a7218c5SRudolf Cornelissen memcpy(&buffer[2], &BtNtscMacro0, 19); 769a7218c5SRudolf Cornelissen break; 779a7218c5SRudolf Cornelissen case 1: 789a7218c5SRudolf Cornelissen /* enabled mode 1 */ 799a7218c5SRudolf Cornelissen memcpy(&buffer[2], &BtNtscMacro1, 19); 809a7218c5SRudolf Cornelissen break; 819a7218c5SRudolf Cornelissen case 2: 829a7218c5SRudolf Cornelissen /* enabled mode 2 */ 839a7218c5SRudolf Cornelissen memcpy(&buffer[2], &BtNtscMacro2, 19); 849a7218c5SRudolf Cornelissen break; 859a7218c5SRudolf Cornelissen case 3: 869a7218c5SRudolf Cornelissen /* enabled mode 3 */ 879a7218c5SRudolf Cornelissen memcpy(&buffer[2], &BtNtscMacro3, 19); 889a7218c5SRudolf Cornelissen break; 899a7218c5SRudolf Cornelissen } 909a7218c5SRudolf Cornelissen break; 919a7218c5SRudolf Cornelissen case 1: 929a7218c5SRudolf Cornelissen /* PAL */ 939a7218c5SRudolf Cornelissen switch (mode) 949a7218c5SRudolf Cornelissen { 959a7218c5SRudolf Cornelissen case 0: 969a7218c5SRudolf Cornelissen /* disabled */ 979a7218c5SRudolf Cornelissen memcpy(&buffer[2], &BtPalMacro0, 19); 989a7218c5SRudolf Cornelissen break; 999a7218c5SRudolf Cornelissen case 1: 1009a7218c5SRudolf Cornelissen case 2: 1019a7218c5SRudolf Cornelissen case 3: 1029a7218c5SRudolf Cornelissen /* enabled */ 1039a7218c5SRudolf Cornelissen memcpy(&buffer[2], &BtPalMacro1, 19); 1049a7218c5SRudolf Cornelissen break; 1059a7218c5SRudolf Cornelissen } 1069a7218c5SRudolf Cornelissen break; 1079a7218c5SRudolf Cornelissen } 1089a7218c5SRudolf Cornelissen 1099a7218c5SRudolf Cornelissen buffer[0] = si->ps.tv_encoder.adress + WR; 1109a7218c5SRudolf Cornelissen /* select first register to write to */ 1119a7218c5SRudolf Cornelissen buffer[1] = 0xda; 1129a7218c5SRudolf Cornelissen 1139a7218c5SRudolf Cornelissen /* reset status */ 1149a7218c5SRudolf Cornelissen i2c_flag_error (-1); 1159a7218c5SRudolf Cornelissen 1169a7218c5SRudolf Cornelissen i2c_bstart(si->ps.tv_encoder.bus); 1179a7218c5SRudolf Cornelissen i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer)); 1189a7218c5SRudolf Cornelissen i2c_bstop(si->ps.tv_encoder.bus); 1199a7218c5SRudolf Cornelissen /* log on errors */ 1209a7218c5SRudolf Cornelissen stat = i2c_flag_error(0); 1219a7218c5SRudolf Cornelissen if (stat) 1229a7218c5SRudolf Cornelissen LOG(4,("Brooktree: I2C errors occurred while setting Macro\n")); 1239a7218c5SRudolf Cornelissen 1249a7218c5SRudolf Cornelissen return stat; 1259a7218c5SRudolf Cornelissen }//end BT_set_macro. 1269a7218c5SRudolf Cornelissen 12712566cbdSRudolf Cornelissen /* 12812566cbdSRudolf Cornelissen see if a (possible) BT/CX chip resides at the given adress. 12912566cbdSRudolf Cornelissen Return zero if no errors occurred. 13012566cbdSRudolf Cornelissen */ 13112566cbdSRudolf Cornelissen static uint8 BT_check (uint8 bus, uint8 adress) 13212566cbdSRudolf Cornelissen { 1330ece4905SRudolf Cornelissen uint8 buffer[3]; 13412566cbdSRudolf Cornelissen 1350ece4905SRudolf Cornelissen buffer[0] = adress + WR; 13612566cbdSRudolf Cornelissen /* set ESTATUS at b'00'; and enable bt chip-outputs 13712566cbdSRudolf Cornelissen * WARNING: 13812566cbdSRudolf Cornelissen * If bit0 = 0 is issued below (EN_OUT = disabled), the BT will lock SDA 13912566cbdSRudolf Cornelissen * after writing adress $A0 (setting EN_XCLK)!!! 1409a7218c5SRudolf Cornelissen * Until a reboot the corresponding I2C bus will be inacessable then!!! */ 1410ece4905SRudolf Cornelissen buffer[1] = 0xc4; 14212566cbdSRudolf Cornelissen /* fixme: if testimage 'was' active txbuffer[3] should become 0x05... 14312566cbdSRudolf Cornelissen * (currently this cannot be detected in a 'foolproof' way so don't touch...) */ 14412566cbdSRudolf Cornelissen /* (ESTATUS b'0x' means: RX ID and VERSION info later..) */ 1450ece4905SRudolf Cornelissen buffer[2] = 0x01; 1460ece4905SRudolf Cornelissen 1470ece4905SRudolf Cornelissen /* reset status */ 1480ece4905SRudolf Cornelissen i2c_flag_error (-1); 1490ece4905SRudolf Cornelissen 1500ece4905SRudolf Cornelissen /* do check */ 1510ece4905SRudolf Cornelissen i2c_bstart(bus); 1520ece4905SRudolf Cornelissen i2c_writebuffer(bus, buffer, sizeof(buffer)); 15312566cbdSRudolf Cornelissen i2c_bstop(bus); 15412566cbdSRudolf Cornelissen return i2c_flag_error(0); 15512566cbdSRudolf Cornelissen } 15612566cbdSRudolf Cornelissen 15712566cbdSRudolf Cornelissen /* identify chiptype */ 15812566cbdSRudolf Cornelissen static uint8 BT_read_type (void) 15912566cbdSRudolf Cornelissen { 1600ece4905SRudolf Cornelissen uint8 id, type, stat; 1610ece4905SRudolf Cornelissen uint8 buffer[3]; 1620ece4905SRudolf Cornelissen 1630ece4905SRudolf Cornelissen /* Make sure a CX (Conexant) chip (if this turns out to be there) is set to 1640ece4905SRudolf Cornelissen * BT-compatibility mode! (This command will do nothing on a BT chip...) */ 1650ece4905SRudolf Cornelissen buffer[0] = si->ps.tv_encoder.adress + WR; 1660ece4905SRudolf Cornelissen /* select CX reg. for BT-compatible readback, video still off */ 1670ece4905SRudolf Cornelissen buffer[1] = 0x6c; 1680ece4905SRudolf Cornelissen /* set it up */ 1690ece4905SRudolf Cornelissen buffer[2] = 0x02; 17012566cbdSRudolf Cornelissen 17112566cbdSRudolf Cornelissen /* reset status */ 17212566cbdSRudolf Cornelissen i2c_flag_error (-1); 17312566cbdSRudolf Cornelissen 17412566cbdSRudolf Cornelissen i2c_bstart(si->ps.tv_encoder.bus); 1750ece4905SRudolf Cornelissen i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer)); 17612566cbdSRudolf Cornelissen i2c_bstop(si->ps.tv_encoder.bus); 17712566cbdSRudolf Cornelissen /* abort on errors */ 17812566cbdSRudolf Cornelissen stat = i2c_flag_error(0); 17912566cbdSRudolf Cornelissen if (stat) return stat; 18012566cbdSRudolf Cornelissen 18112566cbdSRudolf Cornelissen /* Do actual readtype command */ 18212566cbdSRudolf Cornelissen i2c_bstart(si->ps.tv_encoder.bus); 1839a7218c5SRudolf Cornelissen /* issue I2C read command */ 18412566cbdSRudolf Cornelissen i2c_writebyte(si->ps.tv_encoder.bus, si->ps.tv_encoder.adress + RD); 18512566cbdSRudolf Cornelissen /* receive 1 byte; 1869a7218c5SRudolf Cornelissen * ACK level to TX after last byte to RX should be 1 (= NACK) (see I2C spec). */ 18712566cbdSRudolf Cornelissen /* note: 18812566cbdSRudolf Cornelissen * While the BT's don't care, CX chips will block the SDA line if 18912566cbdSRudolf Cornelissen * an ACK gets sent! */ 19012566cbdSRudolf Cornelissen id = i2c_readbyte(si->ps.tv_encoder.bus, true); 19112566cbdSRudolf Cornelissen i2c_bstop(si->ps.tv_encoder.bus); 19212566cbdSRudolf Cornelissen /* abort on errors */ 19312566cbdSRudolf Cornelissen stat = i2c_flag_error(0); 19412566cbdSRudolf Cornelissen if (stat) return stat; 19512566cbdSRudolf Cornelissen 1960ece4905SRudolf Cornelissen /* check type to be supported one */ 1970ece4905SRudolf Cornelissen type = (id & 0xe0) >> 5; 1980ece4905SRudolf Cornelissen if (type > 3) 1990ece4905SRudolf Cornelissen { 2000ece4905SRudolf Cornelissen LOG(4,("Brooktree: Found unsupported encoder type %d, aborting.\n", type)); 2010ece4905SRudolf Cornelissen return 0x80; 2020ece4905SRudolf Cornelissen } 2030ece4905SRudolf Cornelissen 20412566cbdSRudolf Cornelissen /* inform driver about TV encoder found */ 20512566cbdSRudolf Cornelissen si->ps.tvout = true; 2060ece4905SRudolf Cornelissen si->ps.tv_encoder.type = BT868 + type; 20712566cbdSRudolf Cornelissen si->ps.tv_encoder.version = id & 0x1f; 20812566cbdSRudolf Cornelissen 20912566cbdSRudolf Cornelissen return stat; 21012566cbdSRudolf Cornelissen } 21112566cbdSRudolf Cornelissen 21212566cbdSRudolf Cornelissen bool BT_probe() 21312566cbdSRudolf Cornelissen { 21412566cbdSRudolf Cornelissen bool btfound = false; 21512566cbdSRudolf Cornelissen 2169a7218c5SRudolf Cornelissen LOG(4,("Brooktree: Checking I2C bus(ses) for first possible TV encoder...\n")); 21712566cbdSRudolf Cornelissen if (si->ps.i2c_bus0) 21812566cbdSRudolf Cornelissen { 21912566cbdSRudolf Cornelissen /* try primary adress on bus 0 */ 22012566cbdSRudolf Cornelissen if (!BT_check(0, PRADR)) 22112566cbdSRudolf Cornelissen { 22212566cbdSRudolf Cornelissen btfound = true; 22312566cbdSRudolf Cornelissen si->ps.tv_encoder.adress = PRADR; 22412566cbdSRudolf Cornelissen si->ps.tv_encoder.bus = 0; 22512566cbdSRudolf Cornelissen } 22612566cbdSRudolf Cornelissen else 22712566cbdSRudolf Cornelissen { 22812566cbdSRudolf Cornelissen /* try secondary adress on bus 0 */ 22912566cbdSRudolf Cornelissen if (!BT_check(0, SCADR)) 23012566cbdSRudolf Cornelissen { 23112566cbdSRudolf Cornelissen btfound = true; 23212566cbdSRudolf Cornelissen si->ps.tv_encoder.adress = SCADR; 23312566cbdSRudolf Cornelissen si->ps.tv_encoder.bus = 0; 23412566cbdSRudolf Cornelissen } 23512566cbdSRudolf Cornelissen } 23612566cbdSRudolf Cornelissen } 23712566cbdSRudolf Cornelissen 23812566cbdSRudolf Cornelissen if (si->ps.i2c_bus1 && !btfound) 23912566cbdSRudolf Cornelissen { 24012566cbdSRudolf Cornelissen /* try primary adress on bus 1 */ 24112566cbdSRudolf Cornelissen if (!BT_check(1, PRADR)) 24212566cbdSRudolf Cornelissen { 24312566cbdSRudolf Cornelissen btfound = true; 24412566cbdSRudolf Cornelissen si->ps.tv_encoder.adress = PRADR; 24512566cbdSRudolf Cornelissen si->ps.tv_encoder.bus = 1; 24612566cbdSRudolf Cornelissen } 24712566cbdSRudolf Cornelissen else 24812566cbdSRudolf Cornelissen { 24912566cbdSRudolf Cornelissen /* try secondary adress on bus 1 */ 25012566cbdSRudolf Cornelissen if (!BT_check(1, SCADR)) 25112566cbdSRudolf Cornelissen { 25212566cbdSRudolf Cornelissen btfound = true; 25312566cbdSRudolf Cornelissen si->ps.tv_encoder.adress = SCADR; 25412566cbdSRudolf Cornelissen si->ps.tv_encoder.bus = 1; 25512566cbdSRudolf Cornelissen } 25612566cbdSRudolf Cornelissen } 25712566cbdSRudolf Cornelissen } 25812566cbdSRudolf Cornelissen 25912566cbdSRudolf Cornelissen /* identify exact TV encoder type */ 26012566cbdSRudolf Cornelissen if (btfound) 26112566cbdSRudolf Cornelissen { 26212566cbdSRudolf Cornelissen /* if errors are found, retry */ 26312566cbdSRudolf Cornelissen /* note: 26412566cbdSRudolf Cornelissen * NACK: occurs on some ASUS V7700 GeForce cards! 26512566cbdSRudolf Cornelissen * (apparantly the video-in chip or another chip resides at 'BT' adresses 26612566cbdSRudolf Cornelissen * there..) */ 26712566cbdSRudolf Cornelissen uint8 stat; 26812566cbdSRudolf Cornelissen uint8 cnt = 0; 26912566cbdSRudolf Cornelissen while ((stat = BT_read_type()) && (cnt < 3)) 27012566cbdSRudolf Cornelissen { 2710ece4905SRudolf Cornelissen /* don't retry on unsupported chiptype */ 2720ece4905SRudolf Cornelissen if (stat == 0x80) 2730ece4905SRudolf Cornelissen { 2740ece4905SRudolf Cornelissen btfound = 0; 2750ece4905SRudolf Cornelissen break; 2760ece4905SRudolf Cornelissen } 27712566cbdSRudolf Cornelissen cnt++; 27812566cbdSRudolf Cornelissen } 2790ece4905SRudolf Cornelissen if (stat & 0x7f) 28012566cbdSRudolf Cornelissen { 2819a7218c5SRudolf Cornelissen LOG(4,("Brooktree: Too much errors occurred, aborting.\n")); 28212566cbdSRudolf Cornelissen btfound = 0; 28312566cbdSRudolf Cornelissen } 28412566cbdSRudolf Cornelissen } 28512566cbdSRudolf Cornelissen 28612566cbdSRudolf Cornelissen if (btfound) 28712566cbdSRudolf Cornelissen LOG(4,("Brooktree: Found TV encoder on bus %d, adress $%02x\n", 28812566cbdSRudolf Cornelissen si->ps.tv_encoder.bus, si->ps.tv_encoder.adress)); 28912566cbdSRudolf Cornelissen else 29012566cbdSRudolf Cornelissen LOG(4,("Brooktree: No TV encoder Found\n")); 29112566cbdSRudolf Cornelissen 29212566cbdSRudolf Cornelissen return btfound; 29312566cbdSRudolf Cornelissen } 29412566cbdSRudolf Cornelissen 29577497c49SRudolf Cornelissen static uint8 BT_init_PAL640() 296fb6cadf1Sshatty { 29777497c49SRudolf Cornelissen uint8 stat; 298fb6cadf1Sshatty 29977497c49SRudolf Cornelissen uint8 buffer[35]; 300fb6cadf1Sshatty 3019a7218c5SRudolf Cornelissen LOG(4,("Brooktree: Setting PAL 640x480 desktop mode\n")); 3029a7218c5SRudolf Cornelissen 3039a7218c5SRudolf Cornelissen buffer[0] = si->ps.tv_encoder.adress + WR; //issue I2C write command 30477497c49SRudolf Cornelissen buffer[1] = 0x76; //select first bt register to write to 30577497c49SRudolf Cornelissen buffer[2] = 0x60; 30677497c49SRudolf Cornelissen buffer[3] = 0x80; 30777497c49SRudolf Cornelissen buffer[4] = 0x8a; 30877497c49SRudolf Cornelissen buffer[5] = 0xa6; 30977497c49SRudolf Cornelissen buffer[6] = 0x68; 31077497c49SRudolf Cornelissen buffer[7] = 0xc1; 31177497c49SRudolf Cornelissen buffer[8] = 0x2e; 31277497c49SRudolf Cornelissen buffer[9] = 0xf2; 31377497c49SRudolf Cornelissen buffer[10] = 0x27; 31477497c49SRudolf Cornelissen buffer[11] = 0x00; 31577497c49SRudolf Cornelissen buffer[12] = 0xb0; 31677497c49SRudolf Cornelissen buffer[13] = 0x0a; 31777497c49SRudolf Cornelissen buffer[14] = 0x0b; 31877497c49SRudolf Cornelissen buffer[15] = 0x71; 31977497c49SRudolf Cornelissen buffer[16] = 0x5a; 32077497c49SRudolf Cornelissen buffer[17] = 0xe0; 32177497c49SRudolf Cornelissen buffer[18] = 0x36; 32277497c49SRudolf Cornelissen buffer[19] = 0x00; 32377497c49SRudolf Cornelissen buffer[20] = 0x50; 32477497c49SRudolf Cornelissen buffer[21] = 0x72; 32577497c49SRudolf Cornelissen buffer[22] = 0x1c; 32677497c49SRudolf Cornelissen buffer[23] = 0x8d; //chip-pin CLKI is pixel clock (only non-default here!) 32777497c49SRudolf Cornelissen buffer[24] = 0x24; 32877497c49SRudolf Cornelissen buffer[25] = 0xf0; 32977497c49SRudolf Cornelissen buffer[26] = 0x58; 33077497c49SRudolf Cornelissen buffer[27] = 0x81; 33177497c49SRudolf Cornelissen buffer[28] = 0x49; 33277497c49SRudolf Cornelissen buffer[29] = 0x8c; 33377497c49SRudolf Cornelissen buffer[30] = 0x0c; 33477497c49SRudolf Cornelissen buffer[31] = 0x8c; 33577497c49SRudolf Cornelissen buffer[32] = 0x79; 33677497c49SRudolf Cornelissen buffer[33] = 0x26; 33777497c49SRudolf Cornelissen buffer[34] = 0x00; 33877497c49SRudolf Cornelissen 33977497c49SRudolf Cornelissen /* reset status */ 34077497c49SRudolf Cornelissen i2c_flag_error (-1); 34177497c49SRudolf Cornelissen 34277497c49SRudolf Cornelissen i2c_bstart(si->ps.tv_encoder.bus); 34377497c49SRudolf Cornelissen i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer)); 34477497c49SRudolf Cornelissen i2c_bstop(si->ps.tv_encoder.bus); 34577497c49SRudolf Cornelissen /* log on errors */ 34677497c49SRudolf Cornelissen stat = i2c_flag_error(0); 34777497c49SRudolf Cornelissen if (stat) 34877497c49SRudolf Cornelissen LOG(4,("Brooktree: I2C errors occurred while setting mode PAL640\n")); 34977497c49SRudolf Cornelissen 35077497c49SRudolf Cornelissen return stat; 35177497c49SRudolf Cornelissen }//end BT_init_PAL640. 35277497c49SRudolf Cornelissen 35377497c49SRudolf Cornelissen static uint8 BT_init_PAL800() 354fb6cadf1Sshatty { 35577497c49SRudolf Cornelissen uint8 stat; 356fb6cadf1Sshatty 35777497c49SRudolf Cornelissen uint8 buffer[35]; 358fb6cadf1Sshatty 3599a7218c5SRudolf Cornelissen LOG(4,("Brooktree: Setting PAL 800x600 desktop mode\n")); 3609a7218c5SRudolf Cornelissen 3619a7218c5SRudolf Cornelissen buffer[0] = si->ps.tv_encoder.adress + WR; //issue I2C write command 36277497c49SRudolf Cornelissen buffer[1] = 0x76; //select first bt register to write to 36377497c49SRudolf Cornelissen buffer[2] = 0x00; 36477497c49SRudolf Cornelissen buffer[3] = 0x20; 36577497c49SRudolf Cornelissen buffer[4] = 0xaa; 36677497c49SRudolf Cornelissen buffer[5] = 0xca; 36777497c49SRudolf Cornelissen buffer[6] = 0x9a; 36877497c49SRudolf Cornelissen buffer[7] = 0x0d; 36977497c49SRudolf Cornelissen buffer[8] = 0x29; 37077497c49SRudolf Cornelissen buffer[9] = 0xfc; 37177497c49SRudolf Cornelissen buffer[10] = 0x39; 37277497c49SRudolf Cornelissen buffer[11] = 0x00; 37377497c49SRudolf Cornelissen buffer[12] = 0xc0; 37477497c49SRudolf Cornelissen buffer[13] = 0x8c; 37577497c49SRudolf Cornelissen buffer[14] = 0x03; 37677497c49SRudolf Cornelissen buffer[15] = 0xee; 37777497c49SRudolf Cornelissen buffer[16] = 0x5f; 37877497c49SRudolf Cornelissen buffer[17] = 0x58; 37977497c49SRudolf Cornelissen buffer[18] = 0x3a; 38077497c49SRudolf Cornelissen buffer[19] = 0x66; 38177497c49SRudolf Cornelissen buffer[20] = 0x96; 38277497c49SRudolf Cornelissen buffer[21] = 0x00; 38377497c49SRudolf Cornelissen buffer[22] = 0x00; 38477497c49SRudolf Cornelissen buffer[23] = 0x90; //chip-pin CLKI is pixel clock (only non-default here!) 38577497c49SRudolf Cornelissen buffer[24] = 0x24; 38677497c49SRudolf Cornelissen buffer[25] = 0xf0; 38777497c49SRudolf Cornelissen buffer[26] = 0x57; 38877497c49SRudolf Cornelissen buffer[27] = 0x80; 38977497c49SRudolf Cornelissen buffer[28] = 0x48; 39077497c49SRudolf Cornelissen buffer[29] = 0x8c; 39177497c49SRudolf Cornelissen buffer[30] = 0x18; 39277497c49SRudolf Cornelissen buffer[31] = 0x28; 39377497c49SRudolf Cornelissen buffer[32] = 0x87; 39477497c49SRudolf Cornelissen buffer[33] = 0x1f; 39577497c49SRudolf Cornelissen buffer[34] = 0x00; 39677497c49SRudolf Cornelissen 39777497c49SRudolf Cornelissen /* reset status */ 39877497c49SRudolf Cornelissen i2c_flag_error (-1); 39977497c49SRudolf Cornelissen 40077497c49SRudolf Cornelissen i2c_bstart(si->ps.tv_encoder.bus); 40177497c49SRudolf Cornelissen i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer)); 40277497c49SRudolf Cornelissen i2c_bstop(si->ps.tv_encoder.bus); 40377497c49SRudolf Cornelissen /* log on errors */ 40477497c49SRudolf Cornelissen stat = i2c_flag_error(0); 40577497c49SRudolf Cornelissen if (stat) 40677497c49SRudolf Cornelissen LOG(4,("Brooktree: I2C errors occurred while setting mode PAL800\n")); 40777497c49SRudolf Cornelissen 40877497c49SRudolf Cornelissen return stat; 40977497c49SRudolf Cornelissen }//end BT_init_PAL800. 41077497c49SRudolf Cornelissen 41177497c49SRudolf Cornelissen static uint8 BT_init_NTSC640() 412fb6cadf1Sshatty { 41377497c49SRudolf Cornelissen uint8 stat; 414fb6cadf1Sshatty 41577497c49SRudolf Cornelissen uint8 buffer[35]; 41677497c49SRudolf Cornelissen 4179a7218c5SRudolf Cornelissen LOG(4,("Brooktree: Setting NTSC 640x480 desktop mode\n")); 4189a7218c5SRudolf Cornelissen 4199a7218c5SRudolf Cornelissen buffer[0] = si->ps.tv_encoder.adress + WR; //issue I2C write command 42077497c49SRudolf Cornelissen buffer[1] = 0x76; //select first bt register to write to 42177497c49SRudolf Cornelissen buffer[2] = 0x00; 42277497c49SRudolf Cornelissen buffer[3] = 0x80; 42377497c49SRudolf Cornelissen buffer[4] = 0x84; 42477497c49SRudolf Cornelissen buffer[5] = 0x96; 42577497c49SRudolf Cornelissen buffer[6] = 0x60; 42677497c49SRudolf Cornelissen buffer[7] = 0x7d; 42777497c49SRudolf Cornelissen buffer[8] = 0x22; 42877497c49SRudolf Cornelissen buffer[9] = 0xd4; 42977497c49SRudolf Cornelissen buffer[10] = 0x27; 43077497c49SRudolf Cornelissen buffer[11] = 0x00; 43177497c49SRudolf Cornelissen buffer[12] = 0x10; 43277497c49SRudolf Cornelissen buffer[13] = 0x7e; 43377497c49SRudolf Cornelissen buffer[14] = 0x03; 43477497c49SRudolf Cornelissen buffer[15] = 0x58; 43577497c49SRudolf Cornelissen buffer[16] = 0x4b; 43677497c49SRudolf Cornelissen buffer[17] = 0xe0; 43777497c49SRudolf Cornelissen buffer[18] = 0x36; 43877497c49SRudolf Cornelissen buffer[19] = 0x92; 43977497c49SRudolf Cornelissen buffer[20] = 0x54; 44077497c49SRudolf Cornelissen buffer[21] = 0x0e; 44177497c49SRudolf Cornelissen buffer[22] = 0x88; 44277497c49SRudolf Cornelissen buffer[23] = 0x8c; //chip-pin CLKI is pixel clock (only non-default here!) 44377497c49SRudolf Cornelissen buffer[24] = 0x0a; 44477497c49SRudolf Cornelissen buffer[25] = 0xe5; 44577497c49SRudolf Cornelissen buffer[26] = 0x76; 44677497c49SRudolf Cornelissen buffer[27] = 0x79; 44777497c49SRudolf Cornelissen buffer[28] = 0x44; 44877497c49SRudolf Cornelissen buffer[29] = 0x85; 44977497c49SRudolf Cornelissen buffer[30] = 0x00; 45077497c49SRudolf Cornelissen buffer[31] = 0x00; 45177497c49SRudolf Cornelissen buffer[32] = 0x80; 45277497c49SRudolf Cornelissen buffer[33] = 0x20; 45377497c49SRudolf Cornelissen buffer[34] = 0x00; 45477497c49SRudolf Cornelissen 45577497c49SRudolf Cornelissen /* reset status */ 45677497c49SRudolf Cornelissen i2c_flag_error (-1); 45777497c49SRudolf Cornelissen 45877497c49SRudolf Cornelissen i2c_bstart(si->ps.tv_encoder.bus); 45977497c49SRudolf Cornelissen i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer)); 46077497c49SRudolf Cornelissen i2c_bstop(si->ps.tv_encoder.bus); 46177497c49SRudolf Cornelissen /* log on errors */ 46277497c49SRudolf Cornelissen stat = i2c_flag_error(0); 46377497c49SRudolf Cornelissen if (stat) 46477497c49SRudolf Cornelissen LOG(4,("Brooktree: I2C errors occurred while setting mode NTSC640\n")); 46577497c49SRudolf Cornelissen 46677497c49SRudolf Cornelissen return stat; 46777497c49SRudolf Cornelissen }//end BT_init_NTSC640. 46877497c49SRudolf Cornelissen 46977497c49SRudolf Cornelissen static uint8 BT_init_NTSC800() 470fb6cadf1Sshatty { 47177497c49SRudolf Cornelissen uint8 stat; 472fb6cadf1Sshatty 47377497c49SRudolf Cornelissen uint8 buffer[35]; 474fb6cadf1Sshatty 4759a7218c5SRudolf Cornelissen LOG(4,("Brooktree: Setting NTSC 800x600 desktop mode\n")); 4769a7218c5SRudolf Cornelissen 4779a7218c5SRudolf Cornelissen buffer[0] = si->ps.tv_encoder.adress + WR; //issue I2C write command 47877497c49SRudolf Cornelissen buffer[1] = 0x76; //select first bt register to write to 47977497c49SRudolf Cornelissen buffer[2] = 0xa0; 48077497c49SRudolf Cornelissen buffer[3] = 0x20; 48177497c49SRudolf Cornelissen buffer[4] = 0xb6; 48277497c49SRudolf Cornelissen buffer[5] = 0xce; 48377497c49SRudolf Cornelissen buffer[6] = 0x84; 48477497c49SRudolf Cornelissen buffer[7] = 0x55; 48577497c49SRudolf Cornelissen buffer[8] = 0x20; 48677497c49SRudolf Cornelissen buffer[9] = 0xd8; 48777497c49SRudolf Cornelissen buffer[10] = 0x39; 48877497c49SRudolf Cornelissen buffer[11] = 0x00; 48977497c49SRudolf Cornelissen buffer[12] = 0x70; 49077497c49SRudolf Cornelissen buffer[13] = 0x42; 49177497c49SRudolf Cornelissen buffer[14] = 0x03; 49277497c49SRudolf Cornelissen buffer[15] = 0xdf; 49377497c49SRudolf Cornelissen buffer[16] = 0x56; 49477497c49SRudolf Cornelissen buffer[17] = 0x58; 49577497c49SRudolf Cornelissen buffer[18] = 0x3a; 49677497c49SRudolf Cornelissen buffer[19] = 0xcd; 49777497c49SRudolf Cornelissen buffer[20] = 0x9c; 49877497c49SRudolf Cornelissen buffer[21] = 0x14; 49977497c49SRudolf Cornelissen buffer[22] = 0x3b; 50077497c49SRudolf Cornelissen buffer[23] = 0x91; //chip-pin CLKI is pixel clock (only non-default here!) 50177497c49SRudolf Cornelissen buffer[24] = 0x0a; 50277497c49SRudolf Cornelissen buffer[25] = 0xe5; 50377497c49SRudolf Cornelissen buffer[26] = 0x74; 50477497c49SRudolf Cornelissen buffer[27] = 0x77; 50577497c49SRudolf Cornelissen buffer[28] = 0x43; 50677497c49SRudolf Cornelissen buffer[29] = 0x85; 50777497c49SRudolf Cornelissen buffer[30] = 0xba; 50877497c49SRudolf Cornelissen buffer[31] = 0xe8; 50977497c49SRudolf Cornelissen buffer[32] = 0xa2; 51077497c49SRudolf Cornelissen buffer[33] = 0x17; 51177497c49SRudolf Cornelissen buffer[34] = 0x00; 51277497c49SRudolf Cornelissen 51377497c49SRudolf Cornelissen /* reset status */ 51477497c49SRudolf Cornelissen i2c_flag_error (-1); 51577497c49SRudolf Cornelissen 51677497c49SRudolf Cornelissen i2c_bstart(si->ps.tv_encoder.bus); 51777497c49SRudolf Cornelissen i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer)); 51877497c49SRudolf Cornelissen i2c_bstop(si->ps.tv_encoder.bus); 51977497c49SRudolf Cornelissen /* log on errors */ 52077497c49SRudolf Cornelissen stat = i2c_flag_error(0); 52177497c49SRudolf Cornelissen if (stat) 52277497c49SRudolf Cornelissen LOG(4,("Brooktree: I2C errors occurred while setting mode PAL800\n")); 52377497c49SRudolf Cornelissen 52477497c49SRudolf Cornelissen return stat; 52577497c49SRudolf Cornelissen }//end BT_init_NTSC800. 52677497c49SRudolf Cornelissen 52777497c49SRudolf Cornelissen static uint8 BT_init_PAL720() 528fb6cadf1Sshatty { 52977497c49SRudolf Cornelissen uint8 stat; 53077497c49SRudolf Cornelissen 53177497c49SRudolf Cornelissen uint8 buffer[35]; 53277497c49SRudolf Cornelissen 5339a7218c5SRudolf Cornelissen LOG(4,("Brooktree: Setting PAL 720x576 overscanning DVD mode\n")); 5349a7218c5SRudolf Cornelissen 5359a7218c5SRudolf Cornelissen buffer[0] = si->ps.tv_encoder.adress + WR; //issue I2C write command 53677497c49SRudolf Cornelissen buffer[1] = 0x76; //select first bt register to write to 53777497c49SRudolf Cornelissen buffer[2] = 0xf0; 53877497c49SRudolf Cornelissen buffer[3] = 0xd0; 53977497c49SRudolf Cornelissen buffer[4] = 0x82; 54077497c49SRudolf Cornelissen buffer[5] = 0x9c; 54177497c49SRudolf Cornelissen buffer[6] = 0x5a; 54277497c49SRudolf Cornelissen buffer[7] = 0x31; 54377497c49SRudolf Cornelissen buffer[8] = 0x16; 54477497c49SRudolf Cornelissen buffer[9] = 0x22; 54577497c49SRudolf Cornelissen buffer[10] = 0xa6; 54677497c49SRudolf Cornelissen buffer[11] = 0x00; 54777497c49SRudolf Cornelissen buffer[12] = 0x78; 54877497c49SRudolf Cornelissen buffer[13] = 0x93; 54977497c49SRudolf Cornelissen buffer[14] = 0x03; 55077497c49SRudolf Cornelissen buffer[15] = 0x71; 55177497c49SRudolf Cornelissen buffer[16] = 0x2a; 55277497c49SRudolf Cornelissen buffer[17] = 0x40; 55377497c49SRudolf Cornelissen buffer[18] = 0x0a; 55477497c49SRudolf Cornelissen buffer[19] = 0x00; 55577497c49SRudolf Cornelissen buffer[20] = 0x50; 55677497c49SRudolf Cornelissen buffer[21] = 0x55; 55777497c49SRudolf Cornelissen buffer[22] = 0x55; 55877497c49SRudolf Cornelissen buffer[23] = 0x8c; //chip-pin CLKI is pixel clock (only non-default here!) 55977497c49SRudolf Cornelissen buffer[24] = 0x24; 56077497c49SRudolf Cornelissen buffer[25] = 0xf0; 56177497c49SRudolf Cornelissen buffer[26] = 0x59; 56277497c49SRudolf Cornelissen buffer[27] = 0x82; 56377497c49SRudolf Cornelissen buffer[28] = 0x49; 56477497c49SRudolf Cornelissen buffer[29] = 0x8c; 56577497c49SRudolf Cornelissen buffer[30] = 0x8e; 56677497c49SRudolf Cornelissen buffer[31] = 0xb0; 56777497c49SRudolf Cornelissen buffer[32] = 0xe6; 56877497c49SRudolf Cornelissen buffer[33] = 0x28; 56977497c49SRudolf Cornelissen buffer[34] = 0x00; 57077497c49SRudolf Cornelissen 57177497c49SRudolf Cornelissen /* reset status */ 57277497c49SRudolf Cornelissen i2c_flag_error (-1); 57377497c49SRudolf Cornelissen 57477497c49SRudolf Cornelissen i2c_bstart(si->ps.tv_encoder.bus); 57577497c49SRudolf Cornelissen i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer)); 57677497c49SRudolf Cornelissen i2c_bstop(si->ps.tv_encoder.bus); 57777497c49SRudolf Cornelissen /* log on errors */ 57877497c49SRudolf Cornelissen stat = i2c_flag_error(0); 57977497c49SRudolf Cornelissen if (stat) 58077497c49SRudolf Cornelissen LOG(4,("Brooktree: I2C errors occurred while setting mode PAL720\n")); 58177497c49SRudolf Cornelissen 58277497c49SRudolf Cornelissen return stat; 58377497c49SRudolf Cornelissen }//end BT_init_PAL720. 58477497c49SRudolf Cornelissen 58577497c49SRudolf Cornelissen static uint8 BT_init_NTSC720() 586fb6cadf1Sshatty { 58777497c49SRudolf Cornelissen uint8 stat; 588fb6cadf1Sshatty 58977497c49SRudolf Cornelissen uint8 buffer[35]; 59077497c49SRudolf Cornelissen 5919a7218c5SRudolf Cornelissen LOG(4,("Brooktree: Setting NTSC 720x480 overscanning DVD mode\n")); 5929a7218c5SRudolf Cornelissen 5939a7218c5SRudolf Cornelissen buffer[0] = si->ps.tv_encoder.adress + WR; //issue I2C write command 59477497c49SRudolf Cornelissen buffer[1] = 0x76; //select first bt register to write to. 59577497c49SRudolf Cornelissen buffer[2] = 0xf0; //lsb h_clk_o: overscan comp = 0, so h_clk_o = 2 * h_clk_i (VSR=2 = scaling=1) 59677497c49SRudolf Cornelissen buffer[3] = 0xd0; //lsb h_active: h_active = 720 pixels wide port 59777497c49SRudolf Cornelissen buffer[4] = 0x83; //scope: OK hsync_width: (hsync_width / h_clk_o) * 63.55556uS = 4.70uS for NTSC 59877497c49SRudolf Cornelissen buffer[5] = 0x98; //scope: OK hburst_begin: (hburst_begin / h_clk_o) * 63.55556uS = 5.3uS for NTSC 59977497c49SRudolf Cornelissen buffer[6] = 0x5e; //scope: OK hburst_end: ((hburst_end + 128) / h_clk_o) * 63.55556uS = 7.94uS for NTSC 60077497c49SRudolf Cornelissen 60177497c49SRudolf Cornelissen //How to find the correct values for h_blank_o and v_blank_o: 60277497c49SRudolf Cornelissen // 1. Calculate h_blank_o according to initial setting guideline mentioned below; 60377497c49SRudolf Cornelissen // 2. Set v_blank_o in the neighbourhood of $18, so that TV picture does not have ghosts on right side in it while 60477497c49SRudolf Cornelissen // horizontal position is about OK; 60577497c49SRudolf Cornelissen // 3. Then tune h_blank_o for centered output on scope (look at front porch and back porch); 60677497c49SRudolf Cornelissen // 4. Now shift the TV output using Hsync_offset for centered output while looking at TV (in method 'SetBT_Hphase' above); 60777497c49SRudolf Cornelissen // 5. If no vertical shivering occurs when image is centered, you're done. Else: 60877497c49SRudolf Cornelissen // 6. Modify the RIVA (BeScreen) h_sync_start setting somewhat to get stable centered picture possible on TV AND!: 60977497c49SRudolf Cornelissen // 7. Make sure you update the Chrontel horizontal Phase setting also then! 61077497c49SRudolf Cornelissen 61177497c49SRudolf Cornelissen buffer[7] = 0x28; //scope: tuned. lsb h_blank_o: h_blank_o = horizontal viewport location on TV 61277497c49SRudolf Cornelissen //(guideline for initial setting: (h_blank_o / h_clk_0) * 63.55556uS = 9.5uS for NTSC) 61377497c49SRudolf Cornelissen buffer[8] = 0x18; //try-out; scope: checked against other modes, looks OK. v_blank_o: 1e active line ('pixel') 61477497c49SRudolf Cornelissen 61577497c49SRudolf Cornelissen buffer[9] = 0xf2; //v_active_o: = (active output lines + 2) / field (on TV) 61677497c49SRudolf Cornelissen buffer[10] = 0x26; //lsn = msn h_clk_o; 61777497c49SRudolf Cornelissen //b4-5 = msbits h_active; 61877497c49SRudolf Cornelissen //b7 = b8 v_avtive_o. 61977497c49SRudolf Cornelissen buffer[11] = 0x00; //h_fract is always 0. 62077497c49SRudolf Cornelissen buffer[12] = 0x78; //lsb h_clk_i: h_clk_i is horizontal total = 888. 62177497c49SRudolf Cornelissen buffer[13] = 0x90; //try-out; lsb h_blank_i: #clks between start sync and new line 1st pixel; copy to VGA delta-sync! 62277497c49SRudolf Cornelissen buffer[14] = 0x03; //b2-0 = msn h_clk_i; 62377497c49SRudolf Cornelissen //try-out: b3 = msn h_blank_i; 62477497c49SRudolf Cornelissen //b4 = vblankdly is always 0. 62577497c49SRudolf Cornelissen buffer[15] = 0x0d; //lsb v_lines_i: v_lines_i = 525 62677497c49SRudolf Cornelissen buffer[16] = 0x1a; //try-out; v_blank_i: #input lines between start sync and new line (pixel); copy to VGA delta-sync! 62777497c49SRudolf Cornelissen //Make sure though that this value for the BT is *even*, or image will shiver a *lot* horizontally on TV. 62877497c49SRudolf Cornelissen buffer[17] = 0xe0; //lsb v_active_i: v_active_i = 480 62977497c49SRudolf Cornelissen buffer[18] = 0x36; //b1-0 = msn v_lines_i; 63077497c49SRudolf Cornelissen //b3-2 = msn v_active_i; 63177497c49SRudolf Cornelissen //b5-4 = ylpf = 3; 63277497c49SRudolf Cornelissen //b7-6 = clpf = 0. 63377497c49SRudolf Cornelissen buffer[19] = 0x00; //lsb v_scale: v_scale = off = $1000 63477497c49SRudolf Cornelissen buffer[20] = 0x50; //b5-0 = msn v_scale; 63577497c49SRudolf Cornelissen //scope: tuned. b7-6 = msn h_blank_o. 63677497c49SRudolf Cornelissen //(((PLL_INT + (PLL_FRACT/65536)) / 6) * 13500000) = PIXEL_CLK = (hor.tot. * v_lines_i * 60Hz) 63777497c49SRudolf Cornelissen buffer[21] = 0x98; //lsb PLL fract: PLL fract = 0x6e98 63877497c49SRudolf Cornelissen buffer[22] = 0x6e; //msb PLL fract 63977497c49SRudolf Cornelissen buffer[23] = 0x8c; //b5-0 = PLL int: PLL int = 0x0c; 64077497c49SRudolf Cornelissen //b6 = by_pll: by_pll = 0; 64177497c49SRudolf Cornelissen //b7 = EN_XCLK: chip-pin CLKI is pixel clock. 64277497c49SRudolf Cornelissen buffer[24] = 0x0a; //b0 = ni_out is always 0; 64377497c49SRudolf Cornelissen //b1 = setup = 1 for NTSC; 64477497c49SRudolf Cornelissen //b2 = 625line = 0 for NTSC; 64577497c49SRudolf Cornelissen //b3 = vsync_dur = 1 for NTSC; 64677497c49SRudolf Cornelissen //b4 = dic_screset is always 0; 64777497c49SRudolf Cornelissen //b5 = pal_md = 0 for NTSC; 64877497c49SRudolf Cornelissen //b6 = eclip is always 0; 64977497c49SRudolf Cornelissen //b7 = reserved (en_scart) is always 0. 65077497c49SRudolf Cornelissen buffer[25] = 0xe5; //sync_amp $e5 for NTSC 65177497c49SRudolf Cornelissen buffer[26] = 0x75; //bst_amp $74-$76 for NTSC 65277497c49SRudolf Cornelissen buffer[27] = 0x78; //mcr: r-y $77-$79 for NTSC 65377497c49SRudolf Cornelissen buffer[28] = 0x44; //mcb: b-y $43-$44 for NTSC 65477497c49SRudolf Cornelissen buffer[29] = 0x85; //my: y $85 for NTSC 65577497c49SRudolf Cornelissen buffer[30] = 0x3c; //lsb msc: msc b31-0: NTSC formula: ((3579545 / pixelclk) * 2^32) = MSC 65677497c49SRudolf Cornelissen buffer[31] = 0x91; //msc = $20c2913c 65777497c49SRudolf Cornelissen buffer[32] = 0xc2; 65877497c49SRudolf Cornelissen buffer[33] = 0x20; //msb msc. 65977497c49SRudolf Cornelissen buffer[34] = 0x00; //phase_off always $00 66077497c49SRudolf Cornelissen 66177497c49SRudolf Cornelissen /* reset status */ 66277497c49SRudolf Cornelissen i2c_flag_error (-1); 66377497c49SRudolf Cornelissen 66477497c49SRudolf Cornelissen i2c_bstart(si->ps.tv_encoder.bus); 66577497c49SRudolf Cornelissen i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer)); 66677497c49SRudolf Cornelissen i2c_bstop(si->ps.tv_encoder.bus); 66777497c49SRudolf Cornelissen /* log on errors */ 66877497c49SRudolf Cornelissen stat = i2c_flag_error(0); 66977497c49SRudolf Cornelissen if (stat) 67077497c49SRudolf Cornelissen LOG(4,("Brooktree: I2C errors occurred while setting mode NTSC720\n")); 67177497c49SRudolf Cornelissen 67277497c49SRudolf Cornelissen return stat; 67377497c49SRudolf Cornelissen }//end BT_init_NTSC720. 67477497c49SRudolf Cornelissen 67577497c49SRudolf Cornelissen static uint8 BT_init_PAL800_OS() 676fb6cadf1Sshatty { 67777497c49SRudolf Cornelissen uint8 stat; 678fb6cadf1Sshatty 67977497c49SRudolf Cornelissen uint8 buffer[35]; 68077497c49SRudolf Cornelissen 6819a7218c5SRudolf Cornelissen LOG(4,("Brooktree: Setting PAL 800x600 overscanning VCD mode\n")); 6829a7218c5SRudolf Cornelissen 6839a7218c5SRudolf Cornelissen buffer[0] = si->ps.tv_encoder.adress + WR; //issue I2C write command 68477497c49SRudolf Cornelissen buffer[1] = 0x76; //select first bt register to write to. 68577497c49SRudolf Cornelissen buffer[2] = 0x60; //lsb h_clk_o: overscan comp = 0, so h_clk_o = 2 * h_clk_i (VSR=2 = scaling=1) 68677497c49SRudolf Cornelissen buffer[3] = 0x20; //lsb h_active: h_active = 800 pixels wide port 68777497c49SRudolf Cornelissen buffer[4] = 0x8b; //scope: OK hsync_width: (hsync_width / h_clk_o) * 64.0uS = 4.70uS for PAL 68877497c49SRudolf Cornelissen buffer[5] = 0xa5; //scope: OK hburst_begin: (hburst_begin / h_clk_o) * 64.0uS = 5.6uS for PAL 68977497c49SRudolf Cornelissen buffer[6] = 0x6b; //scope: OK hburst_end: ((hburst_end + 128) / h_clk_o) * 64.0uS = 7.97uS for PAL 69077497c49SRudolf Cornelissen 69177497c49SRudolf Cornelissen //How to find the correct values for h_blank_o and v_blank_o: 69277497c49SRudolf Cornelissen // 1. Calculate h_blank_o according to initial setting guideline mentioned below; 69377497c49SRudolf Cornelissen // 2. Set v_blank_o in the neighbourhood of $18, so that TV picture does not have ghosts on right side in it while 69477497c49SRudolf Cornelissen // horizontal position is about OK; 69577497c49SRudolf Cornelissen // 3. Then tune h_blank_o for centered output on scope (look at front porch and back porch); 69677497c49SRudolf Cornelissen // 4. Now shift the TV output using Hsync_offset for centered output while looking at TV (in method 'SetBT_Hphase' above); 69777497c49SRudolf Cornelissen // 5. If no vertical shivering occurs when image is centered, you're done. Else: 69877497c49SRudolf Cornelissen // 6. Modify the RIVA (BeScreen) h_sync_start setting somewhat to get stable centered picture possible on TV AND!: 69977497c49SRudolf Cornelissen // 7. Make sure you update the Chrontel horizontal Phase setting also then! 70077497c49SRudolf Cornelissen 70177497c49SRudolf Cornelissen if (si->ps.tv_encoder.type >= CX25870)//set CX value 702fb6cadf1Sshatty { 70377497c49SRudolf Cornelissen buffer[7] = 0xf4; 70477497c49SRudolf Cornelissen buffer[8] = 0x17; 705fb6cadf1Sshatty } 706fb6cadf1Sshatty else 70777497c49SRudolf Cornelissen { //set BT value 70877497c49SRudolf Cornelissen buffer[7] = 0xc0;//scope: tuned. lsb h_blank_o: h_blank_o = horizontal viewport location on TV 70977497c49SRudolf Cornelissen //(guideline for initial setting: (h_blank_o / h_clk_0) * 64.0uS = 10.0uS for PAL) 71077497c49SRudolf Cornelissen buffer[8] = 0x18;//try-out; scope: checked against other modes, looks OK. v_blank_o: 1e active line ('pixel') 71177497c49SRudolf Cornelissen } 71277497c49SRudolf Cornelissen 71377497c49SRudolf Cornelissen buffer[9] = 0x2e; //v_active_o: = (active output lines + 2) / field (on TV) 71477497c49SRudolf Cornelissen buffer[10] = 0xb7; //lsn = msn h_clk_o; 71577497c49SRudolf Cornelissen //b4-5 = msbits h_active; 71677497c49SRudolf Cornelissen //b7 = b8 v_avtive_o. 71777497c49SRudolf Cornelissen buffer[11] = 0x00; //h_fract is always 0. 71877497c49SRudolf Cornelissen buffer[12] = 0xb0; //lsb h_clk_i: h_clk_i is horizontal total = 944. 71977497c49SRudolf Cornelissen 72077497c49SRudolf Cornelissen if (si->ps.tv_encoder.type >= CX25870)//set CX value 72177497c49SRudolf Cornelissen buffer[13] = 0x20; 72277497c49SRudolf Cornelissen else //set BT value 72377497c49SRudolf Cornelissen buffer[13] = 0x14;//try-out; lsb h_blank_i: #clks between start sync and new line 1st pixel; copy to VGA delta-sync! 72477497c49SRudolf Cornelissen 72577497c49SRudolf Cornelissen buffer[14] = 0x03; //b2-0 = msn h_clk_i; 72677497c49SRudolf Cornelissen //try-out: b3 = msn h_blank_i; 72777497c49SRudolf Cornelissen //b4 = vblankdly is always 0. 72877497c49SRudolf Cornelissen buffer[15] = 0x71; //lsb v_lines_i: v_lines_i = 625 72977497c49SRudolf Cornelissen 73077497c49SRudolf Cornelissen if (si->ps.tv_encoder.type >= CX25870)//set CX value 73177497c49SRudolf Cornelissen buffer[16] = 0x08; 73277497c49SRudolf Cornelissen else //set BT value 73377497c49SRudolf Cornelissen buffer[16] = 0x2a;//try-out; v_blank_i: #input lines between start sync and new line (pixel); copy to VGA delta-sync! 73477497c49SRudolf Cornelissen //Make sure though that this value for the BT is *even*, or image will shiver a *lot* horizontally on TV. 73577497c49SRudolf Cornelissen 73677497c49SRudolf Cornelissen buffer[17] = 0x58; //lsb v_active_i: v_active_i = 600 73777497c49SRudolf Cornelissen buffer[18] = 0x3a; //b1-0 = msn v_lines_i; 73877497c49SRudolf Cornelissen //b3-2 = msn v_active_i; 73977497c49SRudolf Cornelissen //b5-4 = ylpf = 3; 74077497c49SRudolf Cornelissen //b7-6 = clpf = 0. 74177497c49SRudolf Cornelissen buffer[19] = 0x00; //lsb v_scale: v_scale = off = $1000 74277497c49SRudolf Cornelissen buffer[20] = 0x10; //b5-0 = msn v_scale; 74377497c49SRudolf Cornelissen //scope: tuned. b7-6 = msn h_blank_o. 74477497c49SRudolf Cornelissen //(((PLL_INT + (PLL_FRACT/65536)) / 6) * 13500000) = PIXEL_CLK = (hor.tot. * v_lines_i * 50Hz) 74577497c49SRudolf Cornelissen buffer[21] = 0x72; //lsb PLL fract: PLL fract = 0x1c72 74677497c49SRudolf Cornelissen buffer[22] = 0x1c; //msb PLL fract 74777497c49SRudolf Cornelissen buffer[23] = 0x8d; //b5-0 = PLL int: PLL int = 0x0d; 74877497c49SRudolf Cornelissen //b6 = by_pll: by_pll = 0; 74977497c49SRudolf Cornelissen //b7 = EN_XCLK: chip-pin CLKI is pixel clock. 75077497c49SRudolf Cornelissen buffer[24] = 0x24; //b0 = ni_out is always 0; 75177497c49SRudolf Cornelissen //b1 = setup = 0 for PAL; 75277497c49SRudolf Cornelissen //b2 = 625line = 1 for PAL; 75377497c49SRudolf Cornelissen //b3 = vsync_dur = 0 for PAL; 75477497c49SRudolf Cornelissen //b4 = dic_screset is always 0; 75577497c49SRudolf Cornelissen //b5 = pal_md = 1 for PAL; 75677497c49SRudolf Cornelissen //b6 = eclip is always 0; 75777497c49SRudolf Cornelissen //b7 = reserved (en_scart) is always 0. 75877497c49SRudolf Cornelissen buffer[25] = 0xf0; //sync_amp $f0 for PAL 75977497c49SRudolf Cornelissen buffer[26] = 0x57; //bst_amp $57-$58 for PAL 76077497c49SRudolf Cornelissen buffer[27] = 0x80; //mcr: r-y $80-$81 for PAL 76177497c49SRudolf Cornelissen buffer[28] = 0x48; //mcb: b-y $48-$49 for PAL 76277497c49SRudolf Cornelissen buffer[29] = 0x8c; //my: y $8c for PAL 76377497c49SRudolf Cornelissen buffer[30] = 0x31; //lsb msc: msc b31-0: PAL formula: ((4433619 / pixelclk) * 2^32) = MSC 76477497c49SRudolf Cornelissen buffer[31] = 0x8c; //msc = $26798c31 76577497c49SRudolf Cornelissen buffer[32] = 0x79; 76677497c49SRudolf Cornelissen buffer[33] = 0x26; //msb msc. 76777497c49SRudolf Cornelissen buffer[34] = 0x00; //phase_off always $00 76877497c49SRudolf Cornelissen 76977497c49SRudolf Cornelissen /* reset status */ 77077497c49SRudolf Cornelissen i2c_flag_error (-1); 77177497c49SRudolf Cornelissen 77277497c49SRudolf Cornelissen i2c_bstart(si->ps.tv_encoder.bus); 77377497c49SRudolf Cornelissen i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer)); 77477497c49SRudolf Cornelissen i2c_bstop(si->ps.tv_encoder.bus); 77577497c49SRudolf Cornelissen /* log on errors */ 77677497c49SRudolf Cornelissen stat = i2c_flag_error(0); 77777497c49SRudolf Cornelissen if (stat) 77877497c49SRudolf Cornelissen LOG(4,("Brooktree: I2C errors occurred while setting mode PAL800 OS\n")); 77977497c49SRudolf Cornelissen 78077497c49SRudolf Cornelissen return stat; 78177497c49SRudolf Cornelissen }//end BT_init_PAL800_OS. 78277497c49SRudolf Cornelissen 78377497c49SRudolf Cornelissen static uint8 BT_init_NTSC640_OS() 784fb6cadf1Sshatty { 78577497c49SRudolf Cornelissen uint8 stat; 786fb6cadf1Sshatty 78777497c49SRudolf Cornelissen uint8 buffer[35]; 788fb6cadf1Sshatty 7899a7218c5SRudolf Cornelissen LOG(4,("Brooktree: Setting NTSC 640x480 overscanning VCD mode\n")); 7909a7218c5SRudolf Cornelissen 7919a7218c5SRudolf Cornelissen buffer[0] = si->ps.tv_encoder.adress + WR; //issue I2C write command 79277497c49SRudolf Cornelissen buffer[1] = 0x76; //select first bt register to write to. 79377497c49SRudolf Cornelissen buffer[2] = 0x20; //lsb h_clk_o: overscan comp = 0, so h_clk_o = 2 * h_clk_i (VSR=2 = scaling=1) 79477497c49SRudolf Cornelissen buffer[3] = 0x80; //lsb h_active: h_active = 640 pixels wide port 79577497c49SRudolf Cornelissen buffer[4] = 0x74; //scope: OK hsync_width: (hsync_width / h_clk_o) * 63.55556uS = 4.70uS for NTSC 79677497c49SRudolf Cornelissen buffer[5] = 0x83; //scope: OK hburst_begin: (hburst_begin / h_clk_o) * 63.55556uS = 5.3uS for NTSC 79777497c49SRudolf Cornelissen buffer[6] = 0x44; //scope: OK hburst_end: ((hburst_end + 128) / h_clk_o) * 63.55556uS = 7.94uS for NTSC 798fb6cadf1Sshatty 79977497c49SRudolf Cornelissen //How to find the correct values for h_blank_o and v_blank_o: 80077497c49SRudolf Cornelissen // 1. Calculate h_blank_o according to initial setting guideline mentioned below; 80177497c49SRudolf Cornelissen // 2. Set v_blank_o in the neighbourhood of $18, so that TV picture does not have ghosts on right side in it while 80277497c49SRudolf Cornelissen // horizontal position is about OK; 80377497c49SRudolf Cornelissen // 3. Then tune h_blank_o for centered output on scope (look at front porch and back porch); 80477497c49SRudolf Cornelissen // 4. Now shift the TV output using Hsync_offset for centered output while looking at TV (in method 'SetBT_Hphase' above); 80577497c49SRudolf Cornelissen // 5. If no vertical shivering occurs when image is centered, you're done. Else: 80677497c49SRudolf Cornelissen // 6. Modify the RIVA (BeScreen) h_sync_start setting somewhat to get stable centered picture possible on TV AND!: 80777497c49SRudolf Cornelissen // 7. Make sure you update the Chrontel horizontal Phase setting also then! 808fb6cadf1Sshatty 80977497c49SRudolf Cornelissen buffer[7] = 0xf7; //scope: tuned. lsb h_blank_o: h_blank_o = horizontal viewport location on TV: 81077497c49SRudolf Cornelissen //(guideline for initial setting: (h_blank_o / h_clk_0) * 63.55556uS = 9.5uS for NTSC) 811fb6cadf1Sshatty 81277497c49SRudolf Cornelissen if (si->ps.tv_encoder.type >= CX25870)//set CX value 81377497c49SRudolf Cornelissen buffer[8] = 0x1d; 81477497c49SRudolf Cornelissen else //set BT value 81577497c49SRudolf Cornelissen buffer[8] = 0x1c;//try-out; scope: checked against other modes, looks OK. v_blank_o: 1e active line ('pixel') 816fb6cadf1Sshatty 81777497c49SRudolf Cornelissen buffer[9] = 0xf2; //v_active_o: = (active output lines + 2) / field (on TV) 81877497c49SRudolf Cornelissen buffer[10] = 0x26; //lsn = msn h_clk_o; 81977497c49SRudolf Cornelissen //b4-5 = msbits h_active; 82077497c49SRudolf Cornelissen //b7 = b8 v_avtive_o. 82177497c49SRudolf Cornelissen buffer[11] = 0x00; //h_fract is always 0. 82277497c49SRudolf Cornelissen buffer[12] = 0x10; //lsb h_clk_i: h_clk_i is horizontal total = 784. 82377497c49SRudolf Cornelissen buffer[13] = 0x14; //try-out; lsb h_blank_i: #clks between start sync and new line 1st pixel; copy to VGA delta-sync! 82477497c49SRudolf Cornelissen buffer[14] = 0x03; //b2-0 = msn h_clk_i; 82577497c49SRudolf Cornelissen //try-out: b3 = msn h_blank_i; 82677497c49SRudolf Cornelissen //b4 = vblankdly is always 0. 82777497c49SRudolf Cornelissen buffer[15] = 0x0d; //lsb v_lines_i: v_lines_i = 525 82877497c49SRudolf Cornelissen buffer[16] = 0x18; //try-out; v_blank_i: #input lines between start sync and new line (pixel); copy to VGA delta-sync! 82977497c49SRudolf Cornelissen //Make sure though that this value for the BT is *even*, or image will shiver a *lot* horizontally on TV. 83077497c49SRudolf Cornelissen buffer[17] = 0xe0; //lsb v_active_i: v_active_i = 480 83177497c49SRudolf Cornelissen buffer[18] = 0x36; //b1-0 = msn v_lines_i; 83277497c49SRudolf Cornelissen //b3-2 = msn v_active_i; 83377497c49SRudolf Cornelissen //b5-4 = ylpf = 3; 83477497c49SRudolf Cornelissen //b7-6 = clpf = 0. 83577497c49SRudolf Cornelissen buffer[19] = 0x00; //lsb v_scale: v_scale = off = $1000 83677497c49SRudolf Cornelissen buffer[20] = 0x10; //b5-0 = msn v_scale; 83777497c49SRudolf Cornelissen //scope: tuned. b7-6 = msn h_blank_o. 83877497c49SRudolf Cornelissen //(((PLL_INT + (PLL_FRACT/65536)) / 6) * 13500000) = PIXEL_CLK = (hor.tot. * v_lines_i * 60Hz) 83977497c49SRudolf Cornelissen buffer[21] = 0xdb; //lsb PLL fract: PLL fract = 0xf9db 84077497c49SRudolf Cornelissen buffer[22] = 0xf9; //msb PLL fract 84177497c49SRudolf Cornelissen buffer[23] = 0x8a; //b5-0 = PLL int: PLL int = 0x0a; 84277497c49SRudolf Cornelissen //b6 = by_pll: by_pll = 0; 84377497c49SRudolf Cornelissen //b7 = EN_XCLK: chip-pin CLKI is pixel clock. 84477497c49SRudolf Cornelissen buffer[24] = 0x0a; //b0 = ni_out is always 0; 84577497c49SRudolf Cornelissen //b1 = setup = 1 for NTSC; 84677497c49SRudolf Cornelissen //b2 = 625line = 0 for NTSC; 84777497c49SRudolf Cornelissen //b3 = vsync_dur = 1 for NTSC; 84877497c49SRudolf Cornelissen //b4 = dic_screset is always 0; 84977497c49SRudolf Cornelissen //b5 = pal_md = 0 for NTSC; 85077497c49SRudolf Cornelissen //b6 = eclip is always 0; 85177497c49SRudolf Cornelissen //b7 = reserved (en_scart) is always 0. 85277497c49SRudolf Cornelissen buffer[25] = 0xe5; //sync_amp $e5 for NTSC 85377497c49SRudolf Cornelissen buffer[26] = 0x75; //bst_amp $74-$76 for NTSC 85477497c49SRudolf Cornelissen buffer[27] = 0x78; //mcr: r-y $77-$79 for NTSC 85577497c49SRudolf Cornelissen buffer[28] = 0x44; //mcb: b-y $43-$44 for NTSC 85677497c49SRudolf Cornelissen buffer[29] = 0x85; //my: y $85 for NTSC 85777497c49SRudolf Cornelissen buffer[30] = 0x37; //lsb msc: msc b31-0: NTSC formula: ((3579545 / pixelclk) * 2^32) = MSC 85877497c49SRudolf Cornelissen buffer[31] = 0x12; //msc = $251b1237 85977497c49SRudolf Cornelissen buffer[32] = 0x1b; 86077497c49SRudolf Cornelissen buffer[33] = 0x25; //msb msc. 86177497c49SRudolf Cornelissen buffer[34] = 0x00; //phase_off always $00 862fb6cadf1Sshatty 86377497c49SRudolf Cornelissen /* reset status */ 86477497c49SRudolf Cornelissen i2c_flag_error (-1); 865fb6cadf1Sshatty 86677497c49SRudolf Cornelissen i2c_bstart(si->ps.tv_encoder.bus); 86777497c49SRudolf Cornelissen i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer)); 86877497c49SRudolf Cornelissen i2c_bstop(si->ps.tv_encoder.bus); 86977497c49SRudolf Cornelissen /* log on errors */ 87077497c49SRudolf Cornelissen stat = i2c_flag_error(0); 87177497c49SRudolf Cornelissen if (stat) 87277497c49SRudolf Cornelissen LOG(4,("Brooktree: I2C errors occurred while setting mode NTSC640 OS\n")); 873fb6cadf1Sshatty 87477497c49SRudolf Cornelissen return stat; 87577497c49SRudolf Cornelissen }//end BT_init_NTSC640_OS. 876fb6cadf1Sshatty 87721f6ecabSRudolf Cornelissen static uint8 BT_testsignal(void) 87821f6ecabSRudolf Cornelissen { 87921f6ecabSRudolf Cornelissen uint8 stat; 88021f6ecabSRudolf Cornelissen 88121f6ecabSRudolf Cornelissen uint8 buffer[3]; 88221f6ecabSRudolf Cornelissen 8839a7218c5SRudolf Cornelissen LOG(4,("Brooktree: Enabling testsignal\n")); 8849a7218c5SRudolf Cornelissen 88521f6ecabSRudolf Cornelissen buffer[0] = si->ps.tv_encoder.adress + WR; 88621f6ecabSRudolf Cornelissen /* select bt register for enabling colorbars and outputs */ 88721f6ecabSRudolf Cornelissen buffer[1] = 0xc4; 88821f6ecabSRudolf Cornelissen /* issue the actual command */ 88921f6ecabSRudolf Cornelissen buffer[2] = 0x05; 89021f6ecabSRudolf Cornelissen 89121f6ecabSRudolf Cornelissen /* reset status */ 89221f6ecabSRudolf Cornelissen i2c_flag_error (-1); 89321f6ecabSRudolf Cornelissen 89421f6ecabSRudolf Cornelissen i2c_bstart(si->ps.tv_encoder.bus); 89521f6ecabSRudolf Cornelissen i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer)); 89621f6ecabSRudolf Cornelissen i2c_bstop(si->ps.tv_encoder.bus); 89721f6ecabSRudolf Cornelissen /* log on errors */ 89821f6ecabSRudolf Cornelissen stat = i2c_flag_error(0); 89921f6ecabSRudolf Cornelissen if (stat) 90021f6ecabSRudolf Cornelissen LOG(4,("Brooktree: I2C errors occurred while setting up flickerfilter and outputs\n")); 90121f6ecabSRudolf Cornelissen 90221f6ecabSRudolf Cornelissen return stat; 90321f6ecabSRudolf Cornelissen }//end BT_testsignal. 90421f6ecabSRudolf Cornelissen 90521f6ecabSRudolf Cornelissen static uint8 BT_setup_output(uint8 monstat, uint8 output, uint8 ffilter) 90621f6ecabSRudolf Cornelissen { 90721f6ecabSRudolf Cornelissen uint8 stat; 90821f6ecabSRudolf Cornelissen 90921f6ecabSRudolf Cornelissen uint8 buffer[7]; 91021f6ecabSRudolf Cornelissen 91121f6ecabSRudolf Cornelissen buffer[0] = si->ps.tv_encoder.adress + WR; 91221f6ecabSRudolf Cornelissen /* select first TV config register to write */ 91321f6ecabSRudolf Cornelissen buffer[1] = 0xc6; 91421f6ecabSRudolf Cornelissen /* input is 24bit mpx'd RGB, BLANK = out, sync = act. hi */ 91521f6ecabSRudolf Cornelissen buffer[2] = 0x98; 91621f6ecabSRudolf Cornelissen /* disable all filters, exept flicker filter */ 91721f6ecabSRudolf Cornelissen buffer[3] = 0x98; 91821f6ecabSRudolf Cornelissen if (!ffilter) 91921f6ecabSRudolf Cornelissen { 92021f6ecabSRudolf Cornelissen /* disable flicker filter */ 92121f6ecabSRudolf Cornelissen buffer[3] = 0xc0; 9229a7218c5SRudolf Cornelissen LOG(4,("Brooktree: Disabling flickerfilter\n")); 92321f6ecabSRudolf Cornelissen } 9249a7218c5SRudolf Cornelissen else 9259a7218c5SRudolf Cornelissen LOG(4,("Brooktree: Enabling flickerfilter\n")); 9269a7218c5SRudolf Cornelissen 92721f6ecabSRudolf Cornelissen /* (disable filters) */ 92821f6ecabSRudolf Cornelissen buffer[4] = 0xc0; 92921f6ecabSRudolf Cornelissen /* (disable filters) */ 93021f6ecabSRudolf Cornelissen buffer[5] = 0xc0; 93121f6ecabSRudolf Cornelissen switch (output) 93221f6ecabSRudolf Cornelissen /* Description of ELSA Erazor III hardware layout: 93321f6ecabSRudolf Cornelissen * (This is the default (recommended) layout by NVIDIA) 93421f6ecabSRudolf Cornelissen * DAC A = CVBS 93521f6ecabSRudolf Cornelissen * DAC B = C (chrominance) 93621f6ecabSRudolf Cornelissen * DAC C = Y (luminance) */ 93721f6ecabSRudolf Cornelissen 93821f6ecabSRudolf Cornelissen /* Description of Diamond VIPER550: 93921f6ecabSRudolf Cornelissen * DAC A = Not connected 94021f6ecabSRudolf Cornelissen * DAC B = C (chrominance) 94121f6ecabSRudolf Cornelissen * DAC C = Y (luminance) 94221f6ecabSRudolf Cornelissen * To be able to connect to CVBS TV's a special cable is supplied: 94321f6ecabSRudolf Cornelissen * This cable connects the Y (DAC C) output to the TV CVBS input. */ 94421f6ecabSRudolf Cornelissen { 9459a7218c5SRudolf Cornelissen case 1: 9469a7218c5SRudolf Cornelissen LOG(4,("Brooktree: Outputting both Y/C and CVBS where supported by hardware\n")); 9479a7218c5SRudolf Cornelissen buffer[6] = 0x18; // Y/C and CVBS out if all ports implemented 94821f6ecabSRudolf Cornelissen // in hardware, else only Y/C or CVBS out. 94921f6ecabSRudolf Cornelissen break; 9509a7218c5SRudolf Cornelissen case 2: 9519a7218c5SRudolf Cornelissen LOG(4,("Brooktree: Outputting CVBS on all outputs\n")); 9529a7218c5SRudolf Cornelissen buffer[6] = 0x00; // put CVBS on all outputs. Used for cards 95321f6ecabSRudolf Cornelissen break; // with only Y/C out and 'translation cable'. 9549a7218c5SRudolf Cornelissen default: 9559a7218c5SRudolf Cornelissen LOG(4,("Brooktree: Outputting signals according to autodetect status\n")); 9569a7218c5SRudolf Cornelissen switch (monstat) // only 'autodetect' remains... 95721f6ecabSRudolf Cornelissen { 9589a7218c5SRudolf Cornelissen case 1: 9599a7218c5SRudolf Cornelissen buffer[6] = 0x00; //only Y connected: must be CVBS! 96021f6ecabSRudolf Cornelissen break; 9619a7218c5SRudolf Cornelissen case 2: 9629a7218c5SRudolf Cornelissen buffer[6] = 0x00; //only C connected: must be CVBS! 96321f6ecabSRudolf Cornelissen break; //(though cable is wired wrong...) 9649a7218c5SRudolf Cornelissen case 5: 9659a7218c5SRudolf Cornelissen buffer[6] = 0x00; //CVBS and only Y connected: 2x CVBS! 96621f6ecabSRudolf Cornelissen break; //(officially not supported...) 9679a7218c5SRudolf Cornelissen case 6: 9689a7218c5SRudolf Cornelissen buffer[6] = 0x00; //CVBS and only C connected: 2x CVBS! 96921f6ecabSRudolf Cornelissen break; //(officially not supported...) 9709a7218c5SRudolf Cornelissen default: 9719a7218c5SRudolf Cornelissen buffer[6] = 0x18; //nothing, or 97221f6ecabSRudolf Cornelissen //Y/C only, or 97321f6ecabSRudolf Cornelissen //CVBS only (but on CVBS output), or 97421f6ecabSRudolf Cornelissen //Y/C and CVBS connected: 97521f6ecabSRudolf Cornelissen //So activate recommended signals. 97621f6ecabSRudolf Cornelissen } 97721f6ecabSRudolf Cornelissen } 97821f6ecabSRudolf Cornelissen 97921f6ecabSRudolf Cornelissen /* reset status */ 98021f6ecabSRudolf Cornelissen i2c_flag_error (-1); 98121f6ecabSRudolf Cornelissen 98221f6ecabSRudolf Cornelissen i2c_bstart(si->ps.tv_encoder.bus); 98321f6ecabSRudolf Cornelissen i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer)); 98421f6ecabSRudolf Cornelissen i2c_bstop(si->ps.tv_encoder.bus); 98521f6ecabSRudolf Cornelissen /* log on errors */ 98621f6ecabSRudolf Cornelissen stat = i2c_flag_error(0); 98721f6ecabSRudolf Cornelissen if (stat) 98821f6ecabSRudolf Cornelissen LOG(4,("Brooktree: I2C errors occurred while setting up flickerfilter and outputs\n")); 98921f6ecabSRudolf Cornelissen 99021f6ecabSRudolf Cornelissen return stat; 99121f6ecabSRudolf Cornelissen }//end BT_setup_output. 99221f6ecabSRudolf Cornelissen 99321f6ecabSRudolf Cornelissen static uint8 BT_setup_hphase(uint8 mode) 99421f6ecabSRudolf Cornelissen { 99521f6ecabSRudolf Cornelissen uint8 stat, hoffset; 99621f6ecabSRudolf Cornelissen 99721f6ecabSRudolf Cornelissen uint8 buffer[7]; 99821f6ecabSRudolf Cornelissen 9999a7218c5SRudolf Cornelissen LOG(4,("Brooktree: Tuning horizontal phase\n")); 10009a7218c5SRudolf Cornelissen 100121f6ecabSRudolf Cornelissen /* CX needs timing reset (advised on BT also), first 1mS delay needed! */ 100221f6ecabSRudolf Cornelissen snooze(1000); 100321f6ecabSRudolf Cornelissen 100421f6ecabSRudolf Cornelissen /* values below are all tested on TNT1, TNT2 and GeForce2MX */ 100521f6ecabSRudolf Cornelissen buffer[0] = si->ps.tv_encoder.adress + WR; 100621f6ecabSRudolf Cornelissen /* select first TV output timing register to write */ 100721f6ecabSRudolf Cornelissen buffer[1] = 0x6c; 100821f6ecabSRudolf Cornelissen /* turn on active video & generate timing reset on CX chips! */ 100921f6ecabSRudolf Cornelissen buffer[2] = 0x86; 101021f6ecabSRudolf Cornelissen /* (set fail save values...) */ 101121f6ecabSRudolf Cornelissen buffer[3] = 0x00; //set default horizontal sync offset 101221f6ecabSRudolf Cornelissen buffer[4] = 0x02; //set default horizontal sync width 101321f6ecabSRudolf Cornelissen buffer[5] = 0x00; //set default vertical sync offset 101421f6ecabSRudolf Cornelissen 101521f6ecabSRudolf Cornelissen /* do specific timing setup for all chips and modes: */ 101621f6ecabSRudolf Cornelissen hoffset = 8; //TNT2 and TNT2 M64...(8 pixels delayed hpos, 101721f6ecabSRudolf Cornelissen //so picture more to the right) 101821f6ecabSRudolf Cornelissen //fixme: check this out... 101921f6ecabSRudolf Cornelissen // if (ddata->type == 1) hoffset = 0; //TNT1 or GeForce2... (std hpos) 102021f6ecabSRudolf Cornelissen //NOTE: It might be that GeForce needs TNT2 offset: 102121f6ecabSRudolf Cornelissen //for now CX chips get seperate extra offset, until sure. 102221f6ecabSRudolf Cornelissen //(CX is only found AFAIK on GeForce cards, no BT tested 102321f6ecabSRudolf Cornelissen // on GeForce yet. CH was tested on GeForce and seemed to 102421f6ecabSRudolf Cornelissen // indicate TNT1 offset was needed.) 102521f6ecabSRudolf Cornelissen 102621f6ecabSRudolf Cornelissen switch (mode) 102721f6ecabSRudolf Cornelissen { 102821f6ecabSRudolf Cornelissen case NTSC640_TST: 102921f6ecabSRudolf Cornelissen case NTSC640: 103021f6ecabSRudolf Cornelissen if (si->ps.tv_encoder.type >= CX25870) hoffset +=8; //if CX shift picture right some more... 103121f6ecabSRudolf Cornelissen buffer[3] = (0x25 + hoffset); //set horizontal sync offset 103221f6ecabSRudolf Cornelissen break; 103321f6ecabSRudolf Cornelissen case NTSC800: 103421f6ecabSRudolf Cornelissen if (si->ps.tv_encoder.type >= CX25870) hoffset +=8; //if CX shift picture right some more... 103521f6ecabSRudolf Cornelissen buffer[3] = (0xe1 + hoffset); //set horizontal sync offset 103621f6ecabSRudolf Cornelissen buffer[4] = 0xc2; 103721f6ecabSRudolf Cornelissen //Vsync offset reg. does not exist on CX: mode is checked and OK. 103821f6ecabSRudolf Cornelissen buffer[5] = 0x40; //set VSync offset (on BT's only) 103921f6ecabSRudolf Cornelissen break; 104021f6ecabSRudolf Cornelissen case PAL640: 104121f6ecabSRudolf Cornelissen if (si->ps.tv_encoder.type >= CX25870) hoffset +=8; //if CX shift picture right some more... 104221f6ecabSRudolf Cornelissen buffer[3] = (0xa8 + hoffset); 104321f6ecabSRudolf Cornelissen break; 104421f6ecabSRudolf Cornelissen case PAL800_TST: 104521f6ecabSRudolf Cornelissen case PAL800: 104621f6ecabSRudolf Cornelissen if (si->ps.tv_encoder.type >= CX25870) hoffset +=8; //if CX shift picture right some more... 104721f6ecabSRudolf Cornelissen buffer[3] = (0x2c + hoffset); 104821f6ecabSRudolf Cornelissen break; 104921f6ecabSRudolf Cornelissen case NTSC720: 105021f6ecabSRudolf Cornelissen if (si->ps.tv_encoder.type >= CX25870) 105121f6ecabSRudolf Cornelissen buffer[3] = (0xb2 + hoffset); //set horizontal sync offset CX 105221f6ecabSRudolf Cornelissen else 105321f6ecabSRudolf Cornelissen buffer[3] = (0xd0 + hoffset); //set horizontal sync offset BT 105421f6ecabSRudolf Cornelissen buffer[4] = 0xff; //hsync width = max: 105521f6ecabSRudolf Cornelissen break; //to prevent vertical image 'shivering'. 105621f6ecabSRudolf Cornelissen case PAL720: 105721f6ecabSRudolf Cornelissen buffer[3] = (0xd4 + hoffset); 105821f6ecabSRudolf Cornelissen buffer[4] = 0xff; 105921f6ecabSRudolf Cornelissen break; 106021f6ecabSRudolf Cornelissen case NTSC640_OS: 106121f6ecabSRudolf Cornelissen buffer[3] = (0xc8 + hoffset); 106221f6ecabSRudolf Cornelissen buffer[4] = 0xff; 106321f6ecabSRudolf Cornelissen break; 106421f6ecabSRudolf Cornelissen case PAL800_OS: 106521f6ecabSRudolf Cornelissen if (si->ps.tv_encoder.type >= CX25870) 106621f6ecabSRudolf Cornelissen buffer[3] = (0x78 + hoffset); //set horizontal sync offset CX 106721f6ecabSRudolf Cornelissen else 106821f6ecabSRudolf Cornelissen buffer[3] = (0xc4 + hoffset); //set horizontal sync offset BT 106921f6ecabSRudolf Cornelissen buffer[4] = 0xff; 107021f6ecabSRudolf Cornelissen break; 107121f6ecabSRudolf Cornelissen default: //nothing to be done here... 107221f6ecabSRudolf Cornelissen break; 107321f6ecabSRudolf Cornelissen } 107421f6ecabSRudolf Cornelissen 107521f6ecabSRudolf Cornelissen buffer[6] = 0x01; //set default vertical sync width 107621f6ecabSRudolf Cornelissen 107721f6ecabSRudolf Cornelissen /* reset status */ 107821f6ecabSRudolf Cornelissen i2c_flag_error (-1); 107921f6ecabSRudolf Cornelissen 108021f6ecabSRudolf Cornelissen i2c_bstart(si->ps.tv_encoder.bus); 108121f6ecabSRudolf Cornelissen i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer)); 108221f6ecabSRudolf Cornelissen i2c_bstop(si->ps.tv_encoder.bus); 108321f6ecabSRudolf Cornelissen /* log on errors */ 108421f6ecabSRudolf Cornelissen stat = i2c_flag_error(0); 108521f6ecabSRudolf Cornelissen if (stat) 108621f6ecabSRudolf Cornelissen LOG(4,("Brooktree: I2C errors occurred while setting up h_phase\n")); 108721f6ecabSRudolf Cornelissen 108821f6ecabSRudolf Cornelissen return stat; 108921f6ecabSRudolf Cornelissen }//end BT_setup_hphase. 109021f6ecabSRudolf Cornelissen 109121f6ecabSRudolf Cornelissen static uint8 BT_read_monstat(uint8* monstat) 109221f6ecabSRudolf Cornelissen { 109321f6ecabSRudolf Cornelissen uint8 stat; 109421f6ecabSRudolf Cornelissen uint8 buffer[3]; 109521f6ecabSRudolf Cornelissen 1096efe9c7a6SRudolf Cornelissen /* make sure we have the recommended failsafe selected */ 1097efe9c7a6SRudolf Cornelissen *monstat = 0; 1098efe9c7a6SRudolf Cornelissen 10999a7218c5SRudolf Cornelissen LOG(4,("Brooktree: Autodetecting connected output devices\n")); 11009a7218c5SRudolf Cornelissen 110121f6ecabSRudolf Cornelissen /* set BT to return connection status in ESTATUS on next read CMD: */ 110221f6ecabSRudolf Cornelissen buffer[0] = si->ps.tv_encoder.adress + WR; 110321f6ecabSRudolf Cornelissen /* set ESTATUS at b'01' (return conn.stat.) */ 110421f6ecabSRudolf Cornelissen buffer[1] = 0xc4; 110521f6ecabSRudolf Cornelissen /* and leave chip outputs on. */ 110621f6ecabSRudolf Cornelissen buffer[2] = 0x41; 110721f6ecabSRudolf Cornelissen 110821f6ecabSRudolf Cornelissen /* reset status */ 110921f6ecabSRudolf Cornelissen i2c_flag_error (-1); 111021f6ecabSRudolf Cornelissen 111121f6ecabSRudolf Cornelissen i2c_bstart(si->ps.tv_encoder.bus); 111221f6ecabSRudolf Cornelissen i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer)); 111321f6ecabSRudolf Cornelissen i2c_bstop(si->ps.tv_encoder.bus); 111421f6ecabSRudolf Cornelissen /* log on errors */ 111521f6ecabSRudolf Cornelissen stat = i2c_flag_error(0); 111621f6ecabSRudolf Cornelissen if (stat) 111721f6ecabSRudolf Cornelissen { 111821f6ecabSRudolf Cornelissen LOG(4,("Brooktree: I2C errors occurred while reading connection status (1)\n")); 111921f6ecabSRudolf Cornelissen return stat; 112021f6ecabSRudolf Cornelissen } 112121f6ecabSRudolf Cornelissen 112221f6ecabSRudolf Cornelissen /* do actual read connection status: */ 112321f6ecabSRudolf Cornelissen buffer[0] = si->ps.tv_encoder.adress + WR; 112421f6ecabSRudolf Cornelissen /* select register with CHECK_STAT CMD */ 112521f6ecabSRudolf Cornelissen buffer[1] = 0xba; 112621f6ecabSRudolf Cornelissen /* issue actual command. */ 112721f6ecabSRudolf Cornelissen buffer[2] = 0x40; 112821f6ecabSRudolf Cornelissen 112921f6ecabSRudolf Cornelissen i2c_bstart(si->ps.tv_encoder.bus); 113021f6ecabSRudolf Cornelissen i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer)); 113121f6ecabSRudolf Cornelissen i2c_bstop(si->ps.tv_encoder.bus); 113221f6ecabSRudolf Cornelissen /* log on errors */ 113321f6ecabSRudolf Cornelissen stat = i2c_flag_error(0); 113421f6ecabSRudolf Cornelissen if (stat) 113521f6ecabSRudolf Cornelissen { 113621f6ecabSRudolf Cornelissen LOG(4,("Brooktree: I2C errors occurred while reading connection status (2)\n")); 113721f6ecabSRudolf Cornelissen return stat; 113821f6ecabSRudolf Cornelissen } 113921f6ecabSRudolf Cornelissen 114021f6ecabSRudolf Cornelissen /* CX: Wait 600uS for signals to stabilize (see datasheet) */ 114121f6ecabSRudolf Cornelissen /* warning, note: 114221f6ecabSRudolf Cornelissen * datasheet is in error! 60mS needed!! */ 114321f6ecabSRudolf Cornelissen snooze(60000); 114421f6ecabSRudolf Cornelissen 114521f6ecabSRudolf Cornelissen /* read back updated connection status: */ 114621f6ecabSRudolf Cornelissen buffer[0] = si->ps.tv_encoder.adress + RD; 114721f6ecabSRudolf Cornelissen 114821f6ecabSRudolf Cornelissen /* transmit 1 byte */ 114921f6ecabSRudolf Cornelissen i2c_bstart(si->ps.tv_encoder.bus); 115021f6ecabSRudolf Cornelissen i2c_writebuffer(si->ps.tv_encoder.bus, buffer, 1); 115121f6ecabSRudolf Cornelissen 115221f6ecabSRudolf Cornelissen /* receive 1 byte */ 11539a7218c5SRudolf Cornelissen /* ACK level to TX after last byte to RX should be 1 (= NACK) (see I2C spec) 115421f6ecabSRudolf Cornelissen * While the BT's don't care, CX chips will block the SDA line if an ACK gets sent! */ 115521f6ecabSRudolf Cornelissen buffer[0] = 1; 115621f6ecabSRudolf Cornelissen i2c_readbuffer(si->ps.tv_encoder.bus, buffer, 1); 115721f6ecabSRudolf Cornelissen i2c_bstop(si->ps.tv_encoder.bus); 115821f6ecabSRudolf Cornelissen /* log on errors */ 115921f6ecabSRudolf Cornelissen stat = i2c_flag_error(0); 116021f6ecabSRudolf Cornelissen if (stat) 116121f6ecabSRudolf Cornelissen { 116221f6ecabSRudolf Cornelissen LOG(4,("Brooktree: I2C errors occurred while reading connection status (3)\n")); 116321f6ecabSRudolf Cornelissen return stat; 116421f6ecabSRudolf Cornelissen } 116521f6ecabSRudolf Cornelissen 116621f6ecabSRudolf Cornelissen *monstat = ((buffer[0] & 0xe0) >> 5); 116721f6ecabSRudolf Cornelissen LOG(4,("Brooktree: TV output monitor status = %d\n", *monstat)); 116821f6ecabSRudolf Cornelissen 116921f6ecabSRudolf Cornelissen /* instruct BT to go back to normal operation: */ 117021f6ecabSRudolf Cornelissen buffer[0] = si->ps.tv_encoder.adress + WR; 117121f6ecabSRudolf Cornelissen /* select register with CHECK_STAT CMD */ 117221f6ecabSRudolf Cornelissen buffer[1] = 0xba; 117321f6ecabSRudolf Cornelissen /* issue actual command. */ 117421f6ecabSRudolf Cornelissen buffer[2] = 0x00; 117521f6ecabSRudolf Cornelissen 117621f6ecabSRudolf Cornelissen i2c_bstart(si->ps.tv_encoder.bus); 117721f6ecabSRudolf Cornelissen i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer)); 117821f6ecabSRudolf Cornelissen i2c_bstop(si->ps.tv_encoder.bus); 117921f6ecabSRudolf Cornelissen /* log on errors */ 118021f6ecabSRudolf Cornelissen stat = i2c_flag_error(0); 118121f6ecabSRudolf Cornelissen if (stat) 118221f6ecabSRudolf Cornelissen { 118321f6ecabSRudolf Cornelissen LOG(4,("Brooktree: I2C errors occurred while reading connection status (4)\n")); 118421f6ecabSRudolf Cornelissen return stat; 118521f6ecabSRudolf Cornelissen } 118621f6ecabSRudolf Cornelissen 118721f6ecabSRudolf Cornelissen return stat; 118821f6ecabSRudolf Cornelissen }//end BT_read_monstat. 118921f6ecabSRudolf Cornelissen 119021f6ecabSRudolf Cornelissen static uint8 BT_killclk_blackout(void) 119121f6ecabSRudolf Cornelissen { 119221f6ecabSRudolf Cornelissen uint8 stat; 119321f6ecabSRudolf Cornelissen 119421f6ecabSRudolf Cornelissen uint8 buffer[4]; 119521f6ecabSRudolf Cornelissen 11969a7218c5SRudolf Cornelissen LOG(4,("Brooktree: Killing clock and/or blacking out (blocking output signals)\n")); 11979a7218c5SRudolf Cornelissen 119821f6ecabSRudolf Cornelissen /* reset status */ 119921f6ecabSRudolf Cornelissen i2c_flag_error (-1); 120021f6ecabSRudolf Cornelissen 120121f6ecabSRudolf Cornelissen if (si->ps.tv_encoder.type <= BT869) //BT... 120221f6ecabSRudolf Cornelissen { 120321f6ecabSRudolf Cornelissen /* Only disable external pixelclock input on BT's. 120421f6ecabSRudolf Cornelissen * CX chips will lock the bus if you do this. 120521f6ecabSRudolf Cornelissen * (It looks like the external pixelclock is always OK as long as a valid 120621f6ecabSRudolf Cornelissen * mode is programmed for the TVout chip. This means that disabling the use 120721f6ecabSRudolf Cornelissen * of this clock is not needed anyway. 120821f6ecabSRudolf Cornelissen * If you do disable this input, this pixelclock will rise to about 60Mhz BTW..) */ 120921f6ecabSRudolf Cornelissen 121021f6ecabSRudolf Cornelissen /* disable use of external pixelclock source... */ 121121f6ecabSRudolf Cornelissen /* (should prevent BT for being 'overclocked' by RIVA in VGA-only mode...) */ 121221f6ecabSRudolf Cornelissen buffer[0] = si->ps.tv_encoder.adress + WR; 121321f6ecabSRudolf Cornelissen /* select BT register for setting EN_XCLK */ 121421f6ecabSRudolf Cornelissen buffer[1] = 0xa0; 121521f6ecabSRudolf Cornelissen /* clear it */ 121621f6ecabSRudolf Cornelissen buffer[2] = 0x00; 121721f6ecabSRudolf Cornelissen 121821f6ecabSRudolf Cornelissen i2c_bstart(si->ps.tv_encoder.bus); 121921f6ecabSRudolf Cornelissen i2c_writebuffer(si->ps.tv_encoder.bus, buffer, 3); 122021f6ecabSRudolf Cornelissen i2c_bstop(si->ps.tv_encoder.bus); 122121f6ecabSRudolf Cornelissen /* log on errors */ 122221f6ecabSRudolf Cornelissen stat = i2c_flag_error(0); 122321f6ecabSRudolf Cornelissen if (stat) 122421f6ecabSRudolf Cornelissen { 122521f6ecabSRudolf Cornelissen LOG(4,("Brooktree: I2C errors occurred while doing killclk_blackout (1-BT)\n")); 122621f6ecabSRudolf Cornelissen return stat; 122721f6ecabSRudolf Cornelissen } 122821f6ecabSRudolf Cornelissen } 122921f6ecabSRudolf Cornelissen else //CX... 123021f6ecabSRudolf Cornelissen { 123121f6ecabSRudolf Cornelissen /* Disable CX video out (or wild output will be seen on TV..) */ 123221f6ecabSRudolf Cornelissen buffer[0] = si->ps.tv_encoder.adress + WR; 123321f6ecabSRudolf Cornelissen /* select register in CX */ 123421f6ecabSRudolf Cornelissen buffer[1] = 0x6c; 123521f6ecabSRudolf Cornelissen /* disable active video out. */ 123621f6ecabSRudolf Cornelissen buffer[2] = 0x02; 123721f6ecabSRudolf Cornelissen 123821f6ecabSRudolf Cornelissen i2c_bstart(si->ps.tv_encoder.bus); 123921f6ecabSRudolf Cornelissen i2c_writebuffer(si->ps.tv_encoder.bus, buffer, 3); 124021f6ecabSRudolf Cornelissen i2c_bstop(si->ps.tv_encoder.bus); 124121f6ecabSRudolf Cornelissen /* log on errors */ 124221f6ecabSRudolf Cornelissen stat = i2c_flag_error(0); 124321f6ecabSRudolf Cornelissen if (stat) 124421f6ecabSRudolf Cornelissen { 124521f6ecabSRudolf Cornelissen LOG(4,("Brooktree: I2C errors occurred while doing killclk_blackout (1-CX)\n")); 124621f6ecabSRudolf Cornelissen return stat; 124721f6ecabSRudolf Cornelissen } 124821f6ecabSRudolf Cornelissen } 124921f6ecabSRudolf Cornelissen 125021f6ecabSRudolf Cornelissen /* black-out TVout while outputs are enabled... */ 125121f6ecabSRudolf Cornelissen buffer[0] = si->ps.tv_encoder.adress + WR; 125221f6ecabSRudolf Cornelissen /* select first TV config register to write */ 125321f6ecabSRudolf Cornelissen buffer[1] = 0xc4; 125421f6ecabSRudolf Cornelissen /* disable testimage while outputs remain enabled */ 125521f6ecabSRudolf Cornelissen buffer[2] = 0x01; 125621f6ecabSRudolf Cornelissen /* input is 24bit mpx'd RGB, BLANK = in, sync = act. hi */ 125721f6ecabSRudolf Cornelissen buffer[3] = 0x18; 125821f6ecabSRudolf Cornelissen 125921f6ecabSRudolf Cornelissen i2c_bstart(si->ps.tv_encoder.bus); 126021f6ecabSRudolf Cornelissen i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer)); 126121f6ecabSRudolf Cornelissen i2c_bstop(si->ps.tv_encoder.bus); 126221f6ecabSRudolf Cornelissen /* log on errors */ 126321f6ecabSRudolf Cornelissen stat = i2c_flag_error(0); 126421f6ecabSRudolf Cornelissen if (stat) 126521f6ecabSRudolf Cornelissen { 126621f6ecabSRudolf Cornelissen LOG(4,("Brooktree: I2C errors occurred while doing killclk_blackout (2)\n")); 126721f6ecabSRudolf Cornelissen return stat; 126821f6ecabSRudolf Cornelissen } 126921f6ecabSRudolf Cornelissen 127021f6ecabSRudolf Cornelissen return stat; 127121f6ecabSRudolf Cornelissen }//end BT_killclk_blackout. 127221f6ecabSRudolf Cornelissen 1273b2459715SRudolf Cornelissen uint8 BT_check_tvmode(display_mode target) 1274fb6cadf1Sshatty { 1275b2459715SRudolf Cornelissen uint8 status = NOT_SUPPORTED; 1276b2459715SRudolf Cornelissen uint32 mode = ((target.timing.h_display) | ((target.timing.v_display) << 16)); 1277b2459715SRudolf Cornelissen 1278b2459715SRudolf Cornelissen switch (mode) 1279b2459715SRudolf Cornelissen { 1280b2459715SRudolf Cornelissen case (640 | (480 << 16)): 1281c5fe5f2dSRudolf Cornelissen if (((target.flags & TV_BITS) == TV_PAL) && (!(target.flags & TV_VIDEO))) 1282c5fe5f2dSRudolf Cornelissen status = PAL640; 1283b2459715SRudolf Cornelissen if ((target.flags & TV_BITS) == TV_NTSC) 1284b2459715SRudolf Cornelissen { 1285b2459715SRudolf Cornelissen if (!(target.flags & TV_VIDEO)) status = NTSC640; 1286b2459715SRudolf Cornelissen else status = NTSC640_OS; 1287b2459715SRudolf Cornelissen } 1288b2459715SRudolf Cornelissen break; 1289c5fe5f2dSRudolf Cornelissen case (768 | (576 << 16)): 1290c5fe5f2dSRudolf Cornelissen if (((target.flags & TV_BITS) == TV_PAL) && (target.flags & TV_VIDEO)) 1291c5fe5f2dSRudolf Cornelissen status = PAL800_OS; 1292c5fe5f2dSRudolf Cornelissen break; 1293b2459715SRudolf Cornelissen case (800 | (600 << 16)): 1294c5fe5f2dSRudolf Cornelissen if (((target.flags & TV_BITS) == TV_PAL) && (!(target.flags & TV_VIDEO))) 1295c5fe5f2dSRudolf Cornelissen status = PAL800; 1296c5fe5f2dSRudolf Cornelissen if (((target.flags & TV_BITS) == TV_NTSC) && (!(target.flags & TV_VIDEO))) 1297c5fe5f2dSRudolf Cornelissen status = NTSC800; 1298b2459715SRudolf Cornelissen break; 1299b2459715SRudolf Cornelissen case (720 | (480 << 16)): 1300b2459715SRudolf Cornelissen if (((target.flags & TV_BITS) == TV_NTSC) && (target.flags & TV_VIDEO)) 1301b2459715SRudolf Cornelissen status = NTSC720; 1302b2459715SRudolf Cornelissen break; 1303b2459715SRudolf Cornelissen case (720 | (576 << 16)): 1304b2459715SRudolf Cornelissen if (((target.flags & TV_BITS) == TV_PAL) && (target.flags & TV_VIDEO)) 1305b2459715SRudolf Cornelissen status = PAL720; 1306b2459715SRudolf Cornelissen break; 1307b2459715SRudolf Cornelissen } 1308b2459715SRudolf Cornelissen 1309b2459715SRudolf Cornelissen return status; 1310b2459715SRudolf Cornelissen }//end BT_check_tvmode. 1311b2459715SRudolf Cornelissen 1312bd7693f2SRudolf Cornelissen 1313bd7693f2SRudolf Cornelissen /* 1314*da3804eeSRudolf Cornelissen //BeTVOut's SwitchRIVAtoTV(vtot) timing formula: (note: vtot = (v_total - 2)) 1315bd7693f2SRudolf Cornelissen //----------------------------------------------------------------------------------- 1316bd7693f2SRudolf Cornelissen //HORIZONTAL: 1317bd7693f2SRudolf Cornelissen //----------- 1318bd7693f2SRudolf Cornelissen h_sync_start = h_display; 1319bd7693f2SRudolf Cornelissen 1320bd7693f2SRudolf Cornelissen //fixme, note, checkout: 1321bd7693f2SRudolf Cornelissen //feels like in fact TNT2-M64 nv_crtc.c registerprogramming should be adapted... 1322bd7693f2SRudolf Cornelissen if (TNT2-M64) 1323bd7693f2SRudolf Cornelissen { 1324bd7693f2SRudolf Cornelissen h_sync_end = h_display + 8; 1325bd7693f2SRudolf Cornelissen h_total = h_display + 56; 1326bd7693f2SRudolf Cornelissen } 1327bd7693f2SRudolf Cornelissen else //TNT1, TNT2, Geforce2... (so default) 1328bd7693f2SRudolf Cornelissen { 1329bd7693f2SRudolf Cornelissen h_sync_end = h_display + 16; 1330bd7693f2SRudolf Cornelissen h_total = h_display + 48; 1331bd7693f2SRudolf Cornelissen } 1332bd7693f2SRudolf Cornelissen 1333bd7693f2SRudolf Cornelissen //fixme, note, checkout: 1334bd7693f2SRudolf Cornelissen //BeTVOut uses two 'tweaks': 1335bd7693f2SRudolf Cornelissen // - on TNT2-M64 only: 1336bd7693f2SRudolf Cornelissen // register h_blank_e is increased with 1 (so should be done in nv_crtc.c here) 1337bd7693f2SRudolf Cornelissen // - all cards: 1338bd7693f2SRudolf Cornelissen // register h_blank_e b6 = 0. 1339bd7693f2SRudolf Cornelissen //----------------------------------------------------------------------------------- 1340bd7693f2SRudolf Cornelissen //VERTICAL: 1341bd7693f2SRudolf Cornelissen //--------- 1342*da3804eeSRudolf Cornelissen v_sync_start = v_display; 1343*da3804eeSRudolf Cornelissen v_total = vtot + 2; 1344*da3804eeSRudolf Cornelissen v_sync_end = v_total - 1; //(This takes care of the 'cursor trash' on TNT1's...) 1345bd7693f2SRudolf Cornelissen //----------------------------------------------------------------------------------- 1346bd7693f2SRudolf Cornelissen */ 134785406c4dSRudolf Cornelissen static status_t BT_update_mode_for_gpu(display_mode *target, uint8 tvmode) 134885406c4dSRudolf Cornelissen { 134985406c4dSRudolf Cornelissen switch (tvmode) 135085406c4dSRudolf Cornelissen { 135185406c4dSRudolf Cornelissen case NTSC640: 135285406c4dSRudolf Cornelissen case NTSC640_TST: 1353bd7693f2SRudolf Cornelissen target->timing.h_display = 640; 1354bd7693f2SRudolf Cornelissen target->timing.h_sync_start = 640; 1355bd7693f2SRudolf Cornelissen if (si->ps.card_type == NV05M64) 1356bd7693f2SRudolf Cornelissen { 1357bd7693f2SRudolf Cornelissen target->timing.h_sync_end = 648; 1358bd7693f2SRudolf Cornelissen target->timing.h_total = 696; 1359bd7693f2SRudolf Cornelissen } 1360bd7693f2SRudolf Cornelissen else 1361bd7693f2SRudolf Cornelissen { 1362bd7693f2SRudolf Cornelissen target->timing.h_sync_end = 656; 1363bd7693f2SRudolf Cornelissen target->timing.h_total = 688; 1364bd7693f2SRudolf Cornelissen } 1365bd7693f2SRudolf Cornelissen target->timing.v_display = 480; 1366*da3804eeSRudolf Cornelissen target->timing.v_sync_start = 480; 1367*da3804eeSRudolf Cornelissen target->timing.v_sync_end = 555; //This prevents 'cursor trash' on TNT1's 1368*da3804eeSRudolf Cornelissen target->timing.v_total = 556; //Above 525 because mode scales down 1369bd7693f2SRudolf Cornelissen //fixme: not actually programmed because PLL is programmed earlier... 1370*da3804eeSRudolf Cornelissen if (si->ps.card_type == NV05M64) 1371*da3804eeSRudolf Cornelissen target->timing.pixel_clock = ((696 * 556 * 60) / 1000); 1372*da3804eeSRudolf Cornelissen else 1373*da3804eeSRudolf Cornelissen target->timing.pixel_clock = ((688 * 556 * 60) / 1000); 137485406c4dSRudolf Cornelissen break; 137585406c4dSRudolf Cornelissen case NTSC800: 1376*da3804eeSRudolf Cornelissen target->timing.h_display = 800; 1377*da3804eeSRudolf Cornelissen target->timing.h_sync_start = 800; 1378*da3804eeSRudolf Cornelissen if (si->ps.card_type == NV05M64) 1379*da3804eeSRudolf Cornelissen { 1380*da3804eeSRudolf Cornelissen target->timing.h_sync_end = 808; 1381*da3804eeSRudolf Cornelissen target->timing.h_total = 856; 1382*da3804eeSRudolf Cornelissen } 1383*da3804eeSRudolf Cornelissen else 1384*da3804eeSRudolf Cornelissen { 1385*da3804eeSRudolf Cornelissen target->timing.h_sync_end = 816; 1386*da3804eeSRudolf Cornelissen target->timing.h_total = 848; 1387*da3804eeSRudolf Cornelissen } 1388*da3804eeSRudolf Cornelissen target->timing.v_display = 600; 1389*da3804eeSRudolf Cornelissen target->timing.v_sync_start = 600; 1390*da3804eeSRudolf Cornelissen target->timing.v_sync_end = 685; //This prevents 'cursor trash' on TNT1's 1391*da3804eeSRudolf Cornelissen target->timing.v_total = 686; //Above 525 because mode scales down 1392*da3804eeSRudolf Cornelissen //fixme: not actually programmed because PLL is programmed earlier... 1393*da3804eeSRudolf Cornelissen if (si->ps.card_type == NV05M64) 1394*da3804eeSRudolf Cornelissen target->timing.pixel_clock = ((856 * 686 * 60) / 1000); 1395*da3804eeSRudolf Cornelissen else 1396*da3804eeSRudolf Cornelissen target->timing.pixel_clock = ((848 * 686 * 60) / 1000); 139785406c4dSRudolf Cornelissen break; 139885406c4dSRudolf Cornelissen case PAL640: 1399bd7693f2SRudolf Cornelissen target->timing.h_display = 640; 1400*da3804eeSRudolf Cornelissen target->timing.h_sync_start = 640; 1401*da3804eeSRudolf Cornelissen if (si->ps.card_type == NV05M64) 1402*da3804eeSRudolf Cornelissen { 1403*da3804eeSRudolf Cornelissen target->timing.h_sync_end = 648; 1404*da3804eeSRudolf Cornelissen target->timing.h_total = 696; 1405*da3804eeSRudolf Cornelissen } 1406*da3804eeSRudolf Cornelissen else 1407*da3804eeSRudolf Cornelissen { 1408*da3804eeSRudolf Cornelissen target->timing.h_sync_end = 656; 1409*da3804eeSRudolf Cornelissen target->timing.h_total = 688; 1410*da3804eeSRudolf Cornelissen } 1411bd7693f2SRudolf Cornelissen target->timing.v_display = 480; 1412*da3804eeSRudolf Cornelissen target->timing.v_sync_start = 480; 1413*da3804eeSRudolf Cornelissen target->timing.v_sync_end = 570; //This prevents 'cursor trash' on TNT1's 1414*da3804eeSRudolf Cornelissen target->timing.v_total = 571; //Below 625 because mode scales up 1415bd7693f2SRudolf Cornelissen //fixme: not actually programmed because PLL is programmed earlier... 1416*da3804eeSRudolf Cornelissen if (si->ps.card_type == NV05M64) 1417*da3804eeSRudolf Cornelissen target->timing.pixel_clock = ((696 * 571 * 50) / 1000); 1418*da3804eeSRudolf Cornelissen else 1419*da3804eeSRudolf Cornelissen target->timing.pixel_clock = ((688 * 571 * 50) / 1000); 142085406c4dSRudolf Cornelissen break; 142185406c4dSRudolf Cornelissen case PAL800: 142285406c4dSRudolf Cornelissen case PAL800_TST: 1423*da3804eeSRudolf Cornelissen target->timing.h_display = 800; 1424*da3804eeSRudolf Cornelissen target->timing.h_sync_start = 800; 1425*da3804eeSRudolf Cornelissen if (si->ps.card_type == NV05M64) 1426*da3804eeSRudolf Cornelissen { 1427*da3804eeSRudolf Cornelissen target->timing.h_sync_end = 808; 1428*da3804eeSRudolf Cornelissen target->timing.h_total = 856; 1429*da3804eeSRudolf Cornelissen } 1430*da3804eeSRudolf Cornelissen else 1431*da3804eeSRudolf Cornelissen { 1432*da3804eeSRudolf Cornelissen target->timing.h_sync_end = 816; 1433*da3804eeSRudolf Cornelissen target->timing.h_total = 848; 1434*da3804eeSRudolf Cornelissen } 1435*da3804eeSRudolf Cornelissen target->timing.v_display = 600; 1436*da3804eeSRudolf Cornelissen target->timing.v_sync_start = 600; 1437*da3804eeSRudolf Cornelissen target->timing.v_sync_end = 695; //This prevents 'cursor trash' on TNT1's 1438*da3804eeSRudolf Cornelissen target->timing.v_total = 696; //Above 625 because mode scales down 1439*da3804eeSRudolf Cornelissen //fixme: not actually programmed because PLL is programmed earlier... 1440*da3804eeSRudolf Cornelissen if (si->ps.card_type == NV05M64) 1441*da3804eeSRudolf Cornelissen target->timing.pixel_clock = ((856 * 696 * 50) / 1000); 1442*da3804eeSRudolf Cornelissen else 1443*da3804eeSRudolf Cornelissen target->timing.pixel_clock = ((848 * 696 * 50) / 1000); 144485406c4dSRudolf Cornelissen break; 144585406c4dSRudolf Cornelissen case NTSC640_OS: 144685406c4dSRudolf Cornelissen target->timing.h_display = 640; //BT H_ACTIVE 144785406c4dSRudolf Cornelissen target->timing.h_sync_start = 744; //set for CH/BT compatible TV output 144885406c4dSRudolf Cornelissen target->timing.h_sync_end = 744+20; //delta is BT H_BLANKI 144985406c4dSRudolf Cornelissen target->timing.h_total = 784; //BT H_CLKI 145085406c4dSRudolf Cornelissen target->timing.v_display = 480; //BT V_ACTIVEI 145185406c4dSRudolf Cornelissen target->timing.v_sync_start = 490; //set for centered sync pulse 145285406c4dSRudolf Cornelissen target->timing.v_sync_end = 490+25; //delta is BT V_BLANKI 1453*da3804eeSRudolf Cornelissen target->timing.v_total = 525; //BT V_LINESI (== 525: 1:1 scaled mode) 145485406c4dSRudolf Cornelissen //fixme: not actually programmed because PLL is programmed earlier... 145585406c4dSRudolf Cornelissen target->timing.pixel_clock = ((784 * 525 * 60) / 1000); //refresh 145685406c4dSRudolf Cornelissen break; 145785406c4dSRudolf Cornelissen case PAL800_OS: 145885406c4dSRudolf Cornelissen target->timing.h_display = 768; //H_ACTIVE 145985406c4dSRudolf Cornelissen target->timing.h_sync_start = 848; //set for centered TV output 146085406c4dSRudolf Cornelissen target->timing.h_sync_end = 848+20; //delta is BT H_BLANKI 146185406c4dSRudolf Cornelissen target->timing.h_total = 944; //BT H_CLKI 146285406c4dSRudolf Cornelissen target->timing.v_display = 576; //V_ACTIVEI 146385406c4dSRudolf Cornelissen target->timing.v_sync_start = 579; //set for centered sync pulse 146485406c4dSRudolf Cornelissen target->timing.v_sync_end = 579+42; //delta is BT V_BLANKI 1465*da3804eeSRudolf Cornelissen target->timing.v_total = 625; //BT V_LINESI (== 625: 1:1 scaled mode) 146685406c4dSRudolf Cornelissen //fixme: not actually programmed because PLL is programmed earlier... 146785406c4dSRudolf Cornelissen target->timing.pixel_clock = ((944 * 625 * 50) / 1000); //refresh 146885406c4dSRudolf Cornelissen break; 146985406c4dSRudolf Cornelissen case NTSC720: 147085406c4dSRudolf Cornelissen /* (tested on TNT2 with BT869) */ 147185406c4dSRudolf Cornelissen target->timing.h_display = 720; //H_ACTIVE 147285406c4dSRudolf Cornelissen target->timing.h_sync_start = 744; //do not change! 147385406c4dSRudolf Cornelissen target->timing.h_sync_end = 744+144; //delta is H_sync_pulse 147485406c4dSRudolf Cornelissen target->timing.h_total = 888; //BT H_TOTAL 147585406c4dSRudolf Cornelissen target->timing.v_display = 480; //V_ACTIVEI 147685406c4dSRudolf Cornelissen target->timing.v_sync_start = 490; //set for centered sync pulse 147785406c4dSRudolf Cornelissen target->timing.v_sync_end = 490+26; //delta is V_sync_pulse 1478*da3804eeSRudolf Cornelissen target->timing.v_total = 525; //CH V_TOTAL (== 525: 1:1 scaled mode) 147985406c4dSRudolf Cornelissen //fixme: not actually programmed because PLL is programmed earlier... 148085406c4dSRudolf Cornelissen target->timing.pixel_clock = ((888 * 525 * 60) / 1000); //refresh 148185406c4dSRudolf Cornelissen break; 148285406c4dSRudolf Cornelissen case PAL720: 148385406c4dSRudolf Cornelissen target->timing.h_display = 720; //BT H_ACTIVE 148485406c4dSRudolf Cornelissen target->timing.h_sync_start = 744; //set for centered sync pulse 148585406c4dSRudolf Cornelissen target->timing.h_sync_end = 744+140; //delta is BT H_BLANKI 148685406c4dSRudolf Cornelissen target->timing.h_total = 888; //BT H_CLKI 148785406c4dSRudolf Cornelissen target->timing.v_display = 576; //BT V_ACTIVEI 148885406c4dSRudolf Cornelissen target->timing.v_sync_start = 579; //set for centered sync pulse 148985406c4dSRudolf Cornelissen target->timing.v_sync_end = 579+42; //delta is BT V_BLANKI 1490*da3804eeSRudolf Cornelissen target->timing.v_total = 625; //BT V_LINESI (== 625: 1:1 scaled mode) 149185406c4dSRudolf Cornelissen //fixme: not actually programmed because PLL is programmed earlier... 149285406c4dSRudolf Cornelissen target->timing.pixel_clock = ((888 * 625 * 50) / 1000); //refresh 149385406c4dSRudolf Cornelissen break; 149485406c4dSRudolf Cornelissen default: 149585406c4dSRudolf Cornelissen return B_ERROR; 149685406c4dSRudolf Cornelissen } 149785406c4dSRudolf Cornelissen 149885406c4dSRudolf Cornelissen return B_OK; 149985406c4dSRudolf Cornelissen }//end BT_update_mode_for_gpu. 150085406c4dSRudolf Cornelissen 1501b2459715SRudolf Cornelissen status_t BT_setmode(display_mode target) 1502b2459715SRudolf Cornelissen { 1503efe9c7a6SRudolf Cornelissen uint8 tvmode, monstat; 1504efe9c7a6SRudolf Cornelissen /* enable flickerfilter in desktop modes, disable it in video modes. */ 1505efe9c7a6SRudolf Cornelissen uint8 ffilter = 0; 1506b2459715SRudolf Cornelissen 1507fb6cadf1Sshatty /* use a display_mode copy because we might tune it for TVout compatibility */ 1508fb6cadf1Sshatty display_mode tv_target = target; 1509fb6cadf1Sshatty 1510fb6cadf1Sshatty /* preset new TVout mode */ 1511b2459715SRudolf Cornelissen tvmode = BT_check_tvmode(tv_target); 1512b2459715SRudolf Cornelissen if (!tvmode) return B_ERROR; 1513b2459715SRudolf Cornelissen 1514b2459715SRudolf Cornelissen //fixme: only testing singlehead cards for now... 1515b2459715SRudolf Cornelissen if (si->ps.secondary_head) 1516fb6cadf1Sshatty { 1517b2459715SRudolf Cornelissen head1_set_timing(tv_target); 1518b2459715SRudolf Cornelissen return B_ERROR; 1519fb6cadf1Sshatty } 1520b2459715SRudolf Cornelissen 1521efe9c7a6SRudolf Cornelissen /* fixme: reset BT should be here... 1522efe9c7a6SRudolf Cornelissen * (but: beware of the 'locked SDA' syndrome then!) */ 1523efe9c7a6SRudolf Cornelissen BT_killclk_blackout(); 1524efe9c7a6SRudolf Cornelissen 1525efe9c7a6SRudolf Cornelissen /* read current output devices connection status */ 1526efe9c7a6SRudolf Cornelissen BT_read_monstat(&monstat); 1527efe9c7a6SRudolf Cornelissen 1528efe9c7a6SRudolf Cornelissen //fixme? 1529efe9c7a6SRudolf Cornelissen //'slowdown RIVA clock' if TVout is requested: 1530efe9c7a6SRudolf Cornelissen //makes sure TVout chip is not being overclocked! (VESA640/800 is safe..) 1531efe9c7a6SRudolf Cornelissen //NOTE: it looks like this is unnesessary after all.. 1532efe9c7a6SRudolf Cornelissen 1533efe9c7a6SRudolf Cornelissen /* (pre)set TV mode */ 1534efe9c7a6SRudolf Cornelissen /* note: 1535efe9c7a6SRudolf Cornelissen * Manual config is non-dependent of the state of the PAL hardware input pin; 1536efe9c7a6SRudolf Cornelissen * Also SDA lockups occur when setting EN_XCLK after autoconfig! 1537efe9c7a6SRudolf Cornelissen * Make sure PAL_MD=0 for NTSC and PAL_MD = 1 for PAL... */ 1538b2459715SRudolf Cornelissen switch (tvmode) 1539fb6cadf1Sshatty { 1540b2459715SRudolf Cornelissen case NTSC640: 1541b2459715SRudolf Cornelissen case NTSC640_TST: 1542efe9c7a6SRudolf Cornelissen ffilter = 1; 1543efe9c7a6SRudolf Cornelissen BT_init_NTSC640(); 1544b2459715SRudolf Cornelissen break; 1545b2459715SRudolf Cornelissen case NTSC800: 1546efe9c7a6SRudolf Cornelissen ffilter = 1; 1547efe9c7a6SRudolf Cornelissen BT_init_NTSC800(); 1548b2459715SRudolf Cornelissen break; 1549b2459715SRudolf Cornelissen case PAL640: 1550efe9c7a6SRudolf Cornelissen ffilter = 1; 1551efe9c7a6SRudolf Cornelissen BT_init_PAL640(); 1552b2459715SRudolf Cornelissen break; 1553b2459715SRudolf Cornelissen case PAL800: 1554b2459715SRudolf Cornelissen case PAL800_TST: 1555efe9c7a6SRudolf Cornelissen ffilter = 1; 1556efe9c7a6SRudolf Cornelissen BT_init_PAL800(); 1557b2459715SRudolf Cornelissen break; 1558b2459715SRudolf Cornelissen case NTSC640_OS: 1559efe9c7a6SRudolf Cornelissen BT_init_NTSC640_OS(); 1560b2459715SRudolf Cornelissen break; 1561b2459715SRudolf Cornelissen case PAL800_OS: 1562efe9c7a6SRudolf Cornelissen BT_init_PAL800_OS(); 1563b2459715SRudolf Cornelissen break; 1564b2459715SRudolf Cornelissen case NTSC720: 1565efe9c7a6SRudolf Cornelissen BT_init_NTSC720(); 1566b2459715SRudolf Cornelissen break; 1567b2459715SRudolf Cornelissen case PAL720: 1568efe9c7a6SRudolf Cornelissen BT_init_PAL720(); 1569b2459715SRudolf Cornelissen break; 1570fb6cadf1Sshatty } 1571fb6cadf1Sshatty 1572efe9c7a6SRudolf Cornelissen /* modify BT Hphase signal to center TV image... */ 1573efe9c7a6SRudolf Cornelissen BT_setup_hphase(tvmode); 1574fb6cadf1Sshatty 1575efe9c7a6SRudolf Cornelissen /* disable Macro mode */ 1576efe9c7a6SRudolf Cornelissen switch (tvmode) 1577efe9c7a6SRudolf Cornelissen { 1578efe9c7a6SRudolf Cornelissen case NTSC640: 1579efe9c7a6SRudolf Cornelissen case NTSC640_TST: 1580efe9c7a6SRudolf Cornelissen case NTSC800: 1581efe9c7a6SRudolf Cornelissen case NTSC640_OS: 1582efe9c7a6SRudolf Cornelissen case NTSC720: 1583efe9c7a6SRudolf Cornelissen /* NTSC */ 1584efe9c7a6SRudolf Cornelissen BT_set_macro (0, 0); 1585efe9c7a6SRudolf Cornelissen break; 1586efe9c7a6SRudolf Cornelissen default: 1587efe9c7a6SRudolf Cornelissen /* PAL */ 1588efe9c7a6SRudolf Cornelissen BT_set_macro (1, 0); 1589efe9c7a6SRudolf Cornelissen break; 1590efe9c7a6SRudolf Cornelissen } 1591fb6cadf1Sshatty 1592efe9c7a6SRudolf Cornelissen /* setup output signal routing and flickerfilter */ 1593efe9c7a6SRudolf Cornelissen //fixme: add output force settings in nv.settings, defaulting to autodetect. 1594efe9c7a6SRudolf Cornelissen BT_setup_output(monstat, 0, ffilter); 1595fb6cadf1Sshatty 1596efe9c7a6SRudolf Cornelissen //tmp: enabling testimage... 1597efe9c7a6SRudolf Cornelissen BT_testsignal(); 1598fb6cadf1Sshatty 159985406c4dSRudolf Cornelissen /* update the GPU CRTC timing for the requested mode */ 160085406c4dSRudolf Cornelissen BT_update_mode_for_gpu(&tv_target, tvmode); 1601fb6cadf1Sshatty 1602efe9c7a6SRudolf Cornelissen /* setup GPU CRTC timing */ 1603b2459715SRudolf Cornelissen head1_set_timing(tv_target); 1604fb6cadf1Sshatty 1605efe9c7a6SRudolf Cornelissen //fixme: set GPU CRTC to slave mode... 1606efe9c7a6SRudolf Cornelissen 1607efe9c7a6SRudolf Cornelissen //fixme: add code to disable VGA screen when TVout enabled 1608efe9c7a6SRudolf Cornelissen //(use via nv.setting preset) 1609fb6cadf1Sshatty 1610b2459715SRudolf Cornelissen return B_OK; 1611fb6cadf1Sshatty } 1612