1 /* 2 Copyright (c) 2003, Thomas Kurschel 3 4 5 Part of DDC driver 6 7 Raw EDID data block. 8 9 Raw data are packed in a really weird way. Never even 10 think about using it directly, instead translate it via decode_edidpixel_clock 11 first. I did my best to make the code endian-independant, but 12 I cannot guarantee that I haven't missed something. 13 */ 14 15 #ifndef _EDID_RAW_H 16 #define _EDID_RAW_H 17 18 #include "bendian_bitfield.h" 19 20 #define EDID1_NUM_DETAILED_MONITOR_DESC 4 21 #define EDID1_NUM_STD_TIMING 8 22 #define EDID1_NUM_EXTRA_STD_TIMING 6 23 #define EDID1_EXTRA_STRING_LEN 13 24 #define EDID1_NUM_EXTRA_WHITEPOINTS 2 25 26 27 // header 28 typedef struct _PACKED { 29 int8 pad[8]; // contains 0, -1, -1, -1, -1, -1, -1, 0 30 } edid1_header_raw; 31 32 33 // vendor info 34 typedef struct _PACKED { 35 BBITFIELD8_3 ( // manufacturer 36 pad : 1, 37 c1 : 5, // add '@' to get ascii 38 c2_high : 2 39 ); 40 BBITFIELD8_2 ( 41 c2_low : 3, 42 c3 : 5 43 ); 44 uint16 prod_id; 45 uint32 serial; 46 uint8 week; 47 uint8 year; // x+1990 48 } edid1_vendor_raw; 49 50 51 // version info 52 typedef struct _PACKED { 53 uint8 version; 54 uint8 revision; 55 } edid1_version_raw; 56 57 58 // display info 59 typedef struct _PACKED { 60 BBITFIELD8_7 ( 61 input_type : 1, // 1 : digital 62 input_voltage : 2, // 0=0.7V/0.3V, 1=0.714V/0.286, 63 // 2=1V/0.4V, 3=0.7V/0V 64 setup : 1, // true if voltage configurable 65 sep_sync : 1, 66 comp_sync : 1, 67 sync_on_green : 1, 68 sync_serr : 1 69 ); 70 uint8 h_size; 71 uint8 v_size; 72 uint8 gamma; // (x+100)/100 73 BBITFIELD8_7 ( 74 dpms_standby : 1, 75 dpms_suspend : 1, 76 dpms_off : 1, 77 display_type : 2, // 0=mono, 1=rgb, 2=multicolour 78 // since EDID version 1.1 79 std_colour_space : 1, 80 preferred_timing_mode : 1, 81 gtf_supported : 1 82 ); 83 BBITFIELD8_4 ( // low bits of red_x etc. 84 red_x_low : 2, 85 red_y_low : 2, 86 green_x_low : 2, 87 green_y_low : 2 88 ); 89 BBITFIELD8_4 ( 90 blue_x_low : 2, 91 blue_y_low : 2, 92 white_x_low : 2, 93 white_y_low : 2 94 ); 95 uint8 red_x; // all colours are 0.10 fixed point 96 uint8 red_y; 97 uint8 green_x; 98 uint8 green_y; 99 uint8 blue_x; 100 uint8 blue_y; 101 uint8 white_x; 102 uint8 white_y; 103 } edid1_display_raw; 104 105 106 // raw standard timing data 107 typedef union _PACKED { 108 struct _PACKED { 109 uint8 h_size; // (x+31)*8 110 BBITFIELD8_2 ( 111 ratio : 2, // 0=1:1, 1=3/4, 2=4/5, 3=9/16 112 refresh : 6 // (x+60) 113 ); 114 } timing; 115 uint16 id; 116 } edid1_std_timing_raw; 117 118 119 // list of supported fixed timings 120 typedef struct _PACKED { 121 BBITFIELD8_8 ( 122 res_720x400x70 : 1, 123 res_720x400x88 : 1, 124 res_640x480x60 : 1, 125 res_640x480x67 : 1, 126 res_640x480x72 : 1, 127 res_640x480x75 : 1, 128 res_800x600x56 : 1, 129 res_800x600x60 : 1 130 ); 131 BBITFIELD8_8 ( 132 res_800x600x72 : 1, 133 res_800x600x75 : 1, 134 res_832x624x75 : 1, 135 res_1024x768x87i : 1, 136 res_1024x768x60 : 1, 137 res_1024x768x70 : 1, 138 res_1024x768x75 : 1, 139 res_1280x1024x75 : 1 140 ); 141 BBITFIELD8_2 ( 142 res_1152x870x75 : 1, 143 pad : 7 144 ); 145 } edid1_established_timing; 146 147 148 // types of detailed monitor description 149 enum { 150 edid1_serial_number = 0xff, 151 edid1_ascii_data = 0xfe, 152 edid1_monitor_ranges = 0xfd, 153 edid1_monitor_name = 0xfc, 154 edid1_add_colour_pointer = 0xfb, 155 edid1_add_std_timing = 0xfa, 156 edid1_is_detailed_timing = 1 157 }; 158 159 160 // monitor frequency range 161 typedef struct _PACKED { 162 uint8 min_v; 163 uint8 max_v; 164 uint8 min_h; 165 uint8 max_h; 166 uint8 max_clock; // in 10 MHz (!) 167 } edid1_monitor_range; 168 169 170 // additional whitepoint 171 typedef struct _PACKED { 172 uint8 index1; 173 BBITFIELD8_3 ( 174 pad1 : 4, 175 white_x1_low : 2, 176 white_y1_low : 2 177 ); 178 uint8 white_x1; 179 uint8 white_y1; 180 uint8 gamma1; // (x+100)/100 181 uint8 index2; 182 BBITFIELD8_3 ( 183 pad2 : 4, 184 white_x2_low : 2, 185 white_y2_low : 2 186 ); 187 uint8 white_x2; 188 uint8 white_y2; 189 uint8 gamma2; // (x+100)/100 190 } edid1_whitepoint_raw; 191 192 193 // detailed timing description 194 typedef struct _PACKED { 195 uint16 pixel_clock; // in 10 kHz (!) 196 uint8 h_active; 197 uint8 h_blank; 198 BBITFIELD8_2 ( 199 h_active_high : 4, 200 h_blank_high : 4 201 ); 202 uint8 v_active; 203 uint8 v_blank; 204 BBITFIELD8_2 ( 205 v_active_high : 4, 206 v_blank_high : 4 207 ); 208 uint8 h_sync_off; 209 uint8 h_sync_width; 210 BBITFIELD8_2 ( 211 v_sync_off : 4, 212 v_sync_width : 4 213 ); 214 BBITFIELD8_4 ( 215 h_sync_off_high : 2, 216 h_sync_width_high : 2, 217 v_sync_off_high : 2, 218 v_sync_width_high : 2 219 ); 220 uint8 h_size; 221 uint8 v_size; 222 BBITFIELD8_2 ( 223 h_size_high : 4, 224 v_size_high : 4 225 ); 226 uint8 h_border; 227 uint8 v_border; 228 BBITFIELD8_4 ( 229 interlaced : 1, 230 stereo : 2, // upper bit set - left on sync 231 // lower bit set - right on sync 232 sync : 2, 233 misc : 2 234 ); 235 } edid1_detailed_timing_raw; 236 237 238 // detailed monitor description 239 typedef union _PACKED { 240 edid1_detailed_timing_raw detailed_timing; 241 struct _PACKED { 242 uint8 zero_0[3]; 243 uint8 monitor_desc_type; 244 uint8 zero_4; 245 union _PACKED { 246 uint8 serial_number[EDID1_EXTRA_STRING_LEN]; 247 uint8 ascii_data[EDID1_EXTRA_STRING_LEN]; 248 uint8 monitor_name[EDID1_EXTRA_STRING_LEN]; 249 edid1_monitor_range monitor_range; 250 edid1_whitepoint_raw whitepoint; 251 edid1_std_timing_raw std_timing[EDID1_NUM_EXTRA_STD_TIMING]; 252 253 } data; 254 } extra; 255 } edid1_detailed_monitor_raw; 256 257 258 // raw EDID data 259 // everything is packed data, mixture of little endian and big endian 260 // and a bit brain dead overall - nothing your dad would be proud of 261 typedef struct _PACKED { 262 edid1_header_raw header; // 8 bytes 263 edid1_vendor_raw vendor; // 10 bytes 264 edid1_version_raw version; // 2 bytes 265 edid1_display_raw display; // 15 bytes 266 edid1_established_timing established_timing; // 3 bytes 267 edid1_std_timing_raw std_timing[EDID1_NUM_STD_TIMING]; 268 // 8 a 2 bytes -> 16 bytes 269 270 // since EDID version 1.2 271 edid1_detailed_monitor_raw detailed_monitor[EDID1_NUM_DETAILED_MONITOR_DESC]; 272 // 4 a 18 bytes -> 72 bytes 273 274 uint8 num_sections; // 1 byte 275 uint8 check_sum; // 1 byte 276 } edid1_raw; // total: 128 bytes 277 278 #endif 279