xref: /haiku/src/add-ons/accelerants/s3/virge_edid.cpp (revision 3af8011358bd4c624a0979336d48dabb466171ed)
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