1 /* 2 Haiku S3 Virge driver adapted from the X.org Virge and Savage driver. 3 4 Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. 5 6 Copyright 2007-2008 Haiku, Inc. All rights reserved. 7 Distributed under the terms of the MIT license. 8 9 Authors: 10 Gerald Zajac 2007-2008 11 */ 12 13 #include "accel.h" 14 #include "virge.h" 15 16 #include <string.h> 17 #include <ddc.h> 18 #include <edid.h> 19 20 21 22 static status_t 23 GetI2CSignals_Alt(void* cookie, int* _clock, int* data) 24 { 25 uint32 index = (uint32)(addr_t)cookie; 26 uint8 value = ReadCrtcReg(index); 27 28 *_clock = (value & 0x4) != 0; 29 *data = (value & 0x8) != 0; 30 return B_OK; 31 } 32 33 34 static status_t 35 SetI2CSignals_Alt(void* cookie, int _clock, int data) 36 { 37 uint32 index = (uint32)(addr_t)cookie; 38 uint8 value = 0x10; 39 40 if (_clock) 41 value |= 0x1; 42 if (data) 43 value |= 0x2; 44 45 WriteCrtcReg(index, value); 46 return B_OK; 47 } 48 49 50 51 static status_t 52 GetI2CSignals(void* cookie, int* _clock, int* data) 53 { 54 (void)cookie; // avoid compiler warning for unused arg 55 56 uint8 reg = ReadReg8(DDC_REG); 57 58 *_clock = (reg & 0x4) != 0; 59 *data = (reg & 0x8) != 0; 60 return B_OK; 61 } 62 63 64 static status_t 65 SetI2CSignals(void* cookie, int _clock, int data) 66 { 67 (void)cookie; // avoid compiler warning for unused arg 68 69 uint8 reg = 0x10; 70 71 if (_clock) 72 reg |= 0x1; 73 if (data) 74 reg |= 0x2; 75 76 WriteReg8(DDC_REG, reg); 77 return B_OK; 78 } 79 80 81 82 bool 83 Virge_GetEdidInfo(edid1_info& edidInfo) 84 { 85 // Get the EDID info and return true if successful. 86 87 SharedInfo& si = *gInfo.sharedInfo; 88 89 bool bResult = false; 90 91 if (si.chipType == S3_TRIO_3D_2X) { 92 uint32 DDCPort = 0xAA; 93 94 i2c_bus bus; 95 bus.cookie = (void*)(addr_t)DDCPort; 96 bus.set_signals = &SetI2CSignals_Alt; 97 bus.get_signals = &GetI2CSignals_Alt; 98 ddc2_init_timing(&bus); 99 100 uint8 tmp = ReadCrtcReg(DDCPort); 101 WriteCrtcReg(DDCPort, tmp | 0x13); 102 103 bResult = (ddc2_read_edid1(&bus, &edidInfo, NULL, NULL) == B_OK); 104 105 WriteCrtcReg(DDCPort, tmp); 106 } else { 107 i2c_bus bus; 108 bus.cookie = (void*)DDC_REG; 109 bus.set_signals = &SetI2CSignals; 110 bus.get_signals = &GetI2CSignals; 111 ddc2_init_timing(&bus); 112 113 uint8 tmp = ReadReg8(DDC_REG); 114 WriteReg8(DDC_REG, tmp | 0x13); 115 116 bResult = (ddc2_read_edid1(&bus, &edidInfo, NULL, NULL) == B_OK); 117 118 WriteReg8(DDC_REG, tmp); 119 } 120 121 return bResult; 122 } 123