| 1 | /* |
| 2 | * edid.h: defines to parse an EDID block |
| 3 | * |
| 4 | * This file contains all information to interpret a standard EDIC block |
| 5 | * transmitted by a display device via DDC (Display Data Channel). So far |
| 6 | * there is no information to deal with optional EDID blocks. |
| 7 | * DDC is a Trademark of VESA (Video Electronics Standard Association). |
| 8 | * |
| 9 | * Copyright 1998 by Egbert Eich <Egbert.Eich@Physik.TU-Darmstadt.DE> |
| 10 | */ |
| 11 | |
| 12 | #ifndef _EDID_H_ |
| 13 | #define _EDID_H_ |
| 14 | |
| 15 | #include <X11/Xmd.h> |
| 16 | |
| 17 | #ifndef _X_EXPORT |
| 18 | #include <X11/Xfuncproto.h> |
| 19 | #endif |
| 20 | |
| 21 | /* read complete EDID record */ |
| 22 | #define EDID1_LEN 128 |
| 23 | #define BITS_PER_BYTE 9 |
| 24 | #define NUM BITS_PER_BYTE*EDID1_LEN |
| 25 | #define HEADER 6 |
| 26 | |
| 27 | #define STD_TIMINGS 8 |
| 28 | #define DET_TIMINGS 4 |
| 29 | |
| 30 | #ifdef _PARSE_EDID_ |
| 31 | |
| 32 | /* header: 0x00 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0x00 */ |
| 33 | #define HEADER_SECTION 0 |
| 34 | #define HEADER_LENGTH 8 |
| 35 | |
| 36 | /* vendor section */ |
| 37 | #define VENDOR_SECTION (HEADER_SECTION + HEADER_LENGTH) |
| 38 | #define V_MANUFACTURER 0 |
| 39 | #define V_PROD_ID (V_MANUFACTURER + 2) |
| 40 | #define V_SERIAL (V_PROD_ID + 2) |
| 41 | #define V_WEEK (V_SERIAL + 4) |
| 42 | #define V_YEAR (V_WEEK + 1) |
| 43 | #define VENDOR_LENGTH (V_YEAR + 1) |
| 44 | |
| 45 | /* EDID version */ |
| 46 | #define VERSION_SECTION (VENDOR_SECTION + VENDOR_LENGTH) |
| 47 | #define V_VERSION 0 |
| 48 | #define V_REVISION (V_VERSION + 1) |
| 49 | #define VERSION_LENGTH (V_REVISION + 1) |
| 50 | |
| 51 | /* display information */ |
| 52 | #define DISPLAY_SECTION (VERSION_SECTION + VERSION_LENGTH) |
| 53 | #define D_INPUT 0 |
| 54 | #define D_HSIZE (D_INPUT + 1) |
| 55 | #define D_VSIZE (D_HSIZE + 1) |
| 56 | #define D_GAMMA (D_VSIZE + 1) |
| 57 | #define FEAT_S (D_GAMMA + 1) |
| 58 | #define D_RG_LOW (FEAT_S + 1) |
| 59 | #define D_BW_LOW (D_RG_LOW + 1) |
| 60 | #define D_REDX (D_BW_LOW + 1) |
| 61 | #define D_REDY (D_REDX + 1) |
| 62 | #define D_GREENX (D_REDY + 1) |
| 63 | #define D_GREENY (D_GREENX + 1) |
| 64 | #define D_BLUEX (D_GREENY + 1) |
| 65 | #define D_BLUEY (D_BLUEX + 1) |
| 66 | #define D_WHITEX (D_BLUEY + 1) |
| 67 | #define D_WHITEY (D_WHITEX + 1) |
| 68 | #define DISPLAY_LENGTH (D_WHITEY + 1) |
| 69 | |
| 70 | /* supported VESA and other standard timings */ |
| 71 | #define ESTABLISHED_TIMING_SECTION (DISPLAY_SECTION + DISPLAY_LENGTH) |
| 72 | #define E_T1 0 |
| 73 | #define E_T2 (E_T1 + 1) |
| 74 | #define E_TMANU (E_T2 + 1) |
| 75 | #define E_TIMING_LENGTH (E_TMANU + 1) |
| 76 | |
| 77 | /* non predefined standard timings supported by display */ |
| 78 | #define STD_TIMING_SECTION (ESTABLISHED_TIMING_SECTION + E_TIMING_LENGTH) |
| 79 | #define STD_TIMING_INFO_LEN 2 |
| 80 | #define STD_TIMING_INFO_NUM STD_TIMINGS |
| 81 | #define STD_TIMING_LENGTH (STD_TIMING_INFO_LEN * STD_TIMING_INFO_NUM) |
| 82 | |
| 83 | /* detailed timing info of non standard timings */ |
| 84 | #define DET_TIMING_SECTION (STD_TIMING_SECTION + STD_TIMING_LENGTH) |
| 85 | #define DET_TIMING_INFO_LEN 18 |
| 86 | #define MONITOR_DESC_LEN DET_TIMING_INFO_LEN |
| 87 | #define DET_TIMING_INFO_NUM DET_TIMINGS |
| 88 | #define DET_TIMING_LENGTH (DET_TIMING_INFO_LEN * DET_TIMING_INFO_NUM) |
| 89 | |
| 90 | /* number of EDID sections to follow */ |
| 91 | #define NO_EDID (DET_TIMING_SECTION + DET_TIMING_LENGTH) |
| 92 | /* one byte checksum */ |
| 93 | #define CHECKSUM (NO_EDID + 1) |
| 94 | |
| 95 | #if (CHECKSUM != (EDID1_LEN - 1)) |
| 96 | #error "EDID1 length != 128!" |
| 97 | #endif |
| 98 | |
| 99 | #define SECTION(x,y) (Uchar *)(x + y) |
| 100 | #define GET_ARRAY(y) ((Uchar *)(c + y)) |
| 101 | #define GET(y) *(Uchar *)(c + y) |
| 102 | |
| 103 | /* extract information from vendor section */ |
| 104 | #define _PROD_ID(x) x[0] + (x[1] << 8); |
| 105 | #define PROD_ID _PROD_ID(GET_ARRAY(V_PROD_ID)) |
| 106 | #define _SERIAL_NO(x) x[0] + (x[1] << 8) + (x[2] << 16) + (x[3] << 24) |
| 107 | #define SERIAL_NO _SERIAL_NO(GET_ARRAY(V_SERIAL)) |
| 108 | #define _YEAR(x) (x & 0xFF) + 1990 |
| 109 | #define YEAR _YEAR(GET(V_YEAR)) |
| 110 | #define WEEK GET(V_WEEK) & 0xFF |
| 111 | #define _L1(x) ((x[0] & 0x7C) >> 2) + '@' |
| 112 | #define _L2(x) ((x[0] & 0x03) << 3) + ((x[1] & 0xE0) >> 5) + '@' |
| 113 | #define _L3(x) (x[1] & 0x1F) + '@'; |
| 114 | #define L1 _L1(GET_ARRAY(V_MANUFACTURER)) |
| 115 | #define L2 _L2(GET_ARRAY(V_MANUFACTURER)) |
| 116 | #define L3 _L3(GET_ARRAY(V_MANUFACTURER)) |
| 117 | |
| 118 | /* extract information from version section */ |
| 119 | #define VERSION GET(V_VERSION) |
| 120 | #define REVISION GET(V_REVISION) |
| 121 | |
| 122 | /* extract information from display section */ |
| 123 | #define _INPUT_TYPE(x) ((x & 0x80) >> 7) |
| 124 | #define INPUT_TYPE _INPUT_TYPE(GET(D_INPUT)) |
| 125 | #define _INPUT_VOLTAGE(x) ((x & 0x60) >> 5) |
| 126 | #define INPUT_VOLTAGE _INPUT_VOLTAGE(GET(D_INPUT)) |
| 127 | #define _SETUP(x) ((x & 0x10) >> 4) |
| 128 | #define SETUP _SETUP(GET(D_INPUT)) |
| 129 | #define _SYNC(x) (x & 0x0F) |
| 130 | #define SYNC _SYNC(GET(D_INPUT)) |
| 131 | #define _DFP(x) (x & 0x01) |
| 132 | #define DFP _DFP(GET(D_INPUT)) |
| 133 | #define _BPC(x) ((x & 0x70) >> 4) |
| 134 | #define BPC _BPC(GET(D_INPUT)) |
| 135 | #define _DIGITAL_INTERFACE(x) (x & 0x0F) |
| 136 | #define DIGITAL_INTERFACE _DIGITAL_INTERFACE(GET(D_INPUT)) |
| 137 | #define _GAMMA(x) (x == 0xff ? 0.0 : ((x + 100.0)/100.0)) |
| 138 | #define GAMMA _GAMMA(GET(D_GAMMA)) |
| 139 | #define HSIZE_MAX GET(D_HSIZE) |
| 140 | #define VSIZE_MAX GET(D_VSIZE) |
| 141 | #define _DPMS(x) ((x & 0xE0) >> 5) |
| 142 | #define DPMS _DPMS(GET(FEAT_S)) |
| 143 | #define _DISPLAY_TYPE(x) ((x & 0x18) >> 3) |
| 144 | #define DISPLAY_TYPE _DISPLAY_TYPE(GET(FEAT_S)) |
| 145 | #define _MSC(x) (x & 0x7) |
| 146 | #define MSC _MSC(GET(FEAT_S)) |
| 147 | |
| 148 | /* color characteristics */ |
| 149 | #define CC_L(x,y) ((x & (0x03 << y)) >> y) |
| 150 | #define CC_H(x) (x << 2) |
| 151 | #define I_CC(x,y,z) CC_H(y) | CC_L(x,z) |
| 152 | #define F_CC(x) ((x)/1024.0) |
| 153 | #define REDX F_CC(I_CC((GET(D_RG_LOW)),(GET(D_REDX)),6)) |
| 154 | #define REDY F_CC(I_CC((GET(D_RG_LOW)),(GET(D_REDY)),4)) |
| 155 | #define GREENX F_CC(I_CC((GET(D_RG_LOW)),(GET(D_GREENX)),2)) |
| 156 | #define GREENY F_CC(I_CC((GET(D_RG_LOW)),(GET(D_GREENY)),0)) |
| 157 | #define BLUEX F_CC(I_CC((GET(D_BW_LOW)),(GET(D_BLUEX)),6)) |
| 158 | #define BLUEY F_CC(I_CC((GET(D_BW_LOW)),(GET(D_BLUEY)),4)) |
| 159 | #define WHITEX F_CC(I_CC((GET(D_BW_LOW)),(GET(D_WHITEX)),2)) |
| 160 | #define WHITEY F_CC(I_CC((GET(D_BW_LOW)),(GET(D_WHITEY)),0)) |
| 161 | |
| 162 | /* extract information from standard timing section */ |
| 163 | #define T1 GET(E_T1) |
| 164 | #define T2 GET(E_T2) |
| 165 | #define T_MANU GET(E_TMANU) |
| 166 | |
| 167 | /* extract information from estabished timing section */ |
| 168 | #define _VALID_TIMING(x) !(((x[0] == 0x01) && (x[1] == 0x01)) \ |
| 169 | || ((x[0] == 0x00) && (x[1] == 0x00)) \ |
| 170 | || ((x[0] == 0x20) && (x[1] == 0x20)) ) |
| 171 | #define VALID_TIMING _VALID_TIMING(c) |
| 172 | #define _HSIZE1(x) ((x[0] + 31) * 8) |
| 173 | #define HSIZE1 _HSIZE1(c) |
| 174 | #define RATIO(x) ((x[1] & 0xC0) >> 6) |
| 175 | #define RATIO1_1 0 |
| 176 | /* EDID Ver. 1.3 redefined this */ |
| 177 | #define RATIO16_10 RATIO1_1 |
| 178 | #define RATIO4_3 1 |
| 179 | #define RATIO5_4 2 |
| 180 | #define RATIO16_9 3 |
| 181 | #define _VSIZE1(x,y,r) switch(RATIO(x)){ \ |
| 182 | case RATIO1_1: y = ((v->version > 1 || v->revision > 2) \ |
| 183 | ? (_HSIZE1(x) * 10) / 16 : _HSIZE1(x)); break; \ |
| 184 | case RATIO4_3: y = _HSIZE1(x) * 3 / 4; break; \ |
| 185 | case RATIO5_4: y = _HSIZE1(x) * 4 / 5; break; \ |
| 186 | case RATIO16_9: y = _HSIZE1(x) * 9 / 16; break; \ |
| 187 | } |
| 188 | #define VSIZE1(x) _VSIZE1(c,x,v) |
| 189 | #define _REFRESH_R(x) (x[1] & 0x3F) + 60 |
| 190 | #define REFRESH_R _REFRESH_R(c) |
| 191 | #define _ID_LOW(x) x[0] |
| 192 | #define ID_LOW _ID_LOW(c) |
| 193 | #define _ID_HIGH(x) (x[1] << 8) |
| 194 | #define ID_HIGH _ID_HIGH(c) |
| 195 | #define STD_TIMING_ID (ID_LOW | ID_HIGH) |
| 196 | #define _NEXT_STD_TIMING(x) (x = (x + STD_TIMING_INFO_LEN)) |
| 197 | #define NEXT_STD_TIMING _NEXT_STD_TIMING(c) |
| 198 | |
| 199 | /* EDID Ver. >= 1.2 */ |
| 200 | /** |
| 201 | * Returns true if the pointer is the start of a monitor descriptor block |
| 202 | * instead of a detailed timing descriptor. |
| 203 | * |
| 204 | * Checking the reserved pad fields for zeroes fails on some monitors with |
| 205 | * broken empty ASCII strings. Only the first two bytes are reliable. |
| 206 | */ |
| 207 | #define _IS_MONITOR_DESC(x) (x[0] == 0 && x[1] == 0) |
| 208 | #define IS_MONITOR_DESC _IS_MONITOR_DESC(c) |
| 209 | #define _PIXEL_CLOCK(x) (x[0] + (x[1] << 8)) * 10000 |
| 210 | #define PIXEL_CLOCK _PIXEL_CLOCK(c) |
| 211 | #define _H_ACTIVE(x) (x[2] + ((x[4] & 0xF0) << 4)) |
| 212 | #define H_ACTIVE _H_ACTIVE(c) |
| 213 | #define _H_BLANK(x) (x[3] + ((x[4] & 0x0F) << 8)) |
| 214 | #define H_BLANK _H_BLANK(c) |
| 215 | #define _V_ACTIVE(x) (x[5] + ((x[7] & 0xF0) << 4)) |
| 216 | #define V_ACTIVE _V_ACTIVE(c) |
| 217 | #define _V_BLANK(x) (x[6] + ((x[7] & 0x0F) << 8)) |
| 218 | #define V_BLANK _V_BLANK(c) |
| 219 | #define _H_SYNC_OFF(x) (x[8] + ((x[11] & 0xC0) << 2)) |
| 220 | #define H_SYNC_OFF _H_SYNC_OFF(c) |
| 221 | #define _H_SYNC_WIDTH(x) (x[9] + ((x[11] & 0x30) << 4)) |
| 222 | #define H_SYNC_WIDTH _H_SYNC_WIDTH(c) |
| 223 | #define _V_SYNC_OFF(x) ((x[10] >> 4) + ((x[11] & 0x0C) << 2)) |
| 224 | #define V_SYNC_OFF _V_SYNC_OFF(c) |
| 225 | #define _V_SYNC_WIDTH(x) ((x[10] & 0x0F) + ((x[11] & 0x03) << 4)) |
| 226 | #define V_SYNC_WIDTH _V_SYNC_WIDTH(c) |
| 227 | #define _H_SIZE(x) (x[12] + ((x[14] & 0xF0) << 4)) |
| 228 | #define H_SIZE _H_SIZE(c) |
| 229 | #define _V_SIZE(x) (x[13] + ((x[14] & 0x0F) << 8)) |
| 230 | #define V_SIZE _V_SIZE(c) |
| 231 | #define _H_BORDER(x) (x[15]) |
| 232 | #define H_BORDER _H_BORDER(c) |
| 233 | #define _V_BORDER(x) (x[16]) |
| 234 | #define V_BORDER _V_BORDER(c) |
| 235 | #define _INTERLACED(x) ((x[17] & 0x80) >> 7) |
| 236 | #define INTERLACED _INTERLACED(c) |
| 237 | #define _STEREO(x) ((x[17] & 0x60) >> 5) |
| 238 | #define STEREO _STEREO(c) |
| 239 | #define _STEREO1(x) (x[17] & 0x1) |
| 240 | #define STEREO1 _STEREO(c) |
| 241 | #define _SYNC_T(x) ((x[17] & 0x18) >> 3) |
| 242 | #define SYNC_T _SYNC_T(c) |
| 243 | #define _MISC(x) ((x[17] & 0x06) >> 1) |
| 244 | #define MISC _MISC(c) |
| 245 | |
| 246 | #define _MONITOR_DESC_TYPE(x) x[3] |
| 247 | #define MONITOR_DESC_TYPE _MONITOR_DESC_TYPE(c) |
| 248 | #define SERIAL_NUMBER 0xFF |
| 249 | #define ASCII_STR 0xFE |
| 250 | #define MONITOR_RANGES 0xFD |
| 251 | #define _MIN_V_OFFSET(x) ((!!(x[4] & 0x01)) * 255) |
| 252 | #define _MAX_V_OFFSET(x) ((!!(x[4] & 0x02)) * 255) |
| 253 | #define _MIN_H_OFFSET(x) ((!!(x[4] & 0x04)) * 255) |
| 254 | #define _MAX_H_OFFSET(x) ((!!(x[4] & 0x08)) * 255) |
| 255 | #define _MIN_V(x) x[5] |
| 256 | #define MIN_V (_MIN_V(c) + _MIN_V_OFFSET(c)) |
| 257 | #define _MAX_V(x) x[6] |
| 258 | #define MAX_V (_MAX_V(c) + _MAX_V_OFFSET(c)) |
| 259 | #define _MIN_H(x) x[7] |
| 260 | #define MIN_H (_MIN_H(c) + _MIN_H_OFFSET(c)) |
| 261 | #define _MAX_H(x) x[8] |
| 262 | #define MAX_H (_MAX_H(c) + _MAX_H_OFFSET(c)) |
| 263 | #define _MAX_CLOCK(x) x[9] |
| 264 | #define MAX_CLOCK _MAX_CLOCK(c) |
| 265 | #define _HAVE_2ND_GTF(x) (x[10] == 0x02) |
| 266 | #define HAVE_2ND_GTF _HAVE_2ND_GTF(c) |
| 267 | #define _F_2ND_GTF(x) (x[12] * 2) |
| 268 | #define F_2ND_GTF _F_2ND_GTF(c) |
| 269 | #define _C_2ND_GTF(x) (x[13] / 2) |
| 270 | #define C_2ND_GTF _C_2ND_GTF(c) |
| 271 | #define _M_2ND_GTF(x) (x[14] + (x[15] << 8)) |
| 272 | #define M_2ND_GTF _M_2ND_GTF(c) |
| 273 | #define _K_2ND_GTF(x) (x[16]) |
| 274 | #define K_2ND_GTF _K_2ND_GTF(c) |
| 275 | #define _J_2ND_GTF(x) (x[17] / 2) |
| 276 | #define J_2ND_GTF _J_2ND_GTF(c) |
| 277 | #define _HAVE_CVT(x) (x[10] == 0x04) |
| 278 | #define HAVE_CVT _HAVE_CVT(c) |
| 279 | #define _MAX_CLOCK_KHZ(x) (x[12] >> 2) |
| 280 | #define MAX_CLOCK_KHZ (MAX_CLOCK * 10000) - (_MAX_CLOCK_KHZ(c) * 250) |
| 281 | #define _MAXWIDTH(x) ((x[13] == 0 ? 0 : x[13] + ((x[12] & 0x03) << 8)) * 8) |
| 282 | #define MAXWIDTH _MAXWIDTH(c) |
| 283 | #define _SUPPORTED_ASPECT(x) x[14] |
| 284 | #define SUPPORTED_ASPECT _SUPPORTED_ASPECT(c) |
| 285 | #define SUPPORTED_ASPECT_4_3 0x80 |
| 286 | #define SUPPORTED_ASPECT_16_9 0x40 |
| 287 | #define SUPPORTED_ASPECT_16_10 0x20 |
| 288 | #define SUPPORTED_ASPECT_5_4 0x10 |
| 289 | #define SUPPORTED_ASPECT_15_9 0x08 |
| 290 | #define _PREFERRED_ASPECT(x) ((x[15] & 0xe0) >> 5) |
| 291 | #define PREFERRED_ASPECT _PREFERRED_ASPECT(c) |
| 292 | #define PREFERRED_ASPECT_4_3 0 |
| 293 | #define PREFERRED_ASPECT_16_9 1 |
| 294 | #define PREFERRED_ASPECT_16_10 2 |
| 295 | #define PREFERRED_ASPECT_5_4 3 |
| 296 | #define PREFERRED_ASPECT_15_9 4 |
| 297 | #define _SUPPORTED_BLANKING(x) ((x[15] & 0x18) >> 3) |
| 298 | #define SUPPORTED_BLANKING _SUPPORTED_BLANKING(c) |
| 299 | #define CVT_STANDARD 0x01 |
| 300 | #define CVT_REDUCED 0x02 |
| 301 | #define _SUPPORTED_SCALING(x) ((x[16] & 0xf0) >> 4) |
| 302 | #define SUPPORTED_SCALING _SUPPORTED_SCALING(c) |
| 303 | #define SCALING_HSHRINK 0x08 |
| 304 | #define SCALING_HSTRETCH 0x04 |
| 305 | #define SCALING_VSHRINK 0x02 |
| 306 | #define SCALING_VSTRETCH 0x01 |
| 307 | #define _PREFERRED_REFRESH(x) x[17] |
| 308 | #define PREFERRED_REFRESH _PREFERRED_REFRESH(c) |
| 309 | |
| 310 | #define MONITOR_NAME 0xFC |
| 311 | #define ADD_COLOR_POINT 0xFB |
| 312 | #define WHITEX F_CC(I_CC((GET(D_BW_LOW)),(GET(D_WHITEX)),2)) |
| 313 | #define WHITEY F_CC(I_CC((GET(D_BW_LOW)),(GET(D_WHITEY)),0)) |
| 314 | #define _WHITEX_ADD(x,y) F_CC(I_CC(((*(x + y))),(*(x + y + 1)),2)) |
| 315 | #define _WHITEY_ADD(x,y) F_CC(I_CC(((*(x + y))),(*(x + y + 2)),0)) |
| 316 | #define _WHITE_INDEX1(x) x[5] |
| 317 | #define WHITE_INDEX1 _WHITE_INDEX1(c) |
| 318 | #define _WHITE_INDEX2(x) x[10] |
| 319 | #define WHITE_INDEX2 _WHITE_INDEX2(c) |
| 320 | #define WHITEX1 _WHITEX_ADD(c,6) |
| 321 | #define WHITEY1 _WHITEY_ADD(c,6) |
| 322 | #define WHITEX2 _WHITEX_ADD(c,12) |
| 323 | #define WHITEY2 _WHITEY_ADD(c,12) |
| 324 | #define _WHITE_GAMMA1(x) _GAMMA(x[9]) |
| 325 | #define WHITE_GAMMA1 _WHITE_GAMMA1(c) |
| 326 | #define _WHITE_GAMMA2(x) _GAMMA(x[14]) |
| 327 | #define WHITE_GAMMA2 _WHITE_GAMMA2(c) |
| 328 | #define ADD_STD_TIMINGS 0xFA |
| 329 | #define COLOR_MANAGEMENT_DATA 0xF9 |
| 330 | #define CVT_3BYTE_DATA 0xF8 |
| 331 | #define ADD_EST_TIMINGS 0xF7 |
| 332 | #define ADD_DUMMY 0x10 |
| 333 | |
| 334 | #define _NEXT_DT_MD_SECTION(x) (x = (x + DET_TIMING_INFO_LEN)) |
| 335 | #define NEXT_DT_MD_SECTION _NEXT_DT_MD_SECTION(c) |
| 336 | |
| 337 | #endif /* _PARSE_EDID_ */ |
| 338 | |
| 339 | /* input type */ |
| 340 | #define DIGITAL(x) x |
| 341 | |
| 342 | /* DFP */ |
| 343 | #define DFP1(x) x |
| 344 | |
| 345 | /* input voltage level */ |
| 346 | #define V070 0 /* 0.700V/0.300V */ |
| 347 | #define V071 1 /* 0.714V/0.286V */ |
| 348 | #define V100 2 /* 1.000V/0.400V */ |
| 349 | #define V007 3 /* 0.700V/0.000V */ |
| 350 | |
| 351 | /* Signal level setup */ |
| 352 | #define SIG_SETUP(x) (x) |
| 353 | |
| 354 | /* sync characteristics */ |
| 355 | #define SEP_SYNC(x) (x & 0x08) |
| 356 | #define COMP_SYNC(x) (x & 0x04) |
| 357 | #define SYNC_O_GREEN(x) (x & 0x02) |
| 358 | #define SYNC_SERR(x) (x & 0x01) |
| 359 | |
| 360 | /* DPMS features */ |
| 361 | #define DPMS_STANDBY(x) (x & 0x04) |
| 362 | #define DPMS_SUSPEND(x) (x & 0x02) |
| 363 | #define DPMS_OFF(x) (x & 0x01) |
| 364 | |
| 365 | /* display type, analog */ |
| 366 | #define DISP_MONO 0 |
| 367 | #define DISP_RGB 1 |
| 368 | #define DISP_MULTCOLOR 2 |
| 369 | |
| 370 | /* display color encodings, digital */ |
| 371 | #define DISP_YCRCB444 0x01 |
| 372 | #define DISP_YCRCB422 0x02 |
| 373 | |
| 374 | /* Msc stuff EDID Ver > 1.1 */ |
| 375 | #define STD_COLOR_SPACE(x) (x & 0x4) |
| 376 | #define PREFERRED_TIMING_MODE(x) (x & 0x2) |
| 377 | #define GFT_SUPPORTED(x) (x & 0x1) |
| 378 | #define GTF_SUPPORTED(x) (x & 0x1) |
| 379 | #define CVT_SUPPORTED(x) (x & 0x1) |
| 380 | |
| 381 | /* detailed timing misc */ |
| 382 | #define IS_INTERLACED(x) (x) |
| 383 | #define IS_STEREO(x) (x) |
| 384 | #define IS_RIGHT_STEREO(x) (x & 0x01) |
| 385 | #define IS_LEFT_STEREO(x) (x & 0x02) |
| 386 | #define IS_4WAY_STEREO(x) (x & 0x03) |
| 387 | #define IS_RIGHT_ON_SYNC(x) IS_RIGHT_STEREO(x) |
| 388 | #define IS_LEFT_ON_SYNC(x) IS_LEFT_STEREO(x) |
| 389 | |
| 390 | typedef unsigned int Uint; |
| 391 | typedef unsigned char Uchar; |
| 392 | |
| 393 | struct vendor { |
| 394 | char name[4]; |
| 395 | int prod_id; |
| 396 | Uint serial; |
| 397 | int week; |
| 398 | int year; |
| 399 | }; |
| 400 | |
| 401 | struct edid_version { |
| 402 | int version; |
| 403 | int revision; |
| 404 | }; |
| 405 | |
| 406 | struct disp_features { |
| 407 | unsigned int input_type:1; |
| 408 | unsigned int input_voltage:2; |
| 409 | unsigned int input_setup:1; |
| 410 | unsigned int input_sync:5; |
| 411 | unsigned int input_dfp:1; |
| 412 | unsigned int input_bpc:3; |
| 413 | unsigned int input_interface:4; |
| 414 | /* 15 bit hole */ |
| 415 | int hsize; |
| 416 | int vsize; |
| 417 | float gamma; |
| 418 | unsigned int dpms:3; |
| 419 | unsigned int display_type:2; |
| 420 | unsigned int msc:3; |
| 421 | float redx; |
| 422 | float redy; |
| 423 | float greenx; |
| 424 | float greeny; |
| 425 | float bluex; |
| 426 | float bluey; |
| 427 | float whitex; |
| 428 | float whitey; |
| 429 | }; |
| 430 | |
| 431 | struct established_timings { |
| 432 | Uchar t1; |
| 433 | Uchar t2; |
| 434 | Uchar t_manu; |
| 435 | }; |
| 436 | |
| 437 | struct std_timings { |
| 438 | int hsize; |
| 439 | int vsize; |
| 440 | int refresh; |
| 441 | CARD16 id; |
| 442 | }; |
| 443 | |
| 444 | struct detailed_timings { |
| 445 | int clock; |
| 446 | int h_active; |
| 447 | int h_blanking; |
| 448 | int v_active; |
| 449 | int v_blanking; |
| 450 | int h_sync_off; |
| 451 | int h_sync_width; |
| 452 | int v_sync_off; |
| 453 | int v_sync_width; |
| 454 | int h_size; |
| 455 | int v_size; |
| 456 | int h_border; |
| 457 | int v_border; |
| 458 | unsigned int interlaced:1; |
| 459 | unsigned int stereo:2; |
| 460 | unsigned int sync:2; |
| 461 | unsigned int misc:2; |
| 462 | unsigned int stereo_1:1; |
| 463 | }; |
| 464 | |
| 465 | #define DT 0 |
| 466 | #define DS_SERIAL 0xFF |
| 467 | #define DS_ASCII_STR 0xFE |
| 468 | #define DS_NAME 0xFC |
| 469 | #define DS_RANGES 0xFD |
| 470 | #define DS_WHITE_P 0xFB |
| 471 | #define DS_STD_TIMINGS 0xFA |
| 472 | #define DS_CMD 0xF9 |
| 473 | #define DS_CVT 0xF8 |
| 474 | #define DS_EST_III 0xF7 |
| 475 | #define DS_DUMMY 0x10 |
| 476 | #define DS_UNKOWN 0x100 /* type is an int */ |
| 477 | #define DS_VENDOR 0x101 |
| 478 | #define DS_VENDOR_MAX 0x110 |
| 479 | |
| 480 | struct monitor_ranges { |
| 481 | int min_v; |
| 482 | int max_v; |
| 483 | int min_h; |
| 484 | int max_h; |
| 485 | int max_clock; /* in mhz */ |
| 486 | int gtf_2nd_f; |
| 487 | int gtf_2nd_c; |
| 488 | int gtf_2nd_m; |
| 489 | int gtf_2nd_k; |
| 490 | int gtf_2nd_j; |
| 491 | int max_clock_khz; |
| 492 | int maxwidth; /* in pixels */ |
| 493 | char supported_aspect; |
| 494 | char preferred_aspect; |
| 495 | char supported_blanking; |
| 496 | char supported_scaling; |
| 497 | int preferred_refresh; /* in hz */ |
| 498 | }; |
| 499 | |
| 500 | struct whitePoints { |
| 501 | int index; |
| 502 | float white_x; |
| 503 | float white_y; |
| 504 | float white_gamma; |
| 505 | }; |
| 506 | |
| 507 | struct cvt_timings { |
| 508 | int width; |
| 509 | int height; |
| 510 | int rate; |
| 511 | int rates; |
| 512 | }; |
| 513 | |
| 514 | /* |
| 515 | * Be careful when adding new sections; this structure can't grow, it's |
| 516 | * embedded in the middle of xf86Monitor which is ABI. Sizes below are |
| 517 | * in bytes, for ILP32 systems. If all else fails just copy the section |
| 518 | * literally like serial and friends. |
| 519 | */ |
| 520 | struct detailed_monitor_section { |
| 521 | int type; |
| 522 | union { |
| 523 | struct detailed_timings d_timings; /* 56 */ |
| 524 | Uchar serial[13]; |
| 525 | Uchar ascii_data[13]; |
| 526 | Uchar name[13]; |
| 527 | struct monitor_ranges ranges; /* 56 */ |
| 528 | struct std_timings std_t[5]; /* 80 */ |
| 529 | struct whitePoints wp[2]; /* 32 */ |
| 530 | /* color management data */ |
| 531 | struct cvt_timings cvt[4]; /* 64 */ |
| 532 | Uchar est_iii[6]; /* 6 */ |
| 533 | } section; /* max: 80 */ |
| 534 | }; |
| 535 | |
| 536 | /* flags */ |
| 537 | #define MONITOR_EDID_COMPLETE_RAWDATA 0x01 |
| 538 | /* old, don't use */ |
| 539 | #define EDID_COMPLETE_RAWDATA 0x01 |
| 540 | #define MONITOR_DISPLAYID 0x02 |
| 541 | |
| 542 | /* |
| 543 | * For DisplayID devices, only the scrnIndex, flags, and rawData fields |
| 544 | * are meaningful. For EDID, they all are. |
| 545 | */ |
| 546 | typedef struct { |
| 547 | int scrnIndex; |
| 548 | struct vendor vendor; |
| 549 | struct edid_version ver; |
| 550 | struct disp_features features; |
| 551 | struct established_timings timings1; |
| 552 | struct std_timings timings2[8]; |
| 553 | struct detailed_monitor_section det_mon[4]; |
| 554 | unsigned long flags; |
| 555 | int no_sections; |
| 556 | Uchar *rawData; |
| 557 | } xf86Monitor, *xf86MonPtr; |
| 558 | |
| 559 | extern _X_EXPORT xf86MonPtr ConfiguredMonitor; |
| 560 | |
| 561 | #define EXT_TAG 0 |
| 562 | #define EXT_REV 1 |
| 563 | #define CEA_EXT 0x02 |
| 564 | #define VTB_EXT 0x10 |
| 565 | #define DI_EXT 0x40 |
| 566 | #define LS_EXT 0x50 |
| 567 | #define MI_EXT 0x60 |
| 568 | |
| 569 | #define CEA_EXT_MIN_DATA_OFFSET 4 |
| 570 | #define CEA_EXT_MAX_DATA_OFFSET 127 |
| 571 | #define CEA_EXT_DET_TIMING_NUM 6 |
| 572 | |
| 573 | #define IEEE_ID_HDMI 0x000C03 |
| 574 | #define CEA_AUDIO_BLK 1 |
| 575 | #define CEA_VIDEO_BLK 2 |
| 576 | #define CEA_VENDOR_BLK 3 |
| 577 | #define CEA_SPEAKER_ALLOC_BLK 4 |
| 578 | #define CEA_VESA_DTC_BLK 5 |
| 579 | #define VENDOR_SUPPORT_AI(x) ((x) >> 7) |
| 580 | #define VENDOR_SUPPORT_DC_48bit(x) ( ( (x) >> 6) & 0x01) |
| 581 | #define VENDOR_SUPPORT_DC_36bit(x) ( ( (x) >> 5) & 0x01) |
| 582 | #define VENDOR_SUPPORT_DC_30bit(x) ( ( (x) >> 4) & 0x01) |
| 583 | #define VENDOR_SUPPORT_DC_Y444(x) ( ( (x) >> 3) & 0x01) |
| 584 | #define VENDOR_LATENCY_PRESENT(x) ( (x) >> 7) |
| 585 | #define VENDOR_LATENCY_PRESENT_I(x) ( ( (x) >> 6) & 0x01) |
| 586 | #define HDMI_MAX_TMDS_UNIT (5000) |
| 587 | |
| 588 | struct cea_video_block { |
| 589 | Uchar video_code; |
| 590 | }; |
| 591 | |
| 592 | struct cea_audio_block_descriptor { |
| 593 | Uchar audio_code[3]; |
| 594 | }; |
| 595 | |
| 596 | struct cea_audio_block { |
| 597 | struct cea_audio_block_descriptor descriptor[10]; |
| 598 | }; |
| 599 | |
| 600 | struct cea_vendor_block_hdmi { |
| 601 | Uchar portB:4; |
| 602 | Uchar portA:4; |
| 603 | Uchar portD:4; |
| 604 | Uchar portC:4; |
| 605 | Uchar support_flags; |
| 606 | Uchar max_tmds_clock; |
| 607 | Uchar latency_present; |
| 608 | Uchar video_latency; |
| 609 | Uchar audio_latency; |
| 610 | Uchar interlaced_video_latency; |
| 611 | Uchar interlaced_audio_latency; |
| 612 | }; |
| 613 | |
| 614 | struct cea_vendor_block { |
| 615 | unsigned char ieee_id[3]; |
| 616 | union { |
| 617 | struct cea_vendor_block_hdmi hdmi; |
| 618 | /* any other vendor blocks we know about */ |
| 619 | }; |
| 620 | }; |
| 621 | |
| 622 | struct cea_speaker_block { |
| 623 | Uchar FLR:1; |
| 624 | Uchar LFE:1; |
| 625 | Uchar FC:1; |
| 626 | Uchar RLR:1; |
| 627 | Uchar RC:1; |
| 628 | Uchar FLRC:1; |
| 629 | Uchar RLRC:1; |
| 630 | Uchar FLRW:1; |
| 631 | Uchar FLRH:1; |
| 632 | Uchar TC:1; |
| 633 | Uchar FCH:1; |
| 634 | Uchar Resv:5; |
| 635 | Uchar ResvByte; |
| 636 | }; |
| 637 | |
| 638 | struct cea_data_block { |
| 639 | Uchar len:5; |
| 640 | Uchar tag:3; |
| 641 | union { |
| 642 | struct cea_video_block video; |
| 643 | struct cea_audio_block audio; |
| 644 | struct cea_vendor_block vendor; |
| 645 | struct cea_speaker_block speaker; |
| 646 | } u; |
| 647 | }; |
| 648 | |
| 649 | struct cea_ext_body { |
| 650 | Uchar tag; |
| 651 | Uchar rev; |
| 652 | Uchar dt_offset; |
| 653 | Uchar flags; |
| 654 | struct cea_data_block data_collection; |
| 655 | }; |
| 656 | |
| 657 | #endif /* _EDID_H_ */ |